about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-10-18 09:58:59 +0000
committerJakub Jelinek <jakub@redhat.com>2004-10-18 09:58:59 +0000
commit56c4396a6e1568a5511ac43873fa3c9e1ebfa8d1 (patch)
treef2d0f6e1aaf9794668b53c6456fcacbbacd63805
parent4ce1a5c9712b4d7616058e708630c33744f983f6 (diff)
downloadglibc-56c4396a6e1568a5511ac43873fa3c9e1ebfa8d1.tar.gz
glibc-56c4396a6e1568a5511ac43873fa3c9e1ebfa8d1.tar.xz
glibc-56c4396a6e1568a5511ac43873fa3c9e1ebfa8d1.zip
Updated to fedora-glibc-20041018T0940
-rw-r--r--ChangeLog239
-rw-r--r--argp/argp-fs-xinl.c4
-rw-r--r--argp/argp-xinl.c4
-rw-r--r--debug/Makefile23
-rw-r--r--debug/Versions8
-rw-r--r--debug/chk_fail.c38
-rw-r--r--debug/fprintf_chk.c45
-rw-r--r--debug/gets_chk.c77
-rw-r--r--debug/printf_chk.c45
-rw-r--r--debug/snprintf_chk.c38
-rw-r--r--debug/sprintf_chk.c35
-rw-r--r--debug/test-stpcpy_chk.c46
-rw-r--r--debug/test-strcpy_chk.c370
-rw-r--r--debug/tst-chk1.c466
-rw-r--r--debug/tst-chk2.c2
-rw-r--r--debug/tst-chk3.c2
-rw-r--r--debug/vfprintf_chk.c42
-rw-r--r--debug/vprintf_chk.c42
-rw-r--r--debug/vsnprintf_chk.c70
-rw-r--r--debug/vsprintf_chk.c91
-rw-r--r--elf/dl-minimal.c7
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in6
-rw-r--r--include/bits/string3.h1
-rw-r--r--include/features.h40
-rw-r--r--include/libc-symbols.h18
-rw-r--r--include/resolv.h38
-rw-r--r--include/stdio.h14
-rw-r--r--include/string.h28
-rw-r--r--include/sys/cdefs.h8
-rw-r--r--libio/Makefile4
-rw-r--r--libio/bits/stdio2.h78
-rw-r--r--libio/libio.h3
-rw-r--r--libio/stdio.h3
-rw-r--r--libio/strfile.h10
-rw-r--r--libio/vsnprintf.c12
-rw-r--r--libio/vswprintf.c8
-rw-r--r--linuxthreads/ChangeLog5
-rw-r--r--manual/memory.texi2
-rw-r--r--misc/sys/cdefs.h5
-rw-r--r--nptl/ChangeLog7
-rw-r--r--nptl/sysdeps/alpha/tcb-offsets.sym6
-rw-r--r--nscd/Makefile4
-rw-r--r--nscd/connections.c10
-rw-r--r--nscd/nscd.h9
-rw-r--r--nscd/nscd.init1
-rw-r--r--resolv/base64.c9
-rw-r--r--resolv/gethnamaddr.c8
-rw-r--r--resolv/ns_name.c2
-rw-r--r--resolv/ns_netint.c3
-rw-r--r--resolv/res_comp.c15
-rw-r--r--resolv/res_data.c7
-rw-r--r--resolv/res_debug.c31
-rw-r--r--resolv/res_mkquery.c1
-rw-r--r--resolv/res_query.c6
-rw-r--r--resolv/res_send.c3
-rw-r--r--stdio-common/vfprintf.c19
-rw-r--r--string/Makefile2
-rw-r--r--string/bits/string3.h167
-rw-r--r--string/string.h5
-rw-r--r--sunrpc/rpc_clntout.c4
-rw-r--r--sunrpc/rpc_cout.c4
-rw-r--r--sunrpc/rpc_hout.c4
-rw-r--r--sunrpc/rpc_main.c4
-rw-r--r--sunrpc/rpc_parse.c4
-rw-r--r--sunrpc/rpc_sample.c4
-rw-r--r--sunrpc/rpc_scan.c4
-rw-r--r--sunrpc/rpc_svcout.c4
-rw-r--r--sunrpc/rpc_tblout.c4
-rw-r--r--sunrpc/rpc_util.c4
-rw-r--r--sysdeps/alpha/dl-machine.h6
-rw-r--r--sysdeps/generic/memcpy_chk.c66
-rw-r--r--sysdeps/generic/memmove_chk.c98
-rw-r--r--sysdeps/generic/mempcpy_chk.c67
-rw-r--r--sysdeps/generic/memset_chk.c92
-rw-r--r--sysdeps/generic/readonly-area.c29
-rw-r--r--sysdeps/generic/stpcpy_chk.c45
-rw-r--r--sysdeps/generic/strcat_chk.c58
-rw-r--r--sysdeps/generic/strcpy_chk.c46
-rw-r--r--sysdeps/generic/strncat_chk.c100
-rw-r--r--sysdeps/generic/strncpy_chk.c89
-rw-r--r--sysdeps/i386/i686/memcpy.S9
-rw-r--r--sysdeps/i386/i686/memcpy_chk.S35
-rw-r--r--sysdeps/i386/i686/memmove.S9
-rw-r--r--sysdeps/i386/i686/memmove_chk.S35
-rw-r--r--sysdeps/i386/i686/mempcpy.S7
-rw-r--r--sysdeps/i386/i686/mempcpy_chk.S35
-rw-r--r--sysdeps/i386/i686/memset.S7
-rw-r--r--sysdeps/i386/i686/memset_chk.S35
-rw-r--r--sysdeps/mach/hurd/Makefile6
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.c8
-rw-r--r--sysdeps/unix/sysv/linux/adjtime.c7
-rw-r--r--sysdeps/unix/sysv/linux/alpha/adjtime.c11
-rw-r--r--sysdeps/unix/sysv/linux/alpha/register-dump.h161
-rw-r--r--sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h12
-rw-r--r--sysdeps/unix/sysv/linux/i386/syscall.S10
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h7
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/sysdep.h5
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h5
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h5
-rw-r--r--sysdeps/unix/sysv/linux/readonly-area.c90
-rw-r--r--sysdeps/x86_64/memcpy.S6
-rw-r--r--sysdeps/x86_64/memcpy_chk.S34
-rw-r--r--sysdeps/x86_64/mempcpy.S1
-rw-r--r--sysdeps/x86_64/mempcpy_chk.S34
-rw-r--r--sysdeps/x86_64/memset.S8
-rw-r--r--sysdeps/x86_64/memset_chk.S34
-rw-r--r--sysdeps/x86_64/stpcpy_chk.S3
-rw-r--r--sysdeps/x86_64/strcpy_chk.S211
109 files changed, 3731 insertions, 131 deletions
diff --git a/ChangeLog b/ChangeLog
index fc66050f1e..1e5ff7d981 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,242 @@
+2004-10-06  Maciej W. Rozycki  <macro@mips.com>
+
+	* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
+	(__SYSCALL_CLOBBERS): Add "memory".
+	* sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
+	(__SYSCALL_CLOBBERS): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
+	(__SYSCALL_CLOBBERS): Likewise.
+
+2004-10-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* include/libc-symbols.h: Define libresolv_hidden_proto and friends.
+	* include/resolv.h: Add libresolv_hidden_proto for symbols defined,
+	used, and exported in libresolv.
+	* resolv/base64.c: Add libresolv_hidden_def.
+	* resolv/gethnamaddr.c: Likewise.
+	* resolv/ns_name.c: Likewise.
+	* resolv/ns_netint.c: Likewise.
+	* resolv/res_comp.c: Likewise.
+	* resolv/res_data.c: Likewise.
+	* resolv/res_debug.c: Likewise.
+	* resolv/res_mkquery.c: Likewise.
+	* resolv/res_query.c: Likewise.
+	* resolv/res_send.c: Likewise.
+
+2004-10-15  Jakub Jelinek  <jakub@redhat.com>
+
+	* elf/dl-minimal.c (__chk_fail): New.  Add rtld_hidden_def.
+	* sysdeps/unix/sysv/linux/readonly-area.c: New file.
+	* sysdeps/i386/i686/memmove.S (__memmove_chk): Add checking
+	routine.
+	* sysdeps/i386/i686/memcpy.S (__memcpy_chk): Likewise.
+	* sysdeps/i386/i686/mempcpy.S (__mempcpy_chk): Likewise.
+	* sysdeps/i386/i686/memset.S (__memset_chk): Likewise.
+	* sysdeps/i386/i686/memmove-chk.S: New file.
+	* sysdeps/i386/i686/memcpy-chk.S: Likewise.
+	* sysdeps/i386/i686/mempcpy-chk.S: Likewise.
+	* sysdeps/i386/i686/memset-chk.S: Likewise.
+	* sysdeps/generic/strcat-chk.c (__strcat_chk): Don't __chk_fail
+	if exactly fitting into buffer.
+	* sysdeps/generic/strncat-chk.c (__strncat_chk): Likewise.
+	* sysdeps/generic/readonly-area.c: New file.
+	* sysdeps/generic/strncpy-chk.c (__strncpy_chk): Only test
+	destlen once.
+	* sysdeps/x86_64/memset.S (__memset_chk): Add checking routine.
+	* sysdeps/x86_64/memcpy.S (__memcpy_chk): Likewise.
+	* sysdeps/x86_64/mempcpy.S (__memcpy_chk): Define to __mempcpy_chk.
+	* sysdeps/x86_64/memcpy-chk.S: New file.
+	* sysdeps/x86_64/mempcpy-chk.S: Likewise.
+	* sysdeps/x86_64/memset-chk.S: Likewise.
+	* sysdeps/x86_64/strcpy-chk.S: Likewise.
+	* sysdeps/x86_64/stpcpy-chk.S: Likewise.
+	* argp/argp-xinl.c (__OPTIMIZE__): Define to 1 instead of nothing.
+	* argp/argp-fs-xinl.c (__OPTIMIZE__): Likewise.
+	* debug/tst-chk1.c: New test.
+	* debug/tst-chk2.c: Likewise.
+	* debug/tst-chk3.c: Likewise.
+	* debug/test-strcpy_chk.c: Likewise.
+	* debug/test-stpcpy_chk.c: Likewise.
+	* debug/vsprintf_chk.c (__vsprintf_chk): If flags > 0, request
+	_IO_FLAGS2_CHECK_PERCENT_N.  Add libc_hidden_def.
+	* debug/Makefile (routines): Add printf_chk, fprintf_chk, vprintf_chk,
+	vfprintf_chk, gets_chk and readonly-area.
+	(CFLAGS-*_chk.c): Set.
+	(tests): Add tst-chk1, tst-chk2, tst-chk3, test-strcpy_chk and
+	test-stpcpy_chk.
+	* debug/vprintf_chk.c: New file.
+	* debug/printf_chk.c: Likewise.
+	* debug/vfprintf_chk.c: Likewise.
+	* debug/fprintf_chk.c: Likewise.
+	* debug/gets_chk.c: Likewise.
+	* debug/chk_fail.c (__chk_fail): Add libc_hidden_def.
+	* debug/snprintf_chk.c (__snprintf_chk): Fix order of arguments
+	passed to __vsnprintf_chk.
+	* debug/Versions (libc): Export __printf_chk, __fprintf_chk,
+	__vprintf_chk, __vfprintf_chk and __gets_chk @GLIBC_2.3.4.
+	* debug/vsnprintf_chk.c (__vsnprintf_chk): Don't call
+	__vsnprintf, instead create a temporary file with
+	_IO_strn_jumps jumptable.  If flags > 0, request
+	_IO_FLAGS2_CHECK_PERCENT_N.  Add libc_hidden_def.
+	* libio/Makefile (headers): Add bits/stdio2.h.
+	* libio/stdio.h: Include <bits/stdio2.h> if __USE_FORTIFY_LEVEL.
+	(sprintf, snprintf, vsprintf, vsnprintf): Remove defines.
+	* libio/strfile.h (_IO_strnfile): New type.
+	(_IO_strn_jumps): New extern.
+	* libio/vsnprintf.c (_IO_strnfile): Remove.
+	(_IO_strn_jumps): Remove static.
+	* libio/bits/stdio2.h: New file.
+	* libio/vswprintf.c (_IO_strnfile): Rename type to...
+	(_IO_wstrnfile): ...this.  Adjust all uses.
+	* libio/libio.h (_IO_FLAGS2_CHECK_PERCENT_N): Define.
+	* stdio-common/vfprintf.c (STR_LEN): Define.
+	(vfprintf): Add readonly_format variable.
+	Handle _IO_FLAGS2_CHECK_PERCENT_N.
+	(buffered_vfprintf): Copy _flags2.
+	* include/stdio.h (__sprintf_chk, __snprintf_chk, __vsprintf_chk,
+	__vsnprintf_chk, __printf_chk, __fprintf_chk, __vprintf_chk,
+	__vfprintf_chk): New prototypes.
+	(__vsprintf_chk, __vsnprintf_chk): Add libc_hidden_proto.
+	* include/string.h (__memcpy_chk, __memmove_chk, __mempcpy_chk,
+	__memset_chk, __strcpy_chk, __stpcpy_chk, __strncpy_chk, __strcat_chk,
+	__strncat_chk): New prototypes.
+	* include/bits/string3.h: New file.
+	* include/sys/cdefs.h (__chk_fail): Add libc_hidden_proto
+	and rtld_hidden_proto.
+	* string/Makefile (headers): Add bits/string3.h.
+	* string/bits/string3.h (bcopy, bzero): New defines.
+	(memset, memcpy, memmove, strcpy, strncpy, strcat, strncat): Change
+	macros so that inlines are used only if unknown destination size
+	or side-effects in destination argument.
+	(mempcpy, stpcpy): Likewise.  Protect with #ifdef __USE_GNU.
+
+2004-09-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* debug/Makefile (routines): Add *_chk.
+	* debug/Versions (libc): Export __chk_fail, __memcpy_chk,
+	__memmove_chk, __mempcpy_chk, __memset_chk, __stpcpy_chk,
+	__strcat_chk, __strcpy_chk, __strncat_chk, __strncpy_chk,
+	__sprintf_chk, __vsprintf_chk, __snprintf_chk, __vsnprintf_chk
+	@GLIBC_2.3.4.
+	* debug/chk_fail.c: New file.
+	* debug/snprintf_chk.c: Likewise.
+	* debug/sprintf_chk.c: Likewise.
+	* debug/vsnprintf_chk.c: Likewise.
+	* debug/vsprintf_chk.c: Likewise.
+	* include/features.h (_FORTIFY_SOURCE): Document, handle.
+	(__USE_FORTIFY_LEVEL): Define.
+	(__GNUC_PREREQ): Move to earlier location.
+	* include/sys/cdefs.h (__chk_fail): New prototype.
+	* libio/bits/stdio.h (sprintf, vsprintf, snprintf, vsnprintf):
+	Define if __USE_FORTIFY_LEVEL.
+	* misc/sys/cdefs.h (__bos, __bos0): Define.
+	* string/string.h: Include <bits/string3.h> if __USE_FORTIFY_LEVEL.
+	* bits/string/string3.h: New header.
+	* sysdeps/generic/memcpy_chk.c: New file.
+	* sysdeps/generic/memmove_chk.c: Likewise.
+	* sysdeps/generic/mempcpy_chk.c: Likewise.
+	* sysdeps/generic/memset_chk.c: Likewise.
+	* sysdeps/generic/stpcpy_chk.c: Likewise.
+	* sysdeps/generic/strcat_chk.c: Likewise.
+	* sysdeps/generic/strcpy_chk.c: Likewise.
+	* sysdeps/generic/strncat_chk.c: Likewise.
+	* sysdeps/generic/strncpy_chk.c: Likewise.
+
+2004-10-17  Roland McGrath  <roland@frob.com>
+
+	* manual/memory.texi (Page Lock Functions): Typo fix.
+	Reported by Carlos Maziero <maziero@ppgia.pucpr.br>
+
+2004-10-16  Alfred M. Szmidt  <ams@kemisten.nu>
+
+	* sysdeps/mach/hurd/Makefile (link-libc-static): Use
+	`$(static-gnulib') instead of `$(gnulib)'.
+
+2004-10-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* sunrpc/rpc_clntout.c: Avoid including rcsid into binary.
+	* sunrpc/rpc_cout.c: Likewise.
+	* sunrpc/rpc_hout.c: Likewise.
+	* sunrpc/rpc_main.c: Likewise.
+	* sunrpc/rpc_parse.c: Likewise.
+	* sunrpc/rpc_sample.c: Likewise.
+	* sunrpc/rpc_scan.c: Likewise.
+	* sunrpc/rpc_svcout.c: Likewise.
+	* sunrpc/rpc_tblout.c: Likewise.
+	* sunrpc/rpc_util.c: Likewise.
+
+2004-10-15  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/sysdep.h (PUSHARGS_6, DOARGS_6,
+	POPARGS_6, _PUSHARGS_6, _DOARGS_6, _POPARGS_6): Define.
+	* sysdeps/unix/sysv/linux/i386/syscall.S (syscall): Handle 6 argument
+	syscalls.
+
+2004-10-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* nscd/nscd.h (_PATH_NSCD_PASSWD_DB): Move to /var/db.
+	(_PATH_NSCD_GROUP_DB): Likewise.
+	(_PATH_NSCD_HOSTS_DB): Likewise.
+	(_PATH_NSCD_XYZ_DB_TMP): New #define, point to /var/run.
+	* nscd/connections.c (nscd_init): Non-persistent database files
+	are created with the _PATH_NSCD_XYZ_DB_TMP path.
+	* nscd/nscd.init: Create /var/db/nscd if necessary.
+
+2004-10-15  Richard Henderson  <rth@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/register-dump.h: New file.
+	* sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h (SIGCONTEXT): Add
+	_code argument, pass sigcontext by pointer.
+	(SIGCONTEXT_EXTRA_ARGS): Likewise.
+	(GET_PC, GET_FRAME, GET_STACK): Expect ctx as pointer.
+
+2004-10-14  Richard Henderson  <rth@redhat.com>
+
+	* sysdeps/alpha/dl-machine.h (elf_machine_rela,
+	elf_machine_rela_relative, elf_machine_lazy_rel): Mark auto
+	instead of static.
+
+	* sysdeps/unix/sysv/linux/adjtime.c (ADJTIME): Use prototype
+	style definition.
+	* sysdeps/unix/sysv/linux/alpha/adjtime.c (ADJTIME): If
+	__ASSUME_TIMEVAL64, define __adjtime directly rather than
+	via strong_alias.
+
+2004-10-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* nscd/Makefile: When using compilers without -fpie support, also
+	link with -lselinux if necessary.
+	Patch by Arkadiusz Miskiewicz <arekm@pld-linux.org>.
+
+	* nscd/connections.c (nscd_init): Remove file if not persistent
+	and not shared.  Patch by Jerome Borsboom <j.borsboom@erasmusmc.nl>.
+
+2004-10-14  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/setresuid.c: Handle
+	defined __NR_setresuid32 && !defined __NR_setresuid.
+	* sysdeps/unix/sysv/linux/i386/setresgid.c: Handle
+	defined __NR_setresgid32 && !defined __NR_setresgid.
+
+	* sysdeps/sparc/fpu/bits/mathinline.h (__signbitf, __signbit,
+	__signbitl, sqrtf, sqrt, sqrtl, fdim, fdimf): Use __NTH macro.
+
+	* sysdeps/generic/errno-loc.c: Don't undef #errno
+	if RTLD_PRIVATE_ERRNO.
+	* include/errno.h (__errno_location): If RTLD_PRIVATE_ERRNO,
+	add attribute_hidden.
+
+	* dlfcn/dlinfo.c (dlinfo_doit): Replace iteration over GL(dl_loaded)
+	chain with iteration over all namespaces' _ns_loaded chains.
+	* sysdeps/powerpc/powerpc32/dl-machine.c (__elf_preferred_address):
+	Likewise.
+	* sysdeps/mips/dl-machine.h (elf_machine_runtime_link_map): Likewise.
+
+	* elf/rtld.c (_dl_start): Fix one last dl_loaded.
+	* elf/dl-load.c (_dl_map_object_from_fd): Avoid definition of
+	label when it is not needed.
+	* elf/dl-close.c (_dl_close): Typo: & -> &&.
+
 2004-10-12  Jakub Jelinek  <jakub@redhat.com>
 
 	* sysdeps/generic/segfault.c: Include alloca.h and stdint.h.
diff --git a/argp/argp-fs-xinl.c b/argp/argp-fs-xinl.c
index 21f9bd9f71..3cf1f9827d 100644
--- a/argp/argp-fs-xinl.c
+++ b/argp/argp-fs-xinl.c
@@ -1,5 +1,5 @@
 /* Real definitions for extern inline functions in argp-fmtstream.h
-   Copyright (C) 1997, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <miles@gnu.ai.mit.edu>.
 
@@ -24,7 +24,7 @@
 
 #define ARGP_FS_EI
 #undef __OPTIMIZE__
-#define __OPTIMIZE__
+#define __OPTIMIZE__ 1
 #include "argp-fmtstream.h"
 
 #if 0
diff --git a/argp/argp-xinl.c b/argp/argp-xinl.c
index 2431093ea3..73177585e8 100644
--- a/argp/argp-xinl.c
+++ b/argp/argp-xinl.c
@@ -1,5 +1,5 @@
 /* Real definitions for extern inline functions in argp.h
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <miles@gnu.ai.mit.edu>.
 
@@ -31,7 +31,7 @@
 #endif
 #define ARGP_EI
 #undef __OPTIMIZE__
-#define __OPTIMIZE__
+#define __OPTIMIZE__ 1
 #include "argp.h"
 
 /* Add weak aliases.  */
diff --git a/debug/Makefile b/debug/Makefile
index aba98926da..fed60d78b5 100644
--- a/debug/Makefile
+++ b/debug/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1998, 1999, 2000, 2001, 2004 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
@@ -24,11 +24,26 @@ subdir	:= debug
 headers	:= execinfo.h
 distribute = sigcontextinfo.h register-dump.h frame.h
 
-routines := backtrace backtracesyms backtracesymsfd noophooks
+routines := backtrace backtracesyms backtracesymsfd noophooks \
+	    memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
+	    strcat_chk strcpy_chk strncat_chk strncpy_chk \
+	    sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
+	    printf_chk fprintf_chk vprintf_chk vfprintf_chk \
+	    gets_chk chk_fail readonly-area
 
 CFLAGS-backtrace.c = -fno-omit-frame-pointer
-
-tests = backtrace-tst
+CFLAGS-sprintf_chk.c = -D_IO_MTSAFE_IO
+CFLAGS-snprintf_chk.c = -D_IO_MTSAFE_IO
+CFLAGS-vsprintf_chk.c = -D_IO_MTSAFE_IO
+CFLAGS-vsnprintf_chk.c = -D_IO_MTSAFE_IO
+CFLAGS-printf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-fprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-vprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions) 
+CFLAGS-vfprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-gets_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+
+tests = backtrace-tst tst-chk1 tst-chk2 tst-chk3 \
+	test-strcpy_chk test-stpcpy_chk
 
 extra-libs = libSegFault libpcprofile
 extra-libs-others = $(extra-libs)
diff --git a/debug/Versions b/debug/Versions
index c2b6396d82..07d6fbb830 100644
--- a/debug/Versions
+++ b/debug/Versions
@@ -10,4 +10,12 @@ libc {
     # These are to support some gcc features.
     __cyg_profile_func_enter; __cyg_profile_func_exit;
   }
+  GLIBC_2.3.4 {
+    __chk_fail;
+    __memcpy_chk; __memmove_chk; __mempcpy_chk; __memset_chk; __stpcpy_chk;
+    __strcat_chk; __strcpy_chk; __strncat_chk; __strncpy_chk;
+    __sprintf_chk; __vsprintf_chk; __snprintf_chk; __vsnprintf_chk;
+    __printf_chk; __fprintf_chk; __vprintf_chk; __vfprintf_chk;
+    __gets_chk;
+  }
 }
diff --git a/debug/chk_fail.c b/debug/chk_fail.c
new file mode 100644
index 0000000000..48848fbe35
--- /dev/null
+++ b/debug/chk_fail.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <abort-instr.h>
+
+
+void
+__attribute__ ((noreturn))
+__chk_fail (void)
+{
+  while (1)
+    {
+      /* This will leave a nice backtrace.  */
+      abort ();
+#ifdef ABORT_INSTRUCTION
+      ABORT_INSTRUCTION;
+#endif
+      _exit (127);
+    }
+}
+libc_hidden_def (__chk_fail)
diff --git a/debug/fprintf_chk.c b/debug/fprintf_chk.c
new file mode 100644
index 0000000000..77508b902e
--- /dev/null
+++ b/debug/fprintf_chk.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+   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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "../libio/libioP.h"
+
+
+/* Write formatted output to FP from the format string FORMAT.  */
+int
+__fprintf_chk (FILE *fp, int flag, const char *format, ...)
+{
+  va_list ap;
+  int done;
+
+  _IO_acquire_lock (fp);
+  if (flag > 0)
+    fp->_flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
+
+  va_start (ap, format);
+  done = vfprintf (fp, format, ap);
+  va_end (ap);
+
+  if (flag > 0)
+    fp->_flags2 &= ~_IO_FLAGS2_CHECK_PERCENT_N;
+  _IO_release_lock (fp);
+
+  return done;
+}
diff --git a/debug/gets_chk.c b/debug/gets_chk.c
new file mode 100644
index 0000000000..3715a39672
--- /dev/null
+++ b/debug/gets_chk.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 1993, 1996, 1997, 1998, 2002, 2003, 2004
+   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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.
+
+   As a special exception, if you link the code in this file with
+   files compiled with a GNU compiler to produce an executable,
+   that does not cause the resulting executable to be covered by
+   the GNU Lesser General Public License.  This exception does not
+   however invalidate any other reasons why the executable file
+   might be covered by the GNU Lesser General Public License.
+   This exception applies to code released by its copyright holders
+   in files containing the exception.  */
+
+#include "../libio/libioP.h"
+#include <limits.h>
+
+char *
+__gets_chk (char *buf, size_t size)
+{
+  _IO_size_t count;
+  int ch;
+  char *retval;
+
+  if (size == 0)
+    __chk_fail ();
+
+  _IO_acquire_lock (_IO_stdin);
+  ch = _IO_getc_unlocked (_IO_stdin);
+  if (ch == EOF)
+    {
+      retval = NULL;
+      goto unlock_return;
+    }
+  if (ch == '\n')
+    count = 0;
+  else
+    {
+      /* This is very tricky since a file descriptor may be in the
+	 non-blocking mode. The error flag doesn't mean much in this
+	 case. We return an error only when there is a new error. */
+      int old_error = _IO_stdin->_IO_file_flags & _IO_ERR_SEEN;
+      _IO_stdin->_IO_file_flags &= ~_IO_ERR_SEEN;
+      buf[0] = (char) ch;
+      count = INTUSE(_IO_getline) (_IO_stdin, buf + 1, size - 1, '\n', 0) + 1;
+      if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN)
+	{
+	  retval = NULL;
+	  goto unlock_return;
+	}
+      else
+	_IO_stdin->_IO_file_flags |= old_error;
+    }
+  if (count >= size)
+    __chk_fail ();
+  buf[count] = 0;
+  retval = buf;
+unlock_return:
+  _IO_release_lock (_IO_stdin);
+  return retval;
+}
+
+link_warning (__gets_chk, "the `gets' function is dangerous and should not be used.")
diff --git a/debug/printf_chk.c b/debug/printf_chk.c
new file mode 100644
index 0000000000..d2b387323d
--- /dev/null
+++ b/debug/printf_chk.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+   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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "../libio/libioP.h"
+
+
+/* Write formatted output to stdout from the format string FORMAT.  */
+int
+__printf_chk (int flag, const char *format, ...)
+{
+  va_list ap;
+  int done;
+
+  _IO_acquire_lock (stdout);
+  if (flag > 0)
+    stdout->_flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
+
+  va_start (ap, format);
+  done = vfprintf (stdout, format, ap);
+  va_end (ap);
+
+  if (flag > 0)
+    stdout->_flags2 &= ~_IO_FLAGS2_CHECK_PERCENT_N;
+  _IO_release_lock (stdout);
+
+  return done;
+}
diff --git a/debug/snprintf_chk.c b/debug/snprintf_chk.c
new file mode 100644
index 0000000000..5a77afef29
--- /dev/null
+++ b/debug/snprintf_chk.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991, 1995, 1997, 1998, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+
+/* Write formatted output into S, according to the format
+   string FORMAT, writing no more than MAXLEN characters.  */
+/* VARARGS5 */
+int
+__snprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
+		const char *format, ...)
+{
+  va_list arg;
+  int done;
+
+  va_start (arg, format);
+  done = __vsnprintf_chk (s, maxlen, flags, slen, format, arg);
+  va_end (arg);
+
+  return done;
+}
diff --git a/debug/sprintf_chk.c b/debug/sprintf_chk.c
new file mode 100644
index 0000000000..d141633b9f
--- /dev/null
+++ b/debug/sprintf_chk.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991,1995,1997,1998,2002,2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+/* Write formatted output into S, according to the format string FORMAT.  */
+/* VARARGS4 */
+int
+__sprintf_chk (char *s, int flags, size_t slen, const char *format, ...)
+{
+  va_list arg;
+  int done;
+
+  va_start (arg, format);
+  done = __vsprintf_chk (s, flags, slen, format, arg);
+  va_end (arg);
+
+  return done;
+}
diff --git a/debug/test-stpcpy_chk.c b/debug/test-stpcpy_chk.c
new file mode 100644
index 0000000000..d717ca7363
--- /dev/null
+++ b/debug/test-stpcpy_chk.c
@@ -0,0 +1,46 @@
+/* Test and measure stpcpy checking functions.
+   Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define STRCPY_RESULT(dst, len) ((dst) + (len))
+#define TEST_MAIN
+#include "../string/test-string.h"
+
+extern void __attribute__ ((noreturn)) __chk_fail (void);
+char *simple_stpcpy_chk (char *, const char *, size_t);
+extern char *normal_stpcpy (char *, const char *, size_t)
+  __asm ("stpcpy");
+extern char *__stpcpy_chk (char *, const char *, size_t);
+
+IMPL (simple_stpcpy_chk, 0)
+IMPL (normal_stpcpy, 1)
+IMPL (__stpcpy_chk, 2)
+
+char *
+simple_stpcpy_chk (char *dst, const char *src, size_t len)
+{
+  if (! len)
+    __chk_fail ();
+  while ((*dst++ = *src++) != '\0')
+    if (--len == 0)
+      __chk_fail ();
+  return dst - 1;
+}
+
+#include "test-strcpy_chk.c"
diff --git a/debug/test-strcpy_chk.c b/debug/test-strcpy_chk.c
new file mode 100644
index 0000000000..4c61f4fb43
--- /dev/null
+++ b/debug/test-strcpy_chk.c
@@ -0,0 +1,370 @@
+/* Test and measure __strcpy_chk functions.
+   Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef STRCPY_RESULT
+# define STRCPY_RESULT(dst, len) dst
+# define TEST_MAIN
+# include "../string/test-string.h"
+
+extern void __attribute__ ((noreturn)) __chk_fail (void);
+char *simple_strcpy_chk (char *, const char *, size_t);
+extern char *normal_strcpy (char *, const char *, size_t)
+  __asm ("strcpy");
+extern char *__strcpy_chk (char *, const char *, size_t);
+
+IMPL (simple_strcpy_chk, 0)
+IMPL (normal_strcpy, 1)
+IMPL (__strcpy_chk, 2)
+
+char *
+simple_strcpy_chk (char *dst, const char *src, size_t len)
+{
+  char *ret = dst;
+  if (! len)
+    __chk_fail ();
+  while ((*dst++ = *src++) != '\0')
+    if (--len == 0)
+      __chk_fail ();
+  return ret;
+}
+#endif
+
+#include <setjmp.h>
+#include <signal.h>
+
+volatile int chk_fail_ok;
+jmp_buf chk_fail_buf;
+
+static void
+handler (int sig)
+{
+  if (chk_fail_ok)
+    {
+      chk_fail_ok = 0;
+      longjmp (chk_fail_buf, 1);
+    }
+  else
+    _exit (127);
+}
+
+typedef char *(*proto_t) (char *, const char *, size_t);
+
+static void
+do_one_test (impl_t *impl, char *dst, const char *src,
+	     size_t len, size_t dlen)
+{
+  char *res;
+  if (dlen <= len)
+    {
+      if (impl->test == 1)
+	return;
+
+      chk_fail_ok = 1;
+      if (setjmp (chk_fail_buf) == 0)
+	{
+	  res = CALL (impl, dst, src, dlen);
+	  error (0, 0, "Function %s (%zd; %zd) did not __chk_fail",
+	  	 impl->name, len, dlen);
+	  chk_fail_ok = 0;
+	  ret = 1;
+	}
+      return;
+    }
+  else
+    res = CALL (impl, dst, src, dlen);
+
+  if (res != STRCPY_RESULT (dst, len))
+    {
+      error (0, 0, "Wrong result in function %s %p %p", impl->name,
+	     res, STRCPY_RESULT (dst, len));
+      ret = 1;
+      return;
+    }
+
+  if (strcmp (dst, src) != 0)
+    {
+      error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
+	     impl->name, dst, src);
+      ret = 1;
+      return;
+    }
+
+  if (HP_TIMING_AVAIL)
+    {
+      hp_timing_t start __attribute ((unused));
+      hp_timing_t stop __attribute ((unused));;
+      hp_timing_t best_time = ~ (hp_timing_t) 0;
+      size_t i;
+
+      for (i = 0; i < 32; ++i)
+	{
+	  HP_TIMING_NOW (start);
+	  CALL (impl, dst, src, dlen);
+	  HP_TIMING_NOW (stop);
+	  HP_TIMING_BEST (best_time, start, stop);
+	}
+
+      printf ("\t%zd", (size_t) best_time);
+    }
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char)
+{
+  size_t i;
+  char *s1, *s2;
+
+  align1 &= 7;
+  if (align1 + len >= page_size)
+    return;
+
+  align2 &= 7;
+  if (align2 + len >= page_size)
+    return;
+
+  s1 = buf1 + align1;
+  s2 = buf2 + align2;
+
+  for (i = 0; i < len; i++)
+    s1[i] = 32 + 23 * i % (max_char - 32);
+  s1[len] = 0;
+
+  if (HP_TIMING_AVAIL && dlen > len)
+    printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
+
+  FOR_EACH_IMPL (impl, 0)
+    do_one_test (impl, s2, s1, len, dlen);
+
+  if (HP_TIMING_AVAIL && dlen > len)
+    putchar ('\n');
+}
+
+static void
+do_random_tests (void)
+{
+  size_t i, j, n, align1, align2, len, dlen;
+  unsigned char *p1 = buf1 + page_size - 512;
+  unsigned char *p2 = buf2 + page_size - 512;
+  unsigned char *res;
+
+  for (n = 0; n < ITERATIONS; n++)
+    {
+      align1 = random () & 31;
+      if (random () & 1)
+	align2 = random () & 31;
+      else
+	align2 = align1 + (random () & 24);
+      len = random () & 511;
+      j = align1;
+      if (align2 > j)
+	j = align2;
+      if (len + j >= 511)
+	len = 510 - j - (random () & 7);
+      j = len + align1 + 64;
+      if (j > 512)
+	j = 512;
+      for (i = 0; i < j; i++)
+	{
+	  if (i == len + align1)
+	    p1[i] = 0;
+	  else
+	    {
+	      p1[i] = random () & 255;
+	      if (i >= align1 && i < len + align1 && !p1[i])
+		p1[i] = (random () & 127) + 3;
+	    }
+	}
+
+      switch (random () & 7)
+	{
+	case 0:
+	  dlen = len - (random () & 31);
+	  if (dlen > len)
+	    dlen = len;
+	  break;
+	case 1:
+	  dlen = (size_t) -1;
+	  break;
+	case 2:
+	  dlen = len + 1 + (random () & 65535);
+	  break;
+	case 3:
+	  dlen = len + 1 + (random () & 255);
+	  break;
+	case 4:
+	  dlen = len + 1 + (random () & 31);
+	  break;
+	case 5:
+	  dlen = len + 1 + (random () & 7);
+	  break;
+	case 6:
+	  dlen = len + 1 + (random () & 3);
+	  break;
+	default:
+	  dlen = len + 1;
+	  break;
+	}
+
+      FOR_EACH_IMPL (impl, 1)
+	{
+	  if (dlen <= len)
+	    {
+	      if (impl->test != 1)
+		{
+		  chk_fail_ok = 1;
+		  if (setjmp (chk_fail_buf) == 0)
+		    {
+		      res = CALL (impl, p2 + align2, p1 + align1, dlen);
+		      error (0, 0, "Iteration %zd - did not __chk_fail", n);
+		      chk_fail_ok = 0;
+		      ret = 1;
+		    }
+		}
+	      continue;
+	    }
+	  memset (p2 - 64, '\1', 512 + 64);
+	  res = CALL (impl, p2 + align2, p1 + align1, dlen);
+	  if (res != STRCPY_RESULT (p2 + align2, len))
+	    {
+	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
+		     n, impl->name, align1, align2, len, res,
+		     STRCPY_RESULT (p2 + align2, len));
+	      ret = 1;
+	    }
+	  for (j = 0; j < align2 + 64; ++j)
+	    {
+	      if (p2[j - 64] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  for (j = align2 + len + 1; j < 512; ++j)
+	    {
+	      if (p2[j] != '\1')
+		{
+		  error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
+			 n, impl->name, align1, align2, len);
+		  ret = 1;
+		  break;
+		}
+	    }
+	  if (memcmp (p1 + align1, p2 + align2, len + 1))
+	    {
+	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+		     n, impl->name, align1, align2, len);
+	      ret = 1;
+	    }
+	}
+    }
+}
+
+int
+test_main (void)
+{
+  size_t i;
+
+  struct sigaction sa;
+  sa.sa_handler = handler;
+  sa.sa_flags = 0;
+  sigemptyset (&sa.sa_mask);
+
+  sigaction (SIGABRT, &sa, NULL);
+
+  test_init ();
+
+  printf ("%23s", "");
+  FOR_EACH_IMPL (impl, 0)
+    printf ("\t%s", impl->name);
+  putchar ('\n');
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, i + 1, 127);
+      do_test (0, 0, i, i + 1, 255);
+      do_test (0, i, i, i + 1, 127);
+      do_test (i, 0, i, i + 1, 255);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, (8 << i) + 1, 127);
+      do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127);
+      do_test (2 * i, i, (8 << i), (8 << i) + 1, 255);
+      do_test (i, i, (8 << i), (8 << i) + 1, 127);
+      do_test (i, i, (8 << i), (8 << i) + 1, 255);
+    }
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, i + 256, 127);
+      do_test (0, 0, i, i + 256, 255);
+      do_test (0, i, i, i + 256, 127);
+      do_test (i, 0, i, i + 256, 255);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, (8 << i) + 256, 127);
+      do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127);
+      do_test (2 * i, i, (8 << i), (8 << i) + 256, 255);
+      do_test (i, i, (8 << i), (8 << i) + 256, 127);
+      do_test (i, i, (8 << i), (8 << i) + 256, 255);
+    }
+
+  for (i = 0; i < 16; ++i)
+    {
+      do_test (0, 0, i, i, 127);
+      do_test (0, 0, i, i + 2, 255);
+      do_test (0, i, i, i + 3, 127);
+      do_test (i, 0, i, i + 4, 255);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (0, 0, 8 << i, (8 << i) - 15, 127);
+      do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127);
+    }
+
+  for (i = 1; i < 8; ++i)
+    {
+      do_test (i, 2 * i, (8 << i), (8 << i) + i, 127);
+      do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255);
+      do_test (i, i, (8 << i), (8 << i) + i + 2, 127);
+      do_test (i, i, (8 << i), (8 << i) + i + 3, 255);
+    }
+
+  do_random_tests ();
+  return ret;
+}
+
+#include "../test-skeleton.c"
diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
new file mode 100644
index 0000000000..639da3847c
--- /dev/null
+++ b/debug/tst-chk1.c
@@ -0,0 +1,466 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+char *temp_filename;
+static void do_prepare (void);
+static int do_test (void);
+#define PREPARE(argc, argv) do_prepare ()
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+static void
+do_prepare (void)
+{
+  int temp_fd = create_temp_file ("tst-chk1.", &temp_filename);
+  if (temp_fd == -1)
+    {
+      printf ("cannot create temporary file: %m\n");
+      exit (1);
+    }
+
+  const char *strs = "abcdefgh\nABCDEFGHI\nabcdefghij\nABCDEFGHIJ";
+  if (write (temp_fd, strs, strlen (strs)) != strlen (strs))
+    {
+      puts ("could not write test strings into file");
+      unlink (temp_filename);
+      exit (1);
+    }
+}
+
+volatile int chk_fail_ok;
+jmp_buf chk_fail_buf;
+
+static void
+handler (int sig)
+{
+  if (chk_fail_ok)
+    {
+      chk_fail_ok = 0;
+      longjmp (chk_fail_buf, 1);
+    }
+  else
+    _exit (127);
+}
+
+char buf[10];
+volatile size_t l0;
+volatile char *p;
+const char *str1 = "JIHGFEDCBA";
+const char *str2 = "F";
+const char *str3 = "%s%n%s%n";
+const char *str4 = "Hello, ";
+const char *str5 = "World!\n";
+char buf2[10] = "%s";
+int num1 = 67;
+int num2 = 987654;
+
+#define FAIL() \
+  do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0)
+#define CHK_FAIL_START \
+  chk_fail_ok = 1;				\
+  if (! setjmp (chk_fail_buf))			\
+    {
+#define CHK_FAIL_END \
+      chk_fail_ok = 0;				\
+      FAIL ();					\
+      ret = 1;					\
+    }
+#if __USE_FORTIFY_LEVEL >= 2
+#define CHK_FAIL2_START CHK_FAIL_START
+#define CHK_FAIL2_END CHK_FAIL_END
+#else
+#define CHK_FAIL2_START
+#define CHK_FAIL2_END
+#endif
+
+static int
+do_test (void)
+{
+  int ret = 0;
+  struct sigaction sa;
+  sa.sa_handler = handler;
+  sa.sa_flags = 0;
+  sigemptyset (&sa.sa_mask);
+
+  sigaction (SIGABRT, &sa, NULL);
+
+  struct A { char buf1[9]; char buf2[1]; } a;
+
+  printf ("Test checking routines at fortify level %d\n",
+#ifdef __USE_FORTIFY_LEVEL
+	  (int) __USE_FORTIFY_LEVEL
+#else
+	  0
+#endif
+	  );
+
+  /* These ops can be done without runtime checking of object size.  */
+  memcpy (buf, "abcdefghij", 10);
+  memmove (buf + 1, buf, 9);
+  if (memcmp (buf, "aabcdefghi", 10))
+    FAIL ();
+
+  if (mempcpy (buf + 5, "abcde", 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
+    FAIL ();
+
+  memset (buf + 8, 'j', 2);
+  if (memcmp (buf, "aabcdabcjj", 10))
+    FAIL ();
+
+  strcpy (buf + 4, "EDCBA");
+  if (memcmp (buf, "aabcEDCBA", 10))
+    FAIL ();
+
+  if (stpcpy (buf + 8, "F") != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
+    FAIL ();
+
+  strncpy (buf + 6, "X", 4);
+  if (memcmp (buf, "aabcEDX\0\0", 10))
+    FAIL ();
+
+  if (sprintf (buf + 7, "%s", "67") != 2 || memcmp (buf, "aabcEDX67", 10))
+    FAIL ();
+
+  if (snprintf (buf + 7, 3, "%s", "987654") != 6
+      || memcmp (buf, "aabcEDX98", 10))
+    FAIL ();
+
+  /* These ops need runtime checking, but shouldn't __chk_fail.  */
+  memcpy (buf, "abcdefghij", l0 + 10);
+  memmove (buf + 1, buf, l0 + 9);
+  if (memcmp (buf, "aabcdefghi", 10))
+    FAIL ();
+
+  if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
+    FAIL ();
+
+  memset (buf + 8, 'j', l0 + 2);
+  if (memcmp (buf, "aabcdabcjj", 10))
+    FAIL ();
+
+  strcpy (buf + 4, str1 + 5);
+  if (memcmp (buf, "aabcEDCBA", 10))
+    FAIL ();
+
+  if (stpcpy (buf + 8, str2) != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
+    FAIL ();
+
+  strncpy (buf + 6, "X", l0 + 4);
+  if (memcmp (buf, "aabcEDX\0\0", 10))
+    FAIL ();
+
+  if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEDX67", 10))
+    FAIL ();
+
+  if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEDX98", 10))
+    FAIL ();
+
+  buf[l0 + 8] = '\0';
+  strcat (buf, "A");
+  if (memcmp (buf, "aabcEDX9A", 10))
+    FAIL ();
+
+  buf[l0 + 7] = '\0';
+  strncat (buf, "ZYXWV", l0 + 2);
+  if (memcmp (buf, "aabcEDXZY", 10))
+    FAIL ();
+
+  memcpy (a.buf1, "abcdefghij", l0 + 10);
+  memmove (a.buf1 + 1, a.buf1, l0 + 9);
+  if (memcmp (a.buf1, "aabcdefghi", 10))
+    FAIL ();
+
+  if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
+      || memcmp (a.buf1, "aabcdabcde", 10))
+    FAIL ();
+
+  memset (a.buf1 + 8, 'j', l0 + 2);
+  if (memcmp (a.buf1, "aabcdabcjj", 10))
+    FAIL ();
+
+#if __USE_FORTIFY_LEVEL < 2
+  /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
+     and sufficient GCC support, as the string operations overflow
+     from a.buf1 into a.buf2.  */
+  strcpy (a.buf1 + 4, str1 + 5);
+  if (memcmp (a.buf1, "aabcEDCBA", 10))
+    FAIL ();
+
+  if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9 || memcmp (a.buf1, "aabcEDCBF", 10))
+    FAIL ();
+
+  strncpy (a.buf1 + 6, "X", l0 + 4);
+  if (memcmp (a.buf1, "aabcEDX\0\0", 10))
+    FAIL ();
+
+  if (sprintf (a.buf1 + 7, "%d", num1) != 2 || memcmp (a.buf1, "aabcEDX67", 10))
+    FAIL ();
+
+  if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6
+      || memcmp (a.buf1, "aabcEDX98", 10))
+    FAIL ();
+
+  a.buf1[l0 + 8] = '\0';
+  strcat (a.buf1, "A");
+  if (memcmp (a.buf1, "aabcEDX9A", 10))
+    FAIL ();
+
+  a.buf1[l0 + 7] = '\0';
+  strncat (a.buf1, "ZYXWV", l0 + 2);
+  if (memcmp (a.buf1, "aabcEDXZY", 10))
+    FAIL ();
+
+#endif
+
+#if __USE_FORTIFY_LEVEL >= 1
+  /* Now check if all buffer overflows are caught at runtime.  */
+
+  CHK_FAIL_START
+  memcpy (buf + 1, "abcdefghij", l0 + 10);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  memmove (buf + 2, buf + 1, l0 + 9);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  p = mempcpy (buf + 6, "abcde", l0 + 5);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  memset (buf + 9, 'j', l0 + 2);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  strcpy (buf + 5, str1 + 5);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  p = stpcpy (buf + 9, str2);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  strncpy (buf + 7, "X", l0 + 4);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  sprintf (buf + 8, "%d", num1);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  snprintf (buf + 8, l0 + 3, "%d", num2);
+  CHK_FAIL_END
+
+  memcpy (buf, str1 + 2, l0 + 9);
+  CHK_FAIL_START
+  strcat (buf, "AB");
+  CHK_FAIL_END
+
+  memcpy (buf, str1 + 3, l0 + 8);
+  CHK_FAIL_START
+  strncat (buf, "ZYXWV", l0 + 3);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  memcpy (a.buf1 + 1, "abcdefghij", l0 + 10);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  p = mempcpy (a.buf1 + 6, "abcde", l0 + 5);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  memset (a.buf1 + 9, 'j', l0 + 2);
+  CHK_FAIL_END
+
+#if __USE_FORTIFY_LEVEL >= 2
+# define O 0
+#else
+# define O 1
+#endif
+
+  CHK_FAIL_START
+  strcpy (a.buf1 + (O + 4), str1 + 5);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  p = stpcpy (a.buf1 + (O + 8), str2);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  strncpy (a.buf1 + (O + 6), "X", l0 + 4);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  sprintf (a.buf1 + (O + 7), "%d", num1);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2);
+  CHK_FAIL_END
+
+  memcpy (a.buf1, str1 + (3 - O), l0 + 8 + O);
+  CHK_FAIL_START
+  strcat (a.buf1, "AB");
+  CHK_FAIL_END
+
+  memcpy (a.buf1, str1 + (4 - O), l0 + 7 + O);
+  CHK_FAIL_START
+  strncat (a.buf1, "ZYXWV", l0 + 3);
+  CHK_FAIL_END
+#endif
+
+  /* Now checks for %n protection.  */
+
+  /* Constant literals passed directly are always ok
+     (even with warnings about possible bugs from GCC).  */
+  int n1, n2;
+  if (sprintf (buf, "%s%n%s%n", str2, &n1, str2, &n2) != 2
+      || n1 != 1 || n2 != 2)
+    FAIL ();
+
+  /* In this case the format string is not known at compile time,
+     but resides in read-only memory, so is ok.  */
+  if (snprintf (buf, 4, str3, str2, &n1, str2, &n2) != 2
+      || n1 != 1 || n2 != 2)
+    FAIL ();
+
+  strcpy (buf2 + 2, "%n%s%n");
+  /* When the format string is writable and contains %n,
+     with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
+  CHK_FAIL2_START
+  if (sprintf (buf, buf2, str2, &n1, str2, &n1) != 2)
+    FAIL ();
+  CHK_FAIL2_END
+
+  CHK_FAIL2_START
+  if (snprintf (buf, 3, buf2, str2, &n1, str2, &n1) != 2)
+    FAIL ();
+  CHK_FAIL2_END
+
+  /* But if there is no %n, even writable format string
+     should work.  */
+  buf2[6] = '\0';
+  if (sprintf (buf, buf2 + 4, str2) != 1)
+    FAIL ();
+
+  /* Constant literals passed directly are always ok
+     (even with warnings about possible bugs from GCC).  */
+  if (printf ("%s%n%s%n", str4, &n1, str5, &n2) != 14
+      || n1 != 7 || n2 != 14)
+    FAIL ();
+
+  /* In this case the format string is not known at compile time,
+     but resides in read-only memory, so is ok.  */
+  if (printf (str3, str4, &n1, str5, &n2) != 14
+      || n1 != 7 || n2 != 14)
+    FAIL ();
+
+  strcpy (buf2 + 2, "%n%s%n");
+  /* When the format string is writable and contains %n,
+     with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
+  CHK_FAIL2_START
+  if (printf (buf2, str4, &n1, str5, &n1) != 14)
+    FAIL ();
+  CHK_FAIL2_END
+
+  /* But if there is no %n, even writable format string
+     should work.  */
+  buf2[6] = '\0';
+  if (printf (buf2 + 4, str5) != 7)
+    FAIL ();
+
+  FILE *fp = stdout;
+
+  /* Constant literals passed directly are always ok
+     (even with warnings about possible bugs from GCC).  */
+  if (fprintf (fp, "%s%n%s%n", str4, &n1, str5, &n2) != 14
+      || n1 != 7 || n2 != 14)
+    FAIL ();
+
+  /* In this case the format string is not known at compile time,
+     but resides in read-only memory, so is ok.  */
+  if (fprintf (fp, str3, str4, &n1, str5, &n2) != 14
+      || n1 != 7 || n2 != 14)
+    FAIL ();
+
+  strcpy (buf2 + 2, "%n%s%n");
+  /* When the format string is writable and contains %n,
+     with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
+  CHK_FAIL2_START
+  if (fprintf (fp, buf2, str4, &n1, str5, &n1) != 14)
+    FAIL ();
+  CHK_FAIL2_END
+
+  /* But if there is no %n, even writable format string
+     should work.  */
+  buf2[6] = '\0';
+  if (fprintf (fp, buf2 + 4, str5) != 7)
+    FAIL ();
+
+  if (freopen (temp_filename, "r", stdin) == NULL)
+    {
+      puts ("could not open temporary file");
+      exit (1);
+    }
+
+  if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9))
+    FAIL ();
+  if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10))
+    FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+  CHK_FAIL_START
+  if (gets (buf) != buf)
+    FAIL ();
+  CHK_FAIL_END
+#endif
+
+  if (freopen (temp_filename, "r", stdin) == NULL)
+    {
+      puts ("could not open temporary file");
+      exit (1);
+    }
+
+  if (fseek (stdin, 9 + 10 + 11, SEEK_SET))
+    {
+      puts ("could not seek in test file");
+      exit (1);
+    }
+
+#if __USE_FORTIFY_LEVEL >= 1
+  CHK_FAIL_START
+  if (gets (buf) != buf)
+    FAIL ();
+  CHK_FAIL_END
+#endif
+
+  return ret;
+}
diff --git a/debug/tst-chk2.c b/debug/tst-chk2.c
new file mode 100644
index 0000000000..be37ce2d22
--- /dev/null
+++ b/debug/tst-chk2.c
@@ -0,0 +1,2 @@
+#define _FORTIFY_SOURCE 1
+#include "tst-chk1.c"
diff --git a/debug/tst-chk3.c b/debug/tst-chk3.c
new file mode 100644
index 0000000000..38b8e4fb36
--- /dev/null
+++ b/debug/tst-chk3.c
@@ -0,0 +1,2 @@
+#define _FORTIFY_SOURCE 2
+#include "tst-chk1.c"
diff --git a/debug/vfprintf_chk.c b/debug/vfprintf_chk.c
new file mode 100644
index 0000000000..a9e107d8e5
--- /dev/null
+++ b/debug/vfprintf_chk.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+   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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "../libio/libioP.h"
+
+
+/* Write formatted output to FP from the format string FORMAT.  */
+int
+__vfprintf_chk (FILE *fp, int flag, const char *format, va_list ap)
+{
+  int done;
+
+  _IO_acquire_lock (fp);
+  if (flag > 0)
+    fp->_flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
+
+  done = vfprintf (fp, format, ap);
+
+  if (flag > 0)
+    fp->_flags2 &= ~_IO_FLAGS2_CHECK_PERCENT_N;
+  _IO_release_lock (fp);
+
+  return done;
+}
diff --git a/debug/vprintf_chk.c b/debug/vprintf_chk.c
new file mode 100644
index 0000000000..f477f15411
--- /dev/null
+++ b/debug/vprintf_chk.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+   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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "../libio/libioP.h"
+
+
+/* Write formatted output to stdout from the format string FORMAT.  */
+int
+__vprintf_chk (int flag, const char *format, va_list ap)
+{
+  int done;
+
+  _IO_acquire_lock (stdout);
+  if (flag > 0)
+    stdout->_flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
+
+  done = vfprintf (stdout, format, ap);
+
+  if (flag > 0)
+    stdout->_flags2 &= ~_IO_FLAGS2_CHECK_PERCENT_N;
+  _IO_release_lock (stdout);
+
+  return done;
+}
diff --git a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c
new file mode 100644
index 0000000000..850cd5af5a
--- /dev/null
+++ b/debug/vsnprintf_chk.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 1991, 1995, 1997, 1998, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "../libio/libioP.h"
+#include "../libio/strfile.h"
+
+extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
+
+/* Write formatted output into S, according to the format
+   string FORMAT, writing no more than MAXLEN characters.  */
+/* VARARGS5 */
+int
+__vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
+		 const char *format, va_list args)
+{
+  /* XXX Maybe for less strict version do not fail immediately.
+     Though, maxlen is supposed to be the size of buffer pointed
+     to by s, so a conforming program can't pass such maxlen
+     to *snprintf.  */
+  if (__builtin_expect (slen < maxlen, 0))
+    __chk_fail ();
+
+  _IO_strnfile sf;
+  int ret;
+#ifdef _IO_MTSAFE_IO
+  sf.f._sbf._f._lock = NULL;
+#endif
+
+  /* We need to handle the special case where MAXLEN is 0.  Use the
+     overflow buffer right from the start.  */
+  if (maxlen == 0)
+    {
+      s = sf.overflow_buf;
+      maxlen = sizeof (sf.overflow_buf);
+    }
+
+  _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
+  _IO_JUMPS ((struct _IO_FILE_plus *) &sf.f._sbf) = &_IO_strn_jumps;
+  s[0] = '\0';
+
+  /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
+     can only come from read-only format strings.  */
+  if (flags > 0)
+    sf.f._sbf._f._flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
+
+  _IO_str_init_static_internal (&sf.f, s, maxlen - 1, s);
+  ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &sf.f._sbf, format, args);
+
+  if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
+    *sf.f._sbf._f._IO_write_ptr = '\0';
+  return ret;
+}
+libc_hidden_def (__vsnprintf_chk)
diff --git a/debug/vsprintf_chk.c b/debug/vsprintf_chk.c
new file mode 100644
index 0000000000..83383286da
--- /dev/null
+++ b/debug/vsprintf_chk.c
@@ -0,0 +1,91 @@
+/* Copyright (C) 1994, 1997, 1999-2003, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "../libio/libioP.h"
+#include "../libio/strfile.h"
+
+
+static int _IO_str_chk_overflow (_IO_FILE *fp, int c) __THROW;
+
+static int
+_IO_str_chk_overflow (fp, c)
+     _IO_FILE *fp;
+     int c;
+{
+  /* When we come to here this means the user supplied buffer is
+     filled.  */
+  __chk_fail ();
+}
+
+
+static const struct _IO_jump_t _IO_str_chk_jumps =
+{
+  JUMP_INIT_DUMMY,
+  JUMP_INIT(finish, _IO_str_finish),
+  JUMP_INIT(overflow, _IO_str_chk_overflow),
+  JUMP_INIT(underflow, INTUSE(_IO_str_underflow)),
+  JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
+  JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)),
+  JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)),
+  JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
+  JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)),
+  JUMP_INIT(seekpos, _IO_default_seekpos),
+  JUMP_INIT(setbuf, _IO_default_setbuf),
+  JUMP_INIT(sync, _IO_default_sync),
+  JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)),
+  JUMP_INIT(read, _IO_default_read),
+  JUMP_INIT(write, _IO_default_write),
+  JUMP_INIT(seek, _IO_default_seek),
+  JUMP_INIT(close, _IO_default_close),
+  JUMP_INIT(stat, _IO_default_stat),
+  JUMP_INIT(showmanyc, _IO_default_showmanyc),
+  JUMP_INIT(imbue, _IO_default_imbue)
+};
+
+
+int
+__vsprintf_chk (char *s, int flags, size_t slen, const char *format,
+		va_list args)
+{
+  _IO_strfile f;
+  int ret;
+#ifdef _IO_MTSAFE_IO
+  f._sbf._f._lock = NULL;
+#endif
+
+  if (slen == 0)
+    __chk_fail ();
+
+  _IO_no_init (&f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
+  _IO_JUMPS ((struct _IO_FILE_plus *) &f._sbf) = &_IO_str_chk_jumps;
+  s[0] = '\0';
+  _IO_str_init_static_internal (&f, s, slen - 1, s);
+
+  /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
+     can only come from read-only format strings.  */
+  if (flags > 0)
+    f._sbf._f._flags2 |= _IO_FLAGS2_CHECK_PERCENT_N;
+
+  ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &f._sbf, format, args);
+
+  *f._sbf._f._IO_write_ptr = '\0';
+  return ret;
+}
+libc_hidden_def (__vsprintf_chk)
diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c
index 4ec2ebcbb4..adb85e6753 100644
--- a/elf/dl-minimal.c
+++ b/elf/dl-minimal.c
@@ -354,6 +354,13 @@ __strsep (char **stringp, const char *delim)
 weak_alias (__strsep, strsep)
 strong_alias (__strsep, __strsep_g)
 
+void
+__attribute__ ((noreturn))
+__chk_fail (void)
+{
+  _exit (127);
+}
+rtld_hidden_def (__chk_fail)
 
 /* The '_itoa_lower_digits' variable in libc.so is able to handle bases
    up to 36.  We don't need this here.  */
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 939c3e1144..d97f635a5d 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -1,5 +1,5 @@
 # This file is updated automatically by Makefile.
 glibc-branch := fedora
 glibc-base := HEAD
