@@ -36,23 +36,54 @@ use libipt_sys::{
36
36
pt_insn_time
37
37
} ;
38
38
39
- pub struct InsnDecoder < T > ( pt_insn_decoder , PhantomData < T > ) ;
40
- impl < T > InsnDecoder < T > {
39
+ #[ cfg( test) ]
40
+ mod test {
41
+ use super :: * ;
42
+
43
+ #[ test]
44
+ fn test_blkdec_alloc ( ) {
45
+ InsnDecoder :: new ( & Config :: < ( ) > :: new ( & mut [ 0 ; 0 ] ) ) . unwrap ( ) ;
46
+ }
47
+
48
+ #[ test ]
49
+ fn test_blkdec_props ( ) {
50
+ // this just checks memory safety for property access
51
+ // usage can be found in the integration tests
52
+ let mut b = InsnDecoder :: new ( & Config :: < ( ) > :: new ( & mut [ 0 ; 0 ] ) ) . unwrap ( ) ;
53
+ let a = b. asid ( ) . unwrap ( ) ;
54
+ assert ! ( a. cr3( ) . is_none( ) ) ;
55
+ assert ! ( a. vmcs( ) . is_none( ) ) ;
56
+
57
+ assert ! ( b. core_bus_ratio( ) . is_err( ) ) ;
58
+ assert ! ( b. event( ) . is_err( ) ) ;
59
+ assert ! ( b. config( ) . is_ok( ) ) ;
60
+ assert ! ( b. image( ) . unwrap( ) . name( ) . is_none( ) ) ;
61
+ assert ! ( b. offset( ) . is_err( ) ) ;
62
+ assert ! ( b. sync_offset( ) . is_err( ) ) ;
63
+ assert ! ( b. next( ) . is_err( ) ) ;
64
+ assert ! ( b. sync_backward( ) . is_err( ) ) ;
65
+ assert ! ( b. sync_forward( ) . is_err( ) ) ;
66
+ assert ! ( b. time( ) . is_err( ) ) ;
67
+ }
68
+ }
69
+
70
+ pub struct InsnDecoder < ' a , T > ( & ' a mut pt_insn_decoder , PhantomData < T > ) ;
71
+ impl < ' a , T > InsnDecoder < ' a , T > {
41
72
/// Allocate an Intel PT instruction flow decoder.
42
73
///
43
74
/// The decoder will work on the buffer defined in @config,
44
75
/// it shall contain raw trace data and remain valid for the lifetime of the decoder.
45
76
/// The decoder needs to be synchronized before it can be used.
46
77
pub fn new ( cfg : & Config < T > ) -> Result < Self , PtError > {
47
- deref_ptresult ( unsafe { pt_insn_alloc_decoder ( cfg. 0 . as_ref ( ) ) } )
48
- . map ( |d| InsnDecoder :: < T > ( * d, PhantomData ) )
78
+ deref_ptresult_mut ( unsafe { pt_insn_alloc_decoder ( cfg. 0 . as_ref ( ) ) } )
79
+ . map ( |d| InsnDecoder :: < T > ( d, PhantomData ) )
49
80
}
50
81
51
82
/// Return the current address space identifier.
52
83
pub fn asid ( & self ) -> Result < Asid , PtError > {
53
84
let mut asid: pt_asid = unsafe { mem:: zeroed ( ) } ;
54
85
ensure_ptok ( unsafe {
55
- pt_insn_asid ( & self . 0 ,
86
+ pt_insn_asid ( self . 0 ,
56
87
& mut asid,
57
88
mem:: size_of :: < pt_asid > ( ) )
58
89
} ) . map ( |_| Asid ( asid) )
@@ -65,7 +96,7 @@ impl<T> InsnDecoder<T> {
65
96
/// Returns NoCbr if there has not been a CBR packet.
66
97
pub fn core_bus_ratio ( & mut self ) -> Result < u32 , PtError > {
67
98
let mut cbr: u32 = 0 ;
68
- ensure_ptok ( unsafe { pt_insn_core_bus_ratio ( & mut self . 0 , & mut cbr) } )
99
+ ensure_ptok ( unsafe { pt_insn_core_bus_ratio ( self . 0 , & mut cbr) } )
69
100
. map ( |_| cbr)
70
101
}
71
102
@@ -76,14 +107,14 @@ impl<T> InsnDecoder<T> {
76
107
pub fn event ( & mut self ) -> Result < ( Event , Status ) , PtError > {
77
108
let mut evt: pt_event = unsafe { mem:: zeroed ( ) } ;
78
109
extract_pterr ( unsafe {
79
- pt_insn_event ( & mut self . 0 ,
110
+ pt_insn_event ( self . 0 ,
80
111
& mut evt,
81
112
mem:: size_of :: < pt_event > ( ) )
82
113
} ) . map ( |s| ( Event ( evt) , Status :: from_bits ( s) . unwrap ( ) ) )
83
114
}
84
115
85
116
pub fn config ( & self ) -> Result < Config < T > , PtError > {
86
- deref_ptresult ( unsafe { pt_insn_get_config ( & self . 0 ) } )
117
+ deref_ptresult ( unsafe { pt_insn_get_config ( self . 0 ) } )
87
118
. map ( Config :: from)
88
119
}
89
120
@@ -92,7 +123,7 @@ impl<T> InsnDecoder<T> {
92
123
/// The returned image may be modified as long as no decoder that uses this image is running.
93
124
/// Returns the traced image the decoder uses for reading memory.
94
125
pub fn image ( & mut self ) -> Result < Image , PtError > {
95
- deref_ptresult_mut ( unsafe { pt_insn_get_image ( & mut self . 0 ) } )
126
+ deref_ptresult_mut ( unsafe { pt_insn_get_image ( self . 0 ) } )
96
127
. map ( Image :: from)
97
128
}
98
129
@@ -101,7 +132,7 @@ impl<T> InsnDecoder<T> {
101
132
/// Returns Nosync if decoder is out of sync.
102
133
pub fn offset ( & self ) -> Result < u64 , PtError > {
103
134
let mut off: u64 = 0 ;
104
- ensure_ptok ( unsafe { pt_insn_get_offset ( & self . 0 , & mut off) } )
135
+ ensure_ptok ( unsafe { pt_insn_get_offset ( self . 0 , & mut off) } )
105
136
. map ( |_| off)
106
137
}
107
138
@@ -110,7 +141,7 @@ impl<T> InsnDecoder<T> {
110
141
/// Returns Nosync if @decoder is out of sync.
111
142
pub fn sync_offset ( & self ) -> Result < u64 , PtError > {
112
143
let mut off = 0 ;
113
- ensure_ptok ( unsafe { pt_insn_get_sync_offset ( & self . 0 , & mut off) } )
144
+ ensure_ptok ( unsafe { pt_insn_get_sync_offset ( self . 0 , & mut off) } )
114
145
. map ( |_| off)
115
146
}
116
147
@@ -129,7 +160,7 @@ impl<T> InsnDecoder<T> {
129
160
pub fn next ( & mut self ) -> Result < ( Insn , Status ) , PtError > {
130
161
let mut insn: pt_insn = unsafe { mem:: zeroed ( ) } ;
131
162
extract_pterr ( unsafe {
132
- pt_insn_next ( & mut self . 0 ,
163
+ pt_insn_next ( self . 0 ,
133
164
& mut insn,
134
165
mem:: size_of :: < pt_insn > ( ) )
135
166
} ) . map ( |s| ( Insn ( insn) , Status :: from_bits ( s) . unwrap ( ) ) )
@@ -142,7 +173,7 @@ impl<T> InsnDecoder<T> {
142
173
/// Only one image can be active at any time.
143
174
pub fn set_image ( & mut self , img : Option < & mut Image > ) -> Result < ( ) , PtError > {
144
175
ensure_ptok ( unsafe {
145
- pt_insn_set_image ( & mut self . 0 ,
176
+ pt_insn_set_image ( self . 0 ,
146
177
match img {
147
178
None => ptr:: null_mut ( ) ,
148
179
Some ( i) => i. inner
@@ -151,7 +182,7 @@ impl<T> InsnDecoder<T> {
151
182
}
152
183
153
184
pub fn sync_backward ( & mut self ) -> Result < ( ) , PtError > {
154
- ensure_ptok ( unsafe { pt_insn_sync_backward ( & mut self . 0 ) } )
185
+ ensure_ptok ( unsafe { pt_insn_sync_backward ( self . 0 ) } )
155
186
}
156
187
157
188
/// Synchronize an Intel PT instruction flow decoder.
@@ -165,7 +196,7 @@ impl<T> InsnDecoder<T> {
165
196
/// Returns BadPacket if an unknown packet payload is encountered.
166
197
/// Returns Eos if no further synchronization point is found.
167
198
pub fn sync_forward ( & mut self ) -> Result < ( ) , PtError > {
168
- ensure_ptok ( unsafe { pt_insn_sync_forward ( & mut self . 0 ) } )
199
+ ensure_ptok ( unsafe { pt_insn_sync_forward ( self . 0 ) } )
169
200
}
170
201
171
202
/// Manually synchronize an Intel PT instruction flow decoder.
@@ -178,7 +209,7 @@ impl<T> InsnDecoder<T> {
178
209
/// Returns Eos if decoder reaches the end of its trace buffer.
179
210
/// Returns Nosync if there is no syncpoint at @offset.
180
211
pub fn sync_set ( & mut self , offset : u64 ) -> Result < ( ) , PtError > {
181
- ensure_ptok ( unsafe { pt_insn_sync_set ( & mut self . 0 , offset) } )
212
+ ensure_ptok ( unsafe { pt_insn_sync_set ( self . 0 , offset) } )
182
213
}
183
214
184
215
/// Return the current time.
@@ -200,7 +231,7 @@ impl<T> InsnDecoder<T> {
200
231
let mut lost_cyc: u32 = 0 ;
201
232
ensure_ptok (
202
233
unsafe {
203
- pt_insn_time ( & mut self . 0 ,
234
+ pt_insn_time ( self . 0 ,
204
235
& mut time,
205
236
& mut lost_mtc,
206
237
& mut lost_cyc)
@@ -209,6 +240,6 @@ impl<T> InsnDecoder<T> {
209
240
}
210
241
}
211
242
212
- impl < T > Drop for InsnDecoder < T > {
213
- fn drop ( & mut self ) { unsafe { pt_insn_free_decoder ( & mut self . 0 ) } }
243
+ impl < ' a , T > Drop for InsnDecoder < ' a , T > {
244
+ fn drop ( & mut self ) { unsafe { pt_insn_free_decoder ( self . 0 ) } }
214
245
}
0 commit comments