Tests which currently use the vDSO find it using getauxval(). However, in purecap, the pointer to the vDSO in the auxiliary vector is a capability and therefore cannot be returned as an unsigned long. Replace getauxval() with getauxptr() when building for purecap to solve this issue.
This patch replicates changes made to the Morello kernel vDSO selftests to enable testing in purecap. See Morello/Linux/Kernel: ("Add support for purecap vDSO testing").
Signed-off-by: Aditya Deshpande aditya.deshpande@arm.com --- include/parse_vdso.h | 20 ++++++++++++++++++++ libs/libltpvdso/vdso_helpers.c | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/include/parse_vdso.h b/include/parse_vdso.h index 5212fc659..643c773da 100644 --- a/include/parse_vdso.h +++ b/include/parse_vdso.h @@ -9,6 +9,10 @@
#include <stdint.h>
+#ifdef HAVE_GETAUXVAL +# include <sys/auxv.h> +#endif /* HAVE_GETAUXVAL */ + /* * To use this vDSO parser, first call one of the vdso_init_* functions. * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR @@ -38,4 +42,20 @@ extern void *vdso_sym(const char *version, const char *name); typedef int (*gettime_t)(clockid_t clk_id, void *ts); void find_clock_gettime_vdso(gettime_t *ptr_vdso_gettime, gettime_t *ptr_vdso_gettime64); + +/* + * Under PCuABI, pointers in the auxiliary vector can no longer be represented + * as unsigned long as they are now capabilities. Get the capability to the + * vDSO using getauxptr() instead, which returns a a capability instead of + * unsigned long. + */ +static inline uintptr_t get_sysinfo_ehdr() +{ +#ifdef __CHERI_PURE_CAPABILITY__ + return (uintptr_t)getauxptr(AT_SYSINFO_EHDR); +#else + return getauxval(AT_SYSINFO_EHDR); +#endif +} + #endif /* PARSE_VDSO_H__ */ diff --git a/libs/libltpvdso/vdso_helpers.c b/libs/libltpvdso/vdso_helpers.c index 208c12f65..cb5e01687 100644 --- a/libs/libltpvdso/vdso_helpers.c +++ b/libs/libltpvdso/vdso_helpers.c @@ -14,7 +14,7 @@ # include <sys/auxv.h> #endif /* HAVE_GETAUXVAL */
-static unsigned long sysinfo_ehdr; +static uintptr_t sysinfo_ehdr;
static void vdso_init(void) { @@ -22,7 +22,7 @@ static void vdso_init(void) if (sysinfo_ehdr) return;
- sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR); + sysinfo_ehdr = get_sysinfo_ehdr(); if (!sysinfo_ehdr) { tst_res(TINFO, "Couldn't find AT_SYSINFO_EHDR"); return;