svf-tools 1.0.733 → 1.0.735
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/svf/include/AbstractExecution/SVFIR2ConsExeState.h +1 -1
- package/svf/include/AbstractExecution/SVFIR2ItvExeState.h +1 -1
- package/svf/include/Graphs/ConsG.h +4 -4
- package/svf/include/Graphs/ConsGEdge.h +10 -8
- package/svf/include/MemoryModel/{LocationSet.h → AccessPath.h} +26 -25
- package/svf/include/MemoryModel/PointerAnalysis.h +2 -2
- package/svf/include/SVFIR/PAGBuilderFromFile.h +1 -1
- package/svf/include/SVFIR/SVFFileSystem.h +3 -3
- package/svf/include/SVFIR/SVFIR.h +16 -15
- package/svf/include/SVFIR/SVFStatements.h +14 -14
- package/svf/include/SVFIR/SVFType.h +1 -0
- package/svf/include/SVFIR/SVFVariables.h +13 -19
- package/svf/include/SVFIR/SymbolTableInfo.h +5 -4
- package/svf/include/Util/Options.h +1 -1
- package/svf/include/Util/Z3Expr.h +2 -2
- package/svf/include/WPA/AndersenPWC.h +1 -1
- package/svf/lib/AbstractExecution/SVFIR2ConsExeState.cpp +2 -2
- package/svf/lib/AbstractExecution/SVFIR2ItvExeState.cpp +3 -3
- package/svf/lib/DDA/ContextDDA.cpp +1 -1
- package/svf/lib/DDA/FlowDDA.cpp +1 -1
- package/svf/lib/Graphs/ConsG.cpp +8 -7
- package/svf/lib/MemoryModel/{LocationSet.cpp → AccessPath.cpp} +20 -23
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +4 -4
- package/svf/lib/SVFIR/PAGBuilderFromFile.cpp +4 -4
- package/svf/lib/SVFIR/SVFFileSystem.cpp +14 -14
- package/svf/lib/SVFIR/SVFIR.cpp +29 -28
- package/svf/lib/SVFIR/SVFVariables.cpp +1 -1
- package/svf/lib/SVFIR/SymbolTableInfo.cpp +8 -8
- package/svf/lib/Util/Options.cpp +1 -1
- package/svf/lib/Util/Z3Expr.cpp +2 -2
- package/svf/lib/WPA/Andersen.cpp +4 -4
- package/svf/lib/WPA/AndersenSFR.cpp +7 -7
- package/svf/lib/WPA/FlowSensitive.cpp +1 -1
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +17 -17
- package/svf-llvm/lib/SVFIRBuilder.cpp +30 -30
- package/svf-llvm/lib/SVFIRExtAPI.cpp +9 -9
- package/svf-llvm/tools/MTA/LockResultValidator.cpp +1 -1
|
@@ -171,7 +171,7 @@ CxtPtSet ContextDDA::processGepPts(const GepSVFGNode* gep, const CxtPtSet& srcPt
|
|
|
171
171
|
}
|
|
172
172
|
else
|
|
173
173
|
{
|
|
174
|
-
CxtVar var(ptd.get_cond(),getGepObjVar(ptd.get_id(),gepStmt->
|
|
174
|
+
CxtVar var(ptd.get_cond(),getGepObjVar(ptd.get_id(),gepStmt->getAccessPath().getConstantFieldIdx()));
|
|
175
175
|
tmpDstPts.set(var);
|
|
176
176
|
}
|
|
177
177
|
}
|
package/svf/lib/DDA/FlowDDA.cpp
CHANGED
|
@@ -156,7 +156,7 @@ PointsTo FlowDDA::processGepPts(const GepSVFGNode* gep, const PointsTo& srcPts)
|
|
|
156
156
|
}
|
|
157
157
|
else
|
|
158
158
|
{
|
|
159
|
-
NodeID fieldSrcPtdNode = getGepObjVar(ptd, gepStmt->
|
|
159
|
+
NodeID fieldSrcPtdNode = getGepObjVar(ptd, gepStmt->getAccessPath().getConstantFieldIdx());
|
|
160
160
|
tmpDstPts.set(fieldSrcPtdNode);
|
|
161
161
|
}
|
|
162
162
|
}
|
package/svf/lib/Graphs/ConsG.cpp
CHANGED
|
@@ -121,7 +121,7 @@ void ConstraintGraph::buildCG()
|
|
|
121
121
|
if(edge->isVariantFieldGep())
|
|
122
122
|
addVariantGepCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
|
|
123
123
|
else
|
|
124
|
-
addNormalGepCGEdge(edge->getRHSVarID(),edge->getLHSVarID(),edge->
|
|
124
|
+
addNormalGepCGEdge(edge->getRHSVarID(),edge->getLHSVarID(),edge->getAccessPath());
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
SVFStmt::SVFStmtSetTy& loads = getPAGEdgeSet(SVFStmt::Load);
|
|
@@ -210,14 +210,15 @@ CopyCGEdge* ConstraintGraph::addCopyCGEdge(NodeID src, NodeID dst)
|
|
|
210
210
|
/*!
|
|
211
211
|
* Add Gep edge
|
|
212
212
|
*/
|
|
213
|
-
NormalGepCGEdge* ConstraintGraph::addNormalGepCGEdge(NodeID src, NodeID dst, const
|
|
213
|
+
NormalGepCGEdge* ConstraintGraph::addNormalGepCGEdge(NodeID src, NodeID dst, const AccessPath& ap)
|
|
214
214
|
{
|
|
215
215
|
ConstraintNode* srcNode = getConstraintNode(src);
|
|
216
216
|
ConstraintNode* dstNode = getConstraintNode(dst);
|
|
217
217
|
if (hasEdge(srcNode, dstNode, ConstraintEdge::NormalGep))
|
|
218
218
|
return nullptr;
|
|
219
219
|
|
|
220
|
-
NormalGepCGEdge* edge =
|
|
220
|
+
NormalGepCGEdge* edge =
|
|
221
|
+
new NormalGepCGEdge(srcNode, dstNode, ap, edgeIndex++);
|
|
221
222
|
|
|
222
223
|
bool inserted = directEdgeSet.insert(edge).second;
|
|
223
224
|
(void)inserted; // Suppress warning of unused variable under release build
|
|
@@ -320,9 +321,9 @@ void ConstraintGraph::reTargetDstOfEdge(ConstraintEdge* edge, ConstraintNode* ne
|
|
|
320
321
|
}
|
|
321
322
|
else if(NormalGepCGEdge* gep = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
|
|
322
323
|
{
|
|
323
|
-
const
|
|
324
|
+
const AccessPath ap = gep->getAccessPath();
|
|
324
325
|
removeDirectEdge(gep);
|
|
325
|
-
addNormalGepCGEdge(srcId,newDstNodeID,
|
|
326
|
+
addNormalGepCGEdge(srcId,newDstNodeID, ap);
|
|
326
327
|
}
|
|
327
328
|
else if(VariantGepCGEdge* gep = SVFUtil::dyn_cast<VariantGepCGEdge>(edge))
|
|
328
329
|
{
|
|
@@ -364,9 +365,9 @@ void ConstraintGraph::reTargetSrcOfEdge(ConstraintEdge* edge, ConstraintNode* ne
|
|
|
364
365
|
}
|
|
365
366
|
else if(NormalGepCGEdge* gep = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
|
|
366
367
|
{
|
|
367
|
-
const
|
|
368
|
+
const AccessPath ap = gep->getAccessPath();
|
|
368
369
|
removeDirectEdge(gep);
|
|
369
|
-
addNormalGepCGEdge(newSrcNodeID,dstId,
|
|
370
|
+
addNormalGepCGEdge(newSrcNodeID, dstId, ap);
|
|
370
371
|
}
|
|
371
372
|
else if(VariantGepCGEdge* gep = SVFUtil::dyn_cast<VariantGepCGEdge>(edge))
|
|
372
373
|
{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===-
|
|
1
|
+
//===- AccessPath.cpp -- Location set for modeling abstract memory object----//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
//===----------------------------------------------------------------------===//
|
|
22
22
|
|
|
23
23
|
/*
|
|
24
|
-
* @file:
|
|
24
|
+
* @file: AccessPath.cpp
|
|
25
25
|
* @author: yesen
|
|
26
26
|
* @date: 26 Sep 2014
|
|
27
27
|
*
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
32
|
#include "Util/Options.h"
|
|
33
|
-
#include "MemoryModel/
|
|
33
|
+
#include "MemoryModel/AccessPath.h"
|
|
34
34
|
#include "Util/SVFUtil.h"
|
|
35
35
|
|
|
36
36
|
using namespace SVF;
|
|
@@ -39,14 +39,14 @@ using namespace SVFUtil;
|
|
|
39
39
|
/*!
|
|
40
40
|
* Add offset value to vector offsetVarAndGepTypePairs
|
|
41
41
|
*/
|
|
42
|
-
bool
|
|
42
|
+
bool AccessPath::addOffsetVarAndGepTypePair(const SVFVar* var, const SVFType* gepIterType)
|
|
43
43
|
{
|
|
44
44
|
offsetVarAndGepTypePairs.emplace_back(var, gepIterType);
|
|
45
45
|
return true;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/// Return true if all offset values are constants
|
|
49
|
-
bool
|
|
49
|
+
bool AccessPath::isConstantOffset() const
|
|
50
50
|
{
|
|
51
51
|
for(auto it : offsetVarAndGepTypePairs)
|
|
52
52
|
{
|
|
@@ -60,7 +60,7 @@ bool LocationSet::isConstantOffset() const
|
|
|
60
60
|
/// (1) StructType or Array, return flatterned number elements.
|
|
61
61
|
/// (2) PointerType, return the element number of the pointee
|
|
62
62
|
/// (3) non-pointer SingleValueType, return 1
|
|
63
|
-
u32_t
|
|
63
|
+
u32_t AccessPath::getElementNum(const SVFType* type) const
|
|
64
64
|
{
|
|
65
65
|
|
|
66
66
|
if (SVFUtil::isa<SVFArrayType, SVFStructType>(type))
|
|
@@ -115,7 +115,7 @@ u32_t LocationSet::getElementNum(const SVFType* type) const
|
|
|
115
115
|
/// value1: i64 0 type1: [3 x i8]*
|
|
116
116
|
/// value2: i64 2 type2: [3 x i8]
|
|
117
117
|
/// computeConstantOffset = 2
|
|
118
|
-
|
|
118
|
+
APOffset AccessPath::computeConstantOffset() const
|
|
119
119
|
{
|
|
120
120
|
|
|
121
121
|
assert(isConstantOffset() && "not a constant offset");
|
|
@@ -123,7 +123,7 @@ s32_t LocationSet::computeConstantOffset() const
|
|
|
123
123
|
if(offsetVarAndGepTypePairs.empty())
|
|
124
124
|
return getConstantFieldIdx();
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
APOffset totalConstOffset = 0;
|
|
127
127
|
for(int i = offsetVarAndGepTypePairs.size() - 1; i >= 0; i--)
|
|
128
128
|
{
|
|
129
129
|
const SVFValue* value = offsetVarAndGepTypePairs[i].first->getValue();
|
|
@@ -140,7 +140,7 @@ s32_t LocationSet::computeConstantOffset() const
|
|
|
140
140
|
totalConstOffset += op->getSExtValue() * getElementNum(pty->getPtrElementType());
|
|
141
141
|
else
|
|
142
142
|
{
|
|
143
|
-
|
|
143
|
+
APOffset offset = op->getSExtValue();
|
|
144
144
|
u32_t flattenOffset = SymbolTableInfo::SymbolInfo()->getFlattenedElemIdx(type, offset);
|
|
145
145
|
totalConstOffset += flattenOffset;
|
|
146
146
|
}
|
|
@@ -150,27 +150,24 @@ s32_t LocationSet::computeConstantOffset() const
|
|
|
150
150
|
/*!
|
|
151
151
|
* Compute all possible locations according to offset and number-stride pairs.
|
|
152
152
|
*/
|
|
153
|
-
NodeBS
|
|
153
|
+
NodeBS AccessPath::computeAllLocations() const
|
|
154
154
|
{
|
|
155
155
|
NodeBS result;
|
|
156
156
|
result.set(getConstantFieldIdx());
|
|
157
157
|
return result;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
AccessPath AccessPath::operator+(const AccessPath& rhs) const
|
|
161
161
|
{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
for (; it != eit; ++it)
|
|
167
|
-
ls.addOffsetVarAndGepTypePair(it->first, it->second);
|
|
162
|
+
AccessPath ap(rhs);
|
|
163
|
+
ap.fldIdx += getConstantFieldIdx();
|
|
164
|
+
for (auto &p : ap.getOffsetVarAndGepTypePairVec())
|
|
165
|
+
ap.addOffsetVarAndGepTypePair(p.first, p.second);
|
|
168
166
|
|
|
169
|
-
return
|
|
167
|
+
return ap;
|
|
170
168
|
}
|
|
171
169
|
|
|
172
|
-
|
|
173
|
-
bool LocationSet::operator< (const LocationSet& rhs) const
|
|
170
|
+
bool AccessPath::operator< (const AccessPath& rhs) const
|
|
174
171
|
{
|
|
175
172
|
if (fldIdx != rhs.fldIdx)
|
|
176
173
|
return (fldIdx < rhs.fldIdx);
|
|
@@ -194,7 +191,7 @@ bool LocationSet::operator< (const LocationSet& rhs) const
|
|
|
194
191
|
}
|
|
195
192
|
}
|
|
196
193
|
|
|
197
|
-
SVF::
|
|
194
|
+
SVF::AccessPath::LSRelation AccessPath::checkRelation(const AccessPath& LHS, const AccessPath& RHS)
|
|
198
195
|
{
|
|
199
196
|
NodeBS lhsLocations = LHS.computeAllLocations();
|
|
200
197
|
NodeBS rhsLocations = RHS.computeAllLocations();
|
|
@@ -216,12 +213,12 @@ SVF::LocationSet::LSRelation LocationSet::checkRelation(const LocationSet& LHS,
|
|
|
216
213
|
}
|
|
217
214
|
|
|
218
215
|
/// Dump location set
|
|
219
|
-
std::string
|
|
216
|
+
std::string AccessPath::dump() const
|
|
220
217
|
{
|
|
221
218
|
std::string str;
|
|
222
219
|
std::stringstream rawstr(str);
|
|
223
220
|
|
|
224
|
-
rawstr << "
|
|
221
|
+
rawstr << "AccessPath\tField_Index: " << getConstantFieldIdx();
|
|
225
222
|
rawstr << ",\tNum-Stride: {";
|
|
226
223
|
const OffsetVarAndGepTypePairs& vec = getOffsetVarAndGepTypePairVec();
|
|
227
224
|
OffsetVarAndGepTypePairs::const_iterator it = vec.begin();
|
|
@@ -366,7 +366,7 @@ bool BVDataPTAImpl::readFromFile(const string& filename)
|
|
|
366
366
|
NodeID base;
|
|
367
367
|
size_t offset;
|
|
368
368
|
ss >> id >> base >> offset;
|
|
369
|
-
NodeID n = pag->getGepObjVar(base,
|
|
369
|
+
NodeID n = pag->getGepObjVar(base, offset);
|
|
370
370
|
bool matched = (id == n);
|
|
371
371
|
(void)matched;
|
|
372
372
|
assert(matched && "Error adding GepObjNode into SVFIR!");
|
|
@@ -480,7 +480,7 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,
|
|
|
480
480
|
void BVDataPTAImpl::normalizePointsTo()
|
|
481
481
|
{
|
|
482
482
|
SVFIR::MemObjToFieldsMap &memToFieldsMap = pag->getMemToFieldsMap();
|
|
483
|
-
SVFIR::
|
|
483
|
+
SVFIR::NodeOffsetMap &GepObjVarMap = pag->getGepObjNodeMap();
|
|
484
484
|
|
|
485
485
|
// collect each gep node whose base node has been set as field-insensitive
|
|
486
486
|
NodeBS dropNodes;
|
|
@@ -525,8 +525,8 @@ void BVDataPTAImpl::normalizePointsTo()
|
|
|
525
525
|
{
|
|
526
526
|
NodeID base = pag->getBaseObjVar(n);
|
|
527
527
|
GepObjVar *gepNode = SVFUtil::dyn_cast<GepObjVar>(pag->getGNode(n));
|
|
528
|
-
const
|
|
529
|
-
GepObjVarMap.erase(std::make_pair(base,
|
|
528
|
+
const APOffset apOffset = gepNode->getConstantFieldIdx();
|
|
529
|
+
GepObjVarMap.erase(std::make_pair(base, apOffset));
|
|
530
530
|
memToFieldsMap[base].reset(n);
|
|
531
531
|
|
|
532
532
|
pag->removeGNode(gepNode);
|
|
@@ -103,7 +103,7 @@ SVFIR* PAGBuilderFromFile::build()
|
|
|
103
103
|
{
|
|
104
104
|
NodeID nodeSrc;
|
|
105
105
|
NodeID nodeDst;
|
|
106
|
-
|
|
106
|
+
APOffset offsetOrCSId;
|
|
107
107
|
string edge;
|
|
108
108
|
istringstream ss(line);
|
|
109
109
|
ss >> nodeSrc;
|
|
@@ -144,7 +144,7 @@ SVFIR* PAGBuilderFromFile::build()
|
|
|
144
144
|
* Add SVFIR edge according to a file format
|
|
145
145
|
*/
|
|
146
146
|
void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID,
|
|
147
|
-
|
|
147
|
+
APOffset offsetOrCSId, std::string edge)
|
|
148
148
|
{
|
|
149
149
|
|
|
150
150
|
//check whether these two nodes available
|
|
@@ -169,9 +169,9 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID,
|
|
|
169
169
|
else if (edge == "store")
|
|
170
170
|
pag->addStoreStmt(srcID, dstID, nullptr);
|
|
171
171
|
else if (edge == "gep")
|
|
172
|
-
pag->addNormalGepStmt(srcID, dstID,
|
|
172
|
+
pag->addNormalGepStmt(srcID, dstID, AccessPath(offsetOrCSId));
|
|
173
173
|
else if (edge == "variant-gep")
|
|
174
|
-
pag->addVariantGepStmt(srcID, dstID,
|
|
174
|
+
pag->addVariantGepStmt(srcID, dstID, AccessPath(offsetOrCSId));
|
|
175
175
|
else if (edge == "call")
|
|
176
176
|
pag->addEdge(srcNode, dstNode, new CallPE(srcNode, dstNode, nullptr, nullptr));
|
|
177
177
|
else if (edge == "ret")
|
|
@@ -323,7 +323,7 @@ cJSON* SVFIRWriter::contentToJson(const ObjVar* var)
|
|
|
323
323
|
cJSON* SVFIRWriter::contentToJson(const GepValVar* var)
|
|
324
324
|
{
|
|
325
325
|
cJSON* root = contentToJson(static_cast<const ValVar*>(var));
|
|
326
|
-
JSON_WRITE_FIELD(root, var,
|
|
326
|
+
JSON_WRITE_FIELD(root, var, ap);
|
|
327
327
|
JSON_WRITE_FIELD(root, var, gepValType);
|
|
328
328
|
return root;
|
|
329
329
|
}
|
|
@@ -331,7 +331,7 @@ cJSON* SVFIRWriter::contentToJson(const GepValVar* var)
|
|
|
331
331
|
cJSON* SVFIRWriter::contentToJson(const GepObjVar* var)
|
|
332
332
|
{
|
|
333
333
|
cJSON* root = contentToJson(static_cast<const ObjVar*>(var));
|
|
334
|
-
JSON_WRITE_FIELD(root, var,
|
|
334
|
+
JSON_WRITE_FIELD(root, var, apOffset);
|
|
335
335
|
JSON_WRITE_FIELD(root, var, base);
|
|
336
336
|
return root;
|
|
337
337
|
}
|
|
@@ -701,7 +701,7 @@ cJSON* SVFIRWriter::contentToJson(const LoadStmt* edge)
|
|
|
701
701
|
cJSON* SVFIRWriter::contentToJson(const GepStmt* edge)
|
|
702
702
|
{
|
|
703
703
|
cJSON* root = contentToJson(static_cast<const AssignStmt*>(edge));
|
|
704
|
-
JSON_WRITE_FIELD(root, edge,
|
|
704
|
+
JSON_WRITE_FIELD(root, edge, ap);
|
|
705
705
|
JSON_WRITE_FIELD(root, edge, variantField);
|
|
706
706
|
return root;
|
|
707
707
|
}
|
|
@@ -1240,11 +1240,11 @@ cJSON* SVFIRWriter::toJson(const StInfo* stInfo)
|
|
|
1240
1240
|
return jsonCreateIndex(svfModuleWriter.getStInfoID(stInfo));
|
|
1241
1241
|
}
|
|
1242
1242
|
|
|
1243
|
-
cJSON* SVFIRWriter::toJson(const
|
|
1243
|
+
cJSON* SVFIRWriter::toJson(const AccessPath& ap)
|
|
1244
1244
|
{
|
|
1245
1245
|
cJSON* root = jsonCreateObject();
|
|
1246
|
-
JSON_WRITE_FIELD(root, &
|
|
1247
|
-
JSON_WRITE_FIELD(root, &
|
|
1246
|
+
JSON_WRITE_FIELD(root, &ap, fldIdx);
|
|
1247
|
+
JSON_WRITE_FIELD(root, &ap, offsetVarAndGepTypePairs);
|
|
1248
1248
|
return root;
|
|
1249
1249
|
}
|
|
1250
1250
|
|
|
@@ -1844,13 +1844,13 @@ void SVFIRReader::readJson(const cJSON* obj, CallSite& cs)
|
|
|
1844
1844
|
readJson(obj, cs.CB);
|
|
1845
1845
|
}
|
|
1846
1846
|
|
|
1847
|
-
void SVFIRReader::readJson(const cJSON* obj,
|
|
1847
|
+
void SVFIRReader::readJson(const cJSON* obj, AccessPath& ap)
|
|
1848
1848
|
{
|
|
1849
|
-
ABORT_IFNOT(jsonIsObject(obj), "Expected obj for
|
|
1849
|
+
ABORT_IFNOT(jsonIsObject(obj), "Expected obj for AccessPath");
|
|
1850
1850
|
obj = obj->child;
|
|
1851
|
-
JSON_READ_FIELD_FWD(obj, &
|
|
1852
|
-
JSON_READ_FIELD_FWD(obj, &
|
|
1853
|
-
ABORT_IFNOT(!obj, "Extra field " << JSON_KEY(obj) << " in
|
|
1851
|
+
JSON_READ_FIELD_FWD(obj, &ap, fldIdx);
|
|
1852
|
+
JSON_READ_FIELD_FWD(obj, &ap, offsetVarAndGepTypePairs);
|
|
1853
|
+
ABORT_IFNOT(!obj, "Extra field " << JSON_KEY(obj) << " in AccessPath");
|
|
1854
1854
|
}
|
|
1855
1855
|
|
|
1856
1856
|
void SVFIRReader::readJson(const cJSON* obj, SVFLoop*& loop)
|
|
@@ -1948,14 +1948,14 @@ void SVFIRReader::fill(const cJSON*& fieldJson, ObjVar* var)
|
|
|
1948
1948
|
void SVFIRReader::fill(const cJSON*& fieldJson, GepValVar* var)
|
|
1949
1949
|
{
|
|
1950
1950
|
fill(fieldJson, static_cast<ValVar*>(var));
|
|
1951
|
-
JSON_READ_FIELD_FWD(fieldJson, var,
|
|
1951
|
+
JSON_READ_FIELD_FWD(fieldJson, var, ap);
|
|
1952
1952
|
JSON_READ_FIELD_FWD(fieldJson, var, gepValType);
|
|
1953
1953
|
}
|
|
1954
1954
|
|
|
1955
1955
|
void SVFIRReader::fill(const cJSON*& fieldJson, GepObjVar* var)
|
|
1956
1956
|
{
|
|
1957
1957
|
fill(fieldJson, static_cast<ObjVar*>(var));
|
|
1958
|
-
JSON_READ_FIELD_FWD(fieldJson, var,
|
|
1958
|
+
JSON_READ_FIELD_FWD(fieldJson, var, apOffset);
|
|
1959
1959
|
JSON_READ_FIELD_FWD(fieldJson, var, base);
|
|
1960
1960
|
}
|
|
1961
1961
|
|
|
@@ -2053,7 +2053,7 @@ void SVFIRReader::fill(const cJSON*& fieldJson, LoadStmt* stmt)
|
|
|
2053
2053
|
void SVFIRReader::fill(const cJSON*& fieldJson, GepStmt* stmt)
|
|
2054
2054
|
{
|
|
2055
2055
|
fill(fieldJson, static_cast<AssignStmt*>(stmt));
|
|
2056
|
-
JSON_READ_FIELD_FWD(fieldJson, stmt,
|
|
2056
|
+
JSON_READ_FIELD_FWD(fieldJson, stmt, ap);
|
|
2057
2057
|
JSON_READ_FIELD_FWD(fieldJson, stmt, variantField);
|
|
2058
2058
|
}
|
|
2059
2059
|
|
package/svf/lib/SVFIR/SVFIR.cpp
CHANGED
|
@@ -324,7 +324,7 @@ TDJoinPE* SVFIR::addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode* cs,
|
|
|
324
324
|
* Find the base node id of src and connect base node to dst node
|
|
325
325
|
* Create gep offset: (offset + baseOff <nested struct gep size>)
|
|
326
326
|
*/
|
|
327
|
-
GepStmt* SVFIR::addGepStmt(NodeID src, NodeID dst, const
|
|
327
|
+
GepStmt* SVFIR::addGepStmt(NodeID src, NodeID dst, const AccessPath& ap, bool constGep)
|
|
328
328
|
{
|
|
329
329
|
|
|
330
330
|
SVFVar* node = getGNode(src);
|
|
@@ -332,18 +332,18 @@ GepStmt* SVFIR::addGepStmt(NodeID src, NodeID dst, const LocationSet& ls, bool c
|
|
|
332
332
|
{
|
|
333
333
|
/// Since the offset from base to src is variant,
|
|
334
334
|
/// the new gep edge being created is also a Variant GepStmt edge.
|
|
335
|
-
return addVariantGepStmt(src, dst,
|
|
335
|
+
return addVariantGepStmt(src, dst, ap);
|
|
336
336
|
}
|
|
337
337
|
else
|
|
338
338
|
{
|
|
339
|
-
return addNormalGepStmt(src, dst,
|
|
339
|
+
return addNormalGepStmt(src, dst, ap);
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
/*!
|
|
344
344
|
* Add normal (Gep) edge
|
|
345
345
|
*/
|
|
346
|
-
GepStmt* SVFIR::addNormalGepStmt(NodeID src, NodeID dst, const
|
|
346
|
+
GepStmt* SVFIR::addNormalGepStmt(NodeID src, NodeID dst, const AccessPath& ap)
|
|
347
347
|
{
|
|
348
348
|
SVFVar* baseNode = getGNode(src);
|
|
349
349
|
SVFVar* dstNode = getGNode(dst);
|
|
@@ -351,7 +351,7 @@ GepStmt* SVFIR::addNormalGepStmt(NodeID src, NodeID dst, const LocationSet& ls)
|
|
|
351
351
|
return nullptr;
|
|
352
352
|
else
|
|
353
353
|
{
|
|
354
|
-
GepStmt* gepPE = new GepStmt(baseNode, dstNode,
|
|
354
|
+
GepStmt* gepPE = new GepStmt(baseNode, dstNode, ap);
|
|
355
355
|
addToStmt2TypeMap(gepPE);
|
|
356
356
|
addEdge(baseNode, dstNode, gepPE);
|
|
357
357
|
return gepPE;
|
|
@@ -362,7 +362,7 @@ GepStmt* SVFIR::addNormalGepStmt(NodeID src, NodeID dst, const LocationSet& ls)
|
|
|
362
362
|
* Add variant(Gep) edge
|
|
363
363
|
* Find the base node id of src and connect base node to dst node
|
|
364
364
|
*/
|
|
365
|
-
GepStmt* SVFIR::addVariantGepStmt(NodeID src, NodeID dst, const
|
|
365
|
+
GepStmt* SVFIR::addVariantGepStmt(NodeID src, NodeID dst, const AccessPath& ap)
|
|
366
366
|
{
|
|
367
367
|
SVFVar* baseNode = getGNode(src);
|
|
368
368
|
SVFVar* dstNode = getGNode(dst);
|
|
@@ -370,7 +370,7 @@ GepStmt* SVFIR::addVariantGepStmt(NodeID src, NodeID dst, const LocationSet& ls)
|
|
|
370
370
|
return nullptr;
|
|
371
371
|
else
|
|
372
372
|
{
|
|
373
|
-
GepStmt* gepPE = new GepStmt(baseNode, dstNode,
|
|
373
|
+
GepStmt* gepPE = new GepStmt(baseNode, dstNode, ap, true);
|
|
374
374
|
addToStmt2TypeMap(gepPE);
|
|
375
375
|
addEdge(baseNode, dstNode, gepPE);
|
|
376
376
|
return gepPE;
|
|
@@ -383,29 +383,29 @@ GepStmt* SVFIR::addVariantGepStmt(NodeID src, NodeID dst, const LocationSet& ls)
|
|
|
383
383
|
* Add a temp field value node, this method can only invoked by getGepValVar
|
|
384
384
|
* due to constaint expression, curInst is used to distinguish different instructions (e.g., memorycpy) when creating GepValVar.
|
|
385
385
|
*/
|
|
386
|
-
NodeID SVFIR::addGepValNode(const SVFValue* curInst,const SVFValue* gepVal, const
|
|
386
|
+
NodeID SVFIR::addGepValNode(const SVFValue* curInst,const SVFValue* gepVal, const AccessPath& ap, NodeID i, const SVFType* type)
|
|
387
387
|
{
|
|
388
388
|
NodeID base = getBaseValVar(getValueNode(gepVal));
|
|
389
389
|
//assert(findPAGNode(i) == false && "this node should not be created before");
|
|
390
|
-
assert(0==GepValObjMap[curInst].count(std::make_pair(base,
|
|
390
|
+
assert(0==GepValObjMap[curInst].count(std::make_pair(base, ap))
|
|
391
391
|
&& "this node should not be created before");
|
|
392
|
-
GepValObjMap[curInst][std::make_pair(base,
|
|
393
|
-
GepValVar *node = new GepValVar(gepVal, i,
|
|
392
|
+
GepValObjMap[curInst][std::make_pair(base, ap)] = i;
|
|
393
|
+
GepValVar *node = new GepValVar(gepVal, i, ap, type);
|
|
394
394
|
return addValNode(gepVal, node, i);
|
|
395
395
|
}
|
|
396
396
|
|
|
397
397
|
/*!
|
|
398
398
|
* Given an object node, find its field object node
|
|
399
399
|
*/
|
|
400
|
-
NodeID SVFIR::getGepObjVar(NodeID id, const
|
|
400
|
+
NodeID SVFIR::getGepObjVar(NodeID id, const APOffset& apOffset)
|
|
401
401
|
{
|
|
402
402
|
SVFVar* node = pag->getGNode(id);
|
|
403
403
|
if (GepObjVar* gepNode = SVFUtil::dyn_cast<GepObjVar>(node))
|
|
404
|
-
return getGepObjVar(gepNode->getMemObj(), gepNode->
|
|
404
|
+
return getGepObjVar(gepNode->getMemObj(), gepNode->getConstantFieldIdx() + apOffset);
|
|
405
405
|
else if (FIObjVar* baseNode = SVFUtil::dyn_cast<FIObjVar>(node))
|
|
406
|
-
return getGepObjVar(baseNode->getMemObj(),
|
|
406
|
+
return getGepObjVar(baseNode->getMemObj(), apOffset);
|
|
407
407
|
else if (DummyObjVar* baseNode = SVFUtil::dyn_cast<DummyObjVar>(node))
|
|
408
|
-
return getGepObjVar(baseNode->getMemObj(),
|
|
408
|
+
return getGepObjVar(baseNode->getMemObj(), apOffset);
|
|
409
409
|
else
|
|
410
410
|
{
|
|
411
411
|
assert(false && "new gep obj node kind?");
|
|
@@ -419,7 +419,7 @@ NodeID SVFIR::getGepObjVar(NodeID id, const LocationSet& ls)
|
|
|
419
419
|
* offset = offset % obj->getMaxFieldOffsetLimit() to create limited number of mem objects
|
|
420
420
|
* maximum number of field object creation is obj->getMaxFieldOffsetLimit()
|
|
421
421
|
*/
|
|
422
|
-
NodeID SVFIR::getGepObjVar(const MemObj* obj, const
|
|
422
|
+
NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset)
|
|
423
423
|
{
|
|
424
424
|
NodeID base = obj->getId();
|
|
425
425
|
|
|
@@ -427,12 +427,12 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const LocationSet& ls)
|
|
|
427
427
|
if (obj->isFieldInsensitive())
|
|
428
428
|
return getFIObjVar(obj);
|
|
429
429
|
|
|
430
|
-
|
|
430
|
+
APOffset newLS = pag->getSymbolInfo()->getModulusOffset(obj, apOffset);
|
|
431
431
|
|
|
432
432
|
// Base and first field are the same memory location.
|
|
433
|
-
if (Options::FirstFieldEqBase() && newLS
|
|
433
|
+
if (Options::FirstFieldEqBase() && newLS == 0) return base;
|
|
434
434
|
|
|
435
|
-
|
|
435
|
+
NodeOffsetMap::iterator iter = GepObjVarMap.find(std::make_pair(base, newLS));
|
|
436
436
|
if (iter == GepObjVarMap.end())
|
|
437
437
|
return addGepObjNode(obj, newLS);
|
|
438
438
|
else
|
|
@@ -443,16 +443,16 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const LocationSet& ls)
|
|
|
443
443
|
/*!
|
|
444
444
|
* Add a field obj node, this method can only invoked by getGepObjVar
|
|
445
445
|
*/
|
|
446
|
-
NodeID SVFIR::addGepObjNode(const MemObj* obj, const
|
|
446
|
+
NodeID SVFIR::addGepObjNode(const MemObj* obj, const APOffset& apOffset)
|
|
447
447
|
{
|
|
448
448
|
//assert(findPAGNode(i) == false && "this node should not be created before");
|
|
449
449
|
NodeID base = obj->getId();
|
|
450
|
-
assert(0==GepObjVarMap.count(std::make_pair(base,
|
|
450
|
+
assert(0==GepObjVarMap.count(std::make_pair(base, apOffset))
|
|
451
451
|
&& "this node should not be created before");
|
|
452
452
|
|
|
453
|
-
NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base,
|
|
454
|
-
GepObjVarMap[std::make_pair(base,
|
|
455
|
-
GepObjVar *node = new GepObjVar(obj, gepId,
|
|
453
|
+
NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, apOffset, Options::MaxFieldLimit());
|
|
454
|
+
GepObjVarMap[std::make_pair(base, apOffset)] = gepId;
|
|
455
|
+
GepObjVar *node = new GepObjVar(obj, gepId, apOffset);
|
|
456
456
|
memToFieldsMap[base].set(gepId);
|
|
457
457
|
return addObjNode(obj->getValue(), node, gepId);
|
|
458
458
|
}
|
|
@@ -535,7 +535,7 @@ NodeID SVFIR::getBaseValVar(NodeID nodeId)
|
|
|
535
535
|
/*!
|
|
536
536
|
* It is used to create a dummy GepValVar during global initiailzation.
|
|
537
537
|
*/
|
|
538
|
-
NodeID SVFIR::getGepValVar(const SVFValue* curInst, NodeID base, const
|
|
538
|
+
NodeID SVFIR::getGepValVar(const SVFValue* curInst, NodeID base, const AccessPath& ap) const
|
|
539
539
|
{
|
|
540
540
|
GepValueVarMap::const_iterator iter = GepValObjMap.find(curInst);
|
|
541
541
|
if(iter==GepValObjMap.end())
|
|
@@ -544,8 +544,9 @@ NodeID SVFIR::getGepValVar(const SVFValue* curInst, NodeID base, const LocationS
|
|
|
544
544
|
}
|
|
545
545
|
else
|
|
546
546
|
{
|
|
547
|
-
|
|
548
|
-
|
|
547
|
+
NodeAccessPathMap::const_iterator lit =
|
|
548
|
+
iter->second.find(std::make_pair(base, ap));
|
|
549
|
+
if (lit == iter->second.end())
|
|
549
550
|
return UINT_MAX;
|
|
550
551
|
else
|
|
551
552
|
return lit->second;
|
|
@@ -679,7 +680,7 @@ bool SVFIR::isNonPointerObj(NodeID id) const
|
|
|
679
680
|
}
|
|
680
681
|
else if (const GepObjVar* gepNode = SVFUtil::dyn_cast<GepObjVar>(node))
|
|
681
682
|
{
|
|
682
|
-
return (gepNode->getMemObj()->isNonPtrFieldObj(gepNode->
|
|
683
|
+
return (gepNode->getMemObj()->isNonPtrFieldObj(gepNode->getConstantFieldIdx()));
|
|
683
684
|
}
|
|
684
685
|
else if (const DummyObjVar* dummyNode = SVFUtil::dyn_cast<DummyObjVar>(node))
|
|
685
686
|
{
|
|
@@ -145,7 +145,7 @@ const std::string GepObjVar::toString() const
|
|
|
145
145
|
{
|
|
146
146
|
std::string str;
|
|
147
147
|
std::stringstream rawstr(str);
|
|
148
|
-
rawstr << "GepObjVar ID: " << getId() << " with offset_" + std::to_string(
|
|
148
|
+
rawstr << "GepObjVar ID: " << getId() << " with offset_" + std::to_string(apOffset);
|
|
149
149
|
if (Options::ShowSVFIRValue())
|
|
150
150
|
{
|
|
151
151
|
rawstr << "\n";
|
|
@@ -91,14 +91,14 @@ SymbolTableInfo* SymbolTableInfo::SymbolInfo()
|
|
|
91
91
|
/*!
|
|
92
92
|
* Get modulus offset given the type information
|
|
93
93
|
*/
|
|
94
|
-
|
|
94
|
+
APOffset SymbolTableInfo::getModulusOffset(const MemObj* obj, const APOffset& apOffset)
|
|
95
95
|
{
|
|
96
96
|
|
|
97
97
|
/// if the offset is negative, it's possible that we're looking for an obj node out of range
|
|
98
98
|
/// of current struct. Make the offset positive so we can still get a node within current
|
|
99
99
|
/// struct to represent this obj.
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
APOffset offset = apOffset;
|
|
102
102
|
if(offset < 0)
|
|
103
103
|
{
|
|
104
104
|
writeWrnMsg("try to create a gep node with negative offset.");
|
|
@@ -132,7 +132,7 @@ LocationSet SymbolTableInfo::getModulusOffset(const MemObj* obj, const LocationS
|
|
|
132
132
|
offset = maxOffset - 1;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
return
|
|
135
|
+
return offset;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
|
|
@@ -368,7 +368,7 @@ void SymbolTableInfo::dump()
|
|
|
368
368
|
/*!
|
|
369
369
|
* Whether a location set is a pointer type or not
|
|
370
370
|
*/
|
|
371
|
-
bool ObjTypeInfo::isNonPtrFieldObj(const
|
|
371
|
+
bool ObjTypeInfo::isNonPtrFieldObj(const APOffset& apOffset)
|
|
372
372
|
{
|
|
373
373
|
if (hasPtrObj() == false)
|
|
374
374
|
return true;
|
|
@@ -383,13 +383,13 @@ bool ObjTypeInfo::isNonPtrFieldObj(const LocationSet& ls)
|
|
|
383
383
|
else
|
|
384
384
|
sz = SymbolTableInfo::SymbolInfo()->getTypeInfo(ety)->getFlattenFieldTypes().size();
|
|
385
385
|
|
|
386
|
-
if(sz <= (u32_t)
|
|
386
|
+
if(sz <= (u32_t) apOffset)
|
|
387
387
|
{
|
|
388
388
|
writeWrnMsg("out of bound error when accessing the struct/array");
|
|
389
389
|
return false;
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
-
const SVFType* elemTy = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(ety,
|
|
392
|
+
const SVFType* elemTy = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(ety, apOffset);
|
|
393
393
|
return (elemTy->isPointerTy() == false);
|
|
394
394
|
}
|
|
395
395
|
else
|
|
@@ -537,9 +537,9 @@ bool MemObj::hasPtrObj() const
|
|
|
537
537
|
return typeInfo->hasPtrObj();
|
|
538
538
|
}
|
|
539
539
|
|
|
540
|
-
bool MemObj::isNonPtrFieldObj(const
|
|
540
|
+
bool MemObj::isNonPtrFieldObj(const APOffset& apOffset) const
|
|
541
541
|
{
|
|
542
|
-
return typeInfo->isNonPtrFieldObj(
|
|
542
|
+
return typeInfo->isNonPtrFieldObj(apOffset);
|
|
543
543
|
}
|
|
544
544
|
|
|
545
545
|
const std::string MemObj::toString() const
|
package/svf/lib/Util/Options.cpp
CHANGED
|
@@ -253,7 +253,7 @@ const Option<bool> Options::DumpVFG(
|
|
|
253
253
|
);
|
|
254
254
|
|
|
255
255
|
|
|
256
|
-
// Location set for modeling abstract memory object (
|
|
256
|
+
// Location set for modeling abstract memory object (AccessPath.cpp)
|
|
257
257
|
const Option<bool> Options::SingleStride(
|
|
258
258
|
"stride-only",
|
|
259
259
|
"Only use single stride in LocMemoryModel",
|
package/svf/lib/Util/Z3Expr.cpp
CHANGED
|
@@ -105,7 +105,7 @@ Z3Expr Z3Expr::AND(const Z3Expr &lhs, const Z3Expr &rhs)
|
|
|
105
105
|
}
|
|
106
106
|
else
|
|
107
107
|
{
|
|
108
|
-
Z3Expr expr = lhs && rhs;
|
|
108
|
+
Z3Expr expr = (lhs && rhs).simplify();
|
|
109
109
|
// check subexpression size and option limit
|
|
110
110
|
if (Z3Expr::getExprSize(expr) > Options::MaxZ3Size())
|
|
111
111
|
{
|
|
@@ -143,7 +143,7 @@ Z3Expr Z3Expr::OR(const Z3Expr &lhs, const Z3Expr &rhs)
|
|
|
143
143
|
}
|
|
144
144
|
else
|
|
145
145
|
{
|
|
146
|
-
Z3Expr expr = lhs || rhs;
|
|
146
|
+
Z3Expr expr = (lhs || rhs).simplify();
|
|
147
147
|
// check subexpression size and option limit
|
|
148
148
|
if (Z3Expr::getExprSize(expr) > Options::MaxZ3Size())
|
|
149
149
|
{
|
package/svf/lib/WPA/Andersen.cpp
CHANGED
|
@@ -170,7 +170,7 @@ void AndersenBase::cleanConsCG(NodeID id)
|
|
|
170
170
|
void AndersenBase::normalizePointsTo()
|
|
171
171
|
{
|
|
172
172
|
SVFIR::MemObjToFieldsMap &memToFieldsMap = pag->getMemToFieldsMap();
|
|
173
|
-
SVFIR::
|
|
173
|
+
SVFIR::NodeOffsetMap &GepObjVarMap = pag->getGepObjNodeMap();
|
|
174
174
|
|
|
175
175
|
// clear GepObjVarMap/memToFieldsMap/nodeToSubsMap/nodeToRepMap
|
|
176
176
|
// for redundant gepnodes and remove those nodes from pag
|
|
@@ -179,8 +179,8 @@ void AndersenBase::normalizePointsTo()
|
|
|
179
179
|
NodeID base = pag->getBaseObjVar(n);
|
|
180
180
|
GepObjVar *gepNode = SVFUtil::dyn_cast<GepObjVar>(pag->getGNode(n));
|
|
181
181
|
assert(gepNode && "Not a gep node in redundantGepNodes set");
|
|
182
|
-
const
|
|
183
|
-
GepObjVarMap.erase(std::make_pair(base,
|
|
182
|
+
const APOffset apOffset = gepNode->getConstantFieldIdx();
|
|
183
|
+
GepObjVarMap.erase(std::make_pair(base, apOffset));
|
|
184
184
|
memToFieldsMap[base].reset(n);
|
|
185
185
|
cleanConsCG(n);
|
|
186
186
|
|
|
@@ -437,7 +437,7 @@ bool Andersen::processGepPts(const PointsTo& pts, const GepCGEdge* edge)
|
|
|
437
437
|
continue;
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
-
NodeID fieldSrcPtdNode = consCG->getGepObjVar(o, normalGepEdge->
|
|
440
|
+
NodeID fieldSrcPtdNode = consCG->getGepObjVar(o, normalGepEdge->getAccessPath().getConstantFieldIdx());
|
|
441
441
|
tmpDstPts.set(fieldSrcPtdNode);
|
|
442
442
|
}
|
|
443
443
|
}
|