about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-09-27 00:21:42 +0000
committerUlrich Drepper <drepper@redhat.com>1997-09-27 00:21:42 +0000
commita2b08ee54130cf3a74655856e6ca6c29874a9df2 (patch)
tree71e7d867304f432bc57043e0c54a5cf101835651
parent650425ceb40e840b2123b6c8cc65389589f41218 (diff)
downloadglibc-a2b08ee54130cf3a74655856e6ca6c29874a9df2.tar.gz
glibc-a2b08ee54130cf3a74655856e6ca6c29874a9df2.tar.xz
glibc-a2b08ee54130cf3a74655856e6ca6c29874a9df2.zip
1997-09-27 01:14  Ulrich Drepper  <drepper@cygnus.com>

	* Makeconfig (extra-objs): Depend in before-compile.

	* configure.in: Locate Perl and substitute with complete path.
	* config.make.in: Add PERL for substitution.
	* elf/Makefile (routines): Add dl-addr.
	* elf/dladdr.c: Move the real code into ...
	* elf/dl-addr.c: New file.
	* elf/link.h: Add prototype for _dl_addr.

	* elf/dladdr.c (dladdr): Change address argument to be const.
	* elf/dlfcn.h: Likewise.

	* locale/C_name.c: Add _nl_POSIX_name.
	* locale/localeinfo.h: Add declaration of _nl_POSIX_name.
	* locale/findlocale.c (_nl_find_locale): Use _nl_POSIX_name.
	(_nl_remove_locale): Free name of data set.
	* locale/setlocale.c (clever_copy): Remove.
	(new_composite_name): Use _nl_C_name and _nl_POSIX_name in compare.
	(setname): Only remove old name when it is for category LC_ALL.

	Change malloc, free, realloc, and memalign hooks for glibc to take
	another parameter indicating the location of the caller.
	* malloc/malloc.c: Change hook functions and variables.
	* malloc/malloc.h: Likewise.
	* malloc/mcheck.c: Likewise.  Make sure later hooked function also
	get the original caller address.
	* malloc/mtrace.c: Likewise.
	(tr_where): If no information in _mtrace_file is given use the
	information about the caller.
	* malloc/Makefile (distribute): Replace mtrace.awk by mtrace.pl.
	Add rules to install mtrace.pl after rewriting.
	* malloc/mtrace.pl: New file.  Based on the old AWK script but
	with extended functionality.
	* malloc/mtrace.awk: Removed.

	* po/fr.po: New version.

	* string/Makefile: Do use builtins for tester.c and inl-tester.c.
	* string/tester.c: Rewrite.  Split in many small functions to not
	exceed gcc's limits.

	* sysdeps/unix/sysv/linux/syscalls.list: Add prctl.

1997-09-25  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* string/bits/string2.h (__stpcpy_small): Don't use casts as
	lvalues.

1997-09-26  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* manual/time.texi (Formatting Date and Time): Clarify
	explanation of strftime flags a bit.
	Suggested by Robert Bihlmeyer <robbe@orcus.priv.at>.

1997-09-25 00:13  David S. Miller  <davem@tanya.rutgers.edu>

	* sysdeps/libm-ieee754/s_exp2f.c: Protect _GNU_SOURCE definition.
	Fix typo, it is FLT_MANT_DIG.

1997-09-24 18:52  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* math/atest-exp2.c: Include <stdlib/gmp.h> instead of <gmp.h>.

1997-08-27 08:10  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* libio/libio.h, libio/libioP.h: Support libio in libstdc++.

	* libio/libio.h (_IO_peekc): Defined as _IO_peekc_unlocked if
	_IO_MTSAFE_IO is undefined.

1997-09-24 23:27  Richard Henderson  <rth@cygnus.com>

	* elf/dl-runtime.c (fixup): Don't go through elf_machine_relplt, but
	lookup the value of the target symbol ourselves and call the new
	elf_machine_fixup_plt.  This kills the ELF_FIXUP_RETURN_VALUE hack.
	(profile_fixup): Likewise, but don't fix up the plt.
	* elf/rtld.c (_dl_main): ELF_MACHINE_RELOC_NOPLT renamed _JMP_SLOT.
	* sysdeps/alpha/dl-machine.h (ELF_MACHINE_RELOC_NOPLT): Renamed.
	(elf_alpha_fix_plt): Renamed elf_machine_fixup_plt.
	* sysdeps/i386/dl-machine.h (elf_machine_relplt): Killed.
	(ELF_MACHINE_JMP_SLOT): Renamed.
	(elf_machine_fixup_plt): New function.
	* sysdeps/m68k/dl-machine.h: Likewise.
	* sysdeps/powerpc/dl-machine.h: Likewise.
	(elf_machine_rela): Moved JMP_SLOT fixup out to elf_machine_fixup_plt.
	* sysdeps/sparc/sparc32/dl-machine.h: Likewise.
	* sysdeps/sparc/sparc64/dl-machine.h: Likewise.
	* sysdeps/stub/dl-machine.h: Update, sorta.

	* sysdeps/alpha/dl-machine.h (elf_machine_runtime_setup): Do profiling.
	(TRAMPOLINE_TEMPLATE): From the carcas of _RUNTIME_TRAMPOLINE, do
	both normal and profile code.
	(elf_machine_rela): Handle r_addend for .got and .plt too.
-rw-r--r--ChangeLog96
-rw-r--r--FAQ11
-rw-r--r--Makerules3
-rw-r--r--config.make.in3
-rwxr-xr-xconfigure112
-rw-r--r--configure.in3
-rw-r--r--elf/Makefile2
-rw-r--r--elf/dl-addr.c85
-rw-r--r--elf/dl-runtime.c174
-rw-r--r--elf/dladdr.c64
-rw-r--r--elf/dlfcn.h2
-rw-r--r--elf/link.h4
-rw-r--r--elf/rtld.c2
-rw-r--r--libio/libio.h20
-rw-r--r--libio/libioP.h9
-rw-r--r--locale/C_name.c1
-rw-r--r--locale/findlocale.c5
-rw-r--r--locale/localeinfo.h3
-rw-r--r--locale/setlocale.c30
-rw-r--r--malloc/Makefile21
-rw-r--r--malloc/malloc.c117
-rw-r--r--malloc/malloc.h21
-rw-r--r--malloc/mcheck.c41
-rw-r--r--malloc/mtrace.awk50
-rw-r--r--malloc/mtrace.c83
-rw-r--r--malloc/mtrace.pl192
-rw-r--r--manual/time.texi5
-rw-r--r--math/atest-exp2.c2
-rw-r--r--po/fr.po272
-rw-r--r--string/Makefile2
-rw-r--r--string/bits/string2.h6
-rw-r--r--string/tester.c331
-rw-r--r--sysdeps/alpha/dl-machine.h85
-rw-r--r--sysdeps/i386/dl-machine.h13
-rw-r--r--sysdeps/libm-ieee754/s_exp2f.c6
-rw-r--r--sysdeps/m68k/dl-machine.h13
-rw-r--r--sysdeps/powerpc/dl-machine.h134
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h44
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h44
-rw-r--r--sysdeps/stub/dl-machine.h17
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list1
41 files changed, 1427 insertions, 702 deletions
diff --git a/ChangeLog b/ChangeLog
index f754101122..7e94c28c7b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,99 @@
+1997-09-27 01:14  Ulrich Drepper  <drepper@cygnus.com>
+
+	* Makeconfig (extra-objs): Depend in before-compile.
+
+	* configure.in: Locate Perl and substitute with complete path.
+	* config.make.in: Add PERL for substitution.
+	* elf/Makefile (routines): Add dl-addr.
+	* elf/dladdr.c: Move the real code into ...
+	* elf/dl-addr.c: New file.
+	* elf/link.h: Add prototype for _dl_addr.
+
+	* elf/dladdr.c (dladdr): Change address argument to be const.
+	* elf/dlfcn.h: Likewise.
+
+	* locale/C_name.c: Add _nl_POSIX_name.
+	* locale/localeinfo.h: Add declaration of _nl_POSIX_name.
+	* locale/findlocale.c (_nl_find_locale): Use _nl_POSIX_name.
+	(_nl_remove_locale): Free name of data set.
+	* locale/setlocale.c (clever_copy): Remove.
+	(new_composite_name): Use _nl_C_name and _nl_POSIX_name in compare.
+	(setname): Only remove old name when it is for category LC_ALL.
+
+	Change malloc, free, realloc, and memalign hooks for glibc to take
+	another parameter indicating the location of the caller.
+	* malloc/malloc.c: Change hook functions and variables.
+	* malloc/malloc.h: Likewise.
+	* malloc/mcheck.c: Likewise.  Make sure later hooked function also
+	get the original caller address.
+	* malloc/mtrace.c: Likewise.
+	(tr_where): If no information in _mtrace_file is given use the
+	information about the caller.
+	* malloc/Makefile (distribute): Replace mtrace.awk by mtrace.pl.
+	Add rules to install mtrace.pl after rewriting.
+	* malloc/mtrace.pl: New file.  Based on the old AWK script but
+	with extended functionality.
+	* malloc/mtrace.awk: Removed.
+
+	* po/fr.po: New version.
+
+	* string/Makefile: Do use builtins for tester.c and inl-tester.c.
+	* string/tester.c: Rewrite.  Split in many small functions to not
+	exceed gcc's limits.
+
+	* sysdeps/unix/sysv/linux/syscalls.list: Add prctl.
+
+1997-09-25  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* string/bits/string2.h (__stpcpy_small): Don't use casts as
+	lvalues.
+
+1997-09-26  Andreas Jaeger  <aj@arthur.rhein-neckar.de>
+
+	* manual/time.texi (Formatting Date and Time): Clarify
+	explanation of strftime flags a bit.
+	Suggested by Robert Bihlmeyer <robbe@orcus.priv.at>.
+
+1997-09-25 00:13  David S. Miller  <davem@tanya.rutgers.edu>
+
+	* sysdeps/libm-ieee754/s_exp2f.c: Protect _GNU_SOURCE definition.
+	Fix typo, it is FLT_MANT_DIG.
+
+1997-09-24 18:52  H.J. Lu  <hjl@gnu.ai.mit.edu>
+
+	* math/atest-exp2.c: Include <stdlib/gmp.h> instead of <gmp.h>.
+
+1997-08-27 08:10  H.J. Lu  <hjl@gnu.ai.mit.edu>
+
+	* libio/libio.h, libio/libioP.h: Support libio in libstdc++.
+
+	* libio/libio.h (_IO_peekc): Defined as _IO_peekc_unlocked if
+	_IO_MTSAFE_IO is undefined.
+
+1997-09-24 23:27  Richard Henderson  <rth@cygnus.com>
+
+	* elf/dl-runtime.c (fixup): Don't go through elf_machine_relplt, but
+	lookup the value of the target symbol ourselves and call the new
+	elf_machine_fixup_plt.  This kills the ELF_FIXUP_RETURN_VALUE hack.
+	(profile_fixup): Likewise, but don't fix up the plt.
+	* elf/rtld.c (_dl_main): ELF_MACHINE_RELOC_NOPLT renamed _JMP_SLOT.
+	* sysdeps/alpha/dl-machine.h (ELF_MACHINE_RELOC_NOPLT): Renamed.
+	(elf_alpha_fix_plt): Renamed elf_machine_fixup_plt.
+	* sysdeps/i386/dl-machine.h (elf_machine_relplt): Killed.
+	(ELF_MACHINE_JMP_SLOT): Renamed.
+	(elf_machine_fixup_plt): New function.
+	* sysdeps/m68k/dl-machine.h: Likewise.
+	* sysdeps/powerpc/dl-machine.h: Likewise.
+	(elf_machine_rela): Moved JMP_SLOT fixup out to elf_machine_fixup_plt.
+	* sysdeps/sparc/sparc32/dl-machine.h: Likewise.
+	* sysdeps/sparc/sparc64/dl-machine.h: Likewise.
+	* sysdeps/stub/dl-machine.h: Update, sorta.
+
+	* sysdeps/alpha/dl-machine.h (elf_machine_runtime_setup): Do profiling.
+	(TRAMPOLINE_TEMPLATE): From the carcas of _RUNTIME_TRAMPOLINE, do
+	both normal and profile code.
+	(elf_machine_rela): Handle r_addend for .got and .plt too.
+
 1997-09-25 00:23  Ulrich Drepper  <drepper@cygnus.com>
 
 	* elf/dl-profile.c: Correct implementation.
diff --git a/FAQ b/FAQ
index eb35e1cd00..568af9f207 100644
--- a/FAQ
+++ b/FAQ
@@ -87,6 +87,9 @@ please let me know.
 
 [Q24]	``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
 	  works great.  But the glibc NIS+ doesn't seem to work.''
+
+[Q25]	``After installing glibc name resolving doesn't work properly.''
+
 
 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 [Q1]	``What systems does the GNU C Library run on?''
@@ -687,6 +690,14 @@ http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
 
 
 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+[Q25]	``After installing glibc name resolving doesn't work properly.''
+
+[A25] {AJ} You  probable should read the manual section describing
+``nsswitch.conf'' (just type `info libc "NSS Configuration File"').
+The NSS configuration file is usually the culprit.
+
+
+~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 Answers were given by:
 {UD} Ulrich Drepper, <drepper@cygnus.com>
diff --git a/Makerules b/Makerules
index 85ed6eb13e..abfb8ef85e 100644
--- a/Makerules
+++ b/Makerules
@@ -701,6 +701,9 @@ $(inst_slibdir)/libc.so: $(common-objpfx)libc.so
 	$(do-install-program)
 endif
 
+ifdef extra-objs
+$(addprefix $(objpfx),$(extra-objs)): $(before-compile)
+endif
 
 ifneq (,$(versioned))
 # Produce three sets of rules as above for all the smaller versioned libraries.
diff --git a/config.make.in b/config.make.in
index ba689ececa..ae4d898dd2 100644
--- a/config.make.in
+++ b/config.make.in
@@ -63,7 +63,10 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 LN_S = @LN_S@
 MSGFMT = @MSGFMT@
+
+# Script execution tools.
 BASH = @BASH@
 KSH = @KSH@
+PERL = @PERL@
 
 # More variables may be inserted below by configure.
diff --git a/configure b/configure
index 2ba44100f2..5060a9adc7 100755
--- a/configure
+++ b/configure
@@ -1682,8 +1682,47 @@ else
 fi
 
 
+for ac_prog in perl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1691: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$PERL" in
+  /*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_PERL="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+PERL="$ac_cv_path_PERL"
+if test -n "$PERL"; then
+  echo "$ac_t""$PERL" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PERL" && break
+done
+test -n "$PERL" || PERL="no"
+
+
+
 echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:1687: checking for signed size_t type" >&5
+echo "configure:1726: checking for signed size_t type" >&5
 if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1707,12 +1746,12 @@ EOF
 fi
 
 echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:1711: checking for libc-friendly stddef.h" >&5
+echo "configure:1750: checking for libc-friendly stddef.h" >&5
 if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1716 "configure"
+#line 1755 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -1727,7 +1766,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:1731: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1770: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -1746,7 +1785,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
 fi
 
 echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
-echo "configure:1750: checking whether we need to use -P to assemble .S files" >&5
+echo "configure:1789: checking whether we need to use -P to assemble .S files" >&5
 if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1769,7 +1808,7 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
 fi
 
 echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:1773: checking for assembler global-symbol directive" >&5
+echo "configure:1812: checking for assembler global-symbol directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1799,7 +1838,7 @@ EOF
 fi
 
 echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:1803: checking for .set assembler directive" >&5
+echo "configure:1842: checking for .set assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1833,7 +1872,7 @@ EOF
 fi
 
 echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
-echo "configure:1837: checking for .symver assembler directive" >&5
+echo "configure:1876: checking for .symver assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1852,7 +1891,7 @@ fi
 
 echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
 echo $ac_n "checking for ld --version-script""... $ac_c" 1>&6
-echo "configure:1856: checking for ld --version-script" >&5
+echo "configure:1895: checking for ld --version-script" >&5
 if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1871,7 +1910,7 @@ EOF
     if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
 					-nostartfiles -nostdlib
 					-Wl,--version-script,conftest.map
-		       1>&5'; { (eval echo configure:1875: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+		       1>&5'; { (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
     then
       libc_cv_ld_version_script_option=yes
     else
@@ -1902,7 +1941,7 @@ fi
 
 if test $elf = yes; then
   echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:1906: checking for .previous assembler directive" >&5
+echo "configure:1945: checking for .previous assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1910,7 +1949,7 @@ else
 .section foo_section
 .previous
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1953: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_asm_previous_directive=yes
   else
     libc_cv_asm_previous_directive=no
@@ -1926,7 +1965,7 @@ EOF
 
   else
     echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:1930: checking for .popsection assembler directive" >&5
+echo "configure:1969: checking for .popsection assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1934,7 +1973,7 @@ else
 .pushsection foo_section
 .popsection
 EOF
-    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1977: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
       libc_cv_asm_popsection_directive=yes
     else
       libc_cv_asm_popsection_directive=no
@@ -1954,12 +1993,12 @@ fi
 
 if test $elf != yes; then
   echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:1958: checking for .init and .fini sections" >&5
+echo "configure:1997: checking for .init and .fini sections" >&5
 if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1963 "configure"
+#line 2002 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1968,7 +2007,7 @@ asm (".section .init");
 				    asm (".text");
 ; return 0; }
 EOF
-if { (eval echo configure:1972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2011: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -1996,19 +2035,19 @@ if test $elf = yes; then
 else
   if test $ac_cv_prog_cc_works = yes; then
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2000: checking for _ prefix on C symbol names" >&5
+echo "configure:2039: checking for _ prefix on C symbol names" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2005 "configure"
+#line 2044 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:2012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2051: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -2023,17 +2062,17 @@ fi
 echo "$ac_t""$libc_cv_asm_underscores" 1>&6
   else
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2027: checking for _ prefix on C symbol names" >&5
+echo "configure:2066: checking for _ prefix on C symbol names" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2032 "configure"
+#line 2071 "configure"
 #include "confdefs.h"
 void underscore_test(void) {
 return; }
 EOF
-if { (eval echo configure:2037: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2076: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   if grep _underscore_test conftest* >/dev/null; then
     rm -f conftest*
     libc_cv_asm_underscores=yes
@@ -2066,7 +2105,7 @@ if test $elf = yes; then
   libc_cv_asm_weakext_directive=no
 else
   echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
-echo "configure:2070: checking for assembler .weak directive" >&5
+echo "configure:2109: checking for assembler .weak directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2089,7 +2128,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
 
 if test $libc_cv_asm_weak_directive = no; then
   echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
-echo "configure:2093: checking for assembler .weakext directive" >&5
+echo "configure:2132: checking for assembler .weakext directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2126,7 +2165,7 @@ EOF
 fi
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:2130: checking for ld --no-whole-archive" >&5
+echo "configure:2169: checking for ld --no-whole-archive" >&5
 if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2137,7 +2176,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -Wl,--no-whole-archive
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:2141: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:2180: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_ld_no_whole_archive=yes
 else
   libc_cv_ld_no_whole_archive=no
@@ -2148,7 +2187,7 @@ fi
 echo "$ac_t""$libc_cv_ld_no_whole_archive" 1>&6
 
 echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 1>&6
-echo "configure:2152: checking for gcc -fno-exceptions" >&5
+echo "configure:2191: checking for gcc -fno-exceptions" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2159,7 +2198,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -fno-exceptions
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:2163: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:2202: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_no_exceptions=yes
 else
   libc_cv_gcc_no_exceptions=no
@@ -2170,12 +2209,12 @@ fi
 echo "$ac_t""$libc_cv_gcc_no_exceptions" 1>&6
 
 echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
-echo "configure:2174: checking for DWARF2 unwind info support" >&5
+echo "configure:2213: checking for DWARF2 unwind info support" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 2179 "configure"
+#line 2218 "configure"
 static char __EH_FRAME_BEGIN__;
 _start ()
 {
@@ -2195,7 +2234,7 @@ abort () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles
-			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2199: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_dwarf2_unwind_info=yes
 else
   libc_cv_gcc_dwarf2_unwind_info=no
@@ -2253,7 +2292,7 @@ if test "$uname" = "sysdeps/generic"; then
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:2257: checking OS release for uname" >&5
+echo "configure:2296: checking OS release for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2275,7 +2314,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
   uname_release="$libc_cv_uname_release"
 
   echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
-echo "configure:2279: checking OS version for uname" >&5
+echo "configure:2318: checking OS version for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2297,7 +2336,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:2301: checking stdio selection" >&5
+echo "configure:2340: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -2309,7 +2348,7 @@ esac
 echo "$ac_t""$stdio" 1>&6
 
 echo $ac_n "checking ldap selection""... $ac_c" 1>&6
-echo "configure:2313: checking ldap selection" >&5
+echo "configure:2352: checking ldap selection" >&5
 
 case $add_ons in
 *ldap*)
@@ -2533,6 +2572,7 @@ s%@BASH@%$BASH%g
 s%@libc_cv_have_bash2@%$libc_cv_have_bash2%g
 s%@KSH@%$KSH%g
 s%@libc_cv_have_ksh@%$libc_cv_have_ksh%g
+s%@PERL@%$PERL%g
 s%@VERSIONING@%$VERSIONING%g
 s%@libc_cv_have_initfini@%$libc_cv_have_initfini%g
 s%@libc_cv_ld_no_whole_archive@%$libc_cv_ld_no_whole_archive%g
diff --git a/configure.in b/configure.in
index 4c507bb1e3..efa338c3ee 100644
--- a/configure.in
+++ b/configure.in
@@ -435,6 +435,9 @@ else
 fi
 AC_SUBST(libc_cv_have_ksh)
 
+AC_PATH_PROGS(PERL, perl, no)
+AC_SUBST(PERL)
+
 AC_CACHE_CHECK(for signed size_t type, libc_cv_signed_size_t, [dnl
 echo '#include <stddef.h>
 FOOBAR __SIZE_TYPE__ FOOBAR' > conftest.c
diff --git a/elf/Makefile b/elf/Makefile
index fb85b85e3c..5f78c5cb1d 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -22,7 +22,7 @@ subdir		:= elf
 
 headers		= elf.h bits/elfclass.h bits/dlfcn.h link.h dlfcn.h
 routines	= $(dl-routines) dl-open dl-close dl-symbol dl-support \
-		  enbl-secure
+		  dl-addr enbl-secure
 
 # The core dynamic linking functions are in libc for the static and
 # profiled libraries.
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
new file mode 100644
index 0000000000..d50cc4bf10
--- /dev/null
+++ b/elf/dl-addr.c
@@ -0,0 +1,85 @@
+/* Locate the shared object symbol nearest a given address.
+   Copyright (C) 1996, 1997 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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <stddef.h>
+#include <link.h>
+#include <dlfcn.h>
+
+
+int
+_dl_addr (const void *address, Dl_info *info)
+{
+  const ElfW(Addr) addr = (ElfW(Addr)) address;
+  struct link_map *l, *match;
+  const ElfW(Sym) *symtab, *matchsym;
+  const char *strtab;
+
+  /* Find the highest-addressed object that ADDRESS is not below.  */
+  match = NULL;
+  for (l = _dl_loaded; l; l = l->l_next)
+    if (addr >= l->l_addr && !match || match->l_addr < l->l_addr)
+      match = l;
+
+  if (match)
+    {
+      /* We know ADDRESS lies within MATCH if in any shared object.
+	 Make sure it isn't past the end of MATCH's segments.  */
+      size_t n = match->l_phnum;
+      do
+	--n;
+      while (match->l_phdr[n].p_type != PT_LOAD);
+      if (addr >= (match->l_addr +
+		   match->l_phdr[n].p_vaddr + match->l_phdr[n].p_memsz))
+	/* Off the end of the highest-addressed shared object.  */
+	return 0;
+    }
+  else
+    return 0;
+
+  /* Now we know what object the address lies in.  */
+  info->dli_fname = match->l_name;
+  info->dli_fbase = (void *) match->l_addr;
+
+  symtab = ((void *) match->l_addr + match->l_info[DT_SYMTAB]->d_un.d_ptr);
+  strtab = ((void *) match->l_addr + match->l_info[DT_STRTAB]->d_un.d_ptr);
+
+  /* We assume that the string table follows the symbol table, because
+     there is no way in ELF to know the size of the dynamic symbol table!!  */
+  for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
+    if (addr >= match->l_addr + symtab->st_value && !matchsym ||
+	matchsym->st_value < symtab->st_value &&
+	ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL ||
+	ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
+      matchsym = symtab;
+
+  if (matchsym)
+    {
+      /* We found a symbol close by.  Fill in its name and exact address.  */
+      info->dli_sname = strtab + matchsym->st_name;
+      info->dli_saddr = (void *) (match->l_addr + matchsym->st_value);
+    }
+  else
+    {
+      /* No symbol matches.  We return only the containing object.  */
+      info->dli_sname = NULL;
+      info->dli_saddr = NULL;
+    }
+
+  return 1;
+}
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index e7132ed832..3f09d72c32 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -70,37 +70,16 @@ _dl_object_relocation_scope (struct link_map *l)
 
 #include "dynamic-link.h"
 
-/* Figure out the right type, Rel or Rela.  */
-#define elf_machine_rel 1
-#define elf_machine_rela 2
-#if elf_machine_relplt == elf_machine_rel
-# define PLTREL ElfW(Rel)
-#elif elf_machine_relplt == elf_machine_rela
-# define PLTREL ElfW(Rela)
+#if !defined ELF_MACHINE_NO_RELA || ELF_MACHINE_NO_REL
+# define PLTREL  ElfW(Rela)
 #else
-# error "dl-machine.h bug: elf_machine_relplt not rel or rela"
+# define PLTREL  ElfW(Rel)
 #endif
-#undef elf_machine_rel
-#undef elf_machine_rela
 
 #ifndef VERSYMIDX
 # define VERSYMIDX(sym)	(DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
 #endif
 
-#ifndef ELF_FIXUP_RETURN_VALUE
-#define ELF_FIXUP_RETURN_VALUE(map, result)  (result)
-#endif
-
-/* We need to define the function as a local symbol so that the reference
-   in the trampoline code will be a local PC-relative call.  Tell the
-   compiler not to worry that the function appears not to be called.  */
-
-static ElfW(Addr) fixup (
-#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
-			 ELF_MACHINE_RUNTIME_FIXUP_ARGS,
-#endif
-			 struct link_map *l, ElfW(Word) reloc_offset)
-     __attribute__ ((unused));
 
 /* This function is called through a special trampoline from the PLT the
    first time each PLT entry is called.  We must perform the relocation
@@ -109,7 +88,7 @@ static ElfW(Addr) fixup (
    to that address.  Future calls will bounce directly from the PLT to the
    function.  */
 
-static ElfW(Addr)
+static ElfW(Addr) __attribute__ ((unused))
 fixup (
 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
        ELF_MACHINE_RUNTIME_FIXUP_ARGS,
@@ -124,57 +103,63 @@ fixup (
   const PLTREL *const reloc
     = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
 		      reloc_offset);
-  ElfW(Addr) *const rel_addr = (ElfW(Addr) *)(l->l_addr + reloc->r_offset);
+  const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+  void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
+  ElfW(Addr) value;
 
   /* Set up the scope to find symbols referenced by this object.  */
   struct link_map **scope = _dl_object_relocation_scope (l);
 
-  {
-    const struct r_found_version *here_version;
-
-    /* This macro is used as a callback from the elf_machine_relplt code.  */
-#define RESOLVE(ref, version, flags) \
-  ((version) != NULL && (version)->hash != 0				      \
-   ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope,     \
-				  l->l_name, (version), (flags))	      \
-   : _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope,		      \
-			l->l_name, (flags)))
-#include "dynamic-link.h"
+  /* Sanity check that we're really looking at a PLT relocation.  */
+  assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
 
-    /* Perform the specified relocation.  */
-    if (l->l_info[VERSYMIDX (DT_VERSYM)])
+   /* Look up the target symbol.  */
+  switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+    {
+    default:
       {
-	const ElfW(Half) *version =
-	  (const ElfW(Half) *) (l->l_addr +
-				l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
-	ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
-
-	here_version = &l->l_versions[ndx];
+	const ElfW(Half) *vernum = (const ElfW(Half) *)
+	  (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+	ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
+	const struct r_found_version *version = &l->l_versions[ndx];
+
+	if (version->hash != 0)
+	  {
+	    value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
+						&sym, scope, l->l_name,
+						version, ELF_MACHINE_JMP_SLOT);
+	    break;
+	  }
       }
-    else
-      here_version = NULL;
+    case 0:
+      value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
+				 l->l_name, ELF_MACHINE_JMP_SLOT);
+    }
+
+  /* Currently value contains the base load address of the object
+     that defines sym.  Now add in the symbol offset.  */
+  value = (sym ? value + sym->st_value : 0);
+
+  /* And now the relocation addend.  */
+#ifndef ELF_MACHINE_NO_RELA
+  if (l->l_info[DT_PLTRELSZ]->d_un.d_val == sizeof (ElfW(Rela)))
+    value += reloc->r_addend;
+#elif ELF_MACHINE_NO_REL
+  value += reloc->r_addend;
+#endif
 
-    elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
-			here_version, (void *) rel_addr);
-  }
+  /* Finally, fix up the plt itself.  */
+  elf_machine_fixup_plt (l, reloc, rel_addr, value);
 
   *_dl_global_scope_end = NULL;
 
-  /* Return the address that was written by the relocation.  */
-  return ELF_FIXUP_RETURN_VALUE(l, *rel_addr);
+  return value;
 }
 
 
 #ifndef PROF
-static ElfW(Addr)
-profile_fixup (
-#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
-	       ELF_MACHINE_RUNTIME_FIXUP_ARGS,
-#endif
-	       struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
-     __attribute__ ((unused));
 
-static ElfW(Addr)
+static ElfW(Addr) __attribute__ ((unused))
 profile_fixup (
 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
        ELF_MACHINE_RUNTIME_FIXUP_ARGS,
@@ -182,6 +167,7 @@ profile_fixup (
        struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
 {
   void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount;
+
   const ElfW(Sym) *const symtab
     = (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
   const char *strtab =
@@ -190,47 +176,57 @@ profile_fixup (
   const PLTREL *const reloc
     = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
 		      reloc_offset);
-  ElfW(Addr) result;
+  const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+  ElfW(Addr) value;
 
   /* Set up the scope to find symbols referenced by this object.  */
   struct link_map **scope = _dl_object_relocation_scope (l);
 
-  {
-    const struct r_found_version *here_version;
+  /* Sanity check that we're really looking at a PLT relocation.  */
+  assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
 
-    /* This macro is used as a callback from the elf_machine_relplt code.  */
-#define RESOLVE(ref, version, flags) \
-  ((version) != NULL && (version)->hash != 0				      \
-   ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope,     \
-				  l->l_name, (version), (flags))	      \
-   : _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope,		      \
-			l->l_name, (flags)))
-#include "dynamic-link.h"
-
-    /* Perform the specified relocation.  */
-    if (l->l_info[VERSYMIDX (DT_VERSYM)])
+  /* Look up the target symbol.  */
+  switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+    {
+    default:
       {
-	const ElfW(Half) *version =
-	  (const ElfW(Half) *) (l->l_addr +
-				l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
-	ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
-
-	here_version = &l->l_versions[ndx];
+	const ElfW(Half) *vernum = (const ElfW(Half) *)
+	  (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+	ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
+	const struct r_found_version *version = &l->l_versions[ndx];
+
+	if (version->hash != 0)
+	  {
+	    value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
+						&sym, scope, l->l_name,
+						version, ELF_MACHINE_JMP_SLOT);
+	    break;
+	  }
       }
-    else
-      here_version = NULL;
+    case 0:
+      value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
+				 l->l_name, ELF_MACHINE_JMP_SLOT);
+    }
+
+  /* Currently value contains the base load address of the object
+     that defines sym.  Now add in the symbol offset.  */
+  value = (sym ? value + sym->st_value : 0);
 
-    elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
-			here_version, (void *) &result);
-  }
+  /* And now the relocation addend.  */
+#ifndef ELF_MACHINE_NO_RELA
+  if (l->l_info[DT_PLTRELSZ]->d_un.d_val == sizeof (ElfW(Rela)))
+    value += reloc->r_addend;
+#elif ELF_MACHINE_NO_REL
+  value += reloc->r_addend;
+#endif
 
   *_dl_global_scope_end = NULL;
-  (*mcount_fct) (retaddr, ELF_FIXUP_RETURN_VALUE (l, result));
+  (*mcount_fct) (retaddr, value);
 
-  /* Return the address that was written by the relocation.  */
-  return ELF_FIXUP_RETURN_VALUE (l, result);
+  return value;
 }
-#endif
+
+#endif /* PROF */
 
 
 /* This macro is defined in dl-machine.h to define the entry point called
diff --git a/elf/dladdr.c b/elf/dladdr.c
index 59e9783760..d82a9e78cb 100644
--- a/elf/dladdr.c
+++ b/elf/dladdr.c
@@ -1,5 +1,5 @@
-/* dladdr -- Locate the shared object symbol nearest a given address.
-   Copyright (C) 1996 Free Software Foundation, Inc.
+/* Locate the shared object symbol nearest a given address.
+   Copyright (C) 1996, 1997 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
@@ -23,63 +23,7 @@
 
 
 int
-dladdr (void *address, Dl_info *info)
+dladdr (const void *address, Dl_info *info)
 {
-  const ElfW(Addr) addr = (ElfW(Addr)) address;
-  struct link_map *l, *match;
-  const ElfW(Sym) *symtab, *matchsym;
-  const char *strtab;
-
-  /* Find the highest-addressed object that ADDRESS is not below.  */
-  match = NULL;
-  for (l = _dl_loaded; l; l = l->l_next)
-    if (addr >= l->l_addr && !match || match->l_addr < l->l_addr)
-      match = l;
-
-  if (match)
-    {
-      /* We know ADDRESS lies within MATCH if in any shared object.
-	 Make sure it isn't past the end of MATCH's segments.  */
-      size_t n = match->l_phnum;
-      do
-	--n;
-      while (match->l_phdr[n].p_type != PT_LOAD);
-      if (addr >= (match->l_addr +
-		   match->l_phdr[n].p_vaddr + match->l_phdr[n].p_memsz))
-	/* Off the end of the highest-addressed shared object.  */
-	return 0;
-    }
-  else
-    return 0;
-
-  /* Now we know what object the address lies in.  */
-  info->dli_fname = match->l_name;
-  info->dli_fbase = (void *) match->l_addr;
-
-  symtab = ((void *) match->l_addr + match->l_info[DT_SYMTAB]->d_un.d_ptr);
-  strtab = ((void *) match->l_addr + match->l_info[DT_STRTAB]->d_un.d_ptr);
-
-  /* We assume that the string table follows the symbol table, because
-     there is no way in ELF to know the size of the dynamic symbol table!!  */
-  for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
-    if (addr >= match->l_addr + symtab->st_value && !matchsym ||
-	matchsym->st_value < symtab->st_value &&
-	ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL ||
-	ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
-      matchsym = symtab;
-
-  if (matchsym)
-    {
-      /* We found a symbol close by.  Fill in its name and exact address.  */
-      info->dli_sname = strtab + matchsym->st_name;
-      info->dli_saddr = (void *) (match->l_addr + matchsym->st_value);
-    }
-  else
-    {
-      /* No symbol matches.  We return only the containing object.  */
-      info->dli_sname = NULL;
-      info->dli_saddr = NULL;
-    }
-
-  return 1;
+  return _dl_addr (address, info);
 }
diff --git a/elf/dlfcn.h b/elf/dlfcn.h
index 9db5fb4635..825b4843c1 100644
--- a/elf/dlfcn.h
+++ b/elf/dlfcn.h
@@ -68,7 +68,7 @@ typedef struct
     __const char *dli_sname;	/* Name of nearest symbol.  */
     void *dli_saddr;		/* Exact value of nearest symbol.  */
   } Dl_info;
-extern int dladdr __P ((void *__address, Dl_info *__info));
+extern int dladdr __P ((const void *__address, Dl_info *__info));
 
 __END_DECLS
 
diff --git a/elf/link.h b/elf/link.h
index a90854a2ea..c4b0a4fd9c 100644
--- a/elf/link.h
+++ b/elf/link.h
@@ -27,6 +27,7 @@
 #include <stddef.h>
 
 #include <elf.h>
+#include <dlfcn.h>
 
 __BEGIN_DECLS
 
@@ -358,6 +359,9 @@ extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef,
 						    const struct r_found_version *version,
 						    struct link_map *skip_this);
 
+/* Locate shared object containing the given address.  */
+extern int _dl_addr (const void *address, Dl_info *info);
+
 /* Look up symbol NAME in MAP's scope and return its run-time address.  */
 extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name);
 
diff --git a/elf/rtld.c b/elf/rtld.c
index 3e21f1a95a..74a8f3b05b 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -671,7 +671,7 @@ of this helper program; chances are you did not intend to run this program.\n",
 	    ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
 						     &_dl_default_scope[2],
 						     "argument",
-						     ELF_MACHINE_RELOC_NOPLT);
+						     ELF_MACHINE_JMP_SLOT);
 	    char buf[20], *bp;
 	    buf[sizeof buf - 1] = '\0';
 	    bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
diff --git a/libio/libio.h b/libio/libio.h
index 9e8c108af6..1dddaf27b7 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -26,7 +26,6 @@
 
 #ifndef _IO_STDIO_H
 #define _IO_STDIO_H
-#include <features.h>
 
 #include <_G_config.h>
 #define _IO_pos_t _G_fpos_t /* obsolete */
@@ -76,12 +75,6 @@
 # define _IO_USE_DTOA 1
 #endif
 
-#if 0
-# ifdef _IO_NEED_STDARG_H
-#  include <stdarg.h>
-# endif
-#endif
-
 #ifndef EOF
 # define EOF (-1)
 #endif
@@ -156,7 +149,11 @@ struct _IO_jump_t;  struct _IO_FILE;
 
 /* Handle lock.  */
 #ifdef _IO_MTSAFE_IO
-# include <bits/stdio-lock.h>
+# if defined __GLIBC__ && __GLIBC__ >= 2
+#  include <bits/stdio-lock.h>
+# else
+/*# include <comthread.h>*/
+# endif
 #else
 typedef void _IO_lock_t;
 #endif
@@ -290,7 +287,10 @@ extern void _IO_flockfile __P ((_IO_FILE *));
 extern void _IO_funlockfile __P ((_IO_FILE *));
 extern int _IO_ftrylockfile __P ((_IO_FILE *));
 
-#ifndef _IO_MTSAFE_IO
+#ifdef _IO_MTSAFE_IO
+# define _IO_peekc(_fp) _IO_peekc_locked (_fp)
+#else
+# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp)
 # define _IO_flockfile(_fp) /**/
 # define _IO_funlockfile(_fp) /**/
 # define _IO_ftrylockfile(_fp) /**/
@@ -298,8 +298,6 @@ extern int _IO_ftrylockfile __P ((_IO_FILE *));
 # define _IO_cleanup_region_end(_Doit) /**/
 #endif /* !_IO_MTSAFE_IO */
 
-#define _IO_peekc(_fp) _IO_peekc_locked (_fp)
-
 extern int _IO_vfscanf __P ((_IO_FILE *, const char *, _IO_va_list, int *));
 extern int _IO_vfprintf __P ((_IO_FILE *, const char *, _IO_va_list));
 extern _IO_ssize_t _IO_padn __P ((_IO_FILE *, int, _IO_ssize_t));
diff --git a/libio/libioP.h b/libio/libioP.h
index 66acb93bf4..2337071d39 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -24,7 +24,14 @@
    General Public License.  */
 
 #include <errno.h>
-#include <bits/libc-lock.h>
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
+#if defined __GLIBC__ && __GLIBC__ >= 2
+# include <bits/libc-lock.h>
+#else
+/*# include <comthread.h>*/
+#endif
 
 #include "iolibio.h"
 
diff --git a/locale/C_name.c b/locale/C_name.c
index 5e7cb85a09..fa2ac0539c 100644
--- a/locale/C_name.c
+++ b/locale/C_name.c
@@ -5,3 +5,4 @@
 
 /* Name of our standard locale.  */
 const char _nl_C_name[] = "C";
+const char _nl_POSIX_name[] = "POSIX";
diff --git a/locale/findlocale.c b/locale/findlocale.c
index 308aa2b60f..c027968530 100644
--- a/locale/findlocale.c
+++ b/locale/findlocale.c
@@ -64,7 +64,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
 	*name = (char *) _nl_C_name;
     }
 
-  if (strcmp (*name, _nl_C_name) == 0 || strcmp (*name, "POSIX") == 0)
+  if (strcmp (*name, _nl_C_name) == 0 || strcmp (*name, _nl_POSIX_name) == 0)
     {
       /* We need not load anything.  The needed data is contained in
 	 the library itself.  */
@@ -203,6 +203,9 @@ _nl_remove_locale (int locale, struct locale_data *data)
       ptr->decided = 0;
       ptr->data = NULL;
 
+      /* Free the name.  */
+      free ((char *) data->name);
+
       /* Really delete the data.  First delete the real data.  */
       if (data->mmaped)
 	{
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index 79db06d2f5..29731fa4c6 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -107,8 +107,9 @@ extern const char *const _nl_category_names[LC_ALL + 1];
 extern const size_t _nl_category_name_sizes[LC_ALL + 1];
 extern struct locale_data * *const _nl_current[LC_ALL + 1];
 
-/* Name of the standard locale.  */
+/* Name of the standard locales.  */
 extern const char _nl_C_name[];
+extern const char _nl_POSIX_name[];
 
 /* Extract the current CATEGORY locale's string for ITEM.  */
 #define _NL_CURRENT(category, item) \
diff --git a/locale/setlocale.c b/locale/setlocale.c
index 79f15ccb40..42c1e5033a 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -130,24 +130,6 @@ __libc_lock_define_initialized (, __libc_setlocale_lock)
   } while (0)
 
 
-static inline char *
-clever_copy (const char *string)
-{
-  size_t len;
-  char *new;
-
-  if (strcmp (string, "C") == 0 || strcmp (string, "POSIX") == 0)
-    /* This return is dangerous because the returned string might be
-       placed in read-only memory.  But everything should be set up to
-       handle this case.  */
-    return (char *) _nl_C_name;
-
-  len = strlen (string) + 1;
-  new = (char *) malloc (len);
-  return new != NULL ? memcpy (new, string, len) : NULL;
-}
-
-
 /* Construct a new composite name.  */
 static inline char *
 new_composite_name (int category, const char *newnames[LC_ALL])
@@ -172,7 +154,8 @@ new_composite_name (int category, const char *newnames[LC_ALL])
   if (same)
     {
       /* All the categories use the same name.  */
-      if (strcmp (newnames[0], "C") == 0 || strcmp (newnames[0], "POSIX") == 0)
+      if (strcmp (newnames[0], _nl_C_name) == 0
+	  || strcmp (newnames[0], _nl_POSIX_name) == 0)
 	return (char *) _nl_C_name;
 
       new = malloc (last_len + 1);
@@ -207,8 +190,8 @@ setname (int category, const char *name)
   if (_nl_current_names[category] == name)
     return;
 
-  if (_nl_current_names[category] != _nl_C_name)
-    free ((void *) _nl_current_names[category]);
+  if (category == LC_ALL && _nl_current_names[category] != _nl_C_name)
+    free ((char *) _nl_current_names[category]);
 
   _nl_current_names[category] = name;
 }
@@ -375,7 +358,10 @@ setlocale (int category, const char *locale)
 	    goto abort_single;
 
 	  /* We must not simply free a global locale since we have no
-	     control over the usage.  So we mark it as un-deletable.  */
+	     control over the usage.  So we mark it as un-deletable.
+
+	     Note: do ont remove the `if', it's necessary to copy with
+	     the builtin locale data.  */
 	  if (newdata->usage_count != MAX_USAGE_COUNT)
 	    newdata->usage_count = MAX_USAGE_COUNT;
 	}
diff --git a/malloc/Makefile b/malloc/Makefile
index b43ce136cd..addabf12f8 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -27,7 +27,7 @@ dist-headers := malloc.h
 headers := $(dist-headers) obstack.h
 tests := mallocbug
 
-distribute = thread-m.h mtrace.awk mcheck-init.c mcheck.h
+distribute = thread-m.h mtrace.pl mcheck-init.c mcheck.h
 
 # Things which get pasted together into gmalloc.c.
 gmalloc-routines := malloc morecore
@@ -41,6 +41,19 @@ non-lib.a := libmcheck.a
 # These should be removed by `make clean'.
 extra-objs = mcheck-init.o libmcheck.a
 
+# The AWK script to analyze the output of the mtrace functions.
+ifneq ($(PERL),no)
+install-bin = mtrace
+
+# The Perl script will print addresses and to do this nicely we must know
+# whether we are on a 32 or 64 bit machine.
+ifneq ($strip($(findstring wordsize-32,$(config-sysdirs))),)
+address-width=10
+else
+address-width=18
+endif
+endif
+
 include ../Rules
 
 $(objpfx)libmcheck.a: $(objpfx)mcheck-init.o
@@ -52,3 +65,9 @@ lib: $(objpfx)libmcheck.a
 
 # Uncomment this for test releases.  For public releases it is too expensive.
 #CPPFLAGS-malloc.o += -DMALLOC_DEBUG
+
+$(objpfx)mtrace: mtrace.pl
+	rm -fr %@.new
+	sed -e 's|@PERL@|$(PERL)|' -e 's|@XXX@|$(address-width)|' \
+	    -e 's|@VERSION@|$(version)|' $^ > $@.new \
+	&& rm -fr $@ && mv $@.new $@ && chmod +x $@
diff --git a/malloc/malloc.c b/malloc/malloc.c
index fb51483279..17350eb426 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1178,7 +1178,19 @@ static int       main_trim(size_t pad);
 #ifndef NO_THREADS
 static int       heap_trim(heap_info *heap, size_t pad);
 #endif
-#if defined(_LIBC) || defined(MALLOC_HOOKS)
+#ifdef _LIBC
+static Void_t*   malloc_check(size_t sz, const Void_t *caller);
+static void      free_check(Void_t* mem, const Void_t *caller);
+static Void_t*   realloc_check(Void_t* oldmem, size_t bytes,
+			       const Void_t *caller);
+static Void_t*   memalign_check(size_t alignment, size_t bytes,
+				const Void_t *caller);
+static Void_t*   malloc_starter(size_t sz, const Void_t *caller);
+static void      free_starter(Void_t* mem, const Void_t *caller);
+static Void_t*   malloc_atfork(size_t sz, const Void_t *caller);
+static void      free_atfork(Void_t* mem, const Void_t *caller);
+#else
+#ifdef MALLOC_HOOKS
 static Void_t*   malloc_check(size_t sz);
 static void      free_check(Void_t* mem);
 static Void_t*   realloc_check(Void_t* oldmem, size_t bytes);
@@ -1188,6 +1200,7 @@ static void      free_starter(Void_t* mem);
 static Void_t*   malloc_atfork(size_t sz);
 static void      free_atfork(Void_t* mem);
 #endif
+#endif
 
 #else
 
@@ -1520,11 +1533,19 @@ int __malloc_initialized = 0;
    temporarily, because the `atfork' handler mechanism may use
    malloc/free internally (e.g. in LinuxThreads). */
 
-#if defined(_LIBC) || defined(MALLOC_HOOKS)
+#ifdef _LIBC
+static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size,
+						       const __malloc_ptr_t));
+static void           (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
+						     const __malloc_ptr_t));
+static Void_t*        save_arena;
+#else
+#ifdef MALLOC_HOOKS
 static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size));
 static void           (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr));
 static Void_t*        save_arena;
 #endif
+#endif
 
 static void
 ptmalloc_lock_all __MALLOC_P((void))
@@ -1639,11 +1660,15 @@ thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \
    initialization routine, then do the normal work. */
 
 static Void_t*
+#ifdef _LIBC
+malloc_hook_ini(size_t sz, const __malloc_ptr_t caller)
+#else
 #if __STD_C
 malloc_hook_ini(size_t sz)
 #else
 malloc_hook_ini(sz) size_t sz;
 #endif
+#endif
 {
   __malloc_hook = NULL;
   __realloc_hook = NULL;
@@ -1653,11 +1678,15 @@ malloc_hook_ini(sz) size_t sz;
 }
 
 static Void_t*
+#ifdef _LIBC
+realloc_hook_ini(Void_t* ptr, size_t sz, const __malloc_ptr_t caller)
+#else
 #if __STD_C
 realloc_hook_ini(Void_t* ptr, size_t sz)
 #else
 realloc_hook_ini(ptr, sz) Void_t* ptr; size_t sz;
 #endif
+#endif
 {
   __malloc_hook = NULL;
   __realloc_hook = NULL;
@@ -1667,11 +1696,15 @@ realloc_hook_ini(ptr, sz) Void_t* ptr; size_t sz;
 }
 
 static Void_t*
+#ifdef _LIBC
+memalign_hook_ini(size_t sz, size_t alignment, const __malloc_ptr_t caller)
+#else
 #if __STD_C
 memalign_hook_ini(size_t sz, size_t alignment)
 #else
 memalign_hook_ini(sz, alignment) size_t sz; size_t alignment;
 #endif
+#endif
 {
   __malloc_hook = NULL;
   __realloc_hook = NULL;
@@ -1681,6 +1714,18 @@ memalign_hook_ini(sz, alignment) size_t sz; size_t alignment;
 }
 
 void weak_variable (*__malloc_initialize_hook) __MALLOC_P ((void)) = NULL;
+#ifdef _LIBC
+void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
+					       const __malloc_ptr_t)) = NULL;
+__malloc_ptr_t weak_variable (*__malloc_hook)
+ __MALLOC_P ((size_t __size, const __malloc_ptr_t)) = malloc_hook_ini;
+__malloc_ptr_t weak_variable (*__realloc_hook)
+ __MALLOC_P ((__malloc_ptr_t __ptr, size_t __size, const __malloc_ptr_t))
+     = realloc_hook_ini;
+__malloc_ptr_t weak_variable (*__memalign_hook)
+ __MALLOC_P ((size_t __size, size_t __alignment, const __malloc_ptr_t))
+     = memalign_hook_ini;
+#else
 void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)) = NULL;
 __malloc_ptr_t weak_variable (*__malloc_hook)
  __MALLOC_P ((size_t __size)) = malloc_hook_ini;
@@ -1688,6 +1733,7 @@ __malloc_ptr_t weak_variable (*__realloc_hook)
  __MALLOC_P ((__malloc_ptr_t __ptr, size_t __size)) = realloc_hook_ini;
 __malloc_ptr_t weak_variable (*__memalign_hook)
  __MALLOC_P ((size_t __size, size_t __alignment)) = memalign_hook_ini;
+#endif
 void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL;
 
 /* Activate a standard set of debugging hooks. */
@@ -2489,7 +2535,11 @@ Void_t* mALLOc(bytes) size_t bytes;
   if (__malloc_hook != NULL) {
     Void_t* result;
 
+#ifdef _LIBC
+    result = (*__malloc_hook)(bytes, __builtin_return_address (0));
+#else
     result = (*__malloc_hook)(bytes);
+#endif
     return result;
   }
 #endif
@@ -2780,7 +2830,11 @@ void fREe(mem) Void_t* mem;
 
 #if defined(_LIBC) || defined(MALLOC_HOOKS)
   if (__free_hook != NULL) {
+#ifdef _LIBC
+    (*__free_hook)(mem, __builtin_return_address (0));
+#else
     (*__free_hook)(mem);
+#endif
     return;
   }
 #endif
@@ -2980,7 +3034,11 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   if (__realloc_hook != NULL) {
     Void_t* result;
 
+#ifdef _LIBC
+    result = (*__realloc_hook)(oldmem, bytes, __builtin_return_address (0));
+#else
     result = (*__realloc_hook)(oldmem, bytes);
+#endif
     return result;
   }
 #endif
@@ -3242,7 +3300,12 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
   if (__memalign_hook != NULL) {
     Void_t* result;
 
+#ifdef _LIBC
+    result = (*__memalign_hook)(alignment, bytes,
+				__builtin_return_address (0));
+#else
     result = (*__memalign_hook)(alignment, bytes);
+#endif
     return result;
   }
 #endif
@@ -3413,10 +3476,14 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
 #if defined(_LIBC) || defined(MALLOC_HOOKS)
   if (__malloc_hook != NULL) {
     sz = n * elem_size;
+#ifdef _LIBC
+    mem = (*__malloc_hook)(sz, __builtin_return_address (0));
+#else
     mem = (*__malloc_hook)(sz);
+#endif
     if(mem == 0)
       return 0;
-#ifdef HAVE_MEMCPY
+#ifdef HAVE_MEMSET
     return memset(mem, 0, sz);
 #else
     while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */
@@ -4106,11 +4173,15 @@ mem2chunk_check(mem) Void_t* mem;
 }
 
 static Void_t*
+#ifdef _LIBC
+malloc_check(size_t sz, const Void_t *caller)
+#else
 #if __STD_C
 malloc_check(size_t sz)
 #else
 malloc_check(sz) size_t sz;
 #endif
+#endif
 {
   mchunkptr victim;
   INTERNAL_SIZE_T nb = request2size(sz + 1);
@@ -4129,11 +4200,15 @@ malloc_check(sz) size_t sz;
 }
 
 static void
+#ifdef _LIBC
+free_check(Void_t* mem, const Void_t *caller)
+#else
 #if __STD_C
 free_check(Void_t* mem)
 #else
 free_check(mem) Void_t* mem;
 #endif
+#endif
 {
   mchunkptr p;
 
@@ -4166,16 +4241,24 @@ free_check(mem) Void_t* mem;
 }
 
 static Void_t*
+#ifdef _LIBC
+realloc_check(Void_t* oldmem, size_t bytes, const Void_t *caller)
+#else
 #if __STD_C
 realloc_check(Void_t* oldmem, size_t bytes)
 #else
 realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
 #endif
+#endif
 {
   mchunkptr oldp, newp;
   INTERNAL_SIZE_T nb, oldsize;
 
+#ifdef _LIBC
+  if (oldmem == 0) return malloc_check(bytes, NULL);
+#else
   if (oldmem == 0) return malloc_check(bytes);
+#endif
   (void)mutex_lock(&main_arena.mutex);
   oldp = mem2chunk_check(oldmem);
   if(!oldp) {
@@ -4187,7 +4270,11 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
     case 2:
       abort();
     }
+#ifdef _LIBC
+    return malloc_check(bytes, NULL);
+#else
     return malloc_check(bytes);
+#endif
   }
   oldsize = chunksize(oldp);
 
@@ -4240,16 +4327,24 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
 }
 
 static Void_t*
+#ifdef _LIBC
+memalign_check(size_t alignment, size_t bytes, const Void_t *caller)
+#else
 #if __STD_C
 memalign_check(size_t alignment, size_t bytes)
 #else
 memalign_check(alignment, bytes) size_t alignment; size_t bytes;
 #endif
+#endif
 {
   INTERNAL_SIZE_T nb;
   mchunkptr p;
 
+#ifdef _LIBC
+  if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL);
+#else
   if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes);
+#endif
   if (alignment <  MINSIZE) alignment = MINSIZE;
 
   nb = request2size(bytes+1);
@@ -4270,11 +4365,15 @@ memalign_check(alignment, bytes) size_t alignment; size_t bytes;
    ptmalloc_init() hasn't completed yet. */
 
 static Void_t*
+#ifdef _LIBC
+malloc_starter(size_t sz, const Void_t *caller)
+#else
 #if __STD_C
 malloc_starter(size_t sz)
 #else
 malloc_starter(sz) size_t sz;
 #endif
+#endif
 {
   mchunkptr victim = chunk_alloc(&main_arena, request2size(sz));
 
@@ -4282,11 +4381,15 @@ malloc_starter(sz) size_t sz;
 }
 
 static void
+#ifdef _LIBC
+free_starter(Void_t* mem, const Void_t *caller)
+#else
 #if __STD_C
 free_starter(Void_t* mem)
 #else
 free_starter(mem) Void_t* mem;
 #endif
+#endif
 {
   mchunkptr p;
 
@@ -4305,11 +4408,15 @@ free_starter(mem) Void_t* mem;
    is active. */
 
 static Void_t*
+#ifdef _LIBC
+malloc_atfork (size_t sz, const Void_t *caller)
+#else
 #if __STD_C
 malloc_atfork(size_t sz)
 #else
 malloc_atfork(sz) size_t sz;
 #endif
+#endif
 {
   Void_t *vptr = NULL;
 
@@ -4328,11 +4435,15 @@ malloc_atfork(sz) size_t sz;
 }
 
 static void
+#ifdef _LIBC
+free_atfork(Void_t* mem, const Void_t *caller)
+#else
 #if __STD_C
 free_atfork(Void_t* mem)
 #else
 free_atfork(mem) Void_t* mem;
 #endif
+#endif
 {
   Void_t *vptr = NULL;
   arena *ar_ptr;
diff --git a/malloc/malloc.h b/malloc/malloc.h
index a72102e607..65381705df 100644
--- a/malloc/malloc.h
+++ b/malloc/malloc.h
@@ -178,8 +178,25 @@ extern __malloc_ptr_t malloc_get_state __MALLOC_P ((void));
    malloc_get_state(). */
 extern int malloc_set_state __MALLOC_P ((__malloc_ptr_t __ptr));
 
-#if defined(__GLIBC__) || defined(MALLOC_HOOKS)
+#ifdef __GLIBC__
+/* Hooks for debugging versions. */
+extern void (*__malloc_initialize_hook) __MALLOC_P ((void));
+extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
+					__const __malloc_ptr_t));
+extern __malloc_ptr_t (*__malloc_hook) __MALLOC_P ((size_t __size,
+						    __const __malloc_ptr_t));
+extern __malloc_ptr_t (*__realloc_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
+						     size_t __size,
+						     __const __malloc_ptr_t));
+extern __malloc_ptr_t (*__memalign_hook) __MALLOC_P ((size_t __size,
+						      size_t __alignment,
+						      __const __malloc_ptr_t));
+extern void (*__after_morecore_hook) __MALLOC_P ((void));
 
+/* Activate a standard set of debugging hooks. */
+extern void __malloc_check_init __MALLOC_P ((void));
+#else
+#ifdef MALLOC_HOOKS
 /* Hooks for debugging versions. */
 extern void (*__malloc_initialize_hook) __MALLOC_P ((void));
 extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr));
@@ -192,7 +209,7 @@ extern void (*__after_morecore_hook) __MALLOC_P ((void));
 
 /* Activate a standard set of debugging hooks. */
 extern void __malloc_check_init __MALLOC_P ((void));
-
+#endif
 #endif
 
 #ifdef __cplusplus
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
index 1a80a56570..47d35f1f1f 100644
--- a/malloc/mcheck.c
+++ b/malloc/mcheck.c
@@ -28,9 +28,10 @@
 #endif
 
 /* Old hook values.  */
-static void (*old_free_hook) __P ((__ptr_t ptr));
-static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size));
-static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
+static void (*old_free_hook) __P ((__ptr_t ptr, __const __ptr_t));
+static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size, const __ptr_t));
+static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size,
+					 __const __ptr_t));
 
 /* Function to call when something awful happens.  */
 static void (*abortfunc) __P ((enum mcheck_status));
@@ -91,10 +92,11 @@ checkhdr (hdr)
   return status;
 }
 
-static void freehook __P ((__ptr_t));
+static void freehook __P ((__ptr_t, const __ptr_t));
 static void
-freehook (ptr)
+freehook (ptr, caller)
      __ptr_t ptr;
+     const __ptr_t caller;
 {
   if (ptr)
     {
@@ -105,19 +107,27 @@ freehook (ptr)
       ptr = (__ptr_t) hdr;
     }
   __free_hook = old_free_hook;
-  free (ptr);
+  if (old_free_hook != NULL)
+    (*old_free_hook) (ptr, caller);
+  else
+    free (ptr);
   __free_hook = freehook;
 }
 
-static __ptr_t mallochook __P ((__malloc_size_t));
+static __ptr_t mallochook __P ((__malloc_size_t, const __ptr_t));
 static __ptr_t
-mallochook (size)
+mallochook (size, caller)
      __malloc_size_t size;
+     const __ptr_t caller;
 {
   struct hdr *hdr;
 
   __malloc_hook = old_malloc_hook;
-  hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
+  if (old_malloc_hook != NULL)
+    hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1,
+					     caller);
+  else
+    hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
   __malloc_hook = mallochook;
   if (hdr == NULL)
     return NULL;
@@ -129,11 +139,12 @@ mallochook (size)
   return (__ptr_t) (hdr + 1);
 }
 
-static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t));
+static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t));
 static __ptr_t
-reallochook (ptr, size)
+reallochook (ptr, size, caller)
      __ptr_t ptr;
      __malloc_size_t size;
+     const __ptr_t caller;
 {
   struct hdr *hdr;
   __malloc_size_t osize;
@@ -155,7 +166,13 @@ reallochook (ptr, size)
   __free_hook = old_free_hook;
   __malloc_hook = old_malloc_hook;
   __realloc_hook = old_realloc_hook;
-  hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1);
+  if (old_realloc_hook != NULL)
+    hdr = (struct hdr *) (*old_realloc_hook) ((__ptr_t) hdr,
+					      sizeof (struct hdr) + size + 1,
+					      caller);
+  else
+    hdr = (struct hdr *) realloc ((__ptr_t) hdr,
+				  sizeof (struct hdr) + size + 1);
   __free_hook = freehook;
   __malloc_hook = mallochook;
   __realloc_hook = reallochook;
diff --git a/malloc/mtrace.awk b/malloc/mtrace.awk
deleted file mode 100644
index 06844d1a4b..0000000000
--- a/malloc/mtrace.awk
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-#  Awk program to analyze mtrace.c output.
-#
-{
-  if ($1 == "@") {
-    where = " (" $2 ")"
-    n = 3
-  } else {
-    where = ""
-    n = 1
-  }
-  if ($n == "+") {
-    if (allocated[$(n+1)] != "")
-      print "+", $(n+1), "Alloc", NR, "duplicate:", allocated[$(n+1)], wherewas[$(n+1)], where;
-    else {
-      wherewas[$(n+1)] = where;
-      allocated[$(n+1)] = $(n+2);
-    }
-  } else if ($n == "-") {
-    if (allocated[$(n+1)] != "") {
-      wherewas[$(n+1)] = "";
-      allocated[$(n+1)] = "";
-      if (allocated[$(n+1)] != "")
-	print "DELETE FAILED", $(n+1), allocated[$(n+1)];
-    } else
-      print "-", $(n+1), "Free", NR, "was never alloc'd", where;
-  } else if ($n == "<")	{
-    if (allocated[$(n+1)] != "") {
-      wherewas[$(n+1)] = "";
-      allocated[$(n+1)] = "";
-    } else
-      print "-", $(n+1), "Realloc", NR, "was never alloc'd", where;
-  } else if ($n == ">") {
-    if (allocated[$(n+1)] != "")
-      print "+", $(n+1), "Realloc", NR, "duplicate:", allocated[$(n+1)], where;
-    else {
-      wherewas[$(n+1)] = $(n+2);
-      allocated[$(n+1)] = $(n+2);
-    }
-  } else if ($n == "=") {
-    # Ignore "= Start"
-  } else if ($n == "!") {
-    # Ignore failed realloc attempts for now
-  }
-}
-END {
-  for (x in allocated) 
-    if (allocated[x] != "")
-      print "+", x, allocated[x], wherewas[x];
-}
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
index 3f0cbb9726..aeefd5600e 100644
--- a/malloc/mtrace.c
+++ b/malloc/mtrace.c
@@ -1,5 +1,5 @@
 /* More debugging hooks for `malloc'.
-   Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
 		 Written April 2, 1991 by John Gilmore of Cygnus Support.
 		 Based on mcheck.c by Mike Haertel.
 
@@ -28,6 +28,10 @@
 #include <bits/libc-lock.h>
 #endif
 
+#ifdef HAVE_ELF
+#include <link.h>
+#endif
+
 #include <stdio.h>
 
 #ifndef	__GNU_LIBRARY__
@@ -51,9 +55,12 @@ char *_mtrace_file;
 int _mtrace_line;
 
 /* Old hook values.  */
-static void (*tr_old_free_hook) __P ((__ptr_t ptr));
-static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size));
-static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
+static void (*tr_old_free_hook) __P ((__ptr_t ptr, const __ptr_t));
+static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size,
+					   const __ptr_t));
+static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr,
+					    __malloc_size_t size,
+					    const __ptr_t));
 
 /* This function is called when the block being alloc'd, realloc'd, or
    freed has an address matching the variable "mallwatch".  In a debugger,
@@ -66,51 +73,77 @@ tr_break ()
 {
 }
 
-static void tr_where __P ((void));
+static void tr_where __P ((const __ptr_t));
 static void
-tr_where ()
+tr_where (caller)
+     const __ptr_t caller;
 {
   if (_mtrace_file)
     {
       fprintf (mallstream, "@ %s:%d ", _mtrace_file, _mtrace_line);
       _mtrace_file = NULL;
     }
+  else if (caller != NULL)
+    {
+#ifdef HAVE_ELF
+      Dl_info info;
+      if (_dl_addr (caller, &info))
+	{
+	  fprintf (mallstream, "@ %s%s%s%s%s[%p]",
+		   info.dli_fname ?: "", info.dli_fname ? ":" : "",
+		   info.dli_sname ? "(" : "",
+		   info.dli_sname ?: "", info.dli_sname ? ") " : " ",
+		   caller);
+	}
+      else
+#endif
+	fprintf (mallstream, "@ [%p] ", caller);
+    }
 }
 
-static void tr_freehook __P ((__ptr_t));
+static void tr_freehook __P ((__ptr_t, const __ptr_t));
 static void
-tr_freehook (ptr)
+tr_freehook (ptr, caller)
      __ptr_t ptr;
+     const __ptr_t caller;
 {
-  tr_where ();
-  fprintf (mallstream, "- %p\n", ptr);	/* Be sure to print it first.  */
+  tr_where (caller);
+  /* Be sure to print it first.  */
+  fprintf (mallstream, "- %p\n", ptr);
   if (ptr == mallwatch)
     tr_break ();
   __libc_lock_lock (lock);
   __free_hook = tr_old_free_hook;
-  free (ptr);
+  if (tr_old_free_hook != NULL)
+    (*tr_old_free_hook) (ptr, caller);
+  else
+    free (ptr);
   __free_hook = tr_freehook;
   __libc_lock_unlock (lock);
 }
 
-static __ptr_t tr_mallochook __P ((__malloc_size_t));
+static __ptr_t tr_mallochook __P ((__malloc_size_t, const __ptr_t));
 static __ptr_t
-tr_mallochook (size)
+tr_mallochook (size, caller)
      __malloc_size_t size;
+     const __ptr_t caller;
 {
   __ptr_t hdr;
 
   __libc_lock_lock (lock);
 
   __malloc_hook = tr_old_malloc_hook;
-  hdr = (__ptr_t) malloc (size);
+  if (tr_old_malloc_hook != NULL)
+    hdr = (__ptr_t) (*tr_old_malloc_hook) (size, caller);
+  else
+    hdr = (__ptr_t) malloc (size);
   __malloc_hook = tr_mallochook;
 
   __libc_lock_unlock (lock);
 
-  tr_where ();
+  tr_where (caller);
   /* We could be printing a NULL here; that's OK.  */
-  fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size);
+  fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size);
 
   if (hdr == mallwatch)
     tr_break ();
@@ -118,11 +151,12 @@ tr_mallochook (size)
   return hdr;
 }
 
-static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t));
+static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t));
 static __ptr_t
-tr_reallochook (ptr, size)
+tr_reallochook (ptr, size, caller)
      __ptr_t ptr;
      __malloc_size_t size;
+     const __ptr_t caller;
 {
   __ptr_t hdr;
 
@@ -134,21 +168,24 @@ tr_reallochook (ptr, size)
   __free_hook = tr_old_free_hook;
   __malloc_hook = tr_old_malloc_hook;
   __realloc_hook = tr_old_realloc_hook;
-  hdr = (__ptr_t) realloc (ptr, size);
+  if (tr_old_realloc_hook != NULL)
+    hdr = (__ptr_t) (*tr_old_realloc_hook) (ptr, size, caller);
+  else
+    hdr = (__ptr_t) realloc (ptr, size);
   __free_hook = tr_freehook;
   __malloc_hook = tr_mallochook;
   __realloc_hook = tr_reallochook;
 
   __libc_lock_unlock (lock);
 
-  tr_where ();
+  tr_where (caller);
   if (hdr == NULL)
     /* Failed realloc.  */
-    fprintf (mallstream, "! %p %lx\n", ptr, (unsigned long)size);
+    fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long)size);
   else if (ptr == NULL)
-    fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size);
+    fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size);
   else
-    fprintf (mallstream, "< %p\n> %p %lx\n", ptr, hdr, (unsigned long)size);
+    fprintf (mallstream, "< %p\n> %p %#lx\n", ptr, hdr, (unsigned long)size);
 
   if (hdr == mallwatch)
     tr_break ();
diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl
new file mode 100644
index 0000000000..46d8425bee
--- /dev/null
+++ b/malloc/mtrace.pl
@@ -0,0 +1,192 @@
+#! @PERL@
+eval "exec @PERL@ -S $0 $*"
+    if 0;
+# Copyright (C) 1997 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1997.
+# Based on the mtrace.awk script.
+
+# 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+$VERSION = "@VERSION@";
+$PACKAGE = "libc";
+$progname = $0;
+
+sub usage {
+    print "Usage: mtrace [OPTION]... [Binary] MtraceData\n";
+    print "  --help       print this help, then exit\n";
+    print "  --version    print version number, then exit\n";
+    exit 0;
+}
+
+# We expect two arguments:
+#   #1: the complete path to the binary
+#   #2: the mtrace data filename
+# The usual options are also recognized.
+
+arglist: while (@ARGV) {
+    if ($ARGV[0] eq "--v" || $ARGV[0] eq "--ve" || $ARGV[0] eq "--ver" ||
+	$ARGV[0] eq "--vers" || $ARGV[0] eq "--versi" ||
+	$ARGV[0] eq "--versio" || $ARGV[0] eq "--version") {
+	print "mtrace (GNU $PACKAGE) $VERSION\n";
+	print "Copyright (C) 1997 Free Software Foundation, Inc.\n";
+	print "This is free software; see the source for copying conditions.  There is NO\n";
+	print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
+	print "Written by Ulrich Drepper <drepper\@gnu.ai.mit.edu>\n";
+
+	exit 0;
+    } elsif ($ARGV[0] eq "--h" || $ARGV[0] eq "--he" || $ARGV[0] eq "--hel" ||
+	     $ARGV[0] eq "--help") {
+	&usage;
+    } elsif ($ARGV[0] =~ /^-/) {
+	print "$progname: unrecognized option `$ARGV[0]'\n";
+	print "Try `$progname --help' for more information.\n";
+	exit 1;
+    } else {
+	last arglist;
+    }
+}
+
+if ($#ARGV == 0) {
+    $binary="";
+    $data=$ARGV[0];
+} elsif ($#ARGV == 1) {
+    $binary=$ARGV[0];
+    $data=$ARGV[1];
+} else {
+    die "Wrong number of arguments.";
+}
+
+sub location {
+    my $str = pop(@_);
+    return $str if ($str eq "");
+    if ($str =~ /[[](0x[^]]*)]:(.)*/) {
+	my $addr = $1;
+	my $fct = $2;
+	return $cache{$addr} if (exists $cache{$addr});
+	if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
+	    my $line = <ADDR>;
+	    chomp $line;
+	    close (ADDR);
+	    if ($line ne '??:0') {
+		$cache{$addr} = $line;
+		return $cache{$addr};
+	    }
+	}
+	$cache{$addr} = $str = "$fct @ $addr";
+    } elsif ($str =~ /^[[](0x[^]]*)]$/) {
+	my $addr = $1;
+	return $cache{$addr} if (exists $cache{$addr});
+	if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
+	    my $line = <ADDR>;
+	    chomp $line;
+	    close (ADDR);
+	    if ($line ne '??:0') {
+		$cache{$addr} = $line;
+		return $cache{$addr};
+	    }
+	}
+	$cache{$addr} = $str = $addr;
+    }
+    return $str;
+}
+
+$nr=0;
+open(DATA, "<$data") || die "Cannot open mtrace data file";
+while (<DATA>) {
+    my @cols = split (' ');
+    my $n, $where;
+    if ($cols[0] eq "@") {
+	# We have address and/or function name.
+	$where=$cols[1];
+	$n=2;
+    } else {
+	$where="";
+	$n=0;
+    }
+
+    $allocaddr=$cols[$n + 1];
+    $howmuch=hex($cols[$n + 2]);
+
+    ++$nr;
+    SWITCH: {
+	if ($cols[$n] eq "+") {
+	    if (defined $allocated{$allocaddr}) {
+		printf ("+ %#010x Alloc %d duplicate: %s %s\n",
+			hex($allocaddr), $nr, $wherewas{$allocaddr}, $where);
+	    } else {
+		$allocated{$allocaddr}=$howmuch;
+		$wherewas{$allocaddr}=&location($where);
+	    }
+	    last SWITCH;
+	}
+	if ($cols[$n] eq "-") {
+	    if (defined $allocated{$allocaddr}) {
+		undef $allocated{$allocaddr};
+		undef $wherewas{$allocaddr};
+	    } else {
+		printf ("- %#010x Free %d was never alloc'd %s\n",
+			hex($allocaddr), $nr, &location($where));
+	    }
+	    last SWITCH;
+	}
+	if ($cols[$n] eq "<") {
+	    if (defined $allocated{$allocaddr}) {
+		undef $allocated{$allocaddr};
+		undef $wherewas{$allocaddr};
+	    } else {
+		printf ("- %#010x Realloc %d was never alloc'd %s\n",
+			hex($allocaddr), $nr, &location($where));
+	    }
+	    last SWITCH;
+	}
+	if ($cols[$n] eq ">") {
+	    if (defined $allocated{$allocaddr}) {
+		printf ("+ %#010x Realloc %d duplicate: %#010x %s %s\n",
+			hex($allocaddr), $nr, $allocated{$allocaddr},
+			$wherewas{$allocaddr}, &location($where));
+	    } else {
+		$allocated{$allocaddr}=$howmuch;
+		$wherewas{$allocaddr}=&location($where);
+	    }
+	    last SWITCH;
+	}
+	if ($cols[$n] eq "=") {
+	    # Ignore "= Start".
+	    last SWITCH;
+	}
+	if ($cols[$n] eq "!") {
+	    # Ignore failed realloc for now.
+	    last SWITCH;
+	}
+    }
+}
+close (DATA);
+
+# Now print all remaining entries.
+@addrs= keys %allocated;
+if ($#addrs >= 0) {
+    print "\nNot freed memory:\n-----------------\n";
+    print ' ' x (@XXX@ - 7), "Address     Size     Caller\n";
+    foreach $addr (sort @addrs) {
+	if (defined $allocated{$addr}) {
+	    printf ("%#0@XXX@x %#8x  at %s\n", hex($addr), $allocated{$addr},
+		    $wherewas{$addr});
+	}
+    }
+}
+
+exit 0;
diff --git a/manual/time.texi b/manual/time.texi
index d711234c0b..7a5cd655c0 100644
--- a/manual/time.texi
+++ b/manual/time.texi
@@ -695,8 +695,9 @@ time conversion (@pxref{Locales}).
 Ordinary characters appearing in the @var{template} are copied to the
 output string @var{s}; this can include multibyte character sequences.
 Conversion specifiers are introduced by a @samp{%} character, followed
-by an optional flag which can be one of the following.  These flags,
-which are GNU extensions, affect only the output of numbers:
+by an optional flag which can be one of the following.  These flags
+are all GNU extensions. The first three affect only the output of
+numbers:
 
 @table @code
 @item _
diff --git a/math/atest-exp2.c b/math/atest-exp2.c
index 95e72aa507..1f5d7ccd86 100644
--- a/math/atest-exp2.c
+++ b/math/atest-exp2.c
@@ -19,7 +19,7 @@
 
 #include <stdio.h>
 #include <math.h>
-#include <gmp.h>
+#include <stdlib/gmp.h>
 #include <string.h>
 #include <limits.h>
 #include <assert.h>
diff --git a/po/fr.po b/po/fr.po
index 8f20403658..b79e9d658e 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -4,9 +4,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: GNU libc 2.0.3\n"
-"POT-Creation-Date: 1997-03-30 19:08+0200\n"
-"PO-Revision-Date: 1997-04-02 23:02 -0500\n"
+"Project-Id-Version: GNU libc 2.0.5\n"
+"POT-Creation-Date: 1997-08-21 04:13+0200\n"
+"PO-Revision-Date: 1997-09-23 16:00 -0500\n"
 "Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n"
 "Language-Team: French <fr@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -33,7 +33,7 @@ msgstr "       rpcinfo [ -n no_de_port ] -t hôte no_program [ no_version ]\n"
 msgid "   program vers proto   port\n"
 msgstr "   program no_version protocole  no_port\n"
 
-#: time/zic.c:419
+#: time/zic.c:421
 #, c-format
 msgid " (rule from \"%s\", line %d)"
 msgstr " (règles de \"%s\", ligne %d)"
@@ -42,22 +42,22 @@ msgstr " (règles de \"%s\", ligne %d)"
 msgid " done\n"
 msgstr " complété.\n"
 
-#: time/zic.c:416
+#: time/zic.c:418
 #, c-format
 msgid "\"%s\", line %d: %s"
 msgstr "\"%s\", ligne %d: %s."
 
-#: time/zic.c:943
+#: time/zic.c:947
 #, c-format
 msgid "\"Zone %s\" line and -l option are mutually exclusive"
 msgstr "La ligne \"Zone %s\" et l'option -l sont mutuellement exclusives."
 
-#: time/zic.c:951
+#: time/zic.c:955
 #, c-format
 msgid "\"Zone %s\" line and -p option are mutually exclusive"
 msgstr "La ligne \"Zone %s\" et l'option -p sont mutuellement exclusives."
 
-#: time/zic.c:754
+#: time/zic.c:758
 #, c-format
 msgid "%s in ruleless zone"
 msgstr "%s est dans une zone sans règle."
@@ -77,7 +77,7 @@ msgstr "%s%s%s:%u: %s%s erreur imprévue: %s.\n"
 msgid "%s%sUnknown signal %d\n"
 msgstr "%s%ssignal inconnu %d.\n"
 
-#: time/zic.c:2172
+#: time/zic.c:2185
 #, c-format
 msgid "%s: %d did not sign extend correctly\n"
 msgstr "%s: %d n'a pas fait correctement l'expansion de la valeur signée.\n"
@@ -87,42 +87,42 @@ msgstr "%s: %d n'a pas fait correctement l'expansion de la valeur signée.\n"
 msgid "%s: <mb_cur_max> must be greater than <mb_cur_min>\n"
 msgstr "%s: <mb_cur_max> doit être plus grande que <mb_cur_min>.\n"
 
-#: time/zic.c:1443
+#: time/zic.c:1456
 #, c-format
 msgid "%s: Can't create %s: %s\n"
 msgstr "%s: ne peut créer %s: %s.\n"
 
-#: time/zic.c:2150
+#: time/zic.c:2163
 #, c-format
 msgid "%s: Can't create directory %s: %s\n"
 msgstr "%s: ne peut créer le répertoire %s: %s.\n"
 
-#: time/zic.c:608
+#: time/zic.c:610
 #, c-format
 msgid "%s: Can't link from %s to %s: %s\n"
 msgstr "%s: ne peut établir un lien entre %s et %s: %s.\n"
 
-#: time/zic.c:780
+#: time/zic.c:784
 #, c-format
 msgid "%s: Can't open %s: %s\n"
 msgstr "%s: ne peut ouvrir %s: %s.\n"
 
-#: time/zic.c:1433
+#: time/zic.c:1446
 #, c-format
 msgid "%s: Can't remove %s: %s\n"
 msgstr "%s: ne peut enlever %s: %s.\n"
 
-#: time/zic.c:849
+#: time/zic.c:853
 #, c-format
 msgid "%s: Error closing %s: %s\n"
 msgstr "%s: erreur lors de la fermeture de %s: %s.\n"
 
-#: time/zic.c:842
+#: time/zic.c:846
 #, c-format
 msgid "%s: Error reading %s\n"
 msgstr "%s: erreur de lecture de %s.\n"
 
-#: time/zic.c:1507
+#: time/zic.c:1520
 #, c-format
 msgid "%s: Error writing %s\n"
 msgstr "%s: erreur d'écriture de %s.\n"
@@ -132,44 +132,44 @@ msgstr "%s: erreur d'écriture de %s.\n"
 msgid "%s: Error writing standard output "
 msgstr "%s: erreur d'écriture sur la sortie standard."
 
-#: time/zic.c:827
+#: time/zic.c:831
 #, c-format
 msgid "%s: Leap line in non leap seconds file %s\n"
 msgstr ""
 "%s: ligne de type `Leap' dans un fichier qui n'a pas\n"
 "de délai en secondes %s.\n"
 
-#: time/zic.c:357
+#: time/zic.c:359
 #, c-format
 msgid "%s: Memory exhausted: %s\n"
 msgstr "%s: mémoire épuisée: %s.\n"
 
-#: time/zic.c:522
+#: time/zic.c:524
 #, c-format
 msgid "%s: More than one -L option specified\n"
 msgstr "%s: option -L spécifiée plus d'une fois.\n"
 
-#: time/zic.c:482
+#: time/zic.c:484
 #, c-format
 msgid "%s: More than one -d option specified\n"
 msgstr "%s: option -d spécifiée plus d'une fois.\n"
 
-#: time/zic.c:492
+#: time/zic.c:494
 #, c-format
 msgid "%s: More than one -l option specified\n"
 msgstr "%s: option -l spécifiée plus d'une fois.\n"
 
-#: time/zic.c:502
+#: time/zic.c:504
 #, c-format
 msgid "%s: More than one -p option specified\n"
 msgstr "%s: option -p spécifiée plus d'une fois.\n"
 
-#: time/zic.c:512
+#: time/zic.c:514
 #, c-format
 msgid "%s: More than one -y option specified\n"
 msgstr "%s: option -y spécifiée plus d'une fois.\n"
 
-#: time/zic.c:1872
+#: time/zic.c:1885
 #, c-format
 msgid "%s: command was '%s', result was %d\n"
 msgstr "%s: la commande était '%s', le résultat était %d.\n"
@@ -224,7 +224,7 @@ msgstr "%s: l'option `-W %s' est ambiguë.\n"
 msgid "%s: option requires an argument -- %c\n"
 msgstr "%s: l'option requiert un paramètre -- %c.\n"
 
-#: time/zic.c:834 time/zic.c:1246 time/zic.c:1266
+#: time/zic.c:838 time/zic.c:1251 time/zic.c:1275
 #, c-format
 msgid "%s: panic: Invalid l_value %d\n"
 msgstr "%s: panique: valeur %d de type `l_value' invalide.\n"
@@ -244,7 +244,7 @@ msgstr "%s: option non reconnue `%c%s'.\n"
 msgid "%s: unrecognized option `--%s'\n"
 msgstr "%s: option non reconnue `--%s'.\n"
 
-#: time/zic.c:441
+#: time/zic.c:443
 #, c-format
 msgid ""
 "%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d "
@@ -545,7 +545,7 @@ msgstr "Connexion terminée par expiration du délai d'inactivité."
 msgid "Continued"
 msgstr "Poursuite."
 
-#: catgets/gencat.c:169 db/makedb.c:120 locale/programs/locale.c:187
+#: catgets/gencat.c:169 db/makedb.c:120 locale/programs/locale.c:191
 #: locale/programs/localedef.c:180
 #, c-format
 msgid ""
@@ -803,11 +803,11 @@ msgstr "Appel système interrompu, il aurait dû être relancé."
 msgid "Invalid argument"
 msgstr "Paramètre invalide."
 
-#: posix/regex.c:960
+#: posix/regex.c:978
 msgid "Invalid back reference"
 msgstr "Référence arrière invalide."
 
-#: posix/regex.c:958
+#: posix/regex.c:976
 msgid "Invalid character class name"
 msgstr "Nom de classe de caractères invalide."
 
@@ -819,11 +819,11 @@ msgstr "Identité du client invalide."
 msgid "Invalid client verifier"
 msgstr "Vérificateur du client invalide."
 
-#: posix/regex.c:957
+#: posix/regex.c:975
 msgid "Invalid collation character"
 msgstr "Caractère de fusionnement invalide."
 
-#: posix/regex.c:964
+#: posix/regex.c:982
 msgid "Invalid content of \\{\\}"
 msgstr "Contenu invalide de \\{\\}"
 
@@ -844,15 +844,15 @@ msgstr "Échange invalide."
 msgid "Invalid or incomplete multibyte or wide character"
 msgstr "Chaîne multi-octets ou étendue de caractères invalide ou incomplète."
 
-#: posix/regex.c:967
+#: posix/regex.c:985
 msgid "Invalid preceding regular expression"
 msgstr "Expression régulière précédente invalide."
 
-#: posix/regex.c:965
+#: posix/regex.c:983
 msgid "Invalid range end"
 msgstr "Fin d'intervalle invalide."
 
-#: posix/regex.c:956
+#: posix/regex.c:974
 msgid "Invalid regular expression"
 msgstr "Expression régulière invalide."
 
@@ -923,7 +923,7 @@ msgstr "Échec d'allocation de ressources locales."
 msgid "Machine is not on the network"
 msgstr "La machine cible n'est pas sur le réseau."
 
-#: posix/regex.c:966
+#: posix/regex.c:984
 msgid "Memory exhausted"
 msgstr "Mémoire épuisée."
 
@@ -1016,7 +1016,7 @@ msgstr "Aucune donnée disponible."
 msgid "No locks available"
 msgstr "Aucun verrou disponible."
 
-#: posix/regex.c:955
+#: posix/regex.c:973
 msgid "No match"
 msgstr "Pas de concordance."
 
@@ -1028,7 +1028,7 @@ msgstr "Aucun message du type désiré."
 msgid "No more records in map database"
 msgstr "Aucun autre enregistrement dans la table de la base de données."
 
-#: posix/regex.c:5324
+#: posix/regex.c:5434
 msgid "No previous regular expression"
 msgstr "Aucune expression régulière ne précède."
 
@@ -1096,7 +1096,7 @@ msgstr "Le résultat numérique est en dehors de l'intervalle."
 msgid "Object is remote"
 msgstr "L'objet est télé-accessible."
 
-#: time/zic.c:1966
+#: time/zic.c:1979
 msgid "Odd number of quotation marks"
 msgstr "Nombre impair de caractères apostrophe."
 
@@ -1166,7 +1166,7 @@ msgstr "Permission non accordée."
 msgid "Power failure"
 msgstr "Panne d'alimentation."
 
-#: posix/regex.c:968
+#: posix/regex.c:986
 msgid "Premature end of regular expression"
 msgstr "Fin prématurée de l'expression régulière."
 
@@ -1329,7 +1329,7 @@ msgstr "Le RTLD_NEXT utilisé dans le code n'est pas chargé dynamiquement."
 msgid "Read-only file system"
 msgstr "Système de fichiers accessible en lecture seulement."
 
-#: posix/regex.c:969
+#: posix/regex.c:987
 msgid "Regular expression too big"
 msgstr "Expression régulière trop grosse."
 
@@ -1346,8 +1346,8 @@ msgid "Remove password or make file unreadable by others."
 msgstr ""
 "Retirer le mot de passe ou rendre les fichiers illisibles par les autres."
 
-#: catgets/gencat.c:224 db/makedb.c:227 locale/programs/locale.c:257
-#: locale/programs/localedef.c:412
+#: catgets/gencat.c:224 db/makedb.c:227 locale/programs/locale.c:262
+#: locale/programs/localedef.c:415
 msgid "Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"
 msgstr ""
 "Rapporter toutes anomalies via le script `glibcbug' à l'adresse:\n"
@@ -1486,7 +1486,7 @@ msgstr "Erreur de relais de type streams."
 msgid "Structure needs cleaning"
 msgstr "La structure a besoin d'un nettoyage."
 
-#: nis/ypclnt.c:689 nis/ypclnt.c:763 posix/regex.c:954
+#: nis/ypclnt.c:689 nis/ypclnt.c:763 posix/regex.c:972
 #: stdio-common/../sysdeps/gnu/errlist.c:7
 msgid "Success"
 msgstr "Succès."
@@ -1570,7 +1570,7 @@ msgstr "Trappe de point d'arrêt lors de trace."
 msgid "Trace/breakpoint trap"
 msgstr "Trappe pour point d'arrêt et de trace."
 
-#: posix/regex.c:959
+#: posix/regex.c:977
 msgid "Trailing backslash"
 msgstr "Barre oblique en suffixe."
 
@@ -1595,8 +1595,8 @@ msgstr "Noeud final de transport déjà connecté."
 msgid "Transport endpoint is not connected"
 msgstr "Le noeud final de transport n'est pas connecté."
 
-#: catgets/gencat.c:208 db/makedb.c:209 locale/programs/locale.c:241
-#: locale/programs/localedef.c:393
+#: catgets/gencat.c:208 db/makedb.c:209 locale/programs/locale.c:246
+#: locale/programs/localedef.c:396
 #, c-format
 msgid "Try `%s --help' for more information.\n"
 msgstr "Pour en savoir davantage, faites: `%s --help'.\n"
@@ -1645,19 +1645,19 @@ msgstr "Erreur système inconnue."
 msgid "Unknown ypbind error"
 msgstr "Erreur inconnue de ypbind."
 
-#: posix/regex.c:962
+#: posix/regex.c:980
 msgid "Unmatched ( or \\("
 msgstr "Échec du pairage de ( ou de \\("
 
-#: posix/regex.c:970
+#: posix/regex.c:988
 msgid "Unmatched ) or \\)"
 msgstr "Échec du pairage de ) ou de \\)"
 
-#: posix/regex.c:961
+#: posix/regex.c:979
 msgid "Unmatched [ or [^"
 msgstr "Échec du pairage de [ ou de [^"
 
-#: posix/regex.c:963
+#: posix/regex.c:981
 msgid "Unmatched \\{"
 msgstr "Échec du pairage de \\{."
 
@@ -1677,7 +1677,8 @@ msgid ""
 "Usage: %s [OPTION]... -o OUTPUT-FILE [INPUT-FILE]...\n"
 "       %s [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]\n"
 "Mandatory arguments to long options are mandatory for short options too.\n"
-"  -H, --header        create C header file containing symbol definitions\n"
+"  -H, --header=NAME   create C header file NAME containing symbol "
+"definitions\n"
 "  -h, --help          display this help and exit\n"
 "      --new           do not use existing catalog, force new output file\n"
 "  -o, --output=NAME   write output to file NAME\n"
@@ -1729,7 +1730,7 @@ msgstr ""
 "  -V, --version        afficher le nom et la version du logiciel\n"
 "Si le FICHIER_D_ENTRÉE est -, la lecture se fait l'entrée standard.\n"
 
-#: locale/programs/localedef.c:397
+#: locale/programs/localedef.c:400
 #, c-format
 msgid ""
 "Usage: %s [OPTION]... name\n"
@@ -1767,7 +1768,7 @@ msgstr ""
 "Répertoire système des tables de caractères: %s\n"
 "                            fichiers locaux: %s\n"
 
-#: locale/programs/locale.c:245
+#: locale/programs/locale.c:250
 #, c-format
 msgid ""
 "Usage: %s [OPTION]... name\n"
@@ -1822,7 +1823,7 @@ msgstr "Valeur trop grande pour le type défini de données."
 msgid "Virtual timer expired"
 msgstr "Expiration de la minuterie virtuelle."
 
-#: time/zic.c:1871
+#: time/zic.c:1884
 msgid "Wild result from command execution"
 msgstr "Résultat anarchique résultant de l'exécution de la commande."
 
@@ -1831,7 +1832,7 @@ msgstr "Résultat anarchique résultant de l'exécution de la commande."
 msgid "Window changed"
 msgstr "La fenêtre a changée."
 
-#: catgets/gencat.c:174 db/makedb.c:125 locale/programs/locale.c:192
+#: catgets/gencat.c:174 db/makedb.c:125 locale/programs/locale.c:196
 #: locale/programs/localedef.c:185
 #, c-format
 msgid "Written by %s.\n"
@@ -1859,7 +1860,7 @@ msgstr "YPBINDPROC_DOMAIN: erreur inconnue.\n"
 msgid "You really blew it this time"
 msgstr "Vous avez vraiment tout gâcher cette fois-ci."
 
-#: time/zic.c:1048
+#: time/zic.c:1052
 msgid "Zone continuation line end time is not after end time of previous line"
 msgstr ""
 "Temps final de la ligne de la zone de continuation est antérieur\n"
@@ -1913,11 +1914,11 @@ msgstr "Mauvais propriétaire du fichier .rhosts."
 msgid "bad argument"
 msgstr "Mauvais paramètre."
 
-#: time/zic.c:1170
+#: time/zic.c:1174
 msgid "blank FROM field on Link line"
 msgstr "Champ `FROM' vide dans la ligne de type `Link'."
 
-#: time/zic.c:1174
+#: time/zic.c:1178
 msgid "blank TO field on Link line"
 msgstr "Champ `TO' vide dans la ligne de type `Link'."
 
@@ -1941,7 +1942,7 @@ msgstr "Diffusion: ioctl (a obtenu la valeur des fanions de l'interface)"
 msgid "cache_set: victim not found"
 msgstr "cache_set: victime non repérée."
 
-#: time/zic.c:1698
+#: time/zic.c:1711
 msgid "can't determine time zone abbreviation to use just after until time"
 msgstr ""
 "Ne peut déterminer l'abréviation du fuseau horaire à utiliser\n"
@@ -1952,7 +1953,7 @@ msgstr ""
 msgid "can't reassign procedure number %d\n"
 msgstr "Ne peut réassigner le numéro de procédure %d.\n"
 
-#: locale/programs/localedef.c:291
+#: locale/programs/localedef.c:294
 #, c-format
 msgid "cannot `stat' locale file `%s'"
 msgstr "Ne peut effectuer l'évaluation `stat' du fichier local `%s'."
@@ -1992,7 +1993,7 @@ msgstr "Ne peut ouvrir le fichier des localisations `%s'."
 msgid "cannot open output file `%s'"
 msgstr "Ne peut ouvrir le fichier de sortie `%s'."
 
-#: locale/programs/locfile.c:1008
+#: locale/programs/locfile.c:1020
 #, c-format
 msgid "cannot open output file `%s' for category `%s'"
 msgstr "Ne peut ouvrir le fichier de sortie `%s' de catégorie `%s'."
@@ -2001,27 +2002,27 @@ msgstr "Ne peut ouvrir le fichier de sortie `%s' de catégorie `%s'."
 msgid "cannot process order specification"
 msgstr "Ne peut traiter la spécification d'ordonnancement."
 
-#: locale/programs/locale.c:304
+#: locale/programs/locale.c:444
 #, c-format
 msgid "cannot read character map directory `%s'"
 msgstr "Ne peut lire via le répertoire de la table des caractères `%s'."
 
-#: locale/programs/locale.c:279
+#: locale/programs/locale.c:301
 #, c-format
 msgid "cannot read locale directory `%s'"
 msgstr "Ne peut lire via le répertoire des définitions localisées `%s'."
 
-#: locale/programs/localedef.c:313
+#: locale/programs/localedef.c:316
 #, c-format
 msgid "cannot read locale file `%s'"
 msgstr "Ne peut lire le fichier des définitions localisées `%s'."
 
-#: locale/programs/localedef.c:338
+#: locale/programs/localedef.c:341
 #, c-format
 msgid "cannot write output files to `%s'"
 msgstr "Ne peut écrire dans les fichiers de sortie vers `%s'."
 
-#: locale/programs/localedef.c:381
+#: locale/programs/localedef.c:384
 msgid "category data requested more than once: should not happen"
 msgstr ""
 "Catégorie de données requises plus d'une fois: n'aurait pas dû se produire."
@@ -2146,7 +2147,7 @@ msgstr "Duplicité de clé."
 msgid "duplicate set definition"
 msgstr "Duplicité de la définition d'ensemble."
 
-#: time/zic.c:963
+#: time/zic.c:967
 #, c-format
 msgid "duplicate zone name %s (file \"%s\", line %d)"
 msgstr "Duplicité du nom de zone  %s (fichier \"%s\", ligne %d)."
@@ -2197,11 +2198,11 @@ msgstr "Erreur lors de l'insertion dans la table de hachage."
 msgid "expect string argument for `copy'"
 msgstr "Chaîne attendue pour le paramètre de `copy'."
 
-#: time/zic.c:854
+#: time/zic.c:858
 msgid "expected continuation line not found"
 msgstr "Ligne de continuation attendue, non repérée."
 
-#: locale/programs/locfile.c:1032
+#: locale/programs/locfile.c:1044
 #, c-format
 msgid "failure while writing data for category `%s'"
 msgstr "Échec durant l'écriture des données de catégorie `%s'."
@@ -2260,11 +2261,11 @@ msgstr ""
 msgid "get_myaddress: ioctl (get interface configuration)"
 msgstr "get_myaddress: ioctl (a obtenu la configuration de l'interface)."
 
-#: time/zic.c:1147
+#: time/zic.c:1151
 msgid "illegal CORRECTION field on Leap line"
 msgstr "CORRECTION illégale du champ dans la ligne de type `Leap'."
 
-#: time/zic.c:1151
+#: time/zic.c:1155
 msgid "illegal Rolling/Stationary field on Leap line"
 msgstr "Champ `Rolling/Stationary' illégal sur la ligne de type `Leap'."
 
@@ -2333,19 +2334,19 @@ msgstr ""
 msgid "incorrectly formatted file"
 msgstr "Fichier incorrectement formaté."
 
-#: time/zic.c:811
+#: time/zic.c:815
 msgid "input line of unknown type"
 msgstr "Ligne d'entrée de type inconnu."
 
-#: time/zic.c:1760
+#: time/zic.c:1773
 msgid "internal error - addtype called with bad isdst"
 msgstr "Erreur interne - addtype appellé avec un mauvais bloc isdst."
 
-#: time/zic.c:1768
+#: time/zic.c:1781
 msgid "internal error - addtype called with bad ttisgmt"
 msgstr "Erreur interne - addtype appellé avec un mauvais bloc ttisgmt."
 
-#: time/zic.c:1764
+#: time/zic.c:1777
 msgid "internal error - addtype called with bad ttisstd"
 msgstr "Erreur interne - addtype appellé avec un mauvais bloc ttisstd."
 
@@ -2354,43 +2355,43 @@ msgstr "Erreur interne - addtype appellé avec un mauvais bloc ttisstd."
 msgid "internal error in %s, line %u"
 msgstr "Erreur interne dans %s, ligne %u."
 
-#: time/zic.c:1019
+#: time/zic.c:1023
 msgid "invalid GMT offset"
 msgstr "Décalage relatif GMT invalide."
 
-#: time/zic.c:1022
+#: time/zic.c:1026
 msgid "invalid abbreviation format"
 msgstr "Format d'abréviation invalide."
 
-#: time/zic.c:1112 time/zic.c:1313 time/zic.c:1327
+#: time/zic.c:1116 time/zic.c:1326 time/zic.c:1340
 msgid "invalid day of month"
 msgstr "Jour du mois invalide."
 
-#: time/zic.c:1270
+#: time/zic.c:1279
 msgid "invalid ending year"
 msgstr "Année finale invalide."
 
-#: time/zic.c:1084
+#: time/zic.c:1088
 msgid "invalid leaping year"
 msgstr "Année bissextile invalide."
 
-#: time/zic.c:1099 time/zic.c:1202
+#: time/zic.c:1103 time/zic.c:1206
 msgid "invalid month name"
 msgstr "Nom de mois invalide."
 
-#: time/zic.c:918
+#: time/zic.c:922
 msgid "invalid saved time"
 msgstr "Temps sauvegardé invalide."
 
-#: time/zic.c:1250
+#: time/zic.c:1255
 msgid "invalid starting year"
 msgstr "Année initiale invalide."
 
-#: time/zic.c:1128 time/zic.c:1230
+#: time/zic.c:1132 time/zic.c:1235
 msgid "invalid time of day"
 msgstr "Heure du jour invalide."
 
-#: time/zic.c:1318
+#: time/zic.c:1331
 msgid "invalid weekday name"
 msgstr "Nom du jour de semaine invalide."
 
@@ -2404,11 +2405,11 @@ msgstr ""
 "La ligne avant l'ellipse ne doit pas contenir la définition d'une constante "
 "de caractères."
 
-#: time/zic.c:791
+#: time/zic.c:795
 msgid "line too long"
 msgstr "Ligne trop longue."
 
-#: locale/programs/localedef.c:285
+#: locale/programs/localedef.c:288
 #, c-format
 msgid "locale file `%s', used in `copy' statement, not found"
 msgstr ""
@@ -2428,12 +2429,12 @@ msgstr "Mémoire écrasée après la fin du bloc alloué."
 
 #: locale/programs/ld-collate.c:167 locale/programs/ld-collate.c:173
 #: locale/programs/ld-collate.c:177 locale/programs/ld-collate.c:1442
-#: locale/programs/ld-collate.c:1471 locale/programs/locfile.c:962
+#: locale/programs/ld-collate.c:1471 locale/programs/locfile.c:974
 #: locale/programs/xmalloc.c:68 posix/getconf.c:250
 msgid "memory exhausted"
 msgstr "Mémoire épuisée."
 
-#: malloc/obstack.c:462
+#: malloc/obstack.c:466
 msgid "memory exhausted\n"
 msgstr "Mémoire épuisée.\n"
 
@@ -2453,7 +2454,7 @@ msgstr ""
 msgid "missing era name in string %d in `era' field in category `%s'"
 msgstr "Nom manquant dans la chaîne %d du champ `era' de catégorie `%s'."
 
-#: time/zic.c:913
+#: time/zic.c:917
 msgid "nameless rule"
 msgstr "Règle sans nom."
 
@@ -2467,7 +2468,7 @@ msgstr "Le programme %d n'a jamais été enregistré.\n"
 msgid "no correct regular expression for field `%s' in category `%s': %s"
 msgstr "Expression reguliere incorrecte du champ `%s' de catégorie `%s': %s"
 
-#: time/zic.c:2086
+#: time/zic.c:2099
 msgid "no day in month matches rule"
 msgstr "Pas de jour dans les règles de concordance."
 
@@ -2479,7 +2480,7 @@ msgstr "Pas de définition de type `UNDEFINED'."
 msgid "no other keyword shall be specified when `copy' is used"
 msgstr "Aucun autre mot clé ne doit être spécifié lorsque `copy' est utilisé."
 
-#: locale/programs/localedef.c:344
+#: locale/programs/localedef.c:347
 msgid "no output file produced because warning were issued"
 msgstr "Aucun fichier de sortie généré en raison d'un avertissement déjà émis."
 
@@ -2543,7 +2544,7 @@ msgstr "rcmd: écriture (configuration de stderr): %m.\n"
 msgid "registerrpc: out of memory\n"
 msgstr "registerrpc: mémoire épuisée.\n"
 
-#: time/zic.c:1821
+#: time/zic.c:1834
 msgid "repeated leap second moment"
 msgstr "Répétition du délai une seconde fois."
 
@@ -2576,7 +2577,7 @@ msgstr "rpcinfo: ne peut contacter le convertisseur de ports."
 msgid "rpcinfo: can't contact portmapper: "
 msgstr "rpcinfo: ne peut contacter le convertisseur de ports."
 
-#: time/zic.c:704 time/zic.c:706
+#: time/zic.c:708 time/zic.c:710
 msgid "same rule name in multiple files"
 msgstr "Même nom de règle dans plusieurs fichiers."
 
@@ -2600,7 +2601,7 @@ msgstr ""
 "La spécification de tri par le poids des symboles de\n"
 "fusionnement n'a aucun sens."
 
-#: time/zic.c:775
+#: time/zic.c:779
 msgid "standard input"
 msgstr "entrée standard"
 
@@ -2615,10 +2616,18 @@ msgstr ""
 "Date initiale illégale dans la chaîne %d du champ `era'\n"
 "de catégorie `%s'."
 
-#: time/zic.c:1274
+#: time/zic.c:1287
 msgid "starting year greater than ending year"
 msgstr "Année initiale plus grande que l'année finale."
 
+#: time/zic.c:1261 time/zic.c:1285
+msgid "starting year too high to be represented"
+msgstr "Année de départ trop grance pour être représentée."
+
+#: time/zic.c:1259 time/zic.c:1283
+msgid "starting year too low to be represented"
+msgstr "Année de départ trop petite pour être représentée"
+
 #: locale/programs/ld-time.c:330
 #, c-format
 msgid "stopping date is illegal in string %d in `era' field in category `%s'"
@@ -2626,6 +2635,10 @@ msgstr ""
 "Date finale illégale dans la chaîne %d du champ `era'\\n\"\n"
 "de catégorie `%s'."
 
+#: sunrpc/svc_run.c:81
+msgid "svc_run: - select failed"
+msgstr "svc_run: - échec de sélection"
+
 #: sunrpc/svc_tcp.c:201 sunrpc/svc_tcp.c:206
 msgid "svc_tcp: makefd_xprt: out of memory\n"
 msgstr "svc_tcp: makefd_xprt: mémoire épuisée.\n"
@@ -2777,11 +2790,11 @@ msgstr "Ceci est la première définition."
 
 # time/zic.c:1120A
 # mro: à investiguer dans le code source
-#: time/zic.c:1117
+#: time/zic.c:1121
 msgid "time before zero"
 msgstr "Temps défini avant le zéro."
 
-#: time/zic.c:1125 time/zic.c:1986 time/zic.c:2005
+#: time/zic.c:1129 time/zic.c:1999 time/zic.c:2018
 msgid "time overflow"
 msgstr "Débordement du temps alloué."
 
@@ -2797,15 +2810,15 @@ msgstr "Trop d'octets pour l'encodage des caractères."
 msgid "too many character classes defined"
 msgstr "Trop de définitions de classes de caractères."
 
-#: time/zic.c:1815
+#: time/zic.c:1828
 msgid "too many leap seconds"
 msgstr "Trop de délai en secondes."
 
-#: time/zic.c:1787
+#: time/zic.c:1800
 msgid "too many local time types"
 msgstr "Trop de types localisés pour la représentation du temps."
 
-#: time/zic.c:1741
+#: time/zic.c:1754
 msgid "too many transitions?!"
 msgstr "Trop de transitions définies?!"
 
@@ -2813,7 +2826,7 @@ msgstr "Trop de transitions définies?!"
 msgid "too many weights"
 msgstr "Trop de poids définis."
 
-#: time/zic.c:2109
+#: time/zic.c:2122
 msgid "too many, or too long, time zone abbreviations"
 msgstr "Trop ou de trop longues abréviations de fuseaux horaires."
 
@@ -2830,7 +2843,7 @@ msgstr "Problème à répondre au programme %d.\n"
 msgid "two lines in a row containing `...' are not allowed"
 msgstr "Deux lignes consécutives contenant `...' ne sont pas permises."
 
-#: time/zic.c:1281
+#: time/zic.c:1294
 msgid "typed single year"
 msgstr "Une seule année fournie."
 
@@ -2870,7 +2883,7 @@ msgstr "Ensemble inconnu `%s'."
 msgid "unknown symbol `%.*s': line ignored"
 msgstr "Symbole inconnu `%.*s': ligne ignorée."
 
-#: time/zic.c:747
+#: time/zic.c:751
 msgid "unruly zone"
 msgstr "Zone sans règle."
 
@@ -2893,10 +2906,10 @@ msgstr "Nom de poids incomplet."
 #: locale/programs/charset.c:119
 msgid "upper limit in range is not smaller then lower limit"
 msgstr ""
-"Limite supérieure de l'intervalle n'est pas plus petite que la limite "
-"inférieure."
+"Limite supérieure de l'intervalle n'est pas plus petite que\n"
+"la limite inférieure."
 
-#: time/zic.c:2052
+#: time/zic.c:2065
 msgid "use of 2/29 in non leap-year"
 msgstr "Utiliser 2/29 pour les années non-bissextiles."
 
@@ -2919,7 +2932,7 @@ msgstr ""
 #: locale/programs/charmap.c:245
 msgid "value of <mb_cur_max> must be greater than the value of <mb_cur_min>"
 msgstr ""
-"La valeur de <mb_cur_max> doit être plus grande que la valeur de "
+"La valeur de <mb_cur_max> doit être plus grande que la valeur de\n"
 "<mb_cur_min>."
 
 #: locale/programs/ld-monetary.c:139
@@ -2949,7 +2962,7 @@ msgid "values for field `%s' in category `%s' must not be zero"
 msgstr ""
 "Les valeurs du champ `%s' de catégorie `%s' ne doivent pas être égal à zéro."
 
-#: login/utmp_file.c:84
+#: login/utmp_file.c:76
 msgid "while opening UTMP file"
 msgstr "durant l'ouverture du fichier UTMP."
 
@@ -2957,6 +2970,11 @@ msgstr "durant l'ouverture du fichier UTMP."
 msgid "while opening old catalog file"
 msgstr "durant l'ouverture du vieux fichier du catalogue."
 
+#: locale/programs/locale.c:341
+#, 
+msgid "while preparing output"
+msgstr "durant la préparation de la sortie"
+
 #: db/makedb.c:354
 msgid "while reading database"
 msgstr "durant la lecture de la base de données."
@@ -2969,23 +2987,23 @@ msgstr "durant l'écriture dans le fichier de la base de données."
 msgid "wrong number of arguments"
 msgstr "Mauvais nombre de paramètres."
 
-#: time/zic.c:1075
+#: time/zic.c:1079
 msgid "wrong number of fields on Leap line"
 msgstr "Mauvais nombre de champs sur la ligne de type `Leap'."
 
-#: time/zic.c:1166
+#: time/zic.c:1170
 msgid "wrong number of fields on Link line"
 msgstr "Mauvais nombre de champs sur la ligne de type `Link'."
 
-#: time/zic.c:909
+#: time/zic.c:913
 msgid "wrong number of fields on Rule line"
 msgstr "Mauvais nombre de champs sur la ligne de type `Rule'."
 
-#: time/zic.c:979
+#: time/zic.c:983
 msgid "wrong number of fields on Zone continuation line"
 msgstr "Mauvais nombre de champs sur la ligne de type continuation de `Zone'."
 
-#: time/zic.c:937
+#: time/zic.c:941
 msgid "wrong number of fields on Zone line"
 msgstr "Mauvais nombre de champs sur la ligne de type `Zone'."
 
@@ -2997,27 +3015,3 @@ msgstr ""
 #: nis/ypclnt.c:823
 msgid "yp_update: cannot get server address\n"
 msgstr "yp_update: ne peut obtenir l'adresse du serveur.\n"
-
-#~ msgid "unknown signal"
-#~ msgstr "Signal inconnu."
-
-#~ msgid "yp_all: clnttcp_create failed"
-#~ msgstr "yp_all: échec de la fonction clnttcp_create()."
-
-#~ msgid "character `%c' not defined while needed as default value"
-#~ msgstr "Caractère `%c' non défini alors qu'attendu comme valeur par défaut."
-
-#~ msgid "couldn't do tcp_create\n"
-#~ msgstr "Ne peut exécuter tcp_create.\n"
-
-#~ msgid "couldn't do udp_create\n"
-#~ msgstr "Ne peut exécuter udp_create.\n"
-
-#~ msgid "portmap CALLIT: cannot fork.\n"
-#~ msgstr "portmap CALLIT: ne peut procéder à un clonage de type fork.\n"
-
-#~ msgid "portmap cannot create socket"
-#~ msgstr "portmap ne créer un socket"
-
-#~ msgid "run_svc returned unexpectedly\n"
-#~ msgstr "run_svc a retourné de façon imprévue.\n"
diff --git a/string/Makefile b/string/Makefile
index b0200e5d4f..1a1b269845 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -51,8 +51,6 @@ include ../Rules
 tester-ENV = LANGUAGE=C
 inl-tester-ENV = LANGUAGE=C
 noinl-tester-ENV = LANGUAGE=C
-CFLAGS-tester.c = -fno-builtin
-CFLAGS-inl-tester.c = -fno-builtin
 CFLAGS-noinl-tester.c = -fno-builtin
 CFLAGS-tst-strlen.c = -fno-builtin
 CFLAGS-stratcliff.c = -fno-builtin
diff --git a/string/bits/string2.h b/string/bits/string2.h
index 51255aaf4c..8555d677ab 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -226,8 +226,9 @@ __STRING2_COPY_TYPE (8);
 			++__dest;					      \
 			break;						      \
 		      case 3:						      \
-			*((__uint16_t *) __dest)++ =			      \
+			*((__uint16_t *) __dest) =			      \
 			  __STRING2_SMALL_GET16 (src, 0);		      \
+			__dest += sizeof (__uint16_t);			      \
 			*__dest = '\0';					      \
 			break;						      \
 		      case 4:						      \
@@ -236,8 +237,9 @@ __STRING2_COPY_TYPE (8);
 			__dest += 3;					      \
 			break;						      \
 		      case 5:						      \
-			*((__uint32_t *) __dest)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
+			__dest += sizeof (__uint32_t);			      \
 			*__dest = '\0';					      \
 			break;						      \
 		      case 6:						      \
diff --git a/string/tester.c b/string/tester.c
index ee36e12a6d..5b7b2f97f9 100644
--- a/string/tester.c
+++ b/string/tester.c
@@ -56,20 +56,19 @@ check (int thing, int number)
 }
 
 /* Complain if first two args don't strcmp as equal.  */
-void equal (const char *a, const char *b, int number)
+void
+equal (const char *a, const char *b, int number)
 {
   check(a != NULL && b != NULL && STREQ (a, b), number);
 }
 
 char one[50];
 char two[50];
+char *cp;
 
-int
-main (void)
+void
+test_strcmp (void)
 {
-  char *cp;
-
-  /* Test strcmp first because we use it to test other things.  */
   it = "strcmp";
   check (strcmp ("", "") == 0, 1);		/* Trivial case. */
   check (strcmp ("a", "a") == 0, 2);		/* Identity. */
@@ -115,8 +114,11 @@ main (void)
 	    }
 	}
   }
+}
 
-  /* Test strcpy next because we need it to set up other tests.  */
+void
+test_strcpy (void)
+{
   it = "strcpy";
   check (strcpy (one, "abcd") == one, 1); /* Returned value. */
   equal (one, "abcd", 2);		/* Basic test. */
@@ -132,8 +134,11 @@ main (void)
 
   (void) strcpy (one, "");
   equal (one, "", 7);			/* Boundary condition. */
+}
 
-  /* A closely related function is stpcpy.  */
+void
+test_stpcpy (void)
+{
   it = "stpcpy";
   check ((stpcpy (one, "a") - one) == 1, 1);
   equal (one, "a", 2);
@@ -193,10 +198,12 @@ main (void)
   check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
   equal (one, "abc", 41);
   equal (one + 4, "xxx", 42);
+}
 
-  /* stpncpy.  */
+void
+test_stpncpy (void)
+{
   it = "stpncpy";
-
   memset (one, 'x', sizeof (one));
   check (stpncpy (one, "abc", 2) == one + 2, 1);
   check (stpncpy (one, "abc", 3) == one + 3, 2);
@@ -206,8 +213,11 @@ main (void)
   check (one[4] == '\0' && one[5] == 'x', 6);
   check (stpncpy (one, "abcd", 6) == one + 4, 7);
   check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
+}
 
-  /* strcat.  */
+void
+test_strcat (void)
+{
   it = "strcat";
   (void) strcpy (one, "ijk");
   check (strcat (one, "lmn") == one, 1); /* Returned value. */
@@ -233,9 +243,13 @@ main (void)
   (void) strcpy (one, "");
   (void) strcat (one, "cd");
   equal (one, "cd", 9);
+}
 
-  /* strncat - first test it as strcat, with big counts,
-     then test the count mechanism.  */
+void
+test_strncat (void)
+{
+  /* First test it as strcat, with big counts, then test the count
+     mechanism.  */
   it = "strncat";
   (void) strcpy (one, "ijk");
   check (strncat (one, "lmn", 99) == one, 1);	/* Returned value. */
@@ -271,9 +285,12 @@ main (void)
 
   (void) strncat (one, "gh", 2);
   equal (one, "abcdgh", 12);		/* Count and length equal. */
+}
 
-  /* strncmp - first test as strcmp with big counts,
-     then test count code.  */
+void
+test_strncmp (void)
+{
+  /* First test as strcmp with big counts, then test count code.  */
   it = "strncmp";
   check (strncmp ("", "", 99) == 0, 1);	/* Trivial case. */
   check (strncmp ("a", "a", 99) == 0, 2);	/* Identity. */
@@ -288,8 +305,12 @@ main (void)
   check (strncmp ("abce", "abc", 3) == 0, 11);	/* Count == length. */
   check (strncmp ("abcd", "abce", 4) < 0, 12);	/* Nudging limit. */
   check (strncmp ("abc", "def", 0) == 0, 13);	/* Zero count. */
+}
 
-  /* strncpy - testing is a bit different because of odd semantics.  */
+void
+test_strncpy (void)
+{
+  /* Testing is a bit different because of odd semantics.  */
   it = "strncpy";
   check (strncpy (one, "abc", 4) == one, 1);	/* Returned value. */
   equal (one, "abc", 2);			/* Did the copy go right? */
@@ -326,8 +347,11 @@ main (void)
   (void) strncpy (two, one, 9);
   equal (two, "hi there", 14);		/* Just paranoia. */
   equal (one, "hi there", 15);		/* Stomped on source? */
+}
 
-  /* strlen.  */
+void
+test_strlen (void)
+{
   it = "strlen";
   check (strlen ("") == 0, 1);		/* Empty. */
   check (strlen ("a") == 1, 2);		/* Single char. */
@@ -344,8 +368,11 @@ main (void)
 	check (strlen (p) == 2, 4+i);
       }
    }
+}
 
-  /* strchr.  */
+void
+test_strchr (void)
+{
   it = "strchr";
   check (strchr ("abcd", 'z') == NULL, 1);	/* Not found. */
   (void) strcpy (one, "abcd");
@@ -370,9 +397,11 @@ main (void)
 	check (strchr (p, '/') == NULL, 9+i);
       }
    }
+}
 
-#if 0
-  /* index - just like strchr.  */
+void
+test_index (void)
+{
   it = "index";
   check (index ("abcd", 'z') == NULL, 1);	/* Not found. */
   (void) strcpy (one, "abcd");
@@ -385,9 +414,11 @@ main (void)
   (void) strcpy (one, "");
   check (index (one, 'b') == NULL, 7);	/* Empty string. */
   check (index (one, '\0') == one, 8);	/* NUL in empty string. */
-#endif
+}
 
-  /* strrchr.  */
+void
+test_strrchr (void)
+{
   it = "strrchr";
   check (strrchr ("abcd", 'z') == NULL, 1);	/* Not found. */
   (void) strcpy (one, "abcd");
@@ -412,9 +443,11 @@ main (void)
 	check (strrchr (p, '/') == NULL, 9+i);
       }
    }
+}
 
-#if 0
-  /* rindex - just like strrchr.  */
+void
+test_rindex (void)
+{
   it = "rindex";
   check (rindex ("abcd", 'z') == NULL, 1);	/* Not found. */
   (void) strcpy (one, "abcd");
@@ -427,9 +460,11 @@ main (void)
   (void) strcpy (one, "");
   check (rindex (one, 'b') == NULL, 7);	/* Empty string. */
   check (rindex (one, '\0') == one, 8);	/* NUL in empty string. */
-#endif
+}
 
-  /* strpbrk - somewhat like strchr.  */
+void
+test_strpbrk (void)
+{
   it = "strpbrk";
   check(strpbrk("abcd", "z") == NULL, 1);	/* Not found. */
   (void) strcpy(one, "abcd");
@@ -445,8 +480,11 @@ main (void)
   (void) strcpy(one, "");
   check(strpbrk(one, "bc") == NULL, 10);	/* Empty string. */
   check(strpbrk(one, "") == NULL, 11);	/* Both strings empty. */
+}
 
-  /* strstr - somewhat like strchr.  */
+void
+test_strstr (void)
+{
   it = "strstr";
   check(strstr("abcd", "z") == NULL, 1);	/* Not found. */
   check(strstr("abcd", "abx") == NULL, 2);	/* Dead end. */
@@ -469,24 +507,33 @@ main (void)
   check(strstr(one, "bca") == one+2, 15);	/* False start. */
   (void) strcpy(one, "bbbcabbca");
   check(strstr(one, "bbca") == one+1, 16);	/* With overlap. */
+}
 
-  /* strspn.  */
+void
+test_strspn (void)
+{
   it = "strspn";
   check(strspn("abcba", "abc") == 5, 1);	/* Whole string. */
   check(strspn("abcba", "ab") == 2, 2);	/* Partial. */
   check(strspn("abc", "qx") == 0, 3);	/* None. */
   check(strspn("", "ab") == 0, 4);	/* Null string. */
   check(strspn("abc", "") == 0, 5);	/* Null search list. */
+}
 
-  /* strcspn.  */
+void
+test_strcspn (void)
+{
   it = "strcspn";
   check(strcspn("abcba", "qx") == 5, 1);	/* Whole string. */
   check(strcspn("abcba", "cx") == 2, 2);	/* Partial. */
   check(strcspn("abc", "abc") == 0, 3);	/* None. */
   check(strcspn("", "ab") == 0, 4);	/* Null string. */
   check(strcspn("abc", "") == 3, 5);	/* Null search list. */
+}
 
-  /* strtok - the hard one.  */
+void
+test_strtok (void)
+{
   it = "strtok";
   (void) strcpy(one, "first, second, third");
   equal(strtok(one, ", "), "first", 1);	/* Basic test. */
@@ -532,8 +579,11 @@ main (void)
   equal(one, "a", 31);			/* Stomped old tokens? */
   equal(one+2, "b", 32);
   equal(one+4, "c", 33);
+}
 
-  /* strtok_r.  */
+void
+test_strtok_r (void)
+{
   it = "strtok_r";
   (void) strcpy(one, "first, second, third");
   equal(strtok_r(one, ", ", &cp), "first", 1);	/* Basic test. */
@@ -579,8 +629,11 @@ main (void)
   equal(one, "a", 31);			/* Stomped old tokens? */
   equal(one+2, "b", 32);
   equal(one+4, "c", 33);
+}
 
-  /* strsep.  */
+void
+test_strsep (void)
+{
   it = "strsep";
   cp = strcpy(one, "first, second, third");
   equal(strsep(&cp, ", "), "first", 1);	/* Basic test. */
@@ -640,7 +693,21 @@ main (void)
   equal(one+2, "b", 45);
   equal(one+4, "c", 46);
 
-  /* memcmp.  */
+  {
+    char text[] = "This,is,a,test";
+    char *list = text;
+    it = "strsep";
+    check (!strcmp ("This", strsep (&list, ",")), 1);
+    check (!strcmp ("is", strsep (&list, ",")), 2);
+    check (!strcmp ("a", strsep (&list, ",")), 3);
+    check (!strcmp ("test", strsep (&list, ",")), 4);
+    check (strsep (&list, ",") == NULL, 5);
+  }
+}
+
+void
+test_memcmp (void)
+{
   it = "memcmp";
   check(memcmp("a", "a", 1) == 0, 1);		/* Identity. */
   check(memcmp("abc", "abc", 3) == 0, 2);	/* Multicharacter. */
@@ -650,8 +717,11 @@ main (void)
   check(memcmp("a\203", "a\003", 2) > 0, 6);
   check(memcmp("abce", "abcd", 3) == 0, 7);	/* Count limited. */
   check(memcmp("abc", "def", 0) == 0, 8);	/* Zero count. */
+}
 
-  /* memchr.  */
+void
+test_memchr (void)
+{
   it = "memchr";
   check(memchr("abcd", 'z', 4) == NULL, 1);	/* Not found. */
   (void) strcpy(one, "abcd");
@@ -690,8 +760,11 @@ main (void)
       }
     }
   }
+}
 
-  /* memcpy - need not work for overlap.  */
+void
+test_memcpy (void)
+{
   it = "memcpy";
   check(memcpy(one, "abc", 4) == one, 1);	/* Returned value. */
   equal(one, "abc", 2);			/* Did the copy go right? */
@@ -709,8 +782,11 @@ main (void)
   (void) memcpy(two, one, 9);
   equal(two, "hi there", 5);		/* Just paranoia. */
   equal(one, "hi there", 6);		/* Stomped on source? */
+}
 
-  /* memmove - must work on overlap.  */
+void
+test_memmove (void)
+{
   it = "memmove";
   check(memmove(one, "abc", 4) == one, 1);	/* Returned value. */
   equal(one, "abc", 2);			/* Did the copy go right? */
@@ -740,11 +816,15 @@ main (void)
   (void) strcpy(one, "abcdefgh");
   (void) memmove(one, one, 9);
   equal(one, "abcdefgh", 9);		/* 100% overlap. */
+}
 
-  /* memccpy - first test like memcpy, then the search part
-     The SVID, the only place where memccpy is mentioned, says
-     overlap might fail, so we don't try it.  Besides, it's hard
-     to see the rationale for a non-left-to-right memccpy.  */
+void
+test_memccpy (void)
+{
+  /* First test like memcpy, then the search part The SVID, the only
+     place where memccpy is mentioned, says overlap might fail, so we
+     don't try it.  Besides, it's hard to see the rationale for a
+     non-left-to-right memccpy.  */
   it = "memccpy";
   check(memccpy(one, "abc", 'q', 4) == NULL, 1);	/* Returned value. */
   equal(one, "abc", 2);			/* Did the copy go right? */
@@ -778,8 +858,11 @@ main (void)
   (void) strcpy(one, "xyz");
   check(memccpy(two, one, 'x', 1) == two+1, 14);	/* Singleton. */
   equal(two, "xbcdlebee", 15);
+}
 
-  /* memset.  */
+void
+test_memset (void)
+{
   it = "memset";
   (void) strcpy(one, "abcdefgh");
   check(memset(one+1, 'x', 3) == one+1, 1);	/* Return value. */
@@ -831,9 +914,13 @@ main (void)
 	    check(0,7+i+j*256+(c != 0)*256*256);
 	  }
   }
+}
 
-  /* bcopy - much like memcpy.
-     Berklix manual is silent about overlap, so don't test it.  */
+void
+test_bcopy (void)
+{
+  /* Much like memcpy.  Berklix manual is silent about overlap, so
+     don't test it.  */
   it = "bcopy";
   (void) bcopy("abc", one, 4);
   equal(one, "abc", 1);			/* Simple copy. */
@@ -851,8 +938,11 @@ main (void)
   (void) bcopy(one, two, 9);
   equal(two, "hi there", 4);		/* Just paranoia. */
   equal(one, "hi there", 5);		/* Stomped on source? */
+}
 
-  /* bzero.  */
+void
+test_bzero (void)
+{
   it = "bzero";
   (void) strcpy(one, "abcdef");
   bzero(one+2, 2);
@@ -863,9 +953,11 @@ main (void)
   (void) strcpy(one, "abcdef");
   bzero(one+2, 0);
   equal(one, "abcdef", 4);		/* Zero-length copy. */
+}
 
-#if 0
-  /* bcmp - somewhat like memcmp.  */
+void
+test_bcmp (void)
+{
   it = "bcmp";
   check(bcmp("a", "a", 1) == 0, 1);	/* Identity. */
   check(bcmp("abc", "abc", 3) == 0, 2);	/* Multicharacter. */
@@ -874,40 +966,123 @@ main (void)
   check(bcmp("alph", "beta", 4) != 0, 5);
   check(bcmp("abce", "abcd", 3) == 0, 6);	/* Count limited. */
   check(bcmp("abc", "def", 0) == 0, 8);	/* Zero count. */
-#endif
+}
 
-  {
-    char text[] = "This,is,a,test";
-    char *list = text;
-    it = "strsep";
-    check (!strcmp ("This", strsep (&list, ",")), 1);
-    check (!strcmp ("is", strsep (&list, ",")), 2);
-    check (!strcmp ("a", strsep (&list, ",")), 3);
-    check (!strcmp ("test", strsep (&list, ",")), 4);
-    check (strsep (&list, ",") == NULL, 5);
-  }
+void
+test_strerror (void)
+{
+  int f;
+  it = "strerror";
+  f = __open("/", O_WRONLY);	/* Should always fail. */
+  check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
+  equal(strerror(errno), _sys_errlist[errno], 2);
+}
+
+int
+main (void)
+{
+  int status;
+
+  /* Test strcmp first because we use it to test other things.  */
+  test_strcmp ();
+
+  /* Test strcpy next because we need it to set up other tests.  */
+  test_strcpy ();
+
+  /* A closely related function is stpcpy.  */
+  test_stpcpy ();
+
+  /* stpncpy.  */
+  test_stpncpy ();
+
+  /* strcat.  */
+  test_strcat ();
+
+  /* strncat.  */
+  test_strncat ();
+
+  /* strncmp.  */
+  test_strncmp ();
+
+  /* strncpy.  */
+  test_strncpy ();
+
+  /* strlen.  */
+  test_strlen ();
+
+  /* strchr.  */
+  test_strchr ();
+
+  /* index - just like strchr.  */
+  test_index ();
+
+  /* strrchr.  */
+  test_strrchr ();
+
+  /* rindex - just like strrchr.  */
+  test_rindex ();
+
+  /* strpbrk - somewhat like strchr.  */
+  test_strpbrk ();
+
+  /* strstr - somewhat like strchr.  */
+  test_strstr ();
+
+  /* strspn.  */
+  test_strspn ();
+
+  /* strcspn.  */
+  test_strcspn ();
+
+  /* strtok - the hard one.  */
+  test_strtok ();
+
+  /* strtok_r.  */
+  test_strtok_r ();
+
+  /* strsep.  */
+  test_strsep ();
+
+  /* memcmp.  */
+  test_memcmp ();
+
+  /* memchr.  */
+  test_memchr ();
+
+  /* memcpy - need not work for overlap.  */
+  test_memcpy ();
+
+  /* memmove - must work on overlap.  */
+  test_memmove ();
+
+  /* memccpy.  */
+  test_memccpy ();
+
+  /* memset.  */
+  test_memset ();
+
+  /* bcopy.  */
+  test_bcopy ();
+
+  /* bzero.  */
+  test_bzero ();
+
+  /* bcmp - somewhat like memcmp.  */
+  test_bcmp ();
 
   /* strerror - VERY system-dependent.  */
-  {
-    int f;
-    it = "strerror";
-    f = __open("/", O_WRONLY);	/* Should always fail. */
-    check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
-    equal(strerror(errno), _sys_errlist[errno], 2);
-  }
+  test_strerror ();
 
-  {
-    int status;
-    if (errors == 0)
-      {
-	status = EXIT_SUCCESS;
-	puts("No errors.");
-      }
-    else
-      {
-	status = EXIT_FAILURE;
-	printf("%Zd errors.\n", errors);
-      }
-    exit(status);
-  }
+
+  if (errors == 0)
+    {
+      status = EXIT_SUCCESS;
+      puts("No errors.");
+    }
+  else
+    {
+      status = EXIT_FAILURE;
+      printf("%Zd errors.\n", errors);
+    }
+  exit(status);
 }
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index e0ba67b48b..d3eb242c04 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -91,6 +91,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 {
   Elf64_Addr plt;
   extern void _dl_runtime_resolve (void);
+  extern void _dl_runtime_profile (void);
 
   if (l->l_info[DT_JMPREL] && lazy)
     {
@@ -100,7 +101,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
       plt = l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr;
 
       /* This function will be called to perform the relocation.  */
-      *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_resolve;
+      if (!profile)
+        *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_resolve;
+      else
+	{
+	  *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_profile;
+	  /* Say that we really want profiling and the timers are started.  */
+	  _dl_profile_map = l;
+	}
 
       /* Identify this shared object */
       *(Elf64_Addr *)(plt + 24) = (Elf64_Addr) l;
@@ -115,11 +123,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 
 /* This code is used in dl-runtime.c to call the `fixup' function
    and then redirect to the address it returns.  */
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ( \
-"/* Trampoline for _dl_runtime_resolver */
-	.globl _dl_runtime_resolve
-	.ent _dl_runtime_resolve
-_dl_runtime_resolve:
+#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name, IMB) asm ( "\
+	.globl " #tramp_name "
+	.ent " #tramp_name "
+" #tramp_name ":
 	lda	$sp, -168($sp)
 	.frame	$sp, 168, $26
 	/* Preserve all registers that C normally doesn't.  */
@@ -146,18 +153,20 @@ _dl_runtime_resolve:
 	stq	$29, 160($sp)
 	.mask	0x27ff01ff, -168
 	/* Set up our $gp */
-	br	$gp, 0f
-0:	ldgp	$gp, 0($gp)
+	br	$gp, .+4
+	ldgp	$gp, 0($gp)
 	.prologue 1
-	/* Set up the arguments for _dl_runtime_resolve. */
+	/* Set up the arguments for fixup: */
 	/* $16 = link_map out of plt0 */
 	/* $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24 */
+	/* $18 = return address */
 	subq	$28, $27, $17
 	ldq	$16, 8($27)
 	subq	$17, 20, $17
+	mov	$26, $18
 	addq	$17, $17, $17
 	/* Do the fixup */
-	bsr	$26, fixup..ng
+	bsr	$26, " #fixup_name "..ng
 	/* Move the destination address into position.  */
 	mov	$0, $27
 	/* Restore program registers.  */
@@ -183,14 +192,21 @@ _dl_runtime_resolve:
 	ldq	$25, 152($sp)
 	ldq	$29, 160($sp)
 	/* Flush the Icache after having modified the .plt code.  */
-	imb
+	" #IMB "
 	/* Clean up and turn control to the destination */
 	lda	$sp, 168($sp)
 	jmp	$31, ($27)
-	.end _dl_runtime_resolve");
+	.end " #tramp_name)
 
-/* The PLT uses Elf64_Rela relocs.  */
-#define elf_machine_relplt elf_machine_rela
+#ifndef PROF
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE 				\
+  TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup, imb);	\
+  TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup, #nop);
+#else
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE				\
+  TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);		\
+  strong_alias (_dl_runtime_resolve, _dl_runtime_profile);
+#endif
 
 /* Initial entry point code for the dynamic linker.
    The C function `_dl_start' is the real entry point;
@@ -255,37 +271,31 @@ _dl_start_user:
 #define elf_machine_lookup_noexec_p(type)  (0)
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
-#define ELF_MACHINE_RELOC_NOPLT	 R_ALPHA_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT	 R_ALPHA_JMP_SLOT
 
 /* The alpha never uses Elf64_Rel relocations.  */
 #define ELF_MACHINE_NO_REL 1
 
-#endif /* !dl_machine_h */
-
-#ifdef RESOLVE
-
 /* Fix up the instructions of a PLT entry to invoke the function
    rather than the dynamic linker.  */
 static inline void
-elf_alpha_fix_plt(struct link_map *l,
-		  const Elf64_Rela *reloc,
-		  Elf64_Addr got_addr,
-		  Elf64_Addr value)
+elf_machine_fixup_plt(struct link_map *l, const Elf64_Rela *reloc,
+		      Elf64_Addr *got_addr, Elf64_Addr value)
 {
   const Elf64_Rela *rela_plt;
   Elf64_Word *plte;
   long edisp;
 
+  /* Store the value we are going to load.  */
+  *got_addr = value;
+
   /* Recover the PLT entry address by calculating reloc's index into the
      .rela.plt, and finding that entry in the .plt.  */
-
   rela_plt = (void *)(l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr);
-
   plte = (void *)(l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr + 32);
   plte += 3 * (reloc - rela_plt);
 
   /* Find the displacement from the plt entry to the function.  */
-
   edisp = (long)(value - (Elf64_Addr)&plte[3]) / 4;
 
   if (edisp >= -0x100000 && edisp < 0x100000)
@@ -299,7 +309,7 @@ elf_alpha_fix_plt(struct link_map *l,
       lo = (short)hi;
       hi = (hi - lo) >> 16;
 
-      /* Emit "lda $27,L($27)" */
+      /* Emit "lda $27,lo($27)" */
       plte[1] = 0x237b0000 | (lo & 0xffff);
 
       /* Emit "br $31,function" */
@@ -309,7 +319,7 @@ elf_alpha_fix_plt(struct link_map *l,
 	 committed to memory before the first is overwritten.  */
       __asm__ __volatile__("wmb" : : : "memory");
 
-      /* Emit "ldah $27,H($27)" */
+      /* Emit "ldah $27,hi($27)" */
       plte[0] = 0x277b0000 | (hi & 0xffff);
     }
   else
@@ -319,11 +329,11 @@ elf_alpha_fix_plt(struct link_map *l,
 	 into the cache.  */
 
       int hi, lo;
-      hi = got_addr - (Elf64_Addr)&plte[0];
+      hi = (Elf64_Addr)got_addr - (Elf64_Addr)&plte[0];
       lo = (short)hi;
       hi = (hi - lo) >> 16;
 
-      /* Emit "ldq $27,L($27)" */
+      /* Emit "ldq $27,lo($27)" */
       plte[1] = 0xa77b0000 | (lo & 0xffff);
 
       /* Emit "jmp $31,($27)" */
@@ -333,7 +343,7 @@ elf_alpha_fix_plt(struct link_map *l,
 	 committed to memory before the first is overwritten.  */
       __asm__ __volatile__("wmb" : : : "memory");
 
-      /* Emit "ldah $27,H($27)" */
+      /* Emit "ldah $27,hi($27)" */
       plte[0] = 0x277b0000 | (hi & 0xffff);
     }
 
@@ -343,6 +353,10 @@ elf_alpha_fix_plt(struct link_map *l,
      hasn't made it into Icache yet, so there's nothing to clean up.  */
 }
 
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE
+
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 static inline void
@@ -382,14 +396,12 @@ elf_machine_rela (struct link_map *map,
 
       loadbase = RESOLVE (&sym, version, r_type);
       sym_value = sym ? loadbase + sym->st_value : 0;
+      sym_value += reloc->r_addend;
 
       if (r_type == R_ALPHA_GLOB_DAT)
 	*reloc_addr = sym_value;
       else if (r_type == R_ALPHA_JMP_SLOT)
-	{
-	  *reloc_addr = sym_value;
-	  elf_alpha_fix_plt (map, reloc, (Elf64_Addr) reloc_addr, sym_value);
-	}
+	elf_machine_fixup_plt (map, reloc, reloc_addr, sym_value);
       else if (r_type == R_ALPHA_REFQUAD)
 	{
 	  sym_value += *reloc_addr;
@@ -405,10 +417,9 @@ elf_machine_rela (struct link_map *map,
 		= (void *)(map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
 	      sym_value -= map->l_addr;
 	      sym_value -= dlsymtab[ELF64_R_SYM(reloc->r_info)].st_value;
+	      sym_value -= reloc->r_addend;
 	    }
-	  else
 #endif
-	    sym_value += reloc->r_addend;
 	  *reloc_addr = sym_value;
 	}
       else
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 041643ef5a..0ac67c05d9 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -185,15 +185,11 @@ _dl_runtime_profile:
 	.previous
 ");
 #endif
-/* The PLT uses Elf32_Rel relocs.  */
-#define elf_machine_relplt elf_machine_rel
 
 /* Mask identifying addresses reserved for the user program,
    where the dynamic linker should not map anything.  */
 #define ELF_MACHINE_USER_ADDRESS_MASK	0xf8000000UL
 
-
-
 /* Initial entry point code for the dynamic linker.
    The C function `_dl_start' is the real entry point;
    its return value is the user program's entry point.  */
@@ -265,7 +261,7 @@ _dl_start_user:\n\
 #define elf_machine_lookup_noplt_p(type) ((type) == R_386_JMP_SLOT)
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
-#define ELF_MACHINE_RELOC_NOPLT	R_386_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT	R_386_JMP_SLOT
 
 /* The i386 never uses Elf32_Rela relocations.  */
 #define ELF_MACHINE_NO_RELA 1
@@ -287,6 +283,13 @@ dl_platform_init (void)
     _dl_platform = NULL;
 }
 
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rel *reloc,
+		       Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+  *reloc_addr = value;
+}
+
 #endif /* !dl_machine_h */
 
 #ifdef RESOLVE
diff --git a/sysdeps/libm-ieee754/s_exp2f.c b/sysdeps/libm-ieee754/s_exp2f.c
index e50ac77792..92c1f16c5a 100644
--- a/sysdeps/libm-ieee754/s_exp2f.c
+++ b/sysdeps/libm-ieee754/s_exp2f.c
@@ -25,7 +25,9 @@
    It has been slightly modified to compute 2^x instead of e^x, and for
    single-precision.
    */
-#define _GNU_SOURCE
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
 #include <float.h>
 #include <ieee754.h>
 #include <math.h>
@@ -116,7 +118,7 @@ __ieee754_exp2f (float x)
   else if (isgreaterequal (x, (float) FLT_MAX_EXP))
     return huge * huge;
   /* And underflow (including -inf).  */
-  else if (isless (x, (float) (FLT_MIN_EXP - FLT_MANT_DIF)))
+  else if (isless (x, (float) (FLT_MIN_EXP - FLT_MANT_DIG)))
     return TWOM100 * TWOM100;
   /* Maybe the result needs to be a denormalised number...  */
   else if (!isnan (x))
diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h
index 44eefb20f5..cc0fb56189 100644
--- a/sysdeps/m68k/dl-machine.h
+++ b/sysdeps/m68k/dl-machine.h
@@ -135,8 +135,6 @@ asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \
      ".set _dl_runtime_profile, _dl_runtime_resolve");
 #endif
 #define ELF_MACHINE_RUNTIME_FIXUP_ARGS long int save_a0, long int save_a1
-/* The PLT uses Elf32_Rela relocs.  */
-#define elf_machine_relplt elf_machine_rela
 
 
 /* Mask identifying addresses reserved for the user program,
@@ -216,11 +214,18 @@ _dl_start_user:
 #define elf_machine_lookup_noplt_p(type) ((type) == R_68K_JMP_SLOT)
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
-#define ELF_MACHINE_RELOC_NOPLT	R_68K_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT	R_68K_JMP_SLOT
 
 /* The m68k never uses Elf32_Rel relocations.  */
 #define ELF_MACHINE_NO_REL 1
 
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+		       Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+  *reloc_addr = value + reloc->r_addend;
+}
+
 #endif /* !dl_machine_h */
 
 #ifdef RESOLVE
@@ -267,7 +272,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  break;
 	case R_68K_GLOB_DAT:
 	case R_68K_JMP_SLOT:
-	  *reloc_addr = value;
+	  *reloc_addr = value + reloc->r_addend;
 	  break;
 	case R_68K_8:
 	  *(char *) reloc_addr = value + reloc->r_addend;
diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h
index 70a3f20b31..beabc1d4ff 100644
--- a/sysdeps/powerpc/dl-machine.h
+++ b/sysdeps/powerpc/dl-machine.h
@@ -197,8 +197,7 @@ _dl_runtime_resolve:
  # ...unwind the stack frame, and jump to the PLT entry we updated.
 	addi 1,1,48
 	bctr
-0:
-	.size	 _dl_runtime_resolve,0b-_dl_runtime_resolve
+	.size	 _dl_runtime_resolve,.-_dl_runtime_resolve
 
 	.align 2
 	.globl _dl_prof_resolve
@@ -395,10 +394,6 @@ static ElfW(Addr) _dl_preferred_address = 1
      _dl_preferred_address = mapstart;					      \
 } )
 
-/* We require the address of the PLT entry returned from fixup, not
-   the first word of the PLT entry. */
-#define ELF_FIXUP_RETURN_VALUE(map, result)  ((Elf32_Addr) &(result))
-
 /* Nonzero iff TYPE should not be allowed to resolve to one of
    the main executable's symbols, as for a COPY reloc.  */
 #define elf_machine_lookup_noexec_p(type) ((type) == R_PPC_COPY)
@@ -413,7 +408,7 @@ static ElfW(Addr) _dl_preferred_address = 1
 					  (type) == R_PPC_JMP_SLOT)
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
-#define ELF_MACHINE_RELOC_NOPLT	R_PPC_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT	R_PPC_JMP_SLOT
 
 /* Nonzero iff TYPE describes relocation of a PLT entry, so
    PLT entries should not be allowed to define the value.  */
@@ -554,6 +549,70 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
   /* elf_machine_runtime_setup handles this. */
 }
 
+static inline void
+elf_machine_fixup_plt(struct link_map *map, const Elf32_Rela *reloc,
+                      Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
+{
+  Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
+  if (delta << 6 >> 6 == delta)
+    *reloc_addr = OPCODE_B (delta);
+  else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
+    *reloc_addr = OPCODE_BA (finaladdr);
+  else
+    {
+      Elf32_Word *plt;
+      Elf32_Word index;
+
+      plt = (Elf32_Word *)((char *)map->l_addr
+			   + map->l_info[DT_PLTGOT]->d_un.d_val);
+      index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
+      if (index >= PLT_DOUBLE_SIZE)
+	{
+	  /* Slots greater than or equal to 2^13 have 4 words available
+	     instead of two.  */
+	  /* FIXME: There are some possible race conditions in this code,
+	     when called from 'fixup'.
+
+	     1) Suppose that a lazy PLT entry is executing, a context switch
+	     between threads (or a signal) occurs, and the new thread or
+	     signal handler calls the same lazy PLT entry.  Then the PLT entry
+	     would be changed while it's being run, which will cause a segfault
+	     (almost always).
+
+	     2) Suppose the reverse: that a lazy PLT entry is being updated,
+	     a context switch occurs, and the new code calls the lazy PLT
+	     entry that is being updated.  Then the half-fixed PLT entry will
+	     be executed, which will also almost always cause a segfault.
+
+	     These problems don't happen with the 2-word entries, because
+	     only one of the two instructions are changed when a lazy entry
+	     is retargeted at the actual PLT entry; the li instruction stays
+	     the same (we have to update it anyway, because we might not be
+	     updating a lazy PLT entry).  */
+
+	  reloc_addr[0] = OPCODE_LI (11, finaladdr);
+	  reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16);
+	  reloc_addr[2] = OPCODE_MTCTR (11);
+	  reloc_addr[3] = OPCODE_BCTR ();
+	}
+      else
+	{
+	  Elf32_Word num_plt_entries;
+
+	  num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+			     / sizeof(Elf32_Rela));
+
+	  plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr;
+	  reloc_addr[0] = OPCODE_LI (11, index*4);
+	  reloc_addr[1] = OPCODE_B (-(4*(index*2
+					 + 1
+					 - PLT_LONGBRANCH_ENTRY_WORDS
+					 + PLT_INITIAL_ENTRY_WORDS)));
+	}
+    }
+  MODIFIED_CODE (reloc_addr);
+}
+
 #endif /* dl_machine_h */
 
 #ifdef RESOLVE
@@ -674,66 +733,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
   else if (rinfo == R_PPC_JMP_SLOT)
     {
-      Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
-      if (delta << 6 >> 6 == delta)
-	*reloc_addr = OPCODE_B (delta);
-      else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
-	*reloc_addr = OPCODE_BA (finaladdr);
-      else
-	{
-	  Elf32_Word *plt;
-	  Elf32_Word index;
-
-	  plt = (Elf32_Word *)((char *)map->l_addr
-			       + map->l_info[DT_PLTGOT]->d_un.d_val);
-	  index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
-	  if (index >= PLT_DOUBLE_SIZE)
-	    {
-	      /* Slots greater than or equal to 2^13 have 4 words available
-		 instead of two.  */
-	      /* FIXME: There are some possible race conditions in this code,
-		 when called from 'fixup'.
-
-		 1) Suppose that a lazy PLT entry is executing, a
-		 context switch between threads (or a signal) occurs,
-		 and the new thread or signal handler calls the same
-		 lazy PLT entry.  Then the PLT entry would be changed
-		 while it's being run, which will cause a segfault
-		 (almost always).
-
-		 2) Suppose the reverse: that a lazy PLT entry is
-		 being updated, a context switch occurs, and the new
-		 code calls the lazy PLT entry that is being updated.
-		 Then the half-fixed PLT entry will be executed, which
-		 will also almost always cause a segfault.
-
-		 These problems don't happen with the 2-word entries, because
-		 only one of the two instructions are changed when a lazy
-		 entry is retargeted at the actual PLT entry; the li
-		 instruction stays the same (we have to update it anyway,
-		 because we might not be updating a lazy PLT entry).  */
-	      reloc_addr[0] = OPCODE_LI (11, finaladdr);
-	      reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16);
-	      reloc_addr[2] = OPCODE_MTCTR (11);
-	      reloc_addr[3] = OPCODE_BCTR ();
-	    }
-	  else
-	    {
-	      Elf32_Word num_plt_entries;
-
-	      num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
-				 / sizeof(Elf32_Rela));
-
-	      plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr;
-	      reloc_addr[0] = OPCODE_LI (11, index*4);
-	      reloc_addr[1] =
-		OPCODE_B (-(4*(index*2
-			       + 1
-			       - PLT_LONGBRANCH_ENTRY_WORDS
-			       + PLT_INITIAL_ENTRY_WORDS)));
-	    }
-	}
-      MODIFIED_CODE (reloc_addr);
+      elf_machine_fixup_plt (map, reloc, reloc_addr, finalvalue);
     }
   else
     {
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index b80c126487..288a140245 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -126,13 +126,6 @@ _dl_runtime_resolve:
 	 restore
 	.size _dl_runtime_resolve, . - _dl_runtime_resolve");
 
-/* The address of the JMP_SLOT reloc is the .plt entry, thus we don't
-   dereference the reloc's addr to get the final destination.  Ideally
-   there would be a generic way to return the value of the symbol from
-   elf_machine_relplt, but as it is, the address of the .plt entry is
-   good enough.  */
-#define ELF_FIXUP_RETURN_VALUE(map, result)  ((Elf32_Addr) &(result))
-
 /* Nonzero iff TYPE should not be allowed to resolve to one of
    the main executable's symbols, as for a COPY reloc.  */
 #define elf_machine_lookup_noexec_p(type) ((type) == R_SPARC_COPY)
@@ -142,7 +135,7 @@ _dl_runtime_resolve:
 #define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
-#define ELF_MACHINE_RELOC_NOPLT	R_SPARC_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT	R_SPARC_JMP_SLOT
 
 /* The SPARC never uses Elf32_Rel relocations.  */
 #define ELF_MACHINE_NO_REL 1
@@ -150,9 +143,6 @@ _dl_runtime_resolve:
 /* The SPARC overlaps DT_RELA and DT_PLTREL.  */
 #define ELF_MACHINE_PLTREL_OVERLAP 1
 
-/* The PLT uses Elf32_Rela relocs.  */
-#define elf_machine_relplt elf_machine_rela
-
 /* Initial entry point code for the dynamic linker.
    The C function `_dl_start' is the real entry point;
    its return value is the user program's entry point.  */
@@ -246,7 +236,30 @@ _dl_start_user:
 	.size   _dl_start_user,.-_dl_start_user
 .previous");
 
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+		       Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+  /* For thread safety, write the instructions from the bottom and
+     flush before we overwrite the critical "b,a".  This of course
+     need not be done during bootstrapping, since there are no threads.
+     But we also can't tell if we _can_ use flush, so don't. */
+
+  reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
+#ifndef RTLD_BOOTSTRAP
+  if (_dl_hwcap & HWCAP_SPARC_FLUSH)
+    __asm __volatile ("flush %0+8" : : "r"(reloc_addr));
+#endif
+
+  reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
+#ifndef RTLD_BOOTSTRAP
+  if (_dl_hwcap & HWCAP_SPARC_FLUSH)
+    __asm __volatile ("flush %0+4" : : "r"(reloc_addr));
+#endif
+}
+
 #ifdef RESOLVE
+
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
@@ -305,14 +318,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  *reloc_addr = value;
 	  break;
 	case R_SPARC_JMP_SLOT:
-	  /* For thread safety, write the instructions from the bottom and
-	     flush before we overwrite the critical "b,a".  */
-	  reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
-	  if (_dl_hwcap & HWCAP_SPARC_FLUSH)
-	    __asm __volatile ("flush %0+8" : : "r"(reloc_addr));
-	  reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
-	  if (_dl_hwcap & HWCAP_SPARC_FLUSH)
-	    __asm __volatile ("flush %0+4" : : "r"(reloc_addr));
+	  elf_machine_fixup_plt(map, reloc, reloc_addr, value);
 	  break;
 	case R_SPARC_8:
 	  *(char *) reloc_addr = value;
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index e302f4a1fe..226623152d 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -67,7 +67,26 @@ elf_machine_load_address (void)
   return pc - *(Elf64_Addr *)(elf_pic_register + la);
 }
 
+static inline void
+elf_machine_fixup_plt(struct link_map *map, const Elf64_Rela *reloc,
+                      Elf64_Addr *reloc_addr, Elf64_Addr value)
+{
+  Elf64_Dyn *pltfmt = map->l_info[DT_SPARC(PLTFMT)];
+  switch (pltfmt ? pltfmt->d_un.d_val : 0)
+    {
+    case 1: /* .got.plt with absolute addresses */
+      *reloc_addr = value;
+      break;
+    case 2: /* .got.plt with got-relative addresses */
+      *reloc_addr = value - (map->l_info[DT_PLTGOT]->d_un.d_ptr + map->l_addr);
+      break;
+    default:
+      assert (! "unexpected .plt format type");
+    }
+}
+
 #ifdef RESOLVE
+
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
@@ -160,21 +179,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 	  break;
 
 	case R_SPARC_JMP_SLOT:
-	  {
-	    Elf64_Dyn *pltfmt = map->l_info[DT_SPARC(PLTFMT)];
-	    switch (pltfmt ? pltfmt->d_un.d_val : 0)
-	      {
-	      case 1: /* .got.plt with absolute addresses */
-		*reloc_addr = value;
-	        break;
-	      case 2: /* .got.plt with got-relative addresses */
-		*reloc_addr = value - (map->l_info[DT_PLTGOT]->d_un.d_ptr
-				       + map->l_addr);
-		break;
-	      default:
-		assert (! "unexpected .plt format type");
-	      }
-	  }
+	  elf_machine_fixup_plt(map, reloc, reloc_addr, value);
 	  break;
 
 	case R_SPARC_NONE:		/* Alright, Wilbur.  */
@@ -212,7 +217,7 @@ elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
 #define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
-#define ELF_MACHINE_RELOC_NOPLT	R_SPARC_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT	R_SPARC_JMP_SLOT
 
 /* The SPARC never uses Elf64_Rel relocations.  */
 #define ELF_MACHINE_NO_REL 1
@@ -220,13 +225,6 @@ elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
 /* The SPARC overlaps DT_RELA and DT_PLTREL.  */
 #define ELF_MACHINE_PLTREL_OVERLAP 1
 
-/* The return value from dl-runtime's fixup, if it should be special.  */
-#define ELF_FIXUP_RETURN_VALUE(map, result)				\
-  ((map)->l_info[DT_SPARC(PLTFMT)]					\
-   && (map)->l_info[DT_SPARC(PLTFMT)]->d_un.d_val == 2			\
-   ? (result) + (map)->l_info[DT_PLTGOT]->d_un.d_ptr + (map)->l_addr	\
-   : (result))
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/stub/dl-machine.h b/sysdeps/stub/dl-machine.h
index 239d0b0e9f..f787df3500 100644
--- a/sysdeps/stub/dl-machine.h
+++ b/sysdeps/stub/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  Stub version.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997 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
@@ -51,9 +51,14 @@ elf_machine_load_address (void)
 #error "Where am I?"
 }
 
-/* This can modify DYNAMIC_INFO to avoid relocating code in
-   the functions above if they are doing bizarre magic.  */
-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
+/* Fixup a PLT entry to bounce directly to the function at VALUE.  */
+
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rel *reloc,
+		       Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+  *reloc_addr = value;
+}
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    LOADADDR is the load address of the object; INFO is an array indexed
@@ -82,7 +87,7 @@ elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
 }
 
 
-static inline void
+static inline Elf32_Addr
 elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
 		  const Elf32_Rel *reloc, const Elf32_Sym *sym,
 		  Elf32_Addr (*resolve) (const Elf32_Sym **ref,
@@ -107,7 +112,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy)
 {
   extern void _dl_runtime_resolve (Elf32_Word);
 
-  if (lazy) 
+  if (lazy)
     {
       /* The GOT entries for functions in the PLT have not yet been filled
          in.  Their initial contents will arrange when called to push an
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index a3b0eef691..d5c486d7d0 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -32,6 +32,7 @@ nfsservctl	EXTRA	nfsservctl	3	nfsservctl
 pause		-	pause		0	__libc_pause	pause
 personality	init-first personality	1	__personality	personality
 pipe		-	pipe		1	__pipe		pipe
+prctl		EXTRA	prctl		5
 query_module	EXTRA	query_module	5	query_module
 quotactl	EXTRA	quotactl	4	quotactl
 s_getdents	EXTRA	getdents	3	__getdents