Static Value-Flow Analysis
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

Member Function Documentation

◆ addFuncToFuncVector()

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

Definition at line 740 of file CHGBuilder.cpp.

741 {
743  {
744  if (const auto* tf = cppUtil::getThunkTarget(lf))
745  {
746  SVFFunction* pFunction =
748  v.push_back(pFunction);
749  }
750  }
751  else
752  {
753  SVFFunction* pFunction =
755  v.push_back(pFunction);
756  }
757 }
LLVMModuleSet * llvmModuleSet()
Definition: CHGBuilder.cpp:60
SVFFunction * getSVFFunction(const Function *fun) const
Definition: LLVMModule.h:230
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 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  {
375  const ConstantStruct *vtblStruct = cppUtil::getVtblStruct(globalvalue);
376 
377  string vtblClassName = getClassNameFromVtblObj(globalvalue->getName().str());
378  CHNode *node = chg->getNode(vtblClassName);
379  assert(node && "node not found?");
380 
381  SVFGlobalValue* pValue =
383  globalvalue);
384  pValue->setName(vtblClassName);
385  node->setVTable(pValue);
386 
387  for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
388  {
389  const ConstantArray *vtbl =
390  SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
391  assert(vtbl && "Element of initializer not an array?");
392 
393  /*
394  * items in vtables can be classified into 3 categories:
395  * 1. i8* null
396  * 2. i8* inttoptr xxx
397  * 3. i8* bitcast xxx
398  */
399  bool pure_abstract = true;
400  u32_t i = 0;
401  while (i < vtbl->getNumOperands())
402  {
403  CHNode::FuncVector virtualFunctions;
404  bool is_virtual = false; // virtual inheritance
405  int null_ptr_num = 0;
406  for (; i < vtbl->getNumOperands(); ++i)
407  {
408  Constant* operand = vtbl->getOperand(i);
409  if (SVFUtil::isa<ConstantPointerNull>(operand))
410  {
411  if (i > 0 && !SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i-1)))
412  {
413  auto foo = [&is_virtual, &null_ptr_num, &vtbl, &i](const Value* val)
414  {
415  if (val->getName().str().compare(0, ztiLabel.size(), ztiLabel) == 0)
416  {
417  is_virtual = true;
418  null_ptr_num = 1;
419  while (i+null_ptr_num < vtbl->getNumOperands())
420  {
421  if (SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i+null_ptr_num)))
422  null_ptr_num++;
423  else
424  break;
425  }
426  }
427  };
428  if (const ConstantExpr *ce =
429  SVFUtil::dyn_cast<ConstantExpr>(vtbl->getOperand(i-1)))
430  {
431  if(ce->getOpcode() == Instruction::BitCast)
432  foo(ce->getOperand(0));
433  }
434  else
435  {
436  // opaque pointer mode
437  foo(vtbl->getOperand(i - 1));
438  }
439  }
440  continue;
441  }
442 
443  auto foo = [this, &virtualFunctions, &pure_abstract, &vtblClassName](const Value* operand)
444  {
445  if (const Function* f = SVFUtil::dyn_cast<Function>(operand))
446  {
447  addFuncToFuncVector(virtualFunctions, f);
448  if (f->getName().str().compare(pureVirtualFunName) == 0)
449  {
450  pure_abstract &= true;
451  }
452  else
453  {
454  pure_abstract &= false;
455  }
456  struct DemangledName dname = demangle(f->getName().str());
457  if (dname.className.size() > 0 &&
458  vtblClassName.compare(dname.className) != 0)
459  {
460  if(!chg->getNode(dname.className)) createNode(dname.className);
461  chg->addEdge(vtblClassName, dname.className, CHEdge::INHERITANCE);
462  }
463  }
464  else
465  {
466  if (const GlobalAlias *alias =
467  SVFUtil::dyn_cast<GlobalAlias>(operand))
468  {
469  const Constant *aliasValue = alias->getAliasee();
470  if (const Function* aliasFunc =
471  SVFUtil::dyn_cast<Function>(aliasValue))
472  {
473  addFuncToFuncVector(virtualFunctions, aliasFunc);
474  }
475  else if (const ConstantExpr *aliasconst =
476  SVFUtil::dyn_cast<ConstantExpr>(aliasValue))
477  {
478  (void)aliasconst; // Suppress warning of unused variable under release build
479  assert(aliasconst->getOpcode() == Instruction::BitCast &&
480  "aliased constantexpr in vtable not a bitcast");
481  const Function* aliasbitcastfunc =
482  SVFUtil::dyn_cast<Function>(aliasconst->getOperand(0));
483  assert(aliasbitcastfunc &&
484  "aliased bitcast in vtable not a function");
485  addFuncToFuncVector(virtualFunctions, aliasbitcastfunc);
486  }
487  else
488  {
489  assert(false && "alias not function or bitcast");
490  }
491 
492  pure_abstract &= false;
493  }
494  else if (operand->getName().str().compare(0, ztiLabel.size(),
495  ztiLabel) == 0)
496  {
497  }
498  else
499  {
500  assert("what else can be in bitcast of a vtable?");
501  }
502  }
503  };
504 
520  if (const ConstantExpr *ce =
521  SVFUtil::dyn_cast<ConstantExpr>(operand))
522  {
523  u32_t opcode = ce->getOpcode();
524  assert(opcode == Instruction::IntToPtr);
525  assert(ce->getNumOperands() == 1 &&
526  "inttptr operand num not 1");
527  if (opcode == Instruction::IntToPtr)
528  {
529  node->setMultiInheritance();
530  ++i;
531  break;
532  }
533  }
534  else
535  {
536  foo(operand);
537  }
538  }
539  if (is_virtual && virtualFunctions.size() > 0)
540  {
541  for (int i = 0; i < null_ptr_num; ++i)
542  {
543  const SVFFunction* fun = virtualFunctions[i];
544  virtualFunctions.insert(virtualFunctions.begin(), fun);
545  }
546  }
547  if (virtualFunctions.size() > 0)
548  node->addVirtualFunctionVector(virtualFunctions);
549  }
550  if (pure_abstract == true)
551  {
552  node->setPureAbstract();
553  }
554  }
555  }
556  }
557 }
const string ztiLabel
Definition: CHGBuilder.cpp:58
const string pureVirtualFunName
Definition: CHGBuilder.cpp:56
unsigned u32_t
Definition: CommandLine.h:18
@ INHERITANCE
Definition: CHG.h:86
void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f)
Definition: CHGBuilder.cpp:740
CHNode * createNode(const std::string &name)
Definition: CHGBuilder.cpp:241
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 setMultiInheritance()
Definition: CHG.h:152
void addVirtualFunctionVector(FuncVector vfuncvec)
Definition: CHG.h:174
std::vector< const SVFFunction * > FuncVector
Definition: CHG.h:121
void setVTable(const SVFGlobalValue *vtbl)
Definition: CHG.h:189
void setPureAbstract()
Attribute.
Definition: CHG.h:148
SVFGlobalValue * getSVFGlobalValue(const GlobalValue *g) const
Definition: LLVMModule.h:258
void setName(const std::string &n)
Definition: SVFValue.h:247
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:128
llvm::ConstantStruct ConstantStruct
Definition: BasicTypes.h:106
llvm::ConstantArray ConstantArray
Definition: BasicTypes.h:123
llvm::Function Function
Definition: BasicTypes.h:85
llvm::GlobalValue GlobalValue
Definition: BasicTypes.h:88
llvm::Constant Constant
Definition: BasicTypes.h:124
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82
llvm::ConstantExpr ConstantExpr
Definition: BasicTypes.h:120

