41using namespace SVFUtil;
190 "AE -ae-fun-entry=main requires a program entry function, but main/svf.main was not found.\n");
191 assert(
false &&
"No program entry function found for -ae-fun-entry=main");
215 assert(
false &&
"No entry functions found for analysis");
298 else if (SVFUtil::isa<CallCFGEdge>(
edge))
303 else if (SVFUtil::isa<RetCFGEdge>(
edge))
347 if (
var->getInEdges().empty())
354 const SVFVar* src = cs->getRHSVar();
356 return SVFUtil::dyn_cast<LoadStmt>(*src->
getInEdges().begin());
410 predicate =
it->second;
443 predicate =
it->second;
497 *
edge->getCondition()->getInEdges().begin());
546 "branch condition has no defining edge?");
572 for (
int i = 0;
i < 2;
i++)
578 if (
opVal[
i].getInterval().is_numeral())
582 else if (!
opVal[
other].getInterval().is_numeral())
645 const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(
stmt);
711 assert(!
cmpVar->getInEdges().empty() &&
"branch condition has no defining edge?");
712 if (SVFUtil::isa<CmpStmt>(*
cmpVar->getInEdges().begin()))
726 bool isFunEntry = SVFUtil::isa<FunEntryICFGNode>(node);
790 while (!worklist.
empty())
824 assert (
false &&
"it is not call node");
859 if (!
Addrs.isAddr() ||
Addrs.getAddrs().empty())
864 return SVFUtil::dyn_cast<FunObjVar>(
func_var);
898 if (
callee->isDeclaration())
925 else if (SVFUtil::isa<UnaryOPStmt>(
stmt))
928 else if (SVFUtil::isa<BranchStmt>(
stmt))
932 else if (
const LoadStmt *load = SVFUtil::dyn_cast<LoadStmt>(
stmt))
936 else if (
const StoreStmt *store = SVFUtil::dyn_cast<StoreStmt>(
stmt))
956 else if (
const CallPE *callPE = SVFUtil::dyn_cast<CallPE>(
stmt))
961 else if (
const RetPE *retPE = SVFUtil::dyn_cast<RetPE>(
stmt))
966 assert(
false &&
"implement this part");
974 (!
it->second.isInterval() && !
it->second.isAddr()));
993 if (
condVal.getInterval().is_numeral())
1071 as.initObjVar(SVFUtil::cast<ObjVar>(
addr->getRHSVar()));
1092 switch (
binary->getOpcode())
1135 assert(
false &&
"undefined binary: ");
1184 auto predicate =
cmp->getPredicate();
1236 assert(
false &&
"undefined compare: ");
1244 auto predicate =
cmp->getPredicate();
1251 if (
lhs.hasIntersect(
rhs))
1255 else if (
lhs.empty() &&
rhs.empty())
1269 if (
lhs.hasIntersect(
rhs))
1273 else if (
lhs.empty() &&
rhs.empty())
1288 if (
lhs.size() == 1 &&
rhs.size() == 1)
1303 if (
lhs.size() == 1 &&
rhs.size() == 1)
1318 if (
lhs.size() == 1 &&
rhs.size() == 1)
1333 if (
lhs.size() == 1 &&
rhs.size() == 1)
1357 assert(
false &&
"undefined compare: ");
1386 auto getZExtValue = [&](
const SVFVar*
var)
1389 if (SVFUtil::isa<SVFIntegerType>(
type))
1393 if (
val.getInterval().is_numeral())
1401 else if (
bits == 16)
1407 else if (
bits == 32)
1413 else if (
bits == 64)
1419 assert(
false &&
"cannot support int type other than u8/16/32/64");
1432 if(
itv.isBottom())
return itv;
1462 assert(
false &&
"cannot support dst int type other than u8/16/32");
1519 assert(
false &&
"undefined copy kind");
static const LoadStmt * findBackingLoad(const SVFVar *var)
static IntervalValue computeCmpConstraint(s32_t predicate, s64_t succ, bool isLHS, const IntervalValue &self, const IntervalValue &other)
void performStat() override
u32_t & getICFGNodeTrace()
const Map< const FunObjVar *, const ICFGWTO * > & getFuncToWTO() const
Accessors for WTO data.
CallGraph * getCallGraph() const
CallGraphSCC * getCallGraphSCC() const
void initWTO()
Build WTO for each function using call graph SCC.
Handles external API calls and manages abstract states.
void handleExtAPI(const CallICFGNode *call)
Handles an external API call.
IntervalValue getRangeLimitFromType(const SVFType *type)
Gets the range limit from a type.
void handleFunction(const ICFGNode *funEntry, const CallICFGNode *caller)
Handle a function body via worklist-driven WTO traversal starting from funEntry.
void updateStateOnCall(const CallPE *callPE)
const FunObjVar * getCallee(const CallICFGNode *callNode)
Get callee function: directly for direct calls, via pointer analysis for indirect calls.
AbstractState & getAbsState(const ICFGNode *node)
void updateStateOnStore(const StoreStmt *store)
virtual void handleFunCall(const CallICFGNode *callNode)
void analyzeFromAllProgEntries()
Analyze all entry points (functions without callers)
void updateStateOnGep(const GepStmt *gep)
bool isCmpBranchEdgeFeasible(const IntraCFGEdge *edge, AbstractState &as)
Returns true if the cmp-conditional branch is feasible.
void analyse()
Program entry.
virtual void handleGlobalNode()
virtual bool hasAbsValue(const ValVar *var, const ICFGNode *node) const
Side-effect-free existence check.
virtual bool isExtCall(const CallICFGNode *callNode)
virtual void runOnModule()
void updateStateOnPhi(const PhiStmt *phi)
bool handleICFGNode(const ICFGNode *node)
Handle an ICFG node: execute statements; return true if state changed.
std::vector< std::unique_ptr< AEDetector > > detectors
virtual AbstractValue loadValue(const ValVar *pointer, const ICFGNode *node)
Virtual so full-sparse can layer the GepObj overlay on top.
virtual void handleExtCall(const CallICFGNode *callNode)
bool isBranchEdgeFeasible(const IntraCFGEdge *edge, AbstractState &as)
AddressValue getGepObjAddrs(const ValVar *pointer, IntervalValue offset)
IntervalValue getGepElementIndex(const GepStmt *gep)
virtual void joinStates(AbstractState &dst, const AbstractState &src)
virtual bool mergeStatesFromPredecessors(const ICFGNode *node)
void updateStateOnSelect(const SelectStmt *select)
virtual void handleSVFStatement(const SVFStmt *stmt)
Dispatch an SVF statement (Addr/Binary/Cmp/Load/Store/Copy/Gep/Select/Phi/Call/Ret) to its handler.
bool skipRecursiveCall(const CallICFGNode *callNode)
Skip recursive callsites (within SCC); entry calls from outside SCC are not skipped.
SVFIR * svfir
Data and helpers reachable from SparseAbstractInterpretation.
virtual void handleLoopOrRecursion(const ICFGCycleWTO *cycle, const CallICFGNode *caller)
Handle a WTO cycle (loop or recursive function) using widening/narrowing iteration.
void updateStateOnAddr(const AddrStmt *addr)
virtual ~AbstractInterpretation()
Destructor.
virtual const AbstractValue & getAbsValue(const ValVar *var, const ICFGNode *node)
virtual void handleCallSite(const ICFGNode *node)
Handle a call site node: dispatch to ext-call, direct-call, or indirect-call handling.
void collectBranchRefinement(const IntraCFGEdge *edge, AbstractState &as)
void updateStateOnRet(const RetPE *retPE)
bool hasAbsState(const ICFGNode *node)
void updateStateOnCopy(const CopyStmt *copy)
FIFOWorkList< const FunObjVar * > collectProgEntryFuns()
Get all entry point functions (functions without callers)
bool isSwitchBranchEdgeFeasible(const IntraCFGEdge *edge, AbstractState &as)
Returns true if the switch branch is feasible.
void updateStateOnLoad(const LoadStmt *load)
void updateStateOnBinary(const BinaryOPStmt *binary)
Map< const ICFGNode *, AbstractState > abstractTrace
per-node trace; owned here
static AbstractInterpretation & getAEInstance()
virtual void recordBranchRefinement(NodeID objId, const IntervalValue &narrowed, AbstractState &as, const ICFGNode *loadIcfg, const ICFGNode *succ)
virtual void updateAbsValue(const ValVar *var, const AbstractValue &val, const ICFGNode *node)
Set< const ICFGNode * > allAnalyzedNodes
virtual void storeValue(const ValVar *pointer, const AbstractValue &val, const ICFGNode *node)
const SVFVar * getSVFVar(NodeID varId) const
Retrieve SVFVar given its ID; asserts if no such variable exists.
void updateStateOnCmp(const CmpStmt *cmp)
virtual void updateAbsState(const ICFGNode *node, const AbstractState &state)
const VarToAbsValMap & getVarToVal() const
get var2val map
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
IntervalValue & getInterval()
s64_t getIntNumeral() const
const FunObjVar * getFunction() const
Get function of this call node.
bool hasIndCSCallees(const CallICFGNode *cs) const
const FunctionSet & getIndCSCallees(const CallICFGNode *cs) const
const CallICFGNode * getOpCallICFGNode(u32_t op_idx) const
Return the CallICFGNode of the i-th operand.
@ ICMP_SGT
signed greater than
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ ICMP_UGE
unsigned greater or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_ULT
unsigned less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_SLE
signed less or equal
bool isDeclaration() const
iterator begin()
Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
const GEdgeSetTy & getInEdges() const
const SVFStmtList & getSVFStmts() const
ICFGEdge * getICFGEdge(const ICFGNode *src, const ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Get a SVFG edge according to src and dst.
void updateCallGraph(CallGraph *callgraph)
update ICFG for indirect calls
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
GlobalICFGNode * getGlobalICFGNode() const
void meet_with(const IntervalValue &other)
Return a intersected IntervalValue.
static BoundedInt minus_infinity()
Get minus infinity -inf.
bool is_zero() const
Return true if the IntervalValue is [0, 0].
static BoundedInt plus_infinity()
Get plus infinity +inf.
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
const BoundedInt & lb() const
Return the lower bound.
const ValVar * getLHSVar() const
const ValVar * getRHSVar() const
const ValVar * getRes() const
Result SVFVar.
const ValVar * getOpVar(u32_t pos) const
Operand SVFVars.
u32_t getOpVarNum() const
static const OptionMap< u32_t > HandleRecur
recursion handling mode, Default: TOP
static const OptionMap< u32_t > AESparsity
static const OptionMap< u32_t > AEFunEntry
static const Option< bool > PStat
const ValVar * getRHSVar() const
const ValVar * getLHSVar() const
const CallSiteToFunPtrMap & getIndirectCallsites() const
Add/get indirect callsites.
const SVFVar * getSVFVar(NodeID id) const
ObjVar/GepObjVar/BaseObjVar.
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
ICFGNode * getICFGNode() const
u32_t getByteSize() const
NodeID getId() const
Get ID.
const ValVar * getRHSVar() const
const ValVar * getLHSVar() const
bool isProgEntryFunction(const FunObjVar *)
Program entry function e.g. main.
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
std::ostream & errs()
Overwrite llvm::errs()
bool isExtCall(const FunObjVar *fun)
WTONode< ICFG > ICFGSingletonWTO
llvm::IRBuilder IRBuilder
WTOComponent< ICFG > ICFGWTOComp