From 61c12b27780e5aec8d4535d5d35bf58765ef4c26 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Wed, 1 Jun 2005 14:08:13 +0000 Subject: Initial support for both RUNPATH support. RPATH sematics changed to match RUNPATH. Only difference is that RPATH is searched before LD_LIBRARY_PATH and RUNPATH after. This is not complete but better than the current mess(I think). --- ldso/include/dl-elf.h | 4 ++++ ldso/ldso/dl-elf.c | 32 +++++++++++++++++++------------- ldso/libdl/libdl.c | 6 +++--- 3 files changed, 26 insertions(+), 16 deletions(-) (limited to 'ldso') 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; -- cgit v1.2.3