svf-tools 1.0.976 → 1.0.978

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.
@@ -1,364 +0,0 @@
1
- //===- PCG.cpp -- Procedure creation graph-------------//
2
- //
3
- // SVF: Static Value-Flow Analysis
4
- //
5
- // Copyright (C) <2013-> <Yulei Sui>
6
- //
7
-
8
- // This program is free software: you can redistribute it and/or modify
9
- // it under the terms of the GNU Affero General Public License as published by
10
- // the Free Software Foundation, either version 3 of the License, or
11
- // (at your option) any later version.
12
-
13
- // This program is distributed in the hope that it will be useful,
14
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- // GNU Affero General Public License for more details.
17
-
18
- // You should have received a copy of the GNU Affero General Public License
19
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
- //
21
- //===----------------------------------------------------------------------===//
22
-
23
- /*
24
- * PCG.cpp
25
- *
26
- * Created on: Jun 24, 2015
27
- * Author: Yulei Sui, Peng Di
28
- */
29
-
30
- #include "Util/CommandLine.h"
31
- #include "Util/Options.h"
32
- #include "MTA/PCG.h"
33
- #include "Util/SVFUtil.h"
34
-
35
- using namespace SVF;
36
- using namespace SVFUtil;
37
-
38
- //=====================================================//
39
- /*!
40
- * Whether two functions may happen in parallel
41
- */
42
-
43
- //static Option<bool> TDPrint(
44
- // "print-td",
45
- // true,
46
- // "Print Thread Analysis Results"
47
- //);
48
-
49
- bool PCG::analyze()
50
- {
51
-
52
- //callgraph = new CallGraph(mod);
53
-
54
- DBOUT(DMTA, outs() << pasMsg("Starting MHP analysis\n"));
55
-
56
- initFromThreadAPI(mod);
57
-
58
- inferFromCallGraph();
59
-
60
- //interferenceAnalysis();
61
-
62
- //if (Options::TDPrint()) {
63
- //printResults();
64
- //tdAPI->performAPIStat(mod);
65
- //}
66
- return false;
67
- }
68
-
69
- bool PCG::mayHappenInParallelBetweenFunctions(const SVFFunction* fun1, const SVFFunction* fun2) const
70
- {
71
- // if neither of functions are spawnees, then they won't happen in parallel
72
- if (isSpawneeFun(fun1) == false && isSpawneeFun(fun2) == false)
73
- return false;
74
- // if there exit one of the function are not spawner, spawnee or follower, then they won't happen in parallel
75
- if (isSpawnerFun(fun1) == false && isSpawneeFun(fun1) == false && isFollowerFun(fun1) == false)
76
- return false;
77
- if (isSpawnerFun(fun2) == false && isSpawneeFun(fun2) == false && isFollowerFun(fun2) == false)
78
- return false;
79
-
80
- return true;
81
- }
82
-
83
- bool PCG::mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2) const
84
- {
85
- const SVFFunction* fun1 = i1->getFunction();
86
- const SVFFunction* fun2 = i2->getFunction();
87
- return mayHappenInParallelBetweenFunctions(fun1, fun2);
88
- }
89
-
90
-
91
- /*!
92
- * Initialize thread spawners and spawnees from threadAPI functions
93
- * a procedure is a spawner if it creates a thread and the created thread is still existent on its return
94
- * a procedure is a spawnee if it is created by fork call
95
- */
96
- void PCG::initFromThreadAPI(SVFModule* module)
97
- {
98
- for (const SVFFunction* fun : module->getFunctionSet())
99
- {
100
- for (const SVFBasicBlock* svfbb : fun->getBasicBlockList())
101
- {
102
- for (const SVFInstruction* inst : svfbb->getInstructionList())
103
- {
104
- if (tdAPI->isTDFork(inst))
105
- {
106
- const SVFValue* forkVal = tdAPI->getForkedFun(inst);
107
- if (const SVFFunction* svForkfun = SVFUtil::dyn_cast<SVFFunction>(forkVal))
108
- {
109
- addSpawnsite(inst);
110
- spawners.insert(fun);
111
- spawnees.insert(svForkfun);
112
- }
113
- /// TODO: handle indirect call here for the fork Fun
114
- else
115
- {
116
- writeWrnMsg("pthread create");
117
- outs() << inst->toString() << "\n";
118
- writeWrnMsg("invoke spawnee indirectly");
119
- }
120
- }
121
- }
122
- }
123
- }
124
- }
125
-
126
- /*!
127
- * Infer spawners and spawnees from call graph. The inference are recursively done
128
- * spawners: procedures may create a thread and return with the created thread still running
129
- * spawnees: procedures may be executed as a spawned thread
130
- * followers: procedures may be invoked by a thread after the thread returns from a spawner
131
- * (procedure may be called after pthread_creat is called).
132
- */
133
- void PCG::inferFromCallGraph()
134
- {
135
-
136
- collectSpawners();
137
-
138
- collectSpawnees();
139
-
140
- collectFollowers();
141
- }
142
-
143
- /*!
144
- * spawner: given a spawner, all its callers on callgraph are spawners
145
- */
146
- void PCG::collectSpawners()
147
- {
148
-
149
- /// find all the spawners recursively on call graph
150
- FunWorkList worklist;
151
- for (FunSet::iterator it = spawners.begin(), eit = spawners.end(); it != eit; ++it)
152
- {
153
- worklist.push(*it);
154
- }
155
- while (!worklist.empty())
156
- {
157
- const SVFFunction* svffun = worklist.pop();
158
- CallGraphNode* funNode = callgraph->getCallGraphNode(svffun);
159
- for (CallGraphNode::const_iterator it = funNode->InEdgeBegin(), eit = funNode->InEdgeEnd(); it != eit;
160
- ++it)
161
- {
162
- CallGraphEdge* callEdge = (*it);
163
- const SVFFunction* caller = callEdge->getSrcNode()->getFunction();
164
- if (isSpawnerFun(caller) == false)
165
- {
166
- worklist.push(caller);
167
- addSpawnerFun(caller);
168
- }
169
- /// add all the callsites from callers to callee (spawner) as a spawn site.
170
- for (CallGraphEdge::CallInstSet::const_iterator dit = callEdge->directCallsBegin(), deit =
171
- callEdge->directCallsEnd(); dit != deit; ++dit)
172
- {
173
- addSpawnsite((*dit)->getCallSite());
174
- }
175
- for (CallGraphEdge::CallInstSet::const_iterator dit = callEdge->indirectCallsBegin(), deit =
176
- callEdge->indirectCallsEnd(); dit != deit; ++dit)
177
- {
178
- addSpawnsite((*dit)->getCallSite());
179
- }
180
- }
181
- }
182
- }
183
-
184
- /*!
185
- * spawnee: given a spawnee, all its callees on callgraph are spawnees
186
- */
187
- void PCG::collectSpawnees()
188
- {
189
-
190
- /// find all the spawnees recursively on call graph
191
- FunWorkList worklist;
192
- for (FunSet::iterator it = spawnees.begin(), eit = spawnees.end(); it != eit; ++it)
193
- {
194
- worklist.push(*it);
195
- }
196
- while (!worklist.empty())
197
- {
198
- const SVFFunction* svffun = worklist.pop();
199
- CallGraphNode* funNode = callgraph->getCallGraphNode(svffun);
200
- for (CallGraphNode::const_iterator it = funNode->OutEdgeBegin(), eit = funNode->OutEdgeEnd(); it != eit;
201
- ++it)
202
- {
203
- const SVFFunction* caller = (*it)->getDstNode()->getFunction();
204
- if (isSpawneeFun(caller) == false)
205
- {
206
- worklist.push(caller);
207
- addSpawneeFun(caller);
208
- }
209
- }
210
- }
211
- }
212
-
213
- /*!
214
- * Identify initial followers
215
- * a procedure whose callsite lies in a control flow path that starts just after a spawner's callsite
216
- */
217
- void PCG::identifyFollowers()
218
- {
219
-
220
- for (CallInstSet::const_iterator sit = spawnSitesBegin(), esit = spawnSitesEnd(); sit != esit; ++sit)
221
- {
222
- const SVFInstruction* inst = *sit;
223
- BBWorkList bb_worklist;
224
- Set<const SVFBasicBlock*> visitedBBs;
225
- bb_worklist.push(inst->getParent());
226
- while (!bb_worklist.empty())
227
- {
228
- const SVFBasicBlock* bb = bb_worklist.pop();
229
- for (SVFBasicBlock::const_iterator it = bb->begin(), eit = bb->end(); it != eit; ++it)
230
- {
231
- const SVFInstruction* inst = *it;
232
- // mark the callee of this callsite as follower
233
- // if this is an call/invoke instruction but not a spawn site
234
- if ((SVFUtil::isCallSite(inst)) && !isSpawnsite(inst) && !SVFUtil::isIntrinsicInst(inst))
235
- {
236
- CallICFGNode* cbn = getCallICFGNode(inst);
237
- if (callgraph->hasCallGraphEdge(cbn))
238
- {
239
- for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = callgraph->getCallEdgeBegin(cbn),
240
- ecgIt = callgraph->getCallEdgeEnd(cbn); cgIt != ecgIt; ++cgIt)
241
- {
242
- const CallGraphEdge* edge = *cgIt;
243
- addFollowerFun(edge->getDstNode()->getFunction());
244
- }
245
- }
246
- }
247
- }
248
- for (const SVFBasicBlock* svf_scc_bb : bb->getSuccessors())
249
- {
250
- if (visitedBBs.count(svf_scc_bb) == 0)
251
- {
252
- visitedBBs.insert(svf_scc_bb);
253
- bb_worklist.push(svf_scc_bb);
254
- }
255
- }
256
- }
257
- }
258
-
259
- }
260
-
261
- /*!
262
- * collect follower procedures which may be called after pthread_create is invoked directly or indirectly
263
- * a procedure which is called from a follower is also a follower.
264
- */
265
- void PCG::collectFollowers()
266
- {
267
-
268
- /// identify initial followers
269
- identifyFollowers();
270
-
271
- /// find all the followers recursively on call graph
272
- FunWorkList worklist;
273
- for (FunSet::iterator it = followers.begin(), eit = followers.end(); it != eit; ++it)
274
- {
275
- worklist.push(*it);
276
- }
277
- while (!worklist.empty())
278
- {
279
- const SVFFunction* svffun = worklist.pop();
280
- CallGraphNode* funNode = callgraph->getCallGraphNode(svffun);
281
- for (CallGraphNode::const_iterator it = funNode->OutEdgeBegin(), eit = funNode->OutEdgeEnd(); it != eit;
282
- ++it)
283
- {
284
- const SVFFunction* caller = (*it)->getDstNode()->getFunction();
285
- if (isFollowerFun(caller) == false)
286
- {
287
- worklist.push(caller);
288
- addFollowerFun(caller);
289
- }
290
- }
291
- }
292
- }
293
-
294
- /*!
295
- * Thread interference analysis,
296
- * Suppose we have a undirected graph G = {F,E,I}
297
- * F denotes procedure,
298
- * E represents interference edge (x,y) \in E, x \in F, y \in F
299
- * means execution of x in one thread may overlap execution of y in another thread
300
- * I(x,y) is a set of memory locations for this interference edge
301
- */
302
- void PCG::interferenceAnalysis()
303
- {
304
-
305
- // DBOUT(DMTA, outs() << pasMsg("Starting Race Detection\n"));
306
-
307
- PCG::FunVec worklist;
308
- for (SVFModule::const_iterator F = mod->begin(), E = mod->end(); F != E; ++F)
309
- {
310
- const SVFFunction* fun = *F;
311
- if (isExtCall(fun))
312
- continue;
313
- worklist.push_back(fun);
314
- }
315
-
316
- while (!worklist.empty())
317
- {
318
- const SVFFunction* fun1 = worklist.back();
319
- worklist.pop_back();
320
-
321
- bool ismhpfun = false;
322
- for (PCG::FunVec::iterator it = worklist.begin(), eit = worklist.end(); it != eit; ++it)
323
- {
324
- const SVFFunction* fun2 = *it;
325
- if (mayHappenInParallelBetweenFunctions(fun1, fun2))
326
- {
327
- ismhpfun = true;
328
- mhpfuns.insert(fun2);
329
- }
330
- }
331
- if (ismhpfun)
332
- {
333
- mhpfuns.insert(fun1);
334
- }
335
- }
336
- }
337
-
338
- /*!
339
- * Print analysis results
340
- */
341
- void PCG::printResults()
342
- {
343
-
344
- printTDFuns();
345
- }
346
-
347
- /*!
348
- * Print Thread sensitive properties for each function
349
- */
350
- void PCG::printTDFuns()
351
- {
352
-
353
- for (SVFModule::const_iterator fi = mod->begin(), efi = mod->end(); fi != efi; ++fi)
354
- {
355
- const SVFFunction* fun = (*fi);
356
- if (fun->isDeclaration())
357
- continue;
358
-
359
- std::string isSpawner = isSpawnerFun(fun) ? " SPAWNER " : "";
360
- std::string isSpawnee = isSpawneeFun(fun) ? " CHILDREN " : "";
361
- std::string isFollower = isFollowerFun(fun) ? " FOLLOWER " : "";
362
- outs() << fun->getName() << " [" << isSpawner << isSpawnee << isFollower << "]\n";
363
- }
364
- }
@@ -1,251 +0,0 @@
1
- /*
2
- * LOCKResultValidator.cpp
3
- *
4
- * Created on: 24/07/2021
5
- */
6
-
7
- #include "Util/Options.h"
8
- #include <string>
9
- #include <sstream>
10
- #include "LockResultValidator.h"
11
- #include "MTAResultValidator.h"
12
- #include "SVF-LLVM/LLVMModule.h"
13
-
14
- using namespace SVF;
15
- using namespace SVFUtil;
16
-
17
- namespace SVF
18
- {
19
-
20
- // Subclassing RCResultValidator to define the abstract methods.
21
- class RaceValidator : public RaceResultValidator
22
- {
23
- public:
24
- RaceValidator(LockAnalysis* lockAnalysis) :lsa(lockAnalysis)
25
- {
26
- }
27
- bool protectedByCommonLocks(const Instruction* I1, const Instruction* I2)
28
- {
29
- const SVFInstruction* inst1 = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I1);
30
- const SVFInstruction* inst2 = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I2);
31
- return lsa->isProtectedByCommonLock(inst1, inst2);
32
- }
33
- private:
34
- LockAnalysis *lsa;
35
- };
36
-
37
- } // End namespace SVF
38
-
39
- Set<std::string> LockResultValidator::getStringArg(const Instruction* inst, unsigned int arg_num)
40
- {
41
- assert(LLVMUtil::isCallSite(inst) && "getFirstIntArg: inst is not a callsite");
42
- const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
43
- assert((arg_num < cs->arg_size()) && "Does not has this argument");
44
- const GetElementPtrInst* gepinst = SVFUtil::dyn_cast<GetElementPtrInst>(cs->getArgOperand(arg_num));
45
- const Constant* arrayinst = SVFUtil::dyn_cast<Constant>(gepinst->getOperand(0));
46
- const ConstantDataArray* cxtarray = SVFUtil::dyn_cast<ConstantDataArray>(arrayinst->getOperand(0));
47
- if (!cxtarray)
48
- {
49
- Set<std::string> strvec;
50
- return strvec;
51
- }
52
- const std::string vthdcxtstring = cxtarray->getAsCString().str();
53
- return split(vthdcxtstring, ',');
54
- }
55
-
56
- Set<std::string> &LockResultValidator::split(const std::string &s, char delim, Set<std::string> &elems)
57
- {
58
- std::stringstream ss(s);
59
- std::string item;
60
- while (std::getline(ss, item, delim))
61
- {
62
- elems.insert(item);
63
- }
64
- return elems;
65
- }
66
-
67
- Set<std::string> LockResultValidator::split(const std::string &s, char delim)
68
- {
69
- Set<std::string> elems;
70
- split(s, delim, elems);
71
- return elems;
72
- }
73
-
74
- inline std::string LockResultValidator::getOutput(const char *scenario, LOCK_FLAG analysisRes)
75
- {
76
- std::string ret(scenario);
77
- ret += "\t";
78
- switch (analysisRes)
79
- {
80
- case LOCK_TRUE:
81
- ret += SVFUtil::sucMsg("SUCCESS");
82
- break;
83
- case LOCK_UNSOUND:
84
- ret += SVFUtil::bugMsg2("UNSOUND");
85
- break;
86
- case LOCK_IMPRECISE:
87
- ret += SVFUtil::bugMsg1("IMPRECISE");
88
- break;
89
- default:
90
- ret += SVFUtil::errMsg("FAILURE");
91
- }
92
- return ret;
93
- }
94
-
95
- bool LockResultValidator::collectLockTargets()
96
- {
97
- const Function* F = nullptr;
98
- for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
99
- {
100
- for(auto it = M.begin(); it != M.end(); it++)
101
- {
102
- const std::string fName = (*it).getName().str();
103
- if(fName.find(LOCK) != std::string::npos)
104
- {
105
- F = &(*it);
106
- break;
107
- }
108
- }
109
- }
110
- if (!F)
111
- return false;
112
- for(Value::const_use_iterator it = F->use_begin(), ie = F->use_end(); it!=ie; it++)
113
- {
114
- const Use *u = &*it;
115
- const Value* user = u->getUser();
116
- const Instruction* inst = SVFUtil::dyn_cast<Instruction>(user);
117
- CxtLockSetStr y = getStringArg(inst, 0);
118
- const Instruction* memInst = getPreviousMemoryAccessInst(inst);
119
- const SVFInstruction* svfMemInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(memInst);
120
-
121
- instToCxtLockSet[svfMemInst] = y;
122
- if(const StoreInst* store = SVFUtil::dyn_cast<StoreInst> (memInst))
123
- {
124
- if(const BinaryOperator* bop = SVFUtil::dyn_cast<BinaryOperator> (store->getValueOperand()))
125
- {
126
- const Value* v = bop->getOperand(0);
127
- const Instruction* prevInst = SVFUtil::dyn_cast<LoadInst> (v);
128
- const SVFInstruction* svfPrevInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(prevInst);
129
- instToCxtLockSet[svfPrevInst] = y;
130
- }
131
- }
132
- }
133
- return true;
134
- }
135
-
136
- LockResultValidator::LOCK_FLAG LockResultValidator::validateStmtInLock()
137
- {
138
- SVFIR* pag = SVFIR::getPAG();
139
- LockResultValidator::LOCK_FLAG res = LockResultValidator::LOCK_TRUE;
140
- LockAnalysis::CxtStmtToCxtLockSet analyedLS = _la->getCSTCLS();
141
- for(LockAnalysis::CxtStmtToCxtLockSet::iterator it = analyedLS.begin(),
142
- eit = analyedLS.end(); it!=eit; it++)
143
- {
144
- const SVFInstruction* inst = ((*it).first).getStmt();
145
- bool interestedInst = true;
146
- for(const SVFStmt* stmt : pag->getSVFStmtList(pag->getICFG()->getICFGNode(inst)))
147
- {
148
- if(!SVFUtil::isa<LoadStmt>(stmt) && !SVFUtil::isa<StoreStmt>(stmt))
149
- interestedInst = false;
150
- }
151
- if(interestedInst==false)
152
- continue;
153
- const SVFFunction* F = inst->getFunction();
154
- if(inFilter(F->getName()))
155
- continue;
156
- CxtLockSetStr LS = instToCxtLockSet[inst];
157
- if(LS.size() != (*it).second.size())
158
- {
159
- if (Options::PrintValidRes())
160
- {
161
- outs() << errMsg("\nValidate Stmt's Lock : Wrong at: ") << inst->toString() << "\n";
162
- outs() << "Reason: The number of lock on current stmt is wrong\n";
163
- outs() << "\n----Given locks:\n";
164
- for (CxtLockSetStr::iterator it1 = LS.begin(),eit1 = LS.end(); it1 != eit1; it++)
165
- {
166
- outs() << "Lock " << *it1 << " ";
167
- }
168
- outs() << "\n----Analysis locks:\n";
169
- for (LockAnalysis::CxtLockSet::iterator it2 = (*it).second.begin(),
170
- eit2 = (*it).second.end(); it2 != eit2; ++it)
171
- {
172
- const SVFInstruction* call = (*it2).getStmt();
173
- outs()<<"Lock " << call->toString() << " ";
174
- }
175
- outs() << "\n";
176
- }
177
- res = LockResultValidator::LOCK_UNSOUND;
178
- }
179
- LockAnalysis::CxtLockSet LSA = (*it).second;
180
-
181
- for(LockAnalysis::CxtLockSet::iterator it3 = LSA.begin(), eit3=LSA.end(); it3!=eit3; it3++)
182
- {
183
- const SVFInstruction* call = (*it3).getStmt();
184
- if(SVFUtil::isCallSite(call) == false)
185
- continue;
186
- std::string lockName = SVFUtil::getSVFCallSite(call).getArgOperand(0)->getName();
187
- if(!match(lockName, LS))
188
- {
189
- if(Options::PrintValidRes())
190
- {
191
- outs() << "\nValidate Stmt's Lock : Wrong at (" << inst->toString() << ")\n";
192
- outs() << "Reason: The number of lock on current stmt is wrong\n";
193
- outs() << "\n Lock " << lockName << " should not protect current instruction\n";
194
- res = LockResultValidator::LOCK_IMPRECISE;
195
- }
196
- }
197
- }
198
- }
199
- return res;
200
- }
201
-
202
- void LockResultValidator::analyze()
203
- {
204
- outs() << SVFUtil::pasMsg(" --- Lock Analysis Result Validation ---\n");
205
- if(!collectLockTargets())
206
- return;
207
- std::string errstring;
208
- errstring = getOutput("Validate Lock Analysis :", validateStmtInLock());
209
- outs() << "======" << errstring << "======\n";
210
-
211
- RaceValidator validator(_la);
212
- validator.init(_la->getTCT()->getSVFModule());
213
- validator.analyze();
214
- }
215
-
216
- const Instruction* LockResultValidator::getPreviousMemoryAccessInst( const Instruction* I)
217
- {
218
- I = I->getPrevNode();
219
- while (I)
220
- {
221
- if (SVFUtil::isa<LoadInst>(I) || SVFUtil::isa<StoreInst>(I))
222
- return I;
223
- SVFFunction* callee = nullptr;
224
-
225
- if(LLVMUtil::isCallSite(I))
226
- {
227
- CallGraph::FunctionSet callees;
228
- const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I);
229
- _la->getTCT()->getThreadCallGraph()->getCallees(getCBN(svfInst), callees);
230
-
231
- for(CallGraph::FunctionSet::const_iterator cit = callees.begin(),
232
- ecit = callees.end(); cit!=ecit; cit++)
233
- {
234
- if(*cit != nullptr)
235
- {
236
- callee = const_cast<SVFFunction*> (*cit);
237
- break;
238
- }
239
-
240
- }
241
- }
242
-
243
- if (callee)
244
- {
245
- if (callee->getName().find("llvm.memset") != std::string::npos)
246
- return I;
247
- }
248
- I = I->getPrevNode();
249
- }
250
- return nullptr;
251
- }
@@ -1,84 +0,0 @@
1
- /*
2
- * LOCKResultValidator.h
3
- *
4
- * Created on: 24/07/2021
5
- */
6
-
7
-
8
-
9
- #ifndef LOCKRESULTVALIDATOR_H_
10
- #define LOCKRESULTVALIDATOR_H_
11
-
12
- #include "MTA/LockAnalysis.h"
13
- #include "SVF-LLVM/LLVMUtil.h"
14
-
15
- /* Validate the result of lock analysis */
16
-
17
- namespace SVF
18
- {
19
- class LockResultValidator
20
- {
21
- public:
22
- typedef Set<std::string> CxtLockSetStr;
23
- typedef Map<const SVFInstruction*, CxtLockSetStr> CxtStmtToCxtLockS;
24
-
25
- typedef unsigned LOCK_FLAG;
26
-
27
- LockResultValidator(LockAnalysis* la) : _la(la)
28
- {
29
- _mod = _la->getTCT()->getSVFModule();
30
- }
31
-
32
- ~LockResultValidator() {}
33
-
34
- void analyze();
35
-
36
- inline SVFModule* getModule() const
37
- {
38
- return _mod;
39
- }
40
- private:
41
- // Get CallICFGNode
42
- inline CallICFGNode* getCBN(const SVFInstruction* inst)
43
- {
44
- return _la->getTCT()->getCallICFGNode(inst);
45
- }
46
- const Instruction* getPreviousMemoryAccessInst( const Instruction* I);
47
-
48
- inline bool inFilter(const std::string& name)
49
- {
50
- return filterFun.find(name) != filterFun.end();
51
- }
52
-
53
- inline bool match(const std::string& lockName, CxtLockSetStr LS)
54
- {
55
- return LS.find(lockName) != LS.end();
56
- }
57
-
58
- Set<std::string> &split(const std::string &s, char delim, Set<std::string> &elems);
59
- Set<std::string> split(const std::string &s, char delim);
60
-
61
- std::string getOutput(const char* scenario, LOCK_FLAG analysisRes);
62
-
63
- Set<std::string> getStringArg(const Instruction* inst, unsigned int arg_num);
64
-
65
- bool collectLockTargets();
66
- LOCK_FLAG validateStmtInLock();
67
-
68
- CxtStmtToCxtLockS instToCxtLockSet;
69
- LockAnalysis::CxtStmtToCxtLockSet cxtStmtToCxtLockSet;
70
- LockAnalysis::CxtLockSet cxtLockSet;
71
-
72
- LockAnalysis* _la;
73
- SVFModule* _mod;
74
-
75
- static const LOCK_FLAG LOCK_TRUE = 0x01;
76
- static const LOCK_FLAG LOCK_IMPRECISE = 0x02;
77
- static const LOCK_FLAG LOCK_UNSOUND = 0x04;
78
-
79
- static constexpr char const *LOCK = "LOCK";
80
-
81
- Set<std::string> filterFun = {"LOCK", "INTERLEV_ACCESS", "PAUSE", "CXT_THREAD", "TCT_ACCESS"};
82
- };
83
- } // End namespace SVF
84
- #endif /* LOCKRESULTVALIDATOR_H_ */