From 7b0a184109229cb3fc9d088949a0f887746f61f8 Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Fri, 11 Sep 2015 14:59:59 +0000 Subject: [PATCH] Find constant indirect call and jump targets using SCCP, output debug info. Former-commit-id: 893f24b12f193534a9e0ca4471e1140b6359fb82 --- include/base/SMPFunction.h | 1 + include/base/SMPInstr.h | 1 + include/interfaces/idapro/STARSSegment.h | 9 +++--- src/base/SMPFunction.cpp | 37 ++++++++++++++++++++++++ src/base/SMPProgram.cpp | 6 ++++ 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h index 4d4716df..1c48d026 100644 --- a/include/base/SMPFunction.h +++ b/include/base/SMPFunction.h @@ -397,6 +397,7 @@ public: bool PropagateGlobalMetadata(const STARSOpndTypePtr &UseOp, SMPMetadataType Status, int SSANum, STARS_ea_t UseAddr); void FindRedundantMetadata(void); // Do consecutive DEFs have same type? void SparseConditionalConstantPropagation(void); // perform SCCP to find constant values for DEFs, store in this->ConstantDefs + void AuditSCCPForIndirectTargets(void); // emit debug output if SCCP found constant call target for an indir call or jump void EvaluateAllPhiConstants(int BlockNum, std::vector<STARSBitSet> ExecutedEdgeBitSet, std::list<std::pair<int, int> > &SSAWorkList); // part of SCCP processing; propagate const DEFs into Phi USEs and Phi DEFs bool IsBenignUnderflowDEF(const STARSOpndTypePtr &DefOp, int DefSSANum, STARS_ea_t DefAddr, int &IdiomCode); // Do we not care if DEF underflowed, due to how it is used? bool HasIntErrorCallSink(const STARSOpndTypePtr &DefOp, int DefSSANum, STARS_ea_t DefAddr, std::string &SinkString, bool &FoundAnyCall); // DEF is passed to known system/lib call diff --git a/include/base/SMPInstr.h b/include/base/SMPInstr.h index 19ac295a..296174ce 100644 --- a/include/base/SMPInstr.h +++ b/include/base/SMPInstr.h @@ -390,6 +390,7 @@ public: inline uint16_t GetIDAOpcode(void) const { return STARSInstPtr->GetIDAOpcode(); }; inline STARS_ea_t GetCallTarget(void) const { return CallTarget; }; inline STARS_ea_t GetFarBranchTarget(void) const { return FarBranchTarget; }; + inline STARSOpndTypePtr GetControlFlowTarget(void) const { return RTL.GetRT(0)->GetRightOperand(); }; char *GetDisasm(void) const; inline SMPBasicBlock *GetBlock(void) const { return BasicBlock; }; inline std::set<DefOrUse, LessDefUse>::iterator GetFirstUse(void) { return Uses.GetFirstRef(); }; diff --git a/include/interfaces/idapro/STARSSegment.h b/include/interfaces/idapro/STARSSegment.h index cc0154e4..12db2726 100644 --- a/include/interfaces/idapro/STARSSegment.h +++ b/include/interfaces/idapro/STARSSegment.h @@ -3,6 +3,7 @@ #include <pro.h> #include <segment.hpp> +#include <bytes.hpp> #include "interfaces/STARSTypes.h" @@ -26,22 +27,22 @@ class STARS_IDA_Segment_t : public STARS_Segment_t // Fetch read-only data values, if any. virtual bool GetReadOnlyMem64BitValue(STARS_ea_t MemAddr, uint64_t &Value) const { assert(!IsWriteableSegment()); - Value = (uint64_t) get_qword(MemAddr); + Value = (uint64_t) ::get_qword(MemAddr); return true; } virtual bool GetReadOnlyMem32BitValue(STARS_ea_t MemAddr, uint32_t &Value) const { assert(!IsWriteableSegment()); - Value = (uint32_t) get_long(MemAddr); + Value = (uint32_t) ::get_long(MemAddr); return true; } virtual bool GetReadOnlyMem16BitValue(STARS_ea_t MemAddr, uint16_t &Value) const { assert(!IsWriteableSegment()); - Value = (uint16_t) get_word(MemAddr); + Value = (uint16_t) ::get_word(MemAddr); return true; } virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const { assert(!IsWriteableSegment()); - Value = (uint8_t) get_byte(MemAddr); + Value = (uint8_t) ::get_byte(MemAddr); return true; } diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index b11cbf64..84bf0ba0 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -4811,6 +4811,43 @@ void SMPFunction::SparseConditionalConstantPropagation(void) { return; } // end of SMPFunction::SparseConditionalConstantPropagation() +// emit debug output if SCCP found constant call target for an indir call or jump +void SMPFunction::AuditSCCPForIndirectTargets(void) { + list<SMPInstr *>::iterator InstIter = this->GetFirstInstIter(); + ++InstIter; // skip SSA Marker inst + for (; InstIter != this->Instrs.end(); ++InstIter) { + SMPInstr *CurrInst = (*InstIter); + SMPitype CurrDataFlow = CurrInst->GetDataFlowType(); + if (((CurrDataFlow == INDIR_CALL) || (CurrDataFlow == INDIR_JUMP)) && (!CurrInst->MDIsInterruptCall())) { + STARSOpndTypePtr TargetOp = CurrInst->GetControlFlowTarget(); + STARSOpndTypePtr SearchOp = CloneIfSubwordReg(TargetOp); + if (TargetOp->IsRegOp()) { // can only find SCCP constant values for regs + set<DefOrUse, LessDefUse>::iterator TargetIter = CurrInst->FindUse(SearchOp); + int UseSSANum = TargetIter->GetSSANum(); + int UseHashValue = HashGlobalNameAndSSA(TargetOp, UseSSANum); + STARS_SCCP_Const_Struct ConstStruct; + ConstStruct.ConstType = STARS_CONST_TOP; // default to no const found + if (CurrInst->GetBlock()->IsLocalName(TargetOp)) { // local name + map<int, struct STARS_SCCP_Const_Struct>::iterator ConstValIter = CurrInst->GetBlock()->FindLocalConstValue(UseHashValue); + if (ConstValIter != CurrInst->GetBlock()->GetLastLocalConstValueIter()) { // Has current const val entry + ConstStruct = ConstValIter->second; + } + } + else { // global name + map<int, struct STARS_SCCP_Const_Struct>::iterator ConstValIter = CurrInst->GetBlock()->GetFunc()->FindConstValue(UseHashValue); + if (ConstValIter != CurrInst->GetBlock()->GetFunc()->GetLastConstValueIter()) { // Has current const val entry + ConstStruct = ConstValIter->second; + } + } + if (ConstStruct.ConstType == STARS_CONST_HAS_VALUE) { + SMP_msg("INFO: SCCP found constant value of %llx for indirect target at %llx\n", + (unsigned long long) ConstStruct.ConstValue, (unsigned long long) CurrInst->GetAddr()); + } + } + } + } + return; +} // end of SMPFunction::AuditSCCPForIndirectTargets() // part of SCCP processing; propagate const DEFs into Phi USEs and Phi DEFs void SMPFunction::EvaluateAllPhiConstants(int BlockNum, vector<STARSBitSet> ExecutedEdgeBitSet, list<pair<int, int> > &SSAWorkList) { diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp index 9b9837e0..d4a4cc75 100644 --- a/src/base/SMPProgram.cpp +++ b/src/base/SMPProgram.cpp @@ -64,6 +64,9 @@ using namespace std; #define SMP_DEBUG_FUNC 1 #define STARS_DEBUG_CALL_GRAPH_PRIORITY 1 +// Did SCCP find an indirect call target that is constant? +#define STARS_DEBUG_INDIR_CALL_SCCP_SUCCESS 1 + // Perform interprocedural type inference and propagation? #define STARS_INTERPROCEDURAL_TYPE_INFERENCE 1 #define STARS_INTERPROCEDURAL_ITERATION_LIMIT 7 @@ -426,6 +429,9 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn // Find constant-valued DEFs using SCCP algorithm CurrFunc->SparseConditionalConstantPropagation(); } +#if STARS_DEBUG_INDIR_CALL_SCCP_SUCCESS + CurrFunc->AuditSCCPForIndirectTargets(); +#endif Time3 = time(NULL); Analysis2 += difftime(Time3, Time2); CurrFunc->AliasAnalysis(); -- GitLab