コード例 #1
0
ファイル: nteh.c プロジェクト: klickverbot/dmd
code *nteh_unwind(regm_t retregs,unsigned index)
{
    code cs;
    regm_t desregs;
    int reg;
    int local_unwind;

    // Shouldn't this always be CX?
#if SCPP
    reg = AX;
#else
    reg = CX;
#endif

#if MARS
    local_unwind = RTLSYM_D_LOCAL_UNWIND2;
#else
    local_unwind = RTLSYM_LOCAL_UNWIND2;
#endif
    desregs = (~getRtlsym(local_unwind)->Sregsaved & (ALLREGS)) | mask[reg];
    code *cs1;
    code *cs2;
    gensaverestore(retregs & desregs,&cs1,&cs2);

    CodeBuilder cdb(getregs(desregs));

    cs.Iop = 0x8D;
    cs.Irm = modregrm(2,reg,BPRM);
    cs.Iflags = 0;
    cs.Irex = 0;
    cs.IFL1 = FLconst;
    // EBP offset of __context.prev
    cs.IEV1.Vint = nteh_EBPoffset_prev();
    cdb.gen(&cs);                             // LEA  ECX,contextsym

    cdb.genc2(0x68,0,index);                      // PUSH index
    cdb.gen1(0x50 + reg);                         // PUSH ECX

#if MARS
    //cdb.gencs(0xB8+AX,0,FLextern,nteh_scopetable());    // MOV EAX,&scope_table
    cdb.gencs(0x68,0,FLextern,nteh_scopetable());         // PUSH &scope_table

    cdb.gencs(0xE8,0,FLfunc,getRtlsym(local_unwind));        // CALL __d_local_unwind2()
    cdb.append(cod3_stackadj(NULL, -12));
#else
    cdb.gencs(0xE8,0,FLfunc,getRtlsym(local_unwind));        // CALL __local_unwind2()
    cdb.append(cod3_stackadj(NULL, -8));
#endif

    CodeBuilder cdb1(cs1);
    CodeBuilder cdb2(cs2);
    cdb1.append(cdb, cdb2);
    return cdb1.finish();
}
コード例 #2
0
ファイル: nteh.c プロジェクト: spott/dmd
code *nteh_unwind(regm_t retregs,unsigned index)
{   code *c;
    code cs;
    code *cs1;
    code *cs2;
    regm_t desregs;
    int reg;
    int local_unwind;

    // Shouldn't this always be CX?
#if SCPP
    reg = AX;
#else
    reg = CX;
#endif

#if MARS
    local_unwind = RTLSYM_D_LOCAL_UNWIND2;
#else
    local_unwind = RTLSYM_LOCAL_UNWIND2;
#endif
    desregs = (~rtlsym[local_unwind]->Sregsaved & (ALLREGS)) | mask[reg];
    gensaverestore(retregs & desregs,&cs1,&cs2);

    c = getregs(desregs);

    cs.Iop = 0x8D;
    cs.Irm = modregrm(2,reg,BPRM);
    cs.Iflags = 0;
    cs.Irex = 0;
    cs.IFL1 = FLconst;
    // EBP offset of __context.prev
    cs.IEV1.Vint = nteh_EBPoffset_prev();
    c = gen(c,&cs);                             // LEA  ECX,contextsym

    genc2(c,0x68,0,index);                      // PUSH index
    gen1(c,0x50 + reg);                         // PUSH ECX

#if MARS
    //gencs(c,0xB8+AX,0,FLextern,nteh_scopetable());    // MOV EAX,&scope_table
    gencs(c,0x68,0,FLextern,nteh_scopetable());         // PUSH &scope_table

    gencs(c,0xE8,0,FLfunc,rtlsym[local_unwind]);        // CALL __d_local_unwind2()
    genc2(c,0x81,modregrm(3,0,SP),12);                  // ADD ESP,12
#else
    gencs(c,0xE8,0,FLfunc,rtlsym[local_unwind]);        // CALL __local_unwind2()
    genc2(c,0x81,modregrm(3,0,SP),8);                   // ADD ESP,8
#endif

    c = cat4(cs1,c,cs2,NULL);
    return c;
}
コード例 #3
0
ファイル: nteh.c プロジェクト: spott/dmd
code *nteh_prolog()
{
    code cs;
    code *c1;
    code *c;

    if (usednteh & NTEHpassthru)
    {
        /* An sindex value of -2 is a magic value that tells the
         * stack unwinder to skip this frame.
         */
        assert(config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_OSX64 | EX_FREEBSD | EX_FREEBSD64 | EX_SOLARIS | EX_SOLARIS64));
        cs.Iop = 0x68;
        cs.Iflags = 0;
        cs.Irex = 0;
        cs.IFL2 = FLconst;
        cs.IEV2.Vint = -2;
        return gen(CNIL,&cs);                   // PUSH -2
    }

    /* Generate instance of struct __nt_context on stack frame:
        [  ]                                    // previous ebp already there
        push    -1                              // sindex
        mov     EDX,FS:__except_list
        push    offset FLAT:scope_table         // stable (not for MARS or C++)
        push    offset FLAT:__except_handler3   // handler
        push    EDX                             // prev
        mov     FS:__except_list,ESP
        sub     ESP,8                           // info, esp for __except support
     */

//    useregs(mAX);                     // What is this for?

    cs.Iop = 0x68;
    cs.Iflags = 0;
    cs.Irex = 0;
    cs.IFL2 = FLconst;
    cs.IEV2.Vint = -1;
    c1 = gen(CNIL,&cs);                 // PUSH -1

    if (usednteh & NTEHcpp || MARS)
    {
        // PUSH &framehandler
        cs.IFL2 = FLframehandler;
#if MARS
        nteh_scopetable();
#endif
    }
    else
    {
        // Do stable
        cs.Iflags |= CFoff;
        cs.IFL2 = FLextern;
        cs.IEVsym2 = nteh_scopetable();
        cs.IEVoffset2 = 0;
        c1 = gen(c1,&cs);                       // PUSH &scope_table

        cs.IFL2 = FLextern;
        cs.IEVsym2 = rtlsym[RTLSYM_EXCEPT_HANDLER3];
        makeitextern(rtlsym[RTLSYM_EXCEPT_HANDLER3]);
    }
    c = gen(NULL,&cs);                          // PUSH &__except_handler3

    if (config.exe == EX_NT)
    {
        makeitextern(rtlsym[RTLSYM_EXCEPT_LIST]);
#if 0
        cs.Iop = 0xFF;
        cs.Irm = modregrm(0,6,BPRM);
        cs.Iflags = CFfs;
        cs.Irex = 0;
        cs.IFL1 = FLextern;
        cs.IEVsym1 = rtlsym[RTLSYM_EXCEPT_LIST];
        cs.IEVoffset1 = 0;
        gen(c,&cs);                             // PUSH FS:__except_list
#else
        useregs(mDX);
        cs.Iop = 0x8B;
        cs.Irm = modregrm(0,DX,BPRM);
        cs.Iflags = CFfs;
        cs.Irex = 0;
        cs.IFL1 = FLextern;
        cs.IEVsym1 = rtlsym[RTLSYM_EXCEPT_LIST];
        cs.IEVoffset1 = 0;
        gen(c1,&cs);                            // MOV EDX,FS:__except_list

        gen1(c,0x50 + DX);                      // PUSH EDX
#endif
        cs.Iop = 0x89;
        NEWREG(cs.Irm,SP);
        gen(c,&cs);                             // MOV FS:__except_list,ESP
    }

    c = genc2(c,0x81,modregrm(3,5,SP),8);       // SUB ESP,8

    return cat(c1,c);
}
コード例 #4
0
ファイル: nteh.c プロジェクト: klickverbot/dmd
code *nteh_prolog()
{
    code cs;

    if (usednteh & NTEHpassthru)
    {
        /* An sindex value of -2 is a magic value that tells the
         * stack unwinder to skip this frame.
         */
        assert(config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_OSX64 | EX_FREEBSD | EX_FREEBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_OPENBSD | EX_OPENBSD64));
        cs.Iop = 0x68;
        cs.Iflags = 0;
        cs.Irex = 0;
        cs.IFL2 = FLconst;
        cs.IEV2.Vint = -2;
        return gen(CNIL,&cs);                   // PUSH -2
    }

    /* Generate instance of struct __nt_context on stack frame:
        [  ]                                    // previous ebp already there
        push    -1                              // sindex
        mov     EDX,FS:__except_list
        push    offset FLAT:scope_table         // stable (not for MARS or C++)
        push    offset FLAT:__except_handler3   // handler
        push    EDX                             // prev
        mov     FS:__except_list,ESP
        sub     ESP,8                           // info, esp for __except support
     */

//    useregs(mAX);                     // What is this for?

    CodeBuilder cdb1;

    cs.Iop = 0x68;
    cs.Iflags = 0;
    cs.Irex = 0;
    cs.IFL2 = FLconst;
    cs.IEV2.Vint = -1;
    cdb1.gen(&cs);                 // PUSH -1

    if (MARS || (usednteh & NTEHcpp))
    {
        // PUSH &framehandler
        cs.IFL2 = FLframehandler;
#if MARS
        nteh_scopetable();
#endif
    }
    else
    {
        // Do stable
        cs.Iflags |= CFoff;
        cs.IFL2 = FLextern;
        cs.IEVsym2 = nteh_scopetable();
        cs.IEVoffset2 = 0;
        cdb1.gen(&cs);                       // PUSH &scope_table

        cs.IFL2 = FLextern;
        cs.IEVsym2 = getRtlsym(RTLSYM_EXCEPT_HANDLER3);
        makeitextern(getRtlsym(RTLSYM_EXCEPT_HANDLER3));
    }
    CodeBuilder cdb2;
    cdb2.gen(&cs);                          // PUSH &__except_handler3

    if (config.exe == EX_WIN32)
    {
        makeitextern(getRtlsym(RTLSYM_EXCEPT_LIST));
    #if 0
        cs.Iop = 0xFF;
        cs.Irm = modregrm(0,6,BPRM);
        cs.Iflags = CFfs;
        cs.Irex = 0;
        cs.IFL1 = FLextern;
        cs.IEVsym1 = getRtlsym(RTLSYM_EXCEPT_LIST);
        cs.IEVoffset1 = 0;
        cdb2.gen(&cs);                             // PUSH FS:__except_list
    #else
        useregs(mDX);
        cs.Iop = 0x8B;
        cs.Irm = modregrm(0,DX,BPRM);
        cs.Iflags = CFfs;
        cs.Irex = 0;
        cs.IFL1 = FLextern;
        cs.IEVsym1 = getRtlsym(RTLSYM_EXCEPT_LIST);
        cs.IEVoffset1 = 0;
        cdb1.gen(&cs);                            // MOV EDX,FS:__except_list

        cdb2.gen1(0x50 + DX);                      // PUSH EDX
    #endif
        cs.Iop = 0x89;
        NEWREG(cs.Irm,SP);
        cdb2.gen(&cs);                             // MOV FS:__except_list,ESP
    }

    CodeBuilder cdb3(cod3_stackadj(NULL, 8));

    cdb1.append(cdb2, cdb3);
    return cdb1.finish();
}