Static Value-Flow Analysis
Loading...
Searching...
No Matches
AbsExtAPI.cpp
Go to the documentation of this file.
1//===- AbsExtAPI.cpp -- Abstract Interpretation External API handler-----//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <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//
25// Created on: Sep 9, 2024
26// Author: Xiao Cheng, Jiawei Wang
27//
28//
29#include "AE/Svfexe/AbsExtAPI.h"
31#include "WPA/Andersen.h"
32#include "Util/Options.h"
33
34using namespace SVF;
41
43{
44#define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \
45 auto sse_##FUNC_NAME = [this](const CallICFGNode *callNode) { \
46 /* run real ext function */ \
47 const SVFVar* argVar = callNode->getArgument(0); \
48 const AbstractValue& argVal = ae->getAbsValue(argVar, callNode); \
49 if (!argVal.isInterval() && !argVal.isAddr()) return; \
50 u32_t rhs = argVal.getInterval().lb().getIntNumeral(); \
51 s32_t res = FUNC_NAME(rhs); \
52 const SVFVar* retVar = callNode->getRetICFGNode()->getActualRet(); \
53 ae->updateAbsValue(retVar, IntervalValue(res), callNode); \
54 return; \
55 }; \
56 func_map[#FUNC_NAME] = sse_##FUNC_NAME;
57
69 SSE_FUNC_PROCESS(llvm.sin.f64, sin);
70 SSE_FUNC_PROCESS(llvm.cos.f64, cos);
71 SSE_FUNC_PROCESS(llvm.tan.f64, tan);
72 SSE_FUNC_PROCESS(llvm.log.f64, log);
76
77 auto sse_svf_assert = [this](const CallICFGNode* callNode)
78 {
79 checkpoints.erase(callNode);
80 const AbstractValue& arg0Val = ae->getAbsValue(callNode->getArgument(0), callNode);
81 if (arg0Val.getInterval().equals(IntervalValue(1, 1)))
82 {
83 SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
84 }
85 else
86 {
87 SVFUtil::errs() << SVFUtil::errMsg("Assertion failure, this svf_assert cannot be verified!!\n") << callNode->toString() << "\n";
88 assert(false);
89 }
90 return;
91 };
92 func_map["svf_assert"] = sse_svf_assert;
93
94 auto svf_assert_eq = [this](const CallICFGNode* callNode)
95 {
96 const AbstractValue& arg0Val = ae->getAbsValue(callNode->getArgument(0), callNode);
97 const AbstractValue& arg1Val = ae->getAbsValue(callNode->getArgument(1), callNode);
98 if (arg0Val.getInterval().equals(arg1Val.getInterval()))
99 {
100 SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
101 }
102 else
103 {
104 SVFUtil::errs() <<"svf_assert_eq Fail. " << callNode->toString() << "\n";
105 assert(false);
106 }
107 return;
108 };
109 func_map["svf_assert_eq"] = svf_assert_eq;
110
111 auto svf_print = [&](const CallICFGNode* callNode)
112 {
113 if (callNode->arg_size() < 2) return;
114 std::string text = strRead(callNode->getArgument(1), callNode);
116 std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
117 << ", PrintVal: " << itv.toString() << ", Loc:" << callNode->getSourceLoc() << std::endl;
118 return;
119 };
120 func_map["svf_print"] = svf_print;
121
122 auto svf_set_value = [&](const CallICFGNode* callNode)
123 {
124 if (callNode->arg_size() < 2) return;
126 const AbstractValue& lbVal = ae->getAbsValue(callNode->getArgument(1), callNode);
127 const AbstractValue& ubVal = ae->getAbsValue(callNode->getArgument(2), callNode);
128 assert(lbVal.getInterval().is_numeral() && ubVal.getInterval().is_numeral());
131 num.getInterval().meet_with(IntervalValue(lbVal.getInterval().lb(), ubVal.getInterval().ub()));
132 ae->updateAbsValue(callNode->getArgument(0), num, callNode);
133 const ICFGNode* node = SVFUtil::cast<ValVar>(callNode->getArgument(0))->getICFGNode();
134 for (const SVFStmt* stmt: node->getSVFStmts())
135 {
136 if (SVFUtil::isa<LoadStmt>(stmt))
137 {
138 const LoadStmt* load = SVFUtil::cast<LoadStmt>(stmt);
140 for (auto addr : ptrVal.getAddrs())
141 as.store(addr, num);
142 }
143 }
144 return;
145 };
146 func_map["set_value"] = svf_set_value;
147
148 auto sse_fread = [&](const CallICFGNode *callNode)
149 {
150 if (callNode->arg_size() < 3) return;
151 IntervalValue block_count = ae->getAbsValue(callNode->getArgument(2), callNode).getInterval();
152 IntervalValue block_size = ae->getAbsValue(callNode->getArgument(1), callNode).getInterval();
154 (void)block_byte;
155 };
156 func_map["fread"] = sse_fread;
157
158 auto sse_sprintf = [&](const CallICFGNode *callNode)
159 {
160 // printf is difficult to predict since it has no byte size arguments
161 };
162
163 auto sse_snprintf = [&](const CallICFGNode *callNode)
164 {
165 if (callNode->arg_size() < 2) return;
166 // get elem size of arg2
167 u32_t elemSize = 1;
168 if (callNode->getArgument(2)->getType()->isArrayTy())
169 {
170 elemSize = SVFUtil::dyn_cast<SVFArrayType>(
171 callNode->getArgument(2)->getType())->getTypeOfElement()->getByteSize();
172 }
173 else if (callNode->getArgument(2)->getType()->isPointerTy())
174 {
175 elemSize = 1;
176 }
177 else
178 {
179 return;
180 }
181 IntervalValue size = ae->getAbsValue(callNode->getArgument(1), callNode).getInterval()
183 (void)size;
184 };
185 func_map["__snprintf_chk"] = sse_snprintf;
186 func_map["__vsprintf_chk"] = sse_sprintf;
187 func_map["__sprintf_chk"] = sse_sprintf;
188 func_map["snprintf"] = sse_snprintf;
189 func_map["sprintf"] = sse_sprintf;
190 func_map["vsprintf"] = sse_sprintf;
191 func_map["vsnprintf"] = sse_snprintf;
192 func_map["__vsnprintf_chk"] = sse_snprintf;
193 func_map["swprintf"] = sse_snprintf;
194 func_map["_snwprintf"] = sse_snprintf;
195
196
197 auto sse_itoa = [&](const CallICFGNode* callNode)
198 {
199 if (callNode->arg_size() < 3) return;
200 u32_t num = (u32_t) ae->getAbsValue(callNode->getArgument(0), callNode).getInterval().getNumeral();
201 std::string snum = std::to_string(num);
202 (void)snum;
203 };
204 func_map["itoa"] = sse_itoa;
205
206
207 auto sse_strlen = [&](const CallICFGNode *callNode)
208 {
209 if (callNode->arg_size() < 1) return;
210 const SVFVar* retVar = callNode->getRetICFGNode()->getActualRet();
211 IntervalValue byteLen = getStrlen(callNode->getArgument(0), callNode);
212 u32_t elemSize = getElementSize(callNode->getArgument(0));
213 if (byteLen.is_numeral() && elemSize > 1)
215 else
217 };
218 func_map["strlen"] = sse_strlen;
219 func_map["wcslen"] = sse_strlen;
220
221 auto sse_recv = [&](const CallICFGNode *callNode)
222 {
223 if (callNode->arg_size() < 4) return;
224 IntervalValue len = ae->getAbsValue(callNode->getArgument(2), callNode).getInterval() - IntervalValue(1);
225 const SVFVar* retVar = callNode->getRetICFGNode()->getActualRet();
227 };
228 func_map["recv"] = sse_recv;
229 func_map["__recv"] = sse_recv;
230
231 auto sse_free = [&](const CallICFGNode *callNode)
232 {
233 if (callNode->arg_size() < 1) return;
235 const AbstractValue& ptrVal = ae->getAbsValue(callNode->getArgument(0), callNode);
236 for (auto addr: ptrVal.getAddrs())
237 {
239 {
240 }
241 else
242 {
243 as.addToFreedAddrs(addr);
244 }
245 }
246 };
247 // Add all free-related functions to func_map
248 std::vector<std::string> freeFunctions =
249 {
250 "VOS_MemFree", "cfree", "free", "free_all_mem", "freeaddrinfo",
251 "gcry_mpi_release", "gcry_sexp_release", "globfree", "nhfree",
252 "obstack_free", "safe_cfree", "safe_free", "safefree", "safexfree",
253 "sm_free", "vim_free", "xfree", "SSL_CTX_free", "SSL_free", "XFree"
254 };
255
256 for (const auto& name : freeFunctions)
257 {
259 }
260};
261
263{
264 return ae->getAbsState(node);
265}
266
268{
269 // traverse every ICFGNode
270 Set<std::string> ae_checkpoint_names = {"svf_assert"};
271 Set<std::string> buf_checkpoint_names = {"UNSAFE_BUFACCESS", "SAFE_BUFACCESS"};
272 Set<std::string> nullptr_checkpoint_names = {"UNSAFE_LOAD", "SAFE_LOAD"};
273
274 for (auto it = svfir->getICFG()->begin(); it != svfir->getICFG()->end(); ++it)
275 {
276 const ICFGNode* node = it->second;
277 if (const CallICFGNode *call = SVFUtil::dyn_cast<CallICFGNode>(node))
278 {
279 if (const FunObjVar *fun = call->getCalledFunction())
280 {
281 if (ae_checkpoint_names.find(fun->getName()) !=
283 {
284 checkpoints.insert(call);
285 }
287 {
288 if (buf_checkpoint_names.find(fun->getName()) !=
290 {
291 checkpoints.insert(call);
292 }
293 }
295 {
296 if (nullptr_checkpoint_names.find(fun->getName()) !=
298 {
299 checkpoints.insert(call);
300 }
301 }
302 }
303 }
304 }
305}
306
308{
309 if (checkpoints.size() == 0)
310 {
311 return;
312 }
313 else
314 {
315 SVFUtil::errs() << SVFUtil::errMsg("At least one svf_assert has not been checked!!") << "\n";
316 for (const CallICFGNode* call: checkpoints)
317 SVFUtil::errs() << call->toString() + "\n";
318 assert(false);
319 }
320}
321
322std::string AbsExtAPI::strRead(const ValVar* rhs, const ICFGNode* node)
323{
325 std::string str0;
326
328 {
329 if (!ae->getAbsValue(rhs, node).isAddr()) continue;
332
334 for (const auto &addr: expr0.getAddrs())
335 {
336 val.join_with(as.load(addr));
337 }
338 if (!val.getInterval().is_numeral())
339 {
340 break;
341 }
342 if ((char) val.getInterval().getIntNumeral() == '\0')
343 {
344 break;
345 }
346 str0.push_back((char) val.getInterval().getIntNumeral());
347 }
348 return str0;
349}
350
352{
353 const FunObjVar *fun = call->getCalledFunction();
354 assert(fun && "FunObjVar* is nullptr");
356 // get type of mem api
357 for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(fun))
358 {
359 if (annotation.find("MEMCPY") != std::string::npos)
360 extType = MEMCPY;
361 if (annotation.find("MEMSET") != std::string::npos)
362 extType = MEMSET;
363 if (annotation.find("STRCPY") != std::string::npos)
364 extType = STRCPY;
365 if (annotation.find("STRCAT") != std::string::npos)
366 extType = STRCAT;
367 }
368 if (extType == UNCLASSIFIED)
369 {
370 if (func_map.find(fun->getName()) != func_map.end())
371 {
372 func_map[fun->getName()](call);
373 }
374 else
375 {
376 if (const SVFVar* ret = call->getRetICFGNode()->getActualRet())
377 {
378 const AbstractValue& retVal = ae->getAbsValue(ret, call);
379 if (!retVal.isAddr())
380 {
381 ae->updateAbsValue(ret, IntervalValue(), call);
382 }
383 }
384 return;
385 }
386 }
387 // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
388 else if (extType == MEMCPY)
389 {
390 IntervalValue len = ae->getAbsValue(call->getArgument(2), call).getInterval();
391 handleMemcpy(call->getArgument(0), call->getArgument(1), len, 0, call);
392 }
393 else if (extType == MEMSET)
394 {
397 handleMemset(call->getArgument(0), elem, len, call);
398 }
399 else if (extType == STRCPY)
400 {
401 handleStrcpy(call);
402 }
403 else if (extType == STRCAT)
404 {
405 // Both strcat and strncat are annotated as STRCAT.
406 // Distinguish by name: strncat/wcsncat contain "ncat".
407 const std::string& name = fun->getName();
408 if (name.find("ncat") != std::string::npos)
409 handleStrncat(call);
410 else
411 handleStrcat(call);
412 }
413 else
414 {
415
416 }
417 return;
418}
419
420// ===----------------------------------------------------------------------===//
421// Shared primitives for string/memory handlers
422// ===----------------------------------------------------------------------===//
423
427{
428 if (var->getType()->isArrayTy())
429 {
430 return SVFUtil::dyn_cast<SVFArrayType>(var->getType())
431 ->getTypeOfElement()->getByteSize();
432 }
433 if (var->getType()->isPointerTy())
434 return 1;
435 assert(false && "unsupported type for element size");
436 return 1;
437}
438
443{
444 return !len.isBottom() && !len.lb().is_minus_infinity();
445}
446
451{
453 // Step 1: determine the buffer size (in bytes) backing this pointer
454 u32_t dst_size = 0;
455 const AbstractValue& ptrVal = ae->getAbsValue(strValue, node);
456 for (const auto& addr : ptrVal.getAddrs())
457 {
458 NodeID objId = as.getIDFromAddr(addr);
460 {
462 }
463 else
464 {
465 const ICFGNode* icfgNode = svfir->getBaseObject(objId)->getICFGNode();
466 for (const SVFStmt* stmt2: icfgNode->getSVFStmts())
467 {
468 if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
469 {
471 }
472 }
473 }
474 }
475
476 // Step 2: scan for '\0' terminator
477 u32_t len = 0;
478 if (ae->getAbsValue(strValue, node).isAddr())
479 {
480 for (u32_t index = 0; index < dst_size; index++)
481 {
485 for (const auto &addr: expr0.getAddrs())
486 {
487 val.join_with(as.load(addr));
488 }
489 if (val.getInterval().is_numeral() &&
490 (char) val.getInterval().getIntNumeral() == '\0')
491 {
492 break;
493 }
494 ++len;
495 }
496 }
497
498 // Step 3: scale by element size and return
500 if (len == 0)
502 return IntervalValue(len * elemSize);
503}
504
505// ===----------------------------------------------------------------------===//
506// String/memory operation handlers
507// ===----------------------------------------------------------------------===//
508
512{
513 const ValVar* dst = call->getArgument(0);
514 const ValVar* src = call->getArgument(1);
515 IntervalValue srcLen = getStrlen(src, call);
516 if (!isValidLength(srcLen)) return;
517 handleMemcpy(dst, src, srcLen, 0, call);
518}
519
523{
524 const ValVar* dst = call->getArgument(0);
525 const ValVar* src = call->getArgument(1);
526 IntervalValue dstLen = getStrlen(dst, call);
527 IntervalValue srcLen = getStrlen(src, call);
528 if (!isValidLength(dstLen)) return;
529 handleMemcpy(dst, src, srcLen, dstLen.lb().getIntNumeral(), call);
530}
531
535{
536 const ValVar* dst = call->getArgument(0);
537 const ValVar* src = call->getArgument(1);
539 IntervalValue dstLen = getStrlen(dst, call);
540 if (!isValidLength(dstLen)) return;
541 handleMemcpy(dst, src, n, dstLen.lb().getIntNumeral(), call);
542}
543
546 const ValVar *src, const IntervalValue& len,
547 u32_t start_idx, const ICFGNode* node)
548{
549 if (!isValidLength(len)) return;
551
553 u32_t size = std::min((u32_t)Options::MaxFieldLimit(),
554 (u32_t)len.lb().getIntNumeral());
555 u32_t range_val = size / elemSize;
556
557 if (!ae->getAbsValue(src, node).isAddr() || !ae->getAbsValue(dst, node).isAddr())
558 return;
559
560 for (u32_t index = 0; index < range_val; index++)
561 {
566 for (const auto &dstAddr: expr_dst.getAddrs())
567 {
568 for (const auto &srcAddr: expr_src.getAddrs())
569 {
570 u32_t objId = as.getIDFromAddr(srcAddr);
571 if (as.inAddrToValTable(objId) || as.inAddrToAddrsTable(objId))
572 {
573 as.store(dstAddr, as.load(srcAddr));
574 }
575 }
576 }
577 }
578}
579
586 const IntervalValue& elem, const IntervalValue& len, const ICFGNode* node)
587{
588 if (!isValidLength(len)) return;
590
591 u32_t elemSize = 1;
592 if (dst->getType()->isArrayTy())
593 {
594 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())
595 ->getTypeOfElement()->getByteSize();
596 }
597 else if (dst->getType()->isPointerTy())
598 {
599 elemSize = 1;
600 }
601 else
602 {
603 assert(false && "unsupported type for element size");
604 }
605 u32_t size = std::min((u32_t)Options::MaxFieldLimit(),
606 (u32_t)len.lb().getIntNumeral());
607 u32_t range_val = size / elemSize;
608
609 for (u32_t index = 0; index < range_val; index++)
610 {
611 if (!ae->getAbsValue(dst, node).isAddr())
612 break;
614 for (const auto &addr: lhs_gep.getAddrs())
615 {
616 u32_t objId = as.getIDFromAddr(addr);
617 if (as.inAddrToValTable(objId))
618 {
619 AbstractValue tmp = as.load(addr);
621 as.store(addr, tmp);
622 }
623 else
624 {
625 as.store(addr, elem);
626 }
627 }
628 }
629}
630
643{
644 if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
645 {
646 u32_t bits = type->getByteSize() * 8;
647 s64_t ub = 0;
648 s64_t lb = 0;
649 if (bits >= 32)
650 {
651 if (intType->isSigned())
652 {
653 ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
654 lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
655 }
656 else
657 {
658 ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
659 lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
660 }
661 }
662 else if (bits == 16)
663 {
664 if (intType->isSigned())
665 {
666 ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
667 lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
668 }
669 else
670 {
671 ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
672 lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
673 }
674 }
675 else if (bits == 8)
676 {
677 if (intType->isSigned())
678 {
679 ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
680 lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
681 }
682 else
683 {
684 ub = static_cast<s64_t>(std::numeric_limits<uint8_t>::max());
685 lb = static_cast<s64_t>(std::numeric_limits<uint8_t>::min());
686 }
687 }
688 return IntervalValue(lb, ub);
689 }
690 else if (SVFUtil::isa<SVFOtherType>(type))
691 {
692 // handle other type like float double, set s32_t as the range
693 s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
694 s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
695 return IntervalValue(lb, ub);
696 }
697 else
698 {
699 return IntervalValue::top();
700 // other types, return top interval
701 }
702}
#define SSE_FUNC_PROCESS(LLVM_NAME,FUNC_NAME)
newitem type
Definition cJSON.cpp:2739
cJSON * n
Definition cJSON.cpp:2558
const char *const name
Definition cJSON.h:264
int index
Definition cJSON.h:170
AbstractInterpretation * ae
Owning AbstractInterpretation; provides state access.
Definition AbsExtAPI.h:116
AbstractState & getAbsState(const ICFGNode *node)
Retrieves the abstract state from the trace for a given ICFG node.
void collectCheckPoint()
void initExtFunMap()
Initializes the external function map.
Definition AbsExtAPI.cpp:42
IntervalValue getStrlen(const ValVar *strValue, const ICFGNode *node)
Calculate the length of a null-terminated string in abstract state.
void handleMemcpy(const ValVar *dst, const ValVar *src, const IntervalValue &len, u32_t start_idx, const ICFGNode *node)
Core memcpy: copy len bytes from src to dst starting at dst[start_idx].
void handleExtAPI(const CallICFGNode *call)
Handles an external API call.
void handleStrncat(const CallICFGNode *call)
static bool isValidLength(const IntervalValue &len)
Check if an interval length is usable (not bottom, not unbounded).
Set< const CallICFGNode * > checkpoints
Definition AbsExtAPI.h:113
void checkPointAllSet()
std::string strRead(const ValVar *rhs, const ICFGNode *node)
Reads a string from the abstract state.
u32_t getElementSize(const ValVar *var)
Get the byte size of each element for a pointer/array variable.
void handleMemset(const ValVar *dst, const IntervalValue &elem, const IntervalValue &len, const ICFGNode *node)
AbsExtAPI(AbstractInterpretation *ae)
Constructor for AbsExtAPI.
Definition AbsExtAPI.cpp:35
SVFIR * svfir
Pointer to the SVF intermediate representation.
Definition AbsExtAPI.h:117
ExtAPIType
Enumeration of external API types.
Definition AbsExtAPI.h:49
IntervalValue getRangeLimitFromType(const SVFType *type)
Gets the range limit from a type.
ICFG * icfg
Pointer to the interprocedural control flow graph.
Definition AbsExtAPI.h:118
void handleStrcat(const CallICFGNode *call)
void handleStrcpy(const CallICFGNode *call)
Map< std::string, std::function< void(const CallICFGNode *)> > func_map
Map of function names to handlers.
Definition AbsExtAPI.h:119
AbstractState & getAbsState(const ICFGNode *node)
u32_t getAllocaInstByteSize(const AddrStmt *addr)
AddressValue getGepObjAddrs(const ValVar *pointer, IntervalValue offset)
virtual const AbstractValue & getAbsValue(const ValVar *var, const ICFGNode *node)
virtual void updateAbsValue(const ValVar *var, const AbstractValue &val, const ICFGNode *node)
static bool isBlackHoleObjAddr(u32_t addr)
void join_with(const AbstractValue &other)
IntervalValue & getInterval()
bool isAddr() const
const ICFGNode * getICFGNode() const
Get the ICFGNode related to the creation of this object.
bool isConstantByteSize() const
Check if byte size is a const value.
u32_t getByteSizeOfObj() const
Get the byte size of this object.
const ValVar * getArgument(u32_t ArgNo) const
Parameter operations.
Definition ICFGNode.h:482
const FunObjVar * getCalledFunction() const
Definition ICFGNode.h:500
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:439
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:44
const std::vector< std::string > & getExtFuncAnnotations(const FunObjVar *fun)
Definition ExtAPI.cpp:256
iterator begin()
Iterators.
virtual const std::string toString() const
Definition ICFG.cpp:49
const SVFStmtList & getSVFStmts() const
Definition ICFGNode.h:115
const std::string toString() const
void set_to_top()
Set current IntervalValue as top.
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
const ValVar * getRHSVar() const
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:35
static const Option< bool > NullDerefCheck
nullptr dereference checker, Default: false
Definition Options.h:255
static const Option< bool > BufferOverflowCheck
buffer overflow checker, Default: false
Definition Options.h:253
const SVFVar * getActualRet() const
Return actual return parameter.
Definition ICFGNode.h:624
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:496
ICFG * getICFG() const
Definition SVFIR.h:229
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:118
bool isArrayTy() const
Definition SVFType.h:299
bool isPointerTy() const
Definition SVFType.h:294
virtual const SVFType * getType() const
Definition SVFValue.h:174
virtual const std::string & getName() const
Definition SVFValue.h:189
int iscntrl(int c)
Definition extapi.c:969
int isdigit(int c)
Definition extapi.c:974
int isgraph(int c)
Definition extapi.c:979
int isspace(char c)
Definition extapi.c:999
int isprint(int c)
Definition extapi.c:989
int ispunct(int argument)
Definition extapi.c:994
int isblank(int character)
Definition extapi.c:964
int isalnum(int character)
Definition extapi.c:954
int isupper(int c)
Definition extapi.c:1004
int isxdigit(int c)
Definition extapi.c:1009
int isalpha(int character)
Definition extapi.c:959
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition SVFUtil.cpp:55
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition SVFUtil.cpp:78
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:58
for isBitcode
Definition BasicTypes.h:70
u32_t NodeID
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:47
signed long long s64_t
Definition GeneralType.h:50