diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2005-03-23 19:48:06 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2005-03-23 19:48:06 +0000 |
commit | 3004e7060a61b8cd19902ea87d76783f0aa86144 (patch) | |
tree | 89de3b6a7b0f222e2297e1be89279be2a0ec4a9d /libexec/ld.so/library_mquery.c | |
parent | 1a88b22742a7df6205d19a7ecf78aba3eda53a16 (diff) |
Code reorganization, move copied code in library.c and library_mquery.c
into its own file. no functional change.
Diffstat (limited to 'libexec/ld.so/library_mquery.c')
-rw-r--r-- | libexec/ld.so/library_mquery.c | 326 |
1 files changed, 3 insertions, 323 deletions
diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c index 46139beda9e..2fa1165d627 100644 --- a/libexec/ld.so/library_mquery.c +++ b/libexec/ld.so/library_mquery.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library_mquery.c,v 1.15 2005/03/22 18:03:39 drahn Exp $ */ +/* $OpenBSD: library_mquery.c,v 1.16 2005/03/23 19:48:05 drahn Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -30,314 +30,18 @@ #define _DYN_LOADER #include <sys/types.h> -#include <sys/syslimits.h> #include <sys/param.h> #include <fcntl.h> -#include <nlist.h> -#include <link.h> #include <sys/mman.h> -#include <dirent.h> #include "syscall.h" #include "archdep.h" #include "resolve.h" -#include "dir.h" -#include "sod.h" - -#define DEFAULT_PATH "/usr/lib" #define PFLAGS(X) ((((X) & PF_R) ? PROT_READ : 0) | \ (((X) & PF_W) ? PROT_WRITE : 0) | \ (((X) & PF_X) ? PROT_EXEC : 0)) -elf_object_t *_dl_tryload_shlib(const char *libname, int type); - -/* - * _dl_match_file() - * - * This fucntion determines if a given name matches what is specified - * in a struct sod. The major must match exactly, and the minor must - * be same or larger. - * - * sodp is updated with the minor if this matches. - */ - -int -_dl_match_file(struct sod *sodp, char *name, int namelen) -{ - int match; - struct sod lsod; - char *lname; - - lname = name; - if (sodp->sod_library) { - if (_dl_strncmp(name, "lib", 3)) - return 0; - lname += 3; - } - if (_dl_strncmp(lname, (char *)sodp->sod_name, - _dl_strlen((char *)sodp->sod_name))) - return 0; - - _dl_build_sod(name, &lsod); - - match = 0; - if ((_dl_strcmp((char *)lsod.sod_name, (char *)sodp->sod_name) == 0) && - (lsod.sod_library == sodp->sod_library) && - ((sodp->sod_major == -1) || (sodp->sod_major == lsod.sod_major)) && - ((sodp->sod_minor == -1) || - (lsod.sod_minor >= sodp->sod_minor))) { - match = 1; - - /* return version matched */ - sodp->sod_major = lsod.sod_major; - sodp->sod_minor = lsod.sod_minor; - } - _dl_free((char *)lsod.sod_name); - return match; -} - -char _dl_hint_store[MAXPATHLEN]; - -char * -_dl_find_shlib(struct sod *sodp, const char *searchpath, int nohints) -{ - char *hint, lp[PATH_MAX + 10], *path; - struct dirent *dp; - const char *pp; - int match, len; - DIR *dd; - struct sod tsod, bsod; /* transient and best sod */ - - /* if we are to search default directories, and hints - * are not to be used, search the standard path from ldconfig - * (_dl_hint_search_path) or use the default path - */ - if (nohints) - goto nohints; - - if (searchpath == NULL) { - /* search 'standard' locations, find any match in the hints */ - hint = _dl_findhint((char *)sodp->sod_name, sodp->sod_major, - sodp->sod_minor, NULL); - if (hint) - return hint; - } else { - /* search hints requesting matches for only - * the searchpath directories, - */ - pp = searchpath; - while (pp) { - path = lp; - while (path < lp + PATH_MAX && - *pp && *pp != ':' && *pp != ';') - *path++ = *pp++; - *path = 0; - - /* interpret "" as curdir "." */ - if (lp[0] == '\0') { - lp[0] = '.'; - lp[1] = '\0'; - } - - hint = _dl_findhint((char *)sodp->sod_name, - sodp->sod_major, sodp->sod_minor, lp); - if (hint != NULL) - return hint; - - if (*pp) /* Try curdir if ':' at end */ - pp++; - else - pp = 0; - } - } - - /* - * For each directory in the searchpath, read the directory - * entries looking for a match to sod. filename compare is - * done by _dl_match_file() - */ -nohints: - if (searchpath == NULL) { - if (_dl_hint_search_path != NULL) - searchpath = _dl_hint_search_path; - else - searchpath = DEFAULT_PATH; - } - pp = searchpath; - while (pp) { - path = lp; - while (path < lp + PATH_MAX && *pp && *pp != ':' && *pp != ';') - *path++ = *pp++; - *path = 0; - - /* interpret "" as curdir "." */ - if (lp[0] == '\0') { - lp[0] = '.'; - lp[1] = '\0'; - } - - if ((dd = _dl_opendir(lp)) != NULL) { - match = 0; - while ((dp = _dl_readdir(dd)) != NULL) { - tsod = *sodp; - if (_dl_match_file(&tsod, dp->d_name, - dp->d_namlen)) { - /* - * When a match is found, tsod is - * updated with the major+minor found. - * This version is compared with the - * largest so far (kept in bsod), - * and saved if larger. - */ - if (!match || - tsod.sod_major == -1 || - tsod.sod_major > bsod.sod_major || - ((tsod.sod_major == - bsod.sod_major) && - tsod.sod_minor > bsod.sod_minor)) { - bsod = tsod; - match = 1; - len = _dl_strlcpy( - _dl_hint_store, lp, - MAXPATHLEN); - if (lp[len-1] != '/') { - _dl_hint_store[len] = - '/'; - len++; - } - _dl_strlcpy( - &_dl_hint_store[len], - dp->d_name, - MAXPATHLEN-len); - if (tsod.sod_major == -1) - break; - } - } - } - _dl_closedir(dd); - if (match) { - *sodp = bsod; - return (_dl_hint_store); - } - } - - if (*pp) /* Try curdir if ':' at end */ - pp++; - else - pp = 0; - } - return NULL; -} - -/* - * Load a shared object. Search order is: - * If the name contains a '/' use the name exactly as is. (only) - * try the LD_LIBRARY_PATH specification (if present) - * search hints for match in LD_LIBRARY_PATH dirs - * this will only match specific libary version. - * search LD_LIBRARY_PATH dirs for match. - * this will find largest minor version in first dir found. - * check DT_RPATH paths, (if present) - * search hints for match in DT_RPATH dirs - * this will only match specific libary version. - * search DT_RPATH dirs for match. - * this will find largest minor version in first dir found. - * last look in default search directory, either as specified - * by ldconfig or default to '/usr/lib' - */ - -elf_object_t * -_dl_load_shlib(const char *libname, elf_object_t *parent, int type, int flags) -{ - int try_any_minor, ignore_hints; - struct sod sod, req_sod; - elf_object_t *object; - char *hint; - - try_any_minor = 0; - ignore_hints = 0; - - if (_dl_strchr(libname, '/')) { - object = _dl_tryload_shlib(libname, type); - return(object); - } - - _dl_build_sod(libname, &sod); - req_sod = sod; - -again: - /* - * No '/' in name. Scan the known places, LD_LIBRARY_PATH first. - */ - if (_dl_libpath != NULL) { - hint = _dl_find_shlib(&req_sod, _dl_libpath, ignore_hints); - if (hint != NULL) { - if (req_sod.sod_minor < sod.sod_minor) - _dl_printf("warning: lib%s.so.%d.%d: " - "minor version >= %d expected, " - "using it anyway\n", - sod.sod_name, sod.sod_major, - req_sod.sod_minor, sod.sod_minor); - object = _dl_tryload_shlib(hint, type); - if (object != NULL) { - _dl_free((char *)sod.sod_name); - object->obj_flags = flags; - return (object); - } - } - } - - /* - * Check DT_RPATH. - */ - if (parent->dyn.rpath != NULL) { - hint = _dl_find_shlib(&req_sod, parent->dyn.rpath, - ignore_hints); - if (hint != NULL) { - if (req_sod.sod_minor < sod.sod_minor) - _dl_printf("warning: lib%s.so.%d.%d: " - "minor version >= %d expected, " - "using it anyway\n", - sod.sod_name, sod.sod_major, - req_sod.sod_minor, sod.sod_minor); - object = _dl_tryload_shlib(hint, type); - if (object != NULL) { - _dl_free((char *)sod.sod_name); - object->obj_flags = flags; - return (object); - } - } - } - - /* check 'standard' locations */ - hint = _dl_find_shlib(&req_sod, NULL, ignore_hints); - if (hint != NULL) { - if (req_sod.sod_minor < sod.sod_minor) - _dl_printf("warning: lib%s.so.%d.%d: " - "minor version >= %d expected, " - "using it anyway\n", - sod.sod_name, sod.sod_major, - req_sod.sod_minor, sod.sod_minor); - object = _dl_tryload_shlib(hint, type); - if (object != NULL) { - _dl_free((char *)sod.sod_name); - object->obj_flags = flags; - return(object); - } - } - - if (try_any_minor == 0) { - try_any_minor = 1; - ignore_hints = 1; - req_sod.sod_minor = -1; - goto again; - } - _dl_free((char *)sod.sod_name); - _dl_errno = DL_NOT_FOUND; - return(0); -} - void _dl_load_list_free(struct load_list *load_list) { @@ -354,8 +58,6 @@ _dl_load_list_free(struct load_list *load_list) } } -void _dl_run_dtors(elf_object_t *object); - void _dl_unload_shlib(elf_object_t *object) { @@ -381,7 +83,7 @@ _dl_tryload_shlib(const char *libname, int type) int size; Elf_Addr load_end = 0; struct stat sb; - + #define ROUND_PG(x) (((x) + align) & ~(align)) #define TRUNC_PG(x) ((x) & ~(align)) @@ -409,7 +111,7 @@ _dl_tryload_shlib(const char *libname, int type) return(object); } } - + _dl_read(libfile, hbuf, sizeof(hbuf)); ehdr = (Elf_Ehdr *)hbuf; if (ehdr->e_ident[0] != ELFMAG0 || ehdr->e_ident[1] != ELFMAG1 || @@ -572,25 +274,3 @@ fail: _dl_load_list_free(lowld); return(0); } - -void -_dl_link_sub(elf_object_t *dep, elf_object_t *p) -{ - struct dep_node *n; - - n = _dl_malloc(sizeof *n); - if (n == NULL) - _dl_exit(5); - n->data = dep; - n->next_sibling = NULL; - if (p->first_child) { - p->last_child->next_sibling = n; - p->last_child = n; - } else - p->first_child = p->last_child = n; - - DL_DEB(("linking dep %s as child of %s\n", dep->load_name, - p->load_name)); -} - - |