diff options
Diffstat (limited to 'libexec/rtld-elf')
-rw-r--r-- | libexec/rtld-elf/rtld.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index c52efa0..5cb35e0 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.6 1998/09/02 02:51:12 jdp Exp $ + * $Id: rtld.c,v 1.7 1998/09/04 19:03:57 dfr Exp $ */ /* @@ -75,6 +75,7 @@ static void digest_dynamic(Obj_Entry *); static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t); static Obj_Entry *dlcheck(void *); static char *find_library(const char *, const Obj_Entry *); +static const char *gethints(void); static void init_rtld(caddr_t); static bool is_exported(const Elf_Sym *); static void linkmap_add(Obj_Entry *); @@ -626,6 +627,12 @@ elf_hash(const char *name) * * If the second argument is non-NULL, then it refers to an already- * loaded shared object, whose library search path will be searched. + * + * The search order is: + * LD_LIBRARY_PATH + * ldconfig hints + * rpath in the referencing file + * /usr/lib */ static char * find_library(const char *name, const Obj_Entry *refobj) @@ -643,9 +650,10 @@ find_library(const char *name, const Obj_Entry *refobj) dbg(" Searching for \"%s\"", name); - if ((refobj != NULL && + if ((pathname = search_library_path(name, ld_library_path)) != NULL || + (pathname = search_library_path(name, gethints())) != NULL || + (refobj != NULL && (pathname = search_library_path(name, refobj->rpath)) != NULL) || - (pathname = search_library_path(name, ld_library_path)) != NULL || (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL) return pathname; @@ -747,6 +755,45 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj, } /* + * Return the search path from the ldconfig hints file, reading it if + * necessary. Returns NULL if there are problems with the hints file, + * or if the search path there is empty. + */ +static const char * +gethints(void) +{ + static char *hints; + + if (hints == NULL) { + int fd; + struct elfhints_hdr hdr; + char *p; + + /* Keep from trying again in case the hints file is bad. */ + hints = ""; + + if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1) + return NULL; + if (read(fd, &hdr, sizeof hdr) != sizeof hdr || + hdr.magic != ELFHINTS_MAGIC || + hdr.version != 1) { + close(fd); + return NULL; + } + p = xmalloc(hdr.dirlistlen + 1); + if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 || + read(fd, p, hdr.dirlistlen + 1) != hdr.dirlistlen + 1) { + free(p); + close(fd); + return NULL; + } + hints = p; + close(fd); + } + return hints[0] != '\0' ? hints : NULL; +} + +/* * Initialize the dynamic linker. The argument is the address at which * the dynamic linker has been mapped into memory. The primary task of * this function is to relocate the dynamic linker. |