[PATCH v7 20/23] aarch64: Process gnu properties in static exe
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Thu Jan 9 18:01:37 GMT 2025
On 03/01/25 12:41, Yury Khrustalev wrote:
> From: Szabolcs Nagy <szabolcs.nagy@arm.com>
>
> Unlike for BTI, the kernel does not process GCS properties so update
> GL(dl_aarch64_gcs) before the GCS status is set.
>
> Co-authored-by: Yury Khrustalev <yury.khrustalev@arm.com>
> ---
> csu/libc-start.c | 12 ++++++++++++
> sysdeps/generic/libc-start.h | 1 +
> sysdeps/unix/sysv/linux/aarch64/libc-start.h | 19 +++++++++++++++++++
> 3 files changed, 32 insertions(+)
>
> diff --git a/csu/libc-start.c b/csu/libc-start.c
> index 6f3d52e223..325ef010d4 100644
> --- a/csu/libc-start.c
> +++ b/csu/libc-start.c
> @@ -206,6 +206,10 @@ call_fini (void *unused)
>
> #include <libc-start.h>
>
> +#ifndef ARCH_PROCESS_NOTES
> +# define ARCH_PROCESS_NOTES()
> +#endif
> +
I think it would be better to avoid the old way of defining arch-hooks,
since they are error-prone. For instance, although is not the case
(since the function is currently empty) if/when we need to add generic
__libc_process_notes code, just adding on the function below will not
be suffice for x86_64/powerpc because they have its own libc-start.h
(and this patch did not add an ARCH_PROCESS_NOTES for such ABIs).
Instead, the usual way is to either use the generic definitions
on sysdeps/generic or add a new one. For this case, I think it would
be better to add new a file with the notes processing function instead
of reuse the dl-prop.h.
I plan to use it to add the generic memory seal support, which requires
PT_GNU_PROPERTY for all ABIs, without the need to replicate the same
code on x86_64 (in fact, I can move the aarch64 definitions on generic
code and remove aarch64 libc-prop.h).
Something like this diff over your patch:
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 325ef010d4..f19a996bb2 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -36,7 +36,7 @@
#include <stdbool.h>
#include <elf-initfini.h>
#include <shlib-compat.h>
-
+#include <libc-prop.h>
#include <elf/dl-tunables.h>
extern void __libc_init_first (int argc, char **argv, char **envp);
@@ -206,10 +206,6 @@ call_fini (void *unused)
#include <libc-start.h>
-#ifndef ARCH_PROCESS_NOTES
-# define ARCH_PROCESS_NOTES()
-#endif
-
STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
MAIN_AUXVEC_DECL),
int argc,
@@ -223,11 +219,6 @@ STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
void *stack_end)
__attribute__ ((noreturn));
-void
-__libc_process_notes (void)
-{
-
-}
/* Note: The init and fini parameters are no longer used. fini is
completely unused, init is still called if not NULL, but the
@@ -286,7 +277,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
ARCH_SETUP_IREL ();
/* Process notes: PT_NOTE / PT_GNU_PROPERTY. */
- ARCH_PROCESS_NOTES ();
+ __libc_process_gnu_attributes ();
/* The stack guard goes into the TCB, so initialize it early. */
ARCH_SETUP_TLS ();
diff --git a/sysdeps/aarch64/libc-prop.h b/sysdeps/aarch64/libc-prop.h
new file mode 100644
index 0000000000..478c21f669
--- /dev/null
+++ b/sysdeps/aarch64/libc-prop.h
@@ -0,0 +1,44 @@
+/* Support for GNU properties for static builds. AArch64 version.
+ Copyright (C) 2025 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_PROP_H
+#define _LIBC_PROP_H
+
+#include <dl-prop.h>
+
+/* Called at the start of program execution to handle GNU attribute from
+ PT_NOTE / PT_GNU_PROPERTY. Must be on a top-level stack frame that does
+ not return. */
+static __always_inline void
+__libc_process_gnu_attributes (void)
+{
+# ifndef SHARED
+ struct link_map *main_map = _dl_get_dl_main_map ();
+ const ElfW(Phdr) *phdr = GL(dl_phdr);
+ const ElfW(Phdr) *ph;
+ for (ph = phdr; ph < phdr + GL(dl_phnum); ph++)
+ if (ph->p_type == PT_GNU_PROPERTY)
+ {
+ _dl_process_pt_gnu_property (main_map, -1, ph);
+ _rtld_main_check (main_map, _dl_argv[0]);
+ break;
+ }
+# endif
+}
+
+#endif
diff --git a/sysdeps/generic/libc-prop.h b/sysdeps/generic/libc-prop.h
new file mode 100644
index 0000000000..22510a1972
--- /dev/null
+++ b/sysdeps/generic/libc-prop.h
@@ -0,0 +1,29 @@
+/* Support for GNU properties for static builds. Generic version.
+ Copyright (C) 2025 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_PROP_H
+#define _LIBC_PROP_H
+
+/* Called at the start of program executation to handle GNU attribute
+ from PT_NOTE / PT_GNU_PROPERTY. */
+static __always_inline void
+__libc_process_gnu_attributes (void)
+{
+}
+
+#endif
diff --git a/sysdeps/generic/libc-start.h b/sysdeps/generic/libc-start.h
index 1a421626b5..0b107cf2a1 100644
--- a/sysdeps/generic/libc-start.h
+++ b/sysdeps/generic/libc-start.h
@@ -24,7 +24,6 @@
initialization, and this means you cannot, without machine
knowledge, access TLS from an IFUNC resolver. */
#define ARCH_SETUP_IREL() apply_irel ()
-#define ARCH_PROCESS_NOTES() __libc_process_notes ()
#define ARCH_SETUP_TLS() __libc_setup_tls ()
#define ARCH_APPLY_IREL()
#endif /* ! SHARED */
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc-start.h b/sysdeps/unix/sysv/linux/aarch64/libc-start.h
index 0f80a8abe9..735076c086 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc-start.h
+++ b/sysdeps/unix/sysv/linux/aarch64/libc-start.h
@@ -21,24 +21,6 @@
#ifndef SHARED
-# include <dl-prop.h>
-
-/* Must be on a top-level stack frame that does not return. */
-static inline void __attribute__((always_inline))
-aarch64_libc_process_notes (void)
-{
- struct link_map *main_map = _dl_get_dl_main_map ();
- const ElfW(Phdr) *phdr = GL(dl_phdr);
- const ElfW(Phdr) *ph;
- for (ph = phdr; ph < phdr + GL(dl_phnum); ph++)
- if (ph->p_type == PT_GNU_PROPERTY)
- {
- _dl_process_pt_gnu_property (main_map, -1, ph);
- _rtld_main_check (main_map, _dl_argv[0]);
- break;
- }
-}
-
# ifndef PR_SET_SHADOW_STACK_STATUS
# define PR_SET_SHADOW_STACK_STATUS 75
# define PR_SHADOW_STACK_ENABLE (1UL << 0)
@@ -57,7 +39,6 @@ aarch64_libc_setup_tls (void)
}
# define ARCH_SETUP_IREL() apply_irel ()
-# define ARCH_PROCESS_NOTES() aarch64_libc_process_notes ()
# define ARCH_SETUP_TLS() aarch64_libc_setup_tls ()
# define ARCH_APPLY_IREL()
#endif /* ! SHARED */
> STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
> MAIN_AUXVEC_DECL),
> int argc,
> @@ -219,6 +223,11 @@ STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
> void *stack_end)
> __attribute__ ((noreturn));
>
> +void
> +__libc_process_notes (void)
> +{
> +
> +}
>
> /* Note: The init and fini parameters are no longer used. fini is
> completely unused, init is still called if not NULL, but the
> @@ -276,6 +285,9 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
> /* Perform IREL{,A} relocations. */
> ARCH_SETUP_IREL ();
>
> + /* Process notes: PT_NOTE / PT_GNU_PROPERTY. */
> + ARCH_PROCESS_NOTES ();
> +
> /* The stack guard goes into the TCB, so initialize it early. */
> ARCH_SETUP_TLS ();
>
> diff --git a/sysdeps/generic/libc-start.h b/sysdeps/generic/libc-start.h
> index 0b107cf2a1..1a421626b5 100644
> --- a/sysdeps/generic/libc-start.h
> +++ b/sysdeps/generic/libc-start.h
> @@ -24,6 +24,7 @@
> initialization, and this means you cannot, without machine
> knowledge, access TLS from an IFUNC resolver. */
> #define ARCH_SETUP_IREL() apply_irel ()
> +#define ARCH_PROCESS_NOTES() __libc_process_notes ()
> #define ARCH_SETUP_TLS() __libc_setup_tls ()
> #define ARCH_APPLY_IREL()
> #endif /* ! SHARED */
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc-start.h b/sysdeps/unix/sysv/linux/aarch64/libc-start.h
> index 735076c086..0f80a8abe9 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc-start.h
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc-start.h
> @@ -21,6 +21,24 @@
>
> #ifndef SHARED
>
> +# include <dl-prop.h>
> +
> +/* Must be on a top-level stack frame that does not return. */
> +static inline void __attribute__((always_inline))
> +aarch64_libc_process_notes (void)
> +{
> + struct link_map *main_map = _dl_get_dl_main_map ();
> + const ElfW(Phdr) *phdr = GL(dl_phdr);
> + const ElfW(Phdr) *ph;
> + for (ph = phdr; ph < phdr + GL(dl_phnum); ph++)
> + if (ph->p_type == PT_GNU_PROPERTY)
> + {
> + _dl_process_pt_gnu_property (main_map, -1, ph);
> + _rtld_main_check (main_map, _dl_argv[0]);
> + break;
> + }
> +}
> +
> # ifndef PR_SET_SHADOW_STACK_STATUS
> # define PR_SET_SHADOW_STACK_STATUS 75
> # define PR_SHADOW_STACK_ENABLE (1UL << 0)
> @@ -39,6 +57,7 @@ aarch64_libc_setup_tls (void)
> }
>
> # define ARCH_SETUP_IREL() apply_irel ()
> +# define ARCH_PROCESS_NOTES() aarch64_libc_process_notes ()
> # define ARCH_SETUP_TLS() aarch64_libc_setup_tls ()
> # define ARCH_APPLY_IREL()
> #endif /* ! SHARED */
More information about the Libc-alpha
mailing list