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 AbstractState& as = getAbsStateFromTrace(callNode); \
48 u32_t rhs_id = callNode->getArgument(0)->getId(); \
49 if (!as.inVarToValTable(rhs_id)) return; \
50 u32_t rhs = as[rhs_id].getInterval().lb().getIntNumeral(); \
51 s32_t res = FUNC_NAME(rhs); \
52 u32_t lhsId = callNode->getRetICFGNode()->getActualRet()->getId(); \
53 as[lhsId] = IntervalValue(res); \
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 {
80 u32_t arg0 = callNode->getArgument(0)->getId();
82 if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
83 {
84 SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
85 }
86 else
87 {
88 SVFUtil::errs() << SVFUtil::errMsg("Assertion failure, this svf_assert cannot be verified!!\n") << callNode->toString() << "\n";
89 assert(false);
90 }
91 return;
92 };
93 func_map["svf_assert"] = sse_svf_assert;
94
95 auto svf_assert_eq = [this](const CallICFGNode* callNode)
96 {
97 u32_t arg0 = callNode->getArgument(0)->getId();
98 u32_t arg1 = callNode->getArgument(1)->getId();
100 if (as[arg0].getInterval().equals(as[arg1].getInterval()))
101 {
102 SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
103 }
104 else
105 {
106 SVFUtil::errs() <<"svf_assert_eq Fail. " << callNode->toString() << "\n";
107 assert(false);
108 }
109 return;
110 };
111 func_map["svf_assert_eq"] = svf_assert_eq;
112
113 auto svf_print = [&](const CallICFGNode* callNode)
114 {
115 if (callNode->arg_size() < 2) return;
117 u32_t num_id = callNode->getArgument(0)->getId();
118 std::string text = strRead(as, callNode->getArgument(1));
119 assert(as.inVarToValTable(num_id) && "print() should pass integer");
120 IntervalValue itv = as[num_id].getInterval();
121 std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
122 << ", PrintVal: " << itv.toString() << ", Loc:" << callNode->getSourceLoc() << std::endl;
123 return;
124 };
125 func_map["svf_print"] = svf_print;
126
127 auto svf_set_value = [&](const CallICFGNode* callNode)
128 {
129 if (callNode->arg_size() < 2) return;
131 AbstractValue& num = as[callNode->getArgument(0)->getId()];
132 AbstractValue& lb = as[callNode->getArgument(1)->getId()];
133 AbstractValue& ub = as[callNode->getArgument(2)->getId()];
135 num.getInterval().set_to_top();
136 num.getInterval().meet_with(IntervalValue(lb.getInterval().lb(), ub.getInterval().ub()));
137 const ICFGNode* node = SVFUtil::cast<ValVar>(callNode->getArgument(0))->getICFGNode();
138 for (const SVFStmt* stmt: node->getSVFStmts())
139 {
140 if (SVFUtil::isa<LoadStmt>(stmt))
141 {
142 const LoadStmt* load = SVFUtil::cast<LoadStmt>(stmt);
143 NodeID rhsId = load->getRHSVarID();
144 as.storeValue(rhsId, num);
145 }
146 }
147 return;
148 };
149 func_map["set_value"] = svf_set_value;
150
151 auto sse_scanf = [&](const CallICFGNode* callNode)
152 {
154 //scanf("%d", &data);
155 if (callNode->arg_size() < 2) return;
156
157 u32_t dst_id = callNode->getArgument(1)->getId();
158 if (!as.inVarToAddrsTable(dst_id))
159 {
160 return;
161 }
162 else
163 {
165 for (auto vaddr: Addrs.getAddrs())
166 {
167 u32_t objId = as.getIDFromAddr(vaddr);
169 as.store(vaddr, range);
170 }
171 }
172 };
173 auto sse_fscanf = [&](const CallICFGNode* callNode)
174 {
175 //fscanf(stdin, "%d", &data);
176 if (callNode->arg_size() < 3) return;
178 u32_t dst_id = callNode->getArgument(2)->getId();
179 if (!as.inVarToAddrsTable(dst_id))
180 {
181 }
182 else
183 {
185 for (auto vaddr: Addrs.getAddrs())
186 {
187 u32_t objId = as.getIDFromAddr(vaddr);
189 as.store(vaddr, range);
190 }
191 }
192 };
193
194 func_map["__isoc99_fscanf"] = sse_fscanf;
195 func_map["__isoc99_scanf"] = sse_scanf;
196 func_map["__isoc99_vscanf"] = sse_scanf;
197 func_map["fscanf"] = sse_fscanf;
198 func_map["scanf"] = sse_scanf;
199 func_map["sscanf"] = sse_scanf;
200 func_map["__isoc99_sscanf"] = sse_scanf;
201 func_map["vscanf"] = sse_scanf;
202
203 auto sse_fread = [&](const CallICFGNode *callNode)
204 {
205 if (callNode->arg_size() < 3) return;
207 u32_t block_count_id = callNode->getArgument(2)->getId();
208 u32_t block_size_id = callNode->getArgument(1)->getId();
210 IntervalValue block_size = as[block_size_id].getInterval();
212 };
213 func_map["fread"] = sse_fread;
214
215 auto sse_sprintf = [&](const CallICFGNode *callNode)
216 {
217 // printf is difficult to predict since it has no byte size arguments
218 };
219
220 auto sse_snprintf = [&](const CallICFGNode *callNode)
221 {
222 if (callNode->arg_size() < 2) return;
224 u32_t size_id = callNode->getArgument(1)->getId();
225 u32_t dst_id = callNode->getArgument(0)->getId();
226 // get elem size of arg2
227 u32_t elemSize = 1;
228 if (callNode->getArgument(2)->getType()->isArrayTy())
229 {
230 elemSize = SVFUtil::dyn_cast<SVFArrayType>(
231 callNode->getArgument(2)->getType())->getTypeOfElement()->getByteSize();
232 }
233 else if (callNode->getArgument(2)->getType()->isPointerTy())
234 {
235 elemSize = as.getPointeeElement(callNode->getArgument(2)->getId())->getByteSize();
236 }
237 else
238 {
239 return;
240 // assert(false && "we cannot support this type");
241 }
242 IntervalValue size = as[size_id].getInterval() * IntervalValue(elemSize) - IntervalValue(1);
243 if (!as.inVarToAddrsTable(dst_id))
244 {
245 }
246 };
247 func_map["__snprintf_chk"] = sse_snprintf;
248 func_map["__vsprintf_chk"] = sse_sprintf;
249 func_map["__sprintf_chk"] = sse_sprintf;
250 func_map["snprintf"] = sse_snprintf;
251 func_map["sprintf"] = sse_sprintf;
252 func_map["vsprintf"] = sse_sprintf;
253 func_map["vsnprintf"] = sse_snprintf;
254 func_map["__vsnprintf_chk"] = sse_snprintf;
255 func_map["swprintf"] = sse_snprintf;
256 func_map["_snwprintf"] = sse_snprintf;
257
258
259 auto sse_itoa = [&](const CallICFGNode* callNode)
260 {
261 // itoa(num, ch, 10);
262 // num: int, ch: char*, 10 is decimal
263 if (callNode->arg_size() < 3) return;
265 u32_t num_id = callNode->getArgument(0)->getId();
266
267 u32_t num = (u32_t) as[num_id].getInterval().getNumeral();
268 std::string snum = std::to_string(num);
269 };
270 func_map["itoa"] = sse_itoa;
271
272
273 auto sse_strlen = [&](const CallICFGNode *callNode)
274 {
275 // check the arg size
276 if (callNode->arg_size() < 1) return;
277 const SVFVar* strValue = callNode->getArgument(0);
279 NodeID value_id = strValue->getId();
280 u32_t lhsId = callNode->getRetICFGNode()->getActualRet()->getId();
281 u32_t dst_size = 0;
282 for (const auto& addr : as[value_id].getAddrs())
283 {
284 NodeID objId = as.getIDFromAddr(addr);
286 {
288 }
289 else
290 {
292 for (const SVFStmt* stmt2: addrNode->getSVFStmts())
293 {
294 if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
295 {
296 dst_size = as.getAllocaInstByteSize(addrStmt);
297 }
298 }
299 }
300 }
301 u32_t len = 0;
303 if (as.inVarToAddrsTable(dstid))
304 {
305 for (u32_t index = 0; index < dst_size; index++)
306 {
308 as.getGepObjAddrs(dstid, IntervalValue(index));
310 for (const auto &addr: expr0.getAddrs())
311 {
312 val.join_with(as.load(addr));
313 }
314 if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
315 {
316 break;
317 }
318 ++len;
319 }
320 }
321 if (len == 0)
322 {
324 }
325 else
326 {
328 }
329 };
330 func_map["strlen"] = sse_strlen;
331 func_map["wcslen"] = sse_strlen;
332
333 auto sse_recv = [&](const CallICFGNode *callNode)
334 {
335 // recv(sockfd, buf, len, flags);
336 if (callNode->arg_size() < 4) return;
338 u32_t len_id = callNode->getArgument(2)->getId();
339 IntervalValue len = as[len_id].getInterval() - IntervalValue(1);
340 u32_t lhsId = callNode->getRetICFGNode()->getActualRet()->getId();
341 as[lhsId] = len;
342 };
343 func_map["recv"] = sse_recv;
344 func_map["__recv"] = sse_recv;
345
346 auto sse_free = [&](const CallICFGNode *callNode)
347 {
348 if (callNode->arg_size() < 1) return;
350 const u32_t freePtr = callNode->getArgument(0)->getId();
351 for (auto addr: as[freePtr].getAddrs())
352 {
354 {
355 // Detected a double free — the address has already been freed.
356 // No action is taken at this point.
357 }
358 else
359 {
360 as.addToFreedAddrs(addr);
361 }
362 }
363 };
364 // Add all free-related functions to func_map
365 std::vector<std::string> freeFunctions =
366 {
367 "VOS_MemFree", "cfree", "free", "free_all_mem", "freeaddrinfo",
368 "gcry_mpi_release", "gcry_sexp_release", "globfree", "nhfree",
369 "obstack_free", "safe_cfree", "safe_free", "safefree", "safexfree",
370 "sm_free", "vim_free", "xfree", "SSL_CTX_free", "SSL_free", "XFree"
371 };
372
373 for (const auto& name : freeFunctions)
374 {
376 }
377};
378
380{
381 if (abstractTrace.count(node) == 0)
382 {
383 assert(0 && "No preAbsTrace for this node");
384 abort();
385 }
386 else
387 {
388 return abstractTrace[node];
389 }
390}
391
393{
394 // sse read string nodeID->string
395 std::string str0;
396
398 {
399 // dead loop for string and break if there's a \0. If no \0, it will throw err.
400 if (!as.inVarToAddrsTable(rhs->getId())) continue;
402 as.getGepObjAddrs(rhs->getId(), IntervalValue(index));
403
405 for (const auto &addr: expr0.getAddrs())
406 {
407 val.join_with(as.load(addr));
408 }
409 if (!val.getInterval().is_numeral())
410 {
411 break;
412 }
413 if ((char) val.getInterval().getIntNumeral() == '\0')
414 {
415 break;
416 }
417 str0.push_back((char) val.getInterval().getIntNumeral());
418 }
419 return str0;
420}
421
423{
425 const FunObjVar *fun = call->getCalledFunction();
426 assert(fun && "FunObjVar* is nullptr");
428 // get type of mem api
429 for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(fun))
430 {
431 if (annotation.find("MEMCPY") != std::string::npos)
432 extType = MEMCPY;
433 if (annotation.find("MEMSET") != std::string::npos)
434 extType = MEMSET;
435 if (annotation.find("STRCPY") != std::string::npos)
436 extType = STRCPY;
437 if (annotation.find("STRCAT") != std::string::npos)
438 extType = STRCAT;
439 }
440 if (extType == UNCLASSIFIED)
441 {
442 if (func_map.find(fun->getName()) != func_map.end())
443 {
444 func_map[fun->getName()](call);
445 }
446 else
447 {
448 if (const SVFVar* ret = call->getRetICFGNode()->getActualRet())
449 {
450 u32_t lhsId = ret->getId();
451 if (as.inVarToAddrsTable(lhsId))
452 {
453
454 }
455 else
456 {
458 }
459 }
460 return;
461 }
462 }
463 // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
464 else if (extType == MEMCPY)
465 {
466 IntervalValue len = as[call->getArgument(2)->getId()].getInterval();
467 svfir->getGNode(call->getArgument(0)->getId());
468 handleMemcpy(as, call->getArgument(0), call->getArgument(1), len, 0);
469 }
470 else if (extType == MEMSET)
471 {
472 // memset dst is arg0, elem is arg1, size is arg2
473 IntervalValue len = as[call->getArgument(2)->getId()].getInterval();
474 IntervalValue elem = as[call->getArgument(1)->getId()].getInterval();
475 handleMemset(as, call->getArgument(0), elem, len);
476 }
477 else if (extType == STRCPY)
478 {
479 handleStrcpy(call);
480 }
481 else if (extType == STRCAT)
482 {
483 handleStrcat(call);
484 }
485 else
486 {
487
488 }
489 return;
490}
491
493{
494 // strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk
495 // get the dst and src
497 const SVFVar* arg0Val = call->getArgument(0);
498 const SVFVar* arg1Val = call->getArgument(1);
500 // no need to -1, since it has \0 as the last byte
501 handleMemcpy(as, arg0Val, arg1Val, strLen, strLen.lb().getIntNumeral());
502}
503
505{
506 NodeID value_id = strValue->getId();
507 u32_t dst_size = 0;
508 for (const auto& addr : as[value_id].getAddrs())
509 {
510 NodeID objId = as.getIDFromAddr(addr);
512 {
514 }
515 else
516 {
517 const ICFGNode* icfgNode = svfir->getBaseObject(objId)->getICFGNode();
518 for (const SVFStmt* stmt2: icfgNode->getSVFStmts())
519 {
520 if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
521 {
522 dst_size = as.getAllocaInstByteSize(addrStmt);
523 }
524 }
525 }
526 }
527 u32_t len = 0;
528 u32_t elemSize = 1;
529 if (as.inVarToAddrsTable(value_id))
530 {
531 for (u32_t index = 0; index < dst_size; index++)
532 {
534 as.getGepObjAddrs(value_id, IntervalValue(index));
536 for (const auto &addr: expr0.getAddrs())
537 {
538 val.join_with(as.load(addr));
539 }
540 if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
541 {
542 break;
543 }
544 ++len;
545 }
546 if (strValue->getType()->isArrayTy())
547 {
548 elemSize = SVFUtil::dyn_cast<SVFArrayType>(strValue->getType())->getTypeOfElement()->getByteSize();
549 }
550 else if (strValue->getType()->isPointerTy())
551 {
552 if (const SVFType* elemType = as.getPointeeElement(value_id))
553 {
554 if (elemType->isArrayTy())
555 elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
556 else
557 elemSize = elemType->getByteSize();
558 }
559 else
560 {
561 elemSize = 1;
562 }
563 }
564 else
565 {
566 assert(false && "we cannot support this type");
567 }
568 }
569 if (len == 0)
570 {
572 }
573 else
574 {
575 return IntervalValue(len * elemSize);
576 }
577}
578
579
581{
582 // __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat
583 // to check it is strcat group or strncat group
585 const FunObjVar *fun = call->getCalledFunction();
586 const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
587 const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
588 if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
589 {
590 const SVFVar* arg0Val = call->getArgument(0);
591 const SVFVar* arg1Val = call->getArgument(1);
595 handleMemcpy(as, arg0Val, arg1Val, strLen1, strLen0.lb().getIntNumeral());
596 // do memcpy
597 }
598 else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
599 {
600 const SVFVar* arg0Val = call->getArgument(0);
601 const SVFVar* arg1Val = call->getArgument(1);
602 const SVFVar* arg2Val = call->getArgument(2);
603 IntervalValue arg2Num = as[arg2Val->getId()].getInterval();
606 handleMemcpy(as, arg0Val, arg1Val, arg2Num, strLen0.lb().getIntNumeral());
607 // do memcpy
608 }
609 else
610 {
611 assert(false && "unknown strcat function, please add it to strcatGroup or strncatGroup");
612 }
613}
614
616{
617 u32_t dstId = dst->getId(); // pts(dstId) = {objid} objbar objtypeinfo->getType().
618 u32_t srcId = src->getId();
619 u32_t elemSize = 1;
620 if (dst->getType()->isArrayTy())
621 {
622 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
623 }
624 // memcpy(i32*, i32*, 40)
625 else if (dst->getType()->isPointerTy())
626 {
627 if (const SVFType* elemType = as.getPointeeElement(dstId))
628 {
629 if (elemType->isArrayTy())
630 elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
631 else
632 elemSize = elemType->getByteSize();
633 }
634 else
635 {
636 elemSize = 1;
637 }
638 }
639 else
640 {
641 assert(false && "we cannot support this type");
642 }
643 u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
644 u32_t range_val = size / elemSize;
645 if (as.inVarToAddrsTable(srcId) && as.inVarToAddrsTable(dstId))
646 {
647 for (u32_t index = 0; index < range_val; index++)
648 {
649 // dead loop for string and break if there's a \0. If no \0, it will throw err.
651 as.getGepObjAddrs(srcId, IntervalValue(index));
653 as.getGepObjAddrs(dstId, IntervalValue(index + start_idx));
654 for (const auto &dst: expr_dst.getAddrs())
655 {
656 for (const auto &src: expr_src.getAddrs())
657 {
658 u32_t objId = as.getIDFromAddr(src);
659 if (as.inAddrToValTable(objId))
660 {
661 as.store(dst, as.load(src));
662 }
663 else if (as.inAddrToAddrsTable(objId))
664 {
665 as.store(dst, as.load(src));
666 }
667 }
668 }
669 }
670 }
671}
672
674{
675 u32_t dstId = dst->getId();
676 u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
677 u32_t elemSize = 1;
678 if (dst->getType()->isArrayTy())
679 {
680 elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
681 }
682 else if (dst->getType()->isPointerTy())
683 {
684 if (const SVFType* elemType = as.getPointeeElement(dstId))
685 {
686 elemSize = elemType->getByteSize();
687 }
688 else
689 {
690 elemSize = 1;
691 }
692 }
693 else
694 {
695 assert(false && "we cannot support this type");
696 }
697
698 u32_t range_val = size / elemSize;
699 for (u32_t index = 0; index < range_val; index++)
700 {
701 // dead loop for string and break if there's a \0. If no \0, it will throw err.
702 if (as.inVarToAddrsTable(dstId))
703 {
704 AbstractValue lhs_gep = as.getGepObjAddrs(dstId, IntervalValue(index));
705 for (const auto &addr: lhs_gep.getAddrs())
706 {
707 u32_t objId = as.getIDFromAddr(addr);
708 if (as.inAddrToValTable(objId))
709 {
710 AbstractValue tmp = as.load(addr);
712 as.store(addr, tmp);
713 }
714 else
715 {
716 as.store(addr, elem);
717 }
718 }
719 }
720 else
721 break;
722 }
723}
724
737{
738 if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
739 {
740 u32_t bits = type->getByteSize() * 8;
741 s64_t ub = 0;
742 s64_t lb = 0;
743 if (bits >= 32)
744 {
745 if (intType->isSigned())
746 {
747 ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
748 lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
749 }
750 else
751 {
752 ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
753 lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
754 }
755 }
756 else if (bits == 16)
757 {
758 if (intType->isSigned())
759 {
760 ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
761 lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
762 }
763 else
764 {
765 ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
766 lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
767 }
768 }
769 else if (bits == 8)
770 {
771 if (intType->isSigned())
772 {
773 ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
774 lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
775 }
776 else
777 {
778 ub = static_cast<s64_t>(std::numeric_limits<uint8_t>::max());
779 lb = static_cast<s64_t>(std::numeric_limits<uint8_t>::min());
780 }
781 }
782 return IntervalValue(lb, ub);
783 }
784 else if (SVFUtil::isa<SVFOtherType>(type))
785 {
786 // handle other type like float double, set s32_t as the range
787 s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
788 s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
789 return IntervalValue(lb, ub);
790 }
791 else
792 {
793 return IntervalValue::top();
794 // other types, return top interval
795 }
796}
#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:42
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:35
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 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:419
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:160
virtual const SVFType * getType() const
Definition SVFValue.h:171
virtual const std::string & getName() const
Definition SVFValue.h:186
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