-fedora-sync-date := 2004-10-14 05:48 UTC
-fedora-sync-tag := fedora-glibc-20041014T0548
+fedora-sync-date := 2004-10-18 09:40 UTC
+fedora-sync-tag := fedora-glibc-20041018T0940
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index b32811dd1f..7b263153e0 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 68
+%define glibcrelease 69
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define prelinkarches noarch
 %define nptlarches i386 i686 athlon x86_64 ia64 s390 s390x sparcv9 ppc ppc64
@@ -1239,6 +1239,10 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Mon Oct 18 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-69
+- update from CVS
+  - object size checking support (-D_FORTIFY_SOURCE={1,2})
+
 * Thu Oct 14 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-68
 - update from CVS
   - support for namespaces in the dynamic linker
diff --git a/include/bits/string3.h b/include/bits/string3.h
new file mode 100644
index 0000000000..1ddd981a90
--- /dev/null
+++ b/include/bits/string3.h
@@ -0,0 +1 @@
+#include <string/bits/string3.h>
diff --git a/include/features.h b/include/features.h
index 221b25ffe2..9940304ccb 100644
--- a/include/features.h
+++ b/include/features.h
@@ -41,6 +41,8 @@
    _GNU_SOURCE		All of the above, plus GNU extensions.
    _REENTRANT		Select additionally reentrant object.
    _THREAD_SAFE		Same as _REENTRANT, often used by other systems.
