Static Value-Flow Analysis
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/PTACallGraph.h"
31 
32 using namespace SVF;
33 using 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  {
51  dfsNodesBetweenPdomNodes(nxt, tgt, path, tgtNodes, ld);
52  }
53  }
54  path.pop_back();
55 }
56 
64 void
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();
71  dfsNodesBetweenPdomNodes(LCA, succ, path, tgtNodes, ld);
72 }
73 
78 {
79  if (_controlDG->getTotalNodeNum() > 0)
80  return;
81  PAG *pag = PAG::getPAG();
82  buildControlDependence(pag->getModule());
83  buildICFGNodeControlMap();
84 }
85 
86 
88 {
89  ICFG *icfg = PAG::getPAG()->getICFG();
90  assert(!BB->getICFGNodeList().empty() && "empty bb?");
91  const ICFGNode *pred = BB->back();
92  if (const CallICFGNode* callNode = dyn_cast<CallICFGNode>(pred))
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  }
99  const ICFGEdge *edge = icfg->getICFGEdge(pred, Succ->front(), ICFGEdge::ICFGEdgeK::IntraCF);
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 {
126  PTACallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
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
133  extractBBS(svfFun, BBS);
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
151  extractNodesBetweenPdomNodes(succ, SVFLCA, tgtNodes);
152  }
153 
154  s64_t pos = getBBSuccessorBranchID(pred, succ);
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 =
213  dyn_cast<IntraICFGNode>(controlNode))
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();
221  _controlDG->addCDGEdgeFromSrcDst(controlNode, controllee,
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();
231  _controlDG->addCDGEdgeFromSrcDst(
232  controlNode, controllee,
233  pag->getGNode(pag->getNullPtr()), pos);
234  }
235 
236  }
237  }
238  }
239  }
240 }
return NULL
Definition: cJSON.cpp:1173
cJSON * item
Definition: cJSON.h:222
void extractNodesBetweenPdomNodes(const SVFBasicBlock *succ, const SVFBasicBlock *LCA, std::vector< const SVFBasicBlock * > &tgtNodes)
extract nodes between two nodes in pdom tree
Definition: CDGBuilder.cpp:65
void dfsNodesBetweenPdomNodes(const SVFBasicBlock *cur, const SVFBasicBlock *tgt, std::vector< const SVFBasicBlock * > &path, std::vector< const SVFBasicBlock * > &tgtNodes, SVFLoopAndDomInfo *ld)
Definition: CDGBuilder.cpp:35
void buildControlDependence(const SVFModule *svfgModule)
build control dependence for each function
Definition: CDGBuilder.cpp:124
void buildICFGNodeControlMap()
build map at icfg node level
Definition: CDGBuilder.cpp:188
static void extractBBS(const SVFFunction *func, Map< const SVFBasicBlock *, std::vector< const SVFBasicBlock * >> &res)
extract basic block edges to be processed
Definition: CDGBuilder.cpp:171
void build()
start here
Definition: CDGBuilder.cpp:77
s64_t getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasicBlock *Succ)
Definition: CDGBuilder.cpp:87
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
Definition: ICFG.h:48
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
const std::vector< const ICFGNode * > & getICFGNodeList() const
Definition: SVFValue.h:569
const ICFGNode * front() const
Definition: SVFValue.h:594
const ICFGNode * back() const
Definition: SVFValue.h:600
const SVFFunction * getFunction() const
Definition: SVFValue.h:589
bool postDominate(const SVFBasicBlock *bbKey, const SVFBasicBlock *bbValue) const
Definition: SVFValue.h:510
PTACallGraph * getCallGraph()
Definition: SVFIR.h:192
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
ICFG * getICFG() const
Definition: SVFIR.h:171
SVFModule * getModule()
Definition: SVFIR.h:161
const Map< const SVFBasicBlock *, BBSet > & getPostDomTreeMap() const
Definition: SVFValue.h:108
const SVFFunction * getFunction(const std::string &name)
Get the corresponding Function based on its name.
Definition: LLVMUtil.cpp:412
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278
for isBitcode
Definition: BasicTypes.h:68
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
signed s32_t
Definition: GeneralType.h:47
signed long long s64_t
Definition: GeneralType.h:49