svf-lib 1.0.982 → 1.0.983
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/SVF-linux/Release-build/lib/libSvf.a +0 -0
- package/SVF-linux/include/CFL/CFGNormalizer.h +70 -0
- package/SVF-linux/include/CFL/CFLAlias.h +124 -0
- package/SVF-linux/include/CFL/CFLGrammar.h +127 -0
- package/SVF-linux/include/CFL/CFLSolver.h +94 -0
- package/SVF-linux/include/CFL/GrammarBuilder.h +65 -0
- package/SVF-linux/include/Graphs/CFLGraph.h +175 -0
- package/SVF-linux/include/Graphs/IRGraph.h +1 -1
- package/SVF-linux/include/MemoryModel/PointerAnalysis.h +3 -3
- package/SVF-linux/include/SABER/SrcSnkDDA.h +3 -2
- package/SVF-linux/include/Util/GraphReachSolver.h +186 -0
- package/SVF-linux/include/Util/Options.h +6 -0
- package/package.json +1 -1
|
Binary file
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//===----- CFGNormalizer.h -- CFL Alias Analysis Client--------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* CFGNormalizer.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: April 19 , 2022
|
|
27
|
+
* Author: Pei Xu
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef CFGNormalizer_H_
|
|
31
|
+
#define CFGNormalizer_H_
|
|
32
|
+
|
|
33
|
+
#include "CFLGrammar.h"
|
|
34
|
+
|
|
35
|
+
namespace SVF{
|
|
36
|
+
|
|
37
|
+
/*!
|
|
38
|
+
* Normalize Grammar from a grammarbase
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
class CFGNormalizer {
|
|
42
|
+
|
|
43
|
+
public:
|
|
44
|
+
typedef u32_t Symbol;
|
|
45
|
+
typedef std::vector<Symbol> Production;
|
|
46
|
+
typedef Set<Production> Productions;
|
|
47
|
+
|
|
48
|
+
CFGNormalizer(){
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// Start Normalize (BIN Only)
|
|
52
|
+
// TODO: Add different Combination Transformation Option
|
|
53
|
+
CFLGrammar* normalize(GrammarBase *generalGrammar);
|
|
54
|
+
private:
|
|
55
|
+
|
|
56
|
+
void ebnf_bin(GrammarBase *generalGrammar, CFLGrammar *grammar);
|
|
57
|
+
|
|
58
|
+
void ebnf_sign_replace(char sign, GrammarBase* generalGrammar, CFLGrammar *grammar);
|
|
59
|
+
|
|
60
|
+
int ebnf_bracket_match(Production& prod, int i, CFLGrammar *grammar) ;
|
|
61
|
+
|
|
62
|
+
Production strTrans(std::string strPro, CFLGrammar *grammar);
|
|
63
|
+
|
|
64
|
+
int check_head(Map<Symbol, Productions>& grammar, Production& rule);
|
|
65
|
+
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
} // End namespace SVF
|
|
69
|
+
|
|
70
|
+
#endif /* CFGNormalizer_H_*/
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
//===----- CFLAlias.h -- CFL Alias Analysis Client--------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* CFLAlias.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: March 5, 2022
|
|
27
|
+
* Author: Yulei Sui
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
#include "CFL/CFLSolver.h"
|
|
32
|
+
#include "CFL/CFGNormalizer.h"
|
|
33
|
+
#include "CFL/GrammarBuilder.h"
|
|
34
|
+
#include "MemoryModel/PointerAnalysis.h"
|
|
35
|
+
#include "Graphs/ConsG.h"
|
|
36
|
+
#include "Util/Options.h"
|
|
37
|
+
|
|
38
|
+
namespace SVF{
|
|
39
|
+
|
|
40
|
+
class CFLAlias : public PointerAnalysis{
|
|
41
|
+
|
|
42
|
+
public:
|
|
43
|
+
CFLAlias(SVFIR* ir) : PointerAnalysis(ir, PointerAnalysis::CFLFICI_WPA), svfir(ir), graph(nullptr), grammar(nullptr), solver(nullptr){
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/// Destructor
|
|
47
|
+
virtual ~CFLAlias(){
|
|
48
|
+
delete graph;
|
|
49
|
+
delete grammar;
|
|
50
|
+
delete solver;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// Start Analysis here (main part of pointer analysis).
|
|
54
|
+
virtual void analyze(){
|
|
55
|
+
PointerAnalysis::initialize();
|
|
56
|
+
GrammarBuilder * gReader = new GrammarBuilder(Options::GrammarFilename);
|
|
57
|
+
CFGNormalizer *normalizer = new CFGNormalizer();
|
|
58
|
+
|
|
59
|
+
graph = new CFLGraph();
|
|
60
|
+
if (Options::GraphIsFromDot == false){
|
|
61
|
+
// Maybe could put in SVFIR Class
|
|
62
|
+
// In memory Graph does not have string type label
|
|
63
|
+
Map<std::string, SVF::CFLGraph::Symbol> ConstMap = {{"Addr",0}, {"Copy", 1},{"Store", 2},{"Load", 3},{"Gep", 4},{"Vgep", 5},{"Addrbar",6}, {"Copybar", 7},{"Storebar", 8},{"Loadbar", 9},{"Gepbar", 10},{"Vgepbar", 11}};
|
|
64
|
+
ConstraintGraph *consCG = new ConstraintGraph(svfir);
|
|
65
|
+
svfir->dump("SVFIR");
|
|
66
|
+
// Can be put in build, copy from general graph
|
|
67
|
+
graph->label2SymMap = ConstMap;
|
|
68
|
+
graph->buildBigraph(consCG);
|
|
69
|
+
graph->dump("PAG");
|
|
70
|
+
delete consCG;
|
|
71
|
+
GrammarBase *generalGrammar = gReader->build(&ConstMap);
|
|
72
|
+
grammar = normalizer->normalize(generalGrammar);
|
|
73
|
+
graph->setMap(&grammar->terminals, &grammar->nonterminals);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
GrammarBase *generalGrammar = gReader->build();
|
|
77
|
+
grammar = normalizer->normalize(generalGrammar);
|
|
78
|
+
graph->setMap(&grammar->terminals, &grammar->nonterminals);
|
|
79
|
+
graph->buildFromDot(Options::InputFilename);
|
|
80
|
+
}
|
|
81
|
+
graph->startSymbol = grammar->startSymbol;
|
|
82
|
+
solver = new CFLSolver(graph, grammar);
|
|
83
|
+
solver->solve();
|
|
84
|
+
graph->dump("map");
|
|
85
|
+
PointerAnalysis::finalize();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/// Interface exposed to users of our pointer analysis, given Value infos
|
|
89
|
+
virtual AliasResult alias(const Value* v1, const Value* v2) {
|
|
90
|
+
NodeID n1 = svfir->getValueNode(v1);
|
|
91
|
+
NodeID n2 = svfir->getValueNode(v2);
|
|
92
|
+
return alias(n1,n2);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/// Interface exposed to users of our pointer analysis, given PAGNodeID
|
|
96
|
+
virtual AliasResult alias(NodeID node1, NodeID node2) {
|
|
97
|
+
/// TODO:: Fix the edge label for a reachable alias relation if it is not 1;
|
|
98
|
+
if(graph->hasEdge(graph->getGNode(node1), graph->getGNode(node2), graph->startSymbol))
|
|
99
|
+
return AliasResult::MayAlias;
|
|
100
|
+
else
|
|
101
|
+
return AliasResult::NoAlias;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/// Get points-to targets of a pointer.
|
|
105
|
+
virtual const PointsTo& getPts(NodeID ptr) {
|
|
106
|
+
/// Check Outgoing edge Dst of ptr
|
|
107
|
+
//PointsTo * ps;
|
|
108
|
+
abort(); // to be implemented
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/// Given an object, get all the nodes having whose pointsto contains the object
|
|
112
|
+
virtual const NodeSet& getRevPts(NodeID nodeId) {
|
|
113
|
+
/// Check Outgoing flowtobar edge dst of ptr
|
|
114
|
+
abort(); // to be implemented
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private:
|
|
118
|
+
SVFIR* svfir;
|
|
119
|
+
CFLGraph* graph;
|
|
120
|
+
CFLGrammar* grammar;
|
|
121
|
+
CFLSolver *solver;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
//===----- CFLGrammar.h -- Context-free grammar --------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* CFLGrammar.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: March 5, 2022
|
|
27
|
+
* Author: Yulei Sui
|
|
28
|
+
*/
|
|
29
|
+
#ifndef CFLGrammar_H_
|
|
30
|
+
#define CFLGrammar_H_
|
|
31
|
+
#include "Util/BasicTypes.h"
|
|
32
|
+
|
|
33
|
+
namespace SVF{
|
|
34
|
+
|
|
35
|
+
class GrammarBase{
|
|
36
|
+
public:
|
|
37
|
+
typedef u32_t Symbol;
|
|
38
|
+
typedef std::vector<Symbol> Production;
|
|
39
|
+
typedef Set<Production> Productions;
|
|
40
|
+
Map<std::string, Symbol> terminals;
|
|
41
|
+
Map<std::string, Symbol> nonterminals;
|
|
42
|
+
|
|
43
|
+
Symbol str2Sym(std::string str) const;
|
|
44
|
+
|
|
45
|
+
std::string sym2Str(Symbol sym) const;
|
|
46
|
+
|
|
47
|
+
Symbol getSymbol(const Production& prod, u32_t pos){
|
|
48
|
+
return prod.at(pos);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Symbol insertTerminalSymbol(std::string strLit);
|
|
52
|
+
Symbol insertNonTerminalSymbol(std::string strLit);
|
|
53
|
+
|
|
54
|
+
Symbol startSymbol;
|
|
55
|
+
Symbol totalSymbol;
|
|
56
|
+
Map<Symbol, Productions> rawProductions;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
class CFLGrammar : public GrammarBase{
|
|
60
|
+
|
|
61
|
+
public:
|
|
62
|
+
Set<Production > epsilonProds;
|
|
63
|
+
Map<Symbol, Productions> singleRHS2Prods;
|
|
64
|
+
Map<Symbol, Productions> firstRHS2Prods;
|
|
65
|
+
Map<Symbol, Productions> secondRHS2Prods;
|
|
66
|
+
Symbol newTerminalSubscript;
|
|
67
|
+
CFLGrammar();
|
|
68
|
+
|
|
69
|
+
const Productions& getEpsilonProds() const{
|
|
70
|
+
return epsilonProds;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const bool hasProdsFromFirstRHS(Symbol sym) const{
|
|
74
|
+
auto it = firstRHS2Prods.find(sym);
|
|
75
|
+
return it!=firstRHS2Prods.end();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const bool hasProdsFromSingleRHS(Symbol sym) const{
|
|
79
|
+
auto it = singleRHS2Prods.find(sym);
|
|
80
|
+
return it!=singleRHS2Prods.end();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const bool hasProdsFromSecondRHS(Symbol sym) const{
|
|
84
|
+
auto it = secondRHS2Prods.find(sym);
|
|
85
|
+
return it!=secondRHS2Prods.end();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const Productions& getProdsFromSingleRHS(Symbol sym) const{
|
|
89
|
+
auto it = singleRHS2Prods.find(sym);
|
|
90
|
+
assert(it!=singleRHS2Prods.end() && "production (X -> sym) not found for sym!!");
|
|
91
|
+
return it->second;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const Productions& getProdsFromFirstRHS(Symbol sym) const{
|
|
95
|
+
auto it = firstRHS2Prods.find(sym);
|
|
96
|
+
assert(it!=firstRHS2Prods.end() && "production (X -> sym Y) not found for sym!!");
|
|
97
|
+
return it->second;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const Productions& getProdsFromSecondRHS(Symbol sym) const{
|
|
101
|
+
auto it = secondRHS2Prods.find(sym);
|
|
102
|
+
assert(it!=secondRHS2Prods.end() && "production (X -> Y sym) not found for sym!!");
|
|
103
|
+
return it->second;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Symbol getLHSSymbol(const Production& prod){
|
|
107
|
+
return prod.at(0);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
Symbol getFirstRHSSymbol(const Production& prod){
|
|
111
|
+
return prod.at(1);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
Symbol getSecondRHSSymbol(const Production& prod){
|
|
115
|
+
return prod.at(2);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
inline int num_generator()
|
|
119
|
+
{
|
|
120
|
+
return newTerminalSubscript++;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
#endif /* CFLGrammar_H_ */
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
//===----- CFLSolver.h -- Context-free language reachability solver--------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* CFLSolver.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: March 5, 2022
|
|
27
|
+
* Author: Yulei Sui
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#include "Graphs/CFLGraph.h"
|
|
31
|
+
#include "CFL/CFLGrammar.h"
|
|
32
|
+
#include "Util/WorkList.h"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
namespace SVF{
|
|
36
|
+
|
|
37
|
+
class CFLSolver{
|
|
38
|
+
|
|
39
|
+
public:
|
|
40
|
+
/// Define worklist
|
|
41
|
+
typedef FIFOWorkList<const CFLEdge*> WorkList;
|
|
42
|
+
typedef CFLGrammar::Production Production;
|
|
43
|
+
typedef CFLGrammar::Symbol Symbol;
|
|
44
|
+
|
|
45
|
+
CFLSolver(CFLGraph* _graph, CFLGrammar* _grammar): graph(_graph), grammar(_grammar)
|
|
46
|
+
{
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
~CFLSolver()
|
|
50
|
+
{
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// Start solving
|
|
54
|
+
void solve();
|
|
55
|
+
|
|
56
|
+
/// Return CFL Graph
|
|
57
|
+
inline const CFLGraph* getGraph() const {
|
|
58
|
+
return graph;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/// Return CFL Grammar
|
|
62
|
+
inline const CFLGrammar* getGrammar() const {
|
|
63
|
+
return grammar;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected:
|
|
67
|
+
/// Worklist operations
|
|
68
|
+
//@{
|
|
69
|
+
inline const CFLEdge* popFromWorklist()
|
|
70
|
+
{
|
|
71
|
+
return worklist.pop();
|
|
72
|
+
}
|
|
73
|
+
inline bool pushIntoWorklist(const CFLEdge* item)
|
|
74
|
+
{
|
|
75
|
+
return worklist.push(item);
|
|
76
|
+
}
|
|
77
|
+
inline bool isWorklistEmpty()
|
|
78
|
+
{
|
|
79
|
+
return worklist.empty();
|
|
80
|
+
}
|
|
81
|
+
inline bool isInWorklist(const CFLEdge* item)
|
|
82
|
+
{
|
|
83
|
+
return worklist.find(item);
|
|
84
|
+
}
|
|
85
|
+
//@}
|
|
86
|
+
|
|
87
|
+
private:
|
|
88
|
+
CFLGraph* graph;
|
|
89
|
+
CFLGrammar* grammar;
|
|
90
|
+
/// Worklist for resolution
|
|
91
|
+
WorkList worklist;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//===----- CFGNormalizer.h -- CFL Alias Analysis Client--------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* GrammarBuilder.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: April 26, 2022
|
|
27
|
+
* Author: Pei Xu
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
#include "CFL/CFLGrammar.h"
|
|
32
|
+
#include "Graphs/CFLGraph.h"
|
|
33
|
+
|
|
34
|
+
namespace SVF{
|
|
35
|
+
|
|
36
|
+
/*!
|
|
37
|
+
* Build Grammar from a user specified grammar text
|
|
38
|
+
* Input Format:
|
|
39
|
+
* Start: // Special string 'epsilon' for empty RHS
|
|
40
|
+
* M // Specify Start Symbol in Second Line
|
|
41
|
+
* Productions: // Each Symbol seperate by 'Space', production end with ';'
|
|
42
|
+
* M -> V d; // Terminal in NonCapital
|
|
43
|
+
* M -> dbar V d; // NonTerminal in Capital
|
|
44
|
+
* V -> M abar M a M; // LHS and RHS, Seperate by '->'
|
|
45
|
+
* V -> ( M ? abar ) * M ? ( a M ? ) *; // Support '(' ')' '?' '*' four regular expression sign
|
|
46
|
+
* Note:
|
|
47
|
+
* When provide EBNF form text (i.e Last production above),
|
|
48
|
+
* Please specify -ebnf flag, otherwise regular experssion sign will treat as NonTerminal.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
class GrammarBuilder{
|
|
52
|
+
public:
|
|
53
|
+
std::string fileName;
|
|
54
|
+
GrammarBase *grammar;
|
|
55
|
+
|
|
56
|
+
GrammarBuilder(std::string fileName): fileName(fileName), grammar(nullptr){
|
|
57
|
+
grammar = new GrammarBase();
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
GrammarBase* build();
|
|
61
|
+
|
|
62
|
+
GrammarBase* build(Map<std::string, SVF::CFLGraph::Symbol> *preMap);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
} // SVF
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
//===----- CFLGraph.h -- Graph for context-free language reachability analysis --//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* CFLGraph.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: March 5, 2022
|
|
27
|
+
* Author: Yulei Sui
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef CFLG_H_
|
|
31
|
+
#define CFLG_H_
|
|
32
|
+
|
|
33
|
+
#include <fstream>
|
|
34
|
+
#include <iostream>
|
|
35
|
+
#include <string>
|
|
36
|
+
#include <regex>
|
|
37
|
+
#include "CFL/CFLGrammar.h"
|
|
38
|
+
#include "Graphs/GenericGraph.h"
|
|
39
|
+
|
|
40
|
+
namespace SVF
|
|
41
|
+
{
|
|
42
|
+
class CFLNode;
|
|
43
|
+
|
|
44
|
+
typedef GenericEdge<CFLNode> GenericCFLEdgeTy;
|
|
45
|
+
|
|
46
|
+
class CFLEdge: public GenericCFLEdgeTy
|
|
47
|
+
{
|
|
48
|
+
public:
|
|
49
|
+
CFLEdge(CFLNode *s, CFLNode *d, GEdgeFlag k = 0):
|
|
50
|
+
GenericCFLEdgeTy(s,d,k)
|
|
51
|
+
{
|
|
52
|
+
}
|
|
53
|
+
~CFLEdge() override = default;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
typedef GenericNode<CFLNode,CFLEdge> GenericCFLNodeTy;
|
|
58
|
+
class CFLNode: public GenericCFLNodeTy
|
|
59
|
+
{
|
|
60
|
+
public:
|
|
61
|
+
CFLNode (NodeID i = 0, GNodeK k = 0):
|
|
62
|
+
GenericCFLNodeTy(i, k)
|
|
63
|
+
{
|
|
64
|
+
}
|
|
65
|
+
~CFLNode() override = default;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/// Edge-labeled graph for CFL Reachability analysis
|
|
69
|
+
typedef GenericGraph<CFLNode,CFLEdge> GenericCFLGraphTy;
|
|
70
|
+
class CFLGraph: public GenericCFLGraphTy
|
|
71
|
+
{
|
|
72
|
+
public:
|
|
73
|
+
typedef u32_t Symbol;
|
|
74
|
+
typedef GenericNode<CFLNode,CFLEdge>::GEdgeSetTy CFLEdgeSet;
|
|
75
|
+
Map<std::string, Symbol> label2SymMap;
|
|
76
|
+
Symbol startSymbol;
|
|
77
|
+
|
|
78
|
+
CFLGraph()
|
|
79
|
+
{
|
|
80
|
+
}
|
|
81
|
+
~CFLGraph() override = default;
|
|
82
|
+
|
|
83
|
+
/// Build graph by copying nodes and edges from any graph inherited from GenericGraph
|
|
84
|
+
template<class N, class E>
|
|
85
|
+
void build(GenericGraph<N,E>* graph){
|
|
86
|
+
for(auto it = graph->begin(); it!= graph->end(); it++){
|
|
87
|
+
CFLNode* node = new CFLNode((*it).first);
|
|
88
|
+
addCFLNode((*it).first, node);
|
|
89
|
+
}
|
|
90
|
+
for(auto it = graph->begin(); it!= graph->end(); it++){
|
|
91
|
+
N* node = (*it).second;
|
|
92
|
+
for(E* edge : node->getOutEdges())
|
|
93
|
+
{
|
|
94
|
+
addCFLEdge(getGNode(edge->getSrcID()), getGNode(edge->getDstID()), edge->getEdgeKind());
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/// Build Bidirectional graph by copying nodes and edges from any graph inherited from GenericGraph
|
|
100
|
+
template<class N, class E>
|
|
101
|
+
void buildBigraph(GenericGraph<N,E>* graph){
|
|
102
|
+
for(auto it = graph->begin(); it!= graph->end(); it++){
|
|
103
|
+
CFLNode* node = new CFLNode((*it).first);
|
|
104
|
+
addCFLNode((*it).first, node);
|
|
105
|
+
}
|
|
106
|
+
for(auto it = graph->begin(); it!= graph->end(); it++){
|
|
107
|
+
N* node = (*it).second;
|
|
108
|
+
for(E* edge : node->getOutEdges())
|
|
109
|
+
{
|
|
110
|
+
addCFLEdge(getGNode(edge->getSrcID()), getGNode(edge->getDstID()), edge->getEdgeKind());
|
|
111
|
+
std::string key = "";
|
|
112
|
+
for (auto &i : this->label2SymMap)
|
|
113
|
+
{
|
|
114
|
+
if (i.second == edge->getEdgeKind())
|
|
115
|
+
{
|
|
116
|
+
key = i.first;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
key.append("bar");
|
|
120
|
+
addCFLEdge(getGNode(edge->getDstID()), getGNode(edge->getSrcID()), this->label2SymMap[key]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
virtual void addCFLNode(NodeID id, CFLNode* node);
|
|
126
|
+
|
|
127
|
+
virtual const CFLEdge* addCFLEdge(CFLNode* src, CFLNode* dst, CFLEdge::GEdgeFlag label);
|
|
128
|
+
|
|
129
|
+
virtual const CFLEdge* hasEdge(CFLNode* src, CFLNode* dst, CFLEdge::GEdgeFlag label);
|
|
130
|
+
|
|
131
|
+
void dump(const std::string& filename);
|
|
132
|
+
|
|
133
|
+
void view();
|
|
134
|
+
|
|
135
|
+
/// Build graph from file
|
|
136
|
+
void build(std::string filename);
|
|
137
|
+
|
|
138
|
+
/// Build graph from Dot
|
|
139
|
+
void buildFromDot(std::string filename);
|
|
140
|
+
|
|
141
|
+
/// Set label2Sym from External
|
|
142
|
+
void setMap(Map<std::string, Symbol>* terminals, Map<std::string, Symbol>* nonterminals);
|
|
143
|
+
|
|
144
|
+
private:
|
|
145
|
+
CFLEdgeSet cflEdgeSet;
|
|
146
|
+
Symbol current;
|
|
147
|
+
bool externMap;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
namespace llvm
|
|
153
|
+
{
|
|
154
|
+
/* !
|
|
155
|
+
* GraphTraits specializations for generic graph algorithms.
|
|
156
|
+
* Provide graph traits for traversing from a constraint node using standard graph traversals.
|
|
157
|
+
*/
|
|
158
|
+
template<> struct GraphTraits<SVF::CFLNode*> : public GraphTraits<SVF::GenericNode<SVF::CFLNode,SVF::CFLEdge>* >
|
|
159
|
+
{
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/// Inverse GraphTraits specializations for call graph node, it is used for inverse traversal.
|
|
163
|
+
template<>
|
|
164
|
+
struct GraphTraits<Inverse<SVF::CFLNode *> > : public GraphTraits<Inverse<SVF::GenericNode<SVF::CFLNode,SVF::CFLEdge>* > >
|
|
165
|
+
{
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
template<> struct GraphTraits<SVF::CFLGraph*> : public GraphTraits<SVF::GenericGraph<SVF::CFLNode,SVF::CFLEdge>* >
|
|
169
|
+
{
|
|
170
|
+
typedef SVF::CFLNode *NodeRef;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
} // End namespace llvm
|
|
174
|
+
|
|
175
|
+
#endif /* CFLG_H_ */
|
|
@@ -53,7 +53,7 @@ public:
|
|
|
53
53
|
|
|
54
54
|
protected:
|
|
55
55
|
SVFStmt::KindToSVFStmtMapTy KindToSVFStmtSetMap; // < SVFIR edge map containing all PAGEdges
|
|
56
|
-
SVFStmt::KindToSVFStmtMapTy KindToPTASVFStmtSetMap; // < SVFIR edge map containing only pointer-related edges, i.e, both
|
|
56
|
+
SVFStmt::KindToSVFStmtMapTy KindToPTASVFStmtSetMap; // < SVFIR edge map containing only pointer-related edges, i.e, both LHS and RHS are of pointer type
|
|
57
57
|
bool fromFile; ///< Whether the SVFIR is built according to user specified data from a txt file
|
|
58
58
|
NodeID nodeNumAfterPAGBuild; // initial node number after building SVFIR, excluding later added nodes, e.g., gepobj nodes
|
|
59
59
|
u32_t totalPTAPAGEdge;
|
|
@@ -79,9 +79,9 @@ public:
|
|
|
79
79
|
FSTBHC_WPA, ///< Sparse flow-sensitive type-based heap cloning WPA
|
|
80
80
|
VFS_WPA, ///< Versioned sparse flow-sensitive WPA
|
|
81
81
|
FSCS_WPA, ///< Flow-, context- sensitive WPA
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
CFLFICI_WPA, ///< Flow-, context-, insensitive CFL-reachability-based analysis
|
|
83
|
+
CFLFSCI_WPA, ///< Flow-insensitive, context-sensitive CFL-reachability-based analysis
|
|
84
|
+
CFLFSCS_WPA, ///< Flow-, context-, CFL-reachability-based analysis
|
|
85
85
|
TypeCPP_WPA, ///< Type-based analysis for C++
|
|
86
86
|
|
|
87
87
|
// Demand driven analysis
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
#ifndef SRCSNKANALYSIS_H_
|
|
31
31
|
#define SRCSNKANALYSIS_H_
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
#include "Util/GraphReachSolver.h"
|
|
34
35
|
#include "Graphs/SVFGOPT.h"
|
|
35
36
|
#include "SABER/ProgSlice.h"
|
|
36
37
|
#include "SABER/SaberSVFGBuilder.h"
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
namespace SVF
|
|
39
40
|
{
|
|
40
41
|
|
|
41
|
-
typedef
|
|
42
|
+
typedef GraphReachSolver<SVFG*,CxtDPItem> CFLSrcSnkSolver;
|
|
42
43
|
|
|
43
44
|
/*!
|
|
44
45
|
* General source-sink analysis, which serves as a base analysis to be extended for various clients
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
//===- GraphReachSolver.h -- Generic graph reachability solver---------------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2017> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* GraphReachSolver.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: Apr 1, 2014
|
|
27
|
+
* Author: Yulei Sui
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef CFLSOLVER_H_
|
|
31
|
+
#define CFLSOLVER_H_
|
|
32
|
+
|
|
33
|
+
#include "Util/WorkList.h"
|
|
34
|
+
#include "Util/DPItem.h"
|
|
35
|
+
|
|
36
|
+
namespace SVF
|
|
37
|
+
{
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
* Generic Graph Reachability solver for demand-driven analysis based on different graphs (e.g. SVFIR, VFG, ThreadVFG)
|
|
41
|
+
* Extend this class for sophisticated CFL-reachability resolution (e.g. field, flow, path)
|
|
42
|
+
*/
|
|
43
|
+
template<class GraphType, class DPIm = DPItem>
|
|
44
|
+
class GraphReachSolver
|
|
45
|
+
{
|
|
46
|
+
|
|
47
|
+
public:
|
|
48
|
+
///Define the GTraits and node iterator
|
|
49
|
+
typedef llvm::GraphTraits<GraphType> GTraits;
|
|
50
|
+
typedef typename GTraits::NodeType GNODE;
|
|
51
|
+
typedef typename GTraits::EdgeType GEDGE;
|
|
52
|
+
typedef typename GTraits::nodes_iterator node_iterator;
|
|
53
|
+
typedef typename GTraits::ChildIteratorType child_iterator;
|
|
54
|
+
|
|
55
|
+
/// Define inverse GTraits and note iterator
|
|
56
|
+
typedef llvm::GraphTraits<llvm::Inverse<GNODE *> > InvGTraits;
|
|
57
|
+
typedef typename InvGTraits::ChildIteratorType inv_child_iterator;
|
|
58
|
+
|
|
59
|
+
/// Define worklist
|
|
60
|
+
typedef FIFOWorkList<DPIm> WorkList;
|
|
61
|
+
|
|
62
|
+
protected:
|
|
63
|
+
|
|
64
|
+
/// Constructor
|
|
65
|
+
GraphReachSolver(): _graph(nullptr)
|
|
66
|
+
{
|
|
67
|
+
}
|
|
68
|
+
/// Destructor
|
|
69
|
+
virtual ~GraphReachSolver()
|
|
70
|
+
{
|
|
71
|
+
}
|
|
72
|
+
/// Get/Set graph methods
|
|
73
|
+
//@{
|
|
74
|
+
const inline GraphType graph() const
|
|
75
|
+
{
|
|
76
|
+
return _graph;
|
|
77
|
+
}
|
|
78
|
+
inline void setGraph(GraphType g)
|
|
79
|
+
{
|
|
80
|
+
_graph = g;
|
|
81
|
+
}
|
|
82
|
+
//@}
|
|
83
|
+
|
|
84
|
+
inline GNODE* getNode(NodeID id) const
|
|
85
|
+
{
|
|
86
|
+
return _graph->getGNode(id);
|
|
87
|
+
}
|
|
88
|
+
virtual inline NodeID getNodeIDFromItem(const DPIm& item) const
|
|
89
|
+
{
|
|
90
|
+
return item.getCurNodeID();
|
|
91
|
+
}
|
|
92
|
+
/// CFL forward traverse solve
|
|
93
|
+
virtual void forwardTraverse(DPIm& it)
|
|
94
|
+
{
|
|
95
|
+
pushIntoWorklist(it);
|
|
96
|
+
|
|
97
|
+
while (!isWorklistEmpty())
|
|
98
|
+
{
|
|
99
|
+
DPIm item = popFromWorklist();
|
|
100
|
+
FWProcessCurNode(item);
|
|
101
|
+
|
|
102
|
+
GNODE* v = getNode(getNodeIDFromItem(item));
|
|
103
|
+
child_iterator EI = GTraits::child_begin(v);
|
|
104
|
+
child_iterator EE = GTraits::child_end(v);
|
|
105
|
+
for (; EI != EE; ++EI)
|
|
106
|
+
{
|
|
107
|
+
FWProcessOutgoingEdge(item,*(EI.getCurrent()) );
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/// CFL forward traverse solve
|
|
112
|
+
virtual void backwardTraverse(DPIm& it)
|
|
113
|
+
{
|
|
114
|
+
pushIntoWorklist(it);
|
|
115
|
+
|
|
116
|
+
while (!isWorklistEmpty())
|
|
117
|
+
{
|
|
118
|
+
DPIm item = popFromWorklist();
|
|
119
|
+
BWProcessCurNode(item);
|
|
120
|
+
|
|
121
|
+
GNODE* v = getNode(getNodeIDFromItem(item));
|
|
122
|
+
inv_child_iterator EI = InvGTraits::child_begin(v);
|
|
123
|
+
inv_child_iterator EE = InvGTraits::child_end(v);
|
|
124
|
+
for (; EI != EE; ++EI)
|
|
125
|
+
{
|
|
126
|
+
BWProcessIncomingEdge(item,*(EI.getCurrent()) );
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/// Process the DP item
|
|
131
|
+
//@{
|
|
132
|
+
virtual void FWProcessCurNode(const DPIm&)
|
|
133
|
+
{
|
|
134
|
+
}
|
|
135
|
+
virtual void BWProcessCurNode(const DPIm&)
|
|
136
|
+
{
|
|
137
|
+
}
|
|
138
|
+
//@}
|
|
139
|
+
/// Propagation for the solving, to be implemented in the child class
|
|
140
|
+
//@{
|
|
141
|
+
virtual void FWProcessOutgoingEdge(const DPIm& item, GEDGE* edge)
|
|
142
|
+
{
|
|
143
|
+
DPIm newItem(item);
|
|
144
|
+
newItem.setCurNodeID(edge->getDstID());
|
|
145
|
+
pushIntoWorklist(newItem);
|
|
146
|
+
}
|
|
147
|
+
virtual void BWProcessIncomingEdge(const DPIm& item, GEDGE* edge)
|
|
148
|
+
{
|
|
149
|
+
DPIm newItem(item);
|
|
150
|
+
newItem.setCurNodeID(edge->getSrcID());
|
|
151
|
+
pushIntoWorklist(newItem);
|
|
152
|
+
}
|
|
153
|
+
//@}
|
|
154
|
+
/// Worklist operations
|
|
155
|
+
//@{
|
|
156
|
+
inline DPIm popFromWorklist()
|
|
157
|
+
{
|
|
158
|
+
return worklist.pop();
|
|
159
|
+
}
|
|
160
|
+
inline bool pushIntoWorklist(DPIm& item)
|
|
161
|
+
{
|
|
162
|
+
return worklist.push(item);
|
|
163
|
+
}
|
|
164
|
+
inline bool isWorklistEmpty()
|
|
165
|
+
{
|
|
166
|
+
return worklist.empty();
|
|
167
|
+
}
|
|
168
|
+
inline bool isInWorklist(DPIm& item)
|
|
169
|
+
{
|
|
170
|
+
return worklist.find(item);
|
|
171
|
+
}
|
|
172
|
+
//@}
|
|
173
|
+
|
|
174
|
+
private:
|
|
175
|
+
|
|
176
|
+
/// Graph
|
|
177
|
+
GraphType _graph;
|
|
178
|
+
|
|
179
|
+
/// Worklist for resolution
|
|
180
|
+
WorkList worklist;
|
|
181
|
+
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
} // End namespace SVF
|
|
185
|
+
|
|
186
|
+
#endif /* CFLSOLVER_H_ */
|
|
@@ -254,6 +254,12 @@ public:
|
|
|
254
254
|
// DOTGraphTraits
|
|
255
255
|
static const llvm::cl::opt<bool> ShowHiddenNode;
|
|
256
256
|
|
|
257
|
+
// CFL option
|
|
258
|
+
static const llvm::cl::opt<std::string> InputFilename;
|
|
259
|
+
static const llvm::cl::opt<std::string> GrammarFilename;
|
|
260
|
+
static const llvm::cl::opt<bool> GraphIsFromDot;
|
|
261
|
+
static const llvm::cl::opt<bool> GrammarIsEBNF;
|
|
262
|
+
static const llvm::cl::opt<bool> FlexSymMap;
|
|
257
263
|
};
|
|
258
264
|
} // namespace SVF
|
|
259
265
|
|