#!/bin/sh -e ## 152_arm_branches_to_weak_symbols.dpatch ## ## DP: Description: http://sourceware.org/ml/binutils/2010-04/msg00446.html ## DP: Description: taken from the trunk if [ $# -ne 1 ]; then echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 fi [ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts patch_opts="${patch_opts:--f --no-backup-if-mismatch}" case "$1" in -patch) patch $patch_opts -p0 < $0;; -unpatch) patch $patch_opts -p0 -R < $0;; *) echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1;; esac exit 0 gas/ 2010-05-04 Nick Clifton * write.c (fixup_segment): Revert previous delta. * config/tc-arm.h (TC_FORCE_RELOCATION_LOCAL): Also force the generation of relocations for fixups against weak symbols. 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. gas/testsuite/ 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. @DPATCH@ diff -urN gas.orig/config/tc-arm.c gas/config/tc-arm.c --- a/gas/config/tc-arm.c 2010-02-22 08:06:52.000000000 +0000 +++ b/gas/config/tc-arm.c 2010-05-06 12:52:25.391085365 +0000 @@ -18207,7 +18207,8 @@ /* 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; val = relaxed_symbol_addr (fragp, stretch); @@ -18250,7 +18251,8 @@ /* 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 @@ -19463,22 +19465,23 @@ 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); @@ -19504,24 +19507,25 @@ 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 -urN gas.orig/config/tc-arm.h gas/config/tc-arm.h --- a/gas/config/tc-arm.h 2009-09-01 00:24:01.000000000 +0000 +++ b/gas/config/tc-arm.h 2010-05-06 12:53:42.784835970 +0000 @@ -183,6 +183,7 @@ (!(FIX)->fx_pcrel \ || (FIX)->fx_r_type == BFD_RELOC_ARM_GOT32 \ || (FIX)->fx_r_type == BFD_RELOC_32 \ + || ((FIX)->fx_addsy != NULL && S_IS_WEAK ((FIX)->fx_addsy)) \ || TC_FORCE_RELOCATION (FIX)) /* Force output of R_ARM_REL32 relocations against thumb function symbols. diff -urN gas.orig/testsuite/gas/arm/weakdef-1.d gas/testsuite/gas/arm/weakdef-1.d --- a/gas/testsuite/gas/arm/weakdef-1.d 1970-01-01 00:00:00.000000000 +0000 +++ b/gas/testsuite/gas/arm/weakdef-1.d 2010-05-06 12:52:25.391085365 +0000 @@ -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 -urN gas.orig/testsuite/gas/arm/weakdef-1.s gas/testsuite/gas/arm/weakdef-1.s --- a/gas/testsuite/gas/arm/weakdef-1.s 1970-01-01 00:00:00.000000000 +0000 +++ b/gas/testsuite/gas/arm/weakdef-1.s 2010-05-06 12:52:25.391085365 +0000 @@ -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 -urN gas.orig/testsuite/gas/arm/weakdef-2.d gas/testsuite/gas/arm/weakdef-2.d --- a/gas/testsuite/gas/arm/weakdef-2.d 1970-01-01 00:00:00.000000000 +0000 +++ b/gas/testsuite/gas/arm/weakdef-2.d 2010-05-06 12:52:25.391085365 +0000 @@ -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 -urN gas.orig/testsuite/gas/arm/weakdef-2.l gas/testsuite/gas/arm/weakdef-2.l --- a/gas/testsuite/gas/arm/weakdef-2.l 1970-01-01 00:00:00.000000000 +0000 +++ b/gas/testsuite/gas/arm/weakdef-2.l 2010-05-06 12:52:25.391085365 +0000 @@ -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 -urN gas.orig/testsuite/gas/arm/weakdef-2.s gas/testsuite/gas/arm/weakdef-2.s --- a/gas/testsuite/gas/arm/weakdef-2.s 1970-01-01 00:00:00.000000000 +0000 +++ b/gas/testsuite/gas/arm/weakdef-2.s 2010-05-06 12:52:25.391085365 +0000 @@ -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