This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Add ifunc memcpy and memmove for aarch64
On Wednesday 08 February 2017 04:50 AM, Steve Ellcey wrote:
> OK, here is the basic IFUNC enablement for aarch64 without the
> memcpy/memmove changes that use it. I verified that it builds and
> causes no regressions on aarch64. As mentioned in the original email
> this code depends on the mrs instruction which is privileged, but the
> 4.11 kernel will have emulation for it (https://lkml.org/lkml/2017/1/10
> /816).
>
> OK to checkin this part?
Looks OK with a couple of nits below.
>
> Steve Ellcey
> sellcey@cavium.com
>
>
> 2017-02-07 Steve Ellcey <sellcey@caviumnetworks.com>
> Adhemerval Zanella <adhemerval.zanella@linaro.org>
>
> * sysdeps/aarch64/dl-machine.h: Include cpu-features.c.
> (DL_PLATFORM_INIT): New define.
> (dl_platform_init): New function.
> * sysdeps/aarch64/ldsodefs.h: Include cpu-features.h.
> * sysdeps/unix/sysv/linux/aarch64/cpu-features.c: New file.
> * sysdeps/unix/sysv/linux/aarch64/cpu-features.h: Ditto.
> * sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c: Ditto.
> * sysdeps/unix/sysv/linux/aarch64/libc-start.c: Ditto.
I was told years ago that we prefer 'Likewise' to 'Ditto' :)
>
>
> ifunc.patch
>
>
> diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
> index 84b8aec..15d79a6 100644
> --- a/sysdeps/aarch64/dl-machine.h
> +++ b/sysdeps/aarch64/dl-machine.h
> @@ -25,6 +25,7 @@
> #include <tls.h>
> #include <dl-tlsdesc.h>
> #include <dl-irel.h>
> +#include <cpu-features.c>
>
> /* Return nonzero iff ELF header is compatible with the running host. */
> static inline int __attribute__ ((unused))
> @@ -225,6 +226,23 @@ _dl_start_user: \n\
> #define ELF_MACHINE_NO_REL 1
> #define ELF_MACHINE_NO_RELA 0
>
> +#define DL_PLATFORM_INIT dl_platform_init ()
> +
> +static inline void __attribute__ ((unused))
> +dl_platform_init (void)
> +{
> + if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
> + /* Avoid an empty string which would disturb us. */
> + GLRO(dl_platform) = NULL;
> +
> +#ifdef SHARED
> + /* init_cpu_features has been called early from __libc_start_main in
> + static executable. */
> + init_cpu_features (&GLRO(dl_aarch64_cpu_features));
> +#endif
> +}
> +
> +
> static inline ElfW(Addr)
> elf_machine_fixup_plt (struct link_map *map, lookup_t t,
> const ElfW(Rela) *reloc,
> diff --git a/sysdeps/aarch64/ldsodefs.h b/sysdeps/aarch64/ldsodefs.h
> index f277074..ba4ada3 100644
> --- a/sysdeps/aarch64/ldsodefs.h
> +++ b/sysdeps/aarch64/ldsodefs.h
> @@ -20,6 +20,7 @@
> #define _AARCH64_LDSODEFS_H 1
>
> #include <elf.h>
> +#include <cpu-features.h>
>
> struct La_aarch64_regs;
> struct La_aarch64_retval;
> diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> index e69de29..8e4b514 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> @@ -0,0 +1,38 @@
> +/* Initialize CPU feature data. AArch64 version.
> + This file is part of the GNU C Library.
> + Copyright (C) 2017 Free Software Foundation, Inc.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#include <cpu-features.h>
> +
> +#ifndef HWCAP_CPUID
> +# define HWCAP_CPUID (1 << 11)
> +#endif
> +
> +static inline void
> +init_cpu_features (struct cpu_features *cpu_features)
> +{
> + if (GLRO(dl_hwcap) & HWCAP_CPUID)
> + {
> + register uint64_t id = 0;
> + asm volatile ("mrs %0, midr_el1" : "=r"(id));
> + cpu_features->midr_el1 = id;
> + }
> + else
> + {
> + cpu_features->midr_el1 = 0;
> + }
> +}
> diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
> index e69de29..c92b650 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
> +++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
> @@ -0,0 +1,49 @@
> +/* Initialize CPU feature data. AArch64 version.
> + This file is part of the GNU C Library.
> + Copyright (C) 2017 Free Software Foundation, Inc.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#ifndef _CPU_FEATURES_AARCH64_H
> +#define _CPU_FEATURES_AARCH64_H
> +
> +#include <stdint.h>
> +
> +#define MIDR_PARTNUM_SHIFT 4
> +#define MIDR_PARTNUM_MASK (0xfff << MIDR_PARTNUM_SHIFT)
> +#define MIDR_PARTNUM(midr) \
> + (((midr) & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT)
> +#define MIDR_ARCHITECTURE_SHIFT 16
> +#define MIDR_ARCHITECTURE_MASK (0xf << MIDR_ARCHITECTURE_SHIFT)
> +#define MIDR_ARCHITECTURE(midr) \
> + (((midr) & MIDR_ARCHITECTURE_MASK) >> MIDR_ARCHITECTURE_SHIFT)
> +#define MIDR_VARIANT_SHIFT 20
> +#define MIDR_VARIANT_MASK (0xf << MIDR_VARIANT_SHIFT)
> +#define MIDR_VARIANT(midr) \
> + (((midr) & MIDR_VARIANT_MASK) >> MIDR_VARIANT_SHIFT)
> +#define MIDR_IMPLEMENTOR_SHIFT 24
> +#define MIDR_IMPLEMENTOR_MASK (0xff << MIDR_IMPLEMENTOR_SHIFT)
> +#define MIDR_IMPLEMENTOR(midr) \
> + (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
> +
> +#define IS_THUNDERX(midr) (MIDR_IMPLEMENTOR(midr) == 'C' \
> + && MIDR_PARTNUM(midr) == 0x0a1)
> +
> +struct cpu_features
> +{
> + uint64_t midr_el1;
> +};
> +
> +#endif /* _CPU_FEATURES_AARCH64_H */
> diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c b/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> index e69de29..438046a 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> @@ -0,0 +1,60 @@
> +/* Data for AArch64 version of processor capability information.
> + Linux version.
> + Copyright (C) 2017 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +/* If anything should be added here check whether the size of each string
> + is still ok with the given array size.
> +
> + All the #ifdefs in the definitions are quite irritating but
> + necessary if we want to avoid duplicating the information. There
> + are three different modes:
> +
> + - PROCINFO_DECL is defined. This means we are only interested in
> + declarations.
> +
> + - PROCINFO_DECL is not defined:
> +
> + + if SHARED is defined the file is included in an array
> + initializer. The .element = { ... } syntax is needed.
> +
> + + if SHARED is not defined a normal array initialization is
> + needed.
> + */
> +
> +#ifndef PROCINFO_CLASS
> +# define PROCINFO_CLASS
> +#endif
> +
> +#if !IS_IN (ldconfig)
> +# if !defined PROCINFO_DECL && defined SHARED
> + ._dl_aarch64_cpu_features
> +# else
> +PROCINFO_CLASS struct cpu_features _dl_aarch64_cpu_features
> +# endif
> +# ifndef PROCINFO_DECL
> += { }
> +# endif
> +# if !defined SHARED || defined PROCINFO_DECL
> +;
> +# else
> +,
> +# endif
> +#endif
> +
> +#undef PROCINFO_DECL
> +#undef PROCINFO_CLASS
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc-start.c b/sysdeps/unix/sysv/linux/aarch64/libc-start.c
> index e69de29..c98aff1 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc-start.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc-start.c
> @@ -0,0 +1,40 @@
You've forgotten to add a one line description for this file.
> +/* Copyright (C) 2017 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <http://www.gnu.org/licenses/>. */
> +
> +#ifdef SHARED
> +# include <csu/libc-start.c>
> +# else
> +/* The main work is done in the generic function. */
> +# define LIBC_START_DISABLE_INLINE
> +# define LIBC_START_MAIN generic_start_main
> +# include <csu/libc-start.c>
> +# include <cpu-features.c>
> +
> +extern struct cpu_features _dl_aarch64_cpu_features;
> +
> +int
> +__libc_start_main (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
> + int argc, char **argv,
> + __typeof (main) init,
> + void (*fini) (void),
> + void (*rtld_fini) (void), void *stack_end)
> +{
> + init_cpu_features (&_dl_aarch64_cpu_features);
> + return generic_start_main (main, argc, argv, init, fini, rtld_fini,
> + stack_end);
> +}
> +#endif
>