This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to insert dynamic code? (continued)


On 7/13/06, jacob navia <jacob@jacob.remcomp.fr> 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";


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]