Gaier, Bjoern via llvm-dev
2018-Aug-29 05:38 UTC
[llvm-dev] JIT client - late cross references
Hello Lang, thank you for your response! So the use case would be some kind of wrapping or just taking control. Taking that Module 'A' has function a() and Module 'B' has function b() and c() - also a() calls b(). The normal resolving process would resolve the function call correct. But for some reason (like having a wrapper) I would prefer to resolve calls to b() with a call to c(), but only for module 'A'. For my own hobby-project I tried working with custom section names. When I came to allocating the memory for these sections I just kept the address and used it. Would this be suitable way too? That I allocate 'points of interest' in their own sections and keep the address? Or could it happen that these sections merge into one? Would this have negative consequences? Like using more memory or so? Kind greetings Björn From: Lang Hames <lhames at gmail.com> Sent: Dienstag, 21. August 2018 17:49 To: Gaier, Bjoern <Bjoern.Gaier at horiba.com> Cc: LLVM Developers Mailing List <llvm-dev at lists.llvm.org> Subject: Re: [llvm-dev] JIT client - late cross references Hi Bjoern, I do not think there is any practical way to do this yourself, short of writing your own RuntimeDyld implementation. The reason is that you cannot resolve a symbol to an address until you have compiled it down to an object file, but in the case of circular reference you would need to compile both IR Modules to object files before either could be patched up, and by that stage it is too late to patch either up at the IR level. What is the use case for trying to resolve these references yourself, rather than letting RuntimeDyld do it for you? Cheers, Lang. On Mon, Aug 6, 2018 at 4:20 AM Gaier, Bjoern via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: Hello everyone, I'm still a beginner with the LLVM and the process of jitting a BC file at runtime as a JIT client - but I'm really interested into this subject. In my current use case I have two BC files which have cross references to each other, normally I could just add them both to the llvm::ExecutionEngine and they will be resolved. But I would like to resolve these cross references by myself, through the llvm::JITSymbolResolver but I see no way for this, since both files references each other. If I jit A, it will reach the undefined function from file B. So at this point I would have to jit B, but B references a function from A, which isn't completely resolved yet. Is there a way to get the addresses of the functions before the jit process is completed? Maybe via the section addresses and some kind of offset or so? Thank you for any response! Kind greetings Björn _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180829/0cd1dd61/attachment.html>
Alex Denisov via llvm-dev
2018-Aug-29 08:39 UTC
[llvm-dev] JIT client - late cross references
Hi Björn, Not sure if I got it right, but I hope it gives you a hint. Assuming that you have the following setup: Module A has function a() Module B has function b() a() calls b() You are loading only module A, but it fails because it cannot resolve function b(), right? If so, then you can try this approach: Create a global variable in the module A of type "pointer to b()" named, e.g., b_trampoline. Replace call instruction with the load+call instructions, as described in pseudocode: Before: declare b(...) define a(): { ... call b(%1, %2, %3) ... } After: @b_trampoline = <pointer to b()> declare b(...) define a(): { ... %ptr = load @b_trampoline call %ptr(%1, %2, %3) ... } Then, when you load module A SymbolResolver will ask for an address of b_trampoline, you can give back an address of a heap-allocated storage, i.e.: ... uint64_t *trampolineStorage = new uint64_t; ... SymbolResolver::findSymbol(const std::string &name) { if (name == "b_trampoline") { JITSymbolInfo((uint64_t) trampolineStorage, JITSymbolFlags::Exported) } ... } Later on, when everything is loaded and you are ready to execute JITed code you can fill in the trampolineStorage with the actual address, i.e.: *trampolineStorage = jit.getSymbol("b").getAddress(); That should do the trick. I still hope I got your problem right and it helps ;) Cheers, Alex.> On 29. Aug 2018, at 07:38, Gaier, Bjoern via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hello Lang, > > thank you for your response! > > So the use case would be some kind of wrapping or just taking control. > Taking that Module 'A' has function a() and Module 'B' has function b() and c() - also a() calls b(). > The normal resolving process would resolve the function call correct. But for some reason (like having a wrapper) I would prefer to resolve calls to b() with a call to c(), but only for module 'A'. > > For my own hobby-project I tried working with custom section names. When I came to allocating the memory for these sections I just kept the address and used it. Would this be suitable way too? That I allocate 'points of interest' in their own sections and keep the address? Or could it happen that these sections merge into one? Would this have negative consequences? Like using more memory or so? > > Kind greetings > Björn > > From: Lang Hames <lhames at gmail.com> > Sent: Dienstag, 21. August 2018 17:49 > To: Gaier, Bjoern <Bjoern.Gaier at horiba.com> > Cc: LLVM Developers Mailing List <llvm-dev at lists.llvm.org> > Subject: Re: [llvm-dev] JIT client - late cross references > > Hi Bjoern, > > I do not think there is any practical way to do this yourself, short of writing your own RuntimeDyld implementation. > > The reason is that you cannot resolve a symbol to an address until you have compiled it down to an object file, but in the case of circular reference you would need to compile both IR Modules to object files before either could be patched up, and by that stage it is too late to patch either up at the IR level. > > What is the use case for trying to resolve these references yourself, rather than letting RuntimeDyld do it for you? > > Cheers, > Lang. > > On Mon, Aug 6, 2018 at 4:20 AM Gaier, Bjoern via llvm-dev <llvm-dev at lists.llvm.org> wrote: > Hello everyone, > > I'm still a beginner with the LLVM and the process of jitting a BC file at runtime as a JIT client - but I'm really interested into this subject. > > In my current use case I have two BC files which have cross references to each other, normally I could just add them both to the llvm::ExecutionEngine and they will be resolved. > But I would like to resolve these cross references by myself, through the llvm::JITSymbolResolver but I see no way for this, since both files references each other. > > If I jit A, it will reach the undefined function from file B. So at this point I would have to jit B, but B references a function from A, which isn't completely resolved yet. > Is there a way to get the addresses of the functions before the jit process is completed? Maybe via the section addresses and some kind of offset or so? > > Thank you for any response! > > Kind greetings > Björn > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- AlexDenisov Software Engineer, https://lowlevelbits.org -------------- 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/20180829/7de0f6e1/attachment-0001.sig>
Gaier, Bjoern via llvm-dev
2018-Aug-29 14:22 UTC
[llvm-dev] JIT client - late cross references
Hello Alex, This is an interesting approach! Thank you for that! I understand the basic idea but sadly... My skills in handling the IR are not very high, so I can't imagine where and when to replace the calls to b() with the trampoline. The only thing I can handle would be creating that trampoline variable. Also will this approach be a problem for really time critical tasks? Since I replace the call to an address ( b() ) with an call to a function pointer? Kind greetings Björn -----Original Message----- From: Alex Denisov <1101.debian at gmail.com> Sent: Mittwoch, 29. August 2018 10:40 To: Gaier, Bjoern <Bjoern.Gaier at horiba.com> Cc: Lang Hames <lhames at gmail.com>; LLVM Developers Mailing List <llvm-dev at lists.llvm.org> Subject: Re: [llvm-dev] JIT client - late cross references Hi Björn, Not sure if I got it right, but I hope it gives you a hint. Assuming that you have the following setup: Module A has function a() Module B has function b() a() calls b() You are loading only module A, but it fails because it cannot resolve function b(), right? If so, then you can try this approach: Create a global variable in the module A of type "pointer to b()" named, e.g., b_trampoline. Replace call instruction with the load+call instructions, as described in pseudocode: Before: declare b(...) define a(): { ... call b(%1, %2, %3) ... } After: @b_trampoline = <pointer to b()> declare b(...) define a(): { ... %ptr = load @b_trampoline call %ptr(%1, %2, %3) ... } Then, when you load module A SymbolResolver will ask for an address of b_trampoline, you can give back an address of a heap-allocated storage, i.e.: ... uint64_t *trampolineStorage = new uint64_t; ... SymbolResolver::findSymbol(const std::string &name) { if (name == "b_trampoline") { JITSymbolInfo((uint64_t) trampolineStorage, JITSymbolFlags::Exported) } ... } Later on, when everything is loaded and you are ready to execute JITed code you can fill in the trampolineStorage with the actual address, i.e.: *trampolineStorage = jit.getSymbol("b").getAddress(); That should do the trick. I still hope I got your problem right and it helps ;) Cheers, Alex.> On 29. Aug 2018, at 07:38, Gaier, Bjoern via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hello Lang, > > thank you for your response! > > So the use case would be some kind of wrapping or just taking control. > Taking that Module 'A' has function a() and Module 'B' has function b() and c() - also a() calls b(). > The normal resolving process would resolve the function call correct. But for some reason (like having a wrapper) I would prefer to resolve calls to b() with a call to c(), but only for module 'A'. > > For my own hobby-project I tried working with custom section names. When I came to allocating the memory for these sections I just kept the address and used it. Would this be suitable way too? That I allocate 'points of interest' in their own sections and keep the address? Or could it happen that these sections merge into one? Would this have negative consequences? Like using more memory or so? > > Kind greetings > Björn > > From: Lang Hames <lhames at gmail.com> > Sent: Dienstag, 21. August 2018 17:49 > To: Gaier, Bjoern <Bjoern.Gaier at horiba.com> > Cc: LLVM Developers Mailing List <llvm-dev at lists.llvm.org> > Subject: Re: [llvm-dev] JIT client - late cross references > > Hi Bjoern, > > I do not think there is any practical way to do this yourself, short of writing your own RuntimeDyld implementation. > > The reason is that you cannot resolve a symbol to an address until you have compiled it down to an object file, but in the case of circular reference you would need to compile both IR Modules to object files before either could be patched up, and by that stage it is too late to patch either up at the IR level. > > What is the use case for trying to resolve these references yourself, rather than letting RuntimeDyld do it for you? > > Cheers, > Lang. > > On Mon, Aug 6, 2018 at 4:20 AM Gaier, Bjoern via llvm-dev <llvm-dev at lists.llvm.org> wrote: > Hello everyone, > > I'm still a beginner with the LLVM and the process of jitting a BC file at runtime as a JIT client - but I'm really interested into this subject. > > In my current use case I have two BC files which have cross references to each other, normally I could just add them both to the llvm::ExecutionEngine and they will be resolved. > But I would like to resolve these cross references by myself, through the llvm::JITSymbolResolver but I see no way for this, since both files references each other. > > If I jit A, it will reach the undefined function from file B. So at this point I would have to jit B, but B references a function from A, which isn't completely resolved yet. > Is there a way to get the addresses of the functions before the jit process is completed? Maybe via the section addresses and some kind of offset or so? > > Thank you for any response! > > Kind greetings > Björn > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- AlexDenisov Software Engineer, https://lowlevelbits.org