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 by Jiawei Wang on 2024/9/9.
26//
27#include "AE/Svfexe/AbsExtAPI.h"
29#include "WPA/Andersen.h"
30#include "Util/Options.h"
31
32using namespace SVF;
39
41{
42#define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \
43 auto sse_##FUNC_NAME = [this](const CallICFGNode *callNode) { \
44 /* run real ext function */ \
45 AbstractState& as = getAbsStateFromTrace(callNode); \
46 u32_t rhs_id = callNode->getArgument(0)->getId(); \
47 if (!as.inVarToValTable(rhs_id)) return; \
48 u32_t rhs = as[rhs_id].getInterval().lb().getIntNumeral(); \
49 s32_t res = FUNC_NAME(rhs); \
50 u32_t lhsId = callNode->getRetICFGNode()->getActualRet()->getId(); \
51 as[lhsId] = IntervalValue(res); \
52 return; \
53 }; \
54 func_map[#FUNC_NAME] = sse_##FUNC_NAME;
55
67 SSE_FUNC_PROCESS(llvm.sin.f64, sin);
68 SSE_FUNC_PROCESS(llvm.cos.f64, cos);
69 SSE_FUNC_PROCESS(llvm.tan.f64, tan);
70 SSE_FUNC_PROCESS(llvm.log.f64, log);
74
75 auto sse_svf_assert = [this](const CallICFGNode* callNode)
76 {
78 u32_t arg0 = callNode->getArgument(0)->getId();
80 if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
81 {
82 SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
83 }
84 else
85 {
86 SVFUtil::errs() << SVFUtil::errMsg("Assertion failure, this svf_assert cannot be verified!!\n") << callNode->toString() << "\n";
87 assert(false);
88 }
89 return;
90 };
91 func_map["svf_assert"] = sse_svf_assert;
92
93 auto svf_assert_eq = [this](const CallICFGNode* callNode)
94 {
95 u32_t arg0 = callNode->getArgument(0)->getId();
96 u32_t arg1 = callNode->getArgument(1)->getId();
98 if (as[arg0].getInterval().equals(as[arg1].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;
115 u32_t num_id = callNode->getArgument(0)->getId();
116 std::string text = strRead(as, callNode->getArgument(1));
117 assert(as.inVarToValTable(num_id) && "print() should pass integer");
118 IntervalValue itv = as[num_id].getInterval();
119 std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
120 << ", PrintVal: " << itv.toString() << ", Loc:" << callNode->getSourceLoc() << std::endl;
121 return;
122 };
123 func_map["svf_print"] = svf_print;
124
125 auto svf_set_value = [&](const CallICFGNode* callNode)
126 {
127 if (callNode->arg_size() < 2) return;
129 AbstractValue& num = as[callNode->getArgument(0)->getId()];
130 AbstractValue& lb = as[callNode->getArgument(1)->getId()];
131 AbstractValue& ub = as[callNode->getArgument(2)->getId()];
133 num.getInterval().set_to_top();
134 num.getInterval().meet_with(IntervalValue(lb.getInterval().lb(), ub.getInterval().ub()));
135 const ICFGNode* node = SVFUtil::cast<ValVar>(callNode->getArgument(0))->getICFGNode();
136 for (const SVFStmt* stmt: node->getSVFStmts())
137 {
138 if (SVFUtil::isa<LoadStmt>(stmt))
139 {
140 const LoadStmt* load = SVFUtil::cast<LoadStmt>(stmt);
141 NodeID rhsId = load->getRHSVarID();
142 as.storeValue(rhsId, num);
143 }
144 }
145 return;
146 };
147 func_map["set_value"] = svf_set_value;
148
149 auto sse_scanf = [&](const CallICFGNode* callNode)
150 {
152 //scanf("%d", &data);
153 if (callNode->arg_size() < 2) return;
154
155 u32_t dst_id = callNode->getArgument(1)->getId();
156 if (!as.inVarToAddrsTable(dst_id))
157 {
158 return;
159 }
160 else
161 {
163 for (auto vaddr: Addrs.getAddrs())
164 {
165 u32_t objId = as.getIDFromAddr(vaddr);
167 as.store(vaddr, range);
168 }
169 }
170 };
171 auto sse_fscanf = [&](const CallICFGNode* callNode)
172 {
173 //fscanf(stdin, "%d", &data);
174 if (callNode->arg_size() < 3) return;
176 u32_t dst_id = callNode->getArgument(2)->getId();
177 if (!as.inVarToAddrsTable(dst_id))
178 {
179 }
180 else
181 {
183 for (auto vaddr: Addrs.getAddrs())
184 {
185 u32_t objId = as.getIDFromAddr(vaddr);
187 as.store(vaddr, range);
188 }
189 }
190 };
191
192 func_map["__isoc99_fscanf"] = sse_fscanf;
193 func_map["__isoc99_scanf"] = sse_scanf;
194 func_map["__isoc99_vscanf"] = sse_scanf;
195 func_map["fscanf"] = sse_fscanf;
196 func_map["scanf"] = sse_scanf;
197 func_map["sscanf"] = sse_scanf;
198 func_map["__isoc99_sscanf"] = sse_scanf;
199 func_map["vscanf"] = sse_scanf;
200
201 auto sse_fread = [&](const CallICFGNode *callNode)
202 {
203 if (callNode->arg_size() < 3) return;
205 u32_t block_count_id = callNode->getArgument(2)->getId();
206 u32_t block_size_id = callNode->getArgument(1)->getId();
208 IntervalValue block_size = as[block_size_id].getInterval();
210 };
211 func_map["fread"] = sse_fread;
212
213 auto sse_sprintf = [&](const CallICFGNode *callNode)
214 {
215 // printf is difficult to predict since it has no byte size arguments
216 };
217
218 auto sse_snprintf = [&](const CallICFGNode *callNode)
219 {
220 if (callNode->arg_size() < 2) return;
222 u32_t size_id = callNode->getArgument(1)->getId();
223 u32_t dst_id = callNode->getArgument(0)->getId();
224 // get elem size of arg2
225 u32_t elemSize = 1;
226 if (callNode->getArgument(2)->getType()->isArrayTy())
227 {
228 elemSize = SVFUtil::dyn_cast<SVFArrayType>(
229 callNode->getArgument(2)->getType())->getTypeOfElement()->getByteSize();
230 }
231 else if (callNode->getArgument(2)->getType()->isPointerTy())
232 {
233 elemSize = as.getPointeeElement(callNode->getArgument(2)->getId())->getByteSize();
234 }
235 else
236 {
237 return;
238 // assert(false && "we cannot support this type");
239 }
240 IntervalValue size = as[size_id].getInterval() * IntervalValue(elemSize) - IntervalValue(1);
241 if (!as.inVarToAddrsTable(dst_id))
242 {
243 }
244 };
245 func_map["__snprintf_chk"] = sse_snprintf;
246 func_map["__vsprintf_chk"] = sse_sprintf;
247 func_map["__sprintf_chk"] = sse_sprintf;
248 func_map["snprintf"] = sse_snprintf;
249 func_map["sprintf"] = sse_sprintf;
250 func_map["vsprintf"] = sse_sprintf;
251 func_map["vsnprintf"] = sse_snprintf;
252 func_map["__vsnprintf_chk"] = sse_snprintf;
253 func_map["swprintf"] = sse_snprintf;
254 func_map["_snwprintf"] = sse_snprintf;
255
256
257 auto sse_itoa = [&](const CallICFGNode* callNode)
258 {
259 // itoa(num, ch, 10);
260 // num: int, ch: char*, 10 is decimal
261 if (callNode->arg_size() < 3) return;
263 u32_t num_id = callNode->getArgument(0)->getId();
264
265 u32_t num = (u32_t) as[num_id].getInterval().getNumeral();
266 std::string snum = std::to_string(num);
267 };
268 func_map["itoa"] = sse_itoa;
269
270
271 auto sse_strlen = [&](const CallICFGNode *callNode)
272 {
273 // check the arg size
274 if (callNode->arg_size() < 1) return;
275 const SVFVar* strValue = callNode->getArgument(0);
277 NodeID value_id = strValue->getId();
278 u32_t lhsId = callNode->getRetICFGNode()->getActualRet()->getId();
279 u32_t dst_size = 0;
280 for (const auto& addr : as[value_id].getAddrs())
281 {
282 NodeID objId = as.getIDFromAddr(addr);
284 {
286 }
287 else
288 {
290 for (const SVFStmt* stmt2: addrNode->getSVFStmts())
291 {
292 if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
293 {
294 dst_size = as.getAllocaInstByteSize(addrStmt);
295 }
296 }
297 }
298 }
299 u32_t len = 0;
301 if (as.inVarToAddrsTable(dstid))
302 {
303 for (u32_t index = 0; index < dst_size; index++)
304 {
306 as.getGepObjAddrs(dstid, IntervalValue(index));
308 for (const auto &addr: expr0.getAddrs())
309 {
310 val.join_with(as.load(addr));
311 }
312 if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
313 {
314 break;
315 }
316 ++len;
317 }
318 }
319 if (len == 0)
320 {
322 }
323 else
324 {
326 }
327 };
328 func_map["strlen"] = sse_strlen;
329 func_map["wcslen"] = sse_strlen;
330
331 auto sse_recv = [&](const CallICFGNode *callNode)
332 {
333 // recv(sockfd, buf, len, flags);
334 if (callNode->arg_size() < 4) return;
336 u32_t len_id = callNode->getArgument(2)->getId();
337 IntervalValue len = as[len_id].getInterval() - IntervalValue(1);
338 u32_t lhsId = callNode->getRetICFGNode()->getActualRet()->getId();
339 as[lhsId] = len;
340 };
341 func_map["recv"] = sse_recv;
342 func_map["__recv"] = sse_recv;
343
344 auto sse_free = [&](const CallICFGNode *callNode)
345 {
346 if (callNode->arg_size() < 1) return;
348 const u32_t freePtr = callNode->getArgument(0)->getId();
349 for (auto addr: as[freePtr].getAddrs())
350 {
352 {
353 // Detected a double free — the address has already been freed.
354 // No action is taken at this point.
355 }
356 else
357 {
358 as.addToFreedAddrs(addr);
359 }
360 }
361 };
362 // Add all free-related functions to func_map
363 std::vector<std::string> freeFunctions =
364 {
365 "VOS_MemFree", "cfree", "free", "free_all_mem", "freeaddrinfo",
366 "gcry_mpi_release", "gcry_sexp_release", "globfree", "nhfree",
367 "obstack_free", "safe_cfree", "safe_free", "safefree", "safexfree",
368 "sm_free", "vim_free", "xfree", "SSL_CTX_free", "SSL_free", "XFree"
369 };
370
371 for (const auto& name : freeFunctions)
372 {
374 }
375};
376
378{
379 const ICFGNode* repNode = icfg->getRepNode(node);
380 if (abstractTrace.count(repNode) == 0)
381 {
382 assert(0 && "No preAbsTrace for this node");
383 abort();
384 }
385 else
386 {
387 return abstractTrace[repNode];
388 }
389}
390
392{
393 // sse read string nodeID->string
394 std::string str0;
395
397 {
398 // dead loop for string and break if there's a \0. If no \0, it will throw err.
399 if (!as.inVarToAddrsTable(rhs->getId())) continue;
401 as.getGepObjAddrs(rhs->getId(), IntervalValue(index));
402
404 for (const auto &addr: expr0.getAddrs())
405 {
406 val.join_with(as.load(addr));
407 }
408 if (!val.getInterval().is_numeral())
409 {
410 break;
411 }
412 if ((char) val.getInterval().getIntNumeral() == '\0')
413 {
414 break;
415 }
416 str0.push_back((char) val.getInterval().getIntNumeral());
417 }
418 return str0;
419}
420
422{
424 const FunObjVar *fun = call->getCalledFunction();
425 assert(fun && "FunObjVar* is nullptr");
427 // get type of mem api
428 for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(fun))
429 {
430 if (annotation.find("MEMCPY") != std::string::npos)
431 extType = MEMCPY;
432 if (annotation.find("MEMSET") != std::string::npos)
433 extType = MEMSET;
434 if (annotation.find("STRCPY") != std::string::npos)
435 extType = STRCPY;
436 if (annotation.find("STRCAT") != std::string::npos)
437 extType = STRCAT;
438 }
439 if (extType == UNCLASSIFIED)
440 {
441 if (func_map.find(fun->getName()) != func_map.end())
442 {
443 func_map[fun->getName()](call);
444 }
445 else
446 {
447 if (const SVFVar* ret = call->getRetICFGNode()->getActualRet())
448 {
449 u32_t lhsId = ret->getId();
450 if (as.inVarToAddrsTable(lhsId))
451 {
452
453 }
454 else
455 {
457 }
458 }
459 return;
460 }
461 }
462 // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
463 else if (extType == MEMCPY)
464 {
465 IntervalValue len = as[call->getArgument(2)->getId()].getInterval();
466 svfir->getGNode(call->getArgument(0)->getId());
467 handleMemcpy(as, call->getArgument(0), call->getArgument(1), len, 0);
468 }
469 else if (extType == MEMSET)
470 {
471 // memset dst is arg0, elem is arg1, size is arg2
472 IntervalValue len = as[call->getArgument(2)->getId()].getInterval();
473 IntervalValue elem = as[call->getArgument(1)->getId()].getInterval();
474 handleMemset(as, call->getArgument(0), elem, len);
475 }
476 else if (extType == STRCPY)
477 {
478 handleStrcpy(call);
479 }
480 else if (extType == STRCAT)
481 {
482 handleStrcat(call);
483 }
484 else
485 {
486
487 }
488 return;
489}
490
492{
493 // strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk
494 // get the dst and src
496 const SVFVar* arg0Val = call->getArgument(0);
497 const SVFVar* arg1Val = call->getArgument(1);
499 // no need to -1, since it has \0 as the last byte
500 handleMemcpy(as, arg0Val, arg1Val, strLen, strLen.lb().getIntNumeral());
501}
502
504{
505 NodeID value_id = strValue->getId();
506 u32_t dst_size = 0;
507 for (const auto& addr : as[value_id].getAddrs())
508 {
509 NodeID objId = as.getIDFromAddr(addr);
511 {
513 }
514 else
515 {
516 const ICFGNode* icfgNode = svfir->getBaseObject(objId)->getICFGNode();
517 for (const SVFStmt* stmt2: icfgNode->getSVFStmts())
518 {
519 if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
520 {
521 dst_size = as.getAllocaInstByteSize(addrStmt);
522 }
523 }
524 }
525 }
526 u32_t len = 0;
527 u32_t elemSize = 1;
528 if (as.inVarToAddrsTable(value_id))
529 {
530 for (u32_t index = 0; index < dst_size; index++)
531 {
533 as.getGepObjAddrs(value_id, IntervalValue(index));
535 for (const auto &addr: expr0.getAddrs())
536 {
537 val.join_with(as.load(addr));
538 }
539 if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
540 {
541 break;
542 }
543 ++len;
544 }
545 if (strValue->getType()->isArrayTy())
546 {
547 elemSize = SVFUtil::dyn_cast<SVFArrayType>(strValue->getType())->getTypeOfElement()->getByteSize();
548 }
549 else if (strValue->getType()->isPointerTy())
550 {
551 if (const SVFType* elemType = as.getPointeeElement(value_id))
552 {
553 if (elemType->isArrayTy())
554 elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
555 else
556 elemSize = elemType->getByteSize();
557 }
558 else
559 {
560 elemSize = 1;
561 }
562 }
563 else
564 {
565 assert(false && "we cannot support this type");
566 }
567 }
568 if (len == 0)
569 {
571 }
572 else
573 {
574 return IntervalValue(len * elemSize);
575 }
576}
577
578
580{
581 // __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat
582 // to check it is strcat group or strncat group
584 const FunObjVar *fun = call->getCalledFunction();
585 const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
586 const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
587 if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
588 {
589 const SVFVar* arg0Val = call->getArgument(0);
590 const SVFVar* arg1Val = call->getArgument(1);
594 handleMemcpy(as, arg0Val, arg1Val, strLen1, strLen0.lb().getIntNumeral());
595 // do memcpy
596 }
597 else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
598 {
599 const SVFVar* arg0Val = call->getArgument(0);
600 const SVFVar* arg1Val = call->getArgument(1);
601 const SVFVar* arg2Val = call->getArgument(2);
602 IntervalValue arg2Num = as[arg2Val->getId()].getInterval();
605 handleMemcpy(as, arg0Val, arg1Val, arg2Num, strLen0.lb().getIntNumeral());
606 // do memcpy
607 }
608 else
609 {
610 assert(false && "unknown strcat function, please add it to strcatGroup or strncatGroup");
611 }
612}
613
615{
616 u32_t dstId = dst->getId(); // pts(dstId) = {objid} objbar objtypeinfo->getType().
617 u32_t srcId = src->getId();
618 u32_t elemSize = 1;
619 if (dst->getType()->isArrayTy())
620 {
621 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
622 }
623 // memcpy(i32*, i32*, 40)
624 else if (dst->getType()->isPointerTy())
625 {
626 if (const SVFType* elemType = as.getPointeeElement(dstId))
627 {
628 if (elemType->isArrayTy())
629 elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
630 else
631 elemSize = elemType->getByteSize();
632 }
633 else
634 {
635 elemSize = 1;
636 }
637 }
638 else
639 {
640 assert(false && "we cannot support this type");
641 }
642 u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
643 u32_t range_val = size / elemSize;
644 if (as.inVarToAddrsTable(srcId) && as.inVarToAddrsTable(dstId))
645 {
646 for (u32_t index = 0; index < range_val; index++)
647 {
648 // dead loop for string and break if there's a \0. If no \0, it will throw err.
650 as.getGepObjAddrs(srcId, IntervalValue(index));
652 as.getGepObjAddrs(dstId, IntervalValue(index + start_idx));
653 for (const auto &dst: expr_dst.getAddrs())
654 {
655 for (const auto &src: expr_src.getAddrs())
656 {
657 u32_t objId = as.getIDFromAddr(src);
658 if (as.inAddrToValTable(objId))
659 {
660 as.store(dst, as.load(src));
661 }
662 else if (as.inAddrToAddrsTable(objId))
663 {
664 as.store(dst, as.load(src));
665 }
666 }
667 }
668 }
669 }
670}
671
673{
674 u32_t dstId = dst->getId();
675 u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
676 u32_t elemSize = 1;
677 if (dst->getType()->isArrayTy())
678 {
679 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
680 }
681 else if (dst->getType()->isPointerTy())
682 {
683 if (const SVFType* elemType = as.getPointeeElement(dstId))
684 {
685 elemSize = elemType->getByteSize();
686 }
687 else
688 {
689 elemSize = 1;
690 }
691 }
692 else
693 {
694 assert(false && "we cannot support this type");
695 }
696
697 u32_t range_val = size / elemSize;
698 for (u32_t index = 0; index < range_val; index++)
699 {
700 // dead loop for string and break if there's a \0. If no \0, it will throw err.
701 if (as.inVarToAddrsTable(dstId))
702 {
703 AbstractValue lhs_gep = as.getGepObjAddrs(dstId, IntervalValue(index));
704 for (const auto &addr: lhs_gep.getAddrs())
705 {
706 u32_t objId = as.getIDFromAddr(addr);
707 if (as.inAddrToValTable(objId))
708 {
709 AbstractValue tmp = as.load(addr);
711 as.store(addr, tmp);
712 }
713 else
714 {
715 as.store(addr, elem);
716 }
717 }
718 }
719 else
720 break;
721 }
722}
723
736{
737 if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
738 {
739 u32_t bits = type->getByteSize() * 8;
740 s64_t ub = 0;
741 s64_t lb = 0;
742 if (bits >= 32)
743 {
744 if (intType->isSigned())
745 {
746 ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
747 lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
748 }
749 else
750 {
751 ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
752 lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
753 }
754 }
755 else if (bits == 16)
756 {
757 if (intType->isSigned())
758 {
759 ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
760 lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
761 }
762 else
763 {
764 ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
765 lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
766 }
767 }
768 else if (bits == 8)
769 {
770 if (intType->isSigned())
771 {
772 ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
773 lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
774 }
775 else
776 {
777 ub = static_cast<s64_t>(std::numeric_limits<uint8_t>::max());
778 lb = static_cast<s64_t>(std::numeric_limits<uint8_t>::min());
779 }
780 }
781 return IntervalValue(lb, ub);
782 }
783 else if (SVFUtil::isa<SVFOtherType>(type))
784 {
785 // handle other type like float double, set s32_t as the range
786 s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
787 s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
788 return IntervalValue(lb, ub);
789 }
790 else
791 {
792 return IntervalValue::top();
793 // other types, return top interval
794 }
795}
#define SSE_FUNC_PROCESS(LLVM_NAME,FUNC_NAME)
newitem type
Definition cJSON.cpp:2739
const char *const name
Definition cJSON.h:264
int index
Definition cJSON.h:170
std::string strRead(AbstractState &as, const SVFVar *rhs)
Reads a string from the abstract state.
void handleMemset(AbstractState &as, const SVFVar *dst, IntervalValue elem, IntervalValue len)
Handles the memset API call.
void initExtFunMap()
Initializes the external function map.
Definition AbsExtAPI.cpp:40
IntervalValue getStrlen(AbstractState &as, const SVF::SVFVar *strValue)
Calculates the length of a string.
Map< const ICFGNode *, AbstractState > & abstractTrace
Map of ICFG nodes to abstract states.
Definition AbsExtAPI.h:134
void handleExtAPI(const CallICFGNode *call)
Handles an external API call.
AbsExtAPI(Map< const ICFGNode *, AbstractState > &traces)
Constructor for AbsExtAPI.
Definition AbsExtAPI.cpp:33
AbstractState & getAbsStateFromTrace(const ICFGNode *node)
Retrieves the abstract state from the trace for a given ICFG node.
void handleMemcpy(AbstractState &as, const SVF::SVFVar *dst, const SVF::SVFVar *src, IntervalValue len, u32_t start_idx)
Handles the memcpy API call.
SVFIR * svfir
Pointer to the SVF intermediate representation.
Definition AbsExtAPI.h:132
void handleStrcat(const SVF::CallICFGNode *call)
Handles the strcat API call.
ExtAPIType
Enumeration of external API types.
Definition AbsExtAPI.h:50
IntervalValue getRangeLimitFromType(const SVFType *type)
Gets the range limit from a type.
ICFG * icfg
Pointer to the interprocedural control flow graph.
Definition AbsExtAPI.h:133
void handleStrcpy(const CallICFGNode *call)
Handles the strcpy API call.
Map< std::string, std::function< void(const CallICFGNode *)> > func_map
Map of function names to handlers.
Definition AbsExtAPI.h:135
static AbstractInterpretation & getAEInstance()
Set< const CallICFGNode * > checkpoints
static bool isInvalidMem(u32_t addr)
void join_with(const AbstractValue &other)
IntervalValue & getInterval()
NodeID getRHSVarID() 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:494
const FunObjVar * getCalledFunction() const
Definition ICFGNode.h:512
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:451
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:44
const std::vector< std::string > & getExtFuncAnnotations(const FunObjVar *fun)
Definition ExtAPI.cpp:256
NodeType * getGNode(NodeID id) const
Get a node.
const SVFStmtList & getSVFStmts() const
Definition ICFGNode.h:117
const ICFGNode * getRepNode(const ICFGNode *node) const
Definition ICFG.h:246
const BoundedInt & ub() const
Return the upper bound.
bool is_numeral() const
Return true if the IntervalValue is a number [num, num].
const std::string toString() const
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
const BoundedInt & lb() const
Return the lower bound.
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:35
const SVFVar * getActualRet() const
Return actual return parameter.
Definition ICFGNode.h:621
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:423
ICFG * getICFG() const
Definition SVFIR.h:163
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 isArrayTy() const
Definition SVFType.h:259
bool isPointerTy() const
Definition SVFType.h:254
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual const SVFType * getType() const
Definition SVFValue.h:169
virtual const std::string & getName() const
Definition SVFValue.h:184
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:68
u32_t NodeID
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned u32_t
Definition GeneralType.h:47
signed long long s64_t
Definition GeneralType.h:50