public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Linux: Auxiliary vector parsing cleanups
@ 2022-01-11 18:43 Florian Weimer
  2022-01-11 18:43 ` [PATCH 1/5] elf: Merge dl-sysdep.c into the Linux version Florian Weimer
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Florian Weimer @ 2022-01-11 18:43 UTC (permalink / raw)
  To: libc-alpha

This removes some support code for pre-2.4.0 kernels and Native Client.

The simplified version of _dl_sysdep_start has a higher chance to run on
CPUs with older ISA levels, which is the main motivation for this
cleanup.

Thanks,
Florian

Florian Weimer (5):
  elf: Merge dl-sysdep.c into the Linux version
  Linux: Remove HAVE_AUX_SECURE, HAVE_AUX_XID, HAVE_AUX_PAGESIZE
  Linux: Remove DL_FIND_ARG_COMPONENTS
  Linux: Assume that NEED_DL_SYSINFO_DSO is always defined
  Linux: Consolidate auxiliary vector parsing

 elf/dl-support.c                             |  80 +----
 elf/dl-sysdep.c                              | 352 +------------------
 sysdeps/unix/sysv/linux/alpha/dl-auxv.h      |  18 +-
 sysdeps/unix/sysv/linux/dl-parse_auxv.h      |  61 ++++
 sysdeps/unix/sysv/linux/dl-sysdep.c          | 240 ++++++++++++-
 sysdeps/unix/sysv/linux/ldsodefs.h           |  12 -
 sysdeps/unix/sysv/linux/m68k/sysdep.h        |   4 +-
 sysdeps/unix/sysv/linux/powerpc/dl-auxv.h    |  14 +-
 sysdeps/unix/sysv/linux/powerpc/dl-support.c |   4 +
 9 files changed, 305 insertions(+), 480 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/dl-parse_auxv.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/dl-support.c


base-commit: 7e08db3359c86c94918feb33a1182cd0ff3bb10b
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] elf: Merge dl-sysdep.c into the Linux version
  2022-01-11 18:43 [PATCH 0/5] Linux: Auxiliary vector parsing cleanups Florian Weimer
@ 2022-01-11 18:43 ` Florian Weimer
  2022-01-11 18:43 ` [PATCH 2/5] Linux: Remove HAVE_AUX_SECURE, HAVE_AUX_XID, HAVE_AUX_PAGESIZE Florian Weimer
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Florian Weimer @ 2022-01-11 18:43 UTC (permalink / raw)
  To: libc-alpha

The generic version is the de-facto Linux implementation.  It
requires an auxiliary vector, so Hurd does not use it.
---
 elf/dl-sysdep.c                     | 352 +---------------------------
 sysdeps/unix/sysv/linux/dl-sysdep.c | 347 ++++++++++++++++++++++++++-
 2 files changed, 337 insertions(+), 362 deletions(-)

diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index f1dba8ef24..7aa90ad6ee 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -1,4 +1,4 @@
-/* Operating system support for run-time dynamic linker.  Generic Unix version.
+/* Operating system support for run-time dynamic linker.  Stub version.
    Copyright (C) 1995-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,352 +16,4 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-/* We conditionalize the whole of this file rather than simply eliding it
-   from the static build, because other sysdeps/ versions of this file
-   might define things needed by a static build.  */
-
-#ifdef SHARED
-
-#include <assert.h>
-#include <elf.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <libintl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <ldsodefs.h>
-#include <_itoa.h>
-#include <fpu_control.h>
-
-#include <entry.h>
-#include <dl-machine.h>
-#include <dl-procinfo.h>
-#include <dl-osinfo.h>
-#include <libc-internal.h>
-#include <tls.h>
-
-#include <dl-tunables.h>
-#include <dl-auxv.h>
-#include <dl-hwcap-check.h>
-
-extern char **_environ attribute_hidden;
-extern char _end[] attribute_hidden;
-
-/* Protect SUID program against misuse of file descriptors.  */
-extern void __libc_check_standard_fds (void);
-
-int __libc_enable_secure attribute_relro = 0;
-rtld_hidden_data_def (__libc_enable_secure)
-/* This variable contains the lowest stack address ever used.  */
-void *__libc_stack_end attribute_relro = NULL;
-rtld_hidden_data_def(__libc_stack_end)
-void *_dl_random attribute_relro = NULL;
-
-#ifndef DL_FIND_ARG_COMPONENTS
-# define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp)	\
-  do {									      \
-    void **_tmp;							      \
-    (argc) = *(long int *) cookie;					      \
-    (argv) = (char **) ((long int *) cookie + 1);			      \
-    (envp) = (argv) + (argc) + 1;					      \
-    for (_tmp = (void **) (envp); *_tmp; ++_tmp)			      \
-      continue;								      \
-    (auxp) = (void *) ++_tmp;						      \
-  } while (0)
-#endif
-
-#ifndef DL_STACK_END
-# define DL_STACK_END(cookie) ((void *) (cookie))
-#endif
-
-ElfW(Addr)
-_dl_sysdep_start (void **start_argptr,
-		  void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
-				   ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv))
-{
-  const ElfW(Phdr) *phdr = NULL;
-  ElfW(Word) phnum = 0;
-  ElfW(Addr) user_entry;
-  ElfW(auxv_t) *av;
-#ifdef HAVE_AUX_SECURE
-# define set_seen(tag) (tag)	/* Evaluate for the side effects.  */
-# define set_seen_secure() ((void) 0)
-#else
-  uid_t uid = 0;
-  gid_t gid = 0;
-  unsigned int seen = 0;
-# define set_seen_secure() (seen = -1)
-# ifdef HAVE_AUX_XID
-#  define set_seen(tag) (tag)	/* Evaluate for the side effects.  */
-# else
-#  define M(type) (1 << (type))
-#  define set_seen(tag) seen |= M ((tag)->a_type)
-# endif
-#endif
-#ifdef NEED_DL_SYSINFO
-  uintptr_t new_sysinfo = 0;
-#endif
-
-  __libc_stack_end = DL_STACK_END (start_argptr);
-  DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ,
-			  GLRO(dl_auxv));
-
-  user_entry = (ElfW(Addr)) ENTRY_POINT;
-  GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
-
-  /* NB: Default to a constant CONSTANT_MINSIGSTKSZ.  */
-  _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ),
-		  "CONSTANT_MINSIGSTKSZ is constant");
-  GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ;
-
-  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
-    switch (av->a_type)
-      {
-      case AT_PHDR:
-	phdr = (void *) av->a_un.a_val;
-	break;
-      case AT_PHNUM:
-	phnum = av->a_un.a_val;
-	break;
-      case AT_PAGESZ:
-	GLRO(dl_pagesize) = av->a_un.a_val;
-	break;
-      case AT_ENTRY:
-	user_entry = av->a_un.a_val;
-	break;
-#ifndef HAVE_AUX_SECURE
-      case AT_UID:
-      case AT_EUID:
-	uid ^= av->a_un.a_val;
-	break;
-      case AT_GID:
-      case AT_EGID:
-	gid ^= av->a_un.a_val;
-	break;
-#endif
-      case AT_SECURE:
-#ifndef HAVE_AUX_SECURE
-	seen = -1;
-#endif
-	__libc_enable_secure = av->a_un.a_val;
-	break;
-      case AT_PLATFORM:
-	GLRO(dl_platform) = (void *) av->a_un.a_val;
-	break;
-      case AT_HWCAP:
-	GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
-	break;
-      case AT_HWCAP2:
-	GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val;
-	break;
-      case AT_CLKTCK:
-	GLRO(dl_clktck) = av->a_un.a_val;
-	break;
-      case AT_FPUCW:
-	GLRO(dl_fpu_control) = av->a_un.a_val;
-	break;
-#ifdef NEED_DL_SYSINFO
-      case AT_SYSINFO:
-	new_sysinfo = av->a_un.a_val;
-	break;
-#endif
-#ifdef NEED_DL_SYSINFO_DSO
-      case AT_SYSINFO_EHDR:
-	GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val;
-	break;
-#endif
-      case AT_RANDOM:
-	_dl_random = (void *) av->a_un.a_val;
-	break;
-      case AT_MINSIGSTKSZ:
-	GLRO(dl_minsigstacksize) = av->a_un.a_val;
-	break;
-      DL_PLATFORM_AUXV
-      }
-
-  dl_hwcap_check ();
-
-#ifndef HAVE_AUX_SECURE
-  if (seen != -1)
-    {
-      /* Fill in the values we have not gotten from the kernel through the
-	 auxiliary vector.  */
-# ifndef HAVE_AUX_XID
-#  define SEE(UID, var, uid) \
-   if ((seen & M (AT_##UID)) == 0) var ^= __get##uid ()
-      SEE (UID, uid, uid);
-      SEE (EUID, uid, euid);
-      SEE (GID, gid, gid);
-      SEE (EGID, gid, egid);
-# endif
-
-      /* If one of the two pairs of IDs does not match this is a setuid
-	 or setgid run.  */
-      __libc_enable_secure = uid | gid;
-    }
-#endif
-
-#ifndef HAVE_AUX_PAGESIZE
-  if (GLRO(dl_pagesize) == 0)
-    GLRO(dl_pagesize) = __getpagesize ();
-#endif
-
-#ifdef NEED_DL_SYSINFO
-  if (new_sysinfo != 0)
-    {
-# ifdef NEED_DL_SYSINFO_DSO
-      /* Only set the sysinfo value if we also have the vsyscall DSO.  */
-      if (GLRO(dl_sysinfo_dso) != 0)
-# endif
-        GLRO(dl_sysinfo) = new_sysinfo;
-    }
-#endif
-
-  __tunables_init (_environ);
-
-  /* Initialize DSO sorting algorithm after tunables.  */
-  _dl_sort_maps_init ();
-
-#ifdef DL_SYSDEP_INIT
-  DL_SYSDEP_INIT;
-#endif
-
-#ifdef DL_PLATFORM_INIT
-  DL_PLATFORM_INIT;
-#endif
-
-  /* Determine the length of the platform name.  */
-  if (GLRO(dl_platform) != NULL)
-    GLRO(dl_platformlen) = strlen (GLRO(dl_platform));
-
-  if (__sbrk (0) == _end)
-    /* The dynamic linker was run as a program, and so the initial break
-       starts just after our bss, at &_end.  The malloc in dl-minimal.c
-       will consume the rest of this page, so tell the kernel to move the
-       break up that far.  When the user program examines its break, it
-       will see this new value and not clobber our data.  */
-    __sbrk (GLRO(dl_pagesize)
-	    - ((_end - (char *) 0) & (GLRO(dl_pagesize) - 1)));
-
-  /* If this is a SUID program we make sure that FDs 0, 1, and 2 are
-     allocated.  If necessary we are doing it ourself.  If it is not
-     possible we stop the program.  */
-  if (__builtin_expect (__libc_enable_secure, 0))
-    __libc_check_standard_fds ();
-
-  (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv));
-  return user_entry;
-}
-
-void
-_dl_sysdep_start_cleanup (void)
-{
-}
-
-void
-_dl_show_auxv (void)
-{
-  char buf[64];
-  ElfW(auxv_t) *av;
-
-  /* Terminate string.  */
-  buf[63] = '\0';
-
-  /* The following code assumes that the AT_* values are encoded
-     starting from 0 with AT_NULL, 1 for AT_IGNORE, and all other values
-     close by (otherwise the array will be too large).  In case we have
-     to support a platform where these requirements are not fulfilled
-     some alternative implementation has to be used.  */
-  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av)
-    {
-      static const struct
-      {
-	const char label[22];
-	enum { unknown = 0, dec, hex, str, ignore } form : 8;
-      } auxvars[] =
-	{
-	  [AT_EXECFD - 2] =		{ "EXECFD:            ", dec },
-	  [AT_EXECFN - 2] =		{ "EXECFN:            ", str },
-	  [AT_PHDR - 2] =		{ "PHDR:              0x", hex },
-	  [AT_PHENT - 2] =		{ "PHENT:             ", dec },
-	  [AT_PHNUM - 2] =		{ "PHNUM:             ", dec },
-	  [AT_PAGESZ - 2] =		{ "PAGESZ:            ", dec },
-	  [AT_BASE - 2] =		{ "BASE:              0x", hex },
-	  [AT_FLAGS - 2] =		{ "FLAGS:             0x", hex },
-	  [AT_ENTRY - 2] =		{ "ENTRY:             0x", hex },
-	  [AT_NOTELF - 2] =		{ "NOTELF:            ", hex },
-	  [AT_UID - 2] =		{ "UID:               ", dec },
-	  [AT_EUID - 2] =		{ "EUID:              ", dec },
-	  [AT_GID - 2] =		{ "GID:               ", dec },
-	  [AT_EGID - 2] =		{ "EGID:              ", dec },
-	  [AT_PLATFORM - 2] =		{ "PLATFORM:          ", str },
-	  [AT_HWCAP - 2] =		{ "HWCAP:             ", hex },
-	  [AT_CLKTCK - 2] =		{ "CLKTCK:            ", dec },
-	  [AT_FPUCW - 2] =		{ "FPUCW:             ", hex },
-	  [AT_DCACHEBSIZE - 2] =	{ "DCACHEBSIZE:       0x", hex },
-	  [AT_ICACHEBSIZE - 2] =	{ "ICACHEBSIZE:       0x", hex },
-	  [AT_UCACHEBSIZE - 2] =	{ "UCACHEBSIZE:       0x", hex },
-	  [AT_IGNOREPPC - 2] =		{ "IGNOREPPC", ignore },
-	  [AT_SECURE - 2] =		{ "SECURE:            ", dec },
-	  [AT_BASE_PLATFORM - 2] =	{ "BASE_PLATFORM:     ", str },
-	  [AT_SYSINFO - 2] =		{ "SYSINFO:           0x", hex },
-	  [AT_SYSINFO_EHDR - 2] =	{ "SYSINFO_EHDR:      0x", hex },
-	  [AT_RANDOM - 2] =		{ "RANDOM:            0x", hex },
-	  [AT_HWCAP2 - 2] =		{ "HWCAP2:            0x", hex },
-	  [AT_MINSIGSTKSZ - 2] =	{ "MINSIGSTKSZ:       ", dec },
-	  [AT_L1I_CACHESIZE - 2] =	{ "L1I_CACHESIZE:     ", dec },
-	  [AT_L1I_CACHEGEOMETRY - 2] =	{ "L1I_CACHEGEOMETRY: 0x", hex },
-	  [AT_L1D_CACHESIZE - 2] =	{ "L1D_CACHESIZE:     ", dec },
-	  [AT_L1D_CACHEGEOMETRY - 2] =	{ "L1D_CACHEGEOMETRY: 0x", hex },
-	  [AT_L2_CACHESIZE - 2] =	{ "L2_CACHESIZE:      ", dec },
-	  [AT_L2_CACHEGEOMETRY - 2] =	{ "L2_CACHEGEOMETRY:  0x", hex },
-	  [AT_L3_CACHESIZE - 2] =	{ "L3_CACHESIZE:      ", dec },
-	  [AT_L3_CACHEGEOMETRY - 2] =	{ "L3_CACHEGEOMETRY:  0x", hex },
-	};
-      unsigned int idx = (unsigned int) (av->a_type - 2);
-
-      if ((unsigned int) av->a_type < 2u
-	  || (idx < sizeof (auxvars) / sizeof (auxvars[0])
-	      && auxvars[idx].form == ignore))
-	continue;
-
-      assert (AT_NULL == 0);
-      assert (AT_IGNORE == 1);
-
-      /* Some entries are handled in a special way per platform.  */
-      if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
-	continue;
-
-      if (idx < sizeof (auxvars) / sizeof (auxvars[0])
-	  && auxvars[idx].form != unknown)
-	{
-	  const char *val = (char *) av->a_un.a_val;
-
-	  if (__builtin_expect (auxvars[idx].form, dec) == dec)
-	    val = _itoa ((unsigned long int) av->a_un.a_val,
-			 buf + sizeof buf - 1, 10, 0);
-	  else if (__builtin_expect (auxvars[idx].form, hex) == hex)
-	    val = _itoa ((unsigned long int) av->a_un.a_val,
-			 buf + sizeof buf - 1, 16, 0);
-
-	  _dl_printf ("AT_%s%s\n", auxvars[idx].label, val);
-
-	  continue;
-	}
-
-      /* Unknown value: print a generic line.  */
-      char buf2[17];
-      buf2[sizeof (buf2) - 1] = '\0';
-      const char *val2 = _itoa ((unsigned long int) av->a_un.a_val,
-				buf2 + sizeof buf2 - 1, 16, 0);
-      const char *val =  _itoa ((unsigned long int) av->a_type,
-				buf + sizeof buf - 1, 16, 0);
-      _dl_printf ("AT_??? (0x%s): 0x%s\n", val, val2);
-    }
-}
-
-#endif
+#error dl-sysdep support missing.
diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c
index 66ba489cd3..4f60cecf98 100644
--- a/sysdeps/unix/sysv/linux/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c
@@ -16,29 +16,352 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-/* Linux needs some special initialization, but otherwise uses
-   the generic dynamic linker system interface code.  */
-
-#include <string.h>
+#include <_itoa.h>
+#include <assert.h>
+#include <dl-auxv.h>
+#include <dl-hwcap-check.h>
+#include <dl-osinfo.h>
+#include <dl-procinfo.h>
+#include <dl-tunables.h>
+#include <elf.h>
+#include <entry.h>
+#include <errno.h>
 #include <fcntl.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/utsname.h>
+#include <fpu_control.h>
 #include <ldsodefs.h>
+#include <libc-internal.h>
+#include <libintl.h>
 #include <not-cancel.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <tls.h>
+#include <unistd.h>
+
+#include <dl-machine.h>
 
 #ifdef SHARED
-# define DL_SYSDEP_INIT frob_brk ()
+extern char **_environ attribute_hidden;
+extern char _end[] attribute_hidden;
+
+/* Protect SUID program against misuse of file descriptors.  */
+extern void __libc_check_standard_fds (void);
 
-static inline void
-frob_brk (void)
+int __libc_enable_secure attribute_relro = 0;
+rtld_hidden_data_def (__libc_enable_secure)
+/* This variable contains the lowest stack address ever used.  */
+void *__libc_stack_end attribute_relro = NULL;
+rtld_hidden_data_def(__libc_stack_end)
+void *_dl_random attribute_relro = NULL;
+
+#ifndef DL_FIND_ARG_COMPONENTS
+# define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp)	\
+  do {									      \
+    void **_tmp;							      \
+    (argc) = *(long int *) cookie;					      \
+    (argv) = (char **) ((long int *) cookie + 1);			      \
+    (envp) = (argv) + (argc) + 1;					      \
+    for (_tmp = (void **) (envp); *_tmp; ++_tmp)			      \
+      continue;								      \
+    (auxp) = (void *) ++_tmp;						      \
+  } while (0)
+#endif
+
+#ifndef DL_STACK_END
+# define DL_STACK_END(cookie) ((void *) (cookie))
+#endif
+
+ElfW(Addr)
+_dl_sysdep_start (void **start_argptr,
+		  void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
+				   ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv))
 {
+  const ElfW(Phdr) *phdr = NULL;
+  ElfW(Word) phnum = 0;
+  ElfW(Addr) user_entry;
+  ElfW(auxv_t) *av;
+#ifdef HAVE_AUX_SECURE
+# define set_seen(tag) (tag)	/* Evaluate for the side effects.  */
+# define set_seen_secure() ((void) 0)
+#else
+  uid_t uid = 0;
+  gid_t gid = 0;
+  unsigned int seen = 0;
+# define set_seen_secure() (seen = -1)
+# ifdef HAVE_AUX_XID
+#  define set_seen(tag) (tag)	/* Evaluate for the side effects.  */
+# else
+#  define M(type) (1 << (type))
+#  define set_seen(tag) seen |= M ((tag)->a_type)
+# endif
+#endif
+#ifdef NEED_DL_SYSINFO
+  uintptr_t new_sysinfo = 0;
+#endif
+
+  __libc_stack_end = DL_STACK_END (start_argptr);
+  DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ,
+			  GLRO(dl_auxv));
+
+  user_entry = (ElfW(Addr)) ENTRY_POINT;
+  GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
+
+  /* NB: Default to a constant CONSTANT_MINSIGSTKSZ.  */
+  _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ),
+		  "CONSTANT_MINSIGSTKSZ is constant");
+  GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ;
+
+  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
+    switch (av->a_type)
+      {
+      case AT_PHDR:
+	phdr = (void *) av->a_un.a_val;
+	break;
+      case AT_PHNUM:
+	phnum = av->a_un.a_val;
+	break;
+      case AT_PAGESZ:
+	GLRO(dl_pagesize) = av->a_un.a_val;
+	break;
+      case AT_ENTRY:
+	user_entry = av->a_un.a_val;
+	break;
+#ifndef HAVE_AUX_SECURE
+      case AT_UID:
+      case AT_EUID:
+	uid ^= av->a_un.a_val;
+	break;
+      case AT_GID:
+      case AT_EGID:
+	gid ^= av->a_un.a_val;
+	break;
+#endif
+      case AT_SECURE:
+#ifndef HAVE_AUX_SECURE
+	seen = -1;
+#endif
+	__libc_enable_secure = av->a_un.a_val;
+	break;
+      case AT_PLATFORM:
+	GLRO(dl_platform) = (void *) av->a_un.a_val;
+	break;
+      case AT_HWCAP:
+	GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
+	break;
+      case AT_HWCAP2:
+	GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val;
+	break;
+      case AT_CLKTCK:
+	GLRO(dl_clktck) = av->a_un.a_val;
+	break;
+      case AT_FPUCW:
+	GLRO(dl_fpu_control) = av->a_un.a_val;
+	break;
+#ifdef NEED_DL_SYSINFO
+      case AT_SYSINFO:
+	new_sysinfo = av->a_un.a_val;
+	break;
+#endif
+#ifdef NEED_DL_SYSINFO_DSO
+      case AT_SYSINFO_EHDR:
+	GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val;
+	break;
+#endif
+      case AT_RANDOM:
+	_dl_random = (void *) av->a_un.a_val;
+	break;
+      case AT_MINSIGSTKSZ:
+	GLRO(dl_minsigstacksize) = av->a_un.a_val;
+	break;
+      DL_PLATFORM_AUXV
+      }
+
+  dl_hwcap_check ();
+
+#ifndef HAVE_AUX_SECURE
+  if (seen != -1)
+    {
+      /* Fill in the values we have not gotten from the kernel through the
+	 auxiliary vector.  */
+# ifndef HAVE_AUX_XID
+#  define SEE(UID, var, uid) \
+   if ((seen & M (AT_##UID)) == 0) var ^= __get##uid ()
+      SEE (UID, uid, uid);
+      SEE (EUID, uid, euid);
+      SEE (GID, gid, gid);
+      SEE (EGID, gid, egid);
+# endif
+
+      /* If one of the two pairs of IDs does not match this is a setuid
+	 or setgid run.  */
+      __libc_enable_secure = uid | gid;
+    }
+#endif
+
+#ifndef HAVE_AUX_PAGESIZE
+  if (GLRO(dl_pagesize) == 0)
+    GLRO(dl_pagesize) = __getpagesize ();
+#endif
+
+#ifdef NEED_DL_SYSINFO
+  if (new_sysinfo != 0)
+    {
+# ifdef NEED_DL_SYSINFO_DSO
+      /* Only set the sysinfo value if we also have the vsyscall DSO.  */
+      if (GLRO(dl_sysinfo_dso) != 0)
+# endif
+        GLRO(dl_sysinfo) = new_sysinfo;
+    }
+#endif
+
+  __tunables_init (_environ);
+
+  /* Initialize DSO sorting algorithm after tunables.  */
+  _dl_sort_maps_init ();
+
   __brk (0);			/* Initialize the break.  */
-}
 
-# include <elf/dl-sysdep.c>
+#ifdef DL_PLATFORM_INIT
+  DL_PLATFORM_INIT;
 #endif
 
+  /* Determine the length of the platform name.  */
+  if (GLRO(dl_platform) != NULL)
+    GLRO(dl_platformlen) = strlen (GLRO(dl_platform));
+
+  if (__sbrk (0) == _end)
+    /* The dynamic linker was run as a program, and so the initial break
+       starts just after our bss, at &_end.  The malloc in dl-minimal.c
+       will consume the rest of this page, so tell the kernel to move the
+       break up that far.  When the user program examines its break, it
+       will see this new value and not clobber our data.  */
+    __sbrk (GLRO(dl_pagesize)
+	    - ((_end - (char *) 0) & (GLRO(dl_pagesize) - 1)));
+
+  /* If this is a SUID program we make sure that FDs 0, 1, and 2 are
+     allocated.  If necessary we are doing it ourself.  If it is not
+     possible we stop the program.  */
+  if (__builtin_expect (__libc_enable_secure, 0))
+    __libc_check_standard_fds ();
+
+  (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv));
+  return user_entry;
+}
+
+void
+_dl_sysdep_start_cleanup (void)
+{
+}
+
+void
+_dl_show_auxv (void)
+{
+  char buf[64];
+  ElfW(auxv_t) *av;
+
+  /* Terminate string.  */
+  buf[63] = '\0';
+
+  /* The following code assumes that the AT_* values are encoded
+     starting from 0 with AT_NULL, 1 for AT_IGNORE, and all other values
+     close by (otherwise the array will be too large).  In case we have
+     to support a platform where these requirements are not fulfilled
+     some alternative implementation has to be used.  */
+  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av)
+    {
+      static const struct
+      {
+	const char label[22];
+	enum { unknown = 0, dec, hex, str, ignore } form : 8;
+      } auxvars[] =
+	{
+	  [AT_EXECFD - 2] =		{ "EXECFD:            ", dec },
+	  [AT_EXECFN - 2] =		{ "EXECFN:            ", str },
+	  [AT_PHDR - 2] =		{ "PHDR:              0x", hex },
+	  [AT_PHENT - 2] =		{ "PHENT:             ", dec },
+	  [AT_PHNUM - 2] =		{ "PHNUM:             ", dec },
+	  [AT_PAGESZ - 2] =		{ "PAGESZ:            ", dec },
+	  [AT_BASE - 2] =		{ "BASE:              0x", hex },
+	  [AT_FLAGS - 2] =		{ "FLAGS:             0x", hex },
+	  [AT_ENTRY - 2] =		{ "ENTRY:             0x", hex },
+	  [AT_NOTELF - 2] =		{ "NOTELF:            ", hex },
+	  [AT_UID - 2] =		{ "UID:               ", dec },
+	  [AT_EUID - 2] =		{ "EUID:              ", dec },
+	  [AT_GID - 2] =		{ "GID:               ", dec },
+	  [AT_EGID - 2] =		{ "EGID:              ", dec },
+	  [AT_PLATFORM - 2] =		{ "PLATFORM:          ", str },
+	  [AT_HWCAP - 2] =		{ "HWCAP:             ", hex },
+	  [AT_CLKTCK - 2] =		{ "CLKTCK:            ", dec },
+	  [AT_FPUCW - 2] =		{ "FPUCW:             ", hex },
+	  [AT_DCACHEBSIZE - 2] =	{ "DCACHEBSIZE:       0x", hex },
+	  [AT_ICACHEBSIZE - 2] =	{ "ICACHEBSIZE:       0x", hex },
+	  [AT_UCACHEBSIZE - 2] =	{ "UCACHEBSIZE:       0x", hex },
+	  [AT_IGNOREPPC - 2] =		{ "IGNOREPPC", ignore },
+	  [AT_SECURE - 2] =		{ "SECURE:            ", dec },
+	  [AT_BASE_PLATFORM - 2] =	{ "BASE_PLATFORM:     ", str },
+	  [AT_SYSINFO - 2] =		{ "SYSINFO:           0x", hex },
+	  [AT_SYSINFO_EHDR - 2] =	{ "SYSINFO_EHDR:      0x", hex },
+	  [AT_RANDOM - 2] =		{ "RANDOM:            0x", hex },
+	  [AT_HWCAP2 - 2] =		{ "HWCAP2:            0x", hex },
+	  [AT_MINSIGSTKSZ - 2] =	{ "MINSIGSTKSZ:       ", dec },
+	  [AT_L1I_CACHESIZE - 2] =	{ "L1I_CACHESIZE:     ", dec },
+	  [AT_L1I_CACHEGEOMETRY - 2] =	{ "L1I_CACHEGEOMETRY: 0x", hex },
+	  [AT_L1D_CACHESIZE - 2] =	{ "L1D_CACHESIZE:     ", dec },
+	  [AT_L1D_CACHEGEOMETRY - 2] =	{ "L1D_CACHEGEOMETRY: 0x", hex },
+	  [AT_L2_CACHESIZE - 2] =	{ "L2_CACHESIZE:      ", dec },
+	  [AT_L2_CACHEGEOMETRY - 2] =	{ "L2_CACHEGEOMETRY:  0x", hex },
+	  [AT_L3_CACHESIZE - 2] =	{ "L3_CACHESIZE:      ", dec },
+	  [AT_L3_CACHEGEOMETRY - 2] =	{ "L3_CACHEGEOMETRY:  0x", hex },
+	};
+      unsigned int idx = (unsigned int) (av->a_type - 2);
+
+      if ((unsigned int) av->a_type < 2u
+	  || (idx < sizeof (auxvars) / sizeof (auxvars[0])
+	      && auxvars[idx].form == ignore))
+	continue;
+
+      assert (AT_NULL == 0);
+      assert (AT_IGNORE == 1);
+
+      /* Some entries are handled in a special way per platform.  */
+      if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
+	continue;
+
+      if (idx < sizeof (auxvars) / sizeof (auxvars[0])
+	  && auxvars[idx].form != unknown)
+	{
+	  const char *val = (char *) av->a_un.a_val;
+
+	  if (__builtin_expect (auxvars[idx].form, dec) == dec)
+	    val = _itoa ((unsigned long int) av->a_un.a_val,
+			 buf + sizeof buf - 1, 10, 0);
+	  else if (__builtin_expect (auxvars[idx].form, hex) == hex)
+	    val = _itoa ((unsigned long int) av->a_un.a_val,
+			 buf + sizeof buf - 1, 16, 0);
+
+	  _dl_printf ("AT_%s%s\n", auxvars[idx].label, val);
+
+	  continue;
+	}
+
+      /* Unknown value: print a generic line.  */
+      char buf2[17];
+      buf2[sizeof (buf2) - 1] = '\0';
+      const char *val2 = _itoa ((unsigned long int) av->a_un.a_val,
+				buf2 + sizeof buf2 - 1, 16, 0);
+      const char *val =  _itoa ((unsigned long int) av->a_type,
+				buf + sizeof buf - 1, 16, 0);
+      _dl_printf ("AT_??? (0x%s): 0x%s\n", val, val2);
+    }
+}
+
+#endif /* SHARED */
+
 
 int
 attribute_hidden
-- 
2.34.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/5] Linux: Remove HAVE_AUX_SECURE, HAVE_AUX_XID, HAVE_AUX_PAGESIZE
  2022-01-11 18:43 [PATCH 0/5] Linux: Auxiliary vector parsing cleanups Florian Weimer
  2022-01-11 18:43 ` [PATCH 1/5] elf: Merge dl-sysdep.c into the Linux version Florian Weimer
