Static Value-Flow Analysis
Loading...
Searching...
No Matches
CDGBuilder.cpp
Go to the documentation of this file.
1//===----- CDGBuilder.cpp -- Control Dependence Graph Builder -------------//
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 * CDGBuilder.cpp
25 *
26 * Created on: Sep 27, 2023
27 * Author: Xiao Cheng
28 */
29#include "Util/CDGBuilder.h"
30#include "Graphs/CallGraph.h"
31
32using namespace SVF;
33using namespace SVFUtil;
34
36 const SVFBasicBlock *tgt,
37 std::vector<const SVFBasicBlock *> &path,
38 std::vector<const SVFBasicBlock *> &tgtNodes,
40{
41 path.push_back(cur);
42 if (cur == tgt)
43 {
44 tgtNodes.insert(tgtNodes.end(), path.begin() + 1, path.end());
45 }
46 else
47 {
48 auto it = ld->getPostDomTreeMap().find(cur);
49 for (const auto &nxt: it->second)
50 {
52 }
53 }
54 path.pop_back();
55}
56
64void
66 std::vector<const SVFBasicBlock *> &tgtNodes)
67{
68 if (succ == LCA) return;
69 std::vector<const SVFBasicBlock *> path;
70 SVFLoopAndDomInfo *ld = const_cast<SVFFunction *>(LCA->getFunction())->getLoopAndDomInfo();
72}
73
78{
79 if (_controlDG->getTotalNodeNum() > 0)
80 return;
81 PAG *pag = PAG::getPAG();
84}
85
86
88{
89 ICFG *icfg = PAG::getPAG()->getICFG();
90 assert(!BB->getICFGNodeList().empty() && "empty bb?");
91 const ICFGNode *pred = BB->back();
93 {
94 // not a branch statement:
95 // invoke void %3(ptr noundef nonnull align 8 dereferenceable(8) %1, ptr noundef %2)
96 // to label %invoke.cont1 unwind label %lpad
97 pred = callNode->getRetICFGNode();
98 }
100 if (const IntraCFGEdge *intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
101 {
102 if(intraEdge->getCondition())
103 return intraEdge->getSuccessorCondValue();
104 else
105 return 0;
106 }
107 else
108 {
109 assert(false && "not intra edge?");
110 abort();
111 }
112}
113
125{
127 for (const auto& item: *svfirCallGraph)
128 {
129 const SVFFunction *svfFun = (item.second)->getFunction();
130 if (SVFUtil::isExtCall(svfFun)) continue;
131 // extract basic block edges to be processed
134
135 for (const auto &item: BBS)
136 {
137 const SVFBasicBlock *pred = item.first;
138 // for each bb pair
139 for (const SVFBasicBlock *succ: item.second)
140 {
141 const SVFBasicBlock *SVFLCA = const_cast<SVFFunction *>(svfFun)->
142 getLoopAndDomInfo()->findNearestCommonPDominator(pred, succ);
143 std::vector<const SVFBasicBlock *> tgtNodes;
144 // no common ancestor, may be exit()
145 if (SVFLCA == NULL)
146 tgtNodes.push_back(succ);
147 else
148 {
149 if (SVFLCA == pred) tgtNodes.push_back(SVFLCA);
150 // from succ to LCA
152 }
153
155 for (const SVFBasicBlock *bb: tgtNodes)
156 {
157 updateMap(pred, bb, pos);
158 }
159 }
160 }
161 }
162}
163
164
172 Map<const SVF::SVFBasicBlock *, std::vector<const SVFBasicBlock *>> &res)
173{
174 for (const auto &bb: *func)
175 {
176 for (const auto &succ: bb->getSuccessors())
177 {
178 if (func->postDominate(succ, bb))
179 continue;
180 res[bb].push_back(succ);
181 }
182 }
183}
184
189{
190 for (const auto &it: _svfcontrolMap)
191 {
192 for (const auto &it2: it.second)
193 {
194 const SVFBasicBlock *controllingBB = it2.first;
195 const ICFGNode *controlNode = it.first->getICFGNodeList().back();
196 if (const CallICFGNode* callNode =
197 SVFUtil::dyn_cast<CallICFGNode>(controlNode))
198 {
199 // not a branch statement:
200 // invoke void %3(ptr noundef nonnull align 8 dereferenceable(8) %1, ptr noundef %2)
201 // to label %invoke.cont1 unwind label %lpad
202 controlNode = callNode->getRetICFGNode();
203 }
204 if (!controlNode) continue;
205 // controlNode control at pos
206 for (const auto &controllee: controllingBB->getICFGNodeList())
207 {
208 _nodeControlMap[controlNode][controllee].insert(it2.second.begin(), it2.second.end());
209 _nodeDependentOnMap[controllee][controlNode].insert(it2.second.begin(), it2.second.end());
210 for (s32_t pos: it2.second)
211 {
212 if (const IntraICFGNode* intraNode =
214 {
215 assert(intraNode->getSVFStmts().size() == 1 &&
216 "not a branch stmt?");
217 const SVFVar* condition =
218 SVFUtil::cast<BranchStmt>(
219 intraNode->getSVFStmts().front())
220 ->getCondition();
222 condition,
223 pos);
224 }
225 else
226 {
227 // not a branch statement:
228 // invoke void %3(ptr noundef nonnull align 8 dereferenceable(8) %1, ptr noundef %2)
229 // to label %invoke.cont1 unwind label %lpad
230 SVFIR* pag = PAG::getPAG();
233 pag->getGNode(pag->getNullPtr()), pos);
234 }
235
236 }
237 }
238 }
239 }
240}
cJSON * item
Definition cJSON.h:222
Map< const ICFGNode *, Map< const ICFGNode *, Set< s32_t > > > _nodeControlMap
map an ICFG node to its controlling ICFG nodes (position, set of Nodes)
Definition CDGBuilder.h:101
void updateMap(const SVFBasicBlock *pred, const SVFBasicBlock *bb, s32_t pos)
update map
Definition CDGBuilder.h:90
void extractNodesBetweenPdomNodes(const SVFBasicBlock *succ, const SVFBasicBlock *LCA, std::vector< const SVFBasicBlock * > &tgtNodes)
extract nodes between two nodes in pdom tree
static void extractBBS(const SVFFunction *func, Map< const SVFBasicBlock *, std::vector< const SVFBasicBlock * > > &res)
extract basic block edges to be processed
void dfsNodesBetweenPdomNodes(const SVFBasicBlock *cur, const SVFBasicBlock *tgt, std::vector< const SVFBasicBlock * > &path, std::vector< const SVFBasicBlock * > &tgtNodes, SVFLoopAndDomInfo *ld)
void buildControlDependence(const SVFModule *svfgModule)
build control dependence for each function
Map< const SVFBasicBlock *, Map< const SVFBasicBlock *, Set< s32_t > > > _svfcontrolMap
map a basicblock to its controlling BBs (position, set of BBs)
Definition CDGBuilder.h:99
void buildICFGNodeControlMap()
build map at icfg node level
Map< const ICFGNode *, Map< const ICFGNode *, Set< s32_t > > > _nodeDependentOnMap
map an ICFG node to its dependent on ICFG nodes (position, set of Nodes)
Definition CDGBuilder.h:102
void build()
start here
s64_t getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasicBlock *Succ)
void addCDGEdgeFromSrcDst(const ICFGNode *src, const ICFGNode *dst, const SVFVar *pNode, s32_t branchID)
Add CDG edges from nodeid pair.
Definition CDG.cpp:35
u32_t getTotalNodeNum() const
Get total number of node/edge.
NodeType * getGNode(NodeID id) const
Get a node.
ICFGEdge * getICFGEdge(const ICFGNode *src, const ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Get a SVFG edge according to src and dst.
Definition ICFG.cpp:303
NodeID getNullPtr() const
Definition IRGraph.h:173
bool postDominate(const SVFBasicBlock *bbKey, const SVFBasicBlock *bbValue) const
Definition SVFValue.h:521
CallGraph * getCallGraph()
Definition SVFIR.h:193
ICFG * getICFG() const
Definition SVFIR.h:172
SVFModule * getModule()
Definition SVFIR.h:162
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:116
#define NULL
Definition extapi.c:2
bool isExtCall(const SVFFunction *fun)
Definition SVFUtil.h:278
for isBitcode
Definition BasicTypes.h:68
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
signed s32_t
Definition GeneralType.h:47
signed long long s64_t
Definition GeneralType.h:49