Static Value-Flow Analysis
Loading...
Searching...
No Matches
ICFGBuilder.cpp
Go to the documentation of this file.
1//===- ICFGBuilder.cpp ----------------------------------------------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <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/*
25 * ICFGBuilder.cpp
26 *
27 * Created on:
28 * Author: yulei
29 */
30
32#include "SVF-LLVM/CppUtil.h"
33#include "SVF-LLVM/LLVMModule.h"
34#include "SVF-LLVM/LLVMUtil.h"
35
36using namespace SVF;
37using namespace SVFUtil;
38
39
44{
45 icfg = new ICFG();
46 DBOUT(DGENERAL, outs() << pasMsg("\t Building ICFG ...\n"));
47 // Add the unique global ICFGNode at the entry of a program (before the main method).
49
50 // Add function entry and exit
52 {
53 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
54 {
55 const Function *fun = &*F;
56 if (fun->isDeclaration())
57 continue;
59 addFunExitBlock(fun);
60 }
61
62 }
63
65 {
66 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
67 {
68 const Function *fun = &*F;
69 if (fun->isDeclaration())
70 continue;
71 WorkList worklist;
72 processFunEntry(fun,worklist);
73 processUnreachableFromEntry(fun, worklist);
74 processFunBody(worklist);
75 processFunExit(fun);
76
78 }
79
80 }
82 return icfg;
83}
84
86{
87 for (const auto& bb: *fun)
88 {
89 for (const auto& inst: bb)
90 {
92 continue;
93 assert(visited.count(&inst) && "inst never visited");
94 assert(hasICFGNode(&inst) && "icfgnode not created");
95 }
96 }
97}
102{
104 const Instruction* entryInst = &((fun->getEntryBlock()).front());
105
109 else
110 insts.push_back(entryInst);
111 for (InstVec::const_iterator nit = insts.begin(), enit = insts.end();
112 nit != enit; ++nit)
113 {
114 visited.insert(*nit);
115 ICFGNode* instNode = addBlockICFGNode(*nit); //add interprocedural edge
116 worklist.push(*nit);
118 }
119
120
121
122}
123
128{
131 for (const auto& bb : *fun)
132 {
133 if (pInfo->isUnreachable(llvmModuleSet()->getSVFBasicBlock(&bb)) &&
134 !visited.count(&bb.front()))
135 {
136 visited.insert(&bb.front());
137 (void)addBlockICFGNode(&bb.front());
138 worklist.push(&bb.front());
139 }
140 }
141}
142
147{
149 while (!worklist.empty())
150 {
151 const Instruction* inst = worklist.pop();
153 if (SVFUtil::isa<ReturnInst>(inst))
154 {
155 FunExitICFGNode* FunExitICFGNode = getFunExitICFGNode(inst->getFunction());
157 }
160 s64_t branchID = 0;
161 for (InstVec::const_iterator nit = nextInsts.begin(), enit =
162 nextInsts.end(); nit != enit; ++nit)
163 {
164 const Instruction* succ = *nit;
166 if (visited.find(succ) != visited.end())
167 {
169 }
170 else
171 {
172 visited.insert(succ);
174 worklist.push(succ);
175 }
176
177
179 {
182 }
183
184 if (const BranchInst* br = SVFUtil::dyn_cast<BranchInst>(inst))
185 {
186 assert(branchID <= 1 && "if/else has more than two branches?");
187 if(br->isConditional())
189 else
191 }
192 else if (const SwitchInst* si = SVFUtil::dyn_cast<SwitchInst>(inst))
193 {
195 const ConstantInt* condVal = const_cast<SwitchInst*>(si)->findCaseDest(const_cast<BasicBlock*>(succ->getParent()));
197 s64_t val = -1;
198 if (condVal && condVal->getBitWidth() <= 64)
199 val = condVal->getSExtValue();
201 }
202 else
204 branchID++;
205 }
206 }
207}
208
215{
217
218 for (const auto& bb : *f)
219 {
220 for (const auto& inst : bb)
221 {
222 if (SVFUtil::isa<ReturnInst>(&inst))
223 {
225 }
226 }
227 }
228}
229
230
231
232
238{
239 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
240 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
241 assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
242 const CallBase* cb = SVFUtil::dyn_cast<CallBase>(inst);
244 SVFFunction* calledFunc = nullptr;
245 auto called_llvmval = cb->getCalledOperand()->stripPointerCasts();
246 if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
247 {
249 }
250 else
251 {
252 calledFunc = SVFUtil::dyn_cast<SVFFunction>(
253 llvmModuleSet()->getSVFValue(called_llvmval));
254 }
255
256 SVFBasicBlock* bb = llvmModuleSet()->getSVFBasicBlock(inst->getParent());
257
259 bb, llvmModuleSet()->getSVFType(inst->getType()),
260 calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
264
265 assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
268
269 addICFGInterEdges(inst, LLVMUtil::getCallee(SVFUtil::cast<CallBase>(inst))); //creating interprocedural edges
270 return callICFGNode;
271}
272
307/*
308* Add the global initialization statements immediately after the function entry of main
309*/
311{
313 {
315 {
316 // main function
321 }
322 else
323 {
324 // not main function
325 }
326 }
327}
328
330{
331 ICFGNode* node;
333 node = addInterBlockICFGNode(inst);
334 else
335 node = addIntraBlockICFGNode(inst);
336 const_cast<SVFBasicBlock*>(
337 llvmModuleSet()->getSVFBasicBlock(inst->getParent()))
338 ->addICFGNode(node);
339 return node;
340}
341
343{
345 assert (node==nullptr && "no IntraICFGNode for this instruction?");
347 llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
349 return sNode;
350}
351
357
359{
360 return llvmModuleSet()->FunToFunExitNodeMap[fun] =
361 icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
362}
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define DGENERAL
Definition SVFType.h:490
bool push(const Data &data)
Definition WorkList.h:165
bool empty() const
Definition WorkList.h:146
ICFGNode * getICFGNode(const Instruction *inst)
Definition ICFGBuilder.h:93
FunEntryICFGNode * addFunEntryBlock(const Function *fun)
void connectGlobalToProgEntry()
FunEntryICFGNode * getFunEntryICFGNode(const Function *fun)
get a function entry node
FunExitICFGNode * getFunExitICFGNode(const Function *fun)
get a function exit node
IntraICFGNode * addIntraBlockICFGNode(const Instruction *inst)
Add and get IntraBlock ICFGNode.
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
std::vector< const Instruction * > InstVec
Definition ICFGBuilder.h:46
LLVMModuleSet * llvmModuleSet()
Definition ICFGBuilder.h:67
void addGlobalICFGNode()
void processUnreachableFromEntry(const Function *fun, WorkList &worklist)
InterICFGNode * addInterBlockICFGNode(const Instruction *inst)
Add/Get an inter block ICFGNode.
bool hasICFGNode(const Instruction *inst)
Definition ICFGBuilder.h:98
void processFunBody(WorkList &worklist)
GlobalICFGNode * getGlobalICFGNode() const
void checkICFGNodesVisited(const Function *fun)
void processFunEntry(const Function *fun, WorkList &worklist)
FunExitICFGNode * addFunExitBlock(const Function *fun)
ICFGNode * addBlockICFGNode(const Instruction *inst)
Add/Get a basic block ICFGNode.
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
void addICFGInterEdges(const Instruction *cs, const Function *callee)
Create edges between ICFG nodes across functions.
void processFunExit(const Function *fun)
bool addICFGEdge(ICFGEdge *edge)
Add ICFG edge, only used by addIntraEdge, addCallEdge, addRetEdge etc.
Definition ICFG.h:277
virtual RetICFGNode * addRetICFGNode(CallICFGNode *call)
Definition ICFG.h:196
virtual FunEntryICFGNode * addFunEntryICFGNode(const SVFFunction *svfFunc)
Definition ICFG.h:204
virtual CallICFGNode * addCallICFGNode(const SVFBasicBlock *bb, const SVFType *ty, const SVFFunction *calledFunc, bool isVararg, bool isvcall, s32_t vcallIdx, const std::string &funNameOfVcall)
Definition ICFG.h:183
virtual IntraICFGNode * addIntraICFGNode(const SVFBasicBlock *bb, bool isRet)
Definition ICFG.h:175
ICFGEdge * addCallEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition ICFG.cpp:366
ICFGEdge * addRetEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition ICFG.cpp:384
ICFGEdge * addConditionalIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode, s64_t branchCondVal)
Definition ICFG.cpp:344
virtual FunExitICFGNode * addFunExitICFGNode(const SVFFunction *svfFunc)
Definition ICFG.h:211
ICFGEdge * addIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Add intraprocedural and interprocedural control-flow edges.
Definition ICFG.cpp:325
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition LLVMModule.h:455
void addInstructionMap(const Instruction *inst, SVFInstruction *svfInst)
Definition LLVMModule.h:185
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb) const
Definition LLVMModule.h:267
SVFFunction * getSVFFunction(const Function *fun) const
Definition LLVMModule.h:260
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:153
FunToFunEntryNodeMapTy FunToFunEntryNodeMap
map a function to its FunExitICFGNode
Definition LLVMModule.h:108
FunToFunExitNodeMapTy FunToFunExitNodeMap
map a function to its FunEntryICFGNode
Definition LLVMModule.h:109
SVFLoopAndDomInfo * getLoopAndDomInfo()
Definition SVFValue.h:373
const SVFFunctionType * getFunctionType() const
Returns the FunctionType.
Definition SVFValue.h:393
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition LLVMUtil.cpp:203
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:45
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition LLVMUtil.cpp:550
const Function * getProgEntryFunction(Module &module)
Get program entry function from module.
Definition LLVMUtil.h:380
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:63
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 & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
std::string getFunNameOfVCallSite(const CallBase *cs)
Definition CppUtil.cpp:635
s32_t getVCallIdx(const CallBase *cs)
Definition CppUtil.cpp:646
bool isVirtualCallSite(const CallBase *cs)
Definition CppUtil.cpp:352
for isBitcode
Definition BasicTypes.h:68
llvm::CallBase CallBase
Definition BasicTypes.h:146
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:86
llvm::SwitchInst SwitchInst
Definition BasicTypes.h:155
llvm::Function Function
Definition BasicTypes.h:85
llvm::Instruction Instruction
Definition BasicTypes.h:87
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
llvm::Module Module
Definition BasicTypes.h:84
llvm::BranchInst BranchInst
Definition BasicTypes.h:154
signed long long s64_t
Definition GeneralType.h:49
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:125