]> sourceware.org Git - glibc.git/blobdiff - elf/rtld.c
handle password file locking.
[glibc.git] / elf / rtld.c
index 3657efdc61e98320dd86e8108e2c3d12698be0f8..be71e88c3cf6cab1a4eb401684f4d8c7253d9fd7 100644 (file)
@@ -42,6 +42,15 @@ int _dl_argc;
 char **_dl_argv;
 const char *_dl_rpath;
 
+/* Set nonzero during loading and initialization of executable and
+   libraries, cleared before the executable's entry point runs.  This
+   must not be initialized to nonzero, because the unused dynamic
+   linker loaded in for libc.so's "ld.so.1" dep will provide the
+   definition seen by libc.so's initializer; that value must be zero,
+   and will be since that dynamic linker's _dl_start and dl_main will
+   never be called.  */
+int _dl_starting_up;
+
 static void dl_main (const ElfW(Phdr) *phdr,
                     ElfW(Half) phent,
                     ElfW(Addr) *user_entry);
@@ -62,7 +71,7 @@ _dl_start (void *arg)
   /* This #define produces dynamic linking inline functions for
      bootstrap relocation instead of general-purpose relocation.  */
 #define RTLD_BOOTSTRAP
-#define RESOLVE(sym, reloc_addr, noplt) bootstrap_map.l_addr
+#define RESOLVE(sym, flags) bootstrap_map.l_addr
 #include "dynamic-link.h"
 
   /* Figure out the run-time load address of the dynamic linker itself.  */
@@ -126,10 +135,12 @@ dl_main (const ElfW(Phdr) *phdr,
   const ElfW(Phdr) *ph;
   struct link_map *l;
   int lazy;
-  enum { normal, list, verify } mode = normal;
+  enum { normal, list, verify, trace } mode;
   struct link_map **preloads;
   unsigned int npreloads;
 
+  mode = getenv ("LD_TRACE_LOADED_OBJECTS") != NULL ? trace : normal;
+
   if (*user_entry == (ElfW(Addr)) &_start)
     {
       /* Ho ho.  We are not the program interpreter!  We are the program
@@ -187,7 +198,25 @@ of this helper program; chances are you did not intend to run this program.\n",
       --_dl_argc;
       ++_dl_argv;
 
-      l = _dl_map_object (NULL, _dl_argv[0], lt_library);
+      if (mode == verify)
+       {
+         void doit (void)
+           {
+             l = _dl_map_object (NULL, _dl_argv[0], lt_library);
+           }
+         char *err_str = NULL;
+         const char *obj_name __attribute__ ((unused));
+
+         (void) _dl_catch_error (&err_str, &obj_name, doit);
+         if (err_str != NULL)
+           {
+             free (err_str);
+             _exit (EXIT_FAILURE);
+           }
+       }
+      else
+       l = _dl_map_object (NULL, _dl_argv[0], lt_library);
+
       phdr = l->l_phdr;
       phent = l->l_phnum;
       l->l_name = (char *) "";
@@ -197,7 +226,7 @@ of this helper program; chances are you did not intend to run this program.\n",
     {
       /* Create a link_map for the executable itself.
         This will be what dlopen on "" returns.  */
-      l = _dl_new_object ((char *) "", "", lt_library);
+      l = _dl_new_object ((char *) "", "", lt_executable);
       l->l_phdr = phdr;
       l->l_phnum = phent;
       l->l_entry = *user_entry;
@@ -245,7 +274,8 @@ of this helper program; chances are you did not intend to run this program.\n",
   if (mode == verify)
     /* We were called just to verify that this is a dynamic executable
        using us as the program interpreter.  */
-    _exit (strcmp (_dl_rtld_map.l_libname, _dl_rtld_map.l_name)
+    _exit ((strcmp (_dl_rtld_map.l_libname, _dl_rtld_map.l_name) ||
+           l->l_ld == NULL)
           ? EXIT_FAILURE : EXIT_SUCCESS);
 
   /* Extract the contents of the dynamic section for easy access.  */
@@ -339,7 +369,7 @@ of this helper program; chances are you did not intend to run this program.\n",
        }
     }
 
-  if (mode != normal || getenv ("LD_TRACE_LOADED_OBJECTS") != NULL)
+  if (mode != normal)
     {
       /* We were run just to list the shared libraries.  It is
         important that we do this before real relocation, because the
@@ -362,13 +392,14 @@ of this helper program; chances are you did not intend to run this program.\n",
                                " (0x", bp, ")\n", NULL);
          }
 
-      if (mode != normal)
+      if (mode != trace)
        for (i = 1; i < _dl_argc; ++i)
          {
            const ElfW(Sym) *ref = NULL;
            ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
                                                     &_dl_default_scope[2],
-                                                    "argument", 0, 0);
+                                                    "argument",
+                                                    DL_LOOKUP_NOPLT);
            char buf[20], *bp;
            buf[sizeof buf - 1] = '\0';
            bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
@@ -461,13 +492,17 @@ of this helper program; chances are you did not intend to run this program.\n",
         dynamic linker.  There is no additional initialization
         required for the ABI-compliant dynamic linker.  */
 
-      (*(void (*) (void)) (_dl_rtld_map.l_addr +
-                          _dl_rtld_map.l_info[DT_INIT]->d_un.d_ptr)) ();
+      (*(void (*) (int, char **, char**))
+       (_dl_rtld_map.l_addr + _dl_rtld_map.l_info[DT_INIT]->d_un.d_ptr))
+       (0, NULL, NULL);
 
       /* Clear the field so a future dlopen won't run it again.  */
       _dl_rtld_map.l_info[DT_INIT] = NULL;
     }
 
+  /* We finished the intialization and will start up.  */
+  _dl_starting_up = 1;
+
   /* Once we return, _dl_sysdep_start will invoke
      the DT_INIT functions and then *USER_ENTRY.  */
 }
This page took 0.033214 seconds and 5 git commands to generate.