about summary refs log tree commit diff
path: root/elf/dl-deps.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-deps.c')
-rw-r--r--elf/dl-deps.c74
1 files changed, 56 insertions, 18 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 01e4f1974e..f034196762 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -1,5 +1,5 @@
 /* Load the dependencies of a mapped object.
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997 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
@@ -32,33 +32,65 @@ _dl_map_object_deps (struct link_map *map,
       struct link_map *map;
       struct list *next;
     };
-  struct list head[1 + npreloads], *tailp, *scanp;
+  struct list head[2 + npreloads], *tailp, *scanp;
   struct list duphead, *duptailp;
-  unsigned int nlist;
   unsigned int nduplist;
+  unsigned int nlist, naux, i;
+  inline void preload (struct link_map *map)
+    {
+      head[nlist].next = &head[nlist + 1];
+      head[nlist++].map = map;
 
-  /* Start the search list with one element: MAP itself.  */
-  head[0].map = map;
+      /* We use `l_reserved' as a mark bit to detect objects we have
+	 already put in the search list and avoid adding duplicate
+	 elements later in the list.  */
+      map->l_reserved = 1;
+    }
 
-  /* We use `l_reserved' as a mark bit to detect objects we have already
-     put in the search list and avoid adding duplicate elements later in
-     the list.  */
-  map->l_reserved = 1;
+  naux = nlist = 0;
 
-  /* Add the preloaded items after MAP but before any of its dependencies.  */
-  for (nlist = 0; nlist < npreloads; ++nlist)
+#define AUXTAG	(DT_NUM + DT_PROCNUM + DT_EXTRATAGIDX (DT_AUXILIARY))
+
+  if (map->l_info[AUXTAG])
     {
-      head[nlist].next = &head[nlist + 1];
-      head[nlist + 1].map = preloads[nlist];
-      preloads[nlist]->l_reserved = 1;
+      /* There is an auxiliary library specified.  We try to load it,
+	 and if we can, use its symbols in preference to our own.
+	 But if we can't load it, we just silently ignore it.
+	 XXX support multiple DT_AUXILIARYs?
+       */
+      struct link_map *aux;
+      void openaux (void)
+	{
+	  const char *strtab
+	    = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
+	  aux = _dl_map_object (map, strtab + map->l_info[AUXTAG]->d_un.d_val,
+				map->l_type == lt_executable ? lt_library :
+				map->l_type, trace_mode);
+	}
+      char *errstring;
+      const char *objname;
+      if (! _dl_catch_error (&errstring, &objname, &openaux))
+	{
+	  /* The auxiliary object is actually there.  Use it
+	     as the first search element, even before MAP itself.  */
+	  preload (aux);
+	  naux = 1;
+	}
     }
 
+  /* Start the search list with one element: MAP itself.  */
+  preload (map);
+
+  /* Add the preloaded items after MAP but before any of its dependencies.  */
+  for (i = 0; i < npreloads; ++i)
+    preload (preloads[i]);
+
   /* Terminate the lists.  */
-  head[nlist].next = NULL;
+  head[nlist - 1].next = NULL;
   duphead.next = NULL;
 
   /* Start here for adding dependencies to the list.  */
-  tailp = &head[nlist++];
+  tailp = &head[nlist - 1];
 
   /* Until now we have the same number of libraries in the normal and
      the list with duplicates.  */
@@ -104,7 +136,7 @@ _dl_map_object_deps (struct link_map *map,
 		    dep->l_reserved = 1;
 		  }
 
-		/* In any case Append DEP to the duplicates search list.  */
+		/* In any case append DEP to the duplicates search list.  */
 		duptailp->next = alloca (sizeof *duptailp);
 		duptailp = duptailp->next;
 		duptailp->map = dep;
@@ -117,6 +149,9 @@ _dl_map_object_deps (struct link_map *map,
   /* Store the search list we built in the object.  It will be used for
      searches in the scope of this object.  */
   map->l_searchlist = malloc (nlist * sizeof (struct link_map *));
+  if (map->l_searchlist == NULL)
+    _dl_signal_error (ENOMEM, map->l_name,
+		      "cannot allocate symbol search list");
   map->l_nsearchlist = nlist;
 
   nlist = 0;
@@ -130,9 +165,12 @@ _dl_map_object_deps (struct link_map *map,
     }
 
   map->l_dupsearchlist = malloc (nduplist * sizeof (struct link_map *));
+  if (map->l_dupsearchlist == NULL)
+    _dl_signal_error (ENOMEM, map->l_name,
+		      "cannot allocate symbol search list");
   map->l_ndupsearchlist = nduplist;
 
-  for (nlist = 0; nlist < npreloads + 1; ++nlist)
+  for (nlist = 0; nlist < naux + 1 + npreloads; ++nlist)
     map->l_dupsearchlist[nlist] = head[nlist].map;
   for (scanp = duphead.next; scanp; scanp = scanp->next)
     map->l_dupsearchlist[nlist++] = scanp->map;