about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-deps.c74
-rw-r--r--elf/dl-error.c9
-rw-r--r--elf/dynamic-link.h9
-rw-r--r--elf/elf.h10
-rw-r--r--elf/ldd.bash.in6
-rw-r--r--elf/ldd.sh.in8
-rw-r--r--elf/link.h9
7 files changed, 89 insertions, 36 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;
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 55d9c2fc93..52eb577eb0 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -1,5 +1,5 @@
 /* Error handling for runtime dynamic linker.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 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
@@ -76,21 +76,22 @@ _dl_catch_error (char **errstring,
 		 void (*operate) (void))
 {
   int errcode;
-  struct catch c = { errstring: NULL, objname: NULL };
+  struct catch *old, c = { errstring: NULL, objname: NULL };
 
+  old = catch;
   errcode = setjmp (c.env);
   if (errcode == 0)
     {
       catch = &c;
       (*operate) ();
-      catch = NULL;
+      catch = old;
       *errstring = NULL;
       *objname = NULL;
       return 0;
     }
 
   /* We get here only if we longjmp'd out of OPERATE.  */
-  catch = NULL;
+  catch = old;
   *errstring = c.errstring;
   *objname = c.objname;
   return errcode == -1 ? 0 : errcode;
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 97eb6a58c8..c613f824d8 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -1,5 +1,5 @@
 /* Inline functions for dynamic linking.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 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
@@ -25,11 +25,12 @@
 /* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */
 
 static inline void __attribute__ ((unused))
-elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Dyn) *info[DT_NUM + DT_PROCNUM])
+elf_get_dynamic_info (ElfW(Dyn) *dyn,
+		      ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_EXTRANUM])
 {
   unsigned int i;
 
-  for (i = 0; i < DT_NUM + DT_PROCNUM; ++i)
+  for (i = 0; i < DT_NUM + DT_PROCNUM + DT_EXTRANUM; ++i)
     info[i] = NULL;
 
   if (! dyn)
@@ -42,6 +43,8 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Dyn) *info[DT_NUM + DT_PROCNUM])
       else if (dyn->d_tag >= DT_LOPROC &&
 	       dyn->d_tag < DT_LOPROC + DT_PROCNUM)
 	info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
+      else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
+	info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM] = dyn;
       else
 	assert (! "bad dynamic tag");
       dyn++;
diff --git a/elf/elf.h b/elf/elf.h
index f111508889..d25934b411 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1,5 +1,5 @@
 /* This file defines standard ELF types, structures, and macros.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ian Lance Taylor <ian@cygnus.com>.
 
@@ -464,6 +464,14 @@ typedef struct
 #define DT_HIPROC	0x7fffffff	/* End of processor-specific */
 #define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
 
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+
 /* Auxiliary vector.  */
 
 /* This vector is normally only used by the program interpreter.  The
diff --git a/elf/ldd.bash.in b/elf/ldd.bash.in
index 311ef82550..6e2b51591a 100644
--- a/elf/ldd.bash.in
+++ b/elf/ldd.bash.in
@@ -1,6 +1,6 @@
 #! @BASH@
 
-# 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
@@ -34,7 +34,7 @@ while test $# -gt 0; do
   case "$1" in
   --v*)
     echo $"ldd (GNU libc) @VERSION@
-Copyright (C) 1996 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997 Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
     exit 0 ;;
@@ -42,7 +42,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
     echo $"ldd [OPTION]... FILE...
   --help           print this help and exit
   --version        print version information and exit
-Report bugs to <bug-glibc@prep.ai.mit.edu>."
+Report bugs using the \`glibcbug' script to <bugs@gnu.ai.mit.edu>."
     exit 0 ;;
   --)		# Stop option processing.
     shift; break ;;
diff --git a/elf/ldd.sh.in b/elf/ldd.sh.in
index 7b7276f544..5b6cc3a75d 100644
--- a/elf/ldd.sh.in
+++ b/elf/ldd.sh.in
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-# 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
@@ -30,15 +30,15 @@ while test $# -gt 0; do
   case "$1" in
   --v*)
     echo 'ldd (GNU libc) @VERSION@
-Copyright (C) 1996 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997 Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.'
     exit 0 ;;
   --h*)
-    echo 'ldd [OPTION]... FILE...
+    echo "ldd [OPTION]... FILE...
   --help           print this help and exit
   --version        print version information and exit
-Report bugs to <bug-glibc@prep.ai.mit.edu>.'
+Report bugs using the \`glibcbug' script to <bugs@gnu.ai.mit.edu>."
     exit 0 ;;
   --)		# Stop option processing.
     shift; break ;;
diff --git a/elf/link.h b/elf/link.h
index b277bf75c1..7e0b60793f 100644
--- a/elf/link.h
+++ b/elf/link.h
@@ -1,5 +1,5 @@
 /* Run-time dynamic linker data structures for loaded ELF shared objects.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 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
@@ -97,8 +97,11 @@ struct link_map
     const char *l_libname;	/* Name requested (before search).  */
     /* Indexed pointers to dynamic section.
        [0,DT_NUM) are indexed by the processor-independent tags.
-       [DT_NUM,DT_NUM+DT_PROCNUM] are indexed by the tag minus DT_LOPROC.  */
-    ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM];
+       [DT_NUM,DT_NUM+DT_PROCNUM) are indexed by the tag minus DT_LOPROC.
+       [DT_NUM+DT_PROCNUM,DT_NUM+DT_PROCNUM+DT_EXTRANUM) are indexed
+       by DT_EXTRATAGIDX(tagvalue) (see <elf.h>).  */
+
+    ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM + DT_EXTRANUM];
     const ElfW(Phdr) *l_phdr;	/* Pointer to program header table in core.  */
     ElfW(Addr) l_entry;		/* Entry point location.  */
     ElfW(Half) l_phnum;		/* Number of program header entries.  */