#include LDSO_ELFINTERP
/* Global variables used within the shared library loader */
+#ifdef __LDSO_LD_LIBRARY_PATH__
char *_dl_library_path = NULL; /* Where we look for libraries */
+#endif
#ifdef __LDSO_PRELOAD_ENV_SUPPORT__
char *_dl_preload = NULL; /* Things to be loaded before the libs */
#endif
-char *_dl_ldsopath = NULL; /* Location of the shared lib loader */
int _dl_errno = 0; /* We can't use the real errno in ldso */
size_t _dl_pagesize = 0; /* Store the page size for use later */
struct r_debug *_dl_debug_addr = NULL; /* Used to communicate with the gdb debugger */
# endif
#endif
+#ifdef __LDSO_SEARCH_INTERP_PATH__
+const char *_dl_ldsopath = NULL; /* Location of the shared lib loader */
+
+static void _dl_ldsopath_init(struct elf_resolve *tpnt)
+{
+ char *ldsopath, *ptmp;
+
+ /*
+ * Store the path where the shared lib loader was found for later use.
+ * Note that this logic isn't bullet proof when it comes to relative
+ * paths: if you use "./lib/ldso.so", and then the app does chdir()
+ * followed by dlopen(), the old ldso path won't get searched. But
+ * that is a fairly pathological use case, so if you don't like that,
+ * then set a full path to your interp and be done :P.
+ */
+ ldsopath = _dl_strdup(tpnt->libname);
+ ptmp = _dl_strrchr(ldsopath, '/');
+ /*
+ * If there is no "/", then set the path to "", and the code
+ * later on will take this to implicitly mean "search $PWD".
+ */
+ if (!ptmp)
+ ptmp = ldsopath;
+ *ptmp = '\0';
+
+ _dl_ldsopath = ldsopath;
+ _dl_debug_early("Lib Loader: (%x) %s: using path: %s\n",
+ (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname,
+ _dl_ldsopath);
+}
+#else
+#define _dl_ldsopath_init(tpnt)
+#endif
+
char *_dl_getenv(const char *symbol, char **envp)
{
char *pnt;
static struct elf_resolve * add_ldso(struct elf_resolve *tpnt,
DL_LOADADDR_TYPE load_addr,
+ ElfW(Addr) ldso_mapaddr,
ElfW(auxv_t) auxvt[AT_EGID + 1],
struct dyn_elf *rpnt)
{
ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
ElfW(Phdr) *myppnt = (ElfW(Phdr) *)
- DL_RELOC_ADDR(load_addr, epnt->e_phoff);
+ DL_RELOC_ADDR(DL_GET_RUN_ADDR(load_addr, ldso_mapaddr),
+ epnt->e_phoff);
int j;
struct stat st;
tpnt->dynamic_info, (unsigned long)tpnt->dynamic_addr,
0);
- tpnt->mapaddr = load_addr;
+ tpnt->mapaddr = ldso_mapaddr;
if (_dl_stat(tpnt->libname, &st) >= 0) {
tpnt->st_dev = st.st_dev;
tpnt->st_ino = st.st_ino;
ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv
DL_GET_READY_TO_RUN_EXTRA_PARMS)
{
- ElfW(Addr) app_mapaddr = 0;
+ ElfW(Addr) app_mapaddr = 0, ldso_mapaddr = 0;
ElfW(Phdr) *ppnt;
ElfW(Dyn) *dpnt;
char *lpntstr;
#ifdef __LDSO_PRELOAD_ENV_SUPPORT__
_dl_preload = _dl_getenv("LD_PRELOAD", envp);
#endif
+#ifdef __LDSO_LD_LIBRARY_PATH__
_dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
+#endif
} else {
static const char unsecure_envvars[] =
#ifdef EXTRA_UNSECURE_ENVVARS
#ifdef __LDSO_PRELOAD_ENV_SUPPORT__
_dl_preload = NULL;
#endif
+#ifdef __LDSO_LD_LIBRARY_PATH__
_dl_library_path = NULL;
+#endif
/* SUID binaries can be exploited if they do LAZY relocation. */
unlazy = RTLD_NOW;
}
#ifdef __LDSO_STANDALONE_SUPPORT__
if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
- char *ptmp;
unsigned int *aux_dat = (unsigned int *) argv;
int argc = aux_dat[-1];
tpnt->libname = argv[0];
while (argc > 1)
if (! _dl_strcmp (argv[1], "--library-path") && argc > 2) {
+#ifdef __LDSO_LD_LIBRARY_PATH__
_dl_library_path = argv[2];
+#endif
_dl_skip_args += 2;
argc -= 2;
argv += 2;
}
}
- /* Store the path where the shared lib loader was found
- * for later use
- */
- _dl_ldsopath = _dl_strdup(tpnt->libname);
- ptmp = _dl_strrchr(_dl_ldsopath, '/');
- if (ptmp != _dl_ldsopath)
- *ptmp = '\0';
-
- _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
+ _dl_ldsopath_init(tpnt);
} else {
#endif
/* OK, fill this in - we did not have this before */
if (ppnt->p_type == PT_INTERP) {
tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
-#ifdef __LDSO_SEARCH_INTERP_PATH__
- {
- char *ptmp;
- /* Store the path where the shared lib loader was found
- * for later use
- */
- _dl_ldsopath = _dl_strdup(tpnt->libname);
- ptmp = _dl_strrchr(_dl_ldsopath, '/');
- if (ptmp != _dl_ldsopath)
- *ptmp = '\0';
- }
- _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
-#endif
+
+ _dl_ldsopath_init(tpnt);
}
/* Discover any TLS sections if the target supports them. */
_dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
}
- _dl_debug_early("Found TLS header for appplication program\n");
+ _dl_debug_early("Found TLS header for application program\n");
break;
#else
_dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
}
#endif
+ ldso_mapaddr = (ElfW(Addr)) auxvt[AT_BASE].a_un.a_val;
/*
* OK, fix one more thing - set up debug_addr so it will point
* to our chain. Later we may need to fill in more fields, but this
*/
debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
debug_addr->r_version = 1;
- debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
+ debug_addr->r_ldbase = (ElfW(Addr))
+ DL_LOADADDR_BASE(DL_GET_RUN_ADDR(load_addr, ldso_mapaddr));
debug_addr->r_brk = (unsigned long) &_dl_debug_state;
_dl_debug_addr = debug_addr;
if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
_dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
- tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
+ tpnt1 = _dl_load_shared_library(
+ _dl_secure ? DL_RESOLVE_SECURE : 0,
+ &rpnt, NULL, str, trace_loaded_objects);
if (!tpnt1) {
#ifdef __LDSO_LDD_SUPPORT__
if (trace_loaded_objects || _dl_trace_prelink)
if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
if (!ldso_tpnt) {
/* Insert the ld.so only once */
- ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
+ ldso_tpnt = add_ldso(tpnt, load_addr,
+ ldso_mapaddr, auxvt, rpnt);
}
ldso_tpnt->usage_count++;
tpnt1 = ldso_tpnt;
* again once all libs are loaded.
*/
if (!ldso_tpnt) {
- tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
+ tpnt = add_ldso(tpnt, load_addr, ldso_mapaddr, auxvt, rpnt);
tpnt->usage_count++;
nscope_elem++;
} else