📄 toir.c
字号:
register references, we need to take the host endianness into account. Supplied value is 0 .. 7 and in the Intel instruction encoding. */static IRType szToITy ( Int n ){ switch (n) { case 1: return Ity_I8; case 2: return Ity_I16; case 4: return Ity_I32; default: vpanic("szToITy(x86)"); }}/* On a little-endian host, less significant bits of the guest registers are at lower addresses. Therefore, if a reference to a register low half has the safe guest state offset as a reference to the full register.*/static Int integerGuestRegOffset ( Int sz, UInt archreg ){ vassert(archreg < 8); /* Correct for little-endian host only. */ vassert(!host_is_bigendian); if (sz == 4 || sz == 2 || (sz == 1 && archreg < 4)) { switch (archreg) { case R_EAX: return OFFB_EAX; case R_EBX: return OFFB_EBX; case R_ECX: return OFFB_ECX; case R_EDX: return OFFB_EDX; case R_ESI: return OFFB_ESI; case R_EDI: return OFFB_EDI; case R_ESP: return OFFB_ESP; case R_EBP: return OFFB_EBP; default: vpanic("integerGuestRegOffset(x86,le)(4,2)"); } } vassert(archreg >= 4 && archreg < 8 && sz == 1); switch (archreg-4) { case R_EAX: return 1+ OFFB_EAX; case R_EBX: return 1+ OFFB_EBX; case R_ECX: return 1+ OFFB_ECX; case R_EDX: return 1+ OFFB_EDX; default: vpanic("integerGuestRegOffset(x86,le)(1h)"); } /* NOTREACHED */ vpanic("integerGuestRegOffset(x86,le)");}static Int segmentGuestRegOffset ( UInt sreg ){ switch (sreg) { case R_ES: return OFFB_ES; case R_CS: return OFFB_CS; case R_SS: return OFFB_SS; case R_DS: return OFFB_DS; case R_FS: return OFFB_FS; case R_GS: return OFFB_GS; default: vpanic("segmentGuestRegOffset(x86)"); }}static Int xmmGuestRegOffset ( UInt xmmreg ){ switch (xmmreg) { case 0: return OFFB_XMM0; case 1: return OFFB_XMM1; case 2: return OFFB_XMM2; case 3: return OFFB_XMM3; case 4: return OFFB_XMM4; case 5: return OFFB_XMM5; case 6: return OFFB_XMM6; case 7: return OFFB_XMM7; default: vpanic("xmmGuestRegOffset"); }}/* Lanes of vector registers are always numbered from zero being the least significant lane (rightmost in the register). */static Int xmmGuestRegLane16offset ( UInt xmmreg, Int laneno ){ /* Correct for little-endian host only. */ vassert(!host_is_bigendian); vassert(laneno >= 0 && laneno < 8); return xmmGuestRegOffset( xmmreg ) + 2 * laneno;}static Int xmmGuestRegLane32offset ( UInt xmmreg, Int laneno ){ /* Correct for little-endian host only. */ vassert(!host_is_bigendian); vassert(laneno >= 0 && laneno < 4); return xmmGuestRegOffset( xmmreg ) + 4 * laneno;}static Int xmmGuestRegLane64offset ( UInt xmmreg, Int laneno ){ /* Correct for little-endian host only. */ vassert(!host_is_bigendian); vassert(laneno >= 0 && laneno < 2); return xmmGuestRegOffset( xmmreg ) + 8 * laneno;}static IRExpr* getIReg ( Int sz, UInt archreg ){ vassert(sz == 1 || sz == 2 || sz == 4); vassert(archreg < 8); return IRExpr_Get( integerGuestRegOffset(sz,archreg), szToITy(sz) );}/* Ditto, but write to a reg instead. */static void putIReg ( Int sz, UInt archreg, IRExpr* e ){ IRType ty = typeOfIRExpr(irbb->tyenv, e); switch (sz) { case 1: vassert(ty == Ity_I8); break; case 2: vassert(ty == Ity_I16); break; case 4: vassert(ty == Ity_I32); break; default: vpanic("putIReg(x86)"); } vassert(archreg < 8); stmt( IRStmt_Put(integerGuestRegOffset(sz,archreg), e) );}static IRExpr* getSReg ( UInt sreg ){ return IRExpr_Get( segmentGuestRegOffset(sreg), Ity_I16 );}static void putSReg ( UInt sreg, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I16); stmt( IRStmt_Put( segmentGuestRegOffset(sreg), e ) );}static IRExpr* getXMMReg ( UInt xmmreg ){ return IRExpr_Get( xmmGuestRegOffset(xmmreg), Ity_V128 );}static IRExpr* getXMMRegLane64 ( UInt xmmreg, Int laneno ){ return IRExpr_Get( xmmGuestRegLane64offset(xmmreg,laneno), Ity_I64 );}static IRExpr* getXMMRegLane64F ( UInt xmmreg, Int laneno ){ return IRExpr_Get( xmmGuestRegLane64offset(xmmreg,laneno), Ity_F64 );}static IRExpr* getXMMRegLane32 ( UInt xmmreg, Int laneno ){ return IRExpr_Get( xmmGuestRegLane32offset(xmmreg,laneno), Ity_I32 );}static IRExpr* getXMMRegLane32F ( UInt xmmreg, Int laneno ){ return IRExpr_Get( xmmGuestRegLane32offset(xmmreg,laneno), Ity_F32 );}static void putXMMReg ( UInt xmmreg, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_V128); stmt( IRStmt_Put( xmmGuestRegOffset(xmmreg), e ) );}static void putXMMRegLane64 ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I64); stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );}static void putXMMRegLane64F ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_F64); stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );}static void putXMMRegLane32F ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_F32); stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );}static void putXMMRegLane32 ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I32); stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );}static void putXMMRegLane16 ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I16); stmt( IRStmt_Put( xmmGuestRegLane16offset(xmmreg,laneno), e ) );}static void assign ( IRTemp dst, IRExpr* e ){ stmt( IRStmt_Tmp(dst, e) );}static void storeLE ( IRExpr* addr, IRExpr* data ){ stmt( IRStmt_Store(Iend_LE,addr,data) );}static IRExpr* unop ( IROp op, IRExpr* a ){ return IRExpr_Unop(op, a);}static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 ){ return IRExpr_Binop(op, a1, a2);}static IRExpr* triop ( IROp op, IRExpr* a1, IRExpr* a2, IRExpr* a3 ){ return IRExpr_Triop(op, a1, a2, a3);}static IRExpr* mkexpr ( IRTemp tmp ){ return IRExpr_Tmp(tmp);}static IRExpr* mkU8 ( UInt i ){ vassert(i < 256); return IRExpr_Const(IRConst_U8( (UChar)i ));}static IRExpr* mkU16 ( UInt i ){ vassert(i < 65536); return IRExpr_Const(IRConst_U16( (UShort)i ));}static IRExpr* mkU32 ( UInt i ){ return IRExpr_Const(IRConst_U32(i));}static IRExpr* mkU64 ( ULong i ){ return IRExpr_Const(IRConst_U64(i));}static IRExpr* mkU ( IRType ty, UInt i ){ if (ty == Ity_I8) return mkU8(i); if (ty == Ity_I16) return mkU16(i); if (ty == Ity_I32) return mkU32(i); /* If this panics, it usually means you passed a size (1,2,4) value as the IRType, rather than a real IRType. */ vpanic("mkU(x86)");}static IRExpr* mkV128 ( UShort mask ){ return IRExpr_Const(IRConst_V128(mask));}static IRExpr* loadLE ( IRType ty, IRExpr* data ){ return IRExpr_Load(Iend_LE,ty,data);}static IROp mkSizedOp ( IRType ty, IROp op8 ){ Int adj; vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32); vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8 || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8 || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8 || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8 || op8 == Iop_Neg8); adj = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2); return adj + op8;}static IROp mkWidenOp ( Int szSmall, Int szBig, Bool signd ){ if (szSmall == 1 && szBig == 4) { return signd ? Iop_8Sto32 : Iop_8Uto32; } if (szSmall == 1 && szBig == 2) { return signd ? Iop_8Sto16 : Iop_8Uto16; } if (szSmall == 2 && szBig == 4) { return signd ? Iop_16Sto32 : Iop_16Uto32; } vpanic("mkWidenOp(x86,guest)");}static IRExpr* mkAnd1 ( IRExpr* x, IRExpr* y ){ vassert(typeOfIRExpr(irbb->tyenv,x) == Ity_I1); vassert(typeOfIRExpr(irbb->tyenv,y) == Ity_I1); return unop(Iop_32to1, binop(Iop_And32, unop(Iop_1Uto32,x), unop(Iop_1Uto32,y)));}/*------------------------------------------------------------*//*--- Helpers for %eflags. ---*//*------------------------------------------------------------*//* -------------- Evaluating the flags-thunk. -------------- *//* Build IR to calculate all the eflags from stored CC_OP/CC_DEP1/CC_DEP2/CC_NDEP. Returns an expression :: Ity_I32. */static IRExpr* mk_x86g_calculate_eflags_all ( void ){ IRExpr** args = mkIRExprVec_4( IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_DEP1, Ity_I32), IRExpr_Get(OFFB_CC_DEP2, Ity_I32), IRExpr_Get(OFFB_CC_NDEP, Ity_I32) ); IRExpr* call = mkIRExprCCall( Ity_I32, 0/*regparm*/, "x86g_calculate_eflags_all", &x86g_calculate_eflags_all, args ); /* Exclude OP and NDEP from definedness checking. We're only interested in DEP1 and DEP2. */ call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3); return call;}/* Build IR to calculate some particular condition from stored CC_OP/CC_DEP1/CC_DEP2/CC_NDEP. Returns an expression :: Ity_Bit. */static IRExpr* mk_x86g_calculate_condition ( X86Condcode cond ){ IRExpr** args = mkIRExprVec_5( mkU32(cond), IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_DEP1, Ity_I32), IRExpr_Get(OFFB_CC_DEP2, Ity_I32), IRExpr_Get(OFFB_CC_NDEP, Ity_I32) ); IRExpr* call = mkIRExprCCall( Ity_I32, 0/*regparm*/, "x86g_calculate_condition", &x86g_calculate_condition, args ); /* Exclude the requested condition, OP and NDEP from definedness checking. We're only interested in DEP1 and DEP2. */ call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4); return unop(Iop_32to1, call);}/* Build IR to calculate just the carry flag from stored CC_OP/CC_DEP1/CC_DEP2/CC_NDEP. Returns an expression :: Ity_I32. */static IRExpr* mk_x86g_calculate_eflags_c ( void ){ IRExpr** args = mkIRExprVec_4( IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_DEP1, Ity_I32), IRExpr_Get(OFFB_CC_DEP2, Ity_I32), IRExpr_Get(OFFB_CC_NDEP, Ity_I32) ); IRExpr* call = mkIRExprCCall( Ity_I32, 3/*regparm*/, "x86g_calculate_eflags_c", &x86g_calculate_eflags_c, args ); /* Exclude OP and NDEP from definedness checking. We're only interested in DEP1 and DEP2. */ call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3); return call;}/* -------------- Building the flags-thunk. -------------- *//* The machinery in this section builds the flag-thunk following a flag-setting operation. Hence the various setFlags_* functions.*/static Bool isAddSub ( IROp op8 ){ return toBool(op8 == Iop_Add8 || op8 == Iop_Sub8);}static Bool isLogic ( IROp op8 ){ return toBool(op8 == Iop_And8 || op8 == Iop_Or8 || op8 == Iop_Xor8);}/* U-widen 8/16/32 bit int expr to 32. */static IRExpr* widenUto32 ( IRExpr* e ){ switch (typeOfIRExpr(irbb->tyenv,e)) { case Ity_I32: return e; case Ity_I16: return unop(Iop_16Uto32,e);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -