How to insert dynamic code? (continued)

jacob navia jacob@jacob.remcomp.fr
Thu Jul 13 15:52:00 GMT 2006


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



More information about the Gcc mailing list