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