From 77db8e2e96ba37bb1915261d21f7287f15b67bf8 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 29 Apr 2010 14:44:15 +0000 Subject: [PATCH] * 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. --- gas/ChangeLog | 8 +++++ gas/config/tc-arm.c | 66 +++++++++++++++++++++------------------ gas/testsuite/ChangeLog | 8 +++++ gas/testsuite/gas/arm/weakdef-1.d | 20 ++++++++++++ gas/testsuite/gas/arm/weakdef-1.s | 18 +++++++++++ gas/testsuite/gas/arm/weakdef-2.d | 5 +++ gas/testsuite/gas/arm/weakdef-2.l | 3 ++ gas/testsuite/gas/arm/weakdef-2.s | 10 ++++++ gas/write.c | 4 ++- 9 files changed, 110 insertions(+), 32 deletions(-) create mode 100644 gas/testsuite/gas/arm/weakdef-1.d create mode 100644 gas/testsuite/gas/arm/weakdef-1.s create mode 100644 gas/testsuite/gas/arm/weakdef-2.d create mode 100644 gas/testsuite/gas/arm/weakdef-2.l create mode 100644 gas/testsuite/gas/arm/weakdef-2.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 961b716..c2b3faa 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2010-04-29 Nathan Sidwell + + * 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. + 2010-04-27 Joseph Myers * config/tc-tic6x.h (tic6x_label_list): New. 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); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index f381115..c9eae54 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2010-04-29 Nathan Sidwell + + * 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. + 2010-04-27 Joseph Myers * gas/tic6x/align-1-be.d, gas/tic6x/align-1.d, diff --git a/gas/testsuite/gas/arm/weakdef-1.d b/gas/testsuite/gas/arm/weakdef-1.d new file mode 100644 index 0000000..8351fc2 --- /dev/null +++ b/gas/testsuite/gas/arm/weakdef-1.d @@ -0,0 +1,20 @@ +# name: Thumb branch to weak +# as: +# objdump: -dr +# This test is only valid on ELF based ports. +#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix* + +.*: +file format .*arm.* + + +Disassembly of section .text: + +0+000 : + 0: e7fe b.n 2 + 0: R_ARM_THM_JUMP11 Strong + +0+002 : + 2: f7ff bffe b.w 0 + 2: R_ARM_THM_JUMP24 Random + 6: f7ff bffe b.w 0 + 6: R_ARM_THM_JUMP24 Weak diff --git a/gas/testsuite/gas/arm/weakdef-1.s b/gas/testsuite/gas/arm/weakdef-1.s new file mode 100644 index 0000000..4aa6bc4 --- /dev/null +++ b/gas/testsuite/gas/arm/weakdef-1.s @@ -0,0 +1,18 @@ + .syntax unified + .text + .thumb + + .globl Weak + .weak Weak + .thumb_func + .type Weak, %function +Weak: + b Strong + .size Weak, .-Weak + + .globl Strong + .type Strong, %function +Strong: + b Random + b Weak + .size Strong, .-Strong diff --git a/gas/testsuite/gas/arm/weakdef-2.d b/gas/testsuite/gas/arm/weakdef-2.d new file mode 100644 index 0000000..e0ff272 --- /dev/null +++ b/gas/testsuite/gas/arm/weakdef-2.d @@ -0,0 +1,5 @@ +# name: adr of weak +# as: +# error-output: weakdef-2.l +# This test is only valid on ELF based ports. +#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix* diff --git a/gas/testsuite/gas/arm/weakdef-2.l b/gas/testsuite/gas/arm/weakdef-2.l new file mode 100644 index 0000000..7aec5e1 --- /dev/null +++ b/gas/testsuite/gas/arm/weakdef-2.l @@ -0,0 +1,3 @@ +[^:]*: Assembler messages: +[^:]*:9: Error: symbol Weak is weak and may be overridden later +[^:]*:10: Error: symbol Weak is weak and may be overridden later diff --git a/gas/testsuite/gas/arm/weakdef-2.s b/gas/testsuite/gas/arm/weakdef-2.s new file mode 100644 index 0000000..08da196 --- /dev/null +++ b/gas/testsuite/gas/arm/weakdef-2.s @@ -0,0 +1,10 @@ + .syntax unified + .text + .globl Strong +Strong: + adrl r0,Strong + adr r0,Strong + .globl Weak + .weak Weak +Weak: adrl r0,Weak + adr r0,Weak diff --git a/gas/write.c b/gas/write.c index a148b24..b50b0d4 100644 --- a/gas/write.c +++ b/gas/write.c @@ -992,7 +992,9 @@ fixup_segment (fixS *fixP, segT this_segment) if (fixP->fx_addsy) { - if (add_symbol_segment == this_segment + if (S_IS_WEAK (fixP->fx_addsy)) + ; // even if it is defined, it might be overridden later + else if (add_symbol_segment == this_segment && !TC_FORCE_RELOCATION_LOCAL (fixP)) { /* This fixup was made when the symbol's segment was -- 2.7.4