Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove tmpes in SVFIR2AbsState #1436

Merged
merged 5 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading