This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] MIPS gas: Fix broken relocation sorting
- From: Richard Sandiford <richard at codesourcery dot com>
- To: David Daney <ddaney at avtrex dot com>
- Cc: binutils at sourceware dot org
- Date: Tue, 07 Nov 2006 21:26:15 +0000
- Subject: Re: [PATCH] MIPS gas: Fix broken relocation sorting
- References: <4550F1D3.70705@avtrex.com>
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.
Richard