◆ buildCHG()

void CHGBuilder::buildCHG ( )

Definition at line 65 of file CHGBuilder.cpp.

66 {
67 
68  double timeStart, timeEnd;
69  timeStart = PTAStat::getClk(true);
70  for (Module &M : llvmModuleSet()->getLLVMModules())
71  {
72  DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("construct CHGraph From module "
73  + M.getName().str() + "...\n"));
75  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
76  buildCHGNodes(&(*I));
77  for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
78  buildCHGNodes(&(*F));
79  for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
80  buildCHGEdges(&(*F));
81 
82  analyzeVTables(M);
83  }
84 
85  DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("build Internal Maps ...\n"));
87 
88  timeEnd = PTAStat::getClk(true);
89  chg->buildingCHGTime = (timeEnd - timeStart) / TIMEINTERVAL;
90 
91  if (Options::DumpCHA())
92  chg->dump("cha");
93 }
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define TIMEINTERVAL
Definition: SVFType.h:512
#define DGENERAL
Definition: SVFType.h:490
void analyzeVTables(const Module &M)
Definition: CHGBuilder.cpp:367
void readInheritanceMetadataFromModule(const Module &M)
Definition: CHGBuilder.cpp:220
void buildCHGNodes(const GlobalValue *V)
Definition: CHGBuilder.cpp:95
void buildCHGEdges(const Function *F)
Definition: CHGBuilder.cpp:136
void buildInternalMaps()
Definition: CHGBuilder.cpp:158
void dump(const std::string &filename)
Definition: CHG.cpp:242
double buildingCHGTime
Definition: CHG.h:323
static const Option< bool > DumpCHA
Definition: Options.h:176
static double getClk(bool mark=false)
Definition: SVFStat.cpp:47
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
llvm::Module Module
Definition: BasicTypes.h:84

