1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! Read auxv entries by chasing pointers in the ELF stack layout.
//!
//! The sole public function is `iterate_stack_auxv`. It iterates across the entries, exposing them via
//! `AuxvPair`. The two fields in `AuxvPair` will be of type `AuxvType`.
//!
//! **Only use this code when all of the following are satisfied**:
//!
//! - In an ELF binary. In practice, this means Linux, FreeBSD, and other Unix
//! variants (but not macOS).
//! - No other threads have manipulating the environment (setenv, putenv, or equivalent). In
//! practice this means do it as the very first stuff in `main` before touching the environment
//! or spawning any other threads.
//!
//! This works by navigating the stack at runtime to find the auxv entries, so it is `unsafe`.
//! It may segfault or produce bogus output when run on non-ELF systems or when the environment
//! has been modified. It relies on navigating from the original destination of the `environ`
//! pointer in the ELF stack layout to auxv.
//!
//! `iterate_stack_auxv` is not available on Windows since they use a different (non-POSIX)
//! environment pointer name. And, of course, it wouldn't work even if it compiled.
//!
//! If you're on a system with ELF executables (Linux, FreeBSD, other Unixes), run the example
//! that shows its own auxv keys and values: `cargo run --example elf_stack_show_auxv`.
//! It should print a short table of a dozen or two numbers. On macOS, it tends to produce garbage
//! numbers for a while before mercifully exiting normally. On Windows, the function is not
//! available because their names are not POSIX compatible so it wouldn't even compile, and so the
//! example prints nothing.
use std;
use ;
/// Returns an iterator across the auxv entries.
pub unsafe
/// An iterator across auxv pairs from crawling the ELF stack.
extern "C"
/// returns a pointer to the first entry in the auxv table
/// (specifically, the key in the first key / value pair)
unsafe