diff options
author | Cupertino Miranda <cmiranda@synopsys.com> | 2015-10-28 13:48:00 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-10-28 13:48:00 +0000 |
commit | 6f4b1afcdc8317280669d020765b8215110c4584 (patch) | |
tree | b6365ff26a33f93899421909914d54c7e69e7721 /gas/config | |
parent | 7963511fbf0459fff586c3129705bfbc706770e3 (diff) | |
download | gdb-6f4b1afcdc8317280669d020765b8215110c4584.zip gdb-6f4b1afcdc8317280669d020765b8215110c4584.tar.gz gdb-6f4b1afcdc8317280669d020765b8215110c4584.tar.bz2 |
Fix errors in the gas testsuite for the ARC target.
bfd * reloc.c (BFD_RELOC_ARC_32_PCREL): New entry.
(ARC_TLS_DTPOFF): Arrange it in order.
* elf32-arc.c (arc_elf_howto_ini): Update formula.
(get_middle_endian_relocation): New function.
(PDATA): Define.
* bfd-in2.h: Regenerate.
* libbfd.h: Likewise.
elf * arc-reloc.def (ARC_32_PCREL): New definition.
gas * config/tc-arc.c (tokenize_arguments): Avoid creating unused
symbols when parsing relocation types.
(md_apply_fix): Handle TLS relocations. Fix BFD_RELOC_ARC_32_PCREL
relocation.
(arc_check_reloc): Emit BFD_RELOC_ARC_32_PCREL relocation.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-arc.c | 402 |
1 files changed, 213 insertions, 189 deletions
diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index cc56797..e0a4b57 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -91,122 +91,122 @@ static void arc_option (int); static void arc_extra_reloc (int); const pseudo_typeS md_pseudo_table[] = - { - /* Make sure that .word is 32 bits. */ - { "word", cons, 4 }, +{ + /* Make sure that .word is 32 bits. */ + { "word", cons, 4 }, - { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */ - { "lcomm", arc_lcomm, 0 }, - { "lcommon", arc_lcomm, 0 }, - { "cpu", arc_option, 0 }, + { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */ + { "lcomm", arc_lcomm, 0 }, + { "lcommon", arc_lcomm, 0 }, + { "cpu", arc_option, 0 }, - { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD }, - { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL }, + { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD }, + { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL }, - { NULL, NULL, 0 } - }; + { NULL, NULL, 0 } +}; const char *md_shortopts = ""; enum options - { - OPTION_EB = OPTION_MD_BASE, - OPTION_EL, - - OPTION_ARC600, - OPTION_ARC601, - OPTION_ARC700, - OPTION_ARCEM, - OPTION_ARCHS, - - OPTION_MCPU, - OPTION_CD, - - /* The following options are deprecated and provided here only for - compatibility reasons. */ - OPTION_USER_MODE, - OPTION_LD_EXT_MASK, - OPTION_SWAP, - OPTION_NORM, - OPTION_BARREL_SHIFT, - OPTION_MIN_MAX, - OPTION_NO_MPY, - OPTION_EA, - OPTION_MUL64, - OPTION_SIMD, - OPTION_SPFP, - OPTION_DPFP, - OPTION_XMAC_D16, - OPTION_XMAC_24, - OPTION_DSP_PACKA, - OPTION_CRC, - OPTION_DVBF, - OPTION_TELEPHONY, - OPTION_XYMEMORY, - OPTION_LOCK, - OPTION_SWAPE, - OPTION_RTSC, - OPTION_FPUDA - }; +{ + OPTION_EB = OPTION_MD_BASE, + OPTION_EL, + + OPTION_ARC600, + OPTION_ARC601, + OPTION_ARC700, + OPTION_ARCEM, + OPTION_ARCHS, + + OPTION_MCPU, + OPTION_CD, + + /* The following options are deprecated and provided here only for + compatibility reasons. */ + OPTION_USER_MODE, + OPTION_LD_EXT_MASK, + OPTION_SWAP, + OPTION_NORM, + OPTION_BARREL_SHIFT, + OPTION_MIN_MAX, + OPTION_NO_MPY, + OPTION_EA, + OPTION_MUL64, + OPTION_SIMD, + OPTION_SPFP, + OPTION_DPFP, + OPTION_XMAC_D16, + OPTION_XMAC_24, + OPTION_DSP_PACKA, + OPTION_CRC, + OPTION_DVBF, + OPTION_TELEPHONY, + OPTION_XYMEMORY, + OPTION_LOCK, + OPTION_SWAPE, + OPTION_RTSC, + OPTION_FPUDA +}; struct option md_longopts[] = - { - { "EB", no_argument, NULL, OPTION_EB }, - { "EL", no_argument, NULL, OPTION_EL }, - { "mcpu", required_argument, NULL, OPTION_MCPU }, - { "mA6", no_argument, NULL, OPTION_ARC600 }, - { "mARC600", no_argument, NULL, OPTION_ARC600 }, - { "mARC601", no_argument, NULL, OPTION_ARC601 }, - { "mARC700", no_argument, NULL, OPTION_ARC700 }, - { "mA7", no_argument, NULL, OPTION_ARC700 }, - { "mEM", no_argument, NULL, OPTION_ARCEM }, - { "mHS", no_argument, NULL, OPTION_ARCHS }, - { "mcode-density", no_argument, NULL, OPTION_CD }, - - /* The following options are deprecated and provided here only for - compatibility reasons. */ - { "mav2em", no_argument, NULL, OPTION_ARCEM }, - { "mav2hs", no_argument, NULL, OPTION_ARCHS }, - { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE }, - { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK }, - { "mswap", no_argument, NULL, OPTION_SWAP }, - { "mnorm", no_argument, NULL, OPTION_NORM }, - { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT }, - { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT }, - { "mmin-max", no_argument, NULL, OPTION_MIN_MAX }, - { "mmin_max", no_argument, NULL, OPTION_MIN_MAX }, - { "mno-mpy", no_argument, NULL, OPTION_NO_MPY }, - { "mea", no_argument, NULL, OPTION_EA }, - { "mEA", no_argument, NULL, OPTION_EA }, - { "mmul64", no_argument, NULL, OPTION_MUL64 }, - { "msimd", no_argument, NULL, OPTION_SIMD}, - { "mspfp", no_argument, NULL, OPTION_SPFP}, - { "mspfp-compact", no_argument, NULL, OPTION_SPFP}, - { "mspfp_compact", no_argument, NULL, OPTION_SPFP}, - { "mspfp-fast", no_argument, NULL, OPTION_SPFP}, - { "mspfp_fast", no_argument, NULL, OPTION_SPFP}, - { "mdpfp", no_argument, NULL, OPTION_DPFP}, - { "mdpfp-compact", no_argument, NULL, OPTION_DPFP}, - { "mdpfp_compact", no_argument, NULL, OPTION_DPFP}, - { "mdpfp-fast", no_argument, NULL, OPTION_DPFP}, - { "mdpfp_fast", no_argument, NULL, OPTION_DPFP}, - { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16}, - { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16}, - { "mmac-24", no_argument, NULL, OPTION_XMAC_24}, - { "mmac_24", no_argument, NULL, OPTION_XMAC_24}, - { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA}, - { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA}, - { "mcrc", no_argument, NULL, OPTION_CRC}, - { "mdvbf", no_argument, NULL, OPTION_DVBF}, - { "mtelephony", no_argument, NULL, OPTION_TELEPHONY}, - { "mxy", no_argument, NULL, OPTION_XYMEMORY}, - { "mlock", no_argument, NULL, OPTION_LOCK}, - { "mswape", no_argument, NULL, OPTION_SWAPE}, - { "mrtsc", no_argument, NULL, OPTION_RTSC}, - { "mfpuda", no_argument, NULL, OPTION_FPUDA}, - - { NULL, no_argument, NULL, 0 } - }; +{ + { "EB", no_argument, NULL, OPTION_EB }, + { "EL", no_argument, NULL, OPTION_EL }, + { "mcpu", required_argument, NULL, OPTION_MCPU }, + { "mA6", no_argument, NULL, OPTION_ARC600 }, + { "mARC600", no_argument, NULL, OPTION_ARC600 }, + { "mARC601", no_argument, NULL, OPTION_ARC601 }, + { "mARC700", no_argument, NULL, OPTION_ARC700 }, + { "mA7", no_argument, NULL, OPTION_ARC700 }, + { "mEM", no_argument, NULL, OPTION_ARCEM }, + { "mHS", no_argument, NULL, OPTION_ARCHS }, + { "mcode-density", no_argument, NULL, OPTION_CD }, + + /* The following options are deprecated and provided here only for + compatibility reasons. */ + { "mav2em", no_argument, NULL, OPTION_ARCEM }, + { "mav2hs", no_argument, NULL, OPTION_ARCHS }, + { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE }, + { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK }, + { "mswap", no_argument, NULL, OPTION_SWAP }, + { "mnorm", no_argument, NULL, OPTION_NORM }, + { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT }, + { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT }, + { "mmin-max", no_argument, NULL, OPTION_MIN_MAX }, + { "mmin_max", no_argument, NULL, OPTION_MIN_MAX }, + { "mno-mpy", no_argument, NULL, OPTION_NO_MPY }, + { "mea", no_argument, NULL, OPTION_EA }, + { "mEA", no_argument, NULL, OPTION_EA }, + { "mmul64", no_argument, NULL, OPTION_MUL64 }, + { "msimd", no_argument, NULL, OPTION_SIMD}, + { "mspfp", no_argument, NULL, OPTION_SPFP}, + { "mspfp-compact", no_argument, NULL, OPTION_SPFP}, + { "mspfp_compact", no_argument, NULL, OPTION_SPFP}, + { "mspfp-fast", no_argument, NULL, OPTION_SPFP}, + { "mspfp_fast", no_argument, NULL, OPTION_SPFP}, + { "mdpfp", no_argument, NULL, OPTION_DPFP}, + { "mdpfp-compact", no_argument, NULL, OPTION_DPFP}, + { "mdpfp_compact", no_argument, NULL, OPTION_DPFP}, + { "mdpfp-fast", no_argument, NULL, OPTION_DPFP}, + { "mdpfp_fast", no_argument, NULL, OPTION_DPFP}, + { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16}, + { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16}, + { "mmac-24", no_argument, NULL, OPTION_XMAC_24}, + { "mmac_24", no_argument, NULL, OPTION_XMAC_24}, + { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA}, + { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA}, + { "mcrc", no_argument, NULL, OPTION_CRC}, + { "mdvbf", no_argument, NULL, OPTION_DVBF}, + { "mtelephony", no_argument, NULL, OPTION_TELEPHONY}, + { "mxy", no_argument, NULL, OPTION_XYMEMORY}, + { "mlock", no_argument, NULL, OPTION_LOCK}, + { "mswape", no_argument, NULL, OPTION_SWAPE}, + { "mrtsc", no_argument, NULL, OPTION_RTSC}, + { "mfpuda", no_argument, NULL, OPTION_FPUDA}, + + { NULL, no_argument, NULL, 0 } +}; size_t md_longopts_size = sizeof (md_longopts); @@ -354,19 +354,19 @@ static const struct arc_reloc_op_tag unsigned int complex_expr : 1; } arc_reloc_op[] = - { - DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1), - DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0), - DEF (plt, BFD_RELOC_ARC_PLT32, 0), - DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1), - DEF (pcl, BFD_RELOC_ARC_PC32, 1), - DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0), - DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0), - DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0), - DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 0), - DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0), - DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0), - }; +{ + DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1), + DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0), + DEF (plt, BFD_RELOC_ARC_PLT32, 0), + DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1), + DEF (pcl, BFD_RELOC_ARC_PC32, 1), + DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0), + DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0), + DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0), + DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 0), + DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0), + DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0), +}; static const int arc_num_reloc_op = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op); @@ -414,9 +414,7 @@ static const struct arc_opcode *find_special_case_pseudo (const char *, this function is used for regular 4 byte instructions as well. */ static void -md_number_to_chars_midend (char *buf, - valueT val, - int n) +md_number_to_chars_midend (char *buf, valueT val, int n) { if (n == 4) { @@ -623,11 +621,11 @@ tokenize_arguments (char *str, bfd_boolean saw_arg = FALSE; int brk_lvl = 0; int num_args = 0; - const char *p; int i; size_t len; const struct arc_reloc_op_tag *r; expressionS tmpE; + char *reloc_name, c; memset (tok, 0, sizeof (*tok) * ntok); @@ -685,6 +683,8 @@ tokenize_arguments (char *str, if (*input_line_pointer != '@') goto normalsymbol; /* This is not a relocation. */ + relocationsym: + /* A relocation opernad has the following form @identifier@relocation_type. The identifier is already in tok! */ @@ -695,37 +695,29 @@ tokenize_arguments (char *str, } /* Parse @relocation_type. */ - memset (&tmpE, 0, sizeof (tmpE)); - tmpE.X_op = O_symbol; - expression (&tmpE); - - if (tmpE.X_op != O_symbol) + input_line_pointer++; + c = get_symbol_name (&reloc_name); + len = input_line_pointer - reloc_name; + if (len == 0) { as_bad (_("No relocation operand")); goto err; } - p = S_GET_NAME (tmpE.X_add_symbol); - len = strlen (p); /* Go through known relocation and try to find a match. */ r = &arc_reloc_op[0]; for (i = arc_num_reloc_op - 1; i >= 0; i--, r++) - if (len == r->length && memcmp (p, r->name, len) == 0) + if (len == r->length + && memcmp (reloc_name, r->name, len) == 0) break; - if (i < 0) { - as_bad (_("Unknown relocation operand: @%s"), p); - goto err; - } - tok->X_md = r->op; - tok->X_add_number = tmpE.X_add_number; - if (tmpE.X_add_number && !r->complex_expr) - { - as_bad (_("Complex relocation operand.")); + as_bad (_("Unknown relocation operand: @%s"), reloc_name); goto err; } + *input_line_pointer = c; + SKIP_WHITESPACE_AFTER_NAME (); /* Extra check for TLS: base. */ if (*input_line_pointer == '@') { @@ -733,17 +725,44 @@ tokenize_arguments (char *str, if (tok->X_op_symbol != NULL || tok->X_op != O_symbol) { - as_bad (_("Unable to parse this reloc")); + as_bad (_("Unable to parse TLS base: %s"), + input_line_pointer); goto err; } input_line_pointer++; char *sym_name; - char c = get_symbol_name (&sym_name); + c = get_symbol_name (&sym_name); base = symbol_find_or_make (sym_name); tok->X_op = O_subtract; tok->X_op_symbol = base; restore_line_pointer (c); + tmpE.X_add_number = 0; + } + else if ((*input_line_pointer != '+') + && (*input_line_pointer != '-')) + { + tmpE.X_add_number = 0; } + else + { + /* Parse the constant of a complex relocation expression + like @identifier@reloc +/- const. */ + if (! r->complex_expr) + { + as_bad (_("@%s is not a complex relocation."), r->name); + goto err; + } + expression (&tmpE); + if (tmpE.X_op != O_constant) + { + as_bad (_("Bad expression: @%s + %s."), + r->name, input_line_pointer); + goto err; + } + } + + tok->X_md = r->op; + tok->X_add_number = tmpE.X_add_number; debug_exp (tok); @@ -763,8 +782,15 @@ tokenize_arguments (char *str, goto err; tok->X_op = O_absent; + tok->X_md = O_absent; expression (tok); + /* Legacy: There are cases when we have + identifier@relocation_type, if it is the case parse the + relocation type as well. */ + if (*input_line_pointer == '@') + goto relocationsym; + normalsymbol: debug_exp (tok); @@ -1234,6 +1260,7 @@ md_apply_fix (fixS *fixP, fixP->fx_r_type = BFD_RELOC_ARC_PC32; /* Fall through. */ case BFD_RELOC_ARC_PC32: + /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */ break; default: if ((int) fixP->fx_r_type < 0) @@ -1249,8 +1276,48 @@ md_apply_fix (fixS *fixP, bfd_get_reloc_code_name (fixP->fx_r_type), value, fixP->fx_offset); + + /* Now check for TLS relocations. */ + reloc = fixP->fx_r_type; + switch (reloc) + { + case BFD_RELOC_ARC_TLS_DTPOFF: + case BFD_RELOC_ARC_TLS_LE_32: + fixP->fx_offset = 0; + /* Fall through. */ + case BFD_RELOC_ARC_TLS_GD_GOT: + case BFD_RELOC_ARC_TLS_IE_GOT: + S_SET_THREAD_LOCAL (fixP->fx_addsy); + break; + + case BFD_RELOC_ARC_TLS_GD_LD: + gas_assert (!fixP->fx_offset); + if (fixP->fx_subsy) + fixP->fx_offset + = (S_GET_VALUE (fixP->fx_subsy) + - fixP->fx_frag->fr_address- fixP->fx_where); + fixP->fx_subsy = NULL; + /* Fall through. */ + case BFD_RELOC_ARC_TLS_GD_CALL: + /* These two relocs are there just to allow ld to change the tls + model for this symbol, by patching the code. The offset - + and scale, if any - will be installed by the linker. */ + S_SET_THREAD_LOCAL (fixP->fx_addsy); + break; + + case BFD_RELOC_ARC_TLS_LE_S9: + case BFD_RELOC_ARC_TLS_DTPOFF_S9: + as_bad (_("TLS_*_S9 relocs are not supported yet")); + break; + + default: + break; + } + if (!fixP->fx_done) - return; + { + return; + } /* Addjust the value if we have a constant. */ value += fx_offset; @@ -1269,6 +1336,7 @@ md_apply_fix (fixS *fixP, case BFD_RELOC_24: case BFD_RELOC_32: case BFD_RELOC_64: + case BFD_RELOC_ARC_32_PCREL: md_number_to_chars (fixpos, value, fixP->fx_size); return; @@ -1312,50 +1380,6 @@ md_apply_fix (fixS *fixP, gas_assert (operand); break; - case BFD_RELOC_ARC_TLS_DTPOFF: - case BFD_RELOC_ARC_TLS_LE_32: - if (fixP->fx_done) - { - gas_assert (!fixP->fx_addsy); - gas_assert (!fixP->fx_subsy); - md_number_to_chars_midend (fixpos, value, fixP->fx_size); - return; - } - else - { - value = fixP->fx_offset; - fixP->fx_offset = 0; - } - /* Fall through. */ - case BFD_RELOC_ARC_TLS_GD_GOT: - case BFD_RELOC_ARC_TLS_IE_GOT: - S_SET_THREAD_LOCAL (fixP->fx_addsy); - md_number_to_chars_midend (fixpos, value, fixP->fx_size); - return; - - case BFD_RELOC_ARC_TLS_GD_LD: - gas_assert (!fixP->fx_offset); - if (fixP->fx_subsy) - fixP->fx_offset - = (S_GET_VALUE (fixP->fx_subsy) - - fixP->fx_frag->fr_address- fixP->fx_where); - fixP->fx_subsy = NULL; - /* Fall through. */ - case BFD_RELOC_ARC_TLS_GD_CALL: - /* These two relocs are there just to allow ld to change the tls - model for this symbol, by patching the code. */ - /* Fall through. */ - /* The offset - and scale, if any - will be installed by the - linker. */ - gas_assert (!fixP->fx_done); - S_SET_THREAD_LOCAL (fixP->fx_addsy); - return; - - case BFD_RELOC_ARC_TLS_LE_S9: - case BFD_RELOC_ARC_TLS_DTPOFF_S9: - as_bad (_("TLS_*_S9 relocs are not supported yet")); - break; - default: { if ((int) fixP->fx_r_type >= 0) @@ -3046,7 +3070,7 @@ arc_check_reloc (expressionS *exp, && exp->X_op == O_subtract && exp->X_op_symbol != NULL && exp->X_op_symbol->bsym->section == now_seg) - *r_type_p = BFD_RELOC_ARC_PC32; + *r_type_p = BFD_RELOC_ARC_32_PCREL; } |