svf-tools 1.0.734 → 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/Graphs/ConsG.h +4 -4
- package/svf/include/Graphs/ConsGEdge.h +8 -6
- package/svf/include/MemoryModel/AccessPath.h +6 -5
- package/svf/include/MemoryModel/PointerAnalysis.h +2 -2
- package/svf/include/SVFIR/SVFFileSystem.h +2 -2
- package/svf/include/SVFIR/SVFIR.h +9 -8
- package/svf/include/SVFIR/SVFStatements.h +4 -4
- package/svf/include/SVFIR/SVFVariables.h +11 -11
- package/svf/include/SVFIR/SymbolTableInfo.h +4 -3
- package/svf/include/Util/Z3Expr.h +2 -2
- package/svf/lib/Graphs/ConsG.cpp +7 -6
- package/svf/lib/MemoryModel/AccessPath.cpp +6 -9
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +2 -2
- package/svf/lib/SVFIR/SVFFileSystem.cpp +12 -12
- package/svf/lib/SVFIR/SVFIR.cpp +26 -25
- package/svf/lib/SVFIR/SVFVariables.cpp +1 -1
- package/svf/lib/SVFIR/SymbolTableInfo.cpp +7 -7
- package/svf/lib/Util/Z3Expr.cpp +2 -2
- package/svf/lib/WPA/Andersen.cpp +2 -2
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +15 -15
- package/svf-llvm/lib/SVFIRBuilder.cpp +20 -20
- package/svf-llvm/lib/SVFIRExtAPI.cpp +2 -2
- package/svf-llvm/tools/MTA/LockResultValidator.cpp +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.735",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -52,7 +52,7 @@ public:
|
|
|
52
52
|
typedef FIFOWorkList<NodeID> WorkList;
|
|
53
53
|
|
|
54
54
|
protected:
|
|
55
|
-
SVFIR*pag;
|
|
55
|
+
SVFIR* pag;
|
|
56
56
|
NodeToRepMap nodeToRepMap;
|
|
57
57
|
NodeToSubsMap nodeToSubsMap;
|
|
58
58
|
WorkList nodesToBeCollapsed;
|
|
@@ -180,7 +180,7 @@ public:
|
|
|
180
180
|
/// Add Copy edge
|
|
181
181
|
CopyCGEdge* addCopyCGEdge(NodeID src, NodeID dst);
|
|
182
182
|
/// Add Gep edge
|
|
183
|
-
NormalGepCGEdge*
|
|
183
|
+
NormalGepCGEdge* addNormalGepCGEdge(NodeID src, NodeID dst, const AccessPath& ap);
|
|
184
184
|
VariantGepCGEdge* addVariantGepCGEdge(NodeID src, NodeID dst);
|
|
185
185
|
/// Add Load edge
|
|
186
186
|
LoadCGEdge* addLoadCGEdge(NodeID src, NodeID dst);
|
|
@@ -325,9 +325,9 @@ public:
|
|
|
325
325
|
return (mem->getMaxFieldOffsetLimit() == 1);
|
|
326
326
|
}
|
|
327
327
|
/// Get a field of a memory object
|
|
328
|
-
inline NodeID getGepObjVar(NodeID id, const APOffset&
|
|
328
|
+
inline NodeID getGepObjVar(NodeID id, const APOffset& apOffset)
|
|
329
329
|
{
|
|
330
|
-
NodeID gep = pag->getGepObjVar(id,
|
|
330
|
+
NodeID gep = pag->getGepObjVar(id, apOffset);
|
|
331
331
|
/// Create a node when it is (1) not exist on graph and (2) not merged
|
|
332
332
|
if(sccRepNode(gep)==gep && hasConstraintNode(gep)==false)
|
|
333
333
|
addConstraintNode(new ConstraintNode(gep),gep);
|
|
@@ -269,7 +269,7 @@ private:
|
|
|
269
269
|
NormalGepCGEdge(const NormalGepCGEdge &); ///< place holder
|
|
270
270
|
void operator=(const NormalGepCGEdge &); ///< place holder
|
|
271
271
|
|
|
272
|
-
AccessPath
|
|
272
|
+
AccessPath ap; ///< Access path of the gep edge
|
|
273
273
|
|
|
274
274
|
public:
|
|
275
275
|
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
@@ -293,20 +293,22 @@ public:
|
|
|
293
293
|
//@}
|
|
294
294
|
|
|
295
295
|
/// Constructor
|
|
296
|
-
NormalGepCGEdge(ConstraintNode* s, ConstraintNode* d, const AccessPath&
|
|
297
|
-
|
|
298
|
-
|
|
296
|
+
NormalGepCGEdge(ConstraintNode* s, ConstraintNode* d, const AccessPath& ap,
|
|
297
|
+
EdgeID id)
|
|
298
|
+
: GepCGEdge(s, d, NormalGep, id), ap(ap)
|
|
299
|
+
{
|
|
300
|
+
}
|
|
299
301
|
|
|
300
302
|
/// Get location set of the gep edge
|
|
301
303
|
inline const AccessPath& getAccessPath() const
|
|
302
304
|
{
|
|
303
|
-
return
|
|
305
|
+
return ap;
|
|
304
306
|
}
|
|
305
307
|
|
|
306
308
|
/// Get location set of the gep edge
|
|
307
309
|
inline APOffset getConstantFieldIdx() const
|
|
308
310
|
{
|
|
309
|
-
return
|
|
311
|
+
return ap.getConstantFieldIdx();
|
|
310
312
|
}
|
|
311
313
|
|
|
312
314
|
};
|
|
@@ -68,9 +68,9 @@ public:
|
|
|
68
68
|
AccessPath(APOffset o = 0) : fldIdx(o) {}
|
|
69
69
|
|
|
70
70
|
/// Copy Constructor
|
|
71
|
-
AccessPath(const AccessPath&
|
|
72
|
-
: fldIdx(
|
|
73
|
-
offsetVarAndGepTypePairs(
|
|
71
|
+
AccessPath(const AccessPath& ap)
|
|
72
|
+
: fldIdx(ap.fldIdx),
|
|
73
|
+
offsetVarAndGepTypePairs(ap.getOffsetVarAndGepTypePairVec())
|
|
74
74
|
{
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -146,11 +146,12 @@ private:
|
|
|
146
146
|
|
|
147
147
|
template <> struct std::hash<SVF::AccessPath>
|
|
148
148
|
{
|
|
149
|
-
size_t operator()(const SVF::AccessPath &
|
|
149
|
+
size_t operator()(const SVF::AccessPath &ap) const
|
|
150
150
|
{
|
|
151
151
|
SVF::Hash<std::pair<SVF::NodeID, SVF::NodeID>> h;
|
|
152
152
|
std::hash<SVF::AccessPath::OffsetVarAndGepTypePairs> v;
|
|
153
|
-
return h(std::make_pair(
|
|
153
|
+
return h(std::make_pair(ap.getConstantFieldIdx(),
|
|
154
|
+
v(ap.getOffsetVarAndGepTypePairVec())));
|
|
154
155
|
}
|
|
155
156
|
};
|
|
156
157
|
|
|
@@ -338,9 +338,9 @@ public:
|
|
|
338
338
|
{
|
|
339
339
|
return pag->getFIObjVar(id);
|
|
340
340
|
}
|
|
341
|
-
inline NodeID getGepObjVar(NodeID id, const APOffset&
|
|
341
|
+
inline NodeID getGepObjVar(NodeID id, const APOffset& ap)
|
|
342
342
|
{
|
|
343
|
-
return pag->getGepObjVar(id,
|
|
343
|
+
return pag->getGepObjVar(id, ap);
|
|
344
344
|
}
|
|
345
345
|
virtual inline const NodeBS& getAllFieldsObjVars(NodeID id)
|
|
346
346
|
{
|
|
@@ -422,7 +422,7 @@ private:
|
|
|
422
422
|
cJSON* toJson(const CHEdge* edge); // CHGraph Edge
|
|
423
423
|
|
|
424
424
|
cJSON* toJson(const CallSite& cs);
|
|
425
|
-
cJSON* toJson(const AccessPath&
|
|
425
|
+
cJSON* toJson(const AccessPath& ap);
|
|
426
426
|
cJSON* toJson(const SVFLoop* loop);
|
|
427
427
|
cJSON* toJson(const MemObj* memObj);
|
|
428
428
|
cJSON* toJson(const ObjTypeInfo* objTypeInfo); // Only owned by MemObj
|
|
@@ -1104,7 +1104,7 @@ private:
|
|
|
1104
1104
|
void readJson(const cJSON* obj, CHEdge*& edge); // CHGraph Edge
|
|
1105
1105
|
void readJson(const cJSON* obj, CallSite& cs); // CHGraph's csToClassMap
|
|
1106
1106
|
|
|
1107
|
-
void readJson(const cJSON* obj, AccessPath&
|
|
1107
|
+
void readJson(const cJSON* obj, AccessPath& ap);
|
|
1108
1108
|
void readJson(const cJSON* obj, SVFLoop*& loop);
|
|
1109
1109
|
void readJson(const cJSON* obj, MemObj*& memObj);
|
|
1110
1110
|
void readJson(const cJSON* obj,
|
|
@@ -328,7 +328,8 @@ public:
|
|
|
328
328
|
//@}
|
|
329
329
|
|
|
330
330
|
/// Due to constaint expression, curInst is used to distinguish different instructions (e.g., memorycpy) when creating GepValVar.
|
|
331
|
-
NodeID getGepValVar(const SVFValue* curInst, NodeID base,
|
|
331
|
+
NodeID getGepValVar(const SVFValue* curInst, NodeID base,
|
|
332
|
+
const AccessPath& ap) const;
|
|
332
333
|
|
|
333
334
|
/// Add/get indirect callsites
|
|
334
335
|
//@{
|
|
@@ -392,9 +393,9 @@ public:
|
|
|
392
393
|
//@}
|
|
393
394
|
|
|
394
395
|
/// Get a field SVFIR Object node according to base mem obj and offset
|
|
395
|
-
NodeID getGepObjVar(const MemObj* obj, const APOffset&
|
|
396
|
+
NodeID getGepObjVar(const MemObj* obj, const APOffset& ap);
|
|
396
397
|
/// Get a field obj SVFIR node according to a mem obj and a given offset
|
|
397
|
-
NodeID getGepObjVar(NodeID id, const APOffset&
|
|
398
|
+
NodeID getGepObjVar(NodeID id, const APOffset& ap) ;
|
|
398
399
|
/// Get a field-insensitive obj SVFIR node according to a mem obj
|
|
399
400
|
//@{
|
|
400
401
|
inline NodeID getFIObjVar(const MemObj* obj) const
|
|
@@ -557,9 +558,9 @@ private:
|
|
|
557
558
|
}
|
|
558
559
|
|
|
559
560
|
/// Add a temp field value node, this method can only invoked by getGepValVar
|
|
560
|
-
NodeID addGepValNode(const SVFValue* curInst,const SVFValue* val, const AccessPath&
|
|
561
|
+
NodeID addGepValNode(const SVFValue* curInst,const SVFValue* val, const AccessPath& ap, NodeID i, const SVFType* type);
|
|
561
562
|
/// Add a field obj node, this method can only invoked by getGepObjVar
|
|
562
|
-
NodeID addGepObjNode(const MemObj* obj, const APOffset&
|
|
563
|
+
NodeID addGepObjNode(const MemObj* obj, const APOffset& apOffset);
|
|
563
564
|
/// Add a field-insensitive node, this method can only invoked by getFIGepObjNode
|
|
564
565
|
NodeID addFIObjNode(const MemObj* obj);
|
|
565
566
|
//@}
|
|
@@ -665,12 +666,12 @@ private:
|
|
|
665
666
|
RetPE* addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs,
|
|
666
667
|
const FunExitICFGNode* exit);
|
|
667
668
|
/// Add Gep edge
|
|
668
|
-
GepStmt* addGepStmt(NodeID src, NodeID dst, const AccessPath&
|
|
669
|
+
GepStmt* addGepStmt(NodeID src, NodeID dst, const AccessPath& ap,
|
|
669
670
|
bool constGep);
|
|
670
671
|
/// Add Offset(Gep) edge
|
|
671
|
-
GepStmt* addNormalGepStmt(NodeID src, NodeID dst, const AccessPath&
|
|
672
|
+
GepStmt* addNormalGepStmt(NodeID src, NodeID dst, const AccessPath& ap);
|
|
672
673
|
/// Add Variant(Gep) edge
|
|
673
|
-
GepStmt* addVariantGepStmt(NodeID src, NodeID dst, const AccessPath&
|
|
674
|
+
GepStmt* addVariantGepStmt(NodeID src, NodeID dst, const AccessPath& ap);
|
|
674
675
|
/// Add Thread fork edge for parameter passing
|
|
675
676
|
TDForkPE* addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs,
|
|
676
677
|
const FunEntryICFGNode* entry);
|
|
@@ -465,7 +465,7 @@ private:
|
|
|
465
465
|
GepStmt(const GepStmt &); ///< place holder
|
|
466
466
|
void operator=(const GepStmt &); ///< place holder
|
|
467
467
|
|
|
468
|
-
AccessPath
|
|
468
|
+
AccessPath ap; ///< Access path of the GEP edge
|
|
469
469
|
bool variantField; ///< Gep statement with a variant field index (pointer arithmetic) for struct field access (e.g., p = &(q + f), where f is a variable)
|
|
470
470
|
public:
|
|
471
471
|
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
@@ -486,7 +486,7 @@ public:
|
|
|
486
486
|
|
|
487
487
|
inline const AccessPath& getAccessPath() const
|
|
488
488
|
{
|
|
489
|
-
return
|
|
489
|
+
return ap;
|
|
490
490
|
}
|
|
491
491
|
inline const AccessPath::OffsetVarAndGepTypePairs getOffsetVarAndGepTypePairVec() const
|
|
492
492
|
{
|
|
@@ -515,8 +515,8 @@ public:
|
|
|
515
515
|
}
|
|
516
516
|
|
|
517
517
|
/// constructor
|
|
518
|
-
GepStmt(SVFVar* s, SVFVar* d, const AccessPath&
|
|
519
|
-
: AssignStmt(s, d, SVFStmt::Gep),
|
|
518
|
+
GepStmt(SVFVar* s, SVFVar* d, const AccessPath& ap, bool varfld = false)
|
|
519
|
+
: AssignStmt(s, d, SVFStmt::Gep), ap(ap), variantField(varfld)
|
|
520
520
|
{
|
|
521
521
|
}
|
|
522
522
|
|
|
@@ -383,7 +383,7 @@ class GepValVar: public ValVar
|
|
|
383
383
|
friend class SVFIRReader;
|
|
384
384
|
|
|
385
385
|
private:
|
|
386
|
-
AccessPath
|
|
386
|
+
AccessPath ap; // AccessPath
|
|
387
387
|
const SVFType* gepValType;
|
|
388
388
|
|
|
389
389
|
/// Constructor to create empty GeValVar (for SVFIRReader/deserialization)
|
|
@@ -411,16 +411,16 @@ public:
|
|
|
411
411
|
//@}
|
|
412
412
|
|
|
413
413
|
/// Constructor
|
|
414
|
-
GepValVar(const SVFValue* val, NodeID i, const AccessPath&
|
|
414
|
+
GepValVar(const SVFValue* val, NodeID i, const AccessPath& ap,
|
|
415
415
|
const SVFType* ty)
|
|
416
|
-
: ValVar(val, i, GepValNode),
|
|
416
|
+
: ValVar(val, i, GepValNode), ap(ap), gepValType(ty)
|
|
417
417
|
{
|
|
418
418
|
}
|
|
419
419
|
|
|
420
420
|
/// offset of the base value variable
|
|
421
421
|
inline APOffset getConstantFieldIdx() const
|
|
422
422
|
{
|
|
423
|
-
return
|
|
423
|
+
return ap.getConstantFieldIdx();
|
|
424
424
|
}
|
|
425
425
|
|
|
426
426
|
/// Return name of a LLVM value
|
|
@@ -451,7 +451,7 @@ class GepObjVar: public ObjVar
|
|
|
451
451
|
friend class SVFIRReader;
|
|
452
452
|
|
|
453
453
|
private:
|
|
454
|
-
APOffset
|
|
454
|
+
APOffset apOffset = 0;
|
|
455
455
|
NodeID base = 0;
|
|
456
456
|
|
|
457
457
|
/// Constructor to create empty GepObjVar (for SVFIRReader/deserialization)
|
|
@@ -480,9 +480,9 @@ public:
|
|
|
480
480
|
//@}
|
|
481
481
|
|
|
482
482
|
/// Constructor
|
|
483
|
-
GepObjVar(const MemObj* mem, NodeID i, const APOffset&
|
|
483
|
+
GepObjVar(const MemObj* mem, NodeID i, const APOffset& apOffset,
|
|
484
484
|
PNODEK ty = GepObjNode)
|
|
485
|
-
: ObjVar(mem->getValue(), i, mem, ty),
|
|
485
|
+
: ObjVar(mem->getValue(), i, mem, ty), apOffset(apOffset)
|
|
486
486
|
{
|
|
487
487
|
base = mem->getId();
|
|
488
488
|
}
|
|
@@ -490,7 +490,7 @@ public:
|
|
|
490
490
|
/// offset of the mem object
|
|
491
491
|
inline APOffset getConstantFieldIdx() const
|
|
492
492
|
{
|
|
493
|
-
return
|
|
493
|
+
return apOffset;
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
/// Set the base object from which this GEP node came from.
|
|
@@ -508,15 +508,15 @@ public:
|
|
|
508
508
|
/// Return the type of this gep object
|
|
509
509
|
inline virtual const SVFType* getType() const
|
|
510
510
|
{
|
|
511
|
-
return SymbolTableInfo::SymbolInfo()->getFlatternedElemType(mem->getType(),
|
|
511
|
+
return SymbolTableInfo::SymbolInfo()->getFlatternedElemType(mem->getType(), apOffset);
|
|
512
512
|
}
|
|
513
513
|
|
|
514
514
|
/// Return name of a LLVM value
|
|
515
515
|
inline const std::string getValueName() const
|
|
516
516
|
{
|
|
517
517
|
if (value)
|
|
518
|
-
return value->getName() + "_" + std::to_string(
|
|
519
|
-
return "offset_" + std::to_string(
|
|
518
|
+
return value->getName() + "_" + std::to_string(apOffset);
|
|
519
|
+
return "offset_" + std::to_string(apOffset);
|
|
520
520
|
}
|
|
521
521
|
|
|
522
522
|
virtual const std::string toString() const;
|
|
@@ -333,7 +333,8 @@ public:
|
|
|
333
333
|
virtual void dump();
|
|
334
334
|
|
|
335
335
|
/// Given an offset from a Gep Instruction, return it modulus offset by considering memory layout
|
|
336
|
-
virtual APOffset getModulusOffset(const MemObj* obj,
|
|
336
|
+
virtual APOffset getModulusOffset(const MemObj* obj,
|
|
337
|
+
const APOffset& apOffset);
|
|
337
338
|
|
|
338
339
|
///The struct type with the most fields
|
|
339
340
|
const SVFType* maxStruct;
|
|
@@ -453,7 +454,7 @@ public:
|
|
|
453
454
|
bool isConstDataOrConstGlobal() const;
|
|
454
455
|
bool isConstDataOrAggData() const;
|
|
455
456
|
bool hasPtrObj() const;
|
|
456
|
-
bool isNonPtrFieldObj(const APOffset&
|
|
457
|
+
bool isNonPtrFieldObj(const APOffset& apOffset) const;
|
|
457
458
|
//@}
|
|
458
459
|
|
|
459
460
|
/// Operator overloading
|
|
@@ -621,7 +622,7 @@ public:
|
|
|
621
622
|
{
|
|
622
623
|
return hasFlag(HASPTR_OBJ);
|
|
623
624
|
}
|
|
624
|
-
virtual bool isNonPtrFieldObj(const APOffset&
|
|
625
|
+
virtual bool isNonPtrFieldObj(const APOffset& apOffset);
|
|
625
626
|
//@}
|
|
626
627
|
};
|
|
627
628
|
|
|
@@ -261,7 +261,7 @@ public:
|
|
|
261
261
|
|
|
262
262
|
friend bool eq(const Z3Expr &lhs, const Z3Expr &rhs)
|
|
263
263
|
{
|
|
264
|
-
return eq(lhs.getExpr(), rhs.getExpr());
|
|
264
|
+
return eq(lhs.getExpr().simplify(), rhs.getExpr().simplify());
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
z3::sort get_sort() const
|
|
@@ -293,7 +293,7 @@ public:
|
|
|
293
293
|
/// compute NEG
|
|
294
294
|
static inline Z3Expr NEG(const Z3Expr &z3Expr)
|
|
295
295
|
{
|
|
296
|
-
return !z3Expr;
|
|
296
|
+
return (!z3Expr).simplify();
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
/// compute AND, used for branch condition
|
package/svf/lib/Graphs/ConsG.cpp
CHANGED
|
@@ -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 AccessPath&
|
|
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 AccessPath
|
|
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 AccessPath
|
|
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
|
{
|
|
@@ -157,19 +157,16 @@ NodeBS AccessPath::computeAllLocations() const
|
|
|
157
157
|
return result;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
AccessPath AccessPath::operator+
|
|
160
|
+
AccessPath AccessPath::operator+(const AccessPath& rhs) const
|
|
161
161
|
{
|
|
162
|
-
AccessPath
|
|
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
170
|
bool AccessPath::operator< (const AccessPath& rhs) const
|
|
174
171
|
{
|
|
175
172
|
if (fldIdx != rhs.fldIdx)
|
|
@@ -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 APOffset
|
|
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);
|
|
@@ -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 AccessPath&
|
|
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,12 +1844,12 @@ 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, AccessPath&
|
|
1847
|
+
void SVFIRReader::readJson(const cJSON* obj, AccessPath& ap)
|
|
1848
1848
|
{
|
|
1849
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, &
|
|
1851
|
+
JSON_READ_FIELD_FWD(obj, &ap, fldIdx);
|
|
1852
|
+
JSON_READ_FIELD_FWD(obj, &ap, offsetVarAndGepTypePairs);
|
|
1853
1853
|
ABORT_IFNOT(!obj, "Extra field " << JSON_KEY(obj) << " in AccessPath");
|
|
1854
1854
|
}
|
|
1855
1855
|
|
|
@@ -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 AccessPath&
|
|
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 AccessPath& ls, bool co
|
|
|
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 AccessPath&
|
|
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 AccessPath& 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 AccessPath& 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 AccessPath&
|
|
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 AccessPath& 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 AccessPath& 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 AccessPath&
|
|
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 APOffset&
|
|
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->getConstantFieldIdx() +
|
|
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 APOffset& 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 APOffset&
|
|
422
|
+
NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset)
|
|
423
423
|
{
|
|
424
424
|
NodeID base = obj->getId();
|
|
425
425
|
|
|
@@ -427,7 +427,7 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& ls)
|
|
|
427
427
|
if (obj->isFieldInsensitive())
|
|
428
428
|
return getFIObjVar(obj);
|
|
429
429
|
|
|
430
|
-
APOffset newLS = pag->getSymbolInfo()->getModulusOffset(obj,
|
|
430
|
+
APOffset newLS = pag->getSymbolInfo()->getModulusOffset(obj, apOffset);
|
|
431
431
|
|
|
432
432
|
// Base and first field are the same memory location.
|
|
433
433
|
if (Options::FirstFieldEqBase() && newLS == 0) return base;
|
|
@@ -443,16 +443,16 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& 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 APOffset&
|
|
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 AccessPath&
|
|
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 AccessPat
|
|
|
544
544
|
}
|
|
545
545
|
else
|
|
546
546
|
{
|
|
547
|
-
NodeAccessPathMap::const_iterator lit =
|
|
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;
|
|
@@ -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
|
-
APOffset SymbolTableInfo::getModulusOffset(const MemObj* obj, const APOffset&
|
|
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
|
-
APOffset offset =
|
|
101
|
+
APOffset offset = apOffset;
|
|
102
102
|
if(offset < 0)
|
|
103
103
|
{
|
|
104
104
|
writeWrnMsg("try to create a gep node with negative offset.");
|
|
@@ -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 APOffset&
|
|
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 APOffset& 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 APOffset&
|
|
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/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
|
@@ -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 APOffset
|
|
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
|
|
|
@@ -216,10 +216,10 @@ protected:
|
|
|
216
216
|
void processCE(const Value* val);
|
|
217
217
|
|
|
218
218
|
/// Infer field index from byteoffset.
|
|
219
|
-
u32_t inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, DataLayout *dl, AccessPath&
|
|
219
|
+
u32_t inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, DataLayout *dl, AccessPath& ap, APOffset idx);
|
|
220
220
|
|
|
221
221
|
/// Compute offset of a gep instruction or gep constant expression
|
|
222
|
-
bool computeGepOffset(const User *V, AccessPath&
|
|
222
|
+
bool computeGepOffset(const User *V, AccessPath& ap);
|
|
223
223
|
|
|
224
224
|
/// Get the base value of (i8* src and i8* dst) for external argument (e.g. memcpy(i8* dst, i8* src, int size))
|
|
225
225
|
const Value* getBaseValueForExtArg(const Value* V);
|
|
@@ -287,7 +287,7 @@ protected:
|
|
|
287
287
|
return nullPtr;
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
NodeID getGepValVar(const SVFValue* val, const AccessPath&
|
|
290
|
+
NodeID getGepValVar(const SVFValue* val, const AccessPath& ap, const SVFType* baseType);
|
|
291
291
|
|
|
292
292
|
void setCurrentBBAndValueForPAGEdge(PAGEdge* edge);
|
|
293
293
|
|
|
@@ -364,53 +364,53 @@ protected:
|
|
|
364
364
|
inline void addStoreEdge(NodeID src, NodeID dst)
|
|
365
365
|
{
|
|
366
366
|
IntraICFGNode* node;
|
|
367
|
-
if(const SVFInstruction* inst = SVFUtil::dyn_cast<SVFInstruction>(curVal))
|
|
367
|
+
if (const SVFInstruction* inst = SVFUtil::dyn_cast<SVFInstruction>(curVal))
|
|
368
368
|
node = pag->getICFG()->getIntraICFGNode(inst);
|
|
369
369
|
else
|
|
370
370
|
node = nullptr;
|
|
371
|
-
if(StoreStmt
|
|
371
|
+
if (StoreStmt* edge = pag->addStoreStmt(src, dst, node))
|
|
372
372
|
setCurrentBBAndValueForPAGEdge(edge);
|
|
373
373
|
}
|
|
374
374
|
/// Add Call edge
|
|
375
375
|
inline void addCallEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry)
|
|
376
376
|
{
|
|
377
|
-
if(CallPE
|
|
377
|
+
if (CallPE* edge = pag->addCallPE(src, dst, cs, entry))
|
|
378
378
|
setCurrentBBAndValueForPAGEdge(edge);
|
|
379
379
|
}
|
|
380
380
|
/// Add Return edge
|
|
381
381
|
inline void addRetEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit)
|
|
382
382
|
{
|
|
383
|
-
if(RetPE
|
|
383
|
+
if (RetPE* edge = pag->addRetPE(src, dst, cs, exit))
|
|
384
384
|
setCurrentBBAndValueForPAGEdge(edge);
|
|
385
385
|
}
|
|
386
386
|
/// Add Gep edge
|
|
387
|
-
inline void addGepEdge(NodeID src, NodeID dst, const AccessPath&
|
|
387
|
+
inline void addGepEdge(NodeID src, NodeID dst, const AccessPath& ap, bool constGep)
|
|
388
388
|
{
|
|
389
|
-
if(GepStmt
|
|
389
|
+
if (GepStmt* edge = pag->addGepStmt(src, dst, ap, constGep))
|
|
390
390
|
setCurrentBBAndValueForPAGEdge(edge);
|
|
391
391
|
}
|
|
392
392
|
/// Add Offset(Gep) edge
|
|
393
|
-
inline void addNormalGepEdge(NodeID src, NodeID dst, const AccessPath&
|
|
393
|
+
inline void addNormalGepEdge(NodeID src, NodeID dst, const AccessPath& ap)
|
|
394
394
|
{
|
|
395
|
-
if(GepStmt
|
|
395
|
+
if (GepStmt* edge = pag->addNormalGepStmt(src, dst, ap))
|
|
396
396
|
setCurrentBBAndValueForPAGEdge(edge);
|
|
397
397
|
}
|
|
398
398
|
/// Add Variant(Gep) edge
|
|
399
|
-
inline void addVariantGepEdge(NodeID src, NodeID dst, const AccessPath&
|
|
399
|
+
inline void addVariantGepEdge(NodeID src, NodeID dst, const AccessPath& ap)
|
|
400
400
|
{
|
|
401
|
-
if(GepStmt
|
|
401
|
+
if (GepStmt* edge = pag->addVariantGepStmt(src, dst, ap))
|
|
402
402
|
setCurrentBBAndValueForPAGEdge(edge);
|
|
403
403
|
}
|
|
404
404
|
/// Add Thread fork edge for parameter passing
|
|
405
405
|
inline void addThreadForkEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry)
|
|
406
406
|
{
|
|
407
|
-
if(TDForkPE
|
|
407
|
+
if (TDForkPE* edge = pag->addThreadForkPE(src, dst, cs, entry))
|
|
408
408
|
setCurrentBBAndValueForPAGEdge(edge);
|
|
409
409
|
}
|
|
410
410
|
/// Add Thread join edge for parameter passing
|
|
411
411
|
inline void addThreadJoinEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit)
|
|
412
412
|
{
|
|
413
|
-
if(TDJoinPE
|
|
413
|
+
if (TDJoinPE* edge = pag->addThreadJoinPE(src, dst, cs, exit))
|
|
414
414
|
setCurrentBBAndValueForPAGEdge(edge);
|
|
415
415
|
}
|
|
416
416
|
//@}
|
|
@@ -257,7 +257,7 @@ void SVFIRBuilder::initialiseNodes()
|
|
|
257
257
|
e.g. field_idx = getelementptr i8, %struct_type %p, i64 1
|
|
258
258
|
|
|
259
259
|
*/
|
|
260
|
-
u32_t SVFIRBuilder::inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, DataLayout *dl, AccessPath&
|
|
260
|
+
u32_t SVFIRBuilder::inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, DataLayout *dl, AccessPath& ap, APOffset idx)
|
|
261
261
|
{
|
|
262
262
|
return 0;
|
|
263
263
|
}
|
|
@@ -268,7 +268,7 @@ u32_t SVFIRBuilder::inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp,
|
|
|
268
268
|
* otherwise if "i" is a variable determined by runtime, then it is a variant offset
|
|
269
269
|
* Return TRUE if the offset of this GEP insn is a constant.
|
|
270
270
|
*/
|
|
271
|
-
bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath&
|
|
271
|
+
bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
|
|
272
272
|
{
|
|
273
273
|
assert(V);
|
|
274
274
|
|
|
@@ -290,7 +290,7 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ls)
|
|
|
290
290
|
const Value* offsetVal = gi.getOperand();
|
|
291
291
|
const SVFValue* offsetSvfVal = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(offsetVal);
|
|
292
292
|
assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
|
|
293
|
-
|
|
293
|
+
ap.addOffsetVarAndGepTypePair(getPAG()->getGNode(getPAG()->getValueNode(offsetSvfVal)), svfGepTy);
|
|
294
294
|
|
|
295
295
|
//The int value of the current index operand
|
|
296
296
|
const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(offsetVal);
|
|
@@ -303,7 +303,7 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ls)
|
|
|
303
303
|
continue;
|
|
304
304
|
APOffset idx = op->getSExtValue();
|
|
305
305
|
u32_t offset = pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(arrTy), idx);
|
|
306
|
-
|
|
306
|
+
ap.setFldIdx(ap.getConstantFieldIdx() + offset);
|
|
307
307
|
}
|
|
308
308
|
else if (const StructType *ST = SVFUtil::dyn_cast<StructType>(gepTy))
|
|
309
309
|
{
|
|
@@ -311,7 +311,7 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ls)
|
|
|
311
311
|
//The actual index
|
|
312
312
|
APOffset idx = op->getSExtValue();
|
|
313
313
|
u32_t offset = pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(ST), idx);
|
|
314
|
-
|
|
314
|
+
ap.setFldIdx(ap.getConstantFieldIdx() + offset);
|
|
315
315
|
}
|
|
316
316
|
else if (gepTy->isSingleValueType())
|
|
317
317
|
{
|
|
@@ -325,8 +325,8 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ls)
|
|
|
325
325
|
//s32_t idx = op->getSExtValue();
|
|
326
326
|
|
|
327
327
|
// For pointer arithmetic we ignore the byte offset
|
|
328
|
-
// consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,
|
|
329
|
-
//
|
|
328
|
+
// consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,ap,idx)?
|
|
329
|
+
// ap.setFldIdx(ap.getConstantFieldIdx() + inferFieldIdxFromByteOffset(geopOp,idx));
|
|
330
330
|
}
|
|
331
331
|
}
|
|
332
332
|
return isConst;
|
|
@@ -345,8 +345,8 @@ void SVFIRBuilder::processCE(const Value* val)
|
|
|
345
345
|
const Constant* opnd = gepce->getOperand(0);
|
|
346
346
|
// handle recursive constant express case (gep (bitcast (gep X 1)) 1)
|
|
347
347
|
processCE(opnd);
|
|
348
|
-
AccessPath
|
|
349
|
-
bool constGep = computeGepOffset(gepce,
|
|
348
|
+
AccessPath ap;
|
|
349
|
+
bool constGep = computeGepOffset(gepce, ap);
|
|
350
350
|
// must invoke pag methods here, otherwise it will be a dead recursion cycle
|
|
351
351
|
const SVFValue* cval = getCurrentValue();
|
|
352
352
|
const SVFBasicBlock* cbb = getCurrentBB();
|
|
@@ -355,7 +355,7 @@ void SVFIRBuilder::processCE(const Value* val)
|
|
|
355
355
|
* The gep edge created are like constexpr (same edge may appear at multiple callsites)
|
|
356
356
|
* so bb/inst of this edge may be rewritten several times, we treat it as global here.
|
|
357
357
|
*/
|
|
358
|
-
addGepEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gepce)),
|
|
358
|
+
addGepEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gepce)), ap, constGep);
|
|
359
359
|
setCurrentLocation(cval, cbb);
|
|
360
360
|
}
|
|
361
361
|
else if (const ConstantExpr* castce = isCastConstantExpr(ref))
|
|
@@ -710,9 +710,9 @@ void SVFIRBuilder::visitGetElementPtrInst(GetElementPtrInst &inst)
|
|
|
710
710
|
|
|
711
711
|
NodeID src = getValueNode(inst.getPointerOperand());
|
|
712
712
|
|
|
713
|
-
AccessPath
|
|
714
|
-
bool constGep = computeGepOffset(&inst,
|
|
715
|
-
addGepEdge(src, dst,
|
|
713
|
+
AccessPath ap;
|
|
714
|
+
bool constGep = computeGepOffset(&inst, ap);
|
|
715
|
+
addGepEdge(src, dst, ap, constGep);
|
|
716
716
|
}
|
|
717
717
|
|
|
718
718
|
/*
|
|
@@ -1161,7 +1161,7 @@ void SVFIRBuilder::preProcessExtCall(CallBase* cs)
|
|
|
1161
1161
|
LLVMContext& context = LLVMModuleSet::getLLVMModuleSet()->getContext();
|
|
1162
1162
|
for(u32_t ei = 0; ei < numOfElems; ei++)
|
|
1163
1163
|
{
|
|
1164
|
-
AccessPath
|
|
1164
|
+
AccessPath ap(ei);
|
|
1165
1165
|
// make a ConstantInt and create char for the content type due to byte-wise copy
|
|
1166
1166
|
const ConstantInt* offset = ConstantInt::get(context, llvm::APInt(32, ei));
|
|
1167
1167
|
const SVFValue* svfOffset = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(offset);
|
|
@@ -1171,8 +1171,8 @@ void SVFIRBuilder::preProcessExtCall(CallBase* cs)
|
|
|
1171
1171
|
builder.collectSym(offset);
|
|
1172
1172
|
pag->addValNode(svfOffset, pag->getSymbolInfo()->getValSym(svfOffset));
|
|
1173
1173
|
}
|
|
1174
|
-
|
|
1175
|
-
fields.push_back(
|
|
1174
|
+
ap.addOffsetVarAndGepTypePair(getPAG()->getGNode(getPAG()->getValueNode(svfOffset)), nullptr);
|
|
1175
|
+
fields.push_back(ap);
|
|
1176
1176
|
}
|
|
1177
1177
|
NodeID argId = pag->getValueNode(svfcall->getArgOperand(i));
|
|
1178
1178
|
std::pair<const SVFType*, std::vector<AccessPath>> pairToInsert = std::make_pair(st, fields);
|
|
@@ -1256,10 +1256,10 @@ void SVFIRBuilder::sanityCheck()
|
|
|
1256
1256
|
* Add a temp field value node according to base value and offset
|
|
1257
1257
|
* this node is after the initial node method, it is out of scope of symInfo table
|
|
1258
1258
|
*/
|
|
1259
|
-
NodeID SVFIRBuilder::getGepValVar(const SVFValue* val, const AccessPath&
|
|
1259
|
+
NodeID SVFIRBuilder::getGepValVar(const SVFValue* val, const AccessPath& ap, const SVFType* elementType)
|
|
1260
1260
|
{
|
|
1261
1261
|
NodeID base = pag->getBaseValVar(pag->getValueNode(val));
|
|
1262
|
-
NodeID gepval = pag->getGepValVar(curVal, base,
|
|
1262
|
+
NodeID gepval = pag->getGepValVar(curVal, base, ap);
|
|
1263
1263
|
if (gepval==UINT_MAX)
|
|
1264
1264
|
{
|
|
1265
1265
|
assert(((int) UINT_MAX)==-1 && "maximum limit of unsigned int is not -1?");
|
|
@@ -1278,8 +1278,8 @@ NodeID SVFIRBuilder::getGepValVar(const SVFValue* val, const AccessPath& ls, con
|
|
|
1278
1278
|
const SVFValue* cval = getCurrentValue();
|
|
1279
1279
|
const SVFBasicBlock* cbb = getCurrentBB();
|
|
1280
1280
|
setCurrentLocation(curVal, nullptr);
|
|
1281
|
-
NodeID gepNode= pag->addGepValNode(curVal, val,
|
|
1282
|
-
addGepEdge(base, gepNode,
|
|
1281
|
+
NodeID gepNode= pag->addGepValNode(curVal, val, ap, NodeIDAllocator::get()->allocateValueId(),elementType->getPointerTo());
|
|
1282
|
+
addGepEdge(base, gepNode, ap, true);
|
|
1283
1283
|
setCurrentLocation(cval, cbb);
|
|
1284
1284
|
return gepNode;
|
|
1285
1285
|
}
|
|
@@ -471,8 +471,8 @@ void SVFIRBuilder::extFuncAtomaticOperation(ExtAPI::Operand& atomicOp, const SVF
|
|
|
471
471
|
{
|
|
472
472
|
if (!atomicOp.getSrcValue().empty() && !atomicOp.getDstValue().empty() && !atomicOp.getOffsetOrSizeStr().empty())
|
|
473
473
|
{
|
|
474
|
-
AccessPath
|
|
475
|
-
addNormalGepEdge(atomicOp.getSrcID(), atomicOp.getDstID(),
|
|
474
|
+
AccessPath ap(atomicOp.getOffsetOrSize());
|
|
475
|
+
addNormalGepEdge(atomicOp.getSrcID(), atomicOp.getDstID(), ap);
|
|
476
476
|
}
|
|
477
477
|
else
|
|
478
478
|
writeWrnMsg("We need two valid NodeIDs and an offset to add a Gep edge");
|
|
@@ -20,7 +20,7 @@ namespace SVF
|
|
|
20
20
|
class RaceValidator : public RaceResultValidator
|
|
21
21
|
{
|
|
22
22
|
public:
|
|
23
|
-
RaceValidator(LockAnalysis*
|
|
23
|
+
RaceValidator(LockAnalysis* lockAnalysis) :lsa(lockAnalysis)
|
|
24
24
|
{
|
|
25
25
|
}
|
|
26
26
|
bool protectedByCommonLocks(const Instruction* I1, const Instruction* I2)
|