/* System-specific function to do initial startup for the dynamic linker.
After this, file access calls and getenv must work. This is responsible
- for setting _dl_secure if we need to be secure (e.g. setuid),
+ for setting __libc_enable_secure if we need to be secure (e.g. setuid),
and for setting _dl_argc and _dl_argv, and then calling _dl_main. */
extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr,
ElfW(Addr) *user_entry));
extern void _dl_sysdep_start_cleanup (void);
-int _dl_secure;
int _dl_argc;
char **_dl_argv;
const char *_dl_rpath;
+/* Set nonzero during loading and initialization of executable and
+ libraries, cleared before the executable's entry point runs. This
+ must not be initialized to nonzero, because the unused dynamic
+ linker loaded in for libc.so's "ld.so.1" dep will provide the
+ definition seen by libc.so's initializer; that value must be zero,
+ and will be since that dynamic linker's _dl_start and dl_main will
+ never be called. */
+int _dl_starting_up;
+
static void dl_main (const ElfW(Phdr) *phdr,
ElfW(Half) phent,
ElfW(Addr) *user_entry);
/* This #define produces dynamic linking inline functions for
bootstrap relocation instead of general-purpose relocation. */
#define RTLD_BOOTSTRAP
-#define RESOLVE(sym, reloc_addr, noplt) bootstrap_map.l_addr
+#define RESOLVE(sym, flags) bootstrap_map.l_addr
#include "dynamic-link.h"
/* Figure out the run-time load address of the dynamic linker itself. */
const ElfW(Phdr) *ph;
struct link_map *l;
int lazy;
- enum { normal, list, verify } mode = normal;
+ enum { normal, list, verify, trace } mode;
struct link_map **preloads;
unsigned int npreloads;
+ mode = getenv ("LD_TRACE_LOADED_OBJECTS") != NULL ? trace : normal;
+
if (*user_entry == (ElfW(Addr)) &_start)
{
/* Ho ho. We are not the program interpreter! We are the program
--_dl_argc;
++_dl_argv;
- l = _dl_map_object (NULL, _dl_argv[0], lt_library);
+ if (mode == verify)
+ {
+ void doit (void)
+ {
+ l = _dl_map_object (NULL, _dl_argv[0], lt_library);
+ }
+ char *err_str = NULL;
+ const char *obj_name __attribute__ ((unused));
+
+ (void) _dl_catch_error (&err_str, &obj_name, doit);
+ if (err_str != NULL)
+ {
+ free (err_str);
+ _exit (EXIT_FAILURE);
+ }
+ }
+ else
+ l = _dl_map_object (NULL, _dl_argv[0], lt_library);
+
phdr = l->l_phdr;
phent = l->l_phnum;
l->l_name = (char *) "";
{
/* Create a link_map for the executable itself.
This will be what dlopen on "" returns. */
- l = _dl_new_object ((char *) "", "", lt_library);
+ l = _dl_new_object ((char *) "", "", lt_executable);
l->l_phdr = phdr;
l->l_phnum = phent;
l->l_entry = *user_entry;
if (mode == verify)
/* We were called just to verify that this is a dynamic executable
using us as the program interpreter. */
- _exit (strcmp (_dl_rtld_map.l_libname, _dl_rtld_map.l_name)
+ _exit ((strcmp (_dl_rtld_map.l_libname, _dl_rtld_map.l_name) ||
+ l->l_ld == NULL)
? EXIT_FAILURE : EXIT_SUCCESS);
/* Extract the contents of the dynamic section for easy access. */
preloads = NULL;
npreloads = 0;
- if (! _dl_secure)
+ if (! __libc_enable_secure)
{
const char *preloadlist = getenv ("LD_PRELOAD");
if (preloadlist)
}
}
- if (mode == normal && getenv ("LD_TRACE_LOADED_OBJECTS") != NULL)
- mode = list;
-
if (mode != normal)
{
/* We were run just to list the shared libraries. It is
" (0x", bp, ")\n", NULL);
}
- for (i = 1; i < _dl_argc; ++i)
- {
- const ElfW(Sym) *ref = NULL;
- ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
- &_dl_default_scope[2],
- "argument", 0, 0);
- char buf[20], *bp;
- buf[sizeof buf - 1] = '\0';
- bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
- while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
- *--bp = '0';
- _dl_sysdep_message (_dl_argv[i], " found at 0x", bp, NULL);
- buf[sizeof buf - 1] = '\0';
- bp = _itoa (loadbase, &buf[sizeof buf - 1], 16, 0);
- while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
- *--bp = '0';
- _dl_sysdep_message (" in object at 0x", bp, "\n", NULL);
- }
+ if (mode != trace)
+ for (i = 1; i < _dl_argc; ++i)
+ {
+ const ElfW(Sym) *ref = NULL;
+ ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
+ &_dl_default_scope[2],
+ "argument",
+ DL_LOOKUP_NOPLT);
+ char buf[20], *bp;
+ buf[sizeof buf - 1] = '\0';
+ bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
+ while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
+ *--bp = '0';
+ _dl_sysdep_message (_dl_argv[i], " found at 0x", bp, NULL);
+ buf[sizeof buf - 1] = '\0';
+ bp = _itoa (loadbase, &buf[sizeof buf - 1], 16, 0);
+ while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
+ *--bp = '0';
+ _dl_sysdep_message (" in object at 0x", bp, "\n", NULL);
+ }
_exit (0);
}
- lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
+ lazy = !__libc_enable_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
{
/* Now we have all the objects loaded. Relocate them all except for
dynamic linker. There is no additional initialization
required for the ABI-compliant dynamic linker. */
- (*(void (*) (void)) (_dl_rtld_map.l_addr +
- _dl_rtld_map.l_info[DT_INIT]->d_un.d_ptr)) ();
+ (*(void (*) (int, char **, char**))
+ (_dl_rtld_map.l_addr + _dl_rtld_map.l_info[DT_INIT]->d_un.d_ptr))
+ (0, NULL, NULL);
/* Clear the field so a future dlopen won't run it again. */
_dl_rtld_map.l_info[DT_INIT] = NULL;
}
+ /* We finished the intialization and will start up. */
+ _dl_starting_up = 1;
+
/* Once we return, _dl_sysdep_start will invoke
the DT_INIT functions and then *USER_ENTRY. */
}