Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVF::CHGBuilder Class Reference

#include <CHGBuilder.h>

Public Types

typedef CHGraph::CHNodeSetTy CHNodeSetTy
typedef CHGraph::WorkList WorkList

Public Member Functions

 CHGBuilder (CHGraph *c)
void buildCHG ()
void buildCHGNodes (const GlobalValue *V)
void buildCHGNodes (const Function *F)
void buildCHGEdges (const Function *F)
void buildInternalMaps ()
void readInheritanceMetadataFromModule (const Module &M)
CHNode * createNode (const std::string &name)
void connectInheritEdgeViaCall (const Function *caller, const CallBase *cs)
void connectInheritEdgeViaStore (const Function *caller, const StoreInst *store)
void buildClassNameToAncestorsDescendantsMap ()
const CHGraph::CHNodeSetTy & getInstancesAndDescendants (const std::string &className)
void analyzeVTables (const Module &M)
void buildVirtualFunctionToIDMap ()
void buildCSToCHAVtblsAndVfnsMap ()
const CHNodeSetTy & getCSClasses (const CallBase *cs)
void addFuncToFuncVector (CHNode::FuncVector &v, const Function *f)

Private Member Functions

LLVMModuleSet * llvmModuleSet ()

Private Attributes

CHGraph * chg

Detailed Description

Definition at line 38 of file CHGBuilder.h.

Member Typedef Documentation

◆ CHNodeSetTy

◆ WorkList

Definition at line 46 of file CHGBuilder.h.

Constructor & Destructor Documentation

◆ CHGBuilder()

SVF::CHGBuilder::CHGBuilder ( CHGraph * c)
inline

Definition at line 48 of file CHGBuilder.h.

48 : chg(c)
49 {
50
51 }
CHGraph * chg
Definition CHGBuilder.h:42

Member Function Documentation

◆ addFuncToFuncVector()

void CHGBuilder::addFuncToFuncVector ( CHNode::FuncVector & v,
const Function * f )

Definition at line 751 of file CHGBuilder.cpp.

752{
754 {
755 const auto* tf = cppUtil::getThunkTarget(lf);
756 const FunObjVar* pFunction =
757 llvmModuleSet()->getFunObjVar(tf ? tf : lf);
758 v.push_back(pFunction);
759 }
760 else
761 {
762 const FunObjVar* pFunction =
764 v.push_back(pFunction);
765 }
766}
LLVMModuleSet * llvmModuleSet()
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:274
bool isCPPThunkFunction(const Function *F)
Definition CppUtil.cpp:341
const Function * getThunkTarget(const Function *F)
Definition CppUtil.cpp:347

◆ analyzeVTables()

void CHGBuilder::analyzeVTables ( const Module & M)

vtable in llvm 16 does not have bitcast: e.g., @_ZTV1B = linkonce_odr dso_local unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI1B, ptr @_ZN1B1fEPi, ptr @_ZN1B1gEPi] }, comdat, align 8 compared to its llvm 13 version: @_ZTV1B = linkonce_odr dso_local unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i8* bitcast (void (class.B*, i32*)* @_ZN1B1fEPi to i8*), i8* bitcast (void (class.B*, i32*)* @_ZN1B1gEPi to i8*)] }, comdat, align 8

For llvm 13, we need to cast the operand into a constant expr and then process the first operand of that constant expr For llvm 16, things get simpler. We can directly process each operand

for inttoptr in llvm 16, the handling method is the same as before

Definition at line 373 of file CHGBuilder.cpp.

374{
375 for (Module::const_global_iterator I = M.global_begin(),
376 E = M.global_end(); I != E; ++I)
377 {
378 const GlobalValue *globalvalue = SVFUtil::dyn_cast<const GlobalValue>(&(*I));
379 if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
380 {
381 const ConstantStruct *vtblStruct = cppUtil::getVtblStruct(globalvalue);
382 if (!vtblStruct)
383 continue;
384
385 string vtblClassName = getClassNameFromVtblObj(globalvalue->getName().str());
386 CHNode *node = chg->getNode(vtblClassName);
387 assert(node && "node not found?");
388 NodeID i = llvmModuleSet()->getObjectNode(globalvalue);
389 SVFVar* pVar = PAG::getPAG()->getGNode(i);
390 GlobalObjVar* globalObjVar = SVFUtil::cast<GlobalObjVar>(pVar);
391 globalObjVar->setName(vtblClassName);
392 node->setVTable(globalObjVar);
393
394 for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
395 {
396 const ConstantArray *vtbl =
397 SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
398 assert(vtbl && "Element of initializer not an array?");
399
400 /*
401 * items in vtables can be classified into 3 categories:
402 * 1. i8* null
403 * 2. i8* inttoptr xxx
404 * 3. i8* bitcast xxx
405 */
406 bool pure_abstract = true;
407 u32_t i = 0;
408 while (i < vtbl->getNumOperands())
409 {
410 CHNode::FuncVector virtualFunctions;
411 bool is_virtual = false; // virtual inheritance
412 int null_ptr_num = 0;
413 for (; i < vtbl->getNumOperands(); ++i)
414 {
415 Constant* operand = vtbl->getOperand(i);
417 {
418 if (i > 0 && !SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i-1)))
419 {
420 auto foo = [&is_virtual, &null_ptr_num, &vtbl, &i](const Value* val)
421 {
422 if (getCXXABI(val)->isTypeInfo(val->getName().str()))
423 {
424 is_virtual = true;
425 null_ptr_num = 1;
426 while (i+null_ptr_num < vtbl->getNumOperands())
427 {
428 if (SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i+null_ptr_num)))
429 null_ptr_num++;
430 else
431 break;
432 }
433 }
434 };
435 if (const ConstantExpr *ce =
436 SVFUtil::dyn_cast<ConstantExpr>(vtbl->getOperand(i-1)))
437 {
438 if(ce->getOpcode() == Instruction::BitCast)
439 foo(ce->getOperand(0));
440 }
441 else
442 {
443 // opaque pointer mode
444 foo(vtbl->getOperand(i - 1));
445 }
446 }
447 continue;
448 }
449
450 auto foo = [this, &virtualFunctions, &pure_abstract, &vtblClassName](const Value* operand)
451 {
452 if (const Function* f = SVFUtil::dyn_cast<Function>(operand))
453 {
454 addFuncToFuncVector(virtualFunctions, f);
455 if (f->getName().str().compare(pureVirtualFunName) == 0)
456 {
457 pure_abstract &= true;
458 }
459 else
460 {
461 pure_abstract &= false;
462 }
463 struct DemangledName dname = demangle(f->getName().str());
464 if (dname.className.size() > 0 &&
465 vtblClassName.compare(dname.className) != 0)
466 {
467 if(!chg->getNode(dname.className)) createNode(dname.className);
468 chg->addEdge(vtblClassName, dname.className, CHEdge::INHERITANCE);
469 }
470 }
471 else
472 {
473 if (const GlobalAlias *alias =
475 {
476 const Constant *aliasValue = alias->getAliasee();
477 while (const GlobalAlias *valAsAlias = SVFUtil::dyn_cast<GlobalAlias>(aliasValue))
478 {
479 aliasValue = valAsAlias->getAliasee();
480 }
481
482 if (const Function* aliasFunc =
483 SVFUtil::dyn_cast<Function>(aliasValue))
484 {
485 addFuncToFuncVector(virtualFunctions, aliasFunc);
486 }
487 else if (const ConstantExpr *aliasconst =
489 {
490 (void)aliasconst; // Suppress warning of unused variable under release build
491 assert(aliasconst->getOpcode() == Instruction::BitCast &&
492 "aliased constantexpr in vtable not a bitcast");
493 const Function* aliasbitcastfunc =
494 SVFUtil::dyn_cast<Function>(aliasconst->getOperand(0));
495 assert(aliasbitcastfunc &&
496 "aliased bitcast in vtable not a function");
497 addFuncToFuncVector(virtualFunctions, aliasbitcastfunc);
498 }
499 else
500 {
501 assert(false && "alias not function or bitcast");
502 }
503
504 pure_abstract &= false;
505 }
506 else if (getCXXABI(operand)->isTypeInfo(operand->getName().str()))
507 {
508 }
509 else
510 {
511 assert("what else can be in bitcast of a vtable?");
512 }
513 }
514 };
515
531 if (const ConstantExpr *ce =
533 {
534 u32_t opcode = ce->getOpcode();
535 assert(opcode == Instruction::IntToPtr);
536 assert(ce->getNumOperands() == 1 &&
537 "inttptr operand num not 1");
538 if (opcode == Instruction::IntToPtr)
539 {
540 node->setMultiInheritance();
541 ++i;
542 break;
543 }
544 }
545 else
546 {
547 foo(operand);
548 }
549 }
550 if (is_virtual && virtualFunctions.size() > 0)
551 {
552 for (int i = 0; i < null_ptr_num; ++i)
553 {
554 const FunObjVar* fun = virtualFunctions[i];
555 virtualFunctions.insert(virtualFunctions.begin(), fun);
556 }
557 }
558 if (virtualFunctions.size() > 0)
559 node->addVirtualFunctionVector(virtualFunctions);
560 }
561 if (pure_abstract == true)
562 {
563 node->setPureAbstract();
564 }
565 }
566 }
567 }
568}
const string pureVirtualFunName
@ INHERITANCE
Definition CHG.h:84
void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f)
CHNode * createNode(const std::string &name)
void setVTable(const GlobalObjVar *vtbl)
Definition CHG.h:186
void setMultiInheritance()
Definition CHG.h:149
void addVirtualFunctionVector(FuncVector vfuncvec)
Definition CHG.h:171
void setPureAbstract()
Attribute.
Definition CHG.h:145
std::vector< const FunObjVar * > FuncVector
Definition CHG.h:118
NodeType * getGNode(NodeID id) const
Get a node.
NodeID getObjectNode(const Value *V)
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:121
virtual void setName(const std::string &nameInfo)
Definition SVFValue.h:174
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
Definition Casting.h:360
LLVM_NODISCARD bool isa(const Y &Val)
Definition Casting.h:241
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition Casting.h:405
struct DemangledName demangle(const std::string &name)
Definition CppUtil.cpp:195
CXXABI * getCXXABI()
Definition CppUtil.cpp:1015
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
Definition CppUtil.cpp:261
std::string getClassNameFromVtblObj(const std::string &vtblName)
Definition CppUtil.cpp:256
bool isValVtbl(const Value *val)
A carefully crafted input such as FakeVTable _ZTV1A = {{nullptr, nullptr}}; can forge a vtable; detec...
Definition CppUtil.cpp:295
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:129
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:104
u32_t NodeID
Definition GeneralType.h:76
llvm::ConstantArray ConstantArray
Definition BasicTypes.h:121
llvm::Function Function
Definition BasicTypes.h:83
llvm::GlobalValue GlobalValue
Definition BasicTypes.h:86
llvm::Constant Constant
Definition BasicTypes.h:122
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:80
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:118
unsigned u32_t
Definition GeneralType.h:67

