Static Value-Flow Analysis
Loading...
Searching...
No Matches
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"
38#include "Util/Options.h"
39#include "Util/SVFUtil.h"
41
42using namespace SVF;
43using namespace SVFUtil;
44using namespace LLVMUtil;
45
60
75
76
81{
83
84 // Pointer #0 always represents the null pointer.
85 assert(svfir->totalSymNum++ == IRGraph::NullPtr && "Something changed!");
86
87 // Pointer #1 always represents the pointer points-to black hole.
88 assert(svfir->totalSymNum++ == IRGraph::BlkPtr && "Something changed!");
89
90 // Object #2 is black hole the object that may point to any object
91 assert(svfir->totalSymNum++ == IRGraph::BlackHole && "Something changed!");
93
94 // Object #3 always represents the unique constant of a program (merging all constants if Options::ModelConsts is disabled)
95 assert(svfir->totalSymNum++ == IRGraph::ConstantObj && "Something changed!");
97
99 {
100 // Add symbols for all the globals .
101 for (const GlobalVariable& gv : M.globals())
102 {
103 collectSym(&gv);
104 }
105
106 // Add symbols for all the global aliases
107 for (const GlobalAlias& ga : M.aliases())
108 {
109 collectSym(&ga);
110 collectSym(ga.getAliasee());
111 }
112
113 // Add symbols for all of the functions and the instructions in them.
114 for (const Function& fun : M.functions())
115 {
116 collectSym(&fun);
117 collectRet(&fun);
118 if (fun.getFunctionType()->isVarArg())
119 collectVararg(&fun);
120
121 // Add symbols for all formal parameters.
122 for (const Argument& arg : fun.args())
123 {
124 collectSym(&arg);
125 }
126
127 // collect and create symbols inside the function body
128 for (const Instruction& inst : instructions(fun))
129 {
130 collectSym(&inst);
131
132 // initialization for some special instructions
133 //{@
134 if (const StoreInst* st = SVFUtil::dyn_cast<StoreInst>(&inst))
135 {
136 collectSym(st->getPointerOperand());
137 collectSym(st->getValueOperand());
138 }
139 else if (const LoadInst* ld =
140 SVFUtil::dyn_cast<LoadInst>(&inst))
141 {
142 collectSym(ld->getPointerOperand());
143 }
144 else if (const AllocaInst* alloc =
145 SVFUtil::dyn_cast<AllocaInst>(&inst))
146 {
147 collectSym(alloc->getArraySize());
148 }
149 else if (const PHINode* phi = SVFUtil::dyn_cast<PHINode>(&inst))
150 {
151 for (u32_t i = 0; i < phi->getNumIncomingValues(); ++i)
152 {
153 collectSym(phi->getIncomingValue(i));
154 }
155 }
156 else if (const GetElementPtrInst* gep =
157 SVFUtil::dyn_cast<GetElementPtrInst>(&inst))
158 {
159 collectSym(gep->getPointerOperand());
160 for (u32_t i = 0; i < gep->getNumOperands(); ++i)
161 {
162 collectSym(gep->getOperand(i));
163 }
164 }
165 else if (const SelectInst* sel =
166 SVFUtil::dyn_cast<SelectInst>(&inst))
167 {
168 collectSym(sel->getTrueValue());
169 collectSym(sel->getFalseValue());
170 collectSym(sel->getCondition());
171 }
172 else if (const BinaryOperator* binary =
173 SVFUtil::dyn_cast<BinaryOperator>(&inst))
174 {
175 for (u32_t i = 0; i < binary->getNumOperands(); i++)
176 collectSym(binary->getOperand(i));
177 }
178 else if (const UnaryOperator* unary =
179 SVFUtil::dyn_cast<UnaryOperator>(&inst))
180 {
181 for (u32_t i = 0; i < unary->getNumOperands(); i++)
182 collectSym(unary->getOperand(i));
183 }
184 else if (const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(&inst))
185 {
186 for (u32_t i = 0; i < cmp->getNumOperands(); i++)
187 collectSym(cmp->getOperand(i));
188 }
189 else if (const CastInst* cast =
190 SVFUtil::dyn_cast<CastInst>(&inst))
191 {
192 collectSym(cast->getOperand(0));
193 }
194 else if (const ReturnInst* ret =
195 SVFUtil::dyn_cast<ReturnInst>(&inst))
196 {
197 if (ret->getReturnValue())
198 collectSym(ret->getReturnValue());
199 }
200 else if (const BranchInst* br =
201 SVFUtil::dyn_cast<BranchInst>(&inst))
202 {
203 Value* opnd = br->isConditional() ? br->getCondition() : br->getOperand(0);
205 }
206 else if (const SwitchInst* sw =
207 SVFUtil::dyn_cast<SwitchInst>(&inst))
208 {
209 collectSym(sw->getCondition());
210 }
211 else if (const FreezeInst* fz = SVFUtil::dyn_cast<FreezeInst>(&inst))
212 {
213
214 for (u32_t i = 0; i < fz->getNumOperands(); i++)
215 {
216 Value* opnd = inst.getOperand(i);
218 }
219 }
220 else if (isNonInstricCallSite(&inst))
221 {
222
223 const CallBase* cs = LLVMUtil::getLLVMCallSite(&inst);
224 for (u32_t i = 0; i < cs->arg_size(); i++)
225 {
226 collectSym(cs->getArgOperand(i));
227 }
228 // Calls to inline asm need to be added as well because the
229 // callee isn't referenced anywhere else.
230 const Value* Callee = cs->getCalledOperand();
232
233 // TODO handle inlineAsm
236 {
238 }
239 }
241 }
242 }
243 }
244
247 {
249 }
250}
251
253{
254 Type *valType = val->getType();
256 if(isGepConstantExpr(val) || SVFUtil::isa<GetElementPtrInst>(val))
257 {
259 gi = bridge_gep_begin(SVFUtil::cast<User>(val)),
260 ge = bridge_gep_end(SVFUtil::cast<User>(val));
261 gi != ge; ++gi)
262 {
263 const Type* gepTy = *gi;
265 }
266 }
267}
268
273{
274
275 //TODO: filter the non-pointer type // if (!SVFUtil::isa<PointerType>(val->getType())) return;
276
278 outs() << "collect sym from ##" << LLVMUtil::dumpValue(val) << "\n");
279 //TODO handle constant expression value here??
280 handleCE(val);
281
282 // create a value sym
284
287
288 // create an object If it is a heap, stack, global, function.
289 if (isObject(val))
290 {
292 }
293}
294
299{
300 // collect and record special sym here
301 if (
304 SVFUtil::isa<BasicBlock>(val)
305 )
306 {
307 return;
308 }
309
310 LLVMModuleSet::ValueToIDMapTy::iterator iter = llvmModuleSet()->valSymMap.find(val);
311 if (iter == llvmModuleSet()->valSymMap.end())
312 {
313 // create val sym and sym type
315 llvmModuleSet()->valSymMap.insert(std::make_pair(val, id));
317 outs() << "create a new value sym " << id << "\n");
319 if (const GlobalVariable* globalVar = SVFUtil::dyn_cast<GlobalVariable>(val))
321 }
322
325}
326
331{
333 LLVMModuleSet::ValueToIDMapTy::iterator iter = llvmModuleSet()->objSymMap.find(val);
334 if (iter == llvmModuleSet()->objSymMap.end())
335 {
336 // if the object pointed by the pointer is a constant data (e.g., i32 0) or a global constant object (e.g. string)
337 // then we treat them as one ConstantObj
338 // the IR features can't be modelled, like Blockaddress still maps to the ConstantObj
339 const bool mcUnmodelled = isConstDataOrAggData(val) && val->getType()->isPointerTy();
341 {
342 llvmModuleSet()->objSymMap.insert(std::make_pair(val, svfir->constantSymID()));
343 }
344 // otherwise, we will create an object for each abstract memory location
345 else
346 {
347 // create obj sym and sym type
349 llvmModuleSet()->objSymMap.insert(std::make_pair(val, id));
351 outs() << "create a new obj sym " << id << "\n");
352
353 // create a memory object
355 assert(svfir->objTypeInfoMap.find(id) == svfir->objTypeInfoMap.end());
356 svfir->objTypeInfoMap[id] = ti;
357 }
358 }
359}
360
365{
366
367 LLVMModuleSet::FunToIDMapTy::iterator iter =
369 if (iter == llvmModuleSet()->returnSymMap.end())
370 {
372 llvmModuleSet()->returnSymMap.insert(std::make_pair(val, id));
373 DBOUT(DMemModel, outs() << "create a return sym " << id << "\n");
374 }
375}
376
381{
382 LLVMModuleSet::FunToIDMapTy::iterator iter =
384 if (iter == llvmModuleSet()->varargSymMap.end())
385 {
387 llvmModuleSet()->varargSymMap.insert(std::make_pair(val, id));
388 DBOUT(DMemModel, outs() << "create a vararg sym " << id << "\n");
389 }
390}
391
396{
397 if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
398 {
399 if (const ConstantExpr* ce = isGepConstantExpr(ref))
400 {
401 DBOUT(DMemModelCE, outs() << "handle constant expression "
402 << LLVMUtil::dumpValue(ref) << "\n");
403 collectVal(ce);
404
405 // handle the recursive constant express case
406 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
407 for (u32_t i = 0; i < ce->getNumOperands(); ++i)
408 {
409 collectVal(ce->getOperand(i));
410 handleCE(ce->getOperand(i));
411 }
412 }
413 else if (const ConstantExpr* ce = isCastConstantExpr(ref))
414 {
415 DBOUT(DMemModelCE, outs() << "handle constant expression "
416 << LLVMUtil::dumpValue(ref) << "\n");
417 collectVal(ce);
418 collectVal(ce->getOperand(0));
419 // handle the recursive constant express case
420 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
421 handleCE(ce->getOperand(0));
422 }
423 else if (const ConstantExpr* ce = isSelectConstantExpr(ref))
424 {
425 DBOUT(DMemModelCE, outs() << "handle constant expression "
426 << LLVMUtil::dumpValue(ref) << "\n");
427 collectVal(ce);
428 collectVal(ce->getOperand(0));
429 collectVal(ce->getOperand(1));
430 collectVal(ce->getOperand(2));
431 // handle the recursive constant express case
432 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
433 handleCE(ce->getOperand(0));
434 handleCE(ce->getOperand(1));
435 handleCE(ce->getOperand(2));
436 }
437 // if we meet a int2ptr, then it points-to black hole
439 {
441 const Constant* opnd = int2Ptrce->getOperand(0);
442 handleCE(opnd);
443 }
445 {
447 const Constant* opnd = ptr2Intce->getOperand(0);
448 handleCE(opnd);
449 }
451 {
453 }
454 else if (isBinaryConstantExpr(ref))
455 {
457 }
458 else if (isUnaryConstantExpr(ref))
459 {
460 // we don't handle unary constant expression like fneg(x) now
462 }
463 else if (SVFUtil::isa<ConstantAggregate>(ref))
464 {
465 // we don't handle constant aggregate like constant vectors
467 }
468 else
469 {
470 assert(!SVFUtil::isa<ConstantExpr>(val) &&
471 "we don't handle all other constant expression for now!");
473 }
474 }
475}
476
481{
482 assert(G);
483
484 //The type this global points to
485 const Type* T = G->getValueType();
486 bool is_array = 0;
487 //An array is considered a single variable of its type.
488 while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(T))
489 {
490 T = AT->getElementType();
491 is_array = true;
492 }
493
494 if (SVFUtil::isa<StructType>(T))
495 {
496 //A struct may be used in constant GEP expr.
497 for (const User* user : G->users())
498 {
499 handleCE(user);
500 }
501 }
502 else if (is_array)
503 {
504 for (const User* user : G->users())
505 {
506 handleCE(user);
507 }
508 }
509
510 if (G->hasInitializer())
511 {
512 handleGlobalInitializerCE(G->getInitializer());
513 }
514}
515
520{
521
522 if (C->getType()->isSingleValueType())
523 {
524 if (const ConstantExpr* E = SVFUtil::dyn_cast<ConstantExpr>(C))
525 {
526 handleCE(E);
527 }
528 else
529 {
530 collectVal(C);
531 }
532 }
533 else if (SVFUtil::isa<ConstantArray>(C))
534 {
535 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
536 {
537 handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
538 }
539 }
540 else if (SVFUtil::isa<ConstantStruct>(C))
541 {
542 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
543 {
544 handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
545 }
546 }
547 else if(const ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
548 {
550 {
551 if (const ConstantDataSequential* seq =
552 SVFUtil::dyn_cast<ConstantDataSequential>(data))
553 {
554 for(u32_t i = 0; i < seq->getNumElements(); i++)
555 {
556 const Constant* ct = seq->getElementAsConstant(i);
558 }
559 }
560 else
561 {
562 assert(
563 (SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) &&
564 "Single value type data should have been handled!");
565 }
566 }
567 }
568 else
569 {
570 //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
571 }
572}
573
578
579
584
589{
590 const Value* startValue = inst;
591 const PointerType *originalPType = SVFUtil::dyn_cast<PointerType>(inst->getType());
592 const Type* inferedType = nullptr;
593 assert(originalPType && "empty type?");
595 {
596 if(const Value* v = getFirstUseViaCastInst(inst))
597 {
598 if (const PointerType *newTy = SVFUtil::dyn_cast<PointerType>(v->getType()))
599 {
601 }
602 }
604 }
606 {
607 const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
608 u32_t arg_pos = LLVMUtil::getHeapAllocHoldingArgPosition(cs->getCalledFunction());
609 const Value* arg = cs->getArgOperand(arg_pos);
610 originalPType = SVFUtil::dyn_cast<PointerType>(arg->getType());
612 }
613 else
614 {
615 assert( false && "not a heap allocation instruction?");
616 }
617
619
620 return inferedType;
621}
622
623/*
624 * Initial the memory object here
625 */
627{
628 const Type* objTy = nullptr;
629
630 const Instruction* I = SVFUtil::dyn_cast<Instruction>(val);
631
632 // We consider two types of objects:
633 // (1) A heap/static object from a callsite
634 if (I && isNonInstricCallSite(I))
635 {
637 }
638 // (2) Other objects (e.g., alloca, global, etc.)
639 else
640 {
641 if (SVFUtil::isa<PointerType>(val->getType()))
642 {
643 if (const AllocaInst *allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
644 {
645 // get the type of the allocated memory
646 // e.g., for `%retval = alloca i64, align 4`, we return i64
647 objTy = allocaInst->getAllocatedType();
648 }
649 else if (const GlobalValue *global = SVFUtil::dyn_cast<GlobalValue>(val))
650 {
651 // get the pointee type of the global pointer (begins with @ symbol in llvm)
652 objTy = global->getValueType();
653 }
654 else
655 {
657 assert(false && "not an allocation or global?");
658 }
659 }
660 }
661
662 if (objTy)
663 {
665 ObjTypeInfo* typeInfo = new ObjTypeInfo(
666 llvmModuleSet()->getSVFType(objTy),
668 initTypeInfo(typeInfo,val, objTy);
669 return typeInfo;
670 }
671 else
672 {
673 writeWrnMsg("try to create an object with a non-pointer type.");
674 writeWrnMsg(val->getName().str());
675 writeWrnMsg("(" + getSourceLoc(val) + ")");
677 {
678 ObjTypeInfo* typeInfo = new ObjTypeInfo(
679 llvmModuleSet()->getSVFType(val->getType()),
680 0);
681 initTypeInfo(typeInfo,val, val->getType());
682 return typeInfo;
683 }
684 else
685 {
686 assert(false && "Memory object must be either (1) held by a pointer-typed ref value or (2) a constant value (e.g., 10).");
687 abort();
688 }
689 }
690}
691
696{
697 const Type *elemTy = llvmModuleSet()->getLLVMType(typeinfo->getType());
698 // Find the inter nested array element
699 while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(elemTy))
700 {
701 elemTy = AT->getElementType();
702 if (SVFUtil::isa<GlobalVariable>(val) &&
703 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
704 SVFUtil::isa<ConstantArray>(
705 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
707 else
709 }
710 if (SVFUtil::isa<StructType>(elemTy))
711 {
712 if (SVFUtil::isa<GlobalVariable>(val) &&
713 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
714 SVFUtil::isa<ConstantStruct>(
715 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
717 else
719 }
720}
721
737{
738 if(const llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(val))
739 {
740 if (const llvm::Function* calledFunction =
741 callInst->getCalledFunction())
742 {
743 std::vector<const Value*> args;
744 // Heap alloc functions have annoation like "AllocSize:Arg1"
746 {
747 if (annotation.find("AllocSize:") != std::string::npos)
748 {
749 std::string allocSize = annotation.substr(10);
750 std::stringstream ss(allocSize);
751 std::string token;
752 // Analyaze annotation string and attract Arg list
753 while (std::getline(ss, token, '*'))
754 {
755 if (token.rfind("Arg", 0) == 0)
756 {
758 std::istringstream(token.substr(3)) >> argIndex;
760 {
761 args.push_back(
762 callInst->getArgOperand(argIndex));
763 }
764 }
765 }
766 }
767 }
768 u64_t product = 1;
769 if (args.size() > 0)
770 {
771 // for annotations like "AllocSize:Arg0*Arg1"
772 for (const llvm::Value* arg : args)
773 {
774 if (const llvm::ConstantInt* constIntArg =
775 llvm::dyn_cast<llvm::ConstantInt>(arg))
776 {
777 // Multiply the constant Value if all Args are const
779 }
780 else
781 {
782 // if Arg list has non-const value, return 0 to indicate it is non const byte size
783 return 0;
784 }
785 }
786 // If all the Args are const, return product
787 return product;
788 }
789 else
790 {
791 // for annotations like "AllocSize:UNKNOWN"
792 return 0;
793 }
794 }
795 }
796 // if it is not CallInst or CallInst has no CalledFunction, return 0 to indicate it is non const byte size
797 return 0;
798}
799
804{
806 analyzeObjType(typeinfo, val);
807 const Type* objTy = llvmModuleSet()->getLLVMType(typeinfo->getType());
808 if(SVFUtil::isa<ArrayType>(objTy))
809 return getNumOfElements(objTy);
810 else if(const StructType* st = SVFUtil::dyn_cast<StructType>(objTy))
811 {
815 typeinfo->resetTypeForHeapStaticObj(llvmModuleSet()->getSVFType(
816 llvmModuleSet()->getTypeInference()->ptrType()));
817 else
818 return getNumOfElements(objTy);
819 }
820 return typeinfo->getMaxFieldOffsetLimit();
821}
822
827{
829 {
831 analyzeObjType(typeinfo,castUse);
832 }
833 else
834 {
836 }
837}
838
843 const Type* objTy)
844{
845
846 u32_t elemNum = 1;
847 // init byteSize = 0, If byteSize is changed in the following process,
848 // it means that ObjTypeInfo has a Constant Byte Size
849 u32_t byteSize = 0;
850 // Global variable
851 // if val is Function Obj, byteSize is not set
852 if (SVFUtil::isa<Function>(val))
853 {
855 analyzeObjType(typeinfo,val);
856 elemNum = 0;
857 }
860 else if(const AllocaInst* allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
861 {
863 analyzeObjType(typeinfo,val);
866 if(const ConstantInt* sz = SVFUtil::dyn_cast<ConstantInt>(allocaInst->getArraySize()))
867 {
869 byteSize = LLVMUtil::getIntegerValue(sz).second * typeinfo->getType()->getByteSize();
870 }
872 else
873 {
874 elemNum = getNumOfElements(objTy);
875 byteSize = 0;
876 }
877 }
880 else if(SVFUtil::isa<GlobalVariable>(val))
881 {
885 analyzeObjType(typeinfo,val);
886 elemNum = getNumOfElements(objTy);
887 byteSize = typeinfo->getType()->getByteSize();
888 }
890 else if (SVFUtil::isa<Instruction>(val) &&
892 SVFUtil::cast<Instruction>(val)))
893 {
894 elemNum = analyzeHeapObjType(typeinfo,val);
895 // analyze heap alloc like (malloc/calloc/...), the alloc functions have
896 // annotation like "AllocSize:Arg1". Please refer to extapi.c.
897 // e.g. calloc(4, 10), annotation is "AllocSize:Arg0*Arg1",
898 // it means byteSize = 4 (Arg0) * 10 (Arg1) = 40
899 byteSize = analyzeHeapAllocByteSize(val);
900 }
902 {
903 analyzeStaticObjType(typeinfo,val);
904 // user input data, label its field as infinite here
905 elemNum = typeinfo->getMaxFieldOffsetLimit();
906 byteSize = typeinfo->getType()->getByteSize();
907 }
909 {
911 elemNum = getNumOfFlattenElements(val->getType());
912 byteSize = typeinfo->getType()->getByteSize();
913 }
914 else
915 {
916 assert("what other object do we have??");
917 abort();
918 }
919
920 // Reset maxOffsetLimit if it is over the total fieldNum of this object
921 if(typeinfo->getMaxFieldOffsetLimit() > elemNum)
922 typeinfo->setNumOfElements(elemNum);
923
924 // set ByteSize. If ByteSize > 0, this typeinfo has constant type.
925 // If ByteSize == 0, this typeinfo has 1) zero byte 2) non-const byte size
926 // If ByteSize>MaxFieldLimit, set MaxFieldLimit to the byteSize;
927 byteSize = Options::MaxFieldLimit() > byteSize? byteSize: Options::MaxFieldLimit();
928 typeinfo->setByteSizeOfObj(byteSize);
929}
930
935{
936 assert(ety && "type is null?");
937 u32_t numOfFields = 1;
938 if (SVFUtil::isa<StructType, ArrayType>(ety))
939 {
941 }
942 return numOfFields;
943}
944
953
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DMemModelCE
Definition SVFType.h:586
#define DMemModel
Definition SVFType.h:585
NodeID constantSymID() const
Definition IRGraph.h:192
ObjTypeInfo * createObjTypeInfo(const SVFType *type)
Create an objectInfo based on LLVM type (value is null, and type could be null, representing a dummy ...
Definition IRGraph.cpp:248
static bool isBlkObj(NodeID id)
Definition IRGraph.h:164
IDToTypeInfoMapTy objTypeInfoMap
map a memory sym id to its obj
Definition IRGraph.h:86
NodeID totalSymNum
total number of symbols
Definition IRGraph.h:99
static bool isConstantSym(NodeID id)
Definition IRGraph.h:173
ValueToIDMapTy valSymMap
map a value to its sym id
Definition LLVMModule.h:120
FunToIDMapTy varargSymMap
vararg map
Definition LLVMModule.h:123
const std::vector< std::string > & getExtFuncAnnotations(const Function *fun)
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
const Type * getLLVMType(const SVFType *T) const
Get LLVM Type.
ValueToIDMapTy objSymMap
map a obj reference to its sym id
Definition LLVMModule.h:121
FunToIDMapTy returnSymMap
return map
Definition LLVMModule.h:122
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:164
ObjTypeInference * getTypeInference()
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.
void typeSizeDiffTest(const PointerType *oPTy, const Type *iTy, const Value *val)
const Type * inferObjType(const Value *var)
get or infer the type of the object pointed by the value
void validateTypeCheck(const CallBase *cs)
validate type inference
void resetTypeForHeapStaticObj(const SVFType *t)
Definition ObjTypeInfo.h:79
u32_t getMaxFieldOffsetLimit()
Get max field offset limit.
const SVFType * getType() const
Get LLVM type.
Definition ObjTypeInfo.h:98
void setByteSizeOfObj(u32_t size)
Set the byte size of this object.
void setFlag(MEMTYPE mask)
Flag for this object type.
void setNumOfElements(u32_t num)
Set the number of elements of this object.
static Option< bool > ModelArrays
Definition Options.h:179
static const Option< bool > EnableTypeCheck
Definition Options.h:128
static const Option< bool > SymTabPrint
Definition Options.h:181
static Option< bool > ModelConsts
Definition Options.h:178
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:34
StInfo * getTypeInfo()
Definition SVFType.h:273
u32_t getByteSize() const
Definition SVFType.h:287
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition SVFType.h:164
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition SVFType.h:170
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
LLVMModuleSet * llvmModuleSet()
ObjTypeInference * getTypeInference()
ObjTypeInfo * createBlkObjTypeInfo(NodeID 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.
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 buildMemModel()
Start building memory model.
ObjTypeInfo * createConstantObjTypeInfo(NodeID symId)
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 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.
bool isHeapAllocExtCallViaRet(const Instruction *inst)
Definition LLVMUtil.cpp:649
const Value * getFirstUseViaCastInst(const Value *val)
Definition LLVMUtil.cpp:279
const CallBase * getLLVMCallSite(const Value *value)
Return LLVM callsite given a value.
Definition LLVMUtil.h:108
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition LLVMUtil.h:310
bool isHeapAllocExtCall(const Instruction *inst)
Definition LLVMUtil.h:443
bool isConstantObjSym(const Value *val)
Check whether this value points-to a constant object.
Definition CppUtil.cpp:684
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:245
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:275
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition LLVMUtil.h:285
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:99
bool isNullPtrSym(const Value *val)
Check whether this value is a black hole.
Definition LLVMUtil.h:143
std::string dumpValueAndDbgInfo(const Value *val)
Definition LLVMUtil.cpp:638
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition LLVMUtil.h:415
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:454
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:255
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:441
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:321
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:265
bool isBlackholeSym(const Value *val)
Check whether this value is a black hole.
Definition LLVMUtil.h:137
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition LLVMUtil.cpp:664
bool isObject(const Value *ref)
Return true if this value refers to a object.
Definition LLVMUtil.cpp:61
bool ArgInProgEntryFunction(const Value *val)
Return true if this is an argument of a program entry function (e.g. main)
Definition LLVMUtil.h:184
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition LLVMUtil.h:235
u32_t getHeapAllocHoldingArgPosition(const Function *fun)
Definition LLVMUtil.cpp:402
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:736
std::string dumpValue(const Value *val)
Definition LLVMUtil.cpp:616
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:299
void increaseStackSize()
Increase the stack size limit.
Definition SVFUtil.cpp:249
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
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:64
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:88
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:58
bool classTyHasVTable(const StructType *ty)
Definition CppUtil.cpp:581
for isBitcode
Definition BasicTypes.h:70
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:137
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:135
llvm::ArrayType ArrayType
Definition BasicTypes.h:99
llvm::Type Type
Definition BasicTypes.h:87
llvm::CallBase CallBase
Definition BasicTypes.h:153
llvm::UnaryOperator UnaryOperator
Definition BasicTypes.h:187
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:98
unsigned long long u64_t
Definition GeneralType.h:69
llvm::AllocaInst AllocaInst
Definition BasicTypes.h:157
llvm::SwitchInst SwitchInst
Definition BasicTypes.h:162
u32_t NodeID
Definition GeneralType.h:76
llvm::Argument Argument
Definition BasicTypes.h:152
llvm::LoadInst LoadInst
Definition BasicTypes.h:156
llvm::CmpInst CmpInst
Definition BasicTypes.h:166
llvm::Function Function
Definition BasicTypes.h:89
llvm::GlobalValue GlobalValue
Definition BasicTypes.h:92
llvm::ConstantData ConstantData
Definition BasicTypes.h:120
llvm::Instruction Instruction
Definition BasicTypes.h:91
llvm::Constant Constant
Definition BasicTypes.h:128
llvm::ConstantDataSequential ConstantDataSequential
Definition BasicTypes.h:123
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:86
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:124
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
llvm::CastInst CastInst
Definition BasicTypes.h:165
llvm::FreezeInst FreezeInst
Definition BasicTypes.h:176
llvm::Module Module
Definition BasicTypes.h:88
llvm::PointerType PointerType
Definition BasicTypes.h:100
llvm::BinaryOperator BinaryOperator
Definition BasicTypes.h:186
llvm::StoreInst StoreInst
Definition BasicTypes.h:155
llvm::SelectInst SelectInst
Definition BasicTypes.h:181
llvm::GetElementPtrInst GetElementPtrInst
Definition BasicTypes.h:169
llvm::ReturnInst ReturnInst
Definition BasicTypes.h:164
llvm::PHINode PHINode
Definition BasicTypes.h:172
llvm::BranchInst BranchInst
Definition BasicTypes.h:161
unsigned u32_t
Definition GeneralType.h:67
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:129
llvm::User User
Definition BasicTypes.h:149