https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97908
Bug ID: 97908
Summary: Should _ZTI and _ZTS symbols be marked GNU_UNIQUE
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jengelh at inai dot de
Target Milestone: ---
» cat libx.cpp
#include <typeinfo>
class Foobar {};
extern "C" { const char *makename(); }
const char *makename() { Foobar f; return typeid(f).name(); }
» cat m.cpp
#include <cstdio>
#include <dlfcn.h>
int main()
{
auto hnd = dlopen("./libx.so", RTLD_NOW);
auto f = reinterpret_cast<const char *(*)()>(dlsym(hnd, "makename"));
auto name = f();
printf("%s\n", name);
dlclose(hnd);
printf("%s\n", name);
}
» g++-11 libx.cpp -shared -fPIC -ggdb3 -o libx.so; g++ m.cpp -fPIC -ggdb3 -Wall
-ldl
» ./a.out
6Foobar
Segmentation fault (core dumped)
» g++-11 -v
gcc version 11.0.0 20201112 (experimental) [revision
876b45db81a708616d70b1ab66b71bd503809c21] (SUSE Linux)
I do not know if this is even supposed to work. dlopen/dlclose is outside the
scope of the C++ standard, and POSIX (where dlopen comes from) does not mention
C++ during dlopen. However, this _alternate_ libx.cpp makes the program work:
#include <typeinfo>
struct Foobar { static constexpr char __tag[sizeof(std::type_info)] = { }; };
extern "C" { const char *makename(); }
const char *makename() { Foobar f; return typeid(f).name(); }
const char *helperfunc() { Foobar f; return f.__tag; }
__tag is emitted into the object file as a STB_GNU_UNIQUE symbol, which happens
to implicate RTLD_NODELETE for dlopen.
So, if __tag is getting the "unique" treatment to fulfill some guarantee,
should typeinfo variables (_ZTS* and _ZTI*) not get the same treatment, for the
same reasons?