◆ buildCHG()

void CHGBuilder::buildCHG ( )

Definition at line 62 of file CHGBuilder.cpp.

63{
64
65 double timeStart, timeEnd;
66 timeStart = PTAStat::getClk(true);
67 for (Module &M : llvmModuleSet()->getLLVMModules())
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
85 timeEnd = PTAStat::getClk(true);
86 chg->buildingCHGTime = (timeEnd - timeStart) / TIMEINTERVAL;
87
88 if (Options::DumpCHA())
89 chg->dump("cha");
90}
#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 DGENERAL
Definition SVFType.h:582
void analyzeVTables(const Module &M)
void readInheritanceMetadataFromModule(const Module &M)
void buildCHGNodes(const GlobalValue *V)
void buildCHGEdges(const Function *F)
void buildInternalMaps()
static const Option< bool > DumpCHA
Definition Options.h:171
static double getClk(bool mark=false)
Definition SVFStat.cpp:52
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
llvm::Module Module
Definition BasicTypes.h:82

◆ buildCHGEdges()

void CHGBuilder::buildCHGEdges ( const Function * F)

Definition at line 139 of file CHGBuilder.cpp.

140{
141 if (isConstructor(F) || isDestructor(F))
142 {
143 for (Function::const_iterator B = F->begin(), E = F->end(); B != E; ++B)
144 {
145 for (BasicBlock::const_iterator I = B->begin(), E = B->end(); I != E; ++I)
146 {
147 if (LLVMUtil::isCallSite(&(*I)))
148 {
150 }
151 else if (const StoreInst *store = SVFUtil::dyn_cast<StoreInst>(&(*I)))
152 {
154 }
155 }
156 }
157 }
158}
void connectInheritEdgeViaStore(const Function *caller, const StoreInst *store)
void connectInheritEdgeViaCall(const Function *caller, const CallBase *cs)
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:57
bool isConstructor(const Function *F)
Definition CppUtil.cpp:522
bool isDestructor(const Function *F)
Definition CppUtil.cpp:542
llvm::StoreInst StoreInst
Definition BasicTypes.h:149

◆ buildCHGNodes() [1/2]

void CHGBuilder::buildCHGNodes ( const Function * F)

Definition at line 128 of file CHGBuilder.cpp.

129{
130 if (isConstructor(F) || isDestructor(F))
131 {
132 struct DemangledName dname = demangle(F->getName().str());
133 DBOUT(DCHA, outs() << "\t build CHANode for class " + dname.className + "...\n");
134 if (!chg->getNode(dname.className))
135 createNode(dname.className);
136 }
137}
#define DCHA
Definition SVFType.h:598

◆ buildCHGNodes() [2/2]

void CHGBuilder::buildCHGNodes ( const GlobalValue * V)

Definition at line 92 of file CHGBuilder.cpp.

93{
94 if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
95 {
96 const ConstantStruct *vtblStruct = cppUtil::getVtblStruct(globalvalue);
97 if (!vtblStruct)
98 {
99 SVFUtil::errs() << "Warning: skipping unsupported vtable initializer for "
100 << globalvalue->getName().str() << "; class hierarchy analysis may be incomplete\n";
101 return;
102 }
103 string className = getClassNameFromVtblObj(globalvalue->getName().str());
104 if (!chg->getNode(className))
105 createNode(className);
106
107 for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
108 {
109 const ConstantArray *vtbl = SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
110 assert(vtbl && "Element of initializer not an array?");
111 for (u32_t i = 0; i < vtbl->getNumOperands(); ++i)
112 {
113 if(const ConstantExpr *ce = isCastConstantExpr(vtbl->getOperand(i)))
114 {
115 const Value* bitcastValue = ce->getOperand(0);
116 if (const Function* func = SVFUtil::dyn_cast<Function>(bitcastValue))
117 {
118 struct DemangledName dname = demangle(func->getName().str());
119 if (!chg->getNode(dname.className))
120 createNode(dname.className);
121 }
122 }
123 }
124 }
125 }
126}
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:247
std::ostream & errs()
Overwrite llvm::errs().
Definition SVFUtil.h:64

◆ buildClassNameToAncestorsDescendantsMap()

void CHGBuilder::buildClassNameToAncestorsDescendantsMap ( )

Definition at line 274 of file CHGBuilder.cpp.

275{
276
277 for (CHGraph::const_iterator it = chg->begin(), eit = chg->end();
278 it != eit; ++it)
279 {
280 const CHNode *node = it->second;
281 WorkList worklist;
282 CHNodeSetTy visitedNodes;
283 worklist.push(node);
284 while (!worklist.empty())
285 {
286 const CHNode *curnode = worklist.pop();
287 if (visitedNodes.find(curnode) == visitedNodes.end())
288 {
289 for (CHEdge::CHEdgeSetTy::const_iterator it =
290 curnode->getOutEdges().begin(), eit =
291 curnode->getOutEdges().end(); it != eit; ++it)
292 {
293 if ((*it)->getEdgeType() == CHEdge::INHERITANCE)
294 {
295 CHNode *succnode = (*it)->getDstNode();
296 chg->classNameToAncestorsMap[node->getName()].insert(succnode);
297 chg->classNameToDescendantsMap[succnode->getName()].insert(node);
298 worklist.push(succnode);
299 }
300 }
301 visitedNodes.insert(curnode);
302 }
303 }
304 }
305}
CHGraph::WorkList WorkList
Definition CHGBuilder.h:46
CHGraph::CHNodeSetTy CHNodeSetTy
Definition CHGBuilder.h:45
virtual const std::string & getName() const
Definition CHG.h:127
IDToNodeMapTy::const_iterator const_iterator
const GEdgeSetTy & getOutEdges() const

◆ buildCSToCHAVtblsAndVfnsMap()

void CHGBuilder::buildCSToCHAVtblsAndVfnsMap ( )

Definition at line 670 of file CHGBuilder.cpp.

671{
672
673 for (Module &M : llvmModuleSet()->getLLVMModules())
674 {
675 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
676 {
677 for (const_inst_iterator II = inst_begin(*F), E = inst_end(*F); II != E; ++II)
678 {
679 if(const CallBase* callInst = SVFUtil::dyn_cast<CallBase>(&*II))
680 {
681 if (cppUtil::isVirtualCallSite(callInst) == false)
682 continue;
683
684 VTableSet vtbls;
685 const CHNodeSetTy& chClasses = getCSClasses(callInst);
686 for (CHNodeSetTy::const_iterator it = chClasses.begin(), eit = chClasses.end(); it != eit; ++it)
687 {
688 const CHNode *child = *it;
689 const GlobalObjVar *vtbl = child->getVTable();
690 if (vtbl != nullptr)
691 {
692 vtbls.insert(vtbl);
693 }
694 }
695 if (vtbls.size() > 0)
696 {
697 ICFGNode* icfgNode =
698 llvmModuleSet()->getICFGNode(callInst);
699 chg->callNodeToCHAVtblsMap[icfgNode] = vtbls;
700 VFunSet virtualFunctions;
701 chg->getVFnsFromVtbls(SVFUtil::cast<CallICFGNode>(icfgNode), vtbls, virtualFunctions);
702 if (virtualFunctions.size() > 0)
703 chg->callNodeToCHAVFnsMap[icfgNode] = virtualFunctions;
704 }
705 }
706 }
707 }
708 }
709}
cJSON * child
Definition cJSON.cpp:2723
const CHNodeSetTy & getCSClasses(const CallBase *cs)
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
bool isVirtualCallSite(const CallBase *cs)
Definition CppUtil.cpp:310
llvm::const_inst_iterator const_inst_iterator
Definition BasicTypes.h:253
llvm::CallBase CallBase
Definition BasicTypes.h:147
Set< const GlobalObjVar * > VTableSet
Definition CHG.h:46
Set< const FunObjVar * > VFunSet
Definition CHG.h:47

◆ buildInternalMaps()

void CHGBuilder::buildInternalMaps ( )

Definition at line 161 of file CHGBuilder.cpp.

◆ buildVirtualFunctionToIDMap()

void CHGBuilder::buildVirtualFunctionToIDMap ( )

Definition at line 571 of file CHGBuilder.cpp.

572{
573 /*
574 * 1. Divide classes into groups
575 * 2. Get all virtual functions in a group
576 * 3. Assign consecutive IDs to virtual functions that have
577 * the same name (after demangling) in a group
578 */
579 CHGraph::CHNodeSetTy visitedNodes;
580 for (CHGraph::const_iterator nit = chg->begin(),
581 neit = chg->end(); nit != neit; ++nit)
582 {
583 CHNode *node = nit->second;
584 if (visitedNodes.find(node) != visitedNodes.end())
585 continue;
586
587 string className = node->getName();
588
589 /*
590 * get all the classes in a specific group
591 */
593 stack<const CHNode*> nodeStack;
594 nodeStack.push(node);
595 while (!nodeStack.empty())
596 {
597 const CHNode *curnode = nodeStack.top();
598 nodeStack.pop();
599 group.insert(curnode);
600 if (visitedNodes.find(curnode) != visitedNodes.end())
601 continue;
602 for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getOutEdges().begin(),
603 eit = curnode->getOutEdges().end(); it != eit; ++it)
604 {
605 CHNode *tmpnode = (*it)->getDstNode();
606 nodeStack.push(tmpnode);
607 group.insert(tmpnode);
608 }
609 for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getInEdges().begin(),
610 eit = curnode->getInEdges().end(); it != eit; ++it)
611 {
612 CHNode *tmpnode = (*it)->getSrcNode();
613 nodeStack.push(tmpnode);
614 group.insert(tmpnode);
615 }
616 visitedNodes.insert(curnode);
617 }
618
619 /*
620 * get all virtual functions in a specific group
621 */
622 set<const FunObjVar*> virtualFunctions;
623 for (CHGraph::CHNodeSetTy::iterator it = group.begin(),
624 eit = group.end(); it != eit; ++it)
625 {
626 const vector<CHNode::FuncVector> &vecs = (*it)->getVirtualFunctionVectors();
627 for (vector<CHNode::FuncVector>::const_iterator vit = vecs.begin(),
628 veit = vecs.end(); vit != veit; ++vit)
629 {
630 for (vector<const FunObjVar*>::const_iterator fit = (*vit).begin(),
631 feit = (*vit).end(); fit != feit; ++fit)
632 {
633 virtualFunctions.insert(*fit);
634 }
635 }
636 }
637
638 /*
639 * build a set of pairs of demangled function name and function in a
640 * specific group, items in the set will be sort by the first item of the
641 * pair, so all the virtual functions in a group will be sorted by the
642 * demangled function name
643 * <f, A::f>
644 * <f, B::f>
645 * <g, A::g>
646 * <g, B::g>
647 * <g, C::g>
648 * <~A, A::~A>
649 * <~B, B::~B>
650 * <~C, C::~C>
651 * ...
652 */
653 set<pair<string, const FunObjVar*> > fNameSet;
654 for (set<const FunObjVar*>::iterator fit = virtualFunctions.begin(),
655 feit = virtualFunctions.end(); fit != feit; ++fit)
656 {
657 const FunObjVar* f = *fit;
658 struct DemangledName dname = demangle(f->getName());
659 fNameSet.insert(pair<string, const FunObjVar*>(dname.funcName, f));
660 }
661 for (set<pair<string, const FunObjVar*>>::iterator it = fNameSet.begin(),
662 eit = fNameSet.end(); it != eit; ++it)
663 {
664 chg->virtualFunctionToIDMap[it->second] = chg->vfID++;
665 }
666 }
667}
PRIVATE Xlinker stack
Set< const CHNode * > CHNodeSetTy
Definition CHG.h:246
const GEdgeSetTy & getInEdges() const
virtual const std::string & getName() const
Definition SVFValue.h:184

◆ connectInheritEdgeViaCall()

void CHGBuilder::connectInheritEdgeViaCall ( const Function * caller,
const CallBase * cs )

Definition at line 168 of file CHGBuilder.cpp.

169{
170 if (getCallee(cs) == nullptr)
171 return;
172
173 const Function* callee = getCallee(cs);
174
175 struct DemangledName dname = demangle(caller->getName().str());
176 if ((isConstructor(caller) && isConstructor(callee)) || (isDestructor(caller) && isDestructor(callee)))
177 {
178 if (cs->arg_size() < 1 || (cs->arg_size() < 2 && cs->paramHasAttr(0, llvm::Attribute::StructRet)))
179 return;
180 if(caller->arg_size() == 0)
181 {
182 return;
183 }
184 const Value* csThisPtr = cppUtil::getVCallThisPtr(cs);
185 const Argument* consThisPtr = getConstructorThisPtr(caller);
186 bool samePtr = isSameThisPtrInConstructor(consThisPtr, csThisPtr);
187 if (csThisPtr != nullptr && samePtr)
188 {
189 struct DemangledName basename = demangle(callee->getName().str());
190 if (!LLVMUtil::isCallSite(csThisPtr) &&
191 basename.className.size() > 0)
192 {
193 chg->addEdge(dname.className, basename.className, CHEdge::INHERITANCE);
194 }
195 }
196 }
197}
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:110
const Argument * getConstructorThisPtr(const Function *fun)
Definition CppUtil.cpp:486
bool isSameThisPtrInConstructor(const Argument *thisPtr1, const Value *thisPtr2)
Definition CppUtil.cpp:442
const Value * getVCallThisPtr(const CallBase *cs)
Definition CppUtil.cpp:369
llvm::Argument Argument
Definition BasicTypes.h:146

◆ connectInheritEdgeViaStore()

void CHGBuilder::connectInheritEdgeViaStore ( const Function * caller,
const StoreInst * store )

Definition at line 199 of file CHGBuilder.cpp.

200{
201 struct DemangledName dname = demangle(caller->getName().str());
202 if (const ConstantExpr *ce = SVFUtil::dyn_cast<ConstantExpr>(storeInst->getValueOperand()))
203 {
204 if (ce->getOpcode() == Instruction::BitCast)
205 {
206 const Value* bitcastval = ce->getOperand(0);
207 if (const ConstantExpr *bcce = SVFUtil::dyn_cast<ConstantExpr>(bitcastval))
208 {
209 if (bcce->getOpcode() == Instruction::GetElementPtr)
210 {
211 const Value* gepval = bcce->getOperand(0);
212 if (cppUtil::isValVtbl(gepval))
213 {
214 string vtblClassName = getClassNameFromVtblObj(gepval->getName().str());
215 if (vtblClassName.size() > 0 && dname.className.compare(vtblClassName) != 0)
216 {
217 chg->addEdge(dname.className, vtblClassName, CHEdge::INHERITANCE);
218 }
219 }
220 }
221 }
222 }
223 }
224}

◆ createNode()

CHNode * CHGBuilder::createNode ( const std::string & name)

Definition at line 247 of file CHGBuilder.cpp.

248{
249 assert(!chg->getNode(className) && "this node should never be created before!");
250 CHNode * node = new CHNode(className, chg->classNum++);
251 chg->classNameToNodeMap[className] = node;
252 chg->addGNode(node->getId(), node);
253 if (className.size() > 0 && className[className.size() - 1] == '>')
254 {
255 string templateName = getBeforeBrackets(className);
256 CHNode* templateNode = chg->getNode(templateName);
257 if (!templateNode)
258 {
259 DBOUT(DCHA, outs() << "\t Create Template CHANode " + templateName + " for class " + className + "...\n");
260 templateNode = createNode(templateName);
261 templateNode->setTemplate();
262 }
263 chg->addEdge(className, templateName, CHEdge::INSTANTCE);
264 chg->addInstances(templateName,node);
265 }
266 return node;
267}
@ INSTANTCE
Definition CHG.h:85
void setTemplate()
Definition CHG.h:153
NodeID getId() const
Get ID.
Definition SVFValue.h:158
std::string getBeforeBrackets(const std::string &name)
Definition CppUtil.cpp:127

◆ getCSClasses()

const CHGraph::CHNodeSetTy & CHGBuilder::getCSClasses ( const CallBase * cs)

Definition at line 712 of file CHGBuilder.cpp.

