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