Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVFIRExtAPI.cpp
Go to the documentation of this file.
1//===- SVFIRExtAPI.cpp -- External function IR of SVF ---------------------------------------------//
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 * SVFIRExtAPI.cpp
25 *
26 * Created on: 18, 5, 2023
27 * Author: Shuangxiang Kan
28 */
29
31#include "Util/SVFUtil.h"
34#include "Graphs/CallGraph.h"
35#include "Util/ExtAPI.h"
36#include "Util/Options.h"
37
38using namespace std;
39using namespace SVF;
40using namespace SVFUtil;
41using namespace LLVMUtil;
42
43namespace
44{
45
46struct MemcpyField
47{
48 APOffset byteOffset;
49 AccessPath accessPath;
50 const SVFType* elementType;
51};
52
57bool parseAnnotationArgIndex(const std::string& annotation, const std::string& prefix,
58 u32_t& argIdx, size_t& end)
59{
60 const size_t start = annotation.find(prefix);
61 if (start == std::string::npos)
62 return false;
63
64 end = start + prefix.size();
65 if (end >= annotation.size() || annotation[end] < '0' || annotation[end] > '9')
66 return false;
67
68 argIdx = 0;
69 do
70 {
71 argIdx = argIdx * 10 + static_cast<u32_t>(annotation[end] - '0');
72 ++end;
73 }
74 while (end < annotation.size() && annotation[end] >= '0' && annotation[end] <= '9');
75 return true;
76}
77
82{
83 size_t end = 0;
84 return parseAnnotationArgIndex(annotation, "STORE_TOP:Arg", firstArg, end) &&
85 end < annotation.size() && annotation[end] == '+';
86}
87
93bool parseScanfFormatArg(const std::string& annotation, u32_t& formatArg)
94{
95 size_t end = 0;
96 return parseAnnotationArgIndex(annotation, "SCANF:FormatArg", formatArg, end);
97}
98
102{
103 // Unknown or writable formats may contain pointer conversions.
104 const GlobalVariable* glob = SVFUtil::dyn_cast<GlobalVariable>(cs->getArgOperand(formatArg));
105 if (!glob || !glob->isConstant() || !glob->hasDefinitiveInitializer())
106 return true;
107 const ConstantDataArray* data = SVFUtil::dyn_cast<ConstantDataArray>(glob->getInitializer());
108 if (!data || !data->isCString())
109 return true;
110
111 auto format = data->getAsCString();
112 auto in = [](const std::string& set, char c)
113 {
114 return set.find(c) != std::string::npos;
115 };
116 // Consume one conversion at a time. For "%*5d %lf %p", %*5d suppresses
117 // assignment, %lf writes a double, and %p makes us return true.
118 // With just "%*5d %lf", no conversion writes a pointer, so we return false.
119 while (!format.empty())
120 {
121 const size_t percent = format.find('%');
122 if (percent == format.npos)
123 break;
124 format = format.drop_front(percent + 1);
125 if (format.consume_front("%")) // %% is a literal percent sign.
126 continue;
127
128 // Split %*5ld into suppression (*), width (5), modifier (l), and type (d).
129 const bool suppressed = format.consume_front("*");
130 format = format.ltrim("0123456789");
131 const auto modifiers = format.take_front(format.find_first_not_of("hljztLqm"));
132 format = format.drop_front(modifiers.size());
133 if (format.empty())
134 return true;
135 const char conversion = format.front();
136 format = format.drop_front();
137 // Keep the pointer model when a conversion is not recognized.
138 if (!in("diouxXaAeEfFgGsScCnp[", conversion))
139 return true;
140
141 // %m and the old GNU %as/%a[ forms allocate a string and store its address.
142 const bool allocatesString = modifiers.contains('m') ||
143 (conversion == 'a' && !format.empty() && in("sS[", format.front()));
144 if (!suppressed && (conversion == 'p' || allocatesString))
145 return true;
146
147 if (conversion == '[')
148 {
149 // Skip the whole character set: %[%p] matches '%' or 'p', not a pointer.
150 // In %[^]p], the first ']' is part of the character set.
151 format.consume_front("^");
152 format.consume_front("]");
153 const size_t end = format.find(']');
154 if (end == format.npos)
155 return true;
156 format = format.drop_front(end + 1);
157 }
158 }
159 return false;
160}
161
163{
164 const FunObjVar* extFun = callICFGNode->getCalledFunction();
165 if (extFun == nullptr)
166 return false;
167
168 for (const std::string& annotation :
169 ExtAPI::getExtAPI()->getExtFuncAnnotations(extFun))
170 {
171 u32_t firstArg = 0;
173 return true;
174 }
175 return false;
176}
177
179 const Type* llvmType,
180 const SVFType* svfType,
181 const DataLayout& dl,
182 IRGraph* pag,
183 std::vector<MemcpyField>& fields,
186{
187 if (llvmType == nullptr || svfType == nullptr)
188 return;
195 const u32_t maxFields = std::max(Options::MaxFieldLimit(), u32_t{1});
196 if (fields.size() >= maxFields)
197 return;
198
199 if (svfType->isPointerTy())
200 {
201 fields.push_back({baseByteOffset, AccessPath(baseFldIdx), svfType});
202 return;
203 }
204
205 // The LLVM and SVF types are walked one level at a time, so each element's SVF type is
206 // taken from its parent SVF type directly. getOriginalElemType() cannot be used here: it
207 // is keyed by flattened field index, and for nested arrays it returns the innermost
208 // element type, which pairs e.g. [8192 x i8] with i8 one level down.
209 if (const auto* structType = SVFUtil::dyn_cast<StructType>(llvmType))
210 {
211 const auto* svfStructType = SVFUtil::dyn_cast<SVFStructType>(svfType);
212 assert(svfStructType && "an LLVM struct type maps to an SVFStructType");
213 const StructLayout* layout = dl.getStructLayout(const_cast<StructType*>(structType));
214 for (u32_t i = 0;
215 i < structType->getNumElements() && fields.size() < maxFields; ++i)
216 {
217 const Type* elemLLVMType = structType->getElementType(i);
218 const SVFType* elemSVFType = svfStructType->getFieldTypes()[i];
219 if (elemSVFType == nullptr)
220 return;
221 APOffset elemByteOffset = baseByteOffset + static_cast<APOffset>(layout->getElementOffset(i));
224 }
225 return;
226 }
227
228 if (const auto* arrayType = SVFUtil::dyn_cast<ArrayType>(llvmType))
229 {
230 const auto* svfArrayType = SVFUtil::dyn_cast<SVFArrayType>(svfType);
231 assert(svfArrayType && "an LLVM array type maps to an SVFArrayType");
232 const Type* elemLLVMType = arrayType->getElementType();
233 const SVFType* elemSVFType = svfArrayType->getTypeOfElement();
234 if (elemSVFType == nullptr)
235 return;
236 const APOffset elemByteSize = static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(elemLLVMType)));
237 for (u32_t i = 0;
238 i < arrayType->getNumElements() && fields.size() < maxFields; ++i)
239 {
243 }
244 }
245}
246
247std::vector<MemcpyField> getMemcpyFields(const Value* value, const Type* llvmType, const SVFType* svfType)
248{
249 std::vector<MemcpyField> fields;
251 auto* pag = PAG::getPAG();
252 const DataLayout& dl = mset->getMainLLVMModule()->getDataLayout();
253 collectMemcpyFields(llvmType, svfType, dl, pag, fields);
254 return fields;
255}
256
258{
259 if (const auto* allocaInst = llvm::dyn_cast_or_null<AllocaInst>(baseValue))
260 return allocaInst->getAllocatedType();
261
262 if (const auto* global = llvm::dyn_cast_or_null<GlobalVariable>(baseValue))
263 return global->getValueType();
264
265 return fallbackType;
266}
267
268}
269
273const Type* SVFIRBuilder::getBaseTypeAndFlattenedFields(const Value* V, std::vector<AccessPath> &fields, const Value* szValue)
274{
275 assert(V);
276 const Value* value = getBaseValueForExtArg(V);
280 if(szValue && SVFUtil::isa<ConstantInt>(szValue))
281 {
282 auto szIntVal = LLVMUtil::getIntegerValue(SVFUtil::cast<ConstantInt>(szValue));
283 numOfElems = (numOfElems > szIntVal.first) ? szIntVal.first : numOfElems;
284 }
291 numOfElems = std::min(numOfElems, std::max(Options::MaxFieldLimit(), u32_t{1}));
292
294 for(u32_t ei = 0; ei < numOfElems; ei++)
295 {
297 // make a ConstantInt and create char for the content type due to byte-wise copy
298 const ConstantInt* offset = ConstantInt::get(context, llvm::APInt(32, ei));
299 if (!llvmModuleSet()->hasValueNode(offset))
300 {
302 builder.collectSym(offset);
304 pag->addConstantIntValNode(id, LLVMUtil::getIntegerValue(offset), nullptr, llvmModuleSet()->getSVFType(offset->getType()));
306 pag->getGNode(id));
307 }
308 ls.addOffsetVarAndGepTypePair(getPAG()->getValVar(llvmModuleSet()->getValueNode(offset)), nullptr);
309 fields.push_back(ls);
310 }
311 return objType;
312}
313
319{
320 assert(D && S);
322 if(!vnD || !vnS)
323 return;
324
325 std::vector<AccessPath> fields;
326
327 //Get the max possible size of the copy, unless it was provided.
328 std::vector<AccessPath> srcFields;
329 std::vector<AccessPath> dstFields;
332 if(srcFields.size() > dstFields.size())
333 fields = dstFields;
334 else
335 fields = srcFields;
336
338 u32_t sz = fields.size();
339
340 if (fields.size() == 1 && (LLVMUtil::isConstDataOrAggData(D) || LLVMUtil::isConstDataOrAggData(S)))
341 {
345 return;
346 }
347
354 const bool hasRemappedGlobalBase =
355 (dstFieldBase != D && SVFUtil::isa<GlobalVariable>(dstFieldBase)) ||
356 (srcFieldBase != S && SVFUtil::isa<GlobalVariable>(srcFieldBase));
357 const bool useByteLayoutMemcpy =
360 {
363 std::vector<MemcpyField> dstMemcpyFields = getMemcpyFields(D, dstLayoutType, dstSVFType);
364 std::vector<MemcpyField> srcMemcpyFields = getMemcpyFields(S, srcLayoutType, srcSVFType);
365 if (!dstMemcpyFields.empty() && !srcMemcpyFields.empty())
366 {
367 std::unordered_map<APOffset, MemcpyField> srcFieldsByByteOffset;
368 for (const auto& field : srcMemcpyFields)
369 srcFieldsByByteOffset.emplace(field.byteOffset, field);
370
371 const DataLayout& dl = llvmModuleSet()->getMainLLVMModule()->getDataLayout();
372 APOffset copyBytes = std::min<APOffset>(
373 static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(dstLayoutType))),
374 static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(srcLayoutType))));
375 if (szValue && SVFUtil::isa<ConstantInt>(szValue))
376 {
377 auto szIntVal = LLVMUtil::getIntegerValue(SVFUtil::cast<ConstantInt>(szValue));
378 copyBytes = std::min(copyBytes, static_cast<APOffset>(szIntVal.first));
379 }
380
381 for (const auto& dstField : dstMemcpyFields)
382 {
383 if (dstField.byteOffset >= copyBytes)
384 continue;
385 auto it = srcFieldsByByteOffset.find(dstField.byteOffset);
386 if (it == srcFieldsByByteOffset.end())
387 continue;
388
389 NodeID dField = getGepValVar(dstFieldBase, dstField.accessPath, dstField.elementType);
390 NodeID sField = getGepValVar(srcFieldBase, it->second.accessPath, it->second.elementType);
394 }
395 return;
396 }
397 }
398
399 //For each field (i), add (Ti = *S + i) and (*D + i = Ti).
400 for (u32_t index = 0; index < sz; index++)
401 {
404 fields[index].getConstantStructFldIdx());
406 fields[index].getConstantStructFldIdx());
412 }
413}
414
416{
418 NodeID src = pag->getBlkPtr();
419 const FunObjVar* extFun = callICFGNode->getCalledFunction();
420 if (extFun)
421 {
422 for (const std::string& annotation :
424 {
427 {
428 if (annotatedFormatArg < cs->arg_size())
429 {
430 src = pag->getBlkPtr();
432 {
433 // scanf("%d", &n) writes a number, not a pointer. Copy BlkPtr
434 // into a non-pointer variable so AE still sees an unknown value.
436 // Keep the call's LLVM value available when printing this variable.
439 }
440 }
441 continue;
442 }
443
444 u32_t firstArg = 0;
446 continue;
447 if (firstArg >= cs->arg_size())
448 continue;
449
450 for (u32_t argIdx = firstArg; argIdx < cs->arg_size(); ++argIdx)
451 storeTopArgs.insert(argIdx);
452 }
453 }
454
456 {
457 const Value* arg = cs->getArgOperand(argIdx);
458 if (!arg->getType()->isPointerTy())
459 continue;
460
461 const Type* storedType =
463 NodeID dst = getValueNode(arg);
465 dst = fieldZero;
466 if (src && dst)
467 addStoreEdge(src, dst);
468 }
469}
470
472{
474
476 {
478 }
480 {
484 }
486 {
488 Value* arg = cs->getArgOperand(arg_pos);
489 if (cs->getArgOperand(arg_pos)->getType()->isPointerTy())
490 {
493 NodeID obj = pag->addDummyObjNode(llvmModuleSet()->getSVFType(cs->getArgOperand(arg_pos)->getType()));
494 if (vnArg && dummy && obj)
495 {
498 }
499 }
500 else
501 {
502 writeWrnMsg("Arg receiving new object must be pointer type");
503 }
504 }
506 {
507 // Side-effects similar to void *memcpy(void *dest, const void * src, size_t n)
508 // which copies n characters from memory area 'src' to memory area 'dest'.
509 if(callee->getName().find("iconv") != std::string::npos)
510 addComplexConsForExt(cs->getArgOperand(3), cs->getArgOperand(1), nullptr);
511 else if(callee->getName().find("bcopy") != std::string::npos)
512 addComplexConsForExt(cs->getArgOperand(1), cs->getArgOperand(0), cs->getArgOperand(2));
513 if(cs->arg_size() == 3)
514 addComplexConsForExt(cs->getArgOperand(0), cs->getArgOperand(1), cs->getArgOperand(2));
515 else
516 addComplexConsForExt(cs->getArgOperand(0), cs->getArgOperand(1), nullptr);
517 if(SVFUtil::isa<PointerType>(cs->getType()))
518 addCopyEdge(getValueNode(cs->getArgOperand(0)), getValueNode(cs), CopyStmt::COPYVAL);
519 }
521 {
522 // Side-effects similar to memset(void *str, int c, size_t n)
523 // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
524 std::vector<AccessPath> dstFields;
525 const Type *dtype = getBaseTypeAndFlattenedFields(cs->getArgOperand(0), dstFields, cs->getArgOperand(2));
526 u32_t sz = dstFields.size();
527 //For each field (i), add store edge *(arg0 + i) = arg1
528 for (u32_t index = 0; index < sz; index++)
529 {
532 dstFields[index].getConstantStructFldIdx());
533 NodeID dField = getGepValVar(cs->getArgOperand(0), dstFields[index], dElementType);
534 addStoreEdge(getValueNode(cs->getArgOperand(1)),dField);
535 }
536 if(SVFUtil::isa<PointerType>(cs->getType()))
537 addCopyEdge(getValueNode(cs->getArgOperand(0)), getValueNode(cs), CopyStmt::COPYVAL);
538 }
539 else if(callee->getName().compare("dlsym") == 0)
540 {
541 /*
542 Side-effects of void* dlsym( void* handle, const char* funName),
543 Locate the function with the name "funName," then add a "copy" edge between the callsite and that function.
544 dlsym() example:
545 int main() {
546 // Open the shared library
547 void* handle = dlopen("./my_shared_library.so", RTLD_LAZY);
548 // Find the function address
549 void (*myFunctionPtr)() = (void (*)())dlsym(handle, "myFunction");
550 // Call the function
551 myFunctionPtr();
552 }
553 */
554 const Value* src = cs->getArgOperand(1);
555 if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
556 src = stripConstantCasts(gep->getPointerOperand());
557
558 auto getHookFn = [](const Value* src)->const Function*
559 {
560 if (!SVFUtil::isa<GlobalVariable>(src))
561 return nullptr;
562
563 auto *glob = SVFUtil::cast<GlobalVariable>(src);
564 if (!glob->hasInitializer() || !SVFUtil::isa<ConstantDataArray>(glob->getInitializer()))
565 return nullptr;
566
567 auto *constarray = SVFUtil::cast<ConstantDataArray>(glob->getInitializer());
568 return LLVMUtil::getProgFunction(constarray->getAsCString().str());
569 };
570
571 if (const Function *fn = getHookFn(src))
572 {
575 }
576 }
577 else if(callee->getName().find("_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_") != std::string::npos)
578 {
579 // The purpose of this function is to insert a new node into the red-black tree and then rebalance the tree to ensure that the red-black tree properties are maintained.
580 assert(cs->arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
581
582 // We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
583 // Now we calculate the offset from base to vArg3
584 NodeID vnArg3 = llvmModuleSet()->getValueNode(cs->getArgOperand(3));
587
588 // We get all flattened fields of base
590
591 // We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
592 // Note that arg0 is aligned with "offset".
593 for (APOffset i = offset + 1; i <= offset + 3; ++i)
594 {
595 if((u32_t)i >= fields.size())
596 break;
597 const SVFType* elementType = pag->getFlatternedElemType(pag->getTypeLocSetsMap(vnArg3).first,
598 fields[i].getConstantStructFldIdx());
599 NodeID vnD = getGepValVar(cs->getArgOperand(3), fields[i], elementType);
600 NodeID vnS = llvmModuleSet()->getValueNode(cs->getArgOperand(1));
601 if(vnD && vnS)
603 }
604 }
605
607 {
609 if (const FunValVar* funcValVar = SVFUtil::dyn_cast<FunValVar>(valVar))
610 {
615 assert((forkedFun->arg_size() <= 2) && "Size of formal parameter of start routine should be one");
616 if (forkedFun->arg_size() <= 2 && forkedFun->arg_size() >= 1)
617 {
618 const ArgValVar* formalParm = forkedFun->getArg(0);
620 if (actualParm->isPointer() && formalParm->getType()->isPointerTy())
621 {
623 addThreadForkEdge(actualParm->getId(), formalParm->getId(), callICFGNode, entry);
624 }
625 }
626 }
627 else
628 {
633 }
637 }
638
640}
unsigned u32_t
Definition CommandLine.h:18
buffer offset
Definition cJSON.cpp:1113
char const int const cJSON_bool format
Definition cJSON.h:163
int index
Definition cJSON.h:170
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:102
Class representing a function argument variable in the SVFIR.
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:43
const std::vector< std::string > & getExtFuncAnnotations(const FunObjVar *fun)
Definition ExtAPI.cpp:232
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
const FunObjVar * getDefFunForMultipleModule() const
NodeType * getGNode(NodeID id) const
Get a node.
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
Definition ICFG.cpp:243
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
Definition IRGraph.cpp:148
u32_t getNumOfFlattenElements(const SVFType *T)
Definition IRGraph.cpp:186
NodeID getBlkPtr() const
Definition IRGraph.h:259
const SVFType * getFlatternedElemType(const SVFType *baseType, u32_t flatten_idx)
Return the type of a flattened element given a flattened index.
Definition IRGraph.cpp:127
NodeID getValueNode(const Value *V)
Module * getMainLLVMModule() const
Definition LLVMModule.h:373
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:137
void addToSVFVar2LLVMValueMap(const Value *val, SVFValue *svfBaseNode)
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
NodeID getObjectNode(const Value *V)
LLVMContext & getContext() const
Definition LLVMModule.h:393
ObjTypeInference * getTypeInference()
NodeID allocateValueId(void)
Allocate a value ID as determined by the strategy.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
const Type * inferObjType(const Value *var)
get or infer the type of the object pointed by the value
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:34
SVFIR * getPAG() const
Return SVFIR.
void addStoreEdge(NodeID src, NodeID dst)
Add Store edge.
void addLoadEdge(NodeID src, NodeID dst)
Add Load edge.
virtual void handleExtCall(const CallBase *cs, const Function *callee)
AddrStmt * addAddrWithHeapSz(NodeID src, NodeID dst, const CallBase *cs)
Add Address edge from ext call with args like "%5 = call i8* @malloc(i64 noundef 5)".
LLVMModuleSet * llvmModuleSet()
void addThreadForkEdge(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Thread fork edge for parameter passing.
AccessPath getAccessPathFromBaseNode(NodeID nodeId)
const Value * getBaseValueForExtArg(const Value *V)
Get the base value of (i8* src and i8* dst) for external argument (e.g. memcpy(i8* dst,...
virtual void handleNondetArgStoreAtExtCall(const CallBase *cs, const CallICFGNode *callICFGNode)
NodeID getDirectAccessFieldZeroValVar(const Value *ptr, const Type *accessTy)
virtual const Type * getBaseTypeAndFlattenedFields(const Value *V, std::vector< AccessPath > &fields, const Value *szValue)
Handle external call.
CopyStmt * addCopyEdge(NodeID src, NodeID dst, CopyStmt::CopyKind kind)
NodeID getValueNode(const Value *V)
Get different kinds of node.
virtual void addComplexConsForExt(Value *D, Value *S, const Value *sz)
NodeID getGepValVar(const Value *val, const AccessPath &ap, const SVFType *elementType)
NodeID addConstantIntValNode(NodeID i, const std::pair< s64_t, u64_t > &intValue, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:691
ICFG * getICFG() const
Definition SVFIR.h:232
NodeID addValNode(NodeID i, const SVFType *type, const ICFGNode *icfgNode)
add node into SVFIR
Definition SVFIR.h:665
NodeID addDummyValNode()
Definition SVFIR.h:566
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:121
SVFTypeLocSetsPair & getTypeLocSetsMap(NodeID argId)
Given an arg NodeId, get its base SVFType* and all its field location sets.
Definition SVFIR.h:342
NodeID addDummyObjNode(const SVFType *type)
Definition SVFIR.h:570
static SVFType * getSVFInt8Type()
Definition SVFType.h:222
const Function * getProgFunction(const std::string &funName)
Get program entry function from module.
Definition LLVMUtil.cpp:41
const Value * stripConstantCasts(const Value *val)
Strip off the constant casts.
Definition LLVMUtil.cpp:220
bool isHeapAllocExtCallViaRet(const Instruction *inst)
Definition LLVMUtil.cpp:649
bool isMemcpyExtFun(const Function *fun)
Definition LLVMUtil.cpp:390
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:99
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition LLVMUtil.h:415
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition LLVMUtil.cpp:664
bool isMemsetExtFun(const Function *fun)
Definition LLVMUtil.cpp:396
bool isObject(const Value *ref)
Return true if this value refers to a object.
Definition LLVMUtil.cpp:61
u32_t getHeapAllocHoldingArgPosition(const Function *fun)
Definition LLVMUtil.cpp:402
bool isThreadForkCall(const CallICFGNode *inst)
Definition SVFUtil.h:365
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:88
const ValVar * getActualParmAtForkSite(const CallICFGNode *cs)
Return sole argument of the thread routine.
Definition SVFUtil.h:413
const ValVar * getForkedFun(const CallICFGNode *inst)
Return thread fork function.
Definition SVFUtil.h:336
for isBitcode
Definition BasicTypes.h:70
llvm::DataLayout DataLayout
Definition BasicTypes.h:112
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:137
llvm::Type Type
Definition BasicTypes.h:87
llvm::CallBase CallBase
Definition BasicTypes.h:153
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:98
u32_t NodeID
Definition GeneralType.h:76
llvm::StructLayout StructLayout
Definition BasicTypes.h:109
s64_t APOffset
Definition GeneralType.h:80
llvm::Function Function
Definition BasicTypes.h:89
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:86
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
llvm::GetElementPtrInst GetElementPtrInst
Definition BasicTypes.h:169
unsigned u32_t
Definition GeneralType.h:67
llvm::ConstantDataArray ConstantDataArray
Definition BasicTypes.h:125
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:129
llvm::LLVMContext LLVMContext
Definition BasicTypes.h:72