51 using namespace SVFUtil;
52 using namespace cppUtil;
53 using namespace LLVMUtil;
68 double timeStart, timeEnd;
70 for (
Module &M : llvmModuleSet()->getLLVMModules())
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)
77 for (Module::const_iterator
F = M.begin(), E = M.end();
F != E; ++
F)
79 for (Module::const_iterator
F = M.begin(), E = M.end();
F != E; ++
F)
89 chg->buildingCHGTime = (timeEnd - timeStart) /
TIMEINTERVAL;
101 if (!chg->getNode(className))
102 createNode(className);
104 for (
unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
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)
112 const Value* bitcastValue = ce->getOperand(0);
113 if (
const Function* func = SVFUtil::dyn_cast<Function>(bitcastValue))
140 for (Function::const_iterator B =
F->begin(), E =
F->end(); B != E; ++B)
142 for (BasicBlock::const_iterator I = B->begin(), E = B->end(); I != E; ++I)
146 connectInheritEdgeViaCall(
F, SVFUtil::cast<CallBase>(&(*I)));
148 else if (
const StoreInst *store = SVFUtil::dyn_cast<StoreInst>(&(*I)))
150 connectInheritEdgeViaStore(
F, store);
160 buildClassNameToAncestorsDescendantsMap();
161 buildVirtualFunctionToIDMap();
162 buildCSToCHAVtblsAndVfnsMap();
175 if (cs->arg_size() < 1 || (cs->arg_size() < 2 && cs->paramHasAttr(0, llvm::Attribute::StructRet)))
180 bool samePtrTrue =
true;
181 if (csThisPtr !=
nullptr && samePtrTrue)
196 if (
const ConstantExpr *ce = SVFUtil::dyn_cast<ConstantExpr>(storeInst->getValueOperand()))
198 if (ce->getOpcode() == Instruction::BitCast)
200 const Value* bitcastval = ce->getOperand(0);
201 if (
const ConstantExpr *bcce = SVFUtil::dyn_cast<ConstantExpr>(bitcastval))
203 if (bcce->getOpcode() == Instruction::GetElementPtr)
205 const Value* gepval = bcce->getOperand(0);
209 if (vtblClassName.size() > 0 && dname.
className.compare(vtblClassName) != 0)
222 for (Module::const_named_metadata_iterator mdit = M.named_metadata_begin(),
223 mdeit = M.named_metadata_end(); mdit != mdeit; ++mdit)
226 string mdname = md->getName().str();
227 if (mdname.compare(0, 15,
"__cxx_bases_of_") != 0)
229 string className = mdname.substr(15);
230 for (NamedMDNode::const_op_iterator opit = md->op_begin(),
231 opeit = md->op_end(); opit != opeit; ++opit)
234 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
235 string baseName = mdstr->getString().str();
243 assert(!chg->getNode(className) &&
"this node should never be created before!");
245 chg->classNameToNodeMap[className] = node;
246 chg->addGNode(node->
getId(), node);
247 if (className.size() > 0 && className[className.size() - 1] ==
'>')
250 CHNode* templateNode = chg->getNode(templateName);
253 DBOUT(
DCHA,
outs() <<
"\t Create Template CHANode " + templateName +
" for class " + className +
"...\n");
254 templateNode = createNode(templateName);
258 chg->addInstances(templateName,node);
274 const CHNode *node = it->second;
278 while (!worklist.
empty())
281 if (visitedNodes.find(curnode) == visitedNodes.end())
283 for (CHEdge::CHEdgeSetTy::const_iterator it =
289 CHNode *succnode = (*it)->getDstNode();
290 chg->classNameToAncestorsMap[node->
getName()].insert(succnode);
291 chg->classNameToDescendantsMap[succnode->
getName()].insert(node);
292 worklist.
push(succnode);
295 visitedNodes.insert(curnode);
302 const string& className)
305 CHGraph::NameToCHNodesMap::const_iterator it = chg->classNameToInstAndDescsMap.find(className);
306 if (it != chg->classNameToInstAndDescsMap.end())
312 chg->classNameToInstAndDescsMap[className] = chg->getDescendants(className);
313 if (chg->getNode(className)->isTemplate())
315 const CHNodeSetTy& instances = chg->getInstances(className);
316 for (CHNodeSetTy::const_iterator it = instances.begin(), eit = instances.end(); it != eit; ++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)
325 chg->classNameToInstAndDescsMap[className].insert(*dit);
329 return chg->classNameToInstAndDescsMap[className];
369 for (Module::const_global_iterator I = M.global_begin(),
370 E = M.global_end(); I != E; ++I)
372 const GlobalValue *globalvalue = SVFUtil::dyn_cast<const GlobalValue>(&(*I));
378 CHNode *node = chg->getNode(vtblClassName);
379 assert(node &&
"node not found?");
382 llvmModuleSet()->getSVFGlobalValue(
384 pValue->
setName(vtblClassName);
387 for (
unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei)
390 SVFUtil::dyn_cast<ConstantArray>(vtblStruct->getOperand(ei));
391 assert(vtbl &&
"Element of initializer not an array?");
399 bool pure_abstract =
true;
401 while (i < vtbl->getNumOperands())
404 bool is_virtual =
false;
405 int null_ptr_num = 0;
406 for (; i < vtbl->getNumOperands(); ++i)
408 Constant* operand = vtbl->getOperand(i);
409 if (SVFUtil::isa<ConstantPointerNull>(operand))
411 if (i > 0 && !SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i-1)))
413 auto foo = [&is_virtual, &null_ptr_num, &vtbl, &i](
const Value* val)
419 while (i+null_ptr_num < vtbl->getNumOperands())
421 if (SVFUtil::isa<ConstantPointerNull>(vtbl->getOperand(i+null_ptr_num)))
429 SVFUtil::dyn_cast<ConstantExpr>(vtbl->getOperand(i-1)))
431 if(ce->getOpcode() == Instruction::BitCast)
432 foo(ce->getOperand(0));
437 foo(vtbl->getOperand(i - 1));
443 auto foo = [
this, &virtualFunctions, &pure_abstract, &vtblClassName](
const Value* operand)
445 if (
const Function* f = SVFUtil::dyn_cast<Function>(operand))
447 addFuncToFuncVector(virtualFunctions, f);
450 pure_abstract &=
true;
454 pure_abstract &=
false;
458 vtblClassName.compare(dname.
className) != 0)
467 SVFUtil::dyn_cast<GlobalAlias>(operand))
469 const Constant *aliasValue = alias->getAliasee();
471 SVFUtil::dyn_cast<Function>(aliasValue))
473 addFuncToFuncVector(virtualFunctions, aliasFunc);
476 SVFUtil::dyn_cast<ConstantExpr>(aliasValue))
479 assert(aliasconst->getOpcode() == Instruction::BitCast &&
480 "aliased constantexpr in vtable not a bitcast");
482 SVFUtil::dyn_cast<Function>(aliasconst->getOperand(0));
483 assert(aliasbitcastfunc &&
484 "aliased bitcast in vtable not a function");
485 addFuncToFuncVector(virtualFunctions, aliasbitcastfunc);
489 assert(
false &&
"alias not function or bitcast");
492 pure_abstract &=
false;
494 else if (operand->getName().str().compare(0,
ztiLabel.size(),
500 assert(
"what else can be in bitcast of a vtable?");
521 SVFUtil::dyn_cast<ConstantExpr>(operand))
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)
539 if (is_virtual && virtualFunctions.size() > 0)
541 for (
int i = 0; i < null_ptr_num; ++i)
544 virtualFunctions.insert(virtualFunctions.begin(), fun);
547 if (virtualFunctions.size() > 0)
550 if (pure_abstract ==
true)
570 neit = chg->end(); nit != neit; ++nit)
572 CHNode *node = nit->second;
573 if (visitedNodes.find(node) != visitedNodes.end())
576 string className = node->
getName();
582 stack<const CHNode*> nodeStack;
583 nodeStack.push(node);
584 while (!nodeStack.empty())
586 const CHNode *curnode = nodeStack.top();
588 group.insert(curnode);
589 if (visitedNodes.find(curnode) != visitedNodes.end())
591 for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->
getOutEdges().begin(),
592 eit = curnode->
getOutEdges().end(); it != eit; ++it)
594 CHNode *tmpnode = (*it)->getDstNode();
595 nodeStack.push(tmpnode);
596 group.insert(tmpnode);
598 for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->
getInEdges().begin(),
599 eit = curnode->
getInEdges().end(); it != eit; ++it)
601 CHNode *tmpnode = (*it)->getSrcNode();
602 nodeStack.push(tmpnode);
603 group.insert(tmpnode);
605 visitedNodes.insert(curnode);
611 set<const SVFFunction*> virtualFunctions;
612 for (CHGraph::CHNodeSetTy::iterator it = group.begin(),
613 eit = group.end(); it != eit; ++it)
616 for (vector<CHNode::FuncVector>::const_iterator vit = vecs.begin(),
617 veit = vecs.end(); vit != veit; ++vit)
619 for (vector<const SVFFunction*>::const_iterator fit = (*vit).begin(),
620 feit = (*vit).end(); fit != feit; ++fit)
622 virtualFunctions.insert(*fit);
642 set<pair<string, const SVFFunction*> > fNameSet;
643 for (set<const SVFFunction*>::iterator fit = virtualFunctions.begin(),
644 feit = virtualFunctions.end(); fit != feit; ++fit)
648 fNameSet.insert(pair<string, const SVFFunction*>(dname.
funcName, f));
650 for (
set<pair<string, const SVFFunction*>>::iterator it = fNameSet.begin(),
651 eit = fNameSet.end(); it != eit; ++it)
653 chg->virtualFunctionToIDMap[it->second] = chg->vfID++;
662 for (
Module &M : llvmModuleSet()->getLLVMModules())
664 for (Module::const_iterator
F = M.begin(), E = M.end();
F != E; ++
F)
668 if(
const CallBase* callInst = SVFUtil::dyn_cast<CallBase>(&*II))
674 const CHNodeSetTy& chClasses = getCSClasses(callInst);
675 for (CHNodeSetTy::const_iterator it = chClasses.begin(), eit = chClasses.end(); it != eit; ++it)
684 if (vtbls.size() > 0)
687 llvmModuleSet()->getICFGNode(callInst);
688 chg->callNodeToCHAVtblsMap[icfgNode] = vtbls;
690 chg->getVFnsFromVtbls(SVFUtil::cast<CallICFGNode>(icfgNode), vtbls, virtualFunctions);
691 if (virtualFunctions.size() > 0)
692 chg->callNodeToCHAVFnsMap[icfgNode] = virtualFunctions;
705 ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(cs);
707 CHGraph::CallNodeToCHNodesMap::const_iterator it = chg->callNodeToClassesMap.find(icfgNode);
708 if (it != chg->callNodeToClassesMap.end())
716 if(thisPtrClassNames.empty())
719 for (
const auto &node: *chg)
721 chg->callNodeToClassesMap[icfgNode].insert(node.second);
723 return chg->callNodeToClassesMap[icfgNode];
726 for (
const auto &thisPtrClassName: thisPtrClassNames)
728 if (
const CHNode* thisNode = chg->getNode(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);
736 return chg->callNodeToClassesMap[icfgNode];
747 llvmModuleSet()->getSVFFunction(tf);
748 v.push_back(pFunction);
754 llvmModuleSet()->getSVFFunction(lf);
755 v.push_back(pFunction);
const string pureVirtualFunName
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) add_llvm_executable(wpa wpa.cpp) target_link_libraries(wpa PUBLIC $
void analyzeVTables(const Module &M)
void connectInheritEdgeViaStore(const Function *caller, const StoreInst *store)
LLVMModuleSet * llvmModuleSet()
void readInheritanceMetadataFromModule(const Module &M)
void buildCHGNodes(const GlobalValue *V)
const CHGraph::CHNodeSetTy & getInstancesAndDescendants(const std::string &className)
void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f)
void buildCHGEdges(const Function *F)
void buildVirtualFunctionToIDMap()
void buildCSToCHAVtblsAndVfnsMap()
CHGraph::CHNodeSetTy CHNodeSetTy
const CHNodeSetTy & getCSClasses(const CallBase *cs)
CHNode * createNode(const std::string &name)
void connectInheritEdgeViaCall(const Function *caller, const CallBase *cs)
void buildClassNameToAncestorsDescendantsMap()
Set< const CHNode * > CHNodeSetTy
void setMultiInheritance()
const std::vector< FuncVector > & getVirtualFunctionVectors() const
void addVirtualFunctionVector(FuncVector vfuncvec)
std::vector< const SVFFunction * > FuncVector
void setVTable(const SVFGlobalValue *vtbl)
void setPureAbstract()
Attribute.
std::string getName() const
bool push(const Data &data)
IDToNodeMapTy::const_iterator const_iterator
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
static LLVMModuleSet * getLLVMModuleSet()
static const Option< bool > DumpCHA
NodeID getId() const
Get ID.
static double getClk(bool mark=false)
const std::string & getName() const
void setName(const std::string &n)
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
const Function * getCallee(const CallBase *cs)
const ConstantExpr * isCastConstantExpr(const Value *val)
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
std::ostream & outs()
Overwrite llvm::outs()
std::string getBeforeBrackets(const std::string &name)
const Value * getVCallThisPtr(const CallBase *cs)
struct DemangledName demangle(const std::string &name)
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
bool isCPPThunkFunction(const Function *F)
bool isVirtualCallSite(const CallBase *cs)
const Function * getThunkTarget(const Function *F)
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
bool isConstructor(const Function *F)
std::string getClassNameFromVtblObj(const std::string &vtblName)
bool isValVtbl(const Value *val)
bool isDestructor(const Function *F)
llvm::const_inst_iterator const_inst_iterator
llvm::GlobalAlias GlobalAlias
llvm::ConstantStruct ConstantStruct
llvm::NamedMDNode NamedMDNode
LLVM metadata and debug information.
Set< const SVFGlobalValue * > VTableSet
llvm::ConstantArray ConstantArray
llvm::GlobalValue GlobalValue
llvm::Value Value
LLVM Basic classes.
llvm::ConstantExpr ConstantExpr
llvm::StoreInst StoreInst
Set< const SVFFunction * > VFunSet
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set