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.
@@ -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/Conditions.h"
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 CondExpr Condition; /// z3 condition
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 CondExpr* cond, const Instruction* inst){
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
- CondManager* condMgr; ///< z3 manager
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 "Util/CFLSolver.h"
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 CFLSolver<SVFG*,CxtDPItem> CFLSrcSnkSolver;
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_ */