diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h index 77daedcd670cd37fbb0940a6d41e4595a5ed0714..2879baacd7163e0a8808fcfd70a838656c763333 100644 --- a/include/base/SMPFunction.h +++ b/include/base/SMPFunction.h @@ -350,7 +350,7 @@ public: STARS_ea_t GetFirstUnprocessedCallee(void); // first addr of first callee in AllCallTargets with Processed == false inline std::size_t GetNumBlocks(void) const { return Blocks.size(); }; inline std::size_t GetNumTCFGBlocks(void) const { return TCFGBlocks.size(); }; - STARSOpndTypePtr GetNormalizedOperand(STARS_ea_t InstAddr, const STARSOpndTypePtr &RTLop); // Return RTLop if not stack opnd; return normalized RTLop otherwise. + STARSOpndTypePtr GetNormalizedOperand(STARS_ea_t InstAddr, const STARSOpndTypePtr &RTLop, bool DEFFlag); // Return RTLop if not stack opnd; return normalized RTLop otherwise. inline int GetReturnRegType(STARS_regnum_t RegNum) const { return ((RegNum < (decltype(RegNum))ReturnRegTypes.size()) ? (int) ReturnRegTypes[RegNum] : 0); }; inline struct FineGrainedInfo GetReturnRegFGInfo(STARS_regnum_t RegNum) const { return ReturnRegFGInfo.at(RegNum); }; inline std::size_t GetReturnRegFGInfoSize(void) const { return ReturnRegFGInfo.size(); }; @@ -477,7 +477,7 @@ public: inline void SetCallerSavedLocalReg(STARS_regnum_t RegNum) { CallerSavedLocalRegsBitmap.set(RegNum); }; void UpdateLocalMaxSSANum(int CurrSSANum) { if (CurrSSANum > MaxLocalSSANum) MaxLocalSSANum = CurrSSANum; }; void AddLeaOperand(STARS_ea_t addr, STARSOpndTypePtr LeaOperand); // add map entry to LeaInstOpMap - void AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t InstAddr, STARSOpndTypePtr NormalizedOp); // add to map for RTL lookup later + void AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t InstAddr, STARSOpndTypePtr NormalizedOp, bool DEFFlag); // add to map for RTL lookup later void UpdateMaxDirectStackAccessOffset(STARS_sval_t NewOffset); // Update MaxDirectStackAccessDelta void MarkTaintInArgReg(std::size_t ArgPos) { TaintInArgPosBits |= (1 << ArgPos); }; void SetControlFlowType(STARS_ea_t InstAddr, ControlFlowType JumpTypeCode); // insert into ControlFlowMap @@ -955,9 +955,12 @@ private: std::set<std::pair<STARSOpndTypePtr, std::pair<STARS_ea_t, STARS_sval_t> >, LessStackDeltaCopy> StackPtrCopySet; // triple: operand holding copy, InstAddr where copy is made, stack delta for copy std::list<std::pair<STARS_ea_t, STARS_sval_t> > TempStackDeltaReachesList; // Used for temporary lookups of particular op_t in StackPtrCopySet. std::set<STARS_ea_t, LessAddr> TempReachingDefs; // Temporary list of InstAddrs with defs of one op_t that reach a particular InstAddr. - std::map<STARSDefinition, STARSOpndTypePtr, LessDefinition> NormalizedStackOpsMap; // normalized stack operands, indexed by instruction address (for lookup from RTLs). - std::map<STARSDefinition, std::map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator, LessDefinition> InverseNormalizedStackOpsMap; // index: normalized op, - // mapped to: iterator into NormalizedStackOpsMap; only for use in functions that call alloca() and need to re-normalize stack ops repeatedly + std::map<STARSDefinition, STARSOpndTypePtr, LessDefinition> NormalizedStackDEFOpsMap; // normalized stack DEF operands, indexed by instruction address (for lookup from RTLs). + std::map<STARSDefinition, STARSOpndTypePtr, LessDefinition> NormalizedStackUSEOpsMap; // normalized stack USE operands, indexed by instruction address (for lookup from RTLs). + std::map<STARSDefinition, std::map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator, LessDefinition> InverseNormalizedStackDEFOpsMap; // index: normalized op, + // mapped to: iterator into NormalizedStackDEFOpsMap; only for use in functions that call alloca() and need to re-normalize stack ops repeatedly + std::map<STARSDefinition, std::map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator, LessDefinition> InverseNormalizedStackUSEOpsMap; // index: normalized op, + // mapped to: iterator into NormalizedStackUSEOpsMap; only for use in functions that call alloca() and need to re-normalize stack ops repeatedly std::bitset<1 + MD_LAST_REG_NO> PreservedRegsBitmap; // Registers that are saved on entry and restored before return from func, or never used, as a bitmap. std::bitset<1 + MD_LAST_REG_NO> CallerSavedLocalRegsBitmap; // Reg numbers that are local names and are caller-saved std::bitset<1 + MD_LAST_REG_NO> MemRangeRegsBitmap; // Reg numbers that are used in defining the memory writing range expr diff --git a/include/base/SMPInstr.h b/include/base/SMPInstr.h index d2c506db412b695f7070cf6c91ace14de9ac1e52..0797be98afb0de34e9d636bdf5c0585818238e31 100644 --- a/include/base/SMPInstr.h +++ b/include/base/SMPInstr.h @@ -1011,7 +1011,7 @@ public: void AnalyzeIndirectRefs(bool UseFP); // Detect indirect memory operands STARS_sval_t AnalyzeStackPointerDelta(STARS_sval_t IncomingDelta, STARS_sval_t FramePtrDelta); STARS_sval_t FindStackAdjustment(void); // Find amount of stack adjustment, e.g. if this inst is after a call - bool MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, STARSOpndTypePtr &DefOp); // Normalize stack operands to use incoming stack delta; leave others as is + bool MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, STARSOpndTypePtr &StackOp, bool DEFFlag); // Normalize stack operands to use incoming stack delta; leave others as is // return true if register or stack memory operand, false otherwise bool MDNormalizeStackOps(bool UseFP, STARS_sval_t FPDelta, bool Recomputing, STARS_sval_t DeltaIncrement = 0); // Iterate through Defs and Uses, calling MDComputeNormalizedDataFlowOp(); true if changed DEFs or USEs @@ -1334,7 +1334,7 @@ private: bool MDIsAddImmediateToReg(STARSOpndTypePtr &DefOp, STARSOpndTypePtr &ImmOp); // return true if we have register DefOp += ImmOp. - bool MDRecomputeNormalizedDataFlowOp(STARS_sval_t DeltaIncrement, bool UpdateMaps, STARSOpndTypePtr &DefOp); // Alter stack delta for SP-relative stack operands in alloca-calling functions + bool MDRecomputeNormalizedDataFlowOp(STARS_sval_t DeltaIncrement, bool UpdateMaps, STARSOpndTypePtr &StackOp, bool DEFFlag); // Alter stack delta for SP-relative stack operands in alloca-calling functions // return true if register or stack memory operand, false otherwise }; // end class SMPInstr diff --git a/src/base/SMPFunction_part1.cpp b/src/base/SMPFunction_part1.cpp index fe766ad32c09f4d3b3c42cd4811fd075761f7424..51cabce174d6c88f72c0b379d0981e63d2d361df 100644 --- a/src/base/SMPFunction_part1.cpp +++ b/src/base/SMPFunction_part1.cpp @@ -1369,7 +1369,7 @@ void SMPFunction::AddLeaOperand(STARS_ea_t addr, STARSOpndTypePtr LeaOperand) { } // Add input arguments to the NormalizedStackOpsMap. -void SMPFunction::AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t InstAddr, STARSOpndTypePtr NormalizedOp) { +void SMPFunction::AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t InstAddr, STARSOpndTypePtr NormalizedOp, bool DEFFlag) { bool DuplicateCase = false; // e.g. inc [esp+8] will have [esp+8] as a DEF and a USE and maps will see [esp+8] twice #if SMP_DEBUG_DATAFLOW_VERBOSE bool DebugFlag = (InstAddr == 0x8048463); @@ -1380,15 +1380,16 @@ void SMPFunction::AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t I pair<STARSOpndTypePtr, STARS_ea_t> InverseValue(OldOp, InstAddr); // OldOp was NormalizedOp when it was inserted previously pair<pair<STARSOpndTypePtr, STARS_ea_t>, STARSOpndTypePtr> InsertValue(OldValue, NormalizedOp); pair<STARSOpndTypePtr, STARS_ea_t> InverseInsertValue(NormalizedOp, InstAddr); - map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator OldIter = this->NormalizedStackOpsMap.begin(); + map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator OldIter = DEFFlag ? this->NormalizedStackDEFOpsMap.begin() : this->NormalizedStackUSEOpsMap.begin(); pair<STARSDefinition, map<pair<STARSOpndTypePtr, STARS_ea_t>, STARSOpndTypePtr, LessDefinition>::iterator> InverseInsertTriple(InverseInsertValue, OldIter); map<STARSDefinition, map<pair<STARSOpndTypePtr, STARS_ea_t>, STARSOpndTypePtr, LessDefinition>::iterator>::iterator InverseIter; // If this function calls alloca(), stack operands could be normalized more than once. // Before we proceed, we update an old entry instead of inserting a new entry. if (this->CallsAlloca || this->HasPushAfterFrameAlloc()) { - InverseIter = this->InverseNormalizedStackOpsMap.find(InverseValue); - if (InverseIter != this->InverseNormalizedStackOpsMap.end()) { + InverseIter = DEFFlag ? this->InverseNormalizedStackDEFOpsMap.find(InverseValue) : this->InverseNormalizedStackUSEOpsMap.find(InverseValue); + bool FoundIt = DEFFlag ? (InverseIter != this->InverseNormalizedStackDEFOpsMap.end()) : (InverseIter != this->InverseNormalizedStackUSEOpsMap.end()); + if (FoundIt) { // We have our alloca() update case. We formerly mapped <A, InstAddr> to B. // Now B is being normalized to C. All we want to do is change the original // map entry so that we map <A, InstAddr> to C. In this manner, A is always the @@ -1397,11 +1398,18 @@ void SMPFunction::AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t I OldIter->second = NormalizedOp; // Change B to C // Now we want to erase the Inverse map entry and insert a new one that maps // <C, InstAddr> to OldIter instead of mapping <B, InstAddr> to OldIter. - (void) this->InverseNormalizedStackOpsMap.erase(InverseIter); - InverseInsertTriple.second = OldIter; - InverseInsertResult = this->InverseNormalizedStackOpsMap.insert(InverseInsertTriple); + if (DEFFlag) { + (void) this->InverseNormalizedStackDEFOpsMap.erase(InverseIter); + InverseInsertTriple.second = OldIter; + InverseInsertResult = this->InverseNormalizedStackDEFOpsMap.insert(InverseInsertTriple); + } + else { + (void) this->InverseNormalizedStackUSEOpsMap.erase(InverseIter); + InverseInsertTriple.second = OldIter; + InverseInsertResult = this->InverseNormalizedStackUSEOpsMap.insert(InverseInsertTriple); + } if (!InverseInsertResult.second) { // ERROR - SMP_msg("FATAL ERROR: Conflict in InverseNormalizedStackOpsMap in inst at %llx in ", (uint64_t) InstAddr); + SMP_msg("FATAL ERROR: Conflict in InverseNormalizedStackOpsMap DEFFlag %d in inst at %llx in ", DEFFlag, (uint64_t) InstAddr); this->DumpFuncNameAndAddr(); SMP_msg("OldOp : "); PrintOperand(OldOp); @@ -1429,14 +1437,20 @@ void SMPFunction::AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t I // does not execute. We can only detect this case by finding an existing C->A reverse mapping // and an existing A->C mapping to confirm our inference. pair<STARSOpndTypePtr, STARS_ea_t> TestInverseValue(NormalizedOp, InstAddr); - InverseIter = this->InverseNormalizedStackOpsMap.find(TestInverseValue); - if (InverseIter != this->InverseNormalizedStackOpsMap.end()) { + InverseIter = DEFFlag ? this->InverseNormalizedStackDEFOpsMap.find(TestInverseValue) + : this->InverseNormalizedStackUSEOpsMap.find(TestInverseValue); + bool FoundIt2 = DEFFlag ? (InverseIter != this->InverseNormalizedStackDEFOpsMap.end()) + : (InverseIter != this->InverseNormalizedStackUSEOpsMap.end()); + if (FoundIt2) { // Found existing C->A inverse mapping. Is there an A->C mapping to confirm // our interpretation of the situation? pair<STARSOpndTypePtr, STARS_ea_t> TestOldValue(InverseIter->second->first.first, InstAddr); map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator TestOldIter; - TestOldIter = this->NormalizedStackOpsMap.find(TestOldValue); - if (TestOldIter != this->NormalizedStackOpsMap.end()) { + TestOldIter = DEFFlag ? this->NormalizedStackDEFOpsMap.find(TestOldValue) + : this->NormalizedStackUSEOpsMap.find(TestOldValue); + bool FoundIt3 = DEFFlag ? (TestOldIter != this->NormalizedStackDEFOpsMap.end()) + : (TestOldIter != this->NormalizedStackUSEOpsMap.end()); + if (FoundIt3) { // We found a mapping from <A, InstAddr>. if (IsEqOp(NormalizedOp, TestOldIter->second)) { // The mapping is A->C as suspected. @@ -1448,7 +1462,8 @@ void SMPFunction::AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t I } // At this point, we have no inverse map entry to worry about, because we are // normalizing this operand for the first time. - InsertResult = this->NormalizedStackOpsMap.insert(InsertValue); + InsertResult = DEFFlag ? this->NormalizedStackDEFOpsMap.insert(InsertValue) + : this->NormalizedStackUSEOpsMap.insert(InsertValue); OldIter = InsertResult.first; if (!(InsertResult.second)) { // Already had an entry. That should mean a rare case such as "inc [esp+8]" which @@ -1463,19 +1478,32 @@ void SMPFunction::AddNormalizedStackOperand(STARSOpndTypePtr OldOp, STARS_ea_t I if (this->CallsAlloca || this->HasPushAfterFrameAlloc()) { // We need to add an entry to the inverse map. InverseInsertTriple.second = OldIter; - InverseInsertResult = this->InverseNormalizedStackOpsMap.insert(InverseInsertTriple); + InverseInsertResult = DEFFlag ? this->InverseNormalizedStackDEFOpsMap.insert(InverseInsertTriple) + : this->InverseNormalizedStackUSEOpsMap.insert(InverseInsertTriple); assert(InverseInsertResult.second || DuplicateCase); } #if SMP_DEBUG_DATAFLOW_VERBOSE if (DebugFlag) { map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator StackMapIter; - SMP_msg("DEBUG: NormalizedStackOpsMap size: %zd\n", this->NormalizedStackOpsMap.size()); - for (StackMapIter = this->NormalizedStackOpsMap.begin(); StackMapIter != this->NormalizedStackOpsMap.end(); ++ StackMapIter) { - STARSOpndTypePtr OldOp = StackMapIter->first.first; - STARS_ea_t InstAddr = StackMapIter->first.second; - SMP_msg("DEBUG: NormalizedStackOps: "); - PrintOperand(OldOp); - SMP_msg(" addr: %llx\n", (uint64_t) InstAddr); + if (DEFFlag) { + SMP_msg("DEBUG: NormalizedStackDEFOpsMap size: %zd\n", this->NormalizedStackDEFOpsMap.size()); + for (StackMapIter = this->NormalizedStackDEFOpsMap.begin(); StackMapIter != this->NormalizedStackDEFOpsMap.end(); ++StackMapIter) { + STARSOpndTypePtr OldOp = StackMapIter->first.first; + STARS_ea_t InstAddr = StackMapIter->first.second; + SMP_msg("DEBUG: NormalizedStackDEFOps: "); + PrintOperand(OldOp); + SMP_msg(" addr: %llx\n", (uint64_t)InstAddr); + } + } + else { + SMP_msg("DEBUG: NormalizedStackUSEOpsMap size: %zd\n", this->NormalizedStackUSEOpsMap.size()); + for (StackMapIter = this->NormalizedStackUSEOpsMap.begin(); StackMapIter != this->NormalizedStackUSEOpsMap.end(); ++StackMapIter) { + STARSOpndTypePtr OldOp = StackMapIter->first.first; + STARS_ea_t InstAddr = StackMapIter->first.second; + SMP_msg("DEBUG: NormalizedStackUSEOps: "); + PrintOperand(OldOp); + SMP_msg(" addr: %llx\n", (uint64_t)InstAddr); + } } } #endif @@ -1543,7 +1571,7 @@ STARSSCCPMapIter SMPFunction::InsertGlobalConstValue(int DefHashValue, struct ST // Return RTLop if not stack opnd; return normalized RTLop otherwise. -STARSOpndTypePtr SMPFunction::GetNormalizedOperand(STARS_ea_t InstAddr, const STARSOpndTypePtr &RTLop) { +STARSOpndTypePtr SMPFunction::GetNormalizedOperand(STARS_ea_t InstAddr, const STARSOpndTypePtr &RTLop, bool DEFFlag) { STARSOpndTypePtr NormOp = nullptr; #if SMP_DEBUG_DATAFLOW_VERBOSE bool DebugFlag = (0x8048463 == InstAddr); @@ -1563,8 +1591,15 @@ STARSOpndTypePtr SMPFunction::GetNormalizedOperand(STARS_ea_t InstAddr, const ST #endif if (MDIsStackAccessOpnd(RTLop, this->UsesFramePointer())) { pair<STARSOpndTypePtr, STARS_ea_t> OldDefn(RTLop, InstAddr); - map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator FindIter = this->NormalizedStackOpsMap.find(OldDefn); - assert(this->NormalizedStackOpsMap.end() != FindIter); + map<STARSDefinition, STARSOpndTypePtr, LessDefinition>::iterator FindIter; + if (DEFFlag) { + FindIter = this->NormalizedStackDEFOpsMap.find(OldDefn); + assert(this->NormalizedStackDEFOpsMap.end() != FindIter); + } + else { + FindIter = this->NormalizedStackUSEOpsMap.find(OldDefn); + assert(this->NormalizedStackUSEOpsMap.end() != FindIter); + } NormOp = FindIter->second; } else { diff --git a/src/base/SMPFunction_part4.cpp b/src/base/SMPFunction_part4.cpp index ba45b19defa5ce83bdec30389dbb8d555bef2ad1..e578afff71dde35119064edfa363980e250a1c55 100644 --- a/src/base/SMPFunction_part4.cpp +++ b/src/base/SMPFunction_part4.cpp @@ -8378,7 +8378,7 @@ void SMPFunction::EmitFuncPtrShadowingAnnotations2(FILE *InfoAnnotFile) { CanonicalizeOpnd(ArgOp); } else if (MDIsStackAccessOpnd(ArgOp, this->UsesFramePointer()) && CurrInst->AreDefsNormalized()) { - ArgOp = this->GetNormalizedOperand(CurrInst->GetAddr(), ArgOp); + ArgOp = this->GetNormalizedOperand(CurrInst->GetAddr(), ArgOp, false); } } if ((nullptr != ArgOp) && !ArgOp->IsVoidOp()) { @@ -8446,7 +8446,7 @@ void SMPFunction::EmitArgShadowingAnnotations(FILE *InfoAnnotFile) { CanonicalizeOpnd(ArgOp); } else if (MDIsStackAccessOpnd(ArgOp, this->UsesFramePointer()) && CurrInst->AreDefsNormalized()) { - ArgOp = this->GetNormalizedOperand(CurrInst->GetAddr(), ArgOp); + ArgOp = this->GetNormalizedOperand(CurrInst->GetAddr(), ArgOp, false); } } if ((nullptr != ArgOp) && !ArgOp->IsVoidOp()) { diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp index 34833ae818e39eeb05a80d62a8e9c36dd4fe67b8..e14bb0bd7eee253b8af8b1d567c801191f751577 100644 --- a/src/base/SMPInstr.cpp +++ b/src/base/SMPInstr.cpp @@ -1454,7 +1454,8 @@ STARSOpndTypePtr SMPRegTransfer::GetLeftOperand(void) const { if (this->ParentInst->AreDefsNormalized()) { #endif STARS_ea_t InstAddr = this->ParentInst->GetAddr(); - TempOp = this->ParentInst->GetBlock()->GetFunc()->GetNormalizedOperand(InstAddr, TempOp); + bool DEFFlag = (SMP_ASSIGN == this->GetOperator()); + TempOp = this->ParentInst->GetBlock()->GetFunc()->GetNormalizedOperand(InstAddr, TempOp, DEFFlag); } return TempOp; } // end of SMPRegTransfer::GetLeftOperand() @@ -1468,7 +1469,7 @@ STARSOpndTypePtr SMPRegTransfer::GetRightOperand(void) const { if (this->ParentInst->AreDefsNormalized()) { #endif STARS_ea_t InstAddr = this->ParentInst->GetAddr(); - TempOp = this->ParentInst->GetBlock()->GetFunc()->GetNormalizedOperand(InstAddr, TempOp); + TempOp = this->ParentInst->GetBlock()->GetFunc()->GetNormalizedOperand(InstAddr, TempOp, false); } return TempOp; } // end of SMPRegTransfer::GetRightOperand() @@ -10030,26 +10031,27 @@ STARS_sval_t SMPInstr::FindStackAdjustment(void) { // rather than the current stack pointer value. // UseFP indicates we are using a frame pointer in the function. // FPDelta holds the stack delta (normalized) for the frame pointer. -// DefOp comes in with the operand to be normalized, and contains the normalized operand upon return. +// StackOp comes in with the operand to be normalized, and contains the normalized operand upon return. +// DEFFlag is true for DEF operands, false for USE operands. // Return true if operand is a register or stack location, false otherwise (true => include in data flow analysis sets and SSA.) -bool SMPInstr::MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, STARSOpndTypePtr &DefOp) { +bool SMPInstr::MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, STARSOpndTypePtr &StackOp, bool DEFFlag) { #if 0 - if ((nullptr == DefOp) || (this->GetStackPtrOffset() == 0)) + if ((nullptr == StackOp) || (this->GetStackPtrOffset() == 0)) return false; #else // instead of optimizing, need all stack operands to pass through SIBWithNoIndexReg check and correction - if (nullptr == DefOp) + if (nullptr == StackOp) return false; #endif - if (DefOp->IsRegOp()) { + if (StackOp->IsRegOp()) { return true; } - else if (MDIsStackAccessOpnd(DefOp, UseFP)) { - STARSOpndTypePtr OldOp = DefOp->clone(); - int SignedOffset = (int) DefOp->GetAddr(); + else if (MDIsStackAccessOpnd(StackOp, UseFP)) { + STARSOpndTypePtr OldOp = StackOp->clone(); + int SignedOffset = (int) StackOp->GetAddr(); STARS_sval_t NormalizedDelta = 0; - if (DefOp->HasSIBByte()) { + if (StackOp->HasSIBByte()) { // We must deal with a potentially indexed memory expression. We want to // normalize two different cases here: e.g. [esp+ebx+4] will become [esp+ebx-24] // and [ebp+ebx-8] will become [esp+ebx-12] after normalization. A wrinkle @@ -10057,8 +10059,8 @@ bool SMPInstr::MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, S // in the SIB byte, and we make [ebx+ebp-4] into [esp+ebx-12], which involves // correcting the index/base reg order in the SIB, because an index reg of ESP // is the SIB encoding for "no index register" and we cannot leave it like that. - int BaseReg = MD_STARS_sib_base(DefOp); - int IndexReg = (int) MD_STARS_sib_index(DefOp); + int BaseReg = MD_STARS_sib_base(StackOp); + int IndexReg = (int) MD_STARS_sib_index(StackOp); if (X86_STACK_POINTER_REG == IndexReg) { // signifies no index register IndexReg = STARS_x86_R_none; } @@ -10071,7 +10073,7 @@ bool SMPInstr::MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, S // Must be EBP-relative. NormalizedDelta = FPDelta + (STARS_sval_t) SignedOffset; // Unfortunately, when we are dealing with a SIB byte in the opcode, we cannot - // just say DefOp.reg = MD_STACK_POINTER_REG to convert from the frame pointer + // just say StackOp.reg = MD_STACK_POINTER_REG to convert from the frame pointer // to the stack pointer. Instead, we have to get into the nasty machine code // level and change the SIB bits that specify either the base register or the // index register, whichever one is the frame pointer. @@ -10080,8 +10082,8 @@ bool SMPInstr::MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, S // They must contain a 5, which is the x86 value for register EBP, and we // want to convert it to a 4, denoting register ESP. We can just zero out // the least significant bit to accomplish that. - char OldSIB = DefOp->GetSIB(); - DefOp->SetSIB(OldSIB & 0xfe); + char OldSIB = StackOp->GetSIB(); + StackOp->SetSIB(OldSIB & 0xfe); } else { // We sometimes have an instruction in which the frame pointer is used as @@ -10091,14 +10093,14 @@ bool SMPInstr::MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, S // The true index reg is in the lowest three bits, while the next three // bits must contain a 5 (register EBP) and we want to make them a 4 (ESP). // We must swap base and index regs as we normalize (see explanation above). - char SIBtemp = DefOp->GetSIB(); + char SIBtemp = StackOp->GetSIB(); char SIBindex = SIBtemp & 0x38; char SIBbase = SIBtemp & 0x07; assert ((SIBindex >> 3) == 5); // must be EBP SIBtemp &= 0xa0; // zero out lower 6 bits; upper 2 bits are scale factor - leave them alone SIBtemp &= (SIBbase << 3); // make old base reg (e.g. ebx) into a proper index reg SIBtemp |= 0x04; // make the new base reg be 4 (reg ESP) - DefOp->SetSIB(SIBtemp); + StackOp->SetSIB(SIBtemp); } this->SetFPNormalizedToSP(); // Add the stack pointer to the USE set for the instruction. @@ -10106,47 +10108,47 @@ bool SMPInstr::MDComputeNormalizedDataFlowOp(bool UseFP, STARS_sval_t FPDelta, S } } // end if SIB byte - else if (DefOp->GetReg() == MD_FRAME_POINTER_REG) { // no SIB byte, just o_displ with one address reg - // If FPDelta is -4 and SignedOffset is +8, then we have [ebp+8] as DefOp, and this + else if (StackOp->GetReg() == MD_FRAME_POINTER_REG) { // no SIB byte, just o_displ with one address reg + // If FPDelta is -4 and SignedOffset is +8, then we have [ebp+8] as StackOp, and this // is equivalent to [esp+4] where esp has its entry value, i.e. this would be the first incoming - // argument. If SignedOffset is -12, we have [ebp-12] as DefOp, and this is [esp-16] when + // argument. If SignedOffset is -12, we have [ebp-12] as StackOp, and this is [esp-16] when // normalized to the entry point value of the stack pointer. In both cases, we can see that the // normalized stack delta is just FPDelta+SignedOffset. NormalizedDelta = FPDelta + (STARS_sval_t) SignedOffset; // Now, we simply convert the memory operand from EBP to ESP and replace the SignedOffset with the // NormalizedDelta just computed. - DefOp->SetReg(MD_STACK_POINTER_REG); - DefOp->SetByteWidth(OldOp->GetByteWidth()); // undo possible width change in SetReg() + StackOp->SetReg(MD_STACK_POINTER_REG); + StackOp->SetByteWidth(OldOp->GetByteWidth()); // undo possible width change in SetReg() this->SetFPNormalizedToSP(); // Add the stack pointer to the USE set for the instruction. this->MDAddRegUse(MD_STACK_POINTER_REG, false); } else { - assert(DefOp->GetReg() == MD_STACK_POINTER_REG); + assert(StackOp->GetReg() == MD_STACK_POINTER_REG); // We only need to adjust the offset to reflect the change in the stack pointer since the function // was entered, e.g. [esp+4] is normalized to [esp-28] if the current esp value is 32 less than it // was upon function entry. We get the value "-32" in that case from a member variable. NormalizedDelta = this->GetStackPtrOffset() + (STARS_sval_t) SignedOffset; } - DefOp->SetAddr((STARS_ea_t) NormalizedDelta); // common to frame and stack pointer cases + StackOp->SetAddr((STARS_ea_t) NormalizedDelta); // common to frame and stack pointer cases this->GetBlock()->GetFunc()->UpdateMaxDirectStackAccessOffset(NormalizedDelta); // maintain record of maximum if (NormalizedDelta == 0) { // [esp+0] is the return address location. Reading or writing the return address makes // the function unsafe for the Strata fast return mechanism. if (this->HasDestMemoryOperand()) { this->GetBlock()->GetFunc()->SetUnsafeForFastReturns(true, RETURN_ADDRESS_WRITE); - SMP_msg("INFO: Return address overwritten in instruction at %llx\n", (unsigned long long) this->GetAddr()); + SMP_msg("INFO: Return address overwritten in instruction at %llx\n", (uint64_t) this->GetAddr()); } else { this->GetBlock()->GetFunc()->SetUnsafeForFastReturns(true, RETURN_ADDRESS_READ); - SMP_msg("INFO: Return address read in instruction at %llx\n", (unsigned long long) this->GetAddr()); + SMP_msg("INFO: Return address read in instruction at %llx\n", (uint64_t) this->GetAddr()); } } // Clean up unnecessary SIB byte, make sure offset matches operand type, etc. - DefOp->CleanOpndEncoding(); + StackOp->CleanOpndEncoding(); - this->GetBlock()->GetFunc()->AddNormalizedStackOperand(OldOp, this->GetAddr(), DefOp); + this->GetBlock()->GetFunc()->AddNormalizedStackOperand(OldOp, this->GetAddr(), StackOp, DEFFlag); return true; } else { @@ -10182,10 +10184,10 @@ bool SMPInstr::MDNormalizeStackOps(bool UseFP, STARS_sval_t FPDelta, bool Recomp if ((! OldOp->IsRegOp()) && (! OldOp->IsImmedOp())) { NewOp = OldOp->clone(); if (Recomputing) { - OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, true, NewOp); + OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, true, NewOp, true); } else { - OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, NewOp); + OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, NewOp, true); } if (OpNormalized) { StackOpFound = true; @@ -10218,10 +10220,10 @@ bool SMPInstr::MDNormalizeStackOps(bool UseFP, STARS_sval_t FPDelta, bool Recomp // Normalize STARSOpndTypePtr private data member DEFs. if (HasDEFMemOp && UniqueDEFMemOp) { // DefOp and this->DEFMemOp could be shared_ptr to same object; don't duplicate work if so if (Recomputing) { - OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, UniqueDEFMemOp, this->DEFMemOp); + OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, UniqueDEFMemOp, this->DEFMemOp, true); } else { - OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, this->DEFMemOp); + OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, this->DEFMemOp, true); } } @@ -10238,10 +10240,10 @@ bool SMPInstr::MDNormalizeStackOps(bool UseFP, STARS_sval_t FPDelta, bool Recomp if ((!OldOp->IsRegOp()) && (!OldOp->IsImmedOp())) { NewOp = OldOp->clone(); if (Recomputing) { - OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, true, NewOp); + OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, true, NewOp, false); } else { - OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, NewOp); + OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, NewOp, false); } if (OpNormalized) { StackOpFound = true; @@ -10293,31 +10295,31 @@ bool SMPInstr::MDNormalizeStackOps(bool UseFP, STARS_sval_t FPDelta, bool Recomp // Normalize STARSOpndTypePtr private data member USEs. if (Recomputing) { if (HasUSEMemOp && UniqueUSEMemOp) { - OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, UniqueUSEMemOp, this->USEMemOp); + OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, UniqueUSEMemOp, this->USEMemOp, false); } if (this->MDIsLoadEffectiveAddressInstr()) { STARSOpndTypePtr TempLeaMemOp = nullptr; if (HasLeaMemUseOp) TempLeaMemOp = this->GetLeaMemUseOp()->clone(); - OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, UniqueLeaUSEMemOp, TempLeaMemOp); + OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, UniqueLeaUSEMemOp, TempLeaMemOp, false); if (OpNormalized) this->SetLeaMemUseOp(TempLeaMemOp); } if (HasMoveSourceMemOp && UniqueMoveSource) { - OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, UniqueMoveSource, this->MoveSource); + OpNormalized = this->MDRecomputeNormalizedDataFlowOp(DeltaIncrement, UniqueMoveSource, this->MoveSource, false); } } else { if (HasUSEMemOp && UniqueUSEMemOp) // avoid shared_ptr duplicate normalization - OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, this->USEMemOp); + OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, this->USEMemOp, false); if (HasLeaMemUseOp && UniqueLeaUSEMemOp && this->MDIsLoadEffectiveAddressInstr()) { // avoid shared_ptr duplicate normalization STARSOpndTypePtr TempLeaMemOp = this->GetLeaMemUseOp()->clone(); - OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, TempLeaMemOp); + OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, TempLeaMemOp, false); if (OpNormalized) this->SetLeaMemUseOp(TempLeaMemOp); } if (HasMoveSourceMemOp && UniqueMoveSource) // avoid shared_ptr duplicate normalization - OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, this->MoveSource); + OpNormalized = this->MDComputeNormalizedDataFlowOp(UseFP, FPDelta, this->MoveSource, false); } #if 0 } // end if we have some mem USE to normalize @@ -10330,16 +10332,17 @@ bool SMPInstr::MDNormalizeStackOps(bool UseFP, STARS_sval_t FPDelta, bool Recomp } // end of SMPInstr::MDNormalizeStackOps() // Renormalize SP-relative stack operands in functions that call alloca() by adding DeltaIncrement to their stack displacements. -// DefOp comes in with the operand to be renormalized, and contains the normalized operand upon return. +// StackOp comes in with the operand to be renormalized, and contains the normalized operand upon return. +// DEFFlag is true for DEF operands, false for USE operands. // Return true if operand is a register or stack location, false otherwise (true => include in data flow analysis sets and SSA.) -bool SMPInstr::MDRecomputeNormalizedDataFlowOp(STARS_sval_t DeltaIncrement, bool UpdateMaps, STARSOpndTypePtr &DefOp) { - if ((nullptr == DefOp) || (DeltaIncrement == 0)) +bool SMPInstr::MDRecomputeNormalizedDataFlowOp(STARS_sval_t DeltaIncrement, bool UpdateMaps, STARSOpndTypePtr &StackOp, bool DEFFlag) { + if ((nullptr == StackOp) || (DeltaIncrement == 0)) return false; - if (DefOp->IsRegOp()) { + if (StackOp->IsRegOp()) { return true; } - else if (MDIsStackAccessOpnd(DefOp, this->GetBlock()->GetFunc()->UsesFramePointer())) { + else if (MDIsStackAccessOpnd(StackOp, this->GetBlock()->GetFunc()->UsesFramePointer())) { if (this->HasFPNormalizedToSP()) { // FP-relative operands do not change in alloca() functions when the alloca() // causes the SP to change. @@ -10348,21 +10351,21 @@ bool SMPInstr::MDRecomputeNormalizedDataFlowOp(STARS_sval_t DeltaIncrement, bool // The remaining cases are simple. The ESP-relative displacement is incremented by // DeltaIncrement, regardless of the presence of a SIB byte. - int SignedOffset = (int) DefOp->GetAddr(); + int SignedOffset = (int) StackOp->GetAddr(); STARS_sval_t NormalizedDelta = DeltaIncrement + (STARS_sval_t) SignedOffset; - STARSOpndTypePtr OldOp = DefOp->clone(); - DefOp->SetAddr((STARS_ea_t) NormalizedDelta); + STARSOpndTypePtr OldOp = StackOp->clone(); + StackOp->SetAddr((STARS_ea_t) NormalizedDelta); - if (DefOp->IsMemNoDisplacementOp() && (0 != NormalizedDelta)) { + if (StackOp->IsMemNoDisplacementOp() && (0 != NormalizedDelta)) { // mov [esp],eax has an [esp] operand of type o_phrase, because there is no // displacement field. After normalization, it will have a displacement field, so // it has become an operand like [esp-32] and is now type o_displ. - DefOp->SetTypeToMemDisplacement(); + StackOp->SetTypeToMemDisplacement(); } if (UpdateMaps) { // We don't update maps for duplicate entries, e.g. USEMemOp, DEFMemOp, MoveSource - this->GetBlock()->GetFunc()->AddNormalizedStackOperand(OldOp, this->GetAddr(), DefOp); + this->GetBlock()->GetFunc()->AddNormalizedStackOperand(OldOp, this->GetAddr(), StackOp, DEFFlag); } return true; } @@ -12635,7 +12638,7 @@ bool SMPInstr::IsSimpleCopy(STARSOpndTypePtr &rhs) const { if (this->IsRegUpperBitsClearIdiom()) { rhs = this->GetFirstRightOperandNoNorm(); if (this->AreDefsNormalized() && MDIsStackAccessOpnd(rhs, this->GetBlock()->GetFunc()->UsesFramePointer())) { - rhs = this->GetBlock()->GetFunc()->GetNormalizedOperand(this->GetAddr(), rhs); + rhs = this->GetBlock()->GetFunc()->GetNormalizedOperand(this->GetAddr(), rhs, false); } } else { @@ -12675,7 +12678,7 @@ bool SMPInstr::IsSimpleOrExtendedCopy(STARSOpndTypePtr &rhs) const { if (this->IsRegUpperBitsClearIdiom()) { rhs = this->GetFirstRightOperandNoNorm(); if (this->AreDefsNormalized() && MDIsStackAccessOpnd(rhs, this->GetBlock()->GetFunc()->UsesFramePointer())) { - rhs = this->GetBlock()->GetFunc()->GetNormalizedOperand(this->GetAddr(), rhs); + rhs = this->GetBlock()->GetFunc()->GetNormalizedOperand(this->GetAddr(), rhs, false); } } else {