svf-tools 1.0.983 → 1.0.985
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/svf/include/AE/Svfexe/AbstractInterpretation.h +1 -1
- package/svf/include/CFL/CFLAlias.h +3 -3
- package/svf/include/Graphs/CHG.h +13 -31
- package/svf/include/Graphs/ICFG.h +2 -2
- package/svf/include/Graphs/ICFGEdge.h +4 -16
- package/svf/include/Graphs/ICFGNode.h +58 -0
- package/svf/include/Graphs/ThreadCallGraph.h +6 -6
- package/svf/include/MTA/MHP.h +3 -3
- package/svf/include/MTA/TCT.h +1 -1
- package/svf/include/SVFIR/SVFFileSystem.h +0 -2
- package/svf/include/SVFIR/SVFValue.h +0 -131
- package/svf/include/Util/SVFUtil.h +20 -37
- package/svf/include/Util/ThreadAPI.h +5 -26
- package/svf/include/WPA/Andersen.h +3 -3
- package/svf/include/WPA/Steensgaard.h +3 -3
- package/svf/include/WPA/WPAPass.h +3 -3
- package/svf/lib/AE/Svfexe/AEDetector.cpp +14 -18
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +66 -94
- package/svf/lib/CFL/CFLAlias.cpp +11 -12
- package/svf/lib/DDA/DDAClient.cpp +2 -2
- package/svf/lib/Graphs/CHG.cpp +33 -9
- package/svf/lib/Graphs/ICFG.cpp +13 -10
- package/svf/lib/MSSA/MemRegion.cpp +3 -3
- package/svf/lib/MTA/MHP.cpp +1 -1
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +21 -23
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +2 -2
- package/svf/lib/SABER/SaberCondAllocator.cpp +1 -1
- package/svf/lib/SABER/SaberSVFGBuilder.cpp +1 -1
- package/svf/lib/SVFIR/SVFFileSystem.cpp +2 -20
- package/svf/lib/Util/SVFUtil.cpp +34 -18
- package/svf/lib/Util/ThreadAPI.cpp +32 -15
- package/svf/lib/WPA/Andersen.cpp +8 -9
- package/svf/lib/WPA/AndersenSCD.cpp +1 -2
- package/svf/lib/WPA/Steensgaard.cpp +8 -12
- package/svf/lib/WPA/TypeAnalysis.cpp +2 -3
- package/svf/lib/WPA/WPAPass.cpp +6 -13
- package/svf-llvm/include/SVF-LLVM/DCHG.h +7 -7
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +0 -8
- package/svf-llvm/lib/CHGBuilder.cpp +4 -4
- package/svf-llvm/lib/DCHG.cpp +8 -7
- package/svf-llvm/lib/ICFGBuilder.cpp +2 -2
- package/svf-llvm/lib/LLVMModule.cpp +0 -2
- package/svf-llvm/lib/LLVMUtil.cpp +0 -58
- package/svf-llvm/lib/SVFIRExtAPI.cpp +2 -2
package/svf/lib/Graphs/CHG.cpp
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
#include "Graphs/CHG.h"
|
|
31
31
|
#include "Util/SVFUtil.h"
|
|
32
|
+
#include "Graphs/ICFG.h"
|
|
32
33
|
|
|
33
34
|
using namespace SVF;
|
|
34
35
|
using namespace SVFUtil;
|
|
@@ -48,16 +49,16 @@ static bool hasEdge(const CHNode *src, const CHNode *dst,
|
|
|
48
49
|
return false;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
static bool checkArgTypes(
|
|
52
|
+
static bool checkArgTypes(const SVFCallInst* cs, const SVFFunction* fn)
|
|
52
53
|
{
|
|
53
54
|
|
|
54
55
|
// here we skip the first argument (i.e., this pointer)
|
|
55
|
-
u32_t arg_size = (fn->arg_size() > cs
|
|
56
|
+
u32_t arg_size = (fn->arg_size() > cs->arg_size()) ? cs->arg_size(): fn->arg_size();
|
|
56
57
|
if(arg_size > 1)
|
|
57
58
|
{
|
|
58
59
|
for (unsigned i = 1; i < arg_size; i++)
|
|
59
60
|
{
|
|
60
|
-
auto cs_arg = cs
|
|
61
|
+
auto cs_arg = cs->getArgOperand(i);
|
|
61
62
|
auto fn_arg = fn->getArg(i);
|
|
62
63
|
if (cs_arg->getType() != fn_arg->getType())
|
|
63
64
|
{
|
|
@@ -69,6 +70,29 @@ static bool checkArgTypes(CallSite cs, const SVFFunction* fn)
|
|
|
69
70
|
return true;
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
bool CHGraph::csHasVtblsBasedonCHA(const CallICFGNode* cs)
|
|
74
|
+
{
|
|
75
|
+
CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs->getCallSite());
|
|
76
|
+
return it != csToCHAVtblsMap.end();
|
|
77
|
+
}
|
|
78
|
+
bool CHGraph::csHasVFnsBasedonCHA(const CallICFGNode* cs)
|
|
79
|
+
{
|
|
80
|
+
CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs->getCallSite());
|
|
81
|
+
return it != csToCHAVFnsMap.end();
|
|
82
|
+
}
|
|
83
|
+
const VTableSet& CHGraph::getCSVtblsBasedonCHA(const CallICFGNode* cs)
|
|
84
|
+
{
|
|
85
|
+
CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs->getCallSite());
|
|
86
|
+
assert(it != csToCHAVtblsMap.end() && "cs does not have vtabls based on CHA.");
|
|
87
|
+
return it->second;
|
|
88
|
+
}
|
|
89
|
+
const VFunSet& CHGraph::getCSVFsBasedonCHA(const CallICFGNode* cs)
|
|
90
|
+
{
|
|
91
|
+
CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs->getCallSite());
|
|
92
|
+
assert(it != csToCHAVFnsMap.end() && "cs does not have vfns based on CHA.");
|
|
93
|
+
return it->second;
|
|
94
|
+
}
|
|
95
|
+
|
|
72
96
|
void CHGraph::addEdge(const string className, const string baseClassName,
|
|
73
97
|
CHEdge::CHEDGETYPE edgeType)
|
|
74
98
|
{
|
|
@@ -96,13 +120,13 @@ CHNode *CHGraph::getNode(const string name) const
|
|
|
96
120
|
* Get virtual functions for callsite "cs" based on vtbls (calculated
|
|
97
121
|
* based on pointsto set)
|
|
98
122
|
*/
|
|
99
|
-
void CHGraph::getVFnsFromVtbls(
|
|
123
|
+
void CHGraph::getVFnsFromVtbls(const SVFCallInst* callsite, const VTableSet &vtbls, VFunSet &virtualFunctions)
|
|
100
124
|
{
|
|
101
|
-
|
|
125
|
+
const SVFVirtualCallInst* cs = SVFUtil::cast<SVFVirtualCallInst>(callsite);
|
|
102
126
|
/// get target virtual functions
|
|
103
|
-
size_t idx = cs
|
|
127
|
+
size_t idx = cs->getFunIdxInVtable();
|
|
104
128
|
/// get the function name of the virtual callsite
|
|
105
|
-
string funName = cs
|
|
129
|
+
string funName = cs->getFunNameOfVirtualCall();
|
|
106
130
|
for (const SVFGlobalValue *vt : vtbls)
|
|
107
131
|
{
|
|
108
132
|
const CHNode *child = getNode(vt->getName());
|
|
@@ -114,8 +138,8 @@ void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &vir
|
|
|
114
138
|
feit = vfns.end(); fit != feit; ++fit)
|
|
115
139
|
{
|
|
116
140
|
const SVFFunction* callee = *fit;
|
|
117
|
-
if (cs
|
|
118
|
-
(cs
|
|
141
|
+
if (cs->arg_size() == callee->arg_size() ||
|
|
142
|
+
(cs->isVarArg() && callee->isVarArg()))
|
|
119
143
|
{
|
|
120
144
|
|
|
121
145
|
// if argument types do not match
|
package/svf/lib/Graphs/ICFG.cpp
CHANGED
|
@@ -179,7 +179,7 @@ const std::string CallCFGEdge::toString() const
|
|
|
179
179
|
std::string str;
|
|
180
180
|
std::stringstream rawstr(str);
|
|
181
181
|
rawstr << "CallCFGEdge " << " [ICFGNode";
|
|
182
|
-
rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " <<
|
|
182
|
+
rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << getSrcNode()->toString() << "\t";
|
|
183
183
|
return rawstr.str();
|
|
184
184
|
}
|
|
185
185
|
|
|
@@ -188,7 +188,7 @@ const std::string RetCFGEdge::toString() const
|
|
|
188
188
|
std::string str;
|
|
189
189
|
std::stringstream rawstr(str);
|
|
190
190
|
rawstr << "RetCFGEdge " << " [ICFGNode";
|
|
191
|
-
rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " <<
|
|
191
|
+
rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << getDstNode()->toString() << "\t";
|
|
192
192
|
return rawstr.str();
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -438,7 +438,7 @@ ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, co
|
|
|
438
438
|
/*!
|
|
439
439
|
* Add interprocedural call edges between two nodes
|
|
440
440
|
*/
|
|
441
|
-
ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode
|
|
441
|
+
ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode)
|
|
442
442
|
{
|
|
443
443
|
ICFGEdge* edge = hasInterICFGEdge(srcNode,dstNode, ICFGEdge::CallCF);
|
|
444
444
|
if (edge != nullptr)
|
|
@@ -448,7 +448,7 @@ ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstr
|
|
|
448
448
|
}
|
|
449
449
|
else
|
|
450
450
|
{
|
|
451
|
-
CallCFGEdge* callEdge = new CallCFGEdge(srcNode,dstNode
|
|
451
|
+
CallCFGEdge* callEdge = new CallCFGEdge(srcNode,dstNode);
|
|
452
452
|
return (addICFGEdge(callEdge) ? callEdge : nullptr);
|
|
453
453
|
}
|
|
454
454
|
}
|
|
@@ -456,7 +456,7 @@ ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstr
|
|
|
456
456
|
/*!
|
|
457
457
|
* Add interprocedural return edges between two nodes
|
|
458
458
|
*/
|
|
459
|
-
ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode
|
|
459
|
+
ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode)
|
|
460
460
|
{
|
|
461
461
|
ICFGEdge* edge = hasInterICFGEdge(srcNode, dstNode, ICFGEdge::RetCF);
|
|
462
462
|
if (edge != nullptr)
|
|
@@ -466,7 +466,7 @@ ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstru
|
|
|
466
466
|
}
|
|
467
467
|
else
|
|
468
468
|
{
|
|
469
|
-
RetCFGEdge* retEdge = new RetCFGEdge(srcNode,dstNode
|
|
469
|
+
RetCFGEdge* retEdge = new RetCFGEdge(srcNode,dstNode);
|
|
470
470
|
return (addICFGEdge(retEdge) ? retEdge : nullptr);
|
|
471
471
|
}
|
|
472
472
|
}
|
|
@@ -513,7 +513,7 @@ void ICFG::updateCallGraph(CallGraph* callgraph)
|
|
|
513
513
|
{
|
|
514
514
|
FunEntryICFGNode* calleeEntryNode = getFunEntryBlock(callee);
|
|
515
515
|
FunExitICFGNode* calleeExitNode = getFunExitBlock(callee);
|
|
516
|
-
if(ICFGEdge* callEdge = addCallEdge(callBlockNode, calleeEntryNode
|
|
516
|
+
if(ICFGEdge* callEdge = addCallEdge(callBlockNode, calleeEntryNode))
|
|
517
517
|
{
|
|
518
518
|
for (const SVFStmt *stmt : callBlockNode->getSVFStmts())
|
|
519
519
|
{
|
|
@@ -524,7 +524,7 @@ void ICFG::updateCallGraph(CallGraph* callgraph)
|
|
|
524
524
|
}
|
|
525
525
|
}
|
|
526
526
|
}
|
|
527
|
-
if(ICFGEdge* retEdge = addRetEdge(calleeExitNode, retBlockNode
|
|
527
|
+
if(ICFGEdge* retEdge = addRetEdge(calleeExitNode, retBlockNode))
|
|
528
528
|
{
|
|
529
529
|
for (const SVFStmt *stmt : retBlockNode->getSVFStmts())
|
|
530
530
|
{
|
|
@@ -650,9 +650,12 @@ struct DOTGraphTraits<ICFG*> : public DOTGraphTraits<SVFIR*>
|
|
|
650
650
|
std::string str;
|
|
651
651
|
std::stringstream rawstr(str);
|
|
652
652
|
if (CallCFGEdge* dirCall = SVFUtil::dyn_cast<CallCFGEdge>(edge))
|
|
653
|
-
rawstr << dirCall->
|
|
653
|
+
rawstr << dirCall->getSrcNode();
|
|
654
654
|
else if (RetCFGEdge* dirRet = SVFUtil::dyn_cast<RetCFGEdge>(edge))
|
|
655
|
-
|
|
655
|
+
{
|
|
656
|
+
if(RetICFGNode* ret = SVFUtil::dyn_cast<RetICFGNode>(dirRet->getDstNode()))
|
|
657
|
+
rawstr << ret->getCallICFGNode();
|
|
658
|
+
}
|
|
656
659
|
|
|
657
660
|
return rawstr.str();
|
|
658
661
|
}
|
|
@@ -601,7 +601,7 @@ bool MRGenerator::isNonLocalObject(NodeID id, const SVFFunction* curFun) const
|
|
|
601
601
|
bool MRGenerator::handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGNode* cs, const SVFFunction* callee)
|
|
602
602
|
{
|
|
603
603
|
/// if a callee is a heap allocator function, then its mod set of this callsite is the heap object.
|
|
604
|
-
if(isHeapAllocExtCall(cs
|
|
604
|
+
if(isHeapAllocExtCall(cs))
|
|
605
605
|
{
|
|
606
606
|
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
|
|
607
607
|
for (SVFStmtList::const_iterator bit = pagEdgeList.begin(),
|
|
@@ -667,7 +667,7 @@ void MRGenerator::modRefAnalysis(CallGraphNode* callGraphNode, WorkList& worklis
|
|
|
667
667
|
*/
|
|
668
668
|
NodeBS MRGenerator::getModInfoForCall(const CallICFGNode* cs)
|
|
669
669
|
{
|
|
670
|
-
if (isExtCall(cs
|
|
670
|
+
if (isExtCall(cs) && !isHeapAllocExtCall(cs))
|
|
671
671
|
{
|
|
672
672
|
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
|
|
673
673
|
NodeBS mods;
|
|
@@ -691,7 +691,7 @@ NodeBS MRGenerator::getModInfoForCall(const CallICFGNode* cs)
|
|
|
691
691
|
*/
|
|
692
692
|
NodeBS MRGenerator::getRefInfoForCall(const CallICFGNode* cs)
|
|
693
693
|
{
|
|
694
|
-
if (isExtCall(cs
|
|
694
|
+
if (isExtCall(cs) && !isHeapAllocExtCall(cs))
|
|
695
695
|
{
|
|
696
696
|
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
|
|
697
697
|
NodeBS refs;
|
package/svf/lib/MTA/MHP.cpp
CHANGED
|
@@ -819,7 +819,7 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
819
819
|
const ICFGNode* forkSite = tct->getTCTNode(rootTid)->getCxtThread().getThread();
|
|
820
820
|
const ICFGNode* joinSite = cts.getStmt();
|
|
821
821
|
|
|
822
|
-
if (isAliasedForkJoin(forkSite, joinSite))
|
|
822
|
+
if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite), SVFUtil::cast<CallICFGNode>(joinSite)))
|
|
823
823
|
{
|
|
824
824
|
if (hasJoinLoop(joinSite))
|
|
825
825
|
{
|
|
@@ -320,8 +320,8 @@ void PointerAnalysis::printIndCSTargets(const CallICFGNode* cs, const FunctionSe
|
|
|
320
320
|
{
|
|
321
321
|
outs() << "\nNodeID: " << getFunPtr(cs);
|
|
322
322
|
outs() << "\nCallSite: ";
|
|
323
|
-
outs() << cs->
|
|
324
|
-
outs() << "\tLocation: " << cs->
|
|
323
|
+
outs() << cs->toString();
|
|
324
|
+
outs() << "\tLocation: " << cs->getSourceLoc();
|
|
325
325
|
outs() << "\t with Targets: ";
|
|
326
326
|
|
|
327
327
|
if (!targets.empty())
|
|
@@ -368,8 +368,8 @@ void PointerAnalysis::printIndCSTargets()
|
|
|
368
368
|
{
|
|
369
369
|
outs() << "\nNodeID: " << csIt->second;
|
|
370
370
|
outs() << "\nCallSite: ";
|
|
371
|
-
outs() << cs->
|
|
372
|
-
outs() << "\tLocation: " << cs->
|
|
371
|
+
outs() << cs->toString();
|
|
372
|
+
outs() << "\tLocation: " << cs->getSourceLoc();
|
|
373
373
|
outs() << "\n\t!!!has no targets!!!\n";
|
|
374
374
|
}
|
|
375
375
|
}
|
|
@@ -428,8 +428,8 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta
|
|
|
428
428
|
*/
|
|
429
429
|
void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns)
|
|
430
430
|
{
|
|
431
|
-
if (chgraph->csHasVFnsBasedonCHA(
|
|
432
|
-
vfns = chgraph->getCSVFsBasedonCHA(
|
|
431
|
+
if (chgraph->csHasVFnsBasedonCHA(cs))
|
|
432
|
+
vfns = chgraph->getCSVFsBasedonCHA(cs);
|
|
433
433
|
}
|
|
434
434
|
|
|
435
435
|
/*
|
|
@@ -438,10 +438,10 @@ void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns)
|
|
|
438
438
|
void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &target, VFunSet &vfns)
|
|
439
439
|
{
|
|
440
440
|
|
|
441
|
-
if (chgraph->csHasVtblsBasedonCHA(
|
|
441
|
+
if (chgraph->csHasVtblsBasedonCHA(cs))
|
|
442
442
|
{
|
|
443
443
|
Set<const SVFGlobalValue*> vtbls;
|
|
444
|
-
const VTableSet &chaVtbls = chgraph->getCSVtblsBasedonCHA(
|
|
444
|
+
const VTableSet &chaVtbls = chgraph->getCSVtblsBasedonCHA(cs);
|
|
445
445
|
for (PointsTo::iterator it = target.begin(), eit = target.end(); it != eit; ++it)
|
|
446
446
|
{
|
|
447
447
|
const PAGNode *ptdnode = pag->getGNode(*it);
|
|
@@ -454,7 +454,7 @@ void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &tar
|
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
|
-
chgraph->getVFnsFromVtbls(SVFUtil::
|
|
457
|
+
chgraph->getVFnsFromVtbls(SVFUtil::cast<SVFCallInst>(cs->getCallSite()), vtbls, vfns);
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
460
|
|
|
@@ -471,12 +471,12 @@ void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet &
|
|
|
471
471
|
callee = callee->getDefFunForMultipleModule();
|
|
472
472
|
if (getIndCallMap()[cs].count(callee) > 0)
|
|
473
473
|
continue;
|
|
474
|
-
if(
|
|
475
|
-
(
|
|
474
|
+
if(cs->arg_size() == callee->arg_size() ||
|
|
475
|
+
(cs->isVarArg() && callee->isVarArg()))
|
|
476
476
|
{
|
|
477
477
|
newEdges[cs].insert(callee);
|
|
478
478
|
getIndCallMap()[cs].insert(callee);
|
|
479
|
-
const CallICFGNode* callBlockNode =
|
|
479
|
+
const CallICFGNode* callBlockNode = cs;
|
|
480
480
|
callgraph->addIndirectCallGraphEdge(callBlockNode, cs->getCaller(),callee);
|
|
481
481
|
}
|
|
482
482
|
}
|
|
@@ -485,7 +485,7 @@ void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet &
|
|
|
485
485
|
/// Resolve cpp indirect call edges
|
|
486
486
|
void PointerAnalysis::resolveCPPIndCalls(const CallICFGNode* cs, const PointsTo& target, CallEdgeMap& newEdges)
|
|
487
487
|
{
|
|
488
|
-
assert(
|
|
488
|
+
assert(cs->isVirtualCall() && "not cpp virtual call");
|
|
489
489
|
|
|
490
490
|
VFunSet vfns;
|
|
491
491
|
if (Options::ConnectVCallOnCHA())
|
|
@@ -511,11 +511,10 @@ void PointerAnalysis::validateSuccessTests(std::string fun)
|
|
|
511
511
|
{
|
|
512
512
|
if (SVFUtil::getCallee(callNode) == checkFun)
|
|
513
513
|
{
|
|
514
|
-
|
|
515
|
-
assert(cs.getNumArgOperands() == 2
|
|
514
|
+
assert(callNode->getNumArgOperands() == 2
|
|
516
515
|
&& "arguments should be two pointers!!");
|
|
517
|
-
const SVFValue* V1 =
|
|
518
|
-
const SVFValue* V2 =
|
|
516
|
+
const SVFValue* V1 = callNode->getArgOperand(0);
|
|
517
|
+
const SVFValue* V2 = callNode->getArgOperand(1);
|
|
519
518
|
AliasResult aliasRes = alias(V1, V2);
|
|
520
519
|
|
|
521
520
|
bool checkSuccessful = false;
|
|
@@ -577,11 +576,10 @@ void PointerAnalysis::validateExpectedFailureTests(std::string fun)
|
|
|
577
576
|
{
|
|
578
577
|
if (SVFUtil::getCallee(callNode) == checkFun)
|
|
579
578
|
{
|
|
580
|
-
|
|
581
|
-
assert(call.arg_size() == 2
|
|
579
|
+
assert(callNode->arg_size() == 2
|
|
582
580
|
&& "arguments should be two pointers!!");
|
|
583
|
-
const SVFValue* V1 =
|
|
584
|
-
const SVFValue* V2 =
|
|
581
|
+
const SVFValue* V1 = callNode->getArgOperand(0);
|
|
582
|
+
const SVFValue* V2 = callNode->getArgOperand(1);
|
|
585
583
|
AliasResult aliasRes = alias(V1, V2);
|
|
586
584
|
|
|
587
585
|
bool expectedFailure = false;
|
|
@@ -605,11 +603,11 @@ void PointerAnalysis::validateExpectedFailureTests(std::string fun)
|
|
|
605
603
|
|
|
606
604
|
if (expectedFailure)
|
|
607
605
|
outs() << sucMsg("\t EXPECTED-FAILURE :") << fun << " check <id:" << id1 << ", id:" << id2 << "> at ("
|
|
608
|
-
<<
|
|
606
|
+
<< callNode->getSourceLoc() << ")\n";
|
|
609
607
|
else
|
|
610
608
|
{
|
|
611
609
|
SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << fun << " check <id:" << id1 << ", id:" << id2 << "> at ("
|
|
612
|
-
<<
|
|
610
|
+
<< callNode->getSourceLoc() << ")\n";
|
|
613
611
|
assert(false && "test case failed!");
|
|
614
612
|
}
|
|
615
613
|
}
|
|
@@ -495,9 +495,9 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,
|
|
|
495
495
|
{
|
|
496
496
|
const CallICFGNode* cs = iter->first;
|
|
497
497
|
|
|
498
|
-
if (
|
|
498
|
+
if (cs->isVirtualCall())
|
|
499
499
|
{
|
|
500
|
-
const SVFValue* vtbl =
|
|
500
|
+
const SVFValue* vtbl = cs->getVtablePtr();
|
|
501
501
|
assert(pag->hasValueNode(vtbl));
|
|
502
502
|
NodeID vtblId = pag->getValueNode(vtbl);
|
|
503
503
|
resolveCPPIndCalls(cs, getPts(vtblId), newEdges);
|
|
@@ -428,7 +428,7 @@ void SaberCondAllocator::collectBBCallingProgExit(const SVFBasicBlock &bb)
|
|
|
428
428
|
for (const auto& icfgNode: bb.getICFGNodeList())
|
|
429
429
|
{
|
|
430
430
|
if (const CallICFGNode* cs = SVFUtil::dyn_cast<CallICFGNode>(icfgNode))
|
|
431
|
-
if (SVFUtil::isProgExitCall(cs
|
|
431
|
+
if (SVFUtil::isProgExitCall(cs))
|
|
432
432
|
{
|
|
433
433
|
const SVFFunction* svfun = bb.getParent();
|
|
434
434
|
funToExitBBsMap[svfun].insert(&bb);
|
|
@@ -138,7 +138,7 @@ PointsTo& SaberSVFGBuilder::CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeT
|
|
|
138
138
|
if(pta->isFIObjNode(baseId) && pag->getGNode(baseId)->hasValue())
|
|
139
139
|
{
|
|
140
140
|
const SVFCallInst* inst = SVFUtil::dyn_cast<SVFCallInst>(pag->getGNode(baseId)->getValue());
|
|
141
|
-
if(inst && SVFUtil::isExtCall(inst))
|
|
141
|
+
if(inst && SVFUtil::isExtCall(pag->getICFG()->getCallICFGNode(inst)))
|
|
142
142
|
{
|
|
143
143
|
return pts;
|
|
144
144
|
}
|
|
@@ -443,7 +443,6 @@ cJSON* SVFIRWriter::contentToJson(const IntraCFGEdge* edge)
|
|
|
443
443
|
cJSON* SVFIRWriter::contentToJson(const CallCFGEdge* edge)
|
|
444
444
|
{
|
|
445
445
|
cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
|
|
446
|
-
JSON_WRITE_FIELD(root, edge, cs);
|
|
447
446
|
JSON_WRITE_FIELD(root, edge, callPEs);
|
|
448
447
|
return root;
|
|
449
448
|
}
|
|
@@ -451,7 +450,6 @@ cJSON* SVFIRWriter::contentToJson(const CallCFGEdge* edge)
|
|
|
451
450
|
cJSON* SVFIRWriter::contentToJson(const RetCFGEdge* edge)
|
|
452
451
|
{
|
|
453
452
|
cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
|
|
454
|
-
JSON_WRITE_FIELD(root, edge, cs);
|
|
455
453
|
JSON_WRITE_FIELD(root, edge, retPE);
|
|
456
454
|
return root;
|
|
457
455
|
}
|
|
@@ -571,8 +569,6 @@ cJSON* SVFIRWriter::contentToJson(const SVFInstruction* value)
|
|
|
571
569
|
JSON_WRITE_FIELD(root, value, bb);
|
|
572
570
|
JSON_WRITE_FIELD(root, value, terminator);
|
|
573
571
|
JSON_WRITE_FIELD(root, value, ret);
|
|
574
|
-
JSON_WRITE_FIELD(root, value, succInsts);
|
|
575
|
-
JSON_WRITE_FIELD(root, value, predInsts);
|
|
576
572
|
return root;
|
|
577
573
|
}
|
|
578
574
|
|
|
@@ -1179,11 +1175,6 @@ cJSON* SVFIRWriter::toJson(const CHEdge* edge)
|
|
|
1179
1175
|
return jsonCreateIndex(chgWriter.getEdgeID(edge));
|
|
1180
1176
|
}
|
|
1181
1177
|
|
|
1182
|
-
cJSON* SVFIRWriter::toJson(const CallSite& cs)
|
|
1183
|
-
{
|
|
1184
|
-
return toJson(cs.getInstruction());
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
1178
|
cJSON* SVFIRWriter::toJson(const SVFLoop* loop)
|
|
1188
1179
|
{
|
|
1189
1180
|
return jsonCreateIndex(icfgWriter.getSvfLoopID(loop));
|
|
@@ -1613,9 +1604,9 @@ ICFGEdge* SVFIRReader::createICFGEdge(GEdgeKind kind)
|
|
|
1613
1604
|
case ICFGEdge::IntraCF:
|
|
1614
1605
|
return new IntraCFGEdge(src, dst);
|
|
1615
1606
|
case ICFGEdge::CallCF:
|
|
1616
|
-
return new CallCFGEdge(src, dst
|
|
1607
|
+
return new CallCFGEdge(src, dst);
|
|
1617
1608
|
case ICFGEdge::RetCF:
|
|
1618
|
-
return new RetCFGEdge(src, dst
|
|
1609
|
+
return new RetCFGEdge(src, dst);
|
|
1619
1610
|
}
|
|
1620
1611
|
}
|
|
1621
1612
|
|
|
@@ -1855,11 +1846,6 @@ void SVFIRReader::readJson(const cJSON* obj, CHEdge*& edge)
|
|
|
1855
1846
|
edge = chGraphReader.getEdgePtr(jsonGetNumber(obj));
|
|
1856
1847
|
}
|
|
1857
1848
|
|
|
1858
|
-
void SVFIRReader::readJson(const cJSON* obj, CallSite& cs)
|
|
1859
|
-
{
|
|
1860
|
-
readJson(obj, cs.CB);
|
|
1861
|
-
}
|
|
1862
|
-
|
|
1863
1849
|
void SVFIRReader::readJson(const cJSON* obj, AccessPath& ap)
|
|
1864
1850
|
{
|
|
1865
1851
|
ABORT_IFNOT(jsonIsObject(obj), "Expected obj for AccessPath");
|
|
@@ -2270,14 +2256,12 @@ void SVFIRReader::fill(const cJSON*& fieldJson, IntraCFGEdge* edge)
|
|
|
2270
2256
|
void SVFIRReader::fill(const cJSON*& fieldJson, CallCFGEdge* edge)
|
|
2271
2257
|
{
|
|
2272
2258
|
fill(fieldJson, static_cast<ICFGEdge*>(edge));
|
|
2273
|
-
JSON_READ_FIELD_FWD(fieldJson, edge, cs);
|
|
2274
2259
|
JSON_READ_FIELD_FWD(fieldJson, edge, callPEs);
|
|
2275
2260
|
}
|
|
2276
2261
|
|
|
2277
2262
|
void SVFIRReader::fill(const cJSON*& fieldJson, RetCFGEdge* edge)
|
|
2278
2263
|
{
|
|
2279
2264
|
fill(fieldJson, static_cast<ICFGEdge*>(edge));
|
|
2280
|
-
JSON_READ_FIELD_FWD(fieldJson, edge, cs);
|
|
2281
2265
|
JSON_READ_FIELD_FWD(fieldJson, edge, retPE);
|
|
2282
2266
|
}
|
|
2283
2267
|
|
|
@@ -2391,8 +2375,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, SVFInstruction* value)
|
|
|
2391
2375
|
JSON_READ_FIELD_FWD(fieldJson, value, bb);
|
|
2392
2376
|
JSON_READ_FIELD_FWD(fieldJson, value, terminator);
|
|
2393
2377
|
JSON_READ_FIELD_FWD(fieldJson, value, ret);
|
|
2394
|
-
JSON_READ_FIELD_FWD(fieldJson, value, succInsts);
|
|
2395
|
-
JSON_READ_FIELD_FWD(fieldJson, value, predInsts);
|
|
2396
2378
|
}
|
|
2397
2379
|
|
|
2398
2380
|
void SVFIRReader::fill(const cJSON*& fieldJson, SVFCallInst* value)
|
package/svf/lib/Util/SVFUtil.cpp
CHANGED
|
@@ -319,11 +319,10 @@ void SVFUtil::stopAnalysisLimitTimer(bool limitTimerSet)
|
|
|
319
319
|
/// for variadic function, callsite arg size must be greater than or equal to callee arg size
|
|
320
320
|
bool SVFUtil::matchArgs(const CallICFGNode* call, const SVFFunction* callee)
|
|
321
321
|
{
|
|
322
|
-
CallSite cs(call->getCallSite());
|
|
323
322
|
if (callee->isVarArg() || ThreadAPI::getThreadAPI()->isTDFork(call))
|
|
324
|
-
return
|
|
323
|
+
return call->arg_size() >= callee->arg_size();
|
|
325
324
|
else
|
|
326
|
-
return
|
|
325
|
+
return call->arg_size() == callee->arg_size();
|
|
327
326
|
}
|
|
328
327
|
|
|
329
328
|
bool SVFUtil::isCallSite(const ICFGNode* inst)
|
|
@@ -331,19 +330,11 @@ bool SVFUtil::isCallSite(const ICFGNode* inst)
|
|
|
331
330
|
return SVFUtil::isa<CallICFGNode>(inst);
|
|
332
331
|
}
|
|
333
332
|
|
|
334
|
-
CallSite SVFUtil::getSVFCallSite(const ICFGNode* inst)
|
|
335
|
-
{
|
|
336
|
-
assert(isCallSite(inst) && "not a callsite?");
|
|
337
|
-
CallSite cs(cast<CallICFGNode>(inst)->getCallSite());
|
|
338
|
-
return cs;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
333
|
bool SVFUtil::isIntrinsicInst(const ICFGNode* inst)
|
|
342
334
|
{
|
|
343
335
|
if (const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst))
|
|
344
336
|
{
|
|
345
|
-
|
|
346
|
-
const SVFFunction* func = cs.getCalledFunction();
|
|
337
|
+
const SVFFunction* func = call->getCalledFunction();
|
|
347
338
|
if (func && func->isIntrinsic())
|
|
348
339
|
{
|
|
349
340
|
return true;
|
|
@@ -356,22 +347,47 @@ const SVFFunction* SVFUtil::getCallee(const ICFGNode *inst)
|
|
|
356
347
|
{
|
|
357
348
|
if (!isCallSite(inst))
|
|
358
349
|
return nullptr;
|
|
359
|
-
|
|
360
|
-
return
|
|
350
|
+
const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(inst);
|
|
351
|
+
return call->getCalledFunction();
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const SVFFunction* SVFUtil::getCallee(const CallICFGNode *inst)
|
|
355
|
+
{
|
|
356
|
+
return inst->getCalledFunction();
|
|
361
357
|
}
|
|
362
358
|
|
|
359
|
+
|
|
363
360
|
bool SVFUtil::isExtCall(const ICFGNode* node)
|
|
364
361
|
{
|
|
365
362
|
if(!isCallSite(node)) return false;
|
|
366
|
-
|
|
367
|
-
return isExtCall(getCallee(cs));
|
|
363
|
+
return isExtCall(getCallee(node));
|
|
368
364
|
}
|
|
369
365
|
|
|
370
366
|
bool SVFUtil::isHeapAllocExtCall(const ICFGNode* cs)
|
|
371
367
|
{
|
|
372
368
|
if(!isCallSite(cs)) return false;
|
|
373
|
-
|
|
374
|
-
|
|
369
|
+
return isHeapAllocExtCallViaRet(cast<CallICFGNode>(cs)) || isHeapAllocExtCallViaArg(cast<CallICFGNode>(cs));
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
bool SVFUtil::isHeapAllocExtCallViaRet(const CallICFGNode* cs)
|
|
373
|
+
{
|
|
374
|
+
bool isPtrTy = cs->getCallSite()->getType()->isPointerTy();
|
|
375
|
+
return isPtrTy && isHeapAllocExtFunViaRet(getCallee(cs));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
bool SVFUtil::isReallocExtCall(const CallICFGNode* cs)
|
|
379
|
+
{
|
|
380
|
+
bool isPtrTy = cs->getCallSite()->getType()->isPointerTy();
|
|
381
|
+
return isPtrTy && isReallocExtFun(getCallee(cs));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
bool SVFUtil::isHeapAllocExtCallViaRet(const SVFInstruction *inst)
|
|
385
|
+
{
|
|
386
|
+
bool isPtrTy = inst->getType()->isPointerTy();
|
|
387
|
+
if(const SVFCallInst* call = SVFUtil::dyn_cast<SVFCallInst>(inst))
|
|
388
|
+
return isPtrTy && isHeapAllocExtFunViaRet(call->getCalledFunction());
|
|
389
|
+
else
|
|
390
|
+
return false;
|
|
375
391
|
}
|
|
376
392
|
|
|
377
393
|
bool SVFUtil::isRetInstNode(const ICFGNode* node)
|
|
@@ -129,6 +129,32 @@ void ThreadAPI::init()
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
const SVFValue* ThreadAPI::getForkedThread(const CallICFGNode *inst) const
|
|
133
|
+
{
|
|
134
|
+
assert(isTDFork(inst) && "not a thread fork function!");
|
|
135
|
+
return inst->getArgument(0);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const SVFValue* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
|
|
139
|
+
{
|
|
140
|
+
assert(isTDFork(inst) && "not a thread fork function!");
|
|
141
|
+
return inst->getArgument(2);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/// Return the forth argument of the call,
|
|
145
|
+
/// Note that, it is the sole argument of start routine ( a void* pointer )
|
|
146
|
+
const SVFValue* ThreadAPI::getActualParmAtForkSite(const CallICFGNode *inst) const
|
|
147
|
+
{
|
|
148
|
+
assert(isTDFork(inst) && "not a thread fork function!");
|
|
149
|
+
return inst->getArgument(3);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const SVFValue* ThreadAPI::getRetParmAtJoinedSite(const CallICFGNode *inst) const
|
|
153
|
+
{
|
|
154
|
+
assert(isTDJoin(inst) && "not a thread join function!");
|
|
155
|
+
return inst->getArgument(1);
|
|
156
|
+
}
|
|
157
|
+
|
|
132
158
|
/*!
|
|
133
159
|
*
|
|
134
160
|
*/
|
|
@@ -140,27 +166,18 @@ const SVFFunction* ThreadAPI::getCallee(const ICFGNode *inst) const
|
|
|
140
166
|
return nullptr;
|
|
141
167
|
}
|
|
142
168
|
|
|
143
|
-
const
|
|
169
|
+
const SVFValue* ThreadAPI::getLockVal(const ICFGNode *cs) const
|
|
144
170
|
{
|
|
145
|
-
|
|
146
|
-
CallSite cs(SVFUtil::cast<CallICFGNode>(inst)->getCallSite());
|
|
147
|
-
return cs;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const SVFValue* ThreadAPI::getLockVal(const ICFGNode *inst) const
|
|
151
|
-
{
|
|
152
|
-
const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst);
|
|
171
|
+
const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cs);
|
|
153
172
|
assert(call && "not a call ICFGNode?");
|
|
154
173
|
assert((isTDAcquire(call) || isTDRelease(call)) && "not a lock acquire or release function");
|
|
155
|
-
|
|
156
|
-
return cs.getArgument(0);
|
|
174
|
+
return call->getArgument(0);
|
|
157
175
|
}
|
|
158
176
|
|
|
159
|
-
const SVFValue* ThreadAPI::getJoinedThread(const
|
|
177
|
+
const SVFValue* ThreadAPI::getJoinedThread(const CallICFGNode *cs) const
|
|
160
178
|
{
|
|
161
|
-
assert(isTDJoin(
|
|
162
|
-
|
|
163
|
-
const SVFValue* join = cs.getArgument(0);
|
|
179
|
+
assert(isTDJoin(cs) && "not a thread join function!");
|
|
180
|
+
const SVFValue* join = cs->getArgument(0);
|
|
164
181
|
const SVFVar* var = PAG::getPAG()->getGNode(PAG::getPAG()->getValueNode(join));
|
|
165
182
|
for(const SVFStmt* stmt : var->getInEdges())
|
|
166
183
|
{
|
package/svf/lib/WPA/Andersen.cpp
CHANGED
|
@@ -661,10 +661,9 @@ bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites)
|
|
|
661
661
|
NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge
|
|
662
662
|
for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it )
|
|
663
663
|
{
|
|
664
|
-
CallSite cs = SVFUtil::getSVFCallSite(it->first);
|
|
665
664
|
for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
|
|
666
665
|
{
|
|
667
|
-
connectCaller2CalleeParams(
|
|
666
|
+
connectCaller2CalleeParams(it->first,*cit,cpySrcNodes);
|
|
668
667
|
}
|
|
669
668
|
}
|
|
670
669
|
for(NodePairSet::iterator it = cpySrcNodes.begin(), eit = cpySrcNodes.end(); it!=eit; ++it)
|
|
@@ -678,10 +677,10 @@ bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites)
|
|
|
678
677
|
return (!newEdges.empty());
|
|
679
678
|
}
|
|
680
679
|
|
|
681
|
-
void Andersen::heapAllocatorViaIndCall(
|
|
680
|
+
void Andersen::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet &cpySrcNodes)
|
|
682
681
|
{
|
|
683
682
|
assert(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?");
|
|
684
|
-
RetICFGNode* retBlockNode =
|
|
683
|
+
const RetICFGNode* retBlockNode = cs->getRetICFGNode();
|
|
685
684
|
const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
|
|
686
685
|
NodeID srcret;
|
|
687
686
|
CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
|
|
@@ -692,7 +691,7 @@ void Andersen::heapAllocatorViaIndCall(CallSite cs, NodePairSet &cpySrcNodes)
|
|
|
692
691
|
else
|
|
693
692
|
{
|
|
694
693
|
NodeID valNode = pag->addDummyValNode();
|
|
695
|
-
NodeID objNode = pag->addDummyObjNode(cs
|
|
694
|
+
NodeID objNode = pag->addDummyObjNode(cs->getCallSite()->getType());
|
|
696
695
|
addPts(valNode,objNode);
|
|
697
696
|
callsite2DummyValPN.insert(std::make_pair(cs,valNode));
|
|
698
697
|
consCG->addConstraintNode(new ConstraintNode(valNode),valNode);
|
|
@@ -708,14 +707,14 @@ void Andersen::heapAllocatorViaIndCall(CallSite cs, NodePairSet &cpySrcNodes)
|
|
|
708
707
|
/*!
|
|
709
708
|
* Connect formal and actual parameters for indirect callsites
|
|
710
709
|
*/
|
|
711
|
-
void Andersen::connectCaller2CalleeParams(
|
|
710
|
+
void Andersen::connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F, NodePairSet &cpySrcNodes)
|
|
712
711
|
{
|
|
713
712
|
assert(F);
|
|
714
713
|
|
|
715
714
|
DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() << " to callee " << *F << "\n");
|
|
716
715
|
|
|
717
|
-
CallICFGNode* callBlockNode =
|
|
718
|
-
RetICFGNode* retBlockNode =
|
|
716
|
+
const CallICFGNode* callBlockNode = cs;
|
|
717
|
+
const RetICFGNode* retBlockNode = cs->getRetICFGNode();
|
|
719
718
|
|
|
720
719
|
if(SVFUtil::isHeapAllocExtFunViaRet(F) && pag->callsiteHasRet(retBlockNode))
|
|
721
720
|
{
|
|
@@ -795,7 +794,7 @@ void Andersen::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, Nod
|
|
|
795
794
|
if(csArgIt != csArgEit)
|
|
796
795
|
{
|
|
797
796
|
writeWrnMsg("too many args to non-vararg func.");
|
|
798
|
-
writeWrnMsg("(" + cs
|
|
797
|
+
writeWrnMsg("(" + cs->getSourceLoc() + ")");
|
|
799
798
|
}
|
|
800
799
|
}
|
|
801
800
|
}
|