X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-mn10300.c;h=1a244aba897bc871efd5fee38e4a5d1b7e42cc40;hb=389b8029b69e2a4cdbc3a23d0ee9d5b3c974bd34;hp=5068904f0120cb8a9f8fd3f44a7ba824d08c119c;hpb=ca75ed2d8fd6fd97f7536ceb9fb0f3e2b99f6211;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c index 5068904f01..1a244aba89 100644 --- a/gas/config/tc-mn10300.c +++ b/gas/config/tc-mn10300.c @@ -1,6 +1,5 @@ /* tc-mn10300.c -- Assembler code for the Matsushita 10300 - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 1996-2015 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -281,6 +280,8 @@ static const struct reg_name other_registers[] = { "pc", AM33 }, { "psw", 0 }, { "sp", 0 }, + { "ssp", 0 }, + { "usp", 0 }, }; #define OTHER_REG_NAME_CNT ARRAY_SIZE (other_registers) @@ -689,6 +690,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, fragP->fr_literal[offset] = 0xdd; fragP->fr_literal[offset + 5] = fragP->fr_literal[offset + 3]; fragP->fr_literal[offset + 6] = fragP->fr_literal[offset + 4]; + fragP->fr_literal[offset + 3] = 0; + fragP->fr_literal[offset + 4] = 0; fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL); @@ -1010,7 +1013,8 @@ mn10300_check_fixup (struct mn10300_fixup *fixup) } void -mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp) +mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp, + bfd_reloc_code_real_type r ATTRIBUTE_UNUSED) { struct mn10300_fixup fixup; @@ -1772,8 +1776,6 @@ keep_going: that they do indeed not match. */ if (opcode->no_match_operands) { - int i; - /* Look at each operand to see if it's marked. */ for (i = 0; i < MN10300_MAX_OPERANDS; i++) { @@ -2056,18 +2058,23 @@ keep_going: for (i = 0; i < fc; i++) { const struct mn10300_operand *operand; + int reloc_size; operand = &mn10300_operands[fixups[i].opindex]; if (fixups[i].reloc != BFD_RELOC_UNUSED && fixups[i].reloc != BFD_RELOC_32_GOT_PCREL && fixups[i].reloc != BFD_RELOC_32_GOTOFF && fixups[i].reloc != BFD_RELOC_32_PLT_PCREL + && fixups[i].reloc != BFD_RELOC_MN10300_TLS_GD + && fixups[i].reloc != BFD_RELOC_MN10300_TLS_LD + && fixups[i].reloc != BFD_RELOC_MN10300_TLS_LDO + && fixups[i].reloc != BFD_RELOC_MN10300_TLS_GOTIE + && fixups[i].reloc != BFD_RELOC_MN10300_TLS_IE + && fixups[i].reloc != BFD_RELOC_MN10300_TLS_LE && fixups[i].reloc != BFD_RELOC_MN10300_GOT32) { reloc_howto_type *reloc_howto; - int size; int offset; - fixS *fixP; reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc); @@ -2075,20 +2082,20 @@ keep_going: if (!reloc_howto) abort (); - size = bfd_get_reloc_size (reloc_howto); + reloc_size = bfd_get_reloc_size (reloc_howto); - if (size < 1 || size > 4) + if (reloc_size < 1 || reloc_size > 4) abort (); offset = 4 - size; - fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, - size, &fixups[i].exp, - reloc_howto->pc_relative, - fixups[i].reloc); + fix_new_exp (frag_now, f - frag_now->fr_literal + offset, + reloc_size, &fixups[i].exp, + reloc_howto->pc_relative, + fixups[i].reloc); } else { - int reloc, pcrel, reloc_size, offset; + int reloc, pcrel, offset; fixS *fixP; reloc = BFD_RELOC_NONE; @@ -2192,8 +2199,6 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) asec = S_GET_SEGMENT (fixp->fx_addsy); ssec = S_GET_SEGMENT (fixp->fx_subsy); - reloc->sym_ptr_ptr = NULL; - /* If we have a difference between two (non-absolute) symbols we must generate two relocs (one for each symbol) and allow the linker to resolve them - relaxation may change the distances between symbols, @@ -2213,10 +2218,15 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) reloc->addend = fixp->fx_offset; if (asec == absolute_section) - reloc->addend += S_GET_VALUE (fixp->fx_addsy); - - reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); - *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + { + reloc->addend += S_GET_VALUE (fixp->fx_addsy); + reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + } + else + { + reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + } fixp->fx_pcrel = 0; fixp->fx_done = 1; @@ -2253,8 +2263,6 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) return relocs; } - if (reloc->sym_ptr_ptr) - free (reloc->sym_ptr_ptr); free (reloc); return & no_relocs; } @@ -2322,7 +2330,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) int size = 0; int value = (int) * valP; - assert (fixP->fx_r_type < BFD_RELOC_UNUSED); + gas_assert (fixP->fx_r_type < BFD_RELOC_UNUSED); /* This should never happen. */ if (seg->flags & SEC_ALLOC) @@ -2501,6 +2509,18 @@ mn10300_parse_name (char const *name, reloc_type = BFD_RELOC_MN10300_GOT32; else if ((next_end = mn10300_end_of_match (next + 1, "PLT"))) reloc_type = BFD_RELOC_32_PLT_PCREL; + else if ((next_end = mn10300_end_of_match (next + 1, "tlsgd"))) + reloc_type = BFD_RELOC_MN10300_TLS_GD; + else if ((next_end = mn10300_end_of_match (next + 1, "tlsldm"))) + reloc_type = BFD_RELOC_MN10300_TLS_LD; + else if ((next_end = mn10300_end_of_match (next + 1, "dtpoff"))) + reloc_type = BFD_RELOC_MN10300_TLS_LDO; + else if ((next_end = mn10300_end_of_match (next + 1, "gotntpoff"))) + reloc_type = BFD_RELOC_MN10300_TLS_GOTIE; + else if ((next_end = mn10300_end_of_match (next + 1, "indntpoff"))) + reloc_type = BFD_RELOC_MN10300_TLS_IE; + else if ((next_end = mn10300_end_of_match (next + 1, "tpoff"))) + reloc_type = BFD_RELOC_MN10300_TLS_LE; else goto no_suffix;