Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to obtain a pointer out of a C++ vtable?
    primarykey
    data
    text
    <p>Say you have a C++ class like:</p> <pre><code>class Foo { public: virtual ~Foo() {} virtual DoSomething() = 0; }; </code></pre> <p>The C++ compiler translates a call into a vtable lookup:</p> <pre><code>Foo* foo; // Translated by C++ to: // foo-&gt;vtable-&gt;DoSomething(foo); foo-&gt;DoSomething(); </code></pre> <p>Suppose I was writing a JIT compiler and I wanted to obtain the address of the DoSomething() function for a particular instance of class Foo, so I can generate code that jumps to it directly instead of doing a table lookup and an indirect branch.</p> <p>My questions are:</p> <ol> <li><p>Is there any standard C++ way to do this (I'm almost sure the answer is no, but wanted to ask for the sake of completeness).</p></li> <li><p>Is there any remotely compiler-independent way of doing this, like a library someone has implemented that provides an API for accessing a vtable?</p></li> </ol> <p>I'm open completely to hacks, if they will work. For example, if I created my own derived class and could determine the address of its DoSomething method, I could assume that the vtable is the first (hidden) member of Foo and search through its vtable until I find my pointer value. However, I don't know a way of getting this address: if I write <code>&amp;DerivedFoo::DoSomething</code> I get a pointer-to-member, which is something totally different.</p> <p>Maybe I could turn the pointer-to-member into the vtable offset. When I compile the following:</p> <pre><code>class Foo { public: virtual ~Foo() {} virtual void DoSomething() = 0; }; void foo(Foo *f, void (Foo::*member)()) { (f-&gt;*member)(); } </code></pre> <p>On GCC/x86-64, I get this assembly output:</p> <pre><code>Disassembly of section .text: 0000000000000000 &lt;_Z3fooP3FooMS_FvvE&gt;: 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 &lt;_Z3fooP3FooMS_FvvE+0x20&gt; 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 </code></pre> <p>I don't fully understand what's going on here, but if I could reverse-engineer this or use an ABI spec I could generate a fragment like the above for each separate platform, as a way of obtaining a pointer out of a vtable.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload