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 = mgr->getAbstractValue(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 mgr->updateAbstractValue(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 = mgr->getAbstractValue(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 = mgr->getAbstractValue(callNode->getArgument(0), callNode);
97 const AbstractValue& arg1Val = mgr->getAbstractValue(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 = mgr->getAbstractValue(callNode->getArgument(1), callNode);
127 const AbstractValue& ubVal = mgr->getAbstractValue(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 mgr->updateAbstractValue(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_scanf = [&](const CallICFGNode* callNode)
149 {
150 //scanf("%d", &data);
151 if (callNode->arg_size() < 2) return;
153 const AbstractValue& dstVal = mgr->getAbstractValue(callNode->getArgument(1), callNode);
154 if (!dstVal.isAddr()) return;
155 for (auto vaddr: dstVal.getAddrs())
156 {
157 u32_t objId = as.getIDFromAddr(vaddr);
159 as.store(vaddr, range);
160 }
161 };
162 auto sse_fscanf = [&](const CallICFGNode* callNode)
163 {
164 //fscanf(stdin, "%d", &data);
165 if (callNode->arg_size() < 3) return;
167 const AbstractValue& dstVal = mgr->getAbstractValue(callNode->getArgument(2), callNode);
168 if (!dstVal.isAddr()) return;
169 for (auto vaddr: dstVal.getAddrs())
170 {
171 u32_t objId = as.getIDFromAddr(vaddr);
173 as.store(vaddr, range);
174 }
175 };
176
177 func_map["__isoc99_fscanf"] = sse_fscanf;
178 func_map["__isoc99_scanf"] = sse_scanf;
179 func_map["__isoc99_vscanf"] = sse_scanf;
180 func_map["fscanf"] = sse_fscanf;
181 func_map["scanf"] = sse_scanf;
182 func_map["sscanf"] = sse_scanf;
183 func_map["__isoc99_sscanf"] = sse_scanf;
184 func_map["vscanf"] = sse_scanf;
185
186 auto sse_fread = [&](const CallICFGNode *callNode)
187 {
188 if (callNode->arg_size() < 3) return;
189 IntervalValue block_count = mgr->getAbstractValue(callNode->getArgument(2), callNode).getInterval();
190 IntervalValue block_size = mgr->getAbstractValue(callNode->getArgument(1), callNode).getInterval();
192 (void)block_byte;
193 };
194 func_map["fread"] = sse_fread;
195
196 auto sse_sprintf = [&](const CallICFGNode *callNode)
197 {
198 // printf is difficult to predict since it has no byte size arguments
199 };
200
201 auto sse_snprintf = [&](const CallICFGNode *callNode)
202 {
203 if (callNode->arg_size() < 2) return;
204 // get elem size of arg2
205 u32_t elemSize = 1;
206 if (callNode->getArgument(2)->getType()->isArrayTy())
207 {
208 elemSize = SVFUtil::dyn_cast<SVFArrayType>(
209 callNode->getArgument(2)->getType())->getTypeOfElement()->getByteSize();
210 }
211 else if (callNode->getArgument(2)->getType()->isPointerTy())
212 {
213 elemSize = 1;
214 }
215 else
216 {
217 return;
218 }
221 (void)size;
222 };
223 func_map["__snprintf_chk"] = sse_snprintf;
224 func_map["__vsprintf_chk"] = sse_sprintf;
225 func_map["__sprintf_chk"] = sse_sprintf;
226 func_map["snprintf"] = sse_snprintf;
227 func_map["sprintf"] = sse_sprintf;
228 func_map["vsprintf"] = sse_sprintf;
229 func_map["vsnprintf"] = sse_snprintf;
230 func_map["__vsnprintf_chk"] = sse_snprintf;
231 func_map["swprintf"] = sse_snprintf;
232 func_map["_snwprintf"] = sse_snprintf;
233
234
235 auto sse_itoa = [&](const CallICFGNode* callNode)
236 {
237 if (callNode->arg_size() < 3) return;
238 u32_t num = (u32_t) mgr->getAbstractValue(callNode->getArgument(0), callNode).getInterval().getNumeral();
239 std::string snum = std::to_string(num);
240 (void)snum;
241 };
242 func_map["itoa"] = sse_itoa;
243
244
245 auto sse_strlen = [&](const CallICFGNode *callNode)
246 {
247 if (callNode->arg_size() < 1) return;
248 const SVFVar* retVar = callNode->getRetICFGNode()->getActualRet();
249 IntervalValue byteLen = getStrlen(callNode->getArgument(0), callNode);
250 u32_t elemSize = getElementSize(callNode->getArgument(0));
251 if (byteLen.is_numeral() && elemSize > 1)
253 else
255 };
256 func_map["strlen"] = sse_strlen;
257 func_map["wcslen"] = sse_strlen;
258
259 auto sse_recv = [&](const CallICFGNode *callNode)
260 {
261 if (callNode->arg_size() < 4) return;
262 IntervalValue len = mgr->getAbstractValue(callNode->getArgument(2), callNode).getInterval() - IntervalValue(1);
263 const SVFVar* retVar = callNode->getRetICFGNode()->getActualRet();
265 };
266 func_map["recv"] = sse_recv;
267 func_map["__recv"] = sse_recv;
268
269 auto sse_free = [&](const CallICFGNode *callNode)
270 {
271 if (callNode->arg_size() < 1) return;
273 const AbstractValue& ptrVal = mgr->getAbstractValue(callNode->getArgument(0), callNode);
274 for (auto addr: ptrVal.getAddrs())
275 {
277 {
278 }
279 else
280 {
281 as.addToFreedAddrs(addr);
282 }
283 }
284 };
285 // Add all free-related functions to func_map
286 std::vector<std::string> freeFunctions =
287 {
288 "VOS_MemFree", "cfree", "free", "free_all_mem", "freeaddrinfo",
289 "gcry_mpi_release", "gcry_sexp_release", "globfree", "nhfree",
290 "obstack_free", "safe_cfree", "safe_free", "safefree", "safexfree",
291 "sm_free", "vim_free", "xfree", "SSL_CTX_free", "SSL_free", "XFree"
292 };
293
294 for (const auto& name : freeFunctions)
295 {
297 }
298};
299
304
306{
307 // traverse every ICFGNode
308 Set<std::string> ae_checkpoint_names = {"svf_assert"};
309 Set<std::string> buf_checkpoint_names = {"UNSAFE_BUFACCESS", "SAFE_BUFACCESS"};
310 Set<std::string> nullptr_checkpoint_names = {"UNSAFE_LOAD", "SAFE_LOAD"};
311
312 for (auto it = svfir->getICFG()->begin(); it != svfir->getICFG()->end(); ++it)
313 {
314 const ICFGNode* node = it->second;
315 if (const CallICFGNode *call = SVFUtil::dyn_cast<CallICFGNode>(node))
316 {
317 if (const FunObjVar *fun = call->getCalledFunction())
318 {
319 if (ae_checkpoint_names.find(fun->getName()) !=
321 {
322 checkpoints.insert(call);
323 }
325 {
326 if (buf_checkpoint_names.find(fun->getName()) !=
328 {
329 checkpoints.insert(call);
330 }
331 }
333 {
334 if (nullptr_checkpoint_names.find(fun->getName()) !=
336 {
337 checkpoints.insert(call);
338 }
339 }
340 }
341 }
342 }
343}
344
346{
347 if (checkpoints.size() == 0)
348 {
349 return;
350 }
351 else
352 {
353 SVFUtil::errs() << SVFUtil::errMsg("At least one svf_assert has not been checked!!") << "\n";
354 for (const CallICFGNode* call: checkpoints)
355 SVFUtil::errs() << call->toString() + "\n";
356 assert(false);
357 }
358}
359
360std::string AbsExtAPI::strRead(const ValVar* rhs, const ICFGNode* node)
361{
363 std::string str0;
364
366 {
367 if (!mgr->getAbstractValue(rhs, node).isAddr()) continue;
370
372 for (const auto &addr: expr0.getAddrs())
373 {
374 val.join_with(as.load(addr));
375 }
376 if (!val.getInterval().is_numeral())
377 {
378 break;
379 }
380 if ((char) val.getInterval().getIntNumeral() == '\0')
381 {
382 break;
383 }
384 str0.push_back((char) val.getInterval().getIntNumeral());
385 }
386 return str0;
387}
388
390{
391 const FunObjVar *fun = call->getCalledFunction();
392 assert(fun && "FunObjVar* is nullptr");
394 // get type of mem api
395 for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(fun))
396 {
397 if (annotation.find("MEMCPY") != std::string::npos)
398 extType = MEMCPY;
399 if (annotation.find("MEMSET") != std::string::npos)
400 extType = MEMSET;
401 if (annotation.find("STRCPY") != std::string::npos)
402 extType = STRCPY;
403 if (annotation.find("STRCAT") != std::string::npos)
404 extType = STRCAT;
405 }
406 if (extType == UNCLASSIFIED)
407 {
408 if (func_map.find(fun->getName()) != func_map.end())
409 {
410 func_map[fun->getName()](call);
411 }
412 else
413 {
414 if (const SVFVar* ret = call->getRetICFGNode()->getActualRet())
415 {
416 const AbstractValue& retVal = mgr->getAbstractValue(ret, call);
417 if (!retVal.isAddr())
418 {
420 }
421 }
422 return;
423 }
424 }
425 // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
426 else if (extType == MEMCPY)
427 {
428 IntervalValue len = mgr->getAbstractValue(call->getArgument(2), call).getInterval();
429 handleMemcpy(call->getArgument(0), call->getArgument(1), len, 0, call);
430 }
431 else if (extType == MEMSET)
432 {
435 handleMemset(call->getArgument(0), elem, len, call);
436 }
437 else if (extType == STRCPY)
438 {
439 handleStrcpy(call);
440 }
441 else if (extType == STRCAT)
442 {
443 // Both strcat and strncat are annotated as STRCAT.
444 // Distinguish by name: strncat/wcsncat contain "ncat".
445 const std::string& name = fun->getName();
446 if (name.find("ncat") != std::string::npos)
447 handleStrncat(call);
448 else
449 handleStrcat(call);
450 }
451 else
452 {
453
454 }
455 return;
456}
457
458// ===----------------------------------------------------------------------===//
459// Shared primitives for string/memory handlers
460// ===----------------------------------------------------------------------===//
461
465{
466 if (var->getType()->isArrayTy())
467 {
468 return SVFUtil::dyn_cast<SVFArrayType>(var->getType())
469 ->getTypeOfElement()->getByteSize();
470 }
471 if (var->getType()->isPointerTy())
472 return 1;
473 assert(false && "unsupported type for element size");
474 return 1;
475}
476
481{
482 return !len.isBottom() && !len.lb().is_minus_infinity();
483}
484
489{
491 // Step 1: determine the buffer size (in bytes) backing this pointer
492 u32_t dst_size = 0;
494 for (const auto& addr : ptrVal.getAddrs())
495 {
496 NodeID objId = as.getIDFromAddr(addr);
498 {
500 }
501 else
502 {
503 const ICFGNode* icfgNode = svfir->getBaseObject(objId)->getICFGNode();
504 for (const SVFStmt* stmt2: icfgNode->getSVFStmts())
505 {
506 if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
507 {
509 }
510 }
511 }
512 }
513
514 // Step 2: scan for '\0' terminator
515 u32_t len = 0;
516 if (mgr->getAbstractValue(strValue, node).isAddr())
517 {
518 for (u32_t index = 0; index < dst_size; index++)
519 {
523 for (const auto &addr: expr0.getAddrs())
524 {
525 val.join_with(as.load(addr));
526 }
527 if (val.getInterval().is_numeral() &&
528 (char) val.getInterval().getIntNumeral() == '\0')
529 {
530 break;
531 }
532 ++len;
533 }
534 }
535
536 // Step 3: scale by element size and return
538 if (len == 0)
540 return IntervalValue(len * elemSize);
541}
542
543// ===----------------------------------------------------------------------===//
544// String/memory operation handlers
545// ===----------------------------------------------------------------------===//
546
550{
551 const ValVar* dst = call->getArgument(0);
552 const ValVar* src = call->getArgument(1);
553 IntervalValue srcLen = getStrlen(src, call);
554 if (!isValidLength(srcLen)) return;
555 handleMemcpy(dst, src, srcLen, 0, call);
556}
557
561{
562 const ValVar* dst = call->getArgument(0);
563 const ValVar* src = call->getArgument(1);
564 IntervalValue dstLen = getStrlen(dst, call);
565 IntervalValue srcLen = getStrlen(src, call);
566 if (!isValidLength(dstLen)) return;
567 handleMemcpy(dst, src, srcLen, dstLen.lb().getIntNumeral(), call);
568}
569
573{
574 const ValVar* dst = call->getArgument(0);
575 const ValVar* src = call->getArgument(1);
577 IntervalValue dstLen = getStrlen(dst, call);
578 if (!isValidLength(dstLen)) return;
579 handleMemcpy(dst, src, n, dstLen.lb().getIntNumeral(), call);
580}
581
584 const ValVar *src, const IntervalValue& len,
585 u32_t start_idx, const ICFGNode* node)
586{
587 if (!isValidLength(len)) return;
589
591 u32_t size = std::min((u32_t)Options::MaxFieldLimit(),
592 (u32_t)len.lb().getIntNumeral());
593 u32_t range_val = size / elemSize;
594
595 if (!mgr->getAbstractValue(src, node).isAddr() || !mgr->getAbstractValue(dst, node).isAddr())
596 return;
597
598 for (u32_t index = 0; index < range_val; index++)
599 {
604 for (const auto &dstAddr: expr_dst.getAddrs())
605 {
606 for (const auto &srcAddr: expr_src.getAddrs())
607 {
608 u32_t objId = as.getIDFromAddr(srcAddr);
609 if (as.inAddrToValTable(objId) || as.inAddrToAddrsTable(objId))
610 {
611 as.store(dstAddr, as.load(srcAddr));
612 }
613 }
614 }
615 }
616}
617
624 const IntervalValue& elem, const IntervalValue& len, const ICFGNode* node)
625{
626 if (!isValidLength(len)) return;
628
629 u32_t elemSize = 1;
630 if (dst->getType()->isArrayTy())
631 {
632 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())
633 ->getTypeOfElement()->getByteSize();
634 }
635 else if (dst->getType()->isPointerTy())
636 {
637 elemSize = 1;
638 }
639 else
640 {
641 assert(false && "unsupported type for element size");
642 }
643 u32_t size = std::min((u32_t)Options::MaxFieldLimit(),
644 (u32_t)len.lb().getIntNumeral());
645 u32_t range_val = size / elemSize;
646
647 for (u32_t index = 0; index < range_val; index++)
648 {
649 if (!mgr->getAbstractValue(dst, node).isAddr())
650 break;
652 for (const auto &addr: lhs_gep.getAddrs())
653 {
654 u32_t objId = as.getIDFromAddr(addr);
655 if (as.inAddrToValTable(objId))
656 {
657 AbstractValue tmp = as.load(addr);
659 as.store(addr, tmp);
660 }
661 else
662 {
663 as.store(addr, elem);
664 }
665 }
666 }
667}
668
681{
682 if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
683 {
684 u32_t bits = type->getByteSize() * 8;
685 s64_t ub = 0;
686 s64_t lb = 0;
687 if (bits >= 32)
688 {
689 if (intType->isSigned())
690 {
691 ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
692 lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
693 }
694 else
695 {
696 ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
697 lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
698 }
699 }
700 else if (bits == 16)
701 {
702 if (intType->isSigned())
703 {
704 ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
705 lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
706 }
707 else
708 {
709 ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
710 lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
711 }
712 }
713 else if (bits == 8)
714 {
715 if (intType->isSigned())
716 {
717 ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
718 lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
719 }
720 else
721 {
722 ub = static_cast<s64_t>(std::numeric_limits<uint8_t>::max());
723 lb = static_cast<s64_t>(std::numeric_limits<uint8_t>::min());
724 }
725 }
726 return IntervalValue(lb, ub);
727 }
728 else if (SVFUtil::isa<SVFOtherType>(type))
729 {
730 // handle other type like float double, set s32_t as the range
731 s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
732 s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
733 return IntervalValue(lb, ub);
734 }
735 else
736 {
737 return IntervalValue::top();
738 // other types, return top interval
739 }
740}
#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
AbstractStateManager * mgr
Pointer to the state manager.
Definition AbsExtAPI.h:117
void collectCheckPoint()
void initExtFunMap()
Initializes the external function map.
Definition AbsExtAPI.cpp:42
AbsExtAPI(AbstractStateManager *mgr)
Constructor for AbsExtAPI.
Definition AbsExtAPI.cpp:35
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:114
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)
SVFIR * svfir
Pointer to the SVF intermediate representation.
Definition AbsExtAPI.h:118
ExtAPIType
Enumeration of external API types.
Definition AbsExtAPI.h:50
AbstractState & getAbstractState(const ICFGNode *node)
Retrieves the abstract state from the trace for a given ICFG node.
IntervalValue getRangeLimitFromType(const SVFType *type)
Gets the range limit from a type.
ICFG * icfg
Pointer to the interprocedural control flow graph.
Definition AbsExtAPI.h:119
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:120
void updateAbstractValue(const ValVar *var, const AbstractValue &val, const ICFGNode *node)
Write a top-level variable's abstract value into abstractTrace[node].
AbstractState & getAbstractState(const ICFGNode *node)
Retrieve the abstract state for a given ICFG node. Asserts if absent.
u32_t getAllocaInstByteSize(const AddrStmt *addr)
Get the byte size of a stack allocation.
const AbstractValue & getAbstractValue(const ValVar *var, const ICFGNode *node)
AddressValue getGepObjAddrs(const ValVar *pointer, IntervalValue offset)
Compute GEP object addresses for a pointer at a given element offset.
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:254
static const Option< bool > BufferOverflowCheck
buffer overflow checker, Default: false
Definition Options.h:252
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
const SVFVar * getSVFVar(NodeID id) const
ObjVar/GepObjVar/BaseObjVar.
Definition SVFIR.h:133
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:932
int isdigit(int c)
Definition extapi.c:937
int isgraph(int c)
Definition extapi.c:942
int isspace(char c)
Definition extapi.c:962
int isprint(int c)
Definition extapi.c:952
int ispunct(int argument)
Definition extapi.c:957
int isblank(int character)
Definition extapi.c:927
int isalnum(int character)
Definition extapi.c:917
int isupper(int c)
Definition extapi.c:967
int isxdigit(int c)
Definition extapi.c:972
int isalpha(int character)
Definition extapi.c:922
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