Predator
[unstable] git snapshot
Main Page
Related Pages
Namespaces
Data Structures
Files
File List
Globals
symtrace.hh
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2011 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_TRACE_H
21
#define H_GUARD_SYM_TRACE_H
22
23
/**
24
* @file symtrace.hh
25
* directed acyclic graph of the symbolic execution trace, see namespace Trace
26
*/
27
28
#include "
config.h
"
29
30
#include "
id_mapper.hh
"
31
#include "
join_status.hh
"
32
#include "
symbt.hh
"
// needed for EMsgLevel
33
#include "
symheap.hh
"
// needed for EObjKind
34
35
#include <vector>
36
#include <string>
37
38
struct
cl_loc
;
39
40
class
SymState
;
41
42
namespace
CodeStorage {
43
struct
Fnc;
44
struct
Insn;
45
}
46
47
/// directed acyclic graph of the symbolic execution trace
48
namespace
Trace {
49
50
class
Node;
51
52
struct
TracePlotter;
53
54
typedef
const
struct
cl_loc
*
TLoc
;
55
typedef
const
CodeStorage::Fnc
*
TFnc
;
56
typedef
const
CodeStorage::Insn
*
TInsn
;
57
58
typedef
std::vector<Node *>
TNodeList
;
59
60
// TODO: should we use a more generic ID type?
61
typedef
IdMapper<TObjId, OBJ_INVALID, OBJ_MAX_ID>
TIdMapper
;
62
typedef
std::vector<TIdMapper>
TIdMapperList
;
63
64
std::string
insnToLabel
(
const
TInsn
insn);
65
66
/// an abstract base for Node and NodeHandle (externally not much useful)
67
class
NodeBase
{
68
protected
:
69
/// list of all (0..n) parent nodes
70
TNodeList
parents_
;
71
72
/// this is an abstract class, its instantiation is @b not allowed
73
NodeBase
() { }
74
75
/// construct Node with exactly one parent, can be extended later
76
NodeBase
(
Node
*node):
77
parents_
(1, node)
78
{
79
}
80
81
public
:
82
/// force virtual destructor
83
virtual
~NodeBase
();
84
85
/// this can be called only on nodes with exactly one parent
86
virtual
Node
*
parent
()
const
;
87
88
/// reference to list of parents (containing 0..n pointers)
89
const
TNodeList
&
parents
()
const
{
return
parents_
; }
90
91
private
:
92
virtual
void
replaceParent
(
Node
*parentOld,
Node
*parentNew);
93
friend
void
replaceNode
(
Node
*tr,
Node
*by);
94
};
95
96
/// an abstract node of the symbolic execution trace graph
97
class
Node
:
public
NodeBase
{
98
private
:
99
/// birth notification from a child node
100
void
notifyBirth
(
NodeBase
*child);
101
102
/// death notification from a child node
103
void
notifyDeath
(
NodeBase
*child);
104
105
friend
class
NodeBase
;
106
friend
class
NodeHandle
;
107
108
protected
:
109
/// this is an abstract class, its instantiation is @b not allowed
110
Node
():
111
alive_
(true)
112
{
113
}
114
115
/// constructor for nodes with exactly one parent
116
Node
(
Node
*ref):
117
NodeBase
(ref),
118
alive_
(true)
119
{
120
idMapperList_
.resize(1U);
121
ref->
notifyBirth
(
this
);
122
}
123
124
/// constructor for nodes with exactly two parents
125
Node
(
Node
*ref1,
Node
*ref2):
126
NodeBase
(ref1),
127
alive_
(true)
128
{
129
parents_
.push_back(ref2);
130
idMapperList_
.resize(2U);
131
ref1->
notifyBirth
(
this
);
132
ref2->
notifyBirth
(
this
);
133
}
134
135
virtual
~Node
();
136
137
/// serialize this node to the given plot (externally not much useful)
138
virtual
void
plotNode
(TracePlotter &)
const
= 0;
139
140
friend
void
plotTraceCore
(TracePlotter &);
141
142
public
:
143
/// used to store a list of child nodes
144
typedef
std::vector<NodeBase *>
TBaseList
;
145
146
/// reference to list of child nodes (containing 0..n pointers)
147
const
TBaseList
&
children
()
const
{
return
children_
; }
148
149
/// print the node in a human-readable format if considered interesting
150
virtual
Node
*
/* selected predecessor */
printNode
()
const
{
151
return
this->
parent
();
152
}
153
154
public
:
155
/// return the ID mapping describing the operation behind the trace node
156
TIdMapperList
&
idMapperList
();
157
158
/// return the ID mapping describing the operation behind the trace node
159
const
TIdMapperList
&
idMapperList
()
const
;
160
161
/// return the ID mapping describing the operation behind the trace node
162
TIdMapper
&
idMapper
();
163
164
/// return the ID mapping describing the operation behind the trace node
165
const
TIdMapper
&
idMapper
()
const
;
166
167
private
:
168
// copying NOT allowed
169
Node
(
const
Node
&);
170
Node
&
operator=
(
const
Node
&);
171
172
protected
:
173
TIdMapperList
idMapperList_
;
174
175
private
:
176
TBaseList
children_
;
177
bool
alive_
;
178
};
179
180
void
replaceNode
(
Node
*tr,
Node
*by);
181
182
/// useful to prevent a trace sub-graph from being destroyed too early
183
class
NodeHandle
:
public
NodeBase
{
184
public
:
185
/// initialize the handle with the given node, can be reset later
186
NodeHandle
(
Node
*ref):
187
NodeBase
(ref)
188
{
189
ref->
notifyBirth
(
this
);
190
}
191
192
/// return the node stored within this handle
193
Node
*
node
()
const
{
194
return
this->
parent
();
195
}
196
197
/// release the old node and re-initialize the handle with the new one
198
void
reset
(
Node
*);
199
200
/// overridden copy constructor keeping the semantics of a handle
201
NodeHandle
(
const
NodeHandle
&tpl):
202
NodeBase
(tpl.
node
())
203
{
204
this->
parent
()->
notifyBirth
(
this
);
205
}
206
207
/// overridden assignment operator keeping the semantics of a handle
208
NodeHandle
&
operator=
(
const
NodeHandle
&tpl) {
209
this->
reset
(tpl.
node
());
210
return
*
this
;
211
}
212
};
213
214
/// used to explicitly highlight trace graph nodes that should not be reachable
215
class
TransientNode
:
public
Node
{
216
public
:
217
/// @param origin describe where the unreachable node originates from
218
TransientNode
(
const
char
*origin):
219
origin_
(origin)
220
{
221
}
222
223
virtual
Node
*
printNode
()
const
;
224
225
protected
:
226
void
virtual
plotNode
(TracePlotter &)
const
;
227
228
private
:
229
const
char
*
origin_
;
230
};
231
232
/// root node of the trace graph (usually a call of the root function)
233
class
RootNode
:
public
Node
{
234
private
:
235
const
TFnc
rootFnc_
;
236
237
public
:
238
/// @param rootFnc a CodeStorage::Fnc object used for the root call
239
RootNode
(
const
TFnc
rootFnc):
240
rootFnc_
(rootFnc)
241
{
242
}
243
244
virtual
Node
*
printNode
()
const
;
245
246
protected
:
247
void
virtual
plotNode
(TracePlotter &)
const
;
248
};
249
250
/// a trace graph node that represents a non-terminal instruction
251
class
InsnNode
:
public
Node
{
252
private
:
253
const
TInsn
insn_
;
254
const
bool
isBuiltin_
;
255
256
public
:
257
/**
258
* @param ref a reference to a trace leading to this instruction
259
* @param insn a CodeStorage::Insn object representing the instruction
260
* @param isBuiltin true, if the instruction is recognized as a built-in
261
*/
262
InsnNode
(
Node
*ref,
TInsn
insn,
const
bool
isBuiltin):
263
Node
(ref),
264
insn_
(insn),
265
isBuiltin_
(isBuiltin)
266
{
267
this->
idMapper
().
setNotFoundAction
(
TIdMapper::NFA_RETURN_IDENTITY
);
268
}
269
270
virtual
Node
*
printNode
()
const
;
271
272
protected
:
273
void
virtual
plotNode
(TracePlotter &)
const
;
274
};
275
276
/// a trace graph node that represents a conditional insn being traversed
277
class
CondNode
:
public
Node
{
278
private
:
279
const
TInsn
inCmp_
;
280
const
TInsn
inCnd_
;
281
const
bool
determ_
;
282
const
bool
branch_
;
283
284
public
:
285
/**
286
* @param ref a reference to a trace leading to this instruction
287
* @param inCmp a comparison instruction occurring prior to inCnd
288
* @param inCnd a conditional jump instruction being traversed
289
* @param determ true if the branch being taken was known in advance
290
* @param branch true if the 'then' branch was taken, false for 'else'
291
*/
292
CondNode
(
Node
*ref,
TInsn
inCmp,
TInsn
inCnd,
bool
determ,
bool
branch):
293
Node
(ref),
294
inCmp_
(inCmp),
295
inCnd_
(inCnd),
296
determ_
(determ),
297
branch_
(branch)
298
{
299
this->
idMapper
().
setNotFoundAction
(
TIdMapper::NFA_RETURN_IDENTITY
);
300
}
301
302
virtual
Node
*
printNode
()
const
;
303
304
protected
:
305
void
virtual
plotNode
(TracePlotter &)
const
;
306
};
307
308
/// a trace graph node that represents a @b single abstraction step
309
class
AbstractionNode
:
public
Node
{
310
private
:
311
const
EObjKind
kind_
;
312
std::string
name_
;
313
314
public
:
315
/**
316
* @param ref a trace leading to this abstraction step
317
* @param kind the kind of abstraction step being performed
318
*/
319
AbstractionNode
(
Node
*ref,
EObjKind
kind):
320
Node
(ref),
321
kind_
(kind)
322
{
323
}
324
325
/// @param name name of the corresponding debug plot (empty if unused)
326
void
setPlotName
(
const
std::string &name) {
327
name_
= name;
328
}
329
330
protected
:
331
void
virtual
plotNode
(TracePlotter &)
const
;
332
};
333
334
/// a trace graph node that represents a @b single concretization step
335
class
ConcretizationNode
:
public
Node
{
336
private
:
337
const
EObjKind
kind_
;
338
const
std::string
name_
;
339
340
public
:
341
/**
342
* @param ref a trace leading to this concretization step
343
* @param kind the kind of concretization step being performed
344
* @param name name of the corresponding debug plot (empty if unused)
345
*/
346
ConcretizationNode
(
Node
*ref,
EObjKind
kind,
const
std::string &name):
347
Node
(ref),
348
kind_
(kind),
349
name_
(name)
350
{
351
}
352
353
protected
:
354
void
virtual
plotNode
(TracePlotter &)
const
;
355
};
356
357
/// a trace graph node that represents a @b single splice-out operation
358
class
SpliceOutNode
:
public
Node
{
359
private
:
360
const
bool
len_
;
361
362
public
:
363
/**
364
* @param ref a trace leading to this splice-out operation
365
* @param len count of successfully spliced-out segments
366
*/
367
SpliceOutNode
(
Node
*ref,
const
int
len = 1):
368
Node
(ref),
369
len_
(len)
370
{
371
this->
idMapper
().
setNotFoundAction
(
TIdMapper::NFA_RETURN_IDENTITY
);
372
}
373
374
protected
:
375
void
virtual
plotNode
(TracePlotter &)
const
;
376
};
377
378
/// a trace graph node that represents a @b single join operation
379
class
JoinNode
:
public
Node
{
380
public
:
381
/// takes references to both traces being joined by this operation
382
JoinNode
(
Node
*ref1,
Node
*ref2,
const
EJoinStatus
status):
383
Node
(ref1, ref2),
384
status_
(status)
385
{
386
idMapperList_
[0].setNotFoundAction(
TIdMapper::NFA_RETURN_NOTHING
);
387
idMapperList_
[1].setNotFoundAction(
TIdMapper::NFA_RETURN_NOTHING
);
388
}
389
390
virtual
Node
*
parent
()
const
;
391
392
virtual
Node
*
printNode
()
const
;
393
394
protected
:
395
void
virtual
plotNode
(TracePlotter &)
const
;
396
397
private
:
398
const
EJoinStatus
status_
;
399
};
400
401
/// trace graph nodes inserted automatically per each SymHeap clone operation
402
class
CloneNode
:
public
Node
{
403
public
:
404
CloneNode
(
Node
*ref):
405
Node
(ref)
406
{
407
}
408
409
virtual
Node
*
printNode
()
const
;
410
411
protected
:
412
void
virtual
plotNode
(TracePlotter &)
const
;
413
};
414
415
/// trace graph node representing a call entry point
416
class
CallEntryNode
:
public
Node
{
417
private
:
418
const
TInsn
insn_
;
419
420
public
:
421
/**
422
* @param ref trace representing the call entry as seen by the @b caller
423
* @param insn a CodeStorage::Insn object representing the call
424
*/
425
CallEntryNode
(
Node
*ref,
const
TInsn
insn):
426
Node
(ref),
427
insn_
(insn)
428
{
429
}
430
431
virtual
Node
*
printNode
()
const
;
432
433
protected
:
434
void
virtual
plotNode
(TracePlotter &)
const
;
435
};
436
437
/// trace graph node representing a cached call result
438
class
CallCacheHitNode
:
public
Node
{
439
private
:
440
const
TFnc
fnc_
;
441
442
public
:
443
/**
444
* @param entry trace representing the call cache entry
445
* @param result trace representing a cached call result (without frame)
446
* @param fnc a CodeStorage::Fnc fld representing the called function
447
*/
448
CallCacheHitNode
(
Node
*entry,
Node
*result,
const
TFnc
fnc):
449
Node
(entry, result),
450
fnc_
(fnc)
451
{
452
}
453
454
virtual
Node
*
printNode
()
const
;
455
456
protected
:
457
void
virtual
plotNode
(TracePlotter &)
const
;
458
};
459
460
/// trace graph node representing a call frame
461
class
CallFrameNode
:
public
Node
{
462
private
:
463
const
TInsn
insn_
;
464
465
public
:
466
/**
467
* @param ref trace representing the call entry as seen by the @b caller
468
* @param insn a CodeStorage::Insn object representing the call
469
*/
470
CallFrameNode
(
Node
*ref,
const
TInsn
insn):
471
Node
(ref),
472
insn_
(insn)
473
{
474
}
475
476
virtual
Node
*
printNode
()
const
;
477
478
protected
:
479
void
virtual
plotNode
(TracePlotter &)
const
;
480
};
481
482
/// trace graph node representing a call result
483
class
CallDoneNode
:
public
Node
{
484
private
:
485
const
TFnc
fnc_
;
486
487
public
:
488
/**
489
* @param result trace representing the result as seen by the @b callee
490
* @param fnc a CodeStorage::Fnc fld representing the called function
491
*/
492
CallDoneNode
(
Node
*result,
const
TFnc
fnc):
493
Node
(result),
494
fnc_
(fnc)
495
{
496
}
497
498
/**
499
* @param result trace representing the result as seen by the @b callee
500
* @param callFrame trace representing the call frame of the call
501
* @param fnc a CodeStorage::Fnc fld representing the called function
502
*/
503
CallDoneNode
(
Node
*result,
Node
*callFrame,
const
TFnc
fnc):
504
Node
(result, callFrame),
505
fnc_
(fnc)
506
{
507
}
508
509
virtual
Node
*
printNode
()
const
;
510
511
protected
:
512
void
virtual
plotNode
(TracePlotter &)
const
;
513
};
514
515
/// a trace graph node that represents a @b single call of importGlVar()
516
class
ImportGlVarNode
:
public
Node
{
517
private
:
518
const
std::string
varString_
;
519
520
public
:
521
/**
522
* @param ref a trace leading to this concretization step
523
* @param varString describing the global variable being imported
524
*/
525
ImportGlVarNode
(
Node
*ref,
const
std::string &varString):
526
Node
(ref),
527
varString_
(varString)
528
{
529
}
530
531
protected
:
532
void
virtual
plotNode
(TracePlotter &)
const
;
533
};
534
535
/// trace graph node representing an error/warning message
536
class
MsgNode
:
public
Node
{
537
private
:
538
const
EMsgLevel
level_
;
539
const
TLoc
loc_
;
540
541
public
:
542
/**
543
* @param ref a trace leading to this error/warning message
544
* @param level classification of the message (error, warning, ...)
545
* @param loc a location info the message was emitted with
546
*/
547
MsgNode
(
Node
*ref,
const
EMsgLevel
level,
const
TLoc
loc):
548
Node
(ref),
549
level_
(level),
550
loc_
(loc)
551
{
552
this->
idMapper
().
setNotFoundAction
(
TIdMapper::NFA_RETURN_IDENTITY
);
553
}
554
555
protected
:
556
void
virtual
plotNode
(TracePlotter &)
const
;
557
};
558
559
/// trace graph node representing something important for the user
560
class
UserNode
:
public
Node
{
561
private
:
562
const
TInsn
insn_
;
563
const
std::string
label_
;
564
565
public
:
566
/**
567
* @param ref a trace leading to this use node
568
* @param insn a CodeStorage::Insn object that caused the node to appear
569
* @param label a label describing what this node actually means
570
*/
571
UserNode
(
Node
*ref,
const
TInsn
insn,
const
char
*label):
572
Node
(ref),
573
insn_
(insn),
574
label_
(label)
575
{
576
this->
idMapper
().
setNotFoundAction
(
TIdMapper::NFA_RETURN_IDENTITY
);
577
}
578
579
virtual
Node
*
printNode
()
const
;
580
581
protected
:
582
void
virtual
plotNode
(TracePlotter &)
const
;
583
};
584
585
/// resolve composite ID mapping from trSrc to trDst
586
void
resolveIdMapping
(
TIdMapper
*pDst,
const
Node *trSrc,
const
Node *trDst);
587
588
/// plot a trace graph named "name-NNNN.dot" leading to the given node
589
bool
plotTrace
(Node *endPoint,
const
std::string &name, std::string *pName = 0);
590
591
/// print a human-readable trace using the Code Listener messaging API
592
void
printTrace
(Node *endPoint);
593
594
/// this runs in the debug build only
595
bool
chkTraceGraphConsistency
(Node *
const
from);
596
597
/// a container maintaining a set of trace graph end-points
598
class
EndPointConsolidator
{
599
public
:
600
EndPointConsolidator
();
601
~EndPointConsolidator
();
602
603
/// insert a new trace graph end-point
604
bool
/* any change */
insert
(
Node
*);
605
606
/// plot a common graph leading to all end-points inside the container
607
bool
plotAll
(
const
std::string &name);
608
609
private
:
610
// copying NOT allowed
611
EndPointConsolidator
(
const
EndPointConsolidator
&);
612
EndPointConsolidator
&
operator=
(
const
EndPointConsolidator
&);
613
614
private
:
615
struct
Private;
616
Private *
d
;
617
};
618
619
/// a container maintaining a set of trace graphs being built on the fly
620
class
GraphProxy
{
621
public
:
622
GraphProxy
();
623
~GraphProxy
();
624
625
/// insert a new trace graph end-point into the specified trace graph
626
bool
/* any change */
insert
(
Node
*,
const
std::string &graphName);
627
628
/// plot the specified graph
629
bool
plotGraph
(
const
std::string &name);
630
631
/// plot all graphs being maintained by this proxy
632
bool
plotAll
();
633
634
private
:
635
// copying NOT allowed
636
GraphProxy
(
const
GraphProxy
&);
637
GraphProxy
&
operator=
(
const
GraphProxy
&);
638
639
private
:
640
struct
Private;
641
Private *
d
;
642
};
643
644
/// a singleton holding global GraphProxy (may be extended later)
645
class
Globals
{
646
private
:
647
GraphProxy
glProxy_
;
648
static
Globals
*
inst_
;
649
650
public
:
651
static
bool
alive
() {
652
return
!!
inst_
;
653
}
654
655
static
Globals
*
instance
() {
656
return
(
alive
())
657
? (
inst_
)
658
: (
inst_
=
new
Globals
);
659
}
660
661
GraphProxy
*
glProxy
() {
662
return
&
glProxy_
;
663
}
664
665
static
void
cleanup
() {
666
delete
inst_
;
667
inst_
= 0;
668
}
669
};
670
671
/// mark the just completed @b clone operation as @b intended and unimportant
672
void
waiveCloneOperation
(
SymHeap
&sh);
673
674
/// mark the just completed @b clone operation as @b intended and unimportant
675
void
waiveCloneOperation
(
SymState
&);
676
677
}
// namespace Trace
678
679
#endif
/* H_GUARD_SYM_TRACE_H */
Generated on Mon Nov 9 2015 14:51:59 for Predator by
1.8.1.2