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. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils