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
302 {
303 return;
304 }
305 LLVMModuleSet::ValueToIDMapTy::iterator iter = llvmModuleSet()->valSymMap.find(val);
306 if (iter == llvmModuleSet()->valSymMap.end())
307 {
308 // create val sym and sym type
310 llvmModuleSet()->valSymMap.insert(std::make_pair(val, id));
312 outs() << "create a new value sym " << id << "\n");
314 if (const GlobalVariable* globalVar = SVFUtil::dyn_cast<GlobalVariable>(val))
316 }
317
320}
321
326{
328 LLVMModuleSet::ValueToIDMapTy::iterator iter = llvmModuleSet()->objSymMap.find(val);
329 if (iter == llvmModuleSet()->objSymMap.end())
330 {
331 // if the object pointed by the pointer is a constant data (e.g., i32 0) or a global constant object (e.g. string)
332 // then we treat them as one ConstantObj
334 {
335 llvmModuleSet()->objSymMap.insert(std::make_pair(val, svfir->constantSymID()));
336 }
337 // otherwise, we will create an object for each abstract memory location
338 else
339 {
340 // create obj sym and sym type
342 llvmModuleSet()->objSymMap.insert(std::make_pair(val, id));
344 outs() << "create a new obj sym " << id << "\n");
345
346 // create a memory object
348 assert(svfir->objTypeInfoMap.find(id) == svfir->objTypeInfoMap.end());
349 svfir->objTypeInfoMap[id] = ti;
350 }
351 }
352}
353
358{
359
360 LLVMModuleSet::FunToIDMapTy::iterator iter =
362 if (iter == llvmModuleSet()->returnSymMap.end())
363 {
365 llvmModuleSet()->returnSymMap.insert(std::make_pair(val, id));
366 DBOUT(DMemModel, outs() << "create a return sym " << id << "\n");
367 }
368}
369
374{
375 LLVMModuleSet::FunToIDMapTy::iterator iter =
377 if (iter == llvmModuleSet()->varargSymMap.end())
378 {
380 llvmModuleSet()->varargSymMap.insert(std::make_pair(val, 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 "
395 << LLVMUtil::dumpValue(ref) << "\n");
396 collectVal(ce);
397
398 // handle the recursive constant express case
399 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
400 for (u32_t i = 0; i < ce->getNumOperands(); ++i)
401 {
402 collectVal(ce->getOperand(i));
403 handleCE(ce->getOperand(i));
404 }
405 }
406 else if (const ConstantExpr* ce = isCastConstantExpr(ref))
407 {
408 DBOUT(DMemModelCE, outs() << "handle constant expression "
409 << LLVMUtil::dumpValue(ref) << "\n");
410 collectVal(ce);
411 collectVal(ce->getOperand(0));
412 // handle the recursive constant express case
413 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
414 handleCE(ce->getOperand(0));
415 }
416 else if (const ConstantExpr* ce = isSelectConstantExpr(ref))
417 {
418 DBOUT(DMemModelCE, outs() << "handle constant expression "
419 << LLVMUtil::dumpValue(ref) << "\n");
420 collectVal(ce);
421 collectVal(ce->getOperand(0));
422 collectVal(ce->getOperand(1));
423 collectVal(ce->getOperand(2));
424 // handle the recursive constant express case
425 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
426 handleCE(ce->getOperand(0));
427 handleCE(ce->getOperand(1));
428 handleCE(ce->getOperand(2));
429 }
430 // if we meet a int2ptr, then it points-to black hole
432 {
434 const Constant* opnd = int2Ptrce->getOperand(0);
435 handleCE(opnd);
436 }
438 {
440 const Constant* opnd = ptr2Intce->getOperand(0);
441 handleCE(opnd);
442 }
444 {
446 }
447 else if (isBinaryConstantExpr(ref))
448 {
450 }
451 else if (isUnaryConstantExpr(ref))
452 {
453 // we don't handle unary constant expression like fneg(x) now
455 }
456 else if (SVFUtil::isa<ConstantAggregate>(ref))
457 {
458 // we don't handle constant aggregate like constant vectors
460 }
461 else
462 {
463 assert(!SVFUtil::isa<ConstantExpr>(val) &&
464 "we don't handle all other constant expression for now!");
466 }
467 }
468}
469
474{
475 assert(G);
476
477 //The type this global points to
478 const Type* T = G->getValueType();
479 bool is_array = 0;
480 //An array is considered a single variable of its type.
481 while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(T))
482 {
483 T = AT->getElementType();
484 is_array = true;
485 }
486
487 if (SVFUtil::isa<StructType>(T))
488 {
489 //A struct may be used in constant GEP expr.
490 for (const User* user : G->users())
491 {
492 handleCE(user);
493 }
494 }
495 else if (is_array)
496 {
497 for (const User* user : G->users())
498 {
499 handleCE(user);
500 }
501 }
502
503 if (G->hasInitializer())
504 {
505 handleGlobalInitializerCE(G->getInitializer());
506 }
507}
508
513{
514
515 if (C->getType()->isSingleValueType())
516 {
517 if (const ConstantExpr* E = SVFUtil::dyn_cast<ConstantExpr>(C))
518 {
519 handleCE(E);
520 }
521 else
522 {
523 collectVal(C);
524 }
525 }
526 else if (SVFUtil::isa<ConstantArray>(C))
527 {
528 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
529 {
530 handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
531 }
532 }
533 else if (SVFUtil::isa<ConstantStruct>(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(const ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
541 {
543 {
544 if (const ConstantDataSequential* seq =
545 SVFUtil::dyn_cast<ConstantDataSequential>(data))
546 {
547 for(u32_t i = 0; i < seq->getNumElements(); i++)
548 {
549 const Constant* ct = seq->getElementAsConstant(i);
551 }
552 }
553 else
554 {
555 assert(
556 (SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) &&
557 "Single value type data should have been handled!");
558 }
559 }
560 }
561 else
562 {
563 //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
564 }
565}
566
571
572
577
582{
583 const Value* startValue = inst;
584 const PointerType *originalPType = SVFUtil::dyn_cast<PointerType>(inst->getType());
585 const Type* inferedType = nullptr;
586 assert(originalPType && "empty type?");
588 {
589 if(const Value* v = getFirstUseViaCastInst(inst))
590 {
591 if (const PointerType *newTy = SVFUtil::dyn_cast<PointerType>(v->getType()))
592 {
594 }
595 }
597 }
599 {
600 const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
601 u32_t arg_pos = LLVMUtil::getHeapAllocHoldingArgPosition(cs->getCalledFunction());
602 const Value* arg = cs->getArgOperand(arg_pos);
603 originalPType = SVFUtil::dyn_cast<PointerType>(arg->getType());
605 }
606 else
607 {
608 assert( false && "not a heap allocation instruction?");
609 }
610
612
613 return inferedType;
614}
615
616/*
617 * Initial the memory object here
618 */
620{
621 const Type* objTy = nullptr;
622
623 const Instruction* I = SVFUtil::dyn_cast<Instruction>(val);
624
625 // We consider two types of objects:
626 // (1) A heap/static object from a callsite
627 if (I && isNonInstricCallSite(I))
628 {
630 }
631 // (2) Other objects (e.g., alloca, global, etc.)
632 else
633 {
634 if (SVFUtil::isa<PointerType>(val->getType()))
635 {
636 if (const AllocaInst *allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
637 {
638 // get the type of the allocated memory
639 // e.g., for `%retval = alloca i64, align 4`, we return i64
640 objTy = allocaInst->getAllocatedType();
641 }
642 else if (const GlobalValue *global = SVFUtil::dyn_cast<GlobalValue>(val))
643 {
644 // get the pointee type of the global pointer (begins with @ symbol in llvm)
645 objTy = global->getValueType();
646 }
647 else
648 {
650 assert(false && "not an allocation or global?");
651 }
652 }
653 }
654
655 if (objTy)
656 {
658 ObjTypeInfo* typeInfo = new ObjTypeInfo(
659 llvmModuleSet()->getSVFType(objTy),
661 initTypeInfo(typeInfo,val, objTy);
662 return typeInfo;
663 }
664 else
665 {
666 writeWrnMsg("try to create an object with a non-pointer type.");
667 writeWrnMsg(val->getName().str());
668 writeWrnMsg("(" + getSourceLoc(val) + ")");
670 {
671 ObjTypeInfo* typeInfo = new ObjTypeInfo(
672 llvmModuleSet()->getSVFType(val->getType()),
673 0);
674 initTypeInfo(typeInfo,val, val->getType());
675 return typeInfo;
676 }
677 else
678 {
679 assert(false && "Memory object must be either (1) held by a pointer-typed ref value or (2) a constant value (e.g., 10).");
680 abort();
681 }
682 }
683}
684
689{
690 const Type *elemTy = llvmModuleSet()->getLLVMType(typeinfo->getType());
691 // Find the inter nested array element
692 while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(elemTy))
693 {
694 elemTy = AT->getElementType();
695 if (SVFUtil::isa<GlobalVariable>(val) &&
696 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
697 SVFUtil::isa<ConstantArray>(
698 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
700 else
702 }
703 if (SVFUtil::isa<StructType>(elemTy))
704 {
705 if (SVFUtil::isa<GlobalVariable>(val) &&
706 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
707 SVFUtil::isa<ConstantStruct>(
708 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
710 else
712 }
713}
714
730{
731 if(const llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(val))
732 {
733 if (const llvm::Function* calledFunction =
734 callInst->getCalledFunction())
735 {
736 std::vector<const Value*> args;
737 // Heap alloc functions have annoation like "AllocSize:Arg1"
739 {
740 if (annotation.find("AllocSize:") != std::string::npos)
741 {
742 std::string allocSize = annotation.substr(10);
743 std::stringstream ss(allocSize);
744 std::string token;
745 // Analyaze annotation string and attract Arg list
746 while (std::getline(ss, token, '*'))
747 {
748 if (token.rfind("Arg", 0) == 0)
749 {
751 std::istringstream(token.substr(3)) >> argIndex;
753 {
754 args.push_back(
755 callInst->getArgOperand(argIndex));
756 }
757 }
758 }
759 }
760 }
761 u64_t product = 1;
762 if (args.size() > 0)
763 {
764 // for annotations like "AllocSize:Arg0*Arg1"
765 for (const llvm::Value* arg : args)
766 {
767 if (const llvm::ConstantInt* constIntArg =
768 llvm::dyn_cast<llvm::ConstantInt>(arg))
769 {
770 // Multiply the constant Value if all Args are const
772 }
773 else
774 {
775 // if Arg list has non-const value, return 0 to indicate it is non const byte size
776 return 0;
777 }
778 }
779 // If all the Args are const, return product
780 return product;
781 }
782 else
783 {
784 // for annotations like "AllocSize:UNKNOWN"
785 return 0;
786 }
787 }
788 }
789 // if it is not CallInst or CallInst has no CalledFunction, return 0 to indicate it is non const byte size
790 return 0;
791}
792
797{
799 analyzeObjType(typeinfo, val);
800 const Type* objTy = llvmModuleSet()->getLLVMType(typeinfo->getType());
801 if(SVFUtil::isa<ArrayType>(objTy))
802 return getNumOfElements(objTy);
803 else if(const StructType* st = SVFUtil::dyn_cast<StructType>(objTy))
804 {
808 typeinfo->resetTypeForHeapStaticObj(llvmModuleSet()->getSVFType(
809 llvmModuleSet()->getTypeInference()->ptrType()));
810 else
811 return getNumOfElements(objTy);
812 }
813 return typeinfo->getMaxFieldOffsetLimit();
814}
815
820{
822 {
824 analyzeObjType(typeinfo,castUse);
825 }
826 else
827 {
829 }
830}
831
836 const Type* objTy)
837{
838
839 u32_t elemNum = 1;
840 // init byteSize = 0, If byteSize is changed in the following process,
841 // it means that ObjTypeInfo has a Constant Byte Size
842 u32_t byteSize = 0;
843 // Global variable
844 // if val is Function Obj, byteSize is not set
845 if (SVFUtil::isa<Function>(val))
846 {
848 analyzeObjType(typeinfo,val);
849 elemNum = 0;
850 }
853 else if(const AllocaInst* allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
854 {
856 analyzeObjType(typeinfo,val);
859 if(const ConstantInt* sz = SVFUtil::dyn_cast<ConstantInt>(allocaInst->getArraySize()))
860 {
862 byteSize = LLVMUtil::getIntegerValue(sz).second * typeinfo->getType()->getByteSize();
863 }
865 else
866 {
867 elemNum = getNumOfElements(objTy);
868 byteSize = 0;
869 }
870 }
873 else if(SVFUtil::isa<GlobalVariable>(val))
874 {
878 analyzeObjType(typeinfo,val);
879 elemNum = getNumOfElements(objTy);
880 byteSize = typeinfo->getType()->getByteSize();
881 }
883 else if (SVFUtil::isa<Instruction>(val) &&
885 SVFUtil::cast<Instruction>(val)))
886 {
887 elemNum = analyzeHeapObjType(typeinfo,val);
888 // analyze heap alloc like (malloc/calloc/...), the alloc functions have
889 // annotation like "AllocSize:Arg1". Please refer to extapi.c.
890 // e.g. calloc(4, 10), annotation is "AllocSize:Arg0*Arg1",
891 // it means byteSize = 4 (Arg0) * 10 (Arg1) = 40
892 byteSize = analyzeHeapAllocByteSize(val);
893 }
895 {
896 analyzeStaticObjType(typeinfo,val);
897 // user input data, label its field as infinite here
898 elemNum = typeinfo->getMaxFieldOffsetLimit();
899 byteSize = typeinfo->getType()->getByteSize();
900 }
902 {
904 elemNum = getNumOfFlattenElements(val->getType());
905 byteSize = typeinfo->getType()->getByteSize();
906 }
907 else
908 {
909 assert("what other object do we have??");
910 abort();
911 }
912
913 // Reset maxOffsetLimit if it is over the total fieldNum of this object
914 if(typeinfo->getMaxFieldOffsetLimit() > elemNum)
915 typeinfo->setNumOfElements(elemNum);
916
917 // set ByteSize. If ByteSize > 0, this typeinfo has constant type.
918 // If ByteSize == 0, this typeinfo has 1) zero byte 2) non-const byte size
919 // If ByteSize>MaxFieldLimit, set MaxFieldLimit to the byteSize;
920 byteSize = Options::MaxFieldLimit() > byteSize? byteSize: Options::MaxFieldLimit();
921 typeinfo->setByteSizeOfObj(byteSize);
922}
923
928{
929 assert(ety && "type is null?");
930 u32_t numOfFields = 1;
931 if (SVFUtil::isa<StructType, ArrayType>(ety))
932 {
934 }
935 return numOfFields;
936}
937
946
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:593
#define DMemModelCE
Definition SVFType.h:603
#define DMemModel
Definition SVFType.h:602
NodeID constantSymID() const
Definition IRGraph.h:188
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:231
static bool isBlkObj(NodeID id)
Definition IRGraph.h:165
IDToTypeInfoMapTy objTypeInfoMap
map a memory sym id to its obj
Definition IRGraph.h:87
NodeID totalSymNum
total number of symbols
Definition IRGraph.h:100
static bool isConstantSym(NodeID id)
Definition IRGraph.h:169
ValueToIDMapTy valSymMap
map a value to its sym id
Definition LLVMModule.h:114
FunToIDMapTy varargSymMap
vararg map
Definition LLVMModule.h:117
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:115
FunToIDMapTy returnSymMap
return map
Definition LLVMModule.h:116
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:158
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:78
u32_t getMaxFieldOffsetLimit()
Get max field offset limit.
const SVFType * getType() const
Get LLVM type.
Definition ObjTypeInfo.h:97
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:185
static const Option< bool > EnableTypeCheck
Definition Options.h:128
static const Option< bool > SymTabPrint
Definition Options.h:187
static Option< bool > ModelConsts
Definition Options.h:184
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:35
StInfo * getTypeInfo()
Definition SVFType.h:275
u32_t getByteSize() const
Definition SVFType.h:289
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition SVFType.h:166
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition SVFType.h:172
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:638
const Value * getFirstUseViaCastInst(const Value *val)
Definition LLVMUtil.cpp:278
const CallBase * getLLVMCallSite(const Value *value)
Return LLVM callsite given a value.
Definition LLVMUtil.h:92
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition LLVMUtil.h:294
bool isHeapAllocExtCall(const Instruction *inst)
Definition LLVMUtil.h:404
bool isConstantObjSym(const Value *val)
Check whether this value points-to a constant object.
Definition CppUtil.cpp:747
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:229
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:259
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition LLVMUtil.h:269
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:83
bool isNullPtrSym(const Value *val)
Check whether this value is a black hole.
Definition LLVMUtil.h:127
std::string dumpValueAndDbgInfo(const Value *val)
Definition LLVMUtil.cpp:627
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition LLVMUtil.h:376
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:453
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:239
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:440
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:305
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:249
bool isBlackholeSym(const Value *val)
Check whether this value is a black hole.
Definition LLVMUtil.h:121
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition LLVMUtil.cpp:653
bool isObject(const Value *ref)
Return true if this value refers to a object.
Definition LLVMUtil.cpp:60
bool ArgInProgEntryFunction(const Value *val)
Return true if this is an argument of a program entry function (e.g. main)
Definition LLVMUtil.h:168
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition LLVMUtil.h:219
u32_t getHeapAllocHoldingArgPosition(const Function *fun)
Definition LLVMUtil.cpp:401
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:725
std::string dumpValue(const Value *val)
Definition LLVMUtil.cpp:605
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:283
void increaseStackSize()
Increase the stack size limit.
Definition SVFUtil.cpp:229
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:58
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:68
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
bool classTyHasVTable(const StructType *ty)
Definition CppUtil.cpp:644
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:49
llvm::AllocaInst AllocaInst
Definition BasicTypes.h:157
llvm::SwitchInst SwitchInst
Definition BasicTypes.h:162
u32_t NodeID
Definition GeneralType.h:56
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:47
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:129
llvm::User User
Definition BasicTypes.h:149