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 330 of file ICFGBuilder.cpp.

331{
332 ICFGNode* node;
334 node = addInterBlockICFGNode(inst);
335 else
336 node = addIntraBlockICFGNode(inst);
337 const_cast<SVFBasicBlock*>(
338 llvmModuleSet()->getSVFBasicBlock(inst->getParent()))
339 ->addICFGNode(node);
340 return node;
341}
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)
Definition LLVMModule.h:298
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:720

◆ addFunEntryBlock()

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

Definition at line 353 of file ICFGBuilder.cpp.

354{
355 return llvmModuleSet()->FunToFunEntryNodeMap[fun] =
357}
virtual FunEntryICFGNode * addFunEntryICFGNode(const FunObjVar *svfFunc)
Definition ICFG.h:200
FunToFunEntryNodeMapTy FunToFunEntryNodeMap
map a function to its FunExitICFGNode
Definition LLVMModule.h:109
const FunObjVar * getFunObjVar(const std::string &name)
Definition LLVMUtil.cpp:435

◆ addFunExitBlock()

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

Definition at line 359 of file ICFGBuilder.cpp.

360{
361 return llvmModuleSet()->FunToFunExitNodeMap[fun] =
363}
virtual FunExitICFGNode * addFunExitICFGNode(const FunObjVar *svfFunc)
Definition ICFG.h:207
FunToFunExitNodeMapTy FunToFunExitNodeMap
map a function to its FunEntryICFGNode
Definition LLVMModule.h:110

◆ 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:215
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 277 of file ICFGBuilder.cpp.

278{
279
282
284 if(callee)
285 {
286 const FunObjVar* svfFun =
290 {
292 }
294 else
295 {
300 }
301 }
303 else
304 {
306 }
307}
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:374
ICFGEdge * addRetEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition ICFG.cpp:392
ICFGEdge * addIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Add intraprocedural and interprocedural control-flow edges.
Definition ICFG.cpp:333
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:267
bool isExtCall(const FunObjVar *fun)
Definition SVFUtil.cpp:437
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 239 of file ICFGBuilder.cpp.

240{
241 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
242 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
243 assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
244 const CallBase* cb = SVFUtil::dyn_cast<CallBase>(inst);
246 const FunObjVar* calledFunc = nullptr;
247 auto called_llvmval = cb->getCalledOperand()->stripPointerCasts();
248 if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
249 {
251 }
252 else
253 {
254 assert(SVFUtil::dyn_cast<Function>(called_llvmval) == nullptr && "must be nullptr");
255 }
256
257 SVFBasicBlock* bb = llvmModuleSet()->getSVFBasicBlock(inst->getParent());
258
260 bb, llvmModuleSet()->getSVFType(inst->getType()),
261 calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
263 isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
265
266 assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
269
270 addICFGInterEdges(inst, LLVMUtil::getCallee(SVFUtil::cast<CallBase>(inst))); //creating interprocedural edges
271 return callICFGNode;
272}
void addICFGInterEdges(const Instruction *cs, const Function *callee)
Create edges between ICFG nodes across functions.
virtual CallICFGNode * addCallICFGNode(const SVFBasicBlock *bb, const SVFType *ty, const FunObjVar *calledFunc, bool isVararg, bool isvcall, s32_t vcallIdx, const std::string &funNameOfVcall)
Definition ICFG.h:179
virtual RetICFGNode * addRetICFGNode(CallICFGNode *call)
Definition ICFG.h:192
void addInstructionMap(const Instruction *inst, CallICFGNode *svfInst)
Definition LLVMModule.h:239
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:44
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:97
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 343 of file ICFGBuilder.cpp.

344{
346 assert (node==nullptr && "no IntraICFGNode for this instruction?");
348 llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
350 return sNode;
351}
virtual IntraICFGNode * addIntraICFGNode(const SVFBasicBlock *bb, bool isRet)
Definition ICFG.h:171
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition LLVMModule.h:500

◆ build()

ICFG * ICFGBuilder::build ( )

Create ICFG nodes and edges

Definition at line 45 of file ICFGBuilder.cpp.

