Browse Source

Allow use of executable RUNPATH/RPATH when finding libraries.

This option will modify ldso so that it will use the executables
RUNPATH/RPATH to find to find libraries even though this behavour
is not standard.  Setting this option causes the uclibc dynamic linker
behavour to match the glibc dynamic linker.

Signed-off-by: Steve Ellcey <sellcey@imgtec.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Steve Ellcey 9 years ago
parent
commit
409f14d9b5
2 changed files with 41 additions and 0 deletions
  1. 9 0
      extra/Configs/Config.in
  2. 32 0
      ldso/ldso/dl-elf.c

+ 9 - 0
extra/Configs/Config.in

@@ -419,6 +419,15 @@ config LDSO_RUNPATH
 	  Usage of RUNPATH tags is not too common, so disabling this feature
 	  should be safe for most people.
 
+config LDSO_RUNPATH_OF_EXECUTABLE
+	bool "Use executables RUNPATH/RPATH when searching for libraries."
+	depends on LDSO_RUNPATH
+	default n
+	help
+	  Use the executables RUNPATH/RPATH to find to find libraries even
+	  though this behavour is not standard.  Setting this option causes
+	  the uclibc dynamic linker behavour to match the glibc dynamic linker.
+
 config LDSO_SAFE_RUNPATH
 	bool "Allow only RUNPATH beginning with /"
 	depends on LDSO_RUNPATH

+ 32 - 0
ldso/ldso/dl-elf.c

@@ -308,6 +308,38 @@ struct elf_resolve *_dl_load_shared_library(unsigned rflags, struct dyn_elf **rp
 	if (tpnt1 != NULL)
 		return tpnt1;
 
+#ifdef __LDSO_RUNPATH_OF_EXECUTABLE__
+	/* Very last resort, try the executable's DT_RUNPATH and DT_RPATH */
+	/* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#shobj_dependencies
+	 * The set of directories specified by a given DT_RUNPATH entry is
+	 * used to find only the immediate dependencies of the executable or
+	 * shared object containing the DT_RUNPATH entry. That is, it is
+	 * used only for those dependencies contained in the DT_NEEDED
+	 * entries of the dynamic structure containing the DT_RUNPATH entry,
+	 * itself. One object's DT_RUNPATH entry does not affect the search
+	 * for any other object's dependencies.
+	 *
+	 * glibc (around 2.19) violates this and the usual suspects are
+	 * abusing this bug^Wrelaxed, user-friendly behaviour.
+	 */
+
+	pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RUNPATH];
+	if (pnt) {
+		pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB];
+		_dl_if_debug_dprint("\tsearching exe's RUNPATH='%s'\n", pnt);
+		if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt)) != NULL)
+			return tpnt1;
+	}
+	pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RPATH];
+	if (pnt) {
+		pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB];
+		_dl_if_debug_dprint("\tsearching exe's RPATH='%s'\n", pnt);
+		if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt)) != NULL)
+			return tpnt1;
+	}
+#endif
+
+
 goof:
 	/* Well, we shot our wad on that one.  All we can do now is punt */
 	if (_dl_internal_error_number)