about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile16
-rw-r--r--elf/dl-error.c2
-rw-r--r--elf/dl-load.c115
3 files changed, 84 insertions, 49 deletions
diff --git a/elf/Makefile b/elf/Makefile
index f8dc9d0ef2..fb85b85e3c 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -30,7 +30,7 @@ dl-routines	= $(addprefix dl-,load cache lookup object reloc deps \
 			          runtime error init fini debug misc \
 				  version profile)
 # But they are absent from the shared libc, because that code is in ld.so.
-elide-routines.so = $(dl-routines) dl-support enbl-secure
+elide-routines.os = $(dl-routines) dl-support enbl-secure
 
 # ld.so uses those routines, plus some special stuff for being the program
 # interpreter and operating independent of libc.
@@ -54,8 +54,8 @@ all: # Make this the default target; it will be defined in Rules.
 include ../Makeconfig
 
 ifeq (yes,$(build-shared))
-extra-objs	= $(rtld-routines:=.so) soinit.so sofini.so eval.so
-generated	= librtld.so dl-allobjs.so trusted-dirs.h rtldtbl.h
+extra-objs	= $(rtld-routines:=.os) soinit.os sofini.os eval.os
+generated	= librtld.os dl-allobjs.os trusted-dirs.h rtldtbl.h
 install-others	= $(inst_slibdir)/$(rtld-installed-name)
 install-bin	= ldd
 endif
@@ -85,11 +85,11 @@ endif
 # Command to link into a larger single relocatable object.
 reloc-link = $(LINK.o) -nostdlib -nostartfiles -r -o $@
 
-$(objpfx)dl-allobjs.so: $(rtld-routines:%=$(objpfx)%.so)
+$(objpfx)dl-allobjs.os: $(rtld-routines:%=$(objpfx)%.os)
 	$(reloc-link) $^
 
 # Link together the dynamic linker into a single relocatable object.
-$(objpfx)librtld.so: $(objpfx)dl-allobjs.so $(common-objpfx)libc_pic.a
+$(objpfx)librtld.os: $(objpfx)dl-allobjs.os $(common-objpfx)libc_pic.a
 	$(reloc-link) '-Wl,-(' $^ -lgcc '-Wl,-)'
 
 # Do we need a linker script?
@@ -107,7 +107,7 @@ $(objpfx)rtld-ldscript: $(rtld-ldscript-in) $(rtld-parms)
 	    -e 's#@@rtld-entry@@#$(rtld-entry)#' \
 	    -e 's#@@rtld-base@@#$(rtld-base)#' $< >$@
 
-$(objpfx)ld.so: $(objpfx)librtld.so $(objpfx)rtld-ldscript
+$(objpfx)ld.so: $(objpfx)librtld.os $(objpfx)rtld-ldscript
 	$(rtld-link) -Wl,-soname=$(rtld-installed-name)
 
 define rtld-link
@@ -116,7 +116,7 @@ $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
 	  $(filter-out $(objpfx)rtld-ldscript,$^)
 endef
 else
-$(objpfx)ld.so: $(objpfx)librtld.so
+$(objpfx)ld.so: $(objpfx)librtld.os
 	$(rtld-link) -Wl,-soname=$(rtld-installed-name)
 
 define rtld-link
@@ -186,4 +186,4 @@ endif
 # muwahaha
 
 LDFLAGS-dl.so = -Wl,-dynamic-linker,$(slibdir)/$(rtld-installed-name)
-$(objpfx)libdl.so: $(objpfx)eval.so
+$(objpfx)libdl.so: $(objpfx)eval.os
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 7ee803ad9b..72af85985d 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -75,7 +75,7 @@ _dl_signal_error (int errcode,
       /* Lossage while resolving the program's own symbols is always fatal.  */
       extern char **_dl_argv;	/* Set in rtld.c at startup.  */
       _dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
-			": error in loading shared libraries",
+			": error in loading shared libraries: ",
 			objname ?: "", objname ? ": " : "",
 			errstring, errcode ? ": " : "",
 			errcode ? strerror (errcode) : "", "\n", NULL);
diff --git a/elf/dl-load.c b/elf/dl-load.c
index f0af29292a..ce3bd9fb94 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -94,6 +94,11 @@ size_t _dl_pagesize;
 extern const char *_dl_platform;
 extern size_t _dl_platformlen;
 
+/* This is a fake list to store the RPATH information for static
+   binaries.  */
+static struct r_search_path_elem **fake_path_list;
+
+
 /* Local version of `strdup' function.  */
 static inline char *
 local_strdup (const char *s)
@@ -308,6 +313,12 @@ decompose_rpath (const char *rpath, size_t additional_room)
 void
 _dl_init_paths (void)
 {
+  static const char *trusted_dirs[] =
+  {
+#include "trusted-dirs.h"
+    NULL
+  };
+
   struct r_search_path_elem **pelem;
 
   /* We have in `search_path' the information about the RPATH of the
@@ -333,53 +344,72 @@ _dl_init_paths (void)
     nllp = 0;
 
   l = _dl_loaded;
-  if (l && l->l_type != lt_loaded && l->l_info[DT_RPATH])
+  if (l != NULL)
     {
-      /* Allocate room for the search path and fill in information from
-	 RPATH.  */
-      l->l_rpath_dirs =
-	decompose_rpath ((const char *) (l->l_addr
-					 + l->l_info[DT_STRTAB]->d_un.d_ptr
-					 + l->l_info[DT_RPATH]->d_un.d_val),
-			 nllp);
+      if (l->l_type != lt_loaded && l->l_info[DT_RPATH])
+	{
+	  /* Allocate room for the search path and fill in information
+	     from RPATH.  */
+	  l->l_rpath_dirs =
+	    decompose_rpath ((const char *)
+			     (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr
+			      + l->l_info[DT_RPATH]->d_un.d_val),
+			     nllp);
+	}
+      else
+	{
+	  /* If we have no LD_LIBRARY_PATH and no RPATH we must tell
+	     this somehow to prevent we look this up again and again.  */
+	  if (nllp == 0)
+	    l->l_rpath_dirs = (struct r_search_path_elem **) -1l;
+	  else
+	    {
+	      l->l_rpath_dirs = (struct r_search_path_elem **)
+		malloc ((nllp + 1) * sizeof (*l->l_rpath_dirs));
+	      if (l->l_rpath_dirs == NULL)
+		_dl_signal_error (ENOMEM, NULL,
+				  "cannot create cache for search path");
+	      l->l_rpath_dirs[0] = NULL;
+	    }
+	}
+
+      /* We don't need to search the list of fake entries which is searched
+	 when no dynamic objects were loaded at this time.  */
+      fake_path_list = NULL;
+
+      if (nllp > 0)
+	{
+	  char *copy = strdupa (llp);
+
+	  /* Decompose the LD_LIBRARY_PATH and fill in the result.
+	     First search for the next place to enter elements.  */
+	  struct r_search_path_elem **result = l->l_rpath_dirs;
+	  while (*result != NULL)
+	    ++result;
+
+	  /* We need to take care that the LD_LIBRARY_PATH environment
+	     variable can contain a semicolon.  */
+	  (void) fillin_rpath (copy, result, ":;",
+			       __libc_enable_secure ? trusted_dirs : NULL);
+	}
     }
   else
     {
-      /* If we have no LD_LIBRARY_PATH and no RPATH we must tell this
-	 somehow to prevent we look this up again and again.  */
+      /* This is a statically linked program but we still have to
+	 take care for the LD_LIBRARY_PATH environment variable.  We
+	 use a fake link_map entry.  This will only contain the
+	 l_rpath_dirs information.  */
+
       if (nllp == 0)
-	 l->l_rpath_dirs = (struct r_search_path_elem **) -1l;
+	fake_path_list = NULL;
       else
 	{
-	  l->l_rpath_dirs =
-	    (struct r_search_path_elem **) malloc ((nllp + 1)
-						   * sizeof (*l->l_rpath_dirs));
-	  if (l->l_rpath_dirs == NULL)
-	    _dl_signal_error (ENOMEM, NULL,
-			      "cannot create cache for search path");
-	  l->l_rpath_dirs[0] = NULL;
-	}
-    }
+	  fake_path_list = (struct r_search_path_elem **)
+	    malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
 
-  if (nllp > 0)
-    {
-      static const char *trusted_dirs[] =
-      {
-#include "trusted-dirs.h"
-	NULL
-      };
-      char *copy = strdupa (llp);
-
-      /* Decompose the LD_LIBRARY_PATH and fill in the result.
-         First search for the next place to enter elements.  */
-      struct r_search_path_elem **result = l->l_rpath_dirs;
-      while (*result != NULL)
-	++result;
-
-      /* We need to take care that the LD_LIBRARY_PATH environement
-	 variable can contain a semicolon.  */
-      (void) fillin_rpath (copy, result, ":;",
-			   __libc_enable_secure ? trusted_dirs : NULL);
+	  (void) fillin_rpath (local_strdup (llp), fake_path_list, ":;",
+			       __libc_enable_secure ? trusted_dirs : NULL);
+	}
     }
 
   /* Now set up the rest of the rtld_search_dirs.  */
@@ -871,7 +901,7 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
 
   /* Look for this name among those already loaded.  */
   for (l = _dl_loaded; l; l = l->l_next)
-    if (_dl_name_match_p (name, l) ||
+    if (l->l_opencount > 0 && _dl_name_match_p (name, l) ||
 	/* If the requested name matches the soname of a loaded object,
 	   use that object.  */
 	(l->l_info[DT_SONAME] &&
@@ -923,6 +953,11 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
 	  && l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
 	fd = open_path (name, namelen, l->l_rpath_dirs, &realname);
 
+      /* This is used if a static binary uses dynamic loading and there
+	 is a LD_LIBRARY_PATH given.  */
+      if (fd == -1 && fake_path_list != NULL)
+	fd = open_path (name, namelen, fake_path_list, &realname);
+
       if (fd == -1)
 	{
 	  /* Check the list of libraries in the file /etc/ld.so.cache,