summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog170
-rw-r--r--Makeconfig5
-rw-r--r--Rules7
-rw-r--r--aclocal.m428
-rw-r--r--config.h.in3
-rw-r--r--config.make.in1
-rwxr-xr-xconfigure299
-rw-r--r--configure.in94
-rw-r--r--csu/Makefile2
-rw-r--r--elf/dl-profile.c88
-rw-r--r--elf/dl-runtime.c27
-rw-r--r--elf/sofini.c10
-rw-r--r--elf/soinit.c13
-rw-r--r--io/ftwtest-sh102
-rw-r--r--libc.map4
-rw-r--r--locale/setlocale.c12
-rw-r--r--manual/maint.texi1
-rw-r--r--math/Makefile6
-rw-r--r--math/atest-exp2.c240
-rw-r--r--math/libm-test.c3
-rw-r--r--math/math_private.h3
-rw-r--r--math/test-reduce.c207
-rw-r--r--nis/Banner2
-rw-r--r--nis/Makefile2
-rw-r--r--nis/TODO8
-rw-r--r--nis/nis_add.c3
-rw-r--r--nis/nis_cache.c2
-rw-r--r--nis/nis_call.c98
-rw-r--r--nis/nis_callback.c339
-rw-r--r--nis/nis_checkpoint.c2
-rw-r--r--nis/nis_file.c2
-rw-r--r--nis/nis_findserv.c73
-rw-r--r--nis/nis_intern.h24
-rw-r--r--nis/nis_lookup.c2
-rw-r--r--nis/nis_mkdir.c4
-rw-r--r--nis/nis_modify.c3
-rw-r--r--nis/nis_ping.c2
-rw-r--r--nis/nis_remove.c3
-rw-r--r--nis/nis_rmdir.c4
-rw-r--r--nis/nis_server.c4
-rw-r--r--nis/nis_table.c234
-rw-r--r--nis/nis_util.c21
-rw-r--r--nis/nss_nisplus/nisplus-publickey.c4
-rw-r--r--nis/rpcsvc/nis.h538
-rw-r--r--posix/globtest.c7
-rwxr-xr-xposix/globtest.sh29
-rw-r--r--string/bits/string2.h198
-rw-r--r--sunrpc/get_myaddr.c32
-rw-r--r--sysdeps/i386/dl-machine.h4
-rw-r--r--sysdeps/i386/i486/atomicity.h2
-rw-r--r--sysdeps/i386/i486/bits/string.h145
-rw-r--r--sysdeps/libm-i387/s_exp2.S5
-rw-r--r--sysdeps/libm-i387/s_exp2f.S5
-rw-r--r--sysdeps/libm-i387/s_exp2l.S5
-rw-r--r--sysdeps/libm-ieee754/Dist2
-rw-r--r--sysdeps/libm-ieee754/k_standard.c36
-rw-r--r--sysdeps/libm-ieee754/s_exp2.c128
-rw-r--r--sysdeps/libm-ieee754/s_exp2f.c126
-rw-r--r--sysdeps/libm-ieee754/t_exp2.h585
-rw-r--r--sysdeps/libm-ieee754/t_exp2f.h301
-rw-r--r--sysdeps/libm-ieee754/w_exp2.c36
-rw-r--r--sysdeps/libm-ieee754/w_exp2f.c32
-rw-r--r--sysdeps/libm-ieee754/w_exp2l.c30
-rw-r--r--sysdeps/powerpc/Makefile6
-rw-r--r--sysdeps/powerpc/bits/mathinline.h44
-rw-r--r--sysdeps/powerpc/bzero.S27
-rw-r--r--sysdeps/powerpc/dl-machine.h71
-rw-r--r--sysdeps/powerpc/machine-gmon.h1
-rw-r--r--sysdeps/powerpc/stpcpy.S100
-rw-r--r--sysdeps/powerpc/strcat.c30
-rw-r--r--sysdeps/powerpc/strcpy.S100
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/kernel_termios.h12
73 files changed, 3697 insertions, 1103 deletions
diff --git a/ChangeLog b/ChangeLog
index 6048b08796..f754101122 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,173 @@
+1997-09-25 00:23  Ulrich Drepper  <drepper@cygnus.com>
+
+	* elf/dl-profile.c: Correct implementation.
+
+	* io/ftwtest-sh: Don't depend on TMPDIR == /tmp.
+
+	* locale/setlocale.c: Rewrite a bit for more clarity.
+
+	* math/Makefile (libm-calls): Add w_exp2.
+	* math/math_private.h: Add prototypes for __ieee754_exp2{,f,l}.
+	* sysdeps/libm-i387/s_exp2.S: Change name to __ieee754_exp2.
+	* sysdeps/libm-i387/s_exp2f.S: Likewise.
+	* sysdeps/libm-i387/s_exp2l.S: Likewise.
+	* sysdeps/libm-ieee754/k_standard.c: Add error cases for exp2.
+
+	* string/bits/string2.h (__strcpy_small): Optimize.
+	(__stpcpy_small): Likewise.
+	(strncpy): Use variable for dest argument since it's used more than
+	once.
+	(strncat): Likewise.
+	(strcmp): Add optimization for this function.
+	* sysdeps/i386/i486/string.h (strlen): Correctly use __builtin_strlen.
+	(__strcpy_small): Optimize.
+	(__stpcpy_small): Likewise.
+	(__stpcpy_c): Correctly use __mempcpy_* macros.
+	(__mempcpy_by2, __mempcpy_by4, __mempcpy_byn): Return pointer to
+	byte following last copied.
+	(strncat): Use variable for dest argument since it's used more than
+	once.
+	(strcmp): Add optimization for this function.
+
+	* sysdeps/i386/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE): Use
+	.text and .previous to select correct section.
+
+1997-09-23 19:56  Philip Blundell  <Philip.Blundell@pobox.com>
+
+	* configure.in: Add `--disable-versioning' option to suppress the
+	use of symbol versions even if binutils claims to support it.
+
+1997-09-24 20:10  Philip Blundell  <Philip.Blundell@pobox.com>
+
+	* csu/Makefile (before-compile): Don't try to build abi-tags.h if
+	not using ELF.
+
+1997-09-21  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* elf/sofini.c [HAVE_DWARF2_UNWIND_INFO]: Supply termination for
+	the frame unwind info section.
+
+	* elf/soinit.c [HAVE_DWARF2_UNWIND_INFO]: Register and unregister
+	the frame unwind info.
+
+	* config.h.in (HAVE_DWARF2_UNWIND_INFO): Add #undef.
+
+	* configure.in: Check whether gcc supports DWARF2 unwind info.
+
+	* libc.map: Export frame handling tables.
+
+1997-09-10 06:56  Geoff Keating  <geoffk@ozemail.com.au>
+
+	* sysdeps/unix/sysv/linux/powerpc/bits/kernel_termios.h:
+	Use the size of the kernel's termios structure for ioctls.
+
+	* sysdeps/powerpc/dl-machine.h: Prepare for library profiling.
+
+	* sysdeps/powerpc/bits/mathinline.h: Add slightly slower versions
+	of the C9X FP comparison macros. Delete 'fabs' and 'sqrt' inline
+	routines, because gcc has them as internals.
+
+	* sysdeps/powerpc/Makefile (pic-ccflags): Define this instead of
+	CFLAGS-.os.
+
+	* sysdeps/powerpc/bzero.S: New file.
+	* sysdeps/powerpc/strcat.c: New file.
+	* sysdeps/powerpc/strcpy.S: New file.
+	* sysdeps/powerpc/stpcpy.S: New file.
+
+	* math/Makefile: Add atest_exp2, test-reduce.
+	* math/atest_exp2.c: New file.
+	* math/test-reduce.c: New file.
+	* sysdeps/libm-ieee754/Dist: New file.
+	* sysdeps/libm-ieee754/s_exp2.c: New file.
+	* sysdeps/libm-ieee754/s_exp2f.c: New file.
+	* sysdeps/libm-ieee754/t_exp2.h: New file.
+	* sysdeps/libm-ieee754/t_exp2f.h: New file.
+	* math/libm-test.c (exp2_test): Add some more tests.
+
+	* Rules: Use empty.os instead of empty.o, since it gets linked into
+	libc.so...
+	* configure.in: Add --disable-static to disable building .a files.
+	* config.make.in: Substitute the new variable.
+	* Makeconfig: Don't build .o files if not building .a files.
+
+	* elf/dl-runtime.c (fixup): Factor out call to elf_machine_relplt.
+	(profile_fixup): Likewise.
+
+1997-09-23  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* posix/globtest.c (main): Change to directory passed as first
+	argument.
+
+	* posix/globtest.sh: Don't cd before running the program, instead
+	pass testdir as argument, so that $common_objpfx remains valid.
+
+1997-09-23 18:01  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+	* nis/nis_call.c (__do_niscall2): Fix multiple Server support.
+
+	* nis/nis_findserver.c: Save latest working sockaddr_in.
+
+1997-09-17 22:07  Zack Weinberg  <zack@rabi.phys.columbia.edu>
+
+	* configure.in: Automatically determine whether as and ld are the
+	GNU versions.
+	(options):  --with-gnu-{as,ld,binutils} replaced by
+	single option --with-binutils=PATH specifying a -B option to gcc.
+	* aclocal.m4: Two new macros defined, LIBC_PROG_FOO_GNU and
+	LIBC_PROG_BINUTILS.
+
+	* configure.in: Allow the user to force configuration for
+	unsupported platforms with an undocumented option.
+
+1997-09-22 16:55  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+	* sunrpc/get_myaddr.c (get_myaddress): Avoid loopback interfaces,
+	return loopback address only if there is no other interface.
+
+	* nis/Makefile: Add nis_callback libnsl-routines.
+
+	* nis/nis_add.c: Use new __do_niscall* interface.
+	* nis/nis_cache.c: Likewise.
+	* nis/nis_checkpoint.c: Likewise.
+	* nis/nis_lookup.c: Likewise.
+	* nis/nis_mkdir.c: Likewise.
+	* nis/nis_modify.c: Likewise.
+	* nis/nis_ping.c: Likewise.
+	* nis/nis_remove.c: Likewise.
+	* nis/nis_rmdir.c: Likewise.
+	* nis/nis_server.c: Likewise.
+	* nis/nis_util.c: Likewise.
+
+	* nis/rpcsvc/nis.h: Make C++ safe.
+
+	* nis/nss_nisplus/nisplus-publickey.c (getsecretkey): Fix use
+	of variables.
+
+	* nis/nis_findserv.c: Make thread safe.
+
+	* nis/nis_call.c: Add support for callback, Fix use of variables.
+	* nis/nis_table.c: Add support for callback, FOLLOW_PATH and
+	ALL_RESULTS.
+	* nis/nis_callback.c: New, callback functions.
+	* nis/nis_intern.h: Add callback declarations.
+
+1997-09-20  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* string/bits/string2.h: Fix logic in preprocessor directive.
+	(__strsep_1c, __strsep_g): Don't declare __retval as pointing to
+	const, to save a cast and a possible warning.
+
+1997-09-22 04:12  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sysdeps/i386/i486/atomicity.h (exchange_and_add): Really address
+	memory in xadd not %1.
+
+1997-09-21 13:56  Ulrich Drepper  <drepper@cygnus.com>
+
+	* manual/maint.texi (Supported Configurations): Add SPARC64 to
+	list of supported platforms.
+
 1997-09-21 03:19  Ulrich Drepper  <drepper@cygnus.com>
 
 	* libio/libio.h: More libstdc++ cleanups.  Define _IO_USE_DTOA if
diff --git a/Makeconfig b/Makeconfig
index 9f6786cbba..e87100e9af 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -533,9 +533,12 @@ endif
 # The compilation rules use $(CPPFLAGS-${SUFFIX}) and $(CFLAGS-${SUFFIX})
 # to pass different flags for each flavor.
 libtypes = $(foreach o,$(object-suffixes),$(libtype$o))
-object-suffixes := .o
 all-object-suffixes := .o .os .op .og .ob
+object-suffixes :=
+ifeq (yes,$(build-static))
 libtype.o := lib%.a
+object-suffixes += .o
+endif
 ifeq (yes,$(build-shared))
 # Under --enable-shared, we will build a shared library of PIC objects.
 # The PIC object files are named foo.os.
diff --git a/Rules b/Rules
index e74b6367c7..ca1361b9f6 100644
--- a/Rules
+++ b/Rules
@@ -81,7 +81,7 @@ $(common-objpfx)dummy.c:
 	echo 'void __dummy__ (void) { }' > $@
 $(common-objpfx)empty.c:
 	cp -f /dev/null $@
-common-generated := $(common-generated) dummy.o dummy.c empty.c empty.o
+common-generated := $(common-generated) dummy.o dummy.c empty.c empty.os
 
 # This makes all the auxiliary and test programs.
 
@@ -166,7 +166,10 @@ endif
 ifdef static-only-routines
 # These routines are to be omitted from the shared library object,
 # so we replace the PIC objects for them with the empty object file.
-$(static-only-routines:%=$(objpfx)%.os): %.os: $(common-objpfx)empty.o
+$(static-only-routines:%=$(objpfx)%.os): %.os: $(common-objpfx)empty.os
 	rm -f $@
 	ln $< $@
+
+$(common-objpfx)empty.os: $(common-objpfx)empty.c $(before-compile)
+	$(compile-command.c)
 endif
diff --git a/aclocal.m4 b/aclocal.m4
index bf1ad40e2a..3c8e794d21 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -90,3 +90,31 @@ AC_MSG_RESULT($ac_cv_prog_cc_cross)
 AC_SUBST(cross_linkable)
 cross_compiling=$ac_cv_prog_cc_cross
 ])
+
+AC_DEFUN(LIBC_PROG_FOO_GNU,
+[# Most GNU programs take a -v and spit out some text including
+# the word 'GNU'.  Some try to read stdin, so give them /dev/null.
+if $1 -v </dev/null 2>&1 | grep -q GNU; then
+  $2
+else
+  $3
+fi])
+
+AC_DEFUN(LIBC_PROG_BINUTILS,
+[# Was a --with-binutils option given?
+if test -n "$path_binutils"; then
+    # Make absolute; ensure a single trailing slash.
+    path_binutils=`(cd $path_binutils; pwd) | sed 's%/*$%/%'`
+    CC="$CC -B$with_binutils"
+fi
+AS=`$CC -print-file-name=as`
+LD=`$CC -print-file-name=ld`
+
+# Determine whether we are using GNU binutils.
+AC_CACHE_CHECK(whether $AS is GNU as, libc_cv_prog_as_gnu,
+[LIBC_PROG_FOO_GNU($AS, libc_cv_prog_as_gnu=yes, libc_cv_prog_as_gnu=no)])
+gnu_as=$libc_cv_prog_as_gnu
+
+AC_CACHE_CHECK(whether $LD is GNU ld, libc_cv_prog_ld_gnu,
+[LIBC_PROG_FOO_GNU($LD, libc_cv_prog_ld_gnu=yes, libc_cv_prog_ld_gnu=no)])
+gnu_ld=$libc_cv_prog_ld_gnu])
diff --git a/config.h.in b/config.h.in
index 390b228529..1301d9ea68 100644
--- a/config.h.in
+++ b/config.h.in
@@ -49,6 +49,9 @@
 /* Define if static NSS modules are wanted.  */
 #undef	DO_STATIC_NSS
 
+/* Define if gcc uses DWARF2 unwind information for exception support.  */
+#undef	HAVE_DWARF2_UNWIND_INFO
+
 /*
  */
 
diff --git a/config.make.in b/config.make.in
index 8472c496ec..ba689ececa 100644
--- a/config.make.in
+++ b/config.make.in
@@ -37,6 +37,7 @@ have-ksh = @libc_cv_have_ksh@
 # Configuration options.
 gnu-as = @gnu_as@
 gnu-ld = @gnu_ld@
+build-static = @static@
 build-shared = @shared@
 build-profile = @profile@
 build-omitfp = @omitfp@
diff --git a/configure b/configure
index 958e588dcc..2ba44100f2 100755
--- a/configure
+++ b/configure
@@ -5,6 +5,10 @@
 
 
 
+
+
+
+
 # Guess values for system-dependent variables and create Makefiles.
 # Generated automatically using autoconf version 2.12 
 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
@@ -23,11 +27,8 @@ ac_help="$ac_help
 ac_help="$ac_help
   --with-fp		  if using floating-point hardware [default=yes]"
 ac_help="$ac_help
-  --with-gnu-binutils	  if using GNU binutils (as and ld)"
-ac_help="$ac_help
-  --with-gnu-ld		  if using GNU ld (in the binutils package)"
-ac_help="$ac_help
-  --with-gnu-as		  if using GNU as (in the binutils package)"
+  --with-binutils=PATH	  specify location of binutils (as and ld)
+	    path_binutils=$withval"
 ac_help="$ac_help
   --with-elf		  if using the ELF object format"
 ac_help="$ac_help
@@ -36,6 +37,8 @@ ac_help="$ac_help
   --disable-sanity-checks really do not use threads (should not be used
 			  except in special situations) [default=yes]"
 ac_help="$ac_help
+  --enable-static         build static library [default=yes]"
+ac_help="$ac_help
   --enable-shared         build shared library [default=yes if GNU ld & ELF]"
 ac_help="$ac_help
   --enable-profile        build profiled library [default=yes]"
@@ -44,6 +47,9 @@ ac_help="$ac_help
 ac_help="$ac_help
   --enable-bounded        build with runtime bounds checking [default=no]"
 ac_help="$ac_help
+  --disable-versioning    do not include versioning information in the
+                          library objects [default=yes if supported]"
+ac_help="$ac_help
   --enable-add-ons=DIR... configure and build named extra directories"
 ac_help="$ac_help
   --enable-static-nss     build static NSS modules [default=no]"
@@ -604,31 +610,12 @@ else
   with_fp=yes
 fi
 
-# Check whether --with-gnu-binutils or --without-gnu-binutils was given.
-if test "${with_gnu_binutils+set}" = set; then
-  withval="$with_gnu_binutils"
-  gnu_binutils=$withval
-else
-  gnu_binutils=no
+# Check whether --with-binutils or --without-binutils was given.
+if test "${with_binutils+set}" = set; then
+  withval="$with_binutils"
+  path_binutils=''
 fi
 
-# Check whether --with-gnu-ld or --without-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then
-  withval="$with_gnu_ld"
-  gnu_ld=$withval
-else
-  gnu_ld=no
-fi
-
-# Check whether --with-gnu-as or --without-gnu-as was given.
-if test "${with_gnu_as+set}" = set; then
-  withval="$with_gnu_as"
-  gnu_as=$withval
-else
-  gnu_as=no
-fi
-
-test $gnu_binutils = yes && gnu_as=yes gnu_ld=yes
 # Check whether --with-elf or --without-elf was given.
 if test "${with_elf+set}" = set; then
   withval="$with_elf"
@@ -660,6 +647,14 @@ else
 fi
 
 
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  static=$enableval
+else
+  static=yes
+fi
+
 # Check whether --enable-shared or --disable-shared was given.
 if test "${enable_shared+set}" = set; then
   enableval="$enable_shared"
@@ -692,6 +687,14 @@ else
   bounded=no
 fi
 
+# Check whether --enable-versioning or --disable-versioning was given.
+if test "${enable_versioning+set}" = set; then
+  enableval="$enable_versioning"
+  enable_versioning=$enableval
+else
+  enable_versioning=yes
+fi
+
 
 # Check whether --enable-add-ons or --disable-add-ons was given.
 if test "${enable_add_ons+set}" = set; then
@@ -751,7 +754,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:755: checking host system type" >&5
+echo "configure:758: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -789,19 +792,25 @@ esac
 ### I put this here to prevent those annoying emails from people who cannot
 ### read and try to compile glibc on unsupported platforms.  --drepper
 ###
-case "$host_os" in
-linux* | gnu*)
-  ;;
-*)
-  echo "*** The GNU C library is currently not available for this platform."
-  echo "*** So far nobody cared to port it and if there is no volunteer it"
-  echo "*** might never happen.  So, if you have interest to see glibc on"
-  echo "*** this platform visit"
-  echo "***	http://www.gnu.ai.mit.edu/software/libc/porting.html"
-  echo "*** and join the group of porters"
-  exit 1
-  ;;
-esac
+### By using the undocumented --enable-hacker-mode option for configure
+### one can skip this test to make the configuration not fail for unsupported
+### platforms.
+###
+if test -z "$enable_hacker_mode"; then
+  case "$host_os" in
+  linux* | gnu*)
+    ;;
+  *)
+    echo "*** The GNU C library is currently not available for this platform."
+    echo "*** So far nobody cared to port it and if there is no volunteer it"
+    echo "*** might never happen.  So, if you have interest to see glibc on"
+    echo "*** this platform visit"
+    echo "***	http://www.gnu.ai.mit.edu/software/libc/porting.html"
+    echo "*** and join the group of porters"
+    exit 1
+    ;;
+  esac
+fi
 
 # We keep the original values in `$config_*' and never modify them, so we
 # can write them unchanged into config.make.  Everything else uses
@@ -857,7 +866,7 @@ esac
 # This can take a while to compute.
 sysdep_dir=$srcdir/sysdeps
 echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
-echo "configure:861: checking sysdep dirs" >&5
+echo "configure:870: checking sysdep dirs" >&5
 # Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
 os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`"
 
@@ -1058,7 +1067,7 @@ echo "$ac_t""sysdeps/generic sysdeps/stub" 1>&6
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1062: checking for a BSD compatible install" >&5
+echo "configure:1071: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1112,7 +1121,7 @@ if test "$INSTALL" = "${srcdir}/install-sh -c"; then
   INSTALL='\$(..)./install-sh -c'
 fi
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1116: checking whether ln -s works" >&5
+echo "configure:1125: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1137,7 +1146,7 @@ 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:1141: checking for $ac_word" >&5
+echo "configure:1150: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1170,7 +1179,7 @@ test -n "$MSGFMT" || MSGFMT=":"
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1174: checking for $ac_word" >&5
+echo "configure:1183: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1199,7 +1208,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1203: checking for $ac_word" >&5
+echo "configure:1212: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1247,7 +1256,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1251: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1260: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1257,11 +1266,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS
 cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext <<EOF
-#line 1261 "configure"
+#line 1270 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
-if { (eval echo configure:1265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1284,13 +1293,13 @@ else
  cross_linkable=yes
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1288: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1297: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1294: checking whether we are using GNU C" >&5
+echo "configure:1303: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1299,7 +1308,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1303: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1312: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1316,7 +1325,7 @@ if test $ac_cv_prog_gcc = yes; then
   yes;
 #endif
 EOF
-  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1320: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1329: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
     if test -z "$CFLAGS"; then
       CFLAGS="-g -O2"
     fi
@@ -1328,7 +1337,7 @@ else
 fi
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1332: checking build system type" >&5
+echo "configure:1341: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -1351,7 +1360,7 @@ 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:1355: checking for $ac_word" >&5
+echo "configure:1364: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1382,7 +1391,7 @@ done
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1386: checking how to run the C preprocessor" >&5
+echo "configure:1395: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1397,13 +1406,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1401 "configure"
+#line 1410 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1407: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1416: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1414,13 +1423,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1418 "configure"
+#line 1427 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1424: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1433: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1442,6 +1451,49 @@ else
 fi
 echo "$ac_t""$CPP" 1>&6
 
+# Was a --with-binutils option given?
+if test -n "$path_binutils"; then
+    # Make absolute; ensure a single trailing slash.
+    path_binutils=`(cd $path_binutils; pwd) | sed 's%/*$%/%'`
+    CC="$CC -B$with_binutils"
+fi
+AS=`$CC -print-file-name=as`
+LD=`$CC -print-file-name=ld`
+
+# Determine whether we are using GNU binutils.
+echo $ac_n "checking whether $AS is GNU as""... $ac_c" 1>&6
+echo "configure:1466: checking whether $AS is GNU as" >&5
+if eval "test \"`echo '$''{'libc_cv_prog_as_gnu'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # Most GNU programs take a -v and spit out some text including
+# the word 'GNU'.  Some try to read stdin, so give them /dev/null.
+if $AS -v </dev/null 2>&1 | grep -q GNU; then
+  libc_cv_prog_as_gnu=yes
+else
+  libc_cv_prog_as_gnu=no
+fi
+fi
+
+echo "$ac_t""$libc_cv_prog_as_gnu" 1>&6
+gnu_as=$libc_cv_prog_as_gnu
+
+echo $ac_n "checking whether $LD is GNU ld""... $ac_c" 1>&6
+echo "configure:1483: checking whether $LD is GNU ld" >&5
+if eval "test \"`echo '$''{'libc_cv_prog_ld_gnu'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # Most GNU programs take a -v and spit out some text including
+# the word 'GNU'.  Some try to read stdin, so give them /dev/null.
+if $LD -v </dev/null 2>&1 | grep -q GNU; then
+  libc_cv_prog_ld_gnu=yes
+else
+  libc_cv_prog_ld_gnu=no
+fi
+fi
+
+echo "$ac_t""$libc_cv_prog_ld_gnu" 1>&6
+gnu_ld=$libc_cv_prog_ld_gnu
 if test $host != $build; then
   ac_tool_prefix=${host_alias}-
 else
@@ -1451,7 +1503,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1455: checking for $ac_word" >&5
+echo "configure:1507: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1482,7 +1534,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1486: checking for $ac_word" >&5
+echo "configure:1538: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1513,7 +1565,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1517: checking for $ac_word" >&5
+echo "configure:1569: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1548,7 +1600,7 @@ fi
 # Extract the first word of "bash", so it can be a program name with args.
 set dummy bash; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1552: checking for $ac_word" >&5
+echo "configure:1604: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1589,7 +1641,7 @@ if test "$BASH" = no; then
   # Extract the first word of "ksh", so it can be a program name with args.
 set dummy ksh; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1593: checking for $ac_word" >&5
+echo "configure:1645: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_KSH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1631,7 +1683,7 @@ fi
 
 
 echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:1635: checking for signed size_t type" >&5
+echo "configure:1687: 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
@@ -1655,12 +1707,12 @@ EOF
 fi
 
 echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:1659: checking for libc-friendly stddef.h" >&5
+echo "configure:1711: 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 1664 "configure"
+#line 1716 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -1675,7 +1727,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:1679: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1731: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -1694,7 +1746,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:1698: checking whether we need to use -P to assemble .S files" >&5
+echo "configure:1750: 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
@@ -1717,7 +1769,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:1721: checking for assembler global-symbol directive" >&5
+echo "configure:1773: 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
@@ -1747,7 +1799,7 @@ EOF
 fi
 
 echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:1751: checking for .set assembler directive" >&5
+echo "configure:1803: 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
@@ -1781,7 +1833,7 @@ EOF
 fi
 
 echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
-echo "configure:1785: checking for .symver assembler directive" >&5
+echo "configure:1837: 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
@@ -1800,7 +1852,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:1804: checking for ld --version-script" >&5
+echo "configure:1856: 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
@@ -1819,7 +1871,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:1823: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+		       1>&5'; { (eval echo configure:1875: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
     then
       libc_cv_ld_version_script_option=yes
     else
@@ -1836,7 +1888,8 @@ fi
 
 echo "$ac_t""$libc_cv_ld_version_script_option" 1>&6
 if test $libc_cv_asm_symver_directive = yes &&
-   test $libc_cv_ld_version_script_option = yes; then
+   test $libc_cv_ld_version_script_option = yes &&
+   test $enable_versioning = yes; then
   VERSIONING=yes
   cat >> confdefs.h <<\EOF
 #define DO_VERSIONING 1
@@ -1849,7 +1902,7 @@ fi
 
 if test $elf = yes; then
   echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:1853: checking for .previous assembler directive" >&5
+echo "configure:1906: 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
@@ -1857,7 +1910,7 @@ else
 .section foo_section
 .previous
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1861: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  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
     libc_cv_asm_previous_directive=yes
   else
     libc_cv_asm_previous_directive=no
@@ -1873,7 +1926,7 @@ EOF
 
   else
     echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:1877: checking for .popsection assembler directive" >&5
+echo "configure:1930: 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
@@ -1881,7 +1934,7 @@ else
 .pushsection foo_section
 .popsection
 EOF
-    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1885: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+    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
       libc_cv_asm_popsection_directive=yes
     else
       libc_cv_asm_popsection_directive=no
@@ -1901,12 +1954,12 @@ fi
 
 if test $elf != yes; then
   echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:1905: checking for .init and .fini sections" >&5
+echo "configure:1958: 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 1910 "configure"
+#line 1963 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1915,7 +1968,7 @@ asm (".section .init");
 				    asm (".text");
 ; return 0; }
 EOF
-if { (eval echo configure:1919: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -1943,19 +1996,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:1947: checking for _ prefix on C symbol names" >&5
+echo "configure:2000: 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 1952 "configure"
+#line 2005 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:1959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -1970,17 +2023,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:1974: checking for _ prefix on C symbol names" >&5
+echo "configure:2027: 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 1979 "configure"
+#line 2032 "configure"
 #include "confdefs.h"
 void underscore_test(void) {
 return; }
 EOF
-if { (eval echo configure:1984: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2037: \"$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
@@ -2013,7 +2066,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:2017: checking for assembler .weak directive" >&5
+echo "configure:2070: 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
@@ -2036,7 +2089,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:2040: checking for assembler .weakext directive" >&5
+echo "configure:2093: 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
@@ -2073,7 +2126,7 @@ EOF
 fi
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:2077: checking for ld --no-whole-archive" >&5
+echo "configure:2130: 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
@@ -2084,7 +2137,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -Wl,--no-whole-archive
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:2088: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:2141: \"$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
@@ -2095,7 +2148,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:2099: checking for gcc -fno-exceptions" >&5
+echo "configure:2152: 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
@@ -2106,7 +2159,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -fno-exceptions
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:2110: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:2163: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_no_exceptions=yes
 else
   libc_cv_gcc_no_exceptions=no
@@ -2116,6 +2169,48 @@ 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
+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"
+static char __EH_FRAME_BEGIN__;
+_start ()
+{
+  __register_frame (__EH_FRAME_BEGIN__);
+  __deregister_frame (__EH_FRAME_BEGIN__);
+}
+int __eh_pc;
+__throw () {}
+/* FIXME: this is fragile.  */
+malloc () {}
+strcmp () {}
+strlen () {}
+memcpy () {}
+memset () {}
+free () {}
+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
+  libc_cv_gcc_dwarf2_unwind_info=yes
+else
+  libc_cv_gcc_dwarf2_unwind_info=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libc_cv_gcc_dwarf2_unwind_info" 1>&6
+if test $libc_cv_gcc_dwarf2_unwind_info = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_DWARF2_UNWIND_INFO 1
+EOF
+
+fi
+
 ### End of automated tests.
 ### Now run sysdeps configure fragments.
 
@@ -2158,7 +2253,7 @@ if test "$uname" = "sysdeps/generic"; then
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:2162: checking OS release for uname" >&5
+echo "configure:2257: 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
@@ -2180,7 +2275,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:2184: checking OS version for uname" >&5
+echo "configure:2279: 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
@@ -2202,7 +2297,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:2206: checking stdio selection" >&5
+echo "configure:2301: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -2214,7 +2309,7 @@ esac
 echo "$ac_t""$stdio" 1>&6
 
 echo $ac_n "checking ldap selection""... $ac_c" 1>&6
-echo "configure:2218: checking ldap selection" >&5
+echo "configure:2313: checking ldap selection" >&5
 
 case $add_ons in
 *ldap*)
@@ -2252,6 +2347,7 @@ EOF
 fi
 
 
+
 if test $shared = default; then
   if test $gnu_ld = yes; then
     shared=$elf
@@ -2453,6 +2549,7 @@ s%@has_ldconfig@%$has_ldconfig%g
 s%@gnu_ld@%$gnu_ld%g
 s%@gnu_as@%$gnu_as%g
 s%@elf@%$elf%g
+s%@static@%$static%g
 s%@shared@%$shared%g
 s%@profile@%$profile%g
 s%@omitfp@%$omitfp%g
diff --git a/configure.in b/configure.in
index 340e86774a..4c507bb1e3 100644
--- a/configure.in
+++ b/configure.in
@@ -36,16 +36,9 @@ dnl Arguments to specify presence of other packages/features.
 AC_ARG_WITH(fp, dnl
 [  --with-fp		  if using floating-point hardware [default=yes]],
 	    with_fp=$withval, with_fp=yes)
-AC_ARG_WITH(gnu-binutils, dnl
-  --with-gnu-binutils	  if using GNU binutils (as and ld),
-	    gnu_binutils=$withval, gnu_binutils=no)
-AC_ARG_WITH(gnu-ld, dnl
-  --with-gnu-ld		  if using GNU ld (in the binutils package),
-	    gnu_ld=$withval, gnu_ld=no)
-AC_ARG_WITH(gnu-as, dnl
-  --with-gnu-as		  if using GNU as (in the binutils package),
-	    gnu_as=$withval, gnu_as=no)
-test $gnu_binutils = yes && gnu_as=yes gnu_ld=yes
+AC_ARG_WITH(binutils, dnl
+  --with-binutils=PATH	  specify location of binutils (as and ld)
+	    path_binutils=$withval, path_binutils='')
 AC_ARG_WITH(elf, dnl
   --with-elf		  if using the ELF object format,
 	    elf=$withval, elf=no)
@@ -64,8 +57,11 @@ AC_ARG_ENABLE(sanity-checks, dnl
 			  except in special situations) [default=yes]],
               enable_sanity=$enableval, enable_sanity=yes)
 
-dnl Arguments to enable or disable building the shared, profiled, and
-dnl -fomit-frame-pointer libraries.
+dnl Arguments to enable or disable building the static, shared, profiled,
+dnl and -fomit-frame-pointer libraries.
+AC_ARG_ENABLE(static, dnl
+[  --enable-static         build static library [default=yes]],
+	      static=$enableval, static=yes)
 AC_ARG_ENABLE(shared, dnl
 [  --enable-shared         build shared library [default=yes if GNU ld & ELF]],
 	      shared=$enableval, shared=default)
@@ -78,6 +74,10 @@ AC_ARG_ENABLE(omitfp, dnl
 AC_ARG_ENABLE(bounded, dnl
 [  --enable-bounded        build with runtime bounds checking [default=no]],
 	      bounded=$enableval, bounded=no)
+AC_ARG_ENABLE(versioning, dnl
+[  --disable-versioning    do not include versioning information in the
+                          library objects [default=yes if supported]],
+             enable_versioning=$enableval, enable_versioning=yes)
 
 dnl Generic infrastructure for drop-in additions to libc.
 AC_ARG_ENABLE(add-ons, dnl
@@ -120,19 +120,25 @@ esac
 ### I put this here to prevent those annoying emails from people who cannot
 ### read and try to compile glibc on unsupported platforms.  --drepper
 ###
-case "$host_os" in
-linux* | gnu*)
-  ;;
-*)
-  echo "*** The GNU C library is currently not available for this platform."
-  echo "*** So far nobody cared to port it and if there is no volunteer it"
-  echo "*** might never happen.  So, if you have interest to see glibc on"
-  echo "*** this platform visit"
-  echo "***	http://www.gnu.ai.mit.edu/software/libc/porting.html"
-  echo "*** and join the group of porters"
-  exit 1
-  ;;
-esac
+### By using the undocumented --enable-hacker-mode option for configure
+### one can skip this test to make the configuration not fail for unsupported
+### platforms.
+###
+if test -z "$enable_hacker_mode"; then
+  case "$host_os" in
+  linux* | gnu*)
+    ;;
+  *)
+    echo "*** The GNU C library is currently not available for this platform."
+    echo "*** So far nobody cared to port it and if there is no volunteer it"
+    echo "*** might never happen.  So, if you have interest to see glibc on"
+    echo "*** this platform visit"
+    echo "***	http://www.gnu.ai.mit.edu/software/libc/porting.html"
+    echo "*** and join the group of porters"
+    exit 1
+    ;;
+  esac
+fi
 
 # We keep the original values in `$config_*' and never modify them, so we
 # can write them unchanged into config.make.  Everything else uses
@@ -401,6 +407,7 @@ if test $host != $build; then
 fi
 AC_SUBST(cross_compiling)
 AC_PROG_CPP
+LIBC_PROG_BINUTILS
 AC_CHECK_TOOL(AR, ar)
 AC_CHECK_TOOL(RANLIB, ranlib, :)
 
@@ -568,7 +575,8 @@ else
 fi
 rm -f conftest*])
 if test $libc_cv_asm_symver_directive = yes &&
-   test $libc_cv_ld_version_script_option = yes; then
+   test $libc_cv_ld_version_script_option = yes &&
+   test $enable_versioning = yes; then
   VERSIONING=yes
   AC_DEFINE(DO_VERSIONING)
 else
@@ -749,6 +757,39 @@ fi
 rm -f conftest*])
 AC_SUBST(libc_cv_gcc_no_exceptions)dnl
 
+AC_CACHE_CHECK(for DWARF2 unwind info support, libc_cv_gcc_dwarf2_unwind_info,
+[cat > conftest.c <<EOF
+#line __oline__ "configure"
+static char __EH_FRAME_BEGIN__[];
+_start ()
+{
+  __register_frame (__EH_FRAME_BEGIN__);
+  __deregister_frame (__EH_FRAME_BEGIN__);
+}
+int __eh_pc;
+__throw () {}
+/* FIXME: this is fragile.  */
+malloc () {}
+strcmp () {}
+strlen () {}
+memcpy () {}
+memset () {}
+free () {}
+abort () {}
+EOF
+dnl No \ in command here because it ends up inside ''.
+if AC_TRY_COMMAND([${CC-cc} $CFLAGS
+			    -nostdlib -nostartfiles
+			    -o conftest conftest.c -lgcc >&AC_FD_CC]); then
+  libc_cv_gcc_dwarf2_unwind_info=yes
+else
+  libc_cv_gcc_dwarf2_unwind_info=no
+fi
+rm -f conftest*])
+if test $libc_cv_gcc_dwarf2_unwind_info = yes; then
+  AC_DEFINE(HAVE_DWARF2_UNWIND_INFO)
+fi
+
 ### End of automated tests.
 ### Now run sysdeps configure fragments.
 
@@ -876,6 +917,7 @@ if test $elf = yes; then
   AC_DEFINE(HAVE_ELF)
 fi
 
+AC_SUBST(static)
 AC_SUBST(shared)
 if test $shared = default; then
   if test $gnu_ld = yes; then
diff --git a/csu/Makefile b/csu/Makefile
index 1c9ebb1003..8388032e1d 100644
--- a/csu/Makefile
+++ b/csu/Makefile
@@ -32,7 +32,9 @@ csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o)
 extra-objs = start.o gmon-start.o \
 	     $(start-installed-name) g$(start-installed-name) \
 	     $(csu-dummies)
+ifeq ($(elf),yes)
 before-compile = $(objpfx)abi-tag.h
+endif
 omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \
 		             $(csu-dummies))
 install-lib = $(start-installed-name) g$(start-installed-name) \
diff --git a/elf/dl-profile.c b/elf/dl-profile.c
index 9b020e8fe9..dcbbcd026e 100644
--- a/elf/dl-profile.c
+++ b/elf/dl-profile.c
@@ -30,6 +30,7 @@
 #include <sys/gmon.h>
 #include <sys/gmon_out.h>
 #include <sys/mman.h>
+#include <sys/param.h>
 #include <sys/stat.h>
 #include <atomicity.h>
 
@@ -97,7 +98,7 @@
 					?? ?? ?? ??	<- ToPC#CGN
 	0038+(2*CN+2)*A+(CN-1)*4+K	?? ?? ?? ??	<- Count#CGN
 
-   We put (for now? no basic block information in the file since this would
+   We put (for now?) no basic block information in the file since this would
    introduce rase conditions among all the processes who want to write them.
 
    `K' is the number of count entries which is computed as
@@ -140,10 +141,10 @@ static uint32_t narcs;
    currently in the mmaped file.  At no point of time this has to be the
    same as NARCS.  If it is equal all entries from the file are in our
    lists.  */
-static uint32_t *narcsp;
+static volatile uint32_t *narcsp;
 
 /* Description of the currently profiled object.  */
-static long int state;
+static long int state = GMON_PROF_OFF;
 
 static volatile uint16_t *kcount;
 static size_t kcountsize;
@@ -260,13 +261,24 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
 
   fd = __open (filename, O_RDWR | O_CREAT, 0666);
   if (fd == -1)
-    /* We cannot write the profiling data so don't do anthing.  */
-    return;
+    {
+      /* We cannot write the profiling data so don't do anthing.  */
+      char buf[400];
+      _dl_sysdep_message (filename, ": cannot open file: ",
+			  _strerror_internal (errno, buf, sizeof buf),
+			  "\n", NULL);
+      return;
+    }
 
   if (fstat (fd, &st) < 0 || !S_ISREG (st.st_mode))
     {
       /* Not stat'able or not a regular file => don't use it.  */
-      close (fd);
+      char buf[400];
+      int errnum = errno;
+      __close (fd);
+      _dl_sysdep_message (filename, ": cannot stat file: ",
+			  _strerror_internal (errnum, buf, sizeof buf),
+			  "\n", NULL);
       return;
     }
 
@@ -286,9 +298,9 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
 	cannot_create:
 	  errnum = errno;
 	  __close (fd);
-	  _dl_sysdep_error (filename, ": cannot create file: ",
-			    _strerror_internal (errnum, buf, sizeof buf),
-			    "\n", NULL);
+	  _dl_sysdep_message (filename, ": cannot create file: ",
+			      _strerror_internal (errnum, buf, sizeof buf),
+			      "\n", NULL);
 	  return;
 	}
 
@@ -304,9 +316,9 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
       if (addr != NULL)
 	__munmap ((void *) addr, expected_size);
 
-      _dl_sysdep_error (filename,
-			": file is no correct profile data file for `",
-			_dl_profile, "'\n", NULL);
+      _dl_sysdep_message (filename,
+			  ": file is no correct profile data file for `",
+			  _dl_profile, "'\n", NULL);
       return;
     }
 
@@ -317,9 +329,9 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
       char buf[400];
       int errnum = errno;
       __close (fd);
-      _dl_sysdep_error (filename, ": cannot map file: ",
-			_strerror_internal (errnum, buf, sizeof buf),
-			"\n", NULL);
+      _dl_sysdep_message (filename, ": cannot map file: ",
+			  _strerror_internal (errnum, buf, sizeof buf),
+			  "\n", NULL);
       return;
     }
 
@@ -332,10 +344,8 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
 			 + sizeof (struct gmon_hist_hdr));
 
   /* Compute pointer to array of the arc information.  */
-  data = (struct here_cg_arc_record *) ((char *) kcount + kcountsize
-					+ 2 * sizeof (uint32_t));
-  narcsp = (uint32_t *) (hist + sizeof (uint32_t)
-			 + sizeof (struct gmon_hist_hdr) + sizeof (uint32_t));
+  narcsp = (uint32_t *) ((char *) kcount + kcountsize + sizeof (uint32_t));
+  data = (struct here_cg_arc_record *) ((char *) narcsp + sizeof (uint32_t));
 
   if (st.st_size == 0)
     {
@@ -346,8 +356,7 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
       memcpy (hist + sizeof (uint32_t), &hist_hdr,
 	      sizeof (struct gmon_hist_hdr));
 
-      *(uint32_t *) (hist + sizeof (uint32_t) + sizeof (struct gmon_hist_hdr)
-		     + kcountsize) = GMON_TAG_CG_ARC;
+      narcsp[-1] = GMON_TAG_CG_ARC;
     }
   else
     {
@@ -356,18 +365,16 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
 	  || *(uint32_t *) hist != GMON_TAG_TIME_HIST
 	  || memcmp (hist + sizeof (uint32_t), &hist_hdr,
 		     sizeof (struct gmon_hist_hdr)) != 0
-	  || (*(uint32_t *) (hist + sizeof (uint32_t)
-			    + sizeof (struct gmon_hist_hdr) + kcountsize)
-	      != GMON_TAG_CG_ARC))
+	  || narcsp[-1] != GMON_TAG_CG_ARC)
 	goto wrong_format;
     }
 
   /* Allocate memory for the froms data and the pointer to the tos records.  */
   tos = (uint16_t *) calloc (tossize + fromssize, 1);
-  if (froms == NULL)
+  if (tos == NULL)
     {
       __munmap ((void *) addr, expected_size);
-      _dl_sysdep_fatal ("Out of memory while initializing profiler", NULL);
+      _dl_sysdep_fatal ("Out of memory while initializing profiler\n", NULL);
       /* NOTREACHED */
     }
 
@@ -381,13 +388,12 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
 
      Loading the entries in reverse order should help to get the most
      frequently used entries at the front of the list.  */
-  for (idx = narcs = *narcsp; idx > 0; )
+  for (idx = narcs = MIN (*narcsp, fromlimit); idx > 0; )
     {
       size_t to_index;
       size_t newfromidx;
       --idx;
-      to_index = ((data[idx].self_pc - lowpc)
-		  / (hashfraction * sizeof (*tos)));
+      to_index = (data[idx].self_pc / (hashfraction * sizeof (*tos)));
       newfromidx = fromidx++;
       froms[newfromidx].here = &data[idx];
       froms[newfromidx].link = tos[to_index];
@@ -458,18 +464,18 @@ _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
 	  fromp = &froms[fromp->link];
 	while (fromp->link != 0 && fromp->here->from_pc != frompc);
 
-      if (fromp->link == 0)
+      if (fromp->here->from_pc != frompc)
 	{
 	  topcindex = &fromp->link;
 
 	check_new_or_add:
 	  /* Our entry is not among the entries we read so far from the
 	     data file.  Now see whether we have to update the list.  */
-	  while (narcs != *narcsp)
+	  while (narcs != *narcsp && narcs < fromlimit)
 	    {
 	      size_t to_index;
 	      size_t newfromidx;
-	      to_index = ((data[narcs].self_pc - lowpc)
+	      to_index = (data[narcs].self_pc
 			  / (hashfraction * sizeof (*tos)));
 	      newfromidx = fromidx++;
 	      froms[newfromidx].here = &data[narcs];
@@ -481,22 +487,22 @@ _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
 	  /* If we still have no entry stop searching and insert.  */
 	  if (*topcindex == 0)
 	    {
-	      fromidx = 1 + exchange_and_add (narcsp, 1);
-	      ++narcs;
+	      size_t newarc = 1 + exchange_and_add (narcsp, 1);
 
 	      /* In rare cases it could happen that all entries in FROMS are
 		 occupied.  So we cannot count this anymore.  */
-	      if (fromidx >= fromlimit)
+	      if (newarc >= fromlimit)
 		goto done;
 
-	      *topcindex = fromindex;
-	      fromp = &froms[fromindex];
-
-	      fromp = &froms[fromp->link];
+	      fromp = &froms[*topcindex = fromidx++];
 
+	      fromp->here = &data[newarc];
+	      data[newarc].from_pc = frompc;
+	      data[newarc].self_pc = selfpc;
+	      data[newarc].count = 0;
 	      fromp->link = 0;
-	      fromp->here->from_pc = frompc;
-	      fromp->here->count = 0;
+
+	      narcs++;
 
 	      break;
 	    }
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 46c0e1b8ab..e7132ed832 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -130,6 +130,8 @@ fixup (
   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				      \
@@ -147,13 +149,13 @@ fixup (
 				l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
 	ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
 
-	elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
-			    &l->l_versions[ndx],
-			    (void *) rel_addr);
+	here_version = &l->l_versions[ndx];
       }
     else
-      elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
-			  NULL, (void *) rel_addr);
+      here_version = NULL;
+
+    elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
+			here_version, (void *) rel_addr);
   }
 
   *_dl_global_scope_end = NULL;
@@ -194,6 +196,8 @@ profile_fixup (
   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				      \
@@ -211,19 +215,20 @@ profile_fixup (
 				l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
 	ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
 
-	elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
-			    &l->l_versions[ndx], (void *) &result);
+	here_version = &l->l_versions[ndx];
       }
     else
-      elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
-			  NULL, (void *) &result);
+      here_version = NULL;
+
+    elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
+			here_version, (void *) &result);
   }
 
   *_dl_global_scope_end = NULL;
-  (*mcount_fct) (retaddr, result);
+  (*mcount_fct) (retaddr, ELF_FIXUP_RETURN_VALUE (l, result));
 
   /* Return the address that was written by the relocation.  */
-  return ELF_FIXUP_RETURN_VALUE(l, result);
+  return ELF_FIXUP_RETURN_VALUE (l, result);
 }
 #endif
 
diff --git a/elf/sofini.c b/elf/sofini.c
index e44041b5ec..6da0062d06 100644
--- a/elf/sofini.c
+++ b/elf/sofini.c
@@ -7,3 +7,13 @@ static void (*const __CTOR_END__[1]) (void)
 static void (*const __DTOR_END__[1]) (void)
      __attribute__ ((unused, section (".dtors")))
      = { 0 };
+
+#ifdef HAVE_DWARF2_UNWIND_INFO
+/* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
+   this would be the 'length' field in a real FDE.  */
+
+typedef unsigned int ui32 __attribute__ ((mode (SI)));
+static const ui32 __FRAME_END__[1]
+     __attribute__ ((unused, section (".eh_frame")))
+     = { 0 };
+#endif
diff --git a/elf/soinit.c b/elf/soinit.c
index 0310b74b93..0c3f5b3163 100644
--- a/elf/soinit.c
+++ b/elf/soinit.c
@@ -17,6 +17,13 @@ run_hooks (void (*const list[]) (void))
     (**list) ();
 }
 
+#ifdef HAVE_DWARF2_UNWIND_INFO
+static const char __EH_FRAME_BEGIN__[]
+     __attribute__ ((section (".eh_frame")))
+     = { };
+extern void __register_frame (const void *);
+extern void __deregister_frame (const void *);
+#endif
 
 /* This function will be called from _init in init-first.c.  */
 void
@@ -24,6 +31,9 @@ __libc_global_ctors (void)
 {
   /* Call constructor functions.  */
   run_hooks (__CTOR_LIST__);
+#ifdef HAVE_DWARF2_UNWIND_INFO
+  __register_frame (__EH_FRAME_BEGIN__);
+#endif
 }
 
 
@@ -35,4 +45,7 @@ _fini (void)
 {
   /* Call destructor functions.  */
   run_hooks (__DTOR_LIST__);
+#ifdef HAVE_DWARF2_UNWIND_INFO
+  __deregister_frame (__EH_FRAME_BEGIN__);
+#endif
 }
diff --git a/io/ftwtest-sh b/io/ftwtest-sh
index f0cd56ab02..16dc1e1d47 100644
--- a/io/ftwtest-sh
+++ b/io/ftwtest-sh
@@ -13,7 +13,7 @@ testprogram=$2
 
 
 # First create our scenario:
-tmp=${TMPDIR:-/tmp}
+tmp=`echo ${TMPDIR:-/tmp} | sed 's|\(.\)/*$|\1|'`
 tmpdir=$tmp/ftwtest.d
 
 [ -f ${objpfx}elf/ld.so ] && ldso=${objpfx}elf/ld.so
@@ -46,18 +46,18 @@ LD_LIBRARY_PATH=$objpfx $ldso $testprogram $tmpdir |
     sort > $testout
 
 cat <<EOF | cmp $testout - || exit 1
-base = "/tmp/", file = "ftwtest.d", flag = FTW_D, level = 0
-base = "/tmp/ftwtest.d/", file = "bar", flag = FTW_D, level = 1
-base = "/tmp/ftwtest.d/", file = "baz", flag = FTW_F, level = 1
-base = "/tmp/ftwtest.d/", file = "foo", flag = FTW_D, level = 1
-base = "/tmp/ftwtest.d/bar/", file = "xo", flag = FTW_NS, level = 2
-base = "/tmp/ftwtest.d/foo/", file = "lvl1", flag = FTW_D, level = 2
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "file@1", flag = FTW_F, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "link@1", flag = FTW_SLN, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "lvl2", flag = FTW_D, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_D, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, level = 5
+base = "$tmp/", file = "ftwtest.d", flag = FTW_D, level = 0
+base = "$tmp/ftwtest.d/", file = "bar", flag = FTW_D, level = 1
+base = "$tmp/ftwtest.d/", file = "baz", flag = FTW_F, level = 1
+base = "$tmp/ftwtest.d/", file = "foo", flag = FTW_D, level = 1
+base = "$tmp/ftwtest.d/bar/", file = "xo", flag = FTW_NS, level = 2
+base = "$tmp/ftwtest.d/foo/", file = "lvl1", flag = FTW_D, level = 2
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "file@1", flag = FTW_F, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "link@1", flag = FTW_SLN, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "lvl2", flag = FTW_D, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_D, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, level = 5
 EOF
 rm $testout
 
@@ -65,18 +65,18 @@ LD_LIBRARY_PATH=$objpfx $ldso $testprogram --depth $tmpdir |
     sort > $testout
 
 cat <<EOF | cmp $testout - || exit 1
-base = "/tmp/", file = "ftwtest.d", flag = FTW_DP, level = 0
-base = "/tmp/ftwtest.d/", file = "bar", flag = FTW_DP, level = 1
-base = "/tmp/ftwtest.d/", file = "baz", flag = FTW_F, level = 1
-base = "/tmp/ftwtest.d/", file = "foo", flag = FTW_DP, level = 1
-base = "/tmp/ftwtest.d/bar/", file = "xo", flag = FTW_NS, level = 2
-base = "/tmp/ftwtest.d/foo/", file = "lvl1", flag = FTW_DP, level = 2
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "file@1", flag = FTW_F, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "link@1", flag = FTW_SLN, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "lvl2", flag = FTW_DP, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_DP, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, level = 5
+base = "$tmp/", file = "ftwtest.d", flag = FTW_DP, level = 0
+base = "$tmp/ftwtest.d/", file = "bar", flag = FTW_DP, level = 1
+base = "$tmp/ftwtest.d/", file = "baz", flag = FTW_F, level = 1
+base = "$tmp/ftwtest.d/", file = "foo", flag = FTW_DP, level = 1
+base = "$tmp/ftwtest.d/bar/", file = "xo", flag = FTW_NS, level = 2
+base = "$tmp/ftwtest.d/foo/", file = "lvl1", flag = FTW_DP, level = 2
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "file@1", flag = FTW_F, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "link@1", flag = FTW_SLN, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "lvl2", flag = FTW_DP, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_DP, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, level = 5
 EOF
 rm $testout
 
@@ -84,20 +84,20 @@ LD_LIBRARY_PATH=$objpfx $ldso $testprogram --phys $tmpdir |
     sort > $testout
 
 cat <<EOF | cmp $testout - || exit 1
-base = "/tmp/", file = "ftwtest.d", flag = FTW_D, level = 0
-base = "/tmp/ftwtest.d/", file = "bar", flag = FTW_D, level = 1
-base = "/tmp/ftwtest.d/", file = "baz", flag = FTW_F, level = 1
-base = "/tmp/ftwtest.d/", file = "foo", flag = FTW_D, level = 1
-base = "/tmp/ftwtest.d/bar/", file = "xo", flag = FTW_NS, level = 2
-base = "/tmp/ftwtest.d/foo/", file = "lvl1", flag = FTW_D, level = 2
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "file@1", flag = FTW_F, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "link@1", flag = FTW_SL, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "lvl2", flag = FTW_D, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "link@2", flag = FTW_SL, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_D, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, level = 5
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "link@3", flag = FTW_SL, level = 5
+base = "$tmp/", file = "ftwtest.d", flag = FTW_D, level = 0
+base = "$tmp/ftwtest.d/", file = "bar", flag = FTW_D, level = 1
+base = "$tmp/ftwtest.d/", file = "baz", flag = FTW_F, level = 1
+base = "$tmp/ftwtest.d/", file = "foo", flag = FTW_D, level = 1
+base = "$tmp/ftwtest.d/bar/", file = "xo", flag = FTW_NS, level = 2
+base = "$tmp/ftwtest.d/foo/", file = "lvl1", flag = FTW_D, level = 2
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "file@1", flag = FTW_F, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "link@1", flag = FTW_SL, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "lvl2", flag = FTW_D, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "link@2", flag = FTW_SL, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_D, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, level = 5
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "link@3", flag = FTW_SL, level = 5
 EOF
 rm $testout
 
@@ -108,18 +108,18 @@ LD_LIBRARY_PATH=$objpfx $ldso $testprogram --chdir $tmpdir |
     sort > $testout
 
 cat <<EOF | cmp $testout - || exit 1
-base = "/tmp/", file = "ftwtest.d", flag = FTW_D, cwd = /tmp, level = 0
-base = "/tmp/ftwtest.d/", file = "bar", flag = FTW_D, cwd = /tmp/ftwtest.d, level = 1
-base = "/tmp/ftwtest.d/", file = "baz", flag = FTW_F, cwd = /tmp/ftwtest.d, level = 1
-base = "/tmp/ftwtest.d/", file = "foo", flag = FTW_D, cwd = /tmp/ftwtest.d, level = 1
-base = "/tmp/ftwtest.d/bar/", file = "xo", flag = FTW_F, cwd = /tmp/ftwtest.d/bar, level = 2
-base = "/tmp/ftwtest.d/foo/", file = "lvl1", flag = FTW_D, cwd = /tmp/ftwtest.d/foo, level = 2
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "file@1", flag = FTW_F, cwd = /tmp/ftwtest.d/foo/lvl1, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "link@1", flag = FTW_SLN, cwd = /tmp/ftwtest.d/foo/lvl1, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/", file = "lvl2", flag = FTW_D, cwd = /tmp/ftwtest.d/foo/lvl1, level = 3
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, cwd = /tmp/ftwtest.d/foo/lvl1/lvl2, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_D, cwd = /tmp/ftwtest.d/foo/lvl1/lvl2, level = 4
-base = "/tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, cwd = /tmp/ftwtest.d/foo/lvl1/lvl2/lvl3, level = 5
+base = "$tmp/", file = "ftwtest.d", flag = FTW_D, cwd = $tmp, level = 0
+base = "$tmp/ftwtest.d/", file = "bar", flag = FTW_D, cwd = $tmp/ftwtest.d, level = 1
+base = "$tmp/ftwtest.d/", file = "baz", flag = FTW_F, cwd = $tmp/ftwtest.d, level = 1
+base = "$tmp/ftwtest.d/", file = "foo", flag = FTW_D, cwd = $tmp/ftwtest.d, level = 1
+base = "$tmp/ftwtest.d/bar/", file = "xo", flag = FTW_F, cwd = $tmp/ftwtest.d/bar, level = 2
+base = "$tmp/ftwtest.d/foo/", file = "lvl1", flag = FTW_D, cwd = $tmp/ftwtest.d/foo, level = 2
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "file@1", flag = FTW_F, cwd = $tmp/ftwtest.d/foo/lvl1, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "link@1", flag = FTW_SLN, cwd = $tmp/ftwtest.d/foo/lvl1, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/", file = "lvl2", flag = FTW_D, cwd = $tmp/ftwtest.d/foo/lvl1, level = 3
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "file@2", flag = FTW_F, cwd = $tmp/ftwtest.d/foo/lvl1/lvl2, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/", file = "lvl3", flag = FTW_D, cwd = $tmp/ftwtest.d/foo/lvl1/lvl2, level = 4
+base = "$tmp/ftwtest.d/foo/lvl1/lvl2/lvl3/", file = "file@3", flag = FTW_F, cwd = $tmp/ftwtest.d/foo/lvl1/lvl2/lvl3, level = 5
 EOF
 rm $testout
 
diff --git a/libc.map b/libc.map
index 3f3d28d485..c83fb38b22 100644
--- a/libc.map
+++ b/libc.map
@@ -89,6 +89,10 @@ GLIBC_2.0 {
     _rpc_dtablesize; _null_auth; _seterr_reply;
     __res_randomid;
 
+    # Exception handling support functions from libgcc
+    __register_frame; __register_frame_table; __deregister_frame;
+    __frame_state_for;
+
     # variables in normal name space
     argp_err_exit_status; argp_program_bug_address; argp_program_version;
     argp_program_version_hook;
diff --git a/locale/setlocale.c b/locale/setlocale.c
index bdc65f523e..79f15ccb40 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -361,7 +361,7 @@ setlocale (int category, const char *locale)
   else
     {
       struct locale_data *newdata = NULL;
-      const char *newname = locale;
+      const char *newname[1] = { locale };
 
       /* Protect global data.  */
       __libc_lock_lock (__libc_setlocale_lock);
@@ -370,7 +370,7 @@ setlocale (int category, const char *locale)
 	{
 	  /* Only actually load the data if anything will use it.  */
 	  newdata = _nl_find_locale (locale_path, locale_path_len, category,
-				     &newname);
+				     &newname[0]);
 	  if (newdata == NULL)
 	    goto abort_single;
 
@@ -381,19 +381,19 @@ setlocale (int category, const char *locale)
 	}
 
       /* Create new composite name.  */
-      composite = new_composite_name (category, &newname);
+      composite = new_composite_name (category, newname);
       if (composite == NULL)
 	{
 	  /* Say that we don't have any data loaded.  */
 	abort_single:
-	  newname = NULL;
+	  newname[0] = NULL;
 	}
       else
 	{
 	  if (_nl_current[category] != NULL)
 	    setdata (category, newdata);
 
-	  setname (category, newname);
+	  setname (category, newname[0]);
 	  setname (LC_ALL, composite);
 	}
 
@@ -403,6 +403,6 @@ setlocale (int category, const char *locale)
       /* Free the resources (the locale path variable.  */
       free (locale_path);
 
-      return (char *) newname;
+      return (char *) newname[0];
     }
 }
diff --git a/manual/maint.texi b/manual/maint.texi
index d8e835f441..2818270103 100644
--- a/manual/maint.texi
+++ b/manual/maint.texi
@@ -272,6 +272,7 @@ i@var{x}86-@var{anything}-gnu
 i@var{x}86-@var{anything}-linux
 m68k-@var{anything}-linux
 powerpc-@var{anything}-linux
+sparc64-@var{anything}-linux
 @end smallexample
 
 Former releases of this library (version 1.09.1 and perhaps earlier
diff --git a/math/Makefile b/math/Makefile
index 62619111c9..bc54d57c43 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -51,7 +51,7 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod	\
 	     s_floor s_frexp s_ilogb s_ldexp s_log1p s_logb 		\
 	     s_modf s_nextafter s_rint s_scalbn s_significand		\
 	     s_sin s_tan s_tanh w_acos w_acosh w_asin			\
-	     w_atan2 w_atanh w_cosh w_drem w_exp w_fmod w_gamma		\
+	     w_atan2 w_atanh w_cosh w_drem w_exp w_exp2 w_fmod w_gamma	\
 	     w_hypot w_j0 w_j1 w_jn w_lgamma w_lgamma_r			\
 	     w_log w_log10 w_pow w_remainder w_scalb w_sinh w_sqrt	\
 	     s_signbit s_fpclassify s_fmax s_fmin s_fdim s_nan s_trunc	\
@@ -78,7 +78,7 @@ distribute += $(long-c-yes:=.c)
 # Rules for the test suite.
 tests = test-float test-double $(test-longdouble-$(long-double-fcts)) \
 	test-ifloat test-idouble test-matherr test-fenv \
-	atest-exp atest-sincos
+	atest-exp atest-sincos atest-exp2 # test-reduce
 # We do the `long double' tests only if this data type is available and
 # distrinct from `double'.
 test-longdouble-yes = test-ldouble test-ildoubl
@@ -93,8 +93,10 @@ LDLIBS-test-float = math/libm
 LDLIBS-test-double = math/libm
 LDLIBS-test-ldouble = math/libm
 LDLIBS-test-matherr = math/libm
+LDLIBS-test-reduce = math/libm
 LDLIBS-atest-exp = math/libm
 LDLIBS-atest-sincos = math/libm
+LDLIBS-atest-exp2 = math/libm
 
 distribute += libm-test.c
 
diff --git a/math/atest-exp2.c b/math/atest-exp2.c
new file mode 100644
index 0000000000..95e72aa507
--- /dev/null
+++ b/math/atest-exp2.c
@@ -0,0 +1,240 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Geoffrey Keating <Geoff.Keating@anu.edu.au>, 1997.
+
+   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 <stdio.h>
+#include <math.h>
+#include <gmp.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#define PRINT_ERRORS 0
+
+#define TOL 80
+#define N2 18
+#define FRAC (32*4)
+
+#define mpbpl (CHAR_BIT * sizeof (mp_limb_t))
+#define SZ (FRAC / mpbpl + 1)
+typedef mp_limb_t mp1[SZ], mp2[SZ * 2];
+
+/* This string has 101 hex digits.  */
+static const char exp1[102] = "2" /* point */
+"b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a7"
+"84d9045190cfef324e7738926cfbe5f4bf8d8d8c31d763da07";
+static const char exp_m1[102] = "0" /* point */
+"5e2d58d8b3bcdf1abadec7829054f90dda9805aab56c773330"
+"24b9d0a507daedb16400bf472b4215b8245b669d90d27a5aea";
+
+static const char hexdig[] = "0123456789abcdef";
+
+void
+print_mpn_fp (const mp_limb_t *x, unsigned int dp, unsigned int base)
+{
+   unsigned int i;
+   mp1 tx;
+
+   memcpy (tx, x, sizeof (mp1));
+   if (base == 16)
+     fputs ("0x", stdout);
+   assert (x[SZ-1] < base);
+   fputc (hexdig[x[SZ - 1]], stdout);
+   fputc ('.', stdout);
+   for (i = 0; i < dp; i++)
+     {
+       tx[SZ - 1] = 0;
+       mpn_mul_1 (tx, tx, SZ, base);
+       assert (tx[SZ - 1] < base);
+       fputc (hexdig[tx[SZ - 1]], stdout);
+     }
+}
+
+void
+read_mpn_hex(mp_limb_t *x, const char *str)
+{
+  int i;
+
+  memset (x, 0, sizeof (mp1));
+  for (i = -1; i < 100 && i < FRAC / 4; ++i)
+    x[(FRAC - i * 4 - 4) / mpbpl] |= (strchr (hexdig, str[i + 1]) - hexdig
+				      << (FRAC - i * 4 - 4) % mpbpl);
+}
+
+static mp_limb_t *get_log2(void) __attribute__((const));
+static mp_limb_t *
+get_log2(void)
+{
+  static mp1 log2_m;
+  static int log2_m_inited = 0;
+  static const char log2[102] = "0" /* point */
+    "b17217f7d1cf79abc9e3b39803f2f6af40f343267298b62d8a"
+    "0d175b8baafa2be7b876206debac98559552fb4afa1b10ed2e";
+
+  if (!log2_m_inited)
+    {
+      read_mpn_hex (log2_m, log2);
+      log2_m_inited = 1;
+    }
+  return log2_m;
+}
+
+/* Compute e^x.  */
+void
+exp_mpn (mp1 ex, mp1 x)
+{
+   unsigned int n;
+   mp1 xp;
+   mp2 tmp;
+   mp_limb_t chk, round;
+   mp1 tol;
+
+   memset (xp, 0, sizeof (mp1));
+   memset (ex, 0, sizeof (mp1));
+   xp[FRAC / mpbpl] = 1 << FRAC % mpbpl;
+   memset (tol, 0, sizeof (mp1));
+   tol[(FRAC - TOL) / mpbpl] = 1 << (FRAC - TOL) % mpbpl;
+
+   n = 0;
+
+   do
+     {
+       /* Calculate sum(x^n/n!) until the next term is sufficiently small.  */
+
+       mpn_mul_n (tmp, xp, x, SZ);
+       assert(tmp[SZ * 2 - 1] == 0);
+       if (n > 0)
+	 round = mpn_divmod_1 (xp, tmp + FRAC / mpbpl, SZ, n);
+       chk = mpn_add_n (ex, ex, xp, SZ);
+       assert (chk == 0);
+       ++n;
+       assert (n < 80); /* Catch too-high TOL.  */
+     }
+   while (n < 10 || mpn_cmp (xp, tol, SZ) >= 0);
+}
+
+/* Calculate 2^x.  */
+void
+exp2_mpn (mp1 ex, mp1 x)
+{
+  mp2 tmp;
+  mpn_mul_n (tmp, x, get_log2 (), SZ);
+  assert(tmp[SZ * 2 - 1] == 0);
+  exp_mpn (ex, tmp + FRAC / mpbpl);
+}
+
+
+static int
+mpn_bitsize(const mp_limb_t *SRC_PTR, mp_size_t SIZE)
+{
+  int i, j;
+  for (i = SIZE - 1; i > 0; --i)
+    if (SRC_PTR[i] != 0)
+      break;
+  for (j = mpbpl - 1; j > 0; --j)
+    if ((SRC_PTR[i] & 1 << j) != 0)
+      break;
+
+  return i * 32 + j;
+}
+
+int
+main (void)
+{
+  mp1 ex, x, xt, e2, e3;
+  int i;
+  int errors = 0;
+  int failures = 0;
+  mp1 maxerror;
+  int maxerror_s = 0;
+  const double sf = pow (2, mpbpl);
+
+  /* assert(mpbpl == mp_bits_per_limb); */
+  assert(FRAC / mpbpl * mpbpl == FRAC);
+
+  memset (maxerror, 0, sizeof (mp1));
+  memset (xt, 0, sizeof (mp1));
+  xt[(FRAC - N2) / mpbpl] = 1 << (FRAC - N2) % mpbpl;
+
+  for (i = 0; i < (1 << N2); ++i)
+    {
+      int e2s, e3s, j;
+      double de2;
+
+      mpn_mul_1 (x, xt, SZ, i);
+      exp2_mpn (ex, x);
+      de2 = exp2 (i / (double) (1 << N2));
+      for (j = SZ - 1; j >= 0; --j)
+	{
+	  e2[j] = (mp_limb_t) de2;
+	  de2 = (de2 - e2[j]) * sf;
+	}
+      if (mpn_cmp (ex, e2, SZ) >= 0)
+	mpn_sub_n (e3, ex, e2, SZ);
+      else
+	mpn_sub_n (e3, e2, ex, SZ);
+
+      e2s = mpn_bitsize (e2, SZ);
+      e3s = mpn_bitsize (e3, SZ);
+      if (e3s > 1 && e2s - e3s < 54)
+	{
+#if PRINT_ERRORS
+	  printf ("%06x ", i * (0x100000 / (1 << N2)));
+	  print_mpn_fp (ex, (FRAC / 4) + 1, 16);
+	  putchar ('\n');
+	  fputs ("       ",stdout);
+	  print_mpn_fp (e2, (FRAC / 4) + 1, 16);
+	  putchar ('\n');
+	  printf (" %c     ",
+		  e2s - e3s < 54 ? e2s - e3s == 53 ? 'e' : 'F' : 'P');
+	  print_mpn_fp (e3, (FRAC / 4) + 1, 16);
+	  putchar ('\n');
+#endif
+	  errors += (e2s - e3s == 53);
+	  failures += (e2s - e3s < 53);
+	}
+      if (e3s >= maxerror_s
+	  && mpn_cmp (e3, maxerror, SZ) > 0)
+	{
+	  memcpy (maxerror, e3, sizeof (mp1));
+	  maxerror_s = e3s;
+	}
+    }
+
+  /* Check exp_mpn against precomputed value of exp(1).  */
+  memset (x, 0, sizeof (mp1));
+  x[FRAC / mpbpl] = 1 << FRAC % mpbpl;
+  exp_mpn (ex, x);
+  read_mpn_hex (e2, exp1);
+  if (mpn_cmp (ex, e2, SZ) >= 0)
+    mpn_sub_n (e3, ex, e2, SZ);
+  else
+    mpn_sub_n (e3, e2, ex, SZ);
+
+  printf ("%d failures; %d errors; error rate %0.2f%%\n", failures, errors,
+	  errors * 100.0 / (double) (1 << N2));
+  fputs ("maximum error:   ", stdout);
+  print_mpn_fp (maxerror, (FRAC / 4) + 1, 16);
+  putchar ('\n');
+  fputs ("error in exp(1): ", stdout);
+  print_mpn_fp (e3, (FRAC / 4) + 1, 16);
+  putchar ('\n');
+
+  return failures == 0 ? 0 : 1;
+}
diff --git a/math/libm-test.c b/math/libm-test.c
index da1de8385f..2075adcb59 100644
--- a/math/libm-test.c
+++ b/math/libm-test.c
@@ -1114,6 +1114,9 @@ exp2_test (void)
   check_isinfp ("exp2 (+inf) == +inf", FUNC(exp2) (plus_infty));
   check ("exp2 (-inf) == 0", FUNC(exp2) (minus_infty), 0);
   check ("exp2 (10) == 1024", FUNC(exp2) (10), 1024);
+  check ("exp2 (-1) == 0.5", FUNC(exp2) (-1), 0.5);
+  check_isinfp ("exp2 (1e6) == +inf", FUNC(exp2) (1e6));
+  check ("exp2 (-1e6) == 0", FUNC(exp2) (-1e6), 0);
 }
 
 
diff --git a/math/math_private.h b/math/math_private.h
index 74b729d419..4b3b5be3bf 100644
--- a/math/math_private.h
+++ b/math/math_private.h
@@ -252,6 +252,7 @@ extern double __ieee754_atanh __P((double));
 extern double __ieee754_asin __P((double));
 extern double __ieee754_atan2 __P((double,double));
 extern double __ieee754_exp __P((double));
+extern double __ieee754_exp2 __P((double));
 extern double __ieee754_cosh __P((double));
 extern double __ieee754_fmod __P((double,double));
 extern double __ieee754_pow __P((double,double));
@@ -290,6 +291,7 @@ extern float __ieee754_atanhf __P((float));
 extern float __ieee754_asinf __P((float));
 extern float __ieee754_atan2f __P((float,float));
 extern float __ieee754_expf __P((float));
+extern float __ieee754_exp2f __P((float));
 extern float __ieee754_coshf __P((float));
 extern float __ieee754_fmodf __P((float,float));
 extern float __ieee754_powf __P((float,float));
@@ -327,6 +329,7 @@ extern long double __ieee754_atanhl __P((long double));
 extern long double __ieee754_asinl __P((long double));
 extern long double __ieee754_atan2l __P((long double,long double));
 extern long double __ieee754_expl __P((long double));
+extern long double __ieee754_exp2l __P((long double));
 extern long double __ieee754_coshl __P((long double));
 extern long double __ieee754_fmodl __P((long double,long double));
 extern long double __ieee754_powl __P((long double,long double));
diff --git a/math/test-reduce.c b/math/test-reduce.c
new file mode 100644
index 0000000000..5149ead341
--- /dev/null
+++ b/math/test-reduce.c
@@ -0,0 +1,207 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Geoffrey Keating <Geoff.Keating@anu.edu.au>, 1997.
+
+   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.  */
+
+/* This is a generic program for comparing two precisions of a one-input
+   mathematical function.  It is amazingly good at detecting when GCC
+   folds constants improperly.  */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <math.h>
+#include <ieee754.h>
+#include <fenv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#define TSMALL float
+#define RSMALL(rfun) ({ unsigned rnum = (rfun); *(float *) &rnum; })
+#define TBIG double
+#define XDIFF (24)
+#define REDUCE(x) \
+   ({ union ieee754_float u = { x }; u.ieee.exponent = 0x80; x = u.f; })
+#define ABS(x) fabs(x)
+
+#define string_0(x) #x
+#define string_1(x) string_0(x)
+#define TBIG_NAME string_1(TBIG)
+#define TSMALL_NAME string_1(TSMALL)
+
+#define R_NEAREST 1
+#define R_ZERO 2
+#define R_UP 4
+#define R_DOWN 8
+#define R_ALL (R_NEAREST|R_ZERO|R_UP|R_DOWN)
+static fenv_t rmodes[4];
+static const char * const rmnames[4] =
+{ "near","zero","+Inf","-Inf" };
+
+static int quiet = 0;
+
+#ifdef FE_ALL_INVALID
+static const int invalid_exceptions = (FE_ALL_INVALID
+				       | FE_INVALID | FE_DIVBYZERO);
+#else
+static const int invalid_exceptions = (FE_INVALID | FE_DIVBYZERO);
+#endif
+
+static int
+checkit (char *fname,
+	 TSMALL (*fsmall) (TSMALL), TBIG (*fbig) (TBIG),
+	 unsigned smalltries, unsigned largetries)
+{
+  unsigned int i, nerrors = 0, nwarn;
+
+  int tryone (TSMALL fval)
+    {
+      int rmode;
+      int excepts, exceptsb;
+      TSMALL fres;
+      TBIG fvalb, fresb, diff;
+      char warn;
+
+      fvalb = (TBIG) fval;
+
+      for (rmode = 0; rmode < 4; ++rmode)
+	{
+	  fesetenv (rmodes + rmode);
+	  fres = fsmall (fval);
+	  excepts = fetestexcept (invalid_exceptions);
+	  fesetenv (rmodes + rmode);
+	  fresb = fbig (fvalb);
+	  exceptsb = fetestexcept (invalid_exceptions);
+
+	  if (excepts != exceptsb)
+	    {
+	      unsigned char *fvp = (unsigned char *) &fval;
+	      size_t j;
+
+	      printf ("%s(", fname);
+	      for (j = 0; j < sizeof (TSMALL); j++)
+		printf ("%02x", fvp[j]);
+	      printf ("),%s: exceptions %s: %08x, %s: %08x\n",
+		      rmnames[rmode],
+		      TBIG_NAME, exceptsb, TSMALL_NAME, excepts);
+	      if (++nerrors > 10)
+		return 1;
+	    }
+
+	  diff = ABS (fres - (TSMALL) fresb);
+	  if (fres == (TSMALL) fresb
+	      || isnan (fres) && isnan (fresb)
+	      || logb (fresb) - logb (diff) < XDIFF - 1)
+	    continue;
+
+	  if (logb (fresb) - logb (diff) < XDIFF)
+	    {
+	      if (++nwarn > 10 || quiet)
+		continue;
+	      warn = 'w';
+	    }
+	  else
+	    {
+	      if (++nerrors > 10)
+		return 1;
+	      warn = 'e';
+	    }
+
+	  {
+	    TSMALL fresbs = (TSMALL) fresb;
+	    unsigned char *fvp = (unsigned char *) &fval;
+	    unsigned char *frp = (unsigned char *) &fres;
+	    unsigned char *frpb = (unsigned char *) &fresb;
+	    unsigned char *frpbs = (unsigned char *) &fresbs;
+	    size_t j;
+
+	    printf ("%s(",fname);
+	    for (j = 0; j < sizeof (TSMALL); ++j)
+	      printf ("%02x", fvp[j]);
+	    printf ("),%s: %s ", rmnames[rmode], TBIG_NAME);
+	    for (j = 0; j < sizeof (TBIG); ++j)
+	      printf ("%02x", frpb[j]);
+	    printf (" (");
+	    for (j = 0; j < sizeof (TSMALL); ++j)
+	      printf ("%02x", frpbs[j]);
+	    printf ("), %s ", TSMALL_NAME);
+	    for (j = 0; j < sizeof (TSMALL); ++j)
+	      printf ("%02x", frp[j]);
+	    printf (" %c\n", warn);
+	  }
+	}
+      return 0;
+    }
+
+  nwarn = 0;
+  for (i = 0; i < smalltries; i++)
+    {
+      TSMALL fval;
+
+      fval = RSMALL (rand () ^ rand () << 16);
+      REDUCE (fval);
+      if (tryone (fval))
+	break;
+    }
+
+  printf ("%s-small: %d errors, %d (%0.2f%%) inaccuracies\n",
+	  fname, nerrors, nwarn,
+	  nwarn * 0.25 / ((double) smalltries));
+
+  nwarn = 0;
+  for (i = 0; i < largetries; ++i)
+    {
+      TSMALL fval;
+
+      fval = RSMALL (rand () ^ rand () << 16);
+      if (tryone (fval))
+	break;
+    }
+
+  printf ("%s-large: %d errors, %d (%0.2f%%) inaccuracies\n",
+	  fname, nerrors, nwarn,
+	  nwarn * 0.25 / ((double) largetries));
+  return nerrors == 0;
+}
+
+int
+main (void)
+{
+  int r;
+
+  _LIB_VERSION = _IEEE_;
+
+  /* Set up environments for rounding modes.  */
+  fesetenv (FE_DFL_ENV);
+  fesetround (FE_TONEAREST);
+  fegetenv (rmodes + 0);
+  fesetround (FE_TOWARDSZERO);
+  fegetenv (rmodes + 1);
+  fesetround (FE_UPWARD);
+  fegetenv (rmodes + 2);
+  fesetround (FE_DOWNWARD);
+  fegetenv (rmodes + 3);
+
+  /* Seed the RNG.  */
+  srand (time (0));
+
+  /* Do it.  */
+  r  = checkit ("exp2", exp2f, exp2, 1 << 20, 1 << 15);
+  r &= checkit ("exp",  expf,  exp,  1 << 20, 1 << 15);
+  return r ? 0 : 1;
+}
diff --git a/nis/Banner b/nis/Banner
index 3a1729c3b0..d6cf7a9f5e 100644
--- a/nis/Banner
+++ b/nis/Banner
@@ -1 +1 @@
-NIS(YP)/NIS+ NSS modules 0.13 by Thorsten Kukuk
+NIS(YP)/NIS+ NSS modules 0.14 by Thorsten Kukuk
diff --git a/nis/Makefile b/nis/Makefile
index 9b72429f8f..82c5f24963 100644
--- a/nis/Makefile
+++ b/nis/Makefile
@@ -51,7 +51,7 @@ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
 		  nis_removemember nis_creategroup nis_destroygroup\
 		  nis_print_group_entry nis_domain_of nis_domain_of_r\
 		  nis_modify nis_remove nis_add nis_defaults lckcache\
-		  nis_findserv
+		  nis_findserv nis_callback
 libnsl-map	= libnsl.map
 
 libnss_compat-routines	:= $(addprefix compat-,grp pwd spwd) nisplus-parser
diff --git a/nis/TODO b/nis/TODO
index f34bc09a06..8528de7e1a 100644
--- a/nis/TODO
+++ b/nis/TODO
@@ -1,11 +1,3 @@
 
  * nis_addmember: Where checks for duplicate group members ? nisgrpadm or
 		  nis_addmember ?
-
- * nis_table.c: nis_list(): 
-	Missing flags: FOLLOW_PATH, ALL_RESULTS
-	callback: Don't simulate it, use server callback thread
-
- * Missing flags:
-	- FOLLOW_PATH	(nis_list, not supported)
-	- ALL_RESULTS	(nis_list, not supported, needs server callback)
diff --git a/nis/nis_add.c b/nis/nis_add.c
index 9baf4e8278..6693a25766 100644
--- a/nis/nis_add.c
+++ b/nis/nis_add.c
@@ -59,7 +59,8 @@ nis_add (const_nis_name name, const nis_object *obj)
   if ((status = __do_niscall (req.ns_object.ns_object_val[0].zo_domain,
 			      NIS_ADD, (xdrproc_t) xdr_ns_request,
 			      (caddr_t) &req, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+			      (caddr_t) res, MASTER_ONLY,
+			      NULL)) != RPC_SUCCESS)
     res->status = status;
 
   req.ns_object.ns_object_val[0].zo_name = p1;
diff --git a/nis/nis_cache.c b/nis/nis_cache.c
index 4c0ea7b186..e10b8c07fd 100644
--- a/nis/nis_cache.c
+++ b/nis/nis_cache.c
@@ -143,7 +143,7 @@ __cache_refresh (nis_name name)
   if (cache_clnt == NULL)
     result = NIS_FAIL;
   else if (clnt_call (cache_clnt, NIS_CACHE_REFRESH_ENTRY,
-		      (xdrproc_t) xdr_wrapstring, (caddr_t) name,
+		      (xdrproc_t) xdr_wrapstring, (caddr_t) &name,
 		      (xdrproc_t) xdr_void, &clnt_res, TIMEOUT)
 	   != RPC_SUCCESS)
     {
diff --git a/nis/nis_call.c b/nis/nis_call.c
index 672755055b..fd777f5948 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -98,8 +98,7 @@ __bind_next (dir_binding *bind)
   if (bind->server_used >= bind->server_len)
     bind->server_used = 0;
 
-  for (j = bind->current_ep + 1;
-       j < bind->server_val[bind->server_used].ep.ep_len; ++j)
+  for (j = 0; j < bind->server_val[bind->server_used].ep.ep_len; ++j)
     if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].family,
 		"inet") == 0)
       if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].proto,
@@ -280,7 +279,7 @@ __bind_create (const nis_server *serv_val, u_int serv_len, u_long flags)
 nis_error
 __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
 	       xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp,
-	       u_long flags)
+	       u_long flags, nis_cb *cb)
 {
   enum clnt_stat result;
   nis_error retcode;
@@ -315,63 +314,83 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
 	{
 	  switch (prog)
 	    {
+	    case NIS_IBLIST:
+	      if ((((nis_result *)resp)->status == NIS_CBRESULTS) &&
+		  (cb != NULL))
+		{
+		  __nis_do_callback(dbp, &((nis_result *)resp)->cookie, cb);
+		  break;
+		}
+	      /* Yes, this is correct. If we doesn't have to start
+		 a callback, look if we have to search another server */
 	    case NIS_LOOKUP:
 	    case NIS_ADD:
 	    case NIS_MODIFY:
 	    case NIS_REMOVE:
-	    case NIS_IBLIST:
 	    case NIS_IBADD:
 	    case NIS_IBMODIFY:
 	    case NIS_IBREMOVE:
 	    case NIS_IBFIRST:
 	    case NIS_IBNEXT:
-	      if ((((nis_result *)xres)->status == NIS_NOTFOUND) ||
-		  (((nis_result *)xres)->status == NIS_NOSUCHNAME) ||
-		  (((nis_result *)xres)->status == NIS_NOT_ME))
+	      if ((((nis_result *)resp)->status == NIS_NOTFOUND) ||
+		  (((nis_result *)resp)->status == NIS_NOSUCHNAME) ||
+		  (((nis_result *)resp)->status == NIS_NOT_ME))
 		{
 		  if (__bind_next (dbp) == NIS_SUCCESS)
-		    while (__bind_connect (dbp) != NIS_SUCCESS)
-		      {
-			if (__bind_next (dbp) != NIS_SUCCESS)
-			  {
-			    __bind_destroy (dbp);
-			    return NIS_SUCCESS;
-			  }
-		      }
+		    {
+		      while (__bind_connect (dbp) != NIS_SUCCESS)
+			{
+			  if (__bind_next (dbp) != NIS_SUCCESS)
+			    {
+			      __bind_destroy (dbp);
+			      return NIS_SUCCESS;
+			    }
+			}
+		    }
+		  else
+		    break; /* No more servers to search in */
 		  goto again;
 		}
 	    case NIS_FINDDIRECTORY:
-	      if ((((fd_result *)xres)->status == NIS_NOTFOUND) ||
-		  (((fd_result *)xres)->status == NIS_NOSUCHNAME) ||
-		  (((fd_result *)xres)->status == NIS_NOT_ME))
+	      if ((((fd_result *)resp)->status == NIS_NOTFOUND) ||
+		  (((fd_result *)resp)->status == NIS_NOSUCHNAME) ||
+		  (((fd_result *)resp)->status == NIS_NOT_ME))
 		{
 		  if (__bind_next (dbp) == NIS_SUCCESS)
-		    while (__bind_connect (dbp) != NIS_SUCCESS)
-		      {
-			if (__bind_next (dbp) != NIS_SUCCESS)
-			  {
-			    __bind_destroy (dbp);
-			    return NIS_SUCCESS;
-			  }
-		      }
+		    {
+		      while (__bind_connect (dbp) != NIS_SUCCESS)
+			{
+			  if (__bind_next (dbp) != NIS_SUCCESS)
+			    {
+			      __bind_destroy (dbp);
+			      return NIS_SUCCESS;
+			    }
+			}
+		    }
+		  else
+		    break; /* No more servers to search in */
 		  goto again;
 		}
 	      break;
 	    case NIS_DUMPLOG: /* log_result */
 	    case NIS_DUMP:
-	      if ((((log_result *)xres)->lr_status == NIS_NOTFOUND) ||
-		  (((log_result *)xres)->lr_status == NIS_NOSUCHNAME) ||
-		  (((log_result *)xres)->lr_status == NIS_NOT_ME))
+	      if ((((log_result *)resp)->lr_status == NIS_NOTFOUND) ||
+		  (((log_result *)resp)->lr_status == NIS_NOSUCHNAME) ||
+		  (((log_result *)resp)->lr_status == NIS_NOT_ME))
 		{
 		  if (__bind_next (dbp) == NIS_SUCCESS)
-		    while (__bind_connect (dbp) != NIS_SUCCESS)
-		      {
-			if (__bind_next (dbp) != NIS_SUCCESS)
-			  {
-			    __bind_destroy (dbp);
-			    return NIS_SUCCESS;
-			  }
-		      }
+		    {
+		      while (__bind_connect (dbp) != NIS_SUCCESS)
+			{
+			  if (__bind_next (dbp) != NIS_SUCCESS)
+			    {
+			      __bind_destroy (dbp);
+			      return NIS_SUCCESS;
+			    }
+			}
+		    }
+		  else
+		    break; /* No more servers to search in */
 		  goto again;
 		}
 	      break;
@@ -523,7 +542,8 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
 
 nis_error
 __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
-	      caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags)
+	      caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags,
+	      nis_cb *cb)
 {
   nis_error retcode;
   directory_obj *dir = NULL;
@@ -561,7 +581,7 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
 
 
   retcode = __do_niscall2 (server, server_len, prog, xargs, req, xres, resp,
-			   flags);
+			   flags, cb);
 
   nis_free_directory (dir);
 
diff --git a/nis/nis_callback.c b/nis/nis_callback.c
new file mode 100644
index 0000000000..48c1950dd7
--- /dev/null
+++ b/nis/nis_callback.c
@@ -0,0 +1,339 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <rpc/pmap_clnt.h>
+#include <string.h>
+#include <memory.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <rpcsvc/nis.h>
+#include <bits/libc-lock.h>
+
+#include "nis_intern.h"
+
+extern void get_myaddress (struct sockaddr_in *addr);
+
+/* Sorry, we are not able to make this threadsafe. Stupid. But some
+   functions doesn't send us a nis_result obj, so we don't have a
+   cookie. Maybe we could use keys for threads ? Have to learn more
+   about pthreads -- kukuk@vt.uni-paderborn.de */
+
+#define CB_PROG ((u_long)100302)
+#define CB_VERS ((u_long)1)
+#define CBPROC_RECEIVE ((u_long)1)
+#define CBPROC_FINISH ((u_long)2)
+#define CBPROC_ERROR ((u_long)3)
+
+typedef nis_object *obj_p;
+
+struct cback_data
+  {
+    struct
+      {
+	u_int entries_len;
+	obj_p *entries_val;
+      }
+    entries;
+  };
+typedef struct cback_data cback_data;
+
+static nis_cb *data;
+
+__libc_lock_define_initialized (static, callback)
+
+static bool_t xdr_cback_data (XDR *, cback_data *);
+
+static void
+cb_prog_1 (struct svc_req *rqstp, SVCXPRT *transp)
+{
+  union
+    {
+      cback_data cbproc_receive_1_arg;
+      nis_error cbproc_error_1_arg;
+    }
+  argument;
+  char *result;
+  xdrproc_t xdr_argument, xdr_result;
+  bool_t bool_result;
+
+  switch (rqstp->rq_proc)
+    {
+    case NULLPROC:
+      (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *) NULL);
+      return;
+
+    case CBPROC_RECEIVE:
+      {
+	char name[NIS_MAXNAMELEN + 1];
+	u_long i;
+
+	xdr_argument = (xdrproc_t) xdr_cback_data;
+	xdr_result = (xdrproc_t) xdr_bool;
+	memset (&argument, 0, sizeof (argument));
+	if (!svc_getargs (transp, xdr_argument, (caddr_t) & argument))
+	  {
+	    svcerr_decode (transp);
+	    return;
+	  }
+	bool_result = FALSE;
+	for (i = 0; i < argument.cbproc_receive_1_arg.entries.entries_len; ++i)
+	  {
+	    snprintf (name, NIS_MAXNAMELEN, "%s.%s",
+	      argument.cbproc_receive_1_arg.entries.entries_val[i]->zo_name,
+	    argument.cbproc_receive_1_arg.entries.entries_val[i]->zo_domain);
+
+	    if ((data->callback)
+		(name, argument.cbproc_receive_1_arg.entries.entries_val[i],
+		 data->userdata))
+	      {
+		bool_result = TRUE;
+		data->nomore = 1;
+		data->result = NIS_SUCCESS;
+		break;
+	      }
+	  }
+	result = (char *) &bool_result;
+      }
+      break;
+    case CBPROC_FINISH:
+      xdr_argument = (xdrproc_t) xdr_void;
+      xdr_result = (xdrproc_t) xdr_void;
+      memset (&argument, 0, sizeof (argument));
+      if (!svc_getargs (transp, xdr_argument, (caddr_t) & argument))
+	{
+	  svcerr_decode (transp);
+	  return;
+	}
+      data->nomore = 1;
+      data->result = NIS_SUCCESS;
+      bool_result = TRUE;	/* to make gcc happy, not necessary */
+      result = (char *) &bool_result;
+      break;
+    case CBPROC_ERROR:
+      xdr_argument = (xdrproc_t) xdr_nis_error;
+      xdr_result = (xdrproc_t) xdr_void;
+      memset (&argument, 0, sizeof (argument));
+      if (!svc_getargs (transp, xdr_argument, (caddr_t) & argument))
+	{
+	  svcerr_decode (transp);
+	  return;
+	}
+      data->nomore = 1;
+      data->result = argument.cbproc_error_1_arg;
+      bool_result = TRUE;	/* to make gcc happy, not necessary */
+      result = (char *) &bool_result;
+      break;
+    default:
+      svcerr_noproc (transp);
+      return;
+    }
+  if (result != NULL && !svc_sendreply (transp, xdr_result, result))
+    svcerr_systemerr (transp);
+  if (!svc_freeargs (transp, xdr_argument, (caddr_t) & argument))
+    {
+      fputs (_ ("unable to free arguments"), stderr);
+      exit (1);
+    }
+  return;
+}
+
+static bool_t
+xdr_obj_p (XDR * xdrs, obj_p *objp)
+{
+  if (!xdr_pointer (xdrs, (char **) objp, sizeof (nis_object),
+		    (xdrproc_t) xdr_nis_object))
+    return FALSE;
+  return TRUE;
+}
+
+static bool_t
+xdr_cback_data (XDR *xdrs, cback_data *objp)
+{
+  if (!xdr_array (xdrs, (char **) &objp->entries.entries_val,
+		  (u_int *) & objp->entries.entries_len, ~0, sizeof (obj_p),
+		  (xdrproc_t) xdr_obj_p))
+    return FALSE;
+  return TRUE;
+}
+
+static nis_error
+internal_nis_do_callback (struct dir_binding *bptr, netobj *cookie,
+			  struct nis_cb *cb)
+{
+  /* Default timeout can be changed using clnt_control() */
+  static struct timeval TIMEOUT = {25, 0};
+#ifdef FD_SETSIZE
+  fd_set readfds;
+#else
+  int readfds;
+#endif /* def FD_SETSIZE */
+  struct timeval tv;
+  bool_t cb_is_running = FALSE;
+
+  data = cb;
+
+  for (;;)
+    {
+#ifdef FD_SETSIZE
+      readfds = svc_fdset;
+#else
+      readfds = svc_fds;
+#endif /* def FD_SETSIZE */
+      tv.tv_sec = 25;
+      tv.tv_usec = 0;
+      switch (select (_rpc_dtablesize (), &readfds, NULL, NULL, &tv))
+	{
+	case -1:
+	  if (errno == EINTR)
+	    continue;
+	  return NIS_CBERROR;
+	case 0:
+	  /* See if callback 'thread' in the server is still alive. */
+	  memset ((char *) &cb_is_running, 0, sizeof (cb_is_running));
+	  if (clnt_call (bptr->clnt, NIS_CALLBACK, (xdrproc_t) xdr_netobj,
+			 (caddr_t) cookie, (xdrproc_t) xdr_bool,
+			 (caddr_t) & cb_is_running, TIMEOUT) != RPC_SUCCESS)
+	    cb_is_running = FALSE;
+
+	  if (cb_is_running == FALSE)
+	    {
+	      syslog (LOG_ERR, "NIS+: callback timed out");
+	      return NIS_CBERROR;
+	    }
+	  break;
+	default:
+	  svc_getreqset (&readfds);
+	  if (data->nomore)
+	    return data->result;
+	}
+    }
+}
+
+nis_error
+__nis_do_callback (struct dir_binding *bptr, netobj *cookie,
+		   struct nis_cb *cb)
+{
+  nis_error result;
+
+  __libc_lock_lock (callback);
+
+  result = internal_nis_do_callback (bptr, cookie, cb);
+
+  __libc_lock_unlock (callback);
+
+  return result;
+}
+
+struct nis_cb *
+__nis_create_callback (int (*callback) (const_nis_name, const nis_object *,
+					const void *),
+		       const void *userdata, u_long flags)
+{
+  struct nis_cb *cb;
+  int sock = RPC_ANYSOCK;
+  struct sockaddr_in sin;
+  int len = sizeof (struct sockaddr_in);
+  char addr[NIS_MAXNAMELEN + 1];
+  unsigned short port;
+
+  cb = (struct nis_cb *) calloc (1, sizeof (struct nis_cb));
+  if (cb == NULL)
+    {
+      syslog (LOG_ERR, "NIS+: out of memory allocating callback");
+      return NULL;
+    }
+
+  cb->serv = (nis_server *) calloc (1, sizeof (nis_server));
+  if (cb->serv == NULL)
+    {
+      free (cb);
+      syslog (LOG_ERR, "NIS+: out of memory allocating callback");
+      return (NULL);
+    }
+  cb->serv->name = strdup (nis_local_host ());
+  cb->serv->ep.ep_val = (endpoint *) calloc (2, sizeof (endpoint));
+  cb->serv->ep.ep_len = 1;
+  cb->serv->ep.ep_val[0].family = strdup ("inet");
+  cb->callback = callback;
+  cb->userdata = userdata;
+
+  /* XXX Sometimes, we should add the public key of the user here ! */
+  cb->serv->key_type = NIS_PK_NONE;
+  cb->serv->pkey.n_bytes = NULL;
+  cb->serv->pkey.n_len = 0;
+
+  if (flags & USE_DGRAM)
+    {
+      cb->serv->ep.ep_val[0].proto = strdup ("udp");
+      cb->xprt = svcudp_bufcreate (sock, 100, 8192);
+    }
+  else
+    {
+      cb->serv->ep.ep_val[0].proto = strdup ("tcp");
+      cb->xprt = svctcp_create (sock, 100, 8192);
+    }
+  cb->sock = cb->xprt->xp_sock;
+  if (!svc_register (cb->xprt, CB_PROG, CB_VERS, cb_prog_1, 0))
+    {
+      xprt_unregister (cb->xprt);
+      svc_destroy (cb->xprt);
+      xdr_free ((xdrproc_t) xdr_nis_server, (char *) cb->serv);
+      free (cb->serv);
+      free (cb);
+      syslog (LOG_ERR, "NIS+: failed to register callback dispatcher");
+      return NULL;
+    }
+
+  if (getsockname (cb->sock, (struct sockaddr *) &sin, &len) == -1)
+    {
+      xprt_unregister (cb->xprt);
+      svc_destroy (cb->xprt);
+      xdr_free ((xdrproc_t) xdr_nis_server, (char *) cb->serv);
+      free (cb->serv);
+      free (cb);
+      syslog (LOG_ERR, "NIS+: failed to read local socket info");
+      return (NULL);
+    }
+  port = sin.sin_port;
+  get_myaddress (&sin);
+  snprintf (addr, sizeof (addr), "%s.%d.%d", inet_ntoa (sin.sin_addr),
+	    port & 0x00FF, (port & 0xFF00) >> 8);
+  cb->serv->ep.ep_val[0].uaddr = strdup (addr);
+
+  return cb;
+}
+
+nis_error
+__nis_destroy_callback (struct nis_cb *cb)
+{
+  xprt_unregister (cb->xprt);
+  svc_destroy (cb->xprt);
+  close (cb->sock);
+  xdr_free ((xdrproc_t) xdr_nis_server, (char *) cb->serv);
+  free (cb->serv);
+  free (cb);
+
+  return NIS_SUCCESS;
+}
diff --git a/nis/nis_checkpoint.c b/nis/nis_checkpoint.c
index ff0a9b37a7..15cdd58402 100644
--- a/nis/nis_checkpoint.c
+++ b/nis/nis_checkpoint.c
@@ -53,7 +53,7 @@ nis_checkpoint(const_nis_name dirname)
 	  if (__do_niscall2 (&res2->objects.objects_val[0].DI_data.do_servers.do_servers_val[i],
 			    1, NIS_CHECKPOINT, (xdrproc_t) xdr_nis_name,
 			    (caddr_t) &dirname, (xdrproc_t) xdr_cp_result,
-			    (caddr_t) &cpres, 0) != RPC_SUCCESS)
+			    (caddr_t) &cpres, 0, NULL) != RPC_SUCCESS)
 	    res->status = NIS_RPCERROR;
 	  else
 	    {
diff --git a/nis/nis_file.c b/nis/nis_file.c
index 84818519b0..c32d54a622 100644
--- a/nis/nis_file.c
+++ b/nis/nis_file.c
@@ -91,8 +91,6 @@ nis_write_obj (const char *name, const nis_object *obj)
     return FALSE;
 
   xdrstdio_create (&xdrs, out, XDR_ENCODE);
-  /* XXX The following cast is bad!  Shouldn't the XDR functions take
-     pointers to const objects?  */
   if (!xdr_nis_object (&xdrs, (nis_object *) obj))
     return FALSE;
 
diff --git a/nis/nis_findserv.c b/nis/nis_findserv.c
index 5ab369c84a..84508177e6 100644
--- a/nis/nis_findserv.c
+++ b/nis/nis_findserv.c
@@ -86,9 +86,10 @@ __pmap_getport (struct sockaddr_in *address, u_long program,
 	  rpc_createerr.cf_stat = RPC_PMAPFAILURE;
 	  clnt_geterr (client, &rpc_createerr.cf_error);
 	}
-      else if (port == 0)
+      else
 	{
-	  rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+	  if (port == 0)
+	    rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
 	}
       CLNT_DESTROY (client);
     }
@@ -97,39 +98,7 @@ __pmap_getport (struct sockaddr_in *address, u_long program,
   return port;
 }
 
-/* Transmit to NULLPROC, return immediately. */
-static void *
-nis_null_3_send (void *argp, CLIENT * clnt)
-{
-  static char clnt_res;
-  struct timeval TIMEOUT = {0, 0};
-
-  memset ((char *) &clnt_res, 0, sizeof (clnt_res));
-  if (clnt_call (clnt, NULLPROC,
-		 (xdrproc_t) xdr_void, (caddr_t) argp,
-		 (xdrproc_t) xdr_void, (caddr_t) & clnt_res,
-		 TIMEOUT) != RPC_SUCCESS)
-    return NULL;
-  return (void *) &clnt_res;
-}
-
-/* Receive request from NULLPROC asynchronously. */
-static void *
-nis_null_3_recv (void *argp, CLIENT * clnt)
-{
-  static char clnt_res;
-  struct timeval TIMEOUT = {0, 0};
-
-  memset ((char *) &clnt_res, 0, sizeof (clnt_res));
-  if (clnt_call (clnt, NULLPROC,
-		 (xdrproc_t) NULL, (caddr_t) argp,
-		 (xdrproc_t) xdr_void, (caddr_t) & clnt_res,
-		 TIMEOUT) != RPC_SUCCESS)
-    return NULL;
-  return (void *) &clnt_res;
-}
-
-/* This is now the public functions, which should find the fastest server */
+/* This is now the public function, which should find the fastest server */
 
 struct findserv_req
 {
@@ -142,13 +111,15 @@ struct findserv_req
 long
 __nis_findfastest (dir_binding * bind)
 {
-  struct timeval TIMEOUT = {5, 0};
+  const struct timeval TIMEOUT50 = {5, 0};
+  const struct timeval TIMEOUT00 = {0, 0};
   struct findserv_req **pings;
-  struct sockaddr_in sin;
+  struct sockaddr_in sin, saved_sin;
   int found = -1;
-  uint32_t xid_seed, xid_lookup;
+  u_int32_t xid_seed, xid_lookup;
   int sock, dontblock = 1;
   CLIENT *clnt;
+  char clnt_res;
   void *foo = NULL;
   u_long i, j, pings_count, pings_max;
   struct cu_data *cu;
@@ -157,14 +128,16 @@ __nis_findfastest (dir_binding * bind)
 					   for multihomed hosts */
   pings_count = 0;
   pings = malloc (sizeof (struct findserv_req *) * pings_max);
-  xid_seed = (uint32_t) (time (NULL) ^ getpid ());
+  xid_seed = (u_int32_t) (time (NULL) ^ getpid ());
 
   memset (&sin, '\0', sizeof (sin));
   sin.sin_family = AF_INET;
   for (i = 0; i < bind->server_len; i++)
     for (j = 0; j < bind->server_val[i].ep.ep_len; ++j)
       if (strcmp (bind->server_val[i].ep.ep_val[j].family, "inet") == 0)
-	if (strcmp (bind->server_val[i].ep.ep_val[j].proto, "-") == 0)
+	if ((bind->server_val[i].ep.ep_val[j].proto == NULL) ||
+	    (strcmp (bind->server_val[i].ep.ep_val[j].proto, "-") == 0) ||
+	    (strlen (bind->server_val[i].ep.ep_val[j].proto) == 0))
 	  {
 	    sin.sin_addr.s_addr =
 	      inetstr2int (bind->server_val[i].ep.ep_val[j].uaddr);
@@ -184,6 +157,7 @@ __nis_findfastest (dir_binding * bind)
 	    pings[pings_count] = calloc (1, sizeof (struct findserv_req));
 	    memcpy ((char *) &pings[pings_count]->sin, (char *) &sin,
 		    sizeof (sin));
+	    memcpy ((char *)&saved_sin, (char *)&sin, sizeof(sin));
 	    pings[pings_count]->xid = xid_seed;
 	    pings[pings_count]->server_nr = i;
 	    pings[pings_count]->server_ep = j;
@@ -200,7 +174,7 @@ __nis_findfastest (dir_binding * bind)
 
   /* Create RPC handle */
   sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-  clnt = clntudp_create (&sin, NIS_PROG, NIS_VERSION, TIMEOUT, &sock);
+  clnt = clntudp_create (&saved_sin, NIS_PROG, NIS_VERSION, TIMEOUT50, &sock);
   if (clnt == NULL)
     {
       close (sock);
@@ -211,8 +185,7 @@ __nis_findfastest (dir_binding * bind)
     }
   clnt->cl_auth = authunix_create_default ();
   cu = (struct cu_data *) clnt->cl_private;
-  TIMEOUT.tv_sec = 0;
-  clnt_control (clnt, CLSET_TIMEOUT, (char *) &TIMEOUT);
+  clnt_control (clnt, CLSET_TIMEOUT, (char *) &TIMEOUT00);
   ioctl (sock, FIONBIO, &dontblock);
 
   /* Send to all servers the NULLPROC */
@@ -220,13 +193,17 @@ __nis_findfastest (dir_binding * bind)
     {
       /* clntudp_call() will increment, subtract one */
       *((u_int32_t *) (cu->cu_outbuf)) = pings[i]->xid - 1;
-      bcopy ((char *) &pings[i]->sin, (char *) &cu->cu_raddr,
-	     sizeof (struct sockaddr_in));
-      nis_null_3_send (foo, clnt);
+      memcpy ((char *) &cu->cu_raddr, (char *) &pings[i]->sin,
+	      sizeof (struct sockaddr_in));
+      /* Transmit to NULLPROC, return immediately. */
+      clnt_call (clnt, NULLPROC, (xdrproc_t) xdr_void, (caddr_t) foo,
+		 (xdrproc_t) xdr_void, (caddr_t) & clnt_res, TIMEOUT00);
     }
 
-  /* Receive reply */
-  nis_null_3_recv (foo, clnt);
+  /* Receive reply from NULLPROC asynchronously */
+  memset ((char *) &clnt_res, 0, sizeof (clnt_res));
+  clnt_call (clnt, NULLPROC, (xdrproc_t) NULL, (caddr_t) foo,
+	     (xdrproc_t) xdr_void, (caddr_t) &clnt_res, TIMEOUT00);
 
   xid_lookup = *((u_int32_t *) (cu->cu_inbuf));
   for (i = 0; i < pings_count; i++)
diff --git a/nis/nis_intern.h b/nis/nis_intern.h
index 9852c24d55..ce88f0790d 100644
--- a/nis/nis_intern.h
+++ b/nis/nis_intern.h
@@ -42,16 +42,28 @@ struct dir_binding
 };
 typedef struct dir_binding dir_binding;
 
+struct nis_cb
+  {
+    nis_server *serv;
+    SVCXPRT *xprt;
+    int sock;
+    int nomore;
+    nis_error result;
+    int (*callback) (const_nis_name, const nis_object *, const void *);
+    const void *userdata;
+  };
+typedef struct nis_cb nis_cb;
+
 extern unsigned long inetstr2int __P ((const char *str));
 extern long __nis_findfastest __P ((dir_binding *bind));
 extern nis_error __do_niscall2 __P ((const nis_server *serv, u_int serv_len,
 				     u_long prog, xdrproc_t xargs, caddr_t req,
 				     xdrproc_t xres, caddr_t resp,
-				     u_long flags));
+				     u_long flags, nis_cb *cb));
 extern nis_error __do_niscall __P ((const_nis_name name, u_long prog,
 				    xdrproc_t xargs, caddr_t req,
 				    xdrproc_t xres, caddr_t resp,
-				    u_long flags));
+				    u_long flags, nis_cb *cb));
 extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int,
 				     struct sockaddr *, des_block *));
 
@@ -59,6 +71,14 @@ extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int,
 extern directory_obj *__cache_search __P ((const_nis_name name));
 extern nis_error __cache_add __P ((fd_result *));
 
+/* NIS+ callback */
+extern nis_error __nis_do_callback __P ((struct dir_binding *bptr,
+					 netobj *cookie, struct nis_cb *cb));
+extern struct nis_cb *__nis_create_callback
+      __P ((int (*callback)(const_nis_name, const nis_object *, const void *),
+	    const void *userdata, u_long flags));
+extern nis_error __nis_destroy_callback __P ((struct nis_cb *cb));
+
 __END_DECLS
 
 #endif
diff --git a/nis/nis_lookup.c b/nis/nis_lookup.c
index 6224b1f2c4..bdce5d5a0a 100644
--- a/nis/nis_lookup.c
+++ b/nis/nis_lookup.c
@@ -63,7 +63,7 @@ nis_lookup (const_nis_name name, const u_long flags)
 			     (xdrproc_t) xdr_ns_request,
 			     (caddr_t) & req,
 			     (xdrproc_t) xdr_nis_result,
-			     (caddr_t) res, flags);
+			     (caddr_t) res, flags, NULL);
       if (status != NIS_SUCCESS)
 	res->status = status;
 
diff --git a/nis/nis_mkdir.c b/nis/nis_mkdir.c
index 685dae64aa..b762e93f27 100644
--- a/nis/nis_mkdir.c
+++ b/nis/nis_mkdir.c
@@ -30,7 +30,7 @@ nis_mkdir (const_nis_name dir, const nis_server *server)
     {
       if (__do_niscall (dir, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
 			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			(caddr_t) &res, 0) != RPC_SUCCESS)
+			(caddr_t) &res, 0, NULL) != RPC_SUCCESS)
 	return NIS_RPCERROR;
     }
   else
@@ -38,7 +38,7 @@ nis_mkdir (const_nis_name dir, const nis_server *server)
       if (__do_niscall2 (server, 1, NIS_MKDIR,
 			 (xdrproc_t) xdr_nis_name,
 			 (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			 (caddr_t) &res, 0) != RPC_SUCCESS)
+			 (caddr_t) &res, 0, NULL) != RPC_SUCCESS)
 	return NIS_RPCERROR;
     }
 
diff --git a/nis/nis_modify.c b/nis/nis_modify.c
index 04572794a8..739ae0c351 100644
--- a/nis/nis_modify.c
+++ b/nis/nis_modify.c
@@ -58,7 +58,8 @@ nis_modify (const_nis_name name, const nis_object *obj)
 
   if ((status = __do_niscall (name, NIS_MODIFY, (xdrproc_t) xdr_ns_request,
 			      (caddr_t) & req, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+			      (caddr_t) res, MASTER_ONLY,
+			      NULL)) != RPC_SUCCESS)
     res->status = status;
 
   req.ns_object.ns_object_val[0].zo_name = p1;
diff --git a/nis/nis_ping.c b/nis/nis_ping.c
index 4ec34ce4c0..a06dfdee8d 100644
--- a/nis/nis_ping.c
+++ b/nis/nis_ping.c
@@ -60,7 +60,7 @@ nis_ping (const_nis_name dirname, u_long utime, const nis_object *dirobj)
     __do_niscall2 (&obj->DI_data.do_servers.do_servers_val[i], 1,
 		   NIS_PING, (xdrproc_t) xdr_ping_args,
 		   (caddr_t) &args, (xdrproc_t) xdr_void,
-		   (caddr_t) NULL, 0);
+		   (caddr_t) NULL, 0, NULL);
   if (res)
     nis_freeresult (res);
 }
diff --git a/nis/nis_remove.c b/nis/nis_remove.c
index e6aed00393..2fa9ecc353 100644
--- a/nis/nis_remove.c
+++ b/nis/nis_remove.c
@@ -46,7 +46,8 @@ nis_remove (const_nis_name name, const nis_object *obj)
 
   if ((status = __do_niscall (name, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
 			      (caddr_t) & req, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+			      (caddr_t) res, MASTER_ONLY,
+			      NULL)) != RPC_SUCCESS)
     res->status = status;
 
   nis_destroy_object (req.ns_object.ns_object_val);
diff --git a/nis/nis_rmdir.c b/nis/nis_rmdir.c
index a8c239ec70..adf5924ada 100644
--- a/nis/nis_rmdir.c
+++ b/nis/nis_rmdir.c
@@ -30,7 +30,7 @@ nis_rmdir (const_nis_name dir, const nis_server *server)
     {
       if (__do_niscall (dir, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
 			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			(caddr_t) &res, 0) != RPC_SUCCESS)
+			(caddr_t) &res, 0, NULL) != RPC_SUCCESS)
 	return NIS_RPCERROR;
     }
   else
@@ -38,7 +38,7 @@ nis_rmdir (const_nis_name dir, const nis_server *server)
       if (__do_niscall2 (server, 1, NIS_RMDIR,
 			 (xdrproc_t) xdr_nis_name,
 			 (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			 (caddr_t) &res, 0) != RPC_SUCCESS)
+			 (caddr_t) &res, 0, NULL) != RPC_SUCCESS)
 	return NIS_RPCERROR;
     }
 
diff --git a/nis/nis_server.c b/nis/nis_server.c
index 0df608a153..7eb785423a 100644
--- a/nis/nis_server.c
+++ b/nis/nis_server.c
@@ -39,7 +39,7 @@ nis_servstate (const nis_server *serv, const nis_tag *tags,
 
   if (__do_niscall2 (serv, 1, NIS_SERVSTATE, (xdrproc_t) xdr_nis_taglist,
 		     (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
-		     (caddr_t) &tagres, 0) != RPC_SUCCESS)
+		     (caddr_t) &tagres, 0, NULL) != RPC_SUCCESS)
     return NIS_RPCERROR;
 
   *result = tagres.tags.tags_val;
@@ -65,7 +65,7 @@ nis_stats (const nis_server *serv, const nis_tag *tags,
 
   if (__do_niscall2 (serv, 1, NIS_STATUS, (xdrproc_t) xdr_nis_taglist,
 		     (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
-		     (caddr_t) &tagres, 0) != RPC_SUCCESS)
+		     (caddr_t) &tagres, 0, NULL) != RPC_SUCCESS)
     return NIS_RPCERROR;
 
   *result = tagres.tags.tags_val;
diff --git a/nis/nis_table.c b/nis/nis_table.c
index a3bfa2c0cc..3efba6084e 100644
--- a/nis/nis_table.c
+++ b/nis/nis_table.c
@@ -148,7 +148,7 @@ __create_ib_request (const_nis_name name, struct ib_request *ibreq,
 
   ibreq->ibr_flags = (flags & (RETURN_RESULT | ADD_OVERWRITE | REM_MULTIPLE |
 			       MOD_SAMEOBJ | ADD_RESERVED | REM_RESERVED |
-			       MOD_EXCLUSIVE));
+			       MOD_EXCLUSIVE | ALL_RESULTS));
   ibreq->ibr_obj.ibr_obj_len = 0;
   ibreq->ibr_obj.ibr_obj_val = NULL;
   ibreq->ibr_cbhost.ibr_cbhost_len = 0;
@@ -170,11 +170,12 @@ nis_list (const_nis_name name, u_long flags,
   nis_result *res = NULL;
   struct ib_request ibreq;
   int status;
-  int count_links = 0;	    /* We will only follow 16 links! */
+  int count_links = 0;		/* We will only follow NIS_MAXLINKS links! */
   int done = 0;
   nis_name *names;
   nis_name namebuf[2] = {NULL, NULL};
   int name_nr = 0;
+  nis_cb *cb = NULL;
 
   res = calloc (1, sizeof (nis_result));
 
@@ -197,95 +198,170 @@ nis_list (const_nis_name name, u_long flags,
       ibreq.ibr_name = strdup (names[name_nr]);
     }
   else
-    names = namebuf;
+    {
+      names = namebuf;
+      names[name_nr] = ibreq.ibr_name;
+    }
 
-  while (!done)
+  cb = NULL;
+
+  if (flags & FOLLOW_PATH)
     {
-      memset (res, '\0', sizeof (nis_result));
+      nis_result *lres;
+      u_long newflags = flags & ~FOLLOW_PATH;
+      char table_path[NIS_MAXPATH + 1];
+      char *ntable, *p;
+      u_long done = 0, failures = 0;
 
-      status = __do_niscall (ibreq.ibr_name, NIS_IBLIST,
-			     (xdrproc_t) xdr_ib_request,
-			     (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
-			     (caddr_t) res, flags);
-      if (status != NIS_SUCCESS)
-	res->status = status;
+      memset (res, '\0', sizeof (nis_result));
 
-      switch (res->status)
+      while (names[name_nr] != NULL && !done)
 	{
-	case NIS_PARTIAL:
-	case NIS_SUCCESS:
-	case NIS_S_SUCCESS:
-	  if (__type_of(NIS_RES_OBJECT (res)) == LINK_OBJ &&
-	      flags & FOLLOW_LINKS) /* We are following links */
+	  lres = nis_lookup (names[name_nr], newflags);
+	  if (lres == NULL || lres->status != NIS_SUCCESS)
+	    {
+	      res->status = lres->status;
+	      nis_freeresult (lres);
+	      ++name_nr;
+	      continue;
+	      }
+
+	  /* nis_lookup handles FOLLOW_LINKS,
+	     so we must have a table object.  */
+	  if (__type_of (NIS_RES_OBJECT (lres)) != TABLE_OBJ)
+	    {
+	      nis_freeresult (lres);
+	      res->status = NIS_INVALIDOBJ;
+	      break;
+	    }
+
+	  /* Save the path, discard everything else.  */
+	  snprintf (table_path, NIS_MAXPATH, "%s:%s", names[name_nr],
+		    NIS_RES_OBJECT (lres)->TA_data.ta_path);
+	  nis_freeresult (lres);
+	  free (res);
+
+	  p = table_path;
+
+	  while (((ntable = strsep (&p, ":")) != NULL) && !done)
 	    {
-	      /* if we hit the link limit, bail */
-	      if (count_links > NIS_MAXLINKS)
+	      /* Do the job recursive here!  */
+	      res = nis_list (name, newflags, callback, userdata);
+	      if (res == NULL)
+		return NULL;
+	      switch (res->status)
 		{
-		  res->status = NIS_LINKNAMEERROR;
-		  ++done;
+		case NIS_SUCCESS:
+		case NIS_CBRESULTS:
+		  if (!(flags & ALL_RESULTS))
+		    done = 1;
+		  break;
+		default:
+		  if (flags & ALL_RESULTS)
+		    failures++;
+		  else
+		    done = 1;
 		  break;
-		}
-	      if (count_links)
-		free (ibreq.ibr_name);
-	      ++count_links;
-	      free (ibreq.ibr_name);
-	      ibreq.ibr_name = strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
-	      if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len)
-		if (ibreq.ibr_srch.ibr_srch_len == 0)
-		  {
-		    ibreq.ibr_srch.ibr_srch_len =
-		      NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len;
-		    ibreq.ibr_srch.ibr_srch_val =
-		      NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val;
 		  }
-	      nis_freeresult (res);
-	      res = calloc (1, sizeof (nis_result));
 	    }
-	  else
-	    ++done;
-	  break;
-	case NIS_CBRESULTS:
-	  /* XXX Implement CALLBACK here ! */
-	  ++done;
+	  if (res->status == NIS_SUCCESS && failures)
+	    res->status = NIS_S_SUCCESS;
+	  if (res->status == NIS_NOTFOUND && failures)
+	    res->status = NIS_S_NOTFOUND;
 	  break;
-        case NIS_UNAVAIL:  
-          /* NIS+ is not installed, or all servers are down */
-          ++done;
-          break;
-        default:
-	  /* Try the next domainname if we don't follow a link */
-	  if (count_links)
+	}
+    }
+  else
+    {
+      if (callback != NULL)
+	{
+	  cb = __nis_create_callback (callback, userdata, flags);
+	  ibreq.ibr_cbhost.ibr_cbhost_len = 1;
+	  ibreq.ibr_cbhost.ibr_cbhost_val = cb->serv;
+	  }
+
+      while (!done)
+	{
+	  memset (res, '\0', sizeof (nis_result));
+
+	  status = __do_niscall (ibreq.ibr_name, NIS_IBLIST,
+				 (xdrproc_t) xdr_ib_request,
+				 (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+				 (caddr_t) res, flags, cb);
+	  if (status != NIS_SUCCESS)
+	    res->status = status;
+
+	  switch (res->status)
 	    {
-	      free (ibreq.ibr_name);
-	      res->status = NIS_LINKNAMEERROR;
+	    case NIS_PARTIAL:
+	    case NIS_SUCCESS:
+	    case NIS_S_SUCCESS:
+	      if (__type_of (NIS_RES_OBJECT (res)) == LINK_OBJ &&
+		  flags & FOLLOW_LINKS)		/* We are following links.  */
+		{
+		  /* If we hit the link limit, bail.  */
+		  if (count_links > NIS_MAXLINKS)
+		    {
+		      res->status = NIS_LINKNAMEERROR;
+		      ++done;
+		      break;
+		    }
+		  if (count_links)
+		    free (ibreq.ibr_name);
+		  ++count_links;
+		  free (ibreq.ibr_name);
+		  ibreq.ibr_name =
+		    strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
+		  if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len)
+		    if (ibreq.ibr_srch.ibr_srch_len == 0)
+		      {
+			ibreq.ibr_srch.ibr_srch_len =
+			  NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len;
+			ibreq.ibr_srch.ibr_srch_val =
+			  NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val;
+		      }
+		  nis_freeresult (res);
+		  res = calloc (1, sizeof (nis_result));
+		}
+	      else
+		++done;
+	      break;
+	    case NIS_CBRESULTS:
+	      /* Calback is handled in nis_call.c (__do_niscall2).  */
 	      ++done;
 	      break;
-	    }
-	  ++name_nr;
-	  if (names[name_nr] == NULL)
-	    {
+	    case NIS_UNAVAIL:
+	      /* NIS+ is not installed, or all servers are down.  */
 	      ++done;
 	      break;
+	    default:
+	      /* Try the next domainname if we don't follow a link.  */
+	      if (count_links)
+		{
+		  free (ibreq.ibr_name);
+		  res->status = NIS_LINKNAMEERROR;
+		  ++done;
+		  break;
+		}
+	      ++name_nr;
+	      if (names[name_nr] == NULL)
+		{
+		  ++done;
+		  break;
+		}
+	      ibreq.ibr_name = names[name_nr];
+	      break;
 	    }
-	  ibreq.ibr_name = names[name_nr];
-	  break;
 	}
-    }
+    }				/* End of not FOLLOW_PATH.  */
 
   if (names != namebuf)
     nis_freenames (names);
 
   nis_free_request (&ibreq);
 
-  if (callback != NULL &&
-      (res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS))
-    {
-      unsigned int i;
-
-      for (i = 0; i < res->objects.objects_len; ++i)
-	if ((*callback) (name, &(res->objects.objects_val)[i], userdata) != 0)
-	  break;
-    }
+  if (cb)
+    __nis_destroy_callback (cb);
 
   return res;
 }
@@ -298,8 +374,8 @@ nis_add_entry (const_nis_name name, const nis_object *obj,
   nis_error status;
   struct ib_request ibreq;
   char *p1, *p2, *p3, *p4;
-  char buf1 [strlen (name) + 20];
-  char buf4 [strlen (name) + 20];
+  char buf1[strlen (name) + 20];
+  char buf4[strlen (name) + 20];
 
   res = calloc (1, sizeof (nis_result));
 
@@ -332,9 +408,9 @@ nis_add_entry (const_nis_name name, const nis_object *obj,
 
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBADD,
 			      (xdrproc_t) xdr_ib_request,
-			      (caddr_t) &ibreq,
+			      (caddr_t) & ibreq,
 			      (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   ibreq.ibr_obj.ibr_obj_val->zo_name = p1;
@@ -355,8 +431,8 @@ nis_modify_entry (const_nis_name name, const nis_object *obj,
   nis_error status;
   struct ib_request ibreq;
   char *p1, *p2, *p3, *p4;
-  char buf1 [strlen (name) + 20];
-  char buf4 [strlen (name) + 20];
+  char buf1[strlen (name) + 20];
+  char buf4[strlen (name) + 20];
 
   res = calloc (1, sizeof (nis_result));
 
@@ -390,7 +466,7 @@ nis_modify_entry (const_nis_name name, const nis_object *obj,
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBMODIFY,
 			      (xdrproc_t) xdr_ib_request,
 			      (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   ibreq.ibr_obj.ibr_obj_val->zo_name = p1;
@@ -429,7 +505,7 @@ nis_remove_entry (const_nis_name name, const nis_object *obj,
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBREMOVE,
 			      (xdrproc_t) xdr_ib_request,
 			      (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
@@ -454,8 +530,8 @@ nis_first_entry (const_nis_name name)
 
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBFIRST,
 			      (xdrproc_t) xdr_ib_request,
-			      (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
@@ -493,8 +569,8 @@ nis_next_entry (const_nis_name name, const netobj *cookie)
 
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBNEXT,
 			      (xdrproc_t) xdr_ib_request,
-			      (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
diff --git a/nis/nis_util.c b/nis/nis_util.c
index b6eef9b227..fd9ff26bf5 100644
--- a/nis/nis_util.c
+++ b/nis/nis_util.c
@@ -31,15 +31,15 @@ __nis_finddirectory (directory_obj *dir, const_nis_name name)
   fd_args.dir_name = strdup (name);
   fd_args.requester = nis_local_host();
   fd_res = calloc (1, sizeof (fd_result));
-      
-  if ((status = __do_niscall2 (dir->do_servers.do_servers_val, 
-			       dir->do_servers.do_servers_len, 
+
+  if ((status = __do_niscall2 (dir->do_servers.do_servers_val,
+			       dir->do_servers.do_servers_len,
 			       NIS_FINDDIRECTORY, (xdrproc_t) xdr_fd_args,
 			       (caddr_t) &fd_args, (xdrproc_t) xdr_fd_result,
-			       (caddr_t) fd_res, 
-			       NO_AUTHINFO|USE_DGRAM)) != NIS_SUCCESS)
+			       (caddr_t) fd_res,
+			       NO_AUTHINFO|USE_DGRAM, NULL)) != NIS_SUCCESS)
     fd_res->status = status;
-      
+
   return fd_res;
 }
 
@@ -59,15 +59,15 @@ __nis_hash (const void *keyarg, register size_t len)
   register const u_char *key;
   register size_t loop;
   register u_int32_t h;
-  
+
 #define HASHC   h = *key++ + 65599 * h
-  
+
   h = 0;
   key = keyarg;
-  if (len > 0) 
+  if (len > 0)
     {
       loop = (len + 8 - 1) >> 3;
-      switch (len & (8 - 1)) 
+      switch (len & (8 - 1))
 	{
 	case 0:
 	  do {
@@ -98,4 +98,3 @@ __nis_hash (const void *keyarg, register size_t len)
     }
   return (h);
 }
-
diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c
index 72ed1a5044..aa2a6f0c3a 100644
--- a/nis/nss_nisplus/nisplus-publickey.c
+++ b/nis/nss_nisplus/nisplus-publickey.c
@@ -162,8 +162,8 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
 
   len = ENTRY_LEN (res->objects.objects_val, 4);
   memcpy (buf, ENTRY_VAL (res->objects.objects_val,4), len);
-  skey[len] = 0;
-  cptr = strchr (skey, ':');
+  buf[len] = '\0';
+  cptr = strchr (buf, ':');
   if (cptr)
     cptr[0] = '\0';
   nis_freeresult (res);
diff --git a/nis/rpcsvc/nis.h b/nis/rpcsvc/nis.h
index b91ce19903..f94b96cba4 100644
--- a/nis/rpcsvc/nis.h
+++ b/nis/rpcsvc/nis.h
@@ -28,10 +28,14 @@
  * Mountain View, California  94043
  */
 
-#ifndef _NIS_H_RPCGEN
-#define _NIS_H_RPCGEN
+#ifndef _RPCSVC_NIS_H
+#define _RPCSVC_NIS_H 1
 
+#include <features.h>
 #include <rpc/rpc.h>
+#include <rpcsvc/nis_tags.h>
+
+__BEGIN_DECLS
 
 /*
  *	nis.h
@@ -48,8 +52,7 @@
  *	       Makefile target nis.h)
  *
  */
-#include <rpcsvc/nis_tags.h>
-#include <rpc/xdr.h>
+
 #pragma ident	"@(#)nis_object.x	1.7	92/07/14 SMI"
 
 #ifndef __nis_object_h
@@ -77,24 +80,10 @@ struct nis_attr {
 	} zattr_val;
 };
 typedef struct nis_attr nis_attr;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_attr(XDR *, nis_attr*);
-#elif __STDC__
-extern  bool_t xdr_nis_attr(XDR *, nis_attr*);
-#else /* Old Style C */
-bool_t xdr_nis_attr();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_attr __P ((XDR *, nis_attr*));
 
 typedef char *nis_name;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_name(XDR *, nis_name*);
-#elif __STDC__
-extern  bool_t xdr_nis_name(XDR *, nis_name*);
-#else /* Old Style C */
-bool_t xdr_nis_name();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_name __P ((XDR *, nis_name*));
 
 enum zotypes {
 	BOGUS_OBJ = 0,
@@ -107,14 +96,7 @@ enum zotypes {
 	PRIVATE_OBJ = 7,
 };
 typedef enum zotypes zotypes;
-#ifdef __cplusplus
-extern "C" bool_t xdr_zotypes(XDR *, zotypes*);
-#elif __STDC__
-extern  bool_t xdr_zotypes(XDR *, zotypes*);
-#else /* Old Style C */
-bool_t xdr_zotypes();
-#endif /* Old Style C */
-
+extern  bool_t xdr_zotypes __P ((XDR *, zotypes*));
 
 enum nstype {
 	UNKNOWN = 0,
@@ -128,28 +110,14 @@ enum nstype {
 	CDS = 8,
 };
 typedef enum nstype nstype;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nstype(XDR *, nstype*);
-#elif __STDC__
-extern  bool_t xdr_nstype(XDR *, nstype*);
-#else /* Old Style C */
-bool_t xdr_nstype();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nstype __P ((XDR *, nstype*));
 
 struct oar_mask {
 	u_long oa_rights;
 	zotypes oa_otype;
 };
 typedef struct oar_mask oar_mask;
-#ifdef __cplusplus
-extern "C" bool_t xdr_oar_mask(XDR *, oar_mask*);
-#elif __STDC__
-extern  bool_t xdr_oar_mask(XDR *, oar_mask*);
-#else /* Old Style C */
-bool_t xdr_oar_mask();
-#endif /* Old Style C */
-
+extern  bool_t xdr_oar_mask __P ((XDR *, oar_mask*));
 
 struct endpoint {
 	char *uaddr;
@@ -157,14 +125,7 @@ struct endpoint {
 	char *proto;
 };
 typedef struct endpoint endpoint;
-#ifdef __cplusplus
-extern "C" bool_t xdr_endpoint(XDR *, endpoint*);
-#elif __STDC__
-extern  bool_t xdr_endpoint(XDR *, endpoint*);
-#else /* Old Style C */
-bool_t xdr_endpoint();
-#endif /* Old Style C */
-
+extern  bool_t xdr_endpoint __P ((XDR *, endpoint*));
 
 struct nis_server {
 	nis_name name;
@@ -176,14 +137,7 @@ struct nis_server {
 	netobj pkey;
 };
 typedef struct nis_server nis_server;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_server(XDR *, nis_server*);
-#elif __STDC__
-extern  bool_t xdr_nis_server(XDR *, nis_server*);
-#else /* Old Style C */
-bool_t xdr_nis_server();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_server __P ((XDR *, nis_server*));
 
 struct directory_obj {
 	nis_name do_name;
@@ -199,13 +153,7 @@ struct directory_obj {
 	} do_armask;
 };
 typedef struct directory_obj directory_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_directory_obj(XDR *, directory_obj*);
-#elif __STDC__
-extern  bool_t xdr_directory_obj(XDR *, directory_obj*);
-#else /* Old Style C */
-bool_t xdr_directory_obj();
-#endif /* Old Style C */
+extern  bool_t xdr_directory_obj __P ((XDR *, directory_obj*));
 
 #define EN_BINARY 1
 #define EN_CRYPT 2
@@ -221,14 +169,7 @@ struct entry_col {
 	} ec_value;
 };
 typedef struct entry_col entry_col;
-#ifdef __cplusplus
-extern "C" bool_t xdr_entry_col(XDR *, entry_col*);
-#elif __STDC__
-extern  bool_t xdr_entry_col(XDR *, entry_col*);
-#else /* Old Style C */
-bool_t xdr_entry_col();
-#endif /* Old Style C */
-
+extern  bool_t xdr_entry_col __P ((XDR *, entry_col*));
 
 struct entry_obj {
 	char *en_type;
@@ -238,14 +179,7 @@ struct entry_obj {
 	} en_cols;
 };
 typedef struct entry_obj entry_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_entry_obj(XDR *, entry_obj*);
-#elif __STDC__
-extern  bool_t xdr_entry_obj(XDR *, entry_obj*);
-#else /* Old Style C */
-bool_t xdr_entry_obj();
-#endif /* Old Style C */
-
+extern  bool_t xdr_entry_obj __P ((XDR *, entry_obj*));
 
 struct group_obj {
 	u_long gr_flags;
@@ -255,14 +189,7 @@ struct group_obj {
 	} gr_members;
 };
 typedef struct group_obj group_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_group_obj(XDR *, group_obj*);
-#elif __STDC__
-extern  bool_t xdr_group_obj(XDR *, group_obj*);
-#else /* Old Style C */
-bool_t xdr_group_obj();
-#endif /* Old Style C */
-
+extern  bool_t xdr_group_obj __P ((XDR *, group_obj*));
 
 struct link_obj {
 	zotypes li_rtype;
@@ -273,13 +200,7 @@ struct link_obj {
 	nis_name li_name;
 };
 typedef struct link_obj link_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_link_obj(XDR *, link_obj*);
-#elif __STDC__
-extern  bool_t xdr_link_obj(XDR *, link_obj*);
-#else /* Old Style C */
-bool_t xdr_link_obj();
-#endif /* Old Style C */
+extern  bool_t xdr_link_obj __P ((XDR *, link_obj*));
 
 #define TA_BINARY 1
 #define TA_CRYPT 2
@@ -295,14 +216,7 @@ struct table_col {
 	u_long tc_rights;
 };
 typedef struct table_col table_col;
-#ifdef __cplusplus
-extern "C" bool_t xdr_table_col(XDR *, table_col*);
-#elif __STDC__
-extern  bool_t xdr_table_col(XDR *, table_col*);
-#else /* Old Style C */
-bool_t xdr_table_col();
-#endif /* Old Style C */
-
+extern  bool_t xdr_table_col __P ((XDR *, table_col*));
 
 struct table_obj {
 	char *ta_type;
@@ -315,14 +229,7 @@ struct table_obj {
 	char *ta_path;
 };
 typedef struct table_obj table_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_table_obj(XDR *, table_obj*);
-#elif __STDC__
-extern  bool_t xdr_table_obj(XDR *, table_obj*);
-#else /* Old Style C */
-bool_t xdr_table_obj();
-#endif /* Old Style C */
-
+extern  bool_t xdr_table_obj __P ((XDR *, table_obj*));
 
 struct objdata {
 	zotypes zo_type;
@@ -339,28 +246,14 @@ struct objdata {
 	} objdata_u;
 };
 typedef struct objdata objdata;
-#ifdef __cplusplus
-extern "C" bool_t xdr_objdata(XDR *, objdata*);
-#elif __STDC__
-extern  bool_t xdr_objdata(XDR *, objdata*);
-#else /* Old Style C */
-bool_t xdr_objdata();
-#endif /* Old Style C */
-
+extern  bool_t xdr_objdata __P ((XDR *, objdata*));
 
 struct nis_oid {
 	u_long ctime;
 	u_long mtime;
 };
 typedef struct nis_oid nis_oid;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_oid(XDR *, nis_oid*);
-#elif __STDC__
-extern  bool_t xdr_nis_oid(XDR *, nis_oid*);
-#else /* Old Style C */
-bool_t xdr_nis_oid();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_oid __P ((XDR *, nis_oid*));
 
 struct nis_object {
 	nis_oid zo_oid;
@@ -373,18 +266,10 @@ struct nis_object {
 	objdata zo_data;
 };
 typedef struct nis_object nis_object;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_object(XDR *, nis_object*);
-#elif __STDC__
-extern  bool_t xdr_nis_object(XDR *, nis_object*);
-#else /* Old Style C */
-bool_t xdr_nis_object();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_object __P ((XDR *, nis_object*));
 
 #endif /* if __nis_object_h */
 
-
 enum nis_error {
 	NIS_SUCCESS = 0,
 	NIS_S_SUCCESS = 1,
@@ -436,14 +321,7 @@ enum nis_error {
 	NIS_DUMPLATER = 47,
 };
 typedef enum nis_error nis_error;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_error(XDR *, nis_error*);
-#elif __STDC__
-extern  bool_t xdr_nis_error(XDR *, nis_error*);
-#else /* Old Style C */
-bool_t xdr_nis_error();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_error __P ((XDR *, nis_error*));
 
 struct nis_result {
 	nis_error status;
@@ -458,14 +336,7 @@ struct nis_result {
 	u_long cticks;
 };
 typedef struct nis_result nis_result;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_result(XDR *, nis_result*);
-#elif __STDC__
-extern  bool_t xdr_nis_result(XDR *, nis_result*);
-#else /* Old Style C */
-bool_t xdr_nis_result();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_result __P ((XDR *, nis_result*));
 
 struct ns_request {
 	nis_name ns_name;
@@ -475,14 +346,7 @@ struct ns_request {
 	} ns_object;
 };
 typedef struct ns_request ns_request;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ns_request(XDR *, ns_request*);
-#elif __STDC__
-extern  bool_t xdr_ns_request(XDR *, ns_request*);
-#else /* Old Style C */
-bool_t xdr_ns_request();
-#endif /* Old Style C */
-
+extern  bool_t xdr_ns_request __P ((XDR *, ns_request*));
 
 struct ib_request {
 	nis_name ibr_name;
@@ -503,28 +367,14 @@ struct ib_request {
 	netobj ibr_cookie;
 };
 typedef struct ib_request ib_request;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ib_request(XDR *, ib_request*);
-#elif __STDC__
-extern  bool_t xdr_ib_request(XDR *, ib_request*);
-#else /* Old Style C */
-bool_t xdr_ib_request();
-#endif /* Old Style C */
-
+extern  bool_t xdr_ib_request __P ((XDR *, ib_request*));
 
 struct ping_args {
 	nis_name dir;
 	u_long stamp;
 };
 typedef struct ping_args ping_args;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ping_args(XDR *, ping_args*);
-#elif __STDC__
-extern  bool_t xdr_ping_args(XDR *, ping_args*);
-#else /* Old Style C */
-bool_t xdr_ping_args();
-#endif /* Old Style C */
-
+extern  bool_t xdr_ping_args __P ((XDR *, ping_args*));
 
 enum log_entry_t {
 	LOG_NOP = 0,
@@ -538,14 +388,7 @@ enum log_entry_t {
 	UPD_STAMP = 8,
 };
 typedef enum log_entry_t log_entry_t;
-#ifdef __cplusplus
-extern "C" bool_t xdr_log_entry_t(XDR *, log_entry_t*);
-#elif __STDC__
-extern  bool_t xdr_log_entry_t(XDR *, log_entry_t*);
-#else /* Old Style C */
-bool_t xdr_log_entry_t();
-#endif /* Old Style C */
-
+extern  bool_t xdr_log_entry_t __P ((XDR *, log_entry_t*));
 
 struct log_entry {
 	u_long le_time;
@@ -559,14 +402,7 @@ struct log_entry {
 	nis_object le_object;
 };
 typedef struct log_entry log_entry;
-#ifdef __cplusplus
-extern "C" bool_t xdr_log_entry(XDR *, log_entry*);
-#elif __STDC__
-extern  bool_t xdr_log_entry(XDR *, log_entry*);
-#else /* Old Style C */
-bool_t xdr_log_entry();
-#endif /* Old Style C */
-
+extern  bool_t xdr_log_entry __P ((XDR *, log_entry*));
 
 struct log_result {
 	nis_error lr_status;
@@ -577,14 +413,7 @@ struct log_result {
 	} lr_entries;
 };
 typedef struct log_result log_result;
-#ifdef __cplusplus
-extern "C" bool_t xdr_log_result(XDR *, log_result*);
-#elif __STDC__
-extern  bool_t xdr_log_result(XDR *, log_result*);
-#else /* Old Style C */
-bool_t xdr_log_result();
-#endif /* Old Style C */
-
+extern  bool_t xdr_log_result __P ((XDR *, log_result*));
 
 struct cp_result {
 	nis_error cp_status;
@@ -592,28 +421,14 @@ struct cp_result {
 	u_long cp_dticks;
 };
 typedef struct cp_result cp_result;
-#ifdef __cplusplus
-extern "C" bool_t xdr_cp_result(XDR *, cp_result*);
-#elif __STDC__
-extern  bool_t xdr_cp_result(XDR *, cp_result*);
-#else /* Old Style C */
-bool_t xdr_cp_result();
-#endif /* Old Style C */
-
+extern  bool_t xdr_cp_result __P ((XDR *, cp_result*));
 
 struct nis_tag {
 	u_long tag_type;
 	char *tag_val;
 };
 typedef struct nis_tag nis_tag;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_tag(XDR *, nis_tag*);
-#elif __STDC__
-extern  bool_t xdr_nis_tag(XDR *, nis_tag*);
-#else /* Old Style C */
-bool_t xdr_nis_tag();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_tag __P ((XDR *, nis_tag*));
 
 struct nis_taglist {
 	struct {
@@ -622,14 +437,7 @@ struct nis_taglist {
 	} tags;
 };
 typedef struct nis_taglist nis_taglist;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_taglist(XDR *, nis_taglist*);
-#elif __STDC__
-extern  bool_t xdr_nis_taglist(XDR *, nis_taglist*);
-#else /* Old Style C */
-bool_t xdr_nis_taglist();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_taglist __P ((XDR *, nis_taglist*));
 
 struct dump_args {
 	nis_name da_dir;
@@ -640,28 +448,14 @@ struct dump_args {
 	} da_cbhost;
 };
 typedef struct dump_args dump_args;
-#ifdef __cplusplus
-extern "C" bool_t xdr_dump_args(XDR *, dump_args*);
-#elif __STDC__
-extern  bool_t xdr_dump_args(XDR *, dump_args*);
-#else /* Old Style C */
-bool_t xdr_dump_args();
-#endif /* Old Style C */
-
+extern  bool_t xdr_dump_args __P ((XDR *, dump_args*));
 
 struct fd_args {
 	nis_name dir_name;
 	nis_name requester;
 };
 typedef struct fd_args fd_args;
-#ifdef __cplusplus
-extern "C" bool_t xdr_fd_args(XDR *, fd_args*);
-#elif __STDC__
-extern  bool_t xdr_fd_args(XDR *, fd_args*);
-#else /* Old Style C */
-bool_t xdr_fd_args();
-#endif /* Old Style C */
-
+extern  bool_t xdr_fd_args __P ((XDR *, fd_args*));
 
 struct fd_result {
 	nis_error status;
@@ -676,13 +470,7 @@ struct fd_result {
 	} signature;
 };
 typedef struct fd_result fd_result;
-#ifdef __cplusplus
-extern "C" bool_t xdr_fd_result(XDR *, fd_result*);
-#elif __STDC__
-extern  bool_t xdr_fd_result(XDR *, fd_result*);
-#else /* Old Style C */
-bool_t xdr_fd_result();
-#endif /* Old Style C */
+extern  bool_t xdr_fd_result __P ((XDR *, fd_result*));
 
 /*
  * Generic "hash" datastructures, used by all types of hashed data.
@@ -762,14 +550,10 @@ typedef enum name_pos name_pos;
 #define ENTRY_VAL(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val
 #define ENTRY_LEN(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len
 
-#ifdef __cplusplus
-}
-#endif
 
 /* Prototypes, and extern declarations for the NIS library functions. */
 #include <rpcsvc/nislib.h>
-#endif /* __NIS_RPCGEN_H */
-/* EDIT_START */
+#endif
 
 /*
  * nis_3.h
@@ -784,229 +568,79 @@ typedef enum name_pos name_pos;
  */
 #ifndef __nis_3_h
 #define __nis_3_h
-#ifdef __cplusplus
-extern "C" {
-#endif
 
 #define NIS_PROG ((u_long)100300)
-extern struct rpcgen_table nis_prog_3_table[];
-extern int nis_prog_3_nproc;
 #define NIS_VERSION ((u_long)3)
 
-#ifdef __cplusplus
 #define NIS_LOOKUP ((u_long)1)
-extern "C" nis_result * nis_lookup_3(ns_request *, CLIENT *);
-extern "C" nis_result * nis_lookup_3_svc(ns_request *, struct svc_req *);
+extern  nis_result * nis_lookup_3 __P ((ns_request *, CLIENT *));
+extern  nis_result * nis_lookup_3_svc __P ((ns_request *, struct svc_req *));
 #define NIS_ADD ((u_long)2)
-extern "C" nis_result * nis_add_3(ns_request *, CLIENT *);
-extern "C" nis_result * nis_add_3_svc(ns_request *, struct svc_req *);
+extern  nis_result * nis_add_3 __P ((ns_request *, CLIENT *));
+extern  nis_result * nis_add_3_svc __P ((ns_request *, struct svc_req *));
 #define NIS_MODIFY ((u_long)3)
-extern "C" nis_result * nis_modify_3(ns_request *, CLIENT *);
-extern "C" nis_result * nis_modify_3_svc(ns_request *, struct svc_req *);
+extern  nis_result * nis_modify_3 __P ((ns_request *, CLIENT *));
+extern  nis_result * nis_modify_3_svc __P ((ns_request *, struct svc_req *));
 #define NIS_REMOVE ((u_long)4)
-extern "C" nis_result * nis_remove_3(ns_request *, CLIENT *);
-extern "C" nis_result * nis_remove_3_svc(ns_request *, struct svc_req *);
+extern  nis_result * nis_remove_3 __P ((ns_request *, CLIENT *));
+extern  nis_result * nis_remove_3_svc __P ((ns_request *, struct svc_req *));
 #define NIS_IBLIST ((u_long)5)
-extern "C" nis_result * nis_iblist_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_iblist_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_iblist_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_iblist_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBADD ((u_long)6)
-extern "C" nis_result * nis_ibadd_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibadd_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibadd_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibadd_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBMODIFY ((u_long)7)
-extern "C" nis_result * nis_ibmodify_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibmodify_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibmodify_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibmodify_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBREMOVE ((u_long)8)
-extern "C" nis_result * nis_ibremove_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibremove_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibremove_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibremove_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBFIRST ((u_long)9)
-extern "C" nis_result * nis_ibfirst_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibfirst_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibfirst_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibfirst_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBNEXT ((u_long)10)
-extern "C" nis_result * nis_ibnext_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibnext_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibnext_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibnext_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_FINDDIRECTORY ((u_long)12)
-extern "C" fd_result * nis_finddirectory_3(fd_args *, CLIENT *);
-extern "C" fd_result * nis_finddirectory_3_svc(fd_args *, struct svc_req *);
+extern  fd_result * nis_finddirectory_3 __P ((fd_args *, CLIENT *));
+extern  fd_result * nis_finddirectory_3_svc __P ((fd_args *,
+						  struct svc_req *));
 #define NIS_STATUS ((u_long)14)
-extern "C" nis_taglist * nis_status_3(nis_taglist *, CLIENT *);
-extern "C" nis_taglist * nis_status_3_svc(nis_taglist *, struct svc_req *);
+extern  nis_taglist * nis_status_3 __P ((nis_taglist *, CLIENT *));
+extern  nis_taglist * nis_status_3_svc __P ((nis_taglist *, struct svc_req *));
 #define NIS_DUMPLOG ((u_long)15)
-extern "C" log_result * nis_dumplog_3(dump_args *, CLIENT *);
-extern "C" log_result * nis_dumplog_3_svc(dump_args *, struct svc_req *);
+extern  log_result * nis_dumplog_3 __P ((dump_args *, CLIENT *));
+extern  log_result * nis_dumplog_3_svc __P ((dump_args *, struct svc_req *));
 #define NIS_DUMP ((u_long)16)
-extern "C" log_result * nis_dump_3(dump_args *, CLIENT *);
-extern "C" log_result * nis_dump_3_svc(dump_args *, struct svc_req *);
+extern  log_result * nis_dump_3 __P ((dump_args *, CLIENT *));
+extern  log_result * nis_dump_3_svc __P ((dump_args *, struct svc_req *));
 #define NIS_CALLBACK ((u_long)17)
-extern "C" bool_t * nis_callback_3(netobj *, CLIENT *);
-extern "C" bool_t * nis_callback_3_svc(netobj *, struct svc_req *);
+extern  bool_t * nis_callback_3 __P ((netobj *, CLIENT *));
+extern  bool_t * nis_callback_3_svc __P ((netobj *, struct svc_req *));
 #define NIS_CPTIME ((u_long)18)
-extern "C" u_long * nis_cptime_3(nis_name *, CLIENT *);
-extern "C" u_long * nis_cptime_3_svc(nis_name *, struct svc_req *);
+extern  u_long * nis_cptime_3 __P ((nis_name *, CLIENT *));
+extern  u_long * nis_cptime_3_svc __P ((nis_name *, struct svc_req *));
 #define NIS_CHECKPOINT ((u_long)19)
-extern "C" cp_result * nis_checkpoint_3(nis_name *, CLIENT *);
-extern "C" cp_result * nis_checkpoint_3_svc(nis_name *, struct svc_req *);
+extern  cp_result * nis_checkpoint_3 __P ((nis_name *, CLIENT *));
+extern  cp_result * nis_checkpoint_3_svc __P ((nis_name *, struct svc_req *));
 #define NIS_PING ((u_long)20)
-extern "C" void * nis_ping_3(ping_args *, CLIENT *);
-extern "C" void * nis_ping_3_svc(ping_args *, struct svc_req *);
+extern  void * nis_ping_3 __P ((ping_args *, CLIENT *));
+extern  void * nis_ping_3_svc __P ((ping_args *, struct svc_req *));
 #define NIS_SERVSTATE ((u_long)21)
-extern "C" nis_taglist * nis_servstate_3(nis_taglist *, CLIENT *);
-extern "C" nis_taglist * nis_servstate_3_svc(nis_taglist *, struct svc_req *);
+extern  nis_taglist * nis_servstate_3 __P ((nis_taglist *, CLIENT *));
+extern  nis_taglist * nis_servstate_3_svc __P ((nis_taglist *,
+						struct svc_req *));
 #define NIS_MKDIR ((u_long)22)
-extern "C" nis_error * nis_mkdir_3(nis_name *, CLIENT *);
-extern "C" nis_error * nis_mkdir_3_svc(nis_name *, struct svc_req *);
+extern  nis_error * nis_mkdir_3 __P ((nis_name *, CLIENT *));
+extern  nis_error * nis_mkdir_3_svc __P ((nis_name *, struct svc_req *));
 #define NIS_RMDIR ((u_long)23)
-extern "C" nis_error * nis_rmdir_3(nis_name *, CLIENT *);
-extern "C" nis_error * nis_rmdir_3_svc(nis_name *, struct svc_req *);
+extern  nis_error * nis_rmdir_3 __P ((nis_name *, CLIENT *));
+extern  nis_error * nis_rmdir_3_svc __P ((nis_name *, struct svc_req *));
 #define NIS_UPDKEYS ((u_long)24)
-extern "C" nis_error * nis_updkeys_3(nis_name *, CLIENT *);
-extern "C" nis_error * nis_updkeys_3_svc(nis_name *, struct svc_req *);
+extern  nis_error * nis_updkeys_3 __P ((nis_name *, CLIENT *));
+extern  nis_error * nis_updkeys_3_svc __P ((nis_name *, struct svc_req *));
 
-#elif __STDC__
-#define NIS_LOOKUP ((u_long)1)
-extern  nis_result * nis_lookup_3(ns_request *, CLIENT *);
-extern  nis_result * nis_lookup_3_svc(ns_request *, struct svc_req *);
-#define NIS_ADD ((u_long)2)
-extern  nis_result * nis_add_3(ns_request *, CLIENT *);
-extern  nis_result * nis_add_3_svc(ns_request *, struct svc_req *);
-#define NIS_MODIFY ((u_long)3)
-extern  nis_result * nis_modify_3(ns_request *, CLIENT *);
-extern  nis_result * nis_modify_3_svc(ns_request *, struct svc_req *);
-#define NIS_REMOVE ((u_long)4)
-extern  nis_result * nis_remove_3(ns_request *, CLIENT *);
-extern  nis_result * nis_remove_3_svc(ns_request *, struct svc_req *);
-#define NIS_IBLIST ((u_long)5)
-extern  nis_result * nis_iblist_3(ib_request *, CLIENT *);
-extern  nis_result * nis_iblist_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBADD ((u_long)6)
-extern  nis_result * nis_ibadd_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibadd_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBMODIFY ((u_long)7)
-extern  nis_result * nis_ibmodify_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibmodify_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBREMOVE ((u_long)8)
-extern  nis_result * nis_ibremove_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibremove_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBFIRST ((u_long)9)
-extern  nis_result * nis_ibfirst_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibfirst_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBNEXT ((u_long)10)
-extern  nis_result * nis_ibnext_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibnext_3_svc(ib_request *, struct svc_req *);
-#define NIS_FINDDIRECTORY ((u_long)12)
-extern  fd_result * nis_finddirectory_3(fd_args *, CLIENT *);
-extern  fd_result * nis_finddirectory_3_svc(fd_args *, struct svc_req *);
-#define NIS_STATUS ((u_long)14)
-extern  nis_taglist * nis_status_3(nis_taglist *, CLIENT *);
-extern  nis_taglist * nis_status_3_svc(nis_taglist *, struct svc_req *);
-#define NIS_DUMPLOG ((u_long)15)
-extern  log_result * nis_dumplog_3(dump_args *, CLIENT *);
-extern  log_result * nis_dumplog_3_svc(dump_args *, struct svc_req *);
-#define NIS_DUMP ((u_long)16)
-extern  log_result * nis_dump_3(dump_args *, CLIENT *);
-extern  log_result * nis_dump_3_svc(dump_args *, struct svc_req *);
-#define NIS_CALLBACK ((u_long)17)
-extern  bool_t * nis_callback_3(netobj *, CLIENT *);
-extern  bool_t * nis_callback_3_svc(netobj *, struct svc_req *);
-#define NIS_CPTIME ((u_long)18)
-extern  u_long * nis_cptime_3(nis_name *, CLIENT *);
-extern  u_long * nis_cptime_3_svc(nis_name *, struct svc_req *);
-#define NIS_CHECKPOINT ((u_long)19)
-extern  cp_result * nis_checkpoint_3(nis_name *, CLIENT *);
-extern  cp_result * nis_checkpoint_3_svc(nis_name *, struct svc_req *);
-#define NIS_PING ((u_long)20)
-extern  void * nis_ping_3(ping_args *, CLIENT *);
-extern  void * nis_ping_3_svc(ping_args *, struct svc_req *);
-#define NIS_SERVSTATE ((u_long)21)
-extern  nis_taglist * nis_servstate_3(nis_taglist *, CLIENT *);
-extern  nis_taglist * nis_servstate_3_svc(nis_taglist *, struct svc_req *);
-#define NIS_MKDIR ((u_long)22)
-extern  nis_error * nis_mkdir_3(nis_name *, CLIENT *);
-extern  nis_error * nis_mkdir_3_svc(nis_name *, struct svc_req *);
-#define NIS_RMDIR ((u_long)23)
-extern  nis_error * nis_rmdir_3(nis_name *, CLIENT *);
-extern  nis_error * nis_rmdir_3_svc(nis_name *, struct svc_req *);
-#define NIS_UPDKEYS ((u_long)24)
-extern  nis_error * nis_updkeys_3(nis_name *, CLIENT *);
-extern  nis_error * nis_updkeys_3_svc(nis_name *, struct svc_req *);
-
-#else /* Old Style C */
-#define NIS_LOOKUP ((u_long)1)
-extern  nis_result * nis_lookup_3();
-extern  nis_result * nis_lookup_3_svc();
-#define NIS_ADD ((u_long)2)
-extern  nis_result * nis_add_3();
-extern  nis_result * nis_add_3_svc();
-#define NIS_MODIFY ((u_long)3)
-extern  nis_result * nis_modify_3();
-extern  nis_result * nis_modify_3_svc();
-#define NIS_REMOVE ((u_long)4)
-extern  nis_result * nis_remove_3();
-extern  nis_result * nis_remove_3_svc();
-#define NIS_IBLIST ((u_long)5)
-extern  nis_result * nis_iblist_3();
-extern  nis_result * nis_iblist_3_svc();
-#define NIS_IBADD ((u_long)6)
-extern  nis_result * nis_ibadd_3();
-extern  nis_result * nis_ibadd_3_svc();
-#define NIS_IBMODIFY ((u_long)7)
-extern  nis_result * nis_ibmodify_3();
-extern  nis_result * nis_ibmodify_3_svc();
-#define NIS_IBREMOVE ((u_long)8)
-extern  nis_result * nis_ibremove_3();
-extern  nis_result * nis_ibremove_3_svc();
-#define NIS_IBFIRST ((u_long)9)
-extern  nis_result * nis_ibfirst_3();
-extern  nis_result * nis_ibfirst_3_svc();
-#define NIS_IBNEXT ((u_long)10)
-extern  nis_result * nis_ibnext_3();
-extern  nis_result * nis_ibnext_3_svc();
-#define NIS_FINDDIRECTORY ((u_long)12)
-extern  fd_result * nis_finddirectory_3();
-extern  fd_result * nis_finddirectory_3_svc();
-#define NIS_STATUS ((u_long)14)
-extern  nis_taglist * nis_status_3();
-extern  nis_taglist * nis_status_3_svc();
-#define NIS_DUMPLOG ((u_long)15)
-extern  log_result * nis_dumplog_3();
-extern  log_result * nis_dumplog_3_svc();
-#define NIS_DUMP ((u_long)16)
-extern  log_result * nis_dump_3();
-extern  log_result * nis_dump_3_svc();
-#define NIS_CALLBACK ((u_long)17)
-extern  bool_t * nis_callback_3();
-extern  bool_t * nis_callback_3_svc();
-#define NIS_CPTIME ((u_long)18)
-extern  u_long * nis_cptime_3();
-extern  u_long * nis_cptime_3_svc();
-#define NIS_CHECKPOINT ((u_long)19)
-extern  cp_result * nis_checkpoint_3();
-extern  cp_result * nis_checkpoint_3_svc();
-#define NIS_PING ((u_long)20)
-extern  void * nis_ping_3();
-extern  void * nis_ping_3_svc();
-#define NIS_SERVSTATE ((u_long)21)
-extern  nis_taglist * nis_servstate_3();
-extern  nis_taglist * nis_servstate_3_svc();
-#define NIS_MKDIR ((u_long)22)
-extern  nis_error * nis_mkdir_3();
-extern  nis_error * nis_mkdir_3_svc();
-#define NIS_RMDIR ((u_long)23)
-extern  nis_error * nis_rmdir_3();
-extern  nis_error * nis_rmdir_3_svc();
-#define NIS_UPDKEYS ((u_long)24)
-extern  nis_error * nis_updkeys_3();
-extern  nis_error * nis_updkeys_3_svc();
-#endif /* Old Style C */
-struct rpcgen_table {
-#if defined __cplusplus || __STDC__
-	char	*(*proc)(void);
-#else
-	char	*(*proc)();
-#endif
-	xdrproc_t	xdr_arg;
-	unsigned	len_arg;
-	xdrproc_t	xdr_res;
-	unsigned	len_res;
-};
+__END_DECLS
 
 #endif /* !_NIS_H_RPCGEN */
diff --git a/posix/globtest.c b/posix/globtest.c
index 589e91b973..7008a8bcd1 100644
--- a/posix/globtest.c
+++ b/posix/globtest.c
@@ -18,6 +18,7 @@
 
 #include <stdio.h>
 #include <glob.h>
+#include <unistd.h>
 
 int
 main (int argc, char *argv[])
@@ -26,7 +27,11 @@ main (int argc, char *argv[])
   int glob_flags = GLOB_NOSORT;
   glob_t filenames;
 
-  i = glob (argv[1], glob_flags, NULL, &filenames);
+  if (argc != 3)
+    exit (1);
+  if (chdir (argv[1]))
+    exit (1);
+  i = glob (argv[2], glob_flags, NULL, &filenames);
 
   if (i == GLOB_NOSPACE)
     puts ("GLOB_NOSPACE");
diff --git a/posix/globtest.sh b/posix/globtest.sh
index c51655b9b3..61fec9874c 100755
--- a/posix/globtest.sh
+++ b/posix/globtest.sh
@@ -20,10 +20,9 @@ echo 1_2 > $testdir/dir1/file1_2
 
 # Run some tests.
 result=0
-here=`pwd`
 
-(cd $testdir &&
- LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*") |
+LD_LIBRARY_PATH=$common_objpfx \
+${common_objpfx}posix/globtest "$testdir" "*" |
 sort > $testout
 cat <<"EOF" | cmp - $testout || result=1
 `dir1'
@@ -33,8 +32,8 @@ cat <<"EOF" | cmp - $testout || result=1
 not NULL
 EOF
 
-(cd $testdir &&
- LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*/*") |
+LD_LIBRARY_PATH=$common_objpfx \
+${common_objpfx}posix/globtest "$testdir" "*/*" |
 sort > $testout
 cat <<"EOF" | cmp - $testout || result=1
 `dir1/file1_1'
@@ -42,40 +41,40 @@ cat <<"EOF" | cmp - $testout || result=1
 not NULL
 EOF
 
-(cd $testdir &&
- LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*/1") |
+LD_LIBRARY_PATH=$common_objpfx \
+${common_objpfx}posix/globtest "$testdir" "*/1" |
 sort > $testout
 cat <<"EOF" | cmp - $testout || result=1
 GLOB_NOMATCH
 NULL
 EOF
 
-(cd $testdir &&
- LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*/*1_1") |
+LD_LIBRARY_PATH=$common_objpfx \
+${common_objpfx}posix/globtest "$testdir" "*/*1_1" |
 sort > $testout
 cat <<"EOF" | cmp - $testout || result=1
 `dir1/file1_1'
 not NULL
 EOF
 
-(cd $testdir &&
- LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*/file1_1") |
+LD_LIBRARY_PATH=$common_objpfx \
+${common_objpfx}posix/globtest "$testdir" "*/file1_1" |
 sort > $testout
 cat <<"EOF" | cmp - $testout || result=1
 `dir1/file1_1'
 not NULL
 EOF
 
-(cd $testdir &&
- LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*-/*") |
+LD_LIBRARY_PATH=$common_objpfx \
+${common_objpfx}posix/globtest "$testdir" "*-/*" |
 sort > $testout
 cat <<"EOF" | cmp - $testout || result=1
 GLOB_NOMATCH
 NULL
 EOF
 
-(cd $testdir &&
- LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*-") |
+LD_LIBRARY_PATH=$common_objpfx \
+${common_objpfx}posix/globtest "$testdir" "*-" |
 sort > $testout
 cat <<"EOF" | cmp - $testout || result=1
 GLOB_NOMATCH
diff --git a/string/bits/string2.h b/string/bits/string2.h
index b0e9cdcb8a..51255aaf4c 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -22,7 +22,7 @@
 # error "Never use <bits/string2.h> directly; include <string.h> instead."
 #endif
 
-#ifdef __NO_STRING_INLINES
+#ifndef __NO_STRING_INLINES
 
 /* Unlike the definitions in the header <bits/string.h> the
    definitions contained here are not optimizing down to assembler
@@ -100,102 +100,101 @@ __STRING2_COPY_TYPE (8);
 
 # if _STRING_ARCH_unaligned
 #  define __strcpy_small(dest, src, srclen) \
-  (__extension__ ({ char *__retval = (dest);				      \
-		    char *__cp = __retval;				      \
+  (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);	      \
 		    switch (srclen)					      \
 		      {							      \
 		      case 1:						      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 2:						      \
-			*((__uint16_t *) __cp) =			      \
+			*((__uint16_t *) __dest) =			      \
 			  __STRING2_SMALL_GET16 (src, 0);		      \
 			break;						      \
 		      case 3:						      \
-			*((__uint16_t *) __cp)++ =			      \
+			*((__uint16_t *) __dest) =			      \
 			  __STRING2_SMALL_GET16 (src, 0);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*(__dest + 2) = '\0';				      \
 			break;						      \
 		      case 4:						      \
-			*((__uint32_t *) __cp) =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
 			break;						      \
 		      case 5:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*(__dest + 4) = '\0';				      \
 			break;						      \
 		      case 6:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			*((__uint16_t *) __cp) =			      \
+			*((__uint16_t *) (__dest + 4)) =		      \
 			  __STRING2_SMALL_GET16 (src, 4);		      \
 			break;						      \
 		      case 7:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			*((__uint16_t *) __cp)++ =			      \
+			*((__uint16_t *) (__dest + 4)) =		      \
 			  __STRING2_SMALL_GET16 (src, 4);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*(__dest + 6) = '\0';				      \
 			break;						      \
 		      case 8:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			*((__uint32_t *) __cp) =			      \
+			*((__uint32_t *) (__dest + 4)) =		      \
 			  __STRING2_SMALL_GET32 (src, 4);		      \
 			break;						      \
 		      }							      \
-		    __retval; }))
+		    (char *) __dest; }))
 # else
 #  define __strcpy_small(dest, src, srclen) \
-  (__extension__ ({ char *__cp = (dest);				      \
+  (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);	      \
 		    switch (srclen)					      \
 		      {							      \
 		      case 1:						      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 2:						      \
-			*((__STRING2_COPY_ARR2 *) __cp) =		      \
+			*((__STRING2_COPY_ARR2 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR2) { { (src)[0], '\0' } });     \
 			break;						      \
 		      case 3:						      \
-			*((__STRING2_COPY_ARR3 *) __cp) =		      \
+			*((__STRING2_COPY_ARR3 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR3) { { (src)[0], (src)[1],      \
 						     '\0' } });		      \
 			break;						      \
 		      case 4:						      \
-			*((__STRING2_COPY_ARR4 *) __cp) =		      \
+			*((__STRING2_COPY_ARR4 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR4) { { (src)[0], (src)[1],      \
 						     (src)[2], '\0' } });     \
 			break;						      \
 		      case 5:						      \
-			*((__STRING2_COPY_ARR5 *) __cp) =		      \
+			*((__STRING2_COPY_ARR5 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR5) { { (src)[0], (src)[1],      \
 						     (src)[2], (src)[3],      \
 						     '\0' } });		      \
 			break;						      \
 		      case 6:						      \
-			*((__STRING2_COPY_ARR6 *) __cp) =		      \
+			*((__STRING2_COPY_ARR6 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR6) { { (src)[0], (src)[1],      \
 						     (src)[2], (src)[3],      \
 						     (src)[4], '\0' } });     \
 			break;						      \
 		      case 7:						      \
-			*((__STRING2_COPY_ARR7 *) __cp) =		      \
+			*((__STRING2_COPY_ARR7 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR7) { { (src)[0], (src)[1],      \
 						     (src)[2], (src)[3],      \
 						     (src)[4], (src)[5],      \
 						     '\0' } });		      \
 			break;						      \
 		      case 8:						      \
-			*((__STRING2_COPY_ARR8 *) __cp) =		      \
+			*((__STRING2_COPY_ARR8 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR8) { { (src)[0], (src)[1],      \
 						     (src)[2], (src)[3],      \
 						     (src)[4], (src)[5],      \
 						     (src)[6], '\0' } });     \
 			break;						      \
 		    }							      \
-		  __cp; }))
+		  (char *) __dest; }))
 # endif
 #endif
 
@@ -215,105 +214,106 @@ __STRING2_COPY_TYPE (8);
 
 #  if _STRING_ARCH_unaligned
 #   define __stpcpy_small(dest, src, srclen) \
-  (__extension__ ({ char *__cp = (dest);				      \
+  (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);	      \
 		    switch (srclen)					      \
 		      {							      \
 		      case 1:						      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 2:						      \
-			*((__uint16_t *) __cp) =			      \
+			*((__uint16_t *) __dest) =			      \
 			  __STRING2_SMALL_GET16 (src, 0);		      \
-			++__cp;						      \
+			++__dest;					      \
 			break;						      \
 		      case 3:						      \
-			*((__uint16_t *) __cp)++ =			      \
+			*((__uint16_t *) __dest)++ =			      \
 			  __STRING2_SMALL_GET16 (src, 0);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 4:						      \
-			*((__uint32_t *) __cp) =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			__cp += 3;					      \
+			__dest += 3;					      \
 			break;						      \
 		      case 5:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest)++ =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 6:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			*((__uint16_t *) __cp) =			      \
+			*((__uint16_t *) (__dest + 4)) =		      \
 			  __STRING2_SMALL_GET16 (src, 4);		      \
-			++__cp;						      \
+			__dest += 5;					      \
 			break;						      \
 		      case 7:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			*((__uint16_t *) __cp)++ =			      \
+			*((__uint16_t *) (__dest + 4)) =		      \
 			  __STRING2_SMALL_GET16 (src, 4);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			__dest += 6;					      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 8:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING2_SMALL_GET32 (src, 0);		      \
-			*((__uint32_t *) __cp) =			      \
+			*((__uint32_t *) (__dest + 4)) =		      \
 			  __STRING2_SMALL_GET32 (src, 4);		      \
-			__cp += 3;					      \
+			__dest += 7;					      \
 			break;						      \
 		      }							      \
-		    __cp; }))
+		    (char *) __dest; }))
 #  else
 #   define __stpcpy_small(dest, src, srclen) \
-  (__extension__ ({ char *__cp = (dest);				      \
+  (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);	      \
 		    switch (srclen)					      \
 		      {							      \
 		      case 1:						      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 2:						      \
-			*((__STRING2_COPY_ARR2 *) __cp) =		      \
+			*((__STRING2_COPY_ARR2 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR2) { { (src)[0], '\0' } });     \
 			break;						      \
 		      case 3:						      \
-			*((__STRING2_COPY_ARR3 *) __cp) =		      \
+			*((__STRING2_COPY_ARR3 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR3) { { (src)[0], (src)[1],      \
 						     '\0' } });		      \
 			break;						      \
 		      case 4:						      \
-			*((__STRING2_COPY_ARR4 *) __cp) =		      \
+			*((__STRING2_COPY_ARR4 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR4) { { (src)[0], (src)[1],      \
 						     (src)[2], '\0' } });     \
 			break;						      \
 		      case 5:						      \
-			*((__STRING2_COPY_ARR5 *) __cp) =		      \
+			*((__STRING2_COPY_ARR5 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR5) { { (src)[0], (src)[1],      \
 						     (src)[2], (src)[3],      \
 						     '\0' } });		      \
 			break;						      \
 		      case 6:						      \
-			*((__STRING2_COPY_ARR6 *) __cp) =		      \
+			*((__STRING2_COPY_ARR6 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR6) { { (src)[0], (src)[1],      \
 						     (src)[2], (src)[3],      \
 						     (src)[4], '\0' } });     \
 			break;						      \
 		      case 7:						      \
-			*((__STRING2_COPY_ARR7 *) __cp) =		      \
+			*((__STRING2_COPY_ARR7 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR7) { { (src)[0], (src)[1],      \
 						     (src)[2], (src)[3],      \
 						     (src)[4], (src)[5],      \
 						     '\0' } });		      \
 			break;						      \
 		      case 8:						      \
-			*((__STRING2_COPY_ARR8 *) __cp) =		      \
+			*((__STRING2_COPY_ARR8 *) __dest) =		      \
 			  ((__STRING2_COPY_ARR8) { { (src)[0], (src)[1],      \
 						     (src)[2], (src)[3],      \
 						     (src)[4], (src)[5],      \
 						     (src)[6], '\0' } });     \
 			break;						      \
 		    }							      \
-		  __cp + ((srclen) - 1); }))
+		  (char *) (__dest + ((srclen) - 1)); }))
 #  endif
 # endif
 #endif
@@ -323,13 +323,14 @@ __STRING2_COPY_TYPE (8);
 #ifndef _HAVE_STRING_ARCH_strncpy
 # if defined _HAVE_STRING_ARCH_memset && defined _HAVE_STRING_ARCH_mempcpy
 #  define strncpy(dest, src, n) \
-  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
-		  ? (strlen (src) + 1 >= ((size_t) (n))			      \
-		     ? (char *) memcpy (dest, src, n)			      \
-		     : (memset (__mempcpy (dest, src, strlen (src)), '\0',    \
-				n - strlen (src)),			      \
-			(char *) dest))					      \
-		  : strncpy (dest, src, n)))
+  (__extension__ ({ char *__dest = (dest);				      \
+		    __builtin_constant_p (src) && __builtin_constant_p (n)    \
+		    ? (strlen (src) + 1 >= ((size_t) (n))		      \
+		       ? (char *) memcpy (__dest, src, n)		      \
+		       : (memset (__mempcpy (__dest, src, strlen (src)),      \
+				  '\0', n - strlen (src)),		      \
+			  __dest))					      \
+		    : strncpy (__dest, src, n); }))
 # else
 #  define strncpy(dest, src, n) \
   (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
@@ -345,11 +346,12 @@ __STRING2_COPY_TYPE (8);
 #ifndef _HAVE_STRING_ARCH_strncat
 # ifdef _HAVE_STRING_ARCH_strchr
 #  define strncat(dest, src, n) \
-  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
-		  ? (strlen (src) < ((size_t) (n))			      \
-		     ? strcat (dest, src)				      \
-		     : (memcpy (strchr (dest, '\0'), src, n), (char *) dest)) \
-		  : strncat (dest, src, n)))
+  (__extension__ ({ char *__dest = (dest);				      \
+		    __builtin_constant_p (src) && __builtin_constant_p (n)    \
+		    ? (strlen (src) < ((size_t) (n))			      \
+		       ? strcat (__dest, src)				      \
+		       : (memcpy (strchr (__dest, '\0'), src, n), __dest))    \
+		    : strncat (dest, src, n); }))
 # else
 #  define strncat(dest, src, n) \
   (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
@@ -361,6 +363,54 @@ __STRING2_COPY_TYPE (8);
 #endif
 
 
+/* Compare characters of S1 and S2.  */
+#ifndef _HAVE_STRING_ARCH_strcmp
+# define strcmp(s1, s2) \
+  (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2)      \
+		  && (sizeof (s1)[0] != 1 || strlen (s1) >= 4)		      \
+		  && (sizeof (s2)[0] != 1 || strlen (s2) >= 4)		      \
+		  ? memcmp (s1, s2, (strlen (s1) < strlen (s2)		      \
+				     ? strlen (s1) : strlen (s2)) + 1)	      \
+		  : (__builtin_constant_p (s1) && sizeof (s1)[0] == 1	      \
+		     && sizeof (s2)[0] == 1 && strlen (s1) < 4		      \
+		     ? __strcmp_cg (s1, s2, strlen (s1))		      \
+		     : (__builtin_constant_p (s2) && sizeof (s1)[0] == 1      \
+			&& sizeof (s2)[0] == 1 && strlen (s2) < 4	      \
+			? __strcmp_gc (s1, s2, strlen (s2))		      \
+			: strcmp (s1, s2)))))
+
+# define __strcmp_cg(s1, s2, l1) \
+  (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2);     \
+		    register int __result = (unsigned char) (s1)[0] - __s2[0];\
+		    if (l1 > 0 && __result == 0)			      \
+		      {							      \
+			__result = (unsigned char) (s1)[1] - __s2[1];	      \
+			if (l1 > 1 && __result == 0)			      \
+			  {						      \
+			    __result = (unsigned char) (s1)[2] - __s2[2];     \
+			    if (l1 > 2 && __result == 0)		      \
+			      __result = (unsigned char) (s1)[3] - __s2[3];   \
+			  }						      \
+		      }							      \
+		    __result; }))
+
+# define __strcmp_gc(s1, s2, l2) \
+  (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1);     \
+		    register int __result = __s1[0] - (unsigned char) (s2)[0];\
+		    if (l2 > 0 && __result == 0)			      \
+		      {							      \
+			__result = __s1[1] - (unsigned char) (s2)[1];	      \
+			if (l2 > 1 && __result == 0)			      \
+			  {						      \
+			    __result = __s1[2] - (unsigned char) (s2)[2];     \
+			    if (l2 > 2 && __result == 0)		      \
+			      __result = __s1[3] - (unsigned char) (s2)[3];   \
+			  }						      \
+		      }							      \
+		    __result; }))
+#endif
+
+
 /* Compare N characters of S1 and S2.  */
 #ifndef _HAVE_STRING_ARCH_strncmp
 # define strncmp(s1, s2, n) \
@@ -474,26 +524,26 @@ __STRING_INLINE char *__strsep_1c (char **__s, char __reject);
 __STRING_INLINE char *
 __strsep_1c (char **__s, char __reject)
 {
-  register __const char *__retval = *__s;
+  register char *__retval = *__s;
   if (__retval == NULL || *__retval == '\0')
     return NULL;
   while (*__retval == __reject)
     ++__retval;
   if ((*__s = strchr (__retval, __reject)) != NULL)
     *(*__s)++ = '\0';
-  return (char *) __retval;
+  return __retval;
 }
 
 __STRING_INLINE char *__strsep_g (char **__s, __const char *__reject);
 __STRING_INLINE char *
 __strsep_g (char **__s, __const char *__reject)
 {
-  register __const char *__retval = *__s;
+  register char *__retval = *__s;
   if (__retval == NULL || *__retval == '\0')
     return NULL;
   if ((*__s = strpbrk (__retval, __reject)) != NULL)
     *(*__s)++ = '\0';
-  return (char *) __retval;
+  return __retval;
 }
 # endif
 #endif
diff --git a/sunrpc/get_myaddr.c b/sunrpc/get_myaddr.c
index d45cb6d908..757fe06718 100644
--- a/sunrpc/get_myaddr.c
+++ b/sunrpc/get_myaddr.c
@@ -1,4 +1,4 @@
-/* @(#)get_myaddress.c	2.1 88/07/29 4.0 RPCSRC */
+/* @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC */
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  * unrestricted use provided that this legend is included on all tape
@@ -38,13 +38,11 @@ static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";
  * Copyright (C) 1984, Sun Microsystems, Inc.
  */
 
-#include <unistd.h>
 #include <rpc/types.h>
 #include <rpc/pmap_prot.h>
 #include <sys/socket.h>
 #include <stdio.h>
-#undef	 _POSIX_SOURCE		/* Ultrix <sys/param.h> needs --roland@gnu */
-#include <sys/param.h>		/* Ultrix needs before net/if --roland@gnu */
+#include <unistd.h>
 #include <net/if.h>
 #include <sys/ioctl.h>
 /* Order of following two #includes reversed by roland@gnu */
@@ -53,6 +51,9 @@ static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";
 
 /*
  * don't use gethostbyname, which would invoke yellow pages
+ *
+ * Avoid loopback interfaces.  We return information from a loopback
+ * interface only if there are no other possible interfaces.
  */
 void
 get_myaddress (struct sockaddr_in *addr)
@@ -61,7 +62,7 @@ get_myaddress (struct sockaddr_in *addr)
   char buf[BUFSIZ];
   struct ifconf ifc;
   struct ifreq ifreq, *ifr;
-  int len;
+  int len, loopback = 0;
 
   if ((s = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
     {
@@ -75,23 +76,32 @@ get_myaddress (struct sockaddr_in *addr)
       perror (_("get_myaddress: ioctl (get interface configuration)"));
       exit (1);
     }
+
+ again:
   ifr = ifc.ifc_req;
   for (len = ifc.ifc_len; len; len -= sizeof ifreq)
     {
       ifreq = *ifr;
       if (ioctl (s, SIOCGIFFLAGS, (char *) &ifreq) < 0)
 	{
-	  perror ("get_myaddress: ioctl");
-	  exit (1);
+          perror ("get_myaddress: ioctl");
+          exit (1);
 	}
-      if ((ifreq.ifr_flags & IFF_UP) &&
-	  ifr->ifr_addr.sa_family == AF_INET)
+      if ((ifreq.ifr_flags & IFF_UP) && (ifr->ifr_addr.sa_family == AF_INET)
+	  && (!(ifreq.ifr_flags & IFF_LOOPBACK) ||
+	      (loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK))))
 	{
 	  *addr = *((struct sockaddr_in *) &ifr->ifr_addr);
 	  addr->sin_port = htons (PMAPPORT);
-	  break;
+	  close (s);
+	  return;
 	}
       ifr++;
     }
-  (void) close (s);
+  if (loopback == 0)
+    {
+      loopback = 1;
+      goto again;
+    }
+  close (s);
 }
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index f9913cf00c..041643ef5a 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -121,6 +121,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
    and then redirect to the address it returns.  */
 #ifndef PROF
 # define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
+	.text
 	.globl _dl_runtime_resolve
 	.type _dl_runtime_resolve, @function
 	.align 16
@@ -153,9 +154,11 @@ _dl_runtime_profile:
 	xchgl %eax, (%esp)	# Get %eax contents end store function address.
 	ret $8			# Jump to function address.
 	.size _dl_runtime_profile, .-_dl_runtime_profile
+	.previous
 ");
 #else
 # define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
+	.text
 	.globl _dl_runtime_resolve
 	.globl _dl_runtime_profile
 	.type _dl_runtime_resolve, @function
@@ -179,6 +182,7 @@ _dl_runtime_profile:
 	ret $8			# Jump to function address.
 	.size _dl_runtime_resolve, .-_dl_runtime_resolve
 	.size _dl_runtime_profile, .-_dl_runtime_profile
+	.previous
 ");
 #endif
 /* The PLT uses Elf32_Rel relocs.  */
diff --git a/sysdeps/i386/i486/atomicity.h b/sysdeps/i386/i486/atomicity.h
index 7157bc33d8..da4137abe1 100644
--- a/sysdeps/i386/i486/atomicity.h
+++ b/sysdeps/i386/i486/atomicity.h
@@ -28,7 +28,7 @@ __attribute__ ((unused))
 exchange_and_add (volatile uint32_t *mem, int val)
 {
   register int result;
-  __asm__ __volatile__ ("lock; xaddl %0,%1"
+  __asm__ __volatile__ ("lock; xaddl %0,%2"
 			: "=r" (result) : "0" (val), "m" (*mem) : "memory");
   return result;
 }
diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h
index 10915ced1d..28ca38315e 100644
--- a/sysdeps/i386/i486/bits/string.h
+++ b/sysdeps/i386/i486/bits/string.h
@@ -344,7 +344,7 @@ memchr (__const void *__s, int __c, size_t __n)
 #define _HAVE_STRING_ARCH_strlen 1
 #define strlen(str) \
   (__extension__ (__builtin_constant_p (str)				      \
-		  ? sizeof (str) - 1					      \
+		  ? __builtin_strlen (str)				      \
 		  : __strlen_g (str)))
 __STRING_INLINE size_t
 __strlen_g (__const char *__str)
@@ -374,52 +374,51 @@ __strlen_g (__const char *__str)
 		  : __strcpy_g (dest, src)))
 
 # define __strcpy_small(dest, src, srclen) \
-  (__extension__ ({ char *__retval = (dest);				      \
-		    char *__cp = __retval;				      \
+  (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);	      \
 		    switch (srclen)					      \
 		      {							      \
 		      case 1:						      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 2:						      \
-			*((__uint16_t *) __cp) =			      \
+			*((__uint16_t *) __dest) =			      \
 			  __STRING_SMALL_GET16 (src, 0);		      \
 			break;						      \
 		      case 3:						      \
-			*((__uint16_t *) __cp)++ =			      \
+			*((__uint16_t *) __dest) =			      \
 			  __STRING_SMALL_GET16 (src, 0);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*(__dest + 2) = '\0';				      \
 			break;						      \
 		      case 4:						      \
-			*((__uint32_t *) __cp) =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
 			break;						      \
 		      case 5:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*(__dest + 4) = '\0';				      \
 			break;						      \
 		      case 6:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			*((__uint16_t *) __cp) =			      \
+			*((__uint16_t *) (__dest + 4)) =		      \
 			  __STRING_SMALL_GET16 (src, 4);		      \
 			break;						      \
 		      case 7:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			*((__uint16_t *) __cp)++ =			      \
+			*((__uint16_t *) (__dest + 4)) =		      \
 			  __STRING_SMALL_GET16 (src, 4);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*(__dest + 6) = '\0';				      \
 			break;						      \
 		      case 8:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			*((__uint32_t *) __cp) =			      \
+			*((__uint32_t *) (__dest + 4)) =		      \
 			  __STRING_SMALL_GET32 (src, 4);		      \
 			break;						      \
 		      }							      \
-		    __retval; }))
+		    (char *) __dest; }))
 
 __STRING_INLINE char *
 __strcpy_g (char *__dest, __const char *__src)
@@ -453,64 +452,65 @@ __strcpy_g (char *__dest, __const char *__src)
 		  : __stpcpy_g (dest, src)))
 # define __stpcpy_c(dest, src, srclen) \
   ((srclen) % 4 == 0							      \
-   ? __mempcpy_by4 (dest, src, srclen)					      \
+   ? __mempcpy_by4 (dest, src, srclen) - 1				      \
    : ((srclen) % 2 == 0							      \
-      ? __mempcpy_by2 (dest, src, srclen)				      \
-      : __mempcpy_byn (dest, src, srclen)))
+      ? __mempcpy_by2 (dest, src, srclen) - 1				      \
+      : __mempcpy_byn (dest, src, srclen) - 1))
 
 /* In glibc itself we use this symbol for namespace reasons.  */
 # define stpcpy(dest, src) __stpcpy (dest, src)
 
 # define __stpcpy_small(dest, src, srclen) \
-  (__extension__ ({ char *__cp = (dest);				      \
+  (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest);	      \
 		    switch (srclen)					      \
 		      {							      \
 		      case 1:						      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 2:						      \
-			*((__uint16_t *) __cp) =			      \
+			*((__uint16_t *) __dest) =			      \
 			  __STRING_SMALL_GET16 (src, 0);		      \
-			++__cp;						      \
+			++__dest;					      \
 			break;						      \
 		      case 3:						      \
-			*((__uint16_t *) __cp)++ =			      \
+			*((__uint16_t *) __dest)++ =			      \
 			  __STRING_SMALL_GET16 (src, 0);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 4:						      \
-			*((__uint32_t *) __cp) =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			__cp += 3;					      \
+			__dest += 3;					      \
 			break;						      \
 		      case 5:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest)++ =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 6:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			*((__uint16_t *) __cp) =			      \
+			*((__uint16_t *) (__dest + 4)) =		      \
 			  __STRING_SMALL_GET16 (src, 4);		      \
-			++__cp;						      \
+			__dest += 5;					      \
 			break;						      \
 		      case 7:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			*((__uint16_t *) __cp)++ =			      \
+			*((__uint16_t *) (__dest + 4)) =		      \
 			  __STRING_SMALL_GET16 (src, 4);		      \
-			*((unsigned char *) __cp) = '\0';		      \
+			__dest += 6;					      \
+			*__dest = '\0';					      \
 			break;						      \
 		      case 8:						      \
-			*((__uint32_t *) __cp)++ =			      \
+			*((__uint32_t *) __dest) =			      \
 			  __STRING_SMALL_GET32 (src, 0);		      \
-			*((__uint32_t *) __cp) =			      \
+			*((__uint32_t *) (__dest + 4)) =		      \
 			  __STRING_SMALL_GET32 (src, 4);		      \
-			__cp += 3;					      \
+			__dest += 7;					      \
 			break;						      \
 		      }							      \
-		    __cp; }))
+		    (char *) __dest; }))
 
 __STRING_INLINE char *
 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
@@ -528,7 +528,7 @@ __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
      : "=r" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
      : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
      : "memory", "cc");
-  return __tmp - 1;
+  return __tmp;
 }
 
 __STRING_INLINE char *
@@ -552,7 +552,7 @@ __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
      : "=q" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
      : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
      : "memory", "cc");
-  return __tmp + 1;
+  return __tmp + 2;
 }
 
 __STRING_INLINE char *
@@ -573,7 +573,7 @@ __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
      : "=D" (__tmp)
      : "c" (__srclen), "0" (__tmp),"S" (__src)
      : "cx", "di", "si", "memory", "cc");
-  return __tmp - 1;
+  return __tmp;
 }
 
 __STRING_INLINE char *
@@ -760,11 +760,12 @@ __strcat_g (char *__dest, __const char *__src)
 /* Append no more than N characters from SRC onto DEST.  */
 #define _HAVE_STRING_ARCH_strncat 1
 #define strncat(dest, src, n) \
-  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
-		  ? (strlen (src) < ((size_t) (n))			      \
-		     ? strcat (dest, src)				      \
-		     : (memcpy (strchr (dest, '\0'), src, n), dest))	      \
-		  : __strncat_g (dest, src, n)))
+  (__extension__ ({ char *__dest = (dest);				      \
+		    __builtin_constant_p (src) && __builtin_constant_p (n)    \
+		    ? (strlen (src) < ((size_t) (n))			      \
+		       ? strcat (__dest, src)				      \
+		       : (memcpy (strchr (__dest, '\0'), src, n), __dest))    \
+		    : __strncat_g (__dest, src, n); }))
 
 __STRING_INLINE char *
 __strncat_g (char *__dest, __const char __src[], size_t __n)
@@ -797,8 +798,52 @@ __strncat_g (char *__dest, __const char __src[], size_t __n)
 
 /* Compare S1 and S2.  */
 #define _HAVE_STRING_ARCH_strcmp 1
+#define strcmp(s1, s2) \
+  (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2)      \
+		  && (sizeof (s1)[0] != 1 || strlen (s1) >= 4)		      \
+		  && (sizeof (s2)[0] != 1 || strlen (s2) >= 4)		      \
+		  ? memcmp (s1, s2, (strlen (s1) < strlen (s2)		      \
+				     ? strlen (s1) : strlen (s2)) + 1)	      \
+		  : (__builtin_constant_p (s1) && sizeof (s1)[0] == 1	      \
+		     && sizeof (s2)[0] == 1 && strlen (s1) < 4		      \
+		     ? __strcmp_cg (s1, s2, strlen (s1))		      \
+		     : (__builtin_constant_p (s2) && sizeof (s1)[0] == 1      \
+			&& sizeof (s2)[0] == 1 && strlen (s2) < 4	      \
+			? __strcmp_gc (s1, s2, strlen (s2))		      \
+			: __strcmp_gg (s1, s2)))))
+
+#define __strcmp_cg(s1, s2, l1) \
+  (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2);     \
+		    register int __result = (unsigned char) (s1)[0] - __s2[0];\
+		    if (l1 > 0 && __result == 0)			      \
+		      {							      \
+			__result = (unsigned char) (s1)[1] - __s2[1];	      \
+			if (l1 > 1 && __result == 0)			      \
+			  {						      \
+			    __result = (unsigned char) (s1)[2] - __s2[2];     \
+			    if (l1 > 2 && __result == 0)		      \
+			      __result = (unsigned char) (s1)[3] - __s2[3];   \
+			  }						      \
+		      }							      \
+		    __result; }))
+
+#define __strcmp_gc(s1, s2, l2) \
+  (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1);     \
+		    register int __result = __s1[0] - (unsigned char) (s2)[0];\
+		    if (l2 > 0 && __result == 0)			      \
+		      {							      \
+			__result = __s1[1] - (unsigned char) (s2)[1];	      \
+			if (l2 > 1 && __result == 0)			      \
+			  {						      \
+			    __result = __s1[2] - (unsigned char) (s2)[2];     \
+			    if (l2 > 2 && __result == 0)		      \
+			      __result = __s1[3] - (unsigned char) (s2)[3];   \
+			  }						      \
+		      }							      \
+		    __result; }))
+
 __STRING_INLINE int
-strcmp (__const char *__s1, __const char *__s2)
+__strcmp_gg (__const char *__s1, __const char *__s2)
 {
   register int __res;
   __asm__ __volatile__
diff --git a/sysdeps/libm-i387/s_exp2.S b/sysdeps/libm-i387/s_exp2.S
index 1afacf58cd..778c0c0eb6 100644
--- a/sysdeps/libm-i387/s_exp2.S
+++ b/sysdeps/libm-i387/s_exp2.S
@@ -6,7 +6,7 @@
 
 #include <machine/asm.h>
 
-ENTRY(__exp2)
+ENTRY(__ieee754_exp2)
 	fldl	4(%esp)
 /* I added the following ugly construct because exp(+-Inf) resulted
    in NaN.  The ugliness results from the bright minds at Intel.
@@ -34,5 +34,4 @@ ENTRY(__exp2)
 	fstp	%st
 	fldz				/* Set result to 0.  */
 2:	ret
-END (__exp2)
-weak_alias (__exp2, exp2)
+END (__ieee754_exp2)
diff --git a/sysdeps/libm-i387/s_exp2f.S b/sysdeps/libm-i387/s_exp2f.S
index 896583bf83..c2d1af1af1 100644
--- a/sysdeps/libm-i387/s_exp2f.S
+++ b/sysdeps/libm-i387/s_exp2f.S
@@ -6,7 +6,7 @@
 
 #include <machine/asm.h>
 
-ENTRY(__exp2f)
+ENTRY(__ieee754_exp2f)
 	flds	4(%esp)
 /* I added the following ugly construct because exp(+-Inf) resulted
    in NaN.  The ugliness results from the bright minds at Intel.
@@ -34,5 +34,4 @@ ENTRY(__exp2f)
 	fstp	%st
 	fldz				/* Set result to 0.  */
 2:	ret
-END (__exp2f)
-weak_alias (__exp2f, exp2f)
+END (__ieee754_exp2f)
diff --git a/sysdeps/libm-i387/s_exp2l.S b/sysdeps/libm-i387/s_exp2l.S
index 4b543d06f8..fa1fdc9236 100644
--- a/sysdeps/libm-i387/s_exp2l.S
+++ b/sysdeps/libm-i387/s_exp2l.S
@@ -6,7 +6,7 @@
 
 #include <machine/asm.h>
 
-ENTRY(__exp2l)
+ENTRY(__ieee754_exp2l)
 	fldt	4(%esp)
 /* I added the following ugly construct because exp(+-Inf) resulted
    in NaN.  The ugliness results from the bright minds at Intel.
@@ -34,5 +34,4 @@ ENTRY(__exp2l)
 	fstp	%st
 	fldz				/* Set result to 0.  */
 2:	ret
-END (__exp2l)
-weak_alias (__exp2l, exp2l)
+END (__ieee754_exp2l)
diff --git a/sysdeps/libm-ieee754/Dist b/sysdeps/libm-ieee754/Dist
new file mode 100644
index 0000000000..4b085470f5
--- /dev/null
+++ b/sysdeps/libm-ieee754/Dist
@@ -0,0 +1,2 @@
+t_exp2.h
+t_exp2f.h
diff --git a/sysdeps/libm-ieee754/k_standard.c b/sysdeps/libm-ieee754/k_standard.c
index 391ab057ca..6c410c4c1a 100644
--- a/sysdeps/libm-ieee754/k_standard.c
+++ b/sysdeps/libm-ieee754/k_standard.c
@@ -80,6 +80,9 @@ static double zero = 0.0;	/* used as const */
  *	40-- gamma(finite) overflow
  *	41-- gamma(-integer)
  *	42-- pow(NaN,0.0)
+ *	43-- +0**neg
+ *	44-- exp2 overflow
+ *	45-- exp2 underflow
  */
 
 
@@ -865,7 +868,38 @@ static double zero = 0.0;	/* used as const */
 		}
 		break;
 
-		/* #### Last used is 43/143/243 ### */
+	    case 44:
+	    case 144:
+	    case 244:
+		/* exp(finite) overflow */
+		exc.type = OVERFLOW;
+		exc.name = type < 100 ? "exp2" : (type < 200
+						 ? "exp2f" : "exp2l");
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = HUGE;
+		else
+		  exc.retval = HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  __set_errno (ERANGE);
+		else if (!matherr(&exc)) {
+			__set_errno (ERANGE);
+		}
+		break;
+	    case 45:
+	    case 145:
+	    case 245:
+		/* exp(finite) underflow */
+		exc.type = UNDERFLOW;
+		exc.name = type < 100 ? "exp2" : (type < 200
+						 ? "exp2f" : "exp2l");
+		exc.retval = zero;
+		if (_LIB_VERSION == _POSIX_)
+		  __set_errno (ERANGE);
+		else if (!matherr(&exc)) {
+			__set_errno (ERANGE);
+		}
+		break;
+		/* #### Last used is 44/144/244 ### */
 	}
 	return exc.retval;
 }
diff --git a/sysdeps/libm-ieee754/s_exp2.c b/sysdeps/libm-ieee754/s_exp2.c
new file mode 100644
index 0000000000..e10fae5492
--- /dev/null
+++ b/sysdeps/libm-ieee754/s_exp2.c
@@ -0,0 +1,128 @@
+/* Double-precision floating point 2^x.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Geoffrey Keating <geoffk@ozemail.com.au>
+
+   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.  */
+
+/* The basic design here is from
+   Shmuel Gal and Boris Bachelis, "An Accurate Elementary Mathematical
+   Library for the IEEE Floating Point Standard", ACM Trans. Math. Soft.,
+   17 (1), March 1991, pp. 26-45.
+   It has been slightly modified to compute 2^x instead of e^x.
+   */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <float.h>
+#include <ieee754.h>
+#include <math.h>
+#include <fenv.h>
+#include <inttypes.h>
+#include <math_private.h>
+
+#include "t_exp2.h"
+
+static const volatile double TWO1000 = 1.071508607186267320948e+301;
+static const volatile double TWOM1000 = 9.3326361850321887899e-302;
+
+double
+__ieee754_exp2 (double x)
+{
+  static const uint32_t a_inf = 0x7f800000;
+  /* Check for usual case.  */
+  if (isless (x, (double) DBL_MAX_EXP)
+      && isgreater (x, (double) (DBL_MIN_EXP - 1)))
+    {
+      static const float TWO43 = 8796093022208.0;
+      int tval;
+      double rx, x22;
+      union ieee754_double ex2_u;
+      fenv_t oldenv;
+
+      feholdexcept (&oldenv);
+      fesetround (FE_TONEAREST);
+
+      /* 1. Argument reduction.
+	 Choose integers ex, -256 <= t < 256, and some real
+	 -1/1024 <= x1 <= 1024 so that
+	 x = ex + t/512 + x1.
+
+	 First, calculate rx = ex + t/512.  */
+      if (x >= 0)
+	{
+	  rx = x + TWO43;
+	  rx -= TWO43;
+	}
+      else
+	{
+	  rx = x - TWO43;
+	  rx += TWO43;
+	}
+      x -= rx;  /* Compute x=x1. */
+      /* Compute tval = (ex*512 + t)+256.
+	 Now, t = (tval mod 512)-256 and ex=tval/512  [that's mod, NOT %; and
+	 /-round-to-nearest not the usual c integer /].  */
+      tval = (int) (rx * 512.0 + 256.0);
+
+      /* 2. Adjust for accurate table entry.
+	 Find e so that
+	 x = ex + t/512 + e + x2
+	 where -1e6 < e < 1e6, and
+	 (double)(2^(t/512+e))
+	 is accurate to one part in 2^-64.  */
+
+      /* 'tval & 511' is the same as 'tval%512' except that it's always
+	 positive.
+	 Compute x = x2.  */
+      x -= exp2_deltatable[tval & 511];
+
+      /* 3. Compute ex2 = 2^(t/512+e+ex).  */
+      ex2_u.d = exp2_accuratetable[tval & 511];
+      ex2_u.ieee.exponent += tval >> 9;
+
+      /* 4. Approximate 2^x2 - 1, using a fourth-degree polynomial,
+	 2^x2 ~= sum(k=0..4 | (x2 * ln(2))^k / k! ) +
+	 so
+	 2^x2 - 1 ~= sum(k=1..4 | (x2 * ln(2))^k / k! )
+	 with error less than 2^(1/1024) * (x2 * ln(2))^5 / 5! < 1.2e-18.  */
+
+      x22 = (((.0096181291076284772
+	       * x + .055504108664821580)
+	      * x + .240226506959100712)
+	     * x + .69314718055994531) * ex2_u.d;
+
+      /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex).  */
+      fesetenv (&oldenv);
+
+      /* Need to check: does this set FE_INEXACT correctly? */
+      return x22 * x + ex2_u.d;
+    }
+  /* 2^inf == inf, with no error.  */
+  else if (x == *(const float *) &a_inf)
+    return x;
+  /* Check for overflow.  */
+  else if (isgreaterequal (x, (double) DBL_MAX_EXP))
+    return TWO1000 * TWO1000;
+  /* And underflow (including -inf).  */
+  else if (isless (x, (double) (DBL_MIN_EXP - DBL_MANT_DIG)))
+    return TWOM1000 * TWOM1000;
+  /* Maybe the result needs to be a denormalised number...  */
+  else if (!isnan (x))
+    return __ieee754_exp2 (x + 1000.0) * TWOM1000;
+  else /* isnan(x) */
+    return x + x;
+}
diff --git a/sysdeps/libm-ieee754/s_exp2f.c b/sysdeps/libm-ieee754/s_exp2f.c
new file mode 100644
index 0000000000..e50ac77792
--- /dev/null
+++ b/sysdeps/libm-ieee754/s_exp2f.c
@@ -0,0 +1,126 @@
+/* Single-precision floating point 2^x.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Geoffrey Keating <geoffk@ozemail.com.au>
+
+   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.  */
+
+/* The basic design here is from
+   Shmuel Gal and Boris Bachelis, "An Accurate Elementary Mathematical
+   Library for the IEEE Floating Point Standard", ACM Trans. Math. Soft.,
+   17 (1), March 1991, pp. 26-45.
+   It has been slightly modified to compute 2^x instead of e^x, and for
+   single-precision.
+   */
+#define _GNU_SOURCE
+#include <float.h>
+#include <ieee754.h>
+#include <math.h>
+#include <fenv.h>
+#include <inttypes.h>
+#include <math_private.h>
+
+#include "t_exp2f.h"
+
+static const volatile float TWOM100 = 7.88860905e-31;
+static const volatile float huge = 1e+30;
+
+float
+__ieee754_exp2f (float x)
+{
+  static const uint32_t a_inf = 0x7f800000;
+  /* Check for usual case.  */
+  if (isless (x, (float) FLT_MAX_EXP)
+      && isgreater (x, (float) (FLT_MIN_EXP - 1)))
+    {
+      static const float TWO16 = 65536.0;
+      int tval;
+      float rx, x22;
+      union ieee754_float ex2_u;
+      fenv_t oldenv;
+
+      feholdexcept (&oldenv);
+      fesetround (FE_TONEAREST);
+
+      /* 1. Argument reduction.
+	 Choose integers ex, -128 <= t < 128, and some real
+	 -1/512 <= x1 <= 1/512 so that
+	 x = ex + t/512 + x1.
+
+	 First, calculate rx = ex + t/256.  */
+      if (x >= 0)
+	{
+	  rx = x + TWO16;
+	  rx -= TWO16;
+	}
+      else
+	{
+	  rx = x - TWO16;
+	  rx += TWO16;
+	}
+      x -= rx;  /* Compute x=x1. */
+      /* Compute tval = (ex*256 + t)+128.
+	 Now, t = (tval mod 256)-128 and ex=tval/256  [that's mod, NOT %; and
+	 /-round-to-nearest not the usual c integer /].  */
+      tval = (int) (rx * 256.0f + 128.0f);
+
+      /* 2. Adjust for accurate table entry.
+	 Find e so that
+	 x = ex + t/256 + e + x2
+	 where -7e-4 < e < 7e-4, and
+	 (float)(2^(t/256+e))
+	 is accurate to one part in 2^-64.  */
+
+      /* 'tval & 255' is the same as 'tval%256' except that it's always
+	 positive.
+	 Compute x = x2.  */
+      x -= exp2_deltatable[tval & 255];
+
+      /* 3. Compute ex2 = 2^(t/255+e+ex).  */
+      ex2_u.f = exp2_accuratetable[tval & 255];
+      ex2_u.ieee.exponent += tval >> 8;
+
+      /* 4. Approximate 2^x2 - 1, using a second-degree polynomial,
+	 2^x2 ~= sum(k=0..2 | (x2 * ln(2))^k / k! ) +
+	 so
+	 2^x2 - 1 ~= sum(k=1..4 | (x2 * ln(2))^k / k! )
+	 with error less than 2^(1/512+7e-4) * (x2 * ln(2))^3 / 3! < 1.2e-18.  */
+
+      x22 = (.240226507f * x + .6931471806f) * ex2_u.f;
+
+      /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex).  */
+      fesetenv (&oldenv);
+
+      /* Need to check: does this set FE_INEXACT correctly? */
+      return x22 * x + ex2_u.f;
+    }
+  /* 2^inf == inf, with no error.  */
+  else if (x == *(const float *)&a_inf)
+    {
+      return x;
+    }
+  /* Check for overflow.  */
+  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)))
+    return TWOM100 * TWOM100;
+  /* Maybe the result needs to be a denormalised number...  */
+  else if (!isnan (x))
+    return __ieee754_exp2f (x + 100.0) * TWOM100;
+  else /* isnan(x) */
+    return x + x;
+}
diff --git a/sysdeps/libm-ieee754/t_exp2.h b/sysdeps/libm-ieee754/t_exp2.h
new file mode 100644
index 0000000000..1fd73338cf
--- /dev/null
+++ b/sysdeps/libm-ieee754/t_exp2.h
@@ -0,0 +1,585 @@
+/* These values are accurate to 52+12 bits when represented as
+   a double.  */
+static const double exp2_accuratetable[512] = {
+0.707106781187802013759 /* 0x0.b504f333fb3f80007 */,
+0.708064712808760599040 /* 0x0.b543baa0f71b38000 */,
+0.709023942160304065938 /* 0x0.b58297d3a8d518002 */,
+0.709984470998547667624 /* 0x0.b5c18ad39b4ba0001 */,
+0.710946301084324217006 /* 0x0.b60093a85e8d30001 */,
+0.711909434180505784637 /* 0x0.b63fb25984e628005 */,
+0.712873872052760648733 /* 0x0.b67ee6eea3b5f8003 */,
+0.713839616467838999908 /* 0x0.b6be316f518c98001 */,
+0.714806669195984345523 /* 0x0.b6fd91e328d148007 */,
+0.715775032009894562898 /* 0x0.b73d0851c69e20002 */,
+0.716744706683768884058 /* 0x0.b77c94c2c9b3d0003 */,
+0.717715694995770148178 /* 0x0.b7bc373dd52eb0003 */,
+0.718687998724665488852 /* 0x0.b7fbefca8cd530004 */,
+0.719661619652575468291 /* 0x0.b83bbe70981da8001 */,
+0.720636559564428180758 /* 0x0.b87ba337a194b0006 */,
+0.721612820246623098989 /* 0x0.b8bb9e27556508004 */,
+0.722590403488338473025 /* 0x0.b8fbaf4762c798006 */,
+0.723569311081411870036 /* 0x0.b93bd69f7be1d0000 */,
+0.724549544820974333906 /* 0x0.b97c1437567828007 */,
+0.725531106502312561633 /* 0x0.b9bc6816a87ae8002 */,
+0.726513997924421062181 /* 0x0.b9fcd2452bee00000 */,
+0.727498220889519875430 /* 0x0.ba3d52ca9e6148002 */,
+0.728483777200401694265 /* 0x0.ba7de9aebe05c8003 */,
+0.729470668664712662563 /* 0x0.babe96f94e62a8002 */,
+0.730458897090379144517 /* 0x0.baff5ab2134df0004 */,
+0.731448464287988597833 /* 0x0.bb4034e0d38ab0000 */,
+0.732439372072965166897 /* 0x0.bb81258d5b2d60001 */,
+0.733431622260458326859 /* 0x0.bbc22cbf75fd28001 */,
+0.734425216668725511232 /* 0x0.bc034a7ef32c00001 */,
+0.735420157118880535324 /* 0x0.bc447ed3a50fe0005 */,
+0.736416445434497690674 /* 0x0.bc85c9c560b350001 */,
+0.737414083433310718618 /* 0x0.bcc72b5bf4b4e0000 */,
+0.738413072966152328496 /* 0x0.bd08a39f5417a8007 */,
+0.739413415848264365956 /* 0x0.bd4a32974abcd0002 */,
+0.740415113911250699637 /* 0x0.bd8bd84bb68300002 */,
+0.741418168994518067562 /* 0x0.bdcd94c47ddd30003 */,
+0.742422582936659858376 /* 0x0.be0f6809865968006 */,
+0.743428357577745613238 /* 0x0.be515222b72530003 */,
+0.744435494762383687126 /* 0x0.be935317fc6ba0002 */,
+0.745443996335090397492 /* 0x0.bed56af1423de8001 */,
+0.746453864145572798553 /* 0x0.bf1799b67a6248007 */,
+0.747465100043933849969 /* 0x0.bf59df6f970e70002 */,
+0.748477705883256683178 /* 0x0.bf9c3c248dbee8001 */,
+0.749491683518965001732 /* 0x0.bfdeafdd568308000 */,
+0.750507034813367890373 /* 0x0.c0213aa1f0fc38004 */,
+0.751523761622240105153 /* 0x0.c063dc7a559ca0003 */,
+0.752541865811731880422 /* 0x0.c0a6956e883ed8000 */,
+0.753561349247157341600 /* 0x0.c0e965868bd220006 */,
+0.754582213796583967110 /* 0x0.c12c4cca664cb8002 */,
+0.755604461332336940791 /* 0x0.c16f4b42225350006 */,
+0.756628093726406381068 /* 0x0.c1b260f5ca2c48002 */,
+0.757653112855631305506 /* 0x0.c1f58ded6d72d8001 */,
+0.758679520599333412360 /* 0x0.c238d2311e7d08001 */,
+0.759707318837184453227 /* 0x0.c27c2dc8f00368005 */,
+0.760736509456435783249 /* 0x0.c2bfa0bcfd1400000 */,
+0.761767094336480043995 /* 0x0.c3032b155818d0000 */,
+0.762799075372231349951 /* 0x0.c346ccda248cc0001 */,
+0.763832454453522768941 /* 0x0.c38a8613805488005 */,
+0.764867233473625618441 /* 0x0.c3ce56c98d1ca8005 */,
+0.765903414329434539816 /* 0x0.c4123f04708d80002 */,
+0.766940998920452976510 /* 0x0.c4563ecc532dc0001 */,
+0.767979989148100838946 /* 0x0.c49a56295f9f88006 */,
+0.769020386915772125040 /* 0x0.c4de8523c2b0a0001 */,
+0.770062194131770905170 /* 0x0.c522cbc3ae94e0003 */,
+0.771105412703856241146 /* 0x0.c5672a1154e6b8004 */,
+0.772150044545352520777 /* 0x0.c5aba014ed5f18003 */,
+0.773196091570364285606 /* 0x0.c5f02dd6b09288003 */,
+0.774243555696622731700 /* 0x0.c634d35edb1260003 */,
+0.775292438842697939641 /* 0x0.c67990b5aa5c18004 */,
+0.776342742931542928455 /* 0x0.c6be65e360bed8000 */,
+0.777394469888802008854 /* 0x0.c70352f0437f50004 */,
+0.778447621641124243320 /* 0x0.c74857e498fd00006 */,
+0.779502200118583399303 /* 0x0.c78d74c8ab5b60000 */,
+0.780558207255445668515 /* 0x0.c7d2a9a4c959f8000 */,
+0.781615644985491186966 /* 0x0.c817f681412f80002 */,
+0.782674515247667956808 /* 0x0.c85d5b6666c150006 */,
+0.783734819983036512536 /* 0x0.c8a2d85c904760003 */,
+0.784796561133562109454 /* 0x0.c8e86d6c14f850002 */,
+0.785859740645942328471 /* 0x0.c92e1a9d513ec8002 */,
+0.786924360469767103536 /* 0x0.c973dff8a4b390007 */,
+0.787990422552312885808 /* 0x0.c9b9bd866c6440007 */,
+0.789057928854407064640 /* 0x0.c9ffb34f1444b0001 */,
+0.790126881326406182996 /* 0x0.ca45c15afcc570001 */,
+0.791197281930050233534 /* 0x0.ca8be7b292db38000 */,
+0.792269132620954885659 /* 0x0.cad2265e3cbee8000 */,
+0.793342435380726906957 /* 0x0.cb187d667d3d38006 */,
+0.794417192158282659010 /* 0x0.cb5eecd3b33158006 */,
+0.795493404931386649540 /* 0x0.cba574ae5d2e80001 */,
+0.796571075671306805268 /* 0x0.cbec14fef2a348004 */,
+0.797650206352955137846 /* 0x0.cc32cdcdef0000000 */,
+0.798730798954342069432 /* 0x0.cc799f23d11d18000 */,
+0.799812855456121796232 /* 0x0.ccc089091abb28004 */,
+0.800896377841454287795 /* 0x0.cd078b86505c18003 */,
+0.801981368096190028208 /* 0x0.cd4ea6a3f97720007 */,
+0.803067828208752554378 /* 0x0.cd95da6aa057b8007 */,
+0.804155760170129796375 /* 0x0.cddd26e2d21b28001 */,
+0.805245165974338261710 /* 0x0.ce248c151f3330001 */,
+0.806336047619038653883 /* 0x0.ce6c0a0a1c1350001 */,
+0.807428407102107836855 /* 0x0.ceb3a0ca5d6be0006 */,
+0.808522246427078927792 /* 0x0.cefb505e7e2550007 */,
+0.809617567597010201484 /* 0x0.cf4318cf18a268002 */,
+0.810714372621179513182 /* 0x0.cf8afa24ce1c98004 */,
+0.811812663508675536069 /* 0x0.cfd2f4683f9810005 */,
+0.812912442272482604912 /* 0x0.d01b07a2126188003 */,
+0.814013710929394895825 /* 0x0.d06333daeff618001 */,
+0.815116471495287542325 /* 0x0.d0ab791b80d028006 */,
+0.816220725993571205593 /* 0x0.d0f3d76c75b330000 */,
+0.817326476447408967199 /* 0x0.d13c4ed67f1cf8000 */,
+0.818433724883006474832 /* 0x0.d184df6250e3b0001 */,
+0.819542473330909460055 /* 0x0.d1cd8918a3a328004 */,
+0.820652723822034690935 /* 0x0.d2164c02305fa0002 */,
+0.821764478391968422618 /* 0x0.d25f2827b53fb0005 */,
+0.822877739077315761840 /* 0x0.d2a81d91f188b8000 */,
+0.823992507918612782109 /* 0x0.d2f12c49a8d290005 */,
+0.825108786960634610365 /* 0x0.d33a5457a35e40003 */,
+0.826226578247117093869 /* 0x0.d38395c4a84848007 */,
+0.827345883828319528258 /* 0x0.d3ccf09985d958004 */,
+0.828466705754248966560 /* 0x0.d41664df0a1320005 */,
+0.829589046080638992111 /* 0x0.d45ff29e094330000 */,
+0.830712906863802391671 /* 0x0.d4a999df585a20005 */,
+0.831838290163696481037 /* 0x0.d4f35aabd04a60006 */,
+0.832965198041969556729 /* 0x0.d53d350c4be258002 */,
+0.834093632565442222342 /* 0x0.d5872909aba050007 */,
+0.835223595802037643865 /* 0x0.d5d136acd138e8006 */,
+0.836355089820669306292 /* 0x0.d61b5dfe9f7780004 */,
+0.837488116698010487424 /* 0x0.d6659f0801afa8005 */,
+0.838622678508982644113 /* 0x0.d6aff9d1e147d8004 */,
+0.839758777333464490056 /* 0x0.d6fa6e652d19e0000 */,
+0.840896415254110962690 /* 0x0.d744fccad70d00003 */,
+0.842035594355151628676 /* 0x0.d78fa50bd2c3b0000 */,
+0.843176316724478125433 /* 0x0.d7da673117e730007 */,
+0.844318584453106590905 /* 0x0.d8254343a19038003 */,
+0.845462399634695271912 /* 0x0.d870394c6dbf30003 */,
+0.846607764365415071965 /* 0x0.d8bb49547d37c0004 */,
+0.847754680744707056494 /* 0x0.d9067364d45608003 */,
+0.848903150873708822763 /* 0x0.d951b7867953b0006 */,
+0.850053176859071113491 /* 0x0.d99d15c2787a30006 */,
+0.851204760807439786431 /* 0x0.d9e88e21de11a0003 */,
+0.852357904828824897169 /* 0x0.da3420adba1508003 */,
+0.853512611037803181642 /* 0x0.da7fcd6f2184d8005 */,
+0.854668881550406100980 /* 0x0.dacb946f2afaf8000 */,
+0.855826718478671755185 /* 0x0.db1775b6e8ad48000 */,
+0.856986123964844970247 /* 0x0.db63714f8e0818006 */,
+0.858147100114499461478 /* 0x0.dbaf87422625b8000 */,
+0.859309649060962410524 /* 0x0.dbfbb797daa460002 */,
+0.860473772936213743282 /* 0x0.dc480259d3a710001 */,
+0.861639473872910177676 /* 0x0.dc9467913a0f48006 */,
+0.862806754008130227807 /* 0x0.dce0e7473b9b28003 */,
+0.863975615481124226159 /* 0x0.dd2d8185086c20006 */,
+0.865146060433749419813 /* 0x0.dd7a3653d38168005 */,
+0.866318091005120138881 /* 0x0.ddc705bcccd628000 */,
+0.867491709362415264210 /* 0x0.de13efc9434100004 */,
+0.868666917636779056818 /* 0x0.de60f4825df9b8005 */,
+0.869843717989716047624 /* 0x0.deae13f16599c0003 */,
+0.871022112578215268471 /* 0x0.defb4e1f9dc388002 */,
+0.872202103559697183859 /* 0x0.df48a3164a92f0001 */,
+0.873383693097737778847 /* 0x0.df9612deb6e878007 */,
+0.874566883362160263365 /* 0x0.dfe39d82348310001 */,
+0.875751676517234511901 /* 0x0.e031430a0f0688000 */,
+0.876938074732511840819 /* 0x0.e07f037f97e548001 */,
+0.878126080186539592654 /* 0x0.e0ccdeec2a75e0006 */,
+0.879315695055312818168 /* 0x0.e11ad5591f4078001 */,
+0.880506921518618312932 /* 0x0.e168e6cfd2f880004 */,
+0.881699761760385225541 /* 0x0.e1b71359a6df60003 */,
+0.882894217964411143207 /* 0x0.e2055afffc1178000 */,
+0.884090292325693805080 /* 0x0.e253bdcc3ffbb8001 */,
+0.885287987031581180559 /* 0x0.e2a23bc7d7a1d8002 */,
+0.886487304278189114386 /* 0x0.e2f0d4fc31ab80004 */,
+0.887688246263368285778 /* 0x0.e33f8972bea8a8005 */,
+0.888890815189881999840 /* 0x0.e38e5934f49010007 */,
+0.890095013257492739835 /* 0x0.e3dd444c460bd0007 */,
+0.891300842677948068626 /* 0x0.e42c4ac232f380000 */,
+0.892508305659222567226 /* 0x0.e47b6ca036f8b8005 */,
+0.893717404414979710310 /* 0x0.e4caa9efd40e58002 */,
+0.894928141160697743242 /* 0x0.e51a02ba8e2610007 */,
+0.896140518115016826430 /* 0x0.e5697709ecab90000 */,
+0.897354537501434679237 /* 0x0.e5b906e77c61d0006 */,
+0.898570201543732793877 /* 0x0.e608b25cca5ba8005 */,
+0.899787512470129891014 /* 0x0.e6587973688ce8002 */,
+0.901006472512270728537 /* 0x0.e6a85c34ecadb8000 */,
+0.902227083902570559127 /* 0x0.e6f85aaaed4f20006 */,
+0.903449348881299796343 /* 0x0.e74874df09a530003 */,
+0.904673269686823378091 /* 0x0.e798aadadecba0007 */,
+0.905898848559668845585 /* 0x0.e7e8fca80c3ee0001 */,
+0.907126087750156795426 /* 0x0.e8396a503c3fe0005 */,
+0.908354989505901100354 /* 0x0.e889f3dd1615b0002 */,
+0.909585556079328783087 /* 0x0.e8da9958465228007 */,
+0.910817789726044213523 /* 0x0.e92b5acb7d0578001 */,
+0.912051692703457872481 /* 0x0.e97c38406c3c30003 */,
+0.913287267274154990210 /* 0x0.e9cd31c0cbb370001 */,
+0.914524515702244578108 /* 0x0.ea1e475654d540000 */,
+0.915763440256158633982 /* 0x0.ea6f790ac5cc78001 */,
+0.917004043205012497909 /* 0x0.eac0c6e7dd8448007 */,
+0.918246326823137892807 /* 0x0.eb1230f760a428007 */,
+0.919490293387826285200 /* 0x0.eb63b7431714a8007 */,
+0.920735945178816406225 /* 0x0.ebb559d4cb6f30007 */,
+0.921983284479243714322 /* 0x0.ec0718b64c0940002 */,
+0.923232313574974705626 /* 0x0.ec58f3f16a3910002 */,
+0.924483034755387955725 /* 0x0.ecaaeb8ffb3168005 */,
+0.925735450311948926408 /* 0x0.ecfcff9bd67078000 */,
+0.926989562542820610982 /* 0x0.ed4f301edad1a0007 */,
+0.928245373740515189457 /* 0x0.eda17d22e0f9b0001 */,
+0.929502886213858126045 /* 0x0.edf3e6b1d37d40001 */,
+0.930762102264245716494 /* 0x0.ee466cd594c5c8005 */,
+0.932023024199046146183 /* 0x0.ee990f980dcdb0005 */,
+0.933285654329454095216 /* 0x0.eeebcf032bc470007 */,
+0.934549994971191289044 /* 0x0.ef3eab20e0d3c0001 */,
+0.935816048439005676599 /* 0x0.ef91a3fb1e1340004 */,
+0.937083817055075818404 /* 0x0.efe4b99bdcc618006 */,
+0.938353303143720007819 /* 0x0.f037ec0d1889b8000 */,
+0.939624509028518128972 /* 0x0.f08b3b58cc2bb8006 */,
+0.940897437041863904384 /* 0x0.f0dea788fc2a90000 */,
+0.942172089516254085427 /* 0x0.f13230a7ad21b8003 */,
+0.943448468787511540534 /* 0x0.f185d6bee754e0006 */,
+0.944726577195256100890 /* 0x0.f1d999d8b73478005 */,
+0.946006417082291717338 /* 0x0.f22d79ff2cb130000 */,
+0.947287990793413858827 /* 0x0.f281773c59ec48007 */,
+0.948571300678290207925 /* 0x0.f2d5919a566268001 */,
+0.949856349088629370320 /* 0x0.f329c9233bceb0001 */,
+0.951143138379053731954 /* 0x0.f37e1de1272068002 */,
+0.952431670908847949364 /* 0x0.f3d28fde3a6728006 */,
+0.953721949039916472305 /* 0x0.f4271f249a93f0001 */,
+0.955013975135367898520 /* 0x0.f47bcbbe6deab0001 */,
+0.956307751564417496418 /* 0x0.f4d095b5e16638004 */,
+0.957603280698967163097 /* 0x0.f5257d1524f590006 */,
+0.958900564911197350604 /* 0x0.f57a81e668d628000 */,
+0.960199606581278120057 /* 0x0.f5cfa433e60e50007 */,
+0.961500408088936442422 /* 0x0.f624e407d527a0007 */,
+0.962802971817578789903 /* 0x0.f67a416c72b760006 */,
+0.964107300155846558292 /* 0x0.f6cfbc6c011458004 */,
+0.965413395493874504368 /* 0x0.f7255510c439a8002 */,
+0.966721260225105960572 /* 0x0.f77b0b6503c5b8006 */,
+0.968030896745834645873 /* 0x0.f7d0df730a7940005 */,
+0.969342307458006424716 /* 0x0.f826d145294be8003 */,
+0.970655494764855020231 /* 0x0.f87ce0e5b29fd8000 */,
+0.971970461071268720958 /* 0x0.f8d30e5efaa8f0004 */,
+0.973287208789983648852 /* 0x0.f92959bb5e3c08001 */,
+0.974605740331924708124 /* 0x0.f97fc305383028004 */,
+0.975926058115625383329 /* 0x0.f9d64a46ebb9f8004 */,
+0.977248164559556209435 /* 0x0.fa2cef8adbfc68004 */,
+0.978572062087848637573 /* 0x0.fa83b2db7253d0007 */,
+0.979897753126343307191 /* 0x0.fada944319fda0005 */,
+0.981225240104636631254 /* 0x0.fb3193cc425870002 */,
+0.982554525455618277276 /* 0x0.fb88b1815e61d0003 */,
+0.983885611617111077747 /* 0x0.fbdfed6ce683e0007 */,
+0.985218501026348891812 /* 0x0.fc3747995282f8006 */,
+0.986553196127724962867 /* 0x0.fc8ec0112202a0005 */,
+0.987889699367056062238 /* 0x0.fce656ded63710002 */,
+0.989228013193998778636 /* 0x0.fd3e0c0cf48d50005 */,
+0.990568140061241164686 /* 0x0.fd95dfa605c7b0003 */,
+0.991910082424819927754 /* 0x0.fdedd1b4965710004 */,
+0.993253842749249660216 /* 0x0.fe45e2433bfea0000 */,
+0.994599423484053835071 /* 0x0.fe9e115c7c05f0005 */,
+0.995946827107488830167 /* 0x0.fef65f0afb4c28006 */,
+0.997296056085008264529 /* 0x0.ff4ecb59509cc8001 */,
+0.998647112892057764479 /* 0x0.ffa756521dbfd0007 */,
+1.000000000000000000000 /* 0x1.00000000000000000 */,
+1.001354719891689004659 /* 0x1.0058c86da14aa0005 */,
+1.002711275050312211844 /* 0x1.00b1afa5abead0003 */,
+1.004069667960743483835 /* 0x1.010ab5b2cc0660009 */,
+1.005429901112333324093 /* 0x1.0163da9fb2af30008 */,
+1.006791976999887428009 /* 0x1.01bd1e7716f6a0008 */,
+1.008155898118476168101 /* 0x1.02168143b03890006 */,
+1.009521666967782227439 /* 0x1.027003103ae320002 */,
+1.010889286051850133326 /* 0x1.02c9a3e7783030002 */,
+1.012258757875921233497 /* 0x1.032363d42aaa8000e */,
+1.013630084952214405194 /* 0x1.037d42e11c88d0000 */,
+1.015003269791313389451 /* 0x1.03d741191635a0001 */,
+1.016378314911229763267 /* 0x1.04315e86e84630008 */,
+1.017755222831652872635 /* 0x1.048b9b35652800002 */,
+1.019133996077934645224 /* 0x1.04e5f72f65827000b */,
+1.020514637175266248212 /* 0x1.0540727fc1cfa0006 */,
+1.021897148653734488385 /* 0x1.059b0d3157ebb0002 */,
+1.023281533050062419584 /* 0x1.05f5c74f0cfeb0002 */,
+1.024667792897328677539 /* 0x1.0650a0e3c22ee0003 */,
+1.026055930738840826806 /* 0x1.06ab99fa63e1b0008 */,
+1.027445949118511947550 /* 0x1.0706b29ddf2700009 */,
+1.028837850584049418178 /* 0x1.0761ead9253ab0009 */,
+1.030231637685799839262 /* 0x1.07bd42b72a3f80008 */,
+1.031627312979383592802 /* 0x1.0818ba42e824a000c */,
+1.033024879021186448496 /* 0x1.0874518759b0b0008 */,
+1.034424338374263729911 /* 0x1.08d0088f80ffa0006 */,
+1.035825693601787333992 /* 0x1.092bdf66604e30005 */,
+1.037228947273990842283 /* 0x1.0987d617019cd000a */,
+1.038634101961269928846 /* 0x1.09e3ecac6f199000f */,
+1.040041160239590700707 /* 0x1.0a402331b91270002 */,
+1.041450124688240164200 /* 0x1.0a9c79b1f37c3000b */,
+1.042860997889083929381 /* 0x1.0af8f038352160000 */,
+1.044273782427270314011 /* 0x1.0b5586cf986890006 */,
+1.045688480893644856116 /* 0x1.0bb23d833dfbf0006 */,
+1.047105095879385272564 /* 0x1.0c0f145e46e330007 */,
+1.048523629981608529302 /* 0x1.0c6c0b6bdaadc000f */,
+1.049944085800634585634 /* 0x1.0cc922b72470a000f */,
+1.051366465939483019223 /* 0x1.0d265a4b5238b0007 */,
+1.052790773004648849929 /* 0x1.0d83b23395e510002 */,
+1.054217009607077093512 /* 0x1.0de12a7b263970006 */,
+1.055645178360430591625 /* 0x1.0e3ec32d3cf680000 */,
+1.057075281882416506511 /* 0x1.0e9c7c55184f5000e */,
+1.058507322794714378170 /* 0x1.0efa55fdfad51000a */,
+1.059941303721639416236 /* 0x1.0f58503329fed0003 */,
+1.061377227289284297385 /* 0x1.0fb66affed37f0000 */,
+1.062815096132297298980 /* 0x1.1014a66f95540000c */,
+1.064254912884593951029 /* 0x1.1073028d725850007 */,
+1.065696680185205469411 /* 0x1.10d17f64d9ea2000b */,
+1.067140400676658718053 /* 0x1.11301d012586a0007 */,
+1.068586077004890055886 /* 0x1.118edb6db26ab0003 */,
+1.070033711820396415998 /* 0x1.11edbab5e2d6e000b */,
+1.071483307775789262099 /* 0x1.124cbae51b5ef0001 */,
+1.072934867526001312439 /* 0x1.12abdc06c3240000c */,
+1.074388393734249103080 /* 0x1.130b1e264a62e0005 */,
+1.075843889063253344684 /* 0x1.136a814f20ccd0003 */,
+1.077301356179926061823 /* 0x1.13ca058cbaaed000b */,
+1.078760797756675327056 /* 0x1.1429aaea9260e000e */,
+1.080222216468626150775 /* 0x1.148971742537c0009 */,
+1.081685614993597610617 /* 0x1.14e95934f37e8000b */,
+1.083150996013011013776 /* 0x1.1549623881762000d */,
+1.084618362213087383633 /* 0x1.15a98c8a58a6a000b */,
+1.086087716284427351384 /* 0x1.1609d8360768c0008 */,
+1.087559060917626885283 /* 0x1.166a45471c13f0008 */,
+1.089032398810997337465 /* 0x1.16cad3c92d7b50009 */,
+1.090507732647478578212 /* 0x1.172b83c7c18b5000f */,
+1.091985065182095926460 /* 0x1.178c554ead72a000c */,
+1.093464399073070136880 /* 0x1.17ed48695befe000c */,
+1.094945737045367906172 /* 0x1.184e5d23812500007 */,
+1.096429081816546080591 /* 0x1.18af9388c90e40005 */,
+1.097914436104650892651 /* 0x1.1910eba4e031a0001 */,
+1.099401802629782043408 /* 0x1.19726583755720003 */,
+1.100891184121537858001 /* 0x1.19d4013041b860007 */,
+1.102382583308144647940 /* 0x1.1a35beb6fd0cd0007 */,
+1.103876002922312915544 /* 0x1.1a979e2363fa10000 */,
+1.105371445702084232160 /* 0x1.1af99f8139025000e */,
+1.106868914387219016199 /* 0x1.1b5bc2dc408b9000e */,
+1.108368411723785085252 /* 0x1.1bbe084045eb30002 */,
+1.109869940458469095340 /* 0x1.1c206fb91524c000e */,
+1.111373503344554869449 /* 0x1.1c82f952817cc0001 */,
+1.112879103137133007859 /* 0x1.1ce5a51860344000f */,
+1.114386742595953938610 /* 0x1.1d4873168babf000e */,
+1.115896424484008608911 /* 0x1.1dab6358e1d4a000f */,
+1.117408151567338414664 /* 0x1.1e0e75eb43f9c000c */,
+1.118921926613465345265 /* 0x1.1e71aad995078000f */,
+1.120437752409564780022 /* 0x1.1ed5022fcd8600003 */,
+1.121955631720569668277 /* 0x1.1f387bf9cd88b0000 */,
+1.123475567332998359439 /* 0x1.1f9c18438cdec000a */,
+1.124997562033035469759 /* 0x1.1fffd71902f970002 */,
+1.126521618608448571713 /* 0x1.2063b88629079000e */,
+1.128047739853580200284 /* 0x1.20c7bc96ff72a0002 */,
+1.129575928566289189112 /* 0x1.212be3578a81e0006 */,
+1.131106187546149888259 /* 0x1.21902cd3d05f70007 */,
+1.132638519598779369743 /* 0x1.21f49917ddda5000c */,
+1.134172927531616359481 /* 0x1.2259282fc1c24000e */,
+1.135709414157753949251 /* 0x1.22bdda27911e90007 */,
+1.137247982292643566662 /* 0x1.2322af0b638e60007 */,
+1.138788634756517259562 /* 0x1.2387a6e755f270000 */,
+1.140331374372893558110 /* 0x1.23ecc1c788c890006 */,
+1.141876203969685699176 /* 0x1.2451ffb821639000c */,
+1.143423126377846266197 /* 0x1.24b760c5486dc0009 */,
+1.144972144431494420774 /* 0x1.251ce4fb2a0cc0005 */,
+1.146523260971646252006 /* 0x1.25828c65f9fb8000d */,
+1.148076478839068270690 /* 0x1.25e85711ebaeb0000 */,
+1.149631800883562204903 /* 0x1.264e450b3c8a30008 */,
+1.151189229953253789786 /* 0x1.26b4565e281a20003 */,
+1.152748768902654319399 /* 0x1.271a8b16f0f000002 */,
+1.154310420590433317050 /* 0x1.2780e341de2fc0001 */,
+1.155874187878668246681 /* 0x1.27e75eeb3abc90007 */,
+1.157440073633736243899 /* 0x1.284dfe1f5633e000a */,
+1.159008080725518974322 /* 0x1.28b4c0ea840d90001 */,
+1.160578212048386514965 /* 0x1.291ba75932ae60000 */,
+1.162150470417516290340 /* 0x1.2982b177796850008 */,
+1.163724858777502646494 /* 0x1.29e9df51fdd900001 */,
+1.165301379991388053320 /* 0x1.2a5130f50bf34000e */,
+1.166880036952526289469 /* 0x1.2ab8a66d10fdc0008 */,
+1.168460832550151540268 /* 0x1.2b203fc675b7a000a */,
+1.170043769683112966389 /* 0x1.2b87fd0dad7260008 */,
+1.171628851252754177681 /* 0x1.2befde4f2e3da000d */,
+1.173216080163546060084 /* 0x1.2c57e397719940002 */,
+1.174805459325657830448 /* 0x1.2cc00cf2f7491000c */,
+1.176396991650083379037 /* 0x1.2d285a6e3ff90000b */,
+1.177990680055698513602 /* 0x1.2d90cc15d4ff90005 */,
+1.179586527463262646306 /* 0x1.2df961f641c57000c */,
+1.181184536796979545103 /* 0x1.2e621c1c157cd000d */,
+1.182784710984701836994 /* 0x1.2ecafa93e35af0004 */,
+1.184387052960675701386 /* 0x1.2f33fd6a459cb0000 */,
+1.185991565661414393112 /* 0x1.2f9d24abd8fd1000e */,
+1.187598252026902612178 /* 0x1.300670653e083000a */,
+1.189207115003001469262 /* 0x1.306fe0a31bc040008 */,
+1.190818157535919796833 /* 0x1.30d9757219895000e */,
+1.192431382587621380206 /* 0x1.31432edef01a1000f */,
+1.194046793097208292195 /* 0x1.31ad0cf63f0630008 */,
+1.195664392040319823392 /* 0x1.32170fc4ce0db000c */,
+1.197284182375793593084 /* 0x1.32813757527750005 */,
+1.198906167074650808198 /* 0x1.32eb83ba8eef3000f */,
+1.200530349107333139048 /* 0x1.3355f4fb457e5000d */,
+1.202156731453099647353 /* 0x1.33c08b2641df9000c */,
+1.203785317090505513368 /* 0x1.342b46484f07b0005 */,
+1.205416109005122526928 /* 0x1.3496266e3fa270005 */,
+1.207049110184904572310 /* 0x1.35012ba4e8fa10000 */,
+1.208684323627194912036 /* 0x1.356c55f92aabb0004 */,
+1.210321752322854882437 /* 0x1.35d7a577dd33f0004 */,
+1.211961399276747286580 /* 0x1.36431a2de8748000d */,
+1.213603267492579629347 /* 0x1.36aeb4283309e000c */,
+1.215247359985374142610 /* 0x1.371a7373b00160000 */,
+1.216893679753690671322 /* 0x1.3786581d404e90000 */,
+1.218542229828181611183 /* 0x1.37f26231e82e4000c */,
+1.220193013225231215567 /* 0x1.385e91be9c2d20002 */,
+1.221846032973555429280 /* 0x1.38cae6d05e66f0000 */,
+1.223501292099485437962 /* 0x1.393761742e5830001 */,
+1.225158793636904830441 /* 0x1.39a401b713cb3000e */,
+1.226818540625497444577 /* 0x1.3a10c7a61ceae0007 */,
+1.228480536107136034131 /* 0x1.3a7db34e5a4a50003 */,
+1.230144783126481566885 /* 0x1.3aeac4bcdf8d60001 */,
+1.231811284734168454619 /* 0x1.3b57fbfec6e950008 */,
+1.233480043984379381835 /* 0x1.3bc559212e7a2000f */,
+1.235151063936380300149 /* 0x1.3c32dc3139f2a0004 */,
+1.236824347652524913647 /* 0x1.3ca0853c106ac000e */,
+1.238499898199571624970 /* 0x1.3d0e544eddd240003 */,
+1.240177718649636107175 /* 0x1.3d7c4976d3fcd0000 */,
+1.241857812073360767273 /* 0x1.3dea64c1231f70004 */,
+1.243540181554270152039 /* 0x1.3e58a63b099920005 */,
+1.245224830175077013244 /* 0x1.3ec70df1c4e46000e */,
+1.246911761022835740725 /* 0x1.3f359bf29741c000e */,
+1.248600977188942806639 /* 0x1.3fa4504ac7b800009 */,
+1.250292481770148400634 /* 0x1.40132b07a330d000a */,
+1.251986277866492969263 /* 0x1.40822c367a340000b */,
+1.253682368581898742876 /* 0x1.40f153e4a18e0000d */,
+1.255380757024939564249 /* 0x1.4160a21f73289000d */,
+1.257081446308726757662 /* 0x1.41d016f44deaa000c */,
+1.258784439550028944083 /* 0x1.423fb27094c090008 */,
+1.260489739869405489991 /* 0x1.42af74a1aec1c0006 */,
+1.262197350394008266193 /* 0x1.431f5d950a453000c */,
+1.263907274252603851764 /* 0x1.438f6d58176860004 */,
+1.265619514578811388761 /* 0x1.43ffa3f84b9eb000d */,
+1.267334074511444086425 /* 0x1.44700183221180008 */,
+1.269050957191869555296 /* 0x1.44e0860618b930006 */,
+1.270770165768063009230 /* 0x1.4551318eb4d20000e */,
+1.272491703389059036805 /* 0x1.45c2042a7cc26000b */,
+1.274215573211836316547 /* 0x1.4632fde6ffacd000d */,
+1.275941778396075143580 /* 0x1.46a41ed1cfac40001 */,
+1.277670322103555911043 /* 0x1.471566f8812ac0000 */,
+1.279401207505722393185 /* 0x1.4786d668b33260005 */,
+1.281134437771823675369 /* 0x1.47f86d3002637000a */,
+1.282870016078732078362 /* 0x1.486a2b5c13c00000e */,
+1.284607945607987078432 /* 0x1.48dc10fa916bd0004 */,
+1.286348229545787758022 /* 0x1.494e1e192aaa30007 */,
+1.288090871080605159846 /* 0x1.49c052c5913df000c */,
+1.289835873406902644341 /* 0x1.4a32af0d7d8090002 */,
+1.291583239722392528754 /* 0x1.4aa532feab5e10002 */,
+1.293332973229098792374 /* 0x1.4b17dea6db8010008 */,
+1.295085077135345708087 /* 0x1.4b8ab213d57d9000d */,
+1.296839554650994097442 /* 0x1.4bfdad53629e10003 */,
+1.298596408992440220988 /* 0x1.4c70d0735358a000d */,
+1.300355643380135983739 /* 0x1.4ce41b817c99e0001 */,
+1.302117261036232376282 /* 0x1.4d578e8bb52cb0003 */,
+1.303881265192249561154 /* 0x1.4dcb299fde2920008 */,
+1.305647659079073541490 /* 0x1.4e3eeccbd7f4c0003 */,
+1.307416445934474813521 /* 0x1.4eb2d81d8a86f000b */,
+1.309187629001237640529 /* 0x1.4f26eba2e35a5000e */,
+1.310961211525240921493 /* 0x1.4f9b2769d35090009 */,
+1.312737196755087820678 /* 0x1.500f8b804e4a30000 */,
+1.314515587949291131086 /* 0x1.508417f4530d00009 */,
+1.316296388365203462468 /* 0x1.50f8ccd3df1840003 */,
+1.318079601265708777911 /* 0x1.516daa2cf60020002 */,
+1.319865229921343141607 /* 0x1.51e2b00da3c2b0007 */,
+1.321653277603506371251 /* 0x1.5257de83f5512000d */,
+1.323443747588034513690 /* 0x1.52cd359dfc7d5000e */,
+1.325236643161341820781 /* 0x1.5342b569d6baa000f */,
+1.327031967602244177939 /* 0x1.53b85df59921b0000 */,
+1.328829724206201046165 /* 0x1.542e2f4f6b17e0006 */,
+1.330629916266568235675 /* 0x1.54a4298571b27000e */,
+1.332432547083447937938 /* 0x1.551a4ca5d97190009 */,
+1.334237619959296017340 /* 0x1.559098bed16bf0008 */,
+1.336045138203900251029 /* 0x1.56070dde90c800000 */,
+1.337855105129210686631 /* 0x1.567dac13510cd0009 */,
+1.339667524053662184301 /* 0x1.56f4736b52e2c000c */,
+1.341482398296830025383 /* 0x1.576b63f4d8333000f */,
+1.343299731186792467254 /* 0x1.57e27dbe2c40e0003 */,
+1.345119526053918823702 /* 0x1.5859c0d59cd37000f */,
+1.346941786233264881662 /* 0x1.58d12d497cd9a0005 */,
+1.348766515064854010261 /* 0x1.5948c32824b87000c */,
+1.350593715891792223641 /* 0x1.59c0827ff03890007 */,
+1.352423392064920459908 /* 0x1.5a386b5f43a3e0006 */,
+1.354255546937278120764 /* 0x1.5ab07dd485af1000c */,
+1.356090183865519494030 /* 0x1.5b28b9ee21085000f */,
+1.357927306213322804534 /* 0x1.5ba11fba8816e000b */,
+1.359766917346459269620 /* 0x1.5c19af482f8f2000f */,
+1.361609020638567812980 /* 0x1.5c9268a594cc00004 */,
+1.363453619463660171403 /* 0x1.5d0b4be135916000c */,
+1.365300717204201985683 /* 0x1.5d84590998eeb0005 */,
+1.367150317245710233754 /* 0x1.5dfd902d494e40001 */,
+1.369002422974674892971 /* 0x1.5e76f15ad22c40008 */,
+1.370857037789471544224 /* 0x1.5ef07ca0cc166000b */,
+1.372714165088220639199 /* 0x1.5f6a320dcf5280006 */,
+1.374573808273481745378 /* 0x1.5fe411b0790800009 */,
+1.376435970755022220096 /* 0x1.605e1b976e4b1000e */,
+1.378300655944092456600 /* 0x1.60d84fd155d15000e */,
+1.380167867259843417228 /* 0x1.6152ae6cdf0030003 */,
+1.382037608124419003675 /* 0x1.61cd3778bc879000d */,
+1.383909881963391264069 /* 0x1.6247eb03a4dc40009 */,
+1.385784692209972801544 /* 0x1.62c2c91c56d9b0002 */,
+1.387662042298923203992 /* 0x1.633dd1d1930ec0001 */,
+1.389541935670444372533 /* 0x1.63b90532200630004 */,
+1.391424375772021271329 /* 0x1.6434634ccc4cc0007 */,
+1.393309366052102982208 /* 0x1.64afec30677e90008 */,
+1.395196909966106124701 /* 0x1.652b9febc8e0f000d */,
+1.397087010973788290271 /* 0x1.65a77e8dcc7f10004 */,
+1.398979672539331309267 /* 0x1.66238825534170000 */,
+1.400874898129892187656 /* 0x1.669fbcc1415600008 */,
+1.402772691220124823310 /* 0x1.671c1c708328e000a */,
+1.404673055288671035301 /* 0x1.6798a7420988b000d */,
+1.406575993818903302975 /* 0x1.68155d44ca77a000f */,
+1.408481510297352468121 /* 0x1.68923e87bf70e000a */,
+1.410389608216942924956 /* 0x1.690f4b19e8f74000c */,
+1.412300291075172076232 /* 0x1.698c830a4c94c0008 */
+};
+#define S (1.0/4503599627370496.0)  /* 2^-52 */
+static const float exp2_deltatable[512] = {
+ 11527*S,  -963*S,   884*S,  -781*S, -2363*S, -3441*S,   123*S,   526*S,
+    -6*S,  1254*S, -1138*S,  1519*S,  1576*S,   -65*S,  1040*S,   793*S,
+ -1662*S, -5063*S,  -387*S,   968*S,  -941*S,   984*S, -2856*S,  -545*S,
+   495*S, -5246*S, -2109*S,  1281*S,  2075*S,   909*S, -1642*S,-78233*S,
+-31653*S,  -265*S,   130*S,   430*S,  2482*S,  -742*S,  1616*S, -2213*S,
+  -519*S,    20*S, -3134*S,-13981*S,  1343*S, -1740*S,   247*S,  1679*S,
+ -1097*S,  3131*S,   871*S, -1480*S,  1936*S, -1827*S, 17325*S,   528*S,
+  -322*S,  1404*S,  -152*S, -1845*S,  -212*S,  2639*S,  -476*S,  2960*S,
+  -962*S, -1012*S, -1231*S,  3030*S,  1659*S,  -486*S,  2154*S,  1728*S,
+ -2793*S,   699*S, -1560*S, -2125*S,  2156*S,   142*S, -1888*S,  4426*S,
+-13443*S,  1970*S,   -50*S,  1771*S,-43399*S,  4979*S, -2448*S,  -370*S,
+  1414*S,  1075*S,   232*S,   206*S,   873*S,  2141*S,  2970*S,  1279*S,
+ -2331*S,   336*S, -2595*S,   753*S, -3384*S,  -616*S,    89*S,  -818*S,
+  5755*S,  -241*S,  -528*S,  -661*S, -3777*S,  -354*S,   250*S,  3881*S,
+  2632*S, -2131*S,  2565*S,  -316*S,  1746*S, -2541*S, -1324*S,   -50*S,
+  2564*S,  -782*S,  1176*S,  6452*S, -1002*S,  1288*S,   336*S,  -185*S,
+  3063*S,  3784*S,  2169*S,   686*S,   328*S,  -400*S,   312*S, -4517*S,
+ -1457*S,  1046*S, -1530*S,  -685*S,  1328*S,-49815*S,  -895*S,  1063*S,
+ -2091*S,  -672*S, -1710*S,  -665*S,  1545*S,  1819*S,-45265*S,  3548*S,
+  -554*S,  -568*S,  4752*S, -1907*S,-13738*S,   675*S,  9611*S, -1115*S,
+  -815*S,   408*S, -1281*S,  -937*S,-16376*S, -4772*S, -1440*S,   992*S,
+   788*S, 10364*S, -1602*S,  -661*S, -1783*S,  -265*S,   -20*S, -3781*S,
+  -861*S,  -345*S,  -994*S,  1364*S, -5339*S,  1620*S,  9390*S, -1066*S,
+  -305*S,  -170*S,   175*S,  2461*S,  -490*S,  -769*S, -1450*S,  3315*S,
+  2418*S,   -45*S,  -852*S, -1295*S,  -488*S,   -96*S,  1142*S, -2639*S,
+  7905*S, -9306*S, -3859*S,   760*S,  1057*S, -1570*S,  3977*S,   209*S,
+  -514*S,  7151*S,  1646*S,   627*S,   599*S,  -774*S, -1468*S,   633*S,
+  -473*S,   851*S,  2406*S,   143*S,    74*S,  4260*S,  1177*S,  -913*S,
+  2670*S, -3298*S, -1662*S,  -120*S, -3264*S, -2148*S,   410*S,  2078*S,
+ -2098*S,  -926*S,  3580*S, -1289*S,  2450*S, -1158*S,   907*S,  -590*S,
+   986*S,  1801*S,  1145*S, -1677*S,  3455*S,   956*S,   710*S,   144*S,
+   153*S,  -255*S, -1898*S, 28102*S,  2748*S,  1194*S, -3009*S,  7076*S,
+     0*S, -2720*S,   711*S,  1225*S, -3034*S,  -473*S,   378*S, -1046*S,
+   962*S, -2006*S,  4647*S,  3206*S,  1769*S, -2665*S,  1254*S,  2025*S,
+ -2430*S,  6193*S,  1224*S,  -856*S, -1592*S,  -325*S, -1521*S,  1827*S,
+  -264*S,  2403*S, -1065*S,   967*S,  -681*S, -2106*S,  -474*S,  1333*S,
+  -893*S,  2296*S,   592*S, -1220*S,  -326*S,   990*S,   139*S,   206*S,
+  -779*S, -1683*S,  1238*S,  6098*S,   136*S,  1197*S,   790*S,  -107*S,
+ -1004*S, -2449*S,   939*S,  5568*S,   156*S,  1812*S,  2792*S, -1094*S,
+ -2677*S,  -251*S,  2297*S,   943*S, -1329*S,  2883*S,  -853*S, -2626*S,
+-105929*S, -6552*S,  1095*S, -1508*S,  1003*S,  5039*S, -2600*S,  -749*S,
+  1790*S,   890*S,  2016*S, -1073*S,   624*S, -2084*S, -1536*S, -1330*S,
+   358*S,  2444*S,  -179*S,-25759*S,  -243*S,  -552*S,  -124*S,  3766*S,
+  1192*S, -1614*S,     6*S, -1227*S,   345*S,  -981*S,  -295*S, -1006*S,
+  -995*S, -1195*S,   706*S,  2512*S, -1758*S,  -734*S, -6286*S,  -922*S,
+  1530*S,  1542*S,  1223*S,    61*S,   -83*S,   522*S,116937*S,  -914*S,
+  -418*S, -7339*S,   249*S,  -520*S,  -762*S,   426*S,  -505*S,  2664*S,
+ -1093*S, -1035*S,  2130*S,  4878*S,  1982*S,  1551*S,  2304*S,   193*S,
+  1532*S, -7268*S, 24357*S,   531*S,  2676*S, -1170*S,  1465*S, -1917*S,
+  2143*S,  1466*S,    -7*S, -7300*S,  3297*S, -1197*S,  -289*S, -1548*S,
+ 26226*S,  4401*S,  4123*S, -1588*S,  4243*S,  4069*S, -1276*S, -2010*S,
+  1407*S,  1478*S,   488*S, -2366*S, -2909*S, -2534*S, -1285*S,  7095*S,
+  -645*S, -2089*S,  -944*S,   -40*S, -1363*S,  -833*S,   917*S,  1609*S,
+  1286*S,  1677*S,  1613*S, -2295*S, -1248*S,    40*S,    26*S,  2038*S,
+   698*S,  2675*S, -1755*S, -3522*S, -1614*S, -6111*S,   270*S,  1822*S,
+  -234*S, -2844*S, -1201*S,  -830*S,  1193*S,  2354*S,    47*S,  1522*S,
+   -78*S,  -640*S,  2425*S, -1596*S,  1563*S,  1169*S, -1006*S,   -83*S,
+  2362*S, -3521*S,  -314*S,  1814*S, -1751*S,   305*S,  1715*S, -3741*S,
+  7847*S,  1291*S,  1206*S,    36*S,  1397*S, -1419*S, -1194*S, -2014*S,
+  1742*S,  -578*S,  -207*S,   875*S,  1539*S,  2826*S, -1165*S,  -909*S,
+  1849*S,   927*S,  2018*S,  -981*S,  1637*S,  -463*S,   905*S,  6618*S,
+   400*S,   630*S,  2614*S,   900*S,  2323*S, -1094*S, -1858*S,  -212*S,
+ -2069*S,   747*S,  1845*S, -1450*S,   444*S,  -213*S,  -438*S,  1158*S,
+  4738*S,  2497*S,  -370*S, -2016*S,  -518*S, -1160*S, -1510*S,   123*S
+};
+/* Maximum magnitude in above table: 116937 */
+#undef S
diff --git a/sysdeps/libm-ieee754/t_exp2f.h b/sysdeps/libm-ieee754/t_exp2f.h
new file mode 100644
index 0000000000..0f7674cefb
--- /dev/null
+++ b/sysdeps/libm-ieee754/t_exp2f.h
@@ -0,0 +1,301 @@
+/* These values are accurate to 23+9 bits when represented as
+   a float.  */
+static const float exp2_accuratetable[256] = {
+0.70711034541 /* 0x0.b5052f003 */,
+0.70903021104 /* 0x0.b58301004 */,
+0.71092861900 /* 0x0.b5ff6b006 */,
+0.71286851176 /* 0x0.b67e8d006 */,
+0.71481245762 /* 0x0.b6fdf3004 */,
+0.71673321725 /* 0x0.b77bd4001 */,
+0.71868461379 /* 0x0.b7fbb7006 */,
+0.72064983853 /* 0x0.b87c82006 */,
+0.72258073096 /* 0x0.b8fb0d003 */,
+0.72456008199 /* 0x0.b97cc5002 */,
+0.72652846578 /* 0x0.b9fdc5002 */,
+0.72848570353 /* 0x0.ba7e0a004 */,
+0.73046034578 /* 0x0.baff73003 */,
+0.73244112730 /* 0x0.bb8143000 */,
+0.73443359139 /* 0x0.bc03d7002 */,
+0.73646944762 /* 0x0.bc8943000 */,
+0.73839598903 /* 0x0.bd0785006 */,
+0.74041211608 /* 0x0.bd8ba6002 */,
+0.74243509775 /* 0x0.be103a004 */,
+0.74444299943 /* 0x0.be93d1004 */,
+0.74646854405 /* 0x0.bf1890003 */,
+0.74849390993 /* 0x0.bf9d4c006 */,
+0.75051373248 /* 0x0.c021ab003 */,
+0.75252974037 /* 0x0.c0a5ca002 */,
+0.75460278996 /* 0x0.c12da6006 */,
+0.75663453342 /* 0x0.c1b2cd001 */,
+0.75867807874 /* 0x0.c238ba006 */,
+0.76072299481 /* 0x0.c2bebe000 */,
+0.76271909478 /* 0x0.c3418f002 */,
+0.76482868204 /* 0x0.c3cbd0006 */,
+0.76694220311 /* 0x0.c45653004 */,
+0.76902121311 /* 0x0.c4de93003 */,
+0.77110719688 /* 0x0.c56748005 */,
+0.77314376835 /* 0x0.c5ecc0003 */,
+0.77531152970 /* 0x0.c67ad1004 */,
+0.77739948042 /* 0x0.c703a7005 */,
+0.77948719274 /* 0x0.c78c79007 */,
+0.78161448246 /* 0x0.c817e3004 */,
+0.78381162885 /* 0x0.c8a7e1002 */,
+0.78587090971 /* 0x0.c92ed6001 */,
+0.78799921275 /* 0x0.c9ba51001 */,
+0.79011362800 /* 0x0.ca44e3006 */,
+0.79225623615 /* 0x0.cad14e005 */,
+0.79441082487 /* 0x0.cb5e82006 */,
+0.79654645924 /* 0x0.cbea78003 */,
+0.79873132707 /* 0x0.cc79a8001 */,
+0.80093026168 /* 0x0.cd09c4005 */,
+0.80304825308 /* 0x0.cd9492001 */,
+0.80526113516 /* 0x0.ce2598004 */,
+0.80742740634 /* 0x0.ceb390002 */,
+0.80963188410 /* 0x0.cf4409000 */,
+0.81180763254 /* 0x0.cfd2a0006 */,
+0.81401169308 /* 0x0.d06312005 */,
+0.81622666121 /* 0x0.d0f43b000 */,
+0.81843453653 /* 0x0.d184ed005 */,
+0.82070738078 /* 0x0.d219e1001 */,
+0.82289630179 /* 0x0.d2a955003 */,
+0.82509487868 /* 0x0.d3396b000 */,
+0.82737630616 /* 0x0.d3ceef007 */,
+0.82961845408 /* 0x0.d461e0007 */,
+0.83179849386 /* 0x0.d4f0bf000 */,
+0.83408612023 /* 0x0.d586ab007 */,
+0.83636939536 /* 0x0.d61c4e007 */,
+0.83862531186 /* 0x0.d6b026000 */,
+0.84094470740 /* 0x0.d74827000 */,
+0.84316509971 /* 0x0.d7d9ab006 */,
+0.84546715027 /* 0x0.d87089004 */,
+0.84781247378 /* 0x0.d90a3d000 */,
+0.85004067431 /* 0x0.d99c44007 */,
+0.85237431530 /* 0x0.da3534003 */,
+0.85468208790 /* 0x0.dacc72000 */,
+0.85696077349 /* 0x0.db61c8002 */,
+0.85931611062 /* 0x0.dbfc24000 */,
+0.86171466122 /* 0x0.dc9955007 */,
+0.86397939929 /* 0x0.dd2dc1006 */,
+0.86633706098 /* 0x0.ddc844004 */,
+0.86868536481 /* 0x0.de622a006 */,
+0.87101131681 /* 0x0.defa99002 */,
+0.87337517739 /* 0x0.df9584000 */,
+0.87576484682 /* 0x0.e03220001 */,
+0.87814646969 /* 0x0.e0ce35007 */,
+0.88050335648 /* 0x0.e168ab002 */,
+0.88291734457 /* 0x0.e206df000 */,
+0.88522624975 /* 0x0.e29e30004 */,
+0.88768237833 /* 0x0.e33f27003 */,
+0.89007008077 /* 0x0.e3dba2001 */,
+0.89250904327 /* 0x0.e47b79004 */,
+0.89490824949 /* 0x0.e518b5007 */,
+0.89735335113 /* 0x0.e5b8f3001 */,
+0.89977204799 /* 0x0.e65776000 */,
+0.90221023561 /* 0x0.e6f740001 */,
+0.90468037137 /* 0x0.e79922006 */,
+0.90711551909 /* 0x0.e838b9003 */,
+0.90958660844 /* 0x0.e8daab002 */,
+0.91205561170 /* 0x0.e97c7a006 */,
+0.91451990614 /* 0x0.ea1dfa006 */,
+0.91699457179 /* 0x0.eac028007 */,
+0.91948717833 /* 0x0.eb6383000 */,
+0.92201787240 /* 0x0.ec095d004 */,
+0.92446959027 /* 0x0.ecaa0a006 */,
+0.92700457577 /* 0x0.ed502c003 */,
+0.92946064473 /* 0x0.edf122000 */,
+0.93202102187 /* 0x0.ee98ee001 */,
+0.93454003345 /* 0x0.ef3e04007 */,
+0.93707615143 /* 0x0.efe439004 */,
+0.93964391957 /* 0x0.f08c81007 */,
+0.94217014323 /* 0x0.f13210007 */,
+0.94470518835 /* 0x0.f1d833005 */,
+0.94727593667 /* 0x0.f280ad004 */,
+0.94985383753 /* 0x0.f3299f002 */,
+0.95245110992 /* 0x0.f3d3d6002 */,
+0.95500063903 /* 0x0.f47aec004 */,
+0.95758175857 /* 0x0.f52414004 */,
+0.96018302447 /* 0x0.f5ce8e004 */,
+0.96279788024 /* 0x0.f679ec005 */,
+0.96541762355 /* 0x0.f7259c002 */,
+0.96803289660 /* 0x0.f7d101005 */,
+0.97066921004 /* 0x0.f87dc7006 */,
+0.97328519823 /* 0x0.f92938001 */,
+0.97589331867 /* 0x0.f9d425001 */,
+0.97858297827 /* 0x0.fa846a001 */,
+0.98121380814 /* 0x0.fb30d4005 */,
+0.98389244083 /* 0x0.fbe060002 */,
+0.98657202723 /* 0x0.fc8ffc001 */,
+0.98919564488 /* 0x0.fd3bed001 */,
+0.99194401506 /* 0x0.fdf00b002 */,
+0.99460238224 /* 0x0.fe9e43004 */,
+0.99728542574 /* 0x0.ff4e19005 */,
+1.00000000000 /* 0x1.000000000 */,
+1.00271666054 /* 0x1.00b20a003 */,
+1.00544095058 /* 0x1.01649400c */,
+1.00819313547 /* 0x1.0218f200e */,
+1.01089513312 /* 0x1.02ca06007 */,
+1.01363527782 /* 0x1.037d9a005 */,
+1.01635849497 /* 0x1.04301200e */,
+1.01918780808 /* 0x1.04e97e003 */,
+1.02182090297 /* 0x1.05960e00a */,
+1.02468311789 /* 0x1.0651a2002 */,
+1.02744102491 /* 0x1.070660009 */,
+1.03019988541 /* 0x1.07bb2e002 */,
+1.03300857552 /* 0x1.087340005 */,
+1.03580951708 /* 0x1.092ad000b */,
+1.03865504271 /* 0x1.09e54c004 */,
+1.04145348082 /* 0x1.0a9cb2007 */,
+1.04426109801 /* 0x1.0b54b2007 */,
+1.04706287389 /* 0x1.0c0c50003 */,
+1.04996109020 /* 0x1.0cca40007 */,
+1.05282557024 /* 0x1.0d85fa009 */,
+1.05564439314 /* 0x1.0e3eb600c */,
+1.05850863475 /* 0x1.0efa6c00c */,
+1.06137108805 /* 0x1.0fb604001 */,
+1.06423723713 /* 0x1.1071da00a */,
+1.06716394429 /* 0x1.1131a8003 */,
+1.07004547127 /* 0x1.11ee80005 */,
+1.07294559497 /* 0x1.12ac9000c */,
+1.07586789139 /* 0x1.136c14005 */,
+1.07873940478 /* 0x1.142844007 */,
+1.08172726651 /* 0x1.14ec1400e */,
+1.08459246171 /* 0x1.15a7da008 */,
+1.08752059939 /* 0x1.1667c0001 */,
+1.09050178536 /* 0x1.172b20005 */,
+1.09349620361 /* 0x1.17ef5e00d */,
+1.09634935875 /* 0x1.18aa5a00d */,
+1.09940552720 /* 0x1.1972a4006 */,
+1.10237383858 /* 0x1.1a352c00a */,
+1.10530221471 /* 0x1.1af516006 */,
+1.10838031771 /* 0x1.1bbed0001 */,
+1.11137616648 /* 0x1.1c8326009 */,
+1.11441528816 /* 0x1.1d4a5200d */,
+1.11741960066 /* 0x1.1e0f3600c */,
+1.12044525152 /* 0x1.1ed580003 */,
+1.12346303485 /* 0x1.1f9b4600f */,
+1.12655401230 /* 0x1.2065d8000 */,
+1.12955987463 /* 0x1.212ad6007 */,
+1.13263440148 /* 0x1.21f45400b */,
+1.13567769541 /* 0x1.22bbc6009 */,
+1.13877141483 /* 0x1.238686005 */,
+1.14189016826 /* 0x1.2452ea004 */,
+1.14495265504 /* 0x1.251b9e00e */,
+1.14807951452 /* 0x1.25e88a001 */,
+1.15118837366 /* 0x1.26b448006 */,
+1.15428590795 /* 0x1.277f4800e */,
+1.15744590761 /* 0x1.284e60001 */,
+1.16055941596 /* 0x1.291a6c00a */,
+1.16371822369 /* 0x1.29e970008 */,
+1.16683173193 /* 0x1.2ab57c009 */,
+1.17002511035 /* 0x1.2b86c4007 */,
+1.17321026344 /* 0x1.2c578200d */,
+1.17639815811 /* 0x1.2d286e002 */,
+1.17961537856 /* 0x1.2dfb4600c */,
+1.18278920671 /* 0x1.2ecb4600e */,
+1.18602204342 /* 0x1.2f9f2400d */,
+1.18924140952 /* 0x1.30722000f */,
+1.19246912021 /* 0x1.3145a800c */,
+1.19566547881 /* 0x1.321722007 */,
+1.19890022298 /* 0x1.32eb2000e */,
+1.20205938816 /* 0x1.33ba2a000 */,
+1.20533752458 /* 0x1.34910000b */,
+1.20865476136 /* 0x1.356a66003 */,
+1.21195018302 /* 0x1.36425e007 */,
+1.21525228034 /* 0x1.371ac6007 */,
+1.21851313125 /* 0x1.37f07a007 */,
+1.22183310988 /* 0x1.38ca0e001 */,
+1.22516608253 /* 0x1.39a47c00a */,
+1.22848713419 /* 0x1.3a7e2200f */,
+1.23174583912 /* 0x1.3b53b2000 */,
+1.23522067082 /* 0x1.3c376c008 */,
+1.23849928397 /* 0x1.3d0e4a00c */,
+1.24181902431 /* 0x1.3de7da00f */,
+1.24523758889 /* 0x1.3ec7e4001 */,
+1.24859035038 /* 0x1.3fa39e00f */,
+1.25193393249 /* 0x1.407ebe00d */,
+1.25539278994 /* 0x1.41616c007 */,
+1.25880420214 /* 0x1.4240fe004 */,
+1.26223969480 /* 0x1.43222400e */,
+1.26558542253 /* 0x1.43fd68001 */,
+1.26904225354 /* 0x1.44dff4003 */,
+1.27251851576 /* 0x1.45c3c600c */,
+1.27593302748 /* 0x1.46a38c00f */,
+1.27941727649 /* 0x1.4787e4007 */,
+1.28286683578 /* 0x1.4869f600d */,
+1.28636789342 /* 0x1.494f6800e */,
+1.28982734693 /* 0x1.4a3220009 */,
+1.29335498813 /* 0x1.4b1950002 */,
+1.29684555547 /* 0x1.4bfe1200b */,
+1.30039131655 /* 0x1.4ce672009 */,
+1.30388665216 /* 0x1.4dcb8400b */,
+1.30738770972 /* 0x1.4eb0f6007 */,
+1.31095492852 /* 0x1.4f9abe008 */,
+1.31452167056 /* 0x1.50847e00f */,
+1.31807971017 /* 0x1.516dac00b */,
+1.32168746004 /* 0x1.525a1c006 */,
+1.32518649117 /* 0x1.533f6c00b */,
+1.32884454737 /* 0x1.542f28007 */,
+1.33244597914 /* 0x1.551b2e002 */,
+1.33601069461 /* 0x1.5604cc007 */,
+1.33969032765 /* 0x1.56f5f2000 */,
+1.34328985233 /* 0x1.57e1d800d */,
+1.34692609319 /* 0x1.58d026006 */,
+1.35055744648 /* 0x1.59be22000 */,
+1.35424625891 /* 0x1.5aafe200c */,
+1.35795569436 /* 0x1.5ba2fc00b */,
+1.36158764384 /* 0x1.5c910200e */,
+1.36525344864 /* 0x1.5d814000a */,
+1.36908590815 /* 0x1.5e7c6a00e */,
+1.37272357954 /* 0x1.5f6ad0009 */,
+1.37639832498 /* 0x1.605ba4001 */,
+1.38020527377 /* 0x1.615522009 */,
+1.38388323800 /* 0x1.62462c00b */,
+1.38770687583 /* 0x1.6340c2002 */,
+1.39144265656 /* 0x1.643596003 */,
+1.39518976211 /* 0x1.652b28000 */,
+1.39905631551 /* 0x1.66288e006 */,
+1.40280294419 /* 0x1.671e18000 */,
+1.40661609194 /* 0x1.6817fe00e */,
+1.41035604489 /* 0x1.690d18008 */
+};
+#define S (1.0/8388608.0)  /* 2^-23 */
+static const float exp2_deltatable[256] = {
+    61*S,   107*S,  -301*S,   -91*S,    98*S,  -194*S,   -57*S,   223*S,
+  -162*S,   176*S,   241*S,    32*S,    24*S,    29*S,   138*S,   871*S,
+  -280*S,   -49*S,   204*S,   122*S,   238*S,   262*S,   108*S,  -195*S,
+   330*S,   103*S,   -23*S,  -215*S, -1269*S,  -610*S,    19*S,    13*S,
+    28*S,  -819*S,   298*S,    78*S,  -233*S,   -18*S,  1186*S,   172*S,
+   135*S,  -203*S,  -197*S,   -97*S,  -374*S,     8*S,   512*S,  -295*S,
+   240*S,   -15*S,   214*S,   -75*S,   -30*S,    88*S,    12*S,   806*S,
+   273*S,  -204*S,   445*S,   429*S,  -579*S,  -109*S,   207*S,    38*S,
+   695*S,  -161*S,    68*S,   825*S,  -178*S,   233*S,   187*S,  -358*S,
+    91*S,  1056*S,    53*S,   265*S,   257*S,  -150*S,  -118*S,   182*S,
+   281*S,   -49*S,   317*S,  -844*S,   -80*S,  -339*S,    10*S,  -269*S,
+   -16*S,  -208*S,  -226*S,    95*S,  -141*S,    14*S,    52*S,   -61*S,
+  -125*S,   -41*S,   454*S,  -176*S,   196*S,  -550*S,   -26*S,  -129*S,
+   -99*S,   250*S,   -25*S,  -274*S,  -154*S,   -32*S,   247*S,  -169*S,
+  -272*S,  -209*S,   -64*S,    53*S,    25*S,   171*S,   -25*S,  -406*S,
+   135*S,  -141*S,    84*S,   231*S,  -396*S,   414*S,    36*S,  -129*S,
+     0*S,    65*S,   133*S,   447*S,    70*S,    62*S,  -236*S,   639*S,
+  -903*S,   181*S,   -58*S,  -373*S,  -191*S,  -189*S,   244*S,    39*S,
+  -147*S,  -488*S,   196*S,   400*S,    -9*S,    15*S,   -70*S,  -201*S,
+   267*S,   133*S,   121*S,   270*S,  -240*S,   466*S,  -289*S,  -428*S,
+   -66*S,   352*S,  -880*S,    41*S,   -96*S,  -758*S,   130*S,    29*S,
+   310*S,   124*S,    81*S,  -135*S,   348*S,  -172*S,   -44*S,  -338*S,
+  -183*S,   148*S,  -206*S,    32*S,    -9*S,  -257*S,    61*S,  -196*S,
+   -69*S,  -501*S,  -193*S,   -60*S,    12*S,   296*S,    46*S,   311*S,
+   349*S,   383*S,    11*S,   -60*S,  -980*S,  -789*S,  -296*S,  -112*S,
+    49*S,  -289*S,  -128*S,    72*S,    65*S,  -643*S,   682*S,    -6*S,
+  -378*S,   124*S,  -103*S,  -506*S,   116*S,   190*S,   406*S,  -326*S,
+   -83*S,   255*S,   -83*S,   152*S,   -30*S,   185*S,   -80*S,   206*S,
+    56*S,   332*S,    50*S,  -266*S,   -58*S,    56*S,     1*S,   313*S,
+  -458*S,   135*S,   122*S,  -312*S,   206*S,   -89*S,  -141*S,  -325*S,
+   -83*S,   253*S,  -190*S,  -419*S,   738*S,    83*S,  -331*S,   328*S,
+  -233*S,   391*S,   159*S,   -62*S,   663*S,   261*S,   345*S,  -288*S
+};
+/* Maximum magnitude in above table: 1269 */
+#undef S
+#define EXP2_TSIZE 8
+#define EXP2_TTOL 9
+#define EXP2_FSIZE 23
+#define EXP2_FNAME float
diff --git a/sysdeps/libm-ieee754/w_exp2.c b/sysdeps/libm-ieee754/w_exp2.c
new file mode 100644
index 0000000000..126aa090bc
--- /dev/null
+++ b/sysdeps/libm-ieee754/w_exp2.c
@@ -0,0 +1,36 @@
+/*
+ * wrapper exp2(x)
+ */
+
+#include <float.h>
+#include "math.h"
+#include "math_private.h"
+
+static const double o_threshold= (double) DBL_MAX_EXP;
+static const double u_threshold= (double) DBL_MIN_EXP;
+
+double
+__exp2 (double x)		/* wrapper exp2 */
+{
+#ifdef _IEEE_LIBM
+  return __ieee754_exp2 (x);
+#else
+  double z;
+  z = __ieee754_exp2 (x);
+  if (_LIB_VERSION != _IEEE_ && __finite (x))
+    {
+      if (x > o_threshold)
+	/* exp2 overflow */
+	return __kernel_standard (x, x, 44);
+      else if (x < u_threshold)
+	/* exp2 underflow */
+	return __kernel_standard (x, x, 45);
+    }
+  return z;
+#endif
+}
+weak_alias (__exp2, exp2)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__exp2, __expl2)
+weak_alias (__exp2, expl2)
+#endif
diff --git a/sysdeps/libm-ieee754/w_exp2f.c b/sysdeps/libm-ieee754/w_exp2f.c
new file mode 100644
index 0000000000..d2c340db3f
--- /dev/null
+++ b/sysdeps/libm-ieee754/w_exp2f.c
@@ -0,0 +1,32 @@
+/*
+ * wrapper exp2f(x)
+ */
+
+#include <float.h>
+#include "math.h"
+#include "math_private.h"
+
+static const float o_threshold= (float) FLT_MAX_EXP;
+static const float u_threshold= (float) FLT_MIN_EXP;
+
+float
+__exp2f (float x)		/* wrapper exp2f */
+{
+#ifdef _IEEE_LIBM
+  return __ieee754_exp2f (x);
+#else
+  float z;
+  z = __ieee754_exp2f (x);
+  if (_LIB_VERSION != _IEEE_ && __finitef (x))
+    {
+      if (x > o_threshold)
+	/* exp2 overflow */
+	return (float) __kernel_standard ((double) x, (double) x, 144);
+      else if (x < u_threshold)
+	/* exp2 underflow */
+	return (float) __kernel_standard ((double) x, (double) x, 145);
+    }
+  return z;
+#endif
+}
+weak_alias (__exp2f, exp2f)
diff --git a/sysdeps/libm-ieee754/w_exp2l.c b/sysdeps/libm-ieee754/w_exp2l.c
new file mode 100644
index 0000000000..965e9bf3e4
--- /dev/null
+++ b/sysdeps/libm-ieee754/w_exp2l.c
@@ -0,0 +1,30 @@
+/*
+ * wrapper exp2l(x)
+ */
+
+#include <float.h>
+#include "math.h"
+#include "math_private.h"
+
+static const long double o_threshold = (long double) LDBL_MAX_EXP;
+static const long double u_threshold = (long double) LDBL_MIN_EXP;
+
+long double
+__exp2l (long double x)			/* wrapper exp2l */
+{
+#ifdef _IEEE_LIBM
+  return __ieee754_exp2l (x);
+#else
+  long double z;
+  z = __ieee754_exp2l (x);
+  if (_LIB_VERSION != _IEEE_ && __finitel (x))
+    {
+      if (x > o_threshold)
+	return __kernel_standard (x, x, 244); /* exp2l overflow */
+      else if (x < u_threshold)
+	return __kernel_standard (x, x, 245); /* exp2l underflow */
+    }
+  return z;
+#endif
+}
+weak_alias (__exp2l, exp2l)
diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
index 3e8f22b573..1813c78dd8 100644
--- a/sysdeps/powerpc/Makefile
+++ b/sysdeps/powerpc/Makefile
@@ -21,7 +21,7 @@ endif
 # so that's at least 8192 entries.  Since libc only uses about 1200 entries,
 # we want to use -fpic, because this generates fewer relocs.
 ifeq (yes,$(build-shared))
-CFLAGS-.os = -fpic -fno-common
+pic-ccflag = -fpic
 endif
 
 # The initfini generation code doesn't work in the presence of -fPIC, so
@@ -29,3 +29,7 @@ endif
 ifeq ($(subdir),csu)
 CFLAGS-initfini.s = -g0 -fpic
 endif
+
+ifeq ($(subdir),string)
+CFLAGS-memcmp.c += -Wno-uninitialized
+endif
diff --git a/sysdeps/powerpc/bits/mathinline.h b/sysdeps/powerpc/bits/mathinline.h
index d7f2a3ac0d..d7cabaf28b 100644
--- a/sysdeps/powerpc/bits/mathinline.h
+++ b/sysdeps/powerpc/bits/mathinline.h
@@ -32,34 +32,22 @@ __sgn1 (double __x)
 {
   return __x >= 0.0 ? 1.0 : -1.0;
 }
+#endif /* __NO_MATH_INLINES && __OPTIMZE__ */
 
-/* We'd want to use this if it was implemented in hardware, but
-   how can we tell? */
-#if 0
-__MATH_INLINE double sqrt (double __x);
-__MATH_INLINE double
-sqrt (double __x)
-{
-  register double __value;
-  __asm
-    ("fsqrt %0,%1"
-     : "=f" (__value) : "f" (__x));
-
-  return __value;
-}
-#endif
-
-__MATH_INLINE double fabs (double __x);
-__MATH_INLINE double
-fabs (double __x)
-{
-  register double __value;
-  __asm
-    ("fabs %0,%1"
-     : "=f" (__value) : "f" (__x));
-
-  return __value;
-}
+#if __USE_ISOC9X
+# define __unordered_cmp(x, y) \
+  (__extension__							      \
+   ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y);			      \
+      unsigned __r;							      \
+      __asm__("fcmpu 7,%1,%2 ; mfcr %0" : "=r" (__r) : "f" (__x), "f"(__y));  \
+      __r; }))
+
+# define isgreater(x, y) (__unordered_cmp (x, y) >> 2 & 1)
+# define isgreaterequal(x, y) ((__unordered_cmp (x, y) & 6) != 0)
+# define isless(x, y) (__unordered_cmp (x, y) >> 3 & 1)
+# define islessequal(x, y) ((__unordered_cmp (x, y) & 0xA) != 0)
+# define islessgreater(x, y) ((__unordered_cmp (x, y) & 0xC) != 0)
+# define isunordered(x, y) (__unordered_cmp (x, y) & 1)
+#endif /* __USE_ISOC9X */
 
-#endif /* __NO_MATH_INLINES && __OPTIMZE__ */
 #endif /* __GNUC__  */
diff --git a/sysdeps/powerpc/bzero.S b/sysdeps/powerpc/bzero.S
new file mode 100644
index 0000000000..783a91fdcb
--- /dev/null
+++ b/sysdeps/powerpc/bzero.S
@@ -0,0 +1,27 @@
+/* Optimized bzero `implementation' for PowerPC.
+   Copyright (C) 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 <sysdep.h>
+
+ENTRY(__bzero)
+	mr	%r5,%r4
+	li	%r4,0
+	b	memset@local
+END(__bzero)
+weak_alias (__bzero, bzero)
diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h
index 771b711a14..70a3f20b31 100644
--- a/sysdeps/powerpc/dl-machine.h
+++ b/sysdeps/powerpc/dl-machine.h
@@ -199,6 +199,53 @@ _dl_runtime_resolve:
 	bctr
 0:
 	.size	 _dl_runtime_resolve,0b-_dl_runtime_resolve
+
+	.align 2
+	.globl _dl_prof_resolve
+	.type _dl_prof_resolve,@function
+_dl_prof_resolve:
+ # We need to save the registers used to pass parameters, and register 0,
+ # which is used by _mcount; the registers are saved in a stack frame.
+	stwu 1,-48(1)
+        stw 0,12(1)
+	stw 3,16(1)
+	stw 4,20(1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+	mr 3,12
+	stw 5,24(1)
+	mr 4,11
+	stw 6,28(1)
+	mflr 5
+ # We also need to save some of the condition register fields.
+	stw 7,32(1)
+	stw 5,52(1)
+	stw 8,36(1)
+	mfcr 0
+	stw 9,40(1)
+	stw 10,44(1)
+	stw 0,8(1)
+	bl profile_fixup@local
+ # 'fixup' returns the address we want to branch to.
+	mtctr 3
+ # Put the registers back...
+	lwz 0,52(1)
+	lwz 10,44(1)
+	lwz 9,40(1)
+	mtlr 0
+	lwz 8,36(1)
+	lwz 0,8(1)
+	lwz 7,32(1)
+	lwz 6,28(1)
+	mtcrf 0xFF,0
+	lwz 5,24(1)
+	lwz 4,20(1)
+	lwz 3,16(1)
+        lwz 0,12(1)
+ # ...unwind the stack frame, and jump to the PLT entry we updated.
+	addi 1,1,48
+	bctr
+0:
+	.size	 _dl_prof_resolve,0b-_dl_prof_resolve
  # Undo '.section text'.
 	.previous
 ");
@@ -409,8 +456,14 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
       Elf32_Word num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
 				    / sizeof (Elf32_Rela));
       Elf32_Word rel_offset_words = PLT_DATA_START_WORDS (num_plt_entries);
-      extern void _dl_runtime_resolve (void);
       Elf32_Word size_modified;
+      extern void _dl_runtime_resolve (void);
+      extern void _dl_prof_resolve (void);
+      Elf32_Word dlrr;
+
+      dlrr = (Elf32_Word)(char *)(profile
+				  ? _dl_prof_resolve
+				  : _dl_runtime_resolve);
 
       if (lazy)
 	for (i = 0; i < num_plt_entries; i++)
@@ -433,8 +486,7 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
       /* Multiply index of entry by 3 (in r11).  */
       plt[0] = OPCODE_SLWI (12, 11, 1);
       plt[1] = OPCODE_ADD (11, 12, 11);
-      if ((Elf32_Word) (char *) _dl_runtime_resolve <= 0x01fffffc ||
-	  (Elf32_Word) (char *) _dl_runtime_resolve >= 0xfe000000)
+      if (dlrr <= 0x01fffffc || dlrr >= 0xfe000000)
 	{
 	  /* Load address of link map in r12.  */
 	  plt[2] = OPCODE_LI (12, (Elf32_Word) (char *) map);
@@ -442,15 +494,13 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
 					   + 0x8000) >> 16));
 
 	  /* Call _dl_runtime_resolve.  */
-	  plt[4] = OPCODE_BA ((Elf32_Word) (char *) _dl_runtime_resolve);
+	  plt[4] = OPCODE_BA (dlrr);
 	}
       else
 	{
 	  /* Get address of _dl_runtime_resolve in CTR.  */
-	  plt[2] = OPCODE_LI (12, (Elf32_Word) (char *) _dl_runtime_resolve);
-	  plt[3] = OPCODE_ADDIS (12, 12, ((((Elf32_Word) (char *)
-					    _dl_runtime_resolve)
-					   + 0x8000) >> 16));
+	  plt[2] = OPCODE_LI (12, dlrr);
+	  plt[3] = OPCODE_ADDIS (12, 12, (dlrr + 0x8000) >> 16);
 	  plt[4] = OPCODE_MTCTR (12);
 
 	  /* Load address of link map in r12.  */
@@ -501,7 +551,6 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
 static inline void
 elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
 {
-  assert (ELF32_R_TYPE (reloc->r_info) == R_PPC_JMP_SLOT);
   /* elf_machine_runtime_setup handles this. */
 }
 
@@ -513,7 +562,7 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
    LOADADDR is the load address of the object; INFO is an array indexed
    by DT_* of the .dynamic section info.  */
 
-static inline void
+static void
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
 		  Elf32_Addr *const reloc_addr)
@@ -709,4 +758,4 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 
 #define ELF_MACHINE_NO_REL 1
 
-#endif
+#endif /* RESOLVE */
diff --git a/sysdeps/powerpc/machine-gmon.h b/sysdeps/powerpc/machine-gmon.h
index ba53807308..b890dd5c53 100644
--- a/sysdeps/powerpc/machine-gmon.h
+++ b/sysdeps/powerpc/machine-gmon.h
@@ -1,7 +1,6 @@
 /* PowerPC-specific implementation of profiling support.
    Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
    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
diff --git a/sysdeps/powerpc/stpcpy.S b/sysdeps/powerpc/stpcpy.S
new file mode 100644
index 0000000000..58ad5b12b6
--- /dev/null
+++ b/sysdeps/powerpc/stpcpy.S
@@ -0,0 +1,100 @@
+/* Optimized stpcpy implementation for PowerPC.
+   Copyright (C) 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 <sysdep.h>
+
+/* See strlen.s for comments on how the end-of-string testing works.  */
+
+EALIGN(__stpcpy,4,0)
+/* char * [r3] stpcpy (char *dest [r3], const char *src [r4])  */
+
+/* General register assignments:
+   r0:	temporary
+   r3:	pointer to previous word in dest
+   r4:	pointer to previous word in src
+   r6:	current word from src
+   r7:	0xfefefeff
+   r8:	0x7f7f7f7f
+   r9:	~(word in src | 0x7f7f7f7f)
+   r10:	alternate word from src.  */
+
+	or    %r0,%r4,%r3
+	clrlwi. %r0,%r0,30
+	addi  %r3,%r3,-4
+	bne   L(unaligned)
+
+	lis   %r7,0xfeff
+	lis   %r8,0x7f7f
+	lwz   %r6,0(%r4)
+	addi  %r7,%r7,-0x101
+	addi  %r8,%r8,0x7f7f
+	b     2f
+
+0:	lwzu  %r10,4(%r4)
+	stwu  %r6,4(%r3)
+	add   %r0,%r7,%r10
+	nor   %r9,%r8,%r10
+	and.  %r0,%r0,%r9
+	bne-  1f
+	lwzu  %r6,4(%r4)
+	stwu  %r10,4(%r3)
+2:	add   %r0,%r7,%r6
+	nor   %r9,%r8,%r6
+	and.  %r0,%r0,%r9
+	beq+  0b
+
+	mr    %r10,%r6
+/* We've hit the end of the string.  Do the rest byte-by-byte.  */
+1:	rlwinm. %r0,%r10,8,24,31
+	stbu  %r0,4(%r3)
+	beqlr-
+	rlwinm. %r0,%r10,16,24,31
+	stbu  %r0,1(%r3)
+	beqlr-
+	rlwinm. %r0,%r10,24,24,31
+	stbu  %r0,1(%r3)
+	beqlr-
+	stbu  %r10,1(%r3)
+	blr
+
+/* Oh well.  In this case, we just do a byte-by-byte copy.  */
+	.align 4
+	nop
+L(unaligned):
+	lbz   %r6,0(%r4)
+	addi  %r3,%r3,3
+	cmpwi %r6,0
+	beq-  2f
+
+0:	lbzu  %r10,1(%r4)
+	stbu  %r6,1(%r3)
+	cmpwi %r10,0
+	beq-  1f
+	nop		/* Let 601 load start of loop.  */
+	lbzu  %r6,1(%r4)
+	stbu  %r10,1(%r3)
+	cmpwi %r6,0
+	bne+  0b
+2:	stbu  %r6,1(%r3)
+	blr
+1:	stbu  %r10,1(%r3)
+	blr
+END(__stpcpy)
+
+weak_alias (__stpcpy, stpcpy)
diff --git a/sysdeps/powerpc/strcat.c b/sysdeps/powerpc/strcat.c
new file mode 100644
index 0000000000..9d9ab6549a
--- /dev/null
+++ b/sysdeps/powerpc/strcat.c
@@ -0,0 +1,30 @@
+/* strcat version that uses fast strcpy/strlen.
+   Copyright (C) 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 <string.h>
+
+#undef strcat
+
+/* Append SRC on the end of DEST.  */
+char *
+strcat (char *dest, const char *src)
+{
+  strcpy (dest + strlen (dest), src);
+  return dest;
+}
diff --git a/sysdeps/powerpc/strcpy.S b/sysdeps/powerpc/strcpy.S
new file mode 100644
index 0000000000..3c0cce7844
--- /dev/null
+++ b/sysdeps/powerpc/strcpy.S
@@ -0,0 +1,100 @@
+/* Optimized strcpy implementation for PowerPC.
+   Copyright (C) 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 <sysdep.h>
+
+/* See strlen.s for comments on how the end-of-string testing works.  */
+
+EALIGN(strcpy,4,0)
+/* char * [r3] strcpy (char *dest [r3], const char *src [r4])  */
+
+/* General register assignments:
+   r0:	temporary
+   r3:	saved `dest'
+   r4:	pointer to previous word in src
+   r5:	pointer to previous word in dest
+   r6:	current word from src
+   r7:	0xfefefeff
+   r8:	0x7f7f7f7f
+   r9:	~(word in src | 0x7f7f7f7f)
+   r10:	alternate word from src.  */
+
+	or    %r0,%r4,%r3
+	clrlwi. %r0,%r0,30
+	addi  %r5,%r3,-4
+	bne   L(unaligned)
+
+	lis   %r7,0xfeff
+	lis   %r8,0x7f7f
+	lwz   %r6,0(%r4)
+	addi  %r7,%r7,-0x101
+	addi  %r8,%r8,0x7f7f
+	b     2f
+
+0:	lwzu  %r10,4(%r4)
+	stwu  %r6,4(%r5)
+	add   %r0,%r7,%r10
+	nor   %r9,%r8,%r10
+	and.  %r0,%r0,%r9
+	bne-  1f
+	lwzu  %r6,4(%r4)
+	stwu  %r10,4(%r5)
+2:	add   %r0,%r7,%r6
+	nor   %r9,%r8,%r6
+	and.  %r0,%r0,%r9
+	beq+  0b
+
+	mr    %r10,%r6
+/* We've hit the end of the string.  Do the rest byte-by-byte.  */
+1:	rlwinm. %r0,%r10,8,24,31
+	stb   %r0,4(%r5)
+	beqlr-
+	rlwinm. %r0,%r10,16,24,31
+	stb   %r0,5(%r5)
+	beqlr-
+	rlwinm. %r0,%r10,24,24,31
+	stb   %r0,6(%r5)
+	beqlr-
+	stb   %r10,7(%r5)
+	blr
+
+/* Oh well.  In this case, we just do a byte-by-byte copy.  */
+	.align 4
+	nop
+L(unaligned):
+	lbz   %r6,0(%r4)
+	addi  %r5,%r3,-1
+	cmpwi %r6,0
+	beq-  2f
+
+0:	lbzu  %r10,1(%r4)
+	stbu  %r6,1(%r5)
+	cmpwi %r10,0
+	beq-  1f
+	nop		/* Let 601 load start of loop.  */
+	lbzu  %r6,1(%r4)
+	stbu  %r10,1(%r5)
+	cmpwi %r6,0
+	bne+  0b
+2:	stb   %r6,1(%r5)
+	blr
+1:	stb   %r10,1(%r5)
+	blr
+
+END(strcpy)
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
index 7a2b0c8279..6b4373db0f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
@@ -1,5 +1,5 @@
 /* Operating system support for run-time dynamic linker.  Linux/PPC version.
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 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
diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h b/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h
index 49460661e2..c3908d7080 100644
--- a/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h
+++ b/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h
@@ -39,4 +39,16 @@ struct __kernel_termios
 #define _HAVE_C_ISPEED 1
 #define _HAVE_C_OSPEED 1
 
+/* We have the kernel termios structure, so we can presume this code knows
+   what it's doing...  */
+
+#undef  TCGETS
+#undef  TCSETS
+#undef  TCSETSW
+#undef  TCSETSF
+#define TCGETS	_IOR ('t', 19, struct __kernel_termios)
+#define TCSETS	_IOW ('t', 20, struct __kernel_termios)
+#define TCSETSW	_IOW ('t', 21, struct __kernel_termios)
+#define TCSETSF	_IOW ('t', 22, struct __kernel_termios)
+
 #endif /* kernel_termios.h */