cross platform - How to obtain a pointer out of a C++ vtable? -
say have c++ class like:
class foo { public: virtual ~foo() {} virtual dosomething() = 0; };
the c++ compiler translates call vtable lookup:
foo* foo; // translated c++ to: // foo->vtable->dosomething(foo); foo->dosomething();
suppose writing jit compiler , wanted obtain address of dosomething() function particular instance of class foo, can generate code jumps directly instead of doing table lookup , indirect branch.
my questions are:
is there standard c++ way (i'm sure answer no, wanted ask sake of completeness).
is there remotely compiler-independent way of doing this, library has implemented provides api accessing vtable?
i'm open hacks, if work. example, if created own derived class , determine address of dosomething method, assume vtable first (hidden) member of foo , search through vtable until find pointer value. however, don't know way of getting address: if write &derivedfoo::dosomething
pointer-to-member, totally different.
maybe turn pointer-to-member vtable offset. when compile following:
class foo { public: virtual ~foo() {} virtual void dosomething() = 0; }; void foo(foo *f, void (foo::*member)()) { (f->*member)(); }
on gcc/x86-64, assembly output:
disassembly of section .text: 0000000000000000 <_z3foop3fooms_fvve>: 0: 40 f6 c6 01 test sil,0x1 4: 48 89 74 24 e8 mov qword ptr [rsp-0x18],rsi 9: 48 89 54 24 f0 mov qword ptr [rsp-0x10],rdx e: 74 10 je 20 <_z3foop3fooms_fvve+0x20> 10: 48 01 d7 add rdi,rdx 13: 48 8b 07 mov rax,qword ptr [rdi] 16: 48 8b 74 30 ff mov rsi,qword ptr [rax+rsi*1-0x1] 1b: ff e6 jmp rsi 1d: 0f 1f 00 nop dword ptr [rax] 20: 48 01 d7 add rdi,rdx 23: ff e6 jmp rsi
i don't understand what's going on here, if reverse-engineer or use abi spec generate fragment above each separate platform, way of obtaining pointer out of vtable.
why think &derivedfoo::dosomething
different? isn't you're asking for? way think it, call derivedfoo::dosomething()
call same function, passing different pointer. vtable merely distinguishes between different types derived foo
, not instances.
Comments
Post a Comment