This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[arm] branches to weak symbols
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils <binutils at sources dot redhat dot com>
- Cc: Paul Brook <paul at codesourcery dot com>
- Date: Wed, 28 Apr 2010 09:49:17 +0100
- Subject: [arm] branches to weak symbols
This patch fixes some arm cases where the assembler did not consider that a
weakly defined symbol might be overridden in the final link. It would use a
short thumb branch resulting in an unoverridable relocation (and inability to
build the linux kernel)
The same error is made in write.c's fixup_segment (and affects this arm problem)
It may affect other targets.
Fixed thusly, tested on arm-eabi. ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
2010-04-28 Nathan Sidwell <nathan@codesourcery.com>
* 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.
testsuite/
* 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.
Index: write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.129
diff -c -3 -p -r1.129 write.c
*** write.c 23 Jan 2010 12:05:32 -0000 1.129
--- write.c 28 Apr 2010 08:40:28 -0000
*************** fixup_segment (fixS *fixP, segT this_seg
*** 992,998 ****
if (fixP->fx_addsy)
{
! if (add_symbol_segment == this_segment
&& !TC_FORCE_RELOCATION_LOCAL (fixP))
{
/* This fixup was made when the symbol's segment was
--- 992,1000 ----
if (fixP->fx_addsy)
{
! 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
Index: config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.441
diff -c -3 -p -r1.441 tc-arm.c
*** config/tc-arm.c 15 Apr 2010 10:56:37 -0000 1.441
--- config/tc-arm.c 28 Apr 2010 08:40:34 -0000
*************** relax_adr (fragS *fragp, asection *sec,
*** 18530,18536 ****
/* 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))
return 4;
val = relaxed_symbol_addr (fragp, stretch);
--- 18530,18537 ----
/* 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)
! || S_IS_WEAK (fragp->fr_symbol))
return 4;
val = relaxed_symbol_addr (fragp, stretch);
*************** relax_branch (fragS *fragp, asection *se
*** 18573,18579 ****
/* 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))
return 4;
#ifdef OBJ_ELF
--- 18574,18581 ----
/* 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)
! || S_IS_WEAK (fragp->fr_symbol))
return 4;
#ifdef OBJ_ELF
*************** md_apply_fix (fixS * fixP,
*** 19784,19805 ****
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))
{
! as_bad_where (fixP->fx_file, fixP->fx_line,
! _("undefined symbol %s used as an immediate value"),
! S_GET_NAME (fixP->fx_addsy));
! break;
! }
! 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;
}
newimm = encode_arm_immediate (value);
--- 19786,19808 ----
not have a reloc for it, so tc_gen_reloc will reject it. */
fixP->fx_done = 1;
! if (fixP->fx_addsy)
{
! const char *msg = 0;
! 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);
*************** md_apply_fix (fixS * fixP,
*** 19825,19848 ****
unsigned int highpart = 0;
unsigned int newinsn = 0xe1a00000; /* nop. */
! if (fixP->fx_addsy
! && ! S_IS_DEFINED (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;
! }
! 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;
! }
newimm = encode_arm_immediate (value);
temp = md_chars_to_number (buf, INSN_SIZE);
--- 19828,19852 ----
unsigned int highpart = 0;
unsigned int newinsn = 0xe1a00000; /* nop. */
! if (fixP->fx_addsy)
{
! const char *msg = 0;
! 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);
Index: testsuite/gas/arm/weakdef-1.d
===================================================================
RCS file: testsuite/gas/arm/weakdef-1.d
diff -N testsuite/gas/arm/weakdef-1.d
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gas/arm/weakdef-1.d 28 Apr 2010 08:40:34 -0000
***************
*** 0 ****
--- 1,18 ----
+ # name: Thumb branch to weak
+ # as:
+ # objdump: -dr
+
+ .*: +file format .*arm.*
+
+
+ Disassembly of section .text:
+
+ 0+000 <Weak>:
+ 0: e7fe b.n 2 <Strong>
+ 0: R_ARM_THM_JUMP11 Strong
+
+ 0+002 <Strong>:
+ 2: f7ff bffe b.w 0 <Random>
+ 2: R_ARM_THM_JUMP24 Random
+ 6: f7ff bffe b.w 0 <Weak>
+ 6: R_ARM_THM_JUMP24 Weak
Index: testsuite/gas/arm/weakdef-1.s
===================================================================
RCS file: testsuite/gas/arm/weakdef-1.s
diff -N testsuite/gas/arm/weakdef-1.s
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gas/arm/weakdef-1.s 28 Apr 2010 08:40:34 -0000
***************
*** 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
Index: testsuite/gas/arm/weakdef-2.d
===================================================================
RCS file: testsuite/gas/arm/weakdef-2.d
diff -N testsuite/gas/arm/weakdef-2.d
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gas/arm/weakdef-2.d 28 Apr 2010 08:40:34 -0000
***************
*** 0 ****
--- 1,3 ----
+ # name: adr of weak
+ # as:
+ # error-output: weakdef-2.l
Index: testsuite/gas/arm/weakdef-2.l
===================================================================
RCS file: testsuite/gas/arm/weakdef-2.l
diff -N testsuite/gas/arm/weakdef-2.l
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gas/arm/weakdef-2.l 28 Apr 2010 08:40:34 -0000
***************
*** 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
Index: testsuite/gas/arm/weakdef-2.s
===================================================================
RCS file: testsuite/gas/arm/weakdef-2.s
diff -N testsuite/gas/arm/weakdef-2.s
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gas/arm/weakdef-2.s 28 Apr 2010 08:40:34 -0000
***************
*** 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