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(preProcessed==false)
169
172
173 if (Options::SVFMain())
174 addSVFMain();
175
177
178}
179
181{
184 // Functions need to be retrieved in the order of insertion
185 // candidateDefs is the vector for all used defined functions
186 // candidateDecls is the vector for all used declared functions
187 std::vector<const Function*> candidateDefs, candidateDecls;
188
189 for (Module& mod : modules)
190 {
192 for (Function& func : mod.functions())
193 {
194 if (func.isDeclaration())
195 {
196 candidateDecls.push_back(&func);
197 }
198 else
199 {
200 candidateDefs.push_back(&func);
201 }
202 }
203 }
204
205 for (const Function* func: candidateDefs)
206 {
208 }
209 for (const Function* func: candidateDecls)
210 {
212 }
213
214 // set function exit block
215 for (const auto& func: funSet)
216 {
217 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
218 {
219 const BasicBlock* bb = &*bit;
221 if (succ_size(bb) == 0)
222 {
224 {
226 SVFUtil::isa<ReturnInst>(bb->back())) &&
227 "last inst must be return inst");
228 setFunExitBB(func, bb);
229 }
230 }
231 }
232 // For no return functions, we set the last block as exit BB
233 // This ensures that each function that has definition must have an exit BB
234 if (func->size() != 0 && !getFunExitBB(func))
235 {
237 SVFUtil::isa<ReturnInst>(&func->back().back())) &&
238 "last inst must be return inst");
239 setFunExitBB(func, &func->back());
240 }
241 }
242
243 // Store annotations of functions in extapi.bc
244 for (const auto& pair : ExtFun2Annotations)
245 {
246 const Function* fun = getFunction(pair.first);
247 setExtFuncAnnotations(fun, pair.second);
248 }
249
250}
251
256{
258 std::unique_ptr<BreakConstantGEPs> p1 = std::make_unique<BreakConstantGEPs>();
259 for (Module &M : getLLVMModules())
260 {
261 p1->runOnModule(M);
262 }
263
265 std::unique_ptr<UnifyFunctionExitNodes> p2 =
266 std::make_unique<UnifyFunctionExitNodes>();
267 for (Module &M : getLLVMModules())
268 {
269 for (auto F = M.begin(), E = M.end(); F != E; ++F)
270 {
271 Function &fun = *F;
272 if (fun.isDeclaration())
273 continue;
274#if LLVM_VERSION_MAJOR <= 16
275 p2->runOnFunction(fun);
276#else
277 llvm::PassBuilder PB;
278 llvm::LoopAnalysisManager LAM;
279 llvm::FunctionAnalysisManager FAM;
280 llvm::CGSCCAnalysisManager CGAM;
281 llvm::ModuleAnalysisManager MAM;
282 PB.registerModuleAnalyses(MAM);
283 PB.registerCGSCCAnalyses(CGAM);
284 PB.registerFunctionAnalyses(FAM);
285 PB.registerLoopAnalyses(LAM);
286 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
287 llvm::FunctionPassManager FPM;
288 FPM.addPass(llvm::UnifyFunctionExitNodesPass());
289 FPM.run(fun, FAM);
290#endif
291 }
292 }
293}
294
295void LLVMModuleSet::preProcessBCs(std::vector<std::string> &moduleNameVec)
296{
298 mset->loadModules(moduleNameVec);
299 mset->loadExtAPIModules();
300 mset->prePassSchedule();
301
302 std::string preProcessSuffix = ".pre.bc";
303 // Get the existing module names, remove old extension, add preProcessSuffix
304 for (u32_t i = 0; i < moduleNameVec.size(); i++)
305 {
306 u32_t lastIndex = moduleNameVec[i].find_last_of(".");
307 std::string rawName = moduleNameVec[i].substr(0, lastIndex);
309 }
310
311 mset->dumpModulesToFile(preProcessSuffix);
312 preProcessed = true;
314}
315
316void LLVMModuleSet::loadModules(const std::vector<std::string> &moduleNameVec)
317{
318
319 // We read SVFIR from LLVM IR
321 {
322 if(moduleNameVec.empty())
323 {
324 SVFUtil::outs() << "no LLVM bc file is found!\n";
325 exit(0);
326 }
327 //assert(!moduleNameVec.empty() && "no LLVM bc file is found!");
328 }
329 // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
330 else
331 {
333 }
334 //
335 // LLVMContext objects separate global LLVM settings (from which e.g. types are
336 // derived); multiple LLVMContext objects can coexist and each context can "own"
337 // multiple modules (modules can only have one context). Mixing contexts can lead
338 // to unintended inequalities, such as the following:
339 //
340 // ------------------------------------------------------------------
341 // LLVMContext ctxa,ctxb;
342 // IntegerType * t1 = IntegerType::get(ctxa,32);
343 // IntegerType * t2 = IntegerType::get(ctxa,32);
344 // assert(t1 == t2);
345 // IntegerType * t3 = IntegerType::get(ctxb,32);
346 // IntegerType * t4 = IntegerType::get(ctxb,32);
347 // assert(t3 == t4);
348 // assert(t1 != t3);
349 // ------------------------------------------------------------------
350 //
351 // When loading bytecode files, SVF will use the same LLVMContext object for all
352 // modules (i.e. the context owns all loaded modules). This applies to ExtAPI as
353 // well, which *must* be loaded using the same LLVMContext object. Hence, when
354 // loading modules from bitcode files, a new LLVMContext is created (using a
355 // `std::unique_ptr<LLVMContext>` type to ensure automatic garbage collection).
356 //
357 // This garbage collection should be avoided when building an SVF module from an LLVM
358 // module instance; see the comment(s) in `buildSVFModule` and `loadExtAPIModules()`
359
360 owned_ctx = std::make_unique<LLVMContext>();
361 for (const std::string& moduleName : moduleNameVec)
362 {
363 if (!LLVMUtil::isIRFile(moduleName))
364 {
365 SVFUtil::errs() << "not an IR file: " << moduleName << std::endl;
366 abort();
367 }
368
370 std::unique_ptr<Module> mod = parseIRFile(moduleName, Err, *owned_ctx);
371 if (mod == nullptr)
372 {
373 SVFUtil::errs() << "load module: " << moduleName << "failed!!\n\n";
374 Err.print("SVFModuleLoader", llvm::errs());
375 abort();
376 }
377 modules.emplace_back(*mod);
378 owned_modules.emplace_back(std::move(mod));
379 }
380}
381
383{
384 // This function loads the ExtAPI bitcode file as an LLVM module. Note that it is important that
385 // the same LLVMContext object is used to load this bitcode file as is used by the other modules
386 // being analysed.
387 // When the modules are loaded from bitcode files (i.e. passing filenames to files containing
388 // LLVM IR to `buildSVFModule({file1.bc, file2.bc, ...})) the context is created while loading
389 // the modules in `loadModules()`, which populates this->modules and this->owned_modules.
390 // If, however, an LLVM Module object is passed to `buildSVFModule` (e.g. from an LLVM pass),
391 // the context should be retrieved from the module itself (note that the garbage collection from
392 // `std::unique_ptr<LLVMContext> LLVMModuleSet::owned_ctx` should be avoided in this case). This
393 // function populates only this->modules.
394 // In both cases, fetching the context from the main LLVM module (through `getContext`) works
395 assert(!empty() && "LLVMModuleSet contains no modules; cannot load ExtAPI module without LLVMContext!");
396
397 // Load external API module (extapi.bc)
398 if (!ExtAPI::getExtAPI()->getExtBcPath().empty())
399 {
402 {
403 SVFUtil::errs() << "not an external IR file: " << extModuleName << std::endl;
404 abort();
405 }
407 std::unique_ptr<Module> mod = parseIRFile(extModuleName, Err, getContext());
408 if (mod == nullptr)
409 {
410 SVFUtil::errs() << "load external module: " << extModuleName << "failed!!\n\n";
411 Err.print("SVFModuleLoader", llvm::errs());
412 abort();
413 }
414 // The module of extapi.bc needs to be inserted before applications modules, like std::vector<std::reference_wrapper<Module>> modules{extapi_module, app_module}.
415 // Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found.
416 modules.insert(modules.begin(), *mod);
417 owned_modules.insert(owned_modules.begin(),std::move(mod));
418 }
419}
420
422{
423 // This function is used to extract constructor and destructor functions
424 // sorted by their priority from @llvm.global_ctors or @llvm.global_dtors.
425 // For example, given following @llvm.global_ctors, the returning sorted
426 // function list should be [ctor3, ctor1, ctor2].
427 // ------------------------------------------------------------------
428 // ; Each struct in the array is {priority, function, associated data}
429 //
430 // @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }]
431 // [{ i32, void ()*, i8* } { i32 1234, void ()* @ctor1.cpp, i8* null },
432 // { i32, void ()*, i8* } { i32 2345, void ()* @ctor2.cpp, i8* null },
433 // { i32, void ()*, i8* } { i32 345, void ()* @ctor3.cpp, i8* null }]
434 // ------------------------------------------------------------------
435 // TODO: According to LLVM language reference, if the third field is
436 // non-null, and points to a global variable or function, the initializer
437 // function will only run if the associated data from the current module is
438 // not discarded. However the associated data is currently ignored.
439
440
441 // This class is used for the priority queue that sorts the functions by
442 // their priority. Each object of this class stands for an item in the
443 // function array.
445 {
446 public:
448 const Function* func;
452 bool operator>(const LLVMGlobalFunction &other) const
453 {
454 if (priority != other.priority)
455 {
456 return priority > other.priority;
457 }
458 else
459 {
460 return func > other.func;
461 }
462 }
463 };
464
465 std::priority_queue<LLVMGlobalFunction, std::vector<LLVMGlobalFunction>,
467 queue;
468 std::vector<const Function* > result;
469
470 // The @llvm.global_ctors/dtors global variable is an array of struct. Each
471 // struct has three fields: {i32 priority, void ()* @ctor/dtor, i8* @data}.
472 // First get the array here.
474 SVFUtil::dyn_cast<ConstantArray>(global->getInitializer()))
475 {
476 // Get each struct in the array.
477 for (unsigned int i = 0; i < globalFuncArray->getNumOperands(); ++i)
478 {
479 if (
481 SVFUtil::dyn_cast<ConstantStruct>(
482 globalFuncArray->getOperand(i)))
483 {
484
485 // Extract priority and function from the struct
486 const ConstantInt* priority = SVFUtil::dyn_cast<ConstantInt>(
487 globalFuncItem->getOperand(0));
488 const Function* func = SVFUtil::dyn_cast<Function>(
489 globalFuncItem->getOperand(1));
490
491 if (priority && func)
492 {
494 func));
495 }
496 }
497 }
498 }
499
500 // Generate a sorted vector of functions from the priority queue.
501 while (!queue.empty())
502 {
503 result.push_back(queue.top().func);
504 queue.pop();
505 }
506 return result;
507}
508
510{
511 std::vector<const Function*> ctor_funcs;
512 std::vector<const Function*> dtor_funcs;
513 Function* orgMain = 0;
514 Module* mainMod = nullptr;
515
516 for (Module &mod : modules)
517 {
518 // Collect ctor and dtor functions
519 for (const GlobalVariable& global : mod.globals())
520 {
521 if (global.getName() == SVF_GLOBAL_CTORS && global.hasInitializer())
522 {
524 }
525 else if (global.getName() == SVF_GLOBAL_DTORS && global.hasInitializer())
526 {
528 }
529 }
530
531 // Find main function
532 for (auto &func : mod)
533 {
534 auto funName = func.getName();
535
536 assert(!(funName == SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
537
538 if (funName == "main")
539 {
540 orgMain = &func;
541 mainMod = &mod;
542 }
543 }
544 }
545
546 // Only create svf.main when the original main function is found, and also
547 // there are global constructor or destructor functions.
548 if (orgMain && getModuleNum() > 0 &&
549 (ctor_funcs.size() > 0 || dtor_funcs.size() > 0))
550 {
551 assert(mainMod && "Module with main function not found.");
552 Module& M = *mainMod;
553 // char **
554 Type* ptr = PointerType::getUnqual(M.getContext());
555 Type* i32 = IntegerType::getInt32Ty(M.getContext());
556 // define void @svf.main(i32, i8**, i8**)
557#if (LLVM_VERSION_MAJOR >= 9)
558 FunctionCallee svfmainFn = M.getOrInsertFunction(
560 Type::getVoidTy(M.getContext()),
561 i32,ptr,ptr
562 );
563 Function* svfmain = SVFUtil::dyn_cast<Function>(svfmainFn.getCallee());
564#else
565 Function* svfmain = SVFUtil::dyn_cast<Function>(M.getOrInsertFunction(
567 Type::getVoidTy(M.getContext()),
569 ));
570#endif
571 svfmain->setCallingConv(llvm::CallingConv::C);
572 BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", svfmain);
574 // emit "call void @ctor()". ctor_funcs is sorted so the functions are
575 // emitted in the order of priority
576 for (auto& ctor : ctor_funcs)
577 {
578 auto target = M.getOrInsertFunction(
579 ctor->getName(),
580 Type::getVoidTy(M.getContext())
581 );
582 Builder.CreateCall(target);
583 }
584 // main() should be called after all ctor functions and before dtor
585 // functions.
586 Function::arg_iterator arg_it = svfmain->arg_begin();
587 Value* args[] = {arg_it, arg_it + 1, arg_it + 2};
588 size_t cnt = orgMain->arg_size();
589 assert(cnt <= 3 && "Too many arguments for main()");
590 Builder.CreateCall(orgMain, llvm::ArrayRef<Value*>(args, args + cnt));
591 // emit "call void @dtor()". dtor_funcs is sorted so the functions are
592 // emitted in the order of priority
593 for (auto& dtor : dtor_funcs)
594 {
595 auto target = M.getOrInsertFunction(dtor->getName(), Type::getVoidTy(M.getContext()));
596 Builder.CreateCall(target);
597 }
598 // return;
599 Builder.CreateRetVoid();
600 }
601 else
602 {
603 // use SVF::Options to record whether svf.main is added or not
605 }
606}
607
609{
610 GlobalVariable *glob = mod->getGlobalVariable("llvm.global.annotations");
611 if (glob == nullptr || !glob->hasInitializer())
612 return;
613
614 ConstantArray *ca = SVFUtil::dyn_cast<ConstantArray>(glob->getInitializer());
615 if (ca == nullptr)
616 return;
617
618 for (unsigned i = 0; i < ca->getNumOperands(); ++i)
619 {
620 ConstantStruct *structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
621 if (structAn == nullptr || structAn->getNumOperands() == 0)
622 continue;
623
624 // Check if the annotation is for a function
625 Function* fun = nullptr;
626 GlobalVariable *annotateStr = nullptr;
628 if (ConstantExpr *expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0)))
629 {
630 if (expr->getOpcode() == Instruction::BitCast && SVFUtil::isa<Function>(expr->getOperand(0)))
631 fun = SVFUtil::cast<Function>(expr->getOperand(0));
632
633 ConstantExpr *note = SVFUtil::cast<ConstantExpr>(structAn->getOperand(1));
634 if (note->getOpcode() != Instruction::GetElementPtr)
635 continue;
636
637 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(note->getOperand(0));
638 }
640 else
641 {
642 fun = SVFUtil::dyn_cast<Function>(structAn->getOperand(0));
643 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(structAn->getOperand(1));
644 }
645
646 if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer())
647 continue;;
648
649 ConstantDataSequential *data = SVFUtil::dyn_cast<ConstantDataSequential>(annotateStr->getInitializer());
650 if (data && data->isString())
651 {
652 std::string annotation = data->getAsString().str();
653 if (!annotation.empty())
654 ExtFun2Annotations[fun->getName().str()].push_back(annotation);
655 }
656 }
657}
658
659/*
660 There are three types of functions(definitions) in extapi.c:
661 1. (Fun_Overwrite): Functions with "OVERWRITE" annotion:
662 These functions are used to replace the corresponding function definitions in the application.
663 2. (Fun_Annotation): Functions with annotation(s) but without "OVERWRITE" annotation:
664 These functions are used to tell SVF to do special processing, like malloc().
665 3. (Fun_Noraml): Functions without any annotation:
666 These functions are used to replace the corresponding function declarations in the application.
667
668
669 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:
670 1. appFuncDecl --> Fun_Normal: Clone the Fun_Overwrite and replace the appFuncDecl in application.
671 2. appFuncDecl --> Fun_Annotation: Move the annotions on Fun_Annotation to appFuncDecl in application.
672
673 3. appFunDef --> Fun_Overwrite: Clone the Fun_Overwrite and overwrite the appFunDef in application.
674 4. appFunDef --> Fun_Annotation: Replace the appFunDef with appFunDecl and move the annotions to appFunDecl in application
675*/
677{
681 Module* appModule = nullptr;
682 Module* extModule = nullptr;
683
684 for (Module& mod : modules)
685 {
686 // extapi.bc functions
687 if (mod.getName().str() == ExtAPI::getExtAPI()->getExtBcPath())
688 {
690 extModule = &mod;
691 for (const Function& fun : mod.functions())
692 {
693 // there is main declaration in ext bc, it should be mapped to
694 // main definition in app bc.
695 if (fun.getName().str() == "main")
696 {
697 appFunDecls.insert(&fun);
698 appFuncDeclNames.insert(fun.getName().str());
699 }
701 else if (fun.getName().str() == "svf__main")
702 {
703 ExtFuncsVec.push_back(&fun);
704 }
705 else
706 {
707 extFuncs.insert(&fun);
708 extFunDefNames.insert(fun.getName().str());
709 }
710 }
711 }
712 else
713 {
714 appModule = &mod;
716 for (const Function& fun : mod.functions())
717 {
718 if (fun.isDeclaration())
719 {
720 appFunDecls.insert(&fun);
721 appFuncDeclNames.insert(fun.getName().str());
722 }
723 else
724 {
725 appFunDefs.insert(&fun);
726 appFuncDefNames.insert(fun.getName().str());
727 }
728 }
729 }
730 }
731
732 // Find the intersectNames between appFuncDefNames and externalFunDefNames
733 std::set_intersection(
734 appFuncDefNames.begin(), appFuncDefNames.end(), extFunDefNames.begin(), extFunDefNames.end(),
735 std::inserter(intersectNames, intersectNames.end()));
736
738 {
739 assert(!(appFunToReplace == NULL && appModule == NULL) && "appFunToReplace and appModule cannot both be NULL");
740
741 if (appFunToReplace)
742 {
743 appModule = appFunToReplace->getParent();
744 }
745 Function* clonedFunction = Function::Create(extFunToClone->getFunctionType(),
746 Function::ExternalLinkage,
747 extFunToClone->getName());
748 // Map the arguments of the new function to the arguments of extFunToClone
749 llvm::ValueToValueMapTy valueMap;
750 Function::arg_iterator destArg = clonedFunction->arg_begin();
751 for (Function::const_arg_iterator srcArg = extFunToClone->arg_begin(); srcArg != extFunToClone->arg_end(); ++srcArg)
752 {
753 destArg->setName(srcArg->getName()); // Copy the name of the original argument
754 valueMap[&*srcArg] = &*destArg++; // Add a mapping from the old arg to the new arg
755 }
756 if (cloneBody)
757 {
758 // Collect global variables referenced by extFunToClone
759 // This step identifies all global variables used within the function to be cloned
760 std::set<GlobalVariable*> referencedGlobals;
761 for (const BasicBlock& BB : *extFunToClone)
762 {
763 for (const Instruction& I : BB)
764 {
765 for (const Value* operand : I.operands())
766 {
767 // Check if the operand is a global variable
768 if (const GlobalVariable* GV = SVFUtil::dyn_cast<GlobalVariable>(operand))
769 {
770 referencedGlobals.insert(const_cast<GlobalVariable*>(GV));
771 }
772 }
773 }
774 }
775
776 // Copy global variables to target module and update valueMap
777 // When cloning a function, we need to ensure all global variables it references are available in the target module
779 {
780 // Check if the global variable already exists in the target module
781 GlobalVariable* existingGV = appModule->getGlobalVariable(GV->getName());
782 if (existingGV)
783 {
784 // If the global variable already exists, ensure type consistency
785 assert(existingGV->getType() == GV->getType() && "Global variable type mismatch in client module!");
786 // Map the original global to the existing one in the target module
787 valueMap[GV] = existingGV; // Map to existing global variable
788 }
789 else
790 {
791 // If the global variable doesn't exist in the target module, create a new one with the same properties
793 *appModule, // Target module
794 GV->getValueType(), // Type of the global variable
795 GV->isConstant(), // Whether it's constant
796 GV->getLinkage(), // Linkage type
797 nullptr, // No initializer yet
798 GV->getName(), // Same name
799 nullptr, // No insert before instruction
800 GV->getThreadLocalMode(), // Thread local mode
801 GV->getAddressSpace() // Address space
802 );
803
804 // Copy initializer if present to maintain the global's value
805 if (GV->hasInitializer())
806 {
807 Constant* init = GV->getInitializer();
808 newGV->setInitializer(init); // Simple case: direct copy
809 }
810
811 // Copy other attributes like alignment to ensure identical behavior
812 newGV->copyAttributesFrom(GV);
813
814 // Add mapping from original global to the new one for use during function cloning
815 valueMap[GV] = newGV;
816 }
817 }
818
819 // Clone function body with updated valueMap
820 llvm::SmallVector<ReturnInst*, 8> ignoredReturns;
821 CloneFunctionInto(clonedFunction, extFunToClone, valueMap, llvm::CloneFunctionChangeType::LocalChangesOnly, ignoredReturns, "", nullptr);
822 }
823 if (appFunToReplace)
824 {
825 // Replace all uses of appFunToReplace with clonedFunction
826 appFunToReplace->replaceAllUsesWith(clonedFunction);
827 std::string oldFunctionName = appFunToReplace->getName().str();
828 // Delete the old function
829 appFunToReplace->eraseFromParent();
830 appModule->getFunctionList().push_back(clonedFunction);
832 }
833 else
834 {
835 appModule->getFunctionList().push_back(clonedFunction);
836 }
837 return clonedFunction;
838 };
839
841 for (const Function* appFunDecl : appFunDecls)
842 {
843 std::string appFunDeclName = LLVMUtil::restoreFuncName(appFunDecl->getName().str());
844 for (const Function* extFun : extFuncs)
845 {
846 if (extFun->getName().str().compare(appFunDeclName) == 0)
847 {
848 auto it = ExtFun2Annotations.find(extFun->getName().str());
849 // Without annotations, this function is normal function with useful function body
850 if (it == ExtFun2Annotations.end())
851 {
852 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFun), const_cast<Function*>(appFunDecl), nullptr, true);
855 }
856 else
857 {
858 ExtFuncsVec.push_back(appFunDecl);
859 }
860 break;
861 }
862 }
863 }
864
867 for (string sameFuncDef: intersectNames)
868 {
869 Function* appFuncDef = appModule->getFunction(sameFuncDef);
870 Function* extFuncDef = extModule->getFunction(sameFuncDef);
871 if (appFuncDef == nullptr || extFuncDef == nullptr)
872 continue;
873
874 FunctionType *appFuncDefType = appFuncDef->getFunctionType();
875 FunctionType *extFuncDefType = extFuncDef->getFunctionType();
877 continue;
878
879 auto it = ExtFun2Annotations.find(sameFuncDef);
880 if (it != ExtFun2Annotations.end())
881 {
882 std::vector<std::string> annotations = it->second;
883 if (annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos)
884 {
885 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFuncDef), const_cast<Function*>(appFuncDef), nullptr, true);
888 }
889 else
890 {
891 if (annotations.size() >= 2)
892 {
893 for (const auto& annotation : annotations)
894 {
895 if(annotation.find("OVERWRITE") != std::string::npos)
896 {
897 assert(false && "overwrite and other annotations cannot co-exist");
898 }
899 }
900 }
901 }
902 }
903 }
904
906 {
907 for (inst_iterator I = inst_begin(caller), E = inst_end(caller); I != E; ++I)
908 {
909 Instruction *inst = &*I;
910
911 if (CallInst *callInst = SVFUtil::dyn_cast<CallInst>(inst))
912 {
913 Function *calledFunc = callInst->getCalledFunction();
914
915 if (calledFunc && calledFunc->getName() == callee->getName())
916 {
917 callInst->setCalledFunction(callee);
918 }
919 }
920 }
921 };
922
923 std::function<void(const Function*, Function*)> cloneAndLinkFunction;
925 {
926 if (clonedFuncs.find(extFunToClone) != clonedFuncs.end())
927 return;
928
929 Module* appModule = appClonedFun->getParent();
930 // Check if the function already exists in the parent module
931 if (appModule->getFunction(extFunToClone->getName()))
932 {
933 // The function already exists, no need to clone, but need to link it with the caller
934 Function* func = appModule->getFunction(extFunToClone->getName());
936 return;
937 }
938 // Decide whether to clone the function body based on ExtFun2Annotations
939 bool cloneBody = true;
940 auto it = ExtFun2Annotations.find(extFunToClone->getName().str());
941 if (it != ExtFun2Annotations.end())
942 {
943 std::vector<std::string> annotations = it->second;
944 if (!(annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos))
945 {
946 cloneBody = false;
947 }
948 }
949
951
953 // Add the cloned function to ExtFuncsVec for further processing
954 ExtFuncsVec.push_back(clonedFunction);
955
957
958 std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(extFunToClone);
959
960 for (const auto& calledFunction : calledFunctions)
961 {
963 }
964 };
965
966 // Recursive clone called functions
967 for (const auto& pair : extFuncs2ClonedFuncs)
968 {
969 Function* extFun = const_cast<Function*>(pair.first);
970 Function* clonedExtFun = const_cast<Function*>(pair.second);
971 std::vector<const Function*> extCalledFuns = LLVMUtil::getCalledFunctions(extFun);
972
973 for (const auto& extCalledFun : extCalledFuns)
974 {
976 }
977 }
978
979 // Remove unused annotations in ExtFun2Annotations according to the functions in ExtFuncsVec
981 for (const Function* extFun : ExtFuncsVec)
982 {
983 std::string name = LLVMUtil::restoreFuncName(extFun->getName().str());
984 auto it = ExtFun2Annotations.find(name);
985 if (it != ExtFun2Annotations.end())
986 {
987 std::string newKey = name;
988 if (name != extFun->getName().str())
989 {
990 newKey = extFun->getName().str();
991 }
992 newFun2AnnoMap.insert({newKey, it->second});
993 }
994 }
996
997 // Remove ExtAPI module from modules
998 auto it = std::find_if(modules.begin(), modules.end(),
999 [&extModule](const std::reference_wrapper<llvm::Module>& moduleRef)
1000 {
1001 return &moduleRef.get() == extModule;
1002 });
1003
1004 if (it != modules.end())
1005 {
1006 size_t index = std::distance(modules.begin(), it);
1007 modules.erase(it);
1008 owned_modules.erase(owned_modules.begin() + index);
1009 }
1010}
1011
1013{
1016 for (Module &mod : modules)
1017 {
1018 // Collect ctor and dtor functions
1019 for (GlobalVariable& global : mod.globals())
1020 {
1021 if (global.hasPrivateLinkage())
1022 continue;
1023 string name = global.getName().str();
1024 if (name.empty())
1025 continue;
1026 nameToGlobalsMap[std::move(name)].insert(&global);
1027 }
1028 }
1029
1030 for (const auto& pair : nameToGlobalsMap)
1031 {
1032 const Set<GlobalVariable*> &globals = pair.second;
1033
1034 const auto repIt =
1035 std::find_if(globals.begin(), globals.end(),
1036 [](GlobalVariable* g)
1037 {
1038 return g->hasInitializer();
1039 });
1040 GlobalVariable* rep =
1041 repIt != globals.end()
1042 ? *repIt
1043 // When there is no initializer, just pick the first one.
1044 : (assert(!globals.empty() && "Empty global set"),
1045 *globals.begin());
1046
1047 for (const GlobalVariable* cur : globals)
1048 {
1049 GlobalDefToRepMap[cur] = rep;
1050 }
1051 }
1052}
1053
1054// Dump modules to files
1056{
1057 for (Module& mod : modules)
1058 {
1059 std::string moduleName = mod.getName().str();
1060 std::string OutputFilename;
1061 std::size_t pos = moduleName.rfind('.');
1062 if (pos != std::string::npos)
1063 OutputFilename = moduleName.substr(0, pos) + suffix;
1064 else
1065 OutputFilename = moduleName + suffix;
1066
1067 std::error_code EC;
1068 raw_fd_ostream OS(OutputFilename.c_str(), EC, llvm::sys::fs::OF_None);
1069
1070#if (LLVM_VERSION_MAJOR >= 7)
1072#else
1074#endif
1075
1076 OS.flush();
1077 }
1078}
1079
1081{
1082 if (SVFUtil::isa<ConstantPointerNull>(llvm_value))
1083 return svfir->nullPtrSymID();
1084 else if (SVFUtil::isa<UndefValue>(llvm_value))
1085 return svfir->blkPtrSymID();
1086 else
1087 {
1088 ValueToIDMapTy::const_iterator iter = valSymMap.find(llvm_value);
1089 assert(iter!=valSymMap.end() &&"value sym not found");
1090 return iter->second;
1091 }
1092}
1094{
1095 if (SVFUtil::isa<ConstantPointerNull, UndefValue>(val))
1096 return true;
1097 else
1098 return (valSymMap.find(val) != valSymMap.end());
1099}
1100
1102{
1103 if (const GlobalVariable* glob = SVFUtil::dyn_cast<GlobalVariable>(llvm_value))
1105 ValueToIDMapTy::const_iterator iter = objSymMap.find(llvm_value);
1106 assert(iter!=objSymMap.end() && "obj sym not found");
1107 return iter->second;
1108}
1109
1110
1112{
1114 for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end();
1115 ++iter)
1116 {
1117 const NodeID i = iter->second;
1118 idmap[i] = iter->first;
1119 }
1120 for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end();
1121 ++iter)
1122 {
1123 const NodeID i = iter->second;
1124 idmap[i] = iter->first;
1125 }
1126 for (FunToIDMapTy::iterator iter = retSyms().begin(); iter != retSyms().end();
1127 ++iter)
1128 {
1129 const NodeID i = iter->second;
1130 idmap[i] = iter->first;
1131 }
1132 for (FunToIDMapTy::iterator iter = varargSyms().begin(); iter != varargSyms().end();
1133 ++iter)
1134 {
1135 const NodeID i = iter->second;
1136 idmap[i] = iter->first;
1137 }
1138 SVFUtil::outs() << "{SymbolTableInfo \n";
1139
1140
1141
1142
1143 for (auto iter : idmap)
1144 {
1145 std::string str;
1146 llvm::raw_string_ostream rawstr(str);
1147 auto llvmVal = iter.second;
1148 if (llvmVal)
1149 rawstr << " " << *llvmVal << " ";
1150 else
1151 rawstr << " No llvmVal found";
1153 SVFUtil::outs() << iter.first << " " << rawstr.str() << "\n";
1154 }
1155 SVFUtil::outs() << "}\n";
1156}
1157
1160{
1162 svfBaseNode->setSourceLoc(LLVMUtil::getSourceLoc(val));
1163 svfBaseNode->setName(val->getName().str());
1164}
1165
1167{
1168 Function* fun = nullptr;
1169
1170 for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
1171 {
1173 fun = mod->getFunction(name);
1174 if (fun)
1175 {
1176 return llvmModuleSet->getFunObjVar(fun);
1177 }
1178 }
1179 return nullptr;
1180}
1181
1182
1184{
1185 for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it)
1186 {
1187 if (it->second == T)
1188 return it->first;
1189 }
1190 assert(false && "can't find the corresponding LLVM Type");
1191 abort();
1192}
1193
1198{
1199 assert(T && "SVFType should not be null");
1200 LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.find(T);
1201 if (it != LLVMType2SVFType.end())
1202 return it->second;
1203
1206 svfType->setTypeInfo(stinfo);
1207 return svfType;
1208}
1209
1210
1213{
1214 ICFGNode* node;
1216 node = getCallICFGNode(inst);
1217 else if(LLVMUtil::isIntrinsicInst(inst))
1218 node = getIntraICFGNode(inst);
1219 else
1220 node = getIntraICFGNode(inst);
1221
1222 assert (node!=nullptr && "no ICFGNode for this instruction?");
1223 return node;
1224}
1225
1227{
1228 ICFGNode* node;
1230 node = getCallBlock(inst);
1231 else if(LLVMUtil::isIntrinsicInst(inst))
1232 node = getIntraBlock(inst);
1233 else
1234 node = getIntraBlock(inst);
1235
1236 return node != nullptr;
1237}
1238
1240{
1241 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1242 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1243 CallICFGNode* node = getCallBlock(inst);
1244 assert (node!=nullptr && "no CallICFGNode for this instruction?");
1245 return node;
1246}
1247
1249{
1250 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1251 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1252 RetICFGNode* node = getRetBlock(inst);
1253 assert (node!=nullptr && "no RetICFGNode for this instruction?");
1254 return node;
1255}
1256
1258{
1259 IntraICFGNode* node = getIntraBlock(inst);
1260 assert (node!=nullptr && "no IntraICFGNode for this instruction?");
1261 return node;
1262}
1263
1265{
1266 Type2TypeInfoMap::iterator tit = Type2TypeInfo.find(T);
1267 if (tit != Type2TypeInfo.end())
1268 {
1269 return tit->second;
1270 }
1271 // No such StInfo for T, create it now.
1272 StInfo* stInfo;
1273 if (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(T))
1274 {
1276 }
1277 else if (const StructType* sty = SVFUtil::dyn_cast<StructType>(T))
1278 {
1279 u32_t nf;
1281 if (nf > svfir->maxStSize)
1282 {
1284 svfir->maxStSize = nf;
1285 }
1286 }
1287 else
1288 {
1290 }
1291 Type2TypeInfo.emplace(T, stInfo);
1293 return stInfo;
1294}
1295
1297{
1298 assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() &&
1299 "SVFType has been added before");
1300
1301 // add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 1 (default value)
1302 u32_t byteSize = 1;
1303 if (T->isSized())
1304 {
1305 const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()->
1306 getMainLLVMModule()->getDataLayout();
1307 Type *mut_T = const_cast<Type *>(T);
1308 byteSize = DL.getTypeAllocSize(mut_T);
1309 }
1310
1312
1314 if (SVFUtil::isa<PointerType>(T))
1315 {
1316 svftype = new SVFPointerType(id, byteSize);
1317 }
1318 else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
1319 {
1320 auto svfIntT = new SVFIntegerType(id, byteSize);
1321 unsigned signWidth = intT->getBitWidth();
1322 assert(signWidth < INT16_MAX && "Integer width too big");
1323 svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
1324 svftype = svfIntT;
1325 }
1326 else if (const FunctionType* ft = SVFUtil::dyn_cast<FunctionType>(T))
1327 {
1328 std::vector<const SVFType*> paramTypes;
1329 for (const auto& t: ft->params())
1330 {
1331 paramTypes.push_back(getSVFType(t));
1332 }
1333 svftype = new SVFFunctionType(id, getSVFType(ft->getReturnType()), paramTypes, ft->isVarArg());
1334 }
1335 else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
1336 {
1337 std::vector<const SVFType*> fieldTypes;
1338
1339 for (const auto& t: st->elements())
1340 {
1341 fieldTypes.push_back(getSVFType(t));
1342 }
1343 auto svfst = new SVFStructType(id, fieldTypes, byteSize);
1344 if (st->hasName())
1345 svfst->setName(st->getName().str());
1346 svftype = svfst;
1347 }
1348 else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
1349 {
1350 auto svfat = new SVFArrayType(id, byteSize);
1351 svfat->setNumOfElement(at->getNumElements());
1352 svfat->setTypeOfElement(getSVFType(at->getElementType()));
1353 svftype = svfat;
1354 }
1355 else
1356 {
1357 std::string buffer;
1358 auto ot = new SVFOtherType(id, T->isSingleValueType(), byteSize);
1359 llvm::raw_string_ostream(buffer) << *T;
1360 ot->setRepr(std::move(buffer));
1361 svftype = ot;
1362 }
1363
1366
1367 return svftype;
1368}
1369
1374{
1375 u64_t totalElemNum = ty->getNumElements();
1376 const Type* elemTy = ty->getElementType();
1377 while (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(elemTy))
1378 {
1379 totalElemNum *= aty->getNumElements();
1380 elemTy = aty->getElementType();
1381 }
1382
1385
1387 if (totalElemNum == 0)
1388 {
1389 stInfo->addFldWithType(0, elemSvfType, 0);
1390 stInfo->setNumOfFieldsAndElems(1, 1);
1391 stInfo->getFlattenFieldTypes().push_back(elemSvfType);
1392 stInfo->getFlattenElementTypes().push_back(elemSvfType);
1393 return stInfo;
1394 }
1395
1399 u32_t nfF = elemStInfo->getNumOfFlattenFields();
1400 u32_t nfE = elemStInfo->getNumOfFlattenElements();
1401 for (u32_t j = 0; j < nfF; j++)
1402 {
1403 const SVFType* fieldTy = elemStInfo->getFlattenFieldTypes()[j];
1404 stInfo->getFlattenFieldTypes().push_back(fieldTy);
1405 }
1406
1409 u32_t outArrayElemNum = ty->getNumElements();
1410 for (u32_t i = 0; i < outArrayElemNum; ++i)
1411 {
1412 auto idx = (i * nfE * totalElemNum) / outArrayElemNum;
1413 stInfo->addFldWithType(0, elemSvfType, idx);
1414 }
1415
1416 for (u32_t i = 0; i < totalElemNum; ++i)
1417 {
1418 for (u32_t j = 0; j < nfE; ++j)
1419 {
1420 const SVFType* et = elemStInfo->getFlattenElementTypes()[j];
1421 stInfo->getFlattenElementTypes().push_back(et);
1422 }
1423 }
1424
1425 assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum &&
1426 "typeForArray size incorrect!!!");
1427 stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum);
1428
1429 return stInfo;
1430}
1431
1438{
1440 StInfo* stInfo = new StInfo(1);
1441
1442 // Number of fields after flattening the struct
1443 numFields = 0;
1444 // The offset when considering array stride info
1445 u32_t strideOffset = 0;
1446 for (const Type* elemTy : structTy->elements())
1447 {
1449 // offset with int_32 (s32_t) is large enough and won't overflow
1450 stInfo->addFldWithType(numFields, elemSvfTy, strideOffset);
1451
1452 if (SVFUtil::isa<StructType, ArrayType>(elemTy))
1453 {
1455 u32_t nfF = subStInfo->getNumOfFlattenFields();
1456 u32_t nfE = subStInfo->getNumOfFlattenElements();
1457 // Copy ST's info, whose element 0 is the size of ST itself.
1458 for (u32_t j = 0; j < nfF; ++j)
1459 {
1460 const SVFType* elemTy = subStInfo->getFlattenFieldTypes()[j];
1461 stInfo->getFlattenFieldTypes().push_back(elemTy);
1462 }
1463 numFields += nfF;
1464 strideOffset += nfE;
1465 for (u32_t tpj = 0; tpj < nfE; ++tpj)
1466 {
1467 const SVFType* ty = subStInfo->getFlattenElementTypes()[tpj];
1468 stInfo->getFlattenElementTypes().push_back(ty);
1469 }
1470
1471 }
1472 else
1473 {
1474 // Simple type
1475 numFields += 1;
1476 strideOffset += 1;
1477 stInfo->getFlattenFieldTypes().push_back(elemSvfTy);
1478 stInfo->getFlattenElementTypes().push_back(elemSvfTy);
1479 }
1480 }
1481
1482 assert(stInfo->getFlattenElementTypes().size() == strideOffset &&
1483 "typeForStruct size incorrect!");
1484 stInfo->setNumOfFieldsAndElems(numFields,strideOffset);
1485
1486 return stInfo;
1487}
1488
1489
1494{
1496 StInfo* stInfo = new StInfo(1);
1498 stInfo->addFldWithType(0, svfType, 0);
1499
1500 stInfo->getFlattenFieldTypes().push_back(svfType);
1501 stInfo->getFlattenElementTypes().push_back(svfType);
1502 stInfo->setNumOfFieldsAndElems(1,1);
1503
1504 return stInfo;
1505}
1506
1507void LLVMModuleSet::setExtFuncAnnotations(const Function* fun, const std::vector<std::string>& funcAnnotations)
1508{
1509 assert(fun && "Null SVFFunction* pointer");
1511}
1512
1514{
1515 assert(fun && "Null SVFFunction* pointer");
1516 auto it = func2Annotations.find(fun);
1517 if (it != func2Annotations.end())
1518 {
1519 for (const std::string& annotation : it->second)
1520 if (annotation.find(funcAnnotation) != std::string::npos)
1521 return true;
1522 }
1523 return false;
1524}
1525
1526std::string LLVMModuleSet::getExtFuncAnnotation(const Function* fun, const std::string& funcAnnotation)
1527{
1528 assert(fun && "Null Function* pointer");
1529 auto it = func2Annotations.find(fun);
1530 if (it != func2Annotations.end())
1531 {
1532 for (const std::string& annotation : it->second)
1533 if (annotation.find(funcAnnotation) != std::string::npos)
1534 return annotation;
1535 }
1536 return "";
1537}
1538
1539const std::vector<std::string>& LLVMModuleSet::getExtFuncAnnotations(const Function* fun)
1540{
1541 assert(fun && "Null Function* pointer");
1542 auto it = func2Annotations.find(fun);
1543 if (it != func2Annotations.end())
1544 return it->second;
1545 return func2Annotations[fun];
1546}
1547
1549{
1550 return F &&
1551 (hasExtFuncAnnotation(F, "MEMCPY") || hasExtFuncAnnotation(F, "STRCPY")
1552 || hasExtFuncAnnotation(F, "STRCAT"));
1553}
1554
1556{
1557 return F && hasExtFuncAnnotation(F, "MEMSET");
1558}
1559
1561{
1562 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_RET");
1563}
1564
1565// Does (F) allocate a new object and assign it to one of its arguments?
1567{
1568 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1569}
1570
1572{
1573 return F && hasExtFuncAnnotation(F, "ALLOC_STACK_RET");
1574}
1575
1576// Get the position of argument which holds the new object
1578{
1579 std::string allocArg = getExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1580 assert(!allocArg.empty() && "Not an alloc call via argument or incorrect extern function annotation!");
1581
1582 std::string number;
1583 for (char c : allocArg)
1584 {
1585 if (isdigit(c))
1586 number.push_back(c);
1587 }
1588 assert(!number.empty() && "Incorrect naming convention for svf external functions(ALLOC_HEAP_ARG + number)?");
1589 return std::stoi(number);
1590}
1591
1592// Does (F) reallocate a new object?
1594{
1595 return F && hasExtFuncAnnotation(F, "REALLOC_HEAP_RET");
1596}
1597
1598
1599// Should (F) be considered "external" (either not defined in the program
1600// or a user-defined version of a known alloc or no-op)?
1602{
1603 assert(F && "Null SVFFunction* pointer");
1604 if (F->isDeclaration() || F->isIntrinsic())
1605 return true;
1606 else if (hasExtFuncAnnotation(F, "OVERWRITE") && getExtFuncAnnotations(F).size() == 1)
1607 return false;
1608 else
1609 return !getExtFuncAnnotations(F).empty();
1610}
#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:593
#define TIMEINTERVAL
Definition SVFType.h:621
#define DGENERAL
Definition SVFType.h:599
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:136
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:44
const SVFType * maxStruct
The struct type with the most fields.
Definition IRGraph.h:360
void addStInfo(StInfo *stInfo)
Definition IRGraph.h:372
NodeID blkPtrSymID() const
Definition IRGraph.h:178
NodeID nullPtrSymID() const
Definition IRGraph.h:183
void addTypeInfo(const SVFType *ty)
Definition IRGraph.h:365
u32_t maxStSize
The number of fields in max_struct.
Definition IRGraph.h:363
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.
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< std::string > Graphtxt
Definition Options.h:179
static Option< bool > SVFMain
Definition Options.h:180
static bool pagReadFromTXT()
Definition SVFIR.h:278
void setModuleIdentifier(const std::string &moduleIdentifier)
Definition SVFIR.h:288
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:118
static void setPagFromTXT(const std::string &txt)
Definition SVFIR.h:283
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:232
static SVFType * svfI8Ty
8-bit int type
Definition SVFType.h:233
#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:203
std::vector< const Function * > getCalledFunctions(const Function *F)
Get all called funcions in a parent function.
Definition LLVMUtil.cpp:364
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:45
bool functionDoesNotRet(const Function *fun)
Definition LLVMUtil.cpp:123
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:83
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:453
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:440
bool basicBlockHasRetInst(const BasicBlock *bb)
Return true if the function has a return instruction.
Definition LLVMUtil.cpp:109
bool isIRFile(const std::string &filename)
Check whether a file is an LLVM IR file.
Definition LLVMUtil.cpp:315
std::string restoreFuncName(std::string funcName)
Definition LLVMUtil.cpp:407
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:725
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: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:49
llvm::IntegerType IntegerType
Definition BasicTypes.h:101
u32_t NodeID
Definition GeneralType.h:56
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:48
llvm::Module Module
Definition BasicTypes.h:88
unsigned u32_t
Definition GeneralType.h:47
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)