Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • opensrc/SMPStaticAnalyzer
1 result
Show changes
Commits on Source (1)
......@@ -234,7 +234,6 @@ public:
std::vector<SMPInstr *>::const_reverse_iterator GetInstConstRevIterFromAddr(STARS_ea_t InstAddr) const;
inline SMPInstr *GetInstFromIndex(size_t VecIndex) const { return InstVec.at(VecIndex); };
size_t GetIndexFromInstAddr(STARS_ea_t InstAddr) const; // Get the InstVec index for the instruction at InstAddr. Assert if not found.
SMPInstr *FindBranchCompareOrTest(SMPoperator &BranchOperator, STARS_ea_t &DecAddr, bool SearchCase, int FlagsSSANum); // Find the compare or test that sets the flags used in COND_BRANCH at end of block, else NULL; If decrement found instead, fill DecAddr
STARS_sval_t GetIncomingStackDelta(void) const { return (*(GetFirstConstInst()))->GetStackPtrOffset(); };
inline STARS_sval_t GetOutgoingStackDelta(void) const { return OutgoingStackDelta; };
ControlFlowType GetLastInstCFType(void) const; // Get the enum ControlFlowType for the last inst
......@@ -413,6 +412,7 @@ public:
std::size_t GetNumSuccessorsMinusBackEdges(void) const; // Compute successor count, excluding loop-back edges.
int GetFirstNonBackEdgeSuccNum(void) const; // Avoid back edges; get first SuccBlockNum that is not back edge.
bool DoesBlockExitLoop(void) const; // block ends with LOOP_EXIT of some kind?
SMPInstr *FindBranchCompareOrTest(SMPoperator &BranchOperator, STARS_ea_t &DecAddr, bool SearchCase, int FlagsSSANum); // Find the compare or test that sets the flags used in COND_BRANCH at end of block, else NULL; If decrement found instead, fill DecAddr
STARS_ea_t GetUltimateOperandSource(STARS_ea_t UseAddr, const STARSOpndTypePtr &UseOp, int UseSSANum); // trace through move and Phi defs to some defining operation.
bool GetUltimateInitValue(const STARSOpndTypePtr &UseOp, STARS_ea_t InstAddr, int SSANum, bool LocalName, STARSOpndTypePtr &DefMoveOp, STARS_uval_t &InitValue);
// Trace back to const or InArg with min const value; follow Phi USEs to before-loop locations only.
......
......@@ -806,6 +806,7 @@ private:
typedef std::set<DefOrUse, LessDefUse> STARSDefUseSet;
typedef std::set<DefOrUse, LessDefUse>::iterator STARSDefUseIter;
typedef std::set<DefOrUse, LessDefUse>::const_iterator STARSDefUseConstIter;
typedef std::vector<DefOrUse>::iterator DefUseListIter;
// A data or function pointer shadowing point is a code address paired with an index
......
......@@ -170,6 +170,15 @@ enum SPARKTranslationCFType {
#define STARS_BOTTOM_TESTING_LOOP 2
#define STARS_INFINITE_OR_MIDDLE_TESTING_LOOP 3
#define STARS_CONSTANT_ITERATIONS_TOP_TESTING_LOOP 4
#define STARS_TOP_AND_BOTTOM_TESTING_LOOP 5
inline bool DoesLoopTestAtTop(const int LoopType) {
return ((STARS_TOP_TESTING_LOOP == LoopType) || (STARS_TOP_AND_BOTTOM_TESTING_LOOP == LoopType) || (STARS_CONSTANT_ITERATIONS_TOP_TESTING_LOOP == LoopType));
}
inline bool DoesLoopTestAtBottom(const int LoopType) {
return ((STARS_BOTTOM_TESTING_LOOP == LoopType) || (STARS_TOP_AND_BOTTOM_TESTING_LOOP == LoopType));
}
// A struct used to describe the comparison used to exit a loop or loop back.
// For loops that could not be analyzed, CompareOperator is SMP_NULL_OPERATOR.
......@@ -225,6 +234,14 @@ struct InductionVarFamily {
typedef std::list<struct InductionVarFamily> STARSInductionVarFamilyList;
typedef STARSInductionVarFamilyList::iterator STARSInductionVarFamilyIter;
struct LoopExitingBlockInfo {
int ExitingBlockNum; // Block # within loop that exits the loop
int TargetBlockNum; // Block # branched to outside the loop
SMPInstr *CompareTestDecInst; // The compare, test, or decrement instruction that sets flags used by the COND_BRANCH to exit.
bool ShortCircuitExpr; // COND_BRANCH is part of a short circuit expression
bool ReferencesBIV; // CompareTestDecInst references a BIV for this loop
};
// triple: memory write expr, ByteWidth, index into vector of stack pointer copy InstAddrs
typedef std::list<std::pair<STARSExprSetIter, std::pair<std::size_t, int> > > STARSMemWriteExprsList;
typedef STARSMemWriteExprsList::iterator STARSMemWriteExprListIter;
......@@ -420,16 +437,17 @@ public:
inline void SetReturnAddressStatus(FuncType funcType) {
ReturnAddrStatus = funcType;
}
inline void SetFuncProcessed(bool Status) { FuncProcessed = Status; return; };
inline void SetFuncProcessed(bool Status) { FuncProcessed = Status; };
inline void SetHasIndirectCalls(void) { IndirectCalls = true; };
inline void SetHasUnresolvedIndirectCalls(void) { UnresolvedIndirectCalls = true; };
void SetHasUnstructuredCFG(void);
inline void SetHasSystemCalls(void) { SystemCalls = true; };
inline void SetAltersSPARKMemory(void) { AltersMemory = true; };
inline void SetFuncSafe(bool Status) { SafeFunc = Status; return; };
inline void SetSpecFuncSafe(bool Status) { SpecSafeFunc = Status; return; };
inline void SetNeedsFrame(bool Status) { NeedsStackReferent = Status; return; };
inline void SetSpecNeedsFrame(bool Status) { SpecNeedsStackReferent = Status; return; };
inline void SetUnsafeForFastReturns(bool Status, UnsafeFastReturnReason Reason) { UnsafeForFastReturns = Status; FastReturnStatus |= (int) Reason; return; };
inline void SetFuncSafe(bool Status) { SafeFunc = Status; };
inline void SetSpecFuncSafe(bool Status) { SpecSafeFunc = Status; };
inline void SetNeedsFrame(bool Status) { NeedsStackReferent = Status; };
inline void SetSpecNeedsFrame(bool Status) { SpecNeedsStackReferent = Status; };
inline void SetUnsafeForFastReturns(bool Status, UnsafeFastReturnReason Reason) { UnsafeForFastReturns = Status; FastReturnStatus |= (int) Reason; };
inline void SetIsSpeculative(bool IsS) { IsSpeculative = IsS; };
inline void SetIsMutuallyRecursive(void) { MutuallyRecursive = true; };
inline void SetIsCalledFromOrphanedCode(void) { CalledFromOrphanCode = true; };
......@@ -524,6 +542,7 @@ public:
inline bool IsOddIfThenBranch(const int BranchBlockNum) const { return (OddIfThenBranches.cend() != OddIfThenBranches.find(BranchBlockNum)); };
inline bool UsesFramePointer(void) const { return UseFP; };
inline bool FuncHasHashingCode(void) const { return HasHashingCode; };
inline bool HasShortCircuitConditional(void) const { return HasShortCircuitExpr; };
inline bool HasGoodFGStackTable(void) const { return (!(NegativeOffsetFineGrainedStackTable.empty())); };
bool IsLiveIn(const STARSOpndTypePtr &CurrOp) const;
inline bool IsLiveOut(const STARSOpndTypePtr &CurrOp) const {
......@@ -631,6 +650,7 @@ public:
void BuildLoopList(int BlockNum, std::list<std::size_t> &LoopList) const; // build list of loop numbers that BlockNum is part of.
void BuildLoopBlockList(const size_t LoopNum, std::list<std::size_t> &BlockList); // build list of Block numbers contained in LoopNum.
void BuildBlockListFromBitset(const STARSBitSet &CurrBitSet, std::list<std::size_t> &BlockList) const; // each bit set in CurrBitSet is a block # for BlockList
void BuildLoopIterationCountExprs(const bool VerboseOutput, FILE *InfoAnnotFile); // Fill in LoopIterationsCountExprs[each LoopIndex]; emit SENTINEL annotations
void AnalyzeLoopIterations(void); // analyze how many times each loop iterates
STARSExpression *CreateMemoryAddressExpr(const STARSOpndTypePtr &MemDefOp, SMPInstr *WriteInst); // create expression for the memory address computation in MemDefOp
void AliasAnalysis(void); // Find memory writes with possible aliases
......@@ -656,6 +676,7 @@ public:
bool IsDefUsedInUnsafeMemWrite(STARSOpndTypePtr DefOp, int DefSSANum, STARS_ea_t DefAddr); // Is Defop+DefSSANum at DefAddr used as address reg or as source operand in unsafe memory write?
bool IsAddressRegSafe(const STARSOpndTypePtr &UseOp, STARS_ea_t UseAddr, int UseSSANum); // Is UseOp+UseSSANum at UseAddr a safe write?
void MarkFunctionSafe(void); // Does analysis to see if the function can be marked safe
void MarkSpecialNumericErrorCases(void); // Detect and mark special cases before emitting numeric error annotations.
void FreeUnusedMemory2(void); // After loop 2 in SMPProgram::Analyze(), free memory
void FreeUnusedMemory3(void); // After loop 3 in SMPProgram::Analyze(), free memory
void FreeUnusedMemory4(void); // After loop 4 (type inference) in SMPProgram::Analyze(), free memory
......@@ -724,6 +745,7 @@ private:
bool StackFrameExtendsPastStackTop; // Locals are accessed from unallocated space beyond the top of stack.
bool IsSpeculative; // Have we started the speculative portion of the analysis for this function.
bool HasHashingCode; // Has apparent hashing or crypto code that intentionally overflows.
bool HasShortCircuitExpr; // Has at least one short circuit conditional expression.
bool HasInArgCodePointer; // Has incoming arg of type CODEPTR
bool HasInArgDataPointer; // Has incoming arg of type POINTER or a refinement of POINTER
bool HasMallocCall; // calls malloc()
......@@ -827,6 +849,7 @@ private:
std::vector<int> LoopHeadBlockNumbers; // indexed by loop number; block number of header block
std::vector<std::set<int> > LoopExitTargets; // indexed by loop number; block number of exit destinations
std::vector<std::map<int, STARSBitSet> > LoopExitTargetsReachabilitySets; // indexed by LoopNum, map exit target block num to bitset of block nums downward reachable from exit block num; SPARK-useful if multiple exit block targets
std::vector<std::vector<struct LoopExitingBlockInfo> > LoopExitingBlocksVector; // indexed by LoopNum, info about each block that can exit the loop
std::vector<bool> LoopHasMultipleExits;
std::vector<bool> LoopWritesMemory; // static, indirect or indexed writes
std::vector<bool> LoopReadsMemory; // static, indirect or indexed reads
......@@ -1134,7 +1157,6 @@ private:
bool PropagateSignedness(void); // Propagate signedness FG info from DEFs to USEs whenever there is no USE sign info.
bool FindLoopContinuePattern(const int BranchBlockNum); // Does code starting at COND_BRANCH in BranchBlockNum represent a C/C++ loop continue statement?
bool LoopContinueHelper(const int BranchBlockNum, const int InnerMostLoopNum, const SMPBasicBlock *CurrentBlock);
void MarkSpecialNumericErrorCases(void); // Detect and mark special cases before emitting numeric error annotations.
void MarkLoopContinueCases(const SMPBasicBlock *CurrBlock, const int HeaderBlockNum, const std::size_t BlockIndex, const STARS_ea_t InstAddr); // refactored helper for MarkSpecialNumericErrorCases()
void EmitReturnTargetAnnotations(void); // Emit Indirect Branch Target destinations for return instructions in this func.
void EmitFuncPtrShadowingAnnotations(FILE *InfoAnnotFile); // Emit annotations for func ptr shadowing defense
......
......@@ -93,6 +93,7 @@
#define STARS_PSEUDO_ID_MIN ((STARS_ea_t) STARS_BADADDR - STARS_BLOCKNUM_MASK)
#define STARS_PSEUDO_BLOCKNUM_MAX ((STARS_ea_t) STARS_BADADDR - 3)
#define STARS_IsNotPseudoInstID(addr) (STARS_PSEUDO_ID_MIN > addr)
#define STARS_IsLiveInPseudoID(addr) (STARS_LIVEIN_PSEUDO_ID == ((STARS_ea_t) addr))
#define STARS_IsSSAMarkerPseudoID(addr) (STARS_SSA_MARKER_PSEUDO_ID == ((STARS_ea_t) addr))
#define STARS_IsBlockNumPseudoID(addr) ((STARS_PSEUDO_ID_MIN <= ((STARS_ea_t) addr)) && (STARS_PSEUDO_BLOCKNUM_MAX >= ((STARS_ea_t) addr)))
......
......@@ -1732,8 +1732,10 @@ SMPInstr * SMPBasicBlock::FindBranchCompareOrTest(SMPoperator &BranchOperator, S
bool EndsWithCondBranch = ((COND_BRANCH == BranchInst->GetDataFlowType()) && (!EndsWithLoopInst));
// NOTE: Handle loop opcodes later.
if (EndsWithLoopInst)
if (EndsWithLoopInst) {
DecAddr = STARS_BADADDR;
return CompareOrTestInst;
}
if (!SearchCase) {
BranchOperator = BranchInst->GetCondBranchOperator();
......@@ -1779,6 +1781,7 @@ SMPInstr * SMPBasicBlock::FindBranchCompareOrTest(SMPoperator &BranchOperator, S
// Something besides compare, test or decrement set the flags.
SMP_msg("ERROR: COND_BRANCH: Flags set by unexpected opcode in inst at %llx: CurrSSA: %d \n",
(uint64_t) InstAddr, CurrFlagsSSANum);
CurrInst->Dump();
}
else {
SMP_msg("ERROR: COND_BRANCH: Flags SSANum did not match in block at %llx: CurrSSA: %d SearchSSA: %d\n",
......
This diff is collapsed.
......@@ -895,6 +895,25 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn
SMP_msg("INFO: TIME: Phase 7: ReturnTargets + InterproceduralTypes + InArgTypes + TraceInArgs: %7.2f\n", TimeDiff);
SMP_msg("INFO: VMEM: Phase 7: Maximum resident memory usage in MB: %ld \n", global_stars_interface->GetMemoryInUse());
// Loop 7A: MarkSpecialNumericErrorCases(), including SPARK structured analysis.
// Find and mark special cases that will affect the integer error and other security annotations.
Time4 = time(nullptr);
if (global_STARS_program->ShouldSTARSPerformDeepLoopAnalyses()) {
for (FuncListIter = this->PrioritizedFuncList.begin(); FuncListIter != this->PrioritizedFuncList.end(); ++FuncListIter) {
CurrFunc = (*FuncListIter);
if (nullptr == CurrFunc) {
SMP_msg("ERROR: NULL Func ptr in PrioritizedFuncList\n");
continue;
}
if (CurrFunc->StackPtrAnalysisSucceeded() && CurrFunc->HasGoodRTLs()) {
CurrFunc->MarkSpecialNumericErrorCases();
}
}
}
Time5 = time(nullptr);
TimeDiff = difftime(Time5, Time4);
SMP_msg("INFO: TIME: Phase 7A: MarkSpecialNumericErrorCases+StructuralAnalysis: %7.2f \n", TimeDiff);
SMP_msg("INFO: VMEM: Phase 7A: Maximum resident memory usage in MB: %ld \n", global_stars_interface->GetMemoryInUse());
// Loop 7B: Loop iteration and memory access analysis.
Time4 = time(nullptr);
......@@ -905,9 +924,9 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn
SMP_msg("ERROR: NULL Func ptr in PrioritizedFuncList\n");
continue;
}
if (CurrFunc->StackPtrAnalysisSucceeded() && CurrFunc->HasGoodRTLs() && (!CurrFunc->HasUnresolvedIndirectJumps())) {
CurrFunc->AnalyzeLoopIterations();
}
if (CurrFunc->StackPtrAnalysisSucceeded() && CurrFunc->HasGoodRTLs() && (!CurrFunc->HasUnresolvedIndirectJumps())) {
CurrFunc->AnalyzeLoopIterations();
}
}
}
Time5 = time(nullptr);
......