Skip to content

Commit

Permalink
Merge pull request #1227 from jumormt/10.16.2
Browse files Browse the repository at this point in the history
Split callsite and return site in a CFBBNode
  • Loading branch information
yuleisui authored Oct 17, 2023
2 parents 09ecc98 + 8fc5113 commit c3bcbc7
Show file tree
Hide file tree
Showing 5 changed files with 314 additions and 175 deletions.
63 changes: 50 additions & 13 deletions svf/include/AbstractExecution/WTO.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,11 +492,12 @@ class CFBasicBlockGWTO
NodeRefToCycleDepthNumber _nodeToCDN;
CycleDepthNumber _num;
CFBasicBlockNodes _stack;
CFBasicBlockGraph* _graph;

public:
explicit CFBasicBlockGWTO() : _num(0) {}

explicit CFBasicBlockGWTO(const CFBasicBlockNode *entry) : _num(0)
explicit CFBasicBlockGWTO(CFBasicBlockGraph* graph, const CFBasicBlockNode *entry) : _num(0), _graph(graph)
{
build(entry);
}
Expand Down Expand Up @@ -652,12 +653,13 @@ class CFBasicBlockGWTO
const CFBasicBlockGWTOCycleDepth &_headWTOCycleDepth;
const CFBasicBlockNode *_head;
NodeRefToWTOCycleDepthPtr &_nodeToWTOCycleDepth;
CFBasicBlockGraph* _graph;

public:

explicit TailBuilder(NodeRefToWTOCycleDepthPtr &nodeToWTOCycleDepth, NodeRefSet &tails, const CFBasicBlockNode *head,
explicit TailBuilder(CFBasicBlockGraph* graph, NodeRefToWTOCycleDepthPtr &nodeToWTOCycleDepth, NodeRefSet &tails, const CFBasicBlockNode *head,
const CFBasicBlockGWTOCycleDepth &headWTOCycleDepth) : _tails(tails), _headWTOCycleDepth(headWTOCycleDepth), _head(head), _nodeToWTOCycleDepth(
nodeToWTOCycleDepth)
nodeToWTOCycleDepth), _graph(graph)
{
}

Expand All @@ -671,14 +673,23 @@ class CFBasicBlockGWTO

