svf-lib 1.0.1035 → 1.0.1038
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SVF-linux/Release-build/lib/libSvf.a +0 -0
- package/SVF-linux/include/SVF-FE/BasicTypes.h +1 -0
- package/SVF-linux/include/SVF-FE/Graph2Json.h +1 -1
- package/SVF-linux/include/SVF-FE/LLVMUtil.h +0 -122
- package/SVF-linux/include/Util/BasicTypes.h +0 -1
- package/SVF-linux/include/Util/SVFUtil.h +124 -0
- package/SVF-osx/Release-build/lib/CUDD/libCudd.a +0 -0
- package/SVF-osx/Release-build/lib/libSvf.a +0 -0
- package/SVF-osx/include/CFL/CFGNormalizer.h +11 -18
- package/SVF-osx/include/CFL/CFLAlias.h +8 -7
- package/SVF-osx/include/CFL/CFLGramGraphChecker.h +19 -12
- package/SVF-osx/include/CFL/CFLGrammar.h +81 -25
- package/SVF-osx/include/CFL/CFLGrammar.txt +9 -1
- package/SVF-osx/include/CFL/CFLGrammarDev.txt +16 -0
- package/SVF-osx/include/CFL/CFLGraphBuilder.h +51 -11
- package/SVF-osx/include/CFL/CFLSolver.h +2 -0
- package/SVF-osx/include/Graphs/CFLGraph.h +5 -29
- package/SVF-osx/include/SVF-FE/BasicTypes.h +1 -0
- package/SVF-osx/include/SVF-FE/Graph2Json.h +1 -1
- package/SVF-osx/include/SVF-FE/LLVMUtil.h +0 -122
- package/SVF-osx/include/Util/BasicTypes.h +0 -1
- package/SVF-osx/include/Util/SVFUtil.h +124 -0
- package/package.json +1 -1
|
Binary file
|
|
@@ -57,6 +57,7 @@ typedef llvm::ConstantDataSequential ConstantDataSequential;
|
|
|
57
57
|
typedef llvm::ConstantExpr ConstantExpr;
|
|
58
58
|
typedef llvm::ConstantDataArray ConstantDataArray;
|
|
59
59
|
typedef llvm::ConstantData ConstantData;
|
|
60
|
+
typedef llvm::ConstantArray ConstantArray;
|
|
60
61
|
|
|
61
62
|
// LLVM Instructions
|
|
62
63
|
typedef llvm::AllocaInst AllocaInst;
|
|
@@ -66,14 +66,6 @@ inline bool isBlackholeSym(const Value *val)
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
/// Return true if the call is an external call (external library in function summary table)
|
|
70
|
-
/// If the libary function is redefined in the application code (e.g., memcpy), it will return false and will not be treated as an external call.
|
|
71
|
-
//@{
|
|
72
|
-
inline bool isExtCall(const SVFFunction* fun)
|
|
73
|
-
{
|
|
74
|
-
return fun && ExtAPI::getExtAPI()->is_ext(fun);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
69
|
inline bool isExtCall(const CallSite cs)
|
|
78
70
|
{
|
|
79
71
|
return isExtCall(getCallee(cs));
|
|
@@ -91,19 +83,6 @@ inline bool isReturn(const Instruction* inst)
|
|
|
91
83
|
return SVFUtil::isa<ReturnInst>(inst);
|
|
92
84
|
}
|
|
93
85
|
|
|
94
|
-
/// Return true if the call is a heap allocator/reallocator
|
|
95
|
-
//@{
|
|
96
|
-
/// note that these two functions are not suppose to be used externally
|
|
97
|
-
inline bool isHeapAllocExtFunViaRet(const SVFFunction* fun)
|
|
98
|
-
{
|
|
99
|
-
return fun && (ExtAPI::getExtAPI()->is_alloc(fun)
|
|
100
|
-
|| ExtAPI::getExtAPI()->is_realloc(fun));
|
|
101
|
-
}
|
|
102
|
-
inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun)
|
|
103
|
-
{
|
|
104
|
-
return fun && ExtAPI::getExtAPI()->is_arg_alloc(fun);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
86
|
static inline Type *getPtrElementType(const PointerType* pty)
|
|
108
87
|
{
|
|
109
88
|
#if (LLVM_VERSION_MAJOR < 14)
|
|
@@ -148,13 +127,6 @@ inline bool isHeapAllocExtCall(const Instruction *inst)
|
|
|
148
127
|
}
|
|
149
128
|
//@}
|
|
150
129
|
|
|
151
|
-
/// Get the position of argument that holds an allocated heap object.
|
|
152
|
-
//@{
|
|
153
|
-
inline int getHeapAllocHoldingArgPosition(const SVFFunction* fun)
|
|
154
|
-
{
|
|
155
|
-
return ExtAPI::getExtAPI()->get_alloc_arg_pos(fun);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
130
|
inline int getHeapAllocHoldingArgPosition(const CallSite cs)
|
|
159
131
|
{
|
|
160
132
|
return getHeapAllocHoldingArgPosition(getCallee(cs));
|
|
@@ -166,14 +138,6 @@ inline int getHeapAllocHoldingArgPosition(const Instruction *inst)
|
|
|
166
138
|
}
|
|
167
139
|
//@}
|
|
168
140
|
|
|
169
|
-
/// Return true if the call is a heap reallocator
|
|
170
|
-
//@{
|
|
171
|
-
/// note that this function is not suppose to be used externally
|
|
172
|
-
inline bool isReallocExtFun(const SVFFunction* fun)
|
|
173
|
-
{
|
|
174
|
-
return fun && (ExtAPI::getExtAPI()->is_realloc(fun));
|
|
175
|
-
}
|
|
176
|
-
|
|
177
141
|
inline bool isReallocExtCall(const CallSite cs)
|
|
178
142
|
{
|
|
179
143
|
bool isPtrTy = cs.getInstruction()->getType()->isPointerTy();
|
|
@@ -187,14 +151,6 @@ inline bool isReallocExtCall(const Instruction *inst)
|
|
|
187
151
|
}
|
|
188
152
|
//@}
|
|
189
153
|
|
|
190
|
-
/// Return true if the call is a heap dealloc or not
|
|
191
|
-
//@{
|
|
192
|
-
/// note that this function is not suppose to be used externally
|
|
193
|
-
inline bool isDeallocExtFun(const SVFFunction* fun)
|
|
194
|
-
{
|
|
195
|
-
return fun && (ExtAPI::getExtAPI()->is_dealloc(fun));
|
|
196
|
-
}
|
|
197
|
-
|
|
198
154
|
inline bool isDeallocExtCall(const CallSite cs)
|
|
199
155
|
{
|
|
200
156
|
return isDeallocExtFun(getCallee(cs));
|
|
@@ -206,15 +162,6 @@ inline bool isDeallocExtCall(const Instruction *inst)
|
|
|
206
162
|
}
|
|
207
163
|
//@}
|
|
208
164
|
|
|
209
|
-
|
|
210
|
-
/// Return true if the call is a static global call
|
|
211
|
-
//@{
|
|
212
|
-
/// note that this function is not suppose to be used externally
|
|
213
|
-
inline bool isStaticExtFun(const SVFFunction* fun)
|
|
214
|
-
{
|
|
215
|
-
return fun && ExtAPI::getExtAPI()->has_static(fun);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
165
|
inline bool isStaticExtCall(const CallSite cs)
|
|
219
166
|
{
|
|
220
167
|
bool isPtrTy = cs.getInstruction()->getType()->isPointerTy();
|
|
@@ -241,12 +188,6 @@ inline bool isHeapAllocOrStaticExtCall(const Instruction *inst)
|
|
|
241
188
|
}
|
|
242
189
|
//@}
|
|
243
190
|
|
|
244
|
-
/// Return external call type
|
|
245
|
-
inline ExtAPI::extf_t extCallTy(const SVFFunction* fun)
|
|
246
|
-
{
|
|
247
|
-
return ExtAPI::getExtAPI()->get_type(fun);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
191
|
/// Get the reference type of heap/static object from an allocation site.
|
|
251
192
|
//@{
|
|
252
193
|
inline const PointerType *getRefTypeOfHeapAllocOrStatic(const CallSite cs)
|
|
@@ -362,18 +303,6 @@ inline bool isBarrierWaitCall(const Instruction *inst)
|
|
|
362
303
|
}
|
|
363
304
|
//@}
|
|
364
305
|
|
|
365
|
-
/// Return thread fork function
|
|
366
|
-
//@{
|
|
367
|
-
inline const Value* getForkedFun(const CallSite cs)
|
|
368
|
-
{
|
|
369
|
-
return ThreadAPI::getThreadAPI()->getForkedFun(cs);
|
|
370
|
-
}
|
|
371
|
-
inline const Value* getForkedFun(const Instruction *inst)
|
|
372
|
-
{
|
|
373
|
-
return ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
374
|
-
}
|
|
375
|
-
//@}
|
|
376
|
-
|
|
377
306
|
/// Return sole argument of the thread routine
|
|
378
307
|
//@{
|
|
379
308
|
inline const Value* getActualParmAtForkSite(const CallSite cs)
|
|
@@ -413,15 +342,6 @@ inline const Value* getTaskDataAtHareParForSite(const Instruction *inst)
|
|
|
413
342
|
/// Return true if this value refers to a object
|
|
414
343
|
bool isObject (const Value * ref);
|
|
415
344
|
|
|
416
|
-
/// Return true if the value refers to constant data, e.g., i32 0
|
|
417
|
-
inline bool isConstantData(const Value* val)
|
|
418
|
-
{
|
|
419
|
-
return SVFUtil::isa<ConstantData>(val)
|
|
420
|
-
|| SVFUtil::isa<ConstantAggregate>(val)
|
|
421
|
-
|| SVFUtil::isa<MetadataAsValue>(val)
|
|
422
|
-
|| SVFUtil::isa<BlockAddress>(val);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
345
|
/// Method for dead function, which does not have any possible caller
|
|
426
346
|
/// function address is not taken and never be used in call or invoke instruction
|
|
427
347
|
//@{
|
|
@@ -436,43 +356,11 @@ inline bool ArgInDeadFunction (const Value * val)
|
|
|
436
356
|
}
|
|
437
357
|
//@}
|
|
438
358
|
|
|
439
|
-
/// Program entry function e.g. main
|
|
440
|
-
//@{
|
|
441
|
-
/// Return true if this is a program entry function (e.g. main)
|
|
442
|
-
inline bool isProgEntryFunction (const SVFFunction * fun)
|
|
443
|
-
{
|
|
444
|
-
return fun && fun->getName() == "main";
|
|
445
|
-
}
|
|
446
|
-
|
|
447
359
|
inline bool isProgEntryFunction (const Function * fun)
|
|
448
360
|
{
|
|
449
361
|
return fun && fun->getName() == "main";
|
|
450
362
|
}
|
|
451
363
|
|
|
452
|
-
/// Get program entry function from module.
|
|
453
|
-
inline const SVFFunction* getProgFunction(SVFModule* svfModule, const std::string& funName)
|
|
454
|
-
{
|
|
455
|
-
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
456
|
-
{
|
|
457
|
-
const SVFFunction *fun = *it;
|
|
458
|
-
if (fun->getName()==funName)
|
|
459
|
-
return fun;
|
|
460
|
-
}
|
|
461
|
-
return nullptr;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/// Get program entry function from module.
|
|
465
|
-
inline const SVFFunction* getProgEntryFunction(SVFModule* svfModule)
|
|
466
|
-
{
|
|
467
|
-
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
468
|
-
{
|
|
469
|
-
const SVFFunction *fun = *it;
|
|
470
|
-
if (isProgEntryFunction(fun))
|
|
471
|
-
return (fun);
|
|
472
|
-
}
|
|
473
|
-
return nullptr;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
364
|
/// Return true if this is an argument of a program entry function (e.g. main)
|
|
477
365
|
inline bool ArgInProgEntryFunction (const Value * val)
|
|
478
366
|
{
|
|
@@ -483,15 +371,6 @@ inline bool ArgInProgEntryFunction (const Value * val)
|
|
|
483
371
|
bool isPtrInDeadFunction (const Value * value);
|
|
484
372
|
//@}
|
|
485
373
|
|
|
486
|
-
/// Return true if this is a program exit function call
|
|
487
|
-
//@{
|
|
488
|
-
inline bool isProgExitFunction (const SVFFunction * fun)
|
|
489
|
-
{
|
|
490
|
-
return fun && (fun->getName() == "exit" ||
|
|
491
|
-
fun->getName() == "__assert_rtn" ||
|
|
492
|
-
fun->getName() == "__assert_fail" );
|
|
493
|
-
}
|
|
494
|
-
|
|
495
374
|
inline bool isProgExitCall(const CallSite cs)
|
|
496
375
|
{
|
|
497
376
|
return isProgExitFunction(getCallee(cs));
|
|
@@ -677,7 +556,6 @@ u32_t getTypeSizeInBytes(const Type* type);
|
|
|
677
556
|
u32_t getTypeSizeInBytes(const StructType *sty, u32_t field_index);
|
|
678
557
|
//@}
|
|
679
558
|
|
|
680
|
-
const std::string type2String(const Type* type);
|
|
681
559
|
|
|
682
560
|
} // End namespace SVFUtil
|
|
683
561
|
|
|
@@ -94,7 +94,6 @@ typedef llvm::Argument Argument;
|
|
|
94
94
|
typedef llvm::Constant Constant;
|
|
95
95
|
typedef llvm::ConstantInt ConstantInt;
|
|
96
96
|
typedef llvm::ConstantPointerNull ConstantPointerNull;
|
|
97
|
-
typedef llvm::ConstantArray ConstantArray;
|
|
98
97
|
typedef llvm::GlobalAlias GlobalAlias;
|
|
99
98
|
|
|
100
99
|
/// LLVM metadata
|
|
@@ -352,6 +352,130 @@ bool startAnalysisLimitTimer(unsigned timeLimit);
|
|
|
352
352
|
/// timer or not (return value of startLimitTimer).
|
|
353
353
|
void stopAnalysisLimitTimer(bool limitTimerSet);
|
|
354
354
|
|
|
355
|
+
/// Return true if the call is an external call (external library in function summary table)
|
|
356
|
+
/// If the libary function is redefined in the application code (e.g., memcpy), it will return false and will not be treated as an external call.
|
|
357
|
+
//@{
|
|
358
|
+
inline bool isExtCall(const SVFFunction* fun)
|
|
359
|
+
{
|
|
360
|
+
return fun && ExtAPI::getExtAPI()->is_ext(fun);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/// Return true if the call is a heap allocator/reallocator
|
|
364
|
+
//@{
|
|
365
|
+
/// note that these two functions are not suppose to be used externally
|
|
366
|
+
inline bool isHeapAllocExtFunViaRet(const SVFFunction* fun)
|
|
367
|
+
{
|
|
368
|
+
return fun && (ExtAPI::getExtAPI()->is_alloc(fun)
|
|
369
|
+
|| ExtAPI::getExtAPI()->is_realloc(fun));
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun)
|
|
373
|
+
{
|
|
374
|
+
return fun && ExtAPI::getExtAPI()->is_arg_alloc(fun);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/// Get the position of argument that holds an allocated heap object.
|
|
378
|
+
//@{
|
|
379
|
+
inline int getHeapAllocHoldingArgPosition(const SVFFunction* fun)
|
|
380
|
+
{
|
|
381
|
+
return ExtAPI::getExtAPI()->get_alloc_arg_pos(fun);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/// Return true if the call is a heap reallocator
|
|
385
|
+
//@{
|
|
386
|
+
/// note that this function is not suppose to be used externally
|
|
387
|
+
inline bool isReallocExtFun(const SVFFunction* fun)
|
|
388
|
+
{
|
|
389
|
+
return fun && (ExtAPI::getExtAPI()->is_realloc(fun));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/// Return true if the call is a heap dealloc or not
|
|
393
|
+
//@{
|
|
394
|
+
/// note that this function is not suppose to be used externally
|
|
395
|
+
inline bool isDeallocExtFun(const SVFFunction* fun)
|
|
396
|
+
{
|
|
397
|
+
return fun && (ExtAPI::getExtAPI()->is_dealloc(fun));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/// Return true if the call is a static global call
|
|
401
|
+
//@{
|
|
402
|
+
/// note that this function is not suppose to be used externally
|
|
403
|
+
inline bool isStaticExtFun(const SVFFunction* fun)
|
|
404
|
+
{
|
|
405
|
+
return fun && ExtAPI::getExtAPI()->has_static(fun);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/// Return external call type
|
|
409
|
+
inline ExtAPI::extf_t extCallTy(const SVFFunction* fun)
|
|
410
|
+
{
|
|
411
|
+
return ExtAPI::getExtAPI()->get_type(fun);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/// Program entry function e.g. main
|
|
415
|
+
//@{
|
|
416
|
+
/// Return true if this is a program entry function (e.g. main)
|
|
417
|
+
inline bool isProgEntryFunction (const SVFFunction * fun)
|
|
418
|
+
{
|
|
419
|
+
return fun && fun->getName() == "main";
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
/// Get program entry function from module.
|
|
424
|
+
inline const SVFFunction* getProgFunction(SVFModule* svfModule, const std::string& funName)
|
|
425
|
+
{
|
|
426
|
+
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
427
|
+
{
|
|
428
|
+
const SVFFunction *fun = *it;
|
|
429
|
+
if (fun->getName()==funName)
|
|
430
|
+
return fun;
|
|
431
|
+
}
|
|
432
|
+
return nullptr;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/// Get program entry function from module.
|
|
436
|
+
inline const SVFFunction* getProgEntryFunction(SVFModule* svfModule)
|
|
437
|
+
{
|
|
438
|
+
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
439
|
+
{
|
|
440
|
+
const SVFFunction *fun = *it;
|
|
441
|
+
if (isProgEntryFunction(fun))
|
|
442
|
+
return (fun);
|
|
443
|
+
}
|
|
444
|
+
return nullptr;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/// Return true if this is a program exit function call
|
|
448
|
+
//@{
|
|
449
|
+
inline bool isProgExitFunction (const SVFFunction * fun)
|
|
450
|
+
{
|
|
451
|
+
return fun && (fun->getName() == "exit" ||
|
|
452
|
+
fun->getName() == "__assert_rtn" ||
|
|
453
|
+
fun->getName() == "__assert_fail" );
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/// Return true if the value refers to constant data, e.g., i32 0
|
|
457
|
+
inline bool isConstantData(const Value* val)
|
|
458
|
+
{
|
|
459
|
+
return SVFUtil::isa<ConstantData>(val)
|
|
460
|
+
|| SVFUtil::isa<ConstantAggregate>(val)
|
|
461
|
+
|| SVFUtil::isa<MetadataAsValue>(val)
|
|
462
|
+
|| SVFUtil::isa<BlockAddress>(val);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/// Return thread fork function
|
|
466
|
+
//@{
|
|
467
|
+
inline const Value* getForkedFun(const CallSite cs)
|
|
468
|
+
{
|
|
469
|
+
return ThreadAPI::getThreadAPI()->getForkedFun(cs);
|
|
470
|
+
}
|
|
471
|
+
inline const Value* getForkedFun(const Instruction *inst)
|
|
472
|
+
{
|
|
473
|
+
return ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
474
|
+
}
|
|
475
|
+
//@}
|
|
476
|
+
|
|
477
|
+
const std::string type2String(const Type* type);
|
|
478
|
+
|
|
355
479
|
} // End namespace SVFUtil
|
|
356
480
|
|
|
357
481
|
} // End namespace SVF
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===----- CFGNormalizer.h --
|
|
1
|
+
//===----- CFGNormalizer.h -- Context Free Grammar Normalizer--------------//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -43,40 +43,33 @@ class CFGNormalizer
|
|
|
43
43
|
{
|
|
44
44
|
|
|
45
45
|
public:
|
|
46
|
-
typedef u32_t Symbol;
|
|
47
|
-
typedef std::vector<Symbol> Production;
|
|
48
|
-
typedef Set<Production> Productions;
|
|
49
|
-
|
|
50
46
|
CFGNormalizer()
|
|
51
47
|
{
|
|
52
48
|
}
|
|
53
49
|
|
|
54
|
-
///
|
|
55
|
-
// TODO: Add different Combination Transformation Option
|
|
56
|
-
|
|
57
|
-
/// Normalization without attribute expanded
|
|
50
|
+
/// Normalization with attribute expanded
|
|
58
51
|
CFLGrammar* normalize(GrammarBase *generalGrammar);
|
|
59
52
|
|
|
60
53
|
/// Fill Every attribute in CFL grammar
|
|
61
|
-
CFLGrammar* fillAttribute(CFLGrammar *grammar, Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute
|
|
54
|
+
CFLGrammar* fillAttribute(CFLGrammar *grammar, const Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& kind2AttrsMap);
|
|
62
55
|
|
|
63
56
|
private:
|
|
64
57
|
/// Add nonterminal to tranfer long rules to binary rules
|
|
65
|
-
void ebnf_bin(
|
|
58
|
+
void ebnf_bin(CFLGrammar *grammar);
|
|
66
59
|
|
|
67
|
-
void ebnf_sign_replace(char sign,
|
|
60
|
+
void ebnf_sign_replace(char sign, CFLGrammar *grammar);
|
|
68
61
|
|
|
69
|
-
void insertToCFLGrammar(CFLGrammar *grammar, Production &prod);
|
|
62
|
+
void insertToCFLGrammar(CFLGrammar *grammar, GrammarBase::Production &prod);
|
|
70
63
|
|
|
71
|
-
int ebnf_bracket_match(Production& prod, int i, CFLGrammar *grammar) ;
|
|
64
|
+
int ebnf_bracket_match(GrammarBase::Production& prod, int i, CFLGrammar *grammar) ;
|
|
72
65
|
|
|
73
|
-
int check_head(Map<Symbol, Productions>& grammar, Production& rule);
|
|
66
|
+
int check_head(Map<GrammarBase::Symbol, GrammarBase::Productions>& grammar, GrammarBase::Production& rule);
|
|
74
67
|
|
|
75
|
-
Production strTrans(std::string strPro, CFLGrammar *grammar);
|
|
68
|
+
GrammarBase::Production strTrans(std::string strPro, CFLGrammar *grammar);
|
|
76
69
|
|
|
77
|
-
Production getFilledProd(Production &prod, CFLGrammar::Attribute attribute, CFLGrammar *grammar);
|
|
70
|
+
GrammarBase::Production getFilledProd(GrammarBase::Production &prod, CFLGrammar::Attribute attribute, CFLGrammar *grammar);
|
|
78
71
|
|
|
79
|
-
Productions getFilledProductions(Production &prod, Map<CFLGrammar::Kind,
|
|
72
|
+
GrammarBase::Productions getFilledProductions(GrammarBase::Production &prod,const Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& kind2AttriMap, CFLGrammar *grammar);
|
|
80
73
|
};
|
|
81
74
|
|
|
82
75
|
} // End namespace SVF
|
|
@@ -70,21 +70,22 @@ public:
|
|
|
70
70
|
Map<std::string, SVF::CFLGraph::Symbol> ConstMap = {{"Addr",0}, {"Copy", 1},{"Store", 2},{"Load", 3},{"Gep_i", 4},{"Vgep", 5},{"Addrbar",6}, {"Copybar", 7},{"Storebar", 8},{"Loadbar", 9},{"Gepbar_i", 10},{"Vgepbar", 11}};
|
|
71
71
|
GrammarBase *generalGrammar = gReader.build(ConstMap);
|
|
72
72
|
ConstraintGraph *consCG = new ConstraintGraph(svfir);
|
|
73
|
-
graph = cflGraphBuilder.buildBigraph(consCG);
|
|
74
|
-
cflChecker.check(generalGrammar, graph);
|
|
73
|
+
graph = cflGraphBuilder.buildBigraph(consCG, generalGrammar->getStartKind());
|
|
74
|
+
cflChecker.check(generalGrammar, &cflGraphBuilder, graph);
|
|
75
75
|
grammar = normalizer.normalize(generalGrammar);
|
|
76
|
-
cflChecker.check(grammar, graph);
|
|
76
|
+
cflChecker.check(grammar, &cflGraphBuilder, graph);
|
|
77
|
+
svfir->dump("SVFIR");
|
|
78
|
+
grammar->dump();
|
|
77
79
|
delete consCG;
|
|
78
80
|
delete generalGrammar;
|
|
79
|
-
grammar->dump();
|
|
80
81
|
}
|
|
81
82
|
else
|
|
82
83
|
{
|
|
83
84
|
GrammarBase *generalGrammar = gReader.build();
|
|
84
85
|
graph = cflGraphBuilder.buildFromDot(Options::InputFilename, generalGrammar);
|
|
85
|
-
cflChecker.check(generalGrammar, graph);
|
|
86
|
+
cflChecker.check(generalGrammar, &cflGraphBuilder, graph);
|
|
86
87
|
grammar = normalizer.normalize(generalGrammar);
|
|
87
|
-
cflChecker.check(grammar, graph);
|
|
88
|
+
cflChecker.check(grammar, &cflGraphBuilder, graph);
|
|
88
89
|
delete generalGrammar;
|
|
89
90
|
}
|
|
90
91
|
solver = new CFLSolver(graph, grammar);
|
|
@@ -106,7 +107,7 @@ public:
|
|
|
106
107
|
/// Interface exposed to users of our pointer analysis, given PAGNodeID
|
|
107
108
|
virtual AliasResult alias(NodeID node1, NodeID node2)
|
|
108
109
|
{
|
|
109
|
-
if(graph->hasEdge(graph->getGNode(node1), graph->getGNode(node2), graph->
|
|
110
|
+
if(graph->hasEdge(graph->getGNode(node1), graph->getGNode(node2), graph->startKind))
|
|
110
111
|
return AliasResult::MayAlias;
|
|
111
112
|
else
|
|
112
113
|
return AliasResult::NoAlias;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===----- CFLGramGraphChecker.h -- CFL Checker for Grammar and
|
|
1
|
+
//===----- CFLGramGraphChecker.h -- CFL Checker for Grammar and graphBuilder alignment --------------//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -35,28 +35,35 @@ namespace SVF
|
|
|
35
35
|
class CFLGramGraphChecker
|
|
36
36
|
{
|
|
37
37
|
public:
|
|
38
|
-
void check(GrammarBase *grammar, CFLGraph *graph)
|
|
38
|
+
void check(GrammarBase *grammar, CFLGraphBuilder *graphBuilder, CFLGraph *graph)
|
|
39
39
|
{
|
|
40
|
-
/// Check all
|
|
41
|
-
for(auto pairV : grammar->
|
|
40
|
+
/// Check all kinds in grammar in graphBuilder with the same label
|
|
41
|
+
for(auto pairV : grammar->getTerminals())
|
|
42
42
|
{
|
|
43
|
-
if (
|
|
43
|
+
if (graphBuilder->getLabel2KindMap().find(pairV.first) != graphBuilder->getLabel2KindMap().end())
|
|
44
44
|
{
|
|
45
|
-
assert(
|
|
45
|
+
assert(graphBuilder->getLabel2KindMap()[pairV.first] == pairV.second);
|
|
46
|
+
assert(graphBuilder->getKind2LabelMap()[pairV.second] == pairV.first);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
for(auto pairV : grammar->
|
|
50
|
+
for(auto pairV : grammar->getNonterminals())
|
|
50
51
|
{
|
|
51
|
-
if (
|
|
52
|
+
if (graphBuilder->getLabel2KindMap().find(pairV.first) != graphBuilder->getLabel2KindMap().end())
|
|
52
53
|
{
|
|
53
|
-
assert(
|
|
54
|
+
assert(graphBuilder->getLabel2KindMap()[pairV.first] == pairV.second);
|
|
55
|
+
assert(graphBuilder->getKind2LabelMap()[pairV.second] == pairV.first);
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
{
|
|
59
|
+
graphBuilder->getLabel2KindMap().insert(std::make_pair (pairV.first,pairV.second));
|
|
60
|
+
graphBuilder->getKind2LabelMap().insert(std::make_pair (pairV.second, pairV.first));
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
|
|
57
|
-
/// Get
|
|
58
|
-
grammar->
|
|
59
|
-
graph->
|
|
64
|
+
/// Get Kind2Attrs Map from Graph to Grammar
|
|
65
|
+
grammar->setKind2AttrsMap(graphBuilder->getKind2AttrsMap());
|
|
66
|
+
graph->startKind = grammar->getStartKind();
|
|
60
67
|
}
|
|
61
68
|
};
|
|
62
69
|
|
|
@@ -40,17 +40,66 @@ public:
|
|
|
40
40
|
typedef Set<Production> Productions;
|
|
41
41
|
typedef u32_t Attribute;
|
|
42
42
|
typedef u32_t Kind;
|
|
43
|
-
Map<std::string, Symbol> terminals;
|
|
44
|
-
Map<std::string, Symbol> nonterminals;
|
|
45
|
-
Symbol startSymbol;
|
|
46
|
-
Symbol totalSymbol;
|
|
47
|
-
Map<Symbol, Productions> rawProductions;
|
|
48
|
-
Set<Symbol> attributeSymbol;
|
|
49
|
-
Map<Kind, Set<Attribute>> kind2AttrMap;
|
|
50
43
|
|
|
51
|
-
|
|
44
|
+
inline Map<std::string, Kind>& getNonterminals()
|
|
45
|
+
{
|
|
46
|
+
return this->nonterminals;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
inline void setNonterminals(Map<std::string, Kind>& nonterminals)
|
|
50
|
+
{
|
|
51
|
+
this->nonterminals = nonterminals;
|
|
52
|
+
}
|
|
52
53
|
|
|
53
|
-
std::string
|
|
54
|
+
inline Map<std::string, Kind>& getTerminals()
|
|
55
|
+
{
|
|
56
|
+
return this->terminals;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
inline void setTerminals(Map<std::string, Kind>& terminals)
|
|
60
|
+
{
|
|
61
|
+
this->terminals = terminals;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
inline Map<Symbol, Productions>& getRawProductions()
|
|
65
|
+
{
|
|
66
|
+
return this->rawProductions;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
inline const Map<Kind, Set<Attribute>>& getKind2AttrsMap() const
|
|
70
|
+
{
|
|
71
|
+
return this->kind2AttrsMap;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
inline Kind getTotalKind()
|
|
75
|
+
{
|
|
76
|
+
return this->totalKind;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
inline Kind getStartKind()
|
|
80
|
+
{
|
|
81
|
+
return this->startKind;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
inline void setStartKind(Kind startKind)
|
|
85
|
+
{
|
|
86
|
+
this->startKind = startKind;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
inline void setTotalKind(Kind totalKind)
|
|
90
|
+
{
|
|
91
|
+
this->totalKind = totalKind;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void setRawProductions(Map<Symbol, Productions>& rawProductions);
|
|
95
|
+
|
|
96
|
+
void setKind2AttrsMap(const Map<Kind, Set<Attribute>>& kind2AttrsMap);
|
|
97
|
+
|
|
98
|
+
void setAttributeKinds(const Set<Kind>& attributeKind);
|
|
99
|
+
|
|
100
|
+
Kind str2Kind(std::string str) const;
|
|
101
|
+
|
|
102
|
+
std::string kind2Str(Kind kind) const;
|
|
54
103
|
|
|
55
104
|
std::string sym2StrDump(Symbol sym) const;
|
|
56
105
|
|
|
@@ -59,14 +108,14 @@ public:
|
|
|
59
108
|
return prod.at(pos);
|
|
60
109
|
}
|
|
61
110
|
|
|
62
|
-
inline Set<Symbol>& getAttrSyms()
|
|
111
|
+
inline const Set<Symbol>& getAttrSyms() const
|
|
63
112
|
{
|
|
64
|
-
return this->
|
|
113
|
+
return this->attributeKinds;
|
|
65
114
|
}
|
|
66
115
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
void insertAttribute(
|
|
116
|
+
Kind insertTerminalKind(std::string strLit);
|
|
117
|
+
Kind insertNonTerminalKind(std::string strLit);
|
|
118
|
+
void insertAttribute(Kind kind, Attribute a);
|
|
70
119
|
|
|
71
120
|
inline static Kind getSymKind(Symbol sym)
|
|
72
121
|
{
|
|
@@ -86,7 +135,14 @@ public:
|
|
|
86
135
|
protected:
|
|
87
136
|
static constexpr unsigned char EdgeKindMaskBits = 8; ///< We use the lower 8 bits to denote edge kind
|
|
88
137
|
static constexpr u64_t EdgeKindMask = (~0ULL) >> (64 - EdgeKindMaskBits);
|
|
89
|
-
|
|
138
|
+
Kind startKind;
|
|
139
|
+
private:
|
|
140
|
+
Set<Kind> attributeKinds;
|
|
141
|
+
Map<Kind, Set<Attribute>> kind2AttrsMap;
|
|
142
|
+
Map<Symbol, Productions> rawProductions;
|
|
143
|
+
Kind totalKind;
|
|
144
|
+
Map<std::string, Kind> nonterminals;
|
|
145
|
+
Map<std::string, Kind> terminals;
|
|
90
146
|
};
|
|
91
147
|
|
|
92
148
|
class CFLGrammar : public GrammarBase
|
|
@@ -127,39 +183,39 @@ public:
|
|
|
127
183
|
return secondRHS2Prods;
|
|
128
184
|
}
|
|
129
185
|
|
|
130
|
-
const bool hasProdsFromFirstRHS(Symbol sym) const
|
|
186
|
+
const bool hasProdsFromFirstRHS(const Symbol sym) const
|
|
131
187
|
{
|
|
132
188
|
auto it = firstRHS2Prods.find(sym);
|
|
133
189
|
return it!=firstRHS2Prods.end();
|
|
134
190
|
}
|
|
135
191
|
|
|
136
|
-
const bool hasProdsFromSingleRHS(Symbol sym) const
|
|
192
|
+
const bool hasProdsFromSingleRHS(const Symbol sym) const
|
|
137
193
|
{
|
|
138
194
|
auto it = singleRHS2Prods.find(sym);
|
|
139
195
|
return it!=singleRHS2Prods.end();
|
|
140
196
|
}
|
|
141
197
|
|
|
142
|
-
const bool hasProdsFromSecondRHS(Symbol sym) const
|
|
198
|
+
const bool hasProdsFromSecondRHS(const Symbol sym) const
|
|
143
199
|
{
|
|
144
200
|
auto it = secondRHS2Prods.find(sym);
|
|
145
201
|
return it!=secondRHS2Prods.end();
|
|
146
202
|
}
|
|
147
203
|
|
|
148
|
-
const Productions& getProdsFromSingleRHS(Symbol sym) const
|
|
204
|
+
const Productions& getProdsFromSingleRHS(const Symbol sym) const
|
|
149
205
|
{
|
|
150
206
|
auto it = singleRHS2Prods.find(sym);
|
|
151
207
|
assert(it!=singleRHS2Prods.end() && "production (X -> sym) not found for sym!!");
|
|
152
208
|
return it->second;
|
|
153
209
|
}
|
|
154
210
|
|
|
155
|
-
const Productions& getProdsFromFirstRHS(Symbol sym) const
|
|
211
|
+
const Productions& getProdsFromFirstRHS(const Symbol sym) const
|
|
156
212
|
{
|
|
157
213
|
auto it = firstRHS2Prods.find(sym);
|
|
158
214
|
assert(it!=firstRHS2Prods.end() && "production (X -> sym Y ) not found for sym!!");
|
|
159
215
|
return it->second;
|
|
160
216
|
}
|
|
161
217
|
|
|
162
|
-
const Productions& getProdsFromSecondRHS(Symbol sym) const
|
|
218
|
+
const Productions& getProdsFromSecondRHS(const Symbol sym) const
|
|
163
219
|
{
|
|
164
220
|
auto it = secondRHS2Prods.find(sym);
|
|
165
221
|
assert(it!=secondRHS2Prods.end() && "production (X -> Y sym) not found for sym!!");
|
|
@@ -167,22 +223,22 @@ public:
|
|
|
167
223
|
}
|
|
168
224
|
|
|
169
225
|
|
|
170
|
-
const Symbol& getLHSSymbol(const Production& prod)
|
|
226
|
+
const Symbol& getLHSSymbol(const Production& prod) const
|
|
171
227
|
{
|
|
172
228
|
return prod.at(0);
|
|
173
229
|
}
|
|
174
230
|
|
|
175
|
-
const Symbol& getFirstRHSSymbol(const Production& prod)
|
|
231
|
+
const Symbol& getFirstRHSSymbol(const Production& prod) const
|
|
176
232
|
{
|
|
177
233
|
return prod.at(1);
|
|
178
234
|
}
|
|
179
235
|
|
|
180
|
-
const Symbol& getSecondRHSSymbol(const Production& prod)
|
|
236
|
+
const Symbol& getSecondRHSSymbol(const Production& prod) const
|
|
181
237
|
{
|
|
182
238
|
return prod.at(2);
|
|
183
239
|
}
|
|
184
240
|
|
|
185
|
-
void dump();
|
|
241
|
+
void dump() const;
|
|
186
242
|
|
|
187
243
|
const inline int num_generator()
|
|
188
244
|
{
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
Start:
|
|
2
2
|
V
|
|
3
3
|
Productions:
|
|
4
|
+
F -> Addr;
|
|
5
|
+
F -> Addr ( Copy ) *;
|
|
6
|
+
F -> Addr ( Store V Load ) *;
|
|
4
7
|
F -> ( Copy ) *;
|
|
5
8
|
F -> ( Store V Load ) *;
|
|
9
|
+
Fbar -> Addrbar;
|
|
10
|
+
Fbar -> Addrbar ( Copybar ) *;
|
|
11
|
+
Fbar -> Addrbar ( Loadbar V Storebar ) *;
|
|
6
12
|
Fbar -> ( Copybar ) *;
|
|
7
13
|
Fbar -> ( Loadbar V Storebar ) *;
|
|
8
14
|
V -> Fbar V F;
|
|
9
15
|
V -> Gepbar_i V Gep_i;
|
|
10
16
|
V -> Addrbar Addr;
|
|
11
|
-
V -> epsilon;
|
|
17
|
+
V -> epsilon;
|
|
18
|
+
|
|
19
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Start:
|
|
2
|
+
V
|
|
3
|
+
Productions:
|
|
4
|
+
F -> ( Copy ) *;
|
|
5
|
+
F -> ( Store V Load ) *;
|
|
6
|
+
Fbar -> ( Copybar ) *;
|
|
7
|
+
Fbar -> ( Loadbar Vbar Storebar ) *;
|
|
8
|
+
V -> Fbar V F;
|
|
9
|
+
V -> Gepbar_i V Gep_i;
|
|
10
|
+
V -> Addrbar Addr;
|
|
11
|
+
V -> epsilon;
|
|
12
|
+
Vbar -> Fbar Vbar Fbar;
|
|
13
|
+
Vbar -> Gepbar_i Vbar Gep_i;
|
|
14
|
+
Vbar -> Addrbar Addr;
|
|
15
|
+
Vbar -> epsilon;
|
|
16
|
+
|
|
@@ -39,7 +39,19 @@ namespace SVF
|
|
|
39
39
|
|
|
40
40
|
class CFLGraphBuilder
|
|
41
41
|
{
|
|
42
|
+
private:
|
|
43
|
+
typedef CFLGrammar::Kind Kind;
|
|
44
|
+
typedef CFLGrammar::Symbol Symbol;
|
|
45
|
+
Map<std::string, Kind> label2KindMap;
|
|
46
|
+
Map<Kind, std::string> kind2LabelMap;
|
|
47
|
+
Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>> kind2AttrsMap;
|
|
48
|
+
bool externMap;
|
|
49
|
+
Symbol current;
|
|
50
|
+
|
|
42
51
|
public:
|
|
52
|
+
/// add attribute to kind2Attribute Map
|
|
53
|
+
void addAttribute(CFLGrammar::Kind kind, CFLGrammar::Attribute attribute);
|
|
54
|
+
|
|
43
55
|
/// Build graph by copying nodes and edges from any graph inherited from GenericGraph
|
|
44
56
|
template<class N, class E>
|
|
45
57
|
void build(GenericGraph<N,E>* graph, CFLGraph* cflGraph)
|
|
@@ -61,11 +73,22 @@ public:
|
|
|
61
73
|
|
|
62
74
|
/// Build Bidirectional graph by copying nodes and edges from any graph inherited from GenericGraph
|
|
63
75
|
template<class N, class E>
|
|
64
|
-
CFLGraph* buildBigraph(GenericGraph<N,E>* graph)
|
|
76
|
+
CFLGraph* buildBigraph(GenericGraph<N,E>* graph, Kind startKind)
|
|
65
77
|
{
|
|
66
|
-
CFLGraph *cflGraph = new CFLGraph();
|
|
78
|
+
CFLGraph *cflGraph = new CFLGraph(startKind);
|
|
67
79
|
Map<std::string, SVF::CFLGraph::Symbol> ConstMap = {{"Addr",0}, {"Copy", 1},{"Store", 2},{"Load", 3},{"Gep_i", 4},{"Vgep", 5},{"Addrbar",6}, {"Copybar", 7},{"Storebar", 8},{"Loadbar", 9},{"Gepbar_i", 10},{"Vgepbar", 11}};
|
|
68
|
-
|
|
80
|
+
externMap = true;
|
|
81
|
+
for(auto pairV : ConstMap)
|
|
82
|
+
{
|
|
83
|
+
if(label2KindMap.find(pairV.first) == label2KindMap.end())
|
|
84
|
+
{
|
|
85
|
+
label2KindMap.insert(pairV);
|
|
86
|
+
}
|
|
87
|
+
if(kind2LabelMap.find(pairV.second) == kind2LabelMap.end())
|
|
88
|
+
{
|
|
89
|
+
kind2LabelMap.insert(make_pair(pairV.second, pairV.first));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
69
92
|
for(auto it = graph->begin(); it!= graph->end(); it++)
|
|
70
93
|
{
|
|
71
94
|
CFLNode* node = new CFLNode((*it).first);
|
|
@@ -82,23 +105,23 @@ public:
|
|
|
82
105
|
if(NormalGepCGEdge::classof(edge))
|
|
83
106
|
{
|
|
84
107
|
NormalGepCGEdge *nGepEdge = SVFUtil::dyn_cast<NormalGepCGEdge>(edge);
|
|
85
|
-
CFLGrammar::Attribute
|
|
86
|
-
|
|
87
|
-
edgeLabel = CFLGrammar::getAttributedKind(
|
|
108
|
+
CFLGrammar::Attribute attr = nGepEdge->getConstantFieldIdx();
|
|
109
|
+
addAttribute(edgeLabel, attr);
|
|
110
|
+
edgeLabel = CFLGrammar::getAttributedKind(attr, edgeLabel);
|
|
88
111
|
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel);
|
|
89
|
-
std::string key =
|
|
112
|
+
std::string key = kind2LabelMap[edge->getEdgeKind()];
|
|
90
113
|
key.pop_back();
|
|
91
114
|
key.pop_back(); // _i standsfor attribute variable should place at last
|
|
92
115
|
key.append("bar_i"); // for example Gep_i should be Gepbar_i, not Gep_ibar
|
|
93
|
-
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFLGrammar::getAttributedKind(
|
|
94
|
-
|
|
116
|
+
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFLGrammar::getAttributedKind(attr, label2KindMap[key]));
|
|
117
|
+
addAttribute(label2KindMap[key], attr);
|
|
95
118
|
}
|
|
96
119
|
else
|
|
97
120
|
{
|
|
98
121
|
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel);
|
|
99
|
-
std::string key =
|
|
122
|
+
std::string key = kind2LabelMap[edge->getEdgeKind()];
|
|
100
123
|
key.append("bar");
|
|
101
|
-
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()),
|
|
124
|
+
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), label2KindMap[key]);
|
|
102
125
|
}
|
|
103
126
|
}
|
|
104
127
|
}
|
|
@@ -109,6 +132,23 @@ public:
|
|
|
109
132
|
|
|
110
133
|
/// Build graph from Dot
|
|
111
134
|
CFLGraph *buildFromDot(std::string filename, GrammarBase *grammar);
|
|
135
|
+
|
|
136
|
+
Map<std::string, Kind>& getLabel2KindMap()
|
|
137
|
+
{
|
|
138
|
+
return this->label2KindMap;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
Map<Kind, std::string>& getKind2LabelMap()
|
|
142
|
+
{
|
|
143
|
+
return this->kind2LabelMap;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& getKind2AttrsMap()
|
|
147
|
+
{
|
|
148
|
+
return this->kind2AttrsMap;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
112
152
|
};
|
|
113
153
|
}// SVF
|
|
114
154
|
|
|
@@ -77,16 +77,13 @@ class CFLGraph: public GenericCFLGraphTy
|
|
|
77
77
|
{
|
|
78
78
|
public:
|
|
79
79
|
typedef CFLGrammar::Symbol Symbol;
|
|
80
|
+
typedef CFLGrammar::Kind Kind;
|
|
80
81
|
typedef GenericNode<CFLNode,CFLEdge>::GEdgeSetTy CFLEdgeSet;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>> kind2AttrMap;
|
|
85
|
-
bool externMap;
|
|
86
|
-
Symbol current;
|
|
87
|
-
|
|
88
|
-
CFLGraph()
|
|
82
|
+
Kind startKind;
|
|
83
|
+
|
|
84
|
+
CFLGraph(Kind kind)
|
|
89
85
|
{
|
|
86
|
+
startKind = kind;
|
|
90
87
|
}
|
|
91
88
|
~CFLGraph() override = default;
|
|
92
89
|
|
|
@@ -100,27 +97,6 @@ public:
|
|
|
100
97
|
|
|
101
98
|
void view();
|
|
102
99
|
|
|
103
|
-
void setMap(Map<std::string, Symbol> &labelMap);
|
|
104
|
-
/// Set label2Sym from External
|
|
105
|
-
void setMap(GrammarBase *grammar);
|
|
106
|
-
|
|
107
|
-
/// add attribute to kind2Attribute Map
|
|
108
|
-
void addAttribute(CFLGrammar::Kind kind, CFLGrammar::Attribute attribute)
|
|
109
|
-
{
|
|
110
|
-
if(kind2AttrMap.find(kind) == kind2AttrMap.end())
|
|
111
|
-
{
|
|
112
|
-
Set<CFLGrammar::Attribute> attrs {attribute};
|
|
113
|
-
kind2AttrMap.insert(make_pair(kind, attrs));
|
|
114
|
-
}
|
|
115
|
-
else
|
|
116
|
-
{
|
|
117
|
-
if(kind2AttrMap[kind].find(attribute) == kind2AttrMap[kind].end())
|
|
118
|
-
{
|
|
119
|
-
kind2AttrMap[kind].insert(attribute);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
100
|
private:
|
|
125
101
|
CFLEdgeSet cflEdgeSet;
|
|
126
102
|
|
|
@@ -57,6 +57,7 @@ typedef llvm::ConstantDataSequential ConstantDataSequential;
|
|
|
57
57
|
typedef llvm::ConstantExpr ConstantExpr;
|
|
58
58
|
typedef llvm::ConstantDataArray ConstantDataArray;
|
|
59
59
|
typedef llvm::ConstantData ConstantData;
|
|
60
|
+
typedef llvm::ConstantArray ConstantArray;
|
|
60
61
|
|
|
61
62
|
// LLVM Instructions
|
|
62
63
|
typedef llvm::AllocaInst AllocaInst;
|
|
@@ -66,14 +66,6 @@ inline bool isBlackholeSym(const Value *val)
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
/// Return true if the call is an external call (external library in function summary table)
|
|
70
|
-
/// If the libary function is redefined in the application code (e.g., memcpy), it will return false and will not be treated as an external call.
|
|
71
|
-
//@{
|
|
72
|
-
inline bool isExtCall(const SVFFunction* fun)
|
|
73
|
-
{
|
|
74
|
-
return fun && ExtAPI::getExtAPI()->is_ext(fun);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
69
|
inline bool isExtCall(const CallSite cs)
|
|
78
70
|
{
|
|
79
71
|
return isExtCall(getCallee(cs));
|
|
@@ -91,19 +83,6 @@ inline bool isReturn(const Instruction* inst)
|
|
|
91
83
|
return SVFUtil::isa<ReturnInst>(inst);
|
|
92
84
|
}
|
|
93
85
|
|
|
94
|
-
/// Return true if the call is a heap allocator/reallocator
|
|
95
|
-
//@{
|
|
96
|
-
/// note that these two functions are not suppose to be used externally
|
|
97
|
-
inline bool isHeapAllocExtFunViaRet(const SVFFunction* fun)
|
|
98
|
-
{
|
|
99
|
-
return fun && (ExtAPI::getExtAPI()->is_alloc(fun)
|
|
100
|
-
|| ExtAPI::getExtAPI()->is_realloc(fun));
|
|
101
|
-
}
|
|
102
|
-
inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun)
|
|
103
|
-
{
|
|
104
|
-
return fun && ExtAPI::getExtAPI()->is_arg_alloc(fun);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
86
|
static inline Type *getPtrElementType(const PointerType* pty)
|
|
108
87
|
{
|
|
109
88
|
#if (LLVM_VERSION_MAJOR < 14)
|
|
@@ -148,13 +127,6 @@ inline bool isHeapAllocExtCall(const Instruction *inst)
|
|
|
148
127
|
}
|
|
149
128
|
//@}
|
|
150
129
|
|
|
151
|
-
/// Get the position of argument that holds an allocated heap object.
|
|
152
|
-
//@{
|
|
153
|
-
inline int getHeapAllocHoldingArgPosition(const SVFFunction* fun)
|
|
154
|
-
{
|
|
155
|
-
return ExtAPI::getExtAPI()->get_alloc_arg_pos(fun);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
130
|
inline int getHeapAllocHoldingArgPosition(const CallSite cs)
|
|
159
131
|
{
|
|
160
132
|
return getHeapAllocHoldingArgPosition(getCallee(cs));
|
|
@@ -166,14 +138,6 @@ inline int getHeapAllocHoldingArgPosition(const Instruction *inst)
|
|
|
166
138
|
}
|
|
167
139
|
//@}
|
|
168
140
|
|
|
169
|
-
/// Return true if the call is a heap reallocator
|
|
170
|
-
//@{
|
|
171
|
-
/// note that this function is not suppose to be used externally
|
|
172
|
-
inline bool isReallocExtFun(const SVFFunction* fun)
|
|
173
|
-
{
|
|
174
|
-
return fun && (ExtAPI::getExtAPI()->is_realloc(fun));
|
|
175
|
-
}
|
|
176
|
-
|
|
177
141
|
inline bool isReallocExtCall(const CallSite cs)
|
|
178
142
|
{
|
|
179
143
|
bool isPtrTy = cs.getInstruction()->getType()->isPointerTy();
|
|
@@ -187,14 +151,6 @@ inline bool isReallocExtCall(const Instruction *inst)
|
|
|
187
151
|
}
|
|
188
152
|
//@}
|
|
189
153
|
|
|
190
|
-
/// Return true if the call is a heap dealloc or not
|
|
191
|
-
//@{
|
|
192
|
-
/// note that this function is not suppose to be used externally
|
|
193
|
-
inline bool isDeallocExtFun(const SVFFunction* fun)
|
|
194
|
-
{
|
|
195
|
-
return fun && (ExtAPI::getExtAPI()->is_dealloc(fun));
|
|
196
|
-
}
|
|
197
|
-
|
|
198
154
|
inline bool isDeallocExtCall(const CallSite cs)
|
|
199
155
|
{
|
|
200
156
|
return isDeallocExtFun(getCallee(cs));
|
|
@@ -206,15 +162,6 @@ inline bool isDeallocExtCall(const Instruction *inst)
|
|
|
206
162
|
}
|
|
207
163
|
//@}
|
|
208
164
|
|
|
209
|
-
|
|
210
|
-
/// Return true if the call is a static global call
|
|
211
|
-
//@{
|
|
212
|
-
/// note that this function is not suppose to be used externally
|
|
213
|
-
inline bool isStaticExtFun(const SVFFunction* fun)
|
|
214
|
-
{
|
|
215
|
-
return fun && ExtAPI::getExtAPI()->has_static(fun);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
165
|
inline bool isStaticExtCall(const CallSite cs)
|
|
219
166
|
{
|
|
220
167
|
bool isPtrTy = cs.getInstruction()->getType()->isPointerTy();
|
|
@@ -241,12 +188,6 @@ inline bool isHeapAllocOrStaticExtCall(const Instruction *inst)
|
|
|
241
188
|
}
|
|
242
189
|
//@}
|
|
243
190
|
|
|
244
|
-
/// Return external call type
|
|
245
|
-
inline ExtAPI::extf_t extCallTy(const SVFFunction* fun)
|
|
246
|
-
{
|
|
247
|
-
return ExtAPI::getExtAPI()->get_type(fun);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
191
|
/// Get the reference type of heap/static object from an allocation site.
|
|
251
192
|
//@{
|
|
252
193
|
inline const PointerType *getRefTypeOfHeapAllocOrStatic(const CallSite cs)
|
|
@@ -362,18 +303,6 @@ inline bool isBarrierWaitCall(const Instruction *inst)
|
|
|
362
303
|
}
|
|
363
304
|
//@}
|
|
364
305
|
|
|
365
|
-
/// Return thread fork function
|
|
366
|
-
//@{
|
|
367
|
-
inline const Value* getForkedFun(const CallSite cs)
|
|
368
|
-
{
|
|
369
|
-
return ThreadAPI::getThreadAPI()->getForkedFun(cs);
|
|
370
|
-
}
|
|
371
|
-
inline const Value* getForkedFun(const Instruction *inst)
|
|
372
|
-
{
|
|
373
|
-
return ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
374
|
-
}
|
|
375
|
-
//@}
|
|
376
|
-
|
|
377
306
|
/// Return sole argument of the thread routine
|
|
378
307
|
//@{
|
|
379
308
|
inline const Value* getActualParmAtForkSite(const CallSite cs)
|
|
@@ -413,15 +342,6 @@ inline const Value* getTaskDataAtHareParForSite(const Instruction *inst)
|
|
|
413
342
|
/// Return true if this value refers to a object
|
|
414
343
|
bool isObject (const Value * ref);
|
|
415
344
|
|
|
416
|
-
/// Return true if the value refers to constant data, e.g., i32 0
|
|
417
|
-
inline bool isConstantData(const Value* val)
|
|
418
|
-
{
|
|
419
|
-
return SVFUtil::isa<ConstantData>(val)
|
|
420
|
-
|| SVFUtil::isa<ConstantAggregate>(val)
|
|
421
|
-
|| SVFUtil::isa<MetadataAsValue>(val)
|
|
422
|
-
|| SVFUtil::isa<BlockAddress>(val);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
345
|
/// Method for dead function, which does not have any possible caller
|
|
426
346
|
/// function address is not taken and never be used in call or invoke instruction
|
|
427
347
|
//@{
|
|
@@ -436,43 +356,11 @@ inline bool ArgInDeadFunction (const Value * val)
|
|
|
436
356
|
}
|
|
437
357
|
//@}
|
|
438
358
|
|
|
439
|
-
/// Program entry function e.g. main
|
|
440
|
-
//@{
|
|
441
|
-
/// Return true if this is a program entry function (e.g. main)
|
|
442
|
-
inline bool isProgEntryFunction (const SVFFunction * fun)
|
|
443
|
-
{
|
|
444
|
-
return fun && fun->getName() == "main";
|
|
445
|
-
}
|
|
446
|
-
|
|
447
359
|
inline bool isProgEntryFunction (const Function * fun)
|
|
448
360
|
{
|
|
449
361
|
return fun && fun->getName() == "main";
|
|
450
362
|
}
|
|
451
363
|
|
|
452
|
-
/// Get program entry function from module.
|
|
453
|
-
inline const SVFFunction* getProgFunction(SVFModule* svfModule, const std::string& funName)
|
|
454
|
-
{
|
|
455
|
-
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
456
|
-
{
|
|
457
|
-
const SVFFunction *fun = *it;
|
|
458
|
-
if (fun->getName()==funName)
|
|
459
|
-
return fun;
|
|
460
|
-
}
|
|
461
|
-
return nullptr;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/// Get program entry function from module.
|
|
465
|
-
inline const SVFFunction* getProgEntryFunction(SVFModule* svfModule)
|
|
466
|
-
{
|
|
467
|
-
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
468
|
-
{
|
|
469
|
-
const SVFFunction *fun = *it;
|
|
470
|
-
if (isProgEntryFunction(fun))
|
|
471
|
-
return (fun);
|
|
472
|
-
}
|
|
473
|
-
return nullptr;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
364
|
/// Return true if this is an argument of a program entry function (e.g. main)
|
|
477
365
|
inline bool ArgInProgEntryFunction (const Value * val)
|
|
478
366
|
{
|
|
@@ -483,15 +371,6 @@ inline bool ArgInProgEntryFunction (const Value * val)
|
|
|
483
371
|
bool isPtrInDeadFunction (const Value * value);
|
|
484
372
|
//@}
|
|
485
373
|
|
|
486
|
-
/// Return true if this is a program exit function call
|
|
487
|
-
//@{
|
|
488
|
-
inline bool isProgExitFunction (const SVFFunction * fun)
|
|
489
|
-
{
|
|
490
|
-
return fun && (fun->getName() == "exit" ||
|
|
491
|
-
fun->getName() == "__assert_rtn" ||
|
|
492
|
-
fun->getName() == "__assert_fail" );
|
|
493
|
-
}
|
|
494
|
-
|
|
495
374
|
inline bool isProgExitCall(const CallSite cs)
|
|
496
375
|
{
|
|
497
376
|
return isProgExitFunction(getCallee(cs));
|
|
@@ -677,7 +556,6 @@ u32_t getTypeSizeInBytes(const Type* type);
|
|
|
677
556
|
u32_t getTypeSizeInBytes(const StructType *sty, u32_t field_index);
|
|
678
557
|
//@}
|
|
679
558
|
|
|
680
|
-
const std::string type2String(const Type* type);
|
|
681
559
|
|
|
682
560
|
} // End namespace SVFUtil
|
|
683
561
|
|
|
@@ -94,7 +94,6 @@ typedef llvm::Argument Argument;
|
|
|
94
94
|
typedef llvm::Constant Constant;
|
|
95
95
|
typedef llvm::ConstantInt ConstantInt;
|
|
96
96
|
typedef llvm::ConstantPointerNull ConstantPointerNull;
|
|
97
|
-
typedef llvm::ConstantArray ConstantArray;
|
|
98
97
|
typedef llvm::GlobalAlias GlobalAlias;
|
|
99
98
|
|
|
100
99
|
/// LLVM metadata
|
|
@@ -352,6 +352,130 @@ bool startAnalysisLimitTimer(unsigned timeLimit);
|
|
|
352
352
|
/// timer or not (return value of startLimitTimer).
|
|
353
353
|
void stopAnalysisLimitTimer(bool limitTimerSet);
|
|
354
354
|
|
|
355
|
+
/// Return true if the call is an external call (external library in function summary table)
|
|
356
|
+
/// If the libary function is redefined in the application code (e.g., memcpy), it will return false and will not be treated as an external call.
|
|
357
|
+
//@{
|
|
358
|
+
inline bool isExtCall(const SVFFunction* fun)
|
|
359
|
+
{
|
|
360
|
+
return fun && ExtAPI::getExtAPI()->is_ext(fun);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/// Return true if the call is a heap allocator/reallocator
|
|
364
|
+
//@{
|
|
365
|
+
/// note that these two functions are not suppose to be used externally
|
|
366
|
+
inline bool isHeapAllocExtFunViaRet(const SVFFunction* fun)
|
|
367
|
+
{
|
|
368
|
+
return fun && (ExtAPI::getExtAPI()->is_alloc(fun)
|
|
369
|
+
|| ExtAPI::getExtAPI()->is_realloc(fun));
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun)
|
|
373
|
+
{
|
|
374
|
+
return fun && ExtAPI::getExtAPI()->is_arg_alloc(fun);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/// Get the position of argument that holds an allocated heap object.
|
|
378
|
+
//@{
|
|
379
|
+
inline int getHeapAllocHoldingArgPosition(const SVFFunction* fun)
|
|
380
|
+
{
|
|
381
|
+
return ExtAPI::getExtAPI()->get_alloc_arg_pos(fun);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/// Return true if the call is a heap reallocator
|
|
385
|
+
//@{
|
|
386
|
+
/// note that this function is not suppose to be used externally
|
|
387
|
+
inline bool isReallocExtFun(const SVFFunction* fun)
|
|
388
|
+
{
|
|
389
|
+
return fun && (ExtAPI::getExtAPI()->is_realloc(fun));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/// Return true if the call is a heap dealloc or not
|
|
393
|
+
//@{
|
|
394
|
+
/// note that this function is not suppose to be used externally
|
|
395
|
+
inline bool isDeallocExtFun(const SVFFunction* fun)
|
|
396
|
+
{
|
|
397
|
+
return fun && (ExtAPI::getExtAPI()->is_dealloc(fun));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/// Return true if the call is a static global call
|
|
401
|
+
//@{
|
|
402
|
+
/// note that this function is not suppose to be used externally
|
|
403
|
+
inline bool isStaticExtFun(const SVFFunction* fun)
|
|
404
|
+
{
|
|
405
|
+
return fun && ExtAPI::getExtAPI()->has_static(fun);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/// Return external call type
|
|
409
|
+
inline ExtAPI::extf_t extCallTy(const SVFFunction* fun)
|
|
410
|
+
{
|
|
411
|
+
return ExtAPI::getExtAPI()->get_type(fun);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/// Program entry function e.g. main
|
|
415
|
+
//@{
|
|
416
|
+
/// Return true if this is a program entry function (e.g. main)
|
|
417
|
+
inline bool isProgEntryFunction (const SVFFunction * fun)
|
|
418
|
+
{
|
|
419
|
+
return fun && fun->getName() == "main";
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
/// Get program entry function from module.
|
|
424
|
+
inline const SVFFunction* getProgFunction(SVFModule* svfModule, const std::string& funName)
|
|
425
|
+
{
|
|
426
|
+
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
427
|
+
{
|
|
428
|
+
const SVFFunction *fun = *it;
|
|
429
|
+
if (fun->getName()==funName)
|
|
430
|
+
return fun;
|
|
431
|
+
}
|
|
432
|
+
return nullptr;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/// Get program entry function from module.
|
|
436
|
+
inline const SVFFunction* getProgEntryFunction(SVFModule* svfModule)
|
|
437
|
+
{
|
|
438
|
+
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
439
|
+
{
|
|
440
|
+
const SVFFunction *fun = *it;
|
|
441
|
+
if (isProgEntryFunction(fun))
|
|
442
|
+
return (fun);
|
|
443
|
+
}
|
|
444
|
+
return nullptr;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/// Return true if this is a program exit function call
|
|
448
|
+
//@{
|
|
449
|
+
inline bool isProgExitFunction (const SVFFunction * fun)
|
|
450
|
+
{
|
|
451
|
+
return fun && (fun->getName() == "exit" ||
|
|
452
|
+
fun->getName() == "__assert_rtn" ||
|
|
453
|
+
fun->getName() == "__assert_fail" );
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/// Return true if the value refers to constant data, e.g., i32 0
|
|
457
|
+
inline bool isConstantData(const Value* val)
|
|
458
|
+
{
|
|
459
|
+
return SVFUtil::isa<ConstantData>(val)
|
|
460
|
+
|| SVFUtil::isa<ConstantAggregate>(val)
|
|
461
|
+
|| SVFUtil::isa<MetadataAsValue>(val)
|
|
462
|
+
|| SVFUtil::isa<BlockAddress>(val);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/// Return thread fork function
|
|
466
|
+
//@{
|
|
467
|
+
inline const Value* getForkedFun(const CallSite cs)
|
|
468
|
+
{
|
|
469
|
+
return ThreadAPI::getThreadAPI()->getForkedFun(cs);
|
|
470
|
+
}
|
|
471
|
+
inline const Value* getForkedFun(const Instruction *inst)
|
|
472
|
+
{
|
|
473
|
+
return ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
474
|
+
}
|
|
475
|
+
//@}
|
|
476
|
+
|
|
477
|
+
const std::string type2String(const Type* type);
|
|
478
|
+
|
|
355
479
|
} // End namespace SVFUtil
|
|
356
480
|
|
|
357
481
|
} // End namespace SVF
|