Skip to content

Commit 631ba24

Browse files
committed
Fix VDSO clock_gettime detection on older Linux versions.
On arm, use the `64`-suffixed symbol so that the optimized path only uses the y2038-safe version. On risc-v, use the symbol name from the actual kernel code. And on arm and x86, handle the case where the y2038-safe symbol is not present.
1 parent 0f918b8 commit 631ba24

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

src/imp/linux_raw/vdso_wrappers.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -355,24 +355,41 @@ fn init() {
355355
minimal_init();
356356

357357
if let Some(vdso) = vdso::Vdso::new() {
358+
// Look up the platform-specific `clock_gettime` symbol as documented
359+
// [here], except on 32-bit platforms where we look up the
360+
// `64`-suffixed variant and fail if we don't find it.
361+
//
362+
// [here]: https://man7.org/linux/man-pages/man7/vdso.7.html
358363
#[cfg(target_arch = "x86_64")]
359364
let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime"));
360365
#[cfg(target_arch = "arm")]
361-
let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime"));
366+
let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime64"));
362367
#[cfg(target_arch = "aarch64")]
363368
let ptr = vdso.sym(zstr!("LINUX_2.6.39"), zstr!("__kernel_clock_gettime"));
364369
#[cfg(target_arch = "x86")]
365370
let ptr = vdso.sym(zstr!("LINUX_2.6"), zstr!("__vdso_clock_gettime64"));
366371
#[cfg(target_arch = "riscv64")]
367-
let ptr = vdso.sym(zstr!("LINUX_4.15"), zstr!("__kernel_clock_gettime"));
372+
let ptr = vdso.sym(zstr!("LINUX_4.15"), zstr!("__vdso_clock_gettime"));
368373

369-
assert!(!ptr.is_null());
374+
// On all 64-bit platforms, the 64-bit `clock_gettime` symbols are
375+
// always available.
376+
#[cfg(any(target_pointer_width = "64"))]
377+
let ok = true;
370378

371-
// Safety: Store the computed function addresses in static storage
372-
// so that we don't need to compute it again (but if we do, it doesn't
373-
// hurt anything).
374-
unsafe {
375-
CLOCK_GETTIME.store(ptr as usize, Relaxed);
379+
// On some 32-bit platforms, the 64-bit `clock_gettime` symbols are not
380+
// available on older kernel versions.
381+
#[cfg(any(target_arch = "arm", target_arch = "x86"))]
382+
let ok = !ptr.is_null();
383+
384+
if ok {
385+
assert!(!ptr.is_null());
386+
387+
// Safety: Store the computed function addresses in static storage
388+
// so that we don't need to compute it again (but if we do, it doesn't
389+
// hurt anything).
390+
unsafe {
391+
CLOCK_GETTIME.store(ptr as usize, Relaxed);
392+
}
376393
}
377394

378395
// On x86, also look up the vsyscall entry point.

0 commit comments

Comments
 (0)