riscv64: use vdso for __riscv_hwprobe().
Also de-pessimize time(), where the vdso entrypoint only exists on
x86/x86-64 anyway.
Bug: https://github.com/google/android-riscv64/issues/8
Test: strace
Change-Id: I14cb2a3130b6ff88d06d43ea13d3a825a26de290
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 079acf9..f4f9e1b 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -357,7 +357,7 @@
# riscv64-specific
int __riscv_flush_icache:riscv_flush_icache(void*, void*, unsigned long) riscv64
-int __riscv_hwprobe:riscv_hwprobe(riscv_hwprobe*, size_t, size_t, unsigned long*, unsigned) riscv64
+int riscv_hwprobe(riscv_hwprobe*, size_t, size_t, unsigned long*, unsigned) riscv64
# x86-specific
int __set_thread_area:set_thread_area(void*) x86
diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp
index dbca9c0..e834ec7 100644
--- a/libc/bionic/vdso.cpp
+++ b/libc/bionic/vdso.cpp
@@ -22,10 +22,16 @@
#include <string.h>
#include <sys/auxv.h>
#include <sys/cdefs.h>
+#include <sys/hwprobe.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
+extern "C" int __clock_gettime(int, struct timespec*);
+extern "C" int __clock_getres(int, struct timespec*);
+extern "C" int __gettimeofday(struct timeval*, struct timezone*);
+extern "C" int riscv_hwprobe(struct riscv_hwprobe*, size_t, size_t, unsigned long*, unsigned);
+
static inline int vdso_return(int result) {
if (__predict_true(result == 0)) return 0;
@@ -61,10 +67,13 @@
}
time_t time(time_t* t) {
+ // Only x86/x86-64 actually have time() in the vdso.
+#if defined(VDSO_TIME_SYMBOL)
auto vdso_time = reinterpret_cast<decltype(&time)>(__libc_globals->vdso[VDSO_TIME].fn);
if (__predict_true(vdso_time)) {
return vdso_time(t);
}
+#endif
// We can't fallback to the time(2) system call because it doesn't exist for most architectures.
timeval tv;
@@ -73,12 +82,29 @@
return tv.tv_sec;
}
+#if defined(__riscv)
+int __riscv_hwprobe(struct riscv_hwprobe* _Nonnull pairs, size_t pair_count, size_t cpu_count,
+ unsigned long* _Nullable cpus, unsigned flags) {
+ auto vdso_riscv_hwprobe =
+ reinterpret_cast<decltype(&__riscv_hwprobe)>(__libc_globals->vdso[VDSO_RISCV_HWPROBE].fn);
+ if (__predict_true(vdso_riscv_hwprobe)) {
+ return vdso_return(vdso_riscv_hwprobe(pairs, pair_count, cpu_count, cpus, flags));
+ }
+ return riscv_hwprobe(pairs, pair_count, cpu_count, cpus, flags);
+}
+#endif
+
void __libc_init_vdso(libc_globals* globals) {
auto&& vdso = globals->vdso;
- vdso[VDSO_CLOCK_GETTIME] = { VDSO_CLOCK_GETTIME_SYMBOL, nullptr };
- vdso[VDSO_CLOCK_GETRES] = { VDSO_CLOCK_GETRES_SYMBOL, nullptr };
- vdso[VDSO_GETTIMEOFDAY] = { VDSO_GETTIMEOFDAY_SYMBOL, nullptr };
- vdso[VDSO_TIME] = { VDSO_TIME_SYMBOL, nullptr };
+ vdso[VDSO_CLOCK_GETTIME] = {VDSO_CLOCK_GETTIME_SYMBOL, nullptr};
+ vdso[VDSO_CLOCK_GETRES] = {VDSO_CLOCK_GETRES_SYMBOL, nullptr};
+ vdso[VDSO_GETTIMEOFDAY] = {VDSO_GETTIMEOFDAY_SYMBOL, nullptr};
+#if defined(VDSO_TIME_SYMBOL)
+ vdso[VDSO_TIME] = {VDSO_TIME_SYMBOL, nullptr};
+#endif
+#if defined(VDSO_RISCV_HWPROBE_SYMBOL)
+ vdso[VDSO_RISCV_HWPROBE] = {VDSO_RISCV_HWPROBE_SYMBOL, nullptr};
+#endif
// Do we have a vdso?
uintptr_t vdso_ehdr_addr = getauxval(AT_SYSINFO_EHDR);
diff --git a/libc/private/bionic_asm_offsets.h b/libc/private/bionic_asm_offsets.h
index c2f2b56..e72adda 100644
--- a/libc/private/bionic_asm_offsets.h
+++ b/libc/private/bionic_asm_offsets.h
@@ -28,6 +28,6 @@
#pragma once
-#ifdef __aarch64__
-#define OFFSETOF_libc_globals_memtag_stack 80
+#if defined(__aarch64__)
+#define OFFSETOF_libc_globals_memtag_stack 64
#endif
diff --git a/libc/private/bionic_vdso.h b/libc/private/bionic_vdso.h
index da19b29..406b064 100644
--- a/libc/private/bionic_vdso.h
+++ b/libc/private/bionic_vdso.h
@@ -26,26 +26,23 @@
* SUCH DAMAGE.
*/
-#ifndef _PRIVATE_BIONIC_VDSO_H
-#define _PRIVATE_BIONIC_VDSO_H
-
-#include <time.h>
+#pragma once
#if defined(__aarch64__)
#define VDSO_CLOCK_GETTIME_SYMBOL "__kernel_clock_gettime"
-#define VDSO_CLOCK_GETRES_SYMBOL "__kernel_clock_getres"
-#define VDSO_GETTIMEOFDAY_SYMBOL "__kernel_gettimeofday"
-#define VDSO_TIME_SYMBOL "__kernel_time"
+#define VDSO_CLOCK_GETRES_SYMBOL "__kernel_clock_getres"
+#define VDSO_GETTIMEOFDAY_SYMBOL "__kernel_gettimeofday"
#else
#define VDSO_CLOCK_GETTIME_SYMBOL "__vdso_clock_gettime"
-#define VDSO_CLOCK_GETRES_SYMBOL "__vdso_clock_getres"
-#define VDSO_GETTIMEOFDAY_SYMBOL "__vdso_gettimeofday"
-#define VDSO_TIME_SYMBOL "__vdso_time"
+#define VDSO_CLOCK_GETRES_SYMBOL "__vdso_clock_getres"
+#define VDSO_GETTIMEOFDAY_SYMBOL "__vdso_gettimeofday"
#endif
-
-extern "C" int __clock_gettime(int, timespec*);
-extern "C" int __clock_getres(int, timespec*);
-extern "C" int __gettimeofday(timeval*, struct timezone*);
+#if defined(__riscv)
+#define VDSO_RISCV_HWPROBE_SYMBOL "__vdso_riscv_hwprobe"
+#endif
+#if defined(__i386__) || defined(__x86_64__)
+#define VDSO_TIME_SYMBOL "__vdso_time"
+#endif
struct vdso_entry {
const char* name;
@@ -56,8 +53,11 @@
VDSO_CLOCK_GETTIME = 0,
VDSO_CLOCK_GETRES,
VDSO_GETTIMEOFDAY,
+#if defined(VDSO_TIME_SYMBOL)
VDSO_TIME,
+#endif
+#if defined(VDSO_RISCV_HWPROBE_SYMBOL)
+ VDSO_RISCV_HWPROBE,
+#endif
VDSO_END
};
-
-#endif // _PRIVATE_BIONIC_VDSO_H