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

0822 wip #1196

Merged
merged 19 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions svf/include/MemoryModel/PointerAnalysisImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,12 @@ class BVDataPTAImpl : public PointerAnalysis
//@{
virtual void writeToFile(const std::string& filename);
virtual void writeObjVarToFile(const std::string& filename);
virtual void writePtsResultToFile(std::fstream& f);
virtual void writeGepObjVarMapToFile(std::fstream& f);
virtual bool readFromFile(const std::string& filename);
virtual void readPtsResultFromFile(std::ifstream& f);
virtual void readGepObjVarMapFromFile(std::ifstream& f);
virtual void readAndSetObjFieldSensitivity(std::ifstream& f, const std::string& delimiterStr);
//@}

protected:
Expand Down
5 changes: 3 additions & 2 deletions svf/include/SVFIR/SVFIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class SVFIR : public IRGraph
friend class TypeBasedHeapCloning;
friend class SVFIRWriter;
friend class SVFIRReader;
friend class BVDataPTAImpl;

public:
typedef Set<const CallICFGNode*> CallSiteSet;
Expand Down Expand Up @@ -391,7 +392,7 @@ class SVFIR : public IRGraph
return node->getMemObj();
}
//@}

/// Get a field SVFIR Object node according to base mem obj and offset
NodeID getGepObjVar(const MemObj* obj, const APOffset& ap);
/// Get a field obj SVFIR node according to a mem obj and a given offset
Expand Down Expand Up @@ -560,7 +561,7 @@ class SVFIR : public IRGraph
/// Add a temp field value node, this method can only invoked by getGepValVar
NodeID addGepValNode(const SVFValue* curInst,const SVFValue* val, const AccessPath& ap, NodeID i, const SVFType* type);
/// Add a field obj node, this method can only invoked by getGepObjVar
NodeID addGepObjNode(const MemObj* obj, const APOffset& apOffset);
NodeID addGepObjNode(const MemObj* obj, const APOffset& apOffset, const NodeID gepId);
/// Add a field-insensitive node, this method can only invoked by getFIGepObjNode
NodeID addFIObjNode(const MemObj* obj);
//@}
Expand Down
6 changes: 6 additions & 0 deletions svf/include/Util/NodeIDAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ class NodeIDAllocator
return numObjects;
}

inline void increaseNumOfObjAndNodes()
{
++numObjects;
++numNodes;
}

private:
/// Builds a node ID allocator with the strategy specified on the command line.
NodeIDAllocator(void);
Expand Down
8 changes: 8 additions & 0 deletions svf/include/WPA/VersionedFlowSensitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ class VersionedFlowSensitive : public FlowSensitive
/// Dumps maps consume and yield.
void dumpLocVersionMaps(void) const;

void solveAndwritePtsToFile(const std::string& filename) override;

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

void readVersionedAnalysisResultFromFile(std::ifstream& F);

void readPtsFromFile(const std::string& filename) override;

/// Dumps a MeldVersion to stdout.
static void dumpMeldVersion(MeldVersion &v);

Expand Down
169 changes: 102 additions & 67 deletions svf/lib/MemoryModel/PointerAnalysisImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,24 +195,8 @@ void BVDataPTAImpl::writeObjVarToFile(const string& filename)

}

/*!
* Store pointer analysis result into a file.
* It includes the points-to relations, and all SVFIR nodes including those
* created when solving Andersen's constraints.
*/
void BVDataPTAImpl::writeToFile(const string& filename)
void BVDataPTAImpl::writePtsResultToFile(std::fstream& f)
{

outs() << "Storing pointer analysis results to '" << filename << "'...";

error_code err;
std::fstream f(filename.c_str(), std::ios_base::app);
if (!f.good())
{
outs() << " error opening file for writing!\n";
return;
}

// Write analysis results to file
for (auto it = pag->begin(), ie = pag->end(); it != ie; ++it)
{
Expand All @@ -235,20 +219,49 @@ void BVDataPTAImpl::writeToFile(const string& filename)
f << "}\n";
}

f << "------\n";
}

// Write GepPAGNodes to file
for (auto it = pag->begin(), ie = pag->end(); it != ie; ++it)
void BVDataPTAImpl::writeGepObjVarMapToFile(std::fstream& f)
{
//write gepObjVarMap to file(in form of: baseID offset gepObjNodeId)
SVFIR::NodeOffsetMap &gepObjVarMap = pag->getGepObjNodeMap();
for(SVFIR::NodeOffsetMap::const_iterator it = gepObjVarMap.begin(), eit = gepObjVarMap.end(); it != eit; it++)
{
PAGNode* pagNode = it->second;
if (GepObjVar *gepObjPN = SVFUtil::dyn_cast<GepObjVar>(pagNode))
{
f << it->first << " ";
f << pag->getBaseObjVar(it->first) << " ";
f << gepObjPN->getConstantFieldIdx() << "\n";
}
const SVFIR::NodeOffset offsetPair = it -> first;
//write the base id to file
f << offsetPair.first << " ";
//write the offset to file
f << offsetPair.second << " ";
//write the gepObjNodeId to file
f << it->second << "\n";
}

}

/*!
* Store pointer analysis result into a file.
* It includes the points-to relations, and all SVFIR nodes including those
* created when solving Andersen's constraints.
*/
void BVDataPTAImpl::writeToFile(const string& filename)
{

outs() << "Storing pointer analysis results to '" << filename << "'...";

error_code err;
std::fstream f(filename.c_str(), std::ios_base::app);
if (!f.good())
{
outs() << " error opening file for writing!\n";
return;
}

writePtsResultToFile(f);

f << "------\n";

writeGepObjVarMapToFile(f);

f << "------\n";

// Write BaseNodes insensitivity to file
Expand All @@ -273,39 +286,9 @@ void BVDataPTAImpl::writeToFile(const string& filename)
}
}

/*!
* Load pointer analysis result form a file.
* It populates BVDataPTAImpl with the points-to data, and updates SVFIR with
* the SVFIR offset nodes created during Andersen's solving stage.
*/
bool BVDataPTAImpl::readFromFile(const string& filename)
void BVDataPTAImpl::readPtsResultFromFile(std::ifstream& F)
{

outs() << "Loading pointer analysis results from '" << filename << "'...";

ifstream F(filename.c_str());
if (!F.is_open())
{
outs() << " error opening file for reading!\n";
return false;
}

// Read ObjVar
string line;
while (F.good())
{
getline(F, line);
if (line == "------") break;
// Parse a single line in the form of "baseNodeID insensitive"
istringstream ss(line);
NodeID base;
bool insensitive;
ss >> base >> insensitive;

if (insensitive)
setObjFieldInsensitive(base);
}

// Read analysis results from file
PTDataTy *ptD = getPTDataTy();

Expand All @@ -319,6 +302,7 @@ bool BVDataPTAImpl::readFromFile(const string& filename)
{
// Parse a single line in the form of "var -> { obj1 obj2 obj3 }"
getline(F, line);
if (line.at(0) == '[' || line == "---VERSIONED---") continue;
if (line == "------") break;
size_t pos = line.find(delimiter1);
if (pos == string::npos) break;
Expand Down Expand Up @@ -354,29 +338,52 @@ bool BVDataPTAImpl::readFromFile(const string& filename)
// map the variable ID to its pointer set
for (auto t: nodePtsMap)
ptD->unionPts(t.first, strPtsMap[t.second]);
}

// Read BaseNode insensitivity
while (F.good())
void BVDataPTAImpl::readGepObjVarMapFromFile(std::ifstream& F)
{
string line;
//read GepObjVarMap from file
SVFIR::NodeOffsetMap gepObjVarMap = pag->getGepObjNodeMap();
while (F.good())
{
getline(F, line);
if (line == "------") break;
// Parse a single line in the form of "ID baseNodeID offset"
istringstream ss(line);
NodeID id;
NodeID base;
size_t offset;
ss >> id >> base >> offset;
NodeID n = pag->getGepObjVar(base, offset);
bool matched = (id == n);
(void)matched;
assert(matched && "Error adding GepObjNode into SVFIR!");
NodeID id;
ss >> base >> offset >>id;
SVFIR::NodeOffsetMap::const_iterator iter = gepObjVarMap.find(std::make_pair(base, offset));
if (iter == gepObjVarMap.end())
{
SVFVar* node = pag->getGNode(base);
const MemObj* obj = nullptr;
if (GepObjVar* gepObjVar = SVFUtil::dyn_cast<GepObjVar>(node))
obj = gepObjVar->getMemObj();
else if (FIObjVar* baseNode = SVFUtil::dyn_cast<FIObjVar>(node))
obj = baseNode->getMemObj();
else if (DummyObjVar* baseNode = SVFUtil::dyn_cast<DummyObjVar>(node))
obj = baseNode->getMemObj();
else
assert(false && "new gep obj node kind?");
pag->addGepObjNode(obj, offset, id);
NodeIDAllocator::get()->increaseNumOfObjAndNodes();
}


}
}

void BVDataPTAImpl::readAndSetObjFieldSensitivity(std::ifstream& F, const std::string& delimiterStr)
{
string line;
// //update ObjVar status
while (F.good())
{
getline(F, line);
if (line.empty())
if (line.empty() || line == delimiterStr)
break;
// Parse a single line in the form of "baseNodeID insensitive"
istringstream ss(line);
Expand All @@ -388,6 +395,33 @@ bool BVDataPTAImpl::readFromFile(const string& filename)
setObjFieldInsensitive(base);
}

}

/*!
* Load pointer analysis result form a file.
* It populates BVDataPTAImpl with the points-to data, and updates SVFIR with
* the SVFIR offset nodes created during Andersen's solving stage.
*/
bool BVDataPTAImpl::readFromFile(const string& filename)
{

outs() << "Loading pointer analysis results from '" << filename << "'...";

ifstream F(filename.c_str());
if (!F.is_open())
{
outs() << " error opening file for reading!\n";
return false;
}

readAndSetObjFieldSensitivity(F,"------");

readPtsResultFromFile(F);

readGepObjVarMapFromFile(F);

readAndSetObjFieldSensitivity(F,"");

// Update callgraph
updateCallGraph(pag->getIndirectCallsites());

Expand All @@ -397,6 +431,7 @@ bool BVDataPTAImpl::readFromFile(const string& filename)
return true;
}


/*!
* Dump points-to of each pag node
*/
Expand Down
8 changes: 5 additions & 3 deletions svf/lib/SVFIR/SVFIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,10 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset)

NodeOffsetMap::iterator iter = GepObjVarMap.find(std::make_pair(base, newLS));
if (iter == GepObjVarMap.end())
return addGepObjNode(obj, newLS);
{
NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, apOffset, Options::MaxFieldLimit());
return addGepObjNode(obj, newLS,gepId);
}
else
return iter->second;

Expand All @@ -443,14 +446,13 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset)
/*!
* Add a field obj node, this method can only invoked by getGepObjVar
*/
NodeID SVFIR::addGepObjNode(const MemObj* obj, const APOffset& apOffset)
NodeID SVFIR::addGepObjNode(const MemObj* obj, const APOffset& apOffset, const NodeID gepId)
{
//assert(findPAGNode(i) == false && "this node should not be created before");
NodeID base = obj->getId();
assert(0==GepObjVarMap.count(std::make_pair(base, apOffset))
&& "this node should not be created before");

NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, apOffset, Options::MaxFieldLimit());
GepObjVarMap[std::make_pair(base, apOffset)] = gepId;
GepObjVar *node = new GepObjVar(obj, gepId, apOffset);
memToFieldsMap[base].set(gepId);
Expand Down
6 changes: 2 additions & 4 deletions svf/lib/Util/NodeIDAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ NodeID NodeIDAllocator::allocateObjectId(void)
assert(false && "NodeIDAllocator::allocateObjectId: unimplemented node allocation strategy.");
}

++numObjects;
++numNodes;
increaseNumOfObjAndNodes();

assert(id != 0 && "NodeIDAllocator::allocateObjectId: ID not allocated");
return id;
Expand Down Expand Up @@ -120,8 +119,7 @@ NodeID NodeIDAllocator::allocateGepObjectId(NodeID base, u32_t offset, u32_t max
assert(false && "NodeIDAllocator::allocateGepObjectId: unimplemented node allocation strategy");
}

++numObjects;
++numNodes;
increaseNumOfObjAndNodes();

assert(id != 0 && "NodeIDAllocator::allocateGepObjectId: ID not allocated");
return id;
Expand Down
2 changes: 1 addition & 1 deletion svf/lib/WPA/Andersen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ void AndersenBase::readPtsFromFile(const std::string& filename)
initialize();
if (!filename.empty())
this->readFromFile(filename);
PointerAnalysis::finalize();
finalize();
}

/*!
Expand Down
Loading