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#include <unistd.h>
31#include <signal.h>
32
33#include "Util/Options.h"
34#include "Util/SVFUtil.h"
36#include "Graphs/CallGraph.h"
37#include "SVFIR/SVFIR.h"
38#include "SVFIR/SVFVariables.h"
39
40#include <sys/resource.h>
41
42using namespace SVF;
43
45#define KNRM "\x1B[1;0m"
46#define KRED "\x1B[1;31m"
47#define KGRN "\x1B[1;32m"
48#define KYEL "\x1B[1;33m"
49#define KBLU "\x1B[1;34m"
50#define KPUR "\x1B[1;35m"
51#define KCYA "\x1B[1;36m"
52#define KWHT "\x1B[1;37m"
53
54
55
59std::string SVFUtil::sucMsg(const std::string& msg)
60{
61 return KGRN + msg + KNRM;
62}
63
67std::string SVFUtil::wrnMsg(const std::string& msg)
68{
69 return KYEL + msg + KNRM;
70}
71
72void SVFUtil::writeWrnMsg(const std::string& msg)
73{
75 return;
76 outs() << wrnMsg(msg) << "\n";
77}
78
82std::string SVFUtil::errMsg(const std::string& msg)
83{
84 return KRED + msg + KNRM;
85}
86
87std::string SVFUtil::bugMsg1(const std::string& msg)
88{
89 return KYEL + msg + KNRM;
90}
91
92std::string SVFUtil::bugMsg2(const std::string& msg)
93{
94 return KPUR + msg + KNRM;
95}
96
97std::string SVFUtil::bugMsg3(const std::string& msg)
98{
99 return KCYA + msg + KNRM;
100}
101
105std::string SVFUtil::pasMsg(const std::string& msg)
106{
107 return KBLU + msg + KNRM;
108}
109
114{
115 outs() << "node " << node << " points-to: {";
116 dumpSet(bs);
117 outs() << "}\n";
118}
119
120// For use from the debugger.
122{
123 outs() << "{";
124 dumpSet(bs);
125 outs() << "}\n";
126}
127
129{
130 outs() << "{";
131 for (PointsToList::const_iterator ii = ptl.begin(), ie = ptl.end();
132 ii != ie; ii++)
133 {
134 auto bs = *ii;
135 dumpSet(bs);
136 }
137 outs() << "}\n";
138}
139
143void SVFUtil::dumpAliasSet(unsigned node, NodeBS bs)
144{
145 outs() << "node " << node << " alias set: {";
146 dumpSet(bs);
147 outs() << "}\n";
148}
149
154{
155 for (NodeBS::iterator ii = bs.begin(), ie = bs.end();
156 ii != ie; ii++)
157 {
158 O << " " << *ii << " ";
159 }
160}
161
163{
164 for (NodeID n : pt)
165 {
166 o << " " << n << " ";
167 }
168}
169
173void SVFUtil::reportMemoryUsageKB(const std::string& infor, OutStream & O)
174{
177 O << infor << "\tVmRSS: " << vmrss << "\tVmSize: " << vmsize << "\n";
178}
179
184{
185 /* Get the current process' status file from the proc filesystem */
186 char buffer[8192];
187 FILE* procfile = fopen("/proc/self/status", "r");
188 if(procfile)
189 {
190 u32_t result = fread(buffer, sizeof(char), 8192, procfile);
191 if (result == 0)
192 {
193 fputs ("Reading error\n",stderr);
194 }
195 }
196 else
197 {
198 SVFUtil::writeWrnMsg(" /proc/self/status file not exit!");
199 return false;
200 }
202
203 /* Look through proc status contents line by line */
204 char delims[] = "\n";
205 char* line = strtok(buffer, delims);
206
207 bool found_vmrss = false;
208 bool found_vmsize = false;
209
210 while (line != nullptr && (found_vmrss == false || found_vmsize == false))
211 {
212 if (strstr(line, "VmRSS:") != nullptr)
213 {
214 sscanf(line, "%*s %u", vmrss_kb);
215 found_vmrss = true;
216 }
217
218 if (strstr(line, "VmSize:") != nullptr)
219 {
220 sscanf(line, "%*s %u", vmsize_kb);
221 found_vmsize = true;
222 }
223
224 line = strtok(nullptr, delims);
225 }
226
227 return (found_vmrss && found_vmsize);
228}
229
234{
235 const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb
236 struct rlimit rl;
238 if (result == 0)
239 {
240 if (rl.rlim_cur < kStackSize)
241 {
242 rl.rlim_cur = kStackSize;
244 if (result != 0)
245 writeWrnMsg("setrlimit returned result !=0 \n");
246 }
247 }
248}
249
250
251
253{
254 switch (method)
255 {
257 return "single";
259 return "complete";
261 return "average";
263 return "median";
265 return "svf-best";
266 default:
267 assert(false && "SVFUtil::hclustMethodToString: unknown method");
268 abort();
269 }
270}
271
273{
274 SVFUtil::outs().flush();
275 // TODO: output does not indicate which time limit is reached.
276 // This can be better in the future.
277 SVFUtil::outs() << "WPA: time limit reached\n";
278 exit(101);
279}
280
282{
283 if (timeLimit == 0) return false;
284
285 // If an alarm is already set, don't set another. That means this analysis
286 // is part of another which has a time limit.
287 unsigned remainingSeconds = alarm(0);
288 if (remainingSeconds != 0)
289 {
290 // Continue the previous alarm and move on.
292 return false;
293 }
294
297 return true;
298}
299
306
313{
314 if (callee->isVarArg() || ThreadAPI::getThreadAPI()->isTDFork(call))
315 return call->arg_size() >= callee->arg_size();
316 else
317 return call->arg_size() == callee->arg_size();
318}
319
321{
322 return SVFUtil::isa<CallICFGNode>(inst);
323}
324
326{
327 if (const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst))
328 {
329 const FunObjVar* func = call->getCalledFunction();
330 if (func && func->isIntrinsic())
331 {
332 return true;
333 }
334 }
335 return false;
336}
337
339{
340 return isExtCall(cs->getCalledFunction());
341}
342
347
348
350{
351 return getHeapAllocHoldingArgPosition(cs->getCalledFunction());
352}
353
354
356{
357 if(!isCallSite(node)) return false;
358 return isExtCall(cast<CallICFGNode>(node)->getCalledFunction());
359}
360
362{
363 if(!isCallSite(cs)) return false;
364 return isHeapAllocExtCallViaRet(cast<CallICFGNode>(cs)) || isHeapAllocExtCallViaArg(cast<CallICFGNode>(cs));
365}
366
372
374{
375 bool isPtrTy = cs->getType()->isPointerTy();
377}
378
379
381{
382 if (const auto& intraNode = dyn_cast<IntraICFGNode>(node))
383 return intraNode->isRetInst();
384 else
385 return false;
386}
387
389{
390 return fun && (fun->getName() == "exit" ||
391 fun->getName() == "__assert_rtn" ||
392 fun->getName() == "__assert_fail");
393}
394
399
402{
404 for (const auto& item: *svfirCallGraph)
405 {
406 const CallGraphNode*fun = item.second;
407 if (fun->getName()==funName)
408 return fun->getFunction();
409 }
410 return nullptr;
411}
412
415{
417 for (const auto& item: *svfirCallGraph)
418 {
419 const CallGraphNode*fun = item.second;
420 if (isProgEntryFunction(fun->getFunction()))
421 return (fun->getFunction());
422 }
423 return nullptr;
424}
425
427{
428 const ValVar* pVar = PAG::getPAG()->getBaseValVar(svfvar->getId());
429 if(const ArgValVar* arg = SVFUtil::dyn_cast<ArgValVar>(pVar))
430 return arg->isArgOfUncalledFunction();
431 else
432 return false;
433}
434
436{
437 assert(valVar->getInEdges().size() == 1);
438 return SVFUtil::dyn_cast<ObjVar>((*valVar->getInEdges().begin())->getSrcNode());
439}
440
442{
443 return fun && ExtAPI::getExtAPI()->is_ext(fun);
444}
445
447{
448 const char* main_name=Options::SVFMain() ? "svf.main" : "main";
449 return funObjVar && funObjVar->getName() == main_name;
450}
#define KNRM
Color for output format.
Definition SVFUtil.cpp:45
#define KPUR
Definition SVFUtil.cpp:50
#define KBLU
Definition SVFUtil.cpp:49
#define KRED
Definition SVFUtil.cpp:46
#define KYEL
Definition SVFUtil.cpp:48
#define KGRN
Definition SVFUtil.cpp:47
#define KCYA
Definition SVFUtil.cpp:51
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:48
const FunObjVar * getCalledFunction() const
Definition ICFGNode.h:500
u32_t arg_size() const
Definition ICFGNode.h:487
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:44
bool is_ext(const FunObjVar *funObjVar)
Definition ExtAPI.cpp:333
static const Option< bool > DisableWarn
Definition Options.h:199
static Option< bool > SVFMain
Definition Options.h:177
const CallGraph * getCallGraph()
Get CG.
Definition SVFIR.h:246
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:118
const ValVar * getBaseValVar(NodeID id) const
Definition SVFIR.h:506
bool isPointerTy() const
Definition SVFType.h:294
virtual const SVFType * getType() const
Definition SVFValue.h:172
virtual const std::string & getName() const
Definition SVFValue.h:187
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:98
char * strtok(char *str, const char *delim)
Definition extapi.c:456
char * strstr(const char *haystack, const char *needle)
Definition extapi.c:944
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:373
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition SVFUtil.cpp:59
void increaseStackSize()
Increase the stack size limit.
Definition SVFUtil.cpp:233
const ObjVar * getObjVarOfValVar(const ValVar *valVar)
Definition SVFUtil.cpp:435
std::string bugMsg1(const std::string &msg)
Definition SVFUtil.cpp:87
bool isProgEntryFunction(const FunObjVar *)
Program entry function e.g. main.
Definition SVFUtil.cpp:446
std::string hclustMethodToString(hclust_fast_methods method)
Returns a string representation of a hclust method.
Definition SVFUtil.cpp:252
void stopAnalysisLimitTimer(bool limitTimerSet)
Definition SVFUtil.cpp:302
bool isIntrinsicInst(const ICFGNode *inst)
Return true if it is an llvm intrinsic instruction.
Definition SVFUtil.cpp:325
u32_t getHeapAllocHoldingArgPosition(const FunObjVar *fun)
Get the position of argument that holds an allocated heap object.
Definition SVFUtil.h:293
const FunObjVar * getProgEntryFunction()
Get program entry function.
Definition SVFUtil.cpp:414
bool isHeapAllocExtFunViaRet(const FunObjVar *fun)
Return true if the call is a heap allocator/reallocator.
Definition SVFUtil.h:279
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:105
OrderedSet< PointsTo, equalPointsTo > PointsToList
Definition SVFUtil.h:168
void dumpAliasSet(unsigned node, NodeBS To)
Dump alias set.
Definition SVFUtil.cpp:143
bool isHeapAllocExtFunViaArg(const FunObjVar *fun)
Definition SVFUtil.h:285
bool getMemoryUsageKB(u32_t *vmrss_kb, u32_t *vmsize_kb)
Get memory usage from system file. Return TRUE if succeed.
Definition SVFUtil.cpp:183
void reportMemoryUsageKB(const std::string &infor, OutStream &O=SVFUtil::outs())
Print memory usage in KB.
Definition SVFUtil.cpp:173
bool startAnalysisLimitTimer(unsigned timeLimit)
Definition SVFUtil.cpp:281
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition SVFUtil.cpp:82
std::string bugMsg3(const std::string &msg)
Definition SVFUtil.cpp:97
bool isHeapAllocExtCallViaArg(const CallICFGNode *cs)
Definition SVFUtil.cpp:343
bool isHeapAllocExtCall(const ICFGNode *cs)
Definition SVFUtil.cpp:361
bool isArgOfUncalledFunction(const SVFVar *svfvar)
Definition SVFUtil.cpp:426
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:441
bool matchArgs(const CallICFGNode *cs, const FunObjVar *callee)
Definition SVFUtil.cpp:312
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:72
void dumpSparseSet(const NodeBS &To)
Definition SVFUtil.cpp:121
void dumpPointsToSet(unsigned node, NodeBS To)
Dump points-to set.
Definition SVFUtil.cpp:113
std::string bugMsg2(const std::string &msg)
Definition SVFUtil.cpp:92
bool isProgExitCall(const CallICFGNode *cs)
Definition SVFUtil.cpp:395
bool isCallSite(const ICFGNode *inst)
Definition SVFUtil.cpp:320
std::string wrnMsg(const std::string &msg)
Returns warning message by converting a string into yellow string output.
Definition SVFUtil.cpp:67
bool isReallocExtFun(const FunObjVar *fun)
Return true if the call is a heap reallocator.
Definition SVFUtil.h:301
bool isRetInstNode(const ICFGNode *node)
Definition SVFUtil.cpp:380
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
void timeLimitReached(int signum)
Function to call when alarm for time limit hits.
Definition SVFUtil.cpp:272
bool isHeapAllocExtCallViaRet(const CallICFGNode *cs)
interfaces to be used externally
Definition SVFUtil.cpp:367
void dumpSet(NodeBS To, OutStream &O=SVFUtil::outs())
Dump sparse bitvector set.
Definition SVFUtil.cpp:153
void dumpPointsToList(const PointsToList &ptl)
Definition SVFUtil.cpp:128
bool isProgExitFunction(const FunObjVar *fun)
Return true if this is a program exit function call.
Definition SVFUtil.cpp:388
const FunObjVar * getProgFunction(const std::string &funName)
Get program entry function from function name.
Definition SVFUtil.cpp:401
for isBitcode
Definition BasicTypes.h:70
u32_t NodeID
Definition GeneralType.h:56
std::ostream OutStream
Definition GeneralType.h:46
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:47