Skip to content

Commit

Permalink
Merge pull request #1436 from bjjwwang/master
Browse files Browse the repository at this point in the history
remove tmpes in SVFIR2AbsState
  • Loading branch information
yuleisui authored Apr 18, 2024
2 parents a7c5c80 + 3d51d88 commit fe17fb8
Show file tree
Hide file tree
Showing 7 changed files with 382 additions and 618 deletions.
25 changes: 13 additions & 12 deletions svf-llvm/tools/Example/svf-ex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,32 +77,33 @@ std::string printPts(PointerAnalysis* pta, const SVFValue* svfval)
*/
void traverseOnSVFStmt(const ICFGNode* node)
{
SVFIR2AbsState* svfir2ExeState = new SVFIR2AbsState(SVFIR::getPAG());
AbstractState es;
SVFIR2AbsState* svfir2AbsState = new SVFIR2AbsState(SVFIR::getPAG());
for (const SVFStmt* stmt: node->getSVFStmts())
{
if (const AddrStmt *addr = SVFUtil::dyn_cast<AddrStmt>(stmt))
{
svfir2ExeState->handleAddr(addr);
svfir2AbsState->handleAddr(es, addr);
}
else if (const BinaryOPStmt *binary = SVFUtil::dyn_cast<BinaryOPStmt>(stmt))
{
svfir2ExeState->handleBinary(binary);
svfir2AbsState->handleBinary(es, binary);
}
else if (const CmpStmt *cmp = SVFUtil::dyn_cast<CmpStmt>(stmt))
{
svfir2ExeState->handleCmp(cmp);
svfir2AbsState->handleCmp(es, cmp);
}
else if (const LoadStmt *load = SVFUtil::dyn_cast<LoadStmt>(stmt))
{
svfir2ExeState->handleLoad(load);
svfir2AbsState->handleLoad(es, load);
}
else if (const StoreStmt *store = SVFUtil::dyn_cast<StoreStmt>(stmt))
{
svfir2ExeState->handleStore(store);
svfir2AbsState->handleStore(es, store);
}
else if (const CopyStmt *copy = SVFUtil::dyn_cast<CopyStmt>(stmt))
{
svfir2ExeState->handleCopy(copy);
svfir2AbsState->handleCopy(es, copy);
}
else if (const GepStmt *gep = SVFUtil::dyn_cast<GepStmt>(stmt))
{
Expand All @@ -111,24 +112,24 @@ void traverseOnSVFStmt(const ICFGNode* node)
gep->accumulateConstantByteOffset();
gep->accumulateConstantOffset();
}
svfir2ExeState->handleGep(gep);
svfir2AbsState->handleGep(es, gep);
}
else if (const SelectStmt *select = SVFUtil::dyn_cast<SelectStmt>(stmt))
{
svfir2ExeState->handleSelect(select);
svfir2AbsState->handleSelect(es, select);
}
else if (const PhiStmt *phi = SVFUtil::dyn_cast<PhiStmt>(stmt))
{
svfir2ExeState->handlePhi(phi);
svfir2AbsState->handlePhi(es, phi);
}
else if (const CallPE *callPE = SVFUtil::dyn_cast<CallPE>(stmt))
{
// To handle Call Edge
svfir2ExeState->handleCall(callPE);
svfir2AbsState->handleCall(es, callPE);
}
else if (const RetPE *retPE = SVFUtil::dyn_cast<RetPE>(stmt))
{
svfir2ExeState->handleRet(retPE);
svfir2AbsState->handleRet(es, retPE);
}
else
assert(false && "implement this part");
Expand Down
42 changes: 23 additions & 19 deletions svf/include/AE/Svfexe/AbstractInterpretation.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class AbstractInterpretation
* @param intraEdge the edge from CmpStmt to the next node
* @return if this edge is feasible
*/
bool hasBranchES(const IntraCFGEdge* intraEdge, AbstractState& es);
bool isBranchFeasible(const IntraCFGEdge* intraEdge, AbstractState& es);

/**
* handle instructions in ICFGNode
Expand Down Expand Up @@ -205,12 +205,6 @@ class AbstractInterpretation
*/
virtual void SkipRecursiveCall(const CallICFGNode* callnode);

/**
* Check if this function is recursive function and skip it.
*
* @param func SVFFunction is a recursive function
*/
virtual void SkipRecursiveFunc(const SVFFunction* func);

/**
* Check if this cmpStmt and succ are satisfiable to the execution state.
Expand All @@ -219,7 +213,7 @@ class AbstractInterpretation
* @param succ the value of cmpStmt (True or False)
* @return if this ICFGNode has preceding execution state
*/
bool hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ,
bool isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t succ,
AbstractState& es);

/**
Expand All @@ -229,7 +223,7 @@ class AbstractInterpretation
* @param succ the case value of switch inst
* @return if this ICFGNode has preceding execution state
*/
bool hasSwitchBranchES(const SVFVar* var, s64_t succ,
bool isSwitchBranchFeasible(const SVFVar* var, s64_t succ,
AbstractState& es);


Expand All @@ -254,7 +248,7 @@ class AbstractInterpretation
* @param addr Address Stmt like malloc/calloc/ALLOCA/StackAlloc
* @return the byte size e.g. int32_t a[10] -> return 40
*/
u32_t getAllocaInstByteSize(const AddrStmt *addr);
u32_t getAllocaInstByteSize(AbstractState& es, const AddrStmt *addr);

/**
* get byte size of alloca inst
Expand All @@ -263,7 +257,7 @@ class AbstractInterpretation
* @param rhs SVFValue of string
* @return the string
*/
std::string strRead(const SVFValue* rhs);
std::string strRead(AbstractState& es,const SVFValue* rhs);

/**
* get length of string
Expand All @@ -272,7 +266,7 @@ class AbstractInterpretation
* @param strValue SVFValue of string
* @return AbstractValue of string length
*/
AbstractValue getStrlen(const SVF::SVFValue *strValue);
AbstractValue getStrlen(AbstractState& es, const SVF::SVFValue *strValue);

/**
* get memory allocation size
Expand All @@ -283,7 +277,7 @@ class AbstractInterpretation
* @param value to be traced
* @return AbstractValue of allocation size
*/
AbstractValue traceMemoryAllocationSize(const SVFValue *value);
AbstractValue traceMemoryAllocationSize(AbstractState& es, const SVFValue *value);
/**
* execute strcpy in abstract execution
* e.g arr = new char[10]
Expand All @@ -310,15 +304,15 @@ class AbstractInterpretation
* we can set arr[3]='d', arr[4]='e', arr[5]='\0'
* @param call callnode of memcpy like api
*/
virtual void handleMemcpy(const SVFValue* dst, const SVFValue* src, AbstractValue len, u32_t start_idx);
virtual void handleMemcpy(AbstractState& es, const SVFValue* dst, const SVFValue* src, AbstractValue len, u32_t start_idx);
/**
* execute memset in abstract execution
* e.g arr = new char[10]
* memset(arr, 'c', 2)
* we can set arr[0]='c', arr[1]='c', arr[2]='\0'
* @param call callnode of memset like api
*/
virtual void handleMemset(const SVFValue* dst, AbstractValue elem, AbstractValue len);
virtual void handleMemset(AbstractState& es, const SVFValue* dst, AbstractValue elem, AbstractValue len);

/**
* if this NodeID in SVFIR is a pointer, get the pointee type
Expand All @@ -327,14 +321,14 @@ class AbstractInterpretation
* we can set arr[0]='c', arr[1]='c', arr[2]='\0'
* @param call callnode of memset like api
*/
const SVFType* getPointeeElement(NodeID id);
const SVFType* getPointeeElement(AbstractState& es, NodeID id);

void collectCheckPoint();
void checkPointAllSet();
// helper functions for traceMemoryAllocationSize and canSafelyAccessMemory
void AccessMemoryViaRetNode(const CallICFGNode *callnode, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);
void AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);
void AccessMemoryViaLoadStmt(const LoadStmt *load, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);
void AccessMemoryViaLoadStmt(AbstractState& es, const LoadStmt *load, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);
void AccessMemoryViaCallArgs(const SVF::SVFArgument *arg, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);


Expand Down Expand Up @@ -375,13 +369,23 @@ class AbstractInterpretation
bool narrowFixpointPass(const ICFGNode* cycle_head,
AbstractState& pre_es);

AbstractState& getState(const ICFGNode* node) {
const ICFGNode* repNode = _icfg->getRepNode(node);
if (_postAbsTrace.count(repNode) == 0) {
assert(0 && "No preAbsTrace for this node");
} else
{
return _postAbsTrace[repNode];
}
}

protected:
// there data should be shared with subclasses
Map<std::string, std::function<void(const CallSite &)>> _func_map;
Set<const CallICFGNode*> _checkpoints;
Set<std::string> _checkpoint_names;
Map<const ICFGNode*, AbstractState> _preAbstractTrace;
Map<const ICFGNode*, AbstractState> _postAbstractTrace;
Map<const ICFGNode*, AbstractState> _preAbsTrace;
Map<const ICFGNode*, AbstractState> _postAbsTrace;
std::string _moduleName;
};
}
104 changes: 37 additions & 67 deletions svf/include/AE/Svfexe/SVFIR2AbsState.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,6 @@ class SVFIR2AbsState
public:
SVFIR2AbsState(SVFIR *ir) : _svfir(ir) {}

void setEs(const AbstractState&es)
{
_es = es;
}

AbstractState& getAbsState()
{
return _es;
}

void setRelEs(const RelExeState &relEs)
{
Expand All @@ -66,34 +57,34 @@ class SVFIR2AbsState
return _relEs;
}

void widenAddrs(AbstractState&lhs, const AbstractState&rhs);
void widenAddrs(AbstractState& es, AbstractState&lhs, const AbstractState&rhs);

void narrowAddrs(AbstractState&lhs, const AbstractState&rhs);
void narrowAddrs(AbstractState& es, AbstractState&lhs, const AbstractState&rhs);

/// Return the field address given a pointer points to a struct object and an offset
AbstractValue getGepObjAddress(u32_t pointer, APOffset offset);
AbstractValue getGepObjAddress(AbstractState& es, u32_t pointer, APOffset offset);

/// Return the value range of Integer SVF Type, e.g. unsigned i8 Type->[0, 255], signed i8 Type->[-128, 127]
AbstractValue getRangeLimitFromType(const SVFType* type);

AbstractValue getZExtValue(const SVFVar* var);
AbstractValue getSExtValue(const SVFVar* var);
AbstractValue getFPToSIntValue(const SVFVar* var);
AbstractValue getFPToUIntValue(const SVFVar* var);
AbstractValue getSIntToFPValue(const SVFVar* var);
AbstractValue getUIntToFPValue(const SVFVar* var);
AbstractValue getTruncValue(const SVFVar* var, const SVFType* dstType);
AbstractValue getFPTruncValue(const SVFVar* var, const SVFType* dstType);
AbstractValue getZExtValue(AbstractState& es, const SVFVar* var);
AbstractValue getSExtValue(AbstractState& es, const SVFVar* var);
AbstractValue getFPToSIntValue(AbstractState& es, const SVFVar* var);
AbstractValue getFPToUIntValue(AbstractState& es, const SVFVar* var);
AbstractValue getSIntToFPValue(AbstractState& es, const SVFVar* var);
AbstractValue getUIntToFPValue(AbstractState& es, const SVFVar* var);
AbstractValue getTruncValue(AbstractState& es, const SVFVar* var, const SVFType* dstType);
AbstractValue getFPTruncValue(AbstractState& es, const SVFVar* var, const SVFType* dstType);

/// Return the byte offset expression of a GepStmt
/// elemBytesize is the element byte size of an static alloc or heap alloc array
/// e.g. GepStmt* gep = [i32*10], x, and x is [0,3]
/// std::pair<s32_t, s32_t> byteOffset = getByteOffset(gep);
/// byteOffset should be [0, 12] since i32 is 4 bytes.
AbstractValue getByteOffset(const GepStmt *gep);
AbstractValue getByteOffset(AbstractState& es, const GepStmt *gep);

/// Return the offset expression of a GepStmt
AbstractValue getItvOfFlattenedElemIndex(const GepStmt *gep);
AbstractValue getItvOfFlattenedElemIndex(AbstractState& es, const GepStmt *gep);


static z3::context &getContext()
Expand All @@ -105,66 +96,66 @@ class SVFIR2AbsState


/// Init ObjVar
void initObjVar(const ObjVar *objVar, u32_t varId);
void initObjVar(AbstractState& es, const ObjVar *objVar, u32_t varId);

/// Init SVFVar
void initSVFVar(u32_t varId);
void initSVFVar(AbstractState& es, u32_t varId);

inline AbstractValue &getAddrs(u32_t id)
inline AbstractValue &getAddrs(AbstractState& es, u32_t id)
{
if (inVarToAddrsTable(id))
return _es.getAddrs(id);
if (inVarToAddrsTable(es, id))
return es.getAddrs(id);
else
return globalNulladdrs;
}


/// whether the variable is in varToVal table
inline bool inVarToValTable(u32_t id) const
inline bool inVarToValTable(AbstractState& es, u32_t id) const
{
return _es.inVarToValTable(id);
return es.inVarToValTable(id);
}

/// whether the variable is in varToAddrs table
inline bool inVarToAddrsTable(u32_t id) const
inline bool inVarToAddrsTable(AbstractState& es, u32_t id) const
{
return _es.inVarToAddrsTable(id);
return es.inVarToAddrsTable(id);
}


/// whether the memory address stores a interval value
inline bool inLocToValTable(u32_t id) const
inline bool inLocToValTable(AbstractState& es, u32_t id) const
{
return _es.inLocToValTable(id);
return es.inLocToValTable(id);
}

/// whether the memory address stores memory addresses
inline bool inLocToAddrsTable(u32_t id) const
inline bool inLocToAddrsTable(AbstractState& es, u32_t id) const
{
return _es.inLocToAddrsTable(id);
return es.inLocToAddrsTable(id);
}

void handleAddr(const AddrStmt *addr);
void handleAddr(AbstractState& es, const AddrStmt *addr);

void handleBinary(const BinaryOPStmt *binary);
void handleBinary(AbstractState& es, const BinaryOPStmt *binary);

void handleCmp(const CmpStmt *cmp);
void handleCmp(AbstractState& es, const CmpStmt *cmp);

void handleLoad(const LoadStmt *load);
void handleLoad(AbstractState& es, const LoadStmt *load);

void handleStore(const StoreStmt *store);
void handleStore(AbstractState& es, const StoreStmt *store);

void handleCopy(const CopyStmt *copy);
void handleCopy(AbstractState& es, const CopyStmt *copy);

void handleCall(const CallPE *callPE);
void handleCall(AbstractState& es, const CallPE *callPE);

void handleRet(const RetPE *retPE);
void handleRet(AbstractState& es, const RetPE *retPE);

void handleGep(const GepStmt *gep);
void handleGep(AbstractState& es, const GepStmt *gep);

void handleSelect(const SelectStmt *select);
void handleSelect(AbstractState& es, const SelectStmt *select);

void handlePhi(const PhiStmt *phi);
void handlePhi(AbstractState& es, const PhiStmt *phi);

/// Return the internal index if idx is an address otherwise return the value of idx
static inline u32_t getInternalID(u32_t idx)
Expand All @@ -184,29 +175,8 @@ class SVFIR2AbsState
return AbstractState::isVirtualMemAddress(val);
}

protected:

void handleBinaryRel(const BinaryOPStmt *binary);

void handleCmpRel(const CmpStmt *cmp);

void handleLoadRel(const LoadStmt *load);

void handleStoreRel(const StoreStmt *store);

void handleCopyRel(const CopyStmt *copy);

void handleCallRel(const CallPE *callPE);

void handleRetRel(const RetPE *retPE);

void handleSelectRel(const SelectStmt *select);

void handlePhiRel(const PhiStmt *phi, const ICFGNode *srcNode, const std::vector<const ICFGEdge *> &path);

private:
SVFIR *_svfir;
AbstractState _es;
RelExeState _relEs;
};
}
Expand Down
Loading

0 comments on commit fe17fb8

Please sign in to comment.