[llvm-dev] Can I use the JIT interface to create trampolines? (For functions and global values)

Alex Denisov via llvm-dev llvm-dev at lists.llvm.org
Thu May 9 03:22:26 PDT 2019


Hi Björn,

No sure it exactly matches your issue, but we had a similar problem.

TL;DR: you can achieve this by manipulating IR and a little help from JIT.

Here is a high-level algorithm of what we did:

Created an external global variable (GlobalFunctionPointer) with the same type as the function (basically a function pointer).
Created a copy of the function, e.g. foobar -> foobar_copy.
Replace the body of the original function with something like this (pseudocode):

define foobar(a, b, c) {
  ptr = load @GlobalFunctionPointer
  call ptr(a, b, c)
}

Then, when you add your program into JIT you will hit the unresolved external symbol (GlobalFunctionPointer) that you should hook up to an address under your control:
Something like this:

SymbolInfo Resolver::findSymbol(const std::string &name) {
  if (name == "GlobalFunctionPointer") {
    return SymbolInfo((uint64_t)trampoline, JITSymbolFlags::Exported);
  }
  return SymbolInfo(nullptr);
}

Where the trampoline is a pointer, which can hold the address of a function you want to redirect your call to, e.g.:

uint64_t *trampoline = new uint64_t;
....
*trampoline = jit.getFunctionAddess("foobar_copy");

===

I hope it gives you an idea of how that can be done.

> On 9. May 2019, at 11:04, Gaier, Bjoern via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> Dear LLVM-Mailing list (again),
> 
> I still have another beginners question in my mind - thank you for your patience.
> 
> Again I was playing around, but this time with llvm::Function. In an older question I learned, that I can replace a llvm::Function directly with an address.
> 
> llvm::Function *function = mainModue->getFunction("puts");
> function->replaceAllUsesWith(
>                 llvm::ConstantExpr::getIntToPtr(
>                                 llvm::ConstantInt::get(llvm::IntegerType::get(context, 64), 0xF),
>                                 function->getType()
>                 )
> );
> With this code I 'overloaded' the function "puts" with the address 0xF - that is what I was taught and it is functional. I also noticed that you can do the same with a llvm::GlobalValue - as said I'm still a beginner.
> 
> Now I wonder can I replace the use of a specific function with the address of an address? (I think this is called a trampoline)
> In C++ I know that I could use a function pointer instead of a function call to achieve this.
> 
> So... Deriving from that knowledge I would have to create a function pointer with the same signature as the function I want to replace.
> Is this possible with the llvm JIT interface? Can I simply use that value in the "replaceAllUsesWith" function?
> And would the same technique also work with a llvm::GlobalValue?
> 
> Kind greetings and thank you for the help in advance
> Björn
> Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789 Geschäftsführer: Dr. Hiroshi Nakamura, Dr. Robert Plank, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima. Junichi Tajika _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: Message signed with OpenPGP
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190509/53e60d77/attachment.sig>


More information about the llvm-dev mailing list