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
61
63{
64
65 double timeStart, timeEnd;
68 {
69 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("construct CHGraph From module "
70 + M.getName().str() + "...\n"));
72 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
73 buildCHGNodes(&(*I));
74 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
75 buildCHGNodes(&(*F));
76 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
77 buildCHGEdges(&(*F));
78
80 }
81
82 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("build Internal Maps ...\n"));
84
87
88 if (Options::DumpCHA())
89 chg->dump("cha");
90}
91
93{
94 if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
95 {
97 string className = getClassNameFromVtblObj(globalvalue->getName().str());
98 if (!chg->getNode(className))
99 createNode(className);
100
101 for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
102 {
103 const ConstantArray *vtbl = SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
104 assert(vtbl && "Element of initializer not an array?");
105 for (u32_t i = 0; i < vtbl->getNumOperands(); ++i)
106 {
107 if(const ConstantExpr *ce = isCastConstantExpr(vtbl->getOperand(i)))
108 {
109 const Value* bitcastValue = ce->getOperand(0);
110 if (const Function* func = SVFUtil::dyn_cast<Function>(bitcastValue))
111 {
112 struct DemangledName dname = demangle(func->getName().str());
113 if (!chg->getNode(dname.className))
114 createNode(dname.className);
115 }
116 }
117 }
118 }
119 }
120}
121
123{
124 if (isConstructor(F) || isDestructor(F))
125 {
126 struct DemangledName dname = demangle(F->getName().str());
127 DBOUT(DCHA, outs() << "\t build CHANode for class " + dname.className + "...\n");
128 if (!chg->getNode(dname.className))
129 createNode(dname.className);
130 }
131}
132
134{
135 if (isConstructor(F) || isDestructor(F))
136 {
137 for (Function::const_iterator B = F->begin(), E = F->end(); B != E; ++B)
138 {
139 for (BasicBlock::const_iterator I = B->begin(), E = B->end(); I != E; ++I)
140 {
141 if (LLVMUtil::isCallSite(&(*I)))
142 {
143 connectInheritEdgeViaCall(F, SVFUtil::cast<CallBase>(&(*I)));
144 }
145 else if (const StoreInst *store = SVFUtil::dyn_cast<StoreInst>(&(*I)))
146 {
148 }
149 }
150 }
151 }
152}
153
154
161
163{
164 if (getCallee(cs) == nullptr)
165 return;
166
167 const Function* callee = getCallee(cs);
168
169 struct DemangledName dname = demangle(caller->getName().str());
171 {
172 if (cs->arg_size() < 1 || (cs->arg_size() < 2 && cs->paramHasAttr(0, llvm::Attribute::StructRet)))
173 return;
174 if(caller->arg_size() == 0)
175 {
176 return;
177 }
181 if (csThisPtr != nullptr && samePtr)
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?");
382 GlobalObjVar* globalObjVar = SVFUtil::cast<GlobalObjVar>(pVar);
383 globalObjVar->setName(vtblClassName);
384 node->setVTable(globalObjVar);
385
386 for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
387 {
388 const ConstantArray *vtbl =
389 SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
390 assert(vtbl && "Element of initializer not an array?");
391
392 /*
393 * items in vtables can be classified into 3 categories:
394 * 1. i8* null
395 * 2. i8* inttoptr xxx
396 * 3. i8* bitcast xxx
397 */
398 bool pure_abstract = true;
399 u32_t i = 0;
401 {
403 bool is_virtual = false; // virtual inheritance
404 int null_ptr_num = 0;
405 for (; i < vtbl->getNumOperands(); ++i)
406 {
407 Constant* operand = vtbl->getOperand(i);
408 if (SVFUtil::isa<ConstantPointerNull>(operand))
409 {
410 if (i > 0 && !SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i-1)))
411 {
412 auto foo = [&is_virtual, &null_ptr_num, &vtbl, &i](const Value* val)
413 {
414 if (getCXXABI(val)->isTypeInfo(val->getName().str()))
415 {
416 is_virtual = true;
417 null_ptr_num = 1;
419 {
420 if (SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i+null_ptr_num)))
421 null_ptr_num++;
422 else
423 break;
424 }
425 }
426 };
427 if (const ConstantExpr *ce =
428 SVFUtil::dyn_cast<ConstantExpr>(vtbl->getOperand(i-1)))
429 {
430 if(ce->getOpcode() == Instruction::BitCast)
431 foo(ce->getOperand(0));
432 }
433 else
434 {
435 // opaque pointer mode
436 foo(vtbl->getOperand(i - 1));
437 }
438 }
439 continue;
440 }
441
442 auto foo = [this, &virtualFunctions, &pure_abstract, &vtblClassName](const Value* operand)
443 {
444 if (const Function* f = SVFUtil::dyn_cast<Function>(operand))
445 {
447 if (f->getName().str().compare(pureVirtualFunName) == 0)
448 {
449 pure_abstract &= true;
450 }
451 else
452 {
453 pure_abstract &= false;
454 }
455 struct DemangledName dname = demangle(f->getName().str());
456 if (dname.className.size() > 0 &&
457 vtblClassName.compare(dname.className) != 0)
458 {
459 if(!chg->getNode(dname.className)) createNode(dname.className);
461 }
462 }
463 else
464 {
465 if (const GlobalAlias *alias =
466 SVFUtil::dyn_cast<GlobalAlias>(operand))
467 {
468 const Constant *aliasValue = alias->getAliasee();
469 while (const GlobalAlias *valAsAlias = SVFUtil::dyn_cast<GlobalAlias>(aliasValue))
470 {
471 aliasValue = valAsAlias->getAliasee();
472 }
473
474 if (const Function* aliasFunc =
475 SVFUtil::dyn_cast<Function>(aliasValue))
476 {
478 }
479 else if (const ConstantExpr *aliasconst =
480 SVFUtil::dyn_cast<ConstantExpr>(aliasValue))
481 {
482 (void)aliasconst; // Suppress warning of unused variable under release build
483 assert(aliasconst->getOpcode() == Instruction::BitCast &&
484 "aliased constantexpr in vtable not a bitcast");
486 SVFUtil::dyn_cast<Function>(aliasconst->getOperand(0));
488 "aliased bitcast in vtable not a function");
490 }
491 else
492 {
493 assert(false && "alias not function or bitcast");
494 }
495
496 pure_abstract &= false;
497 }
498 else if (getCXXABI(operand)->isTypeInfo(operand->getName().str()))
499 {
500 }
501 else
502 {
503 assert("what else can be in bitcast of a vtable?");
504 }
505 }
506 };
507
523 if (const ConstantExpr *ce =
524 SVFUtil::dyn_cast<ConstantExpr>(operand))
525 {
526 u32_t opcode = ce->getOpcode();
527 assert(opcode == Instruction::IntToPtr);
528 assert(ce->getNumOperands() == 1 &&
529 "inttptr operand num not 1");
530 if (opcode == Instruction::IntToPtr)
531 {
532 node->setMultiInheritance();
533 ++i;
534 break;
535 }
536 }
537 else
538 {
539 foo(operand);
540 }
541 }
542 if (is_virtual && virtualFunctions.size() > 0)
543 {
544 for (int i = 0; i < null_ptr_num; ++i)
545 {
546 const FunObjVar* fun = virtualFunctions[i];
547 virtualFunctions.insert(virtualFunctions.begin(), fun);
548 }
549 }
550 if (virtualFunctions.size() > 0)
552 }
553 if (pure_abstract == true)
554 {
555 node->setPureAbstract();
556 }
557 }
558 }
559 }
560}
561
562
564{
565 /*
566 * 1. Divide classes into groups
567 * 2. Get all virtual functions in a group
568 * 3. Assign consecutive IDs to virtual functions that have
569 * the same name (after demangling) in a group
570 */
573 neit = chg->end(); nit != neit; ++nit)
574 {
575 CHNode *node = nit->second;
576 if (visitedNodes.find(node) != visitedNodes.end())
577 continue;
578
579 string className = node->getName();
580
581 /*
582 * get all the classes in a specific group
583 */
585 stack<const CHNode*> nodeStack;
586 nodeStack.push(node);
587 while (!nodeStack.empty())
588 {
589 const CHNode *curnode = nodeStack.top();
590 nodeStack.pop();
591 group.insert(curnode);
592 if (visitedNodes.find(curnode) != visitedNodes.end())
593 continue;
594 for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getOutEdges().begin(),
595 eit = curnode->getOutEdges().end(); it != eit; ++it)
596 {
597 CHNode *tmpnode = (*it)->getDstNode();
598 nodeStack.push(tmpnode);
599 group.insert(tmpnode);
600 }
601 for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getInEdges().begin(),
602 eit = curnode->getInEdges().end(); it != eit; ++it)
603 {
604 CHNode *tmpnode = (*it)->getSrcNode();
605 nodeStack.push(tmpnode);
606 group.insert(tmpnode);
607 }
608 visitedNodes.insert(curnode);
609 }
610
611 /*
612 * get all virtual functions in a specific group
613 */
615 for (CHGraph::CHNodeSetTy::iterator it = group.begin(),
616 eit = group.end(); it != eit; ++it)
617 {
620 veit = vecs.end(); vit != veit; ++vit)
621 {
622 for (vector<const FunObjVar*>::const_iterator fit = (*vit).begin(),
623 feit = (*vit).end(); fit != feit; ++fit)
624 {
625 virtualFunctions.insert(*fit);
626 }
627 }
628 }
629
630 /*
631 * build a set of pairs of demangled function name and function in a
632 * specific group, items in the set will be sort by the first item of the
633 * pair, so all the virtual functions in a group will be sorted by the
634 * demangled function name
635 * <f, A::f>
636 * <f, B::f>
637 * <g, A::g>
638 * <g, B::g>
639 * <g, C::g>
640 * <~A, A::~A>
641 * <~B, B::~B>
642 * <~C, C::~C>
643 * ...
644 */
646 for (set<const FunObjVar*>::iterator fit = virtualFunctions.begin(),
647 feit = virtualFunctions.end(); fit != feit; ++fit)
648 {
649 const FunObjVar* f = *fit;
650 struct DemangledName dname = demangle(f->getName());
652 }
653 for (set<pair<string, const FunObjVar*>>::iterator it = fNameSet.begin(),
654 eit = fNameSet.end(); it != eit; ++it)
655 {
656 chg->virtualFunctionToIDMap[it->second] = chg->vfID++;
657 }
658 }
659}
660
661
663{
664
666 {
667 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
668 {
669 for (const_inst_iterator II = inst_begin(*F), E = inst_end(*F); II != E; ++II)
670 {
671 if(const CallBase* callInst = SVFUtil::dyn_cast<CallBase>(&*II))
672 {
673 if (cppUtil::isVirtualCallSite(callInst) == false)
674 continue;
675
677 const CHNodeSetTy& chClasses = getCSClasses(callInst);
678 for (CHNodeSetTy::const_iterator it = chClasses.begin(), eit = chClasses.end(); it != eit; ++it)
679 {
680 const CHNode *child = *it;
681 const GlobalObjVar *vtbl = child->getVTable();
682 if (vtbl != nullptr)
683 {
684 vtbls.insert(vtbl);
685 }
686 }
687 if (vtbls.size() > 0)
688 {
689 ICFGNode* icfgNode =
690 llvmModuleSet()->getICFGNode(callInst);
691 chg->callNodeToCHAVtblsMap[icfgNode] = vtbls;
693 chg->getVFnsFromVtbls(SVFUtil::cast<CallICFGNode>(icfgNode), vtbls, virtualFunctions);
694 if (virtualFunctions.size() > 0)
696 }
697 }
698 }
699 }
700 }
701}
702
703
705{
706 assert(cppUtil::isVirtualCallSite(cs) && "not virtual callsite!");
707
708 ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(cs);
709
710 CHGraph::CallNodeToCHNodesMap::const_iterator it = chg->callNodeToClassesMap.find(icfgNode);
711 if (it != chg->callNodeToClassesMap.end())
712 {
713 return it->second;
714 }
715 else
716 {
718
719 if(thisPtrClassNames.empty())
720 {
721 // if we cannot infer classname, conservatively push all class nodes
722 for (const auto &node: *chg)
723 {
724 chg->callNodeToClassesMap[icfgNode].insert(node.second);
725 }
726 return chg->callNodeToClassesMap[icfgNode];
727 }
728
729 for (const auto &thisPtrClassName: thisPtrClassNames)
730 {
732 {
734 chg->callNodeToClassesMap[icfgNode].insert(thisNode);
735 for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); it2 != eit; ++it2)
736 chg->callNodeToClassesMap[icfgNode].insert(*it2);
737 }
738 }
739 return chg->callNodeToClassesMap[icfgNode];
740 }
741}
742
744{
746 {
747 const auto* tf = cppUtil::getThunkTarget(lf);
748 const FunObjVar* pFunction =
750 v.push_back(pFunction);
751 }
752 else
753 {
754 const FunObjVar* pFunction =
756 v.push_back(pFunction);
757 }
758}
const string pureVirtualFunName
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define TIMEINTERVAL
Definition SVFType.h:604
#define DCHA
Definition SVFType.h:598
#define DGENERAL
Definition SVFType.h:582
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:243
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:98
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:125
CHNode * getNode(const std::string name) const
Definition CHG.cpp:113
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:270
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:133
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:160
static const Option< bool > DumpCHA
Definition Options.h:169
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:120
static double getClk(bool mark=false)
Definition SVFStat.cpp:52
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual bool isTypeInfo(const std::string &name)=0
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:47
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:251
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:100
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:121
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:58
std::string getBeforeBrackets(const std::string &name)
Definition CppUtil.cpp:127
const Argument * getConstructorThisPtr(const Function *fun)
Definition CppUtil.cpp:465
bool isSameThisPtrInConstructor(const Argument *thisPtr1, const Value *thisPtr2)
Definition CppUtil.cpp:421
const Value * getVCallThisPtr(const CallBase *cs)
Definition CppUtil.cpp:348
struct DemangledName demangle(const std::string &name)
Definition CppUtil.cpp:195
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition CppUtil.cpp:613
bool isCPPThunkFunction(const Function *F)
Definition CppUtil.cpp:320
CXXABI * getCXXABI()
Definition CppUtil.cpp:994
bool isVirtualCallSite(const CallBase *cs)
Definition CppUtil.cpp:289
const Function * getThunkTarget(const Function *F)
Definition CppUtil.cpp:326
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
Definition CppUtil.cpp:261
bool isConstructor(const Function *F)
Definition CppUtil.cpp:501
std::string getClassNameFromVtblObj(const std::string &vtblName)
Definition CppUtil.cpp:256
bool isValVtbl(const Value *val)
Definition CppUtil.cpp:274
bool isDestructor(const Function *F)
Definition CppUtil.cpp:521
for isBitcode
Definition BasicTypes.h:70
llvm::const_inst_iterator const_inst_iterator
Definition BasicTypes.h:261
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:135
llvm::CallBase CallBase
Definition BasicTypes.h:153
llvm::MDString MDString
Definition BasicTypes.h:105
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:110
llvm::NamedMDNode NamedMDNode
LLVM metadata and debug information.
Definition BasicTypes.h:115
u32_t NodeID
Definition GeneralType.h:76
Set< const GlobalObjVar * > VTableSet
Definition CHG.h:46
llvm::Argument Argument
Definition BasicTypes.h:152
llvm::ConstantArray ConstantArray
Definition BasicTypes.h:127
llvm::Function Function
Definition BasicTypes.h:89
llvm::GlobalValue GlobalValue
Definition BasicTypes.h:92
llvm::Constant Constant
Definition BasicTypes.h:128
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:86
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:124
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
llvm::Module Module
Definition BasicTypes.h:88
llvm::StoreInst StoreInst
Definition BasicTypes.h:155
llvm::MDNode MDNode
Definition BasicTypes.h:116
unsigned u32_t
Definition GeneralType.h:67
Set< const FunObjVar * > VFunSet
Definition CHG.h:47