summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/include/dl-elf.h4
-rw-r--r--ldso/ldso/dl-elf.c32
-rw-r--r--ldso/libdl/libdl.c6
3 files changed, 26 insertions, 16 deletions
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index d8f3b382c..06b881f21 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -84,6 +84,10 @@ void __dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void
dynamic_info[DT_BIND_NOW] = 1;
if (dpnt->d_tag == DT_TEXTREL)
dynamic_info[DT_TEXTREL] = 1;
+ if (dpnt->d_tag == DT_RUNPATH)
+ dynamic_info[DT_RPATH] = 0;
+ if (dpnt->d_tag == DT_RPATH && dynamic_info[DT_RUNPATH])
+ dynamic_info[DT_RPATH] = 0;
} else if (dpnt->d_tag < DT_LOPROC) {
if (dpnt->d_tag == DT_RELOCCOUNT)
dynamic_info[DT_RELCONT_IDX] = dpnt->d_un.d_val;
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 67d42110c..c8d2b9340 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -304,23 +304,17 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
}
/*
- * The ABI specifies that RPATH is searched before LD_*_PATH or
+ * The ABI specifies that RPATH is searched before LD_LIBRARY_PATH or
* the default path of /usr/lib. Check in rpath directories.
*/
- for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
- if (tpnt->libtype == elf_executable) {
- pnt = (char *) tpnt->dynamic_info[DT_RPATH];
- if (pnt) {
- pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB];
+ pnt = (tpnt ? (char *) tpnt->dynamic_info[DT_RPATH] : NULL);
+ if (pnt) {
+ pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB];
#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching RPATH='%s'\n", pnt);
+ if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching RPATH='%s'\n", pnt);
#endif
- if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL)
- {
- return tpnt1;
- }
- }
- }
+ if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL)
+ return tpnt1;
}
/* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
@@ -333,6 +327,18 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
return tpnt1;
}
}
+ /*
+ * The ABI specifies that RUNPATH is searched after LD_LIBRARY_PATH.
+ */
+ pnt = (tpnt ? (char *)tpnt->dynamic_info[DT_RUNPATH] : NULL);
+ if (pnt) {
+ pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB];
+#if defined (__SUPPORT_LD_DEBUG__)
+ if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching RUNPATH='%s'\n", pnt);
+#endif
+ if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL)
+ return tpnt1;
+ }
/*
* Where should the cache be searched? There is no such concept in the
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 0c744c210..78da63c38 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -128,7 +128,7 @@ void __attribute__ ((destructor)) dl_cleanup(void)
void *dlopen(const char *libname, int flag)
{
- struct elf_resolve *tpnt, *tfrom, *tcurr=NULL;
+ struct elf_resolve *tpnt, *tfrom;
struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle;
struct dyn_elf *dpnt;
ElfW(Addr) from;
@@ -155,7 +155,7 @@ void *dlopen(const char *libname, int flag)
/*
* Try and locate the module we were called from - we
- * need this so that we get the correct RPATH. Note that
+ * need this so that we get the correct RPATH/RUNPATH. Note that
* this is the current behavior under Solaris, but the
* ABI+ specifies that we should only use the RPATH from
* the application. Thus this may go away at some time
@@ -239,7 +239,7 @@ void *dlopen(const char *libname, int flag)
fprintf(stderr, "Trying to load '%s', needed by '%s'\n",
lpntstr, runp->tpnt->libname);
#endif
- tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, 0);
+ tpnt1 = _dl_load_shared_library(0, &rpnt, runp->tpnt, lpntstr, 0);
if (!tpnt1)
goto oops;