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)
 
CHNodecreateNode (const std::string &name)
 
void connectInheritEdgeViaCall (const Function *caller, const CallBase *cs)
 
void connectInheritEdgeViaStore (const Function *caller, const StoreInst *store)
 
void buildClassNameToAncestorsDescendantsMap ()
 
const CHGraph::CHNodeSetTygetInstancesAndDescendants (const std::string &className)
 
void analyzeVTables (const Module &M)
 
void buildVirtualFunctionToIDMap ()
 
void buildCSToCHAVtblsAndVfnsMap ()
 
const CHNodeSetTygetCSClasses (const CallBase *cs)
 
void addFuncToFuncVector (CHNode::FuncVector &v, const Function *f)
 

Private Member Functions

LLVMModuleSetllvmModuleSet ()
 

Private Attributes

CHGraphchg
 

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

747{
749 {
750 const auto* tf = cppUtil::getThunkTarget(lf);
751 const FunObjVar* pFunction =
753 v.push_back(pFunction);
754 }
755 else
756 {
757 const FunObjVar* pFunction =
759 v.push_back(pFunction);
760 }
761}
LLVMModuleSet * llvmModuleSet()
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:270
bool isCPPThunkFunction(const Function *F)
Definition CppUtil.cpp:383
const Function * getThunkTarget(const Function *F)
Definition CppUtil.cpp:389

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

370{
371 for (Module::const_global_iterator I = M.global_begin(),
372 E = M.global_end(); I != E; ++I)
373 {
374 const GlobalValue *globalvalue = SVFUtil::dyn_cast<const GlobalValue>(&(*I));
375 if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
376 {
378
379 string vtblClassName = getClassNameFromVtblObj(globalvalue->getName().str());
381 assert(node && "node not found?");
384 GlobalObjVar* globalObjVar = SVFUtil::cast<GlobalObjVar>(pVar);
385 globalObjVar->setName(vtblClassName);
386 node->setVTable(globalObjVar);
387
388 for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
389 {
390 const ConstantArray *vtbl =
391 SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
392 assert(vtbl && "Element of initializer not an array?");
393
394 /*
395 * items in vtables can be classified into 3 categories:
396 * 1. i8* null
397 * 2. i8* inttoptr xxx
398 * 3. i8* bitcast xxx
399 */
400 bool pure_abstract = true;
401 u32_t i = 0;
403 {
405 bool is_virtual = false; // virtual inheritance
406 int null_ptr_num = 0;
407 for (; i < vtbl->getNumOperands(); ++i)
408 {
409 Constant* operand = vtbl->getOperand(i);
410 if (SVFUtil::isa<ConstantPointerNull>(operand))
411 {
412 if (i > 0 && !SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i-1)))
413 {
414 auto foo = [&is_virtual, &null_ptr_num, &vtbl, &i](const Value* val)
415 {
416 if (val->getName().str().compare(0, ztiLabel.size(), ztiLabel) == 0)
417 {
418 is_virtual = true;
419 null_ptr_num = 1;
421 {
422 if (SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i+null_ptr_num)))
423 null_ptr_num++;
424 else
425 break;
426 }
427 }
428 };
429 if (const ConstantExpr *ce =
430 SVFUtil::dyn_cast<ConstantExpr>(vtbl->getOperand(i-1)))
431 {
432 if(ce->getOpcode() == Instruction::BitCast)
433 foo(ce->getOperand(0));
434 }
435 else
436 {
437 // opaque pointer mode
438 foo(vtbl->getOperand(i - 1));
439 }
440 }
441 continue;
442 }
443
444 auto foo = [this, &virtualFunctions, &pure_abstract, &vtblClassName](const Value* operand)
445 {
446 if (const Function* f = SVFUtil::dyn_cast<Function>(operand))
447 {
449 if (f->getName().str().compare(pureVirtualFunName) == 0)
450 {
451 pure_abstract &= true;
452 }
453 else
454 {
455 pure_abstract &= false;
456 }
457 struct DemangledName dname = demangle(f->getName().str());
458 if (dname.className.size() > 0 &&
459 vtblClassName.compare(dname.className) != 0)
460 {
461 if(!chg->getNode(dname.className)) createNode(dname.className);
463 }
464 }
465 else
466 {
467 if (const GlobalAlias *alias =
468 SVFUtil::dyn_cast<GlobalAlias>(operand))
469 {
470 const Constant *aliasValue = alias->getAliasee();
471 while (const GlobalAlias *valAsAlias = SVFUtil::dyn_cast<GlobalAlias>(aliasValue))
472 {
473 aliasValue = valAsAlias->getAliasee();
474 }
475
476 if (const Function* aliasFunc =
477 SVFUtil::dyn_cast<Function>(aliasValue))
478 {
480 }
481 else if (const ConstantExpr *aliasconst =
482 SVFUtil::dyn_cast<ConstantExpr>(aliasValue))
483 {
484 (void)aliasconst; // Suppress warning of unused variable under release build
485 assert(aliasconst->getOpcode() == Instruction::BitCast &&
486 "aliased constantexpr in vtable not a bitcast");
488 SVFUtil::dyn_cast<Function>(aliasconst->getOperand(0));
490 "aliased bitcast in vtable not a function");
492 }
493 else
494 {
495 assert(false && "alias not function or bitcast");
496 }
497
498 pure_abstract &= false;
499 }
500 else if (operand->getName().str().compare(0, ztiLabel.size(),
501 ztiLabel) == 0)
502 {
503 }
504 else
505 {
506 assert("what else can be in bitcast of a vtable?");
507 }
508 }
509 };
510
526 if (const ConstantExpr *ce =
527 SVFUtil::dyn_cast<ConstantExpr>(operand))
528 {
529 u32_t opcode = ce->getOpcode();
530 assert(opcode == Instruction::IntToPtr);
531 assert(ce->getNumOperands() == 1 &&
532 "inttptr operand num not 1");
533 if (opcode == Instruction::IntToPtr)
534 {
535 node->setMultiInheritance();
536 ++i;
537 break;
538 }
539 }
540 else
541 {
542 foo(operand);
543 }
544 }
545 if (is_virtual && virtualFunctions.size() > 0)
546 {
547 for (int i = 0; i < null_ptr_num; ++i)
548 {
549 const FunObjVar* fun = virtualFunctions[i];
550 virtualFunctions.insert(virtualFunctions.begin(), fun);
551 }
552 }
553 if (virtualFunctions.size() > 0)
555 }
556 if (pure_abstract == true)
557 {
558 node->setPureAbstract();
559 }
560 }
561 }
562 }
563}
const string ztiLabel
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:97
CHNode * getNode(const std::string name) const
Definition CHG.cpp:112
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:118
struct DemangledName demangle(const std::string &name)
Definition CppUtil.cpp:195
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
Definition CppUtil.cpp:323
std::string getClassNameFromVtblObj(const std::string &vtblName)
Definition CppUtil.cpp:304
bool isValVtbl(const Value *val)
Definition CppUtil.cpp:336
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:135
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:110
u32_t NodeID
Definition GeneralType.h:56
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 64 of file CHGBuilder.cpp.

65{
66
67 double timeStart, timeEnd;
69 for (Module &M : llvmModuleSet()->getLLVMModules())
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}
#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 DGENERAL
Definition SVFType.h:599
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:242
double buildingCHGTime
Definition CHG.h:328
static const Option< bool > DumpCHA
Definition Options.h:173
static double getClk(bool mark=false)
Definition SVFStat.cpp:51
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:105
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
llvm::Module Module
Definition BasicTypes.h:88

◆ buildCHGEdges()

void CHGBuilder::buildCHGEdges ( const Function F)

Definition at line 135 of file CHGBuilder.cpp.

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

◆ buildCHGNodes() [1/2]

void CHGBuilder::buildCHGNodes ( const Function F)

Definition at line 124 of file CHGBuilder.cpp.

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}
#define DCHA
Definition SVFType.h:615

◆ buildCHGNodes() [2/2]

void CHGBuilder::buildCHGNodes ( const GlobalValue V)

Definition at line 94 of file CHGBuilder.cpp.

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

◆ buildClassNameToAncestorsDescendantsMap()

void CHGBuilder::buildClassNameToAncestorsDescendantsMap ( )

Definition at line 270 of file CHGBuilder.cpp.

271{
272
273 for (CHGraph::const_iterator it = chg->begin(), eit = chg->end();
274 it != eit; ++it)
275 {
276 const CHNode *node = it->second;
277 WorkList worklist;
279 worklist.push(node);
280 while (!worklist.empty())
281 {
282 const CHNode *curnode = worklist.pop();
283 if (visitedNodes.find(curnode) == visitedNodes.end())
284 {
285 for (CHEdge::CHEdgeSetTy::const_iterator it =
286 curnode->getOutEdges().begin(), eit =
287 curnode->getOutEdges().end(); it != eit; ++it)
288 {
289 if ((*it)->getEdgeType() == CHEdge::INHERITANCE)
290 {
291 CHNode *succnode = (*it)->getDstNode();
293 chg->classNameToDescendantsMap[succnode->getName()].insert(node);
294 worklist.push(succnode);
295 }
296 }
297 visitedNodes.insert(curnode);
298 }
299 }
300 }
301}
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 665 of file CHGBuilder.cpp.

666{
667
668 for (Module &M : llvmModuleSet()->getLLVMModules())
669 {
670 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
671 {
672 for (const_inst_iterator II = inst_begin(*F), E = inst_end(*F); II != E; ++II)
673 {
674 if(const CallBase* callInst = SVFUtil::dyn_cast<CallBase>(&*II))
675 {
676 if (cppUtil::isVirtualCallSite(callInst) == false)
677 continue;
678
680 const CHNodeSetTy& chClasses = getCSClasses(callInst);
681 for (CHNodeSetTy::const_iterator it = chClasses.begin(), eit = chClasses.end(); it != eit; ++it)
682 {
683 const CHNode *child = *it;
684 const GlobalObjVar *vtbl = child->getVTable();
685 if (vtbl != nullptr)
686 {
687 vtbls.insert(vtbl);
688 }
689 }
690 if (vtbls.size() > 0)
691 {
692 ICFGNode* icfgNode =
693 llvmModuleSet()->getICFGNode(callInst);
694 chg->callNodeToCHAVtblsMap[icfgNode] = vtbls;
696 chg->getVFnsFromVtbls(SVFUtil::cast<CallICFGNode>(icfgNode), vtbls, virtualFunctions);
697 if (virtualFunctions.size() > 0)
699 }
700 }
701 }
702 }
703 }
704}
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:124
CallNodeToVTableSetMap callNodeToCHAVtblsMap
Definition CHG.h:338
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
bool isVirtualCallSite(const CallBase *cs)
Definition CppUtil.cpp:352
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 157 of file CHGBuilder.cpp.

◆ buildVirtualFunctionToIDMap()

void CHGBuilder::buildVirtualFunctionToIDMap ( )

Definition at line 566 of file CHGBuilder.cpp.

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

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;
176 if(caller->arg_size() == 0)
177 {
178 return;
179 }
183 if (csThisPtr != nullptr && samePtr)
184 {
185 struct DemangledName basename = demangle(callee->getName().str());
187 basename.className.size() > 0)
188 {
189 chg->addEdge(dname.className, basename.className, CHEdge::INHERITANCE);
190 }
191 }
192 }
193}
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:98
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
llvm::Argument Argument
Definition BasicTypes.h:152

◆ connectInheritEdgeViaStore()

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

Definition at line 195 of file CHGBuilder.cpp.

196{
197 struct DemangledName dname = demangle(caller->getName().str());
198 if (const ConstantExpr *ce = SVFUtil::dyn_cast<ConstantExpr>(storeInst->getValueOperand()))
199 {
200 if (ce->getOpcode() == Instruction::BitCast)
201 {
202 const Value* bitcastval = ce->getOperand(0);
203 if (const ConstantExpr *bcce = SVFUtil::dyn_cast<ConstantExpr>(bitcastval))
204 {
205 if (bcce->getOpcode() == Instruction::GetElementPtr)
206 {
207 const Value* gepval = bcce->getOperand(0);
209 {
210 string vtblClassName = getClassNameFromVtblObj(gepval->getName().str());
211 if (vtblClassName.size() > 0 && dname.className.compare(vtblClassName) != 0)
212 {
214 }
215 }
216 }
217 }
218 }
219 }
220}

◆ createNode()

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

Definition at line 243 of file CHGBuilder.cpp.

244{
245 assert(!chg->getNode(className) && "this node should never be created before!");
246 CHNode * node = new CHNode(className, chg->classNum++);
247 chg->classNameToNodeMap[className] = node;
248 chg->addGNode(node->getId(), node);
249 if (className.size() > 0 && className[className.size() - 1] == '>')
250 {
251 string templateName = getBeforeBrackets(className);
253 if (!templateNode)
254 {
255 DBOUT(DCHA, outs() << "\t Create Template CHANode " + templateName + " for class " + className + "...\n");
257 templateNode->setTemplate();
258 }
261 }
262 return node;
263}
@ 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:161
std::string getBeforeBrackets(const std::string &name)
Definition CppUtil.cpp:127

◆ getCSClasses()

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

Definition at line 707 of file CHGBuilder.cpp.

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

◆ getInstancesAndDescendants()

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

Definition at line 303 of file CHGBuilder.cpp.

305{
306
307 CHGraph::NameToCHNodesMap::const_iterator it = chg->classNameToInstAndDescsMap.find(className);
308 if (it != chg->classNameToInstAndDescsMap.end())
309 {
310 return it->second;
311 }
312 else
313 {
314 chg->classNameToInstAndDescsMap[className] = chg->getDescendants(className);
315 if (chg->getNode(className)->isTemplate())
316 {
317 const CHNodeSetTy& instances = chg->getInstances(className);
318 for (CHNodeSetTy::const_iterator it = instances.begin(), eit = instances.end(); it != eit; ++it)
319 {
320 const CHNode *node = *it;
321 chg->classNameToInstAndDescsMap[className].insert(node);
323 for (CHNodeSetTy::const_iterator dit =
324 instance_descendants.begin(), deit =
325 instance_descendants.end(); dit != deit; ++dit)
326 {
327 chg->classNameToInstAndDescsMap[className].insert(*dit);
328 }
329 }
330 }
331 return chg->classNameToInstAndDescsMap[className];
332 }
333}
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 59 of file CHGBuilder.cpp.

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

◆ readInheritanceMetadataFromModule()

void CHGBuilder::readInheritanceMetadataFromModule ( const Module M)

Definition at line 222 of file CHGBuilder.cpp.

223{
224 for (Module::const_named_metadata_iterator mdit = M.named_metadata_begin(),
225 mdeit = M.named_metadata_end(); mdit != mdeit; ++mdit)
226 {
227 const NamedMDNode *md = &*mdit;
228 string mdname = md->getName().str();
229 if (mdname.compare(0, 15, "__cxx_bases_of_") != 0)
230 continue;
231 string className = mdname.substr(15);
232 for (NamedMDNode::const_op_iterator opit = md->op_begin(),
233 opeit = md->op_end(); opit != opeit; ++opit)
234 {
235 const MDNode *N = *opit;
236 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
237 string baseName = mdstr->getString().str();
239 }
240 }
241}
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: