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
 	  Usage of RUNPATH tags is not too common, so disabling this feature
 	  should be safe for most people.
 	  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
 config LDSO_SAFE_RUNPATH
 	bool "Allow only RUNPATH beginning with /"
 	bool "Allow only RUNPATH beginning with /"
 	depends on LDSO_RUNPATH
 	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)
 	if (tpnt1 != NULL)
 		return tpnt1;
 		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:
 goof:
 	/* Well, we shot our wad on that one.  All we can do now is punt */
 	/* Well, we shot our wad on that one.  All we can do now is punt */
 	if (_dl_internal_error_number)
 	if (_dl_internal_error_number)