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().equals(SVF_GLOBAL_CTORS) && global.hasInitializer())
522 {
524 }
525 else if (global.getName().equals(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.equals(SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
537
538 if (funName.equals("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}
602
604{
605 GlobalVariable *glob = mod->getGlobalVariable("llvm.global.annotations");
606 if (glob == nullptr || !glob->hasInitializer())
607 return;
608
609 ConstantArray *ca = SVFUtil::dyn_cast<ConstantArray>(glob->getInitializer());
610 if (ca == nullptr)
611 return;
612
613 for (unsigned i = 0; i < ca->getNumOperands(); ++i)
614 {
615 ConstantStruct *structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
616 if (structAn == nullptr || structAn->getNumOperands() == 0)
617 continue;
618
619 // Check if the annotation is for a function
620 Function* fun = nullptr;
621 GlobalVariable *annotateStr = nullptr;
623 if (ConstantExpr *expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0)))
624 {
625 if (expr->getOpcode() == Instruction::BitCast && SVFUtil::isa<Function>(expr->getOperand(0)))
626 fun = SVFUtil::cast<Function>(expr->getOperand(0));
627
628 ConstantExpr *note = SVFUtil::cast<ConstantExpr>(structAn->getOperand(1));
629 if (note->getOpcode() != Instruction::GetElementPtr)
630 continue;
631
632 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(note->getOperand(0));
633 }
635 else
636 {
637 fun = SVFUtil::dyn_cast<Function>(structAn->getOperand(0));
638 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(structAn->getOperand(1));
639 }
640
641 if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer())
642 continue;;
643
644 ConstantDataSequential *data = SVFUtil::dyn_cast<ConstantDataSequential>(annotateStr->getInitializer());
645 if (data && data->isString())
646 {
647 std::string annotation = data->getAsString().str();
648 if (!annotation.empty())
649 ExtFun2Annotations[fun->getName().str()].push_back(annotation);
650 }
651 }
652}
653
654/*
655 There are three types of functions(definitions) in extapi.c:
656 1. (Fun_Overwrite): Functions with "OVERWRITE" annotion:
657 These functions are used to replace the corresponding function definitions in the application.
658 2. (Fun_Annotation): Functions with annotation(s) but without "OVERWRITE" annotation:
659 These functions are used to tell SVF to do special processing, like malloc().
660 3. (Fun_Noraml): Functions without any annotation:
661 These functions are used to replace the corresponding function declarations in the application.
662
663
664 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:
665 1. appFuncDecl --> Fun_Normal: Clone the Fun_Overwrite and replace the appFuncDecl in application.
666 2. appFuncDecl --> Fun_Annotation: Move the annotions on Fun_Annotation to appFuncDecl in application.
667
668 3. appFunDef --> Fun_Overwrite: Clone the Fun_Overwrite and overwrite the appFunDef in application.
669 4. appFunDef --> Fun_Annotation: Replace the appFunDef with appFunDecl and move the annotions to appFunDecl in application
670*/
672{
676 Module* appModule = nullptr;
677 Module* extModule = nullptr;
678
679 for (Module& mod : modules)
680 {
681 // extapi.bc functions
682 if (mod.getName().str() == ExtAPI::getExtAPI()->getExtBcPath())
683 {
685 extModule = &mod;
686 for (const Function& fun : mod.functions())
687 {
688 // there is main declaration in ext bc, it should be mapped to
689 // main definition in app bc.
690 if (fun.getName().str() == "main")
691 {
692 appFunDecls.insert(&fun);
693 appFuncDeclNames.insert(fun.getName().str());
694 }
696 else if (fun.getName().str() == "svf__main")
697 {
698 ExtFuncsVec.push_back(&fun);
699 }
700 else
701 {
702 extFuncs.insert(&fun);
703 extFunDefNames.insert(fun.getName().str());
704 }
705 }
706 }
707 else
708 {
709 appModule = &mod;
711 for (const Function& fun : mod.functions())
712 {
713 if (fun.isDeclaration())
714 {
715 appFunDecls.insert(&fun);
716 appFuncDeclNames.insert(fun.getName().str());
717 }
718 else
719 {
720 appFunDefs.insert(&fun);
721 appFuncDefNames.insert(fun.getName().str());
722 }
723 }
724 }
725 }
726
727 // Find the intersectNames between appFuncDefNames and externalFunDefNames
728 std::set_intersection(
729 appFuncDefNames.begin(), appFuncDefNames.end(), extFunDefNames.begin(), extFunDefNames.end(),
730 std::inserter(intersectNames, intersectNames.end()));
731
733 {
734 assert(!(appFunToReplace == NULL && appModule == NULL) && "appFunToReplace and appModule cannot both be NULL");
735
736 if (appFunToReplace)
737 {
738 appModule = appFunToReplace->getParent();
739 }
740 // Create a new function with the same signature as extFunToClone
741 Function *clonedFunction = Function::Create(extFunToClone->getFunctionType(), Function::ExternalLinkage, extFunToClone->getName(), appModule);
742 // Map the arguments of the new function to the arguments of extFunToClone
743 llvm::ValueToValueMapTy valueMap;
744 Function::arg_iterator destArg = clonedFunction->arg_begin();
745 for (Function::const_arg_iterator srcArg = extFunToClone->arg_begin(); srcArg != extFunToClone->arg_end(); ++srcArg)
746 {
747 destArg->setName(srcArg->getName()); // Copy the name of the original argument
748 valueMap[&*srcArg] = &*destArg++; // Add a mapping from the old arg to the new arg
749 }
750 if (cloneBody)
751 {
752 // Collect global variables referenced by extFunToClone
753 // This step identifies all global variables used within the function to be cloned
754 std::set<GlobalVariable*> referencedGlobals;
755 for (const BasicBlock& BB : *extFunToClone)
756 {
757 for (const Instruction& I : BB)
758 {
759 for (const Value* operand : I.operands())
760 {
761 // Check if the operand is a global variable
762 if (const GlobalVariable* GV = SVFUtil::dyn_cast<GlobalVariable>(operand))
763 {
764 referencedGlobals.insert(const_cast<GlobalVariable*>(GV));
765 }
766 }
767 }
768 }
769
770 // Copy global variables to target module and update valueMap
771 // When cloning a function, we need to ensure all global variables it references are available in the target module
773 {
774 // Check if the global variable already exists in the target module
775 GlobalVariable* existingGV = appModule->getGlobalVariable(GV->getName());
776 if (existingGV)
777 {
778 // If the global variable already exists, ensure type consistency
779 assert(existingGV->getType() == GV->getType() && "Global variable type mismatch in client module!");
780 // Map the original global to the existing one in the target module
781 valueMap[GV] = existingGV; // Map to existing global variable
782 }
783 else
784 {
785 // If the global variable doesn't exist in the target module, create a new one with the same properties
787 *appModule, // Target module
788 GV->getValueType(), // Type of the global variable
789 GV->isConstant(), // Whether it's constant
790 GV->getLinkage(), // Linkage type
791 nullptr, // No initializer yet
792 GV->getName(), // Same name
793 nullptr, // No insert before instruction
794 GV->getThreadLocalMode(), // Thread local mode
795 GV->getAddressSpace() // Address space
796 );
797
798 // Copy initializer if present to maintain the global's value
799 if (GV->hasInitializer())
800 {
801 Constant* init = GV->getInitializer();
802 newGV->setInitializer(init); // Simple case: direct copy
803 }
804
805 // Copy other attributes like alignment to ensure identical behavior
806 newGV->copyAttributesFrom(GV);
807
808 // Add mapping from original global to the new one for use during function cloning
809 valueMap[GV] = newGV;
810 }
811 }
812
813 // Clone function body with updated valueMap
814 llvm::SmallVector<ReturnInst*, 8> ignoredReturns;
815 CloneFunctionInto(clonedFunction, extFunToClone, valueMap, llvm::CloneFunctionChangeType::LocalChangesOnly, ignoredReturns, "", nullptr);
816 }
817 if (appFunToReplace)
818 {
819 // Replace all uses of appFunToReplace with clonedFunction
820 appFunToReplace->replaceAllUsesWith(clonedFunction);
821 std::string oldFunctionName = appFunToReplace->getName().str();
822 // Delete the old function
823 appFunToReplace->eraseFromParent();
825 }
826 return clonedFunction;
827 };
828
830 for (const Function* appFunDecl : appFunDecls)
831 {
832 std::string appFunDeclName = LLVMUtil::restoreFuncName(appFunDecl->getName().str());
833 for (const Function* extFun : extFuncs)
834 {
835 if (extFun->getName().str().compare(appFunDeclName) == 0)
836 {
837 auto it = ExtFun2Annotations.find(extFun->getName().str());
838 // Without annotations, this function is normal function with useful function body
839 if (it == ExtFun2Annotations.end())
840 {
841 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFun), const_cast<Function*>(appFunDecl), nullptr, true);
844 }
845 else
846 {
847 ExtFuncsVec.push_back(appFunDecl);
848 }
849 break;
850 }
851 }
852 }
853
856 for (string sameFuncDef: intersectNames)
857 {
858 Function* appFuncDef = appModule->getFunction(sameFuncDef);
859 Function* extFuncDef = extModule->getFunction(sameFuncDef);
860 if (appFuncDef == nullptr || extFuncDef == nullptr)
861 continue;
862
863 FunctionType *appFuncDefType = appFuncDef->getFunctionType();
864 FunctionType *extFuncDefType = extFuncDef->getFunctionType();
866 continue;
867
868 auto it = ExtFun2Annotations.find(sameFuncDef);
869 if (it != ExtFun2Annotations.end())
870 {
871 std::vector<std::string> annotations = it->second;
872 if (annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos)
873 {
874 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFuncDef), const_cast<Function*>(appFuncDef), nullptr, true);
877 }
878 else
879 {
880 if (annotations.size() >= 2)
881 {
882 for (const auto& annotation : annotations)
883 {
884 if(annotation.find("OVERWRITE") != std::string::npos)
885 {
886 assert(false && "overwrite and other annotations cannot co-exist");
887 }
888 }
889 }
890 }
891 }
892 }
893
895 {
896 for (inst_iterator I = inst_begin(caller), E = inst_end(caller); I != E; ++I)
897 {
898 Instruction *inst = &*I;
899
900 if (CallInst *callInst = SVFUtil::dyn_cast<CallInst>(inst))
901 {
902 Function *calledFunc = callInst->getCalledFunction();
903
904 if (calledFunc && calledFunc->getName() == callee->getName())
905 {
906 callInst->setCalledFunction(callee);
907 }
908 }
909 }
910 };
911
912 std::function<void(const Function*, Function*)> cloneAndLinkFunction;
914 {
915 if (clonedFuncs.find(extFunToClone) != clonedFuncs.end())
916 return;
917
918 Module* appModule = appClonedFun->getParent();
919 // Check if the function already exists in the parent module
920 if (appModule->getFunction(extFunToClone->getName()))
921 {
922 // The function already exists, no need to clone, but need to link it with the caller
923 Function* func = appModule->getFunction(extFunToClone->getName());
925 return;
926 }
927 // Decide whether to clone the function body based on ExtFun2Annotations
928 bool cloneBody = true;
929 auto it = ExtFun2Annotations.find(extFunToClone->getName().str());
930 if (it != ExtFun2Annotations.end())
931 {
932 std::vector<std::string> annotations = it->second;
933 if (!(annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos))
934 {
935 cloneBody = false;
936 }
937 }
938
940
942 // Add the cloned function to ExtFuncsVec for further processing
943 ExtFuncsVec.push_back(clonedFunction);
944
946
947 std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(extFunToClone);
948
949 for (const auto& calledFunction : calledFunctions)
950 {
952 }
953 };
954
955 // Recursive clone called functions
956 for (const auto& pair : extFuncs2ClonedFuncs)
957 {
958 Function* extFun = const_cast<Function*>(pair.first);
959 Function* clonedExtFun = const_cast<Function*>(pair.second);
960 std::vector<const Function*> extCalledFuns = LLVMUtil::getCalledFunctions(extFun);
961
962 for (const auto& extCalledFun : extCalledFuns)
963 {
965 }
966 }
967
968 // Remove unused annotations in ExtFun2Annotations according to the functions in ExtFuncsVec
970 for (const Function* extFun : ExtFuncsVec)
971 {
972 std::string name = LLVMUtil::restoreFuncName(extFun->getName().str());
973 auto it = ExtFun2Annotations.find(name);
974 if (it != ExtFun2Annotations.end())
975 {
976 std::string newKey = name;
977 if (name != extFun->getName().str())
978 {
979 newKey = extFun->getName().str();
980 }
981 newFun2AnnoMap.insert({newKey, it->second});
982 }
983 }
985
986 // Remove ExtAPI module from modules
987 auto it = std::find_if(modules.begin(), modules.end(),
988 [&extModule](const std::reference_wrapper<llvm::Module>& moduleRef)
989 {
990 return &moduleRef.get() == extModule;
991 });
992
993 if (it != modules.end())
994 {
995 size_t index = std::distance(modules.begin(), it);
996 modules.erase(it);
997 owned_modules.erase(owned_modules.begin() + index);
998 }
999}
1000
1002{
1005 for (Module &mod : modules)
1006 {
1007 // Collect ctor and dtor functions
1008 for (GlobalVariable& global : mod.globals())
1009 {
1010 if (global.hasPrivateLinkage())
1011 continue;
1012 string name = global.getName().str();
1013 if (name.empty())
1014 continue;
1015 nameToGlobalsMap[std::move(name)].insert(&global);
1016 }
1017 }
1018
1019 for (const auto& pair : nameToGlobalsMap)
1020 {
1021 const Set<GlobalVariable*> &globals = pair.second;
1022
1023 const auto repIt =
1024 std::find_if(globals.begin(), globals.end(),
1025 [](GlobalVariable* g)
1026 {
1027 return g->hasInitializer();
1028 });
1029 GlobalVariable* rep =
1030 repIt != globals.end()
1031 ? *repIt
1032 // When there is no initializer, just pick the first one.
1033 : (assert(!globals.empty() && "Empty global set"),
1034 *globals.begin());
1035
1036 for (const GlobalVariable* cur : globals)
1037 {
1038 GlobalDefToRepMap[cur] = rep;
1039 }
1040 }
1041}
1042
1043// Dump modules to files
1045{
1046 for (Module& mod : modules)
1047 {
1048 std::string moduleName = mod.getName().str();
1049 std::string OutputFilename;
1050 std::size_t pos = moduleName.rfind('.');
1051 if (pos != std::string::npos)
1052 OutputFilename = moduleName.substr(0, pos) + suffix;
1053 else
1054 OutputFilename = moduleName + suffix;
1055
1056 std::error_code EC;
1057 raw_fd_ostream OS(OutputFilename.c_str(), EC, llvm::sys::fs::OF_None);
1058
1059#if (LLVM_VERSION_MAJOR >= 7)
1061#else
1063#endif
1064
1065 OS.flush();
1066 }
1067}
1068
1070{
1071 if (SVFUtil::isa<ConstantPointerNull>(llvm_value))
1072 return svfir->nullPtrSymID();
1073 else if (SVFUtil::isa<UndefValue>(llvm_value))
1074 return svfir->blkPtrSymID();
1075 else
1076 {
1077 ValueToIDMapTy::const_iterator iter = valSymMap.find(llvm_value);
1078 assert(iter!=valSymMap.end() &&"value sym not found");
1079 return iter->second;
1080 }
1081}
1083{
1084 if (SVFUtil::isa<ConstantPointerNull, UndefValue>(val))
1085 return true;
1086 else
1087 return (valSymMap.find(val) != valSymMap.end());
1088}
1089
1091{
1092 if (const GlobalVariable* glob = SVFUtil::dyn_cast<GlobalVariable>(llvm_value))
1094 ValueToIDMapTy::const_iterator iter = objSymMap.find(llvm_value);
1095 assert(iter!=objSymMap.end() && "obj sym not found");
1096 return iter->second;
1097}
1098
1099
1101{
1103 for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end();
1104 ++iter)
1105 {
1106 const NodeID i = iter->second;
1107 idmap[i] = iter->first;
1108 }
1109 for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end();
1110 ++iter)
1111 {
1112 const NodeID i = iter->second;
1113 idmap[i] = iter->first;
1114 }
1115 for (FunToIDMapTy::iterator iter = retSyms().begin(); iter != retSyms().end();
1116 ++iter)
1117 {
1118 const NodeID i = iter->second;
1119 idmap[i] = iter->first;
1120 }
1121 for (FunToIDMapTy::iterator iter = varargSyms().begin(); iter != varargSyms().end();
1122 ++iter)
1123 {
1124 const NodeID i = iter->second;
1125 idmap[i] = iter->first;
1126 }
1127 SVFUtil::outs() << "{SymbolTableInfo \n";
1128
1129
1130
1131
1132 for (auto iter : idmap)
1133 {
1134 std::string str;
1135 llvm::raw_string_ostream rawstr(str);
1136 auto llvmVal = iter.second;
1137 if (llvmVal)
1138 rawstr << " " << *llvmVal << " ";
1139 else
1140 rawstr << " No llvmVal found";
1142 SVFUtil::outs() << iter.first << " " << rawstr.str() << "\n";
1143 }
1144 SVFUtil::outs() << "}\n";
1145}
1146
1149{
1151 svfBaseNode->setSourceLoc(LLVMUtil::getSourceLoc(val));
1152 svfBaseNode->setName(val->getName().str());
1153}
1154
1156{
1157 Function* fun = nullptr;
1158
1159 for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
1160 {
1162 fun = mod->getFunction(name);
1163 if (fun)
1164 {
1165 return llvmModuleSet->getFunObjVar(fun);
1166 }
1167 }
1168 return nullptr;
1169}
1170
1171
1173{
1174 for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it)
1175 {
1176 if (it->second == T)
1177 return it->first;
1178 }
1179 assert(false && "can't find the corresponding LLVM Type");
1180 abort();
1181}
1182
1187{
1188 assert(T && "SVFType should not be null");
1189 LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.find(T);
1190 if (it != LLVMType2SVFType.end())
1191 return it->second;
1192
1195 svfType->setTypeInfo(stinfo);
1196 return svfType;
1197}
1198
1199
1202{
1203 ICFGNode* node;
1205 node = getCallICFGNode(inst);
1206 else if(LLVMUtil::isIntrinsicInst(inst))
1207 node = getIntraICFGNode(inst);
1208 else
1209 node = getIntraICFGNode(inst);
1210
1211 assert (node!=nullptr && "no ICFGNode for this instruction?");
1212 return node;
1213}
1214
1216{
1217 ICFGNode* node;
1219 node = getCallBlock(inst);
1220 else if(LLVMUtil::isIntrinsicInst(inst))
1221 node = getIntraBlock(inst);
1222 else
1223 node = getIntraBlock(inst);
1224
1225 return node != nullptr;
1226}
1227
1229{
1230 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1231 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1232 CallICFGNode* node = getCallBlock(inst);
1233 assert (node!=nullptr && "no CallICFGNode for this instruction?");
1234 return node;
1235}
1236
1238{
1239 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1240 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1241 RetICFGNode* node = getRetBlock(inst);
1242 assert (node!=nullptr && "no RetICFGNode for this instruction?");
1243 return node;
1244}
1245
1247{
1248 IntraICFGNode* node = getIntraBlock(inst);
1249 assert (node!=nullptr && "no IntraICFGNode for this instruction?");
1250 return node;
1251}
1252
1254{
1255 Type2TypeInfoMap::iterator tit = Type2TypeInfo.find(T);
1256 if (tit != Type2TypeInfo.end())
1257 {
1258 return tit->second;
1259 }
1260 // No such StInfo for T, create it now.
1261 StInfo* stInfo;
1262 if (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(T))
1263 {
1265 }
1266 else if (const StructType* sty = SVFUtil::dyn_cast<StructType>(T))
1267 {
1268 u32_t nf;
1270 if (nf > svfir->maxStSize)
1271 {
1273 svfir->maxStSize = nf;
1274 }
1275 }
1276 else
1277 {
1279 }
1280 Type2TypeInfo.emplace(T, stInfo);
1282 return stInfo;
1283}
1284
1286{
1287 assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() &&
1288 "SVFType has been added before");
1289
1290 // add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 1 (default value)
1291 u32_t byteSize = 1;
1292 if (T->isSized())
1293 {
1294 const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()->
1295 getMainLLVMModule()->getDataLayout();
1296 Type *mut_T = const_cast<Type *>(T);
1297 byteSize = DL.getTypeAllocSize(mut_T);
1298 }
1299
1301
1303 if (SVFUtil::isa<PointerType>(T))
1304 {
1305 svftype = new SVFPointerType(id, byteSize);
1306 }
1307 else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
1308 {
1309 auto svfIntT = new SVFIntegerType(id, byteSize);
1310 unsigned signWidth = intT->getBitWidth();
1311 assert(signWidth < INT16_MAX && "Integer width too big");
1312 svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
1313 svftype = svfIntT;
1314 }
1315 else if (const FunctionType* ft = SVFUtil::dyn_cast<FunctionType>(T))
1316 {
1317 std::vector<const SVFType*> paramTypes;
1318 for (const auto& t: ft->params())
1319 {
1320 paramTypes.push_back(getSVFType(t));
1321 }
1322 svftype = new SVFFunctionType(id, getSVFType(ft->getReturnType()), paramTypes, ft->isVarArg());
1323 }
1324 else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
1325 {
1326 std::vector<const SVFType*> fieldTypes;
1327
1328 for (const auto& t: st->elements())
1329 {
1330 fieldTypes.push_back(getSVFType(t));
1331 }
1332 auto svfst = new SVFStructType(id, fieldTypes, byteSize);
1333 if (st->hasName())
1334 svfst->setName(st->getName().str());
1335 svftype = svfst;
1336 }
1337 else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
1338 {
1339 auto svfat = new SVFArrayType(id, byteSize);
1340 svfat->setNumOfElement(at->getNumElements());
1341 svfat->setTypeOfElement(getSVFType(at->getElementType()));
1342 svftype = svfat;
1343 }
1344 else
1345 {
1346 std::string buffer;
1347 auto ot = new SVFOtherType(id, T->isSingleValueType(), byteSize);
1348 llvm::raw_string_ostream(buffer) << *T;
1349 ot->setRepr(std::move(buffer));
1350 svftype = ot;
1351 }
1352
1355
1356 return svftype;
1357}
1358
1363{
1364 u64_t totalElemNum = ty->getNumElements();
1365 const Type* elemTy = ty->getElementType();
1366 while (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(elemTy))
1367 {
1368 totalElemNum *= aty->getNumElements();
1369 elemTy = aty->getElementType();
1370 }
1371
1374
1376 if (totalElemNum == 0)
1377 {
1378 stInfo->addFldWithType(0, elemSvfType, 0);
1379 stInfo->setNumOfFieldsAndElems(1, 1);
1380 stInfo->getFlattenFieldTypes().push_back(elemSvfType);
1381 stInfo->getFlattenElementTypes().push_back(elemSvfType);
1382 return stInfo;
1383 }
1384
1388 u32_t nfF = elemStInfo->getNumOfFlattenFields();
1389 u32_t nfE = elemStInfo->getNumOfFlattenElements();
1390 for (u32_t j = 0; j < nfF; j++)
1391 {
1392 const SVFType* fieldTy = elemStInfo->getFlattenFieldTypes()[j];
1393 stInfo->getFlattenFieldTypes().push_back(fieldTy);
1394 }
1395
1398 u32_t outArrayElemNum = ty->getNumElements();
1399 for (u32_t i = 0; i < outArrayElemNum; ++i)
1400 {
1401 auto idx = (i * nfE * totalElemNum) / outArrayElemNum;
1402 stInfo->addFldWithType(0, elemSvfType, idx);
1403 }
1404
1405 for (u32_t i = 0; i < totalElemNum; ++i)
1406 {
1407 for (u32_t j = 0; j < nfE; ++j)
1408 {
1409 const SVFType* et = elemStInfo->getFlattenElementTypes()[j];
1410 stInfo->getFlattenElementTypes().push_back(et);
1411 }
1412 }
1413
1414 assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum &&
1415 "typeForArray size incorrect!!!");
1416 stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum);
1417
1418 return stInfo;
1419}
1420
1427{
1429 StInfo* stInfo = new StInfo(1);
1430
1431 // Number of fields after flattening the struct
1432 numFields = 0;
1433 // The offset when considering array stride info
1434 u32_t strideOffset = 0;
1435 for (const Type* elemTy : structTy->elements())
1436 {
1438 // offset with int_32 (s32_t) is large enough and won't overflow
1439 stInfo->addFldWithType(numFields, elemSvfTy, strideOffset);
1440
1441 if (SVFUtil::isa<StructType, ArrayType>(elemTy))
1442 {
1444 u32_t nfF = subStInfo->getNumOfFlattenFields();
1445 u32_t nfE = subStInfo->getNumOfFlattenElements();
1446 // Copy ST's info, whose element 0 is the size of ST itself.
1447 for (u32_t j = 0; j < nfF; ++j)
1448 {
1449 const SVFType* elemTy = subStInfo->getFlattenFieldTypes()[j];
1450 stInfo->getFlattenFieldTypes().push_back(elemTy);
1451 }
1452 numFields += nfF;
1453 strideOffset += nfE;
1454 for (u32_t tpj = 0; tpj < nfE; ++tpj)
1455 {
1456 const SVFType* ty = subStInfo->getFlattenElementTypes()[tpj];
1457 stInfo->getFlattenElementTypes().push_back(ty);
1458 }
1459
1460 }
1461 else
1462 {
1463 // Simple type
1464 numFields += 1;
1465 strideOffset += 1;
1466 stInfo->getFlattenFieldTypes().push_back(elemSvfTy);
1467 stInfo->getFlattenElementTypes().push_back(elemSvfTy);
1468 }
1469 }
1470
1471 assert(stInfo->getFlattenElementTypes().size() == strideOffset &&
1472 "typeForStruct size incorrect!");
1473 stInfo->setNumOfFieldsAndElems(numFields,strideOffset);
1474
1475 return stInfo;
1476}
1477
1478
1483{
1485 StInfo* stInfo = new StInfo(1);
1487 stInfo->addFldWithType(0, svfType, 0);
1488
1489 stInfo->getFlattenFieldTypes().push_back(svfType);
1490 stInfo->getFlattenElementTypes().push_back(svfType);
1491 stInfo->setNumOfFieldsAndElems(1,1);
1492
1493 return stInfo;
1494}
1495
1496void LLVMModuleSet::setExtFuncAnnotations(const Function* fun, const std::vector<std::string>& funcAnnotations)
1497{
1498 assert(fun && "Null SVFFunction* pointer");
1500}
1501
1503{
1504 assert(fun && "Null SVFFunction* pointer");
1505 auto it = func2Annotations.find(fun);
1506 if (it != func2Annotations.end())
1507 {
1508 for (const std::string& annotation : it->second)
1509 if (annotation.find(funcAnnotation) != std::string::npos)
1510 return true;
1511 }
1512 return false;
1513}
1514
1515std::string LLVMModuleSet::getExtFuncAnnotation(const Function* fun, const std::string& funcAnnotation)
1516{
1517 assert(fun && "Null Function* pointer");
1518 auto it = func2Annotations.find(fun);
1519 if (it != func2Annotations.end())
1520 {
1521 for (const std::string& annotation : it->second)
1522 if (annotation.find(funcAnnotation) != std::string::npos)
1523 return annotation;
1524 }
1525 return "";
1526}
1527
1528const std::vector<std::string>& LLVMModuleSet::getExtFuncAnnotations(const Function* fun)
1529{
1530 assert(fun && "Null Function* pointer");
1531 auto it = func2Annotations.find(fun);
1532 if (it != func2Annotations.end())
1533 return it->second;
1534 return func2Annotations[fun];
1535}
1536
1538{
1539 return F &&
1540 (hasExtFuncAnnotation(F, "MEMCPY") || hasExtFuncAnnotation(F, "STRCPY")
1541 || hasExtFuncAnnotation(F, "STRCAT"));
1542}
1543
1545{
1546 return F && hasExtFuncAnnotation(F, "MEMSET");
1547}
1548
1550{
1551 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_RET");
1552}
1553
1554// Does (F) allocate a new object and assign it to one of its arguments?
1556{
1557 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1558}
1559
1561{
1562 return F && hasExtFuncAnnotation(F, "ALLOC_STACK_RET");
1563}
1564
1565// Get the position of argument which holds the new object
1567{
1568 std::string allocArg = getExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1569 assert(!allocArg.empty() && "Not an alloc call via argument or incorrect extern function annotation!");
1570
1571 std::string number;
1572 for (char c : allocArg)
1573 {
1574 if (isdigit(c))
1575 number.push_back(c);
1576 }
1577 assert(!number.empty() && "Incorrect naming convention for svf external functions(ALLOC_HEAP_ARG + number)?");
1578 return std::stoi(number);
1579}
1580
1581// Does (F) reallocate a new object?
1583{
1584 return F && hasExtFuncAnnotation(F, "REALLOC_HEAP_RET");
1585}
1586
1587
1588// Should (F) be considered "external" (either not defined in the program
1589// or a user-defined version of a known alloc or no-op)?
1591{
1592 assert(F && "Null SVFFunction* pointer");
1593 if (F->isDeclaration() || F->isIntrinsic())
1594 return true;
1595 else if (hasExtFuncAnnotation(F, "OVERWRITE") && getExtFuncAnnotations(F).size() == 1)
1596 return false;
1597 else
1598 return !getExtFuncAnnotations(F).empty();
1599}
#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
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< bool > SVFMain
Definition Options.h:180
static const Option< std::string > Graphtxt
Definition Options.h:179
static bool pagReadFromTXT()
Definition SVFIR.h:212
void setModuleIdentifier(const std::string &moduleIdentifier)
Definition SVFIR.h:222
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:217
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: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:724
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:132
llvm::ArrayType ArrayType
Definition BasicTypes.h:97
llvm::raw_fd_ostream raw_fd_ostream
LLVM outputs.
Definition BasicTypes.h:266
llvm::Type Type
Definition BasicTypes.h:85
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:88
llvm::inst_iterator inst_iterator
Definition BasicTypes.h:251
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:108
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:96
unsigned long long u64_t
Definition GeneralType.h:49
llvm::IntegerType IntegerType
Definition BasicTypes.h:99
u32_t NodeID
Definition GeneralType.h:56
llvm::ConstantArray ConstantArray
Definition BasicTypes.h:125
llvm::Function Function
Definition BasicTypes.h:87
llvm::FunctionType FunctionType
Definition BasicTypes.h:100
llvm::Instruction Instruction
Definition BasicTypes.h:89
llvm::Constant Constant
Definition BasicTypes.h:126
llvm::SMDiagnostic SMDiagnostic
Definition BasicTypes.h:92
llvm::ConstantDataSequential ConstantDataSequential
Definition BasicTypes.h:121
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:84
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:122
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
signed s32_t
Definition GeneralType.h:48
llvm::Module Module
Definition BasicTypes.h:86
unsigned u32_t
Definition GeneralType.h:47
llvm::CallInst CallInst
Definition BasicTypes.h:149
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:127
llvm::DominatorTree DominatorTree
LLVM Dominators.
Definition BasicTypes.h:135
IntervalValue operator>(const IntervalValue &lhs, const IntervalValue &rhs)