@@ -53,6 +53,7 @@ pub(super) struct MapsEntry {
53
53
pathname : OsString ,
54
54
}
55
55
56
+ #[ cfg( not( target_os = "nto" ) ) ]
56
57
pub ( super ) fn parse_maps ( ) -> Result < Vec < MapsEntry > , & ' static str > {
57
58
let mut v = Vec :: new ( ) ;
58
59
let mut proc_self_maps =
@@ -68,6 +69,26 @@ pub(super) fn parse_maps() -> Result<Vec<MapsEntry>, &'static str> {
68
69
Ok ( v)
69
70
}
70
71
72
+ // TODO: This could be merged with the above block but seems to require
73
+ // creating a couple of extra strings to pass to map_err(). Is
74
+ // there a way to pass it paramenters without adding a bunch of
75
+ // lines of code?
76
+ #[ cfg( target_os = "nto" ) ]
77
+ pub ( super ) fn parse_maps ( ) -> Result < Vec < MapsEntry > , & ' static str > {
78
+ let mut v = Vec :: new ( ) ;
79
+ let mut proc_self_maps =
80
+ File :: open ( "/proc/self/pmap" ) . map_err ( |_| "Couldn't open /proc/self/pmap" ) ?;
81
+ let mut buf = String :: new ( ) ;
82
+ let _bytes_read = proc_self_maps
83
+ . read_to_string ( & mut buf)
84
+ . map_err ( |_| "Couldn't read /proc/self/pmap" ) ?;
85
+ for line in buf. lines ( ) {
86
+ v. push ( line. parse ( ) ?) ;
87
+ }
88
+
89
+ Ok ( v)
90
+ }
91
+
71
92
impl MapsEntry {
72
93
pub ( super ) fn pathname ( & self ) -> & OsString {
73
94
& self . pathname
@@ -78,6 +99,7 @@ impl MapsEntry {
78
99
}
79
100
}
80
101
102
+ #[ cfg( not( target_os = "nto" ) ) ]
81
103
impl FromStr for MapsEntry {
82
104
type Err = & ' static str ;
83
105
@@ -141,9 +163,64 @@ impl FromStr for MapsEntry {
141
163
}
142
164
}
143
165
166
+ #[ cfg( target_os = "nto" ) ]
167
+ impl FromStr for MapsEntry {
168
+ type Err = & ' static str ;
169
+
170
+ // Format: vaddr,size,flags,prot,maxprot,dev,ino,offset,rsv,guardsize,refcnt,mapcnt,path
171
+ // e.g.: "0x00000022fa36b000,0x0000000000002000,0x00000071,0x05,0x0f,0x0000040b,0x00000000000000dd,
172
+ // 0x0000000000000000,0x0000000000000000,0x00000000,0x00000005,0x00000003,/proc/boot/cat"
173
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
174
+ let mut parts = s. split ( ',' ) ;
175
+ let vaddr_str = parts. next ( ) . ok_or ( "Couldn't find virtual address" ) ?;
176
+ let size_str = parts. next ( ) . ok_or ( "Couldn't find size" ) ?;
177
+ let _flags_str = parts. next ( ) . ok_or ( "Couldn't find flags" ) ?;
178
+ let prot_str = parts. next ( ) . ok_or ( "Couldn't find protection" ) ?;
179
+ let _maxprot_str = parts. next ( ) . ok_or ( "Couldn't find maximum protection" ) ?;
180
+ let dev_str = parts. next ( ) . ok_or ( "Couldn't find device" ) ?;
181
+ let ino_str = parts. next ( ) . ok_or ( "Couldn't find inode" ) ?;
182
+ let offset_str = parts. next ( ) . ok_or ( "Couldn't find offset" ) ?;
183
+ let _rsv_str = parts. next ( ) . ok_or ( "Couldn't find reserved pages" ) ?;
184
+ let _guardsize_str = parts. next ( ) . ok_or ( "Couldn't find guard size" ) ?;
185
+ let _refcnt_str = parts. next ( ) . ok_or ( "Couldn't find reference count" ) ?;
186
+ let _mapcnt_str = parts. next ( ) . ok_or ( "Couldn't find mapped count" ) ?;
187
+ let pathname_str = parts. next ( ) . unwrap_or ( "" ) ; // pathname may be omitted.
188
+
189
+ let hex = |s : & str | usize:: from_str_radix ( & s[ 2 ..] , 16 ) . map_err ( |_| "Couldn't parse hex number" ) ;
190
+ let address = { ( hex ( vaddr_str) ?, hex ( vaddr_str) ? + hex ( size_str) ?) } ;
191
+
192
+ // TODO: Probably a rust'ier way of doing this
193
+ let mut perms: [ char ; 4 ] = [ '-' , '-' , '-' , '-' ] ;
194
+ let perm_str: [ char ; 3 ] = [ 'r' , 'w' , 'x' ] ;
195
+ let perm_bits: [ usize ; 3 ] = [ 0x1 , 0x2 , 0x4 ] ;
196
+
197
+ for ( pos, val) in perm_bits. iter ( ) . enumerate ( ) {
198
+ let prot = hex ( prot_str) ?;
199
+ if val & prot != 0 {
200
+ perms[ pos] = perm_str[ pos]
201
+ }
202
+ }
203
+
204
+ let offset = hex ( offset_str) ?;
205
+ let dev = { ( hex ( dev_str) ?, 0x00000000 ) } ;
206
+ let inode = hex ( ino_str) ?;
207
+ let pathname = pathname_str. into ( ) ;
208
+
209
+ Ok ( MapsEntry {
210
+ address,
211
+ perms,
212
+ offset,
213
+ dev,
214
+ inode,
215
+ pathname,
216
+ } )
217
+ }
218
+ }
219
+
144
220
// Make sure we can parse 64-bit sample output if we're on a 64-bit target.
145
221
#[ cfg( target_pointer_width = "64" ) ]
146
222
#[ test]
223
+ #[ cfg( not( target_os = "nto" ) ) ]
147
224
fn check_maps_entry_parsing_64bit ( ) {
148
225
assert_eq ! (
149
226
"ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 \
@@ -189,7 +266,55 @@ fn check_maps_entry_parsing_64bit() {
189
266
) ;
190
267
}
191
268
269
+ #[ cfg( target_os = "nto" ) ]
270
+ fn check_maps_entry_parsing_64bit ( ) {
271
+ assert_eq ! (
272
+ "0xffffffffff600000,0x0000000000001000,0x00000071,0x04,0x0f,0x00000000,0x0000000000000000,\
273
+ 0x0000000000000000,0x0000000000000000,0x00000000,0x00000005,0x00000003,/proc/boot/foo"
274
+ . parse:: <MapsEntry >( )
275
+ . unwrap( ) ,
276
+ MapsEntry {
277
+ address: ( 0xffffffffff600000 , 0xffffffffff601000 ) ,
278
+ perms: [ '-' , '-' , 'x' , '-' ] ,
279
+ offset: 0x00000000 ,
280
+ dev: ( 0x00 , 0x00 ) ,
281
+ inode: 0x0 ,
282
+ pathname: "/proc/boot/foo" . into( ) ,
283
+ }
284
+ ) ;
285
+
286
+ assert_eq ! (
287
+ "0x00007f5985f46000,0x0000000000002000,0x00000071,0x03,0x0f,0x00000103,0x0000000076021795,\
288
+ 0x0000000000039000,0x0000000000000000,0x00000000,0x00000005,0x00000003,/usr/lib/ldqnx-64.so.2"
289
+ . parse:: <MapsEntry >( )
290
+ . unwrap( ) ,
291
+ MapsEntry {
292
+ address: ( 0x7f5985f46000 , 0x7f5985f48000 ) ,
293
+ perms: [ 'r' , 'w' , '-' , '-' ] ,
294
+ offset: 0x00039000 ,
295
+ dev: ( 0x103 , 0x0 ) ,
296
+ inode: 0x76021795 ,
297
+ pathname: "/usr/lib/ldqnx-64.so.2" . into( ) ,
298
+ }
299
+ ) ;
300
+ assert_eq ! (
301
+ "0x00000035b1a21000,0x0000000000001000,0x00000071,0x03,0x0f,0x00000000,0x0000000000000000,\
302
+ 0x0000000000000000,0x0000000000000000,0x00000000,0x00000005,0x00000003,"
303
+ . parse:: <MapsEntry >( )
304
+ . unwrap( ) ,
305
+ MapsEntry {
306
+ address: ( 0x35b1a21000 , 0x35b1a22000 ) ,
307
+ perms: [ 'r' , 'w' , '-' , '-' ] ,
308
+ offset: 0x00000000 ,
309
+ dev: ( 0x00 , 0x00 ) ,
310
+ inode: 0x0 ,
311
+ pathname: Default :: default ( ) ,
312
+ }
313
+ ) ;
314
+ }
315
+
192
316
// (This output was taken from a 32-bit machine, but will work on any target)
317
+ #[ cfg( not( target_os = "nto" ) ) ]
193
318
#[ test]
194
319
fn check_maps_entry_parsing_32bit ( ) {
195
320
/* Example snippet of output:
0 commit comments