diff options
author | Roland McGrath <roland@gnu.org> | 1995-11-07 21:46:52 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1995-11-07 21:46:52 +0000 |
commit | 86d2c878acad4d2f16d0af6fe6a030b90815362d (patch) | |
tree | 69e150aefd1002c3411b34da02bf852525c01ff7 /elf/rtld.c | |
parent | 51093422b2ea7d61c17e4ac55af61ba9558d18d4 (diff) | |
download | glibc-86d2c878acad4d2f16d0af6fe6a030b90815362d.tar glibc-86d2c878acad4d2f16d0af6fe6a030b90815362d.tar.gz glibc-86d2c878acad4d2f16d0af6fe6a030b90815362d.tar.bz2 glibc-86d2c878acad4d2f16d0af6fe6a030b90815362d.zip |
Tue Nov 7 12:29:46 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* elf/linux-compat.c: New file.
* elf/Makefile (distribute): Add linux-compat.c.
(generated): Add librtld.so.
[$(config-os)=linux*] (extra-objs): Add linux-compat.so.
[$(config-os)=linux*] (extra-objs): Add ld-linux.so.1.
(librtld.so): New target.
(ld.so, ld-linux.so.1): Make from librtld.so.
* elf/rtld.c (dl_main): Instead of weak call to _dl_compat_init,
call our own DT_INIT if we have one (and then clear it).
(__dgettext): New weak function.
* intl/localealias.c (read_alias_file): Avoid sprintf; use memcpy
by hand instead.
* sysdeps/generic/_strerror.c (_strerror_internal): Use _itoa
instead of snprintf.
* sysdeps/mach/_strerror.c (_strerror_internal): Don't write
BUF[BUFLEN].
* elf/rtld.c (rtld_map): New static variable.
(_dl_start): Use a differently named local BOOTSTRAP_MAP for the
bootstrapping. Then copy data into `rtld_map'.
(dl_main): Finish filling in rtld_map and link it into the chain,
instead of allocating a new structure.
(dl_main): Call _dl_compat_init if it is defined (use weak ref).
* elf/dlsym.c: Fix last change: move REF out of `doit'.
control.
using it.
and cwdir ports.
functions.
these.
$(libdir)(rtld-installed-name).
leading zeroes.
in the rhs.
pattern rule.
never know.
(fork): Use symbol_set_* macros for _hurd_fork_locks.
* sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S (__syscall_error):
instead of unix/sysv.
-dynamic-linker.
(__printf_fp): Last arg ARGS is now `const void **const';
locale/C-ctype.c.
* sysdeps/mach/hurd/sigsuspend.c: Likewise.
* sysdeps/mach/hurd/mips/sigreturn.c: Likewise.
alias gethostname.
setitmr
setpgrp
(_S_msg_get_exec_flags, _S_msg_set_exec_flags,
(abort_thread, abort_rpcs): Take same new arg and pass it through.
Diffstat (limited to 'elf/rtld.c')
-rw-r--r-- | elf/rtld.c | 76 |
1 files changed, 56 insertions, 20 deletions
diff --git a/elf/rtld.c b/elf/rtld.c index 19f5439ed0..9a822a8c66 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -50,22 +50,24 @@ static void dl_main (const Elf32_Phdr *phdr, Elf32_Word phent, Elf32_Addr *user_entry); +static struct link_map rtld_map; + Elf32_Addr _dl_start (void *arg) { - struct link_map rtld_map; + struct link_map bootstrap_map; /* Figure out the run-time load address of the dynamic linker itself. */ - rtld_map.l_addr = elf_machine_load_address (); + bootstrap_map.l_addr = elf_machine_load_address (); /* Read our own dynamic section and fill in the info array. Conveniently, the first element of the GOT contains the offset of _DYNAMIC relative to the run-time load address. */ - rtld_map.l_ld = (void *) rtld_map.l_addr + *elf_machine_got (); - elf_get_dynamic_info (rtld_map.l_ld, rtld_map.l_info); + bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + *elf_machine_got (); + elf_get_dynamic_info (bootstrap_map.l_ld, bootstrap_map.l_info); #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC - ELF_MACHINE_BEFORE_RTLD_RELOC (rtld_map.l_info); + ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info); #endif /* Relocate ourselves so we can do normal function calls and @@ -77,8 +79,8 @@ _dl_start (void *arg) bootstrapping, so it must anti-perform each bootstrapping relocation before applying the final relocation when ld.so is linked in as normal a shared library. */ - rtld_map.l_type = lt_library; - ELF_DYNAMIC_RELOCATE (&rtld_map, 0, NULL); + bootstrap_map.l_type = lt_library; + ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, NULL); /* Now life is sane; we can call functions and access global data. @@ -86,7 +88,12 @@ _dl_start (void *arg) the operating system's program loader where to find the program header table in core. */ - dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address. */ + + /* Transfer data about ourselves to the permanent link_map structure. */ + rtld_map.l_addr = bootstrap_map.l_addr; + rtld_map.l_ld = bootstrap_map.l_ld; + memcpy (rtld_map.l_info, bootstrap_map.l_info, sizeof rtld_map.l_info); + /* Call the OS-dependent function to set up life so we can do things like file access. It will call `dl_main' (below) to do all the real work @@ -122,9 +129,9 @@ dl_main (const Elf32_Phdr *phdr, itself! This means someone ran ld.so as a command. Well, that might be convenient to do sometimes. We support it by interpreting the args like this: - + ld.so PROGRAM ARGS... - + The first argument is the name of a file containing an ELF executable we will load and run with the following arguments. To simplify life here, PROGRAM is searched for using the @@ -228,8 +235,14 @@ of this helper program; chances are you did not intend to run this program.\n", will set up later to communicate with the debugger. */ l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug; - l = _dl_new_object ((char *) interpreter_name, interpreter_name, - lt_interpreter); + /* Put the link_map for ourselves on the chain so it can be found by + name. */ + rtld_map.l_name = (char *) rtld_map.l_libname = interpreter_name; + rtld_map.l_type = lt_interpreter; + while (l->l_next) + l = l->l_next; + l->l_next = &rtld_map; + rtld_map.l_prev = l; /* Now process all the DT_NEEDED entries and map in the objects. Each new link_map will go on the end of the chain, so we will @@ -248,16 +261,13 @@ of this helper program; chances are you did not intend to run this program.\n", l->l_deps_loaded = 1; } - l = _dl_loaded->l_next; - while (l->l_type != lt_interpreter) - l = l->l_next; - if (l->l_opencount == 0) + if (rtld_map.l_opencount == 0) { /* No DT_NEEDED entry referred to the interpreter object itself. Remove it from the maps we will use for symbol resolution. */ - l->l_prev->l_next = l->l_next; - if (l->l_next) - l->l_next->l_prev = l->l_prev; + rtld_map.l_prev->l_next = rtld_map.l_next; + if (rtld_map.l_next) + rtld_map.l_next->l_prev = rtld_map.l_prev; } lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0'; @@ -276,6 +286,7 @@ of this helper program; chances are you did not intend to run this program.\n", /* Tell the debugger where to find the map of loaded objects. */ dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */; + dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address. */ dl_r_debug.r_map = _dl_loaded; dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state; @@ -301,6 +312,19 @@ of this helper program; chances are you did not intend to run this program.\n", _exit (0); } + + if (rtld_map.l_info[DT_INIT]) + { + /* Call the initializer for the compatibility version of the + dynamic linker. There is no additional initialization + required for the ABI-compliant dynamic linker. */ + + (*(void (*) (void)) (rtld_map.l_addr + + rtld_map.l_info[DT_INIT]->d_un.d_ptr)) (); + + /* Clear the field so a future dlopen won't run it again. */ + rtld_map.l_info[DT_INIT] = NULL; + } } const char *errstring; const char *errobj; @@ -318,13 +342,25 @@ of this helper program; chances are you did not intend to run this program.\n", the DT_INIT functions and then *USER_ENTRY. */ } -/* This function exists solely to have a breakpoint set on it by the +/* This function exists solely to have a breakpoint set on it by the debugger. */ void _dl_r_debug_state (void) { } +/* Define our own stub for the localization function used by strerror. + English-only in the dynamic linker keeps it smaller. */ + +char * +__dgettext (const char *domainname, const char *msgid) +{ + assert (domainname == _libc_intl_domainname); + return (char *) msgid; +} +weak_symbol (__dgettext) +weak_alias (__dgettext, dgettext) + #ifndef NDEBUG /* Define (weakly) our own assert failure function which doesn't use stdio. |