From cc4458765c0202899eec3818b84fd5d24d904a0a Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Wed, 30 Apr 2008 19:28:31 +0000 Subject: [PATCH] Add functions MDExtractAddressFields, MDIsIndirectMemoryOpnd, and DefOrUseSet::TypesAgreeNoFlags. --- SMPDataFlowAnalysis.cpp | 106 +++++++++++++++++++++++++++++++++++++++- SMPDataFlowAnalysis.h | 9 +++- 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp index e1c9f610..c8f5cb6a 100644 --- a/SMPDataFlowAnalysis.cpp +++ b/SMPDataFlowAnalysis.cpp @@ -145,6 +145,89 @@ void SetGlobalIndex(op_t *TempOp, size_t index) { return; } +// Return true if CurrOp could be an indirect memory reference. +bool MDIsIndirectMemoryOpnd(op_t CurrOp, bool UseFP) { + bool indirect = false; + if ((CurrOp.type != o_mem) && (CurrOp.type != o_phrase) && (CurrOp.type != o_displ)) + return false; + + if (CurrOp.hasSIB) { + int BaseReg = sib_base(CurrOp); + short IndexReg = sib_index(CurrOp); + if ((R_none != IndexReg) && (R_sp != IndexReg)) { + if ((R_bp == IndexReg) && UseFP) + ; + else + indirect = true; + } + if (0 != sib_scale(CurrOp)) + indirect = true; + if (R_none != BaseReg) { + if ((BaseReg == R_bp) && (CurrOp.type == o_mem)) { + ; // EBP ==> no base register for o_mem type + } + else if ((BaseReg == R_bp) && UseFP) + ; // EBP used as frame pointer for direct access + else if (BaseReg == R_sp) + ; // ESP used as stack pointer for direct access + else + indirect = true; // conservative; some register used for addressing + // other than a stack or frame pointer + } + } // end if hasSIB + else { // no SIB; can have base register only + ushort BaseReg = CurrOp.reg; + if (CurrOp.type == o_mem) { // no base register for o_mem + if (!((0 == BaseReg) || (R_bp == BaseReg))) { + msg("base reg %d ignored \n", BaseReg); + } + } + else if ((BaseReg == R_bp) && UseFP) + ; // EBP used as frame pointer for direct access + else if (BaseReg == R_sp) + ; // ESP used as stack pointer for direct access + else { + indirect = true; + } + } + + return indirect; +} // end MDIsIndirectMemoryOpnd() + +// Extract the base and index registers and scale factor and displacement from the +// memory operand. +void MDExtractAddressFields(op_t MemOp, int &BaseReg, int &IndexReg, ushort &Scale, ea_t &Offset) { + assert((MemOp.type == o_phrase) || (MemOp.type == o_displ) || (MemOp.type == o_mem)); + + Scale = 0; + BaseReg = R_none; + IndexReg = R_none; + Offset = MemOp.addr; + + if (MemOp.hasSIB) { + BaseReg = sib_base(MemOp); + IndexReg = (int) sib_index(MemOp); + if (R_sp == IndexReg) // signifies no index register + IndexReg = R_none; + if (R_none != IndexReg) { + Scale = sib_scale(MemOp); + } + if (R_none != BaseReg) { + if ((BaseReg == R_bp) && (MemOp.type == o_mem)) { + BaseReg = R_none; + } + } + } + else { // no SIB byte; can have base reg but no index reg or scale factor + BaseReg = (int) MemOp.reg; // cannot be R_none for no SIB case + if (MemOp.type == o_mem) { + BaseReg = R_none; // no Base register for o_mem operands + } + } + + return; +} // end of MDExtractAddressFields() + // DEBUG Print DEF and/or USE for an operand. void PrintDefUse(ulong feature, int OpNum) { // CF_ macros number the operands from 1 to 6, while OpNum @@ -425,7 +508,7 @@ set<DefOrUse, LessDefUse>::iterator DefOrUseSet::SetType(op_t CurrOp, SMPOperand #if 1 if (o_imm == CurrOp.type) { if (UNINIT != CurrRef->GetType()) { - msg("ERROR: Changing type of immediate to %d : ", Type); + msg("ERROR: Changing type of immediate from %d to %d : ", CurrRef->GetType(), Type); CurrRef->Dump(); msg("\n"); } @@ -451,6 +534,27 @@ void DefOrUseSet::Dump(void) { return; } +// Do all types agree, ignoring any flags registers in the set? +bool DefOrUseSet::TypesAgreeNoFlags(void) { + bool FoundFirstUse = false; + set<DefOrUse, LessDefUse>::iterator CurrUse; + SMPOperandType UseType = UNINIT; + for (CurrUse = this->Refs.begin(); CurrUse != this->Refs.end(); ++CurrUse) { + if (!(CurrUse->GetOp().is_reg(X86_FLAGS_REG))) { // ignore flags + if (!FoundFirstUse) { + FoundFirstUse = true; + UseType = CurrUse->GetType(); + } + else { + if (CurrUse->GetType() != UseType) { + return false; // inconsistent types + } + } + } + } + return true; +} // end of DefOrUseSet::TypesAgreeNoFlags() + // ***************************************************************** // Class DefOrUseList diff --git a/SMPDataFlowAnalysis.h b/SMPDataFlowAnalysis.h index ce060987..092e6c46 100644 --- a/SMPDataFlowAnalysis.h +++ b/SMPDataFlowAnalysis.h @@ -43,6 +43,12 @@ void PrintOneOperand(op_t Opnd, ulong features, int OpNum); void PrintListOperand(op_t Opnd, int SSANum = SMP_SSA_UNINIT); void PrintOperand(op_t Opnd); +// MACHINE DEPENDENT: Could operand be an indirect memory access? +bool MDIsIndirectMemoryOpnd(op_t CurrOp, bool UseFP); + +// MACHINE DEPENDENT: Get base and index registers and displacement/addr from operand. +void MDExtractAddressFields(op_t MemOp, int &BaseReg, int &IndexReg, ushort &Scale, ea_t &Offset); + // MACHINE DEPENDENT: Is operand type a known type that we want to analyze? bool MDKnownOperandType(op_t TempOp); @@ -107,7 +113,7 @@ enum SMPitype { INDIR_JUMP = 16, // indirect unconditional branch, CALL = 32, // direct call INDIR_CALL = 64, // indirect call - RETURN = 128, // function return + RETURN = 128, // function return OR TAIL CALL HALT = 256 // execution stops }; @@ -186,6 +192,7 @@ public: // Printing methods void Dump(void); // Analysis methods + bool TypesAgreeNoFlags(void); // Are all types consistent, ignoring flags registers? private: // Data set<DefOrUse, LessDefUse> Refs; // Defined or used operand with type and SSA subscript -- GitLab