svf-tools 1.0.732 → 1.0.734
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 +2 -2
- package/svf/include/Graphs/ConsGEdge.h +4 -4
- package/svf/include/MemoryModel/{LocationSet.h → AccessPath.h} +22 -22
- package/svf/include/MemoryModel/PointerAnalysis.h +1 -1
- package/svf/include/SVFIR/PAGBuilderFromFile.h +1 -1
- package/svf/include/SVFIR/SVFFileSystem.h +3 -3
- package/svf/include/SVFIR/SVFIR.h +15 -15
- package/svf/include/SVFIR/SVFStatements.h +12 -12
- package/svf/include/SVFIR/SVFType.h +1 -0
- package/svf/include/SVFIR/SVFVariables.h +9 -15
- package/svf/include/SVFIR/SymbolTableInfo.h +4 -4
- package/svf/include/Util/ExtAPI.h +1 -1
- package/svf/include/Util/ExtAPI.json +8 -8
- package/svf/include/Util/Options.h +1 -1
- 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 +4 -4
- package/svf/lib/MemoryModel/{LocationSet.cpp → AccessPath.cpp} +16 -16
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +3 -3
- package/svf/lib/SVFIR/PAGBuilderFromFile.cpp +4 -4
- package/svf/lib/SVFIR/SVFFileSystem.cpp +4 -4
- package/svf/lib/SVFIR/SVFIR.cpp +15 -15
- package/svf/lib/SVFIR/SVFVariables.cpp +1 -1
- package/svf/lib/SVFIR/SymbolTableInfo.cpp +7 -7
- package/svf/lib/Util/ExtAPI.cpp +12 -7
- package/svf/lib/Util/Options.cpp +1 -1
- package/svf/lib/WPA/Andersen.cpp +3 -3
- package/svf/lib/WPA/AndersenSFR.cpp +7 -7
- package/svf/lib/WPA/FlowSensitive.cpp +1 -1
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +8 -8
- package/svf-llvm/lib/SVFIRBuilder.cpp +16 -16
- package/svf-llvm/lib/SVFIRExtAPI.cpp +10 -11
|
@@ -152,7 +152,7 @@ void SVFIR2ItvExeState::narrowVAddrs(IntervalExeState &lhs, const IntervalExeSta
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
SVFIR2ItvExeState::VAddrs SVFIR2ItvExeState::getGepObjAddress(u32_t pointer,
|
|
155
|
+
SVFIR2ItvExeState::VAddrs SVFIR2ItvExeState::getGepObjAddress(u32_t pointer, s32_t offset)
|
|
156
156
|
{
|
|
157
157
|
assert(!getVAddrs(pointer).empty());
|
|
158
158
|
VAddrs &addrs = getVAddrs(pointer);
|
|
@@ -242,8 +242,8 @@ std::pair<s32_t, s32_t> SVFIR2ItvExeState::getGepOffset(const GepStmt *gep)
|
|
|
242
242
|
|
|
243
243
|
if (const SVFPointerType *pty = SVFUtil::dyn_cast<SVFPointerType>(type))
|
|
244
244
|
{
|
|
245
|
-
offsetLb = offsetLb * gep->
|
|
246
|
-
offsetUb = offsetUb * gep->
|
|
245
|
+
offsetLb = offsetLb * gep->getAccessPath().getElementNum(pty->getPtrElementType());
|
|
246
|
+
offsetUb = offsetUb * gep->getAccessPath().getElementNum(pty->getPtrElementType());
|
|
247
247
|
|
|
248
248
|
}
|
|
249
249
|
else
|
|
@@ -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,7 +210,7 @@ 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& ls)
|
|
214
214
|
{
|
|
215
215
|
ConstraintNode* srcNode = getConstraintNode(src);
|
|
216
216
|
ConstraintNode* dstNode = getConstraintNode(dst);
|
|
@@ -320,7 +320,7 @@ void ConstraintGraph::reTargetDstOfEdge(ConstraintEdge* edge, ConstraintNode* ne
|
|
|
320
320
|
}
|
|
321
321
|
else if(NormalGepCGEdge* gep = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
|
|
322
322
|
{
|
|
323
|
-
const
|
|
323
|
+
const AccessPath ls = gep->getAccessPath();
|
|
324
324
|
removeDirectEdge(gep);
|
|
325
325
|
addNormalGepCGEdge(srcId,newDstNodeID,ls);
|
|
326
326
|
}
|
|
@@ -364,7 +364,7 @@ void ConstraintGraph::reTargetSrcOfEdge(ConstraintEdge* edge, ConstraintNode* ne
|
|
|
364
364
|
}
|
|
365
365
|
else if(NormalGepCGEdge* gep = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
|
|
366
366
|
{
|
|
367
|
-
const
|
|
367
|
+
const AccessPath ls = gep->getAccessPath();
|
|
368
368
|
removeDirectEdge(gep);
|
|
369
369
|
addNormalGepCGEdge(newSrcNodeID,dstId,ls);
|
|
370
370
|
}
|
|
@@ -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,16 +150,16 @@ 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
|
-
|
|
162
|
+
AccessPath ls(rhs);
|
|
163
163
|
ls.fldIdx += getConstantFieldIdx();
|
|
164
164
|
OffsetVarAndGepTypePairs::const_iterator it = getOffsetVarAndGepTypePairVec().begin();
|
|
165
165
|
OffsetVarAndGepTypePairs::const_iterator eit = getOffsetVarAndGepTypePairVec().end();
|
|
@@ -170,7 +170,7 @@ LocationSet LocationSet::operator+ (const LocationSet& rhs) const
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
|
|
173
|
-
bool
|
|
173
|
+
bool AccessPath::operator< (const AccessPath& rhs) const
|
|
174
174
|
{
|
|
175
175
|
if (fldIdx != rhs.fldIdx)
|
|
176
176
|
return (fldIdx < rhs.fldIdx);
|
|
@@ -194,7 +194,7 @@ bool LocationSet::operator< (const LocationSet& rhs) const
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
SVF::
|
|
197
|
+
SVF::AccessPath::LSRelation AccessPath::checkRelation(const AccessPath& LHS, const AccessPath& RHS)
|
|
198
198
|
{
|
|
199
199
|
NodeBS lhsLocations = LHS.computeAllLocations();
|
|
200
200
|
NodeBS rhsLocations = RHS.computeAllLocations();
|
|
@@ -216,12 +216,12 @@ SVF::LocationSet::LSRelation LocationSet::checkRelation(const LocationSet& LHS,
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
/// Dump location set
|
|
219
|
-
std::string
|
|
219
|
+
std::string AccessPath::dump() const
|
|
220
220
|
{
|
|
221
221
|
std::string str;
|
|
222
222
|
std::stringstream rawstr(str);
|
|
223
223
|
|
|
224
|
-
rawstr << "
|
|
224
|
+
rawstr << "AccessPath\tField_Index: " << getConstantFieldIdx();
|
|
225
225
|
rawstr << ",\tNum-Stride: {";
|
|
226
226
|
const OffsetVarAndGepTypePairs& vec = getOffsetVarAndGepTypePairVec();
|
|
227
227
|
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,7 +525,7 @@ 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
|
|
528
|
+
const APOffset ls = gepNode->getConstantFieldIdx();
|
|
529
529
|
GepObjVarMap.erase(std::make_pair(base, ls));
|
|
530
530
|
memToFieldsMap[base].reset(n);
|
|
531
531
|
|
|
@@ -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")
|
|
@@ -1240,7 +1240,7 @@ 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& ls)
|
|
1244
1244
|
{
|
|
1245
1245
|
cJSON* root = jsonCreateObject();
|
|
1246
1246
|
JSON_WRITE_FIELD(root, &ls, fldIdx);
|
|
@@ -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& ls)
|
|
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
1851
|
JSON_READ_FIELD_FWD(obj, &ls, fldIdx);
|
|
1852
1852
|
JSON_READ_FIELD_FWD(obj, &ls, offsetVarAndGepTypePairs);
|
|
1853
|
-
ABORT_IFNOT(!obj, "Extra field " << JSON_KEY(obj) << " in
|
|
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)
|
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& ls, bool constGep)
|
|
328
328
|
{
|
|
329
329
|
|
|
330
330
|
SVFVar* node = getGNode(src);
|
|
@@ -343,7 +343,7 @@ GepStmt* SVFIR::addGepStmt(NodeID src, NodeID dst, const LocationSet& ls, bool c
|
|
|
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& ls)
|
|
347
347
|
{
|
|
348
348
|
SVFVar* baseNode = getGNode(src);
|
|
349
349
|
SVFVar* dstNode = getGNode(dst);
|
|
@@ -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& ls)
|
|
366
366
|
{
|
|
367
367
|
SVFVar* baseNode = getGNode(src);
|
|
368
368
|
SVFVar* dstNode = getGNode(dst);
|
|
@@ -383,7 +383,7 @@ 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& ls, 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");
|
|
@@ -397,11 +397,11 @@ NodeID SVFIR::addGepValNode(const SVFValue* curInst,const SVFValue* gepVal, cons
|
|
|
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& ls)
|
|
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() + ls);
|
|
405
405
|
else if (FIObjVar* baseNode = SVFUtil::dyn_cast<FIObjVar>(node))
|
|
406
406
|
return getGepObjVar(baseNode->getMemObj(), ls);
|
|
407
407
|
else if (DummyObjVar* baseNode = SVFUtil::dyn_cast<DummyObjVar>(node))
|
|
@@ -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& ls)
|
|
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,ls);
|
|
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,14 +443,14 @@ 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& ls)
|
|
447
447
|
{
|
|
448
448
|
//assert(findPAGNode(i) == false && "this node should not be created before");
|
|
449
449
|
NodeID base = obj->getId();
|
|
450
450
|
assert(0==GepObjVarMap.count(std::make_pair(base, ls))
|
|
451
451
|
&& "this node should not be created before");
|
|
452
452
|
|
|
453
|
-
NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, ls
|
|
453
|
+
NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, ls, Options::MaxFieldLimit());
|
|
454
454
|
GepObjVarMap[std::make_pair(base, ls)] = gepId;
|
|
455
455
|
GepObjVar *node = new GepObjVar(obj, gepId, ls);
|
|
456
456
|
memToFieldsMap[base].set(gepId);
|
|
@@ -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& ls) const
|
|
539
539
|
{
|
|
540
540
|
GepValueVarMap::const_iterator iter = GepValObjMap.find(curInst);
|
|
541
541
|
if(iter==GepValObjMap.end())
|
|
@@ -544,7 +544,7 @@ NodeID SVFIR::getGepValVar(const SVFValue* curInst, NodeID base, const LocationS
|
|
|
544
544
|
}
|
|
545
545
|
else
|
|
546
546
|
{
|
|
547
|
-
|
|
547
|
+
NodeAccessPathMap::const_iterator lit = iter->second.find(std::make_pair(base, ls));
|
|
548
548
|
if(lit==iter->second.end())
|
|
549
549
|
return UINT_MAX;
|
|
550
550
|
else
|
|
@@ -679,7 +679,7 @@ bool SVFIR::isNonPointerObj(NodeID id) const
|
|
|
679
679
|
}
|
|
680
680
|
else if (const GepObjVar* gepNode = SVFUtil::dyn_cast<GepObjVar>(node))
|
|
681
681
|
{
|
|
682
|
-
return (gepNode->getMemObj()->isNonPtrFieldObj(gepNode->
|
|
682
|
+
return (gepNode->getMemObj()->isNonPtrFieldObj(gepNode->getConstantFieldIdx()));
|
|
683
683
|
}
|
|
684
684
|
else if (const DummyObjVar* dummyNode = SVFUtil::dyn_cast<DummyObjVar>(node))
|
|
685
685
|
{
|
|
@@ -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(ls
|
|
148
|
+
rawstr << "GepObjVar ID: " << getId() << " with offset_" + std::to_string(ls);
|
|
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& ls)
|
|
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 = ls;
|
|
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& ls)
|
|
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) ls
|
|
386
|
+
if(sz <= (u32_t) ls)
|
|
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, ls
|
|
392
|
+
const SVFType* elemTy = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(ety, ls);
|
|
393
393
|
return (elemTy->isPointerTy() == false);
|
|
394
394
|
}
|
|
395
395
|
else
|
|
@@ -537,7 +537,7 @@ bool MemObj::hasPtrObj() const
|
|
|
537
537
|
return typeInfo->hasPtrObj();
|
|
538
538
|
}
|
|
539
539
|
|
|
540
|
-
bool MemObj::isNonPtrFieldObj(const
|
|
540
|
+
bool MemObj::isNonPtrFieldObj(const APOffset& ls) const
|
|
541
541
|
{
|
|
542
542
|
return typeInfo->isNonPtrFieldObj(ls);
|
|
543
543
|
}
|
package/svf/lib/Util/ExtAPI.cpp
CHANGED
|
@@ -389,15 +389,19 @@ ExtAPI::Operand ExtAPI::getBasicOperation(cJSON* obj)
|
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
// Get all operations of an extern function
|
|
392
|
-
ExtAPI::ExtFunctionOps ExtAPI::getExtFunctionOps(
|
|
392
|
+
ExtAPI::ExtFunctionOps ExtAPI::getExtFunctionOps(const SVFFunction* extFunction)
|
|
393
393
|
{
|
|
394
|
-
|
|
394
|
+
ExtAPI::ExtFunctionOps extFunctionOps;
|
|
395
|
+
extFunctionOps.setExtFunName(extFunction->getName());
|
|
396
|
+
if (!is_sameSignature(extFunction))
|
|
397
|
+
return extFunctionOps;
|
|
398
|
+
|
|
399
|
+
auto it = extFunToOps.find(extFunction->getName());
|
|
395
400
|
if (it != extFunToOps.end())
|
|
396
401
|
return it->second;
|
|
397
402
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
cJSON* item = get_FunJson(funName);
|
|
403
|
+
extFunctionOps.setExtFunName(extFunction->getName());
|
|
404
|
+
cJSON* item = get_FunJson(extFunction->getName());
|
|
401
405
|
if (item != nullptr)
|
|
402
406
|
{
|
|
403
407
|
cJSON* obj = item->child;
|
|
@@ -456,7 +460,7 @@ ExtAPI::ExtFunctionOps ExtAPI::getExtFunctionOps(std::string funName)
|
|
|
456
460
|
extFunctionOps.getOperations().push_back(operation);
|
|
457
461
|
}
|
|
458
462
|
}
|
|
459
|
-
extFunToOps[
|
|
463
|
+
extFunToOps[extFunction->getName()] = extFunctionOps;
|
|
460
464
|
return extFunctionOps;
|
|
461
465
|
}
|
|
462
466
|
|
|
@@ -649,7 +653,8 @@ bool ExtAPI::is_sameSignature(const SVFFunction* F)
|
|
|
649
653
|
argNum++;
|
|
650
654
|
}
|
|
651
655
|
}
|
|
652
|
-
|
|
656
|
+
|
|
657
|
+
if ( !F->isVarArg() && F->arg_size() != argNum) // The number of arguments is different
|
|
653
658
|
return false;
|
|
654
659
|
// Is the return type the same?
|
|
655
660
|
return F->getReturnType()->isPointerTy() == isPointer;
|
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/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,7 +179,7 @@ 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
|
|
182
|
+
const APOffset ls = gepNode->getConstantFieldIdx();
|
|
183
183
|
GepObjVarMap.erase(std::make_pair(base, ls));
|
|
184
184
|
memToFieldsMap[base].reset(n);
|
|
185
185
|
cleanConsCG(n);
|
|
@@ -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
|
}
|
|
@@ -97,7 +97,7 @@ bool AndersenSFR::processGepPts(const PointsTo& pts, const GepCGEdge* edge)
|
|
|
97
97
|
for (NodeID ptd : srcInits)
|
|
98
98
|
sortSrcInits.insert(ptd);
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
APOffset offset = SVFUtil::dyn_cast<NormalGepCGEdge>(edge)->getConstantFieldIdx();
|
|
101
101
|
fieldExpand(sortSrcInits, offset, dst->strides, tmpDstPts);
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -117,7 +117,7 @@ bool AndersenSFR::processGepPts(const PointsTo& pts, const GepCGEdge* edge)
|
|
|
117
117
|
/*!
|
|
118
118
|
* Expand field IDs in target pts based on the initials and offsets
|
|
119
119
|
*/
|
|
120
|
-
void AndersenSFR::fieldExpand(NodeSet& initials,
|
|
120
|
+
void AndersenSFR::fieldExpand(NodeSet& initials, APOffset offset, NodeBS& strides, PointsTo& expandPts)
|
|
121
121
|
{
|
|
122
122
|
numOfFieldExpand++;
|
|
123
123
|
|
|
@@ -133,7 +133,7 @@ void AndersenSFR::fieldExpand(NodeSet& initials, s32_t offset, NodeBS& strides,
|
|
|
133
133
|
PAGNode* initPN = pag->getGNode(init);
|
|
134
134
|
const MemObj* obj = pag->getBaseObj(init);
|
|
135
135
|
const u32_t maxLimit = obj->getMaxFieldOffsetLimit();
|
|
136
|
-
|
|
136
|
+
APOffset initOffset;
|
|
137
137
|
if (GepObjVar *gepNode = SVFUtil::dyn_cast<GepObjVar>(initPN))
|
|
138
138
|
initOffset = gepNode->getConstantFieldIdx();
|
|
139
139
|
else if (SVFUtil::isa<FIObjVar, DummyObjVar>(initPN))
|
|
@@ -144,7 +144,7 @@ void AndersenSFR::fieldExpand(NodeSet& initials, s32_t offset, NodeBS& strides,
|
|
|
144
144
|
abort();
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
Set<
|
|
147
|
+
Set<APOffset> offsets;
|
|
148
148
|
offsets.insert(offset);
|
|
149
149
|
|
|
150
150
|
// calculate offsets
|
|
@@ -155,7 +155,7 @@ void AndersenSFR::fieldExpand(NodeSet& initials, s32_t offset, NodeBS& strides,
|
|
|
155
155
|
for (auto _f : offsets)
|
|
156
156
|
for (auto _s : strides)
|
|
157
157
|
{
|
|
158
|
-
|
|
158
|
+
APOffset _f1 = _f + _s;
|
|
159
159
|
loopFlag = (offsets.find(_f1) == offsets.end()) && ( (u32_t)(initOffset + _f1) < maxLimit);
|
|
160
160
|
if (loopFlag)
|
|
161
161
|
offsets.insert(_f1);
|
|
@@ -163,9 +163,9 @@ void AndersenSFR::fieldExpand(NodeSet& initials, s32_t offset, NodeBS& strides,
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
// get gep objs
|
|
166
|
-
for (
|
|
166
|
+
for (APOffset _f : offsets)
|
|
167
167
|
{
|
|
168
|
-
NodeID gepId = consCG->getGepObjVar(init,
|
|
168
|
+
NodeID gepId = consCG->getGepObjVar(init, _f);
|
|
169
169
|
initials.erase(gepId); // gep id in initials should be removed to avoid redundant derivation
|
|
170
170
|
expandPts.set(gepId);
|
|
171
171
|
}
|
|
@@ -487,7 +487,7 @@ bool FlowSensitive::processGep(const GepSVFGNode* edge)
|
|
|
487
487
|
continue;
|
|
488
488
|
}
|
|
489
489
|
|
|
490
|
-
NodeID fieldSrcPtdNode = getGepObjVar(o, gepStmt->
|
|
490
|
+
NodeID fieldSrcPtdNode = getGepObjVar(o, gepStmt->getAccessPath().getConstantFieldIdx());
|
|
491
491
|
tmpDstPts.set(fieldSrcPtdNode);
|
|
492
492
|
}
|
|
493
493
|
}
|