Update.
authorUlrich Drepper <drepper@redhat.com>
Mon, 9 Mar 1998 18:30:58 +0000 (18:30 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 9 Mar 1998 18:30:58 +0000 (18:30 +0000)
1998-03-09 18:21  Ulrich Drepper  <drepper@cygnus.com>

* elf/dl-support.c (_dl_debug_bindings): Add definition.
* elf/rtld.c (_dl_debug_bindings): Add definition.
(process_dl_debug): Recognize bindings option.  Update help message.
* elf/link.h (struct link_map): Add l_versyms member.
(_dl_debug_bindings): Add declaration.
* elf/version.c (_dl_check_map_versions): Initialize l_versyms.
* elf/dl-object.c (_dl_new_object): Don't initialize l_rpath_dirs
and l_reloc_result.
* elf/dl-lookup.c (do_lookup): Define verstab from l_versyms.
(sym_val): Remove a member, add m as link_map.
(do_lookup): Return result appropriately.
(_dl_lookup_symbol): If _dl_debug_bindings is defined print message.
Call do_lookup correctly.
(_dl_lookup_symbol_skip): Likewise.
(_dl_lookup_versioned_symbol): Likewise.
(_dl_lookup_versioned_symbol_skip): Likewise.

ChangeLog
elf/dl-lookup.c
elf/dl-object.c
elf/dl-support.c
elf/dl-version.c
elf/link.h
elf/rtld.c

index 2b21f19..c63c207 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+1998-03-09 18:21  Ulrich Drepper  <drepper@cygnus.com>
+
+       * elf/dl-support.c (_dl_debug_bindings): Add definition.
+       * elf/rtld.c (_dl_debug_bindings): Add definition.
+       (process_dl_debug): Recognize bindings option.  Update help message.
+       * elf/link.h (struct link_map): Add l_versyms member.
+       (_dl_debug_bindings): Add declaration.
+       * elf/version.c (_dl_check_map_versions): Initialize l_versyms.
+       * elf/dl-object.c (_dl_new_object): Don't initialize l_rpath_dirs
+       and l_reloc_result.
+       * elf/dl-lookup.c (do_lookup): Define verstab from l_versyms.
+       (sym_val): Remove a member, add m as link_map.
+       (do_lookup): Return result appropriately.
+       (_dl_lookup_symbol): If _dl_debug_bindings is defined print message.
+       Call do_lookup correctly.
+       (_dl_lookup_symbol_skip): Likewise.
+       (_dl_lookup_versioned_symbol): Likewise.
+       (_dl_lookup_versioned_symbol_skip): Likewise.
+
 1998-03-09 08:21  Ulrich Drepper  <drepper@cygnus.com>
 
        * sysdeps/unix/sysv/linux/chown.c: Moved to ...
index c0f9731..c3231ac 100644 (file)
@@ -34,8 +34,8 @@ static const char undefined_msg[] = "undefined symbol: ";
 
 struct sym_val
   {
-    ElfW(Addr) a;
     const ElfW(Sym) *s;
+    struct link_map *m;
   };
 
 
@@ -88,8 +88,8 @@ do_lookup (const char *undef_name, unsigned long int hash,
        continue;
 
       /* Don't search the executable when resolving a copy reloc.  */
-      if (elf_machine_lookup_noexec_p (reloc_type) &&
-         map->l_type == lt_executable)
+      if (elf_machine_lookup_noexec_p (reloc_type)
+         && map->l_type == lt_executable)
        continue;
 
       /* Skip objects without symbol tables.  */
@@ -98,11 +98,7 @@ do_lookup (const char *undef_name, unsigned long int hash,
 
       symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
       strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
-      if (map->l_nversions > 0 && map->l_info[VERSTAG (DT_VERSYM)] != NULL)
-       verstab = ((void *) map->l_addr
-                  + map->l_info[VERSTAG (DT_VERSYM)]->d_un.d_ptr);
-      else
-       verstab = NULL;
+      verstab = map->l_versyms;
 
       /* Search the appropriate hash bucket in this object's symbol table
         for a definition for the same symbol name.  */
@@ -171,7 +167,7 @@ do_lookup (const char *undef_name, unsigned long int hash,
            case STB_GLOBAL:
              /* Global definition.  Just what we need.  */
              result->s = sym;
-             result->a = map->l_addr;
+             result->m = map;
              return 1;
            case STB_WEAK:
              /* Weak definition.  Use this value if we don't find
@@ -179,7 +175,7 @@ do_lookup (const char *undef_name, unsigned long int hash,
              if (! result->s)
                {
                  result->s = sym;
-                 result->a = map->l_addr;
+                 result->m = map;
                }
              break;
            default:
@@ -212,7 +208,7 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
                   int reloc_type)
 {
   const unsigned long int hash = _dl_elf_hash (undef_name);
-  struct sym_val current_value = { 0, NULL };
+  struct sym_val current_value = { NULL, NULL };
   struct link_map **scope;
 
   /* Search the relevant loaded objects for a definition.  */
@@ -222,14 +218,24 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
                   reference_name, NULL, NULL, reloc_type))
       break;
 
-  if (current_value.s == NULL &&
-      (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK))
-    /* We could find no value for a strong reference.  */
-    _dl_signal_error (0, reference_name,
-                     make_string (undefined_msg, undef_name));
+  if (current_value.s == NULL)
+    {
+      if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
+       /* We could find no value for a strong reference.  */
+       _dl_signal_error (0, reference_name,
+                         make_string (undefined_msg, undef_name));
+      *ref = NULL;
+      return 0;
+    }
+
+  if (_dl_debug_bindings)
+    _dl_debug_message ("\tbinding file ", reference_name, " to ",
+                      current_value.m->l_name[0]
+                      ? current_value.m->l_name : _dl_argv[0],
+                      ": symbol `", undef_name, "'\n", NULL);
 
   *ref = current_value.s;
-  return current_value.a;
+  return current_value.m->l_addr;
 }
 
 
@@ -245,7 +251,7 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
                        struct link_map *skip_map)
 {
   const unsigned long int hash = _dl_elf_hash (undef_name);
-  struct sym_val current_value = { 0, NULL };
+  struct sym_val current_value = { NULL, NULL };
   struct link_map **scope;
   size_t i;
 
@@ -263,8 +269,20 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
                     reference_name, NULL, skip_map, 0))
        break;
 
