[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