e354a5
commit 2bf9e641fd50ec34b04b70829679abf64fc0ed78
e354a5
Author: Florian Weimer <fweimer@redhat.com>
e354a5
Date:   Thu Oct 8 10:57:09 2020 +0200
e354a5
e354a5
    elf: Extract command-line/environment variables state from rtld.c
e354a5
    
e354a5
    Introduce struct dl_main_state and move it to <dl-main.h>.  Rename
e354a5
    enum mode to enum rtld_mode and add the rtld_mode_ prefix to the enum
e354a5
    constants.
e354a5
    
e354a5
    This avoids the need for putting state that is only needed during
e354a5
    startup into the ld.so data segment.
e354a5
e354a5
Conflicts:
e354a5
	elf/rtld.c
e354a5
	  (Caused by glibc-fedora-__libc_multiple_libcs.patch.)
e354a5
e354a5
diff --git a/elf/dl-main.h b/elf/dl-main.h
e354a5
new file mode 100644
e354a5
index 0000000000000000..bcc9bcf2e8fee6e7
e354a5
--- /dev/null
e354a5
+++ b/elf/dl-main.h
e354a5
@@ -0,0 +1,98 @@
e354a5
+/* Information collection during ld.so startup.
e354a5
+   Copyright (C) 1995-2020 Free Software Foundation, Inc.
e354a5
+   This file is part of the GNU C Library.
e354a5
+
e354a5
+   The GNU C Library is free software; you can redistribute it and/or
e354a5
+   modify it under the terms of the GNU Lesser General Public
e354a5
+   License as published by the Free Software Foundation; either
e354a5
+   version 2.1 of the License, or (at your option) any later version.
e354a5
+
e354a5
+   The GNU C Library is distributed in the hope that it will be useful,
e354a5
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
e354a5
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
e354a5
+   Lesser General Public License for more details.
e354a5
+
e354a5
+   You should have received a copy of the GNU Lesser General Public
e354a5
+   License along with the GNU C Library; if not, see
e354a5
+   <https://www.gnu.org/licenses/>.  */
e354a5
+
e354a5
+#ifndef _DL_MAIN
e354a5
+#define _DL_MAIN
e354a5
+
e354a5
+#include <limits.h>
e354a5
+
e354a5
+/* Length limits for names and paths, to protect the dynamic linker,
e354a5
+   particularly when __libc_enable_secure is active.  */
e354a5
+#ifdef NAME_MAX
e354a5
+# define SECURE_NAME_LIMIT NAME_MAX
e354a5
+#else
e354a5
+# define SECURE_NAME_LIMIT 255
e354a5
+#endif
e354a5
+#ifdef PATH_MAX
e354a5
+# define SECURE_PATH_LIMIT PATH_MAX
e354a5
+#else
e354a5
+# define SECURE_PATH_LIMIT 1024
e354a5
+#endif
e354a5
+
e354a5
+/* Strings containing colon-separated lists of audit modules.  */
e354a5
+struct audit_list
e354a5
+{
e354a5
+  /* Array of strings containing colon-separated path lists.  Each
e354a5
+     audit module needs its own namespace, so pre-allocate the largest
e354a5
+     possible list.  */
e354a5
+  const char *audit_strings[DL_NNS];
e354a5
+
e354a5
+  /* Number of entries added to audit_strings.  */
e354a5
+  size_t length;
e354a5
+
e354a5
+  /* Index into the audit_strings array (for the iteration phase).  */
e354a5
+  size_t current_index;
e354a5
+
e354a5
+  /* Tail of audit_strings[current_index] which still needs
e354a5
+     processing.  */
e354a5
+  const char *current_tail;
e354a5
+
e354a5
+  /* Scratch buffer for returning a name which is part of the strings
e354a5
+     in audit_strings.  */
e354a5
+  char fname[SECURE_NAME_LIMIT];
e354a5
+};
e354a5
+
e354a5
+/* This is a list of all the modes the dynamic loader can be in.  */
e354a5
+enum rtld_mode
e354a5
+  {
e354a5
+    rtld_mode_normal, rtld_mode_list, rtld_mode_verify, rtld_mode_trace,
e354a5
+  };
e354a5
+
e354a5
+/* Aggregated state information extracted from environment variables
e354a5
+   and the ld.so command line.  */
e354a5
+struct dl_main_state
e354a5
+{
e354a5
+  struct audit_list audit_list;
e354a5
+
e354a5
+  /* The library search path.  */
e354a5
+  const char *library_path;
e354a5
+
e354a5
+  /* The list preloaded objects from LD_PRELOAD.  */
e354a5
+  const char *preloadlist;
e354a5
+
e354a5
+  /* The preload list passed as a command argument.  */
e354a5
+  const char *preloadarg;
e354a5
+
e354a5
+  enum rtld_mode mode;
e354a5
+
e354a5
+  /* True if any of the debugging options is enabled.  */
e354a5
+  bool any_debug;
e354a5
+
e354a5
+  /* True if information about versions has to be printed.  */
e354a5
+  bool version_info;
e354a5
+};
e354a5
+
e354a5
+/* Helper function to invoke _dl_init_paths with the right arguments
e354a5
+   from *STATE.  */
e354a5
+static inline void
e354a5
+call_init_paths (const struct dl_main_state *state)
e354a5
+{
e354a5
+  _dl_init_paths (state->library_path);
e354a5
+}
e354a5
+
e354a5
+#endif /* _DL_MAIN */
e354a5
diff --git a/elf/rtld.c b/elf/rtld.c
e354a5
index 4107a215abd554f4..fbfa441bf3b050ff 100644
e354a5
--- a/elf/rtld.c
e354a5
+++ b/elf/rtld.c
e354a5
@@ -45,6 +45,7 @@
e354a5
 #include <not-cancel.h>
e354a5
 #include <array_length.h>
e354a5
 #include <libc-early-init.h>
e354a5
+#include <dl-main.h>
e354a5
 
e354a5
 #include <assert.h>
e354a5
 
e354a5
@@ -109,42 +110,6 @@ static void print_missing_version (int errcode, const char *objname,
e354a5
 /* Print the various times we collected.  */
e354a5
 static void print_statistics (const hp_timing_t *total_timep);
e354a5
 
e354a5
-/* Length limits for names and paths, to protect the dynamic linker,
e354a5
-   particularly when __libc_enable_secure is active.  */
e354a5
-#ifdef NAME_MAX
e354a5
-# define SECURE_NAME_LIMIT NAME_MAX
e354a5
-#else
e354a5
-# define SECURE_NAME_LIMIT 255
e354a5
-#endif
e354a5
-#ifdef PATH_MAX
e354a5
-# define SECURE_PATH_LIMIT PATH_MAX
e354a5
-#else
e354a5
-# define SECURE_PATH_LIMIT 1024
e354a5
-#endif
e354a5
-
e354a5
-/* Strings containing colon-separated lists of audit modules.  */
e354a5
-struct audit_list
e354a5
-{
e354a5
-  /* Array of strings containing colon-separated path lists.  Each
e354a5
-     audit module needs its own namespace, so pre-allocate the largest
e354a5
-     possible list.  */
e354a5
-  const char *audit_strings[DL_NNS];
e354a5
-
e354a5
-  /* Number of entries added to audit_strings.  */
e354a5
-  size_t length;
e354a5
-
e354a5
-  /* Index into the audit_strings array (for the iteration phase).  */
e354a5
-  size_t current_index;
e354a5
-
e354a5
-  /* Tail of audit_strings[current_index] which still needs
e354a5
-     processing.  */
e354a5
-  const char *current_tail;
e354a5
-
e354a5
-  /* Scratch buffer for returning a name which is part of the strings
e354a5
-     in audit_strings.  */
e354a5
-  char fname[SECURE_NAME_LIMIT];
e354a5
-};
e354a5
-
e354a5
 /* Creates an empty audit list.  */
e354a5
 static void audit_list_init (struct audit_list *);
e354a5
 
e354a5
@@ -165,13 +130,13 @@ static void audit_list_add_dynamic_tag (struct audit_list *,
e354a5
    audit_list_add_dynamic_tags calls.  */
e354a5
 static const char *audit_list_next (struct audit_list *);
e354a5
 
e354a5
-/* This is a list of all the modes the dynamic loader can be in.  */
e354a5
-enum mode { normal, list, verify, trace };
e354a5
+/* Initialize *STATE with the defaults.  */
e354a5
+static void dl_main_state_init (struct dl_main_state *state);
e354a5
 
e354a5
 /* Process all environments variables the dynamic linker must recognize.
e354a5
    Since all of them start with `LD_' we are a bit smarter while finding
e354a5
    all the entries.  */
e354a5
-static void process_envvars (enum mode *modep, struct audit_list *);
e354a5
+static void process_envvars (struct dl_main_state *state);
e354a5
 
e354a5
 #ifdef DL_ARGV_NOT_RELRO
e354a5
 int _dl_argc attribute_hidden;
e354a5
@@ -314,6 +279,18 @@ audit_list_count (struct audit_list *list)
e354a5
   return naudit;
e354a5
 }
e354a5
 
e354a5
+static void
e354a5
+dl_main_state_init (struct dl_main_state *state)
e354a5
+{
e354a5
+  audit_list_init (&state->audit_list);
e354a5
+  state->library_path = NULL;
e354a5
+  state->preloadlist = NULL;
e354a5
+  state->preloadarg = NULL;
e354a5
+  state->mode = rtld_mode_normal;
e354a5
+  state->any_debug = false;
e354a5
+  state->version_info = false;
e354a5
+}
e354a5
+
e354a5
 /* Set nonzero during loading and initialization of executable and
e354a5
    libraries, cleared before the executable's entry point runs.  This
e354a5
    must not be initialized to nonzero, because the unused dynamic
e354a5
@@ -896,15 +873,6 @@ security_init (void)
e354a5
 
e354a5
 #include "setup-vdso.h"
e354a5
 
e354a5
-/* The library search path.  */
e354a5
-static const char *library_path attribute_relro;
e354a5
-/* The list preloaded objects.  */
e354a5
-static const char *preloadlist attribute_relro;
e354a5
-/* Nonzero if information about versions has to be printed.  */
e354a5
-static int version_info attribute_relro;
e354a5
-/* The preload list passed as a command argument.  */
e354a5
-static const char *preloadarg attribute_relro;
e354a5
-
e354a5
 /* The LD_PRELOAD environment variable gives list of libraries
e354a5
    separated by white space or colons that are loaded before the
e354a5
    executable's dependencies and prepended to the global scope list.
e354a5
@@ -1146,7 +1114,6 @@ dl_main (const ElfW(Phdr) *phdr,
e354a5
 	 ElfW(auxv_t) *auxv)
e354a5
 {
e354a5
   const ElfW(Phdr) *ph;
e354a5
-  enum mode mode;
e354a5
   struct link_map *main_map;
e354a5
   size_t file_size;
e354a5
   char *file;
e354a5
@@ -1156,8 +1123,8 @@ dl_main (const ElfW(Phdr) *phdr,
e354a5
   bool rtld_is_main = false;
e354a5
   void *tcbp = NULL;
e354a5
 
e354a5
-  struct audit_list audit_list;
e354a5
-  audit_list_init (&audit_list);
e354a5
+  struct dl_main_state state;
e354a5
+  dl_main_state_init (&state);
e354a5
 
e354a5
   GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
e354a5
 
e354a5
@@ -1172,7 +1139,7 @@ dl_main (const ElfW(Phdr) *phdr,
e354a5
   GL(dl_make_stack_executable_hook) = &_dl_make_stack_executable;
e354a5
 
e354a5
   /* Process the environment variable which control the behaviour.  */
e354a5
-  process_envvars (&mode, &audit_list);
e354a5
+  process_envvars (&state);
e354a5
 
e354a5
   /* Set up a flag which tells we are just starting.  */
e354a5
   _dl_starting_up = 1;
e354a5
@@ -1204,7 +1171,7 @@ dl_main (const ElfW(Phdr) *phdr,
e354a5
       while (_dl_argc > 1)
e354a5
 	if (! strcmp (_dl_argv[1], "--list"))
e354a5
 	  {
e354a5
-	    mode = list;
e354a5
+	    state.mode = rtld_mode_list;
e354a5
 	    GLRO(dl_lazy) = -1;	/* This means do no dependency analysis.  */
e354a5
 
e354a5
 	    ++_dl_skip_args;
e354a5
@@ -1213,7 +1180,7 @@ dl_main (const ElfW(Phdr) *phdr,
e354a5
 	  }
e354a5
 	else if (! strcmp (_dl_argv[1], "--verify"))
e354a5
 	  {
e354a5
-	    mode = verify;
e354a5
+	    state.mode = rtld_mode_verify;
e354a5
 
e354a5
 	    ++_dl_skip_args;
e354a5
 	    --_dl_argc;
e354a5
@@ -1229,7 +1196,7 @@ dl_main (const ElfW(Phdr) *phdr,
e354a5
 	else if (! strcmp (_dl_argv[1], "--library-path")
e354a5
 		 && _dl_argc > 2)
e354a5
 	  {
e354a5
-	    library_path = _dl_argv[2];
e354a5
+	    state.library_path = _dl_argv[2];
e354a5
 
e354a5
 	    _dl_skip_args += 2;
e354a5
 	    _dl_argc -= 2;
e354a5
@@ -1246,7 +1213,7 @@ dl_main (const ElfW(Phdr) *phdr,
e354a5
 	  }
e354a5
 	else if (! strcmp (_dl_argv[1], "--audit") && _dl_argc > 2)
e354a5
 	  {
e354a5
-	    audit_list_add_string (&audit_list, _dl_argv[2]);
e354a5
+	    audit_list_add_string (&state.audit_list, _dl_argv[2]);
e354a5
 
e354a5
 	    _dl_skip_args += 2;
e354a5
 	    _dl_argc -= 2;
e354a5
@@ -1254,7 +1221,7 @@ dl_main (const ElfW(Phdr) *phdr,
e354a5
 	  }
e354a5
 	else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2)
e354a5
 	  {
e354a5
-	    preloadarg = _dl_argv[2];
e354a5
+	    state.preloadarg = _dl_argv[2];
e354a5
 	    _dl_skip_args += 2;
e354a5
 	    _dl_argc -= 2;
e354a5
 	    _dl_argv += 2;
e354a5
@@ -1322,7 +1289,7 @@ of this helper program; chances are you did not intend to run this program.\n\
e354a5
 	    break;
e354a5
 	  }
e354a5
 
e354a5
-      if (__builtin_expect (mode, normal) == verify)
e354a5
+      if (__glibc_unlikely (state.mode == rtld_mode_verify))
e354a5
 	{
e354a5
 	  const char *objname;
e354a5
 	  const char *err_str = NULL;
e354a5
@@ -1351,7 +1318,7 @@ of this helper program; chances are you did not intend to run this program.\n\
e354a5
       /* Now the map for the main executable is available.  */
e354a5
       main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
e354a5
 
e354a5
-      if (__builtin_expect (mode, normal) == normal
e354a5
+      if (__glibc_likely (state.mode == rtld_mode_normal)
e354a5
 	  && GL(dl_rtld_map).l_info[DT_SONAME] != NULL
e354a5
 	  && main_map->l_info[DT_SONAME] != NULL
e354a5
 	  && strcmp ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
e354a5
@@ -1592,7 +1559,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
       _dl_setup_hash (main_map);
e354a5
     }
e354a5
 
e354a5
-  if (__builtin_expect (mode, normal) == verify)
e354a5
+  if (__glibc_unlikely (state.mode == rtld_mode_verify))
e354a5
     {
e354a5
       /* We were called just to verify that this is a dynamic
e354a5
 	 executable using us as the program interpreter.  Exit with an
e354a5
@@ -1619,7 +1586,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
 
e354a5
   /* Initialize the data structures for the search paths for shared
e354a5
      objects.  */
e354a5
-  _dl_init_paths (library_path);
e354a5
+  call_init_paths (&state);
e354a5
 
e354a5
   /* Initialize _r_debug.  */
e354a5
   struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr,
e354a5
@@ -1684,14 +1651,14 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
     /* Assign a module ID.  Do this before loading any audit modules.  */
e354a5
     GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
e354a5
 
e354a5
-  audit_list_add_dynamic_tag (&audit_list, main_map, DT_AUDIT);
e354a5
-  audit_list_add_dynamic_tag (&audit_list, main_map, DT_DEPAUDIT);
e354a5
+  audit_list_add_dynamic_tag (&state.audit_list, main_map, DT_AUDIT);
e354a5
+  audit_list_add_dynamic_tag (&state.audit_list, main_map, DT_DEPAUDIT);
e354a5
 
e354a5
   /* If we have auditing DSOs to load, do it now.  */
e354a5
   bool need_security_init = true;
e354a5
-  if (audit_list.length > 0)
e354a5
+  if (state.audit_list.length > 0)
e354a5
     {
e354a5
-      size_t naudit = audit_list_count (&audit_list);
e354a5
+      size_t naudit = audit_list_count (&state.audit_list);
e354a5
 
e354a5
       /* Since we start using the auditing DSOs right away we need to
e354a5
 	 initialize the data structures now.  */
e354a5
@@ -1704,7 +1671,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
       security_init ();
e354a5
       need_security_init = false;
e354a5
 
e354a5
-      load_audit_modules (main_map, &audit_list);
e354a5
+      load_audit_modules (main_map, &state.audit_list);
e354a5
 
e354a5
       /* The count based on audit strings may overestimate the number
e354a5
 	 of audit modules that got loaded, but not underestimate.  */
e354a5
@@ -1759,19 +1726,21 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
   struct link_map **preloads = NULL;
e354a5
   unsigned int npreloads = 0;
e354a5
 
e354a5
-  if (__glibc_unlikely (preloadlist != NULL))
e354a5
+  if (__glibc_unlikely (state.preloadlist != NULL))
e354a5
     {
e354a5
       RTLD_TIMING_VAR (start);
e354a5
       rtld_timer_start (&start;;
e354a5
-      npreloads += handle_preload_list (preloadlist, main_map, "LD_PRELOAD");
e354a5
+      npreloads += handle_preload_list (state.preloadlist, main_map,
e354a5
+					"LD_PRELOAD");
e354a5
       rtld_timer_accum (&load_time, start);
e354a5
     }
e354a5
 
e354a5
-  if (__glibc_unlikely (preloadarg != NULL))
e354a5
+  if (__glibc_unlikely (state.preloadarg != NULL))
e354a5
     {
e354a5
       RTLD_TIMING_VAR (start);
e354a5
       rtld_timer_start (&start;;
e354a5
-      npreloads += handle_preload_list (preloadarg, main_map, "--preload");
e354a5
+      npreloads += handle_preload_list (state.preloadarg, main_map,
e354a5
+					"--preload");
e354a5
       rtld_timer_accum (&load_time, start);
e354a5
     }
e354a5
 
e354a5
@@ -1878,7 +1847,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
   {
e354a5
     RTLD_TIMING_VAR (start);
e354a5
     rtld_timer_start (&start;;
e354a5
-    _dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0);
e354a5
+    _dl_map_object_deps (main_map, preloads, npreloads,
e354a5
+			 state.mode == rtld_mode_trace, 0);
e354a5
     rtld_timer_accum (&load_time, start);
e354a5
   }
e354a5
 
e354a5
@@ -1905,7 +1875,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
       rtld_multiple_ref = true;
e354a5
 
e354a5
       GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1];
e354a5
-      if (__builtin_expect (mode, normal) == normal)
e354a5
+      if (__glibc_likely (state.mode == rtld_mode_normal))
e354a5
 	{
e354a5
 	  GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist
e354a5
 				    ? main_map->l_searchlist.r_list[i + 1]
e354a5
@@ -1938,8 +1908,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
      versions we need.  */
e354a5
   {
e354a5
     struct version_check_args args;
e354a5
-    args.doexit = mode == normal;
e354a5
-    args.dotrace = mode == trace;
e354a5
+    args.doexit = state.mode == rtld_mode_normal;
e354a5
+    args.dotrace = state.mode == rtld_mode_trace;
e354a5
     _dl_receive_error (print_missing_version, version_check_doit, &args);
e354a5
   }
e354a5
 
e354a5
@@ -1959,7 +1929,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
        earlier.  */
e354a5
     security_init ();
e354a5
 
e354a5
-  if (__builtin_expect (mode, normal) != normal)
e354a5
+  if (__glibc_unlikely (state.mode != rtld_mode_normal))
e354a5
     {
e354a5
       /* We were run just to list the shared libraries.  It is
e354a5
 	 important that we do this before real relocation, because the
e354a5
@@ -2061,7 +2031,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
 			  (size_t) l->l_map_start);
e354a5
 	}
e354a5
 
e354a5
-      if (__builtin_expect (mode, trace) != trace)
e354a5
+      if (__glibc_unlikely (state.mode != rtld_mode_trace))
e354a5
 	for (i = 1; i < (unsigned int) _dl_argc; ++i)
e354a5
 	  {
e354a5
 	    const ElfW(Sym) *ref = NULL;
e354a5
@@ -2115,7 +2085,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
e354a5
 		}
e354a5
 	    }
e354a5
 #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
e354a5
-	  if (version_info)
e354a5
+	  if (state.version_info)
e354a5
 	    {
e354a5
 	      /* Print more information.  This means here, print information
e354a5
 		 about the versions needed.  */
e354a5
@@ -2477,13 +2447,10 @@ print_missing_version (int errcode __attribute__ ((unused)),
e354a5
 		    objname, errstring);
e354a5
 }
e354a5
 
e354a5
-/* Nonzero if any of the debugging options is enabled.  */
e354a5
-static int any_debug attribute_relro;
e354a5
-
e354a5
 /* Process the string given as the parameter which explains which debugging
e354a5
    options are enabled.  */
e354a5
 static void
e354a5
-process_dl_debug (const char *dl_debug)
e354a5
+process_dl_debug (struct dl_main_state *state, const char *dl_debug)
e354a5
 {
e354a5
   /* When adding new entries make sure that the maximal length of a name
e354a5
      is correctly handled in the LD_DEBUG_HELP code below.  */
e354a5
@@ -2540,7 +2507,7 @@ process_dl_debug (const char *dl_debug)
e354a5
 		&& memcmp (dl_debug, debopts[cnt].name, len) == 0)
e354a5
 	      {
e354a5
 		GLRO(dl_debug_mask) |= debopts[cnt].mask;
e354a5
-		any_debug = 1;
e354a5
+		state->any_debug = true;
e354a5
 		break;
e354a5
 	      }
e354a5
 
e354a5
@@ -2594,11 +2561,10 @@ extern char **_environ attribute_hidden;
e354a5
 
e354a5
 
e354a5
 static void
e354a5
-process_envvars (enum mode *modep, struct audit_list *audit_list)
e354a5
+process_envvars (struct dl_main_state *state)
e354a5
 {
e354a5
   char **runp = _environ;
e354a5
   char *envline;
e354a5
-  enum mode mode = normal;
e354a5
   char *debug_output = NULL;
e354a5
 
e354a5
   /* This is the default place for profiling data file.  */
e354a5
@@ -2630,25 +2596,25 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
e354a5
 	  /* Debugging of the dynamic linker?  */
e354a5
 	  if (memcmp (envline, "DEBUG", 5) == 0)
e354a5
 	    {
e354a5
-	      process_dl_debug (&envline[6]);
e354a5
+	      process_dl_debug (state, &envline[6]);
e354a5
 	      break;
e354a5
 	    }
e354a5
 	  if (memcmp (envline, "AUDIT", 5) == 0)
e354a5
-	    audit_list_add_string (audit_list, &envline[6]);
e354a5
+	    audit_list_add_string (&state->audit_list, &envline[6]);
e354a5
 	  break;
e354a5
 
e354a5
 	case 7:
e354a5
 	  /* Print information about versions.  */
e354a5
 	  if (memcmp (envline, "VERBOSE", 7) == 0)
e354a5
 	    {
e354a5
-	      version_info = envline[8] != '\0';
e354a5
+	      state->version_info = envline[8] != '\0';
e354a5
 	      break;
e354a5
 	    }
e354a5
 
e354a5
 	  /* List of objects to be preloaded.  */
e354a5
 	  if (memcmp (envline, "PRELOAD", 7) == 0)
e354a5
 	    {
e354a5
-	      preloadlist = &envline[8];
e354a5
+	      state->preloadlist = &envline[8];
e354a5
 	      break;
e354a5
 	    }
e354a5
 
e354a5
@@ -2697,7 +2663,7 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
e354a5
 	  if (!__libc_enable_secure
e354a5
 	      && memcmp (envline, "LIBRARY_PATH", 12) == 0)
e354a5
 	    {
e354a5
-	      library_path = &envline[13];
e354a5
+	      state->library_path = &envline[13];
e354a5
 	      break;
e354a5
 	    }
e354a5
 
e354a5
@@ -2739,7 +2705,7 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
e354a5
 	  /* The mode of the dynamic linker can be set.  */
e354a5
 	  if (memcmp (envline, "TRACE_PRELINKING", 16) == 0)
e354a5
 	    {
e354a5
-	      mode = trace;
e354a5
+	      state->mode = rtld_mode_trace;
e354a5
 	      GLRO(dl_verbose) = 1;
e354a5
 	      GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
e354a5
 	      GLRO(dl_trace_prelink) = &envline[17];
e354a5
@@ -2749,7 +2715,7 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
e354a5
 	case 20:
e354a5
 	  /* The mode of the dynamic linker can be set.  */
e354a5
 	  if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
e354a5
-	    mode = trace;
e354a5
+	    state->mode = rtld_mode_trace;
e354a5
 	  break;
e354a5
 
e354a5
 	  /* We might have some extra environment variable to handle.  This
e354a5
@@ -2762,9 +2728,6 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
e354a5
 	}
e354a5
     }
e354a5
 
e354a5
-  /* The caller wants this information.  */
e354a5
-  *modep = mode;
e354a5
-
e354a5
   /* Extra security for SUID binaries.  Remove all dangerous environment
e354a5
      variables.  */
e354a5
   if (__builtin_expect (__libc_enable_secure, 0))
e354a5
@@ -2793,13 +2756,13 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
e354a5
 	  GLRO(dl_debug_mask) = 0;
e354a5
 	}
e354a5
 
e354a5
-      if (mode != normal)
e354a5
+      if (state->mode != rtld_mode_normal)
e354a5
 	_exit (5);
e354a5
     }
e354a5
   /* If we have to run the dynamic linker in debugging mode and the
e354a5
      LD_DEBUG_OUTPUT environment variable is given, we write the debug
e354a5
      messages to this file.  */
e354a5
-  else if (any_debug && debug_output != NULL)
e354a5
+  else if (state->any_debug && debug_output != NULL)
e354a5
     {
e354a5
       const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
e354a5
       size_t name_len = strlen (debug_output);