svf-lib 1.0.1032 → 1.0.1035
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 +11 -18
- package/SVF-linux/include/CFL/CFLAlias.h +8 -7
- package/SVF-linux/include/CFL/CFLGramGraphChecker.h +19 -12
- package/SVF-linux/include/CFL/CFLGrammar.h +81 -25
- package/SVF-linux/include/CFL/CFLGrammar.txt +9 -1
- package/SVF-linux/include/CFL/CFLGrammarDev.txt +16 -0
- package/SVF-linux/include/CFL/CFLGraphBuilder.h +51 -11
- package/SVF-linux/include/CFL/CFLSolver.h +2 -0
- package/SVF-linux/include/DDA/ContextDDA.h +0 -2
- package/SVF-linux/include/DDA/FlowDDA.h +0 -2
- package/SVF-linux/include/Graphs/CFLGraph.h +5 -29
- package/SVF-linux/include/Graphs/ICFG.h +33 -3
- package/SVF-linux/include/MTA/TCT.h +0 -1
- package/SVF-linux/include/MemoryModel/SVFLoop.h +163 -0
- package/SVF-linux/include/SVF-FE/LLVMLoopAnalysis.h +59 -0
- package/SVF-linux/include/Util/Options.h +4 -0
- package/SVF-osx/Release-build/lib/CUDD/libCudd.a +0 -0
- package/SVF-osx/Release-build/lib/libSvf.a +0 -0
- package/SVF-osx/include/DDA/ContextDDA.h +0 -2
- package/SVF-osx/include/DDA/FlowDDA.h +0 -2
- package/SVF-osx/include/Graphs/ICFG.h +33 -3
- package/SVF-osx/include/MTA/TCT.h +0 -1
- package/SVF-osx/include/MemoryModel/SVFLoop.h +163 -0
- package/SVF-osx/include/SVF-FE/LLVMLoopAnalysis.h +59 -0
- package/SVF-osx/include/Util/Options.h +4 -0
- package/package.json +1 -1
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===----- CFGNormalizer.h --
|
|
1
|
+
//===----- CFGNormalizer.h -- Context Free Grammar Normalizer--------------//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -43,40 +43,33 @@ class CFGNormalizer
|
|
|
43
43
|
{
|
|
44
44
|
|
|
45
45
|
public:
|
|
46
|
-
typedef u32_t Symbol;
|
|
47
|
-
typedef std::vector<Symbol> Production;
|
|
48
|
-
typedef Set<Production> Productions;
|
|
49
|
-
|
|
50
46
|
CFGNormalizer()
|
|
51
47
|
{
|
|
52
48
|
}
|
|
53
49
|
|
|
54
|
-
///
|
|
55
|
-
// TODO: Add different Combination Transformation Option
|
|
56
|
-
|
|
57
|
-
/// Normalization without attribute expanded
|
|
50
|
+
/// Normalization with attribute expanded
|
|
58
51
|
CFLGrammar* normalize(GrammarBase *generalGrammar);
|
|
59
52
|
|
|
60
53
|
/// Fill Every attribute in CFL grammar
|
|
61
|
-
CFLGrammar* fillAttribute(CFLGrammar *grammar, Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute
|
|
54
|
+
CFLGrammar* fillAttribute(CFLGrammar *grammar, const Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& kind2AttrsMap);
|
|
62
55
|
|
|
63
56
|
private:
|
|
64
57
|
/// Add nonterminal to tranfer long rules to binary rules
|
|
65
|
-
void ebnf_bin(
|
|
58
|
+
void ebnf_bin(CFLGrammar *grammar);
|
|
66
59
|
|
|
67
|
-
void ebnf_sign_replace(char sign,
|
|
60
|
+
void ebnf_sign_replace(char sign, CFLGrammar *grammar);
|
|
68
61
|
|
|
69
|
-
void insertToCFLGrammar(CFLGrammar *grammar, Production &prod);
|
|
62
|
+
void insertToCFLGrammar(CFLGrammar *grammar, GrammarBase::Production &prod);
|
|
70
63
|
|
|
71
|
-
int ebnf_bracket_match(Production& prod, int i, CFLGrammar *grammar) ;
|
|
64
|
+
int ebnf_bracket_match(GrammarBase::Production& prod, int i, CFLGrammar *grammar) ;
|
|
72
65
|
|
|
73
|
-
int check_head(Map<Symbol, Productions>& grammar, Production& rule);
|
|
66
|
+
int check_head(Map<GrammarBase::Symbol, GrammarBase::Productions>& grammar, GrammarBase::Production& rule);
|
|
74
67
|
|
|
75
|
-
Production strTrans(std::string strPro, CFLGrammar *grammar);
|
|
68
|
+
GrammarBase::Production strTrans(std::string strPro, CFLGrammar *grammar);
|
|
76
69
|
|
|
77
|
-
Production getFilledProd(Production &prod, CFLGrammar::Attribute attribute, CFLGrammar *grammar);
|
|
70
|
+
GrammarBase::Production getFilledProd(GrammarBase::Production &prod, CFLGrammar::Attribute attribute, CFLGrammar *grammar);
|
|
78
71
|
|
|
79
|
-
Productions getFilledProductions(Production &prod, Map<CFLGrammar::Kind,
|
|
72
|
+
GrammarBase::Productions getFilledProductions(GrammarBase::Production &prod,const Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& kind2AttriMap, CFLGrammar *grammar);
|
|
80
73
|
};
|
|
81
74
|
|
|
82
75
|
} // End namespace SVF
|
|
@@ -70,21 +70,22 @@ public:
|
|
|
70
70
|
Map<std::string, SVF::CFLGraph::Symbol> ConstMap = {{"Addr",0}, {"Copy", 1},{"Store", 2},{"Load", 3},{"Gep_i", 4},{"Vgep", 5},{"Addrbar",6}, {"Copybar", 7},{"Storebar", 8},{"Loadbar", 9},{"Gepbar_i", 10},{"Vgepbar", 11}};
|
|
71
71
|
GrammarBase *generalGrammar = gReader.build(ConstMap);
|
|
72
72
|
ConstraintGraph *consCG = new ConstraintGraph(svfir);
|
|
73
|
-
graph = cflGraphBuilder.buildBigraph(consCG);
|
|
74
|
-
cflChecker.check(generalGrammar, graph);
|
|
73
|
+
graph = cflGraphBuilder.buildBigraph(consCG, generalGrammar->getStartKind());
|
|
74
|
+
cflChecker.check(generalGrammar, &cflGraphBuilder, graph);
|
|
75
75
|
grammar = normalizer.normalize(generalGrammar);
|
|
76
|
-
cflChecker.check(grammar, graph);
|
|
76
|
+
cflChecker.check(grammar, &cflGraphBuilder, graph);
|
|
77
|
+
svfir->dump("SVFIR");
|
|
78
|
+
grammar->dump();
|
|
77
79
|
delete consCG;
|
|
78
80
|
delete generalGrammar;
|
|
79
|
-
grammar->dump();
|
|
80
81
|
}
|
|
81
82
|
else
|
|
82
83
|
{
|
|
83
84
|
GrammarBase *generalGrammar = gReader.build();
|
|
84
85
|
graph = cflGraphBuilder.buildFromDot(Options::InputFilename, generalGrammar);
|
|
85
|
-
cflChecker.check(generalGrammar, graph);
|
|
86
|
+
cflChecker.check(generalGrammar, &cflGraphBuilder, graph);
|
|
86
87
|
grammar = normalizer.normalize(generalGrammar);
|
|
87
|
-
cflChecker.check(grammar, graph);
|
|
88
|
+
cflChecker.check(grammar, &cflGraphBuilder, graph);
|
|
88
89
|
delete generalGrammar;
|
|
89
90
|
}
|
|
90
91
|
solver = new CFLSolver(graph, grammar);
|
|
@@ -106,7 +107,7 @@ public:
|
|
|
106
107
|
/// Interface exposed to users of our pointer analysis, given PAGNodeID
|
|
107
108
|
virtual AliasResult alias(NodeID node1, NodeID node2)
|
|
108
109
|
{
|
|
109
|
-
if(graph->hasEdge(graph->getGNode(node1), graph->getGNode(node2), graph->
|
|
110
|
+
if(graph->hasEdge(graph->getGNode(node1), graph->getGNode(node2), graph->startKind))
|
|
110
111
|
return AliasResult::MayAlias;
|
|
111
112
|
else
|
|
112
113
|
return AliasResult::NoAlias;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===----- CFLGramGraphChecker.h -- CFL Checker for Grammar and
|
|
1
|
+
//===----- CFLGramGraphChecker.h -- CFL Checker for Grammar and graphBuilder alignment --------------//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -35,28 +35,35 @@ namespace SVF
|
|
|
35
35
|
class CFLGramGraphChecker
|
|
36
36
|
{
|
|
37
37
|
public:
|
|
38
|
-
void check(GrammarBase *grammar, CFLGraph *graph)
|
|
38
|
+
void check(GrammarBase *grammar, CFLGraphBuilder *graphBuilder, CFLGraph *graph)
|
|
39
39
|
{
|
|
40
|
-
/// Check all
|
|
41
|
-
for(auto pairV : grammar->
|
|
40
|
+
/// Check all kinds in grammar in graphBuilder with the same label
|
|
41
|
+
for(auto pairV : grammar->getTerminals())
|
|
42
42
|
{
|
|
43
|
-
if (
|
|
43
|
+
if (graphBuilder->getLabel2KindMap().find(pairV.first) != graphBuilder->getLabel2KindMap().end())
|
|
44
44
|
{
|
|
45
|
-
assert(
|
|
45
|
+
assert(graphBuilder->getLabel2KindMap()[pairV.first] == pairV.second);
|
|
46
|
+
assert(graphBuilder->getKind2LabelMap()[pairV.second] == pairV.first);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
for(auto pairV : grammar->
|
|
50
|
+
for(auto pairV : grammar->getNonterminals())
|
|
50
51
|
{
|
|
51
|
-
if (
|
|
52
|
+
if (graphBuilder->getLabel2KindMap().find(pairV.first) != graphBuilder->getLabel2KindMap().end())
|
|
52
53
|
{
|
|
53
|
-
assert(
|
|
54
|
+
assert(graphBuilder->getLabel2KindMap()[pairV.first] == pairV.second);
|
|
55
|
+
assert(graphBuilder->getKind2LabelMap()[pairV.second] == pairV.first);
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
{
|
|
59
|
+
graphBuilder->getLabel2KindMap().insert(std::make_pair (pairV.first,pairV.second));
|
|
60
|
+
graphBuilder->getKind2LabelMap().insert(std::make_pair (pairV.second, pairV.first));
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
|
|
57
|
-
/// Get
|
|
58
|
-
grammar->
|
|
59
|
-
graph->
|
|
64
|
+
/// Get Kind2Attrs Map from Graph to Grammar
|
|
65
|
+
grammar->setKind2AttrsMap(graphBuilder->getKind2AttrsMap());
|
|
66
|
+
graph->startKind = grammar->getStartKind();
|
|
60
67
|
}
|
|
61
68
|
};
|
|
62
69
|
|
|
@@ -40,17 +40,66 @@ public:
|
|
|
40
40
|
typedef Set<Production> Productions;
|
|
41
41
|
typedef u32_t Attribute;
|
|
42
42
|
typedef u32_t Kind;
|
|
43
|
-
Map<std::string, Symbol> terminals;
|
|
44
|
-
Map<std::string, Symbol> nonterminals;
|
|
45
|
-
Symbol startSymbol;
|
|
46
|
-
Symbol totalSymbol;
|
|
47
|
-
Map<Symbol, Productions> rawProductions;
|
|
48
|
-
Set<Symbol> attributeSymbol;
|
|
49
|
-
Map<Kind, Set<Attribute>> kind2AttrMap;
|
|
50
43
|
|
|
51
|
-
|
|
44
|
+
inline Map<std::string, Kind>& getNonterminals()
|
|
45
|
+
{
|
|
46
|
+
return this->nonterminals;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
inline void setNonterminals(Map<std::string, Kind>& nonterminals)
|
|
50
|
+
{
|
|
51
|
+
this->nonterminals = nonterminals;
|
|
52
|
+
}
|
|
52
53
|
|
|
53
|
-
std::string
|
|
54
|
+
inline Map<std::string, Kind>& getTerminals()
|
|
55
|
+
{
|
|
56
|
+
return this->terminals;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
inline void setTerminals(Map<std::string, Kind>& terminals)
|
|
60
|
+
{
|
|
61
|
+
this->terminals = terminals;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
inline Map<Symbol, Productions>& getRawProductions()
|
|
65
|
+
{
|
|
66
|
+
return this->rawProductions;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
inline const Map<Kind, Set<Attribute>>& getKind2AttrsMap() const
|
|
70
|
+
{
|
|
71
|
+
return this->kind2AttrsMap;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
inline Kind getTotalKind()
|
|
75
|
+
{
|
|
76
|
+
return this->totalKind;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
inline Kind getStartKind()
|
|
80
|
+
{
|
|
81
|
+
return this->startKind;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
inline void setStartKind(Kind startKind)
|
|
85
|
+
{
|
|
86
|
+
this->startKind = startKind;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
inline void setTotalKind(Kind totalKind)
|
|
90
|
+
{
|
|
91
|
+
this->totalKind = totalKind;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void setRawProductions(Map<Symbol, Productions>& rawProductions);
|
|
95
|
+
|
|
96
|
+
void setKind2AttrsMap(const Map<Kind, Set<Attribute>>& kind2AttrsMap);
|
|
97
|
+
|
|
98
|
+
void setAttributeKinds(const Set<Kind>& attributeKind);
|
|
99
|
+
|
|
100
|
+
Kind str2Kind(std::string str) const;
|
|
101
|
+
|
|
102
|
+
std::string kind2Str(Kind kind) const;
|
|
54
103
|
|
|
55
104
|
std::string sym2StrDump(Symbol sym) const;
|
|
56
105
|
|
|
@@ -59,14 +108,14 @@ public:
|
|
|
59
108
|
return prod.at(pos);
|
|
60
109
|
}
|
|
61
110
|
|
|
62
|
-
inline Set<Symbol>& getAttrSyms()
|
|
111
|
+
inline const Set<Symbol>& getAttrSyms() const
|
|
63
112
|
{
|
|
64
|
-
return this->
|
|
113
|
+
return this->attributeKinds;
|
|
65
114
|
}
|
|
66
115
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
void insertAttribute(
|
|
116
|
+
Kind insertTerminalKind(std::string strLit);
|
|
117
|
+
Kind insertNonTerminalKind(std::string strLit);
|
|
118
|
+
void insertAttribute(Kind kind, Attribute a);
|
|
70
119
|
|
|
71
120
|
inline static Kind getSymKind(Symbol sym)
|
|
72
121
|
{
|
|
@@ -86,7 +135,14 @@ public:
|
|
|
86
135
|
protected:
|
|
87
136
|
static constexpr unsigned char EdgeKindMaskBits = 8; ///< We use the lower 8 bits to denote edge kind
|
|
88
137
|
static constexpr u64_t EdgeKindMask = (~0ULL) >> (64 - EdgeKindMaskBits);
|
|
89
|
-
|
|
138
|
+
Kind startKind;
|
|
139
|
+
private:
|
|
140
|
+
Set<Kind> attributeKinds;
|
|
141
|
+
Map<Kind, Set<Attribute>> kind2AttrsMap;
|
|
142
|
+
Map<Symbol, Productions> rawProductions;
|
|
143
|
+
Kind totalKind;
|
|
144
|
+
Map<std::string, Kind> nonterminals;
|
|
145
|
+
Map<std::string, Kind> terminals;
|
|
90
146
|
};
|
|
91
147
|
|
|
92
148
|
class CFLGrammar : public GrammarBase
|
|
@@ -127,39 +183,39 @@ public:
|
|
|
127
183
|
return secondRHS2Prods;
|
|
128
184
|
}
|
|
129
185
|
|
|
130
|
-
const bool hasProdsFromFirstRHS(Symbol sym) const
|
|
186
|
+
const bool hasProdsFromFirstRHS(const Symbol sym) const
|
|
131
187
|
{
|
|
132
188
|
auto it = firstRHS2Prods.find(sym);
|
|
133
189
|
return it!=firstRHS2Prods.end();
|
|
134
190
|
}
|
|
135
191
|
|
|
136
|
-
const bool hasProdsFromSingleRHS(Symbol sym) const
|
|
192
|
+
const bool hasProdsFromSingleRHS(const Symbol sym) const
|
|
137
193
|
{
|
|
138
194
|
auto it = singleRHS2Prods.find(sym);
|
|
139
195
|
return it!=singleRHS2Prods.end();
|
|
140
196
|
}
|
|
141
197
|
|
|
142
|
-
const bool hasProdsFromSecondRHS(Symbol sym) const
|
|
198
|
+
const bool hasProdsFromSecondRHS(const Symbol sym) const
|
|
143
199
|
{
|
|
144
200
|
auto it = secondRHS2Prods.find(sym);
|
|
145
201
|
return it!=secondRHS2Prods.end();
|
|
146
202
|
}
|
|
147
203
|
|
|
148
|
-
const Productions& getProdsFromSingleRHS(Symbol sym) const
|
|
204
|
+
const Productions& getProdsFromSingleRHS(const Symbol sym) const
|
|
149
205
|
{
|
|
150
206
|
auto it = singleRHS2Prods.find(sym);
|
|
151
207
|
assert(it!=singleRHS2Prods.end() && "production (X -> sym) not found for sym!!");
|
|
152
208
|
return it->second;
|
|
153
209
|
}
|
|
154
210
|
|
|
155
|
-
const Productions& getProdsFromFirstRHS(Symbol sym) const
|
|
211
|
+
const Productions& getProdsFromFirstRHS(const Symbol sym) const
|
|
156
212
|
{
|
|
157
213
|
auto it = firstRHS2Prods.find(sym);
|
|
158
214
|
assert(it!=firstRHS2Prods.end() && "production (X -> sym Y ) not found for sym!!");
|
|
159
215
|
return it->second;
|
|
160
216
|
}
|
|
161
217
|
|
|
162
|
-
const Productions& getProdsFromSecondRHS(Symbol sym) const
|
|
218
|
+
const Productions& getProdsFromSecondRHS(const Symbol sym) const
|
|
163
219
|
{
|
|
164
220
|
auto it = secondRHS2Prods.find(sym);
|
|
165
221
|
assert(it!=secondRHS2Prods.end() && "production (X -> Y sym) not found for sym!!");
|
|
@@ -167,22 +223,22 @@ public:
|
|
|
167
223
|
}
|
|
168
224
|
|
|
169
225
|
|
|
170
|
-
const Symbol& getLHSSymbol(const Production& prod)
|
|
226
|
+
const Symbol& getLHSSymbol(const Production& prod) const
|
|
171
227
|
{
|
|
172
228
|
return prod.at(0);
|
|
173
229
|
}
|
|
174
230
|
|
|
175
|
-
const Symbol& getFirstRHSSymbol(const Production& prod)
|
|
231
|
+
const Symbol& getFirstRHSSymbol(const Production& prod) const
|
|
176
232
|
{
|
|
177
233
|
return prod.at(1);
|
|
178
234
|
}
|
|
179
235
|
|
|
180
|
-
const Symbol& getSecondRHSSymbol(const Production& prod)
|
|
236
|
+
const Symbol& getSecondRHSSymbol(const Production& prod) const
|
|
181
237
|
{
|
|
182
238
|
return prod.at(2);
|
|
183
239
|
}
|
|
184
240
|
|
|
185
|
-
void dump();
|
|
241
|
+
void dump() const;
|
|
186
242
|
|
|
187
243
|
const inline int num_generator()
|
|
188
244
|
{
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
Start:
|
|
2
2
|
V
|
|
3
3
|
Productions:
|
|
4
|
+
F -> Addr;
|
|
5
|
+
F -> Addr ( Copy ) *;
|
|
6
|
+
F -> Addr ( Store V Load ) *;
|
|
4
7
|
F -> ( Copy ) *;
|
|
5
8
|
F -> ( Store V Load ) *;
|
|
9
|
+
Fbar -> Addrbar;
|
|
10
|
+
Fbar -> Addrbar ( Copybar ) *;
|
|
11
|
+
Fbar -> Addrbar ( Loadbar V Storebar ) *;
|
|
6
12
|
Fbar -> ( Copybar ) *;
|
|
7
13
|
Fbar -> ( Loadbar V Storebar ) *;
|
|
8
14
|
V -> Fbar V F;
|
|
9
15
|
V -> Gepbar_i V Gep_i;
|
|
10
16
|
V -> Addrbar Addr;
|
|
11
|
-
V -> epsilon;
|
|
17
|
+
V -> epsilon;
|
|
18
|
+
|
|
19
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Start:
|
|
2
|
+
V
|
|
3
|
+
Productions:
|
|
4
|
+
F -> ( Copy ) *;
|
|
5
|
+
F -> ( Store V Load ) *;
|
|
6
|
+
Fbar -> ( Copybar ) *;
|
|
7
|
+
Fbar -> ( Loadbar Vbar Storebar ) *;
|
|
8
|
+
V -> Fbar V F;
|
|
9
|
+
V -> Gepbar_i V Gep_i;
|
|
10
|
+
V -> Addrbar Addr;
|
|
11
|
+
V -> epsilon;
|
|
12
|
+
Vbar -> Fbar Vbar Fbar;
|
|
13
|
+
Vbar -> Gepbar_i Vbar Gep_i;
|
|
14
|
+
Vbar -> Addrbar Addr;
|
|
15
|
+
Vbar -> epsilon;
|
|
16
|
+
|
|
@@ -39,7 +39,19 @@ namespace SVF
|
|
|
39
39
|
|
|
40
40
|
class CFLGraphBuilder
|
|
41
41
|
{
|
|
42
|
+
private:
|
|
43
|
+
typedef CFLGrammar::Kind Kind;
|
|
44
|
+
typedef CFLGrammar::Symbol Symbol;
|
|
45
|
+
Map<std::string, Kind> label2KindMap;
|
|
46
|
+
Map<Kind, std::string> kind2LabelMap;
|
|
47
|
+
Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>> kind2AttrsMap;
|
|
48
|
+
bool externMap;
|
|
49
|
+
Symbol current;
|
|
50
|
+
|
|
42
51
|
public:
|
|
52
|
+
/// add attribute to kind2Attribute Map
|
|
53
|
+
void addAttribute(CFLGrammar::Kind kind, CFLGrammar::Attribute attribute);
|
|
54
|
+
|
|
43
55
|
/// Build graph by copying nodes and edges from any graph inherited from GenericGraph
|
|
44
56
|
template<class N, class E>
|
|
45
57
|
void build(GenericGraph<N,E>* graph, CFLGraph* cflGraph)
|
|
@@ -61,11 +73,22 @@ public:
|
|
|
61
73
|
|
|
62
74
|
/// Build Bidirectional graph by copying nodes and edges from any graph inherited from GenericGraph
|
|
63
75
|
template<class N, class E>
|
|
64
|
-
CFLGraph* buildBigraph(GenericGraph<N,E>* graph)
|
|
76
|
+
CFLGraph* buildBigraph(GenericGraph<N,E>* graph, Kind startKind)
|
|
65
77
|
{
|
|
66
|
-
CFLGraph *cflGraph = new CFLGraph();
|
|
78
|
+
CFLGraph *cflGraph = new CFLGraph(startKind);
|
|
67
79
|
Map<std::string, SVF::CFLGraph::Symbol> ConstMap = {{"Addr",0}, {"Copy", 1},{"Store", 2},{"Load", 3},{"Gep_i", 4},{"Vgep", 5},{"Addrbar",6}, {"Copybar", 7},{"Storebar", 8},{"Loadbar", 9},{"Gepbar_i", 10},{"Vgepbar", 11}};
|
|
68
|
-
|
|
80
|
+
externMap = true;
|
|
81
|
+
for(auto pairV : ConstMap)
|
|
82
|
+
{
|
|
83
|
+
if(label2KindMap.find(pairV.first) == label2KindMap.end())
|
|
84
|
+
{
|
|
85
|
+
label2KindMap.insert(pairV);
|
|
86
|
+
}
|
|
87
|
+
if(kind2LabelMap.find(pairV.second) == kind2LabelMap.end())
|
|
88
|
+
{
|
|
89
|
+
kind2LabelMap.insert(make_pair(pairV.second, pairV.first));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
69
92
|
for(auto it = graph->begin(); it!= graph->end(); it++)
|
|
70
93
|
{
|
|
71
94
|
CFLNode* node = new CFLNode((*it).first);
|
|
@@ -82,23 +105,23 @@ public:
|
|
|
82
105
|
if(NormalGepCGEdge::classof(edge))
|
|
83
106
|
{
|
|
84
107
|
NormalGepCGEdge *nGepEdge = SVFUtil::dyn_cast<NormalGepCGEdge>(edge);
|
|
85
|
-
CFLGrammar::Attribute
|
|
86
|
-
|
|
87
|
-
edgeLabel = CFLGrammar::getAttributedKind(
|
|
108
|
+
CFLGrammar::Attribute attr = nGepEdge->getConstantFieldIdx();
|
|
109
|
+
addAttribute(edgeLabel, attr);
|
|
110
|
+
edgeLabel = CFLGrammar::getAttributedKind(attr, edgeLabel);
|
|
88
111
|
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel);
|
|
89
|
-
std::string key =
|
|
112
|
+
std::string key = kind2LabelMap[edge->getEdgeKind()];
|
|
90
113
|
key.pop_back();
|
|
91
114
|
key.pop_back(); // _i standsfor attribute variable should place at last
|
|
92
115
|
key.append("bar_i"); // for example Gep_i should be Gepbar_i, not Gep_ibar
|
|
93
|
-
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFLGrammar::getAttributedKind(
|
|
94
|
-
|
|
116
|
+
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFLGrammar::getAttributedKind(attr, label2KindMap[key]));
|
|
117
|
+
addAttribute(label2KindMap[key], attr);
|
|
95
118
|
}
|
|
96
119
|
else
|
|
97
120
|
{
|
|
98
121
|
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel);
|
|
99
|
-
std::string key =
|
|
122
|
+
std::string key = kind2LabelMap[edge->getEdgeKind()];
|
|
100
123
|
key.append("bar");
|
|
101
|
-
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()),
|
|
124
|
+
cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), label2KindMap[key]);
|
|
102
125
|
}
|
|
103
126
|
}
|
|
104
127
|
}
|
|
@@ -109,6 +132,23 @@ public:
|
|
|
109
132
|
|
|
110
133
|
/// Build graph from Dot
|
|
111
134
|
CFLGraph *buildFromDot(std::string filename, GrammarBase *grammar);
|
|
135
|
+
|
|
136
|
+
Map<std::string, Kind>& getLabel2KindMap()
|
|
137
|
+
{
|
|
138
|
+
return this->label2KindMap;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
Map<Kind, std::string>& getKind2LabelMap()
|
|
142
|
+
{
|
|
143
|
+
return this->kind2LabelMap;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>>& getKind2AttrsMap()
|
|
147
|
+
{
|
|
148
|
+
return this->kind2AttrsMap;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
112
152
|
};
|
|
113
153
|
}// SVF
|
|
114
154
|
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
#include "MemoryModel/PointerAnalysisImpl.h"
|
|
12
12
|
#include "DDA/DDAVFSolver.h"
|
|
13
13
|
#include "Util/DPItem.h"
|
|
14
|
-
#include "SVF-FE/DataFlowUtil.h"
|
|
15
14
|
|
|
16
15
|
namespace SVF
|
|
17
16
|
{
|
|
@@ -195,7 +194,6 @@ private:
|
|
|
195
194
|
ConstSVFGEdgeSet insensitveEdges;///< insensitive call-return edges
|
|
196
195
|
FlowDDA* flowDDA; ///< downgrade to flowDDA if out-of-budget
|
|
197
196
|
DDAClient* _client; ///< DDA client
|
|
198
|
-
PTACFInfoBuilder loopInfoBuilder; ///< LoopInfo
|
|
199
197
|
};
|
|
200
198
|
|
|
201
199
|
} // End namespace SVF
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
#include "MemoryModel/PointerAnalysisImpl.h"
|
|
12
12
|
#include "Util/DPItem.h"
|
|
13
13
|
#include "DDA/DDAVFSolver.h"
|
|
14
|
-
#include "SVF-FE/DataFlowUtil.h"
|
|
15
14
|
|
|
16
15
|
namespace SVF
|
|
17
16
|
{
|
|
@@ -143,7 +142,6 @@ public:
|
|
|
143
142
|
|
|
144
143
|
private:
|
|
145
144
|
DDAClient* _client; ///< DDA client
|
|
146
|
-
PTACFInfoBuilder loopInfoBuilder; ///< LoopInfo
|
|
147
145
|
};
|
|
148
146
|
|
|
149
147
|
} // End namespace SVF
|
|
@@ -77,16 +77,13 @@ class CFLGraph: public GenericCFLGraphTy
|
|
|
77
77
|
{
|
|
78
78
|
public:
|
|
79
79
|
typedef CFLGrammar::Symbol Symbol;
|
|
80
|
+
typedef CFLGrammar::Kind Kind;
|
|
80
81
|
typedef GenericNode<CFLNode,CFLEdge>::GEdgeSetTy CFLEdgeSet;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Map<CFLGrammar::Kind, Set<CFLGrammar::Attribute>> kind2AttrMap;
|
|
85
|
-
bool externMap;
|
|
86
|
-
Symbol current;
|
|
87
|
-
|
|
88
|
-
CFLGraph()
|
|
82
|
+
Kind startKind;
|
|
83
|
+
|
|
84
|
+
CFLGraph(Kind kind)
|
|
89
85
|
{
|
|
86
|
+
startKind = kind;
|
|
90
87
|
}
|
|
91
88
|
~CFLGraph() override = default;
|
|
92
89
|
|
|
@@ -100,27 +97,6 @@ public:
|
|
|
100
97
|
|
|
101
98
|
void view();
|
|
102
99
|
|
|
103
|
-
void setMap(Map<std::string, Symbol> &labelMap);
|
|
104
|
-
/// Set label2Sym from External
|
|
105
|
-
void setMap(GrammarBase *grammar);
|
|
106
|
-
|
|
107
|
-
/// add attribute to kind2Attribute Map
|
|
108
|
-
void addAttribute(CFLGrammar::Kind kind, CFLGrammar::Attribute attribute)
|
|
109
|
-
{
|
|
110
|
-
if(kind2AttrMap.find(kind) == kind2AttrMap.end())
|
|
111
|
-
{
|
|
112
|
-
Set<CFLGrammar::Attribute> attrs {attribute};
|
|
113
|
-
kind2AttrMap.insert(make_pair(kind, attrs));
|
|
114
|
-
}
|
|
115
|
-
else
|
|
116
|
-
{
|
|
117
|
-
if(kind2AttrMap[kind].find(attribute) == kind2AttrMap[kind].end())
|
|
118
|
-
{
|
|
119
|
-
kind2AttrMap[kind].insert(attribute);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
100
|
private:
|
|
125
101
|
CFLEdgeSet cflEdgeSet;
|
|
126
102
|
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
#include "Graphs/ICFGNode.h"
|
|
34
34
|
#include "Graphs/ICFGEdge.h"
|
|
35
35
|
#include "Util/WorkList.h"
|
|
36
|
+
#include "MemoryModel/SVFLoop.h"
|
|
36
37
|
|
|
37
38
|
namespace SVF
|
|
38
39
|
{
|
|
@@ -60,6 +61,8 @@ public:
|
|
|
60
61
|
typedef Map<const Instruction*, CallICFGNode *> CSToCallNodeMapTy;
|
|
61
62
|
typedef Map<const Instruction*, RetICFGNode *> CSToRetNodeMapTy;
|
|
62
63
|
typedef Map<const Instruction*, IntraICFGNode *> InstToBlockNodeMapTy;
|
|
64
|
+
typedef std::vector<const SVFLoop *> SVFLoopVec;
|
|
65
|
+
typedef Map<const ICFGNode *, SVFLoopVec> ICFGNodeToSVFLoopVec;
|
|
63
66
|
|
|
64
67
|
NodeID totalICFGNode;
|
|
65
68
|
|
|
@@ -70,15 +73,15 @@ private:
|
|
|
70
73
|
CSToRetNodeMapTy CSToRetNodeMap; ///< map a callsite to its RetICFGNode
|
|
71
74
|
InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode
|
|
72
75
|
GlobalICFGNode* globalBlockNode; ///< unique basic block for all globals
|
|
76
|
+
ICFGNodeToSVFLoopVec icfgNodeToSVFLoopVec; ///< map ICFG node to the SVF loops where it resides
|
|
77
|
+
|
|
73
78
|
|
|
74
79
|
public:
|
|
75
80
|
/// Constructor
|
|
76
81
|
ICFG();
|
|
77
82
|
|
|
78
83
|
/// Destructor
|
|
79
|
-
virtual ~ICFG()
|
|
80
|
-
{
|
|
81
|
-
}
|
|
84
|
+
virtual ~ICFG();
|
|
82
85
|
|
|
83
86
|
/// Get a ICFG node
|
|
84
87
|
inline ICFGNode* getICFGNode(NodeID id) const
|
|
@@ -111,6 +114,33 @@ public:
|
|
|
111
114
|
/// update ICFG for indirect calls
|
|
112
115
|
void updateCallGraph(PTACallGraph* callgraph);
|
|
113
116
|
|
|
117
|
+
/// Whether node is in a loop
|
|
118
|
+
inline bool isInLoop(const ICFGNode *node)
|
|
119
|
+
{
|
|
120
|
+
auto it = icfgNodeToSVFLoopVec.find(node);
|
|
121
|
+
return it != icfgNodeToSVFLoopVec.end();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/// Whether node is in a loop
|
|
125
|
+
inline bool isInLoop(const Instruction *inst)
|
|
126
|
+
{
|
|
127
|
+
return isInLoop(getICFGNode(inst));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// Insert (node, loop) to icfgNodeToSVFLoopVec
|
|
131
|
+
inline void addNodeToSVFLoop(const ICFGNode *node, const SVFLoop* loop)
|
|
132
|
+
{
|
|
133
|
+
icfgNodeToSVFLoopVec[node].push_back(loop);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/// Get loops where a node resides
|
|
137
|
+
inline SVFLoopVec& getSVFLoops(const ICFGNode *node)
|
|
138
|
+
{
|
|
139
|
+
auto it = icfgNodeToSVFLoopVec.find(node);
|
|
140
|
+
assert(it != icfgNodeToSVFLoopVec.end() && "node not in loop");
|
|
141
|
+
return it->second;
|
|
142
|
+
}
|
|
143
|
+
|
|
114
144
|
protected:
|
|
115
145
|
/// Remove a SVFG edge
|
|
116
146
|
inline void removeICFGEdge(ICFGEdge* edge)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
//===- SVFLoop.h -- SVFLoop of SVF ------------------------------//
|
|
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
|
+
* SVFLoop.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: 14, 06, 2022
|
|
27
|
+
* Author: Jiawei Wang, Xiao Cheng
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef SVF_SVFLOOP_H
|
|
31
|
+
#define SVF_SVFLOOP_H
|
|
32
|
+
|
|
33
|
+
#include "Util/SVFBasicTypes.h"
|
|
34
|
+
|
|
35
|
+
namespace SVF
|
|
36
|
+
{
|
|
37
|
+
class SVFLoop
|
|
38
|
+
{
|
|
39
|
+
typedef Set<const ICFGEdge *> ICFGEdgeSet;
|
|
40
|
+
typedef Set<const ICFGNode *> ICFGNodeSet;
|
|
41
|
+
private:
|
|
42
|
+
ICFGEdgeSet entryICFGEdges, backICFGEdges, inICFGEdges, outICFGEdges;
|
|
43
|
+
ICFGNodeSet icfgNodes;
|
|
44
|
+
u32_t loopBound;
|
|
45
|
+
|
|
46
|
+
public:
|
|
47
|
+
SVFLoop(const ICFGNodeSet &_nodes, u32_t _bound) :
|
|
48
|
+
icfgNodes(_nodes), loopBound(_bound)
|
|
49
|
+
{
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
virtual ~SVFLoop() = default;
|
|
54
|
+
|
|
55
|
+
inline ICFGNodeSet::iterator ICFGNodesBegin()
|
|
56
|
+
{
|
|
57
|
+
return icfgNodes.begin();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
inline ICFGNodeSet::iterator ICFGNodesEnd()
|
|
61
|
+
{
|
|
62
|
+
return icfgNodes.end();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
inline bool isInLoop(const ICFGNode *icfgNode) const
|
|
66
|
+
{
|
|
67
|
+
return icfgNodes.find(icfgNode) != icfgNodes.end();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
inline bool isEntryICFGEdge(const ICFGEdge *edge) const
|
|
71
|
+
{
|
|
72
|
+
return entryICFGEdges.find(edge) != entryICFGEdges.end();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
inline bool isBackICFGEdge(const ICFGEdge *edge) const
|
|
76
|
+
{
|
|
77
|
+
return backICFGEdges.find(edge) != entryICFGEdges.end();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
inline bool isInICFGEdge(const ICFGEdge *edge) const
|
|
81
|
+
{
|
|
82
|
+
return inICFGEdges.find(edge) != entryICFGEdges.end();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
inline bool isOutICFGEdge(const ICFGEdge *edge) const
|
|
86
|
+
{
|
|
87
|
+
return outICFGEdges.find(edge) != entryICFGEdges.end();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
inline void addEntryICFGEdge(const ICFGEdge *edge)
|
|
91
|
+
{
|
|
92
|
+
entryICFGEdges.insert(edge);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
inline ICFGEdgeSet::iterator entryICFGEdgesBegin()
|
|
96
|
+
{
|
|
97
|
+
return entryICFGEdges.begin();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
inline ICFGEdgeSet::iterator entryICFGEdgesEnd()
|
|
101
|
+
{
|
|
102
|
+
return entryICFGEdges.end();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
inline void addOutICFGEdge(const ICFGEdge *edge)
|
|
106
|
+
{
|
|
107
|
+
outICFGEdges.insert(edge);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
inline ICFGEdgeSet::iterator outICFGEdgesBegin()
|
|
111
|
+
{
|
|
112
|
+
return outICFGEdges.begin();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
inline ICFGEdgeSet::iterator outICFGEdgesEnd()
|
|
116
|
+
{
|
|
117
|
+
return outICFGEdges.end();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
inline void addBackICFGEdge(const ICFGEdge *edge)
|
|
121
|
+
{
|
|
122
|
+
backICFGEdges.insert(edge);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
inline ICFGEdgeSet::iterator backICFGEdgesBegin()
|
|
126
|
+
{
|
|
127
|
+
return backICFGEdges.begin();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
inline ICFGEdgeSet::iterator backICFGEdgesEnd()
|
|
131
|
+
{
|
|
132
|
+
return backICFGEdges.end();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
inline void addInICFGEdge(const ICFGEdge *edge)
|
|
136
|
+
{
|
|
137
|
+
inICFGEdges.insert(edge);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
inline ICFGEdgeSet::iterator inEdgesBegin()
|
|
141
|
+
{
|
|
142
|
+
return inICFGEdges.begin();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
inline ICFGEdgeSet::iterator inEdgesEnd()
|
|
146
|
+
{
|
|
147
|
+
return inICFGEdges.end();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
inline void setLoopBound(u32_t _bound)
|
|
151
|
+
{
|
|
152
|
+
loopBound = _bound;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
inline u32_t getLoopBound() const
|
|
156
|
+
{
|
|
157
|
+
return loopBound;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#endif //SVF_SVFLOOP_H
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//===- LLVMLoopAnalysis.h -- LoopAnalysis of SVF --------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2022> <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
|
+
* LLVMLoopAnalysis.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: 14, 06, 2022
|
|
27
|
+
* Author: Jiawei Wang, Xiao Cheng
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef SVF_LLVMLOOPANALYSIS_H
|
|
31
|
+
#define SVF_LLVMLOOPANALYSIS_H
|
|
32
|
+
|
|
33
|
+
#include "MemoryModel/SVFIR.h"
|
|
34
|
+
#include "MemoryModel/SVFLoop.h"
|
|
35
|
+
|
|
36
|
+
namespace SVF
|
|
37
|
+
{
|
|
38
|
+
class LLVMLoopAnalysis
|
|
39
|
+
{
|
|
40
|
+
public:
|
|
41
|
+
|
|
42
|
+
/// Constructor
|
|
43
|
+
LLVMLoopAnalysis() = default;;
|
|
44
|
+
|
|
45
|
+
/// Destructor
|
|
46
|
+
virtual ~LLVMLoopAnalysis() = default;
|
|
47
|
+
|
|
48
|
+
/// Build llvm loops based on LoopInfo analysis
|
|
49
|
+
virtual void buildLLVMLoops(SVFModule *mod, std::vector<const Loop *> &llvmLoops);
|
|
50
|
+
|
|
51
|
+
/// Start from here
|
|
52
|
+
virtual void build(ICFG *icfg);
|
|
53
|
+
|
|
54
|
+
/// Build SVF loops based on llvm loops
|
|
55
|
+
virtual void buildSVFLoops(ICFG *icfg, std::vector<const Loop *> &llvmLoops);
|
|
56
|
+
};
|
|
57
|
+
} // end fo SVF
|
|
58
|
+
|
|
59
|
+
#endif //SVF_LLVMLOOPANALYSIS_H
|
|
@@ -260,6 +260,10 @@ public:
|
|
|
260
260
|
static const llvm::cl::opt<bool> GraphIsFromDot;
|
|
261
261
|
static const llvm::cl::opt<bool> GrammarIsEBNF;
|
|
262
262
|
static const llvm::cl::opt<bool> FlexSymMap;
|
|
263
|
+
|
|
264
|
+
// Loop Analysis
|
|
265
|
+
static const llvm::cl::opt<bool> LoopAnalysis;
|
|
266
|
+
static const llvm::cl::opt<unsigned> LoopBound;
|
|
263
267
|
};
|
|
264
268
|
} // namespace SVF
|
|
265
269
|
|
|
Binary file
|
|
Binary file
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
#include "MemoryModel/PointerAnalysisImpl.h"
|
|
12
12
|
#include "DDA/DDAVFSolver.h"
|
|
13
13
|
#include "Util/DPItem.h"
|
|
14
|
-
#include "SVF-FE/DataFlowUtil.h"
|
|
15
14
|
|
|
16
15
|
namespace SVF
|
|
17
16
|
{
|
|
@@ -195,7 +194,6 @@ private:
|
|
|
195
194
|
ConstSVFGEdgeSet insensitveEdges;///< insensitive call-return edges
|
|
196
195
|
FlowDDA* flowDDA; ///< downgrade to flowDDA if out-of-budget
|
|
197
196
|
DDAClient* _client; ///< DDA client
|
|
198
|
-
PTACFInfoBuilder loopInfoBuilder; ///< LoopInfo
|
|
199
197
|
};
|
|
200
198
|
|
|
201
199
|
} // End namespace SVF
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
#include "MemoryModel/PointerAnalysisImpl.h"
|
|
12
12
|
#include "Util/DPItem.h"
|
|
13
13
|
#include "DDA/DDAVFSolver.h"
|
|
14
|
-
#include "SVF-FE/DataFlowUtil.h"
|
|
15
14
|
|
|
16
15
|
namespace SVF
|
|
17
16
|
{
|
|
@@ -143,7 +142,6 @@ public:
|
|
|
143
142
|
|
|
144
143
|
private:
|
|
145
144
|
DDAClient* _client; ///< DDA client
|
|
146
|
-
PTACFInfoBuilder loopInfoBuilder; ///< LoopInfo
|
|
147
145
|
};
|
|
148
146
|
|
|
149
147
|
} // End namespace SVF
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
#include "Graphs/ICFGNode.h"
|
|
34
34
|
#include "Graphs/ICFGEdge.h"
|
|
35
35
|
#include "Util/WorkList.h"
|
|
36
|
+
#include "MemoryModel/SVFLoop.h"
|
|
36
37
|
|
|
37
38
|
namespace SVF
|
|
38
39
|
{
|
|
@@ -60,6 +61,8 @@ public:
|
|
|
60
61
|
typedef Map<const Instruction*, CallICFGNode *> CSToCallNodeMapTy;
|
|
61
62
|
typedef Map<const Instruction*, RetICFGNode *> CSToRetNodeMapTy;
|
|
62
63
|
typedef Map<const Instruction*, IntraICFGNode *> InstToBlockNodeMapTy;
|
|
64
|
+
typedef std::vector<const SVFLoop *> SVFLoopVec;
|
|
65
|
+
typedef Map<const ICFGNode *, SVFLoopVec> ICFGNodeToSVFLoopVec;
|
|
63
66
|
|
|
64
67
|
NodeID totalICFGNode;
|
|
65
68
|
|
|
@@ -70,15 +73,15 @@ private:
|
|
|
70
73
|
CSToRetNodeMapTy CSToRetNodeMap; ///< map a callsite to its RetICFGNode
|
|
71
74
|
InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode
|
|
72
75
|
GlobalICFGNode* globalBlockNode; ///< unique basic block for all globals
|
|
76
|
+
ICFGNodeToSVFLoopVec icfgNodeToSVFLoopVec; ///< map ICFG node to the SVF loops where it resides
|
|
77
|
+
|
|
73
78
|
|
|
74
79
|
public:
|
|
75
80
|
/// Constructor
|
|
76
81
|
ICFG();
|
|
77
82
|
|
|
78
83
|
/// Destructor
|
|
79
|
-
virtual ~ICFG()
|
|
80
|
-
{
|
|
81
|
-
}
|
|
84
|
+
virtual ~ICFG();
|
|
82
85
|
|
|
83
86
|
/// Get a ICFG node
|
|
84
87
|
inline ICFGNode* getICFGNode(NodeID id) const
|
|
@@ -111,6 +114,33 @@ public:
|
|
|
111
114
|
/// update ICFG for indirect calls
|
|
112
115
|
void updateCallGraph(PTACallGraph* callgraph);
|
|
113
116
|
|
|
117
|
+
/// Whether node is in a loop
|
|
118
|
+
inline bool isInLoop(const ICFGNode *node)
|
|
119
|
+
{
|
|
120
|
+
auto it = icfgNodeToSVFLoopVec.find(node);
|
|
121
|
+
return it != icfgNodeToSVFLoopVec.end();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/// Whether node is in a loop
|
|
125
|
+
inline bool isInLoop(const Instruction *inst)
|
|
126
|
+
{
|
|
127
|
+
return isInLoop(getICFGNode(inst));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// Insert (node, loop) to icfgNodeToSVFLoopVec
|
|
131
|
+
inline void addNodeToSVFLoop(const ICFGNode *node, const SVFLoop* loop)
|
|
132
|
+
{
|
|
133
|
+
icfgNodeToSVFLoopVec[node].push_back(loop);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/// Get loops where a node resides
|
|
137
|
+
inline SVFLoopVec& getSVFLoops(const ICFGNode *node)
|
|
138
|
+
{
|
|
139
|
+
auto it = icfgNodeToSVFLoopVec.find(node);
|
|
140
|
+
assert(it != icfgNodeToSVFLoopVec.end() && "node not in loop");
|
|
141
|
+
return it->second;
|
|
142
|
+
}
|
|
143
|
+
|
|
114
144
|
protected:
|
|
115
145
|
/// Remove a SVFG edge
|
|
116
146
|
inline void removeICFGEdge(ICFGEdge* edge)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
//===- SVFLoop.h -- SVFLoop of SVF ------------------------------//
|
|
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
|
+
* SVFLoop.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: 14, 06, 2022
|
|
27
|
+
* Author: Jiawei Wang, Xiao Cheng
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef SVF_SVFLOOP_H
|
|
31
|
+
#define SVF_SVFLOOP_H
|
|
32
|
+
|
|
33
|
+
#include "Util/SVFBasicTypes.h"
|
|
34
|
+
|
|
35
|
+
namespace SVF
|
|
36
|
+
{
|
|
37
|
+
class SVFLoop
|
|
38
|
+
{
|
|
39
|
+
typedef Set<const ICFGEdge *> ICFGEdgeSet;
|
|
40
|
+
typedef Set<const ICFGNode *> ICFGNodeSet;
|
|
41
|
+
private:
|
|
42
|
+
ICFGEdgeSet entryICFGEdges, backICFGEdges, inICFGEdges, outICFGEdges;
|
|
43
|
+
ICFGNodeSet icfgNodes;
|
|
44
|
+
u32_t loopBound;
|
|
45
|
+
|
|
46
|
+
public:
|
|
47
|
+
SVFLoop(const ICFGNodeSet &_nodes, u32_t _bound) :
|
|
48
|
+
icfgNodes(_nodes), loopBound(_bound)
|
|
49
|
+
{
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
virtual ~SVFLoop() = default;
|
|
54
|
+
|
|
55
|
+
inline ICFGNodeSet::iterator ICFGNodesBegin()
|
|
56
|
+
{
|
|
57
|
+
return icfgNodes.begin();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
inline ICFGNodeSet::iterator ICFGNodesEnd()
|
|
61
|
+
{
|
|
62
|
+
return icfgNodes.end();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
inline bool isInLoop(const ICFGNode *icfgNode) const
|
|
66
|
+
{
|
|
67
|
+
return icfgNodes.find(icfgNode) != icfgNodes.end();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
inline bool isEntryICFGEdge(const ICFGEdge *edge) const
|
|
71
|
+
{
|
|
72
|
+
return entryICFGEdges.find(edge) != entryICFGEdges.end();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
inline bool isBackICFGEdge(const ICFGEdge *edge) const
|
|
76
|
+
{
|
|
77
|
+
return backICFGEdges.find(edge) != entryICFGEdges.end();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
inline bool isInICFGEdge(const ICFGEdge *edge) const
|
|
81
|
+
{
|
|
82
|
+
return inICFGEdges.find(edge) != entryICFGEdges.end();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
inline bool isOutICFGEdge(const ICFGEdge *edge) const
|
|
86
|
+
{
|
|
87
|
+
return outICFGEdges.find(edge) != entryICFGEdges.end();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
inline void addEntryICFGEdge(const ICFGEdge *edge)
|
|
91
|
+
{
|
|
92
|
+
entryICFGEdges.insert(edge);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
inline ICFGEdgeSet::iterator entryICFGEdgesBegin()
|
|
96
|
+
{
|
|
97
|
+
return entryICFGEdges.begin();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
inline ICFGEdgeSet::iterator entryICFGEdgesEnd()
|
|
101
|
+
{
|
|
102
|
+
return entryICFGEdges.end();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
inline void addOutICFGEdge(const ICFGEdge *edge)
|
|
106
|
+
{
|
|
107
|
+
outICFGEdges.insert(edge);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
inline ICFGEdgeSet::iterator outICFGEdgesBegin()
|
|
111
|
+
{
|
|
112
|
+
return outICFGEdges.begin();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
inline ICFGEdgeSet::iterator outICFGEdgesEnd()
|
|
116
|
+
{
|
|
117
|
+
return outICFGEdges.end();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
inline void addBackICFGEdge(const ICFGEdge *edge)
|
|
121
|
+
{
|
|
122
|
+
backICFGEdges.insert(edge);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
inline ICFGEdgeSet::iterator backICFGEdgesBegin()
|
|
126
|
+
{
|
|
127
|
+
return backICFGEdges.begin();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
inline ICFGEdgeSet::iterator backICFGEdgesEnd()
|
|
131
|
+
{
|
|
132
|
+
return backICFGEdges.end();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
inline void addInICFGEdge(const ICFGEdge *edge)
|
|
136
|
+
{
|
|
137
|
+
inICFGEdges.insert(edge);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
inline ICFGEdgeSet::iterator inEdgesBegin()
|
|
141
|
+
{
|
|
142
|
+
return inICFGEdges.begin();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
inline ICFGEdgeSet::iterator inEdgesEnd()
|
|
146
|
+
{
|
|
147
|
+
return inICFGEdges.end();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
inline void setLoopBound(u32_t _bound)
|
|
151
|
+
{
|
|
152
|
+
loopBound = _bound;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
inline u32_t getLoopBound() const
|
|
156
|
+
{
|
|
157
|
+
return loopBound;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#endif //SVF_SVFLOOP_H
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//===- LLVMLoopAnalysis.h -- LoopAnalysis of SVF --------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2022> <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
|
+
* LLVMLoopAnalysis.h
|
|
25
|
+
*
|
|
26
|
+
* Created on: 14, 06, 2022
|
|
27
|
+
* Author: Jiawei Wang, Xiao Cheng
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef SVF_LLVMLOOPANALYSIS_H
|
|
31
|
+
#define SVF_LLVMLOOPANALYSIS_H
|
|
32
|
+
|
|
33
|
+
#include "MemoryModel/SVFIR.h"
|
|
34
|
+
#include "MemoryModel/SVFLoop.h"
|
|
35
|
+
|
|
36
|
+
namespace SVF
|
|
37
|
+
{
|
|
38
|
+
class LLVMLoopAnalysis
|
|
39
|
+
{
|
|
40
|
+
public:
|
|
41
|
+
|
|
42
|
+
/// Constructor
|
|
43
|
+
LLVMLoopAnalysis() = default;;
|
|
44
|
+
|
|
45
|
+
/// Destructor
|
|
46
|
+
virtual ~LLVMLoopAnalysis() = default;
|
|
47
|
+
|
|
48
|
+
/// Build llvm loops based on LoopInfo analysis
|
|
49
|
+
virtual void buildLLVMLoops(SVFModule *mod, std::vector<const Loop *> &llvmLoops);
|
|
50
|
+
|
|
51
|
+
/// Start from here
|
|
52
|
+
virtual void build(ICFG *icfg);
|
|
53
|
+
|
|
54
|
+
/// Build SVF loops based on llvm loops
|
|
55
|
+
virtual void buildSVFLoops(ICFG *icfg, std::vector<const Loop *> &llvmLoops);
|
|
56
|
+
};
|
|
57
|
+
} // end fo SVF
|
|
58
|
+
|
|
59
|
+
#endif //SVF_LLVMLOOPANALYSIS_H
|
|
@@ -260,6 +260,10 @@ public:
|
|
|
260
260
|
static const llvm::cl::opt<bool> GraphIsFromDot;
|
|
261
261
|
static const llvm::cl::opt<bool> GrammarIsEBNF;
|
|
262
262
|
static const llvm::cl::opt<bool> FlexSymMap;
|
|
263
|
+
|
|
264
|
+
// Loop Analysis
|
|
265
|
+
static const llvm::cl::opt<bool> LoopAnalysis;
|
|
266
|
+
static const llvm::cl::opt<unsigned> LoopBound;
|
|
263
267
|
};
|
|
264
268
|
} // namespace SVF
|
|
265
269
|
|