1use crate::aux_var::{AuxVar, AuxVarRaw, AuxVarType};
25use crate::util::count_bytes_until_null;
26use core::ffi::CStr;
27use core::fmt::Debug;
28
29#[derive(Debug)]
59pub struct StackLayoutRef<'a> {
60 bytes: &'a [u8],
62 argc: Option<usize>,
63}
64
65impl<'a> StackLayoutRef<'a> {
66 #[must_use]
71 pub fn new(bytes: &'a [u8], argc: Option<usize>) -> Self {
72 assert_eq!(bytes.as_ptr().align_offset(align_of::<usize>()), 0);
73 Self { bytes, argc }
74 }
75
76 fn get_slice_argv(&self) -> &'a [u8] {
83 match self.argc {
84 None => {
85 let start = size_of::<usize>();
86 &self.bytes[start..]
88 }
89 Some(_) => self.bytes,
90 }
91 }
92
93 fn get_slice_envv(&self) -> &'a [u8] {
99 let base_slice = self.get_slice_argv();
101
102 let start = self.argc() * size_of::<usize>() + size_of::<usize>() ;
103 &base_slice[start..]
104 }
105
106 fn get_slice_auxv(&self) -> &'a [u8] {
111 let base_slice = self.get_slice_envv();
113
114 let start = self.envc() * size_of::<usize>() + size_of::<usize>() ;
116 &base_slice[start..]
117 }
118
119 #[must_use]
123 pub fn argc(&self) -> usize {
124 self.argc.unwrap_or_else(|| unsafe {
125 self.bytes
127 .as_ptr()
128 .cast::<usize>()
129 .as_ref()
130 .copied()
131 .unwrap()
132 })
133 }
134
135 #[must_use]
137 pub fn envc(&self) -> usize {
138 self.envv_raw_iter().count()
139 }
140
141 #[must_use]
143 pub fn auxvc(&self) -> usize {
144 self.auxv_raw_iter().count()
145 }
146
147 pub fn argv_raw_iter(&self) -> impl Iterator<Item = *const u8> {
155 let buffer = self.get_slice_argv();
156 unsafe { NullTermArrIter::new(buffer) }
157 }
158
159 pub fn envv_raw_iter(&self) -> impl Iterator<Item = *const u8> {
167 let buffer = self.get_slice_envv();
168 unsafe { NullTermArrIter::new(buffer) }
169 }
170
171 pub fn auxv_raw_iter(&self) -> impl Iterator<Item = AuxVarRaw> {
179 AuxVarRawIter::new(self.get_slice_auxv())
180 }
181
182 pub unsafe fn argv_iter(&self) -> impl Iterator<Item = &'a CStr> {
193 let buffer = self.get_slice_argv();
194 unsafe { CStrArrayIter::new(buffer) }
195 }
196 pub unsafe fn envv_iter(&self) -> impl Iterator<Item = &'a CStr> {
207 let buffer = self.get_slice_envv();
208 unsafe { CStrArrayIter::new(buffer) }
209 }
210
211 pub unsafe fn auxv_iter(&self) -> impl Iterator<Item = AuxVar<'a>> {
222 unsafe { AuxVarIter::new(self.get_slice_auxv()) }
223 }
224}
225
226#[derive(Debug)]
231struct NullTermArrIter<'a> {
232 buffer: &'a [u8],
235 i: usize,
236}
237
238impl<'a> NullTermArrIter<'a> {
239 unsafe fn new(buffer: &'a [u8]) -> Self {
241 assert_eq!(buffer.as_ptr().align_offset(align_of::<usize>()), 0);
242
243 Self { buffer, i: 0 }
244 }
245}
246
247impl Iterator for NullTermArrIter<'_> {
248 type Item = *const u8;
249
250 fn next(&mut self) -> Option<Self::Item> {
251 if self.i >= self.buffer.len() {
252 panic!("null terminated array ended prematurely");
253 }
254
255 let entry_ptr = unsafe {
256 self.buffer
257 .as_ptr()
258 .cast::<*const u8>()
259 .add(self.i)
261 };
262 let entry = unsafe { entry_ptr.as_ref().copied().unwrap() };
263 if entry.is_null() {
264 return None;
265 }
266
267 self.i += 1;
268 Some(entry)
269 }
270}
271
272#[derive(Debug)]
277struct CStrArrayIter<'a> {
278 buffer: &'a [u8],
281 i: usize,
282}
283
284impl<'a> CStrArrayIter<'a> {
285 unsafe fn new(buffer: &'a [u8]) -> Self {
287 assert_eq!(buffer.as_ptr().align_offset(align_of::<usize>()), 0);
288
289 Self { buffer, i: 0 }
290 }
291}
292
293impl<'a> Iterator for CStrArrayIter<'a> {
294 type Item = &'a CStr;
295
296 fn next(&mut self) -> Option<Self::Item> {
297 if self.i >= self.buffer.len() {
298 panic!("null terminated array ended prematurely");
299 }
300
301 let entry_ptr = unsafe { self.buffer.as_ptr().cast::<*const u8>().add(self.i) };
302 let entry = unsafe { entry_ptr.as_ref().copied().unwrap() };
303 if entry.is_null() {
304 return None;
305 }
306
307 {
309 let end = &raw const self.buffer[self.buffer.len() - 1];
310 assert!(entry > self.buffer.as_ptr());
311 assert!(entry <= end);
312 }
313
314 let begin_index = entry as usize - self.buffer.as_ptr() as usize;
316 let end_index_rel =
317 count_bytes_until_null(&self.buffer[begin_index..]).expect("should have NUL byte");
318 let end_index = begin_index + end_index_rel + 1 ;
319 let cstr = CStr::from_bytes_with_nul(&self.buffer[begin_index..end_index]).unwrap();
320
321 self.i += 1;
322 Some(cstr)
323 }
324}
325
326#[derive(Debug)]
330pub struct AuxVarRawIter<'a> {
331 auxv: &'a [u8],
334 i: usize,
335}
336
337impl<'a> AuxVarRawIter<'a> {
338 const fn new(auxv: &'a [u8]) -> Self {
339 Self { auxv, i: 0 }
340 }
341}
342
343impl<'a> Iterator for AuxVarRawIter<'a> {
344 type Item = AuxVarRaw;
345
346 fn next(&mut self) -> Option<Self::Item> {
347 let entry = unsafe {
348 let entry_ptr = self.auxv.as_ptr().cast::<AuxVarRaw>().add(self.i);
349 entry_ptr.as_ref().unwrap()
350 };
351
352 if let Ok(key) = entry.key() {
353 if key == AuxVarType::Null {
354 None
355 } else {
356 self.i += 1;
357 Some(*entry)
358 }
359 } else {
360 None
363 }
364 }
365}
366
367#[derive(Debug)]
369pub struct AuxVarIter<'a> {
370 auxv: &'a [u8],
373 serialized_iter: AuxVarRawIter<'a>,
374}
375
376impl<'a> AuxVarIter<'a> {
377 const unsafe fn new(auxv: &'a [u8]) -> Self {
379 Self {
380 serialized_iter: AuxVarRawIter::new(auxv),
381 auxv,
382 }
383 }
384}
385
386impl<'a> Iterator for AuxVarIter<'a> {
387 type Item = AuxVar<'a>;
388
389 fn next(&mut self) -> Option<Self::Item> {
390 unsafe {
391 self.serialized_iter
392 .next()
393 .map(|ref x| AuxVar::from_raw(x, self.auxv))
394 }
395 }
396}
397
398#[cfg(test)]
399mod tests {
400 use crate::StackLayoutRef;
401
402 #[repr(C, align(8))]
403 struct Aligned8<T>(T);
404
405 impl<T> AsRef<T> for Aligned8<T> {
406 fn as_ref(&self) -> &T {
407 &self.0
408 }
409 }
410
411 #[cfg(target_arch = "x86_64")]
413 const TEST_DATA_X86_64: Aligned8<[u8; 1592]> = Aligned8([
414 4, 0, 0, 0, 0, 0, 0, 0, 190, 252, 185, 93, 255, 127, 0, 0, 237, 252, 185, 93, 255, 127, 0,
415 0, 243, 252, 185, 93, 255, 127, 0, 0, 250, 252, 185, 93, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0,
416 0, 0, 0, 253, 185, 93, 255, 127, 0, 0, 109, 253, 185, 93, 255, 127, 0, 0, 191, 253, 185,
417 93, 255, 127, 0, 0, 224, 253, 185, 93, 255, 127, 0, 0, 22, 254, 185, 93, 255, 127, 0, 0,
418 88, 254, 185, 93, 255, 127, 0, 0, 144, 254, 185, 93, 255, 127, 0, 0, 70, 0, 186, 93, 255,
419 127, 0, 0, 133, 0, 186, 93, 255, 127, 0, 0, 155, 0, 186, 93, 255, 127, 0, 0, 179, 0, 186,
420 93, 255, 127, 0, 0, 210, 0, 186, 93, 255, 127, 0, 0, 237, 0, 186, 93, 255, 127, 0, 0, 46,
421 1, 186, 93, 255, 127, 0, 0, 76, 1, 186, 93, 255, 127, 0, 0, 100, 1, 186, 93, 255, 127, 0,
422 0, 126, 1, 186, 93, 255, 127, 0, 0, 152, 1, 186, 93, 255, 127, 0, 0, 178, 1, 186, 93, 255,
423 127, 0, 0, 201, 1, 186, 93, 255, 127, 0, 0, 24, 2, 186, 93, 255, 127, 0, 0, 78, 2, 186, 93,
424 255, 127, 0, 0, 100, 2, 186, 93, 255, 127, 0, 0, 122, 2, 186, 93, 255, 127, 0, 0, 133, 2,
425 186, 93, 255, 127, 0, 0, 179, 2, 186, 93, 255, 127, 0, 0, 192, 2, 186, 93, 255, 127, 0, 0,
426 134, 15, 186, 93, 255, 127, 0, 0, 226, 15, 186, 93, 255, 127, 0, 0, 243, 15, 186, 93, 255,
427 127, 0, 0, 8, 16, 186, 93, 255, 127, 0, 0, 216, 16, 186, 93, 255, 127, 0, 0, 119, 18, 186,
428 93, 255, 127, 0, 0, 215, 18, 186, 93, 255, 127, 0, 0, 251, 18, 186, 93, 255, 127, 0, 0,
429 110, 29, 186, 93, 255, 127, 0, 0, 134, 29, 186, 93, 255, 127, 0, 0, 167, 29, 186, 93, 255,
430 127, 0, 0, 190, 29, 186, 93, 255, 127, 0, 0, 33, 31, 186, 93, 255, 127, 0, 0, 244, 33, 186,
431 93, 255, 127, 0, 0, 8, 34, 186, 93, 255, 127, 0, 0, 189, 35, 186, 93, 255, 127, 0, 0, 236,
432 35, 186, 93, 255, 127, 0, 0, 81, 36, 186, 93, 255, 127, 0, 0, 181, 36, 186, 93, 255, 127,
433 0, 0, 37, 37, 186, 93, 255, 127, 0, 0, 60, 37, 186, 93, 255, 127, 0, 0, 77, 37, 186, 93,
434 255, 127, 0, 0, 100, 37, 186, 93, 255, 127, 0, 0, 130, 37, 186, 93, 255, 127, 0, 0, 157,
435 37, 186, 93, 255, 127, 0, 0, 181, 37, 186, 93, 255, 127, 0, 0, 201, 37, 186, 93, 255, 127,
436 0, 0, 224, 37, 186, 93, 255, 127, 0, 0, 245, 37, 186, 93, 255, 127, 0, 0, 14, 38, 186, 93,
437 255, 127, 0, 0, 34, 38, 186, 93, 255, 127, 0, 0, 194, 39, 186, 93, 255, 127, 0, 0, 227, 39,
438 186, 93, 255, 127, 0, 0, 43, 40, 186, 93, 255, 127, 0, 0, 14, 41, 186, 93, 255, 127, 0, 0,
439 78, 41, 186, 93, 255, 127, 0, 0, 190, 41, 186, 93, 255, 127, 0, 0, 207, 41, 186, 93, 255,
440 127, 0, 0, 239, 41, 186, 93, 255, 127, 0, 0, 108, 49, 186, 93, 255, 127, 0, 0, 124, 49,
441 186, 93, 255, 127, 0, 0, 12, 50, 186, 93, 255, 127, 0, 0, 63, 50, 186, 93, 255, 127, 0, 0,
442 81, 50, 186, 93, 255, 127, 0, 0, 188, 50, 186, 93, 255, 127, 0, 0, 231, 50, 186, 93, 255,
443 127, 0, 0, 140, 51, 186, 93, 255, 127, 0, 0, 193, 51, 186, 93, 255, 127, 0, 0, 253, 51,
444 186, 93, 255, 127, 0, 0, 133, 52, 186, 93, 255, 127, 0, 0, 56, 53, 186, 93, 255, 127, 0, 0,
445 117, 53, 186, 93, 255, 127, 0, 0, 200, 53, 186, 93, 255, 127, 0, 0, 242, 53, 186, 93, 255,
446 127, 0, 0, 253, 53, 186, 93, 255, 127, 0, 0, 210, 56, 186, 93, 255, 127, 0, 0, 220, 56,
447 186, 93, 255, 127, 0, 0, 3, 57, 186, 93, 255, 127, 0, 0, 60, 58, 186, 93, 255, 127, 0, 0,
448 165, 58, 186, 93, 255, 127, 0, 0, 187, 58, 186, 93, 255, 127, 0, 0, 222, 58, 186, 93, 255,
449 127, 0, 0, 15, 59, 186, 93, 255, 127, 0, 0, 38, 59, 186, 93, 255, 127, 0, 0, 120, 59, 186,
450 93, 255, 127, 0, 0, 157, 59, 186, 93, 255, 127, 0, 0, 165, 59, 186, 93, 255, 127, 0, 0, 10,
451 60, 186, 93, 255, 127, 0, 0, 51, 60, 186, 93, 255, 127, 0, 0, 83, 60, 186, 93, 255, 127, 0,
452 0, 130, 60, 186, 93, 255, 127, 0, 0, 152, 60, 186, 93, 255, 127, 0, 0, 172, 60, 186, 93,
453 255, 127, 0, 0, 209, 60, 186, 93, 255, 127, 0, 0, 223, 61, 186, 93, 255, 127, 0, 0, 20, 62,
454 186, 93, 255, 127, 0, 0, 47, 62, 186, 93, 255, 127, 0, 0, 67, 62, 186, 93, 255, 127, 0, 0,
455 81, 62, 186, 93, 255, 127, 0, 0, 99, 62, 186, 93, 255, 127, 0, 0, 112, 62, 186, 93, 255,
456 127, 0, 0, 138, 62, 186, 93, 255, 127, 0, 0, 192, 62, 186, 93, 255, 127, 0, 0, 237, 64,
457 186, 93, 255, 127, 0, 0, 43, 66, 186, 93, 255, 127, 0, 0, 69, 66, 186, 93, 255, 127, 0, 0,
458 29, 76, 186, 93, 255, 127, 0, 0, 52, 76, 186, 93, 255, 127, 0, 0, 83, 76, 186, 93, 255,
459 127, 0, 0, 106, 76, 186, 93, 255, 127, 0, 0, 132, 76, 186, 93, 255, 127, 0, 0, 157, 76,
460 186, 93, 255, 127, 0, 0, 193, 76, 186, 93, 255, 127, 0, 0, 237, 76, 186, 93, 255, 127, 0,
461 0, 30, 77, 186, 93, 255, 127, 0, 0, 76, 77, 186, 93, 255, 127, 0, 0, 109, 77, 186, 93, 255,
462 127, 0, 0, 159, 77, 186, 93, 255, 127, 0, 0, 180, 77, 186, 93, 255, 127, 0, 0, 220, 77,
463 186, 93, 255, 127, 0, 0, 43, 78, 186, 93, 255, 127, 0, 0, 60, 78, 186, 93, 255, 127, 0, 0,
464 81, 78, 186, 93, 255, 127, 0, 0, 115, 78, 186, 93, 255, 127, 0, 0, 211, 78, 186, 93, 255,
465 127, 0, 0, 236, 78, 186, 93, 255, 127, 0, 0, 18, 79, 186, 93, 255, 127, 0, 0, 53, 79, 186,
466 93, 255, 127, 0, 0, 95, 79, 186, 93, 255, 127, 0, 0, 116, 79, 186, 93, 255, 127, 0, 0, 141,
467 79, 186, 93, 255, 127, 0, 0, 170, 79, 186, 93, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33,
468 0, 0, 0, 0, 0, 0, 0, 0, 208, 160, 43, 202, 127, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 48, 14, 0,
469 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 255, 251, 235, 191, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
470 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
471 0, 0, 0, 0, 0, 64, 144, 123, 202, 20, 86, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0,
472 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 240, 160,
473 43, 202, 127, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
474 64, 25, 124, 202, 20, 86, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 232, 3, 0, 0, 0, 0, 0, 0, 12, 0,
475 0, 0, 0, 0, 0, 0, 232, 3, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0,
476 0, 14, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
477 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 153, 240, 185, 93, 255, 127, 0, 0, 26, 0, 0, 0, 0, 0,
478 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 201, 79, 186, 93, 255, 127, 0, 0,
479 15, 0, 0, 0, 0, 0, 0, 0, 169, 240, 185, 93, 255, 127, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 28, 0,
480 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
481 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 120, 161, 11, 82, 13, 91, 238, 102,
482 222, 133, 171, 66, 146, 247, 165, 120, 56, 54, 95, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
483 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
484 ]);
485
486 #[cfg(target_arch = "x86")]
488 const TEST_DATA_X86: Aligned8<[u8; 804]> = Aligned8([
489 4, 0, 0, 0, 148, 92, 235, 255, 213, 92, 235, 255, 219, 92, 235, 255, 226, 92, 235, 255, 0,
490 0, 0, 0, 232, 92, 235, 255, 85, 93, 235, 255, 167, 93, 235, 255, 200, 93, 235, 255, 254,
491 93, 235, 255, 64, 94, 235, 255, 120, 94, 235, 255, 30, 95, 235, 255, 93, 95, 235, 255, 115,
492 95, 235, 255, 139, 95, 235, 255, 170, 95, 235, 255, 197, 95, 235, 255, 6, 96, 235, 255, 36,
493 96, 235, 255, 60, 96, 235, 255, 86, 96, 235, 255, 112, 96, 235, 255, 138, 96, 235, 255,
494 161, 96, 235, 255, 240, 96, 235, 255, 38, 97, 235, 255, 60, 97, 235, 255, 82, 97, 235, 255,
495 93, 97, 235, 255, 139, 97, 235, 255, 152, 97, 235, 255, 94, 110, 235, 255, 186, 110, 235,
496 255, 203, 110, 235, 255, 224, 110, 235, 255, 176, 111, 235, 255, 55, 114, 235, 255, 151,
497 114, 235, 255, 186, 114, 235, 255, 45, 125, 235, 255, 69, 125, 235, 255, 102, 125, 235,
498 255, 125, 125, 235, 255, 224, 126, 235, 255, 179, 129, 235, 255, 199, 129, 235, 255, 124,
499 131, 235, 255, 171, 131, 235, 255, 16, 132, 235, 255, 116, 132, 235, 255, 228, 132, 235,
500 255, 251, 132, 235, 255, 12, 133, 235, 255, 35, 133, 235, 255, 65, 133, 235, 255, 92, 133,
501 235, 255, 116, 133, 235, 255, 136, 133, 235, 255, 159, 133, 235, 255, 180, 133, 235, 255,
502 205, 133, 235, 255, 225, 133, 235, 255, 176, 135, 235, 255, 209, 135, 235, 255, 25, 136,
503 235, 255, 252, 136, 235, 255, 60, 137, 235, 255, 172, 137, 235, 255, 189, 137, 235, 255,
504 221, 137, 235, 255, 90, 145, 235, 255, 106, 145, 235, 255, 250, 145, 235, 255, 45, 146,
505 235, 255, 63, 146, 235, 255, 170, 146, 235, 255, 213, 146, 235, 255, 122, 147, 235, 255,
506 175, 147, 235, 255, 235, 147, 235, 255, 115, 148, 235, 255, 38, 149, 235, 255, 99, 149,
507 235, 255, 182, 149, 235, 255, 224, 149, 235, 255, 235, 149, 235, 255, 192, 152, 235, 255,
508 202, 152, 235, 255, 241, 152, 235, 255, 42, 154, 235, 255, 147, 154, 235, 255, 169, 154,
509 235, 255, 204, 154, 235, 255, 253, 154, 235, 255, 20, 155, 235, 255, 102, 155, 235, 255,
510 139, 155, 235, 255, 147, 155, 235, 255, 248, 155, 235, 255, 33, 156, 235, 255, 65, 156,
511 235, 255, 112, 156, 235, 255, 134, 156, 235, 255, 154, 156, 235, 255, 191, 156, 235, 255,
512 205, 157, 235, 255, 2, 158, 235, 255, 29, 158, 235, 255, 49, 158, 235, 255, 63, 158, 235,
513 255, 81, 158, 235, 255, 94, 158, 235, 255, 120, 158, 235, 255, 174, 158, 235, 255, 219,
514 160, 235, 255, 25, 162, 235, 255, 51, 162, 235, 255, 11, 172, 235, 255, 34, 172, 235, 255,
515 65, 172, 235, 255, 88, 172, 235, 255, 114, 172, 235, 255, 139, 172, 235, 255, 175, 172,
516 235, 255, 219, 172, 235, 255, 12, 173, 235, 255, 58, 173, 235, 255, 91, 173, 235, 255, 141,
517 173, 235, 255, 162, 173, 235, 255, 202, 173, 235, 255, 25, 174, 235, 255, 42, 174, 235,
518 255, 63, 174, 235, 255, 97, 174, 235, 255, 193, 174, 235, 255, 218, 174, 235, 255, 0, 175,
519 235, 255, 35, 175, 235, 255, 77, 175, 235, 255, 98, 175, 235, 255, 123, 175, 235, 255, 152,
520 175, 235, 255, 0, 0, 0, 0, 32, 0, 0, 0, 176, 117, 245, 247, 33, 0, 0, 0, 0, 112, 245, 247,
521 51, 0, 0, 0, 48, 14, 0, 0, 16, 0, 0, 0, 255, 251, 235, 191, 6, 0, 0, 0, 0, 16, 0, 0, 17, 0,
522 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 52, 128, 4, 8, 4, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0,
523 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 201, 170, 4, 8, 11, 0, 0,
524 0, 232, 3, 0, 0, 12, 0, 0, 0, 232, 3, 0, 0, 13, 0, 0, 0, 100, 0, 0, 0, 14, 0, 0, 0, 100, 0,
525 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 219, 77, 235, 255, 26, 0, 0, 0, 2, 0, 0, 0, 31,
526 0, 0, 0, 183, 175, 235, 255, 15, 0, 0, 0, 235, 77, 235, 255, 27, 0, 0, 0, 28, 0, 0, 0, 28,
527 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 213, 250, 168, 134, 233, 229,
528 101, 88, 100, 213, 132, 214, 57, 104, 200, 105, 54, 56, 54, 0, 0, 0, 0, 0,
529 ]);
530
531 #[test]
532 #[cfg(target_arch = "x86_64")]
533 fn test_parse_real_data() {
534 let data = TEST_DATA_X86_64.as_ref();
535 let layout = StackLayoutRef::new(data, None);
536
537 assert_eq!(layout.argc(), 4);
538
539 {
541 assert_eq!(
542 layout
543 .get_slice_argv()
544 .as_ptr()
545 .align_offset(align_of::<usize>()),
546 0
547 );
548 assert_eq!(layout.argv_raw_iter().count(), 4);
549 layout
551 .argv_raw_iter()
552 .enumerate()
553 .for_each(|(i, ptr)| eprintln!(" arg {i:>2}: {ptr:?}"));
554 }
555
556 {
558 assert_eq!(
559 layout
560 .get_slice_envv()
561 .as_ptr()
562 .align_offset(align_of::<usize>()),
563 0
564 );
565 assert_eq!(layout.envv_raw_iter().count(), 139);
566 layout
568 .envv_raw_iter()
569 .enumerate()
570 .for_each(|(i, ptr)| eprintln!(" env {i:>2}: {ptr:?}"));
571 }
572
573 {
575 assert_eq!(
576 layout
577 .get_slice_auxv()
578 .as_ptr()
579 .align_offset(align_of::<usize>()),
580 0
581 );
582 assert_eq!(layout.auxv_raw_iter().count(), 20);
584 layout
585 .auxv_raw_iter()
586 .enumerate()
587 .for_each(|(i, ptr)| eprintln!(" aux {i:>2}: {ptr:?}"));
588 }
589 }
590
591 #[test]
592 #[cfg(target_arch = "x86")]
593 fn test_parse_real_data() {
594 let data = TEST_DATA_X86.as_ref();
595 let layout = StackLayoutRef::new(data, None);
596
597 assert_eq!(layout.argc(), 4);
598
599 {
601 assert_eq!(
602 layout
603 .get_slice_argv()
604 .as_ptr()
605 .align_offset(align_of::<usize>()),
606 0
607 );
608
609 layout
611 .argv_raw_iter()
612 .enumerate()
613 .for_each(|(i, ptr)| eprintln!(" arg {i:>2}: {ptr:?}"));
614
615 assert_eq!(layout.argv_raw_iter().count(), 4);
616 }
617
618 {
620 assert_eq!(
621 layout
622 .get_slice_envv()
623 .as_ptr()
624 .align_offset(align_of::<usize>()),
625 0
626 );
627
628 layout
630 .envv_raw_iter()
631 .enumerate()
632 .for_each(|(i, ptr)| eprintln!(" env {i:>2}: {ptr:?}"));
633
634 assert_eq!(layout.envv_raw_iter().count(), 139);
635 }
636
637 {
639 assert_eq!(
640 layout
641 .get_slice_auxv()
642 .as_ptr()
643 .align_offset(align_of::<usize>()),
644 0
645 );
646
647 layout
649 .auxv_raw_iter()
650 .enumerate()
651 .for_each(|(i, ptr)| eprintln!(" aux {i:>2}: {ptr:?}"));
652 assert_eq!(layout.auxv_raw_iter().count(), 21);
653 }
654 }
655}