Static Value-Flow Analysis
CHGBuilder.cpp
Go to the documentation of this file.
1 //===----- CHGBuilder.cpp -- Class hierarchy graph builder ---------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * CHGBuilder.cpp
25  *
26  * Created on: Jun 4, 2021
27  * Author: Yulei Sui
28  */
29 
30 #include <set>
31 #include <vector>
32 #include <map>
33 #include <fstream>
34 #include <iostream>
35 #include <iomanip> // setw() for formatting cout
36 #include <assert.h>
37 #include <stack>
38 
39 #include "SVF-LLVM/CHGBuilder.h"
40 #include "Util/Options.h"
41 #include "SVF-LLVM/CppUtil.h"
42 #include "SVFIR/SymbolTableInfo.h"
43 #include "Util/SVFUtil.h"
44 #include "SVF-LLVM/LLVMUtil.h"
45 #include "SVFIR/SVFModule.h"
46 #include "Util/PTAStat.h"
47 #include "SVF-LLVM/LLVMModule.h"
49 
50 using namespace SVF;
51 using namespace SVFUtil;
52 using namespace cppUtil;
53 using namespace LLVMUtil;
54 using namespace std;
55 
56 const string pureVirtualFunName = "__cxa_pure_virtual";
57 
58 const string ztiLabel = "_ZTI";
59 
61 {
63 }
64 
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"));
74  readInheritanceMetadataFromModule(M);
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"));
86  buildInternalMaps();
87 
88  timeEnd = PTAStat::getClk(true);
89  chg->buildingCHGTime = (timeEnd - timeStart) / TIMEINTERVAL;
90 
91  if (Options::DumpCHA())
92  chg->dump("cha");
93 }
94 
95 void CHGBuilder::buildCHGNodes(const GlobalValue *globalvalue)
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 }
124 
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 }
135 
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  {
150  connectInheritEdgeViaStore(F, store);
151  }
152  }
153  }
154  }
155 }
156 
157 
159 {
160  buildClassNameToAncestorsDescendantsMap();
161  buildVirtualFunctionToIDMap();
162  buildCSToCHAVtblsAndVfnsMap();
163 }
164 
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  {
187  chg->addEdge(dname.className, basename.className, CHEdge::INHERITANCE);
188  }
189  }
190  }
191 }
192 
193 void CHGBuilder::connectInheritEdgeViaStore(const Function* caller, const StoreInst* storeInst)
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 }
219 
221 {
222  for (Module::const_named_metadata_iterator mdit = M.named_metadata_begin(),
223  mdeit = M.named_metadata_end(); mdit != mdeit; ++mdit)
224  {
225  const NamedMDNode *md = &*mdit;
226  string mdname = md->getName().str();
227  if (mdname.compare(0, 15, "__cxx_bases_of_") != 0)
228  continue;
229  string className = mdname.substr(15);
230  for (NamedMDNode::const_op_iterator opit = md->op_begin(),
231  opeit = md->op_end(); opit != opeit; ++opit)
232  {
233  const MDNode *N = *opit;
234  const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
235  string baseName = mdstr->getString().str();
236  chg->addEdge(className, baseName, CHEdge::INHERITANCE);
237  }
238  }
239 }
240 
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 }
262 
263 /*
264  * build the following two maps:
265  * classNameToDescendantsMap
266  * chg->classNameToAncestorsMap
267  */
269 {
270 
271  for (CHGraph::const_iterator it = chg->begin(), eit = chg->end();
272  it != eit; ++it)
273  {
274  const CHNode *node = it->second;
275  WorkList worklist;
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 }
300 
302  const string& className)
303 {
304 
305  CHGraph::NameToCHNodesMap::const_iterator it = chg->classNameToInstAndDescsMap.find(className);
306  if (it != chg->classNameToInstAndDescsMap.end())
307  {
308  return it->second;
309  }
310  else
311  {
312  chg->classNameToInstAndDescsMap[className] = chg->getDescendants(className);
313  if (chg->getNode(className)->isTemplate())
314  {
315  const CHNodeSetTy& instances = chg->getInstances(className);
316  for (CHNodeSetTy::const_iterator it = instances.begin(), eit = instances.end(); it != eit; ++it)
317  {
318  const CHNode *node = *it;
319  chg->classNameToInstAndDescsMap[className].insert(node);
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 }
332 
333 
334 
335 
336 /*
337  * do the following things:
338  * 1. initialize virtualFunctions for each class
339  * 2. mark multi-inheritance classes
340  * 3. mark pure abstract classes
341  *
342  * Layout of VTables:
343  *
344  * 1. single inheritance
345  * class A {...};
346  * class B: public A {...};
347  * B's vtable: {i8 *null, _ZTI1B, ...}
348  *
349  * 2. normal multiple inheritance
350  * class A {...};
351  * class B {...};
352  * class C: public A, public B {...};
353  * C's vtable: {i8 *null, _ZTI1C, ..., inttoptr xxx, _ZTI1C, ...}
354  * "inttoptr xxx" servers as a delimiter for dividing virtual methods inherited
355  * from "class A" and "class B"
356  *
357  * 3. virtual diamond inheritance
358  * class A {...};
359  * class B: public virtual A {...};
360  * class C: public virtual A {...};
361  * class D: public B, public C {...};
362  * D's vtable: {i8 *null, _ZTI1C, ..., inttoptr xxx, _ZTI1C, i8 *null, ...}
363  * there will several "i8 *null" following "inttoptr xxx, _ZTI1C,", and the
364  * number of "i8 *null" is the same as the number of virtual methods in
365  * "class A"
366  */
368 {
369  for (Module::const_global_iterator I = M.global_begin(),
370  E = M.global_end(); I != E; ++I)
371  {
372  const GlobalValue *globalvalue = SVFUtil::dyn_cast<const GlobalValue>(&(*I));
373  if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
374  {
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 =
382  llvmModuleSet()->getSVFGlobalValue(
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 }
558 
559 
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 }
657 
658 
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 }
699 
700 
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 }
739 
741 {
743  {
744  if (const auto* tf = cppUtil::getThunkTarget(lf))
745  {
746  SVFFunction* pFunction =
747  llvmModuleSet()->getSVFFunction(tf);
748  v.push_back(pFunction);
749  }
750  }
751  else
752  {
753  SVFFunction* pFunction =
754  llvmModuleSet()->getSVFFunction(lf);
755  v.push_back(pFunction);
756  }
757 }
const string ztiLabel
Definition: CHGBuilder.cpp:58
const string pureVirtualFunName
Definition: CHGBuilder.cpp:56
#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 DCHA
Definition: SVFType.h:506
#define DGENERAL
Definition: SVFType.h:490
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
cJSON * child
Definition: cJSON.cpp:2723
const char *const string
Definition: cJSON.h:172
@ INHERITANCE
Definition: CHG.h:86
@ INSTANTCE
Definition: CHG.h:87
void analyzeVTables(const Module &M)
Definition: CHGBuilder.cpp:367
void connectInheritEdgeViaStore(const Function *caller, const StoreInst *store)
Definition: CHGBuilder.cpp:193
LLVMModuleSet * llvmModuleSet()
Definition: CHGBuilder.cpp:60
void readInheritanceMetadataFromModule(const Module &M)
Definition: CHGBuilder.cpp:220
void buildCHGNodes(const GlobalValue *V)
Definition: CHGBuilder.cpp:95
const CHGraph::CHNodeSetTy & getInstancesAndDescendants(const std::string &className)
Definition: CHGBuilder.cpp:301
void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f)
Definition: CHGBuilder.cpp:740
void buildCHGEdges(const Function *F)
Definition: CHGBuilder.cpp:136
void buildVirtualFunctionToIDMap()
Definition: CHGBuilder.cpp:560
void buildCSToCHAVtblsAndVfnsMap()
Definition: CHGBuilder.cpp:659
void buildInternalMaps()
Definition: CHGBuilder.cpp:158
CHGraph::CHNodeSetTy CHNodeSetTy
Definition: CHGBuilder.h:45
const CHNodeSetTy & getCSClasses(const CallBase *cs)
Definition: CHGBuilder.cpp:701
CHNode * createNode(const std::string &name)
Definition: CHGBuilder.cpp:241
void connectInheritEdgeViaCall(const Function *caller, const CallBase *cs)
Definition: CHGBuilder.cpp:165
void buildClassNameToAncestorsDescendantsMap()
Definition: CHGBuilder.cpp:268
Set< const CHNode * > CHNodeSetTy
Definition: CHG.h:240
void setTemplate()
Definition: CHG.h:156
void setMultiInheritance()
Definition: CHG.h:152
const std::vector< FuncVector > & getVirtualFunctionVectors() const
Definition: CHG.h:178
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
std::string getName() const
Definition: CHG.h:130
bool push(const Data &data)
Definition: WorkList.h:165
bool empty() const
Definition: WorkList.h:146
IDToNodeMapTy::const_iterator const_iterator
Definition: GenericGraph.h:607
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:118
static const Option< bool > DumpCHA
Definition: Options.h:176
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
static double getClk(bool mark=false)
Definition: SVFStat.cpp:47
const std::string & getName() const
Definition: SVFValue.h:243
void setName(const std::string &n)
Definition: SVFValue.h:247
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition: LLVMUtil.h:45
const Function * getCallee(const CallBase *cs)
Definition: LLVMUtil.h:63
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition: LLVMUtil.h:211
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
std::string getBeforeBrackets(const std::string &name)
Definition: CppUtil.cpp:127
const Value * getVCallThisPtr(const CallBase *cs)
Definition: CppUtil.cpp:411
struct DemangledName demangle(const std::string &name)
Definition: CppUtil.cpp:195
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition: CppUtil.cpp:601
bool isCPPThunkFunction(const Function *F)
Definition: CppUtil.cpp:383
bool isVirtualCallSite(const CallBase *cs)
Definition: CppUtil.cpp:352
const Function * getThunkTarget(const Function *F)
Definition: CppUtil.cpp:389
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
Definition: CppUtil.cpp:323
bool isConstructor(const Function *F)
Definition: CppUtil.cpp:489
std::string getClassNameFromVtblObj(const std::string &vtblName)
Definition: CppUtil.cpp:304
bool isValVtbl(const Value *val)
Definition: CppUtil.cpp:336
bool isDestructor(const Function *F)
Definition: CppUtil.cpp:509
for isBitcode
Definition: BasicTypes.h:68
llvm::const_inst_iterator const_inst_iterator
Definition: BasicTypes.h:250
llvm::GlobalAlias GlobalAlias
Definition: BasicTypes.h:128
llvm::CallBase CallBase
Definition: BasicTypes.h:146
llvm::MDString MDString
Definition: BasicTypes.h:101
llvm::ConstantStruct ConstantStruct
Definition: BasicTypes.h:106
llvm::NamedMDNode NamedMDNode
LLVM metadata and debug information.
Definition: BasicTypes.h:111
Set< const SVFGlobalValue * > VTableSet
Definition: CHG.h:44
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
llvm::Module Module
Definition: BasicTypes.h:84
llvm::StoreInst StoreInst
Definition: BasicTypes.h:148
Set< const SVFFunction * > VFunSet
Definition: CHG.h:47
llvm::MDNode MDNode
Definition: BasicTypes.h:112
unsigned u32_t
Definition: GeneralType.h:46
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96