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 (18)
Showing
with 762 additions and 327 deletions
...@@ -712,6 +712,7 @@ extern DisAsmString DisAsmText; ...@@ -712,6 +712,7 @@ extern DisAsmString DisAsmText;
#define DEFORUSE_RESET_UNUSED5 0xbf #define DEFORUSE_RESET_UNUSED5 0xbf
#define DEFORUSE_RESET_UNUSED6 0x7f #define DEFORUSE_RESET_UNUSED6 0x7f
#pragma pack(1)
class DefOrUse { class DefOrUse {
public: public:
// Constructors // Constructors
...@@ -764,6 +765,7 @@ private: ...@@ -764,6 +765,7 @@ private:
bool GloballyLoopInvariant; // DEF is not variant in any loop bool GloballyLoopInvariant; // DEF is not variant in any loop
#endif #endif
}; // end of class DefOrUse }; // end of class DefOrUse
#pragma pack() // back to normal packing
// Comparison operator class to permit use of DefOrUse type in sets. // Comparison operator class to permit use of DefOrUse type in sets.
class LessDefUse { class LessDefUse {
......
...@@ -886,6 +886,7 @@ private: ...@@ -886,6 +886,7 @@ private:
STARSBufferCallArgMap BufferCallConstBufferArgsMap; // list of (bufptrargpos, bufsize) indexed by CallAddr STARSBufferCallArgMap BufferCallConstBufferArgsMap; // list of (bufptrargpos, bufsize) indexed by CallAddr
// Methods // Methods
void DestroyLoopExprs(void); // release loop-based symbolic memory access expressions
void EraseInstRange(STARS_ea_t FirstAddr, STARS_ea_t LastAddr); void EraseInstRange(STARS_ea_t FirstAddr, STARS_ea_t LastAddr);
void SetLinks(void); // Link basic blocks and map instructions to blocks void SetLinks(void); // Link basic blocks and map instructions to blocks
bool FindDistantCodeFragment(STARS_ea_t TargetAddr); // Is TargetAddr the start of a code fragment that belongs to this func, not a separate func? bool FindDistantCodeFragment(STARS_ea_t TargetAddr); // Is TargetAddr the start of a code fragment that belongs to this func, not a separate func?
......
...@@ -464,6 +464,7 @@ public: ...@@ -464,6 +464,7 @@ public:
void ListInArgRegsUsed(std::bitset<1 + MD_LAST_REG_NO> &RegNums); // list incoming argument register numbers encountered (SSA #0 in an InArg reg) void ListInArgRegsUsed(std::bitset<1 + MD_LAST_REG_NO> &RegNums); // list incoming argument register numbers encountered (SSA #0 in an InArg reg)
bool IsStackPtrOffset(const STARS_sval_t CurrentStackPtrOffset, STARS_sval_t &FinalStackPtrOffset) const; // If expr is SP+offset, add offset to Current to get Final bool IsStackPtrOffset(const STARS_sval_t CurrentStackPtrOffset, STARS_sval_t &FinalStackPtrOffset) const; // If expr is SP+offset, add offset to Current to get Final
void SubstituteSSANum(SMPInstr *CallInst, const int NewSSANum, const STARSOpndTypePtr &InArgOp); // Find all uses of InArgOp, SSANum == 0, and give it NewSSANum; replace all ParentInsts with CallInst void SubstituteSSANum(SMPInstr *CallInst, const int NewSSANum, const STARSOpndTypePtr &InArgOp); // Find all uses of InArgOp, SSANum == 0, and give it NewSSANum; replace all ParentInsts with CallInst
bool SubstituteGlobalRangeValues(const bool InitCase); // Use MinVal if InitCase, MaxVal otherwise for global vars in expression
STARSOpndTypePtr FindLeftPreLoopDefOp(void) const; // For loop exprs, find the DefOp at LeftPreLoopDefAddr STARSOpndTypePtr FindLeftPreLoopDefOp(void) const; // For loop exprs, find the DefOp at LeftPreLoopDefAddr
bool AreAllRegsLoopInvariant(void) const; // Detect loop-invariant exprs, which can occur inside loops. bool AreAllRegsLoopInvariant(void) const; // Detect loop-invariant exprs, which can occur inside loops.
void SplitMemoryRangeExpr(bool PositiveIncrement, STARSExpression *&InitExpr, STARSExpression *&LimitExpr); // If this is a relational range expr, produce the lower and limit exprs void SplitMemoryRangeExpr(bool PositiveIncrement, STARSExpression *&InitExpr, STARSExpression *&LimitExpr); // If this is a relational range expr, produce the lower and limit exprs
......
...@@ -101,6 +101,12 @@ struct GlobalVar { ...@@ -101,6 +101,12 @@ struct GlobalVar {
std::set<std::pair<std::size_t, bool>, LessOff> FieldOffsets; // bool = accessed through index register by any instruction? std::set<std::pair<std::size_t, bool>, LessOff> FieldOffsets; // bool = accessed through index register by any instruction?
}; };
// For tracking the minimum and maximum values seen that were written to a global var.
struct STARSValueRange {
STARS_uval_t MinVal;
STARS_uval_t MaxVal;
};
class LtStr { class LtStr {
public: public:
bool operator() (const char* c1, const char* c2) const { bool operator() (const char* c1, const char* c2) const {
...@@ -124,6 +130,9 @@ public: ...@@ -124,6 +130,9 @@ public:
inline std::map<std::string, STARS_ea_t>::iterator GetLastGlobalName(void) { inline std::map<std::string, STARS_ea_t>::iterator GetLastGlobalName(void) {
return GlobalNameMap.end(); return GlobalNameMap.end();
} }
// Methods for recovering min or max value seen directly written to a global var.
bool FindGlobalMinValue(const STARS_ea_t GlobalAddr, STARS_uval_t &MinValue) const;
bool FindGlobalMaxValue(const STARS_ea_t GlobalAddr, STARS_uval_t &MaxValue) const;
inline ProfilerInformation *GetProfInfo(void) { return ProfInfo; }; inline ProfilerInformation *GetProfInfo(void) { return ProfInfo; };
SMPFunction* FindFunction(STARS_ea_t FirstAddr) const; // get function from first addr in function SMPFunction* FindFunction(STARS_ea_t FirstAddr) const; // get function from first addr in function
SMPFunction* FindFunctionAndBlockFromInstID(const STARS_ea_t AnyInstID, int &BlockNum) const; // get function and block # for any instruction ID, not just first ID SMPFunction* FindFunctionAndBlockFromInstID(const STARS_ea_t AnyInstID, int &BlockNum) const; // get function and block # for any instruction ID, not just first ID
...@@ -140,7 +149,8 @@ public: ...@@ -140,7 +149,8 @@ public:
void SetProgramThrowsExceptions(void); // Record detection of __cxa_throw in the binary void SetProgramThrowsExceptions(void); // Record detection of __cxa_throw in the binary
void AddBlockToRemovalList(SMPBasicBlock *UnreachableBlock); // Add block, e.g. with "call 0" instruction, to later removal list. void AddBlockToRemovalList(SMPBasicBlock *UnreachableBlock); // Add block, e.g. with "call 0" instruction, to later removal list.
std::pair<std::map<std::string, STARS_ea_t>::iterator, bool> InsertGlobalNameAddrMapEntry(std::pair<std::string, STARS_ea_t> TempPair) { return GlobalNameMap.insert(TempPair); }; std::pair<std::map<std::string, STARS_ea_t>::iterator, bool> InsertGlobalNameAddrMapEntry(std::pair<std::string, STARS_ea_t> TempPair) { return GlobalNameMap.insert(TempPair); };
void InsertGlobalVarTableEntry(std::pair<STARS_ea_t, struct GlobalVar> VarItem) { GlobalVarTable.insert(VarItem); }; inline void InsertGlobalVarTableEntry(std::pair<STARS_ea_t, struct GlobalVar> VarItem) { GlobalVarTable.insert(VarItem); };
void InsertGlobalVarMinMaxValue(const STARS_ea_t GlobalAddr, const STARS_uval_t ValueSeen); // Update min or max value seen if needed
inline std::pair<std::set<std::string>::iterator, bool> InsertLibraryFuncName(std::string FuncName) { return LibraryCallTargetNames.insert(FuncName); }; inline std::pair<std::set<std::string>::iterator, bool> InsertLibraryFuncName(std::string FuncName) { return LibraryCallTargetNames.insert(FuncName); };
// Query methods // Query methods
...@@ -175,6 +185,7 @@ private: ...@@ -175,6 +185,7 @@ private:
std::list<SMPFunction *> PrioritizedFuncList; // Functions in bottom-up call-graph analysis order std::list<SMPFunction *> PrioritizedFuncList; // Functions in bottom-up call-graph analysis order
std::map<STARS_ea_t, struct GlobalVar> GlobalVarTable; // all global static variables std::map<STARS_ea_t, struct GlobalVar> GlobalVarTable; // all global static variables
std::map<std::string, STARS_ea_t> GlobalNameMap; // map global name to address std::map<std::string, STARS_ea_t> GlobalNameMap; // map global name to address
std::map<STARS_ea_t, struct STARSValueRange> GlobalValueRangeMap; // map global addr to min/max values directly written to it
std::list<std::pair<STARS_ea_t, SMPFunction *> > FuncList; // FuncMap entries prioritized in desired order for analysis std::list<std::pair<STARS_ea_t, SMPFunction *> > FuncList; // FuncMap entries prioritized in desired order for analysis
std::set<STARS_ea_t> UnsharedFragments; // Code fragments incorporated into their callers; remove from FuncMaps std::set<STARS_ea_t> UnsharedFragments; // Code fragments incorporated into their callers; remove from FuncMaps
std::set<STARS_ea_t> DataToCodeXrefTargets; // Code targets of data xrefs; probably will be called indirectly std::set<STARS_ea_t> DataToCodeXrefTargets; // Code targets of data xrefs; probably will be called indirectly
...@@ -189,7 +200,6 @@ private: ...@@ -189,7 +200,6 @@ private:
// Methods // Methods
void InitStaticDataTable(void); // Gather info about global static data locations void InitStaticDataTable(void); // Gather info about global static data locations
void ComputeGlobalFieldOffsets(struct GlobalVar &CurrGlobal);
FuncType RecurseAndMarkRetAdd(SMPFunction *); FuncType RecurseAndMarkRetAdd(SMPFunction *);
void ProcessExceptionHandlingFileSections(void); // If exception throwing code is detected, mark exception-handling functions as unsafe for fast returns. void ProcessExceptionHandlingFileSections(void); // If exception throwing code is detected, mark exception-handling functions as unsafe for fast returns.
void ResetFuncsProcessed(void); // set all funcs to not processed before a whole program analysis void ResetFuncsProcessed(void); // set all funcs to not processed before a whole program analysis
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <assert.h> #include <assert.h>
#include <map> #include <map>
#include <iostream>
#include "interfaces/STARSTypes.h" #include "interfaces/STARSTypes.h"
#include "interfaces/SMPDBInterface.h" #include "interfaces/SMPDBInterface.h"
...@@ -20,9 +21,15 @@ class STARS_Instruction_t ...@@ -20,9 +21,15 @@ class STARS_Instruction_t
// Constructors and destructors // Constructors and destructors
STARS_Instruction_t(const STARS_InstructionID_t& p_id) : m_id(p_id) STARS_Instruction_t(const STARS_InstructionID_t& p_id) : m_id(p_id)
{ p_id.AddIDToInsnMapping(this);} {
objects_created++;
p_id.AddIDToInsnMapping(this);
}
virtual ~STARS_Instruction_t(){} virtual ~STARS_Instruction_t()
{
objects_destroyed++;
}
// Data initialization methods // Data initialization methods
virtual bool STARS_GetCmd(void) = 0; virtual bool STARS_GetCmd(void) = 0;
...@@ -83,9 +90,21 @@ class STARS_Instruction_t ...@@ -83,9 +90,21 @@ class STARS_Instruction_t
virtual void Dump() { } ; virtual void Dump() { } ;
static void DumpCreationStats(std::ostream & out)
{
out<<"#ATTRIBUTE STARS_Instruction_t_created: "<<std::dec<<objects_created<<std::endl;
out<<"#ATTRIBUTE STARS_Instruction_t_destroyed: "<<std::dec<<objects_destroyed<<std::endl;
out<<"#ATTRIBUTE STARS_Instruction_t_current : "<<std::dec<<objects_created-objects_destroyed<<std::endl;
}
protected: protected:
STARS_InstructionID_t m_id; STARS_InstructionID_t m_id;
private:
static uint64_t objects_created;
static uint64_t objects_destroyed;
}; };
#endif #endif
......
...@@ -12,8 +12,14 @@ class STARS_op_t ...@@ -12,8 +12,14 @@ class STARS_op_t
public: public:
// Constructors // Constructors
STARS_op_t() = default; STARS_op_t()
virtual ~STARS_op_t() = default; {
objects_created++;
}
virtual ~STARS_op_t()
{
objects_destroyed++;
}
// Clone method (deep copy). // Clone method (deep copy).
virtual STARSOpndTypePtr clone(void) const = 0; virtual STARSOpndTypePtr clone(void) const = 0;
...@@ -78,6 +84,18 @@ class STARS_op_t ...@@ -78,6 +84,18 @@ class STARS_op_t
// Printing methods. // Printing methods.
virtual void Dump() { } virtual void Dump() { }
static void DumpCreationStats(std::ostream & out)
{
out<<"#ATTRIBUTE STARS_op_t_created: "<<std::dec<<objects_created<<std::endl;
out<<"#ATTRIBUTE STARS_op_t_destroyed: "<<std::dec<<objects_destroyed<<std::endl;
out<<"#ATTRIBUTE STARS_op_t_current : "<<std::dec<<objects_created-objects_destroyed<<std::endl;
}
private:
static uint64_t objects_created;
static uint64_t objects_destroyed;
}; };
......
...@@ -16,8 +16,61 @@ class SMPInstr; ...@@ -16,8 +16,61 @@ class SMPInstr;
extern STARS_Interface_t* global_stars_interface; extern STARS_Interface_t* global_stars_interface;
#pragma pack(1)
class STARS_IRDB_Instruction_t : public STARS_Instruction_t class STARS_IRDB_Instruction_t : public STARS_Instruction_t
{ {
private:
class DecodedInstructionMicro_t
{
public:
DecodedInstructionMicro_t(const libIRDB::virtual_offset_t addr, const void* bits, const uint32_t length)
{
const auto disasm=libIRDB::DecodedInstruction_t(addr, bits,length);
init(disasm);
}
DecodedInstructionMicro_t(const libIRDB::Instruction_t* irdb_insn)
{
const auto disasm=libIRDB::DecodedInstruction_t(irdb_insn);
init(disasm);
}
bool hasRelevantRepnePrefix() const { return m_hasRelevantRepnePrefix;}
bool hasRelevantRepPrefix() const { return m_hasRelevantRepPrefix;}
bool hasRelevantOperandSizePrefix() const { return m_hasRelevantOperandSizePrefix;}
bool hasRexWPrefix() const { return m_hasRexWPrefix;}
bool hasImplicitlyModifiedRegs() const { return m_hasImplicitlyModifiedRegs;}
bool isUnconditionalBranch() const { return m_isUnconditionalBranch;}
bool isCall() const { return m_isCall;}
uint32_t length() const { return m_length;}
libIRDB::virtual_offset_t getAddress() const { return m_getAddress; }
const std::string& getMnemonic() const { return m_getMnemonic; }
private:
bool m_hasRelevantRepnePrefix:1;
bool m_hasRelevantRepPrefix:1;
bool m_hasRelevantOperandSizePrefix:1;
bool m_hasRexWPrefix:1;
bool m_hasImplicitlyModifiedRegs:1;
bool m_isUnconditionalBranch:1;
bool m_isCall:1;
uint32_t m_length:6;
libIRDB::virtual_offset_t m_getAddress;
std::string m_getMnemonic;
private:
void init(const libIRDB::DecodedInstruction_t& disasm)
{
m_hasRelevantRepnePrefix=disasm.hasRelevantRepnePrefix();
m_hasRelevantRepPrefix=disasm.hasRelevantRepPrefix();
m_hasRelevantOperandSizePrefix=disasm.hasRelevantOperandSizePrefix();
m_hasRexWPrefix=disasm.hasRexWPrefix();
m_hasImplicitlyModifiedRegs=disasm.hasImplicitlyModifiedRegs();
m_getMnemonic=disasm.getMnemonic();
m_isUnconditionalBranch=disasm.isUnconditionalBranch();
m_isCall=disasm.isCall();
m_length=disasm.length();
m_getAddress=disasm.getAddress();
}
};
public: public:
// create SSA marker // create SSA marker
...@@ -42,8 +95,10 @@ class STARS_IRDB_Instruction_t : public STARS_Instruction_t ...@@ -42,8 +95,10 @@ class STARS_IRDB_Instruction_t : public STARS_Instruction_t
{ {
assert(irdb_insn); assert(irdb_insn);
IDAOpcodeCached = false; IDAOpcodeCached = false;
#if 0 // Redundant; called from SMPInstr::Analyze()
bool res=STARS_GetCmd(); bool res=STARS_GetCmd();
assert(res); assert(res);
#endif
} }
virtual ~STARS_IRDB_Instruction_t() {} virtual ~STARS_IRDB_Instruction_t() {}
...@@ -71,7 +126,7 @@ class STARS_IRDB_Instruction_t : public STARS_Instruction_t ...@@ -71,7 +126,7 @@ class STARS_IRDB_Instruction_t : public STARS_Instruction_t
// add rax, rdx (intel) means rax=rax+rdx; // add rax, rdx (intel) means rax=rax+rdx;
// features = STARS_CF_USE1 | STARS_CF_USE2 | STARS_CF_CHG1 // features = STARS_CF_USE1 | STARS_CF_USE2 | STARS_CF_CHG1
virtual uint32_t GetInstFeatures(void) const { return features; } virtual uint32_t GetInstFeatures(void) const { return features; }
virtual uint32_t GetInitialInstFeatures(bool ShiftOperands = false) const; virtual uint32_t GetInitialInstFeatures(bool ShiftOperands, const libIRDB::DecodedInstruction_t& p_disasm) const;
// jdh: consider returning by reference? // jdh: consider returning by reference?
virtual STARSOpndTypePtr GetOpnd(std::size_t OpndNum) const virtual STARSOpndTypePtr GetOpnd(std::size_t OpndNum) const
...@@ -213,9 +268,12 @@ class STARS_IRDB_Instruction_t : public STARS_Instruction_t ...@@ -213,9 +268,12 @@ class STARS_IRDB_Instruction_t : public STARS_Instruction_t
// useful for other IRDB classes. // useful for other IRDB classes.
virtual const libIRDB::Instruction_t* GetIRDBInstruction() const { return irdb_insn;} virtual const libIRDB::Instruction_t* GetIRDBInstruction() const { return irdb_insn;}
protected:
static STARSOpndTypePtr VoidOpndsPtr; // common pointer to a void operand for all operands not used, to save memory
private: private:
const libIRDB::Instruction_t* irdb_insn; const libIRDB::Instruction_t* irdb_insn;
libIRDB::DecodedInstruction_t disasm; DecodedInstructionMicro_t disasm;
std::vector<STARSOpndTypePtr> Operands; std::vector<STARSOpndTypePtr> Operands;
uint32_t features; uint32_t features;
uint16_t IDAOpcode; // cached result from GetIDAOpcode() uint16_t IDAOpcode; // cached result from GetIDAOpcode()
...@@ -223,6 +281,7 @@ class STARS_IRDB_Instruction_t : public STARS_Instruction_t ...@@ -223,6 +281,7 @@ class STARS_IRDB_Instruction_t : public STARS_Instruction_t
std::size_t DetermineRegByteWidth(STARS_regnum_t RegNum); // Based on RegNum, determine byte width to set for new operand. std::size_t DetermineRegByteWidth(STARS_regnum_t RegNum); // Based on RegNum, determine byte width to set for new operand.
}; };
#pragma pack()
#endif #endif
......
...@@ -15,6 +15,7 @@ class STARS_IRDB_op_t; ...@@ -15,6 +15,7 @@ class STARS_IRDB_op_t;
// to help easy porting if this ever changes. // to help easy porting if this ever changes.
typedef std::shared_ptr<STARS_IRDB_op_t> STARSIRDBOpndTypePtr; typedef std::shared_ptr<STARS_IRDB_op_t> STARSIRDBOpndTypePtr;
#pragma pack(1)
class STARS_IRDB_op_t : public STARS_op_t class STARS_IRDB_op_t : public STARS_op_t
{ {
public: public:
...@@ -98,6 +99,14 @@ class STARS_IRDB_op_t : public STARS_op_t ...@@ -98,6 +99,14 @@ class STARS_IRDB_op_t : public STARS_op_t
switch(OpType) switch(OpType)
{ {
case op_Reg: case op_Reg:
case op_CrReg:
case op_DrReg:
case op_Eflags:
case op_MMXReg:
case op_XMMReg:
case op_YMMReg:
case op_FPReg:
case op_Mxcsr:
return operand.reg.RegNum; return operand.reg.RegNum;
case op_Mem: case op_Mem:
return operand.mem.base; return operand.mem.base;
...@@ -182,14 +191,10 @@ class STARS_IRDB_op_t : public STARS_op_t ...@@ -182,14 +191,10 @@ class STARS_IRDB_op_t : public STARS_op_t
virtual bool IsMemNoDisplacementOp(void) const { return OpType==op_Mem && operand.mem.disp==0; } virtual bool IsMemNoDisplacementOp(void) const { return OpType==op_Mem && operand.mem.disp==0; }
virtual bool IsMemOp(void) const { return OpType==op_Mem; } virtual bool IsMemOp(void) const { return OpType==op_Mem; }
virtual bool HasSIBByte(void) const { assert(OpType==op_Mem); return operand.mem.hasSIB; } virtual bool HasSIBByte(void) const { assert(OpType==op_Mem); return operand.mem.hasSIB; }
virtual bool IsFloatingPointRegOp(void) const virtual bool IsFloatingPointRegOp(void) const { return (OpType == op_FPReg); }
{ if(OpType!=op_Reg) return false; return STARS_x86_R_st0<= operand.reg.RegNum && operand.reg.RegNum<=STARS_x86_R_st7; } virtual bool IsMMXRegOp(void) const { return (OpType == op_MMXReg); }
virtual bool IsMMXRegOp(void) const virtual bool IsXMMRegOp(void) const { return (OpType == op_XMMReg); }
{ if(OpType!=op_Reg) return false; return STARS_x86_R_mm0<= operand.reg.RegNum && operand.reg.RegNum<=STARS_x86_R_mm7; } virtual bool IsYMMRegOp(void) const { return (OpType == op_YMMReg); }
virtual bool IsXMMRegOp(void) const
{ if(OpType!=op_Reg) return false; return STARS_x86_R_xmm0<= operand.reg.RegNum && operand.reg.RegNum<=STARS_x86_R_xmm15; }
virtual bool IsYMMRegOp(void) const
{ if(OpType!=op_Reg) return false; return STARS_x86_R_ymm0<= operand.reg.RegNum && operand.reg.RegNum<=STARS_x86_R_ymm15; }
virtual bool IsTestRegOp(void) const { return false; } virtual bool IsTestRegOp(void) const { return false; }
virtual bool IsDebugRegOp(void) const { return false; } virtual bool IsDebugRegOp(void) const { return false; }
virtual bool IsControlRegOp(void) const { return false; } virtual bool IsControlRegOp(void) const { return false; }
...@@ -242,11 +247,6 @@ class STARS_IRDB_op_t : public STARS_op_t ...@@ -242,11 +247,6 @@ class STARS_IRDB_op_t : public STARS_op_t
private: private:
// what's the global_index for Get/SetOpGlobalIndex // what's the global_index for Get/SetOpGlobalIndex
std::size_t global_index; std::size_t global_index;
STARS_RegNo SegReg;
int byteWidth;
enum OperandType_t { op_Void, op_Reg, op_Mem, op_Imm, op_CrReg, op_DrReg, op_Eflags, op_MMXReg, op_XMMReg, op_YMMReg, op_FPReg, op_Mxcsr, op_SegReg, op_Addr } OpType;
union union
{ {
struct struct
...@@ -257,8 +257,8 @@ class STARS_IRDB_op_t : public STARS_op_t ...@@ -257,8 +257,8 @@ class STARS_IRDB_op_t : public STARS_op_t
{ {
STARS_RegNo base; STARS_RegNo base;
STARS_RegNo index; STARS_RegNo index;
unsigned int scale:4; // can take values 0, 1, 2, 4, 8.
libIRDB::virtual_offset_t disp; // may be 64-bit imm in some x86-64 instructions. libIRDB::virtual_offset_t disp; // may be 64-bit imm in some x86-64 instructions.
unsigned int scale:4; // can take values 0, 1, 2, 4, 8.
bool hasSIB:1; bool hasSIB:1;
} mem; } mem;
struct struct
...@@ -273,24 +273,17 @@ class STARS_IRDB_op_t : public STARS_op_t ...@@ -273,24 +273,17 @@ class STARS_IRDB_op_t : public STARS_op_t
} operand; } operand;
bool visible; enum OperandType_t { op_Void, op_Reg, op_Mem, op_Imm, op_CrReg, op_DrReg, op_Eflags, op_MMXReg, op_XMMReg, op_YMMReg, op_FPReg, op_Mxcsr, op_SegReg, op_Addr } OpType;
STARS_RegNo SegReg;
uint32_t byteWidth:6;
void Init() bool visible:1;
{
SegReg=STARS_x86_R_none;
OpType=op_Void;
// init the operand to 0, because the it should have no semantically valid meaning in any sense anyhow if OpType==Void.
memset(&operand,0,sizeof(operand));
visible=0; void Init(void);
byteWidth=0;
}
virtual void Dump(); virtual void Dump();
}; };
#pragma pack()
#endif #endif
......
...@@ -778,15 +778,48 @@ list<SMPBasicBlock *>::const_iterator SMPBasicBlock::GetFallThroughSucc(void) co ...@@ -778,15 +778,48 @@ list<SMPBasicBlock *>::const_iterator SMPBasicBlock::GetFallThroughSucc(void) co
if ((JUMP != LastDataFlow) && (INDIR_JUMP != LastDataFlow) && (RETURN != LastDataFlow) && (HALT != LastDataFlow) && (!LastInst->IsFixedCallJump())) { if ((JUMP != LastDataFlow) && (INDIR_JUMP != LastDataFlow) && (RETURN != LastDataFlow) && (HALT != LastDataFlow) && (!LastInst->IsFixedCallJump())) {
// Block has fall-through. // Block has fall-through.
STARS_InstructionID_t NextInstID = LastInst->GetInstID().GetInstruction()->GetNextInstructionID(); STARS_ea_t FallThroughSuccAddr = STARS_BADADDR;
STARS_ea_t FallThroughSuccAddr = NextInstID.GetIDWithinFile(); #if 0
for (list<SMPBasicBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) { bool ValidLastInst = ((nullptr != LastInst) && (nullptr != LastInst->GetInstID().GetInstruction()));
STARS_ea_t FirstSuccAddr = (*SuccIter)->GetFirstAddr(); if (ValidLastInst) {
if (FirstSuccAddr == FallThroughSuccAddr) { // found fall-through STARS_InstructionID_t NextInstID = LastInst->GetInstID().GetInstruction()->GetNextInstructionID();
FallThroughSuccIter = SuccIter; FallThroughSuccAddr = NextInstID.GetIDWithinFile();
break; for (list<SMPBasicBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) {
STARS_ea_t FirstSuccAddr = (*SuccIter)->GetFirstAddr();
if (FirstSuccAddr == FallThroughSuccAddr) { // found fall-through
FallThroughSuccIter = SuccIter;
break;
}
}
}
#else
if (COND_BRANCH == LastDataFlow) {
STARS_ea_t NonFallThroughAddr = LastInst->GetJumpTarget();
assert(STARS_BADADDR != NonFallThroughAddr);
for (list<SMPBasicBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) {
SMPBasicBlock *SuccBlock = (*SuccIter);
if (SuccBlock->GetFirstAddr() != NonFallThroughAddr) {
FallThroughSuccIter = SuccIter;
break;
}
} }
} }
else {
assert((DEFAULT == LastDataFlow) || (CALL == LastDataFlow) || (INDIR_CALL == LastDataFlow));
if (1 >= this->GetNumSuccessors())
FallThroughSuccIter = this->GetFirstConstSucc();
else { // computed call or indir_call targets
STARS_ea_t FallThroughAddr = LastInst->GetFallThroughAddr();
for (list<SMPBasicBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) {
SMPBasicBlock *SuccBlock = (*SuccIter);
if (SuccBlock->GetFirstAddr() == FallThroughAddr) {
FallThroughSuccIter = SuccIter;
break;
}
}
}
}
#endif
} }
return FallThroughSuccIter; return FallThroughSuccIter;
...@@ -798,12 +831,13 @@ list<SMPBasicBlock *>::const_iterator SMPBasicBlock::GetCondNonFallThroughSucc(v ...@@ -798,12 +831,13 @@ list<SMPBasicBlock *>::const_iterator SMPBasicBlock::GetCondNonFallThroughSucc(v
vector<SMPInstr *>::const_reverse_iterator LastInstIter = this->GetRevInstCBegin(); vector<SMPInstr *>::const_reverse_iterator LastInstIter = this->GetRevInstCBegin();
SMPInstr *LastInst = (*LastInstIter); SMPInstr *LastInst = (*LastInstIter);
SMPitype LastDataFlow = LastInst->GetDataFlowType(); SMPitype LastDataFlow = LastInst->GetDataFlowType();
if (COND_BRANCH == LastDataFlow) { if (COND_BRANCH == LastDataFlow) {
STARS_InstructionID_t NextInstID = LastInst->GetInstID().GetInstruction()->GetNextInstructionID(); STARS_ea_t NonFallThroughAddr = LastInst->GetJumpTarget();
STARS_ea_t FallThroughSuccAddr = NextInstID.GetIDWithinFile(); assert(STARS_BADADDR != NonFallThroughAddr);
for (list<SMPBasicBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) { for (list<SMPBasicBlock *>::const_iterator SuccIter = this->GetFirstConstSucc(); SuccIter != this->GetLastConstSucc(); ++SuccIter) {
STARS_ea_t FirstSuccAddr = (*SuccIter)->GetFirstAddr(); SMPBasicBlock *SuccBlock = (*SuccIter);
if (FirstSuccAddr != FallThroughSuccAddr) { // found non-fall-through if (SuccBlock->GetFirstAddr() == NonFallThroughAddr) {
BranchTakenSuccIter = SuccIter; BranchTakenSuccIter = SuccIter;
break; break;
} }
...@@ -1528,6 +1562,7 @@ STARS_ea_t SMPBasicBlock::GetUltimateDefAddr(const STARSOpndTypePtr &UseOp, STAR ...@@ -1528,6 +1562,7 @@ STARS_ea_t SMPBasicBlock::GetUltimateDefAddr(const STARSOpndTypePtr &UseOp, STAR
SMPInstr *CurrInst = this->GetFunc()->GetInstFromAddr(DefAddr); SMPInstr *CurrInst = this->GetFunc()->GetInstFromAddr(DefAddr);
assert(NULL != CurrInst); assert(NULL != CurrInst);
bool NewDefMoveOp = false; bool NewDefMoveOp = false;
#if 0
if (CurrInst->MDIsMoveInstr()) { if (CurrInst->MDIsMoveInstr()) {
DefMoveOp = CurrInst->GetMoveSource(); DefMoveOp = CurrInst->GetMoveSource();
DefMoveOp = CloneIfNecessary(DefMoveOp, this->GetFunc()->UsesFramePointer()); DefMoveOp = CloneIfNecessary(DefMoveOp, this->GetFunc()->UsesFramePointer());
...@@ -1543,6 +1578,9 @@ STARS_ea_t SMPBasicBlock::GetUltimateDefAddr(const STARSOpndTypePtr &UseOp, STAR ...@@ -1543,6 +1578,9 @@ STARS_ea_t SMPBasicBlock::GetUltimateDefAddr(const STARSOpndTypePtr &UseOp, STAR
DefMoveOp = CurrInst->MakeRegOpnd(LeaAddrReg); // convert to RegOp DefMoveOp = CurrInst->MakeRegOpnd(LeaAddrReg); // convert to RegOp
} }
} }
#else
NewDefMoveOp = CurrInst->IsSimpleCopy(DefMoveOp);
#endif
// We recurse if the DefMoveOp is a non-stack-ptr-reg, including the LeaMemUseOp being // We recurse if the DefMoveOp is a non-stack-ptr-reg, including the LeaMemUseOp being
// a single register (e.g. base but no index: lea ebx,[edx] is just a move in disguise) // a single register (e.g. base but no index: lea ebx,[edx] is just a move in disguise)
bool ValidOperand = NewDefMoveOp && ((DefMoveOp->IsRegOp() && (!MDIsStackPtrReg(DefMoveOp->GetReg(), UseFP))) bool ValidOperand = NewDefMoveOp && ((DefMoveOp->IsRegOp() && (!MDIsStackPtrReg(DefMoveOp->GetReg(), UseFP)))
......
This diff is collapsed.
...@@ -2219,10 +2219,25 @@ STARSExpression::STARSExpression(const STARSDefUseIter Ref, SMPInstr *CurrInst) ...@@ -2219,10 +2219,25 @@ STARSExpression::STARSExpression(const STARSDefUseIter Ref, SMPInstr *CurrInst)
   
// Destructor // Destructor
STARSExpression::~STARSExpression() { STARSExpression::~STARSExpression() {
if (this->HasRightSubTree() && (nullptr != this->RightExpr)) #if 1
if (this->HasRightSubTree() && (nullptr != this->RightExpr)) {
delete this->RightExpr; delete this->RightExpr;
if (this->HasLeftSubTree() && (nullptr != this->LeftExpr)) this->RightExpr = nullptr;
}
if (this->HasLeftSubTree() && (nullptr != this->LeftExpr)) {
delete this->LeftExpr; delete this->LeftExpr;
this->LeftExpr = nullptr;
}
#else
if (nullptr != this->RightExpr) {
delete this->RightExpr;
this->RightExpr = nullptr;
}
if (nullptr != this->LeftExpr) {
delete this->LeftExpr;
this->LeftExpr = nullptr;
}
#endif
return; return;
} }
   
...@@ -3398,8 +3413,19 @@ bool STARSExpression::SimplifyExpr(STARSExpression *ParentExpr) { ...@@ -3398,8 +3413,19 @@ bool STARSExpression::SimplifyExpr(STARSExpression *ParentExpr) {
if (ConstLeftOperand) { if (ConstLeftOperand) {
STARS_uval_t LeftValue = this->GetConstLeftOperand()->GetImmedValue(); STARS_uval_t LeftValue = this->GetConstLeftOperand()->GetImmedValue();
SMPoperator CurrOperator = this->GetOperator(); SMPoperator CurrOperator = this->GetOperator();
// Simplify increment or decrement of a constant.
if ((SMP_INCREMENT == CurrOperator) || (SMP_DECREMENT == CurrOperator)) {
// Hardware wraps around, so we don't have to prevent underflow or overflow here.
if (SMP_INCREMENT == CurrOperator)
++LeftValue;
else
--LeftValue;
STARSOpndTypePtr NewLeftOp = this->GetParentInst()->MakeImmediateOpnd(LeftValue);
this->SetLeftOperand(NewLeftOp);
return true; // Nothing more can be done at this level of the expr.
}
// Simplify multiplication by 0 or 1, division by 1, addition or subtraction of 0. // Simplify multiplication by 0 or 1, division by 1, addition or subtraction of 0.
if (1 == LeftValue) { else if (1 == LeftValue) {
if ((SMP_U_MULTIPLY == CurrOperator) || (SMP_S_MULTIPLY == CurrOperator)) { if ((SMP_U_MULTIPLY == CurrOperator) || (SMP_S_MULTIPLY == CurrOperator)) {
// Multiply by 1, produces right tree as result. // Multiply by 1, produces right tree as result.
// We can simplify the current expr by making it just be the RightTree or RightOperand. // We can simplify the current expr by making it just be the RightTree or RightOperand.
...@@ -4474,6 +4500,47 @@ void STARSExpression::SubstituteSSANum(SMPInstr *CallInst, const int NewSSANum, ...@@ -4474,6 +4500,47 @@ void STARSExpression::SubstituteSSANum(SMPInstr *CallInst, const int NewSSANum,
return; return;
} // end of STARSExpression::SubstituteSSANum() } // end of STARSExpression::SubstituteSSANum()
   
// Use MinVal if InitCase, MaxVal otherwise for global vars in expression
bool STARSExpression::SubstituteGlobalRangeValues(const bool InitCase) {
bool changed = false;
if (this->HasLeftSubTree()) {
changed = this->GetLeftTree()->SubstituteGlobalRangeValues(InitCase);
}
else if (this->GetConstLeftOperand()->IsStaticMemOp()) {
STARS_ea_t GlobalAddr = this->GetConstLeftOperand()->GetAddr();
STARS_uval_t ImmedVal;
bool found = false;
if (InitCase)
found = this->GetParentFunc()->GetProg()->FindGlobalMinValue(GlobalAddr, ImmedVal);
else
found = this->GetParentFunc()->GetProg()->FindGlobalMaxValue(GlobalAddr, ImmedVal);
if (found) {
STARSOpndTypePtr ImmedOp = this->GetParentInst()->MakeImmediateOpnd(ImmedVal);
this->SetLeftOperand(ImmedOp);
changed = true;
}
}
if (this->HasRightSubTree()) {
changed = (this->GetRightTree()->SubstituteGlobalRangeValues(InitCase) || changed);
}
else if ((nullptr != this->GetConstRightOperand()) && this->GetConstRightOperand()->IsStaticMemOp()) {
STARS_ea_t GlobalAddr = this->GetConstRightOperand()->GetAddr();
STARS_uval_t ImmedVal;
bool found = false;
if (InitCase)
found = this->GetParentFunc()->GetProg()->FindGlobalMinValue(GlobalAddr, ImmedVal);
else
found = this->GetParentFunc()->GetProg()->FindGlobalMaxValue(GlobalAddr, ImmedVal);
if (found) {
STARSOpndTypePtr ImmedOp = this->GetParentInst()->MakeImmediateOpnd(ImmedVal);
this->SetRightOperand(ImmedOp);
changed = true;
}
}
return changed;
} // end of STARSExpression::SubstituteGlobalRangeValues()
// For loop exprs, find the DefOp at LeftPreLoopDefAddr // For loop exprs, find the DefOp at LeftPreLoopDefAddr
STARSOpndTypePtr STARSExpression::FindLeftPreLoopDefOp(void) const { STARSOpndTypePtr STARSExpression::FindLeftPreLoopDefOp(void) const {
STARS_ea_t DefAddr = this->GetLeftPreLoopDefAddr(); STARS_ea_t DefAddr = this->GetLeftPreLoopDefAddr();
...@@ -4814,6 +4881,12 @@ SMPInstr::~SMPInstr() { ...@@ -4814,6 +4881,12 @@ SMPInstr::~SMPInstr() {
this->Defs.clear(); this->Defs.clear();
this->Uses.clear(); this->Uses.clear();
} }
#if 0 // fix crashes before enabling this
if (nullptr != this->STARSInstPtr) {
delete this->STARSInstPtr;
this->STARSInstPtr = nullptr;
}
#endif
return; return;
} }
   
...@@ -4907,11 +4980,13 @@ bool SMPInstr::HasSourceMemoryOperand(void) const { ...@@ -4907,11 +4980,13 @@ bool SMPInstr::HasSourceMemoryOperand(void) const {
} // end of SMPInstr::HasSourceMemoryOperand() } // end of SMPInstr::HasSourceMemoryOperand()
   
bool SMPInstr::HasStaticMemWrite(void) const { bool SMPInstr::HasStaticMemWrite(void) const {
return ((nullptr != this->DEFMemOp) && (this->DEFMemOp->IsStaticMemOp())); return ((nullptr != this->DEFMemOp)
&& (this->DEFMemOp->IsStaticMemOp() || IsImmedGlobalAddress(this->DEFMemOp->GetAddr())));
} }
   
bool SMPInstr::HasStaticMemRead(void) const { bool SMPInstr::HasStaticMemRead(void) const {
return ((nullptr != this->USEMemOp) && (this->USEMemOp->IsStaticMemOp())); return ((nullptr != this->USEMemOp)
&& (this->USEMemOp->IsStaticMemOp() || IsImmedGlobalAddress(this->USEMemOp->GetAddr())));
} }
   
int SMPInstr::GetOptType(void) const { int SMPInstr::GetOptType(void) const {
...@@ -5155,17 +5230,18 @@ bool SMPInstr::HasNegatedPtrUSE(void) { ...@@ -5155,17 +5230,18 @@ bool SMPInstr::HasNegatedPtrUSE(void) {
// Detect indirect memory DEFs or USEs // Detect indirect memory DEFs or USEs
void SMPInstr::AnalyzeIndirectRefs(bool UseFP) { void SMPInstr::AnalyzeIndirectRefs(bool UseFP) {
STARS_ea_t InstAddr = this->GetAddr(); STARS_ea_t InstAddr = this->GetAddr();
bool HasBlock = (nullptr != this->GetBlock());
if (this->HasDestMemoryOperand()) { if (this->HasDestMemoryOperand()) {
// Found a memory DEF. Is it indirect? // Found a memory DEF. Is it indirect?
STARSOpndTypePtr DefMemOp = this->MDGetMemDefOp(); STARSOpndTypePtr DefMemOp = this->MDGetMemDefOp();
if (MDIsIndirectMemoryOpnd(DefMemOp, UseFP)) { if (MDIsIndirectMemoryOpnd(DefMemOp, UseFP)) {
this->SetIndirectMemWrite(); this->SetIndirectMemWrite();
if (NULL != this->GetBlock()) { if (HasBlock) {
this->GetBlock()->SetHasIndirectMemWrite(); this->GetBlock()->SetHasIndirectMemWrite();
} }
} }
if (DefMemOp->IsStaticMemOp()) { if (this->HasStaticMemWrite()) {
if (NULL != this->GetBlock()) { if (HasBlock) {
this->GetBlock()->SetHasStaticMemWrite(); this->GetBlock()->SetHasStaticMemWrite();
} }
} }
...@@ -5176,22 +5252,46 @@ void SMPInstr::AnalyzeIndirectRefs(bool UseFP) { ...@@ -5176,22 +5252,46 @@ void SMPInstr::AnalyzeIndirectRefs(bool UseFP) {
STARSOpndTypePtr UseMemOp = this->MDGetMemUseOp(); STARSOpndTypePtr UseMemOp = this->MDGetMemUseOp();
if (MDIsIndirectMemoryOpnd(UseMemOp, UseFP)) { if (MDIsIndirectMemoryOpnd(UseMemOp, UseFP)) {
this->SetIndirectMemRead(); this->SetIndirectMemRead();
if (NULL != this->GetBlock()) { if (HasBlock) {
this->GetBlock()->SetHasIndirectMemRead(); this->GetBlock()->SetHasIndirectMemRead();
} }
} }
if (UseMemOp->IsStaticMemOp()) { if (this->HasStaticMemRead()) {
STARS_ea_t AddrOffset = USEMemOp->GetAddr(); STARS_ea_t AddrOffset = USEMemOp->GetAddr();
if (!IsImmedGlobalAddress(AddrOffset) && (STARS_x86_R_none == UseMemOp->GetSegReg())) { if (!IsImmedGlobalAddress(AddrOffset) && (STARS_x86_R_none == UseMemOp->GetSegReg())) {
SMP_msg("INFO: Doubtful identification of %llx as StaticMem at %llx\n", SMP_msg("INFO: Doubtful identification of %llx as StaticMem at %llx\n",
(uint64_t) AddrOffset, (uint64_t) InstAddr); (uint64_t) AddrOffset, (uint64_t) InstAddr);
} }
if (NULL != this->GetBlock()) { if (HasBlock) {
this->GetBlock()->SetHasStaticMemRead(); this->GetBlock()->SetHasStaticMemRead();
} }
} }
} }
   
if (HasBlock && this->HasDestMemoryOperand() && this->GetMemDef()->IsStaticMemOp() && (!MDIsIndirectMemoryOpnd(this->GetMemDef(), false))) {
// Direct write to static mem op. Is this a simple assignment RTL?
STARSOpndTypePtr rhs = nullptr;
STARS_ea_t GlobalAddr = this->GetMemDef()->GetAddr();
SMPRegTransfer *CurrRT = this->RTL.GetRT(0);
if ((NULL != CurrRT) && (this->RTL.GetCount() == 1)) {
bool Simple = ((!CurrRT->HasRightSubTree()) || this->IsRegUpperBitsClearIdiom());
if (Simple && (SMP_ASSIGN == CurrRT->GetOperator())) {
bool SimpleCopyRTL = (DEFAULT == this->GetDataFlowType());
if (SimpleCopyRTL) {
rhs = this->GetFirstRightOperandNoNorm();
if ((nullptr != rhs) && rhs->IsImmedOp()) {
STARS_uval_t ImmedVal = rhs->GetImmedValue();
this->GetBlock()->GetFunc()->GetProg()->InsertGlobalVarMinMaxValue(GlobalAddr, ImmedVal);
if (global_stars_interface->VerboseLoopsMode()) {
SMP_msg("INFO: GLOBALS: Found const value %llx written to global addr %llx at %llx\n",
(uint64_t)ImmedVal, (uint64_t)GlobalAddr, (uint64_t)InstAddr);
}
}
}
}
}
}
return; return;
} // end of SMPInstr::AnalyzeIndirectRefs() } // end of SMPInstr::AnalyzeIndirectRefs()
   
...@@ -8671,8 +8771,9 @@ bool SMPInstr::FillCmd(void) { ...@@ -8671,8 +8771,9 @@ bool SMPInstr::FillCmd(void) {
// Analyze the instruction and its operands. // Analyze the instruction and its operands.
void SMPInstr::Analyze(void) { void SMPInstr::Analyze(void) {
bool DebugFlag = false; bool DebugFlag = false;
STARS_ea_t InstAddr = this->GetAddr();
   
if (0x8049b00 == this->GetAddr()) { if (0x8049b00 == InstAddr) {
// Setting up breakpoint line. // Setting up breakpoint line.
DebugFlag = true; DebugFlag = true;
} }
...@@ -8747,8 +8848,8 @@ void SMPInstr::Analyze(void) { ...@@ -8747,8 +8848,8 @@ void SMPInstr::Analyze(void) {
this->MDFixFloatingPointRTL(); this->MDFixFloatingPointRTL();
} }
else { else {
SMP_msg("ERROR: RTL not built at %llx %s\n", (unsigned long long) this->GetAddr(), SMP_msg("ERROR: RTL not built at %llx %s\n", (uint64_t) InstAddr,
DisAsmText.GetDisAsm(this->GetAddr())); DisAsmText.GetDisAsm(InstAddr));
return; return;
} }
   
...@@ -8788,20 +8889,21 @@ void SMPInstr::Analyze(void) { ...@@ -8788,20 +8889,21 @@ void SMPInstr::Analyze(void) {
} }
} }
if (STARS_BADADDR == this->CallTarget) { if (STARS_BADADDR == this->CallTarget) {
SMP_msg("ERROR: Target not found for direct call at %llx\n", (unsigned long long) this->GetAddr()); SMP_msg("ERROR: Target not found for direct call at %llx\n", (uint64_t) InstAddr);
} }
} }
   
if (this->MDIsPushInstr()) { if (this->MDIsPushInstr()) {
if (this->STARSInstPtr->IsPushFromFixedCall()) { if (this->STARSInstPtr->IsPushFromFixedCall()) {
this->SetFixedCallPush(); this->SetFixedCallPush();
SMP_msg("INFO: Found internal code address push from fixed call at %llx\n", (unsigned long long) this->GetAddr()); SMP_msg("INFO: Found internal code address push from fixed call at %llx\n", (uint64_t) InstAddr);
} }
} }
   
if (DebugFlag) { if (DebugFlag) {
SMP_msg("Analyzed debug instruction at %llx\n", (unsigned long long) this->GetAddr()); SMP_msg("Analyzed debug instruction at %llx\n", (uint64_t) InstAddr);
} }
return; return;
} // end of SMPInstr::Analyze() } // end of SMPInstr::Analyze()
   
...@@ -165,6 +165,25 @@ SMPProgram::~SMPProgram(void) { ...@@ -165,6 +165,25 @@ SMPProgram::~SMPProgram(void) {
return; return;
} }
// Methods for recovering min or max value seen directly written to a global var.
bool SMPProgram::FindGlobalMinValue(const STARS_ea_t GlobalAddr, STARS_uval_t &MinValue) const {
map<STARS_ea_t, struct STARSValueRange>::const_iterator MapIter = this->GlobalValueRangeMap.find(GlobalAddr);
bool found = (MapIter != this->GlobalValueRangeMap.cend());
if (found)
MinValue = MapIter->second.MinVal;
return found;
} // end of SMPProgram::FindGlobalMinValue()
bool SMPProgram::FindGlobalMaxValue(const STARS_ea_t GlobalAddr, STARS_uval_t &MaxValue) const {
map<STARS_ea_t, struct STARSValueRange>::const_iterator MapIter = this->GlobalValueRangeMap.find(GlobalAddr);
bool found = (MapIter != this->GlobalValueRangeMap.cend());
if (found)
MaxValue = MapIter->second.MaxVal;
return found;
} // end of SMPProgram::FindGlobalMaxValue()
// Return SMPFunction pointer from FuncMap for FirstAddr if it exists // Return SMPFunction pointer from FuncMap for FirstAddr if it exists
// in the FuncMap, else return NULL. // in the FuncMap, else return NULL.
SMPFunction *SMPProgram::FindFunction(STARS_ea_t FirstAddr) const { SMPFunction *SMPProgram::FindFunction(STARS_ea_t FirstAddr) const {
...@@ -267,6 +286,26 @@ void SMPProgram::AddBlockToRemovalList(SMPBasicBlock *UnreachableBlock) { ...@@ -267,6 +286,26 @@ void SMPProgram::AddBlockToRemovalList(SMPBasicBlock *UnreachableBlock) {
return; return;
} // end of SMPProgram::AddBlockToRemovalList() } // end of SMPProgram::AddBlockToRemovalList()
// Update, as needed, the min or max value seen so far for GlobalAddr.
void SMPProgram::InsertGlobalVarMinMaxValue(const STARS_ea_t GlobalAddr, const STARS_uval_t ValueSeen) {
map<STARS_ea_t, struct STARSValueRange>::iterator MapIter = this->GlobalValueRangeMap.find(GlobalAddr);
bool found = (MapIter != this->GlobalValueRangeMap.end());
if (found) {
if (ValueSeen < MapIter->second.MinVal)
MapIter->second.MinVal = ValueSeen;
else if (ValueSeen > MapIter->second.MaxVal)
MapIter->second.MaxVal = ValueSeen;
}
else {
struct STARSValueRange TempRange;
TempRange.MinVal = ValueSeen;
TempRange.MaxVal = ValueSeen;
this->GlobalValueRangeMap[GlobalAddr] = TempRange;
}
return;
}
// Is InstAddr in the set of unshared code fragments? // Is InstAddr in the set of unshared code fragments?
bool SMPProgram::IsUnsharedFragment(STARS_ea_t InstAddr) { bool SMPProgram::IsUnsharedFragment(STARS_ea_t InstAddr) {
bool Found = (this->UnsharedFragments.find(InstAddr) != this->UnsharedFragments.end()); bool Found = (this->UnsharedFragments.find(InstAddr) != this->UnsharedFragments.end());
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include <string> #include <string>
#include <sstream>
#include <ctime> #include <ctime>
...@@ -530,6 +531,8 @@ bool IDAP_run(size_t arg) { ...@@ -530,6 +531,8 @@ bool IDAP_run(size_t arg) {
delete CurrProg; delete CurrProg;
delete global_STARS_program; delete global_STARS_program;
delete global_stars_interface; delete global_stars_interface;
#if (IDA_SDK_VERSION < 700) #if (IDA_SDK_VERSION < 700)
return; return;
#else #else
...@@ -627,6 +630,10 @@ bool IDAP_run(size_t arg) { ...@@ -627,6 +630,10 @@ bool IDAP_run(size_t arg) {
delete prof_info; delete prof_info;
SMP_msg("INFO: Deleted prof_info.\n"); SMP_msg("INFO: Deleted prof_info.\n");
delete CurrProg; delete CurrProg;
stringstream sout;
STARS_Instruction_t::DumpCreationStats(sout);
STARS_op_t::DumpCreationStats(sout);
SMP_msg("Interface stats: \n %s", sout.str().c_str());
SMP_msg("INFO: Deleted CurrProg. Returning to IDA Pro.\n"); SMP_msg("INFO: Deleted CurrProg. Returning to IDA Pro.\n");
delete global_STARS_program; delete global_STARS_program;
delete global_stars_interface; delete global_stars_interface;
......
...@@ -148,8 +148,9 @@ void OutputStatistics() ...@@ -148,8 +148,9 @@ void OutputStatistics()
} }
#endif #endif
// mark that we've completed analysis. // mark that we've completed analysis.
SMP_fprintf(global_STARS_program->GetInfoAnnotFile(), " 8000000 2 SUCCESS ANALYSISCOMPLETED\n");
SMP_fprintf(global_STARS_program->GetInfoAnnotFile(), " 8000000 2 SUCCESS ANALYSISCOMPLETED\n"); STARS_Instruction_t::DumpCreationStats(cout);
STARS_op_t::DumpCreationStats(cout);
} }
int STARS::IRDB_Interface_t::do_STARS(FileIR_t* firp) int STARS::IRDB_Interface_t::do_STARS(FileIR_t* firp)
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
// declare global static data for STARS_InstructionID_t class // declare global static data for STARS_InstructionID_t class
std::map<STARS_ea_t, const STARS_Instruction_t*> STARS_InstructionID_t::id_to_insn_map; std::map<STARS_ea_t, const STARS_Instruction_t*> STARS_InstructionID_t::id_to_insn_map;
uint64_t STARS_Instruction_t::objects_created=0;
uint64_t STARS_Instruction_t::objects_destroyed=0;
bool STARS_Instruction_t::OpcodeDefaultsTo64BitOperands(void) bool STARS_Instruction_t::OpcodeDefaultsTo64BitOperands(void)
{ {
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
#include <interfaces/SMPDBInterface.h> #include <interfaces/SMPDBInterface.h>
#include <interfaces/STARSTypes.h> #include <interfaces/STARSTypes.h>
uint64_t STARS_op_t::objects_created=0;
uint64_t STARS_op_t::objects_destroyed=0;
void STARS_op_t::MDExtractAddressFields(int &BaseReg, int &IndexReg, uint16_t &Scale, STARS_ea_t &Offset) const { void STARS_op_t::MDExtractAddressFields(int &BaseReg, int &IndexReg, uint16_t &Scale, STARS_ea_t &Offset) const {
assert(this->IsMemOp()); assert(this->IsMemOp());
......
...@@ -225,7 +225,10 @@ void STARS_IDA_Program_t::InitStaticDataTable(SMPProgram *CurrProg) { ...@@ -225,7 +225,10 @@ void STARS_IDA_Program_t::InitStaticDataTable(SMPProgram *CurrProg) {
SMP_msg(" SegName: %s", SegName); SMP_msg(" SegName: %s", SegName);
SMP_msg(" from %lx to %lx\n", (unsigned long)seg->get_startEA(), (unsigned long)seg->get_endEA()); SMP_msg(" from %lx to %lx\n", (unsigned long)seg->get_startEA(), (unsigned long)seg->get_endEA());
#endif #endif
if ((seg->IsDataSegment()) || (seg->IsBSSSegment()) || (seg->IsCommonSegment())) { bool DataSegFlag = seg->IsDataSegment();
bool BSSSegFlag = seg->IsBSSSegment();
bool CommonSegFlag = seg->IsCommonSegment();
if (DataSegFlag || BSSSegFlag || CommonSegFlag) {
// Loop through each of the segments we are interested in, // Loop through each of the segments we are interested in,
// examining all data objects (effective addresses). // examining all data objects (effective addresses).
ReadOnlyFlag = ((seg->IsReadableSegment()) && (!(seg->IsWriteableSegment()))); ReadOnlyFlag = ((seg->IsReadableSegment()) && (!(seg->IsWriteableSegment())));
...@@ -304,49 +307,51 @@ void STARS_IDA_Program_t::InitStaticDataTable(SMPProgram *CurrProg) { ...@@ -304,49 +307,51 @@ void STARS_IDA_Program_t::InitStaticDataTable(SMPProgram *CurrProg) {
pair<STARS_ea_t, struct GlobalVar> TempItem(ea, VarTemp); pair<STARS_ea_t, struct GlobalVar> TempItem(ea, VarTemp);
CurrProg->InsertGlobalVarTableEntry(TempItem); CurrProg->InsertGlobalVarTableEntry(TempItem);
// Check for code xrefs from the data. if (!BSSSegFlag) {
// Can have a table of pointers, so iterate through large data objects. // Check for code xrefs from the data.
STARS_ea_t TempAddr = ea; // Can have a table of pointers, so iterate through large data objects.
while ((NextEA - TempAddr) >= MD_DEFAULT_RETURN_ADDRESS_SIZE) { STARS_ea_t TempAddr = ea;
SMP_xref_t xrefs; while ((NextEA - TempAddr) >= MD_DEFAULT_RETURN_ADDRESS_SIZE) {
for (bool ok = xrefs.SMP_first_from(TempAddr, XREF_DATA); ok; ok = xrefs.SMP_next_from()) { SMP_xref_t xrefs;
STARS_ea_t TargetAddr = xrefs.GetTo(); for (bool ok = xrefs.SMP_first_from(TempAddr, XREF_DATA); ok; ok = xrefs.SMP_next_from()) {
if ((TargetAddr != 0) && (!xrefs.GetIscode())) { STARS_ea_t TargetAddr = xrefs.GetTo();
// Found a target, with its address in xrefs.to if ((TargetAddr != 0) && (!xrefs.GetIscode())) {
// Is the target code? // Found a target, with its address in xrefs.to
STARS_Segment_t *SegInfo = SMP_getseg(TargetAddr); // Is the target code?
if ((NULL != SegInfo) && (SegInfo->IsCodeSegment())) { STARS_Segment_t *SegInfo = SMP_getseg(TargetAddr);
if (!ReadOnlyFlag) { if ((NULL != SegInfo) && (SegInfo->IsCodeSegment())) {
SMP_msg("INFO: Code Xref from writeable data at %llx\n", (uint64_t) ea); if (!ReadOnlyFlag) {
SMP_msg("INFO: Code Xref from writeable data at %llx\n", (uint64_t)ea);
}
bool NewTarget = CurrProg->InsertDataToCodeXref(TargetAddr);
if (NewTarget)
global_STARS_program->PrintDataToCodeXref(TempAddr, TargetAddr, 0);
} }
bool NewTarget = CurrProg->InsertDataToCodeXref(TargetAddr);
if (NewTarget)
global_STARS_program->PrintDataToCodeXref(TempAddr, TargetAddr, 0);
} }
} }
} STARS_ea_t DataValue;
STARS_ea_t DataValue; if (4 < global_STARS_program->GetSTARS_ISA_Bytewidth())
if (4 < global_STARS_program->GetSTARS_ISA_Bytewidth()) DataValue = (STARS_ea_t) ::get_qword(TempAddr);
DataValue = (STARS_ea_t) ::get_qword(TempAddr); else
else
#if (IDA_SDK_VERSION < 700) #if (IDA_SDK_VERSION < 700)
DataValue = (STARS_ea_t) ::get_long(TempAddr); DataValue = (STARS_ea_t) ::get_long(TempAddr);
#else #else
DataValue = (STARS_ea_t) ::get_dword(TempAddr); DataValue = (STARS_ea_t) ::get_dword(TempAddr);
#endif #endif
if (DataValue != 0) { if (DataValue != 0) {
// Is this a code address? // Is this a code address?
STARS_ea_t PossibleCodeAddr = (STARS_ea_t) DataValue; STARS_ea_t PossibleCodeAddr = (STARS_ea_t)DataValue;
STARS_Segment_t *SegInfo = SMP_getseg(PossibleCodeAddr); STARS_Segment_t *SegInfo = SMP_getseg(PossibleCodeAddr);
if ((NULL != SegInfo) && (SegInfo->IsCodeSegment())) { if ((NULL != SegInfo) && (SegInfo->IsCodeSegment())) {
bool NewTarget = CurrProg->InsertDataToCodeXref(PossibleCodeAddr); bool NewTarget = CurrProg->InsertDataToCodeXref(PossibleCodeAddr);
if (NewTarget) if (NewTarget)
global_STARS_program->PrintDataToCodeXref(TempAddr, PossibleCodeAddr, 0); global_STARS_program->PrintDataToCodeXref(TempAddr, PossibleCodeAddr, 0);
}
} }
} TempAddr += MD_DEFAULT_RETURN_ADDRESS_SIZE;
TempAddr += MD_DEFAULT_RETURN_ADDRESS_SIZE; } // end while ((NextEA - TempAddr) >= MD_DEFAULT_RETURN_ADDRESS_SIZE)
} } // end if (!BSSSegFlag)
// Move on to next data object // Move on to next data object
ea = NextEA; ea = NextEA;
...@@ -359,7 +364,7 @@ void STARS_IDA_Program_t::InitStaticDataTable(SMPProgram *CurrProg) { ...@@ -359,7 +364,7 @@ void STARS_IDA_Program_t::InitStaticDataTable(SMPProgram *CurrProg) {
#endif #endif
} }
} // end while (ea < seg->endEA) } // end while (ea < seg->endEA)
} // end if (seg->type == SEG_DATA ...) } // end if (DataSegFlag || BSSSegFlag || CommonSegFlag)
else if (seg->IsCodeSegment()) { else if (seg->IsCodeSegment()) {
if (seg->get_startEA() < TempLowestCodeAddress) if (seg->get_startEA() < TempLowestCodeAddress)
TempLowestCodeAddress = seg->get_startEA(); TempLowestCodeAddress = seg->get_startEA();
...@@ -544,7 +549,7 @@ void STARS_IDA_Program_t::FindCodeAddressesTaken(SMPProgram *CurrProg) { ...@@ -544,7 +549,7 @@ void STARS_IDA_Program_t::FindCodeAddressesTaken(SMPProgram *CurrProg) {
STARS_ea_t ea = seg->get_startEA(); STARS_ea_t ea = seg->get_startEA();
RecentAddr = ea; RecentAddr = ea;
bool ReadOnlyFlag = ((seg->IsReadableSegment()) && (!(seg->IsWriteableSegment()))); bool ReadOnlyFlag = ((seg->IsReadableSegment()) && (!(seg->IsWriteableSegment())));
bool DataSegment = ((seg->IsDataSegment()) || (seg->IsBSSSegment()) || (seg->IsCommonSegment())); bool DataSegment = ((seg->IsDataSegment()) || (seg->IsCommonSegment()));
#if 0 #if 0
if (ReadOnlyFlag && DataSegment) { if (ReadOnlyFlag && DataSegment) {
#else #else
......
...@@ -211,6 +211,8 @@ bool STARS_IRDB_Function_t::IsInstIDInFunc(STARS_ea_t InstID) ...@@ -211,6 +211,8 @@ bool STARS_IRDB_Function_t::IsInstIDInFunc(STARS_ea_t InstID)
return false; return false;
const STARS_Instruction_t *stars_insn=id.GetInstruction(); const STARS_Instruction_t *stars_insn=id.GetInstruction();
if (nullptr == stars_insn)
return false;
const STARS_IRDB_Instruction_t* interface_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(stars_insn); const STARS_IRDB_Instruction_t* interface_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(stars_insn);
assert(interface_insn); assert(interface_insn);
libIRDB::Instruction_t* irdb_insn=(libIRDB::Instruction_t*)interface_insn->GetIRDBInstruction(); libIRDB::Instruction_t* irdb_insn=(libIRDB::Instruction_t*)interface_insn->GetIRDBInstruction();
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
STARS_Instruction_t * STARS_IRDB_Interface_t::CreateInst(STARS_InstructionID_t InstID) STARS_Instruction_t * STARS_IRDB_Interface_t::CreateInst(STARS_InstructionID_t InstID)
{ {
// check for psuedo-instructions // check for pseudo-instructions
if(STARS_IsSSAMarkerPseudoID(InstID.GetIDWithinFile())) if(STARS_IsSSAMarkerPseudoID(InstID.GetIDWithinFile()))
return new STARS_IRDB_Instruction_t(InstID); return new STARS_IRDB_Instruction_t(InstID);
// already created, just return what we need. // already created, just return what we need.
...@@ -33,6 +33,8 @@ bool STARS_IRDB_Interface_t::STARS_generate_disasm_line(STARS_ea_t addr, char *b ...@@ -33,6 +33,8 @@ bool STARS_IRDB_Interface_t::STARS_generate_disasm_line(STARS_ea_t addr, char *b
{ {
STARS_InstructionID_t id(addr); STARS_InstructionID_t id(addr);
const STARS_Instruction_t* insn=id.GetInstruction(); const STARS_Instruction_t* insn=id.GetInstruction();
if (nullptr == insn)
return false;
const STARS_IRDB_Instruction_t* irdb_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(insn); const STARS_IRDB_Instruction_t* irdb_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(insn);
strncpy(buf,irdb_insn->GetIRDBInstruction()->getDisassembly().c_str(), bufsize); strncpy(buf,irdb_insn->GetIRDBInstruction()->getDisassembly().c_str(), bufsize);
return true; return true;
......