@@ -53,6 +53,7 @@ pub(super) struct MapsEntry {
5353 pathname : OsString ,
5454}
5555
56+ #[ cfg( not( target_os = "nto" ) ) ]
5657pub ( super ) fn parse_maps ( ) -> Result < Vec < MapsEntry > , & ' static str > {
5758 let mut v = Vec :: new ( ) ;
5859 let mut proc_self_maps =
@@ -68,6 +69,26 @@ pub(super) fn parse_maps() -> Result<Vec<MapsEntry>, &'static str> {
6869 Ok ( v)
6970}
7071
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+
7192impl MapsEntry {
7293 pub ( super ) fn pathname ( & self ) -> & OsString {
7394 & self . pathname
@@ -78,6 +99,7 @@ impl MapsEntry {
7899 }
79100}
80101
102+ #[ cfg( not( target_os = "nto" ) ) ]
81103impl FromStr for MapsEntry {
82104 type Err = & ' static str ;
83105
@@ -141,9 +163,64 @@ impl FromStr for MapsEntry {
141163 }
142164}
143165
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+
144220// Make sure we can parse 64-bit sample output if we're on a 64-bit target.
145221#[ cfg( target_pointer_width = "64" ) ]
146222#[ test]
223+ #[ cfg( not( target_os = "nto" ) ) ]
147224fn check_maps_entry_parsing_64bit ( ) {
148225 assert_eq ! (
149226 "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 \
@@ -189,7 +266,55 @@ fn check_maps_entry_parsing_64bit() {
189266 ) ;
190267}
191268
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+
192316// (This output was taken from a 32-bit machine, but will work on any target)
317+ #[ cfg( not( target_os = "nto" ) ) ]
193318#[ test]
194319fn check_maps_entry_parsing_32bit ( ) {
195320 /* Example snippet of output:
0 commit comments