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

📄 toir.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
/*--- JMP helpers                                          ---*//*------------------------------------------------------------*/static void jmp_lit( IRJumpKind kind, Addr32 d32 ){  irbb->next     = mkU32(d32);  irbb->jumpkind = kind;}static void jmp_treg( IRJumpKind kind, IRTemp t ){   irbb->next = mkexpr(t);   irbb->jumpkind = kind;}static void jcc_01( X86Condcode cond, Addr32 d32_false, Addr32 d32_true ){   Bool        invert;   X86Condcode condPos;   condPos = positiveIse_X86Condcode ( cond, &invert );   if (invert) {      stmt( IRStmt_Exit( mk_x86g_calculate_condition(condPos),                         Ijk_Boring,                         IRConst_U32(d32_false) ) );      irbb->next     = mkU32(d32_true);      irbb->jumpkind = Ijk_Boring;   } else {      stmt( IRStmt_Exit( mk_x86g_calculate_condition(condPos),                         Ijk_Boring,                         IRConst_U32(d32_true) ) );      irbb->next     = mkU32(d32_false);      irbb->jumpkind = Ijk_Boring;   }}/*------------------------------------------------------------*//*--- Disassembling addressing modes                       ---*//*------------------------------------------------------------*/static HChar* sorbTxt ( UChar sorb ){   switch (sorb) {      case 0:    return ""; /* no override */      case 0x3E: return "%ds";      case 0x26: return "%es:";      case 0x64: return "%fs:";      case 0x65: return "%gs:";      default: vpanic("sorbTxt(x86,guest)");   }}/* '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 ( UChar sorb, IRExpr* 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.  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.  */static IRTemp disAMode_copy2tmp ( IRExpr* addr32 ){   IRTemp tmp = newTemp(Ity_I32);   assign( tmp, addr32 );   return tmp;}static IRTemp disAMode ( Int* len, UChar sorb, Int delta, HChar* buf ){   UChar mod_reg_rm = getIByte(delta);   delta++;   buf[0] = (UChar)0;   /* 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) {      /* (%eax) .. (%edi), not including (%esp) or (%ebp).         --> GET %reg, t       */      case 0x00: case 0x01: case 0x02: case 0x03:       /* ! 04 */ /* ! 05 */ case 0x06: case 0x07:         { UChar rm = mod_reg_rm;           DIS(buf, "%s(%s)", sorbTxt(sorb), nameIReg(4,rm));           *len = 1;           return disAMode_copy2tmp(                  handleSegOverride(sorb, getIReg(4,rm)));         }      /* d8(%eax) ... d8(%edi), not including d8(%esp)          --> GET %reg, t ; ADDL d8, t      */      case 0x08: case 0x09: case 0x0A: case 0x0B:       /* ! 0C */ case 0x0D: case 0x0E: case 0x0F:         { UChar rm = toUChar(mod_reg_rm & 7);           UInt  d  = getSDisp8(delta);           DIS(buf, "%s%d(%s)", sorbTxt(sorb), (Int)d, nameIReg(4,rm));           *len = 2;           return disAMode_copy2tmp(                  handleSegOverride(sorb,                     binop(Iop_Add32,getIReg(4,rm),mkU32(d))));         }      /* d32(%eax) ... d32(%edi), not including d32(%esp)         --> GET %reg, t ; ADDL d8, t      */      case 0x10: case 0x11: case 0x12: case 0x13:       /* ! 14 */ case 0x15: case 0x16: case 0x17:         { UChar rm = toUChar(mod_reg_rm & 7);           UInt  d  = getUDisp32(delta);           DIS(buf, "%s0x%x(%s)", sorbTxt(sorb), (Int)d, nameIReg(4,rm));           *len = 5;           return disAMode_copy2tmp(                  handleSegOverride(sorb,                     binop(Iop_Add32,getIReg(4,rm),mkU32(d))));         }      /* a register, %eax .. %edi.  This shouldn't happen. */      case 0x18: case 0x19: case 0x1A: case 0x1B:      case 0x1C: case 0x1D: case 0x1E: case 0x1F:         vpanic("disAMode(x86): not an addr!");      /* a 32-bit literal address         --> MOV d32, tmp       */      case 0x05:          { UInt d = getUDisp32(delta);           *len = 5;           DIS(buf, "%s(0x%x)", sorbTxt(sorb), d);           return disAMode_copy2tmp(                      handleSegOverride(sorb, mkU32(d)));         }      case 0x04: {         /* SIB, with no displacement.  Special cases:            -- %esp cannot act as an index value.                 If index_r indicates %esp, zero is used for the index.            -- when mod is zero and base indicates EBP, base is instead               a 32-bit literal.            It's all madness, I tell you.  Extract %index, %base and             scale from the SIB byte.  The value denoted is then:               | %index == %ESP && %base == %EBP               = d32 following SIB byte               | %index == %ESP && %base != %EBP               = %base               | %index != %ESP && %base == %EBP               = d32 following SIB byte + (%index << scale)               | %index != %ESP && %base != %ESP               = %base + (%index << scale)            What happens to the souls of CPU architects who dream up such            horrendous schemes, do you suppose?           */         UChar sib     = getIByte(delta);         UChar scale   = toUChar((sib >> 6) & 3);         UChar index_r = toUChar((sib >> 3) & 7);         UChar base_r  = toUChar(sib & 7);         delta++;         if (index_r != R_ESP && base_r != R_EBP) {            DIS(buf, "%s(%s,%s,%d)", sorbTxt(sorb),                       nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale);            *len = 2;            return               disAMode_copy2tmp(                handleSegOverride(sorb,                  binop(Iop_Add32,                         getIReg(4,base_r),                        binop(Iop_Shl32, getIReg(4,index_r),                              mkU8(scale)))));         }         if (index_r != R_ESP && base_r == R_EBP) {            UInt d = getUDisp32(delta);            DIS(buf, "%s0x%x(,%s,%d)", sorbTxt(sorb), d,                       nameIReg(4,index_r), 1<<scale);            *len = 6;            return               disAMode_copy2tmp(               handleSegOverride(sorb,                   binop(Iop_Add32,                        binop(Iop_Shl32, getIReg(4,index_r), mkU8(scale)),                        mkU32(d))));         }         if (index_r == R_ESP && base_r != R_EBP) {            DIS(buf, "%s(%s,,)", sorbTxt(sorb), nameIReg(4,base_r));            *len = 2;            return disAMode_copy2tmp(                   handleSegOverride(sorb, getIReg(4,base_r)));         }         if (index_r == R_ESP && base_r == R_EBP) {            UInt d = getUDisp32(delta);            DIS(buf, "%s0x%x()", sorbTxt(sorb), d);            *len = 6;            vpanic("disAMode(x86):untested amode: 8");            return disAMode_copy2tmp(                   handleSegOverride(sorb, mkU32(d)));         }         /*NOTREACHED*/         vassert(0);      }      /* SIB, with 8-bit displacement.  Special cases:         -- %esp cannot act as an index value.              If index_r indicates %esp, zero is used for the index.         Denoted value is:            | %index == %ESP            = d8 + %base            | %index != %ESP            = d8 + %base + (%index << scale)      */      case 0x0C: {         UChar sib     = getIByte(delta);         UChar scale   = toUChar((sib >> 6) & 3);         UChar index_r = toUChar((sib >> 3) & 7);         UChar base_r  = toUChar(sib & 7);         UInt  d       = getSDisp8(delta+1);         if (index_r == R_ESP) {            DIS(buf, "%s%d(%s,,)", sorbTxt(sorb),                                    (Int)d, nameIReg(4,base_r));            *len = 3;            return disAMode_copy2tmp(                   handleSegOverride(sorb,                       binop(Iop_Add32, getIReg(4,base_r), mkU32(d)) ));         } else {            DIS(buf, "%s%d(%s,%s,%d)", sorbTxt(sorb), (Int)d,                      nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale);            *len = 3;            return                 disAMode_copy2tmp(                handleSegOverride(sorb,                  binop(Iop_Add32,                        binop(Iop_Add32,                               getIReg(4,base_r),                               binop(Iop_Shl32,                                     getIReg(4,index_r), mkU8(scale))),                        mkU32(d))));         }	 /*NOTREACHED*/         vassert(0);      }      /* SIB, with 32-bit displacement.  Special cases:         -- %esp cannot act as an index value.              If index_r indicates %esp, zero is used for the index.         Denoted value is:            | %index == %ESP            = d32 + %base            | %index != %ESP            = d32 + %base + (%index << scale)      */      case 0x14: {         UChar sib     = getIByte(delta);         UChar scale   = toUChar((sib >> 6) & 3);         UChar index_r = toUChar((sib >> 3) & 7);         UChar base_r  = toUChar(sib & 7);         UInt d        = getUDisp32(delta+1);         if (index_r == R_ESP) {            DIS(buf, "%s%d(%s,,)", sorbTxt(sorb),                                    (Int)d, nameIReg(4,base_r));            *len = 6;            return disAMode_copy2tmp(                   handleSegOverride(sorb,                       binop(Iop_Add32, getIReg(4,base_r), mkU32(d)) ));         } else {            DIS(buf, "%s%d(%s,%s,%d)", sorbTxt(sorb), (Int)d,                      nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale);            *len = 6;            return                 disAMode_copy2tmp(                handleSegOverride(sorb,                  binop(Iop_Add32,                        binop(Iop_Add32,                               getIReg(4,base_r),                               binop(Iop_Shl32,                                     getIReg(4,index_r), mkU8(scale))),                        mkU32(d))));         }	 /*NOTREACHED*/         vassert(0);      }      default:         vpanic("disAMode(x86)");         return 0; /*notreached*/   }}/* Figure out the number of (insn-stream) bytes constituting the amode   beginning at delta.  Is useful for getting hold of literals beyond   the end of the amode before it has been disassembled.  */static UInt lengthAMode ( Int delta ){   UChar mod_reg_rm = getIByte(delta); delta++;   /* 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) {      /* (%eax) .. (%edi), not including (%esp) or (%ebp). */      case 0x00: case 0x01: case 0x02: case 0x03:       /* ! 04 */ /* ! 05 */ case 0x06: case 0x07:         return 1;      /* d8(%eax) ... d8(%edi), not including d8(%esp). */       case 0x08: case 0x09: case 0x0A: case 0x0B:       /* ! 0C */ case 0x0D: case 0x0E: case 0x0F:         return 2;      /* d32(%eax) ... d32(%edi), not including d32(%esp). */      case 0x10: case 0x11: case 0x12: case 0x13:       /* ! 14 */ case 0x15: case 0x16: case 0x17:         return 5;      /* a register, %eax .. %edi.  (Not an addr, but still handled.) */      case 0x18: case 0x19: case 0x1A: case 0x1B:      case 0x1C: case 0x1D: case 0x1E: case 0x1F:         return 1;      /* a 32-bit literal address. */      case 0x05: return 5;

⌨️ 快捷键说明

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