11use core:: fmt:: { self , Write } ;
2- use core:: mem:: { size_of, transmute} ;
32use core:: slice:: from_raw_parts;
43use libc:: c_char;
4+ use object:: NativeEndian as NE ;
55
66unsafe extern "C" {
77 // dl_iterate_phdr takes a callback that will receive a dl_phdr_info pointer
@@ -118,12 +118,7 @@ const NT_GNU_BUILD_ID: u32 = 3;
118118
119119// Elf_Nhdr represents an ELF note header in the endianness of the target.
120120#[ allow( non_camel_case_types) ]
121- #[ repr( C ) ]
122- struct Elf_Nhdr {
123- n_namesz : u32 ,
124- n_descsz : u32 ,
125- n_type : u32 ,
126- }
121+ type Elf_Nhdr = object:: elf:: NoteHeader32 < NE > ;
127122
128123// Note represents an ELF note (header + contents). The name is left as a u8
129124// slice because it is not always null terminated and rust makes it easy enough
@@ -176,19 +171,15 @@ fn take_bytes_align4<'a>(num: usize, bytes: &mut &'a [u8]) -> Option<&'a [u8]> {
176171 Some ( out)
177172}
178173
179- // This function has no real invariants the caller must uphold other than
180- // perhaps that 'bytes' should be aligned for performance (and on some
181- // architectures correctness). The values in the Elf_Nhdr fields might
182- // be nonsense but this function ensures no such thing .
174+ /// This function has no invariants the caller must uphold, but
175+ /// it will return `None`, without mutating, if `bytes` has insufficient size or alignment.
176+ /// If this returns `Some(nhdr)`, then `bytes` was and remains 4-byte-aligned.
177+ /// The values in the Elf_Nhdr fields might be nonsense .
183178fn take_nhdr < ' a > ( bytes : & mut & ' a [ u8 ] ) -> Option < & ' a Elf_Nhdr > {
184- if size_of :: < Elf_Nhdr > ( ) > bytes. len ( ) {
185- return None ;
186- }
187- // This is safe as long as there is enough space and we just confirmed that
188- // in the if statement above so this should not be unsafe.
189- let out = unsafe { transmute :: < * const u8 , & ' a Elf_Nhdr > ( bytes. as_ptr ( ) ) } ;
190- // Note that sice_of::<Elf_Nhdr>() is always 4-byte aligned.
191- * bytes = & bytes[ size_of :: < Elf_Nhdr > ( ) ..] ;
179+ let ( out, rest) = object:: pod:: from_bytes :: < Elf_Nhdr > ( bytes) . ok ( ) ?;
180+ // Note that size_of::<Elf_Nhdr>() is always a multiple of 4-bytes, so the
181+ // 4-byte alignment is maintained.
182+ * bytes = rest;
192183 Some ( out)
193184}
194185
@@ -204,12 +195,12 @@ impl<'a> Iterator for NoteIter<'a> {
204195 // decisions based on the type. So even if we get out complete garbage
205196 // we should still be safe.
206197 let nhdr = take_nhdr ( & mut self . base ) ?;
207- let name = take_bytes_align4 ( nhdr. n_namesz as usize , & mut self . base ) ?;
208- let desc = take_bytes_align4 ( nhdr. n_descsz as usize , & mut self . base ) ?;
198+ let name = take_bytes_align4 ( nhdr. n_namesz . get ( NE ) as usize , & mut self . base ) ?;
199+ let desc = take_bytes_align4 ( nhdr. n_descsz . get ( NE ) as usize , & mut self . base ) ?;
209200 Some ( Note {
210201 name : name,
211202 desc : desc,
212- tipe : nhdr. n_type ,
203+ tipe : nhdr. n_type . get ( NE ) ,
213204 } )
214205 }
215206}
0 commit comments