Predator
[unstable] git snapshot
Main Page
Related Pages
Namespaces
Data Structures
Files
File List
Globals
symseg.hh
Go to the documentation of this file.
1
/*
2
* Copyright (C) 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_SYMSEG_H
21
#define H_GUARD_SYMSEG_H
22
23
/**
24
* @file symseg.hh
25
* some generic utilities operating on list segments (SLS, DLS, Linux lists)
26
*/
27
28
#include "
config.h
"
29
#include "
symheap.hh
"
30
#include "
symutil.hh
"
31
32
/**
33
* return true if there is a list segment among the given pair of values
34
* @param sh an instance of symbolic heap
35
* @param atAddr address of the heap object for consideration
36
* @param pointingTo target address of the given potential list segment
37
* @param kind kind of list segment to look for
38
*/
39
bool
haveSeg
(
40
const
SymHeap
&sh,
41
const
TValId
atAddr,
42
const
TValId
pointingTo,
43
const
EObjKind
kind);
44
45
/**
46
* return true if there is a DLS (Doubly-linked List Segment) among the given
47
* pair of values
48
* @param sh an instance of symbolic heap
49
* @param atAddr address of the heap object for consideration
50
* @param peerAddr potential address of DLS peer object
51
*/
52
bool
haveDlSegAt
(
const
SymHeap
&sh,
TValId
atAddr,
TValId
peerAddr);
53
54
/// return 'next' pointer in the given segment
55
inline
PtrHandle
nextPtrFromSeg
(
const
SymHeap
&sh,
TObjId
seg)
56
{
57
CL_BREAK_IF
(
OK_REGION
== sh.
objKind
(seg));
58
59
const
BindingOff
&off = sh.
segBinding
(seg);
60
return
PtrHandle
(const_cast<SymHeap &>(sh), seg, off.next);
61
}
62
63
/// return 'prev' pointer in the given segment
64
inline
PtrHandle
prevPtrFromSeg
(
const
SymHeap
&sh,
TObjId
seg)
65
{
66
CL_BREAK_IF
(
OK_REGION
== sh.
objKind
(seg));
67
68
const
BindingOff
&off = sh.
segBinding
(seg);
69
return
PtrHandle
(const_cast<SymHeap &>(sh), seg, off.prev);
70
}
71
72
/// return the value of 'next' in the given segment
73
inline
TValId
nextValFromSeg
(
const
SymHeap
&sh,
TObjId
seg)
74
{
75
if
(
OK_OBJ_OR_NULL
== sh.
objKind
(seg))
76
return
VAL_NULL
;
77
78
const
FldHandle
ptrNext =
nextPtrFromSeg
(sh, seg);
79
return
ptrNext.
value
();
80
}
81
82
TValId
nextValFromSegAddr
(
const
SymHeap
&sh,
const
TValId
addr);
83
84
TValId
prevValFromSegAddr
(
const
SymHeap
&sh,
const
TValId
addr);
85
86
inline
TOffset
headOffset
(
const
SymHeap
&sh,
const
TObjId
seg)
87
{
88
const
EObjKind
kind = sh.
objKind
(seg);
89
CL_BREAK_IF
(
OK_REGION
== kind);
90
91
return
(
OK_OBJ_OR_NULL
== kind)
92
? 0
93
: sh.
segBinding
(seg).
head
;
94
}
95
96
/// return address of segment's head (useful mainly for Linux lists)
97
inline
TValId
segHeadAt
(
SymHeap
&sh,
TObjId
seg,
ETargetSpecifier
ts)
98
{
99
CL_BREAK_IF
(
OK_REGION
== sh.
objKind
(seg));
100
101
const
BindingOff
&off = sh.
segBinding
(seg);
102
103
SymHeap
&shWritable =
const_cast<
SymHeap
&
>
(sh);
104
return
shWritable.
addrOfTarget
(seg, ts, off.head);
105
}
106
107
/// we require obj to be an abstract object
108
inline
TObjId
segNextObj
(
SymHeap
&sh,
TObjId
obj)
109
{
110
const
EObjKind
kind = sh.
objKind
(obj);
111
if
(
OK_OBJ_OR_NULL
== kind)
112
return
OBJ_NULL
;
113
114
const
BindingOff
off = sh.
segBinding
(obj);
115
const
TOffset
offNext = (
OK_DLS
== kind)
116
? off.
prev
117
: off.
next
;
118
119
return
nextObj
(sh, obj, offNext);
120
}
121
122
inline
TMinLen
objMinLength
(
const
SymHeap
&sh,
TObjId
obj)
123
{
124
if
(!sh.
isValid
(obj))
125
return
0;
126
127
const
EObjKind
kind = sh.
objKind
(obj);
128
if
(
OK_REGION
== kind)
129
return
1;
130
131
return
sh.
segMinLength
(obj);
132
}
133
134
/// return true if the given pair of values is proven to be non-equal
135
bool
segProveNeq
(
const
SymHeap
&sh,
TValId
v1,
TValId
v2);
136
137
/// if the current segment min length is lower than the given one, update it!
138
inline
void
segIncreaseMinLength
(
SymHeap
&sh,
const
TObjId
seg,
TMinLen
len)
139
{
140
CL_BREAK_IF
(!len);
141
142
if
(sh.
segMinLength
(seg) < len)
143
sh.
segSetMinLength
(seg, len);
144
}
145
146
/// we know (v1 != v2), update related segments in the given heap accordingly!
147
bool
segApplyNeq
(
SymHeap
&sh,
TValId
v1,
TValId
v2);
148
149
inline
bool
isObjWithBinding
(
const
EObjKind
kind)
150
{
151
switch
(kind) {
152
case
OK_REGION
:
153
case
OK_OBJ_OR_NULL
:
154
return
false
;
155
156
case
OK_SLS
:
157
case
OK_DLS
:
158
case
OK_SEE_THROUGH
:
159
case
OK_SEE_THROUGH_2N
:
160
break
;
161
}
162
163
return
true
;
164
}
165
166
inline
void
buildIgnoreList
(
167
TFldSet
&ignoreList,
168
const
SymHeap
&sh,
169
const
TObjId
obj)
170
{
171
SymHeap
&writable =
const_cast<
SymHeap
&
>
(sh);
172
TOffset
off;
173
FldHandle
tmp;
174
175
const
EObjKind
kind = sh.
objKind
(obj);
176
switch
(kind) {
177
case
OK_REGION
:
178
case
OK_OBJ_OR_NULL
:
179
return
;
180
181
case
OK_DLS
:
182
case
OK_SEE_THROUGH_2N
:
183
// preserve 'peer' field
184
off = sh.
segBinding
(obj).
prev
;
185
tmp =
PtrHandle
(writable, obj, off);
186
ignoreList.insert(tmp);
187
// fall through!
188
189
case
OK_SLS
:
190
case
OK_SEE_THROUGH
:
191
// preserve 'next' field
192
off = sh.
segBinding
(obj).
next
;
193
tmp =
PtrHandle
(writable, obj, off);
194
ignoreList.insert(tmp);
195
}
196
}
197
198
inline
void
buildIgnoreList
(
199
TFldSet
&ignoreList,
200
SymHeap
&sh,
201
const
TObjId
obj,
202
const
BindingOff
&bf)
203
{
204
const
PtrHandle
next(sh, obj, bf.
next
);
205
if
(next.
isValidHandle
())
206
ignoreList.insert(next);
207
208
const
PtrHandle
prev(sh, obj, bf.
prev
);
209
if
(prev.
isValidHandle
())
210
ignoreList.insert(prev);
211
}
212
213
/// look through possibly empty objects and return the value seen
214
TValId
lookThrough
(
const
SymHeap
&sh,
TValId
val,
TValSet
*pSeen = 0);
215
216
/// true if all segments have populated next/prev pointers
217
bool
segCheckConsistency
(
const
SymHeap
&sh);
218
219
#endif
/* H_GUARD_SYMSEG_H */
Generated on Sun Feb 10 2013 17:38:16 for Predator by
1.8.3.1