+   _FORTIFY_SOURCE	If set to numeric value > 0 additional security
+			measures are defined, according to level.
 
    The `-ansi' switch to the GNU C compiler defines __STRICT_ANSI__.
    If none of these are defined, the default is to have _SVID_SOURCE,
@@ -69,6 +71,7 @@
    __USE_MISC		Define things common to BSD and System V Unix.
    __USE_GNU		Define GNU extensions.
    __USE_REENTRANT	Define reentrant/thread-safe *_r functions.
+   __USE_FORTIFY_LEVEL	Additional security measures used, according to level.
    __FAVOR_BSD		Favor 4.3BSD things in cases of conflict.
 
    The macros `__GNU_LIBRARY__', `__GLIBC__', and `__GLIBC_MINOR__' are
@@ -101,6 +104,7 @@
 #undef	__USE_MISC
 #undef	__USE_GNU
 #undef	__USE_REENTRANT
+#undef	__USE_FORTIFY_LEVEL
 #undef	__FAVOR_BSD
 #undef	__KERNEL_STRICT_NAMES
 
@@ -113,6 +117,20 @@
 /* Always use ISO C things.  */
 #define	__USE_ANSI	1
 
+/* Convenience macros to test the versions of glibc and gcc.
+   Use them like this:
+   #if __GNUC_PREREQ (2,8)
+   ... code requiring gcc 2.8 or later ...
+   #endif
+   Note - they won't work for gcc1 or glibc1, since the _MINOR macros
+   were not defined then.  */
+#if defined __GNUC__ && defined __GNUC_MINOR__
+# define __GNUC_PREREQ(maj, min) \
+	((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define __GNUC_PREREQ(maj, min) 0
+#endif
+
 
 /* If _BSD_SOURCE was defined by the user, favor BSD over POSIX.  */
 #if defined _BSD_SOURCE && \
@@ -244,6 +262,14 @@
 # define __USE_REENTRANT	1
 #endif
 
+#if _FORTIFY_SOURCE > 0 && __GNUC_PREREQ (4, 1) && __OPTIMIZE__ > 0
+# if _FORTIFY_SOURCE == 1
+#  define __USE_FORTIFY_LEVEL 1
+# elif _FORTIFY_SOURCE > 1
+#  define __USE_FORTIFY_LEVEL 2
+# endif
+#endif
+
 /* We do support the IEC 559 math functionality, real and complex.  */
 #define __STDC_IEC_559__		1
 #define __STDC_IEC_559_COMPLEX__	1
@@ -265,20 +291,6 @@
 #define	__GLIBC__	2
 #define	__GLIBC_MINOR__	3
 
-/* Convenience macros to test the versions of glibc and gcc.
-   Use them like this:
-   #if __GNUC_PREREQ (2,8)
-   ... code requiring gcc 2.8 or later ...
-   #endif
-   Note - they won't work for gcc1 or glibc1, since the _MINOR macros
-   were not defined then.  */
-#if defined __GNUC__ && defined __GNUC_MINOR__
-# define __GNUC_PREREQ(maj, min) \
-	((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
-#else
-# define __GNUC_PREREQ(maj, min) 0
-#endif
-
 #define __GLIBC_PREREQ(maj, min) \
 	((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
 
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 9cc72b261a..e7880b6c46 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -744,6 +744,24 @@ for linking")
 # define libm_hidden_data_ver(local, name)
 #endif
 
+#if defined NOT_IN_libc && defined IS_IN_libresolv
+# define libresolv_hidden_proto(name, attrs...) hidden_proto (name, ##attrs)
+# define libresolv_hidden_def(name) hidden_def (name)
+# define libresolv_hidden_weak(name) hidden_weak (name)
+# define libresolv_hidden_ver(local, name) hidden_ver (local, name)
+# define libresolv_hidden_data_def(name) hidden_data_def (name)
+# define libresolv_hidden_data_weak(name) hidden_data_weak (name)
+# define libresolv_hidden_data_ver(local, name) hidden_data_ver (local, name)
+#else
+# define libresolv_hidden_proto(name, attrs...)
+# define libresolv_hidden_def(name)
+# define libresolv_hidden_weak(name)
+# define libresolv_hidden_ver(local, name)
+# define libresolv_hidden_data_def(name)
+# define libresolv_hidden_data_weak(name)
+# define libresolv_hidden_data_ver(local, name)
+#endif
+
 #ifdef HAVE_BUILTIN_REDIRECTION
 # define libc_hidden_builtin_proto(name, attrs...) libc_hidden_proto (name, ##attrs)
 # define libc_hidden_builtin_def(name) libc_hidden_def (name)
diff --git a/include/resolv.h b/include/resolv.h
index d62a8ff1e5..6f1c343b4a 100644
--- a/include/resolv.h
+++ b/include/resolv.h
@@ -60,6 +60,44 @@ int __libc_res_nsend (res_state, const u_char *, int, u_char *, int,
 		      u_char **)
   attribute_hidden;
 
+libresolv_hidden_proto (_sethtent)
+libresolv_hidden_proto (_gethtent)
+libresolv_hidden_proto (_gethtbyaddr)
+libresolv_hidden_proto (_gethtbyname2)
+libresolv_hidden_proto (__dn_expand)
+libresolv_hidden_proto (__dn_comp)
+libresolv_hidden_proto (__dn_skipname)
+libresolv_hidden_proto (__res_hnok)
+libresolv_hidden_proto (__res_dnok)
+libresolv_hidden_proto (__putlong)
+libresolv_hidden_proto (__putshort)
+libresolv_hidden_proto (__p_cdnname)
+libresolv_hidden_proto (__p_fqnname)
+libresolv_hidden_proto (__p_option)
+libresolv_hidden_proto (__sym_ntos)
+libresolv_hidden_proto (__p_rcode)
+libresolv_hidden_proto (__p_class)
+libresolv_hidden_proto (__p_type)
+libresolv_hidden_proto (__loc_ntoa)
+libresolv_hidden_proto (__fp_nquery)
+libresolv_hidden_proto (__fp_query)
+libresolv_hidden_proto (__hostalias)
+libresolv_hidden_proto (__res_nmkquery)
+libresolv_hidden_proto (__libc_res_nquery)
+libresolv_hidden_proto (__res_nquery)
+libresolv_hidden_proto (__res_nquerydomain)
+libresolv_hidden_proto (__res_hostalias)
+libresolv_hidden_proto (__libc_res_nsearch)
+libresolv_hidden_proto (__res_nsearch)
+libresolv_hidden_proto (__res_nameinquery)
+libresolv_hidden_proto (__res_queriesmatch)
+libresolv_hidden_proto (__res_nsend)
+libresolv_hidden_proto (__b64_ntop)
+libresolv_hidden_proto (__ns_name_ntop)
+libresolv_hidden_proto (__ns_name_unpack)
+libresolv_hidden_proto (__ns_get16)
+libresolv_hidden_proto (__ns_get32)
+
 #endif
 
 #endif
diff --git a/include/stdio.h b/include/stdio.h
index b871abc15e..05a91b4cb3 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -27,6 +27,18 @@ extern int __vsscanf (__const char *__restrict __s,
 		      _G_va_list __arg)
      __attribute__ ((__format__ (__scanf__, 2, 0)));
 
+extern int __sprintf_chk (char *, int, size_t, const char *, ...) __THROW;
+extern int __snprintf_chk (char *, size_t, int, size_t, const char *, ...)
+     __THROW;
+extern int __vsprintf_chk (char *, int, size_t, const char *,
+			   _G_va_list) __THROW;
+extern int __vsnprintf_chk (char *, size_t, int, size_t, const char *,
+			    _G_va_list) __THROW;
+extern int __printf_chk (int, const char *, ...);
+extern int __fprintf_chk (FILE *, int, const char *, ...);
+extern int __vprintf_chk (int, const char *, _G_va_list);
+extern int __vfprintf_chk (FILE *, int, const char *, _G_va_list);
+
 /* Prototypes for compatibility functions.  */
 extern FILE *__new_tmpfile (void);
 extern FILE *__old_tmpfile (void);
@@ -109,6 +121,8 @@ libc_hidden_proto (fgets_unlocked)
 libc_hidden_proto (fputs_unlocked)
 libc_hidden_proto (open_memstream)
 libc_hidden_proto (__libc_fatal)
+libc_hidden_proto (__vsprintf_chk)
+libc_hidden_proto (__vsnprintf_chk)
 
 #  if !defined NOT_IN_libc && defined SHARED && defined DO_VERSIONING \
   && defined HAVE_VISIBILITY_ATTRIBUTE && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE\
diff --git a/include/string.h b/include/string.h
index afc6adfbda..738dd8e27c 100644
--- a/include/string.h
+++ b/include/string.h
@@ -3,7 +3,7 @@
 #include <sys/types.h>
 
 extern void *__memccpy (void *__dest, __const void *__src,
-			  int __c, size_t __n);
+			int __c, size_t __n);
 
 extern size_t __strnlen (__const char *__string, size_t __maxlen)
      __attribute_pure__;
@@ -114,4 +114,30 @@ libc_hidden_builtin_proto (ffs)
 #  endif
 # endif
 
+extern void *__memcpy_chk (void *__restrict __dest,
+			   const void *__restrict __src, size_t __len,
+			   size_t __destlen) __THROW;
+extern void *__memmove_chk (void *__dest, const void *__src, size_t __len,
+			    size_t __destlen) __THROW;
+extern void *__mempcpy_chk (void *__restrict __dest,
+			    const void *__restrict __src, size_t __len,
+			    size_t __destlen) __THROW;
+extern void *__memset_chk (void *__dest, int __ch, size_t __len,
+			   size_t __destlen) __THROW;
+extern char *__strcpy_chk (char *__restrict __dest,
+			   const char *__restrict __src,
+			   size_t __destlen) __THROW;
+extern char *__stpcpy_chk (char *__restrict __dest,
+			   const char *__restrict __src,
+			   size_t __destlen) __THROW;
+extern char *__strncpy_chk (char *__restrict __dest,
+			    const char *__restrict __src,
+			    size_t __len, size_t __destlen) __THROW;
+extern char *__strcat_chk (char *__restrict __dest,
+			   const char *__restrict __src,
+			   size_t __destlen) __THROW;
+extern char *__strncat_chk (char *__restrict __dest,
+			    const char *__restrict __src,
+			    size_t __len, size_t __destlen) __THROW;
+
 #endif
diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h
index 200abb4f02..8ba980477d 100644
--- a/include/sys/cdefs.h
+++ b/include/sys/cdefs.h
@@ -1 +1,9 @@
+#ifndef _SYS_CDEFS_H
+
 #include <misc/sys/cdefs.h>
+
+extern void __chk_fail (void) __attribute__ ((__noreturn__));
+libc_hidden_proto (__chk_fail)
+rtld_hidden_proto (__chk_fail)
+
+#endif
diff --git a/libio/Makefile b/libio/Makefile
index c7253ff571..a9384b55a9 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 1995-2002, 2003, 2004 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
@@ -22,7 +22,7 @@
 subdir	:= libio
 
 headers	:= stdio.h libio.h _G_config.h bits/stdio.h bits/stdio-lock.h \
-	   bits/sys_errlist.h
+	   bits/sys_errlist.h bits/stdio2.h
 
 routines	:=							      \
 	filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen      \
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
new file mode 100644
index 0000000000..acf07ea91b
--- /dev/null
+++ b/libio/bits/stdio2.h
@@ -0,0 +1,78 @@
+/* Checking macros for stdio functions.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _STDIO_H
+# error "Never include <bits/stdio2.h> directly; use <stdio.h> instead."
+#endif
+
+extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen,
+			  __const char *__restrict __format, ...) __THROW;
+extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen,
+			   __const char *__restrict __format,
+			   _G_va_list __ap) __THROW;
+
+#define sprintf(str, ...) \
+  __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \
+			   __VA_ARGS__)
+#define vsprintf(str, fmt, ap) \
+  __builtin___vsprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), fmt, ap)
+
+#if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
+
+extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag,
+			   size_t __slen, __const char *__restrict __format,
+			   ...) __THROW;
+extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
+			    size_t __slen, __const char *__restrict __format,
+			    _G_va_list __ap) __THROW;
+
+# define snprintf(str, len, ...) \
+  __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
+			    __VA_ARGS__)
+# define vsnprintf(str, len, fmt, ap) \
+  __builtin___vsnprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
+			     fmt, ap)
+
+#endif			     
+
+#if __USE_FORTIFY_LEVEL > 1
+
+extern int __fprintf_chk (FILE *__restrict __stream, int __flag,
+			  __const char *__restrict __format, ...);
+extern int __printf_chk (int __flag, __const char *__restrict __format, ...);
+extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
+			   __const char *__restrict __format, _G_va_list __ap);
+extern int __vprintf_chk (int __flag, __const char *__restrict __format,
+			  _G_va_list __ap);
+
+# define printf(...) \
+  __printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
+# define fprintf(stream, ...) \
+  __fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
+# define vprintf(format, ap) \
+  __vprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
+# define vfprintf(stream, format, ap) \
+  __vfprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
+
+#endif
+
+extern char *__gets_chk (char *__str, size_t);
+#define gets(__str) \
+  ((__bos (__str) == (size_t) -1)				\
+   ? (gets) (__str) : __gets_chk (__str, __bos (__str)))
diff --git a/libio/libio.h b/libio/libio.h
index 1672f7b54f..645f9fb83c 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -139,6 +139,9 @@
 
 #define _IO_FLAGS2_MMAP 1
 #define _IO_FLAGS2_NOTCANCEL 2
+#ifdef _LIBC
+# define _IO_FLAGS2_CHECK_PERCENT_N 4
+#endif
 
 /* These are "formatting flags" matching the iostream fmtflags enum values. */
 #define _IO_SKIPWS 01
diff --git a/libio/stdio.h b/libio/stdio.h
index 385bc64618..941a2afc74 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -829,6 +829,9 @@ extern void funlockfile (FILE *__stream) __THROW;
 #ifdef __USE_EXTERN_INLINES
 # include <bits/stdio.h>
 #endif
+#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+# include <bits/stdio2.h>
+#endif
 
 __END_DECLS
 
diff --git a/libio/strfile.h b/libio/strfile.h
index bcac784717..b91111a9d6 100644
--- a/libio/strfile.h
+++ b/libio/strfile.h
@@ -63,3 +63,13 @@ typedef struct _IO_strfile_
 /* frozen: set when the program has requested that the array object not
    be altered, reallocated, or freed. */
 #define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF)
+
+typedef struct
+{
+  _IO_strfile f;
+  /* This is used for the characters which do not fit in the buffer
+     provided by the user.  */
+  char overflow_buf[64];
+} _IO_strnfile;
+
+extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c
index e2cfb16d8a..4250c2d2de 100644
--- a/libio/vsnprintf.c
+++ b/libio/vsnprintf.c
@@ -28,16 +28,6 @@
 #include "libioP.h"
 #include "strfile.h"
 
-
-typedef struct
-{
-  _IO_strfile f;
-  /* This is used for the characters which do not fit in the buffer
-     provided by the user.  */
-  char overflow_buf[64];
-} _IO_strnfile;
-
-
 static int _IO_strn_overflow (_IO_FILE *fp, int c) __THROW;
 
 static int
@@ -77,7 +67,7 @@ _IO_strn_overflow (fp, c)
 }
 
 
-static const struct _IO_jump_t _IO_strn_jumps =
+const struct _IO_jump_t _IO_strn_jumps attribute_hidden =
 {
   JUMP_INIT_DUMMY,
   JUMP_INIT(finish, _IO_str_finish),
diff --git a/libio/vswprintf.c b/libio/vswprintf.c
index 3cf01e2c84..42168aade4 100644
--- a/libio/vswprintf.c
+++ b/libio/vswprintf.c
@@ -35,7 +35,7 @@ typedef struct
   /* This is used for the characters which do not fit in the buffer
      provided by the user.  */
   wchar_t overflow_buf[64];
-} _IO_strnfile;
+} _IO_wstrnfile;
 
 
 static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) __THROW;
@@ -49,8 +49,8 @@ _IO_wstrn_overflow (fp, c)
      filled.  But since we must return the number of characters which
      would have been written in total we must provide a buffer for
      further use.  We can do this by writing on and on in the overflow
-     buffer in the _IO_strnfile structure.  */
-  _IO_strnfile *snf = (_IO_strnfile *) fp;
+     buffer in the _IO_wstrnfile structure.  */
+  _IO_wstrnfile *snf = (_IO_wstrnfile *) fp;
 
   if (fp->_wide_data->_IO_buf_base != snf->overflow_buf)
     {
@@ -107,7 +107,7 @@ _IO_vswprintf (string, maxlen, format, args)
      const wchar_t *format;
      _IO_va_list args;
 {
-  _IO_strnfile sf;
+  _IO_wstrnfile sf;
   int ret;
   struct _IO_wide_data wd;
 #ifdef _IO_MTSAFE_IO
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index c704685250..bfccc57eb7 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,8 @@
+2004-10-14  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/pthread/errno-loc.c: Don't undef #errno
+	if RTLD_PRIVATE_ERRNO.
+
 2004-10-05  Dwayne Grant McConnell  <dgm69@us.ibm.com>
 
 	* pthread.c: Mask restart signal during cancel signal handler.
diff --git a/manual/memory.texi b/manual/memory.texi
index 10ae4dee10..91abb7f5d4 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -2578,7 +2578,7 @@ wouldn't know what address to tell @code{mlock}.
 @comment POSIX.1b
 @deftypefun int munlock (const void *@var{addr}, size_t @var{len})
 
-@code{mlock} unlocks a range of the calling process' virtual pages.
+@code{munlock} unlocks a range of the calling process' virtual pages.
 
 @code{munlock} is the inverse of @code{mlock} and functions completely
 analogously to @code{mlock}, except that there is no @code{EPERM}
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 8894d0d5fc..475cf62961 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -127,6 +127,11 @@
 #endif
 
 
+/* Fortify support.  */
+#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
+#define __bos0(ptr) __builtin_object_size (ptr, 0)
+
+
 /* Support for flexible arrays.  */
 #if __GNUC_PREREQ (2,97)
 /* GCC 2.97 supports C99 flexible array members.  */
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index e842302cb8..2385b9cd37 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,8 @@
+2004-10-14  Richard Henderson  <rth@redhat.com>
+
+	* sysdeps/alpha/tcb-offsets.sym (thread_offsetof): Redefine to
+	make gcc4 happy.
+
 2004-10-06  Jakub Jelinek  <jakub@redhat.com>
 
 	* sysdeps/unix/sysv/linux/jmp-unwind.c: Include pthreadP.h instead
@@ -28,8 +33,6 @@
 	* tst-clock2.c: Likewise.
 	* tst-cond11.c: Likewise.
 
-2004-10-05  Jakub Jelinek  <jakub@redhat.com>
-
 	* sysdeps/pthread/timer_create.c (timer_create): Use
 	defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0 instead of
 	defined CLOCK_PROCESS_CPUTIME_ID #ifs and similarly for
diff --git a/nptl/sysdeps/alpha/tcb-offsets.sym b/nptl/sysdeps/alpha/tcb-offsets.sym
index 14494ee2cd..ebd84f35e5 100644
--- a/nptl/sysdeps/alpha/tcb-offsets.sym
+++ b/nptl/sysdeps/alpha/tcb-offsets.sym
@@ -4,8 +4,10 @@
 --
 
 -- Abuse tls.h macros to derive offsets relative to the thread register.
-# define __builtin_thread_pointer()  ((void *) 0)
-# define thread_offsetof(mem)	     ((void *) &THREAD_SELF->mem - (void *) 0)
+-- # define __builtin_thread_pointer()  ((void *) 0)
+-- # define thread_offsetof(mem)     ((void *) &THREAD_SELF->mem - (void *) 0)
+-- Ho hum, this doesn't work in gcc4, so Know Things about THREAD_SELF
+#define thread_offsetof(mem)	(long)(offsetof(struct pthread, mem) - sizeof(struct pthread))
 
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 PID_OFFSET			thread_offsetof (pid)
diff --git a/nscd/Makefile b/nscd/Makefile
index 70a35198c2..b21edc2b79 100644
--- a/nscd/Makefile
+++ b/nscd/Makefile
@@ -123,10 +123,10 @@ $(objpfx)nscd_nischeck: $(objpfx)nscd_nischeck.o
 
 ifeq ($(build-shared),yes)
 $(objpfx)nscd: $(common-objpfx)rt/librt.so $(shared-thread-library) \
-	       $(common-objpfx)nis/libnsl.so
+	       $(common-objpfx)nis/libnsl.so $(selinux-LIBS)
 $(objpfx)nscd_nischeck: $(common-objpfx)nis/libnsl.so
 else
 $(objpfx)nscd: $(common-objpfx)rt/librt.a $(static-thread-library) \
-	       $(common-objpfx)nis/libnsl.a
+	       $(common-objpfx)nis/libnsl.a $(selinux-LIBS)
 $(objpfx)nscd_nischeck: $(common-objpfx)nis/libnsl.a
 endif
diff --git a/nscd/connections.c b/nscd/connections.c
index d9c11f5425..aa760e0252 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -321,17 +321,15 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
 	      }
 	    else
 	      {
-		size_t slen = strlen (dbs[cnt].db_filename);
-		char fname[slen + 8];
-		strcpy (mempcpy (fname, dbs[cnt].db_filename, slen),
-			".XXXXXX");
+		char fname[] = _PATH_NSCD_XYZ_DB_TMP;
 		fd = mkstemp (fname);
 
 		/* We do not need the file name anymore after we
 		   opened another file descriptor in read-only mode.  */
-		if (fd != -1 && dbs[cnt].shared)
+		if (fd != -1)
 		  {
-		    ro_fd = open (fname, O_RDONLY);
+		    if (dbs[cnt].shared)
+		      ro_fd = open (fname, O_RDONLY);
 
 		    unlink (fname);
 		  }
diff --git a/nscd/nscd.h b/nscd/nscd.h
index 4e00f69fb9..d5dc613d22 100644
--- a/nscd/nscd.h
+++ b/nscd/nscd.h
@@ -87,9 +87,12 @@ struct database_dyn
 
 
 /* Paths of the file for the persistent storage.  */
-#define _PATH_NSCD_PASSWD_DB	"/var/run/nscd/passwd"
-#define _PATH_NSCD_GROUP_DB	"/var/run/nscd/group"
-#define _PATH_NSCD_HOSTS_DB	"/var/run/nscd/hosts"
+#define _PATH_NSCD_PASSWD_DB	"/var/db/nscd/passwd"
+#define _PATH_NSCD_GROUP_DB	"/var/db/nscd/group"
+#define _PATH_NSCD_HOSTS_DB	"/var/db/nscd/hosts"
+
+/* Path used when not using persistent storage.  */
+#define _PATH_NSCD_XYZ_DB_TMP	"/var/run/nscd/dbXXXXXX"
 
 
 /* Global variables.  */
diff --git a/nscd/nscd.init b/nscd/nscd.init
index 568fe3e1e2..d5c1cb9ae3 100644
--- a/nscd/nscd.init
+++ b/nscd/nscd.init
@@ -38,6 +38,7 @@ prog=nscd
 
 start () {
     [ -d /var/run/nscd ] || mkdir /var/run/nscd
+    [ -d /var/db/nscd ] || mkdir /var/db/nscd
     secure=""
 #   for table in passwd group hosts
 #   do
diff --git a/resolv/base64.c b/resolv/base64.c
index b7c7d1c1b8..ea584ed357 100644
--- a/resolv/base64.c
+++ b/resolv/base64.c
@@ -112,9 +112,9 @@ static const char Pad64 = '=';
    end of the data is performed using the '=' character.
 
    Since all base64 input is an integral number of octets, only the
-         -------------------------------------------------                       
+         -------------------------------------------------
    following cases can arise:
-   
+
        (1) the final quantum of encoding input is an integral
            multiple of 24 bits; here, the final unit of encoded
 	   output will be an integral multiple of 4 characters
@@ -156,14 +156,14 @@ b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
 		target[datalength++] = Base64[output[2]];
 		target[datalength++] = Base64[output[3]];
 	}
-    
+
 	/* Now we worry about padding. */
 	if (0 != srclength) {
 		/* Get what's left. */
 		input[0] = input[1] = input[2] = '\0';
 		for (i = 0; i < srclength; i++)
 			input[i] = *src++;
-	
+
 		output[0] = input[0] >> 2;
 		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
 		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
@@ -186,6 +186,7 @@ b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
 	target[datalength] = '\0';	/* Returned value doesn't count \0. */
 	return (datalength);
 }
+libresolv_hidden_def (b64_ntop)
 
 /* skips all whitespace anywhere.
    converts characters, four at a time, starting at (or after)
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index 1a4b08ecdc..3698e4b841 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -487,6 +487,9 @@ getanswer(answer, anslen, qname, qtype)
 	return (NULL);
 }
 
+extern struct hostent *gethostbyname2(const char *name, int af);
+libresolv_hidden_proto (gethostbyname2)
+
 struct hostent *
 gethostbyname(name)
 	const char *name;
@@ -637,6 +640,7 @@ gethostbyname2(name, af)
 		free (buf.buf);
 	return ret;
 }
+libresolv_hidden_def (gethostbyname2)
 
 struct hostent *
 gethostbyaddr(addr, len, af)
@@ -795,6 +799,7 @@ _sethtent(f)
 		rewind(hostf);
 	stayopen = f;
 }
+libresolv_hidden_def (_sethtent)
 
 void
 _endhtent()
@@ -869,6 +874,7 @@ _gethtent()
 	__set_h_errno (NETDB_SUCCESS);
 	return (&host);
 }
+libresolv_hidden_def (_gethtent)
 
 struct hostent *
 _gethtbyname(name)
@@ -907,6 +913,7 @@ _gethtbyname2(name, af)
 	_endhtent();
 	return (p);
 }
+libresolv_hidden_def (_gethtbyname2)
 
 struct hostent *
 _gethtbyaddr(addr, len, af)
@@ -923,6 +930,7 @@ _gethtbyaddr(addr, len, af)
 	_endhtent();
 	return (p);
 }
+libresolv_hidden_def (_gethtbyaddr)
 
 static void
 map_v4v6_address(src, dst)
diff --git a/resolv/ns_name.c b/resolv/ns_name.c
index b96a1fe8ab..ed361915d8 100644
--- a/resolv/ns_name.c
+++ b/resolv/ns_name.c
@@ -145,6 +145,7 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
 	*dn++ = '\0';
 	return (dn - dst);
 }
+libresolv_hidden_def (ns_name_ntop)
 
 /*
  * ns_name_pton(src, dst, dstsiz)
@@ -421,6 +422,7 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
 		len = srcp - src;
 	return (len);
 }
+libresolv_hidden_def (ns_name_unpack)
 
 /*
  * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
diff --git a/resolv/ns_netint.c b/resolv/ns_netint.c
index ff24128cd6..20ecf626d8 100644
--- a/resolv/ns_netint.c
+++ b/resolv/ns_netint.c
@@ -22,6 +22,7 @@ static const char rcsid[] = "$BINDId: ns_netint.c,v 8.4 1999/10/13 16:39:35 vixi
 /* Import. */
 
 #include <arpa/nameser.h>
+#include <resolv.h>
 
 /* Public. */
 
@@ -32,6 +33,7 @@ ns_get16(const u_char *src) {
 	NS_GET16(dst, src);
 	return (dst);
 }
+libresolv_hidden_def (ns_get16)
 
 u_long
 ns_get32(const u_char *src) {
@@ -40,6 +42,7 @@ ns_get32(const u_char *src) {
 	NS_GET32(dst, src);
 	return (dst);
 }
+libresolv_hidden_def (ns_get32)
 
 void
 ns_put16(u_int src, u_char *dst) {
diff --git a/resolv/res_comp.c b/resolv/res_comp.c
index f227c4d163..8157b97566 100644
--- a/resolv/res_comp.c
+++ b/resolv/res_comp.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 1985, 1993
  *    The 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:
@@ -13,7 +13,7 @@
  * 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
@@ -29,14 +29,14 @@
 
 /*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
+ *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -96,6 +96,7 @@ dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
 		dst[0] = '\0';
 	return (n);
 }
+libresolv_hidden_def (dn_expand)
 
 /*
  * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
@@ -110,6 +111,7 @@ dn_comp(const char *src, u_char *dst, int dstsiz,
 				 (const u_char **)dnptrs,
 				 (const u_char **)lastdnptr));
 }
+libresolv_hidden_def (dn_comp)
 
 /*
  * Skip over a compressed domain name. Return the size or -1.
@@ -122,6 +124,7 @@ dn_skipname(const u_char *ptr, const u_char *eom) {
 		return (-1);
 	return (ptr - saveptr);
 }
+libresolv_hidden_def (dn_skipname)
 
 /*
  * Verify that a domain name uses an acceptable character set.
@@ -170,6 +173,7 @@ res_hnok(const char *dn) {
 	}
 	return (1);
 }
+libresolv_hidden_def (res_hnok)
 
 /*
  * hostname-like (A, MX, WKS) owners can have "*" as their first label
@@ -227,6 +231,7 @@ res_dnok(const char *dn) {
 			return (0);
 	return (1);
 }
+libresolv_hidden_def (res_dnok)
 
 #ifdef BIND_4_COMPAT
 /*
@@ -238,7 +243,9 @@ res_dnok(const char *dn) {
  * Note that one _ comes from C and the others come from us.
  */
 void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
+libresolv_hidden_def (__putlong)
 void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
+libresolv_hidden_def (__putshort)
 #ifndef __ultrix__
 u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
 u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
diff --git a/resolv/res_data.c b/resolv/res_data.c
index 2183e022c8..438f815605 100644
--- a/resolv/res_data.c
+++ b/resolv/res_data.c
@@ -39,7 +39,7 @@ static const char rcsid[] = "$BINDId: res_data.c,v 8.17 1999/10/13 17:11:31 vixi
 #include <string.h>
 #include <unistd.h>
 
-const char *_res_opcodes[] = {
+const char *_res_opcodes[] attribute_hidden = {
 	"QUERY",
 	"IQUERY",
 	"CQUERYM",
@@ -59,7 +59,7 @@ const char *_res_opcodes[] = {
 };
 
 #ifdef BIND_UPDATE
-const char *_res_sectioncodes[] = {
+const char *_res_sectioncodes[] attribute_hidden = {
 	"ZONE",
 	"PREREQUISITES",
 	"UPDATE",
@@ -138,6 +138,7 @@ void
 fp_query(const u_char *msg, FILE *file) {
 	fp_nquery(msg, PACKETSZ, file);
 }
+libresolv_hidden_def (fp_query)
 
 void
 fp_nquery(const u_char *msg, int len, FILE *file) {
@@ -146,6 +147,7 @@ fp_nquery(const u_char *msg, int len, FILE *file) {
 
 	res_pquery(&_res, msg, len, file);
 }
+libresolv_hidden_def (fp_nquery)
 
 int
 res_mkquery(int op,			/* opcode of query */
@@ -295,6 +297,7 @@ hostalias(const char *name) {
 
 	return (res_hostalias(&_res, name, abuf, sizeof abuf));
 }
+libresolv_hidden_def (hostalias)
 
 #ifdef ultrix
 int
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index bd1fd3388f..6b719d1f2d 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -118,8 +118,8 @@ static const char rcsid[] = "$BINDId: res_debug.c,v 8.34 2000/02/29 05:30:55 vix
 # define SPRINTF(x) sprintf x
 #endif
 
-extern const char *_res_opcodes[];
-extern const char *_res_sectioncodes[];
+extern const char *_res_opcodes[] attribute_hidden;
+extern const char *_res_sectioncodes[] attribute_hidden;
 
 /*
  * Print the current options.
@@ -298,6 +298,7 @@ p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
 		fputs(name, file);
 	return (cp + n);
 }
+libresolv_hidden_def (p_cdnname)
 
 const u_char *
 p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
@@ -327,6 +328,7 @@ p_fqnname(cp, msg, msglen, name, namelen)
 	}
 	return (cp + n);
 }
+libresolv_hidden_def (p_fqnname)
 
 /* XXX:	the rest of these functions need to become length-limited, too. */
 
@@ -347,7 +349,7 @@ p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
  * that C_ANY is a qclass but not a class.  (You can ask for records of class
  * C_ANY, but you can't have any records of that class in the database.)
  */
-const struct res_sym __p_class_syms[] = {
+const struct res_sym __p_class_syms[] attribute_hidden = {
 	{C_IN,		"IN"},
 	{C_CHAOS,	"CHAOS"},
 	{C_HS,		"HS"},
@@ -360,7 +362,7 @@ const struct res_sym __p_class_syms[] = {
 /*
  * Names of message sections.
  */
-const struct res_sym __p_default_section_syms[] = {
+const struct res_sym __p_default_section_syms[] attribute_hidden = {
 	{ns_s_qd,	"QUERY"},
 	{ns_s_an,	"ANSWER"},
 	{ns_s_ns,	"AUTHORITY"},
@@ -368,7 +370,7 @@ const struct res_sym __p_default_section_syms[] = {
 	{0,             (char *)0}
 };
 
-const struct res_sym __p_update_section_syms[] = {
+const struct res_sym __p_update_section_syms[] attribute_hidden = {
 	{S_ZONE,	"ZONE"},
 	{S_PREREQ,	"PREREQUISITE"},
 	{S_UPDATE,	"UPDATE"},
@@ -376,7 +378,7 @@ const struct res_sym __p_update_section_syms[] = {
 	{0,             (char *)0}
 };
 
-const struct res_sym __p_key_syms[] = {
+const struct res_sym __p_key_syms[] attribute_hidden = {
 	{NS_ALG_MD5RSA,		"RSA",		"RSA KEY with MD5 hash"},
 	{NS_ALG_DH,		"DH",		"Diffie Hellman"},
 	{NS_ALG_DSA,		"DSA",		"Digital Signature Algorithm"},
@@ -385,7 +387,7 @@ const struct res_sym __p_key_syms[] = {
 	{0,			NULL,		NULL}
 };
 
-const struct res_sym __p_cert_syms[] = {
+const struct res_sym __p_cert_syms[] attribute_hidden = {
 	{cert_t_pkix,	"PKIX",		"PKIX (X.509v3) Certificate"},
 	{cert_t_spki,	"SPKI",		"SPKI certificate"},
 	{cert_t_pgp,	"PGP",		"PGP certificate"},
@@ -399,7 +401,7 @@ const struct res_sym __p_cert_syms[] = {
  * that T_ANY is a qtype but not a type.  (You can ask for records of type
  * T_ANY, but you can't have any records of that type in the database.)
  */
-const struct res_sym __p_type_syms[] = {
+const struct res_sym __p_type_syms[] attribute_hidden = {
 	{ns_t_a,	"A",		"address"},
 	{ns_t_ns,	"NS",		"name server"},
 	{ns_t_md,	"MD",		"mail destination (deprecated)"},
@@ -450,7 +452,7 @@ const struct res_sym __p_type_syms[] = {
 /*
  * Names of DNS rcodes.
  */
-const struct res_sym __p_rcode_syms[] = {
+const struct res_sym __p_rcode_syms[] attribute_hidden = {
 	{ns_r_noerror,	"NOERROR",		"no error"},
 	{ns_r_formerr,	"FORMERR",		"format error"},
 	{ns_r_servfail,	"SERVFAIL",		"server failed"},
@@ -500,6 +502,7 @@ sym_ntos(const struct res_sym *syms, int number, int *success) {
 		*success = 0;
 	return (unname);
 }
+libresolv_hidden_def (sym_ntos)
 
 const char *
 sym_ntop(const struct res_sym *syms, int number, int *success) {
@@ -525,6 +528,7 @@ const char *
 p_type(int type) {
 	return (sym_ntos(__p_type_syms, type, (int *)0));
 }
+libresolv_hidden_def (p_type)
 
 /*
  * Return a string for the type.
@@ -551,6 +555,7 @@ const char *
 p_class(int class) {
 	return (sym_ntos(__p_class_syms, class, (int *)0));
 }
+libresolv_hidden_def (p_class)
 
 /*
  * Return a mnemonic for an option
@@ -581,6 +586,7 @@ p_option(u_long option) {
 				return (nbuf);
 	}
 }
+libresolv_hidden_def (p_option)
 
 /*
  * Return a mnemonic for a time to live.
@@ -601,6 +607,7 @@ const char *
 p_rcode(int rcode) {
 	return (sym_ntos(__p_rcode_syms, rcode, (int *)0));
 }
+libresolv_hidden_def (p_rcode)
 
 /*
  * routines to convert between on-the-wire RR format and zone file format.
@@ -608,8 +615,9 @@ p_rcode(int rcode) {
  * by 60*60*1000 for that.
  */
 
-static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
-				      1000000,10000000,100000000,1000000000};
+static const unsigned int poweroften[10]=
+  { 1, 10, 100, 1000, 10000, 100000,
+    1000000,10000000,100000000,1000000000};
 
 /* takes an XeY precision/size value, returns a string representation. */
 static const char *
@@ -988,6 +996,7 @@ loc_ntoa(binary, ascii)
 
 	return (ascii);
 }
+libresolv_hidden_def (loc_ntoa)
 
 
 /* Return the number of DNS hierarchy levels in the name. */
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 9825ae0fa3..875d495b72 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -219,3 +219,4 @@ res_nmkquery(res_state statp,
 	}
 	return (cp - buf);
 }
+libresolv_hidden_def (res_nmkquery)
diff --git a/resolv/res_query.c b/resolv/res_query.c
index d2ef3b5e93..0feba6687a 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -190,6 +190,7 @@ __libc_res_nquery(res_state statp,
 	}
 	return (n);
 }
+libresolv_hidden_def (__libc_res_nquery)
 
 int
 res_nquery(res_state statp,
@@ -201,6 +202,7 @@ res_nquery(res_state statp,
 	return __libc_res_nquery(statp, name, class, type, answer, anslen,
 				 NULL);
 }
+libresolv_hidden_def (res_nquery)
 
 /*
  * Formulate a normal query, send, and retrieve answer in supplied buffer.
@@ -365,6 +367,7 @@ __libc_res_nsearch(res_state statp,
 		RES_SET_H_ERRNO(statp, TRY_AGAIN);
 	return (-1);
 }
+libresolv_hidden_def (__libc_res_nsearch)
 
 int
 res_nsearch(res_state statp,
@@ -376,6 +379,7 @@ res_nsearch(res_state statp,
 	return __libc_res_nsearch(statp, name, class, type, answer,
 				  anslen, NULL);
 }
+libresolv_hidden_def (res_nsearch)
 
 /*
  * Perform a call on res_query on the concatenation of name and domain,
@@ -439,6 +443,7 @@ res_nquerydomain(res_state statp,
 	return __libc_res_nquerydomain(statp, name, domain, class, type,
 				       answer, anslen, NULL);
 }
+libresolv_hidden_def (res_nquerydomain)
 
 const char *
 res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) {
@@ -476,3 +481,4 @@ res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) {
 	fclose(fp);
 	return (NULL);
 }
+libresolv_hidden_def (res_hostalias)
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 44d8cb0fee..7773a2f522 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -312,6 +312,7 @@ res_nameinquery(const char *name, int type, int class,
 	}
 	return (0);
 }
+libresolv_hidden_def (res_nameinquery)
 
 /* int
  * res_queriesmatch(buf1, eom1, buf2, eom2)
@@ -361,6 +362,7 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1,
 	}
 	return (1);
 }
+libresolv_hidden_def (res_queriesmatch)
 
 int
 __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
@@ -689,6 +691,7 @@ res_nsend(res_state statp,
 {
 	return __libc_res_nsend(statp, buf, buflen, ans, anssiz, NULL);
 }
+libresolv_hidden_def (res_nsend)
 
 /* Private */
 
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 38da382efa..5e480ad52b 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -70,6 +70,7 @@
 # define INT_T		int
 # define L_(Str)	Str
 # define ISDIGIT(Ch)	((unsigned int) ((Ch) - '0') < 10)
+# define STR_LEN(Str)	strlen (Str)
 
 # define PUT(F, S, N)	_IO_sputn ((F), (S), (N))
 # define PAD(Padchar) \
@@ -86,6 +87,7 @@
 # define INT_T		wint_t
 # define L_(Str)	L##Str
 # define ISDIGIT(Ch)	((unsigned int) ((Ch) - L'0') < 10)
+# define STR_LEN(Str)	__wcslen (Str)
 
 # include "_itowa.h"
 
@@ -219,6 +221,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
   /* For the %m format we may need the current `errno' value.  */
   int save_errno = errno;
 
