This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Using the PLT for vtables (or not)
On Fri, Dec 05, 2003 at 02:14:36AM -0800, Brian Ryner wrote:
> Jakub Jelinek wrote:
> >Actually this is not completely true.
> >Pointers in vtables normally resolve to:
> >a) the actual method in the binary if it has been linked into the binary
> >b) to the PLT slot in the binary if it was not linked into the binary
> > but is referenced from the binary
>
> Just trying to clarify a bit -- by "referenced from the binary", do you
> mean:
>
> class A { virtual void Foo(); };
> A a;
> a.Foo();
This one is a call to _ZN1A3FooEv (on IA-32 R_386_PC32 reloc).
With older binutils, this acts as any other reference in the binary
and thus, although _ZN1A3FooEv is not defined in the binary, the
SHN_UNDEF _ZN1A3FooEv symbol has non-zero st_value pointing to the
PLT slot. With CVS binutils this doesn't happen.
> or do you mean calling through the vtable:
>
> A *a;
> a->Foo();
This doesn't count as any reference from the binary to _ZN1A3FooEv.
The compiler doesn't output the A's virtual table (_ZTV1A) into test1.o
at all. It happens to be in the binary as COPY reloc because of the
_ZTV1A pointer being used, but e.g. in the shared library you'd just
have a _ZTV1A relocation in GOT.
By reference from the binary other than call I mean something like:
#include "foo.h"
void func(A *a)
{
a->Foo();
}
class B : public A {};
int main(int argc, char **argv)
{
A a;
B b;
func(&a);
func(&b);
return 0;
}
where although A's virtual table is not output into test3.o, B's vtable
(_ZTV1B) is and it contains _ZN1A3FooEv.
In this case, the _ZTV1A virtual table (in the shared library and after the
copy relocation is resolved also in the binary) will unnecessarily point to
the _ZN1A3FooEv PLT slot (which could be fixed by adding a new relocation
R_386_32V or whatever) or by hacking up linker to treat
.gnu.linkonce.[dr]._ZTV* relocations specially (probably not a good idea).
The other thing I talked about is whether _ZTV1B's pointer to _ZN1A3FooEv
should resolve to the PLT slot in the binary or a new dynamic relocation
should be added. In the above exact case adding a dynamic relocation
for _ZTV1B's _ZN1A3FooEv would mean the PLT slot can go away and
R_386_JMP_SLOT reloc as well, but already when you add func2 as you had
in your test2 case PLT would need to stay.
> One more question -- does any of this change if the "binary" is a DSO
> which links against the original DSO?
This doesn't change just with -fpic. But if the binary is a DSO
(whether PIE or you have echo '' | g++ -xc - ... binary and link the
testX.cpp into a new shared library) then there is no such thing
as jumping through PLT unnecessarily.
Jakub