@ 2022-01-11 18:43 ` Florian Weimer
  2022-01-11 18:43 ` [PATCH 3/5] Linux: Remove DL_FIND_ARG_COMPONENTS Florian Weimer
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Florian Weimer @ 2022-01-11 18:43 UTC (permalink / raw)
  To: libc-alpha

They are always defined.
---
 sysdeps/unix/sysv/linux/dl-sysdep.c | 55 +----------------------------
 sysdeps/unix/sysv/linux/ldsodefs.h  | 12 -------
 2 files changed, 1 insertion(+), 66 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c
index 4f60cecf98..72aa109f2f 100644
--- a/sysdeps/unix/sysv/linux/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c
@@ -85,21 +85,6 @@ _dl_sysdep_start (void **start_argptr,
   ElfW(Word) phnum = 0;
   ElfW(Addr) user_entry;
   ElfW(auxv_t) *av;
-#ifdef HAVE_AUX_SECURE
-# define set_seen(tag) (tag)	/* Evaluate for the side effects.  */
-# define set_seen_secure() ((void) 0)
-#else
-  uid_t uid = 0;
-  gid_t gid = 0;
-  unsigned int seen = 0;
-# define set_seen_secure() (seen = -1)
-# ifdef HAVE_AUX_XID
-#  define set_seen(tag) (tag)	/* Evaluate for the side effects.  */
-# else
-#  define M(type) (1 << (type))
-#  define set_seen(tag) seen |= M ((tag)->a_type)
-# endif
-#endif
 #ifdef NEED_DL_SYSINFO
   uintptr_t new_sysinfo = 0;
 #endif
@@ -116,7 +101,7 @@ _dl_sysdep_start (void **start_argptr,
 		  "CONSTANT_MINSIGSTKSZ is constant");
   GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ;
 
-  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
+  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; av++)
     switch (av->a_type)
       {
       case AT_PHDR:
@@ -131,20 +116,7 @@ _dl_sysdep_start (void **start_argptr,
       case AT_ENTRY:
 	user_entry = av->a_un.a_val;
 	break;
-#ifndef HAVE_AUX_SECURE
-      case AT_UID:
-      case AT_EUID:
-	uid ^= av->a_un.a_val;
-	break;
-      case AT_GID:
-      case AT_EGID:
-	gid ^= av->a_un.a_val;
-	break;
-#endif
       case AT_SECURE:
-#ifndef HAVE_AUX_SECURE
-	seen = -1;
-#endif
 	__libc_enable_secure = av->a_un.a_val;
 	break;
       case AT_PLATFORM:
@@ -183,31 +155,6 @@ _dl_sysdep_start (void **start_argptr,
 
   dl_hwcap_check ();
 
-#ifndef HAVE_AUX_SECURE
-  if (seen != -1)
-    {
-      /* Fill in the values we have not gotten from the kernel through the
-	 auxiliary vector.  */
-# ifndef HAVE_AUX_XID
-#  define SEE(UID, var, uid) \
-   if ((seen & M (AT_##UID)) == 0) var ^= __get##uid ()
-      SEE (UID, uid, uid);
-      SEE (EUID, uid, euid);
-      SEE (GID, gid, gid);
-      SEE (EGID, gid, egid);
-# endif
-
-      /* If one of the two pairs of IDs does not match this is a setuid
-	 or setgid run.  */
-      __libc_enable_secure = uid | gid;
-    }
-#endif
-
-#ifndef HAVE_AUX_PAGESIZE
-  if (GLRO(dl_pagesize) == 0)
-    GLRO(dl_pagesize) = __getpagesize ();
-#endif
-
 #ifdef NEED_DL_SYSINFO
   if (new_sysinfo != 0)
     {
diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h
index 011756ddc1..af108991f0 100644
--- a/sysdeps/unix/sysv/linux/ldsodefs.h
+++ b/sysdeps/unix/sysv/linux/ldsodefs.h
@@ -24,16 +24,4 @@
 /* Get the real definitions.  */
 #include_next <ldsodefs.h>
 
-/* We can assume that the kernel always provides the AT_UID, AT_EUID,
-   AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on.  */
-#define HAVE_AUX_XID
-
-/* We can assume that the kernel always provides the AT_SECURE value
-   in the auxiliary vector from 2.5.74 or so on.  */
-#define HAVE_AUX_SECURE
-
-/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes
-   up the page size information.  */
-#define HAVE_AUX_PAGESIZE
-
 #endif /* ldsodefs.h */
-- 
2.34.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/5] Linux: Remove DL_FIND_ARG_COMPONENTS
  2022-01-11 18:43 [PATCH 0/5] Linux: Auxiliary vector parsing cleanups Florian Weimer
  2022-01-11 18:43 ` [PATCH 1/5] elf: Merge dl-sysdep.c into the Linux version Florian Weimer
  2022-01-11 18:43 ` [PATCH 2/5] Linux: Remove HAVE_AUX_SECURE, HAVE_AUX_XID, HAVE_AUX_PAGESIZE Florian Weimer
@ 2022-01-11 18:43 ` Florian Weimer
  2022-01-11 18:44 ` [PATCH 4/5] Linux: Assume that NEED_DL_SYSINFO_DSO is always defined Florian Weimer
  2022-01-11 18:44 ` [PATCH 5/5] Linux: Consolidate auxiliary vector parsing Florian Weimer
  4 siblings, 0 replies; 6+ messages in thread
From: Florian Weimer @ 2022-01-11 18:43 UTC (permalink / raw)
  To: libc-alpha

The generic definition is always used since the Native Client
port has been removed.
---
 sysdeps/unix/sysv/linux/dl-sysdep.c | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c
index 72aa109f2f..a13e0ea7ad 100644
--- a/sysdeps/unix/sysv/linux/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c
@@ -59,19 +59,6 @@ void *__libc_stack_end attribute_relro = NULL;
 rtld_hidden_data_def(__libc_stack_end)
 void *_dl_random attribute_relro = NULL;
 
-#ifndef DL_FIND_ARG_COMPONENTS
-# define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp)	\
-  do {									      \
-    void **_tmp;							      \
-    (argc) = *(long int *) cookie;					      \
-    (argv) = (char **) ((long int *) cookie + 1);			      \
-    (envp) = (argv) + (argc) + 1;					      \
-    for (_tmp = (void **) (envp); *_tmp; ++_tmp)			      \
-      continue;								      \
-    (auxp) = (void *) ++_tmp;						      \
-  } while (0)
-#endif
-
 #ifndef DL_STACK_END
 # define DL_STACK_END(cookie) ((void *) (cookie))
 #endif
@@ -90,8 +77,16 @@ _dl_sysdep_start (void **start_argptr,
 #endif
 
   __libc_stack_end = DL_STACK_END (start_argptr);
-  DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ,
-			  GLRO(dl_auxv));
+  _dl_argc = (intptr_t) *start_argptr;
+  _dl_argv = (char **) (start_argptr + 1); /* Necessary aliasing violation.  */
+  _environ = _dl_argv + _dl_argc + 1;
+  for (char **tmp = _environ + 1; ; ++tmp)
+    if (*tmp == NULL)
+      {
+	/* Another necessary aliasing violation.  */
+	GLRO(dl_auxv) = (ElfW(auxv_t) *) (tmp + 1);
+	break;
+      }
 
   user_entry = (ElfW(Addr)) ENTRY_POINT;
   GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
-- 
2.34.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/5] Linux: Assume that NEED_DL_SYSINFO_DSO is always defined
  2022-01-11 18:43 [PATCH 0/5] Linux: Auxiliary vector parsing cleanups Florian Weimer
                   ` (2 preceding siblings ...)
  2022-01-11 18:43 ` [PATCH 3/5] Linux: Remove DL_FIND_ARG_COMPONENTS Florian Weimer
@ 2022-01-11 18:44 ` Florian Weimer
  2022-01-11 18:44 ` [PATCH 5/5] Linux: Consolidate auxiliary vector parsing Florian Weimer
  4 siblings, 0 replies; 6+ messages in thread
From: Florian Weimer @ 2022-01-11 18:44 UTC (permalink / raw)
  To: libc-alpha

The definition itself is still needed for generic code.
---
 sysdeps/unix/sysv/linux/dl-sysdep.c   | 8 ++------
 sysdeps/unix/sysv/linux/m68k/sysdep.h | 4 +---
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c
index a13e0ea7ad..2bda76b820 100644
--- a/sysdeps/unix/sysv/linux/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c
@@ -134,11 +134,9 @@ _dl_sysdep_start (void **start_argptr,
 	new_sysinfo = av->a_un.a_val;
 	break;
 #endif
-#ifdef NEED_DL_SYSINFO_DSO
       case AT_SYSINFO_EHDR:
 	GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val;
 	break;
-#endif
       case AT_RANDOM:
 	_dl_random = (void *) av->a_un.a_val;
 	break;
@@ -153,10 +151,8 @@ _dl_sysdep_start (void **start_argptr,
 #ifdef NEED_DL_SYSINFO
   if (new_sysinfo != 0)
     {
-# ifdef NEED_DL_SYSINFO_DSO
       /* Only set the sysinfo value if we also have the vsyscall DSO.  */
       if (GLRO(dl_sysinfo_dso) != 0)
-# endif
         GLRO(dl_sysinfo) = new_sysinfo;
     }
 #endif
@@ -309,7 +305,7 @@ int
 attribute_hidden
 _dl_discover_osversion (void)
 {
-#if defined NEED_DL_SYSINFO_DSO && defined SHARED
+#ifdef SHARED
   if (GLRO(dl_sysinfo_map) != NULL)
     {
       /* If the kernel-supplied DSO contains a note indicating the kernel's
@@ -340,7 +336,7 @@ _dl_discover_osversion (void)
 	      }
 	  }
     }
-#endif
+#endif /* SHARED */
 
   char bufmem[64];
   char *buf = bufmem;
diff --git a/sysdeps/unix/sysv/linux/m68k/sysdep.h b/sysdeps/unix/sysv/linux/m68k/sysdep.h
index 628e1be835..d87892a377 100644
--- a/sysdeps/unix/sysv/linux/m68k/sysdep.h
+++ b/sysdeps/unix/sysv/linux/m68k/sysdep.h
@@ -299,8 +299,6 @@ SYSCALL_ERROR_LABEL:							      \
 #define PTR_MANGLE(var) (void) (var)
 #define PTR_DEMANGLE(var) (void) (var)
 
-#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
 /* M68K needs system-supplied DSO to access TLS helpers
    even when statically linked.  */
-# define NEED_STATIC_SYSINFO_DSO 1
-#endif
+#define NEED_STATIC_SYSINFO_DSO 1
-- 
2.34.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 5/5] Linux: Consolidate auxiliary vector parsing
  2022-01-11 18:43 [PATCH 0/5] Linux: Auxiliary vector parsing cleanups Florian Weimer
                   ` (3 preceding siblings ...)
  2022-01-11 18:44 ` [PATCH 4/5] Linux: Assume that NEED_DL_SYSINFO_DSO is always defined Florian Weimer
@ 2022-01-11 18:44 ` Florian Weimer
  4 siblings, 0 replies; 6+ messages in thread
From: Florian Weimer @ 2022-01-11 18:44 UTC (permalink / raw)
  To: libc-alpha

And optimize it slightly.

The large switch statement in _dl_sysdep_start can be replaced with
a large array.  This reduces source code and binary size.  On
i686-linux-gnu:

Before:

   text	   data	    bss	    dec	    hex	filename
   7791	     12	      0	   7803	   1e7b	elf/dl-sysdep.os

After:

   text	   data	    bss	    dec	    hex	filename
   7135	     12	      0	   7147	   1beb	elf/dl-sysdep.os
---
 elf/dl-support.c                             |  80 +------------
 sysdeps/unix/sysv/linux/alpha/dl-auxv.h      |  18 +--
 sysdeps/unix/sysv/linux/dl-parse_auxv.h      |  61 ++++++++++
 sysdeps/unix/sysv/linux/dl-sysdep.c          | 111 ++++++-------------
 sysdeps/unix/sysv/linux/powerpc/dl-auxv.h    |  14 +--
 sysdeps/unix/sysv/linux/powerpc/dl-support.c |   4 +
 6 files changed, 107 insertions(+), 181 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/dl-parse_auxv.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/dl-support.c

diff --git a/elf/dl-support.c b/elf/dl-support.c
index fb64765537..0fff62064a 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -241,93 +241,21 @@ __rtld_lock_define_initialized_recursive (, _dl_load_tls_lock)
 
 
 #ifdef HAVE_AUX_VECTOR
+#include <dl-parse_auxv.h>
+
 int _dl_clktck;
 
 void
 _dl_aux_init (ElfW(auxv_t) *av)
 {
-  int seen = 0;
-  uid_t uid = 0;
-  gid_t gid = 0;
-
 #ifdef NEED_DL_SYSINFO
   /* NB: Avoid RELATIVE relocation in static PIE.  */
   GL(dl_sysinfo) = DL_SYSINFO_DEFAULT;
 #endif
 
   _dl_auxv = av;
-  for (; av->a_type != AT_NULL; ++av)
-    switch (av->a_type)
-      {
-      case AT_PAGESZ:
-	if (av->a_un.a_val != 0)
-	  GLRO(dl_pagesize) = av->a_un.a_val;
-	break;
-      case AT_CLKTCK:
-	GLRO(dl_clktck) = av->a_un.a_val;
-	break;
-      case AT_PHDR:
-	GL(dl_phdr) = (const void *) av->a_un.a_val;
-	break;
-      case AT_PHNUM:
-	GL(dl_phnum) = av->a_un.a_val;
-	break;
-      case AT_PLATFORM:
-	GLRO(dl_platform) = (void *) av->a_un.a_val;
-	break;
-      case AT_HWCAP:
-	GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
-	break;
-      case AT_HWCAP2:
-	GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val;
-	break;
-      case AT_FPUCW:
-	GLRO(dl_fpu_control) = av->a_un.a_val;
-	break;
-#ifdef NEED_DL_SYSINFO
-      case AT_SYSINFO:
-	GL(dl_sysinfo) = av->a_un.a_val;
-	break;
-#endif
-#ifdef NEED_DL_SYSINFO_DSO
-      case AT_SYSINFO_EHDR:
-	GL(dl_sysinfo_dso) = (void *) av->a_un.a_val;
-	break;
-#endif
-      case AT_UID:
-	uid ^= av->a_un.a_val;
-	seen |= 1;
-	break;
-      case AT_EUID:
-	uid ^= av->a_un.a_val;
-	seen |= 2;
-	break;
-      case AT_GID:
-	gid ^= av->a_un.a_val;
-	seen |= 4;
-	break;
-      case AT_EGID:
-	gid ^= av->a_un.a_val;
-	seen |= 8;
-	break;
-      case AT_SECURE:
-	seen = -1;
-	__libc_enable_secure = av->a_un.a_val;
-	__libc_enable_secure_decided = 1;
-	break;
-      case AT_RANDOM:
-	_dl_random = (void *) av->a_un.a_val;
-	break;
-      case AT_MINSIGSTKSZ:
-	_dl_minsigstacksize = av->a_un.a_val;
-	break;
-      DL_PLATFORM_AUXV
-      }
-  if (seen == 0xf)
-    {
-      __libc_enable_secure = uid != 0 || gid != 0;
-      __libc_enable_secure_decided = 1;
-    }
+  dl_parse_auxv_t auxv_values = { 0, };
+  _dl_parse_auxv (av, auxv_values);
 }
 #endif
 
diff --git a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h
index 81d90da095..fcec743239 100644
--- a/sysdeps/unix/sysv/linux/alpha/dl-auxv.h
+++ b/sysdeps/unix/sysv/linux/alpha/dl-auxv.h
@@ -20,16 +20,8 @@
 
 extern long __libc_alpha_cache_shape[4];
 
-#define DL_PLATFORM_AUXV				\
-      case AT_L1I_CACHESHAPE:				\
-	__libc_alpha_cache_shape[0] = av->a_un.a_val;	\
-	break;						\
-      case AT_L1D_CACHESHAPE:				\
-	__libc_alpha_cache_shape[1] = av->a_un.a_val;	\
-	break;						\
-      case AT_L2_CACHESHAPE:				\
-	__libc_alpha_cache_shape[2] = av->a_un.a_val;	\
-	break;						\
-      case AT_L3_CACHESHAPE:				\
-	__libc_alpha_cache_shape[3] = av->a_un.a_val;	\
-	break;
+#define DL_PLATFORM_AUXV					\
+  __libc_alpha_cache_shape[0] = auxv_values[AT_L1I_CACHESHAPE]; \
+  __libc_alpha_cache_shape[1] = auxv_values[AT_L1D_CACHESHAPE]; \
+  __libc_alpha_cache_shape[2] = auxv_values[AT_L2_CACHESHAPE];	\
+  __libc_alpha_cache_shape[3] = auxv_values[AT_L3_CACHESHAPE];
diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h
new file mode 100644
index 0000000000..f450c6c5ce
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h
@@ -0,0 +1,61 @@
+/* Parse the Linux auxiliary vector.
+   Copyright (C) 1995-2022 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/>.  */
+
+#include <elf.h>
+#include <entry.h>
+#include <fpu_control.h>
+#include <ldsodefs.h>
+#include <link.h>
+
+typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1];
+
+/* Copy the auxiliary vector into AUX_VALUES and set up GLRO
+   variables.  */
+static inline
+void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values)
+{
+  auxv_values[AT_ENTRY] =  (ElfW(Addr)) ENTRY_POINT;
+  auxv_values[AT_PAGESZ] = EXEC_PAGESIZE;
+  auxv_values[AT_FPUCW] = _FPU_DEFAULT;
+
+  /* NB: Default to a constant CONSTANT_MINSIGSTKSZ.  */
+  _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ),
+                  "CONSTANT_MINSIGSTKSZ is constant");
+  auxv_values[AT_MINSIGSTKSZ] = CONSTANT_MINSIGSTKSZ;
+
+  for (; av->a_type != AT_NULL; av++)
+    if (av->a_type <= AT_MINSIGSTKSZ)
+      auxv_values[av->a_type] = av->a_un.a_val;
+
+  GLRO(dl_pagesize) = auxv_values[AT_PAGESZ];
+  __libc_enable_secure = auxv_values[AT_SECURE];
+  GLRO(dl_platform) = (void *) auxv_values[AT_PLATFORM];
+  GLRO(dl_hwcap) = auxv_values[AT_HWCAP];
+  GLRO(dl_hwcap2) = auxv_values[AT_HWCAP2];
+  GLRO(dl_clktck) = auxv_values[AT_CLKTCK];
+  GLRO(dl_fpu_control) = auxv_values[AT_FPUCW];
+  _dl_random = (void *) auxv_values[AT_RANDOM];
+  GLRO(dl_minsigstacksize) = auxv_values[AT_MINSIGSTKSZ];
+  GLRO(dl_sysinfo_dso) = (void *) auxv_values[AT_SYSINFO_EHDR];
+#ifdef NEED_DL_SYSINFO
+  if (GLRO(dl_sysinfo_dso) != NULL)
+    GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO];
+#endif
+
+  DL_PLATFORM_AUXV
+}
diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c
index 2bda76b820..71cf1968b5 100644
--- a/sysdeps/unix/sysv/linux/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c
@@ -21,13 +21,12 @@
 #include <dl-auxv.h>
 #include <dl-hwcap-check.h>
 #include <dl-osinfo.h>
+#include <dl-parse_auxv.h>
 #include <dl-procinfo.h>
 #include <dl-tunables.h>
 #include <elf.h>
-#include <entry.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <fpu_control.h>
 #include <ldsodefs.h>
 #include <libc-internal.h>
 #include <libintl.h>
@@ -63,24 +62,24 @@ void *_dl_random attribute_relro = NULL;
 # define DL_STACK_END(cookie) ((void *) (cookie))
 #endif
 
-ElfW(Addr)
-_dl_sysdep_start (void **start_argptr,
-		  void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
-				   ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv))
+/* Arguments passed to dl_main.  */
+struct dl_main_arguments
 {
-  const ElfW(Phdr) *phdr = NULL;
-  ElfW(Word) phnum = 0;
+  const ElfW(Phdr) *phdr;
+  ElfW(Word) phnum;
   ElfW(Addr) user_entry;
-  ElfW(auxv_t) *av;
-#ifdef NEED_DL_SYSINFO
-  uintptr_t new_sysinfo = 0;
-#endif
+};
 