713{
714 assert(cppUtil::isVirtualCallSite(cs) && "not virtual callsite!");
715
716 ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(cs);
717
718 CHGraph::CallNodeToCHNodesMap::const_iterator it = chg->callNodeToClassesMap.find(icfgNode);
719 if (it != chg->callNodeToClassesMap.end())
720 {
721 return it->second;
722 }
723 else
724 {
725 Set<string> thisPtrClassNames = getClassNameOfThisPtr(cs);
726
727 if(thisPtrClassNames.empty())
728 {
729 // if we cannot infer classname, conservatively push all class nodes
730 for (const auto &node: *chg)
731 {
732 chg->callNodeToClassesMap[icfgNode].insert(node.second);
733 }
734 return chg->callNodeToClassesMap[icfgNode];
735 }
736
737 for (const auto &thisPtrClassName: thisPtrClassNames)
738 {
739 if (const CHNode* thisNode = chg->getNode(thisPtrClassName))
740 {
741 const CHGraph::CHNodeSetTy& instAndDesces = getInstancesAndDescendants(thisPtrClassName);
742 chg->callNodeToClassesMap[icfgNode].insert(thisNode);
743 for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); it2 != eit; ++it2)
744 chg->callNodeToClassesMap[icfgNode].insert(*it2);
745 }
746 }
747 return chg->callNodeToClassesMap[icfgNode];
748 }
749}
const CHGraph::CHNodeSetTy & getInstancesAndDescendants(const std::string &className)
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition CppUtil.cpp:634
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition GeneralType.h:51

◆ getInstancesAndDescendants()

const CHGraph::CHNodeSetTy & CHGBuilder::getInstancesAndDescendants ( const std::string & className)

Definition at line 307 of file CHGBuilder.cpp.

309{
310
311 CHGraph::NameToCHNodesMap::const_iterator it = chg->classNameToInstAndDescsMap.find(className);
312 if (it != chg->classNameToInstAndDescsMap.end())
313 {
314 return it->second;
315 }
316 else
317 {
318 chg->classNameToInstAndDescsMap[className] = chg->getDescendants(className);
319 if (chg->getNode(className)->isTemplate())
320 {
321 const CHNodeSetTy& instances = chg->getInstances(className);
322 for (CHNodeSetTy::const_iterator it = instances.begin(), eit = instances.end(); it != eit; ++it)
323 {
324 const CHNode *node = *it;
325 chg->classNameToInstAndDescsMap[className].insert(node);
326 const CHNodeSetTy& instance_descendants = chg->getDescendants(node->getName());
327 for (CHNodeSetTy::const_iterator dit =
328 instance_descendants.begin(), deit =
329 instance_descendants.end(); dit != deit; ++dit)
330 {
331 chg->classNameToInstAndDescsMap[className].insert(*dit);
332 }
333 }
334 }
335 return chg->classNameToInstAndDescsMap[className];
336 }
337}

◆ llvmModuleSet()

LLVMModuleSet * CHGBuilder::llvmModuleSet ( )
private

Definition at line 57 of file CHGBuilder.cpp.

58{
60}
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:137

◆ readInheritanceMetadataFromModule()

void CHGBuilder::readInheritanceMetadataFromModule ( const Module & M)

Definition at line 226 of file CHGBuilder.cpp.

227{
228 for (Module::const_named_metadata_iterator mdit = M.named_metadata_begin(),
229 mdeit = M.named_metadata_end(); mdit != mdeit; ++mdit)
230 {
231 const NamedMDNode *md = &*mdit;
232 string mdname = md->getName().str();
233 if (mdname.compare(0, 15, "__cxx_bases_of_") != 0)
234 continue;
235 string className = mdname.substr(15);
236 for (NamedMDNode::const_op_iterator opit = md->op_begin(),
237 opeit = md->op_end(); opit != opeit; ++opit)
238 {
239 const MDNode *N = *opit;
240 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
241 string baseName = mdstr->getString().str();
242 chg->addEdge(className, baseName, CHEdge::INHERITANCE);
243 }
244 }
245}
llvm::MDString MDString
Definition BasicTypes.h:99
llvm::NamedMDNode NamedMDNode
LLVM metadata and debug information.
Definition BasicTypes.h:109
llvm::MDNode MDNode
Definition BasicTypes.h:110

Member Data Documentation

◆ chg

CHGraph* SVF::CHGBuilder::chg
private

Definition at line 42 of file CHGBuilder.h.


The documentation for this class was generated from the following files: