This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: IA-32 gas _GLOBAL_OFFSET_TABLE_ handling bugs
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: binutils at sources dot redhat dot com, roland at redhat dot com
- Date: Thu, 1 Aug 2002 10:26:32 +0930
- Subject: Re: IA-32 gas _GLOBAL_OFFSET_TABLE_ handling bugs
- References: <20020731152058.M20867@sunsite.ms.mff.cuni.cz>
On Wed, Jul 31, 2002 at 03:20:58PM +0200, Jakub Jelinek wrote:
> Hi!
>
> Roland noticed that gas doesn't handle
> addl $_GLOBAL_OFFSET_TABLE_+[.-test], %eax
> correctly (unlike with any other register), which is very bad, as either
> with TLS, or gcc 3.3+ gcc can use any register for PIC pointer if no PLT
> calls are made, including %eax (in which case the insn is one byte shorter).
>
> The problem is that . here is computed from start of instruction (and thus
Well, that is the standard meaning of `.'!
The underlying confusion here is really that in
call L1
L1:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-L1],%ebx
we want the `.' in "$_GLOBAL_OFFSET_TABLE_+[.-L1]" to mean something
quite different from its standard meaning. It's a very poor choice of
syntax, but I guess we're stuck with it.
> _GLOBAL_OFFSET_TABLE_ is considered relative to start of the instruction
> too), but gas hardcodes this difference as 2 (well, another question is why
> it first does += 3 and later on in another routine subtracts one).
The md_apply_fix3 fudge ought to go, I think, and the commentary could
move to wherever you end up adding your code to adjust the expression.
> The following patch tries to deal with this, unfortunately I'm not sure
> what should actually happen when _GLOBAL_OFFSET_TABLE_ is present in the
> displacement, not immediate and also what should happen if
> _GLOBAL_OFFSET_TABLE_ is mentioned outside of the instruction (ie. in .long
> etc.).
> Current gas behaviour is that for
> movl $1234, _GLOBAL_OFFSET_TABLE_
> it creates R_386_GOTPC relocation without any adjustement, ie.
> addl $_GLOBAL_OFFSET_TABLE_+[.-test], %ebx
> does a different thing than
> leal _GLOBAL_OFFSET_TABLE_+[.-test](%ebx), %ebx
> (in the latter case %ebx will be %ebx in the former - 2).
> Should it match the immediate behaviour (ie. does output_disp need to be
> modified)? Or should it forget about special meaning
> of _GLOBAL_OFFSET_TABLE_ in that case?
>
> What's your preference?
I reckon it should behave the same as the immediate case. ie. do the
adjustments to the offset in output_insn.
Thanks for looking into this problem!
--
Alan Modra
IBM OzLabs - Linux Technology Centre