@@ -32,7 +32,7 @@ pub(crate) fn page_size() -> usize {
32
32
let mut page_size = PAGE_SIZE . load ( Relaxed ) ;
33
33
34
34
if page_size == 0 {
35
- init_from_proc_self_auxv ( ) ;
35
+ init_auxv ( ) ;
36
36
page_size = PAGE_SIZE . load ( Relaxed ) ;
37
37
}
38
38
@@ -45,7 +45,7 @@ pub(crate) fn clock_ticks_per_second() -> u64 {
45
45
let mut ticks = CLOCK_TICKS_PER_SECOND . load ( Relaxed ) ;
46
46
47
47
if ticks == 0 {
48
- init_from_proc_self_auxv ( ) ;
48
+ init_auxv ( ) ;
49
49
ticks = CLOCK_TICKS_PER_SECOND . load ( Relaxed ) ;
50
50
}
51
51
@@ -59,7 +59,7 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
59
59
let mut hwcap2 = HWCAP2 . load ( Relaxed ) ;
60
60
61
61
if hwcap == 0 || hwcap2 == 0 {
62
- init_from_proc_self_auxv ( ) ;
62
+ init_auxv ( ) ;
63
63
hwcap = HWCAP . load ( Relaxed ) ;
64
64
hwcap2 = HWCAP2 . load ( Relaxed ) ;
65
65
}
@@ -73,7 +73,7 @@ pub(crate) fn linux_execfn() -> &'static CStr {
73
73
let mut execfn = EXECFN . load ( Relaxed ) ;
74
74
75
75
if execfn. is_null ( ) {
76
- init_from_proc_self_auxv ( ) ;
76
+ init_auxv ( ) ;
77
77
execfn = EXECFN . load ( Relaxed ) ;
78
78
}
79
79
@@ -89,7 +89,7 @@ pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) {
89
89
let mut phnum = PHNUM . load ( Relaxed ) ;
90
90
91
91
if phdr. is_null ( ) || phnum == 0 {
92
- init_from_proc_self_auxv ( ) ;
92
+ init_auxv ( ) ;
93
93
phdr = PHDR . load ( Relaxed ) ;
94
94
phnum = PHNUM . load ( Relaxed ) ;
95
95
}
@@ -114,7 +114,7 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr {
114
114
let mut ehdr = SYSINFO_EHDR . load ( Relaxed ) ;
115
115
116
116
if ehdr. is_null ( ) {
117
- init_from_proc_self_auxv ( ) ;
117
+ init_auxv ( ) ;
118
118
ehdr = SYSINFO_EHDR . load ( Relaxed ) ;
119
119
}
120
120
@@ -130,9 +130,53 @@ static PHDR: AtomicPtr<Elf_Phdr> = AtomicPtr::new(null_mut());
130
130
static PHNUM : AtomicUsize = AtomicUsize :: new ( 0 ) ;
131
131
static EXECFN : AtomicPtr < c:: c_char > = AtomicPtr :: new ( null_mut ( ) ) ;
132
132
133
- /// On non-Mustang platforms, we read the aux vector from /proc/self/auxv.
134
133
#[ cfg( not( target_vendor = "mustang" ) ) ]
135
- fn init_from_proc_self_auxv ( ) {
134
+ fn pr_get_auxv ( ) -> crate :: io:: Result < Vec < u8 > > {
135
+ use super :: super :: conv:: { c_int, pass_usize, ret_usize} ;
136
+ const PR_GET_AUXV : c:: c_int = 0x41555856 ;
137
+ let mut buffer = alloc:: vec![ 0u8 ; 512 ] ;
138
+ let len = unsafe {
139
+ ret_usize ( syscall_always_asm ! (
140
+ __NR_prctl,
141
+ c_int( PR_GET_AUXV ) ,
142
+ buffer. as_ptr( ) ,
143
+ pass_usize( buffer. len( ) )
144
+ ) ) ?
145
+ } ;
146
+ if len <= buffer. len ( ) {
147
+ buffer. truncate ( len) ;
148
+ return Ok ( buffer) ;
149
+ }
150
+ buffer. resize ( len, 0 ) ;
151
+ let len = unsafe {
152
+ ret_usize ( syscall_always_asm ! (
153
+ __NR_prctl,
154
+ c_int( PR_GET_AUXV ) ,
155
+ buffer. as_ptr( ) ,
156
+ pass_usize( buffer. len( ) )
157
+ ) ) ?
158
+ } ;
159
+ assert_eq ! ( len, buffer. len( ) ) ;
160
+ return Ok ( buffer) ;
161
+ }
162
+
163
+ /// On non-Mustang platforms, we read the aux vector via the prctl PR_GET_AUXV, with a fallback to
164
+ /// /proc/self/auxv for kernels that don't support PR_GET_AUXV.
165
+ #[ cfg( not( target_vendor = "mustang" ) ) ]
166
+ fn init_auxv ( ) {
167
+ match pr_get_auxv ( ) {
168
+ Ok ( buffer) => {
169
+ // SAFETY: We assume the kernel returns a valid auxv.
170
+ unsafe {
171
+ init_from_auxp ( buffer. as_ptr ( ) . cast ( ) ) ;
172
+ }
173
+ return ;
174
+ }
175
+ Err ( _) => {
176
+ // Fall back to /proc/self/auxv on error.
177
+ }
178
+ }
179
+
136
180
// Open "/proc/self/auxv", either because we trust "/proc", or because
137
181
// we're running inside QEMU and `proc_self_auxv`'s extra checking foils
138
182
// QEMU's emulation so we need to do a plain open to get the right
@@ -143,7 +187,7 @@ fn init_from_proc_self_auxv() {
143
187
}
144
188
145
189
#[ cfg( target_vendor = "mustang" ) ]
146
- fn init_from_proc_self_auxv ( ) {
190
+ fn init_auxv ( ) {
147
191
panic ! ( "mustang should have initialized the auxv values" ) ;
148
192
}
149
193
0 commit comments