IA-32 gas _GLOBAL_OFFSET_TABLE_ handling bugs

Alan Modra amodra@bigpond.net.au
Wed Jul 31 18:12:00 GMT 2002


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



More information about the Binutils mailing list