svf-tools 1.0.699 → 1.0.700
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/Util/SVFBugReport.h +24 -86
- package/svf/lib/SABER/DoubleFreeChecker.cpp +2 -2
- package/svf/lib/SABER/FileChecker.cpp +6 -4
- package/svf/lib/SABER/LeakChecker.cpp +6 -4
- package/svf/lib/SABER/ProgSlice.cpp +4 -3
- package/svf/lib/Util/SVFBugReport.cpp +71 -83
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.700",
|
|
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": {
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
#include "Util/cJSON.h"
|
|
38
38
|
#include <set>
|
|
39
39
|
|
|
40
|
+
#define BRANCHFLAGMASK 0x00000010
|
|
41
|
+
#define EVENTTYPEMASK 0x0000000f
|
|
42
|
+
|
|
40
43
|
namespace SVF
|
|
41
44
|
{
|
|
42
45
|
|
|
@@ -45,102 +48,50 @@ namespace SVF
|
|
|
45
48
|
*/
|
|
46
49
|
|
|
47
50
|
|
|
48
|
-
class
|
|
49
|
-
{
|
|
50
|
-
public:
|
|
51
|
-
enum EventType {Branch, Caller, CallSite, Loop, SourceInst};
|
|
52
|
-
|
|
53
|
-
protected:
|
|
54
|
-
EventType eventType;
|
|
55
|
-
|
|
56
|
-
public:
|
|
57
|
-
GenericEvent(EventType eventType): eventType(eventType) { };
|
|
58
|
-
virtual ~GenericEvent() = default;
|
|
59
|
-
|
|
60
|
-
inline EventType getEventType() const
|
|
61
|
-
{
|
|
62
|
-
return eventType;
|
|
63
|
-
}
|
|
64
|
-
virtual const std::string getEventDescription() const = 0;
|
|
65
|
-
virtual const std::string getFuncName() const = 0;
|
|
66
|
-
virtual const std::string getEventLoc() const = 0;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
class BranchEvent: public GenericEvent
|
|
70
|
-
{
|
|
71
|
-
/// branch statement and branch condition true or false
|
|
72
|
-
protected:
|
|
73
|
-
const SVFInstruction *branchInst;
|
|
74
|
-
bool branchSuccessFlg;
|
|
75
|
-
|
|
76
|
-
public:
|
|
77
|
-
BranchEvent(const SVFInstruction *branchInst, bool branchSuccessFlg):
|
|
78
|
-
GenericEvent(GenericEvent::Branch), branchInst(branchInst), branchSuccessFlg(branchSuccessFlg) { }
|
|
79
|
-
|
|
80
|
-
const std::string getEventDescription() const;
|
|
81
|
-
const std::string getFuncName() const;
|
|
82
|
-
const std::string getEventLoc() const;
|
|
83
|
-
|
|
84
|
-
/// ClassOf
|
|
85
|
-
static inline bool classof(const GenericEvent* event)
|
|
86
|
-
{
|
|
87
|
-
return event->getEventType() == GenericEvent::Branch;
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
class CallSiteEvent: public GenericEvent
|
|
51
|
+
class BugEvent
|
|
92
52
|
{
|
|
93
|
-
protected:
|
|
94
|
-
const CallICFGNode *callSite;
|
|
95
|
-
|
|
96
53
|
public:
|
|
97
|
-
|
|
98
|
-
const std::string getEventDescription() const;
|
|
99
|
-
const std::string getFuncName() const;
|
|
100
|
-
const std::string getEventLoc() const;
|
|
101
|
-
|
|
102
|
-
/// ClassOf
|
|
103
|
-
static inline bool classof(const GenericEvent* event)
|
|
54
|
+
enum EventType
|
|
104
55
|
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
56
|
+
Branch = 0x1,
|
|
57
|
+
Caller = 0x2,
|
|
58
|
+
CallSite = 0x3,
|
|
59
|
+
Loop = 0x4,
|
|
60
|
+
SourceInst = 0x5
|
|
61
|
+
};
|
|
108
62
|
|
|
109
|
-
class SourceInstEvent : public GenericEvent
|
|
110
|
-
{
|
|
111
63
|
protected:
|
|
112
|
-
|
|
64
|
+
u32_t typeAndInfoFlag;
|
|
65
|
+
const SVFInstruction *eventInst;
|
|
113
66
|
|
|
114
67
|
public:
|
|
115
|
-
|
|
116
|
-
|
|
68
|
+
BugEvent(u32_t typeAndInfoFlag, const SVFInstruction *eventInst): typeAndInfoFlag(typeAndInfoFlag), eventInst(eventInst) { };
|
|
69
|
+
virtual ~BugEvent() = default;
|
|
117
70
|
|
|
118
|
-
|
|
119
|
-
const std::string getFuncName() const;
|
|
120
|
-
const std::string getEventLoc() const;
|
|
121
|
-
|
|
122
|
-
/// ClassOf
|
|
123
|
-
static inline bool classof(const GenericEvent* event)
|
|
71
|
+
inline u32_t getEventType() const
|
|
124
72
|
{
|
|
125
|
-
return
|
|
73
|
+
return typeAndInfoFlag & EVENTTYPEMASK;
|
|
126
74
|
}
|
|
75
|
+
virtual const std::string getEventDescription() const;
|
|
76
|
+
virtual const std::string getFuncName() const;
|
|
77
|
+
virtual const std::string getEventLoc() const;
|
|
127
78
|
};
|
|
128
79
|
|
|
129
80
|
class GenericBug
|
|
130
81
|
{
|
|
131
82
|
public:
|
|
132
|
-
typedef std::vector<
|
|
83
|
+
typedef std::vector<BugEvent> EventStack;
|
|
133
84
|
|
|
134
85
|
public:
|
|
135
86
|
enum BugType {FULLBUFOVERFLOW, PARTIALBUFOVERFLOW, NEVERFREE, PARTIALLEAK, DOUBLEFREE, FILENEVERCLOSE, FILEPARTIALCLOSE};
|
|
136
87
|
|
|
137
88
|
protected:
|
|
138
89
|
BugType bugType;
|
|
139
|
-
EventStack bugEventStack;
|
|
90
|
+
const EventStack bugEventStack;
|
|
140
91
|
|
|
141
92
|
public:
|
|
142
93
|
/// note: should be initialized with a bugEventStack
|
|
143
|
-
GenericBug(BugType bugType, EventStack bugEventStack):
|
|
94
|
+
GenericBug(BugType bugType, const EventStack &bugEventStack):
|
|
144
95
|
bugType(bugType), bugEventStack(bugEventStack)
|
|
145
96
|
{
|
|
146
97
|
assert(bugEventStack.size() != 0 && "bugEventStack should NOT be empty!");
|
|
@@ -307,13 +258,12 @@ public:
|
|
|
307
258
|
SVFBugReport() = default;
|
|
308
259
|
~SVFBugReport();
|
|
309
260
|
typedef SVF::Set<const GenericBug *> BugSet;
|
|
310
|
-
typedef SVF::Set<const GenericEvent *> EventSet;
|
|
311
261
|
|
|
312
262
|
protected:
|
|
313
263
|
BugSet bugSet; // maintain bugs
|
|
314
|
-
EventSet eventSet;// maintain added events
|
|
315
264
|
|
|
316
265
|
public:
|
|
266
|
+
|
|
317
267
|
/*
|
|
318
268
|
* function: pass bug type (i.e., GenericBug::NEVERFREE) and eventStack as parameter,
|
|
319
269
|
* it will add the bug into bugQueue.
|
|
@@ -321,12 +271,6 @@ public:
|
|
|
321
271
|
*/
|
|
322
272
|
void addSaberBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack)
|
|
323
273
|
{
|
|
324
|
-
/// resign added events
|
|
325
|
-
for(auto eventPtr : eventStack)
|
|
326
|
-
{
|
|
327
|
-
eventSet.insert(eventPtr);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
274
|
/// create and add the bug
|
|
331
275
|
GenericBug *newBug = nullptr;
|
|
332
276
|
switch(bugType)
|
|
@@ -380,12 +324,6 @@ public:
|
|
|
380
324
|
void addAbsExecBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack,
|
|
381
325
|
s64_t allocLowerBound, s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound)
|
|
382
326
|
{
|
|
383
|
-
/// resign added events
|
|
384
|
-
for(auto eventPtr : eventStack)
|
|
385
|
-
{
|
|
386
|
-
eventSet.insert(eventPtr);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
327
|
/// add bugs
|
|
390
328
|
GenericBug *newBug = nullptr;
|
|
391
329
|
switch(bugType)
|
|
@@ -39,10 +39,10 @@ void DoubleFreeChecker::reportBug(ProgSlice* slice)
|
|
|
39
39
|
|
|
40
40
|
if(slice->isSatisfiableForPairs() == false)
|
|
41
41
|
{
|
|
42
|
-
SourceInstEvent*sourceInstEvent = new SourceInstEvent(getSrcCSID(slice->getSource())->getCallSite());
|
|
43
42
|
GenericBug::EventStack eventStack;
|
|
44
43
|
slice->evalFinalCond2Event(eventStack);
|
|
45
|
-
eventStack.push_back(
|
|
44
|
+
eventStack.push_back(
|
|
45
|
+
BugEvent(BugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite()));
|
|
46
46
|
report.addSaberBug(GenericBug::DOUBLEFREE, eventStack);
|
|
47
47
|
}
|
|
48
48
|
if(Options::ValidateTests())
|
|
@@ -39,16 +39,18 @@ void FileChecker::reportBug(ProgSlice* slice)
|
|
|
39
39
|
if(isAllPathReachable() == false && isSomePathReachable() == false)
|
|
40
40
|
{
|
|
41
41
|
// full leakage
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
GenericBug::EventStack eventStack =
|
|
43
|
+
{
|
|
44
|
+
BugEvent(BugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())
|
|
45
|
+
};
|
|
44
46
|
report.addSaberBug(GenericBug::FILENEVERCLOSE, eventStack);
|
|
45
47
|
}
|
|
46
48
|
else if (isAllPathReachable() == false && isSomePathReachable() == true)
|
|
47
49
|
{
|
|
48
|
-
SourceInstEvent*sourceInstEvent = new SourceInstEvent(getSrcCSID(slice->getSource())->getCallSite());
|
|
49
50
|
GenericBug::EventStack eventStack;
|
|
50
51
|
slice->evalFinalCond2Event(eventStack);
|
|
51
|
-
eventStack.push_back(
|
|
52
|
+
eventStack.push_back(
|
|
53
|
+
BugEvent(BugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite()));
|
|
52
54
|
report.addSaberBug(GenericBug::FILEPARTIALCLOSE, eventStack);
|
|
53
55
|
}
|
|
54
56
|
}
|
|
@@ -152,17 +152,19 @@ void LeakChecker::reportBug(ProgSlice* slice)
|
|
|
152
152
|
if(isAllPathReachable() == false && isSomePathReachable() == false)
|
|
153
153
|
{
|
|
154
154
|
// full leakage
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
GenericBug::EventStack eventStack =
|
|
156
|
+
{
|
|
157
|
+
BugEvent(BugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())
|
|
158
|
+
};
|
|
157
159
|
report.addSaberBug(GenericBug::NEVERFREE, eventStack);
|
|
158
160
|
}
|
|
159
161
|
else if (isAllPathReachable() == false && isSomePathReachable() == true)
|
|
160
162
|
{
|
|
161
163
|
// partial leakage
|
|
162
|
-
SourceInstEvent*sourceInstEvent = new SourceInstEvent(getSrcCSID(slice->getSource())->getCallSite());
|
|
163
164
|
GenericBug::EventStack eventStack;
|
|
164
165
|
slice->evalFinalCond2Event(eventStack);
|
|
165
|
-
eventStack.push_back(
|
|
166
|
+
eventStack.push_back(
|
|
167
|
+
BugEvent(BugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite()));
|
|
166
168
|
report.addSaberBug(GenericBug::PARTIALLEAK, eventStack);
|
|
167
169
|
}
|
|
168
170
|
|
|
@@ -149,14 +149,15 @@ const CallICFGNode* ProgSlice::getRetSite(const SVFGEdge* edge) const
|
|
|
149
149
|
void ProgSlice::evalFinalCond2Event(GenericBug::EventStack &eventStack) const
|
|
150
150
|
{
|
|
151
151
|
NodeBS elems = pathAllocator->exactCondElem(finalCond);
|
|
152
|
-
Set<std::string> locations;
|
|
153
152
|
for(NodeBS::iterator it = elems.begin(), eit = elems.end(); it!=eit; ++it)
|
|
154
153
|
{
|
|
155
154
|
const SVFInstruction* tinst = pathAllocator->getCondInst(*it);
|
|
156
155
|
if(pathAllocator->isNegCond(*it))
|
|
157
|
-
eventStack.push_back(
|
|
156
|
+
eventStack.push_back(BugEvent(
|
|
157
|
+
BugEvent::Branch|((((u32_t)false) << 4) & BRANCHFLAGMASK), tinst));
|
|
158
158
|
else
|
|
159
|
-
eventStack.push_back(
|
|
159
|
+
eventStack.push_back(BugEvent(
|
|
160
|
+
BugEvent::Branch|((((u32_t)true) << 4) & BRANCHFLAGMASK), tinst));
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
163
|
|
|
@@ -37,16 +37,16 @@ using namespace SVF;
|
|
|
37
37
|
|
|
38
38
|
const std::string GenericBug::getLoc() const
|
|
39
39
|
{
|
|
40
|
-
const
|
|
41
|
-
assert(
|
|
42
|
-
return sourceInstEvent
|
|
40
|
+
const BugEvent&sourceInstEvent = bugEventStack.at(bugEventStack.size() -1);
|
|
41
|
+
assert(sourceInstEvent.getEventType() == BugEvent::SourceInst && "bugEventStack top should be a SourceInst event");
|
|
42
|
+
return sourceInstEvent.getEventLoc();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const std::string GenericBug::getFuncName() const
|
|
46
46
|
{
|
|
47
|
-
const
|
|
48
|
-
assert(
|
|
49
|
-
return sourceInstEvent
|
|
47
|
+
const BugEvent&sourceInstEvent = bugEventStack.at(bugEventStack.size() -1);
|
|
48
|
+
assert(sourceInstEvent.getEventType() == BugEvent::SourceInst && "bugEventStack top should be a SourceInst event");
|
|
49
|
+
return sourceInstEvent.getFuncName();
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
cJSON *BufferOverflowBug::getBugDescription() const
|
|
@@ -84,22 +84,22 @@ void BufferOverflowBug::printBugToTerminal() const
|
|
|
84
84
|
SVFUtil::errs() << "\t\t Info : \n" << bugInfo.str();
|
|
85
85
|
SVFUtil::errs() << "\t\t Events : \n";
|
|
86
86
|
|
|
87
|
-
for(auto
|
|
87
|
+
for(auto event : bugEventStack)
|
|
88
88
|
{
|
|
89
|
-
switch(
|
|
89
|
+
switch(event.getEventType())
|
|
90
90
|
{
|
|
91
|
-
case
|
|
91
|
+
case BugEvent::CallSite:
|
|
92
92
|
{
|
|
93
|
-
SVFUtil::errs() << "\t\t callsite at : ( " <<
|
|
93
|
+
SVFUtil::errs() << "\t\t callsite at : ( " << event.getEventLoc() << " )\n";
|
|
94
94
|
break;
|
|
95
95
|
}
|
|
96
|
-
default:
|
|
96
|
+
default:
|
|
97
97
|
{
|
|
98
|
+
// TODO: implement more events when needed
|
|
98
99
|
break;
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
|
-
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
cJSON * NeverFreeBug::getBugDescription() const
|
|
@@ -122,9 +122,10 @@ cJSON * PartialLeakBug::getBugDescription() const
|
|
|
122
122
|
for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++)
|
|
123
123
|
{
|
|
124
124
|
cJSON *newBranch = cJSON_CreateObject();
|
|
125
|
-
cJSON *branchLoc = cJSON_Parse((*eventIt)
|
|
125
|
+
cJSON *branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str());
|
|
126
126
|
if(branchLoc == nullptr) branchLoc = cJSON_CreateObject();
|
|
127
|
-
|
|
127
|
+
|
|
128
|
+
cJSON *branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str());
|
|
128
129
|
|
|
129
130
|
cJSON_AddItemToObject(newBranch, "BranchLoc", branchLoc);
|
|
130
131
|
cJSON_AddItemToObject(newBranch, "BranchCond", branchCondition);
|
|
@@ -146,7 +147,7 @@ void PartialLeakBug::printBugToTerminal() const
|
|
|
146
147
|
auto lastBranchEventIt = bugEventStack.end() - 1;
|
|
147
148
|
for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++)
|
|
148
149
|
{
|
|
149
|
-
SVFUtil::errs() << "\t\t --> (" << (*eventIt)
|
|
150
|
+
SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() << ") \n";
|
|
150
151
|
}
|
|
151
152
|
SVFUtil::errs() << "\n";
|
|
152
153
|
}
|
|
@@ -160,9 +161,9 @@ cJSON * DoubleFreeBug::getBugDescription() const
|
|
|
160
161
|
for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++)
|
|
161
162
|
{
|
|
162
163
|
cJSON *newBranch = cJSON_CreateObject();
|
|
163
|
-
cJSON *branchLoc = cJSON_Parse((*eventIt)
|
|
164
|
+
cJSON *branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str());
|
|
164
165
|
if(branchLoc == nullptr) branchLoc = cJSON_CreateObject();
|
|
165
|
-
cJSON *branchCondition = cJSON_CreateString((*eventIt)
|
|
166
|
+
cJSON *branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str());
|
|
166
167
|
|
|
167
168
|
cJSON_AddItemToObject(newBranch, "BranchLoc", branchLoc);
|
|
168
169
|
cJSON_AddItemToObject(newBranch, "BranchCond", branchCondition);
|
|
@@ -183,7 +184,7 @@ void DoubleFreeBug::printBugToTerminal() const
|
|
|
183
184
|
auto lastBranchEventIt = bugEventStack.end() - 1;
|
|
184
185
|
for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++)
|
|
185
186
|
{
|
|
186
|
-
SVFUtil::errs() << "\t\t --> (" << (*eventIt)
|
|
187
|
+
SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() << ") \n";
|
|
187
188
|
}
|
|
188
189
|
SVFUtil::errs() << "\n";
|
|
189
190
|
}
|
|
@@ -210,9 +211,9 @@ cJSON * FilePartialCloseBug::getBugDescription() const
|
|
|
210
211
|
for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++)
|
|
211
212
|
{
|
|
212
213
|
cJSON *newBranch = cJSON_CreateObject();
|
|
213
|
-
cJSON *branchLoc = cJSON_Parse((*eventIt)
|
|
214
|
+
cJSON *branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str());
|
|
214
215
|
if(branchLoc == nullptr) branchLoc = cJSON_CreateObject();
|
|
215
|
-
cJSON *branchCondition = cJSON_CreateString((*eventIt)
|
|
216
|
+
cJSON *branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str());
|
|
216
217
|
|
|
217
218
|
cJSON_AddItemToObject(newBranch, "BranchLoc", branchLoc);
|
|
218
219
|
cJSON_AddItemToObject(newBranch, "BranchCond", branchCondition);
|
|
@@ -233,71 +234,61 @@ void FilePartialCloseBug::printBugToTerminal() const
|
|
|
233
234
|
auto lastBranchEventIt = bugEventStack.end() - 1;
|
|
234
235
|
for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++)
|
|
235
236
|
{
|
|
236
|
-
SVFUtil::errs() << "\t\t --> (" << (*eventIt)
|
|
237
|
+
SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() << ") \n";
|
|
237
238
|
}
|
|
238
239
|
SVFUtil::errs() << "\n";
|
|
239
240
|
}
|
|
240
241
|
|
|
241
|
-
const std::string
|
|
242
|
+
const std::string BugEvent::getFuncName() const
|
|
242
243
|
{
|
|
243
|
-
return
|
|
244
|
+
return eventInst->getFunction()->getName();
|
|
244
245
|
}
|
|
245
246
|
|
|
246
|
-
const std::string
|
|
247
|
+
const std::string BugEvent::getEventLoc() const
|
|
247
248
|
{
|
|
248
|
-
return
|
|
249
|
+
return eventInst->getSourceLoc();
|
|
249
250
|
}
|
|
250
251
|
|
|
251
|
-
const std::string
|
|
252
|
+
const std::string BugEvent::getEventDescription() const
|
|
252
253
|
{
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
254
|
+
switch(getEventType())
|
|
255
|
+
{
|
|
256
|
+
case BugEvent::Branch:
|
|
256
257
|
{
|
|
257
|
-
|
|
258
|
+
if (typeAndInfoFlag & BRANCHFLAGMASK)
|
|
259
|
+
{
|
|
260
|
+
return "True";
|
|
261
|
+
}
|
|
262
|
+
else
|
|
263
|
+
{
|
|
264
|
+
return "False";
|
|
265
|
+
}
|
|
266
|
+
break;
|
|
258
267
|
}
|
|
259
|
-
|
|
268
|
+
case BugEvent::CallSite:
|
|
260
269
|
{
|
|
261
|
-
description
|
|
270
|
+
std::string description("calls ");
|
|
271
|
+
const SVFFunction *callee = SVFUtil::getCallee(eventInst);
|
|
272
|
+
if(callee == nullptr)
|
|
273
|
+
{
|
|
274
|
+
description += "<unknown>";
|
|
275
|
+
}
|
|
276
|
+
else
|
|
277
|
+
{
|
|
278
|
+
description += callee->getName();
|
|
279
|
+
}
|
|
280
|
+
return description;
|
|
281
|
+
break;
|
|
262
282
|
}
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const std::string BranchEvent::getFuncName() const
|
|
267
|
-
{
|
|
268
|
-
return branchInst->getFunction()->getName();
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const std::string BranchEvent::getEventLoc() const
|
|
272
|
-
{
|
|
273
|
-
return branchInst->getSourceLoc();
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const std::string BranchEvent::getEventDescription() const
|
|
277
|
-
{
|
|
278
|
-
if (branchSuccessFlg)
|
|
283
|
+
case BugEvent::SourceInst:
|
|
279
284
|
{
|
|
280
|
-
return "
|
|
285
|
+
return "None";
|
|
281
286
|
}
|
|
282
|
-
|
|
287
|
+
default:
|
|
283
288
|
{
|
|
284
|
-
|
|
289
|
+
assert(false && "No such type of event!");
|
|
290
|
+
}
|
|
285
291
|
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const std::string SourceInstEvent::getFuncName() const
|
|
289
|
-
{
|
|
290
|
-
return sourceSVFInst->getFunction()->getName();
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const std::string SourceInstEvent::getEventLoc() const
|
|
294
|
-
{
|
|
295
|
-
return sourceSVFInst->getSourceLoc();
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const std::string SourceInstEvent::getEventDescription() const
|
|
299
|
-
{
|
|
300
|
-
return "None";
|
|
301
292
|
}
|
|
302
293
|
|
|
303
294
|
SVFBugReport::~SVFBugReport()
|
|
@@ -306,20 +297,16 @@ SVFBugReport::~SVFBugReport()
|
|
|
306
297
|
{
|
|
307
298
|
delete bugIt;
|
|
308
299
|
}
|
|
309
|
-
for(auto eventPtr:eventSet)
|
|
310
|
-
{
|
|
311
|
-
delete eventPtr;
|
|
312
|
-
}
|
|
313
300
|
}
|
|
314
301
|
|
|
315
302
|
void SVFBugReport::dumpToJsonFile(const std::string& filePath)
|
|
316
303
|
{
|
|
317
|
-
std::map<
|
|
304
|
+
std::map<u32_t, std::string> eventType2Str =
|
|
318
305
|
{
|
|
319
|
-
{
|
|
320
|
-
{
|
|
321
|
-
{
|
|
322
|
-
{
|
|
306
|
+
{BugEvent::CallSite, "call site"},
|
|
307
|
+
{BugEvent::Caller, "caller"},
|
|
308
|
+
{BugEvent::Loop, "loop"},
|
|
309
|
+
{BugEvent::Branch, "branch"}
|
|
323
310
|
};
|
|
324
311
|
|
|
325
312
|
std::map<GenericBug::BugType, std::string> bugType2Str =
|
|
@@ -360,32 +347,33 @@ void SVFBugReport::dumpToJsonFile(const std::string& filePath)
|
|
|
360
347
|
|
|
361
348
|
/// add event information to json
|
|
362
349
|
cJSON *eventList = cJSON_CreateArray();
|
|
363
|
-
const GenericBug::EventStack bugEventStack = bugPtr->getEventStack();
|
|
364
|
-
if(BufferOverflowBug::classof(bugPtr))
|
|
350
|
+
const GenericBug::EventStack &bugEventStack = bugPtr->getEventStack();
|
|
351
|
+
if(BufferOverflowBug::classof(bugPtr))
|
|
365
352
|
{
|
|
366
|
-
|
|
353
|
+
// add only when bug is context sensitive
|
|
354
|
+
for(const BugEvent&event : bugEventStack)
|
|
367
355
|
{
|
|
368
|
-
if (
|
|
356
|
+
if (event.getEventType() == BugEvent::SourceInst)
|
|
369
357
|
{
|
|
370
358
|
continue;
|
|
371
359
|
}
|
|
372
360
|
|
|
373
361
|
cJSON *singleEvent = cJSON_CreateObject();
|
|
374
362
|
//event type
|
|
375
|
-
cJSON *eventType = cJSON_CreateString(eventType2Str[
|
|
363
|
+
cJSON *eventType = cJSON_CreateString(eventType2Str[event.getEventType()].c_str());
|
|
376
364
|
cJSON_AddItemToObject(singleEvent, "EventType", eventType);
|
|
377
365
|
//function name
|
|
378
|
-
cJSON *eventFunc = cJSON_CreateString(
|
|
366
|
+
cJSON *eventFunc = cJSON_CreateString(event.getFuncName().c_str());
|
|
379
367
|
cJSON_AddItemToObject(singleEvent, "Function", eventFunc);
|
|
380
368
|
//event loc
|
|
381
|
-
cJSON *eventLoc = cJSON_Parse(
|
|
369
|
+
cJSON *eventLoc = cJSON_Parse(event.getEventLoc().c_str());
|
|
382
370
|
if(eventLoc == nullptr)
|
|
383
371
|
{
|
|
384
372
|
eventLoc = cJSON_CreateObject();
|
|
385
373
|
}
|
|
386
374
|
cJSON_AddItemToObject(singleEvent, "Location", eventLoc);
|
|
387
375
|
//event description
|
|
388
|
-
cJSON *eventDescription = cJSON_CreateString(
|
|
376
|
+
cJSON *eventDescription = cJSON_CreateString(event.getEventDescription().c_str());
|
|
389
377
|
cJSON_AddItemToObject(singleEvent, "Description", eventDescription);
|
|
390
378
|
|
|
391
379
|
cJSON_AddItemToArray(eventList, singleEvent);
|