Static Value-Flow Analysis
Loading...
Searching...
No Matches
CHGBuilder.cpp
Go to the documentation of this file.
1//===----- CHGBuilder.cpp -- Class hierarchy graph builder ---------------------------//
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 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 * CHGBuilder.cpp
25 *
26 * Created on: Jun 4, 2021
27 * Author: Yulei Sui
28 */
29
30#include <set>
31#include <vector>
32#include <map>
33#include <fstream>
34#include <iostream>
35#include <iomanip> // setw() for formatting cout
36#include <assert.h>
37#include <stack>
38
39#include "SVF-LLVM/CHGBuilder.h"
40#include "Util/Options.h"
41#include "SVF-LLVM/CppUtil.h"
43#include "Util/SVFUtil.h"
44#include "SVF-LLVM/LLVMUtil.h"
45#include "SVFIR/SVFModule.h"
46#include "Util/PTAStat.h"
47#include "SVF-LLVM/LLVMModule.h"
49
50using namespace SVF;
51using namespace SVFUtil;
52using namespace cppUtil;
53using namespace LLVMUtil;
54using namespace std;
55
56const string pureVirtualFunName = "__cxa_pure_virtual";
57
58const string ztiLabel = "_ZTI";
59
64
66{
67
68 double timeStart, timeEnd;
71 {
72 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("construct CHGraph From module "
73 + M.getName().str() + "...\n"));
75 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
76 buildCHGNodes(&(*I));
77 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
78 buildCHGNodes(&(*F));
79 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
80 buildCHGEdges(&(*F));
81
83 }
84
85 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("build Internal Maps ...\n"));
87
90
91 if (Options::DumpCHA())
92 chg->dump("cha");
93}
94
96{
97 if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
98 {
100 string className = getClassNameFromVtblObj(globalvalue->getName().str());
101 if (!chg->getNode(className))
102 createNode(className);
103
104 for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
105 {
106 const ConstantArray *vtbl = SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
107 assert(vtbl && "Element of initializer not an array?");
108 for (u32_t i = 0; i < vtbl->getNumOperands(); ++i)
109 {
110 if(const ConstantExpr *ce = isCastConstantExpr(vtbl->getOperand(i)))
111 {
112 const Value* bitcastValue = ce->getOperand(0);
113 if (const Function* func = SVFUtil::dyn_cast<Function>(bitcastValue))
114 {
115 struct DemangledName dname = demangle(func->getName().str());
116 if (!chg->getNode(dname.className))
117 createNode(dname.className);
118 }
119 }
120 }
121 }
122 }
123}
124
126{
127 if (isConstructor(F) || isDestructor(F))
128 {
129 struct DemangledName dname = demangle(F->getName().str());
130 DBOUT(DCHA, outs() << "\t build CHANode for class " + dname.className + "...\n");
131 if (!chg->getNode(dname.className))
132 createNode(dname.className);
133 }
134}
135
137{
138 if (isConstructor(F) || isDestructor(F))
139 {
140 for (Function::const_iterator B = F->begin(), E = F->end(); B != E; ++B)
141 {
142 for (BasicBlock::const_iterator I = B->begin(), E = B->end(); I != E; ++I)
143 {
144 if (LLVMUtil::isCallSite(&(*I)))
145 {
146 connectInheritEdgeViaCall(F, SVFUtil::cast<CallBase>(&(*I)));
147 }
148 else if (const StoreInst *store = SVFUtil::dyn_cast<StoreInst>(&(*I)))
149 {
151 }
152 }
153 }
154 }
155}
156
157
164
166{
167 if (getCallee(cs) == nullptr)
168 return;
169
170 const Function* callee = getCallee(cs);
171
172 struct DemangledName dname = demangle(caller->getName().str());
174 {
175 if (cs->arg_size() < 1 || (cs->arg_size() < 2 && cs->paramHasAttr(0, llvm::Attribute::StructRet)))
176 return;
178 //const Argument* consThisPtr = getConstructorThisPtr(caller);
179 //bool samePtr = isSameThisPtrInConstructor(consThisPtr, csThisPtr);
180 bool samePtrTrue = true;
181 if (csThisPtr != nullptr && samePtrTrue)
182 {
183 struct DemangledName basename = demangle(callee->getName().str());
185 basename.className.size() > 0)
186 {
187 chg->addEdge(dname.className, basename.className, CHEdge::INHERITANCE);
188 }
189 }
190 }
191}
192
194{
195 struct DemangledName dname = demangle(caller->getName().str());
196 if (const ConstantExpr *ce = SVFUtil::dyn_cast<ConstantExpr>(storeInst->getValueOperand()))
197 {
198 if (ce->getOpcode() == Instruction::BitCast)
199 {
200 const Value* bitcastval = ce->getOperand(0);
201 if (const ConstantExpr *bcce = SVFUtil::dyn_cast<ConstantExpr>(bitcastval))
202 {
203 if (bcce->getOpcode() == Instruction::GetElementPtr)
204 {
205 const Value* gepval = bcce->getOperand(0);
207 {
208 string vtblClassName = getClassNameFromVtblObj(gepval->getName().str());
209 if (vtblClassName.size() > 0 && dname.className.compare(vtblClassName) != 0)
210 {
212 }
213 }
214 }
215 }
216 }
217 }
218}
219
221{
222 for (Module::const_named_metadata_iterator mdit = M.named_metadata_begin(),
223 mdeit = M.named_metadata_end(); mdit != mdeit; ++mdit)
224 {
225 const NamedMDNode *md = &*mdit;
226 string mdname = md->getName().str();
227 if (mdname.compare(0, 15, "__cxx_bases_of_") != 0)
228 continue;
229 string className = mdname.substr(15);
230 for (NamedMDNode::const_op_iterator opit = md->op_begin(),
231 opeit = md->op_end(); opit != opeit; ++opit)
232 {
233 const MDNode *N = *opit;
234 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
235 string baseName = mdstr->getString().str();
237 }
238 }
239}
240
241CHNode *CHGBuilder::createNode(const std::string& className)
242{
243 assert(!chg->getNode(className) && "this node should never be created before!");
244 CHNode * node = new CHNode(className, chg->classNum++);
245 chg->classNameToNodeMap[className] = node;
246 chg->addGNode(node->getId(), node);
247 if (className.size() > 0 && className[className.size() - 1] == '>')
248 {
249 string templateName = getBeforeBrackets(className);
251 if (!templateNode)
252 {
253 DBOUT(DCHA, outs() << "\t Create Template CHANode " + templateName + " for class " + className + "...\n");
255 templateNode->setTemplate();
256 }
259 }
260 return node;
261}
262
263/*
264 * build the following two maps:
265 * classNameToDescendantsMap
266 * chg->classNameToAncestorsMap
267 */
269{
270
271 for (CHGraph::const_iterator it = chg->begin(), eit = chg->end();
272 it != eit; ++it)
273 {
274 const CHNode *node = it->second;
275 WorkList worklist;
277 worklist.push(node);
278 while (!worklist.empty())
279 {
280 const CHNode *curnode = worklist.pop();
281 if (visitedNodes.find(curnode) == visitedNodes.end())
282 {
283 for (CHEdge::CHEdgeSetTy::const_iterator it =
284 curnode->getOutEdges().begin(), eit =
285 curnode->getOutEdges().end(); it != eit; ++it)
286 {
287 if ((*it)->getEdgeType() == CHEdge::INHERITANCE)
288 {
289 CHNode *succnode = (*it)->getDstNode();
291 chg->classNameToDescendantsMap[succnode->getName()].insert(node);
292 worklist.push(succnode);
293 }
294 }
295 visitedNodes.insert(curnode);
296 }
297 }
298 }
299}
300
302 const string& className)
303{
304
305 CHGraph::NameToCHNodesMap::const_iterator it = chg->classNameToInstAndDescsMap.find(className);
306 if (it != chg->classNameToInstAndDescsMap.end())
307 {
308 return it->second;
309 }
310 else
311 {
312 chg->classNameToInstAndDescsMap[className] = chg->getDescendants(className);
313 if (chg->getNode(className)->isTemplate())
314 {
315 const CHNodeSetTy& instances = chg->getInstances(className);
316 for (CHNodeSetTy::const_iterator it = instances.begin(), eit = instances.end(); it != eit; ++it)
317 {
318 const CHNode *node = *it;
319 chg->classNameToInstAndDescsMap[className].insert(node);
321 for (CHNodeSetTy::const_iterator dit =
322 instance_descendants.begin(), deit =
323 instance_descendants.end(); dit != deit; ++dit)
324 {
325 chg->classNameToInstAndDescsMap[className].insert(*dit);
326 }
327 }
328 }
329 return chg->classNameToInstAndDescsMap[className];
330 }
331}
332
333
334
335
336/*
337 * do the following things:
338 * 1. initialize virtualFunctions for each class
339 * 2. mark multi-inheritance classes
340 * 3. mark pure abstract classes
341 *
342 * Layout of VTables:
343 *
344 * 1. single inheritance
345 * class A {...};
346 * class B: public A {...};
347 * B's vtable: {i8 *null, _ZTI1B, ...}
348 *
349 * 2. normal multiple inheritance
350 * class A {...};
351 * class B {...};
352 * class C: public A, public B {...};
353 * C's vtable: {i8 *null, _ZTI1C, ..., inttoptr xxx, _ZTI1C, ...}
354 * "inttoptr xxx" servers as a delimiter for dividing virtual methods inherited
355 * from "class A" and "class B"
356 *
357 * 3. virtual diamond inheritance
358 * class A {...};
359 * class B: public virtual A {...};
360 * class C: public virtual A {...};
361 * class D: public B, public C {...};
362 * D's vtable: {i8 *null, _ZTI1C, ..., inttoptr xxx, _ZTI1C, i8 *null, ...}
363 * there will several "i8 *null" following "inttoptr xxx, _ZTI1C,", and the
364 * number of "i8 *null" is the same as the number of virtual methods in
365 * "class A"
366 */
368{
369 for (Module::const_global_iterator I = M.global_begin(),
370 E = M.global_end(); I != E; ++I)
371 {
372 const GlobalValue *globalvalue = SVFUtil::dyn_cast<const GlobalValue>(&(*I));
373 if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
374 {
376
377 string vtblClassName = getClassNameFromVtblObj(globalvalue->getName().str());
379 assert(node && "node not found?");
380
385 node->setVTable(pValue);
386
387 for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
388 {
389 const ConstantArray *vtbl =
390 SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
391 assert(vtbl && "Element of initializer not an array?");
392
393 /*
394 * items in vtables can be classified into 3 categories:
395 * 1. i8* null
396 * 2. i8* inttoptr xxx
397 * 3. i8* bitcast xxx
398 */
399 bool pure_abstract = true;
400 u32_t i = 0;
402 {
404 bool is_virtual = false; // virtual inheritance
405 int null_ptr_num = 0;
406 for (; i < vtbl->getNumOperands(); ++i)
407 {
408 Constant* operand = vtbl->getOperand(i);
409 if (SVFUtil::isa<ConstantPointerNull>(operand))
410 {
411 if (i > 0 && !SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i-1)))
412 {
413 auto foo = [&is_virtual, &null_ptr_num, &vtbl, &i](const Value* val)
414 {
415 if (val->getName().str().compare(0, ztiLabel.size(), ztiLabel) == 0)
416 {
417 is_virtual = true;
418 null_ptr_num = 1;
420 {
421 if (SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i+null_ptr_num)))
422 null_ptr_num++;
423 else
424 break;
425 }
426 }
427 };
428 if (const ConstantExpr *ce =
429 SVFUtil::dyn_cast<ConstantExpr>(vtbl->getOperand(i-1)))
430 {
431 if(ce->getOpcode() == Instruction::BitCast)
432 foo(ce->getOperand(0));
433 }
434 else
435 {
436 // opaque pointer mode
437 foo(vtbl->getOperand(i - 1));
438 }
439 }
440 continue;
441 }
442
443 auto foo = [this, &virtualFunctions, &pure_abstract, &vtblClassName](const Value* operand)
444 {
445 if (const Function* f = SVFUtil::dyn_cast<Function>(operand))
446 {
448 if (f->getName().str().compare(pureVirtualFunName) == 0)
449 {
450 pure_abstract &= true;
451 }
452 else
453 {
454 pure_abstract &= false;
455 }
456 struct DemangledName dname = demangle(f->getName().str());
457 if (dname.className.size() > 0 &&
458 vtblClassName.compare(dname.className) != 0)
459 {
460 if(!chg->getNode(dname.className)) createNode(dname.className);
462 }
463 }
464 else
465 {
466 if (const GlobalAlias *alias =
467 SVFUtil::dyn_cast<GlobalAlias>(operand))
468 {
469 const Constant *aliasValue = alias->getAliasee();
470 if (const Function* aliasFunc =
471 SVFUtil::dyn_cast<Function>(aliasValue))
472 {
474 }
475 else if (const ConstantExpr *aliasconst =
476 SVFUtil::dyn_cast<ConstantExpr>(aliasValue))
477 {
478 (void)aliasconst; // Suppress warning of unused variable under release build
479 assert(aliasconst->getOpcode() == Instruction::BitCast &&
480 "aliased constantexpr in vtable not a bitcast");
482 SVFUtil::dyn_cast<Function>(aliasconst->getOperand(0));
484 "aliased bitcast in vtable not a function");
486 }
487 else
488 {
489 assert(false && "alias not function or bitcast");
490 }
491
492 pure_abstract &= false;
493 }
494 else if (operand->getName().str().compare(0, ztiLabel.size(),
495 ztiLabel) == 0)
496 {
497 }
498 else
499 {
500 assert("what else can be in bitcast of a vtable?");
501 }
502 }
503 };
504
520 if (const ConstantExpr *ce =
521 SVFUtil::dyn_cast<ConstantExpr>(operand))
522 {
523 u32_t opcode = ce->getOpcode();
524 assert(opcode == Instruction::IntToPtr);
525 assert(ce->getNumOperands() == 1 &&
526 "inttptr operand num not 1");
527 if (opcode == Instruction::IntToPtr)
528 {
529 node->setMultiInheritance();
530 ++i;
531 break;
532 }
533 }
534 else
535 {
536 foo(operand);
537 }
538 }
539 if (is_virtual && virtualFunctions.size() > 0)
540 {
541 for (int i = 0; i < null_ptr_num; ++i)
542 {
543 const SVFFunction* fun = virtualFunctions[i];
544 virtualFunctions.insert(virtualFunctions.begin(), fun);
545 }
546 }
547 if (virtualFunctions.size() > 0)
549 }
550 if (pure_abstract == true)
551 {
552 node->setPureAbstract();
553 }
554 }
555 }
556 }
557}
558
559
561{
562 /*
563 * 1. Divide classes into groups
564 * 2. Get all virtual functions in a group
565 * 3. Assign consecutive IDs to virtual functions that have
566 * the same name (after demangling) in a group
567 */
570 neit = chg->end(); nit != neit; ++nit)
571 {
572 CHNode *node = nit->second;
573 if (visitedNodes.find(node) != visitedNodes.end())
574 continue;
575
576 string className = node->getName();
577
578 /*
579 * get all the classes in a specific group
580 */
582 stack<const CHNode*> nodeStack;
583 nodeStack.push(node);
584 while (!nodeStack.empty())
585 {
586 const CHNode *curnode = nodeStack.top();
587 nodeStack.pop();
588 group.insert(curnode);
589 if (visitedNodes.find(curnode) != visitedNodes.end())
590 continue;
591 for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getOutEdges().begin(),
592 eit = curnode->getOutEdges().end(); it != eit; ++it)
593 {
594 CHNode *tmpnode = (*it)->getDstNode();
595 nodeStack.push(tmpnode);
596 group.insert(tmpnode);
597 }
598 for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getInEdges().begin(),
599 eit = curnode->getInEdges().end(); it != eit; ++it)
600 {
601 CHNode *tmpnode = (*it)->getSrcNode();
602 nodeStack.push(tmpnode);
603 group.insert(tmpnode);
604 }
605 visitedNodes.insert(curnode);
606 }
607
608 /*
609 * get all virtual functions in a specific group
610 */
612 for (CHGraph::CHNodeSetTy::iterator it = group.begin(),
613 eit = group.end(); it != eit; ++it)
614 {
617 veit = vecs.end(); vit != veit; ++vit)
618 {
620 feit = (*vit).end(); fit != feit; ++fit)
621 {
622 virtualFunctions.insert(*fit);
623 }
624 }
625 }
626
627 /*
628 * build a set of pairs of demangled function name and function in a
629 * specific group, items in the set will be sort by the first item of the
630 * pair, so all the virtual functions in a group will be sorted by the
631 * demangled function name
632 * <f, A::f>
633 * <f, B::f>
634 * <g, A::g>
635 * <g, B::g>
636 * <g, C::g>
637 * <~A, A::~A>
638 * <~B, B::~B>
639 * <~C, C::~C>
640 * ...
641 */
643 for (set<const SVFFunction*>::iterator fit = virtualFunctions.begin(),
644 feit = virtualFunctions.end(); fit != feit; ++fit)
645 {
646 const SVFFunction* f = *fit;
647 struct DemangledName dname = demangle(f->getName());
649 }
650 for (set<pair<string, const SVFFunction*>>::iterator it = fNameSet.begin(),
651 eit = fNameSet.end(); it != eit; ++it)
652 {
653 chg->virtualFunctionToIDMap[it->second] = chg->vfID++;
654 }
655 }
656}
657
658
660{
661
663 {
664 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
665 {
666 for (const_inst_iterator II = inst_begin(*F), E = inst_end(*F); II != E; ++II)
667 {
668 if(const CallBase* callInst = SVFUtil::dyn_cast<CallBase>(&*II))
669 {
670 if (cppUtil::isVirtualCallSite(callInst) == false)
671 continue;
672
674 const CHNodeSetTy& chClasses = getCSClasses(callInst);
675 for (CHNodeSetTy::const_iterator it = chClasses.begin(), eit = chClasses.end(); it != eit; ++it)
676 {
677 const CHNode *child = *it;
678 const SVFGlobalValue *vtbl = child->getVTable();
679 if (vtbl != nullptr)
680 {
681 vtbls.insert(vtbl);
682 }
683 }
684 if (vtbls.size() > 0)
685 {
686 ICFGNode* icfgNode =
687 llvmModuleSet()->getICFGNode(callInst);
688 chg->callNodeToCHAVtblsMap[icfgNode] = vtbls;
690 chg->getVFnsFromVtbls(SVFUtil::cast<CallICFGNode>(icfgNode), vtbls, virtualFunctions);
691 if (virtualFunctions.size() > 0)
693 }
694 }
695 }
696 }
697 }
698}
699
700
702{
703 assert(cppUtil::isVirtualCallSite(cs) && "not virtual callsite!");
704
705 ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(cs);
706
707 CHGraph::CallNodeToCHNodesMap::const_iterator it = chg->callNodeToClassesMap.find(icfgNode);
708 if (it != chg->callNodeToClassesMap.end())
709 {
710 return it->second;
711 }
712 else
713 {
715
716 if(thisPtrClassNames.empty())
717 {
718 // if we cannot infer classname, conservatively push all class nodes
719 for (const auto &node: *chg)
720 {
721 chg->callNodeToClassesMap[icfgNode].insert(node.second);
722 }
723 return chg->callNodeToClassesMap[icfgNode];
724 }
725
726 for (const auto &thisPtrClassName: thisPtrClassNames)
727 {
729 {
731 chg->callNodeToClassesMap[icfgNode].insert(thisNode);
732 for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); it2 != eit; ++it2)
733 chg->callNodeToClassesMap[icfgNode].insert(*it2);
734 }
735 }
736 return chg->callNodeToClassesMap[icfgNode];
737 }
738}
739
741{
743 {
744 if (const auto* tf = cppUtil::getThunkTarget(lf))
745 {
748 v.push_back(pFunction);
749 }
750 }
751 else
752 {
755 v.push_back(pFunction);
756 }
757}
const string ztiLabel
const string pureVirtualFunName
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define TIMEINTERVAL
Definition SVFType.h:512
#define DCHA
Definition SVFType.h:506
#define DGENERAL
Definition SVFType.h:490
set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) add_llvm_executable(wpa wpa.cpp) target_link_libraries(wpa PUBLIC $
Definition CMakeLists.txt:1
cJSON * child
Definition cJSON.cpp:2723
@ INHERITANCE
Definition CHG.h:86
@ INSTANTCE
Definition CHG.h:87
void analyzeVTables(const Module &M)
void connectInheritEdgeViaStore(const Function *caller, const StoreInst *store)
LLVMModuleSet * llvmModuleSet()
void readInheritanceMetadataFromModule(const Module &M)
void buildCHGNodes(const GlobalValue *V)
const CHGraph::CHNodeSetTy & getInstancesAndDescendants(const std::string &className)
CHGraph::WorkList WorkList
Definition CHGBuilder.h:46
void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f)
void buildCHGEdges(const Function *F)
void buildVirtualFunctionToIDMap()
CHGraph * chg
Definition CHGBuilder.h:42
void buildCSToCHAVtblsAndVfnsMap()
void buildInternalMaps()
CHGraph::CHNodeSetTy CHNodeSetTy
Definition CHGBuilder.h:45
const CHNodeSetTy & getCSClasses(const CallBase *cs)
CHNode * createNode(const std::string &name)
void connectInheritEdgeViaCall(const Function *caller, const CallBase *cs)
void buildClassNameToAncestorsDescendantsMap()
NameToCHNodesMap classNameToAncestorsMap
Definition CHG.h:326
CallNodeToCHNodesMap callNodeToClassesMap
Definition CHG.h:329
CallNodeToVFunSetMap callNodeToCHAVFnsMap
Definition CHG.h:334
void dump(const std::string &filename)
Definition CHG.cpp:242
const CHNodeSetTy & getInstances(const std::string className)
Definition CHG.h:303
void addEdge(const std::string className, const std::string baseClassName, CHEdge::CHEDGETYPE edgeType)
Definition CHG.cpp:97
void addInstances(const std::string templateName, CHNode *node)
Definition CHG.h:290
Map< const SVFFunction *, u32_t > virtualFunctionToIDMap
Definition CHG.h:331
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
NameToCHNodesMap classNameToInstAndDescsMap
Definition CHG.h:327
u32_t vfID
Definition CHG.h:322
double buildingCHGTime
Definition CHG.h:323
NameToCHNodesMap classNameToDescendantsMap
Definition CHG.h:325
Set< const CHNode * > CHNodeSetTy
Definition CHG.h:240
u32_t classNum
Definition CHG.h:321
Map< std::string, CHNode * > classNameToNodeMap
Definition CHG.h:324
CallNodeToVTableSetMap callNodeToCHAVtblsMap
Definition CHG.h:333
const CHNodeSetTy & getDescendants(const std::string className)
Definition CHG.h:299
void setMultiInheritance()
Definition CHG.h:152
void addVirtualFunctionVector(FuncVector vfuncvec)
Definition CHG.h:174
std::vector< const SVFFunction * > FuncVector
Definition CHG.h:121
const std::vector< FuncVector > & getVirtualFunctionVectors() const
Definition CHG.h:178
void setVTable(const SVFGlobalValue *vtbl)
Definition CHG.h:189
void setPureAbstract()
Attribute.
Definition CHG.h:148
std::string getName() const
Definition CHG.h:130
bool isTemplate() const
Definition CHG.h:168
void addGNode(NodeID id, NodeType *node)
Add a Node.
iterator begin()
Iterators.
IDToNodeMapTy::const_iterator const_iterator
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:122
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
SVFFunction * getSVFFunction(const Function *fun) const
Definition LLVMModule.h:260
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:153
SVFGlobalValue * getSVFGlobalValue(const GlobalValue *g) const
Definition LLVMModule.h:288
static const Option< bool > DumpCHA
Definition Options.h:176
NodeID getId() const
Get ID.
static double getClk(bool mark=false)
Definition SVFStat.cpp:48
void setName(const std::string &n)
Definition SVFValue.h:247
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:45
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:246
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:98
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:100
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
std::string getBeforeBrackets(const std::string &name)
Definition CppUtil.cpp:127
const Value * getVCallThisPtr(const CallBase *cs)
Definition CppUtil.cpp:411
struct DemangledName demangle(const std::string &name)
Definition CppUtil.cpp:195
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition CppUtil.cpp:601
bool isCPPThunkFunction(const Function *F)
Definition CppUtil.cpp:383
bool isVirtualCallSite(const CallBase *cs)
Definition CppUtil.cpp:352
const Function * getThunkTarget(const Function *F)
Definition CppUtil.cpp:389
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
Definition CppUtil.cpp:323
bool isConstructor(const Function *F)
Definition CppUtil.cpp:489
std::string getClassNameFromVtblObj(const std::string &vtblName)
Definition CppUtil.cpp:304
bool isValVtbl(const Value *val)
Definition CppUtil.cpp:336
bool isDestructor(const Function *F)
Definition CppUtil.cpp:509
for isBitcode
Definition BasicTypes.h:68
llvm::const_inst_iterator const_inst_iterator
Definition BasicTypes.h:250
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:128
llvm::CallBase CallBase
Definition BasicTypes.h:146
llvm::MDString MDString
Definition BasicTypes.h:101
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:106
llvm::NamedMDNode NamedMDNode
LLVM metadata and debug information.
Definition BasicTypes.h:111
Set< const SVFGlobalValue * > VTableSet
Definition CHG.h:46
llvm::ConstantArray ConstantArray
Definition BasicTypes.h:123
llvm::Function Function
Definition BasicTypes.h:85
llvm::GlobalValue GlobalValue
Definition BasicTypes.h:88
llvm::Constant Constant
Definition BasicTypes.h:124
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:82
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:120
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
llvm::Module Module
Definition BasicTypes.h:84
llvm::StoreInst StoreInst
Definition BasicTypes.h:148
Set< const SVFFunction * > VFunSet
Definition CHG.h:47
llvm::MDNode MDNode
Definition BasicTypes.h:112
unsigned u32_t
Definition GeneralType.h:46