code *nteh_monitor_epilog(regm_t retregs) { /* * CALL _d_monitor_epilog * POP FS:__except_list */ assert(config.exe == EX_WIN32); // BUG: figure out how to implement for other EX's Symbol *s = getRtlsym(RTLSYM_MONITOR_EPILOG); //desregs = ~s->Sregsaved & ALLREGS; regm_t desregs = 0; code *cs1; code *cs2; gensaverestore(retregs& desregs,&cs1,&cs2); CodeBuilder cdb(getregs(desregs)); cdb.gencs(0xE8,0,FLfunc,s); // CALL __d_monitor_epilog CodeBuilder cdb1(cs1); CodeBuilder cdb2(cs2); cdb1.append(cdb, cdb2); code cs; cs.Iop = 0x8F; cs.Irm = modregrm(0,0,BPRM); cs.Iflags = CFfs; cs.Irex = 0; cs.IFL1 = FLextern; cs.IEVsym1 = getRtlsym(RTLSYM_EXCEPT_LIST); cs.IEVoffset1 = 0; cdb1.gen(&cs); // POP FS:__except_list return cdb1.finish(); }
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(); }
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; }
code *linux_unwind(regm_t retregs,unsigned index) { int i; 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)); cdb.genc2(0x68,0,index); // PUSH index #if MARS // 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, -4)); #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(); }
code *linux_unwind(regm_t retregs,unsigned index) { code *c; code *cs1; code *cs2; int i; 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); c = genc2(c,0x68,0,index); // PUSH index #if MARS // 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),4); // 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; }
code *nteh_monitor_epilog(regm_t retregs) { /* * CALL _d_monitor_epilog * POP FS:__except_list */ code cs; code *c; code *cs1; code *cs2; code *cpop; regm_t desregs; Symbol *s; assert(config.flags2 & CFG2seh); // BUG: figure out how to implement for other EX's s = rtlsym[RTLSYM_MONITOR_EPILOG]; //desregs = ~s->Sregsaved & ALLREGS; desregs = 0; gensaverestore(retregs & desregs,&cs1,&cs2); c = getregs(desregs); c = gencs(c,0xE8,0,FLfunc,s); // CALL __d_monitor_epilog cs.Iop = 0x8F; cs.Irm = modregrm(0,0,BPRM); cs.Iflags = CFfs; cs.Irex = 0; cs.IFL1 = FLextern; cs.IEVsym1 = rtlsym[RTLSYM_EXCEPT_LIST]; cs.IEVoffset1 = 0; cpop = gen(NULL,&cs); // POP FS:__except_list c = cat4(cs1,c,cs2,cpop); return c; }