about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/dl-sysdep.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2022-02-28 11:50:41 +0100
committerFlorian Weimer <fweimer@redhat.com>2022-02-28 11:50:41 +0100
commit73fc4e28b9464f0e13edc719a5372839970e7ddb (patch)
tree62b7c150b29bccc23cda28ac57f60d2d1a973481 /sysdeps/unix/sysv/linux/dl-sysdep.c
parent1fe00d3eb602a0754873b536dc92fb6226759ee4 (diff)
downloadglibc-73fc4e28b9464f0e13edc719a5372839970e7ddb.tar.gz
glibc-73fc4e28b9464f0e13edc719a5372839970e7ddb.tar.xz
glibc-73fc4e28b9464f0e13edc719a5372839970e7ddb.zip
Linux: Consolidate auxiliary vector parsing (redo)
And optimize it slightly.

This is commit 8c8510ab2790039e58995ef3a22309582413d3ff revised.

In _dl_aux_init in elf/dl-support.c, use an explicit loop
and -fno-tree-loop-distribute-patterns to avoid memset.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
Diffstat (limited to 'sysdeps/unix/sysv/linux/dl-sysdep.c')
-rw-r--r--sysdeps/unix/sysv/linux/dl-sysdep.c114
1 files changed, 32 insertions, 82 deletions
diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c
index 8ad72c4b7b..c90f109b11 100644
--- a/sysdeps/unix/sysv/linux/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c
@@ -18,15 +18,14 @@
 
 #include <_itoa.h>
 #include <assert.h>
-#include <dl-hwcap-check.h>
+#include <dl-auxv.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>
@@ -43,10 +42,9 @@
 #include <unistd.h>
 
 #include <dl-machine.h>
+#include <dl-hwcap-check.h>
 
 #ifdef SHARED
-# include <dl-auxv.h>
-
 extern char **_environ attribute_hidden;
 extern char _end[] attribute_hidden;
 
@@ -64,20 +62,20 @@ 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;
@@ -89,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);
 
@@ -188,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