Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVFUtil.cpp
Go to the documentation of this file.
1//===- AnalysisUtil.cpp -- Helper functions for pointer analysis--------------//
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 * AnalysisUtil.cpp
25 *
26 * Created on: Apr 11, 2013
27 * Author: Yulei Sui
28 */
29
30#ifdef _WIN32
31#ifndef WIN32_LEAN_AND_MEAN
32#define WIN32_LEAN_AND_MEAN
33#endif
34#ifndef NOMINMAX
35#define NOMINMAX
36#endif
37#include <windows.h>
38#include <sys/types.h>
39#include <sys/stat.h>
40#define stat _stat
41#define popen _popen
42#define pclose _pclose
43#else
44#include <unistd.h>
45#include <signal.h>
46#include <sys/resource.h>
47#include <sys/stat.h>
48#include <dlfcn.h>
49#endif
50
51#include "Util/Options.h"
52#include "Util/SVFUtil.h"
54#include "Graphs/CallGraph.h"
55#include "SVFIR/SVFIR.h"
56#include "SVFIR/SVFVariables.h"
57
58using namespace SVF;
59
61#define KNRM "\x1B[1;0m"
62#define KRED "\x1B[1;31m"
63#define KGRN "\x1B[1;32m"
64#define KYEL "\x1B[1;33m"
65#define KBLU "\x1B[1;34m"
66#define KPUR "\x1B[1;35m"
67#define KCYA "\x1B[1;36m"
68#define KWHT "\x1B[1;37m"
69
70
71
75std::string SVFUtil::sucMsg(const std::string& msg)
76{
77 return KGRN + msg + KNRM;
78}
79
83std::string SVFUtil::wrnMsg(const std::string& msg)
84{
85 return KYEL + msg + KNRM;
86}
87
88void SVFUtil::writeWrnMsg(const std::string& msg)
89{
91 return;
92 outs() << wrnMsg(msg) << "\n";
93}
94
98std::string SVFUtil::errMsg(const std::string& msg)
99{
100 return KRED + msg + KNRM;
101}
102
103std::string SVFUtil::bugMsg1(const std::string& msg)
104{
105 return KYEL + msg + KNRM;
106}
107
108std::string SVFUtil::bugMsg2(const std::string& msg)
109{
110 return KPUR + msg + KNRM;
111}
112
113std::string SVFUtil::bugMsg3(const std::string& msg)
114{
115 return KCYA + msg + KNRM;
116}
117
121std::string SVFUtil::pasMsg(const std::string& msg)
122{
123 return KBLU + msg + KNRM;
124}
125
130{
131 outs() << "node " << node << " points-to: {";
132 dumpSet(bs);
133 outs() << "}\n";
134}
135
136// For use from the debugger.
138{
139 outs() << "{";
140 dumpSet(bs);
141 outs() << "}\n";
142}
143
145{
146 outs() << "{";
147 for (PointsToList::const_iterator ii = ptl.begin(), ie = ptl.end();
148 ii != ie; ii++)
149 {
150 auto bs = *ii;
151 dumpSet(bs);
152 }
153 outs() << "}\n";
154}
155
159void SVFUtil::dumpAliasSet(unsigned node, NodeBS bs)
160{
161 outs() << "node " << node << " alias set: {";
162 dumpSet(bs);
163 outs() << "}\n";
164}
165
170{
171 for (NodeBS::iterator ii = bs.begin(), ie = bs.end();
172 ii != ie; ii++)
173 {
174 O << " " << *ii << " ";
175 }
176}
177
179{
180 for (NodeID n : pt)
181 {
182 o << " " << n << " ";
183 }
184}
185
189void SVFUtil::reportMemoryUsageKB(const std::string& infor, OutStream & O)
190{
193 O << infor << "\tVmRSS: " << vmrss << "\tVmSize: " << vmsize << "\n";
194}
195
200{
201 /* Get the current process' status file from the proc filesystem */
202 char buffer[8192];
203 FILE* procfile = fopen("/proc/self/status", "r");
204 if(procfile)
205 {
206 u32_t result = fread(buffer, sizeof(char), 8192, procfile);
207 if (result == 0)
208 {
209 fputs ("Reading error\n",stderr);
210 }
211 }
212 else
213 {
214 SVFUtil::writeWrnMsg(" /proc/self/status file not exit!");
215 return false;
216 }
218
219 /* Look through proc status contents line by line */
220 char delims[] = "\n";
221 char* line = strtok(buffer, delims);
222
223 bool found_vmrss = false;
224 bool found_vmsize = false;
225
226 while (line != nullptr && (found_vmrss == false || found_vmsize == false))
227 {
228 if (strstr(line, "VmRSS:") != nullptr)
229 {
230 sscanf(line, "%*s %u", vmrss_kb);
231 found_vmrss = true;
232 }
233
234 if (strstr(line, "VmSize:") != nullptr)
235 {
236 sscanf(line, "%*s %u", vmsize_kb);
237 found_vmsize = true;
238 }
239
240 line = strtok(nullptr, delims);
241 }
242
243 return (found_vmrss && found_vmsize);
244}
245
250{
251#ifdef _WIN32
252 // On Windows, stack size is set at link time via CMake (/STACK:268435456)
253#else
254 // Increase stack size via POSIX rlimit
255 const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb
256 struct rlimit rl;
258 if (result == 0)
259 {
260 if (rl.rlim_cur < kStackSize)
261 {
262 rl.rlim_cur = kStackSize;
264 if (result != 0)
265 writeWrnMsg("setrlimit returned result !=0 \n");
266 }
267 }
268#endif
269}
270
271bool SVFUtil::fileExists(const std::string& path)
272{
273 struct stat statbuf;
274 return !path.empty() && (stat(path.c_str(), &statbuf) == 0);
275}
276
277std::string SVFUtil::getStdoutFromCommand(const std::string& command)
278{
279 char buffer[128];
280 std::string result;
281
282 FILE* pipe = popen(command.c_str(), "r");
283 if (!pipe)
284 return "";
285
286 while (fgets(buffer, sizeof(buffer), pipe) != nullptr)
287 {
288 result += buffer;
289 }
290
291 int status = pclose(pipe);
292 if (status != 0)
293 return "";
294
295 // remove trailing newlines
296 result.erase(std::remove(result.begin(), result.end(), '\n'), result.end());
297 result.erase(std::remove(result.begin(), result.end(), '\r'), result.end());
298
299 return result;
300}
301
303{
304#ifdef _WIN32
305 char path[MAX_PATH];
306 HMODULE hm = NULL;
310 {
311 GetModuleFileNameA(hm, path, sizeof(path));
312 std::string s(path);
313 for (size_t i = 0; i < s.length(); ++i)
314 {
315 if (s[i] == '\\')
316 {
317 s[i] = '/';
318 }
319 }
320 return s;
321 }
322 return "";
323#else
325 if (dladdr((void*)&getCurrentSOPath, &info) && info.dli_fname)
326 {
327 return std::string(info.dli_fname);
328 }
329 return "";
330#endif
331}
332
333
334
336{
337 switch (method)
338 {
340 return "single";
342 return "complete";
344 return "average";
346 return "median";
348 return "svf-best";
349 default:
350 assert(false && "SVFUtil::hclustMethodToString: unknown method");
351 abort();
352 }
353}
354
356{
357 SVFUtil::outs().flush();
358 // TODO: output does not indicate which time limit is reached.
359 // This can be better in the future.
360 SVFUtil::outs() << "WPA: time limit reached\n";
361 exit(101);
362}
363
365{
366#ifdef _WIN32
367 // POSIX alarm signals are not available on Win32
368 (void)timeLimit;
369#else
370 assert(timeLimit > 0 && "startAnalysisTimer: given non-0 time-limit.");
371
372 // If an alarm is already set, don't set another. That means this analysis
373 // is part of another which has a time limit.
374 unsigned remainingSeconds = alarm(0);
375 assert(remainingSeconds != 0 && "startAnalysisTimer: attempt to set a second alarm.");
376
378 alarm(timeLimit);
379#endif
380}
381
384{
385#ifdef _WIN32
386 // No-op on Win32
387#else
388 alarm(0);
389#endif
390}
391
398{
399 if (callee->isVarArg() || ThreadAPI::getThreadAPI()->isTDFork(call))
400 return call->arg_size() >= callee->arg_size();
401 else
402 return call->arg_size() == callee->arg_size();
403}
404
406{
407 return SVFUtil::isa<CallICFGNode>(inst);
408}
409
411{
412 if (const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst))
413 {
414 const FunObjVar* func = call->getCalledFunction();
415 if (func && func->isIntrinsic())
416 {
417 return true;
418 }
419 }
420 return false;
421}
422
424{
425 return isExtCall(cs->getCalledFunction());
426}
427
432
433
435{
436 return getHeapAllocHoldingArgPosition(cs->getCalledFunction());
437}
438
439
441{
442 if(!isCallSite(node)) return false;
443 return isExtCall(cast<CallICFGNode>(node)->getCalledFunction());
444}
445
447{
448 if(!isCallSite(cs)) return false;
449 return isHeapAllocExtCallViaRet(cast<CallICFGNode>(cs)) || isHeapAllocExtCallViaArg(cast<CallICFGNode>(cs));
450}
451
457
459{
460 bool isPtrTy = cs->getType()->isPointerTy();
462}
463
464
466{
467 if (const auto& intraNode = dyn_cast<IntraICFGNode>(node))
468 return intraNode->isRetInst();
469 else
470 return false;
471}
472
474{
475 return fun && (fun->getName() == "exit" ||
476 fun->getName() == "__assert_rtn" ||
477 fun->getName() == "__assert_fail");
478}
479
484
487{
489 for (const auto& item: *svfirCallGraph)
490 {
491 const CallGraphNode*fun = item.second;
492 if (fun->getName()==funName)
493 return fun->getFunction();
494 }
495 return nullptr;
496}
497
500{
502 for (const auto& item: *svfirCallGraph)
503 {
504 const CallGraphNode*fun = item.second;
505 if (isProgEntryFunction(fun->getFunction()))
506 return (fun->getFunction());
507 }
508 return nullptr;
509}
510
512{
513 const ValVar* pVar = PAG::getPAG()->getBaseValVar(svfvar->getId());
514 if(const ArgValVar* arg = SVFUtil::dyn_cast<ArgValVar>(pVar))
515 return arg->isArgOfUncalledFunction();
516 else
517 return false;
518}
519
521{
522 assert(valVar->getInEdges().size() == 1);
523 return SVFUtil::dyn_cast<ObjVar>((*valVar->getInEdges().begin())->getSrcNode());
524}
525
527{
528 return fun && ExtAPI::getExtAPI()->is_ext(fun);
529}
530
532{
533 const char* main_name=Options::SVFMain() ? "svf.main" : "main";
534 return funObjVar && funObjVar->getName() == main_name;
535}
#define KNRM
Color for output format.
Definition SVFUtil.cpp:61
#define KPUR
Definition SVFUtil.cpp:66
#define KBLU
Definition SVFUtil.cpp:65
#define KRED
Definition SVFUtil.cpp:62
#define KYEL
Definition SVFUtil.cpp:64
#define KGRN
Definition SVFUtil.cpp:63
#define KCYA
Definition SVFUtil.cpp:67
cJSON * n
Definition cJSON.cpp:2558
char * buffer
Definition cJSON.h:163
cJSON * item
Definition cJSON.h:222
Class representing a function argument variable in the SVFIR.
const FunObjVar * getFunction() const
Get function of this call node.
Definition CallGraph.h:191
const std::string & getName() const
Definition CallGraph.cpp:47
const FunObjVar * getCalledFunction() const
Definition ICFGNode.h:501
u32_t arg_size() const
Definition ICFGNode.h:488
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:43
bool is_ext(const FunObjVar *funObjVar)
Definition ExtAPI.cpp:290
static const Option< bool > DisableWarn
Definition Options.h:196
static Option< bool > SVFMain
Definition Options.h:174
const CallGraph * getCallGraph()
Get CG.
Definition SVFIR.h:249
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:121
const ValVar * getBaseValVar(NodeID id) const
Definition SVFIR.h:509
bool isPointerTy() const
Definition SVFType.h:292
virtual const SVFType * getType() const
Definition SVFValue.h:169
virtual const std::string & getName() const
Definition SVFValue.h:184
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.
static ThreadAPI * getThreadAPI()
Return a static reference.
Definition ThreadAPI.h:99
#define NULL
Definition extapi.c:5
char * fgets(char *str, int n, void *stream)
Definition extapi.c:913
char * strtok(char *str, const char *delim)
Definition extapi.c:500
char * strstr(const char *haystack, const char *needle)
Definition extapi.c:988
hclust_fast_methods
Definition fastcluster.h:66
@ HCLUST_METHOD_AVERAGE
Definition fastcluster.h:72
@ HCLUST_METHOD_COMPLETE
Definition fastcluster.h:70
@ HCLUST_METHOD_SVF_BEST
Definition fastcluster.h:76
@ HCLUST_METHOD_MEDIAN
Definition fastcluster.h:74
@ HCLUST_METHOD_SINGLE
Definition fastcluster.h:68
bool isReallocExtCall(const CallICFGNode *cs)
Definition SVFUtil.cpp:458
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition SVFUtil.cpp:75
void increaseStackSize()
Increase the stack size limit.
Definition SVFUtil.cpp:249
const ObjVar * getObjVarOfValVar(const ValVar *valVar)
Definition SVFUtil.cpp:520
std::string bugMsg1(const std::string &msg)
Definition SVFUtil.cpp:103
bool isProgEntryFunction(const FunObjVar *)
Program entry function e.g. main.
Definition SVFUtil.cpp:531
std::string hclustMethodToString(hclust_fast_methods method)
Returns a string representation of a hclust method.
Definition SVFUtil.cpp:335
bool isIntrinsicInst(const ICFGNode *inst)
Return true if it is an llvm intrinsic instruction.
Definition SVFUtil.cpp:410
u32_t getHeapAllocHoldingArgPosition(const FunObjVar *fun)
Get the position of argument that holds an allocated heap object.
Definition SVFUtil.h:298
const FunObjVar * getProgEntryFunction()
Get program entry function.
Definition SVFUtil.cpp:499
bool isHeapAllocExtFunViaRet(const FunObjVar *fun)
Return true if the call is a heap allocator/reallocator.
Definition SVFUtil.h:284
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:121
OrderedSet< PointsTo, equalPointsTo > PointsToList
Definition SVFUtil.h:176
void dumpAliasSet(unsigned node, NodeBS To)
Dump alias set.
Definition SVFUtil.cpp:159
bool isHeapAllocExtFunViaArg(const FunObjVar *fun)
Definition SVFUtil.h:290
bool getMemoryUsageKB(u32_t *vmrss_kb, u32_t *vmsize_kb)
Get memory usage from system file. Return TRUE if succeed.
Definition SVFUtil.cpp:199
void reportMemoryUsageKB(const std::string &infor, OutStream &O=SVFUtil::outs())
Print memory usage in KB.
Definition SVFUtil.cpp:189
void stopAnalysisLimitTimer(void)
Stops analysis timer.
Definition SVFUtil.cpp:383
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition SVFUtil.cpp:98
std::string bugMsg3(const std::string &msg)
Definition SVFUtil.cpp:113
bool isHeapAllocExtCallViaArg(const CallICFGNode *cs)
Definition SVFUtil.cpp:428
bool isHeapAllocExtCall(const ICFGNode *cs)
Definition SVFUtil.cpp:446
bool isArgOfUncalledFunction(const SVFVar *svfvar)
Definition SVFUtil.cpp:511
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:526
bool matchArgs(const CallICFGNode *cs, const FunObjVar *callee)
Definition SVFUtil.cpp:397
void startAnalysisLimitTimer(unsigned timeLimit)
Starts analysis timer. timeLimit must be non-0. Timer must not be already set.
Definition SVFUtil.cpp:364
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:88
void dumpSparseSet(const NodeBS &To)
Definition SVFUtil.cpp:137
void dumpPointsToSet(unsigned node, NodeBS To)
Dump points-to set.
Definition SVFUtil.cpp:129
bool fileExists(const std::string &path)
Check whether a file exists at the given path.
Definition SVFUtil.cpp:271
std::string getCurrentSOPath()
Return the absolute path of the current module/executable.
Definition SVFUtil.cpp:302
std::string bugMsg2(const std::string &msg)
Definition SVFUtil.cpp:108
bool isProgExitCall(const CallICFGNode *cs)
Definition SVFUtil.cpp:480
bool isCallSite(const ICFGNode *inst)
Definition SVFUtil.cpp:405
std::string wrnMsg(const std::string &msg)
Returns warning message by converting a string into yellow string output.
Definition SVFUtil.cpp:83
bool isReallocExtFun(const FunObjVar *fun)
Return true if the call is a heap reallocator.
Definition SVFUtil.h:306
bool isRetInstNode(const ICFGNode *node)
Definition SVFUtil.cpp:465
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:58
void timeLimitReached(int signum)
Function to call when alarm for time limit hits.
Definition SVFUtil.cpp:355
std::string getStdoutFromCommand(const std::string &command)
Execute a shell command and capture its stdout output.
Definition SVFUtil.cpp:277
bool isHeapAllocExtCallViaRet(const CallICFGNode *cs)
interfaces to be used externally
Definition SVFUtil.cpp:452
void dumpSet(NodeBS To, OutStream &O=SVFUtil::outs())
Dump sparse bitvector set.
Definition SVFUtil.cpp:169
void dumpPointsToList(const PointsToList &ptl)
Definition SVFUtil.cpp:144
bool isProgExitFunction(const FunObjVar *fun)
Return true if this is a program exit function call.
Definition SVFUtil.cpp:473
const FunObjVar * getProgFunction(const std::string &funName)
Get program entry function from function name.
Definition SVFUtil.cpp:486
for isBitcode
Definition BasicTypes.h:70
u32_t NodeID
Definition GeneralType.h:76
std::ostream OutStream
Definition GeneralType.h:66
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:67