Static Value-Flow Analysis
Loading...
Searching...
No Matches
CHG.cpp
Go to the documentation of this file.
1//===----- CHG.cpp Base class of pointer analyses ---------------------------//
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 * CHG.cpp (previously CHA.cpp)
25 *
26 * Created on: Apr 13, 2016
27 * Author: Xiaokang Fan
28 */
29
30#include "Graphs/CHG.h"
31#include "Graphs/GraphPrinter.h"
32#include "Graphs/ICFG.h"
33#include "Util/GeneralType.h"
34#include "Util/SVFUtil.h"
35
36using namespace SVF;
37using namespace SVFUtil;
38using namespace std;
39
40static bool hasEdge(const CHNode *src, const CHNode *dst,
42{
43 for (CHEdge::CHEdgeSetTy::const_iterator it = src->getOutEdges().begin(),
44 eit = src->getOutEdges().end(); it != eit; ++it)
45 {
46 CHNode *node = (*it)->getDstNode();
47 CHEdge::CHEDGETYPE edgeType = (*it)->getEdgeType();
48 if (node == dst && edgeType == et)
49 return true;
50 }
51 return false;
52}
53
54static bool checkArgTypes(const CallICFGNode* cs, const FunObjVar* fn)
55{
56
57 // here we skip the first argument (i.e., this pointer)
58 u32_t arg_size = (fn->arg_size() > cs->arg_size()) ? cs->arg_size(): fn->arg_size();
59 if(arg_size > 1)
60 {
61 for (unsigned i = 1; i < arg_size; i++)
62 {
63 auto cs_arg = cs->getArgument(i);
64 auto fn_arg = fn->getArg(i);
65 if (cs_arg->getType() != fn_arg->getType())
66 {
67 return false;
68 }
69 }
70 }
71
72 return true;
73}
74
76{
77 CallNodeToVTableSetMap::const_iterator it = callNodeToCHAVtblsMap.find(cs);
78 return it != callNodeToCHAVtblsMap.end();
79}
81{
82 CallNodeToVFunSetMap::const_iterator it = callNodeToCHAVFnsMap.find(cs);
83 return it != callNodeToCHAVFnsMap.end();
84}
86{
87 CallNodeToVTableSetMap::const_iterator it = callNodeToCHAVtblsMap.find(cs);
88 assert(it != callNodeToCHAVtblsMap.end() && "cs does not have vtabls based on CHA.");
89 return it->second;
90}
92{
93 CallNodeToVFunSetMap::const_iterator it = callNodeToCHAVFnsMap.find(cs);
94 assert(it != callNodeToCHAVFnsMap.end() && "cs does not have vfns based on CHA.");
95 return it->second;
96}
97
98void CHGraph::addEdge(const string className, const string baseClassName,
99 CHEdge::CHEDGETYPE edgeType)
100{
101 CHNode *srcNode = getNode(className);
103 assert(srcNode && dstNode && "node not found?");
104
105 if (!hasEdge(srcNode, dstNode, edgeType))
106 {
107 CHEdge *edge = new CHEdge(srcNode, dstNode, edgeType);
108 srcNode->addOutgoingEdge(edge);
109 dstNode->addIncomingEdge(edge);
110 }
111}
112
113CHNode *CHGraph::getNode(const string name) const
114{
115 auto chNode = classNameToNodeMap.find(name);
116 if (chNode != classNameToNodeMap.end()) return chNode->second;
117 else return nullptr;
118}
119
120
121/*
122 * Get virtual functions for callsite "cs" based on vtbls (calculated
123 * based on pointsto set)
124 */
126{
128 size_t idx = callsite->getFunIdxInVtable();
130 string funName = callsite->getFunNameOfVirtualCall();
131 for (const GlobalObjVar *vt : vtbls)
132 {
133 const CHNode *child = getNode(vt->getName());
134 if (child == nullptr)
135 continue;
137 child->getVirtualFunctions(idx, vfns);
138 for (CHNode::FuncVector::const_iterator fit = vfns.begin(),
139 feit = vfns.end(); fit != feit; ++fit)
140 {
141 const FunObjVar* callee = *fit;
142 if (callsite->arg_size() == callee->arg_size() ||
143 (callsite->isVarArg() && callee->isVarArg()))
144 {
145
146 // if argument types do not match
147 // skip this one
148 if (!checkArgTypes(callsite, callee))
149 continue;
150
151 string calleeName = callee->getName();
152
153 /*
154 * The compiler will add some special suffix (e.g.,
155 * "[abi:cxx11]") to the end of some virtual function:
156 * In dealII
157 * function: FE_Q<3>::get_name
158 * will be mangled as: _ZNK4FE_QILi3EE8get_nameB5cxx11Ev
159 * after demangling: FE_Q<3>::get_name[abi:cxx11]
160 * The special suffix ("[abi:cxx11]") needs to be removed
161 */
162 const std::string suffix("[abi:cxx11]");
163 size_t suffix_pos = calleeName.rfind(suffix);
164 if (suffix_pos != string::npos)
165 calleeName.erase(suffix_pos, suffix.size());
166
167 /*
168 * if we can't get the function name of a virtual callsite, all virtual
169 * functions calculated by idx will be valid
170 */
171 if (funName.size() == 0)
172 {
173 virtualFunctions.insert(callee);
174 }
175 else if (funName[0] == '~')
176 {
177 /*
178 * if the virtual callsite is calling a destructor, then all
179 * destructors in the ch will be valid
180 * class A { virtual ~A(){} };
181 * class B: public A { virtual ~B(){} };
182 * int main() {
183 * A *a = new B;
184 * delete a; /// the function name of this virtual callsite is ~A()
185 * }
186 */
187 if (calleeName[0] == '~')
188 {
189 virtualFunctions.insert(callee);
190 }
191 }
192 else
193 {
194 /*
195 * for other virtual function calls, the function name of the callsite
196 * and the function name of the target callee should match exactly
197 */
198 if (funName.compare(calleeName) == 0)
199 {
200 virtualFunctions.insert(callee);
201 }
202 }
203 }
204 }
205 }
206}
207
208
210{
212 eit = virtualFunctionVectors.end(); it != eit; ++it)
213 {
214 if ((*it).size() > idx)
215 virtualFunctions.push_back((*it)[idx]);
216 }
217}
218
220{
221 for (CHGraph::const_iterator it = this->begin(), eit = this->end();
222 it != eit; ++it)
223 {
224 const CHNode *node = it->second;
225 outs() << "class: " << node->getName() << "\n";
226 for (CHEdge::CHEdgeSetTy::const_iterator it = node->OutEdgeBegin();
227 it != node->OutEdgeEnd(); ++it)
228 {
229 if ((*it)->getEdgeType() == CHEdge::INHERITANCE)
230 outs() << (*it)->getDstNode()->getName() << " --inheritance--> "
231 << (*it)->getSrcNode()->getName() << "\n";
232 else
233 outs() << (*it)->getSrcNode()->getName() << " --instance--> "
234 << (*it)->getDstNode()->getName() << "\n";
235 }
236 }
237 outs() << '\n';
238}
239
243void CHGraph::dump(const std::string& filename)
244{
246 printCH();
247}
248
250{
251 SVF::ViewGraph(this, "Class Hierarchy Graph");
252}
253
254namespace SVF
255{
256
260template<>
262{
263
265 DOTGraphTraits(bool isSimple = false) :
266 DefaultDOTGraphTraits(isSimple)
267 {
268 }
269
271 static std::string getGraphName(CHGraph*)
272 {
273 return "Class Hierarchy Graph";
274 }
276 static std::string getNodeLabel(CHNode *node, CHGraph*)
277 {
278 return node->getName();
279 }
280
281 static std::string getNodeAttributes(CHNode *node, CHGraph*)
282 {
283 if (node->isPureAbstract())
284 {
285 return "shape=tab";
286 }
287 else
288 return "shape=box";
289 }
290
291 template<class EdgeIter>
293 {
294
295 CHEdge* edge = *(EI.getCurrent());
296 assert(edge && "No edge found!!");
297 if (edge->getEdgeType() == CHEdge::INHERITANCE)
298 {
299 return "style=solid";
300 }
301 else
302 {
303 return "style=dashed";
304 }
305 }
306};
307} // End namespace llvm
static bool hasEdge(const CHNode *src, const CHNode *dst, CHEdge::CHEDGETYPE et)
Definition CHG.cpp:40
static bool checkArgTypes(const CallICFGNode *cs, const FunObjVar *fn)
Definition CHG.cpp:54
unsigned u32_t
Definition CommandLine.h:18
cJSON * child
Definition cJSON.cpp:2723
const char *const name
Definition cJSON.h:264
CHEDGETYPE
Definition CHG.h:83
@ INHERITANCE
Definition CHG.h:84
CallNodeToVFunSetMap callNodeToCHAVFnsMap
Definition CHG.h:339
void dump(const std::string &filename)
Definition CHG.cpp:243
bool csHasVtblsBasedonCHA(const CallICFGNode *cs) override
Definition CHG.cpp:75
void addEdge(const std::string className, const std::string baseClassName, CHEdge::CHEDGETYPE edgeType)
Definition CHG.cpp:98
bool csHasVFnsBasedonCHA(const CallICFGNode *cs) override
Definition CHG.cpp:80
const VFunSet & getCSVFsBasedonCHA(const CallICFGNode *cs) override
Definition CHG.cpp:91
const VTableSet & getCSVtblsBasedonCHA(const CallICFGNode *cs) override
Definition CHG.cpp:85
void getVFnsFromVtbls(const CallICFGNode *cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override
Definition CHG.cpp:125
CHNode * getNode(const std::string name) const
Definition CHG.cpp:113
void view()
Definition CHG.cpp:249
void printCH()
Definition CHG.cpp:219
Map< std::string, CHNode * > classNameToNodeMap
Definition CHG.h:329
CallNodeToVTableSetMap callNodeToCHAVtblsMap
Definition CHG.h:338
virtual const std::string & getName() const
Definition CHG.h:127
void getVirtualFunctions(u32_t idx, FuncVector &virtualFunctions) const
Definition CHG.cpp:209
bool isPureAbstract() const
Definition CHG.h:157
std::vector< FuncVector > virtualFunctionVectors
Definition CHG.h:225
std::vector< const FunObjVar * > FuncVector
Definition CHG.h:118
const ValVar * getArgument(u32_t ArgNo) const
Parameter operations.
Definition ICFGNode.h:483
bool isVarArg() const
Definition ICFGNode.h:506
s32_t getFunIdxInVtable() const
Definition ICFGNode.h:527
u32_t arg_size() const
Definition ICFGNode.h:488
const std::string & getFunNameOfVirtualCall() const
Definition ICFGNode.h:534
iterator begin()
Iterators.
IDToNodeMapTy::const_iterator const_iterator
iterator OutEdgeEnd()
const GEdgeSetTy & getOutEdges() const
iterator OutEdgeBegin()
iterators
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
virtual const std::string & getName() const
Definition SVFValue.h:186
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
Set< const GlobalObjVar * > VTableSet
Definition CHG.h:46
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:67
Set< const FunObjVar * > VFunSet
Definition CHG.h:47
DOTGraphTraits(bool isSimple=false)
Definition CHG.cpp:265
static std::string getNodeLabel(CHNode *node, CHGraph *)
Return function name;.
Definition CHG.cpp:276
static std::string getGraphName(CHGraph *)
Return name of the graph.
Definition CHG.cpp:271
static std::string getNodeAttributes(CHNode *node, CHGraph *)
Definition CHG.cpp:281
static std::string getEdgeAttributes(CHNode *, EdgeIter EI, CHGraph *)
Definition CHG.cpp:292