Predator
[unstable] git snapshot
Main Page
Related Pages
Namespaces
Data Structures
Files
File List
Globals
symstate.hh
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2009-2010 Kamil Dudka <kdudka@redhat.com>
3
*
4
* This file is part of predator.
5
*
6
* predator is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* any later version.
10
*
11
* predator is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with predator. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#ifndef H_GUARD_SYM_STATE_H
21
#define H_GUARD_SYM_STATE_H
22
23
/**
24
* @file symstate.hh
25
* @todo update dox
26
*/
27
28
#include <set>
29
#include <vector>
30
31
#include "
symheap.hh
"
32
33
namespace
CodeStorage {
34
class
Block;
35
}
36
37
class
SymState
{
38
private
:
39
typedef
std::vector<SymHeap *>
TList
;
40
41
public
:
42
typedef
TList::const_iterator
const_iterator
;
43
typedef
TList::iterator
iterator
;
44
45
public
:
46
SymState
() { }
47
virtual
~SymState
();
48
49
SymState
(
const
SymState
&);
50
SymState
&
operator=
(
const
SymState
&);
51
52
virtual
void
clear
();
53
54
virtual
void
swap
(
SymState
&other) {
55
heaps_
.swap(other.
heaps_
);
56
}
57
58
/**
59
* look for the given symbolic heap, return its index if found, -1
60
* otherwise
61
*/
62
virtual
int
lookup
(
const
SymHeap
&heap)
const
= 0;
63
64
/// insert given SymHeap object into the state
65
virtual
bool
insert
(
const
SymHeap
&sh,
bool
allowThreeWay =
true
);
66
67
/// return count of object stored in the container
68
size_t
size
()
const
{
return
heaps_
.size(); }
69
70
/// return nth SymHeap object, 0 <= nth < size()
71
const
SymHeap
&
operator[]
(
int
nth)
const
{
72
return
*
heaps_
[nth];
73
}
74
75
/// return STL-like iterator to go through the container
76
const_iterator
begin
()
const
{
return
heaps_
.begin(); }
77
78
/// return STL-like iterator to go through the container
79
const_iterator
end
()
const
{
return
heaps_
.end(); }
80
81
/// @copydoc begin() const
82
iterator
begin
() {
return
heaps_
.begin(); }
83
84
/// @copydoc begin() const
85
iterator
end
() {
return
heaps_
.end(); }
86
87
protected
:
88
/// insert @b new SymHeap that @ must be guaranteed to be not yet in
89
virtual
void
insertNew
(
const
SymHeap
&sh);
90
91
virtual
void
eraseExisting
(
int
nth) {
92
delete
heaps_
[nth];
93
heaps_
.erase(
heaps_
.begin() + nth);
94
}
95
96
virtual
void
swapExisting
(
int
nth,
SymHeap
&sh) {
97
SymHeap
&existing = *
heaps_
.at(nth);
98
existing.
swap
(sh);
99
}
100
101
virtual
void
rotateExisting
(
const
int
idxA,
const
int
idxB);
102
103
/// lookup/insert optimization in SymCallCache implementation
104
friend
class
PerFncCache
;
105
106
private
:
107
TList
heaps_
;
108
};
109
110
class
SymHeapList
:
public
SymState
{
111
public
:
112
SymHeapList
() { }
113
114
SymHeapList
(
const
SymState
&ref):
115
// safe to slice the base, as we have no data anyway
116
SymState
(ref)
117
{
118
}
119
120
SymHeapList
&
operator=
(
const
SymState
&ref) {
121
// safe to slice the base, as we have no data anyway
122
*
static_cast<
SymState
*
>
(
this
) = ref;
123
124
return
*
this
;
125
}
126
127
virtual
int
lookup
(
const
SymHeap
&)
const
{
128
return
/* not found */
-1;
129
}
130
};
131
132
/**
133
* symbolic state represented as a union of SymHeap objects (aka disjuncts)
134
*
135
* During the symbolic execution (see SymExec) we keep such a state per each
136
* basic block of the function just being processed. The result of a
137
* symbolically executed function is then the SymState taken from the basic
138
* block containing CL_INSN_RET as soon as the fix-point calculation has
139
* terminated.
140
*/
141
class
SymHeapUnion
:
public
SymState
{
142
public
:
143
virtual
int
lookup
(
const
SymHeap
&sh)
const
;
144
};
145
146
class
SymStateWithJoin
:
public
SymHeapUnion
{
147
public
:
148
virtual
bool
insert
(
const
SymHeap
&sh,
bool
allowThreeWay =
true
);
149
150
private
:
151
void
packState
(
unsigned
idx,
bool
allowThreeWay);
152
};
153
154
/**
155
* Extension of SymStateWithJoin, which distinguishes among already processed
156
* symbolic heaps and symbolic heaps scheduled for processing. Newly inserted
157
* symbolic heaps are always marked as scheduled. They can be marked as done
158
* later, using the setDone() method.
159
*/
160
class
SymStateMarked
:
public
SymStateWithJoin
{
161
public
:
162
SymStateMarked
():
163
cntPending_
(0)
164
{
165
}
166
167
/// import of SymState rewrites the base and invalidates all flags
168
SymStateMarked
&
operator=
(
const
SymState
&huni) {
169
static_cast<
SymState
&
>
(*this) = huni;
170
done_
.clear();
171
done_
.resize(huni.
size
(),
false
);
172
cntPending_
= huni.
size
();
173
return
*
this
;
174
}
175
176
virtual
void
clear
() {
177
SymStateWithJoin::clear
();
178
done_
.clear();
179
cntPending_
= 0;
180
}
181
182
/// @attention always reinitializes the markers
183
virtual
void
swap
(
SymState
&);
184
185
/// return count of heaps pending for execution
186
int
cntPending
()
const
{
187
return
cntPending_
;
188
}
189
190
protected
:
191
virtual
void
insertNew
(
const
SymHeap
&sh) {
192
SymStateWithJoin::insertNew
(sh);
193
194
// schedule the just inserted SymHeap for processing
195
done_
.push_back(
false
);
196
++
cntPending_
;
197
}
198
199
virtual
void
eraseExisting
(
int
nth) {
200
SymStateWithJoin::eraseExisting
(nth);
201
202
if
(!
done_
[nth])
203
--
cntPending_
;
204
205
done_
.erase(
done_
.begin() + nth);
206
}
207
208
virtual
void
swapExisting
(
int
nth,
SymHeap
&sh) {
209
SymStateWithJoin::swapExisting
(nth, sh);
210
211
if
(!
done_
.at(nth))
212
return
;
213
214
// an already processed heap has been generalized, we need to
215
// schedule it for precessing once again
216
done_
[nth] =
false
;
217
++
cntPending_
;
218
}
219
220
virtual
void
rotateExisting
(
const
int
idxA,
const
int
idxB);
221
222
friend
class
SymStateMap
;
223
224
public
:
225
/// check if the nth symbolic heap has been already processed
226
bool
isDone
(
int
nth)
const
{
227
return
done_
.at(nth);
228
}
229
230
/// mark the nth symbolic heap as processed
231
void
setDone
(
int
nth) {
232
if
(!
done_
.at(nth))
233
--
cntPending_
;
234
235
done_
[nth] =
true
;
236
}
237
238
private
:
239
typedef
std::vector<bool>
TDone
;
240
241
TDone
done_
;
242
int
cntPending_
;
243
};
244
245
class
IPendingCountProvider
{
246
public
:
247
virtual
~IPendingCountProvider
() { }
248
249
/// return count of heaps pending for execution in the specified blcok
250
virtual
int
cntPending
(
const
CodeStorage::Block
*)
const
= 0;
251
};
252
253
/**
254
* higher-level container that maintains a SymStateMarked object per each basic
255
* block. It's used by SymExecEngine and PathTracer classes.
256
*/
257
class
SymStateMap
:
public
IPendingCountProvider
{
258
public
:
259
typedef
std::vector<const CodeStorage::Block *>
TContBlock
;
260
261
SymStateMap
();
262
virtual
~SymStateMap
();
263
264
/// state lookup, basically equal to std::map semantic
265
SymStateMarked
&
operator[]
(
const
CodeStorage::Block
*);
266
267
/**
268
* managed insertion of the state that keeps track of the relation among
269
* source and destination basic blocks
270
* @param dst @b destination basic block (where the insertion occurs)
271
* @param sh an instance of symbolic heap that should be inserted
272
* @param allowThreeWay if true, three-way join is allowed
273
*/
274
bool
insert
(
const
CodeStorage::Block
*dst,
275
const
SymHeap
&sh,
276
const
bool
allowThreeWay =
true
277
);
278
279
/// true if the specified block has ever joined/entailed any given state
280
bool
anyReuseHappened
(
const
CodeStorage::Block
*)
const
;
281
282
virtual
int
cntPending
(
const
CodeStorage::Block
*)
const
;
283
284
private
:
285
/// object copying is @b not allowed
286
SymStateMap
(
const
SymStateMap
&);
287
288
/// object copying is @b not allowed
289
SymStateMap
&
operator=
(
const
SymStateMap
&);
290
291
private
:
292
struct
Private;
293
Private *
d
;
294
};
295
296
class
IStatsProvider
{
297
public
:
298
virtual
~IStatsProvider
() { }
299
virtual
void
printStats
()
const
= 0;
300
};
301
302
class
BlockScheduler
:
public
IStatsProvider
{
303
public
:
304
typedef
const
CodeStorage::Block
*
TBlock
;
305
typedef
std::set<TBlock>
TBlockSet
;
306
typedef
std::vector<TBlock>
TBlockList
;
307
308
public
:
309
BlockScheduler
(
const
IPendingCountProvider
&);
310
BlockScheduler
(
const
BlockScheduler
&);
311
~BlockScheduler
();
312
313
const
TBlockSet
&
todo
()
const
;
314
315
TBlockList
done
()
const
;
316
317
unsigned
cntWaiting
()
const
;
318
319
bool
schedule
(
const
TBlock
bb);
320
321
bool
getNext
(
TBlock
*dst);
322
323
virtual
void
printStats
()
const
;
324
325
private
:
326
// not implemented
327
BlockScheduler
&
operator=
(
const
BlockScheduler
&);
328
329
struct
Private;
330
Private *
d
;
331
};
332
333
#endif
/* H_GUARD_SYM_STATE_H */
Generated on Sun Feb 10 2013 17:38:16 for Predator by
1.8.3.1