+  if (current_value.s == NULL)
+    {
+      *ref = NULL;
+      return 0;
+    }
+
+  if (_dl_debug_bindings)
+    _dl_debug_message ("\tbinding file ", reference_name, " to ",
+                      current_value.m->l_name[0]
+                      ? current_value.m->l_name : _dl_argv[0],
+                      ": symbol `", undef_name, "'\n", NULL);
+
   *ref = current_value.s;
-  return current_value.a;
+  return current_value.m->l_addr;
 }
 
 
@@ -281,7 +299,7 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
                             int reloc_type)
 {
   const unsigned long int hash = _dl_elf_hash (undef_name);
-  struct sym_val current_value = { 0, NULL };
+  struct sym_val current_value = { NULL, NULL };
   struct link_map **scope;
 
   /* Search the relevant loaded objects for a definition.  */
@@ -308,15 +326,25 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
                                       ? " (no version symbols)" : ""));
     }
 
-  if (current_value.s == NULL &&
-      (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK))
-    /* We could find no value for a strong reference.  */
-    _dl_signal_error (0, reference_name,
-                     make_string (undefined_msg, undef_name,
-                                  ", version ", version->name ?: NULL));
+  if (current_value.s == NULL)
+    {
+      if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
+       /* We could find no value for a strong reference.  */
+       _dl_signal_error (0, reference_name,
+                         make_string (undefined_msg, undef_name,
+                                      ", version ", version->name ?: NULL));
+      *ref = NULL;
+      return 0;
+    }
+
+  if (_dl_debug_bindings)
+    _dl_debug_message ("\tbinding file ", reference_name, " to ",
+                      current_value.m->l_name[0]
+                      ? current_value.m->l_name : _dl_argv[0],
+                      ": symbol `", undef_name, "'\n", NULL);
 
   *ref = current_value.s;
-  return current_value.a;
+  return current_value.m->l_addr;
 }
 
 
@@ -331,7 +359,7 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
                                  struct link_map *skip_map)
 {
   const unsigned long int hash = _dl_elf_hash (undef_name);
-  struct sym_val current_value = { 0, NULL };
+  struct sym_val current_value = { NULL, NULL };
   struct link_map **scope;
   size_t i;
 
@@ -349,19 +377,29 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
                     reference_name, version, skip_map, 0))
        break;
 
-  if (current_value.s == NULL &&
-      (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK))
+  if (current_value.s == NULL)
     {
-      /* We could find no value for a strong reference.  */
-      const size_t len = strlen (undef_name);
-      char buf[sizeof undefined_msg + len];
-      __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
-                undef_name, len + 1);
-      _dl_signal_error (0, reference_name, buf);
+      if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
+       {
+         /* We could find no value for a strong reference.  */
+         const size_t len = strlen (undef_name);
+         char buf[sizeof undefined_msg + len];
+         __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
+                    undef_name, len + 1);
+         _dl_signal_error (0, reference_name, buf);
+       }
+      *ref = NULL;
+      return 0;
     }
 
+  if (_dl_debug_bindings)
+    _dl_debug_message ("\tbinding file ", reference_name, " to ",
+                      current_value.m->l_name[0]
+                      ? current_value.m->l_name : _dl_argv[0],
+                      ": symbol `", undef_name, "'\n", NULL);
+
   *ref = current_value.s;
-  return current_value.a;
+  return current_value.m->l_addr;
 }
 
 
index b2dbb83..9bd600d 100644 (file)
@@ -44,8 +44,6 @@ _dl_new_object (char *realname, const char *libname, int type)
   newname->next = NULL;
   new->l_libname = newname;
   new->l_type = type;
-  new->l_rpath_dirs = NULL;
-  new->l_reloc_result = NULL;
 
   if (_dl_loaded == NULL)
     {
index 797cc99..6b6a22d 100644 (file)
@@ -37,6 +37,7 @@ const char *_dl_platform;
 size_t _dl_platformlen;
 int _dl_debug_libs;
 int _dl_debug_impcalls;
+int _dl_debug_bindings;
 
 /* If nonzero print warnings about problematic situations.  */
 int _dl_verbose;
index a4f77f5..f615bb0 100644 (file)
@@ -273,6 +273,10 @@ _dl_check_map_versions (struct link_map *map, int verbose)
          /* Store the number of available symbols.  */
          map->l_nversions = ndx_high + 1;
 
+         /* Compute the pointer to the version symbols.  */
+         map->l_versyms = ((void *) map->l_addr
+                           + map->l_info[VERSTAG (DT_VERSYM)]->d_un.d_ptr);
+
          if (dyn != NULL)
            {
              ElfW(Verneed) *ent;
index 5847945..d5e2b7f 100644 (file)
@@ -197,6 +197,9 @@ struct link_map
 
     /* Collected results of relocation while profiling.  */
     ElfW(Addr) *l_reloc_result;
+
+    /* Pointer to the version information if available.  */
+    ElfW(Half) *l_versyms;
   };
 
 
@@ -248,6 +251,7 @@ extern struct link_map *_dl_profile_map;
 /* If nonzero the appropriate debug information is printed.  */
 extern int _dl_debug_libs;
 extern int _dl_debug_impcalls;
+extern int _dl_debug_bindings;
 
 /* File deccriptor to write debug messages to.  */
 extern int _dl_debug_fd;
index c466fa2..2cb11bb 100644 (file)
@@ -76,6 +76,7 @@ const char *_dl_profile_output;
 struct link_map *_dl_profile_map;
 int _dl_debug_libs;
 int _dl_debug_impcalls;
+int _dl_debug_bindings;
 
 /* Set nonzero during loading and initialization of executable and
    libraries, cleared before the executable's entry point runs.  This
@@ -928,6 +929,14 @@ process_dl_debug (char *dl_debug)
        ++dl_debug;
       if (*dl_debug != '\0')
        {
+         if (strncmp (dl_debug, "bindings", 8) == 0
+             && (issep (dl_debug[8]) || dl_debug[8] == '\0'))
+           {
+             _dl_debug_bindings = 1;
+             _dl_debug_impcalls = 1;
+             any_debug = 1;
+             dl_debug += 8;
+           }
          if (strncmp (dl_debug, "libs", 4) == 0
              && (issep (dl_debug[4]) || dl_debug[4] == '\0'))
            {
@@ -942,8 +951,13 @@ process_dl_debug (char *dl_debug)
              _dl_sysdep_message ("\
 Valid options for the LD_DEBUG environment variable are:\n\
 \n\
-  help    display this help message and exit
-  libs    display library search paths\n", NULL);
+  bindings  display information about symbol binding\n\
+  help      display this help message and exit\n\
+  libs      display library search paths\n\
+\n\
+To direct the debugging output into a file instead of standard output\n\
+a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
+                                 NULL);
              _exit (0);
            }
          else