svf-tools 1.0.982 → 1.0.984
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/package.json +1 -1
- package/svf/include/AE/Svfexe/AbstractInterpretation.h +1 -1
- package/svf/include/Util/SVFUtil.h +15 -37
- package/svf/include/Util/ThreadAPI.h +1 -55
- package/svf/lib/AE/Svfexe/AEDetector.cpp +4 -4
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +33 -46
- package/svf/lib/CFL/CFLAlias.cpp +3 -3
- package/svf/lib/DDA/DDAClient.cpp +2 -2
- package/svf/lib/Graphs/CallGraph.cpp +1 -1
- package/svf/lib/Graphs/ThreadCallGraph.cpp +4 -4
- package/svf/lib/Graphs/VFG.cpp +1 -1
- package/svf/lib/MTA/MTAStat.cpp +1 -1
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +9 -9
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +2 -2
- package/svf/lib/Util/CallGraphBuilder.cpp +1 -1
- package/svf/lib/Util/SVFUtil.cpp +3 -2
- package/svf/lib/Util/ThreadAPI.cpp +2 -19
- package/svf/lib/WPA/Andersen.cpp +1 -1
- package/svf/lib/WPA/AndersenSCD.cpp +1 -1
- package/svf/lib/WPA/Steensgaard.cpp +1 -1
- package/svf/lib/WPA/TypeAnalysis.cpp +1 -1
- package/svf-llvm/lib/CHGBuilder.cpp +1 -1
- package/svf-llvm/lib/SVFIRExtAPI.cpp +5 -5
- package/svf-llvm/lib/SymbolTableBuilder.cpp +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.984",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -358,7 +358,7 @@ protected:
|
|
|
358
358
|
|
|
359
359
|
protected:
|
|
360
360
|
// there data should be shared with subclasses
|
|
361
|
-
Map<std::string, std::function<void(const
|
|
361
|
+
Map<std::string, std::function<void(const CallICFGNode*)>> func_map;
|
|
362
362
|
Set<const CallICFGNode*> checkpoints;
|
|
363
363
|
Set<std::string> checkpoint_names;
|
|
364
364
|
Map<const ICFGNode*, AbstractState>
|
|
@@ -169,14 +169,8 @@ void dumpPointsToList(const PointsToList& ptl);
|
|
|
169
169
|
/// Return true if it is an llvm intrinsic instruction
|
|
170
170
|
bool isIntrinsicInst(const SVFInstruction* inst);
|
|
171
171
|
bool isIntrinsicInst(const ICFGNode* inst);
|
|
172
|
-
|
|
173
172
|
//@}
|
|
174
173
|
|
|
175
|
-
/// Whether an instruction is a call or invoke instruction
|
|
176
|
-
inline bool isCallSite(const SVFInstruction* inst)
|
|
177
|
-
{
|
|
178
|
-
return SVFUtil::isa<SVFCallInst>(inst);
|
|
179
|
-
}
|
|
180
174
|
/// Whether an instruction is a call or invoke instruction
|
|
181
175
|
inline bool isCallSite(const SVFValue* val)
|
|
182
176
|
{
|
|
@@ -207,31 +201,15 @@ inline bool isNonInstricCallSite(const ICFGNode* inst)
|
|
|
207
201
|
}
|
|
208
202
|
|
|
209
203
|
|
|
210
|
-
|
|
211
204
|
/// Return callsite given an instruction
|
|
212
205
|
CallSite getSVFCallSite(const ICFGNode* inst);
|
|
213
206
|
|
|
214
|
-
/// Return callsite given an instruction
|
|
215
|
-
inline CallSite getSVFCallSite(const SVFInstruction* inst)
|
|
216
|
-
{
|
|
217
|
-
assert(isCallSite(inst) && "not a callsite?");
|
|
218
|
-
CallSite cs(inst);
|
|
219
|
-
return cs;
|
|
220
|
-
}
|
|
221
207
|
|
|
222
208
|
/// Match arguments for callsite at caller and callee
|
|
223
209
|
/// if the arg size does not match then we do not need to connect this parameter
|
|
224
210
|
/// unless the callee is a variadic function (the first parameter of variadic function is its parameter number)
|
|
225
|
-
bool matchArgs(const
|
|
211
|
+
bool matchArgs(const CallICFGNode* cs, const SVFFunction* callee);
|
|
226
212
|
|
|
227
|
-
/// Return LLVM callsite given a value
|
|
228
|
-
inline CallSite getSVFCallSite(const SVFValue* value)
|
|
229
|
-
{
|
|
230
|
-
assert(isCallSite(value) && "not a callsite?");
|
|
231
|
-
const SVFCallInst* svfInst = SVFUtil::cast<SVFCallInst>(value);
|
|
232
|
-
CallSite cs(svfInst);
|
|
233
|
-
return cs;
|
|
234
|
-
}
|
|
235
213
|
|
|
236
214
|
/// Split into two substrings around the first occurrence of a separator string.
|
|
237
215
|
inline std::vector<std::string> split(const std::string& s, char separator)
|
|
@@ -423,7 +401,7 @@ inline bool isArgOfUncalledFunction(const SVFValue* svfval)
|
|
|
423
401
|
|
|
424
402
|
/// Return thread fork function
|
|
425
403
|
//@{
|
|
426
|
-
inline const SVFValue* getForkedFun(const
|
|
404
|
+
inline const SVFValue* getForkedFun(const ICFGNode *inst)
|
|
427
405
|
{
|
|
428
406
|
return ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
429
407
|
}
|
|
@@ -488,7 +466,7 @@ inline bool isReallocExtCall(const CallSite cs)
|
|
|
488
466
|
|
|
489
467
|
/// Return true if this is a thread creation call
|
|
490
468
|
///@{
|
|
491
|
-
inline bool isThreadForkCall(const
|
|
469
|
+
inline bool isThreadForkCall(const ICFGNode *inst)
|
|
492
470
|
{
|
|
493
471
|
return ThreadAPI::getThreadAPI()->isTDFork(inst);
|
|
494
472
|
}
|
|
@@ -496,49 +474,49 @@ inline bool isThreadForkCall(const SVFInstruction *inst)
|
|
|
496
474
|
|
|
497
475
|
/// Return true if this is a thread join call
|
|
498
476
|
///@{
|
|
499
|
-
inline bool isThreadJoinCall(const
|
|
477
|
+
inline bool isThreadJoinCall(const ICFGNode* cs)
|
|
500
478
|
{
|
|
501
|
-
return ThreadAPI::getThreadAPI()->isTDJoin(cs
|
|
479
|
+
return ThreadAPI::getThreadAPI()->isTDJoin(cs);
|
|
502
480
|
}
|
|
503
481
|
//@}
|
|
504
482
|
|
|
505
483
|
/// Return true if this is a thread exit call
|
|
506
484
|
///@{
|
|
507
|
-
inline bool isThreadExitCall(const
|
|
485
|
+
inline bool isThreadExitCall(const ICFGNode* cs)
|
|
508
486
|
{
|
|
509
|
-
return ThreadAPI::getThreadAPI()->isTDExit(cs
|
|
487
|
+
return ThreadAPI::getThreadAPI()->isTDExit(cs);
|
|
510
488
|
}
|
|
511
489
|
//@}
|
|
512
490
|
|
|
513
491
|
/// Return true if this is a lock acquire call
|
|
514
492
|
///@{
|
|
515
|
-
inline bool isLockAquireCall(const
|
|
493
|
+
inline bool isLockAquireCall(const ICFGNode* cs)
|
|
516
494
|
{
|
|
517
|
-
return ThreadAPI::getThreadAPI()->isTDAcquire(cs
|
|
495
|
+
return ThreadAPI::getThreadAPI()->isTDAcquire(cs);
|
|
518
496
|
}
|
|
519
497
|
//@}
|
|
520
498
|
|
|
521
499
|
/// Return true if this is a lock acquire call
|
|
522
500
|
///@{
|
|
523
|
-
inline bool isLockReleaseCall(const
|
|
501
|
+
inline bool isLockReleaseCall(const ICFGNode* cs)
|
|
524
502
|
{
|
|
525
|
-
return ThreadAPI::getThreadAPI()->isTDRelease(cs
|
|
503
|
+
return ThreadAPI::getThreadAPI()->isTDRelease(cs);
|
|
526
504
|
}
|
|
527
505
|
//@}
|
|
528
506
|
|
|
529
507
|
/// Return true if this is a barrier wait call
|
|
530
508
|
//@{
|
|
531
|
-
inline bool isBarrierWaitCall(const
|
|
509
|
+
inline bool isBarrierWaitCall(const ICFGNode* cs)
|
|
532
510
|
{
|
|
533
|
-
return ThreadAPI::getThreadAPI()->isTDBarWait(cs
|
|
511
|
+
return ThreadAPI::getThreadAPI()->isTDBarWait(cs);
|
|
534
512
|
}
|
|
535
513
|
//@}
|
|
536
514
|
|
|
537
515
|
/// Return sole argument of the thread routine
|
|
538
516
|
//@{
|
|
539
|
-
inline const SVFValue* getActualParmAtForkSite(const
|
|
517
|
+
inline const SVFValue* getActualParmAtForkSite(const ICFGNode* cs)
|
|
540
518
|
{
|
|
541
|
-
return ThreadAPI::getThreadAPI()->getActualParmAtForkSite(cs
|
|
519
|
+
return ThreadAPI::getThreadAPI()->getActualParmAtForkSite(cs);
|
|
542
520
|
}
|
|
543
521
|
//@}
|
|
544
522
|
|
|
@@ -37,6 +37,7 @@ namespace SVF
|
|
|
37
37
|
|
|
38
38
|
class SVFModule;
|
|
39
39
|
class ICFGNode;
|
|
40
|
+
class CallICFGNode;
|
|
40
41
|
|
|
41
42
|
/*
|
|
42
43
|
* ThreadAPI class contains interfaces for pthread programs
|
|
@@ -121,8 +122,6 @@ public:
|
|
|
121
122
|
/// Return the callee/callsite/func
|
|
122
123
|
//@{
|
|
123
124
|
const SVFFunction* getCallee(const ICFGNode *inst) const;
|
|
124
|
-
const SVFFunction* getCallee(const SVFInstruction *inst) const;
|
|
125
|
-
const CallSite getSVFCallSite(const SVFInstruction *inst) const;
|
|
126
125
|
const CallSite getSVFCallSite(const ICFGNode *inst) const;
|
|
127
126
|
//@}
|
|
128
127
|
|
|
@@ -132,10 +131,6 @@ public:
|
|
|
132
131
|
{
|
|
133
132
|
return getType(getCallee(inst)) == TD_FORK;
|
|
134
133
|
}
|
|
135
|
-
inline bool isTDFork(const SVFInstruction* cs) const
|
|
136
|
-
{
|
|
137
|
-
return getType(getCallee(cs)) == TD_FORK;
|
|
138
|
-
}
|
|
139
134
|
//@}
|
|
140
135
|
|
|
141
136
|
/// Return arguments/attributes of pthread_create / hare_parallel_for
|
|
@@ -148,13 +143,6 @@ public:
|
|
|
148
143
|
CallSite cs = getSVFCallSite(inst);
|
|
149
144
|
return cs.getArgument(0);
|
|
150
145
|
}
|
|
151
|
-
inline const SVFValue* getForkedThread(const SVFInstruction* inst) const
|
|
152
|
-
{
|
|
153
|
-
assert(isTDFork(inst) && "not a thread fork function!");
|
|
154
|
-
CallSite cs = getSVFCallSite(inst);
|
|
155
|
-
return cs.getArgument(0);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
146
|
/// Return the third argument of the call,
|
|
159
147
|
/// Note that, it could be function type or a void* pointer
|
|
160
148
|
inline const SVFValue* getForkedFun(const ICFGNode *inst) const
|
|
@@ -163,12 +151,6 @@ public:
|
|
|
163
151
|
CallSite cs = getSVFCallSite(inst);
|
|
164
152
|
return cs.getArgument(2);
|
|
165
153
|
}
|
|
166
|
-
inline const SVFValue* getForkedFun(const SVFInstruction* inst) const
|
|
167
|
-
{
|
|
168
|
-
assert(isTDFork(inst) && "not a thread fork function!");
|
|
169
|
-
CallSite cs = getSVFCallSite(inst);
|
|
170
|
-
return cs.getArgument(2);
|
|
171
|
-
}
|
|
172
154
|
|
|
173
155
|
/// Return the forth argument of the call,
|
|
174
156
|
/// Note that, it is the sole argument of start routine ( a void* pointer )
|
|
@@ -178,12 +160,6 @@ public:
|
|
|
178
160
|
CallSite cs = getSVFCallSite(inst);
|
|
179
161
|
return cs.getArgument(3);
|
|
180
162
|
}
|
|
181
|
-
inline const SVFValue* getActualParmAtForkSite(const SVFInstruction* inst) const
|
|
182
|
-
{
|
|
183
|
-
assert(isTDFork(inst) && "not a thread fork function!");
|
|
184
|
-
CallSite cs = getSVFCallSite(inst);
|
|
185
|
-
return cs.getArgument(3);
|
|
186
|
-
}
|
|
187
163
|
//@}
|
|
188
164
|
|
|
189
165
|
/// Return true if this call wait for a worker thread
|
|
@@ -192,10 +168,6 @@ public:
|
|
|
192
168
|
{
|
|
193
169
|
return getType(getCallee(inst)) == TD_JOIN;
|
|
194
170
|
}
|
|
195
|
-
inline bool isTDJoin(const SVFInstruction* inst) const
|
|
196
|
-
{
|
|
197
|
-
return getType(getCallee(inst)) == TD_JOIN;
|
|
198
|
-
}
|
|
199
171
|
//@}
|
|
200
172
|
|
|
201
173
|
/// Return arguments/attributes of pthread_join
|
|
@@ -211,12 +183,6 @@ public:
|
|
|
211
183
|
CallSite cs = getSVFCallSite(inst);
|
|
212
184
|
return cs.getArgument(1);
|
|
213
185
|
}
|
|
214
|
-
inline const SVFValue* getRetParmAtJoinedSite(const SVFInstruction* inst) const
|
|
215
|
-
{
|
|
216
|
-
assert(isTDJoin(inst) && "not a thread join function!");
|
|
217
|
-
CallSite cs = getSVFCallSite(inst);
|
|
218
|
-
return cs.getArgument(1);
|
|
219
|
-
}
|
|
220
186
|
//@}
|
|
221
187
|
|
|
222
188
|
|
|
@@ -226,11 +192,6 @@ public:
|
|
|
226
192
|
{
|
|
227
193
|
return getType(getCallee(inst)) == TD_EXIT;
|
|
228
194
|
}
|
|
229
|
-
|
|
230
|
-
inline bool isTDExit(const SVFInstruction* inst) const
|
|
231
|
-
{
|
|
232
|
-
return getType(getCallee(inst)) == TD_EXIT;
|
|
233
|
-
}
|
|
234
195
|
//@}
|
|
235
196
|
|
|
236
197
|
/// Return true if this call acquire a lock
|
|
@@ -239,11 +200,6 @@ public:
|
|
|
239
200
|
{
|
|
240
201
|
return getType(getCallee(inst)) == TD_ACQUIRE;
|
|
241
202
|
}
|
|
242
|
-
|
|
243
|
-
inline bool isTDAcquire(const SVFInstruction* inst) const
|
|
244
|
-
{
|
|
245
|
-
return getType(getCallee(inst)) == TD_ACQUIRE;
|
|
246
|
-
}
|
|
247
203
|
//@}
|
|
248
204
|
|
|
249
205
|
/// Return true if this call release a lock
|
|
@@ -252,11 +208,6 @@ public:
|
|
|
252
208
|
{
|
|
253
209
|
return getType(getCallee(inst)) == TD_RELEASE;
|
|
254
210
|
}
|
|
255
|
-
|
|
256
|
-
inline bool isTDRelease(const SVFInstruction* inst) const
|
|
257
|
-
{
|
|
258
|
-
return getType(getCallee(inst)) == TD_RELEASE;
|
|
259
|
-
}
|
|
260
211
|
//@}
|
|
261
212
|
|
|
262
213
|
/// Return lock value
|
|
@@ -271,11 +222,6 @@ public:
|
|
|
271
222
|
{
|
|
272
223
|
return getType(getCallee(inst)) == TD_BAR_WAIT;
|
|
273
224
|
}
|
|
274
|
-
|
|
275
|
-
inline bool isTDBarWait(const SVFInstruction* inst) const
|
|
276
|
-
{
|
|
277
|
-
return getType(getCallee(inst)) == TD_BAR_WAIT;
|
|
278
|
-
}
|
|
279
225
|
//@}
|
|
280
226
|
|
|
281
227
|
void performAPIStat(SVFModule* m);
|
|
@@ -148,7 +148,7 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
|
|
|
148
148
|
SVFIR* svfir = PAG::getPAG();
|
|
149
149
|
const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite());
|
|
150
150
|
assert(fun && "SVFFunction* is nullptr");
|
|
151
|
-
CallSite cs = SVFUtil::getSVFCallSite(call
|
|
151
|
+
CallSite cs = SVFUtil::getSVFCallSite(call);
|
|
152
152
|
|
|
153
153
|
AbstractInterpretation::ExtAPIType extType = AbstractInterpretation::UNCLASSIFIED;
|
|
154
154
|
|
|
@@ -322,7 +322,7 @@ void BufOverflowDetector::updateGepObjOffsetFromBase(SVF::AddressValue gepAddrs,
|
|
|
322
322
|
*/
|
|
323
323
|
bool BufOverflowDetector::detectStrcpy(AbstractState& as, const CallICFGNode *call)
|
|
324
324
|
{
|
|
325
|
-
CallSite cs = SVFUtil::getSVFCallSite(call
|
|
325
|
+
CallSite cs = SVFUtil::getSVFCallSite(call);
|
|
326
326
|
const SVFValue* arg0Val = cs.getArgument(0);
|
|
327
327
|
const SVFValue* arg1Val = cs.getArgument(1);
|
|
328
328
|
IntervalValue strLen = AbstractInterpretation::getAEInstance().getStrlen(as, arg1Val);
|
|
@@ -349,7 +349,7 @@ bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *ca
|
|
|
349
349
|
|
|
350
350
|
if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
|
|
351
351
|
{
|
|
352
|
-
CallSite cs = SVFUtil::getSVFCallSite(call
|
|
352
|
+
CallSite cs = SVFUtil::getSVFCallSite(call);
|
|
353
353
|
const SVFValue* arg0Val = cs.getArgument(0);
|
|
354
354
|
const SVFValue* arg1Val = cs.getArgument(1);
|
|
355
355
|
IntervalValue strLen0 = AbstractInterpretation::getAEInstance().getStrlen(as, arg0Val);
|
|
@@ -359,7 +359,7 @@ bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *ca
|
|
|
359
359
|
}
|
|
360
360
|
else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
|
|
361
361
|
{
|
|
362
|
-
CallSite cs = SVFUtil::getSVFCallSite(call
|
|
362
|
+
CallSite cs = SVFUtil::getSVFCallSite(call);
|
|
363
363
|
const SVFValue* arg0Val = cs.getArgument(0);
|
|
364
364
|
const SVFValue* arg2Val = cs.getArgument(2);
|
|
365
365
|
IntervalValue arg2Num = as[svfir->getValueNode(arg2Val)].getInterval();
|
|
@@ -963,10 +963,9 @@ void AEStat::performStat()
|
|
|
963
963
|
void AbstractInterpretation::initExtFunMap()
|
|
964
964
|
{
|
|
965
965
|
#define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \
|
|
966
|
-
auto sse_##FUNC_NAME = [this](const
|
|
966
|
+
auto sse_##FUNC_NAME = [this](const CallICFGNode *callNode) { \
|
|
967
967
|
/* run real ext function */ \
|
|
968
|
-
const
|
|
969
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction())); \
|
|
968
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode); \
|
|
970
969
|
AbstractState& as = getAbsStateFromTrace(callNode); \
|
|
971
970
|
u32_t rhs_id = svfir->getValueNode(cs.getArgument(0)); \
|
|
972
971
|
if (!as.inVarToValTable(rhs_id)) return; \
|
|
@@ -997,12 +996,10 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
997
996
|
SSE_FUNC_PROCESS(cosh, cosh);
|
|
998
997
|
SSE_FUNC_PROCESS(tanh, tanh);
|
|
999
998
|
|
|
1000
|
-
auto sse_svf_assert = [this](const
|
|
999
|
+
auto sse_svf_assert = [this](const CallICFGNode* callNode)
|
|
1001
1000
|
{
|
|
1002
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1003
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1004
1001
|
checkpoints.erase(callNode);
|
|
1005
|
-
u32_t arg0 = svfir->getValueNode(
|
|
1002
|
+
u32_t arg0 = svfir->getValueNode(SVFUtil::getSVFCallSite(callNode).getArgument(0));
|
|
1006
1003
|
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1007
1004
|
as[arg0].getInterval().meet_with(IntervalValue(1, 1));
|
|
1008
1005
|
if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
|
|
@@ -1011,18 +1008,17 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1011
1008
|
}
|
|
1012
1009
|
else
|
|
1013
1010
|
{
|
|
1014
|
-
SVFUtil::errs() <<"svf_assert Fail. " <<
|
|
1011
|
+
SVFUtil::errs() <<"svf_assert Fail. " << callNode->toString() << "\n";
|
|
1015
1012
|
assert(false);
|
|
1016
1013
|
}
|
|
1017
1014
|
return;
|
|
1018
1015
|
};
|
|
1019
1016
|
func_map["svf_assert"] = sse_svf_assert;
|
|
1020
1017
|
|
|
1021
|
-
auto svf_print = [&](const
|
|
1018
|
+
auto svf_print = [&](const CallICFGNode* callNode)
|
|
1022
1019
|
{
|
|
1020
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1023
1021
|
if (cs.arg_size() < 2) return;
|
|
1024
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1025
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1026
1022
|
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1027
1023
|
u32_t num_id = svfir->getValueNode(cs.getArgument(0));
|
|
1028
1024
|
std::string text = strRead(as, cs.getArgument(1));
|
|
@@ -1034,11 +1030,10 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1034
1030
|
func_map["svf_print"] = svf_print;
|
|
1035
1031
|
|
|
1036
1032
|
|
|
1037
|
-
auto sse_scanf = [&](const
|
|
1033
|
+
auto sse_scanf = [&](const CallICFGNode* callNode)
|
|
1038
1034
|
{
|
|
1039
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1040
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1041
1035
|
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
1036
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1042
1037
|
//scanf("%d", &data);
|
|
1043
1038
|
if (cs.arg_size() < 2) return;
|
|
1044
1039
|
|
|
@@ -1058,12 +1053,11 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1058
1053
|
}
|
|
1059
1054
|
}
|
|
1060
1055
|
};
|
|
1061
|
-
auto sse_fscanf = [&](const
|
|
1056
|
+
auto sse_fscanf = [&](const CallICFGNode* callNode)
|
|
1062
1057
|
{
|
|
1063
1058
|
//fscanf(stdin, "%d", &data);
|
|
1059
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1064
1060
|
if (cs.arg_size() < 3) return;
|
|
1065
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1066
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1067
1061
|
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
1068
1062
|
u32_t dst_id = svfir->getValueNode(cs.getArgument(2));
|
|
1069
1063
|
if (!as.inVarToAddrsTable(dst_id))
|
|
@@ -1090,11 +1084,10 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1090
1084
|
func_map["__isoc99_sscanf"] = sse_scanf;
|
|
1091
1085
|
func_map["vscanf"] = sse_scanf;
|
|
1092
1086
|
|
|
1093
|
-
auto sse_fread = [&](const
|
|
1087
|
+
auto sse_fread = [&](const CallICFGNode *callNode)
|
|
1094
1088
|
{
|
|
1089
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1095
1090
|
if (cs.arg_size() < 3) return;
|
|
1096
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1097
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1098
1091
|
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1099
1092
|
u32_t block_count_id = svfir->getValueNode(cs.getArgument(2));
|
|
1100
1093
|
u32_t block_size_id = svfir->getValueNode(cs.getArgument(1));
|
|
@@ -1104,16 +1097,15 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1104
1097
|
};
|
|
1105
1098
|
func_map["fread"] = sse_fread;
|
|
1106
1099
|
|
|
1107
|
-
auto sse_sprintf = [&](const
|
|
1100
|
+
auto sse_sprintf = [&](const CallICFGNode *callNode)
|
|
1108
1101
|
{
|
|
1109
1102
|
// printf is difficult to predict since it has no byte size arguments
|
|
1110
1103
|
};
|
|
1111
1104
|
|
|
1112
|
-
auto sse_snprintf = [&](const
|
|
1105
|
+
auto sse_snprintf = [&](const CallICFGNode *callNode)
|
|
1113
1106
|
{
|
|
1107
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1114
1108
|
if (cs.arg_size() < 2) return;
|
|
1115
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1116
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1117
1109
|
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1118
1110
|
u32_t size_id = svfir->getValueNode(cs.getArgument(1));
|
|
1119
1111
|
u32_t dst_id = svfir->getValueNode(cs.getArgument(0));
|
|
@@ -1149,13 +1141,12 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1149
1141
|
func_map["_snwprintf"] = sse_snprintf;
|
|
1150
1142
|
|
|
1151
1143
|
|
|
1152
|
-
auto sse_itoa = [&](const
|
|
1144
|
+
auto sse_itoa = [&](const CallICFGNode* callNode)
|
|
1153
1145
|
{
|
|
1154
1146
|
// itoa(num, ch, 10);
|
|
1155
1147
|
// num: int, ch: char*, 10 is decimal
|
|
1148
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1156
1149
|
if (cs.arg_size() < 3) return;
|
|
1157
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1158
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1159
1150
|
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1160
1151
|
u32_t num_id = svfir->getValueNode(cs.getArgument(0));
|
|
1161
1152
|
|
|
@@ -1165,13 +1156,12 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1165
1156
|
func_map["itoa"] = sse_itoa;
|
|
1166
1157
|
|
|
1167
1158
|
|
|
1168
|
-
auto sse_strlen = [&](const
|
|
1159
|
+
auto sse_strlen = [&](const CallICFGNode *callNode)
|
|
1169
1160
|
{
|
|
1170
1161
|
// check the arg size
|
|
1162
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1171
1163
|
if (cs.arg_size() < 1) return;
|
|
1172
1164
|
const SVFValue* strValue = cs.getArgument(0);
|
|
1173
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1174
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1175
1165
|
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
1176
1166
|
NodeID value_id = svfir->getValueNode(strValue);
|
|
1177
1167
|
u32_t lhsId = svfir->getValueNode(cs.getInstruction());
|
|
@@ -1227,12 +1217,11 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1227
1217
|
func_map["strlen"] = sse_strlen;
|
|
1228
1218
|
func_map["wcslen"] = sse_strlen;
|
|
1229
1219
|
|
|
1230
|
-
auto sse_recv = [&](const
|
|
1220
|
+
auto sse_recv = [&](const CallICFGNode *callNode)
|
|
1231
1221
|
{
|
|
1232
1222
|
// recv(sockfd, buf, len, flags);
|
|
1223
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1233
1224
|
if (cs.arg_size() < 4) return;
|
|
1234
|
-
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(
|
|
1235
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1236
1225
|
AbstractState&as = getAbsStateFromTrace(callNode);
|
|
1237
1226
|
u32_t len_id = svfir->getValueNode(cs.getArgument(2));
|
|
1238
1227
|
IntervalValue len = as[len_id].getInterval() - IntervalValue(1);
|
|
@@ -1241,10 +1230,9 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1241
1230
|
};
|
|
1242
1231
|
func_map["recv"] = sse_recv;
|
|
1243
1232
|
func_map["__recv"] = sse_recv;
|
|
1244
|
-
auto safe_bufaccess = [&](const
|
|
1233
|
+
auto safe_bufaccess = [&](const CallICFGNode *callNode)
|
|
1245
1234
|
{
|
|
1246
|
-
const
|
|
1247
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1235
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1248
1236
|
checkpoints.erase(callNode);
|
|
1249
1237
|
//void SAFE_BUFACCESS(void* data, int size);
|
|
1250
1238
|
if (cs.arg_size() < 2) return;
|
|
@@ -1280,10 +1268,9 @@ void AbstractInterpretation::initExtFunMap()
|
|
|
1280
1268
|
};
|
|
1281
1269
|
func_map["SAFE_BUFACCESS"] = safe_bufaccess;
|
|
1282
1270
|
|
|
1283
|
-
auto unsafe_bufaccess = [&](const
|
|
1271
|
+
auto unsafe_bufaccess = [&](const CallICFGNode *callNode)
|
|
1284
1272
|
{
|
|
1285
|
-
const
|
|
1286
|
-
svfir->getICFG()->getICFGNode(cs.getInstruction()));
|
|
1273
|
+
const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
|
|
1287
1274
|
checkpoints.erase(callNode);
|
|
1288
1275
|
//void UNSAFE_BUFACCESS(void* data, int size);
|
|
1289
1276
|
if (cs.arg_size() < 2) return;
|
|
@@ -1359,7 +1346,7 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
|
|
|
1359
1346
|
AbstractState& as = getAbsStateFromTrace(call);
|
|
1360
1347
|
const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite());
|
|
1361
1348
|
assert(fun && "SVFFunction* is nullptr");
|
|
1362
|
-
CallSite cs = SVFUtil::getSVFCallSite(call
|
|
1349
|
+
CallSite cs = SVFUtil::getSVFCallSite(call);
|
|
1363
1350
|
ExtAPIType extType = UNCLASSIFIED;
|
|
1364
1351
|
// get type of mem api
|
|
1365
1352
|
for (const std::string &annotation: fun->getAnnotations())
|
|
@@ -1377,11 +1364,11 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
|
|
|
1377
1364
|
{
|
|
1378
1365
|
if (func_map.find(fun->getName()) != func_map.end())
|
|
1379
1366
|
{
|
|
1380
|
-
func_map[fun->getName()](
|
|
1367
|
+
func_map[fun->getName()](call);
|
|
1381
1368
|
}
|
|
1382
1369
|
else
|
|
1383
1370
|
{
|
|
1384
|
-
u32_t lhsId = svfir->getValueNode(SVFUtil::getSVFCallSite(call
|
|
1371
|
+
u32_t lhsId = svfir->getValueNode(SVFUtil::getSVFCallSite(call).getInstruction());
|
|
1385
1372
|
if (as.inVarToAddrsTable(lhsId))
|
|
1386
1373
|
{
|
|
1387
1374
|
|
|
@@ -1463,7 +1450,7 @@ void AbstractInterpretation::handleStrcpy(const CallICFGNode *call)
|
|
|
1463
1450
|
// strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk
|
|
1464
1451
|
// get the dst and src
|
|
1465
1452
|
AbstractState& as = getAbsStateFromTrace(call);
|
|
1466
|
-
CallSite cs = SVFUtil::getSVFCallSite(call
|
|
1453
|
+
CallSite cs = SVFUtil::getSVFCallSite(call);
|
|
1467
1454
|
const SVFValue* arg0Val = cs.getArgument(0);
|
|
1468
1455
|
const SVFValue* arg1Val = cs.getArgument(1);
|
|
1469
1456
|
IntervalValue strLen = getStrlen(as, arg1Val);
|
|
@@ -1553,12 +1540,12 @@ void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call)
|
|
|
1553
1540
|
// __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat
|
|
1554
1541
|
// to check it is strcat group or strncat group
|
|
1555
1542
|
AbstractState& as = getAbsStateFromTrace(call);
|
|
1556
|
-
const SVFFunction *fun = SVFUtil::getCallee(call
|
|
1543
|
+
const SVFFunction *fun = SVFUtil::getCallee(call);
|
|
1557
1544
|
const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
|
|
1558
1545
|
const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
|
|
1559
1546
|
if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
|
|
1560
1547
|
{
|
|
1561
|
-
CallSite cs = SVFUtil::getSVFCallSite(call
|
|
1548
|
+
CallSite cs = SVFUtil::getSVFCallSite(call);
|
|
1562
1549
|
const SVFValue* arg0Val = cs.getArgument(0);
|
|
1563
1550
|
const SVFValue* arg1Val = cs.getArgument(1);
|
|
1564
1551
|
IntervalValue strLen0 = getStrlen(as, arg0Val);
|
|
@@ -1569,7 +1556,7 @@ void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call)
|
|
|
1569
1556
|
}
|
|
1570
1557
|
else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
|
|
1571
1558
|
{
|
|
1572
|
-
CallSite cs = SVFUtil::getSVFCallSite(call
|
|
1559
|
+
CallSite cs = SVFUtil::getSVFCallSite(call);
|
|
1573
1560
|
const SVFValue* arg0Val = cs.getArgument(0);
|
|
1574
1561
|
const SVFValue* arg1Val = cs.getArgument(1);
|
|
1575
1562
|
const SVFValue* arg2Val = cs.getArgument(2);
|
package/svf/lib/CFL/CFLAlias.cpp
CHANGED
|
@@ -42,9 +42,9 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call
|
|
|
42
42
|
{
|
|
43
43
|
const CallICFGNode* cs = iter->first;
|
|
44
44
|
|
|
45
|
-
if (SVFUtil::getSVFCallSite(cs
|
|
45
|
+
if (SVFUtil::getSVFCallSite(cs).isVirtualCall())
|
|
46
46
|
{
|
|
47
|
-
const SVFValue* vtbl = SVFUtil::getSVFCallSite(cs
|
|
47
|
+
const SVFValue* vtbl = SVFUtil::getSVFCallSite(cs).getVtablePtr();
|
|
48
48
|
assert(pag->hasValueNode(vtbl));
|
|
49
49
|
NodeID vtblId = pag->getValueNode(vtbl);
|
|
50
50
|
resolveCPPIndCalls(cs, getCFLPts(vtblId), newEdges);
|
|
@@ -175,7 +175,7 @@ bool CFLAlias::updateCallGraph(const CallSiteToFunPtrMap& callsites)
|
|
|
175
175
|
onTheFlyCallGraphSolve(callsites,newEdges);
|
|
176
176
|
for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it )
|
|
177
177
|
{
|
|
178
|
-
CallSite cs = SVFUtil::getSVFCallSite(it->first
|
|
178
|
+
CallSite cs = SVFUtil::getSVFCallSite(it->first);
|
|
179
179
|
for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
|
|
180
180
|
{
|
|
181
181
|
connectCaller2CalleeParams(cs,*cit);
|
|
@@ -81,9 +81,9 @@ OrderedNodeSet& FunptrDDAClient::collectCandidateQueries(SVFIR* p)
|
|
|
81
81
|
for(SVFIR::CallSiteToFunPtrMap::const_iterator it = pag->getIndirectCallsites().begin(),
|
|
82
82
|
eit = pag->getIndirectCallsites().end(); it!=eit; ++it)
|
|
83
83
|
{
|
|
84
|
-
if (SVFUtil::getSVFCallSite(it->first
|
|
84
|
+
if (SVFUtil::getSVFCallSite(it->first).isVirtualCall())
|
|
85
85
|
{
|
|
86
|
-
const SVFValue* vtblPtr = SVFUtil::getSVFCallSite(it->first
|
|
86
|
+
const SVFValue* vtblPtr = SVFUtil::getSVFCallSite(it->first).getVtablePtr();
|
|
87
87
|
assert(pag->hasValueNode(vtblPtr) && "not a vtable pointer?");
|
|
88
88
|
NodeID vtblId = pag->getValueNode(vtblPtr);
|
|
89
89
|
addCandidate(vtblId);
|
|
@@ -51,7 +51,7 @@ void CallGraphEdge::addDirectCallSite(const CallICFGNode* call)
|
|
|
51
51
|
|
|
52
52
|
void CallGraphEdge::addInDirectCallSite(const CallICFGNode* call)
|
|
53
53
|
{
|
|
54
|
-
assert((nullptr == SVFUtil::getCallee(call->getCallSite()) || nullptr == SVFUtil::dyn_cast<SVFFunction> (SVFUtil::getForkedFun(call
|
|
54
|
+
assert((nullptr == SVFUtil::getCallee(call->getCallSite()) || nullptr == SVFUtil::dyn_cast<SVFFunction> (SVFUtil::getForkedFun(call))) && "not an indirect callsite??");
|
|
55
55
|
indirectCalls.insert(call);
|
|
56
56
|
}
|
|
57
57
|
//@}
|
|
@@ -70,7 +70,7 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta)
|
|
|
70
70
|
// Fork sites
|
|
71
71
|
for (CallSiteSet::const_iterator it = forksitesBegin(), eit = forksitesEnd(); it != eit; ++it)
|
|
72
72
|
{
|
|
73
|
-
const SVFValue* forkedval = tdAPI->getForkedFun(
|
|
73
|
+
const SVFValue* forkedval = tdAPI->getForkedFun(*it);
|
|
74
74
|
if(SVFUtil::dyn_cast<SVFFunction>(forkedval)==nullptr)
|
|
75
75
|
{
|
|
76
76
|
SVFIR* pag = pta->getPAG();
|
|
@@ -105,7 +105,7 @@ void ThreadCallGraph::updateJoinEdge(PointerAnalysis* pta)
|
|
|
105
105
|
CallSiteSet forkset;
|
|
106
106
|
for (CallSiteSet::const_iterator it = forksitesBegin(), eit = forksitesEnd(); it != eit; ++it)
|
|
107
107
|
{
|
|
108
|
-
const SVFValue* forkthread = tdAPI->getForkedThread(
|
|
108
|
+
const SVFValue* forkthread = tdAPI->getForkedThread(*it);
|
|
109
109
|
if (pta->alias(jointhread, forkthread))
|
|
110
110
|
{
|
|
111
111
|
forkset.insert(*it);
|
|
@@ -123,7 +123,7 @@ void ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs)
|
|
|
123
123
|
{
|
|
124
124
|
|
|
125
125
|
CallGraphNode* caller = getCallGraphNode(cs->getCaller());
|
|
126
|
-
const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs
|
|
126
|
+
const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs));
|
|
127
127
|
assert(forkee && "callee does not exist");
|
|
128
128
|
CallGraphNode* callee = getCallGraphNode(forkee->getDefFunForMultipleModule());
|
|
129
129
|
CallSiteID csId = addCallSite(cs, callee->getFunction());
|
|
@@ -176,7 +176,7 @@ void ThreadCallGraph::addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet
|
|
|
176
176
|
for (CallSiteSet::const_iterator it = forkset.begin(), eit = forkset.end(); it != eit; ++it)
|
|
177
177
|
{
|
|
178
178
|
|
|
179
|
-
const SVFFunction* threadRoutineFun = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(
|
|
179
|
+
const SVFFunction* threadRoutineFun = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(*it));
|
|
180
180
|
assert(threadRoutineFun && "thread routine function does not exist");
|
|
181
181
|
CallGraphNode* threadRoutineFunNode = getCallGraphNode(threadRoutineFun);
|
|
182
182
|
CallSiteID csId = addCallSite(cs, threadRoutineFun);
|
package/svf/lib/Graphs/VFG.cpp
CHANGED
|
@@ -979,7 +979,7 @@ void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const SVFFun
|
|
|
979
979
|
RetICFGNode* retBlockNode = icfg->getRetICFGNode(callBlockNode->getCallSite());
|
|
980
980
|
// connect actual and formal param
|
|
981
981
|
if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(callee) &&
|
|
982
|
-
matchArgs(callBlockNode
|
|
982
|
+
matchArgs(callBlockNode, callee))
|
|
983
983
|
{
|
|
984
984
|
const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callBlockNode);
|
|
985
985
|
const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(callee);
|
package/svf/lib/MTA/MTAStat.cpp
CHANGED
|
@@ -49,7 +49,7 @@ void MTAStat::performThreadCallGraphStat(ThreadCallGraph* tcg)
|
|
|
49
49
|
for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it)
|
|
50
50
|
{
|
|
51
51
|
bool indirectfork = false;
|
|
52
|
-
const SVFFunction* spawnee = SVFUtil::dyn_cast<SVFFunction>(tcg->getThreadAPI()->getForkedFun(
|
|
52
|
+
const SVFFunction* spawnee = SVFUtil::dyn_cast<SVFFunction>(tcg->getThreadAPI()->getForkedFun(*it));
|
|
53
53
|
if(spawnee==nullptr)
|
|
54
54
|
{
|
|
55
55
|
numOfIndForksite++;
|
|
@@ -404,7 +404,7 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta
|
|
|
404
404
|
const SVFFunction* calleefun = SVFUtil::cast<SVFFunction>(obj->getValue());
|
|
405
405
|
const SVFFunction* callee = calleefun->getDefFunForMultipleModule();
|
|
406
406
|
|
|
407
|
-
if(SVFUtil::matchArgs(cs
|
|
407
|
+
if(SVFUtil::matchArgs(cs, callee) == false)
|
|
408
408
|
continue;
|
|
409
409
|
|
|
410
410
|
if(0 == getIndCallMap()[cs].count(callee))
|
|
@@ -428,8 +428,8 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta
|
|
|
428
428
|
*/
|
|
429
429
|
void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns)
|
|
430
430
|
{
|
|
431
|
-
if (chgraph->csHasVFnsBasedonCHA(SVFUtil::getSVFCallSite(cs
|
|
432
|
-
vfns = chgraph->getCSVFsBasedonCHA(SVFUtil::getSVFCallSite(cs
|
|
431
|
+
if (chgraph->csHasVFnsBasedonCHA(SVFUtil::getSVFCallSite(cs)))
|
|
432
|
+
vfns = chgraph->getCSVFsBasedonCHA(SVFUtil::getSVFCallSite(cs));
|
|
433
433
|
}
|
|
434
434
|
|
|
435
435
|
/*
|
|
@@ -438,10 +438,10 @@ void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns)
|
|
|
438
438
|
void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &target, VFunSet &vfns)
|
|
439
439
|
{
|
|
440
440
|
|
|
441
|
-
if (chgraph->csHasVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs
|
|
441
|
+
if (chgraph->csHasVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs)))
|
|
442
442
|
{
|
|
443
443
|
Set<const SVFGlobalValue*> vtbls;
|
|
444
|
-
const VTableSet &chaVtbls = chgraph->getCSVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs
|
|
444
|
+
const VTableSet &chaVtbls = chgraph->getCSVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs));
|
|
445
445
|
for (PointsTo::iterator it = target.begin(), eit = target.end(); it != eit; ++it)
|
|
446
446
|
{
|
|
447
447
|
const PAGNode *ptdnode = pag->getGNode(*it);
|
|
@@ -454,7 +454,7 @@ void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &tar
|
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
|
-
chgraph->getVFnsFromVtbls(SVFUtil::getSVFCallSite(cs
|
|
457
|
+
chgraph->getVFnsFromVtbls(SVFUtil::getSVFCallSite(cs), vtbls, vfns);
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
460
|
|
|
@@ -471,8 +471,8 @@ void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet &
|
|
|
471
471
|
callee = callee->getDefFunForMultipleModule();
|
|
472
472
|
if (getIndCallMap()[cs].count(callee) > 0)
|
|
473
473
|
continue;
|
|
474
|
-
if(SVFUtil::getSVFCallSite(cs
|
|
475
|
-
(SVFUtil::getSVFCallSite(cs
|
|
474
|
+
if(SVFUtil::getSVFCallSite(cs).arg_size() == callee->arg_size() ||
|
|
475
|
+
(SVFUtil::getSVFCallSite(cs).isVarArg() && callee->isVarArg()))
|
|
476
476
|
{
|
|
477
477
|
newEdges[cs].insert(callee);
|
|
478
478
|
getIndCallMap()[cs].insert(callee);
|
|
@@ -485,7 +485,7 @@ void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet &
|
|
|
485
485
|
/// Resolve cpp indirect call edges
|
|
486
486
|
void PointerAnalysis::resolveCPPIndCalls(const CallICFGNode* cs, const PointsTo& target, CallEdgeMap& newEdges)
|
|
487
487
|
{
|
|
488
|
-
assert(SVFUtil::getSVFCallSite(cs
|
|
488
|
+
assert(SVFUtil::getSVFCallSite(cs).isVirtualCall() && "not cpp virtual call");
|
|
489
489
|
|
|
490
490
|
VFunSet vfns;
|
|
491
491
|
if (Options::ConnectVCallOnCHA())
|
|
@@ -495,9 +495,9 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,
|
|
|
495
495
|
{
|
|
496
496
|
const CallICFGNode* cs = iter->first;
|
|
497
497
|
|
|
498
|
-
if (SVFUtil::getSVFCallSite(cs
|
|
498
|
+
if (SVFUtil::getSVFCallSite(cs).isVirtualCall())
|
|
499
499
|
{
|
|
500
|
-
const SVFValue* vtbl = SVFUtil::getSVFCallSite(cs
|
|
500
|
+
const SVFValue* vtbl = SVFUtil::getSVFCallSite(cs).getVtablePtr();
|
|
501
501
|
assert(pag->hasValueNode(vtbl));
|
|
502
502
|
NodeID vtblId = pag->getValueNode(vtbl);
|
|
503
503
|
resolveCPPIndCalls(cs, getPts(vtblId), newEdges);
|
|
@@ -84,7 +84,7 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
|
|
|
84
84
|
{
|
|
85
85
|
const CallICFGNode* cs = cast<CallICFGNode>(inst);
|
|
86
86
|
cg->addForksite(cs);
|
|
87
|
-
const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(
|
|
87
|
+
const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs));
|
|
88
88
|
if (forkee)
|
|
89
89
|
{
|
|
90
90
|
cg->addDirectForkEdge(cs);
|
package/svf/lib/Util/SVFUtil.cpp
CHANGED
|
@@ -317,9 +317,10 @@ void SVFUtil::stopAnalysisLimitTimer(bool limitTimerSet)
|
|
|
317
317
|
/// unless the callee is a variadic function (the first parameter of variadic function is its parameter number)
|
|
318
318
|
/// e.g., void variadicFoo(int num, ...); variadicFoo(5, 1,2,3,4,5)
|
|
319
319
|
/// for variadic function, callsite arg size must be greater than or equal to callee arg size
|
|
320
|
-
bool SVFUtil::matchArgs(const
|
|
320
|
+
bool SVFUtil::matchArgs(const CallICFGNode* call, const SVFFunction* callee)
|
|
321
321
|
{
|
|
322
|
-
|
|
322
|
+
CallSite cs(call->getCallSite());
|
|
323
|
+
if (callee->isVarArg() || ThreadAPI::getThreadAPI()->isTDFork(call))
|
|
323
324
|
return cs.arg_size() >= callee->arg_size();
|
|
324
325
|
else
|
|
325
326
|
return cs.arg_size() == callee->arg_size();
|
|
@@ -140,15 +140,6 @@ const SVFFunction* ThreadAPI::getCallee(const ICFGNode *inst) const
|
|
|
140
140
|
return nullptr;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
/*!
|
|
144
|
-
*
|
|
145
|
-
*/
|
|
146
|
-
const SVFFunction* ThreadAPI::getCallee(const SVFInstruction *inst) const
|
|
147
|
-
{
|
|
148
|
-
return SVFUtil::getCallee(inst);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
143
|
const CallSite ThreadAPI::getSVFCallSite(const ICFGNode *inst) const
|
|
153
144
|
{
|
|
154
145
|
assert(SVFUtil::isa<CallICFGNode>(inst) && "not a callsite?");
|
|
@@ -160,19 +151,11 @@ const SVFValue* ThreadAPI::getLockVal(const ICFGNode *inst) const
|
|
|
160
151
|
{
|
|
161
152
|
const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst);
|
|
162
153
|
assert(call && "not a call ICFGNode?");
|
|
163
|
-
assert((isTDAcquire(call
|
|
164
|
-
CallSite cs = getSVFCallSite(call
|
|
154
|
+
assert((isTDAcquire(call) || isTDRelease(call)) && "not a lock acquire or release function");
|
|
155
|
+
CallSite cs = getSVFCallSite(call);
|
|
165
156
|
return cs.getArgument(0);
|
|
166
157
|
}
|
|
167
158
|
|
|
168
|
-
/*!
|
|
169
|
-
*
|
|
170
|
-
*/
|
|
171
|
-
const CallSite ThreadAPI::getSVFCallSite(const SVFInstruction *inst) const
|
|
172
|
-
{
|
|
173
|
-
return SVFUtil::getSVFCallSite(inst);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
159
|
const SVFValue* ThreadAPI::getJoinedThread(const ICFGNode *inst) const
|
|
177
160
|
{
|
|
178
161
|
assert(isTDJoin(inst) && "not a thread join function!");
|
package/svf/lib/WPA/Andersen.cpp
CHANGED
|
@@ -661,7 +661,7 @@ bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites)
|
|
|
661
661
|
NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge
|
|
662
662
|
for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it )
|
|
663
663
|
{
|
|
664
|
-
CallSite cs = SVFUtil::getSVFCallSite(it->first
|
|
664
|
+
CallSite cs = SVFUtil::getSVFCallSite(it->first);
|
|
665
665
|
for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
|
|
666
666
|
{
|
|
667
667
|
connectCaller2CalleeParams(cs,*cit,cpySrcNodes);
|
|
@@ -281,7 +281,7 @@ bool AndersenSCD::updateCallGraph(const PointerAnalysis::CallSiteToFunPtrMap& ca
|
|
|
281
281
|
NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge
|
|
282
282
|
for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it )
|
|
283
283
|
{
|
|
284
|
-
CallSite cs = SVFUtil::getSVFCallSite(it->first
|
|
284
|
+
CallSite cs = SVFUtil::getSVFCallSite(it->first);
|
|
285
285
|
for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
|
|
286
286
|
{
|
|
287
287
|
connectCaller2CalleeParams(cs,*cit,cpySrcNodes);
|
|
@@ -135,7 +135,7 @@ bool Steensgaard::updateCallGraph(const CallSiteToFunPtrMap& callsites)
|
|
|
135
135
|
for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end();
|
|
136
136
|
it != eit; ++it)
|
|
137
137
|
{
|
|
138
|
-
CallSite cs = SVFUtil::getSVFCallSite(it->first
|
|
138
|
+
CallSite cs = SVFUtil::getSVFCallSite(it->first);
|
|
139
139
|
for (FunctionSet::iterator cit = it->second.begin(),
|
|
140
140
|
ecit = it->second.end();
|
|
141
141
|
cit != ecit; ++cit)
|
|
@@ -77,7 +77,7 @@ void TypeAnalysis::callGraphSolveBasedOnCHA(const CallSiteToFunPtrMap& callsites
|
|
|
77
77
|
for(CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter!=eiter; ++iter)
|
|
78
78
|
{
|
|
79
79
|
const CallICFGNode* cbn = iter->first;
|
|
80
|
-
CallSite cs = SVFUtil::getSVFCallSite(cbn
|
|
80
|
+
CallSite cs = SVFUtil::getSVFCallSite(cbn);
|
|
81
81
|
if (cs.isVirtualCall())
|
|
82
82
|
{
|
|
83
83
|
const SVFValue* vtbl = cs.getVtablePtr();
|
|
@@ -679,7 +679,7 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()
|
|
|
679
679
|
}
|
|
680
680
|
if (vtbls.size() > 0)
|
|
681
681
|
{
|
|
682
|
-
CallSite cs
|
|
682
|
+
CallSite cs(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(callInst));
|
|
683
683
|
chg->csToCHAVtblsMap[cs] = vtbls;
|
|
684
684
|
VFunSet virtualFunctions;
|
|
685
685
|
chg->getVFnsFromVtbls(cs, vtbls, virtualFunctions);
|
|
@@ -125,6 +125,7 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
|
|
|
125
125
|
{
|
|
126
126
|
const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
|
|
127
127
|
const SVFCallInst* svfCall = SVFUtil::cast<SVFCallInst>(svfInst);
|
|
128
|
+
const CallICFGNode *callICFGNode = pag->getICFG()->getCallICFGNode(svfInst);
|
|
128
129
|
|
|
129
130
|
if (isHeapAllocExtCallViaRet(svfCall))
|
|
130
131
|
{
|
|
@@ -253,12 +254,12 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
|
|
|
253
254
|
}
|
|
254
255
|
}
|
|
255
256
|
|
|
256
|
-
if (isThreadForkCall(
|
|
257
|
+
if (isThreadForkCall(callICFGNode))
|
|
257
258
|
{
|
|
258
|
-
if (const SVFFunction* forkedFun = SVFUtil::dyn_cast<SVFFunction>(getForkedFun(
|
|
259
|
+
if (const SVFFunction* forkedFun = SVFUtil::dyn_cast<SVFFunction>(getForkedFun(callICFGNode)))
|
|
259
260
|
{
|
|
260
261
|
forkedFun = forkedFun->getDefFunForMultipleModule();
|
|
261
|
-
const SVFValue* actualParm = getActualParmAtForkSite(
|
|
262
|
+
const SVFValue* actualParm = getActualParmAtForkSite(callICFGNode);
|
|
262
263
|
/// pthread_create has 1 arg.
|
|
263
264
|
/// apr_thread_create has 2 arg.
|
|
264
265
|
assert((forkedFun->arg_size() <= 2) && "Size of formal parameter of start routine should be one");
|
|
@@ -268,9 +269,8 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
|
|
|
268
269
|
/// Connect actual parameter to formal parameter of the start routine
|
|
269
270
|
if (actualParm->getType()->isPointerTy() && formalParm->getType()->isPointerTy())
|
|
270
271
|
{
|
|
271
|
-
CallICFGNode *icfgNode = pag->getICFG()->getCallICFGNode(svfInst);
|
|
272
272
|
FunEntryICFGNode *entry = pag->getICFG()->getFunEntryICFGNode(forkedFun);
|
|
273
|
-
addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm),
|
|
273
|
+
addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm), callICFGNode, entry);
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
276
|
}
|
|
@@ -608,7 +608,7 @@ const Type* SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj(const Instruction
|
|
|
608
608
|
else if(SVFUtil::isHeapAllocExtCallViaArg(svfinst))
|
|
609
609
|
{
|
|
610
610
|
const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
|
|
611
|
-
int arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(
|
|
611
|
+
int arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(getCallee(svfinst));
|
|
612
612
|
const Value* arg = cs->getArgOperand(arg_pos);
|
|
613
613
|
originalPType = SVFUtil::dyn_cast<PointerType>(arg->getType());
|
|
614
614
|
inferedType = inferObjType(startValue = arg);
|