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,716 +0,0 @@
1
- /*
2
- * MTAResultValidator.cpp
3
- *
4
- * Created on: 29/06/2015
5
- * Author: Peng Di
6
- */
7
-
8
- #include "Util/Options.h"
9
- #include <string>
10
- #include <sstream>
11
-
12
- #include "MTAResultValidator.h"
13
- #include "SVF-LLVM/LLVMModule.h"
14
-
15
- using namespace SVF;
16
- using namespace SVFUtil;
17
-
18
- namespace SVF
19
- {
20
-
21
- // Subclassing RCResultValidator to define the abstract methods.
22
- class MHPValidator : public RaceResultValidator
23
- {
24
- public:
25
- MHPValidator(MHP *mhp) :mhp(mhp)
26
- {
27
- }
28
- bool mayHappenInParallel(const Instruction* I1, const Instruction* I2)
29
- {
30
- const SVFInstruction* inst1 = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I1);
31
- const SVFInstruction* inst2 = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I2);
32
- return mhp->mayHappenInParallel(inst1, inst2);
33
- }
34
- private:
35
- MHP *mhp;
36
- };
37
-
38
- } // End namespace SVF
39
-
40
- void MTAResultValidator::analyze()
41
- {
42
-
43
- // Initialize the validator and perform validation.
44
- MHPValidator validator(mhp);
45
- validator.init(mhp->getTCT()->getSVFModule());
46
- validator.analyze();
47
-
48
-
49
- std::string errstring;
50
- if (!collectCallsiteTargets())
51
- return;
52
- if (!collectCxtThreadTargets())
53
- return;
54
-
55
- errstring = getOutput("Validate CxtThread:", validateCxtThread());
56
- outs() << "======" << errstring << "======\n";
57
-
58
- if (!collectTCTTargets())
59
- return;
60
- errstring = getOutput("Validate TCT: ", validateTCT());
61
- outs() << "======" << errstring << "======\n";
62
-
63
- if (!collectInterleavingTargets())
64
- return;
65
- errstring = getOutputforInterlevAnalysis("Validate Interleaving:", validateInterleaving());
66
- outs() << "======" << errstring << "======\n";
67
- }
68
-
69
- std::vector<std::string> &MTAResultValidator::split(const std::string &s, char delim, std::vector<std::string> &elems)
70
- {
71
- std::stringstream ss(s);
72
- std::string item;
73
- while (std::getline(ss, item, delim))
74
- {
75
- elems.push_back(item);
76
- }
77
- return elems;
78
- }
79
-
80
- std::vector<std::string> MTAResultValidator::split(const std::string &s, char delim)
81
- {
82
- std::vector<std::string> elems;
83
- split(s, delim, elems);
84
- return elems;
85
- }
86
- NodeID MTAResultValidator::getIntArg(const Instruction* inst, u32_t arg_num)
87
- {
88
- assert(LLVMUtil::isCallSite(inst) && "getFirstIntArg: inst is not a callinst");
89
- const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
90
- const ConstantInt* x = SVFUtil::dyn_cast<ConstantInt>(cs->getArgOperand(arg_num));
91
- assert((arg_num < cs->arg_size()) && "Does not has this argument");
92
- return (NodeID) x->getSExtValue();
93
- }
94
-
95
- std::vector<std::string> MTAResultValidator::getStringArg(const Instruction* inst, unsigned int arg_num)
96
- {
97
- assert(LLVMUtil::isCallSite(inst) && "getFirstIntArg: inst is not a callinst");
98
- const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
99
- assert((arg_num < cs->arg_size()) && "Does not has this argument");
100
- const Constant* arrayinst = SVFUtil::dyn_cast<Constant>(cs->getArgOperand(arg_num));
101
- if(const GetElementPtrInst* gepinst = SVFUtil::dyn_cast<GetElementPtrInst>(cs->getArgOperand(arg_num)))
102
- {
103
- arrayinst = SVFUtil::dyn_cast<Constant>(gepinst->getOperand(0));
104
- }
105
- const ConstantDataArray* cxtarray = SVFUtil::dyn_cast<ConstantDataArray>(arrayinst->getOperand(0));
106
- if (!cxtarray)
107
- {
108
- std::vector<std::string> strvec;
109
- return strvec;
110
- }
111
- const std::string vthdcxtstring = cxtarray->getAsCString().str();
112
- return split(vthdcxtstring, ',');
113
- }
114
-
115
- CallStrCxt MTAResultValidator::getCxtArg(const Instruction* inst, unsigned int arg_num)
116
- {
117
- std::vector<std::string> x = getStringArg(inst, arg_num);
118
- CallStrCxt cxt;
119
- if (0 == x.size())
120
- return cxt;
121
- // Deal with the second argument that records all callsites
122
- for (std::vector<std::string>::iterator i = x.begin(); i != x.end(); i++)
123
- {
124
- std::vector<std::string> y = split((*i), '.');
125
- y[0].erase(y[0].find("cs"), 2);
126
-
127
- const SVFFunction* callee = mod->getSVFFunction(y[1]);
128
- const SVFInstruction* svfInst = csnumToInstMap[atoi(y[0].c_str())];
129
- assert(callee && "callee error");
130
- CallICFGNode* cbn = mhp->getTCT()->getCallICFGNode(svfInst);
131
- CallSiteID csId = tcg->getCallSiteID(cbn, callee);
132
- cxt.push_back(csId);
133
- }
134
- return cxt;
135
- }
136
-
137
- const Instruction* MTAResultValidator::getPreviousMemoryAccessInst(const Instruction* I)
138
- {
139
- I = I->getPrevNode();
140
- while (I)
141
- {
142
- if (SVFUtil::isa<LoadInst>(I) || SVFUtil::isa<StoreInst>(I))
143
- return I;
144
- I = I->getPrevNode();
145
- }
146
- return nullptr;
147
- }
148
-
149
- inline std::string MTAResultValidator::getOutput(const char *scenario, bool analysisRes)
150
- {
151
- std::string ret(scenario);
152
- ret += "\t";
153
-
154
- if (analysisRes)
155
- ret += SVFUtil::sucMsg("SUCCESS");
156
- else
157
- ret += SVFUtil::errMsg("FAILURE");
158
- return ret;
159
- }
160
-
161
- inline std::string MTAResultValidator::getOutputforInterlevAnalysis(const char *scenario, INTERLEV_FLAG analysisRes)
162
- {
163
- std::string ret(scenario);
164
- ret += "\t";
165
- switch (analysisRes)
166
- {
167
- case INTERLEV_TRUE:
168
- ret += SVFUtil::sucMsg("SUCCESS");
169
- break;
170
- case INTERLEV_UNSOUND:
171
- ret += SVFUtil::bugMsg2("UNSOUND");
172
- break;
173
- case INTERLEV_IMPRECISE:
174
- ret += SVFUtil::bugMsg1("IMPRECISE");
175
- break;
176
- default:
177
- ret += SVFUtil::errMsg("FAILURE");
178
- }
179
- return ret;
180
- }
181
-
182
- bool MTAResultValidator::matchCxt(const CallStrCxt cxt1, const CallStrCxt cxt2) const
183
- {
184
- if (cxt1.size() != cxt2.size())
185
- return false;
186
- return std::equal(cxt1.begin(), cxt1.end(), cxt2.begin());
187
- }
188
-
189
- void MTAResultValidator::dumpCxt(const CallStrCxt& cxt) const
190
- {
191
- std::string str;
192
- std::stringstream rawstr(str);
193
- rawstr << "[:";
194
- for (CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it != eit; ++it)
195
- {
196
- rawstr << " ' " << *it << " ' ";
197
- rawstr << tcg->getCallSite(*it)->getCallSite()->toString();
198
- rawstr << " call " << tcg->getCallSite(*it)->getCaller()->getName() << "-->" << tcg->getCalleeOfCallSite(*it)->getName() << ", \n";
199
- }
200
- rawstr << " ]";
201
- outs() << "max cxt = " << cxt.size() << rawstr.str() << "\n";
202
- }
203
-
204
- void MTAResultValidator::dumpInterlev(NodeBS& lev)
205
- {
206
- outs() << " [ ";
207
- for (NodeBS::iterator it = lev.begin(), eit = lev.end(); it != eit; it++)
208
- {
209
- NodeID id = *it;
210
- outs() << rthdTovthd[id] << ", ";
211
- }
212
- outs() << "]\n";
213
- }
214
-
215
- bool MTAResultValidator::collectCallsiteTargets()
216
- {
217
- for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
218
- {
219
- for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
220
- {
221
- for (Function::const_iterator bi = (*F).begin(), ebi = (*F).end(); bi != ebi; ++bi)
222
- {
223
- const BasicBlock* bb = &*bi;
224
- if (!bb->getName().str().compare(0, 2, "cs"))
225
- {
226
- NodeID csnum = atoi(bb->getName().str().substr(2).c_str());
227
- const Instruction* inst = &bb->front();
228
- while (1)
229
- {
230
- if (SVFUtil::isa<CallInst>(inst))
231
- {
232
- break;
233
- }
234
- inst = inst->getNextNode();
235
- assert(inst && "Wrong cs label, cannot find callsite");
236
- }
237
- const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(inst);
238
- csnumToInstMap[csnum] = svfInst;
239
- }
240
- }
241
- }
242
- }
243
- return !csnumToInstMap.empty();
244
- }
245
-
246
- bool MTAResultValidator::collectCxtThreadTargets()
247
- {
248
- const Function* F = nullptr;
249
- for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
250
- {
251
- for(auto it = M.begin(); it != M.end(); it++)
252
- {
253
- const std::string fName = (*it).getName().str();
254
- if(fName.find(CXT_THREAD) != std::string::npos)
255
- {
256
- F = &(*it);
257
- break;
258
- }
259
- }
260
- }
261
- if (!F)
262
- return false;
263
-
264
- // Push main thread into vthdToCxt;
265
- CallStrCxt main_cxt;
266
- vthdToCxt[0] = main_cxt;
267
-
268
- // Collect call sites of all CXT_THREAD function calls.
269
-
270
- for (Value::const_use_iterator it = F->use_begin(), ie = F->use_end(); it != ie; ++it)
271
- {
272
- const Use *u = &*it;
273
- const Value* user = u->getUser();
274
- const Instruction* inst = SVFUtil::dyn_cast<Instruction>(user);
275
-
276
- NodeID vthdnum = getIntArg(inst, 0);
277
- CallStrCxt cxt = getCxtArg(inst, 1);
278
-
279
- vthdToCxt[vthdnum] = cxt;
280
- }
281
- return true;
282
- }
283
-
284
- bool MTAResultValidator::collectTCTTargets()
285
- {
286
-
287
- // Collect call sites of all TCT_ACCESS function calls.
288
- const Function* F = nullptr;
289
- for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
290
- {
291
- for(auto it = M.begin(); it != M.end(); it++)
292
- {
293
- const std::string fName = (*it).getName().str();
294
- if(fName.find(TCT_ACCESS) != std::string::npos)
295
- {
296
- F = &(*it);
297
- break;
298
- }
299
- }
300
- }
301
- if (!F)
302
- return false;
303
-
304
- for (Value::const_use_iterator it = F->use_begin(), ie = F->use_end(); it != ie; ++it)
305
- {
306
- const Use *u = &*it;
307
- const Value* user = u->getUser();
308
- const Instruction* inst = SVFUtil::dyn_cast<Instruction>(user);
309
-
310
- NodeID vthdnum = getIntArg(inst, 0);
311
- NodeID rthdnum = vthdTorthd[vthdnum];
312
- std::vector<std::string> x = getStringArg(inst, 1);
313
-
314
- for (std::vector<std::string>::iterator i = x.begin(); i != x.end(); i++)
315
- {
316
- rthdToChildren[rthdnum].insert(vthdTorthd[atoi((*i).c_str())]);
317
- }
318
- }
319
- return true;
320
- }
321
-
322
- bool MTAResultValidator::collectInterleavingTargets()
323
- {
324
-
325
- // Collect call sites of all INTERLEV_ACCESS function calls.
326
- const Function* F = nullptr;
327
- for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
328
- {
329
- for(auto it = M.begin(); it != M.end(); it++)
330
- {
331
- const std::string fName = (*it).getName().str();
332
- if(fName.find(INTERLEV_ACCESS) != std::string::npos)
333
- {
334
- F = &(*it);
335
- break;
336
- }
337
- }
338
- }
339
- if (!F)
340
- return false;
341
-
342
- for (Value::const_use_iterator it = F->use_begin(), ie = F->use_end(); it != ie; ++it)
343
- {
344
- const Use *u = &*it;
345
- const Value* user = u->getUser();
346
- const Instruction* inst = SVFUtil::dyn_cast<Instruction>(user);
347
-
348
- NodeID vthdnum = getIntArg(inst, 0);
349
- NodeID rthdnum = vthdTorthd[vthdnum];
350
- CallStrCxt x = getCxtArg(inst, 1);
351
- std::vector<std::string> y = getStringArg(inst, 2);
352
-
353
- // Record given interleaving
354
- NodeBS lev;
355
- // Push thread itself into interleaving set
356
- lev.set(rthdnum);
357
- // Find rthd of given vthd and push it into interleaving set
358
- for (std::vector<std::string>::iterator i = y.begin(); i != y.end(); i++)
359
- {
360
- lev.set(vthdTorthd[atoi((*i).c_str())]);
361
- }
362
-
363
- const Instruction* memInst = getPreviousMemoryAccessInst(inst);
364
- const SVFInstruction* svfMemInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(memInst);
365
- CxtThreadStmt cts(rthdnum, x, svfMemInst);
366
- instToTSMap[svfMemInst].insert(cts);
367
- threadStmtToInterLeaving[cts] = lev;
368
- }
369
- return true;
370
- }
371
-
372
- bool MTAResultValidator::validateCxtThread()
373
- {
374
-
375
- bool res = true;
376
- TCT* tct = mhp->getTCT();
377
- if (tct->getTCTNodeNum() != vthdToCxt.size())
378
- {
379
- res = false;
380
- if (Options::PrintValidRes())
381
- {
382
- outs() << errMsg("\nValidate CxtThread: The number of CxtThread is different from given result!!!\n");
383
- outs() << "Given threads:\t" << vthdToCxt.size() << "\nAnalysis result:\t" << tct->getTCTNodeNum() << "\n";
384
- assert(false && "test case failed!");
385
- }
386
- }
387
-
388
- Set<int> visitedvthd;
389
-
390
- for (NodeID i = 0; i < tct->getTCTNodeNum(); i++)
391
- {
392
- const CxtThread rthd = tct->getTCTNode(i)->getCxtThread();
393
- bool matched = false;
394
- for (Map<NodeID, CallStrCxt>::iterator j = vthdToCxt.begin(), ej = vthdToCxt.end(); j != ej; j++)
395
- {
396
- NodeID vthdid = (*j).first;
397
- if (matchCxt(rthd.getContext(), vthdToCxt[vthdid]))
398
- {
399
- if (visitedvthd.find(vthdid) != visitedvthd.end())
400
- {
401
- res = false;
402
- if (Options::PrintValidRes())
403
- {
404
- outs() << "\nValidate CxtThread: Repeat real CxtThread !!!\n";
405
- rthd.dump();
406
- tct->getTCTNode(vthdTorthd[vthdid])->getCxtThread().dump();
407
- }
408
- }
409
- vthdTorthd[vthdid] = i;
410
- rthdTovthd[i] = vthdid;
411
- visitedvthd.insert(vthdid);
412
- matched = true;
413
- break;
414
- }
415
- }
416
- if (!matched)
417
- {
418
- res = false;
419
- if (Options::PrintValidRes())
420
- {
421
- SVFUtil::errs() << errMsg("\nValidate CxtThread: Cannot match real CxtThread !!!\n");
422
- rthd.dump();
423
- assert(false && "test case failed!");
424
- }
425
- }
426
- }
427
- if (visitedvthd.size() != vthdToCxt.size())
428
- {
429
- res = false;
430
- if (Options::PrintValidRes())
431
- {
432
- SVFUtil::errs() << errMsg("\nValidate CxtThread: Some given CxtThreads cannot be found !!!\n");
433
- assert(false && "test case failed!");
434
- for (Map<NodeID, CallStrCxt>::iterator j = vthdToCxt.begin(), ej = vthdToCxt.end(); j != ej; j++)
435
- {
436
- NodeID vthdid = (*j).first;
437
- if (visitedvthd.find(vthdid) == visitedvthd.end())
438
- {
439
- dumpCxt(vthdToCxt[vthdid]);
440
- }
441
- }
442
- }
443
- }
444
- return res;
445
- }
446
-
447
- bool MTAResultValidator::validateTCT()
448
- {
449
- bool res = true;
450
-
451
- TCT* tct = mhp->getTCT();
452
- for (NodeID i = 0; i < tct->getTCTNodeNum(); i++)
453
- {
454
- bool res_node = true;
455
- TCTNode* pnode = tct->getTCTNode(i);
456
- for (TCT::ThreadCreateEdgeSet::const_iterator ci = tct->getChildrenBegin(pnode), cei = tct->getChildrenEnd(pnode); ci != cei;
457
- ci++)
458
- {
459
- NodeID tid = (*ci)->getDstID();
460
- if (rthdToChildren[i].find(tid) == rthdToChildren[i].end())
461
- {
462
- res = false;
463
- res_node = false;
464
- }
465
- }
466
-
467
- for (Set<NodeID>::iterator j = rthdToChildren[i].begin(), ej = rthdToChildren[i].end(); j != ej; j++)
468
- {
469
- NodeID gid = *j;
470
- if (!tct->hasGraphEdge(pnode, tct->getTCTNode(gid), TCTEdge::ThreadCreateEdge))
471
- {
472
- res = false;
473
- res_node = false;
474
- }
475
- }
476
- if ((!res_node) && Options::PrintValidRes())
477
- {
478
- outs() << errMsg("\nValidate TCT: Wrong at TID ") << rthdTovthd[i] << "\n";
479
- outs() << "Given children: \t";
480
- for (Set<NodeID>::iterator j = rthdToChildren[i].begin(), ej = rthdToChildren[i].end(); j != ej; j++)
481
- {
482
- NodeID gid = *j;
483
- outs() << rthdTovthd[gid] << ", ";
484
- }
485
- outs() << "\nAnalysis children:\t";
486
- for (TCT::ThreadCreateEdgeSet::const_iterator ci = tct->getChildrenBegin(pnode), cei = tct->getChildrenEnd(pnode); ci != cei;
487
- ci++)
488
- {
489
- NodeID tid = (*ci)->getDstID();
490
- outs() << rthdTovthd[tid] << ", ";
491
- }
492
- outs() << "\n";
493
- }
494
- }
495
- return res;
496
- }
497
-
498
- MTAResultValidator::INTERLEV_FLAG MTAResultValidator::validateInterleaving()
499
- {
500
- MTAResultValidator::INTERLEV_FLAG res = MTAResultValidator::INTERLEV_TRUE;
501
-
502
- for (MHP::InstToThreadStmtSetMap::iterator seti = instToTSMap.begin(), eseti = instToTSMap.end(); seti != eseti; ++seti)
503
- {
504
- const SVFInstruction* inst = (*seti).first;
505
-
506
- const MHP::CxtThreadStmtSet& tsSet = mhp->getThreadStmtSet(inst);
507
-
508
- if ((*seti).second.size() != tsSet.size())
509
- {
510
- if (Options::PrintValidRes())
511
- {
512
- outs() << errMsg("\n Validate Interleaving: Wrong at : ") << inst->getSourceLoc() << "\n";
513
- outs() << "Reason: The number of thread running on stmt is wrong\n";
514
- outs() << "\n----Given threads:\n";
515
- for (MHP::CxtThreadStmtSet::iterator thdlevi = (*seti).second.begin(), ethdlevi = (*seti).second.end(); thdlevi != ethdlevi;
516
- ++thdlevi)
517
- {
518
- outs() << "TID " << rthdTovthd[(*thdlevi).getTid()] << ": ";
519
- dumpCxt((*thdlevi).getContext());
520
- }
521
- outs() << "\n----Analysis threads:\n";
522
- for (MHP::CxtThreadStmtSet::const_iterator it = tsSet.begin(), eit = tsSet.end(); it != eit; ++it)
523
- {
524
- outs() << "TID " << rthdTovthd[(*it).getTid()] << ": ";
525
- dumpCxt((*it).getContext());
526
- }
527
- outs() << "\n";
528
- }
529
- res = MTAResultValidator::INTERLEV_UNSOUND;
530
- }
531
-
532
- for (MHP::CxtThreadStmtSet::const_iterator it = tsSet.begin(), eit = tsSet.end(); it != eit; ++it)
533
- {
534
- const CxtThreadStmt& ts = *it;
535
- bool matched = false;
536
- for (MHP::CxtThreadStmtSet::iterator it2 = (*seti).second.begin(), eit2 = (*seti).second.end(); it2 != eit2; ++it2)
537
- {
538
- const CxtThreadStmt& ts2 = *it2;
539
-
540
- if (ts2.getTid() == ts.getTid() && matchCxt(ts2.getContext(), ts.getContext()))
541
- {
542
- matched = true;
543
- NodeBS lev = mhp->getInterleavingThreads(ts);
544
- NodeBS lev2 = threadStmtToInterLeaving[ts2];
545
- if (lev != lev2)
546
- {
547
- if (Options::PrintValidRes())
548
- {
549
- outs() << errMsg("\nValidate Interleaving: Wrong at: ") << inst->getSourceLoc() << "\n";
550
- outs() << "Reason: thread interleaving on stmt is wrong\n";
551
- dumpCxt(ts.getContext());
552
- outs() << "Given result: \tTID " << rthdTovthd[ts.getTid()];
553
- dumpInterlev(lev2);
554
- outs() << "Analysis result: \tTID " << rthdTovthd[ts.getTid()];
555
- dumpInterlev(lev);
556
- }
557
-
558
- if (MTAResultValidator::INTERLEV_IMPRECISE > res)
559
- res = MTAResultValidator::INTERLEV_IMPRECISE;
560
-
561
- if (lev.count() >= lev2.count())
562
- {
563
- bool findeveryelement = true;
564
- for (NodeBS::iterator it = lev2.begin(), eit = lev2.end(); it != eit; it++)
565
- {
566
- if (!lev.test(*it))
567
- {
568
- findeveryelement = false;
569
- break;
570
- }
571
- }
572
- if (!findeveryelement)
573
- res = MTAResultValidator::INTERLEV_UNSOUND;
574
- }
575
- else
576
- res = MTAResultValidator::INTERLEV_UNSOUND;
577
- }
578
- }
579
- }
580
-
581
- if (!matched)
582
- {
583
- if (Options::PrintValidRes())
584
- {
585
- outs() << errMsg("\nValidate Interleaving: Wrong at:") << inst->getSourceLoc() << "\n";
586
- outs() << "Reason: analysis thread cxt is not matched by given thread cxt\n";
587
- dumpCxt(ts.getContext());
588
- NodeBS lev = mhp->getInterleavingThreads(ts);
589
-
590
- outs() << "Analysis result: \tTID " << rthdTovthd[ts.getTid()];
591
- dumpInterlev(lev);
592
- }
593
- res = MTAResultValidator::INTERLEV_UNSOUND;
594
- }
595
- }
596
- }
597
- return res;
598
- }
599
-
600
- void RaceResultValidator::collectValidationTargets()
601
- {
602
- // Collect call sites of all RC_ACCESS function calls.
603
- std::vector<const CallBase*> csInsts;
604
- const Function* F = nullptr;
605
- for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
606
- {
607
- for(auto it = M.begin(); it != M.end(); it++)
608
- {
609
- const std::string fName = (*it).getName().str();
610
- if(fName.find(RC_ACCESS) != std::string::npos)
611
- {
612
- F = &(*it);
613
- break;
614
- }
615
- }
616
- }
617
- if (!F) return;
618
-
619
- for (Value::const_use_iterator it = F->use_begin(), ie =
620
- F->use_end(); it != ie; ++it)
621
- {
622
- const Use *u = &*it;
623
- const Value *user = u->getUser();
624
- if(LLVMUtil::isCallSite(user))
625
- {
626
- const CallBase* csInst = LLVMUtil::getLLVMCallSite(user);
627
- csInsts.push_back(csInst);
628
- }
629
- }
630
- assert(csInsts.size() % 2 == 0 && "We should have RC_ACCESS called in pairs.");
631
-
632
- // Sort the validation sites according to their ids.
633
- std::sort(csInsts.begin(), csInsts.end(), compare);
634
-
635
- // Generate access pairs.
636
- for (int i = 0, e = csInsts.size(); i != e;)
637
- {
638
- const CallBase* CI1 = csInsts[i++];
639
- const CallBase* CI2 = csInsts[i++];
640
- const ConstantInt* C = SVFUtil::dyn_cast<ConstantInt>(CI1->getArgOperand(1));
641
- assert(C);
642
- const Instruction* I1 = getPreviousMemoryAccessInst(CI1);
643
- const Instruction* I2 = getPreviousMemoryAccessInst(CI2);
644
- assert(I1 && I2 && "RC_ACCESS should be placed immediately after the target memory access.");
645
- RC_FLAG flags = C->getZExtValue();
646
- accessPairs.push_back(AccessPair(I1, I2, flags));
647
- }
648
- }
649
-
650
- void RaceResultValidator::validateAll()
651
- {
652
- SVFUtil::outs() << SVFUtil::pasMsg(" --- Analysis Result Validation ---\n");
653
-
654
- // Iterate every memory access pair to perform the validation.
655
- for (int i = 0, e = accessPairs.size(); i != e; ++i)
656
- {
657
- const AccessPair &ap = accessPairs[i];
658
- const Instruction* I1 = ap.getInstruction1();
659
- const Instruction* I2 = ap.getInstruction2();
660
-
661
- bool mhp = mayHappenInParallel(I1, I2);
662
- bool alias = mayAccessAliases(I1, I2);
663
- bool protect = protectedByCommonLocks(I1, I2);
664
- bool racy = mayHaveDataRace(I1, I2);
665
-
666
- SVFUtil::outs() << "For the memory access pair at ("
667
- << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(I1)->getSourceLoc() << ", "
668
- << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(I2)->getSourceLoc() << ")\n";
669
- if (selectedValidationScenarios & RC_ALIASES)
670
- {
671
- SVFUtil::outs() << "\t"
672
- << getOutput("ALIASES", alias, ap.isFlaged(RC_ALIASES))
673
- << "\n";
674
- }
675
- if (selectedValidationScenarios & RC_MHP)
676
- {
677
- SVFUtil::outs() << "\t"
678
- << getOutput("MHP", mhp, ap.isFlaged(RC_MHP)) << "\n";
679
- }
680
- if (selectedValidationScenarios & RC_PROTECTED)
681
- {
682
- SVFUtil::outs() << "\t"
683
- << getOutput("PROTECT", protect,
684
- ap.isFlaged(RC_PROTECTED)) << "\n";
685
- }
686
- if (selectedValidationScenarios & RC_RACE)
687
- {
688
- SVFUtil::outs() << "\t"
689
- << getOutput("RACE", racy, ap.isFlaged(RC_RACE))
690
- << "\n";
691
- }
692
- }
693
-
694
- SVFUtil::outs() << "\n";
695
- }
696
-
697
- const Instruction* RaceResultValidator::getPreviousMemoryAccessInst(const Instruction* I)
698
- {
699
- I = I->getPrevNode();
700
- while (I)
701
- {
702
- if (SVFUtil::isa<LoadInst>(I) || SVFUtil::isa<StoreInst>(I))
703
- return I;
704
-
705
- const SVFInstruction* inst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I);
706
-
707
- if (const SVFFunction *callee = SVFUtil::getCallee(inst))
708
- {
709
- if (callee->getName().find("llvm.memset") != std::string::npos)
710
- return I;
711
-
712
- }
713
- I = I->getPrevNode();
714
- }
715
- return nullptr;
716
- }