1
1
use core:: fmt:: { self , Write } ;
2
- use core:: mem:: { size_of, transmute} ;
3
2
use core:: slice:: from_raw_parts;
4
3
use libc:: c_char;
4
+ use object:: NativeEndian as NE ;
5
5
6
6
unsafe extern "C" {
7
7
// 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;
118
118
119
119
// Elf_Nhdr represents an ELF note header in the endianness of the target.
120
120
#[ 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 > ;
127
122
128
123
// Note represents an ELF note (header + contents). The name is left as a u8
129
124
// 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]> {
176
171
Some ( out)
177
172
}
178
173
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 .
183
178
fn 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;
192
183
Some ( out)
193
184
}
194
185
@@ -204,12 +195,12 @@ impl<'a> Iterator for NoteIter<'a> {
204
195
// decisions based on the type. So even if we get out complete garbage
205
196
// we should still be safe.
206
197
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 ) ?;
209
200
Some ( Note {
210
201
name : name,
211
202
desc : desc,
212
- tipe : nhdr. n_type ,
203
+ tipe : nhdr. n_type . get ( NE ) ,
213
204
} )
214
205
}
215
206
}
0 commit comments