Пример #1
0
code *nteh_monitor_prolog(Symbol *shandle)
{
    /*
     *  PUSH    handle
     *  PUSH    offset _d_monitor_handler
     *  PUSH    FS:__except_list
     *  MOV     FS:__except_list,ESP
     *  CALL    _d_monitor_prolog
     */
    CodeBuilder cdb1;
    CodeBuilder cdb;

    assert(config.exe == EX_WIN32);    // BUG: figure out how to implement for other EX's

    if (shandle->Sclass == SCfastpar)
    {   assert(shandle->Spreg != DX);
        assert(shandle->Spreg2 == NOREG);
        cdb.gen1(0x50 + shandle->Spreg);   // PUSH shandle
    }
    else
    {
        // PUSH shandle
        useregs(mCX);
        cdb.genc1(0x8B,modregrm(2,CX,4),FLconst,4 * (1 + needframe) + shandle->Soffset + localsize);
        cdb.last()->Isib = modregrm(0,4,SP);
        cdb.gen1(0x50 + CX);                      // PUSH ECX
    }

    Symbol *smh = getRtlsym(RTLSYM_MONITOR_HANDLER);
    cdb.gencs(0x68,0,FLextern,smh);             // PUSH offset _d_monitor_handler
    makeitextern(smh);

    code cs;
    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

    cdb.gen1(0x50 + DX);                  // PUSH EDX

    Symbol *s = getRtlsym(RTLSYM_MONITOR_PROLOG);
    regm_t desregs = ~s->Sregsaved & ALLREGS;
    cdb.append(getregs(desregs));
    cdb.gencs(0xE8,0,FLfunc,s);       // CALL _d_monitor_prolog

    cs.Iop = 0x89;
    NEWREG(cs.Irm,SP);
    cdb.gen(&cs);                         // MOV FS:__except_list,ESP

    cdb1.append(cdb);
    return cdb1.finish();
}
Пример #2
0
code *nteh_epilog()
{
    if (config.exe != EX_WIN32)
        return NULL;

    /* Generate:
        mov     ECX,__context[EBP].prev
        mov     FS:__except_list,ECX
     */
    code cs;
    CodeBuilder cdb;
    unsigned reg;

#if MARS
    reg = CX;
#else
    reg = (tybasic(funcsym_p->Stype->Tnext->Tty) == TYvoid) ? AX : CX;
#endif
    useregs(mask[reg]);

    cs.Iop = 0x8B;
    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);

    cs.Iop = 0x89;
    cs.Irm = modregrm(0,reg,BPRM);
    cs.Iflags |= CFfs;
    cs.IFL1 = FLextern;
    cs.IEVsym1 = getRtlsym(RTLSYM_EXCEPT_LIST);
    cs.IEVoffset1 = 0;
    cdb.gen(&cs);
    return cdb.finish();
}
Пример #3
0
Файл: nteh.c Проект: spott/dmd
code *nteh_epilog()
{
    if (!(config.flags2 & CFG2seh))
        return NULL;

    /* Generate:
        mov     ECX,__context[EBP].prev
        mov     FS:__except_list,ECX
     */
    code cs;
    code *c;
    unsigned reg;

#if MARS
    reg = CX;
#else
    reg = (tybasic(funcsym_p->Stype->Tnext->Tty) == TYvoid) ? AX : CX;
#endif
    useregs(mask[reg]);

    cs.Iop = 0x8B;
    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(CNIL,&cs);

    cs.Iop = 0x89;
    cs.Irm = modregrm(0,reg,BPRM);
    cs.Iflags |= CFfs;
    cs.IFL1 = FLextern;
    cs.IEVsym1 = rtlsym[RTLSYM_EXCEPT_LIST];
    cs.IEVoffset1 = 0;
    return gen(c,&cs);
}
Пример #4
0
Файл: nteh.c Проект: spott/dmd
code *nteh_monitor_prolog(Symbol *shandle)
{
    /*
     *  PUSH    handle
     *  PUSH    offset _d_monitor_handler
     *  PUSH    FS:__except_list
     *  MOV     FS:__except_list,ESP
     *  CALL    _d_monitor_prolog
     */
    code *c1 = NULL;
    code *c;
    code cs;
    Symbol *s;
    regm_t desregs;

    assert(config.flags2 & CFG2seh);    // BUG: figure out how to implement for other EX's

    if (shandle->Sclass == SCfastpar)
    {   assert(shandle->Spreg != DX);
        c = gen1(NULL,0x50 + shandle->Spreg);   // PUSH shandle
    }
    else
    {
        // PUSH shandle
#if 0
        c = genc1(NULL,0xFF,modregrm(2,6,4),FLconst,4 * (1 + needframe) + shandle->Soffset + localsize);
        c->Isib = modregrm(0,4,SP);
#else
        useregs(mCX);
        c = genc1(NULL,0x8B,modregrm(2,CX,4),FLconst,4 * (1 + needframe) + shandle->Soffset + localsize);
        c->Isib = modregrm(0,4,SP);
        gen1(c,0x50 + CX);                      // PUSH ECX
#endif
    }

    s = rtlsym[RTLSYM_MONITOR_HANDLER];
    c = gencs(c,0x68,0,FLextern,s);             // PUSH offset _d_monitor_handler
    makeitextern(s);

#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;
    c1 = gen(c1,&cs);                   // MOV EDX,FS:__except_list

    gen1(c,0x50 + DX);                  // PUSH EDX
#endif

    s = rtlsym[RTLSYM_MONITOR_PROLOG];
    desregs = ~s->Sregsaved & ALLREGS;
    c = cat(c,getregs(desregs));
    c = gencs(c,0xE8,0,FLfunc,s);       // CALL _d_monitor_prolog

    cs.Iop = 0x89;
    NEWREG(cs.Irm,SP);
    gen(c,&cs);                         // MOV FS:__except_list,ESP

    return cat(c1,c);
}
Пример #5
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);
}
Пример #6
0
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();
}