svf-tools 1.0.980 → 1.0.981
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/Graphs/ICFG.h +9 -0
- package/svf/include/MSSA/MemRegion.h +2 -2
- package/svf/include/MTA/MHP.h +1 -2
- package/svf/include/SVFIR/SVFIR.h +1 -1
- package/svf/include/SVFIR/SVFStatements.h +1 -1
- package/svf/include/SVFIR/SVFValue.h +21 -16
- package/svf/include/Util/SVFUtil.h +19 -17
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +1 -2
- package/svf/lib/Graphs/ICFG.cpp +41 -10
- package/svf/lib/Graphs/SVFG.cpp +7 -3
- package/svf/lib/Graphs/SVFGReadWrite.cpp +2 -2
- package/svf/lib/MSSA/MemRegion.cpp +13 -13
- package/svf/lib/MSSA/MemSSA.cpp +10 -18
- package/svf/lib/MTA/LockAnalysis.cpp +12 -13
- package/svf/lib/MTA/MHP.cpp +26 -28
- package/svf/lib/MTA/MTA.cpp +2 -2
- package/svf/lib/MTA/MTAStat.cpp +2 -4
- package/svf/lib/SABER/SaberCondAllocator.cpp +6 -7
- package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -2
- package/svf/lib/SVFIR/SVFIR.cpp +1 -1
- package/svf/lib/SVFIR/SVFStatements.cpp +1 -1
- package/svf/lib/SVFIR/SVFValue.cpp +1 -10
- package/svf/lib/Util/CDGBuilder.cpp +6 -9
- package/svf/lib/Util/CallGraphBuilder.cpp +7 -7
- package/svf/lib/Util/SVFUtil.cpp +49 -0
- package/svf/lib/Util/ThreadAPI.cpp +1 -2
- package/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +16 -6
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +11 -0
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +2 -2
- package/svf-llvm/lib/ICFGBuilder.cpp +103 -53
- package/svf-llvm/lib/LLVMLoopAnalysis.cpp +18 -4
- package/svf-llvm/lib/LLVMModule.cpp +16 -3
- package/svf-llvm/lib/ObjTypeInference.cpp +6 -2
- package/svf-llvm/lib/SVFIRBuilder.cpp +7 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.981",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -198,12 +198,21 @@ public:
|
|
|
198
198
|
//@{
|
|
199
199
|
ICFGNode* getICFGNode(const SVFInstruction* inst);
|
|
200
200
|
|
|
201
|
+
/// Whether has the ICFGNode
|
|
202
|
+
bool hasICFGNode(const SVFInstruction* inst);
|
|
203
|
+
|
|
201
204
|
CallICFGNode* getCallICFGNode(const SVFInstruction* inst);
|
|
202
205
|
|
|
206
|
+
CallICFGNode* addCallICFGNode(const SVFInstruction* inst);
|
|
207
|
+
|
|
203
208
|
RetICFGNode* getRetICFGNode(const SVFInstruction* inst);
|
|
204
209
|
|
|
210
|
+
RetICFGNode* addRetICFGNode(const SVFInstruction* inst);
|
|
211
|
+
|
|
205
212
|
IntraICFGNode* getIntraICFGNode(const SVFInstruction* inst);
|
|
206
213
|
|
|
214
|
+
IntraICFGNode* addIntraICFGNode(const SVFInstruction* inst);
|
|
215
|
+
|
|
207
216
|
FunEntryICFGNode* getFunEntryICFGNode(const SVFFunction* fun);
|
|
208
217
|
|
|
209
218
|
FunExitICFGNode* getFunExitICFGNode(const SVFFunction* fun);
|
|
@@ -470,9 +470,9 @@ public:
|
|
|
470
470
|
}
|
|
471
471
|
//@}
|
|
472
472
|
/// Whether this instruction has SVFIR Edge
|
|
473
|
-
bool hasSVFStmtList(const
|
|
473
|
+
bool hasSVFStmtList(const ICFGNode* icfgNode);
|
|
474
474
|
/// Given an instruction, get all its the PAGEdge (statement) in sequence
|
|
475
|
-
SVFStmtList& getPAGEdgesFromInst(const
|
|
475
|
+
SVFStmtList& getPAGEdgesFromInst(const ICFGNode* node);
|
|
476
476
|
|
|
477
477
|
/// getModRefInfo APIs
|
|
478
478
|
//@{
|
package/svf/include/MTA/MHP.h
CHANGED
|
@@ -341,8 +341,7 @@ public:
|
|
|
341
341
|
NodeID parentTid = tct->getParentThread(tid);
|
|
342
342
|
const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread();
|
|
343
343
|
const SVFFunction* parentRoutine = tct->getStartRoutineOfCxtThread(parentct);
|
|
344
|
-
|
|
345
|
-
return tct->getICFGNode(inst);
|
|
344
|
+
return parentRoutine->getExitBB()->back();
|
|
346
345
|
}
|
|
347
346
|
|
|
348
347
|
/// Get loop for join site
|
|
@@ -658,7 +658,7 @@ private:
|
|
|
658
658
|
/// Add Load edge
|
|
659
659
|
LoadStmt* addLoadStmt(NodeID src, NodeID dst);
|
|
660
660
|
/// Add Store edge
|
|
661
|
-
StoreStmt* addStoreStmt(NodeID src, NodeID dst, const
|
|
661
|
+
StoreStmt* addStoreStmt(NodeID src, NodeID dst, const ICFGNode* val);
|
|
662
662
|
/// Add Call edge
|
|
663
663
|
CallPE* addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs,
|
|
664
664
|
const FunEntryICFGNode* entry);
|
|
@@ -524,6 +524,8 @@ public:
|
|
|
524
524
|
}
|
|
525
525
|
};
|
|
526
526
|
|
|
527
|
+
class ICFGNode;
|
|
528
|
+
|
|
527
529
|
class SVFBasicBlock : public SVFValue
|
|
528
530
|
{
|
|
529
531
|
friend class LLVMModuleSet;
|
|
@@ -531,21 +533,26 @@ class SVFBasicBlock : public SVFValue
|
|
|
531
533
|
friend class SVFIRReader;
|
|
532
534
|
friend class SVFIRBuilder;
|
|
533
535
|
friend class SVFFunction;
|
|
536
|
+
friend class ICFGBuilder;
|
|
537
|
+
friend class ICFG;
|
|
534
538
|
|
|
535
539
|
public:
|
|
536
|
-
typedef std::vector<const
|
|
540
|
+
typedef std::vector<const ICFGNode*>::const_iterator const_iterator;
|
|
537
541
|
|
|
538
542
|
private:
|
|
539
|
-
std::vector<const
|
|
543
|
+
std::vector<const ICFGNode*> allICFGNodes; ///< all ICFGNodes in this BasicBlock
|
|
540
544
|
std::vector<const SVFBasicBlock*> succBBs; ///< all successor BasicBlocks of this BasicBlock
|
|
541
545
|
std::vector<const SVFBasicBlock*> predBBs; ///< all predecessor BasicBlocks of this BasicBlock
|
|
542
546
|
const SVFFunction* fun; /// Function where this BasicBlock is
|
|
543
547
|
|
|
544
548
|
protected:
|
|
545
549
|
///@{ attributes to be set only through Module builders e.g., LLVMModule
|
|
546
|
-
|
|
550
|
+
|
|
551
|
+
inline void addICFGNode(const ICFGNode* icfgNode)
|
|
547
552
|
{
|
|
548
|
-
|
|
553
|
+
assert(std::find(getICFGNodeList().begin(), getICFGNodeList().end(),
|
|
554
|
+
icfgNode) == getICFGNodeList().end() && "duplicated icfgnode");
|
|
555
|
+
allICFGNodes.push_back(icfgNode);
|
|
549
556
|
}
|
|
550
557
|
|
|
551
558
|
inline void addSuccBasicBlock(const SVFBasicBlock* succ)
|
|
@@ -570,19 +577,19 @@ public:
|
|
|
570
577
|
return node->getKind() == SVFBB;
|
|
571
578
|
}
|
|
572
579
|
|
|
573
|
-
inline const std::vector<const
|
|
580
|
+
inline const std::vector<const ICFGNode*>& getICFGNodeList() const
|
|
574
581
|
{
|
|
575
|
-
return
|
|
582
|
+
return allICFGNodes;
|
|
576
583
|
}
|
|
577
584
|
|
|
578
585
|
inline const_iterator begin() const
|
|
579
586
|
{
|
|
580
|
-
return
|
|
587
|
+
return allICFGNodes.begin();
|
|
581
588
|
}
|
|
582
589
|
|
|
583
590
|
inline const_iterator end() const
|
|
584
591
|
{
|
|
585
|
-
return
|
|
592
|
+
return allICFGNodes.end();
|
|
586
593
|
}
|
|
587
594
|
|
|
588
595
|
inline const SVFFunction* getParent() const
|
|
@@ -595,20 +602,18 @@ public:
|
|
|
595
602
|
return fun;
|
|
596
603
|
}
|
|
597
604
|
|
|
598
|
-
inline const
|
|
605
|
+
inline const ICFGNode* front() const
|
|
599
606
|
{
|
|
600
|
-
|
|
607
|
+
assert(!allICFGNodes.empty() && "bb empty?");
|
|
608
|
+
return allICFGNodes.front();
|
|
601
609
|
}
|
|
602
610
|
|
|
603
|
-
inline const
|
|
611
|
+
inline const ICFGNode* back() const
|
|
604
612
|
{
|
|
605
|
-
|
|
613
|
+
assert(!allICFGNodes.empty() && "bb empty?");
|
|
614
|
+
return allICFGNodes.back();
|
|
606
615
|
}
|
|
607
616
|
|
|
608
|
-
/// Returns the terminator instruction if the block is well formed or null
|
|
609
|
-
/// if the block is not well formed.
|
|
610
|
-
const SVFInstruction* getTerminator() const;
|
|
611
|
-
|
|
612
617
|
inline const std::vector<const SVFBasicBlock*>& getSuccessors() const
|
|
613
618
|
{
|
|
614
619
|
return succBBs;
|
|
@@ -168,6 +168,8 @@ void dumpPointsToList(const PointsToList& ptl);
|
|
|
168
168
|
|
|
169
169
|
/// Return true if it is an llvm intrinsic instruction
|
|
170
170
|
bool isIntrinsicInst(const SVFInstruction* inst);
|
|
171
|
+
bool isIntrinsicInst(const ICFGNode* inst);
|
|
172
|
+
|
|
171
173
|
//@}
|
|
172
174
|
|
|
173
175
|
/// Whether an instruction is a call or invoke instruction
|
|
@@ -184,6 +186,10 @@ inline bool isCallSite(const SVFValue* val)
|
|
|
184
186
|
return false;
|
|
185
187
|
}
|
|
186
188
|
|
|
189
|
+
bool isCallSite(const ICFGNode* inst);
|
|
190
|
+
|
|
191
|
+
bool isRetInstNode(const ICFGNode* node);
|
|
192
|
+
|
|
187
193
|
/// Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls
|
|
188
194
|
inline bool isNonInstricCallSite(const SVFInstruction* inst)
|
|
189
195
|
{
|
|
@@ -192,6 +198,14 @@ inline bool isNonInstricCallSite(const SVFInstruction* inst)
|
|
|
192
198
|
return isCallSite(inst);
|
|
193
199
|
}
|
|
194
200
|
|
|
201
|
+
/// Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls
|
|
202
|
+
inline bool isNonInstricCallSite(const ICFGNode* inst)
|
|
203
|
+
{
|
|
204
|
+
if(isIntrinsicInst(inst))
|
|
205
|
+
return false;
|
|
206
|
+
return isCallSite(inst);
|
|
207
|
+
}
|
|
208
|
+
|
|
195
209
|
/// Return LLVM callsite given an instruction
|
|
196
210
|
inline CallSite getSVFCallSite(const SVFInstruction* inst)
|
|
197
211
|
{
|
|
@@ -250,6 +264,8 @@ inline const SVFFunction* getCallee(const SVFInstruction *inst)
|
|
|
250
264
|
CallSite cs(inst);
|
|
251
265
|
return getCallee(cs);
|
|
252
266
|
}
|
|
267
|
+
|
|
268
|
+
const SVFFunction* getCallee(const ICFGNode *inst);
|
|
253
269
|
//@}
|
|
254
270
|
|
|
255
271
|
/// Given a map mapping points-to sets to a count, adds from into to.
|
|
@@ -402,27 +418,20 @@ inline bool isArgOfUncalledFunction(const SVFValue* svfval)
|
|
|
402
418
|
|
|
403
419
|
/// Return thread fork function
|
|
404
420
|
//@{
|
|
405
|
-
inline const SVFValue* getForkedFun(const CallSite cs)
|
|
406
|
-
{
|
|
407
|
-
return ThreadAPI::getThreadAPI()->getForkedFun(cs.getInstruction());
|
|
408
|
-
}
|
|
409
421
|
inline const SVFValue* getForkedFun(const SVFInstruction *inst)
|
|
410
422
|
{
|
|
411
423
|
return ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
412
424
|
}
|
|
413
425
|
//@}
|
|
414
426
|
|
|
415
|
-
/// This function servers a allocation wrapper detector
|
|
416
|
-
inline bool isAnAllocationWraper(const SVFInstruction*)
|
|
417
|
-
{
|
|
418
|
-
return false;
|
|
419
|
-
}
|
|
420
427
|
|
|
421
428
|
inline bool isExtCall(const CallSite cs)
|
|
422
429
|
{
|
|
423
430
|
return isExtCall(getCallee(cs));
|
|
424
431
|
}
|
|
425
432
|
|
|
433
|
+
bool isExtCall(const ICFGNode* node);
|
|
434
|
+
|
|
426
435
|
inline bool isExtCall(const SVFInstruction *inst)
|
|
427
436
|
{
|
|
428
437
|
return isExtCall(getCallee(inst));
|
|
@@ -451,10 +460,7 @@ inline bool isHeapAllocExtCallViaRet(const SVFInstruction *inst)
|
|
|
451
460
|
return isPtrTy && isHeapAllocExtFunViaRet(getCallee(inst));
|
|
452
461
|
}
|
|
453
462
|
|
|
454
|
-
|
|
455
|
-
{
|
|
456
|
-
return isHeapAllocExtCallViaRet(cs) || isHeapAllocExtCallViaArg(cs);
|
|
457
|
-
}
|
|
463
|
+
bool isHeapAllocExtCall(const ICFGNode* cs);
|
|
458
464
|
|
|
459
465
|
inline bool isHeapAllocExtCall(const SVFInstruction *inst)
|
|
460
466
|
{
|
|
@@ -477,10 +483,6 @@ inline bool isReallocExtCall(const CallSite cs)
|
|
|
477
483
|
|
|
478
484
|
/// Return true if this is a thread creation call
|
|
479
485
|
///@{
|
|
480
|
-
inline bool isThreadForkCall(const CallSite cs)
|
|
481
|
-
{
|
|
482
|
-
return ThreadAPI::getThreadAPI()->isTDFork(cs.getInstruction());
|
|
483
|
-
}
|
|
484
486
|
inline bool isThreadForkCall(const SVFInstruction *inst)
|
|
485
487
|
{
|
|
486
488
|
return ThreadAPI::getThreadAPI()->isTDFork(inst);
|
|
@@ -845,9 +845,8 @@ void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode)
|
|
|
845
845
|
FIFOWorkList<const ICFGNode *> instWorklist;
|
|
846
846
|
for (const SVFBasicBlock * bb: callfun->getReachableBBs())
|
|
847
847
|
{
|
|
848
|
-
for (const
|
|
848
|
+
for (const ICFGNode* node: bb->getICFGNodeList())
|
|
849
849
|
{
|
|
850
|
-
const ICFGNode* node = icfg->getICFGNode(inst);
|
|
851
850
|
for (const SVFStmt *stmt: node->getSVFStmts())
|
|
852
851
|
{
|
|
853
852
|
if (const StoreStmt *store = SVFUtil::dyn_cast<StoreStmt>(stmt))
|
package/svf/lib/Graphs/ICFG.cpp
CHANGED
|
@@ -119,7 +119,8 @@ const std::string FunExitICFGNode::toString() const
|
|
|
119
119
|
rawstr << " {fun: " << fun->getName();
|
|
120
120
|
// ensure the enclosing function has exit basic block
|
|
121
121
|
if (!isExtCall(fun) && fun->hasReturn())
|
|
122
|
-
|
|
122
|
+
if(const IntraICFGNode* intraICFGNode = dyn_cast<IntraICFGNode>(fun->getExitBB()->front()))
|
|
123
|
+
rawstr << intraICFGNode->getInst()->getSourceLoc();
|
|
123
124
|
rawstr << "}";
|
|
124
125
|
for (const SVFStmt *stmt : getSVFStmts())
|
|
125
126
|
rawstr << "\n" << stmt->toString();
|
|
@@ -229,7 +230,6 @@ ICFGNode* ICFG::getICFGNode(const SVFInstruction* inst)
|
|
|
229
230
|
node = getCallICFGNode(inst);
|
|
230
231
|
else if(SVFUtil::isIntrinsicInst(inst))
|
|
231
232
|
node = getIntraICFGNode(inst);
|
|
232
|
-
// assert (false && "associating an intrinsic instruction with an ICFGNode!");
|
|
233
233
|
else
|
|
234
234
|
node = getIntraICFGNode(inst);
|
|
235
235
|
|
|
@@ -237,39 +237,70 @@ ICFGNode* ICFG::getICFGNode(const SVFInstruction* inst)
|
|
|
237
237
|
return node;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
bool ICFG::hasICFGNode(const SVF::SVFInstruction* inst)
|
|
241
|
+
{
|
|
242
|
+
ICFGNode* node;
|
|
243
|
+
if(SVFUtil::isNonInstricCallSite(inst))
|
|
244
|
+
node = getCallBlock(inst);
|
|
245
|
+
else if(SVFUtil::isIntrinsicInst(inst))
|
|
246
|
+
node = getIntraBlock(inst);
|
|
247
|
+
else
|
|
248
|
+
node = getIntraBlock(inst);
|
|
249
|
+
|
|
250
|
+
return node != nullptr;
|
|
251
|
+
}
|
|
252
|
+
|
|
240
253
|
|
|
241
254
|
CallICFGNode* ICFG::getCallICFGNode(const SVFInstruction* inst)
|
|
242
255
|
{
|
|
243
|
-
if(SVFUtil::isCallSite(inst) ==false)
|
|
244
|
-
outs() << inst->toString() << "\n";
|
|
245
256
|
assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
|
|
246
257
|
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
247
258
|
CallICFGNode* node = getCallBlock(inst);
|
|
248
|
-
if(node==nullptr)
|
|
249
|
-
node = addCallBlock(inst);
|
|
250
259
|
assert (node!=nullptr && "no CallICFGNode for this instruction?");
|
|
251
260
|
return node;
|
|
252
261
|
}
|
|
253
262
|
|
|
263
|
+
CallICFGNode* ICFG::addCallICFGNode(const SVFInstruction* inst)
|
|
264
|
+
{
|
|
265
|
+
assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
|
|
266
|
+
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
267
|
+
assert(getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
|
|
268
|
+
return addCallBlock(inst);
|
|
269
|
+
}
|
|
270
|
+
|
|
254
271
|
RetICFGNode* ICFG::getRetICFGNode(const SVFInstruction* inst)
|
|
255
272
|
{
|
|
256
273
|
assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
|
|
257
274
|
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
258
275
|
RetICFGNode* node = getRetBlock(inst);
|
|
259
|
-
if(node==nullptr)
|
|
260
|
-
node = addRetBlock(inst);
|
|
261
276
|
assert (node!=nullptr && "no RetICFGNode for this instruction?");
|
|
262
277
|
return node;
|
|
263
278
|
}
|
|
264
279
|
|
|
280
|
+
RetICFGNode* ICFG::addRetICFGNode(const SVFInstruction* inst)
|
|
281
|
+
{
|
|
282
|
+
assert(SVFUtil::isCallSite(inst) && "not a call instruction?");
|
|
283
|
+
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
284
|
+
assert(getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
|
|
285
|
+
return addRetBlock(inst);
|
|
286
|
+
}
|
|
287
|
+
|
|
265
288
|
IntraICFGNode* ICFG::getIntraICFGNode(const SVFInstruction* inst)
|
|
266
289
|
{
|
|
267
290
|
IntraICFGNode* node = getIntraBlock(inst);
|
|
268
|
-
|
|
269
|
-
node = addIntraBlock(inst);
|
|
291
|
+
assert (node!=nullptr && "no IntraICFGNode for this instruction?");
|
|
270
292
|
return node;
|
|
271
293
|
}
|
|
272
294
|
|
|
295
|
+
|
|
296
|
+
IntraICFGNode* ICFG::addIntraICFGNode(const SVFInstruction* inst)
|
|
297
|
+
{
|
|
298
|
+
IntraICFGNode* node = getIntraBlock(inst);
|
|
299
|
+
assert (node==nullptr && "no IntraICFGNode for this instruction?");
|
|
300
|
+
return addIntraBlock(inst);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
|
|
273
304
|
/// Add a function entry node
|
|
274
305
|
FunEntryICFGNode* ICFG::getFunEntryICFGNode(const SVFFunction* fun)
|
|
275
306
|
{
|
package/svf/lib/Graphs/SVFG.cpp
CHANGED
|
@@ -111,7 +111,11 @@ const std::string MSSAPHISVFGNode::toString() const
|
|
|
111
111
|
rawstr << ")\n";
|
|
112
112
|
|
|
113
113
|
rawstr << getResVer()->getMR()->dumpStr();
|
|
114
|
-
|
|
114
|
+
if (const IntraICFGNode* intraNode =
|
|
115
|
+
dyn_cast<IntraICFGNode>(getICFGNode()->getBB()->back()))
|
|
116
|
+
{
|
|
117
|
+
rawstr << intraNode->getInst()->getSourceLoc();
|
|
118
|
+
}
|
|
115
119
|
return rawstr.str();
|
|
116
120
|
}
|
|
117
121
|
|
|
@@ -271,8 +275,8 @@ void SVFG::addSVFGNodesForAddrTakenVars()
|
|
|
271
275
|
for(PHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
|
|
272
276
|
{
|
|
273
277
|
MemSSA::PHI* phi = *pi;
|
|
274
|
-
const
|
|
275
|
-
addIntraMSSAPHISVFGNode(
|
|
278
|
+
const ICFGNode* inst = phi->getBasicBlock()->front();
|
|
279
|
+
addIntraMSSAPHISVFGNode(const_cast<ICFGNode*>(inst), phi->opVerBegin(), phi->opVerEnd(),phi->getResVer(), totalVFGNode++);
|
|
276
280
|
}
|
|
277
281
|
}
|
|
278
282
|
/// initialize memory SSA entry chi nodes
|
|
@@ -100,8 +100,8 @@ void SVFG::writeToFile(const string& filename)
|
|
|
100
100
|
// opvers
|
|
101
101
|
f << " >= MVER: {";
|
|
102
102
|
f << *phiNode->getResVer();
|
|
103
|
-
const
|
|
104
|
-
f << "} >= ICFGNodeID: " <<
|
|
103
|
+
const ICFGNode* inst = phiNode->getICFGNode()->getBB()->front();
|
|
104
|
+
f << "} >= ICFGNodeID: " << inst->getId();
|
|
105
105
|
f << " >= OPVers: {";
|
|
106
106
|
for (auto x: opvers)
|
|
107
107
|
{
|
|
@@ -147,24 +147,26 @@ void MRGenerator::generateMRs()
|
|
|
147
147
|
updateAliasMRs();
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
bool MRGenerator::hasSVFStmtList(const
|
|
150
|
+
bool MRGenerator::hasSVFStmtList(const ICFGNode* node)
|
|
151
151
|
{
|
|
152
152
|
SVFIR* pag = pta->getPAG();
|
|
153
153
|
if (ptrOnlyMSSA)
|
|
154
|
-
return pag->hasPTASVFStmtList(
|
|
154
|
+
return pag->hasPTASVFStmtList(node);
|
|
155
155
|
else
|
|
156
|
-
return pag->hasSVFStmtList(
|
|
156
|
+
return pag->hasSVFStmtList(node);
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
|
|
160
|
+
SVFIR::SVFStmtList& MRGenerator::getPAGEdgesFromInst(const ICFGNode* node)
|
|
160
161
|
{
|
|
161
162
|
SVFIR* pag = pta->getPAG();
|
|
162
163
|
if (ptrOnlyMSSA)
|
|
163
|
-
return pag->getPTASVFStmtList(
|
|
164
|
+
return pag->getPTASVFStmtList(node);
|
|
164
165
|
else
|
|
165
|
-
return pag->getSVFStmtList(
|
|
166
|
+
return pag->getSVFStmtList(node);
|
|
166
167
|
}
|
|
167
168
|
|
|
169
|
+
|
|
168
170
|
/*!
|
|
169
171
|
* Generate memory regions for loads/stores
|
|
170
172
|
*/
|
|
@@ -185,11 +187,9 @@ void MRGenerator::collectModRefForLoadStore()
|
|
|
185
187
|
iter != eiter; ++iter)
|
|
186
188
|
{
|
|
187
189
|
const SVFBasicBlock* bb = *iter;
|
|
188
|
-
for (
|
|
189
|
-
bit != ebit; ++bit)
|
|
190
|
+
for (const auto& inst: bb->getICFGNodeList())
|
|
190
191
|
{
|
|
191
|
-
|
|
192
|
-
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(svfInst);
|
|
192
|
+
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(inst);
|
|
193
193
|
for (SVFStmtList::iterator bit = pagEdgeList.begin(), ebit =
|
|
194
194
|
pagEdgeList.end(); bit != ebit; ++bit)
|
|
195
195
|
{
|
|
@@ -603,7 +603,7 @@ bool MRGenerator::handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGN
|
|
|
603
603
|
/// if a callee is a heap allocator function, then its mod set of this callsite is the heap object.
|
|
604
604
|
if(isHeapAllocExtCall(cs->getCallSite()))
|
|
605
605
|
{
|
|
606
|
-
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs
|
|
606
|
+
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
|
|
607
607
|
for (SVFStmtList::const_iterator bit = pagEdgeList.begin(),
|
|
608
608
|
ebit = pagEdgeList.end(); bit != ebit; ++bit)
|
|
609
609
|
{
|
|
@@ -669,7 +669,7 @@ NodeBS MRGenerator::getModInfoForCall(const CallICFGNode* cs)
|
|
|
669
669
|
{
|
|
670
670
|
if (isExtCall(cs->getCallSite()) && !isHeapAllocExtCall(cs->getCallSite()))
|
|
671
671
|
{
|
|
672
|
-
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs
|
|
672
|
+
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
|
|
673
673
|
NodeBS mods;
|
|
674
674
|
for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit =
|
|
675
675
|
pagEdgeList.end(); bit != ebit; ++bit)
|
|
@@ -693,7 +693,7 @@ NodeBS MRGenerator::getRefInfoForCall(const CallICFGNode* cs)
|
|
|
693
693
|
{
|
|
694
694
|
if (isExtCall(cs->getCallSite()) && !isHeapAllocExtCall(cs->getCallSite()))
|
|
695
695
|
{
|
|
696
|
-
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs
|
|
696
|
+
SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs);
|
|
697
697
|
NodeBS refs;
|
|
698
698
|
for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit =
|
|
699
699
|
pagEdgeList.end(); bit != ebit; ++bit)
|
package/svf/lib/MSSA/MemSSA.cpp
CHANGED
|
@@ -114,7 +114,6 @@ void MemSSA::buildMemSSA(const SVFFunction& fun)
|
|
|
114
114
|
void MemSSA::createMUCHI(const SVFFunction& fun)
|
|
115
115
|
{
|
|
116
116
|
|
|
117
|
-
SVFIR* pag = pta->getPAG();
|
|
118
117
|
|
|
119
118
|
DBOUT(DMSSA,
|
|
120
119
|
outs() << "\t creating mu chi for function " << fun.getName()
|
|
@@ -142,9 +141,8 @@ void MemSSA::createMUCHI(const SVFFunction& fun)
|
|
|
142
141
|
{
|
|
143
142
|
const SVFBasicBlock* bb = *iter;
|
|
144
143
|
varKills.clear();
|
|
145
|
-
for (
|
|
144
|
+
for (const auto& inst: bb->getICFGNodeList())
|
|
146
145
|
{
|
|
147
|
-
const SVFInstruction* inst = *it;
|
|
148
146
|
if(mrGen->hasSVFStmtList(inst))
|
|
149
147
|
{
|
|
150
148
|
SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(inst);
|
|
@@ -160,7 +158,7 @@ void MemSSA::createMUCHI(const SVFFunction& fun)
|
|
|
160
158
|
}
|
|
161
159
|
if (isNonInstricCallSite(inst))
|
|
162
160
|
{
|
|
163
|
-
const CallICFGNode* cs =
|
|
161
|
+
const CallICFGNode* cs = cast<CallICFGNode>(inst);
|
|
164
162
|
if(mrGen->hasRefMRSet(cs))
|
|
165
163
|
AddCallSiteMU(cs,mrGen->getCallSiteRefMRSet(cs));
|
|
166
164
|
|
|
@@ -263,7 +261,6 @@ void MemSSA::SSARename(const SVFFunction& fun)
|
|
|
263
261
|
void MemSSA::SSARenameBB(const SVFBasicBlock& bb)
|
|
264
262
|
{
|
|
265
263
|
|
|
266
|
-
SVFIR* pag = pta->getPAG();
|
|
267
264
|
// record which mem region needs to pop stack
|
|
268
265
|
MRVector memRegs;
|
|
269
266
|
|
|
@@ -281,13 +278,11 @@ void MemSSA::SSARenameBB(const SVFBasicBlock& bb)
|
|
|
281
278
|
// rewrite r' with top mrver of stack(r)
|
|
282
279
|
// rewrite r with new name
|
|
283
280
|
|
|
284
|
-
for (
|
|
285
|
-
it != eit; ++it)
|
|
281
|
+
for (const auto& pNode: bb.getICFGNodeList())
|
|
286
282
|
{
|
|
287
|
-
|
|
288
|
-
if(mrGen->hasSVFStmtList(inst))
|
|
283
|
+
if(mrGen->hasSVFStmtList(pNode))
|
|
289
284
|
{
|
|
290
|
-
SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(
|
|
285
|
+
SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(pNode);
|
|
291
286
|
for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end();
|
|
292
287
|
bit!=ebit; ++bit)
|
|
293
288
|
{
|
|
@@ -300,16 +295,16 @@ void MemSSA::SSARenameBB(const SVFBasicBlock& bb)
|
|
|
300
295
|
|
|
301
296
|
}
|
|
302
297
|
}
|
|
303
|
-
if (isNonInstricCallSite(
|
|
298
|
+
if (isNonInstricCallSite(pNode))
|
|
304
299
|
{
|
|
305
|
-
const CallICFGNode* cs =
|
|
300
|
+
const CallICFGNode* cs = cast<CallICFGNode>(pNode);
|
|
306
301
|
if(mrGen->hasRefMRSet(cs))
|
|
307
302
|
RenameMuSet(getMUSet(cs));
|
|
308
303
|
|
|
309
304
|
if(mrGen->hasModMRSet(cs))
|
|
310
305
|
RenameChiSet(getCHISet(cs),memRegs);
|
|
311
306
|
}
|
|
312
|
-
else if(
|
|
307
|
+
else if(isRetInstNode(pNode))
|
|
313
308
|
{
|
|
314
309
|
const SVFFunction* fun = bb.getParent();
|
|
315
310
|
RenameMuSet(getReturnMuSet(fun));
|
|
@@ -579,7 +574,6 @@ u32_t MemSSA::getBBPhiNum() const
|
|
|
579
574
|
*/
|
|
580
575
|
void MemSSA::dumpMSSA(OutStream& Out)
|
|
581
576
|
{
|
|
582
|
-
SVFIR* pag = pta->getPAG();
|
|
583
577
|
|
|
584
578
|
for (SVFModule::iterator fit = pta->getModule()->begin(), efit = pta->getModule()->end();
|
|
585
579
|
fit != efit; ++fit)
|
|
@@ -611,14 +605,12 @@ void MemSSA::dumpMSSA(OutStream& Out)
|
|
|
611
605
|
}
|
|
612
606
|
|
|
613
607
|
bool last_is_chi = false;
|
|
614
|
-
for (
|
|
615
|
-
it != eit; ++it)
|
|
608
|
+
for (const auto& inst: bb->getICFGNodeList())
|
|
616
609
|
{
|
|
617
|
-
const SVFInstruction* inst = *it;
|
|
618
610
|
bool isAppCall = isNonInstricCallSite(inst) && !isExtCall(inst);
|
|
619
611
|
if (isAppCall || isHeapAllocExtCall(inst))
|
|
620
612
|
{
|
|
621
|
-
const CallICFGNode* cs =
|
|
613
|
+
const CallICFGNode* cs = cast<CallICFGNode>(inst);
|
|
622
614
|
if(hasMU(cs))
|
|
623
615
|
{
|
|
624
616
|
if (!last_is_chi)
|
|
@@ -74,9 +74,8 @@ void LockAnalysis::collectLockUnlocksites()
|
|
|
74
74
|
{
|
|
75
75
|
for (const SVFBasicBlock* bb : F->getBasicBlockList())
|
|
76
76
|
{
|
|
77
|
-
for (const
|
|
77
|
+
for (const ICFGNode* icfgNode : bb->getICFGNodeList())
|
|
78
78
|
{
|
|
79
|
-
const ICFGNode* icfgNode = tct->getICFGNode(inst);
|
|
80
79
|
if (tcg->getThreadAPI()->isTDRelease(icfgNode))
|
|
81
80
|
{
|
|
82
81
|
unlocksites.insert(icfgNode);
|
|
@@ -180,8 +179,8 @@ bool LockAnalysis::intraForwardTraverse(const ICFGNode* lockSite, InstSet& unloc
|
|
|
180
179
|
{
|
|
181
180
|
const ICFGNode *I = worklist.back();
|
|
182
181
|
worklist.pop_back();
|
|
183
|
-
const
|
|
184
|
-
if(
|
|
182
|
+
const ICFGNode* exitInst = svfFun->getExitBB()->back();
|
|
183
|
+
if(exitInst == I)
|
|
185
184
|
return false;
|
|
186
185
|
|
|
187
186
|
// Skip the visited Instructions.
|
|
@@ -220,7 +219,7 @@ bool LockAnalysis::intraBackwardTraverse(const InstSet& unlockSet, InstSet& back
|
|
|
220
219
|
for(InstSet::const_iterator it = unlockSet.begin(), eit = unlockSet.end(); it!=eit; ++it)
|
|
221
220
|
{
|
|
222
221
|
const ICFGNode* unlockSite = *it;
|
|
223
|
-
const
|
|
222
|
+
const ICFGNode* entryInst = unlockSite->getFun()->getEntryBlock()->back();
|
|
224
223
|
worklist.push_back(*it);
|
|
225
224
|
|
|
226
225
|
while (!worklist.empty())
|
|
@@ -228,7 +227,7 @@ bool LockAnalysis::intraBackwardTraverse(const InstSet& unlockSet, InstSet& back
|
|
|
228
227
|
const ICFGNode *I = worklist.back();
|
|
229
228
|
worklist.pop_back();
|
|
230
229
|
|
|
231
|
-
if(
|
|
230
|
+
if(entryInst == I)
|
|
232
231
|
return false;
|
|
233
232
|
|
|
234
233
|
// Skip the visited Instructions.
|
|
@@ -337,8 +336,8 @@ void LockAnalysis::analyzeLockSpanCxtStmt()
|
|
|
337
336
|
if (!isLockCandidateFun(*it))
|
|
338
337
|
continue;
|
|
339
338
|
CallStrCxt cxt;
|
|
340
|
-
const
|
|
341
|
-
CxtStmt cxtstmt(cxt,
|
|
339
|
+
const ICFGNode* frontInst = (*it)->getEntryBlock()->front();
|
|
340
|
+
CxtStmt cxtstmt(cxt, frontInst);
|
|
342
341
|
pushToCTSWorkList(cxtstmt);
|
|
343
342
|
}
|
|
344
343
|
|
|
@@ -375,7 +374,7 @@ void LockAnalysis::analyzeLockSpanCxtStmt()
|
|
|
375
374
|
{
|
|
376
375
|
handleCall(cts);
|
|
377
376
|
}
|
|
378
|
-
else if (
|
|
377
|
+
else if (isRetInstNode(curInst))
|
|
379
378
|
{
|
|
380
379
|
handleRet(cts);
|
|
381
380
|
}
|
|
@@ -417,8 +416,8 @@ void LockAnalysis::handleFork(const CxtStmt& cts)
|
|
|
417
416
|
const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction();
|
|
418
417
|
CallStrCxt newCxt = curCxt;
|
|
419
418
|
pushCxt(newCxt,call,svfcallee);
|
|
420
|
-
const
|
|
421
|
-
CxtStmt newCts(newCxt,
|
|
419
|
+
const ICFGNode* svfInst = svfcallee->getEntryBlock()->front();
|
|
420
|
+
CxtStmt newCts(newCxt, svfInst);
|
|
422
421
|
markCxtStmtFlag(newCts, cts);
|
|
423
422
|
}
|
|
424
423
|
}
|
|
@@ -441,8 +440,8 @@ void LockAnalysis::handleCall(const CxtStmt& cts)
|
|
|
441
440
|
continue;
|
|
442
441
|
CallStrCxt newCxt = curCxt;
|
|
443
442
|
pushCxt(newCxt, call, svfcallee);
|
|
444
|
-
const
|
|
445
|
-
CxtStmt newCts(newCxt,
|
|
443
|
+
const ICFGNode* svfInst = svfcallee->getEntryBlock()->front();
|
|
444
|
+
CxtStmt newCts(newCxt, svfInst);
|
|
446
445
|
markCxtStmtFlag(newCts, cts);
|
|
447
446
|
}
|
|
448
447
|
}
|