samedi 26 mars 2016

Get vtable pointer for class without instance

I need to statically capture the vtable pointer for classes, and trying to think of tricks to solve this problem for each major compiler.

The ideal goal is that I could write something like this:

void **vtbl = GET_VTABLE(ClassName);

I managed to craft an MSVC solution:

#define STRINGIFY(Token) #Token
#define MSVC_MANGLE_VTABLE(Class) STRINGIFY(??_7##Class##@@6B@)
#define MSVC_VTABLE(Class) (__pragma(warning(suppress: 4483)) __identifier(MSVC_MANGLE_VTABLE(Class)))

Note: it took me quite a while to think of that stringification trick with the awkward MSVC mangled symbol name! ;)

Now I need a GCC solution, and I thought this would be easy, since their symbol names are valid C identifiers. I intended to approach it with a simple extern:

extern "C" void **_ZTV9ClassName;

Wrap that in a macro, done... except there's a problem; GCC mangled names follow the pattern #Name, where # is the number of characters in Name, ie, 4Name, or 9ClassName as I wrote above.

This seems to be a real problem... I can't think of any clever way to create a macro that can take a class name and produce that symbol name.

An alternative (and probably preferable) solution would be to find some expression within C++ to coerce GCC/Clang (either one) to emit the pointer in some way. I haven't been able to think of any such expression. Perhaps there is some GCC or Clang extension that can be used to coerce the compiler to emit with the pointer?

If anyone has any ideas to move forward on either approach, or some other creative ideas... I'm all ears!

Note, I'm happy to depend on C++11 features.

Edit: One extra thought, I have managed to fabricate the symbol name as a string with a template, but things like __attribute__(alias("name")) expects a literal, the template doesn't seem to work, even though it is resolved at compile time >_<

Aucun commentaire:

Enregistrer un commentaire