<div dir="rtl"><div dir="ltr">You have done an impressive in-depth research.Such details are usually poorly documented since very few people actually use them, for most people it just works (or not).</div><div dir="ltr"><br></div><div dir="ltr">Does it make sense to integrate your results into LLVM MCJIT codebase so it will "just work" on Darwin?</div><div dir="ltr">Once it's in (with tests) you won't need to remerge your changes again.</div><div dir="ltr"><br></div><div dir="ltr"><br></div><div dir="ltr"><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div dir="ltr">2015-08-25 22:59 GMT+03:00 jacob navia via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span>:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Le 25/08/2015 20:39, Renato Golin a écrit :<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I'm also interested in knowing what you did. I think most people here<br>
would be glad to know your peril and how you solved it.<br>
</blockquote>
<br></span>
Stack layout:<br>
<br>
C++ code calls<br>
   |<br>
   |<br>
JITted C code, compiled and linked on the fly tha calls<br>
   |<br>
   |<br>
C++ code that throws<br>
<br>
The throw must pass through the JITted code to arrive at the catch at the top.<br>
<br>
So, the JIT must generate and install the CIE/FDE DWARF4 debug info to inform the stack unwinding virtual machine how to do it.<br>
<br>
Problems solved:<br>
<br>
1) Do not read the DWARF docs. They give you a general idea but nobody follows it.<br>
2) Do not try to *understand* anything. It is hopeless and you will just lose your time.<br>
3) Try to generate EXACTLY what llvm is generating.<br>
<br>
So, I extracted the __eh_frame section from a simple C program.<br>
<br>
otool -s __TEXT __eh_frame hello.o<br>
<br>
I figure out from the hexadecimal dump where the CIE lies. Then, I generate exactly the same.<br>
<br>
Then, generate the FDEs for each function. Again, use the dump of the __eh_frame section as a guide but add your own virtual machine instructions. Of course do not copy blindly what llvm generates since some fields like length, etc mst be changed!<br>
<br>
Then the problem arises:<br>
<br>
You have to inform the running program that a new piece of code has ben JITted and add the eh_frame info dynamically. That is the question I asked here a month ago.<br>
<br>
Since there were no answers, I tried the code that uses the<br>
<br>
 _keymgr_get_and_lock_processwide_ptr<br>
<br>
as specified in some Apple's program source.<br>
<br>
Do not do that. It will just never work, it returns always zero.<br>
<br>
Then I tried to use what I use on Linux:<br>
<br>
register_table_bases with<br>
void __register_frame_info_table_bases (void *begin, struct object *ob, void *tbase, void *dbase);<br>
This function requires a different format than register_frame_info, quite difficult to generate.<br>
<br>
Do not bother, it doesn't work, even if it is advertised as "working in OS X now".<br>
<br>
Then I tried to use<br>
register_frame_info with yet another format. Didn't work either. Desperate to know WHY it wasn't working I followed the machine on assembly, instruction by instruction until I got there. The reason was obvious: That function consists of just...<br>
<br>
a return statement. Nothing more. It is decoy to avoid giving you a linker error.<br>
<br>
Then  I was TRULY desperate and asked Apple. That worked. The friendly people at the Apple groups told me to look into the code of the dynamic loader that does exactly what I was trying to do OF COURSE!<br>
<br>
I compiled that. Do not use the xcode project coming with the software because I got incredible strange debugger problems and could not debug it. Using a simple Makefile works.<br>
<br>
Then, I could follow ALL the process of calling __register_frame(); and that function works. It expects an FDE (not a CIE as I thought) but reads the CIE using the CIE pointer in the given FDE for each FDE.<br>
<br>
Now, the throw of the C++ code below my JIT code is catched by the C++ code above.<br>
<br>
GOSH!<br>
<br>
This is just a quick description. I do not speak about all the wrong starts, the dead ends, the sheer frustration at the lack of docs, etc. This is the result of this part of the compiler being very complex by design (DWARF is incredibly complex), and a total lack of documentation. For instance the entry for __register_frame_info in GNU docs is just:<br>
<br>
"DOCUMENT THIS!"<br>
<br>
On top of this, Apple has modified the DWARF specs to compress the information, and it uses a public domain library (libunwind) that has been heavily modified. If this isn't a MESS I do not know what a mess is.<br>
<br>
Anyway, I got there in just a month of work. I am getting better, under linux it took me three months, but that was the first time.<span class="HOEnZb"><font color="#888888"><br>
<br>
jacob<br>
</font></span><br>
P.S. Sorry for the message about GNU software. I was mad at you, but actually is not your fault. You have also your share of hard work. I suppose that at a certain level of complexity there are always VERY FEW people that know anything, and you have to figure it out yourself without any help.<div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</div></div></blockquote></div><br></div>