about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-09-11 12:09:10 +0000
committerUlrich Drepper <drepper@redhat.com>1997-09-11 12:09:10 +0000
commit9a0a462ceb4ab96c909b182f3052de2ef13fbe3a (patch)
tree59456497b6acefe69aab04fc28c38ea38852ccc7
parent26b4d7667169f8db26fd8194b3c498ec58e50f90 (diff)
downloadglibc-9a0a462ceb4ab96c909b182f3052de2ef13fbe3a.tar.gz
glibc-9a0a462ceb4ab96c909b182f3052de2ef13fbe3a.tar.xz
glibc-9a0a462ceb4ab96c909b182f3052de2ef13fbe3a.zip
Update.
1997-09-11 04:36  Ulrich Drepper  <drepper@cygnus.com>

	* db2/db_int.h: Define __set_errno if not yet available.
	* db2/btree/bt_rec.c: Use __set_errno to set errno value.
	* db2/clib/getlong.c: Likewise.
	* db2/db185/db185.c: Likewise.
	* db2/db185/db185_int.h: Likewise.
	* db2/dbm/dbm.c: Likewise.
	* db2/lock/lock_deadlock.c: Likewise.
	* db2/log/log_archive.c: Likewise.

	* elf/dl-profile.c: Implement mcount function.

	* gmon/gmon.c: Use __profil not profil because of namespace pollution.
	* gmon/mcount.c: Remove BSD kernel code.
	Use compare&swap instruction if possible to change state variable.
	Optimize frompc folding.
	* gmon/sys/gmon.h (struct gmonparam): Change state field to long int.
	* sysdeps/i386/i486/atomicity.h: New file.
	* sysdeps/stub/atomicity.h: New file.
	* sysdeps/mach/hurd/profil.c: Define function as __profil and make
	profil weak alias.
	* sysdeps/posix/profil.c: Likewise.

	* string/bits/string2.h: New file.
	* include/bits/string2.h: New file.
	* string/Makefile (routines): Add mempcpy.
	(tests): Add inl-tester.
	Remove _D__NO_STRING_INLINES from CFLAGS-* variables.
	* sysdeps/generic/mempcpy.c: New file.
	* sysdeps/generic/memccpy.c: Undef function name to enable definition
	as macro.
	* sysdeps/generic/memchr.c: Likewise.
	* sysdeps/generic/memcmp.c: Likewise.
	* sysdeps/generic/memmem.c: Likewise.
	* sysdeps/generic/memmove.c: Likewise.
	* sysdeps/generic/strcat.c: Likewise.
	* sysdeps/generic/strchr.c: Likewise.
	* sysdeps/generic/strcmp.c: Likewise.
	* sysdeps/generic/strcpy.c: Likewise.
	* sysdeps/generic/strcspn.c: Likewise.
	* sysdeps/generic/strlen.c: Likewise.
	* sysdeps/generic/strncat.c: Likewise.
	* sysdeps/generic/strncmp.c: Likewise.
	* sysdeps/generic/strncpy.c: Likewise.
	* sysdeps/generic/strpbrk.c: Likewise.
	* sysdeps/generic/strrchr.c: Likewise.
	* sysdeps/generic/strsep.c: Likewise.
	* sysdeps/generic/strspn.c: Likewise.
	* sysdeps/generic/strstr.c: Likewise.
	* sysdeps/generic/strtok.c: Likewise.
	* sysdeps/generic/strtok_r.c: Likewise.
	* sysdeps/i386/memset.c: Likewise.
	* sysdeps/i386/bits/string.h: Correct a few types and constraints.
	* sysdeps/i386/i486/bits/string.h: Heavy rewrites and optimizations.
	* string/stratcliff.c: Undefine __USE_STRING_INLINES.
	* string/tst-strlen.c: Likewise.
	* string/string.h: Add prototype for mempcpy.  Include bits/string2.h
	header always if optimizing.
	* intl/dcgettext.c: Don't unconditionally define stpcpy, only if not
	yet defined.
	* intl/l10nflist.c: Likewise.

	* string/tester.c: Add copyright and make little cleanups.

	* inet/test_ifindex.c: Change type of ni variable to unsigned int.

	* locale/programs/ld-ctype.c (struct locale_ctype_t): Change type
	of fields map_collection_max and map_collection_act to size_t.

	* nss/libnss_files.map: Group entries.

	* posix/unistd.h: Add prototype for __setpgid and __profil.

	* sysdeps/generic/crypt.h: Declare __crypt_r.

	* sysdeps/i386/bits/select.h: Fix fatal bugs, use correct casts now.

	* sysdeps/i386/fpu/bits/mathinline.h (isgreater, isgreaterequal,
	isless, islessequal, islessgreater, isunordered): Optimize a bit.

	* sysdeps/stub/ftruncate.c: Include missing header for prototype.
	* sysdeps/stub/getdents.c: Likewise.
	* sysdeps/stub/reboot.c: Likewise.
	* sysdeps/stub/swapon.c: Likewise.
	* sysdeps/stub/syscall.c: Likewise.
	* sysdeps/stub/ualarm.c: Likewise.
	* sysdeps/stub/usleep.c: Likewise.

	* sysdeps/unix/sysv/linux/if_index.c: Don't compile or use opensock
	if SIOGIFINDEX and SIOGIFNAME are not defined.

	* sysdeps/unix/sysv/linux/net/if.h: Add IFF_PORTSEL and IFF_AUTOMEDIA
	according to recent kernel changes.

1997-09-10 21:32  Klaus Espenlaub  <kespenla@student.informatik.uni-ulm.de>

	* Makeconfig: Use $(have-initfini) instead of $(elf) to figure out
	the installed name of the startup code.
	(common-generated): Add version.mk.
	* Makefile (distclean-1): Add glibcbug.
	* Makerules: Replace -lgcc by $(gnulib).
	* catgets/Makefile (generated): Add xmalloc.o.
	* csu/Makefile (generated): Replace align.h and end.h by defs.h to
	match the generated file.
	* manual/Makefile (mostlyclean): Add stub-manual and stamp.o.
	(realclean): Changed to remove chapters-incl[12].
	* po/Makefile (realclean): New rule to remove the generated .mo files.
	* time/Makefile: Only include zonefile dependencies if $(no_deps) is
	not true to avoid make clean failure when directory time doesn't exist
	yet.
	(generated): Add tzselect.

	* stdio/fgets.c (fgets): Add casts to reduce gcc warning noise.
	* stdio/internals.c (flushbuf): Likewise.
	* stdio/linewrap.c (lwupdate): Likewise.
	* stdio/memstream.c (enlarge_buffer): Likewise.
	* stdio-common/vfscanf.c (_IO_vfscanf): Likewise.
	* time/tzset.c (compute_change): Likewise.
	* misc/init-misc.c (__init_misc): Only declare static if HAVE_GNU_LD
	is defined.
	* sysdeps/posix/pipestream.c (FUNC): Change to generate ANSI C style
	functions.
	* sysdeps/stub/init-posix.c: Likewise.
	* sysdeps/stub/profil.c: Likewise.
	* munch-tmpl.c (__libc_init): Convert to ANSI C style declaration to
	reduce gcc warning noise.
	* stdio/glue.c (_filbuf, _flsbuf): Likewise.
	* stdio/obstream.c (grow, seek, input, init_obstream): Likewise.
	* stdio/vasprintf.c (enlarge_buffer): Likewise.
	* sysdeps/generic/sysd-stdio.c (__stdio_read, __stdio_write,
	__stdio_seek, __stdio_close, __stdio_fileno, __stdio_open,
	__stdio_reopen): Likewise.
	* sysdeps/posix/defs.c (_cleanup): Likewise.
	* time/offtime.c (__offtime): Add cast.

	* posix/getopt.c: Don't use text_set_element if not defined.

	* configure.in: Provide a check for underscores before user labels
	that works even when the compiler used for building doesn't work
	(like when there is no C library).  Use the old way if the compiler
	works.

1997-09-10 05:08  David S. Miller  <davem@caip.rutgers.edu>

	* sysdeps/unix/sysv/linux/sparc/bits/ioctls.h: The TC* ioctls use
	'T' not 't' on SparcLinux.
	* sysdeps/unix/sysv/linux/sparc/bits/termios.h: tcflag_t is 32 bits.

	* sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S: Add aliases for
	_longjmp and siglongjmp.

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

	* libio/stdio.h: Add format attributes to the extra printf and
	scanf like functions.
	* stdio/stdio.h: Likewise.

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

	* nis/nss_nisplus/nisplus-network.c (_nss_nisplus_getnetbyaddr_r):
	Print tablename_val, not tablename_len.

	* nis/nss_nisplus/nisplus-ethers.c (_nss_nisplus_getntohost_r):
	Use sprintf instead of sprintf, the string always fits.
	* nis/nss_nisplus/nisplus-hosts.c (_nss_nisplus_gethostbyaddr_r):
	Likewise.
	* nis/nss_nisplus/nisplus-network.c (_nss_nisplus_getnetbyaddr_r):
	Likewise.
	* nis/nss_nisplus/nisplus-proto.c
	(_nss_nisplus_getprotobynumber_r): Likewise.
	* nis/nss_nisplus/nisplus-rpc.c (_nss_nisplus_getrpcbynumber_r):
	Likewise.
	* nis/nss_nisplus/nisplus-service.c
	(_nss_nisplus_getservbynumber_r): Likewise.

	* nis/nss_nisplus/nisplus-alias.c (_nss_create_tablename): Use
	__stpcpy, __stpncpy and __strdup instead of public names.
	* nis/nss_nisplus/nisplus-ethers.c (_nss_create_tablename):
	Likewise.
	* nis/nss_nisplus/nisplus-grp.c (_nss_create_tablename): Likewise.
	* nis/nss_nisplus/nisplus-hosts.c (_nss_create_tablename):
	Likewise.
	* nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_parse_netgroup):
	Likewise.
	* nis/nss_nisplus/nisplus-network.c (_nss_nisplus_parse_netent):
	Likewise.
	(_nss_create_tablename): Likewise.
	* nis/nss_nisplus/nisplus-proto.c (_nss_nisplus_parse_protoent):
	Likewise.
	(_nss_create_tablename): Likewise.
	* nis/nss_nisplus/nisplus-pwd.c (_nss_create_tablename):
	Likewise.
	* nis/nss_nisplus/nisplus-rpc.c (_nss_nisplus_parse_rpcent):
	Likewise.
	(_nss_create_tablename): Likewise.
	* nis/nss_nisplus/nisplus-service.c (_nss_nisplus_parse_servent):
	Likewise.
	(_nss_create_tablename): Likewise.
	* nis/nss_nisplus/nisplus-spwd.c (_nss_create_tablename):
	Likewise.

	* libc.map: Export __stpcpy and __strdup.

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

	* math/Makefile (CFLAGS-test-float.c, CFLAGS-test-double.c,
	CFLAGS-test-ldouble.c): Pass -ffloat-store to avoid excessive
	precision.

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

	* include/rpc/auth_des.h: New file.

1997-09-09  Paul Eggert  <eggert@twinsun.com>

	* time/mktime.c (__mktime_internal): Declare sec_requested even if
	!LEAP_SECONDS_POSSIBLE, since it's needed at the end when checking
	for time_t overflow.

1997-09-09 22:11  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/posix/getcwd.c: Correct test for too small buffer.
	Reported by Erik Troan <ewt@redhat.com>.

	* elf/dl-close.c: Include <bits/libc-lock.h>, not <libc-lock.h>.
	* elf/dl-open.c: Likewise.

1997-09-07 17:09  Richard Henderson  <rth@cygnus.com>

	* sysdeps/alpha/Makefile: Kill setjmp_aux.
	* sysdeps/alpha/bits/setjmp.h: Rewrite in terms of an array.
	* sysdeps/alpha/__longjmp.c: Remove.
	* sysdeps/alpha/setjmp_aux.c: Remove.
	* sysdeps/alpha/__longjmp.S: New file.
	* sysdeps/alpha/bsd-_setjmp.S: Stub out.
	* sysdeps/alpha/bsd-setjmp.S: Likewise.
	* sysdeps/alpha/setjmp.S: Do the work; don't call __setjmp_aux.
	Move _setjmp and setjmp from bsd-*.S.

1997-09-06  20:20  Ulrich Drepper  <drepper@cygnus.com>

	* include/rpc/auth.h: New file.
	* include/rpc/auth_unix.h: New file.

1997-09-06  Paul Eggert  <eggert@twinsun.com>

	Fix gmtime so that it reports leap seconds when TZ
	indicates that leap seconds are desired.

	* time/gmtime.c (<stddef.h>): Remove unnecessary include.
	(gmtime): Put after gmtime_r, to help the compiler inline.
	(__tz_convert): New decl.
	(gmtime_r): Use __tz_convert instead of __offtime,
	so that leap seconds are handled correctly.

	* time/localtime.c (<errno.h>, <libc-lock.h>): Remove includes that
	are now unnecessary.
	(__tzset_internal, __tz_compute, __tzfile_compute, __use_tzfile,
	__tzset_lock): Remove extern decls that are now unnecessary.
	(localtime_internal): Moved to __tz_convert in tzset.c.
	so that localtime and gmtime can both use it easily.
	(localtime): Put after localtime_r, to help the compiler inline.
	(localtime_r): Use __tz_convert instead of localtime_internal.

	* time/strftime.c (__tz_compute): Remove unused (and now incorrect)
	decl.

	* time/tzfile.c (__tzfile_compute): New arg USE_LOCALTIME.

	* time/tzset.c (<errno.h>): Include.
	(_tmbuf): New decl.
	(__tzfile_compute): New function.
	(tz_compute): Renamed from __tz_compute.  No longer extern.
	Remove redundant call to tzset_internal.
	(tzset_internal): Renamed from __tzset_internal.  No longer extern.
	(tzset_lock): Renamed from __tzset_lock.  No longer extern.
	(__tz_convert): New function, containing functionality of old
	localtime_internal function, plus locking and optional UTC.

1997-09-06  Paul Eggert  <eggert@twinsun.com>

	* time/tzfile.c (__tzfile_read): Don't read a file if TZ is the empty
	string, just use UTC without leap seconds.  This is for compatibility
	with the Olson code.

1997-09-06  Paul Eggert  <eggert@twinsun.com>

	* time/tzset.c (__tzname_max): Lock tz data structures before
	invoking tzset_internal.

	* time/tzfile.c: Define compute_tzname_max statically.

1997-09-07 10:57  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

	* nis/nis_call.c: Remove not longer necessary HAVE_SECURE_RPC ifdefs.
	* nis/nis_intern.h: Likewise.
	* nis/nss_nis/nis-publickey.c: Likewise.
	* nis/nss_nisplus/nisplus-publickey.c: Likewise.
	* nis/ypclnt.c: Likewise.

	* sunrpc/auth_des.c: Don't dereference NULL pointer,
	initialize ad->ad_timediff.

	* sunrpc/auth_none.c: Don't define our own prototypes, use the one
	from the header files.
	* sunrpc/auth_unix.c: Likewise.
	* sunrpc/clnt_raw.c: Likewise.
	* sunrpc/clnt_tcp.c: Likewise.
	* sunrpc/rpc_cmsg.c: Likewise.

	* sunrpc/key_call.c: Fix signal handling.

	* sunrpc/openchild.c: Don't use /bin/sh to start /usr/etc/keyenvoy,
	or we will get a deadlock with NIS+.

	* sunrpc/rpc/auth.h: Add prototype for xdr_opaque_auth, don't define
	HAVE_SECURE_RPC.

1997-09-07 15:51  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/i386/bits/select.h [__GNUC__] (__FD_ZERO, __FD_SET, __FD_CLR,
	__FD_ISSET): Use correct casts to address array correctly.
	Reported by urbanw@cs.umu.se.

1997-09-07 05:07  Ulrich Drepper  <drepper@cygnus.com>

	* elf/dl-close.c: Include <bits/libc-lock.h>, not <libc-lock.h>.
	* elf/dl-open.c: Likewise.
	* sysdeps/i386/memset.c: Undefine memset in case the header with the
	optimized functions is included.
	Patches by NIIBE Yutaka <gniibe@mri.co.jp>.

	* sysdeps/i386/bits/string.h [__PIC__] (strcspn, strspn, strpbrk,
	strsep): Use register for second parameter.
	* sysdeps/i386/i486/bits/string.h: Likewise.
	Reported by NIIBE Yutaka <gniibe@mri.co.jp>.

1997-09-03 09:48  Geoff Keating  <geoffk@ozemail.com.au>

	* math/libm-test.c: Change various tolerances to match what the
	tested routines can actually provide.

	* math/Makefile: Add new tests.
	* math/atest-sincos.c: New file.
	* math/atest-exp.c: New file.

	* csu/Makefile: Give initfini.s and initfiniS.s their own
	CFLAGS-* macros so they can be overridden.
	* sysdeps/powerpc/Makefile [subdir=csu]: Override flags for
	initfiniS.s to use -fpic instead of -fPIC, because the sed script
	breaks otherwise.

	* sysdeps/powerpc/Makefile [build-shared]: Use -fpic not -fPIC for
	efficiency.

	* sysdeps/powerpc/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE):
	Don't use register 0, to let _mcount be in a shared object.

	* sysdeps/powerpc/dl-machine.h: Use full sentences in comments.
	Generally clean up.  Suppress some code we don't need when relocating
	ld.so.
	* sysdeps/powerpc/test-arith.c: Change loop indices to size_t when
	appropriate to suppress gcc warning.
	* resolv/res_send.c: Suppress warning.
	* sunrpc/xdr_sizeof.c: Suppress warning.

	* FAQ: Add ppc-linux.
	* manual/maint.texi: Add ppc-linux.  Explain that gcc can't build it
	yet.

	* sysdeps/unix/sysv/linux/powerpc/profil-counter.h: Correct for
	current kernels.

1997-08-15 07:45  Geoff Keating  <geoffk@ozemail.com.au>

	* stdlib/fmtmsg.c: Use two parameters for __libc_once_define.
	* sysdeps/i386/machine-gmon.h: Correct typo.

	* sysdeps/unix/sysv/linux/powerpc/bits/mman.h: Change to match
	kernel.

	* sysdeps/generic/dl-sysdep.c: Add hook for bizzare PPC argument hack.
	* sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c: Rewrite to use
	sysdeps/linux/dl-sysdep.c.

	* sysdeps/powerpc/Makefile [subdir=gmon]: Compile ppc-mcount.
	* sysdeps/powerpc/machine-gmon.h: Use ppc-mcount.
	* sysdeps/powerpc/ppc-mcount: New file.

	The following are mostly changes to allow profiling:
	* sysdeps/powerpc/add_n.S: Added.
	* sysdeps/powerpc/add_n.s: Removed.
	* sysdeps/powerpc/addmul_1.S: Added.
	* sysdeps/powerpc/addmul_1.s: Removed.
	* sysdeps/powerpc/bsd-_setjmp.S: Use JUMPTARGET macro.
	* sysdeps/powerpc/bsd-setjmp.S: Use JUMPTARGET macro.
	* sysdeps/powerpc/lshift.S: Added.
	* sysdeps/powerpc/lshift.s: Removed.
	* sysdeps/powerpc/memset.S: Added.
	* sysdeps/powerpc/memset.s: Removed.
	* sysdeps/powerpc/mul_1.S: Added.
	* sysdeps/powerpc/mul_1.s: Removed.
	* sysdeps/powerpc/rshift.S: Added.
	* sysdeps/powerpc/rshift.s: Removed.
	* sysdeps/powerpc/s_copysign.S: Use ENTRY, END, weak_alias macros.
	* sysdeps/powerpc/s_fabs.S: Use ENTRY, END, weak_alias macros.
	* sysdeps/powerpc/setjmp.S: Use JUMPTARGET macro.
	* sysdeps/powerpc/strchr.S: Added.
	* sysdeps/powerpc/strchr.s: Removed.
	* sysdeps/powerpc/strcmp.S: Added.
	* sysdeps/powerpc/strcmp.s: Removed.
	* sysdeps/powerpc/strlen.S: Added.
	* sysdeps/powerpc/strlen.s: Removed.
	* sysdeps/powerpc/sub_n.S: Added.
	* sysdeps/powerpc/sub_n.s: Removed.
	* sysdeps/powerpc/submul_1.S: Added.
	* sysdeps/powerpc/submul_1.s: Removed.
	* sysdeps/unix/sysv/linux/powerpc/_exit.S: Removed.
	* sysdeps/unix/sysv/linux/powerpc/brk.S: Added.
	* sysdeps/unix/sysv/linux/powerpc/brk.c: Removed.
	* sysdeps/unix/sysv/linux/powerpc/clone.S: Use new macros. Fix
	various bugs. Document that it isn't tested.
	* sysdeps/unix/sysv/linux/powerpc/sigreturn.S: Make look like
	sysdeps/unix/_exit.S.
	* sysdeps/unix/sysv/linux/powerpc/socket.S: Use new macros.
	* sysdeps/unix/sysv/linux/powerpc/syscall.S: Use new macros.
	* sysdeps/unix/sysv/linux/powerpc/sysdep.h: Define some new macros
	to make assembler (possibly) more portable, allow profiling, etc.
-rw-r--r--BUGS6
-rw-r--r--ChangeLog430
-rw-r--r--FAQ4
-rw-r--r--Makeconfig14
-rw-r--r--Makefile1
-rw-r--r--Makerules4
-rw-r--r--catgets/Makefile4
-rwxr-xr-xconfig.guess61
-rwxr-xr-xconfig.sub15
-rwxr-xr-xconfigure62
-rw-r--r--configure.in40
-rw-r--r--csu/Makefile6
-rw-r--r--db2/README3
-rw-r--r--db2/btree/bt_rec.c4
-rw-r--r--db2/clib/getlong.c3
-rw-r--r--db2/db185/db185.c67
-rw-r--r--db2/db185/db185_int.h1
-rw-r--r--db2/db_int.h6
-rw-r--r--db2/dbm/dbm.c12
-rw-r--r--db2/lock/lock_deadlock.c6
-rw-r--r--db2/log/log_archive.c2
-rw-r--r--elf/dl-close.c2
-rw-r--r--elf/dl-open.c2
-rw-r--r--elf/dl-profile.c167
-rw-r--r--gmon/gmon.c6
-rw-r--r--gmon/mcount.c32
-rw-r--r--gmon/sys/gmon.h2
-rw-r--r--include/bits/string2.h1
-rw-r--r--include/rpc/auth.h1
-rw-r--r--include/rpc/auth_des.h1
-rw-r--r--include/rpc/key_prot.h1
-rw-r--r--inet/test_ifindex.c3
-rw-r--r--intl/dcgettext.c4
-rw-r--r--intl/l10nflist.c4
-rw-r--r--libc.map2
-rw-r--r--libio/stdio.h42
-rw-r--r--locale/programs/ld-ctype.c4
-rw-r--r--manual/Makefile5
-rw-r--r--manual/maint.texi12
-rw-r--r--math/Makefile11
-rw-r--r--math/atest-exp.c191
-rw-r--r--math/atest-sincos.c275
-rw-r--r--math/libm-test.c14
-rw-r--r--misc/init-misc.c10
-rw-r--r--munch-tmpl.c5
-rw-r--r--nis/nis_call.c2
-rw-r--r--nis/nis_intern.h2
-rw-r--r--nis/nss_nis/nis-publickey.c8
-rw-r--r--nis/nss_nisplus/nisplus-alias.c6
-rw-r--r--nis/nss_nisplus/nisplus-ethers.c14
-rw-r--r--nis/nss_nisplus/nisplus-grp.c6
-rw-r--r--nis/nss_nisplus/nisplus-hosts.c16
-rw-r--r--nis/nss_nisplus/nisplus-netgrp.c12
-rw-r--r--nis/nss_nisplus/nisplus-network.c13
-rw-r--r--nis/nss_nisplus/nisplus-proto.c12
-rw-r--r--nis/nss_nisplus/nisplus-publickey.c6
-rw-r--r--nis/nss_nisplus/nisplus-pwd.c6
-rw-r--r--nis/nss_nisplus/nisplus-rpc.c12
-rw-r--r--nis/nss_nisplus/nisplus-service.c14
-rw-r--r--nis/nss_nisplus/nisplus-spwd.c6
-rw-r--r--nis/ypclnt.c7
-rw-r--r--nss/libnss_files.map90
-rw-r--r--po/Makefile3
-rw-r--r--posix/getopt.c4
-rw-r--r--posix/unistd.h3
-rw-r--r--resolv/res_send.c2
-rw-r--r--stdio/fgets.c4
-rw-r--r--stdio/glue.c7
-rw-r--r--stdio/internals.c4
-rw-r--r--stdio/linewrap.c2
-rw-r--r--stdio/memstream.c2
-rw-r--r--stdio/obstream.c18
-rw-r--r--stdio/stdio.h28
-rw-r--r--stdio/vasprintf.c4
-rw-r--r--string/Makefile14
-rw-r--r--string/bits/string2.h292
-rw-r--r--string/inl-tester.c6
-rw-r--r--string/stratcliff.c5
-rw-r--r--string/string.h44
-rw-r--r--string/tester.c30
-rw-r--r--string/tst-strlen.c4
-rw-r--r--sunrpc/auth_des.c15
-rw-r--r--sunrpc/auth_none.c2
-rw-r--r--sunrpc/auth_unix.c2
-rw-r--r--sunrpc/clnt_raw.c2
-rw-r--r--sunrpc/clnt_tcp.c2
-rw-r--r--sunrpc/key_call.c79
-rw-r--r--sunrpc/openchild.c17
-rw-r--r--sunrpc/rpc/auth.h16
-rw-r--r--sunrpc/rpc_cmsg.c2
-rw-r--r--sysdeps/alpha/Makefile6
-rw-r--r--sysdeps/alpha/__longjmp.S59
-rw-r--r--sysdeps/alpha/__longjmp.c92
-rw-r--r--sysdeps/alpha/bits/setjmp.h79
-rw-r--r--sysdeps/alpha/bsd-_setjmp.S40
-rw-r--r--sysdeps/alpha/bsd-setjmp.S38
-rw-r--r--sysdeps/alpha/setjmp.S68
-rw-r--r--sysdeps/alpha/setjmp_aux.c76
-rw-r--r--sysdeps/generic/crypt.h2
-rw-r--r--sysdeps/generic/memccpy.c11
-rw-r--r--sysdeps/generic/memchr.c5
-rw-r--r--sysdeps/generic/memcmp.c2
-rw-r--r--sysdeps/generic/memmem.c1
-rw-r--r--sysdeps/generic/memmove.c2
-rw-r--r--sysdeps/generic/mempcpy.c66
-rw-r--r--sysdeps/generic/strcat.c2
-rw-r--r--sysdeps/generic/strchr.c2
-rw-r--r--sysdeps/generic/strcmp.c4
-rw-r--r--sysdeps/generic/strcpy.c2
-rw-r--r--sysdeps/generic/strcspn.c2
-rw-r--r--sysdeps/generic/strlen.c2
-rw-r--r--sysdeps/generic/strncat.c2
-rw-r--r--sysdeps/generic/strncmp.c4
-rw-r--r--sysdeps/generic/strncpy.c1
-rw-r--r--sysdeps/generic/strpbrk.c2
-rw-r--r--sysdeps/generic/strrchr.c4
-rw-r--r--sysdeps/generic/strsep.c2
-rw-r--r--sysdeps/generic/strspn.c1
-rw-r--r--sysdeps/generic/strstr.c2
-rw-r--r--sysdeps/generic/strtok.c2
-rw-r--r--sysdeps/generic/strtok_r.c1
-rw-r--r--sysdeps/generic/sysd-stdio.c33
-rw-r--r--sysdeps/i386/bits/select.h15
-rw-r--r--sysdeps/i386/bits/string.h17
-rw-r--r--sysdeps/i386/fpu/bits/mathinline.h21
-rw-r--r--sysdeps/i386/i486/atomicity.h57
-rw-r--r--sysdeps/i386/i486/bits/string.h850
-rw-r--r--sysdeps/i386/machine-gmon.h4
-rw-r--r--sysdeps/i386/memset.c2
-rw-r--r--sysdeps/mach/hurd/profil.c3
-rw-r--r--sysdeps/posix/defs.c2
-rw-r--r--sysdeps/posix/getcwd.c2
-rw-r--r--sysdeps/posix/pipestream.c20
-rw-r--r--sysdeps/posix/profil.c3
-rw-r--r--sysdeps/posix/sleep.c3
-rw-r--r--sysdeps/posix/stdio_init.c3
-rw-r--r--sysdeps/powerpc/Makefile18
-rw-r--r--sysdeps/powerpc/add_n.S68
-rw-r--r--sysdeps/powerpc/add_n.s68
-rw-r--r--sysdeps/powerpc/addmul_1.S49
-rw-r--r--sysdeps/powerpc/addmul_1.s50
-rw-r--r--sysdeps/powerpc/bsd-_setjmp.S6
-rw-r--r--sysdeps/powerpc/bsd-setjmp.S6
-rw-r--r--sysdeps/powerpc/dl-machine.h152
-rw-r--r--sysdeps/powerpc/lshift.S123
-rw-r--r--sysdeps/powerpc/lshift.s479
-rw-r--r--sysdeps/powerpc/machine-gmon.h (renamed from sysdeps/unix/sysv/linux/powerpc/_exit.S)20
-rw-r--r--sysdeps/powerpc/memset.S199
-rw-r--r--sysdeps/powerpc/memset.s202
-rw-r--r--sysdeps/powerpc/mul_1.S46
-rw-r--r--sysdeps/powerpc/mul_1.s47
-rw-r--r--sysdeps/powerpc/ppc-mcount.S84
-rw-r--r--sysdeps/powerpc/rshift.S56
-rw-r--r--sysdeps/powerpc/rshift.s59
-rw-r--r--sysdeps/powerpc/s_copysign.S40
-rw-r--r--sysdeps/powerpc/s_fabs.S33
-rw-r--r--sysdeps/powerpc/setjmp.S6
-rw-r--r--sysdeps/powerpc/strchr.S111
-rw-r--r--sysdeps/powerpc/strchr.s118
-rw-r--r--sysdeps/powerpc/strcmp.S115
-rw-r--r--sysdeps/powerpc/strcmp.s273
-rw-r--r--sysdeps/powerpc/strlen.S144
-rw-r--r--sysdeps/powerpc/strlen.s144
-rw-r--r--sysdeps/powerpc/sub_n.S68
-rw-r--r--sysdeps/powerpc/sub_n.s69
-rw-r--r--sysdeps/powerpc/submul_1.S52
-rw-r--r--sysdeps/powerpc/submul_1.s52
-rw-r--r--sysdeps/powerpc/test-arith.c15
-rw-r--r--sysdeps/stub/atomicity.h53
-rw-r--r--sysdeps/stub/ftruncate.c1
-rw-r--r--sysdeps/stub/getdents.c1
-rw-r--r--sysdeps/stub/init-posix.c2
-rw-r--r--sysdeps/stub/profil.c3
-rw-r--r--sysdeps/stub/reboot.c1
-rw-r--r--sysdeps/stub/swapon.c1
-rw-r--r--sysdeps/stub/syscall.c1
-rw-r--r--sysdeps/stub/ualarm.c1
-rw-r--r--sysdeps/stub/usleep.c1
-rw-r--r--sysdeps/unix/sysv/linux/if_index.c2
-rw-r--r--sysdeps/unix/sysv/linux/net/if.h5
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/mman.h26
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/brk.S (renamed from sysdeps/unix/sysv/linux/powerpc/brk.c)52
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/clone.S29
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/profil-counter.h14
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sigreturn.S9
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/socket.S14
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/syscall.S8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sysdep.h111
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/ioctls.h8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/termios.h10
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S2
-rw-r--r--sysdeps/vax/strcmp.s85
-rw-r--r--time/Makefile3
-rw-r--r--time/README4
-rw-r--r--time/gmtime.c29
-rw-r--r--time/localtime.c99
-rw-r--r--time/mktime.c2
-rw-r--r--time/offtime.c6
-rw-r--r--time/strftime.c1
-rw-r--r--time/tzfile.c30
-rw-r--r--time/tzset.c109
201 files changed, 4818 insertions, 2887 deletions
diff --git a/BUGS b/BUGS
index 3d449f362d..520311f9f4 100644
--- a/BUGS
+++ b/BUGS
@@ -1,7 +1,7 @@
 	    List of known bugs (certainly very incomplete)
 	    ----------------------------------------------
 
-Time-stamp: <1997-08-04T00:50:04+0200 drepper>
+Time-stamp: <1997-09-06T18:30:16+0200 drepper>
 
 This following list contains those bugs which I'm aware of.  Please
 make sure that bugs you report are not listed here.  If you can fix one
@@ -25,6 +25,10 @@ Severity: [  *] to [***]
 
 [ **]  There are problems with signal handling when using LinuxThreads.
 
+[ **]  The libm-ieee `log2' function seems to be very inaccurate.
+
+[  *]  The libm-ieee `remquo' function rounds 3.0/2.0 incorrectly.
+
 [  *]  The precision of the `sinhl' and/or `asinhl' function do not seem
        to be the best.
 
diff --git a/ChangeLog b/ChangeLog
index 663b4e2e6e..a8b57bbeca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,433 @@
+1997-09-11 04:36  Ulrich Drepper  <drepper@cygnus.com>
+
+	* db2/db_int.h: Define __set_errno if not yet available.
+	* db2/btree/bt_rec.c: Use __set_errno to set errno value.
+	* db2/clib/getlong.c: Likewise.
+	* db2/db185/db185.c: Likewise.
+	* db2/db185/db185_int.h: Likewise.
+	* db2/dbm/dbm.c: Likewise.
+	* db2/lock/lock_deadlock.c: Likewise.
+	* db2/log/log_archive.c: Likewise.
+
+	* elf/dl-profile.c: Implement mcount function.
+
+	* gmon/gmon.c: Use __profil not profil because of namespace pollution.
+	* gmon/mcount.c: Remove BSD kernel code.
+	Use compare&swap instruction if possible to change state variable.
+	Optimize frompc folding.
+	* gmon/sys/gmon.h (struct gmonparam): Change state field to long int.
+	* sysdeps/i386/i486/atomicity.h: New file.
+	* sysdeps/stub/atomicity.h: New file.
+	* sysdeps/mach/hurd/profil.c: Define function as __profil and make
+	profil weak alias.
+	* sysdeps/posix/profil.c: Likewise.
+
+	* string/bits/string2.h: New file.
+	* include/bits/string2.h: New file.
+	* string/Makefile (routines): Add mempcpy.
+	(tests): Add inl-tester.
+	Remove _D__NO_STRING_INLINES from CFLAGS-* variables.
+	* sysdeps/generic/mempcpy.c: New file.
+	* sysdeps/generic/memccpy.c: Undef function name to enable definition
+	as macro.
+	* sysdeps/generic/memchr.c: Likewise.
+	* sysdeps/generic/memcmp.c: Likewise.
+	* sysdeps/generic/memmem.c: Likewise.
+	* sysdeps/generic/memmove.c: Likewise.
+	* sysdeps/generic/strcat.c: Likewise.
+	* sysdeps/generic/strchr.c: Likewise.
+	* sysdeps/generic/strcmp.c: Likewise.
+	* sysdeps/generic/strcpy.c: Likewise.
+	* sysdeps/generic/strcspn.c: Likewise.
+	* sysdeps/generic/strlen.c: Likewise.
+	* sysdeps/generic/strncat.c: Likewise.
+	* sysdeps/generic/strncmp.c: Likewise.
+	* sysdeps/generic/strncpy.c: Likewise.
+	* sysdeps/generic/strpbrk.c: Likewise.
+	* sysdeps/generic/strrchr.c: Likewise.
+	* sysdeps/generic/strsep.c: Likewise.
+	* sysdeps/generic/strspn.c: Likewise.
+	* sysdeps/generic/strstr.c: Likewise.
+	* sysdeps/generic/strtok.c: Likewise.
+	* sysdeps/generic/strtok_r.c: Likewise.
+	* sysdeps/i386/memset.c: Likewise.
+	* sysdeps/i386/bits/string.h: Correct a few types and constraints.
+	* sysdeps/i386/i486/bits/string.h: Heavy rewrites and optimizations.
+	* string/stratcliff.c: Undefine __USE_STRING_INLINES.
+	* string/tst-strlen.c: Likewise.
+	* string/string.h: Add prototype for mempcpy.  Include bits/string2.h
+	header always if optimizing.
+	* intl/dcgettext.c: Don't unconditionally define stpcpy, only if not
+	yet defined.
+	* intl/l10nflist.c: Likewise.
+
+	* string/tester.c: Add copyright and make little cleanups.
+
+	* inet/test_ifindex.c: Change type of ni variable to unsigned int.
+
+	* locale/programs/ld-ctype.c (struct locale_ctype_t): Change type
+	of fields map_collection_max and map_collection_act to size_t.
+
+	* nss/libnss_files.map: Group entries.
+
+	* posix/unistd.h: Add prototype for __setpgid and __profil.
+
+	* sysdeps/generic/crypt.h: Declare __crypt_r.
+
+	* sysdeps/i386/bits/select.h: Fix fatal bugs, use correct casts now.
+
+	* sysdeps/i386/fpu/bits/mathinline.h (isgreater, isgreaterequal,
+	isless, islessequal, islessgreater, isunordered): Optimize a bit.
+
+	* sysdeps/stub/ftruncate.c: Include missing header for prototype.
+	* sysdeps/stub/getdents.c: Likewise.
+	* sysdeps/stub/reboot.c: Likewise.
+	* sysdeps/stub/swapon.c: Likewise.
+	* sysdeps/stub/syscall.c: Likewise.
+	* sysdeps/stub/ualarm.c: Likewise.
+	* sysdeps/stub/usleep.c: Likewise.
+
+	* sysdeps/unix/sysv/linux/if_index.c: Don't compile or use opensock
+	if SIOGIFINDEX and SIOGIFNAME are not defined.
+
+	* sysdeps/unix/sysv/linux/net/if.h: Add IFF_PORTSEL and IFF_AUTOMEDIA
+	according to recent kernel changes.
+
+1997-09-10 21:32  Klaus Espenlaub  <kespenla@student.informatik.uni-ulm.de>
+
+	* Makeconfig: Use $(have-initfini) instead of $(elf) to figure out
+	the installed name of the startup code.
+	(common-generated): Add version.mk.
+	* Makefile (distclean-1): Add glibcbug.
+	* Makerules: Replace -lgcc by $(gnulib).
+	* catgets/Makefile (generated): Add xmalloc.o.
+	* csu/Makefile (generated): Replace align.h and end.h by defs.h to
+	match the generated file.
+	* manual/Makefile (mostlyclean): Add stub-manual and stamp.o.
+	(realclean): Changed to remove chapters-incl[12].
+	* po/Makefile (realclean): New rule to remove the generated .mo files.
+	* time/Makefile: Only include zonefile dependencies if $(no_deps) is
+	not true to avoid make clean failure when directory time doesn't exist
+	yet.
+	(generated): Add tzselect.
+
+	* stdio/fgets.c (fgets): Add casts to reduce gcc warning noise.
+	* stdio/internals.c (flushbuf): Likewise.
+	* stdio/linewrap.c (lwupdate): Likewise.
+	* stdio/memstream.c (enlarge_buffer): Likewise.
+	* stdio-common/vfscanf.c (_IO_vfscanf): Likewise.
+	* time/tzset.c (compute_change): Likewise.
+	* misc/init-misc.c (__init_misc): Only declare static if HAVE_GNU_LD
+	is defined.
+	* sysdeps/posix/pipestream.c (FUNC): Change to generate ANSI C style
+	functions.
+	* sysdeps/stub/init-posix.c: Likewise.
+	* sysdeps/stub/profil.c: Likewise.
+	* munch-tmpl.c (__libc_init): Convert to ANSI C style declaration to
+	reduce gcc warning noise.
+	* stdio/glue.c (_filbuf, _flsbuf): Likewise.
+	* stdio/obstream.c (grow, seek, input, init_obstream): Likewise.
+	* stdio/vasprintf.c (enlarge_buffer): Likewise.
+	* sysdeps/generic/sysd-stdio.c (__stdio_read, __stdio_write,
+	__stdio_seek, __stdio_close, __stdio_fileno, __stdio_open,
+	__stdio_reopen): Likewise.
+	* sysdeps/posix/defs.c (_cleanup): Likewise.
+	* time/offtime.c (__offtime): Add cast.
+
+	* posix/getopt.c: Don't use text_set_element if not defined.
+
+	* configure.in: Provide a check for underscores before user labels
+	that works even when the compiler used for building doesn't work
+	(like when there is no C library).  Use the old way if the compiler
+	works.
+
+1997-09-10 05:08  David S. Miller  <davem@caip.rutgers.edu>
+
+	* sysdeps/unix/sysv/linux/sparc/bits/ioctls.h: The TC* ioctls use
+	'T' not 't' on SparcLinux.
+	* sysdeps/unix/sysv/linux/sparc/bits/termios.h: tcflag_t is 32 bits.
+
+	* sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S: Add aliases for
+	_longjmp and siglongjmp.
+
+1997-09-09  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* libio/stdio.h: Add format attributes to the extra printf and
+	scanf like functions.
+	* stdio/stdio.h: Likewise.
+
+1997-09-09  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* nis/nss_nisplus/nisplus-network.c (_nss_nisplus_getnetbyaddr_r):
+	Print tablename_val, not tablename_len.
+
+	* nis/nss_nisplus/nisplus-ethers.c (_nss_nisplus_getntohost_r):
+	Use sprintf instead of sprintf, the string always fits.
+	* nis/nss_nisplus/nisplus-hosts.c (_nss_nisplus_gethostbyaddr_r):
+	Likewise.
+	* nis/nss_nisplus/nisplus-network.c (_nss_nisplus_getnetbyaddr_r):
+	Likewise.
+	* nis/nss_nisplus/nisplus-proto.c
+	(_nss_nisplus_getprotobynumber_r): Likewise.
+	* nis/nss_nisplus/nisplus-rpc.c (_nss_nisplus_getrpcbynumber_r):
+	Likewise.
+	* nis/nss_nisplus/nisplus-service.c
+	(_nss_nisplus_getservbynumber_r): Likewise.
+
+	* nis/nss_nisplus/nisplus-alias.c (_nss_create_tablename): Use
+	__stpcpy, __stpncpy and __strdup instead of public names.
+	* nis/nss_nisplus/nisplus-ethers.c (_nss_create_tablename):
+	Likewise.
+	* nis/nss_nisplus/nisplus-grp.c (_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-hosts.c (_nss_create_tablename):
+	Likewise.
+	* nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_parse_netgroup):
+	Likewise.
+	* nis/nss_nisplus/nisplus-network.c (_nss_nisplus_parse_netent):
+	Likewise.
+	(_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-proto.c (_nss_nisplus_parse_protoent):
+	Likewise.
+	(_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-pwd.c (_nss_create_tablename):
+	Likewise.
+	* nis/nss_nisplus/nisplus-rpc.c (_nss_nisplus_parse_rpcent):
+	Likewise.
+	(_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-service.c (_nss_nisplus_parse_servent):
+	Likewise.
+	(_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-spwd.c (_nss_create_tablename):
+	Likewise.
+
+	* libc.map: Export __stpcpy and __strdup.
+
+1997-09-09  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* math/Makefile (CFLAGS-test-float.c, CFLAGS-test-double.c,
+	CFLAGS-test-ldouble.c): Pass -ffloat-store to avoid excessive
+	precision.
+
+1997-09-09  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* include/rpc/auth_des.h: New file.
+
+1997-09-09  Paul Eggert  <eggert@twinsun.com>
+
+	* time/mktime.c (__mktime_internal): Declare sec_requested even if
+	!LEAP_SECONDS_POSSIBLE, since it's needed at the end when checking
+	for time_t overflow.
+
+1997-09-09 22:11  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sysdeps/posix/getcwd.c: Correct test for too small buffer.
+	Reported by Erik Troan <ewt@redhat.com>.
+
+	* elf/dl-close.c: Include <bits/libc-lock.h>, not <libc-lock.h>.
+	* elf/dl-open.c: Likewise.
+
+1997-09-07 17:09  Richard Henderson  <rth@cygnus.com>
+
+	* sysdeps/alpha/Makefile: Kill setjmp_aux.
+	* sysdeps/alpha/bits/setjmp.h: Rewrite in terms of an array.
+	* sysdeps/alpha/__longjmp.c: Remove.
+	* sysdeps/alpha/setjmp_aux.c: Remove.
+	* sysdeps/alpha/__longjmp.S: New file.
+	* sysdeps/alpha/bsd-_setjmp.S: Stub out.
+	* sysdeps/alpha/bsd-setjmp.S: Likewise.
+	* sysdeps/alpha/setjmp.S: Do the work; don't call __setjmp_aux.
+	Move _setjmp and setjmp from bsd-*.S.
+
+1997-09-06  20:20  Ulrich Drepper  <drepper@cygnus.com>
+
+	* include/rpc/auth.h: New file.
+	* include/rpc/auth_unix.h: New file.
+
+1997-09-06  Paul Eggert  <eggert@twinsun.com>
+
+	Fix gmtime so that it reports leap seconds when TZ
+	indicates that leap seconds are desired.
+
+	* time/gmtime.c (<stddef.h>): Remove unnecessary include.
+	(gmtime): Put after gmtime_r, to help the compiler inline.
+	(__tz_convert): New decl.
+	(gmtime_r): Use __tz_convert instead of __offtime,
+	so that leap seconds are handled correctly.
+
+	* time/localtime.c (<errno.h>, <libc-lock.h>): Remove includes that
+	are now unnecessary.
+	(__tzset_internal, __tz_compute, __tzfile_compute, __use_tzfile,
+	__tzset_lock): Remove extern decls that are now unnecessary.
+	(localtime_internal): Moved to __tz_convert in tzset.c.
+	so that localtime and gmtime can both use it easily.
+	(localtime): Put after localtime_r, to help the compiler inline.
+	(localtime_r): Use __tz_convert instead of localtime_internal.
+
+	* time/strftime.c (__tz_compute): Remove unused (and now incorrect)
+	decl.
+
+	* time/tzfile.c (__tzfile_compute): New arg USE_LOCALTIME.
+
+	* time/tzset.c (<errno.h>): Include.
+	(_tmbuf): New decl.
+	(__tzfile_compute): New function.
+	(tz_compute): Renamed from __tz_compute.  No longer extern.
+	Remove redundant call to tzset_internal.
+	(tzset_internal): Renamed from __tzset_internal.  No longer extern.
+	(tzset_lock): Renamed from __tzset_lock.  No longer extern.
+	(__tz_convert): New function, containing functionality of old
+	localtime_internal function, plus locking and optional UTC.
+
+1997-09-06  Paul Eggert  <eggert@twinsun.com>
+
+	* time/tzfile.c (__tzfile_read): Don't read a file if TZ is the empty
+	string, just use UTC without leap seconds.  This is for compatibility
+	with the Olson code.
+
+1997-09-06  Paul Eggert  <eggert@twinsun.com>
+
+	* time/tzset.c (__tzname_max): Lock tz data structures before
+	invoking tzset_internal.
+
+	* time/tzfile.c: Define compute_tzname_max statically.
+
+1997-09-07 10:57  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+	* nis/nis_call.c: Remove not longer necessary HAVE_SECURE_RPC ifdefs.
+	* nis/nis_intern.h: Likewise.
+	* nis/nss_nis/nis-publickey.c: Likewise.
+	* nis/nss_nisplus/nisplus-publickey.c: Likewise.
+	* nis/ypclnt.c: Likewise.
+
+	* sunrpc/auth_des.c: Don't dereference NULL pointer,
+	initialize ad->ad_timediff.
+
+	* sunrpc/auth_none.c: Don't define our own prototypes, use the one
+	from the header files.
+	* sunrpc/auth_unix.c: Likewise.
+	* sunrpc/clnt_raw.c: Likewise.
+	* sunrpc/clnt_tcp.c: Likewise.
+	* sunrpc/rpc_cmsg.c: Likewise.
+
+	* sunrpc/key_call.c: Fix signal handling.
+
+	* sunrpc/openchild.c: Don't use /bin/sh to start /usr/etc/keyenvoy,
+	or we will get a deadlock with NIS+.
+
+	* sunrpc/rpc/auth.h: Add prototype for xdr_opaque_auth, don't define
+	HAVE_SECURE_RPC.
+
+1997-09-07 15:51  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sysdeps/i386/bits/select.h [__GNUC__] (__FD_ZERO, __FD_SET, __FD_CLR,
+	__FD_ISSET): Use correct casts to address array correctly.
+	Reported by urbanw@cs.umu.se.
+
+1997-09-07 05:07  Ulrich Drepper  <drepper@cygnus.com>
+
+	* elf/dl-close.c: Include <bits/libc-lock.h>, not <libc-lock.h>.
+	* elf/dl-open.c: Likewise.
+	* sysdeps/i386/memset.c: Undefine memset in case the header with the
+	optimized functions is included.
+	Patches by NIIBE Yutaka <gniibe@mri.co.jp>.
+
+	* sysdeps/i386/bits/string.h [__PIC__] (strcspn, strspn, strpbrk,
+	strsep): Use register for second parameter.
+	* sysdeps/i386/i486/bits/string.h: Likewise.
+	Reported by NIIBE Yutaka <gniibe@mri.co.jp>.
+
+1997-09-03 09:48  Geoff Keating  <geoffk@ozemail.com.au>
+
+	* math/libm-test.c: Change various tolerances to match what the
+	tested routines can actually provide.
+
+	* math/Makefile: Add new tests.
+	* math/atest-sincos.c: New file.
+	* math/atest-exp.c: New file.
+
+	* csu/Makefile: Give initfini.s and initfiniS.s their own
+	CFLAGS-* macros so they can be overridden.
+	* sysdeps/powerpc/Makefile [subdir=csu]: Override flags for
+	initfiniS.s to use -fpic instead of -fPIC, because the sed script
+	breaks otherwise.
+
+	* sysdeps/powerpc/Makefile [build-shared]: Use -fpic not -fPIC for
+	efficiency.
+
+	* sysdeps/powerpc/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE):
+	Don't use register 0, to let _mcount be in a shared object.
+
+	* sysdeps/powerpc/dl-machine.h: Use full sentences in comments.
+	Generally clean up.  Suppress some code we don't need when relocating
+	ld.so.
+	* sysdeps/powerpc/test-arith.c: Change loop indices to size_t when
+	appropriate to suppress gcc warning.
+	* resolv/res_send.c: Suppress warning.
+	* sunrpc/xdr_sizeof.c: Suppress warning.
+
+	* FAQ: Add ppc-linux.
+	* manual/maint.texi: Add ppc-linux.  Explain that gcc can't build it
+	yet.
+
+	* sysdeps/unix/sysv/linux/powerpc/profil-counter.h: Correct for
+	current kernels.
+
+1997-08-15 07:45  Geoff Keating  <geoffk@ozemail.com.au>
+
+	* stdlib/fmtmsg.c: Use two parameters for __libc_once_define.
+	* sysdeps/i386/machine-gmon.h: Correct typo.
+
+	* sysdeps/unix/sysv/linux/powerpc/bits/mman.h: Change to match
+	kernel.
+
+	* sysdeps/generic/dl-sysdep.c: Add hook for bizzare PPC argument hack.
+	* sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c: Rewrite to use
+	sysdeps/linux/dl-sysdep.c.
+
+	* sysdeps/powerpc/Makefile [subdir=gmon]: Compile ppc-mcount.
+	* sysdeps/powerpc/machine-gmon.h: Use ppc-mcount.
+	* sysdeps/powerpc/ppc-mcount: New file.
+
+	The following are mostly changes to allow profiling:
+	* sysdeps/powerpc/add_n.S: Added.
+	* sysdeps/powerpc/add_n.s: Removed.
+	* sysdeps/powerpc/addmul_1.S: Added.
+	* sysdeps/powerpc/addmul_1.s: Removed.
+	* sysdeps/powerpc/bsd-_setjmp.S: Use JUMPTARGET macro.
+	* sysdeps/powerpc/bsd-setjmp.S: Use JUMPTARGET macro.
+	* sysdeps/powerpc/lshift.S: Added.
+	* sysdeps/powerpc/lshift.s: Removed.
+	* sysdeps/powerpc/memset.S: Added.
+	* sysdeps/powerpc/memset.s: Removed.
+	* sysdeps/powerpc/mul_1.S: Added.
+	* sysdeps/powerpc/mul_1.s: Removed.
+	* sysdeps/powerpc/rshift.S: Added.
+	* sysdeps/powerpc/rshift.s: Removed.
+	* sysdeps/powerpc/s_copysign.S: Use ENTRY, END, weak_alias macros.
+	* sysdeps/powerpc/s_fabs.S: Use ENTRY, END, weak_alias macros.
+	* sysdeps/powerpc/setjmp.S: Use JUMPTARGET macro.
+	* sysdeps/powerpc/strchr.S: Added.
+	* sysdeps/powerpc/strchr.s: Removed.
+	* sysdeps/powerpc/strcmp.S: Added.
+	* sysdeps/powerpc/strcmp.s: Removed.
+	* sysdeps/powerpc/strlen.S: Added.
+	* sysdeps/powerpc/strlen.s: Removed.
+	* sysdeps/powerpc/sub_n.S: Added.
+	* sysdeps/powerpc/sub_n.s: Removed.
+	* sysdeps/powerpc/submul_1.S: Added.
+	* sysdeps/powerpc/submul_1.s: Removed.
+	* sysdeps/unix/sysv/linux/powerpc/_exit.S: Removed.
+	* sysdeps/unix/sysv/linux/powerpc/brk.S: Added.
+	* sysdeps/unix/sysv/linux/powerpc/brk.c: Removed.
+	* sysdeps/unix/sysv/linux/powerpc/clone.S: Use new macros. Fix
+	various bugs. Document that it isn't tested.
+	* sysdeps/unix/sysv/linux/powerpc/sigreturn.S: Make look like
+	sysdeps/unix/_exit.S.
+	* sysdeps/unix/sysv/linux/powerpc/socket.S: Use new macros.
+	* sysdeps/unix/sysv/linux/powerpc/syscall.S: Use new macros.
+	* sysdeps/unix/sysv/linux/powerpc/sysdep.h: Define some new macros
+	to make assembler (possibly) more portable, allow profiling, etc.
+
 1997-09-05 03:15  Ulrich Drepper  <drepper@cygnus.com>
 
 	* Makefile (subdirs): Reorganize order so that nss follows add-ons.
diff --git a/FAQ b/FAQ
index d4af13b05b..eb35e1cd00 100644
--- a/FAQ
+++ b/FAQ
@@ -102,6 +102,7 @@ in the future are:
 	i[3456]86-*-linux-gnu	Linux-2.0 on Intel
 	m68k-*-linux-gnu	Linux-2.0 on Motorola 680x0
 	alpha-*-linux-gnu	Linux-2.0 on DEC Alpha
+	powerpc-*-linux-gnu     Linux and MkLinux on PowerPC systems
 
 Other Linux platforms are also on the way to be supported but I need
 some success reports first.
@@ -177,7 +178,8 @@ Library.
   form the tools from the GNU gettext package are necessary.  See
   ftp://prep.ai.mit.edu/pub/gnu or better any mirror site.
 
-* lots of diskspace (for i?86-linux this means, e.g., ~70MB).
+* lots of diskspace (for i?86-linux this means, e.g., ~170MB; for ppc-linux
+  even ~200MB).
 
   You should avoid compiling on a NFS mounted device.  This is very
   slow.
diff --git a/Makeconfig b/Makeconfig
index 53dedee507..9f6786cbba 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -338,15 +338,19 @@ ifndef asm-CPPFLAGS
 asm-CPPFLAGS =
 endif
 
+# ELF always supports init/fini sections
+ifeq ($(elf),yes)
+have-initfini = yes
+endif
+
 # Installed name of the startup code.
-ifneq ($(elf),yes)
-# When not using ELF, there is just one startfile, called crt0.o.
+ifneq ($(have-initfini),yes)
+# When not having init/fini, there is just one startfile, called crt0.o.
 start-installed-name = crt0.o
 else
-# In the ELF universe, crt0.o is called crt1.o, and there are
+# On systems having init/fini, crt0.o is called crt1.o, and there are
 # some additional bizarre files.
 start-installed-name = crt1.o
-have-initfini = yes
 endif
 
 
@@ -584,6 +588,8 @@ $(common-objpfx)version.mk: $(..)version.h $(..)Makeconfig
 	    < $< > $@-new
 	mv -f $@-new $@
 
+common-generated += version.mk
+
 ifeq (yes, $(build-shared))
 
 # Process the shlib-versions file, which tells us what shared library
diff --git a/Makefile b/Makefile
index 9d66fb49b0..22cea63624 100644
--- a/Makefile
+++ b/Makefile
@@ -268,6 +268,7 @@ distclean-1: subdir_$(distclean-1)
 	-rm -f $(config-generated)
 	-rm -f $(addprefix $(objpfx),config.status config.cache config.log)
 	-rm -f $(addprefix $(objpfx),config.make config-name.h config.h)
+	-rm -f $(addprefix $(objpfx),glibcbug)
 ifdef objdir
 	-rm -f $(objpfx)Makefile
 endif
diff --git a/Makerules b/Makerules
index 8f35b716d5..85ed6eb13e 100644
--- a/Makerules
+++ b/Makerules
@@ -377,8 +377,8 @@ endef
 # Also omits crti.o and crtn.o, which we do not want
 # since we define our own `.init' section specially.
 LDFLAGS-c.so = -nostdlib -nostartfiles
-# But we still want to link libc.so against -lgcc.
-LDLIBS-c.so = -lgcc
+# But we still want to link libc.so against $(gnulib).
+LDLIBS-c.so = $(gnulib)
 # Give libc.so an entry point and make it directly runnable itself.
 LDFLAGS-c.so += -e __libc_main
 # We have a versioning file for libc.so.
diff --git a/catgets/Makefile b/catgets/Makefile
index 4646dd5a3f..725d826249 100644
--- a/catgets/Makefile
+++ b/catgets/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -29,6 +29,8 @@ install-bin	= gencat
 
 gencat-modules	= xmalloc
 
+generated += xmalloc.o
+
 # To find xmalloc.c
 vpath %.c ../locale/programs
 
diff --git a/config.guess b/config.guess
index 1448103304..413ed41c0f 100755
--- a/config.guess
+++ b/config.guess
@@ -52,6 +52,9 @@ trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
 
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
 	# A Vn.n version is a released version.
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
@@ -62,9 +65,14 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 main:
 	.frame \$30,0,\$26,0
 	.prologue 0
-	.long 0x47e03d84
-	cmoveq \$4,0,\$3
-	addl \$3,\$31,\$0
+	.long 0x47e03d80 # implver $0
+	lda \$2,259
+	.long 0x47e20c21 # amask $2,$1
+	srl \$1,8,\$2
+	sll \$2,2,\$2
+	sll \$0,3,\$0
+	addl \$1,\$0,\$0
+	addl \$2,\$0,\$0
 	ret \$31,(\$26),1
 	.end main
 EOF
@@ -72,16 +80,25 @@ EOF
 	if test "$?" = 0 ; then
 		./dummy
 		case "$?" in
-			1)
+			7)
+				UNAME_MACHINE="alpha"
+				;;
+			15)
 				UNAME_MACHINE="alphaev5"
 				;;
-			2)
+			14)
 				UNAME_MACHINE="alphaev56"
 				;;
+			10)
+				UNAME_MACHINE="alphapca56"
+				;;
+			16)
+				UNAME_MACHINE="alphaev6"
+				;;
 		esac
 	fi
 	rm -f dummy.s dummy
-	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
 	exit 0 ;;
     21064:Windows_NT:50:3)
 	echo alpha-dec-winnt3.5
@@ -500,9 +517,14 @@ EOF
 	main:
 		.frame \$30,0,\$26,0
 		.prologue 0
-		.long 0x47e03d84
-		cmoveq \$4,0,\$3
-		addl \$3,\$31,\$0
+		.long 0x47e03d80 # implver $0
+		lda \$2,259
+		.long 0x47e20c21 # amask $2,$1
+		srl \$1,8,\$2
+		sll \$2,2,\$2
+		sll \$0,3,\$0
+		addl \$1,\$0,\$0
+		addl \$2,\$0,\$0
 		ret \$31,(\$26),1
 		.end main
 EOF
@@ -511,12 +533,21 @@ EOF
 		if test "$?" = 0 ; then
 			./dummy
 			case "$?" in
-				1)
-					UNAME_MACHINE="alphaev5"
-				;;	
-			2)	
-					UNAME_MACHINE="alphaev56"
-				;;	
+			7)
+				UNAME_MACHINE="alpha"
+				;;
+			15)
+				UNAME_MACHINE="alphaev5"
+				;;
+			14)
+				UNAME_MACHINE="alphaev56"
+				;;
+			10)
+				UNAME_MACHINE="alphapca56"
+				;;
+			16)
+				UNAME_MACHINE="alphaev6"
+				;;
 			esac	
 
 			objdump --private-headers dummy | \
diff --git a/config.sub b/config.sub
index 0ac2ca1bee..dacb4bde68 100755
--- a/config.sub
+++ b/config.sub
@@ -149,14 +149,14 @@ esac
 case $basic_machine in
 	# Recognize the basic CPU types without company name.
 	# Some are omitted here because they have special meanings below.
-	tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \
+	tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
 		| arme[lb] | pyramid | mn10200 | mn10300 \
 		| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
 		| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
 		| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
 		| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
 		| mipstx39 | mipstx39el \
-		| sparc | sparclet | sparclite | sparc64)
+		| sparc | sparclet | sparclite | sparc64 | v850)
 		basic_machine=$basic_machine-unknown
 		;;
 	# We use `pc' rather than `unknown'
@@ -172,7 +172,7 @@ case $basic_machine in
 		;;
 	# Recognize the basic CPU types with company name.
 	vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
-	      | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
+	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
 	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
 	      | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
 	      | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
@@ -209,9 +209,9 @@ case $basic_machine in
 	amiga | amiga-*)
 		basic_machine=m68k-cbm
 		;;
-	amigados)
+	amigaos | amigados)
 		basic_machine=m68k-cbm
-		os=-amigados
+		os=-amigaos
 		;;
 	amigaunix | amix)
 		basic_machine=m68k-cbm
@@ -707,7 +707,8 @@ case $os in
 	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
 	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
 	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
-	      | -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
@@ -841,7 +842,7 @@ case $basic_machine in
 		os=-sysv
 		;;
 	*-cbm)
-		os=-amigados
+		os=-amigaos
 		;;
 	*-dg)
 		os=-dgux
diff --git a/configure b/configure
index a3fb9989ad..c6042fc9a7 100755
--- a/configure
+++ b/configure
@@ -1918,23 +1918,26 @@ EOF
   fi
 fi
 
+
+
 if test $elf = yes; then
   libc_cv_asm_underscores=no
 else
-  echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:1926: checking for _ prefix on C symbol names" >&5
+  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:1929: 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 1931 "configure"
+#line 1934 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:1938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -1947,6 +1950,37 @@ rm -f conftest*
 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:1956: 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 1961 "configure"
+#include "confdefs.h"
+void underscore_test(void) {
+return; }
+EOF
+if { (eval echo configure:1966: \"$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
+  else
+    rm -f conftest*
+    libc_cv_asm_underscores=no
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -f conftest*
+  libc_cv_asm_underscores=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libc_cv_asm_underscores" 1>&6
+  fi
 fi
 if test $libc_cv_asm_underscores = no; then
   cat >> confdefs.h <<\EOF
@@ -1961,7 +1995,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:1965: checking for assembler .weak directive" >&5
+echo "configure:1999: 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
@@ -1984,7 +2018,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:1988: checking for assembler .weakext directive" >&5
+echo "configure:2022: 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
@@ -2021,7 +2055,7 @@ EOF
 fi
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:2025: checking for ld --no-whole-archive" >&5
+echo "configure:2059: 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
@@ -2032,7 +2066,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -Wl,--no-whole-archive
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:2036: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:2070: \"$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
@@ -2043,7 +2077,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:2047: checking for gcc -fno-exceptions" >&5
+echo "configure:2081: 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
@@ -2054,7 +2088,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -fno-exceptions
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:2058: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:2092: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_no_exceptions=yes
 else
   libc_cv_gcc_no_exceptions=no
@@ -2106,7 +2140,7 @@ if test "$uname" = "sysdeps/generic"; then
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:2110: checking OS release for uname" >&5
+echo "configure:2144: 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
@@ -2128,7 +2162,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:2132: checking OS version for uname" >&5
+echo "configure:2166: 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
@@ -2150,7 +2184,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:2154: checking stdio selection" >&5
+echo "configure:2188: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -2162,7 +2196,7 @@ esac
 echo "$ac_t""$stdio" 1>&6
 
 echo $ac_n "checking ldap selection""... $ac_c" 1>&6
-echo "configure:2166: checking ldap selection" >&5
+echo "configure:2200: checking ldap selection" >&5
 
 case $add_ons in
 *ldap*)
diff --git a/configure.in b/configure.in
index fd7e49bc0e..9f2c984b26 100644
--- a/configure.in
+++ b/configure.in
@@ -605,13 +605,45 @@ if test $elf != yes; then
   fi
 fi
 
+dnl AC_CHECK_ASM_UNDERSCORE([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+AC_DEFUN(AC_CHECK_ASM_UNDERSCORE,
+[cat > conftest.$ac_ext <<EOF
+dnl This sometimes fails to find confdefs.h, for some reason.
+dnl [#]line __oline__ "[$]0"
+[#]line __oline__ "configure"
+#include "confdefs.h"
+void underscore_test(void) {
+return; }
+EOF
+if AC_TRY_EVAL(ac_compile); then
+  if grep _underscore_test conftest* >/dev/null; then
+    ifelse([$1], , :, [rm -f conftest*
+    $1])
+  else
+    ifelse([$2], , , [rm -f conftest*
+    $2])
+  fi
+else
+  echo "configure: failed program was:" >&AC_FD_CC
+  cat conftest.$ac_ext >&AC_FD_CC
+  ifelse([$2], , , [rm -f conftest*
+  $2])
+fi
+rm -f conftest*])
+
 if test $elf = yes; then
   libc_cv_asm_underscores=no
 else
-  AC_CACHE_CHECK(for _ prefix on C symbol names, libc_cv_asm_underscores,
-		 [AC_TRY_LINK([asm ("_glibc_foobar:");], [glibc_foobar ();],
-			      libc_cv_asm_underscores=yes,
-			      libc_cv_asm_underscores=no)])
+  if test $ac_cv_prog_cc_works = yes; then
+    AC_CACHE_CHECK(for _ prefix on C symbol names, libc_cv_asm_underscores,
+		   [AC_TRY_LINK([asm ("_glibc_foobar:");], [glibc_foobar ();],
+			        libc_cv_asm_underscores=yes,
+			        libc_cv_asm_underscores=no)])
+  else
+    AC_CACHE_CHECK(for _ prefix on C symbol names, libc_cv_asm_underscores,
+		   [AC_CHECK_ASM_UNDERSCORE(libc_cv_asm_underscores=yes,
+				            libc_cv_asm_underscores=no)])
+  fi
 fi
 if test $libc_cv_asm_underscores = no; then
   AC_DEFINE(NO_UNDERSCORES)
diff --git a/csu/Makefile b/csu/Makefile
index cfc5340d36..1c9ebb1003 100644
--- a/csu/Makefile
+++ b/csu/Makefile
@@ -55,15 +55,17 @@ crtstuff = crti crtn
 
 install-lib += $(crtstuff:=.o)
 extra-objs += $(crtstuff:=.o)
-generated += $(crtstuff:=.S) initfini.s align.h end.h
+generated += $(crtstuff:=.S) initfini.s defs.h
 omit-deps += $(crtstuff)
 
 # Special rules for the building of crti.o and crtn.o
 $(objpfx)crt%.o: $(objpfx)crt%.S $(objpfx)defs.h
 	$(compile.S) -g0 $(ASFLAGS-.os) -o $@
 
+CFLAGS-initfini.s = -O0 -g0 -fPIC
+
 $(objpfx)initfini.s: initfini.c
-	$(compile.c) -O0 -g0 -S -fPIC -finhibit-size-directive \
+	$(compile.c) -S $(CFLAGS-initfini.s) -finhibit-size-directive \
 		$(no-exceptions) -o $@
 
 # We only have one kind of startup code files.  Static binaries and
diff --git a/db2/README b/db2/README
new file mode 100644
index 0000000000..2dc1d1be8a
--- /dev/null
+++ b/db2/README
@@ -0,0 +1,3 @@
+The LICENSE file, mentioned in the beginning of the source files, can
+be found together with all the other relevant license texts in the
+manual and the INSTALL file in the toplevel directory.
diff --git a/db2/btree/bt_rec.c b/db2/btree/bt_rec.c
index bf48e01d54..07a3d93c74 100644
--- a/db2/btree/bt_rec.c
+++ b/db2/btree/bt_rec.c
@@ -301,7 +301,7 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
 		if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL)
 			goto nomem;
 		if ((_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) {
-nomem:			errno = ENOMEM;
+nomem:			__set_errno(ENOMEM);
 			__db_err(file_dbp->dbenv, "%s", strerror(errno));
 			goto out;
 		}
@@ -668,7 +668,7 @@ __bam_cadjust_recover(logp, dbtp, lsnp, redo, info)
 	REC_INTRO(__bam_cadjust_read);
 
 	if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
-		errno = __db_pgerr(file_dbp, argp->pgno);
+		__set_errno(__db_pgerr(file_dbp, argp->pgno));
 		pagep = NULL;
 		goto out;
 	}
diff --git a/db2/clib/getlong.c b/db2/clib/getlong.c
index d79c6846df..0cc8567081 100644
--- a/db2/clib/getlong.c
+++ b/db2/clib/getlong.c
@@ -18,6 +18,7 @@ static const char sccsid[] = "@(#)getlong.c	10.2 (Sleepycat) 5/1/97";
 #endif
 
 #include "db.h"
+#include "db_int.h"
 #include "clib_ext.h"
 
 /*
@@ -34,7 +35,7 @@ get_long(p, min, max, storep)
 	long val;
 	char *end;
 
-	errno = 0;
+	__set_errno(0);
 	val = strtol(p, &end, 10);
 	if ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)
 		err(1, "%s", p);
diff --git a/db2/db185/db185.c b/db2/db185/db185.c
index 8e53a1b734..bf5e37edcb 100644
--- a/db2/db185/db185.c
+++ b/db2/db185/db185.c
@@ -38,7 +38,7 @@ static int db185_seq __P((const DB185 *, DBT185 *, DBT185 *, u_int));
 static int db185_sync __P((const DB185 *, u_int));
 
 DB185 *
-dbopen(file, oflags, mode, type, openinfo)
+__dbopen(file, oflags, mode, type, openinfo)
 	const char *file;
 	int oflags, mode;
 	DBTYPE type;
@@ -181,18 +181,19 @@ dbopen(file, oflags, mode, type, openinfo)
 	 * Store the returned pointer to the real DB 2.0 structure in the
 	 * internal pointer.  Ugly, but we're not going for pretty, here.
 	 */
-	if ((errno = db_open(file,
-	    type, __db_oflags(oflags), mode, NULL, dbinfop, &dbp)) != 0) {
+	if ((__set_errno(db_open(file,
+	    type, __db_oflags(oflags), mode, NULL, dbinfop, &dbp))) != 0) {
 		free(db185p);
 		return (NULL);
 	}
 
 	/* Create the cursor used for sequential ops. */
-	if ((errno = dbp->cursor(dbp, NULL, &((DB185 *)db185p)->dbc)) != 0) {
+	if ((__set_errno(dbp->cursor(dbp, NULL, &((DB185 *)db185p)->dbc)))
+	    != 0) {
 		s_errno = errno;
 		(void)dbp->close(dbp, 0);
 		free(db185p);
-		errno = s_errno;
+		__set_errno(s_errno);
 		return (NULL);
 	}
 
@@ -200,9 +201,10 @@ dbopen(file, oflags, mode, type, openinfo)
 	return (db185p);
 
 einval:	free(db185p);
-	errno = EINVAL;
+	__set_errno(EINVAL);
 	return (NULL);
 }
+weak_alias (__dbopen, dbopen)
 
 static int
 db185_close(db185p)
@@ -212,7 +214,7 @@ db185_close(db185p)
 
 	dbp = (DB *)db185p->internal;
 
-	errno = dbp->close(dbp, 0);
+	__set_errno(dbp->close(dbp, 0));
 
 	free(db185p);
 
@@ -237,9 +239,9 @@ db185_del(db185p, key185, flags)
 	if (flags & ~R_CURSOR)
 		goto einval;
 	if (flags & R_CURSOR)
-		errno = db185p->dbc->c_del(db185p->dbc, 0);
+		__set_errno(db185p->dbc->c_del(db185p->dbc, 0));
 	else
-		errno = dbp->del(dbp, NULL, &key, 0);
+		__set_errno(dbp->del(dbp, NULL, &key, 0));
 
 	switch (errno) {
 	case 0:
@@ -249,7 +251,7 @@ db185_del(db185p, key185, flags)
 	}
 	return (-1);
 
-einval:	errno = EINVAL;
+einval:	__set_errno(EINVAL);
 	return (-1);
 }
 
@@ -262,7 +264,7 @@ db185_fd(db185p)
 
 	dbp = (DB *)db185p->internal;
 
-	return ((errno = dbp->fd(dbp, &fd)) == 0 ? fd : -1);
+	return ((__set_errno(dbp->fd(dbp, &fd))) == 0 ? fd : -1);
 }
 
 static int
@@ -287,7 +289,7 @@ db185_get(db185p, key185, data185, flags)
 	if (flags)
 		goto einval;
 
-	switch (errno = dbp->get(dbp, NULL, &key, &data, 0)) {
+	switch (__set_errno(dbp->get(dbp, NULL, &key, &data, 0))) {
 	case 0:
 		data185->data = data.data;
 		data185->size = data.size;
@@ -297,7 +299,7 @@ db185_get(db185p, key185, data185, flags)
 	}
 	return (-1);
 
-einval:	errno = EINVAL;
+einval:	__set_errno(EINVAL);
 	return (-1);
 }
 
@@ -324,46 +326,46 @@ db185_put(db185p, key185, data185, flags)
 
 	switch (flags) {
 	case 0:
-		errno = dbp->put(dbp, NULL, &key, &data, 0);
+		__set_errno(dbp->put(dbp, NULL, &key, &data, 0));
 		break;
 	case R_CURSOR:
-		errno =
-		    db185p->dbc->c_put(db185p->dbc, &key, &data, DB_CURRENT);
+		__set_errno(
+		    db185p->dbc->c_put(db185p->dbc, &key, &data, DB_CURRENT));
 		break;
 	case R_IAFTER:
 	case R_IBEFORE:
 		if (dbp->type != DB_RECNO)
 			goto einval;
 
-		if ((errno = dbp->cursor(dbp, NULL, &dbcp_put)) != 0)
+		if ((__set_errno(dbp->cursor(dbp, NULL, &dbcp_put))) != 0)
 			return (-1);
-		if ((errno =
-		    dbcp_put->c_get(dbcp_put, &key, &data, DB_SET)) != 0) {
+		if ((__set_errno(
+		    dbcp_put->c_get(dbcp_put, &key, &data, DB_SET))) != 0) {
 			s_errno = errno;
 			(void)dbcp_put->c_close(dbcp_put);
-			errno = s_errno;
+			__set_errno(s_errno);
 			return (-1);
 		}
 		memset(&data, 0, sizeof(data));
 		data.data = data185->data;
 		data.size = data185->size;
-		errno = dbcp_put->c_put(dbcp_put,
-		    &key, &data, flags == R_IAFTER ? DB_AFTER : DB_BEFORE);
+		__set_errno(dbcp_put->c_put(dbcp_put,
+		    &key, &data, flags == R_IAFTER ? DB_AFTER : DB_BEFORE));
 		s_errno = errno;
 		(void)dbcp_put->c_close(dbcp_put);
-		errno = s_errno;
+		__set_errno(s_errno);
 		break;
 	case R_NOOVERWRITE:
-		errno = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
+		__set_errno(dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE));
 		break;
 	case R_SETCURSOR:
 		if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
 			goto einval;
 
-		if ((errno = dbp->put(dbp, NULL, &key, &data, 0)) != 0)
+		if ((__set_errno(dbp->put(dbp, NULL, &key, &data, 0))) != 0)
 			break;
-		errno =
-		    db185p->dbc->c_get(db185p->dbc, &key, &data, DB_SET_RANGE);
+		__set_errno(db185p->dbc->c_get(db185p->dbc,
+					       &key, &data, DB_SET_RANGE));
 		break;
 	default:
 		goto einval;
@@ -379,7 +381,7 @@ db185_put(db185p, key185, data185, flags)
 	}
 	return (-1);
 
-einval:	errno = EINVAL;
+einval:	__set_errno(EINVAL);
 	return (-1);
 }
 
@@ -424,7 +426,8 @@ db185_seq(db185p, key185, data185, flags)
 	default:
 		goto einval;
 	}
-	switch (errno = db185p->dbc->c_get(db185p->dbc, &key, &data, flags)) {
+	switch (__set_errno(db185p->dbc->c_get(db185p->dbc,
+					       &key, &data, flags))) {
 	case 0:
 		key185->data = key.data;
 		key185->size = key.size;
@@ -436,7 +439,7 @@ db185_seq(db185p, key185, data185, flags)
 	}
 	return (-1);
 
-einval:	errno = EINVAL;
+einval:	__set_errno(EINVAL);
 	return (-1);
 }
 
@@ -464,8 +467,8 @@ db185_sync(db185p, flags)
 		goto einval;
 	}
 
-	return ((errno = dbp->sync(dbp, 0)) == 0 ? 0 : -1);
+	return ((__set_errno(dbp->sync(dbp, 0))) == 0 ? 0 : -1);
 
-einval:	errno = EINVAL;
+einval:	__set_errno(EINVAL);
 	return (-1);
 }
diff --git a/db2/db185/db185_int.h b/db2/db185/db185_int.h
index 656dfddf78..f3e24b9026 100644
--- a/db2/db185/db185_int.h
+++ b/db2/db185/db185_int.h
@@ -130,6 +130,7 @@ typedef struct {
 #if defined(__cplusplus)
 extern "C" {
 #endif
+DB185 *__dbopen __P((const char *, int, int, DBTYPE, const void *));
 DB185 *dbopen __P((const char *, int, int, DBTYPE, const void *));
 #if defined(__cplusplus)
 };
diff --git a/db2/db_int.h b/db2/db_int.h
index 23fb106755..a088c693a8 100644
--- a/db2/db_int.h
+++ b/db2/db_int.h
@@ -25,6 +25,12 @@
 
 #define	DB_MINCACHE	10		/* Minimum cached pages */
 
+/* Handle `errno' in the presence of multi-threading correctly.  On some
+   systems we need a special macro to do this right.  */
+#ifndef __set_errno
+# define __set_errno(val) (errno) = (val)
+#endif
+
 /*
  * Aligning items to particular sizes or in pages or memory.  ALIGNP is a
  * separate macro, as we've had to cast the pointer to different integral
diff --git a/db2/dbm/dbm.c b/db2/dbm/dbm.c
index fb21ade020..1fa92ce1fa 100644
--- a/db2/dbm/dbm.c
+++ b/db2/dbm/dbm.c
@@ -199,8 +199,8 @@ dbm_open(file, oflags, mode)
 	dbinfo.h_nelem = 1;
 
 	(void)snprintf(path, sizeof(path), "%s%s", file, DBM_SUFFIX);
-	if ((errno = db_open(path,
-	    DB_HASH, __db_oflags(oflags), mode, NULL, &dbinfo, &dbp)) != 0)
+	if ((__set_errno(db_open(path,
+	    DB_HASH, __db_oflags(oflags), mode, NULL, &dbinfo, &dbp))) != 0)
 		return (NULL);
 	return ((DBM *)dbp);
 }
@@ -261,7 +261,7 @@ dbm_firstkey(db)
 	DBC *cp;
 
 	if ((cp = TAILQ_FIRST(&db->curs_queue)) == NULL)
-		if ((errno = db->cursor(db, NULL, &cp)) != 0) {
+		if ((__set_errno(db->cursor(db, NULL, &cp))) != 0) {
 			memset(&key, 0, sizeof(key));
 			return (key);
 		}
@@ -294,7 +294,7 @@ dbm_nextkey(db)
 	int status;
 
 	if ((cp = TAILQ_FIRST(&db->curs_queue)) == NULL)
-		if ((errno = db->cursor(db, NULL, &cp)) != 0) {
+		if ((__set_errno(db->cursor(db, NULL, &cp))) != 0) {
 			memset(&key, 0, sizeof(key));
 			return (key);
 		}
@@ -330,9 +330,9 @@ dbm_delete(db, key)
 	_key.size = key.dsize;
 	ret = (((DB *)db)->del)((DB *)db, NULL, &_key, 0);
 	if (ret < 0)
-		errno = ENOENT;
+		__set_errno(ENOENT);
 	else if (ret > 0) {
-		errno = ret;
+		__set_errno(ret);
 		ret = -1;
 	}
 	return (ret);
diff --git a/db2/lock/lock_deadlock.c b/db2/lock/lock_deadlock.c
index 54a73afd1b..f753958b21 100644
--- a/db2/lock/lock_deadlock.c
+++ b/db2/lock/lock_deadlock.c
@@ -300,8 +300,8 @@ retry:	count = lt->region->nlockers;
 			for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock);
 			    lp != NULL;
 			    lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
-				if ((errno = __lock_getobj(lt, lp->holder,
-				    NULL, DB_LOCK_LOCKER, &lockerp)) != 0) {
+				if ((__set_errno(__lock_getobj(lt, lp->holder,
+				    NULL, DB_LOCK_LOCKER, &lockerp))) != 0) {
 					__db_err(dbenv,
 					    "warning unable to find object");
 					continue;
@@ -472,7 +472,7 @@ __dd_debug(dbenv, idmap, bitmap, nlockers)
 	 * Alloc space to print 10 bytes per item waited on.
 	 */
 	if ((msgbuf = (char *)malloc((nlockers + 1) * 10 + 64)) == NULL) {
-		errno = ENOMEM;
+		__set_errno(ENOMEM);
 		__db_err(dbenv, "%s", strerror(errno));
 		return;
 	}
diff --git a/db2/log/log_archive.c b/db2/log/log_archive.c
index d70d4c64c0..0d6c3f2bea 100644
--- a/db2/log/log_archive.c
+++ b/db2/log/log_archive.c
@@ -68,7 +68,7 @@ log_archive(logp, listp, flags, db_malloc)
 	 * but that's just not possible.
 	 */
 	if (LF_ISSET(DB_ARCH_ABS)) {
-		errno = 0;
+		__set_errno(0);
 		if ((pref = getcwd(buf, sizeof(buf))) == NULL)
 			return (errno == 0 ? ENOMEM : errno);
 	} else
diff --git a/elf/dl-close.c b/elf/dl-close.c
index fa9e92cb9f..9467385080 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/mman.h>
-#include <libc-lock.h>
+#include <bits/libc-lock.h>
 
 
 /* During the program run we must not modify the global data of
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 113e472165..84a76cfb4a 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -21,7 +21,7 @@
 #include <dlfcn.h>
 #include <stdlib.h>
 #include <errno.h>
-#include <libc-lock.h>
+#include <bits/libc-lock.h>
 
 
 extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
diff --git a/elf/dl-profile.c b/elf/dl-profile.c
index c8028a7c5a..9b020e8fe9 100644
--- a/elf/dl-profile.c
+++ b/elf/dl-profile.c
@@ -2,6 +2,7 @@
    Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+   Based on the BSD mcount implementation.
 
    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
@@ -30,6 +31,7 @@
 #include <sys/gmon_out.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
+#include <atomicity.h>
 
 /* The LD_PROFILE feature has to be implemented different to the
    normal profiling using the gmon/ functions.  The problem is that an
@@ -146,19 +148,19 @@ static long int state;
 static volatile uint16_t *kcount;
 static size_t kcountsize;
 
-struct here_tostruct
+struct here_fromstruct
   {
     struct here_cg_arc_record volatile *here;
     uint16_t link;
   };
 
-static uint16_t *froms;
-static size_t fromssize;
-
-static struct here_tostruct *tos;
+static uint16_t *tos;
 static size_t tossize;
-static size_t tolimit;
-static size_t toidx;
+
+static struct here_fromstruct *froms;
+static size_t fromssize;
+static size_t fromlimit;
+static size_t fromidx;
 
 static uintptr_t lowpc;
 static uintptr_t highpc;
@@ -170,6 +172,11 @@ static unsigned int log_hashfraction;
 static struct gmon_hdr *addr;
 static off_t expected_size;
 
+/* See profil(2) where this is described.  */
+static int s_scale;
+#define SCALE_1_TO_1	0x10000L
+
+
 
 /* Set up profiling data to profile object desribed by MAP.  The output
    file is found (or created) in OUTPUT_DIR.  */
@@ -184,7 +191,7 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
   ElfW(Addr) mapend = 0;
   struct gmon_hdr gmon_hdr;
   struct gmon_hist_hdr hist_hdr;
-  char *hist;
+  char *hist, *cp;
   size_t idx;
 
   /* Compute the size of the sections which contain program code.  */
@@ -205,9 +212,9 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
      with the same formulars as in `monstartup' (see gmon.c).  */
   state = GMON_PROF_OFF;
   lowpc = ROUNDDOWN (mapstart + map->l_addr,
-		     HISTFRACTION * sizeof(HISTCOUNTER));
+		     HISTFRACTION * sizeof (HISTCOUNTER));
   highpc = ROUNDUP (mapend + map->l_addr,
-		    HISTFRACTION * sizeof(HISTCOUNTER));
+		    HISTFRACTION * sizeof (HISTCOUNTER));
   textsize = highpc - lowpc;
   kcountsize = textsize / HISTFRACTION;
   hashfraction = HASHFRACTION;
@@ -217,17 +224,17 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
     log_hashfraction = __builtin_ffs (hashfraction * sizeof (*froms)) - 1;
   else
     log_hashfraction = -1;
-  fromssize = textsize / HASHFRACTION;
-  tolimit = textsize * ARCDENSITY / 100;
-  if (tolimit < MINARCS)
-    tolimit = MINARCS;
-  if (tolimit > MAXARCS)
-    tolimit = MAXARCS;
-  tossize = tolimit * sizeof (struct here_tostruct);
+  tossize = textsize / HASHFRACTION;
+  fromlimit = textsize * ARCDENSITY / 100;
+  if (fromlimit < MINARCS)
+    fromlimit = MINARCS;
+  if (fromlimit > MAXARCS)
+    fromlimit = MAXARCS;
+  fromssize = fromlimit * sizeof (struct here_fromstruct);
 
   expected_size = (sizeof (struct gmon_hdr)
 		   + 4 + sizeof (struct gmon_hist_hdr) + kcountsize
-		   + 4 + 4 + tossize * sizeof (struct here_cg_arc_record));
+		   + 4 + 4 + fromssize * sizeof (struct here_cg_arc_record));
 
   /* Create the gmon_hdr we expect or write.  */
   memset (&gmon_hdr, '\0', sizeof (struct gmon_hdr));
@@ -247,9 +254,9 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
      soname (or the file name) and the ending ".profile".  */
   filename = (char *) alloca (strlen (output_dir) + 1 + strlen (_dl_profile)
 			      + sizeof ".profile");
-  __stpcpy (__stpcpy (__stpcpy (__stpcpy (filename, output_dir), "/"),
-		      _dl_profile),
-	    ".profile");
+  cp = __stpcpy (filename, output_dir);
+  *cp++ = '/';
+  __stpcpy (__stpcpy (cp, _dl_profile), ".profile");
 
   fd = __open (filename, O_RDWR | O_CREAT, 0666);
   if (fd == -1)
@@ -356,7 +363,7 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
     }
 
   /* Allocate memory for the froms data and the pointer to the tos records.  */
-  froms = (uint16_t *) calloc (fromssize + tossize, 1);
+  tos = (uint16_t *) calloc (tossize + fromssize, 1);
   if (froms == NULL)
     {
       __munmap ((void *) addr, expected_size);
@@ -364,8 +371,8 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
       /* NOTREACHED */
     }
 
-  tos = (struct here_tostruct *) ((char *) froms + fromssize);
-  toidx = 0;
+  froms = (struct here_fromstruct *) ((char *) tos + tossize);
+  fromidx = 0;
 
   /* Now we have to process all the arc count entries.  BTW: it is
      not critical whether the *NARCSP value changes meanwhile.  Before
@@ -376,17 +383,26 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
      frequently used entries at the front of the list.  */
   for (idx = narcs = *narcsp; idx > 0; )
     {
-      size_t from_index;
-      size_t newtoidx;
+      size_t to_index;
+      size_t newfromidx;
       --idx;
-      from_index = ((data[idx].from_pc - lowpc)
-		    / (hashfraction * sizeof (*froms)));
-      newtoidx = toidx++;
-      tos[newtoidx].here = &data[idx];
-      tos[newtoidx].link = froms[from_index];
-      froms[from_index] = newtoidx;
+      to_index = ((data[idx].self_pc - lowpc)
+		  / (hashfraction * sizeof (*tos)));
+      newfromidx = fromidx++;
+      froms[newfromidx].here = &data[idx];
+      froms[newfromidx].link = tos[to_index];
+      tos[to_index] = newfromidx;
     }
 
+  /* Setup counting data.  */
+  if (kcountsize < highpc - lowpc)
+    s_scale = ((double) kcountsize / (highpc - lowpc)) * SCALE_1_TO_1;
+  else
+    s_scale = SCALE_1_TO_1;
+
+  /* Start the profiler.  */
+  __profil ((void *) kcount, kcountsize, lowpc, s_scale);
+
   /* Turn on profiling.  */
   state = GMON_PROF_ON;
 }
@@ -395,9 +411,12 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
 void
 _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
 {
-  if (state != GMON_PROF_ON)
+  uint16_t *topcindex;
+  size_t i, fromindex;
+  struct here_fromstruct *fromp;
+
+  if (! compare_and_swap (&state, GMON_PROF_ON, GMON_PROF_BUSY))
     return;
-  state = GMON_PROF_BUSY;
 
   /* Compute relative addresses.  The shared object can be loaded at
      any address.  The value of frompc could be anything.  We cannot
@@ -411,6 +430,86 @@ _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
   if (selfpc >= textsize)
     goto done;
 
+  /* Getting here we now have to find out whether the location was
+     already used.  If yes we are lucky and only have to increment a
+     counter (this also has to be atomic).  If the entry is new things
+     are getting complicated...  */
+
+  /* Avoid integer divide if possible.  */
+  if ((HASHFRACTION & (HASHFRACTION - 1)) == 0)
+    i = selfpc >> log_hashfraction;
+  else
+    i = selfpc / (hashfraction * sizeof (*tos));
+
+  topcindex = &tos[i];
+  fromindex = *topcindex;
+
+  if (fromindex == 0)
+    goto check_new_or_add;
+
+  fromp = &froms[fromindex];
+
+  /* We have to look through the chain of arcs whether there is already
+     an entry for our arc.  */
+  while (fromp->here->from_pc == frompc)
+    {
+      if (fromp->link != 0)
+	do
+	  fromp = &froms[fromp->link];
+	while (fromp->link != 0 && fromp->here->from_pc != frompc);
+
+      if (fromp->link == 0)
+	{
+	  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)
+	    {
+	      size_t to_index;
+	      size_t newfromidx;
+	      to_index = ((data[narcs].self_pc - lowpc)
+			  / (hashfraction * sizeof (*tos)));
+	      newfromidx = fromidx++;
+	      froms[newfromidx].here = &data[narcs];
+	      froms[newfromidx].link = tos[to_index];
+	      tos[to_index] = newfromidx;
+	      ++narcs;
+	    }
+
+	  /* If we still have no entry stop searching and insert.  */
+	  if (*topcindex == 0)
+	    {
+	      fromidx = 1 + exchange_and_add (narcsp, 1);
+	      ++narcs;
+
+	      /* In rare cases it could happen that all entries in FROMS are
+		 occupied.  So we cannot count this anymore.  */
+	      if (fromidx >= fromlimit)
+		goto done;
+
+	      *topcindex = fromindex;
+	      fromp = &froms[fromindex];
+
+	      fromp = &froms[fromp->link];
+
+	      fromp->link = 0;
+	      fromp->here->from_pc = frompc;
+	      fromp->here->count = 0;
+
+	      break;
+	    }
+
+	  fromp = &froms[*topcindex];
+	}
+      else
+	/* Found in.  */
+	break;
+    }
+
+  /* Increment the counter.  */
+  atomic_add (&fromp->here->count, 1);
 
  done:
   state = GMON_PROF_ON;
diff --git a/gmon/gmon.c b/gmon/gmon.c
index 300ca30a09..10ae215c80 100644
--- a/gmon/gmon.c
+++ b/gmon/gmon.c
@@ -82,13 +82,13 @@ __moncontrol (mode)
   if (mode)
     {
       /* start */
-      profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale);
+      __profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale);
       p->state = GMON_PROF_ON;
     }
   else
     {
       /* stop */
-      profil((void *) 0, 0, 0, 0);
+      __profil(NULL, 0, 0, 0);
       p->state = GMON_PROF_OFF;
     }
 }
@@ -113,6 +113,8 @@ __monstartup (lowpc, highpc)
   p->kcountsize = p->textsize / HISTFRACTION;
   p->hashfraction = HASHFRACTION;
   p->log_hashfraction = -1;
+  /* The following test must be kept in sync with the corresponding
+     test in mcount.c.  */
   if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) {
       /* if HASHFRACTION is a power of two, mcount can use shifting
 	 instead of integer division.  Precompute shift amount. */
diff --git a/gmon/mcount.c b/gmon/mcount.c
index 66da3d054b..fe392c0949 100644
--- a/gmon/mcount.c
+++ b/gmon/mcount.c
@@ -42,6 +42,8 @@ static char sccsid[] = "@(#)mcount.c	8.1 (Berkeley) 6/4/93";
    and MCOUNT macros.  */
 #include "machine-gmon.h"
 
+#include <atomicity.h>
+
 /*
  * mcount is called on entry to each function compiled with the profiling
  * switch set.  _mcount(), which is declared in a machine-dependent way
@@ -63,9 +65,6 @@ _MCOUNT_DECL(frompc, selfpc)	/* _mcount; may be static, inline, etc */
 	register struct tostruct *top, *prevtop;
 	register struct gmonparam *p;
 	register long toindex;
-#ifdef KERNEL
-	register int s;
-#endif
 	int i;
 
 	p = &_gmonparam;
@@ -73,13 +72,9 @@ _MCOUNT_DECL(frompc, selfpc)	/* _mcount; may be static, inline, etc */
 	 * check that we are profiling
 	 * and that we aren't recursively invoked.
 	 */
-	if (p->state != GMON_PROF_ON)
-		return;
-#ifdef KERNEL
-	MCOUNT_ENTER;
-#else
-	p->state = GMON_PROF_BUSY;
-#endif
+	if (! compare_and_swap (&p->state, GMON_PROF_ON, GMON_PROF_BUSY))
+	  return;
+
 	/*
 	 * check that frompcindex is a reasonable pc value.
 	 * for example:	signal catchers get called from the stack,
@@ -89,8 +84,14 @@ _MCOUNT_DECL(frompc, selfpc)	/* _mcount; may be static, inline, etc */
 	if (frompc > p->textsize)
 		goto done;
 
-	/* avoid integer divide if possible: */
-	if (p->log_hashfraction >= 0) {
+	/* The following test used to be
+		if (p->log_hashfraction >= 0)
+	   But we can simplify this if we assume the profiling data
+	   is always initialized by the functions in gmon.c.  But
+	   then it is possible to avoid a runtime check and use the
+	   smae `if' as in gmon.c.  So keep these tests in sync.  */
+	if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) {
+	  /* avoid integer divide if possible: */
 	    i = frompc >> p->log_hashfraction;
 	} else {
 	    i = frompc / (p->hashfraction * sizeof(*p->froms));
@@ -167,17 +168,10 @@ _MCOUNT_DECL(frompc, selfpc)	/* _mcount; may be static, inline, etc */
 
 	}
 done:
-#ifdef KERNEL
-	MCOUNT_EXIT;
-#else
 	p->state = GMON_PROF_ON;
-#endif
 	return;
 overflow:
 	p->state = GMON_PROF_ERROR;
-#ifdef KERNEL
-	MCOUNT_EXIT;
-#endif
 	return;
 }
 
diff --git a/gmon/sys/gmon.h b/gmon/sys/gmon.h
index 930729e7fc..85d9392d8e 100644
--- a/gmon/sys/gmon.h
+++ b/gmon/sys/gmon.h
@@ -133,7 +133,7 @@ struct rawarc {
  * The profiling data structures are housed in this structure.
  */
 struct gmonparam {
-	int		state;
+	long int	state;
 	u_short		*kcount;
 	u_long		kcountsize;
 	u_short		*froms;
diff --git a/include/bits/string2.h b/include/bits/string2.h
new file mode 100644
index 0000000000..e4c4c709b5
--- /dev/null
+++ b/include/bits/string2.h
@@ -0,0 +1 @@
+#include <string/bits/string2.h>
diff --git a/include/rpc/auth.h b/include/rpc/auth.h
new file mode 100644
index 0000000000..5721091a56
--- /dev/null
+++ b/include/rpc/auth.h
@@ -0,0 +1 @@
+#include <sunrpc/rpc/auth.h>
diff --git a/include/rpc/auth_des.h b/include/rpc/auth_des.h
new file mode 100644
index 0000000000..02736aa03b
--- /dev/null
+++ b/include/rpc/auth_des.h
@@ -0,0 +1 @@
+#include <sunrpc/rpc/auth_des.h>
diff --git a/include/rpc/key_prot.h b/include/rpc/key_prot.h
new file mode 100644
index 0000000000..2baa99d297
--- /dev/null
+++ b/include/rpc/key_prot.h
@@ -0,0 +1 @@
+#include <sunrpc/rpc/key_prot.h>
diff --git a/inet/test_ifindex.c b/inet/test_ifindex.c
index f0a34cf0da..d44e0b1cb4 100644
--- a/inet/test_ifindex.c
+++ b/inet/test_ifindex.c
@@ -45,7 +45,8 @@ main (void)
   for (p = idx; p->if_index || p->if_name; ++p)
     {
       char buf[IFNAMSIZ];
-      int ni, result;
+      unsigned int ni;
+      int result;
       printf ("%3d %15s | ", p->if_index, p->if_name);
       printf ("%3d", ni = if_nametoindex (p->if_name));
       printf ("%15s", if_indextoname (p->if_index, buf));
diff --git a/intl/dcgettext.c b/intl/dcgettext.c
index c7540053b2..ecc2e1ac26 100644
--- a/intl/dcgettext.c
+++ b/intl/dcgettext.c
@@ -95,7 +95,9 @@ void free ();
    because some ANSI C functions will require linking with this object
    file and the name space must not be polluted.  */
 # define getcwd __getcwd
-# define stpcpy __stpcpy
+# ifndef stpcpy
+#  define stpcpy __stpcpy
+# endif
 #else
 # if !defined HAVE_GETCWD
 char *getwd ();
diff --git a/intl/l10nflist.c b/intl/l10nflist.c
index 640b932b01..5309cc73ed 100644
--- a/intl/l10nflist.c
+++ b/intl/l10nflist.c
@@ -68,7 +68,9 @@
 /* Rename the non ANSI C functions.  This is required by the standard
    because some ANSI C functions will require linking with this object
    file and the name space must not be polluted.  */
-# define stpcpy(dest, src) __stpcpy(dest, src)
+# ifndef stpcpy
+#  define stpcpy(dest, src) __stpcpy(dest, src)
+# endif
 #else
 # ifndef HAVE_STPCPY
 static char *stpcpy PARAMS ((char *dest, const char *src));
diff --git a/libc.map b/libc.map
index fc6c9fe6c9..3f3d28d485 100644
--- a/libc.map
+++ b/libc.map
@@ -60,7 +60,7 @@ GLIBC_2.0 {
     __ctype_get_mb_cur_max;
 
     # functions used in other libraries
-    __printf_fp; __stpncpy;
+    __printf_fp; __stpncpy; __stpcpy; __strdup;
     _nss_files_parse_grent; _nss_files_parse_pwent; _nss_files_parse_spent;
     __nss_database_lookup; __internal_endnetgrent; __internal_getnetgrent_r;
     __internal_setnetgrent; __gmtime_r; __secure_getenv;
diff --git a/libio/stdio.h b/libio/stdio.h
index c420db8f84..d941aba23b 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -251,30 +251,38 @@ vprintf (const char *__restrict __fmt, _G_va_list __arg)
 #if defined __USE_BSD || defined __USE_ISOC9X
 /* Maximum chars of output to write in MAXLEN.  */
 extern int __snprintf __P ((char *__restrict __s, size_t __maxlen,
-			    __const char *__restrict __format, ...));
+			    __const char *__restrict __format, ...))
+     __attribute__ ((__format__ (__printf__, 3, 4)));
 extern int snprintf __P ((char *__restrict __s, size_t __maxlen,
-			  __const char *__restrict __format, ...));
+			  __const char *__restrict __format, ...))
+     __attribute__ ((__format__ (__printf__, 3, 4)));
 
 extern int __vsnprintf __P ((char *__restrict __s, size_t __maxlen,
 			     __const char *__restrict __format,
-			     _G_va_list __arg));
+			     _G_va_list __arg))
+     __attribute__ ((__format__ (__printf__, 3, 0)));
 extern int vsnprintf __P ((char *__restrict __s, size_t __maxlen,
 			   __const char *__restrict __format,
-			   _G_va_list __arg));
+			   _G_va_list __arg))
+     __attribute__ ((__format__ (__printf__, 3, 0)));
 #endif
 
 #ifdef __USE_GNU
 /* Write formatted output to a string dynamically allocated with `malloc'.
    Store the address of the string in *PTR.  */
 extern int vasprintf __P ((char **__restrict __ptr,
-			   __const char *__restrict __f, _G_va_list __arg));
+			   __const char *__restrict __f, _G_va_list __arg))
+     __attribute__ ((__format__ (__printf__, 2, 0)));
 extern int asprintf __P ((char **__restrict __ptr,
-			  __const char *__restrict __fmt, ...));
+			  __const char *__restrict __fmt, ...))
+     __attribute__ ((__format__ (__printf__, 2, 3)));
 
 /* Write formatted output to a file descriptor.  */
 extern int vdprintf __P ((int __fd, __const char *__restrict __fmt,
-			  _G_va_list __arg));
-extern int dprintf __P ((int __fd, __const char *__restrict __fmt, ...));
+			  _G_va_list __arg))
+     __attribute__ ((__format__ (__printf__, 2, 0)));
+extern int dprintf __P ((int __fd, __const char *__restrict __fmt, ...))
+     __attribute__ ((__format__ (__printf__, 2, 3)));
 #endif
 
 
@@ -291,23 +299,29 @@ extern int sscanf __P ((__const char *__restrict __s,
 /* Read formatted input from S into argument list ARG.  */
 extern int __vfscanf __P ((FILE *__restrict __s,
 			   __const char *__restrict __format,
-			   _G_va_list __arg));
+			   _G_va_list __arg))
+     __attribute__ ((__format__ (__scanf__, 2, 0)));
 extern int vfscanf __P ((FILE *__restrict __s,
 			 __const char *__restrict __format,
-			 _G_va_list __arg));
+			 _G_va_list __arg))
+     __attribute__ ((__format__ (__scanf__, 2, 0)));
 
 /* Read formatted input from stdin into argument list ARG.  */
 extern int __vscanf __P ((__const char *__restrict __format,
-			  _G_va_list __arg));
-extern int vscanf __P ((__const char *__restrict __format, _G_va_list __arg));
+			  _G_va_list __arg))
+     __attribute__ ((__format__ (__scanf__, 1, 0)));
+extern int vscanf __P ((__const char *__restrict __format, _G_va_list __arg))
+     __attribute__ ((__format__ (__scanf__, 1, 0)));
 
 /* Read formatted input from S into argument list ARG.  */
 extern int __vsscanf __P ((__const char *__restrict __s,
 			   __const char *__restrict __format,
-			   _G_va_list __arg));
+			   _G_va_list __arg))
+     __attribute__ ((__format__ (__scanf__, 2, 0)));
 extern int vsscanf __P ((__const char *__restrict __s,
 			 __const char *__restrict __format,
-			 _G_va_list __arg));
+			 _G_va_list __arg))
+     __attribute__ ((__format__ (__scanf__, 2, 0)));
 #endif /* Use GNU.  */
 
 
diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
index 5f1bc48f89..e2ebf26254 100644
--- a/locale/programs/ld-ctype.c
+++ b/locale/programs/ld-ctype.c
@@ -89,8 +89,8 @@ struct locale_ctype_t
 #define MAX_NR_CHARMAP 16
   const char *mapnames[MAX_NR_CHARMAP];
   u_int32_t *map_collection[MAX_NR_CHARMAP];
-  u_int32_t map_collection_max[MAX_NR_CHARMAP];
-  u_int32_t map_collection_act[MAX_NR_CHARMAP];
+  size_t map_collection_max[MAX_NR_CHARMAP];
+  size_t map_collection_act[MAX_NR_CHARMAP];
   size_t map_collection_nr;
   size_t last_map_idx;
   unsigned int from_map_char;
diff --git a/manual/Makefile b/manual/Makefile
index 9359bad6cb..cda84f7bec 100644
--- a/manual/Makefile
+++ b/manual/Makefile
@@ -132,12 +132,13 @@ glibc-doc-$(edition).tar: $(doc-only-dist) $(distribute)
 
 .PHONY: mostlyclean distclean realclean clean
 mostlyclean:
-	-rm -f libc.dvi libc.info* dir-add.info
+	-rm -f libc.dvi libc.info* dir-add.info $(common-objpfx)stub-manual
+	-rm -f $(foreach o,$(object-suffixes),$(objpfx)stamp$o)
 clean: mostlyclean
 distclean: clean
 indices = cp fn pg tp vr ky
 realclean: distclean
-	-rm -f chapters chapters-incl summary.texi stamp-summary *.c.texi
+	-rm -f chapters chapters-incl* summary.texi stamp-summary *.c.texi
 	-rm -f $(foreach index,$(indices),libc.$(index) libc.$(index)s)
 	-rm -f libc.log libc.aux libc.toc dir-add.texi
 
diff --git a/manual/maint.texi b/manual/maint.texi
index c17718111c..3675c4faba 100644
--- a/manual/maint.texi
+++ b/manual/maint.texi
@@ -206,12 +206,15 @@ On most platforms, the GNU C library can only be compiled with the GNU C
 compiler.  We recommend GCC version 2.7.2 or later; earlier versions may
 have problems.
 
+On PowerPC, GCC versions dated earlier than 970904 are known not to work
+(they crash), including 2.7.2.
+
 @item
-@code{binutils} 2.8
+@code{binutils} 2.8.1
 
 Using the GNU @code{binutils} (assembler, linker, and related tools) is
 preferable when possible, and they are required to build an ELF shared C
-library.  We recommend @code{binutils} version 2.8 or later; earlier
+library.  We recommend @code{binutils} version 2.8.1 or later; earlier
 versions are known to have problems or to not support all architectures.
 @end itemize
 
@@ -227,6 +230,7 @@ alpha-@var{anything}-linux
 i@var{x}86-@var{anything}-gnu
 i@var{x}86-@var{anything}-linux
 m68k-@var{anything}-linux
+powerpc-@var{anything}-linux
 @end smallexample
 
 Former releases of this library (version 1.09.1 and perhaps earlier
@@ -898,6 +902,10 @@ David Mosberger-Tang contributed the port to Linux/Alpha
 (@code{alpha-@var{anything}-linux}).
 
 @item
+The port to Linux on PowerPC (@code{powerpc-@var{anything}-linux})
+was contributed by Geoffrey Keating.
+
+@item
 Miles Bader wrote the argp argument-parsing package, and the argz/envz
 interfaces.
 
diff --git a/math/Makefile b/math/Makefile
index 3b1ff4332b..62619111c9 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -77,14 +77,15 @@ 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
+	test-ifloat test-idouble test-matherr test-fenv \
+	atest-exp atest-sincos
 # We do the `long double' tests only if this data type is available and
 # distrinct from `double'.
 test-longdouble-yes = test-ldouble test-ildoubl
 
-CFLAGS-test-float.c = -fno-inline
-CFLAGS-test-double.c = -fno-inline
-CFLAGS-test-ldouble.c = -fno-inline
+CFLAGS-test-float.c = -fno-inline -ffloat-store
+CFLAGS-test-double.c = -fno-inline -ffloat-store
+CFLAGS-test-ldouble.c = -fno-inline -ffloat-store
 LDLIBS-test-ifloat = math/libm
 LDLIBS-test-idouble = math/libm
 LDLIBS-test-ildoubl = math/libm
@@ -92,6 +93,8 @@ LDLIBS-test-float = math/libm
 LDLIBS-test-double = math/libm
 LDLIBS-test-ldouble = math/libm
 LDLIBS-test-matherr = math/libm
+LDLIBS-atest-exp = math/libm
+LDLIBS-atest-sincos = math/libm
 
 distribute += libm-test.c
 
diff --git a/math/atest-exp.c b/math/atest-exp.c
new file mode 100644
index 0000000000..28e572c444
--- /dev/null
+++ b/math/atest-exp.c
@@ -0,0 +1,191 @@
+/* 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 <stdlib/gmp.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+#define PRINT_ERRORS 0
+
+#define TOL 80
+#define N2 17
+#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 hexdig[] = "0123456789abcdef";
+
+void
+print_mpn_hex (const mp_limb_t *x, unsigned size)
+{
+   char value[size + 1];
+   unsigned i;
+   const unsigned final = (size * 4 > SZ * mpbpl) ? SZ * mpbpl / 4 : size;
+
+   memset (value, '0', size);
+
+   for (i = 0; i < final ; i++)
+     value[size - 1 - i] = hexdig[x[i * 4 / mpbpl] >> (i * 4) % mpbpl & 0xf];
+
+   value[size] = '\0';
+   fputs (value, stdout);
+}
+
+void
+exp_mpn (mp1 ex, mp1 x)
+{
+   unsigned 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);
+}
+
+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);
+      exp_mpn (ex, x);
+      de2 = exp (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_hex (ex, (FRAC / 4) + 1);
+	  fputs ("\n       ",stdout);
+	  print_mpn_hex (e2, (FRAC / 4) + 1);
+	  printf ("\n %c     ",
+		  e2s - e3s < 54 ? e2s - e3s == 53 ? 'e' : 'F' : 'P');
+	  print_mpn_hex (e3, (FRAC / 4) + 1);
+	  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);
+
+   memset (e2, '\0', sizeof (mp1));
+   for (i = -1; i < 100 && i < FRAC / 4; i++)
+     e2[(FRAC - i * 4 - 4) / mpbpl] |= (strchr (hexdig, exp1[i + 1]) - hexdig
+					<< (FRAC - i * 4 - 4) % mpbpl);
+
+   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_hex (maxerror, (FRAC / 4) + 1);
+   fputs ("\nerror in exp(1): ", stdout);
+   print_mpn_hex (e3, (FRAC / 4) + 1);
+   putchar ('\n');
+
+   return failures == 0 ? 0 : 1;
+}
diff --git a/math/atest-sincos.c b/math/atest-sincos.c
new file mode 100644
index 0000000000..98f1e719b1
--- /dev/null
+++ b/math/atest-sincos.c
@@ -0,0 +1,275 @@
+/* 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 <stdlib/gmp.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+#define PRINT_ERRORS 0
+
+#define N 0
+#define N2 20
+#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];
+
+/* These strings have exactly 100 hex digits in them.  */
+static const char sin1[101] =
+"d76aa47848677020c6e9e909c50f3c3289e511132f518b4def"
+"b6ca5fd6c649bdfb0bd9ff1edcd4577655b5826a3d3b50c264";
+static const char cos1[101] =
+"8a51407da8345c91c2466d976871bd29a2373a894f96c3b7f2"
+"300240b760e6fa96a94430a52d0e9e43f3450e3b8ff99bc934";
+static const char hexdig[] = "0123456789abcdef";
+
+void
+print_mpn_hex (const mp_limb_t *x, unsigned size)
+{
+   char value[size + 1];
+   unsigned i;
+   const unsigned final = (size * 4 > SZ * mpbpl) ? SZ * mpbpl / 4 : size;
+
+   memset (value, '0', size);
+
+   for (i = 0; i < final ; i++)
+     value[size-1-i] = hexdig[x[i * 4 / mpbpl] >> (i * 4) % mpbpl & 0xf];
+
+   value[size] = '\0';
+   fputs (value, stdout);
+}
+
+void
+sincosx_mpn (mp1 si, mp1 co, mp1 xx, mp1 ix)
+{
+   int i;
+   mp2 s[4], c[4];
+   mp1 tmp, x;
+   mp_limb_t chk, round;
+
+   if (ix == NULL)
+     {
+       memset (si, 0, sizeof (mp1));
+       memset (co, 0, sizeof (mp1));
+       co[SZ-1] = 1;
+       memcpy (x, xx, sizeof (mp1));
+     }
+   else
+      mpn_sub_n (x, xx, ix, SZ);
+
+   for (i = 0; i < 1 << N; i++)
+     {
+#define add_shift_mulh(d,x,s1,s2,sh,n) \
+       /* d = (n ? -1 : 1) * (s1 + (s2>>sh)) * x / (1>>N); */		      \
+      do { 								      \
+	 if (s2 != NULL) {						      \
+	    if (sh > 0) {						      \
+	       assert (sh < mpbpl);					      \
+	       mpn_lshift (tmp, s1, SZ, sh);				      \
+	       chk = (n ? mpn_sub_n : mpn_add_n)(tmp,tmp,s2+FRAC/mpbpl,SZ);   \
+	    } else							      \
+	       chk = (n ? mpn_sub_n : mpn_add_n)(tmp,s1,s2+FRAC/mpbpl,SZ);    \
+	    /* assert(chk == 0); */					      \
+	    mpn_mul_n(d,tmp,x,SZ);					      \
+	 } else 							      \
+	    mpn_mul_n(d,s1,x,SZ);					      \
+	 /* assert(d[SZ*2-1] == 0); */					      \
+	 assert(N+sh < mpbpl);						      \
+	 if (N+sh > 0) mpn_rshift(d,d,2*SZ,N+sh);			      \
+      } while(0)
+#define summ(d,ss,s,n) \
+      /* d = ss +/- (s[0]+2*s[1]+2*s[2]+s[3])/6; */			      \
+      do { 								      \
+	 chk = mpn_add_n(tmp,s[1]+FRAC/mpbpl,s[2]+FRAC/mpbpl,SZ);	      \
+	 mpn_lshift(tmp,tmp,SZ,1);					      \
+	 chk |= mpn_add_n(tmp,tmp,s[0]+FRAC/mpbpl,SZ);			      \
+	 chk |= mpn_add_n(tmp,tmp,s[3]+FRAC/mpbpl,SZ);			      \
+	 round = mpn_divmod_1(tmp,tmp,SZ,6);				      \
+	 /* chk |= mpn_add_1(tmp,tmp,SZ, (round > 3) ); */		      \
+         chk |= (n ? mpn_sub_n : mpn_add_n)(d,ss,tmp,SZ);		      \
+	 /* assert(chk == 0); */					      \
+      } while (0)
+
+      add_shift_mulh (s[0], x, co, NULL, 0, 0); /* s0 = h * c; */
+      add_shift_mulh (c[0], x, si, NULL, 0, 0); /* c0 = h * s; */
+      add_shift_mulh (s[1], x, co, c[0], 1, 1); /* s1 = h * (c - c0/2); */
+      add_shift_mulh (c[1], x, si, s[0], 1, 0); /* c1 = h * (s + s0/2); */
+      add_shift_mulh (s[2], x, co, c[1], 1, 1); /* s2 = h * (c - c1/2); */
+      add_shift_mulh (c[2], x, si, s[1], 1, 0); /* c2 = h * (s + s1/2); */
+      add_shift_mulh (s[3], x, co, c[2], 0, 1); /* s3 = h * (c - c2); */
+      add_shift_mulh (c[3], x, si, s[2], 0, 0); /* c3 = h * (s + s2); */
+      summ (si, si, s, 0);        /* s = s + (s0+2*s1+2*s2+s3)/6; */
+      summ (co, co, c, 1);        /* c = c - (c0+2*c1+2*c2+c3)/6; */
+   }
+#undef add_shift_mulh
+#undef summ
+}
+
+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 si, co, x, ox, xt, s2, c2, s3, c3;
+  int i;
+  int sin_errors = 0, cos_errors = 0;
+  int sin_failures = 0, cos_failures = 0;
+  mp1 sin_maxerror, cos_maxerror;
+  int sin_maxerror_s = 0, cos_maxerror_s = 0;
+  const double sf = pow (2, mpbpl);
+
+  /* assert(mpbpl == mp_bits_per_limb);  */
+  assert(FRAC / mpbpl * mpbpl == FRAC);
+
+  memset (sin_maxerror, 0, sizeof (mp1));
+  memset (cos_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 s2s, s3s, c2s, c3s, j;
+      double ds2,dc2;
+
+      mpn_mul_1 (x, xt, SZ, i);
+      sincosx_mpn (si, co, x, i == 0 ? NULL : ox);
+      memcpy (ox, x, sizeof (mp1));
+      ds2 = sin (i / (double) (1 << N2));
+      dc2 = cos (i / (double) (1 << N2));
+      for (j = SZ-1; j >= 0; j--)
+	{
+	  s2[j] = (mp_limb_t) ds2;
+	  ds2 = (ds2 - s2[j]) * sf;
+	  c2[j] = (mp_limb_t) dc2;
+	  dc2 = (dc2 - c2[j]) * sf;
+	}
+      if (mpn_cmp (si, s2, SZ) >= 0)
+	mpn_sub_n (s3, si, s2, SZ);
+      else
+	mpn_sub_n (s3, s2, si, SZ);
+      if (mpn_cmp (co, c2, SZ) >= 0)
+	mpn_sub_n (c3, co, c2, SZ);
+      else
+	mpn_sub_n (c3, c2, co, SZ);
+
+      s2s = mpn_bitsize (s2, SZ);
+      s3s = mpn_bitsize (s3, SZ);
+      c2s = mpn_bitsize (c2, SZ);
+      c3s = mpn_bitsize (c3, SZ);
+      if (s3s > 1 && s2s - s3s < 54
+	  || c3s > 1 && c2s - c3s < 54
+	  || 0)
+	{
+#if PRINT_ERRORS
+	  printf ("%06x ", i * (0x100000 / (1 << N2)));
+	  print_mpn_hex(si, (FRAC / 4) + 1);
+	  putchar (' ');
+	  print_mpn_hex (co, (FRAC / 4) + 1);
+	  putchar ('\n');
+	  fputs ("       ", stdout);
+	  print_mpn_hex (s2, (FRAC / 4) + 1);
+	  putchar (' ');
+	  print_mpn_hex (c2, (FRAC / 4) + 1);
+	  putchar ('\n');
+	  printf (" %c%c    ",
+		  s2s-s3s < 54 ? s2s - s3s == 53 ? 'e' : 'F' : 'P',
+		  c2s-c3s < 54 ? c2s - c3s == 53 ? 'e' : 'F' : 'P');
+	  print_mpn_hex (s3, (FRAC / 4) + 1);
+	  putchar (' ');
+	  print_mpn_hex (c3, (FRAC / 4) + 1);
+	  putchar ('\n');
+#endif
+	  sin_errors += s2s - s3s == 53;
+	  cos_errors += c2s - c3s == 53;
+	  sin_failures += s2s - s3s < 53;
+	  cos_failures += c2s - c3s < 53;
+	}
+      if (s3s >= sin_maxerror_s
+	  && mpn_cmp (s3, sin_maxerror, SZ) > 0)
+	{
+	  memcpy (sin_maxerror, s3, sizeof (mp1));
+	  sin_maxerror_s = s3s;
+	}
+      if (c3s >= cos_maxerror_s
+	  && mpn_cmp (c3, cos_maxerror, SZ) > 0)
+	{
+	  memcpy (cos_maxerror, c3, sizeof (mp1));
+	  cos_maxerror_s = c3s;
+	}
+    }
+
+   /* Check Range-Kutta against precomputed values of sin(1) and cos(1).  */
+   memset (x, 0, sizeof (mp1));
+   x[FRAC / mpbpl] = 1 << FRAC % mpbpl;
+   sincosx_mpn (si, co, x, ox);
+
+   memset (s2, 0, sizeof (mp1));
+   memset (c2, 0, sizeof (mp1));
+   for (i = 0; i < 100 && i < FRAC / 4; i++)
+     {
+       s2[(FRAC - i * 4 - 4) / mpbpl] |= (strchr (hexdig, sin1[i]) - hexdig
+					  << (FRAC - i * 4 - 4) % mpbpl);
+       c2[(FRAC - i * 4 - 4) / mpbpl] |= (strchr (hexdig, cos1[i]) - hexdig
+					  << (FRAC - i * 4 - 4) % mpbpl);
+     }
+
+   if (mpn_cmp (si, s2, SZ) >= 0)
+     mpn_sub_n (s3, si, s2, SZ);
+   else
+     mpn_sub_n (s3, s2, si, SZ);
+   if (mpn_cmp (co, c2, SZ) >= 0)
+      mpn_sub_n (c3, co, c2, SZ);
+   else
+     mpn_sub_n (c3, c2, co, SZ);
+
+   printf ("sin:\n");
+   printf ("%d failures; %d errors; error rate %0.2f%%\n",
+	   sin_failures, sin_errors, sin_errors * 100.0 / (double) (1 << N2));
+   fputs ("maximum error:   ", stdout);
+   print_mpn_hex (sin_maxerror, (FRAC / 4) + 1);
+   fputs ("\nerror in sin(1): ", stdout);
+   print_mpn_hex (s3, (FRAC / 4) + 1);
+
+   fputs ("\n\ncos:\n", stdout);
+   printf ("%d failures; %d errors; error rate %0.2f%%\n",
+	   cos_failures, cos_errors, cos_errors * 100.0 / (double) (1 << N2));
+   fputs ("maximum error:   ", stdout);
+   print_mpn_hex (cos_maxerror, (FRAC / 4) + 1);
+   fputs ("\nerror in cos(1): ", stdout);
+   print_mpn_hex (c3, (FRAC / 4) + 1);
+   putchar ('\n');
+
+   return (sin_failures == 0 && cos_failures == 0) ? 0 : 1;
+}
diff --git a/math/libm-test.c b/math/libm-test.c
index a173a09631..da1de8385f 100644
--- a/math/libm-test.c
+++ b/math/libm-test.c
@@ -1003,7 +1003,7 @@ cbrt_test (void)
 	     CHOOSE (5e-18L, 0, 0));
   check_eps ("cbrt (8) == 2", FUNC(cbrt) (8), 2, CHOOSE (5e-17L, 0, 0));
   check_eps ("cbrt (-27) == -3", FUNC(cbrt) (-27.0), -3.0,
-	     CHOOSE (3e-16L, 0, 0));
+	     CHOOSE (3e-16L, 5e-16, 0));
 }
 
 
@@ -1095,7 +1095,7 @@ exp_test (void)
   check_isinfp ("exp (+inf) == +inf", FUNC(exp) (plus_infty));
   check ("exp (-inf) == 0", FUNC(exp) (minus_infty), 0);
 #endif
-  check_eps ("exp (1) == e", FUNC(exp) (1), M_E, CHOOSE (4e-18L, 0, 0));
+  check_eps ("exp (1) == e", FUNC(exp) (1), M_E, CHOOSE (4e-18L, 5e-16, 0));
 }
 
 
@@ -1129,7 +1129,7 @@ expm1_test (void)
 #endif
 
   check_eps ("expm1 (1) == e-1", FUNC(expm1) (1), M_E - 1.0,
-	     CHOOSE (4e-18L, 0, 0));
+	     CHOOSE (4e-18L, 0, 2e-7));
 }
 
 
@@ -4600,7 +4600,7 @@ static void
 inverse_functions (void)
 {
   inverse_func_pair_test ("asin(sin(x)) == x",
-			FUNC(sin), FUNC(asin), 1.0, CHOOSE (2e-18L, 0, 1e-7L));
+			FUNC(sin), FUNC(asin), 1.0, CHOOSE (2e-18L, 0, 3e-7L));
   inverse_func_pair_test ("sin(asin(x)) == x",
 			  FUNC(asin), FUNC(sin), 1.0, 0.0);
 
@@ -4706,14 +4706,14 @@ identities (void)
   identities1_test (-1, CHOOSE (1e-18L, 0, 1e-7));
 
   identities2_test (0.2L, CHOOSE (1e-19L, 1e-16, 0));
-  identities2_test (0.9L, CHOOSE (0, 1e-15, 0));
+  identities2_test (0.9L, CHOOSE (0, 1e-15, 2e-7));
   identities2_test (0, 0);
-  identities2_test (-1, CHOOSE (1e-18L, 1e-15, 0));
+  identities2_test (-1, CHOOSE (1e-18L, 1e-15, 2e-7));
 
   identities3_test (0.2L, CHOOSE (1e-18L, 0, 1e-7));
   identities3_test (0.9L, CHOOSE (1e-18L, 1e-15, 1e-6));
   identities3_test (0, CHOOSE (0, 0, 1e-6));
-  identities3_test (-1, CHOOSE (1e-18L, 0, 1e-6));
+  identities3_test (-1, CHOOSE (1e-18L, 7e-16, 1e-6));
 }
 
 
diff --git a/misc/init-misc.c b/misc/init-misc.c
index e079000494..b62f3921ad 100644
--- a/misc/init-misc.c
+++ b/misc/init-misc.c
@@ -26,11 +26,17 @@ weak_alias (__progname_full, program_invocation_name)
 weak_alias (__progname, program_invocation_short_name)
 
 
-static void __init_misc (int argc, char **argv, char **envp)
+#ifdef HAVE_GNU_LD
+static
+#endif /* HAVE_GNU_LD */
+void __init_misc (int argc, char **argv, char **envp)
   __attribute__ ((unused));
 
 
-static void
+#ifdef HAVE_GNU_LD
+static
+#endif /* HAVE_GNU_LD */
+void
 __init_misc (int argc, char **argv, char **envp)
 {
   if (argv && argv[0])
diff --git a/munch-tmpl.c b/munch-tmpl.c
index 883155d66e..c24eb89787 100644
--- a/munch-tmpl.c
+++ b/munch-tmpl.c
@@ -22,10 +22,7 @@
 EXTERNS
 
 void
-__libc_init (argc, argv, envp)
-     int argc;
-     char **argv;
-     char **envp;
+__libc_init (int argc, char **argv, char **envp)
 {
   CALLS
 
diff --git a/nis/nis_call.c b/nis/nis_call.c
index 1dfb12944a..672755055b 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -151,7 +151,6 @@ __bind_connect (dir_binding *dbp)
 
   if (dbp->use_auth)
     {
-#if defined(HAVE_SECURE_RPC)
       if (serv->key_type == NIS_PK_DH)
 	{
 	  char netname[MAXNETNAMELEN+1];
@@ -168,7 +167,6 @@ __bind_connect (dir_binding *dbp)
 	    dbp->clnt->cl_auth = authunix_create_default ();
 	}
       else
-#endif
 	dbp->clnt->cl_auth = authunix_create_default ();
       dbp->use_auth = TRUE;
     }
diff --git a/nis/nis_intern.h b/nis/nis_intern.h
index fdc392ad7f..9852c24d55 100644
--- a/nis/nis_intern.h
+++ b/nis/nis_intern.h
@@ -52,10 +52,8 @@ 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));
-#if defined (HAVE_SECURE_RPC)
 extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int,
 				     struct sockaddr *, des_block *));
-#endif
 
 /* NIS+ cache */
 extern directory_obj *__cache_search __P ((const_nis_name name));
diff --git a/nis/nss_nis/nis-publickey.c b/nis/nss_nis/nis-publickey.c
index ade09c4127..4c921f4853 100644
--- a/nis/nss_nis/nis-publickey.c
+++ b/nis/nss_nis/nis-publickey.c
@@ -25,10 +25,8 @@
 #include <rpc/rpc.h>
 #include <rpcsvc/yp.h>
 #include <rpcsvc/ypclnt.h>
-#if defined (HAVE_SECURE_RPC)
 #include <rpc/key_prot.h>
 extern int xdecrypt (char *, char *);
-#endif
 
 #include "nss-nis.h"
 
@@ -39,7 +37,7 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
   enum nss_status retval;
   char *domain, *result;
   int len;
-  
+
   pkey[0] = 0;
 
   if (netname == NULL)
@@ -76,7 +74,6 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
 enum nss_status
 _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
 {
-#if defined (HAVE_SECURE_RPC)
   enum nss_status retval;
   char buf[1024];
   char *domain, *result;
@@ -122,9 +119,6 @@ _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
       buf[HEXKEYBYTES] = 0;
       strcpy (skey, buf);
     }
-#else
-  skey[0] = 0;
-#endif
   return NSS_STATUS_SUCCESS;
 }
 
diff --git a/nis/nss_nisplus/nisplus-alias.c b/nis/nss_nisplus/nisplus-alias.c
index 8d682d785c..f074c5fa63 100644
--- a/nis/nss_nisplus/nisplus-alias.c
+++ b/nis/nss_nisplus/nisplus-alias.c
@@ -48,9 +48,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "mail_aliases.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "mail_aliases.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c
index cfdb3dc4e1..b21c276df2 100644
--- a/nis/nss_nisplus/nisplus-ethers.c
+++ b/nis/nss_nisplus/nisplus-ethers.c
@@ -92,9 +92,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "ethers.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "ethers.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
@@ -267,10 +267,10 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr,
       char buf[255 + tablename_len];
 
       memset (&buf, '\0', sizeof (buf));
-      snprintf(buf, sizeof (buf), "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir",
-	       addr->ether_addr_octet[0], addr->ether_addr_octet[1],
-	       addr->ether_addr_octet[2], addr->ether_addr_octet[3],
-	       addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
+      sprintf(buf, "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir",
+	      addr->ether_addr_octet[0], addr->ether_addr_octet[1],
+	      addr->ether_addr_octet[2], addr->ether_addr_octet[3],
+	      addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
 
       result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c
index 1031d69ac9..fb200321d2 100644
--- a/nis/nss_nisplus/nisplus-grp.c
+++ b/nis/nss_nisplus/nisplus-grp.c
@@ -43,9 +43,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "group.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "group.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c
index 89a8bf7564..7fefec0fd3 100644
--- a/nis/nss_nisplus/nisplus-hosts.c
+++ b/nis/nss_nisplus/nisplus-hosts.c
@@ -98,8 +98,8 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
   if (NISENTRYLEN (0, 0, result) + 1 > room_left)
     goto no_more_room;
 
-  p = stpncpy (first_unused, NISENTRYVAL (0, 0, result),
-	       NISENTRYLEN (0, 0, result));
+  p = __stpncpy (first_unused, NISENTRYVAL (0, 0, result),
+		 NISENTRYLEN (0, 0, result));
   *p = '\0';
   room_left -= (NISENTRYLEN (0, 0, result) + 1);
   host->h_name = first_unused;
@@ -115,8 +115,8 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
 	    goto no_more_room;
 
 	  *p++ = ' ';
-	  p = stpncpy (p, NISENTRYVAL (i, 1, result),
-		       NISENTRYLEN (i, 1, result));
+	  p = __stpncpy (p, NISENTRYVAL (i, 1, result),
+			 NISENTRYLEN (i, 1, result));
 	  *p = '\0';
 	  room_left -= (NISENTRYLEN (i, 1, result) + 1);
 	}
@@ -176,9 +176,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "hosts.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "hosts.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
@@ -415,7 +415,7 @@ _nss_nisplus_gethostbyaddr_r (const char *addr, int addrlen, int type,
       char buf[255 + tablename_len];
       int retval, parse_res;
 
-      snprintf(buf, sizeof (buf) -1, "[addr=%s],%s",
+      sprintf (buf, "[addr=%s],%s",
 	       inet_ntoa (*(struct in_addr *)addr), tablename_val);
       result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
diff --git a/nis/nss_nisplus/nisplus-netgrp.c b/nis/nss_nisplus/nisplus-netgrp.c
index 967eec898c..2a2f4b5ec9 100644
--- a/nis/nss_nisplus/nisplus-netgrp.c
+++ b/nis/nss_nisplus/nisplus-netgrp.c
@@ -92,8 +92,8 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
       else
 	{
 	  result->val.triple.host = cp;
-	  cp = stpncpy (cp, NISENTRYVAL (position, 2, data),
-			NISENTRYLEN (position, 2, data));
+	  cp = __stpncpy (cp, NISENTRYVAL (position, 2, data),
+			  NISENTRYLEN (position, 2, data));
 	  *cp = '\0';
 	  ++cp;
 	}
@@ -103,8 +103,8 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
       else
 	{
 	  result->val.triple.user = cp;
-	  cp = stpncpy (cp, NISENTRYVAL (position, 3, data),
-			NISENTRYLEN (position, 3, data));
+	  cp = __stpncpy (cp, NISENTRYVAL (position, 3, data),
+			  NISENTRYLEN (position, 3, data));
 	  *cp = '\0';
 	  ++cp;
 	}
@@ -114,8 +114,8 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
       else
 	{
 	  result->val.triple.domain = cp;
-	  cp = stpncpy (cp, NISENTRYVAL (position, 4, data),
-			NISENTRYLEN (position, 4, data));
+	  cp = __stpncpy (cp, NISENTRYVAL (position, 4, data),
+			  NISENTRYLEN (position, 4, data));
 	  *cp = '\0';
 	}
 
diff --git a/nis/nss_nisplus/nisplus-network.c b/nis/nss_nisplus/nisplus-network.c
index ff71af8573..8aa8bc0f9e 100644
--- a/nis/nss_nisplus/nisplus-network.c
+++ b/nis/nss_nisplus/nisplus-network.c
@@ -87,8 +87,8 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
 	    goto no_more_room;
 
 	  *p++ = ' ';
-          p = stpncpy (p, NISENTRYVAL (i, 1, result),
-                       NISENTRYLEN (i, 1, result));
+          p = __stpncpy (p, NISENTRYVAL (i, 1, result),
+			 NISENTRYLEN (i, 1, result));
           *p = '\0';
           room_left -= (NISENTRYLEN (i, 1, result) + 1);
         }
@@ -149,9 +149,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "networks.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "networks.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
@@ -366,8 +366,7 @@ _nss_nisplus_getnetbyaddr_r (const unsigned long addr, const int type,
     struct in_addr in;
 
     in = inet_makeaddr (addr, 0);
-    snprintf(buf, sizeof (buf) - 1, "[addr=%s],%s",
-	     inet_ntoa (in), tablename_len);
+    sprintf (buf, "[addr=%s],%s", inet_ntoa (in), tablename_val);
 
     result = nis_list(buf, EXPAND_NAME, NULL, NULL);
 
diff --git a/nis/nss_nisplus/nisplus-proto.c b/nis/nss_nisplus/nisplus-proto.c
index ddfce86905..b64d4bdd02 100644
--- a/nis/nss_nisplus/nisplus-proto.c
+++ b/nis/nss_nisplus/nisplus-proto.c
@@ -85,8 +85,8 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
           if (NISENTRYLEN (i, 1, result) + 2 > room_left)
             goto no_more_room;
 	  *p++ = ' ';
-          p = stpncpy (p, NISENTRYVAL (i, 1, result),
-                       NISENTRYLEN (i, 1, result));
+          p = __stpncpy (p, NISENTRYVAL (i, 1, result),
+			 NISENTRYLEN (i, 1, result));
           *p = '\0';
           room_left -= (NISENTRYLEN (i, 1, result) + 1);
         }
@@ -143,9 +143,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "protocols.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "protocols.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
@@ -327,7 +327,7 @@ _nss_nisplus_getprotobynumber_r (const int number, struct protoent *proto,
     nis_result *result;
     char buf[46 + tablename_len];
 
-    snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
+    sprintf (buf, "[number=%d],%s", number, tablename_val);
 
     result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c
index 99ec2a08ec..72ed1a5044 100644
--- a/nis/nss_nisplus/nisplus-publickey.c
+++ b/nis/nss_nisplus/nisplus-publickey.c
@@ -25,10 +25,8 @@
 #include <syslog.h>
 #include <rpc/rpc.h>
 #include <rpcsvc/nis.h>
-#ifdef HAVE_SECURE_RPC
 #include <rpc/key_prot.h>
 extern int xdecrypt (char *, char *);
-#endif
 
 #include <nss-nisplus.h>
 
@@ -107,7 +105,6 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
 enum nss_status
 _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
 {
-#ifdef HAVE_SECURE_RPC
   nis_result *res;
   enum nss_status retval;
   char buf[NIS_MAXNAMELEN+2];
@@ -179,9 +176,6 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
 
   buf[HEXKEYBYTES] = 0;
   strcpy (skey, buf);
-#else
-  skey[0] = 0;
-#endif
 
   return NSS_STATUS_SUCCESS;
 }
diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c
index e358b060e1..3974defa47 100644
--- a/nis/nss_nisplus/nisplus-pwd.c
+++ b/nis/nss_nisplus/nisplus-pwd.c
@@ -43,9 +43,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "passwd.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "passwd.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
diff --git a/nis/nss_nisplus/nisplus-rpc.c b/nis/nss_nisplus/nisplus-rpc.c
index 6682a7502a..e93a51652e 100644
--- a/nis/nss_nisplus/nisplus-rpc.c
+++ b/nis/nss_nisplus/nisplus-rpc.c
@@ -82,8 +82,8 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
           if (NISENTRYLEN (i, 1, result) + 2 > room_left)
 	    goto no_more_room;
 	  *p++ = ' ';
-          p = stpncpy (p, NISENTRYVAL (i, 1, result),
-                       NISENTRYLEN (i, 1, result));
+          p = __stpncpy (p, NISENTRYVAL (i, 1, result),
+			 NISENTRYLEN (i, 1, result));
           *p = '\0';
           room_left -= (NISENTRYLEN (i, 1, result) + 1);
         }
@@ -144,9 +144,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "rpc.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "rpc.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
@@ -329,7 +329,7 @@ _nss_nisplus_getrpcbynumber_r (const int number, struct rpcent *rpc,
     nis_result *result;
     char buf[100 + tablename_len];
 
-    snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
+    sprintf (buf, "[number=%d],%s", number, tablename_val);
 
     result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
diff --git a/nis/nss_nisplus/nisplus-service.c b/nis/nss_nisplus/nisplus-service.c
index e8a12145d3..e1a89f92be 100644
--- a/nis/nss_nisplus/nisplus-service.c
+++ b/nis/nss_nisplus/nisplus-service.c
@@ -91,8 +91,8 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
           if (NISENTRYLEN (i, 1, result) + 2 > room_left)
             goto no_more_room;
 	  *p++ = ' ';
-          p = stpncpy (p, NISENTRYVAL (i, 1, result),
-                       NISENTRYLEN (i, 1, result));
+          p = __stpncpy (p, NISENTRYVAL (i, 1, result),
+			 NISENTRYLEN (i, 1, result));
           *p = '\0';
           room_left -= (NISENTRYLEN (i, 1, result) + 1);
         }
@@ -150,9 +150,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "services.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "services.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
@@ -348,8 +348,8 @@ _nss_nisplus_getservbynumber_r (const int number, const char *protocol,
       nis_result *result;
       char buf[60 + strlen (protocol) + tablename_len];
 
-      snprintf (buf, sizeof (buf), "[number=%d,proto=%s],%s",
-		number, protocol, tablename_val);
+      sprintf (buf, "[number=%d,proto=%s],%s",
+	       number, protocol, tablename_val);
 
       result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
diff --git a/nis/nss_nisplus/nisplus-spwd.c b/nis/nss_nisplus/nisplus-spwd.c
index 507aa4bcad..1b3f68325e 100644
--- a/nis/nss_nisplus/nisplus-spwd.c
+++ b/nis/nss_nisplus/nisplus-spwd.c
@@ -41,9 +41,9 @@ _nss_create_tablename (void)
       char buf [40 + strlen (nis_local_directory ())];
       char *p;
 
-      p = stpcpy (buf, "passwd.org_dir.");
-      p = stpcpy (p, nis_local_directory ());
-      tablename_val = strdup (buf);
+      p = __stpcpy (buf, "passwd.org_dir.");
+      p = __stpcpy (p, nis_local_directory ());
+      tablename_val = __strdup (buf);
       if (tablename_val == NULL)
         return NSS_STATUS_TRYAGAIN;
       tablename_len = strlen (tablename_val);
diff --git a/nis/ypclnt.c b/nis/ypclnt.c
index 7c9efec70a..c8db8a8813 100644
--- a/nis/ypclnt.c
+++ b/nis/ypclnt.c
@@ -21,6 +21,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <bits/libc-lock.h>
+#include <rpc/auth.h>
 #include <rpc/rpc.h>
 #include <rpcsvc/nis.h>
 #include <rpcsvc/yp.h>
@@ -627,7 +628,7 @@ yp_all (const char *indomain, const char *inmap,
       clnt = clnttcp_create (&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
       if (clnt == NULL)
 	{
-	  puts ("yp_all: clnttcp_create failed");
+	  puts (_("yp_all: clnttcp_create failed"));
 	  __libc_lock_unlock (ypbindlist_lock);
 	  return YPERR_PMAP;
 	}
@@ -787,7 +788,6 @@ int
 yp_update (char *domain, char *map, unsigned ypop,
 	   char *key, int keylen, char *data, int datalen)
 {
-#if defined (HAVE_SECURE_RPC)
   union
     {
       ypupdate_args update_args;
@@ -872,7 +872,4 @@ again:
       return YPERR_RPC;
     }
   return res;
-#else
-  return YPERR_YPERR;
-#endif
 }
diff --git a/nss/libnss_files.map b/nss/libnss_files.map
index 07e5c9aabb..3e030012d4 100644
--- a/nss/libnss_files.map
+++ b/nss/libnss_files.map
@@ -1,27 +1,73 @@
 GLIBC_2.0 {
   global:
-    _nss_files_endaliasent; _nss_files_endetherent; _nss_files_endgrent;
-    _nss_files_endhostent; _nss_files_endnetent; _nss_files_endnetgrent;
-    _nss_files_endprotoent; _nss_files_endpwent; _nss_files_endrpcent;
-    _nss_files_endservent; _nss_files_endspent; _nss_files_getaliasbyname_r;
-    _nss_files_getaliasent_r; _nss_files_getetherent_r; _nss_files_getgrent_r;
-    _nss_files_getgrgid_r; _nss_files_getgrnam_r; _nss_files_gethostbyaddr_r;
-    _nss_files_gethostbyname2_r; _nss_files_gethostbyname_r;
-    _nss_files_gethostent_r; _nss_files_gethostton_r;
-    _nss_files_getnetbyaddr_r; _nss_files_getnetbyname_r;
-    _nss_files_getnetent_r; _nss_files_getnetgrent_r; _nss_files_getntohost_r;
-    _nss_files_getprotobyname_r; _nss_files_getprotobynumber_r;
-    _nss_files_getprotoent_r; _nss_files_getpwent_r; _nss_files_getpwnam_r;
-    _nss_files_getpwuid_r; _nss_files_getrpcbyname_r;
-    _nss_files_getrpcbynumber_r; _nss_files_getrpcent_r;
-    _nss_files_getservbyname_r; _nss_files_getservbyport_r;
-    _nss_files_getservent_r; _nss_files_getspent_r; _nss_files_getspnam_r;
-    _nss_files_parse_etherent; _nss_files_parse_netent;
-    _nss_files_parse_protoent; _nss_files_parse_rpcent;
-    _nss_files_parse_servent; _nss_files_setaliasent; _nss_files_setetherent;
-    _nss_files_setgrent; _nss_files_sethostent; _nss_files_setnetent;
-    _nss_files_setnetgrent; _nss_files_setprotoent; _nss_files_setpwent;
-    _nss_files_setrpcent; _nss_files_setservent; _nss_files_setspent;
+    _nss_files_setaliasent;
+    _nss_files_endaliasent;
+    _nss_files_getaliasbyname_r;
+    _nss_files_getaliasent_r;
+
+    _nss_files_setetherent;
+    _nss_files_endetherent;
+    _nss_files_getetherent_r;
+    _nss_files_parse_etherent;
+
+    _nss_files_setgrent;
+    _nss_files_endgrent;
+    _nss_files_getgrent_r;
+    _nss_files_getgrgid_r;
+    _nss_files_getgrnam_r;
+
+    _nss_files_sethostent;
+    _nss_files_endhostent;
+    _nss_files_gethostbyaddr_r;
+    _nss_files_gethostbyname2_r;
+    _nss_files_gethostbyname_r;
+    _nss_files_gethostent_r;
+    _nss_files_gethostton_r;
+
+    _nss_files_setnetent;
+    _nss_files_endnetent;
+    _nss_files_getnetbyaddr_r;
+    _nss_files_getnetbyname_r;
+    _nss_files_getnetent_r;
+    _nss_files_getntohost_r;
+    _nss_files_parse_netent;
+
+    _nss_files_setnetgrent;
+    _nss_files_endnetgrent;
+    _nss_files_getnetgrent_r;
+
+    _nss_files_setprotoent;
+    _nss_files_endprotoent;
+    _nss_files_getprotobyname_r;
+    _nss_files_getprotobynumber_r;
+    _nss_files_getprotoent_r;
+    _nss_files_parse_protoent;
+
+    _nss_files_setpwent;
+    _nss_files_endpwent;
+    _nss_files_getpwent_r;
+    _nss_files_getpwnam_r;
+    _nss_files_getpwuid_r;
+
+    _nss_files_setrpcent;
+    _nss_files_endrpcent;
+    _nss_files_getrpcbyname_r;
+    _nss_files_getrpcbynumber_r;
+    _nss_files_getrpcent_r;
+    _nss_files_parse_rpcent;
+
+    _nss_files_setservent;
+    _nss_files_endservent;
+    _nss_files_getservbyname_r;
+    _nss_files_getservbyport_r;
+    _nss_files_getservent_r;
+    _nss_files_parse_servent;
+
+    _nss_files_setspent;
+    _nss_files_endspent;
+    _nss_files_getspent_r;
+    _nss_files_getspnam_r;
+
     _nss_netgroup_parseline;
 
   local:
diff --git a/po/Makefile b/po/Makefile
index 32cdc2d530..20221cb727 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -66,6 +66,9 @@ $(mo-installed): %.mo; $(do-install)
 .PHONY: linguas linguas.mo
 linguas: $(ALL_LINGUAS:=.po)
 linguas.mo: $(ALL_LINGUAS:=.mo)
+
+realclean:
+	rm -f $(ALL_LINGUAS:=.mo)
 
 # Copy the PO files from the translation coordinator's repository.
 
diff --git a/posix/getopt.c b/posix/getopt.c
index c5574eab69..8f639ebed1 100644
--- a/posix/getopt.c
+++ b/posix/getopt.c
@@ -76,7 +76,7 @@
 #endif
 #endif
 
-#if defined (_WINDOWS32) && !defined (__CYGWIN32__)
+#if defined (WINDOWS32) && !defined (__CYGWIN32__)
 /* It's not Unix, really.  See?  Capital letters.  */
 #include <windows.h>
 #define getpid() GetCurrentProcessId()
@@ -273,7 +273,9 @@ store_args_and_env (int argc, char *const *argv)
   original_argc = argc;
   original_argv = argv;
 }
+# ifdef text_set_element
 text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
 
 # define SWAP_FLAGS(ch1, ch2) \
   if (nonoption_flags_len > 0)						      \
diff --git a/posix/unistd.h b/posix/unistd.h
index 69371001c6..f4a331bce3 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -433,6 +433,7 @@ extern __pid_t __bsd_getpgrp __P ((__pid_t __pid));
 /* Set the process group ID of the process matching PID to PGID.
    If PID is zero, the current process's process group ID is set.
    If PGID is zero, the process ID of the process is used.  */
+extern int __setpgid __P ((__pid_t __pid, __pid_t __pgid));
 extern int setpgid __P ((__pid_t __pid, __pid_t __pgid));
 
 /* Get the process group ID of process PID.  */
@@ -705,6 +706,8 @@ extern int revoke __P ((__const char *__file));
    is enabled, the system examines the user PC and increments
    SAMPLE_BUFFER[((PC - OFFSET) / 2) * SCALE / 65536].  If SCALE is zero,
    disable profiling.  Returns zero on success, -1 on error.  */
+extern int __profil __P ((unsigned short int *__sample_buffer, size_t __size,
+			  size_t __offset, unsigned int __scale));
 extern int profil __P ((unsigned short int *__sample_buffer, size_t __size,
 			size_t __offset, unsigned int __scale));
 
diff --git a/resolv/res_send.c b/resolv/res_send.c
index cde6a845d5..a4d242e8aa 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -468,7 +468,7 @@ read_len:
 				while (len != 0) {
 					char junk[PACKETSZ];
 
-					n = (len > sizeof(junk)
+					n = ((size_t) len > sizeof(junk)
 					     ? sizeof(junk)
 					     : len);
 					if ((n = read(s, junk, n)) > 0)
diff --git a/stdio/fgets.c b/stdio/fgets.c
index 03246fb30c..3d6833d089 100644
--- a/stdio/fgets.c
+++ b/stdio/fgets.c
@@ -30,7 +30,7 @@ char *
 fgets (s, n, stream)
      char *s;
      int n;
-     register FILE *stream;
+     FILE *stream;
 {
   register char *p = s;
 
@@ -98,7 +98,7 @@ fgets (s, n, stream)
 	  i = stream->__get_limit - stream->__bufp;
 	}
 
-      if (i > n)
+      if (i > (size_t) n)
 	i = n;
 
       found = (char *) __memccpy ((void *) p, stream->__bufp, '\n', i);
diff --git a/stdio/glue.c b/stdio/glue.c
index d3618aef93..b184524c82 100644
--- a/stdio/glue.c
+++ b/stdio/glue.c
@@ -73,8 +73,7 @@ unix_FILE _iob[] =
    In a Unix stdio FILE `_cnt' is the first element.
    In a GNU stdio or glued FILE, the first element is the magic number.  */
 int
-_filbuf (file)
-     unix_FILE *file;
+_filbuf (unix_FILE *file)
 {
   switch (++file->glue.magic)	/* Compensate for Unix getc's decrement.  */
     {
@@ -95,9 +94,7 @@ _filbuf (file)
 
 /* Called by the Unix stdio `putc' macro.  Much like getc, above.  */
 int
-_flsbuf (c, file)
-     int c;
-     unix_FILE *file;
+_flsbuf (int c, unix_FILE *file)
 {
   /* Compensate for putc's decrement.  */
   switch (++file->glue.magic)
diff --git a/stdio/internals.c b/stdio/internals.c
index 290e3fdf87..96151c1f67 100644
--- a/stdio/internals.c
+++ b/stdio/internals.c
@@ -238,7 +238,7 @@ flushbuf (register FILE *fp, int c)
 	      else
 		__clearerr (fp);
 
-	      if (fp->__get_limit - fp->__buffer < o)
+	      if ((size_t) (fp->__get_limit - fp->__buffer) < o)
 		/* Oops.  We didn't read enough (probably because we got EOF).
 		   Forget we even mentioned it.  */
 		fp->__target += o;
@@ -280,7 +280,7 @@ flushbuf (register FILE *fp, int c)
 	    }
 	}
 
-      if (fp->__bufp - fp->__buffer <= buffer_offset && flush_only)
+      if ((size_t) (fp->__bufp - fp->__buffer) <= buffer_offset && flush_only)
 	{
 	  /* There is nothing new in the buffer, only data that
 	     was read back aligned from the file.  */
diff --git a/stdio/linewrap.c b/stdio/linewrap.c
index a5822c4845..d91f3a4bc2 100644
--- a/stdio/linewrap.c
+++ b/stdio/linewrap.c
@@ -169,7 +169,7 @@ lwupdate (FILE *stream, int c, struct line_wrap_data **wrapper_cookie)
 	       the end of the buffer.  */
 	    nl = stream->__bufp;
 	}
-      else if (d->point_col + (nl - buf) < d->rmargin)
+      else if ((size_t) d->point_col + (nl - buf) < d->rmargin)
 	{
 	  /* The buffer contains a full line that fits within the maximum
 	     line width.  Reset point and scan the next line.  */
diff --git a/stdio/memstream.c b/stdio/memstream.c
index cfac39f24d..fe2ce0a572 100644
--- a/stdio/memstream.c
+++ b/stdio/memstream.c
@@ -39,7 +39,7 @@ enlarge_buffer (register FILE *stream, int c)
     *info->bufsize = stream->__bufp - stream->__buffer;
 
   if (stream->__target != -1
-      && stream->__target > *info->bufsize)
+      && (size_t) stream->__target > *info->bufsize)
     /* Our target (where the buffer maps to) is always zero except when
        the user just did a SEEK_END fseek.  If he sought within the
        buffer, we need do nothing and will zero the target below.  If he
diff --git a/stdio/obstream.c b/stdio/obstream.c
index f9384bd597..f61e80909b 100644
--- a/stdio/obstream.c
+++ b/stdio/obstream.c
@@ -24,9 +24,7 @@
 /* Output-room function for obstack streams.  */
 
 static void
-grow (stream, c)
-     FILE *stream;
-     int c;
+grow (FILE *stream, int c)
 {
   struct obstack *const obstack = (struct obstack *) stream->__cookie;
 
@@ -34,7 +32,7 @@ grow (stream, c)
      of the buffer which the user has already written into.  */
   obstack_blank_fast (obstack, - (stream->__put_limit - stream->__bufp));
 
-  if (stream->__target > obstack_object_size (obstack))
+  if ((size_t) stream->__target > obstack_object_size (obstack))
     {
       /* Our target (where the buffer maps to) is always zero except when
 	 the user just did a SEEK_END fseek.  If he sought within the
@@ -83,10 +81,7 @@ grow (stream, c)
    There is no external state to munge.  */
 
 static int
-seek (cookie, pos, whence)
-     void *cookie;
-     fpos_t *pos;
-     int whence;
+seek (void *cookie, fpos_t *pos, int whence)
 {
   switch (whence)
     {
@@ -110,8 +105,7 @@ seek (cookie, pos, whence)
    Only what has been written to the stream can be read back.  */
 
 static int
-input (stream)
-     FILE *stream;
+input (FILE *stream)
 {
   /* Re-sync with the obstack, growing the object if necessary.  */
   grow (stream, EOF);
@@ -126,9 +120,7 @@ input (stream)
 /* Initialize STREAM to talk to OBSTACK.  */
 
 static void
-init_obstream (stream, obstack)
-      FILE *stream;
-      struct obstack *obstack;
+init_obstream (FILE *stream, struct obstack *obstack)
 {
   stream->__mode.__write = 1;
   stream->__mode.__read = 1;
diff --git a/stdio/stdio.h b/stdio/stdio.h
index c443ecd795..80132879de 100644
--- a/stdio/stdio.h
+++ b/stdio/stdio.h
@@ -423,28 +423,38 @@ vprintf (const char *__restrict __fmt, __gnuc_va_list __arg)
 }
 #endif /* Optimizing.  */
 
-#ifdef	__USE_GNU
+#if defined __USE_BSD || defined __USE_ISOC9X
 /* Maximum chars of output to write in MAXLEN.  */
 extern int __snprintf __P ((char *__s, size_t __maxlen,
-			    __const char *__format, ...));
+			    __const char *__format, ...))
+     __attribute__ ((__format__ (__printf__, 3, 4)));
 extern int snprintf __P ((char *__s, size_t __maxlen,
-			  __const char *__format, ...));
+			  __const char *__format, ...))
+     __attribute__ ((__format__ (__printf__, 3, 4)));
 
 extern int __vsnprintf __P ((char *__s, size_t __maxlen,
-			     __const char *__format, __gnuc_va_list __arg));
+			     __const char *__format, __gnuc_va_list __arg))
+     __attribute__ ((__format__ (__printf__, 3, 0)));
 extern int vsnprintf __P ((char *__s, size_t __maxlen,
-			   __const char *__format, __gnuc_va_list __arg));
+			   __const char *__format, __gnuc_va_list __arg))
+     __attribute__ ((__format__ (__printf__, 3, 0)));
+#endif
 
+#ifdef __USE_GNU
 /* Write formatted output to a string dynamically allocated with `malloc'.
    Store the address of the string in *PTR.  */
 extern int vasprintf __P ((char **__ptr, __const char *__f,
-			   __gnuc_va_list __arg));
-extern int asprintf __P ((char **__ptr, __const char *__fmt, ...));
+			   __gnuc_va_list __arg))
+     __attribute__ ((__format__ (__printf__, 2, 0)));
+extern int asprintf __P ((char **__ptr, __const char *__fmt, ...))
+     __attribute__ ((__format__ (__printf__, 2, 0)));
 
 /* Write formatted output to a file descriptor.  */
 extern int vdprintf __P ((int __fd, __const char *__fmt,
-			  __gnuc_va_list __arg));
-extern int dprintf __P ((int __fd, __const char *__fmt, ...));
+			  __gnuc_va_list __arg))
+     __attribute__ ((__format__ (__printf__, 2, 0)));
+extern int dprintf __P ((int __fd, __const char *__fmt, ...))
+     __attribute__ ((__format__ (__printf__, 2, 0)));
 #endif
 
 
diff --git a/stdio/vasprintf.c b/stdio/vasprintf.c
index 47a074e6ca..ffcf3eb972 100644
--- a/stdio/vasprintf.c
+++ b/stdio/vasprintf.c
@@ -26,9 +26,7 @@
 
 /* Enlarge STREAM's buffer.  */
 static void
-enlarge_buffer (stream, c)
-     FILE *stream;
-     int c;
+enlarge_buffer (FILE *stream, int c)
 {
   ptrdiff_t bufp_offset = stream->__bufp - stream->__buffer;
   char *newbuf;
diff --git a/string/Makefile b/string/Makefile
index ac04557ddc..8596bc1b24 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -30,7 +30,7 @@ routines	:= strcat strchr strcmp strcoll strcpy strcspn		\
 		   strncat strncmp strncpy				\
 		   strrchr strpbrk strsignal strspn strstr strtok	\
 		   strtok_r strxfrm memchr memcmp memmove memset	\
-		   bcopy bzero ffs stpcpy stpncpy			\
+		   mempcpy bcopy bzero ffs stpcpy stpncpy		\
 		   strcasecmp strncase strcasecmp_l strncase_l		\
 		   memccpy memcpy wordcopy strsep			\
 		   swab strfry memfrob memmem				\
@@ -40,17 +40,19 @@ routines	:= strcat strchr strcmp strcoll strcpy strcspn		\
 		   envz basename					\
 		   strcoll_l strxfrm_l
 
-tests		:= tester testcopy test-ffs tst-strlen stratcliff \
-	           tst-svc
+tests		:= tester inl-tester testcopy test-ffs tst-strlen	\
+		   stratcliff tst-svc
 distribute	:= memcopy.h pagecopy.h tst-svc.expect
 
 
 include ../Rules
 
 tester-ENV = LANGUAGE=C
-CFLAGS-tester.c = -fno-builtin -D__NO_STRING_INLINES
-CFLAGS-tst-strlen.c = -fno-builtin -D__NO_STRING_INLINES
-CFLAGS-stratcliff.c = -fno-builtin -D__NO_STRING_INLINES
+inl-tester-ENV = LANGUAGE=C
+CFLAGS-tester.c = -fno-builtin
+CFLAGS-inl-tester.c = -fno-builtin
+CFLAGS-tst-strlen.c = -fno-builtin
+CFLAGS-stratcliff.c = -fno-builtin
 
 tests: $(objpfx)tst-svc.out
 	cmp tst-svc.expect $(objpfx)tst-svc.out
diff --git a/string/bits/string2.h b/string/bits/string2.h
new file mode 100644
index 0000000000..b943fe9aa0
--- /dev/null
+++ b/string/bits/string2.h
@@ -0,0 +1,292 @@
+/* Machine-independant string function optimizations.
+   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
+   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.  */
+
+#ifndef _BITS_STRING2_H
+#define _BITS_STRING2_H	1
+
+/* Unlike the definitions in the header <bits/string.h> the
+   definitions contained here are not optimizing down to assembler
+   level.  These optimizations are not always a good idea since this
+   means the code size increases a lot.  Instead the definitions here
+   optimize some functions in a way which does not dramatically
+   increase the code size and which does not use assembler.  The main
+   trick is to use GNU CC's `__builtin_constant_p' function.
+
+   Every function XXX which has a defined version in
+   <bits/string.h> must be accompanied by a have _HAVE_STRING_ARCH_XXX
+   to make sure we don't get redefinitions.
+
+   We must use here macros instead of inline functions since the
+   trick won't work with the later.  */
+
+#ifdef __cplusplus
+# define __STRING_INLINE inline
+#else
+# define __STRING_INLINE extern __inline
+#endif
+
+/* We need some more types.  */
+#include <bits/types.h>
+
+
+/* Copy SRC to DEST.  */
+#ifndef _HAVE_STRING_ARCH_strcpy
+# define strcpy(dest, src) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? (strlen (src) + 1 <= 8				      \
+		     ? __strcpy_small (dest, src, strlen (src) + 1)	      \
+		     : (char *) memcpy (dest, src, strlen (src) + 1))	      \
+		  : strcpy (dest, src)))
+
+__STRING_INLINE char *
+__strcpy_small (char *__dest, __const char *__src, size_t __srclen)
+{
+  register char *__tmp = __dest;
+  switch (__srclen)
+    {
+    case 7:
+      *((__uint16_t *) __tmp)++ = *((__uint16_t *) __src)++;
+    case 5:
+      *((__uint32_t *) __tmp)++ = *((__uint32_t *) __src)++;
+      *((unsigned char *) __tmp) = '\0';
+      break;
+
+    case 8:
+      *((__uint32_t *) __tmp)++ = *((__uint32_t *) __src)++;
+    case 4:
+      *((__uint32_t *) __tmp) = *((__uint32_t *) __src);
+      break;
+
+    case 6:
+      *((__uint32_t *) __tmp)++ = *((__uint32_t *) __src)++;
+    case 2:
+      *((__uint16_t *) __tmp) = *((__uint16_t *) __src);
+      break;
+
+    case 3:
+      *((__uint16_t *) __tmp)++ = *((__uint16_t *) __src)++;
+    case 1:
+      *((unsigned char *) __tmp) = '\0';
+      break;
+
+    default:
+      break;
+    }
+  return __dest;
+}
+#endif
+
+
+/* Copy SRC to DEST, returning pointer to final NUL byte.  */
+#ifdef __USE_GNU
+# ifndef _HAVE_STRING_ARCH_stpcpy
+#  define __stpcpy(dest, src) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? (strlen (src) + 1 <= 8				      \
+		     ? __stpcpy_small (dest, src, strlen (src) + 1)	      \
+		     : ((char *) __mempcpy (dest, src, strlen (src) + 1) - 1))\
+		  : __stpcpy (dest, src)))
+/* In glibc we use this function frequently but for namespace reasons
+   we have to use the name `__stpcpy'.  */
+#  define stpcpy(dest, src) __stpcpy (dest, src)
+
+__STRING_INLINE char *
+__stpcpy_small (char *__dest, __const char *__src, size_t __srclen)
+{
+  register char *__tmp = __dest;
+  switch (__srclen)
+    {
+    case 7:
+      *((__uint16_t *) __tmp)++ = *((__uint16_t *) __src)++;
+    case 5:
+      *((__uint32_t *) __tmp)++ = *((__uint32_t *) __src)++;
+      *((unsigned char *) __tmp) = '\0';
+      return __tmp;
+
+    case 8:
+      *((__uint32_t *) __tmp)++ = *((__uint32_t *) __src)++;
+    case 4:
+      *((__uint32_t *) __tmp) = *((__uint32_t *) __src);
+      return __tmp + 3;
+
+    case 6:
+      *((__uint32_t *) __tmp)++ = *((__uint32_t *) __src)++;
+    case 2:
+      *((__uint16_t *) __tmp) = *((__uint16_t *) __src);
+      return __tmp + 1;
+
+    case 3:
+      *((__uint16_t *) __tmp)++ = *((__uint16_t *) __src)++;
+    case 1:
+      *((unsigned char *) __tmp) = '\0';
+      return __tmp;
+
+    default:
+      break;
+    }
+  /* This should never happen.  */
+  return NULL;
+}
+# endif
+#endif
+
+
+/* Copy no more than N characters of SRC to DEST.  */
+#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)),			      \
+			dest))						      \
+		  : strncpy (dest, src, n)))
+# else
+#  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)			      \
+		     : strncpy (dest, src, n))				      \
+		  : strncpy (dest, src, n)))
+# endif
+#endif
+
+
+/* Append no more than N characters from SRC onto DEST.  */
+#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), dest))	      \
+		  : strncat (dest, src, n)))
+# else
+#  define strncat(dest, src, n) \
+  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
+		  ? (strlen (src) < ((size_t) (n))			      \
+		     ? strcat (dest, src)				      \
+		     : strncat (dest, src, n))				      \
+		  : strncat (dest, src, n)))
+# endif
+#endif
+
+
+/* Compare N characters of S1 and S2.  */
+#ifndef _HAVE_STRING_ARCH_strncmp
+# define strncmp(s1, s2, n) \
+  (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n))   \
+		  ? strcmp (s1, s2)					      \
+		  : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
+		     ? strcmp (s1, s2)					      \
+		     : strncmp (s1, s2, n))))
+#endif
+
+
+/* Return the length of the initial segment of S which
+   consists entirely of characters not in REJECT.  */
+#ifndef _HAVE_STRING_ARCH_strcspn
+# define strcspn(s, reject) \
+  (__extension__ (__builtin_constant_p (reject)				      \
+		  ? (((const char *) (reject))[0] == '\0'		      \
+		     ? strlen (s)					      \
+		     : (((const char *) (reject))[1] == '\0'		      \
+			? __strcspn_c1 (s, ((((const char *) (reject))[0]     \
+					     & 0xff) << 8))		      \
+			: strcspn (s, reject)))	      \
+		  : strcspn (s, reject)))
+
+__STRING_INLINE size_t
+__strcspn_c1 (__const char *__s, char __reject)
+{
+  register size_t __result = 0;
+  while (__s[__result] != '\0' && __s[__result] != __reject)
+    ++__result;
+  return __result;
+}
+#endif
+
+
+/* Return the length of the initial segment of S which
+   consists entirely of characters in ACCEPT.  */
+#ifndef _HAVE_STRING_ARCH_strspn
+# define strspn(s, accept) \
+  (__extension__ (__builtin_constant_p (accept)				      \
+		  ? (((const char *) (accept))[0] == '\0'		      \
+		     ? 0						      \
+		     : (((const char *) (accept))[1] == '\0'		      \
+			? __strspn_c1 (s, ((const char *) (accept))[0])	      \
+			: strspn (s, accept)))				      \
+		  : strspn (s, accept)))
+
+__STRING_INLINE size_t
+__strspn_c1 (__const char *__s, char __accept)
+{
+  register size_t __result = 0;
+  /* Please note that __accept never can be '\0'.  */
+  while (__s[__result] == __accept)
+    ++__result;
+  return __result;
+}
+#endif
+
+
+/* Find the first occurrence in S of any character in ACCEPT.  */
+#ifndef _HAVE_STRING_ARCH_strpbrk
+# define strpbrk(s, accept) \
+  (__extension__ (__builtin_constant_p (accept)				      \
+		  ? (((const char *) (accept))[0] == '\0'		      \
+		     ? NULL						      \
+		     : (((const char *) (accept))[1] == '\0'		      \
+			? strchr (s, ((const char *) (accept))[0])	      \
+			: strpbrk (s, accept)))				      \
+		  : strpbrk (s, accept)))
+#endif
+
+
+/* Find the first occurrence of NEEDLE in HAYSTACK.  */
+#ifndef _HAVE_STRING_ARCH_strstr
+# define strstr(haystack, needle) \
+  (__extension__ (__builtin_constant_p (needle)				      \
+		  ? (((const char *) (needle))[0] == '\0'		      \
+		     ? haystack						      \
+		     : (((const char *) (needle))[1] == '\0'		      \
+			? strchr (haystack, ((const char *) (needle))[0])     \
+			: strstr (haystack, needle)))			      \
+		  : strstr (haystack, needle)))
+#endif
+
+
+#ifdef __USE_GNU
+# ifndef _HAVE_STRING_ARCH_strnlen
+extern __inline size_t
+strnlen (__const char *__string, size_t __maxlen)
+{
+  __const char *__end = (__const char *) memchr (__string, '\0', __maxlen);
+  return __end ? __end - __string : __maxlen;
+}
+# endif
+#endif
+
+
+#undef __STRING_INLINE
+
+#endif /* bits/string2.h */
diff --git a/string/inl-tester.c b/string/inl-tester.c
new file mode 100644
index 0000000000..88528e5ed8
--- /dev/null
+++ b/string/inl-tester.c
@@ -0,0 +1,6 @@
+/* We want to test the inline functions here.  */
+
+#define DO_STRING_INLINES
+#undef __USE_STRING_INLINES
+#define __USE_STRING_INLINES 1
+#include "tester.c"
diff --git a/string/stratcliff.c b/string/stratcliff.c
index 6115d2f8db..ae1b7ae0ca 100644
--- a/string/stratcliff.c
+++ b/string/stratcliff.c
@@ -19,6 +19,11 @@
    Boston, MA 02111-1307, USA.  */
 
 #define _GNU_SOURCE 1
+
+/* Make sure we don't test the optimized inline functions if we want to
+   test the real implementation.  */
+#undef __USE_STRING_INLINES
+
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/string/string.h b/string/string.h
index 3cac382529..560638be8e 100644
--- a/string/string.h
+++ b/string/string.h
@@ -171,6 +171,13 @@ extern char *strtok_r __P ((char *__s, __const char *__delim,
    HAYSTACK is HAYSTACKLEN bytes long.  */
 extern __ptr_t memmem __P ((__const __ptr_t __haystack, size_t __haystacklen,
 			    __const __ptr_t __needle, size_t __needlelen));
+
+/* Copy N bytes of SRC to DEST, return pointer to bytes after the
+   last written byte.  */
+extern __ptr_t __mempcpy __P ((__ptr_t __restrict __dest,
+			       __const __ptr_t __restrict __src, size_t __n));
+extern __ptr_t mempcpy __P ((__ptr_t __restrict __dest,
+			     __const __ptr_t __restrict __src, size_t __n));
 #endif
 
 
@@ -274,21 +281,30 @@ extern char *basename __P ((__const char *__filename));
 #endif
 
 
-/* Some functions might be implemented as optimized inline assembler
-   functions.  Only include this file if we really want them.  */
-#if defined __USE_STRING_INLINES && defined __OPTIMIZE__
-# include <bits/string.h>
-#endif
-
-
-/* Now provide some generic optimizations.  */
 #if defined __GNUC__ && __GNUC__ >= 2 && defined __OPTIMIZE__
-extern __inline size_t
-strnlen (__const char *__string, size_t __maxlen)
-{
-  __const char *__end = (__const char *) memchr (__string, '\0', __maxlen);
-  return __end ? __end - __string : __maxlen;
-}
+/* When using GNU CC we provide some optimized versions of selected
+   functions from this header.  There are two kinds of optimizations:
+
+   - machine-dependent optmizations, most probably using inline
+     assembler code; these could be quite expensive since the code
+     size could increase significantly.
+     These optimizations are not used unless the symbol
+	__USE_STRING_INLINES
+     is defined before including this header
+
+   - machine-independent optimizations which do not increase the
+     code size significantly and which optimize mainly situations
+     where one or more arguments are compile-time constants.
+     These optimizations are used always when the compiler is
+     taught to optimized.  */
+
+/* Get the machine-dependent optimizations if wanted.  */
+# ifdef __USE_STRING_INLINES
+#  include <bits/string.h>
+# endif
+
+/* These are generic optimizations which do not add too much inline code.  */
+# include <bits/string2.h>
 #endif
 
 __END_DECLS
diff --git a/string/tester.c b/string/tester.c
index 0e65442063..dfb1258864 100644
--- a/string/tester.c
+++ b/string/tester.c
@@ -1,6 +1,32 @@
+/* Tester for string functions.
+   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   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.  */
+
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
+
+/* Make sure we don't test the optimized inline functions if we want to
+   test the real implementation.  */
+#if !defined DO_STRING_INLINES
+#undef __USE_STRING_INLINES
+#endif
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -222,7 +248,7 @@ main (void)
 
   (void) strcpy (one, "abcdefgh");
   (void) strncpy (one, "xyz", 2);
-  equal (one, "xycdefgh", 3);		/* Copy cut by count. */
+  equal (one, "xycdefgh", 3);			/* Copy cut by count. */
 
   (void) strcpy (one, "abcdefgh");
   (void) strncpy (one, "xyz", 3);		/* Copy cut just before NUL. */
@@ -231,7 +257,7 @@ main (void)
   (void) strcpy (one, "abcdefgh");
   (void) strncpy (one, "xyz", 4);		/* Copy just includes NUL. */
   equal (one, "xyz", 5);
-  equal (one+4, "efgh", 6);		/* Wrote too much? */
+  equal (one+4, "efgh", 6);			/* Wrote too much? */
 
   (void) strcpy (one, "abcdefgh");
   (void) strncpy (one, "xyz", 5);		/* Copy includes padding. */
diff --git a/string/tst-strlen.c b/string/tst-strlen.c
index 4acd4045f5..c43cb1a4d6 100644
--- a/string/tst-strlen.c
+++ b/string/tst-strlen.c
@@ -1,3 +1,7 @@
+/* Make sure we don't test the optimized inline functions if we want to
+   test the real implementation.  */
+#undef __USE_STRING_INLINES
+
 #include <stdio.h>
 #include <string.h>
 
diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c
index 4ea6391c6e..9b030567d3 100644
--- a/sunrpc/auth_des.c
+++ b/sunrpc/auth_des.c
@@ -109,7 +109,7 @@ struct ad_private
  * Create the client des authentication object
  */
 AUTH *
-authdes_create (const char *servername, u_int window, 
+authdes_create (const char *servername, u_int window,
 		struct sockaddr *syncaddr, des_block * ckey)
   /* servername - network name of server */
   /* window     - time to live */
@@ -161,6 +161,7 @@ authdes_pk_create (const char *servername, netobj * pkey, u_int window,
    */
   bcopy (namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1);
   bcopy (servername, ad->ad_servername, ad->ad_servernamelen + 1);
+  ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
   if (syncaddr != NULL)
     {
       ad->ad_syncaddr = *syncaddr;
@@ -198,11 +199,13 @@ failed:
   if (auth != NULL)
     FREE (auth, sizeof (AUTH));
   if (ad != NULL)
-    FREE (ad, sizeof (struct ad_private));
-  if (ad->ad_fullname != NULL)
-    FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
-  if (ad->ad_servername != NULL)
-    FREE (ad->ad_servername, ad->ad_servernamelen + 1);
+    {
+      FREE (ad, sizeof (struct ad_private));
+      if (ad->ad_fullname != NULL)
+	FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
+      if (ad->ad_servername != NULL)
+	FREE (ad->ad_servername, ad->ad_servernamelen + 1);
+    }
   return (NULL);
 }
 
diff --git a/sunrpc/auth_none.c b/sunrpc/auth_none.c
index a7c1524ef5..0ab306407c 100644
--- a/sunrpc/auth_none.c
+++ b/sunrpc/auth_none.c
@@ -44,8 +44,6 @@ static char sccsid[] = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
 
 #define MAX_MARSHEL_SIZE 20
 
-extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *);
-
 /*
  * Authenticator operations routines
  */
diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c
index 5e5dc995ca..ac9b53a3e3 100644
--- a/sunrpc/auth_unix.c
+++ b/sunrpc/auth_unix.c
@@ -54,8 +54,6 @@ static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";
 #include <rpc/auth.h>
 #include <rpc/auth_unix.h>
 
-extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *);
-
 /*
  * Unix authenticator operations vector
  */
diff --git a/sunrpc/clnt_raw.c b/sunrpc/clnt_raw.c
index a9ff3ca00a..18ae2414ab 100644
--- a/sunrpc/clnt_raw.c
+++ b/sunrpc/clnt_raw.c
@@ -46,8 +46,6 @@ static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
 #include <rpc/svc.h>
 #include <rpc/xdr.h>
 
-extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *);
-
 #define MCALL_MSG_SIZE 24
 
 /*
diff --git a/sunrpc/clnt_tcp.c b/sunrpc/clnt_tcp.c
index 02c43dd26f..82b34b6259 100644
--- a/sunrpc/clnt_tcp.c
+++ b/sunrpc/clnt_tcp.c
@@ -58,8 +58,6 @@ static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
 #include <sys/socket.h>
 #include <rpc/pmap_clnt.h>
 
-extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *);
-
 #define MCALL_MSG_SIZE 24
 
 struct ct_data
diff --git a/sunrpc/key_call.c b/sunrpc/key_call.c
index ba1c2638fb..dff7da6a7a 100644
--- a/sunrpc/key_call.c
+++ b/sunrpc/key_call.c
@@ -32,11 +32,12 @@
 
 /*
  * The original source is from the RPCSRC 4.0 package from Sun Microsystems.
- * The Interface to keyserver protocoll 2 was added by 
+ * The Interface to keyserver protocoll 2 was added by
  * Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
  */
 
 #include <stdio.h>
+#include <errno.h>
 #include <signal.h>
 #include <unistd.h>
 #include <string.h>
@@ -52,21 +53,21 @@
 
 #define debug(msg)		/* turn off debugging */
 
-extern int _openchild (char *command, FILE ** fto, FILE ** ffrom);
+extern int _openchild (char *command, FILE **fto, FILE **ffrom);
 
 
 static int key_call (u_long, xdrproc_t xdr_arg, char *,
 		     xdrproc_t xdr_rslt, char *);
 
 static struct timeval trytimeout = {KEY_TIMEOUT, 0};
-static struct timeval tottimeout = {KEY_TIMEOUT * KEY_NRETRY, 0};
+static struct timeval tottimeout = {KEY_TIMEOUT *KEY_NRETRY, 0};
 
 int
 key_setsecret (char *secretkey)
 {
   keystatus status;
 
-  if (!key_call ((u_long) KEY_SET, (xdrproc_t) xdr_keybuf, secretkey, 
+  if (!key_call ((u_long) KEY_SET, (xdrproc_t) xdr_keybuf, secretkey,
 		 (xdrproc_t) xdr_keystatus, (char *) &status))
     return -1;
   if (status != KEY_SUCCESS)
@@ -102,14 +103,14 @@ key_secretkey_is_set (void)
 }
 
 int
-key_encryptsession (char *remotename, des_block * deskey)
+key_encryptsession (char *remotename, des_block *deskey)
 {
   cryptkeyarg arg;
   cryptkeyres res;
 
   arg.remotename = remotename;
   arg.deskey = *deskey;
-  if (!key_call ((u_long) KEY_ENCRYPT, (xdrproc_t) xdr_cryptkeyarg, 
+  if (!key_call ((u_long) KEY_ENCRYPT, (xdrproc_t) xdr_cryptkeyarg,
 		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
     return -1;
 
@@ -123,7 +124,7 @@ key_encryptsession (char *remotename, des_block * deskey)
 }
 
 int
-key_decryptsession (char *remotename, des_block * deskey)
+key_decryptsession (char *remotename, des_block *deskey)
 {
   cryptkeyarg arg;
   cryptkeyres res;
@@ -143,8 +144,8 @@ key_decryptsession (char *remotename, des_block * deskey)
 }
 
 int
-key_encryptsession_pk (char *remotename, netobj * remotekey,
-		       des_block * deskey)
+key_encryptsession_pk (char *remotename, netobj *remotekey,
+		       des_block *deskey)
 {
   cryptkeyarg2 arg;
   cryptkeyres res;
@@ -152,7 +153,7 @@ key_encryptsession_pk (char *remotename, netobj * remotekey,
   arg.remotename = remotename;
   arg.remotekey = *remotekey;
   arg.deskey = *deskey;
-  if (!key_call ((u_long) KEY_ENCRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2, 
+  if (!key_call ((u_long) KEY_ENCRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
 		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
     return -1;
 
@@ -166,8 +167,8 @@ key_encryptsession_pk (char *remotename, netobj * remotekey,
 }
 
 int
-key_decryptsession_pk (char *remotename, netobj * remotekey,
-		       des_block * deskey)
+key_decryptsession_pk (char *remotename, netobj *remotekey,
+		       des_block *deskey)
 {
   cryptkeyarg2 arg;
   cryptkeyres res;
@@ -175,7 +176,7 @@ key_decryptsession_pk (char *remotename, netobj * remotekey,
   arg.remotename = remotename;
   arg.remotekey = *remotekey;
   arg.deskey = *deskey;
-  if (!key_call ((u_long) KEY_DECRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2, 
+  if (!key_call ((u_long) KEY_DECRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
 		 (char *) &arg, (xdrproc_t) xdr_cryptkeyres, (char *) &res))
     return -1;
 
@@ -189,7 +190,7 @@ key_decryptsession_pk (char *remotename, netobj * remotekey,
 }
 
 int
-key_gendes (des_block * key)
+key_gendes (des_block *key)
 {
   struct sockaddr_in sin;
   CLIENT *client;
@@ -222,7 +223,7 @@ key_setnet (struct key_netstarg *arg)
 {
   keystatus status;
 
-  if (!key_call ((u_long) KEY_NET_PUT, (xdrproc_t) xdr_key_netstarg, 
+  if (!key_call ((u_long) KEY_NET_PUT, (xdrproc_t) xdr_key_netstarg,
 		 (char *) arg,(xdrproc_t) xdr_keystatus, (char *) &status))
     return -1;
 
@@ -235,7 +236,7 @@ key_setnet (struct key_netstarg *arg)
 }
 
 int
-key_get_conv (char *pkey, des_block * deskey)
+key_get_conv (char *pkey, des_block *deskey)
 {
   cryptkeyres res;
 
@@ -273,7 +274,7 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
   XDR xdrrslt;
   FILE *fargs;
   FILE *frslt;
-  void (*osigchild) (int);
+  sigset_t oldmask, mask;
   union wait status;
   int pid;
   int success;
@@ -281,9 +282,6 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
   uid_t euid;
   static char MESSENGER[] = "/usr/etc/keyenvoy";
 
-  success = 1;
-  osigchild = signal (SIGCHLD, SIG_IGN);
-
   if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL)
     {
       cryptkeyres *res;
@@ -306,6 +304,11 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
       return 1;
     }
 
+  success = 1;
+  sigemptyset (&mask);
+  sigaddset (&mask, SIGCHLD);
+  sigprocmask (SIG_BLOCK, &mask, &oldmask);
+
   /*
    * We are going to exec a set-uid program which makes our effective uid
    * zero, and authenticates us with our real uid. We need to make the
@@ -320,6 +323,7 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
   if (pid < 0)
     {
       debug ("open_streams");
+      sigprocmask(SIG_SETMASK, &oldmask, NULL);
       return (0);
     }
   xdrstdio_create (&xdrargs, fargs, XDR_ENCODE);
@@ -337,27 +341,26 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
       debug ("xdr rslt");
       success = 0;
     }
+  fclose(frslt);
 
-#ifdef NOTDEF
-  /*
-   * WARNING! XXX
-   * The original code appears first.  wait4 returns only after the process
-   * with the requested pid terminates.  The effect of using wait() instead
-   * has not been determined.
-   */
-  fclose (frslt);
-  if (wait4 (pid, &status, 0, NULL) < 0 || status.w_retcode != 0)
+ wait_again:
+  if (wait4(pid, &status, 0, NULL) < 0)
     {
-      debug ("wait4");
-      success = 0;
-    }
-#endif /* def NOTDEF */
-  if (wait (&status) < 0 || status.w_retcode != 0)
-    {
-      debug ("wait");
-      success = 0;
+      if (errno == EINTR)
+	goto wait_again;
+      debug("wait4");
+      if (errno == ECHILD || errno == ESRCH)
+	perror("wait");
+      else
+	success = 0;
     }
-  signal (SIGCHLD, osigchild);
+  else
+    if (status.w_retcode)
+      {
+	debug("wait4 1");
+	success = 0;
+      }
+  sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
   return (success);
 }
diff --git a/sunrpc/openchild.c b/sunrpc/openchild.c
index 2fa26fae45..11e06006b3 100644
--- a/sunrpc/openchild.c
+++ b/sunrpc/openchild.c
@@ -1,6 +1,3 @@
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)openchild.c	2.3 88/08/15 4.0 RPCSRC; from 1.7 88/02/08 SMI";
-#endif
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  * unrestricted use provided that this legend is included on all tape
@@ -46,8 +43,6 @@ static char sccsid[] = "@(#)openchild.c	2.3 88/08/15 4.0 RPCSRC; from 1.7 88/02/
 #include <rpc/rpc.h>
 #include <rpc/clnt.h>
 
-static char SHELL[] = "/bin/sh";
-
 /*
  * returns pid, or -1 for failure
  */
@@ -58,13 +53,12 @@ _openchild (char *command, FILE ** fto, FILE ** ffrom)
   int pid;
   int pdto[2];
   int pdfrom[2];
-  char *com;
 
   if (pipe (pdto) < 0)
     goto error1;
   if (pipe (pdfrom) < 0)
     goto error2;
-  switch (pid = vfork ())
+  switch (pid = fork ())
     {
     case -1:
       goto error3;
@@ -77,13 +71,12 @@ _openchild (char *command, FILE ** fto, FILE ** ffrom)
       dup (pdto[0]);
       close (1);
       dup (pdfrom[1]);
+      fflush (stderr);
       for (i = _rpc_dtablesize () - 1; i >= 3; i--)
 	close (i);
-      com = malloc (strlen (command) + 6);
-      if (com == NULL)
-	_exit (~0);
-      sprintf (com, "exec %s", command);
-      execl (SHELL, basename (SHELL), "-c", com, NULL);
+      fflush (stderr);
+      execlp (command, command, 0);
+      perror ("exec");
       _exit (~0);
 
     default:
diff --git a/sunrpc/rpc/auth.h b/sunrpc/rpc/auth.h
index 22174193d4..9519ca27f4 100644
--- a/sunrpc/rpc/auth.h
+++ b/sunrpc/rpc/auth.h
@@ -99,7 +99,7 @@ struct AUTH {
   struct auth_ops {
     void (*ah_nextverf) __P ((AUTH *));
     int  (*ah_marshal) __P ((AUTH *, XDR *));	/* nextverf & serialize */
-    int  (*ah_validate) __P ((AUTH *, struct opaque_auth *));	
+    int  (*ah_validate) __P ((AUTH *, struct opaque_auth *));
 						/* validate verifier */
     int  (*ah_refresh) __P ((AUTH *));		/* refresh credentials */
     void (*ah_destroy) __P ((AUTH *));     	/* destroy this structure */
@@ -163,7 +163,7 @@ extern AUTH *authunix_create __P ((char *__machname, __uid_t __uid,
 				   __gid_t *__aup_gids));
 extern AUTH *authunix_create_default __P ((void));
 extern AUTH *authnone_create __P ((void));
-extern AUTH *authdes_create __P ((const char *__servername, u_int __window, 
+extern AUTH *authdes_create __P ((const char *__servername, u_int __window,
 				  struct sockaddr *__syncaddr,
 				  des_block *__ckey));
 
@@ -182,7 +182,7 @@ extern AUTH *authdes_create __P ((const char *__servername, u_int __window,
 extern int getnetname __P ((char *));
 extern int host2netname __P ((char *, __const char *, __const char *));
 extern int user2netname __P ((char *, __const uid_t, __const char *));
-extern int netname2user __P ((__const char *, uid_t *, gid_t *, int *, 
+extern int netname2user __P ((__const char *, uid_t *, gid_t *, int *,
 			      gid_t *));
 extern int netname2host __P ((__const char *, char *, __const int));
 
@@ -200,11 +200,11 @@ extern int key_setsecret __P ((char *));
 extern int key_secretkey_is_set __P ((void));
 extern int key_get_conv __P ((char *, des_block *));
 
-__END_DECLS
+/*
+ * XDR an opaque authentication struct.
+ */
+extern bool_t xdr_opaque_auth __P ((XDR *, struct opaque_auth *));
 
-/* This is for compiling the glibc NIS+ code with DES auth. */
-#ifdef _LIBC
-#define HAVE_SECURE_RPC 1
-#endif
+__END_DECLS
 
 #endif /* rpc/auth.h */
diff --git a/sunrpc/rpc_cmsg.c b/sunrpc/rpc_cmsg.c
index 5759360b21..4cd2a8f35a 100644
--- a/sunrpc/rpc_cmsg.c
+++ b/sunrpc/rpc_cmsg.c
@@ -42,8 +42,6 @@ static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
 #include <sys/param.h>
 #include <rpc/rpc.h>
 
-extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *);
-
 /*
  * XDR a call message
  */
diff --git a/sysdeps/alpha/Makefile b/sysdeps/alpha/Makefile
index 5fe8e4ee7f..6cf4a173a6 100644
--- a/sysdeps/alpha/Makefile
+++ b/sysdeps/alpha/Makefile
@@ -21,10 +21,6 @@ ifeq ($(subdir),gmon)
 sysdep_routines += _mcount
 endif
 
-ifeq ($(subdir),setjmp)
-sysdep_routines += setjmp_aux
-endif
-
 ifeq ($(subdir),gnulib)
 sysdep_routines += $(divrem)
 endif
@@ -45,6 +41,6 @@ endif
 
 divrem := divl divq reml remq
 
-# For now, build everything with full IEEE math support. 
+# For now, build everything with full IEEE math support.
 # TODO: build separate libm and libm-ieee.
 sysdep-CFLAGS += -mieee
diff --git a/sysdeps/alpha/__longjmp.S b/sysdeps/alpha/__longjmp.S
new file mode 100644
index 0000000000..34731172e1
--- /dev/null
+++ b/sysdeps/alpha/__longjmp.S
@@ -0,0 +1,59 @@
+/* Copyright (C) 1992, 1994, 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.  */
+
+#define __ASSEMBLY__
+
+#include <sysdep.h>
+#include <bits/setjmp.h>
+
+
+ENTRY(__longjmp)
+#ifdef PROF
+	ldgp    gp, 0(pv)
+	.set noat
+	lda     AT, _mcount
+	jsr     AT, (AT), _mcount
+	.set at
+	.prologue 1
+#else
+	.prologue 0
+#endif
+
+	mov     a1, v0
+	ldq     s0, JB_S0*8(a0)
+	ldq     s1, JB_S1*8(a0)
+	ldq     s2, JB_S2*8(a0)
+	ldq     s3, JB_S3*8(a0)
+	ldq     s4, JB_S4*8(a0)
+	ldq     s5, JB_S5*8(a0)
+	ldq     ra, JB_PC*8(a0)
+	ldq     fp, JB_FP*8(a0)
+	ldq     t0, JB_SP*8(a0)
+	ldt     $f2, JB_F2*8(a0)
+	ldt     $f3, JB_F3*8(a0)
+	ldt     $f4, JB_F4*8(a0)
+	ldt     $f5, JB_F5*8(a0)
+	ldt     $f6, JB_F6*8(a0)
+	ldt     $f7, JB_F7*8(a0)
+	ldt     $f8, JB_F8*8(a0)
+	ldt     $f9, JB_F9*8(a0)
+	cmoveq  v0, 1, v0
+	mov     t0, sp
+	ret
+
+END(__longjmp)
diff --git a/sysdeps/alpha/__longjmp.c b/sysdeps/alpha/__longjmp.c
deleted file mode 100644
index 98eba7c513..0000000000
--- a/sysdeps/alpha/__longjmp.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (C) 1992, 1994, 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.  */
-
-/* Global register vars must come before any function defn.  */
-
-register long int
-  r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"),
-  r13 asm ("$13"), r14 asm ("$14");
-
-register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26");
-
-#if 1				/* XXX */
-register double
-  f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"),
-  f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9");
-#endif
-
-#include <setjmp.h>
-
-
-/* Jump to the position specified by ENV, causing the
-   setjmp call there to return VAL, or 1 if VAL is 0.  */
-void
-__longjmp (__jmp_buf env, int val)
-{
-  register long int retval asm ("$0");
-
-  /* Restore the integer registers.  */
-  r9 = env[0].__9;
-  r10 = env[0].__10;
-  r11 = env[0].__11;
-  r12 = env[0].__12;
-  r13 = env[0].__13;
-  r14 = env[0].__14;
-
-#if 1				/* XXX */
-  /* Restore the floating point registers.  */
-  f2 = env[0].__f2;
-  f3 = env[0].__f3;
-  f4 = env[0].__f4;
-  f5 = env[0].__f5;
-  f6 = env[0].__f6;
-  f7 = env[0].__f7;
-  f8 = env[0].__f8;
-  f9 = env[0].__f9;
-#endif
-
-  /* Set the return PC to that of setjmp's caller.  */
-  retpc = env[0].__pc;
-
-  /* Restore the FP and SP of setjmp's caller.  */
-  fp = env[0].__fp;
-  sp = env[0].__sp;
-
-  /* Return VAL (or 1 if VAL is zero) to setjmp's caller.
-
-     We use an asm here rather than a normal C return statement
-     just in case the compiler wanted to do some stack frobnication
-     in the function epilogue.  Since we have already restored
-     precisely the FP and SP the desired environment needs,
-     we must avoid the compiler doing anything with the stack.  */
-
-
-  asm volatile
-    ("cmoveq %1, 1, %0\n\t"	/* $0 = val ?: 1; */
-     "ret $31, (%2), 1"	/* return $0 */
-     : "=r" (retval)
-     /* The "0" constraint should force VAL into $0.  */
-     : "0" (val), "r" (retpc));
-
-  while (1)
-    {
-      /* The loop is just to avoid `volatile function does return' warnings.
-	 The instruction will only be executed once.  */
-      asm volatile ("");
-    }
-}
diff --git a/sysdeps/alpha/bits/setjmp.h b/sysdeps/alpha/bits/setjmp.h
index d461205c06..9aa30463d6 100644
--- a/sysdeps/alpha/bits/setjmp.h
+++ b/sysdeps/alpha/bits/setjmp.h
@@ -17,30 +17,57 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-typedef struct
-  {
-    /* Integer registers:
-	   $0 is the return value;
-	   $1-$8, $22-$25, $28 are call-used;
-	   $9-$14 we save here;
-	   $15 is the FP and we save it here;
-	   $16-$21 are input arguments (call-used);
-	   $26 is the return PC and we save it here;
-	   $27 is the procedure value (i.e., the address of __setjmp);
-	   $29 is the global pointer, which the caller will reconstruct
-	   from the return address restored in $26;
-	   $30 is the stack pointer and we save it here;
-	   $31 is always zero.  */
-    long int __9, __10, __11, __12, __13, __14;
-    long int *__pc, *__fp, *__sp;
+/* The previous bits/setjmp.h had __jmp_buf defined as a structure.
+   We use an array of 'long int' instead, to make writing the
+   assembler easier. Naturally, user code should not depend on
+   either representation. */
 
-#if 1				/* XXX need predefine for TARGET_FPREGS */
-    /* Floating-point registers:
-	   $f0 is the floating return value;
-	   $f1, $f10-$f15, $f22-$f30 are call-used;
-	   $f2-$f9 we save here;
-	   $f16-$21 are input args (call-used);
-	   $f31 is always zero.  */
-    double __f2, __f3, __f4, __f5, __f6, __f7, __f8, __f9;
-#endif	/* Have FP regs.  */
-  } __jmp_buf[1];
+/*
+ * Integer registers:
+ *    $0 is the return value (va);
+ *    $1-$8, $22-$25, $28 are call-used (t0-t7, t8-t11, at);
+ *    $9-$14 we save here (s0-s5);
+ *    $15 is the FP and we save it here (fp or s6);
+ *    $16-$21 are input arguments (call-used) (a0-a5);
+ *    $26 is the return PC and we save it here (ra);
+ *    $27 is the procedure value (i.e., the address of __setjmp) (pv or t12);
+ *    $29 is the global pointer, which the caller will reconstruct
+ *        from the return address restored in $26 (gp);
+ *    $30 is the stack pointer and we save it here (sp);
+ *    $31 is always zero (zero).
+ *
+ * Floating-point registers:
+ *    $f0 is the floating return value;
+ *    $f1, $f10-$f15, $f22-$f30 are call-used;
+ *    $f2-$f9 we save here;
+ *    $f16-$21 are input args (call-used);
+ *    $f31 is always zero.
+ *
+ * Note that even on Alpha hardware that does not have an FPU (there
+ * isn't such a thing currently) it is required to implement the FP
+ * registers.
+ */
+
+#if defined(__USE_MISC) || defined(__ASSEMBLY__)
+#define JB_S0  0
+#define JB_S1  1
+#define JB_S2  2
+#define JB_S3  3
+#define JB_S4  4
+#define JB_S5  5
+#define JB_PC  6
+#define JB_FP  7
+#define JB_SP  8
+#define JB_F2  9
+#define JB_F3  10
+#define JB_F4  11
+#define JB_F5  12
+#define JB_F6  13
+#define JB_F7  14
+#define JB_F8  15
+#define JB_F9  16
+#endif
+
+#ifndef __ASSEMBLY__
+typedef long int __jmp_buf[17];
+#endif
diff --git a/sysdeps/alpha/bsd-_setjmp.S b/sysdeps/alpha/bsd-_setjmp.S
index 07fb0c7637..4e6a2da560 100644
--- a/sysdeps/alpha/bsd-_setjmp.S
+++ b/sysdeps/alpha/bsd-_setjmp.S
@@ -1,39 +1 @@
-/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  Alpha version.
-   Copyright (C) 1994, 1996 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.  */
-
-/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
-   We cannot do it in C because it must be a tail-call, so frame-unwinding
-   in setjmp doesn't clobber the state restored by longjmp.  */
-
-#include <sysdep.h>
-
-ENTRY(_setjmp)
-	ldgp	$29,0($27)
-#ifdef PROF
-	.set noat
-	lda	AT, _mcount
-	jsr	AT, (AT), _mcount
-	.set at
-#endif
-	.prologue 1
-	bis	$31, $31, $17		/* Pass a second argument of zero.  */
-	jmp	$31, __sigsetjmp	/* Call __sigsetjmp.  */
-	END(_setjmp)
-
-strong_alias_asm(_setjmp, __setjmp)
+/* _setjmp is in setjmp.S  */
diff --git a/sysdeps/alpha/bsd-setjmp.S b/sysdeps/alpha/bsd-setjmp.S
index cf5bf189de..1da848d2f1 100644
--- a/sysdeps/alpha/bsd-setjmp.S
+++ b/sysdeps/alpha/bsd-setjmp.S
@@ -1,37 +1 @@
-/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  Alpha version.
-   Copyright (C) 1994, 1996 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.  */
-
-/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
-   We cannot do it in C because it must be a tail-call, so frame-unwinding
-   in setjmp doesn't clobber the state restored by longjmp.  */
-
-#include <sysdep.h>
-
-ENTRY(setjmp)
-	ldgp	$29, 0($27)
-#ifdef PROF
-	.set noat
-	lda	AT, _mcount
-	jsr	AT, (AT), _mcount
-	.set at
-#endif
-	.prologue 1
-	bis	$31, 1, $17		/* Pass a second argument of one.  */
-	jmp	$31, __sigsetjmp	/* Call __sigsetjmp.  */
-	END(setjmp)
+/* setjmp is in setjmp.S  */
diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S
index 4b2e147b15..48fe33b3ec 100644
--- a/sysdeps/alpha/setjmp.S
+++ b/sysdeps/alpha/setjmp.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1994, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -16,13 +16,21 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#define __ASSEMBLY__
+
 #include <sysdep.h>
+#include <bits/setjmp.h>
+
+       .ent __sigsetjmp
+       .global __sigsetjmp
+__sigsetjmp:
+       ldgp    gp, 0(pv)
 
-/* The function __sigsetjmp_aux saves all the registers, but it can't
-   reliably access the stack or frame pointers, so we pass them in as
-   extra arguments.  */
-ENTRY (__sigsetjmp)
-	ldgp	$29, 0($27)
+$sigsetjmp_local:
+       subq    sp, 16, sp
+       .frame  sp, 16, ra, 0
+       stq     ra, 0(sp)
+       .mask   0x04000000, -16
 #ifdef PROF
 	.set noat
 	lda	AT, _mcount
@@ -31,8 +39,48 @@ ENTRY (__sigsetjmp)
 #endif
 	.prologue 1
 
-	bis	$30, $30, $18		/* Pass SP as 3rd arg.  */
-	bis	$15, $15, $19		/* Pass FP as 4th arg.  */
-	jmp	$31, __sigsetjmp_aux	/* Call __sigsetjmp_aux.  */
+	stq	s0, JB_S0*8(a0)
+	stq	s1, JB_S1*8(a0)
+	stq	s2, JB_S2*8(a0)
+	stq	s3, JB_S3*8(a0)
+	stq	s4, JB_S4*8(a0)
+	stq	s5, JB_S5*8(a0)
+	stq	ra, JB_PC*8(a0)
+	addq	sp, 16, t0
+	stq	fp, JB_FP*8(a0)
+	stq	t0, JB_SP*8(a0)
+	stt	$f2, JB_F2*8(a0)
+	stt	$f3, JB_F3*8(a0)
+	stt	$f4, JB_F4*8(a0)
+	stt	$f5, JB_F5*8(a0)
+	stt	$f6, JB_F6*8(a0)
+	stt	$f7, JB_F7*8(a0)
+	stt	$f8, JB_F8*8(a0)
+	stt	$f9, JB_F9*8(a0)
+
+	/* Call to C to (potentially) save our signal mask.  */
+	jsr	ra, __sigjmp_save
+
+	ldq	ra, 0(sp)
+	addq	sp, 16, sp
+	ret
+
+END(__sigsetjmp)
+
+/* Put these traditional entry points in the same file so that we can
+   elide much of the nonsense in trying to jmp to the real function.  */
+
+ENTRY(_setjmp)
+	ldgp	gp, 0(pv)
+	mov	0, a1
+	br	$sigsetjmp_local
+END(_setjmp)
+
+ENTRY(setjmp)
+	ldgp	gp, 0(pv)
+	mov	1, a1
+	br	$sigsetjmp_local
+END(setjmp)
 
-	END(__sigsetjmp)
+weak_extern(_setjmp)
+weak_extern(setjmp)
diff --git a/sysdeps/alpha/setjmp_aux.c b/sysdeps/alpha/setjmp_aux.c
deleted file mode 100644
index fa26975295..0000000000
--- a/sysdeps/alpha/setjmp_aux.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (C) 1992, 1994, 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.  */
-
-/* Global register decls must come before any function defn.  */
-
-register long int
-  r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"),
-  r13 asm ("$13"), r14 asm ("$14");
-
-register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26");
-
-#if 1				/* XXX */
-register double
-  f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"),
-  f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9");
-#endif
-
-
-#include <setjmp.h>
-
-
-/* Save the current program position in ENV and return 0.  */
-int
-__sigsetjmp_aux (sigjmp_buf env, int savemask, long int *sp, long int *fp)
-{
-  /* Save the integer registers.  */
-  env[0].__jmpbuf[0].__9 = r9;
-  env[0].__jmpbuf[0].__10 = r10;
-  env[0].__jmpbuf[0].__11 = r11;
-  env[0].__jmpbuf[0].__12 = r12;
-  env[0].__jmpbuf[0].__13 = r13;
-  env[0].__jmpbuf[0].__14 = r14;
-
-#if 1				/* XXX */
-  /* Save the floating point registers.  */
-  env[0].__jmpbuf[0].__f2 = f2;
-  env[0].__jmpbuf[0].__f3 = f3;
-  env[0].__jmpbuf[0].__f4 = f4;
-  env[0].__jmpbuf[0].__f5 = f5;
-  env[0].__jmpbuf[0].__f6 = f6;
-  env[0].__jmpbuf[0].__f7 = f7;
-  env[0].__jmpbuf[0].__f8 = f8;
-  env[0].__jmpbuf[0].__f9 = f9;
-#endif
-
-  /* Save the return address of our caller, where longjmp will jump to.  */
-  env[0].__jmpbuf[0].__pc = retpc;
-
-  /* Save the FP and SP of our caller.  The __sigsetjmp entry point
-     simply puts these in the argument registers for us to fetch.  */
-  env[0].__jmpbuf[0].__fp = fp;
-  env[0].__jmpbuf[0].__sp = sp;
-
-  /* Save the signal mask if requested.  */
-  __sigjmp_save (env, savemask);
-
-  retpc = env[0].__jmpbuf[0].__pc;	/* restore ra, ugly... */
-
-  /* Return to the original caller of __sigsetjmp.  */
-  return 0;
-}
diff --git a/sysdeps/generic/crypt.h b/sysdeps/generic/crypt.h
index 3f8f960140..c14554c829 100644
--- a/sysdeps/generic/crypt.h
+++ b/sysdeps/generic/crypt.h
@@ -50,6 +50,8 @@ struct crypt_data
     int direction, initialized;
   };
 
+extern char *__crypt_r __P ((__const char *__key, __const char *__salt,
+			     struct crypt_data *__data));
 extern char *crypt_r __P ((__const char *__key, __const char *__salt,
 			   struct crypt_data *__data));
 #endif
diff --git a/sysdeps/generic/memccpy.c b/sysdeps/generic/memccpy.c
index 6d85a791c6..44a874a954 100644
--- a/sysdeps/generic/memccpy.c
+++ b/sysdeps/generic/memccpy.c
@@ -18,11 +18,12 @@
 
 #include <string.h>
 
-/*
- * Copy no more than N bytes of SRC to DEST, stopping when C is found.
- * Return the position in DEST one byte past where C was copied,
- * or NULL if C was not found in the first N bytes of SRC.
- */
+#undef __memccpy
+#undef memccpy
+
+/* Copy no more than N bytes of SRC to DEST, stopping when C is found.
+   Return the position in DEST one byte past where C was copied, or
+   NULL if C was not found in the first N bytes of SRC.  */
 void *
 __memccpy (dest, src, c, n)
       void *dest; const void *src;
diff --git a/sysdeps/generic/memchr.c b/sysdeps/generic/memchr.c
index 60276e9942..c8926c7b38 100644
--- a/sysdeps/generic/memchr.c
+++ b/sysdeps/generic/memchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1996, 1997 Free Software Foundation, Inc.
    Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
    with help from Dan Sahlin (dan@sics.se) and
    commentary by Jim Blandy (jimb@ai.mit.edu);
@@ -47,9 +47,10 @@
 
 #include <sys/types.h>
 
+#undef memchr
 
-/* Search no more than N bytes of S for C.  */
 
+/* Search no more than N bytes of S for C.  */
 __ptr_t
 memchr (s, c, n)
      const __ptr_t s;
diff --git a/sysdeps/generic/memcmp.c b/sysdeps/generic/memcmp.c
index 9dac13fc91..8fa371192c 100644
--- a/sysdeps/generic/memcmp.c
+++ b/sysdeps/generic/memcmp.c
@@ -34,6 +34,8 @@
 #include <string.h>
 #endif
 
+#undef memcmp
+
 #ifdef _LIBC
 
 #include <memcopy.h>
diff --git a/sysdeps/generic/memmem.c b/sysdeps/generic/memmem.c
index 8163709686..9e4e342237 100644
--- a/sysdeps/generic/memmem.c
+++ b/sysdeps/generic/memmem.c
@@ -19,6 +19,7 @@
 #include <stddef.h>
 #include <string.h>
 
+#undef memmem
 
 /* Return the first occurrence of NEEDLE in HAYSTACK.  */
 void *
diff --git a/sysdeps/generic/memmove.c b/sysdeps/generic/memmove.c
index f4a900973d..4115aa31c7 100644
--- a/sysdeps/generic/memmove.c
+++ b/sysdeps/generic/memmove.c
@@ -29,12 +29,14 @@
 #define	a1const
 #define	a2	src	/* Second arg is SRC.  */
 #define	a2const	const
+#undef memmove
 #endif
 #if	!defined(RETURN) || !defined(rettype)
 #define	RETURN(s)	return (s)	/* Return DEST.  */
 #define	rettype		void *
 #endif
 
+
 rettype
 memmove (a1, a2, len)
      a1const void *a1;
diff --git a/sysdeps/generic/mempcpy.c b/sysdeps/generic/mempcpy.c
new file mode 100644
index 0000000000..43873405c5
--- /dev/null
+++ b/sysdeps/generic/mempcpy.c
@@ -0,0 +1,66 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied, return pointer to following byte.
+   Overlap is NOT handled correctly.
+   Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   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>
+#include <memcopy.h>
+#include <pagecopy.h>
+
+#undef mempcpy
+
+void *
+__mempcpy (dstpp, srcpp, len)
+     void *dstpp;
+     const void *srcpp;
+     size_t len;
+{
+  unsigned long int dstp = (long int) dstpp;
+  unsigned long int srcp = (long int) srcpp;
+
+  /* Copy from the beginning to the end.  */
+
+  /* If there not too few bytes to copy, use word copy.  */
+  if (len >= OP_T_THRES)
+    {
+      /* Copy just a few bytes to make DSTP aligned.  */
+      len -= (-dstp) % OPSIZ;
+      BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+      /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
+	 as much as possible.  */
+
+      PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+      /* Copy from SRCP to DSTP taking advantage of the known alignment of
+	 DSTP.  Number of bytes remaining is put in the third argument,
+	 i.e. in LEN.  This number may vary from machine to machine.  */
+
+      WORD_COPY_FWD (dstp, srcp, len, len);
+
+      /* Fall out and copy the tail.  */
+    }
+
+  /* There are just a few bytes to copy.  Use byte memory operations.  */
+  BYTE_COPY_FWD (dstp, srcp, len);
+
+  return (void *) dstp;
+}
+weak_alias (__mempcpy, mempcpy)
diff --git a/sysdeps/generic/strcat.c b/sysdeps/generic/strcat.c
index 05abd01eff..d8dbab2192 100644
--- a/sysdeps/generic/strcat.c
+++ b/sysdeps/generic/strcat.c
@@ -19,6 +19,8 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strcat
+
 /* Append SRC on the end of DEST.  */
 char *
 strcat (dest, src)
diff --git a/sysdeps/generic/strchr.c b/sysdeps/generic/strchr.c
index d9e58a85a7..3663382556 100644
--- a/sysdeps/generic/strchr.c
+++ b/sysdeps/generic/strchr.c
@@ -22,9 +22,9 @@
 
 #include <string.h>
 
+#undef strchr
 
 /* Find the first occurrence of C in S.  */
-
 char *
 strchr (s, c)
      const char *s;
diff --git a/sysdeps/generic/strcmp.c b/sysdeps/generic/strcmp.c
index a8d9db1bc9..62e55f56ab 100644
--- a/sysdeps/generic/strcmp.c
+++ b/sysdeps/generic/strcmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -19,6 +19,8 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strcmp
+
 /* Compare S1 and S2, returning less than, equal to or
    greater than zero if S1 is lexicographically less than,
    equal to or greater than S2.  */
diff --git a/sysdeps/generic/strcpy.c b/sysdeps/generic/strcpy.c
index fc6beb27fd..cb260cf85a 100644
--- a/sysdeps/generic/strcpy.c
+++ b/sysdeps/generic/strcpy.c
@@ -20,6 +20,8 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strcpy
+
 /* Copy SRC to DEST.  */
 char *
 strcpy (dest, src)
diff --git a/sysdeps/generic/strcspn.c b/sysdeps/generic/strcspn.c
index d7d59b250b..3630a13332 100644
--- a/sysdeps/generic/strcspn.c
+++ b/sysdeps/generic/strcspn.c
@@ -29,6 +29,8 @@
 # endif
 #endif
 
+#undef strcspn
+
 /* Return the length of the maximum initial segment of S
    which contains no characters from REJECT.  */
 size_t
diff --git a/sysdeps/generic/strlen.c b/sysdeps/generic/strlen.c
index 37dc9ed20c..1fb8b1c97c 100644
--- a/sysdeps/generic/strlen.c
+++ b/sysdeps/generic/strlen.c
@@ -20,10 +20,10 @@
 
 #include <string.h>
 
+#undef strlen
 
 /* Return the length of the null-terminated string STR.  Scan for
    the null terminator quickly by testing four bytes at a time.  */
-
 size_t
 strlen (str)
      const char *str;
diff --git a/sysdeps/generic/strncat.c b/sysdeps/generic/strncat.c
index 1233f8b54b..ae9f5e1be3 100644
--- a/sysdeps/generic/strncat.c
+++ b/sysdeps/generic/strncat.c
@@ -24,6 +24,8 @@
 typedef char reg_char;
 #endif
 
+#undef strncat
+
 char *
 strncat (s1, s2, n)
      char *s1;
diff --git a/sysdeps/generic/strncmp.c b/sysdeps/generic/strncmp.c
index eea64389f8..6e5dabebcd 100644
--- a/sysdeps/generic/strncmp.c
+++ b/sysdeps/generic/strncmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -19,6 +19,8 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strncmp
+
 /* Compare no more than N characters of S1 and S2,
    returning less than, equal to or greater than zero
    if S1 is lexicographically less than, equal to or
diff --git a/sysdeps/generic/strncpy.c b/sysdeps/generic/strncpy.c
index 06f5cec2ed..24c7269b09 100644
--- a/sysdeps/generic/strncpy.c
+++ b/sysdeps/generic/strncpy.c
@@ -19,6 +19,7 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strncpy
 
 char *
 strncpy (s1, s2, n)
diff --git a/sysdeps/generic/strpbrk.c b/sysdeps/generic/strpbrk.c
index 3b533e1b87..a49d2b145b 100644
--- a/sysdeps/generic/strpbrk.c
+++ b/sysdeps/generic/strpbrk.c
@@ -24,6 +24,8 @@
 # include <string.h>
 #endif
 
+#undef strpbrk
+
 /* Find the first occurrence in S of any character in ACCEPT.  */
 char *
 strpbrk (s, accept)
diff --git a/sysdeps/generic/strrchr.c b/sysdeps/generic/strrchr.c
index db5549b922..98839ea4c4 100644
--- a/sysdeps/generic/strrchr.c
+++ b/sysdeps/generic/strrchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -18,6 +18,8 @@
 
 #include <string.h>
 
+#undef strrchr
+
 /* Find the last occurrence of C in S.  */
 char *
 strrchr (const char *s, int c)
diff --git a/sysdeps/generic/strsep.c b/sysdeps/generic/strsep.c
index b2c7e90c39..b5ea6ead9d 100644
--- a/sysdeps/generic/strsep.c
+++ b/sysdeps/generic/strsep.c
@@ -18,6 +18,8 @@
 
 #include <string.h>
 
+#undef strsep
+
 char *
 __strsep (char **stringp, const char *delim)
 {
diff --git a/sysdeps/generic/strspn.c b/sysdeps/generic/strspn.c
index 9d2fe63848..5f64a6f756 100644
--- a/sysdeps/generic/strspn.c
+++ b/sysdeps/generic/strspn.c
@@ -18,6 +18,7 @@
 
 #include <string.h>
 
+#undef strspn
 
 /* Return the length of the maximum initial segment
    of S which contains only characters in ACCEPT.  */
diff --git a/sysdeps/generic/strstr.c b/sysdeps/generic/strstr.c
index 85774d3491..03d6c8e5fc 100644
--- a/sysdeps/generic/strstr.c
+++ b/sysdeps/generic/strstr.c
@@ -36,6 +36,8 @@
 
 typedef unsigned chartype;
 
+#undef strstr
+
 char *
 strstr (phaystack, pneedle)
      const char *phaystack;
diff --git a/sysdeps/generic/strtok.c b/sysdeps/generic/strtok.c
index 5eb0ee6f07..b366653cb3 100644
--- a/sysdeps/generic/strtok.c
+++ b/sysdeps/generic/strtok.c
@@ -21,6 +21,8 @@
 
 static char *olds = NULL;
 
+#undef strtok
+
 /* Parse S into tokens separated by characters in DELIM.
    If S is NULL, the last string strtok() was called with is
    used.  For example:
diff --git a/sysdeps/generic/strtok_r.c b/sysdeps/generic/strtok_r.c
index 3b7d202a6c..44430dae40 100644
--- a/sysdeps/generic/strtok_r.c
+++ b/sysdeps/generic/strtok_r.c
@@ -19,6 +19,7 @@
 
 #include <string.h>
 
+#undef strtok_r
 
 /* Parse S into tokens separated by characters in DELIM.
    If S is NULL, the saved pointer in SAVE_PTR is used as
diff --git a/sysdeps/generic/sysd-stdio.c b/sysdeps/generic/sysd-stdio.c
index f5147bb3aa..9818f84c5c 100644
--- a/sysdeps/generic/sysd-stdio.c
+++ b/sysdeps/generic/sysd-stdio.c
@@ -28,10 +28,7 @@
 
 /* Read N bytes into BUF from COOKIE.  */
 int
-__stdio_read (cookie, buf, n)
-     void *cookie;
-     register char *buf;
-     register size_t n;
+__stdio_read (void *cookie, char *buf, size_t n;)
 {
   const int fd = (int) cookie;
 #if	defined (EINTR) && defined (EINTR_REPEAT)
@@ -58,10 +55,7 @@ __stdio_read (cookie, buf, n)
 
 /* Write N bytes from BUF to COOKIE.  */
 int
-__stdio_write (cookie, buf, n)
-     void *cookie;
-     register const char *buf;
-     register size_t n;
+__stdio_write (void *cookie, const char *buf, size_t n)
 {
   const int fd = (int) cookie;
   register size_t written = 0;
@@ -92,10 +86,7 @@ __stdio_write (cookie, buf, n)
    The new file position is stored in *POS.
    Returns zero if successful, nonzero if not.  */
 int
-__stdio_seek (cookie, pos, whence)
-     void *cookie;
-     fpos_t *pos;
-     int whence;
+__stdio_seek (void *cookie, fpos_t *pos, int whence)
 {
   off_t new;
   new = __lseek ((int) cookie, (off_t) *pos, whence);
@@ -108,8 +99,7 @@ __stdio_seek (cookie, pos, whence)
 
 /* Close COOKIE.  */
 int
-__stdio_close (cookie)
-     void *cookie;
+__stdio_close (void *cookie)
 {
   return __close ((int) cookie);
 }
@@ -118,8 +108,7 @@ __stdio_close (cookie)
    or -1 for errors.  If COOKIE does not relate to any POSIX.1 file
    descriptor, this should return -1 with errno set to EOPNOTSUPP.  */
 int
-__stdio_fileno (cookie)
-     void *cookie;
+__stdio_fileno (void *cookie)
 {
   return (int) cookie;
 }
@@ -127,10 +116,7 @@ __stdio_fileno (cookie)
 
 /* Open the given file with the mode given in the __io_mode argument.  */
 int
-__stdio_open (filename, m, cookieptr)
-     const char *filename;
-     __io_mode m;
-     void **cookieptr;
+__stdio_open (const char *filename, __io_mode m, void **cookieptr)
 {
   int fd;
   int mode;
@@ -164,11 +150,8 @@ __stdio_open (filename, m, cookieptr)
 /* Open FILENAME with the mode in M.  Use the same magic cookie
    already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN.  */
 int
-__stdio_reopen (filename, m, cookieptr, closefn)
-     const char *filename;
-     __io_mode m;
-     void **cookieptr;
-     __io_close_fn closefn;
+__stdio_reopen (const char *filename, __io_mode m, void **cookieptr,
+		__io_close_fn closefn)
 {
   void *newcookie;
 
diff --git a/sysdeps/i386/bits/select.h b/sysdeps/i386/bits/select.h
index 8c9a5434b9..edcb562945 100644
--- a/sysdeps/i386/bits/select.h
+++ b/sysdeps/i386/bits/select.h
@@ -24,29 +24,30 @@
 #if defined __GNUC__ && __GNUC__ >= 2
 
 # define __FD_ZERO(fdsetp) \
-  __asm__ __volatile__ ("cld ; rep ; stosl"				      \
-			: "=m" (*(__fd_set *) (fdsetp))			      \
+  __asm__ __volatile__ ("cld; rep; stosl"				      \
+			: "=m" (((__fd_mask *)				      \
+				 (fdsetp))[__FDELT (__FD_SETSIZE)])	      \
 			: "a" (0), "c" (sizeof (__fd_set)		      \
 					/ sizeof (__fd_mask)),		      \
 			  "D" ((__fd_set *) (fdsetp))			      \
 			:"cx","di")
 # define __FD_SET(fd, fdsetp) \
   __asm__ __volatile__ ("btsl %1,%0"					      \
-			: "=m" (((__fd_set *) (fdsetp))[__FDELT (fd)])	      \
+			: "=m" (((__fd_mask *) (fdsetp))[__FDELT (fd)])	      \
 			: "r" (((int) (fd)) % __NFDBITS)		      \
 			: "cc")
 # define __FD_CLR(fd, fdsetp) \
   __asm__ __volatile__ ("btrl %1,%0"					      \
-			: "=m" (((__fd_set *) (fdsetp))[__FDELT (fd)])	      \
+			: "=m" (((__fd_mask *) (fdsetp))[__FDELT (fd)])	      \
 			: "r" (((int) (fd)) % __NFDBITS)		      \
 			: "cc")
 # define __FD_ISSET(fd, fdsetp) \
   (__extension__							      \
-   ({unsigned int __result;						      \
-     __asm__ __volatile__ ("btl %1,%2 ; setcb %b0; andl $1,%0"		      \
+   ({register char __result;						      \
+     __asm__ __volatile__ ("btl %1,%2 ; setcb %b0"			      \
 			   : "=q" (__result)				      \
 			   : "r" (((int) (fd)) % __NFDBITS),		      \
-			     "m" (((__fd_set *) (fdsetp))[__FDELT (fd)])      \
+			     "m" (((__fd_mask *) (fdsetp))[__FDELT (fd)])     \
 			   : "cc");					      \
      __result; }))
 
diff --git a/sysdeps/i386/bits/string.h b/sysdeps/i386/bits/string.h
index 254db3e7f3..2931684781 100644
--- a/sysdeps/i386/bits/string.h
+++ b/sysdeps/i386/bits/string.h
@@ -41,7 +41,7 @@
 __STRING_INLINE void *
 __memcpy_c (void *__dest, __const void *__src, size_t __n)
 {
-  switch (n)
+  switch (__n)
     {
     case 0:
       return __dest;
@@ -102,10 +102,10 @@ __memcpy_c (void *__dest, __const void *__src, size_t __n)
      "rep; movsl"							      \
      x									      \
      : /* no outputs */							      \
-     : "c" (n / 4), "D" (__dest), "S" (__src)				      \
+     : "c" (__n / 4), "D" (__dest), "S" (__src)				      \
      : "cx", "di", "si", "memory");
 
-  switch (n % 4)
+  switch (__n % 4)
     {
     case 0:
       __COMMON_CODE ("");
@@ -232,8 +232,7 @@ __memset_gg (void *__s, char __c, size_t __n)
 {
   __asm__ __volatile__
     ("cld\n\t"
-     "rep\n\t"
-     "stosb"
+     "rep; stosb"
      : /* no output */
      : "a" (__c),"D" (__s), "c" (__n)
      : "cx", "di", "memory");
@@ -518,7 +517,7 @@ strcspn (__const char *__s, __const char *__reject)
      "2:\n\t"
      "popl	%%ebx"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__reject)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
@@ -577,7 +576,7 @@ strspn (__const char *__s, __const char *__accept)
      "2:\n\t"
      "popl	%%ebx"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__accept)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
@@ -639,7 +638,7 @@ strpbrk (__const char *__s, __const char *__accept)
      "3:\n\t"
      "popl	%%ebx"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__accept)
      : "ax", "cx", "di", "cc");
   return __res;
 }
@@ -704,7 +703,7 @@ strstr (__const char *__haystack, __const char *__needle)
      "2:\n\t"
      "popl	%%ebx"
      : "=a" (__res)
-     : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+     : "0" (0), "c" (0xffffffff), "S" (__haystack), "r" (__needle)
      : "cx", "di", "si", "cc");
   return __res;
 }
diff --git a/sysdeps/i386/fpu/bits/mathinline.h b/sysdeps/i386/fpu/bits/mathinline.h
index 17f62a080f..55e9171459 100644
--- a/sysdeps/i386/fpu/bits/mathinline.h
+++ b/sysdeps/i386/fpu/bits/mathinline.h
@@ -28,43 +28,40 @@
    These must not be inline functions since we have to be able to handle
    all floating-point types.  */
 # define isgreater(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al;"	      \
-		 "andl $0x01, %0"					      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define isgreaterequal(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al;"	      \
-		 "andl $0x01, %0"					      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define isless(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; xorb $0x01, %%ah; testb $0x45, %%ah;"      \
-		 "setz %%al; andl $0x01, %0"				      \
+		 "setz %%al"						      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define islessequal(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; xorb $0x01, %%ah; testb $0x05, %%ah;"      \
-		 "setz %%al; andl $0x01, %0"				      \
+		 "setz %%al"						      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define islessgreater(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al;"	      \
-		 "andl $0x01, %0"					      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define isunordered(x, y) \
-     ({ int __result;							      \
-	__asm__ ("fucompp; fnstsw; sahf; setp %%al; andl $0x01, %0"	      \
+     ({ register char __result;						      \
+	__asm__ ("fucompp; fnstsw; sahf; setp %%al"			      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 #endif
diff --git a/sysdeps/i386/i486/atomicity.h b/sysdeps/i386/i486/atomicity.h
new file mode 100644
index 0000000000..98a2531365
--- /dev/null
+++ b/sysdeps/i386/i486/atomicity.h
@@ -0,0 +1,57 @@
+/* Low-level functions for atomitc operations.  ix86 version, x >= 4.
+   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.  */
+
+#ifndef _ATOMICITY_H
+#define _ATOMICITY_H	1
+
+#include <inttypes.h>
+
+
+static inline int
+__attribute__ ((unused))
+exchange_and_add (volatile uint32_t *mem, int val)
+{
+  register int result;
+  __asm__ __volatile__ ("lock; xaddl %0,%1"
+			: "=r" (result) : "0" (val), "m" (*mem) : "memory");
+  return result;
+}
+
+static inline void
+__attribute__ ((unused))
+atomic_add (volatile uint32_t *mem, int val)
+{
+  __asm__ __volatile__ ("lock; addl %0,%1"
+			: : "ir" (val), "m" (*mem) : "memory");
+}
+
+static inline int
+__attribute__ ((unused))
+compare_and_swap (volatile long int *p, long int oldval, long int newval)
+{
+  char ret;
+  long int readval;
+
+  __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
+                        : "=q" (ret), "=m" (*p), "=a" (readval)
+                        : "r" (newval), "m" (*p), "a" (oldval));
+  return ret;
+}
+
+#endif /* atomicity.h */
diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h
index f141bd50e1..770f5c1e15 100644
--- a/sysdeps/i386/i486/bits/string.h
+++ b/sysdeps/i386/i486/bits/string.h
@@ -32,16 +32,19 @@
 
 
 /* Copy N bytes of SRC to DEST.  */
+#define _HAVE_STRING_ARCH_memcpy 1
 #define memcpy(dest, src, n) \
   (__extension__ (__builtin_constant_p (n)				      \
 		  ? __memcpy_c (dest, src, n)				      \
 		  : __memcpy_g (dest, src, n)))
 #define __memcpy_c(dest, src, n) \
-  (((n) % 4 == 0)							      \
-   ? __memcpy_by4 (dest, src, n)					      \
-   : (((n) % 2 == 0)							      \
-      ? __memcpy_by2 (dest, src, n)					      \
-      : __memcpy_g (dest, src, n)))
+  ((n) == 0								      \
+   ? (dest)								      \
+   : (((n) % 4 == 0)							      \
+      ? __memcpy_by4 (dest, src, n)					      \
+      : (((n) % 2 == 0)							      \
+	 ? __memcpy_by2 (dest, src, n)					      \
+	 : __memcpy_g (dest, src, n))))
 
 __STRING_INLINE void *
 __memcpy_by4 (void *__dest, __const void *__src, size_t __n)
@@ -135,6 +138,7 @@ memmove (void *__dest, __const void *__src, size_t __n)
 
 
 /* Compare N bytes of S1 and S2.  */
+#define _HAVE_STRING_ARCH_memcmp 1
 #ifndef __PIC__
 /* gcc has problems to spill registers when using PIC.  */
 __STRING_INLINE int
@@ -157,6 +161,7 @@ memcmp (__const void *__s1, __const void *__s2, size_t __n)
 
 
 /* Set N bytes of S to C.  */
+#define _HAVE_STRING_ARCH_memset 1
 #define memset(s, c, n) \
   (__extension__ (__builtin_constant_p (c)				      \
 		  ? (__builtin_constant_p (n)				      \
@@ -166,17 +171,21 @@ memcmp (__const void *__s1, __const void *__s2, size_t __n)
 		     ? __memset_gc (s, c, n)				      \
 		     : __memset_gg (s, c, n))))
 #define __memset_cc(s, c, n) \
-  (((n) % 4 == 0)							      \
-   ? __memset_cc_by4 (s, c, n)						      \
-   : (((n) % 2== 0)							      \
-      ? __memset_cc_by2 (s, c, n)					      \
-      : __memset_cg (s, c, n)))
+  ((n) == 0								      \
+   ? (s)								      \
+   : (((n) % 4 == 0)							      \
+      ? __memset_cc_by4 (s, c, n)					      \
+      : (((n) % 2== 0)							      \
+	 ? __memset_cc_by2 (s, c, n)					      \
+	 : __memset_cg (s, c, n))))
 #define __memset_gc(s, c, n) \
-  (((n) % 4== 0)							      \
-   ? __memset_gc_by4 (s, c, n)						      \
-   : (((n) % 2 == 0)							      \
-      ? __memset_gc_by2 (s, c, n)					      \
-      : __memset_gg (s, c, n)))
+  ((n) == 0								      \
+   ? (s)								      \
+   : (((n) % 4== 0)							      \
+      ? __memset_gc_by4 (s, c, n)					      \
+      : (((n) % 2 == 0)							      \
+	 ? __memset_gc_by2 (s, c, n)					      \
+	 : __memset_gg (s, c, n))))
 
 __STRING_INLINE void *
 __memset_cc_by4 (void *__s, int __c, size_t __n)
@@ -196,7 +205,7 @@ __memset_cc_by4 (void *__s, int __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_cc_by2 (void *__s, char __c, size_t __n)
+__memset_cc_by2 (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   register int __dummy;
@@ -217,7 +226,7 @@ __memset_cc_by2 (void *__s, char __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_gc_by4 (void *__s, char __c, size_t __n)
+__memset_gc_by4 (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   register int __dummy;
@@ -238,7 +247,7 @@ __memset_gc_by4 (void *__s, char __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_gc_by2 (void *__s, char __c, size_t __n)
+__memset_gc_by2 (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   register int __dummy1, __dummy2;
@@ -263,7 +272,7 @@ __memset_gc_by2 (void *__s, char __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_cg (void *__s, char __c, size_t __n)
+__memset_cg (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   __asm__ __volatile__
@@ -279,7 +288,7 @@ __memset_cg (void *__s, char __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_gg (void *__s, char __c, size_t __n)
+__memset_gg (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   __asm__ __volatile__
@@ -297,6 +306,7 @@ __memset_gg (void *__s, char __c, size_t __n)
 
 
 /* Search N bytes of S for C.  */
+#define _HAVE_STRING_ARCH_memchr 1
 __STRING_INLINE void *
 memchr (__const void *__s, int __c, size_t __n)
 {
@@ -318,16 +328,21 @@ memchr (__const void *__s, int __c, size_t __n)
 
 
 /* Return the length of S.  */
+#define _HAVE_STRING_ARCH_strlen 1
+#define strlen(str) \
+  (__extension__ (__builtin_constant_p (str)				      \
+		  ? sizeof (str) - 1					      \
+		  : __strlen_g (str)))
 __STRING_INLINE size_t
-strlen (__const char *__str)
+__strlen_g (__const char *__str)
 {
   register char __dummy;
   register __const char *__tmp = __str;
   __asm__ __volatile__
     ("1:\n\t"
-     "movb	(%0),%1\n\t"
+     "movb	(%0),%b1\n\t"
      "leal	1(%0),%0\n\t"
-     "testb	%1,%1\n\t"
+     "testb	%b1,%b1\n\t"
      "jne	1b"
      : "=r" (__tmp), "=q" (__dummy)
      : "0" (__str)
@@ -337,19 +352,25 @@ strlen (__const char *__str)
 
 
 /* Copy SRC to DEST.  */
+#define _HAVE_STRING_ARCH_strcpy 1
+#define strcpy(dest, src) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? (char *) memcpy (dest, src, strlen (src) + 1)	      \
+		  : __strcpy_g (dest, src)))
+
 __STRING_INLINE char *
-strcpy (char *__dest, __const char *__src)
+__strcpy_g (char *__dest, __const char *__src)
 {
   register char *__tmp = __dest;
   register char __dummy;
   __asm__ __volatile__
     (
      "1:\n\t"
-     "movb	(%0),%2\n\t"
-     "incl	%0\n\t"
-     "movb	%2,(%1)\n\t"
-     "incl	%1\n\t"
-     "testb	%2,%2\n\t"
+     "movb	(%0),%b2\n\t"
+     "leal	1(%0),%0\n\t"
+     "movb	%b2,(%1)\n\t"
+     "leal	1(%1),%1\n\t"
+     "testb	%b2,%b2\n\t"
      "jne	1b"
      : "=r" (__src), "=r" (__tmp), "=q" (__dummy)
      : "0" (__src), "1" (__tmp)
@@ -358,9 +379,233 @@ strcpy (char *__dest, __const char *__src)
 }
 
 
+#ifdef __USE_GNU
+# define _HAVE_STRING_ARCH_stpcpy 1
+/* Copy SRC to DEST.  */
+# define __stpcpy(dest, src) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? (strlen (src) + 1 <= 8				      \
+		     ? __stpcpy_small (dest, src, strlen (src) + 1)	      \
+		     : __stpcpy_c (dest, src, strlen (src) + 1))	      \
+		  : __stpcpy_g (dest, src)))
+# define __stpcpy_c(dest, src, srclen) \
+  ((srclen) % 4 == 0							      \
+   ? __mempcpy_by4 (dest, src, srclen)					      \
+   : ((srclen) % 2 == 0							      \
+      ? __mempcpy_by2 (dest, src, srclen)				      \
+      : __mempcpy_byn (dest, src, srclen)))
+
+/* In glibc itself we use this symbol for namespace reasons.  */
+# define stpcpy(dest, src) __stpcpy (dest, src)
+
+__STRING_INLINE char *
+__stpcpy_small (char *__dest, __const char __src[], size_t __srclen)
+{
+  register char *__tmp = __dest;
+  switch (__srclen)
+    {
+    case 7:
+      *((unsigned short int *) __tmp)++ = *((unsigned short int *) __src)++;
+    case 5:
+      *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+      *((unsigned char *) __tmp) = '\0';
+      return __tmp;
+
+    case 8:
+      *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+    case 4:
+      *((unsigned int *) __tmp) = *((unsigned int *) __src);
+      return __tmp + 3;
+
+    case 6:
+      *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+    case 2:
+      *((unsigned short int *) __tmp) = *((unsigned short int *) __src);
+      return __tmp + 1;
+
+    case 3:
+      *((unsigned short int *) __tmp)++ = *((unsigned short int *) __src)++;
+    case 1:
+      *((unsigned char *) __tmp) = '\0';
+      return __tmp;
+
+    default:
+      break;
+    }
+  /* This should never happen.  */
+  return NULL;
+}
+
+__STRING_INLINE char *
+__mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
+{
+  register char *__tmp = __dest;
+  register int __dummy1, __dummy2;
+  __asm__ __volatile__
+    ("1:\n\t"
+     "movl	(%2),%0\n\t"
+     "leal	4(%2),%2\n\t"
+     "movl	%0,(%1)\n\t"
+     "leal	4(%1),%1\n\t"
+     "decl	%3\n\t"
+     "jnz	1b"
+     : "=r" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+     : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
+     : "memory", "cc");
+  return __tmp - 1;
+}
+
+__STRING_INLINE char *
+__mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
+{
+  register char *__tmp = __dest;
+  register int __dummy1, __dummy2;
+  __asm__ __volatile__
+    ("shrl	$1,%3\n\t"
+     "jz	2f\n"                 /* only a word */
+     "1:\n\t"
+     "movl	(%2),%0\n\t"
+     "leal	4(%2),%2\n\t"
+     "movl	%0,(%1)\n\t"
+     "leal	4(%1),%1\n\t"
+     "decl	%3\n\t"
+     "jnz	1b\n"
+     "2:\n\t"
+     "movw	(%2),%w0\n\t"
+     "movw	%w0,(%1)"
+     : "=q" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+     : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
+     : "memory", "cc");
+  return __tmp + 1;
+}
+
+__STRING_INLINE char *
+__mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
+{
+  register char *__tmp = __dest;
+  __asm__ __volatile__
+    ("cld\n\t"
+     "shrl	$1,%%ecx\n\t"
+     "jnc	1f\n\t"
+     "movsb\n"
+     "1:\n\t"
+     "shrl	$1,%%ecx\n\t"
+     "jnc	2f\n\t"
+     "movsw\n"
+     "2:\n\t"
+     "rep; movsl"
+     : "=D" (__tmp)
+     : "c" (__srclen), "0" (__tmp),"S" (__src)
+     : "cx", "di", "si", "memory", "cc");
+  return __tmp - 1;
+}
+
+__STRING_INLINE char *
+__stpcpy_g (char *__dest, __const char *__src)
+{
+  register char *__tmp = __dest;
+  register char __dummy;
+  __asm__ __volatile__
+    (
+     "1:\n\t"
+     "movb	(%0),%b2\n\t"
+     "leal	1(%0),%0\n\t"
+     "movb	%b2,(%1)\n\t"
+     "leal	1(%1),%1\n\t"
+     "testb	%b2,%b2\n\t"
+     "jne	1b"
+     : "=r" (__src), "=r" (__tmp), "=q" (__dummy)
+     : "0" (__src), "1" (__tmp)
+     : "memory", "cc");
+  return __tmp - 1;
+}
+#endif
+
+
 /* Copy no more than N characters of SRC to DEST.  */
+#define _HAVE_STRING_ARCH_strncpy 1
+#define strncpy(dest, src, n) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? ((strlen (src) + 1 >= ((size_t) (n))		      \
+		      ? (char *) memcpy (dest, src, n)			      \
+		      : __strncpy_cg (dest, src, strlen (src) + 1, n)))	      \
+		  : __strncpy_gg (dest, src, n)))
+#define __strncpy_cg(dest, src, srclen, n) \
+  (((srclen) % 4 == 0)							      \
+   ? __strncpy_by4 (dest, src, srclen, n)				      \
+   : (((srclen) % 2 == 0)						      \
+      ? __strncpy_by2 (dest, src, srclen, n)				      \
+      : __strncpy_byn (dest, src, srclen, n)))
+
+__STRING_INLINE char *
+__strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+  register char *__tmp = __dest;
+  register int __dummy1, __dummy2;
+  __asm__ __volatile__
+    ("1:\n\t"
+     "movl	(%2),%0\n\t"
+     "leal	4(%2),%2\n\t"
+     "movl	%0,(%1)\n\t"
+     "leal	4(%1),%1\n\t"
+     "decl	%3\n\t"
+     "jnz	1b"
+     : "=r" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+     : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
+     : "memory", "cc");
+  (void) memset (__tmp, '\0', __n - __srclen);
+  return __dest;
+}
+
 __STRING_INLINE char *
-strncpy (char *__dest, __const char *__src, size_t __n)
+__strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+  register char *__tmp = __dest;
+  register int __dummy1, __dummy2;
+  __asm__ __volatile__
+    ("shrl	$1,%3\n\t"
+     "jz	2f\n"                 /* only a word */
+     "1:\n\t"
+     "movl	(%2),%0\n\t"
+     "leal	4(%2),%2\n\t"
+     "movl	%0,(%1)\n\t"
+     "leal	4(%1),%1\n\t"
+     "decl	%3\n\t"
+     "jnz	1b\n"
+     "2:\n\t"
+     "movw	(%2),%w0\n\t"
+     "movw	%w0,(%1)\n\t"
+     : "=q" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+     : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
+     : "memory", "cc");
+  (void) memset (__tmp + 2, '\0', __n - __srclen);
+  return __dest;
+}
+
+__STRING_INLINE char *
+__strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+  register char *__tmp = __dest;
+  __asm__ __volatile__
+    ("cld\n\t"
+     "shrl	$1,%%ecx\n\t"
+     "jnc	1f\n\t"
+     "movsb\n"
+     "1:\n\t"
+     "shrl	$1,%%ecx\n\t"
+     "jnc	2f\n\t"
+     "movsw\n"
+     "2:\n\t"
+     "rep; movsl"
+     : "=D" (__tmp)
+     : "c" (__srclen), "0" (__tmp),"S" (__src)
+     : "cx", "di", "si", "memory", "cc");
+  (void) memset (__tmp, '\0', __n - __srclen);
+  return __dest;
+}
+
+__STRING_INLINE char *
+__strncpy_gg (char *__dest, __const char *__src, size_t __n)
 {
   register char *__tmp = __dest;
   register char __dummy;
@@ -390,14 +635,35 @@ strncpy (char *__dest, __const char *__src, size_t __n)
 
 
 /* Append SRC onto DEST.  */
+#define _HAVE_STRING_ARCH_strcat 1
+#define strcat(dest, src) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? __strcat_c (dest, src, strlen (src) + 1)		      \
+		  : __strcat_g (dest, src)))
+
+__STRING_INLINE char *
+__strcat_c (char *__dest, __const char __src[], size_t __srclen)
+{
+  register char *__tmp = __dest - 1;
+  __asm__ __volatile__
+    ("1:\n\t"
+     "incl	%0\n\t"
+     "cmpb	$0,(%0)\n\t"
+     "jne	1b\n"
+     : "=r" (__tmp)
+     : "0" (__tmp)
+     : "cc");
+  (void) memcpy (__tmp, __src, __srclen);
+  return __dest;
+}
+
 __STRING_INLINE char *
-strcat (char *__dest, __const char *__src)
+__strcat_g (char *__dest, __const char *__src)
 {
   register char *__tmp = __dest - 1;
   register char __dummy;
   __asm__ __volatile__
-    (
-     "1:\n\t"
+    ("1:\n\t"
      "incl	%1\n\t"
      "cmpb	$0,(%1)\n\t"
      "jne	1b\n"
@@ -416,16 +682,23 @@ strcat (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)))
+
 __STRING_INLINE char *
-strncat (char *__dest, __const char *__src, size_t __n)
+__strncat_g (char *__dest, __const char __src[], size_t __n)
 {
   register char *__tmp = __dest - 1;
   register char __dummy;
   __asm__ __volatile__
-    (
-     "1:\n\t"
-     "incl	%1\n\t"
-     "cmpb	$0,(%1)\n\t"
+    ("1:\n\t"
+     "cmpb	$0,1(%1)\n\t"
+     "leal	1(%1),%1\n\t"
      "jne	1b\n"
      "2:\n\t"
      "decl	%3\n\t"
@@ -435,7 +708,8 @@ strncat (char *__dest, __const char *__src, size_t __n)
      "movb	%b0,(%1)\n\t"
      "leal	1(%1),%1\n\t"
      "testb	%b0,%b0\n\t"
-     "jne	2b\n"
+     "jne	2b\n\t"
+     "decl	%1\n"
      "3:\n\t"
      "movb	$0,(%1)\n\t"
      : "=q" (__dummy), "=r" (__tmp), "=r" (__src), "=r" (__n)
@@ -446,6 +720,7 @@ strncat (char *__dest, __const char *__src, size_t __n)
 
 
 /* Compare S1 and S2.  */
+#define _HAVE_STRING_ARCH_strcmp 1
 __STRING_INLINE int
 strcmp (__const char *__s1, __const char *__s2)
 {
@@ -474,8 +749,16 @@ strcmp (__const char *__s1, __const char *__s2)
 
 
 /* Compare N characters of S1 and S2.  */
+#define _HAVE_STRING_ARCH_strncmp 1
+#define strncmp(s1, s2, n) \
+  (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n))   \
+		  ? strcmp (s1, s2)					      \
+		  : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
+		     ? strcmp (s1, s2)					      \
+		     : __strncmp_g (s1, s2, n))))
+
 __STRING_INLINE int
-strncmp (__const char *__s1, __const char *__s2, size_t __n)
+__strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
 {
   register int __res;
   __asm__ __volatile__
@@ -505,18 +788,18 @@ strncmp (__const char *__s1, __const char *__s2, size_t __n)
 
 
 /* Find the first occurrence of C in S.  */
+#define _HAVE_STRING_ARCH_strchr 1
 #define strchr(s, c) \
   (__extension__ (__builtin_constant_p (c)				      \
 		  ? __strchr_c (s, ((c) & 0xff) << 8)			      \
 		  : __strchr_g (s, c)))
 
 __STRING_INLINE char *
-__strchr_g (__const char *__s, int __c)
+__strchr_c (__const char *__s, int __c)
 {
   register char *__res;
   __asm__ __volatile__
-    ("movb	%%al,%%ah\n"
-     "1:\n\t"
+    ("1:\n\t"
      "movb	(%0),%%al\n\t"
      "cmpb	%%ah,%%al\n\t"
      "je	2f\n\t"
@@ -532,11 +815,12 @@ __strchr_g (__const char *__s, int __c)
 }
 
 __STRING_INLINE char *
-__strchr_c (__const char *__s, int __c)
+__strchr_g (__const char *__s, int __c)
 {
   register char *__res;
   __asm__ __volatile__
-    ("1:\n\t"
+    ("movb	%%al,%%ah\n"
+     "1:\n\t"
      "movb	(%0),%%al\n\t"
      "cmpb	%%ah,%%al\n\t"
      "je	2f\n\t"
@@ -553,18 +837,56 @@ __strchr_c (__const char *__s, int __c)
 
 
 /* Find the last occurrence of C in S.  */
+#define _HAVE_STRING_ARCH_strrchr 1
 #define strrchr(s, c) \
   (__extension__ (__builtin_constant_p (c)				      \
 		  ? __strrchr_c (s, ((c) & 0xff) << 8)			      \
 		  : __strrchr_g (s, c)))
 
+#ifdef __i686__
+__STRING_INLINE char *
+__strrchr_c (__const char *__s, int __c)
+{
+  register char *__res;
+  __asm__ __volatile__
+    ("cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "cmpb	%%ah,%%al\n\t"
+     "cmovne	%%esi,%0\n\t"
+     "testb	%%al,%%al\n\t"
+     "jne 1b"
+     : "=d" (__res)
+     : "0" (1), "S" (__s),"a" (__c)
+     : "ax", "si", "cc");
+  return __res - 1;
+}
+
 __STRING_INLINE char *
 __strrchr_g (__const char *__s, int __c)
 {
   register char *__res;
   __asm__ __volatile__
-    ("cld\n\t"
-     "movb	%%al,%%ah\n"
+    ("movb	%%al,%%ah\n"
+     "cld\n\t"
+     "1:\n\t"
+     "lodsb\n\t"
+     "cmpb	%%ah,%%al\n\t"
+     "cmovne	%%esi,%0\n\t"
+     "testb	%%al,%%al\n\t"
+     "jne 1b"
+     : "=r" (__res)
+     : "0" (1), "S" (__s),"a" (__c)
+     : "ax", "si", "cc");
+  return __res - 1;
+}
+#else
+__STRING_INLINE char *
+__strrchr_c (__const char *__s, int __c)
+{
+  register char *__res;
+  __asm__ __volatile__
+    ("cld\n"
      "1:\n\t"
      "lodsb\n\t"
      "cmpb	%%ah,%%al\n\t"
@@ -580,11 +902,12 @@ __strrchr_g (__const char *__s, int __c)
 }
 
 __STRING_INLINE char *
-__strrchr_c (__const char *__s, int __c)
+__strrchr_g (__const char *__s, int __c)
 {
   register char *__res;
   __asm__ __volatile__
-    ("cld\n\t"
+    ("movb	%%al,%%ah\n"
+     "cld\n\t"
      "1:\n\t"
      "lodsb\n\t"
      "cmpb	%%ah,%%al\n\t"
@@ -593,66 +916,140 @@ __strrchr_c (__const char *__s, int __c)
      "2:\n\t"
      "testb	%%al,%%al\n\t"
      "jne 1b"
-     : "=d" (__res)
+     : "=r" (__res)
      : "0" (0), "S" (__s),"a" (__c)
      : "ax", "si", "cc");
   return __res;
 }
+#endif
 
 
 /* Return the length of the initial segment of S which
    consists entirely of characters not in REJECT.  */
-#ifdef __PIC__
+#define _HAVE_STRING_ARCH_strcspn 1
+#define strcspn(s, reject) \
+  (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1  \
+		  ? ((reject)[0] == '\0'				      \
+		     ? strlen (s)					      \
+		     : ((reject)[1] == '\0'				      \
+			? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00))     \
+			: __strcspn_cg (s, reject, strlen (reject))))	      \
+		  : __strcspn_g (s, reject)))
+
 __STRING_INLINE size_t
-strcspn (__const char *__s, __const char *__reject)
+__strcspn_c1 (__const char *__s, int __reject)
 {
   register char *__res;
   __asm__ __volatile__
-    ("push	%%ebx\n\t"
-     "cld\n\t"
+    ("1:\n\t"
+     "movb	(%0),%%al\n\t"
+     "leal	1(%0),%0\n\t"
+     "cmpb	%%ah,%%al\n\t"
+     "je	2f\n\t"
+     "testb	%%al,%%al\n\t"
+     "jne	1b\n"
+     "2:"
+     : "=r" (__res)
+     : "a" (__reject), "0" (__s)
+     : "ax", "cc");
+  return (__res - 1) - __s;
+}
+
+#ifdef __PIC__
+__STRING_INLINE size_t
+__strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
+{
+  register __const char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%ecx,%%ebx\n\t"
+     "cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
      "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "jne	1b\n"
+     "2:\n\t"
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=&m" (__mem)
+     : "c" (__reject_len), "0" (__s), "r" (__reject), "1" (__mem)
+     : "ax", "cx", "di", "cc");
+  return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strcspn_g (__const char *__s, __const char *__reject)
+{
+  register __const char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
+     "movl	%5,%%edi\n\t"
+     "cld\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "leal	-1(%%ecx),%%ebx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%5,%%edi\n\t"
      "movl	%%ebx,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n"
      "2:\n\t"
-     "popl	%%ebx"
-     : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=&m" (__mem)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__reject), "1" (__mem)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
 #else
 __STRING_INLINE size_t
-strcspn (__const char *__s, __const char *__reject)
+__strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
 {
-  register char *__res;
+  register __const char *__res;
+  __asm__ __volatile__
+    ("cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%ebx,%%edi\n\t"
+     "movl	%%edx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "jne	1b\n"
+     "2:"
+     : "=S" (__res)
+     : "d" (__reject_len), "0" (__s), "b" (__reject)
+     : "ax", "cx", "di", "cc");
+  return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strcspn_g (__const char *__s, __const char *__reject)
+{
+  register __const char *__res;
   __asm__ __volatile__
     ("cld\n\t"
-     "movl	%4,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%edx\n"
+     "leal	-1(%%ecx),%%edx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%edi\n\t"
      "movl	%%edx,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n"
      "2:"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__reject), "D" (__reject)
      : "ax", "cx", "dx", "di", "cc");
   return (__res - 1) - __s;
 }
@@ -661,57 +1058,129 @@ strcspn (__const char *__s, __const char *__reject)
 
 /* Return the length of the initial segment of S which
    consists entirely of characters in ACCEPT.  */
-#ifdef __PIC__
+#define _HAVE_STRING_ARCH_strspn 1
+#define strspn(s, accept) \
+  (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1  \
+		  ? ((accept)[0] == '\0'				      \
+		     ? 0						      \
+		     : ((accept)[1] == '\0'				      \
+			? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00))     \
+			: __strspn_cg (s, accept, strlen (accept))))	      \
+		  : __strspn_g (s, accept)))
+
 __STRING_INLINE size_t
-strspn (__const char *__s, __const char *__accept)
+__strspn_c1 (__const char *__s, int __accept)
 {
   register char *__res;
+  /* Please note that __accept never can be '\0'.  */
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
+    ("1:\n\t"
+     "movb	(%0),%%al\n\t"
+     "leal	1(%0),%0\n\t"
+     "cmpb	%%ah,%%al\n\t"
+     "je	1b\n"
+     "2:"
+     : "=r" (__res)
+     : "a" (__accept), "0" (__s)
+     : "ax", "cc");
+  return (__res - 1) - __s;
+}
+
+#ifdef __PIC__
+__STRING_INLINE size_t
+__strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
+{
+  register __const char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%ecx,%%ebx\n\t"
+     "cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%edx,%%edi\n\t"
+     "movl	%%ebx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "je	1b\n"
+     "2:\n\t"
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=m" (__mem)
+     : "c" (__accept_len), "0" (__s), "d" (__accept), "1" (__mem)
+     : "ax", "cx", "di", "cc");
+  return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strspn_g (__const char *__s, __const char *__accept)
+{
+  register __const char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
      "cld\n\t"
-     "movl	%4,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "leal	-1(%%ecx),%%ebx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%edx,%%edi\n\t"
      "movl	%%ebx,%%ecx\n\t"
      "repne; scasb\n\t"
      "je	1b\n"
      "2:\n\t"
-     "popl	%%ebx"
-     : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=m" (__mem)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "d" (__accept), "1" (__mem),
+       "D" (__accept)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
 #else
 __STRING_INLINE size_t
-strspn (__const char *__s, __const char *__accept)
+__strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
 {
-  register char *__res;
+  register __const char *__res;
+  __asm__ __volatile__
+    ("cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%ebx,%%edi\n\t"
+     "movl	%%edx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "je	1b\n"
+     "2:"
+     : "=S" (__res)
+     : "d" (__accept_len), "0" (__s), "b" (__accept), "D" (__accept)
+     : "ax", "cx", "dx", "di", "cc");
+  return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strspn_g (__const char *__s, __const char *__accept)
+{
+  register __const char *__res;
   __asm__ __volatile__
     ("cld\n\t"
-     "movl	%4,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%edx\n"
+     "leal	-1(%%ecx),%%edx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%edi\n\t"
      "movl	%%edx,%%ecx\n\t"
      "repne; scasb\n\t"
      "je	1b\n"
      "2:"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__accept), "D" (__accept)
      : "ax", "cx", "dx", "di", "cc");
   return (__res - 1) - __s;
 }
@@ -719,24 +1188,63 @@ strspn (__const char *__s, __const char *__accept)
 
 
 /* Find the first occurrence in S of any character in ACCEPT.  */
+#define _HAVE_STRING_ARCH_strpbrk 1
+#define strpbrk(s, accept) \
+  (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1  \
+		  ? ((accept)[0] == '\0'				      \
+		     ? NULL						      \
+		     : ((accept)[1] == '\0'				      \
+			? strchr (s, (accept)[0])			      \
+			: __strpbrk_cg (s, accept, strlen (accept))))	      \
+		  : __strpbrk_g (s, accept)))
+
 #ifdef __PIC__
 __STRING_INLINE char *
-strpbrk (__const char *__s, __const char *__accept)
+__strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
 {
   register char *__res;
+  int __mem;
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%ecx,%%ebx\n\t"
+     "cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%edx,%%edi\n\t"
+     "movl	%%ebx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "jne	1b\n\t"
+     "decl	%0\n\t"
+     "jmp	3f\n"
+     "2:\n\t"
+     "xorl	%0,%0\n"
+     "3:\n\t"
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=m" (__mem)
+     : "c" (__accept_len), "0" (__s), "d" (__accept), "1" (__mem)
+     : "ax", "cx", "di", "cc");
+  return __res;
+}
+
+__STRING_INLINE char *
+__strpbrk_g (__const char *__s, __const char *__accept)
+{
+  register char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%edx,%%edi\n\t"
      "cld\n\t"
-     "movl	%4,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "leal	-1(%%ecx),%%ebx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%edx,%%edi\n\t"
      "movl	%%ebx,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n\t"
@@ -745,29 +1253,54 @@ strpbrk (__const char *__s, __const char *__accept)
      "2:\n\t"
      "xorl	%0,%0\n"
      "3:\n\t"
-     "popl	%%ebx"
-     : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=m" (__mem)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "d" (__accept), "1" (__mem)
      : "ax", "cx", "di", "cc");
   return __res;
 }
 #else
 __STRING_INLINE char *
-strpbrk (__const char *__s, __const char *__accept)
+__strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
 {
   register char *__res;
   __asm__ __volatile__
-    ("cld\n\t"
-     "movl	%4,%%edi\n\t"
+    ("movl	%%ebx,%%edi\n\t"
+     "cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%ebx,%%edi\n\t"
+     "movl	%%edx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "jne	1b\n\t"
+     "decl	%0\n\t"
+     "jmp	3f\n"
+     "2:\n\t"
+     "xorl	%0,%0\n"
+     "3:"
+     : "=S" (__res)
+     : "d" (__accept_len), "0" (__s), "b" (__accept)
+     : "ax", "cx", "dx", "di", "cc");
+  return __res;
+}
+
+__STRING_INLINE char *
+__strpbrk_g (__const char *__s, __const char *__accept)
+{
+  register char *__res;
+  __asm__ __volatile__
+    ("movl	%%ebx,%%edi\n\t"
+     "cld\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%edx\n"
+     "leal	-1(%%ecx),%%edx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%edi\n\t"
      "movl	%%edx,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n\t"
@@ -777,7 +1310,7 @@ strpbrk (__const char *__s, __const char *__accept)
      "xorl	%0,%0\n"
      "3:"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__accept)
      : "ax", "cx", "dx", "di", "cc");
   return __res;
 }
@@ -785,63 +1318,138 @@ strpbrk (__const char *__s, __const char *__accept)
 
 
 /* Find the first occurrence of NEEDLE in HAYSTACK.  */
+#define _HAVE_STRING_ARCH_strstr 1
 #ifdef __PIC__
+/* XXX GCC has problems to spill the registers.  */
+# define strstr(haystack, needle) \
+  (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1  \
+		  ? ((needle)[0] == '\0'				      \
+		     ? haystack						      \
+		     : ((needle)[1] == '\0'				      \
+			? strchr (haystack, (needle)[0])		     \
+			: strstr (haystack, needle)))			      \
+		  : strstr (haystack, needle)))
+
+# if 0
+/* Please note that this function need not handle NEEDLEs with a
+   length shorter than two.  */
 __STRING_INLINE char *
-strstr (__const char *__haystack, __const char *__needle)
+__strstr_cg (__const char *__haystack, __const char __needle[],
+	     size_t __needle_len)
 {
   register char *__res;
+  int __mem;
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
-     "cld\n\t" \
-     "movl	%4,%%edi\n\t"
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%ecx,%%ebx\n"
+     "cld\n" \
+     "1:\n\t"
+     "movl	%%edx,%%edi\n\t"
+     "movl	%%esi,%%eax\n\t"
+     "movl	%%ebx,%%ecx\n\t"
+     "repe; cmpsb\n\t"
+     "je	2f\n\t"
+     "cmpb	$0,-1(%%esi)\n\t"
+     "leal	1(%%eax),%%esi\n\t"
+     "jne	1b\n\t"
+     "xorl	%%eax,%%eax\n"
+     "2:\n\t"
+     "movl	%1,%%ebx"
+     : "=a" (__res), "=m" (__mem)
+     : "c" (__needle_len), "S" (__haystack), "d" (__needle), "1" (__mem)
+     : "cx", "di", "si", "cc");
+  return __res;
+}
+
+__STRING_INLINE char *
+__strstr_g (__const char *__haystack, __const char *__needle)
+{
+  register char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%2,%%edi\n\t"
+     "cld\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
+     "movl	%%ebx,%1\n\t"
      "decl	%%ecx\n\t"	/* NOTE! This also sets Z if searchstring='' */
      "movl	%%ecx,%%ebx\n"
      "1:\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%edx,%%edi\n\t"
      "movl	%%esi,%%eax\n\t"
      "movl	%%ebx,%%ecx\n\t"
      "repe; cmpsb\n\t"
      "je	2f\n\t"		/* also works for empty string, see above */
-     "xchgl	%%eax,%%esi\n\t"
-     "incl	%%esi\n\t"
-     "cmpb	$0,-1(%%eax)\n\t"
+     "cmpb	$0,-1(%%esi)\n\t"
+     "leal	1(%%eax),%%esi\n\t"
      "jne	1b\n\t"
-     "xorl	%%eax,%%eax\n\t"
+     "xorl	%%eax,%%eax\n"
      "2:\n\t"
-     "popl	%%ebx"
-     : "=a" (__res)
-     : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+     "movl	%1,%%ebx"
+     : "=a" (__res), "=&m" (__mem)
+     : "0" (0), "c" (0xffffffff), "S" (__haystack), "d" (__needle), "1" (__mem)
      : "cx", "di", "si", "cc");
   return __res;
 }
+# endif
 #else
+# define strstr(haystack, needle) \
+  (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1  \
+		  ? ((needle)[0] == '\0'				      \
+		     ? haystack						      \
+		     : ((needle)[1] == '\0'				      \
+			? strchr (haystack, (needle)[0]) 		      \
+			: __strstr_cg (haystack, needle, strlen (needle))))   \
+		  : __strstr_g (haystack, needle)))
+
 __STRING_INLINE char *
-strstr (__const char *__haystack, __const char *__needle)
+__strstr_cg (__const char *__haystack, __const char __needle[],
+	     size_t __needle_len)
 {
   register char *__res;
   __asm__ __volatile__
-    ("cld\n\t" \
-     "movl	%4,%%edi\n\t"
+    ("cld\n" \
+     "1:\n\t"
+     "movl	%%ebx,%%edi\n\t"
+     "movl	%%esi,%%eax\n\t"
+     "movl	%%edx,%%ecx\n\t"
+     "repe; cmpsb\n\t"
+     "je	2f\n\t"
+     "cmpb	$0,-1(%%esi)\n\t"
+     "leal	1(%%eax),%%esi\n\t"
+     "jne	1b\n\t"
+     "xorl	%%eax,%%eax\n"
+     "2:"
+     : "=a" (__res)
+     : "d" (__needle_len), "S" (__haystack), "b" (__needle)
+     : "cx", "dx", "di", "si", "cc");
+  return __res;
+}
+
+__STRING_INLINE char *
+__strstr_g (__const char *__haystack, __const char *__needle)
+{
+  register char *__res;
+  __asm__ __volatile__
+    ("movl	%1,%%edi\n\t"
+     "cld\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
      "decl	%%ecx\n\t"	/* NOTE! This also sets Z if searchstring='' */
      "movl	%%ecx,%%edx\n"
      "1:\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%edi\n\t"
      "movl	%%esi,%%eax\n\t"
      "movl	%%edx,%%ecx\n\t"
      "repe; cmpsb\n\t"
      "je	2f\n\t"		/* also works for empty string, see above */
-     "xchgl	%%eax,%%esi\n\t"
-     "incl	%%esi\n\t"
-     "cmpb	$0,-1(%%eax)\n\t"
+     "cmpb	$0,-1(%%esi)\n\t"
+     "leal	1(%%eax),%%esi\n\t"
      "jne	1b\n\t"
-     "xorl	%%eax,%%eax\n\t"
+     "xorl	%%eax,%%eax\n"
      "2:"
      : "=a" (__res)
-     : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+     : "0" (0), "c" (0xffffffff), "S" (__haystack), "b" (__needle)
      : "cx", "dx", "di", "si", "cc");
   return __res;
 }
diff --git a/sysdeps/i386/machine-gmon.h b/sysdeps/i386/machine-gmon.h
index 496a57eb84..e1155989d4 100644
--- a/sysdeps/i386/machine-gmon.h
+++ b/sysdeps/i386/machine-gmon.h
@@ -1,4 +1,4 @@
-/* i386-specific implemetation of profiling support.
+/* i386-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.
@@ -36,6 +36,6 @@ void mcount_internal (u_long frompc, u_long selfpc);
 void mcount_internal (u_long frompc, u_long selfpc)
 
 
-/* Define MCOUNT as empty since we have a the implementation in another
+/* Define MCOUNT as empty since we have the implementation in another
    file.  */
 #define MCOUNT
diff --git a/sysdeps/i386/memset.c b/sysdeps/i386/memset.c
index 454c7385af..0cb6578df6 100644
--- a/sysdeps/i386/memset.c
+++ b/sysdeps/i386/memset.c
@@ -23,6 +23,8 @@
 
 #ifdef	__GNUC__
 
+#undef memset
+
 void *
 memset (void *dstpp, int c, size_t len)
 {
diff --git a/sysdeps/mach/hurd/profil.c b/sysdeps/mach/hurd/profil.c
index d76cc25a3c..365b11bed3 100644
--- a/sysdeps/mach/hurd/profil.c
+++ b/sysdeps/mach/hurd/profil.c
@@ -103,7 +103,7 @@ __profile_frequency (void)
 }
 
 int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 {
   error_t err;
 
@@ -132,6 +132,7 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 
   return err ? __hurd_fail (err) : 0;
 }
+weak_alias (__profil, profil)
 
 /* Fetch PC samples.  This function must be very careful not to depend
    on Hurd threadvar variables.  We arrange that by using a special
diff --git a/sysdeps/posix/defs.c b/sysdeps/posix/defs.c
index bc0d34bf15..b25b9b0fea 100644
--- a/sysdeps/posix/defs.c
+++ b/sysdeps/posix/defs.c
@@ -63,7 +63,7 @@ FILE *__stdio_head = &stdstreams[0];
    to cause _cleanup to be linked in.  */
 
 void
-_cleanup ()
+_cleanup (void)
 {
   __fcloseall ();
 }
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index fa3cf98c74..865bd3fa6a 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -326,7 +326,7 @@ __getcwd (buf, size)
 	{
 	  size_t namlen = _D_EXACT_NAMLEN (d);
 
-	  if ((size_t) (pathp - path) < namlen)
+	  if ((size_t) (pathp - path) <= namlen)
 	    {
 	      if (buf != NULL)
 		{
diff --git a/sysdeps/posix/pipestream.c b/sysdeps/posix/pipestream.c
index 6041f830e7..31348b8976 100644
--- a/sysdeps/posix/pipestream.c
+++ b/sysdeps/posix/pipestream.c
@@ -41,8 +41,8 @@ struct child
    These all simply call the corresponding
    original function with the original cookie.  */
 
-#define FUNC(type, name, args)						      \
-  static type __CONCAT(child_,name) args __CONCAT(name,decl)		      \
+#define FUNC(type, name, proto, args)					      \
+  static type __CONCAT(child_,name) proto				      \
   {									      \
     struct child *c = (struct child *) cookie;				      \
     {									      \
@@ -51,16 +51,12 @@ struct child
     }									      \
   }
 
-#define readdecl void *cookie; register char *buf; register size_t n;
-FUNC (int, read, (cookie, buf, n))
-#define writedecl void *cookie; register const char *buf; register size_t n;
-FUNC (int, write, (cookie, buf, n))
-#define seekdecl void *cookie; fpos_t *pos; int whence;
-FUNC (int, seek, (cookie, pos, whence))
-#define closedecl void *cookie;
-FUNC (int, close, (cookie))
-#define filenodecl void *cookie;
-FUNC (int, fileno, (cookie))
+FUNC (int, read, (void *cookie, char *buf, size_t n), (cookie, buf, n))
+FUNC (int, write, (void *cookie, const char *buf, size_t n), (cookie, buf, n))
+FUNC (int, seek, (void *cookie, fpos_t *pos, int whence),
+      (cookie, pos, whence))
+FUNC (int, close, (void *cookie), (cookie))
+FUNC (int, fileno, (void *cookie), (cookie))
 
 static const __io_functions child_funcs
   = { child_read, child_write, child_seek, child_close, child_fileno };
diff --git a/sysdeps/posix/profil.c b/sysdeps/posix/profil.c
index a51baf3713..734111efbb 100644
--- a/sysdeps/posix/profil.c
+++ b/sysdeps/posix/profil.c
@@ -60,7 +60,7 @@ profil_count (void *pc)
    disable profiling.  Returns zero on success, -1 on error.  */
 
 int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 {
   static struct sigaction act, oact;
   static struct itimerval timer, otimer;
@@ -103,5 +103,6 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
   timer.it_interval = timer.it_value;
   return setitimer (ITIMER_PROF, &timer, &otimer);
 }
+weak_alias (__profil, profil)
 
 #endif
diff --git a/sysdeps/posix/sleep.c b/sysdeps/posix/sleep.c
index e6d8de45ad..5933be6835 100644
--- a/sysdeps/posix/sleep.c
+++ b/sysdeps/posix/sleep.c
@@ -25,8 +25,7 @@
 /* SIGALRM signal handler for `sleep'.  This does nothing but return,
    but SIG_IGN isn't supposed to break `pause'.  */
 static void
-sleep_handler (sig)
-     int sig;
+sleep_handler (int sig)
 {
   return;
 }
diff --git a/sysdeps/posix/stdio_init.c b/sysdeps/posix/stdio_init.c
index 6847d1fdc9..4dc7028133 100644
--- a/sysdeps/posix/stdio_init.c
+++ b/sysdeps/posix/stdio_init.c
@@ -26,8 +26,7 @@
    If no buffer is allocated, but the bufsize is set,
    the bufsize will be used to allocate the buffer.  */
 void
-__stdio_init_stream (stream)
-     FILE *stream;
+__stdio_init_stream (FILE *stream)
 {
   const int fd = (int) stream->__cookie;
   struct stat statb;
diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
index 0a50956640..3e8f22b573 100644
--- a/sysdeps/powerpc/Makefile
+++ b/sysdeps/powerpc/Makefile
@@ -11,3 +11,21 @@ tests += test-arith test-arithf
 LDLIBS-test-arith = libm
 LDLIBS-test-arithf = libm
 endif
+
+ifeq ($(subdir),gmon)
+sysdep_routines += ppc-mcount
+endif
+
+# On PPC, -fpic works until the GOT contains 2^15 bytes, and possibly
+# more depending on how clever the linker is.  Each GOT entry takes 4 bytes,
+# 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
+endif
+
+# The initfini generation code doesn't work in the presence of -fPIC, so
+# we use -fpic instead which is much better.
+ifeq ($(subdir),csu)
+CFLAGS-initfini.s = -g0 -fpic
+endif
diff --git a/sysdeps/powerpc/add_n.S b/sysdeps/powerpc/add_n.S
new file mode 100644
index 0000000000..2bd59ae4a7
--- /dev/null
+++ b/sysdeps/powerpc/add_n.S
@@ -0,0 +1,68 @@
+/* Add two limb vectors of equal, non-zero length 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>
+
+/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+                        mp_size_t size)
+   Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.  */
+
+/* Note on optimisation: This code is optimal for the 601.  Almost every other
+   possible 2-unrolled inner loop will not be.  Also, watch out for the
+   alignment...  */
+
+EALIGN(__mpn_add_n,3,0)
+/* Set up for loop below.  */
+	mtcrf 0x01,%r6
+	srwi. %r7,%r6,1
+	li    %r10,0
+	mtctr %r7
+	bt    31,2f
+
+/* Clear the carry.  */
+	addic %r0,%r0,0
+/* Adjust pointers for loop.  */
+	addi  %r3,%r3,-4
+	addi  %r4,%r4,-4
+	addi  %r5,%r5,-4
+	b     0f
+
+2:	lwz  %r7,0(%r5)
+	lwz  %r6,0(%r4)
+	addc %r6,%r6,%r7
+	stw  %r6,0(%r3)
+        beq  1f
+
+/* The loop.  */
+
+/* Align start of loop to an odd word boundary to guarantee that the
+   last two words can be fetched in one access (for 601).  */
+0:	lwz  %r9,4(%r4)
+	lwz  %r8,4(%r5)
+	lwzu %r6,8(%r4)
+	lwzu %r7,8(%r5)
+	adde %r8,%r9,%r8
+	stw  %r8,4(%r3)
+	adde %r6,%r6,%r7
+	stwu %r6,8(%r3)
+	bdnz 0b
+/* Return the carry.  */
+1:	addze %r3,%r10
+	blr
+END(__mpn_add_n)
diff --git a/sysdeps/powerpc/add_n.s b/sysdeps/powerpc/add_n.s
deleted file mode 100644
index 609f0a502a..0000000000
--- a/sysdeps/powerpc/add_n.s
+++ /dev/null
@@ -1,68 +0,0 @@
- # Add two limb vectors of equal, non-zero length 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.
-
- # mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
- #                      mp_size_t size)
- # Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.
-
- # Note on optimisation: This code is optimal for the 601.  Almost every other
- # possible 2-unrolled inner loop will not be.  Also, watch out for the
- # alignment...
-
-	.align 3
-	.globl __mpn_add_n
-	.type	 __mpn_add_n,@function
-__mpn_add_n:
- # Set up for loop below.
-	mtcrf 0x01,%r6
-	srwi. %r7,%r6,1
-	li    %r10,0
-	mtctr %r7
-	bt    31,2f
-
- # Clear the carry.
-	addic %r0,%r0,0
- # Adjust pointers for loop.
-	addi  %r3,%r3,-4
-	addi  %r4,%r4,-4
-	addi  %r5,%r5,-4
-	b     0f
-
-2:	lwz  %r7,0(%r5)
-	lwz  %r6,0(%r4)
-	addc %r6,%r6,%r7
-	stw  %r6,0(%r3)
-        beq  1f
-
- # The loop.
-
- # Align start of loop to an odd word boundary to guarantee that the
- # last two words can be fetched in one access (for 601).
-0:	lwz  %r9,4(%r4)
-	lwz  %r8,4(%r5)
-	lwzu %r6,8(%r4)
-	lwzu %r7,8(%r5)
-	adde %r8,%r9,%r8
-	stw  %r8,4(%r3)
-	adde %r6,%r6,%r7
-	stwu %r6,8(%r3)
-	bdnz 0b
- # return the carry
-1:	addze %r3,%r10
-	blr
diff --git a/sysdeps/powerpc/addmul_1.S b/sysdeps/powerpc/addmul_1.S
new file mode 100644
index 0000000000..dc762fcc43
--- /dev/null
+++ b/sysdeps/powerpc/addmul_1.S
@@ -0,0 +1,49 @@
+/* Multiply a limb vector by a single limb, for PowerPC.
+   Copyright (C) 1993, 1994, 1995, 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>
+
+/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+                           mp_size_t s1_size, mp_limb_t s2_limb)
+   Calculate res+s1*s2 and put result back in res; return carry.  */
+ENTRY(__mpn_addmul_1)
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,0(%r3)
+	addc	%r8,%r7,%r9
+	addi	%r3,%r3,-4		/* adjust res_ptr */
+	bdz	1f
+
+0:	lwzu	%r0,4(%r4)
+	stwu	%r8,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,4(%r3)
+	addze   %r10,%r10
+	addc    %r8,%r7,%r9
+	bdnz	0b
+
+1:	stw	%r8,4(%r3)
+	addze	%r3,%r10
+	blr
+END(__mpn_addmul_1)
diff --git a/sysdeps/powerpc/addmul_1.s b/sysdeps/powerpc/addmul_1.s
deleted file mode 100644
index cf8fd2a555..0000000000
--- a/sysdeps/powerpc/addmul_1.s
+++ /dev/null
@@ -1,50 +0,0 @@
- # Multiply a limb vector by a single limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 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.
-
- # mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- #                         mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate res+s1*s2 and put result back in res; return carry.
-
-	.align 2
-	.globl __mpn_addmul_1
-	.type	 __mpn_addmul_1,@function
-__mpn_addmul_1:
-	mtctr	%r5
-
-	lwz	%r0,0(%r4)
-	mullw	%r7,%r0,%r6
-	mulhwu	%r10,%r0,%r6
-	lwz     %r9,0(%r3)
-	addc	%r8,%r7,%r9
-	addi	%r3,%r3,-4		# adjust res_ptr
-	bdz	Lend
-
-Loop:	lwzu	%r0,4(%r4)
-	stwu	%r8,4(%r3)
-	mullw	%r8,%r0,%r6
-	adde	%r7,%r8,%r10
-	mulhwu	%r10,%r0,%r6
-	lwz     %r9,4(%r3)
-	addze   %r10,%r10
-	addc    %r8,%r7,%r9
-	bdnz	Loop
-
-Lend:	stw	%r8,4(%r3)
-	addze	%r3,%r10
-	blr
diff --git a/sysdeps/powerpc/bsd-_setjmp.S b/sysdeps/powerpc/bsd-_setjmp.S
index ffd90d5bd2..ef31f841c4 100644
--- a/sysdeps/powerpc/bsd-_setjmp.S
+++ b/sysdeps/powerpc/bsd-_setjmp.S
@@ -25,9 +25,5 @@
 
 ENTRY (_setjmp)
 	li %r4,0			/* Set second argument to 0.  */
-#ifdef PIC
-	b __sigsetjmp@plt
-#else
-	b __sigsetjmp
-#endif
+	b JUMPTARGET(__sigsetjmp)
 END (_setjmp)
diff --git a/sysdeps/powerpc/bsd-setjmp.S b/sysdeps/powerpc/bsd-setjmp.S
index f02d7815ed..d26b3fc93e 100644
--- a/sysdeps/powerpc/bsd-setjmp.S
+++ b/sysdeps/powerpc/bsd-setjmp.S
@@ -25,11 +25,7 @@
 
 ENTRY (__setjmp)
 	li %r4,1			/* Set second argument to 1.  */
-#ifdef PIC
-	b __sigsetjmp@plt
-#else
-	b __sigsetjmp
-#endif
+	b JUMPTARGET(__sigsetjmp)
 END (__setjmp)
 
 	.globl setjmp
diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h
index 917e4f7970..771b711a14 100644
--- a/sysdeps/powerpc/dl-machine.h
+++ b/sysdeps/powerpc/dl-machine.h
@@ -149,33 +149,34 @@ elf_machine_load_address (void)
 #define elf_machine_relplt elf_machine_rela
 
 /* This code is used in dl-runtime.c to call the `fixup' function
-   and then redirect to the address it returns. It is called
-   from code built in the PLT by elf_machine_runtime_setup. */
+   and then redirect to the address it returns.  It is called
+   from code built in the PLT by elf_machine_runtime_setup.  */
 #define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
 	.section \".text\"
 	.align 2
 	.globl _dl_runtime_resolve
 	.type _dl_runtime_resolve,@function
 _dl_runtime_resolve:
- # We need to save the registers used to pass parameters.
- # We build a stack frame to put them in.
+ # 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)
-	mflr 0
+	stw 0,12(1)
 	stw 3,16(1)
 	stw 4,20(1)
-	stw 0,52(1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+	mr 3,12
 	stw 5,24(1)
- # We also need to save some of the condition register fields.
-	mfcr 0
+	mr 4,11
 	stw 6,28(1)
+	mflr 0
+ # We also need to save some of the condition register fields.
 	stw 7,32(1)
+	stw 0,52(1)
 	stw 8,36(1)
+	mfcr 0
 	stw 9,40(1)
 	stw 10,44(1)
-	stw 0,12(1)
- # The code that calls this has put parameters for `fixup' in r12 and r11.
-	mr 3,12
-	mr 4,11
+	stw 0,8(1)
 	bl fixup@local
  # 'fixup' returns the address we want to branch to.
 	mtctr 3
@@ -184,20 +185,21 @@ _dl_runtime_resolve:
 	lwz 10,44(1)
 	lwz 9,40(1)
 	mtlr 0
-	lwz 0,12(1)
 	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_runtime_resolve,0b-_dl_runtime_resolve
- # undo '.section text'.
+ # Undo '.section text'.
 	.previous
 ");
 
@@ -213,20 +215,20 @@ asm ("\
 	.type _start,@function
 _start:
  # We start with the following on the stack, from top:
- # argc (4 bytes)
- # arguments for program (terminated by NULL)
- # environment variables (terminated by NULL)
- # arguments for the program loader
+ # argc (4 bytes);
+ # arguments for program (terminated by NULL);
+ # environment variables (terminated by NULL);
+ # arguments for the program loader.
  # FIXME: perhaps this should do the same trick as elf/start.c?
 
  # Call _dl_start with one parameter pointing at argc
-	mr 3,1
+	mr   3,1
  #  (we have to frob the stack pointer a bit to allow room for
  #   _dl_start to save the link register)
-	li 4,0
+	li   4,0
 	addi 1,1,-16
-	stw 4,0(1)
-	bl _dl_start@local
+	stw  4,0(1)
+	bl   _dl_start@local
 
  # Now, we do our main work of calling initialisation procedures.
  # The ELF ABI doesn't say anything about parameters for these,
@@ -234,70 +236,72 @@ _start:
  # Changing these is strongly discouraged (not least because argc is
  # passed by value!).
 
- #  put our GOT pointer in r31
-	bl _GLOBAL_OFFSET_TABLE_-4@local
+ #  Put our GOT pointer in r31,
+	bl   _GLOBAL_OFFSET_TABLE_-4@local
 	mflr 31
- #  the address of _start in r30
-	mr 30,3
- #  &_dl_argc in 29, &_dl_argv in 27, and _dl_default_scope in 28
-	lwz 28,_dl_default_scope@got(31)
-	lwz 29,_dl_argc@got(31)
-	lwz 27,_dl_argv@got(31)
+ #  the address of _start in r30,
+	mr   30,3
+ #  &_dl_argc in 29, &_dl_argv in 27, and _dl_default_scope in 28.
+	lwz  28,_dl_default_scope@got(31)
+	lwz  29,_dl_argc@got(31)
+	lwz  27,_dl_argv@got(31)
 0:
- #  call initfunc = _dl_init_next(_dl_default_scope[2])
-	lwz 3,8(28)
-	bl _dl_init_next@plt
- # if initfunc is NULL, we exit the loop
-	mr. 0,3
-	beq 1f
+ #  Set initfunc = _dl_init_next(_dl_default_scope[2])
+	lwz  3,8(28)
+	bl   _dl_init_next@plt
+ # If initfunc is NULL, we exit the loop; otherwise,
+	cmpwi 3,0
+	beq  1f
  # call initfunc(_dl_argc, _dl_argv, _dl_argv+_dl_argc+1)
-	mtlr 0
-	lwz 3,0(29)
-	lwz 4,0(27)
+	mtlr 3
+	lwz  3,0(29)
+	lwz  4,0(27)
 	slwi 5,3,2
-	add 5,4,5
+	add  5,4,5
 	addi 5,5,4
 	blrl
  # and loop.
-	b 0b
+	b    0b
 1:
  # Now, to conform to the ELF ABI, we have to:
- # pass argv (actually _dl_argv) in r4
-	lwz 4,0(27)
- # pass argc (actually _dl_argc) in r3
-	lwz 3,0(29)
- # pass envp (actually _dl_argv+_dl_argc+1) in r5
+ # Pass argc (actually _dl_argc) in r3;
+	lwz  3,0(29)
+ # pass argv (actually _dl_argv) in r4;
+	lwz  4,0(27)
+ # pass envp (actually _dl_argv+_dl_argc+1) in r5;
 	slwi 5,3,2
-	add 5,4,5
-	addi 5,5,4
- # pass the auxilary vector in r6. This is passed just after _envp.
-	addi 6,5,-4
+	add  6,4,5
+	addi 5,6,4
+ # pass the auxilary vector in r6. This is passed to us just after _envp.
 2:	lwzu 0,4(6)
-	cmpwi 1,0,0
-	bne 2b
+	cmpwi 0,0,0
+	bne  2b
 	addi 6,6,4
- # pass a termination function pointer (in this case _dl_fini) in r7
-	lwz 7,_dl_fini@got(31)
- # now, call the start function in r30...
+ # Pass a termination function pointer (in this case _dl_fini) in r7.
+	lwz  7,_dl_fini@got(31)
+ # Now, call the start function in r30...
 	mtctr 30
- # pass the stack pointer in r1 (so far so good), pointing to a NULL value
- # (this lets our startup code distinguish between a program linked statically,
+	lwz  26,_dl_starting_up@got(31)
+ # Pass the stack pointer in r1 (so far so good), pointing to a NULL value.
+ # (This lets our startup code distinguish between a program linked statically,
  # which linux will call with argc on top of the stack which will hopefully
  # never be zero, and a dynamically linked program which will always have
  # a NULL on the top of the stack).
  # Take the opportunity to clear LR, so anyone who accidentally returns
- # from _start gets SEGV.
-	li 0,0
-	stw 0,0(1)
-	mtlr 0
- # and also clear _dl_starting_up
-	lwz 26,_dl_starting_up@got(31)
-	stw 0,0(26)
- # go do it!
+ # from _start gets SEGV.  Also clear the next few words of the stack.
+	li   31,0
+	stw  31,0(1)
+	mtlr 31
+	stw  31,4(1)
+ 	stw  31,8(1)
+	stw  31,12(1)
+ # Clear _dl_starting_up.
+	stw  31,0(26)
+ # Go do it!
 	bctr
 0:
 	.size	 _start,0b-_start
- # undo '.section text'.
+ # Undo '.section text'.
 	.previous
 ");
 
@@ -346,7 +350,7 @@ static ElfW(Addr) _dl_preferred_address = 1
 
 /* We require the address of the PLT entry returned from fixup, not
    the first word of the PLT entry. */
-#define ELF_FIXUP_RETURN_VALUE(map, result)  (&(result))
+#define ELF_FIXUP_RETURN_VALUE(map, result)  ((Elf32_Addr) &(result))
 
 /* Nonzero iff TYPE should not be allowed to resolve to one of
    the main executable's symbols, as for a COPY reloc.  */
@@ -396,7 +400,7 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
 {
   if (map->l_info[DT_JMPREL])
     {
-      int i;
+      Elf32_Word i;
       /* Fill in the PLT. Its initial contents are directed to a
 	 function earlier in the PLT which arranges for the dynamic
 	 linker to be called back.  */
@@ -516,10 +520,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 {
 #ifndef RTLD_BOOTSTRAP
   const Elf32_Sym *const refsym = sym;
+  extern char **_dl_argv;
 #endif
   Elf32_Word loadbase, finaladdr;
   const int rinfo = ELF32_R_TYPE (reloc->r_info);
-  extern char **_dl_argv;
 
   if (rinfo == R_PPC_NONE)
     return;
@@ -551,9 +555,9 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		     + reloc->r_addend);
     }
 
-  /* This is an if/else if chain because GCC 2.7.2.[012] turns case
-     statements into non-PIC table lookups.  When a later version
-     comes out that fixes this, this should be changed.  */
+  /* This is still an if/else if chain because GCC uses the GOT to find
+     the table for table-based switch statements, and we haven't set it
+     up yet.  */
   if (rinfo == R_PPC_UADDR32 ||
       rinfo == R_PPC_GLOB_DAT ||
       rinfo == R_PPC_ADDR32 ||
@@ -561,6 +565,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     {
       *reloc_addr = finaladdr;
     }
+#ifndef RTLD_BOOTSTRAP
   else if (rinfo == R_PPC_ADDR16_LO)
     {
       *(Elf32_Half*) reloc_addr = finaladdr;
@@ -573,7 +578,6 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     {
       *(Elf32_Half*) reloc_addr = (finaladdr + 0x8000) >> 16;
     }
-#ifndef RTLD_BOOTSTRAP
   else if (rinfo == R_PPC_REL24)
     {
       Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
@@ -693,12 +697,14 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 #endif
     }
 
+#ifndef RTLD_BOOTSTRAP
   if (rinfo == R_PPC_ADDR16_LO ||
       rinfo == R_PPC_ADDR16_HI ||
       rinfo == R_PPC_ADDR16_HA ||
       rinfo == R_PPC_REL24 ||
       rinfo == R_PPC_ADDR24)
     MODIFIED_CODE_NOQUEUE (reloc_addr);
+#endif
 }
 
 #define ELF_MACHINE_NO_REL 1
diff --git a/sysdeps/powerpc/lshift.S b/sysdeps/powerpc/lshift.S
new file mode 100644
index 0000000000..b1487a1c17
--- /dev/null
+++ b/sysdeps/powerpc/lshift.S
@@ -0,0 +1,123 @@
+/* Shift a limb left, low level routine.
+   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+  			 unsigned int cnt)  */
+
+EALIGN(__mpn_lshift,3,0)
+	mtctr	%r5		# copy size into CTR
+	cmplwi	%cr0,%r5,16	# is size < 16
+	slwi	%r0,%r5,2
+	add	%r7,%r3,%r0	# make r7 point at end of res
+	add	%r4,%r4,%r0	# make r4 point at end of s1
+	lwzu	%r11,-4(%r4)	# load first s1 limb
+	subfic	%r8,%r6,32
+	srw	%r3,%r11,%r8	# compute function return value
+	bge	%cr0,L(big)	# branch if size >= 16
+
+	bdz	L(end1)
+
+0:	lwzu	%r10,-4(%r4)
+	slw	%r9,%r11,%r6
+	srw	%r12,%r10,%r8
+	or	%r9,%r9,%r12
+	stwu	%r9,-4(%r7)
+	bdz	L(end2)
+	lwzu	%r11,-4(%r4)
+	slw	%r9,%r10,%r6
+	srw	%r12,%r11,%r8
+	or	%r9,%r9,%r12
+	stwu	%r9,-4(%r7)
+	bdnz	0b
+
+L(end1):slw	%r0,%r11,%r6
+	stw	%r0,-4(%r7)
+	blr
+
+
+/* Guaranteed not to succeed.  */
+L(boom): tweq    %r0,%r0
+
+/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
+   of size 4*12 bytes.  We have to do this (or something) to make this PIC.  */
+L(big):	mflr    %r9
+	bltl-   %cr0,L(boom)	# Never taken, only used to set LR.
+	slwi    %r10,%r6,4
+	mflr    %r12
+	add     %r10,%r12,%r10
+	slwi	%r8,%r6,5
+	add     %r10,%r8,%r10
+	mtctr   %r10
+	addi	%r5,%r5,-1
+	mtlr    %r9
+	bctr
+
+L(end2):slw	%r0,%r10,%r6
+	stw	%r0,-4(%r7)
+	blr
+
+#define DO_LSHIFT(n) \
+	mtctr	%r5;							\
+0:	lwzu	%r10,-4(%r4);						\
+	slwi	%r9,%r11,n;						\
+	inslwi	%r9,%r10,n,32-n;					\
+	stwu	%r9,-4(%r7);						\
+	bdz-	L(end2);						\
+	lwzu	%r11,-4(%r4);						\
+	slwi	%r9,%r10,n;						\
+	inslwi	%r9,%r11,n,32-n;					\
+	stwu	%r9,-4(%r7);						\
+	bdnz	0b;							\
+	b	L(end1)
+
+	DO_LSHIFT(1)
+	DO_LSHIFT(2)
+	DO_LSHIFT(3)
+	DO_LSHIFT(4)
+	DO_LSHIFT(5)
+	DO_LSHIFT(6)
+	DO_LSHIFT(7)
+	DO_LSHIFT(8)
+	DO_LSHIFT(9)
+	DO_LSHIFT(10)
+	DO_LSHIFT(11)
+	DO_LSHIFT(12)
+	DO_LSHIFT(13)
+	DO_LSHIFT(14)
+	DO_LSHIFT(15)
+	DO_LSHIFT(16)
+	DO_LSHIFT(17)
+	DO_LSHIFT(18)
+	DO_LSHIFT(19)
+	DO_LSHIFT(20)
+	DO_LSHIFT(21)
+	DO_LSHIFT(22)
+	DO_LSHIFT(23)
+	DO_LSHIFT(24)
+	DO_LSHIFT(25)
+	DO_LSHIFT(26)
+	DO_LSHIFT(27)
+	DO_LSHIFT(28)
+	DO_LSHIFT(29)
+	DO_LSHIFT(30)
+	DO_LSHIFT(31)
+
+END(__mpn_lshift)
diff --git a/sysdeps/powerpc/lshift.s b/sysdeps/powerpc/lshift.s
deleted file mode 100644
index 9612a3dbec..0000000000
--- a/sysdeps/powerpc/lshift.s
+++ /dev/null
@@ -1,479 +0,0 @@
- # Shift a limb left, low level routine.
- # Copyright (C) 1996, 1997 Free Software Foundation, Inc.
- # This file is part of the GNU C Library.
- #
- # The GNU C Library is free software; you can redistribute it and/or
- # modify it under the terms of the GNU Library General Public License as
- # published by the Free Software Foundation; either version 2 of the
- # License, or (at your option) any later version.
- #
- # The GNU C Library is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
- #			 unsigned int cnt)
-
-	.align 3
-	.globl __mpn_lshift
-	.type	 __mpn_lshift,@function
-__mpn_lshift:
-	mtctr	%r5		# copy size into CTR
-	cmplwi	%cr0,%r5,16	# is size < 16
-	slwi	%r0,%r5,2
-	add	%r7,%r3,%r0	# make r7 point at end of res
-	add	%r4,%r4,%r0	# make r4 point at end of s1
-	lwzu	%r11,-4(%r4)	# load first s1 limb
-	subfic	%r8,%r6,32
-	srw	%r3,%r11,%r8	# compute function return value
-	bge	%cr0,Lbig	# branch if size >= 16
-
-	bdz	Lend1
-
-Loop:	lwzu	%r10,-4(%r4)
-	slw	%r9,%r11,%r6
-	srw	%r12,%r10,%r8
-	or	%r9,%r9,%r12
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slw	%r9,%r10,%r6
-	srw	%r12,%r11,%r8
-	or	%r9,%r9,%r12
-	stwu	%r9,-4(%r7)
-	bdnz	Loop
-	b	Lend1
-
- # Guaranteed not to succeed.
-LBoom:	tweq    %r0,%r0
-
- # We imitate a case statement, by using (yuk!) fixed-length code chunks,
- # of size 4*12 bytes.  We have to do this (or something) to make this PIC.
-Lbig:	mflr    %r9
-	bltl    %cr0,LBoom      # Never taken, only used to set LR.
-	slwi    %r10,%r6,4
-	mflr    %r12
-	add     %r10,%r12,%r10
-	slwi	%r8,%r6,5
-	add     %r10,%r8,%r10
-	mtctr   %r10
-	addi	%r5,%r5,-1
-	mtlr    %r9
-	bctr
-
-Lend1:	slw	%r0,%r11,%r6
-	stw	%r0,-4(%r7)
-	blr
-
-	mtctr	%r5
-Loop1:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,1
-	inslwi	%r9,%r10,1,31
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,1
-	inslwi	%r9,%r11,1,31
-	stwu	%r9,-4(%r7)
-	bdnz	Loop1
-	b	Lend1
-
-	mtctr	%r5
-Loop2:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,2
-	inslwi	%r9,%r10,2,30
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,2
-	inslwi	%r9,%r11,2,30
-	stwu	%r9,-4(%r7)
-	bdnz	Loop2
-	b	Lend1
-
-	mtctr	%r5
-Loop3:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,3
-	inslwi	%r9,%r10,3,29
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,3
-	inslwi	%r9,%r11,3,29
-	stwu	%r9,-4(%r7)
-	bdnz	Loop3
-	b	Lend1
-
-	mtctr	%r5
-Loop4:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,4
-	inslwi	%r9,%r10,4,28
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,4
-	inslwi	%r9,%r11,4,28
-	stwu	%r9,-4(%r7)
-	bdnz	Loop4
-	b	Lend1
-
-	mtctr	%r5
-Loop5:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,5
-	inslwi	%r9,%r10,5,27
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,5
-	inslwi	%r9,%r11,5,27
-	stwu	%r9,-4(%r7)
-	bdnz	Loop5
-	b	Lend1
-
-	mtctr	%r5
-Loop6:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,6
-	inslwi	%r9,%r10,6,26
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,6
-	inslwi	%r9,%r11,6,26
-	stwu	%r9,-4(%r7)
-	bdnz	Loop6
-	b	Lend1
-
-	mtctr	%r5
-Loop7:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,7
-	inslwi	%r9,%r10,7,25
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,7
-	inslwi	%r9,%r11,7,25
-	stwu	%r9,-4(%r7)
-	bdnz	Loop7
-	b	Lend1
-
-	mtctr	%r5
-Loop8:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,8
-	inslwi	%r9,%r10,8,24
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,8
-	inslwi	%r9,%r11,8,24
-	stwu	%r9,-4(%r7)
-	bdnz	Loop8
-	b	Lend1
-
-	mtctr	%r5
-Loop9:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,9
-	inslwi	%r9,%r10,9,23
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,9
-	inslwi	%r9,%r11,9,23
-	stwu	%r9,-4(%r7)
-	bdnz	Loop9
-	b	Lend1
-
-	mtctr	%r5
-Loop10:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,10
-	inslwi	%r9,%r10,10,22
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,10
-	inslwi	%r9,%r11,10,22
-	stwu	%r9,-4(%r7)
-	bdnz	Loop10
-	b	Lend1
-
-	mtctr	%r5
-Loop11:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,11
-	inslwi	%r9,%r10,11,21
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,11
-	inslwi	%r9,%r11,11,21
-	stwu	%r9,-4(%r7)
-	bdnz	Loop11
-	b	Lend1
-
-	mtctr	%r5
-Loop12:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,12
-	inslwi	%r9,%r10,12,20
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,12
-	inslwi	%r9,%r11,12,20
-	stwu	%r9,-4(%r7)
-	bdnz	Loop12
-	b	Lend1
-
-	mtctr	%r5
-Loop13:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,13
-	inslwi	%r9,%r10,13,19
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,13
-	inslwi	%r9,%r11,13,19
-	stwu	%r9,-4(%r7)
-	bdnz	Loop13
-	b	Lend1
-
-	mtctr	%r5
-Loop14:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,14
-	inslwi	%r9,%r10,14,18
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,14
-	inslwi	%r9,%r11,14,18
-	stwu	%r9,-4(%r7)
-	bdnz	Loop14
-	b	Lend1
-
-	mtctr	%r5
-Loop15:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,15
-	inslwi	%r9,%r10,15,17
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,15
-	inslwi	%r9,%r11,15,17
-	stwu	%r9,-4(%r7)
-	bdnz	Loop15
-	b	Lend1
-
-	mtctr	%r5
-Loop16:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,16
-	inslwi	%r9,%r10,16,16
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,16
-	inslwi	%r9,%r11,16,16
-	stwu	%r9,-4(%r7)
-	bdnz	Loop16
-	b	Lend1
-
-	mtctr	%r5
-Loop17:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,17
-	inslwi	%r9,%r10,17,15
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,17
-	inslwi	%r9,%r11,17,15
-	stwu	%r9,-4(%r7)
-	bdnz	Loop17
-	b	Lend1
-
-	mtctr	%r5
-Loop18:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,18
-	inslwi	%r9,%r10,18,14
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,18
-	inslwi	%r9,%r11,18,14
-	stwu	%r9,-4(%r7)
-	bdnz	Loop18
-	b	Lend1
-
-	mtctr	%r5
-Loop19:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,19
-	inslwi	%r9,%r10,19,13
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,19
-	inslwi	%r9,%r11,19,13
-	stwu	%r9,-4(%r7)
-	bdnz	Loop19
-	b	Lend1
-
-	mtctr	%r5
-Loop20:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,20
-	inslwi	%r9,%r10,20,12
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,20
-	inslwi	%r9,%r11,20,12
-	stwu	%r9,-4(%r7)
-	bdnz	Loop20
-	b	Lend1
-
-	mtctr	%r5
-Loop21:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,21
-	inslwi	%r9,%r10,21,11
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,21
-	inslwi	%r9,%r11,21,11
-	stwu	%r9,-4(%r7)
-	bdnz	Loop21
-	b	Lend1
-
-	mtctr	%r5
-Loop22:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,22
-	inslwi	%r9,%r10,22,10
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,22
-	inslwi	%r9,%r11,22,10
-	stwu	%r9,-4(%r7)
-	bdnz	Loop22
-	b	Lend1
-
-	mtctr	%r5
-Loop23:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,23
-	inslwi	%r9,%r10,23,9
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,23
-	inslwi	%r9,%r11,23,9
-	stwu	%r9,-4(%r7)
-	bdnz	Loop23
-	b	Lend1
-
-	mtctr	%r5
-Loop24:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,24
-	inslwi	%r9,%r10,24,8
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,24
-	inslwi	%r9,%r11,24,8
-	stwu	%r9,-4(%r7)
-	bdnz	Loop24
-	b	Lend1
-
-	mtctr	%r5
-Loop25:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,25
-	inslwi	%r9,%r10,25,7
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,25
-	inslwi	%r9,%r11,25,7
-	stwu	%r9,-4(%r7)
-	bdnz	Loop25
-	b	Lend1
-
-	mtctr	%r5
-Loop26:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,26
-	inslwi	%r9,%r10,26,6
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,26
-	inslwi	%r9,%r11,26,6
-	stwu	%r9,-4(%r7)
-	bdnz	Loop26
-	b	Lend1
-
-	mtctr	%r5
-Loop27:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,27
-	inslwi	%r9,%r10,27,5
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,27
-	inslwi	%r9,%r11,27,5
-	stwu	%r9,-4(%r7)
-	bdnz	Loop27
-	b	Lend1
-
-	mtctr	%r5
-Loop28:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,28
-	inslwi	%r9,%r10,28,4
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,28
-	inslwi	%r9,%r11,28,4
-	stwu	%r9,-4(%r7)
-	bdnz	Loop28
-	b	Lend1
-
-	mtctr	%r5
-Loop29:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,29
-	inslwi	%r9,%r10,29,3
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,29
-	inslwi	%r9,%r11,29,3
-	stwu	%r9,-4(%r7)
-	bdnz	Loop29
-	b	Lend1
-
-	mtctr	%r5
-Loop30:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,30
-	inslwi	%r9,%r10,30,2
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,30
-	inslwi	%r9,%r11,30,2
-	stwu	%r9,-4(%r7)
-	bdnz	Loop30
-	b	Lend1
-
-	mtctr	%r5
-Loop31:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,31
-	inslwi	%r9,%r10,31,1
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,31
-	inslwi	%r9,%r11,31,1
-	stwu	%r9,-4(%r7)
-	bdnz	Loop31
-	b	Lend1
-
-Lend2:	slw	%r0,%r10,%r6
-	stw	%r0,-4(%r7)
-	blr
diff --git a/sysdeps/unix/sysv/linux/powerpc/_exit.S b/sysdeps/powerpc/machine-gmon.h
index a1ca375d54..ba53807308 100644
--- a/sysdeps/unix/sysv/linux/powerpc/_exit.S
+++ b/sysdeps/powerpc/machine-gmon.h
@@ -1,5 +1,7 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* 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
@@ -16,11 +18,15 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <sysdep.h>
+/* We need a special version of the `mcount' function because it has
+   to preserve more registers than your usual function.  */
 
-/* The 'exit' syscall does not return.  */
+void __mcount_internal (unsigned long frompc, unsigned long selfpc);
 
-	.text
-ENTRY(_exit)
-	DO_CALL (SYS_ify (exit))
-PSEUDO_END (_exit)
+#define _MCOUNT_DECL(frompc, selfpc) \
+void __mcount_internal (unsigned long frompc, unsigned long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+   file.  */
+#define MCOUNT
diff --git a/sysdeps/powerpc/memset.S b/sysdeps/powerpc/memset.S
new file mode 100644
index 0000000000..6ac32ddc99
--- /dev/null
+++ b/sysdeps/powerpc/memset.S
@@ -0,0 +1,199 @@
+/* Optimized memset 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>
+
+EALIGN(memset,5,1)
+/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
+   Returns 's'.
+
+   The memset is done in three sizes: byte (8 bits), word (32 bits),
+   cache line (256 bits). There is a special case for setting cache lines
+   to 0, to take advantage of the dcbz instruction.
+   r6:	current address we are storing at
+   r7:	number of bytes we are setting now (when aligning)  */
+
+/* take care of case for size <= 4  */
+	cmplwi %cr1,%r5,4
+	andi.  %r7,%r3,3
+	mr     %r6,%r3
+	ble-   %cr1,L(small)
+/* align to word boundary  */
+	cmplwi %cr5,%r5,31
+	rlwimi %r4,%r4,8,16,23
+	beq+   L(aligned)		# 8th instruction from .align
+	mtcrf  0x01,%r3
+	subfic %r7,%r7,4
+	add    %r6,%r6,%r7
+	sub    %r5,%r5,%r7
+	bf+    31,0f
+	stb    %r4,0(%r3)
+	bt     30,L(aligned)
+0:	sth    %r4,-2(%r6)		#  16th instruction from .align
+/* take care of case for size < 31 */
+L(aligned):
+	mtcrf  0x01,%r5
+	rlwimi %r4,%r4,16,0,15
+	ble    %cr5,L(medium)
+/* align to cache line boundary...  */
+	andi.  %r7,%r6,0x1C
+	subfic %r7,%r7,0x20
+	beq    L(caligned)
+	mtcrf  0x01,%r7
+	add    %r6,%r6,%r7
+	sub    %r5,%r5,%r7
+	cmplwi %cr1,%r7,0x10
+	mr     %r8,%r6
+	bf     28,1f
+	stw    %r4,-4(%r8)
+	stwu   %r4,-8(%r8)
+1:	blt    %cr1,2f
+	stw    %r4,-4(%r8)	# 32nd instruction from .align
+	stw    %r4,-8(%r8)
+	stw    %r4,-12(%r8)
+	stwu   %r4,-16(%r8)
+2:	bf     29,L(caligned)
+	stw    %r4,-4(%r8)
+/* now aligned to a cache line.  */
+L(caligned):
+	cmplwi %cr1,%r4,0
+	clrrwi. %r7,%r5,5
+	mtcrf  0x01,%r5		# 40th instruction from .align
+	beq    %cr1,L(zloopstart) # special case for clearing memory using dcbz
+	srwi   %r0,%r7,5
+	mtctr  %r0
+	beq    L(medium)	# we may not actually get to do a full line
+	clrlwi. %r5,%r5,27
+	add    %r6,%r6,%r7
+0:	li     %r8,-0x40
+	bdz    L(cloopdone)	# 48th instruction from .align
+
+3:	dcbz   %r8,%r6
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stw    %r4,-16(%r6)
+	nop			# let 601 fetch last 4 instructions of loop
+	stw    %r4,-20(%r6)
+	stw    %r4,-24(%r6)	# 56th instruction from .align
+	nop			# let 601 fetch first 8 instructions of loop
+	stw    %r4,-28(%r6)
+	stwu   %r4,-32(%r6)
+	bdnz   3b
+L(cloopdone):
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stw    %r4,-16(%r6)	# 64th instruction from .align
+	stw    %r4,-20(%r6)
+	cmplwi %cr1,%r5,16
+	stw    %r4,-24(%r6)
+	stw    %r4,-28(%r6)
+	stwu   %r4,-32(%r6)
+	beqlr
+	add    %r6,%r6,%r7
+	b      L(medium_tail2)	# 72nd instruction from .align
+
+	.align 5
+	nop
+/* Clear lines of memory in 128-byte chunks.  */
+L(zloopstart):
+	clrlwi %r5,%r5,27
+	mtcrf  0x02,%r7
+	srwi.  %r0,%r7,7
+	mtctr  %r0
+	li     %r7,0x20
+	li     %r8,-0x40
+	cmplwi %cr1,%r5,16	# 8
+	bf     26,0f
+	dcbz   0,%r6
+	addi   %r6,%r6,0x20
+0:	li     %r9,-0x20
+	bf     25,1f
+	dcbz   0,%r6
+	dcbz   %r7,%r6
+	addi   %r6,%r6,0x40	# 16
+1:	cmplwi %cr5,%r5,0
+	beq    L(medium)
+L(zloop):
+	dcbz   0,%r6
+	dcbz   %r7,%r6
+	addi   %r6,%r6,0x80
+	dcbz   %r8,%r6
+	dcbz   %r9,%r6
+	bdnz   L(zloop)
+	beqlr  %cr5
+	b      L(medium_tail2)
+
+	.align 5
+L(small):
+/* Memset of 4 bytes or less.  */
+	cmplwi %cr5,%r5,1
+	cmplwi %cr1,%r5,3
+	bltlr  %cr5
+	stb    %r4,0(%r6)
+	beqlr  %cr5
+	nop
+	stb    %r4,1(%r6)
+	bltlr  %cr1
+	stb    %r4,2(%r6)
+	beqlr  %cr1
+	nop
+	stb    %r4,3(%r6)
+	blr
+
+/* Memset of 0-31 bytes.  */
+	.align 5
+L(medium):
+	cmplwi %cr1,%r5,16
+L(medium_tail2):
+	add    %r6,%r6,%r5
+L(medium_tail):
+	bt-    31,L(medium_31t)
+	bt-    30,L(medium_30t)
+L(medium_30f):
+	bt-    29,L(medium_29t)
+L(medium_29f):
+	bge-   %cr1,L(medium_27t)
+	bflr-  28
+	stw    %r4,-4(%r6)		# 8th instruction from .align
+	stw    %r4,-8(%r6)
+	blr
+
+L(medium_31t):
+	stbu   %r4,-1(%r6)
+	bf-    30,L(medium_30f)
+L(medium_30t):
+	sthu   %r4,-2(%r6)
+	bf-    29,L(medium_29f)
+L(medium_29t):
+	stwu   %r4,-4(%r6)
+	blt-   %cr1,L(medium_27f)	# 16th instruction from .align
+L(medium_27t):
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stwu   %r4,-16(%r6)
+L(medium_27f):
+	bflr-  28
+L(medium_28t):
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	blr
+END(memset)
diff --git a/sysdeps/powerpc/memset.s b/sysdeps/powerpc/memset.s
deleted file mode 100644
index 4c8bf8c6b4..0000000000
--- a/sysdeps/powerpc/memset.s
+++ /dev/null
@@ -1,202 +0,0 @@
- # Optimized memset 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.
-
-	.section ".text"
-	.align 5
-	nop
-	
-	.globl memset
-	.type memset,@function
-memset:	
- # __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
- # Returns 's'.
-
- # The memset is done in three sizes: byte (8 bits), word (32 bits),
- # cache line (256 bits). There is a special case for setting cache lines
- # to 0, to take advantage of the dcbz instruction.
- # r6:	current address we are storing at
- # r7:	number of bytes we are setting now (when aligning)
-
- # take care of case for size <= 4
-	cmplwi %cr1,%r5,4	
-	andi.  %r7,%r3,3
-	mr     %r6,%r3
-	ble-   %cr1,small
- # align to word boundary
-	cmplwi %cr5,%r5,31
-	rlwimi %r4,%r4,8,16,23
-	beq+   aligned			# 8th instruction from .align
-	mtcrf  0x01,%r3
-	subfic %r7,%r7,4
-	add    %r6,%r6,%r7
-	sub    %r5,%r5,%r7
-	bf+    31,0f
-	stb    %r4,0(%r3)
-	bt     30,aligned
-0:	sth    %r4,-2(%r6)		#  16th instruction from .align
- # take care of case for size < 31
-aligned:
-	mtcrf  0x01,%r5
-	rlwimi %r4,%r4,16,0,15
-	ble    %cr5,medium
- # align to cache line boundary...
-	andi.  %r7,%r6,0x1C
-	subfic %r7,%r7,0x20
-	beq    caligned
-	mtcrf  0x01,%r7
-	add    %r6,%r6,%r7
-	sub    %r5,%r5,%r7
-	cmplwi %cr1,%r7,0x10
-	mr     %r8,%r6
-	bf     28,1f
-	stw    %r4,-4(%r8)
-	stwu   %r4,-8(%r8)
-1:	blt    %cr1,2f
-	stw    %r4,-4(%r8)	# 32nd instruction from .align
-	stw    %r4,-8(%r8)
-	stw    %r4,-12(%r8)
-	stwu   %r4,-16(%r8)
-2:	bf     29,caligned
-	stw    %r4,-4(%r8)
- # now aligned to a cache line.
-caligned:
-	cmplwi %cr1,%r4,0
-	clrrwi. %r7,%r5,5
-	mtcrf  0x01,%r5		# 40th instruction from .align
-	beq    %cr1,zloopstart	# special case for clearing memory using dcbz
-	srwi   %r0,%r7,5
-	mtctr  %r0
-	beq    medium		# we may not actually get to do a full line
-	clrlwi. %r5,%r5,27
-	add    %r6,%r6,%r7
-0:	li     %r8,-0x40
-	bdz    cloopdone	# 48th instruction from .align
-	
-cloop:	dcbz   %r8,%r6
-	stw    %r4,-4(%r6)
-	stw    %r4,-8(%r6)
-	stw    %r4,-12(%r6)
-	stw    %r4,-16(%r6)
-	nop			# let 601 fetch last 4 instructions of loop
-	stw    %r4,-20(%r6)
-	stw    %r4,-24(%r6)	# 56th instruction from .align
-	nop			# let 601 fetch first 8 instructions of loop
-	stw    %r4,-28(%r6)
-	stwu   %r4,-32(%r6)
-	bdnz   cloop
-cloopdone:
-	stw    %r4,-4(%r6)
-	stw    %r4,-8(%r6)
-	stw    %r4,-12(%r6)
-	stw    %r4,-16(%r6)	# 64th instruction from .align
-	stw    %r4,-20(%r6)
-	cmplwi %cr1,%r5,16
-	stw    %r4,-24(%r6)
-	stw    %r4,-28(%r6)
-	stwu   %r4,-32(%r6)
-	beqlr
-	add    %r6,%r6,%r7
-	b      medium_tail2	# 72nd instruction from .align
-
-	.align 5
-	nop
-# clear lines of memory in 128-byte chunks.
-zloopstart:
-	clrlwi %r5,%r5,27
-	mtcrf  0x02,%r7
-	srwi.  %r0,%r7,7
-	mtctr  %r0
-	li     %r7,0x20
-	li     %r8,-0x40
-	cmplwi %cr1,%r5,16	# 8
-	bf     26,0f	
-	dcbz   0,%r6
-	addi   %r6,%r6,0x20
-0:	li     %r9,-0x20
-	bf     25,1f
-	dcbz   0,%r6
-	dcbz   %r7,%r6
-	addi   %r6,%r6,0x40	# 16
-1:	cmplwi %cr5,%r5,0
-	beq    medium
-zloop:	
-	dcbz   0,%r6
-	dcbz   %r7,%r6
-	addi   %r6,%r6,0x80
-	dcbz   %r8,%r6
-	dcbz   %r9,%r6
-	bdnz   zloop
-	beqlr  %cr5
-	b      medium_tail2
-	
-	.align 5	
-small:
- # Memset of 4 bytes or less.
-	cmplwi %cr5,%r5,1
-	cmplwi %cr1,%r5,3
-	bltlr  %cr5
-	stb    %r4,0(%r6)
-	beqlr  %cr5
-	nop
-	stb    %r4,1(%r6)
-	bltlr  %cr1
-	stb    %r4,2(%r6)
-	beqlr  %cr1
-	nop
-	stb    %r4,3(%r6)
-	blr
-
-# memset of 0-31 bytes
-	.align 5
-medium:
-	cmplwi %cr1,%r5,16
-medium_tail2:
-	add    %r6,%r6,%r5
-medium_tail:
-	bt-    31,medium_31t
-	bt-    30,medium_30t
-medium_30f:
-	bt-    29,medium_29t
-medium_29f:
-	bge-   %cr1,medium_27t
-	bflr-  28
-	stw    %r4,-4(%r6)	# 8th instruction from .align
-	stw    %r4,-8(%r6)
-	blr
-
-medium_31t:	
-	stbu   %r4,-1(%r6)
-	bf-    30,medium_30f
-medium_30t:
-	sthu   %r4,-2(%r6)
-	bf-    29,medium_29f
-medium_29t:
-	stwu   %r4,-4(%r6)
-	blt-   %cr1,medium_27f	# 16th instruction from .align
-medium_27t:
-	stw    %r4,-4(%r6)
-	stw    %r4,-8(%r6)
-	stw    %r4,-12(%r6)
-	stwu   %r4,-16(%r6)
-medium_27f:
-	bflr-  28
-medium_28t:
-	stw    %r4,-4(%r6)
-	stw    %r4,-8(%r6)
-	blr
diff --git a/sysdeps/powerpc/mul_1.S b/sysdeps/powerpc/mul_1.S
new file mode 100644
index 0000000000..d48bd8fa19
--- /dev/null
+++ b/sysdeps/powerpc/mul_1.S
@@ -0,0 +1,46 @@
+/* Multiply a limb vector by a limb, for PowerPC.
+   Copyright (C) 1993, 1994, 1995, 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>
+
+/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+                        mp_size_t s1_size, mp_limb_t s2_limb)
+   Calculate s1*s2 and put result in res_ptr; return carry.  */
+
+ENTRY(__mpn_mul_1)
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	addi	%r3,%r3,-4		# adjust res_ptr
+	addic	%r5,%r5,0		# clear cy with dummy insn
+	bdz	1f
+
+0:	lwzu	%r0,4(%r4)
+	stwu	%r7,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	bdnz	0b
+
+1:	stw	%r7,4(%r3)
+	addze	%r3,%r10
+	blr
+END(__mpn_mul_1)
diff --git a/sysdeps/powerpc/mul_1.s b/sysdeps/powerpc/mul_1.s
deleted file mode 100644
index d6eb623bd4..0000000000
--- a/sysdeps/powerpc/mul_1.s
+++ /dev/null
@@ -1,47 +0,0 @@
- # Multiply a limb vector by a limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 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.
-
- # mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- #                      mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate s1*s2 and put result in res_ptr; return carry.
-
-	.align 2
-	.globl __mpn_mul_1
-	.type	 __mpn_mul_1,@function
-
-__mpn_mul_1:
-	mtctr	%r5
-
-	lwz	%r0,0(%r4)
-	mullw	%r7,%r0,%r6
-	mulhwu	%r10,%r0,%r6
-	addi	%r3,%r3,-4		# adjust res_ptr
-	addic	%r5,%r5,0		# clear cy with dummy insn
-	bdz	Lend
-
-Loop:	lwzu	%r0,4(%r4)
-	stwu	%r7,4(%r3)
-	mullw	%r8,%r0,%r6
-	adde	%r7,%r8,%r10
-	mulhwu	%r10,%r0,%r6
-	bdnz	Loop
-
-Lend:	stw	%r7,4(%r3)
-	addze	%r3,%r10
-	blr
diff --git a/sysdeps/powerpc/ppc-mcount.S b/sysdeps/powerpc/ppc-mcount.S
new file mode 100644
index 0000000000..06f1fcda12
--- /dev/null
+++ b/sysdeps/powerpc/ppc-mcount.S
@@ -0,0 +1,84 @@
+/* PowerPC-specific implementation of profiling support.
+   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.	*/
+
+/* This would be bad.  */
+#ifdef PROF
+#undef PROF
+#endif
+
+#include <sysdep.h>
+
+/* We do profiling as described in the SYSV ELF ABI, _mcount is called
+   with the address of a data word in r0 (that is different for every
+   routine, initialised to 0, and otherwise unused).  The caller has put
+   the address the caller will return to in the usual place on the stack,
+   4(%r1).  _mcount is responsible for ensuring that when it returns no
+   argument-passing registers are disturbed, and that the LR is set back
+   to (what the caller sees as) 4(%r1).
+
+   This is intended so that the following code can be inserted at the
+   front of any routine without changing the routine:
+
+	.data
+	.align	2
+   0:	.long	0
+	.previous
+	mflr	%r0
+	lis	%r11,0b@ha
+	stw	%r0,4(%r1)
+	addi	%r0,%r11,0b@l
+	bl	_mcount
+*/
+
+ENTRY(_mcount)
+	stwu	%r1,-48(%r1)
+/* We need to save the parameter-passing registers.  */
+	stw	%r3, 12(%r1)
+	stw	%r4, 16(%r1)
+	stw	%r5, 20(%r1)
+	stw	%r6, 24(%r1)
+	mflr	%r4
+	lwz	%r3, 52(%r1)
+	mfcr	%r5
+	stw	%r7, 28(%r1)
+	stw	%r8, 32(%r1)
+	stw	%r9, 36(%r1)
+	stw	%r10,40(%r1)
+	stw	%r4, 44(%r1)
+	stw	%r5,  8(%r1)
+	bl	JUMPTARGET(__mcount_internal)
+ /* Restore the registers...  */
+	lwz     %r6,  8(%r1)
+	lwz	%r0, 44(%r1)
+	lwz	%r3, 12(%r1)
+	mtctr	%r0
+	lwz	%r4, 16(%r1)
+	mtcrf	0xff,%r6
+	lwz	%r5, 20(%r1)
+	lwz	%r6, 24(%r1)
+	lwz	%r0, 52(%r1)
+	lwz	%r7, 28(%r1)
+	lwz	%r8, 32(%r1)
+	mtlr	%r0
+	lwz	%r9, 36(%r1)
+	lwz	%r10,40(%r1)
+ /* ...unwind the stack frame, and return to your usual programming.  */
+	addi	%r1,%r1,48
+	bctr
+END(_mcount)
diff --git a/sysdeps/powerpc/rshift.S b/sysdeps/powerpc/rshift.S
new file mode 100644
index 0000000000..eb1f562bed
--- /dev/null
+++ b/sysdeps/powerpc/rshift.S
@@ -0,0 +1,56 @@
+/* Shift a limb right, low level routine.
+   Copyright (C) 1995, 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>
+
+/* INPUT PARAMETERS
+   res_ptr	r3
+   s1_ptr	r4
+   size		r5
+   cnt		r6  */
+
+ENTRY(__mpn_rshift)
+	mtctr	5		# copy size into CTR
+	addi	7,3,-4		# move adjusted res_ptr to free return reg
+	subfic	8,6,32
+	lwz	11,0(4)		# load first s1 limb
+	slw	3,11,8		# compute function return value
+	bdz	1f
+
+0:	lwzu	10,4(4)
+	srw	9,11,6
+	slw	12,10,8
+	or	9,9,12
+	stwu	9,4(7)
+	bdz	2f
+	lwzu	11,4(4)
+	srw	9,10,6
+	slw	12,11,8
+	or	9,9,12
+	stwu	9,4(7)
+	bdnz	0b
+
+1:	srw	0,11,6
+	stw	0,4(7)
+	blr
+
+2:	srw	0,10,6
+	stw	0,4(7)
+	blr
+END(__mpn_rshift)
diff --git a/sysdeps/powerpc/rshift.s b/sysdeps/powerpc/rshift.s
deleted file mode 100644
index 20f09ad86a..0000000000
--- a/sysdeps/powerpc/rshift.s
+++ /dev/null
@@ -1,59 +0,0 @@
-# PowerPC-32 __mpn_rshift --
-
-# Copyright (C) 1995 Free Software Foundation, Inc.
-
-# This file is part of the GNU MP Library.
-
-# The GNU MP 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 MP 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 MP 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.
-
-
-# INPUT PARAMETERS
-# res_ptr	r3
-# s1_ptr	r4
-# size		r5
-# cnt		r6
-
-	.align 3
-	.globl __mpn_rshift
-	.type	 __mpn_rshift,@function
-__mpn_rshift:
-	mtctr	5		# copy size into CTR
-	addi	7,3,-4		# move adjusted res_ptr to free return reg
-	subfic	8,6,32
-	lwz	11,0(4)		# load first s1 limb
-	slw	3,11,8		# compute function return value
-	bdz	Lend1
-
-Loop:	lwzu	10,4(4)
-	srw	9,11,6
-	slw	12,10,8
-	or	9,9,12
-	stwu	9,4(7)
-	bdz	Lend2
-	lwzu	11,4(4)
-	srw	9,10,6
-	slw	12,11,8
-	or	9,9,12
-	stwu	9,4(7)
-	bdnz	Loop
-
-Lend1:	srw	0,11,6
-	stw	0,4(7)
-	blr
-
-Lend2:	srw	0,10,6
-	stw	0,4(7)
-	blr
diff --git a/sysdeps/powerpc/s_copysign.S b/sysdeps/powerpc/s_copysign.S
index adc7df226a..6d5ba82592 100644
--- a/sysdeps/powerpc/s_copysign.S
+++ b/sysdeps/powerpc/s_copysign.S
@@ -1,17 +1,17 @@
 /* Copy a sign bit between floating-point values.
    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,
@@ -20,15 +20,12 @@
 /* This has been coded in assembler because GCC makes such a mess of it
    when it's coded in C.  */
 
-	.section ".text"
-	.align 2
-	.globl __copysign
-	.type __copysign,@function
-__copysign:	
+#include <sysdep.h>
+
+ENTRY(__copysign)
 /* double [f1] copysign (double [f1] x, double [f2] y);
    copysign(x,y) returns a value with the magnitude of x and
    with the sign bit of y.  */
-
 	stwu	%r1,-16(%r1)
 	stfd	%f2,8(%r1)
 	lwz	%r3,8(%r1)
@@ -39,22 +36,15 @@ __copysign:
 	blr
 0:	fnabs   %f1,%f1
 	blr
-0:
-	.size	 __copysign,0b-__copysign
-	
-	.globl copysign
-	.globl copysignf
-	.globl __copysignf
-	.weak copysign
-	.weak copysignf
-	.set copysign,__copysign
+	END (__copysign)
+
+weak_alias(__copysign,copysign)
+
 /* It turns out that it's safe to use this code even for single-precision.  */
-	.set __copysignf,__copysign
-	.set copysignf,__copysign
+weak_alias(__copysign,copysignf)
+strong_alias(__copysign,__copysignf)
+
 #ifdef NO_LONG_DOUBLE
-	.globl copysignl
-	.globl __copysignl
-	.weak copysignl
-	.set __copysignl,__copysign
-	.set copysignl,__copysign
+weak_alias(__copysign,copysignl)
+strong_alias(__copysign,__copysignl)
 #endif
diff --git a/sysdeps/powerpc/s_fabs.S b/sysdeps/powerpc/s_fabs.S
index a52733568d..3c6374b0aa 100644
--- a/sysdeps/powerpc/s_fabs.S
+++ b/sysdeps/powerpc/s_fabs.S
@@ -1,42 +1,37 @@
 /* Floating-point absolute value.  PowerPC version.
    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.  */
 
-	.section ".text"
-	.align 2
-	.globl __fabs
-	.type __fabs,@function
-__fabs:	
+#include <sysdep.h>
+
+ENTRY(__fabs)
 /* double [f1] fabs (double [f1] x); */
 	fabs %f1,%f1
 	blr
-0:
-	.size	 __fabs,0b-__fabs
+END(__fabs)
+
+weak_alias(__fabs,fabs)
 
-	.globl fabs,fabsf,__fabsf
-	.weak fabs,fabsf
-	.set fabs,__fabs
 /* It turns out that it's safe to use this code even for single-precision.  */
-	.set __fabsf,__fabs
-	.set fabsf,__fabs
+strong_alias(__fabs,__fabsf)
+weak_alias(__fabs,fabsf)
+
 #ifdef NO_LONG_DOUBLE
-	.globl fabsl,__fabsl
-	.weak fabsl
-	.set __fabsl,__fabs
-	.set fabsl,__fabs
+weak_alias(__fabs,__fabsl)
+weak_alias(__fabs,fabsl)
 #endif
diff --git a/sysdeps/powerpc/setjmp.S b/sysdeps/powerpc/setjmp.S
index ddfea7eed3..8fa863f161 100644
--- a/sysdeps/powerpc/setjmp.S
+++ b/sysdeps/powerpc/setjmp.S
@@ -62,9 +62,5 @@ ENTRY (__sigsetjmp)
 	stfd %f30,((JB_FPRS+16*2)*4)(3)
 	stw  %r31,((JB_GPRS+17)*4)(3)
 	stfd %f31,((JB_FPRS+17*2)*4)(3)
-#ifdef PIC
-	b __sigjmp_save@plt
-#else
-	b __sigjmp_save
-#endif
+	b JUMPTARGET(__sigjmp_save)
 END (__sigsetjmp)
diff --git a/sysdeps/powerpc/strchr.S b/sysdeps/powerpc/strchr.S
new file mode 100644
index 0000000000..156d4d155c
--- /dev/null
+++ b/sysdeps/powerpc/strchr.S
@@ -0,0 +1,111 @@
+/* Optimized strchr 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 this works.  */
+
+/* char * [r3] strchr (const char *s [r3] , int c [r4] )
+
+   r0:	a temporary
+   r3:	our return result.
+   r4:	byte we're looking for, spread over the whole word
+   r5:	the current word
+   r6:	the constant 0xfefefeff (-0x01010101)
+   r7:	the constant 0x7f7f7f7f
+   r8:	pointer to the current word.
+   r9:	a temporary
+   r10:	the number of bits we should ignore in the first word
+   r11:	a mask with the bits to ignore set to 0
+   r12:	a temporary  */
+ENTRY(strchr)
+	rlwimi %r4,%r4,8,16,23
+	li   %r11,-1
+	rlwimi %r4,%r4,16,0,15
+	lis  %r6,0xfeff
+	lis  %r7,0x7f7f
+	clrrwi %r8,%r3,2
+	addi %r7,%r7,0x7f7f
+	addi %r6,%r6,0xfffffeff
+	rlwinm %r10,%r3,3,27,28
+/* Test the first (partial?) word.  */
+	lwz  %r5,0(%r8)
+	srw  %r11,%r11,%r10
+	orc  %r5,%r5,%r11
+	add  %r0,%r6,%r5
+	nor  %r9,%r7,%r5
+	and. %r0,%r0,%r9
+	xor  %r12,%r4,%r5
+	orc  %r12,%r12,%r11
+	b    L(loopentry)
+
+/* The loop.  */
+
+L(loop):lwzu %r5,4(%r8)
+	and. %r0,%r0,%r9
+/* Test for 0.  */
+	add  %r0,%r6,%r5
+	nor  %r9,%r7,%r5
+	bne  L(foundit)
+	and. %r0,%r0,%r9
+/* Start test for the bytes we're looking for.  */
+	xor  %r12,%r4,%r5
+L(loopentry):
+	add  %r0,%r6,%r12
+	nor  %r9,%r7,%r12
+	beq  L(loop)
+/* There is a zero byte in the word, but may also be a matching byte (either
+   before or after the zero byte).  In fact, we may be looking for a
+   zero byte, in which case we return a match.  We guess that this hasn't
+   happened, though.  */
+L(missed):
+	and. %r0,%r0,%r9
+	li   %r3,0
+	beqlr
+/* It did happen. Decide which one was first...
+   I'm not sure if this is actually faster than a sequence of
+   rotates, compares, and branches (we use it anyway because it's shorter).  */
+	and  %r6,%r7,%r5
+	or   %r11,%r7,%r5
+	and  %r0,%r7,%r12
+	or   %r10,%r7,%r12
+	add  %r6,%r6,%r7
+	add  %r0,%r0,%r7
+	nor  %r5,%r11,%r6
+	nor  %r9,%r10,%r0
+	cmplw %r5,%r9
+	bgtlr
+	cntlzw %r4,%r9
+	srwi %r4,%r4,3
+	add  %r3,%r8,%r4
+	blr
+
+L(foundit):
+	and  %r0,%r7,%r12
+	or   %r10,%r7,%r12
+	add  %r0,%r0,%r7
+	nor  %r9,%r10,%r0
+	cntlzw %r4,%r9
+	subi %r8,%r8,4
+	srwi %r4,%r4,3
+	add  %r3,%r8,%r4
+	blr
+END(strchr)
+
+weak_alias(strchr,index)
diff --git a/sysdeps/powerpc/strchr.s b/sysdeps/powerpc/strchr.s
deleted file mode 100644
index c1df66f8dc..0000000000
--- a/sysdeps/powerpc/strchr.s
+++ /dev/null
@@ -1,118 +0,0 @@
- # Optimized strchr 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.
-
- # See strlen.s for comments on how this works.
-
-	.section ".text"
-	.align 2
-	.globl strchr
-	.type strchr,@function
-strchr:
- # char * [r3] strchr (const char *s [r3] , int c [r4] )
-
- # r0:	a temporary
- # r3:	our return result.
- # r4:	byte we're looking for, spread over the whole word
- # r5:	the current word
- # r6:	the constant 0xfefefeff (-0x01010101)
- # r7:	the constant 0x7f7f7f7f
- # r8:	pointer to the current word.
- # r9:	a temporary
- # r10:	the number of bits we should ignore in the first word
- # r11:	a mask with the bits to ignore set to 0
- # r12:	a temporary
-	
-	rlwimi %r4,%r4,8,16,23
-	li   %r11,-1
-	rlwimi %r4,%r4,16,0,15
-	lis  %r6,0xfeff
-	lis  %r7,0x7f7f
-	clrrwi %r8,%r3,2
-	addi %r7,%r7,0x7f7f
-	addi %r6,%r6,0xfffffeff
-	rlwinm %r10,%r3,3,27,28
- # Test the first (partial?) word.
-	lwz  %r5,0(%r8)
-	srw  %r11,%r11,%r10
-	orc  %r5,%r5,%r11
-	add  %r0,%r6,%r5
-	nor  %r9,%r7,%r5
-	and. %r0,%r0,%r9
-	xor  %r12,%r4,%r5
-	orc  %r12,%r12,%r11
-	b    loopentry
-	
- # The loop.
-
-loop:	lwzu %r5,4(%r8)
-	and. %r0,%r0,%r9
- # Test for 0
-	add  %r0,%r6,%r5
-	nor  %r9,%r7,%r5
-	bne  foundit
-	and. %r0,%r0,%r9
- # Start test for the bytes we're looking for
-	xor  %r12,%r4,%r5
-loopentry:
-	add  %r0,%r6,%r12
-	nor  %r9,%r7,%r12
-	beq  loop
- # There is a zero byte in the word, but may also be a matching byte (either
- # before or after the zero byte). In fact, we may be looking for a
- # zero byte, in which case we return a match. We guess that this hasn't
- # happened, though.
-missed:	
-	and. %r0,%r0,%r9
-	li   %r3,0
-	beqlr
- # It did happen. Decide which one was first...
- # I'm not sure if this is actually faster than a sequence of
- # rotates, compares, and branches (we use it anyway because it's shorter).
-	and  %r6,%r7,%r5
-	or   %r11,%r7,%r5
-	and  %r0,%r7,%r12
-	or   %r10,%r7,%r12
-	add  %r6,%r6,%r7
-	add  %r0,%r0,%r7
-	nor  %r5,%r11,%r6
-	nor  %r9,%r10,%r0
-	cmplw %r5,%r9
-	bgtlr
-	cntlzw %r4,%r9
-	srwi %r4,%r4,3
-	add  %r3,%r8,%r4
-	blr
-
-foundit:
-	and  %r0,%r7,%r12
-	or   %r10,%r7,%r12
-	add  %r0,%r0,%r7
-	nor  %r9,%r10,%r0
-	cntlzw %r4,%r9
-	subi %r8,%r8,4
-	srwi %r4,%r4,3
-	add  %r3,%r8,%r4
-	blr
-
-0:
-	.size	 strchr,0b-strchr
-
-	.globl index
-	.weak index
-	.set index,strchr
diff --git a/sysdeps/powerpc/strcmp.S b/sysdeps/powerpc/strcmp.S
new file mode 100644
index 0000000000..9f4d134419
--- /dev/null
+++ b/sysdeps/powerpc/strcmp.S
@@ -0,0 +1,115 @@
+/* Optimized strcmp 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(strcmp,4,0)
+/* int [r3] strcmp (const char *p1 [r3], const char *p2 [r4])  */
+
+/* General register assignments:
+   r0:	temporary
+   r3:	pointer to previous word in s1
+   r4:	pointer to previous word in s2
+   r5:	current word from s1
+   r6:	current word from s2
+   r7:	0xfefefeff
+   r8:	0x7f7f7f7f
+   r9:	~(word in s1 | 0x7f7f7f7f)  */
+
+/* Register assignments in the prologue:
+   r10:	low 2 bits of p2-p1
+   r11:	mask to orc with r5/r6  */
+
+	or    %r0,%r4,%r3
+	clrlwi. %r0,%r0,30
+	lis   %r7,0xfeff
+	bne   L(unaligned)
+
+	lwz   %r5,0(%r3)
+	lwz   %r6,0(%r4)
+	lis   %r8,0x7f7f
+	addi  %r7,%r7,-0x101
+	addi  %r8,%r8,0x7f7f
+	b     1f
+
+0:	lwzu  %r5,4(%r3)
+	bne   %cr1,L(different)
+	lwzu  %r6,4(%r4)
+1:	add   %r0,%r7,%r5
+	nor   %r9,%r8,%r5
+	and.  %r0,%r0,%r9
+	cmpw  %cr1,%r5,%r6
+	beq+  0b
+L(endstring):
+/* OK. We've hit the end of the string. We need to be careful that
+   we don't compare two strings as different because of gunk beyond
+   the end of the strings...  */
+	and   %r0,%r8,%r5
+	beq   %cr1,L(equal)
+	add   %r0,%r0,%r8
+	xor.  %r10,%r5,%r6
+	andc  %r9,%r9,%r0
+	blt-  L(highbit)
+	cntlzw %r10,%r10
+	cntlzw %r9,%r9
+	addi  %r9,%r9,7
+	cmpw  %cr1,%r9,%r10
+	sub   %r3,%r5,%r6
+	bgelr+ %cr1
+L(equal):
+	li    %r3,0
+	blr
+
+L(different):
+	lwz   %r5,-4(%r3)
+	xor.  %r10,%r5,%r6
+	sub   %r3,%r5,%r6
+	bgelr+
+L(highbit):
+	mr    %r3,%r6
+	blr
+
+
+/* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+	.align 4
+L(unaligned):
+	lbz   %r5,0(%r3)
+	lbz   %r6,0(%r4)
+	b     1f
+
+0:	lbzu  %r5,1(%r3)
+	bne-  4f
+	lbzu  %r6,1(%r4)
+1:	cmpwi %cr1,%r5,0
+	beq-  %cr1,3f
+	cmpw  %r5,%r6
+	bne-  3f
+	lbzu  %r5,1(%r3)
+	lbzu  %r6,1(%r4)
+	cmpwi %cr1,%r5,0
+	cmpw  %r5,%r6
+	bne+  %cr1,0b
+3:	sub   %r3,%r5,%r6
+	blr
+4:	lbz   %r5,-1(%r3)
+	sub   %r3,%r5,%r6
+	blr
+END(strcmp)
diff --git a/sysdeps/powerpc/strcmp.s b/sysdeps/powerpc/strcmp.s
deleted file mode 100644
index f901b82ab1..0000000000
--- a/sysdeps/powerpc/strcmp.s
+++ /dev/null
@@ -1,273 +0,0 @@
- # Optimized strcmp 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.
-
- # See strlen.s for comments on how the end-of-string testing works.
-
-	.section ".text"
-	.align 3
-	.globl strcmp
-	.type strcmp,@function
-strcmp:
- # int [r3] strcmp (const char *p1 [r3], const char *p2 [r4])
-
- # General register assignments:
- # r0:	temporary
- # r3:	pointer to previous word in s1
- # r4:	pointer to previous word in s2
- # r5:	current first word in s1
- # r6:	current first word in s2 (after re-alignment)
- # r7:	0xfefefeff
- # r8:	0x7f7f7f7f
- # r9:	~(word in s1 | 0x7f7f7f7f)
-	
- # Register assignments in the prologue:
- # r10:	low 2 bits of p2-p1
- # r11:	mask to orc with r5/r6
-	
-	subf. %r10,%r4,%r3
-	beq-  equal
-	andi. %r10,%r10,3
-	cmpi  %cr1,%r10,2
-	beq-  %cr1,align2
-	lis   %r7,0xfeff
-	lis   %r8,0x7f7f
-	addi  %r8,%r8,0x7f7f
-	addi  %r7,%r7,0xfffffeff
-	bgt-  %cr1,align3
-strcmp3:
-	rlwinm %r0,%r3,3,27,28
-	li    %r11,-1
-	srw   %r11,%r11,%r0
-	clrrwi %r3,%r3,2
-	clrrwi %r4,%r4,2
-	lwz   %r5,0(%r3)
-	lwz   %r6,0(%r4)
-	bne-  align1
-
- # The loop, case when both strings are aligned the same.
- # on entry, cr1.eq must be 1.
- # r10:	second word in s1
- # r11:	second word in s2 OR mask to orc with first two words.
-align0:	
-	andi. %r0,%r3,4
-	orc   %r5,%r5,%r11
-	orc   %r6,%r6,%r11
-	beq+  a0start
-	add   %r0,%r7,%r5
-	nor   %r9,%r8,%r5
-	and.  %r0,%r0,%r9
-	cmplw %cr1,%r5,%r6
-	subi  %r3,%r3,4
-	bne-  endstringeq
-	subi  %r4,%r4,4
-	bne-  %cr1,difference
-
-loopalign0:
-	lwzu  %r5,8(%r3)
-	bne-  %cr1,difference2
-	lwzu  %r6,8(%r4)
-a0start:
-	add   %r0,%r7,%r5
-	nor   %r9,%r8,%r5
-	and.  %r0,%r0,%r9
-	cmplw %cr1,%r5,%r6
-	lwz   %r10,4(%r3)
-	bne-  endstringeq
-	add   %r0,%r7,%r10
-	bne-  %cr1,difference
-	nor   %r9,%r8,%r10
-	lwz   %r11,4(%r4)
-	and.  %r0,%r0,%r9
-	cmplw %cr1,%r10,%r11
-	beq+  loopalign0
-
-	mr    %r5,%r10
-	mr    %r6,%r11
-
- # fall through to...
-
-endstringeq:
- # (like 'endstring', but an equality code is in cr1)
-	beq  %cr1,equal
-endstring:
- # OK. We've hit the end of the string. We need to be careful that
- # we don't compare two strings as different because of gunk beyond
- # the end of the strings. We do it like this...
-	and  %r0,%r8,%r5
-	add  %r0,%r0,%r8
-	xor. %r10,%r5,%r6
-	andc %r9,%r9,%r0
-	cntlzw %r10,%r10
-	cntlzw %r9,%r9
-	addi %r9,%r9,7
-	cmpw %cr1,%r9,%r10
-	blt  %cr1,equal
-	sub  %r3,%r5,%r6
-	bgelr+
-	mr   %r3,%r6
-	blr
-equal:	li   %r3,0
-	blr
-	
- # The loop, case when s2 is aligned 1 char behind s1.
- # r10:	current word in s2 (before re-alignment)
-
-align1:
-	cmpwi %cr1,%r0,0
-	orc   %r5,%r5,%r11
-	bne   %cr1,align1_123
- # When s1 is aligned to a word boundary, the startup processing is special.
-	slwi. %r6,%r6,24
-	bne+  a1entry_0
-	nor   %r9,%r8,%r5
-	b     endstring
-
-align1_123:
- # Otherwise (s1 not aligned to a word boundary):
-	mr    %r10,%r6
-	add   %r0,%r7,%r5
-	nor   %r9,%r8,%r5
-	and.  %r0,%r0,%r9
-	srwi  %r6,%r6,8
-	orc   %r6,%r6,%r11
-	cmplw %cr1,%r5,%r6
-	bne-  endstringeq
-	bne-  %cr1,difference
-
-loopalign1:
-	slwi. %r6,%r10,24
-	bne-  %cr1,a1difference
-	lwzu  %r5,4(%r3)
-	beq-  endstring1
-a1entry_0:
-	lwzu  %r10,4(%r4)
-a1entry_123:	
-	add   %r0,%r7,%r5
-	nor   %r9,%r8,%r5
-	and.  %r0,%r0,%r9
-	rlwimi %r6,%r10,24,8,31
-	cmplw %cr1,%r5,%r6
-	beq+  loopalign1
-	b     endstringeq
-
-endstring1:
-	srwi  %r3,%r5,24
-	blr
-
-a1difference:
-	lbz   %r6,-1(%r4)
-	slwi  %r6,%r6,24
-	rlwimi %r6,%r10,24,8,31
-
- # fall through to...
-		
-difference:	
- # The idea here is that we could just return '%r5 - %r6', except
- # that the result might overflow. Overflow can only happen when %r5
- # and %r6 have different signs (thus the xor), in which case we want to
- # return negative iff %r6 has its high bit set so %r5 < %r6.
- # A branch-free implementation of this is
- #	xor  %r0,%r5,%r6
- #	rlwinm %r0,%r0,1,31,31
- #	rlwnm %r5,%r5,%r0,1,31
- #	rlwnm %r6,%r6,%r0,1,31
- #	sub  %r3,%r5,%r6
- #	blr
- # but this is usually more expensive.
-	xor. %r0,%r5,%r6
-	sub  %r3,%r5,%r6
-	bgelr+
-	mr   %r3,%r6
-	blr
-
-difference2:
- # As for 'difference', but use registers r10 and r11 instead of r5 and r6.
-	xor. %r0,%r10,%r11
-	sub  %r3,%r10,%r11
-	bgelr+
-	mr   %r3,%r11
-	blr
-	
- # For the case when s2 is aligned 3 chars behind s1, we switch
- # s1 and s2...
- # r10:	used by 'align2' (see below)
- # r11:	used by 'align2' (see below)
- # r12:	saved link register
- # cr0.eq: must be left as 1.
-
-align3:	mflr %r12
-	mr   %r0,%r3
-	mr   %r3,%r4
-	mr   %r4,%r0
-	bl   strcmp3
-	mtlr %r12
-	neg  %r3,%r3
-	blr
-	
- # The loop, case when s2 and s1's alignments differ by 2
- # This is the ugly case...
- # FIXME: on a 601, the loop takes 7 cycles instead of the 6 you'd expect,
- # because there are too many branches. This loop should probably be
- # coded like the align1 case.
-	
-a2even:	lhz   %r5,0(%r3)
-	lhz   %r6,0(%r4)
-	b     a2entry
-	
-align2:
-	andi. %r0,%r3,1
-	beq+  a2even
-	subi  %r3,%r3,1
-	subi  %r4,%r4,1
-	lbz   %r5,1(%r3)
-	lbz   %r6,1(%r4)
-	cmpwi %cr0,%r5,0
-	cmpw  %cr1,%r5,%r6
-	beq-  align2end2
-	lhzu  %r5,2(%r3)
-	beq+  %cr1,a2entry1
-	lbz   %r5,-1(%r3)
-	sub   %r3,%r5,%r6
-	blr
-
-loopalign2:
-	cmpw  %cr1,%r5,%r6
-	beq-  align2end2
-	lhzu  %r5,2(%r3)
-	bne-  %cr1,align2different
-a2entry1:
-	lhzu  %r6,2(%r4)
-a2entry:	
-	cmpwi %cr5,%r5,0x00ff
-	andi. %r0,%r5,0x00ff
-	bgt+  %cr5,loopalign2
-
-align2end:
-	andi. %r3,%r6,0xff00
-	neg   %r3,%r3
-	blr
-
-align2different:
-	lhzu  %r5,-2(%r3)
-align2end2:
-	sub   %r3,%r5,%r6
-	blr
-		
-0:
-	.size	 strcmp,0b-strcmp
diff --git a/sysdeps/powerpc/strlen.S b/sysdeps/powerpc/strlen.S
new file mode 100644
index 0000000000..dc6660b8fc
--- /dev/null
+++ b/sysdeps/powerpc/strlen.S
@@ -0,0 +1,144 @@
+/* Optimized strlen 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>
+
+/* The algorithm here uses the following techniques:
+
+   1) Given a word 'x', we can test to see if it contains any 0 bytes
+      by subtracting 0x01010101, and seeing if any of the high bits of each
+      byte changed from 0 to 1. This works because the least significant
+      0 byte must have had no incoming carry (otherwise it's not the least
+      significant), so it is 0x00 - 0x01 == 0xff. For all other
+      byte values, either they have the high bit set initially, or when
+      1 is subtracted you get a value in the range 0x00-0x7f, none of which
+      have their high bit set. The expression here is
+      (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
+      there were no 0x00 bytes in the word.
+
+   2) Given a word 'x', we can test to see _which_ byte was zero by
+      calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
+      This produces 0x80 in each byte that was zero, and 0x00 in all
+      the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
+      byte, and the '| x' part ensures that bytes with the high bit set
+      produce 0x00. The addition will carry into the high bit of each byte
+      iff that byte had one of its low 7 bits set. We can then just see
+      which was the most significant bit set and divide by 8 to find how
+      many to add to the index.
+      This is from the book 'The PowerPC Compiler Writer's Guide',
+      by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
+
+   We deal with strings not aligned to a word boundary by taking the
+   first word and ensuring that bytes not part of the string
+   are treated as nonzero. To allow for memory latency, we unroll the
+   loop a few times, being careful to ensure that we do not read ahead
+   across cache line boundaries.
+
+   Questions to answer:
+   1) How long are strings passed to strlen? If they're often really long,
+   we should probably use cache management instructions and/or unroll the
+   loop more. If they're often quite short, it might be better to use
+   fact (2) in the inner loop than have to recalculate it.
+   2) How popular are bytes with the high bit set? If they are very rare,
+   on some processors it might be useful to use the simpler expression
+   ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
+   ALU), but this fails when any character has its high bit set.  */
+
+/* Some notes on register usage: Under the SVR4 ABI, we can use registers
+   0 and 3 through 12 (so long as we don't call any procedures) without
+   saving them. We can also use registers 14 through 31 if we save them.
+   We can't use r1 (it's the stack pointer), r2 nor r13 because the user
+   program may expect them to hold their usual value if we get sent
+   a signal. Integer parameters are passed in r3 through r10.
+   We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
+   them, the others we must save.  */
+
+ENTRY(strlen)
+/* On entry, r3 points to the string, and it's left that way.
+   We use r6 to store 0xfefefeff, and r7 to store 0x7f7f7f7f.
+   r4 is used to keep the current index into the string; r5 holds
+   the number of padding bits we prepend to the string to make it
+   start at a word boundary. r8 holds the 'current' word.
+   r9-12 are temporaries. r0 is used as a temporary and for discarded
+   results.  */
+	clrrwi %r4,%r3,2
+	lis   %r7,0x7f7f
+	rlwinm %r5,%r3,3,27,28
+	lwz   %r8,0(%r4)
+	li    %r9,-1
+	addi  %r7,%r7,0x7f7f
+/* That's the setup done, now do the first pair of words.
+   We make an exception and use method (2) on the first two words, to reduce
+   overhead.  */
+	srw   %r9,%r9,%r5
+	and   %r0,%r7,%r8
+	or    %r10,%r7,%r8
+	add   %r0,%r0,%r7
+	nor   %r0,%r10,%r0
+	and.  %r8,%r0,%r9
+	mtcrf 0x01,%r3
+	bne   L(done0)
+	lis   %r6,0xfeff
+	addi  %r6,%r6,-0x101
+/* Are we now aligned to a doubleword boundary?  */
+	bt    29,L(loop)
+
+/* Handle second word of pair.  */
+	lwzu  %r8,4(%r4)
+	and   %r0,%r7,%r8
+	or    %r10,%r7,%r8
+	add   %r0,%r0,%r7
+	nor.  %r8,%r10,%r0
+	bne   L(done0)
+
+/* The loop.  */
+
+L(loop):
+	lwz   %r8,4(%r4)
+	lwzu  %r9,8(%r4)
+	add   %r0,%r6,%r8
+	nor   %r10,%r7,%r8
+	and.  %r0,%r0,%r10
+	add   %r11,%r6,%r9
+	nor   %r12,%r7,%r9
+	bne   L(done1)
+	and.  %r0,%r11,%r12
+	beq   L(loop)
+
+	and   %r0,%r7,%r9
+	add   %r0,%r0,%r7
+	andc  %r8,%r12,%r0
+	b     L(done0)
+
+L(done1):
+	and   %r0,%r7,%r8
+	subi  %r4,%r4,4
+	add   %r0,%r0,%r7
+	andc  %r8,%r10,%r0
+
+/* When we get to here, r4 points to the first word in the string that
+   contains a zero byte, and the most significant set bit in r8 is in that
+   byte.  */
+L(done0):
+	cntlzw %r11,%r8
+	subf  %r0,%r3,%r4
+	srwi  %r11,%r11,3
+	add   %r3,%r0,%r11
+	blr
+END(strlen)
diff --git a/sysdeps/powerpc/strlen.s b/sysdeps/powerpc/strlen.s
deleted file mode 100644
index ea809772eb..0000000000
--- a/sysdeps/powerpc/strlen.s
+++ /dev/null
@@ -1,144 +0,0 @@
- # Optimized strlen 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.
-
- # The algorithm here uses the following techniques:
- #
- # 1) Given a word 'x', we can test to see if it contains any 0 bytes
- #    by subtracting 0x01010101, and seeing if any of the high bits of each
- #    byte changed from 0 to 1. This works because the least significant
- #    0 byte must have had no incoming carry (otherwise it's not the least
- #    significant), so it is 0x00 - 0x01 == 0xff. For all other
- #    byte values, either they have the high bit set initially, or when
- #    1 is subtracted you get a value in the range 0x00-0x7f, none of which
- #    have their high bit set. The expression here is
- #    (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
- #    there were no 0x00 bytes in the word.
- #
- # 2) Given a word 'x', we can test to see _which_ byte was zero by
- #    calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
- #    This produces 0x80 in each byte that was zero, and 0x00 in all
- #    the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
- #    byte, and the '| x' part ensures that bytes with the high bit set
- #    produce 0x00. The addition will carry into the high bit of each byte
- #    iff that byte had one of its low 7 bits set. We can then just see
- #    which was the most significant bit set and divide by 8 to find how
- #    many to add to the index.
- #    This is from the book 'The PowerPC Compiler Writer's Guide',
- #    by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
- #
- # We deal with strings not aligned to a word boundary by taking the
- # first word and ensuring that bytes not part of the string
- # are treated as nonzero. To allow for memory latency, we unroll the
- # loop a few times, being careful to ensure that we do not read ahead
- # across cache line boundaries.
- #
- # Questions to answer:
- # 1) How long are strings passed to strlen? If they're often really long,
- # we should probably use cache management instructions and/or unroll the
- # loop more. If they're often quite short, it might be better to use
- # fact (2) in the inner loop than have to recalculate it.
- # 2) How popular are bytes with the high bit set? If they are very rare,
- # on some processors it might be useful to use the simpler expression
- # ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
- # ALU), but this fails when any character has its high bit set.
-
- # Some notes on register usage: Under the SVR4 ABI, we can use registers
- # 0 and 3 through 12 (so long as we don't call any procedures) without
- # saving them. We can also use registers 14 through 31 if we save them.
- # We can't use r1 (it's the stack pointer), r2 nor r13 because the user
- # program may expect them to hold their usual value if we get sent
- # a signal. Integer parameters are passed in r3 through r10.
- # We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
- # them, the others we must save.
-
-	.section ".text"
-	.align 2
-	.globl strlen
-	.type strlen,@function
-strlen:
- # On entry, r3 points to the string, and it's left that way.
- # We use r6 to store 0xfefefeff, and r7 to store 0x7f7f7f7f.
- # r4 is used to keep the current index into the string; r5 holds
- # the number of padding bits we prepend to the string to make it
- # start at a word boundary. r8 holds the 'current' word.
- # r9-12 are temporaries. r0 is used as a temporary and for discarded
- # results.
-	clrrwi %r4,%r3,2
-	lis   %r7,0x7f7f
-	rlwinm %r5,%r3,3,27,28
-	lwz   %r8,0(%r4)
-	li    %r9,-1
-	addi  %r7,%r7,0x7f7f
- # That's the setup done, now do the first pair of words.
- # We make an exception and use method (2) on the first two words, to reduce
- # overhead.
-	srw   %r9,%r9,%r5
-	and   %r0,%r7,%r8
-	or    %r10,%r7,%r8
-	add   %r0,%r0,%r7
-	nor   %r0,%r10,%r0
-	and.  %r8,%r0,%r9
-	mtcrf 0x01,%r3
-	bne   done0
-	lis   %r6,0xfeff
-	addi  %r6,%r6,-0x101
- # Are we now aligned to a doubleword boundary?
-	bt    29,loop
-
- # Handle second word of pair.
-	lwzu  %r8,4(%r4)
-	and   %r0,%r7,%r8
-	or    %r10,%r7,%r8
-	add   %r0,%r0,%r7
-	nor.  %r8,%r10,%r0
-	bne   done0
-
- # The loop.
-
-loop:	lwz   %r8,4(%r4)
-	lwzu  %r9,8(%r4)
-	add   %r0,%r6,%r8
-	nor   %r10,%r7,%r8
-	and.  %r0,%r0,%r10
-	add   %r11,%r6,%r9
-	nor   %r12,%r7,%r9
-	bne   done1
-	and.  %r0,%r11,%r12
-	beq   loop
-
-	and   %r0,%r7,%r9
-	add   %r0,%r0,%r7
-	andc  %r8,%r12,%r0
-	b     done0
-
-done1:	and   %r0,%r7,%r8
-	subi  %r4,%r4,4
-	add   %r0,%r0,%r7
-	andc  %r8,%r10,%r0
-
- # When we get to here, r4 points to the first word in the string that
- # contains a zero byte, and the most significant set bit in r8 is in that
- # byte.
-done0:	cntlzw %r11,%r8
-	subf  %r0,%r3,%r4
-	srwi  %r11,%r11,3
-	add   %r3,%r0,%r11
-	blr
-0:
-	.size	 strlen,0b-strlen
diff --git a/sysdeps/powerpc/sub_n.S b/sysdeps/powerpc/sub_n.S
new file mode 100644
index 0000000000..7af577d835
--- /dev/null
+++ b/sysdeps/powerpc/sub_n.S
@@ -0,0 +1,68 @@
+/* Subtract two limb vectors of equal, non-zero length 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>
+
+/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+                        mp_size_t size)
+   Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1.  */
+
+/* Note on optimisation: This code is optimal for the 601.  Almost every other
+   possible 2-unrolled inner loop will not be.  Also, watch out for the
+   alignment...  */
+
+EALIGN(__mpn_sub_n,3,1)
+/* Set up for loop below.  */
+	mtcrf 0x01,%r6
+	srwi. %r7,%r6,1
+	mtctr %r7
+	bt    31,2f
+
+/* Set the carry (clear the borrow).  */
+	subfc %r0,%r0,%r0
+/* Adjust pointers for loop.  */
+	addi  %r3,%r3,-4
+	addi  %r4,%r4,-4
+	addi  %r5,%r5,-4
+	b     0f
+
+2:	lwz   %r7,0(%r5)
+	lwz   %r6,0(%r4)
+	subfc %r6,%r7,%r6
+	stw   %r6,0(%r3)
+        beq   1f
+
+/* Align start of loop to an odd word boundary to guarantee that the
+   last two words can be fetched in one access (for 601).  This turns
+   out to be important.  */
+0:
+	lwz   %r9,4(%r4)
+	lwz   %r8,4(%r5)
+	lwzu  %r6,8(%r4)
+	lwzu  %r7,8(%r5)
+	subfe %r8,%r8,%r9
+	stw   %r8,4(%r3)
+	subfe %r6,%r7,%r6
+	stwu  %r6,8(%r3)
+	bdnz  0b
+/* Return the borrow. */
+1:	subfe %r3,%r3,%r3
+	neg   %r3,%r3
+	blr
+END(__mpn_sub_n)
diff --git a/sysdeps/powerpc/sub_n.s b/sysdeps/powerpc/sub_n.s
deleted file mode 100644
index 8711bf9a40..0000000000
--- a/sysdeps/powerpc/sub_n.s
+++ /dev/null
@@ -1,69 +0,0 @@
- # Subtract two limb vectors of equal, non-zero length 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.
-
- # mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
- #                      mp_size_t size)
- # Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1.
-
- # Note on optimisation: This code is optimal for the 601.  Almost every other
- # possible 2-unrolled inner loop will not be.  Also, watch out for the
- # alignment...
-
-	.align 3
-	.globl __mpn_sub_n
-	.type	 __mpn_sub_n,@function
-	nop
-__mpn_sub_n:
- # Set up for loop below.
-	mtcrf 0x01,%r6
-	srwi. %r7,%r6,1
-	mtctr %r7
-	bt    31,2f
-
- # Set the carry (clear the borrow).
-	subfc %r0,%r0,%r0
- # Adjust pointers for loop.
-	addi  %r3,%r3,-4
-	addi  %r4,%r4,-4
-	addi  %r5,%r5,-4
-	b     0f
-
-2:	lwz   %r7,0(%r5)
-	lwz   %r6,0(%r4)
-	subfc %r6,%r7,%r6
-	stw   %r6,0(%r3)
-        beq   1f
-
- # Align start of loop to an odd word boundary to guarantee that the
- # last two words can be fetched in one access (for 601).  This turns
- # out to be important.
-0:
-	lwz   %r9,4(%r4)
-	lwz   %r8,4(%r5)
-	lwzu  %r6,8(%r4)
-	lwzu  %r7,8(%r5)
-	subfe %r8,%r8,%r9
-	stw   %r8,4(%r3)
-	subfe %r6,%r7,%r6
-	stwu  %r6,8(%r3)
-	bdnz  0b
- # return the borrow
-1:	subfe %r3,%r3,%r3
-	neg   %r3,%r3
-	blr
diff --git a/sysdeps/powerpc/submul_1.S b/sysdeps/powerpc/submul_1.S
new file mode 100644
index 0000000000..80da8ec8c1
--- /dev/null
+++ b/sysdeps/powerpc/submul_1.S
@@ -0,0 +1,52 @@
+/* Multiply a limb vector by a single limb, for PowerPC.
+   Copyright (C) 1993, 1994, 1995, 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>
+
+/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+                           mp_size_t s1_size, mp_limb_t s2_limb)
+   Calculate res-s1*s2 and put result back in res; return carry.  */
+
+ENTRY(__mpn_submul_1)
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,0(%r3)
+	subf 	%r8,%r7,%r9
+	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
+	addi	%r3,%r3,-4		# adjust res_ptr
+	bdz	1f
+
+0:	lwzu	%r0,4(%r4)
+	stwu	%r8,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,4(%r3)
+	addze   %r10,%r10
+	subf    %r8,%r7,%r9
+	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
+	bdnz	0b
+
+1:	stw	%r8,4(%r3)
+	addze	%r3,%r10
+	blr
+END(__mpn_submul_1)
diff --git a/sysdeps/powerpc/submul_1.s b/sysdeps/powerpc/submul_1.s
deleted file mode 100644
index 999430d744..0000000000
--- a/sysdeps/powerpc/submul_1.s
+++ /dev/null
@@ -1,52 +0,0 @@
- # Multiply a limb vector by a single limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 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.
-
- # mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- #                         mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate res-s1*s2 and put result back in res; return carry.
-
-	.align 2
-	.globl __mpn_submul_1
-	.type	 __mpn_submul_1,@function
-__mpn_submul_1:
-	mtctr	%r5
-
-	lwz	%r0,0(%r4)
-	mullw	%r7,%r0,%r6
-	mulhwu	%r10,%r0,%r6
-	lwz     %r9,0(%r3)
-	subf 	%r8,%r7,%r9
-	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
-	addi	%r3,%r3,-4		# adjust res_ptr
-	bdz	Lend
-
-Loop:	lwzu	%r0,4(%r4)
-	stwu	%r8,4(%r3)
-	mullw	%r8,%r0,%r6
-	adde	%r7,%r8,%r10
-	mulhwu	%r10,%r0,%r6
-	lwz     %r9,4(%r3)
-	addze   %r10,%r10
-	subf    %r8,%r7,%r9
-	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
-	bdnz	Loop
-
-Lend:	stw	%r8,4(%r3)
-	addze	%r3,%r10
-	blr
diff --git a/sysdeps/powerpc/test-arith.c b/sysdeps/powerpc/test-arith.c
index c846b0d0ec..9e1be88098 100644
--- a/sysdeps/powerpc/test-arith.c
+++ b/sysdeps/powerpc/test-arith.c
@@ -226,7 +226,7 @@ check_result(int line, const char *rm, tocheck_t expected, tocheck_t actual)
   if (memcmp(&expected, &actual, sizeof(tocheck_t)) != 0)
     {
       unsigned char *ex, *ac;
-      int i;
+      size_t i;
 
       printf("%s:%d:round %s:result failed\n"
 	     " expected result 0x", __FILE__, line, rm);
@@ -323,7 +323,7 @@ check_excepts(int line, const char *rm, int expected, int actual)
     expected = expected & ~excepts_missing | FE_INVALID_SNAN;
   if ((expected & all_exceptions) != actual)
     {
-      int i;
+      size_t i;
       printf("%s:%d:round %s:exceptions failed\n"
 	     " expected exceptions ", __FILE__, line,rm);
       for (i = 0; i < sizeof(excepts)/sizeof(excepts[0]); i++)
@@ -419,7 +419,7 @@ static const optest_t optests[] = {
   {__LINE__,B_NEG, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
   {__LINE__,B_NEG, 0,P_Z,P_Z1,  0,0,0, R_ALL, 0, 1,P_Z,P_Z1 },
   {__LINE__,B_NEG, 1,P_Z,P_Z1,  0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-  
+
   /* Absolute value.  */
   {__LINE__,B_ABS, 0,P_Z,P_Z,   0,0,0, R_ALL, 0, 0,P_Z,P_Z },
   {__LINE__,B_ABS, 1,P_Z,P_Z,   0,0,0, R_ALL, 0, 0,P_Z,P_Z },
@@ -433,7 +433,7 @@ static const optest_t optests[] = {
   {__LINE__,B_ABS, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
   {__LINE__,B_ABS, 0,P_Z,P_Z1,  0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
   {__LINE__,B_ABS, 1,P_Z,P_Z1,  0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-  
+
   /* Square root.  */
   {__LINE__,B_SQRT, 0,P_Z,P_Z,   0,0,0, R_ALL, 0, 0,P_Z,P_Z },
   {__LINE__,B_SQRT, 1,P_Z,P_Z,   0,0,0, R_ALL, 0, 1,P_Z,P_Z },
@@ -459,7 +459,8 @@ static const optest_t optests[] = {
 static void
 check_op(void)
 {
-  int i, j;
+  size_t i;
+  int j;
   tocheck_t r, a, b, x;
   int raised;
 
@@ -497,7 +498,7 @@ static void
 fail_xr(int line, const char *rm, tocheck_t x, tocheck_t r, tocheck_t xx,
 	int xflag)
 {
-  int i;
+  size_t i;
   unsigned char *cx, *cr, *cxx;
 
   printf("%s:%d:round %s:fail\n with x=0x", __FILE__, line,rm);
@@ -539,7 +540,7 @@ check_sqrt(tocheck_t a)
 	  r0 = delta(r1,-1); r2 = delta(r1,1);
 	  switch (1 << j)
 	    {
-	    case R_NEAREST: 
+	    case R_NEAREST:
 	      x0 = r0 * r0 - a; x2 = r2 * r2 - a;
 	      ok = fabs(x0) >= fabs(x1) && fabs(x1) <= fabs(x2);
 	      break;
diff --git a/sysdeps/stub/atomicity.h b/sysdeps/stub/atomicity.h
new file mode 100644
index 0000000000..3916eebbcf
--- /dev/null
+++ b/sysdeps/stub/atomicity.h
@@ -0,0 +1,53 @@
+/* Low-level functions for atomitc operations.  ix86 version, x >= 4.
+   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.  */
+
+#ifndef _ATOMICITY_H
+#define _ATOMICITY_H	1
+
+#include <inttypes.h>
+
+
+static inline int
+__attribute__ ((unused))
+exchange_and_add (uint32_t *mem, int val)
+{
+  int result = *mem;
+  *mem += val;
+  return result;
+}
+
+static inline void
+__attribute__ ((unused))
+atomic_add (uint32_t *mem, int val)
+{
+  *mem += val;
+}
+
+static inline int
+__attribute__ ((unused))
+compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  if (*p != oldval)
+    return 0;
+
+  *p = newval;
+  return 1;
+}
+
+#endif /* atomicity.h */
diff --git a/sysdeps/stub/ftruncate.c b/sysdeps/stub/ftruncate.c
index b70bbc1746..c84ed4ab1b 100644
--- a/sysdeps/stub/ftruncate.c
+++ b/sysdeps/stub/ftruncate.c
@@ -18,6 +18,7 @@
 
 #include <sys/types.h>
 #include <errno.h>
+#include <unistd.h>
 
 /* Truncate the file FD refers to to LENGTH bytes.  */
 int
diff --git a/sysdeps/stub/getdents.c b/sysdeps/stub/getdents.c
index a773347f50..652eda2bc7 100644
--- a/sysdeps/stub/getdents.c
+++ b/sysdeps/stub/getdents.c
@@ -19,6 +19,7 @@
 #include <stddef.h>
 #include <errno.h>
 #include <sys/types.h>
+#include <dirent.h>
 
 ssize_t
 __getdirentries (fd, buf, nbytes, basep)
diff --git a/sysdeps/stub/init-posix.c b/sysdeps/stub/init-posix.c
index 0d632d6fb6..8e37bb6861 100644
--- a/sysdeps/stub/init-posix.c
+++ b/sysdeps/stub/init-posix.c
@@ -19,7 +19,7 @@
 #ifndef	HAVE_GNU_LD
 
 void
-__init_posix ()
+__init_posix (void)
 {
   return;
 }
diff --git a/sysdeps/stub/profil.c b/sysdeps/stub/profil.c
index a0ae3324e9..9613108e3a 100644
--- a/sysdeps/stub/profil.c
+++ b/sysdeps/stub/profil.c
@@ -28,7 +28,7 @@
    disable profiling.  Returns zero on success, -1 on error.  */
 
 int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 {
   if (scale == 0)
     /* Disable profiling.  */
@@ -37,4 +37,5 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
   __set_errno (ENOSYS);
   return -1;
 }
+weak_alias (__profil, profil)
 stub_warning (profil)
diff --git a/sysdeps/stub/reboot.c b/sysdeps/stub/reboot.c
index ae4465d1d9..8139aee83f 100644
--- a/sysdeps/stub/reboot.c
+++ b/sysdeps/stub/reboot.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <unistd.h>
+#include <sys/reboot.h>
 
 /* Reboot the system.  */
 int
diff --git a/sysdeps/stub/swapon.c b/sysdeps/stub/swapon.c
index d580a9a732..cbaa1c2fe3 100644
--- a/sysdeps/stub/swapon.c
+++ b/sysdeps/stub/swapon.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <unistd.h>
+#include <sys/swap.h>
 
 /* Make the block special device PATH available to the system for swapping.
    This call is restricted to the super-user.  */
diff --git a/sysdeps/stub/syscall.c b/sysdeps/stub/syscall.c
index 183ffc2893..4903b409b5 100644
--- a/sysdeps/stub/syscall.c
+++ b/sysdeps/stub/syscall.c
@@ -18,6 +18,7 @@
 
 #include <sysdep.h>
 #include <errno.h>
+#include <unistd.h>
 
 /* Do system call CALLNO, passing it the remaining arguments.
    This only makes sense in certain operating systems.  */
diff --git a/sysdeps/stub/ualarm.c b/sysdeps/stub/ualarm.c
index d8e0b0aff8..5972e240eb 100644
--- a/sysdeps/stub/ualarm.c
+++ b/sysdeps/stub/ualarm.c
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#include <unistd.h>
 
 /* Set an alarm to go off (generating a SIGALRM signal) in VALUE microseconds.
    If INTERVAL is nonzero, when the alarm goes off, the timer is reset to go
diff --git a/sysdeps/stub/usleep.c b/sysdeps/stub/usleep.c
index 412461b4f9..7ee41b63fa 100644
--- a/sysdeps/stub/usleep.c
+++ b/sysdeps/stub/usleep.c
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#include <unistd.h>
 
 /* Sleep USECONDS microseconds, or until a previously set timer goes off.  */
 unsigned int
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
index c0ffbcedf6..36863db486 100644
--- a/sysdeps/unix/sysv/linux/if_index.c
+++ b/sysdeps/unix/sysv/linux/if_index.c
@@ -26,6 +26,7 @@
 #include <bits/libc-lock.h>
 
 /* Try to get a socket to talk to the kernel.  */
+#if defined SIOGIFINDEX || defined SIOGIFNAME
 static int
 opensock (void)
 {
@@ -63,6 +64,7 @@ opensock (void)
   __libc_lock_unlock (lock);
   return fd;
 }
+#endif
 
 unsigned int
 if_nametoindex (const char *ifname)
diff --git a/sysdeps/unix/sysv/linux/net/if.h b/sysdeps/unix/sysv/linux/net/if.h
index 01e9f00943..f4c1a48579 100644
--- a/sysdeps/unix/sysv/linux/net/if.h
+++ b/sysdeps/unix/sysv/linux/net/if.h
@@ -42,7 +42,10 @@ enum
     IFF_MASTER = 0x400,		/* Master of a load balancer.  */
     IFF_SLAVE = 0x800,		/* Slave of a load balancer.  */
 
-    IFF_MULTICAST = 0x1000	/* Supports multicast.  */
+    IFF_MULTICAST = 0x1000,	/* Supports multicast.  */
+
+    IFF_PORTSEL = 0x2000,	/* Can set media type.  */
+    IFF_AUTOMEDIA = 0x4000	/* Auto media select active.  */
   };
 
 /* The ifaddr structure contains information about one address of an
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
index da5ad0eb45..6d240c4b7a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
@@ -1,4 +1,4 @@
-/* Definitions for POSIX memory map inerface.  Linux/MIPS version.
+/* Definitions for POSIX memory map inerface.  Linux/PowerPC version.
    Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -46,26 +46,15 @@
 #define MAP_FIXED	0x010		/* Interpret addr exactly.  */
 #ifdef __USE_MISC
 # define MAP_FILE	0x000
-# define MAP_ANONYMOUS	0x800		/* Don't use a file.  */
+# define MAP_ANONYMOUS	0x020		/* Don't use a file.  */
 # define MAP_ANON	MAP_ANONYMOUS
 #endif
 
-/* Not used by Linux, but here to make sure we don't clash with ABI
-   defines.  */
-#ifdef __USE_MISC
-# define MAP_RENAME	0x020		/* Assign page to file.  */
-# define MAP_AUTOGROW	0x040		/* File may grow by writing.  */
-# define MAP_LOCAL	0x080		/* Copy on fork/sproc.  */
-# define MAP_AUTORSRV	0x100		/* Logical swap reserved on demand.  */
-#endif
-
 /* These are Linux-specific.  */
 #ifdef __USE_MISC
-# define MAP_GROWSDOWN	0x1000		/* Stack-like segment.  */
-# define MAP_DENYWRITE	0x2000		/* ETXTBSY */
-# define MAP_EXECUTABLE	0x4000		/* Mark it as an executable.  */
-# define MAP_LOCKED	0x8000		/* Lock the mapping.  */
-# define MAP_NORESERVE	0x0400		/* Don't check for reservations.  */
+# define MAP_GROWSDOWN	0x0100		/* Stack-like segment.  */
+# define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+# define MAP_EXECUTABLE	0x1000		/* Mark it as an executable.  */
 #endif
 
 /* Flags to `msync'.  */
@@ -74,10 +63,11 @@
 #define MS_INVALIDATE	2		/* Invalidate the caches.  */
 
 /* Flags for `mlockall'.  */
-#define MCL_CURRENT	1		/* Lock all currently mapped pages.  */
-#define MCL_FUTURE	2		/* Lock all additions to address
+#define MCL_CURRENT	0x2000		/* Lock all currently mapped pages.  */
+#define MCL_FUTURE	0x4000		/* Lock all additions to address
 					   space.  */
 
+
 /* Flags for `mremap'.  */
 #ifdef __USE_GNU
 # define MREMAP_MAYMOVE	1
diff --git a/sysdeps/unix/sysv/linux/powerpc/brk.c b/sysdeps/unix/sysv/linux/powerpc/brk.S
index e9826bd098..f4a3f3bcec 100644
--- a/sysdeps/unix/sysv/linux/powerpc/brk.c
+++ b/sysdeps/unix/sysv/linux/powerpc/brk.S
@@ -18,30 +18,32 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <sysdep.h>
-#include <errno.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+	.comm	__curbrk,4,4
+	.section ".text"
+ENTRY(__brk)
+	stwu    %r1,-16(%r1)
+	stw	%r3,8(%r1)
+	DO_CALL(SYS_ify(brk))
+	lwz     %r6,8(%r1)
+#ifdef PIC
+	mflr    %r4
+	bl      _GLOBAL_OFFSET_TABLE_@local-4
+	mflr    %r5
+	lwz     %r5,__curbrk@got(%r5)
+	mtlr    %r4
+	stw     %r3,0(%r5)
+#else
+	stw     %r3,__curbrk@sdarel(%r13)
+#endif
+	cmplw   %r6,%r3
+	addi    %r1,%r1,16
+	li	%r3,0
+	blelr+
+	li      %r3,ENOMEM
+	b	JUMPTARGET(__syscall_error)
+END (__brk)
 
-void *__curbrk;
-
-int
-__brk (void *addr)
-{
-  register void *syscall_arg asm ("r3") = addr;
-  register int syscall_number asm ("r0") = SYS_ify (brk);
-  register void *newbrk asm ("r3");
-  asm ("sc"
-       : "=r" (newbrk)
-       : "r" (syscall_arg), "r" (syscall_number)
-       : "r4","r5","r6","r7","r8","r9","r10","r11","r12",
-         "ctr", "mq", "cr0", "cr1", "cr6", "cr7");
-
-  __curbrk = newbrk;
-
-  if (newbrk < addr)
-    {
-      __set_errno (ENOMEM);
-      return -1;
-    }
-
-  return 0;
-}
 weak_alias (__brk, brk)
diff --git a/sysdeps/unix/sysv/linux/powerpc/clone.S b/sysdeps/unix/sysv/linux/powerpc/clone.S
index cca63fe0bc..6209922b6b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/clone.S
@@ -30,13 +30,12 @@
 ENTRY(__clone)
 	/* Set up stack frame, save registers.  */
 	stwu  %r1,-32(%r1)
-	stw   %r31,16(%r1)
-	stw   %r30,20(%r1)
-
 	/* Check for child_stack == NULL || fn == NULL.  */
 	cmpwi %cr0,%r4,0
-	beq-  %cr0,badargs
+	stw   %r31,16(%r1)
 	cmpwi %cr1,%r3,0
+	stw   %r30,20(%r1)
+	beq-  %cr0,badargs
 	beq-  %cr1,badargs
 
 	/* Set up stack frame for child.  */
@@ -45,7 +44,7 @@ ENTRY(__clone)
 	li    %r0,0
 	stw   %r0,0(%r4)
 
-	/* Save new stack, fn, args across syscall.  */
+	/* Save fn, args across syscall.  */
 	mr    %r30,%r3		/* Function in r30.  */
 	mr    %r31,%r6		/* Arguments in r31.  */
 
@@ -70,21 +69,15 @@ child:
 	mr    %r3,%r31
 	blrl
 	/* Call _exit with result from procedure.  */
-#ifdef PIC
-	b _exit@plt
-#else
-	b _exit
-#endif
+	b JUMPTARGET(_exit)
 
 badargs:
-	li 3,-EINVAL
+	li    %r3,EINVAL
 error:
-#ifdef PIC
-	b __syscall_error@plt
-#else
-	b __syscall_error
-#endif
-
-PSEUDO_END (__clone)
+	lwz   %r31,16(%r1)
+	lwz   %r30,20(%r1)
+	addi  %r1,%r1,32
+	b JUMPTARGET(__syscall_error)
+END (__clone)
 
 weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
index fed0913574..4be6f11270 100644
--- a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
@@ -17,10 +17,18 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <signal.h>
+#include <sys/ptrace.h>
+
+/* You can also do this by using
+   void
+   profil_counter (int signo, struct pt_regs *pt)
+   {
+     profil_count ((void *) pt->nip);
+   }
+   */
 
 void
-profil_counter (int signo, struct sigcontext sc)
+profil_counter (int signo, void **regs)
 {
-  profil_count ((void *) sc.regs->nip);
+  profil_count (regs[PT_NIP]);
 }
diff --git a/sysdeps/unix/sysv/linux/powerpc/sigreturn.S b/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
index 748c26761f..9b9413e2f3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
+++ b/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
@@ -18,9 +18,6 @@
 
 #include <sysdep.h>
 
-/* The 'sigreturn' syscall does not return.  */
-
-	.text
-ENTRY(__sigreturn)
-	DO_CALL(SYS_ify(sigreturn))
-PSEUDO_END (__sigreturn)
+PSEUDO (__sigreturn, sigreturn, 1)
+	/* Shouldn't get here.  */
+PSEUDO_END(__sigreturn)
diff --git a/sysdeps/unix/sysv/linux/powerpc/socket.S b/sysdeps/unix/sysv/linux/powerpc/socket.S
index 904bca4dc3..681f7e6445 100644
--- a/sysdeps/unix/sysv/linux/powerpc/socket.S
+++ b/sysdeps/unix/sysv/linux/powerpc/socket.S
@@ -71,17 +71,11 @@ ENTRY(P(__,socket))
 #if NARGS >= 9
 #error too many arguments!
 #endif
-	li   %r3,P(SOCKOP_,socket)
-	addi %r4,%r1,stackblock
+	li	%r3,P(SOCKOP_,socket)
+	addi	%r4,%r1,stackblock
 	DO_CALL(SYS_ify(socketcall))
-	addi %r1,%r1,48
-	bnslr
-#ifdef PIC
-	b __syscall_error@plt
-#else
-	b __syscall_error
-#endif
-
+	addi	%r1,%r1,48
+	PSEUDO_RET
 PSEUDO_END (P(__,socket))
 
 weak_alias (P(__,socket), socket)
diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S
index 2cb548245b..4d55076907 100644
--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S
+++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S
@@ -18,7 +18,6 @@
 
 #include <sysdep.h>
 
-	.text
 ENTRY (syscall)
 	mr   %r0,%r3
 	mr   %r3,%r4
@@ -27,10 +26,5 @@ ENTRY (syscall)
 	mr   %r6,%r7
 	mr   %r7,%r8
 	sc
-	bnslr
-#ifdef PIC
-	b __syscall_error@plt
-#else
-	b __syscall_error
-#endif
+	PSEUDO_RET
 PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index 577809acb8..944793d56f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -31,32 +31,113 @@
 
 #ifdef ASSEMBLER
 
-#define ENTRY(name)                                                           \
-  .globl name;							              \
-  .type name,@function;						              \
-  .align 2;								      \
+/* This seems to always be the case on PPC.  */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right.  */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+/* If compiled for profiling, call `_mcount' at the start of each function.  */
+#ifdef	PROF
+/* The mcount code relies on a the return address being on the stack
+   to locate our caller and so it can restore it; so store one just
+   for its benefit.  */
+#ifdef PIC
+#define CALL_MCOUNT							      \
+  .pushsection;								      \
+  .section ".data";    							      \
+  .align ALIGNARG(2);							      \
+0:.long 0;								      \
+  .previous;								      \
+  mflr  %r0;								      \
+  stw   %r0,4(%r1);	       						      \
+  bl    _GLOBAL_OFFSET_TABLE_@local-4;					      \
+  mflr  %r11;								      \
+  lwz   %r0,0b@got(%r11);						      \
+  bl    JUMPTARGET(_mcount);
+#else  /* PIC */
+#define CALL_MCOUNT							      \
+  .section ".data";							      \
+  .align ALIGNARG(2);							      \
+0:.long 0;								      \
+  .previous;								      \
+  mflr  %r0;								      \
+  lis   %r11,0b@ha;		       					      \
+  stw   %r0,4(%r1);	       						      \
+  addi  %r0,%r11,0b@l;							      \
+  bl    JUMPTARGET(_mcount);
+#endif /* PIC */
+#else  /* PROF */
+#define CALL_MCOUNT		/* Do nothing.  */
+#endif /* PROF */
+
+#define	ENTRY(name)							      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
+  .align ALIGNARG(2);							      \
+  C_LABEL(name)								      \
+  CALL_MCOUNT
+
+#define EALIGN_W_0  /* No words to insert.  */
+#define EALIGN_W_1  nop
+#define EALIGN_W_2  nop;nop
+#define EALIGN_W_3  nop;nop;nop
+#define EALIGN_W_4  EALIGN_W_3;nop
+#define EALIGN_W_5  EALIGN_W_4;nop
+#define EALIGN_W_6  EALIGN_W_5;nop
+#define EALIGN_W_7  EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+   past a 2^align boundary.  */
+#ifdef PROF
+#define EALIGN(name, alignt, words)					      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
+  .align ALIGNARG(2);							      \
+  C_LABEL(name)								      \
+  CALL_MCOUNT								      \
+  b 0f;									      \
+  .align ALIGNARG(alignt);						      \
+  EALIGN_W_##words;							      \
+  0:
+#else /* PROF */
+#define EALIGN(name, alignt, words)					      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
+  .align ALIGNARG(alignt);						      \
+  EALIGN_W_##words;							      \
   C_LABEL(name)
+#endif
+
+#undef	END
+#define END(name)							      \
+  ASM_SIZE_DIRECTIVE(name)
 
 #define DO_CALL(syscall)				      		      \
     li 0,syscall;						              \
     sc
 
 #ifdef PIC
+#define JUMPTARGET(name) name##@plt
+#else
+#define JUMPTARGET(name) name
+#endif
+
 #define PSEUDO(name, syscall_name, args)				      \
   .section ".text";							      \
   ENTRY (name)								      \
-    DO_CALL (SYS_ify (syscall_name));					      \
+    DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET							      \
     bnslr;								      \
-    b __syscall_error@plt
-#else
-#define PSEUDO(name, syscall_name, args)                                      \
-  .section ".text";							      \
-  ENTRY (name)                                                                \
-    DO_CALL (SYS_ify (syscall_name));				              \
-    bnslr;                                                                    \
-    b __syscall_error
-#endif
+    b JUMPTARGET(__syscall_error)
+#define ret PSEUDO_RET
+
+#undef	PSEUDO_END
+#define	PSEUDO_END(name)						      \
+  END (name)
 
-#define ret	/* Nothing (should be 'blr', but never reached).  */
+/* Local labels stripped out by the linker.  */
+#define L(x) .L##x
 
 #endif	/* ASSEMBLER */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h b/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
index 8a14f99f43..46867d8e41 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
@@ -33,10 +33,10 @@
 #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)
+#define TCGETS	_IOR ('T', 8, struct __kernel_termios)
+#define TCSETS	_IOW ('T', 9, struct __kernel_termios)
+#define TCSETSW	_IOW ('T', 10, struct __kernel_termios)
+#define TCSETSF	_IOW ('T', 11, struct __kernel_termios)
 
 #include <linux/sockios.h>
 
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios.h b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
index bf7aa1480f..54ac773b70 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/termios.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
@@ -20,9 +20,9 @@
 #ifndef _SPARC_TERMBITS_H
 #define _SPARC_TERMBITS_H	1
 
-typedef unsigned char   cc_t;
-typedef unsigned int    speed_t;
-typedef unsigned long   tcflag_t;
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
 
 #define NCCS 17
 struct termios
@@ -31,11 +31,11 @@ struct termios
     tcflag_t c_oflag;		/* output mode flags */
     tcflag_t c_cflag;		/* control mode flags */
     tcflag_t c_lflag;		/* local mode flags */
-    cc_t c_line;			/* line discipline */
+    cc_t c_line;		/* line discipline */
     cc_t c_cc[NCCS];		/* control characters */
 #ifdef __KERNEL__
 #define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
-    cc_t _x_cc[2];                  /* We need them to hold vmin/vtime */
+    cc_t _x_cc[2];		/* We need them to hold vmin/vtime */
 #endif
   };
 
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
index c4563776b6..bcc134e09c 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
@@ -44,3 +44,5 @@ ENTRY(longjmp)
 END(longjmp)
 
 strong_alias(longjmp, __longjmp)
+eak_alias(longjmp, _longjmp)
+weak_alias(longjmp, siglongjmp)
diff --git a/sysdeps/vax/strcmp.s b/sysdeps/vax/strcmp.s
new file mode 100644
index 0000000000..c9c5b479ae
--- /dev/null
+++ b/sysdeps/vax/strcmp.s
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+	.asciz "@(#)strcmp.s	5.6 (Berkeley) 6/1/90"
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Compare string s1 lexicographically to string s2.
+ * Return:
+ *	0	s1 == s2
+ *	> 0	s1 > s2
+ *	< 0	s2 < s2
+ *
+ * strcmp(s1, s2)
+ *	char *s1, *s2;
+ */
+#include "DEFS.h"
+
+ENTRY(strcmp, 0)
+	movl	4(ap),r1	# r1 = s1
+	movl	8(ap),r3	# r3 = s2
+	subb3	(r3),(r1),r0	# quick check for first char different
+	beql	1f		# have to keep checking
+	cvtbl	r0,r0
+	ret
+1:
+	clrl	r5		# calculate min bytes to next page boundary
+	subb3	r1,$255,r5	# r5 = (bytes - 1) to end of page for s1
+	subb3	r3,$255,r0	# r0 = (bytes - 1) to end of page for s2
+	cmpb	r0,r5		# r5 = min(r0, r5);
+	bgtru	2f
+	movb	r0,r5
+2:
+	incl	r5		# r5 = min bytes to next page boundary
+	cmpc3	r5,(r1),(r3)	# compare strings
+	bneq	3f
+	subl2	r5,r1		# check if found null yet
+	locc	$0,r5,(r1)
+	beql	1b		# not yet done, continue checking
+	subl2	r0,r3
+	mnegb	(r3),r0		# r0 = '\0' - *s2
+	cvtbl	r0,r0
+	ret
+3:
+	subl2	r0,r5		# check for null in matching string
+	subl2	r5,r1
+	locc	$0,r5,(r1)
+	bneq	4f
+	subb3	(r3),(r1),r0	# r0 = *s1 - *s2
+	cvtbl	r0,r0
+	ret
+4:
+	clrl	r0		# both the same to null
+	ret
diff --git a/time/Makefile b/time/Makefile
index 123ba2d08a..c4945f7e4b 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -59,7 +59,9 @@ define nl
 
 
 endef
+ifneq ($(no_deps),t)
 -include $(addprefix $(objpfx)z.,$(tzfiles))
+endif
 
 # Make these absolute file names.
 installed-localtime-file := $(firstword $(filter /%,$(inst_localtime-file)) \
@@ -80,6 +82,7 @@ endif
 ifeq ($(have-ksh),yes)
 install-others += $(inst_zonedir)/iso3166.tab $(inst_zonedir)/zone.tab
 install-bin += tzselect
+generated += tzselect
 endif
 
 include ../Rules
diff --git a/time/README b/time/README
index c15f4f6f63..c189555c40 100644
--- a/time/README
+++ b/time/README
@@ -3,7 +3,7 @@ The source files
 	`zdump.c'
 	`tzselect.ksh'
 	`checktab.awk'
-come from the tzcode1997f package by Arthur David Olsen et.al.
+come from the tzcode1997g package by Arthur David Olsen et.al.
 
 The files
 	`africa'
@@ -25,4 +25,4 @@ The files
 	`zone.tab'
 	`leapseconds'
 	`yearistype'
-come from the tzdata1997g package by Arthur David Olsen et.al.
+come from the tzdata1997h package by Arthur David Olsen et.al.
diff --git a/time/gmtime.c b/time/gmtime.c
index f9627e7b62..2b388befb1 100644
--- a/time/gmtime.c
+++ b/time/gmtime.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Convert `time_t' to `struct tm' in UTC.
+   Copyright (C) 1991, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -16,19 +17,14 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <stddef.h>
 #include <time.h>
 
 /* Defined in localtime.c.  */
 extern struct tm _tmbuf;
 
-/* Return the `struct tm' representation of *T in UTC.	*/
-struct tm *
-gmtime (t)
-     const time_t *t;
-{
-  return __gmtime_r (t, &_tmbuf);
-}
+/* Prototype for the internal function to get information based on TZ.  */
+extern struct tm *__tz_convert __P ((const time_t *t, int use_localtime,
+				     struct tm *tp));
 
 
 /* Return the `struct tm' representation of *T in UTC,
@@ -38,12 +34,15 @@ __gmtime_r (t, tp)
      const time_t *t;
      struct tm *tp;
 {
-  __offtime (t, 0L, tp);
+  return __tz_convert (t, 0, tp);
+}
+weak_alias (__gmtime_r, gmtime_r)
 
-  tp->tm_isdst = 0;
-  tp->tm_gmtoff = 0L;
-  tp->tm_zone = "GMT";
 
-  return tp;
+/* Return the `struct tm' representation of *T in UTC.	*/
+struct tm *
+gmtime (t)
+     const time_t *t;
+{
+  return __tz_convert (t, 0, &_tmbuf);
 }
-weak_alias (__gmtime_r, gmtime_r)
diff --git a/time/localtime.c b/time/localtime.c
index 6b7c9f394c..3d8d8fbd10 100644
--- a/time/localtime.c
+++ b/time/localtime.c
@@ -17,106 +17,33 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <errno.h>
 #include <time.h>
-#include <bits/libc-lock.h>
 
 /* The C Standard says that localtime and gmtime return the same pointer.  */
 struct tm _tmbuf;
 
 /* Prototype for the internal function to get information based on TZ.  */
-extern void __tzset_internal __P ((int always));
-extern int __tz_compute __P ((time_t timer, struct tm *tp));
-extern int __tzfile_compute __P ((time_t timer,
-				  long int *leap_correct, int *leap_hit));
+extern struct tm *__tz_convert __P ((const time_t *t, int use_localtime,
+				     struct tm *tp));
 
-extern int __use_tzfile;
 
-/* This lock is defined in tzset.c and locks all the data defined there
-   and in tzfile.c; the internal functions do no locking themselves.
-   This lock is only taken here and in `tzset'.  */
-__libc_lock_define (extern, __tzset_lock)
-
-
-/* Return the `struct tm' representation of *TIMER in the local timezone.  */
-static struct tm *
-localtime_internal (const time_t *timer, struct tm *tp)
-{
-  long int leap_correction;
-  int leap_extra_secs;
-
-  if (timer == NULL)
-    {
-      __set_errno (EINVAL);
-      return NULL;
-    }
-
-  if (__use_tzfile)
-    {
-      if (! __tzfile_compute (*timer, &leap_correction, &leap_extra_secs))
-	tp = NULL;
-    }
-  else
-    {
-      tp = __gmtime_r (timer, tp);
-      if (tp && ! __tz_compute (*timer, tp))
-	tp = NULL;
-      leap_correction = 0L;
-      leap_extra_secs = 0;
-    }
-
-  if (tp)
-    {
-      __offtime (timer, __timezone - leap_correction, tp);
-      tp->tm_sec += leap_extra_secs;
-      tp->tm_isdst = __daylight;
-      tp->tm_gmtoff = __timezone;
-      tp->tm_zone = __tzname[__daylight];
-    }
-
-  return tp;
-}
-
-
-/* POSIX.1 8.3.7.2 says that localtime_r is not required to set
-   tzname.  This is a good idea since this allows at least a bit more
-   parallelism.  */
 
+/* Return the `struct tm' representation of *T in local time,
+   using *TP to store the result.  */
 struct tm *
-localtime (timer)
-     const time_t *timer;
+__localtime_r (t, tp)
+     const time_t *t;
+     struct tm *tp;
 {
-  struct tm *result;
-
-  __libc_lock_lock (__tzset_lock);
-
-  /* Update internal database according to current TZ setting.  */
-  __tzset_internal (1);
-
-  result = localtime_internal (timer, &_tmbuf);
-
-  __libc_lock_unlock (__tzset_lock);
-
-  return result;
+  return __tz_convert (t, 1, tp);
 }
+weak_alias (__localtime_r, localtime_r)
 
 
+/* Return the `struct tm' representation of *T in local time.  */
 struct tm *
-__localtime_r (timer, tp)
-     const time_t *timer;
-     struct tm *tp;
+localtime (t)
+     const time_t *t;
 {
-  struct tm *result;
-
-  __libc_lock_lock (__tzset_lock);
-
-  /* Make sure the database is initialized.  */
-  __tzset_internal (0);
-
-  result = localtime_internal (timer, tp);
-
-  __libc_lock_unlock (__tzset_lock);
-
-  return result;
+  return __tz_convert (t, 1, &_tmbuf);
 }
-weak_alias (__localtime_r, localtime_r)
diff --git a/time/mktime.c b/time/mktime.c
index 5012888967..1573cc79a9 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -225,10 +225,10 @@ __mktime_internal (tp, convert, offset)
 	       [mon_remainder + 12 * negative_mon_remainder])
 	      + mday - 1);
 
+  int sec_requested = sec;
 #if LEAP_SECONDS_POSSIBLE
   /* Handle out-of-range seconds specially,
      since ydhms_tm_diff assumes every minute has 60 seconds.  */
-  int sec_requested = sec;
   if (sec < 0)
     sec = 0;
   if (59 < sec)
diff --git a/time/offtime.c b/time/offtime.c
index f13c8a38ae..a4b59ed209 100644
--- a/time/offtime.c
+++ b/time/offtime.c
@@ -33,8 +33,8 @@ __offtime (t, offset, tp)
      long int offset;
      struct tm *tp;
 {
-  register long int days, rem, y;
-  register const unsigned short int *ip;
+  long int days, rem, y;
+  const unsigned short int *ip;
 
   days = *t / SECS_PER_DAY;
   rem = *t % SECS_PER_DAY;
@@ -75,7 +75,7 @@ __offtime (t, offset, tp)
   tp->tm_year = y - 1900;
   tp->tm_yday = days;
   ip = __mon_yday[__isleap(y)];
-  for (y = 11; days < ip[y]; --y)
+  for (y = 11; days < (long int) ip[y]; --y)
     continue;
   days -= ip[y];
   tp->tm_mon = y;
diff --git a/time/strftime.c b/time/strftime.c
index 891d301f5c..4ecbc5a519 100644
--- a/time/strftime.c
+++ b/time/strftime.c
@@ -132,7 +132,6 @@ extern char *tzname[];
 #ifdef _LIBC
 # define gmtime_r __gmtime_r
 # define localtime_r __localtime_r
-extern int __tz_compute __P ((time_t timer, const struct tm *tm));
 # define tzname __tzname
 # define tzset __tzset
 #else
diff --git a/time/tzfile.c b/time/tzfile.c
index aeec637b3b..9289de63a0 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -112,8 +112,8 @@ __tzfile_read (const char *file)
     /* No user specification; use the site-wide default.  */
     file = TZDEFAULT;
   else if (*file == '\0')
-    /* User specified the empty string; use UTC explicitly.  */
-    file = "Universal";
+    /* User specified the empty string; use UTC with no leap seconds.  */
+    return;
   else
     {
       /* We must not allow to read an arbitrary file in a setuid
@@ -411,19 +411,23 @@ find_transition (time_t timer)
 }
 
 int
-__tzfile_compute (time_t timer, long int *leap_correct, int *leap_hit)
+__tzfile_compute (time_t timer, int use_localtime,
+		  long int *leap_correct, int *leap_hit)
 {
-  struct ttinfo *info;
   register size_t i;
 
-  info = find_transition (timer);
-  __daylight = info->isdst;
-  __timezone = info->offset;
-  for (i = 0; i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]);
-       ++i)
-    __tzname[types[i].isdst] = &zone_names[types[i].idx];
-  if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0]))
-    __tzname[info->isdst] = &zone_names[info->idx];
+  if (use_localtime)
+    {
+      struct ttinfo *info = find_transition (timer);
+      __daylight = info->isdst;
+      __timezone = info->offset;
+      for (i = 0;
+	   i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]);
+	   ++i)
+	__tzname[types[i].isdst] = &zone_names[types[i].idx];
+      if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0]))
+	__tzname[info->isdst] = &zone_names[info->idx];
+    }
 
   *leap_correct = 0L;
   *leap_hit = 0;
@@ -455,7 +459,7 @@ __tzfile_compute (time_t timer, long int *leap_correct, int *leap_hit)
   return 1;
 }
 
-void
+static void
 compute_tzname_max (size_t chars)
 {
   extern size_t __tzname_cur_max; /* Defined in tzset.c. */
diff --git a/time/tzset.c b/time/tzset.c
index 49935c04d3..6c16091ef5 100644
--- a/time/tzset.c
+++ b/time/tzset.c
@@ -17,6 +17,8 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <ctype.h>
+#include <errno.h>
+#include <bits/libc-lock.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -26,15 +28,19 @@
 /* Defined in mktime.c.  */
 extern const unsigned short int __mon_yday[2][13];
 
+/* Defined in localtime.c.  */
+extern struct tm _tmbuf;
+
 #define NOID
 #include "tzfile.h"
 
 extern int __use_tzfile;
 extern void __tzfile_read __P ((const char *file));
+extern int __tzfile_compute __P ((time_t timer, int use_localtime,
+				  long int *leap_correct, int *leap_hit));
 extern void __tzfile_default __P ((const char *std, const char *dst,
 				   long int stdoff, long int dstoff));
 extern char * __tzstring __P ((const char *string));
-extern int __tz_compute __P ((time_t timer, const struct tm *tm));
 
 char *__tzname[2] = { (char *) "GMT", (char *) "GMT" };
 int __daylight = 0;
@@ -44,6 +50,9 @@ weak_alias (__tzname, tzname)
 weak_alias (__daylight, daylight)
 weak_alias (__timezone, timezone)
 
+/* This locks all the state variables in tzfile.c and this file.  */
+__libc_lock_define (static, tzset_lock)
+
 
 #define	min(a, b)	((a) < (b) ? (a) : (b))
 #define	max(a, b)	((a) > (b) ? (a) : (b))
@@ -74,6 +83,8 @@ static tz_rule tz_rules[2];
 
 
 static int compute_change __P ((tz_rule *rule, int year));
+static int tz_compute __P ((time_t timer, const struct tm *tm));
+static void tzset_internal __P ((int always));
 
 /* Header for a list of buffers containing time zone strings.  */
 struct tzstring_head
@@ -139,9 +150,8 @@ __tzstring (string)
 static char *old_tz = NULL;
 
 /* Interpret the TZ envariable.  */
-void __tzset_internal __P ((int always));
-void
-__tzset_internal (always)
+static void
+tzset_internal (always)
      int always;
 {
   static int is_initialized = 0;
@@ -426,7 +436,11 @@ size_t __tzname_cur_max;
 long int
 __tzname_max ()
 {
-  __tzset_internal (0);
+  __libc_lock_lock (tzset_lock);
+
+  tzset_internal (0);
+
+  __libc_lock_unlock (tzset_lock);
 
   return __tzname_cur_max;
 }
@@ -473,8 +487,9 @@ compute_change (rule, year)
     case M:
       /* Mm.n.d - Nth "Dth day" of month M.  */
       {
-	register int i, d, m1, yy0, yy1, yy2, dow;
-	register const unsigned short int *myday =
+	unsigned int i;
+	int d, m1, yy0, yy1, yy2, dow;
+	const unsigned short int *myday =
 	  &__mon_yday[__isleap (year)][rule->m];
 
 	/* First add SECSPERDAY for each day in months before M.  */
@@ -496,7 +511,7 @@ compute_change (rule, year)
 	  d += 7;
 	for (i = 1; i < rule->n; ++i)
 	  {
-	    if (d + 7 >= myday[0] - myday[-1])
+	    if (d + 7 >= (int) myday[0] - myday[-1])
 	      break;
 	    d += 7;
 	  }
@@ -519,13 +534,11 @@ compute_change (rule, year)
 /* Figure out the correct timezone for *TIMER and TM (which must be the same)
    and set `__tzname', `__timezone', and `__daylight' accordingly.
    Return nonzero on success, zero on failure.  */
-int
-__tz_compute (timer, tm)
+static int
+tz_compute (timer, tm)
      time_t timer;
      const struct tm *tm;
 {
-  __tzset_internal (0);
-
   if (! compute_change (&tz_rules[0], 1900 + tm->tm_year) ||
       ! compute_change (&tz_rules[1], 1900 + tm->tm_year))
     return 0;
@@ -548,20 +561,15 @@ __tz_compute (timer, tm)
   return 1;
 }
 
-#include <bits/libc-lock.h>
-
-/* This locks all the state variables in tzfile.c and this file.  */
-__libc_lock_define (, __tzset_lock)
-
 /* Reinterpret the TZ environment variable and set `tzname'.  */
 #undef tzset
 
 void
 __tzset (void)
 {
-  __libc_lock_lock (__tzset_lock);
+  __libc_lock_lock (tzset_lock);
 
-  __tzset_internal (1);
+  tzset_internal (1);
 
   if (!__use_tzfile)
     {
@@ -570,6 +578,67 @@ __tzset (void)
       __tzname[1] = (char *) tz_rules[1].name;
     }
 
-  __libc_lock_unlock (__tzset_lock);
+  __libc_lock_unlock (tzset_lock);
 }
 weak_alias (__tzset, tzset)
+
+/* Return the `struct tm' representation of *TIMER in the local timezone.
+   Use local time if USE_LOCALTIME is nonzero, UTC otherwise.  */
+struct tm *
+__tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
+{
+  long int leap_correction;
+  int leap_extra_secs;
+
+  if (timer == NULL)
+    {
+      __set_errno (EINVAL);
+      return NULL;
+    }
+
+  __libc_lock_lock (tzset_lock);
+
+  /* Update internal database according to current TZ setting.
+     POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.
+     This is a good idea since this allows at least a bit more parallelism.
+     By analogy we apply the same rule to gmtime_r.  */
+  tzset_internal (tp == &_tmbuf);
+
+  if (__use_tzfile)
+    {
+      if (! __tzfile_compute (*timer, use_localtime,
+			      &leap_correction, &leap_extra_secs))
+	tp = NULL;
+    }
+  else
+    {
+      __offtime (timer, 0, tp);
+      if (! tz_compute (*timer, tp))
+	tp = NULL;
+      leap_correction = 0L;
+      leap_extra_secs = 0;
+    }
+
+  if (tp)
+    {
+      if (use_localtime)
+	{
+	  tp->tm_isdst = __daylight;
+	  tp->tm_zone = __tzname[__daylight];
+	  tp->tm_gmtoff = __timezone;
+	}
+      else
+	{
+	  tp->tm_isdst = 0;
+	  tp->tm_zone = "GMT";
+	  tp->tm_gmtoff = 0L;
+	}
+
+      __offtime (timer, tp->tm_gmtoff - leap_correction, tp);
+      tp->tm_sec += leap_extra_secs;
+    }
+
+  __libc_lock_unlock (tzset_lock);
+
+  return tp;
+}