@@ -21,6 +21,8 @@ use core::sync::atomic::AtomicU8;
2121use core:: sync:: atomic:: Ordering :: Relaxed ;
2222use core:: sync:: atomic:: { AtomicPtr , AtomicUsize } ;
2323use linux_raw_sys:: elf:: * ;
24+ #[ cfg( target_arch = "x86" ) ]
25+ use linux_raw_sys:: general:: AT_SYSINFO ;
2426use linux_raw_sys:: general:: {
2527 AT_BASE , AT_CLKTCK , AT_EXECFN , AT_HWCAP , AT_HWCAP2 , AT_MINSIGSTKSZ , AT_NULL , AT_PAGESZ ,
2628 AT_SYSINFO_EHDR ,
@@ -38,8 +40,12 @@ pub(crate) fn page_size() -> usize {
3840 let mut page_size = PAGE_SIZE . load ( Relaxed ) ;
3941
4042 if page_size == 0 {
41- init_auxv ( ) ;
42- page_size = PAGE_SIZE . load ( Relaxed ) ;
43+ #[ cold]
44+ fn compute_page_size ( ) -> usize {
45+ init_auxv ( ) ;
46+ PAGE_SIZE . load ( Relaxed )
47+ }
48+ page_size = compute_page_size ( ) ;
4349 }
4450
4551 page_size
@@ -51,8 +57,12 @@ pub(crate) fn clock_ticks_per_second() -> u64 {
5157 let mut ticks = CLOCK_TICKS_PER_SECOND . load ( Relaxed ) ;
5258
5359 if ticks == 0 {
54- init_auxv ( ) ;
55- ticks = CLOCK_TICKS_PER_SECOND . load ( Relaxed ) ;
60+ #[ cold]
61+ fn compute_clock_ticks_per_second ( ) -> usize {
62+ init_auxv ( ) ;
63+ CLOCK_TICKS_PER_SECOND . load ( Relaxed )
64+ }
65+ ticks = compute_clock_ticks_per_second ( ) ;
5666 }
5767
5868 ticks as u64
@@ -65,9 +75,12 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
6575 let mut hwcap2 = HWCAP2 . load ( Relaxed ) ;
6676
6777 if hwcap == 0 || hwcap2 == 0 {
68- init_auxv ( ) ;
69- hwcap = HWCAP . load ( Relaxed ) ;
70- hwcap2 = HWCAP2 . load ( Relaxed ) ;
78+ #[ cold]
79+ fn compute_linux_hwcap ( ) -> ( usize , usize ) {
80+ init_auxv ( ) ;
81+ ( HWCAP . load ( Relaxed ) , HWCAP2 . load ( Relaxed ) )
82+ }
83+ ( hwcap, hwcap2) = compute_linux_hwcap ( ) ;
7184 }
7285
7386 ( hwcap, hwcap2)
@@ -92,8 +105,12 @@ pub(crate) fn linux_execfn() -> &'static CStr {
92105 let mut execfn = EXECFN . load ( Relaxed ) ;
93106
94107 if execfn. is_null ( ) {
95- init_auxv ( ) ;
96- execfn = EXECFN . load ( Relaxed ) ;
108+ #[ cold]
109+ fn compute_linux_execfn ( ) -> * mut c:: c_char {
110+ init_auxv ( ) ;
111+ EXECFN . load ( Relaxed )
112+ }
113+ execfn = compute_linux_execfn ( ) ;
97114 }
98115
99116 // SAFETY: We assume the `AT_EXECFN` value provided by the kernel is a
@@ -108,8 +125,12 @@ pub(crate) fn linux_secure() -> bool {
108125
109126 // 0 means not initialized yet.
110127 if secure == 0 {
111- init_auxv ( ) ;
112- secure = SECURE . load ( Relaxed ) ;
128+ #[ cold]
129+ fn compute_linux_secure ( ) -> u8 {
130+ init_auxv ( ) ;
131+ SECURE . load ( Relaxed )
132+ }
133+ secure = compute_linux_secure ( ) ;
113134 }
114135
115136 // 0 means not present. Libc `getauxval(AT_SECURE)` would return 0.
@@ -125,11 +146,13 @@ pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) {
125146 let mut phent = PHENT . load ( Relaxed ) ;
126147 let mut phnum = PHNUM . load ( Relaxed ) ;
127148
128- if phdr. is_null ( ) || phnum == 0 {
129- init_auxv ( ) ;
130- phdr = PHDR . load ( Relaxed ) ;
131- phent = PHENT . load ( Relaxed ) ;
132- phnum = PHNUM . load ( Relaxed ) ;
149+ if phdr. is_null ( ) || phent == 0 || phnum == 0 {
150+ #[ cold]
151+ fn compute_exe_phdrs ( ) -> ( * mut Elf_Phdr , usize , usize ) {
152+ init_auxv ( ) ;
153+ ( PHDR . load ( Relaxed ) , PHENT . load ( Relaxed ) , PHNUM . load ( Relaxed ) )
154+ }
155+ ( phdr, phent, phnum) = compute_exe_phdrs ( ) ;
133156 }
134157
135158 ( phdr. cast ( ) , phent, phnum)
@@ -145,12 +168,16 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr {
145168 let mut ehdr = SYSINFO_EHDR . load ( Relaxed ) ;
146169
147170 if ehdr. is_null ( ) {
148- // Use `maybe_init_auxv` to to read the aux vectors if it can, but do
149- // nothing if it can't. If it can't, then we'll get a null pointer
150- // here, which our callers are prepared to deal with.
151- maybe_init_auxv ( ) ;
171+ #[ cold]
172+ fn compute_sysinfo_ehdr ( ) -> * mut Elf_Ehdr {
173+ // Use `maybe_init_auxv` to to read the aux vectors if it can, but do
174+ // nothing if it can't. If it can't, then we'll get a null pointer
175+ // here, which our callers are prepared to deal with.
176+ maybe_init_auxv ( ) ;
177+ SYSINFO_EHDR . load ( Relaxed )
178+ }
152179
153- ehdr = SYSINFO_EHDR . load ( Relaxed ) ;
180+ ehdr = compute_sysinfo_ehdr ( ) ;
154181 }
155182
156183 ehdr
@@ -162,8 +189,12 @@ pub(crate) fn entry() -> usize {
162189 let mut entry = ENTRY . load ( Relaxed ) ;
163190
164191 if entry == 0 {
165- init_auxv ( ) ;
166- entry = ENTRY . load ( Relaxed ) ;
192+ #[ cold]
193+ fn compute_entry ( ) -> usize {
194+ init_auxv ( ) ;
195+ ENTRY . load ( Relaxed )
196+ }
197+ entry = compute_entry ( ) ;
167198 }
168199
169200 entry
@@ -175,13 +206,34 @@ pub(crate) fn random() -> *const [u8; 16] {
175206 let mut random = RANDOM . load ( Relaxed ) ;
176207
177208 if random. is_null ( ) {
178- init_auxv ( ) ;
179- random = RANDOM . load ( Relaxed ) ;
209+ #[ cold]
210+ fn compute_random ( ) -> * mut [ u8 ; 16 ] {
211+ init_auxv ( ) ;
212+ RANDOM . load ( Relaxed )
213+ }
214+ random = compute_random ( ) ;
180215 }
181216
182217 random
183218}
184219
220+ #[ cfg( target_arch = "x86" ) ]
221+ #[ inline]
222+ pub ( crate ) fn vsyscall ( ) -> * const c:: c_void {
223+ let mut vsyscall = VSYSCALL . load ( Relaxed ) ;
224+
225+ if vsyscall. is_null ( ) {
226+ #[ cold]
227+ fn compute_vsyscall ( ) -> * const c:: c_void {
228+ init_auxv ( ) ;
229+ VSYSCALL . load ( Relaxed )
230+ }
231+ vsyscall = compute_vsyscall ( ) ;
232+ }
233+
234+ vsyscall
235+ }
236+
185237static PAGE_SIZE : AtomicUsize = AtomicUsize :: new ( 0 ) ;
186238static CLOCK_TICKS_PER_SECOND : AtomicUsize = AtomicUsize :: new ( 0 ) ;
187239static HWCAP : AtomicUsize = AtomicUsize :: new ( 0 ) ;
@@ -201,6 +253,8 @@ static PHNUM: AtomicUsize = AtomicUsize::new(0);
201253static ENTRY : AtomicUsize = AtomicUsize :: new ( 0 ) ;
202254#[ cfg( feature = "runtime" ) ]
203255static RANDOM : AtomicPtr < [ u8 ; 16 ] > = AtomicPtr :: new ( null_mut ( ) ) ;
256+ #[ cfg( feature = "x86" ) ]
257+ static VSYSCALL : AtomicPtr < c:: c_void > = AtomicPtr :: new ( null_mut ( ) ) ;
204258
205259const PR_GET_AUXV : c:: c_int = 0x4155_5856 ;
206260
@@ -389,6 +443,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
389443 let mut egid = None ;
390444 #[ cfg( feature = "runtime" ) ]
391445 let mut random = null_mut ( ) ;
446+ #[ cfg( target_arch = "x86" ) ]
447+ let mut vsyscall = null_mut ( ) ;
392448
393449 for Elf_auxv_t { a_type, a_val } in aux_iter {
394450 match a_type as _ {
@@ -428,6 +484,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
428484 AT_ENTRY => entry = a_val as usize ,
429485 #[ cfg( feature = "runtime" ) ]
430486 AT_RANDOM => random = check_raw_pointer :: < [ u8 ; 16 ] > ( a_val as * mut _ ) ?. as_ptr ( ) ,
487+ #[ cfg( target_arch = "x86" ) ]
488+ AT_SYSINFO => vsyscall = a_val. cast ( ) ,
431489
432490 AT_NULL => break ,
433491 _ => ( ) ,
@@ -464,6 +522,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
464522 ENTRY . store ( entry, Relaxed ) ;
465523 #[ cfg( feature = "runtime" ) ]
466524 RANDOM . store ( random, Relaxed ) ;
525+ #[ cfg( target_arch = "x86" ) ]
526+ VSYSCALL . store ( vsyscall, Relaxed ) ;
467527
468528 Some ( ( ) )
469529}
0 commit comments