summary refs log tree commit diff
path: root/elf/rtld.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/rtld.c')
-rw-r--r--elf/rtld.c71
1 files changed, 51 insertions, 20 deletions
diff --git a/elf/rtld.c b/elf/rtld.c
index 5e6ee51603..a357a46987 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1,5 +1,5 @@
 /* Run time dynamic linker.
-   Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+   Copyright (C) 1995-2006, 2007 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
@@ -207,7 +207,8 @@ DL_SYSINFO_IMPLEMENTATION
    is fine, too.  The latter is important here.  We can avoid setting
    up a temporary link map for ld.so if we can mark _rtld_global as
    hidden.  */
-#ifdef PI_STATIC_AND_HIDDEN
+#if defined PI_STATIC_AND_HIDDEN && defined HAVE_HIDDEN \
+    && defined HAVE_VISIBILITY_ATTRIBUTE
 # define DONT_USE_BOOTSTRAP_MAP	1
 #endif
 
@@ -291,7 +292,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
   GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
   GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext;
   /* Copy the TLS related data if necessary.  */
-#ifndef DONT_USE_BOOTSTRAP_MAP
+#if USE_TLS && !defined DONT_USE_BOOTSTRAP_MAP
 # if USE___THREAD
   assert (info->l.l_tls_modid != 0);
   GL(dl_rtld_map).l_tls_blocksize = info->l.l_tls_blocksize;
@@ -399,7 +400,7 @@ _dl_start (void *arg)
   bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
   elf_get_dynamic_info (&bootstrap_map, NULL);
 
-#if NO_TLS_OFFSET != 0
+#if defined USE_TLS && NO_TLS_OFFSET != 0
   bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
 #endif
 
@@ -700,6 +701,7 @@ match_version (const char *string, struct link_map *map)
   return 0;
 }
 
+#ifdef USE_TLS
 static bool tls_init_tp_called;
 
 static void *
@@ -771,6 +773,7 @@ cannot allocate TLS data structures for initial thread");
 
   return tcbp;
 }
+#endif
 
 #ifdef _LIBC_REENTRANT
 /* _dl_error_catch_tsd points to this for the single-threaded case.
@@ -858,14 +861,18 @@ dl_main (const ElfW(Phdr) *phdr,
   hp_timing_t stop;
   hp_timing_t diff;
 #endif
+#ifdef USE_TLS
   void *tcbp = NULL;
+#endif
 
 #ifdef _LIBC_REENTRANT
   /* Explicit initialization since the reloc would just be more work.  */
   GL(dl_error_catch_tsd) = &_dl_initial_error_catch_tsd;
 #endif
 
+#ifdef USE_TLS
   GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
+#endif
 
 #if defined SHARED && defined _LIBC_REENTRANT \
     && defined __rtld_lock_default_lock_recursive
@@ -1150,6 +1157,7 @@ of this helper program; chances are you did not intend to run this program.\n\
 	break;
 
       case PT_TLS:
+#ifdef USE_TLS
 	if (ph->p_memsz > 0)
 	  {
 	    /* Note that in the case the dynamic linker we duplicate work
@@ -1169,6 +1177,10 @@ of this helper program; chances are you did not intend to run this program.\n\
 	    /* This image gets the ID one.  */
 	    GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1;
 	  }
+#else
+	_dl_fatal_printf ("\
+ld.so does not support TLS, but program uses it!\n");
+#endif
 	break;
 
       case PT_GNU_STACK:
@@ -1180,12 +1192,13 @@ of this helper program; chances are you did not intend to run this program.\n\
 	main_map->l_relro_size = ph->p_memsz;
 	break;
       }
-
-  /* Adjust the address of the TLS initialization image in case
-     the executable is actually an ET_DYN object.  */
-  if (main_map->l_tls_initimage != NULL)
-    main_map->l_tls_initimage
-      = (char *) main_map->l_tls_initimage + main_map->l_addr;
+#ifdef USE_TLS
+    /* Adjust the address of the TLS initialization image in case
+       the executable is actually an ET_DYN object.  */
+    if (main_map->l_tls_initimage != NULL)
+      main_map->l_tls_initimage
+	= (char *) main_map->l_tls_initimage + main_map->l_addr;
+#endif
   if (! main_map->l_map_end)
     main_map->l_map_end = ~0;
   if (! main_map->l_text_end)
@@ -1388,10 +1401,12 @@ of this helper program; chances are you did not intend to run this program.\n\
 	break;
       }
 
+#ifdef USE_TLS
   /* Add the dynamic linker to the TLS list if it also uses TLS.  */
   if (GL(dl_rtld_map).l_tls_blocksize != 0)
     /* Assign a module ID.  Do this before loading any audit modules.  */
     GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
+#endif
 
   /* If we have auditing DSOs to load, do it now.  */
   if (__builtin_expect (audit_list != NULL, 0))
@@ -1399,8 +1414,15 @@ of this helper program; chances are you did not intend to run this program.\n\
       /* Iterate over all entries in the list.  The order is important.  */
       struct audit_ifaces *last_audit = NULL;
       struct audit_list *al = audit_list->next;
+
+#ifdef USE_TLS
+      /* Since we start using the auditing DSOs right away we need to
+	 initialize the data structures now.  */
+      tcbp = init_tls ();
+#endif
       do
 	{
+#ifdef USE_TLS
 	  int tls_idx = GL(dl_tls_max_dtv_idx);
 
 	  /* Now it is time to determine the layout of the static TLS
@@ -1408,11 +1430,7 @@ of this helper program; chances are you did not intend to run this program.\n\
 	     always allocate the static block, we never defer it even if
 	     no DF_STATIC_TLS bit is set.  The reason is that we know
 	     glibc will use the static model.  */
-
-	  /* Since we start using the auditing DSOs right away we need to
-	     initialize the data structures now.  */
-	  tcbp = init_tls ();
-
+#endif
 	  struct dlmopen_args dlmargs;
 	  dlmargs.fname = al->name;
 	  dlmargs.map = NULL;
@@ -1527,7 +1545,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 		  assert (GL(dl_ns)[ns]._ns_loaded == NULL);
 		  assert (GL(dl_ns)[ns]._ns_nloaded == 0);
 
+#ifdef USE_TLS
 		  GL(dl_tls_max_dtv_idx) = tls_idx;
+#endif
 		  goto not_loaded;
 		}
 	    }
@@ -1803,6 +1823,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
     _dl_receive_error (print_missing_version, version_check_doit, &args);
   }
 
+#ifdef USE_TLS
   /* We do not initialize any of the TLS functionality unless any of the
      initial modules uses TLS.  This makes dynamic loading of modules with
      TLS impossible, but to support it requires either eagerly doing setup
@@ -1813,6 +1834,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
   bool was_tls_init_tp_called = tls_init_tp_called;
   if (tcbp == NULL)
     tcbp = init_tls ();
+#endif
 
   /* Set up the stack checker's canary.  */
   uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
@@ -1869,12 +1891,13 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 			  (size_t) l->l_map_start,
 			  (int) sizeof l->l_addr * 2,
 			  (size_t) l->l_addr);
-
+#ifdef USE_TLS
 	      if (l->l_tls_modid)
 		_dl_printf (" TLS(0x%Zx, 0x%0*Zx)\n", l->l_tls_modid,
 			    (int) sizeof l->l_tls_offset * 2,
 			    (size_t) l->l_tls_offset);
 	      else
+#endif
 		_dl_printf ("\n");
 	    }
 	}
@@ -1942,8 +1965,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 	    lookup_t result;
 
 	    result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map,
-					  &ref, main_map->l_scope,
-					  NULL, ELF_RTYPE_CLASS_PLT,
+					  &ref, main_map->l_scope, NULL,
+					  ELF_RTYPE_CLASS_PLT,
 					  DL_LOOKUP_ADD_DEPENDENCY, NULL);
 
 	    loadbase = LOOKUP_VALUE_ADDRESS (result);
@@ -1985,8 +2008,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 		{
 		  /* Mark the link map as not yet relocated again.  */
 		  GL(dl_rtld_map).l_relocated = 0;
-		  _dl_relocate_object (&GL(dl_rtld_map),
-				       main_map->l_scope, 0, 0);
+		  _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope,
+				       0, 0);
 		}
             }
 #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
@@ -2157,9 +2180,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 	  if (l->l_relro_size)
 	    _dl_protect_relro (l);
 
+#ifdef USE_TLS
 	  /* Add object to slot information data if necessasy.  */
 	  if (l->l_tls_blocksize != 0 && tls_init_tp_called)
 	    _dl_add_to_slotinfo (l);
+#endif
 	}
 
       _dl_sysdep_start_cleanup ();
@@ -2206,9 +2231,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 	    _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy),
 				 consider_profiling);
 
+#ifdef USE_TLS
 	  /* Add object to slot information data if necessasy.  */
 	  if (l->l_tls_blocksize != 0 && tls_init_tp_called)
 	    _dl_add_to_slotinfo (l);
+#endif
 
 	  l = l->l_prev;
 	}
@@ -2237,6 +2264,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 # define NONTLS_INIT_TP do { } while (0)
 #endif
 
+#ifdef USE_TLS
   if (!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0)
     ++GL(dl_tls_generation);
 
@@ -2254,6 +2282,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 	_dl_fatal_printf ("cannot set up thread-local storage: %s\n",
 			  lossage);
     }
+#else
+  NONTLS_INIT_TP;
+#endif
 
   if (! prelinked && rtld_multiple_ref)
     {