Hi, There may be two problems with __register_frame usage. However based on http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-April/061768.html I think the existing code is correct for OS-X but likely buggy for Linux and Windows systems. Your crash is on OS-X, right? Anyhow, the first problem is very easy to fix. On Linux and Windows (at least) __register_frame should be called once and not called on every FDE as in processFDE in RTDyldMemoryManager,cpp does. So RTDyldMemoryManager::registerEHFrames was modified to: void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { __register_frame(Addr); } On Windows 7 / MingW (gcc) this completely solved the problems I had with erratic exception behaviour. The second issue is a bit more complicated. With executable files, the linker combines .eh frames with four zero bytes from crtend to marking .eh_frame section end. As Rafael writes, this can't be done in codegen since it's a linker function done when all .eh_frames are combined. The dynamic linker must perform the same function, else __register_frame(.eh_frame) might continue processing after .eh_frame, depending if there were four zero bytes following it - or not - by chance. However this again isn't likely to be your source of problem, as __registerframe on OS-X processes one FDE at the time and the calling function processFDE() in RTDyldMemoryManager.cpp does know the size of eh_frame so it will not overrun the frame. The solution would be to allocate a larger buffer, copy .eh_frame into it with four zero bytes appended. This buffer needs to live as long as long it's registered in the runtime library. Yaron -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131014/2d983b51/attachment.html>
Christian Schafmeister
2013-Oct-15 03:28 UTC
[LLVMdev] A weird, reproducable problem with MCJIT
With the help of iain at codesourcery.com and andrew.kaylor at intel.com we tracked the problem down to a bad relocation that was clobbering the first bytes of the eh_frame. I think this problem/solution may be OS X specific. On akaylor's suggestion I made the change below and my reproducable test case now compiles fine with MCJIT. As well, my Common Lisp code base now compiles using MCJIT - that's about 1,000 functions at one MCJIT module per function. In llvm/lib/ExecutionEngine/RuntimeDyld Index: RuntimeDyldImpl.h ==================================================================--- RuntimeDyldImpl.h (revision 192535) +++ RuntimeDyldImpl.h (working copy) @@ -195,7 +195,7 @@ else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) return 44; else if (Arch == Triple::x86_64) - return 6; // 2-byte jmp instruction + 32-bit relative address + return 8; /* was 6 but akaylor said change to 8 - meister Oct 2013 */ // 2-byte jmp instruction + 32-bit relative address else if (Arch == Triple::systemz) return 16; else
Correct or no I don't know, but this change will affect all x86-64 targets including Linux and Windows as getMaxStubSize() is called from the ELF linker as well as the Mach-O linker. 2013/10/15 Christian Schafmeister <chris.schaf at verizon.net>> > With the help of iain at codesourcery.com and andrew.kaylor at intel.com we > tracked the problem down to a bad relocation that was clobbering the > first bytes of the eh_frame. I think this problem/solution may be OS X > specific. > > On akaylor's suggestion I made the change below and my reproducable test > case now compiles fine with MCJIT. > > As well, my Common Lisp code base now compiles using MCJIT - that's about > 1,000 > functions at one MCJIT module per function. > > > > In llvm/lib/ExecutionEngine/RuntimeDyld > > Index: RuntimeDyldImpl.h > ==================================================================> --- RuntimeDyldImpl.h (revision 192535) > +++ RuntimeDyldImpl.h (working copy) > @@ -195,7 +195,7 @@ > else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) > return 44; > else if (Arch == Triple::x86_64) > - return 6; // 2-byte jmp instruction + 32-bit relative address > + return 8; /* was 6 but akaylor said change to 8 - meister Oct 2013 > */ // 2-byte jmp instruction + 32-bit relative address > else if (Arch == Triple::systemz) > return 16; > else > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131015/837b0e1c/attachment.html>
Possibly Parallel Threads
- [LLVMdev] A weird, reproducable problem with MCJIT
- [LLVMdev] A weird, reproducable problem with MCJIT
- [LLVMdev] A weird, reproducable problem with MCJIT
- [LLVMdev] A weird, reproducable problem with MCJIT
- [LLVMdev] [llvm] r188726 - Adding PIC support for ELF on x86_64 platforms