@@ -20,6 +20,8 @@ use core::sync::atomic::AtomicU8;
2020use core:: sync:: atomic:: Ordering :: Relaxed ;
2121use core:: sync:: atomic:: { AtomicPtr , AtomicUsize } ;
2222use linux_raw_sys:: elf:: * ;
23+ #[ cfg( target_arch = "x86" ) ]
24+ use linux_raw_sys:: general:: AT_SYSINFO ;
2325use linux_raw_sys:: general:: {
2426 AT_BASE , AT_CLKTCK , AT_EXECFN , AT_HWCAP , AT_HWCAP2 , AT_NULL , AT_PAGESZ , AT_SYSINFO_EHDR ,
2527} ;
@@ -34,8 +36,12 @@ pub(crate) fn page_size() -> usize {
3436 let mut page_size = PAGE_SIZE . load ( Relaxed ) ;
3537
3638 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 ( ) ;
3945 }
4046
4147 page_size
@@ -47,8 +53,12 @@ pub(crate) fn clock_ticks_per_second() -> u64 {
4753 let mut ticks = CLOCK_TICKS_PER_SECOND . load ( Relaxed ) ;
4854
4955 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 ( ) ;
5262 }
5363
5464 ticks as u64
@@ -61,9 +71,12 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
6171 let mut hwcap2 = HWCAP2 . load ( Relaxed ) ;
6272
6373 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 ( ) ;
6780 }
6881
6982 ( hwcap, hwcap2)
@@ -75,8 +88,12 @@ pub(crate) fn linux_execfn() -> &'static CStr {
7588 let mut execfn = EXECFN . load ( Relaxed ) ;
7689
7790 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 ( ) ;
8097 }
8198
8299 // SAFETY: We assume the `AT_EXECFN` value provided by the kernel is a
@@ -91,8 +108,12 @@ pub(crate) fn linux_secure() -> bool {
91108
92109 // 0 means not initialized yet.
93110 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 ( ) ;
96117 }
97118
98119 // 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) {
108129 let mut phent = PHENT . load ( Relaxed ) ;
109130 let mut phnum = PHNUM . load ( Relaxed ) ;
110131
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 ( ) ;
116139 }
117140
118141 ( phdr. cast ( ) , phent, phnum)
@@ -125,8 +148,12 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr {
125148 let mut ehdr = SYSINFO_EHDR . load ( Relaxed ) ;
126149
127150 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 ( ) ;
130157 }
131158
132159 ehdr
@@ -138,8 +165,12 @@ pub(crate) fn entry() -> usize {
138165 let mut entry = ENTRY . load ( Relaxed ) ;
139166
140167 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 ( ) ;
143174 }
144175
145176 entry
@@ -151,13 +182,34 @@ pub(crate) fn random() -> *const [u8; 16] {
151182 let mut random = RANDOM . load ( Relaxed ) ;
152183
153184 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 ( ) ;
156191 }
157192
158193 random
159194}
160195
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+
161213static PAGE_SIZE : AtomicUsize = AtomicUsize :: new ( 0 ) ;
162214static CLOCK_TICKS_PER_SECOND : AtomicUsize = AtomicUsize :: new ( 0 ) ;
163215static HWCAP : AtomicUsize = AtomicUsize :: new ( 0 ) ;
@@ -176,6 +228,8 @@ static PHNUM: AtomicUsize = AtomicUsize::new(0);
176228static ENTRY : AtomicUsize = AtomicUsize :: new ( 0 ) ;
177229#[ cfg( feature = "runtime" ) ]
178230static RANDOM : AtomicPtr < [ u8 ; 16 ] > = AtomicPtr :: new ( null_mut ( ) ) ;
231+ #[ cfg( feature = "x86" ) ]
232+ static VSYSCALL : AtomicPtr < c:: c_void > = AtomicPtr :: new ( null_mut ( ) ) ;
179233
180234#[ cfg( feature = "alloc" ) ]
181235fn 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
315369 let mut egid = None ;
316370 #[ cfg( feature = "runtime" ) ]
317371 let mut random = null_mut ( ) ;
372+ #[ cfg( target_arch = "x86" ) ]
373+ let mut vsyscall = null_mut ( ) ;
318374
319375 for Elf_auxv_t { a_type, a_val } in aux_iter {
320376 match a_type as _ {
@@ -353,6 +409,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
353409 AT_ENTRY => entry = a_val as usize ,
354410 #[ cfg( feature = "runtime" ) ]
355411 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 ( ) ,
356414
357415 AT_NULL => break ,
358416 _ => ( ) ,
@@ -388,6 +446,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
388446 ENTRY . store ( entry, Relaxed ) ;
389447 #[ cfg( feature = "runtime" ) ]
390448 RANDOM . store ( random, Relaxed ) ;
449+ #[ cfg( target_arch = "x86" ) ]
450+ VSYSCALL . store ( vsyscall, Relaxed ) ;
391451
392452 Some ( ( ) )
393453}
0 commit comments