via llvm-dev
2018-Feb-20 09:42 UTC
[llvm-dev] Calling virtual elf functions under windows -> Adding ASM code
Still no progress with this problem. Only that non-member functions seems to be working... Also: Even when I set the target triple of the Module (when the file was parsed at runtime) to "COFF" nothing changes... From: Bjoern Gaier/HE/HORIBA To: llvm-dev at lists.llvm.org Cc: cfe-dev at lists.llvm.org Date: 08.02.2018 12:28 Subject: Re: Calling virtual elf functions under windows -> Adding ASM code Hello everyone, I'm sorry for "flooding" your inbox, but I wanted to extend my message which is shown below. The problem is still not solved and I'm more confused then before. I compiled the code - the one seen in the pictures to elf bc and to msvc (pecoff) bc. Then I used llc to generate assembler output. In my opinion the involved functions are acting exactly the same. There are only some registers swapped. I should mention: when using the msvc bc code, then the calls via the interface are working. I attach the assembly code of the involved code to. Could please anyone explain me the difference, which could cause the crash? Kind regards Björn From: Bjoern Gaier/HE/HORIBA To: llvm-dev at lists.llvm.org, cfe-dev at lists.llvm.org Date: 07.02.2018 11:47 Subject: Calling virtual elf functions under windows Hello everyone reading this, I'm totally confused and need an explanation. I'm also not sure if it's a clang or a LLVM subject. I'm working with Visual Studio 2015, LLVM 5.0.1 and Windows 7 64bit. I have a simple project. With 2 Header files and 1 cpp file. "Interface.h" This file defines a simple class with two pure virtual member functions. "SimpleResult.h" This file defines a struct holding an integer "CM_Elf.cpp" This file defines a class (CM_Elf) implementing the interface from Interface.h Also there is an instance of the class (named "elf"). I compile the CM_Elf.cpp to a CM_Elf.bc file via clang-cl but with target "x86_64-pc-windows-elf" In another application I use LLVM to parse the BC file and use the ExecutionEngine to get some addresses. What I want to archive is: I want to call the implemented member functions of "elf". 1.) I execute all the global constructors collected by the ExecutionEngine -> The constructor of elf gets called 2.) I use ExecutionEngine to get the address of "elf" 3.) I use the interface to execute Interface::init -> Init gets called 4.) I use the interface to execute Interface::shutdown -> CRASH! When I swap the calls to init and shutdown, then everything works. So the virtual call to init seems to corrupt my stack - maybe it's the return value. Could it be a calling convention problem? But my target is still "windows" only msvc changed to elf... When I compile CM_Elf for target "x86_64-pc-windows-msvc19.0.24215" then it works. When I get the address of CM_Elf::init and CM_Elf::shutdown via the ExecutionEngine and call them without using the virtual table, then again everything works. SO! Is it not possible to call virtual elf functions via there interface? But why does normal functions work? Also I reach the functions which are stored in the vTable of CM_Elf so the vTable is correct. I append some pictures of the code... I hope someone could help me with this. Kind regards 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, Hiroshi Kawamura, Takashi Nagano, Takeshi Fukushima. 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, Hiroshi Kawamura, Takashi Nagano, Takeshi Fukushima. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180220/9a231949/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: asmELF.s Type: application/octet-stream Size: 1428 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180220/9a231949/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: asmMSVC.s Type: application/octet-stream Size: 2371 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180220/9a231949/attachment-0001.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: Calling.PNG Type: image/png Size: 14041 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180220/9a231949/attachment.png> -------------- next part -------------- A non-text attachment was scrubbed... Name: CM_Elf_cpp.PNG Type: image/png Size: 12189 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180220/9a231949/attachment-0001.png> -------------- next part -------------- A non-text attachment was scrubbed... Name: Interface_H.PNG Type: image/png Size: 2895 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180220/9a231949/attachment-0002.png> -------------- next part -------------- A non-text attachment was scrubbed... Name: SimpleResult_H.PNG Type: image/png Size: 5952 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180220/9a231949/attachment-0003.png>
Lang Hames via llvm-dev
2018-Feb-21 21:36 UTC
[llvm-dev] [cfe-dev] Calling virtual elf functions under windows -> Adding ASM code
Hi Bjoern, It looks like you are casting a regular function pointer (returned from getFunctionAddress) to a virtual method pointer. This is undefined behavior. The easiest way to achieve the effect you want would be to add a trampoline to your source (or at the IR level): extern "C" SimpleResult call_Interface_init(Interface *Instance) { return Instance->init(); } Then you can just use: auto CallInit (SimpleResult(*)(Interface*))engine->getFunctionAddress("call_Interface_init"); CallInit(inter); Cheers, Lang. On Tue, Feb 20, 2018 at 1:42 AM, via cfe-dev <cfe-dev at lists.llvm.org> wrote:> Still no progress with this problem. Only that non-member functions seems > to be working... > Also: > Even when I set the target triple of the Module (when the file was parsed > at runtime) to "COFF" nothing changes... > > > From: Bjoern Gaier/HE/HORIBA > To: llvm-dev at lists.llvm.org > Cc: cfe-dev at lists.llvm.org > Date: 08.02.2018 12:28 > Subject: Re: Calling virtual elf functions under windows -> Adding > ASM code > ------------------------------ > > > Hello everyone, > > I'm sorry for "flooding" your inbox, but I wanted to extend my message > which is shown below. The problem is still not solved and I'm more confused > then before. > I compiled the code - the one seen in the pictures to elf bc and to msvc > (pecoff) bc. Then I used llc to generate assembler output. > > In my opinion the involved functions are acting exactly the same. There > are only some registers swapped. I should mention: when using the msvc bc > code, then the calls via the interface are working. > > I attach the assembly code of the involved code to. Could please anyone > explain me the difference, which could cause the crash? > > Kind regards > Björn > > > > > From: Bjoern Gaier/HE/HORIBA > To: llvm-dev at lists.llvm.org, cfe-dev at lists.llvm.org > Date: 07.02.2018 11:47 > Subject: Calling virtual elf functions under windows > ------------------------------ > > > Hello everyone reading this, > > I'm totally confused and need an explanation. I'm also not sure if it's a > clang or a LLVM subject. > > I'm working with Visual Studio 2015, LLVM 5.0.1 and Windows 7 64bit. > > I have a simple project. With 2 Header files and 1 cpp file. > "Interface.h" > This file defines a simple class with two pure virtual member functions. > > "SimpleResult.h" > This file defines a struct holding an integer > > "CM_Elf.cpp" > This file defines a class (CM_Elf) implementing the interface from > Interface.h > Also there is an instance of the class (named "elf"). > > I compile the CM_Elf.cpp to a CM_Elf.bc file via clang-cl but with target > "x86_64-pc-windows-elf" > > > In another application I use LLVM to parse the BC file and use the > ExecutionEngine to get some addresses. > What I want to archive is: > I want to call the implemented member functions of "elf". > > 1.) I execute all the global constructors collected by the ExecutionEngine > -> The constructor of elf gets called > 2.) I use ExecutionEngine to get the address of "elf" > 3.) I use the interface to execute Interface::init > -> Init gets called > 4.) I use the interface to execute Interface::shutdown > -> CRASH! > > When I swap the calls to init and shutdown, then everything works. So the > virtual call to init seems to corrupt my stack - maybe it's the return > value. Could it be a calling convention problem? But my target is still > "windows" only msvc changed to elf... > When I compile CM_Elf for target "x86_64-pc-windows-msvc19.0.24215" then > it works. > > When I get the address of CM_Elf::init and CM_Elf::shutdown via the > ExecutionEngine and call them without using the virtual table, then again > everything works. > > SO! Is it not possible to call virtual elf functions via there interface? > But why does normal functions work? Also I reach the functions which are > stored in the vTable of CM_Elf so the vTable is correct. > > I append some pictures of the code... I hope someone could help me with > this. > > Kind regards > 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, Hiroshi Kawamura, Takashi Nagano, Takeshi Fukushima. > > > > 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, Hiroshi Kawamura, Takashi Nagano, Takeshi Fukushima. > > > _______________________________________________ > cfe-dev mailing list > cfe-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180221/17692ea6/attachment.html>
Lang Hames via llvm-dev
2018-Feb-22 16:36 UTC
[llvm-dev] [cfe-dev] Calling virtual elf functions under windows -> Adding ASM code
Hi Björn, It's correct - I tried casting the virtual function to a regular function.> But I also tried using the virtual function in the normal way. >Yes. If I understand your setup correctly you have a base class, Interface, which is currently compiled into your application, and you are creating a derived class in JIT'd code, and returning an Interface pointer to an instance of the derived class. In this case you are probably running into ABI incompatibility issues in the class layout between the ahead-of-time and JIT'd code. Your ahead-of-time code will always have to call virtual functions via trampolines. I would remove all references to the Interface class from your main application (so that the compiler catches anyone who tries to use it directly) and make it an opaque pointer type that you pass into JIT'd code. I don't understand why the generated assemblies are different. Are they> effected by the ELF and PE/COFF ABI? But I thought this problem would be > solved thanks to the target-triple containing "windows".I believe the code generator sometimes uses the format (ELF / COFF / MachO) in making ABI decisions. When I create the trampoline functions on the IR level - would there be a> way to inline them when used?They can be inlined when called from other JIT'd code, but not when called from ahead-of-time code. The ideal solution to your situation would be to generate JIT'd code in the same format as the ahead-of-time code. Then you can just use virtual functions as normal. From memory there is some reason that you can't do that though. Was it exception handling support? Cheers, Lang. On Thu, Feb 22, 2018 at 12:00 AM, <bjoern.gaier at horiba.com> wrote:> Hello Lang, > > It's correct - I tried casting the virtual function to a regular function. > But I also tried using the virtual function in the normal way. > > I don't understand why the generated assemblies are different. Are they > effected by the ELF and PE/COFF ABI? But I thought this problem would be > solved thanks to the target-triple containing "windows". > > When I create the trampoline functions on the IR level - would there be a > way to inline them when used? > > Kind regards > Björn > > > > From: Lang Hames <lhames at gmail.com> > To: bjoern.gaier at horiba.com > Cc: LLVM Developers Mailing List <llvm-dev at lists.llvm.org>, Clang > Dev <cfe-dev at lists.llvm.org> > Date: 21.02.2018 22:36 > Subject: Re: [cfe-dev] Calling virtual elf functions under windows > -> Adding ASM code > ------------------------------ > > > > Hi Bjoern, > > It looks like you are casting a regular function pointer (returned from > getFunctionAddress) to a virtual method pointer. This is undefined behavior. > > The easiest way to achieve the effect you want would be to add a > trampoline to your source (or at the IR level): > > extern "C" SimpleResult call_Interface_init(Interface *Instance) { return > Instance->init(); } > > Then you can just use: > > auto CallInit = (SimpleResult(*)(Interface*))engine->getFunctionAddress(" > call_Interface_init"); > CallInit(inter); > > Cheers, > Lang. > > > On Tue, Feb 20, 2018 at 1:42 AM, via cfe-dev <*cfe-dev at lists.llvm.org* > <cfe-dev at lists.llvm.org>> wrote: > Still no progress with this problem. Only that non-member functions seems > to be working... > Also: > Even when I set the target triple of the Module (when the file was parsed > at runtime) to "COFF" nothing changes... > > > From: Bjoern Gaier/HE/HORIBA > To: *llvm-dev at lists.llvm.org* <llvm-dev at lists.llvm.org> > Cc: *cfe-dev at lists.llvm.org* <cfe-dev at lists.llvm.org> > Date: 08.02.2018 12:28 > Subject: Re: Calling virtual elf functions under windows -> Adding > ASM code > ------------------------------ > > > > Hello everyone, > > I'm sorry for "flooding" your inbox, but I wanted to extend my message > which is shown below. The problem is still not solved and I'm more confused > then before. > I compiled the code - the one seen in the pictures to elf bc and to msvc > (pecoff) bc. Then I used llc to generate assembler output. > > In my opinion the involved functions are acting exactly the same. There > are only some registers swapped. I should mention: when using the msvc bc > code, then the calls via the interface are working. > > I attach the assembly code of the involved code to. Could please anyone > explain me the difference, which could cause the crash? > > Kind regards > Björn > > > > > From: Bjoern Gaier/HE/HORIBA > To: *llvm-dev at lists.llvm.org* <llvm-dev at lists.llvm.org>, > *cfe-dev at lists.llvm.org* <cfe-dev at lists.llvm.org> > Date: 07.02.2018 11:47 > Subject: Calling virtual elf functions under windows > ------------------------------ > > > Hello everyone reading this, > > I'm totally confused and need an explanation. I'm also not sure if it's a > clang or a LLVM subject. > > I'm working with Visual Studio 2015, LLVM 5.0.1 and Windows 7 64bit. > > I have a simple project. With 2 Header files and 1 cpp file. > "Interface.h" > This file defines a simple class with two pure virtual member functions. > > "SimpleResult.h" > This file defines a struct holding an integer > > "CM_Elf.cpp" > This file defines a class (CM_Elf) implementing the interface from > Interface.h > Also there is an instance of the class (named "elf"). > > I compile the CM_Elf.cpp to a CM_Elf.bc file via clang-cl but with target > "x86_64-pc-windows-elf" > > > In another application I use LLVM to parse the BC file and use the > ExecutionEngine to get some addresses. > What I want to archive is: > I want to call the implemented member functions of "elf". > > 1.) I execute all the global constructors collected by the ExecutionEngine > -> The constructor of elf gets called > 2.) I use ExecutionEngine to get the address of "elf" > 3.) I use the interface to execute Interface::init > -> Init gets called > 4.) I use the interface to execute Interface::shutdown > -> CRASH! > > When I swap the calls to init and shutdown, then everything works. So the > virtual call to init seems to corrupt my stack - maybe it's the return > value. Could it be a calling convention problem? But my target is still > "windows" only msvc changed to elf... > When I compile CM_Elf for target "x86_64-pc-windows-msvc19.0.24215" then > it works. > > When I get the address of CM_Elf::init and CM_Elf::shutdown via the > ExecutionEngine and call them without using the virtual table, then again > everything works. > > SO! Is it not possible to call virtual elf functions via there interface? > But why does normal functions work? Also I reach the functions which are > stored in the vTable of CM_Elf so the vTable is correct. > > I append some pictures of the code... I hope someone could help me with > this. > > Kind regards > 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, Hiroshi Kawamura, Takashi Nagano, Takeshi Fukushima. > > > > 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, Hiroshi Kawamura, Takashi Nagano, Takeshi Fukushima. > > > _______________________________________________ > cfe-dev mailing list > *cfe-dev at lists.llvm.org* <cfe-dev at lists.llvm.org> > *http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev* > <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-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, Hiroshi Kawamura, Takashi Nagano, Takeshi Fukushima. > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180222/453be0ad/attachment.html>
Possibly Parallel Threads
- Calling virtual elf functions under windows -> Adding ASM code
- Calling virtual elf functions under windows -> Adding ASM code
- [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?
- JIT - Resolve obj file without a main
- Clang/LLVM JIT - When to use "registerEHFrames()"