On 7/13/06, jacob navia <[EMAIL PROTECTED]> wrote:
Daniel Jacobowitz wrote:>On Thu, Jul 13, 2006 at 05:06:25PM +0200, jacob navia wrote: > > >>>So, what happens when _Unwind_Find_registered_FDE is called? Does it >>>find the EH data you have registered? >>> >>> >>> >>> >>> >>Yes but then it stops there instead of going upwards and finding the catch! >>It is as my insertion left the list of registered routines in a bad state. >> >>I will look again at this part (the registering part) and will try to >>find out what >>is going on. >> >> > >It sounds to me more like it used your data, and then was left pointing >somewhere garbage, not to the next frame. That is, it sounds like >there's something wrong with your generated unwind tables. That's the >usual cause for unexpected end of stack. > > > Yeah... My fault obviously, who else? Problem is, there are so mny undocumented stuff that I do not see how I could avoid making a mistake here. 1) I generate exactly the same code now as gcc: Prolog: push %ebp movq %rsp,%rbp subq xxx,%rsp and I do not touch the stack any more. Nothing is pushed, in the "xxx" is already the stack space for argument pushing reserved, just as gcc does. This took me 3 weeks to do. Now, I write my stuff as follows: 1) CIE 2) FDE for function 1 ..... 1 fde for each function 3) Empty FDE to zero terminate the stuff. 4) Table of pointers to the CIE, then to the FDE p = result.FunctionTable; // Starting place, where CIE, then FDEs are written p = WriteCIE(p); // Write first the CIE pFI = DefinedFunctions; nbOfFunctions=0; pFdeTable[nbOfFunctions++] = result.FunctionTable; while (pFI) { // For each function, write the FDE fde_start = p; p = Write32(0,p); // reserve place for length field (4 bytes) p = Write32(p - result.FunctionTable,p); //Write offset to CIE symbolP = pFI->FunctionInfo.AssemblerSymbol; adr = (long long)symbolP->SymbolValue; adr += (unsigned long long)code_start; // code_start is the pointer to the Jitted code p = Write64(adr,p); p = Write64(pFI->FunctionSize,p); // Write the length in bytes of the function *p++ = 0x41;/// Write the opcodes *p++ = 0x0e; // This opcodes are the same as gcc writes *p++ = 0x10; *p++ = 0x86; *p++ = 0x02; *p++ = 0x43; *p++ = 0x0d; *p++ = 0x06; p = align8(p); Write32((p - fde_start)-4,fde_start);// Fix the length of the FDE pFdeTable[nbOfFunctions] = fde_start; // Save pointer to it in table nbOfFunctions++; pFI = pFI->Next; // loop } The WriteCIE function is this: static unsigned char *WriteCIE(unsigned char *start) { start = Write32(0x14,start); start = Write32(0,start); *start++ = 1; // version 1 *start++ = 0; // no augmentation *start++ = 1; *start++ = 0x78; *start++ = 0x10; *start++ = 0xc; *start++ = 7; *start++ = 8; *start++ = 0x90; *start++ = 1; *start++ = 0; *start++ = 0; start = Write32(0,start); return start; } I hope this is OK... jacob
The above code looks incorrect, for various reasons, not the least of which is that you're assuming CIE/FDE are fixed-length. There are various factors that affect FDE/CIE depending on PIC/non-PIC, C or C++, 32bit/64bit, etc - some of them must be invariant for your JIT but some of them may not. Also some of the datum are encoded as uleb128 (see dwarf spec for the detail of LEB128 encoding) which is a variable-length encoding whose length depends on the value. In short, you'd better start looking at how CIE/FDE structures are *logically* layed out - otherwise you won't be able to generate correct entries. -- #pragma ident "Seongbae Park, compiler, http://seongbae.blogspot.com"