+  /* 1 if format is in read-only memory, -1 if it is in writable memory,
+     0 if unknown.  */
+  int readonly_format = 0;
 
   /* This table maps a character into a number representing a
      class.  In each step there is a destination label for each
@@ -877,6 +882,19 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       /* NOTREACHED */							      \
 									      \
     LABEL (form_number):						      \
+      if (s->_flags2 & _IO_FLAGS2_CHECK_PERCENT_N)			      \
+	{								      \
+	  if (! readonly_format)					      \
+	    {								      \
+	      extern int __readonly_area (const void *, size_t)		      \
+		attribute_hidden;					      \
+	      readonly_format						      \
+		= __readonly_area (format, (STR_LEN (format) + 1)	      \
+					   * sizeof (CHAR_T));		      \
+	    }								      \
+	  if (readonly_format < 0)					      \
+	    __chk_fail ();						      \
+	}								      \
       /* Answer the count of characters written.  */			      \
       if (fspec == NULL)						      \
 	{								      \
@@ -2091,6 +2109,7 @@ buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format,
 #ifdef _IO_MTSAFE_IO
   hp->_lock = NULL;
 #endif
+  hp->_flags2 = s->_flags2;
   _IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_helper_jumps;
 
   /* Now print to helper instead.  */
diff --git a/string/Makefile b/string/Makefile
index 5ab487f5ba..66469f586e 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -23,7 +23,7 @@ subdir	:= string
 
 headers	:= string.h strings.h memory.h endian.h bits/endian.h \
 	   argz.h envz.h byteswap.h bits/byteswap.h bits/string.h \
-	   bits/string2.h
+	   bits/string2.h bits/string3.h
 
 routines	:= strcat strchr strcmp strcoll strcpy strcspn		\
 		   strverscmp strdup strndup				\
diff --git a/string/bits/string3.h b/string/bits/string3.h
new file mode 100644
index 0000000000..87cbe35bb1
--- /dev/null
+++ b/string/bits/string3.h
@@ -0,0 +1,167 @@
+/* Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _STRING_H
+# error "Never use <bits/string3.h> directly; include <string.h> instead."
+#endif
+
+/* XXX This is temporarily.  We should not redefine any of the symbols
+   and instead integrate the error checking into the original
+   definitions.  */
+#undef memcpy
+#undef memmove
+#undef memset
+#undef strcat
+#undef strcpy
+#undef strncat
+#undef strncpy
+#ifdef __USE_GNU
+# undef mempcpy
+# undef stpcpy
+#endif
+#ifdef __USE_BSD
+# undef bcopy
+# undef bzero
+#endif
+
+
+#define memcpy(dest, src, len) \
+  ((__bos0 (dest) != (size_t) -1)					\
+   ? __builtin___memcpy_chk (dest, src, len, __bos0 (dest))		\
+   : __memcpy_ichk (dest, src, len))
+static __inline__ void *
+__attribute__ ((__always_inline__))
+__memcpy_ichk (void *__restrict __dest, const void *__restrict __src,
+	       size_t __len)
+{
+  return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
+}
+
+
+#define memmove(dest, src, len) \
+  ((__bos0 (dest) != (size_t) -1)					\
+   ? __builtin___memmove_chk (dest, src, len, __bos0 (dest))		\
+   : __memmove_ichk (dest, src, len))
+static __inline__ void *
+__attribute__ ((__always_inline__))
+__memmove_ichk (void *__dest, const void *__src, size_t __len)
+{
+  return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
+}
+
+
+#ifdef __USE_GNU
+# define mempcpy(dest, src, len) \
+  ((__bos0 (dest) != (size_t) -1)					\
+   ? __builtin___mempcpy_chk (dest, src, len, __bos0 (dest))		\
+   : __mempcpy_ichk (dest, src, len))
+static __inline__ void *
+__attribute__ ((__always_inline__))
+__mempcpy_ichk (void *__restrict __dest, const void *__restrict __src,
+		size_t __len)
+{
+  return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest));
+}
+#endif
+
+
+#define memset(dest, ch, len) \
+  ((__bos0 (dest) != (size_t) -1)					\
+   ? __builtin___memset_chk (dest, ch, len, __bos0 (dest))		\
+   : __memset_ichk (dest, ch, len))
+static __inline__ void *
+__attribute__ ((__always_inline__))
+__memset_ichk (void *__dest, int __ch, size_t __len)
+{
+  return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
+}
+
+#ifdef __USE_BSD
+# define bcopy(src, dest, len) ((void) \
+  ((__bos0 (dest) != (size_t) -1)					\
+   ? __builtin___memmove_chk (dest, src, len, __bos0 (dest))		\
+   : __memmove_ichk (dest, src, len)))
+# define bzero(dest, len) ((void) \
+  ((__bos0 (dest) != (size_t) -1)					\
+   ? __builtin___memset_chk (dest, '\0', len, __bos0 (dest))		\
+   : __memset_ichk (dest, '\0', len)))
+#endif
+
+
+#define strcpy(dest, src) \
+  ((__bos (dest) != (size_t) -1)					\
+   ? __builtin___strcpy_chk (dest, src, __bos (dest))			\
+   : __strcpy_ichk (dest, src))
+static __inline__ char *
+__attribute__ ((__always_inline__))
+__strcpy_ichk (char *__restrict __dest, const char *__restrict __src)
+{
+  return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
+}
+
+
+#ifdef __USE_GNU
+# define stpcpy(dest, src) \
+  ((__bos (dest) != (size_t) -1)					\
+   ? __builtin___stpcpy_chk (dest, src, __bos (dest))			\
+   : __stpcpy_ichk (dest, src))
+static __inline__ char *
+__attribute__ ((__always_inline__))
+__stpcpy_ichk (char *__restrict __dest, const char *__restrict __src)
+{
+  return __builtin___stpcpy_chk (__dest, __src, __bos (__dest));
+}
+#endif
+
+
+#define strncpy(dest, src, len) \
+  ((__bos (dest) != (size_t) -1)					\
+   ? __builtin___strncpy_chk (dest, src, len, __bos (dest))		\
+   : __strncpy_ichk (dest, src, len))
+static __inline__ char *
+__attribute__ ((__always_inline__))
+__strncpy_ichk (char *__restrict __dest, const char *__restrict __src,
+		size_t __len)
+{
+  return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
+}
+
+
+#define strcat(dest, src) \
+  ((__bos (dest) != (size_t) -1)					\
+   ? __builtin___strcat_chk (dest, src, __bos (dest))			\
+   : __strcat_ichk (dest, src))
+static __inline__ char *
+__attribute__ ((__always_inline__))
+__strcat_ichk (char *__restrict __dest, const char *__restrict __src)
+{
+  return __builtin___strcat_chk (__dest, __src, __bos (__dest));
+}
+
+
+#define strncat(dest, src, len) \
+  ((__bos (dest) != (size_t) -1)					\
+   ? __builtin___strncat_chk (dest, src, len, __bos (dest))		\
+   : __strncat_ichk (dest, src, len))
+static __inline__ char *
+__attribute__ ((__always_inline__))
+__strncat_ichk (char *__restrict __dest, const char *__restrict __src,
+		size_t __len)
+{
+  return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
+}
diff --git a/string/string.h b/string/string.h
index 4ea3a74ca7..1adf925bb0 100644
--- a/string/string.h
+++ b/string/string.h
@@ -416,6 +416,11 @@ extern char *basename (__const char *__filename) __THROW __nonnull ((1));
 /* These are generic optimizations which do not add too much inline code.  */
 #  include <bits/string2.h>
 # endif
+
+# if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+/* Functions with security checks.  */
+#  include <bits/string3.h>
+# endif
 #endif
 
 __END_DECLS
diff --git a/sunrpc/rpc_clntout.c b/sunrpc/rpc_clntout.c
index 1e6bb56728..4e2832ff56 100644
--- a/sunrpc/rpc_clntout.c
+++ b/sunrpc/rpc_clntout.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI
  */
-char clntout_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char clntout_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
diff --git a/sunrpc/rpc_cout.c b/sunrpc/rpc_cout.c
index a6471ab335..a803feb65a 100644
--- a/sunrpc/rpc_cout.c
+++ b/sunrpc/rpc_cout.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI
  */
-char cout_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char cout_rcsid[] =
 "$Id$";
+#endif
 
 /*
  * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
diff --git a/sunrpc/rpc_hout.c b/sunrpc/rpc_hout.c
index 076d63cb12..38cb419527 100644
--- a/sunrpc/rpc_hout.c
+++ b/sunrpc/rpc_hout.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI
  */
-char hout_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char hout_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_hout.c, Header file outputter for the RPC protocol compiler
diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c
index 656f8ae502..fee83514d1 100644
--- a/sunrpc/rpc_main.c
+++ b/sunrpc/rpc_main.c
@@ -31,8 +31,10 @@
 /*
  * From @(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI;
  */
-const char main_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char main_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_main.c, Top level of the RPC protocol compiler.
diff --git a/sunrpc/rpc_parse.c b/sunrpc/rpc_parse.c
index d6eda42309..7115cbdd08 100644
--- a/sunrpc/rpc_parse.c
+++ b/sunrpc/rpc_parse.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI
  */
-const char parse_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char parse_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_parse.c, Parser for the RPC protocol compiler
diff --git a/sunrpc/rpc_sample.c b/sunrpc/rpc_sample.c
index 79214a6a83..50c3d5554b 100644
--- a/sunrpc/rpc_sample.c
+++ b/sunrpc/rpc_sample.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_sample.c  1.1  90/08/30  (C) 1987 SMI
  */
-char sample_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sample_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
diff --git a/sunrpc/rpc_scan.c b/sunrpc/rpc_scan.c
index 15c8e01178..d6211e9105 100644
--- a/sunrpc/rpc_scan.c
+++ b/sunrpc/rpc_scan.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI
  */
-char scan_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char scan_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_scan.c, Scanner for the RPC protocol compiler
diff --git a/sunrpc/rpc_svcout.c b/sunrpc/rpc_svcout.c
index a1eb792097..9a807c4096 100644
--- a/sunrpc/rpc_svcout.c
+++ b/sunrpc/rpc_svcout.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI
  */
-char svcout_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char svcout_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
diff --git a/sunrpc/rpc_tblout.c b/sunrpc/rpc_tblout.c
index 4f62e2e7fd..bf4037fc37 100644
--- a/sunrpc/rpc_tblout.c
+++ b/sunrpc/rpc_tblout.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI
  */
-char tblout_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char tblout_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
diff --git a/sunrpc/rpc_util.c b/sunrpc/rpc_util.c
index 4c986040ce..31e1d3143c 100644
--- a/sunrpc/rpc_util.c
+++ b/sunrpc/rpc_util.c
@@ -31,8 +31,10 @@
 /*
  * From: @(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI
  */
-char util_rcsid[] =
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char util_rcsid[] =
   "$Id$";
+#endif
 
 /*
  * rpc_util.c, Utility routines for the RPC protocol compiler
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 7c5f3c1518..780a3a57fd 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -507,7 +507,7 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
-static inline void
+auto inline void
 elf_machine_rela (struct link_map *map,
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
@@ -645,7 +645,7 @@ elf_machine_rela (struct link_map *map,
    can be skipped.  */
 #define ELF_MACHINE_REL_RELATIVE 1
 
-static inline void
+auto inline void
 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -661,7 +661,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
   memcpy (reloc_addr_arg, &reloc_addr_val, 8);
 }
 
-static inline void
+auto inline void
 elf_machine_lazy_rel (struct link_map *map,
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc)
 {
diff --git a/sysdeps/generic/memcpy_chk.c b/sysdeps/generic/memcpy_chk.c
new file mode 100644
index 0000000000..638cd0e4fb
--- /dev/null
+++ b/sysdeps/generic/memcpy_chk.c
@@ -0,0 +1,66 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied with error checking.  Overlap is NOT handled correctly.
+   Copyright (C) 1991, 1997, 2003, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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>
+
+void *
+__memcpy_chk (dstpp, srcpp, len, dstlen)
+     void *dstpp;
+     const void *srcpp;
+     size_t len;
+     size_t dstlen;
+{
+  if (__builtin_expect (dstlen < len, 0))
+    __chk_fail ();
+
+  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 dstpp;
+}
diff --git a/sysdeps/generic/memmove_chk.c b/sysdeps/generic/memmove_chk.c
new file mode 100644
index 0000000000..f3b74d23d9
--- /dev/null
+++ b/sysdeps/generic/memmove_chk.c
@@ -0,0 +1,98 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied with error checking.  Overlap is handled correctly.
+   Copyright (C) 1991,1995,1996,1997,2003,2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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>
+
+void *
+__memmove_chk (dest, src, len, destlen)
+     void *dest;
+     const void *src;
+     size_t len;
+     size_t destlen;
+{
+  if (__builtin_expect (destlen < len, 0))
+    __chk_fail ();
+
+  unsigned long int dstp = (long int) dest;
+  unsigned long int srcp = (long int) src;
+
+  /* This test makes the forward copying code be used whenever possible.
+     Reduces the working set.  */
+  if (dstp - srcp >= len)	/* *Unsigned* compare!  */
+    {
+      /* 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);
+    }
+  else
+    {
+      /* Copy from the end to the beginning.  */
+      srcp += len;
+      dstp += len;
+
+      /* 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_BWD (dstp, srcp, dstp % OPSIZ);
+
+	  /* 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_BWD (dstp, srcp, len, len);
+
+	  /* Fall out and copy the tail.  */
+	}
+
+      /* There are just a few bytes to copy.  Use byte memory operations.  */
+      BYTE_COPY_BWD (dstp, srcp, len);
+    }
+
+  return dest;
+}
diff --git a/sysdeps/generic/mempcpy_chk.c b/sysdeps/generic/mempcpy_chk.c
new file mode 100644
index 0000000000..5297bbab92
--- /dev/null
+++ b/sysdeps/generic/mempcpy_chk.c
@@ -0,0 +1,67 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied, return pointer to following byte, with error checking.
+   Overlap is NOT handled correctly.
+   Copyright (C) 1991, 1997, 1998, 2002, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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>
+
+void *
+__mempcpy_chk (dstpp, srcpp, len, dstlen)
+     void *dstpp;
+     const void *srcpp;
+     size_t len;
+     size_t dstlen;
+{
+  if (__builtin_expect (dstlen < len, 0))
+    __chk_fail ();
+
+  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;
+}
diff --git a/sysdeps/generic/memset_chk.c b/sysdeps/generic/memset_chk.c
new file mode 100644
index 0000000000..c311914395
--- /dev/null
+++ b/sysdeps/generic/memset_chk.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1991, 1997, 2003, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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>
+
+void *
+__memset_chk (dstpp, c, len, dstlen)
+     void *dstpp;
+     int c;
+     size_t len;
+     size_t dstlen;
+{
+  if (__builtin_expect (dstlen < len, 0))
+    __chk_fail ();
+
+  long int dstp = (long int) dstpp;
+
+  if (len >= 8)
+    {
+      size_t xlen;
+      op_t cccc;
+
+      cccc = (unsigned char) c;
+      cccc |= cccc << 8;
+      cccc |= cccc << 16;
+      if (OPSIZ > 4)
+	/* Do the shift in two steps to avoid warning if long has 32 bits.  */
+	cccc |= (cccc << 16) << 16;
+
+      /* There are at least some bytes to set.
+	 No need to test for LEN == 0 in this alignment loop.  */
+      while (dstp % OPSIZ != 0)
+	{
+	  ((byte *) dstp)[0] = c;
+	  dstp += 1;
+	  len -= 1;
+	}
+
+      /* Write 8 `op_t' per iteration until less than 8 `op_t' remain.  */
+      xlen = len / (OPSIZ * 8);
+      while (xlen > 0)
+	{
+	  ((op_t *) dstp)[0] = cccc;
+	  ((op_t *) dstp)[1] = cccc;
+	  ((op_t *) dstp)[2] = cccc;
+	  ((op_t *) dstp)[3] = cccc;
+	  ((op_t *) dstp)[4] = cccc;
+	  ((op_t *) dstp)[5] = cccc;
+	  ((op_t *) dstp)[6] = cccc;
+	  ((op_t *) dstp)[7] = cccc;
+	  dstp += 8 * OPSIZ;
+	  xlen -= 1;
+	}
+      len %= OPSIZ * 8;
+
+      /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain.  */
+      xlen = len / OPSIZ;
+      while (xlen > 0)
+	{
+	  ((op_t *) dstp)[0] = cccc;
+	  dstp += OPSIZ;
+	  xlen -= 1;
+	}
+      len %= OPSIZ;
+    }
+
+  /* Write the last few bytes.  */
+  while (len > 0)
+    {
+      ((byte *) dstp)[0] = c;
+      dstp += 1;
+      len -= 1;
+    }
+
+  return dstpp;
+}
diff --git a/sysdeps/generic/readonly-area.c b/sysdeps/generic/readonly-area.c
new file mode 100644
index 0000000000..df5b96015c
--- /dev/null
+++ b/sysdeps/generic/readonly-area.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
+   Return -1 if it is writable.  */
+
+#include <stdlib.h>
+
+int
+__readonly_str (const void *ptr, size_t size)
+{
+  /* The conservative answer is that all strings are writable.  */
+  return -1;
+}
diff --git a/sysdeps/generic/stpcpy_chk.c b/sysdeps/generic/stpcpy_chk.c
new file mode 100644
index 0000000000..dacda0115a
--- /dev/null
+++ b/sysdeps/generic/stpcpy_chk.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1992, 1995, 1997, 2002, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+
+/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */
+char *
+__stpcpy_chk (dest, src, destlen)
+     char *dest;
+     const char *src;
+     size_t destlen;
+{
+  register char *d = dest;
+  register const char *s = src;
+
+  do
+    {
+      if (__builtin_expect (destlen-- == 0, 0))
+	__chk_fail ();
+      *d++ = *s;
+    }
+  while (*s++ != '\0');
+
+  return d - 1;
+}
diff --git a/sysdeps/generic/strcat_chk.c b/sysdeps/generic/strcat_chk.c
new file mode 100644
index 0000000000..b3fb3470b7
--- /dev/null
+++ b/sysdeps/generic/strcat_chk.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1991, 1997, 2003, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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>
+
+
+/* Append SRC on the end of DEST.  */
+char *
+__strcat_chk (dest, src, destlen)
+     char *dest;
+     const char *src;
+     size_t destlen;
+{
+  char *s1 = dest;
+  const char *s2 = src;
+  reg_char c;
+
+  /* Find the end of the string.  */
+  do
+    {
+      if (__builtin_expect (destlen-- == 0, 0))
+	__chk_fail ();
+      c = *s1++;
+    }
+  while (c != '\0');
+
+  /* Make S1 point before the next character, so we can increment
+     it while memory is read (wins on pipelined cpus).  */
+  ++destlen;
+  s1 -= 2;
+
+  do
+    {
+      if (__builtin_expect (destlen-- == 0, 0))
+	__chk_fail ();
+      c = *s2++;
+      *++s1 = c;
+    }
+  while (c != '\0');
+
+  return dest;
+}
diff --git a/sysdeps/generic/strcpy_chk.c b/sysdeps/generic/strcpy_chk.c
new file mode 100644
index 0000000000..5c1ae44cd0
--- /dev/null
+++ b/sysdeps/generic/strcpy_chk.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991, 1997, 2000, 2003, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stddef.h>
+#include <string.h>
+#include <memcopy.h>
+
+#undef strcpy
+
+/* Copy SRC to DEST with checking of destination buffer overflow.  */
+char *
+__strcpy_chk (dest, src, destlen)
+     char *dest;
+     const char *src;
+     size_t destlen;
+{
+  reg_char c;
+  char *s = (char *) src;
+  const ptrdiff_t off = dest - s - 1;
+
+  do
+    {
+      if (__builtin_expect (destlen-- == 0, 0))
+	__chk_fail ();
+      c = *s++;
+      s[off] = c;
+    }
+  while (c != '\0');
+
+  return dest;
+}
diff --git a/sysdeps/generic/strncat_chk.c b/sysdeps/generic/strncat_chk.c
new file mode 100644
index 0000000000..953b435a4b
--- /dev/null
+++ b/sysdeps/generic/strncat_chk.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 1991, 1997, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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>
+
+
+char *
+__strncat_chk (s1, s2, n, s1len)
+     char *s1;
+     const char *s2;
+     size_t n;
+     size_t s1len;
+{
+  reg_char c;
+  char *s = s1;
+
+  /* Find the end of S1.  */
+  do
+    {
+      if (__builtin_expect (s1len-- == 0, 0))
+	__chk_fail ();
+      c = *s1++;
+    }
+  while (c != '\0');
+
+  /* Make S1 point before next character, so we can increment
+     it while memory is read (wins on pipelined cpus).  */
+  ++s1len;
+  s1 -= 2;
+
+  if (n >= 4)
+    {
+      size_t n4 = n >> 2;
+      do
+	{
+	  if (__builtin_expect (s1len-- == 0, 0))
+	    __chk_fail ();
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    return s;
+	  if (__builtin_expect (s1len-- == 0, 0))
+	    __chk_fail ();
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    return s;
+	  if (__builtin_expect (s1len-- == 0, 0))
+	    __chk_fail ();
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    return s;
+	  if (__builtin_expect (s1len-- == 0, 0))
+	    __chk_fail ();
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    return s;
+	} while (--n4 > 0);
+      n &= 3;
+    }
+
+  while (n > 0)
+    {
+      if (__builtin_expect (s1len-- == 0, 0))
+	__chk_fail ();
+      c = *s2++;
+      *++s1 = c;
+      if (c == '\0')
+	return s;
+      n--;
+    }
+
+  if (c != '\0')
+    {
+      if (__builtin_expect (s1len-- == 0, 0))
+	__chk_fail ();
+      *++s1 = '\0';
+    }
+
+  return s;
+}
diff --git a/sysdeps/generic/strncpy_chk.c b/sysdeps/generic/strncpy_chk.c
new file mode 100644
index 0000000000..bdede7738b
--- /dev/null
+++ b/sysdeps/generic/strncpy_chk.c
@@ -0,0 +1,89 @@
+/* Copyright (C) 1991, 1997, 2003, 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; 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>
+
+
+char *
+__strncpy_chk (s1, s2, n, s1len)
+     char *s1;
+     const char *s2;
+     size_t n;
+     size_t s1len;
+{
+  reg_char c;
+  char *s = s1;
+
+  if (__builtin_expect (s1len < n, 0))
+    __chk_fail ();
+
+  --s1;
+
+  if (n >= 4)
+    {
+      size_t n4 = n >> 2;
+
+      for (;;)
+	{
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    break;
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    break;
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    break;
+	  c = *s2++;
+	  *++s1 = c;
+	  if (c == '\0')
+	    break;
+	  if (--n4 == 0)
+	    goto last_chars;
+	}
+      n = n - (s1 - s) - 1;
+      if (n == 0)
+	return s;
+      goto zero_fill;
+    }
+
+ last_chars:
+  n &= 3;
+  if (n == 0)
+    return s;
+
+  do
+    {
+      c = *s2++;
+      *++s1 = c;
+      if (--n == 0)
+	return s;
+    }
+  while (c != '\0');
+
+ zero_fill:
+  do
+    *++s1 = '\0';
+  while (--n > 0);
+
+  return s;
+}
diff --git a/sysdeps/i386/i686/memcpy.S b/sysdeps/i386/i686/memcpy.S
index 865967c5c8..00e84ec2e5 100644
--- a/sysdeps/i386/i686/memcpy.S
+++ b/sysdeps/i386/i686/memcpy.S
@@ -1,7 +1,7 @@
 /* Copy memory block and return pointer to beginning of destination block
    For Intel 80x86, x>=6.
    This file is part of the GNU C Library.
-   Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -31,6 +31,13 @@
 #define LEN	SRC+PTR_SIZE
 
 	.text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memcpy_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	HIDDEN_JUMPTARGET (__chk_fail)
+END (__memcpy_chk)
+#endif
 ENTRY (BP_SYM (memcpy))
 	ENTER
 
diff --git a/sysdeps/i386/i686/memcpy_chk.S b/sysdeps/i386/i686/memcpy_chk.S
new file mode 100644
index 0000000000..561263f9bf
--- /dev/null
+++ b/sysdeps/i386/i686/memcpy_chk.S
@@ -0,0 +1,35 @@
+/* Checking memcpy for x86-64.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+	/* For libc.so this is defined in memcpy.S.
+	   For libc.a, this is a separate source to avoid
+	   memcpy bringing in __chk_fail and all routines
+	   it calls.  */
+        .text
+ENTRY (__memcpy_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	__chk_fail
+	jmp	memcpy
+END (__memcpy_chk)
+#endif
diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S
index 421b4effda..951e139ad4 100644
--- a/sysdeps/i386/i686/memmove.S
+++ b/sysdeps/i386/i686/memmove.S
@@ -1,7 +1,7 @@
 /* Copy memory block and return pointer to beginning of destination block
    For Intel 80x86, x>=6.
    This file is part of the GNU C Library.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2003.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -31,6 +31,13 @@
 #define LEN	SRC+PTR_SIZE
 
 	.text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memmove_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	HIDDEN_JUMPTARGET (__chk_fail)
+END (__memmove_chk)
+#endif
 ENTRY (BP_SYM (memmove))
 	ENTER
 
diff --git a/sysdeps/i386/i686/memmove_chk.S b/sysdeps/i386/i686/memmove_chk.S
new file mode 100644
index 0000000000..23382ea8bf
--- /dev/null
+++ b/sysdeps/i386/i686/memmove_chk.S
@@ -0,0 +1,35 @@
+/* Checking memmove for x86-64.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+	/* For libc.so this is defined in memmove.S.
+	   For libc.a, this is a separate source to avoid
+	   memmove bringing in __chk_fail and all routines
+	   it calls.  */
+        .text
+ENTRY (__memmove_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	__chk_fail
+	jmp	memmove
+END (__memmove_chk)
+#endif
diff --git a/sysdeps/i386/i686/mempcpy.S b/sysdeps/i386/i686/mempcpy.S
index 3ea89d4a17..843a35823a 100644
--- a/sysdeps/i386/i686/mempcpy.S
+++ b/sysdeps/i386/i686/mempcpy.S
@@ -31,6 +31,13 @@
 #define LEN	SRC+PTR_SIZE
 
 	.text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__mempcpy_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	HIDDEN_JUMPTARGET (__chk_fail)
+END (__mempcpy_chk)
+#endif
 ENTRY (BP_SYM (__mempcpy))
 	ENTER
 
diff --git a/sysdeps/i386/i686/mempcpy_chk.S b/sysdeps/i386/i686/mempcpy_chk.S
new file mode 100644
index 0000000000..dc9c6095f0
--- /dev/null
+++ b/sysdeps/i386/i686/mempcpy_chk.S
@@ -0,0 +1,35 @@
+/* Checking mempcpy for x86-64.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+	/* For libc.so this is defined in mempcpy.S.
+	   For libc.a, this is a separate source to avoid
+	   mempcpy bringing in __chk_fail and all routines
+	   it calls.  */
+        .text
+ENTRY (__mempcpy_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	__chk_fail
+	jmp	mempcpy
+END (__mempcpy_chk)
+#endif
diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S
index 4ddcb39731..561188ffec 100644
--- a/sysdeps/i386/i686/memset.S
+++ b/sysdeps/i386/i686/memset.S
@@ -39,6 +39,13 @@
 #endif
 
         .text
+#if defined PIC && !defined NOT_IN_libc && !BZERO_P
+ENTRY (__memset_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
 ENTRY (BP_SYM (memset))
 	ENTER
 
diff --git a/sysdeps/i386/i686/memset_chk.S b/sysdeps/i386/i686/memset_chk.S
new file mode 100644
index 0000000000..d178654994
--- /dev/null
+++ b/sysdeps/i386/i686/memset_chk.S
@@ -0,0 +1,35 @@
+/* Checking memset for x86-64.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+	/* For libc.so this is defined in memset.S.
+	   For libc.a, this is a separate source to avoid
+	   memset bringing in __chk_fail and all routines
+	   it calls.  */
+        .text
+ENTRY (__memset_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	__chk_fail
+	jmp	memset
+END (__memset_chk)
+#endif
diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile
index 5f3da04b47..8677515cd9 100644
--- a/sysdeps/mach/hurd/Makefile
+++ b/sysdeps/mach/hurd/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1993,94,95,96,97,98,99,2000,2001,2002, 2003
+# Copyright (C) 1993,94,95,96,97,98,99,2000,2001,2002, 2003, 2004
 #	Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
@@ -177,14 +177,14 @@ ifeq (yes,$(build-static))
 link-libc-static := -Wl,-\( \
 		    $(patsubst %,$(common-objpfx)%.a,\
 			       libc mach/libmachuser hurd/libhurduser) \
-		    $(gnulib) -Wl,-\)
+		    $(static-gnulib) -Wl,-\)
 else
 ifeq (yes,$(build-shared))
 # We can try to link the programs with lib*_pic.a...
 link-libc-static := $(link-libc) -Wl,-\( \
 		    $(patsubst %,$(common-objpfx)%_pic.a,\
 			       libc mach/libmachuser hurd/libhurduser) \
-		    $(gnulib) -Wl,-\)
+		    $(static-gnulib) -Wl,-\)
 endif
 endif
 
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index 606a1dd043..06960716b9 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -101,8 +101,8 @@ weak_extern (__cache_line_size)
    mapped somewhere else.  */
 
 ElfW(Addr)
-__elf_preferred_address(struct link_map *loader, size_t maplength,
-			ElfW(Addr) mapstartpref)
+__elf_preferred_address (struct link_map *loader, size_t maplength,
+			 ElfW(Addr) mapstartpref)
 {
   ElfW(Addr) low, high;
   struct link_map *l;
@@ -343,8 +343,8 @@ __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
 }
 
 Elf32_Addr
-__elf_machine_fixup_plt(struct link_map *map, const Elf32_Rela *reloc,
-			Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
+__elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+			 Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
 {
   Elf32_Sword delta = finaladdr - (Elf32_Word) reloc_addr;
   if (delta << 6 >> 6 == delta)
diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c
index 62008f63ca..38ef805cd5 100644
--- a/sysdeps/unix/sysv/linux/adjtime.c
+++ b/sysdeps/unix/sysv/linux/adjtime.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995, 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 1998, 2002, 2004
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -51,9 +52,7 @@ extern int INTUSE(__adjtimex) (struct timex *__ntx);
 #endif
 
 LINKAGE int
-ADJTIME (itv, otv)
-     const struct TIMEVAL *itv;
-     struct TIMEVAL *otv;
+ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
 {
   struct TIMEX tntx;
 
diff --git a/sysdeps/unix/sysv/linux/alpha/adjtime.c b/sysdeps/unix/sysv/linux/alpha/adjtime.c
index f8b272e9ce..e206cb4727 100644
--- a/sysdeps/unix/sysv/linux/alpha/adjtime.c
+++ b/sysdeps/unix/sysv/linux/alpha/adjtime.c
@@ -87,14 +87,15 @@ compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
 #define TIMEVAL		timeval
 #undef TIMEX
 #define TIMEX		timex
-#undef ADJTIME
-#define ADJTIME		__adjtime_tv64
 #undef ADJTIMEX
 #define ADJTIMEX(x)	INLINE_SYSCALL (adjtimex, 1, x)
+
 #undef LINKAGE
+#undef ADJTIME
+#if !defined __ASSUME_TIMEVAL64
 #define LINKAGE		static
-
-LINKAGE int ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv);
+#define ADJTIME		__adjtime_tv64
+#endif
 
 #include <sysdeps/unix/sysv/linux/adjtime.c>
 #include <stdbool.h>
@@ -135,8 +136,6 @@ __adjtime (itv, otv)
 
   return ret;
 }
-#else
-strong_alias (__adjtime_tv64, __adjtime);
 #endif
 
 versioned_symbol (libc, __adjtime, adjtime, GLIBC_2_1);
diff --git a/sysdeps/unix/sysv/linux/alpha/register-dump.h b/sysdeps/unix/sysv/linux/alpha/register-dump.h
new file mode 100644
index 0000000000..d55899a2c1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/register-dump.h
@@ -0,0 +1,161 @@
+/* Dump registers.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stddef.h>
+#include <sys/uio.h>
+
+/* We will print the register dump in this format:
+
+    V0: XXXXXXXXXXXXXXXX    T0: XXXXXXXXXXXXXXXX    T1: XXXXXXXXXXXXXXXX
+    T2: XXXXXXXXXXXXXXXX    T3: XXXXXXXXXXXXXXXX    T4: XXXXXXXXXXXXXXXX
+    T5: XXXXXXXXXXXXXXXX    T6: XXXXXXXXXXXXXXXX    T7: XXXXXXXXXXXXXXXX
+    S0: XXXXXXXXXXXXXXXX    S1: XXXXXXXXXXXXXXXX    S2: XXXXXXXXXXXXXXXX
+    S3: XXXXXXXXXXXXXXXX    S4: XXXXXXXXXXXXXXXX    S5: XXXXXXXXXXXXXXXX
+    S6: XXXXXXXXXXXXXXXX    A0: XXXXXXXXXXXXXXXX    A1: XXXXXXXXXXXXXXXX
+    A2: XXXXXXXXXXXXXXXX    A3: XXXXXXXXXXXXXXXX    A4: XXXXXXXXXXXXXXXX
+    A5: XXXXXXXXXXXXXXXX    T8: XXXXXXXXXXXXXXXX    T9: XXXXXXXXXXXXXXXX
+   T10: XXXXXXXXXXXXXXXX   T11: XXXXXXXXXXXXXXXX    RA: XXXXXXXXXXXXXXXX
+   T12: XXXXXXXXXXXXXXXX    AT: XXXXXXXXXXXXXXXX    GP: XXXXXXXXXXXXXXXX
+    SP: XXXXXXXXXXXXXXXX    PC: XXXXXXXXXXXXXXXX
+  
+   FP0: XXXXXXXXXXXXXXXX   FP1: XXXXXXXXXXXXXXXX   FP2: XXXXXXXXXXXXXXXX
+   FP3: XXXXXXXXXXXXXXXX   FP4: XXXXXXXXXXXXXXXX   FP5: XXXXXXXXXXXXXXXX
+   FP6: XXXXXXXXXXXXXXXX   FP7: XXXXXXXXXXXXXXXX   FP8: XXXXXXXXXXXXXXXX
+   FP9: XXXXXXXXXXXXXXXX  FP10: XXXXXXXXXXXXXXXX  FP11: XXXXXXXXXXXXXXXX
+  FP12: XXXXXXXXXXXXXXXX  FP13: XXXXXXXXXXXXXXXX  FP14: XXXXXXXXXXXXXXXX
+  FP15: XXXXXXXXXXXXXXXX  FP16: XXXXXXXXXXXXXXXX  FP17: XXXXXXXXXXXXXXXX
+  FP18: XXXXXXXXXXXXXXXX  FP19: XXXXXXXXXXXXXXXX  FP20: XXXXXXXXXXXXXXXX
+  FP21: XXXXXXXXXXXXXXXX  FP22: XXXXXXXXXXXXXXXX  FP23: XXXXXXXXXXXXXXXX
+  FP24: XXXXXXXXXXXXXXXX  FP25: XXXXXXXXXXXXXXXX  FP26: XXXXXXXXXXXXXXXX
+  FP27: XXXXXXXXXXXXXXXX  FP28: XXXXXXXXXXXXXXXX  FP29: XXXXXXXXXXXXXXXX
+  FP30: XXXXXXXXXXXXXXXX  FPCR: XXXXXXXXXXXXXXXX
+  
+   TA0: XXXXXXXXXXXXXXXX   TA1: XXXXXXXXXXXXXXXX   TA2: XXXXXXXXXXXXXXXX
+*/
+
+#define NREGS (32+32+3)
+
+static const char regnames[NREGS][8] = 
+{
+  "    V0: ", "    T0: ", "    T1: ",
+  "    T2: ", "    T3: ", "    T4: ",
+  "    T5: ", "    T6: ", "    T7: ",
+  "    S0: ", "    S1: ", "    S2: ",
+  "    S3: ", "    S4: ", "    S5: ",
+  "    S6: ", "    A0: ", "    A1: ",
+  "    A2: ", "    A3: ", "    A4: ",
+  "    A5: ", "    T8: ", "    T9: ",
+  "   T10: ", "   T11: ", "    RA: ",
+  "   T12: ", "    AT: ", "    GP: ",
+  "    SP: ", "    PC: ",
+
+  "   FP0: ", "   FP1: ", "   FP2: ",
+  "   FP3: ", "   FP4: ", "   FP5: ",
+  "   FP6: ", "   FP7: ", "   FP8: ",
+  "   FP9: ", "  FP10: ", "  FP11: ",
+  "  FP12: ", "  FP13: ", "  FP14: ",
+  "  FP15: ", "  FP16: ", "  FP17: ",
+  "  FP18: ", "  FP19: ", "  FP20: ",
+  "  FP21: ", "  FP22: ", "  FP23: ",
+  "  FP24: ", "  FP25: ", "  FP26: ",
+  "  FP27: ", "  FP28: ", "  FP29: ",
+  "  FP30: ", "  FPCR: ",
+
+  "   TA0: ", "   TA1: ", "   TA2: "
+};
+
+#define O(FIELD, LF)  offsetof(struct sigcontext, FIELD) + LF
+
+static const int offsets[NREGS] = 
+{
+  O(sc_regs[0], 0),  O(sc_regs[1], 0),  O(sc_regs[2], 1),
+  O(sc_regs[3], 0),  O(sc_regs[4], 0),  O(sc_regs[5], 1),
+  O(sc_regs[6], 0),  O(sc_regs[7], 0),  O(sc_regs[8], 1),
+  O(sc_regs[9], 0),  O(sc_regs[10], 0), O(sc_regs[11], 1),
+  O(sc_regs[12], 0), O(sc_regs[13], 0), O(sc_regs[14], 1),
+  O(sc_regs[15], 0), O(sc_regs[16], 0), O(sc_regs[17], 1),
+  O(sc_regs[18], 0), O(sc_regs[19], 0), O(sc_regs[20], 1),
+  O(sc_regs[21], 0), O(sc_regs[22], 0), O(sc_regs[23], 1),
+  O(sc_regs[24], 0), O(sc_regs[25], 0), O(sc_regs[26], 1),
+  O(sc_regs[27], 0), O(sc_regs[28], 0), O(sc_regs[29], 1),
+  O(sc_regs[30], 0), O(sc_pc, 2),
+
+  O(sc_fpregs[0], 0),  O(sc_fpregs[1], 0),  O(sc_fpregs[2], 1),
+  O(sc_fpregs[3], 0),  O(sc_fpregs[4], 0),  O(sc_fpregs[5], 1),
+  O(sc_fpregs[6], 0),  O(sc_fpregs[7], 0),  O(sc_fpregs[8], 1),
+  O(sc_fpregs[9], 0),  O(sc_fpregs[10], 0), O(sc_fpregs[11], 1),
+  O(sc_fpregs[12], 0), O(sc_fpregs[13], 0), O(sc_fpregs[14], 1),
+  O(sc_fpregs[15], 0), O(sc_fpregs[16], 0), O(sc_fpregs[17], 1),
+  O(sc_fpregs[18], 0), O(sc_fpregs[19], 0), O(sc_fpregs[20], 1),
+  O(sc_fpregs[21], 0), O(sc_fpregs[22], 0), O(sc_fpregs[23], 1),
+  O(sc_fpregs[24], 0), O(sc_fpregs[25], 0), O(sc_fpregs[26], 1),
+  O(sc_fpregs[27], 0), O(sc_fpregs[28], 0), O(sc_fpregs[29], 1),
+  O(sc_fpregs[30], 0), O(sc_fpcr, 2),
+
+  O(sc_traparg_a0, 0),  O(sc_traparg_a1, 0),  O(sc_traparg_a2, 1)
+};
+
+#undef O
+
+static const char linefeed[2] = "\n\n";
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+  char regs[NREGS][16];
+  struct iovec iov[2*NREGS+24];
+  size_t iov_i = 0, i, j;
+  
+#define ADD_MEM(str, len)			\
+  (iov[iov_i].iov_base = (void *)(str),		\
+   iov[iov_i].iov_len = len,			\
+   ++iov_i)
+
+#define ADD_STRING(str) ADD_MEM(str, strlen(str))
+
+  ADD_STRING ("Register dump:\n\n");
+
+  for (i = 0; i < NREGS; ++i)
+    {
+      int this_offset, this_lf;
+      unsigned long val;
+      
+      this_offset = offsets[i];
+      this_lf = this_offset & 7;
+      this_offset &= -8;
+
+      val = *(unsigned long *)((char *)ctx + this_offset);
+
+      for (j = 0; j < 16; ++j)
+	{
+	  unsigned long x = (val >> (64 - (j + 1) * 4)) & 15;
+	  x += x < 10 ? '0' : 'a' - 10;
+	  regs[i][j] = x;
+	}
+
+      ADD_MEM (regnames[i], 8);
+      ADD_MEM (regs[i], 16);
+      if (this_lf)
+	ADD_MEM (linefeed, this_lf);
+    }
+
+  writev (fd, iov, iov_i);
+}
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
index eb6f4f0758..16c5dcbc5b 100644
--- a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2004 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,10 +16,10 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#define SIGCONTEXT struct sigcontext
-#define SIGCONTEXT_EXTRA_ARGS
-#define GET_PC(ctx)	((void *) (ctx).sc_pc)
-#define GET_FRAME(ctx)	((void *) (ctx).sc_regs[15])
-#define GET_STACK(ctx)	((void *) (ctx).sc_regs[30])
+#define SIGCONTEXT int _code, struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS _code,
+#define GET_PC(ctx)	((void *) (ctx)->sc_pc)
+#define GET_FRAME(ctx)	((void *) (ctx)->sc_regs[15])
+#define GET_STACK(ctx)	((void *) (ctx)->sc_regs[30])
 #define CALL_SIGHANDLER(handler, signo, ctx) \
   (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/sysdeps/unix/sysv/linux/i386/syscall.S b/sysdeps/unix/sysv/linux/i386/syscall.S
index cd7dc65a5f..b569650b24 100644
--- a/sysdeps/unix/sysv/linux/i386/syscall.S
+++ b/sysdeps/unix/sysv/linux/i386/syscall.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1998, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1998, 2002, 2004 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
@@ -24,11 +24,11 @@
 	.text
 ENTRY (syscall)
 
-	PUSHARGS_5		/* Save register contents.  */
-	_DOARGS_5(36)		/* Load arguments.  */
-	movl 16(%esp), %eax	/* Load syscall number into %eax.  */
+	PUSHARGS_6		/* Save register contents.  */
+	_DOARGS_6(44)		/* Load arguments.  */
+	movl 20(%esp), %eax	/* Load syscall number into %eax.  */
 	ENTER_KERNEL		/* Do the system call.  */
-	POPARGS_5		/* Restore register contents.  */
+	POPARGS_6		/* Restore register contents.  */
 	cmpl $-4095, %eax	/* Check %eax for error.  */
 	jae SYSCALL_ERROR_LABEL	/* Jump to error handler if error.  */
 L(pseudo_end):
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 37e7459a9c..af75d4c51a 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -297,6 +297,13 @@ __i686.get_pc_thunk.reg:						      \
 #define _DOARGS_5(n)	movl n(%esp), %edi; _DOARGS_4 (n-4)
 #define _POPARGS_5	_POPARGS_4; popl %edi; L(POPDI1):
 
+#define PUSHARGS_6	_PUSHARGS_6
+#define DOARGS_6	_DOARGS_6 (36)
+#define POPARGS_6	_POPARGS_6
+#define _PUSHARGS_6	pushl %ebp; L(PUSHBP1): _PUSHARGS_5
+#define _DOARGS_6(n)	movl n(%esp), %ebp; _DOARGS_5 (n-4)
+#define _POPARGS_6	_POPARGS_5; popl %ebp; L(POPBP1):
+
 #else	/* !__ASSEMBLER__ */
 
 /* We need some help from the assembler to generate optimal code.  We
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
index 1f56671ba0..5eaf7a276b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2003, 2004 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
@@ -275,7 +275,8 @@
 	_sys_result;							\
 })
 
-#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
+#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
+	"$14", "$15", "$24", "$25", "memory"
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
index 2b2aefa15d..be343aabca 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2003, 2004 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
@@ -235,7 +235,8 @@
 	_sys_result;							\
 })
 
-#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
+#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
+	"$14", "$15", "$24", "$25", "memory"
 #endif /* __ASSEMBLER__ */
 
 #endif /* linux/mips/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
index e2d8707d25..f30a465081 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2003, 2004 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
@@ -235,7 +235,8 @@
 	_sys_result;							\
 })
 
-#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
+#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
+	"$14", "$15", "$24", "$25", "memory"
 #endif /* __ASSEMBLER__ */
 
 #endif /* linux/mips/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/readonly-area.c b/sysdeps/unix/sysv/linux/readonly-area.c
new file mode 100644
index 0000000000..ce5321bcef
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/readonly-area.c
@@ -0,0 +1,90 @@
+/* Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libio/libioP.h"
+
+/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
+   Return -1 if it is writable.  */
+
+int
+__readonly_area (const char *ptr, size_t size)
+{
+  const void *ptr_end = ptr + size;
+
+  FILE *fp = fopen ("/proc/self/maps", "rc");
+  if (fp == NULL)
+    return -1;
+
+  /* We need no locking.  */
+  __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+  char *line = NULL;
+  size_t linelen = 0;
+
+  while (! feof_unlocked (fp))
+    {
+      if (_IO_getdelim (&line, &linelen, '\n', fp) <= 0)
+	break;
+
+      char *p;
+      uintptr_t from = strtoul (line, &p, 16);
+
+      if (p == line || *p++ != '-')
+	break;
+
+      char *q;
+      uintptr_t to = strtoul (p, &q, 16);
+
+      if (q == p || *q++ != ' ')
+	break;
+
+      if (from < (uintptr_t) ptr_end && to > (uintptr_t) ptr)
+	{
+	  /* Found an entry that at least partially covers the area.  */
+	  if (*q++ != 'r' || *q++ != '-')
+	    break;
+
+	  if (from <= (uintptr_t) ptr && to >= (uintptr_t) ptr_end)
+	    {
+	      size = 0;
+	      break;
+	    }
+	  else if (from <= (uintptr_t) ptr)
+	    size -= to - (uintptr_t) ptr;
+	  else if (to >= (uintptr_t) ptr_end)
+	    size -= (uintptr_t) ptr_end - from;
+	  else
+	    size -= to - from;
+
+	  if (!size)
+	    break;
+	}
+    }
+
+  fclose (fp);
+  free (line);
+
+  /* If the whole area between ptr and ptr_end is covered by read-only
+     VMAs, return 1.  Otherwise return -1.  */
+  return size == 0 ? 1 : -1;
+}
diff --git a/sysdeps/x86_64/memcpy.S b/sysdeps/x86_64/memcpy.S
index de47688241..5f06198b5d 100644
--- a/sysdeps/x86_64/memcpy.S
+++ b/sysdeps/x86_64/memcpy.S
@@ -29,6 +29,12 @@
 #define MEMPCPY_P (defined memcpy)
 
         .text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memcpy_chk)
+	cmpq	%rdx, %rcx
+	jb	HIDDEN_JUMPTARGET (__chk_fail)
+END (__memcpy_chk)
+#endif
 ENTRY (BP_SYM (memcpy))
 	/* Cutoff for the big loop is a size of 32 bytes since otherwise
 	   the loop will never be entered.  */
diff --git a/sysdeps/x86_64/memcpy_chk.S b/sysdeps/x86_64/memcpy_chk.S
new file mode 100644
index 0000000000..c5251ea2d4
--- /dev/null
+++ b/sysdeps/x86_64/memcpy_chk.S
@@ -0,0 +1,34 @@
+/* Checking memcpy for x86-64.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+	/* For libc.so this is defined in memcpy.S.
+	   For libc.a, this is a separate source to avoid
+	   memcpy bringing in __chk_fail and all routines
+	   it calls.  */
+        .text
+ENTRY (__memcpy_chk)
+	cmpq	%rdx, %rcx
+	jb	__chk_fail
+	jmp	memcpy
+END (__memcpy_chk)
+#endif
diff --git a/sysdeps/x86_64/mempcpy.S b/sysdeps/x86_64/mempcpy.S
index 03aa743fba..4558a1699a 100644
--- a/sysdeps/x86_64/mempcpy.S
+++ b/sysdeps/x86_64/mempcpy.S
@@ -1,4 +1,5 @@
 #define memcpy __mempcpy
+#define __memcpy_chk __mempcpy_chk
 #include <sysdeps/x86_64/memcpy.S>
 
 libc_hidden_def (BP_SYM (__mempcpy))
diff --git a/sysdeps/x86_64/mempcpy_chk.S b/sysdeps/x86_64/mempcpy_chk.S
new file mode 100644
index 0000000000..c333a4adb3
--- /dev/null
+++ b/sysdeps/x86_64/mempcpy_chk.S
@@ -0,0 +1,34 @@
+/* Checking mempcpy for x86-64.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+	/* For libc.so this is defined in memcpy.S.
+	   For libc.a, this is a separate source to avoid
+	   mempcpy bringing in __chk_fail and all routines
+	   it calls.  */
+        .text
+ENTRY (__mempcpy_chk)
+	cmpq	%rdx, %rcx
+	jb	__chk_fail
+	jmp	mempcpy
+END (__mempcpy_chk)
+#endif
diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S
index 29afa63e7e..6c47f4c863 100644
--- a/sysdeps/x86_64/memset.S
+++ b/sysdeps/x86_64/memset.S
@@ -1,6 +1,6 @@
 /* memset/bzero -- set memory area to CH/0
    Optimized version for x86-64.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>.
 
@@ -32,6 +32,12 @@
 #define LARGE $120000
 
         .text
+#if !BZERO_P && defined PIC && !defined NOT_IN_libc
+ENTRY (__memset_chk)
+	cmpq	%rdx, %rcx
+	jb	HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
 ENTRY (memset)
 #if BZERO_P
 	mov	%rsi,%rdx	/* Adjust parameter.  */
diff --git a/sysdeps/x86_64/memset_chk.S b/sysdeps/x86_64/memset_chk.S
new file mode 100644
index 0000000000..e62cb58cc0
--- /dev/null
+++ b/sysdeps/x86_64/memset_chk.S
@@ -0,0 +1,34 @@
+/* Checking memset for x86-64.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+	/* For libc.so this is defined in memset.S.
+	   For libc.a, this is a separate source to avoid
+	   memset bringing in __chk_fail and all routines
+	   it calls.  */
+        .text
+ENTRY (__memset_chk)
+	cmpq	%rdx, %rcx
+	jb	__chk_fail
+	jmp	memset
+END (__memset_chk)
+#endif
diff --git a/sysdeps/x86_64/stpcpy_chk.S b/sysdeps/x86_64/stpcpy_chk.S
new file mode 100644
index 0000000000..905e8d7ee3
--- /dev/null
+++ b/sysdeps/x86_64/stpcpy_chk.S
@@ -0,0 +1,3 @@
+#define USE_AS_STPCPY_CHK
+#define STRCPY_CHK __stpcpy_chk
+#include <sysdeps/x86_64/strcpy_chk.S>
diff --git a/sysdeps/x86_64/strcpy_chk.S b/sysdeps/x86_64/strcpy_chk.S
new file mode 100644
index 0000000000..364331553a
--- /dev/null
+++ b/sysdeps/x86_64/strcpy_chk.S
@@ -0,0 +1,211 @@
+/* strcpy/stpcpy checking implementation for x86-64.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+   Adopted into checking version by Jakub Jelinek <jakub@redhat.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#ifndef USE_AS_STPCPY_CHK
+# define STRCPY_CHK __strcpy_chk
+#endif
+
+	.text
+ENTRY (STRCPY_CHK)
+	movq	%rsi, %rcx	/* Source register. */
+	andl	$7, %ecx	/* mask alignment bits */
+#ifndef USE_AS_STPCPY_CHK
+	movq	%rdi, %r10	/* Duplicate destination pointer.  */
+#endif
+	jz 5f			/* aligned => start loop */
+
+	cmpq	$8, %rdx	/* Check if only few bytes left in
+				   destination.  */
+	jb	50f
+
+	subq	$8, %rcx	/* We need to align to 8 bytes.  */
+	addq	%rcx, %rdx	/* Subtract count of stored bytes
+				   in the cycle below from destlen.  */
+
+	/* Search the first bytes directly.  */
+0:
+	movb	(%rsi), %al	/* Fetch a byte */
+	testb	%al, %al	/* Is it NUL? */
+	movb	%al, (%rdi)	/* Store it */
+	jz	4f		/* If it was NUL, done! */
+	incq	%rsi
+	incq	%rdi
+	incl	%ecx
+	jnz	0b
+
+5:
+	movq $0xfefefefefefefeff,%r8
+	cmpq	$32, %rdx	/* Are there enough bytes in destination
+				   for the next unrolled round?  */
+	jb	60f		/* If not, avoid the unrolled loop.  */
+
+	/* Now the sources is aligned.  Unfortunatly we cannot force
+	   to have both source and destination aligned, so ignore the
+	   alignment of the destination.  */
+	.p2align 4
+1:
+	/* 1st unroll.  */
+	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
+	addq	$8, %rsi	/* Adjust pointer for next word.  */
+	movq	%rax, %r9	/* Save a copy for NUL finding.  */
+	addq	%r8, %r9	/* add the magic value to the word.  We get
+				   carry bits reported for each byte which
+				   is *not* 0 */
+	jnc	3f		/* highest byte is NUL => return pointer */
+	xorq	%rax, %r9	/* (word+magic)^word */
+	orq	%r8, %r9	/* set all non-carry bits */
+	incq	%r9		/* add 1: if one carry bit was *not* set
+				   the addition will not result in 0.  */
+
+	jnz	3f		/* found NUL => return pointer */
+
+	movq	%rax, (%rdi)	/* Write value to destination.  */
+	addq	$8, %rdi	/* Adjust pointer.  */
+
+	/* 2nd unroll.  */
+	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
+	addq	$8, %rsi	/* Adjust pointer for next word.  */
+	movq	%rax, %r9	/* Save a copy for NUL finding.  */
+	addq	%r8, %r9	/* add the magic value to the word.  We get
+				   carry bits reported for each byte which
+				   is *not* 0 */
+	jnc	3f		/* highest byte is NUL => return pointer */
+	xorq	%rax, %r9	/* (word+magic)^word */
+	orq	%r8, %r9	/* set all non-carry bits */
+	incq	%r9		/* add 1: if one carry bit was *not* set
+				   the addition will not result in 0.  */
+
+	jnz	3f		/* found NUL => return pointer */
+
+	movq	%rax, (%rdi)	/* Write value to destination.  */
+	addq	$8, %rdi	/* Adjust pointer.  */
+
+	/* 3rd unroll.  */
+	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
+	addq	$8, %rsi	/* Adjust pointer for next word.  */
+	movq	%rax, %r9	/* Save a copy for NUL finding.  */
+	addq	%r8, %r9	/* add the magic value to the word.  We get
+				   carry bits reported for each byte which
+				   is *not* 0 */
+	jnc	3f		/* highest byte is NUL => return pointer */
+	xorq	%rax, %r9	/* (word+magic)^word */
+	orq	%r8, %r9	/* set all non-carry bits */
+	incq	%r9		/* add 1: if one carry bit was *not* set
+				   the addition will not result in 0.  */
+
+	jnz	3f		/* found NUL => return pointer */
+
+	movq	%rax, (%rdi)	/* Write value to destination.  */
+	addq	$8, %rdi	/* Adjust pointer.  */
+
+	/* 4th unroll.  */
+	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
+	addq	$8, %rsi	/* Adjust pointer for next word.  */
+	movq	%rax, %r9	/* Save a copy for NUL finding.  */
+	addq	%r8, %r9	/* add the magic value to the word.  We get
+				   carry bits reported for each byte which
+				   is *not* 0 */
+	jnc	3f		/* highest byte is NUL => return pointer */
+	xorq	%rax, %r9	/* (word+magic)^word */
+	orq	%r8, %r9	/* set all non-carry bits */
+	incq	%r9		/* add 1: if one carry bit was *not* set
+				   the addition will not result in 0.  */
+
+	jnz	3f		/* found NUL => return pointer */
+
+	subq	$32, %rdx	/* Adjust destlen.  */
+	movq	%rax, (%rdi)	/* Write value to destination.  */
+	addq	$8, %rdi	/* Adjust pointer.  */
+	cmpq	$32, %rdx	/* Are there enough bytes in destination
+				   for the next unrolled round?  */
+	jae	1b		/* Next iteration.  */
+
+60:
+	cmpq	$8, %rdx	/* Are there enough bytes in destination
+				   for the next unrolled round?  */
+	jb	50f		/* Now, copy and check byte by byte.  */
+
+	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
+	addq	$8, %rsi	/* Adjust pointer for next word.  */
+	movq	%rax, %r9	/* Save a copy for NUL finding.  */
+	addq	%r8, %r9	/* add the magic value to the word.  We get
+				   carry bits reported for each byte which
+				   is *not* 0 */
+	jnc	3f		/* highest byte is NUL => return pointer */
+	xorq	%rax, %r9	/* (word+magic)^word */
+	orq	%r8, %r9	/* set all non-carry bits */
+	incq	%r9		/* add 1: if one carry bit was *not* set
+				   the addition will not result in 0.  */
+
+	jnz	3f		/* found NUL => return pointer */
+
+	subq	$8, %rdx	/* Adjust destlen.  */
+	movq	%rax, (%rdi)	/* Write value to destination.  */
+	addq	$8, %rdi	/* Adjust pointer.  */
+	jmp	60b		/* Next iteration.  */
+
+	/* Do the last few bytes. %rax contains the value to write.
+	   The loop is unrolled twice.  */
+	.p2align 4
+3:
+	/* Note that stpcpy needs to return with the value of the NUL
+	   byte.  */
+	movb	%al, (%rdi)	/* 1st byte.  */
+	testb	%al, %al	/* Is it NUL.  */
+	jz	4f		/* yes, finish.  */
+	incq	%rdi		/* Increment destination.  */
+	movb	%ah, (%rdi)	/* 2nd byte.  */
+	testb	%ah, %ah	/* Is it NUL?.  */
+	jz	4f		/* yes, finish.  */
+	incq	%rdi		/* Increment destination.  */
+	shrq	$16, %rax	/* Shift...  */
+	jmp	3b		/* and look at next two bytes in %rax.  */
+
+51:
+	/* Search the bytes directly, checking for overflows.  */
+	incq	%rsi
+	incq	%rdi
+	decq	%rdx
+	jz	HIDDEN_JUMPTARGET (__chk_fail)
+52:
+	movb	(%rsi), %al	/* Fetch a byte */
+	testb	%al, %al	/* Is it NUL? */
+	movb	%al, (%rdi)	/* Store it */
+	jnz	51b		/* If it was NUL, done! */
+4:
+#ifdef USE_AS_STPCPY_CHK
+	movq	%rdi, %rax	/* Destination is return value.  */
+#else
+	movq	%r10, %rax	/* Source is return value.  */
+#endif
+	retq
+
+50:
+	testq	%rdx, %rdx
+	jnz	52b
+	jmp	HIDDEN_JUMPTARGET (__chk_fail)
+
+END (STRCPY_CHK)