1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-05 19:35:52 +03:00

elf: Extract command-line/environment variables state from rtld.c

Introduce struct dl_main_state and move it to <dl-main.h>.  Rename
enum mode to enum rtld_mode and add the rtld_mode_ prefix to the enum
constants.

This avoids the need for putting state that is only needed during
startup into the ld.so data segment.
This commit is contained in:
Florian Weimer
2020-10-08 10:57:09 +02:00
parent 72d36ffd7d
commit 2bf9e641fd
2 changed files with 157 additions and 96 deletions

98
elf/dl-main.h Normal file
View File

@@ -0,0 +1,98 @@
/* Information collection during ld.so startup.
Copyright (C) 1995-2020 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 _DL_MAIN
#define _DL_MAIN
#include <limits.h>
/* Length limits for names and paths, to protect the dynamic linker,
particularly when __libc_enable_secure is active. */
#ifdef NAME_MAX
# define SECURE_NAME_LIMIT NAME_MAX
#else
# define SECURE_NAME_LIMIT 255
#endif
#ifdef PATH_MAX
# define SECURE_PATH_LIMIT PATH_MAX
#else
# define SECURE_PATH_LIMIT 1024
#endif
/* Strings containing colon-separated lists of audit modules. */
struct audit_list
{
/* Array of strings containing colon-separated path lists. Each
audit module needs its own namespace, so pre-allocate the largest
possible list. */
const char *audit_strings[DL_NNS];
/* Number of entries added to audit_strings. */
size_t length;
/* Index into the audit_strings array (for the iteration phase). */
size_t current_index;
/* Tail of audit_strings[current_index] which still needs
processing. */
const char *current_tail;
/* Scratch buffer for returning a name which is part of the strings
in audit_strings. */
char fname[SECURE_NAME_LIMIT];
};
/* This is a list of all the modes the dynamic loader can be in. */
enum rtld_mode
{
rtld_mode_normal, rtld_mode_list, rtld_mode_verify, rtld_mode_trace,
};
/* Aggregated state information extracted from environment variables
and the ld.so command line. */
struct dl_main_state
{
struct audit_list audit_list;
/* The library search path. */
const char *library_path;
/* The list preloaded objects from LD_PRELOAD. */
const char *preloadlist;
/* The preload list passed as a command argument. */
const char *preloadarg;
enum rtld_mode mode;
/* True if any of the debugging options is enabled. */
bool any_debug;
/* True if information about versions has to be printed. */
bool version_info;
};
/* Helper function to invoke _dl_init_paths with the right arguments
from *STATE. */
static inline void
call_init_paths (const struct dl_main_state *state)
{
_dl_init_paths (state->library_path);
}
#endif /* _DL_MAIN */

View File

@@ -47,6 +47,7 @@
#include <not-cancel.h> #include <not-cancel.h>
#include <array_length.h> #include <array_length.h>
#include <libc-early-init.h> #include <libc-early-init.h>
#include <dl-main.h>
#include <assert.h> #include <assert.h>
@@ -111,42 +112,6 @@ static void print_missing_version (int errcode, const char *objname,
/* Print the various times we collected. */ /* Print the various times we collected. */
static void print_statistics (const hp_timing_t *total_timep); static void print_statistics (const hp_timing_t *total_timep);
/* Length limits for names and paths, to protect the dynamic linker,
particularly when __libc_enable_secure is active. */
#ifdef NAME_MAX
# define SECURE_NAME_LIMIT NAME_MAX
#else
# define SECURE_NAME_LIMIT 255
#endif
#ifdef PATH_MAX
# define SECURE_PATH_LIMIT PATH_MAX
#else
# define SECURE_PATH_LIMIT 1024
#endif
/* Strings containing colon-separated lists of audit modules. */
struct audit_list
{
/* Array of strings containing colon-separated path lists. Each
audit module needs its own namespace, so pre-allocate the largest
possible list. */
const char *audit_strings[DL_NNS];
/* Number of entries added to audit_strings. */
size_t length;
/* Index into the audit_strings array (for the iteration phase). */
size_t current_index;
/* Tail of audit_strings[current_index] which still needs
processing. */
const char *current_tail;
/* Scratch buffer for returning a name which is part of the strings
in audit_strings. */
char fname[SECURE_NAME_LIMIT];
};
/* Creates an empty audit list. */ /* Creates an empty audit list. */
static void audit_list_init (struct audit_list *); static void audit_list_init (struct audit_list *);
@@ -167,13 +132,13 @@ static void audit_list_add_dynamic_tag (struct audit_list *,
audit_list_add_dynamic_tags calls. */ audit_list_add_dynamic_tags calls. */
static const char *audit_list_next (struct audit_list *); static const char *audit_list_next (struct audit_list *);
/* This is a list of all the modes the dynamic loader can be in. */ /* Initialize *STATE with the defaults. */
enum mode { normal, list, verify, trace }; static void dl_main_state_init (struct dl_main_state *state);
/* Process all environments variables the dynamic linker must recognize. /* Process all environments variables the dynamic linker must recognize.
Since all of them start with `LD_' we are a bit smarter while finding Since all of them start with `LD_' we are a bit smarter while finding
all the entries. */ all the entries. */
static void process_envvars (enum mode *modep, struct audit_list *); static void process_envvars (struct dl_main_state *state);
#ifdef DL_ARGV_NOT_RELRO #ifdef DL_ARGV_NOT_RELRO
int _dl_argc attribute_hidden; int _dl_argc attribute_hidden;
@@ -316,6 +281,18 @@ audit_list_count (struct audit_list *list)
return naudit; return naudit;
} }
static void
dl_main_state_init (struct dl_main_state *state)
{
audit_list_init (&state->audit_list);
state->library_path = NULL;
state->preloadlist = NULL;
state->preloadarg = NULL;
state->mode = rtld_mode_normal;
state->any_debug = false;
state->version_info = false;
}
#ifndef HAVE_INLINED_SYSCALLS #ifndef HAVE_INLINED_SYSCALLS
/* Set nonzero during loading and initialization of executable and /* Set nonzero during loading and initialization of executable and
libraries, cleared before the executable's entry point runs. This libraries, cleared before the executable's entry point runs. This
@@ -900,15 +877,6 @@ security_init (void)
#include <setup-vdso.h> #include <setup-vdso.h>
/* The library search path. */
static const char *library_path attribute_relro;
/* The list preloaded objects. */
static const char *preloadlist attribute_relro;
/* Nonzero if information about versions has to be printed. */
static int version_info attribute_relro;
/* The preload list passed as a command argument. */
static const char *preloadarg attribute_relro;
/* The LD_PRELOAD environment variable gives list of libraries /* The LD_PRELOAD environment variable gives list of libraries
separated by white space or colons that are loaded before the separated by white space or colons that are loaded before the
executable's dependencies and prepended to the global scope list. executable's dependencies and prepended to the global scope list.
@@ -1150,7 +1118,6 @@ dl_main (const ElfW(Phdr) *phdr,
ElfW(auxv_t) *auxv) ElfW(auxv_t) *auxv)
{ {
const ElfW(Phdr) *ph; const ElfW(Phdr) *ph;
enum mode mode;
struct link_map *main_map; struct link_map *main_map;
size_t file_size; size_t file_size;
char *file; char *file;
@@ -1160,8 +1127,8 @@ dl_main (const ElfW(Phdr) *phdr,
bool rtld_is_main = false; bool rtld_is_main = false;
void *tcbp = NULL; void *tcbp = NULL;
struct audit_list audit_list; struct dl_main_state state;
audit_list_init (&audit_list); dl_main_state_init (&state);
GL(dl_init_static_tls) = &_dl_nothread_init_static_tls; GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
@@ -1176,7 +1143,7 @@ dl_main (const ElfW(Phdr) *phdr,
GL(dl_make_stack_executable_hook) = &_dl_make_stack_executable; GL(dl_make_stack_executable_hook) = &_dl_make_stack_executable;
/* Process the environment variable which control the behaviour. */ /* Process the environment variable which control the behaviour. */
process_envvars (&mode, &audit_list); process_envvars (&state);
#ifndef HAVE_INLINED_SYSCALLS #ifndef HAVE_INLINED_SYSCALLS
/* Set up a flag which tells we are just starting. */ /* Set up a flag which tells we are just starting. */
@@ -1210,7 +1177,7 @@ dl_main (const ElfW(Phdr) *phdr,
while (_dl_argc > 1) while (_dl_argc > 1)
if (! strcmp (_dl_argv[1], "--list")) if (! strcmp (_dl_argv[1], "--list"))
{ {
mode = list; state.mode = rtld_mode_list;
GLRO(dl_lazy) = -1; /* This means do no dependency analysis. */ GLRO(dl_lazy) = -1; /* This means do no dependency analysis. */
++_dl_skip_args; ++_dl_skip_args;
@@ -1219,7 +1186,7 @@ dl_main (const ElfW(Phdr) *phdr,
} }
else if (! strcmp (_dl_argv[1], "--verify")) else if (! strcmp (_dl_argv[1], "--verify"))
{ {
mode = verify; state.mode = rtld_mode_verify;
++_dl_skip_args; ++_dl_skip_args;
--_dl_argc; --_dl_argc;
@@ -1235,7 +1202,7 @@ dl_main (const ElfW(Phdr) *phdr,
else if (! strcmp (_dl_argv[1], "--library-path") else if (! strcmp (_dl_argv[1], "--library-path")
&& _dl_argc > 2) && _dl_argc > 2)
{ {
library_path = _dl_argv[2]; state.library_path = _dl_argv[2];
_dl_skip_args += 2; _dl_skip_args += 2;
_dl_argc -= 2; _dl_argc -= 2;
@@ -1252,7 +1219,7 @@ dl_main (const ElfW(Phdr) *phdr,
} }
else if (! strcmp (_dl_argv[1], "--audit") && _dl_argc > 2) else if (! strcmp (_dl_argv[1], "--audit") && _dl_argc > 2)
{ {
audit_list_add_string (&audit_list, _dl_argv[2]); audit_list_add_string (&state.audit_list, _dl_argv[2]);
_dl_skip_args += 2; _dl_skip_args += 2;
_dl_argc -= 2; _dl_argc -= 2;
@@ -1260,7 +1227,7 @@ dl_main (const ElfW(Phdr) *phdr,
} }
else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2) else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2)
{ {
preloadarg = _dl_argv[2]; state.preloadarg = _dl_argv[2];
_dl_skip_args += 2; _dl_skip_args += 2;
_dl_argc -= 2; _dl_argc -= 2;
_dl_argv += 2; _dl_argv += 2;
@@ -1328,7 +1295,7 @@ of this helper program; chances are you did not intend to run this program.\n\
break; break;
} }
if (__builtin_expect (mode, normal) == verify) if (__glibc_unlikely (state.mode == rtld_mode_verify))
{ {
const char *objname; const char *objname;
const char *err_str = NULL; const char *err_str = NULL;
@@ -1357,7 +1324,7 @@ of this helper program; chances are you did not intend to run this program.\n\
/* Now the map for the main executable is available. */ /* Now the map for the main executable is available. */
main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
if (__builtin_expect (mode, normal) == normal if (__glibc_likely (state.mode == rtld_mode_normal)
&& GL(dl_rtld_map).l_info[DT_SONAME] != NULL && GL(dl_rtld_map).l_info[DT_SONAME] != NULL
&& main_map->l_info[DT_SONAME] != NULL && main_map->l_info[DT_SONAME] != NULL
&& strcmp ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB]) && strcmp ((const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
@@ -1604,7 +1571,7 @@ of this helper program; chances are you did not intend to run this program.\n\
_dl_setup_hash (main_map); _dl_setup_hash (main_map);
} }
if (__builtin_expect (mode, normal) == verify) if (__glibc_unlikely (state.mode == rtld_mode_verify))
{ {
/* We were called just to verify that this is a dynamic /* We were called just to verify that this is a dynamic
executable using us as the program interpreter. Exit with an executable using us as the program interpreter. Exit with an
@@ -1634,7 +1601,7 @@ of this helper program; chances are you did not intend to run this program.\n\
/* Initialize the data structures for the search paths for shared /* Initialize the data structures for the search paths for shared
objects. */ objects. */
_dl_init_paths (library_path); call_init_paths (&state);
/* Initialize _r_debug. */ /* Initialize _r_debug. */
struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr, struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr,
@@ -1699,14 +1666,14 @@ of this helper program; chances are you did not intend to run this program.\n\
/* Assign a module ID. Do this before loading any audit modules. */ /* Assign a module ID. Do this before loading any audit modules. */
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
audit_list_add_dynamic_tag (&audit_list, main_map, DT_AUDIT); audit_list_add_dynamic_tag (&state.audit_list, main_map, DT_AUDIT);
audit_list_add_dynamic_tag (&audit_list, main_map, DT_DEPAUDIT); audit_list_add_dynamic_tag (&state.audit_list, main_map, DT_DEPAUDIT);
/* If we have auditing DSOs to load, do it now. */ /* If we have auditing DSOs to load, do it now. */
bool need_security_init = true; bool need_security_init = true;
if (audit_list.length > 0) if (state.audit_list.length > 0)
{ {
size_t naudit = audit_list_count (&audit_list); size_t naudit = audit_list_count (&state.audit_list);
/* Since we start using the auditing DSOs right away we need to /* Since we start using the auditing DSOs right away we need to
initialize the data structures now. */ initialize the data structures now. */
@@ -1719,7 +1686,7 @@ of this helper program; chances are you did not intend to run this program.\n\
security_init (); security_init ();
need_security_init = false; need_security_init = false;
load_audit_modules (main_map, &audit_list); load_audit_modules (main_map, &state.audit_list);
/* The count based on audit strings may overestimate the number /* The count based on audit strings may overestimate the number
of audit modules that got loaded, but not underestimate. */ of audit modules that got loaded, but not underestimate. */
@@ -1774,19 +1741,21 @@ of this helper program; chances are you did not intend to run this program.\n\
struct link_map **preloads = NULL; struct link_map **preloads = NULL;
unsigned int npreloads = 0; unsigned int npreloads = 0;
if (__glibc_unlikely (preloadlist != NULL)) if (__glibc_unlikely (state.preloadlist != NULL))
{ {
RTLD_TIMING_VAR (start); RTLD_TIMING_VAR (start);
rtld_timer_start (&start); rtld_timer_start (&start);
npreloads += handle_preload_list (preloadlist, main_map, "LD_PRELOAD"); npreloads += handle_preload_list (state.preloadlist, main_map,
"LD_PRELOAD");
rtld_timer_accum (&load_time, start); rtld_timer_accum (&load_time, start);
} }
if (__glibc_unlikely (preloadarg != NULL)) if (__glibc_unlikely (state.preloadarg != NULL))
{ {
RTLD_TIMING_VAR (start); RTLD_TIMING_VAR (start);
rtld_timer_start (&start); rtld_timer_start (&start);
npreloads += handle_preload_list (preloadarg, main_map, "--preload"); npreloads += handle_preload_list (state.preloadarg, main_map,
"--preload");
rtld_timer_accum (&load_time, start); rtld_timer_accum (&load_time, start);
} }
@@ -1893,7 +1862,8 @@ of this helper program; chances are you did not intend to run this program.\n\
{ {
RTLD_TIMING_VAR (start); RTLD_TIMING_VAR (start);
rtld_timer_start (&start); rtld_timer_start (&start);
_dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0); _dl_map_object_deps (main_map, preloads, npreloads,
state.mode == rtld_mode_trace, 0);
rtld_timer_accum (&load_time, start); rtld_timer_accum (&load_time, start);
} }
@@ -1920,7 +1890,7 @@ of this helper program; chances are you did not intend to run this program.\n\
rtld_multiple_ref = true; rtld_multiple_ref = true;
GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1]; GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1];
if (__builtin_expect (mode, normal) == normal) if (__glibc_likely (state.mode == rtld_mode_normal))
{ {
GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist
? main_map->l_searchlist.r_list[i + 1] ? main_map->l_searchlist.r_list[i + 1]
@@ -1953,8 +1923,8 @@ of this helper program; chances are you did not intend to run this program.\n\
versions we need. */ versions we need. */
{ {
struct version_check_args args; struct version_check_args args;
args.doexit = mode == normal; args.doexit = state.mode == rtld_mode_normal;
args.dotrace = mode == trace; args.dotrace = state.mode == rtld_mode_trace;
_dl_receive_error (print_missing_version, version_check_doit, &args); _dl_receive_error (print_missing_version, version_check_doit, &args);
} }
@@ -1974,7 +1944,7 @@ of this helper program; chances are you did not intend to run this program.\n\
earlier. */ earlier. */
security_init (); security_init ();
if (__builtin_expect (mode, normal) != normal) if (__glibc_unlikely (state.mode != rtld_mode_normal))
{ {
/* We were run just to list the shared libraries. It is /* We were run just to list the shared libraries. It is
important that we do this before real relocation, because the important that we do this before real relocation, because the
@@ -2076,7 +2046,7 @@ of this helper program; chances are you did not intend to run this program.\n\
(size_t) l->l_map_start); (size_t) l->l_map_start);
} }
if (__builtin_expect (mode, trace) != trace) if (__glibc_unlikely (state.mode != rtld_mode_trace))
for (i = 1; i < (unsigned int) _dl_argc; ++i) for (i = 1; i < (unsigned int) _dl_argc; ++i)
{ {
const ElfW(Sym) *ref = NULL; const ElfW(Sym) *ref = NULL;
@@ -2130,7 +2100,7 @@ of this helper program; chances are you did not intend to run this program.\n\
} }
} }
#define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
if (version_info) if (state.version_info)
{ {
/* Print more information. This means here, print information /* Print more information. This means here, print information
about the versions needed. */ about the versions needed. */
@@ -2492,13 +2462,10 @@ print_missing_version (int errcode __attribute__ ((unused)),
objname, errstring); objname, errstring);
} }
/* Nonzero if any of the debugging options is enabled. */
static int any_debug attribute_relro;
/* Process the string given as the parameter which explains which debugging /* Process the string given as the parameter which explains which debugging
options are enabled. */ options are enabled. */
static void static void
process_dl_debug (const char *dl_debug) process_dl_debug (struct dl_main_state *state, const char *dl_debug)
{ {
/* When adding new entries make sure that the maximal length of a name /* When adding new entries make sure that the maximal length of a name
is correctly handled in the LD_DEBUG_HELP code below. */ is correctly handled in the LD_DEBUG_HELP code below. */
@@ -2555,7 +2522,7 @@ process_dl_debug (const char *dl_debug)
&& memcmp (dl_debug, debopts[cnt].name, len) == 0) && memcmp (dl_debug, debopts[cnt].name, len) == 0)
{ {
GLRO(dl_debug_mask) |= debopts[cnt].mask; GLRO(dl_debug_mask) |= debopts[cnt].mask;
any_debug = 1; state->any_debug = true;
break; break;
} }
@@ -2609,11 +2576,10 @@ extern char **_environ attribute_hidden;
static void static void
process_envvars (enum mode *modep, struct audit_list *audit_list) process_envvars (struct dl_main_state *state)
{ {
char **runp = _environ; char **runp = _environ;
char *envline; char *envline;
enum mode mode = normal;
char *debug_output = NULL; char *debug_output = NULL;
/* This is the default place for profiling data file. */ /* This is the default place for profiling data file. */
@@ -2645,25 +2611,25 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
/* Debugging of the dynamic linker? */ /* Debugging of the dynamic linker? */
if (memcmp (envline, "DEBUG", 5) == 0) if (memcmp (envline, "DEBUG", 5) == 0)
{ {
process_dl_debug (&envline[6]); process_dl_debug (state, &envline[6]);
break; break;
} }
if (memcmp (envline, "AUDIT", 5) == 0) if (memcmp (envline, "AUDIT", 5) == 0)
audit_list_add_string (audit_list, &envline[6]); audit_list_add_string (&state->audit_list, &envline[6]);
break; break;
case 7: case 7:
/* Print information about versions. */ /* Print information about versions. */
if (memcmp (envline, "VERBOSE", 7) == 0) if (memcmp (envline, "VERBOSE", 7) == 0)
{ {
version_info = envline[8] != '\0'; state->version_info = envline[8] != '\0';
break; break;
} }
/* List of objects to be preloaded. */ /* List of objects to be preloaded. */
if (memcmp (envline, "PRELOAD", 7) == 0) if (memcmp (envline, "PRELOAD", 7) == 0)
{ {
preloadlist = &envline[8]; state->preloadlist = &envline[8];
break; break;
} }
@@ -2712,7 +2678,7 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
if (!__libc_enable_secure if (!__libc_enable_secure
&& memcmp (envline, "LIBRARY_PATH", 12) == 0) && memcmp (envline, "LIBRARY_PATH", 12) == 0)
{ {
library_path = &envline[13]; state->library_path = &envline[13];
break; break;
} }
@@ -2754,7 +2720,7 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
/* The mode of the dynamic linker can be set. */ /* The mode of the dynamic linker can be set. */
if (memcmp (envline, "TRACE_PRELINKING", 16) == 0) if (memcmp (envline, "TRACE_PRELINKING", 16) == 0)
{ {
mode = trace; state->mode = rtld_mode_trace;
GLRO(dl_verbose) = 1; GLRO(dl_verbose) = 1;
GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK; GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
GLRO(dl_trace_prelink) = &envline[17]; GLRO(dl_trace_prelink) = &envline[17];
@@ -2764,7 +2730,7 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
case 20: case 20:
/* The mode of the dynamic linker can be set. */ /* The mode of the dynamic linker can be set. */
if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0) if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
mode = trace; state->mode = rtld_mode_trace;
break; break;
/* We might have some extra environment variable to handle. This /* We might have some extra environment variable to handle. This
@@ -2777,9 +2743,6 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
} }
} }
/* The caller wants this information. */
*modep = mode;
/* Extra security for SUID binaries. Remove all dangerous environment /* Extra security for SUID binaries. Remove all dangerous environment
variables. */ variables. */
if (__builtin_expect (__libc_enable_secure, 0)) if (__builtin_expect (__libc_enable_secure, 0))
@@ -2808,13 +2771,13 @@ process_envvars (enum mode *modep, struct audit_list *audit_list)
GLRO(dl_debug_mask) = 0; GLRO(dl_debug_mask) = 0;
} }
if (mode != normal) if (state->mode != rtld_mode_normal)
_exit (5); _exit (5);
} }
/* If we have to run the dynamic linker in debugging mode and the /* If we have to run the dynamic linker in debugging mode and the
LD_DEBUG_OUTPUT environment variable is given, we write the debug LD_DEBUG_OUTPUT environment variable is given, we write the debug
messages to this file. */ messages to this file. */
else if (any_debug && debug_output != NULL) else if (state->any_debug && debug_output != NULL)
{ {
const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW; const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
size_t name_len = strlen (debug_output); size_t name_len = strlen (debug_output);