[PATCH] MIPS gas: Fix broken relocation sorting

Richard Sandiford richard@codesourcery.com
Tue Nov 7 21:26:00 GMT 2006

David Daney <ddaney@avtrex.com> writes:
> 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.

The section symbol is local, not global.  The bug appears to be
that pic_need_relax doesn't realise this.

> 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.

It isn't just an optimisation.  This is one of the nasty warts of
the 32-bit ABI: the meaning of an R_MIPS_GOT16 relocation depends
on whether the symbol is STB_LOCAL.  If the symbol is STB_LOCAL,
the relocation gives the address of the 64k page that contains
the symbol, and you need to add the associated R_MIPS_LO16 to
get the symbol's value.  If the symbol is not STB_LOCAL,
R_MIPS_GOT16 gives the symbol's value up-front.

Thus if we were indeed converting R_MIPS_GOT16 relocations against
local symbols into R_MIPS_GOT16 relocations against global symbols,
(1) would be the right fix.  But like I say, the bug appears at
first glance to be in pic_need_relax.


More information about the Binutils mailing list