svf-lib 1.0.973 → 1.0.976
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/SVF-linux/Release-build/lib/libSvf.a +0 -0
- package/SVF-linux/include/SABER/PathCondAllocator.h +4 -4
- package/SVF-linux/include/SABER/SrcSnkDDA.h +2 -2
- package/SVF-linux/include/SABER/SrcSnkSolver.h +186 -0
- package/SVF-linux/include/SVF-FE/IRAnnotator.h +321 -0
- package/SVF-linux/include/Util/BDDExpr.h +182 -0
- package/SVF-linux/include/Util/DPItem.h +1 -1
- package/SVF-linux/include/Util/ExeState.h +172 -0
- package/SVF-linux/include/Util/Options.h +0 -3
- package/SVF-linux/include/Util/Z3Expr.h +235 -0
- package/SVF-linux/include/WPA/FlowSensitiveTBHC.h +1 -1
- package/SVF-linux/include/WPA/TypeBasedHeapCloning.h +188 -0
- package/SVF-osx/Release-build/lib/CUDD/libCudd.a +0 -0
- package/SVF-osx/Release-build/lib/libSvf.a +0 -0
- package/SVF-osx/include/SABER/PathCondAllocator.h +4 -4
- package/SVF-osx/include/SABER/SrcSnkDDA.h +2 -2
- package/SVF-osx/include/SABER/SrcSnkSolver.h +186 -0
- package/SVF-osx/include/SVF-FE/IRAnnotator.h +321 -0
- package/SVF-osx/include/Util/BDDExpr.h +182 -0
- package/SVF-osx/include/Util/DPItem.h +1 -1
- package/SVF-osx/include/Util/ExeState.h +172 -0
- package/SVF-osx/include/Util/Options.h +0 -3
- package/SVF-osx/include/Util/Z3Expr.h +235 -0
- package/SVF-osx/include/WPA/FlowSensitiveTBHC.h +1 -1
- package/SVF-osx/include/WPA/TypeBasedHeapCloning.h +188 -0
- package/package.json +1 -1
|
Binary file
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
#include "Util/SVFModule.h"
|
|
34
34
|
#include "SVF-FE/DataFlowUtil.h"
|
|
35
35
|
#include "SVF-FE/BasicTypes.h"
|
|
36
|
-
#include "Util/
|
|
36
|
+
#include "Util/BDDExpr.h"
|
|
37
37
|
#include "Util/WorkList.h"
|
|
38
38
|
#include "Graphs/SVFG.h"
|
|
39
39
|
|
|
@@ -49,7 +49,7 @@ class PathCondAllocator
|
|
|
49
49
|
|
|
50
50
|
public:
|
|
51
51
|
|
|
52
|
-
typedef
|
|
52
|
+
typedef BDDExprManager::BDDExpr Condition; /// z3 condition
|
|
53
53
|
|
|
54
54
|
typedef Map<u32_t,Condition*> CondPosMap; ///< map a branch to its Condition
|
|
55
55
|
typedef Map<const BasicBlock*, CondPosMap > BBCondMap; // map bb to a Condition
|
|
@@ -133,7 +133,7 @@ public:
|
|
|
133
133
|
{
|
|
134
134
|
return condMgr->getCondInst(cond);
|
|
135
135
|
}
|
|
136
|
-
inline void setCondInst(const
|
|
136
|
+
inline void setCondInst(const Condition* cond, const Instruction* inst){
|
|
137
137
|
condMgr->setCondInst(cond, inst);
|
|
138
138
|
}
|
|
139
139
|
//@}
|
|
@@ -286,7 +286,7 @@ private:
|
|
|
286
286
|
const SVFGNode* curEvalSVFGNode{}; ///< current llvm value to evaluate branch condition when computing guards
|
|
287
287
|
|
|
288
288
|
protected:
|
|
289
|
-
|
|
289
|
+
BDDExprManager* condMgr; ///< z3 manager
|
|
290
290
|
BBCondMap bbConds; ///< map basic block to its successors/predecessors branch conditions
|
|
291
291
|
|
|
292
292
|
};
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
#ifndef SRCSNKANALYSIS_H_
|
|
31
31
|
#define SRCSNKANALYSIS_H_
|
|
32
32
|
|
|
33
|
-
#include "
|
|
33
|
+
#include "SrcSnkSolver.h"
|
|
34
34
|
#include "Graphs/SVFGOPT.h"
|
|
35
35
|
#include "SABER/ProgSlice.h"
|
|
36
36
|
#include "SABER/SaberSVFGBuilder.h"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
namespace SVF
|
|
39
39
|
{
|
|
40
40
|
|
|
41
|
-
typedef
|
|
41
|
+
typedef SrcSnkSolver<SVFG*,CxtDPItem> CFLSrcSnkSolver;
|
|
42
42
|
|
|
43
43
|
/*!
|
|
44
44
|
* General source-sink analysis, which serves as a base analysis to be extended for various clients
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
//===- SrcSnkSolver.h -- CFL reachability solver---------------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2017> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* SrcSnkSolver.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: Apr 1, 2014
|
|
27
|
+
* Author: Yulei Sui
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef CFLSOLVER_H_
|
|
31
|
+
#define CFLSOLVER_H_
|
|
32
|
+
|
|
33
|
+
#include "Util/WorkList.h"
|
|
34
|
+
#include "Util/DPItem.h"
|
|
35
|
+
|
|
36
|
+
namespace SVF
|
|
37
|
+
{
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
* Generic CFL solver for demand-driven analysis based on different graphs (e.g. SVFIR, VFG, ThreadVFG)
|
|
41
|
+
* Extend this class for sophisticated CFL-reachability resolution (e.g. field, flow, path)
|
|
42
|
+
*/
|
|
43
|
+
template<class GraphType, class DPIm = DPItem>
|
|
44
|
+
class SrcSnkSolver
|
|
45
|
+
{
|
|
46
|
+
|
|
47
|
+
public:
|
|
48
|
+
///Define the GTraits and node iterator
|
|
49
|
+
typedef llvm::GraphTraits<GraphType> GTraits;
|
|
50
|
+
typedef typename GTraits::NodeType GNODE;
|
|
51
|
+
typedef typename GTraits::EdgeType GEDGE;
|
|
52
|
+
typedef typename GTraits::nodes_iterator node_iterator;
|
|
53
|
+
typedef typename GTraits::ChildIteratorType child_iterator;
|
|
54
|
+
|
|
55
|
+
/// Define inverse GTraits and note iterator
|
|
56
|
+
typedef llvm::GraphTraits<llvm::Inverse<GNODE *> > InvGTraits;
|
|
57
|
+
typedef typename InvGTraits::ChildIteratorType inv_child_iterator;
|
|
58
|
+
|
|
59
|
+
/// Define worklist
|
|
60
|
+
typedef FIFOWorkList<DPIm> WorkList;
|
|
61
|
+
|
|
62
|
+
protected:
|
|
63
|
+
|
|
64
|
+
/// Constructor
|
|
65
|
+
SrcSnkSolver(): _graph(nullptr)
|
|
66
|
+
{
|
|
67
|
+
}
|
|
68
|
+
/// Destructor
|
|
69
|
+
virtual ~SrcSnkSolver()
|
|
70
|
+
{
|
|
71
|
+
}
|
|
72
|
+
/// Get/Set graph methods
|
|
73
|
+
//@{
|
|
74
|
+
const inline GraphType graph() const
|
|
75
|
+
{
|
|
76
|
+
return _graph;
|
|
77
|
+
}
|
|
78
|
+
inline void setGraph(GraphType g)
|
|
79
|
+
{
|
|
80
|
+
_graph = g;
|
|
81
|
+
}
|
|
82
|
+
//@}
|
|
83
|
+
|
|
84
|
+
inline GNODE* getNode(NodeID id) const
|
|
85
|
+
{
|
|
86
|
+
return _graph->getGNode(id);
|
|
87
|
+
}
|
|
88
|
+
virtual inline NodeID getNodeIDFromItem(const DPIm& item) const
|
|
89
|
+
{
|
|
90
|
+
return item.getCurNodeID();
|
|
91
|
+
}
|
|
92
|
+
/// CFL forward traverse solve
|
|
93
|
+
virtual void forwardTraverse(DPIm& it)
|
|
94
|
+
{
|
|
95
|
+
pushIntoWorklist(it);
|
|
96
|
+
|
|
97
|
+
while (!isWorklistEmpty())
|
|
98
|
+
{
|
|
99
|
+
DPIm item = popFromWorklist();
|
|
100
|
+
FWProcessCurNode(item);
|
|
101
|
+
|
|
102
|
+
GNODE* v = getNode(getNodeIDFromItem(item));
|
|
103
|
+
child_iterator EI = GTraits::child_begin(v);
|
|
104
|
+
child_iterator EE = GTraits::child_end(v);
|
|
105
|
+
for (; EI != EE; ++EI)
|
|
106
|
+
{
|
|
107
|
+
FWProcessOutgoingEdge(item,*(EI.getCurrent()) );
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/// CFL forward traverse solve
|
|
112
|
+
virtual void backwardTraverse(DPIm& it)
|
|
113
|
+
{
|
|
114
|
+
pushIntoWorklist(it);
|
|
115
|
+
|
|
116
|
+
while (!isWorklistEmpty())
|
|
117
|
+
{
|
|
118
|
+
DPIm item = popFromWorklist();
|
|
119
|
+
BWProcessCurNode(item);
|
|
120
|
+
|
|
121
|
+
GNODE* v = getNode(getNodeIDFromItem(item));
|
|
122
|
+
inv_child_iterator EI = InvGTraits::child_begin(v);
|
|
123
|
+
inv_child_iterator EE = InvGTraits::child_end(v);
|
|
124
|
+
for (; EI != EE; ++EI)
|
|
125
|
+
{
|
|
126
|
+
BWProcessIncomingEdge(item,*(EI.getCurrent()) );
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/// Process the DP item
|
|
131
|
+
//@{
|
|
132
|
+
virtual void FWProcessCurNode(const DPIm&)
|
|
133
|
+
{
|
|
134
|
+
}
|
|
135
|
+
virtual void BWProcessCurNode(const DPIm&)
|
|
136
|
+
{
|
|
137
|
+
}
|
|
138
|
+
//@}
|
|
139
|
+
/// Propagation for the solving, to be implemented in the child class
|
|
140
|
+
//@{
|
|
141
|
+
virtual void FWProcessOutgoingEdge(const DPIm& item, GEDGE* edge)
|
|
142
|
+
{
|
|
143
|
+
DPIm newItem(item);
|
|
144
|
+
newItem.setCurNodeID(edge->getDstID());
|
|
145
|
+
pushIntoWorklist(newItem);
|
|
146
|
+
}
|
|
147
|
+
virtual void BWProcessIncomingEdge(const DPIm& item, GEDGE* edge)
|
|
148
|
+
{
|
|
149
|
+
DPIm newItem(item);
|
|
150
|
+
newItem.setCurNodeID(edge->getSrcID());
|
|
151
|
+
pushIntoWorklist(newItem);
|
|
152
|
+
}
|
|
153
|
+
//@}
|
|
154
|
+
/// Worklist operations
|
|
155
|
+
//@{
|
|
156
|
+
inline DPIm popFromWorklist()
|
|
157
|
+
{
|
|
158
|
+
return worklist.pop();
|
|
159
|
+
}
|
|
160
|
+
inline bool pushIntoWorklist(DPIm& item)
|
|
161
|
+
{
|
|
162
|
+
return worklist.push(item);
|
|
163
|
+
}
|
|
164
|
+
inline bool isWorklistEmpty()
|
|
165
|
+
{
|
|
166
|
+
return worklist.empty();
|
|
167
|
+
}
|
|
168
|
+
inline bool isInWorklist(DPIm& item)
|
|
169
|
+
{
|
|
170
|
+
return worklist.find(item);
|
|
171
|
+
}
|
|
172
|
+
//@}
|
|
173
|
+
|
|
174
|
+
private:
|
|
175
|
+
|
|
176
|
+
/// Graph
|
|
177
|
+
GraphType _graph;
|
|
178
|
+
|
|
179
|
+
/// Worklist for resolution
|
|
180
|
+
WorkList worklist;
|
|
181
|
+
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
} // End namespace SVF
|
|
185
|
+
|
|
186
|
+
#endif /* CFLSOLVER_H_ */
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Annotator.h
|
|
3
|
+
*
|
|
4
|
+
* Created on: March 22, 2021
|
|
5
|
+
* Author: Nicholas Tsom
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#ifndef IRANNOTATOR_H_
|
|
9
|
+
#define IRANNOTATOR_H_
|
|
10
|
+
|
|
11
|
+
#include "MemoryModel/SVFIR.h"
|
|
12
|
+
#include "MemoryModel/PointerAnalysisImpl.h"
|
|
13
|
+
#include "Util/SVFUtil.h"
|
|
14
|
+
#include "llvm/IR/Metadata.h"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
namespace SVF
|
|
18
|
+
{
|
|
19
|
+
/*!
|
|
20
|
+
* Program annotator to write metadata information on LLVM IR
|
|
21
|
+
*/
|
|
22
|
+
class IRAnnotator
|
|
23
|
+
{
|
|
24
|
+
public:
|
|
25
|
+
IRAnnotator():
|
|
26
|
+
mainModule(nullptr),
|
|
27
|
+
ptsTo(nullptr)
|
|
28
|
+
{}
|
|
29
|
+
~IRAnnotator() {}
|
|
30
|
+
|
|
31
|
+
void processAndersenResults(SVFIR *pag, BVDataPTAImpl *ptsTo, bool writeFlag)
|
|
32
|
+
{
|
|
33
|
+
this->ptsTo = ptsTo;
|
|
34
|
+
mainModule = LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule();
|
|
35
|
+
|
|
36
|
+
// Add a named metadata node used to check whether or not
|
|
37
|
+
// this IR has been annotated with Andersen information
|
|
38
|
+
if (writeFlag)
|
|
39
|
+
mainModule->getOrInsertNamedMetadata("SVFIR-Annotated");
|
|
40
|
+
|
|
41
|
+
for (auto it = pag->begin(); it != pag->end(); ++it)
|
|
42
|
+
{
|
|
43
|
+
auto nodeId = it->first;
|
|
44
|
+
auto pagNode = it->second;
|
|
45
|
+
auto gepNode = SVFUtil::dyn_cast<GepObjVar>(pagNode);
|
|
46
|
+
|
|
47
|
+
if (gepNode && writeFlag)
|
|
48
|
+
{
|
|
49
|
+
writePAGgepNode(nodeId, gepNode);
|
|
50
|
+
}
|
|
51
|
+
else if (pagNode->hasValue())
|
|
52
|
+
{
|
|
53
|
+
processPAGNode(pagNode->getValue(), nodeId, writeFlag);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!writeFlag)
|
|
58
|
+
readPAGgepNodes(pag);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private:
|
|
62
|
+
// Write the PAGgepNode to the IR such that metadata name is the SVFIR node id and the operands
|
|
63
|
+
// are its base node's id and location offset
|
|
64
|
+
void writePAGgepNode(SVF::NodeID nodeId, GepObjVar* gepNode)
|
|
65
|
+
{
|
|
66
|
+
auto baseNodeId = gepNode->getBaseNode();
|
|
67
|
+
auto locationSetOffset = gepNode->getConstantFieldIdx();
|
|
68
|
+
|
|
69
|
+
LLVMContext &context = mainModule->getContext();
|
|
70
|
+
llvm::SmallVector<llvm::Metadata *, 32> operands;
|
|
71
|
+
operands.push_back(llvm::MDString::get(context, std::to_string(baseNodeId)));
|
|
72
|
+
operands.push_back(llvm::MDString::get(context, std::to_string(locationSetOffset)));
|
|
73
|
+
|
|
74
|
+
llvm::MDTuple *metadata = llvm::MDTuple::get(context, operands);
|
|
75
|
+
std::string label = "gepnode-" + std::to_string(nodeId);
|
|
76
|
+
|
|
77
|
+
mainModule->getOrInsertNamedMetadata(label)->addOperand(metadata);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Reads the PAGGepNodes in the annotated IR and creates a new SVFIR Node based on the
|
|
81
|
+
// data contained in the operands of the metadata node
|
|
82
|
+
void readPAGgepNodes(SVFIR *pag)
|
|
83
|
+
{
|
|
84
|
+
for (auto it = mainModule->named_metadata_begin(); it != mainModule->named_metadata_end(); ++it)
|
|
85
|
+
{
|
|
86
|
+
std::string label = it->getName().str();
|
|
87
|
+
std::string toErase = "gepnode-";
|
|
88
|
+
std::size_t pos = label.find(toErase);
|
|
89
|
+
if (pos == std::string::npos)
|
|
90
|
+
{
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
label.erase(pos, toErase.length());
|
|
94
|
+
|
|
95
|
+
SVF::NodeID nodeId = std::stoi(label);
|
|
96
|
+
auto mdNode = it->getOperand(0);
|
|
97
|
+
|
|
98
|
+
SVF::NodeID baseNodeId = std::stoi(llvm::cast<llvm::MDString>(mdNode->getOperand(0))->getString().str());
|
|
99
|
+
SVF::s32_t locationSetOffset = std::stoi(llvm::cast<llvm::MDString>(mdNode->getOperand(1))->getString().str());
|
|
100
|
+
|
|
101
|
+
LocationSet locationSet = LocationSet(locationSetOffset);
|
|
102
|
+
SVF::NodeID gepnodeId = pag->getGepObjVar(baseNodeId, locationSet);
|
|
103
|
+
|
|
104
|
+
assert(nodeId == gepnodeId && "nodeId != gepnodeId");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Deduce the LLVM value's type, and process the metadata accordingly
|
|
109
|
+
void processPAGNode(const Value *value, SVF::NodeID nodeId, bool writeFlag)
|
|
110
|
+
{
|
|
111
|
+
if (auto instruction = const_cast<Instruction *>(SVFUtil::dyn_cast<Instruction>(value)))
|
|
112
|
+
{
|
|
113
|
+
processInstructionNode(instruction, nodeId, writeFlag);
|
|
114
|
+
}
|
|
115
|
+
else if (auto argument = const_cast<Argument *>(SVFUtil::dyn_cast<Argument>(value)))
|
|
116
|
+
{
|
|
117
|
+
processArgumentNode(argument, nodeId, writeFlag);
|
|
118
|
+
}
|
|
119
|
+
else if (auto function = const_cast<Function *>(SVFUtil::dyn_cast<Function>(value)))
|
|
120
|
+
{
|
|
121
|
+
processFunctionNode(function, nodeId, writeFlag);
|
|
122
|
+
}
|
|
123
|
+
else if (auto globalVar = const_cast<GlobalVariable *>(SVFUtil::dyn_cast<GlobalVariable>(value)))
|
|
124
|
+
{
|
|
125
|
+
processGlobalVarNode(globalVar, nodeId, writeFlag);
|
|
126
|
+
}
|
|
127
|
+
else if (auto basicBlock = const_cast<BasicBlock *>(SVFUtil::dyn_cast<BasicBlock>(value)))
|
|
128
|
+
{
|
|
129
|
+
processBasicBlockNode(basicBlock, nodeId, writeFlag);
|
|
130
|
+
}
|
|
131
|
+
else if (SVFUtil::isa<Constant>(value))
|
|
132
|
+
{
|
|
133
|
+
processConstantNode(nodeId, writeFlag);
|
|
134
|
+
}
|
|
135
|
+
else if (auto inlineAsm = const_cast<llvm::InlineAsm *>(SVFUtil::dyn_cast<llvm::InlineAsm>(value)))
|
|
136
|
+
{
|
|
137
|
+
processInlineAsmNode(inlineAsm, nodeId, writeFlag);
|
|
138
|
+
}
|
|
139
|
+
else
|
|
140
|
+
{
|
|
141
|
+
SVFUtil::outs() << "Value is NOT a Instruction, Argument, Function, GlobalVariable, BasicBlock, Constant or InlineAsm" << std::endl;
|
|
142
|
+
SVFUtil::outs() << SVFUtil::value2String(value) << "\n";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
void processInstructionNode(Instruction *instruction, const SVF::NodeID &nodeId, bool writeFlag)
|
|
147
|
+
{
|
|
148
|
+
std::string label = "inode-" + std::to_string(nodeId);
|
|
149
|
+
|
|
150
|
+
if (writeFlag)
|
|
151
|
+
{
|
|
152
|
+
LLVMContext &context = instruction->getContext();
|
|
153
|
+
auto mdNodePts = getMdNodePts(nodeId, context);
|
|
154
|
+
instruction->setMetadata(label, mdNodePts);
|
|
155
|
+
}
|
|
156
|
+
else
|
|
157
|
+
{
|
|
158
|
+
auto mdNode = instruction->getMetadata(label);
|
|
159
|
+
assert(mdNode != nullptr && "Failed to retrive valid node id at instruction");
|
|
160
|
+
addAndersenMetadata(nodeId, mdNode);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
void processArgumentNode(Argument *argument, const SVF::NodeID &nodeId, bool writeFlag)
|
|
165
|
+
{
|
|
166
|
+
std::string label = "anode-" + std::to_string(nodeId);
|
|
167
|
+
|
|
168
|
+
if (writeFlag)
|
|
169
|
+
{
|
|
170
|
+
LLVMContext &context = argument->getContext();
|
|
171
|
+
auto mdNodePts = getMdNodePts(nodeId, context);
|
|
172
|
+
argument->getParent()->setMetadata(label, mdNodePts);
|
|
173
|
+
}
|
|
174
|
+
else
|
|
175
|
+
{
|
|
176
|
+
auto mdNode = argument->getParent()->getMetadata(label);
|
|
177
|
+
assert(mdNode != nullptr && "Failed to retrive valid node id at argument");
|
|
178
|
+
addAndersenMetadata(nodeId, mdNode);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
void processFunctionNode(Function *function, const SVF::NodeID &nodeId, bool writeFlag)
|
|
183
|
+
{
|
|
184
|
+
std::string label = "fnode-" + std::to_string(nodeId);
|
|
185
|
+
|
|
186
|
+
if (writeFlag)
|
|
187
|
+
{
|
|
188
|
+
LLVMContext &context = function->getContext();
|
|
189
|
+
auto mdNodePts = getMdNodePts(nodeId, context);
|
|
190
|
+
function->setMetadata(label, mdNodePts);
|
|
191
|
+
}
|
|
192
|
+
else
|
|
193
|
+
{
|
|
194
|
+
auto mdNode = function->getMetadata(label);
|
|
195
|
+
assert(mdNode != nullptr && "Failed to retrive valid node id at function");
|
|
196
|
+
addAndersenMetadata(nodeId, mdNode);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
void processGlobalVarNode(GlobalVariable *globalVar, const SVF::NodeID &nodeId, bool writeFlag)
|
|
201
|
+
{
|
|
202
|
+
std::string label = "gnode-" + std::to_string(nodeId);
|
|
203
|
+
|
|
204
|
+
if (writeFlag)
|
|
205
|
+
{
|
|
206
|
+
LLVMContext &context = globalVar->getContext();
|
|
207
|
+
auto mdNodePts = getMdNodePts(nodeId, context);
|
|
208
|
+
globalVar->setMetadata(label, mdNodePts);
|
|
209
|
+
}
|
|
210
|
+
else
|
|
211
|
+
{
|
|
212
|
+
auto mdNode = globalVar->getMetadata(label);
|
|
213
|
+
assert(mdNode != nullptr && "Failed to retrive valid node id at instruction");
|
|
214
|
+
addAndersenMetadata(nodeId, mdNode);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
void processBasicBlockNode(BasicBlock *basicBlock, const SVF::NodeID &nodeId, bool writeFlag)
|
|
219
|
+
{
|
|
220
|
+
std::string label = "bnode-" + std::to_string(nodeId);
|
|
221
|
+
|
|
222
|
+
if (writeFlag)
|
|
223
|
+
{
|
|
224
|
+
LLVMContext &context = basicBlock->getContext();
|
|
225
|
+
auto mdNodePts = getMdNodePts(nodeId, context);
|
|
226
|
+
basicBlock->getParent()->setMetadata(label, mdNodePts);
|
|
227
|
+
}
|
|
228
|
+
else
|
|
229
|
+
{
|
|
230
|
+
auto mdNode = basicBlock->getParent()->getMetadata(label);
|
|
231
|
+
assert(mdNode != nullptr && "Failed to retrive valid node id at basicBlock");
|
|
232
|
+
addAndersenMetadata(nodeId, mdNode);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
void processConstantNode(const SVF::NodeID &nodeId, bool writeFlag)
|
|
237
|
+
{
|
|
238
|
+
std::string label = "cnode-" + std::to_string(nodeId);
|
|
239
|
+
|
|
240
|
+
if (writeFlag)
|
|
241
|
+
{
|
|
242
|
+
LLVMContext &context = mainModule->getContext();
|
|
243
|
+
auto mdNodePts = getMdNodePts(nodeId, context);
|
|
244
|
+
mainModule->getOrInsertNamedMetadata(label)->addOperand(mdNodePts);
|
|
245
|
+
}
|
|
246
|
+
else
|
|
247
|
+
{
|
|
248
|
+
auto mdNode = mainModule->getNamedMetadata(label);
|
|
249
|
+
assert(mdNode != nullptr && "Failed to retrive valid node id at instruction");
|
|
250
|
+
addAndersenNamedMetdata(nodeId, mdNode);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
void processInlineAsmNode(llvm::InlineAsm *inlineAsm, const SVF::NodeID &nodeId, bool writeFlag)
|
|
255
|
+
{
|
|
256
|
+
std::string label = "iAsmnode-" + std::to_string(nodeId);
|
|
257
|
+
|
|
258
|
+
if (writeFlag)
|
|
259
|
+
{
|
|
260
|
+
LLVMContext &context = mainModule->getContext();
|
|
261
|
+
auto mdNodePts = getMdNodePts(nodeId, context);
|
|
262
|
+
mainModule->getOrInsertNamedMetadata(label)->addOperand(mdNodePts);
|
|
263
|
+
}
|
|
264
|
+
else
|
|
265
|
+
{
|
|
266
|
+
auto mdNode = mainModule->getNamedMetadata(label);
|
|
267
|
+
assert(mdNode != nullptr && "Failed to retrive valid node id at inlineAsm");
|
|
268
|
+
addAndersenNamedMetdata(nodeId, mdNode);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
void addAndersenMetadata(const SVF::NodeID &nodeId, MDNode *mdNode)
|
|
273
|
+
{
|
|
274
|
+
if (mdNode)
|
|
275
|
+
{
|
|
276
|
+
for (unsigned int i = 0; i < mdNode->getNumOperands(); i++)
|
|
277
|
+
{
|
|
278
|
+
auto anderNodeIdStr = llvm::cast<llvm::MDString>(mdNode->getOperand(i))->getString().str();
|
|
279
|
+
auto anderNodeId = SVF::NodeID(std::stoul(anderNodeIdStr));
|
|
280
|
+
ptsTo->addPts(nodeId, anderNodeId);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
void addAndersenNamedMetdata(const SVF::NodeID &nodeId, NamedMDNode *mdNode)
|
|
286
|
+
{
|
|
287
|
+
if (mdNode)
|
|
288
|
+
{
|
|
289
|
+
for (unsigned int i = 0; i < mdNode->getNumOperands(); i++)
|
|
290
|
+
{
|
|
291
|
+
auto node = mdNode->getOperand(i);
|
|
292
|
+
|
|
293
|
+
for (unsigned int j = 0; j < node->getNumOperands(); j++)
|
|
294
|
+
{
|
|
295
|
+
auto anderNodeIdStr = llvm::cast<llvm::MDString>(node->getOperand(j))->getString().str();
|
|
296
|
+
auto anderNodeId = SVF::NodeID(std::stoul(anderNodeIdStr));
|
|
297
|
+
ptsTo->addPts(nodeId, anderNodeId);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
inline llvm::MDTuple* getMdNodePts(const SVF::NodeID &nodeId, LLVMContext &context)
|
|
304
|
+
{
|
|
305
|
+
llvm::SmallVector<llvm::Metadata *, 32> operands;
|
|
306
|
+
auto &ptTo = ptsTo->getPts(nodeId);
|
|
307
|
+
for (const auto p : ptTo)
|
|
308
|
+
{
|
|
309
|
+
operands.push_back(llvm::MDString::get(context, std::to_string(p)));
|
|
310
|
+
}
|
|
311
|
+
return llvm::MDTuple::get(context, operands);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
Module* mainModule;
|
|
315
|
+
BVDataPTAImpl *ptsTo;
|
|
316
|
+
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
} // End namespace SVF
|
|
320
|
+
|
|
321
|
+
#endif /* IRANNOTATOR_H_ */
|