Static Value-Flow Analysis
SymbolTableBuilder.cpp
Go to the documentation of this file.
1 //===- SymbolTableBuilder.cpp -- Symbol Table 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  * SymbolTableBuilder.cpp
25  *
26  * Created on: Apr 28, 2014
27  * Author: Yulei Sui
28  */
29 
30 #include <memory>
31 
32 #include "SVF-LLVM/BasicTypes.h"
33 #include "SVF-LLVM/CppUtil.h"
34 #include "SVF-LLVM/GEPTypeBridgeIterator.h" // include bridge_gep_iterator
35 #include "SVF-LLVM/LLVMUtil.h"
37 #include "SVFIR/SVFModule.h"
38 #include "Util/NodeIDAllocator.h"
39 #include "Util/Options.h"
40 #include "Util/SVFUtil.h"
42 
43 using namespace SVF;
44 using namespace SVFUtil;
45 using namespace LLVMUtil;
46 
48 {
49  assert(symInfo->isBlkObj(symId));
50  assert(symInfo->objMap.find(symId)==symInfo->objMap.end());
52  MemObj* obj =
53  new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType(
54  IntegerType::get(llvmset->getContext(), 32))));
55  symInfo->objMap[symId] = obj;
56  return obj;
57 }
58 
60 {
61  assert(symInfo->isConstantObj(symId));
62  assert(symInfo->objMap.find(symId)==symInfo->objMap.end());
64  MemObj* obj =
65  new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType(
66  IntegerType::get(llvmset->getContext(), 32))));
67  symInfo->objMap[symId] = obj;
68  return obj;
69 }
70 
71 
76 {
78 
79  symInfo->setModule(svfModule);
80 
81  // Pointer #0 always represents the null pointer.
82  assert(symInfo->totalSymNum++ == SymbolTableInfo::NullPtr && "Something changed!");
83 
84  // Pointer #1 always represents the pointer points-to black hole.
85  assert(symInfo->totalSymNum++ == SymbolTableInfo::BlkPtr && "Something changed!");
86 
87  // Object #2 is black hole the object that may point to any object
88  assert(symInfo->totalSymNum++ == SymbolTableInfo::BlackHole && "Something changed!");
89  createBlkObj(SymbolTableInfo::BlackHole);
90 
91  // Object #3 always represents the unique constant of a program (merging all constants if Options::ModelConsts is disabled)
92  assert(symInfo->totalSymNum++ == SymbolTableInfo::ConstantObj && "Something changed!");
93  createConstantObj(SymbolTableInfo::ConstantObj);
94 
95  for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
96  {
97  // Add symbols for all the globals .
98  for (const GlobalVariable& gv : M.globals())
99  {
100  collectSym(&gv);
101  }
102 
103  // Add symbols for all the global aliases
104  for (const GlobalAlias& ga : M.aliases())
105  {
106  collectSym(&ga);
107  collectSym(ga.getAliasee());
108  }
109 
110  // Add symbols for all of the functions and the instructions in them.
111  for (const Function& fun : M.functions())
112  {
113  collectSym(&fun);
114  collectRet(&fun);
115  if (fun.getFunctionType()->isVarArg())
116  collectVararg(&fun);
117 
118  // Add symbols for all formal parameters.
119  for (const Argument& arg : fun.args())
120  {
121  collectSym(&arg);
122  }
123 
124  // collect and create symbols inside the function body
125  for (const Instruction& inst : instructions(fun))
126  {
127  collectSym(&inst);
128 
129  // initialization for some special instructions
130  //{@
131  if (const StoreInst* st = SVFUtil::dyn_cast<StoreInst>(&inst))
132  {
133  collectSym(st->getPointerOperand());
134  collectSym(st->getValueOperand());
135  }
136  else if (const LoadInst* ld =
137  SVFUtil::dyn_cast<LoadInst>(&inst))
138  {
139  collectSym(ld->getPointerOperand());
140  }
141  else if (const AllocaInst* alloc =
142  SVFUtil::dyn_cast<AllocaInst>(&inst))
143  {
144  collectSym(alloc->getArraySize());
145  }
146  else if (const PHINode* phi = SVFUtil::dyn_cast<PHINode>(&inst))
147  {
148  for (u32_t i = 0; i < phi->getNumIncomingValues(); ++i)
149  {
150  collectSym(phi->getIncomingValue(i));
151  }
152  }
153  else if (const GetElementPtrInst* gep =
154  SVFUtil::dyn_cast<GetElementPtrInst>(&inst))
155  {
156  collectSym(gep->getPointerOperand());
157  for (u32_t i = 0; i < gep->getNumOperands(); ++i)
158  {
159  collectSym(gep->getOperand(i));
160  }
161  }
162  else if (const SelectInst* sel =
163  SVFUtil::dyn_cast<SelectInst>(&inst))
164  {
165  collectSym(sel->getTrueValue());
166  collectSym(sel->getFalseValue());
167  collectSym(sel->getCondition());
168  }
169  else if (const BinaryOperator* binary =
170  SVFUtil::dyn_cast<BinaryOperator>(&inst))
171  {
172  for (u32_t i = 0; i < binary->getNumOperands(); i++)
173  collectSym(binary->getOperand(i));
174  }
175  else if (const UnaryOperator* unary =
176  SVFUtil::dyn_cast<UnaryOperator>(&inst))
177  {
178  for (u32_t i = 0; i < unary->getNumOperands(); i++)
179  collectSym(unary->getOperand(i));
180  }
181  else if (const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(&inst))
182  {
183  for (u32_t i = 0; i < cmp->getNumOperands(); i++)
184  collectSym(cmp->getOperand(i));
185  }
186  else if (const CastInst* cast =
187  SVFUtil::dyn_cast<CastInst>(&inst))
188  {
189  collectSym(cast->getOperand(0));
190  }
191  else if (const ReturnInst* ret =
192  SVFUtil::dyn_cast<ReturnInst>(&inst))
193  {
194  if (ret->getReturnValue())
195  collectSym(ret->getReturnValue());
196  }
197  else if (const BranchInst* br =
198  SVFUtil::dyn_cast<BranchInst>(&inst))
199  {
200  Value* opnd = br->isConditional() ? br->getCondition() : br->getOperand(0);
201  collectSym(opnd);
202  }
203  else if (const SwitchInst* sw =
204  SVFUtil::dyn_cast<SwitchInst>(&inst))
205  {
206  collectSym(sw->getCondition());
207  }
208  else if (isNonInstricCallSite(&inst))
209  {
210 
211  const CallBase* cs = LLVMUtil::getLLVMCallSite(&inst);
212  for (u32_t i = 0; i < cs->arg_size(); i++)
213  {
214  collectSym(cs->getArgOperand(i));
215  }
216  // Calls to inline asm need to be added as well because the
217  // callee isn't referenced anywhere else.
218  const Value* Callee = cs->getCalledOperand();
219  collectSym(Callee);
220 
221  // TODO handle inlineAsm
224  {
225  getTypeInference()->validateTypeCheck(cs);
226  }
227  }
229  }
230  }
231  }
232 
233  symInfo->totalSymNum = NodeIDAllocator::get()->endSymbolAllocation();
234  if (Options::SymTabPrint())
235  {
236  symInfo->dump();
237  }
238 }
239 
241 {
242  Type *valType = val->getType();
243  (void)getOrAddSVFTypeInfo(valType);
244  if(isGepConstantExpr(val) || SVFUtil::isa<GetElementPtrInst>(val))
245  {
247  gi = bridge_gep_begin(SVFUtil::cast<User>(val)),
248  ge = bridge_gep_end(SVFUtil::cast<User>(val));
249  gi != ge; ++gi)
250  {
251  const Type* gepTy = *gi;
252  (void)getOrAddSVFTypeInfo(gepTy);
253  }
254  }
255 }
256 
261 {
262 
263  //TODO: filter the non-pointer type // if (!SVFUtil::isa<PointerType>(val->getType())) return;
264 
266  outs()
267  << "collect sym from ##"
268  << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->toString()
269  << " \n");
270  //TODO handle constant expression value here??
271  handleCE(val);
272 
273  // create a value sym
274  collectVal(val);
275 
276  collectSVFTypeInfo(val);
277  collectSVFTypeInfo(LLVMUtil::getGlobalRep(val));
278 
279  // create an object If it is a heap, stack, global, function.
280  if (isObject(val))
281  {
282  collectObj(val);
283  }
284 }
285 
290 {
291  // collect and record special sym here
293  {
294  return;
295  }
296  SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->valSymMap.find(
297  LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val));
298  if (iter == symInfo->valSymMap.end())
299  {
300  // create val sym and sym type
303  symInfo->valSymMap.insert(std::make_pair(svfVal, id));
305  outs() << "create a new value sym " << id << "\n");
307  if (const GlobalVariable* globalVar = SVFUtil::dyn_cast<GlobalVariable>(val))
308  handleGlobalCE(globalVar);
309  }
310 
311  if (isConstantObjSym(val))
312  collectObj(val);
313 }
314 
319 {
320  val = LLVMUtil::getGlobalRep(val);
322  SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->objSymMap.find(llvmModuleSet->getSVFValue(val));
323  if (iter == symInfo->objSymMap.end())
324  {
325  SVFValue* svfVal = llvmModuleSet->getSVFValue(val);
326  // if the object pointed by the pointer is a constant data (e.g., i32 0) or a global constant object (e.g. string)
327  // then we treat them as one ConstantObj
328  if (isConstantObjSym(val) && !symInfo->getModelConstants())
329  {
330  symInfo->objSymMap.insert(std::make_pair(svfVal, symInfo->constantSymID()));
331  }
332  // otherwise, we will create an object for each abstract memory location
333  else
334  {
335  // create obj sym and sym type
337  symInfo->objSymMap.insert(std::make_pair(svfVal, id));
339  outs() << "create a new obj sym " << id << "\n");
340 
341  // create a memory object
342  MemObj* mem =
343  new MemObj(id, createObjTypeInfo(val),
344  llvmModuleSet->getSVFValue(val));
345  assert(symInfo->objMap.find(id) == symInfo->objMap.end());
346  symInfo->objMap[id] = mem;
347  }
348  }
349 }
350 
355 {
356  const SVFFunction* svffun =
358  SymbolTableInfo::FunToIDMapTy::iterator iter =
359  symInfo->returnSymMap.find(svffun);
360  if (iter == symInfo->returnSymMap.end())
361  {
363  symInfo->returnSymMap.insert(std::make_pair(svffun, id));
364  DBOUT(DMemModel, outs() << "create a return sym " << id << "\n");
365  }
366 }
367 
372 {
373  const SVFFunction* svffun =
375  SymbolTableInfo::FunToIDMapTy::iterator iter =
376  symInfo->varargSymMap.find(svffun);
377  if (iter == symInfo->varargSymMap.end())
378  {
380  symInfo->varargSymMap.insert(std::make_pair(svffun, id));
381  DBOUT(DMemModel, outs() << "create a vararg sym " << id << "\n");
382  }
383 }
384 
389 {
390  if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
391  {
392  if (const ConstantExpr* ce = isGepConstantExpr(ref))
393  {
394  DBOUT(DMemModelCE, outs() << "handle constant expression "
396  ->getSVFValue(ref)
397  ->toString()
398  << "\n");
399  collectVal(ce);
400 
401  // handle the recursive constant express case
402  // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
403  for (u32_t i = 0; i < ce->getNumOperands(); ++i)
404  {
405  collectVal(ce->getOperand(i));
406  handleCE(ce->getOperand(i));
407  }
408  }
409  else if (const ConstantExpr* ce = isCastConstantExpr(ref))
410  {
411  DBOUT(DMemModelCE, outs() << "handle constant expression "
413  ->getSVFValue(ref)
414  ->toString()
415  << "\n");
416  collectVal(ce);
417  collectVal(ce->getOperand(0));
418  // handle the recursive constant express case
419  // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
420  handleCE(ce->getOperand(0));
421  }
422  else if (const ConstantExpr* ce = isSelectConstantExpr(ref))
423  {
424  DBOUT(DMemModelCE, outs() << "handle constant expression "
426  ->getSVFValue(ref)
427  ->toString()
428  << "\n");
429  collectVal(ce);
430  collectVal(ce->getOperand(0));
431  collectVal(ce->getOperand(1));
432  collectVal(ce->getOperand(2));
433  // handle the recursive constant express case
434  // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
435  handleCE(ce->getOperand(0));
436  handleCE(ce->getOperand(1));
437  handleCE(ce->getOperand(2));
438  }
439  // if we meet a int2ptr, then it points-to black hole
440  else if (const ConstantExpr* int2Ptrce = isInt2PtrConstantExpr(ref))
441  {
442  collectVal(int2Ptrce);
443  const Constant* opnd = int2Ptrce->getOperand(0);
444  handleCE(opnd);
445  }
446  else if (const ConstantExpr* ptr2Intce = isPtr2IntConstantExpr(ref))
447  {
448  collectVal(ptr2Intce);
449  const Constant* opnd = ptr2Intce->getOperand(0);
450  handleCE(opnd);
451  }
452  else if (isTruncConstantExpr(ref) || isCmpConstantExpr(ref))
453  {
454  collectVal(ref);
455  }
456  else if (isBinaryConstantExpr(ref))
457  {
458  collectVal(ref);
459  }
460  else if (isUnaryConstantExpr(ref))
461  {
462  // we don't handle unary constant expression like fneg(x) now
463  collectVal(ref);
464  }
465  else if (SVFUtil::isa<ConstantAggregate>(ref))
466  {
467  // we don't handle constant aggregate like constant vectors
468  collectVal(ref);
469  }
470  else
471  {
472  assert(!SVFUtil::isa<ConstantExpr>(val) &&
473  "we don't handle all other constant expression for now!");
474  collectVal(ref);
475  }
476  }
477 }
478 
483 {
484  assert(G);
485 
486  //The type this global points to
487  const Type* T = G->getValueType();
488  bool is_array = 0;
489  //An array is considered a single variable of its type.
490  while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(T))
491  {
492  T = AT->getElementType();
493  is_array = true;
494  }
495 
496  if (SVFUtil::isa<StructType>(T))
497  {
498  //A struct may be used in constant GEP expr.
499  for (const User* user : G->users())
500  {
501  handleCE(user);
502  }
503  }
504  else if (is_array)
505  {
506  for (const User* user : G->users())
507  {
508  handleCE(user);
509  }
510  }
511 
512  if (G->hasInitializer())
513  {
514  handleGlobalInitializerCE(G->getInitializer());
515  }
516 }
517 
522 {
523 
524  if (C->getType()->isSingleValueType())
525  {
526  if (const ConstantExpr* E = SVFUtil::dyn_cast<ConstantExpr>(C))
527  {
528  handleCE(E);
529  }
530  else
531  {
532  collectVal(C);
533  }
534  }
535  else if (SVFUtil::isa<ConstantArray>(C))
536  {
537  for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
538  {
539  handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
540  }
541  }
542  else if (SVFUtil::isa<ConstantStruct>(C))
543  {
544  for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
545  {
546  handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
547  }
548  }
549  else if(const ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
550  {
551  if (Options::ModelConsts())
552  {
553  if (const ConstantDataSequential* seq =
554  SVFUtil::dyn_cast<ConstantDataSequential>(data))
555  {
556  for(u32_t i = 0; i < seq->getNumElements(); i++)
557  {
558  const Constant* ct = seq->getElementAsConstant(i);
559  handleGlobalInitializerCE(ct);
560  }
561  }
562  else
563  {
564  assert(
565  (SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) &&
566  "Single value type data should have been handled!");
567  }
568  }
569  }
570  else
571  {
572  //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
573  }
574 }
575 
577 {
579 }
580 
581 
582 const Type* SymbolTableBuilder::inferObjType(const Value *startValue)
583 {
584  return getTypeInference()->inferObjType(startValue);
585 }
586 
591 {
592  const Value* startValue = inst;
593  const PointerType *originalPType = SVFUtil::dyn_cast<PointerType>(inst->getType());
594  const Type* inferedType = nullptr;
595  assert(originalPType && "empty type?");
598  {
599  if(const Value* v = getFirstUseViaCastInst(inst))
600  {
601  if (const PointerType *newTy = SVFUtil::dyn_cast<PointerType>(v->getType()))
602  {
603  originalPType = newTy;
604  }
605  }
606  inferedType = inferObjType(startValue);
607  }
609  {
610  const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
611  u32_t arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(SVFUtil::cast<SVFCallInst>(svfinst)->getCalledFunction());
612  const Value* arg = cs->getArgOperand(arg_pos);
613  originalPType = SVFUtil::dyn_cast<PointerType>(arg->getType());
614  inferedType = inferObjType(startValue = arg);
615  }
616  else
617  {
618  assert( false && "not a heap allocation instruction?");
619  }
620 
621  getTypeInference()->typeSizeDiffTest(originalPType, inferedType, startValue);
622 
623  return inferedType;
624 }
625 
626 /*
627  * Initial the memory object here
628  */
630 {
631  const Type* objTy = nullptr;
632 
633  const Instruction* I = SVFUtil::dyn_cast<Instruction>(val);
634 
635  // We consider two types of objects:
636  // (1) A heap/static object from a callsite
637  if (I && isNonInstricCallSite(I))
638  {
639  objTy = inferTypeOfHeapObjOrStaticObj(I);
640  }
641  // (2) Other objects (e.g., alloca, global, etc.)
642  else
643  {
644  if (SVFUtil::isa<PointerType>(val->getType()))
645  {
646  if (const AllocaInst *allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
647  {
648  // get the type of the allocated memory
649  // e.g., for `%retval = alloca i64, align 4`, we return i64
650  objTy = allocaInst->getAllocatedType();
651  }
652  else if (const GlobalValue *global = SVFUtil::dyn_cast<GlobalValue>(val))
653  {
654  // get the pointee type of the global pointer (begins with @ symbol in llvm)
655  objTy = global->getValueType();
656  }
657  else
658  {
659  SVFUtil::errs() << dumpValueAndDbgInfo(val) << "\n";
660  assert(false && "not an allocation or global?");
661  }
662  }
663  }
664 
665  if (objTy)
666  {
667  (void) getOrAddSVFTypeInfo(objTy);
668  ObjTypeInfo* typeInfo = new ObjTypeInfo(
669  LLVMModuleSet::getLLVMModuleSet()->getSVFType(objTy),
671  initTypeInfo(typeInfo,val, objTy);
672  return typeInfo;
673  }
674  else
675  {
676  writeWrnMsg("try to create an object with a non-pointer type.");
677  writeWrnMsg(val->getName().str());
678  writeWrnMsg("(" + LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->getSourceLoc() + ")");
679  if (isConstantObjSym(val))
680  {
681  ObjTypeInfo* typeInfo = new ObjTypeInfo(
682  LLVMModuleSet::getLLVMModuleSet()->getSVFType(val->getType()),
683  0);
684  initTypeInfo(typeInfo,val, val->getType());
685  return typeInfo;
686  }
687  else
688  {
689  assert(false && "Memory object must be either (1) held by a pointer-typed ref value or (2) a constant value (e.g., 10).");
690  abort();
691  }
692  }
693 }
694 
699 {
700  const Type *elemTy = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(typeinfo->getType());
701  // Find the inter nested array element
702  while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(elemTy))
703  {
704  elemTy = AT->getElementType();
705  if (SVFUtil::isa<GlobalVariable>(val) &&
706  SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
707  SVFUtil::isa<ConstantArray>(
708  SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
710  else
712  }
713  if (SVFUtil::isa<StructType>(elemTy))
714  {
715  if (SVFUtil::isa<GlobalVariable>(val) &&
716  SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
717  SVFUtil::isa<ConstantStruct>(
718  SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
720  else
722  }
723 }
724 
740 {
741  if(const llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(val))
742  {
743  if (const llvm::Function* calledFunction =
744  callInst->getCalledFunction())
745  {
746  const SVFFunction* svfFunction =
748  calledFunction);
749  std::vector<const Value*> args;
750  // Heap alloc functions have annoation like "AllocSize:Arg1"
751  for (std::string annotation : ExtAPI::getExtAPI()->getExtFuncAnnotations(svfFunction))
752  {
753  if (annotation.find("AllocSize:") != std::string::npos)
754  {
755  std::string allocSize = annotation.substr(10);
756  std::stringstream ss(allocSize);
757  std::string token;
758  // Analyaze annotation string and attract Arg list
759  while (std::getline(ss, token, '*'))
760  {
761  if (token.rfind("Arg", 0) == 0)
762  {
763  u32_t argIndex;
764  std::istringstream(token.substr(3)) >> argIndex;
765  if (argIndex < callInst->getNumOperands() - 1)
766  {
767  args.push_back(
768  callInst->getArgOperand(argIndex));
769  }
770  }
771  }
772  }
773  }
774  u64_t product = 1;
775  if (args.size() > 0)
776  {
777  // for annotations like "AllocSize:Arg0*Arg1"
778  for (const llvm::Value* arg : args)
779  {
780  if (const llvm::ConstantInt* constIntArg =
781  llvm::dyn_cast<llvm::ConstantInt>(arg))
782  {
783  // Multiply the constant Value if all Args are const
784  product *= constIntArg->getZExtValue();
785  }
786  else
787  {
788  // if Arg list has non-const value, return 0 to indicate it is non const byte size
789  return 0;
790  }
791  }
792  // If all the Args are const, return product
793  return product;
794  }
795  else
796  {
797  // for annotations like "AllocSize:UNKNOWN"
798  return 0;
799  }
800  }
801  }
802  // if it is not CallInst or CallInst has no CalledFunction, return 0 to indicate it is non const byte size
803  return 0;
804 }
805 
810 {
811  typeinfo->setFlag(ObjTypeInfo::HEAP_OBJ);
812  analyzeObjType(typeinfo, val);
813  const Type* objTy = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(typeinfo->getType());
814  if(SVFUtil::isa<ArrayType>(objTy))
815  return getNumOfElements(objTy);
816  else if(const StructType* st = SVFUtil::dyn_cast<StructType>(objTy))
817  {
822  LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->ptrType()));
823  else
824  return getNumOfElements(objTy);
825  }
826  return typeinfo->getMaxFieldOffsetLimit();
827 }
828 
833 {
834  if(const Value* castUse = getFirstUseViaCastInst(val))
835  {
836  typeinfo->setFlag(ObjTypeInfo::STATIC_OBJ);
837  analyzeObjType(typeinfo,castUse);
838  }
839  else
840  {
841  typeinfo->setFlag(ObjTypeInfo::HEAP_OBJ);
842  }
843 }
844 
849  const Type* objTy)
850 {
851 
852  u32_t elemNum = 1;
853  // init byteSize = 0, If byteSize is changed in the following process,
854  // it means that ObjTypeInfo has a Constant Byte Size
855  u32_t byteSize = 0;
856  // Global variable
857  // if val is Function Obj, byteSize is not set
858  if (SVFUtil::isa<Function>(val))
859  {
861  analyzeObjType(typeinfo,val);
862  elemNum = getNumOfElements(objTy);
863  }
866  else if(const AllocaInst* allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
867  {
868  typeinfo->setFlag(ObjTypeInfo::STACK_OBJ);
869  analyzeObjType(typeinfo,val);
872  if(const ConstantInt* sz = SVFUtil::dyn_cast<ConstantInt>(allocaInst->getArraySize()))
873  {
874  elemNum = sz->getZExtValue() * getNumOfElements(objTy);
875  byteSize = sz->getZExtValue() * typeinfo->getType()->getByteSize();
876  }
878  else
879  {
880  elemNum = getNumOfElements(objTy);
881  byteSize = 0;
882  }
883  }
886  else if(SVFUtil::isa<GlobalVariable>(val))
887  {
889  if(isConstantObjSym(val))
891  analyzeObjType(typeinfo,val);
892  elemNum = getNumOfElements(objTy);
893  byteSize = typeinfo->getType()->getByteSize();
894  }
896  else if (SVFUtil::isa<Instruction>(val) &&
898  SVFUtil::cast<Instruction>(val)))
899  {
900  elemNum = analyzeHeapObjType(typeinfo,val);
901  // analyze heap alloc like (malloc/calloc/...), the alloc functions have
902  // annotation like "AllocSize:Arg1". Please refer to extapi.c.
903  // e.g. calloc(4, 10), annotation is "AllocSize:Arg0*Arg1",
904  // it means byteSize = 4 (Arg0) * 10 (Arg1) = 40
905  byteSize = analyzeHeapAllocByteSize(val);
906  }
907  else if(ArgInProgEntryFunction(val))
908  {
909  analyzeStaticObjType(typeinfo,val);
910  // user input data, label its field as infinite here
911  elemNum = typeinfo->getMaxFieldOffsetLimit();
912  byteSize = typeinfo->getType()->getByteSize();
913  }
914  else if(LLVMUtil::isConstDataOrAggData(val))
915  {
916  typeinfo->setFlag(ObjTypeInfo::CONST_DATA);
917  elemNum = getNumOfFlattenElements(val->getType());
918  byteSize = typeinfo->getType()->getByteSize();
919  }
920  else
921  {
922  assert("what other object do we have??");
923  abort();
924  }
925 
926  // Reset maxOffsetLimit if it is over the total fieldNum of this object
927  if(typeinfo->getMaxFieldOffsetLimit() > elemNum)
928  typeinfo->setNumOfElements(elemNum);
929 
930  // set ByteSize. If ByteSize > 0, this typeinfo has constant type.
931  // If ByteSize == 0, this typeinfo has 1) zero byte 2) non-const byte size
932  // If ByteSize>MaxFieldLimit, set MaxFieldLimit to the byteSize;
933  byteSize = Options::MaxFieldLimit() > byteSize? byteSize: Options::MaxFieldLimit();
934  typeinfo->setByteSizeOfObj(byteSize);
935 }
936 
941 {
942  assert(ety && "type is null?");
943  u32_t numOfFields = 1;
944  if (SVFUtil::isa<StructType, ArrayType>(ety))
945  {
946  numOfFields = getNumOfFlattenElements(ety);
947  }
948  return numOfFields;
949 }
950 
953 {
955  return getOrAddSVFTypeInfo(T)->getNumOfFlattenElements();
956  else
957  return getOrAddSVFTypeInfo(T)->getNumOfFlattenFields();
958 }
959 
961 {
963 }
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DMemModelCE
Definition: SVFType.h:494
#define DMemModel
Definition: SVFType.h:493
const char *const string
Definition: cJSON.h:172
static ExtAPI * getExtAPI()
Definition: ExtAPI.cpp:42
SVFFunction * getSVFFunction(const Function *fun) const
Definition: LLVMModule.h:230
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
const Type * getLLVMType(const SVFType *T) const
Get LLVM Type.
LLVMContext & getContext() const
Definition: LLVMModule.h:349
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:118
SVFInstruction * getSVFInstruction(const Instruction *inst) const
Definition: LLVMModule.h:244
ObjTypeInference * getTypeInference()
Definition: LLVMModule.cpp:97
SVFValue * getSVFValue(const Value *value)
NodeID allocateValueId(void)
Allocate a value ID as determined by the strategy.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID allocateObjectId(void)
Allocate an object ID as determined by the strategy.
NodeID endSymbolAllocation(void)
Notify the allocator that all symbols have had IDs allocated.
u32_t getMaxFieldOffsetLimit()
Get max field offset limit.
const SVFType * getType() const
Get LLVM type.
void setByteSizeOfObj(u32_t size)
Set the byte size of this object.
void setFlag(MEMTYPE mask)
Flag for this object type.
void resetTypeForHeapStaticObj(const SVFType *type)
void setNumOfElements(u32_t num)
Set the number of elements of this object.
static const Option< bool > ModelConsts
Definition: Options.h:187
static const Option< bool > EnableTypeCheck
Definition: Options.h:131
static const Option< bool > ModelArrays
Definition: Options.h:188
static const Option< bool > SymTabPrint
Definition: Options.h:190
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition: Options.h:38
StInfo * getTypeInfo()
Definition: SVFType.h:230
u32_t getByteSize() const
Definition: SVFType.h:244
const Type * inferTypeOfHeapObjOrStaticObj(const Instruction *inst)
Get the reference type of heap/static object from an allocation site.
void handleGlobalInitializerCE(const Constant *C)
void collectRet(const Function *val)
ObjTypeInfo * createObjTypeInfo(const Value *val)
Create an objectInfo based on LLVM value.
const Type * inferObjType(const Value *startValue)
Forward collect all possible infer sites starting from a value.
void collectSVFTypeInfo(const Value *val)
collect the syms
ObjTypeInference * getTypeInference()
MemObj * createBlkObj(SymID symId)
u32_t getNumOfFlattenElements(const Type *T)
Number of flattened elements of an array or struct.
u32_t getNumOfElements(const Type *ety)
Return size of this object based on LLVM value.
void handleGlobalCE(const GlobalVariable *G)
Handle constant expression.
MemObj * createConstantObj(SymID symId)
u32_t analyzeHeapObjType(ObjTypeInfo *typeinfo, const Value *val)
Analyse types of heap and static objects.
u32_t analyzeHeapAllocByteSize(const Value *val)
Analyze byte size of heap alloc function (e.g. malloc/calloc/...)
void collectObj(const Value *val)
void collectVal(const Value *val)
void handleCE(const Value *val)
void collectSym(const Value *val)
void collectVararg(const Function *val)
void initTypeInfo(ObjTypeInfo *typeinfo, const Value *value, const Type *ty)
Initialize TypeInfo based on LLVM Value.
void buildMemModel(SVFModule *svfModule)
Start building memory model.
void analyzeObjType(ObjTypeInfo *typeinfo, const Value *val)
Analyse types of all flattened fields of this object.
StInfo * getOrAddSVFTypeInfo(const Type *T)
Get a reference to StructInfo.
void analyzeStaticObjType(ObjTypeInfo *typeinfo, const Value *val)
Analyse types of heap and static objects.
const CallBase * getLLVMCallSite(const Value *value)
Return LLVM callsite given a value.
Definition: LLVMUtil.h:57
bool isHeapAllocExtCallViaRet(const Instruction *inst)
Definition: LLVMUtil.cpp:618
const Value * getFirstUseViaCastInst(const Value *val)
Definition: LLVMUtil.cpp:279
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition: LLVMUtil.h:267
bool isHeapAllocExtCall(const Instruction *inst)
Definition: LLVMUtil.h:358
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition: LLVMUtil.h:201
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition: LLVMUtil.h:256
bool isNullPtrSym(const Value *val)
Check whether this value is a black hole.
Definition: LLVMUtil.h:91
std::string dumpValueAndDbgInfo(const Value *val)
Definition: LLVMUtil.cpp:607
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition: LLVMUtil.h:327
const std::string getSourceLoc(const Value *val)
Definition: LLVMUtil.cpp:430
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition: LLVMUtil.h:231
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition: LLVMUtil.cpp:417
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition: LLVMUtil.h:245
u32_t getNumOfElements(const Type *ety)
Return size of this object based on LLVM value.
Definition: LLVMUtil.cpp:297
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition: LLVMUtil.h:181
bool isBlackholeSym(const Value *val)
Check whether this value is a black hole.
Definition: LLVMUtil.h:85
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition: LLVMUtil.cpp:634
bool isObject(const Value *ref)
Return true if this value refers to a object.
Definition: LLVMUtil.cpp:59
bool isConstantObjSym(const SVFValue *val)
Check whether this value points-to a constant object.
Definition: LLVMUtil.cpp:579
bool ArgInProgEntryFunction(const Value *val)
Return true if this is an argument of a program entry function (e.g. main)
Definition: LLVMUtil.h:130
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition: LLVMUtil.h:191
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition: LLVMUtil.h:221
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition: LLVMUtil.h:211
void increaseStackSize()
Increase the stack size limit.
Definition: SVFUtil.cpp:227
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
Definition: Casting.h:360
u32_t getHeapAllocHoldingArgPosition(const SVFFunction *fun)
Get the position of argument that holds an allocated heap object.
Definition: SVFUtil.h:309
bool isNonInstricCallSite(const ICFGNode *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition: SVFUtil.h:189
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition: SVFUtil.cpp:66
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
bool classTyHasVTable(const StructType *ty)
Definition: CppUtil.cpp:569
for isBitcode
Definition: BasicTypes.h:68
llvm::GlobalVariable GlobalVariable
Definition: BasicTypes.h:130
llvm::GlobalAlias GlobalAlias
Definition: BasicTypes.h:128
llvm::ArrayType ArrayType
Definition: BasicTypes.h:95
llvm::Type Type
Definition: BasicTypes.h:83
llvm::CallBase CallBase
Definition: BasicTypes.h:146
llvm::UnaryOperator UnaryOperator
Definition: BasicTypes.h:180
llvm::StructType StructType
LLVM types.
Definition: BasicTypes.h:94
unsigned long long u64_t
Definition: GeneralType.h:48
llvm::AllocaInst AllocaInst
Definition: BasicTypes.h:150
llvm::SwitchInst SwitchInst
Definition: BasicTypes.h:155
llvm::Argument Argument
Definition: BasicTypes.h:145
llvm::LoadInst LoadInst
Definition: BasicTypes.h:149
llvm::CmpInst CmpInst
Definition: BasicTypes.h:159
llvm::Function Function
Definition: BasicTypes.h:85
llvm::GlobalValue GlobalValue
Definition: BasicTypes.h:88
llvm::ConstantData ConstantData
Definition: BasicTypes.h:116
llvm::Instruction Instruction
Definition: BasicTypes.h:87
llvm::Constant Constant
Definition: BasicTypes.h:124
llvm::ConstantDataSequential ConstantDataSequential
Definition: BasicTypes.h:119
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82
llvm::ConstantExpr ConstantExpr
Definition: BasicTypes.h:120
llvm::CastInst CastInst
Definition: BasicTypes.h:158
llvm::Module Module
Definition: BasicTypes.h:84
llvm::PointerType PointerType
Definition: BasicTypes.h:96
llvm::BinaryOperator BinaryOperator
Definition: BasicTypes.h:179
llvm::StoreInst StoreInst
Definition: BasicTypes.h:148
llvm::SelectInst SelectInst
Definition: BasicTypes.h:174
llvm::GetElementPtrInst GetElementPtrInst
Definition: BasicTypes.h:162
llvm::ReturnInst ReturnInst
Definition: BasicTypes.h:157
llvm::PHINode PHINode
Definition: BasicTypes.h:165
llvm::BranchInst BranchInst
Definition: BasicTypes.h:154
unsigned SymID
Definition: GeneralType.h:57
unsigned u32_t
Definition: GeneralType.h:46
llvm::CallInst CallInst
Definition: BasicTypes.h:147
llvm::ConstantInt ConstantInt
Definition: BasicTypes.h:125
llvm::User User
Definition: BasicTypes.h:142
bridge_gep_iterator bridge_gep_end(const User *GEP)
bridge_gep_iterator bridge_gep_begin(const User *GEP)