[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 04:37:35 PDT 2019


> Seems like both ideas are way more complex and over my current abilities then I thought...

I don't know the second idea, but in case of my example there is no issues with your abilities to understand/implement, but rather with my abilities to explain the idea.
Given what you have explained I would suggest you drawing the modules and connections between the functions and finding a way to connect them via trampolines and global variables.

> On 9. May 2019, at 13:21, Gaier, Bjoern <Bjoern.Gaier at horiba.com> wrote:
> 
> 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

-------------- 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/2031f6bb/attachment.sig>


More information about the llvm-dev mailing list