Merge "riscv64: use vdso for __riscv_hwprobe()." into main
This commit is contained in:
commit
2df6e5fa8f
4 changed files with 49 additions and 23 deletions
|
@ -357,7 +357,7 @@ int cacheflush:__ARM_NR_cacheflush(long start, long end, long flags) arm
|
|||
|
||||
# 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
|
||||
|
|
|
@ -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 @@ int gettimeofday(timeval* tv, struct timezone* tz) {
|
|||
}
|
||||
|
||||
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 @@ time_t time(time_t* t) {
|
|||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#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
|
||||
|
||||
extern "C" int __clock_gettime(int, timespec*);
|
||||
extern "C" int __clock_getres(int, timespec*);
|
||||
extern "C" int __gettimeofday(timeval*, struct timezone*);
|
||||
|
||||
struct vdso_entry {
|
||||
const char* name;
|
||||
|
@ -56,8 +53,11 @@ enum {
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue