Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The dudes from the LLVM mailing list were <a href="http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-June/032661.html" rel="nofollow noreferrer">helpful enough to provide a better solution</a>. They didn't say how to get the pointer from the method to the function, but I've already figured out this part so it's okay.</p> <p><strong>EDIT</strong> A clean way to do this is simply to wrap your method into a function:</p> <pre><code>int Foo_Bar(Foo* foo) { return foo-&gt;bar(); } </code></pre> <p>Then use <code>Foo_Bar</code>'s address instead of trying to get <code>Foo::bar</code>'s. Use <code>llvm::ExecutionEngine::addGlobalMapping</code> to add the mapping as shown below.</p> <p>As usual, the simplest solution has some interesting benefits. For instance, it works with virtual functions without a hiccup. (But it's so much less entertaining. The rest of the answer is kept for historical purposes, mainly because I had a lot of fun poking at the internals of my C++ runtime. Also note that it's non-portable.)</p> <hr> <p>You'll need something along these lines to figure the address of a method (be warned, that's a dirty hack that probably will only be compatible with the Itanium ABI):</p> <pre><code>template&lt;typename T&gt; const void* void_cast(const T&amp; object) { union Retyper { const T object; void* pointer; Retyper(T obj) : object(obj) { } }; return Retyper(object).pointer; } template&lt;typename T, typename M&gt; const void* getMethodPointer(const T* object, M method) // will work for virtual methods { union MethodEntry { intptr_t offset; void* function; }; const MethodEntry* entry = static_cast&lt;const MethodEntry*&gt;(void_cast(&amp;method)); if (entry-&gt;offset % sizeof(intptr_t) == 0) // looks like that's how the runtime guesses virtual from static return getMethodPointer(method); const void* const* const vtable = *reinterpret_cast&lt;const void* const* const* const&gt;(object); return vtable[(entry-&gt;offset - 1) / sizeof(void*)]; } template&lt;typename M&gt; const void* getMethodPointer(M method) // will only work with non-virtual methods { union MethodEntry { intptr_t offset; void* function; }; return static_cast&lt;const MethodEntry*&gt;(void_cast(&amp;method))-&gt;function; } </code></pre> <p>Then use <code>llvm::ExecutionEngine::addGlobalMapping</code> to map a function to the address you've gotten. To call it, pass it your object as the first parameter, and the rest as usual. Here's a quick example.</p> <pre><code>class Foo { void Bar(); virtual void Baz(); }; class FooFoo : public Foo { virtual void Baz(); }; Foo* foo = new FooFoo; const void* barMethodPointer = getMethodPointer(&amp;Foo::Bar); const void* bazMethodPointer = getMethodPointer(foo, &amp;Foo::Baz); // will get FooFoo::Baz llvm::ExecutionEngine* engine = llvm::EngineBuilder(module).Create(); llvm::Function* bar = llvm::Function::Create(/* function type */, Function::ExternalLinkage, "foo", module); llvm::Function* baz = llvm::Function::Create(/* function type */, Function::ExternalLinkage, "baz", module); engine-&gt;addGlobalMapping(bar, const_cast&lt;void*&gt;(barMethodPointer)); // LLVM always takes non-const pointers engine-&gt;addGlobalMapping(baz, const_cast&lt;void*&gt;(bazMethodPointer)); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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