#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 */
#ifdef __UCLIBC_HAS_SSP__
# include <dl-osinfo.h>
-uintptr_t stack_chk_guard;
+static uintptr_t stack_chk_guard;
# ifndef THREAD_SET_STACK_GUARD
/* Only exported for architectures that don't store the stack guard canary
* in local thread area. */
uintptr_t __stack_chk_guard attribute_relro;
-# ifdef __UCLIBC_HAS_SSP_COMPAT__
-strong_alias(__stack_chk_guard,__guard)
-# endif
-# elif __UCLIBC_HAS_SSP_COMPAT__
+# endif
+# ifdef __UCLIBC_HAS_SSP_COMPAT__
uintptr_t __guard attribute_relro;
# 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;
tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
}
+#if defined USE_TLS && USE_TLS
if ((tpnt->libtype != program_interpreter) && (tpnt->l_tls_modid))
_dl_dprintf (1, " TLS(%x, %x)\n", tpnt->l_tls_modid,
(size_t) tpnt->l_tls_offset);
else
+#endif
_dl_dprintf (1, "\n");
}
#endif
ElfW(Phdr) *ppnt;
ElfW(Dyn) *dpnt;
char *lpntstr;
- unsigned int i, cnt, k, nscope_elem;
+ unsigned int i, cnt, nscope_elem;
int unlazy = 0, trace_loaded_objects = 0;
struct dyn_elf *rpnt;
struct elf_resolve *tcurr;
#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. */
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)
char *preload;
int fd;
char c, *cp, *cp2;
+ struct stat st;
if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
break;
local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
i = 1;
for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
+ unsigned int k;
cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]);
tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *));
tcurr->symbol_scope.r_nlist = cnt;
stack_chk_guard = _dl_setup_stack_chk_guard ();
# ifdef THREAD_SET_STACK_GUARD
THREAD_SET_STACK_GUARD (stack_chk_guard);
-# ifdef __UCLIBC_HAS_SSP_COMPAT__
- __guard = stack_chk_guard;
-# endif
# else
__stack_chk_guard = stack_chk_guard;
# endif
+# ifdef __UCLIBC_HAS_SSP_COMPAT__
+ __guard = stack_chk_guard;
+# endif
#endif
#ifdef __LDSO_PRELINK_SUPPORT__
* ld.so.1, so we have to look up each symbol individually.
*/
- _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, NULL, 0, NULL);
+ _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, 0, NULL);
if (_dl_envp)
*_dl_envp = (unsigned long) envp;
/* Find the real malloc function and make ldso functions use that from now on */
_dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
- global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
+ global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
#if defined(USE_TLS) && USE_TLS
/* Find the real functions and make ldso functions use them from now on */
_dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
- _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
+ _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
_dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
- _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
+ _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
_dl_free_function = (void (*)(void *)) (intptr_t)
- _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
+ _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
_dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
- _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
+ _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
#endif