This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]