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 (26)
Showing
with 3789 additions and 403 deletions
...@@ -360,6 +360,8 @@ public: ...@@ -360,6 +360,8 @@ public:
inline bool IsSelfLoop(void) const { return (IsLoopHeaderBlock() && IsLoopTailBlock() && (GetCondNonFallThroughSuccBlockNum() == GetNumber())); }; inline bool IsSelfLoop(void) const { return (IsLoopHeaderBlock() && IsLoopTailBlock() && (GetCondNonFallThroughSuccBlockNum() == GetNumber())); };
inline bool IsReadyToTranslate(void) const { return (GetSPARKTranslationCount() < GetSPARKTranslationLimit()); }; inline bool IsReadyToTranslate(void) const { return (GetSPARKTranslationCount() < GetSPARKTranslationLimit()); };
bool IsBlockPred(int BlockNum) const; // Is BlockNum a predecessor block of this block bool IsBlockPred(int BlockNum) const; // Is BlockNum a predecessor block of this block
bool IsShortCircuitHead(void) const;
bool IsShortCircuitNonHead(void) const;
bool HasLoopHeadAsSuccessor(int &HeadBlockNum) const; // block has HeadBlockNum as successor, which is a loop header bool HasLoopHeadAsSuccessor(int &HeadBlockNum) const; // block has HeadBlockNum as successor, which is a loop header
bool HasLoopHeadWithInvertedExitAsSuccessor(void) const; // block has loop head successor that ends with INVERTED_LOOP_EXIT bool HasLoopHeadWithInvertedExitAsSuccessor(void) const; // block has loop head successor that ends with INVERTED_LOOP_EXIT
bool HasInvertedLoopBack(void) const; // COND_BRANCH falls through to loop header of innermost loop containing this block bool HasInvertedLoopBack(void) const; // COND_BRANCH falls through to loop header of innermost loop containing this block
...@@ -387,6 +389,7 @@ public: ...@@ -387,6 +389,7 @@ public:
bool IsAddrInBlock(const STARS_ea_t InstAddr) const; bool IsAddrInBlock(const STARS_ea_t InstAddr) const;
bool IsAnyStackOpKilled(void) const; // does VarKill set have any stack operands? bool IsAnyStackOpKilled(void) const; // does VarKill set have any stack operands?
bool HasConditionalBranch(void) const; // true if (last) instruction is conditional branch bool HasConditionalBranch(void) const; // true if (last) instruction is conditional branch
bool HasBranchToOtherFunc(void) const; // Last inst is conditional branch outside current function
bool HasMemoryWrite(void) const; // Writes to stack or has indirect write bool HasMemoryWrite(void) const; // Writes to stack or has indirect write
bool IsInArgPointerCopy(const STARSOpndTypePtr &CurrOp, int SSANum) const; // found in local InArgPointerCopies? bool IsInArgPointerCopy(const STARSOpndTypePtr &CurrOp, int SSANum) const; // found in local InArgPointerCopies?
bool IsOpDestTruncatedWrite(const STARSOpndTypePtr &DefOp, int DefSSANum, STARS_ea_t DefAddr); // Does DefOp get written out in truncated form (lower bits only)? bool IsOpDestTruncatedWrite(const STARSOpndTypePtr &DefOp, int DefSSANum, STARS_ea_t DefAddr); // Does DefOp get written out in truncated form (lower bits only)?
...@@ -780,10 +783,12 @@ public: ...@@ -780,10 +783,12 @@ public:
inline bool IsSelfLoop(void) const { return GetOriginalBlock()->IsSelfLoop(); }; inline bool IsSelfLoop(void) const { return GetOriginalBlock()->IsSelfLoop(); };
inline bool IsUnreachableBlock(void) const { return GetOriginalBlock()->IsUnreachableBlock(); }; inline bool IsUnreachableBlock(void) const { return GetOriginalBlock()->IsUnreachableBlock(); };
inline bool IsReadyToTranslate(void) const { return GetOriginalBlock()->IsReadyToTranslate(); }; inline bool IsReadyToTranslate(void) const { return GetOriginalBlock()->IsReadyToTranslate(); };
inline bool HasBranchToOtherFunc(void) const { return GetOriginalBlock()->HasBranchToOtherFunc(); };
bool IsBlockNumPred(const int BlockNum) const; // Is BlockNum a predecessor block of this block bool IsBlockNumPred(const int BlockNum) const; // Is BlockNum a predecessor block of this block
bool IsBlockPred(const STARSTransCFGBlock *TCFGBlock) const; // Is TCFGBlock a predecessor block of this block bool IsBlockPred(const STARSTransCFGBlock *TCFGBlock) const; // Is TCFGBlock a predecessor block of this block
bool IsBlockSucc(const STARSTransCFGBlock *TCFGBlock) const; // Is TCFGBlock a successor block of this block bool IsBlockSucc(const STARSTransCFGBlock *TCFGBlock) const; // Is TCFGBlock a successor block of this block
bool IsBlockInLoop(std::size_t LoopNum) const; bool IsBlockInLoop(std::size_t LoopNum) const;
inline bool IsBlockInDomFrontier(const int TCFGBlockNum) const { return (this->DomFrontier.find(TCFGBlockNum) != this->DomFrontier.cend()); };
// Auditing methods. // Auditing methods.
bool HasPred(const STARSTransCFGBlock *TestPred) const; bool HasPred(const STARSTransCFGBlock *TestPred) const;
...@@ -796,6 +801,9 @@ public: ...@@ -796,6 +801,9 @@ public:
int FindParentCondBranchTCFGBlockNum(void); // Search upward for block ending in a COND_BRANCH int FindParentCondBranchTCFGBlockNum(void); // Search upward for block ending in a COND_BRANCH
int FindChildLoopHeaderTCFGBlockNum(void); // Search downward for first loop header block that current TCFG block dominates int FindChildLoopHeaderTCFGBlockNum(void); // Search downward for first loop header block that current TCFG block dominates
// NOTE: Call SMPFunction::ResetTCFGVisitedBlocks() before calling STARSTransCFGBlock::isBlockReachableWithoutBackEdges().
bool IsBlockReachableWithoutBackEdges(const int DestTCFGBlockNum, bool &HitDeadEnd) const; // path without back edges?
private: private:
SMPFunction *MyFunc; SMPFunction *MyFunc;
int TCFGBlockNum; // new block number; might be cloned, or might match OriginalBockNum. int TCFGBlockNum; // new block number; might be cloned, or might match OriginalBockNum.
......
...@@ -576,16 +576,17 @@ public: ...@@ -576,16 +576,17 @@ public:
bool IsLoopInductionVarForAnySSANum(std::size_t LoopIndex, const STARSOpndTypePtr &CurrOp, STARSInductionVarFamilyIter &ListIter, std::size_t &FamilyIndex); // Relax the requirement to match SSA number to IV bool IsLoopInductionVarForAnySSANum(std::size_t LoopIndex, const STARSOpndTypePtr &CurrOp, STARSInductionVarFamilyIter &ListIter, std::size_t &FamilyIndex); // Relax the requirement to match SSA number to IV
bool IsLoopNestInductionVar(const STARSOpndTypePtr &CurrOp, SMPInstr *UseInst, STARSInductionVarFamilyIter &ListIter, std::size_t &FamilyIndex, int &LoopIndex); // For CurrOp in loop nest including UseInst, return iterator and position in family if true bool IsLoopNestInductionVar(const STARSOpndTypePtr &CurrOp, SMPInstr *UseInst, STARSInductionVarFamilyIter &ListIter, std::size_t &FamilyIndex, int &LoopIndex); // For CurrOp in loop nest including UseInst, return iterator and position in family if true
inline bool AltersSPARKMemory(void) const { return AltersMemory; }; inline bool AltersSPARKMemory(void) const { return AltersMemory; };
inline bool HasCloningOccurred(void) const { return (TCFGBlocks.size() > RPOBlocks.size()); };
inline bool HasSPARKUnstructuredMsgBeenPrinted(void) const { return PrintedSPARKUnstructuredMsg; }; inline bool HasSPARKUnstructuredMsgBeenPrinted(void) const { return PrintedSPARKUnstructuredMsg; };
inline bool UsesInArgsForLoopMemWrites(void) const { return HasLoopInArgMemWrites; }; inline bool UsesInArgsForLoopMemWrites(void) const { return HasLoopInArgMemWrites; };
inline bool CalleeUsesInArgsForLoopMemWrites(void) const { return CalleeHasLoopInArgMemWrites; }; inline bool CalleeUsesInArgsForLoopMemWrites(void) const { return CalleeHasLoopInArgMemWrites; };
inline bool IsCriticalInArg(std::size_t ArgPos) const { return (0 != (TaintInArgPosBits & (1 << ArgPos))); }; inline bool IsCriticalInArg(std::size_t ArgPos) const { return (0 != (TaintInArgPosBits & (1 << ArgPos))); };
inline bool DoesLoopHaveArgs(int LoopNum) const { return LoopMemRangeInArgRegsBitmap[(size_t) LoopNum].any(); }; inline bool DoesLoopHaveArgs(int LoopNum) const { return LoopMemRangeInArgRegsBitmap[(size_t) LoopNum].any(); };
bool DoesLoopHaveMultipleExitTargets(const size_t LoopNum) const; bool DoesLoopHaveMultipleExitTargets(const std::size_t LoopNum) const;
inline bool IsNonExitingLoopBackBranch(const STARS_ea_t BranchAddr) const { return LoopBackNonExitingBranches.find(BranchAddr) != LoopBackNonExitingBranches.cend(); }; inline bool IsNonExitingLoopBackBranch(const STARS_ea_t BranchAddr) const { return LoopBackNonExitingBranches.find(BranchAddr) != LoopBackNonExitingBranches.cend(); };
// Printing methods // Printing methods
void Dump(const bool SkeletonDump = false); // debug dump void Dump(const bool SkeletonDump); // debug dump
void DumpDotCFG(void); // Dump CFG representation for processing by "dot" program. void DumpDotCFG(void); // Dump CFG representation for processing by "dot" program.
inline void DumpFuncNameAndAddr(void) const { SMP_msg("in %s at %llx\n", this->GetFuncName(), (uint64_t) this->GetFirstFuncAddr()); }; inline void DumpFuncNameAndAddr(void) const { SMP_msg("in %s at %llx\n", this->GetFuncName(), (uint64_t) this->GetFirstFuncAddr()); };
...@@ -1056,7 +1057,7 @@ private: ...@@ -1056,7 +1057,7 @@ private:
bool DoesBlockExitLoop(std::size_t LoopNumber, SMPBasicBlock *LoopBlock, int &FollowBlockNum); // return true if block can exit the loop. bool DoesBlockExitLoop(std::size_t LoopNumber, SMPBasicBlock *LoopBlock, int &FollowBlockNum); // return true if block can exit the loop.
bool DetectMultiLevelLoopBreak(const int LoopBlockNum, const int ExitTargetBlockNum) const; // Is ExitTargetBlockNum more than 1 loop nesting level away from LoopBlockNum? bool DetectMultiLevelLoopBreak(const int LoopBlockNum, const int ExitTargetBlockNum) const; // Is ExitTargetBlockNum more than 1 loop nesting level away from LoopBlockNum?
void ComputeLoopFollowNodesReachability(const std::size_t LoopNum); // populate entry in LoopExitTargetsReachabilitySets void ComputeLoopFollowNodesReachability(const std::size_t LoopNum); // populate entry in LoopExitTargetsReachabilitySets
void MarkReachableBlocks(const int BlockNum, const int LoopNum, const int HeadBlockNum, const bool TestDominance, const int LimitBlockNum, STARSBitSet &ReachableSet); // Set bits of current BlockNum and its descendants in CFG (that are dominated by HeadBlockNum, if TestDominance) void MarkReachableBlocks(const int BlockNum, const int LoopNum, const int HeadBlockNum, const bool TestDominance, const int LimitBlockNum, STARSBitSet &ReachableSet, const int StopBlockNum = SMP_BLOCKNUM_UNINIT); // Set bits of current BlockNum and its descendants in CFG (that are dominated by HeadBlockNum, if TestDominance)
uint32_t GetReachableSourcesCount(const std::size_t TCFGBlockNum, const std::size_t LoopNum) const; // How many of the multiple exit targets from LoopNum reach BlockNum? uint32_t GetReachableSourcesCount(const std::size_t TCFGBlockNum, const std::size_t LoopNum) const; // How many of the multiple exit targets from LoopNum reach BlockNum?
bool CanBlockBypassBlock(const int BlockNum, const int SentinelBlockNum, const int LimitBlockNum, const STARSBitSet &SentinelReachableBlocks) const; // Downward path from BlockNum to Sentinel-reachable-block without hitting SentinelBlockNum? bool CanBlockBypassBlock(const int BlockNum, const int SentinelBlockNum, const int LimitBlockNum, const STARSBitSet &SentinelReachableBlocks) const; // Downward path from BlockNum to Sentinel-reachable-block without hitting SentinelBlockNum?
void DetectLoopInvariantDEFs(void); // Collect a set of loop-invariant DEFs with the inst IDs of the DEFs. void DetectLoopInvariantDEFs(void); // Collect a set of loop-invariant DEFs with the inst IDs of the DEFs.
...@@ -1110,6 +1111,7 @@ private: ...@@ -1110,6 +1111,7 @@ private:
int FindConditionalFollowNode4(const int HeadBlockNum, bool &IfThenCase, bool &OddIfThenCase, bool &IfThenElseCase, bool &ShortCircuit); // Find candidate block # for if-else follow node for HeadBlockNum; return -1 otherwise int FindConditionalFollowNode4(const int HeadBlockNum, bool &IfThenCase, bool &OddIfThenCase, bool &IfThenElseCase, bool &ShortCircuit); // Find candidate block # for if-else follow node for HeadBlockNum; return -1 otherwise
bool SolveConditionalDomFrontierProblemViaCloning(const int HeadBlockNum, const int FTBlockNum, const int NFTBlockNum, const int FTDomFrontierBlockNum, const int NFTDomFrontierBlockNum, int &FollowBlockNum); // return true if cloning blocks would make DomFrontiers converge bool SolveConditionalDomFrontierProblemViaCloning(const int HeadBlockNum, const int FTBlockNum, const int NFTBlockNum, const int FTDomFrontierBlockNum, const int NFTDomFrontierBlockNum, int &FollowBlockNum); // return true if cloning blocks would make DomFrontiers converge
bool IsCloningSafe(const int StartTCFGBlockNum, const int LimitTCFGBlockNum, std::set<int> &BlockNumsToClone) const; // Is it safe to clone path from StartBlockNum, stopping when LimitBlockNum is reached? bool IsCloningSafe(const int StartTCFGBlockNum, const int LimitTCFGBlockNum, std::set<int> &BlockNumsToClone) const; // Is it safe to clone path from StartBlockNum, stopping when LimitBlockNum is reached?
bool IsDoubleCloningSafe(const int StartTCFGBlockNum1, const int StartTCFGBlockNum2); // Is it safe to double clone paths from StartBlockNum1 & 2, without either path running into the other start block?
void MarkBlocksAndClone(const int StartingBlockNum, const int UnlinkBlockNum, const int LimitBlockNum, const int InnermostLoopNum, bool FirstIter); // Clone blocks on path from StartingBlockNum to <LimitBlockNum within InnermostLoopNum; unlink cloned StartingBlockNum from pred UnlinkBlockNum void MarkBlocksAndClone(const int StartingBlockNum, const int UnlinkBlockNum, const int LimitBlockNum, const int InnermostLoopNum, bool FirstIter); // Clone blocks on path from StartingBlockNum to <LimitBlockNum within InnermostLoopNum; unlink cloned StartingBlockNum from pred UnlinkBlockNum
bool UpdateAfterCloning(void); // Update data structures, set pred & succ links, etc. after cloning bool UpdateAfterCloning(void); // Update data structures, set pred & succ links, etc. after cloning
void UpdateCFGExprBlockNums(STARSCondExpr *CurrExpr); // Update left, right, FT and NFT block nums in CurrExpr; recurse into subexprs. void UpdateCFGExprBlockNums(STARSCondExpr *CurrExpr); // Update left, right, FT and NFT block nums in CurrExpr; recurse into subexprs.
...@@ -1141,7 +1143,7 @@ private: ...@@ -1141,7 +1143,7 @@ private:
void EmitSPARKLoopProcGlobals(FILE *BodyFile, FILE *HeaderFile, bool MemoryInput, bool MemoryOutput, const std::bitset<1 + MD_LAST_REG_NO> &InputRegs, const std::bitset<1 + MD_LAST_REG_NO> &OutputRegs, const std::bitset<1 + MD_LAST_REG_NO> &CalleePreservedRegs); // emit Input, Output, In_Out flow annotations void EmitSPARKLoopProcGlobals(FILE *BodyFile, FILE *HeaderFile, bool MemoryInput, bool MemoryOutput, const std::bitset<1 + MD_LAST_REG_NO> &InputRegs, const std::bitset<1 + MD_LAST_REG_NO> &OutputRegs, const std::bitset<1 + MD_LAST_REG_NO> &CalleePreservedRegs); // emit Input, Output, In_Out flow annotations
void EmitSPARKAdaForBlock(int CurrTCFGBlockNum, const int DomTCFGBlockNum, const int FollowTCFGBlockNum, FILE *SPARKBodyFile, const bool ReadytoEmitSwitchDefault, const bool LoopToProc, const uint32_t ReachableSourcesCount = 0); // recursive descent translation to SPARK Ada starting with CurrBlock, stop before Follow Block void EmitSPARKAdaForBlock(int CurrTCFGBlockNum, const int DomTCFGBlockNum, const int FollowTCFGBlockNum, FILE *SPARKBodyFile, const bool ReadytoEmitSwitchDefault, const bool LoopToProc, const uint32_t ReachableSourcesCount = 0); // recursive descent translation to SPARK Ada starting with CurrBlock, stop before Follow Block
void EmitSPARKAdaForLoop(int HeaderTCFGBlockNum, int FollowTCFGBlockNum, FILE *SPARKBodyFile); // recursive descent translation of loop to SPARK Ada starting with header CurrBlock, stop before Follow Block void EmitSPARKAdaForLoop(int HeaderTCFGBlockNum, int FollowTCFGBlockNum, FILE *SPARKBodyFile); // recursive descent translation of loop to SPARK Ada starting with header CurrBlock, stop before Follow Block
void EmitSPARKAdaForMultipleLoopExitTargets(FILE *SPARKBodyFile, std::size_t LoopNum); // translate multiple exit targets & their reachable region void EmitSPARKAdaForMultipleLoopExitTargets(FILE *SPARKBodyFile, const std::size_t LoopNum, const int HeaderTCFGBlockNum); // translate multiple exit targets & their reachable region
void EmitSPARKAdaForSwitch(int HeaderTCFGBlockNum, int FollowTCFGBlockNum, FILE *SPARKBodyFile); // recursive descent translation of switch statement starting with INDIR_JUMP block, stop before Follow Block void EmitSPARKAdaForSwitch(int HeaderTCFGBlockNum, int FollowTCFGBlockNum, FILE *SPARKBodyFile); // recursive descent translation of switch statement starting with INDIR_JUMP block, stop before Follow Block
void EmitSPARKAdaForConditional(int HeaderTCFGBlockNum, int FollowTCFGBlockNum, FILE *SPARKBodyFile); // recursive descent translation of if-else statement starting with COND_BRANCH block, stop before Follow Block void EmitSPARKAdaForConditional(int HeaderTCFGBlockNum, int FollowTCFGBlockNum, FILE *SPARKBodyFile); // recursive descent translation of if-else statement starting with COND_BRANCH block, stop before Follow Block
bool EmitSPARKAdaLoopCall(STARS_ea_t LoopAddr, std::size_t LoopIndex, FILE *SPARKBodyFile); // emit call to loop proc that will be created later starting at LoopAddr bool EmitSPARKAdaLoopCall(STARS_ea_t LoopAddr, std::size_t LoopIndex, FILE *SPARKBodyFile); // emit call to loop proc that will be created later starting at LoopAddr
......
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
// By using STARS_BADADDR, which matches the IDA Pro BADADDR constant, we can automatically adjust for 32/64-bit systems. // By using STARS_BADADDR, which matches the IDA Pro BADADDR constant, we can automatically adjust for 32/64-bit systems.
#define STARS_SSA_MARKER_PSEUDO_ID ((STARS_ea_t) STARS_BADADDR - 1) #define STARS_SSA_MARKER_PSEUDO_ID ((STARS_ea_t) STARS_BADADDR - 1)
#define STARS_LIVEIN_PSEUDO_ID ((STARS_ea_t) STARS_BADADDR - 2) #define STARS_LIVEIN_PSEUDO_ID ((STARS_ea_t) STARS_BADADDR - 2)
#define STARS_EXTERNAL_FUNC_ADDR STARS_LIVEIN_PSEUDO_ID
// All actual instructions should be on addresses below STARS_PSEUDO_ID_MIN // All actual instructions should be on addresses below STARS_PSEUDO_ID_MIN
// Between STARS_PSEUDO_ID_MIN and STARS_PSEUDO_BLOCKNUM_MAX can be basic block numbers as fake addresses // Between STARS_PSEUDO_ID_MIN and STARS_PSEUDO_BLOCKNUM_MAX can be basic block numbers as fake addresses
#define STARS_BLOCKNUM_MASK 0xffff #define STARS_BLOCKNUM_MASK 0xffff
...@@ -95,6 +96,7 @@ ...@@ -95,6 +96,7 @@
#define STARS_IsNotPseudoInstID(addr) (STARS_PSEUDO_ID_MIN > addr) #define STARS_IsNotPseudoInstID(addr) (STARS_PSEUDO_ID_MIN > addr)
#define STARS_IsLiveInPseudoID(addr) (STARS_LIVEIN_PSEUDO_ID == ((STARS_ea_t) addr)) #define STARS_IsLiveInPseudoID(addr) (STARS_LIVEIN_PSEUDO_ID == ((STARS_ea_t) addr))
#define STARS_IsExternalFunc(addr) (STARS_EXTERNAL_FUNC_ADDR == ((STARS_ea_t) addr))
#define STARS_IsSSAMarkerPseudoID(addr) (STARS_SSA_MARKER_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))) #define STARS_IsBlockNumPseudoID(addr) ((STARS_PSEUDO_ID_MIN <= ((STARS_ea_t) addr)) && (STARS_PSEUDO_BLOCKNUM_MAX >= ((STARS_ea_t) addr)))
#define STARS_GetBlockNumFromPseudoID(addr) (((STARS_ea_t) addr) & STARS_BLOCKNUM_MASK) #define STARS_GetBlockNumFromPseudoID(addr) (((STARS_ea_t) addr) & STARS_BLOCKNUM_MASK)
......
...@@ -150,10 +150,18 @@ struct SwitchTableInfo { // info about a switch table ...@@ -150,10 +150,18 @@ struct SwitchTableInfo { // info about a switch table
#define STARS_dt_bitfild 12 // bit field (mc680x0) #define STARS_dt_bitfild 12 // bit field (mc680x0)
#define STARS_dt_string 13 // pointer to asciiz string #define STARS_dt_string 13 // pointer to asciiz string
#define STARS_dt_unicode 14 // pointer to unicode string #define STARS_dt_unicode 14 // pointer to unicode string
#if (IDA_SDK_VERSION < 700)
#define STARS_dt_3byte 15 // 3-byte data #define STARS_dt_3byte 15 // 3-byte data
#define STARS_dt_ldbl 16 // long double (which may be different from tbyte) #define STARS_dt_ldbl 16 // long double (which may be different from tbyte)
#define STARS_dt_byte32 17 // 256 bit #define STARS_dt_byte32 17 // 256 bit
#define STARS_dt_byte64 18 // 512 bit #define STARS_dt_byte64 18 // 512 bit
#else
#define STARS_dt_ldbl 15 // long double (which may be different from tbyte)
#define STARS_dt_byte32 16 // 256 bit
#define STARS_dt_byte64 17 // 512 bit
#define STARS_dt_half 18 // 2-byte floating point
#endif
// Part of our solution to the dense encoding of x86-64 is to record some instruction // Part of our solution to the dense encoding of x86-64 is to record some instruction
// prefix and auxprefix info in each operand, so we can continue to do data flow analysis // prefix and auxprefix info in each operand, so we can continue to do data flow analysis
...@@ -162,7 +170,7 @@ struct SwitchTableInfo { // info about a switch table ...@@ -162,7 +170,7 @@ struct SwitchTableInfo { // info about a switch table
// while analyzing an inst, and is too big to pass around with all operands in Phi DEFs, // while analyzing an inst, and is too big to pass around with all operands in Phi DEFs,
// LiveIn and LiveOut sets, SSA numbering and operand comparisons, etc. So, we record // LiveIn and LiveOut sets, SSA numbering and operand comparisons, etc. So, we record
// the insnpref byte (a.k.a. cmd.rex) into each operand in the specflag4 field, then we // the insnpref byte (a.k.a. cmd.rex) into each operand in the specflag4 field, then we
// record the following two bits of info into unused bits in specflag4. // record the following two bits of info (VEXPR and VSIB) into unused bits in specflag4.
// These first five constants imitate IDA Pro header <intel.hpp> constants. // These first five constants imitate IDA Pro header <intel.hpp> constants.
const int STARS_REX_W = 8; // 64-bit operand size const int STARS_REX_W = 8; // 64-bit operand size
const int STARS_REX_R = 4; // modrm reg field extension const int STARS_REX_R = 4; // modrm reg field extension
...@@ -408,7 +416,7 @@ enum STARS_RegNo ...@@ -408,7 +416,7 @@ enum STARS_RegNo
STARS_x86_R_k6 = 171, STARS_x86_R_k6 = 171,
STARS_x86_R_k7 = 172, STARS_x86_R_k7 = 172,
STARS_x86_R_last, STARS_x86_R_last, // 173
}; };
typedef STARS_RegNo STARS_regnum_t; typedef STARS_RegNo STARS_regnum_t;
...@@ -2475,6 +2483,22 @@ enum ...@@ -2475,6 +2483,22 @@ enum
STARS_NN_xresldtrk, // Resume Tracking Load Addresses STARS_NN_xresldtrk, // Resume Tracking Load Addresses
STARS_NN_xsusldtrk, // Suspend Tracking Load Addresses STARS_NN_xsusldtrk, // Suspend Tracking Load Addresses
// Intel Affine Transformation instructions
STARS_NN_gf2p8mulb, // Galois Field Multiply Bytes
STARS_NN_gf2p8affineqb, // Computes Affine Transformation
STARS_NN_gf2p8affineinvqb, // Computes Inverse Affine Transformation
// VEX versions
STARS_NN_vgf2p8mulb, // Galois Field Multiply Bytes
STARS_NN_vgf2p8affineqb, // Computes Affine Transformation
STARS_NN_vgf2p8affineinvqb, // Computes Inverse Affine Transformation
// Intrinsics for Saving and Restoring the Extended Processor States (64-bits)
STARS_NN_fxsave64, // Fast save FP context (64-bits)
STARS_NN_fxrstor64, // Fast restore FP context (64-bits)
STARS_NN_last, STARS_NN_last,
......
#ifndef STARS_IDA_Function_h #ifndef STARS_IDA_Function_h
#define STARS_IDA_Function_h #define STARS_IDA_Function_h
#if __GCC__ >= 8 #if __GNUC__ >= 8
#pragma GCC diagnostic ignored "-Wclass-memaccess" #pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif #endif
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <funcs.hpp> #include <funcs.hpp>
#include <frame.hpp> #include <frame.hpp>
#if __GCC__ >= 8 #if __GNUC__ >= 8
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
......
Subproject commit 45a8a215b746ac7b189e4c6ccbab669635abcf67 Subproject commit 5e41e26b88d415f3c7d3eb47f9f0d781cc519459
...@@ -641,7 +641,10 @@ void SMPBasicBlock::EmitSPARKAdaForFallThroughInsts(FILE *BodyFile) { ...@@ -641,7 +641,10 @@ void SMPBasicBlock::EmitSPARKAdaForFallThroughInsts(FILE *BodyFile) {
bool ControlFlowTerminator = ((InstAddr == LastID) && CurrInst->IsBasicBlockTerminator()); bool ControlFlowTerminator = ((InstAddr == LastID) && CurrInst->IsBasicBlockTerminator());
bool Untranslatable = CurrInst->IsMarkerInst() || (!CurrInst->IsAnalyzeable()); bool Untranslatable = CurrInst->IsMarkerInst() || (!CurrInst->IsAnalyzeable());
if (Untranslatable) { if (Untranslatable) {
// Set junk instructions to translated. // Set junk instructions to translated; emit only DisAsm text.
if (CurrInst->IsNop()) {
CurrInst->EmitSPARKAda(BodyFile, true);
}
CurrInst->SetSPARKTranslated(true); CurrInst->SetSPARKTranslated(true);
} }
else if (!ControlFlowTerminator) { else if (!ControlFlowTerminator) {
...@@ -1114,6 +1117,12 @@ list<SMPBasicBlock *>::const_iterator SMPBasicBlock::GetFallThroughSucc(void) co ...@@ -1114,6 +1117,12 @@ list<SMPBasicBlock *>::const_iterator SMPBasicBlock::GetFallThroughSucc(void) co
// instrumentation to trample the flags (but, perhaps that does not matter?) // instrumentation to trample the flags (but, perhaps that does not matter?)
// We choose to make the block have a fall-through successor that is the // We choose to make the block have a fall-through successor that is the
// same as the branch-taken successor. // same as the branch-taken successor.
// The other possibility is a conditional tail call, in which case the target
// of the COND_BRANCH is outside the current function. In that case,
// SMPFunction::SetLinks() will not link to the outside function, and there
// will be only one successor, the fall-through block within this function.
// The code below will never find the branch TargetAddr in that lone successor,
// so it will work correctly.
bool LoneSuccessorCase = (this->GetNumSuccessors() == 1); bool LoneSuccessorCase = (this->GetNumSuccessors() == 1);
bool MergeSuccessors = LoneSuccessorCase; bool MergeSuccessors = LoneSuccessorCase;
if (MergeSuccessors) { if (MergeSuccessors) {
...@@ -1123,7 +1132,8 @@ list<SMPBasicBlock *>::const_iterator SMPBasicBlock::GetFallThroughSucc(void) co ...@@ -1123,7 +1132,8 @@ list<SMPBasicBlock *>::const_iterator SMPBasicBlock::GetFallThroughSucc(void) co
MergeSuccessors = (NextAddr == NonFallThroughAddr); MergeSuccessors = (NextAddr == NonFallThroughAddr);
#endif #endif
if (MergeSuccessors) { if (MergeSuccessors) {
SMP_msg("INFO: Fallthrough and branch taken addresses are equal at %llx\n", (uint64_t)LastInst->GetAddr()); SMP_msg("INFO: Fallthrough and branch taken addresses are equal at %llx ", (uint64_t)LastInst->GetAddr());
this->GetFunc()->DumpFuncNameAndAddr();
} }
} }
for (list<SMPBasicBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) { for (list<SMPBasicBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) {
...@@ -1233,7 +1243,34 @@ bool SMPBasicBlock::IsBlockPred(int BlockNum) const { ...@@ -1233,7 +1243,34 @@ bool SMPBasicBlock::IsBlockPred(int BlockNum) const {
} }
} }
return FoundPred; return FoundPred;
} } // end of SMPBasicBlock::IsBlockPred()
// Is the corresponding ShadowCFG block the head of a short circuit expr?
bool SMPBasicBlock::IsShortCircuitHead(void) const {
int BlockNum = this->GetNumber();
bool CloningHasOccurred = this->GetFunc()->HasCloningOccurred();
int NewBlockNum = CloningHasOccurred ? this->GetFunc()->FindAnyTCFGBlockNumMatchingOrigBlockNum(BlockNum) : BlockNum;
STARSCFGBlock *ShadowBlock = this->GetFunc()->GetClonedCFGBlockByNum((size_t)NewBlockNum);
bool ShortCircuitHead = false;
if (nullptr != ShadowBlock) {
ShortCircuitHead = ShadowBlock->IsExprHeadBlock();
}
return ShortCircuitHead;
} // end of SMPBasicBlock::IsShortCircuitHead()
bool SMPBasicBlock::IsShortCircuitNonHead(void) const {
int BlockNum = this->GetNumber();
bool CloningHasOccurred = this->GetFunc()->HasCloningOccurred();
int NewBlockNum = CloningHasOccurred ? this->GetFunc()->FindAnyTCFGBlockNumMatchingOrigBlockNum(BlockNum) : BlockNum;
STARSCFGBlock *ShadowBlock = this->GetFunc()->GetClonedCFGBlockByNum((size_t)NewBlockNum);
bool ShortCircuitNonHead = false;
if (nullptr != ShadowBlock) {
ShortCircuitNonHead = ShadowBlock->IsCoalesced();
}
return ShortCircuitNonHead;
} // end of SMPBasicBlock::IsShortCircuitNonHead()
// Get the enum ControlFlowType for the last inst // Get the enum ControlFlowType for the last inst
ControlFlowType SMPBasicBlock::GetLastInstCFType(void) const { ControlFlowType SMPBasicBlock::GetLastInstCFType(void) const {
...@@ -1876,7 +1913,7 @@ STARS_ea_t SMPBasicBlock::GetDefAddrFromUseAddr(const STARSOpndTypePtr &UseOp, S ...@@ -1876,7 +1913,7 @@ STARS_ea_t SMPBasicBlock::GetDefAddrFromUseAddr(const STARSOpndTypePtr &UseOp, S
// Global DEF for this SSANum must be in the Phi functions or within a block. // Global DEF for this SSANum must be in the Phi functions or within a block.
DefAddr = this->MyFunc->GetGlobalDefAddr(UseOp, SSANum); // only works on registers and stack locations DefAddr = this->MyFunc->GetGlobalDefAddr(UseOp, SSANum); // only works on registers and stack locations
if (DefAddr == STARS_BADADDR) { // Could not find it anywhere. if (DefAddr == STARS_BADADDR) { // Could not find it anywhere.
this->GetFunc()->Dump(); this->GetFunc()->Dump(false);
SMP_msg("ERROR: Failure in GetDefAddrFromUseAddr(): InstAddr %lx SSANum %d\n", SMP_msg("ERROR: Failure in GetDefAddrFromUseAddr(): InstAddr %lx SSANum %d\n",
(unsigned long) InstAddr, SSANum); (unsigned long) InstAddr, SSANum);
SMP_msg(" LocalName: %d UseOp.reg: %d\n", LocalName, UseOp->GetReg()); SMP_msg(" LocalName: %d UseOp.reg: %d\n", LocalName, UseOp->GetReg());
...@@ -6155,6 +6192,14 @@ bool SMPBasicBlock::HasConditionalBranch(void) const { ...@@ -6155,6 +6192,14 @@ bool SMPBasicBlock::HasConditionalBranch(void) const {
return HasCondBranch; return HasCondBranch;
} // end of SMPBasicBlock::HasConditionalBranch() } // end of SMPBasicBlock::HasConditionalBranch()
bool SMPBasicBlock::HasBranchToOtherFunc(void) const {
vector<SMPInstr *>::const_reverse_iterator InstIter = this->InstVec.crbegin();
SMPInstr *LastInst = (*InstIter);
bool HasBranchOutsideFunc = LastInst->IsBranchToOtherFunc();
return HasBranchOutsideFunc;
} // end of SMPBasicBlock::HasBranchToOtherFunc()
// Writes to stack or has indirect write // Writes to stack or has indirect write
bool SMPBasicBlock::HasMemoryWrite(void) const { bool SMPBasicBlock::HasMemoryWrite(void) const {
bool HasMemWrite = this->HasIndirectMemWrite(); bool HasMemWrite = this->HasIndirectMemWrite();
...@@ -8159,7 +8204,7 @@ bool SMPBasicBlock::IsNextDownwardUseNotByExternalCallInst(const STARSOpndTypePt ...@@ -8159,7 +8204,7 @@ bool SMPBasicBlock::IsNextDownwardUseNotByExternalCallInst(const STARSOpndTypePt
// We want to accept their USE of a register as precise, but not // We want to accept their USE of a register as precise, but not
// the pseudo-USEs by external (linker-resolved) calls. // the pseudo-USEs by external (linker-resolved) calls.
STARS_ea_t CallTargetAddr = CurrInst->GetCallTarget(); STARS_ea_t CallTargetAddr = CurrInst->GetCallTarget();
FoundCallUse = (STARS_BADADDR != CallTargetAddr); FoundCallUse = (STARS_BADADDR != CallTargetAddr) && (!STARS_IsExternalFunc(CallTargetAddr));
if (FoundCallUse) { if (FoundCallUse) {
SMPFunction *TargetFunc = this->GetFunc()->GetProg()->FindFunction(CallTargetAddr); SMPFunction *TargetFunc = this->GetFunc()->GetProg()->FindFunction(CallTargetAddr);
FoundCallUse = ((nullptr != TargetFunc) && TargetFunc->IsLinkerStub()); FoundCallUse = ((nullptr != TargetFunc) && TargetFunc->IsLinkerStub());
...@@ -8583,7 +8628,13 @@ list<STARSTransCFGBlock *>::const_iterator STARSTransCFGBlock::GetFallThroughSuc ...@@ -8583,7 +8628,13 @@ list<STARSTransCFGBlock *>::const_iterator STARSTransCFGBlock::GetFallThroughSuc
bool MergeSuccessors = LoneSuccessorCase; bool MergeSuccessors = LoneSuccessorCase;
if (MergeSuccessors) { if (MergeSuccessors) {
if (MergeSuccessors) { if (MergeSuccessors) {
SMP_msg("INFO: Fallthrough and branch taken addresses are equal at %llx\n", (uint64_t)LastInst->GetAddr()); SMP_msg("INFO: Fallthrough and branch taken addresses are equal at %llx ", (uint64_t)LastInst->GetAddr());
if (nullptr != this->GetFunc()) {
this->GetFunc()->DumpFuncNameAndAddr();
}
else {
SMP_msg("\n");
}
} }
} }
for (list<STARSTransCFGBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) { for (list<STARSTransCFGBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) {
...@@ -9130,3 +9181,56 @@ int STARSTransCFGBlock::FindChildLoopHeaderHelper(const int BlockNumThatDominate ...@@ -9130,3 +9181,56 @@ int STARSTransCFGBlock::FindChildLoopHeaderHelper(const int BlockNumThatDominate
} }
return ChildLoopHeaderBlockNum; return ChildLoopHeaderBlockNum;
} // end of STARSTransCFGBlock::FindChildLoopHeaderHelper() } // end of STARSTransCFGBlock::FindChildLoopHeaderHelper()
// NOTE: Call SMPFunction::ResetTCFGVisitedBlocks() before calling STARSTransCFGBlock::isBlockReachableWithoutBackEdges().
// Mark as processed, recurse into successors depth-first, do not follow back edges.
bool STARSTransCFGBlock::IsBlockReachableWithoutBackEdges(const int DestTCFGBlockNum, bool &HitDeadEnd) const {
bool Found = false;
list<STARSTransCFGBlock *>::const_iterator CurrSucc;
int CurrBlockNum = this->GetNumber();
if (CurrBlockNum == DestTCFGBlockNum) {
Found = true;
return Found;
}
// See if we can get lucky by finding the block in the DomFrontier.
// This search is more breadth-first; combining breadth-first checks
// into the depth-first search can speed up the search in a deep CFG.
for (int DomFrontierBlockNum : this->DomFrontier) {
if (DomFrontierBlockNum == DestTCFGBlockNum) {
Found = true;
break;
}
} // end for all DomFrontier blocks
if (0 == this->GetNumSuccessors()) {
HitDeadEnd = true;
}
else {
for (CurrSucc = this->GetFirstConstSucc(); !Found && (CurrSucc != this->GetLastConstSucc()); ++CurrSucc) {
STARSTransCFGBlock *SuccBlock = (*CurrSucc);
int SuccBlockNum = SuccBlock->GetNumber();
if (SuccBlockNum > CurrBlockNum) { // not back edge
if (SuccBlockNum == DestTCFGBlockNum) {
Found = true;
SuccBlock->SetVisited(true);
}
else if (SuccBlock->IsVisited()) { // already hit this block on our search
break; // return false
}
else if (SuccBlockNum > DestTCFGBlockNum) {
// RPO ordering means we can no longer reach DestBlockNum without a back edge.
SuccBlock->SetVisited(true);
break; // return false
}
else {
SuccBlock->SetVisited(true);
Found = SuccBlock->IsBlockReachableWithoutBackEdges(DestTCFGBlockNum, HitDeadEnd); // recurse, depth-first
}
}
} // end for all successor blocks
}
return Found;
} // end of STARSTransCFGBlock::IsBlockReachableWithoutBackEdges()
...@@ -329,15 +329,22 @@ size_t GetOpDataSize(const STARSOpndTypePtr &DataOp) { ...@@ -329,15 +329,22 @@ size_t GetOpDataSize(const STARSOpndTypePtr &DataOp) {
case STARS_dt_fword: case STARS_dt_fword:
DataSize = 6; DataSize = 6;
break; break;
#if (IDA_SDK_VERSION < 700)
case STARS_dt_3byte: case STARS_dt_3byte:
DataSize = 3; DataSize = 3;
break; break;
#endif
case STARS_dt_byte32: case STARS_dt_byte32:
DataSize = 32; DataSize = 32;
break; break;
case STARS_dt_byte64: case STARS_dt_byte64:
DataSize = 64; DataSize = 64;
break; break;
#if (IDA_SDK_VERSION >= 700)
case STARS_dt_half: // 2-byte floating point
DataSize = 16;
break;
#endif
default: default:
SMP_msg("ERROR: unexpected data type %d in GetOpDataSize() :", OpDtyp); SMP_msg("ERROR: unexpected data type %d in GetOpDataSize() :", OpDtyp);
PrintOperand(DataOp); PrintOperand(DataOp);
...@@ -1397,7 +1404,12 @@ void StringPrintOperand(const STARSOpndTypePtr &Opnd, string &OutStream, bool Us ...@@ -1397,7 +1404,12 @@ void StringPrintOperand(const STARSOpndTypePtr &Opnd, string &OutStream, bool Us
if (SignedOffset > 0) { // print plus sign if (SignedOffset > 0) { // print plus sign
(void) SMP_strncat(OutString, "+", STARS_MAXSTR - 1); (void) SMP_strncat(OutString, "+", STARS_MAXSTR - 1);
} }
#if 0
(void) SMP_snprintf(DummyBuf, STARS_MAXSTR - 1, "%lld", (int64_t) Opnd->GetImmedValue()); (void) SMP_snprintf(DummyBuf, STARS_MAXSTR - 1, "%lld", (int64_t) Opnd->GetImmedValue());
#else
(void)SMP_snprintf(DummyBuf, STARS_MAXSTR - 1, "%lld", (int64_t)SignedOffset);
SMP_msg("INFO: StringPrintOperand case reached: MemDisplacement with SIB byte.\n");
#endif
(void) SMP_strncat(OutString, DummyBuf, STARS_MAXSTR - 1); (void) SMP_strncat(OutString, DummyBuf, STARS_MAXSTR - 1);
(void) SMP_strncat(OutString, "]", STARS_MAXSTR - 1); (void) SMP_strncat(OutString, "]", STARS_MAXSTR - 1);
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -191,9 +191,11 @@ bool SMPProgram::FindGlobalMaxValue(const STARS_ea_t GlobalAddr, STARS_uval_t &M ...@@ -191,9 +191,11 @@ bool SMPProgram::FindGlobalMaxValue(const STARS_ea_t GlobalAddr, STARS_uval_t &M
// in the FuncMap, else return nullptr. // in the FuncMap, else return nullptr.
SMPFunction *SMPProgram::FindFunction(STARS_ea_t FirstAddr) const { SMPFunction *SMPProgram::FindFunction(STARS_ea_t FirstAddr) const {
SMPFunction *FuncPtr = nullptr; SMPFunction *FuncPtr = nullptr;
map<STARS_ea_t, SMPFunction *>::const_iterator FuncMapIter = this->FuncMap.find(FirstAddr); if (STARS_BADADDR != FirstAddr) {
if (this->FuncMap.cend() != FuncMapIter) { map<STARS_ea_t, SMPFunction *>::const_iterator FuncMapIter = this->FuncMap.find(FirstAddr);
FuncPtr = FuncMapIter->second; if (this->FuncMap.cend() != FuncMapIter) {
FuncPtr = FuncMapIter->second;
}
} }
return FuncPtr; return FuncPtr;
} // end of SMPProgram::FindFunction() } // end of SMPProgram::FindFunction()
...@@ -724,18 +726,20 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn ...@@ -724,18 +726,20 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn
Time2 = time(nullptr); Time2 = time(nullptr);
for (size_t i = 0; i < NumCallTargets; ++i) { for (size_t i = 0; i < NumCallTargets; ++i) {
STARS_ea_t CallAddr = CurrFunc->GetCallTargetAddr(i); STARS_ea_t CallAddr = CurrFunc->GetCallTargetAddr(i);
SMPFunction *ChildInstance = this->FindFunction(CallAddr); if ((STARS_BADADDR != CallAddr) && (!STARS_IsExternalFunc(CallAddr))) {
if (!ChildInstance) { SMPFunction *ChildInstance = this->FindFunction(CallAddr);
if (!ChildInstance) {
#if SMP_DEBUG_FUNC #if SMP_DEBUG_FUNC
// if a call target doesn't have a SMPFunction instance note it down // if a call target doesn't have a SMPFunction instance note it down
if (!CurrFunc->IsLinkerStub() && (STARS_BADADDR != CallAddr)) { if (!CurrFunc->IsLinkerStub() && (STARS_BADADDR != CallAddr)) {
SMP_msg("ERROR: Function does not have SMPFunction instance at %llx from %s\n", (unsigned long long) CallAddr, CurrFunc->GetFuncName()); SMP_msg("ERROR: Function does not have SMPFunction instance at %llx from %s\n", (unsigned long long) CallAddr, CurrFunc->GetFuncName());
} }
#endif #endif
continue; continue;
}
UnsafeCallees |= (!ChildInstance->IsSafeCallee());
UnsafeSpecCallees |= (!ChildInstance->IsSpecSafeCallee());
} }
UnsafeCallees |= (!ChildInstance->IsSafeCallee());
UnsafeSpecCallees |= (!ChildInstance->IsSpecSafeCallee());
} }
Time3 = time(nullptr); Time3 = time(nullptr);
Analysis2 += difftime(Time3, Time2); Analysis2 += difftime(Time3, Time2);
...@@ -800,7 +804,7 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn ...@@ -800,7 +804,7 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn
#if SMP_DEBUG_OPTIMIZATIONS_VERBOSE #if SMP_DEBUG_OPTIMIZATIONS_VERBOSE
if (DebugFlag) { if (DebugFlag) {
CurrFunc->Dump(); CurrFunc->Dump(false);
DebugFlag = false; DebugFlag = false;
} }
#endif #endif
...@@ -859,9 +863,9 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn ...@@ -859,9 +863,9 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn
} }
#if 1 #if 1
// bool FuncFound = (0 == strcmp("__mktime_internal", CurrFunc->GetFuncName())); // bool FuncFound = (0 == strcmp("__mktime_internal", CurrFunc->GetFuncName()));
bool FuncFound = (0x41e6f0 == CurrFunc->GetFirstFuncAddr()); bool FuncFound = (0x424ea2 == CurrFunc->GetFirstFuncAddr());
if ((!changed || (IterationCounter > STARS_INTERPROCEDURAL_ITERATION_LIMIT)) && FuncFound) { if ((!changed || (IterationCounter > STARS_INTERPROCEDURAL_ITERATION_LIMIT)) && FuncFound) {
CurrFunc->Dump(); CurrFunc->Dump(false);
CurrFunc->DumpDotCFG(); CurrFunc->DumpDotCFG();
} }
#endif #endif
...@@ -1168,7 +1172,7 @@ bool SMPProgram::EmitProgramSPARKAda(void) { ...@@ -1168,7 +1172,7 @@ bool SMPProgram::EmitProgramSPARKAda(void) {
if (TempFunc == nullptr) continue; if (TempFunc == nullptr) continue;
bool FuncFound = (0x444492 == TempFunc->GetFirstFuncAddr()); bool FuncFound = (0x444492 == TempFunc->GetFirstFuncAddr());
if (FuncFound) { if (FuncFound) {
TempFunc->Dump(); TempFunc->Dump(false);
TempFunc->DumpDotCFG(); TempFunc->DumpDotCFG();
} }
...@@ -1209,7 +1213,7 @@ bool SMPProgram::EmitProgramSPARKAda(void) { ...@@ -1209,7 +1213,7 @@ bool SMPProgram::EmitProgramSPARKAda(void) {
if (TempFunc->HasGoodSSAForm()) { if (TempFunc->HasGoodSSAForm()) {
bool EdgeSuccess = TempFunc->ComputeEdgeExpressions(); bool EdgeSuccess = TempFunc->ComputeEdgeExpressions();
if (global_stars_interface->VerboseSPARKMode()) { if (global_stars_interface->VerboseSPARKMode()) {
TempFunc->Dump(); TempFunc->Dump(false);
} }
#if 0 #if 0
else { else {
...@@ -1328,14 +1332,15 @@ FuncType SMPProgram::RecurseAndMarkRetAdd(SMPFunction* FuncAttrib) { ...@@ -1328,14 +1332,15 @@ FuncType SMPProgram::RecurseAndMarkRetAdd(SMPFunction* FuncAttrib) {
for (size_t i = 0; i < CallTargets.size(); i++) { for (size_t i = 0; i < CallTargets.size(); i++) {
STARS_ea_t CallAddr = CallTargets[i]; STARS_ea_t CallAddr = CallTargets[i];
SMPFunction* ChildInstance = this->FindFunction(CallAddr); SMPFunction* ChildInstance = this->FindFunction(CallAddr);
if (!ChildInstance && (STARS_BADADDR != CallAddr)) { if (!ChildInstance && (STARS_BADADDR != CallAddr) && (!STARS_IsExternalFunc(CallAddr))) {
#if SMP_DEBUG_FUNC #if SMP_DEBUG_FUNC
// if a call target doesnt have a SMPFunction instance note it down // If a call target doesn't have a SMPFunction instance note it.
SMP_msg("ERROR: Function does not have SMPFunction instance at %llx from %s\n", SMP_msg("ERROR: Function does not have SMPFunction instance at %llx from %s\n",
(unsigned long long) CallAddr, FuncAttrib->GetFuncName()); (uint64_t) CallAddr, FuncAttrib->GetFuncName());
#endif #endif
continue;
} }
if (!ChildInstance)
continue;
UnsafeCallees |= (!ChildInstance->IsSafeCallee()); UnsafeCallees |= (!ChildInstance->IsSafeCallee());
UnsafeSpecCallees |= (!ChildInstance->IsSpecSafeCallee()); UnsafeSpecCallees |= (!ChildInstance->IsSpecSafeCallee());
switch (ChildInstance->GetReturnAddressStatus()) { switch (ChildInstance->GetReturnAddressStatus()) {
...@@ -1556,7 +1561,7 @@ void SMPProgram::Dump(void) { ...@@ -1556,7 +1561,7 @@ void SMPProgram::Dump(void) {
map<STARS_ea_t, SMPFunction *>::iterator FuncIter; map<STARS_ea_t, SMPFunction *>::iterator FuncIter;
for (FuncIter = this->FuncMap.begin(); FuncIter != this->FuncMap.end(); ++FuncIter) { for (FuncIter = this->FuncMap.begin(); FuncIter != this->FuncMap.end(); ++FuncIter) {
SMPFunction *TempFunc = FuncIter->second; SMPFunction *TempFunc = FuncIter->second;
TempFunc->Dump(); TempFunc->Dump(false);
} // end for all functions } // end for all functions
return; return;
} // end of SMPProgram::Dump() } // end of SMPProgram::Dump()
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
using namespace std; using namespace std;
#define SMP_DEBUG_DELAY 0 // for setting an early breakpoint #define SMP_DEBUG_DELAY 0 // for setting an early breakpoint
#define SMP_DELAY_TIME 25.0 // 25 seconds
// Set to 1 for debugging output // Set to 1 for debugging output
#define SMP_DEBUG 1 #define SMP_DEBUG 1
...@@ -380,11 +381,11 @@ bool idaapi IDAP_run(std::size_t arg) { ...@@ -380,11 +381,11 @@ bool idaapi IDAP_run(std::size_t arg) {
time_t current; time_t current;
time(&start); time(&start);
SMP_msg("delay for 15 seconds.\n"); SMP_msg("delay for 25 seconds.\n");
printf("delay for 15 seconds.\n"); printf("delay for 25 seconds.\n");
do { do {
time(&current); time(&current);
} while(difftime(current,start) < 15.0); } while(difftime(current,start) < SMP_DELAY_TIME);
#endif #endif
#if SMP_DEBUG #if SMP_DEBUG
......
This diff is collapsed.
...@@ -62,12 +62,12 @@ void STARS_IDA_Instruction_t::InitOperand(op_t &InitOp) const { ...@@ -62,12 +62,12 @@ void STARS_IDA_Instruction_t::InitOperand(op_t &InitOp) const {
InitOp.specflag4 = 0; InitOp.specflag4 = 0;
#else // not 0 #else // not 0
#if __GCC__ >= 8 #if __GNUC__ >= 8
#pragma GCC diagnostic ignored "-Wclass-memaccess" #pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif #endif
(void) memset(&InitOp, 0, sizeof(op_t)); (void) memset(&InitOp, 0, sizeof(op_t));
#if __GCC__ >= 8 #if __GNUC__ >= 8
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#endif #endif
#include <funcs.hpp> #include <funcs.hpp>
#include <segment.hpp> // for is_spec_ea()
#if (IDA_SDK_VERSION < 700) #if (IDA_SDK_VERSION < 700)
#include <area.hpp> #include <area.hpp>
...@@ -291,7 +292,13 @@ STARS_InstructionID_t STARS_IDA_Interface_t::FindFirstCallTarget(STARS_Instructi ...@@ -291,7 +292,13 @@ STARS_InstructionID_t STARS_IDA_Interface_t::FindFirstCallTarget(STARS_Instructi
} }
// We found a target, not the fall-through. // We found a target, not the fall-through.
CallTarget = xrefs.GetTo(); CallTarget = xrefs.GetTo();
SMP_msg("Found indirect call target %lx at %lx\n", (unsigned long) CallTarget, (unsigned long) CallInstAddr); if (::is_spec_ea(CallTarget)) {
// Call to external func, most likely. Signify with special address.
CallTarget = STARS_EXTERNAL_FUNC_ADDR;
}
else {
SMP_msg("Found indirect call target %llx at %llx\n", (uint64_t)CallTarget, (uint64_t)CallInstAddr);
}
break; break;
} }
} // end for all code xrefs } // end for all code xrefs
...@@ -510,6 +517,11 @@ bool STARS_IDA_Interface_t::AuditEHFunctionBoundaries(void) { ...@@ -510,6 +517,11 @@ bool STARS_IDA_Interface_t::AuditEHFunctionBoundaries(void) {
SMP_msg("ERROR: Failed to redefine IDA FuncBounds.\n"); SMP_msg("ERROR: Failed to redefine IDA FuncBounds.\n");
} }
} }
else if (nullptr == StartFunc) {
SMP_msg("INFO: FUNCBOUNDS: FDE range from %llx to %llx is orphan code.\n",
(uint64_t) CurrStartEA, (uint64_t) (CurrEndEA - 1));
ProblemFound = true;
}
} // end for (const auto FDEveciter : *FDEvecptr) } // end for (const auto FDEveciter : *FDEvecptr)
} }
catch(const std::exception& e) catch(const std::exception& e)
......
...@@ -2207,11 +2207,18 @@ inline uint32_t STARS_IRDB_Instruction_t::GetInitialInstFeatures(bool ShiftOpera ...@@ -2207,11 +2207,18 @@ inline uint32_t STARS_IRDB_Instruction_t::GetInitialInstFeatures(bool ShiftOpera
{ {
uint32_t my_features=0; uint32_t my_features=0;
#define STARS_DEBUG_IMM_OPERANDS 0
#if STARS_DEBUG_IMM_OPERANDS
#define CHECK_ARG(p_disasm,num,use,def) \
if (p_disasm.hasOperand(num) && (p_disasm.getOperand(num)->isRead() || p_disasm.getOperand(num)->isConstant())) my_features |= use; \
if (p_disasm.hasOperand(num) && (!p_disasm.getOperand(num)->isConstant()) && p_disasm.getOperand(num)->isWritten()) my_features |= def; \
#else
#define CHECK_ARG(p_disasm,num,use,def) \ #define CHECK_ARG(p_disasm,num,use,def) \
if(p_disasm.hasOperand(num) && p_disasm.getOperand(num)->isRead()) my_features|=use; \ if(p_disasm.hasOperand(num) && p_disasm.getOperand(num)->isRead()) my_features|=use; \
if(p_disasm.hasOperand(num) && p_disasm.getOperand(num)->isWritten()) my_features|=def; \ if(p_disasm.hasOperand(num) && p_disasm.getOperand(num)->isWritten()) my_features|=def; \
#endif
if (!ShiftOperands) { if (!ShiftOperands) {
CHECK_ARG(p_disasm, 0, STARS_CF_USE1, STARS_CF_CHG1); CHECK_ARG(p_disasm, 0, STARS_CF_USE1, STARS_CF_CHG1);
CHECK_ARG(p_disasm, 1, STARS_CF_USE2, STARS_CF_CHG2); CHECK_ARG(p_disasm, 1, STARS_CF_USE2, STARS_CF_CHG2);
...@@ -2734,7 +2741,7 @@ bool STARS_IRDB_Instruction_t::STARS_GetCmd(void) ...@@ -2734,7 +2741,7 @@ bool STARS_IRDB_Instruction_t::STARS_GetCmd(void)
if(my_disasm.hasOperand(i)) if(my_disasm.hasOperand(i))
Operands[i]=(std::make_shared<STARS_IRDB_op_t>(my_disasm,0,my_disasm.getOperand(i),length)); Operands[i]=(std::make_shared<STARS_IRDB_op_t>(my_disasm,0,my_disasm.getOperand(i),length));
} }
features=GetInitialInstFeatures(false,my_disasm); this->features = GetInitialInstFeatures(false,my_disasm);
} }
// Simplify the operand encoding so that identical operands don't appear to be different. // Simplify the operand encoding so that identical operands don't appear to be different.
...@@ -2742,6 +2749,35 @@ bool STARS_IRDB_Instruction_t::STARS_GetCmd(void) ...@@ -2742,6 +2749,35 @@ bool STARS_IRDB_Instruction_t::STARS_GetCmd(void)
this->GetOpnd(i)->CleanOpndEncoding(); this->GetOpnd(i)->CleanOpndEncoding();
} }
// Correct disasm errors by ensuring that an immediate operand is not a DEF.
bool DefFound = false;
bool DefFixed = false;
uint64_t InstAddr = (uint64_t)(this->GetID().GetIDWithinFile());
for (std::size_t i = 0; i < STARS_UA_MAXOP; ++i) {
if (nullptr != this->GetOpnd(i)) {
bool DefOperand = this->IsDefOpnd(i);
if (this->GetOpnd(i)->IsImmedOp()) {
if (DefOperand) {
SMP_msg("DEBUG: DISASM ERROR: Operand number %zu is immediate DEF at %llx. Changing to READ-only.\n",
i, InstAddr);
this->features &= (~DefMacros[i]); // unset only the DEF bit in the features.
DefFixed = true;
}
}
else if (DefOperand) {
DefFound = true;
}
}
} // end for all operands
if (DefFixed) {
if (DefFound) { // DEF other than immediate was found
SMP_msg("DEBUG: DISASM ERROR: Inst had good DEF and immediate DEF at %llx.\n", InstAddr);
}
else {
SMP_msg("DEBUG: DISASM ERROR: Only DEF was an immediate DEF at %llx.\n", InstAddr);
}
}
return length > 0; return length > 0;
} }
......