Static Value-Flow Analysis
SVFUtil.h
Go to the documentation of this file.
1 //===- SVFUtil.h -- Analysis helper functions----------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2017> <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  * SVFUtil.h
25  *
26  * Created on: Apr 11, 2013
27  * Author: Yulei Sui, dye
28  */
29 
30 #ifndef AnalysisUtil_H_
31 #define AnalysisUtil_H_
32 
34 #include "SVFIR/SVFValue.h"
35 #include "SVFIR/SVFModule.h"
36 #include "Util/ExtAPI.h"
37 #include "MemoryModel/PointsTo.h"
38 #include <time.h>
39 
40 namespace SVF
41 {
42 
43 /*
44  * Util class to assist pointer analysis
45  */
46 namespace SVFUtil
47 {
48 
50 inline std::ostream &outs()
51 {
52  return std::cout;
53 }
54 
56 inline std::ostream &errs()
57 {
58  return std::cerr;
59 }
60 
62 void dumpSet(NodeBS To, OutStream & O = SVFUtil::outs());
63 void dumpSet(PointsTo To, OutStream & O = SVFUtil::outs());
64 
66 void dumpPointsToSet(unsigned node, NodeBS To) ;
67 void dumpSparseSet(const NodeBS& To);
68 
70 void dumpAliasSet(unsigned node, NodeBS To) ;
71 
73 std::string sucMsg(const std::string& msg);
74 
76 std::string wrnMsg(const std::string& msg);
77 
79 void writeWrnMsg(const std::string& msg);
80 
82 
83 std::string errMsg(const std::string& msg);
84 std::string bugMsg1(const std::string& msg);
85 std::string bugMsg2(const std::string& msg);
86 std::string bugMsg3(const std::string& msg);
88 
90 std::string pasMsg(const std::string& msg);
91 
93 void reportMemoryUsageKB(const std::string& infor,
94  OutStream& O = SVFUtil::outs());
95 
97 bool getMemoryUsageKB(u32_t* vmrss_kb, u32_t* vmsize_kb);
98 
100 void increaseStackSize();
101 
107 inline bool cmpPts (const PointsTo& lpts,const PointsTo& rpts)
108 {
109  if (lpts.count() != rpts.count())
110  return (lpts.count() < rpts.count());
111  else
112  {
113  PointsTo::iterator bit = lpts.begin(), eit = lpts.end();
114  PointsTo::iterator rbit = rpts.begin(), reit = rpts.end();
115  for (; bit != eit && rbit != reit; bit++, rbit++)
116  {
117  if (*bit != *rbit)
118  return (*bit < *rbit);
119  }
120 
121  return false;
122  }
123 }
124 
125 inline bool cmpNodeBS(const NodeBS& lpts,const NodeBS& rpts)
126 {
127  if (lpts.count() != rpts.count())
128  return (lpts.count() < rpts.count());
129  else
130  {
131  NodeBS::iterator bit = lpts.begin(), eit = lpts.end();
132  NodeBS::iterator rbit = rpts.begin(), reit = rpts.end();
133  for (; bit != eit && rbit != reit; bit++, rbit++)
134  {
135  if (*bit != *rbit)
136  return (*bit < *rbit);
137  }
138 
139  return false;
140  }
141 }
142 
143 typedef struct equalPointsTo
144 {
145  bool operator()(const PointsTo& lhs, const PointsTo& rhs) const
146  {
147  return SVFUtil::cmpPts(lhs, rhs);
148  }
150 
151 typedef struct equalNodeBS
152 {
153  bool operator()(const NodeBS& lhs, const NodeBS& rhs) const
154  {
155  return SVFUtil::cmpNodeBS(lhs, rhs);
156  }
158 
159 inline NodeBS ptsToNodeBS(const PointsTo &pts)
160 {
161  NodeBS nbs;
162  for (const NodeID o : pts) nbs.set(o);
163  return nbs;
164 }
165 
167 void dumpPointsToList(const PointsToList& ptl);
168 
170 bool isIntrinsicInst(const SVFInstruction* inst);
171 bool isIntrinsicInst(const ICFGNode* inst);
173 
175 inline bool isCallSite(const SVFValue* val)
176 {
177  if(SVFUtil::isa<SVFCallInst>(val))
178  return true;
179  else
180  return false;
181 }
182 
183 bool isCallSite(const ICFGNode* inst);
184 
185 bool isRetInstNode(const ICFGNode* node);
186 
187 
189 inline bool isNonInstricCallSite(const ICFGNode* inst)
190 {
191  if(isIntrinsicInst(inst))
192  return false;
193  return isCallSite(inst);
194 }
195 
199 bool matchArgs(const CallICFGNode* cs, const SVFFunction* callee);
200 
201 
203 inline std::vector<std::string> split(const std::string& s, char separator)
204 {
205  std::vector<std::string> output;
206  std::string::size_type prev_pos = 0, pos = 0;
207  while ((pos = s.find(separator, pos)) != std::string::npos)
208  {
209  std::string substring(s.substr(prev_pos, pos - prev_pos));
210  if (!substring.empty())
211  {
212  output.push_back(substring);
213  }
214  prev_pos = ++pos;
215  }
216  std::string lastSubstring(s.substr(prev_pos, pos - prev_pos));
217  if (!lastSubstring.empty())
218  {
219  output.push_back(lastSubstring);
220  }
221  return output;
222 }
223 
225 template <typename Data>
227 {
228  for (const typename Map<Data, unsigned>::value_type &ptocc : from)
229  {
230  to[ptocc.first] += ptocc.second;
231  }
232 }
233 
236 
238 template <typename Key, typename KeySet>
239 inline void insertKey(const Key &key, KeySet &keySet)
240 {
241  keySet.insert(key);
242 }
243 
245 inline void insertKey(const NodeID &key, NodeBS &keySet)
246 {
247  keySet.set(key);
248 }
249 
251 template <typename Key, typename KeySet>
252 inline void removeKey(const Key &key, KeySet &keySet)
253 {
254  keySet.erase(key);
255 }
256 
258 inline void removeKey(const NodeID &key, NodeBS &keySet)
259 {
260  keySet.reset(key);
261 }
262 
264 void timeLimitReached(int signum);
265 
269 bool startAnalysisLimitTimer(unsigned timeLimit);
270 
273 void stopAnalysisLimitTimer(bool limitTimerSet);
274 
277 
278 inline bool isExtCall(const SVFFunction* fun)
279 {
280  return fun && ExtAPI::getExtAPI()->is_ext(fun);
281 }
282 
283 inline bool isMemcpyExtFun(const SVFFunction* fun)
284 {
285  return fun && ExtAPI::getExtAPI()->is_memcpy(fun);
286 }
287 
288 inline bool isMemsetExtFun(const SVFFunction* fun)
289 {
290  return fun && ExtAPI::getExtAPI()->is_memset(fun);
291 }
292 
294 
295 inline bool isHeapAllocExtFunViaRet(const SVFFunction* fun)
297 {
298  return fun && (ExtAPI::getExtAPI()->is_alloc(fun)
299  || ExtAPI::getExtAPI()->is_realloc(fun));
300 }
301 
302 inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun)
303 {
304  return fun && ExtAPI::getExtAPI()->is_arg_alloc(fun);
305 }
306 
308 
310 {
311  return ExtAPI::getExtAPI()->get_alloc_arg_pos(fun);
312 }
313 
315 
316 inline bool isReallocExtFun(const SVFFunction* fun)
318 {
319  return fun && (ExtAPI::getExtAPI()->is_realloc(fun));
320 }
321 
323 
324 inline bool isProgEntryFunction(const SVFFunction* fun)
326 {
327  return fun && fun->getName() == "main";
328 }
329 
331 const SVFFunction* getProgFunction(const std::string& funName);
332 
334 const SVFFunction* getProgEntryFunction();
335 
337 
338 inline bool isProgExitFunction (const SVFFunction * fun)
339 {
340  return fun && (fun->getName() == "exit" ||
341  fun->getName() == "__assert_rtn" ||
342  fun->getName() == "__assert_fail" );
343 }
344 
346 inline bool isArgOfUncalledFunction(const SVFValue* svfval)
347 {
348  if(const SVFArgument* arg = SVFUtil::dyn_cast<SVFArgument>(svfval))
349  return arg->isArgOfUncalledFunction();
350  else
351  return false;
352 }
353 
355 
356 inline const SVFVar* getForkedFun(const CallICFGNode *inst)
357 {
358  return ThreadAPI::getThreadAPI()->getForkedFun(inst);
359 }
361 
362 
363 bool isExtCall(const CallICFGNode* cs);
364 
365 bool isExtCall(const ICFGNode* node);
366 
367 bool isHeapAllocExtCallViaArg(const CallICFGNode* cs);
368 
369 
371 bool isHeapAllocExtCallViaRet(const CallICFGNode* cs);
372 
373 bool isHeapAllocExtCall(const ICFGNode* cs);
374 
375 
376 
378 
381 
382 bool isReallocExtCall(const CallICFGNode* cs);
384 
387 inline bool isThreadForkCall(const CallICFGNode *inst)
388 {
389  return ThreadAPI::getThreadAPI()->isTDFork(inst);
390 }
392 
395 inline bool isThreadJoinCall(const CallICFGNode* cs)
396 {
397  return ThreadAPI::getThreadAPI()->isTDJoin(cs);
398 }
400 
403 inline bool isThreadExitCall(const CallICFGNode* cs)
404 {
405  return ThreadAPI::getThreadAPI()->isTDExit(cs);
406 }
408 
411 inline bool isLockAquireCall(const CallICFGNode* cs)
412 {
413  return ThreadAPI::getThreadAPI()->isTDAcquire(cs);
414 }
416 
419 inline bool isLockReleaseCall(const CallICFGNode* cs)
420 {
421  return ThreadAPI::getThreadAPI()->isTDRelease(cs);
422 }
424 
426 
427 inline bool isBarrierWaitCall(const CallICFGNode* cs)
428 {
429  return ThreadAPI::getThreadAPI()->isTDBarWait(cs);
430 }
432 
434 
436 {
438 }
440 
441 
442 bool isProgExitCall(const CallICFGNode* cs);
443 
444 
445 template<typename T>
446 constexpr typename std::remove_reference<T>::type &&
447 move(T &&t) noexcept
448 {
449  return std::move(t);
450 }
451 
453 template <typename... Ts> struct make_void
454 {
455  typedef void type;
456 };
457 template <typename... Ts> using void_t = typename make_void<Ts...>::type;
458 
462 template <typename T, typename = void> struct is_iterable : std::false_type {};
463 template <typename T>
464 struct is_iterable<T, void_t<decltype(std::begin(std::declval<T&>()) !=
465  std::end(std::declval<T&>()))>>
466 : std::true_type {};
467 template <typename T> constexpr bool is_iterable_v = is_iterable<T>::value;
469 
472 template <typename T> struct is_map : std::false_type {};
473 template <typename... Ts> struct is_map<std::map<Ts...>> : std::true_type {};
474 template <typename... Ts>
475 struct is_map<std::unordered_map<Ts...>> : std::true_type {};
476 template <typename... Ts> constexpr bool is_map_v = is_map<Ts...>::value;
478 
481 template <typename T> struct is_set : std::false_type {};
482 template <typename... Ts> struct is_set<std::set<Ts...>> : std::true_type {};
483 template <typename... Ts>
484 struct is_set<std::unordered_set<Ts...>> : std::true_type {};
485 template <typename... Ts> constexpr bool is_set_v = is_set<Ts...>::value;
487 
489 template <typename T> struct is_sequence_container : std::false_type {};
490 template <typename... Ts>
491 struct is_sequence_container<std::vector<Ts...>> : std::true_type {};
492 template <typename... Ts>
493 struct is_sequence_container<std::deque<Ts...>> : std::true_type {};
494 template <typename... Ts>
495 struct is_sequence_container<std::list<Ts...>> : std::true_type {};
496 template <typename... Ts>
497 constexpr bool is_sequence_container_v = is_sequence_container<Ts...>::value;
499 
500 
501 } // End namespace SVFUtil
502 
503 } // End namespace SVF
504 
505 #endif /* AnalysisUtil_H_ */
set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) add_llvm_executable(wpa wpa.cpp) target_link_libraries(wpa PUBLIC $
Definition: CMakeLists.txt:1
newitem type
Definition: cJSON.cpp:2739
const char *const string
Definition: cJSON.h:172
bool is_alloc(const SVFFunction *F)
Definition: ExtAPI.cpp:217
bool is_arg_alloc(const SVFFunction *F)
Definition: ExtAPI.cpp:223
bool is_ext(const SVFFunction *F)
Definition: ExtAPI.cpp:253
static ExtAPI * getExtAPI()
Definition: ExtAPI.cpp:42
s32_t get_alloc_arg_pos(const SVFFunction *F)
Definition: ExtAPI.cpp:229
bool is_memset(const SVFFunction *F)
Definition: ExtAPI.cpp:212
bool is_memcpy(const SVFFunction *F)
Definition: ExtAPI.cpp:205
bool is_realloc(const SVFFunction *F)
Definition: ExtAPI.cpp:245
const_iterator end() const
Definition: PointsTo.h:132
u32_t count() const
Returns number of elements.
Definition: PointsTo.cpp:111
const_iterator begin() const
Definition: PointsTo.h:128
const std::string & getName() const
Definition: SVFValue.h:243
iterator end() const
void set(unsigned Idx)
unsigned count() const
iterator begin() const
void reset(unsigned Idx)
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.
Definition: ThreadAPI.cpp:133
bool isTDJoin(const CallICFGNode *inst) const
Return true if this call wait for a worker thread.
Definition: ThreadAPI.cpp:138
bool isTDRelease(const CallICFGNode *inst) const
Return true if this call release a lock.
Definition: ThreadAPI.cpp:153
static ThreadAPI * getThreadAPI()
Return a static reference.
Definition: ThreadAPI.h:105
const SVFVar * getForkedFun(const CallICFGNode *inst) const
Definition: ThreadAPI.cpp:170
bool isTDExit(const CallICFGNode *inst) const
Return true if this call exits/terminate a thread.
Definition: ThreadAPI.cpp:143
const SVFVar * getActualParmAtForkSite(const CallICFGNode *inst) const
Definition: ThreadAPI.cpp:178
bool isTDBarWait(const CallICFGNode *inst) const
Return true if this call waits for a barrier.
Definition: ThreadAPI.cpp:158
bool isTDAcquire(const CallICFGNode *inst) const
Return true if this call acquire a lock.
Definition: ThreadAPI.cpp:148
hclust_fast_methods
Definition: fastcluster.h:66
bool isReallocExtCall(const CallICFGNode *cs)
Definition: SVFUtil.cpp:381
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition: SVFUtil.cpp:53
constexpr bool is_set_v
Definition: SVFUtil.h:485
void increaseStackSize()
Increase the stack size limit.
Definition: SVFUtil.cpp:227
std::string bugMsg1(const std::string &msg)
Definition: SVFUtil.cpp:81
std::string hclustMethodToString(hclust_fast_methods method)
Returns a string representation of a hclust method.
Definition: SVFUtil.cpp:260
void stopAnalysisLimitTimer(bool limitTimerSet)
Definition: SVFUtil.cpp:310
bool isLockAquireCall(const CallICFGNode *cs)
Definition: SVFUtil.h:411
bool isHeapAllocExtFunViaRet(const SVFFunction *fun)
Return true if the call is a heap allocator/reallocator.
Definition: SVFUtil.h:296
bool isArgOfUncalledFunction(const SVFValue *svfval)
Return true if this argument belongs to an uncalled function.
Definition: SVFUtil.h:346
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278
bool isProgEntryFunction(const SVFFunction *fun)
Program entry function e.g. main.
Definition: SVFUtil.h:325
bool isBarrierWaitCall(const CallICFGNode *cs)
Return true if this is a barrier wait call.
Definition: SVFUtil.h:427
void mergePtsOccMaps(Map< Data, unsigned > &to, const Map< Data, unsigned > from)
Given a map mapping points-to sets to a count, adds from into to.
Definition: SVFUtil.h:226
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
OrderedSet< PointsTo, equalPointsTo > PointsToList
Definition: SVFUtil.h:166
void dumpAliasSet(unsigned node, NodeBS To)
Dump alias set.
Definition: SVFUtil.cpp:137
const SVFVar * getActualParmAtForkSite(const CallICFGNode *cs)
Return sole argument of the thread routine.
Definition: SVFUtil.h:435
bool isMemsetExtFun(const SVFFunction *fun)
Definition: SVFUtil.h:288
bool getMemoryUsageKB(u32_t *vmrss_kb, u32_t *vmsize_kb)
Get memory usage from system file. Return TRUE if succeed.
Definition: SVFUtil.cpp:177
bool isMemcpyExtFun(const SVFFunction *fun)
Definition: SVFUtil.h:283
void reportMemoryUsageKB(const std::string &infor, OutStream &O=SVFUtil::outs())
Print memory usage in KB.
Definition: SVFUtil.cpp:167
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447
bool startAnalysisLimitTimer(unsigned timeLimit)
Definition: SVFUtil.cpp:289
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition: SVFUtil.cpp:76
std::string bugMsg3(const std::string &msg)
Definition: SVFUtil.cpp:91
constexpr bool is_sequence_container_v
Definition: SVFUtil.h:497
bool isHeapAllocExtCallViaArg(const CallICFGNode *cs)
Definition: SVFUtil.cpp:351
bool isHeapAllocExtCall(const ICFGNode *cs)
Definition: SVFUtil.cpp:369
u32_t getHeapAllocHoldingArgPosition(const SVFFunction *fun)
Get the position of argument that holds an allocated heap object.
Definition: SVFUtil.h:309
bool isNonInstricCallSite(const ICFGNode *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition: SVFUtil.h:189
bool isThreadJoinCall(const CallICFGNode *cs)
Definition: SVFUtil.h:395
NodeBS ptsToNodeBS(const PointsTo &pts)
Definition: SVFUtil.h:159
constexpr bool is_map_v
Definition: SVFUtil.h:476
bool isCallSite(const SVFValue *val)
Whether an instruction is a call or invoke instruction.
Definition: SVFUtil.h:175
bool cmpNodeBS(const NodeBS &lpts, const NodeBS &rpts)
Definition: SVFUtil.h:125
bool isReallocExtFun(const SVFFunction *fun)
Return true if the call is a heap reallocator.
Definition: SVFUtil.h:317
constexpr bool is_iterable_v
Definition: SVFUtil.h:467
bool cmpPts(const PointsTo &lpts, const PointsTo &rpts)
Definition: SVFUtil.h:107
const SVFVar * getForkedFun(const CallICFGNode *inst)
Return thread fork function.
Definition: SVFUtil.h:356
bool isThreadForkCall(const CallICFGNode *inst)
Definition: SVFUtil.h:387
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition: SVFUtil.cpp:66
void dumpSparseSet(const NodeBS &To)
Definition: SVFUtil.cpp:115
bool isHeapAllocExtFunViaArg(const SVFFunction *fun)
Definition: SVFUtil.h:302
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
bool isLockReleaseCall(const CallICFGNode *cs)
Definition: SVFUtil.h:419
bool isIntrinsicInst(const SVFInstruction *inst)
Return true if it is an llvm intrinsic instruction.
Definition: SVFUtil.cpp:247
void dumpPointsToSet(unsigned node, NodeBS To)
Dump points-to set.
Definition: SVFUtil.cpp:107
struct SVF::SVFUtil::equalPointsTo equalPointsTo
bool isThreadExitCall(const CallICFGNode *cs)
Definition: SVFUtil.h:403
std::string bugMsg2(const std::string &msg)
Definition: SVFUtil.cpp:86
bool isProgExitCall(const CallICFGNode *cs)
Definition: SVFUtil.cpp:396
std::string wrnMsg(const std::string &msg)
Returns warning message by converting a string into yellow string output.
Definition: SVFUtil.cpp:61
struct SVF::SVFUtil::equalNodeBS equalNodeBS
typename make_void< Ts... >::type void_t
Definition: SVFUtil.h:457
bool isRetInstNode(const ICFGNode *node)
Definition: SVFUtil.cpp:388
bool matchArgs(const CallICFGNode *cs, const SVFFunction *callee)
Definition: SVFUtil.cpp:320
void timeLimitReached(int signum)
Function to call when alarm for time limit hits.
Definition: SVFUtil.cpp:280
const SVFFunction * getProgFunction(const std::string &funName)
Get program entry function from function name.
Definition: SVFUtil.cpp:402
std::vector< std::string > split(const std::string &s, char separator)
Split into two substrings around the first occurrence of a separator string.
Definition: SVFUtil.h:203
bool isHeapAllocExtCallViaRet(const CallICFGNode *cs)
interfaces to be used externally
Definition: SVFUtil.cpp:375
void dumpSet(NodeBS To, OutStream &O=SVFUtil::outs())
Dump sparse bitvector set.
Definition: SVFUtil.cpp:147
bool isProgExitFunction(const SVFFunction *fun)
Return true if this is a program exit function call.
Definition: SVFUtil.h:338
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
const SVFFunction * getProgEntryFunction()
Get program entry function.
Definition: SVFUtil.cpp:415
void removeKey(const Key &key, KeySet &keySet)
Removes an element from a Set/CondSet (or anything implementing ::erase).
Definition: SVFUtil.h:252
void insertKey(const Key &key, KeySet &keySet)
Inserts an element into a Set/CondSet (with ::insert).
Definition: SVFUtil.h:239
void dumpPointsToList(const PointsToList &ptl)
Definition: SVFUtil.cpp:122
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
std::set< Key, Compare, Allocator > OrderedSet
Definition: GeneralType.h:105
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
std::ostream OutStream
Definition: GeneralType.h:45
unsigned u32_t
Definition: GeneralType.h:46
bool operator()(const NodeBS &lhs, const NodeBS &rhs) const
Definition: SVFUtil.h:153
bool operator()(const PointsTo &lhs, const PointsTo &rhs) const
Definition: SVFUtil.h:145
Type trait that checks if a type is iterable (can be applied on a range-based for loop)
Definition: SVFUtil.h:462
Type trait to check if a type is a map or unordered_map.
Definition: SVFUtil.h:472
Type trait to check if a type is vector or list.
Definition: SVFUtil.h:489
Type trait to check if a type is a set or unordered_set.
Definition: SVFUtil.h:481
void_t is not available until C++17. We define it here for C++11/14.
Definition: SVFUtil.h:454