This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: sibcall vs PIC
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Fergus Henderson <fjh at cs dot mu dot OZ dot AU>
- Cc: gcc at gcc dot gnu dot org
- Date: Fri, 6 Sep 2002 00:45:13 +0200
- Subject: Re: sibcall vs PIC
- References: <20020905223814.GC13999@ceres.cs.mu.oz.au>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Fri, Sep 06, 2002 at 08:38:14AM +1000, Fergus Henderson wrote:
> Currently on x86 GCC does not do any sibling call optimization with -fpic.
> The source contains the following comment:
>
> "If PIC, we cannot make sibling calls to global
> functions because the PLT requires %ebx live."
>
> Could anyone elaborate on this comment?
> Why exactly does this prevents sibling calls?
If you have say:
int foo(void)
{
return bar() + 1;
}
in libfoo.so and
int baz(void)
{
return 23;
}
int bar(void)
{
return baz();
}
in libbar.so and say that libfoo.so _GLOBAL_OFFSET_TABLE_ is X and
libbar.so's is Y, then foo sets %ebx to X, calls bar through bar
PLT slot in libfoo.so. When no sibcall is in the game, bar saves a copy
of %ebx, sets %ebx to Y, does call baz through PLT slot in libbar.so,
when it returns bar() restores %ebx to X and returns.
Now for sibcall you'd need to restore %ebx to X before jumping
to baz PLT slot in libbar.so (or don't set %ebx at all), but IA-32 PLT
slot expect %ebx to contain GOT address of the DSO they are in,
so you'd call libbar.so's baz PLT slot with incorrect %ebx and die.
Jakub