📄 toir.c
字号:
= { "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" }; static HChar* ireg32_names[16] = { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", "%r8d", "%r9d", "%r10d","%r11d","%r12d","%r13d","%r14d","%r15d" }; static HChar* ireg16_names[16] = { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di", "%r8w", "%r9w", "%r10w","%r11w","%r12w","%r13w","%r14w","%r15w" }; static HChar* ireg8_names[16] = { "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil", "%r8b", "%r9b", "%r10b","%r11b","%r12b","%r13b","%r14b","%r15b" }; static HChar* ireg8_irregular[8] = { "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh" }; vassert(reg < 16); if (sz == 1) { if (irregular) vassert(reg < 8); } else { vassert(irregular == False); } switch (sz) { case 8: return ireg64_names[reg]; case 4: return ireg32_names[reg]; case 2: return ireg16_names[reg]; case 1: if (irregular) { return ireg8_irregular[reg]; } else { return ireg8_names[reg]; } default: vpanic("nameIReg(amd64)"); }}/* Using the same argument conventions as nameIReg, produce the guest state offset of an integer register. */static Int offsetIReg ( Int sz, UInt reg, Bool irregular ){ vassert(reg < 16); if (sz == 1) { if (irregular) vassert(reg < 8); } else { vassert(irregular == False); } /* Deal with irregular case -- sz==1 and no REX present */ if (sz == 1 && irregular) { switch (reg) { case R_RSP: return 1+ OFFB_RAX; case R_RBP: return 1+ OFFB_RCX; case R_RSI: return 1+ OFFB_RDX; case R_RDI: return 1+ OFFB_RBX; default: break; /* use the normal case */ } } /* Normal case */ return integerGuestReg64Offset(reg);}/* Read the %CL register :: Ity_I8, for shift/rotate operations. */static IRExpr* getIRegCL ( void ){ vassert(!host_is_bigendian); return IRExpr_Get( OFFB_RCX, Ity_I8 );}/* Write to the %AH register. */static void putIRegAH ( IRExpr* e ){ vassert(!host_is_bigendian); vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8); stmt( IRStmt_Put( OFFB_RAX+1, e ) );}/* Read/write various widths of %RAX, as it has various special-purpose uses. */static HChar* nameIRegRAX ( Int sz ){ switch (sz) { case 1: return "%al"; case 2: return "%ax"; case 4: return "%eax"; case 8: return "%rax"; default: vpanic("nameIRegRAX(amd64)"); }}static IRExpr* getIRegRAX ( Int sz ){ vassert(!host_is_bigendian); switch (sz) { case 1: return IRExpr_Get( OFFB_RAX, Ity_I8 ); case 2: return IRExpr_Get( OFFB_RAX, Ity_I16 ); case 4: return IRExpr_Get( OFFB_RAX, Ity_I32 ); case 8: return IRExpr_Get( OFFB_RAX, Ity_I64 ); default: vpanic("getIRegRAX(amd64)"); }}static void putIRegRAX ( Int sz, IRExpr* e ){ IRType ty = typeOfIRExpr(irbb->tyenv, e); vassert(!host_is_bigendian); switch (sz) { case 8: vassert(ty == Ity_I64); stmt( IRStmt_Put( OFFB_RAX, e )); break; case 4: vassert(ty == Ity_I32); stmt( IRStmt_Put( OFFB_RAX, unop(Iop_32Uto64,e) )); break; case 2: vassert(ty == Ity_I16); stmt( IRStmt_Put( OFFB_RAX, e )); break; case 1: vassert(ty == Ity_I8); stmt( IRStmt_Put( OFFB_RAX, e )); break; default: vpanic("putIRegRAX(amd64)"); }}/* Read/write various widths of %RDX, as it has various special-purpose uses. */static IRExpr* getIRegRDX ( Int sz ){ vassert(!host_is_bigendian); switch (sz) { case 1: return IRExpr_Get( OFFB_RDX, Ity_I8 ); case 2: return IRExpr_Get( OFFB_RDX, Ity_I16 ); case 4: return IRExpr_Get( OFFB_RDX, Ity_I32 ); case 8: return IRExpr_Get( OFFB_RDX, Ity_I64 ); default: vpanic("getIRegRDX(amd64)"); }}static void putIRegRDX ( Int sz, IRExpr* e ){ vassert(!host_is_bigendian); vassert(typeOfIRExpr(irbb->tyenv, e) == szToITy(sz)); switch (sz) { case 8: stmt( IRStmt_Put( OFFB_RDX, e )); break; case 4: stmt( IRStmt_Put( OFFB_RDX, unop(Iop_32Uto64,e) )); break; case 2: stmt( IRStmt_Put( OFFB_RDX, e )); break; case 1: stmt( IRStmt_Put( OFFB_RDX, e )); break; default: vpanic("putIRegRDX(amd64)"); }}/* Simplistic functions to deal with the integer registers as a straightforward bank of 16 64-bit regs. */static IRExpr* getIReg64 ( UInt regno ){ return IRExpr_Get( integerGuestReg64Offset(regno), Ity_I64 );}static void putIReg64 ( UInt regno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I64); stmt( IRStmt_Put( integerGuestReg64Offset(regno), e ) );}static HChar* nameIReg64 ( UInt regno ){ return nameIReg( 8, regno, False );}/* Simplistic functions to deal with the lower halves of integer registers as a straightforward bank of 16 32-bit regs. */static IRExpr* getIReg32 ( UInt regno ){ vassert(!host_is_bigendian); return IRExpr_Get( integerGuestReg64Offset(regno), Ity_I32 );}static void putIReg32 ( UInt regno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I32); stmt( IRStmt_Put( integerGuestReg64Offset(regno), unop(Iop_32Uto64,e) ) );}static HChar* nameIReg32 ( UInt regno ){ return nameIReg( 4, regno, False );}/* Simplistic functions to deal with the lower quarters of integer registers as a straightforward bank of 16 16-bit regs. */static IRExpr* getIReg16 ( UInt regno ){ vassert(!host_is_bigendian); return IRExpr_Get( integerGuestReg64Offset(regno), Ity_I16 );}static HChar* nameIReg16 ( UInt regno ){ return nameIReg( 2, regno, False );}/* Sometimes what we know is a 3-bit register number, a REX byte, and which field of the REX byte is to be used to extend to a 4-bit number. These functions cater for that situation. */static IRExpr* getIReg64rexX ( Prefix pfx, UInt lo3bits ){ vassert(lo3bits < 8); vassert(IS_VALID_PFX(pfx)); return getIReg64( lo3bits | (getRexX(pfx) << 3) );}static HChar* nameIReg64rexX ( Prefix pfx, UInt lo3bits ){ vassert(lo3bits < 8); vassert(IS_VALID_PFX(pfx)); return nameIReg( 8, lo3bits | (getRexX(pfx) << 3), False );}static HChar* nameIRegRexB ( Int sz, Prefix pfx, UInt lo3bits ){ vassert(lo3bits < 8); vassert(IS_VALID_PFX(pfx)); vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1); return nameIReg( sz, lo3bits | (getRexB(pfx) << 3), toBool(sz==1 && !haveREX(pfx)) );}static IRExpr* getIRegRexB ( Int sz, Prefix pfx, UInt lo3bits ){ vassert(lo3bits < 8); vassert(IS_VALID_PFX(pfx)); vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1); return IRExpr_Get( offsetIReg( sz, lo3bits | (getRexB(pfx) << 3), toBool(sz==1 && !haveREX(pfx)) ), szToITy(sz) );}static void putIRegRexB ( Int sz, Prefix pfx, UInt lo3bits, IRExpr* e ){ vassert(lo3bits < 8); vassert(IS_VALID_PFX(pfx)); vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1); vassert(typeOfIRExpr(irbb->tyenv, e) == szToITy(sz)); stmt( IRStmt_Put( offsetIReg( sz, lo3bits | (getRexB(pfx) << 3), toBool(sz==1 && !haveREX(pfx)) ), sz==4 ? unop(Iop_32Uto64,e) : e ));}/* Functions for getting register numbers from modrm bytes and REX when we don't have to consider the complexities of integer subreg accesses.*//* Extract the g reg field from a modRM byte, and augment it using the REX.R bit from the supplied REX byte. The R bit usually is associated with the g register field.*/static UInt gregOfRexRM ( Prefix pfx, UChar mod_reg_rm ){ Int reg = (Int)( (mod_reg_rm >> 3) & 7 ); reg += (pfx & PFX_REXR) ? 8 : 0; return reg;}/* Extract the e reg field from a modRM byte, and augment it using the REX.B bit from the supplied REX byte. The B bit usually is associated with the e register field (when modrm indicates e is a register, that is).*/static UInt eregOfRexRM ( Prefix pfx, UChar mod_reg_rm ){ Int rm; vassert(epartIsReg(mod_reg_rm)); rm = (Int)(mod_reg_rm & 0x7); rm += (pfx & PFX_REXB) ? 8 : 0; return rm;}/* General functions for dealing with integer register access. *//* Produce the guest state offset for a reference to the 'g' register field in a modrm byte, taking into account REX (or its absence), and the size of the access.*/static UInt offsetIRegG ( Int sz, Prefix pfx, UChar mod_reg_rm ){ UInt reg; vassert(!host_is_bigendian); vassert(IS_VALID_PFX(pfx)); vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1); reg = gregOfRexRM( pfx, mod_reg_rm ); return offsetIReg( sz, reg, toBool(sz == 1 && !haveREX(pfx)) );}static IRExpr* getIRegG ( Int sz, Prefix pfx, UChar mod_reg_rm ){ return IRExpr_Get( offsetIRegG( sz, pfx, mod_reg_rm ), szToITy(sz) );}static void putIRegG ( Int sz, Prefix pfx, UChar mod_reg_rm, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == szToITy(sz)); if (sz == 4) { e = unop(Iop_32Uto64,e); } stmt( IRStmt_Put( offsetIRegG( sz, pfx, mod_reg_rm ), e ) );}staticHChar* nameIRegG ( Int sz, Prefix pfx, UChar mod_reg_rm ){ return nameIReg( sz, gregOfRexRM(pfx,mod_reg_rm), toBool(sz==1 && !haveREX(pfx)) );}/* Produce the guest state offset for a reference to the 'e' register field in a modrm byte, taking into account REX (or its absence), and the size of the access. eregOfRexRM will assert if mod_reg_rm denotes a memory access rather than a register access.*/static UInt offsetIRegE ( Int sz, Prefix pfx, UChar mod_reg_rm ){ UInt reg; vassert(!host_is_bigendian); vassert(IS_VALID_PFX(pfx)); vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1); reg = eregOfRexRM( pfx, mod_reg_rm ); return offsetIReg( sz, reg, toBool(sz == 1 && !haveREX(pfx)) );}static IRExpr* getIRegE ( Int sz, Prefix pfx, UChar mod_reg_rm ){ return IRExpr_Get( offsetIRegE( sz, pfx, mod_reg_rm ), szToITy(sz) );}static void putIRegE ( Int sz, Prefix pfx, UChar mod_reg_rm, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == szToITy(sz)); if (sz == 4) { e = unop(Iop_32Uto64,e); } stmt( IRStmt_Put( offsetIRegE( sz, pfx, mod_reg_rm ), e ) );}staticHChar* nameIRegE ( Int sz, Prefix pfx, UChar mod_reg_rm ){ return nameIReg( sz, eregOfRexRM(pfx,mod_reg_rm), toBool(sz==1 && !haveREX(pfx)) );}/*------------------------------------------------------------*//*--- For dealing with XMM registers ---*//*------------------------------------------------------------*///.. 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -