44 using namespace SVFUtil;
45 using namespace LLVMUtil;
49 assert(symInfo->isBlkObj(symId));
50 assert(symInfo->objMap.find(symId)==symInfo->objMap.end());
54 IntegerType::get(llvmset->
getContext(), 32))));
55 symInfo->objMap[symId] = obj;
61 assert(symInfo->isConstantObj(symId));
62 assert(symInfo->objMap.find(symId)==symInfo->objMap.end());
66 IntegerType::get(llvmset->
getContext(), 32))));
67 symInfo->objMap[symId] = obj;
79 symInfo->setModule(svfModule);
107 collectSym(ga.getAliasee());
111 for (
const Function& fun : M.functions())
115 if (fun.getFunctionType()->isVarArg())
119 for (
const Argument& arg : fun.args())
131 if (
const StoreInst* st = SVFUtil::dyn_cast<StoreInst>(&inst))
133 collectSym(st->getPointerOperand());
134 collectSym(st->getValueOperand());
137 SVFUtil::dyn_cast<LoadInst>(&inst))
139 collectSym(ld->getPointerOperand());
142 SVFUtil::dyn_cast<AllocaInst>(&inst))
144 collectSym(alloc->getArraySize());
146 else if (
const PHINode* phi = SVFUtil::dyn_cast<PHINode>(&inst))
148 for (
u32_t i = 0; i < phi->getNumIncomingValues(); ++i)
150 collectSym(phi->getIncomingValue(i));
154 SVFUtil::dyn_cast<GetElementPtrInst>(&inst))
156 collectSym(gep->getPointerOperand());
157 for (
u32_t i = 0; i < gep->getNumOperands(); ++i)
159 collectSym(gep->getOperand(i));
163 SVFUtil::dyn_cast<SelectInst>(&inst))
165 collectSym(sel->getTrueValue());
166 collectSym(sel->getFalseValue());
167 collectSym(sel->getCondition());
170 SVFUtil::dyn_cast<BinaryOperator>(&inst))
172 for (
u32_t i = 0; i < binary->getNumOperands(); i++)
173 collectSym(binary->getOperand(i));
176 SVFUtil::dyn_cast<UnaryOperator>(&inst))
178 for (
u32_t i = 0; i < unary->getNumOperands(); i++)
179 collectSym(unary->getOperand(i));
181 else if (
const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(&inst))
183 for (
u32_t i = 0; i < cmp->getNumOperands(); i++)
184 collectSym(cmp->getOperand(i));
187 SVFUtil::dyn_cast<CastInst>(&inst))
189 collectSym(
cast->getOperand(0));
192 SVFUtil::dyn_cast<ReturnInst>(&inst))
194 if (ret->getReturnValue())
195 collectSym(ret->getReturnValue());
198 SVFUtil::dyn_cast<BranchInst>(&inst))
200 Value* opnd = br->isConditional() ? br->getCondition() : br->getOperand(0);
204 SVFUtil::dyn_cast<SwitchInst>(&inst))
206 collectSym(sw->getCondition());
212 for (
u32_t i = 0; i < cs->arg_size(); i++)
214 collectSym(cs->getArgOperand(i));
218 const Value* Callee = cs->getCalledOperand();
225 getTypeInference()->validateTypeCheck(cs);
242 Type *valType = val->getType();
243 (void)getOrAddSVFTypeInfo(valType);
251 const Type* gepTy = *gi;
252 (void)getOrAddSVFTypeInfo(gepTy);
267 <<
"collect sym from ##"
276 collectSVFTypeInfo(val);
296 SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->valSymMap.find(
298 if (iter == symInfo->valSymMap.end())
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);
322 SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->objSymMap.find(llvmModuleSet->
getSVFValue(val));
323 if (iter == symInfo->objSymMap.end())
330 symInfo->objSymMap.insert(std::make_pair(svfVal, symInfo->constantSymID()));
337 symInfo->objSymMap.insert(std::make_pair(svfVal,
id));
339 outs() <<
"create a new obj sym " <<
id <<
"\n");
343 new MemObj(
id, createObjTypeInfo(val),
345 assert(symInfo->objMap.find(
id) == symInfo->objMap.end());
346 symInfo->objMap[id] = mem;
358 SymbolTableInfo::FunToIDMapTy::iterator iter =
359 symInfo->returnSymMap.find(svffun);
360 if (iter == symInfo->returnSymMap.end())
363 symInfo->returnSymMap.insert(std::make_pair(svffun,
id));
375 SymbolTableInfo::FunToIDMapTy::iterator iter =
376 symInfo->varargSymMap.find(svffun);
377 if (iter == symInfo->varargSymMap.end())
380 symInfo->varargSymMap.insert(std::make_pair(svffun,
id));
390 if (
const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
403 for (
u32_t i = 0; i < ce->getNumOperands(); ++i)
405 collectVal(ce->getOperand(i));
406 handleCE(ce->getOperand(i));
417 collectVal(ce->getOperand(0));
420 handleCE(ce->getOperand(0));
430 collectVal(ce->getOperand(0));
431 collectVal(ce->getOperand(1));
432 collectVal(ce->getOperand(2));
435 handleCE(ce->getOperand(0));
436 handleCE(ce->getOperand(1));
437 handleCE(ce->getOperand(2));
442 collectVal(int2Ptrce);
443 const Constant* opnd = int2Ptrce->getOperand(0);
448 collectVal(ptr2Intce);
449 const Constant* opnd = ptr2Intce->getOperand(0);
465 else if (SVFUtil::isa<ConstantAggregate>(ref))
472 assert(!SVFUtil::isa<ConstantExpr>(val) &&
473 "we don't handle all other constant expression for now!");
487 const Type* T = G->getValueType();
490 while (
const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(T))
492 T = AT->getElementType();
496 if (SVFUtil::isa<StructType>(T))
499 for (
const User* user : G->users())
506 for (
const User* user : G->users())
512 if (G->hasInitializer())
514 handleGlobalInitializerCE(G->getInitializer());
524 if (C->getType()->isSingleValueType())
526 if (
const ConstantExpr* E = SVFUtil::dyn_cast<ConstantExpr>(C))
535 else if (SVFUtil::isa<ConstantArray>(C))
537 for (
u32_t i = 0, e = C->getNumOperands(); i != e; i++)
539 handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
542 else if (SVFUtil::isa<ConstantStruct>(C))
544 for (
u32_t i = 0, e = C->getNumOperands(); i != e; i++)
546 handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
549 else if(
const ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
554 SVFUtil::dyn_cast<ConstantDataSequential>(data))
556 for(
u32_t i = 0; i < seq->getNumElements(); i++)
558 const Constant* ct = seq->getElementAsConstant(i);
559 handleGlobalInitializerCE(ct);
565 (SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) &&
566 "Single value type data should have been handled!");
584 return getTypeInference()->inferObjType(startValue);
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?");
601 if (
const PointerType *newTy = SVFUtil::dyn_cast<PointerType>(v->getType()))
603 originalPType = newTy;
606 inferedType = inferObjType(startValue);
612 const Value* arg = cs->getArgOperand(arg_pos);
613 originalPType = SVFUtil::dyn_cast<PointerType>(arg->getType());
614 inferedType = inferObjType(startValue = arg);
618 assert(
false &&
"not a heap allocation instruction?");
621 getTypeInference()->typeSizeDiffTest(originalPType, inferedType, startValue);
631 const Type* objTy =
nullptr;
633 const Instruction* I = SVFUtil::dyn_cast<Instruction>(val);
639 objTy = inferTypeOfHeapObjOrStaticObj(I);
644 if (SVFUtil::isa<PointerType>(val->getType()))
646 if (
const AllocaInst *allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
650 objTy = allocaInst->getAllocatedType();
652 else if (
const GlobalValue *global = SVFUtil::dyn_cast<GlobalValue>(val))
655 objTy = global->getValueType();
660 assert(
false &&
"not an allocation or global?");
667 (void) getOrAddSVFTypeInfo(objTy);
671 initTypeInfo(typeInfo,val, objTy);
676 writeWrnMsg(
"try to create an object with a non-pointer type.");
684 initTypeInfo(typeInfo,val, val->
getType());
689 assert(
false &&
"Memory object must be either (1) held by a pointer-typed ref value or (2) a constant value (e.g., 10).");
702 while (
const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(elemTy))
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()))
713 if (SVFUtil::isa<StructType>(elemTy))
715 if (SVFUtil::isa<GlobalVariable>(val) &&
716 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
717 SVFUtil::isa<ConstantStruct>(
718 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
741 if(
const llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(val))
744 callInst->getCalledFunction())
749 std::vector<const Value*> args;
753 if (annotation.find(
"AllocSize:") != std::string::npos)
756 std::stringstream ss(allocSize);
759 while (std::getline(ss, token,
'*'))
761 if (token.rfind(
"Arg", 0) == 0)
764 std::istringstream(token.substr(3)) >> argIndex;
765 if (argIndex < callInst->getNumOperands() - 1)
768 callInst->getArgOperand(argIndex));
781 llvm::dyn_cast<llvm::ConstantInt>(arg))
784 product *= constIntArg->getZExtValue();
812 analyzeObjType(typeinfo, val);
814 if(SVFUtil::isa<ArrayType>(objTy))
816 else if(
const StructType* st = SVFUtil::dyn_cast<StructType>(objTy))
837 analyzeObjType(typeinfo,castUse);
858 if (SVFUtil::isa<Function>(val))
861 analyzeObjType(typeinfo,val);
866 else if(
const AllocaInst* allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
869 analyzeObjType(typeinfo,val);
872 if(
const ConstantInt* sz = SVFUtil::dyn_cast<ConstantInt>(allocaInst->getArraySize()))
886 else if(SVFUtil::isa<GlobalVariable>(val))
891 analyzeObjType(typeinfo,val);
896 else if (SVFUtil::isa<Instruction>(val) &&
898 SVFUtil::cast<Instruction>(val)))
900 elemNum = analyzeHeapObjType(typeinfo,val);
905 byteSize = analyzeHeapAllocByteSize(val);
909 analyzeStaticObjType(typeinfo,val);
917 elemNum = getNumOfFlattenElements(val->getType());
922 assert(
"what other object do we have??");
942 assert(ety &&
"type is null?");
943 u32_t numOfFields = 1;
944 if (SVFUtil::isa<StructType, ArrayType>(ety))
946 numOfFields = getNumOfFlattenElements(ety);
955 return getOrAddSVFTypeInfo(T)->getNumOfFlattenElements();
957 return getOrAddSVFTypeInfo(T)->getNumOfFlattenFields();
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
static ExtAPI * getExtAPI()
SVFFunction * getSVFFunction(const Function *fun) const
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
const Type * getLLVMType(const SVFType *T) const
Get LLVM Type.
LLVMContext & getContext() const
static LLVMModuleSet * getLLVMModuleSet()
SVFInstruction * getSVFInstruction(const Instruction *inst) const
ObjTypeInference * getTypeInference()
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
static const Option< bool > EnableTypeCheck
static const Option< bool > ModelArrays
static const Option< bool > SymTabPrint
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
u32_t getByteSize() const
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.
bool isHeapAllocExtCallViaRet(const Instruction *inst)
const Value * getFirstUseViaCastInst(const Value *val)
const ConstantExpr * isUnaryConstantExpr(const Value *val)
bool isHeapAllocExtCall(const Instruction *inst)
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
const ConstantExpr * isBinaryConstantExpr(const Value *val)
bool isNullPtrSym(const Value *val)
Check whether this value is a black hole.
std::string dumpValueAndDbgInfo(const Value *val)
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
const std::string getSourceLoc(const Value *val)
const ConstantExpr * isTruncConstantExpr(const Value *val)
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
const ConstantExpr * isCmpConstantExpr(const Value *val)
u32_t getNumOfElements(const Type *ety)
Return size of this object based on LLVM value.
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
bool isBlackholeSym(const Value *val)
Check whether this value is a black hole.
bool isHeapAllocExtCallViaArg(const Instruction *inst)
bool isObject(const Value *ref)
Return true if this value refers to a object.
bool isConstantObjSym(const SVFValue *val)
Check whether this value points-to a constant object.
bool ArgInProgEntryFunction(const Value *val)
Return true if this is an argument of a program entry function (e.g. main)
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
const ConstantExpr * isSelectConstantExpr(const Value *val)
const ConstantExpr * isCastConstantExpr(const Value *val)
void increaseStackSize()
Increase the stack size limit.
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
u32_t getHeapAllocHoldingArgPosition(const SVFFunction *fun)
Get the position of argument that holds an allocated heap object.
bool isNonInstricCallSite(const ICFGNode *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
std::ostream & errs()
Overwrite llvm::errs()
std::ostream & outs()
Overwrite llvm::outs()
bool classTyHasVTable(const StructType *ty)
llvm::GlobalVariable GlobalVariable
llvm::GlobalAlias GlobalAlias
llvm::ArrayType ArrayType
llvm::UnaryOperator UnaryOperator
llvm::StructType StructType
LLVM types.
llvm::AllocaInst AllocaInst
llvm::SwitchInst SwitchInst
llvm::GlobalValue GlobalValue
llvm::ConstantData ConstantData
llvm::Instruction Instruction
llvm::ConstantDataSequential ConstantDataSequential
llvm::Value Value
LLVM Basic classes.
llvm::ConstantExpr ConstantExpr
llvm::PointerType PointerType
llvm::BinaryOperator BinaryOperator
llvm::StoreInst StoreInst
llvm::SelectInst SelectInst
llvm::GetElementPtrInst GetElementPtrInst
llvm::ReturnInst ReturnInst
llvm::BranchInst BranchInst
llvm::ConstantInt ConstantInt
bridge_gep_iterator bridge_gep_end(const User *GEP)
bridge_gep_iterator bridge_gep_begin(const User *GEP)