Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build pag from the given pag json file #174

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
update pag builder
  • Loading branch information
JasonZhongZexin committed Mar 15, 2020
commit ae7fb7070739e305d3798e22f3450a334a07be69
6 changes: 6 additions & 0 deletions include/MemoryModel/PAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,12 @@ class PAG : public GenericGraph<PAGNode,PAGEdge> {
/// Print PAG
void print();

void printInst2JsonFile(const std::string& filename);

std::string getNodeKindValue(int kind);

std::string getEdgeKindValue(int kind);

/// Dump PAG
void dump(std::string name);

Expand Down
167 changes: 167 additions & 0 deletions lib/MemoryModel/PAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include "MemoryModel/PAG.h"
#include "Util/SVFUtil.h"
#include "llvm/Support/JSON.h"

using namespace SVFUtil;

Expand Down Expand Up @@ -246,6 +247,172 @@ bool PAG::addFormalParamBlackHoleAddrEdge(NodeID node, const Argument *arg)
return added;
}

void PAG::printInst2JsonFile(const std::string& filename){
outs() << "write symbols to '" << filename << "'...";

std::error_code err;
ToolOutputFile F(filename.c_str(), err, llvm::sys::fs::F_None);
if (err) {
outs() << " error opening file for writing!\n";
F.os().clear_error();
return;
}

llvm::json::Array root_array;
for(Inst2PAGEdgesMap::const_iterator it = inst2PAGEdgesMap.begin();
it!=inst2PAGEdgesMap.end(); it++){
llvm::json::Object currentInst;
char hex_char[30];
const Instruction* inst = it->first;
const PAGEdgeList& pagEdgeList = it->second;
std::sprintf(hex_char,"%p",inst);
currentInst["current Inst"] =std::string(hex_char);

llvm::json::Array next_inst_array;
std::vector<const Instruction*> instList;
getNextInsts(inst,instList);
for (std::vector<const Instruction*>::const_iterator nit = instList.begin();
nit!=instList.end(); ++nit){
std::sprintf(hex_char,"%p",*nit);
next_inst_array.push_back(std::string(hex_char));
}
llvm::json::Value next_inst_value = llvm::json::Array{next_inst_array};
currentInst["next Inst"] = next_inst_value;

llvm::json::Array edges_array;
for (PAGEdgeList::const_iterator bit = pagEdgeList.begin(),
ebit = pagEdgeList.end(); bit != ebit; ++bit) {
const PAGEdge* edge = *bit;
llvm::json::Object edge_obj;
edge_obj["source node"] = edge->getSrcID();
edge_obj["destination node"] = edge->getDstID();
edge_obj["source node type"] = getNodeKindValue(edge->getSrcNode()->getNodeKind());
edge_obj["destination node type"] = getNodeKindValue(edge->getDstNode()->getNodeKind());
edge_obj["edge type"] = getEdgeKindValue(edge->getEdgeKind());
if(edge->getEdgeKind()==PAGEdge::NormalGep){
const NormalGepPE* gepEdge = SVFUtil::cast<NormalGepPE>(edge);
edge_obj["offset"] = gepEdge->getOffset();
}
llvm::json::Value edge_value = llvm::json::Object{edge_obj};
edges_array.push_back(edge_value);
}

llvm::json::Value edges_array_value = llvm::json::Array{edges_array};
currentInst["edges"] = edges_array_value;

llvm::json::Value currentInst_value = llvm::json::Object{currentInst};
root_array.push_back(currentInst_value);
}

llvm::json::Value root_array_value = llvm::json::Array{root_array};
llvm::json::Object root;
root["Instructions"] = root_array_value;
llvm::json::Array global_edge_array;
for(PAGEdgeSet::const_iterator it = globPAGEdgesSet.begin(); it!=globPAGEdgesSet.end(); it++){
const PAGEdge* edge = *it;
llvm::json::Object global_edge_obj;
global_edge_obj["source node"] = edge->getSrcID();
global_edge_obj["destination node"]= edge->getDstID();
global_edge_obj["source node type"] = getNodeKindValue(edge->getSrcNode()->getNodeKind());
global_edge_obj["destination node type"] = getNodeKindValue(edge->getDstNode()->getNodeKind());
global_edge_obj["edge type"] = getEdgeKindValue(edge->getEdgeKind());
if(edge->getEdgeKind()==PAGEdge::NormalGep){
const NormalGepPE* gepEdge = SVFUtil::cast<NormalGepPE>(edge);
global_edge_obj["offset"] = gepEdge->getOffset();
}
llvm::json::Value edge_value = llvm::json::Object{global_edge_obj};
global_edge_array.push_back(edge_value);
}
llvm::json::Value global_edge_array_value = llvm::json::Array{global_edge_array};
root["global edge"] = global_edge_array_value;
llvm::json::Value root_value = llvm::json::Object{root};

llvm::json::operator<<(F.os(),root_value);

F.os().close();
if (!F.os().has_error()) {
outs() << "\n";
F.keep();
return;
}

}

std::string PAG::getNodeKindValue(int kind){
switch (kind){
case (PAGNode::ValNode):
return "ValNode";
break;
case PAGNode::ObjNode:
return "ObjNode";
break;
case PAGNode::RetNode:
return "RetNode";
break;
case PAGNode::VarargNode:
return "VarargNode";
break;
case PAGNode::GepValNode:
return "GepValNode";
break;
case PAGNode::GepObjNode:
return "GepObjNode";
break;
case PAGNode::FIObjNode:
return "FIObjNode";
break;
case PAGNode::DummyValNode:
return "DummyValNode";
break;
case PAGNode::DummyObjNode:
return "DummyObjNode";
break;
}
return "";
}

std::string PAG::getEdgeKindValue(int kind){
switch(kind){
case (PAGEdge::Addr):
return "Addr";
break;
case (PAGEdge::Copy):
return "Copy";
break;
case (PAGEdge::Store):
return "Store";
break;
case (PAGEdge::Load):
return "Load";
break;
case (PAGEdge::Call):
return "Call";
break;
case (PAGEdge::Ret):
return "Ret";
break;
case (PAGEdge::NormalGep):
return "NormalGep";
break;
case (PAGEdge::VariantGep):
return "VariantGep";
break;
case (PAGEdge::ThreadFork):
return "ThreadFork";
break;
case (PAGEdge::ThreadJoin):
return "ThreadJoin";
break;
case (PAGEdge::Cmp):
return "Cmp";
break;
case (PAGEdge::BinaryOp):
return "BinaryOp";
break;
}
return "";
}


/*!
* Add a temp field value node according to base value and offset
Expand Down
50 changes: 26 additions & 24 deletions lib/MemoryModel/PAGBuilderFromFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,11 @@ PAG* PAGBuilderFromFile::buildFromICFG(){
//add new node
string var = "hello world";
const char *val = var.c_str();
if(!pag->hasGNode(source_node)){
if(!pag->hasGNode(source_node))
addNode(source_node,source_node_type,val);
}else if(!pag->hasGNode(destination_node)){
if(!pag->hasGNode(destination_node))
addNode(destination_node,destination_node_type,val);
}else{
if(pag->hasGNode(source_node)&&pag->hasGNode(destination_node)){
if(offset!="")
addEdge(source_node, destination_node, std::stol(offset), edge_type);
else
Expand Down Expand Up @@ -251,34 +251,36 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID,
PAGNode* srcNode = pag->getPAGNode(srcID);
PAGNode* dstNode = pag->getPAGNode(dstID);

/// sanity check for PAG from txt
assert(SVFUtil::isa<ValPN>(dstNode) && "dst not an value node?");
if(edge=="addr")
assert(SVFUtil::isa<ObjPN>(srcNode) && "src not an value node?");
else
assert(!SVFUtil::isa<ObjPN>(srcNode) && "src not an object node?");

if (edge == "Addr"){
pag->addAddrEdge(srcID, dstID);
}
else if (edge == "Copy")
pag->addCopyEdge(srcID, dstID);
else if (edge == "Load")
pag->addLoadEdge(srcID, dstID);
else if (edge == "Store")
pag->addStoreEdge(srcID, dstID);
else if (edge == "NormalGep")
pag->addNormalGepEdge(srcID, dstID, LocationSet(offsetOrCSId));
else if (edge == "VariantGep")
pag->addVariantGepEdge(srcID, dstID);
else if (edge == "Call")
else if (edge == "Copy"){
pag->addCopyEdge(srcID, dstID);
}
else if (edge == "Load"){
pag->addLoadEdge(srcID, dstID);
}
else if (edge == "Store"){
pag->addStoreEdge(srcID, dstID);
}
else if (edge == "NormalGep"){
pag->addNormalGepEdge(srcID, dstID, LocationSet(offsetOrCSId));
}
else if (edge == "VariantGep"){
pag->addVariantGepEdge(srcID, dstID);
}
else if (edge == "Call"){
pag->addEdge(srcNode, dstNode, new CallPE(srcNode, dstNode, NULL));
else if (edge == "Ret")
}
else if (edge == "Ret"){
pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, NULL));
else if (edge == "Cmp")
}
else if (edge == "Cmp"){
pag->addCmpEdge(srcID, dstID);
else if (edge == "BinaryOp")
}
else if (edge == "BinaryOp"){
pag->addBinaryOPEdge(srcID, dstID);
}
else
assert(false && "format not support, can not create such edge");
}
Expand Down