SVF
PAGBuilder.cpp
Go to the documentation of this file.
1 //===- PAGBuilder.cpp -- PAG builder-----------------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2017> <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 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 General Public License for more details.
17 
18 // You should have received a copy of the GNU General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * PAGBuilder.cpp
25  *
26  * Created on: Nov 1, 2013
27  * Author: Yulei Sui
28  */
29 
30 #include "SVF-FE/PAGBuilder.h"
31 #include "Util/SVFModule.h"
32 #include "Util/SVFUtil.h"
33 #include "SVF-FE/LLVMUtil.h"
34 #include "SVF-FE/CPPUtil.h"
35 #include "Graphs/ExternalPAG.h"
36 #include "Util/BasicTypes.h"
38 
39 using namespace std;
40 using namespace SVF;
41 using namespace SVFUtil;
42 
43 
47 PAG* PAGBuilder::build(SVFModule* svfModule)
48 {
49 
50  // We read PAG from a user-defined txt instead of parsing PAG from LLVM IR
51  if (SVFModule::pagReadFromTXT())
52  {
53  PAGBuilderFromFile fileBuilder(SVFModule::pagFileName());
54  return fileBuilder.build();
55  }
56 
57  // If the PAG has been built before, then we return the unique PAG of the program
58  if(pag->getNodeNumAfterPAGBuild() > 1)
59  return pag;
60 
61  svfMod = svfModule;
62 
65  initialiseNodes();
68  visitGlobal(svfModule);
70 
71  ExternalPAG::initialise(svfModule);
72 
74  for (SVFModule::iterator fit = svfModule->begin(), efit = svfModule->end();
75  fit != efit; ++fit)
76  {
77  const SVFFunction& fun = **fit;
79  if(!SVFUtil::isExtCall(&fun))
80  {
86  if(fun.getLLVMFun()->doesNotReturn() == false && fun.getLLVMFun()->getReturnType()->isVoidTy() == false)
87  pag->addFunRet(&fun,pag->getPAGNode(pag->getReturnNode(&fun)));
88 
91  for (Function::arg_iterator I = fun.getLLVMFun()->arg_begin(), E = fun.getLLVMFun()->arg_end();
92  I != E; ++I) {
93  setCurrentLocation(&*I,&fun.getLLVMFun()->getEntryBlock());
94  NodeID argValNodeId = pag->getValueNode(&*I);
95  // if this is the function does not have caller (e.g. main)
96  // or a dead function, shall we create a black hole address edge for it?
97  // it is (1) too conservative, and (2) make FormalParmVFGNode defined at blackhole address PAGEdge.
98  // if(SVFUtil::ArgInNoCallerFunction(&*I)) {
99  // if(I->getType()->isPointerTy())
100  // addBlackHoleAddrEdge(argValNodeId);
101  //}
102  pag->addFunArgs(&fun,pag->getPAGNode(argValNodeId));
103  }
104  }
105  for (Function::iterator bit = fun.getLLVMFun()->begin(), ebit = fun.getLLVMFun()->end();
106  bit != ebit; ++bit)
107  {
108  BasicBlock& bb = *bit;
109  for (BasicBlock::iterator it = bb.begin(), eit = bb.end();
110  it != eit; ++it)
111  {
112  Instruction& inst = *it;
113  setCurrentLocation(&inst,&bb);
114  visit(inst);
115  }
116  }
117  }
118 
119  sanityCheck();
120 
121  pag->initialiseCandidatePointers();
122 
123  pag->setNodeNumAfterPAGBuild(pag->getTotalNodeNum());
124 
125  return pag;
126 }
127 
128 /*
129  * Initial all the nodes from symbol table
130  */
131 void PAGBuilder::initialiseNodes()
132 {
133  DBOUT(DPAGBuild, outs() << "Initialise PAG Nodes ...\n");
134 
135  SymbolTableInfo* symTable = SymbolTableInfo::SymbolInfo();
136 
137  pag->addBlackholeObjNode();
138  pag->addConstantObjNode();
139  pag->addBlackholePtrNode();
140  addNullPtrNode();
141 
142  for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
143  symTable->valSyms().begin(); iter != symTable->valSyms().end();
144  ++iter)
145  {
146  DBOUT(DPAGBuild, outs() << "add val node " << iter->second << "\n");
147  if(iter->second == symTable->blkPtrSymID() || iter->second == symTable->nullPtrSymID())
148  continue;
149  pag->addValNode(iter->first, iter->second);
150  }
151 
152  for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
153  symTable->objSyms().begin(); iter != symTable->objSyms().end();
154  ++iter)
155  {
156  DBOUT(DPAGBuild, outs() << "add obj node " << iter->second << "\n");
157  if(iter->second == symTable->blackholeSymID() || iter->second == symTable->constantSymID())
158  continue;
159  pag->addObjNode(iter->first, iter->second);
160  }
161 
162  for (SymbolTableInfo::FunToIDMapTy::iterator iter =
163  symTable->retSyms().begin(); iter != symTable->retSyms().end();
164  ++iter)
165  {
166  DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n");
167  const SVFFunction* fun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(iter->first);
168  pag->addRetNode(fun, iter->second);
169  }
170 
171  for (SymbolTableInfo::FunToIDMapTy::iterator iter =
172  symTable->varargSyms().begin();
173  iter != symTable->varargSyms().end(); ++iter)
174  {
175  DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n");
176  const SVFFunction* fun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(iter->first);
177  pag->addVarargNode(fun, iter->second);
178  }
179 
181  for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
182  symTable->objSyms().begin(); iter != symTable->objSyms().end(); ++iter)
183  {
184  DBOUT(DPAGBuild, outs() << "add address edges for constant node " << iter->second << "\n");
185  const Value* val = iter->first;
186  if (symTable->isConstantObjSym(val))
187  {
188  NodeID ptr = pag->getValueNode(val);
189  if(ptr!= pag->getBlkPtr() && ptr!= pag->getNullPtr())
190  {
191  setCurrentLocation(val, nullptr);
192  addAddrEdge(iter->second, ptr);
193  }
194  }
195  }
196 
197  assert(pag->getTotalNodeNum() >= symTable->getTotalSymNum()
198  && "not all node been inititalize!!!");
199 
200 }
201 
208 bool PAGBuilder::computeGepOffset(const User *V, LocationSet& ls)
209 {
210  return SymbolTableInfo::SymbolInfo()->computeGepOffset(V,ls);
211 }
212 
216 void PAGBuilder::processCE(const Value *val)
217 {
218  if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
219  {
220  if (const ConstantExpr* gepce = isGepConstantExpr(ref))
221  {
223  outs() << "handle gep constant expression " << *ref << "\n");
224  const Constant* opnd = gepce->getOperand(0);
225  // handle recursive constant express case (gep (bitcast (gep X 1)) 1)
226  processCE(opnd);
227  LocationSet ls;
228  bool constGep = computeGepOffset(gepce, ls);
229  // must invoke pag methods here, otherwise it will be a dead recursion cycle
230  const Value* cval = getCurrentValue();
231  const BasicBlock* cbb = getCurrentBB();
232  setCurrentLocation(gepce, nullptr);
233  /*
234  * The gep edge created are like constexpr (same edge may appear at multiple callsites)
235  * so bb/inst of this edge may be rewritten several times, we treat it as global here.
236  */
237  addGepEdge(pag->getValueNode(opnd), pag->getValueNode(gepce), ls, constGep);
238  setCurrentLocation(cval, cbb);
239  }
240  else if (const ConstantExpr* castce = isCastConstantExpr(ref))
241  {
243  outs() << "handle cast constant expression " << *ref << "\n");
244  const Constant* opnd = castce->getOperand(0);
245  processCE(opnd);
246  const Value* cval = getCurrentValue();
247  const BasicBlock* cbb = getCurrentBB();
248  setCurrentLocation(castce, nullptr);
249  addCopyEdge(pag->getValueNode(opnd), pag->getValueNode(castce));
250  setCurrentLocation(cval, cbb);
251  }
252  else if (const ConstantExpr* selectce = isSelectConstantExpr(ref))
253  {
255  outs() << "handle select constant expression " << *ref << "\n");
256  const Constant* src1 = selectce->getOperand(1);
257  const Constant* src2 = selectce->getOperand(2);
258  processCE(src1);
259  processCE(src2);
260  const Value* cval = getCurrentValue();
261  const BasicBlock* cbb = getCurrentBB();
262  setCurrentLocation(selectce, nullptr);
263  NodeID nsrc1 = pag->getValueNode(src1);
264  NodeID nsrc2 = pag->getValueNode(src2);
265  NodeID nres = pag->getValueNode(selectce);
266  const CopyPE* cpy1 = addCopyEdge(nsrc1, nres);
267  const CopyPE* cpy2 = addCopyEdge(nsrc2, nres);
268  pag->addPhiNode(pag->getPAGNode(nres),cpy1);
269  pag->addPhiNode(pag->getPAGNode(nres),cpy2);
270  setCurrentLocation(cval, cbb);
271  }
272  // if we meet a int2ptr, then it points-to black hole
273  else if (const ConstantExpr* int2Ptrce = isInt2PtrConstantExpr(ref))
274  {
275  addGlobalBlackHoleAddrEdge(pag->getValueNode(int2Ptrce), int2Ptrce);
276  }
277  else if (const ConstantExpr* ptr2Intce = isPtr2IntConstantExpr(ref))
278  {
279  const Constant* opnd = ptr2Intce->getOperand(0);
280  processCE(opnd);
281  const BasicBlock* cbb = getCurrentBB();
282  const Value* cval = getCurrentValue();
283  setCurrentLocation(ptr2Intce, nullptr);
284  addCopyEdge(pag->getValueNode(opnd), pag->getValueNode(ptr2Intce));
285  setCurrentLocation(cval, cbb);
286  }
287  else if(isTruncConstantExpr(ref) || isCmpConstantExpr(ref))
288  {
289  // we don't handle trunc and cmp instruction for now
290  const Value* cval = getCurrentValue();
291  const BasicBlock* cbb = getCurrentBB();
292  setCurrentLocation(ref, nullptr);
293  NodeID dst = pag->getValueNode(ref);
294  addBlackHoleAddrEdge(dst);
295  setCurrentLocation(cval, cbb);
296  }
297  else if (isBinaryConstantExpr(ref))
298  {
299  // we don't handle binary constant expression like add(x,y) now
300  const Value* cval = getCurrentValue();
301  const BasicBlock* cbb = getCurrentBB();
302  setCurrentLocation(ref, nullptr);
303  NodeID dst = pag->getValueNode(ref);
304  addBlackHoleAddrEdge(dst);
305  setCurrentLocation(cval, cbb);
306  }
307  else if (isUnaryConstantExpr(ref))
308  {
309  // we don't handle unary constant expression like fneg(x) now
310  const Value* cval = getCurrentValue();
311  const BasicBlock* cbb = getCurrentBB();
312  setCurrentLocation(ref, nullptr);
313  NodeID dst = pag->getValueNode(ref);
314  addBlackHoleAddrEdge(dst);
315  setCurrentLocation(cval, cbb);
316  }
317  else if (SVFUtil::isa<ConstantAggregate>(ref))
318  {
319  // we don't handle constant agrgregate like constant vectors
320  }
321  else if (SVFUtil::isa<BlockAddress>(ref))
322  {
323  // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
324  // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and PAGBuilder.cpp:183-194
325  const Value *cval = getCurrentValue();
326  const BasicBlock *cbb = getCurrentBB();
327  setCurrentLocation(ref, nullptr);
328  NodeID dst = pag->getValueNode(ref);
329  addAddrEdge(pag->getConstantNode(), dst);
330  setCurrentLocation(cval, cbb);
331  }
332  else
333  {
334  if(SVFUtil::isa<ConstantExpr>(val))
335  assert(false && "we don't handle all other constant expression for now!");
336  }
337  }
338 }
344 NodeID PAGBuilder::getGlobalVarField(const GlobalVariable *gvar, u32_t offset)
345 {
346 
347  // if the global variable do not have any field needs to be initialized
348  if (offset == 0 && gvar->getInitializer()->getType()->isSingleValueType())
349  {
350  return getValueNode(gvar);
351  }
354  else
355  {
356  const Type *gvartype = gvar->getType();
357  while (const PointerType *ptype = SVFUtil::dyn_cast<PointerType>(gvartype))
358  gvartype = ptype->getElementType();
359  return getGepValNode(gvar, LocationSet(offset), gvartype, offset);
360  }
361 }
362 
363 /*For global variable initialization
364  * Give a simple global variable
365  * int x = 10; // store 10 x (constant, non pointer) |
366  * int *y = &x; // store x y (pointer type)
367  * Given a struct
368  * struct Z { int s; int *t;};
369  * Global initialization:
370  * struct Z z = {10,&x}; // store x z.t (struct type)
371  * struct Z *m = &z; // store z m (pointer type)
372  * struct Z n = {10,&z.s}; // store z.s n , &z.s constant expression (constant expression)
373  */
374 void PAGBuilder::InitialGlobal(const GlobalVariable *gvar, Constant *C,
375  u32_t offset)
376 {
378  outs() << "global " << *gvar << " constant initializer: " << *C
379  << "\n");
380 
381  if (C->getType()->isSingleValueType())
382  {
383  NodeID src = getValueNode(C);
384  // get the field value if it is avaiable, otherwise we create a dummy field node.
385  setCurrentLocation(gvar, nullptr);
386  NodeID field = getGlobalVarField(gvar, offset);
387 
388  if (SVFUtil::isa<GlobalVariable>(C) || SVFUtil::isa<Function>(C))
389  {
390  setCurrentLocation(C, nullptr);
391  addStoreEdge(src, field);
392  }
393  else if (SVFUtil::isa<ConstantExpr>(C))
394  {
395  // add gep edge of C1 itself is a constant expression
396  processCE(C);
397  setCurrentLocation(C, nullptr);
398  addStoreEdge(src, field);
399  }
400  else if (SVFUtil::isa<BlockAddress>(C))
401  {
402  // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
403  // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and PAGBuilder.cpp:183-194
404  processCE(C);
405  setCurrentLocation(C, nullptr);
406  addAddrEdge(pag->getConstantNode(), src);
407  }
408  else
409  {
410  setCurrentLocation(C, nullptr);
411  addStoreEdge(src, field);
413  if (C->getType()->isPtrOrPtrVectorTy() && src != pag->getNullPtr())
414  addCopyEdge(pag->getNullPtr(), src);
415  }
416  }
417  else if (SVFUtil::isa<ConstantArray>(C))
418  {
419  if (cppUtil::isValVtbl(gvar) == false)
420  for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
421  InitialGlobal(gvar, SVFUtil::cast<Constant>(C->getOperand(i)), offset);
422 
423  }
424  else if (SVFUtil::isa<ConstantStruct>(C))
425  {
426  const StructType *sty = SVFUtil::cast<StructType>(C->getType());
427  const std::vector<u32_t>& offsetvect =
428  SymbolTableInfo::SymbolInfo()->getFattenFieldIdxVec(sty);
429  for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
430  {
431  u32_t off = offsetvect[i];
432  InitialGlobal(gvar, SVFUtil::cast<Constant>(C->getOperand(i)), offset + off);
433  }
434 
435  }
436  else
437  {
438  //TODO:assert(false,"what else do we have");
439  }
440 }
441 
445 void PAGBuilder::visitGlobal(SVFModule* svfModule)
446 {
447 
449  for (SVFModule::global_iterator I = svfModule->global_begin(), E =
450  svfModule->global_end(); I != E; ++I)
451  {
452  GlobalVariable *gvar = *I;
453  NodeID idx = getValueNode(gvar);
454  NodeID obj = getObjectNode(gvar);
455 
456  setCurrentLocation(gvar, nullptr);
457  addAddrEdge(obj, idx);
458 
459  if (gvar->hasInitializer())
460  {
461  Constant *C = gvar->getInitializer();
462  DBOUT(DPAGBuild, outs() << "add global var node " << *gvar << "\n");
463  InitialGlobal(gvar, C, 0);
464  }
465  }
466 
468  for (SVFModule::llvm_const_iterator I = svfModule->llvmFunBegin(), E =
469  svfModule->llvmFunEnd(); I != E; ++I)
470  {
471  const Function *fun = *I;
472  NodeID idx = getValueNode(fun);
473  NodeID obj = getObjectNode(fun);
474 
475  DBOUT(DPAGBuild, outs() << "add global function node " << fun->getName() << "\n");
476  setCurrentLocation(fun, nullptr);
477  addAddrEdge(obj, idx);
478  }
479 
480  // Handle global aliases (due to linkage of multiple bc files), e.g., @x = internal alias @y. We need to add a copy from y to x.
481  for (SVFModule::alias_iterator I = svfModule->alias_begin(), E = svfModule->alias_end(); I != E; I++)
482  {
483  NodeID dst = pag->getValueNode(*I);
484  NodeID src = pag->getValueNode((*I)->getAliasee());
485  processCE((*I)->getAliasee());
486  setCurrentLocation(*I, nullptr);
487  addCopyEdge(src,dst);
488  }
489 }
490 
495 void PAGBuilder::visitAllocaInst(AllocaInst &inst)
496 {
497 
498  // AllocaInst should always be a pointer type
499  assert(SVFUtil::isa<PointerType>(inst.getType()));
500 
501  DBOUT(DPAGBuild, outs() << "process alloca " << inst << " \n");
502  NodeID dst = getValueNode(&inst);
503 
504  NodeID src = getObjectNode(&inst);
505 
506  addAddrEdge(src, dst);
507 
508 }
509 
513 void PAGBuilder::visitPHINode(PHINode &inst)
514 {
515 
516  DBOUT(DPAGBuild, outs() << "process phi " << inst << " \n");
517 
518  NodeID dst = getValueNode(&inst);
519 
520  for (Size_t i = 0; i < inst.getNumIncomingValues(); ++i)
521  {
522  const Value* val = inst.getIncomingValue(i);
523  const Instruction* incomingInst = SVFUtil::dyn_cast<Instruction>(val);
524  assert((incomingInst==nullptr) || (incomingInst->getFunction() == inst.getFunction()));
525 
526  NodeID src = getValueNode(val);
527  const CopyPE* copy = addCopyEdge(src, dst);
528  pag->addPhiNode(pag->getPAGNode(dst), copy);
529  }
530 }
531 
532 /*
533  * Visit load instructions
534  */
535 void PAGBuilder::visitLoadInst(LoadInst &inst)
536 {
537  DBOUT(DPAGBuild, outs() << "process load " << inst << " \n");
538 
539  NodeID dst = getValueNode(&inst);
540 
541  NodeID src = getValueNode(inst.getPointerOperand());
542 
543  addLoadEdge(src, dst);
544 }
545 
549 void PAGBuilder::visitStoreInst(StoreInst &inst)
550 {
551  // StoreInst itself should always not be a pointer type
552  assert(!SVFUtil::isa<PointerType>(inst.getType()));
553 
554  DBOUT(DPAGBuild, outs() << "process store " << inst << " \n");
555 
556  NodeID dst = getValueNode(inst.getPointerOperand());
557 
558  NodeID src = getValueNode(inst.getValueOperand());
559 
560  addStoreEdge(src, dst);
561 
562 }
563 
567 void PAGBuilder::visitGetElementPtrInst(GetElementPtrInst &inst)
568 {
569 
570  NodeID dst = getValueNode(&inst);
571  // GetElementPtrInst should always be a pointer or a vector contains pointers
572  // for now we don't handle vector type here
573  if(SVFUtil::isa<VectorType>(inst.getType()))
574  {
575  addBlackHoleAddrEdge(dst);
576  return;
577  }
578 
579  assert(SVFUtil::isa<PointerType>(inst.getType()));
580 
581  DBOUT(DPAGBuild, outs() << "process gep " << inst << " \n");
582 
583  NodeID src = getValueNode(inst.getPointerOperand());
584 
585  LocationSet ls;
586  bool constGep = computeGepOffset(&inst, ls);
587  addGepEdge(src, dst, ls, constGep);
588 }
589 
590 /*
591  * Visit cast instructions
592  */
593 void PAGBuilder::visitCastInst(CastInst &inst)
594 {
595 
596  DBOUT(DPAGBuild, outs() << "process cast " << inst << " \n");
597  NodeID dst = getValueNode(&inst);
598 
599  if (SVFUtil::isa<IntToPtrInst>(&inst))
600  {
601  addBlackHoleAddrEdge(dst);
602  }
603  else
604  {
605  Value * opnd = inst.getOperand(0);
606  if (!SVFUtil::isa<PointerType>(opnd->getType()))
607  opnd = stripAllCasts(opnd);
608 
609  NodeID src = getValueNode(opnd);
610  addCopyEdge(src, dst);
611  }
612 }
613 
617 void PAGBuilder::visitBinaryOperator(BinaryOperator &inst)
618 {
619  NodeID dst = getValueNode(&inst);
620  for (u32_t i = 0; i < inst.getNumOperands(); i++)
621  {
622  Value* opnd = inst.getOperand(i);
623  NodeID src = getValueNode(opnd);
624  const BinaryOPPE* binayPE = addBinaryOPEdge(src, dst);
625  pag->addBinaryNode(pag->getPAGNode(dst),binayPE);
626  }
627 }
628 
632 void PAGBuilder::visitUnaryOperator(UnaryOperator &inst)
633 {
634  NodeID dst = getValueNode(&inst);
635  for (u32_t i = 0; i < inst.getNumOperands(); i++)
636  {
637  Value* opnd = inst.getOperand(i);
638  NodeID src = getValueNode(opnd);
639  const UnaryOPPE* unaryPE = addUnaryOPEdge(src, dst);
640  pag->addUnaryNode(pag->getPAGNode(dst),unaryPE);
641  }
642 }
643 
647 void PAGBuilder::visitCmpInst(CmpInst &inst)
648 {
649  NodeID dst = getValueNode(&inst);
650  for (u32_t i = 0; i < inst.getNumOperands(); i++)
651  {
652  Value* opnd = inst.getOperand(i);
653  NodeID src = getValueNode(opnd);
654  const CmpPE* cmpPE = addCmpEdge(src, dst);
655  pag->addCmpNode(pag->getPAGNode(dst),cmpPE);
656  }
657 }
658 
659 
663 void PAGBuilder::visitSelectInst(SelectInst &inst)
664 {
665 
666  DBOUT(DPAGBuild, outs() << "process select " << inst << " \n");
667 
668  NodeID dst = getValueNode(&inst);
669  NodeID src1 = getValueNode(inst.getTrueValue());
670  NodeID src2 = getValueNode(inst.getFalseValue());
671  const CopyPE* cpy1 = addCopyEdge(src1, dst);
672  const CopyPE* cpy2 = addCopyEdge(src2, dst);
673 
675  pag->addPhiNode(pag->getPAGNode(dst), cpy1);
676  pag->addPhiNode(pag->getPAGNode(dst), cpy2);
677 }
678 
679 /*
680  * Visit callsites
681  */
682 void PAGBuilder::visitCallSite(CallSite cs)
683 {
684 
685  // skip llvm intrinsics
687  return;
688 
690  outs() << "process callsite " << *cs.getInstruction() << "\n");
691 
692  CallBlockNode* callBlockNode = pag->getICFG()->getCallBlockNode(cs.getInstruction());
693  RetBlockNode* retBlockNode = pag->getICFG()->getRetBlockNode(cs.getInstruction());
694 
695  pag->addCallSite(callBlockNode);
696 
698  for(CallSite::arg_iterator itA = cs.arg_begin(), ieA = cs.arg_end(); itA!=ieA; ++itA)
699  pag->addCallSiteArgs(callBlockNode,pag->getPAGNode(getValueNode(*itA)));
700 
701  if(!cs.getType()->isVoidTy())
702  pag->addCallSiteRets(retBlockNode,pag->getPAGNode(getValueNode(cs.getInstruction())));
703 
704  const SVFFunction *callee = getCallee(cs);
705 
706  if (callee)
707  {
708  if (isExtCall(callee))
709  {
710  if (ExternalPAG::hasExternalPAG(callee))
711  {
712  ExternalPAG::connectCallsiteToExternalPAG(&cs);
713  }
714  else
715  {
716  // There is no extpag for the function, use the old method.
717  handleExtCall(cs, callee);
718  }
719  }
720  else
721  {
722  handleDirectCall(cs, callee);
723  }
724  }
725  else
726  {
727  //If the callee was not identified as a function (null F), this is indirect.
728  handleIndCall(cs);
729  }
730 }
731 
735 void PAGBuilder::visitReturnInst(ReturnInst &inst)
736 {
737 
738  // ReturnInst itself should always not be a pointer type
739  assert(!SVFUtil::isa<PointerType>(inst.getType()));
740 
741  DBOUT(DPAGBuild, outs() << "process return " << inst << " \n");
742 
743  if(Value *src = inst.getReturnValue())
744  {
745  const SVFFunction *F = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(inst.getParent()->getParent());
746 
747  NodeID rnF = getReturnNode(F);
748  NodeID vnS = getValueNode(src);
749  //vnS may be null if src is a null ptr
750  const CopyPE* copy = addCopyEdge(vnS, rnF);
751  pag->addPhiNode(pag->getPAGNode(rnF), copy);
752  }
753 }
754 
755 
764 void PAGBuilder::visitExtractValueInst(ExtractValueInst &inst)
765 {
766  NodeID dst = getValueNode(&inst);
767  addBlackHoleAddrEdge(dst);
768 }
769 
778 void PAGBuilder::visitExtractElementInst(ExtractElementInst &inst)
779 {
780  NodeID dst = getValueNode(&inst);
781  addBlackHoleAddrEdge(dst);
782 }
783 
788 void PAGBuilder::visitBranchInst(BranchInst &inst){
789  NodeID dst = getValueNode(&inst);
790  NodeID src;
791  if (inst.isConditional())
792  src = getValueNode(inst.getCondition());
793  else
794  src = pag->getNullPtr();
795  const UnaryOPPE *unaryPE = addUnaryOPEdge(src, dst);
796  pag->addUnaryNode(pag->getPAGNode(dst),unaryPE);
797 }
798 
799 void PAGBuilder::visitSwitchInst(SwitchInst &inst){
800  NodeID dst = getValueNode(&inst);
801  Value* opnd = inst.getCondition();
802  NodeID src = getValueNode(opnd);
803  const UnaryOPPE* unaryPE = addUnaryOPEdge(src, dst);
804  pag->addUnaryNode(pag->getPAGNode(dst),unaryPE);
805 }
806 
812 void PAGBuilder::visitVAArgInst(VAArgInst &inst){
813  NodeID dst = getValueNode(&inst);
814  Value* opnd = inst.getPointerOperand();
815  NodeID src = getValueNode(opnd);
816  addCopyEdge(src,dst);
817 }
818 
823 void PAGBuilder::visitFreezeInst(FreezeInst &inst){
824  NodeID dst = getValueNode(&inst);
825  for (u32_t i = 0; i < inst.getNumOperands(); i++)
826  {
827  Value* opnd = inst.getOperand(i);
828  NodeID src = getValueNode(opnd);
829  addCopyEdge(src,dst);
830  }
831 }
832 
833 
837 void PAGBuilder::handleDirectCall(CallSite cs, const SVFFunction *F)
838 {
839 
840  assert(F);
841 
843  outs() << "handle direct call " << *cs.getInstruction() << " callee " << *F << "\n");
844 
845  //Only handle the ret.val. if it's used as a ptr.
846  NodeID dstrec = getValueNode(cs.getInstruction());
847  //Does it actually return a ptr?
848  if (!cs.getType()->isVoidTy())
849  {
850  NodeID srcret = getReturnNode(F);
851  CallBlockNode* icfgNode = pag->getICFG()->getCallBlockNode(cs.getInstruction());
852  addRetEdge(srcret, dstrec,icfgNode);
853  }
854  //Iterators for the actual and formal parameters
855  CallSite::arg_iterator itA = cs.arg_begin(), ieA = cs.arg_end();
856  Function::const_arg_iterator itF = F->getLLVMFun()->arg_begin(), ieF = F->getLLVMFun()->arg_end();
857  //Go through the fixed parameters.
858  DBOUT(DPAGBuild, outs() << " args:");
859  for (; itF != ieF; ++itA, ++itF)
860  {
861  //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
862  if (itA == ieA)
863  {
864  DBOUT(DPAGBuild, outs() << " !! not enough args\n");
865  break;
866  }
867  const Value *AA = *itA, *FA = &*itF; //current actual/formal arg
868 
869  DBOUT(DPAGBuild, outs() << "process actual parm " << *AA << " \n");
870 
871  NodeID dstFA = getValueNode(FA);
872  NodeID srcAA = getValueNode(AA);
873  CallBlockNode* icfgNode = pag->getICFG()->getCallBlockNode(cs.getInstruction());
874  addCallEdge(srcAA, dstFA, icfgNode);
875  }
876  //Any remaining actual args must be varargs.
877  if (F->getLLVMFun()->isVarArg())
878  {
879  NodeID vaF = getVarargNode(F);
880  DBOUT(DPAGBuild, outs() << "\n varargs:");
881  for (; itA != ieA; ++itA)
882  {
883  Value *AA = *itA;
884  NodeID vnAA = getValueNode(AA);
885  CallBlockNode* icfgNode = pag->getICFG()->getCallBlockNode(cs.getInstruction());
886  addCallEdge(vnAA,vaF, icfgNode);
887  }
888  }
889  if(itA != ieA)
890  {
893  writeWrnMsg("too many args to non-vararg func.");
894  writeWrnMsg("(" + getSourceLoc(cs.getInstruction()) + ")");
895 
896  }
897 }
898 
899 
903 const Type *PAGBuilder::getBaseTypeAndFlattenedFields(Value *V, std::vector<LocationSet> &fields)
904 {
905  return SymbolTableInfo::SymbolInfo()->getBaseTypeAndFlattenedFields(V, fields);
906 }
907 
912 void PAGBuilder::addComplexConsForExt(Value *D, Value *S, u32_t sz)
913 {
914  assert(D && S);
915  NodeID vnD= getValueNode(D), vnS= getValueNode(S);
916  if(!vnD || !vnS)
917  return;
918 
919  std::vector<LocationSet> fields;
920 
921  //Get the max possible size of the copy, unless it was provided.
922  std::vector<LocationSet> srcFields;
923  std::vector<LocationSet> dstFields;
924  const Type *stype = getBaseTypeAndFlattenedFields(S, srcFields);
925  const Type *dtype = getBaseTypeAndFlattenedFields(D, dstFields);
926  if(srcFields.size() > dstFields.size())
927  fields = dstFields;
928  else
929  fields = srcFields;
930 
932  if (sz == 0)
933  sz = fields.size();
934 
935  assert(fields.size() >= sz && "the number of flattened fields is smaller than size");
936 
937  //For each field (i), add (Ti = *S + i) and (*D + i = Ti).
938  for (u32_t index = 0; index < sz; index++)
939  {
940  NodeID dField = getGepValNode(D,fields[index],dtype,index);
941  NodeID sField = getGepValNode(S,fields[index],stype,index);
942  NodeID dummy = pag->addDummyValNode();
943  addLoadEdge(sField,dummy);
944  addStoreEdge(dummy,dField);
945  }
946 }
947 
948 
952 void PAGBuilder::handleExtCall(CallSite cs, const SVFFunction *callee)
953 {
954  const Instruction* inst = cs.getInstruction();
956  {
957  // case 1: ret = new obj
959  {
960  NodeID val = getValueNode(inst);
961  NodeID obj = getObjectNode(inst);
962  addAddrEdge(obj, val);
963  }
964  // case 2: *arg = new obj
965  else
966  {
967  assert(isHeapAllocExtCallViaArg(cs) && "Must be heap alloc call via arg.");
968  int arg_pos = getHeapAllocHoldingArgPosition(callee);
969  const Value *arg = cs.getArgument(arg_pos);
970  if (arg->getType()->isPointerTy())
971  {
972  NodeID vnArg = getValueNode(arg);
973  NodeID dummy = pag->addDummyValNode();
974  NodeID obj = pag->addDummyObjNode();
975  if (vnArg && dummy && obj)
976  {
977  addAddrEdge(obj, dummy);
978  addStoreEdge(dummy, vnArg);
979  }
980  }
981  else
982  {
983  writeWrnMsg("Arg receiving new object must be pointer type");
984  }
985  }
986  }
987  else
988  {
989  if(isExtCall(callee))
990  {
991  ExtAPI::extf_t tF= extCallTy(callee);
992  switch(tF)
993  {
994  case ExtAPI::EFT_REALLOC:
995  {
996  if(!SVFUtil::isa<PointerType>(inst->getType()))
997  break;
998  // e.g. void *realloc(void *ptr, size_t size)
999  // if ptr is null then we will treat it as a malloc
1000  // if ptr is not null, then we assume a new data memory will be attached to
1001  // the tail of old allocated memory block.
1002  if(SVFUtil::isa<ConstantPointerNull>(cs.getArgument(0)))
1003  {
1004  NodeID val = getValueNode(inst);
1005  NodeID obj = getObjectNode(inst);
1006  addAddrEdge(obj, val);
1007  }
1008  break;
1009  }
1010  case ExtAPI::EFT_L_A0:
1011  case ExtAPI::EFT_L_A1:
1012  case ExtAPI::EFT_L_A2:
1013  case ExtAPI::EFT_L_A8:
1014  {
1015  if(!SVFUtil::isa<PointerType>(inst->getType()))
1016  break;
1017  NodeID dstNode = getValueNode(inst);
1018  Size_t arg_pos;
1019  switch(tF)
1020  {
1021  case ExtAPI::EFT_L_A1:
1022  arg_pos= 1;
1023  break;
1024  case ExtAPI::EFT_L_A2:
1025  arg_pos= 2;
1026  break;
1027  case ExtAPI::EFT_L_A8:
1028  arg_pos= 8;
1029  break;
1030  default:
1031  arg_pos= 0;
1032  }
1033  Value *src= cs.getArgument(arg_pos);
1034  if(SVFUtil::isa<PointerType>(src->getType()))
1035  {
1036  NodeID srcNode = getValueNode(src);
1037  addCopyEdge(srcNode, dstNode);
1038  }
1039  else
1040  addBlackHoleAddrEdge(dstNode);
1041  break;
1042  break;
1043  }
1044  case ExtAPI::EFT_L_A0__A0R_A1:
1045  {
1046  // this is only for memset(void *str, int c, size_t n)
1047  // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
1048  // However, the second argument is non-pointer, thus we can not use addComplexConsForExt
1049  // addComplexConsForExt(cs.getArgument(0), cs.getArgument(1));
1050  if(SVFUtil::isa<PointerType>(inst->getType()))
1051  addCopyEdge(getValueNode(cs.getArgument(0)), getValueNode(inst));
1052  break;
1053  }
1054  case ExtAPI::EFT_L_A0__A0R_A1R:
1055  {
1056  addComplexConsForExt(cs.getArgument(0), cs.getArgument(1));
1057  //memcpy returns the dest.
1058  if(SVFUtil::isa<PointerType>(inst->getType()))
1059  {
1060  addCopyEdge(getValueNode(cs.getArgument(0)), getValueNode(inst));
1061  }
1062  break;
1063  }
1064  case ExtAPI::EFT_A1R_A0R:
1065  addComplexConsForExt(cs.getArgument(1), cs.getArgument(0));
1066  break;
1067  case ExtAPI::EFT_A3R_A1R_NS:
1068  //These func. are never used to copy structs, so the size is 1.
1069  addComplexConsForExt(cs.getArgument(3), cs.getArgument(1), 1);
1070  break;
1071  case ExtAPI::EFT_A1R_A0:
1072  {
1073  NodeID vnD= getValueNode(cs.getArgument(1));
1074  NodeID vnS= getValueNode(cs.getArgument(0));
1075  if(vnD && vnS)
1076  addStoreEdge(vnS,vnD);
1077  break;
1078  }
1079  case ExtAPI::EFT_A2R_A1:
1080  {
1081  NodeID vnD= getValueNode(cs.getArgument(2));
1082  NodeID vnS= getValueNode(cs.getArgument(1));
1083  if(vnD && vnS)
1084  addStoreEdge(vnS,vnD);
1085  break;
1086  }
1087  case ExtAPI::EFT_A4R_A1:
1088  {
1089  NodeID vnD= getValueNode(cs.getArgument(4));
1090  NodeID vnS= getValueNode(cs.getArgument(1));
1091  if(vnD && vnS)
1092  addStoreEdge(vnS,vnD);
1093  break;
1094  }
1095  case ExtAPI::EFT_L_A0__A1_A0:
1096  {
1101  if (const LoadInst *load = SVFUtil::dyn_cast<LoadInst>(cs.getArgument(0))) {
1102  addStoreEdge(getValueNode(cs.getArgument(1)), getValueNode(load->getPointerOperand()));
1103  if (SVFUtil::isa<PointerType>(inst->getType()))
1104  addLoadEdge(getValueNode(load->getPointerOperand()), getValueNode(inst));
1105  }
1106 // else if (const GetElementPtrInst *gep = SVFUtil::dyn_cast<GetElementPtrInst>(cs.getArgument(0))) {
1107 // addStoreEdge(getValueNode(cs.getArgument(1)), getValueNode(cs.getArgument(0)));
1108 // if (SVFUtil::isa<PointerType>(inst->getType()))
1109 // addCopyEdge(getValueNode(cs.getArgument(0)), getValueNode(inst));
1110 // }
1111  break;
1112  }
1113  case ExtAPI::EFT_L_A0__A2R_A0:
1114  {
1115  if(SVFUtil::isa<PointerType>(inst->getType()))
1116  {
1117  //Do the L_A0 part if the retval is used.
1118  NodeID vnD= getValueNode(inst);
1119  Value *src= cs.getArgument(0);
1120  if(SVFUtil::isa<PointerType>(src->getType()))
1121  {
1122  NodeID vnS= getValueNode(src);
1123  if(vnS)
1124  addCopyEdge(vnS,vnD);
1125  }
1126  else
1127  addBlackHoleAddrEdge(vnD);
1128  }
1129  //Do the A2R_A0 part.
1130  NodeID vnD= getValueNode(cs.getArgument(2));
1131  NodeID vnS= getValueNode(cs.getArgument(0));
1132  if(vnD && vnS)
1133  addStoreEdge(vnS,vnD);
1134  break;
1135  }
1136  case ExtAPI::EFT_A0R_NEW:
1137  case ExtAPI::EFT_A1R_NEW:
1138  case ExtAPI::EFT_A2R_NEW:
1139  case ExtAPI::EFT_A4R_NEW:
1140  case ExtAPI::EFT_A11R_NEW:
1141  {
1142  assert(!"Alloc via arg cases are not handled here.");
1143  break;
1144  }
1145  case ExtAPI::EFT_ALLOC:
1146  case ExtAPI::EFT_NOSTRUCT_ALLOC:
1147  case ExtAPI::EFT_STAT:
1148  case ExtAPI::EFT_STAT2:
1149  if(SVFUtil::isa<PointerType>(inst->getType()))
1150  assert(!"alloc type func. are not handled here");
1151  else
1152  {
1153  // fdopen will return an integer in LLVM IR.
1154  writeWrnMsg("alloc type func do not return pointer type");
1155  }
1156  break;
1157  case ExtAPI::EFT_NOOP:
1158  case ExtAPI::EFT_FREE:
1159  break;
1160  case ExtAPI::EFT_STD_RB_TREE_INSERT_AND_REBALANCE:
1161  {
1162  Value *vArg1 = cs.getArgument(1);
1163  Value *vArg3 = cs.getArgument(3);
1164 
1165  // We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
1166  // Now we calculate the offset from base to vArg3
1167  NodeID vnArg3 = pag->getValueNode(vArg3);
1168  Size_t offset = pag->getLocationSetFromBaseNode(vnArg3).getOffset();
1169 
1170  // We get all flattened fields of base
1171  vector<LocationSet> fields;
1172  const Type *type = getBaseTypeAndFlattenedFields(vArg3, fields);
1173  assert(fields.size() >= 4 && "_Rb_tree_node_base should have at least 4 fields.\n");
1174 
1175  // We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
1176  // Note that arg0 is aligned with "offset".
1177  for (int i = offset + 1; i <= offset + 3; ++i)
1178  {
1179  NodeID vnD = getGepValNode(vArg3, fields[i], type, i);
1180  NodeID vnS = getValueNode(vArg1);
1181  if(vnD && vnS)
1182  addStoreEdge(vnS,vnD);
1183  }
1184  break;
1185  }
1186  case ExtAPI::EFT_STD_RB_TREE_INCREMENT:
1187  {
1188  NodeID vnD = pag->getValueNode(inst);
1189 
1190  Value *vArg = cs.getArgument(0);
1191  NodeID vnArg = pag->getValueNode(vArg);
1192  Size_t offset = pag->getLocationSetFromBaseNode(vnArg).getOffset();
1193 
1194  // We get all fields
1195  vector<LocationSet> fields;
1196  const Type *type = getBaseTypeAndFlattenedFields(vArg,fields);
1197  assert(fields.size() >= 4 && "_Rb_tree_node_base should have at least 4 fields.\n");
1198 
1199  // We summarize the side effects: ret = arg->parent, ret = arg->left, ret = arg->right
1200  // Note that arg0 is aligned with "offset".
1201  for (int i = offset + 1; i <= offset + 3; ++i)
1202  {
1203  NodeID vnS = getGepValNode(vArg, fields[i], type, i);
1204  if(vnD && vnS)
1205  addStoreEdge(vnS,vnD);
1206  }
1207  break;
1208  }
1209  case ExtAPI::EFT_STD_LIST_HOOK:
1210  {
1211  Value *vSrc = cs.getArgument(0);
1212  Value *vDst = cs.getArgument(1);
1213  NodeID src = pag->getValueNode(vSrc);
1214  NodeID dst = pag->getValueNode(vDst);
1215  addStoreEdge(src, dst);
1216  break;
1217  }
1218  case ExtAPI::CPP_EFT_A0R_A1:
1219  {
1220  SymbolTableInfo* symTable = SymbolTableInfo::SymbolInfo();
1221  if (symTable->getModelConstants())
1222  {
1223  NodeID vnD = pag->getValueNode(cs.getArgument(0));
1224  NodeID vnS = pag->getValueNode(cs.getArgument(1));
1225  addStoreEdge(vnS, vnD);
1226  }
1227  break;
1228  }
1229  case ExtAPI::CPP_EFT_A0R_A1R:
1230  {
1231  SymbolTableInfo* symTable = SymbolTableInfo::SymbolInfo();
1232  if (symTable->getModelConstants())
1233  {
1234  NodeID vnD = getValueNode(cs.getArgument(0));
1235  NodeID vnS = getValueNode(cs.getArgument(1));
1236  assert(vnD && vnS && "dst or src not exist?");
1237  NodeID dummy = pag->addDummyValNode();
1238  addLoadEdge(vnS,dummy);
1239  addStoreEdge(dummy,vnD);
1240  }
1241  break;
1242  }
1243  case ExtAPI::CPP_EFT_A1R:
1244  {
1245  SymbolTableInfo* symTable = SymbolTableInfo::SymbolInfo();
1246  if (symTable->getModelConstants())
1247  {
1248  NodeID vnS = getValueNode(cs.getArgument(1));
1249  assert(vnS && "src not exist?");
1250  NodeID dummy = pag->addDummyValNode();
1251  addLoadEdge(vnS,dummy);
1252  }
1253  break;
1254  }
1255  case ExtAPI::CPP_EFT_DYNAMIC_CAST:
1256  {
1257  Value *vArg0 = cs.getArgument(0);
1258  Value *retVal = cs.getInstruction();
1259  NodeID src = getValueNode(vArg0);
1260  assert(src && "src not exist?");
1261  NodeID dst = getValueNode(retVal);
1262  assert(dst && "dst not exist?");
1263  addCopyEdge(src, dst);
1264  break;
1265  }
1266  case ExtAPI::EFT_CXA_BEGIN_CATCH:
1267  {
1268  break;
1269  }
1270  //default:
1271  case ExtAPI::EFT_OTHER:
1272  {
1273  if(SVFUtil::isa<PointerType>(inst->getType()))
1274  {
1275  std::string str;
1276  raw_string_ostream rawstr(str);
1277  rawstr << "function " << callee->getName() << " not in the external function summary list";
1278  writeWrnMsg(rawstr.str());
1279  //assert("unknown ext.func type");
1280  }
1281  }
1282  }
1283  }
1284 
1286  if(isThreadForkCall(inst))
1287  {
1288  if(const Function* forkedFun = getLLVMFunction(getForkedFun(inst)) )
1289  {
1290  forkedFun = getDefFunForMultipleModule(forkedFun)->getLLVMFun();
1291  const Value* actualParm = getActualParmAtForkSite(inst);
1294  assert((forkedFun->arg_size() <= 2) && "Size of formal parameter of start routine should be one");
1295  if(forkedFun->arg_size() <= 2 && forkedFun->arg_size() >= 1)
1296  {
1297  const Argument* formalParm = &(*forkedFun->arg_begin());
1299  if(SVFUtil::isa<PointerType>(actualParm->getType()) && SVFUtil::isa<PointerType>(formalParm->getType()) )
1300  {
1301  CallBlockNode* icfgNode = pag->getICFG()->getCallBlockNode(inst);
1302  addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm),icfgNode);
1303  }
1304  }
1305  }
1306  else
1307  {
1312  }
1316  }
1317 
1319  else if(isHareParForCall(inst))
1320  {
1321  if(const Function* taskFunc = getLLVMFunction(getTaskFuncAtHareParForSite(inst)) )
1322  {
1324  assert((taskFunc->arg_size() == 3) && "Size of formal parameter of hare_parallel_for's task routine should be 3");
1325  const Value* actualParm = getTaskDataAtHareParForSite(inst);
1326  const Argument* formalParm = &(*taskFunc->arg_begin());
1328  if(SVFUtil::isa<PointerType>(actualParm->getType()) && SVFUtil::isa<PointerType>(formalParm->getType()) )
1329  {
1330  CallBlockNode* icfgNode = pag->getICFG()->getCallBlockNode(inst);
1331  addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm),icfgNode);
1332  }
1333  }
1334  else
1335  {
1340  }
1341  }
1342 
1344  }
1345 }
1346 
1350 void PAGBuilder::handleIndCall(CallSite cs)
1351 {
1352  const CallBlockNode* cbn = pag->getICFG()->getCallBlockNode(cs.getInstruction());
1353  pag->addIndirectCallsites(cbn,pag->getValueNode(cs.getCalledValue()));
1354 }
1355 
1356 /*
1357  * TODO: more sanity checks might be needed here
1358  */
1359 void PAGBuilder::sanityCheck()
1360 {
1361  for (PAG::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter)
1362  {
1363  (void) pag->getPAGNode(nIter->first);
1364  //TODO::
1365  // (1) every source(root) node of a pag tree should be object node
1366  // if a node has no incoming edge, but has outgoing edges
1367  // then it has to be an object node.
1368  // (2) make sure every variable should be initialized
1369  // otherwise it causes the a null pointer, the aliasing relation may not be captured
1370  // when loading a pointer value should make sure
1371  // some value has been store into this pointer before
1372  // q = load p, some value should stored into p first like store w p;
1373  // (3) make sure PAGNode should not have a const expr value (pointer should have unique def)
1374  // (4) look closely into addComplexConsForExt, make sure program locations(e.g.,inst bb)
1375  // are set correctly for dummy gepval node
1376  // (5) reduce unnecessary copy edge (const casts) and ensure correctness.
1377  }
1378 }
1379 
1380 
1385 NodeID PAGBuilder::getGepValNode(const Value* val, const LocationSet& ls, const Type *baseType, u32_t fieldidx)
1386 {
1387  NodeID base = pag->getBaseValNode(getValueNode(val));
1388  NodeID gepval = pag->getGepValNode(curVal, base, ls);
1389  if (gepval==UINT_MAX)
1390  {
1391  assert(UINT_MAX==-1 && "maximum limit of unsigned int is not -1?");
1392  /*
1393  * getGepValNode can only be called from two places:
1394  * 1. PAGBuilder::addComplexConsForExt to handle external calls
1395  * 2. PAGBuilder::getGlobalVarField to initialize global variable
1396  * so curVal can only be
1397  * 1. Instruction
1398  * 2. GlobalVariable
1399  */
1400  assert((SVFUtil::isa<Instruction>(curVal) || SVFUtil::isa<GlobalVariable>(curVal)) && "curVal not an instruction or a globalvariable?");
1401  const std::vector<FieldInfo> &fieldinfo = SymbolTableInfo::SymbolInfo()->getFlattenFieldInfoVec(baseType);
1402  const Type *type = fieldinfo[fieldidx].getFlattenElemTy();
1403 
1404  // We assume every GepValNode and its GepEdge to the baseNode are unique across the whole program
1405  // We preserve the current BB information to restore it after creating the gepNode
1406  const Value* cval = getCurrentValue();
1407  const BasicBlock* cbb = getCurrentBB();
1408  setCurrentLocation(curVal, nullptr);
1409  NodeID gepNode= pag->addGepValNode(curVal, val,ls, NodeIDAllocator::get()->allocateValueId(),type,fieldidx);
1410  addGepEdge(base, gepNode, ls, true);
1411  setCurrentLocation(cval, cbb);
1412  return gepNode;
1413  }
1414  else
1415  return gepval;
1416 }
1417 
1418 
1419 /*
1420  * curVal <--------> PAGEdge
1421  * Instruction Any Edge
1422  * Argument CopyEdge (PAG::addFormalParamBlackHoleAddrEdge)
1423  * ConstantExpr CopyEdge (Int2PtrConstantExpr CastConstantExpr PAGBuilder::processCE)
1424  * GepEdge (GepConstantExpr PAGBuilder::processCE)
1425  * ConstantPointerNull CopyEdge (3-->2 NullPtr-->BlkPtr PAG::addNullPtrNode)
1426  * AddrEdge (0-->2 BlkObj-->BlkPtr PAG::addNullPtrNode)
1427  * GlobalVariable AddrEdge (PAGBuilder::visitGlobal)
1428  * GepEdge (PAGBuilder::getGlobalVarField)
1429  * Function AddrEdge (PAGBuilder::visitGlobal)
1430  * Constant StoreEdge (PAGBuilder::InitialGlobal)
1431  */
1432 void PAGBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge)
1433 {
1434  if (SVFModule::pagReadFromTXT())
1435  return;
1436 
1437  assert(curVal && "current Val is nullptr?");
1438  edge->setBB(curBB);
1439  edge->setValue(curVal);
1440  ICFGNode* icfgNode = pag->getICFG()->getGlobalBlockNode();
1441  if (const Instruction *curInst = SVFUtil::dyn_cast<Instruction>(curVal))
1442  {
1443  const Function* srcFun = edge->getSrcNode()->getFunction();
1444  const Function* dstFun = edge->getDstNode()->getFunction();
1445  if(srcFun!=nullptr && !SVFUtil::isa<RetPE>(edge) && !SVFUtil::isa<Function>(edge->getSrcNode()->getValue())) {
1446  assert(srcFun==curInst->getFunction() && "SrcNode of the PAGEdge not in the same function?");
1447  }
1448  if(dstFun!=nullptr && !SVFUtil::isa<CallPE>(edge) && !SVFUtil::isa<Function>(edge->getDstNode()->getValue())) {
1449  assert(dstFun==curInst->getFunction() && "DstNode of the PAGEdge not in the same function?");
1450  }
1451 
1453  if (!(SVFUtil::isa<GepPE>(edge) && SVFUtil::isa<GepValPN>(edge->getDstNode())))
1454  assert(curBB && "instruction does not have a basic block??");
1455 
1456  icfgNode = pag->getICFG()->getBlockICFGNode(curInst);
1457  }
1458  else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(curVal))
1459  {
1460  assert(curBB && (&curBB->getParent()->getEntryBlock() == curBB));
1461  const SVFFunction* fun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(arg->getParent());
1462  icfgNode = pag->getICFG()->getFunEntryBlockNode(fun);
1463  }
1464  else if (SVFUtil::isa<ConstantExpr>(curVal))
1465  {
1466  if (!curBB)
1467  pag->addGlobalPAGEdge(edge);
1468  else
1469  icfgNode = pag->getICFG()->getBlockICFGNode(&curBB->front());
1470  }
1471  else if (SVFUtil::isa<GlobalVariable>(curVal) ||
1472  SVFUtil::isa<Function>(curVal) ||
1473  SVFUtil::isa<Constant>(curVal) ||
1474  SVFUtil::isa<MetadataAsValue>(curVal))
1475  {
1476  pag->addGlobalPAGEdge(edge);
1477  }
1478  else
1479  {
1480  assert(false && "what else value can we have?");
1481  }
1482 
1483  pag->addToInstPAGEdgeList(icfgNode,edge);
1484  icfgNode->addPAGEdge(edge);
1485 }
1486 
1487 
Value * stripAllCasts(Value *val)
Strip off the all casts.
Definition: LLVMUtil.cpp:192
const Function * getLLVMFunction(const Value *val)
Return LLVM function if this value is.
Definition: LLVMUtil.h:54
llvm_iterator llvmFunEnd()
Definition: SVFModule.h:125
llvm::StoreInst StoreInst
Definition: BasicTypes.h:146
llvm::ExtractElementInst ExtractElementInst
Definition: BasicTypes.h:165
llvm::BranchInst BranchInst
Definition: BasicTypes.h:157
llvm::UnaryOperator UnaryOperator
Definition: BasicTypes.h:162
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition: SVFUtil.h:144
llvm::CastInst CastInst
Definition: BasicTypes.h:150
llvm::BasicBlock BasicBlock
Definition: BasicTypes.h:77
SymID blackholeSymID() const
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition: LLVMUtil.h:559
void setBB(const BasicBlock *bb)
Definition: PAGEdge.h:120
u32_t NodeID
Definition: SVFBasicTypes.h:80
AliasSetType::iterator alias_iterator
Definition: SVFModule.h:54
llvm::Type Type
Definition: BasicTypes.h:75
iterator begin()
Definition: SVFModule.h:134
const SVFFunction * getDefFunForMultipleModule(const Function *fun)
Get the definition of a function across multiple modules.
Definition: SVFUtil.h:209
llvm::GlobalVariable GlobalVariable
Definition: BasicTypes.h:83
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition: LLVMUtil.h:593
#define assert(ex)
Definition: util.h:141
llvm::PointerType PointerType
Definition: BasicTypes.h:108
Value * getCalledValue() const
Definition: BasicTypes.h:327
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition: LLVMUtil.h:519
llvm::PHINode PHINode
Definition: BasicTypes.h:148
llvm::BinaryOperator BinaryOperator
Definition: BasicTypes.h:161
CallBase * getInstruction() const
Definition: BasicTypes.h:316
SymID nullPtrSymID() const
Definition: PAG.h:47
ValueToIDMapTy & valSyms()
Get different kinds of syms maps.
Size_t getTotalSymNum() const
Statistics.
std::string getSourceLoc(const Value *val)
Return source code including line number and file name from debug information.
Definition: SVFUtil.cpp:259
const llvm::StringRef getName() const
User::const_op_iterator arg_end() const
Definition: BasicTypes.h:321
unsigned u32_t
Definition: SVFBasicTypes.h:75
void writeWrnMsg(std::string msg)
Writes a message run through wrnMsg.
Definition: SVFUtil.cpp:67
bool isHeapAllocOrStaticExtCall(const CallSite cs)
Return true if the call is a static global call.
Definition: LLVMUtil.h:209
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition: LLVMUtil.h:573
alias_iterator alias_end()
Definition: SVFModule.h:176
llvm_iterator llvmFunBegin()
Definition: SVFModule.h:117
bool isHareParForCall(const CallSite cs)
Definition: LLVMUtil.h:271
llvm::ReturnInst ReturnInst
Definition: BasicTypes.h:152
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition: LLVMUtil.h:509
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:337
PAG * build()
Start building.
Value * getArgument(unsigned ArgNo) const
Definition: BasicTypes.h:318
llvm::SelectInst SelectInst
Definition: BasicTypes.h:154
SymID constantSymID() const
NodeType * getDstNode() const
Definition: GenericGraph.h:89
llvm::Function Function
Definition: BasicTypes.h:76
llvm::Instruction Instruction
Definition: BasicTypes.h:79
LLVMFunctionSetType::const_iterator llvm_const_iterator
Definition: SVFModule.h:51
llvm::StructType StructType
LLVM types.
Definition: BasicTypes.h:106
signed long Size_t
Definition: SVFBasicTypes.h:78
const Value * getTaskFuncAtHareParForSite(const CallSite cs)
Return the task function of the parallel_for routine.
Definition: LLVMUtil.h:367
llvm::raw_string_ostream raw_string_ostream
Definition: BasicTypes.h:100
bool isHeapAllocExtCallViaArg(const CallSite cs)
Definition: LLVMUtil.h:106
User::const_op_iterator arg_begin() const
Definition: BasicTypes.h:320
llvm::Argument Argument
LLVM Aliases and constants.
Definition: BasicTypes.h:122
ExtAPI::extf_t extCallTy(const SVFFunction *fun)
Return external call type.
Definition: LLVMUtil.h:221
bool isHeapAllocExtCallViaRet(const CallSite cs)
interfaces to be used externally
Definition: LLVMUtil.h:94
bool isValVtbl(const Value *val)
Definition: CPPUtil.cpp:123
llvm::AllocaInst AllocaInst
LLVM Instructions.
Definition: BasicTypes.h:142
const SVFFunction * getCallee(const CallSite cs)
Return callee of a callsite. Return null if this is an indirect call.
Definition: SVFUtil.h:221
GlobalSetType::iterator global_iterator
Definition: SVFModule.h:52
const Value * getActualParmAtForkSite(const CallSite cs)
Return sole argument of the thread routine.
Definition: LLVMUtil.h:355
void setValue(const Value *val)
Definition: PAGEdge.h:112
bool isStaticExtCall(const CallSite cs)
Definition: LLVMUtil.h:194
llvm::GetElementPtrInst GetElementPtrInst
Definition: BasicTypes.h:149
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition: LLVMUtil.h:529
NodeType * getSrcNode() const
Definition: GenericGraph.h:85
bool isThreadForkCall(const CallSite cs)
Definition: LLVMUtil.h:259
int getHeapAllocHoldingArgPosition(const SVFFunction *fun)
Get the position of argument that holds an allocated heap object.
Definition: LLVMUtil.h:129
raw_ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:47
void addPAGEdge(const PAGEdge *edge)
Definition: ICFGNode.h:116
llvm::Constant Constant
Definition: BasicTypes.h:123
SymID blkPtrSymID() const
global_iterator global_begin()
Definition: SVFModule.h:151
FunToIDMapTy & varargSyms()
llvm::SwitchInst SwitchInst
Definition: BasicTypes.h:158
Function * getLLVMFun() const
Definition: BasicTypes.h:245
const Value * getForkedFun(const CallSite cs)
Return thread fork function.
Definition: LLVMUtil.h:343
for isBitcode
Definition: ContextDDA.h:15
alias_iterator alias_begin()
Definition: SVFModule.h:168
llvm::LoadInst LoadInst
Definition: BasicTypes.h:147
FunToIDMapTy & retSyms()
Type * getType() const
Definition: BasicTypes.h:319
ValueToIDMapTy & objSyms()
#define DPAGBuild
iterator end()
Definition: SVFModule.h:142
bool getModelConstants() const
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:343
User::const_op_iterator arg_iterator
Definition: BasicTypes.h:317
llvm::ExtractValueInst ExtractValueInst
Definition: BasicTypes.h:159
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition: LLVMUtil.h:549
FunctionSetType::iterator iterator
Iterators type def.
Definition: SVFModule.h:48
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition: LLVMUtil.h:539
llvm::FreezeInst FreezeInst
Definition: BasicTypes.h:178
llvm::ConstantExpr ConstantExpr
Definition: BasicTypes.h:125
const Value * getTaskDataAtHareParForSite(const CallSite cs)
Return the task data argument of the parallel_for rountine.
Definition: LLVMUtil.h:379
bool isConstantObjSym(const Value *val)
global_iterator global_end()
Definition: SVFModule.h:159
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition: LLVMUtil.h:583
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DEBUG model of each pass.
llvm::Value Value
Definition: BasicTypes.h:78
llvm::User User
Definition: BasicTypes.h:86
llvm::VAArgInst VAArgInst
Definition: BasicTypes.h:164
bool isExtCall(const SVFFunction *fun)
Definition: LLVMUtil.h:64
llvm::CmpInst CmpInst
Definition: BasicTypes.h:156