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

Gaier, Bjoern via llvm-dev llvm-dev at lists.llvm.org
Thu May 9 04:21:53 PDT 2019


Hey Alex and Tim,

Seems like both ideas are way more complex and over my current abilities then I thought...
The basic idea behind this was to deal with references between two llvm::Modules. Normally I could link those cross references simply by adding both modules to the same ExecutionEngine. But I wondered if they could run in there own ExecutionEngines.

When the object file is generated both modules would miss the references to each other, but at this state I'm in a deadlock. Because none of the modules is resolved, I can't look up any address from the other module.
By using trampolines I could had provide the address for the trampoline and could had written the address the trampoline is pointing to, when both modules are done.

-----Original Message-----
From: Alex Denisov <1101.debian at gmail.com>
Sent: Donnerstag, 9. Mai 2019 12:22
To: Gaier, Bjoern <Bjoern.Gaier at horiba.com>
Cc: llvm-dev <llvm-dev at lists.llvm.org>
Subject: Re: [llvm-dev] Can I use the JIT interface to create trampolines? (For functions and global values)

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

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


More information about the llvm-dev mailing list