Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
SVF::ICFGBuilder Class Reference

#include <ICFGBuilder.h>

Public Types

typedef std::vector< const Instruction * > InstVec
 
typedef Set< const Instruction * > BBSet
 
typedef Map< const Instruction *, CallICFGNode * > CSToCallNodeMapTy
 
typedef Map< const Instruction *, RetICFGNode * > CSToRetNodeMapTy
 
typedef Map< const Instruction *, IntraICFGNode * > InstToBlockNodeMapTy
 
typedef Map< const Function *, FunEntryICFGNode * > FunToFunEntryNodeMapTy
 
typedef Map< const Function *, FunExitICFGNode * > FunToFunExitNodeMapTy
 
typedef FIFOWorkList< const Instruction * > WorkList
 

Public Member Functions

 ICFGBuilder ()=default
 
ICFGbuild ()
 

Private Member Functions

LLVMModuleSetllvmModuleSet ()
 

Private Attributes

ICFGicfg
 
BBSet visited
 
void processFunEntry (const Function *fun, WorkList &worklist)
 
void processUnreachableFromEntry (const Function *fun, WorkList &worklist)
 
void processFunBody (WorkList &worklist)
 
void processFunExit (const Function *fun)
 
void checkICFGNodesVisited (const Function *fun)
 
void connectGlobalToProgEntry ()
 
void addICFGInterEdges (const Instruction *cs, const Function *callee)
 Create edges between ICFG nodes across functions.
 
ICFGNodegetICFGNode (const Instruction *inst)
 
bool hasICFGNode (const Instruction *inst)
 
CallICFGNodegetCallICFGNode (const Instruction *cs)
 get a call node
 
RetICFGNodegetRetICFGNode (const Instruction *cs)
 get a return node
 
IntraICFGNodegetIntraICFGNode (const Instruction *inst)
 get a intra node
 
FunEntryICFGNodegetFunEntryICFGNode (const Function *fun)
 get a function entry node
 
FunExitICFGNodegetFunExitICFGNode (const Function *fun)
 get a function exit node
 
GlobalICFGNodegetGlobalICFGNode () const
 
InterICFGNodeaddInterBlockICFGNode (const Instruction *inst)
 Add/Get an inter block ICFGNode.
 
ICFGNodeaddBlockICFGNode (const Instruction *inst)
 Add/Get a basic block ICFGNode.
 
IntraICFGNodeaddIntraBlockICFGNode (const Instruction *inst)
 Add and get IntraBlock ICFGNode.
 
FunEntryICFGNodeaddFunEntryBlock (const Function *fun)
 
FunExitICFGNodeaddFunExitBlock (const Function *fun)
 
void addGlobalICFGNode ()
 

Detailed Description

Definition at line 41 of file ICFGBuilder.h.

Member Typedef Documentation

◆ BBSet

Definition at line 47 of file ICFGBuilder.h.

◆ CSToCallNodeMapTy

Definition at line 48 of file ICFGBuilder.h.

◆ CSToRetNodeMapTy

Definition at line 49 of file ICFGBuilder.h.

◆ FunToFunEntryNodeMapTy

Definition at line 51 of file ICFGBuilder.h.

◆ FunToFunExitNodeMapTy

Definition at line 52 of file ICFGBuilder.h.

◆ InstToBlockNodeMapTy

Definition at line 50 of file ICFGBuilder.h.

◆ InstVec

Definition at line 46 of file ICFGBuilder.h.

◆ WorkList

Definition at line 59 of file ICFGBuilder.h.

Constructor & Destructor Documentation

◆ ICFGBuilder()

SVF::ICFGBuilder::ICFGBuilder ( )
default

Member Function Documentation

◆ addBlockICFGNode()

ICFGNode * ICFGBuilder::addBlockICFGNode ( const Instruction inst)
inlineprivate

Add/Get a basic block ICFGNode.

Definition at line 329 of file ICFGBuilder.cpp.

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}
IntraICFGNode * addIntraBlockICFGNode(const Instruction *inst)
Add and get IntraBlock ICFGNode.
LLVMModuleSet * llvmModuleSet()
Definition ICFGBuilder.h:67
InterICFGNode * addInterBlockICFGNode(const Instruction *inst)
Add/Get an inter block ICFGNode.
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb) const
Definition LLVMModule.h:267
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:707

◆ addFunEntryBlock()

FunEntryICFGNode * ICFGBuilder::addFunEntryBlock ( const Function fun)
private

Definition at line 352 of file ICFGBuilder.cpp.

353{
354 return llvmModuleSet()->FunToFunEntryNodeMap[fun] =
355 icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
356}
virtual FunEntryICFGNode * addFunEntryICFGNode(const SVFFunction *svfFunc)
Definition ICFG.h:204
FunToFunEntryNodeMapTy FunToFunEntryNodeMap
map a function to its FunExitICFGNode
Definition LLVMModule.h:108

◆ addFunExitBlock()

FunExitICFGNode * ICFGBuilder::addFunExitBlock ( const Function fun)
inlineprivate

Definition at line 358 of file ICFGBuilder.cpp.

359{
360 return llvmModuleSet()->FunToFunExitNodeMap[fun] =
361 icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
362}
virtual FunExitICFGNode * addFunExitICFGNode(const SVFFunction *svfFunc)
Definition ICFG.h:211
FunToFunExitNodeMapTy FunToFunExitNodeMap
map a function to its FunEntryICFGNode
Definition LLVMModule.h:109

◆ addGlobalICFGNode()

void SVF::ICFGBuilder::addGlobalICFGNode ( )
inlineprivate

Definition at line 148 of file ICFGBuilder.h.

149 {
150 icfg->globalBlockNode = new GlobalICFGNode(icfg->totalICFGNode++);
152 }
virtual void addICFGNode(ICFGNode *node)
Add a ICFG node.
Definition ICFG.h:219
NodeID totalICFGNode
Definition ICFG.h:66
GlobalICFGNode * globalBlockNode
unique basic block for all globals
Definition ICFG.h:71

◆ addICFGInterEdges()

void ICFGBuilder::addICFGInterEdges ( const Instruction cs,
const Function callee 
)
private

Create edges between ICFG nodes across functions.

Create edges between ICFG nodes across functions

direct call

if this is an external function (no function body)

otherwise connect interprocedural edges

indirect call (don't know callee)

Definition at line 276 of file ICFGBuilder.cpp.

277{
278
281
283 if(callee)
284 {
289 {
291 }
293 else
294 {
299 }
300 }
302 else
303 {
305 }
306}
FunEntryICFGNode * getFunEntryICFGNode(const Function *fun)
get a function entry node
FunExitICFGNode * getFunExitICFGNode(const Function *fun)
get a function exit node
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
ICFGEdge * addCallEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition ICFG.cpp:366
ICFGEdge * addRetEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition ICFG.cpp:384
ICFGEdge * addIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Add intraprocedural and interprocedural control-flow edges.
Definition ICFG.cpp:325
SVFFunction * getSVFFunction(const Function *fun) const
Definition LLVMModule.h:260
bool isExtCall(const SVFFunction *fun)
Definition SVFUtil.h:278
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

◆ addInterBlockICFGNode()

InterICFGNode * ICFGBuilder::addInterBlockICFGNode ( const Instruction inst)
private

Add/Get an inter block ICFGNode.

(1) Add and get CallBlockICFGNode (2) Handle call instruction by creating interprocedural edges

Definition at line 237 of file ICFGBuilder.cpp.

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,
262 isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
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}
void addICFGInterEdges(const Instruction *cs, const Function *callee)
Create edges between ICFG nodes across functions.
virtual RetICFGNode * addRetICFGNode(CallICFGNode *call)
Definition ICFG.h:196
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
void addInstructionMap(const Instruction *inst, SVFInstruction *svfInst)
Definition LLVMModule.h:185
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:45
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:63
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
llvm::CallBase CallBase
Definition BasicTypes.h:146
llvm::Function Function
Definition BasicTypes.h:85

◆ addIntraBlockICFGNode()

IntraICFGNode * ICFGBuilder::addIntraBlockICFGNode ( const Instruction inst)
private

Add and get IntraBlock ICFGNode.

Definition at line 342 of file ICFGBuilder.cpp.

343{
345 assert (node==nullptr && "no IntraICFGNode for this instruction?");
347 llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
349 return sNode;
350}
virtual IntraICFGNode * addIntraICFGNode(const SVFBasicBlock *bb, bool isRet)
Definition ICFG.h:175
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition LLVMModule.h:455

◆ build()

ICFG * ICFGBuilder::build ( )

Create ICFG nodes and edges

Definition at line 43 of file ICFGBuilder.cpp.

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
51 for (Module &M : llvmModuleSet()->getLLVMModules())
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
64 for (Module &M : llvmModuleSet()->getLLVMModules())
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}
#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
FunEntryICFGNode * addFunEntryBlock(const Function *fun)
void connectGlobalToProgEntry()
FIFOWorkList< const Instruction * > WorkList
Definition ICFGBuilder.h:59
void addGlobalICFGNode()
void processUnreachableFromEntry(const Function *fun, WorkList &worklist)
void processFunBody(WorkList &worklist)
void checkICFGNodesVisited(const Function *fun)
void processFunEntry(const Function *fun, WorkList &worklist)
FunExitICFGNode * addFunExitBlock(const Function *fun)
void processFunExit(const Function *fun)
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
llvm::Module Module
Definition BasicTypes.h:84

◆ checkICFGNodesVisited()

void ICFGBuilder::checkICFGNodesVisited ( const Function fun)
private

Definition at line 85 of file ICFGBuilder.cpp.

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}
bool hasICFGNode(const Instruction *inst)
Definition ICFGBuilder.h:98
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition LLVMUtil.cpp:203

◆ connectGlobalToProgEntry()

void ICFGBuilder::connectGlobalToProgEntry ( )
private

Definition at line 310 of file ICFGBuilder.cpp.

311{
312 for (Module &M : llvmModuleSet()->getLLVMModules())
313 {
315 {
316 // main function
321 }
322 else
323 {
324 // not main function
325 }
326 }
327}
GlobalICFGNode * getGlobalICFGNode() const
bool addICFGEdge(ICFGEdge *edge)
Add ICFG edge, only used by addIntraEdge, addCallEdge, addRetEdge etc.
Definition ICFG.h:277
const Function * getProgEntryFunction(Module &module)
Get program entry function from module.
Definition LLVMUtil.h:380

◆ getCallICFGNode()

CallICFGNode * SVF::ICFGBuilder::getCallICFGNode ( const Instruction cs)
inlineprivate

get a call node

Definition at line 104 of file ICFGBuilder.h.

105 {
106 return llvmModuleSet()->getCallICFGNode(cs);
107 }
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node

◆ getFunEntryICFGNode()

FunEntryICFGNode * SVF::ICFGBuilder::getFunEntryICFGNode ( const Function fun)
inlineprivate

get a function entry node

Definition at line 120 of file ICFGBuilder.h.

121 {
122 return llvmModuleSet()->getFunEntryICFGNode(fun);
123 }
FunEntryICFGNode * getFunEntryICFGNode(const Function *fun)
Add a function entry node.
Definition LLVMModule.h:335

◆ getFunExitICFGNode()

FunExitICFGNode * SVF::ICFGBuilder::getFunExitICFGNode ( const Function fun)
inlineprivate

get a function exit node

Definition at line 125 of file ICFGBuilder.h.

126 {
127 return llvmModuleSet()->getFunExitICFGNode(fun);
128 }
FunExitICFGNode * getFunExitICFGNode(const Function *fun)
Add a function exit node.
Definition LLVMModule.h:342

◆ getGlobalICFGNode()

GlobalICFGNode * SVF::ICFGBuilder::getGlobalICFGNode ( ) const
inlineprivate

Definition at line 130 of file ICFGBuilder.h.

131 {
132 return icfg->getGlobalICFGNode();
133 }
GlobalICFGNode * getGlobalICFGNode() const
Definition ICFG.h:236

◆ getICFGNode()

ICFGNode * SVF::ICFGBuilder::getICFGNode ( const Instruction inst)
inlineprivate

Definition at line 93 of file ICFGBuilder.h.

94 {
95 return llvmModuleSet()->getICFGNode(inst);
96 }
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.

◆ getIntraICFGNode()

IntraICFGNode * SVF::ICFGBuilder::getIntraICFGNode ( const Instruction inst)
inlineprivate

get a intra node

Definition at line 114 of file ICFGBuilder.h.

115 {
116 return llvmModuleSet()->getIntraICFGNode(inst);
117 }
IntraICFGNode * getIntraICFGNode(const Instruction *inst)
get a intra node

◆ getRetICFGNode()

RetICFGNode * SVF::ICFGBuilder::getRetICFGNode ( const Instruction cs)
inlineprivate

get a return node

Definition at line 109 of file ICFGBuilder.h.

110 {
111 return llvmModuleSet()->getRetICFGNode(cs);
112 }
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node

◆ hasICFGNode()

bool SVF::ICFGBuilder::hasICFGNode ( const Instruction inst)
inlineprivate

Definition at line 98 of file ICFGBuilder.h.

99 {
100 return llvmModuleSet()->hasICFGNode(inst);
101 }
bool hasICFGNode(const Instruction *inst)

◆ llvmModuleSet()

LLVMModuleSet * SVF::ICFGBuilder::llvmModuleSet ( )
inlineprivate

Definition at line 67 of file ICFGBuilder.h.

68 {
70 }
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:122

◆ processFunBody()

void ICFGBuilder::processFunBody ( WorkList worklist)
private

function body

function body

branch condition value

default case is set to -1;

Definition at line 146 of file ICFGBuilder.cpp.

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}
ICFGNode * getICFGNode(const Instruction *inst)
Definition ICFGBuilder.h:93
std::vector< const Instruction * > InstVec
Definition ICFGBuilder.h:46
ICFGNode * addBlockICFGNode(const Instruction *inst)
Add/Get a basic block ICFGNode.
ICFGEdge * addConditionalIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode, s64_t branchCondVal)
Definition ICFG.cpp:344
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition LLVMUtil.cpp:550
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:86
llvm::SwitchInst SwitchInst
Definition BasicTypes.h:155
llvm::Instruction Instruction
Definition BasicTypes.h:87
llvm::BranchInst BranchInst
Definition BasicTypes.h:154
signed long long s64_t
Definition GeneralType.h:49
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:125

◆ processFunEntry()

void ICFGBuilder::processFunEntry ( const Function fun,
WorkList worklist 
)
private

Create edges between ICFG nodes within a function

function entry

Definition at line 101 of file ICFGBuilder.cpp.

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}

◆ processFunExit()

void ICFGBuilder::processFunExit ( const Function f)
private

function exit e.g., exit(0). In LLVM, it usually manifests as "unreachable" instruction If a function has multiple exit(0), we will only have one "unreachle" instruction after the UnifyFunctionExitNodes pass.

Definition at line 214 of file ICFGBuilder.cpp.

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}

◆ processUnreachableFromEntry()

void ICFGBuilder::processUnreachableFromEntry ( const Function fun,
WorkList worklist 
)
private

bbs unreachable from function entry

Definition at line 127 of file ICFGBuilder.cpp.

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}
SVFLoopAndDomInfo * getLoopAndDomInfo()
Definition SVFValue.h:373

Member Data Documentation

◆ icfg

ICFG* SVF::ICFGBuilder::icfg
private

Definition at line 56 of file ICFGBuilder.h.

◆ visited

BBSet SVF::ICFGBuilder::visited
private

Definition at line 155 of file ICFGBuilder.h.


The documentation for this class was generated from the following files: