37 using namespace SVFUtil;
38 using namespace LLVMUtil;
43 const Type* SVFIRBuilder::getBaseTypeAndFlattenedFields(
const Value* V, std::vector<AccessPath> &fields,
const Value* szValue)
46 const Value* value = getBaseValueForExtArg(V);
47 const Type *objType = LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(value);
48 u32_t numOfElems = pag->getSymbolInfo()->getNumOfFlattenElements(LLVMModuleSet::getLLVMModuleSet()->getSVFType(objType));
50 if(szValue && SVFUtil::isa<ConstantInt>(szValue))
52 numOfElems = (numOfElems > SVFUtil::cast<ConstantInt>(szValue)->getSExtValue()) ? SVFUtil::cast<ConstantInt>(szValue)->getSExtValue() : numOfElems;
55 LLVMContext& context = LLVMModuleSet::getLLVMModuleSet()->getContext();
56 for(
u32_t ei = 0; ei < numOfElems; ei++)
61 const SVFValue* svfOffset = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(
offset);
62 if (!pag->getSymbolInfo()->hasValSym(svfOffset))
66 pag->addValNode(svfOffset, pag->getSymbolInfo()->getValSym(svfOffset),
nullptr);
81 NodeID vnD= getValueNode(D), vnS= getValueNode(S);
85 std::vector<AccessPath> fields;
88 std::vector<AccessPath> srcFields;
89 std::vector<AccessPath> dstFields;
90 const Type* stype = getBaseTypeAndFlattenedFields(S, srcFields, szValue);
91 const Type* dtype = getBaseTypeAndFlattenedFields(D, dstFields, szValue);
92 if(srcFields.size() > dstFields.size())
98 u32_t sz = fields.size();
102 NodeID dummy = pag->addDummyValNode();
103 addLoadEdge(vnD,dummy);
104 addStoreEdge(dummy,vnS);
111 LLVMModuleSet* llvmmodule = LLVMModuleSet::getLLVMModuleSet();
112 const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->
getSVFType(dtype),
113 fields[
index].getConstantStructFldIdx());
114 const SVFType* sElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->
getSVFType(stype),
115 fields[
index].getConstantStructFldIdx());
116 NodeID dField = getGepValVar(D,fields[
index],dElementType);
117 NodeID sField = getGepValVar(S,fields[
index],sElementType);
118 NodeID dummy = pag->addDummyValNode();
119 addLoadEdge(sField,dummy);
120 addStoreEdge(dummy,dField);
126 const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
127 const SVFCallInst* svfCall = SVFUtil::cast<SVFCallInst>(svfInst);
128 const CallICFGNode *callICFGNode = llvmModuleSet()->getCallICFGNode(cs);
132 NodeID val = pag->getValueNode(svfInst);
133 NodeID obj = pag->getObjectNode(svfInst);
134 addAddrWithHeapSz(obj, val, cs);
142 NodeID vnArg = pag->getValueNode(arg);
143 NodeID dummy = pag->addDummyValNode();
145 if (vnArg && dummy && obj)
147 addAddrWithHeapSz(obj, dummy, cs);
148 addStoreEdge(dummy, vnArg);
153 writeWrnMsg(
"Arg receiving new object must be pointer type");
160 if(svfCallee->
getName().find(
"iconv") != std::string::npos)
161 addComplexConsForExt(cs->getArgOperand(3), cs->getArgOperand(1),
nullptr);
162 else if(svfCallee->
getName().find(
"bcopy") != std::string::npos)
163 addComplexConsForExt(cs->getArgOperand(1), cs->getArgOperand(0), cs->getArgOperand(2));
165 addComplexConsForExt(cs->getArgOperand(0), cs->getArgOperand(1), cs->getArgOperand(2));
167 addComplexConsForExt(cs->getArgOperand(0), cs->getArgOperand(1),
nullptr);
168 if(SVFUtil::isa<PointerType>(cs->getType()))
169 addCopyEdge(getValueNode(cs->getArgOperand(0)), getValueNode(cs), CopyStmt::COPYVAL);
175 std::vector<AccessPath> dstFields;
176 const Type *dtype = getBaseTypeAndFlattenedFields(cs->getArgOperand(0), dstFields, cs->getArgOperand(2));
177 u32_t sz = dstFields.size();
181 LLVMModuleSet* llvmmodule = LLVMModuleSet::getLLVMModuleSet();
182 const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->
getSVFType(dtype),
183 dstFields[
index].getConstantStructFldIdx());
184 NodeID dField = getGepValVar(cs->getArgOperand(0), dstFields[
index], dElementType);
185 addStoreEdge(getValueNode(cs->getArgOperand(1)),dField);
187 if(SVFUtil::isa<PointerType>(cs->getType()))
188 addCopyEdge(getValueNode(cs->getArgOperand(0)), getValueNode(cs), CopyStmt::COPYVAL);
190 else if(svfCallee->
getName().compare(
"dlsym") == 0)
205 const Value* src = cs->getArgOperand(1);
211 if (!SVFUtil::isa<GlobalVariable>(src))
214 auto *glob = SVFUtil::cast<GlobalVariable>(src);
215 if (!glob->hasInitializer() || !SVFUtil::isa<ConstantDataArray>(glob->getInitializer()))
218 auto *constarray = SVFUtil::cast<ConstantDataArray>(glob->getInitializer());
222 if (
const Function *fn = getHookFn(src))
224 NodeID srcNode = getValueNode(fn);
225 addCopyEdge(srcNode, getValueNode(cs), CopyStmt::COPYVAL);
228 else if(svfCallee->
getName().find(
"_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_") != std::string::npos)
231 assert(svfCall->
arg_size() == 4 &&
"_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
237 getAccessPathFromBaseNode(vnArg3).getConstantStructFldIdx();
240 vector<AccessPath> fields = pag->getTypeLocSetsMap(vnArg3).second;
246 if((
u32_t)i >= fields.size())
248 const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(pag->getTypeLocSetsMap(vnArg3).first,
249 fields[i].getConstantStructFldIdx());
250 NodeID vnD = getGepValVar(cs->getArgOperand(3), fields[i], elementType);
253 addStoreEdge(vnS,vnD);
261 forkedFun = forkedFun->getDefFunForMultipleModule();
265 assert((forkedFun->arg_size() <= 2) &&
"Size of formal parameter of start routine should be one");
266 if (forkedFun->arg_size() <= 2 && forkedFun->arg_size() >= 1)
268 const SVFArgument* formalParm = forkedFun->getArg(0);
273 addThreadForkEdge(actualParm->
getId(), pag->getValueNode(formalParm), callICFGNode, entry);
bool addOffsetVarAndGepTypePair(const SVFVar *var, const SVFType *gepIterType)
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
NodeID getId() const
Get ID.
const SVFValue * getArgOperand(u32_t i) const
virtual const SVFType * getType() const
const std::string & getName() const
virtual bool isPointer() const
Whether it is a pointer.
void collectSym(const Value *val)
const Function * getProgFunction(const std::string &funName)
Get program entry function from module.
const Value * stripConstantCasts(const Value *val)
Strip off the constant casts.
bool isHeapAllocExtCallViaRet(const Instruction *inst)
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
bool isHeapAllocExtCallViaArg(const Instruction *inst)
const SVFVar * getActualParmAtForkSite(const CallICFGNode *cs)
Return sole argument of the thread routine.
bool isMemsetExtFun(const SVFFunction *fun)
bool isMemcpyExtFun(const SVFFunction *fun)
u32_t getHeapAllocHoldingArgPosition(const SVFFunction *fun)
Get the position of argument that holds an allocated heap object.
const SVFVar * getForkedFun(const CallICFGNode *inst)
Return thread fork function.
bool isThreadForkCall(const CallICFGNode *inst)
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
llvm::Value Value
LLVM Basic classes.
llvm::GetElementPtrInst GetElementPtrInst
llvm::ConstantInt ConstantInt
llvm::LLVMContext LLVMContext