]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
riscv: Add __riscv_hwprobe pointer to ifunc calls
authorEvan Green <evan@rivosinc.com>
Tue, 27 Feb 2024 22:56:40 +0000 (14:56 -0800)
committerPalmer Dabbelt <palmer@rivosinc.com>
Fri, 1 Mar 2024 15:14:58 +0000 (07:14 -0800)
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() 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, to account for older
glibcs that don't pass the function.

Signed-off-by: Evan Green <evan@rivosinc.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
sysdeps/riscv/dl-irel.h
sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h

index e6ab51ccd479f6db3ca0775e8c0196654c1a2577..61b3511c965c0206d927b962a90e9704a3fc1eb4 100644 (file)
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <ldsodefs.h>
 #include <sysdep.h>
+#include <sys/hwprobe.h>
 
 #define ELF_MACHINE_IRELA      1
 
@@ -31,10 +32,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), __riscv_hwprobe, NULL);
 }
 
 static inline void
index 5592b9e100caff782eaca105696eebf08e31ff81..34a2e3dbc2b1c545a2605fb67247bd9980ded568 100644 (file)
@@ -69,6 +69,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)
+     __nonnull ((1)) __wur
+     __fortified_attr_access (__read_write__, 1, 2)
+     __fortified_attr_access (__read_only__, 4, 3);
+
 __END_DECLS
 
 #endif /* sys/hwprobe.h */