46{
47 icfg = new ICFG();
48 DBOUT(DGENERAL, outs() << pasMsg("\t Building ICFG ...\n"));
49 // Add the unique global ICFGNode at the entry of a program (before the main method).
51
52 // Add function entry and exit
53 for (Module &M : llvmModuleSet()->getLLVMModules())
54 {
55 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
56 {
57 const Function *fun = &*F;
58 if (fun->isDeclaration())
59 continue;
61 addFunExitBlock(fun);
62 }
63
64 }
65
66 for (Module &M : llvmModuleSet()->getLLVMModules())
67 {
68 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
69 {
70 const Function *fun = &*F;
71 if (fun->isDeclaration())
72 continue;
73 WorkList worklist;
74 processFunEntry(fun,worklist);
75 processUnreachableFromEntry(fun, worklist);
76 processFunBody(worklist);
77 processFunExit(fun);
78
80 }
81
82 }
84 return icfg;
85}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:512
#define DGENERAL
Definition SVFType.h:518
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:101
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
llvm::Module Module
Definition BasicTypes.h:84

◆ checkICFGNodesVisited()

void ICFGBuilder::checkICFGNodesVisited ( const Function fun)
private

Definition at line 87 of file ICFGBuilder.cpp.

88{
89 for (const auto& bb: *fun)
90 {
91 for (const auto& inst: bb)
92 {
94 continue;
95 assert(visited.count(&inst) && "inst never visited");
96 assert(hasICFGNode(&inst) && "icfgnode not created");
97 }
98 }
99}
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:202

◆ connectGlobalToProgEntry()

void ICFGBuilder::connectGlobalToProgEntry ( )
private

Definition at line 311 of file ICFGBuilder.cpp.

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

◆ 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:337

◆ 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:344

◆ 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:230

◆ 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:131

◆ processFunBody()

void ICFGBuilder::processFunBody ( WorkList worklist)
private

function body

function body

branch condition value

default case is set to -1;

Definition at line 148 of file ICFGBuilder.cpp.

149{
151 while (!worklist.empty())
152 {
153 const Instruction* inst = worklist.pop();
155 if (SVFUtil::isa<ReturnInst>(inst))
156 {
157 FunExitICFGNode* FunExitICFGNode = getFunExitICFGNode(inst->getFunction());
159 }
162 s64_t branchID = 0;
163 for (InstVec::const_iterator nit = nextInsts.begin(), enit =
164 nextInsts.end(); nit != enit; ++nit)
165 {
166 const Instruction* succ = *nit;
168 if (visited.find(succ) != visited.end())
169 {
171 }
172 else
173 {
174 visited.insert(succ);
176 worklist.push(succ);
177 }
178
179
181 {
184 }
185
186 if (const BranchInst* br = SVFUtil::dyn_cast<BranchInst>(inst))
187 {
188 assert(branchID <= 1 && "if/else has more than two branches?");
189 if(br->isConditional())
191 else
193 }
194 else if (const SwitchInst* si = SVFUtil::dyn_cast<SwitchInst>(inst))
195 {
197 const ConstantInt* condVal = const_cast<SwitchInst*>(si)->findCaseDest(const_cast<BasicBlock*>(succ->getParent()));
199 s64_t val = -1;
200 if (condVal && condVal->getBitWidth() <= 64)
203 }
204 else
206 branchID++;
207 }
208 }
209}
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:352
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:82
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition LLVMUtil.cpp:573
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:50
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 103 of file ICFGBuilder.cpp.

104{
106 const Instruction* entryInst = &((fun->getEntryBlock()).front());
107
111 else
112 insts.push_back(entryInst);
113 for (InstVec::const_iterator nit = insts.begin(), enit = insts.end();
114 nit != enit; ++nit)
115 {
116 visited.insert(*nit);
117 ICFGNode* instNode = addBlockICFGNode(*nit); //add interprocedural edge
118 worklist.push(*nit);
120 }
121
122
123
124}

◆ 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 216 of file ICFGBuilder.cpp.

217{
219
220 for (const auto& bb : *f)
221 {
222 for (const auto& inst : bb)
223 {
224 if (SVFUtil::isa<ReturnInst>(&inst))
225 {
227 }
228 }
229 }
230}

◆ processUnreachableFromEntry()

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

bbs unreachable from function entry

Definition at line 129 of file ICFGBuilder.cpp.

130{
133 for (const auto& bb : *fun)
134 {
135 if (pInfo->isUnreachable(llvmModuleSet()->getSVFBasicBlock(&bb)) &&
136 !visited.count(&bb.front()))
137 {
138 visited.insert(&bb.front());
139 (void)addBlockICFGNode(&bb.front());
140 worklist.push(&bb.front());
141 }
142 }
143}
SVFLoopAndDomInfo * getLoopAndDomInfo() const

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: