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