⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toir.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
   switch (sz) {      case 8:  thunkOp = AMD64G_CC_OP_ADCQ; break;      case 4:  thunkOp = AMD64G_CC_OP_ADCL; break;      case 2:  thunkOp = AMD64G_CC_OP_ADCW; break;      case 1:  thunkOp = AMD64G_CC_OP_ADCB; break;      default: vassert(0);   }   /* oldc = old carry flag, 0 or 1 */   assign( oldc,  binop(Iop_And64,                        mk_amd64g_calculate_rflags_c(),                        mkU64(1)) );   assign( oldcn, narrowTo(ty, mkexpr(oldc)) );   assign( tres, binop(plus,                       binop(plus,mkexpr(ta1),mkexpr(ta2)),                       mkexpr(oldcn)) );   stmt( IRStmt_Put( OFFB_CC_OP,   mkU64(thunkOp) ) );   stmt( IRStmt_Put( OFFB_CC_DEP1, mkexpr(ta1) ) );   stmt( IRStmt_Put( OFFB_CC_DEP2, binop(xor, mkexpr(ta2),                                               mkexpr(oldcn)) ) );   stmt( IRStmt_Put( OFFB_CC_NDEP, mkexpr(oldc) ) );}/* Given ta1, ta2 and tres, compute tres = SBB(ta1,ta2) and set flags   appropriately.*/static void helper_SBB ( Int sz,                         IRTemp tres, IRTemp ta1, IRTemp ta2 ){   UInt    thunkOp;   IRType  ty    = szToITy(sz);   IRTemp  oldc  = newTemp(Ity_I64);   IRTemp  oldcn = newTemp(ty);   IROp    minus = mkSizedOp(ty, Iop_Sub8);   IROp    xor   = mkSizedOp(ty, Iop_Xor8);   switch (sz) {      case 8:  thunkOp = AMD64G_CC_OP_SBBQ; break;      case 4:  thunkOp = AMD64G_CC_OP_SBBL; break;      case 2:  thunkOp = AMD64G_CC_OP_SBBW; break;      case 1:  thunkOp = AMD64G_CC_OP_SBBB; break;      default: vassert(0);   }   /* oldc = old carry flag, 0 or 1 */   assign( oldc, binop(Iop_And64,                       mk_amd64g_calculate_rflags_c(),                       mkU64(1)) );   assign( oldcn, narrowTo(ty, mkexpr(oldc)) );   assign( tres, binop(minus,                       binop(minus,mkexpr(ta1),mkexpr(ta2)),                       mkexpr(oldcn)) );   stmt( IRStmt_Put( OFFB_CC_OP,   mkU64(thunkOp) ) );   stmt( IRStmt_Put( OFFB_CC_DEP1, mkexpr(ta1) ) );   stmt( IRStmt_Put( OFFB_CC_DEP2, binop(xor, mkexpr(ta2),                                               mkexpr(oldcn)) ) );   stmt( IRStmt_Put( OFFB_CC_NDEP, mkexpr(oldc) ) );}/* -------------- Helpers for disassembly printing. -------------- */static HChar* nameGrp1 ( Int opc_aux ){   static HChar* grp1_names[8]      = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" };   if (opc_aux < 0 || opc_aux > 7) vpanic("nameGrp1(amd64)");   return grp1_names[opc_aux];}static HChar* nameGrp2 ( Int opc_aux ){   static HChar* grp2_names[8]      = { "rol", "ror", "rcl", "rcr", "shl", "shr", "shl", "sar" };   if (opc_aux < 0 || opc_aux > 7) vpanic("nameGrp2(amd64)");   return grp2_names[opc_aux];}static HChar* nameGrp4 ( Int opc_aux ){   static HChar* grp4_names[8]      = { "inc", "dec", "???", "???", "???", "???", "???", "???" };   if (opc_aux < 0 || opc_aux > 1) vpanic("nameGrp4(amd64)");   return grp4_names[opc_aux];}static HChar* nameGrp5 ( Int opc_aux ){   static HChar* grp5_names[8]      = { "inc", "dec", "call*", "call*", "jmp*", "jmp*", "push", "???" };   if (opc_aux < 0 || opc_aux > 6) vpanic("nameGrp5(amd64)");   return grp5_names[opc_aux];}static HChar* nameGrp8 ( Int opc_aux ){   static HChar* grp8_names[8]       = { "???", "???", "???", "???", "bt", "bts", "btr", "btc" };   if (opc_aux < 4 || opc_aux > 7) vpanic("nameGrp8(amd64)");   return grp8_names[opc_aux];}//.. static HChar* nameSReg ( UInt sreg )//.. {//..    switch (sreg) {//..       case R_ES: return "%es";//..       case R_CS: return "%cs";//..       case R_SS: return "%ss";//..       case R_DS: return "%ds";//..       case R_FS: return "%fs";//..       case R_GS: return "%gs";//..       default: vpanic("nameSReg(x86)");//..    }//.. }static HChar* nameMMXReg ( Int mmxreg ){   static HChar* mmx_names[8]      = { "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" };   if (mmxreg < 0 || mmxreg > 7) vpanic("nameMMXReg(amd64,guest)");   return mmx_names[mmxreg];}static HChar* nameXMMReg ( Int xmmreg ){   static HChar* xmm_names[16]      = { "%xmm0",  "%xmm1",  "%xmm2",  "%xmm3",          "%xmm4",  "%xmm5",  "%xmm6",  "%xmm7",          "%xmm8",  "%xmm9",  "%xmm10", "%xmm11",          "%xmm12", "%xmm13", "%xmm14", "%xmm15" };   if (xmmreg < 0 || xmmreg > 15) vpanic("nameXMMReg(amd64)");   return xmm_names[xmmreg];} static HChar* nameMMXGran ( Int gran ){   switch (gran) {      case 0: return "b";      case 1: return "w";      case 2: return "d";      case 3: return "q";      default: vpanic("nameMMXGran(amd64,guest)");   }}static HChar nameISize ( Int size ){   switch (size) {      case 8: return 'q';      case 4: return 'l';      case 2: return 'w';      case 1: return 'b';      default: vpanic("nameISize(amd64)");   }}/*------------------------------------------------------------*//*--- JMP helpers                                          ---*//*------------------------------------------------------------*/static void jmp_lit( IRJumpKind kind, Addr64 d64 ){  irbb->next     = mkU64(d64);  irbb->jumpkind = kind;}static void jmp_treg( IRJumpKind kind, IRTemp t ){   irbb->next     = mkexpr(t);   irbb->jumpkind = kind;}static void jcc_01 ( AMD64Condcode cond, Addr64 d64_false, Addr64 d64_true ){   Bool          invert;   AMD64Condcode condPos;   condPos = positiveIse_AMD64Condcode ( cond, &invert );   if (invert) {      stmt( IRStmt_Exit( mk_amd64g_calculate_condition(condPos),                         Ijk_Boring,                         IRConst_U64(d64_false) ) );      irbb->next     = mkU64(d64_true);      irbb->jumpkind = Ijk_Boring;   } else {      stmt( IRStmt_Exit( mk_amd64g_calculate_condition(condPos),                         Ijk_Boring,                         IRConst_U64(d64_true) ) );      irbb->next     = mkU64(d64_false);      irbb->jumpkind = Ijk_Boring;   }}/* Let new_rsp be the %rsp value after a call/return.  This function   generates an AbiHint to say that -128(%rsp) .. -1(%rsp) should now   be regarded as uninitialised.*/static void make_redzone_AbiHint ( IRTemp new_rsp, HChar* who ){   if (0) vex_printf("AbiHint: %s\n", who);   vassert(typeOfIRTemp(irbb->tyenv, new_rsp) == Ity_I64);   stmt( IRStmt_AbiHint(             binop(Iop_Sub64, mkexpr(new_rsp), mkU64(128)),             128          ));}/*------------------------------------------------------------*//*--- Disassembling addressing modes                       ---*//*------------------------------------------------------------*/static HChar* sorbTxt ( Prefix pfx ){   if (pfx & PFX_CS) return "%cs:";   if (pfx & PFX_DS) return "%ds:";   if (pfx & PFX_ES) return "%es:";   if (pfx & PFX_FS) return "%fs:";   if (pfx & PFX_GS) return "%gs:";   if (pfx & PFX_SS) return "%ss:";   return ""; /* no override */}/* 'virtual' is an IRExpr* holding a virtual address.  Convert it to a   linear address by adding any required segment override as indicated   by sorb. */staticIRExpr* handleSegOverride ( Prefix pfx, IRExpr* virtual ){   if (pfx & PFX_FS) {      /* Note that this is a linux-kernel specific hack that relies         on the assumption that %fs is always zero. */      /* return virtual + guest_FS_ZERO. */      return binop(Iop_Add64, virtual, IRExpr_Get(OFFB_FS_ZERO, Ity_I64));   }   if (pfx & PFX_GS) {      unimplemented("amd64 %gs segment override");   }   /* cs, ds, es and ss are simply ignored in 64-bit mode. */   return virtual;}//.. {//..    Int    sreg;//..    IRType hWordTy;//..    IRTemp ldt_ptr, gdt_ptr, seg_selector, r64;//.. //..    if (sorb == 0)//..       /* the common case - no override *///..       return virtual;//.. //..    switch (sorb) {//..       case 0x3E: sreg = R_DS; break;//..       case 0x26: sreg = R_ES; break;//..       case 0x64: sreg = R_FS; break;//..       case 0x65: sreg = R_GS; break;//..       default: vpanic("handleSegOverride(x86,guest)");//..    }//.. //..    hWordTy = sizeof(HWord)==4 ? Ity_I32 : Ity_I64;//.. //..    seg_selector = newTemp(Ity_I32);//..    ldt_ptr      = newTemp(hWordTy);//..    gdt_ptr      = newTemp(hWordTy);//..    r64          = newTemp(Ity_I64);//.. //..    assign( seg_selector, unop(Iop_16Uto32, getSReg(sreg)) );//..    assign( ldt_ptr, IRExpr_Get( OFFB_LDT, hWordTy ));//..    assign( gdt_ptr, IRExpr_Get( OFFB_GDT, hWordTy ));//.. //..    /*//..    Call this to do the translation and limit checks: //..    ULong x86g_use_seg_selector ( HWord ldt, HWord gdt,//..                                  UInt seg_selector, UInt virtual_addr )//..    *///..    assign( //..       r64, //..       mkIRExprCCall( //..          Ity_I64, //..          0/*regparms*/, //..          "x86g_use_seg_selector", //..          &x86g_use_seg_selector, //..          mkIRExprVec_4( mkexpr(ldt_ptr), mkexpr(gdt_ptr), //..                         mkexpr(seg_selector), virtual)//..       )//..    );//.. //..    /* If the high 32 of the result are non-zero, there was a //..       failure in address translation.  In which case, make a//..       quick exit.//..    *///..    stmt( //..       IRStmt_Exit(//..          binop(Iop_CmpNE32, unop(Iop_64HIto32, mkexpr(r64)), mkU32(0)),//..          Ijk_MapFail,//..          IRConst_U32( guest_eip_curr_instr )//..       )//..    );//.. //..    /* otherwise, here's the translated result. *///..    return unop(Iop_64to32, mkexpr(r64));//.. }/* Generate IR to calculate an address indicated by a ModRM and   following SIB bytes.  The expression, and the number of bytes in   the address mode, are returned (the latter in *len).  Note that   this fn should not be called if the R/M part of the address denotes   a register instead of memory.  If print_codegen is true, text of   the addressing mode is placed in buf.   The computed address is stored in a new tempreg, and the   identity of the tempreg is returned.   extra_bytes holds the number of bytes after the amode, as supplied   by the caller.  This is needed to make sense of %rip-relative   addresses.  Note that the value that *len is set to is only the   length of the amode itself and does not include the value supplied   in extra_bytes. */static IRTemp disAMode_copy2tmp ( IRExpr* addr64 ){   IRTemp tmp = newTemp(Ity_I64);   assign( tmp, addr64 );   return tmp;}static IRTemp disAMode ( Int* len, Prefix pfx, Long delta,                   HChar* buf, Int extra_bytes ){   UChar mod_reg_rm = getUChar(delta);   delta++;   buf[0] = (UChar)0;   vassert(extra_bytes >= 0 && extra_bytes < 10);   /* squeeze out the reg field from mod_reg_rm, since a 256-entry      jump table seems a bit excessive.    */   mod_reg_rm &= 0xC7;                         /* is now XX000YYY */   mod_reg_rm  = toUChar(mod_reg_rm | (mod_reg_rm >> 3));                                               /* is now XX0XXYYY */   mod_reg_rm &= 0x1F;                         /* is now 000XXYYY */   switch (mod_reg_rm) {      /* REX.B==0: (%rax) .. (%rdi), not including (%rsp) or (%rbp).         REX.B==1: (%r8)  .. (%r15), not including (%r12) or (%r13).      */      case 0x00: case 0x01: case 0x02: case 0x03:       /* ! 04 */ /* ! 05 */ case 0x06: case 0x07:         { UChar rm = toUChar(mod_reg_rm & 7);           DIS(buf, "%s(%s)", sorbTxt(pfx), nameIRegRexB(8,pfx,rm));           *len = 1;           return disAMode_copy2tmp(                  handleSegOverride(pfx, getIRegRexB(8,pfx,rm)));         }      /* REX.B==0: d8(%rax) ... d8(%rdi), not including d8(%rsp)          REX.B==1: d8(%r8)  ... d8(%r15), not including d8(%r12)       */      case 0x08: case 0x09: case 0x0A: case 0x0B:       /* ! 0C */ case 0x0D: case 0x0E: case 0x0F:         { UChar rm = toUChar(mod_reg_rm & 7);           Long d   = getSDisp8(delta);           if (d == 0) {              DIS(buf, "%s(%s)", sorbTxt(pfx), nameIRegRexB(8,pfx,rm));           } else {              DIS(buf, "%s%lld(%s)", sorbTxt(pfx), d, nameIRegRexB(8,pfx,rm));           }           *len = 2;           return disAMode_copy2tmp(                  handleSegOverride(pfx,                     binop(Iop_Add64,getIRegRexB(8,pfx,rm),mkU64(d))));         }      /* REX.B==0: d32(%rax) ... d32(%rdi), not including d32(%rsp)         REX.B==1: d32(%r8)  ... d32(%r15), not including d32(%r12)      */      case 0x10: case 0x11: case 0x12: case 0x13:       /* ! 14 */ case 0x15: case 0x16: case 0x17:         { UChar rm = toUChar(mod_reg_rm & 7);           Long  d  = getSDisp32(delta);           DIS(buf, "%s%lld(%s)", sorbTxt(pfx), d, nameIRegRexB(8,pfx,rm));           *len = 5;           return disAMode_copy2tmp(                  handleSegOverride(pfx,                     binop(Iop_Add64,getIRegRexB(8,pfx,rm),mkU64(d))));         }      /* REX.B==0: a register, %rax .. %rdi.  This shouldn't happen. */      /* REX.B==1: a register, %r8  .. %r16.  This shouldn't happen. */      case 0x18: case 0x19: case 0x1A: case 0x1B:      case 0x1C: case 0x1D: case 0x1E: case 0x1F:         vpanic("disAMode(amd64): not an addr!");      /* RIP + disp32.  This assumes that guest_RIP_curr_instr 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -