Tue Nov 7 12:29:46 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
authorRoland McGrath <roland@gnu.org>
Tue, 7 Nov 1995 21:46:52 +0000 (21:46 +0000)
committerRoland McGrath <roland@gnu.org>
Tue, 7 Nov 1995 21:46:52 +0000 (21:46 +0000)
* 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
elf/Makefile
elf/dlsym.c
elf/linux-compat.c [new file with mode: 0644]
elf/rtld.c
intl/localealias.c
sysdeps/generic/_strerror.c
sysdeps/mach/_strerror.c

index 288513f..79a40ee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+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'.
+
 Mon Nov  6 16:20:14 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * elf/dlsym.c: Return the proper value, not just the defining
@@ -75,7 +107,7 @@ Thu Oct 26 23:11:11 1995  Ulrich Drepper  <drepper@ipd.info.uni-karlsruhe.de>
        * 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  <drepper@ipd.info.uni-karlsruhe.de>
        * 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  <roland@churchy.gnu.ai.mit.edu>
        (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  <roland@churchy.gnu.ai.mit.edu>
        * 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  <roland@churchy.gnu.ai.mit.edu>
        (__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  <roland@churchy.gnu.ai.mit.edu>
        * 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  <roland@churchy.gnu.ai.mit.edu>
        (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  <eggert@twinsun.com>
 
        * 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  <roland@churchy.gnu.ai.mit.edu>
 Thu Sep 28 09:20:04 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>
 
        * stdlib/strtod.c (STRTOF): Fix handling of numbers with lots of
-       leading zeroes. 
-       
+       leading zeroes.
+
 Wed Sep 27 00:27:25 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * sysdeps/mach/hurd/getcwd.c (__getcwd): Renamed from getcwd.
@@ -625,7 +657,7 @@ Wed Sep 27 00:27:25 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * 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  <roland@churchy.gnu.ai.mit.edu>
 
        * 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  <drepper@ipd.info.uni-karlsruhe.de>
        * 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  <drepper@gnu.ai.mit.edu>
        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  <roland@churchy.gnu.ai.mit.edu>
 
        * stdlib/msort.c (msort_with_tmp): Fixed alignment test.  B1 and
@@ -1237,7 +1269,7 @@ Mon Aug 21 16:37:09 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * 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  <roland@churchy.gnu.ai.mit.edu>
 
@@ -1261,7 +1293,7 @@ Thu Aug 17 16:18:38 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * 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  <roland@churchy.gnu.ai.mit.edu>
        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  <roland@churchy.gnu.ai.mit.edu>
        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  <roland@churchy.gnu.ai.mit.edu>
        * 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  <roland@churchy.gnu.ai.mit.edu>
 
        * Makerules (LDFLAGS-c.so): Add -interp and -e switches to make
@@ -2550,7 +2582,7 @@ Mon Mar 13 01:48:16 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * stdio/printf_fp.c (NDEBUG): Define this to disable assert.
        Don't include <stdarg.h>.
-       (__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  <roland@churchy.gnu.ai.mit.edu>
        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  <roland@churchy.gnu.ai.mit.edu>
        * 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  <roland@churchy.gnu.ai.mit.edu>
        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  <roland@churchy.gnu.ai.mit.edu>
        * 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  <roland@churchy.gnu.ai.mit.edu>
        * 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  <roland@churchy.gnu.ai.mit.edu>
        * 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  <roland@churchy.gnu.ai.mit.edu>
         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  <roland@churchy.gnu.ai.mit.edu>
 
        * 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
index 21d2fc5..314289b 100644 (file)
@@ -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)%=%) \
index 8277ca3..0441e54 100644 (file)
@@ -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 (file)
index 0000000..ed1595e
--- /dev/null
@@ -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 <link.h>
+#include <stdlib.h>
+
+/* 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,
+                                          "<ld-linux.so.1 initialization>",
+                                          1);
+  (*(__typeof (atexit) *) (loadbase + ref->st_value)) (&_dl_fini);
+}
index 19f5439..9a822a8 100644 (file)
@@ -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)
 {
 }
 \f
+/* 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.
index 716657c..fc3bc12 100644 (file)
@@ -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)
index 72ebb21..569f701 100644 (file)
@@ -18,6 +18,7 @@ Cambridge, MA 02139, USA.  */
 
 #include <stdio.h>
 #include <string.h>
+#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]);
index 82d83a0..8b32f05 100644 (file)
@@ -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);