[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