[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/10326] New: globbing in linker script doesn't match C++ vtable/t
From: |
thiago at kde dot org |
Subject: |
[Bug ld/10326] New: globbing in linker script doesn't match C++ vtable/typeinfo/etc. |
Date: |
24 Jun 2009 13:27:54 -0000 |
When writing a linker script to control the versioning/exporting/unexporting of
C++ symbols, the globbing provided in the linker script doesn't match some of
the automatically-generated symbols by the C++ ABI. I have noticed that this
applies to the vtable, the VTT, construction vtables, typeinfo, typeinfo names
and all manners of thunks.
Suppose the following code:
$ cat a.cpp
struct Padding { virtual ~Padding() {} };
struct PublicA
{
virtual ~PublicA();
virtual PublicA *a();
};
struct PublicB: Padding, PublicA
{
virtual PublicB *a();
};
struct PublicC: virtual PublicA
{
virtual PublicC *a();
};
PublicA::~PublicA() { }
PublicA *PublicA::a() { return 0; }
PublicB *PublicB::a() { return 0; }
PublicC *PublicC::a() { return 0; }
If we compile it into a shared library:
$ g++ -shared -o a.so a.cpp
The dynamic symbol table will be like this:
$ paste <(nm -D --defined a.so) <(nm -DC --defined a.so | cut -b11-) | grep
Public
00000cee T _ZN7PublicA1aEv PublicA::a()
00000cc8 T _ZN7PublicAD0Ev PublicA::~PublicA()
00000ca2 T _ZN7PublicAD1Ev PublicA::~PublicA()
00000c7c T _ZN7PublicAD2Ev PublicA::~PublicA()
00000d00 T _ZN7PublicB1aEv PublicB::a()
00000ef0 W _ZN7PublicBD0Ev PublicB::~PublicB()
00000ea0 W _ZN7PublicBD1Ev PublicB::~PublicB()
00000d1a T _ZN7PublicC1aEv PublicC::a()
00000e4c W _ZN7PublicCD0Ev PublicC::~PublicC()
00000df0 W _ZN7PublicCD1Ev PublicC::~PublicC()
0000108c V _ZTI7PublicA typeinfo for PublicA
00001060 V _ZTI7PublicB typeinfo for PublicB
00001030 V _ZTI7PublicC typeinfo for PublicC
00001094 V _ZTS7PublicA typeinfo name for PublicA
00001080 V _ZTS7PublicB typeinfo name for PublicB
00001048 V _ZTS7PublicC typeinfo name for PublicC
00000fc8 V _ZTT7PublicC VTT for PublicC
00001008 V _ZTV7PublicA vtable for PublicA
00000fe0 V _ZTV7PublicB vtable for PublicB
00000fa0 V _ZTV7PublicC vtable for PublicC
00000d4d T _ZTch0_h4_N7PublicB1aEv covariant return thunk to PublicB::a()
00000d24 T _ZTch0_v0_n20_N7PublicC1aEv covariant return thunk to PublicC::a()
00000cf8 T _ZTchn4_h4_N7PublicB1aEv covariant return thunk to PublicB::a()
00000d0a T _ZTcv0_n16_v0_n20_N7PublicC1aEv covariant return thunk to
PublicC::a()
00000ee8 W _ZThn4_N7PublicBD0Ev non-virtual thunk to PublicB::~PublicB()
00000e98 W _ZThn4_N7PublicBD1Ev non-virtual thunk to PublicB::~PublicB()
00000e3c W _ZTv0_n12_N7PublicCD0Ev virtual thunk to PublicC::~PublicC()
00000de0 W _ZTv0_n12_N7PublicCD1Ev virtual thunk to PublicC::~PublicC()
Now suppose we use a linker script to hide the internal symbols in our library,
but export only those that we want to:
$ cat a.script
VERSION {
{
global: extern "C++" { Public*; };
local: *;
};
}
If we compile it:
$ g++ -shared -o a.so a.cpp a.script
The symbol table is:
$ paste <(nm -D --defined a.so) <(nm -DC --defined a.so | cut -b11-) | grep
Public
000007fe T _ZN7PublicA1aEv PublicA::a()
000007d8 T _ZN7PublicAD0Ev PublicA::~PublicA()
000007b2 T _ZN7PublicAD1Ev PublicA::~PublicA()
0000078c T _ZN7PublicAD2Ev PublicA::~PublicA()
00000810 T _ZN7PublicB1aEv PublicB::a()
00000a00 W _ZN7PublicBD0Ev PublicB::~PublicB()
000009b0 W _ZN7PublicBD1Ev PublicB::~PublicB()
0000082a T _ZN7PublicC1aEv PublicC::a()
0000095c W _ZN7PublicCD0Ev PublicC::~PublicC()
00000900 W _ZN7PublicCD1Ev PublicC::~PublicC()
To export those symbols, I am forced to know of their existence and the
mangling that they acquire. And it's not possible to match them effectively
with simple globbing (regexp would be necessary at least). And note that spaces
in symbol names are also not possible to match without wildcards in the linker
scripts, which makes it impossible to match " for Public*" reliably.
One way I can think of to solve this problem would be to change the demangling
(the pretty name) of those symbols to place the class name leftmost. For
example:
0000108c V _ZTI7PublicA PublicA::.typeinfo
00001060 V _ZTI7PublicB PublicB::.typeinfo
00001030 V _ZTI7PublicC PublicC::.typeinfo
00001094 V _ZTS7PublicA PublicA::.typeinfo name
00001080 V _ZTS7PublicB PublicB::.typeinfo name
00001048 V _ZTS7PublicC PublicC::.typeinfo name
00000fc8 V _ZTT7PublicC PublicC::.VTT
00001008 V _ZTV7PublicA PublicA::.vtable
00000fe0 V _ZTV7PublicB PublicB::.vtable
00000fa0 V _ZTV7PublicC PublicC::.vtable
00000d4d T _ZTch0_h4_N7PublicB1aEv PublicB::a() [covariant return thunk]
00000d24 T _ZTch0_v0_n20_N7PublicC1aEv PublicC::a() [covariant return thunk]
00000cf8 T _ZTchn4_h4_N7PublicB1aEv PublicB::a() [covariant return thunk]
00000d0a T _ZTcv0_n16_v0_n20_N7PublicC1aEv PublicC::a() [covariant return
thunk]
00000ee8 W _ZThn4_N7PublicBD0Ev PublicB::~PublicB() [non-virtual thunk]
00000e98 W _ZThn4_N7PublicBD1Ev PublicB::~PublicB() [non-virtual thunk]
00000e3c W _ZTv0_n12_N7PublicCD0Ev PublicC::~PublicC() [virtual thunk]
00000de0 W _ZTv0_n12_N7PublicCD1Ev PublicC::~PublicC() [virtual thunk]
(For the thunks, it may be a good idea to match to the base encoding, so that
exporting "PublicC::a()" exports all thunks associated with it)
--
Summary: globbing in linker script doesn't match C++
vtable/typeinfo/etc.
Product: binutils
Version: 2.19
Status: NEW
Severity: normal
Priority: P2
Component: ld
AssignedTo: unassigned at sources dot redhat dot com
ReportedBy: thiago at kde dot org
CC: bug-binutils at gnu dot org
GCC build triplet: i586-manbo-linux-gnu
GCC host triplet: i586-manbo-linux-gnu
GCC target triplet: i586-manbo-linux-gnu
http://sourceware.org/bugzilla/show_bug.cgi?id=10326
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Bug ld/10326] New: globbing in linker script doesn't match C++ vtable/typeinfo/etc.,
thiago at kde dot org <=