svf-tools 1.0.1014 → 1.0.1016
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 +2 -2
- package/svf/include/Graphs/CallGraph.h +2 -0
- package/svf/include/SVFIR/SVFFileSystem.h +0 -3
- package/svf/include/SVFIR/SVFValue.h +12 -61
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +21 -17
- package/svf/lib/Graphs/CallGraph.cpp +10 -0
- package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -21
- package/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +2 -29
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +23 -6
- package/svf-llvm/lib/ICFGBuilder.cpp +6 -8
- package/svf-llvm/lib/LLVMModule.cpp +13 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1016",
|
|
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": {
|
|
@@ -251,8 +251,8 @@ private:
|
|
|
251
251
|
AEStat* stat;
|
|
252
252
|
|
|
253
253
|
std::vector<const CallICFGNode*> callSiteStack;
|
|
254
|
-
Map<const
|
|
255
|
-
Set<const
|
|
254
|
+
Map<const CallGraphNode*, ICFGWTO*> funcToWTO;
|
|
255
|
+
Set<const CallGraphNode*> recursiveFuns;
|
|
256
256
|
|
|
257
257
|
|
|
258
258
|
AbstractState& getAbsStateFromTrace(const ICFGNode* node)
|
|
@@ -116,7 +116,6 @@ class SVFFunction;
|
|
|
116
116
|
class SVFBasicBlock;
|
|
117
117
|
class SVFInstruction;
|
|
118
118
|
class SVFCallInst;
|
|
119
|
-
class SVFVirtualCallInst;
|
|
120
119
|
class SVFConstant;
|
|
121
120
|
class SVFGlobalValue;
|
|
122
121
|
class SVFArgument;
|
|
@@ -516,7 +515,6 @@ private:
|
|
|
516
515
|
cJSON* contentToJson(const SVFBasicBlock* value);
|
|
517
516
|
cJSON* contentToJson(const SVFInstruction* value);
|
|
518
517
|
cJSON* contentToJson(const SVFCallInst* value);
|
|
519
|
-
cJSON* contentToJson(const SVFVirtualCallInst* value);
|
|
520
518
|
cJSON* contentToJson(const SVFConstant* value);
|
|
521
519
|
cJSON* contentToJson(const SVFGlobalValue* value);
|
|
522
520
|
cJSON* contentToJson(const SVFArgument* value);
|
|
@@ -1290,7 +1288,6 @@ private:
|
|
|
1290
1288
|
void fill(const cJSON*& fieldJson, SVFBasicBlock* value);
|
|
1291
1289
|
void fill(const cJSON*& fieldJson, SVFInstruction* value);
|
|
1292
1290
|
void fill(const cJSON*& fieldJson, SVFCallInst* value);
|
|
1293
|
-
void fill(const cJSON*& fieldJson, SVFVirtualCallInst* value);
|
|
1294
1291
|
void fill(const cJSON*& fieldJson, SVFConstant* value);
|
|
1295
1292
|
void fill(const cJSON*& fieldJson, SVFGlobalValue* value);
|
|
1296
1293
|
void fill(const cJSON*& fieldJson, SVFArgument* value);
|
|
@@ -40,7 +40,7 @@ namespace SVF
|
|
|
40
40
|
/// LLVM Aliases and constants
|
|
41
41
|
typedef SVF::GraphPrinter GraphPrinter;
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
class CallGraphNode;
|
|
44
44
|
class SVFInstruction;
|
|
45
45
|
class SVFBasicBlock;
|
|
46
46
|
class SVFArgument;
|
|
@@ -320,8 +320,14 @@ private:
|
|
|
320
320
|
std::vector<const SVFBasicBlock*> allBBs; /// all BasicBlocks of this function
|
|
321
321
|
std::vector<const SVFArgument*> allArgs; /// all formal arguments of this function
|
|
322
322
|
SVFBasicBlock *exitBlock; /// a 'single' basic block having no successors and containing return instruction in a function
|
|
323
|
+
const CallGraphNode *callGraphNode; /// call graph node for this function
|
|
323
324
|
|
|
324
325
|
protected:
|
|
326
|
+
inline void setCallGraphNode(CallGraphNode *cgn)
|
|
327
|
+
{
|
|
328
|
+
callGraphNode = cgn;
|
|
329
|
+
}
|
|
330
|
+
|
|
325
331
|
///@{ attributes to be set only through Module builders e.g., LLVMModule
|
|
326
332
|
inline void addBasicBlock(const SVFBasicBlock* bb)
|
|
327
333
|
{
|
|
@@ -354,6 +360,11 @@ public:
|
|
|
354
360
|
SVFFunction(void) = delete;
|
|
355
361
|
virtual ~SVFFunction();
|
|
356
362
|
|
|
363
|
+
inline const CallGraphNode* getCallGraphNode() const
|
|
364
|
+
{
|
|
365
|
+
return callGraphNode;
|
|
366
|
+
}
|
|
367
|
+
|
|
357
368
|
static inline bool classof(const SVFValue *node)
|
|
358
369
|
{
|
|
359
370
|
return node->getKind() == SVFFunc;
|
|
@@ -735,66 +746,6 @@ public:
|
|
|
735
746
|
}
|
|
736
747
|
};
|
|
737
748
|
|
|
738
|
-
class SVFVirtualCallInst : public SVFCallInst
|
|
739
|
-
{
|
|
740
|
-
friend class SVFIRWriter;
|
|
741
|
-
friend class SVFIRReader;
|
|
742
|
-
friend class LLVMModuleSet;
|
|
743
|
-
|
|
744
|
-
private:
|
|
745
|
-
const SVFValue* vCallVtblPtr; /// virtual table pointer
|
|
746
|
-
s32_t virtualFunIdx; /// virtual function index of the virtual table(s) at a virtual call
|
|
747
|
-
std::string funNameOfVcall; /// the function name of this virtual call
|
|
748
|
-
|
|
749
|
-
protected:
|
|
750
|
-
inline void setFunIdxInVtable(s32_t idx)
|
|
751
|
-
{
|
|
752
|
-
virtualFunIdx = idx;
|
|
753
|
-
}
|
|
754
|
-
inline void setFunNameOfVirtualCall(const std::string& name)
|
|
755
|
-
{
|
|
756
|
-
funNameOfVcall = name;
|
|
757
|
-
}
|
|
758
|
-
inline void setVtablePtr(const SVFValue* vptr)
|
|
759
|
-
{
|
|
760
|
-
vCallVtblPtr = vptr;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
public:
|
|
764
|
-
SVFVirtualCallInst(const SVFType* ty, const SVFBasicBlock* b, bool vararg,
|
|
765
|
-
bool tm)
|
|
766
|
-
: SVFCallInst(ty, b, vararg, tm, SVFVCall), vCallVtblPtr(nullptr),
|
|
767
|
-
virtualFunIdx(-1), funNameOfVcall()
|
|
768
|
-
{
|
|
769
|
-
}
|
|
770
|
-
inline const SVFValue* getVtablePtr() const
|
|
771
|
-
{
|
|
772
|
-
assert(vCallVtblPtr && "virtual call does not have a vtblptr? set it first");
|
|
773
|
-
return vCallVtblPtr;
|
|
774
|
-
}
|
|
775
|
-
inline s32_t getFunIdxInVtable() const
|
|
776
|
-
{
|
|
777
|
-
assert(virtualFunIdx >=0 && "virtual function idx is less than 0? not set yet?");
|
|
778
|
-
return virtualFunIdx;
|
|
779
|
-
}
|
|
780
|
-
inline const std::string& getFunNameOfVirtualCall() const
|
|
781
|
-
{
|
|
782
|
-
return funNameOfVcall;
|
|
783
|
-
}
|
|
784
|
-
static inline bool classof(const SVFValue *node)
|
|
785
|
-
{
|
|
786
|
-
return node->getKind() == SVFVCall;
|
|
787
|
-
}
|
|
788
|
-
static inline bool classof(const SVFInstruction *node)
|
|
789
|
-
{
|
|
790
|
-
return node->getKind() == SVFVCall;
|
|
791
|
-
}
|
|
792
|
-
static inline bool classof(const SVFCallInst *node)
|
|
793
|
-
{
|
|
794
|
-
return node->getKind() == SVFVCall;
|
|
795
|
-
}
|
|
796
|
-
};
|
|
797
|
-
|
|
798
749
|
class SVFConstant : public SVFValue
|
|
799
750
|
{
|
|
800
751
|
friend class SVFIRWriter;
|
|
@@ -84,24 +84,19 @@ void AbstractInterpretation::initWTO()
|
|
|
84
84
|
// Detect if the call graph has cycles by finding its strongly connected components (SCC)
|
|
85
85
|
Andersen::CallGraphSCC* callGraphScc = ander->getCallGraphSCC();
|
|
86
86
|
callGraphScc->find();
|
|
87
|
-
|
|
87
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
88
88
|
|
|
89
89
|
// Iterate through the call graph
|
|
90
|
-
for (auto it =
|
|
90
|
+
for (auto it = svfirCallGraph->begin(); it != svfirCallGraph->end(); it++)
|
|
91
91
|
{
|
|
92
92
|
// Check if the current function is part of a cycle
|
|
93
93
|
if (callGraphScc->isInCycle(it->second->getId()))
|
|
94
|
-
recursiveFuns.insert(it->second
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// Initialize WTO for each function in the module
|
|
98
|
-
for (const SVFFunction* fun : svfir->getModule()->getFunctionSet())
|
|
99
|
-
{
|
|
100
|
-
if(fun->isDeclaration())
|
|
94
|
+
recursiveFuns.insert(it->second); // Mark the function as recursive
|
|
95
|
+
if (it->second->getFunction()->isDeclaration())
|
|
101
96
|
continue;
|
|
102
|
-
auto* wto = new ICFGWTO(icfg, icfg->getFunEntryICFGNode(
|
|
97
|
+
auto* wto = new ICFGWTO(icfg, icfg->getFunEntryICFGNode(it->second->getFunction()));
|
|
103
98
|
wto->init();
|
|
104
|
-
funcToWTO[
|
|
99
|
+
funcToWTO[it->second] = wto;
|
|
105
100
|
}
|
|
106
101
|
}
|
|
107
102
|
/// Program entry
|
|
@@ -112,9 +107,9 @@ void AbstractInterpretation::analyse()
|
|
|
112
107
|
handleGlobalNode();
|
|
113
108
|
getAbsStateFromTrace(
|
|
114
109
|
icfg->getGlobalICFGNode())[PAG::getPAG()->getBlkPtr()] = IntervalValue::top();
|
|
115
|
-
if (const
|
|
110
|
+
if (const CallGraphNode* cgn = svfir->getCallGraph()->getCallGraphNode("main"))
|
|
116
111
|
{
|
|
117
|
-
ICFGWTO* wto = funcToWTO[
|
|
112
|
+
ICFGWTO* wto = funcToWTO[cgn];
|
|
118
113
|
handleWTOComponents(wto->getWTOComponents());
|
|
119
114
|
}
|
|
120
115
|
}
|
|
@@ -586,7 +581,11 @@ void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode)
|
|
|
586
581
|
|
|
587
582
|
bool AbstractInterpretation::isRecursiveCall(const SVF::CallICFGNode *callNode)
|
|
588
583
|
{
|
|
589
|
-
|
|
584
|
+
const SVFFunction *callfun = callNode->getCalledFunction();
|
|
585
|
+
if (!callfun)
|
|
586
|
+
return false;
|
|
587
|
+
else
|
|
588
|
+
return recursiveFuns.find(callfun->getCallGraphNode()) != recursiveFuns.end();
|
|
590
589
|
}
|
|
591
590
|
|
|
592
591
|
void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode)
|
|
@@ -610,7 +609,11 @@ void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode
|
|
|
610
609
|
|
|
611
610
|
bool AbstractInterpretation::isDirectCall(const SVF::CallICFGNode *callNode)
|
|
612
611
|
{
|
|
613
|
-
|
|
612
|
+
const SVFFunction *callfun =callNode->getCalledFunction();
|
|
613
|
+
if (!callfun)
|
|
614
|
+
return false;
|
|
615
|
+
else
|
|
616
|
+
return funcToWTO.find(callfun->getCallGraphNode()) != funcToWTO.end();
|
|
614
617
|
}
|
|
615
618
|
void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode)
|
|
616
619
|
{
|
|
@@ -619,7 +622,8 @@ void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode
|
|
|
619
622
|
|
|
620
623
|
abstractTrace[callNode] = as;
|
|
621
624
|
|
|
622
|
-
|
|
625
|
+
const SVFFunction *callfun =callNode->getCalledFunction();
|
|
626
|
+
ICFGWTO* wto = funcToWTO[callfun->getCallGraphNode()];
|
|
623
627
|
handleWTOComponents(wto->getWTOComponents());
|
|
624
628
|
|
|
625
629
|
callSiteStack.pop_back();
|
|
@@ -649,7 +653,7 @@ void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNo
|
|
|
649
653
|
SVFVar *func_var = svfir->getGNode(AbstractState::getInternalID(addr));
|
|
650
654
|
if(const FunObjVar*funObjVar = SVFUtil::dyn_cast<FunObjVar>(func_var))
|
|
651
655
|
{
|
|
652
|
-
const
|
|
656
|
+
const CallGraphNode* callfun = funObjVar->getCallGraphNode();
|
|
653
657
|
callSiteStack.push_back(callNode);
|
|
654
658
|
abstractTrace[callNode] = as;
|
|
655
659
|
|
|
@@ -143,6 +143,16 @@ void CallGraph::view()
|
|
|
143
143
|
SVF::ViewGraph(this, "Call Graph");
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
const CallGraphNode* CallGraph::getCallGraphNode(const std::string& name)
|
|
147
|
+
{
|
|
148
|
+
for (const auto& item : *this)
|
|
149
|
+
{
|
|
150
|
+
if (item.second->getName() == name)
|
|
151
|
+
return item.second;
|
|
152
|
+
}
|
|
153
|
+
return nullptr;
|
|
154
|
+
}
|
|
155
|
+
|
|
146
156
|
namespace SVF
|
|
147
157
|
{
|
|
148
158
|
|
|
@@ -61,8 +61,6 @@ static SVFValue* createSVFValue(SVFValue::GNodeK kind, const SVFType* type,
|
|
|
61
61
|
return new SVFInstruction(type, {}, {}, {});
|
|
62
62
|
case SVFValue::SVFCall:
|
|
63
63
|
return new SVFCallInst(type, {}, {}, {});
|
|
64
|
-
case SVFValue::SVFVCall:
|
|
65
|
-
return new SVFVirtualCallInst(type, {}, {}, {});
|
|
66
64
|
case SVFValue::SVFGlob:
|
|
67
65
|
return new SVFGlobalValue(type);
|
|
68
66
|
case SVFValue::SVFArg:
|
|
@@ -189,7 +187,6 @@ cJSON* SVFIRWriter::virtToJson(const SVFValue* value)
|
|
|
189
187
|
CASE(SVFBB, SVFBasicBlock);
|
|
190
188
|
CASE(SVFInst, SVFInstruction);
|
|
191
189
|
CASE(SVFCall, SVFCallInst);
|
|
192
|
-
CASE(SVFVCall, SVFVirtualCallInst);
|
|
193
190
|
CASE(SVFGlob, SVFGlobalValue);
|
|
194
191
|
CASE(SVFArg, SVFArgument);
|
|
195
192
|
CASE(SVFConst, SVFConstant);
|
|
@@ -580,15 +577,6 @@ cJSON* SVFIRWriter::contentToJson(const SVFCallInst* value)
|
|
|
580
577
|
return root;
|
|
581
578
|
}
|
|
582
579
|
|
|
583
|
-
cJSON* SVFIRWriter::contentToJson(const SVFVirtualCallInst* value)
|
|
584
|
-
{
|
|
585
|
-
cJSON* root = contentToJson(static_cast<const SVFCallInst*>(value));
|
|
586
|
-
JSON_WRITE_FIELD(root, value, vCallVtblPtr);
|
|
587
|
-
JSON_WRITE_FIELD(root, value, virtualFunIdx);
|
|
588
|
-
JSON_WRITE_FIELD(root, value, funNameOfVcall);
|
|
589
|
-
return root;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
580
|
cJSON* SVFIRWriter::contentToJson(const SVFConstant* value)
|
|
593
581
|
{
|
|
594
582
|
return contentToJson(static_cast<const SVFValue*>(value));
|
|
@@ -2310,7 +2298,6 @@ void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFValue* value)
|
|
|
2310
2298
|
CASE(SVFBB, SVFBasicBlock);
|
|
2311
2299
|
CASE(SVFInst, SVFInstruction);
|
|
2312
2300
|
CASE(SVFCall, SVFCallInst);
|
|
2313
|
-
CASE(SVFVCall, SVFVirtualCallInst);
|
|
2314
2301
|
CASE(SVFGlob, SVFGlobalValue);
|
|
2315
2302
|
CASE(SVFArg, SVFArgument);
|
|
2316
2303
|
CASE(SVFConst, SVFConstant);
|
|
@@ -2375,14 +2362,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, SVFCallInst* value)
|
|
|
2375
2362
|
JSON_READ_FIELD_FWD(fieldJson, value, calledVal);
|
|
2376
2363
|
}
|
|
2377
2364
|
|
|
2378
|
-
void SVFIRReader::fill(const cJSON*& fieldJson, SVFVirtualCallInst* value)
|
|
2379
|
-
{
|
|
2380
|
-
fill(fieldJson, static_cast<SVFCallInst*>(value));
|
|
2381
|
-
JSON_READ_FIELD_FWD(fieldJson, value, vCallVtblPtr);
|
|
2382
|
-
JSON_READ_FIELD_FWD(fieldJson, value, virtualFunIdx);
|
|
2383
|
-
JSON_READ_FIELD_FWD(fieldJson, value, funNameOfVcall);
|
|
2384
|
-
}
|
|
2385
|
-
|
|
2386
2365
|
void SVFIRReader::fill(const cJSON*& fieldJson, SVFConstant* value)
|
|
2387
2366
|
{
|
|
2388
2367
|
fill(fieldJson, static_cast<SVFValue*>(value));
|
|
@@ -58,44 +58,17 @@ private:
|
|
|
58
58
|
public:
|
|
59
59
|
typedef FIFOWorkList<const Instruction*> WorkList;
|
|
60
60
|
|
|
61
|
-
ICFGBuilder()
|
|
62
|
-
{
|
|
61
|
+
ICFGBuilder() = default;
|
|
63
62
|
|
|
64
|
-
}
|
|
65
63
|
ICFG* build();
|
|
66
64
|
|
|
67
65
|
private:
|
|
68
66
|
|
|
69
|
-
LLVMModuleSet* llvmModuleSet()
|
|
67
|
+
inline LLVMModuleSet* llvmModuleSet()
|
|
70
68
|
{
|
|
71
69
|
return LLVMModuleSet::getLLVMModuleSet();
|
|
72
70
|
}
|
|
73
71
|
|
|
74
|
-
CSToRetNodeMapTy& csToRetNodeMap()
|
|
75
|
-
{
|
|
76
|
-
return llvmModuleSet()->CSToRetNodeMap;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
CSToCallNodeMapTy& csToCallNodeMap()
|
|
80
|
-
{
|
|
81
|
-
return llvmModuleSet()->CSToCallNodeMap;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
InstToBlockNodeMapTy& instToBlockNodeMap()
|
|
85
|
-
{
|
|
86
|
-
return llvmModuleSet()->InstToBlockNodeMap;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
FunToFunEntryNodeMapTy& funToFunEntryNodeMap()
|
|
90
|
-
{
|
|
91
|
-
return llvmModuleSet()->FunToFunEntryNodeMap;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
FunToFunExitNodeMapTy& funToFunExitNodeMap()
|
|
95
|
-
{
|
|
96
|
-
return llvmModuleSet()->FunToFunExitNodeMap;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
72
|
private:
|
|
100
73
|
|
|
101
74
|
/// Create edges between ICFG nodes within a function
|
|
@@ -172,6 +172,7 @@ public:
|
|
|
172
172
|
LLVMFunc2SVFFunc[func] = svfFunc;
|
|
173
173
|
setValueAttr(func,svfFunc);
|
|
174
174
|
}
|
|
175
|
+
|
|
175
176
|
void addFunctionMap(const Function* func, CallGraphNode* svfFunc);
|
|
176
177
|
|
|
177
178
|
inline void addBasicBlockMap(const BasicBlock* bb, SVFBasicBlock* svfBB)
|
|
@@ -184,6 +185,22 @@ public:
|
|
|
184
185
|
LLVMInst2SVFInst[inst] = svfInst;
|
|
185
186
|
setValueAttr(inst,svfInst);
|
|
186
187
|
}
|
|
188
|
+
inline void addInstructionMap(const Instruction* inst, CallICFGNode* svfInst)
|
|
189
|
+
{
|
|
190
|
+
CSToCallNodeMap[inst] = svfInst;
|
|
191
|
+
setValueAttr(inst,svfInst);
|
|
192
|
+
}
|
|
193
|
+
inline void addInstructionMap(const Instruction* inst, RetICFGNode* svfInst)
|
|
194
|
+
{
|
|
195
|
+
CSToRetNodeMap[inst] = svfInst;
|
|
196
|
+
setValueAttr(inst,svfInst);
|
|
197
|
+
}
|
|
198
|
+
inline void addInstructionMap(const Instruction* inst, IntraICFGNode* svfInst)
|
|
199
|
+
{
|
|
200
|
+
InstToBlockNodeMap[inst] = svfInst;
|
|
201
|
+
setValueAttr(inst,svfInst);
|
|
202
|
+
}
|
|
203
|
+
|
|
187
204
|
inline void addArgumentMap(const Argument* arg, SVFArgument* svfArg)
|
|
188
205
|
{
|
|
189
206
|
LLVMArgument2SVFArgument[arg] = svfArg;
|
|
@@ -231,17 +248,17 @@ public:
|
|
|
231
248
|
return it->second;
|
|
232
249
|
}
|
|
233
250
|
|
|
234
|
-
inline
|
|
251
|
+
inline CallGraphNode* getCallGraphNode(const Function* fun) const
|
|
235
252
|
{
|
|
236
|
-
|
|
237
|
-
assert(it!=
|
|
253
|
+
LLVMFun2CallGraphNodeMap::const_iterator it = LLVMFunc2CallGraphNode.find(fun);
|
|
254
|
+
assert(it!=LLVMFunc2CallGraphNode.end() && "SVF Function not found!");
|
|
238
255
|
return it->second;
|
|
239
256
|
}
|
|
240
257
|
|
|
241
|
-
inline
|
|
258
|
+
inline SVFFunction* getSVFFunction(const Function* fun) const
|
|
242
259
|
{
|
|
243
|
-
|
|
244
|
-
assert(it!=
|
|
260
|
+
LLVMFun2SVFFunMap::const_iterator it = LLVMFunc2SVFFunc.find(fun);
|
|
261
|
+
assert(it!=LLVMFunc2SVFFunc.end() && "SVF Function not found!");
|
|
245
262
|
return it->second;
|
|
246
263
|
}
|
|
247
264
|
|
|
@@ -42,6 +42,7 @@ using namespace SVFUtil;
|
|
|
42
42
|
*/
|
|
43
43
|
ICFG* ICFGBuilder::build()
|
|
44
44
|
{
|
|
45
|
+
icfg = new ICFG();
|
|
45
46
|
DBOUT(DGENERAL, outs() << pasMsg("\t Building ICFG ...\n"));
|
|
46
47
|
// Add the unique global ICFGNode at the entry of a program (before the main method).
|
|
47
48
|
addGlobalICFGNode();
|
|
@@ -260,13 +261,11 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
|
|
|
260
261
|
calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
|
|
261
262
|
isvcall ? cppUtil::getVCallIdx(cb) : 0,
|
|
262
263
|
isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
|
|
263
|
-
|
|
264
|
-
llvmModuleSet()->setValueAttr(inst, callICFGNode);
|
|
264
|
+
llvmModuleSet()->addInstructionMap(inst, callICFGNode);
|
|
265
265
|
|
|
266
266
|
assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
|
|
267
267
|
RetICFGNode* retICFGNode = icfg->addRetICFGNode(callICFGNode);
|
|
268
|
-
|
|
269
|
-
llvmModuleSet()->setValueAttr(inst, retICFGNode);
|
|
268
|
+
llvmModuleSet()->addInstructionMap(inst, retICFGNode);
|
|
270
269
|
|
|
271
270
|
addICFGInterEdges(inst, LLVMUtil::getCallee(SVFUtil::cast<CallBase>(inst))); //creating interprocedural edges
|
|
272
271
|
return callICFGNode;
|
|
@@ -347,19 +346,18 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
|
|
|
347
346
|
assert (node==nullptr && "no IntraICFGNode for this instruction?");
|
|
348
347
|
IntraICFGNode* sNode = icfg->addIntraICFGNode(
|
|
349
348
|
llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
|
|
350
|
-
|
|
351
|
-
llvmModuleSet()->setValueAttr(inst, sNode);
|
|
349
|
+
llvmModuleSet()->addInstructionMap(inst, sNode);
|
|
352
350
|
return sNode;
|
|
353
351
|
}
|
|
354
352
|
|
|
355
353
|
FunEntryICFGNode* ICFGBuilder::addFunEntryBlock(const Function* fun)
|
|
356
354
|
{
|
|
357
|
-
return
|
|
355
|
+
return llvmModuleSet()->FunToFunEntryNodeMap[fun] =
|
|
358
356
|
icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
|
|
359
357
|
}
|
|
360
358
|
|
|
361
359
|
inline FunExitICFGNode* ICFGBuilder::addFunExitBlock(const Function* fun)
|
|
362
360
|
{
|
|
363
|
-
return
|
|
361
|
+
return llvmModuleSet()->FunToFunExitNodeMap[fun] =
|
|
364
362
|
icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
|
|
365
363
|
}
|
|
@@ -169,11 +169,18 @@ void LLVMModuleSet::build()
|
|
|
169
169
|
|
|
170
170
|
createSVFDataStructure();
|
|
171
171
|
initSVFFunction();
|
|
172
|
+
|
|
173
|
+
|
|
172
174
|
ICFGBuilder icfgbuilder;
|
|
173
175
|
icfg = icfgbuilder.build();
|
|
174
176
|
|
|
175
177
|
CallGraphBuilder callGraphBuilder;
|
|
176
178
|
callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);
|
|
179
|
+
for (const auto& func : svfModule->getFunctionSet())
|
|
180
|
+
{
|
|
181
|
+
SVFFunction* svffunc = const_cast<SVFFunction*>(func);
|
|
182
|
+
svffunc->setCallGraphNode(callgraph->getCallGraphNode(func));
|
|
183
|
+
}
|
|
177
184
|
|
|
178
185
|
for (const auto& it : *callgraph)
|
|
179
186
|
{
|
|
@@ -291,16 +298,10 @@ void LLVMModuleSet::createSVFFunction(const Function* func)
|
|
|
291
298
|
SVFInstruction* svfInst = nullptr;
|
|
292
299
|
if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(&inst))
|
|
293
300
|
{
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
inst.isTerminator());
|
|
299
|
-
else
|
|
300
|
-
svfInst = new SVFCallInst(
|
|
301
|
-
getSVFType(call->getType()), svfBB,
|
|
302
|
-
call->getFunctionType()->isVarArg(),
|
|
303
|
-
inst.isTerminator());
|
|
301
|
+
svfInst = new SVFCallInst(
|
|
302
|
+
getSVFType(call->getType()), svfBB,
|
|
303
|
+
call->getFunctionType()->isVarArg(),
|
|
304
|
+
inst.isTerminator());
|
|
304
305
|
}
|
|
305
306
|
else
|
|
306
307
|
{
|
|
@@ -380,12 +381,6 @@ void LLVMModuleSet::initSVFBasicBlock(const Function* func)
|
|
|
380
381
|
{
|
|
381
382
|
svfcall->setCalledOperand(getSVFValue(called_llvmval));
|
|
382
383
|
}
|
|
383
|
-
if(SVFVirtualCallInst* virtualCall = SVFUtil::dyn_cast<SVFVirtualCallInst>(svfcall))
|
|
384
|
-
{
|
|
385
|
-
virtualCall->setVtablePtr(getSVFValue(cppUtil::getVCallVtblPtr(call)));
|
|
386
|
-
virtualCall->setFunIdxInVtable(cppUtil::getVCallIdx(call));
|
|
387
|
-
virtualCall->setFunNameOfVirtualCall(cppUtil::getFunNameOfVCallSite(call));
|
|
388
|
-
}
|
|
389
384
|
for(u32_t i = 0; i < call->arg_size(); i++)
|
|
390
385
|
{
|
|
391
386
|
SVFValue* svfval = getSVFValue(call->getArgOperand(i));
|
|
@@ -1217,10 +1212,10 @@ void LLVMModuleSet::dumpModulesToFile(const std::string& suffix)
|
|
|
1217
1212
|
}
|
|
1218
1213
|
}
|
|
1219
1214
|
|
|
1220
|
-
void LLVMModuleSet::addFunctionMap(const
|
|
1215
|
+
void LLVMModuleSet::addFunctionMap(const Function* func, CallGraphNode* svfFunc)
|
|
1221
1216
|
{
|
|
1222
1217
|
LLVMFunc2CallGraphNode[func] = svfFunc;
|
|
1223
|
-
setValueAttr(func,svfFunc);
|
|
1218
|
+
setValueAttr(func, svfFunc);
|
|
1224
1219
|
}
|
|
1225
1220
|
|
|
1226
1221
|
void LLVMModuleSet::setValueAttr(const Value* val, SVFValue* svfvalue)
|