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 "Util/Options.h"
31#include "Util/SVFUtil.h"
33#include "Graphs/CallGraph.h"
34
35#include <sys/resource.h>
36
37using namespace SVF;
38
40#define KNRM "\x1B[1;0m"
41#define KRED "\x1B[1;31m"
42#define KGRN "\x1B[1;32m"
43#define KYEL "\x1B[1;33m"
44#define KBLU "\x1B[1;34m"
45#define KPUR "\x1B[1;35m"
46#define KCYA "\x1B[1;36m"
47#define KWHT "\x1B[1;37m"
48
49
50
54std::string SVFUtil::sucMsg(const std::string& msg)
55{
56 return KGRN + msg + KNRM;
57}
58
62std::string SVFUtil::wrnMsg(const std::string& msg)
63{
64 return KYEL + msg + KNRM;
65}
66
67void SVFUtil::writeWrnMsg(const std::string& msg)
68{
70 return;
71 outs() << wrnMsg(msg) << "\n";
72}
73
77std::string SVFUtil::errMsg(const std::string& msg)
78{
79 return KRED + msg + KNRM;
80}
81
82std::string SVFUtil::bugMsg1(const std::string& msg)
83{
84 return KYEL + msg + KNRM;
85}
86
87std::string SVFUtil::bugMsg2(const std::string& msg)
88{
89 return KPUR + msg + KNRM;
90}
91
92std::string SVFUtil::bugMsg3(const std::string& msg)
93{
94 return KCYA + msg + KNRM;
95}
96
100std::string SVFUtil::pasMsg(const std::string& msg)
101{
102 return KBLU + msg + KNRM;
103}
104
109{
110 outs() << "node " << node << " points-to: {";
111 dumpSet(bs);
112 outs() << "}\n";
113}
114
115// For use from the debugger.
117{
118 outs() << "{";
119 dumpSet(bs);
120 outs() << "}\n";
121}
122
124{
125 outs() << "{";
126 for (PointsToList::const_iterator ii = ptl.begin(), ie = ptl.end();
127 ii != ie; ii++)
128 {
129 auto bs = *ii;
130 dumpSet(bs);
131 }
132 outs() << "}\n";
133}
134
138void SVFUtil::dumpAliasSet(unsigned node, NodeBS bs)
139{
140 outs() << "node " << node << " alias set: {";
141 dumpSet(bs);
142 outs() << "}\n";
143}
144
149{
150 for (NodeBS::iterator ii = bs.begin(), ie = bs.end();
151 ii != ie; ii++)
152 {
153 O << " " << *ii << " ";
154 }
155}
156
158{
159 for (NodeID n : pt)
160 {
161 o << " " << n << " ";
162 }
163}
164
168void SVFUtil::reportMemoryUsageKB(const std::string& infor, OutStream & O)
169{
172 O << infor << "\tVmRSS: " << vmrss << "\tVmSize: " << vmsize << "\n";
173}
174
179{
180 /* Get the current process' status file from the proc filesystem */
181 char buffer[8192];
182 FILE* procfile = fopen("/proc/self/status", "r");
183 if(procfile)
184 {
185 u32_t result = fread(buffer, sizeof(char), 8192, procfile);
186 if (result == 0)
187 {
188 fputs ("Reading error\n",stderr);
189 }
190 }
191 else
192 {
193 SVFUtil::writeWrnMsg(" /proc/self/status file not exit!");
194 return false;
195 }
197
198 /* Look through proc status contents line by line */
199 char delims[] = "\n";
200 char* line = strtok(buffer, delims);
201
202 bool found_vmrss = false;
203 bool found_vmsize = false;
204
205 while (line != nullptr && (found_vmrss == false || found_vmsize == false))
206 {
207 if (strstr(line, "VmRSS:") != nullptr)
208 {
209 sscanf(line, "%*s %u", vmrss_kb);
210 found_vmrss = true;
211 }
212
213 if (strstr(line, "VmSize:") != nullptr)
214 {
215 sscanf(line, "%*s %u", vmsize_kb);
216 found_vmsize = true;
217 }
218
219 line = strtok(nullptr, delims);
220 }
221
222 return (found_vmrss && found_vmsize);
223}
224
229{
230 const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb
231 struct rlimit rl;
233 if (result == 0)
234 {
235 if (rl.rlim_cur < kStackSize)
236 {
237 rl.rlim_cur = kStackSize;
239 if (result != 0)
240 writeWrnMsg("setrlimit returned result !=0 \n");
241 }
242 }
243}
244
249{
250 if (const SVFCallInst* call = SVFUtil::dyn_cast<SVFCallInst>(inst))
251 {
252 const SVFFunction* func = call->getCalledFunction();
253 if (func && func->isIntrinsic())
254 {
255 return true;
256 }
257 }
258 return false;
259}
260
262{
263 switch (method)
264 {
266 return "single";
268 return "complete";
270 return "average";
272 return "median";
274 return "svf-best";
275 default:
276 assert(false && "SVFUtil::hclustMethodToString: unknown method");
277 abort();
278 }
279}
280
282{
283 SVFUtil::outs().flush();
284 // TODO: output does not indicate which time limit is reached.
285 // This can be better in the future.
286 SVFUtil::outs() << "WPA: time limit reached\n";
287 exit(101);
288}
289
291{
292 if (timeLimit == 0) return false;
293
294 // If an alarm is already set, don't set another. That means this analysis
295 // is part of another which has a time limit.
296 unsigned remainingSeconds = alarm(0);
297 if (remainingSeconds != 0)
298 {
299 // Continue the previous alarm and move on.
301 return false;
302 }
303
306 return true;
307}
308
315
322{
323 if (callee->isVarArg() || ThreadAPI::getThreadAPI()->isTDFork(call))
324 return call->arg_size() >= callee->arg_size();
325 else
326 return call->arg_size() == callee->arg_size();
327}
328
330{
331 return SVFUtil::isa<CallICFGNode>(inst);
332}
333
335{
336 if (const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst))
337 {
338 const SVFFunction* func = call->getCalledFunction();
339 if (func && func->isIntrinsic())
340 {
341 return true;
342 }
343 }
344 return false;
345}
346
348{
349 return isExtCall(cs->getCalledFunction());
350}
351
356
357
362
363
365{
366 if(!isCallSite(node)) return false;
367 return isExtCall(cast<CallICFGNode>(node)->getCalledFunction());
368}
369
371{
372 if(!isCallSite(cs)) return false;
373 return isHeapAllocExtCallViaRet(cast<CallICFGNode>(cs)) || isHeapAllocExtCallViaArg(cast<CallICFGNode>(cs));
374}
375
381
383{
384 bool isPtrTy = cs->getType()->isPointerTy();
386}
387
388
390{
391 if (const auto& intraNode = dyn_cast<IntraICFGNode>(node))
392 return intraNode->isRetInst();
393 else
394 return false;
395}
396
401
404{
406 for (const auto& item: *svfirCallGraph)
407 {
408 const CallGraphNode*fun = item.second;
409 if (fun->getName()==funName)
410 return fun->getFunction();
411 }
412 return nullptr;
413}
414
417{
419 for (const auto& item: *svfirCallGraph)
420 {
421 const CallGraphNode*fun = item.second;
422 if (isProgEntryFunction(fun->getFunction()))
423 return (fun->getFunction());
424 }
425 return nullptr;
426}
427
428
430{
431 assert(valVar->getInEdges().size() == 1);
432 return SVFUtil::dyn_cast<ObjVar>((*valVar->getInEdges().begin())->getSrcNode());
433}
#define KNRM
Color for output format.
Definition SVFUtil.cpp:40
#define KPUR
Definition SVFUtil.cpp:45
#define KBLU
Definition SVFUtil.cpp:44
#define KRED
Definition SVFUtil.cpp:41
#define KYEL
Definition SVFUtil.cpp:43
#define KGRN
Definition SVFUtil.cpp:42
#define KCYA
Definition SVFUtil.cpp:46
cJSON * n
Definition cJSON.cpp:2558
char * buffer
Definition cJSON.h:163
cJSON * item
Definition cJSON.h:222
const std::string & getName() const
Definition CallGraph.h:125
const SVFFunction * getFunction() const
Get function of this call node.
Definition CallGraph.h:131
const SVFFunction * getCalledFunction() const
Definition ICFGNode.h:518
u32_t arg_size() const
Definition ICFGNode.h:505
static const Option< bool > DisableWarn
Definition Options.h:205
virtual const SVFType * getType() const
bool isIntrinsic() const
Definition SVFValue.h:382
CallGraph * getCallGraph()
Definition SVFIR.h:193
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:116
bool isPointerTy() const
Definition SVFType.h:249
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:107
char * strtok(char *str, const char *delim)
Definition extapi.c:463
char * strstr(const char *haystack, const char *needle)
Definition extapi.c:821
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:382
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition SVFUtil.cpp:54
void increaseStackSize()
Increase the stack size limit.
Definition SVFUtil.cpp:228
const ObjVar * getObjVarOfValVar(const ValVar *valVar)
Definition SVFUtil.cpp:429
std::string bugMsg1(const std::string &msg)
Definition SVFUtil.cpp:82
std::string hclustMethodToString(hclust_fast_methods method)
Returns a string representation of a hclust method.
Definition SVFUtil.cpp:261
void stopAnalysisLimitTimer(bool limitTimerSet)
Definition SVFUtil.cpp:311
bool isHeapAllocExtFunViaRet(const SVFFunction *fun)
Return true if the call is a heap allocator/reallocator.
Definition SVFUtil.h:296
bool isExtCall(const SVFFunction *fun)
Definition SVFUtil.h:278
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:100
OrderedSet< PointsTo, equalPointsTo > PointsToList
Definition SVFUtil.h:166
void dumpAliasSet(unsigned node, NodeBS To)
Dump alias set.
Definition SVFUtil.cpp:138
bool getMemoryUsageKB(u32_t *vmrss_kb, u32_t *vmsize_kb)
Get memory usage from system file. Return TRUE if succeed.
Definition SVFUtil.cpp:178
void reportMemoryUsageKB(const std::string &infor, OutStream &O=SVFUtil::outs())
Print memory usage in KB.
Definition SVFUtil.cpp:168
bool startAnalysisLimitTimer(unsigned timeLimit)
Definition SVFUtil.cpp:290
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition SVFUtil.cpp:77
std::string bugMsg3(const std::string &msg)
Definition SVFUtil.cpp:92
bool isHeapAllocExtCallViaArg(const CallICFGNode *cs)
Definition SVFUtil.cpp:352
bool isHeapAllocExtCall(const ICFGNode *cs)
Definition SVFUtil.cpp:370
u32_t getHeapAllocHoldingArgPosition(const SVFFunction *fun)
Get the position of argument that holds an allocated heap object.
Definition SVFUtil.h:309
bool isCallSite(const SVFValue *val)
Whether an instruction is a call or invoke instruction.
Definition SVFUtil.h:175
bool isReallocExtFun(const SVFFunction *fun)
Return true if the call is a heap reallocator.
Definition SVFUtil.h:317
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:67
void dumpSparseSet(const NodeBS &To)
Definition SVFUtil.cpp:116
bool isHeapAllocExtFunViaArg(const SVFFunction *fun)
Definition SVFUtil.h:302
bool isIntrinsicInst(const SVFInstruction *inst)
Return true if it is an llvm intrinsic instruction.
Definition SVFUtil.cpp:248
void dumpPointsToSet(unsigned node, NodeBS To)
Dump points-to set.
Definition SVFUtil.cpp:108
std::string bugMsg2(const std::string &msg)
Definition SVFUtil.cpp:87
bool isProgExitCall(const CallICFGNode *cs)
Definition SVFUtil.cpp:397
std::string wrnMsg(const std::string &msg)
Returns warning message by converting a string into yellow string output.
Definition SVFUtil.cpp:62
bool isRetInstNode(const ICFGNode *node)
Definition SVFUtil.cpp:389
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
bool matchArgs(const CallICFGNode *cs, const SVFFunction *callee)
Definition SVFUtil.cpp:321
void timeLimitReached(int signum)
Function to call when alarm for time limit hits.
Definition SVFUtil.cpp:281
const SVFFunction * getProgFunction(const std::string &funName)
Get program entry function from function name.
Definition SVFUtil.cpp:403
bool isHeapAllocExtCallViaRet(const CallICFGNode *cs)
interfaces to be used externally
Definition SVFUtil.cpp:376
void dumpSet(NodeBS To, OutStream &O=SVFUtil::outs())
Dump sparse bitvector set.
Definition SVFUtil.cpp:148
bool isProgExitFunction(const SVFFunction *fun)
Return true if this is a program exit function call.
Definition SVFUtil.h:338
const SVFFunction * getProgEntryFunction()
Get program entry function.
Definition SVFUtil.cpp:416
void dumpPointsToList(const PointsToList &ptl)
Definition SVFUtil.cpp:123
for isBitcode
Definition BasicTypes.h:68
u32_t NodeID
Definition GeneralType.h:55
std::ostream OutStream
Definition GeneralType.h:45
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned u32_t
Definition GeneralType.h:46