summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)