@@ -2,8 +2,12 @@ use core::fmt::Debug;
2
2
3
3
use libafl_bolts:: { Error , hash_64_fast} ;
4
4
use libipt:: {
5
- block:: BlockDecoder , enc_dec_builder:: EncoderDecoderBuilder , error:: PtErrorCode ,
6
- event:: EventType , image:: Image , status:: Status ,
5
+ block:: BlockDecoder ,
6
+ enc_dec_builder:: EncoderDecoderBuilder ,
7
+ error:: { PtError , PtErrorCode } ,
8
+ event:: EventType ,
9
+ image:: Image ,
10
+ status:: Status ,
7
11
} ;
8
12
use num_traits:: SaturatingAdd ;
9
13
@@ -81,21 +85,46 @@ where
81
85
}
82
86
83
87
fn decode_and_resync_loop ( & mut self ) -> Result < ( ) , Error > {
88
+ const MAX_RESYNC_TRIALS : usize = 32 ;
89
+ let mut last_error_offset = 0 ;
90
+ let mut last_error_count = 0 ;
91
+
84
92
loop {
85
93
match self . decode_blocks_loop ( ) {
86
- Ok ( ( ) ) if self . status . eos ( ) => return Ok ( ( ) ) ,
87
- Ok ( ( ) ) | Err ( _) => ( ) ,
94
+ Ok ( ( ) ) => {
95
+ debug_assert ! (
96
+ self . status. eos( ) ,
97
+ "PT decoder decode_blocks_loop should return Ok only at the end of stream"
98
+ ) ;
99
+ return Ok ( ( ) ) ;
100
+ }
101
+ Err ( e) if e. code ( ) == PtErrorCode :: Eos => return Ok ( ( ) ) ,
102
+ Err ( _) => ( ) ,
103
+ }
104
+
105
+ let offset = self . decoder . offset ( ) . map_err ( error_from_pt_error) ?;
106
+ if offset == last_error_offset {
107
+ last_error_count += 1 ;
108
+ if last_error_count > MAX_RESYNC_TRIALS {
109
+ return Err ( Error :: illegal_state ( format ! (
110
+ "PT Decoder got stuck at trace offset {offset:x}.\
111
+ Make sure the decoder Image has the right content and offsets.\
112
+ Trying to continue decoding.",
113
+ ) ) ) ;
114
+ }
115
+ } else {
116
+ last_error_offset = offset;
88
117
}
89
118
90
119
match self . resync_loop ( ) {
91
120
Ok ( ( ) ) if self . status . eos ( ) => return Ok ( ( ) ) ,
92
121
Ok ( ( ) ) => ( ) ,
93
- Err ( e) => return Err ( e ) ,
122
+ Err ( e) => return Err ( error_from_pt_error ( e ) ) ,
94
123
}
95
124
}
96
125
}
97
126
98
- fn resync_loop ( & mut self ) -> Result < ( ) , Error >
127
+ fn resync_loop ( & mut self ) -> Result < ( ) , PtError >
99
128
where
100
129
T : SaturatingAdd + From < u8 > + Debug ,
101
130
{
@@ -108,41 +137,22 @@ where
108
137
Err ( e) => match e. code ( ) {
109
138
PtErrorCode :: Eos => return Ok ( ( ) ) ,
110
139
PtErrorCode :: EventIgnored => self . handle_event ( ) ?,
111
- _ => return Err ( Error :: illegal_state ( format ! ( "PT error in resync {e:?}" ) ) ) ,
140
+ _ => return Err ( e ) ,
112
141
} ,
113
142
}
114
143
}
115
144
}
116
145
117
- fn decode_blocks_loop ( & mut self ) -> Result < ( ) , Error >
146
+ fn decode_blocks_loop ( & mut self ) -> Result < ( ) , PtError >
118
147
where
119
148
T : SaturatingAdd + From < u8 > + Debug ,
120
149
{
121
- #[ cfg( debug_assertions) ]
122
- let mut trace_entry_iters: ( u64 , u64 ) = ( 0 , 0 ) ;
123
-
124
150
loop {
125
- #[ cfg( debug_assertions) ]
126
- {
127
- let offset = self . decoder . offset ( ) . map_err ( error_from_pt_error) ?;
128
- if trace_entry_iters. 0 == offset {
129
- trace_entry_iters. 1 += 1 ;
130
- if trace_entry_iters. 1 > 1000 {
131
- return Err ( Error :: illegal_state ( format ! (
132
- "PT Decoder got stuck at trace offset {offset:x}.\
133
- Make sure the decoder Image has the right content and offsets.",
134
- ) ) ) ;
135
- }
136
- } else {
137
- trace_entry_iters = ( offset, 0 ) ;
138
- }
139
- }
140
-
141
151
while self . status . event_pending ( ) {
142
152
self . handle_event ( ) ?;
143
153
}
144
154
145
- let offset = self . decoder . offset ( ) . map_err ( error_from_pt_error ) ?;
155
+ let offset = self . decoder . offset ( ) ?;
146
156
if self . should_ignore_vmx_root ( ) || offset <= self . trace_skip {
147
157
self . ignore_block ( ) ?;
148
158
} else {
@@ -155,7 +165,7 @@ where
155
165
}
156
166
}
157
167
158
- fn decode_block ( & mut self ) -> Result < ( ) , Error > {
168
+ fn decode_block ( & mut self ) -> Result < ( ) , PtError > {
159
169
match self . decoder . decode_next ( ) {
160
170
Ok ( ( b, s) ) => {
161
171
self . status = s;
@@ -172,37 +182,37 @@ where
172
182
}
173
183
Err ( e) => {
174
184
if e. code ( ) != PtErrorCode :: Eos {
175
- let offset = self . decoder . offset ( ) . map_err ( error_from_pt_error ) ?;
185
+ let offset = self . decoder . offset ( ) ?;
176
186
log:: info!(
177
187
"PT error in block next {e:?} trace offset {offset:x} last decoded block end {:x}" ,
178
188
self . previous_block_end_ip
179
189
) ;
180
190
}
181
- Err ( error_from_pt_error ( e ) )
191
+ Err ( e )
182
192
}
183
193
}
184
194
}
185
195
186
- fn ignore_block ( & mut self ) -> Result < ( ) , Error > {
196
+ fn ignore_block ( & mut self ) -> Result < ( ) , PtError > {
187
197
match self . decoder . decode_next ( ) {
188
198
Ok ( ( _, s) ) => {
189
199
self . status = s;
190
200
Ok ( ( ) )
191
201
}
192
202
Err ( e) => {
193
203
if e. code ( ) != PtErrorCode :: Eos {
194
- let offset = self . decoder . offset ( ) . map_err ( error_from_pt_error ) ?;
204
+ let offset = self . decoder . offset ( ) ?;
195
205
log:: trace!(
196
206
"PT error in ignore block {e:?} trace offset {offset:x} last decoded block end {:x}" ,
197
207
self . previous_block_end_ip
198
208
) ;
199
209
}
200
- Err ( error_from_pt_error ( e ) )
210
+ Err ( e )
201
211
}
202
212
}
203
213
}
204
214
205
- fn handle_event ( & mut self ) -> Result < ( ) , Error > {
215
+ fn handle_event ( & mut self ) -> Result < ( ) , PtError > {
206
216
match self . decoder . event ( ) {
207
217
Ok ( ( event, s) ) => {
208
218
self . status = s;
@@ -213,7 +223,7 @@ where
213
223
}
214
224
Ok ( ( ) )
215
225
}
216
- Err ( e) => Err ( Error :: illegal_state ( format ! ( "PT error in event {e:?}" ) ) ) ,
226
+ Err ( e) => Err ( e ) ,
217
227
}
218
228
}
219
229
0 commit comments