20 using namespace SVFUtil;
23 llvm::cl::desc(
"ExternalPAGs to use during PAG construction (format: func1@/path/to/graph,func2@/foo,..."),
24 llvm::cl::CommaSeparated);
27 llvm::cl::desc(
"Dump PAG for functions"),
28 llvm::cl::CommaSeparated);
35 std::vector<std::pair<std::string, std::string>>
38 std::vector<std::pair<std::string, std::string>> parsedExternalPAGs;
39 for (
auto arg = extpagsArgs.begin(); arg != extpagsArgs.end();
42 std::stringstream ss(*arg);
43 std::string functionName;
44 getline(ss, functionName,
'@');
47 parsedExternalPAGs.push_back(
48 std::pair<std::string, std::string>(functionName, path));
51 return parsedExternalPAGs;
56 std::vector<std::pair<std::string, std::string>> parsedExternalPAGs
60 for (
auto extpagPair= parsedExternalPAGs.begin();
61 extpagPair != parsedExternalPAGs.end(); ++extpagPair)
63 std::string fname = extpagPair->first;
64 std::string path = extpagPair->second;
77 std::string functionName =
function->getName().str();
80 if (!hasExternalPAG(svfFun))
return false;
83 functionToExternalPAGEntries[svfFun];
84 PAGNode *retNode = functionToExternalPAGReturns[svfFun];
87 if (llvm::isa<PointerType>(cs->
getType()))
91 if (SVFUtil::isa<PointerType>(function->getReturnType()))
93 if (retNode !=
nullptr)
109 Function::const_arg_iterator itF =
function->arg_begin(),
110 ieF =
function->arg_end();
112 size_t formalNodeIndex = 0;
114 for (; itF != ieF ; ++itA, ++itF, ++formalNodeIndex)
124 PAGNode *formalArgNode = argNodes[formalNodeIndex];
128 if (!SVFUtil::isa<PointerType>(formalArg->getType()))
continue;
130 if (SVFUtil::isa<PointerType>((*itA)->getType()))
133 pag->
addCallPE(actualArgNodeId, formalArgNode->
getId(), icfgNode);
139 assert(
false &&
"you need to set the current location of this PAGEdge");
150 bool ret = functionToExternalPAGEntries.find(
function)
151 != functionToExternalPAGEntries.end();
158 for (
auto it = function->getLLVMFun()->arg_begin(); it !=
function->getLLVMFun()->arg_end();
161 if (arg->getName() == it->getName())
return argNo;
169 o << pagNode->
getId() <<
" ";
201 std::string edgeKind =
"-";
227 edgeKind =
"variant-gep";
233 edgeKind =
"binary-op";
236 edgeKind =
"unary-op";
239 outs() <<
"dump-function-pags: found ThreadFork edge.\n";
242 outs() <<
"dump-function-pags: found ThreadJoin edge.\n";
249 o << srcId <<
" " << edgeKind <<
" " << dstId <<
" " << offset <<
"\n";
266 PAGNode *currNode = it->second;
270 for (PAGEdge::PAGEdgeSetTy::iterator it =
277 static_cast<const CallInst *
>(inst)->getCalledFunction();
279 if (currFunction !=
nullptr)
282 std::string currFunctionName = currFunction->getName().str();
284 if (std::find(functions.begin(), functions.end(),
285 currFunctionName) != functions.end())
289 if (callDsts.find(callEdge->
getDstNode()) == callDsts.end())
293 functionToPAGNodes[svfFun].push_back(callEdge->
getDstNode());
300 for (
auto it = functionToPAGNodes.begin(); it != functionToPAGNodes.end();
304 std::string functionName = it->first->
getName().str();
310 std::stack<PAGNode *> todoNodes;
312 std::vector<PAGNode *> argNodes = it->second;
316 outs() <<
"PAG for function: " << functionName <<
"\n";
317 for (
auto node = argNodes.begin(); node != argNodes.end(); ++node)
319 todoNodes.push(*node);
322 while (!todoNodes.empty())
324 PAGNode *currNode = todoNodes.top();
328 if (nodes.find(currNode) != nodes.end())
continue;
329 nodes.insert(currNode);
339 for (
auto outEdge = outEdges.begin(); outEdge != outEdges.end();
342 edges.insert(*outEdge);
343 todoNodes.push((*outEdge)->getDstNode());
347 for (
auto node = nodes.begin(); node != nodes.end(); ++node)
351 if (std::find(argNodes.begin(), argNodes.end(), *node)
355 getArgNo(
function, (*node)->getValue()));
357 else if (*node == retNode)
367 for (
auto edge = edges.begin(); edge != edges.end(); ++edge)
373 outs() <<
"PAG for functionName " << functionName <<
" done\n";
381 if (
function ==
nullptr)
return false;
384 if (hasExternalPAG(
function))
return false;
386 outs() <<
"Adding extpag " << this->getFunctionName() <<
"\n";
401 for (
auto extNodeIt = this->getValueNodes().begin();
402 extNodeIt != this->getValueNodes().end(); ++extNodeIt)
405 extToNewNodes[*extNodeIt] = pag->
getPAGNode(newNodeId);
409 for (
auto extNodeIt = this->getObjectNodes().begin();
410 extNodeIt != this->getObjectNodes().end(); ++extNodeIt)
414 extToNewNodes[*extNodeIt] = pag->
getPAGNode(newNodeId);
418 for (
auto extEdgeIt = this->getEdges().begin();
419 extEdgeIt != this->getEdges().end(); ++extEdgeIt)
421 NodeID extSrcId = std::get<0>(*extEdgeIt);
422 NodeID extDstId = std::get<1>(*extEdgeIt);
423 std::string extEdgeType = std::get<2>(*extEdgeIt);
424 int extOffsetOrCSId = std::get<3>(*extEdgeIt);
426 PAGNode *srcNode = extToNewNodes[extSrcId];
427 PAGNode *dstNode = extToNewNodes[extDstId];
431 if (extEdgeType ==
"addr")
435 else if (extEdgeType ==
"copy")
439 else if (extEdgeType ==
"load")
443 else if (extEdgeType ==
"store")
447 else if (extEdgeType ==
"gep")
451 else if (extEdgeType ==
"variant-gep")
455 else if (extEdgeType ==
"call")
457 pag->
addEdge(srcNode, dstNode,
new CallPE(srcNode, dstNode,
nullptr));
459 else if (extEdgeType ==
"ret")
461 pag->
addEdge(srcNode, dstNode,
new RetPE(srcNode, dstNode,
nullptr));
463 else if (extEdgeType ==
"cmp")
467 else if (extEdgeType ==
"binary-op")
471 else if (extEdgeType ==
"unary-op")
477 outs() <<
"Bad edge type found during extpag addition\n";
483 for (
auto argNodeIt = this->getArgNodes().begin();
484 argNodeIt != this->getArgNodes().end(); ++argNodeIt)
486 int index = argNodeIt->first;
487 NodeID extNodeId = argNodeIt->second;
488 argNodes[index] = extToNewNodes[extNodeId];
491 functionToExternalPAGEntries[
function] = argNodes;
494 if (this->hasReturnNode())
496 functionToExternalPAGReturns[
function] =
497 extToNewNodes[this->getReturnNode()];
510 std::ifstream pagFile(filename.c_str());
512 if (!pagFile.is_open())
514 outs() <<
"ExternalPAG::buildFromFile: could not open " << filename
519 while (pagFile.good())
521 std::getline(pagFile, line);
525 std::istringstream ss(line);
538 if (tokenCount == 2 || tokenCount == 3)
542 std::string nodeType;
543 std::istringstream ss(line);
549 valueNodes.insert(nodeId);
551 else if (nodeType ==
"o")
553 objectNodes.insert(nodeId);
558 &&
"format not supported, please specify node type");
565 std::string argNoOrRet;
568 if (argNoOrRet ==
"ret")
570 setReturnNode(nodeId);
572 else if (std::all_of(argNoOrRet.begin(), argNoOrRet.end(),
575 int argNo = std::stoi(argNoOrRet);
576 argNodes[argNo] = nodeId;
581 &&
"format not supported, not arg number or ret");
586 else if (tokenCount == 4)
593 std::istringstream ss(line);
600 std::tuple<NodeID, NodeID, std::string, int>(nodeSrc, nodeDst,
608 outs() <<
"format not supported, token count = " 609 << tokenCount <<
"\n";
610 assert(
false &&
"format not supported");
llvm::cl::list< std::string > ExternalPAGArgs("extpags", llvm::cl::desc("ExternalPAGs to use during PAG construction (format: func1@/path/to/graph,func2@/foo,..."), llvm::cl::CommaSeparated)
iterator begin()
Iterators.
static Map< const SVFFunction *, Map< int, PAGNode * > > functionToExternalPAGEntries
GEdgeKind getEdgeKind() const
NodeID getValueNode(const Value *V)
Get PAG Node according to LLVM value.
ICFG * getICFG()
Return ICFG.
llvm::raw_ostream raw_ostream
LLVM outputs.
CallPE * addCallPE(NodeID src, NodeID dst, const CallBlockNode *cs)
Add Call edge.
BinaryOPPE * addBinaryOPPE(NodeID src, NodeID dst)
Add Copy edge.
bool addEdge(PAGNode *src, PAGNode *dst, PAGEdge *edge)
Add an edge into PAG.
CallBlockNode * getCallBlockNode(const Instruction *inst)
NodeID getSrcID() const
get methods of the components
static void outputPAGNodeNoNewLine(raw_ostream &o, PAGNode *pagNode)
NodeID addDummyValNode()
Add a dummy value/object node according to node ID (llvm value is null)
CallBase * getInstruction() const
const llvm::StringRef getName() const
static void outputPAGEdge(raw_ostream &o, PAGEdge *pagEdge)
bool hasOutgoingEdges(PAGEdge::PEDGEK kind) const
Has outgoing PAG edges.
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
User::const_op_iterator arg_end() const
static bool hasExternalPAG(const SVFFunction *function)
Whether an external PAG implementing function exists.
NodeID addDummyObjNode(const Type *type=nullptr)
static PAG * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis. ...
PAGEdge * addBlackHoleAddrPE(NodeID node)
Set a pointer points-to black hole (e.g. int2ptr)
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
IDToNodeMapTy::iterator iterator
Node Iterators.
static bool classof(const RetPN *)
NodeType * getDstNode() const
static std::string pagFileName()
llvm::cl::list< std::string > DumpPAGFunctions("dump-function-pags", llvm::cl::desc("Dump PAG for functions"), llvm::cl::CommaSeparated)
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
llvm::Instruction Instruction
AddrPE * addAddrPE(NodeID src, NodeID dst)
Add Address edge.
const GEdgeSetTy & getOutEdges() const
static void initialise(SVFModule *svfModule)
User::const_op_iterator arg_begin() const
static Map< const SVFFunction *, PAGNode * > functionToExternalPAGReturns
CopyPE * addCopyPE(NodeID src, NodeID dst)
Add Copy edge.
NormalGepPE * addNormalGepPE(NodeID src, NodeID dst, const LocationSet &ls)
Add Offset(Gep) edge.
static bool classof(const ObjPN *)
Methods for support type inquiry through isa, cast, and dyn_cast:
VariantGepPE * addVariantGepPE(NodeID src, NodeID dst)
Add Variant(Gep) edge.
CmpPE * addCmpPE(NodeID src, NodeID dst)
Add Copy edge.
raw_ostream & outs()
Overwrite llvm::outs()
const CallBlockNode * getCallInst() const
Get method for the call instruction.
RetPE * addRetPE(NodeID src, NodeID dst, const CallBlockNode *cs)
Add Return edge.
static void outputPAGNode(raw_ostream &o, PAGNode *pagNode)
PAGEdge::PAGEdgeSetTy::iterator getOutgoingEdgesBegin(PAGEdge::PEDGEK kind) const
Get outgoing PAGEdge iterator.
Function * getCalledFunction() const
static LLVMModuleSet * getLLVMModuleSet()
const Instruction * getCallSite() const
Return callsite.
NodeID getId() const
Get ID.
const SVFFunction * getFunction(StringRef name)
Get the corresponding Function based on its name.
StorePE * addStorePE(NodeID src, NodeID dst, const IntraBlockNode *val)
Add Store edge.
static void dumpFunctions(std::vector< std::string > functions)
Dump individual PAGs of specified functions. Currently to outs().
User::const_op_iterator arg_iterator
static std::vector< std::pair< std::string, std::string > > parseExternalPAGs(llvm::cl::list< std::string > &extpagsArgs)
static void setPagFromTXT(std::string txt)
LoadPE * addLoadPE(NodeID src, NodeID dst)
Add Load edge.
void readFromFile(std::string filename)
UnaryOPPE * addUnaryOPPE(NodeID src, NodeID dst)
Add Unary edge.
bool addExternalPAG(const SVFFunction *function)
const SVFFunction * getSVFFunction(const Function *fun) const
int getArgNo(const SVFFunction *function, const Value *arg)
PAGEdge::PAGEdgeSetTy::iterator getOutgoingEdgesEnd(PAGEdge::PEDGEK kind) const
Get outgoing PAGEdge iterator.
static bool classof(const NormalGepPE *)
Methods for support type inquiry through isa, cast, and dyn_cast:
static bool connectCallsiteToExternalPAG(CallSite *cs)