◆ buildCHGEdges()

void CHGBuilder::buildCHGEdges ( const Function F)

Definition at line 136 of file CHGBuilder.cpp.

137 {
138  if (isConstructor(F) || isDestructor(F))
139  {
140  for (Function::const_iterator B = F->begin(), E = F->end(); B != E; ++B)
141  {
142  for (BasicBlock::const_iterator I = B->begin(), E = B->end(); I != E; ++I)
143  {
144  if (LLVMUtil::isCallSite(&(*I)))
145  {
146  connectInheritEdgeViaCall(F, SVFUtil::cast<CallBase>(&(*I)));
147  }
148  else if (const StoreInst *store = SVFUtil::dyn_cast<StoreInst>(&(*I)))
149  {
151  }
152  }
153  }
154  }
155 }
void connectInheritEdgeViaStore(const Function *caller, const StoreInst *store)
Definition: CHGBuilder.cpp:193
void connectInheritEdgeViaCall(const Function *caller, const CallBase *cs)
Definition: CHGBuilder.cpp:165
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:489
bool isDestructor(const Function *F)
Definition: CppUtil.cpp:509
llvm::StoreInst StoreInst
Definition: BasicTypes.h:148

◆ buildCHGNodes() [1/2]

void CHGBuilder::buildCHGNodes ( const Function F)

Definition at line 125 of file CHGBuilder.cpp.

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

◆ buildCHGNodes() [2/2]

void CHGBuilder::buildCHGNodes ( const GlobalValue V)

Definition at line 95 of file CHGBuilder.cpp.

96 {
97  if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
98  {
99  const ConstantStruct *vtblStruct = cppUtil::getVtblStruct(globalvalue);
100  string className = getClassNameFromVtblObj(globalvalue->getName().str());
101  if (!chg->getNode(className))
102  createNode(className);
103 
104  for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
105  {
106  const ConstantArray *vtbl = SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
107  assert(vtbl && "Element of initializer not an array?");
108  for (u32_t i = 0; i < vtbl->getNumOperands(); ++i)
109  {
110  if(const ConstantExpr *ce = isCastConstantExpr(vtbl->getOperand(i)))
111  {
112  const Value* bitcastValue = ce->getOperand(0);
113  if (const Function* func = SVFUtil::dyn_cast<Function>(bitcastValue))
114  {
115  struct DemangledName dname = demangle(func->getName().str());
116  if (!chg->getNode(dname.className))
117  createNode(dname.className);
118  }
119  }
120  }
121  }
122  }
123 }
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition: LLVMUtil.h:211

◆ 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;
276  CHNodeSetTy visitedNodes;
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();
290  chg->classNameToAncestorsMap[node->getName()].insert(succnode);
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:326
NameToCHNodesMap classNameToDescendantsMap
Definition: CHG.h:325
std::string getName() const
Definition: CHG.h:130
iterator begin()
Iterators.
Definition: GenericGraph.h:627
IDToNodeMapTy::const_iterator const_iterator
Definition: GenericGraph.h:607
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430

◆ buildCSToCHAVtblsAndVfnsMap()

void CHGBuilder::buildCSToCHAVtblsAndVfnsMap ( )

Definition at line 659 of file CHGBuilder.cpp.

660 {
661 
662  for (Module &M : llvmModuleSet()->getLLVMModules())
663  {
664  for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
665  {
666  for (const_inst_iterator II = inst_begin(*F), E = inst_end(*F); II != E; ++II)
667  {
668  if(const CallBase* callInst = SVFUtil::dyn_cast<CallBase>(&*II))
669  {
670  if (cppUtil::isVirtualCallSite(callInst) == false)
671  continue;
672 
673  VTableSet vtbls;
674  const CHNodeSetTy& chClasses = getCSClasses(callInst);
675  for (CHNodeSetTy::const_iterator it = chClasses.begin(), eit = chClasses.end(); it != eit; ++it)
676  {
677  const CHNode *child = *it;
678  const SVFGlobalValue *vtbl = child->getVTable();
679  if (vtbl != nullptr)
680  {
681  vtbls.insert(vtbl);
682  }
683  }
684  if (vtbls.size() > 0)
685  {
686  ICFGNode* icfgNode =
687  llvmModuleSet()->getICFGNode(callInst);
688  chg->callNodeToCHAVtblsMap[icfgNode] = vtbls;
689  VFunSet virtualFunctions;
690  chg->getVFnsFromVtbls(SVFUtil::cast<CallICFGNode>(icfgNode), vtbls, virtualFunctions);
691  if (virtualFunctions.size() > 0)
692  chg->callNodeToCHAVFnsMap[icfgNode] = virtualFunctions;
693  }
694  }
695  }
696  }
697  }
698 }
cJSON * child
Definition: cJSON.cpp:2723
const CHNodeSetTy & getCSClasses(const CallBase *cs)
Definition: CHGBuilder.cpp:701
CallNodeToVFunSetMap callNodeToCHAVFnsMap
Definition: CHG.h:334
void getVFnsFromVtbls(const CallICFGNode *cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override
Definition: CHG.cpp:124
CallNodeToVTableSetMap callNodeToCHAVtblsMap
Definition: CHG.h:333
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:250
llvm::CallBase CallBase
Definition: BasicTypes.h:146
Set< const SVFGlobalValue * > VTableSet
Definition: CHG.h:44
Set< const SVFFunction * > VFunSet
Definition: CHG.h:47

◆ buildInternalMaps()

void CHGBuilder::buildInternalMaps ( )

Definition at line 158 of file CHGBuilder.cpp.

159 {
163 }
void buildVirtualFunctionToIDMap()
Definition: CHGBuilder.cpp:560
void buildCSToCHAVtblsAndVfnsMap()
Definition: CHGBuilder.cpp:659
void buildClassNameToAncestorsDescendantsMap()
Definition: CHGBuilder.cpp:268

◆ buildVirtualFunctionToIDMap()

void CHGBuilder::buildVirtualFunctionToIDMap ( )

Definition at line 560 of file CHGBuilder.cpp.

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

◆ connectInheritEdgeViaCall()

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

Definition at line 165 of file CHGBuilder.cpp.

166 {
167  if (getCallee(cs) == nullptr)
168  return;
169 
170  const Function* callee = getCallee(cs);
171 
172  struct DemangledName dname = demangle(caller->getName().str());
173  if ((isConstructor(caller) && isConstructor(callee)) || (isDestructor(caller) && isDestructor(callee)))
174  {
175  if (cs->arg_size() < 1 || (cs->arg_size() < 2 && cs->paramHasAttr(0, llvm::Attribute::StructRet)))
176  return;
177  const Value* csThisPtr = cppUtil::getVCallThisPtr(cs);
178  //const Argument* consThisPtr = getConstructorThisPtr(caller);
179  //bool samePtr = isSameThisPtrInConstructor(consThisPtr, csThisPtr);
180  bool samePtrTrue = true;
181  if (csThisPtr != nullptr && samePtrTrue)
182  {
183  struct DemangledName basename = demangle(callee->getName().str());
184  if (!LLVMUtil::isCallSite(csThisPtr) &&
185  basename.className.size() > 0)
186  {
188  }
189  }
190  }
191 }
const Function * getCallee(const CallBase *cs)
Definition: LLVMUtil.h:63
const Value * getVCallThisPtr(const CallBase *cs)
Definition: CppUtil.cpp:411

◆ 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);
206  if (cppUtil::isValVtbl(gepval))
207  {
208  string vtblClassName = getClassNameFromVtblObj(gepval->getName().str());
209  if (vtblClassName.size() > 0 && dname.className.compare(vtblClassName) != 0)
210  {
211  chg->addEdge(dname.className, vtblClassName, CHEdge::INHERITANCE);
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);
250  CHNode* templateNode = chg->getNode(templateName);
251  if (!templateNode)
252  {
253  DBOUT(DCHA, outs() << "\t Create Template CHANode " + templateName + " for class " + className + "...\n");
254  templateNode = createNode(templateName);
255  templateNode->setTemplate();
256  }
257  chg->addEdge(className, templateName, CHEdge::INSTANTCE);
258  chg->addInstances(templateName,node);
259  }
260  return node;
261 }
@ INSTANTCE
Definition: CHG.h:87
void addInstances(const std::string templateName, CHNode *node)
Definition: CHG.h:290
u32_t classNum
Definition: CHG.h:321
Map< std::string, CHNode * > classNameToNodeMap
Definition: CHG.h:324
void setTemplate()
Definition: CHG.h:156
void addGNode(NodeID id, NodeType *node)
Add a Node.
Definition: GenericGraph.h:646
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
std::string getBeforeBrackets(const std::string &name)
Definition: CppUtil.cpp:127

◆ getCSClasses()

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

Definition at line 701 of file CHGBuilder.cpp.

702 {
703  assert(cppUtil::isVirtualCallSite(cs) && "not virtual callsite!");
704 
705  ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(cs);
706 
707  CHGraph::CallNodeToCHNodesMap::const_iterator it = chg->callNodeToClassesMap.find(icfgNode);
708  if (it != chg->callNodeToClassesMap.end())
709  {
710  return it->second;
711  }
712  else
713  {
714  Set<string> thisPtrClassNames = getClassNameOfThisPtr(cs);
715 
716  if(thisPtrClassNames.empty())
717  {
718  // if we cannot infer classname, conservatively push all class nodes
719  for (const auto &node: *chg)
720  {
721  chg->callNodeToClassesMap[icfgNode].insert(node.second);
722  }
723  return chg->callNodeToClassesMap[icfgNode];
724  }
725 
726  for (const auto &thisPtrClassName: thisPtrClassNames)
727  {
728  if (const CHNode* thisNode = chg->getNode(thisPtrClassName))
729  {
730  const CHGraph::CHNodeSetTy& instAndDesces = getInstancesAndDescendants(thisPtrClassName);
731  chg->callNodeToClassesMap[icfgNode].insert(thisNode);
732  for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); it2 != eit; ++it2)
733  chg->callNodeToClassesMap[icfgNode].insert(*it2);
734  }
735  }
736  return chg->callNodeToClassesMap[icfgNode];
737  }
738 }
const CHGraph::CHNodeSetTy & getInstancesAndDescendants(const std::string &className)
Definition: CHGBuilder.cpp:301
CallNodeToCHNodesMap callNodeToClassesMap
Definition: CHG.h:329
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition: CppUtil.cpp:601
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96

◆ 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);
320  const CHNodeSetTy& instance_descendants = chg->getDescendants(node->getName());
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 & getDescendants(const std::string className)
Definition: CHG.h:299
const CHNodeSetTy & getInstances(const std::string className)
Definition: CHG.h:303
NameToCHNodesMap classNameToInstAndDescsMap
Definition: CHG.h:327
bool isTemplate() const
Definition: CHG.h:168

◆ llvmModuleSet()

LLVMModuleSet * CHGBuilder::llvmModuleSet ( )
private

Definition at line 60 of file CHGBuilder.cpp.

61 {
63 }
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:118

◆ 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();
236  chg->addEdge(className, baseName, CHEdge::INHERITANCE);
237  }
238  }
239 }
llvm::MDString MDString
Definition: BasicTypes.h:101
llvm::NamedMDNode NamedMDNode
LLVM metadata and debug information.
Definition: BasicTypes.h:111
llvm::MDNode MDNode
Definition: BasicTypes.h:112

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: