Static Value-Flow Analysis
TypeAnalysis.cpp
Go to the documentation of this file.
1 //===- TypeAnalysis.cpp -- Fast type-based analysis without pointer analysis------//
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 Affero 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 Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * TypeAnalysis.cpp
25  *
26  * Created on: 7 Sep. 2018
27  * Author: Yulei Sui
28  */
29 
30 #include "WPA/TypeAnalysis.h"
31 #include "Graphs/CHG.h"
32 #include "Graphs/ICFGStat.h"
33 #include "Graphs/VFG.h"
34 #include "Util/Options.h"
35 #include "Util/PTAStat.h"
36 
37 using namespace SVF;
38 using namespace SVFUtil;
39 using namespace std;
40 
41 
44 {
46  if (Options::DumpICFG())
47  {
48  icfg = SVFIR::getPAG()->getICFG();
49  icfg->dump("icfg_initial");
50  icfg->dump("vfg_initial");
51  if (print_stat)
52  {
53  ICFGStat stat(icfg);
54  stat.performStat();
55  }
56  }
57 }
58 
61 {
63  if (print_stat)
64  dumpCHAStats();
65 }
66 
68 {
69  initialize();
70  CallEdgeMap newEdges;
71  callGraphSolveBasedOnCHA(getIndirectCallsites(), newEdges);
72  finalize();
73 }
74 
76 {
77  for(CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter!=eiter; ++iter)
78  {
79  const CallICFGNode* cbn = iter->first;
80  if (cbn->isVirtualCall())
81  {
82  const SVFVar* vtbl = cbn->getVtablePtr();
83  (void)vtbl; // Suppress warning of unused variable under release build
84  assert(vtbl != nullptr);
85  VFunSet vfns;
86  getVFnsFromCHA(cbn, vfns);
87  connectVCallToVFns(cbn, vfns, newEdges);
88  }
89  }
90 }
91 
92 
94 {
95 
96  const CHGraph *chgraph = SVFUtil::dyn_cast<CHGraph>(getCHGraph());
97  if (chgraph == nullptr)
98  {
99  SVFUtil::errs() << "dumpCHAStats only implemented for standard CHGraph.\n";
100  return;
101  }
102 
103  u32_t pure_abstract_class_num = 0,
104  multi_inheritance_class_num = 0;
105  for (CHGraph::const_iterator it = chgraph->begin(), eit = chgraph->end();
106  it != eit; ++it)
107  {
108  CHNode *node = it->second;
109  outs() << "class " << node->getName() << "\n";
110  if (node->isPureAbstract())
111  pure_abstract_class_num++;
112  if (node->isMultiInheritance())
113  multi_inheritance_class_num++;
114  }
115  outs() << "class_num:\t" << chgraph->getTotalNodeNum() << '\n';
116  outs() << "pure_abstract_class_num:\t" << pure_abstract_class_num << '\n';
117  outs() << "multi_inheritance_class_num:\t" << multi_inheritance_class_num << '\n';
118 
119  /*
120  * count the following info:
121  * vtblnum
122  * total vfunction
123  * vtbl max vfunction
124  * pure abstract class
125  */
126  u32_t vtblnum = 0,
127  vfunc_total = 0,
128  vtbl_max = 0,
129  pure_abstract = 0;
130  set<const SVFFunction*> allVirtualFunctions;
131  for (CHGraph::const_iterator it = chgraph->begin(), eit = chgraph->end();
132  it != eit; ++it)
133  {
134  CHNode *node = it->second;
135  if (node->isPureAbstract())
136  pure_abstract++;
137 
138  u32_t vfuncs_size = 0;
139  const vector<CHNode::FuncVector>& vecs = node->getVirtualFunctionVectors();
140  for (vector<CHNode::FuncVector>::const_iterator vit = vecs.begin(),
141  veit = vecs.end(); vit != veit; ++vit)
142  {
143  vfuncs_size += (*vit).size();
144  for (vector<const SVFFunction*>::const_iterator fit = (*vit).begin(),
145  feit = (*vit).end(); fit != feit; ++fit)
146  {
147  const SVFFunction* func = *fit;
148  allVirtualFunctions.insert(func);
149  }
150  }
151  if (vfuncs_size > 0)
152  {
153  vtblnum++;
154  if (vfuncs_size > vtbl_max)
155  {
156  vtbl_max = vfuncs_size;
157  }
158  }
159  }
160  vfunc_total = allVirtualFunctions.size();
161 
162  outs() << "vtblnum:\t" << vtblnum << '\n';
163  outs() << "vtbl_average:\t" << (double)(vfunc_total)/vtblnum << '\n';
164  outs() << "vtbl_max:\t" << vtbl_max << '\n';
165  outs() << "pure_abstract:\t" << pure_abstract << '\n';
166 }
167 
168 
virtual void finalize() override
Finalize analysis.
Definition: Andersen.cpp:89
virtual void initialize() override
Initialize analysis.
Definition: Andersen.cpp:73
bool isMultiInheritance() const
Definition: CHG.h:164
bool isPureAbstract() const
Definition: CHG.h:160
const std::vector< FuncVector > & getVirtualFunctionVectors() const
Definition: CHG.h:178
std::string getName() const
Definition: CHG.h:130
const SVFVar * getVtablePtr() const
Definition: ICFGNode.h:537
bool isVirtualCall() const
Definition: ICFGNode.h:527
iterator begin()
Iterators.
Definition: GenericGraph.h:627
IDToNodeMapTy::const_iterator const_iterator
Definition: GenericGraph.h:607
u32_t getTotalNodeNum() const
Get total number of node/edge.
Definition: GenericGraph.h:680
void performStat()
Definition: ICFGStat.h:75
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition: ICFG.cpp:403
static const Option< bool > DumpICFG
Definition: Options.h:123
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
Set< const SVFFunction * > VFunSet
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
ICFG * getICFG() const
Definition: SVFIR.h:171
void dumpCHAStats()
Statistics of CHA and callgraph.
virtual void finalize() override
Finalize analysis.
void initialize() override
Initialize analysis.
void analyze() override
Type analysis.
void callGraphSolveBasedOnCHA(const CallSiteToFunPtrMap &callsites, CallEdgeMap &newEdges)
Resolve callgraph based on CHA.
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
unsigned u32_t
Definition: GeneralType.h:46