Static Value-Flow Analysis
Loading...
Searching...
No Matches
LLVMModule.cpp
Go to the documentation of this file.
1//===----- SVFModule.cpp Base class of pointer analyses ---------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <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 * LLVMModule.cpp
25 *
26 * Created on: Aug 4, 2017
27 * Author: Yulei Sui
28 * Refactored on: Jan 25, 2024
29 * Author: Xiao Cheng, Yulei Sui
30 */
31
32#include <queue>
33#include <algorithm>
34#include "Util/SVFUtil.h"
35#include "SVF-LLVM/BasicTypes.h"
36#include "SVF-LLVM/LLVMUtil.h"
37#include "SVF-LLVM/CppUtil.h"
40#include "MSSA/SVFGBuilder.h"
41#include "llvm/Support/FileSystem.h"
43#include "llvm/Transforms/Utils/Cloning.h"
45#include "Graphs/CallGraph.h"
47
48#if LLVM_VERSION_MAJOR > 16
49#include <llvm/Passes/PassBuilder.h>
50#endif
51
52using namespace std;
53using namespace SVF;
54
55/*
56 svf.main() is used to model the real entry point of a C++ program, which
57 initializes all global C++ objects and then call main().
58 LLVM may generate two global arrays @llvm.global_ctors and @llvm.global_dtors
59 that contain constructor and destructor functions for global variables. They
60 are not called explicitly, so we have to add them in the svf.main function.
61 The order to call these constructor and destructor functions are also
62 specified in the global arrays.
63 Related part in LLVM language reference:
64 https://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable
65 For example, given a "int main(int argc, char * argv[])", the corresponding
66 svf.main will be generated as follows:
67 define void @svf.main(i32, i8**, i8**) {
68 entry:
69 call void @ctor1()
70 call void @ctor2()
71 %3 = call i32 @main(i32 %0, i8** %1)
72 call void @dtor1()
73 call void @dtor2()
74 ret void
75 }
76*/
77
78#define SVF_MAIN_FUNC_NAME "svf.main"
79#define SVF_GLOBAL_CTORS "llvm.global_ctors"
80#define SVF_GLOBAL_DTORS "llvm.global_dtors"
81
84
86 : svfir(PAG::getPAG()), typeInference(new ObjTypeInference())
87{
88}
89
91{
92
93 delete typeInference;
94 typeInference = nullptr;
95
96}
97
102
104{
105 auto it = FunToDominatorTree.find(fun);
106 if(it != FunToDominatorTree.end()) return it->second;
108 dt.recalculate(const_cast<Function&>(*fun));
109 return dt;
110}
111
113{
115
116 double startSVFModuleTime = SVFStat::getClk(true);
117 PAG::getPAG()->setModuleIdentifier(mod.getModuleIdentifier());
118 mset->modules.emplace_back(mod); // Populates `modules`; can get context via `this->getContext()`
119 mset->loadExtAPIModules(); // Uses context from module through `this->getContext()`
120 mset->build();
121 double endSVFModuleTime = SVFStat::getClk(true);
123
124 mset->buildSymbolTable();
125}
126
127void LLVMModuleSet::buildSVFModule(const std::vector<std::string> &moduleNameVec)
128{
129 double startSVFModuleTime = SVFStat::getClk(true);
130
132
133 mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()`
134 mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()`
135
136 if (!moduleNameVec.empty())
137 {
139 }
140
141 mset->build();
142
143 double endSVFModuleTime = SVFStat::getClk(true);
146
147 mset->buildSymbolTable();
148}
149
151{
152 double startSymInfoTime = SVFStat::getClk(true);
154 {
156 DBOUT(DGENERAL, SVFUtil::outs() << SVFUtil::pasMsg("Building Symbol table ...\n"));
158 builder.buildMemModel();
159 }
160 double endSymInfoTime = SVFStat::getClk(true);
163}
164
166{
167 if (!empty())
168 {
171 }
172
173 if(preProcessed==false)
175
178
179 if (Options::SVFMain())
180 addSVFMain();
181
183
184}
185
187{
190 // Functions need to be retrieved in the order of insertion
191 // candidateDefs is the vector for all used defined functions
192 // candidateDecls is the vector for all used declared functions
193 std::vector<const Function*> candidateDefs, candidateDecls;
194
195 for (Module& mod : modules)
196 {
198 for (Function& func : mod.functions())
199 {
200 if (func.isDeclaration())
201 {
202 candidateDecls.push_back(&func);
203 }
204 else
205 {
206 candidateDefs.push_back(&func);
207 }
208 }
209 }
210
211 for (const Function* func: candidateDefs)
212 {
214 }
215 for (const Function* func: candidateDecls)
216 {
218 }
219
220 // set function exit block
221 for (const auto& func: funSet)
222 {
223 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
224 {
225 const BasicBlock* bb = &*bit;
227 if (succ_size(bb) == 0)
228 {
230 {
232 SVFUtil::isa<ReturnInst>(bb->back())) &&
233 "last inst must be return inst");
234 setFunExitBB(func, bb);
235 }
236 }
237 }
238 // For no return functions, we set the last block as exit BB
239 // This ensures that each function that has definition must have an exit BB
240 if (func->size() != 0 && !getFunExitBB(func))
241 {
243 SVFUtil::isa<ReturnInst>(&func->back().back())) &&
244 "last inst must be return inst");
245 setFunExitBB(func, &func->back());
246 }
247 }
248
249 // Store annotations of functions in extapi.bc
250 for (const auto& pair : ExtFun2Annotations)
251 {
252 const Function* fun = getFunction(pair.first);
253 setExtFuncAnnotations(fun, pair.second);
254 }
255
256}
257
262{
264 std::unique_ptr<BreakConstantGEPs> p1 = std::make_unique<BreakConstantGEPs>();
265 for (Module &M : getLLVMModules())
266 {
267 p1->runOnModule(M);
268 }
269
271 std::unique_ptr<UnifyFunctionExitNodes> p2 =
272 std::make_unique<UnifyFunctionExitNodes>();
273 for (Module &M : getLLVMModules())
274 {
275 for (auto F = M.begin(), E = M.end(); F != E; ++F)
276 {
277 Function &fun = *F;
278 if (fun.isDeclaration())
279 continue;
280#if LLVM_VERSION_MAJOR <= 16
281 p2->runOnFunction(fun);
282#else
283 llvm::PassBuilder PB;
284 llvm::LoopAnalysisManager LAM;
285 llvm::FunctionAnalysisManager FAM;
286 llvm::CGSCCAnalysisManager CGAM;
287 llvm::ModuleAnalysisManager MAM;
288 PB.registerModuleAnalyses(MAM);
289 PB.registerCGSCCAnalyses(CGAM);
290 PB.registerFunctionAnalyses(FAM);
291 PB.registerLoopAnalyses(LAM);
292 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
293 llvm::FunctionPassManager FPM;
294 FPM.addPass(llvm::UnifyFunctionExitNodesPass());
295 FPM.run(fun, FAM);
296#endif
297 }
298 }
299}
300
301void LLVMModuleSet::preProcessBCs(std::vector<std::string> &moduleNameVec)
302{
304 mset->loadModules(moduleNameVec);
305 mset->loadExtAPIModules();
306 mset->prePassSchedule();
307
308 std::string preProcessSuffix = ".pre.bc";
309 // Get the existing module names, remove old extension, add preProcessSuffix
310 for (u32_t i = 0; i < moduleNameVec.size(); i++)
311 {
312 u32_t lastIndex = moduleNameVec[i].find_last_of(".");
313 std::string rawName = moduleNameVec[i].substr(0, lastIndex);
315 }
316
317 mset->dumpModulesToFile(preProcessSuffix);
318 preProcessed = true;
320}
321
322void LLVMModuleSet::loadModules(const std::vector<std::string> &moduleNameVec)
323{
324
325 // We read SVFIR from LLVM IR
327 {
328 if(moduleNameVec.empty())
329 {
330 SVFUtil::outs() << "no LLVM bc file is found!\n";
331 exit(0);
332 }
333 //assert(!moduleNameVec.empty() && "no LLVM bc file is found!");
334 }
335 // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
336 else
337 {
339 }
340 //
341 // LLVMContext objects separate global LLVM settings (from which e.g. types are
342 // derived); multiple LLVMContext objects can coexist and each context can "own"
343 // multiple modules (modules can only have one context). Mixing contexts can lead
344 // to unintended inequalities, such as the following:
345 //
346 // ------------------------------------------------------------------
347 // LLVMContext ctxa,ctxb;
348 // IntegerType * t1 = IntegerType::get(ctxa,32);
349 // IntegerType * t2 = IntegerType::get(ctxa,32);
350 // assert(t1 == t2);
351 // IntegerType * t3 = IntegerType::get(ctxb,32);
352 // IntegerType * t4 = IntegerType::get(ctxb,32);
353 // assert(t3 == t4);
354 // assert(t1 != t3);
355 // ------------------------------------------------------------------
356 //
357 // When loading bytecode files, SVF will use the same LLVMContext object for all
358 // modules (i.e. the context owns all loaded modules). This applies to ExtAPI as
359 // well, which *must* be loaded using the same LLVMContext object. Hence, when
360 // loading modules from bitcode files, a new LLVMContext is created (using a
361 // `std::unique_ptr<LLVMContext>` type to ensure automatic garbage collection).
362 //
363 // This garbage collection should be avoided when building an SVF module from an LLVM
364 // module instance; see the comment(s) in `buildSVFModule` and `loadExtAPIModules()`
365
366 owned_ctx = std::make_unique<LLVMContext>();
367 for (const std::string& moduleName : moduleNameVec)
368 {
369 if (!LLVMUtil::isIRFile(moduleName))
370 {
371 SVFUtil::errs() << "not an IR file: " << moduleName << std::endl;
372 abort();
373 }
374
376 std::unique_ptr<Module> mod = parseIRFile(moduleName, Err, *owned_ctx);
377 if (mod == nullptr)
378 {
379 SVFUtil::errs() << "load module: " << moduleName << "failed!!\n\n";
380 Err.print("SVFModuleLoader", llvm::errs());
381 abort();
382 }
383 modules.emplace_back(*mod);
384 owned_modules.emplace_back(std::move(mod));
385 }
386}
387
389{
390 // This function loads the ExtAPI bitcode file as an LLVM module. Note that it is important that
391 // the same LLVMContext object is used to load this bitcode file as is used by the other modules
392 // being analysed.
393 // When the modules are loaded from bitcode files (i.e. passing filenames to files containing
394 // LLVM IR to `buildSVFModule({file1.bc, file2.bc, ...})) the context is created while loading
395 // the modules in `loadModules()`, which populates this->modules and this->owned_modules.
396 // If, however, an LLVM Module object is passed to `buildSVFModule` (e.g. from an LLVM pass),
397 // the context should be retrieved from the module itself (note that the garbage collection from
398 // `std::unique_ptr<LLVMContext> LLVMModuleSet::owned_ctx` should be avoided in this case). This
399 // function populates only this->modules.
400 // In both cases, fetching the context from the main LLVM module (through `getContext`) works
401 assert(!empty() && "LLVMModuleSet contains no modules; cannot load ExtAPI module without LLVMContext!");
402
403 // Load external API module (extapi.bc)
404 if (!ExtAPI::getExtAPI()->getExtBcPath().empty())
405 {
408 {
409 SVFUtil::errs() << "not an external IR file: " << extModuleName << std::endl;
410 abort();
411 }
413 std::unique_ptr<Module> mod = parseIRFile(extModuleName, Err, getContext());
414 if (mod == nullptr)
415 {
416 SVFUtil::errs() << "load external module: " << extModuleName << "failed!!\n\n";
417 Err.print("SVFModuleLoader", llvm::errs());
418 abort();
419 }
420 // The module of extapi.bc needs to be inserted before applications modules, like std::vector<std::reference_wrapper<Module>> modules{extapi_module, app_module}.
421 // Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found.
422 modules.insert(modules.begin(), *mod);
423 owned_modules.insert(owned_modules.begin(),std::move(mod));
424 }
425}
426
428{
429 // This function is used to extract constructor and destructor functions
430 // sorted by their priority from @llvm.global_ctors or @llvm.global_dtors.
431 // For example, given following @llvm.global_ctors, the returning sorted
432 // function list should be [ctor3, ctor1, ctor2].
433 // ------------------------------------------------------------------
434 // ; Each struct in the array is {priority, function, associated data}
435 //
436 // @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }]
437 // [{ i32, void ()*, i8* } { i32 1234, void ()* @ctor1.cpp, i8* null },
438 // { i32, void ()*, i8* } { i32 2345, void ()* @ctor2.cpp, i8* null },
439 // { i32, void ()*, i8* } { i32 345, void ()* @ctor3.cpp, i8* null }]
440 // ------------------------------------------------------------------
441 // TODO: According to LLVM language reference, if the third field is
442 // non-null, and points to a global variable or function, the initializer
443 // function will only run if the associated data from the current module is
444 // not discarded. However the associated data is currently ignored.
445
446
447 // This class is used for the priority queue that sorts the functions by
448 // their priority. Each object of this class stands for an item in the
449 // function array.
451 {
452 public:
454 const Function* func;
458 bool operator>(const LLVMGlobalFunction &other) const
459 {
460 if (priority != other.priority)
461 {
462 return priority > other.priority;
463 }
464 else
465 {
466 return func > other.func;
467 }
468 }
469 };
470
471 std::priority_queue<LLVMGlobalFunction, std::vector<LLVMGlobalFunction>,
473 queue;
474 std::vector<const Function* > result;
475
476 // The @llvm.global_ctors/dtors global variable is an array of struct. Each
477 // struct has three fields: {i32 priority, void ()* @ctor/dtor, i8* @data}.
478 // First get the array here.
480 SVFUtil::dyn_cast<ConstantArray>(global->getInitializer()))
481 {
482 // Get each struct in the array.
483 for (unsigned int i = 0; i < globalFuncArray->getNumOperands(); ++i)
484 {
485 if (
487 SVFUtil::dyn_cast<ConstantStruct>(
488 globalFuncArray->getOperand(i)))
489 {
490
491 // Extract priority and function from the struct
492 const ConstantInt* priority = SVFUtil::dyn_cast<ConstantInt>(
493 globalFuncItem->getOperand(0));
494 const Function* func = SVFUtil::dyn_cast<Function>(
495 globalFuncItem->getOperand(1));
496
497 if (priority && func)
498 {
500 func));
501 }
502 }
503 }
504 }
505
506 // Generate a sorted vector of functions from the priority queue.
507 while (!queue.empty())
508 {
509 result.push_back(queue.top().func);
510 queue.pop();
511 }
512 return result;
513}
514
516{
517 std::vector<const Function*> ctor_funcs;
518 std::vector<const Function*> dtor_funcs;
519 Function* orgMain = 0;
520 Module* mainMod = nullptr;
521
522 for (Module &mod : modules)
523 {
524 // Collect ctor and dtor functions
525 for (const GlobalVariable& global : mod.globals())
526 {
527 if (global.getName() == SVF_GLOBAL_CTORS && global.hasInitializer())
528 {
530 }
531 else if (global.getName() == SVF_GLOBAL_DTORS && global.hasInitializer())
532 {
534 }
535 }
536
537 // Find main function
538 for (auto &func : mod)
539 {
540 auto funName = func.getName();
541
542 assert(!(funName == SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
543
544 if (funName == "main")
545 {
546 orgMain = &func;
547 mainMod = &mod;
548 }
549 }
550 }
551
552 // Only create svf.main when the original main function is found, and also
553 // there are global constructor or destructor functions.
554 if (orgMain && getModuleNum() > 0 &&
555 (ctor_funcs.size() > 0 || dtor_funcs.size() > 0))
556 {
557 assert(mainMod && "Module with main function not found.");
558 Module& M = *mainMod;
559 // char **
560 Type* ptr = PointerType::getUnqual(M.getContext());
561 Type* i32 = IntegerType::getInt32Ty(M.getContext());
562 // define void @svf.main(i32, i8**, i8**)
563#if (LLVM_VERSION_MAJOR >= 9)
564 FunctionCallee svfmainFn = M.getOrInsertFunction(
566 Type::getVoidTy(M.getContext()),
567 i32,ptr,ptr
568 );
569 Function* svfmain = SVFUtil::dyn_cast<Function>(svfmainFn.getCallee());
570#else
571 Function* svfmain = SVFUtil::dyn_cast<Function>(M.getOrInsertFunction(
573 Type::getVoidTy(M.getContext()),
575 ));
576#endif
577 svfmain->setCallingConv(llvm::CallingConv::C);
578 BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", svfmain);
580 // emit "call void @ctor()". ctor_funcs is sorted so the functions are
581 // emitted in the order of priority
582 for (auto& ctor : ctor_funcs)
583 {
584 auto target = M.getOrInsertFunction(
585 ctor->getName(),
586 Type::getVoidTy(M.getContext())
587 );
588 Builder.CreateCall(target);
589 }
590 // main() should be called after all ctor functions and before dtor
591 // functions.
592 Function::arg_iterator arg_it = svfmain->arg_begin();
593 Value* args[] = {arg_it, arg_it + 1, arg_it + 2};
594 size_t cnt = orgMain->arg_size();
595 assert(cnt <= 3 && "Too many arguments for main()");
596 Builder.CreateCall(orgMain, llvm::ArrayRef<Value*>(args, args + cnt));
597 // emit "call void @dtor()". dtor_funcs is sorted so the functions are
598 // emitted in the order of priority
599 for (auto& dtor : dtor_funcs)
600 {
601 auto target = M.getOrInsertFunction(dtor->getName(), Type::getVoidTy(M.getContext()));
602 Builder.CreateCall(target);
603 }
604 // return;
605 Builder.CreateRetVoid();
606 }
607 else
608 {
609 // use SVF::Options to record whether svf.main is added or not
611 }
612}
613
615{
616 GlobalVariable *glob = mod->getGlobalVariable("llvm.global.annotations");
617 if (glob == nullptr || !glob->hasInitializer())
618 return;
619
620 ConstantArray *ca = SVFUtil::dyn_cast<ConstantArray>(glob->getInitializer());
621 if (ca == nullptr)
622 return;
623
624 for (unsigned i = 0; i < ca->getNumOperands(); ++i)
625 {
626 ConstantStruct *structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
627 if (structAn == nullptr || structAn->getNumOperands() == 0)
628 continue;
629
630 // Check if the annotation is for a function
631 Function* fun = nullptr;
632 GlobalVariable *annotateStr = nullptr;
634 if (ConstantExpr *expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0)))
635 {
636 if (expr->getOpcode() == Instruction::BitCast && SVFUtil::isa<Function>(expr->getOperand(0)))
637 fun = SVFUtil::cast<Function>(expr->getOperand(0));
638
639 ConstantExpr *note = SVFUtil::cast<ConstantExpr>(structAn->getOperand(1));
640 if (note->getOpcode() != Instruction::GetElementPtr)
641 continue;
642
643 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(note->getOperand(0));
644 }
646 else
647 {
648 fun = SVFUtil::dyn_cast<Function>(structAn->getOperand(0));
649 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(structAn->getOperand(1));
650 }
651
652 if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer())
653 continue;;
654
655 ConstantDataSequential *data = SVFUtil::dyn_cast<ConstantDataSequential>(annotateStr->getInitializer());
656 if (data && data->isString())
657 {
658 std::string annotation = data->getAsString().str();
659 if (!annotation.empty())
660 ExtFun2Annotations[fun->getName().str()].push_back(annotation);
661 }
662 }
663}
664
665/*
666 There are three types of functions(definitions) in extapi.c:
667 1. (Fun_Overwrite): Functions with "OVERWRITE" annotion:
668 These functions are used to replace the corresponding function definitions in the application.
669 2. (Fun_Annotation): Functions with annotation(s) but without "OVERWRITE" annotation:
670 These functions are used to tell SVF to do special processing, like malloc().
671 3. (Fun_Noraml): Functions without any annotation:
672 These functions are used to replace the corresponding function declarations in the application.
673
674
675 We will iterate over declarations (appFunDecl) and definitons (appFunDef) of functions in the application and extapi.c to do the following clone or replace operations:
676 1. appFuncDecl --> Fun_Normal: Clone the Fun_Overwrite and replace the appFuncDecl in application.
677 2. appFuncDecl --> Fun_Annotation: Move the annotions on Fun_Annotation to appFuncDecl in application.
678
679 3. appFunDef --> Fun_Overwrite: Clone the Fun_Overwrite and overwrite the appFunDef in application.
680 4. appFunDef --> Fun_Annotation: Replace the appFunDef with appFunDecl and move the annotions to appFunDecl in application
681*/
683{
687 Module* appModule = nullptr;
688 Module* extModule = nullptr;
689
690 for (Module& mod : modules)
691 {
692 // extapi.bc functions
693 if (mod.getName().str() == ExtAPI::getExtAPI()->getExtBcPath())
694 {
696 extModule = &mod;
697 for (const Function& fun : mod.functions())
698 {
699 // there is main declaration in ext bc, it should be mapped to
700 // main definition in app bc.
701 if (fun.getName().str() == "main")
702 {
703 appFunDecls.insert(&fun);
704 appFuncDeclNames.insert(fun.getName().str());
705 }
707 else if (fun.getName().str() == "svf__main")
708 {
709 ExtFuncsVec.push_back(&fun);
710 }
711 else
712 {
713 extFuncs.insert(&fun);
714 extFunDefNames.insert(fun.getName().str());
715 }
716 }
717 }
718 else
719 {
720 appModule = &mod;
722 for (const Function& fun : mod.functions())
723 {
724 if (fun.isDeclaration())
725 {
726 appFunDecls.insert(&fun);
727 appFuncDeclNames.insert(fun.getName().str());
728 }
729 else
730 {
731 appFunDefs.insert(&fun);
732 appFuncDefNames.insert(fun.getName().str());
733 }
734 }
735 }
736 }
737
738 // Find the intersectNames between appFuncDefNames and externalFunDefNames
739 std::set_intersection(
740 appFuncDefNames.begin(), appFuncDefNames.end(), extFunDefNames.begin(), extFunDefNames.end(),
741 std::inserter(intersectNames, intersectNames.end()));
742
744 {
745 assert(!(appFunToReplace == NULL && appModule == NULL) && "appFunToReplace and appModule cannot both be NULL");
746
747 if (appFunToReplace)
748 {
749 appModule = appFunToReplace->getParent();
750 }
751 Function* clonedFunction = Function::Create(extFunToClone->getFunctionType(),
752 Function::ExternalLinkage,
753 extFunToClone->getName());
754 // Map the arguments of the new function to the arguments of extFunToClone
755 llvm::ValueToValueMapTy valueMap;
756 Function::arg_iterator destArg = clonedFunction->arg_begin();
757 for (Function::const_arg_iterator srcArg = extFunToClone->arg_begin(); srcArg != extFunToClone->arg_end(); ++srcArg)
758 {
759 destArg->setName(srcArg->getName()); // Copy the name of the original argument
760 valueMap[&*srcArg] = &*destArg++; // Add a mapping from the old arg to the new arg
761 }
762 if (cloneBody)
763 {
764 // Collect global variables referenced by extFunToClone
765 // This step identifies all global variables used within the function to be cloned
766 std::set<GlobalVariable*> referencedGlobals;
767 for (const BasicBlock& BB : *extFunToClone)
768 {
769 for (const Instruction& I : BB)
770 {
771 for (const Value* operand : I.operands())
772 {
773 // Check if the operand is a global variable
774 if (const GlobalVariable* GV = SVFUtil::dyn_cast<GlobalVariable>(operand))
775 {
776 referencedGlobals.insert(const_cast<GlobalVariable*>(GV));
777 }
778 }
779 }
780 }
781
782 // Copy global variables to target module and update valueMap
783 // When cloning a function, we need to ensure all global variables it references are available in the target module
785 {
786 // Check if the global variable already exists in the target module
787 GlobalVariable* existingGV = appModule->getGlobalVariable(GV->getName());
788 if (existingGV)
789 {
790 // If the global variable already exists, ensure type consistency
791 assert(existingGV->getType() == GV->getType() && "Global variable type mismatch in client module!");
792 // Map the original global to the existing one in the target module
793 valueMap[GV] = existingGV; // Map to existing global variable
794 }
795 else
796 {
797 // If the global variable doesn't exist in the target module, create a new one with the same properties
799 *appModule, // Target module
800 GV->getValueType(), // Type of the global variable
801 GV->isConstant(), // Whether it's constant
802 GV->getLinkage(), // Linkage type
803 nullptr, // No initializer yet
804 GV->getName(), // Same name
805 nullptr, // No insert before instruction
806 GV->getThreadLocalMode(), // Thread local mode
807 GV->getAddressSpace() // Address space
808 );
809
810 // Copy initializer if present to maintain the global's value
811 if (GV->hasInitializer())
812 {
813 Constant* init = GV->getInitializer();
814 newGV->setInitializer(init); // Simple case: direct copy
815 }
816
817 // Copy other attributes like alignment to ensure identical behavior
818 newGV->copyAttributesFrom(GV);
819
820 // Add mapping from original global to the new one for use during function cloning
821 valueMap[GV] = newGV;
822 }
823 }
824
825 // Clone function body with updated valueMap
826 llvm::SmallVector<ReturnInst*, 8> ignoredReturns;
827 CloneFunctionInto(clonedFunction, extFunToClone, valueMap, llvm::CloneFunctionChangeType::LocalChangesOnly, ignoredReturns, "", nullptr);
828 }
829 if (appFunToReplace)
830 {
831 // Replace all uses of appFunToReplace with clonedFunction
832 appFunToReplace->replaceAllUsesWith(clonedFunction);
833 std::string oldFunctionName = appFunToReplace->getName().str();
834 // Delete the old function
835 appFunToReplace->eraseFromParent();
836 appModule->getFunctionList().push_back(clonedFunction);
838 }
839 else
840 {
841 appModule->getFunctionList().push_back(clonedFunction);
842 }
843 return clonedFunction;
844 };
845
847 for (const Function* appFunDecl : appFunDecls)
848 {
849 std::string appFunDeclName = LLVMUtil::restoreFuncName(appFunDecl->getName().str());
850 for (const Function* extFun : extFuncs)
851 {
852 if (extFun->getName().str().compare(appFunDeclName) == 0)
853 {
854 auto it = ExtFun2Annotations.find(extFun->getName().str());
855 // Without annotations, this function is normal function with useful function body
856 if (it == ExtFun2Annotations.end())
857 {
858 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFun), const_cast<Function*>(appFunDecl), nullptr, true);
861 }
862 else
863 {
864 ExtFuncsVec.push_back(appFunDecl);
865 }
866 break;
867 }
868 }
869 }
870
873 for (string sameFuncDef: intersectNames)
874 {
875 Function* appFuncDef = appModule->getFunction(sameFuncDef);
876 Function* extFuncDef = extModule->getFunction(sameFuncDef);
877 if (appFuncDef == nullptr || extFuncDef == nullptr)
878 continue;
879
880 FunctionType *appFuncDefType = appFuncDef->getFunctionType();
881 FunctionType *extFuncDefType = extFuncDef->getFunctionType();
883 continue;
884
885 auto it = ExtFun2Annotations.find(sameFuncDef);
886 if (it != ExtFun2Annotations.end())
887 {
888 std::vector<std::string> annotations = it->second;
889 if (annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos)
890 {
891 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFuncDef), const_cast<Function*>(appFuncDef), nullptr, true);
894 }
895 else
896 {
897 if (annotations.size() >= 2)
898 {
899 for (const auto& annotation : annotations)
900 {
901 if(annotation.find("OVERWRITE") != std::string::npos)
902 {
903 assert(false && "overwrite and other annotations cannot co-exist");
904 }
905 }
906 }
907 }
908 }
909 }
910
912 {
913 for (inst_iterator I = inst_begin(caller), E = inst_end(caller); I != E; ++I)
914 {
915 Instruction *inst = &*I;
916
917 if (CallInst *callInst = SVFUtil::dyn_cast<CallInst>(inst))
918 {
919 Function *calledFunc = callInst->getCalledFunction();
920
921 if (calledFunc && calledFunc->getName() == callee->getName())
922 {
923 callInst->setCalledFunction(callee);
924 }
925 }
926 }
927 };
928
929 std::function<void(const Function*, Function*)> cloneAndLinkFunction;
931 {
932 if (clonedFuncs.find(extFunToClone) != clonedFuncs.end())
933 return;
934
935 Module* appModule = appClonedFun->getParent();
936 // Check if the function already exists in the parent module
937 if (appModule->getFunction(extFunToClone->getName()))
938 {
939 // The function already exists, no need to clone, but need to link it with the caller
940 Function* func = appModule->getFunction(extFunToClone->getName());
942 return;
943 }
944 // Decide whether to clone the function body based on ExtFun2Annotations
945 bool cloneBody = true;
946 auto it = ExtFun2Annotations.find(extFunToClone->getName().str());
947 if (it != ExtFun2Annotations.end())
948 {
949 std::vector<std::string> annotations = it->second;
950 if (!(annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos))
951 {
952 cloneBody = false;
953 }
954 }
955
957
959 // Add the cloned function to ExtFuncsVec for further processing
960 ExtFuncsVec.push_back(clonedFunction);
961
963
964 std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(extFunToClone);
965
966 for (const auto& calledFunction : calledFunctions)
967 {
969 }
970 };
971
972 // Recursive clone called functions
973 for (const auto& pair : extFuncs2ClonedFuncs)
974 {
975 Function* extFun = const_cast<Function*>(pair.first);
976 Function* clonedExtFun = const_cast<Function*>(pair.second);
977 std::vector<const Function*> extCalledFuns = LLVMUtil::getCalledFunctions(extFun);
978
979 for (const auto& extCalledFun : extCalledFuns)
980 {
982 }
983 }
984
985 // Remove unused annotations in ExtFun2Annotations according to the functions in ExtFuncsVec
987 for (const Function* extFun : ExtFuncsVec)
988 {
989 std::string name = LLVMUtil::restoreFuncName(extFun->getName().str());
990 auto it = ExtFun2Annotations.find(name);
991 if (it != ExtFun2Annotations.end())
992 {
993 std::string newKey = name;
994 if (name != extFun->getName().str())
995 {
996 newKey = extFun->getName().str();
997 }
998 newFun2AnnoMap.insert({newKey, it->second});
999 }
1000 }
1002
1003 // Remove ExtAPI module from modules
1004 auto it = std::find_if(modules.begin(), modules.end(),
1005 [&extModule](const std::reference_wrapper<llvm::Module>& moduleRef)
1006 {
1007 return &moduleRef.get() == extModule;
1008 });
1009
1010 if (it != modules.end())
1011 {
1012 size_t index = std::distance(modules.begin(), it);
1013 modules.erase(it);
1014 owned_modules.erase(owned_modules.begin() + index);
1015 }
1016}
1017
1019{
1022 for (Module &mod : modules)
1023 {
1024 // Collect ctor and dtor functions
1025 for (GlobalVariable& global : mod.globals())
1026 {
1027 if (global.hasPrivateLinkage())
1028 continue;
1029 string name = global.getName().str();
1030 if (name.empty())
1031 continue;
1032 nameToGlobalsMap[std::move(name)].insert(&global);
1033 }
1034 }
1035
1036 for (const auto& pair : nameToGlobalsMap)
1037 {
1038 const Set<GlobalVariable*> &globals = pair.second;
1039
1040 const auto repIt =
1041 std::find_if(globals.begin(), globals.end(),
1042 [](GlobalVariable* g)
1043 {
1044 return g->hasInitializer();
1045 });
1046 GlobalVariable* rep =
1047 repIt != globals.end()
1048 ? *repIt
1049 // When there is no initializer, just pick the first one.
1050 : (assert(!globals.empty() && "Empty global set"),
1051 *globals.begin());
1052
1053 for (const GlobalVariable* cur : globals)
1054 {
1055 GlobalDefToRepMap[cur] = rep;
1056 }
1057 }
1058}
1059
1060// Dump modules to files
1062{
1063 for (Module& mod : modules)
1064 {
1065 std::string moduleName = mod.getName().str();
1066 std::string OutputFilename;
1067 std::size_t pos = moduleName.rfind('.');
1068 if (pos != std::string::npos)
1069 OutputFilename = moduleName.substr(0, pos) + suffix;
1070 else
1071 OutputFilename = moduleName + suffix;
1072
1073 std::error_code EC;
1074 raw_fd_ostream OS(OutputFilename.c_str(), EC, llvm::sys::fs::OF_None);
1075
1076#if (LLVM_VERSION_MAJOR >= 7)
1078#else
1080#endif
1081
1082 OS.flush();
1083 }
1084}
1085
1087{
1088 if (SVFUtil::isa<ConstantPointerNull>(llvm_value))
1089 return svfir->nullPtrSymID();
1090 else if (SVFUtil::isa<UndefValue>(llvm_value))
1091 {
1092 // For phi ptr [ @x, ... ], [ undef, ... ], keep @x without adding
1093 // a black-hole target. Integer and aggregate undef keep their model.
1094 if (Options::UndefAsNull() && llvm_value->getType()->isPointerTy())
1095 return svfir->nullPtrSymID();
1096 return svfir->blkPtrSymID();
1097 }
1098 else
1099 {
1100 ValueToIDMapTy::const_iterator iter = valSymMap.find(llvm_value);
1101 assert(iter!=valSymMap.end() &&"value sym not found");
1102 return iter->second;
1103 }
1104}
1106{
1107 if (SVFUtil::isa<ConstantPointerNull, UndefValue>(val))
1108 return true;
1109 else
1110 return (valSymMap.find(val) != valSymMap.end());
1111}
1112
1114{
1115 if (const GlobalVariable* glob = SVFUtil::dyn_cast<GlobalVariable>(llvm_value))
1117 ValueToIDMapTy::const_iterator iter = objSymMap.find(llvm_value);
1118 assert(iter!=objSymMap.end() && "obj sym not found");
1119 return iter->second;
1120}
1121
1122
1124{
1126 for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end();
1127 ++iter)
1128 {
1129 const NodeID i = iter->second;
1130 idmap[i] = iter->first;
1131 }
1132 for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end();
1133 ++iter)
1134 {
1135 const NodeID i = iter->second;
1136 idmap[i] = iter->first;
1137 }
1138 for (FunToIDMapTy::iterator iter = retSyms().begin(); iter != retSyms().end();
1139 ++iter)
1140 {
1141 const NodeID i = iter->second;
1142 idmap[i] = iter->first;
1143 }
1144 for (FunToIDMapTy::iterator iter = varargSyms().begin(); iter != varargSyms().end();
1145 ++iter)
1146 {
1147 const NodeID i = iter->second;
1148 idmap[i] = iter->first;
1149 }
1150 SVFUtil::outs() << "{SymbolTableInfo \n";
1151
1152
1153
1154
1155 for (auto iter : idmap)
1156 {
1157 std::string str;
1158 llvm::raw_string_ostream rawstr(str);
1159 auto llvmVal = iter.second;
1160 if (llvmVal)
1161 rawstr << " " << *llvmVal << " ";
1162 else
1163 rawstr << " No llvmVal found";
1165 SVFUtil::outs() << iter.first << " " << rawstr.str() << "\n";
1166 }
1167 SVFUtil::outs() << "}\n";
1168}
1169
1172{
1174 svfBaseNode->setSourceLoc(LLVMUtil::getSourceLoc(val));
1175 svfBaseNode->setName(val->getName().str());
1176}
1177
1179{
1180 Function* fun = nullptr;
1181
1182 for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
1183 {
1185 fun = mod->getFunction(name);
1186 if (fun)
1187 {
1188 return llvmModuleSet->getFunObjVar(fun);
1189 }
1190 }
1191 return nullptr;
1192}
1193
1194
1196{
1197 for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it)
1198 {
1199 if (it->second == T)
1200 return it->first;
1201 }
1202 assert(false && "can't find the corresponding LLVM Type");
1203 abort();
1204}
1205
1210{
1211 assert(T && "SVFType should not be null");
1212 LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.find(T);
1213 if (it != LLVMType2SVFType.end())
1214 return it->second;
1215
1218 svfType->setTypeInfo(stinfo);
1219 return svfType;
1220}
1221
1222
1225{
1226 ICFGNode* node;
1228 node = getCallICFGNode(inst);
1229 else if(LLVMUtil::isIntrinsicInst(inst))
1230 node = getIntraICFGNode(inst);
1231 else
1232 node = getIntraICFGNode(inst);
1233
1234 assert (node!=nullptr && "no ICFGNode for this instruction?");
1235 return node;
1236}
1237
1239{
1240 ICFGNode* node;
1242 node = getCallBlock(inst);
1243 else if(LLVMUtil::isIntrinsicInst(inst))
1244 node = getIntraBlock(inst);
1245 else
1246 node = getIntraBlock(inst);
1247
1248 return node != nullptr;
1249}
1250
1252{
1253 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1254 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1255 CallICFGNode* node = getCallBlock(inst);
1256 assert (node!=nullptr && "no CallICFGNode for this instruction?");
1257 return node;
1258}
1259
1261{
1262 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1263 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1264 RetICFGNode* node = getRetBlock(inst);
1265 assert (node!=nullptr && "no RetICFGNode for this instruction?");
1266 return node;
1267}
1268
1270{
1271 IntraICFGNode* node = getIntraBlock(inst);
1272 assert (node!=nullptr && "no IntraICFGNode for this instruction?");
1273 return node;
1274}
1275
1277{
1278 Type2TypeInfoMap::iterator tit = Type2TypeInfo.find(T);
1279 if (tit != Type2TypeInfo.end())
1280 {
1281 return tit->second;
1282 }
1283 // No such StInfo for T, create it now.
1284 StInfo* stInfo;
1285 if (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(T))
1286 {
1288 }
1289 else if (const StructType* sty = SVFUtil::dyn_cast<StructType>(T))
1290 {
1291 u32_t nf;
1293 if (nf > svfir->maxStSize)
1294 {
1296 svfir->maxStSize = nf;
1297 }
1298 }
1299 else
1300 {
1302 }
1303 Type2TypeInfo.emplace(T, stInfo);
1305 return stInfo;
1306}
1307
1309{
1310 assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() &&
1311 "SVFType has been added before");
1312
1313 // add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 1 (default value)
1314 u32_t byteSize = 1;
1315 if (T->isSized())
1316 {
1317 const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()->
1318 getMainLLVMModule()->getDataLayout();
1319 Type *mut_T = const_cast<Type *>(T);
1320 byteSize = DL.getTypeAllocSize(mut_T);
1321 }
1322
1324
1326 if (SVFUtil::isa<PointerType>(T))
1327 {
1328 svftype = new SVFPointerType(id, byteSize);
1329 }
1330 else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
1331 {
1332 auto svfIntT = new SVFIntegerType(id, byteSize);
1333 unsigned signWidth = intT->getBitWidth();
1334 assert(signWidth < INT16_MAX && "Integer width too big");
1335 svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
1336 svftype = svfIntT;
1337 }
1338 else if (const FunctionType* ft = SVFUtil::dyn_cast<FunctionType>(T))
1339 {
1340 std::vector<const SVFType*> paramTypes;
1341 for (const auto& t: ft->params())
1342 {
1343 paramTypes.push_back(getSVFType(t));
1344 }
1345 svftype = new SVFFunctionType(id, getSVFType(ft->getReturnType()), paramTypes, ft->isVarArg());
1346 }
1347 else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
1348 {
1349 std::vector<const SVFType*> fieldTypes;
1350
1351 for (const auto& t: st->elements())
1352 {
1353 fieldTypes.push_back(getSVFType(t));
1354 }
1355 auto svfst = new SVFStructType(id, fieldTypes, byteSize);
1356 if (st->hasName())
1357 svfst->setName(st->getName().str());
1358 svftype = svfst;
1359 }
1360 else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
1361 {
1362 auto svfat = new SVFArrayType(id, byteSize);
1363 svfat->setNumOfElement(at->getNumElements());
1364 svfat->setTypeOfElement(getSVFType(at->getElementType()));
1365 svftype = svfat;
1366 }
1367 else
1368 {
1369 std::string buffer;
1370 auto ot = new SVFOtherType(id, T->isSingleValueType(), byteSize);
1371 llvm::raw_string_ostream(buffer) << *T;
1372 ot->setRepr(std::move(buffer));
1373 svftype = ot;
1374 }
1375
1378
1379 return svftype;
1380}
1381
1386{
1387 u64_t totalElemNum = ty->getNumElements();
1388 const Type* elemTy = ty->getElementType();
1389 while (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(elemTy))
1390 {
1391 totalElemNum *= aty->getNumElements();
1392 elemTy = aty->getElementType();
1393 }
1394
1397
1399 if (totalElemNum == 0)
1400 {
1401 stInfo->addFldWithType(0, elemSvfType, 0);
1402 stInfo->setNumOfFieldsAndElems(1, 1);
1403 stInfo->getFlattenFieldTypes().push_back(elemSvfType);
1404 stInfo->getFlattenElementTypes().push_back(elemSvfType);
1405 return stInfo;
1406 }
1407
1411 u32_t nfF = elemStInfo->getNumOfFlattenFields();
1412 u32_t nfE = elemStInfo->getNumOfFlattenElements();
1413 for (u32_t j = 0; j < nfF; j++)
1414 {
1415 const SVFType* fieldTy = elemStInfo->getFlattenFieldTypes()[j];
1416 stInfo->getFlattenFieldTypes().push_back(fieldTy);
1417 }
1418
1421 u32_t outArrayElemNum = ty->getNumElements();
1422 for (u32_t i = 0; i < outArrayElemNum; ++i)
1423 {
1424 auto idx = (i * nfE * totalElemNum) / outArrayElemNum;
1425 stInfo->addFldWithType(0, elemSvfType, idx);
1426 }
1427
1428 for (u32_t i = 0; i < totalElemNum; ++i)
1429 {
1430 for (u32_t j = 0; j < nfE; ++j)
1431 {
1432 const SVFType* et = elemStInfo->getFlattenElementTypes()[j];
1433 stInfo->getFlattenElementTypes().push_back(et);
1434 }
1435 }
1436
1437 assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum &&
1438 "typeForArray size incorrect!!!");
1439 stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum);
1440
1441 return stInfo;
1442}
1443
1450{
1452 StInfo* stInfo = new StInfo(1);
1453
1454 // Number of fields after flattening the struct
1455 numFields = 0;
1456 // The offset when considering array stride info
1457 u32_t strideOffset = 0;
1458 for (const Type* elemTy : structTy->elements())
1459 {
1461 // offset with int_32 (s32_t) is large enough and won't overflow
1462 stInfo->addFldWithType(numFields, elemSvfTy, strideOffset);
1463
1464 if (SVFUtil::isa<StructType, ArrayType>(elemTy))
1465 {
1467 u32_t nfF = subStInfo->getNumOfFlattenFields();
1468 u32_t nfE = subStInfo->getNumOfFlattenElements();
1469 // Copy ST's info, whose element 0 is the size of ST itself.
1470 for (u32_t j = 0; j < nfF; ++j)
1471 {
1472 const SVFType* elemTy = subStInfo->getFlattenFieldTypes()[j];
1473 stInfo->getFlattenFieldTypes().push_back(elemTy);
1474 }
1475 numFields += nfF;
1476 strideOffset += nfE;
1477 for (u32_t tpj = 0; tpj < nfE; ++tpj)
1478 {
1479 const SVFType* ty = subStInfo->getFlattenElementTypes()[tpj];
1480 stInfo->getFlattenElementTypes().push_back(ty);
1481 }
1482
1483 }
1484 else
1485 {
1486 // Simple type
1487 numFields += 1;
1488 strideOffset += 1;
1489 stInfo->getFlattenFieldTypes().push_back(elemSvfTy);
1490 stInfo->getFlattenElementTypes().push_back(elemSvfTy);
1491 }
1492 }
1493
1494 assert(stInfo->getFlattenElementTypes().size() == strideOffset &&
1495 "typeForStruct size incorrect!");
1496 stInfo->setNumOfFieldsAndElems(numFields,strideOffset);
1497
1498 return stInfo;
1499}
1500
1501
1506{
1508 StInfo* stInfo = new StInfo(1);
1510 stInfo->addFldWithType(0, svfType, 0);
1511
1512 stInfo->getFlattenFieldTypes().push_back(svfType);
1513 stInfo->getFlattenElementTypes().push_back(svfType);
1514 stInfo->setNumOfFieldsAndElems(1,1);
1515
1516 return stInfo;
1517}
1518
1519void LLVMModuleSet::setExtFuncAnnotations(const Function* fun, const std::vector<std::string>& funcAnnotations)
1520{
1521 assert(fun && "Null SVFFunction* pointer");
1523}
1524
1526{
1527 assert(fun && "Null SVFFunction* pointer");
1528 auto it = func2Annotations.find(fun);
1529 if (it != func2Annotations.end())
1530 {
1531 for (const std::string& annotation : it->second)
1532 if (annotation.find(funcAnnotation) != std::string::npos)
1533 return true;
1534 }
1535 return false;
1536}
1537
1538std::string LLVMModuleSet::getExtFuncAnnotation(const Function* fun, const std::string& funcAnnotation)
1539{
1540 assert(fun && "Null Function* pointer");
1541 auto it = func2Annotations.find(fun);
1542 if (it != func2Annotations.end())
1543 {
1544 for (const std::string& annotation : it->second)
1545 if (annotation.find(funcAnnotation) != std::string::npos)
1546 return annotation;
1547 }
1548 return "";
1549}
1550
1551const std::vector<std::string>& LLVMModuleSet::getExtFuncAnnotations(const Function* fun)
1552{
1553 assert(fun && "Null Function* pointer");
1554 auto it = func2Annotations.find(fun);
1555 if (it != func2Annotations.end())
1556 return it->second;
1557 return func2Annotations[fun];
1558}
1559
1561{
1562 return F &&
1563 (hasExtFuncAnnotation(F, "MEMCPY") || hasExtFuncAnnotation(F, "STRCPY")
1564 || hasExtFuncAnnotation(F, "STRCAT"));
1565}
1566
1568{
1569 return F && hasExtFuncAnnotation(F, "MEMSET");
1570}
1571
1573{
1574 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_RET");
1575}
1576
1577// Does (F) allocate a new object and assign it to one of its arguments?
1579{
1580 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1581}
1582
1584{
1585 return F && hasExtFuncAnnotation(F, "ALLOC_STACK_RET");
1586}
1587
1588// Get the position of argument which holds the new object
1590{
1591 std::string allocArg = getExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1592 assert(!allocArg.empty() && "Not an alloc call via argument or incorrect extern function annotation!");
1593
1594 std::string number;
1595 for (char c : allocArg)
1596 {
1597 if (isdigit(c))
1598 number.push_back(c);
1599 }
1600 assert(!number.empty() && "Incorrect naming convention for svf external functions(ALLOC_HEAP_ARG + number)?");
1601 return std::stoi(number);
1602}
1603
1604// Does (F) reallocate a new object?
1606{
1607 return F && hasExtFuncAnnotation(F, "REALLOC_HEAP_RET");
1608}
1609
1610
1611// Should (F) be considered "external" (either not defined in the program
1612// or a user-defined version of a known alloc or no-op)?
1614{
1615 assert(F && "Null SVFFunction* pointer");
1616 if (F->isDeclaration() || F->isIntrinsic())
1617 return true;
1618 else if (hasExtFuncAnnotation(F, "OVERWRITE") && getExtFuncAnnotations(F).size() == 1)
1619 return false;
1620 else
1621 return !getExtFuncAnnotations(F).empty();
1622}
#define SVF_MAIN_FUNC_NAME
#define SVF_GLOBAL_DTORS
#define SVF_GLOBAL_CTORS
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define TIMEINTERVAL
Definition SVFType.h:604
#define DGENERAL
Definition SVFType.h:582
const char *const name
Definition cJSON.h:264
char * buffer
Definition cJSON.h:163
const char *const const double number
Definition cJSON.h:268
int index
Definition cJSON.h:170
void setValue(T v)
std::string getExtBcPath()
Definition ExtAPI.cpp:111
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:43
const SVFType * maxStruct
The struct type with the most fields.
Definition IRGraph.h:363
void addStInfo(StInfo *stInfo)
Definition IRGraph.h:375
NodeID blkPtrSymID() const
Definition IRGraph.h:182
NodeID nullPtrSymID() const
Definition IRGraph.h:187
void addTypeInfo(const SVFType *ty)
Definition IRGraph.h:368
u32_t maxStSize
The number of fields in max_struct.
Definition IRGraph.h:366
bool hasValueNode(const Value *V)
TargetABI targetABI
C++ ABI of the module being analyzed.
Definition LLVMModule.h:92
NodeID getValueNode(const Value *V)
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition LLVMModule.h:512
LLVMType2SVFTypeMap LLVMType2SVFType
Definition LLVMModule.h:107
bool is_alloc_stack_ret(const Function *F)
std::vector< const Function * > getLLVMGlobalFunctions(const GlobalVariable *global)
FunToIDMapTy & retSyms()
Definition LLVMModule.h:281
void buildSymbolTable() const
Module * getMainLLVMModule() const
Definition LLVMModule.h:373
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:274
ValueToIDMapTy valSymMap
map a value to its sym id
Definition LLVMModule.h:120
StInfo * collectTypeInfo(const Type *ty)
Collect a type info.
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:137
void loadModules(const std::vector< std::string > &moduleNameVec)
ObjTypeInference * typeInference
Definition LLVMModule.h:109
static void releaseLLVMModuleSet()
Definition LLVMModule.h:144
static void preProcessBCs(std::vector< std::string > &moduleNameVec)
static bool preProcessed
Definition LLVMModule.h:85
DominatorTree & getDomTree(const Function *fun)
void addToSVFVar2LLVMValueMap(const Value *val, SVFValue *svfBaseNode)
RetICFGNode * getRetBlock(const Instruction *cs)
Get/Add a return node.
Definition LLVMModule.h:504
std::unique_ptr< LLVMContext > owned_ctx
Definition LLVMModule.h:87
void createSVFDataStructure()
StInfo * collectSimpleTypeInfo(const Type *T)
Collect simple type (non-aggregate) info.
bool is_alloc(const Function *F)
const std::vector< std::string > & getExtFuncAnnotations(const Function *fun)
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
void setFunExitBB(const Function *fun, const BasicBlock *bb)
Definition LLVMModule.h:457
const Type * getLLVMType(const SVFType *T) const
Get LLVM Type.
void setExtFuncAnnotations(const Function *fun, const std::vector< std::string > &funcAnnotations)
bool hasICFGNode(const Instruction *inst)
CallICFGNode * getCallBlock(const Instruction *cs)
Get/Add a call node.
Definition LLVMModule.h:495
ValueToIDMapTy objSymMap
map a obj reference to its sym id
Definition LLVMModule.h:121
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
const Function * getFunction(const std::string &name)
Get the corresponding Function based on its name.
Definition LLVMModule.h:313
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
Fun2AnnoMap ExtFun2Annotations
Record annotations of function in extapi.bc.
Definition LLVMModule.h:97
bool is_arg_alloc(const Function *F)
Map< const Function *, std::vector< std::string > > func2Annotations
Definition LLVMModule.h:100
const BasicBlock * getFunExitBB(const Function *fun) const
Definition LLVMModule.h:185
NodeID getObjectNode(const Value *V)
Module * getModule(u32_t idx) const
Definition LLVMModule.h:169
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
void prePassSchedule()
Invoke llvm passes to modify module.
StInfo * collectStructInfo(const StructType *structTy, u32_t &numFields)
Collect the struct info and set the number of fields after flattening.
s32_t get_alloc_arg_pos(const Function *F)
void addFunctionSet(const Function *svfFunc)
Definition LLVMModule.h:452
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:164
LLVMContext & getContext() const
Definition LLVMModule.h:393
bool is_ext(const Function *F)
Map< const Function *, DominatorTree > FunToDominatorTree
Definition LLVMModule.h:118
static void buildSVFModule(Module &mod)
SVFBaseNode2LLVMValueMap SVFBaseNode2LLVMValue
Definition LLVMModule.h:111
StInfo * collectArrayInfo(const ArrayType *T)
Collect the array info.
LLVMModuleSet()
Constructor.
SVFType * addSVFTypeInfo(const Type *t)
Create SVFTypes.
FunctionSet funSet
Definition LLVMModule.h:125
FunctionSetType ExtFuncsVec
Record some "sse_" function declarations used in other ext function definition, e....
Definition LLVMModule.h:95
bool hasExtFuncAnnotation(const Function *fun, const std::string &funcAnnotation)
static LLVMModuleSet * llvmModuleSet
Definition LLVMModule.h:84
IntraICFGNode * getIntraICFGNode(const Instruction *inst)
get a intra node
std::vector< std::reference_wrapper< Module > > modules
Definition LLVMModule.h:89
std::string getExtFuncAnnotation(const Function *fun, const std::string &funcAnnotation)
bool empty() const
Definition LLVMModule.h:399
Map< std::string, std::vector< std::string > > Fun2AnnoMap
Definition LLVMModule.h:65
u32_t getModuleNum() const
Definition LLVMModule.h:159
GlobalDefToRepMapTy GlobalDefToRepMap
Global definition to a rep definition map.
Definition LLVMModule.h:103
std::vector< std::unique_ptr< Module > > owned_modules
Definition LLVMModule.h:88
bool is_memset(const Function *F)
FunToIDMapTy & varargSyms()
Definition LLVMModule.h:286
Type2TypeInfoMap Type2TypeInfo
Definition LLVMModule.h:108
void dumpModulesToFile(const std::string &suffix)
void collectExtFunAnnotations(const Module *mod)
bool is_memcpy(const Function *F)
ObjTypeInference * getTypeInference()
bool is_realloc(const Function *F)
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID allocateTypeId(void)
Allocate an type ID as determined by the strategy.
static const Option< bool > UndefAsNull
Definition Options.h:99
static const Option< std::string > Graphtxt
Definition Options.h:173
static Option< bool > SVFMain
Definition Options.h:174
static bool pagReadFromTXT()
Definition SVFIR.h:281
void setModuleIdentifier(const std::string &moduleIdentifier)
Definition SVFIR.h:291
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:121
static void setPagFromTXT(const std::string &txt)
Definition SVFIR.h:286
static double timeOfBuildingLLVMModule
Definition SVFStat.h:96
static double getClk(bool mark=false)
Definition SVFStat.cpp:52
static double timeOfBuildingSymbolTable
Definition SVFStat.h:97
static SVFType * svfPtrTy
ptr type
Definition SVFType.h:230
static SVFType * svfI8Ty
8-bit int type
Definition SVFType.h:231
#define NULL
Definition extapi.c:5
int isdigit(int c)
Definition extapi.c:1018
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition LLVMUtil.cpp:204
std::vector< const Function * > getCalledFunctions(const Function *F)
Get all called funcions in a parent function.
Definition LLVMUtil.cpp:365
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:61
bool functionDoesNotRet(const Function *fun)
Definition LLVMUtil.cpp:124
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:99
static TargetABI detectTargetABI(const llvm::Triple &triple)
Definition LLVMUtil.h:355
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:454
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:441
bool basicBlockHasRetInst(const BasicBlock *bb)
Return true if the function has a return instruction.
Definition LLVMUtil.cpp:110
static llvm::Triple getTargetTriple(const Module *mod)
Definition LLVMUtil.h:345
bool isIRFile(const std::string &filename)
Check whether a file is an LLVM IR file.
Definition LLVMUtil.cpp:316
std::string restoreFuncName(std::string funcName)
Definition LLVMUtil.cpp:408
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:736
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:121
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:64
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:58
for isBitcode
Definition BasicTypes.h:70
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:137
llvm::ArrayType ArrayType
Definition BasicTypes.h:99
llvm::raw_fd_ostream raw_fd_ostream
LLVM outputs.
Definition BasicTypes.h:275
llvm::Type Type
Definition BasicTypes.h:87
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:90
llvm::inst_iterator inst_iterator
Definition BasicTypes.h:260
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:110
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:98
unsigned long long u64_t
Definition GeneralType.h:69
llvm::IntegerType IntegerType
Definition BasicTypes.h:101
u32_t NodeID
Definition GeneralType.h:76
llvm::ConstantArray ConstantArray
Definition BasicTypes.h:127
llvm::Function Function
Definition BasicTypes.h:89
llvm::FunctionType FunctionType
Definition BasicTypes.h:102
llvm::Instruction Instruction
Definition BasicTypes.h:91
llvm::Constant Constant
Definition BasicTypes.h:128
llvm::SMDiagnostic SMDiagnostic
Definition BasicTypes.h:94
llvm::ConstantDataSequential ConstantDataSequential
Definition BasicTypes.h:123
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:86
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:124
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
signed s32_t
Definition GeneralType.h:68
llvm::Module Module
Definition BasicTypes.h:88
unsigned u32_t
Definition GeneralType.h:67
llvm::CallInst CallInst
Definition BasicTypes.h:154
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:129
llvm::DominatorTree DominatorTree
LLVM Dominators.
Definition BasicTypes.h:140
IntervalValue operator>(const IntervalValue &lhs, const IntervalValue &rhs)