virtual void visit(const CFBasicBlockGWTONode &node) override
{
for (const auto &edge: node.node()->getOutEdges())
{
const CFBasicBlockNode *succ = edge->getDstNode();
if(const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(node.node()->getICFGNodes().front())) {
const CFBasicBlockNode *succ = _graph->getCFBasicBlockNode(callNode->getRetICFGNode()->getId());
const CFBasicBlockGWTOCycleDepth &succNesting = getWTOCycleDepth(succ);
if (succ != _head && succNesting <= _headWTOCycleDepth)
{
_tails.insert(node.node());
}
} else {
for (const auto &edge: node.node()->getOutEdges())
{
const CFBasicBlockNode *succ = edge->getDstNode();
const CFBasicBlockGWTOCycleDepth &succNesting = getWTOCycleDepth(succ);
if (succ != _head && succNesting <= _headWTOCycleDepth)
{
_tails.insert(node.node());
}
}
}
}

Expand Down Expand Up @@ -751,13 +762,21 @@ class CFBasicBlockGWTO
const CFBasicBlockGWTOCycle *component(const CFBasicBlockNode *node)
{
WTOCompRefList partition;
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
{
const CFBasicBlockNode *succ = (*it)->getDstNode();
if (const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(node->getICFGNodes().front())) {
const CFBasicBlockNode *succ = _graph->getCFBasicBlockNode(callNode->getRetICFGNode()->getId());
if (getCDN(succ) == 0)
{
visit(succ, partition);
}
} else {
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
{
const CFBasicBlockNode *succ = (*it)->getDstNode();
if (getCDN(succ) == 0)
{
visit(succ, partition);
}
}
}
const CFBasicBlockGWTOCycle *ptr = newCycle(node, partition);
_headToCycle.emplace(node, ptr);
Expand All @@ -776,9 +795,8 @@ class CFBasicBlockGWTO
head = _num;
setCDN(node, head);
loop = false;
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
{
const CFBasicBlockNode *succ = (*it)->getDstNode();
if (const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(node->getICFGNodes().front())) {
const CFBasicBlockNode *succ = _graph->getCFBasicBlockNode(callNode->getRetICFGNode()->getId());
CycleDepthNumber succ_dfn = getCDN(succ);
if (succ_dfn == CycleDepthNumber(0))
{
Expand All @@ -793,6 +811,25 @@ class CFBasicBlockGWTO
head = min;
loop = true;
}
} else {
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
{
const CFBasicBlockNode *succ = (*it)->getDstNode();
CycleDepthNumber succ_dfn = getCDN(succ);
if (succ_dfn == CycleDepthNumber(0))
{
min = visit(succ, partition);
}
else
{
min = succ_dfn;
}
if (min <= head)
{
head = min;
loop = true;
}
}
}
if (head == getCDN(node))
{
Expand Down Expand Up @@ -831,7 +868,7 @@ class CFBasicBlockGWTO
for (const auto &head: _headToCycle)
{
NodeRefSet tails;
TailBuilder builder(_nodeToDepth, tails, head.first, getWTOCycleDepth(head.first));
TailBuilder builder(_graph, _nodeToDepth, tails, head.first, getWTOCycleDepth(head.first));
for (auto it = head.second->begin(), eit = head.second->end(); it != eit; ++it)
{
(*it)->accept(&builder);
Expand Down
110 changes: 59 additions & 51 deletions svf/include/Graphs/CFBasicBlockG.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ class CFBasicBlockNode : public GenericCFBasicBlockNodeTy
{
}

CFBasicBlockNode(const SVFBasicBlock* bb);

friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockNode &node)
{
o << node.toString();
Expand All @@ -143,10 +141,9 @@ class CFBasicBlockNode : public GenericCFBasicBlockNodeTy
return (*_icfgNodes.begin())->getBB()->getName();
}

inline const SVFBasicBlock *getSVFBasicBlock() const
inline const std::vector<const ICFGNode*>& getICFGNodes() const
{
assert(!_icfgNodes.empty() && "no ICFG nodes in CFBB");
return (*_icfgNodes.begin())->getBB();
return _icfgNodes;
}

inline const SVFFunction *getFunction() const
Expand Down Expand Up @@ -355,7 +352,6 @@ class CFBasicBlockGraph : public GenericCFBasicBlockGTy
private:
u32_t _totalCFBasicBlockNode{0};
u32_t _totalCFBasicBlockEdge{0};
Map<const SVFFunction*, CFBasicBlockNode*> _funToFirstNode;
public:

CFBasicBlockGraph() = default;
Expand All @@ -379,27 +375,6 @@ class CFBasicBlockGraph : public GenericCFBasicBlockGTy
return hasGNode(id);
}

inline CFBasicBlockNode* getFirstCFBasicBlockNode(const SVFFunction* fun) const
{
if (fun && _funToFirstNode.find(fun) != _funToFirstNode.end())
{
return _funToFirstNode.at(fun);
}
else
{
return nullptr;
}
}
inline bool hasFirstCFBasicBlockNode(const SVFFunction* fun) const
{
return fun && _funToFirstNode.find(fun) != _funToFirstNode.end();
}

inline void setFirstCFBasicBlockNode(const Map<const SVFFunction*, CFBasicBlockNode*>& svfNodeMap)
{
_funToFirstNode = svfNodeMap;
}


bool hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst, ICFGEdge *icfgEdge)
{
Expand Down Expand Up @@ -490,24 +465,6 @@ class CFBasicBlockGraph : public GenericCFBasicBlockGTy
}
};

class CFBasicBlockGBuilder
{

private:
CFBasicBlockGraph* _CFBasicBlockG;

public:
CFBasicBlockGBuilder() : _CFBasicBlockG() {}

virtual void build(SVFModule* module);

virtual void build(ICFG* icfg);

inline CFBasicBlockGraph* getCFBasicBlockGraph()
{
return _CFBasicBlockG;
}
};
}


Expand Down Expand Up @@ -537,14 +494,17 @@ struct GenericGraphTraits<SVF::CFBasicBlockGraph *>
typedef SVF::CFBasicBlockNode *NodeRef;
};

} // End namespace SVF

