Static Value-Flow Analysis
svf-ex.cpp
Go to the documentation of this file.
1 //===- svf-ex.cpp -- A driver example of SVF-------------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <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  // A driver program of SVF including usages of SVF APIs
25  //
26  // Author: Yulei Sui,
27  */
28 
29 #include "AE/Core/AbstractState.h"
30 #include "Graphs/SVFG.h"
31 #include "SVF-LLVM/LLVMUtil.h"
32 #include "SVF-LLVM/SVFIRBuilder.h"
33 #include "Util/CommandLine.h"
34 #include "Util/Options.h"
35 #include "WPA/Andersen.h"
36 
37 using namespace llvm;
38 using namespace std;
39 using namespace SVF;
40 
45 {
46  return pta->alias(v1, v2);
47 }
48 
53 {
54 
55  std::string str;
56  raw_string_ostream rawstr(str);
57 
58  NodeID pNodeId = pta->getPAG()->getValueNode(svfval);
59  const PointsTo& pts = pta->getPts(pNodeId);
60  for (PointsTo::iterator ii = pts.begin(), ie = pts.end();
61  ii != ie; ii++)
62  {
63  rawstr << " " << *ii << " ";
64  PAGNode* targetObj = pta->getPAG()->getGNode(*ii);
65  if(targetObj->hasValue())
66  {
67  rawstr << "(" << targetObj->getValue()->toString() << ")\t ";
68  }
69  }
70 
71  return rawstr.str();
72 
73 }
77 void traverseOnICFG(ICFG* icfg, const ICFGNode* iNode)
78 {
80  Set<const ICFGNode*> visited;
81  worklist.push(iNode);
82 
84  while (!worklist.empty())
85  {
86  const ICFGNode* vNode = worklist.pop();
87  for (ICFGNode::const_iterator it = vNode->OutEdgeBegin(), eit =
88  vNode->OutEdgeEnd(); it != eit; ++it)
89  {
90  ICFGEdge* edge = *it;
91  ICFGNode* succNode = edge->getDstNode();
92  if (visited.find(succNode) == visited.end())
93  {
94  visited.insert(succNode);
95  worklist.push(succNode);
96  }
97  }
98  }
99 }
100 
101 void dummyVisit(const VFGNode* node)
102 {
103 
104 }
108 void traverseOnVFG(const SVFG* vfg, const SVFValue* svfval)
109 {
110  SVFIR* pag = SVFIR::getPAG();
111  PAGNode* pNode = pag->getGNode(pag->getValueNode(svfval));
112  if (!vfg->hasDefSVFGNode(pNode))
113  return;
114  const VFGNode* vNode = vfg->getDefSVFGNode(pNode);
116  Set<const VFGNode*> visited;
117  worklist.push(vNode);
118 
120  while (!worklist.empty())
121  {
122  const VFGNode* vNode = worklist.pop();
123  for (VFGNode::const_iterator it = vNode->OutEdgeBegin(), eit =
124  vNode->OutEdgeEnd(); it != eit; ++it)
125  {
126  VFGEdge* edge = *it;
127  VFGNode* succNode = edge->getDstNode();
128  if (visited.find(succNode) == visited.end())
129  {
130  visited.insert(succNode);
131  worklist.push(succNode);
132  }
133  }
134  }
135 
137  for(Set<const VFGNode*>::const_iterator it = visited.begin(), eit = visited.end(); it!=eit; ++it)
138  {
139  const VFGNode* node = *it;
140  dummyVisit(node);
144  }
145 }
146 
147 int main(int argc, char ** argv)
148 {
149 
150  std::vector<std::string> moduleNameVec;
151  moduleNameVec = OptionBase::parseOptions(
152  argc, argv, "Whole Program Points-to Analysis", "[options] <input-bitcode...>"
153  );
154 
155  if (Options::WriteAnder() == "ir_annotator")
156  {
157  LLVMModuleSet::preProcessBCs(moduleNameVec);
158  }
159 
160  SVFModule* svfModule = LLVMModuleSet::buildSVFModule(moduleNameVec);
161 
163  SVFIRBuilder builder(svfModule);
164  SVFIR* pag = builder.build();
165 
167  Andersen* ander = AndersenWaveDiff::createAndersenWaveDiff(pag);
168 
169 
171  PTACallGraph* callgraph = ander->getCallGraph();
172 
174  ICFG* icfg = pag->getICFG();
175 
177  VFG* vfg = new VFG(callgraph);
178 
180  SVFGBuilder svfBuilder;
181  SVFG* svfg = svfBuilder.buildFullSVFG(ander);
182 
184  if (Options::PTSPrint())
185  {
186  for (const auto& it : *svfg)
187  {
188  const SVFGNode* node = it.second;
189  if (node->getValue())
190  {
191  traverseOnVFG(svfg, node->getValue());
193  printPts(ander, node->getValue());
194  for (const SVFGEdge* edge : node->getOutEdges())
195  {
196  const SVFGNode* node2 = edge->getDstNode();
197  if (node2->getValue())
198  aliasQuery(ander, node->getValue(), node2->getValue());
199  }
200  }
201  }
202  }
203 
205  if (Options::PTSPrint())
206  {
207  for (const auto& it : *icfg)
208  {
209  const ICFGNode* node = it.second;
210  traverseOnICFG(icfg, node);
211  }
212  }
213 
214  // clean up memory
215  delete vfg;
216  AndersenWaveDiff::releaseAndersenWaveDiff();
217  SVFIR::releaseSVFIR();
218 
219  LLVMModuleSet::getLLVMModuleSet()->dumpModulesToFile(".svf.bc");
221  llvm::llvm_shutdown();
222  return 0;
223 }
224 
const char *const string
Definition: cJSON.h:172
static std::vector< std::string > parseOptions(int argc, char *argv[], std::string description, std::string callFormat)
Definition: CommandLine.h:75
bool push(const Data &data)
Definition: WorkList.h:165
bool empty() const
Definition: WorkList.h:146
NodeType * getDstNode() const
Definition: GenericGraph.h:101
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
iterator OutEdgeEnd()
Definition: GenericGraph.h:458
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
iterator OutEdgeBegin()
iterators
Definition: GenericGraph.h:454
ICFGEdge::ICFGEdgeSetTy::const_iterator const_iterator
Definition: ICFGNode.h:62
Definition: ICFG.h:48
NodeID getValueNode(const SVFValue *V)
Definition: IRGraph.h:137
static void releaseLLVMModuleSet()
Definition: LLVMModule.h:125
SVFIR * getPAG() const
virtual const PointsTo & getPts(NodeID ptr)=0
Get points-to targets of a pointer. It needs to be implemented in child class.
PTACallGraph * getCallGraph() const
Return call graph.
virtual AliasResult alias(const SVFValue *V1, const SVFValue *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
const_iterator end() const
Definition: PointsTo.h:132
const_iterator begin() const
Definition: PointsTo.h:128
SVFG * buildFullSVFG(BVDataPTAImpl *pta)
Definition: SVFGBuilder.cpp:49
Definition: SVFG.h:66
const SVFGNode * getDefSVFGNode(const PAGNode *pagNode) const
Given a pagNode, return its definition site.
Definition: SVFG.h:171
bool hasDefSVFGNode(const PAGNode *pagNode) const
Given a pagNode, return whether it has definition site.
Definition: SVFG.h:177
virtual SVFIR * build()
Start building SVFIR here.
ICFG * getICFG() const
Definition: SVFIR.h:171
std::string toString() const
Needs to be implemented by a SVF front end.
Definition: LLVMUtil.cpp:663
bool hasValue() const
Definition: SVFVariables.h:101
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
Definition: VFGNode.h:55
virtual const SVFValue * getValue() const
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition: VFGNode.h:85
Definition: VFG.h:51
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
AliasResult
Definition: SVFType.h:527
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96
void traverseOnICFG(ICFG *icfg, const ICFGNode *iNode)
Definition: svf-ex.cpp:77
std::string printPts(PointerAnalysis *pta, const SVFValue *svfval)
Definition: svf-ex.cpp:52
int main(int argc, char **argv)
Definition: svf-ex.cpp:147
void traverseOnVFG(const SVFG *vfg, const SVFValue *svfval)
Definition: svf-ex.cpp:108
void dummyVisit(const VFGNode *node)
Definition: svf-ex.cpp:101
SVF::AliasResult aliasQuery(PointerAnalysis *pta, const SVFValue *v1, const SVFValue *v2)
Definition: svf-ex.cpp:44