Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
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

Definition at line 45 of file CHGBuilder.h.

◆ 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
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

Member Function Documentation

◆ addFuncToFuncVector()

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

Definition at line 743 of file CHGBuilder.cpp.

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}
LLVMModuleSet * llvmModuleSet()
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:270
bool isCPPThunkFunction(const Function *F)
Definition CppUtil.cpp:320
const Function * getThunkTarget(const Function *F)
Definition CppUtil.cpp:326

◆ 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 367 of file CHGBuilder.cpp.

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}
const string pureVirtualFunName
unsigned u32_t
Definition CommandLine.h:18
@ INHERITANCE
Definition CHG.h:84
void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f)
CHNode * createNode(const std::string &name)
void addEdge(const std::string className, const std::string baseClassName, CHEdge::CHEDGETYPE edgeType)
Definition CHG.cpp:98
CHNode * getNode(const std::string name) const
Definition CHG.cpp:113
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:120
virtual bool isTypeInfo(const std::string &name)=0
struct DemangledName demangle(const std::string &name)
Definition CppUtil.cpp:195
CXXABI * getCXXABI()
Definition CppUtil.cpp:994
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)
Definition CppUtil.cpp:274
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:135
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:110
u32_t NodeID
Definition GeneralType.h:76
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

◆ buildCHG()

void CHGBuilder::buildCHG ( )

Definition at line 62 of file CHGBuilder.cpp.

63{
64
65 double timeStart, timeEnd;
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
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()
void dump(const std::string &filename)
Definition CHG.cpp:243
double buildingCHGTime
Definition CHG.h:328
static const Option< bool > DumpCHA
Definition Options.h:169
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:88

◆ buildCHGEdges()

void CHGBuilder::buildCHGEdges ( const Function *  F)

Definition at line 133 of file CHGBuilder.cpp.

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}
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:47
bool isConstructor(const Function *F)
Definition CppUtil.cpp:501
bool isDestructor(const Function *F)
Definition CppUtil.cpp:521
llvm::StoreInst StoreInst
Definition BasicTypes.h:155

◆ buildCHGNodes() [1/2]

void CHGBuilder::buildCHGNodes ( const Function *  F)

Definition at line 122 of file CHGBuilder.cpp.

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}
#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 {
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}
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:251

◆ buildClassNameToAncestorsDescendantsMap()

void CHGBuilder::buildClassNameToAncestorsDescendantsMap ( )

Definition at line 268 of file CHGBuilder.cpp.

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}
CHGraph::WorkList WorkList
Definition CHGBuilder.h:46
CHGraph::CHNodeSetTy CHNodeSetTy
Definition CHGBuilder.h:45
NameToCHNodesMap classNameToAncestorsMap
Definition CHG.h:331
NameToCHNodesMap classNameToDescendantsMap
Definition CHG.h:330
virtual const std::string & getName() const
Definition CHG.h:127
iterator begin()
Iterators.
IDToNodeMapTy::const_iterator const_iterator

◆ buildCSToCHAVtblsAndVfnsMap()

void CHGBuilder::buildCSToCHAVtblsAndVfnsMap ( )

Definition at line 662 of file CHGBuilder.cpp.

663{
664
665 for (Module &M : llvmModuleSet()->getLLVMModules())
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}
cJSON * child
Definition cJSON.cpp:2723
const CHNodeSetTy & getCSClasses(const CallBase *cs)
CallNodeToVFunSetMap callNodeToCHAVFnsMap
Definition CHG.h:339
void getVFnsFromVtbls(const CallICFGNode *cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override
Definition CHG.cpp:125
CallNodeToVTableSetMap callNodeToCHAVtblsMap
Definition CHG.h:338
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
bool isVirtualCallSite(const CallBase *cs)
Definition CppUtil.cpp:289
llvm::const_inst_iterator const_inst_iterator
Definition BasicTypes.h:261
llvm::CallBase CallBase
Definition BasicTypes.h:153
Set< const GlobalObjVar * > VTableSet
Definition CHG.h:46
Set< const FunObjVar * > VFunSet
Definition CHG.h:47

◆ buildInternalMaps()

void CHGBuilder::buildInternalMaps ( )

Definition at line 155 of file CHGBuilder.cpp.

◆ buildVirtualFunctionToIDMap()

void CHGBuilder::buildVirtualFunctionToIDMap ( )

Definition at line 563 of file CHGBuilder.cpp.

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}
Map< const FunObjVar *, u32_t > virtualFunctionToIDMap
Definition CHG.h:336
u32_t vfID
Definition CHG.h:327
Set< const CHNode * > CHNodeSetTy
Definition CHG.h:246
const std::vector< FuncVector > & getVirtualFunctionVectors() const
Definition CHG.h:175

◆ connectInheritEdgeViaCall()

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

Definition at line 162 of file CHGBuilder.cpp.

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}
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:100
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
llvm::Argument Argument
Definition BasicTypes.h:152

◆ connectInheritEdgeViaStore()

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

Definition at line 193 of file CHGBuilder.cpp.

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}

◆ createNode()

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

Definition at line 241 of file CHGBuilder.cpp.

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}
@ INSTANTCE
Definition CHG.h:85
void addInstances(const std::string templateName, CHNode *node)
Definition CHG.h:296
u32_t classNum
Definition CHG.h:326
Map< std::string, CHNode * > classNameToNodeMap
Definition CHG.h:329
void addGNode(NodeID id, NodeType *node)
Add a Node.
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 704 of file CHGBuilder.cpp.

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}
const CHGraph::CHNodeSetTy & getInstancesAndDescendants(const std::string &className)
CallNodeToCHNodesMap callNodeToClassesMap
Definition CHG.h:334
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition CppUtil.cpp:613

◆ getInstancesAndDescendants()

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

Definition at line 301 of file CHGBuilder.cpp.

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}
const CHNodeSetTy & getInstances(const std::string className)
Definition CHG.h:309
NameToCHNodesMap classNameToInstAndDescsMap
Definition CHG.h:332
const CHNodeSetTy & getDescendants(const std::string className)
Definition CHG.h:305
bool isTemplate() const
Definition CHG.h:165

◆ llvmModuleSet()

LLVMModuleSet * CHGBuilder::llvmModuleSet ( )
private

Definition at line 57 of file CHGBuilder.cpp.

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

◆ readInheritanceMetadataFromModule()

void CHGBuilder::readInheritanceMetadataFromModule ( const Module &  M)

Definition at line 220 of file CHGBuilder.cpp.

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}
llvm::MDString MDString
Definition BasicTypes.h:105
llvm::NamedMDNode NamedMDNode
LLVM metadata and debug information.
Definition BasicTypes.h:115
llvm::MDNode MDNode
Definition BasicTypes.h:116

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: