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() <<"svf_assert Fail. " << 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 }
384 else
385 {
386 return abstractTrace[repNode];
387 }
388}
389
391{
392 // sse read string nodeID->string
393 std::string str0;
394
396 {
397 // dead loop for string and break if there's a \0. If no \0, it will throw err.
398 if (!as.inVarToAddrsTable(rhs->getId())) continue;
400 as.getGepObjAddrs(rhs->getId(), IntervalValue(index));
401
403 for (const auto &addr: expr0.getAddrs())
404 {
405 val.join_with(as.load(addr));
406 }
407 if (!val.getInterval().is_numeral())
408 {
409 break;
410 }
411 if ((char) val.getInterval().getIntNumeral() == '\0')
412 {
413 break;
414 }
415 str0.push_back((char) val.getInterval().getIntNumeral());
416 }
417 return str0;
418}
419
421{
423 const FunObjVar *fun = call->getCalledFunction();
424 assert(fun && "FunObjVar* is nullptr");
426 // get type of mem api
427 for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(fun))
428 {
429 if (annotation.find("MEMCPY") != std::string::npos)
430 extType = MEMCPY;
431 if (annotation.find("MEMSET") != std::string::npos)
432 extType = MEMSET;
433 if (annotation.find("STRCPY") != std::string::npos)
434 extType = STRCPY;
435 if (annotation.find("STRCAT") != std::string::npos)
436 extType = STRCAT;
437 }
438 if (extType == UNCLASSIFIED)
439 {
440 if (func_map.find(fun->getName()) != func_map.end())
441 {
442 func_map[fun->getName()](call);
443 }
444 else
445 {
446 if (const SVFVar* ret = call->getRetICFGNode()->getActualRet())
447 {
448 u32_t lhsId = ret->getId();
449 if (as.inVarToAddrsTable(lhsId))
450 {
451
452 }
453 else
454 {
456 }
457 }
458 return;
459 }
460 }
461 // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
462 else if (extType == MEMCPY)
463 {
464 IntervalValue len = as[call->getArgument(2)->getId()].getInterval();
465 svfir->getGNode(call->getArgument(0)->getId());
466 handleMemcpy(as, call->getArgument(0), call->getArgument(1), len, 0);
467 }
468 else if (extType == MEMSET)
469 {
470 // memset dst is arg0, elem is arg1, size is arg2
471 IntervalValue len = as[call->getArgument(2)->getId()].getInterval();
472 IntervalValue elem = as[call->getArgument(1)->getId()].getInterval();
473 handleMemset(as, call->getArgument(0), elem, len);
474 }
475 else if (extType == STRCPY)
476 {
477 handleStrcpy(call);
478 }
479 else if (extType == STRCAT)
480 {
481 handleStrcat(call);
482 }
483 else
484 {
485
486 }
487 return;
488}
489
491{
492 // strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk
493 // get the dst and src
495 const SVFVar* arg0Val = call->getArgument(0);
496 const SVFVar* arg1Val = call->getArgument(1);
498 // no need to -1, since it has \0 as the last byte
499 handleMemcpy(as, arg0Val, arg1Val, strLen, strLen.lb().getIntNumeral());
500}
501
503{
504 NodeID value_id = strValue->getId();
505 u32_t dst_size = 0;
506 for (const auto& addr : as[value_id].getAddrs())
507 {
508 NodeID objId = as.getIDFromAddr(addr);
510 {
512 }
513 else
514 {
515 const ICFGNode* icfgNode = svfir->getBaseObject(objId)->getICFGNode();
516 for (const SVFStmt* stmt2: icfgNode->getSVFStmts())
517 {
518 if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
519 {
520 dst_size = as.getAllocaInstByteSize(addrStmt);
521 }
522 }
523 }
524 }
525 u32_t len = 0;
526 u32_t elemSize = 1;
527 if (as.inVarToAddrsTable(value_id))
528 {
529 for (u32_t index = 0; index < dst_size; index++)
530 {
532 as.getGepObjAddrs(value_id, IntervalValue(index));
534 for (const auto &addr: expr0.getAddrs())
535 {
536 val.join_with(as.load(addr));
537 }
538 if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
539 {
540 break;
541 }
542 ++len;
543 }
544 if (strValue->getType()->isArrayTy())
545 {
546 elemSize = SVFUtil::dyn_cast<SVFArrayType>(strValue->getType())->getTypeOfElement()->getByteSize();
547 }
548 else if (strValue->getType()->isPointerTy())
549 {
550 if (const SVFType* elemType = as.getPointeeElement(value_id))
551 {
552 if (elemType->isArrayTy())
553 elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
554 else
555 elemSize = elemType->getByteSize();
556 }
557 else
558 {
559 elemSize = 1;
560 }
561 }
562 else
563 {
564 assert(false && "we cannot support this type");
565 }
566 }
567 if (len == 0)
568 {
570 }
571 else
572 {
573 return IntervalValue(len * elemSize);
574 }
575}
576
577
579{
580 // __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat
581 // to check it is strcat group or strncat group
583 const FunObjVar *fun = call->getCalledFunction();
584 const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
585 const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
586 if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
587 {
588 const SVFVar* arg0Val = call->getArgument(0);
589 const SVFVar* arg1Val = call->getArgument(1);
593 handleMemcpy(as, arg0Val, arg1Val, strLen1, strLen0.lb().getIntNumeral());
594 // do memcpy
595 }
596 else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
597 {
598 const SVFVar* arg0Val = call->getArgument(0);
599 const SVFVar* arg1Val = call->getArgument(1);
600 const SVFVar* arg2Val = call->getArgument(2);
601 IntervalValue arg2Num = as[arg2Val->getId()].getInterval();
604 handleMemcpy(as, arg0Val, arg1Val, arg2Num, strLen0.lb().getIntNumeral());
605 // do memcpy
606 }
607 else
608 {
609 assert(false && "unknown strcat function, please add it to strcatGroup or strncatGroup");
610 }
611}
612
614{
615 u32_t dstId = dst->getId(); // pts(dstId) = {objid} objbar objtypeinfo->getType().
616 u32_t srcId = src->getId();
617 u32_t elemSize = 1;
618 if (dst->getType()->isArrayTy())
619 {
620 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
621 }
622 // memcpy(i32*, i32*, 40)
623 else if (dst->getType()->isPointerTy())
624 {
625 if (const SVFType* elemType = as.getPointeeElement(dstId))
626 {
627 if (elemType->isArrayTy())
628 elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
629 else
630 elemSize = elemType->getByteSize();
631 }
632 else
633 {
634 elemSize = 1;
635 }
636 }
637 else
638 {
639 assert(false && "we cannot support this type");
640 }
641 u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
642 u32_t range_val = size / elemSize;
643 if (as.inVarToAddrsTable(srcId) && as.inVarToAddrsTable(dstId))
644 {
645 for (u32_t index = 0; index < range_val; index++)
646 {
647 // dead loop for string and break if there's a \0. If no \0, it will throw err.
649 as.getGepObjAddrs(srcId, IntervalValue(index));
651 as.getGepObjAddrs(dstId, IntervalValue(index + start_idx));
652 for (const auto &dst: expr_dst.getAddrs())
653 {
654 for (const auto &src: expr_src.getAddrs())
655 {
656 u32_t objId = as.getIDFromAddr(src);
657 if (as.inAddrToValTable(objId))
658 {
659 as.store(dst, as.load(src));
660 }
661 else if (as.inAddrToAddrsTable(objId))
662 {
663 as.store(dst, as.load(src));
664 }
665 }
666 }
667 }
668 }
669}
670
672{
673 u32_t dstId = dst->getId();
674 u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
675 u32_t elemSize = 1;
676 if (dst->getType()->isArrayTy())
677 {
678 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
679 }
680 else if (dst->getType()->isPointerTy())
681 {
682 if (const SVFType* elemType = as.getPointeeElement(dstId))
683 {
684 elemSize = elemType->getByteSize();
685 }
686 else
687 {
688 elemSize = 1;
689 }
690 }
691 else
692 {
693 assert(false && "we cannot support this type");
694 }
695
696 u32_t range_val = size / elemSize;
697 for (u32_t index = 0; index < range_val; index++)
698 {
699 // dead loop for string and break if there's a \0. If no \0, it will throw err.
700 if (as.inVarToAddrsTable(dstId))
701 {
702 AbstractValue lhs_gep = as.getGepObjAddrs(dstId, IntervalValue(index));
703 for (const auto &addr: lhs_gep.getAddrs())
704 {
705 u32_t objId = as.getIDFromAddr(addr);
706 if (as.inAddrToValTable(objId))
707 {
708 AbstractValue tmp = as.load(addr);
710 as.store(addr, tmp);
711 }
712 else
713 {
714 as.store(addr, elem);
715 }
716 }
717 }
718 else
719 break;
720 }
721}
722
735{
736 if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
737 {
738 u32_t bits = type->getByteSize() * 8;
739 s64_t ub = 0;
740 s64_t lb = 0;
741 if (bits >= 32)
742 {
743 if (intType->isSigned())
744 {
745 ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
746 lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
747 }
748 else
749 {
750 ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
751 lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
752 }
753 }
754 else if (bits == 16)
755 {
756 if (intType->isSigned())
757 {
758 ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
759 lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
760 }
761 else
762 {
763 ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
764 lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
765 }
766 }
767 else if (bits == 8)
768 {
769 if (intType->isSigned())
770 {
771 ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
772 lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
773 }
774 else
775 {
776 ub = static_cast<s64_t>(std::numeric_limits<u_int8_t>::max());
777 lb = static_cast<s64_t>(std::numeric_limits<u_int8_t>::min());
778 }
779 }
780 return IntervalValue(lb, ub);
781 }
782 else if (SVFUtil::isa<SVFOtherType>(type))
783 {
784 // handle other type like float double, set s32_t as the range
785 s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
786 s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
787 return IntervalValue(lb, ub);
788 }
789 else
790 {
791 return IntervalValue::top();
792 // other types, return top interval
793 }
794}
#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:43
const std::vector< std::string > & getExtFuncAnnotations(const FunObjVar *fun)
Definition ExtAPI.cpp:199
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:39
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:254
bool isPointerTy() const
Definition SVFType.h:249
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::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