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 "SVFIR/SVFModule.h"
33#include "Util/SVFUtil.h"
34#include "SVF-LLVM/BasicTypes.h"
35#include "SVF-LLVM/LLVMUtil.h"
36#include "SVF-LLVM/CppUtil.h"
39#include "MSSA/SVFGBuilder.h"
40#include "llvm/Support/FileSystem.h"
42#include "llvm/Transforms/Utils/Cloning.h"
44#include "Graphs/CallGraph.h"
46
47using namespace std;
48using namespace SVF;
49
50/*
51 svf.main() is used to model the real entry point of a C++ program, which
52 initializes all global C++ objects and then call main().
53 LLVM may generate two global arrays @llvm.global_ctors and @llvm.global_dtors
54 that contain constructor and destructor functions for global variables. They
55 are not called explicitly, so we have to add them in the svf.main function.
56 The order to call these constructor and destructor functions are also
57 specified in the global arrays.
58 Related part in LLVM language reference:
59 https://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable
60 For example, given a "int main(int argc, char * argv[])", the corresponding
61 svf.main will be generated as follows:
62 define void @svf.main(i32, i8**, i8**) {
63 entry:
64 call void @ctor1()
65 call void @ctor2()
66 %3 = call i32 @main(i32 %0, i8** %1)
67 call void @dtor1()
68 call void @dtor2()
69 ret void
70 }
71*/
72
73#define SVF_MAIN_FUNC_NAME "svf.main"
74#define SVF_GLOBAL_CTORS "llvm.global_ctors"
75#define SVF_GLOBAL_DTORS "llvm.global_dtors"
76
79
81 : symInfo(SymbolTableInfo::SymbolInfo()),
82 svfModule(SVFModule::getSVFModule()), typeInference(new ObjTypeInference())
83{
84}
85
87{
88 for (auto& item : LLVMInst2SVFInst)
89 {
90 delete item.second;
91 item.second = nullptr;
92 }
93 delete typeInference;
94 typeInference = nullptr;
95}
96
101
103{
104 auto it = FunToDominatorTree.find(fun);
105 if(it != FunToDominatorTree.end()) return it->second;
107 dt.recalculate(const_cast<Function&>(*fun));
108 return dt;
109}
110
112{
114
115 double startSVFModuleTime = SVFStat::getClk(true);
116 SVFModule::getSVFModule()->setModuleIdentifier(mod.getModuleIdentifier());
117 mset->modules.emplace_back(mod); // Populates `modules`; can get context via `this->getContext()`
118 mset->loadExtAPIModules(); // Uses context from module through `this->getContext()`
119 mset->build();
120 double endSVFModuleTime = SVFStat::getClk(true);
122
123 mset->buildSymbolTable();
124 // Don't releaseLLVMModuleSet() here, as IRBuilder might still need LLVMMoudleSet
126}
127
129{
130 double startSVFModuleTime = SVFStat::getClk(true);
131
133
134 mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()`
135 mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()`
136
137 if (!moduleNameVec.empty())
138 {
140 }
141
142 mset->build();
143
144 double endSVFModuleTime = SVFStat::getClk(true);
147
148 mset->buildSymbolTable();
149 // Don't releaseLLVMModuleSet() here, as IRBuilder might still need LLVMMoudleSet
151}
152
154{
155 double startSymInfoTime = SVFStat::getClk(true);
157 {
159 DBOUT(DGENERAL, SVFUtil::outs() << SVFUtil::pasMsg("Building Symbol table ...\n"));
161 builder.buildMemModel(svfModule);
162 }
163 double endSymInfoTime = SVFStat::getClk(true);
166}
167
169{
170 if(preProcessed==false)
172
175
176 if (Options::SVFMain())
177 addSVFMain();
178
181
182
184 icfg = icfgbuilder.build();
185
187 callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);
188 for (const auto& func : svfModule->getFunctionSet())
189 {
190 SVFFunction* svffunc = const_cast<SVFFunction*>(func);
192 }
193
194 for (const auto& it : *callgraph)
195 {
197 SVFUtil::cast<Function>(getLLVMValue(it.second->getFunction())),
198 it.second);
199 }
200}
201
203{
206 // Functions need to be retrieved in the order of insertion
207 // candidateDefs is the vector for all used defined functions
208 // candidateDecls is the vector for all used declared functions
209 std::vector<const Function*> candidateDefs, candidateDecls;
210
211 for (Module& mod : modules)
212 {
214 for (Function& func : mod.functions())
215 {
216 if (func.isDeclaration())
217 {
218 candidateDecls.push_back(&func);
219 }
220 else
221 {
222 candidateDefs.push_back(&func);
223 }
224 }
225 }
226
227 for (const Function* func: candidateDefs)
228 {
229 createSVFFunction(func);
230 }
231 for (const Function* func: candidateDecls)
232 {
233 createSVFFunction(func);
234 }
235
236 // Store annotations of functions in extapi.bc
237 for (const auto& pair : ExtFun2Annotations)
238 {
239 const SVFFunction* svffun = getSVFFunction(pair.first);
241 }
242
244 for (const Module& mod : modules)
245 {
247 for (const GlobalVariable& global : mod.globals())
248 {
250 global.getName().str(), getSVFType(global.getType()));
253 }
254
256 for (const GlobalAlias& alias : mod.aliases())
257 {
259 alias.getName().str(), getSVFType(alias.getType()));
262 }
263
265 for (const GlobalIFunc& ifunc : mod.ifuncs())
266 {
268 ifunc.getName().str(), getSVFType(ifunc.getType()));
271 }
272 }
273}
274
276{
278 getSVFType(func->getType()),
279 SVFUtil::cast<SVFFunctionType>(
280 getSVFType(func->getFunctionType())),
281 func->isDeclaration(), LLVMUtil::isIntrinsicFun(func),
282 func->hasAddressTaken(), func->isVarArg(), new SVFLoopAndDomInfo);
284 addFunctionMap(func, svfFunc);
285
286 for (const Argument& arg : func->args())
287 {
289 getSVFType(arg.getType()), svfFunc, arg.getArgNo(),
291 // Setting up arg name
292 if (!arg.hasName())
293 svfarg->setName(std::to_string(arg.getArgNo()));
294
295 svfFunc->addArgument(svfarg);
297 }
298
299 for (const BasicBlock& bb : *func)
300 {
302 new SVFBasicBlock(getSVFType(bb.getType()), svfFunc);
303 svfFunc->addBasicBlock(svfBB);
305 for (const Instruction& inst : bb)
306 {
307 SVFInstruction* svfInst = nullptr;
308 if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(&inst))
309 {
310 svfInst = new SVFCallInst(
311 getSVFType(call->getType()), svfBB,
312 call->getFunctionType()->isVarArg(),
313 inst.isTerminator());
314 }
315 else
316 {
317 svfInst =
318 new SVFInstruction(getSVFType(inst.getType()),
319 svfBB, inst.isTerminator(),
320 SVFUtil::isa<ReturnInst>(inst));
321 }
322
324 }
325 }
326}
327
329{
330 for (Module& mod : modules)
331 {
333 for (const Function& f : mod.functions())
334 {
337
339 {
341 }
342 }
343 }
344}
345
347{
349 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
350 {
351 const BasicBlock* bb = &*bit;
354 {
356 svfbb->addSuccBasicBlock(svf_scc_bb);
357 }
359 {
361 svfbb->addPredBasicBlock(svf_pred_bb);
362 }
363
365 if (svfbb->getSuccessors().empty())
366 {
368 {
370 SVFUtil::isa<ReturnInst>(bb->back())) &&
371 "last inst must be return inst");
372 svfFun->setExitBlock(svfbb);
373 }
374 }
375
376 for (BasicBlock::const_iterator iit = bb->begin(), eiit = bb->end(); iit != eiit; ++iit)
377 {
378 const Instruction* inst = &*iit;
379 if(const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
380 {
382 SVFCallInst* svfcall = SVFUtil::cast<SVFCallInst>(svfinst);
383 auto called_llvmval = call->getCalledOperand()->stripPointerCasts();
384 if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
385 {
387 svfcall->setCalledOperand(callee);
388 }
389 else
390 {
391 svfcall->setCalledOperand(getSVFValue(called_llvmval));
392 }
393 for(u32_t i = 0; i < call->arg_size(); i++)
394 {
395 SVFValue* svfval = getSVFValue(call->getArgOperand(i));
396 svfcall->addArgument(svfval);
397 }
398 }
399 }
400 }
401 // For no return functions, we set the last block as exit BB
402 // This ensures that each function that has definition must have an exit BB
403 if (svfFun->exitBlock == nullptr && svfFun->hasBasicBlock())
404 {
405 SVFBasicBlock* retBB = const_cast<SVFBasicBlock*>(svfFun->back());
407 SVFUtil::isa<ReturnInst>(&func->back().back())) &&
408 "last inst must be return inst");
409 svfFun->setExitBlock(retBB);
410 }
411}
412
413
415{
416 if (fun->isDeclaration())
417 return;
418 //process and stored dt & df
421 df.analyze(dt);
423 PostDominatorTree pdt = PostDominatorTree(const_cast<Function&>(*fun));
424 SVFLoopAndDomInfo* ld = svffun->getLoopAndDomInfo();
425
427 for (DominanceFrontierBase::const_iterator dfIter = df.begin(), eDfIter = df.end(); dfIter != eDfIter; dfIter++)
428 {
429 const BasicBlock* keyBB = dfIter->first;
430 const std::set<BasicBlock* >& domSet = dfIter->second;
432 for (const BasicBlock* bbValue:domSet)
433 {
435 }
436 }
437 std::vector<const SVFBasicBlock*> reachableBBs;
438 LLVMUtil::getFunReachableBBs(fun, reachableBBs);
439 ld->setReachableBBs(reachableBBs);
440
441 for (Function::const_iterator bit = fun->begin(), beit = fun->end(); bit!=beit; ++bit)
442 {
443 const BasicBlock &bb = *bit;
445 if (DomTreeNode* dtNode = dt.getNode(&bb))
446 {
447 SVFLoopAndDomInfo::BBSet& bbSet = ld->getDomTreeMap()[svfBB];
448 for (const auto domBB : *dtNode)
449 {
450 const auto* domSVFBB = getSVFBasicBlock(domBB->getBlock());
451 bbSet.insert(domSVFBB);
452 }
453 }
454
455 if (DomTreeNode* pdtNode = pdt.getNode(&bb))
456 {
457 u32_t level = pdtNode->getLevel();
458 ld->getBBPDomLevel()[svfBB] = level;
459 BasicBlock* idomBB = pdtNode->getIDom()->getBlock();
461 ld->getBB2PIdom()[svfBB] = idom;
462
463 SVFLoopAndDomInfo::BBSet& bbSet = ld->getPostDomTreeMap()[svfBB];
464 for (const auto domBB : *pdtNode)
465 {
466 const auto* domSVFBB = getSVFBasicBlock(domBB->getBlock());
467 bbSet.insert(domSVFBB);
468 }
469 }
470
471 if (const Loop* loop = loopInfo.getLoopFor(&bb))
472 {
473 for (const BasicBlock* loopBlock : loop->getBlocks())
474 {
476 ld->addToBB2LoopMap(svfBB, loopbb);
477 }
478 }
479 }
480}
481
482
487{
489 std::unique_ptr<BreakConstantGEPs> p1 = std::make_unique<BreakConstantGEPs>();
490 for (Module &M : getLLVMModules())
491 {
492 p1->runOnModule(M);
493 }
494
496 std::unique_ptr<UnifyFunctionExitNodes> p2 =
497 std::make_unique<UnifyFunctionExitNodes>();
498 for (Module &M : getLLVMModules())
499 {
500 for (auto F = M.begin(), E = M.end(); F != E; ++F)
501 {
502 Function &fun = *F;
503 if (fun.isDeclaration())
504 continue;
505 p2->runOnFunction(fun);
506 }
507 }
508}
509
510void LLVMModuleSet::preProcessBCs(std::vector<std::string> &moduleNameVec)
511{
513 mset->loadModules(moduleNameVec);
514 mset->loadExtAPIModules();
515 mset->prePassSchedule();
516
517 std::string preProcessSuffix = ".pre.bc";
518 // Get the existing module names, remove old extension, add preProcessSuffix
519 for (u32_t i = 0; i < moduleNameVec.size(); i++)
520 {
521 u32_t lastIndex = moduleNameVec[i].find_last_of(".");
522 std::string rawName = moduleNameVec[i].substr(0, lastIndex);
524 }
525
526 mset->dumpModulesToFile(preProcessSuffix);
527 preProcessed = true;
529}
530
531void LLVMModuleSet::loadModules(const std::vector<std::string> &moduleNameVec)
532{
533
534 // We read SVFIR from LLVM IR
536 {
537 if(moduleNameVec.empty())
538 {
539 SVFUtil::outs() << "no LLVM bc file is found!\n";
540 exit(0);
541 }
542 //assert(!moduleNameVec.empty() && "no LLVM bc file is found!");
543 }
544 // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
545 else
547
548 //
549 // LLVMContext objects separate global LLVM settings (from which e.g. types are
550 // derived); multiple LLVMContext objects can coexist and each context can "own"
551 // multiple modules (modules can only have one context). Mixing contexts can lead
552 // to unintended inequalities, such as the following:
553 //
554 // ------------------------------------------------------------------
555 // LLVMContext ctxa,ctxb;
556 // IntegerType * t1 = IntegerType::get(ctxa,32);
557 // IntegerType * t2 = IntegerType::get(ctxa,32);
558 // assert(t1 == t2);
559 // IntegerType * t3 = IntegerType::get(ctxb,32);
560 // IntegerType * t4 = IntegerType::get(ctxb,32);
561 // assert(t3 == t4);
562 // assert(t1 != t3);
563 // ------------------------------------------------------------------
564 //
565 // When loading bytecode files, SVF will use the same LLVMContext object for all
566 // modules (i.e. the context owns all loaded modules). This applies to ExtAPI as
567 // well, which *must* be loaded using the same LLVMContext object. Hence, when
568 // loading modules from bitcode files, a new LLVMContext is created (using a
569 // `std::unique_ptr<LLVMContext>` type to ensure automatic garbage collection).
570 //
571 // This garbage collection should be avoided when building an SVF module from an LLVM
572 // module instance; see the comment(s) in `buildSVFModule` and `loadExtAPIModules()`
573
574 owned_ctx = std::make_unique<LLVMContext>();
575 for (const std::string& moduleName : moduleNameVec)
576 {
577 if (!LLVMUtil::isIRFile(moduleName))
578 {
579 SVFUtil::errs() << "not an IR file: " << moduleName << std::endl;
580 abort();
581 }
582
584 std::unique_ptr<Module> mod = parseIRFile(moduleName, Err, *owned_ctx);
585 if (mod == nullptr)
586 {
587 SVFUtil::errs() << "load module: " << moduleName << "failed!!\n\n";
588 Err.print("SVFModuleLoader", llvm::errs());
589 abort();
590 }
591 modules.emplace_back(*mod);
592 owned_modules.emplace_back(std::move(mod));
593 }
594}
595
597{
598 // This function loads the ExtAPI bitcode file as an LLVM module. Note that it is important that
599 // the same LLVMContext object is used to load this bitcode file as is used by the other modules
600 // being analysed.
601 // When the modules are loaded from bitcode files (i.e. passing filenames to files containing
602 // LLVM IR to `buildSVFModule({file1.bc, file2.bc, ...})) the context is created while loading
603 // the modules in `loadModules()`, which populates this->modules and this->owned_modules.
604 // If, however, an LLVM Module object is passed to `buildSVFModule` (e.g. from an LLVM pass),
605 // the context should be retrieved from the module itself (note that the garbage collection from
606 // `std::unique_ptr<LLVMContext> LLVMModuleSet::owned_ctx` should be avoided in this case). This
607 // function populates only this->modules.
608 // In both cases, fetching the context from the main LLVM module (through `getContext`) works
609 assert(!empty() && "LLVMModuleSet contains no modules; cannot load ExtAPI module without LLVMContext!");
610
611 // Load external API module (extapi.bc)
612 if (!ExtAPI::getExtAPI()->getExtBcPath().empty())
613 {
616 {
617 SVFUtil::errs() << "not an external IR file: " << extModuleName << std::endl;
618 abort();
619 }
621 std::unique_ptr<Module> mod = parseIRFile(extModuleName, Err, getContext());
622 if (mod == nullptr)
623 {
624 SVFUtil::errs() << "load external module: " << extModuleName << "failed!!\n\n";
625 Err.print("SVFModuleLoader", llvm::errs());
626 abort();
627 }
628 // The module of extapi.bc needs to be inserted before applications modules, like std::vector<std::reference_wrapper<Module>> modules{extapi_module, app_module}.
629 // Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found.
630 modules.insert(modules.begin(), *mod);
631 owned_modules.insert(owned_modules.begin(),std::move(mod));
632 }
633}
634
636{
637 // This function is used to extract constructor and destructor functions
638 // sorted by their priority from @llvm.global_ctors or @llvm.global_dtors.
639 // For example, given following @llvm.global_ctors, the returning sorted
640 // function list should be [ctor3, ctor1, ctor2].
641 // ------------------------------------------------------------------
642 // ; Each struct in the array is {priority, function, associated data}
643 //
644 // @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }]
645 // [{ i32, void ()*, i8* } { i32 1234, void ()* @ctor1.cpp, i8* null },
646 // { i32, void ()*, i8* } { i32 2345, void ()* @ctor2.cpp, i8* null },
647 // { i32, void ()*, i8* } { i32 345, void ()* @ctor3.cpp, i8* null }]
648 // ------------------------------------------------------------------
649 // TODO: According to LLVM language reference, if the third field is
650 // non-null, and points to a global variable or function, the initializer
651 // function will only run if the associated data from the current module is
652 // not discarded. However the associated data is currently ignored.
653
654
655 // This class is used for the priority queue that sorts the functions by
656 // their priority. Each object of this class stands for an item in the
657 // function array.
659 {
660 public:
662 const Function* func;
665 : priority(_priority), func(_func) {};
666 bool operator>(const LLVMGlobalFunction &other) const
667 {
668 if (priority != other.priority)
669 {
670 return priority > other.priority;
671 }
672 else
673 {
674 return func > other.func;
675 }
676 }
677 };
678
679 std::priority_queue<LLVMGlobalFunction, std::vector<LLVMGlobalFunction>,
681 queue;
682 std::vector<const Function* > result;
683
684 // The @llvm.global_ctors/dtors global variable is an array of struct. Each
685 // struct has three fields: {i32 priority, void ()* @ctor/dtor, i8* @data}.
686 // First get the array here.
688 SVFUtil::dyn_cast<ConstantArray>(global->getInitializer()))
689 {
690 // Get each struct in the array.
691 for (unsigned int i = 0; i < globalFuncArray->getNumOperands(); ++i)
692 {
693 if (
695 SVFUtil::dyn_cast<ConstantStruct>(
696 globalFuncArray->getOperand(i)))
697 {
698
699 // Extract priority and function from the struct
700 const ConstantInt* priority = SVFUtil::dyn_cast<ConstantInt>(
701 globalFuncItem->getOperand(0));
702 const Function* func = SVFUtil::dyn_cast<Function>(
703 globalFuncItem->getOperand(1));
704
705 if (priority && func)
706 {
708 ->getZExtValue(),
709 func));
710 }
711 }
712 }
713 }
714
715 // Generate a sorted vector of functions from the priority queue.
716 while (!queue.empty())
717 {
718 result.push_back(queue.top().func);
719 queue.pop();
720 }
721 return result;
722}
723
725{
726 std::vector<const Function*> ctor_funcs;
727 std::vector<const Function*> dtor_funcs;
728 Function* orgMain = 0;
729 Module* mainMod = nullptr;
730
731 for (Module &mod : modules)
732 {
733 // Collect ctor and dtor functions
734 for (const GlobalVariable& global : mod.globals())
735 {
736 if (global.getName().equals(SVF_GLOBAL_CTORS) && global.hasInitializer())
737 {
739 }
740 else if (global.getName().equals(SVF_GLOBAL_DTORS) && global.hasInitializer())
741 {
743 }
744 }
745
746 // Find main function
747 for (auto &func : mod)
748 {
749 auto funName = func.getName();
750
751 assert(!funName.equals(SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
752
753 if (funName.equals("main"))
754 {
755 orgMain = &func;
756 mainMod = &mod;
757 }
758 }
759 }
760
761 // Only create svf.main when the original main function is found, and also
762 // there are global constructor or destructor functions.
763 if (orgMain && getModuleNum() > 0 &&
764 (ctor_funcs.size() > 0 || dtor_funcs.size() > 0))
765 {
766 assert(mainMod && "Module with main function not found.");
767 Module& M = *mainMod;
768 // char **
769 Type* ptr = PointerType::getUnqual(M.getContext());
770 Type* i32 = IntegerType::getInt32Ty(M.getContext());
771 // define void @svf.main(i32, i8**, i8**)
772#if (LLVM_VERSION_MAJOR >= 9)
773 FunctionCallee svfmainFn = M.getOrInsertFunction(
775 Type::getVoidTy(M.getContext()),
776 i32,ptr,ptr
777 );
778 Function* svfmain = SVFUtil::dyn_cast<Function>(svfmainFn.getCallee());
779#else
780 Function* svfmain = SVFUtil::dyn_cast<Function>(M.getOrInsertFunction(
782 Type::getVoidTy(M.getContext()),
784 ));
785#endif
786 svfmain->setCallingConv(llvm::CallingConv::C);
787 BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", svfmain);
789 // emit "call void @ctor()". ctor_funcs is sorted so the functions are
790 // emitted in the order of priority
791 for (auto& ctor : ctor_funcs)
792 {
793 auto target = M.getOrInsertFunction(
794 ctor->getName(),
795 Type::getVoidTy(M.getContext())
796 );
797 Builder.CreateCall(target);
798 }
799 // main() should be called after all ctor functions and before dtor
800 // functions.
801 Function::arg_iterator arg_it = svfmain->arg_begin();
802 Value* args[] = {arg_it, arg_it + 1, arg_it + 2};
803 size_t cnt = orgMain->arg_size();
804 assert(cnt <= 3 && "Too many arguments for main()");
805 Builder.CreateCall(orgMain, llvm::ArrayRef<Value*>(args, args + cnt));
806 // emit "call void @dtor()". dtor_funcs is sorted so the functions are
807 // emitted in the order of priority
808 for (auto& dtor : dtor_funcs)
809 {
810 auto target = M.getOrInsertFunction(dtor->getName(), Type::getVoidTy(M.getContext()));
811 Builder.CreateCall(target);
812 }
813 // return;
814 Builder.CreateRetVoid();
815 }
816}
817
819{
820 GlobalVariable *glob = mod->getGlobalVariable("llvm.global.annotations");
821 if (glob == nullptr || !glob->hasInitializer())
822 return;
823
824 ConstantArray *ca = SVFUtil::dyn_cast<ConstantArray>(glob->getInitializer());
825 if (ca == nullptr)
826 return;
827
828 for (unsigned i = 0; i < ca->getNumOperands(); ++i)
829 {
830 ConstantStruct *structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
831 if (structAn == nullptr || structAn->getNumOperands() == 0)
832 continue;
833
834 // Check if the annotation is for a function
835 Function* fun = nullptr;
836 GlobalVariable *annotateStr = nullptr;
838 if (ConstantExpr *expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0)))
839 {
840 if (expr->getOpcode() == Instruction::BitCast && SVFUtil::isa<Function>(expr->getOperand(0)))
841 fun = SVFUtil::cast<Function>(expr->getOperand(0));
842
843 ConstantExpr *note = SVFUtil::cast<ConstantExpr>(structAn->getOperand(1));
844 if (note->getOpcode() != Instruction::GetElementPtr)
845 continue;
846
847 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(note->getOperand(0));
848 }
850 else
851 {
852 fun = SVFUtil::dyn_cast<Function>(structAn->getOperand(0));
853 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(structAn->getOperand(1));
854 }
855
856 if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer())
857 continue;;
858
859 ConstantDataSequential *data = SVFUtil::dyn_cast<ConstantDataSequential>(annotateStr->getInitializer());
860 if (data && data->isString())
861 {
862 std::string annotation = data->getAsString().str();
863 if (!annotation.empty())
864 ExtFun2Annotations[fun->getName().str()].push_back(annotation);
865 }
866 }
867}
868
869/*
870 There are three types of functions(definitions) in extapi.c:
871 1. (Fun_Overwrite): Functions with "OVERWRITE" annotion:
872 These functions are used to replace the corresponding function definitions in the application.
873 2. (Fun_Annotation): Functions with annotation(s) but without "OVERWRITE" annotation:
874 These functions are used to tell SVF to do special processing, like malloc().
875 3. (Fun_Noraml): Functions without any annotation:
876 These functions are used to replace the corresponding function declarations in the application.
877
878
879 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:
880 1. appFuncDecl --> Fun_Normal: Clone the Fun_Overwrite and replace the appFuncDecl in application.
881 2. appFuncDecl --> Fun_Annotation: Move the annotions on Fun_Annotation to appFuncDecl in application.
882
883 3. appFunDef --> Fun_Overwrite: Clone the Fun_Overwrite and overwrite the appFunDef in application.
884 4. appFunDef --> Fun_Annotation: Replace the appFunDef with appFunDecl and move the annotions to appFunDecl in application
885*/
887{
891 Module* appModule = nullptr;
892 Module* extModule = nullptr;
893
894 for (Module& mod : modules)
895 {
896 // extapi.bc functions
897 if (mod.getName().str() == ExtAPI::getExtAPI()->getExtBcPath())
898 {
900 extModule = &mod;
901 for (const Function& fun : mod.functions())
902 {
903 // there is main declaration in ext bc, it should be mapped to
904 // main definition in app bc.
905 if (fun.getName().str() == "main")
906 {
907 appFunDecls.insert(&fun);
908 appFuncDeclNames.insert(fun.getName().str());
909 }
911 else if (fun.getName().str() == "svf__main")
912 {
913 ExtFuncsVec.push_back(&fun);
914 }
915 else
916 {
917 extFuncs.insert(&fun);
918 extFunDefNames.insert(fun.getName().str());
919 }
920 }
921 }
922 else
923 {
924 appModule = &mod;
926 for (const Function& fun : mod.functions())
927 {
928 if (fun.isDeclaration())
929 {
930 appFunDecls.insert(&fun);
931 appFuncDeclNames.insert(fun.getName().str());
932 }
933 else
934 {
935 appFunDefs.insert(&fun);
936 appFuncDefNames.insert(fun.getName().str());
937 }
938 }
939 }
940 }
941
942 // Find the intersectNames between appFuncDefNames and externalFunDefNames
943 std::set_intersection(
944 appFuncDefNames.begin(), appFuncDefNames.end(), extFunDefNames.begin(), extFunDefNames.end(),
945 std::inserter(intersectNames, intersectNames.end()));
946
948 {
949 assert(!(appFunToReplace == NULL && appModule == NULL) && "appFunToReplace and appModule cannot both be NULL");
950
951 if (appFunToReplace)
952 {
953 appModule = appFunToReplace->getParent();
954 }
955 // Create a new function with the same signature as extFunToClone
956 Function *clonedFunction = Function::Create(extFunToClone->getFunctionType(), Function::ExternalLinkage, extFunToClone->getName(), appModule);
957 // Map the arguments of the new function to the arguments of extFunToClone
958 llvm::ValueToValueMapTy valueMap;
959 Function::arg_iterator destArg = clonedFunction->arg_begin();
960 for (Function::const_arg_iterator srcArg = extFunToClone->arg_begin(); srcArg != extFunToClone->arg_end(); ++srcArg)
961 {
962 destArg->setName(srcArg->getName()); // Copy the name of the original argument
963 valueMap[&*srcArg] = &*destArg++; // Add a mapping from the old arg to the new arg
964 }
965 if (cloneBody)
966 {
967 // Clone the body of extFunToClone into clonedFunction
968 llvm::SmallVector<ReturnInst*, 8> ignoredReturns;
969 CloneFunctionInto(clonedFunction, extFunToClone, valueMap, llvm::CloneFunctionChangeType::LocalChangesOnly, ignoredReturns, "", nullptr);
970 }
971 if (appFunToReplace)
972 {
973 // Replace all uses of appFunToReplace with clonedFunction
974 appFunToReplace->replaceAllUsesWith(clonedFunction);
975 std::string oldFunctionName = appFunToReplace->getName().str();
976 // Delete the old function
977 appFunToReplace->eraseFromParent();
979 }
980 return clonedFunction;
981 };
982
984 for (const Function* appFunDecl : appFunDecls)
985 {
986 std::string appFunDeclName = LLVMUtil::restoreFuncName(appFunDecl->getName().str());
987 for (const Function* extFun : extFuncs)
988 {
989 if (extFun->getName().str().compare(appFunDeclName) == 0)
990 {
991 auto it = ExtFun2Annotations.find(extFun->getName().str());
992 // Without annotations, this function is normal function with useful function body
993 if (it == ExtFun2Annotations.end())
994 {
995 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFun), const_cast<Function*>(appFunDecl), nullptr, true);
998 }
999 else
1000 {
1001 ExtFuncsVec.push_back(appFunDecl);
1002 }
1003 break;
1004 }
1005 }
1006 }
1007
1010 for (string sameFuncDef: intersectNames)
1011 {
1012 Function* appFuncDef = appModule->getFunction(sameFuncDef);
1013 Function* extFuncDef = extModule->getFunction(sameFuncDef);
1014 if (appFuncDef == nullptr || extFuncDef == nullptr)
1015 continue;
1016
1017 FunctionType *appFuncDefType = appFuncDef->getFunctionType();
1018 FunctionType *extFuncDefType = extFuncDef->getFunctionType();
1020 continue;
1021
1022 auto it = ExtFun2Annotations.find(sameFuncDef);
1023 if (it != ExtFun2Annotations.end())
1024 {
1025 std::vector<std::string> annotations = it->second;
1026 if (annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos)
1027 {
1028 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFuncDef), const_cast<Function*>(appFuncDef), nullptr, true);
1031 }
1032 else
1033 {
1034 if (annotations.size() >= 2)
1035 {
1036 for (const auto& annotation : annotations)
1037 {
1038 if(annotation.find("OVERWRITE") != std::string::npos)
1039 {
1040 assert(false && "overwrite and other annotations cannot co-exist");
1041 }
1042 }
1043 }
1044 }
1045 }
1046 }
1047
1049 {
1050 for (inst_iterator I = inst_begin(caller), E = inst_end(caller); I != E; ++I)
1051 {
1052 Instruction *inst = &*I;
1053
1054 if (CallInst *callInst = SVFUtil::dyn_cast<CallInst>(inst))
1055 {
1056 Function *calledFunc = callInst->getCalledFunction();
1057
1058 if (calledFunc && calledFunc->getName() == callee->getName())
1059 {
1060 callInst->setCalledFunction(callee);
1061 }
1062 }
1063 }
1064 };
1065
1066 std::function<void(const Function*, Function*)> cloneAndLinkFunction;
1068 {
1069 if (clonedFuncs.find(extFunToClone) != clonedFuncs.end())
1070 return;
1071
1072 Module* appModule = appClonedFun->getParent();
1073 // Check if the function already exists in the parent module
1074 if (appModule->getFunction(extFunToClone->getName()))
1075 {
1076 // The function already exists, no need to clone, but need to link it with the caller
1077 Function* func = appModule->getFunction(extFunToClone->getName());
1079 return;
1080 }
1081 // Decide whether to clone the function body based on ExtFun2Annotations
1082 bool cloneBody = true;
1083 auto it = ExtFun2Annotations.find(extFunToClone->getName().str());
1084 if (it != ExtFun2Annotations.end())
1085 {
1086 std::vector<std::string> annotations = it->second;
1087 if (!(annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos))
1088 {
1089 cloneBody = false;
1090 }
1091 }
1092
1094
1096 // Add the cloned function to ExtFuncsVec for further processing
1097 ExtFuncsVec.push_back(clonedFunction);
1098
1100
1101 std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(extFunToClone);
1102
1103 for (const auto& calledFunction : calledFunctions)
1104 {
1106 }
1107 };
1108
1109 // Recursive clone called functions
1110 for (const auto& pair : extFuncs2ClonedFuncs)
1111 {
1112 Function* extFun = const_cast<Function*>(pair.first);
1113 Function* clonedExtFun = const_cast<Function*>(pair.second);
1114 std::vector<const Function*> extCalledFuns = LLVMUtil::getCalledFunctions(extFun);
1115
1116 for (const auto& extCalledFun : extCalledFuns)
1117 {
1119 }
1120 }
1121
1122 // Remove unused annotations in ExtFun2Annotations according to the functions in ExtFuncsVec
1124 for (const Function* extFun : ExtFuncsVec)
1125 {
1126 std::string name = LLVMUtil::restoreFuncName(extFun->getName().str());
1127 auto it = ExtFun2Annotations.find(name);
1128 if (it != ExtFun2Annotations.end())
1129 {
1130 std::string newKey = name;
1131 if (name != extFun->getName().str())
1132 {
1133 newKey = extFun->getName().str();
1134 }
1135 newFun2AnnoMap.insert({newKey, it->second});
1136 }
1137 }
1139
1140 // Remove ExtAPI module from modules
1141 auto it = std::find_if(modules.begin(), modules.end(),
1142 [&extModule](const std::reference_wrapper<llvm::Module>& moduleRef)
1143 {
1144 return &moduleRef.get() == extModule;
1145 });
1146
1147 if (it != modules.end())
1148 {
1149 size_t index = std::distance(modules.begin(), it);
1150 modules.erase(it);
1151 owned_modules.erase(owned_modules.begin() + index);
1152 }
1153}
1154
1156{
1159 for (Module &mod : modules)
1160 {
1161 // Collect ctor and dtor functions
1162 for (GlobalVariable& global : mod.globals())
1163 {
1164 if (global.hasPrivateLinkage())
1165 continue;
1166 string name = global.getName().str();
1167 if (name.empty())
1168 continue;
1169 nameToGlobalsMap[std::move(name)].insert(&global);
1170 }
1171 }
1172
1173 for (const auto& pair : nameToGlobalsMap)
1174 {
1175 const Set<GlobalVariable*> &globals = pair.second;
1176
1177 const auto repIt =
1178 std::find_if(globals.begin(), globals.end(),
1179 [](GlobalVariable* g)
1180 {
1181 return g->hasInitializer();
1182 });
1183 GlobalVariable* rep =
1184 repIt != globals.end()
1185 ? *repIt
1186 // When there is no initializer, just pick the first one.
1187 : (assert(!globals.empty() && "Empty global set"),
1188 *globals.begin());
1189
1190 for (const GlobalVariable* cur : globals)
1191 {
1192 GlobalDefToRepMap[cur] = rep;
1193 }
1194 }
1195}
1196
1197// Dump modules to files
1199{
1200 for (Module& mod : modules)
1201 {
1202 std::string moduleName = mod.getName().str();
1203 std::string OutputFilename;
1204 std::size_t pos = moduleName.rfind('.');
1205 if (pos != std::string::npos)
1206 OutputFilename = moduleName.substr(0, pos) + suffix;
1207 else
1208 OutputFilename = moduleName + suffix;
1209
1210 std::error_code EC;
1211 raw_fd_ostream OS(OutputFilename.c_str(), EC, llvm::sys::fs::OF_None);
1212
1213#if (LLVM_VERSION_MAJOR >= 7)
1214 WriteBitcodeToFile(mod, OS);
1215#else
1216 WriteBitcodeToFile(&mod, OS);
1217#endif
1218
1219 OS.flush();
1220 }
1221}
1222
1228
1230{
1232
1233 if(val->hasName())
1234 svfvalue->setName(val->getName().str());
1236 svfvalue->setPtrInUncalledFunction();
1238 svfvalue->setConstDataOrAggData();
1239
1240 if (SVFGlobalValue* glob = SVFUtil::dyn_cast<SVFGlobalValue>(svfvalue))
1241 {
1243 assert(SVFUtil::isa<GlobalValue>(llvmVal) && "not a GlobalValue?");
1244 glob->setDefGlobalForMultipleModule(getSVFGlobalValue(SVFUtil::cast<GlobalValue>(llvmVal)));
1245 }
1246 if (SVFFunction* svffun = SVFUtil::dyn_cast<SVFFunction>(svfvalue))
1247 {
1248 const Function* func = SVFUtil::cast<Function>(val);
1249 svffun->setIsNotRet(LLVMUtil::functionDoesNotRet(func));
1250 svffun->setIsUncalledFunction(LLVMUtil::isUncalledFunction(func));
1251 svffun->setDefFunForMultipleModule(getSVFFunction(func));
1252 }
1253
1254 svfvalue->setSourceLoc(LLVMUtil::getSourceLoc(val));
1255}
1256
1263
1265{
1266 LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(cd);
1267 if(it!=LLVMConst2SVFConst.end())
1268 {
1269 assert(SVFUtil::isa<SVFConstantData>(it->second) && "not a SVFConstantData type!");
1270 return SVFUtil::cast<SVFConstantData>(it->second);
1271 }
1272 else
1273 {
1274 SVFConstantData* svfcd = nullptr;
1275 if(const ConstantInt* cint = SVFUtil::dyn_cast<ConstantInt>(cd))
1276 {
1280 if(cint->getBitWidth() == 1)
1281 svfcd = new SVFConstantInt(getSVFType(cint->getType()), cint->getZExtValue(), cint->getZExtValue());
1282 else if(cint->getBitWidth() <= 64 && cint->getBitWidth() > 1)
1283 svfcd = new SVFConstantInt(getSVFType(cint->getType()), cint->getZExtValue(), cint->getSExtValue());
1284 else
1285 svfcd = new SVFConstantInt(getSVFType(cint->getType()), 0, 0);
1286 }
1287 else if(const ConstantFP* cfp = SVFUtil::dyn_cast<ConstantFP>(cd))
1288 {
1289 double dval = 0;
1290 // TODO: Why only double is considered? What about float?
1291 if (cfp->isNormalFP())
1292 {
1293 const llvm::fltSemantics& semantics = cfp->getValueAPF().getSemantics();
1294 if (&semantics == &llvm::APFloat::IEEEhalf() ||
1295 &semantics == &llvm::APFloat::IEEEsingle() ||
1296 &semantics == &llvm::APFloat::IEEEdouble() ||
1297 &semantics == &llvm::APFloat::IEEEquad() ||
1298 &semantics == &llvm::APFloat::x87DoubleExtended())
1299 {
1300 dval = cfp->getValueAPF().convertToDouble();
1301 }
1302 else
1303 {
1304 assert (false && "Unsupported floating point type");
1305 abort();
1306 }
1307 }
1308 else
1309 {
1310 // other cfp type, like isZero(), isInfinity(), isNegative(), etc.
1311 // do nothing
1312 }
1313 svfcd = new SVFConstantFP(getSVFType(cd->getType()), dval);
1314 }
1315 else if(SVFUtil::isa<ConstantPointerNull>(cd))
1316 svfcd = new SVFConstantNullPtr(getSVFType(cd->getType()));
1317 else if (SVFUtil::isa<UndefValue>(cd))
1318 svfcd = new SVFBlackHoleValue(getSVFType(cd->getType()));
1319 else
1320 svfcd = new SVFConstantData(getSVFType(cd->getType()));
1321
1322
1325 return svfcd;
1326 }
1327}
1328
1330{
1331 LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(oc);
1332 if(it!=LLVMConst2SVFConst.end())
1333 {
1334 return it->second;
1335 }
1336 else
1337 {
1338 SVFConstant* svfoc = new SVFConstant(getSVFType(oc->getType()));
1341 return svfoc;
1342 }
1343}
1344
1346{
1347 LLVMValue2SVFOtherValueMap::const_iterator it = LLVMValue2SVFOtherValue.find(ov);
1348 if(it!=LLVMValue2SVFOtherValue.end())
1349 {
1350 return it->second;
1351 }
1352 else
1353 {
1355 SVFUtil::isa<MetadataAsValue>(ov)
1356 ? new SVFMetadataAsValue(getSVFType(ov->getType()))
1357 : new SVFOtherValue(getSVFType(ov->getType()));
1360 return svfov;
1361 }
1362}
1363
1365{
1366 if (const Function* fun = SVFUtil::dyn_cast<Function>(value))
1367 return getSVFFunction(fun);
1368 else if (const BasicBlock* bb = SVFUtil::dyn_cast<BasicBlock>(value))
1369 return getSVFBasicBlock(bb);
1370 else if(const Instruction* inst = SVFUtil::dyn_cast<Instruction>(value))
1371 return getSVFInstruction(inst);
1372 else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(value))
1373 return getSVFArgument(arg);
1374 else if (const Constant* cons = SVFUtil::dyn_cast<Constant>(value))
1375 {
1376 if (const ConstantData* cd = SVFUtil::dyn_cast<ConstantData>(cons))
1377 return getSVFConstantData(cd);
1378 else if (const GlobalValue* glob = SVFUtil::dyn_cast<GlobalValue>(cons))
1379 return getSVFGlobalValue(glob);
1380 else
1381 return getOtherSVFConstant(cons);
1382 }
1383 else
1384 return getSVFOtherValue(value);
1385}
1386
1388{
1389 for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it)
1390 {
1391 if (it->second == T)
1392 return it->first;
1393 }
1394 assert(false && "can't find the corresponding LLVM Type");
1395 abort();
1396}
1397
1402{
1403 assert(T && "SVFType should not be null");
1404 LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.find(T);
1405 if (it != LLVMType2SVFType.end())
1406 return it->second;
1407
1410 svfType->setTypeInfo(stinfo);
1411 return svfType;
1412}
1413
1414
1417{
1418 ICFGNode* node;
1420 node = getCallICFGNode(inst);
1421 else if(LLVMUtil::isIntrinsicInst(inst))
1422 node = getIntraICFGNode(inst);
1423 else
1424 node = getIntraICFGNode(inst);
1425
1426 assert (node!=nullptr && "no ICFGNode for this instruction?");
1427 return node;
1428}
1429
1431{
1432 ICFGNode* node;
1434 node = getCallBlock(inst);
1435 else if(LLVMUtil::isIntrinsicInst(inst))
1436 node = getIntraBlock(inst);
1437 else
1438 node = getIntraBlock(inst);
1439
1440 return node != nullptr;
1441}
1442
1444{
1445 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1446 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1447 CallICFGNode* node = getCallBlock(inst);
1448 assert (node!=nullptr && "no CallICFGNode for this instruction?");
1449 return node;
1450}
1451
1453{
1454 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1455 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1456 RetICFGNode* node = getRetBlock(inst);
1457 assert (node!=nullptr && "no RetICFGNode for this instruction?");
1458 return node;
1459}
1460
1462{
1463 IntraICFGNode* node = getIntraBlock(inst);
1464 assert (node!=nullptr && "no IntraICFGNode for this instruction?");
1465 return node;
1466}
1467
1469{
1470 Type2TypeInfoMap::iterator tit = Type2TypeInfo.find(T);
1471 if (tit != Type2TypeInfo.end())
1472 {
1473 return tit->second;
1474 }
1475 // No such StInfo for T, create it now.
1476 StInfo* stInfo;
1477 if (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(T))
1478 {
1480 }
1481 else if (const StructType* sty = SVFUtil::dyn_cast<StructType>(T))
1482 {
1483 u32_t nf;
1485 if (nf > symInfo->maxStSize)
1486 {
1488 symInfo->maxStSize = nf;
1489 }
1490 }
1491 else
1492 {
1494 }
1495 Type2TypeInfo.emplace(T, stInfo);
1497 return stInfo;
1498}
1499
1501{
1502 assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() &&
1503 "SVFType has been added before");
1504
1505 // add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 1 (default value)
1506 u32_t byteSize = 1;
1507 if (T->isSized())
1508 {
1509 const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()->
1510 getMainLLVMModule()->getDataLayout();
1511 Type *mut_T = const_cast<Type *>(T);
1512 byteSize = DL.getTypeAllocSize(mut_T);
1513 }
1514
1516 if (SVFUtil::isa<PointerType>(T))
1517 {
1518 svftype = new SVFPointerType(byteSize);
1519 }
1520 else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
1521 {
1522 auto svfIntT = new SVFIntegerType(byteSize);
1523 unsigned signWidth = intT->getBitWidth();
1524 assert(signWidth < INT16_MAX && "Integer width too big");
1525 svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
1526 svftype = svfIntT;
1527 }
1528 else if (const FunctionType* ft = SVFUtil::dyn_cast<FunctionType>(T))
1529 svftype = new SVFFunctionType(getSVFType(ft->getReturnType()));
1530 else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
1531 {
1532 auto svfst = new SVFStructType(byteSize);
1533 if (st->hasName())
1534 svfst->setName(st->getName().str());
1535 svftype = svfst;
1536 }
1537 else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
1538 {
1539 auto svfat = new SVFArrayType(byteSize);
1540 svfat->setNumOfElement(at->getNumElements());
1541 svfat->setTypeOfElement(getSVFType(at->getElementType()));
1542 svftype = svfat;
1543 }
1544 else
1545 {
1546 std::string buffer;
1547 auto ot = new SVFOtherType(T->isSingleValueType(), byteSize);
1548 llvm::raw_string_ostream(buffer) << *T;
1549 ot->setRepr(std::move(buffer));
1550 svftype = ot;
1551 }
1552
1555
1556 return svftype;
1557}
1558
1563{
1564 u64_t totalElemNum = ty->getNumElements();
1565 const Type* elemTy = ty->getElementType();
1566 while (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(elemTy))
1567 {
1568 totalElemNum *= aty->getNumElements();
1569 elemTy = aty->getElementType();
1570 }
1571
1574
1576 if (totalElemNum == 0)
1577 {
1578 stInfo->addFldWithType(0, elemSvfType, 0);
1579 stInfo->setNumOfFieldsAndElems(1, 1);
1580 stInfo->getFlattenFieldTypes().push_back(elemSvfType);
1581 stInfo->getFlattenElementTypes().push_back(elemSvfType);
1582 return stInfo;
1583 }
1584
1588 u32_t nfF = elemStInfo->getNumOfFlattenFields();
1589 u32_t nfE = elemStInfo->getNumOfFlattenElements();
1590 for (u32_t j = 0; j < nfF; j++)
1591 {
1592 const SVFType* fieldTy = elemStInfo->getFlattenFieldTypes()[j];
1593 stInfo->getFlattenFieldTypes().push_back(fieldTy);
1594 }
1595
1598 u32_t outArrayElemNum = ty->getNumElements();
1599 for (u32_t i = 0; i < outArrayElemNum; ++i)
1600 {
1601 auto idx = (i * nfE * totalElemNum) / outArrayElemNum;
1602 stInfo->addFldWithType(0, elemSvfType, idx);
1603 }
1604
1605 for (u32_t i = 0; i < totalElemNum; ++i)
1606 {
1607 for (u32_t j = 0; j < nfE; ++j)
1608 {
1609 const SVFType* et = elemStInfo->getFlattenElementTypes()[j];
1610 stInfo->getFlattenElementTypes().push_back(et);
1611 }
1612 }
1613
1614 assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum &&
1615 "typeForArray size incorrect!!!");
1616 stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum);
1617
1618 return stInfo;
1619}
1620
1627{
1629 StInfo* stInfo = new StInfo(1);
1630
1631 // Number of fields after flattening the struct
1632 numFields = 0;
1633 // The offset when considering array stride info
1634 u32_t strideOffset = 0;
1635 for (const Type* elemTy : structTy->elements())
1636 {
1638 // offset with int_32 (s32_t) is large enough and won't overflow
1639 stInfo->addFldWithType(numFields, elemSvfTy, strideOffset);
1640
1641 if (SVFUtil::isa<StructType, ArrayType>(elemTy))
1642 {
1644 u32_t nfF = subStInfo->getNumOfFlattenFields();
1645 u32_t nfE = subStInfo->getNumOfFlattenElements();
1646 // Copy ST's info, whose element 0 is the size of ST itself.
1647 for (u32_t j = 0; j < nfF; ++j)
1648 {
1649 const SVFType* elemTy = subStInfo->getFlattenFieldTypes()[j];
1650 stInfo->getFlattenFieldTypes().push_back(elemTy);
1651 }
1652 numFields += nfF;
1653 strideOffset += nfE;
1654 for (u32_t tpj = 0; tpj < nfE; ++tpj)
1655 {
1656 const SVFType* ty = subStInfo->getFlattenElementTypes()[tpj];
1657 stInfo->getFlattenElementTypes().push_back(ty);
1658 }
1659
1660 }
1661 else
1662 {
1663 // Simple type
1664 numFields += 1;
1665 strideOffset += 1;
1666 stInfo->getFlattenFieldTypes().push_back(elemSvfTy);
1667 stInfo->getFlattenElementTypes().push_back(elemSvfTy);
1668 }
1669 }
1670
1671 assert(stInfo->getFlattenElementTypes().size() == strideOffset &&
1672 "typeForStruct size incorrect!");
1673 stInfo->setNumOfFieldsAndElems(numFields,strideOffset);
1674
1675 return stInfo;
1676}
1677
1678
1683{
1685 StInfo* stInfo = new StInfo(1);
1687 stInfo->addFldWithType(0, svfType, 0);
1688
1689 stInfo->getFlattenFieldTypes().push_back(svfType);
1690 stInfo->getFlattenElementTypes().push_back(svfType);
1691 stInfo->setNumOfFieldsAndElems(1,1);
1692
1693 return stInfo;
1694}
#define SVF_MAIN_FUNC_NAME
#define SVF_GLOBAL_DTORS
#define SVF_GLOBAL_CTORS
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define TIMEINTERVAL
Definition SVFType.h:512
#define DGENERAL
Definition SVFType.h:490
const char *const name
Definition cJSON.h:264
char * buffer
Definition cJSON.h:163
int index
Definition cJSON.h:170
cJSON * item
Definition cJSON.h:222
const CallGraphNode * getCallGraphNode(const std::string &name)
std::string getExtBcPath()
Definition ExtAPI.cpp:119
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:42
void setExtFuncAnnotations(const SVFFunction *fun, const std::vector< std::string > &funcAnnotations)
Definition ExtAPI.cpp:164
void addOtherValueMap(const Value *ov, SVFOtherValue *svfov)
Definition LLVMModule.h:231
void createSVFFunction(const Function *func)
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition LLVMModule.h:455
LLVMType2SVFTypeMap LLVMType2SVFType
Definition LLVMModule.h:100
std::vector< const Function * > getLLVMGlobalFunctions(const GlobalVariable *global)
SVFOtherValue * getSVFOtherValue(const Value *ov)
void buildSymbolTable() const
void addInstructionMap(const Instruction *inst, SVFInstruction *svfInst)
Definition LLVMModule.h:185
Module * getMainLLVMModule() const
Definition LLVMModule.h:364
LLVMFun2CallGraphNodeMap LLVMFunc2CallGraphNode
Map an LLVM Function to an CallGraph Node.
Definition LLVMModule.h:93
StInfo * collectTypeInfo(const Type *ty)
Collect a type info.
void initSVFBasicBlock(const Function *func)
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:122
SVFConstantData * getSVFConstantData(const ConstantData *cd)
void loadModules(const std::vector< std::string > &moduleNameVec)
ObjTypeInference * typeInference
Definition LLVMModule.h:102
static void releaseLLVMModuleSet()
Definition LLVMModule.h:129
static void preProcessBCs(std::vector< std::string > &moduleNameVec)
static bool preProcessed
Definition LLVMModule.h:77
void addToLLVMVal2SVFVarMap(const Value *val, SVFBaseNode *svfBaseNode)
void addBasicBlockMap(const BasicBlock *bb, SVFBasicBlock *svfBB)
Definition LLVMModule.h:180
DominatorTree & getDomTree(const Function *fun)
LLVMInst2SVFInstMap LLVMInst2SVFInst
Definition LLVMModule.h:95
SVFModule * svfModule
Borrowed from singleton SVFModule::svfModule.
Definition LLVMModule.h:79
RetICFGNode * getRetBlock(const Instruction *cs)
Get/Add a return node.
Definition LLVMModule.h:447
std::unique_ptr< LLVMContext > owned_ctx
Definition LLVMModule.h:81
LLVMConst2SVFConstMap LLVMConst2SVFConst
Definition LLVMModule.h:97
void createSVFDataStructure()
StInfo * collectSimpleTypeInfo(const Type *T)
Collect simple type (non-aggregate) info.
SymbolTableInfo * symInfo
Definition LLVMModule.h:78
void addArgumentMap(const Argument *arg, SVFArgument *svfArg)
Definition LLVMModule.h:206
const Value * getLLVMValue(const SVFValue *value) const
Definition LLVMModule.h:239
void addOtherConstantMap(const Constant *cons, SVFConstant *svfcons)
Definition LLVMModule.h:226
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
const Type * getLLVMType(const SVFType *T) const
Get LLVM Type.
bool hasICFGNode(const Instruction *inst)
CallICFGNode * getCallBlock(const Instruction *cs)
Get/Add a call node.
Definition LLVMModule.h:438
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb) const
Definition LLVMModule.h:267
SVFConstant * getOtherSVFConstant(const Constant *oc)
SVFArgument * getSVFArgument(const Argument *arg) const
Definition LLVMModule.h:281
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
Fun2AnnoMap ExtFun2Annotations
Record annotations of function in extapi.bc.
Definition LLVMModule.h:88
void setValueAttr(const Value *val, SVFValue *value)
void addGlobalValueMap(const GlobalValue *glob, SVFGlobalValue *svfglob)
Definition LLVMModule.h:211
SVFValue2LLVMValueMap SVFValue2LLVMValue
Definition LLVMModule.h:99
CallGraph * callgraph
Definition LLVMModule.h:110
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
void prePassSchedule()
Invoke llvm passes to modify module.
void initDomTree(SVFFunction *func, const Function *f)
StInfo * collectStructInfo(const StructType *structTy, u32_t &numFields)
Collect the struct info and set the number of fields after flattening.
SVFFunction * getSVFFunction(const Function *fun) const
Definition LLVMModule.h:260
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:153
LLVMContext & getContext() const
Definition LLVMModule.h:379
Map< const Function *, DominatorTree > FunToDominatorTree
Definition LLVMModule.h:112
SVFBaseNode2LLVMValueMap SVFBaseNode2LLVMValue
Definition LLVMModule.h:104
StInfo * collectArrayInfo(const ArrayType *T)
Collect the array info.
LLVMModuleSet()
Constructor.
SVFType * addSVFTypeInfo(const Type *t)
Create SVFTypes.
SVFGlobalValue * getSVFGlobalValue(const GlobalValue *g) const
Definition LLVMModule.h:288
void addFunctionMap(const Function *func, SVFFunction *svfFunc)
Definition LLVMModule.h:172
FunctionSetType ExtFuncsVec
Record some "sse_" function declarations used in other ext function definition, e....
Definition LLVMModule.h:86
LLVMValue2SVFOtherValueMap LLVMValue2SVFOtherValue
Definition LLVMModule.h:98
static LLVMModuleSet * llvmModuleSet
Definition LLVMModule.h:76
IntraICFGNode * getIntraICFGNode(const Instruction *inst)
get a intra node
std::vector< std::reference_wrapper< Module > > modules
Definition LLVMModule.h:83
SVFInstruction * getSVFInstruction(const Instruction *inst) const
Definition LLVMModule.h:274
bool empty() const
Definition LLVMModule.h:385
Map< std::string, std::vector< std::string > > Fun2AnnoMap
Definition LLVMModule.h:67
u32_t getModuleNum() const
Definition LLVMModule.h:148
GlobalDefToRepMapTy GlobalDefToRepMap
Global definition to a rep definition map.
Definition LLVMModule.h:90
std::vector< std::unique_ptr< Module > > owned_modules
Definition LLVMModule.h:82
static SVFModule * buildSVFModule(Module &mod)
Type2TypeInfoMap Type2TypeInfo
Definition LLVMModule.h:101
void dumpModulesToFile(const std::string &suffix)
void addConstantDataMap(const ConstantData *cd, SVFConstantData *svfcd)
Definition LLVMModule.h:221
void collectExtFunAnnotations(const Module *mod)
ObjTypeInference * getTypeInference()
SVFValue * getSVFValue(const Value *value)
static const Option< bool > SVFMain
Definition Options.h:183
static const Option< std::string > Graphtxt
Definition Options.h:182
void setCallGraphNode(CallGraphNode *cgn)
call graph node for this function
Definition SVFValue.h:326
const Map< const SVFBasicBlock *, BBSet > & getDomFrontierMap() const
Definition SVFValue.h:75
Set< const SVFBasicBlock * > BBSet
Definition SVFValue.h:55
void addGlobalSet(SVFGlobalValue *glob)
Definition SVFModule.h:110
static bool pagReadFromTXT()
Definition SVFModule.h:98
void addOtherValue(SVFOtherValue *ov)
Definition SVFModule.h:124
static void setPagFromTXT(const std::string &txt)
Definition SVFModule.h:83
void addFunctionSet(SVFFunction *svfFunc)
Definition SVFModule.h:106
void addAliasSet(SVFGlobalValue *alias)
Definition SVFModule.h:115
const FunctionSetType & getFunctionSet() const
Definition SVFModule.h:199
static SVFModule * getSVFModule()
Definition SVFModule.cpp:60
void setModuleIdentifier(const std::string &moduleIdentifier)
Definition SVFModule.h:88
void addConstant(SVFConstant *cd)
Definition SVFModule.h:120
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
const SVFType * maxStruct
The struct type with the most fields.
void addStInfo(StInfo *stInfo)
void addTypeInfo(const SVFType *ty)
u32_t maxStSize
The number of fields in max_struct.
#define NULL
Definition extapi.c:2
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition LLVMUtil.cpp:203
bool isPtrInUncalledFunction(const Value *value)
Return true if this is value in a dead function (function without any caller)
Definition LLVMUtil.cpp:175
bool isUncalledFunction(const Function *fun)
whether this is a function without any possible caller?
Definition LLVMUtil.cpp:158
bool isArgOfUncalledFunction(const Value *val)
Return true if the argument in a function does not have a caller.
Definition LLVMUtil.h:151
bool isIntrinsicFun(const Function *func)
Definition LLVMUtil.cpp:190
std::vector< const Function * > getCalledFunctions(const Function *F)
Get all called funcions in a parent function.
Definition LLVMUtil.cpp:364
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:45
bool functionDoesNotRet(const Function *fun)
Definition LLVMUtil.cpp:122
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition LLVMUtil.h:327
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:429
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:416
void getFunReachableBBs(const Function *svfFun, std::vector< const SVFBasicBlock * > &bbs)
Get reachable basic block from function entry.
Definition LLVMUtil.cpp:74
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:315
std::string restoreFuncName(std::string funcName)
Definition LLVMUtil.cpp:383
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:707
bool isExtCall(const SVFFunction *fun)
Definition SVFUtil.h:278
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:100
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:56
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
for isBitcode
Definition BasicTypes.h:68
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:130
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:128
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::CallBase CallBase
Definition BasicTypes.h:146
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
llvm::succ_const_iterator succ_const_iterator
LLVM Iterators.
Definition BasicTypes.h:276
unsigned long long u64_t
Definition GeneralType.h:48
llvm::IntegerType IntegerType
Definition BasicTypes.h:97
llvm::Argument Argument
Definition BasicTypes.h:145
llvm::ConstantArray ConstantArray
Definition BasicTypes.h:123
llvm::const_pred_iterator const_pred_iterator
Definition BasicTypes.h:254
llvm::Function Function
Definition BasicTypes.h:85
llvm::GlobalValue GlobalValue
Definition BasicTypes.h:88
llvm::FunctionType FunctionType
Definition BasicTypes.h:98
llvm::ConstantData ConstantData
Definition BasicTypes.h:116
llvm::LoopInfo LoopInfo
Definition BasicTypes.h:141
llvm::Instruction Instruction
Definition BasicTypes.h:87
llvm::Constant Constant
Definition BasicTypes.h:124
llvm::DomTreeNode DomTreeNode
Definition BasicTypes.h:134
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
llvm::Module Module
Definition BasicTypes.h:84
llvm::GlobalIFunc GlobalIFunc
Definition BasicTypes.h:129
llvm::PostDominatorTree PostDominatorTree
Definition BasicTypes.h:136
llvm::DominanceFrontier DominanceFrontier
Definition BasicTypes.h:135
llvm::Loop Loop
LLVM Loop.
Definition BasicTypes.h:140
unsigned u32_t
Definition GeneralType.h:46
llvm::ConstantFP ConstantFP
Definition BasicTypes.h:126
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)