@@ -31,10 +31,10 @@ static inline ElfW(Addr)
__attribute ((always_inline))
elf_ifunc_invoke (ElfW(Addr) addr)
{
- /* The second argument is a void pointer to preserve the extension
- fexibility. */
- return ((ElfW(Addr) (*) (uint64_t, void *)) (addr))
- (GLRO(dl_hwcap), NULL);
+ /* The third argument is a void pointer to preserve the extension
+ flexibility. */
+ return ((ElfW(Addr) (*) (uint64_t, void *, void *)) (addr))
+ (GLRO(dl_hwcap), GLRO(dl_vdso_riscv_hwprobe), NULL);
}
static inline void
@@ -67,6 +67,16 @@ extern int __riscv_hwprobe (struct riscv_hwprobe *__pairs, size_t __pair_count,
__fortified_attr_access (__read_write__, 1, 2)
__fortified_attr_access (__read_only__, 4, 3);
+/* A pointer to the __riscv_hwprobe vDSO function is passed as the second
+ argument to ifunc selector routines. Include a function pointer type for
+ convenience in calling the function in those settings. */
+typedef int (*__riscv_hwprobe_t) (struct riscv_hwprobe *__pairs, size_t __pair_count,
+ size_t __cpu_count, unsigned long int *__cpus,
+ unsigned int __flags)
+ __THROW __nonnull ((1)) __wur
+ __fortified_attr_access (__read_write__, 1, 2)
+ __fortified_attr_access (__read_only__, 4, 3);
+
__END_DECLS
#endif /* sys/hwprobe.h */
The new __riscv_hwprobe() function is designed to be used by ifunc selector functions. This presents a challenge for applications and libraries, as ifunc selectors are invoked before all relocations have been performed, so an external call to __riscv_hwprobe() from an ifunc selector won't work. To address this, pass a pointer to the __riscv_hwprobe() vDSO function into ifunc selectors as the second argument (alongside dl_hwcap, which was already being passed). Include a typedef as well for convenience, so that ifunc users don't have to go through contortions to call this routine. Users will need to remember to check the second argument for NULL, both to account for older glibcs that don't pass the function, and older kernels that don't have the vDSO pointer. Signed-off-by: Evan Green <evan@rivosinc.com> --- (no changes since v1) sysdeps/riscv/dl-irel.h | 8 ++++---- sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-)