[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patches] [PATCH] Remove debug print outs from the run-time linker (RTLD_DEBUG option group)



Joseph,

Would you please review the following patch which make EGLIBC's run-time linker 8-10% smaller.

The following patch adds a new option group to EGLIBC -- OPTION_EGLIBC_RTLD_DEBUG. This group makes debug print-outs of the run-time linker optional. These are the print-outs triggered by LD_DEBUG and TRACE_PRELINKING environment variables. Removing the associated code makes the run-time linker smaller.

From the technical perspective the patch is rather simple. The _dl_debug_mask variable specifies which events the run-time linker should log, these checks are in the form of `if (_dl_debug_mask & DL_DEBUG_<EVENT>)'. If _dl_debug_mask instead of being a variable is defined to plain `0', then all the checks become `if (0)'. And the compiler removes all the printing code as trivially unreachable.

Unfortunately, due to peculiarity of _dl_debug_mask being a field in a struct for shared libc and a global variable for static libc, we cannot simply define

#if __OPTION_EGLIBC_RTLD_DEBUG
# define _dl_debug_mask _dl_debug_mask
#else
# define _dl_debug_mask 0
#endif

and be done with the task. Instead we have to introduce a new name for the variable and rename all the current uses. This is what the main body of the patch does. If you have ideas on how this optimization can be done without renaming all the uses of _dl_debug_mask, I'll appreciate a suggestion.

Otherwise, tested on i686-linux-gnu with no failures.  OK for trunk?

Regards,

--
Maxim Kuvyrkov
CodeSourcery
maxim@xxxxxxxxxxxxxxxx
(650) 331-3385 x724
2010-01-31  Maxim Kuvyrkov  <maxim@xxxxxxxxxxxxxxxx>

	EGLIBC_RTLD_DEBUG option group

	* option-groups.def (OPTION_EGLIBC_RTLD_DEBUG): Define new option
	group.
	* option-groups.defaults: Set the default.
	* sysdeps/generic/ldsodefs.h (GLRO_dl_debug_mask): Define to either
	`GLRO(dl_debug_mask)' or to `0' depending on RTLD_DEBUG option group.
	(_dl_debug_mask): Declare only if RTLD_DEBUG is enabled.
	* elf/dl-support.c (_dl_debug_mask): Define only if RTLD_DEBUG is
	enabled.
	* elf/rtld.c: Replace GLRO(dl_debug_mask) with GLRO_dl_debug_mask
	throughout the file.
	(process_dl_debug): Compile only if RTLD_DEBUG is enabled.
	(process_envvars): Update.
	* csu/libc-start.c, elf/dl-cache.c, elf/dl-close.c, elf/dl-conflict.c,
	* elf/dl-deps.c, elf/dl-error.c, elf/dl-fini.c, elf/dl-init.c,
	* elf/dl-load.c, elf/dl-lookup.c, elf/dl-object.c, elf/dl-open.c,
	* elf/dl-reloc.c, elf/dl-version.c: Replace GLRO(dl_debug_mask) with
	GLRO_dl_debug_mask throughout the file.
diff --git a/csu/libc-start.c b/csu/libc-start.c
index dc7ca55..9c06865 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -178,7 +178,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
 
   /* Call the initializer of the program, if any.  */
 #ifdef SHARED
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
     GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
 #endif
   if (init)
@@ -201,7 +201,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
 #endif
 
 #ifdef SHARED
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
     GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
 #endif
 
diff --git a/elf/dl-cache.c b/elf/dl-cache.c
index bbeba77..0961ee6 100644
--- a/elf/dl-cache.c
+++ b/elf/dl-cache.c
@@ -187,7 +187,7 @@ _dl_load_cache_lookup (const char *name)
   const char *best;
 
   /* Print a message if the loading of libs is traced.  */
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0))
     _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE);
 
   if (cache == NULL)
@@ -283,7 +283,7 @@ _dl_load_cache_lookup (const char *name)
     }
 
   /* Print our result if wanted.  */
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0)
       && best != NULL)
     _dl_debug_printf ("  trying file=%s\n", best);
 
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 865adce..3d14dbe 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -123,7 +123,7 @@ _dl_close_worker (struct link_map *map)
 	dl_close_state = rerun;
 
       /* There are still references to this object.  Do nothing more.  */
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
 	_dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n",
 			  map->l_name, map->l_direct_opencount);
 
@@ -249,7 +249,7 @@ _dl_close_worker (struct link_map *map)
 	  if (imap->l_init_called)
 	    {
 	      /* When debugging print a message first.  */
-	      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
+	      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS,
 				    0))
 		_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
 				  imap->l_name, nsid);
@@ -628,7 +628,7 @@ _dl_close_worker (struct link_map *map)
 	  free (imap->l_reldeps);
 
 	  /* Print debugging message.  */
-	  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
+	  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
 	    _dl_debug_printf ("\nfile=%s [%lu];  destroying link map\n",
 			      imap->l_name, imap->l_ns);
 
diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
index b730105..a01e2a9 100644
--- a/elf/dl-conflict.c
+++ b/elf/dl-conflict.c
@@ -33,7 +33,7 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
 		       ElfW(Rela) *conflictend)
 {
 #if ! ELF_MACHINE_NO_RELA
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_RELOC, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_RELOC, 0))
     _dl_debug_printf ("\nconflict processing: %s\n",
 		      l->l_name[0] ? l->l_name : rtld_progname);
 
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 34c6024..ba6cd04 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -129,7 +129,7 @@ empty dynamic string token substitution"));				      \
 	    else							      \
 	      {								      \
 		/* This is for DT_AUXILIARY.  */			      \
-		if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))\
+		if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0))\
 		  _dl_debug_printf (N_("\
 cannot load auxiliary `%s' because of empty dynamic string token "	      \
 					    "substitution\n"), __str);	      \
@@ -298,7 +298,7 @@ _dl_map_object_deps (struct link_map *map,
 		if (d->d_tag == DT_AUXILIARY)
 		  {
 		    /* Say that we are about to load an auxiliary library.  */
-		    if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS,
+		    if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS,
 					  0))
 		      _dl_debug_printf ("load auxiliary object=%s"
 					" requested by file=%s\n",
@@ -325,7 +325,7 @@ _dl_map_object_deps (struct link_map *map,
 		else
 		  {
 		    /* Say that we are about to load an auxiliary library.  */
-		    if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS,
+		    if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS,
 					  0))
 		      _dl_debug_printf ("load filtered object=%s"
 					" requested by file=%s\n",
@@ -526,7 +526,7 @@ _dl_map_object_deps (struct link_map *map,
       runp->map->l_reserved = 0;
     }
 
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_PRELINK, 0) != 0
       && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
     {
       /* If we are to compute conflicts, we have to build local scope
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 79ebaaf..a65e286 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -136,7 +136,7 @@ internal_function
 _dl_signal_cerror (int errcode, const char *objname, const char *occation,
 		   const char *errstring)
 {
-  if (__builtin_expect (GLRO(dl_debug_mask)
+  if (__builtin_expect (GLRO_dl_debug_mask
 			& ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0))
     _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation,
 		      errstring, receiver ? "continued" : "fatal");
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index ff4c33e..dfd55c9 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -225,7 +225,7 @@ _dl_fini (void)
 		  || l->l_info[DT_FINI] != NULL)
 		{
 		  /* When debugging print a message first.  */
-		  if (__builtin_expect (GLRO(dl_debug_mask)
+		  if (__builtin_expect (GLRO_dl_debug_mask
 					& DL_DEBUG_IMPCALLS, 0))
 		    _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
 				      l->l_name[0] ? l->l_name : rtld_progname,
@@ -277,7 +277,7 @@ _dl_fini (void)
       goto again;
     }
 
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS, 0))
     _dl_debug_printf ("\nruntime linker statistics:\n"
 		      "           final number of relocations: %lu\n"
 		      "final number of relocations from cache: %lu\n",
diff --git a/elf/dl-init.c b/elf/dl-init.c
index e7b6757..e4d701a 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -53,7 +53,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
     return;
 
   /* Print a debug message if wanted.  */
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
     _dl_debug_printf ("\ncalling init: %s\n\n",
 		      l->l_name[0] ? l->l_name : rtld_progname);
 
@@ -109,7 +109,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
       ElfW(Addr) *addrs;
       unsigned int cnt;
 
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
 	_dl_debug_printf ("\ncalling preinit: %s\n\n",
 			  main_map->l_name[0]
 			  ? main_map->l_name : rtld_progname);
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 597193c..0fa3dca 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -911,7 +911,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
     }
 
   /* Print debugging message.  */
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
     _dl_debug_printf ("file=%s [%lu];  generating link map\n", name, nsid);
 
   /* This is the ELF header.  We read it in `open_verify'.  */
@@ -1440,7 +1440,7 @@ cannot enable executable stack as shared object requires");
 
   l->l_entry += l->l_addr;
 
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
     _dl_debug_printf ("\
   dynamic: 0x%0*lx  base: 0x%0*lx   size: 0x%0*Zx\n\
     entry: 0x%0*lx  phdr: 0x%0*lx  phnum:   %*u\n\n",
@@ -1830,7 +1830,7 @@ open_path (const char *name, size_t namelen, int preloaded,
 
       /* If we are debugging the search for libraries print the path
 	 now if it hasn't happened now.  */
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0)
 	  && current_what != this_dir->what)
 	{
 	  current_what = this_dir->what;
@@ -1851,7 +1851,7 @@ open_path (const char *name, size_t namelen, int preloaded,
 	     - buf);
 
 	  /* Print name we try if this is wanted.  */
-	  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
+	  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0))
 	    _dl_debug_printf ("  trying file=%s\n", buf);
 
 	  fd = open_verify (buf, fbp, loader, whatcode, found_other_class,
@@ -1997,7 +1997,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
     }
 
   /* Display information if we are debugging.  */
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0)
       && loader != NULL)
     _dl_debug_printf ("\nfile=%s [%lu];  needed by %s [%lu]\n", name, nsid,
 			      loader->l_name[0]
@@ -2038,7 +2038,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 
       size_t namelen = strlen (name) + 1;
 
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0))
 	_dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid);
 
       fd = -1;
@@ -2163,7 +2163,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 			&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
 
       /* Add another newline when we are tracing the library loading.  */
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0))
         _dl_debug_printf ("\n");
     }
   else
@@ -2196,7 +2196,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
   if (__builtin_expect (fd, 0) == -1)
     {
       if (trace_mode
-	  && __builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) == 0)
+	  && __builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_PRELINK, 0) == 0)
 	{
 	  /* We haven't found an appropriate library.  But since we
 	     are only interested in the list of libraries this isn't
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 763ec16..c350f16 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -110,7 +110,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
 	continue;
 
       /* Print some debugging info if wanted.  */
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS, 0))
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_SYMBOLS, 0))
 	_dl_debug_printf ("symbol=%s;  lookup in file=%s [%lu]\n",
 			  undef_name,
 			  map->l_name[0] ? map->l_name : rtld_progname,
@@ -646,7 +646,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
 	}
 
       /* Display information if we are debugging.  */
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
 	_dl_debug_printf ("\
 \nfile=%s [%lu];  needed by %s [%lu] (relocation dependency)\n\n",
 			  map->l_name[0] ? map->l_name : rtld_progname,
@@ -825,7 +825,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
   if (__builtin_expect (current_value.m->l_used == 0, 0))
     current_value.m->l_used = 1;
 
-  if (__builtin_expect (GLRO(dl_debug_mask)
+  if (__builtin_expect (GLRO_dl_debug_mask
 			& (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
     _dl_debug_bindings (undef_name, undef_map, ref,
 			&current_value, version, type_class, protected);
@@ -890,7 +890,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
 {
   const char *reference_name = undef_map->l_name;
 
-  if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
+  if (GLRO_dl_debug_mask & DL_DEBUG_BINDINGS)
     {
       _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
 			(reference_name[0]
@@ -906,7 +906,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
 	_dl_debug_printf_c ("\n");
     }
 #ifdef SHARED
-  if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
+  if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
     {
       int conflict = 0;
       struct sym_val val = { NULL, NULL };
diff --git a/elf/dl-object.c b/elf/dl-object.c
index 788e2c0..d3517ce 100644
--- a/elf/dl-object.c
+++ b/elf/dl-object.c
@@ -69,7 +69,7 @@ _dl_new_object (char *realname, const char *libname, int type,
   new->l_type = type;
   /* If we set the bit now since we know it is never used we avoid
      dirtying the cache line later.  */
-  if ((GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) == 0)
+  if ((GLRO_dl_debug_mask & DL_DEBUG_UNUSED) == 0)
     new->l_used = 1;
   new->l_loader = loader;
 #if NO_TLS_OFFSET != 0
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 754a263..610ceae 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -274,7 +274,7 @@ dl_open_worker (void *a)
   if (__builtin_expect (new->l_searchlist.r_list != NULL, 0))
     {
       /* Let the user know about the opencount.  */
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
 	_dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
 			  new->l_name, new->l_ns, new->l_direct_opencount);
 
@@ -511,7 +511,7 @@ TLS generation counter wrapped!  Please report this."));
 #endif
 
   /* Let the user know about the opencount.  */
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
     _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
 		      new->l_name, new->l_ns, new->l_direct_opencount);
 }
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 206e815..2754791 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -186,7 +186,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
       && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0))
     lazy = 0;
 
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_RELOC, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_RELOC, 0))
     _dl_debug_printf ("\nrelocation processing: %s%s\n",
 		      l->l_name[0] ? l->l_name : rtld_progname,
 		      lazy ? " (lazy)" : "");
diff --git a/elf/dl-support.c b/elf/dl-support.c
index bcf0e2a..a9b307d 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -40,7 +40,9 @@ char **_dl_argv = &__progname;	/* This is checked for some error messages.  */
 const char *_dl_platform;
 size_t _dl_platformlen;
 
+#if __OPTION_EGLIBC_RTLD_DEBUG
 int _dl_debug_mask;
+#endif
 int _dl_lazy;
 ElfW(Addr) _dl_use_load_bias = -2;
 int _dl_dynamic_weak;
diff --git a/elf/dl-version.c b/elf/dl-version.c
index 9e88116..51a940c 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -88,7 +88,7 @@ match_symbol (const char *name, Lmid_t ns, ElfW(Word) hash, const char *string,
   int result = 0;
 
   /* Display information about what we are doing while debugging.  */
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_VERSIONS, 0))
     _dl_debug_printf ("\
 checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
 		      string, map->l_name[0] ? map->l_name : rtld_progname,
diff --git a/elf/rtld.c b/elf/rtld.c
index 3afb997..0ee0e43 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -346,7 +346,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
     }
 #endif
 
-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
+  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS, 0))
     {
 #ifndef HP_TIMING_NONAVAIL
       print_statistics (&rtld_total_time);
@@ -1888,7 +1888,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 	 after relocation.  */
       struct link_map *l;
 
-      if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
+      if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
 	{
 	  struct r_scope_elem *scope = &main_map->l_searchlist;
 
@@ -1920,7 +1920,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 		_dl_printf ("\n");
 	    }
 	}
-      else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
+      else if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
 	{
 	  /* Look through the dependencies of the main executable
 	     and determine which of them is not actually
@@ -2024,7 +2024,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 		}
 	      while (l != NULL);
 
-	      if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
+	      if ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
 		  && rtld_multiple_ref)
 		{
 		  /* Mark the link map as not yet relocated again.  */
@@ -2158,7 +2158,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
       if (r_list == r_listend && liblist == liblistend)
 	prelinked = true;
 
-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
+      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0))
 	_dl_debug_printf ("\nprelink checking: %s\n",
 			  prelinked ? "ok" : "failed");
     }
@@ -2377,6 +2377,7 @@ print_missing_version (int errcode __attribute__ ((unused)),
 		    objname, errstring);
 }
 
+#if __OPTION_EGLIBC_RTLD_DEBUG
 /* Nonzero if any of the debugging options is enabled.  */
 static int any_debug attribute_relro;
 
@@ -2436,7 +2437,7 @@ process_dl_debug (const char *dl_debug)
 	    if (debopts[cnt].len == len
 		&& 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;
 		break;
 	      }
@@ -2457,7 +2458,7 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
       ++dl_debug;
     }
 
-  if (GLRO(dl_debug_mask) & DL_DEBUG_HELP)
+  if (GLRO_dl_debug_mask & DL_DEBUG_HELP)
     {
       size_t cnt;
 
@@ -2475,6 +2476,7 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
       _exit (0);
     }
 }
+#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
 
 static void
 process_dl_audit (char *str)
@@ -2542,12 +2544,14 @@ process_envvars (enum mode *modep)
 	  break;
 
 	case 5:
+#if __OPTION_EGLIBC_RTLD_DEBUG
 	  /* Debugging of the dynamic linker?  */
 	  if (memcmp (envline, "DEBUG", 5) == 0)
 	    {
 	      process_dl_debug (&envline[6]);
 	      break;
 	    }
+#endif
 	  if (memcmp (envline, "AUDIT", 5) == 0)
 	    process_dl_audit (&envline[6]);
 	  break;
@@ -2656,7 +2660,9 @@ process_envvars (enum mode *modep)
 	    {
 	      mode = trace;
 	      GLRO(dl_verbose) = 1;
-	      GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
+#if __OPTION_EGLIBC_RTLD_DEBUG
+	      GLRO_dl_debug_mask |= DL_DEBUG_PRELINK;
+#endif
 	      GLRO(dl_trace_prelink) = &envline[17];
 	    }
 	  break;
@@ -2703,12 +2709,15 @@ process_envvars (enum mode *modep)
       if (__access ("/etc/suid-debug", F_OK) != 0)
 	{
 	  unsetenv ("MALLOC_CHECK_");
-	  GLRO(dl_debug_mask) = 0;
+#if __OPTION_EGLIBC_RTLD_DEBUG
+	  GLRO_dl_debug_mask = 0;
+#endif
 	}
 
       if (mode != normal)
 	_exit (5);
     }
+#if __OPTION_EGLIBC_RTLD_DEBUG
   /* If we have to run the dynamic linker in debugging mode and the
      LD_DEBUG_OUTPUT environment variable is given, we write the debug
      messages to this file.  */
@@ -2733,6 +2742,7 @@ process_envvars (enum mode *modep)
 	/* We use standard output if opening the file failed.  */
 	GLRO(dl_debug_fd) = STDOUT_FILENO;
     }
+#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
 }
 
 
diff --git a/option-groups.def b/option-groups.def
index 08115f3..92495ae 100644
--- a/option-groups.def
+++ b/option-groups.def
@@ -635,6 +635,13 @@ config OPTION_EGLIBC_RCMD
         rresvport       ruserpass
         rresvport_af
         
+config OPTION_EGLIBC_RTLD_DEBUG
+   bool "Runtime linker debug print outs"
+   help
+      This option group enables debug output of the runtime linker
+      which is activated via LD_DEBUG environment variable.  Disabling
+      this option group yields a smaller runtime linker binary.
+
 config OPTION_EGLIBC_SPAWN
    bool "Support for POSIX posix_spawn functions"
    help
diff --git a/option-groups.defaults b/option-groups.defaults
index b188b15..588fb50 100644
--- a/option-groups.defaults
+++ b/option-groups.defaults
@@ -35,6 +35,7 @@ OPTION_EGLIBC_MEMUSAGE = y
 OPTION_EGLIBC_NIS = y
 OPTION_EGLIBC_NSSWITCH = y
 OPTION_EGLIBC_RCMD = y
+OPTION_EGLIBC_RTLD_DEBUG = y
 OPTION_EGLIBC_SPAWN = y
 OPTION_EGLIBC_STREAMS = y
 OPTION_EGLIBC_SUNRPC = y
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 230c39a..f6dedc4 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -529,6 +529,12 @@ extern struct rtld_global _rtld_global __rtld_global_attribute__;
 # undef __rtld_global_attribute__
 #endif
 
+#if __OPTION_EGLIBC_RTLD_DEBUG
+# define GLRO_dl_debug_mask GLRO(dl_debug_mask)
+#else
+# define GLRO_dl_debug_mask 0
+#endif
+
 #ifndef SHARED
 # define GLRO(name) _##name
 #else
@@ -541,8 +547,10 @@ struct rtld_global_ro
 {
 #endif
 
+#if __OPTION_EGLIBC_RTLD_DEBUG
   /* If nonzero the appropriate debug information is printed.  */
   EXTERN int _dl_debug_mask;
+#endif
 #define DL_DEBUG_LIBS	    (1 << 0)
 #define DL_DEBUG_IMPCALLS   (1 << 1)
 #define DL_DEBUG_BINDINGS   (1 << 2)