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