From c978f02acccbce2ab5e652ec8bb6066b52e8f549 Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Thu, 1 May 2008 14:06:49 +0000 Subject: [PATCH] Use new function MDExtractAddressFields to refactor code. --- SMPBasicBlock.cpp | 30 +++----- SMPDataFlowAnalysis.cpp | 16 ++-- SMPInstr.cpp | 160 ++++++++++++++++------------------------ 3 files changed, 84 insertions(+), 122 deletions(-) diff --git a/SMPBasicBlock.cpp b/SMPBasicBlock.cpp index d0ce90f5..70f5e50b 100644 --- a/SMPBasicBlock.cpp +++ b/SMPBasicBlock.cpp @@ -281,30 +281,24 @@ bool SMPBasicBlock::MDAlreadyKilled(op_t Opnd1) const { else { // Should we add Opnd1 to the KillSet every time we return true below? **!!** op_t TempOp; - if (Opnd1.hasSIB) { - int BaseReg = sib_base(Opnd1); - short IndexReg = sib_index(Opnd1); - TempOp.type = o_reg; + TempOp.type = o_reg; + int BaseReg; + int IndexReg; + ushort ScaleFactor; + ea_t displacement; + + MDExtractAddressFields(Opnd1, BaseReg, IndexReg, ScaleFactor, displacement); + + if (R_none != BaseReg) { TempOp.reg = (ushort) BaseReg; if (this->KillSet.end() != this->KillSet.find(TempOp)) return true; - if (R_sp != IndexReg) { // Cannot have ESP index reg in SIB - TempOp.reg = (ushort) IndexReg; - if (this->KillSet.end() != this->KillSet.find(TempOp)) - return true; - } } - else { // no SIB - ushort BaseReg; - if (Opnd1.type == o_phrase) - BaseReg = Opnd1.phrase; - else // o_displ - BaseReg = Opnd1.reg; - TempOp.type = o_reg; - TempOp.reg = BaseReg; + if (R_none != IndexReg) { // Cannot have ESP index reg in SIB + TempOp.reg = (ushort) IndexReg; if (this->KillSet.end() != this->KillSet.find(TempOp)) return true; - } // end if SIB ... else ... + } } // end if (FoundInKillSet) ... else ... break; default: diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp index c8f5cb6a..6936181e 100644 --- a/SMPDataFlowAnalysis.cpp +++ b/SMPDataFlowAnalysis.cpp @@ -279,18 +279,20 @@ void PrintDefUse(ulong feature, int OpNum) { // DEBUG print SIB info for an operand. void PrintSIB(op_t Opnd) { - int BaseReg = sib_base(Opnd); - short IndexReg = sib_index(Opnd); - int ScaleFactor = sib_scale(Opnd); + int BaseReg; + int IndexReg; + ushort ScaleFactor; + ea_t offset; #define NAME_LEN 5 char BaseName[NAME_LEN] = {'N', 'o', 'n', 'e', '\0'}; char IndexName[NAME_LEN] = {'N', 'o', 'n', 'e', '\0'}; -#if 1 - if (!((BaseReg == R_bp) && (Opnd.type == o_mem))) // EBP can be SIB code for NO BASE REG -#endif + + MDExtractAddressFields(Opnd, BaseReg, IndexReg, ScaleFactor, offset); + + if (BaseReg != R_none) qstrncpy(BaseName, RegNames[BaseReg], NAME_LEN - 1); - if (IndexReg != R_sp) { // SIB code for NO INDEX REG + if (IndexReg != R_none) { qstrncpy(IndexName, RegNames[IndexReg], NAME_LEN -1); } msg(" Base %s Index %s Scale %d", BaseName, IndexName, ScaleFactor); diff --git a/SMPInstr.cpp b/SMPInstr.cpp index 9d0b9ef1..1fb0af47 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -772,6 +772,10 @@ void SMPInstr::MDFixupDefUseLists(void) { // operand, because register USEs, not DEFs, happen within the addressing expressions. size_t OpNum; SMPOperandType RefType; + int BaseReg; + int IndexReg; + ushort ScaleFactor; + ea_t displacement; bool UseFP = true; bool HasIndexReg = false; bool leaInst = (NN_lea == this->SMPcmd.itype); @@ -791,103 +795,58 @@ void SMPInstr::MDFixupDefUseLists(void) { for (OpNum = 0; OpNum < UA_MAXOP; ++OpNum) { op_t Opnd = SMPcmd.Operands[OpNum]; if ((Opnd.type == o_phrase) || (Opnd.type == o_displ) || (Opnd.type == o_mem)) { - if (Opnd.hasSIB) { - if (DebugFlag) { - msg("DEBUG: hasSIB\n"); - } - int BaseReg = sib_base(Opnd); - short IndexReg = sib_index(Opnd); - if ((R_none != IndexReg) && (R_sp != IndexReg)) { - op_t IndexOpnd = Opnd; // Init to current operand field values - IndexOpnd.type = o_reg; // Change type and reg fields - IndexOpnd.reg = IndexReg; - IndexOpnd.hasSIB = 0; - IndexOpnd.set_showed(); - // We want to map AH, AL, and AX to EAX, etc. throughout our data flow - // analysis and type inference systems. - IndexOpnd.reg = MDCanonicalizeSubReg(IndexOpnd.reg); - if (0 == sib_scale(Opnd)) - this->Uses.SetRef(IndexOpnd); - else {// scaling == shift ==> NUMERIC - HasIndexReg = true; - this->Uses.SetRef(IndexOpnd, NUMERIC); - } - } - if (R_none != BaseReg) { - op_t BaseOpnd = Opnd; // Init to current operand field values - BaseOpnd.type = o_reg; // Change type and reg fields - BaseOpnd.reg = BaseReg; - BaseOpnd.hasSIB = 0; - BaseOpnd.set_showed(); - if (BaseOpnd.is_reg(R_bp) && (Opnd.type == o_mem)) { - if (DebugFlag) msg("EBP base reg ignored at %x\n", this->GetAddr()); - } - else { - if (DebugFlag) msg("base reg %d not ignored at %x\n", BaseReg, this->GetAddr()); - // We want to map AH, AL, and AX to EAX, etc. throughout our data flow - // analysis and type inference systems. - BaseOpnd.reg = MDCanonicalizeSubReg(BaseOpnd.reg); - RefType = UNINIT; -#if SMP_BASEREG_POINTER_TYPE - // R_sp and R_bp will get type STACKPTR in SMPInstr::SetImmedTypes(). - // Other registers used as base registers should get their USEs as - // base registers typed as POINTER, which might get refined later - // to STACKPTR, GLOBALPTR, HEAPPTR, etc. - // NOTE: the NN_lea opcode is often used without a true base register. - // E.g. lea eax,[eax+eax+5] is an x86 idiom for eax:=eax*2+5, which - // could not be done in one instruction without using the addressing - // modes of the machine to do the arithmetic. We don't want to set the - // USE of EAX to POINTER in this case, so we will conservatively skip - // all lea instructions here. - // We cannot be sure that a register is truly a base register unless - // there is also an index register. E.g. with reg+displacement, we - // could have memaddr+indexreg or basereg+offset, depending on what - // the displacement is. - if (BaseOpnd.is_reg(R_sp) || (UseFP && BaseOpnd.is_reg(R_bp)) - || leaInst || (!HasIndexReg)) { - ; - } - else { - RefType = POINTER; - } -#endif - this->Uses.SetRef(BaseOpnd, RefType); - } - } - else { - msg("WARNING: R_none base register in SIB: %s\n", this->GetDisasm()); + MDExtractAddressFields(Opnd, BaseReg, IndexReg, ScaleFactor, displacement); + if (R_none != IndexReg) { + op_t IndexOpnd = Opnd; // Init to current operand field values + IndexOpnd.type = o_reg; // Change type and reg fields + IndexOpnd.reg = IndexReg; + IndexOpnd.hasSIB = 0; + IndexOpnd.set_showed(); + // We want to map AH, AL, and AX to EAX, etc. throughout our data flow + // analysis and type inference systems. + IndexOpnd.reg = MDCanonicalizeSubReg(IndexOpnd.reg); + if (0 == ScaleFactor) + this->Uses.SetRef(IndexOpnd); + else { // scaling == shift ==> NUMERIC + HasIndexReg = true; + this->Uses.SetRef(IndexOpnd, NUMERIC); } } - else { // no SIB byte; can have base reg but no index reg - ushort BaseReg = Opnd.reg; // cannot be R_none for no SIB case + if (R_none != BaseReg) { op_t BaseOpnd = Opnd; // Init to current operand field values BaseOpnd.type = o_reg; // Change type and reg fields BaseOpnd.reg = BaseReg; BaseOpnd.hasSIB = 0; BaseOpnd.set_showed(); - if (Opnd.type == o_mem) { - if (!(BaseOpnd.is_reg(0) || BaseOpnd.is_reg(R_bp))) { - msg("base reg %d ignored at %x\n", BaseOpnd.reg, this->GetAddr()); - } + // We want to map AH, AL, and AX to EAX, etc. throughout our data flow + // analysis and type inference systems. + BaseOpnd.reg = MDCanonicalizeSubReg(BaseOpnd.reg); + RefType = UNINIT; +#if SMP_BASEREG_POINTER_TYPE + // R_sp and R_bp will get type STACKPTR in SMPInstr::SetImmedTypes(). + // Other registers used as base registers should get their USEs as + // base registers typed as POINTER, which might get refined later + // to STACKPTR, GLOBALPTR, HEAPPTR, etc. + // NOTE: the NN_lea opcode is often used without a true base register. + // E.g. lea eax,[eax+eax+5] is an x86 idiom for eax:=eax*2+5, which + // could not be done in one instruction without using the addressing + // modes of the machine to do the arithmetic. We don't want to set the + // USE of EAX to POINTER in this case, so we will conservatively skip + // all lea instructions here. + // We cannot be sure that a register is truly a base register unless + // there is also an index register. E.g. with reg+displacement, we + // could have memaddr+indexreg or basereg+offset, depending on what + // the displacement is. + if (BaseOpnd.is_reg(R_sp) || (UseFP && BaseOpnd.is_reg(R_bp)) + || leaInst || (!HasIndexReg)) { + ; } else { - // We want to map AH, AL, and AX to EAX, etc. throughout our data flow - // analysis and type inference systems. - BaseOpnd.reg = MDCanonicalizeSubReg(BaseOpnd.reg); - RefType = UNINIT; -#if SMP_BASEREG_POINTER_TYPE - // See comments above for BaseReg POINTER types. - if (BaseOpnd.is_reg(R_sp) || (UseFP && BaseOpnd.is_reg(R_bp)) - || leaInst || (!HasIndexReg)) { - ; - } - else { - RefType = POINTER; - } -#endif - this->Uses.SetRef(BaseOpnd, RefType); + RefType = POINTER; } - } +#endif + this->Uses.SetRef(BaseOpnd, RefType); + } // end if R_none != BaseReg } // end if (o_phrase or o_displ operand) } // end for (all operands) @@ -1896,18 +1855,20 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { // Handle x86 opcode SIB byte annotations. void SMPInstr::MDAnnotateSIBStackConstants(FILE *AnnotFile, op_t Opnd, ea_t offset, bool UseFP) { - int BaseReg = sib_base(Opnd); - short IndexReg = sib_index(Opnd); - if (BaseReg == R_none) { - msg("BaseReg of R_none at %x\n", this->address); - } + int BaseReg; + int IndexReg; + ea_t displacement; + ushort ScaleFactor; + + MDExtractAddressFields(Opnd, BaseReg, IndexReg, ScaleFactor, displacement); + if (BaseReg == R_sp) { // ESP cannot be IndexReg // ESP-relative constant offset qfprintf(AnnotFile, "%10x %6d PTRIMMEDESP STACK %d displ %s\n", this->SMPcmd.ea, this->SMPcmd.size, offset, this->disasm); } - else if (UseFP && ((IndexReg == R_bp) || ((BaseReg == R_bp) && (Opnd.type != o_mem)))) { + else if (UseFP && ((IndexReg == R_bp) || (BaseReg == R_bp))) { // EBP-relative constant offset qfprintf(AnnotFile, "%10x %6d PTRIMMEDEBP STACK %d displ %s\n", @@ -1922,6 +1883,11 @@ void SMPInstr::MDAnnotateSIBStackConstants(FILE *AnnotFile, op_t Opnd, ea_t offs // offsets if EBP is being used as a frame pointer (UseFP == true). void SMPInstr::AnnotateStackConstants(bool UseFP, FILE *AnnotFile) { op_t Opnd; + ea_t offset; + int BaseReg; + int IndexReg; + ushort ScaleFactor; + #if 0 if (this->address == 0x80925f4) { msg("PROBLEM INSTRUCTION: \n"); @@ -1930,13 +1896,14 @@ void SMPInstr::AnnotateStackConstants(bool UseFP, FILE *AnnotFile) { #endif for (int i = 0; i < UA_MAXOP; ++i) { Opnd = SMPcmd.Operands[i]; + if ((Opnd.type == o_displ) || (Opnd.type == o_phrase)) + MDExtractAddressFields(Opnd, BaseReg, IndexReg, ScaleFactor, offset); + if (Opnd.type == o_displ) { - ea_t offset = Opnd.addr; if (Opnd.hasSIB) { MDAnnotateSIBStackConstants(AnnotFile, Opnd, offset, UseFP); } else { // no SIB - ushort BaseReg = Opnd.reg; if (BaseReg == R_sp) { // ESP-relative constant offset qfprintf(AnnotFile, @@ -1952,12 +1919,11 @@ void SMPInstr::AnnotateStackConstants(bool UseFP, FILE *AnnotFile) { } // end if (Opnd.hasSIB) ... else ... } // end if (Opnd.type == o_displ) else if (Opnd.type == o_phrase) { - ea_t offset = 0; // mmStrata thinks [esp] is [esp+0] + offset = 0; // mmStrata thinks [esp] is [esp+0] if (Opnd.hasSIB) { MDAnnotateSIBStackConstants(AnnotFile, Opnd, offset, UseFP); } else { // Something like [ecx]; is it [esp] or [ebp] ? - ushort BaseReg = Opnd.reg; if (BaseReg == R_sp) { // ESP-relative constant offset qfprintf(AnnotFile, -- GitLab