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>