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]

[PATCH] MIPS gas: Fix broken relocation sorting


The problem here is that some explicit relocations were not getting sorted properly. The %got() and %lo() were being separated by another %got()/%lo() pair. This resulted in incorrect relocations being applied by the linker.

At first I thought this was a GCC bug, but Ian Lance Taylor set me straight here. For those interested, the GCC bug report is here:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29721

The root of the problem is that the relocations are against a local symbol in another section which get converted to relocations against the global section symbol. The relocation sorting was not done for relocations against global symbols.

There are as far as I can see two easy ways to fix it:

1) In mips_fix_adjustable, don't allow the conversion if it would affect a relocation that could possibly need sorting.

2) In mips_from_file, do the sorting with relocations against global symbols also.

I chose the second option, as it looked like the exclusion of global relocations from the sorting was probably just an optimization. The first option would result in many %got() relocations that have no corresponding %lo() not being converted to be against the section.

Tested with a mipsel-linux cross build with no regressions. A bootstrap of GCC 4.2 branch is underway, but test results will not be available for about 5 days.

OK to commit?

This bug causes bad code with both gcc-4.2 and the gcc trunk and perhaps any gcc with explicit relocs. Would it make sense to put this on the 2.17 branch and make a 2.17.1 release before gcc-4.2 is released?


gas: 2006-11-06 David Daney <ddaney@avtrex.com>

* config/tc-mips.c (mips_frob_file): Don't check for global symbol.

gas/testsuite:
2006-11-06  David Daney  <ddaney@avtrex.com>

	* gas/mips/elf-rel26.s: New test.
	* gas/mips/elf-rel26.d: Ditto.
	* gas/mips/mips.exp: Run it.
? doc/as.info
Index: config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.359
diff -c -p -r1.359 tc-mips.c
*** config/tc-mips.c	6 Nov 2006 14:28:21 -0000	1.359
--- config/tc-mips.c	7 Nov 2006 20:21:12 -0000
*************** mips_frob_file (void)
*** 11631,11642 ****
  
        assert (reloc_needs_lo_p (l->fixp->fx_r_type));
  
-       /* If a GOT16 relocation turns out to be against a global symbol,
- 	 there isn't supposed to be a matching LO.  */
-       if (l->fixp->fx_r_type == BFD_RELOC_MIPS_GOT16
- 	  && !pic_need_relax (l->fixp->fx_addsy, l->seg))
- 	continue;
- 
        /* Check quickly whether the next fixup happens to be a matching %lo.  */
        if (fixup_has_matching_lo_p (l->fixp))
  	continue;
--- 11631,11636 ----
Index: testsuite/gas/mips/elf-rel26.d
===================================================================
RCS file: testsuite/gas/mips/elf-rel26.d
diff -N testsuite/gas/mips/elf-rel26.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/mips/elf-rel26.d	7 Nov 2006 20:21:12 -0000
***************
*** 0 ****
--- 1,22 ----
+ #as: -mips32 -EL -KPIC
+ #readelf: --relocs
+ #name: MIPS ELF reloc 26
+ 
+ Relocation section '\.rel\.pdr' .*
+  *Offset.*
+ 00.*
+ 
+ Relocation section '\.rel\.text\.foo' at offset .* contains 11 entries:
+  *Offset * Info * Type * Sym\.Value * Sym\. Name
+ 0+000 * .+ * R_MIPS_HI16 * 0+0 * _gp_disp
+ 0+004 * .+ * R_MIPS_LO16 * 0+0 * _gp_disp
+ 0+014 * .+ * R_MIPS_GOT16 * 0+0 * \$LC28
+ 0+01c * .+ * R_MIPS_LO16 * 0+0 * \$LC28
+ 0+020 * .+ * R_MIPS_CALL16 * 0+0 * bar
+ 0+030 * .+ * R_MIPS_PC16 * 0+0 * \$L846
+ 0+034 * .+ * R_MIPS_GOT16 * 0+0 * \$LC27
+ 0+038 * .+ * R_MIPS_PC16 * 0+0 * \$L848
+ 0+048 * .+ * R_MIPS_PC16 * 0+0 * \$L925
+ 0+010 * .+ * R_MIPS_GOT16 * 0+0 * \.rodata\.foo
+ 0+05c * .+ * R_MIPS_LO16 * 0+0 * \.rodata\.foo
+ #pass
Index: testsuite/gas/mips/elf-rel26.s
===================================================================
RCS file: testsuite/gas/mips/elf-rel26.s
diff -N testsuite/gas/mips/elf-rel26.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gas/mips/elf-rel26.s	7 Nov 2006 20:21:12 -0000
***************
*** 0 ****
--- 1,62 ----
+ 	.section	.text.foo,"axG",@progbits,foo,comdat
+ 	.align	2
+ 	.weak	foo
+ 	.ent	foo
+ 	.type	foo, @function
+ foo:
+ $LFB308:
+ 	.frame	$fp,136,$31		# vars= 72, regs= 10/0, args= 16, gp= 8
+ 	.mask	0xc0ff0000,-4
+ 	.fmask	0x00000000,0
+ 	.set	noreorder
+ 	.cpload	$25
+ 
+ 	.set	nomacro
+ 	bne	$3,$0,$L924
+ 	lw	$25,%got($L874)($28)
+ 	.set	macro
+ 	.set	reorder
+ 	lw	$5,%got($LC28)($28)
+ 	lw	$4,136($fp)
+ 	addiu	$5,$5,%lo($LC28)
+ 	lw	$25,%call16(bar)($28)
+ 	.set	noreorder
+ 	.set	nomacro
+ 	jalr	$25
+ 	li	$6,-1			# 0xffffffffffffffff
+ 	.set	macro
+ 	.set	reorder
+ 	lw	$25,64($fp)
+ 	.set	noreorder
+ 	.set	nomacro
+ 	bne	$25,$0,$L846
+ 	lw	$5,%got($LC27)($28)
+ 	b	$L848
+ 	sw	$0,68($fp)
+ 	.set	macro
+ 	.set	reorder
+ $L920:
+ 	lb	$3,0($18)
+ 	li	$2,59			# 0x3b
+ 	.set	noreorder
+ 	.set	nomacro
+ 	beq	$3,$2,$L925
+ 	lw	$25,76($fp)
+ 	b	$L920
+ 	addiu	$18,$18,1
+ 	.set	macro
+ 	.set	reorder
+ 
+ $L924:
+ 	sll	$2,$2,2
+ 	addiu	$25,$25,%lo($L874)
+ 	addu	$2,$2,$25
+ 	lw	$3,0($2)
+ 	addu	$3,$3,$28
+ 	j	$3
+ 	.end foo
+ 	.section	.rodata.foo,"aG",@progbits,foo,comdat
+ 	.align	2
+ 	.align	2
+ $L874:
+ 	.gpword	$L924
Index: testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.125
diff -c -p -r1.125 mips.exp
*** testsuite/gas/mips/mips.exp	2 Nov 2006 15:20:31 -0000	1.125
--- testsuite/gas/mips/mips.exp	7 Nov 2006 20:21:12 -0000
*************** if { [istarget mips*-*-vxworks*] } {
*** 687,692 ****
--- 687,693 ----
  
  	run_dump_test "elf-rel25"
  	run_dump_test "elf-rel25a"
+ 	run_dump_test "elf-rel26"
  
  	if { !$no_mips16 } {
  	    run_dump_test "${tmips}mips${el}16-e"

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