Skip to content

Commit

Permalink
Merge pull request #38 from MingshanJia/stage-IFDS
Browse files Browse the repository at this point in the history
Mingshan's IFDS
  • Loading branch information
yuleisui authored Jul 25, 2019
2 parents 061e532 + 1a6ee60 commit 0d3baec
Show file tree
Hide file tree
Showing 8 changed files with 766 additions and 69 deletions.
2 changes: 1 addition & 1 deletion include/Util/ICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ class ICFG : public GenericICFGTy {

public:
/// Add a function entry node
inline FunEntryBlockNode* getFunEntryICFGNode(const Function* fun) {
inline FunEntryBlockNode* getFunEntryICFGNode(const Function* fun) {
FunToFunEntryNodeMapTy::const_iterator it = FunToFunEntryNodeMap.find(fun);
if (it == FunToFunEntryNodeMap.end()) {
FunEntryBlockNode* sNode = new FunEntryBlockNode(totalICFGNode++,fun);
Expand Down
52 changes: 38 additions & 14 deletions include/Util/ICFGStat.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include "Util/PTAStat.h"
#include "Util/ICFG.h"
#include <iomanip>

class ICFGStat : public PTAStat {

Expand Down Expand Up @@ -68,6 +69,33 @@ class ICFGStat : public PTAStat {

void performStat() {

countStat();

PTNumStatMap["ICFGNode"] = numOfNodes;
PTNumStatMap["IntraBlockNode"] = numOfIntraNodes;
PTNumStatMap["CallBlockNode"] = numOfCallNodes;
PTNumStatMap["RetBlockNode"] = numOfRetNodes;
PTNumStatMap["FunEntryBlockNode"] = numOfEntryNodes;
PTNumStatMap["FunExitBlockNode"] = numOfExitNodes;

PTNumStatMap["ICFGEdge"] = numOfEdges;
PTNumStatMap["CallCFGEdge"] = numOfCallEdges;
PTNumStatMap["RetCFGEdge"] = numOfRetEdges;
PTNumStatMap["IntraCFGEdge"] = numOfIntraEdges;

printStat("ICFG Stat");
}

void performStatforIFDS() {

countStat();
PTNumStatMap["ICFGNode(N)"] = numOfNodes;
PTNumStatMap["CallBlockNode(Call)"] = numOfCallNodes;
PTNumStatMap["ICFGEdge(E)"] = numOfEdges;
printStat("IFDS Stat");
}

void countStat(){
ICFG::ICFGNodeIDToNodeMapTy::iterator it = icfg->begin();
ICFG::ICFGNodeIDToNodeMapTy::iterator eit = icfg->end();
for (; it != eit; ++it) {
Expand Down Expand Up @@ -102,23 +130,19 @@ class ICFGStat : public PTAStat {
numOfIntraEdges++;
}
}

PTNumStatMap["ICFGNode"] = numOfNodes;
PTNumStatMap["IntraBlockNode"] = numOfIntraNodes;
PTNumStatMap["CallBlockNode"] = numOfCallNodes;
PTNumStatMap["RetBlockNode"] = numOfRetNodes;
PTNumStatMap["FunEntryBlockNode"] = numOfEntryNodes;
PTNumStatMap["FunExitBlockNode"] = numOfExitNodes;

PTNumStatMap["ICFGEdge"] = numOfEdges;
PTNumStatMap["CallCFGEdge"] = numOfCallEdges;
PTNumStatMap["RetCFGEdge"] = numOfRetEdges;
PTNumStatMap["IntraCFGEdge"] = numOfIntraEdges;

printStat("ICFG Stat");
}

void printStat(string statname) {

std::cout << "\n************ " << statname << " ***************\n";
std::cout.flags(std::ios::left);
unsigned field_width = 20;
for(NUMStatMap::iterator it = PTNumStatMap.begin(), eit = PTNumStatMap.end(); it!=eit; ++it) {
// format out put with width 20 space
std::cout << std::setw(field_width) << it->first << it->second << "\n";
}
PTNumStatMap.clear();
}
};


Expand Down
164 changes: 150 additions & 14 deletions include/WPA/IFDS.h
Original file line number Diff line number Diff line change
@@ -1,32 +1,168 @@
/*
* SICFG.h
* IFDS.h
*
*/

#ifndef INCLUDE_UTIL_SICFG_H_
#define INCLUDE_UTIL_SICFG_H_
#ifndef INCLUDE_WPA_IFDS_H_
#define INCLUDE_WPA_IFDS_H_


#include "Util/ICFG.h"
#include "WPA/Andersen.h"
#include <iostream>

class IFDS {

private:
ICFG* icfg;
ICFG *icfg;
PointerAnalysis *pta;

public:
inline VFG* getVFG() const{
return icfg->getVFG();
}
class PathNode;
class PathEdge;

inline ICFG* getICFG() const{
return icfg;
}
typedef std::set<const PAGNode *> Datafact; //set of uninitialized variables at ICFGNode
typedef std::set<Datafact> Facts; //different datafacts from different path
typedef std::set<const ICFGNode *> ICFGNodeSet;
typedef std::list<PathEdge *> PathEdgeSet; //to do : list -> vector (faster)
typedef std::map<const ICFGNode *, Facts> ICFGNodeToDataFactsMap;

IFDS(ICFG* i): icfg(i){
}
protected:
PathEdgeSet WorkList; //worklist used during the tabulation algorithm
PathEdgeSet PathEdgeList; //used to restore all PathEdges (result)
PathEdgeSet SummaryEdgeList; //used to restore all SummaryEdges
ICFGNodeSet ICFGDstNodeSet;
ICFGNodeSet SummaryICFGDstNodeSet;
ICFGNodeToDataFactsMap ICFGNodeToFacts;
ICFGNodeToDataFactsMap SummaryICFGNodeToFacts;
ICFGNode *mainEntryNode;
Facts MainExitFacts;
int32_t estimatedDatafacts;

};
public:
inline VFG *getVFG() const {
return icfg->getVFG();
}

inline ICFG *getICFG() const {
return icfg;
}

inline PAG *getPAG() const {
return icfg->getPAG();
}

//constructor
IFDS(ICFG *i);

//procedures in Tabulation Algorithm
void initialize();

void forwardTabulate();

//add new PathEdge components into PathEdgeList and WorkList
void propagate(PathNode *srcPN, ICFGNode *succ, Datafact& d);
void PEPropagate(PathNode *srcPN, ICFGNode *succ, Datafact& d);
void SEPropagate(const ICFGNode *caller, Datafact& d4, ICFGNode *ret, Datafact& d5);

bool isNotInSummaryEdgeList(const ICFGNode *n1, Datafact& d1, ICFGNode *n2, Datafact& d2);

//transfer function of given ICFGNode
Datafact& transferFun(const ICFGNode *icfgNode, Datafact& fact);

Datafact& getCalleeDatafact(const ICFGNode *icfgNode, Datafact& fact);
Datafact& getCallToRetDatafact(Datafact& fact);
void delDatafact(Datafact& d, s32_t kind);

//whether the variable is initialized
bool isInitialized(const PAGNode *pagNode, Datafact& datafact);

//print ICFGNodes and theirs datafacts
void getIFDSStat();
void printRes();
void printPathEdgeList();
void printSummaryEdgeList();
void validateTests(const char *fun);

void printFacts(Facts facts, bool ObjNodeOnly = false);
Datafact concernedDatafact();

//Get points-to set of given PAGNode
inline PointsTo &getPts(NodeID id) {
return pta->getPts(id);
}

// in order to denote : <node, d> , d here is datafact before the execution of node
class PathNode {
const ICFGNode *icfgNode;
Datafact datafact;
PathNode *caller; // for sp node

//Constructor
public:
PathNode(){
}

PathNode(const ICFGNode *node, const Datafact& fact) : caller (NULL){
icfgNode = node;
datafact = fact;
}

void setCaller(PathNode *caller){
this->caller = caller;
}

PathNode* getCaller(){
return this->caller;
}

void setICFGNode(ICFGNode *node) {
icfgNode = node;
}

void setDataFact(Datafact &fact) {
datafact = fact;
}

const ICFGNode *getICFGNode() const {
return icfgNode;
}

Datafact &getDataFact() {
return datafact;
}

};

// in order to denote : <node1, d1> --> <node2, d2>
class PathEdge {
PathNode *srcNode;
PathNode *dstNode;

public:
PathEdge();

PathEdge(PathNode *src, PathNode *dst) {
srcNode = src;
dstNode = dst;
}

void setStartPathNode(PathNode *node) {
srcNode = node;
}

void setEndPathNode(PathNode *node) {
dstNode = node;
}

PathNode *getDstPathNode() const {
return dstNode;
}

PathNode *getSrcPathNode() const {
return srcNode;
}
};
};

#endif /* INCLUDE_UTIL_SICFG_H_ */
#endif /* INCLUDE_WPA_IFDS_H_ */
3 changes: 3 additions & 0 deletions lib/MemoryModel/PAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,9 @@ struct DOTGraphTraits<PAG*> : public DefaultDOTGraphTraits {
bool nameDisplay = true;
std::string str;
raw_string_ostream rawstr(str);
// print function info
if (node->getFunction())
rawstr << "[" << node->getFunction()->getName() << "] ";

if (briefDisplay) {
if (SVFUtil::isa<ValPN>(node)) {
Expand Down
74 changes: 41 additions & 33 deletions lib/Util/ICFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ void ICFG::build(){

void ICFG::connectGlobalToProgEntry()
{
assert(getProgEntryFunction(pag->getModule()));
const Function* mainFunc = SVFUtil::getProgEntryFunction(pag->getModule());

/// Return back if the main function is not found
Expand Down Expand Up @@ -508,39 +509,46 @@ struct DOTGraphTraits<ICFG*> : public DOTGraphTraits<PAG*> {
std::string str;
raw_string_ostream rawstr(str);
rawstr << "NodeID: " << node->getId() << "\n";
if (IntraBlockNode* bNode = SVFUtil::dyn_cast<IntraBlockNode>(node)) {
rawstr << getSourceLoc(bNode->getInst()) << "\n";
rawstr << "Fun[" << bNode->getInst()->getName() << "]";
if (DumpLLVMInst)
rawstr << *(bNode->getInst()) << "\n";
} else if (FunEntryBlockNode* entry = SVFUtil::dyn_cast<
FunEntryBlockNode>(node)) {
if (isExtCall(entry->getFun()))
rawstr << "Entry(" << ")\n";
else
rawstr << "Entry(" << getSourceLoc(entry->getFun()) << ")\n";
rawstr << "Fun[" << entry->getFun()->getName() << "]";
} else if (FunExitBlockNode* exit = SVFUtil::dyn_cast<FunExitBlockNode>(
node)) {
if (isExtCall(exit->getFun()))
rawstr << "Exit(" << ")\n";
else
rawstr << "Exit(" << getSourceLoc(&(exit->getBB()->back())) << ")\n";
rawstr << "Fun[" << exit->getFun()->getName() << "]";
} else if (CallBlockNode* call = SVFUtil::dyn_cast<CallBlockNode>(
node)) {
rawstr << "Call("
<< getSourceLoc(call->getCallSite().getInstruction())
<< ")\n";
rawstr << "Fun[" << call->getCallSite()->getFunction()->getName()
<< "]";
} else if (RetBlockNode* ret = SVFUtil::dyn_cast<RetBlockNode>(node)) {
rawstr << "Ret("
<< getSourceLoc(ret->getCallSite().getInstruction())
<< ")\n";
rawstr << "Fun[" << ret->getCallSite()->getFunction()->getName()
<< "]";
}
if (IntraBlockNode* bNode = SVFUtil::dyn_cast<IntraBlockNode>(node)) {
rawstr << getSourceLoc(bNode->getInst()) << "\n";

IntraBlockNode::StmtOrPHIVFGNodeVec& nodes = bNode->getVFGNodes();
for (IntraBlockNode::StmtOrPHIVFGNodeVec::iterator it = nodes.begin(), eit = nodes.end(); it != eit; ++it){
const VFGNode* node = *it;
if(const StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node)){
NodeID src = stmtNode->getPAGSrcNodeID();
NodeID dst = stmtNode->getPAGDstNodeID();
rawstr << dst << "<--" << src << "\n";
std::string srcValueName = stmtNode->getPAGSrcNode()->getValueName();
std::string dstValueName = stmtNode->getPAGDstNode()->getValueName();
rawstr << dstValueName << "<--" << srcValueName << "\n";
}
}

if(DumpLLVMInst)
rawstr << *(bNode->getInst()) << "\n";
} else if (FunEntryBlockNode* entry = SVFUtil::dyn_cast<FunEntryBlockNode>(node)) {
if (isExtCall(entry->getFun()))
rawstr << "Entry(" << ")\n";
else
rawstr << "Entry(" << getSourceLoc(entry->getFun()) << ")\n";
rawstr << "Fun[" << entry->getFun()->getName() << "]";
} else if (FunExitBlockNode* exit = SVFUtil::dyn_cast<FunExitBlockNode>(node)) {
if (isExtCall(exit->getFun()))
rawstr << "Exit(" << ")\n";
else
rawstr << "Exit(" << getSourceLoc(&(exit->getBB()->back()))
<< ")\n";
rawstr << "Fun[" << exit->getFun()->getName() << "]";
} else if (CallBlockNode* call = SVFUtil::dyn_cast<CallBlockNode>(node)) {
rawstr << "Call("
<< getSourceLoc(call->getCallSite().getInstruction())
<< ")\n";
} else if (RetBlockNode* ret = SVFUtil::dyn_cast<RetBlockNode>(node)) {
rawstr << "Ret("
<< getSourceLoc(ret->getCallSite().getInstruction())
<< ")\n";
}
else
assert(false && "what else kinds of nodes do we have??");

Expand Down
Loading

0 comments on commit 0d3baec

Please sign in to comment.