Static Value-Flow Analysis
MTAResultValidator.h
Go to the documentation of this file.
1 /*
2  * MTAResultValidator.h
3  *
4  * Created on: 29/06/2015
5  * Author: Peng Di and Ding Ye
6  */
7 
8 #ifndef MTARESULTVALIDATOR_H_
9 #define MTARESULTVALIDATOR_H_
10 
11 #include "MTA/MHP.h"
12 
17 namespace SVF
18 {
19 typedef unsigned NodeID;
20 
21 class MTAResultValidator
22 {
23 
24 public:
25  typedef int INTERLEV_FLAG;
27  mhp(mh)
28  {
30  tdAPI = tcg->getThreadAPI();
31  mod = mhp->getTCT()->getSVFModule();
32  }
33  // Destructor
35  {
36  }
37 
38  // Analysis
39  void analyze();
40  inline SVFModule* getModule() const
41  {
42  return mod;
43  }
44 protected:
45 
46  /*
47  * Assistant functions
48  */
49 
50  // Split string
51  std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems);
52  std::vector<std::string> split(const std::string &s, char delim);
53 
54  // Get special arguments of given call sites
55  NodeID getIntArg(const Instruction* inst, unsigned int arg_num);
56  std::vector<std::string> getStringArg(const Instruction* inst, unsigned int arg_num);
57  CallStrCxt getCxtArg(const Instruction* inst, unsigned int arg_num);
58 
59  /*
60  * Get the previous LoadInst or StoreInst from Instruction "I" in the
61  * same BasicBlock. Return nullptr if none exists.
62  */
64 
65  // Compare two cxts
66  bool matchCxt(const CallStrCxt cxt1, const CallStrCxt cxt2) const;
67 
68  // Dump calling context information
69  void dumpCxt(const CallStrCxt& cxt) const;
70 
71  void dumpInterlev(NodeBS& lev);
72 
73  // Get the validation result string of a single validation scenario.
74  inline std::string getOutput(const char *scenario, bool analysisRes);
75  inline std::string getOutputforInterlevAnalysis(const char *scenario, INTERLEV_FLAG analysisRes);
76 
77  /*
78  * Collect the callsite targets for validations.
79  * The targets are labeled by "cs1:", "cs2:"... that are the names of its basic blocks.
80  * The collected targets are stored in csnumToInstMap that maps label "cs1" to its Callsite.
81  */
83 
84  /*
85  * Collect the CxtThread targets for validations.
86  * The collected targets are stored in vthdToCxt that maps vthd to cxt.
87  */
89 
90  /*
91  * Collect TCT targets for validations.
92  * The collected targets are stored in rthdToChildren.
93  */
95 
96  /*
97  * Collect the thread interleaving targets for validations.
98  * The collected targets are stored in instToTSMap and threadStmtToInterLeaving.
99  */
101 
102  /*
103  * Perform validation for Cxtthread.
104  * If correct, the validator maps given thread vthd to static CxtThread rthd stored in vthdTorthd.
105  */
107 
108  /*
109  * Perform validation for TCT.
110  */
111  bool validateTCT();
112 
113  /*
114  * Perform validation for thread interleaving.
115  */
117 
118 private:
119 
124 
126 
127  MHP::InstToThreadStmtSetMap instToTSMap; // Map a instruction to CxtThreadStmtSet
129 
130  static constexpr char const *CXT_THREAD = "CXT_THREAD";
131  static constexpr char const *INTERLEV_ACCESS = "INTERLEV_ACCESS";
132  static constexpr char const *TCT_ACCESS = "TCT_ACCESS";
133 
134  ThreadAPI* tdAPI;
136  MHP* mhp;
142  SVFModule* mod;
144 
145  static const INTERLEV_FLAG INTERLEV_TRUE = 0x01;
146  static const INTERLEV_FLAG INTERLEV_IMPRECISE = 0x02;
147  static const INTERLEV_FLAG INTERLEV_UNSOUND = 0x04;
149 };
150 
151 
152 
169 {
170 public:
171  typedef int RC_FLAG;
172 
176  class AccessPair
177  {
178  public:
181  const RC_FLAG flags) :
182  I1(I1), I2(I2), flags(flags)
183  {
184  }
185 
187 
188  inline bool isFlaged(const RC_FLAG flag) const
189  {
190  return flags & flag;
191  }
192  inline const Instruction* getInstruction1() const
193  {
194  return I1;
195  }
196  inline const Instruction* getInstruction2() const
197  {
198  return I2;
199  }
201 
202  private:
203  const Instruction* I1;
204  const Instruction* I2;
205  RC_FLAG flags;
206  };
207 
210  {
211  release();
212  }
213 
215  void init(SVFModule* M)
216  {
217  this->M = M;
220  }
221 
223  void analyze()
224  {
225  validateAll();
226  }
227 
229  void release()
230  {
231  }
232 
234  inline bool hasValidationTarget() const
235  {
236  return !accessPairs.empty();
237  }
238 
239 protected:
242 
243  virtual bool mayAccessAliases(const Instruction* I1,
244  const Instruction* I2)
245  {
247  return true;
248  }
249  virtual bool mayHappenInParallel(const Instruction* I1,
250  const Instruction* I2)
251  {
253  return true;
254  }
255  virtual bool protectedByCommonLocks(const Instruction* I1,
256  const Instruction* I2)
257  {
259  return true;
260  }
261  virtual bool mayHaveDataRace(const Instruction* I1,
262  const Instruction* I2)
263  {
265  return true;
266  }
268 
275  {
276  // Collect call sites of all RC_ACCESS function calls.
277  std::vector<const CallBase*> csInsts;
278  const Function* F = nullptr;
279  for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
280  {
281  for(auto it = M.begin(); it != M.end(); it++)
282  {
283  const std::string fName = (*it).getName().str();
284  if(fName.find(RC_ACCESS) != std::string::npos)
285  {
286  F = &(*it);
287  break;
288  }
289  }
290  }
291  if (!F) return;
292 
293  for (Value::const_use_iterator it = F->use_begin(), ie =
294  F->use_end(); it != ie; ++it)
295  {
296  const Use *u = &*it;
297  const Value *user = u->getUser();
298  if(LLVMUtil::isCallSite(user))
299  {
300  const CallBase* csInst = LLVMUtil::getLLVMCallSite(user);
301  csInsts.push_back(csInst);
302  }
303  }
304  assert(csInsts.size() % 2 == 0 && "We should have RC_ACCESS called in pairs.");
305 
306  // Sort the validation sites according to their ids.
307  std::sort(csInsts.begin(), csInsts.end(), compare);
308 
309  // Generate access pairs.
310  for (int i = 0, e = csInsts.size(); i != e;)
311  {
312  const CallBase* CI1 = csInsts[i++];
313  const CallBase* CI2 = csInsts[i++];
314  const ConstantInt* C = SVFUtil::dyn_cast<ConstantInt>(CI1->getArgOperand(1));
315  assert(C);
316  const Instruction* I1 = getPreviousMemoryAccessInst(CI1);
317  const Instruction* I2 = getPreviousMemoryAccessInst(CI2);
318  assert(I1 && I2 && "RC_ACCESS should be placed immediately after the target memory access.");
319  RC_FLAG flags = C->getZExtValue();
320  accessPairs.push_back(AccessPair(I1, I2, flags));
321  }
322  }
323 
325  void validateAll()
326  {
327  SVFUtil::outs() << SVFUtil::pasMsg(" --- Analysis Result Validation ---\n");
328 
329  // Iterate every memory access pair to perform the validation.
330  for (int i = 0, e = accessPairs.size(); i != e; ++i)
331  {
332  const AccessPair &ap = accessPairs[i];
333  const Instruction* I1 = ap.getInstruction1();
334  const Instruction* I2 = ap.getInstruction2();
335 
336  bool mhp = mayHappenInParallel(I1, I2);
337  bool alias = mayAccessAliases(I1, I2);
338  bool protect = protectedByCommonLocks(I1, I2);
339  bool racy = mayHaveDataRace(I1, I2);
340 
341  SVFUtil::outs() << "For the memory access pair at ("
345  {
346  SVFUtil::outs() << "\t"
347  << getOutput("ALIASES", alias, ap.isFlaged(RC_ALIASES))
348  << "\n";
349  }
351  {
352  SVFUtil::outs() << "\t"
353  << getOutput("MHP", mhp, ap.isFlaged(RC_MHP)) << "\n";
354  }
356  {
357  SVFUtil::outs() << "\t"
358  << getOutput("PROTECT", protect,
359  ap.isFlaged(RC_PROTECTED)) << "\n";
360  }
362  {
363  SVFUtil::outs() << "\t"
364  << getOutput("RACE", racy, ap.isFlaged(RC_RACE))
365  << "\n";
366  }
367  }
368 
369  SVFUtil::outs() << "\n";
370  }
371 
373  inline std::string getOutput(const char *scenario,
374  bool analysisRes, bool expectedRes)
375  {
376  std::string ret(scenario);
377  ret += "\t";
378  if (expectedRes)
379  ret += " T: ";
380  else
381  ret += " F: ";
382  if (analysisRes == expectedRes)
383  ret += SVFUtil::sucMsg("SUCCESS");
384  else
385  ret += SVFUtil::errMsg("FAILURE");
386  return ret;
387  }
388 
389 private:
390  SVFModule* M;
391  std::vector<AccessPair> accessPairs;
393 
398  static bool compare(const CallBase* CI1, const CallBase* CI2)
399  {
400  const Value *V1 = CI1->getArgOperand(0);
401  const Value *V2 = CI2->getArgOperand(0);
402  const ConstantInt* C1 = SVFUtil::dyn_cast<ConstantInt>(V1);
403  const ConstantInt* C2 = SVFUtil::dyn_cast<ConstantInt>(V2);
404  assert(0 != C1 && 0 != C2);
405  return C1->getZExtValue() < C2->getZExtValue();
406  }
407 
414  const Instruction* I)
415  {
416  I = I->getPrevNode();
417  while (I)
418  {
419  if (SVFUtil::isa<LoadInst, StoreInst>(I))
420  return I;
421 
423 
424  if (const SVFFunction *callee = SVFUtil::getCallee(inst))
425  {
426  if (callee->getName().find("llvm.memset") != std::string::npos)
427  return I;
428 
429  }
430  I = I->getPrevNode();
431  }
432  return nullptr;
433  }
434 
436 
437  static const RC_FLAG RC_MHP = 0x01;
438  static const RC_FLAG RC_ALIASES = 0x02;
439  static const RC_FLAG RC_PROTECTED = 0x04;
440  static const RC_FLAG RC_RACE = 0x10;
442 
445  static constexpr char const *RC_ACCESS = "RC_ACCESS";
446 };
447 } // namespace SVF end
448 #endif /* MTARESULTVALIDATOR_H_ */
#define F(f)
const char *const string
Definition: cJSON.h:172
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:105
SVFInstruction * getSVFInstruction(const Instruction *inst) const
Definition: LLVMModule.h:224
SVFValue * getSVFValue(const Value *value)
Definition: MHP.h:46
TCT * getTCT() const
Get Thread Creation Tree.
Definition: MHP.h:82
ThreadCallGraph * getThreadCallGraph() const
Get ThreadCallGraph.
Definition: MHP.h:76
Map< const SVFInstruction *, CxtThreadStmtSet > InstToThreadStmtSetMap
Definition: MHP.h:55
Map< CxtThreadStmt, NodeBS > ThreadStmtToThreadInterleav
Definition: MHP.h:54
void dumpCxt(const CallStrCxt &cxt) const
static const INTERLEV_FLAG INTERLEV_UNSOUND
static constexpr char const * INTERLEV_ACCESS
Map< NodeID, CallStrCxt > vthdToCxtMap
const Instruction * getPreviousMemoryAccessInst(const Instruction *I)
bool matchCxt(const CallStrCxt cxt1, const CallStrCxt cxt2) const
Map< NodeID, const SVFInstruction * > csnumToInst
rthdToChildrenMap rthdToChildren
static const INTERLEV_FLAG INTERLEV_TRUE
Constant INTERLEV_FLAG values.
std::vector< std::string > split(const std::string &s, char delim)
std::vector< std::string > getStringArg(const Instruction *inst, unsigned int arg_num)
INTERLEV_FLAG validateInterleaving()
Map< NodeID, Set< NodeID > > rthdToChildrenMap
Map< NodeID, NodeID > vthdTorthdMap
static const INTERLEV_FLAG INTERLEV_IMPRECISE
std::string getOutput(const char *scenario, bool analysisRes)
MHP::InstToThreadStmtSetMap instToTSMap
std::string getOutputforInterlevAnalysis(const char *scenario, INTERLEV_FLAG analysisRes)
static constexpr char const * CXT_THREAD
Map a statement to its thread interleavings.
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
Map< NodeID, NodeID > rthdTovthdMap
MHP::ThreadStmtToThreadInterleav threadStmtToInterLeaving
NodeID getIntArg(const Instruction *inst, unsigned int arg_num)
static constexpr char const * TCT_ACCESS
CallStrCxt getCxtArg(const Instruction *inst, unsigned int arg_num)
SVFModule * getModule() const
void dumpInterlev(NodeBS &lev)
bool isFlaged(const RC_FLAG flag) const
Class member access.
AccessPair(const Instruction *I1, const Instruction *I2, const RC_FLAG flags)
Constructor.
const Instruction * getInstruction1() const
const Instruction * getInstruction2() const
Validate the result of concurrent analysis.
static const RC_FLAG RC_ALIASES
virtual bool mayHaveDataRace(const Instruction *I1, const Instruction *I2)
static bool compare(const CallBase *CI1, const CallBase *CI2)
void validateAll()
Perform validation for all targets.
void validateAll()
Perform validation for all targets.
void release()
Release resource.
bool hasValidationTarget() const
Check if the input program has validation target.
const Instruction * getPreviousMemoryAccessInst(const Instruction *I)
virtual ~RaceResultValidator()
Destructor.
std::vector< AccessPair > accessPairs
static const RC_FLAG RC_MHP
Constant RC_FLAG values.
static const RC_FLAG RC_RACE
static const RC_FLAG RC_PROTECTED
static constexpr char const * RC_ACCESS
const Instruction * getPreviousMemoryAccessInst(const Instruction *I)
virtual bool mayAccessAliases(const Instruction *I1, const Instruction *I2)
virtual bool protectedByCommonLocks(const Instruction *I1, const Instruction *I2)
void init(SVFModule *M)
Initialization.
std::string getOutput(const char *scenario, bool analysisRes, bool expectedRes)
Get the validation result string of a single validation scenario.
virtual bool mayHappenInParallel(const Instruction *I1, const Instruction *I2)
iterator begin()
Definition: SVFModule.h:133
iterator end()
Definition: SVFModule.h:141
virtual const std::string getSourceLoc() const
Definition: SVFValue.h:280
SVFModule * getSVFModule() const
Get SVFFModule.
Definition: TCT.h:176
ThreadAPI * getThreadAPI() const
Thread API.
const CallBase * getLLVMCallSite(const Value *value)
Return LLVM callsite given a value.
Definition: LLVMUtil.h:59
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition: LLVMUtil.h:45
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition: SVFUtil.cpp:53
const SVFFunction * getCallee(const CallSite cs)
Return callee of a callsite. Return null if this is an indirect call.
Definition: SVFUtil.h:241
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition: SVFUtil.cpp:76
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
llvm::CallBase CallBase
Definition: BasicTypes.h:146
llvm::Use Use
Definition: BasicTypes.h:72
unsigned NodeID
llvm::Function Function
Definition: BasicTypes.h:85
llvm::Instruction Instruction
Definition: BasicTypes.h:87
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82
llvm::Module Module
Definition: BasicTypes.h:84
std::vector< u32_t > CallStrCxt
Definition: GeneralType.h:122
llvm::ConstantInt ConstantInt
Definition: BasicTypes.h:125