summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Ellcey <sellcey@imgtec.com>2015-02-19 16:03:26 -0800
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2015-02-20 15:41:13 +0100
commit409f14d9b5e47513d5c939120a33965997c8ceb2 (patch)
treeaf01e95643153b7632712b099057a07f2b61faf5
parent30a92760abebf268c255aa8a15c35ca0c865fe88 (diff)
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>
-rw-r--r--extra/Configs/Config.in9
-rw-r--r--ldso/ldso/dl-elf.c32
2 files changed, 41 insertions, 0 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index 84659650b..f5210cdf9 100644
--- a/extra/Configs/Config.in
+++ b/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
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 54501d143..56319056d 100644
--- a/ldso/ldso/dl-elf.c
+++ b/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)