This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gas/3041: Fix weak pc-relative references
- From: Gunther Nikl <gnikl at users dot sourceforge dot net>
- To: binutils at sourceware dot org
- Cc: Vincent Rivière <vincent dot riviere at freesbee dot fr>, Alan Modra <amodra at gmail dot com>
- Date: Thu, 02 Sep 2010 21:05:30 +0200
- Subject: gas/3041: Fix weak pc-relative references
Hello!
PR 3041 deals with a gas defect for m68k-aout targets where gas
handles references to weak symbols incorrectly. While testing
the changed a.out/m68k weak symbol handling I noticed that there
is still a bug. PC-relative references to weak symbols defined
in the same source file are resolved partially at assembly time.
This is a small test case with undefined pc-relative external
references for comparison purpose (the weak symbols are used
later in a modified example; the .set is also for that later
version and left in in to ease the comparison):
-- undef.s --
.weak _sym1
nop
_sym1:
rts
jbsr _sym3
nop
.set LTHUNK0,_sym2
jbsr LTHUNK0
nop
jbsr _sym4
nop
.weak _sym2
_sym2:
rts
-- undef.s --
Assembled with
./as-new undef.s -o undef.o
yields:
-- undef.d --
00000000 <_sym1-0x2>:
0: 4e71 nop
00000002 <_sym1>:
2: 4e75 rts
4: 61ff ffff fffa bsrl 0 <_sym1-0x2> # 1.1
6: DISP32 _sym3
a: 4e71 nop
c: 610a bsrs 18 <_sym2>
e: 4e71 nop
10: 61ff ffff ffee bsrl 0 <_sym1-0x2> # 2.1
12: DISP32 _sym4
16: 4e71 nop
00000018 <_sym2>:
18: 4e75 rts
-- undef.d --
The following is the example source from above modified to
reference the weak symbols. Assembling:
-- weak.s --
.weak _sym1
nop
_sym1:
rts
jbsr _sym1
nop
.set LTHUNK0,_sym2
jbsr LTHUNK0
nop
jbsr _sym2
nop
.weak _sym2
_sym2:
rts
-- weak.s --
results in:
-- weak1.d --
00000000 <_sym1-0x2>:
0: 4e71 nop
00000002 <_sym1>:
2: 4e75 rts
4: 61ff ffff fffe bsrl 4 <_sym1+0x2> # 1.2
6: DISP32 _sym1
a: 4e71 nop
c: 610a bsrs 18 <_sym2>
e: 4e71 nop
10: 61ff 0000 001e bsrl 30 <_sym2+0x18> # 2.2
12: DISP32 _sym2
16: 4e71 nop
00000018 <_sym2>:
18: 4e75 rts
-- weak1.d --
The "# 1.1" / "# 1.2" and "# 2.1" / "# 2.2" locations should
look equal because all these branches refer to external
symbols.
With the attached patch for tc-m68k.c/tc_gen_reloc disassembling
gives:
-- weak2.d --
00000000 <_sym1-0x2>:
0: 4e71 nop
00000002 <_sym1>:
2: 4e75 rts
4: 61ff ffff fffa bsrl 0 <_sym1-0x2> # 1.3
6: DISP32 _sym1
a: 4e71 nop
c: 610a bsrs 18 <_sym2>
e: 4e71 nop
10: 61ff ffff ffee bsrl 0 <_sym1-0x2> # 2.3
12: DISP32 _sym2
16: 4e71 nop
00000018 <_sym2>:
18: 4e75 rts
-- weak2.d --
Now the installed adjustments match with the corresponding
undef.d locations and the final link is correct.
Gunther
2010-09-02 Gunther Nikl <gnikl@users.sourceforge.net>
* gas/config/tc-m68k.c (tc_gen_reloc): Handle references to defined
weak symbols first if generating an a.out object.
Index: config/tc-m68k.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68k.c,v
retrieving revision 1.114
diff -u -p -u -p -r1.114 tc-m68k.c
--- config/tc-m68k.c 28 Jun 2010 14:06:57 -0000 1.114
+++ config/tc-m68k.c 2 Sep 2010 18:51:28 -0000
@@ -1335,9 +1335,7 @@ tc_gen_reloc (asection *section ATTRIBUT
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
#ifndef OBJ_ELF
- if (fixp->fx_pcrel)
- reloc->addend = fixp->fx_addnumber;
- else if (OUTPUT_FLAVOR == bfd_target_aout_flavour
+ if (OUTPUT_FLAVOR == bfd_target_aout_flavour
&& fixp->fx_addsy
&& S_IS_WEAK (fixp->fx_addsy)
&& ! bfd_is_und_section (S_GET_SEGMENT (fixp->fx_addsy)))
@@ -1364,6 +1362,8 @@ tc_gen_reloc (asection *section ATTRIBUT
- (S_GET_VALUE (fixp->fx_addsy)
+ S_GET_SEGMENT (fixp->fx_addsy)->vma);
}
+ else if (fixp->fx_pcrel)
+ reloc->addend = fixp->fx_addnumber;
else
reloc->addend = 0;
#else