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

📄 toir.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* SIB, no displacement.  */      case 0x04: {         UChar sib    = getIByte(delta);         UChar base_r = toUChar(sib & 7);         if (base_r == R_EBP) return 6; else return 2;      }      /* SIB, with 8-bit displacement.  */      case 0x0C: return 3;      /* SIB, with 32-bit displacement.  */      case 0x14: return 6;      default:         vpanic("lengthAMode");         return 0; /*notreached*/   }}/*------------------------------------------------------------*//*--- Disassembling common idioms                          ---*//*------------------------------------------------------------*//* Handle binary integer instructions of the form      op E, G  meaning      op reg-or-mem, reg   Is passed the a ptr to the modRM byte, the actual operation, and the   data size.  Returns the address advanced completely over this   instruction.   E(src) is reg-or-mem   G(dst) is reg.   If E is reg, -->    GET %G,  tmp                       OP %E,   tmp                       PUT tmp, %G    If E is mem and OP is not reversible,                 -->    (getAddr E) -> tmpa                       LD (tmpa), tmpa                       GET %G, tmp2                       OP tmpa, tmp2                       PUT tmp2, %G   If E is mem and OP is reversible                -->    (getAddr E) -> tmpa                       LD (tmpa), tmpa                       OP %G, tmpa                       PUT tmpa, %G*/staticUInt dis_op2_E_G ( UChar       sorb,                   Bool        addSubCarry,                   IROp        op8,                    Bool        keep,                   Int         size,                    Int         delta0,                   HChar*      t_x86opc ){   HChar   dis_buf[50];   Int     len;   IRType  ty   = szToITy(size);   IRTemp  dst1 = newTemp(ty);   IRTemp  src  = newTemp(ty);   IRTemp  dst0 = newTemp(ty);   UChar   rm   = getUChar(delta0);   IRTemp  addr = IRTemp_INVALID;   /* addSubCarry == True indicates the intended operation is      add-with-carry or subtract-with-borrow. */   if (addSubCarry) {      vassert(op8 == Iop_Add8 || op8 == Iop_Sub8);      vassert(keep);   }   if (epartIsReg(rm)) {      /* Specially handle XOR reg,reg, because that doesn't really         depend on reg, and doing the obvious thing potentially         generates a spurious value check failure due to the bogus         dependency.  Ditto SBB reg,reg. */      if ((op8 == Iop_Xor8 || (op8 == Iop_Sub8 && addSubCarry))          && gregOfRM(rm) == eregOfRM(rm)) {         putIReg(size, gregOfRM(rm), mkU(ty,0));      }      assign( dst0, getIReg(size,gregOfRM(rm)) );      assign( src,  getIReg(size,eregOfRM(rm)) );      if (addSubCarry && op8 == Iop_Add8) {         helper_ADC( size, dst1, dst0, src );         putIReg(size, gregOfRM(rm), mkexpr(dst1));      } else      if (addSubCarry && op8 == Iop_Sub8) {         helper_SBB( size, dst1, dst0, src );         putIReg(size, gregOfRM(rm), mkexpr(dst1));      } else {         assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );         if (isAddSub(op8))            setFlags_DEP1_DEP2(op8, dst0, src, ty);         else            setFlags_DEP1(op8, dst1, ty);         if (keep)            putIReg(size, gregOfRM(rm), mkexpr(dst1));      }      DIP("%s%c %s,%s\n", t_x86opc, nameISize(size),                           nameIReg(size,eregOfRM(rm)),                          nameIReg(size,gregOfRM(rm)));      return 1+delta0;   } else {      /* E refers to memory */      addr = disAMode ( &len, sorb, delta0, dis_buf);      assign( dst0, getIReg(size,gregOfRM(rm)) );      assign( src,  loadLE(szToITy(size), mkexpr(addr)) );      if (addSubCarry && op8 == Iop_Add8) {         helper_ADC( size, dst1, dst0, src );         putIReg(size, gregOfRM(rm), mkexpr(dst1));      } else      if (addSubCarry && op8 == Iop_Sub8) {         helper_SBB( size, dst1, dst0, src );         putIReg(size, gregOfRM(rm), mkexpr(dst1));      } else {         assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );         if (isAddSub(op8))            setFlags_DEP1_DEP2(op8, dst0, src, ty);         else            setFlags_DEP1(op8, dst1, ty);         if (keep)            putIReg(size, gregOfRM(rm), mkexpr(dst1));      }      DIP("%s%c %s,%s\n", t_x86opc, nameISize(size),                           dis_buf,nameIReg(size,gregOfRM(rm)));      return len+delta0;   }}/* Handle binary integer instructions of the form      op G, E  meaning      op reg, reg-or-mem   Is passed the a ptr to the modRM byte, the actual operation, and the   data size.  Returns the address advanced completely over this   instruction.   G(src) is reg.   E(dst) is reg-or-mem   If E is reg, -->    GET %E,  tmp                       OP %G,   tmp                       PUT tmp, %E    If E is mem, -->    (getAddr E) -> tmpa                       LD (tmpa), tmpv                       OP %G, tmpv                       ST tmpv, (tmpa)*/staticUInt dis_op2_G_E ( UChar       sorb,                   Bool        addSubCarry,                   IROp        op8,                    Bool        keep,                   Int         size,                    Int         delta0,                   HChar*      t_x86opc ){   HChar   dis_buf[50];   Int     len;   IRType  ty   = szToITy(size);   IRTemp  dst1 = newTemp(ty);   IRTemp  src  = newTemp(ty);   IRTemp  dst0 = newTemp(ty);   UChar   rm   = getIByte(delta0);   IRTemp  addr = IRTemp_INVALID;   /* addSubCarry == True indicates the intended operation is      add-with-carry or subtract-with-borrow. */   if (addSubCarry) {      vassert(op8 == Iop_Add8 || op8 == Iop_Sub8);      vassert(keep);   }   if (epartIsReg(rm)) {      /* Specially handle XOR reg,reg, because that doesn't really         depend on reg, and doing the obvious thing potentially         generates a spurious value check failure due to the bogus         dependency.  Ditto SBB reg,reg.*/      if ((op8 == Iop_Xor8 || (op8 == Iop_Sub8 && addSubCarry))          && gregOfRM(rm) == eregOfRM(rm)) {         putIReg(size, eregOfRM(rm), mkU(ty,0));      }      assign(dst0, getIReg(size,eregOfRM(rm)));      assign(src,  getIReg(size,gregOfRM(rm)));      if (addSubCarry && op8 == Iop_Add8) {         helper_ADC( size, dst1, dst0, src );         putIReg(size, eregOfRM(rm), mkexpr(dst1));      } else      if (addSubCarry && op8 == Iop_Sub8) {         helper_SBB( size, dst1, dst0, src );         putIReg(size, eregOfRM(rm), mkexpr(dst1));      } else {         assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));         if (isAddSub(op8))            setFlags_DEP1_DEP2(op8, dst0, src, ty);         else            setFlags_DEP1(op8, dst1, ty);         if (keep)            putIReg(size, eregOfRM(rm), mkexpr(dst1));      }      DIP("%s%c %s,%s\n", t_x86opc, nameISize(size),                           nameIReg(size,gregOfRM(rm)),                          nameIReg(size,eregOfRM(rm)));      return 1+delta0;   }   /* E refers to memory */       {      addr = disAMode ( &len, sorb, delta0, dis_buf);      assign(dst0, loadLE(ty,mkexpr(addr)));      assign(src,  getIReg(size,gregOfRM(rm)));      if (addSubCarry && op8 == Iop_Add8) {         helper_ADC( size, dst1, dst0, src );         storeLE(mkexpr(addr), mkexpr(dst1));      } else      if (addSubCarry && op8 == Iop_Sub8) {         helper_SBB( size, dst1, dst0, src );         storeLE(mkexpr(addr), mkexpr(dst1));      } else {         assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));         if (isAddSub(op8))            setFlags_DEP1_DEP2(op8, dst0, src, ty);         else            setFlags_DEP1(op8, dst1, ty);         if (keep)            storeLE(mkexpr(addr), mkexpr(dst1));      }      DIP("%s%c %s,%s\n", t_x86opc, nameISize(size),                           nameIReg(size,gregOfRM(rm)), dis_buf);      return len+delta0;   }}/* Handle move instructions of the form      mov E, G  meaning      mov reg-or-mem, reg   Is passed the a ptr to the modRM byte, and the data size.  Returns   the address advanced completely over this instruction.   E(src) is reg-or-mem   G(dst) is reg.   If E is reg, -->    GET %E,  tmpv                       PUT tmpv, %G    If E is mem  -->    (getAddr E) -> tmpa                       LD (tmpa), tmpb                       PUT tmpb, %G*/staticUInt dis_mov_E_G ( UChar       sorb,                   Int         size,                    Int         delta0 ){   Int len;   UChar rm = getIByte(delta0);   HChar dis_buf[50];   if (epartIsReg(rm)) {      putIReg(size, gregOfRM(rm), getIReg(size, eregOfRM(rm)));      DIP("mov%c %s,%s\n", nameISize(size),                            nameIReg(size,eregOfRM(rm)),                           nameIReg(size,gregOfRM(rm)));      return 1+delta0;   }   /* E refers to memory */       {      IRTemp addr = disAMode ( &len, sorb, delta0, dis_buf );      putIReg(size, gregOfRM(rm), loadLE(szToITy(size), mkexpr(addr)));      DIP("mov%c %s,%s\n", nameISize(size),                            dis_buf,nameIReg(size,gregOfRM(rm)));      return delta0+len;   }}/* Handle move instructions of the form      mov G, E  meaning      mov reg, reg-or-mem   Is passed the a ptr to the modRM byte, and the data size.  Returns   the address advanced completely over this instruction.   G(src) is reg.   E(dst) is reg-or-mem   If E is reg, -->    GET %G,  tmp                       PUT tmp, %E    If E is mem, -->    (getAddr E) -> tmpa                       GET %G, tmpv                       ST tmpv, (tmpa) */staticUInt dis_mov_G_E ( UChar       sorb,                   Int         size,                    Int         delta0 ){   Int len;   UChar rm = getIByte(delta0);   HChar dis_buf[50];   if (epartIsReg(rm)) {      putIReg(size, eregOfRM(rm), getIReg(size, gregOfRM(rm)));      DIP("mov%c %s,%s\n", nameISize(size),                            nameIReg(size,gregOfRM(rm)),                           nameIReg(size,eregOfRM(rm)));      return 1+delta0;   }   /* E refers to memory */       {      IRTemp addr = disAMode ( &len, sorb, delta0, dis_buf);      storeLE( mkexpr(addr), getIReg(size, gregOfRM(rm)) );      DIP("mov%c %s,%s\n", nameISize(size),                            nameIReg(size,gregOfRM(rm)), dis_buf);      return len+delta0;   }}/* op $immediate, AL/AX/EAX. */staticUInt dis_op_imm_A ( Int    size,                    Bool   carrying,                    IROp   op8,                    Bool   keep,                    Int    delta,                    HChar* t_x86opc ){   IRType ty   = szToITy(size);   IRTemp dst0 = newTemp(ty);   IRTemp src  = newTemp(ty);   IRTemp dst1 = newTemp(ty);   UInt lit    = getUDisp(size,delta);   assign(dst0, getIReg(size,R_EAX));   assign(src,  mkU(ty,lit));   if (isAddSub(op8) && !carrying) {      assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );      setFlags_DEP1_DEP2(op8, dst0, src, ty);   }    else   if (isLogic(op8)) {      vassert(!carrying);      assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );      setFlags_DEP1(op8, dst1, ty);   }    else   if (op8 == Iop_Add8 && carrying) {      helper_ADC( size, dst1, dst0, src );   }   else   if (op8 == Iop_Sub8 && carrying) {      helper_SBB( size, dst1, dst0, src );   }   else      vpanic("dis_op_imm_A(x86,guest)");   if (keep)      putIReg(size, R_EAX, mkexpr(dst1));   DIP("%s%c $0x%x, %s\n", t_x86opc, nameISize(size),                            lit, nameIReg(size,R_EAX));   return delta+size;}/* Sign- and Zero-extending moves. */staticUInt dis_movx_E_G ( UChar      sorb,                    Int delta, Int szs, Int szd, Bool sign_extend ){   UChar rm = getIByte(delta);   if (epartIsReg(rm)) {      putIReg(szd, gregOfRM(rm),                   unop(mkWidenOp(szs,szd,sign_extend),                         getIReg(szs,eregOfRM(rm))));      DIP("mov%c%c%c %s,%s\n", sign_extend ? 's' : 'z',                               nameISize(szs), nameISize(szd),                               nameIReg(szs,eregOfRM(rm)),                               nameIReg(szd,gregOfRM(rm)));      return 1+delta;   }   /* E refers to memory */       {      Int    len;      HChar  dis_buf[50];      IRTemp addr = disAMode ( &len, sorb, delta, dis_buf );      putIReg(szd, gregOfRM(rm),                   unop(m

⌨️ 快捷键说明

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