svf-tools 1.0.738 → 1.0.740
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/CFL/CFLGrammar.h +2 -2
- package/svf/include/Graphs/ICFGNode.h +1 -1
- package/svf/include/SVFIR/SVFFileSystem.h +2 -0
- package/svf/include/SVFIR/SVFType.h +49 -14
- package/svf/include/SVFIR/SVFValue.h +82 -42
- package/svf/lib/CFL/CFLGrammar.cpp +2 -2
- package/svf/lib/SVFIR/SVFFileSystem.cpp +53 -39
- package/svf/lib/SVFIR/SVFType.cpp +18 -17
- package/svf/lib/SVFIR/SVFValue.cpp +105 -9
- package/svf/lib/Util/CppUtil.cpp +1 -1
- package/svf-llvm/include/SVF-LLVM/CHGBuilder.h +2 -2
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +7 -0
- package/svf-llvm/lib/CHGBuilder.cpp +3 -3
- package/svf-llvm/lib/LLVMModule.cpp +106 -28
- package/svf-llvm/lib/LLVMUtil.cpp +5 -13
- package/svf-llvm/lib/SVFIRExtAPI.cpp +9 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.740",
|
|
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": {
|
|
@@ -217,9 +217,9 @@ public:
|
|
|
217
217
|
this->totalKind = totalKind;
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
std::string extractKindStrFromSymbolStr(const std::string symbolStr) const;
|
|
220
|
+
std::string extractKindStrFromSymbolStr(const std::string& symbolStr) const;
|
|
221
221
|
|
|
222
|
-
std::string extractAttributeStrFromSymbolStr(const std::string symbolStr) const;
|
|
222
|
+
std::string extractAttributeStrFromSymbolStr(const std::string& symbolStr) const;
|
|
223
223
|
|
|
224
224
|
void setRawProductions(SymbolMap<Symbol, Productions>& rawProductions);
|
|
225
225
|
|
|
@@ -429,6 +429,7 @@ private:
|
|
|
429
429
|
cJSON* toJson(const SVFLoopAndDomInfo* ldInfo); // Only owned by SVFFunction
|
|
430
430
|
cJSON* toJson(const StInfo* stInfo);
|
|
431
431
|
|
|
432
|
+
// No need for 'toJson(short)' because of promotion to int
|
|
432
433
|
static cJSON* toJson(bool flag);
|
|
433
434
|
static cJSON* toJson(unsigned number);
|
|
434
435
|
static cJSON* toJson(int number);
|
|
@@ -1044,6 +1045,7 @@ public:
|
|
|
1044
1045
|
static void readJson(const cJSON* obj, bool& flag);
|
|
1045
1046
|
static void readJson(const cJSON* obj, unsigned& val);
|
|
1046
1047
|
static void readJson(const cJSON* obj, int& val);
|
|
1048
|
+
static void readJson(const cJSON* obj, short& val);
|
|
1047
1049
|
static void readJson(const cJSON* obj, float& val);
|
|
1048
1050
|
static void readJson(const cJSON* obj, unsigned long& val);
|
|
1049
1051
|
static void readJson(const cJSON* obj, long long& val);
|
|
@@ -282,11 +282,11 @@ public:
|
|
|
282
282
|
return kind;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
///
|
|
285
|
+
/// \note Use `os<<svfType` or `svfType.print(os)` when possible to avoid
|
|
286
286
|
/// string concatenation.
|
|
287
287
|
std::string toString() const;
|
|
288
288
|
|
|
289
|
-
virtual void print(std::ostream&
|
|
289
|
+
virtual void print(std::ostream& os) const = 0;
|
|
290
290
|
|
|
291
291
|
inline void setPointerTo(const SVFPointerType* ty)
|
|
292
292
|
{
|
|
@@ -327,7 +327,7 @@ public:
|
|
|
327
327
|
}
|
|
328
328
|
};
|
|
329
329
|
|
|
330
|
-
std::ostream& operator<<(std::ostream&
|
|
330
|
+
std::ostream& operator<<(std::ostream& os, const SVFType& type);
|
|
331
331
|
|
|
332
332
|
class SVFPointerType : public SVFType
|
|
333
333
|
{
|
|
@@ -351,11 +351,17 @@ public:
|
|
|
351
351
|
return ptrElementType;
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
-
void print(std::ostream&
|
|
354
|
+
void print(std::ostream& os) const override;
|
|
355
355
|
};
|
|
356
356
|
|
|
357
357
|
class SVFIntegerType : public SVFType
|
|
358
358
|
{
|
|
359
|
+
friend class SVFIRWriter;
|
|
360
|
+
friend class SVFIRReader;
|
|
361
|
+
|
|
362
|
+
private:
|
|
363
|
+
short signAndWidth; ///< For printing
|
|
364
|
+
|
|
359
365
|
public:
|
|
360
366
|
SVFIntegerType() : SVFType(true, SVFIntegerTy) {}
|
|
361
367
|
static inline bool classof(const SVFType* node)
|
|
@@ -363,7 +369,17 @@ public:
|
|
|
363
369
|
return node->getKind() == SVFIntegerTy;
|
|
364
370
|
}
|
|
365
371
|
|
|
366
|
-
void print(std::ostream&
|
|
372
|
+
void print(std::ostream& os) const override;
|
|
373
|
+
|
|
374
|
+
void setSignAndWidth(short sw)
|
|
375
|
+
{
|
|
376
|
+
signAndWidth = sw;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
bool isSigned() const
|
|
380
|
+
{
|
|
381
|
+
return signAndWidth < 0;
|
|
382
|
+
}
|
|
367
383
|
};
|
|
368
384
|
|
|
369
385
|
class SVFFunctionType : public SVFType
|
|
@@ -388,7 +404,7 @@ public:
|
|
|
388
404
|
return retTy;
|
|
389
405
|
}
|
|
390
406
|
|
|
391
|
-
void print(std::ostream&
|
|
407
|
+
void print(std::ostream& os) const override;
|
|
392
408
|
};
|
|
393
409
|
|
|
394
410
|
class SVFStructType : public SVFType
|
|
@@ -397,6 +413,7 @@ class SVFStructType : public SVFType
|
|
|
397
413
|
friend class SVFIRReader;
|
|
398
414
|
|
|
399
415
|
private:
|
|
416
|
+
/// @brief Field for printing & debugging
|
|
400
417
|
std::string name;
|
|
401
418
|
|
|
402
419
|
public:
|
|
@@ -407,12 +424,20 @@ public:
|
|
|
407
424
|
return node->getKind() == SVFStructTy;
|
|
408
425
|
}
|
|
409
426
|
|
|
410
|
-
void print(std::ostream&
|
|
427
|
+
void print(std::ostream& os) const override;
|
|
411
428
|
|
|
412
|
-
std::string& getName()
|
|
429
|
+
const std::string& getName()
|
|
413
430
|
{
|
|
414
431
|
return name;
|
|
415
432
|
}
|
|
433
|
+
void setName(const std::string& structName)
|
|
434
|
+
{
|
|
435
|
+
name = structName;
|
|
436
|
+
}
|
|
437
|
+
void setName(std::string&& structName)
|
|
438
|
+
{
|
|
439
|
+
name = std::move(structName);
|
|
440
|
+
}
|
|
416
441
|
};
|
|
417
442
|
|
|
418
443
|
class SVFArrayType : public SVFType
|
|
@@ -421,8 +446,8 @@ class SVFArrayType : public SVFType
|
|
|
421
446
|
friend class SVFIRReader;
|
|
422
447
|
|
|
423
448
|
private:
|
|
424
|
-
unsigned numOfElement; /// For printing
|
|
425
|
-
SVFType* typeOfElement; /// For printing
|
|
449
|
+
unsigned numOfElement; /// For printing & debugging
|
|
450
|
+
const SVFType* typeOfElement; /// For printing & debugging
|
|
426
451
|
|
|
427
452
|
public:
|
|
428
453
|
SVFArrayType()
|
|
@@ -435,9 +460,9 @@ public:
|
|
|
435
460
|
return node->getKind() == SVFArrayTy;
|
|
436
461
|
}
|
|
437
462
|
|
|
438
|
-
void print(std::ostream&
|
|
463
|
+
void print(std::ostream& os) const override;
|
|
439
464
|
|
|
440
|
-
void setTypeOfElement(SVFType* elemType)
|
|
465
|
+
void setTypeOfElement(const SVFType* elemType)
|
|
441
466
|
{
|
|
442
467
|
typeOfElement = elemType;
|
|
443
468
|
}
|
|
@@ -464,12 +489,22 @@ public:
|
|
|
464
489
|
return node->getKind() == SVFOtherTy;
|
|
465
490
|
}
|
|
466
491
|
|
|
467
|
-
std::string& getRepr()
|
|
492
|
+
const std::string& getRepr()
|
|
468
493
|
{
|
|
469
494
|
return repr;
|
|
470
495
|
}
|
|
471
496
|
|
|
472
|
-
void
|
|
497
|
+
void setRepr(std::string&& r)
|
|
498
|
+
{
|
|
499
|
+
repr = std::move(r);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
void setRepr(const std::string& r)
|
|
503
|
+
{
|
|
504
|
+
repr = r;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
void print(std::ostream& os) const override;
|
|
473
508
|
};
|
|
474
509
|
|
|
475
510
|
/// [FOR DEBUG ONLY, DON'T USE IT UNSIDE `svf`!]
|
|
@@ -183,17 +183,17 @@ private:
|
|
|
183
183
|
|
|
184
184
|
protected:
|
|
185
185
|
const SVFType* type; ///< Type of this SVFValue
|
|
186
|
-
std::string name; ///< Short name of
|
|
186
|
+
std::string name; ///< Short name of value for printing & debugging
|
|
187
187
|
std::string sourceLoc; ///< Source code information of this value
|
|
188
|
-
/// Constructor
|
|
189
|
-
SVFValue(const
|
|
188
|
+
/// Constructor without name
|
|
189
|
+
SVFValue(const SVFType* ty, SVFValKind k)
|
|
190
190
|
: kind(k), ptrInUncalledFun(false),
|
|
191
|
-
constDataOrAggData(SVFConstData == k), type(ty),
|
|
192
|
-
sourceLoc("No source code Info")
|
|
191
|
+
constDataOrAggData(SVFConstData == k), type(ty), sourceLoc("NoLoc")
|
|
193
192
|
{
|
|
194
193
|
}
|
|
195
194
|
|
|
196
|
-
///@{ attributes to be set only through Module builders e.g.,
|
|
195
|
+
///@{ attributes to be set only through Module builders e.g.,
|
|
196
|
+
/// LLVMModule
|
|
197
197
|
inline void setConstDataOrAggData()
|
|
198
198
|
{
|
|
199
199
|
constDataOrAggData = true;
|
|
@@ -213,14 +213,17 @@ public:
|
|
|
213
213
|
return kind;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
|
|
217
|
-
inline virtual const std::string getName() const
|
|
216
|
+
inline const std::string &getName() const
|
|
218
217
|
{
|
|
219
218
|
return name;
|
|
220
219
|
}
|
|
221
|
-
inline
|
|
220
|
+
inline void setName(const std::string& n)
|
|
221
|
+
{
|
|
222
|
+
name = n;
|
|
223
|
+
}
|
|
224
|
+
inline void setName(std::string&& n)
|
|
222
225
|
{
|
|
223
|
-
name =
|
|
226
|
+
name = std::move(n);
|
|
224
227
|
}
|
|
225
228
|
|
|
226
229
|
inline virtual const SVFType* getType() const
|
|
@@ -252,15 +255,18 @@ public:
|
|
|
252
255
|
return sourceLoc;
|
|
253
256
|
}
|
|
254
257
|
|
|
255
|
-
///
|
|
256
|
-
|
|
258
|
+
/// \note Use `os<<SVFvalue` or `svfValue.print(os)` when possible to avoid
|
|
259
|
+
/// string concatenation.
|
|
260
|
+
std::string toString() const;
|
|
261
|
+
|
|
262
|
+
virtual void print(OutStream& os) const = 0;
|
|
257
263
|
|
|
258
264
|
/// Overloading operator << for dumping ICFG node ID
|
|
259
265
|
//@{
|
|
260
|
-
friend OutStream& operator<<
|
|
266
|
+
friend OutStream& operator<<(OutStream &os, const SVFValue &value)
|
|
261
267
|
{
|
|
262
|
-
|
|
263
|
-
return
|
|
268
|
+
value.print(os);
|
|
269
|
+
return os;
|
|
264
270
|
}
|
|
265
271
|
//@}
|
|
266
272
|
};
|
|
@@ -291,7 +297,6 @@ private:
|
|
|
291
297
|
std::vector<const SVFBasicBlock*> allBBs; /// all BasicBlocks of this function
|
|
292
298
|
std::vector<const SVFArgument*> allArgs; /// all formal arguments of this function
|
|
293
299
|
|
|
294
|
-
|
|
295
300
|
protected:
|
|
296
301
|
///@{ attributes to be set only through Module builders e.g., LLVMModule
|
|
297
302
|
inline void addBasicBlock(const SVFBasicBlock* bb)
|
|
@@ -321,8 +326,7 @@ protected:
|
|
|
321
326
|
/// @}
|
|
322
327
|
|
|
323
328
|
public:
|
|
324
|
-
SVFFunction(const
|
|
325
|
-
SVFFunction(const std::string& f) = delete;
|
|
329
|
+
SVFFunction(const SVFType* ty,const SVFFunctionType* ft, bool declare, bool intrinsic, bool addrTaken, bool varg, SVFLoopAndDomInfo* ld);
|
|
326
330
|
SVFFunction(void) = delete;
|
|
327
331
|
virtual ~SVFFunction();
|
|
328
332
|
|
|
@@ -331,6 +335,8 @@ public:
|
|
|
331
335
|
return node->getKind() == SVFFunc;
|
|
332
336
|
}
|
|
333
337
|
|
|
338
|
+
void print(OutStream& os) const override;
|
|
339
|
+
|
|
334
340
|
inline SVFLoopAndDomInfo* getLoopAndDomInfo()
|
|
335
341
|
{
|
|
336
342
|
return loopAndDom;
|
|
@@ -479,7 +485,6 @@ public:
|
|
|
479
485
|
{
|
|
480
486
|
return loopAndDom->postDominate(bbKey,bbValue);
|
|
481
487
|
}
|
|
482
|
-
|
|
483
488
|
};
|
|
484
489
|
|
|
485
490
|
class SVFBasicBlock : public SVFValue
|
|
@@ -517,7 +522,8 @@ protected:
|
|
|
517
522
|
/// @}
|
|
518
523
|
|
|
519
524
|
public:
|
|
520
|
-
|
|
525
|
+
/// Constructor without name
|
|
526
|
+
SVFBasicBlock(const SVFType* ty, const SVFFunction* f);
|
|
521
527
|
SVFBasicBlock() = delete;
|
|
522
528
|
~SVFBasicBlock() override;
|
|
523
529
|
|
|
@@ -526,6 +532,8 @@ public:
|
|
|
526
532
|
return node->getKind() == SVFBB;
|
|
527
533
|
}
|
|
528
534
|
|
|
535
|
+
void print(OutStream& os) const override;
|
|
536
|
+
|
|
529
537
|
inline const std::vector<const SVFInstruction*>& getInstructionList() const
|
|
530
538
|
{
|
|
531
539
|
return allInsts;
|
|
@@ -599,8 +607,9 @@ private:
|
|
|
599
607
|
InstVec predInsts; /// predecessor Instructions
|
|
600
608
|
|
|
601
609
|
public:
|
|
602
|
-
|
|
603
|
-
SVFInstruction(const
|
|
610
|
+
/// Constructor without name, set name with setName()
|
|
611
|
+
SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, bool tm,
|
|
612
|
+
bool isRet, SVFValKind k = SVFInst);
|
|
604
613
|
SVFInstruction(void) = delete;
|
|
605
614
|
|
|
606
615
|
static inline bool classof(const SVFValue *node)
|
|
@@ -610,6 +619,8 @@ public:
|
|
|
610
619
|
node->getKind() == SVFVCall;
|
|
611
620
|
}
|
|
612
621
|
|
|
622
|
+
void print(OutStream& os) const override;
|
|
623
|
+
|
|
613
624
|
inline const SVFBasicBlock* getParent() const
|
|
614
625
|
{
|
|
615
626
|
return bb;
|
|
@@ -676,11 +687,10 @@ protected:
|
|
|
676
687
|
/// @}
|
|
677
688
|
|
|
678
689
|
public:
|
|
679
|
-
SVFCallInst(const
|
|
680
|
-
SVFInstruction(
|
|
690
|
+
SVFCallInst(const SVFType* ty, const SVFBasicBlock* b, bool va, bool tm, SVFValKind k = SVFCall) :
|
|
691
|
+
SVFInstruction(ty, b, tm, false, k), varArg(va), calledVal(nullptr)
|
|
681
692
|
{
|
|
682
693
|
}
|
|
683
|
-
SVFCallInst(const std::string& i) = delete;
|
|
684
694
|
SVFCallInst(void) = delete;
|
|
685
695
|
|
|
686
696
|
static inline bool classof(const SVFValue *node)
|
|
@@ -752,8 +762,10 @@ protected:
|
|
|
752
762
|
}
|
|
753
763
|
|
|
754
764
|
public:
|
|
755
|
-
SVFVirtualCallInst(const
|
|
756
|
-
|
|
765
|
+
SVFVirtualCallInst(const SVFType* ty, const SVFBasicBlock* b, bool vararg,
|
|
766
|
+
bool tm)
|
|
767
|
+
: SVFCallInst(ty, b, vararg, tm, SVFVCall), vCallVtblPtr(nullptr),
|
|
768
|
+
virtualFunIdx(-1), funNameOfVcall()
|
|
757
769
|
{
|
|
758
770
|
}
|
|
759
771
|
inline const SVFValue* getVtablePtr() const
|
|
@@ -789,7 +801,7 @@ class SVFConstant : public SVFValue
|
|
|
789
801
|
friend class SVFIRWriter;
|
|
790
802
|
friend class SVFIRReader;
|
|
791
803
|
public:
|
|
792
|
-
SVFConstant(const
|
|
804
|
+
SVFConstant(const SVFType* ty, SVFValKind k = SVFConst): SVFValue(ty, k)
|
|
793
805
|
{
|
|
794
806
|
}
|
|
795
807
|
SVFConstant() = delete;
|
|
@@ -804,6 +816,8 @@ public:
|
|
|
804
816
|
node->getKind() == SVFNullPtr ||
|
|
805
817
|
node->getKind() == SVFBlackHole;
|
|
806
818
|
}
|
|
819
|
+
|
|
820
|
+
void print(OutStream& os) const override;
|
|
807
821
|
};
|
|
808
822
|
|
|
809
823
|
class SVFGlobalValue : public SVFConstant
|
|
@@ -822,11 +836,16 @@ protected:
|
|
|
822
836
|
}
|
|
823
837
|
|
|
824
838
|
public:
|
|
825
|
-
SVFGlobalValue(const
|
|
839
|
+
SVFGlobalValue(const SVFType* ty): SVFConstant(ty, SVFValue::SVFGlob), realDefGlobal(nullptr)
|
|
826
840
|
{
|
|
827
841
|
}
|
|
842
|
+
SVFGlobalValue(std::string&& name, const SVFType* ty) : SVFGlobalValue(ty)
|
|
843
|
+
{
|
|
844
|
+
setName(std::move(name));
|
|
845
|
+
}
|
|
828
846
|
SVFGlobalValue() = delete;
|
|
829
847
|
|
|
848
|
+
void print(OutStream& os) const override;
|
|
830
849
|
|
|
831
850
|
inline const SVFValue* getDefGlobalForMultipleModule() const
|
|
832
851
|
{
|
|
@@ -853,11 +872,16 @@ private:
|
|
|
853
872
|
u32_t argNo;
|
|
854
873
|
bool uncalled;
|
|
855
874
|
public:
|
|
856
|
-
SVFArgument(const
|
|
875
|
+
SVFArgument(const SVFType* ty, const SVFFunction* fun, u32_t argNo,
|
|
876
|
+
bool uncalled)
|
|
877
|
+
: SVFValue(ty, SVFValue::SVFArg), fun(fun), argNo(argNo),
|
|
878
|
+
uncalled(uncalled)
|
|
857
879
|
{
|
|
858
880
|
}
|
|
859
881
|
SVFArgument() = delete;
|
|
860
882
|
|
|
883
|
+
void print(OutStream& os) const override;
|
|
884
|
+
|
|
861
885
|
inline const SVFFunction* getParent() const
|
|
862
886
|
{
|
|
863
887
|
return fun;
|
|
@@ -881,18 +905,19 @@ public:
|
|
|
881
905
|
}
|
|
882
906
|
};
|
|
883
907
|
|
|
884
|
-
|
|
885
|
-
|
|
886
908
|
class SVFConstantData : public SVFConstant
|
|
887
909
|
{
|
|
888
910
|
friend class SVFIRWriter;
|
|
889
911
|
friend class SVFIRReader;
|
|
890
912
|
public:
|
|
891
|
-
SVFConstantData(const
|
|
913
|
+
SVFConstantData(const SVFType* ty, SVFValKind k = SVFConstData)
|
|
914
|
+
: SVFConstant(ty, k)
|
|
892
915
|
{
|
|
893
916
|
}
|
|
894
917
|
SVFConstantData() = delete;
|
|
895
918
|
|
|
919
|
+
void print(OutStream& os) const override;
|
|
920
|
+
|
|
896
921
|
static inline bool classof(const SVFValue *node)
|
|
897
922
|
{
|
|
898
923
|
return node->getKind() == SVFConstData ||
|
|
@@ -911,7 +936,6 @@ public:
|
|
|
911
936
|
}
|
|
912
937
|
};
|
|
913
938
|
|
|
914
|
-
|
|
915
939
|
class SVFConstantInt : public SVFConstantData
|
|
916
940
|
{
|
|
917
941
|
friend class SVFIRWriter;
|
|
@@ -920,11 +944,14 @@ private:
|
|
|
920
944
|
u64_t zval;
|
|
921
945
|
s64_t sval;
|
|
922
946
|
public:
|
|
923
|
-
SVFConstantInt(const
|
|
947
|
+
SVFConstantInt(const SVFType* ty, u64_t z, s64_t s)
|
|
948
|
+
: SVFConstantData(ty, SVFValue::SVFConstInt), zval(z), sval(s)
|
|
924
949
|
{
|
|
925
950
|
}
|
|
926
951
|
SVFConstantInt() = delete;
|
|
927
952
|
|
|
953
|
+
void print(OutStream& os) const override;
|
|
954
|
+
|
|
928
955
|
static inline bool classof(const SVFValue *node)
|
|
929
956
|
{
|
|
930
957
|
return node->getKind() == SVFConstInt;
|
|
@@ -945,7 +972,6 @@ public:
|
|
|
945
972
|
}
|
|
946
973
|
};
|
|
947
974
|
|
|
948
|
-
|
|
949
975
|
class SVFConstantFP : public SVFConstantData
|
|
950
976
|
{
|
|
951
977
|
friend class SVFIRWriter;
|
|
@@ -953,11 +979,14 @@ class SVFConstantFP : public SVFConstantData
|
|
|
953
979
|
private:
|
|
954
980
|
float dval;
|
|
955
981
|
public:
|
|
956
|
-
SVFConstantFP(const
|
|
982
|
+
SVFConstantFP(const SVFType* ty, double d)
|
|
983
|
+
: SVFConstantData(ty, SVFValue::SVFConstFP), dval(d)
|
|
957
984
|
{
|
|
958
985
|
}
|
|
959
986
|
SVFConstantFP() = delete;
|
|
960
987
|
|
|
988
|
+
void print(OutStream& os) const override;
|
|
989
|
+
|
|
961
990
|
inline double getFPValue () const
|
|
962
991
|
{
|
|
963
992
|
return dval;
|
|
@@ -972,18 +1001,20 @@ public:
|
|
|
972
1001
|
}
|
|
973
1002
|
};
|
|
974
1003
|
|
|
975
|
-
|
|
976
1004
|
class SVFConstantNullPtr : public SVFConstantData
|
|
977
1005
|
{
|
|
978
1006
|
friend class SVFIRWriter;
|
|
979
1007
|
friend class SVFIRReader;
|
|
980
1008
|
|
|
981
1009
|
public:
|
|
982
|
-
SVFConstantNullPtr(const
|
|
1010
|
+
SVFConstantNullPtr(const SVFType* ty)
|
|
1011
|
+
: SVFConstantData(ty, SVFValue::SVFNullPtr)
|
|
983
1012
|
{
|
|
984
1013
|
}
|
|
985
1014
|
SVFConstantNullPtr() = delete;
|
|
986
1015
|
|
|
1016
|
+
void print(OutStream& os) const override;
|
|
1017
|
+
|
|
987
1018
|
static inline bool classof(const SVFValue *node)
|
|
988
1019
|
{
|
|
989
1020
|
return node->getKind() == SVFNullPtr;
|
|
@@ -1000,11 +1031,14 @@ class SVFBlackHoleValue : public SVFConstantData
|
|
|
1000
1031
|
friend class SVFIRReader;
|
|
1001
1032
|
|
|
1002
1033
|
public:
|
|
1003
|
-
SVFBlackHoleValue(const
|
|
1034
|
+
SVFBlackHoleValue(const SVFType* ty)
|
|
1035
|
+
: SVFConstantData(ty, SVFValue::SVFBlackHole)
|
|
1004
1036
|
{
|
|
1005
1037
|
}
|
|
1006
1038
|
SVFBlackHoleValue() = delete;
|
|
1007
1039
|
|
|
1040
|
+
void print(OutStream& os) const override;
|
|
1041
|
+
|
|
1008
1042
|
static inline bool classof(const SVFValue *node)
|
|
1009
1043
|
{
|
|
1010
1044
|
return node->getKind() == SVFBlackHole;
|
|
@@ -1020,7 +1054,8 @@ class SVFOtherValue : public SVFValue
|
|
|
1020
1054
|
friend class SVFIRWriter;
|
|
1021
1055
|
friend class SVFIRReader;
|
|
1022
1056
|
public:
|
|
1023
|
-
SVFOtherValue(const
|
|
1057
|
+
SVFOtherValue(const SVFType* ty, SVFValKind k = SVFValue::SVFOther)
|
|
1058
|
+
: SVFValue(ty, k)
|
|
1024
1059
|
{
|
|
1025
1060
|
}
|
|
1026
1061
|
SVFOtherValue() = delete;
|
|
@@ -1029,6 +1064,8 @@ public:
|
|
|
1029
1064
|
{
|
|
1030
1065
|
return node->getKind() == SVFOther || node->getKind() == SVFMetaAsValue;
|
|
1031
1066
|
}
|
|
1067
|
+
|
|
1068
|
+
void print(OutStream& os) const override;
|
|
1032
1069
|
};
|
|
1033
1070
|
|
|
1034
1071
|
/*
|
|
@@ -1039,7 +1076,8 @@ class SVFMetadataAsValue : public SVFOtherValue
|
|
|
1039
1076
|
friend class SVFIRWriter;
|
|
1040
1077
|
friend class SVFIRReader;
|
|
1041
1078
|
public:
|
|
1042
|
-
SVFMetadataAsValue(const
|
|
1079
|
+
SVFMetadataAsValue(const SVFType* ty)
|
|
1080
|
+
: SVFOtherValue(ty, SVFValue::SVFMetaAsValue)
|
|
1043
1081
|
{
|
|
1044
1082
|
}
|
|
1045
1083
|
SVFMetadataAsValue() = delete;
|
|
@@ -1052,6 +1090,8 @@ public:
|
|
|
1052
1090
|
{
|
|
1053
1091
|
return node->getKind() == SVFMetaAsValue;
|
|
1054
1092
|
}
|
|
1093
|
+
|
|
1094
|
+
void print(OutStream& os) const override;
|
|
1055
1095
|
};
|
|
1056
1096
|
|
|
1057
1097
|
|
|
@@ -204,7 +204,7 @@ inline GrammarBase::Kind GrammarBase::insertNonterminalKind(std::string const ki
|
|
|
204
204
|
return kind;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
std::string GrammarBase::extractKindStrFromSymbolStr(const std::string symbolStr) const
|
|
207
|
+
std::string GrammarBase::extractKindStrFromSymbolStr(const std::string& symbolStr) const
|
|
208
208
|
{
|
|
209
209
|
std::string kindStr;
|
|
210
210
|
// symbolStr end with '_', the whole symbolStr treat as kind, not with attribute.
|
|
@@ -216,7 +216,7 @@ std::string GrammarBase::extractKindStrFromSymbolStr(const std::string symbolStr
|
|
|
216
216
|
return symbolStr.substr(0, underscorePosition);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
std::string GrammarBase::extractAttributeStrFromSymbolStr(const std::string symbolStr) const
|
|
219
|
+
std::string GrammarBase::extractAttributeStrFromSymbolStr(const std::string& symbolStr) const
|
|
220
220
|
{
|
|
221
221
|
std::string attributeStr;
|
|
222
222
|
// symbolStr end with '_', the whole symbolStr treat as kind, not with attribute.
|
|
@@ -43,45 +43,51 @@ SVFType* createSVFType(SVFType::GNodeK kind, bool isSingleValTy)
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
static SVFValue* createSVFValue(SVFValue::GNodeK kind, const SVFType* type,
|
|
46
|
-
|
|
46
|
+
std::string&& name)
|
|
47
47
|
{
|
|
48
|
-
|
|
48
|
+
auto creator = [=]() -> SVFValue*
|
|
49
49
|
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
50
|
+
switch (kind)
|
|
51
|
+
{
|
|
52
|
+
default:
|
|
53
|
+
ABORT_MSG(kind << " is an impossible SVFValueKind in create()");
|
|
54
|
+
case SVFValue::SVFVal:
|
|
55
|
+
ABORT_MSG("Creation of RAW SVFValue isn't allowed");
|
|
56
|
+
case SVFValue::SVFFunc:
|
|
57
|
+
return new SVFFunction(type, {}, {}, {}, {}, {}, {});
|
|
58
|
+
case SVFValue::SVFBB:
|
|
59
|
+
return new SVFBasicBlock(type, {});
|
|
60
|
+
case SVFValue::SVFInst:
|
|
61
|
+
return new SVFInstruction(type, {}, {}, {});
|
|
62
|
+
case SVFValue::SVFCall:
|
|
63
|
+
return new SVFCallInst(type, {}, {}, {});
|
|
64
|
+
case SVFValue::SVFVCall:
|
|
65
|
+
return new SVFVirtualCallInst(type, {}, {}, {});
|
|
66
|
+
case SVFValue::SVFGlob:
|
|
67
|
+
return new SVFGlobalValue(type);
|
|
68
|
+
case SVFValue::SVFArg:
|
|
69
|
+
return new SVFArgument(type, {}, {}, {});
|
|
70
|
+
case SVFValue::SVFConst:
|
|
71
|
+
return new SVFConstant(type);
|
|
72
|
+
case SVFValue::SVFConstData:
|
|
73
|
+
return new SVFConstantData(type);
|
|
74
|
+
case SVFValue::SVFConstInt:
|
|
75
|
+
return new SVFConstantInt(type, {}, {});
|
|
76
|
+
case SVFValue::SVFConstFP:
|
|
77
|
+
return new SVFConstantFP(type, {});
|
|
78
|
+
case SVFValue::SVFNullPtr:
|
|
79
|
+
return new SVFConstantNullPtr(type);
|
|
80
|
+
case SVFValue::SVFBlackHole:
|
|
81
|
+
return new SVFBlackHoleValue(type);
|
|
82
|
+
case SVFValue::SVFMetaAsValue:
|
|
83
|
+
return new SVFMetadataAsValue(type);
|
|
84
|
+
case SVFValue::SVFOther:
|
|
85
|
+
return new SVFOtherValue(type);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
auto val = creator();
|
|
89
|
+
val->setName(std::move(name));
|
|
90
|
+
return val;
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
template <typename SmallNumberType>
|
|
@@ -486,7 +492,9 @@ cJSON* SVFIRWriter::contentToJson(const SVFPointerType* type)
|
|
|
486
492
|
|
|
487
493
|
cJSON* SVFIRWriter::contentToJson(const SVFIntegerType* type)
|
|
488
494
|
{
|
|
489
|
-
|
|
495
|
+
cJSON* root = contentToJson(static_cast<const SVFType*>(type));
|
|
496
|
+
JSON_WRITE_FIELD(root, type, signAndWidth);
|
|
497
|
+
return root;
|
|
490
498
|
}
|
|
491
499
|
|
|
492
500
|
cJSON* SVFIRWriter::contentToJson(const SVFFunctionType* type)
|
|
@@ -1426,7 +1434,7 @@ const cJSON* SVFIRReader::createObjs(const cJSON* root)
|
|
|
1426
1434
|
JSON_DEF_READ_FWD(svfValueFldJson, SVFValue::GNodeK, kind);
|
|
1427
1435
|
JSON_DEF_READ_FWD(svfValueFldJson, const SVFType*, type, {});
|
|
1428
1436
|
JSON_DEF_READ_FWD(svfValueFldJson, std::string, name);
|
|
1429
|
-
return createSVFValue(kind, type, name);
|
|
1437
|
+
return createSVFValue(kind, type, std::move(name));
|
|
1430
1438
|
},
|
|
1431
1439
|
// SVFValue Filler
|
|
1432
1440
|
[this](const cJSON*& svfVarFldJson, SVFValue* value)
|
|
@@ -1528,6 +1536,11 @@ void SVFIRReader::readJson(const cJSON* obj, int& val)
|
|
|
1528
1536
|
readSmallNumber(obj, val);
|
|
1529
1537
|
}
|
|
1530
1538
|
|
|
1539
|
+
void SVFIRReader::readJson(const cJSON* obj, short& val)
|
|
1540
|
+
{
|
|
1541
|
+
readSmallNumber(obj, val);
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1531
1544
|
void SVFIRReader::readJson(const cJSON* obj, float& val)
|
|
1532
1545
|
{
|
|
1533
1546
|
readSmallNumber(obj, val);
|
|
@@ -2488,6 +2501,7 @@ void SVFIRReader::fill(const cJSON*& fieldJson, SVFPointerType* type)
|
|
|
2488
2501
|
void SVFIRReader::fill(const cJSON*& fieldJson, SVFIntegerType* type)
|
|
2489
2502
|
{
|
|
2490
2503
|
fill(fieldJson, static_cast<SVFType*>(type));
|
|
2504
|
+
JSON_READ_FIELD_FWD(fieldJson, type, signAndWidth);
|
|
2491
2505
|
}
|
|
2492
2506
|
|
|
2493
2507
|
void SVFIRReader::fill(const cJSON*& fieldJson, SVFFunctionType* type)
|
|
@@ -10,42 +10,43 @@ std::string SVFType::toString() const
|
|
|
10
10
|
return os.str();
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
std::ostream& operator<<(std::ostream&
|
|
13
|
+
std::ostream& operator<<(std::ostream& os, const SVFType& type)
|
|
14
14
|
{
|
|
15
|
-
type.print(
|
|
16
|
-
return
|
|
15
|
+
type.print(os);
|
|
16
|
+
return os;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
void SVFPointerType::print(std::ostream&
|
|
19
|
+
void SVFPointerType::print(std::ostream& os) const
|
|
20
20
|
{
|
|
21
|
-
getPtrElementType()
|
|
22
|
-
OS << "*";
|
|
21
|
+
os << *getPtrElementType() << '*';
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
void SVFIntegerType::print(std::ostream&
|
|
24
|
+
void SVFIntegerType::print(std::ostream& os) const
|
|
26
25
|
{
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
if (signAndWidth < 0)
|
|
27
|
+
os << 'i' << -signAndWidth;
|
|
28
|
+
else
|
|
29
|
+
os << 'u' << signAndWidth;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
void SVFFunctionType::print(std::ostream&
|
|
32
|
+
void SVFFunctionType::print(std::ostream& os) const
|
|
32
33
|
{
|
|
33
|
-
|
|
34
|
+
os << *getReturnType() << "()";
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
void SVFStructType::print(std::ostream&
|
|
37
|
+
void SVFStructType::print(std::ostream& os) const
|
|
37
38
|
{
|
|
38
|
-
|
|
39
|
+
os << "S." << name;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
void SVFArrayType::print(std::ostream&
|
|
42
|
+
void SVFArrayType::print(std::ostream& os) const
|
|
42
43
|
{
|
|
43
|
-
|
|
44
|
+
os << '[' << numOfElement << 'x' << *typeOfElement << ']';
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
void SVFOtherType::print(std::ostream&
|
|
47
|
+
void SVFOtherType::print(std::ostream& os) const
|
|
47
48
|
{
|
|
48
|
-
|
|
49
|
+
os << repr;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
} // namespace SVF
|
|
@@ -122,10 +122,17 @@ bool SVFLoopAndDomInfo::isLoopHeader(const SVFBasicBlock* bb) const
|
|
|
122
122
|
return false;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
std::string SVFValue::toString() const
|
|
126
|
+
{
|
|
127
|
+
std::ostringstream os;
|
|
128
|
+
print(os);
|
|
129
|
+
return os.str();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
SVFFunction::SVFFunction(const SVFType* ty, const SVFFunctionType* ft,
|
|
133
|
+
bool declare, bool intrinsic, bool adt, bool varg,
|
|
134
|
+
SVFLoopAndDomInfo* ld)
|
|
135
|
+
: SVFValue(ty, SVFValue::SVFFunc), isDecl(declare), intrinsic(intrinsic),
|
|
129
136
|
addrTaken(adt), isUncalled(false), isNotRet(false), varArg(varg),
|
|
130
137
|
funcType(ft), loopAndDom(ld), realDefFun(nullptr)
|
|
131
138
|
{
|
|
@@ -156,8 +163,8 @@ bool SVFFunction::isVarArg() const
|
|
|
156
163
|
return varArg;
|
|
157
164
|
}
|
|
158
165
|
|
|
159
|
-
SVFBasicBlock::SVFBasicBlock(const
|
|
160
|
-
SVFValue(
|
|
166
|
+
SVFBasicBlock::SVFBasicBlock(const SVFType* ty, const SVFFunction* f)
|
|
167
|
+
: SVFValue(ty, SVFValue::SVFBB), fun(f)
|
|
161
168
|
{
|
|
162
169
|
}
|
|
163
170
|
|
|
@@ -231,7 +238,96 @@ u32_t SVFBasicBlock::getBBPredecessorPos(const SVFBasicBlock* succbb) const
|
|
|
231
238
|
return pos;
|
|
232
239
|
}
|
|
233
240
|
|
|
234
|
-
SVFInstruction::SVFInstruction(const
|
|
235
|
-
|
|
241
|
+
SVFInstruction::SVFInstruction(const SVFType* ty, const SVFBasicBlock* b,
|
|
242
|
+
bool tm, bool isRet, SVFValKind k)
|
|
243
|
+
: SVFValue(ty, k), bb(b), terminator(tm), ret(isRet)
|
|
244
|
+
{
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
void SVFFunction::print(OutStream& os) const
|
|
248
|
+
{
|
|
249
|
+
os << "fun " << getName();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
void SVFBasicBlock::print(OutStream& os) const
|
|
253
|
+
{
|
|
254
|
+
os << "BB";
|
|
255
|
+
if (!getName().empty())
|
|
256
|
+
os << ' ' << getName();
|
|
257
|
+
os << " in " << getFunction()->getName();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
void SVFInstruction::print(OutStream& os) const
|
|
261
|
+
{
|
|
262
|
+
os << '`' << getName() << "` in " << getFunction()->getName();
|
|
263
|
+
const std::string& bbName = getParent()->getName();
|
|
264
|
+
if (bbName.size())
|
|
265
|
+
os << " BB " << bbName;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
void SVFConstant::print(OutStream& os) const
|
|
236
269
|
{
|
|
237
|
-
|
|
270
|
+
os << "Const " << getName();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
void SVFGlobalValue::print(OutStream& os) const
|
|
274
|
+
{
|
|
275
|
+
os << "@" << getName();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
void SVFArgument::print(OutStream& os) const
|
|
279
|
+
{
|
|
280
|
+
os << "arg %" << getName() << " of " << getParent()->getName();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
void SVFConstantData::print(OutStream& os) const
|
|
284
|
+
{
|
|
285
|
+
// N.B. Haven't found instance of this class so far
|
|
286
|
+
os << "ConstData " << getName();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
void SVFConstantInt::print(OutStream& os) const
|
|
290
|
+
{
|
|
291
|
+
os << "ConstInt ";
|
|
292
|
+
if (!getName().empty())
|
|
293
|
+
os << getName() << ' ';
|
|
294
|
+
auto ty = dyn_cast<SVFIntegerType>(getType());
|
|
295
|
+
assert(ty && "ConstantInt has non-integer type?");
|
|
296
|
+
os << *ty << ' ';
|
|
297
|
+
if (ty->isSigned())
|
|
298
|
+
os << getSExtValue();
|
|
299
|
+
else
|
|
300
|
+
os << getZExtValue();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
void SVFConstantFP::print(OutStream& os) const
|
|
304
|
+
{
|
|
305
|
+
os << "ConstFP ";
|
|
306
|
+
if (!getName().empty())
|
|
307
|
+
os << getName() << ' ';
|
|
308
|
+
os << *getType() << ' ' << getFPValue();
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
void SVFConstantNullPtr::print(OutStream& os) const
|
|
312
|
+
{
|
|
313
|
+
os << "ConstNull " << *getType();
|
|
314
|
+
if (!getName().empty())
|
|
315
|
+
os << ' ' << getName();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
void SVFBlackHoleValue::print(OutStream& os) const
|
|
319
|
+
{
|
|
320
|
+
os << "BlackHole " << *getType();
|
|
321
|
+
if (!getName().empty())
|
|
322
|
+
os << ' ' << getName();
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
void SVFOtherValue::print(OutStream& os) const
|
|
326
|
+
{
|
|
327
|
+
os << "OtherVal " << getName();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
void SVFMetadataAsValue::print(OutStream& os) const
|
|
331
|
+
{
|
|
332
|
+
os << "MetaDataVal " << getName();
|
|
333
|
+
}
|
package/svf/lib/Util/CppUtil.cpp
CHANGED
|
@@ -41,7 +41,7 @@ const std::string vtblLabelAfterDemangle = "vtable for ";
|
|
|
41
41
|
const std::string NVThunkFunLabel = "non-virtual thunk to ";
|
|
42
42
|
const std::string VThunkFuncLabel = "virtual thunk to ";
|
|
43
43
|
|
|
44
|
-
static bool isOperOverload(const std::string name)
|
|
44
|
+
static bool isOperOverload(const std::string& name)
|
|
45
45
|
{
|
|
46
46
|
u32_t leftnum = 0, rightnum = 0;
|
|
47
47
|
std::string subname = name;
|
|
@@ -54,13 +54,13 @@ public:
|
|
|
54
54
|
void buildInternalMaps();
|
|
55
55
|
void readInheritanceMetadataFromModule(const Module &M);
|
|
56
56
|
|
|
57
|
-
CHNode *createNode(const std::string name);
|
|
57
|
+
CHNode *createNode(const std::string& name);
|
|
58
58
|
|
|
59
59
|
void connectInheritEdgeViaCall(const Function* caller, const CallBase* cs);
|
|
60
60
|
void connectInheritEdgeViaStore(const Function* caller, const StoreInst* store);
|
|
61
61
|
|
|
62
62
|
void buildClassNameToAncestorsDescendantsMap();
|
|
63
|
-
const CHGraph::CHNodeSetTy& getInstancesAndDescendants(const std::string className);
|
|
63
|
+
const CHGraph::CHNodeSetTy& getInstancesAndDescendants(const std::string& className);
|
|
64
64
|
|
|
65
65
|
void analyzeVTables(const Module &M);
|
|
66
66
|
void buildVirtualFunctionToIDMap();
|
|
@@ -482,6 +482,13 @@ bool VCallInCtorOrDtor(const CallBase* cs);
|
|
|
482
482
|
bool isSameThisPtrInConstructor(const Argument* thisPtr1,
|
|
483
483
|
const Value* thisPtr2);
|
|
484
484
|
|
|
485
|
+
template<typename T>
|
|
486
|
+
std::string llvmToString(const T& val)
|
|
487
|
+
{
|
|
488
|
+
std::string str;
|
|
489
|
+
llvm::raw_string_ostream(str) << val;
|
|
490
|
+
return str;
|
|
491
|
+
}
|
|
485
492
|
} // End namespace LLVMUtil
|
|
486
493
|
|
|
487
494
|
} // End namespace SVF
|
|
@@ -232,7 +232,7 @@ void CHGBuilder::readInheritanceMetadataFromModule(const Module &M)
|
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
CHNode *CHGBuilder::createNode(const std::string className)
|
|
235
|
+
CHNode *CHGBuilder::createNode(const std::string& className)
|
|
236
236
|
{
|
|
237
237
|
assert(!chg->getNode(className) && "this node should never be created before!");
|
|
238
238
|
CHNode * node = new CHNode(className, chg->classNum++);
|
|
@@ -292,8 +292,8 @@ void CHGBuilder::buildClassNameToAncestorsDescendantsMap()
|
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
|
|
296
|
-
const
|
|
295
|
+
const CHGraph::CHNodeSetTy& CHGBuilder::getInstancesAndDescendants(
|
|
296
|
+
const string& className)
|
|
297
297
|
{
|
|
298
298
|
|
|
299
299
|
CHGraph::NameToCHNodesMap::const_iterator it = chg->classNameToInstAndDescsMap.find(className);
|
|
@@ -72,6 +72,19 @@ using namespace SVF;
|
|
|
72
72
|
LLVMModuleSet* LLVMModuleSet::llvmModuleSet = nullptr;
|
|
73
73
|
bool LLVMModuleSet::preProcessed = false;
|
|
74
74
|
|
|
75
|
+
/// Helper function to summarize a long string
|
|
76
|
+
static void shortenLongInfo(std::string& info, unsigned bestLen = 15)
|
|
77
|
+
{
|
|
78
|
+
if (info.size() <= bestLen)
|
|
79
|
+
return;
|
|
80
|
+
// If it is of form "name = value", keep on the name part
|
|
81
|
+
size_t index = info.find(" =");
|
|
82
|
+
if (index != std::string::npos)
|
|
83
|
+
info.resize(index);
|
|
84
|
+
else
|
|
85
|
+
info.resize(bestLen);
|
|
86
|
+
}
|
|
87
|
+
|
|
75
88
|
LLVMModuleSet::LLVMModuleSet()
|
|
76
89
|
: symInfo(SymbolTableInfo::SymbolInfo()),
|
|
77
90
|
svfModule(SVFModule::getSVFModule()), cxts(nullptr)
|
|
@@ -159,27 +172,36 @@ void LLVMModuleSet::createSVFDataStructure()
|
|
|
159
172
|
for (const Function& func : mod.functions())
|
|
160
173
|
{
|
|
161
174
|
SVFFunction* svfFunc = new SVFFunction(
|
|
162
|
-
|
|
175
|
+
getSVFType(func.getType()),
|
|
163
176
|
SVFUtil::cast<SVFFunctionType>(
|
|
164
177
|
getSVFType(func.getFunctionType())),
|
|
165
178
|
func.isDeclaration(), LLVMUtil::isIntrinsicFun(&func),
|
|
166
179
|
func.hasAddressTaken(), func.isVarArg(), new SVFLoopAndDomInfo);
|
|
180
|
+
svfFunc->setName(func.getName().str());
|
|
167
181
|
svfModule->addFunctionSet(svfFunc);
|
|
168
182
|
addFunctionMap(&func, svfFunc);
|
|
169
183
|
|
|
170
184
|
for (const Argument& arg : func.args())
|
|
171
185
|
{
|
|
172
186
|
SVFArgument* svfarg = new SVFArgument(
|
|
173
|
-
arg.
|
|
174
|
-
|
|
187
|
+
getSVFType(arg.getType()), svfFunc, arg.getArgNo(),
|
|
188
|
+
LLVMUtil::isArgOfUncalledFunction(&arg));
|
|
189
|
+
// Setting up arg name
|
|
190
|
+
if (arg.hasName())
|
|
191
|
+
svfarg->setName(arg.getName().str());
|
|
192
|
+
else
|
|
193
|
+
svfarg->setName(std::to_string(arg.getArgNo()));
|
|
194
|
+
|
|
175
195
|
svfFunc->addArgument(svfarg);
|
|
176
196
|
addArgumentMap(&arg, svfarg);
|
|
177
197
|
}
|
|
178
198
|
|
|
179
199
|
for (const BasicBlock& bb : func)
|
|
180
200
|
{
|
|
181
|
-
SVFBasicBlock* svfBB =
|
|
182
|
-
|
|
201
|
+
SVFBasicBlock* svfBB =
|
|
202
|
+
new SVFBasicBlock(getSVFType(bb.getType()), svfFunc);
|
|
203
|
+
if (bb.hasName())
|
|
204
|
+
svfBB->setName(bb.getName().str());
|
|
183
205
|
svfFunc->addBasicBlock(svfBB);
|
|
184
206
|
addBasicBlockMap(&bb, svfBB);
|
|
185
207
|
for (const Instruction& inst : bb)
|
|
@@ -189,23 +211,36 @@ void LLVMModuleSet::createSVFDataStructure()
|
|
|
189
211
|
{
|
|
190
212
|
if (LLVMUtil::isVirtualCallSite(call))
|
|
191
213
|
svfInst = new SVFVirtualCallInst(
|
|
192
|
-
call->getName().str(),
|
|
193
214
|
getSVFType(call->getType()), svfBB,
|
|
194
215
|
call->getFunctionType()->isVarArg(),
|
|
195
216
|
inst.isTerminator());
|
|
196
217
|
else
|
|
197
218
|
svfInst = new SVFCallInst(
|
|
198
|
-
call->getName().str(),
|
|
199
219
|
getSVFType(call->getType()), svfBB,
|
|
200
220
|
call->getFunctionType()->isVarArg(),
|
|
201
221
|
inst.isTerminator());
|
|
202
222
|
}
|
|
203
223
|
else
|
|
204
224
|
{
|
|
205
|
-
svfInst =
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
225
|
+
svfInst =
|
|
226
|
+
new SVFInstruction(getSVFType(inst.getType()),
|
|
227
|
+
svfBB, inst.isTerminator(),
|
|
228
|
+
SVFUtil::isa<ReturnInst>(inst));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Set instruction's string representation
|
|
232
|
+
if (inst.hasName() && !inst.getName().empty())
|
|
233
|
+
{
|
|
234
|
+
svfInst->setName(inst.getName().str());
|
|
235
|
+
}
|
|
236
|
+
else
|
|
237
|
+
{
|
|
238
|
+
std::string str = LLVMUtil::llvmToString(inst);
|
|
239
|
+
auto it = str.begin(), ite = str.end();
|
|
240
|
+
while (it != ite && std::isspace(*it))
|
|
241
|
+
++it;
|
|
242
|
+
// 0xf (15) is the max length a local string can hold
|
|
243
|
+
svfInst->setName({it, std::min(it + 0xf, ite)});
|
|
209
244
|
}
|
|
210
245
|
svfBB->addInstruction(svfInst);
|
|
211
246
|
addInstructionMap(&inst, svfInst);
|
|
@@ -850,25 +885,30 @@ SVFConstantData* LLVMModuleSet::getSVFConstantData(const ConstantData* cd)
|
|
|
850
885
|
/// bitwidth <=64 1 : cint has value from getSExtValue()
|
|
851
886
|
/// bitwidth >64 1 : cint has value 0 because it represents an invalid int
|
|
852
887
|
if(cint->getBitWidth() == 1)
|
|
853
|
-
svfcd = new SVFConstantInt(
|
|
888
|
+
svfcd = new SVFConstantInt(getSVFType(cint->getType()), cint->getZExtValue(), cint->getZExtValue());
|
|
854
889
|
else if(cint->getBitWidth() <= 64 && cint->getBitWidth() > 1)
|
|
855
|
-
svfcd = new SVFConstantInt(
|
|
890
|
+
svfcd = new SVFConstantInt(getSVFType(cint->getType()), cint->getZExtValue(), cint->getSExtValue());
|
|
856
891
|
else
|
|
857
|
-
svfcd = new SVFConstantInt(
|
|
892
|
+
svfcd = new SVFConstantInt(getSVFType(cint->getType()), 0, 0);
|
|
858
893
|
}
|
|
859
894
|
else if(const ConstantFP* cfp = SVFUtil::dyn_cast<ConstantFP>(cd))
|
|
860
895
|
{
|
|
861
896
|
double dval = 0;
|
|
897
|
+
// TODO: Why only double is considered? What about float?
|
|
862
898
|
if(cfp->isNormalFP() && (&cfp->getValueAPF().getSemantics()== &llvm::APFloatBase::IEEEdouble()))
|
|
863
899
|
dval = cfp->getValueAPF().convertToDouble();
|
|
864
|
-
svfcd = new SVFConstantFP(
|
|
900
|
+
svfcd = new SVFConstantFP(getSVFType(cd->getType()), dval);
|
|
865
901
|
}
|
|
866
902
|
else if(SVFUtil::isa<ConstantPointerNull>(cd))
|
|
867
|
-
svfcd = new SVFConstantNullPtr(
|
|
903
|
+
svfcd = new SVFConstantNullPtr(getSVFType(cd->getType()));
|
|
868
904
|
else if (SVFUtil::isa<UndefValue>(cd))
|
|
869
|
-
svfcd = new SVFBlackHoleValue(
|
|
905
|
+
svfcd = new SVFBlackHoleValue(getSVFType(cd->getType()));
|
|
870
906
|
else
|
|
871
|
-
svfcd = new SVFConstantData(
|
|
907
|
+
svfcd = new SVFConstantData(getSVFType(cd->getType()));
|
|
908
|
+
|
|
909
|
+
if (cd->hasName())
|
|
910
|
+
svfcd->setName(cd->getName().str());
|
|
911
|
+
|
|
872
912
|
svfModule->addConstant(svfcd);
|
|
873
913
|
addConstantDataMap(cd,svfcd);
|
|
874
914
|
return svfcd;
|
|
@@ -884,9 +924,32 @@ SVFConstant* LLVMModuleSet::getOtherSVFConstant(const Constant* oc)
|
|
|
884
924
|
}
|
|
885
925
|
else
|
|
886
926
|
{
|
|
887
|
-
SVFConstant* svfoc = new SVFConstant(
|
|
927
|
+
SVFConstant* svfoc = new SVFConstant(getSVFType(oc->getType()));
|
|
888
928
|
svfModule->addConstant(svfoc);
|
|
889
929
|
addOtherConstantMap(oc,svfoc);
|
|
930
|
+
|
|
931
|
+
// Setting up string representation.
|
|
932
|
+
// Usually is a bitcast from a global variable's address
|
|
933
|
+
std::string str = LLVMUtil::llvmToString(*oc);
|
|
934
|
+
const char* spaceChars = " \t\n\v\f\r";
|
|
935
|
+
size_t space = str.find_first_of(spaceChars);
|
|
936
|
+
const int maxLen = 62; // Arbitrary chosen small number that fits string
|
|
937
|
+
// within one line
|
|
938
|
+
if (space != str.npos &&
|
|
939
|
+
(space = str.find_first_of(spaceChars, space + 1)) != str.npos)
|
|
940
|
+
{
|
|
941
|
+
size_t name = str.find('@', space);
|
|
942
|
+
str.erase(space, name - space);
|
|
943
|
+
}
|
|
944
|
+
else if (str.size() > maxLen)
|
|
945
|
+
{
|
|
946
|
+
int extra = str.size() - maxLen;
|
|
947
|
+
int half = maxLen / 2;
|
|
948
|
+
str[half++] = '~';
|
|
949
|
+
str.erase(half, half + extra);
|
|
950
|
+
}
|
|
951
|
+
svfoc->setName(std::move(str));
|
|
952
|
+
|
|
890
953
|
return svfoc;
|
|
891
954
|
}
|
|
892
955
|
}
|
|
@@ -900,11 +963,18 @@ SVFOtherValue* LLVMModuleSet::getSVFOtherValue(const Value* ov)
|
|
|
900
963
|
}
|
|
901
964
|
else
|
|
902
965
|
{
|
|
903
|
-
SVFOtherValue* svfov =
|
|
904
|
-
|
|
905
|
-
|
|
966
|
+
SVFOtherValue* svfov =
|
|
967
|
+
SVFUtil::isa<MetadataAsValue>(ov)
|
|
968
|
+
? new SVFMetadataAsValue(getSVFType(ov->getType()))
|
|
969
|
+
: new SVFOtherValue(getSVFType(ov->getType()));
|
|
970
|
+
if (ov->hasName())
|
|
971
|
+
svfov->setName(ov->getName().str());
|
|
906
972
|
else
|
|
907
|
-
|
|
973
|
+
{
|
|
974
|
+
auto str = LLVMUtil::llvmToString(*ov);
|
|
975
|
+
shortenLongInfo(str, 30);
|
|
976
|
+
svfov->setName(std::move(str));
|
|
977
|
+
}
|
|
908
978
|
svfModule->addOtherValue(svfov);
|
|
909
979
|
addOtherValueMap(ov,svfov);
|
|
910
980
|
return svfov;
|
|
@@ -1008,15 +1078,21 @@ SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T)
|
|
|
1008
1078
|
SVFType* svftype;
|
|
1009
1079
|
if (const PointerType* pt = SVFUtil::dyn_cast<PointerType>(T))
|
|
1010
1080
|
svftype = new SVFPointerType(getSVFType(LLVMUtil::getPtrElementType(pt)));
|
|
1011
|
-
else if (SVFUtil::
|
|
1012
|
-
|
|
1081
|
+
else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
|
|
1082
|
+
{
|
|
1083
|
+
auto svfIntT = new SVFIntegerType();
|
|
1084
|
+
unsigned signWidth = intT->getBitWidth();
|
|
1085
|
+
assert(signWidth < INT16_MAX && "Integer width too big");
|
|
1086
|
+
svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
|
|
1087
|
+
svftype = svfIntT;
|
|
1088
|
+
}
|
|
1013
1089
|
else if (const FunctionType* ft = SVFUtil::dyn_cast<FunctionType>(T))
|
|
1014
1090
|
svftype = new SVFFunctionType(getSVFType(ft->getReturnType()));
|
|
1015
1091
|
else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
|
|
1016
1092
|
{
|
|
1017
1093
|
auto svfst = new SVFStructType();
|
|
1018
|
-
if(st->hasName())
|
|
1019
|
-
svfst->
|
|
1094
|
+
if (st->hasName())
|
|
1095
|
+
svfst->setName(st->getName().str());
|
|
1020
1096
|
svftype = svfst;
|
|
1021
1097
|
}
|
|
1022
1098
|
else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
|
|
@@ -1028,8 +1104,10 @@ SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T)
|
|
|
1028
1104
|
}
|
|
1029
1105
|
else
|
|
1030
1106
|
{
|
|
1107
|
+
std::string buffer;
|
|
1031
1108
|
auto ot = new SVFOtherType(T->isSingleValueType());
|
|
1032
|
-
llvm::raw_string_ostream(
|
|
1109
|
+
llvm::raw_string_ostream(buffer) << *T;
|
|
1110
|
+
ot->setRepr(std::move(buffer));
|
|
1033
1111
|
svftype = ot;
|
|
1034
1112
|
}
|
|
1035
1113
|
|
|
@@ -560,7 +560,7 @@ const std::string LLVMUtil::getSourceLoc(const Value* val )
|
|
|
560
560
|
}
|
|
561
561
|
else
|
|
562
562
|
{
|
|
563
|
-
rawstr << "
|
|
563
|
+
rawstr << "N/A";
|
|
564
564
|
}
|
|
565
565
|
rawstr << " }";
|
|
566
566
|
|
|
@@ -1039,20 +1039,15 @@ s32_t LLVMUtil::getVCallIdx(const CallBase* cs)
|
|
|
1039
1039
|
|
|
1040
1040
|
namespace SVF
|
|
1041
1041
|
{
|
|
1042
|
-
const std::string SVFValue::toString() const
|
|
1043
|
-
{
|
|
1044
|
-
// TODO: Should only use info in SVFValue. Refactor it later.
|
|
1045
|
-
return dumpLLVMValue(this);
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
1042
|
std::string dumpLLVMValue(const SVFValue* svfValue)
|
|
1049
1043
|
{
|
|
1050
1044
|
std::string str;
|
|
1051
1045
|
llvm::raw_string_ostream rawstr(str);
|
|
1052
1046
|
if (LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfValue) == nullptr)
|
|
1053
1047
|
{
|
|
1054
|
-
assert((SVFUtil::isa<SVFInstruction>(svfValue)
|
|
1055
|
-
|
|
1048
|
+
assert((SVFUtil::isa<SVFInstruction, SVFBasicBlock>(svfValue)) &&
|
|
1049
|
+
"Manually created SVF call inst, actual parameter and "
|
|
1050
|
+
"BasicBlock by ExtAPI do not have LLVM value!");
|
|
1056
1051
|
rawstr << svfValue->getName();
|
|
1057
1052
|
return rawstr.str();
|
|
1058
1053
|
}
|
|
@@ -1079,11 +1074,8 @@ std::string dumpLLVMValue(const SVFValue* svfValue)
|
|
|
1079
1074
|
|
|
1080
1075
|
std::string dumpLLVMType(const SVFType* svfType)
|
|
1081
1076
|
{
|
|
1082
|
-
std::string str;
|
|
1083
|
-
llvm::raw_string_ostream rawstr(str);
|
|
1084
1077
|
const Type* ty = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(svfType);
|
|
1085
|
-
|
|
1086
|
-
return rawstr.str();
|
|
1078
|
+
return LLVMUtil::llvmToString(*ty);
|
|
1087
1079
|
}
|
|
1088
1080
|
|
|
1089
1081
|
} // namespace SVF
|
|
@@ -135,7 +135,10 @@ NodeID SVFIRBuilder::getExtID(ExtAPI::OperationType operationType, const std::st
|
|
|
135
135
|
}
|
|
136
136
|
// return value = -6 is an illegal operand format
|
|
137
137
|
else
|
|
138
|
+
{
|
|
138
139
|
assert(false && "The operand format of function operation is illegal!");
|
|
140
|
+
abort();
|
|
141
|
+
}
|
|
139
142
|
}
|
|
140
143
|
|
|
141
144
|
void SVFIRBuilder::parseAtomaticOp(SVF::ExtAPI::Operand &atomaticOp, const SVFCallInst* svfCall, std::map<std::string, NodeID> &nodeIDMap)
|
|
@@ -214,8 +217,8 @@ void SVFIRBuilder::parseExtFunctionOps(ExtAPI::ExtFunctionOps &extFunctionOps, c
|
|
|
214
217
|
|
|
215
218
|
SVFCallInst* SVFIRBuilder::addSVFExtCallInst(const SVFCallInst* svfInst, SVFBasicBlock* svfBB, const SVFFunction* svfCaller, const SVFFunction* svfCallee)
|
|
216
219
|
{
|
|
217
|
-
SVFCallInst* svfCall = new SVFCallInst(
|
|
218
|
-
|
|
220
|
+
SVFCallInst* svfCall = new SVFCallInst(svfCallee->getFunctionType(), svfBB, false, false);
|
|
221
|
+
svfCall->setName("ext_inst");
|
|
219
222
|
LLVMModuleSet::getLLVMModuleSet()->SVFValue2LLVMValue[svfCall] = nullptr;
|
|
220
223
|
svfCall->setCalledOperand(svfCallee);
|
|
221
224
|
setCurrentLocation(svfCall, svfBB);
|
|
@@ -293,8 +296,8 @@ SVFInstruction* SVFIRBuilder::addSVFExtInst(const std::string& instName, const S
|
|
|
293
296
|
}
|
|
294
297
|
|
|
295
298
|
assert(ptType != nullptr && "At least one argument of an external call is of pointer type!");
|
|
296
|
-
SVFInstruction* inst = new SVFInstruction(
|
|
297
|
-
|
|
299
|
+
SVFInstruction* inst = new SVFInstruction(ptType, svfBB, false, false);
|
|
300
|
+
inst->setName(instName);
|
|
298
301
|
LLVMModuleSet::getLLVMModuleSet()->SVFValue2LLVMValue[inst] = nullptr;
|
|
299
302
|
svfBB->addInstruction(inst);
|
|
300
303
|
SymbolTableInfo::ValueToIDMapTy::iterator iter = pag->getSymbolInfo()->valSyms().find(inst);
|
|
@@ -327,8 +330,8 @@ SVFBasicBlock* SVFIRBuilder::extFuncInitialization(const SVFCallInst* svfInst, S
|
|
|
327
330
|
pag->addFunArgs(svfCaller,pag->getGNode(dstFA));
|
|
328
331
|
}
|
|
329
332
|
|
|
330
|
-
SVFBasicBlock* svfBB = new SVFBasicBlock(
|
|
331
|
-
|
|
333
|
+
SVFBasicBlock* svfBB = new SVFBasicBlock(svfInst->getParent()->getType(), svfCaller);
|
|
334
|
+
svfBB->setName("ext_bb");
|
|
332
335
|
LLVMModuleSet::getLLVMModuleSet()->SVFValue2LLVMValue[svfBB] = nullptr;
|
|
333
336
|
|
|
334
337
|
if (!svfCaller->isNotRetFunction())
|