[PATCH v4 3/3] aarch64: helper function to access hwcap elements in ifunc resolver
enh
enh@google.com
Fri Apr 25 13:42:46 GMT 2025
On Fri, Apr 25, 2025 at 7:35 AM Yury Khrustalev <yury.khrustalev@arm.com> wrote:
>
> Add a portable way to access HWCAP elements via the parameter(s)
> passed to an ifunc resolver checking the _IFUNC_ARG_HWCAP in the
> first parameter and size of the buffer in the second parameter.
>
> Note that 0 is return when the requested element is not available.
>
> Also add an enum for HWCAP element IDs to facilitate writing more
> readable code.
> ---
> sysdeps/aarch64/sys/ifunc.h | 25 +++++++++++++++++++++++++
> sysdeps/aarch64/tst-ifunc-arg-1.c | 12 ++++++++++++
> sysdeps/aarch64/tst-ifunc-arg-2.c | 11 +++++++++++
> 3 files changed, 48 insertions(+)
>
> diff --git a/sysdeps/aarch64/sys/ifunc.h b/sysdeps/aarch64/sys/ifunc.h
> index fd4d49f00b..d74eb560e5 100644
> --- a/sysdeps/aarch64/sys/ifunc.h
> +++ b/sysdeps/aarch64/sys/ifunc.h
> @@ -19,6 +19,8 @@
> #ifndef _SYS_IFUNC_H
> #define _SYS_IFUNC_H
>
> +#include <sys/cdefs.h>
> +
> /* A second argument is passed to the ifunc resolver. */
> #define _IFUNC_ARG_HWCAP (1ULL << 62)
>
> @@ -64,4 +66,27 @@ struct __ifunc_arg_t
>
> typedef struct __ifunc_arg_t __ifunc_arg_t;
>
> +/* ID values for the helper function below. */
> +enum
> +{
> + __IFUNC_HWCAP = 1,
> + __IFUNC_HWCAP2,
> + __IFUNC_HWCAP3,
> + __IFUNC_HWCAP4,
> +};
i get why you're adding this enum -- so you can say __IFUNC_HWCAP
rather than 1, which isn't as clear as 2 and later -- but this seems
to partly defeat the purpose of switching to the function. one of the
beauties of the function is that you never need to touch this header
again. personally i think i'd rather live with 1 than undo that?
fweimer?
> +/* A helper function to obtain HWCAP element by its ID from the
> + parameters ARG0 and ARG1 passed to the ifunc resolver. Note that
> + ID 1 corresponds to AT_HWCAP, ID 2 corresponds to AT_HWCAP2, etc.
> + If there is no element available for the requested ID then 0 is
> + returned. */
> +static __inline unsigned long __attribute__ ((unused, always_inline))
> +__ifunc_hwcap (unsigned long __id,
> + unsigned long __arg0, const unsigned long *__arg1)
> +{
> + if (__arg0 & _IFUNC_ARG_HWCAP)
> + return (__id - 1) * sizeof (unsigned long) < __arg1[0] ? __arg1[__id] : 0;
> + return __id == __IFUNC_HWCAP ? __arg0 : 0;
> +}
(lgtm)
> #endif
> diff --git a/sysdeps/aarch64/tst-ifunc-arg-1.c b/sysdeps/aarch64/tst-ifunc-arg-1.c
> index 9cc3d40c48..7868c97b08 100644
> --- a/sysdeps/aarch64/tst-ifunc-arg-1.c
> +++ b/sysdeps/aarch64/tst-ifunc-arg-1.c
> @@ -60,6 +60,18 @@ do_test (void)
> TEST_COMPARE (saved_arg2._hwcap3, getauxval (AT_HWCAP3));
> TEST_COMPARE (saved_arg2._hwcap4, getauxval (AT_HWCAP4));
>
> + const unsigned long *saved_arg2_ptr = (const unsigned long *)&saved_arg2;
> +
> + TEST_COMPARE (__ifunc_hwcap (__IFUNC_HWCAP, saved_arg1, saved_arg2_ptr),
> + getauxval (AT_HWCAP));
> + TEST_COMPARE (__ifunc_hwcap (__IFUNC_HWCAP2, saved_arg1, saved_arg2_ptr),
> + getauxval (AT_HWCAP2));
> + TEST_COMPARE (__ifunc_hwcap (__IFUNC_HWCAP3, saved_arg1, saved_arg2_ptr),
> + getauxval (AT_HWCAP3));
> + TEST_COMPARE (__ifunc_hwcap (__IFUNC_HWCAP4, saved_arg1, saved_arg2_ptr),
> + getauxval (AT_HWCAP4));
> +
> +
> return 0;
> }
>
> diff --git a/sysdeps/aarch64/tst-ifunc-arg-2.c b/sysdeps/aarch64/tst-ifunc-arg-2.c
> index d9950f0e37..ad1e16eba8 100644
> --- a/sysdeps/aarch64/tst-ifunc-arg-2.c
> +++ b/sysdeps/aarch64/tst-ifunc-arg-2.c
> @@ -63,6 +63,17 @@ do_test (void)
> TEST_COMPARE (saved_arg2._hwcap3, getauxval (AT_HWCAP3));
> TEST_COMPARE (saved_arg2._hwcap4, getauxval (AT_HWCAP4));
>
> + const unsigned long *saved_arg2_ptr = (const unsigned long *)&saved_arg2;
> +
> + TEST_COMPARE (__ifunc_hwcap (__IFUNC_HWCAP, saved_arg1, saved_arg2_ptr),
> + getauxval (AT_HWCAP));
> + TEST_COMPARE (__ifunc_hwcap (__IFUNC_HWCAP2, saved_arg1, saved_arg2_ptr),
> + getauxval (AT_HWCAP2));
> + TEST_COMPARE (__ifunc_hwcap (__IFUNC_HWCAP3, saved_arg1, saved_arg2_ptr),
> + getauxval (AT_HWCAP3));
> + TEST_COMPARE (__ifunc_hwcap (__IFUNC_HWCAP4, saved_arg1, saved_arg2_ptr),
> + getauxval (AT_HWCAP4));
> +
> return 0;
> }
>
> --
> 2.39.5
>
More information about the Libc-alpha
mailing list