@@ -20,6 +20,8 @@ use core::sync::atomic::AtomicU8;
20
20
use core:: sync:: atomic:: Ordering :: Relaxed ;
21
21
use core:: sync:: atomic:: { AtomicPtr , AtomicUsize } ;
22
22
use linux_raw_sys:: elf:: * ;
23
+ #[ cfg( target_arch = "x86" ) ]
24
+ use linux_raw_sys:: general:: AT_SYSINFO ;
23
25
use linux_raw_sys:: general:: {
24
26
AT_BASE , AT_CLKTCK , AT_EXECFN , AT_HWCAP , AT_HWCAP2 , AT_NULL , AT_PAGESZ , AT_SYSINFO_EHDR ,
25
27
} ;
@@ -34,8 +36,12 @@ pub(crate) fn page_size() -> usize {
34
36
let mut page_size = PAGE_SIZE . load ( Relaxed ) ;
35
37
36
38
if page_size == 0 {
37
- init_auxv ( ) ;
38
- page_size = PAGE_SIZE . load ( Relaxed ) ;
39
+ #[ cold]
40
+ fn compute_page_size ( ) -> usize {
41
+ init_auxv ( ) ;
42
+ PAGE_SIZE . load ( Relaxed )
43
+ }
44
+ page_size = compute_page_size ( ) ;
39
45
}
40
46
41
47
page_size
@@ -47,8 +53,12 @@ pub(crate) fn clock_ticks_per_second() -> u64 {
47
53
let mut ticks = CLOCK_TICKS_PER_SECOND . load ( Relaxed ) ;
48
54
49
55
if ticks == 0 {
50
- init_auxv ( ) ;
51
- ticks = CLOCK_TICKS_PER_SECOND . load ( Relaxed ) ;
56
+ #[ cold]
57
+ fn compute_clock_ticks_per_second ( ) -> usize {
58
+ init_auxv ( ) ;
59
+ CLOCK_TICKS_PER_SECOND . load ( Relaxed )
60
+ }
61
+ ticks = compute_clock_ticks_per_second ( ) ;
52
62
}
53
63
54
64
ticks as u64
@@ -61,9 +71,12 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
61
71
let mut hwcap2 = HWCAP2 . load ( Relaxed ) ;
62
72
63
73
if hwcap == 0 || hwcap2 == 0 {
64
- init_auxv ( ) ;
65
- hwcap = HWCAP . load ( Relaxed ) ;
66
- hwcap2 = HWCAP2 . load ( Relaxed ) ;
74
+ #[ cold]
75
+ fn compute_linux_hwcap ( ) -> ( usize , usize ) {
76
+ init_auxv ( ) ;
77
+ ( HWCAP . load ( Relaxed ) , HWCAP2 . load ( Relaxed ) )
78
+ }
79
+ ( hwcap, hwcap2) = compute_linux_hwcap ( ) ;
67
80
}
68
81
69
82
( hwcap, hwcap2)
@@ -75,8 +88,12 @@ pub(crate) fn linux_execfn() -> &'static CStr {
75
88
let mut execfn = EXECFN . load ( Relaxed ) ;
76
89
77
90
if execfn. is_null ( ) {
78
- init_auxv ( ) ;
79
- execfn = EXECFN . load ( Relaxed ) ;
91
+ #[ cold]
92
+ fn compute_linux_execfn ( ) -> * mut c:: c_char {
93
+ init_auxv ( ) ;
94
+ EXECFN . load ( Relaxed )
95
+ }
96
+ execfn = compute_linux_execfn ( ) ;
80
97
}
81
98
82
99
// SAFETY: We assume the `AT_EXECFN` value provided by the kernel is a
@@ -91,8 +108,12 @@ pub(crate) fn linux_secure() -> bool {
91
108
92
109
// 0 means not initialized yet.
93
110
if secure == 0 {
94
- init_auxv ( ) ;
95
- secure = SECURE . load ( Relaxed ) ;
111
+ #[ cold]
112
+ fn compute_linux_secure ( ) -> u8 {
113
+ init_auxv ( ) ;
114
+ SECURE . load ( Relaxed )
115
+ }
116
+ secure = compute_linux_secure ( ) ;
96
117
}
97
118
98
119
// 0 means not present. Libc `getauxval(AT_SECURE)` would return 0.
@@ -108,11 +129,13 @@ pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) {
108
129
let mut phent = PHENT . load ( Relaxed ) ;
109
130
let mut phnum = PHNUM . load ( Relaxed ) ;
110
131
111
- if phdr. is_null ( ) || phnum == 0 {
112
- init_auxv ( ) ;
113
- phdr = PHDR . load ( Relaxed ) ;
114
- phent = PHENT . load ( Relaxed ) ;
115
- phnum = PHNUM . load ( Relaxed ) ;
132
+ if phdr. is_null ( ) || phent == 0 || phnum == 0 {
133
+ #[ cold]
134
+ fn compute_exe_phdrs ( ) -> ( * mut Elf_Phdr , usize , usize ) {
135
+ init_auxv ( ) ;
136
+ ( PHDR . load ( Relaxed ) , PHENT . load ( Relaxed ) , PHNUM . load ( Relaxed ) )
137
+ }
138
+ ( phdr, phent, phnum) = compute_exe_phdrs ( ) ;
116
139
}
117
140
118
141
( phdr. cast ( ) , phent, phnum)
@@ -125,8 +148,12 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr {
125
148
let mut ehdr = SYSINFO_EHDR . load ( Relaxed ) ;
126
149
127
150
if ehdr. is_null ( ) {
128
- init_auxv ( ) ;
129
- ehdr = SYSINFO_EHDR . load ( Relaxed ) ;
151
+ #[ cold]
152
+ fn compute_sysinfo_ehdr ( ) -> * mut Elf_Ehdr {
153
+ init_auxv ( ) ;
154
+ SYSINFO_EHDR . load ( Relaxed )
155
+ }
156
+ ehdr = compute_sysinfo_ehdr ( ) ;
130
157
}
131
158
132
159
ehdr
@@ -138,8 +165,12 @@ pub(crate) fn entry() -> usize {
138
165
let mut entry = ENTRY . load ( Relaxed ) ;
139
166
140
167
if entry == 0 {
141
- init_auxv ( ) ;
142
- entry = ENTRY . load ( Relaxed ) ;
168
+ #[ cold]
169
+ fn compute_entry ( ) -> usize {
170
+ init_auxv ( ) ;
171
+ ENTRY . load ( Relaxed )
172
+ }
173
+ entry = compute_entry ( ) ;
143
174
}
144
175
145
176
entry
@@ -151,13 +182,34 @@ pub(crate) fn random() -> *const [u8; 16] {
151
182
let mut random = RANDOM . load ( Relaxed ) ;
152
183
153
184
if random. is_null ( ) {
154
- init_auxv ( ) ;
155
- random = RANDOM . load ( Relaxed ) ;
185
+ #[ cold]
186
+ fn compute_random ( ) -> * mut [ u8 ; 16 ] {
187
+ init_auxv ( ) ;
188
+ RANDOM . load ( Relaxed )
189
+ }
190
+ random = compute_random ( ) ;
156
191
}
157
192
158
193
random
159
194
}
160
195
196
+ #[ cfg( target_arch = "x86" ) ]
197
+ #[ inline]
198
+ pub ( crate ) fn vsyscall ( ) -> * const c:: c_void {
199
+ let mut vsyscall = VSYSCALL . load ( Relaxed ) ;
200
+
201
+ if vsyscall. is_null ( ) {
202
+ #[ cold]
203
+ fn compute_vsyscall ( ) -> * const c:: c_void {
204
+ init_auxv ( ) ;
205
+ VSYSCALL . load ( Relaxed )
206
+ }
207
+ vsyscall = compute_vsyscall ( ) ;
208
+ }
209
+
210
+ vsyscall
211
+ }
212
+
161
213
static PAGE_SIZE : AtomicUsize = AtomicUsize :: new ( 0 ) ;
162
214
static CLOCK_TICKS_PER_SECOND : AtomicUsize = AtomicUsize :: new ( 0 ) ;
163
215
static HWCAP : AtomicUsize = AtomicUsize :: new ( 0 ) ;
@@ -176,6 +228,8 @@ static PHNUM: AtomicUsize = AtomicUsize::new(0);
176
228
static ENTRY : AtomicUsize = AtomicUsize :: new ( 0 ) ;
177
229
#[ cfg( feature = "runtime" ) ]
178
230
static RANDOM : AtomicPtr < [ u8 ; 16 ] > = AtomicPtr :: new ( null_mut ( ) ) ;
231
+ #[ cfg( feature = "x86" ) ]
232
+ static VSYSCALL : AtomicPtr < c:: c_void > = AtomicPtr :: new ( null_mut ( ) ) ;
179
233
180
234
#[ cfg( feature = "alloc" ) ]
181
235
fn pr_get_auxv ( ) -> crate :: io:: Result < Vec < u8 > > {
@@ -315,6 +369,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
315
369
let mut egid = None ;
316
370
#[ cfg( feature = "runtime" ) ]
317
371
let mut random = null_mut ( ) ;
372
+ #[ cfg( target_arch = "x86" ) ]
373
+ let mut vsyscall = null_mut ( ) ;
318
374
319
375
for Elf_auxv_t { a_type, a_val } in aux_iter {
320
376
match a_type as _ {
@@ -353,6 +409,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
353
409
AT_ENTRY => entry = a_val as usize ,
354
410
#[ cfg( feature = "runtime" ) ]
355
411
AT_RANDOM => random = check_raw_pointer :: < [ u8 ; 16 ] > ( a_val as * mut _ ) ?. as_ptr ( ) ,
412
+ #[ cfg( target_arch = "x86" ) ]
413
+ AT_SYSINFO => vsyscall = a_val. cast ( ) ,
356
414
357
415
AT_NULL => break ,
358
416
_ => ( ) ,
@@ -388,6 +446,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
388
446
ENTRY . store ( entry, Relaxed ) ;
389
447
#[ cfg( feature = "runtime" ) ]
390
448
RANDOM . store ( random, Relaxed ) ;
449
+ #[ cfg( target_arch = "x86" ) ]
450
+ VSYSCALL . store ( vsyscall, Relaxed ) ;
391
451
392
452
Some ( ( ) )
393
453
}
0 commit comments