svf-tools 1.0.1000 → 1.0.1002
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 +43 -0
- package/svf/include/Graphs/ICFGNode.h +48 -33
- package/svf/lib/CFL/CFLAlias.cpp +4 -3
- package/svf/lib/DDA/DDAClient.cpp +3 -3
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +3 -3
- package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -4
- package/svf/lib/WPA/TypeAnalysis.cpp +2 -2
- package/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +2 -2
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +6 -0
- package/svf-llvm/lib/ICFGBuilder.cpp +33 -33
- package/svf-llvm/lib/LLVMModule.cpp +3 -0
- package/svf-llvm/lib/SVFIRBuilder.cpp +6 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1002",
|
|
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": {
|
|
@@ -172,6 +172,49 @@ protected:
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
virtual inline IntraICFGNode* addIntraICFGNode(const SVFBasicBlock* bb, bool isRet)
|
|
176
|
+
{
|
|
177
|
+
IntraICFGNode* intraIcfgNode =
|
|
178
|
+
new IntraICFGNode(totalICFGNode++, bb, isRet);
|
|
179
|
+
addICFGNode(intraIcfgNode);
|
|
180
|
+
return intraIcfgNode;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
virtual inline CallICFGNode* addCallICFGNode(
|
|
184
|
+
const SVFBasicBlock* bb, const SVFType* ty,
|
|
185
|
+
const SVFFunction* calledFunc, bool isVararg, bool isvcall,
|
|
186
|
+
s32_t vcallIdx, const std::string& funNameOfVcall)
|
|
187
|
+
{
|
|
188
|
+
|
|
189
|
+
CallICFGNode* callICFGNode =
|
|
190
|
+
new CallICFGNode(totalICFGNode++, bb, ty, calledFunc, isVararg,
|
|
191
|
+
isvcall, vcallIdx, funNameOfVcall);
|
|
192
|
+
addICFGNode(callICFGNode);
|
|
193
|
+
return callICFGNode;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
virtual inline RetICFGNode* addRetICFGNode(CallICFGNode* call)
|
|
197
|
+
{
|
|
198
|
+
RetICFGNode* retICFGNode = new RetICFGNode(totalICFGNode++, call);
|
|
199
|
+
call->setRetICFGNode(retICFGNode);
|
|
200
|
+
addICFGNode(retICFGNode);
|
|
201
|
+
return retICFGNode;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
virtual inline FunEntryICFGNode* addFunEntryICFGNode(const SVFFunction* svfFunc)
|
|
205
|
+
{
|
|
206
|
+
FunEntryICFGNode* sNode = new FunEntryICFGNode(totalICFGNode++,svfFunc);
|
|
207
|
+
addICFGNode(sNode);
|
|
208
|
+
return FunToFunEntryNodeMap[svfFunc] = sNode;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
virtual inline FunExitICFGNode* addFunExitICFGNode(const SVFFunction* svfFunc)
|
|
212
|
+
{
|
|
213
|
+
FunExitICFGNode* sNode = new FunExitICFGNode(totalICFGNode++, svfFunc);
|
|
214
|
+
addICFGNode(sNode);
|
|
215
|
+
return FunToFunExitNodeMap[svfFunc] = sNode;
|
|
216
|
+
}
|
|
217
|
+
|
|
175
218
|
/// Add a ICFG node
|
|
176
219
|
virtual inline void addICFGNode(ICFGNode* node)
|
|
177
220
|
{
|
|
@@ -428,19 +428,28 @@ public:
|
|
|
428
428
|
typedef std::vector<const SVFVar *> ActualParmNodeVec;
|
|
429
429
|
|
|
430
430
|
protected:
|
|
431
|
-
const SVFInstruction* cs;
|
|
432
431
|
const RetICFGNode* ret;
|
|
433
|
-
ActualParmNodeVec APNodes;
|
|
432
|
+
ActualParmNodeVec APNodes; /// arguments
|
|
433
|
+
const SVFFunction* calledFunc; /// called function
|
|
434
|
+
bool isvararg; /// is variable argument
|
|
435
|
+
bool isVirCallInst; /// is virtual call inst
|
|
436
|
+
SVFVar* vtabPtr; /// virtual table pointer
|
|
437
|
+
s32_t virtualFunIdx; /// virtual function index of the virtual table(s) at a virtual call
|
|
438
|
+
std::string funNameOfVcall; /// the function name of this virtual call
|
|
434
439
|
|
|
435
440
|
/// Constructor to create empty CallICFGNode (for SVFIRReader/deserialization)
|
|
436
|
-
CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock),
|
|
441
|
+
CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock), ret{} {}
|
|
437
442
|
|
|
438
443
|
public:
|
|
439
|
-
CallICFGNode(NodeID id, const
|
|
440
|
-
|
|
444
|
+
CallICFGNode(NodeID id, const SVFBasicBlock* b, const SVFType* ty,
|
|
445
|
+
const SVFFunction* cf, bool iv, bool ivc, s32_t vfi,
|
|
446
|
+
const std::string& fnv)
|
|
447
|
+
: InterICFGNode(id, FunCallBlock), ret(nullptr), calledFunc(cf),
|
|
448
|
+
isvararg(iv), isVirCallInst(ivc), vtabPtr(nullptr),
|
|
449
|
+
virtualFunIdx(vfi), funNameOfVcall(fnv)
|
|
441
450
|
{
|
|
442
|
-
fun =
|
|
443
|
-
bb =
|
|
451
|
+
fun = b->getFunction();
|
|
452
|
+
bb = b;
|
|
444
453
|
type = ty;
|
|
445
454
|
}
|
|
446
455
|
|
|
@@ -472,7 +481,7 @@ public:
|
|
|
472
481
|
/// Return true if this is an indirect call
|
|
473
482
|
inline bool isIndirectCall() const
|
|
474
483
|
{
|
|
475
|
-
return nullptr ==
|
|
484
|
+
return nullptr == calledFunc;
|
|
476
485
|
}
|
|
477
486
|
|
|
478
487
|
/// Return the set of actual parameters
|
|
@@ -488,54 +497,61 @@ public:
|
|
|
488
497
|
}
|
|
489
498
|
/// Parameter operations
|
|
490
499
|
//@{
|
|
491
|
-
const SVFVar* getArgument(u32_t ArgNo) const
|
|
500
|
+
inline const SVFVar* getArgument(u32_t ArgNo) const
|
|
492
501
|
{
|
|
493
502
|
return getActualParms()[ArgNo];
|
|
494
503
|
}
|
|
495
504
|
|
|
496
|
-
u32_t arg_size() const
|
|
505
|
+
inline u32_t arg_size() const
|
|
497
506
|
{
|
|
498
507
|
return APNodes.size();
|
|
499
508
|
}
|
|
500
|
-
bool arg_empty() const
|
|
509
|
+
inline bool arg_empty() const
|
|
501
510
|
{
|
|
502
511
|
return APNodes.empty();
|
|
503
512
|
}
|
|
504
513
|
|
|
505
|
-
u32_t getNumArgOperands() const
|
|
514
|
+
inline u32_t getNumArgOperands() const
|
|
506
515
|
{
|
|
507
516
|
return arg_size();
|
|
508
517
|
}
|
|
509
|
-
const SVFFunction* getCalledFunction() const
|
|
518
|
+
inline const SVFFunction* getCalledFunction() const
|
|
510
519
|
{
|
|
511
|
-
return
|
|
520
|
+
return calledFunc;
|
|
512
521
|
}
|
|
513
|
-
|
|
522
|
+
|
|
523
|
+
inline bool isVarArg() const
|
|
514
524
|
{
|
|
515
|
-
return
|
|
525
|
+
return isvararg;
|
|
516
526
|
}
|
|
517
|
-
bool
|
|
527
|
+
inline bool isVirtualCall() const
|
|
518
528
|
{
|
|
519
|
-
return
|
|
529
|
+
return isVirCallInst;
|
|
520
530
|
}
|
|
521
|
-
|
|
531
|
+
|
|
532
|
+
inline void setVtablePtr(SVFVar* v)
|
|
522
533
|
{
|
|
523
|
-
|
|
534
|
+
vtabPtr = v;
|
|
524
535
|
}
|
|
525
|
-
|
|
536
|
+
|
|
537
|
+
inline const SVFVar* getVtablePtr() const
|
|
526
538
|
{
|
|
527
539
|
assert(isVirtualCall() && "not a virtual call?");
|
|
528
|
-
return
|
|
540
|
+
return vtabPtr;
|
|
529
541
|
}
|
|
530
|
-
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
inline s32_t getFunIdxInVtable() const
|
|
531
545
|
{
|
|
532
546
|
assert(isVirtualCall() && "not a virtual call?");
|
|
533
|
-
|
|
547
|
+
assert(virtualFunIdx >=0 && "virtual function idx is less than 0? not set yet?");
|
|
548
|
+
return virtualFunIdx;
|
|
534
549
|
}
|
|
535
|
-
|
|
550
|
+
|
|
551
|
+
inline const std::string& getFunNameOfVirtualCall() const
|
|
536
552
|
{
|
|
537
553
|
assert(isVirtualCall() && "not a virtual call?");
|
|
538
|
-
return
|
|
554
|
+
return funNameOfVcall;
|
|
539
555
|
}
|
|
540
556
|
//@}
|
|
541
557
|
|
|
@@ -585,23 +601,22 @@ class RetICFGNode : public InterICFGNode
|
|
|
585
601
|
friend class SVFIRReader;
|
|
586
602
|
|
|
587
603
|
private:
|
|
588
|
-
const SVFInstruction* cs;
|
|
589
604
|
const SVFVar *actualRet;
|
|
590
605
|
const CallICFGNode* callBlockNode;
|
|
591
606
|
|
|
592
607
|
/// Constructor to create empty RetICFGNode (for SVFIRReader/deserialization)
|
|
593
608
|
RetICFGNode(NodeID id)
|
|
594
|
-
: InterICFGNode(id, FunRetBlock),
|
|
609
|
+
: InterICFGNode(id, FunRetBlock), actualRet{}, callBlockNode{}
|
|
595
610
|
{
|
|
596
611
|
}
|
|
597
612
|
|
|
598
613
|
public:
|
|
599
|
-
RetICFGNode(NodeID id,
|
|
600
|
-
InterICFGNode(id, FunRetBlock),
|
|
614
|
+
RetICFGNode(NodeID id, CallICFGNode* cb) :
|
|
615
|
+
InterICFGNode(id, FunRetBlock), actualRet(nullptr), callBlockNode(cb)
|
|
601
616
|
{
|
|
602
|
-
fun =
|
|
603
|
-
bb =
|
|
604
|
-
type =
|
|
617
|
+
fun = cb->getFun();
|
|
618
|
+
bb = cb->getBB();
|
|
619
|
+
type = cb->getType();
|
|
605
620
|
}
|
|
606
621
|
|
|
607
622
|
inline const CallICFGNode* getCallICFGNode() const
|
package/svf/lib/CFL/CFLAlias.cpp
CHANGED
|
@@ -44,9 +44,10 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call
|
|
|
44
44
|
|
|
45
45
|
if (cs->isVirtualCall())
|
|
46
46
|
{
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
const SVFVar* vtbl = cs->getVtablePtr();
|
|
48
|
+
|
|
49
|
+
assert(vtbl != nullptr);
|
|
50
|
+
NodeID vtblId = vtbl->getId();
|
|
50
51
|
resolveCPPIndCalls(cs, getCFLPts(vtblId), newEdges);
|
|
51
52
|
}
|
|
52
53
|
else
|
|
@@ -83,9 +83,9 @@ OrderedNodeSet& FunptrDDAClient::collectCandidateQueries(SVFIR* p)
|
|
|
83
83
|
{
|
|
84
84
|
if (it->first->isVirtualCall())
|
|
85
85
|
{
|
|
86
|
-
const
|
|
87
|
-
assert(
|
|
88
|
-
NodeID vtblId =
|
|
86
|
+
const SVFVar* vtblPtr = it->first->getVtablePtr();
|
|
87
|
+
assert(vtblPtr != nullptr && "not a vtable pointer?");
|
|
88
|
+
NodeID vtblId = vtblPtr->getId();
|
|
89
89
|
addCandidate(vtblId);
|
|
90
90
|
vtableToCallSiteMap[vtblId] = it->first;
|
|
91
91
|
}
|
|
@@ -497,9 +497,9 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,
|
|
|
497
497
|
|
|
498
498
|
if (cs->isVirtualCall())
|
|
499
499
|
{
|
|
500
|
-
const
|
|
501
|
-
assert(
|
|
502
|
-
NodeID vtblId =
|
|
500
|
+
const SVFVar* vtbl = cs->getVtablePtr();
|
|
501
|
+
assert(vtbl != nullptr);
|
|
502
|
+
NodeID vtblId = vtbl->getId();
|
|
503
503
|
resolveCPPIndCalls(cs, getPts(vtblId), newEdges);
|
|
504
504
|
}
|
|
505
505
|
else
|
|
@@ -412,7 +412,6 @@ cJSON* SVFIRWriter::contentToJson(const FunExitICFGNode* node)
|
|
|
412
412
|
cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
|
|
413
413
|
{
|
|
414
414
|
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
|
|
415
|
-
JSON_WRITE_FIELD(root, node, cs);
|
|
416
415
|
JSON_WRITE_FIELD(root, node, ret);
|
|
417
416
|
JSON_WRITE_FIELD(root, node, APNodes);
|
|
418
417
|
return root;
|
|
@@ -421,7 +420,6 @@ cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
|
|
|
421
420
|
cJSON* SVFIRWriter::contentToJson(const RetICFGNode* node)
|
|
422
421
|
{
|
|
423
422
|
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
|
|
424
|
-
JSON_WRITE_FIELD(root, node, cs);
|
|
425
423
|
JSON_WRITE_FIELD(root, node, actualRet);
|
|
426
424
|
JSON_WRITE_FIELD(root, node, callBlockNode);
|
|
427
425
|
return root;
|
|
@@ -2205,7 +2203,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, FunExitICFGNode* node)
|
|
|
2205
2203
|
void SVFIRReader::fill(const cJSON*& fieldJson, CallICFGNode* node)
|
|
2206
2204
|
{
|
|
2207
2205
|
fill(fieldJson, static_cast<ICFGNode*>(node));
|
|
2208
|
-
JSON_READ_FIELD_FWD(fieldJson, node, cs);
|
|
2209
2206
|
JSON_READ_FIELD_FWD(fieldJson, node, ret);
|
|
2210
2207
|
JSON_READ_FIELD_FWD(fieldJson, node, APNodes);
|
|
2211
2208
|
}
|
|
@@ -2213,7 +2210,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, CallICFGNode* node)
|
|
|
2213
2210
|
void SVFIRReader::fill(const cJSON*& fieldJson, RetICFGNode* node)
|
|
2214
2211
|
{
|
|
2215
2212
|
fill(fieldJson, static_cast<ICFGNode*>(node));
|
|
2216
|
-
JSON_READ_FIELD_FWD(fieldJson, node, cs);
|
|
2217
2213
|
JSON_READ_FIELD_FWD(fieldJson, node, actualRet);
|
|
2218
2214
|
JSON_READ_FIELD_FWD(fieldJson, node, callBlockNode);
|
|
2219
2215
|
}
|
|
@@ -79,9 +79,9 @@ void TypeAnalysis::callGraphSolveBasedOnCHA(const CallSiteToFunPtrMap& callsites
|
|
|
79
79
|
const CallICFGNode* cbn = iter->first;
|
|
80
80
|
if (cbn->isVirtualCall())
|
|
81
81
|
{
|
|
82
|
-
const
|
|
82
|
+
const SVFVar* vtbl = cbn->getVtablePtr();
|
|
83
83
|
(void)vtbl; // Suppress warning of unused variable under release build
|
|
84
|
-
assert(
|
|
84
|
+
assert(vtbl != nullptr);
|
|
85
85
|
VFunSet vfns;
|
|
86
86
|
getVFnsFromCHA(cbn, vfns);
|
|
87
87
|
connectVCallToVFns(cbn, vfns, newEdges);
|
|
@@ -76,6 +76,7 @@ private:
|
|
|
76
76
|
static bool preProcessed;
|
|
77
77
|
SymbolTableInfo* symInfo;
|
|
78
78
|
SVFModule* svfModule; ///< Borrowed from singleton SVFModule::svfModule
|
|
79
|
+
ICFG* icfg;
|
|
79
80
|
std::unique_ptr<LLVMContext> owned_ctx;
|
|
80
81
|
std::vector<std::unique_ptr<Module>> owned_modules;
|
|
81
82
|
std::vector<std::reference_wrapper<Module>> modules;
|
|
@@ -362,6 +363,11 @@ public:
|
|
|
362
363
|
|
|
363
364
|
ObjTypeInference* getTypeInference();
|
|
364
365
|
|
|
366
|
+
inline ICFG* getICFG()
|
|
367
|
+
{
|
|
368
|
+
return icfg;
|
|
369
|
+
}
|
|
370
|
+
|
|
365
371
|
private:
|
|
366
372
|
/// Create SVFTypes
|
|
367
373
|
SVFType* addSVFTypeInfo(const Type* t);
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
#include "SVF-LLVM/ICFGBuilder.h"
|
|
32
|
+
#include "SVF-LLVM/CppUtil.h"
|
|
32
33
|
#include "SVF-LLVM/LLVMModule.h"
|
|
33
34
|
#include "SVF-LLVM/LLVMUtil.h"
|
|
34
35
|
|
|
@@ -39,7 +40,7 @@ using namespace SVFUtil;
|
|
|
39
40
|
/*!
|
|
40
41
|
* Create ICFG nodes and edges
|
|
41
42
|
*/
|
|
42
|
-
|
|
43
|
+
ICFG* ICFGBuilder::build()
|
|
43
44
|
{
|
|
44
45
|
DBOUT(DGENERAL, outs() << pasMsg("\t Building ICFG ...\n"));
|
|
45
46
|
// Add the unique global ICFGNode at the entry of a program (before the main method).
|
|
@@ -77,6 +78,7 @@ void ICFGBuilder::build()
|
|
|
77
78
|
|
|
78
79
|
}
|
|
79
80
|
connectGlobalToProgEntry();
|
|
81
|
+
return icfg;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
void ICFGBuilder::checkICFGNodesVisited(const Function* fun)
|
|
@@ -234,22 +236,35 @@ void ICFGBuilder::processFunExit(const Function* f)
|
|
|
234
236
|
*/
|
|
235
237
|
InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
|
|
236
238
|
{
|
|
237
|
-
SVFInstruction* svfInst =
|
|
238
|
-
llvmModuleSet()->getSVFInstruction(inst);
|
|
239
239
|
assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
|
|
240
240
|
assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
241
241
|
assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
242
|
+
const CallBase* cb = SVFUtil::dyn_cast<CallBase>(inst);
|
|
243
|
+
bool isvcall = cppUtil::isVirtualCallSite(cb);
|
|
244
|
+
SVFFunction* calledFunc = nullptr;
|
|
245
|
+
auto called_llvmval = cb->getCalledOperand()->stripPointerCasts();
|
|
246
|
+
if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
|
|
247
|
+
{
|
|
248
|
+
calledFunc = llvmModuleSet()->getSVFFunction(called_llvmfunc);
|
|
249
|
+
}
|
|
250
|
+
else
|
|
251
|
+
{
|
|
252
|
+
calledFunc = SVFUtil::dyn_cast<SVFFunction>(
|
|
253
|
+
llvmModuleSet()->getSVFValue(called_llvmval));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
SVFBasicBlock* bb = llvmModuleSet()->getSVFBasicBlock(inst->getParent());
|
|
257
|
+
|
|
258
|
+
CallICFGNode* callICFGNode = icfg->addCallICFGNode(
|
|
259
|
+
bb, llvmModuleSet()->getSVFType(inst->getType()),
|
|
260
|
+
calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
|
|
261
|
+
isvcall ? cppUtil::getVCallIdx(cb) : 0,
|
|
262
|
+
isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
|
|
246
263
|
csToCallNodeMap()[inst] = callICFGNode;
|
|
247
264
|
llvmModuleSet()->setValueAttr(inst, callICFGNode);
|
|
248
265
|
|
|
249
266
|
assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
|
|
250
|
-
RetICFGNode* retICFGNode =
|
|
251
|
-
callICFGNode->setRetICFGNode(retICFGNode);
|
|
252
|
-
icfg->addICFGNode(retICFGNode);
|
|
267
|
+
RetICFGNode* retICFGNode = icfg->addRetICFGNode(callICFGNode);
|
|
253
268
|
csToRetNodeMap()[inst] = retICFGNode;
|
|
254
269
|
llvmModuleSet()->setValueAttr(inst, retICFGNode);
|
|
255
270
|
|
|
@@ -316,27 +331,22 @@ void ICFGBuilder::connectGlobalToProgEntry()
|
|
|
316
331
|
inline ICFGNode* ICFGBuilder::addBlockICFGNode(const Instruction* inst)
|
|
317
332
|
{
|
|
318
333
|
ICFGNode* node;
|
|
319
|
-
SVFInstruction* svfINst =
|
|
320
|
-
llvmModuleSet()->getSVFInstruction(inst);
|
|
321
334
|
if(LLVMUtil::isNonInstricCallSite(inst))
|
|
322
335
|
node = addInterBlockICFGNode(inst);
|
|
323
336
|
else
|
|
324
337
|
node = addIntraBlockICFGNode(inst);
|
|
325
|
-
const_cast<SVFBasicBlock*>(
|
|
338
|
+
const_cast<SVFBasicBlock*>(
|
|
339
|
+
llvmModuleSet()->getSVFBasicBlock(inst->getParent()))
|
|
326
340
|
->addICFGNode(node);
|
|
327
341
|
return node;
|
|
328
342
|
}
|
|
329
343
|
|
|
330
344
|
IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
|
|
331
345
|
{
|
|
332
|
-
SVFInstruction* svfInst =
|
|
333
|
-
llvmModuleSet()->getSVFInstruction(inst);
|
|
334
346
|
IntraICFGNode* node = llvmModuleSet()->getIntraBlock(inst);
|
|
335
347
|
assert (node==nullptr && "no IntraICFGNode for this instruction?");
|
|
336
|
-
IntraICFGNode* sNode =
|
|
337
|
-
|
|
338
|
-
SVFUtil::isa<ReturnInst>(inst));
|
|
339
|
-
icfg->addICFGNode(sNode);
|
|
348
|
+
IntraICFGNode* sNode = icfg->addIntraICFGNode(
|
|
349
|
+
llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
|
|
340
350
|
instToBlockNodeMap()[inst] = sNode;
|
|
341
351
|
llvmModuleSet()->setValueAttr(inst, sNode);
|
|
342
352
|
return sNode;
|
|
@@ -344,22 +354,12 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
|
|
|
344
354
|
|
|
345
355
|
FunEntryICFGNode* ICFGBuilder::addFunEntryBlock(const Function* fun)
|
|
346
356
|
{
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
FunEntryICFGNode* sNode = new FunEntryICFGNode(icfg->totalICFGNode++,svfFunc);
|
|
350
|
-
icfg->addICFGNode(sNode);
|
|
351
|
-
funToFunEntryNodeMap()[fun] = sNode;
|
|
352
|
-
icfg->FunToFunEntryNodeMap[svfFunc] = sNode;
|
|
353
|
-
return sNode;
|
|
357
|
+
return funToFunEntryNodeMap()[fun] =
|
|
358
|
+
icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
|
|
354
359
|
}
|
|
355
360
|
|
|
356
361
|
inline FunExitICFGNode* ICFGBuilder::addFunExitBlock(const Function* fun)
|
|
357
362
|
{
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
FunExitICFGNode* sNode = new FunExitICFGNode(icfg->totalICFGNode++, svfFunc);
|
|
361
|
-
icfg->addICFGNode(sNode);
|
|
362
|
-
funToFunExitNodeMap()[fun] = sNode;
|
|
363
|
-
icfg->FunToFunExitNodeMap[svfFunc] = sNode;
|
|
364
|
-
return sNode;
|
|
363
|
+
return funToFunExitNodeMap()[fun] =
|
|
364
|
+
icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
|
|
365
365
|
}
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
#include "llvm/Support/FileSystem.h"
|
|
41
41
|
#include "SVF-LLVM/ObjTypeInference.h"
|
|
42
42
|
#include "llvm/Transforms/Utils/Cloning.h"
|
|
43
|
+
#include "SVF-LLVM/ICFGBuilder.h"
|
|
43
44
|
|
|
44
45
|
using namespace std;
|
|
45
46
|
using namespace SVF;
|
|
@@ -166,6 +167,8 @@ void LLVMModuleSet::build()
|
|
|
166
167
|
|
|
167
168
|
createSVFDataStructure();
|
|
168
169
|
initSVFFunction();
|
|
170
|
+
ICFGBuilder icfgbuilder;
|
|
171
|
+
icfg = icfgbuilder.build();
|
|
169
172
|
}
|
|
170
173
|
|
|
171
174
|
void LLVMModuleSet::createSVFDataStructure()
|
|
@@ -60,10 +60,7 @@ SVFIR* SVFIRBuilder::build()
|
|
|
60
60
|
pag->setModule(svfModule);
|
|
61
61
|
|
|
62
62
|
// Build ICFG
|
|
63
|
-
|
|
64
|
-
ICFGBuilder icfgbuilder(icfg);
|
|
65
|
-
icfgbuilder.build();
|
|
66
|
-
pag->setICFG(icfg);
|
|
63
|
+
pag->setICFG(llvmModuleSet()->getICFG());
|
|
67
64
|
|
|
68
65
|
// Set icfgnode in memobj
|
|
69
66
|
for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())
|
|
@@ -871,6 +868,11 @@ void SVFIRBuilder::visitCallSite(CallBase* cs)
|
|
|
871
868
|
if(!cs->getType()->isVoidTy())
|
|
872
869
|
pag->addCallSiteRets(retBlockNode,pag->getGNode(getValueNode(cs)));
|
|
873
870
|
|
|
871
|
+
if (callBlockNode->isVirtualCall())
|
|
872
|
+
{
|
|
873
|
+
const Value* value = cppUtil::getVCallVtblPtr(cs);
|
|
874
|
+
callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
|
|
875
|
+
}
|
|
874
876
|
if (const Function *callee = LLVMUtil::getCallee(cs))
|
|
875
877
|
{
|
|
876
878
|
const SVFFunction* svfcallee = llvmModuleSet()->getSVFFunction(callee);
|