namespace SVF {
template<>
struct DOTGraphTraits<SVF::CFBasicBlockGraph *> : public DOTGraphTraits<SVF::SVFIR *>
{

typedef SVF::CFBasicBlockNode NodeType;

DOTGraphTraits(bool isSimple = false) :
DOTGraphTraits<SVF::SVFIR *>(isSimple)
DOTGraphTraits<SVF::SVFIR *>(isSimple)
{
}

Expand Down Expand Up @@ -574,22 +534,70 @@ struct DOTGraphTraits<SVF::CFBasicBlockGraph *> : public DOTGraphTraits<SVF::SVF
{
std::string str;
std::stringstream rawstr(str);
rawstr << "color=black";
if(node->getICFGNodes().size() == 1) {
const ICFGNode* n = node->getICFGNodes()[0];
if(SVFUtil::isa<IntraICFGNode>(n))
{
rawstr << "color=black";
}
else if(SVFUtil::isa<FunEntryICFGNode>(n))
{
rawstr << "color=yellow";
}
else if(SVFUtil::isa<FunExitICFGNode>(n))
{
rawstr << "color=green";
}
else if(SVFUtil::isa<CallICFGNode>(n))
{
rawstr << "color=red";
}
else if(SVFUtil::isa<RetICFGNode>(n))
{
rawstr << "color=blue";
}
else if(SVFUtil::isa<GlobalICFGNode>(n))
{
rawstr << "color=purple";
}
else
assert(false && "no such kind of node!!");
} else {
rawstr << "color=black";
}
rawstr << "";
return rawstr.str();
}

template<class EdgeIter>
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::CFBasicBlockGraph *)
{
return "style=solid";
CFBasicBlockEdge* edge = *(EI.getCurrent());
assert(edge && "No edge found!!");
if (SVFUtil::isa<CallCFGEdge>(edge->getICFGEdge()))
return "style=solid,color=red";
else if (SVFUtil::isa<RetCFGEdge>(edge->getICFGEdge()))
return "style=solid,color=blue";
else
return "style=solid";
return "";
}

template<class EdgeIter>
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
{
return "";
CFBasicBlockEdge* edge = *(EI.getCurrent());
assert(edge && "No edge found!!");

std::string str;
std::stringstream rawstr(str);
if (const CallCFGEdge* dirCall = SVFUtil::dyn_cast<CallCFGEdge>(edge->getICFGEdge()))
rawstr << dirCall->getCallSite();
else if (const RetCFGEdge* dirRet = SVFUtil::dyn_cast<RetCFGEdge>(edge->getICFGEdge()))
rawstr << dirRet->getCallSite();

return rawstr.str();
}
};

} // End namespace SVF
}
#endif //SVF_CFBASICBLOCKG_H
58 changes: 58 additions & 0 deletions svf/include/Util/CFBasicBlockGBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//===- CFBasicBlockGBuilder.h ----------------------------------------------------------------//
//
// SVF: Static Value-Flow Analysis
//
// Copyright (C) <2013-> <Yulei Sui>
//

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//===----------------------------------------------------------------------===//

/*
* CFBasicBlockGBuilder.h
*
* Created on: 17 Oct. 2023
* Author: Xiao, Jiawei
*/

#include "Graphs/CFBasicBlockG.h"

namespace SVF {

class CFBasicBlockGBuilder
{

private:
CFBasicBlockGraph* _CFBasicBlockG;

public:
CFBasicBlockGBuilder() : _CFBasicBlockG() {}

virtual void build(ICFG* icfg);

inline CFBasicBlockGraph* getCFBasicBlockGraph()
{
return _CFBasicBlockG;
}
private:
void initCFBasicBlockGNodes(ICFG *icfg, Map<const SVFBasicBlock *, std::vector<CFBasicBlockNode *>> &bbToNodes);

void addInterBBEdge(ICFG *icfg, Map<const SVFBasicBlock *, std::vector<CFBasicBlockNode *>> &bbToNodes);

void addIntraBBEdge(ICFG *icfg, Map<const SVFBasicBlock *, std::vector<CFBasicBlockNode *>> &bbToNodes);

void addInterProceduralEdge(ICFG *icfg, Map<const SVFBasicBlock *, std::vector<CFBasicBlockNode *>> &bbToNodes);
};
}
Loading

0 comments on commit c3bcbc7

Please sign in to comment.