diff options
author | Nick Clifton <nickc@redhat.com> | 2010-04-29 14:44:15 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2010-04-29 14:44:15 +0000 |
commit | 77db8e2e96ba37bb1915261d21f7287f15b67bf8 (patch) | |
tree | 95d5cd9e621e6912a423b1b35b9120b31360df4d /gas/config | |
parent | c0643a5132a92140534e5a0de9fd26ca5c5e9060 (diff) | |
download | gdb-77db8e2e96ba37bb1915261d21f7287f15b67bf8.zip gdb-77db8e2e96ba37bb1915261d21f7287f15b67bf8.tar.gz gdb-77db8e2e96ba37bb1915261d21f7287f15b67bf8.tar.bz2 |
* write.c (fixup_segment): Do not assume we know the section a
defined weak symbol is in.
* config/tc-arm.c (relax_adr, relax_branch, md_apply_fix): Treat
weak symbols as not known to be in the same section, even if they
are defined.
* gas/arm/weakdef-1.s: New.
* gas/arm/weakdef-1.d: New.
* gas/arm/weakdef-2.s: New.
* gas/arm/weakdef-2.d: New.
* gas/arm/weakdef-2.l: New.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-arm.c | 66 |
1 files changed, 35 insertions, 31 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index b7ea21b..a50ac1d 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -18530,7 +18530,8 @@ relax_adr (fragS *fragp, asection *sec, long stretch) /* Assume worst case for symbols not known to be in the same section. */ if (fragp->fr_symbol == NULL || !S_IS_DEFINED (fragp->fr_symbol) - || sec != S_GET_SEGMENT (fragp->fr_symbol)) + || sec != S_GET_SEGMENT (fragp->fr_symbol) + || S_IS_WEAK (fragp->fr_symbol)) return 4; val = relaxed_symbol_addr (fragp, stretch); @@ -18573,7 +18574,8 @@ relax_branch (fragS *fragp, asection *sec, int bits, long stretch) /* Assume worst case for symbols not known to be in the same section. */ if (!S_IS_DEFINED (fragp->fr_symbol) - || sec != S_GET_SEGMENT (fragp->fr_symbol)) + || sec != S_GET_SEGMENT (fragp->fr_symbol) + || S_IS_WEAK (fragp->fr_symbol)) return 4; #ifdef OBJ_ELF @@ -19784,22 +19786,23 @@ md_apply_fix (fixS * fixP, not have a reloc for it, so tc_gen_reloc will reject it. */ fixP->fx_done = 1; - if (fixP->fx_addsy - && ! S_IS_DEFINED (fixP->fx_addsy)) + if (fixP->fx_addsy) { - as_bad_where (fixP->fx_file, fixP->fx_line, - _("undefined symbol %s used as an immediate value"), - S_GET_NAME (fixP->fx_addsy)); - break; - } + const char *msg = 0; - if (fixP->fx_addsy - && S_GET_SEGMENT (fixP->fx_addsy) != seg) - { - as_bad_where (fixP->fx_file, fixP->fx_line, - _("symbol %s is in a different section"), - S_GET_NAME (fixP->fx_addsy)); - break; + if (! S_IS_DEFINED (fixP->fx_addsy)) + msg = _("undefined symbol %s used as an immediate value"); + else if (S_GET_SEGMENT (fixP->fx_addsy) != seg) + msg = _("symbol %s is in a different section"); + else if (S_IS_WEAK (fixP->fx_addsy)) + msg = _("symbol %s is weak and may be overridden later"); + + if (msg) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + msg, S_GET_NAME (fixP->fx_addsy)); + break; + } } newimm = encode_arm_immediate (value); @@ -19825,24 +19828,25 @@ md_apply_fix (fixS * fixP, unsigned int highpart = 0; unsigned int newinsn = 0xe1a00000; /* nop. */ - if (fixP->fx_addsy - && ! S_IS_DEFINED (fixP->fx_addsy)) + if (fixP->fx_addsy) { - as_bad_where (fixP->fx_file, fixP->fx_line, - _("undefined symbol %s used as an immediate value"), - S_GET_NAME (fixP->fx_addsy)); - break; - } + const char *msg = 0; - if (fixP->fx_addsy - && S_GET_SEGMENT (fixP->fx_addsy) != seg) - { - as_bad_where (fixP->fx_file, fixP->fx_line, - _("symbol %s is in a different section"), - S_GET_NAME (fixP->fx_addsy)); - break; - } + if (! S_IS_DEFINED (fixP->fx_addsy)) + msg = _("undefined symbol %s used as an immediate value"); + else if (S_GET_SEGMENT (fixP->fx_addsy) != seg) + msg = _("symbol %s is in a different section"); + else if (S_IS_WEAK (fixP->fx_addsy)) + msg = _("symbol %s is weak and may be overridden later"); + if (msg) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + msg, S_GET_NAME (fixP->fx_addsy)); + break; + } + } + newimm = encode_arm_immediate (value); temp = md_chars_to_number (buf, INSN_SIZE); |