-  __libc_stack_end = DL_STACK_END (start_argptr);
+/* Separate function, so that dl_main can be called without the large
+   array on the stack.  */
+static void
+_dl_sysdep_parse_arguments (void **start_argptr,
+			    struct dl_main_arguments *args)
+{
   _dl_argc = (intptr_t) *start_argptr;
   _dl_argv = (char **) (start_argptr + 1); /* Necessary aliasing violation.  */
   _environ = _dl_argv + _dl_argc + 1;
-  for (char **tmp = _environ + 1; ; ++tmp)
+  for (char **tmp = _environ; ; ++tmp)
     if (*tmp == NULL)
       {
 	/* Another necessary aliasing violation.  */
@@ -88,74 +87,25 @@ _dl_sysdep_start (void **start_argptr,
 	break;
       }
 
-  user_entry = (ElfW(Addr)) ENTRY_POINT;
-  GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
+  dl_parse_auxv_t auxv_values = { 0, };
+  _dl_parse_auxv (GLRO(dl_auxv), auxv_values);
 
-  /* NB: Default to a constant CONSTANT_MINSIGSTKSZ.  */
-  _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ),
-		  "CONSTANT_MINSIGSTKSZ is constant");
-  GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ;
+  args->phdr = (const ElfW(Phdr) *) auxv_values[AT_PHDR];
+  args->phnum = auxv_values[AT_PHNUM];
+  args->user_entry = auxv_values[AT_ENTRY];
+}
 
