From 86d2c878acad4d2f16d0af6fe6a030b90815362d Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 7 Nov 1995 21:46:52 +0000 Subject: [PATCH] Tue Nov 7 12:29:46 1995 Roland McGrath * 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. --- ChangeLog | 96 ++++++++++++++++++++++++++++++--------------- elf/Makefile | 28 ++++++++++--- elf/dlsym.c | 2 +- elf/linux-compat.c | 40 +++++++++++++++++++ elf/rtld.c | 76 +++++++++++++++++++++++++---------- intl/localealias.c | 6 ++- sysdeps/generic/_strerror.c | 14 ++++--- sysdeps/mach/_strerror.c | 6 +-- 8 files changed, 199 insertions(+), 69 deletions(-) create mode 100644 elf/linux-compat.c diff --git a/ChangeLog b/ChangeLog index 288513f..79a40ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +Tue Nov 7 12:29:46 1995 Roland McGrath + + * 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'. + Mon Nov 6 16:20:14 1995 Roland McGrath * elf/dlsym.c: Return the proper value, not just the defining @@ -75,7 +107,7 @@ Thu Oct 26 23:11:11 1995 Ulrich Drepper * sysdeps/unix/sysv/linux/i386/sigaction.c: Correct parameter name usage (new->act, old->oact). Correct asm statement because of gcc strangeness. - + * sysdeps/i386/i586/strchr.S: Correct typos: cmp -> cmpb. * sunrpc/clnt_perr.c: Remove declaration of sys_errlist. They @@ -128,7 +160,7 @@ Thu Oct 26 03:01:22 1995 Ulrich Drepper * sysdeps/unix/sysv/linux/i386/xstat.S: Likewise. * sysdeps/unix/sysv/linux/i386/syscall.S: Likewise. Don't use DO_CALL macro; instead use lower level macros for better - control. + control. * sysdeps/unix/sysv/linux/sigaction.h: New file. * sysdeps/unix/sysv/linux/sigaction.S: File removed. @@ -190,7 +222,7 @@ Wed Oct 18 03:33:22 1995 Roland McGrath (PSEUDO): Use it before jumping to syscall_error. * sysdeps/unix/i386/sysdep.S [! PIC]: Don't find GOT address; expect it in %ebx on entry. Pop old %ebx value off stack after - using it. + using it. * signal/signal.h [__USE_BSD] (_sys_siglist, sys_siglist): Declare them. @@ -219,7 +251,7 @@ Tue Oct 17 01:21:21 1995 Roland McGrath * hurd/hurdsock.c: Include stdio-common/_itoa.h instead of stdio/_itoa.h. * hurd/hurdlookup.c: Likewise. - + * hurd/hurd/signal.h: Declare hurd_preempt_signals and hurd_unpreempt_signals. @@ -346,10 +378,10 @@ Sun Oct 15 21:04:13 1995 Roland McGrath (__hurd_file_name_lookup, __hurd_file_name_lookup_retry, __hurd_file_name_split): Rewritten to take callback functions for using any needed init or dtable port, instead of passing in crdir - and cwdir ports. + and cwdir ports. (__file_name_lookup, __file_name_split): Use new calling convention; pass _hurd_ports_use and __getdport as the callback - functions. + functions. * sysdeps/mach/hurd/chroot.c: Use __file_name_lookup_under instead of __hurd_file_name_lookup. @@ -438,7 +470,7 @@ Tue Oct 10 23:08:53 1995 Roland McGrath * MakeTAGS (all-dirs): Omit CVS directories. Specify vpath directives to find source files in $(all-dirs). (sources, headers): Append sources and headers from $(all-dist) to - these. + these. (all-dist): Filter them out of this. (all-headers, all-sources): Use $(shell find ...) instead of $(wildcard ...). @@ -459,7 +491,7 @@ Mon Oct 9 02:54:14 1995 Roland McGrath (rtld-installed-name): New variable. * elf/Makefile (install-lib): Variable removed. (install-others): Define this instead, to - $(libdir)(rtld-installed-name). + $(libdir)(rtld-installed-name). ($(libdir)(rtld-installed-name)): New target; install from ld.so. * elf/ldd.sh.in: New file. @@ -506,7 +538,7 @@ Fri Sep 29 03:43:51 1995 Paul Eggert * time/mktime.c (__mon_yday): New variable; replaces `__mon_lengths'. time/offtime.c (__offtime), time/tzset.c (compute_change): Use it. - + * time/offtime.c (__offtime): Remove useless assignment `tp->tm_isdst = -1'. @@ -602,8 +634,8 @@ Thu Sep 28 13:05:54 1995 Roland McGrath Thu Sep 28 09:20:04 1995 Ulrich Drepper * stdlib/strtod.c (STRTOF): Fix handling of numbers with lots of - leading zeroes. - + leading zeroes. + Wed Sep 27 00:27:25 1995 Roland McGrath * sysdeps/mach/hurd/getcwd.c (__getcwd): Renamed from getcwd. @@ -625,7 +657,7 @@ Wed Sep 27 00:27:25 1995 Roland McGrath * sysdeps/unix/i386/sysdep.h [HAVE_ELF] (ASM_TYPE_DIRECTIVE): Don't use `type' for arg name, since we are using it as a keyword - in the rhs. + in the rhs. * sysdeps/unix/configure.in: Check for syscalls getpriority, setpriority, getrlimit, setrlimit. @@ -773,7 +805,7 @@ Thu Sep 21 00:03:53 1995 Roland McGrath * Makerules (build-shlib): Use $(@F:lib%.so=%) in place of $(notdir $*), so it wins for the explicit libc.so rule as well as the - pattern rule. + pattern rule. * sysdeps/stub/sys/sem_buf.h (union semun): New type. @@ -967,7 +999,7 @@ Sat Sep 16 17:47:19 1995 Ulrich Drepper * sysdeps/mach/_strerror.c: Change for new interface with three arguments. * stdio/perror.c, stdio/vfprintf.c: Callers changed. - + * sysdeps/mach/hurd/ttyname_r.c: New file. Reentrant version. * sysdeps/posix/ttyname_r.c: New file. Reentrant version. * sysdeps/stub/ttyname_r: New file. Define as dummy function. @@ -1100,7 +1132,7 @@ Fri Sep 8 16:32:12 1995 Ulrich Drepper sysdeps/unix/sysv/linux/sys/timex.h: New Linux/ELF specific, architecture independent header files. * sysdeps/unix/sysv/sysv4/linux: Tree removed. - + Thu Sep 7 17:05:13 1995 Roland McGrath * stdlib/msort.c (msort_with_tmp): Fixed alignment test. B1 and @@ -1237,7 +1269,7 @@ Mon Aug 21 16:37:09 1995 Roland McGrath * sysdeps/i386/dl-machine.h (elf_machine_rel): Grok R_386_NONE relocs, and do nothing. Why the linker generates them we may - never know. + never know. Thu Aug 17 16:18:38 1995 Roland McGrath @@ -1261,7 +1293,7 @@ Thu Aug 17 16:18:38 1995 Roland McGrath * sysdeps/mach/hurd/fork.c (_hurd_fork_locks): Variable removed. Instead, declare with `symbol_set_declare'. - (fork): Use symbol_set_* macros for _hurd_fork_locks. + (fork): Use symbol_set_* macros for _hurd_fork_locks. Use SS->thread instead of __mach_thread_self (). Suspend all other threads during task_create and port copying. @@ -1520,12 +1552,12 @@ Sat Jul 22 01:56:03 1995 Roland McGrath ASM_TYPE_DIRECTIVE. (ASM_TYPE_DIRECTIVE): New macro; defined using `.type' #ifdef ELF. - * sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S (__syscall_error): + * sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S (__syscall_error): Rewritten, #include'ing unix/i386/sysdep.S for most of the code. * sysdeps/unix/i386/sysdep.S [PIC]: Store into `errno' through the GOT. * configure.in (os=linux*): Use unix/sysv/sysv4 for $base_os, - instead of unix/sysv. + instead of unix/sysv. * sysdeps/unix/sysv/linux/{accept,connect,getsockname,rename, socketpair,waitpid,bind,getpeername,listen,setsid,wait4}.S: Moved to new directory sysdeps/unix/sysv/sysv4/linux. @@ -1863,9 +1895,9 @@ Tue May 9 01:26:52 1995 Roland McGrath variable to FORCE in this case, to force a rebuild of sysd-rules. (sysd-rules): Depend on $(sysd-rules-force). Write into the file sysd-rules-sysdirs:=$(sysdirs). - + * Makerules (LDFLAGS-c.so): Change ld option -interp to - -dynamic-linker. + -dynamic-linker. * Makerules (do-install-program): New canned sequence. (install-bin, install-sbin): Use it. @@ -1950,7 +1982,7 @@ Tue May 2 01:52:58 1995 Roland McGrath * sysdeps/mach/hurd/i386/init-first.c: New file. * sysdeps/i386/init-first.c: New file. * sysdeps/stub/init-first.c: New file. - + Mon May 1 18:48:30 1995 Roland McGrath * Makerules (LDFLAGS-c.so): Add -interp and -e switches to make @@ -2550,7 +2582,7 @@ Mon Mar 13 01:48:16 1995 Roland McGrath * stdio/printf_fp.c (NDEBUG): Define this to disable assert. Don't include . - (__printf_fp): Last arg ARGS is now `const void **const'; + (__printf_fp): Last arg ARGS is now `const void **const'; dereference ARGS[0] instead of using va_arg. * locale/setlocale.c: In LC_ALL case, initialize CATEGORY before @@ -2729,7 +2761,7 @@ Wed Mar 8 13:38:13 1995 Roland McGrath time/ialloc.c: Code and data updated from ADO's 95b. * time/emkdir.c: File removed. * time/Makefile (distribute, extra-objs, zic): Omit it. - + * time/localtime.c: Deansideclized. Never #define __tzname et al to non-__ names. @@ -2769,7 +2801,7 @@ Sun Mar 5 19:40:13 1995 Roland McGrath * ctype/ctype.h (_IS*): Use independent bits for all but _ISalnum. * ctype/ctype-info.c: For initial tables, use _nl_C_LC_CTYPE_{class,toupper,tolower} constant tables defined in - locale/C-ctype.c. + locale/C-ctype.c. * locale/C-ctype.c, locale/C-messages.c: New files. * locale/C-monetary.c, locale/C-numeric.c, locale/C-time.c: Default "C" locale data updated for new locale system. @@ -3280,7 +3312,7 @@ Mon Feb 6 18:34:40 1995 Roland McGrath Don't expect _hurd_self_sigstate to lock it. Fix critical section locking. * hurd/hurd-raise.c: Likewise. - * sysdeps/mach/hurd/sigsuspend.c: Likewise. + * sysdeps/mach/hurd/sigsuspend.c: Likewise. * sysdeps/mach/hurd/sigpending.c: Likewise. * sysdeps/mach/hurd/sigaltstack.c: Likewise. * sysdeps/mach/hurd/sigaction.c: Likewise. @@ -3290,7 +3322,7 @@ Mon Feb 6 18:34:40 1995 Roland McGrath * sysdeps/mach/hurd/ioctl.c: Likewise. * sysdeps/mach/hurd/fork.c: Likewise. * sysdeps/mach/hurd/i386/sigreturn.c: Likewise. - * sysdeps/mach/hurd/mips/sigreturn.c: Likewise. + * sysdeps/mach/hurd/mips/sigreturn.c: Likewise. * sysdeps/mach/hurd/alpha/sigreturn.c: Likewise. * hurd/hurdmsg.c (get_int): Likewise. @@ -3874,7 +3906,7 @@ Sat Jan 21 08:08:58 1995 Roland McGrath * sysdeps/unix/common/__getgrps.S: Likewise. * sysdeps/mach/hurd/__getgrps.c: Likewise. * sysdeps/stub/__gethstnm.c: Renamed to gethostname.c; added weak - alias gethostname. + alias gethostname. * sysdeps/unix/inet/__gethstnm.S: Likewise. * sysdeps/unix/sysv/__gethstnm.c: Likewise. * sysdeps/unix/sysv/sysv4/__gethstnm.c: Likewise. @@ -4008,11 +4040,11 @@ Sat Jan 21 08:08:58 1995 Roland McGrath * sysdeps/unix/bsd/__setgid.c: Likewise. * sysdeps/mach/hurd/__setgid.c: Likewise. * sysdeps/stub/__setitmr.c: Renamed to setitmr.c; added weak alias - setitmr + setitmr * sysdeps/unix/common/__setitmr.S: Likewise. * sysdeps/mach/hurd/__setitmr.c: Likewise. * sysdeps/stub/__setpgrp.c: Renamed to setpgrp.c; added weak alias - setpgrp + setpgrp * sysdeps/unix/sysv/sysv4/__setpgrp.c: Likewise. * sysdeps/unix/sysv/sco3.2.4/__setpgrp.c: Likewise. * sysdeps/unix/sysv/irix4/__setpgrp.S: Likewise. @@ -4352,7 +4384,7 @@ Tue Jan 17 03:16:47 1995 Roland McGrath if any are successful. * hurd/hurdmsg.c: Prepend `msg_' to all RPC names. - (_S_msg_get_exec_flags, _S_msg_set_exec_flags, + (_S_msg_get_exec_flags, _S_msg_set_exec_flags, _S_msg_set_some_exec_flags, _S_msg_clear_some_exec_flags): New functions. (_S_io_select_done, _S_dir_changed, _S_file_changed): Stubs removed. @@ -4374,7 +4406,7 @@ Tue Jan 17 03:16:47 1995 Roland McGrath * hurd/hurdsig.c (post_reply): Take new arg UNTRACED; if nonzero, use sig_post_untraced_reply. All callers changed. - (abort_thread, abort_rpcs): Take same new arg and pass it through. + (abort_thread, abort_rpcs): Take same new arg and pass it through. All callers changed. (_hurd_internal_post_signal): Take new arg UNTRACED. If zero and process is traced, stop with SIGNO as stop signal. If diff --git a/elf/Makefile b/elf/Makefile index 21d2fc5..314289b 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -31,24 +31,42 @@ libdl-inhibit-o = $(filter-out .so,$(object-suffixes)) # Build only shared. rtld-routines := rtld $(addprefix dl-,load lookup object reloc \ runtime sysdep error init fini) distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h \ - soinit.c sofini.c ldd.sh.in + soinit.c sofini.c ldd.sh.in linux-compat.c include ../Makeconfig ifeq (yes,$(build-shared)) extra-objs = $(rtld-routines:=.so) soinit.so sofini.so +generated = librtld.so install-others = $(libdir)/$(rtld-installed-name) install-bin = ldd + +ifneq (,$(filter linux%,$(config-os))) +extra-objs += linux-compat.so +install-lib += ld-linux.so.1 +endif endif include ../Rules -$(objpfx)ld.so: $(rtld-routines:%=$(objpfx)%.so) \ - $(patsubst %,$(common-objpfx)lib%_pic.a,\ - elf c $(LDLIBS-c.so:-l%=%)) - $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \ + +# Link together the dynamic linker into a single relocatable object. +# We use this to produce both the ABI-compliant and Linux-compatible +# dynamic linker shared objects below. +$(objpfx)librtld.so: $(rtld-routines:%=$(objpfx)%.so) \ + $(patsubst %,$(common-objpfx)lib%_pic.a,\ + elf c $(LDLIBS-c.so:-l%=%)) + $(LINK.o) -nostdlib -nostartfiles -r -o $@ \ '-Wl,-(' $^ -lgcc '-Wl,-)' +$(objpfx)ld.so $(objpfx)ld-linux.so.1: $(objpfx)librtld.so + $(LINK.o) -nostdlib -nostartfiles -shared -o $@ $^ + +# The Linux-compatible dynamic linker shared object is just the same +# with one object file of compatibility initialization code added. +$(objpfx)ld-linux.so.1: $(objpfx)linux-compat.so + + $(objpfx)libdl.so: $(objpfx)libdl_pic.a $(common-objpfx)libc.so $(objpfx)ld.so $(patsubst %/,cd %;,$(objpfx)) \ $(LINK.o) -shared -o $(@:$(objpfx)%=%) \ diff --git a/elf/dlsym.c b/elf/dlsym.c index 8277ca3..0441e54 100644 --- a/elf/dlsym.c +++ b/elf/dlsym.c @@ -29,10 +29,10 @@ dlsym (void *handle, const char *name) struct link_map *map = handle; struct link_map *real_next; Elf32_Addr loadbase; + const Elf32_Sym *ref = NULL; int lose; void doit (void) { - const Elf32_Sym *ref = NULL; loadbase = _dl_lookup_symbol (name, &ref, map, map->l_name, 1); } diff --git a/elf/linux-compat.c b/elf/linux-compat.c new file mode 100644 index 0000000..ed1595e --- /dev/null +++ b/elf/linux-compat.c @@ -0,0 +1,40 @@ +/* Initializer for Linux-compatible dynamic linker `/lib/ld-linux.so.1'. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include + +/* This function will be the DT_INIT initializer for the ld-linux.so.1 + shared object. This is called from rtld.c before shlib initializers. + + The old Linux ELF startup code expects the dynamic linker to magically + call atexit to arrange for shared object finalizers to run. (The + ABI-compliant startup code does this itself.) We build a compatible + version of the dynamic linker to install as /lib/ld-linux.so.1, the + name old Linux ELF binaries use. */ + +void +_init (void) +{ + const Elf32_Sym *ref = NULL; + Elf32_Addr loadbase = _dl_lookup_symbol ("atexit", &ref, _dl_loaded, + "", + 1); + (*(__typeof (atexit) *) (loadbase + ref->st_value)) (&_dl_fini); +} diff --git a/elf/rtld.c b/elf/rtld.c index 19f5439..9a822a8 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. diff --git a/intl/localealias.c b/intl/localealias.c index 716657c..fc3bc12 100644 --- a/intl/localealias.c +++ b/intl/localealias.c @@ -150,9 +150,11 @@ read_alias_file (fname, fname_len) FILE *fp; char *full_fname; size_t added; + static const char aliasfile[] = "/locale.alias"; - full_fname = (char *) alloca (fname_len + sizeof ("/locale.alias")); - sprintf (full_fname, "%.*s/locale.alias", fname_len, fname); + full_fname = (char *) alloca (fname_len + sizeof aliasfile); + memcpy (full_fname, fname, fname_len); + memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); fp = fopen (full_fname, "r"); if (fp == NULL) diff --git a/sysdeps/generic/_strerror.c b/sysdeps/generic/_strerror.c index 72ebb21..569f701 100644 --- a/sysdeps/generic/_strerror.c +++ b/sysdeps/generic/_strerror.c @@ -18,6 +18,7 @@ Cambridge, MA 02139, USA. */ #include #include +#include "../stdio-common/_itoa.h" #ifndef HAVE_GNU_LD #define _sys_errlist sys_errlist @@ -31,13 +32,14 @@ _strerror_internal (errnum, buf, buflen) char *buf; size_t buflen; { - if (errnum < 0 || errnum > _sys_nerr) + if (errnum < 0 || errnum >= _sys_nerr) { - int len = __snprintf (buf, buflen, _("Unknown error %d"), errnum); - if (len < 0) - return NULL; - buf[len - 1] = '\0'; - return buf; + const char *unk = _("Unknown error "); + const size_t unklen = strlen (unk); + char *p = buf + buflen; + *--p = '\0'; + p = _itoa (errnum, p, 10, 0); + return memcpy (p - unklen, unk, unklen); } return (char *) _(_sys_errlist[errnum]); diff --git a/sysdeps/mach/_strerror.c b/sysdeps/mach/_strerror.c index 82d83a0..8b32f05 100644 --- a/sysdeps/mach/_strerror.c +++ b/sysdeps/mach/_strerror.c @@ -26,7 +26,7 @@ Cambridge, MA 02139, USA. */ char * _strerror_internal (int errnum, char *buf, size_t buflen) { - int system; + int system; int sub; int code; const struct error_system *es; @@ -43,7 +43,7 @@ _strerror_internal (int errnum, char *buf, size_t buflen) const char *unk = _("Error in unknown error system: "); const size_t unklen = strlen (unk); char *p = buf + buflen; - *p-- = '\0'; + *--p = '\0'; p = _itoa (errnum, p, 16, 1); return memcpy (p - unklen, unk, unklen); } @@ -59,7 +59,7 @@ _strerror_internal (int errnum, char *buf, size_t buflen) const size_t unklen = strlen (unk); char *p = buf + buflen; size_t len = strlen (es->subsystem[sub].subsys_name); - *p-- = '\0'; + *--p = '\0'; p = _itoa (errnum, p, 16, 1); *p-- = ' '; p = memcpy (p - len, es->subsystem[sub].subsys_name, len); -- 2.7.4