-  for (av = GLRO(dl_auxv); av->a_type != AT_NULL; av++)
-    switch (av->a_type)
-      {
-      case AT_PHDR:
-	phdr = (void *) av->a_un.a_val;
-	break;
-      case AT_PHNUM:
-	phnum = av->a_un.a_val;
-	break;
-      case AT_PAGESZ:
-	GLRO(dl_pagesize) = av->a_un.a_val;
-	break;
-      case AT_ENTRY:
-	user_entry = av->a_un.a_val;
-	break;
-      case AT_SECURE:
-	__libc_enable_secure = av->a_un.a_val;
-	break;
-      case AT_PLATFORM:
-	GLRO(dl_platform) = (void *) av->a_un.a_val;
-	break;
-      case AT_HWCAP:
-	GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
-	break;
-      case AT_HWCAP2:
-	GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val;
-	break;
-      case AT_CLKTCK:
-	GLRO(dl_clktck) = av->a_un.a_val;
-	break;
-      case AT_FPUCW:
-	GLRO(dl_fpu_control) = av->a_un.a_val;
-	break;
-#ifdef NEED_DL_SYSINFO
-      case AT_SYSINFO:
-	new_sysinfo = av->a_un.a_val;
-	break;
-#endif
-      case AT_SYSINFO_EHDR:
-	GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val;
-	break;
-      case AT_RANDOM:
-	_dl_random = (void *) av->a_un.a_val;
-	break;
-      case AT_MINSIGSTKSZ:
-	GLRO(dl_minsigstacksize) = av->a_un.a_val;
-	break;
-      DL_PLATFORM_AUXV
-      }
+ElfW(Addr)
+_dl_sysdep_start (void **start_argptr,
+		  void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
+				   ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv))
+{
+  __libc_stack_end = DL_STACK_END (start_argptr);
 
-  dl_hwcap_check ();
+  struct dl_main_arguments dl_main_args;
+  _dl_sysdep_parse_arguments (start_argptr, &dl_main_args);
 
-#ifdef NEED_DL_SYSINFO
-  if (new_sysinfo != 0)
-    {
-      /* Only set the sysinfo value if we also have the vsyscall DSO.  */
-      if (GLRO(dl_sysinfo_dso) != 0)
-        GLRO(dl_sysinfo) = new_sysinfo;
-    }
-#endif
+  dl_hwcap_check ();
 
   __tunables_init (_environ);
 
@@ -187,8 +137,9 @@ _dl_sysdep_start (void **start_argptr,
   if (__builtin_expect (__libc_enable_secure, 0))
     __libc_check_standard_fds ();
 
-  (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv));
-  return user_entry;
+  (*dl_main) (dl_main_args.phdr, dl_main_args.phnum,
+              &dl_main_args.user_entry, GLRO(dl_auxv));
+  return dl_main_args.user_entry;
 }
 
 void
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h
index 594371940a..ce2281cf11 100644
--- a/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h
+++ b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h
@@ -16,15 +16,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <ldsodefs.h>
-
-#if IS_IN (libc) && !defined SHARED
-int GLRO(dl_cache_line_size);
-#endif
-
-/* Scan the Aux Vector for the "Data Cache Block Size" entry and assign it
-   to dl_cache_line_size.  */
-#define DL_PLATFORM_AUXV						      \
-      case AT_DCACHEBSIZE:						      \
-	GLRO(dl_cache_line_size) = av->a_un.a_val;			      \
-	break;
+#define DL_PLATFORM_AUXV \
+  GLRO(dl_cache_line_size) = auxv_values[AT_DCACHEBSIZE];
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-support.c b/sysdeps/unix/sysv/linux/powerpc/dl-support.c
new file mode 100644
index 0000000000..abe68a7049
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/dl-support.c
@@ -0,0 +1,4 @@
+#include <elf/dl-support.c>
+
+/* Populated from the auxiliary vector.  */
+int _dl_cache_line_size;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-01-11 18:44 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-11 18:43 [PATCH 0/5] Linux: Auxiliary vector parsing cleanups Florian Weimer
2022-01-11 18:43 ` [PATCH 1/5] elf: Merge dl-sysdep.c into the Linux version Florian Weimer
2022-01-11 18:43 ` [PATCH 2/5] Linux: Remove HAVE_AUX_SECURE, HAVE_AUX_XID, HAVE_AUX_PAGESIZE Florian Weimer
2022-01-11 18:43 ` [PATCH 3/5] Linux: Remove DL_FIND_ARG_COMPONENTS Florian Weimer
2022-01-11 18:44 ` [PATCH 4/5] Linux: Assume that NEED_DL_SYSINFO_DSO is always defined Florian Weimer
2022-01-11 18:44 ` [PATCH 5/5] Linux: Consolidate auxiliary vector parsing Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).