summaryrefslogtreecommitdiff
path: root/debug
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
commit0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch)
tree2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /debug
parent7d58530341304d403a6626d7f7a1913165fe2f32 (diff)
downloadglibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz
2.5-18.1
Diffstat (limited to 'debug')
-rw-r--r--debug/Depend1
-rw-r--r--debug/Makefile51
-rw-r--r--debug/Versions21
-rw-r--r--debug/backtrace.c94
-rw-r--r--debug/backtracesyms.c58
-rw-r--r--debug/backtracesymsfd.c64
-rwxr-xr-xdebug/catchsegv.sh4
-rw-r--r--debug/chk_fail.c10
-rw-r--r--debug/confstr_chk.c30
-rw-r--r--debug/execinfo.h5
-rw-r--r--debug/fgets_chk.c67
-rw-r--r--debug/fgets_u_chk.c65
-rw-r--r--debug/fgetws_chk.c54
-rw-r--r--debug/fgetws_u_chk.c61
-rw-r--r--debug/fprintf_chk.c5
-rw-r--r--debug/fwprintf_chk.c45
-rw-r--r--debug/getcwd_chk.c31
-rw-r--r--debug/getdomainname_chk.c29
-rw-r--r--debug/getgroups_chk.c30
-rw-r--r--debug/gethostname_chk.c29
-rw-r--r--debug/getlogin_r_chk.c29
-rw-r--r--debug/getwd_chk.c34
-rw-r--r--debug/mbsnrtowcs_chk.c31
-rw-r--r--debug/mbsrtowcs_chk.c31
-rw-r--r--debug/mbstowcs_chk.c35
-rw-r--r--debug/memcpy_chk.c66
-rw-r--r--debug/memmove_chk.c98
-rw-r--r--debug/mempcpy_chk.c67
-rw-r--r--debug/memset_chk.c92
-rw-r--r--debug/pread64_chk.c30
-rw-r--r--debug/pread_chk.c30
-rw-r--r--debug/printf_chk.c5
-rw-r--r--debug/ptsname_r_chk.c29
-rw-r--r--debug/read_chk.c38
-rw-r--r--debug/readlink_chk.c38
-rw-r--r--debug/readlinkat_chk.c31
-rw-r--r--debug/readonly-area.c34
-rw-r--r--debug/realpath_chk.c60
-rw-r--r--debug/recv_chk.c30
-rw-r--r--debug/recvfrom_chk.c31
-rw-r--r--debug/segfault.c214
-rw-r--r--debug/snprintf_chk.c9
-rw-r--r--debug/sprintf_chk.c7
-rw-r--r--debug/stack_chk_fail.c33
-rw-r--r--debug/stack_chk_fail_local.c30
-rw-r--r--debug/stpcpy_chk.c45
-rw-r--r--debug/stpncpy_chk.c85
-rw-r--r--debug/strcat_chk.c58
-rw-r--r--debug/strcpy_chk.c68
-rw-r--r--debug/strncat_chk.c100
-rw-r--r--debug/strncpy_chk.c89
-rw-r--r--debug/swprintf_chk.c37
-rw-r--r--debug/tst-chk1.c847
-rw-r--r--debug/tst-lfschk1.c2
-rw-r--r--debug/tst-lfschk2.c2
-rw-r--r--debug/tst-lfschk3.c2
-rw-r--r--debug/ttyname_r_chk.c29
-rw-r--r--debug/vfprintf_chk.c6
-rw-r--r--debug/vfwprintf_chk.c43
-rw-r--r--debug/vprintf_chk.c5
-rw-r--r--debug/vsnprintf_chk.c10
-rw-r--r--debug/vsprintf_chk.c10
-rw-r--r--debug/vswprintf_chk.c75
-rw-r--r--debug/vwprintf_chk.c43
-rw-r--r--debug/warning-nop.c53
-rw-r--r--debug/wcpcpy_chk.c45
-rw-r--r--debug/wcpncpy_chk.c33
-rw-r--r--debug/wcrtomb_chk.c35
-rw-r--r--debug/wcscat_chk.c55
-rw-r--r--debug/wcscpy_chk.c61
-rw-r--r--debug/wcsncat_chk.c96
-rw-r--r--debug/wcsncpy_chk.c33
-rw-r--r--debug/wcsnrtombs_chk.c31
-rw-r--r--debug/wcsrtombs_chk.c31
-rw-r--r--debug/wcstombs_chk.c36
-rw-r--r--debug/wctomb_chk.c36
-rw-r--r--debug/wmemcpy_chk.c30
-rw-r--r--debug/wmemmove_chk.c30
-rw-r--r--debug/wmempcpy_chk.c31
-rw-r--r--debug/wmemset_chk.c30
-rw-r--r--debug/wprintf_chk.c46
-rwxr-xr-xdebug/xtrace.sh28
82 files changed, 4122 insertions, 60 deletions
diff --git a/debug/Depend b/debug/Depend
new file mode 100644
index 0000000000..f3e1156a4e
--- /dev/null
+++ b/debug/Depend
@@ -0,0 +1 @@
+localedata
diff --git a/debug/Makefile b/debug/Makefile
index 6df06116b7..9d9b6ac96a 100644
--- a/debug/Makefile
+++ b/debug/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1998-2001,2004,2005,2006 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,12 +24,27 @@ 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 \
+ strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \
sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
printf_chk fprintf_chk vprintf_chk vfprintf_chk \
- gets_chk chk_fail readonly-area
+ gets_chk chk_fail readonly-area fgets_chk fgets_u_chk \
+ read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
+ readlink_chk readlinkat_chk getwd_chk getcwd_chk \
+ realpath_chk ptsname_r_chk \
+ wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
+ wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
+ wcpncpy_chk \
+ swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \
+ vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \
+ confstr_chk getgroups_chk ttyname_r_chk getlogin_r_chk \
+ gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \
+ wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \
+ wcstombs_chk \
+ stack_chk_fail \
+ $(static-only-routines)
+static-only-routines := warning-nop stack_chk_fail_local
CFLAGS-backtrace.c = -fno-omit-frame-pointer
CFLAGS-sprintf_chk.c = -D_IO_MTSAFE_IO
@@ -41,9 +56,31 @@ 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)
+CFLAGS-fgets_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-fgets_u_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-swprintf_chk.c = -D_IO_MTSAFE_IO
+CFLAGS-vswprintf_chk.c = -D_IO_MTSAFE_IO
+CFLAGS-wprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-fwprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-vwprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-vfwprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-fgetws_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-fgetws_u_chk.c = -D_IO_MTSAFE_IO $(exceptions)
+CFLAGS-read_chk.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pread_chk.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-pread64_chk.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-recv_chk.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-recvfrom_chk.c = -fexceptions -fasynchronous-unwind-tables
+
+tst-chk1-ENV = LOCPATH=$(common-objpfx)localedata
+tst-chk2-ENV = LOCPATH=$(common-objpfx)localedata
+tst-chk3-ENV = LOCPATH=$(common-objpfx)localedata
+tst-lfschk1-ENV = LOCPATH=$(common-objpfx)localedata
+tst-lfschk2-ENV = LOCPATH=$(common-objpfx)localedata
+tst-lfschk3-ENV = LOCPATH=$(common-objpfx)localedata
tests = backtrace-tst tst-chk1 tst-chk2 tst-chk3 \
- test-strcpy_chk test-stpcpy_chk
+ tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk
extra-libs = libSegFault libpcprofile
extra-libs-others = $(extra-libs)
@@ -70,6 +107,8 @@ generated = catchsegv xtrace
include ../Rules
+sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,')
+
$(objpfx)catchsegv: catchsegv.sh $(common-objpfx)soversions.mk \
$(common-objpfx)config.make
slibpfx=`echo $(slibdir)|sed 's/lib\(64\|\)$$/\\\\\\\\$$LIB/'`; \
@@ -82,7 +121,7 @@ $(objpfx)pcprofiledump: $(objpfx)pcprofiledump.o
$(objpfx)xtrace: xtrace.sh
rm -f $@.new
sed -e 's|@BASH@|$(BASH)|' -e 's|@VERSION@|$(version)|' \
- -e 's|@SLIBDIR@|$(slibdir)|' -e 's|@BINDIR@|$(bindir)|' $^ > $@.new \
+ -e 's|@SLIBDIR@|$(sLIBdir)|' -e 's|@BINDIR@|$(bindir)|' $^ > $@.new \
&& rm -f $@ && mv $@.new $@ && chmod +x $@
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
diff --git a/debug/Versions b/debug/Versions
index 07d6fbb830..5c87af27c1 100644
--- a/debug/Versions
+++ b/debug/Versions
@@ -18,4 +18,25 @@ libc {
__printf_chk; __fprintf_chk; __vprintf_chk; __vfprintf_chk;
__gets_chk;
}
+ GLIBC_2.4 {
+ __fgets_chk; __fgets_unlocked_chk;
+ __read_chk; __pread_chk; __pread64_chk;
+ __readlink_chk; __getcwd_chk; __getwd_chk;
+ __recv_chk; __recvfrom_chk;
+ __realpath_chk; __ptsname_r_chk; __wctomb_chk;
+ __stpncpy_chk;
+ __wcscpy_chk; __wmemcpy_chk; __wmemmove_chk; __wmempcpy_chk; __wcpcpy_chk;
+ __wcsncpy_chk; __wcscat_chk; __wcsncat_chk; __wmemset_chk; __wcpncpy_chk;
+ __swprintf_chk; __vswprintf_chk; __wprintf_chk; __fwprintf_chk;
+ __vwprintf_chk; __vfwprintf_chk; __fgetws_chk; __fgetws_unlocked_chk;
+ __confstr_chk; __getgroups_chk; __ttyname_r_chk; __getlogin_r_chk;
+ __gethostname_chk; __getdomainname_chk; __wcrtomb_chk; __mbsnrtowcs_chk;
+ __wcsnrtombs_chk; __mbsrtowcs_chk; __wcsrtombs_chk; __mbstowcs_chk;
+ __wcstombs_chk;
+
+ __stack_chk_fail;
+ }
+ GLIBC_2.5 {
+ __readlinkat_chk;
+ }
}
diff --git a/debug/backtrace.c b/debug/backtrace.c
new file mode 100644
index 0000000000..f2d52372d5
--- /dev/null
+++ b/debug/backtrace.c
@@ -0,0 +1,94 @@
+/* Return backtrace of current program state. Generic version.
+ Copyright (C) 1998, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ 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 <execinfo.h>
+#include <signal.h>
+#include <frame.h>
+#include <sigcontextinfo.h>
+#include <bp-checks.h>
+#include <ldsodefs.h>
+
+/* This implementation assumes a stack layout that matches the defaults
+ used by gcc's `__builtin_frame_address' and `__builtin_return_address'
+ (FP is the frame pointer register):
+
+ +-----------------+ +-----------------+
+ FP -> | previous FP --------> | previous FP ------>...
+ | | | |
+ | return address | | return address |
+ +-----------------+ +-----------------+
+
+ */
+
+/* Get some notion of the current stack. Need not be exactly the top
+ of the stack, just something somewhere in the current frame. */
+#ifndef CURRENT_STACK_FRAME
+# define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
+#endif
+
+/* By default we assume that the stack grows downward. */
+#ifndef INNER_THAN
+# define INNER_THAN <
+#endif
+
+/* By default assume the `next' pointer in struct layout points to the
+ next struct layout. */
+#ifndef ADVANCE_STACK_FRAME
+# define ADVANCE_STACK_FRAME(next) BOUNDED_1 ((struct layout *) (next))
+#endif
+
+/* By default, the frame pointer is just what we get from gcc. */
+#ifndef FIRST_FRAME_POINTER
+# define FIRST_FRAME_POINTER __builtin_frame_address (0)
+#endif
+
+int
+__backtrace (array, size)
+ void **array;
+ int size;
+{
+ struct layout *current;
+ void *__unbounded top_frame;
+ void *__unbounded top_stack;
+ int cnt = 0;
+
+ top_frame = FIRST_FRAME_POINTER;
+ top_stack = CURRENT_STACK_FRAME;
+
+ /* We skip the call to this function, it makes no sense to record it. */
+ current = BOUNDED_1 ((struct layout *) top_frame);
+ while (cnt < size)
+ {
+ if ((void *) current INNER_THAN top_stack
+ || !((void *) current INNER_THAN __libc_stack_end))
+ /* This means the address is out of range. Note that for the
+ toplevel we see a frame pointer with value NULL which clearly is
+ out of range. */
+ break;
+
+ array[cnt++] = current->return_address;
+
+ current = ADVANCE_STACK_FRAME (current->next);
+ }
+
+ return cnt;
+}
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/debug/backtracesyms.c b/debug/backtracesyms.c
new file mode 100644
index 0000000000..db7ba36d0f
--- /dev/null
+++ b/debug/backtracesyms.c
@@ -0,0 +1,58 @@
+/* Return list with names for address in backtrace.
+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ 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 <execinfo.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Assume the worst for the width of an address. */
+#define WORD_WIDTH 16
+
+
+char **
+__backtrace_symbols (array, size)
+ void *const *array;
+ int size;
+{
+ int cnt;
+ size_t total = 0;
+ char **result;
+
+ /* We can compute the text size needed for the symbols since we print
+ them all as "[+0x<addr>]". */
+ total = size * (WORD_WIDTH + 6);
+
+ /* Allocate memory for the result. */
+ result = malloc (size * sizeof (char *) + total);
+ if (result != NULL)
+ {
+ char *last = (char *) (result + size);
+
+ for (cnt = 0; cnt < size; ++cnt)
+ {
+ result[cnt] = last;
+ last += 1 + sprintf (last, "[+%p]", array[cnt]);
+ }
+ }
+
+ return result;
+}
+weak_alias (__backtrace_symbols, backtrace_symbols)
diff --git a/debug/backtracesymsfd.c b/debug/backtracesymsfd.c
new file mode 100644
index 0000000000..b01f8b0094
--- /dev/null
+++ b/debug/backtracesymsfd.c
@@ -0,0 +1,64 @@
+/* Write formatted list with names for addresses in backtrace to a file.
+ Copyright (C) 1998, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ 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 <execinfo.h>
+#include <string.h>
+#include <sys/uio.h>
+
+#include <stdio-common/_itoa.h>
+#include <not-cancel.h>
+
+#if __ELF_NATIVE_CLASS == 32
+# define WORD_WIDTH 8
+#else
+/* We assume 64bits. */
+# define WORD_WIDTH 16
+#endif
+
+
+void
+__backtrace_symbols_fd (array, size, fd)
+ void *const *array;
+ int size;
+ int fd;
+{
+ struct iovec iov[3];
+ int cnt;
+
+ for (cnt = 0; cnt < size; ++cnt)
+ {
+ char buf[WORD_WIDTH];
+
+ iov[0].iov_base = (void *) "[0x";
+ iov[0].iov_len = 3;
+
+ iov[1].iov_base = _itoa_word ((unsigned long int) array[cnt],
+ &buf[WORD_WIDTH], 16, 0);
+ iov[1].iov_len = &buf[WORD_WIDTH] - (char *) iov[1].iov_base;
+
+ iov[2].iov_base = (void *) "]\n";
+ iov[2].iov_len = 2;
+
+ /* We prefer to use the non-cancelable interface if it is available. */
+ writev_not_cancel_no_status (fd, iov, 3);
+ }
+}
+weak_alias (__backtrace_symbols_fd, backtrace_symbols_fd)
+libc_hidden_def (__backtrace_symbols_fd)
diff --git a/debug/catchsegv.sh b/debug/catchsegv.sh
index 14556f712a..f4d971e34b 100755
--- a/debug/catchsegv.sh
+++ b/debug/catchsegv.sh
@@ -1,5 +1,5 @@
#! /bin/sh
-# Copyright (C) 1998, 1999, 2001, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2001,2003,2004,2006 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -39,7 +39,7 @@ if test $# -eq 0; then
;;
--v | --ve | --ver | --vers | --versi | --versio | --version)
echo 'catchsegv (GNU libc) @VERSION@'
- echo 'Copyright (C) 2004 Free Software Foundation, Inc.
+ echo 'Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Ulrich Drepper.'
diff --git a/debug/chk_fail.c b/debug/chk_fail.c
index dc1c3d70b6..0cfca295a9 100644
--- a/debug/chk_fail.c
+++ b/debug/chk_fail.c
@@ -1,5 +1,4 @@
-
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005 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
@@ -21,10 +20,15 @@
#include <stdlib.h>
+extern char **__libc_argv attribute_hidden;
+
void
__attribute__ ((noreturn))
__chk_fail (void)
{
- __libc_fatal ("*** buffer overflow detected ***\n");
+ /* The loop is added only to keep gcc happy. */
+ while (1)
+ __libc_message (2, "*** buffer overflow detected ***: %s terminated\n",
+ __libc_argv[0] ?: "<unknown>");
}
libc_hidden_def (__chk_fail)
diff --git a/debug/confstr_chk.c b/debug/confstr_chk.c
new file mode 100644
index 0000000000..dae7714fcf
--- /dev/null
+++ b/debug/confstr_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@readhat.com>, 20055.
+
+ 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 <unistd.h>
+
+
+size_t
+__confstr_chk (int name, char *buf, size_t len, size_t buflen)
+{
+ if (__builtin_expect (buflen < len, 0))
+ __chk_fail ();
+
+ return confstr (name, buf, len);
+}
diff --git a/debug/execinfo.h b/debug/execinfo.h
index fa9927c71a..c1614cc1f0 100644
--- a/debug/execinfo.h
+++ b/debug/execinfo.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2004, 2005 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
@@ -35,8 +35,7 @@ extern char **backtrace_symbols (void *__const *__array, int __size)
/* This function is similar to backtrace_symbols() but it writes the result
- immediately to a file and can therefore also be used in situations where
- malloc() is not usable anymore. */
+ immediately to a file. */
extern void backtrace_symbols_fd (void *__const *__array, int __size, int __fd)
__THROW __nonnull ((1));
diff --git a/debug/fgets_chk.c b/debug/fgets_chk.c
new file mode 100644
index 0000000000..27fbede7f0
--- /dev/null
+++ b/debug/fgets_chk.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2005
+ 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 "libioP.h"
+#include <stdio.h>
+#include <sys/param.h>
+
+char *
+__fgets_chk (buf, size, n, fp)
+ char *buf;
+ size_t size;
+ int n;
+ _IO_FILE *fp;
+{
+ _IO_size_t count;
+ char *result;
+ CHECK_FILE (fp, NULL);
+ if (n <= 0)
+ return NULL;
+ _IO_acquire_lock (fp);
+ /* 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 = fp->_IO_file_flags & _IO_ERR_SEEN;
+ fp->_IO_file_flags &= ~_IO_ERR_SEEN;
+ count = INTUSE(_IO_getline) (fp, buf, MIN ((size_t) n - 1, size), '\n', 1);
+ /* If we read in some bytes and errno is EAGAIN, that error will
+ be reported for next read. */
+ if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN)
+ && errno != EAGAIN))
+ result = NULL;
+ else if (count >= size)
+ __chk_fail ();
+ else
+ {
+ buf[count] = '\0';
+ result = buf;
+ }
+ fp->_IO_file_flags |= old_error;
+ _IO_release_lock (fp);
+ return result;
+}
diff --git a/debug/fgets_u_chk.c b/debug/fgets_u_chk.c
new file mode 100644
index 0000000000..324d7e371b
--- /dev/null
+++ b/debug/fgets_u_chk.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2005
+ 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 "libioP.h"
+#include <stdio.h>
+#include <sys/param.h>
+
+char *
+__fgets_unlocked_chk (buf, size, n, fp)
+ char *buf;
+ size_t size;
+ int n;
+ _IO_FILE *fp;
+{
+ _IO_size_t count;
+ char *result;
+ CHECK_FILE (fp, NULL);
+ if (n <= 0)
+ return NULL;
+ /* 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 = fp->_IO_file_flags & _IO_ERR_SEEN;
+ fp->_IO_file_flags &= ~_IO_ERR_SEEN;
+ count = INTUSE(_IO_getline) (fp, buf, MIN ((size_t) n - 1, size), '\n', 1);
+ /* If we read in some bytes and errno is EAGAIN, that error will
+ be reported for next read. */
+ if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN)
+ && errno != EAGAIN))
+ result = NULL;
+ else if (count >= size)
+ __chk_fail ();
+ else
+ {
+ buf[count] = '\0';
+ result = buf;
+ }
+ fp->_IO_file_flags |= old_error;
+ return result;
+}
diff --git a/debug/fgetws_chk.c b/debug/fgetws_chk.c
new file mode 100644
index 0000000000..d080ccb473
--- /dev/null
+++ b/debug/fgetws_chk.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2001, 2005
+ 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 "libioP.h"
+#include <wchar.h>
+#include <sys/param.h>
+
+wchar_t *
+__fgetws_chk (wchar_t *buf, size_t size, int n, _IO_FILE *fp)
+{
+ _IO_size_t count;
+ wchar_t *result;
+ int old_error;
+ CHECK_FILE (fp, NULL);
+ if (n <= 0)
+ return NULL;
+ _IO_acquire_lock (fp);
+ /* 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. */
+ old_error = fp->_IO_file_flags & _IO_ERR_SEEN;
+ fp->_IO_file_flags &= ~_IO_ERR_SEEN;
+ count = _IO_getwline (fp, buf, MIN ((size_t) n - 1, size), L'\n', 1);
+ /* If we read in some bytes and errno is EAGAIN, that error will
+ be reported for next read. */
+ if (count == 0 || (_IO_ferror_unlocked (fp) && errno != EAGAIN))
+ result = NULL;
+ else if (count >= size)
+ __chk_fail ();
+ else
+ {
+ buf[count] = '\0';
+ result = buf;
+ }
+ fp->_IO_file_flags |= old_error;
+ _IO_release_lock (fp);
+ return result;
+}
diff --git a/debug/fgetws_u_chk.c b/debug/fgetws_u_chk.c
new file mode 100644
index 0000000000..b6cc87b80d
--- /dev/null
+++ b/debug/fgetws_u_chk.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2005 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 "libioP.h"
+#include <wchar.h>
+#include <sys/param.h>
+
+wchar_t *
+__fgetws_unlocked_chk (wchar_t *buf, size_t size, int n, _IO_FILE *fp)
+{
+ _IO_size_t count;
+ wchar_t *result;
+ int old_error;
+ CHECK_FILE (fp, NULL);
+ if (n <= 0)
+ return NULL;
+ /* 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. */
+ old_error = fp->_IO_file_flags & _IO_ERR_SEEN;
+ fp->_IO_file_flags &= ~_IO_ERR_SEEN;
+ count = _IO_getwline (fp, buf, MIN ((size_t) n - 1, size), L'\n', 1);
+ /* If we read in some bytes and errno is EAGAIN, that error will
+ be reported for next read. */
+ if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN)
+ && errno != EAGAIN))
+ result = NULL;
+ else if (count >= size)
+ __chk_fail ();
+ else
+ {
+ buf[count] = '\0';
+ result = buf;
+ }
+ fp->_IO_file_flags |= old_error;
+ return result;
+}
diff --git a/debug/fprintf_chk.c b/debug/fprintf_chk.c
index 2b7d22b6a6..58b5fb2b3e 100644
--- a/debug/fprintf_chk.c
+++ b/debug/fprintf_chk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -24,7 +24,7 @@
/* Write formatted output to FP from the format string FORMAT. */
int
-__fprintf_chk (FILE *fp, int flag, const char *format, ...)
+___fprintf_chk (FILE *fp, int flag, const char *format, ...)
{
va_list ap;
int done;
@@ -43,3 +43,4 @@ __fprintf_chk (FILE *fp, int flag, const char *format, ...)
return done;
}
+ldbl_strong_alias (___fprintf_chk, __fprintf_chk)
diff --git a/debug/fwprintf_chk.c b/debug/fwprintf_chk.c
new file mode 100644
index 0000000000..710c89f3c8
--- /dev/null
+++ b/debug/fwprintf_chk.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005
+ 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 <wchar.h>
+#include "../libio/libioP.h"
+
+
+/* Write formatted output to FP from the format string FORMAT. */
+int
+__fwprintf_chk (FILE *fp, int flag, const wchar_t *format, ...)
+{
+ va_list ap;
+ int done;
+
+ _IO_acquire_lock (fp);
+ if (flag > 0)
+ fp->_flags2 |= _IO_FLAGS2_FORTIFY;
+
+ va_start (ap, format);
+ done = _IO_vfwprintf (fp, format, ap);
+ va_end (ap);
+
+ if (flag > 0)
+ fp->_flags2 &= ~_IO_FLAGS2_FORTIFY;
+ _IO_release_lock (fp);
+
+ return done;
+}
diff --git a/debug/getcwd_chk.c b/debug/getcwd_chk.c
new file mode 100644
index 0000000000..cb864c858e
--- /dev/null
+++ b/debug/getcwd_chk.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 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 <errno.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+
+char *
+__getcwd_chk (char *buf, size_t size, size_t buflen)
+{
+ if (size > buflen)
+ __chk_fail ();
+
+ return __getcwd (buf, size);
+}
diff --git a/debug/getdomainname_chk.c b/debug/getdomainname_chk.c
new file mode 100644
index 0000000000..a85464589b
--- /dev/null
+++ b/debug/getdomainname_chk.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2005 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 <unistd.h>
+
+
+int
+__getdomainname_chk (char *buf, size_t buflen, size_t nreal)
+{
+ if (buflen > nreal)
+ __chk_fail ();
+
+ return getdomainname (buf, buflen);
+}
diff --git a/debug/getgroups_chk.c b/debug/getgroups_chk.c
new file mode 100644
index 0000000000..c877ddb9ca
--- /dev/null
+++ b/debug/getgroups_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2005 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 <errno.h>
+#include <unistd.h>
+
+
+int
+__getgroups_chk (int size, __gid_t list[], size_t listlen)
+{
+ if (__builtin_expect (size * sizeof (__gid_t) > listlen, 0))
+ __chk_fail ();
+
+ return __getgroups (size, list);
+}
diff --git a/debug/gethostname_chk.c b/debug/gethostname_chk.c
new file mode 100644
index 0000000000..734cc56b0b
--- /dev/null
+++ b/debug/gethostname_chk.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2005 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 <unistd.h>
+
+
+int
+__gethostname_chk (char *buf, size_t buflen, size_t nreal)
+{
+ if (buflen > nreal)
+ __chk_fail ();
+
+ return __gethostname (buf, buflen);
+}
diff --git a/debug/getlogin_r_chk.c b/debug/getlogin_r_chk.c
new file mode 100644
index 0000000000..ae495cd7ab
--- /dev/null
+++ b/debug/getlogin_r_chk.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2005 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 <unistd.h>
+
+
+int
+__getlogin_r_chk (char *buf, size_t buflen, size_t nreal)
+{
+ if (buflen > nreal)
+ __chk_fail ();
+
+ return getlogin_r (buf, buflen);
+}
diff --git a/debug/getwd_chk.c b/debug/getwd_chk.c
new file mode 100644
index 0000000000..898af28d3f
--- /dev/null
+++ b/debug/getwd_chk.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2005 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 <errno.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+
+char *
+__getwd_chk (char *buf, size_t buflen)
+{
+ char *res = __getcwd (buf, buflen);
+ if (res == NULL && errno == ERANGE)
+ __chk_fail ();
+ return res;
+}
+
+link_warning (getwd,
+ "the `getwd' function is dangerous and should not be used.")
diff --git a/debug/mbsnrtowcs_chk.c b/debug/mbsnrtowcs_chk.c
new file mode 100644
index 0000000000..8872540ee0
--- /dev/null
+++ b/debug/mbsnrtowcs_chk.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 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 <locale.h>
+#include <wchar.h>
+
+
+size_t
+__mbsnrtowcs_chk (wchar_t *dst, __const char **src, size_t nmc, size_t len,
+ mbstate_t *ps, size_t dstlen)
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ return __mbsnrtowcs (dst, src, nmc, len, ps);
+}
diff --git a/debug/mbsrtowcs_chk.c b/debug/mbsrtowcs_chk.c
new file mode 100644
index 0000000000..22d5a35580
--- /dev/null
+++ b/debug/mbsrtowcs_chk.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 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 <locale.h>
+#include <wchar.h>
+
+
+size_t
+__mbsrtowcs_chk (wchar_t *dst, __const char **src, size_t len,
+ mbstate_t *ps, size_t dstlen)
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ return __mbsrtowcs (dst, src, len, ps);
+}
diff --git a/debug/mbstowcs_chk.c b/debug/mbstowcs_chk.c
new file mode 100644
index 0000000000..d1403c5d2b
--- /dev/null
+++ b/debug/mbstowcs_chk.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2005 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 <locale.h>
+#include <string.h>
+#include <wchar.h>
+
+
+size_t
+__mbstowcs_chk (wchar_t *dst, const char *src, size_t len, size_t dstlen)
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ mbstate_t state;
+
+ memset (&state, '\0', sizeof state);
+ /* Return how many we wrote (or maybe an error). */
+ return __mbsrtowcs (dst, &src, len, &state);
+}
diff --git a/debug/memcpy_chk.c b/debug/memcpy_chk.c
new file mode 100644
index 0000000000..638cd0e4fb
--- /dev/null
+++ b/debug/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/debug/memmove_chk.c b/debug/memmove_chk.c
new file mode 100644
index 0000000000..f3b74d23d9
--- /dev/null
+++ b/debug/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/debug/mempcpy_chk.c b/debug/mempcpy_chk.c
new file mode 100644
index 0000000000..5297bbab92
--- /dev/null
+++ b/debug/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/debug/memset_chk.c b/debug/memset_chk.c
new file mode 100644
index 0000000000..d6206ffc99
--- /dev/null
+++ b/debug/memset_chk.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1991, 1997, 2003, 2004, 2005 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/debug/pread64_chk.c b/debug/pread64_chk.c
new file mode 100644
index 0000000000..318579f0b5
--- /dev/null
+++ b/debug/pread64_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2005 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 <unistd.h>
+#include <sys/param.h>
+
+
+ssize_t
+__pread64_chk (int fd, void *buf, size_t nbytes, off64_t offset, size_t buflen)
+{
+ if (nbytes > buflen)
+ __chk_fail ();
+
+ return __libc_pread64 (fd, buf, nbytes, offset);
+}
diff --git a/debug/pread_chk.c b/debug/pread_chk.c
new file mode 100644
index 0000000000..de111eaf82
--- /dev/null
+++ b/debug/pread_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2005 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 <unistd.h>
+#include <sys/param.h>
+
+
+ssize_t
+__pread_chk (int fd, void *buf, size_t nbytes, off_t offset, size_t buflen)
+{
+ if (nbytes > buflen)
+ __chk_fail ();
+
+ return __pread (fd, buf, nbytes, offset);
+}
diff --git a/debug/printf_chk.c b/debug/printf_chk.c
index 86096b45c0..b8f00965dc 100644
--- a/debug/printf_chk.c
+++ b/debug/printf_chk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -24,7 +24,7 @@
/* Write formatted output to stdout from the format string FORMAT. */
int
-__printf_chk (int flag, const char *format, ...)
+___printf_chk (int flag, const char *format, ...)
{
va_list ap;
int done;
@@ -43,3 +43,4 @@ __printf_chk (int flag, const char *format, ...)
return done;
}
+ldbl_strong_alias (___printf_chk, __printf_chk)
diff --git a/debug/ptsname_r_chk.c b/debug/ptsname_r_chk.c
new file mode 100644
index 0000000000..5f03592bd1
--- /dev/null
+++ b/debug/ptsname_r_chk.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2005 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>
+
+
+int
+__ptsname_r_chk (int fd, char *buf, size_t buflen, size_t nreal)
+{
+ if (buflen > nreal)
+ __chk_fail ();
+
+ return __ptsname_r (fd, buf, buflen);
+}
diff --git a/debug/read_chk.c b/debug/read_chk.c
new file mode 100644
index 0000000000..da2bc945b7
--- /dev/null
+++ b/debug/read_chk.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2005 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 <unistd.h>
+#include <sys/param.h>
+#ifdef HAVE_INLINED_SYSCALLS
+# include <errno.h>
+# include <sysdep.h>
+#endif
+
+
+ssize_t
+__read_chk (int fd, void *buf, size_t nbytes, size_t buflen)
+{
+ if (nbytes > buflen)
+ __chk_fail ();
+
+#ifdef HAVE_INLINED_SYSCALLS
+ return INLINE_SYSCALL (read, 3, fd, buf, nbytes);
+#else
+ return __read (fd, buf, nbytes);
+#endif
+}
diff --git a/debug/readlink_chk.c b/debug/readlink_chk.c
new file mode 100644
index 0000000000..ac18ee2c29
--- /dev/null
+++ b/debug/readlink_chk.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2005 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 <unistd.h>
+#include <sys/param.h>
+#ifdef HAVE_INLINED_SYSCALLS
+# include <errno.h>
+# include <sysdep.h>
+#endif
+
+
+ssize_t
+__readlink_chk (const char *path, void *buf, size_t len, size_t buflen)
+{
+ if (len > buflen)
+ __chk_fail ();
+
+#ifdef HAVE_INLINED_SYSCALLS
+ return INLINE_SYSCALL (readlink, 3, path, buf, len);
+#else
+ return __readlink (path, buf, len);
+#endif
+}
diff --git a/debug/readlinkat_chk.c b/debug/readlinkat_chk.c
new file mode 100644
index 0000000000..eab99c0ea9
--- /dev/null
+++ b/debug/readlinkat_chk.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2006 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 <unistd.h>
+#include <sys/param.h>
+
+
+ssize_t
+__readlinkat_chk (int fd, const char *path, void *buf, size_t len,
+ size_t buflen)
+{
+ if (len > buflen)
+ __chk_fail ();
+
+ return readlinkat (fd, path, buf, len);
+}
diff --git a/debug/readonly-area.c b/debug/readonly-area.c
new file mode 100644
index 0000000000..4b8172f193
--- /dev/null
+++ b/debug/readonly-area.c
@@ -0,0 +1,34 @@
+/* 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>
+
+/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
+ Return -1 if it is writable. */
+
+int
+__readonly_area (const void *ptr, size_t size)
+{
+ /* We cannot determine in general whether memory is writable or not.
+ This must be handled in a system-dependent manner. to not
+ unconditionally break code we need to return here a positive
+ answer. This disables this security measure but that is the
+ price people have to pay for using systems without a real
+ implementation of this interface. */
+ return 1;
+}
diff --git a/debug/realpath_chk.c b/debug/realpath_chk.c
new file mode 100644
index 0000000000..961aea0b85
--- /dev/null
+++ b/debug/realpath_chk.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2005 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 <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+char *
+__realpath_chk (const char *buf, char *resolved, size_t resolvedlen)
+{
+#ifdef PATH_MAX
+ if (resolvedlen < PATH_MAX)
+ __chk_fail ();
+
+ return __realpath (buf, resolved);
+#else
+ long int pathmax =__pathconf (buf, _PC_PATH_MAX);
+ if (pathmax != -1)
+ {
+ /* We do have a fixed limit. */
+ if (resolvedlen < pathmax)
+ __chk_fail ();
+
+ return __realpath (buf, resolved);
+ }
+
+ /* Since there is no fixed limit we check whether the size is large
+ enough. */
+ char *res = __realpath (buf, NULL);
+ if (res != NULL)
+ {
+ size_t actlen = strlen (res) + 1;
+ if (actlen > resolvedlen)
+ __chk_fail ();
+
+ memcpy (resolved, res, actlen);
+ free (res);
+ res = resolved;
+ }
+
+ return res;
+#endif
+}
diff --git a/debug/recv_chk.c b/debug/recv_chk.c
new file mode 100644
index 0000000000..479ebdfe72
--- /dev/null
+++ b/debug/recv_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2005 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 <sys/param.h>
+#include <sys/socket.h>
+
+
+ssize_t
+__recv_chk (int fd, void *buf, size_t n, size_t buflen, int flags)
+{
+ if (n > buflen)
+ __chk_fail ();
+
+ return __recv (fd, buf, n, flags);
+}
diff --git a/debug/recvfrom_chk.c b/debug/recvfrom_chk.c
new file mode 100644
index 0000000000..9790a15deb
--- /dev/null
+++ b/debug/recvfrom_chk.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 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 <sys/param.h>
+#include <sys/socket.h>
+
+
+ssize_t
+__recvfrom_chk (int fd, void *buf, size_t n, size_t buflen, int flags,
+ __SOCKADDR_ARG addr, socklen_t *addr_len)
+{
+ if (n > buflen)
+ __chk_fail ();
+
+ return __recvfrom (fd, buf, n, flags, addr, addr_len);
+}
diff --git a/debug/segfault.c b/debug/segfault.c
new file mode 100644
index 0000000000..f141fff661
--- /dev/null
+++ b/debug/segfault.c
@@ -0,0 +1,214 @@
+/* Catch segmentation faults and print backtrace.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ 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 <alloca.h>
+#include <ctype.h>
+#include <errno.h>
+#include <execinfo.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio-common/_itoa.h>
+#include <ldsodefs.h>
+
+#include <bp-checks.h>
+
+/* This file defines macros to access the content of the sigcontext element
+ passed up by the signal handler. */
+#include <sigcontextinfo.h>
+
+/* Get code to possibly dump the content of all registers. */
+#include <register-dump.h>
+
+/* We'll use tis a lot. */
+#define WRITE_STRING(s) write (fd, s, strlen (s))
+
+/* Name of the output file. */
+static const char *fname;
+
+
+/* We better should not use `strerror' since it can call far too many
+ other functions which might fail. Do it here ourselves. */
+static void
+write_strsignal (int fd, int signal)
+{
+ if (signal < 0 || signal >= _NSIG || _sys_siglist[signal] == NULL)
+ {
+ char buf[30];
+ char *ptr = _itoa_word (signal, &buf[sizeof (buf)], 10, 0);
+ WRITE_STRING ("signal ");
+ write (fd, buf, &buf[sizeof (buf)] - ptr);
+ }
+ else
+ WRITE_STRING (_sys_siglist[signal]);
+}
+
+
+/* This function is called when a segmentation fault is caught. The system
+ is in an instable state now. This means especially that malloc() might
+ not work anymore. */
+static void
+catch_segfault (int signal, SIGCONTEXT ctx)
+{
+ int fd, cnt, i;
+ void **arr;
+ struct sigaction sa;
+ uintptr_t pc;
+
+ /* This is the name of the file we are writing to. If none is given
+ or we cannot write to this file write to stderr. */
+ fd = 2;
+ if (fname != NULL)
+ {
+ fd = open (fname, O_TRUNC | O_WRONLY | O_CREAT, 0666);
+ if (fd == -1)
+ fd = 2;
+ }
+
+ WRITE_STRING ("*** ");
+ write_strsignal (fd, signal);
+ WRITE_STRING ("\n");
+
+#ifdef REGISTER_DUMP
+ REGISTER_DUMP;
+#endif
+
+ WRITE_STRING ("\nBacktrace:\n");
+
+ /* Get the backtrace. */
+ arr = alloca (256 * sizeof (void *));
+ cnt = backtrace (arr, 256);
+
+ /* Now try to locate the PC from signal context in the backtrace.
+ Normally it will be found at arr[2], but it might appear later
+ if there were some signal handler wrappers. Allow a few bytes
+ difference to cope with as many arches as possible. */
+ pc = (uintptr_t) GET_PC (ctx);
+ for (i = 0; i < cnt; ++i)
+ if ((uintptr_t) arr[i] >= pc - 16 && (uintptr_t) arr[i] <= pc + 16)
+ break;
+
+ /* If we haven't found it, better dump full backtrace even including
+ the signal handler frames instead of not dumping anything. */
+ if (i == cnt)
+ i = 0;
+
+ /* Now generate nicely formatted output. */
+ __backtrace_symbols_fd (arr + i, cnt - i, fd);
+
+#ifdef HAVE_PROC_SELF
+ /* Now the link map. */
+ int mapfd = open ("/proc/self/maps", O_RDONLY);
+ if (mapfd != -1)
+ {
+ write (fd, "\nMemory map:\n\n", 14);
+
+ char buf[256];
+ ssize_t n;
+
+ while ((n = TEMP_FAILURE_RETRY (read (mapfd, buf, sizeof (buf)))) > 0)
+ TEMP_FAILURE_RETRY (write (fd, buf, n));
+
+ close (mapfd);
+ }
+#endif
+
+ /* Pass on the signal (so that a core file is produced). */
+ sa.sa_handler = SIG_DFL;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction (signal, &sa, NULL);
+ raise (signal);
+}
+
+
+static void
+__attribute__ ((constructor))
+install_handler (void)
+{
+ struct sigaction sa;
+ const char *sigs = getenv ("SEGFAULT_SIGNALS");
+ const char *name;
+
+ sa.sa_handler = (void *) catch_segfault;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+
+ /* Maybe we are expected to use an alternative stack. */
+ if (getenv ("SEGFAULT_USE_ALTSTACK") != 0)
+ {
+ void *stack_mem = malloc (2 * SIGSTKSZ);
+ struct sigaltstack ss;
+
+ if (stack_mem != NULL)
+ {
+ ss.ss_sp = stack_mem;
+ ss.ss_flags = 0;
+ ss.ss_size = 2 * SIGSTKSZ;
+
+ if (sigaltstack (&ss, NULL) == 0)
+ sa.sa_flags |= SA_ONSTACK;
+ }
+ }
+
+ if (sigs == NULL)
+ sigaction (SIGSEGV, &sa, NULL);
+ else if (sigs[0] == '\0')
+ /* Do not do anything. */
+ return;
+ else
+ {
+ const char *where;
+ int all = __strcasecmp (sigs, "all") == 0;
+
+#define INSTALL_FOR_SIG(sig, name) \
+ where = __strcasestr (sigs, name); \
+ if (all || (where != NULL \
+ && (where == sigs || !isalnum (where[-1])) \
+ && !isalnum (where[sizeof (name) - 1]))) \
+ sigaction (sig, &sa, NULL);
+
+ INSTALL_FOR_SIG (SIGSEGV, "segv");
+ INSTALL_FOR_SIG (SIGILL, "ill");
+#ifdef SIGBUS
+ INSTALL_FOR_SIG (SIGBUS, "bus");
+#endif
+#ifdef SIGSTKFLT
+ INSTALL_FOR_SIG (SIGSTKFLT, "stkflt");
+#endif
+ INSTALL_FOR_SIG (SIGABRT, "abrt");
+ INSTALL_FOR_SIG (SIGFPE, "fpe");
+ }
+
+ /* Preserve the output file name if there is any given. */
+ name = getenv ("SEGFAULT_OUTPUT_NAME");
+ if (name != NULL && name[0] != '\0')
+ {
+ int ret = access (name, R_OK | W_OK);
+
+ if (ret == 0 || (ret == -1 && errno == ENOENT))
+ fname = __strdup (name);
+ }
+}
diff --git a/debug/snprintf_chk.c b/debug/snprintf_chk.c
index 5a77afef29..315d47c88b 100644
--- a/debug/snprintf_chk.c
+++ b/debug/snprintf_chk.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991, 1995, 1997, 1998, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1997, 1998, 2004, 2006
+ 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,6 +17,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <libioP.h>
#include <stdarg.h>
#include <stdio.h>
@@ -24,8 +26,8 @@
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, ...)
+___snprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
+ const char *format, ...)
{
va_list arg;
int done;
@@ -36,3 +38,4 @@ __snprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
return done;
}
+ldbl_strong_alias (___snprintf_chk, __snprintf_chk)
diff --git a/debug/sprintf_chk.c b/debug/sprintf_chk.c
index d141633b9f..658c0cccda 100644
--- a/debug/sprintf_chk.c
+++ b/debug/sprintf_chk.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1995,1997,1998,2002,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004, 2006
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,13 +17,14 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <libioP.h>
#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, ...)
+___sprintf_chk (char *s, int flags, size_t slen, const char *format, ...)
{
va_list arg;
int done;
@@ -33,3 +35,4 @@ __sprintf_chk (char *s, int flags, size_t slen, const char *format, ...)
return done;
}
+ldbl_strong_alias (___sprintf_chk, __sprintf_chk)
diff --git a/debug/stack_chk_fail.c b/debug/stack_chk_fail.c
new file mode 100644
index 0000000000..298b323671
--- /dev/null
+++ b/debug/stack_chk_fail.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2005 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 <stdio.h>
+#include <stdlib.h>
+
+
+extern char **__libc_argv attribute_hidden;
+
+void
+__attribute__ ((noreturn))
+__stack_chk_fail (void)
+{
+ /* The loop is added only to keep gcc happy. */
+ while (1)
+ __libc_message (1, "*** stack smashing detected ***: %s terminated\n",
+ __libc_argv[0] ?: "<unknown>");
+}
diff --git a/debug/stack_chk_fail_local.c b/debug/stack_chk_fail_local.c
new file mode 100644
index 0000000000..de0de8f397
--- /dev/null
+++ b/debug/stack_chk_fail_local.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2005 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 <sys/cdefs.h>
+
+extern void __stack_chk_fail (void) __attribute__ ((noreturn));
+
+/* On some architectures, this helps needless PIC pointer setup
+ that would be needed just for the __stack_chk_fail call. */
+
+void __attribute__ ((noreturn)) attribute_hidden
+__stack_chk_fail_local (void)
+{
+ __stack_chk_fail ();
+}
diff --git a/debug/stpcpy_chk.c b/debug/stpcpy_chk.c
new file mode 100644
index 0000000000..dacda0115a
--- /dev/null
+++ b/debug/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/debug/stpncpy_chk.c b/debug/stpncpy_chk.c
new file mode 100644
index 0000000000..d136339dea
--- /dev/null
+++ b/debug/stpncpy_chk.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1993,1995,1996,1997,2002,2005 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. */
+
+/* This is almost copied from strncpy.c, written by Torbjorn Granlund. */
+
+#include <string.h>
+
+
+/* Copy no more than N characters of SRC to DEST, returning the address of
+ the terminating '\0' in DEST, if any, or else DEST + N. */
+char *
+__stpncpy_chk (char *dest, const char *src, size_t n, size_t destlen)
+{
+ char c;
+ char *s = dest;
+
+ if (__builtin_expect (destlen < n, 0))
+ __chk_fail ();
+
+ if (n >= 4)
+ {
+ size_t n4 = n >> 2;
+
+ for (;;)
+ {
+ c = *src++;
+ *dest++ = c;
+ if (c == '\0')
+ break;
+ c = *src++;
+ *dest++ = c;
+ if (c == '\0')
+ break;
+ c = *src++;
+ *dest++ = c;
+ if (c == '\0')
+ break;
+ c = *src++;
+ *dest++ = c;
+ if (c == '\0')
+ break;
+ if (--n4 == 0)
+ goto last_chars;
+ }
+ n -= dest - s;
+ goto zero_fill;
+ }
+
+ last_chars:
+ n &= 3;
+ if (n == 0)
+ return dest;
+
+ for (;;)
+ {
+ c = *src++;
+ --n;
+ *dest++ = c;
+ if (c == '\0')
+ break;
+ if (n == 0)
+ return dest;
+ }
+
+ zero_fill:
+ while (n-- > 0)
+ dest[n] = '\0';
+
+ return dest - 1;
+}
diff --git a/debug/strcat_chk.c b/debug/strcat_chk.c
new file mode 100644
index 0000000000..b3fb3470b7
--- /dev/null
+++ b/debug/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/debug/strcpy_chk.c b/debug/strcpy_chk.c
new file mode 100644
index 0000000000..a4d909feda
--- /dev/null
+++ b/debug/strcpy_chk.c
@@ -0,0 +1,68 @@
+/* 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;
+
+ while (__builtin_expect (destlen >= 4, 0))
+ {
+ c = s[0];
+ s[off] = c;
+ if (c == '\0')
+ return dest;
+ c = s[1];
+ s[off + 1] = c;
+ if (c == '\0')
+ return dest;
+ c = s[2];
+ s[off + 2] = c;
+ if (c == '\0')
+ return dest;
+ c = s[3];
+ s[off + 3] = c;
+ if (c == '\0')
+ return dest;
+ destlen -= 4;
+ s += 4;
+ }
+
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *s;
+ *(s++ + off) = c;
+ }
+ while (c != '\0');
+
+ return dest;
+}
diff --git a/debug/strncat_chk.c b/debug/strncat_chk.c
new file mode 100644
index 0000000000..953b435a4b
--- /dev/null
+++ b/debug/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/debug/strncpy_chk.c b/debug/strncpy_chk.c
new file mode 100644
index 0000000000..bdede7738b
--- /dev/null
+++ b/debug/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/debug/swprintf_chk.c b/debug/swprintf_chk.c
new file mode 100644
index 0000000000..554cbe66a3
--- /dev/null
+++ b/debug/swprintf_chk.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991,1995,1997,1998,1999,2000,2003,2005
+ 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 <wchar.h>
+
+/* Write formatted output into S, according to the format string FORMAT. */
+/* VARARGS5 */
+int
+__swprintf_chk (wchar_t *s, size_t n, int flag, size_t s_len,
+ const wchar_t *format, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, format);
+ done = __vswprintf_chk (s, n, flag, s_len, format, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
index 0df660d57f..c450744af5 100644
--- a/debug/tst-chk1.c
+++ b/debug/tst-chk1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
@@ -17,7 +17,12 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+/* Hack: make sure GCC doesn't know __chk_fail () will not return. */
+#define __noreturn__
+
+#include <assert.h>
#include <fcntl.h>
+#include <locale.h>
#include <paths.h>
#include <setjmp.h>
#include <signal.h>
@@ -25,6 +30,9 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <wchar.h>
+#include <sys/socket.h>
+#include <sys/un.h>
char *temp_filename;
static void do_prepare (void);
@@ -69,13 +77,20 @@ handler (int sig)
}
char buf[10];
+wchar_t wbuf[10];
volatile size_t l0;
volatile char *p;
+volatile wchar_t *wp;
const char *str1 = "JIHGFEDCBA";
const char *str2 = "F";
const char *str3 = "%s%n%s%n";
const char *str4 = "Hello, ";
const char *str5 = "World!\n";
+const wchar_t *wstr1 = L"JIHGFEDCBA";
+const wchar_t *wstr2 = L"F";
+const wchar_t *wstr3 = L"%s%n%s%n";
+const wchar_t *wstr4 = L"Hello, ";
+const wchar_t *wstr5 = L"World!\n";
char buf2[10] = "%s";
int num1 = 67;
int num2 = 987654;
@@ -120,6 +135,7 @@ do_test (void)
setenv ("LIBC_FATAL_STDERR_", "1", 1);
struct A { char buf1[9]; char buf2[1]; } a;
+ struct wA { wchar_t buf1[9]; wchar_t buf2[1]; } wa;
printf ("Test checking routines at fortify level %d\n",
#ifdef __USE_FORTIFY_LEVEL
@@ -135,7 +151,8 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10))
FAIL ();
- if (mempcpy (buf + 5, "abcde", 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
+ if (mempcpy (buf + 5, "abcde", 5) != buf + 10
+ || memcmp (buf, "aabcdabcde", 10))
FAIL ();
memset (buf + 8, 'j', 2);
@@ -166,7 +183,8 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10))
FAIL ();
- if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
+ if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10
+ || memcmp (buf, "aabcdabcde", 10))
FAIL ();
memset (buf + 8, 'j', l0 + 2);
@@ -184,20 +202,24 @@ do_test (void)
if (memcmp (buf, "aabcEDX\0\0", 10))
FAIL ();
- if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEDX67", 10))
+ if (stpncpy (buf + 5, "cd", l0 + 5) != buf + 7
+ || memcmp (buf, "aabcEcd\0\0", 10))
+ FAIL ();
+
+ if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEcd67", 10))
FAIL ();
- if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEDX98", 10))
+ if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEcd98", 10))
FAIL ();
buf[l0 + 8] = '\0';
strcat (buf, "A");
- if (memcmp (buf, "aabcEDX9A", 10))
+ if (memcmp (buf, "aabcEcd9A", 10))
FAIL ();
buf[l0 + 7] = '\0';
strncat (buf, "ZYXWV", l0 + 2);
- if (memcmp (buf, "aabcEDXZY", 10))
+ if (memcmp (buf, "aabcEcdZY", 10))
FAIL ();
memcpy (a.buf1, "abcdefghij", l0 + 10);
@@ -213,7 +235,7 @@ do_test (void)
if (memcmp (a.buf1, "aabcdabcjj", 10))
FAIL ();
-#if __USE_FORTIFY_LEVEL < 2
+#if __USE_FORTIFY_LEVEL < 2 || !__GNUC_PREREQ (4, 0)
/* 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. */
@@ -221,14 +243,16 @@ do_test (void)
if (memcmp (a.buf1, "aabcEDCBA", 10))
FAIL ();
- if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9 || memcmp (a.buf1, "aabcEDCBF", 10))
+ 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))
+ if (sprintf (a.buf1 + 7, "%d", num1) != 2
+ || memcmp (a.buf1, "aabcEDX67", 10))
FAIL ();
if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6
@@ -279,6 +303,10 @@ do_test (void)
CHK_FAIL_END
CHK_FAIL_START
+ stpncpy (buf + 6, "cd", l0 + 5);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
sprintf (buf + 8, "%d", num1);
CHK_FAIL_END
@@ -312,7 +340,7 @@ do_test (void)
memset (a.buf1 + 9, 'j', l0 + 2);
CHK_FAIL_END
-#if __USE_FORTIFY_LEVEL >= 2
+#if __USE_FORTIFY_LEVEL >= 2 && __GNUC_PREREQ (4, 0)
# define O 0
#else
# define O 1
@@ -349,6 +377,219 @@ do_test (void)
CHK_FAIL_END
#endif
+
+ /* These ops can be done without runtime checking of object size. */
+ wmemcpy (wbuf, L"abcdefghij", 10);
+ wmemmove (wbuf + 1, wbuf, 9);
+ if (wmemcmp (wbuf, L"aabcdefghi", 10))
+ FAIL ();
+
+ if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10
+ || wmemcmp (wbuf, L"aabcdabcde", 10))
+ FAIL ();
+
+ wmemset (wbuf + 8, L'j', 2);
+ if (wmemcmp (wbuf, L"aabcdabcjj", 10))
+ FAIL ();
+
+ wcscpy (wbuf + 4, L"EDCBA");
+ if (wmemcmp (wbuf, L"aabcEDCBA", 10))
+ FAIL ();
+
+ if (wcpcpy (wbuf + 8, L"F") != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10))
+ FAIL ();
+
+ wcsncpy (wbuf + 6, L"X", 4);
+ if (wmemcmp (wbuf, L"aabcEDX\0\0", 10))
+ FAIL ();
+
+ if (swprintf (wbuf + 7, 3, L"%ls", L"987654") >= 0
+ || wmemcmp (wbuf, L"aabcEDX98", 10))
+ FAIL ();
+
+ if (swprintf (wbuf + 7, 3, L"64") != 2
+ || wmemcmp (wbuf, L"aabcEDX64", 10))
+ FAIL ();
+
+ /* These ops need runtime checking, but shouldn't __chk_fail. */
+ wmemcpy (wbuf, L"abcdefghij", l0 + 10);
+ wmemmove (wbuf + 1, wbuf, l0 + 9);
+ if (wmemcmp (wbuf, L"aabcdefghi", 10))
+ FAIL ();
+
+ if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10
+ || wmemcmp (wbuf, L"aabcdabcde", 10))
+ FAIL ();
+
+ wmemset (wbuf + 8, L'j', l0 + 2);
+ if (wmemcmp (wbuf, L"aabcdabcjj", 10))
+ FAIL ();
+
+ wcscpy (wbuf + 4, wstr1 + 5);
+ if (wmemcmp (wbuf, L"aabcEDCBA", 10))
+ FAIL ();
+
+ if (wcpcpy (wbuf + 8, wstr2) != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10))
+ FAIL ();
+
+ wcsncpy (wbuf + 6, L"X", l0 + 4);
+ if (wmemcmp (wbuf, L"aabcEDX\0\0", 10))
+ FAIL ();
+
+ if (wcpncpy (wbuf + 5, L"cd", l0 + 5) != wbuf + 7
+ || wmemcmp (wbuf, L"aabcEcd\0\0", 10))
+ FAIL ();
+
+ if (swprintf (wbuf + 7, 3, L"%d", num2) >= 0
+ || wmemcmp (wbuf, L"aabcEcd98", 10))
+ FAIL ();
+
+ wbuf[l0 + 8] = L'\0';
+ wcscat (wbuf, L"A");
+ if (wmemcmp (wbuf, L"aabcEcd9A", 10))
+ FAIL ();
+
+ wbuf[l0 + 7] = L'\0';
+ wcsncat (wbuf, L"ZYXWV", l0 + 2);
+ if (wmemcmp (wbuf, L"aabcEcdZY", 10))
+ FAIL ();
+
+ wmemcpy (wa.buf1, L"abcdefghij", l0 + 10);
+ wmemmove (wa.buf1 + 1, wa.buf1, l0 + 9);
+ if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
+ FAIL ();
+
+ if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10
+ || wmemcmp (wa.buf1, L"aabcdabcde", 10))
+ FAIL ();
+
+ wmemset (wa.buf1 + 8, L'j', l0 + 2);
+ if (wmemcmp (wa.buf1, L"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. */
+ wcscpy (wa.buf1 + 4, wstr1 + 5);
+ if (wmemcmp (wa.buf1, L"aabcEDCBA", 10))
+ FAIL ();
+
+ if (wcpcpy (wa.buf1 + 8, wstr2) != wa.buf1 + 9
+ || wmemcmp (wa.buf1, L"aabcEDCBF", 10))
+ FAIL ();
+
+ wcsncpy (wa.buf1 + 6, L"X", l0 + 4);
+ if (wmemcmp (wa.buf1, L"aabcEDX\0\0", 10))
+ FAIL ();
+
+ if (swprintf (wa.buf1 + 7, 3, L"%d", num2) >= 0
+ || wmemcmp (wa.buf1, L"aabcEDX98", 10))
+ FAIL ();
+
+ wa.buf1[l0 + 8] = L'\0';
+ wcscat (wa.buf1, L"A");
+ if (wmemcmp (wa.buf1, L"aabcEDX9A", 10))
+ FAIL ();
+
+ wa.buf1[l0 + 7] = L'\0';
+ wcsncat (wa.buf1, L"ZYXWV", l0 + 2);
+ if (wmemcmp (wa.buf1, L"aabcEDXZY", 10))
+ FAIL ();
+
+#endif
+
+#if __USE_FORTIFY_LEVEL >= 1
+ /* Now check if all buffer overflows are caught at runtime. */
+
+ CHK_FAIL_START
+ wmemcpy (wbuf + 1, L"abcdefghij", l0 + 10);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wmemset (wbuf + 9, L'j', l0 + 2);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wcscpy (wbuf + 5, wstr1 + 5);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wp = wcpcpy (wbuf + 9, wstr2);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wcsncpy (wbuf + 7, L"X", l0 + 4);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wcpncpy (wbuf + 6, L"cd", l0 + 5);
+ CHK_FAIL_END
+
+ wmemcpy (wbuf, wstr1 + 2, l0 + 9);
+ CHK_FAIL_START
+ wcscat (wbuf, L"AB");
+ CHK_FAIL_END
+
+ wmemcpy (wbuf, wstr1 + 3, l0 + 8);
+ CHK_FAIL_START
+ wcsncat (wbuf, L"ZYXWV", l0 + 3);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wmemcpy (wa.buf1 + 1, L"abcdefghij", l0 + 10);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wmemset (wa.buf1 + 9, L'j', l0 + 2);
+ CHK_FAIL_END
+
+#if __USE_FORTIFY_LEVEL >= 2
+# define O 0
+#else
+# define O 1
+#endif
+
+ CHK_FAIL_START
+ wcscpy (wa.buf1 + (O + 4), wstr1 + 5);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wp = wcpcpy (wa.buf1 + (O + 8), wstr2);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wcsncpy (wa.buf1 + (O + 6), L"X", l0 + 4);
+ CHK_FAIL_END
+
+ wmemcpy (wa.buf1, wstr1 + (3 - O), l0 + 8 + O);
+ CHK_FAIL_START
+ wcscat (wa.buf1, L"AB");
+ CHK_FAIL_END
+
+ wmemcpy (wa.buf1, wstr1 + (4 - O), l0 + 7 + O);
+ CHK_FAIL_START
+ wcsncat (wa.buf1, L"ZYXWV", l0 + 3);
+ CHK_FAIL_END
+#endif
+
+
/* Now checks for %n protection. */
/* Constant literals passed directly are always ok
@@ -455,6 +696,121 @@ do_test (void)
CHK_FAIL_END
#endif
+ rewind (stdin);
+
+ if (fgets (buf, sizeof (buf), stdin) != buf
+ || memcmp (buf, "abcdefgh\n", 10))
+ FAIL ();
+ if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
+ FAIL ();
+
+ rewind (stdin);
+
+ if (fgets (buf, l0 + sizeof (buf), stdin) != buf
+ || memcmp (buf, "abcdefgh\n", 10))
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (fgets (buf, sizeof (buf) + 1, stdin) != buf)
+ FAIL ();
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ rewind (stdin);
+
+ if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
+ || memcmp (buf, "abcdefgh\n", 10))
+ FAIL ();
+ if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
+ || memcmp (buf, "ABCDEFGHI", 10))
+ FAIL ();
+
+ rewind (stdin);
+
+ if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf
+ || memcmp (buf, "abcdefgh\n", 10))
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf)
+ FAIL ();
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ lseek (fileno (stdin), 0, SEEK_SET);
+
+ if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
+ || memcmp (buf, "abcdefgh\n", 9))
+ FAIL ();
+ if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
+ || memcmp (buf, "ABCDEFGHI", 9))
+ FAIL ();
+
+ lseek (fileno (stdin), 0, SEEK_SET);
+
+ if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1
+ || memcmp (buf, "abcdefgh\n", 9))
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
+ != sizeof (buf) - 1
+ || memcmp (buf, "\nABCDEFGH", 9))
+ FAIL ();
+ if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
+ || memcmp (buf, "abcdefgh\n", 9))
+ FAIL ();
+ if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
+ != sizeof (buf) - 1
+ || memcmp (buf, "h\nABCDEFG", 9))
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
+ != sizeof (buf) + 1)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
+ != sizeof (buf) - 1
+ || memcmp (buf, "\nABCDEFGH", 9))
+ FAIL ();
+ if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
+ || memcmp (buf, "abcdefgh\n", 9))
+ FAIL ();
+ if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
+ != sizeof (buf) - 1
+ || memcmp (buf, "h\nABCDEFG", 9))
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
+ != sizeof (buf) + 1)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
if (freopen (temp_filename, "r", stdin) == NULL)
{
puts ("could not open temporary file");
@@ -491,5 +847,474 @@ do_test (void)
snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4);
CHK_FAIL2_END
+ int sp[2];
+ if (socketpair (PF_UNIX, SOCK_STREAM, 0, sp))
+ FAIL ();
+ else
+ {
+ const char *sendstr = "abcdefgh\nABCDEFGH\n0123456789\n";
+ if (send (sp[0], sendstr, strlen (sendstr), 0) != strlen (sendstr))
+ FAIL ();
+
+ char recvbuf[12];
+ if (recv (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK)
+ != sizeof recvbuf
+ || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
+ FAIL ();
+
+ if (recv (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK)
+ != sizeof recvbuf - 7
+ || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (recv (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK)
+ != sizeof recvbuf)
+ FAIL ();
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ if (recv (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK)
+ != sizeof recvbuf - 3)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ socklen_t sl;
+ struct sockaddr_un sa_un;
+
+ sl = sizeof (sa_un);
+ if (recvfrom (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK, &sa_un, &sl)
+ != sizeof recvbuf
+ || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
+ FAIL ();
+
+ sl = sizeof (sa_un);
+ if (recvfrom (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK,
+ &sa_un, &sl) != sizeof recvbuf - 7
+ || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ sl = sizeof (sa_un);
+ if (recvfrom (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK, &sa_un, &sl)
+ != sizeof recvbuf)
+ FAIL ();
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ sl = sizeof (sa_un);
+ if (recvfrom (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK,
+ &sa_un, &sl) != sizeof recvbuf - 3)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ close (sp[0]);
+ close (sp[1]);
+ }
+
+ char fname[] = "/tmp/tst-chk1-dir-XXXXXX\0foo";
+ char *enddir = strchr (fname, '\0');
+ if (mkdtemp (fname) == NULL)
+ {
+ printf ("mkdtemp failed: %m\n");
+ return 1;
+ }
+ *enddir = '/';
+ if (symlink ("bar", fname) != 0)
+ FAIL ();
+
+ char readlinkbuf[4];
+ if (readlink (fname, readlinkbuf, 4) != 3
+ || memcmp (readlinkbuf, "bar", 3) != 0)
+ FAIL ();
+ if (readlink (fname, readlinkbuf + 1, l0 + 3) != 3
+ || memcmp (readlinkbuf, "bbar", 4) != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (readlink (fname, readlinkbuf + 2, l0 + 3) != 3)
+ FAIL ();
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ if (readlink (fname, readlinkbuf + 3, 4) != 3)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ int tmpfd = open ("/tmp", O_RDONLY | O_DIRECTORY);
+ if (tmpfd < 0)
+ FAIL ();
+
+ if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf, 4) != 3
+ || memcmp (readlinkbuf, "bar", 3) != 0)
+ FAIL ();
+ if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 1,
+ l0 + 3) != 3
+ || memcmp (readlinkbuf, "bbar", 4) != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 2,
+ l0 + 3) != 3)
+ FAIL ();
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 3,
+ 4) != 3)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ close (tmpfd);
+
+ char *cwd1 = getcwd (NULL, 0);
+ if (cwd1 == NULL)
+ FAIL ();
+
+ char *cwd2 = getcwd (NULL, 250);
+ if (cwd2 == NULL)
+ FAIL ();
+
+ if (cwd1 && cwd2)
+ {
+ if (strcmp (cwd1, cwd2) != 0)
+ FAIL ();
+
+ *enddir = '\0';
+ if (chdir (fname))
+ FAIL ();
+
+ char *cwd3 = getcwd (NULL, 0);
+ if (cwd3 == NULL)
+ FAIL ();
+ if (strcmp (fname, cwd3) != 0)
+ printf ("getcwd after chdir is '%s' != '%s',"
+ "get{c,}wd tests skipped\n", cwd3, fname);
+ else
+ {
+ char getcwdbuf[sizeof fname - 3];
+
+ char *cwd4 = getcwd (getcwdbuf, sizeof getcwdbuf);
+ if (cwd4 != getcwdbuf
+ || strcmp (getcwdbuf, fname) != 0)
+ FAIL ();
+
+ cwd4 = getcwd (getcwdbuf + 1, l0 + sizeof getcwdbuf - 1);
+ if (cwd4 != getcwdbuf + 1
+ || getcwdbuf[0] != fname[0]
+ || strcmp (getcwdbuf + 1, fname) != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (getcwd (getcwdbuf + 2, l0 + sizeof getcwdbuf)
+ != getcwdbuf + 2)
+ FAIL ();
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ if (getcwd (getcwdbuf + 2, sizeof getcwdbuf)
+ != getcwdbuf + 2)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ if (getwd (getcwdbuf) != getcwdbuf
+ || strcmp (getcwdbuf, fname) != 0)
+ FAIL ();
+
+ if (getwd (getcwdbuf + 1) != getcwdbuf + 1
+ || strcmp (getcwdbuf + 1, fname) != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ if (getwd (getcwdbuf + 2) != getcwdbuf + 2)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+ }
+
+ if (chdir (cwd1) != 0)
+ FAIL ();
+ free (cwd3);
+ }
+
+ free (cwd1);
+ free (cwd2);
+ *enddir = '/';
+ if (unlink (fname) != 0)
+ FAIL ();
+
+ *enddir = '\0';
+ if (rmdir (fname) != 0)
+ FAIL ();
+
+
+#if PATH_MAX > 0
+ char largebuf[PATH_MAX];
+ char *realres = realpath (".", largebuf);
+ if (realres != largebuf)
+ FAIL ();
+
+# if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char realbuf[1];
+ realres = realpath (".", realbuf);
+ if (realres != realbuf)
+ FAIL ();
+ CHK_FAIL_END
+# endif
+#endif
+
+ if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
+ {
+ assert (MB_CUR_MAX <= 10);
+
+ /* First a simple test. */
+ char enough[10];
+ if (wctomb (enough, L'A') != 1)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ /* We know the wchar_t encoding is ISO 10646. So pick a
+ character which has a multibyte representation which does not
+ fit. */
+ CHK_FAIL_START
+ char smallbuf[2];
+ if (wctomb (smallbuf, L'\x100') != 2)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ mbstate_t s;
+ memset (&s, '\0', sizeof (s));
+ if (wcrtomb (enough, L'D', &s) != 1 || enough[0] != 'D')
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ /* We know the wchar_t encoding is ISO 10646. So pick a
+ character which has a multibyte representation which does not
+ fit. */
+ CHK_FAIL_START
+ char smallbuf[2];
+ if (wcrtomb (smallbuf, L'\x100', &s) != 2)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+
+ wchar_t wenough[10];
+ memset (&s, '\0', sizeof (s));
+ const char *cp = "A";
+ if (mbsrtowcs (wenough, &cp, 10, &s) != 1
+ || wcscmp (wenough, L"A") != 0)
+ FAIL ();
+
+ cp = "BC";
+ if (mbsrtowcs (wenough, &cp, l0 + 10, &s) != 2
+ || wcscmp (wenough, L"BC") != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ wchar_t wsmallbuf[2];
+ cp = "ABC";
+ mbsrtowcs (wsmallbuf, &cp, 10, &s);
+ CHK_FAIL_END
+#endif
+
+ cp = "A";
+ if (mbstowcs (wenough, cp, 10) != 1
+ || wcscmp (wenough, L"A") != 0)
+ FAIL ();
+
+ cp = "DEF";
+ if (mbstowcs (wenough, cp, l0 + 10) != 3
+ || wcscmp (wenough, L"DEF") != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ wchar_t wsmallbuf[2];
+ cp = "ABC";
+ mbstowcs (wsmallbuf, cp, 10);
+ CHK_FAIL_END
+#endif
+
+ memset (&s, '\0', sizeof (s));
+ cp = "ABC";
+ wcscpy (wenough, L"DEF");
+ if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1
+ || wcscmp (wenough, L"AEF") != 0)
+ FAIL ();
+
+ cp = "IJ";
+ if (mbsnrtowcs (wenough, &cp, 1, l0 + 10, &s) != 1
+ || wcscmp (wenough, L"IEF") != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ wchar_t wsmallbuf[2];
+ cp = "ABC";
+ mbsnrtowcs (wsmallbuf, &cp, 3, 10, &s);
+ CHK_FAIL_END
+#endif
+
+ memset (&s, '\0', sizeof (s));
+ const wchar_t *wcp = L"A";
+ if (wcsrtombs (enough, &wcp, 10, &s) != 1
+ || strcmp (enough, "A") != 0)
+ FAIL ();
+
+ wcp = L"BC";
+ if (wcsrtombs (enough, &wcp, l0 + 10, &s) != 2
+ || strcmp (enough, "BC") != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[2];
+ wcp = L"ABC";
+ wcsrtombs (smallbuf, &wcp, 10, &s);
+ CHK_FAIL_END
+#endif
+
+ memset (enough, 'Z', sizeof (enough));
+ wcp = L"EF";
+ if (wcstombs (enough, wcp, 10) != 2
+ || strcmp (enough, "EF") != 0)
+ FAIL ();
+
+ wcp = L"G";
+ if (wcstombs (enough, wcp, l0 + 10) != 1
+ || strcmp (enough, "G") != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[2];
+ wcp = L"ABC";
+ wcstombs (smallbuf, wcp, 10);
+ CHK_FAIL_END
+#endif
+
+ memset (&s, '\0', sizeof (s));
+ wcp = L"AB";
+ if (wcsnrtombs (enough, &wcp, 1, 10, &s) != 1
+ || strcmp (enough, "A") != 0)
+ FAIL ();
+
+ wcp = L"BCD";
+ if (wcsnrtombs (enough, &wcp, 1, l0 + 10, &s) != 1
+ || strcmp (enough, "B") != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[2];
+ wcp = L"ABC";
+ wcsnrtombs (smallbuf, &wcp, 3, 10, &s);
+ CHK_FAIL_END
+#endif
+ }
+ else
+ {
+ puts ("cannot set locale");
+ ret = 1;
+ }
+
+ fd = posix_openpt (O_RDWR);
+ if (fd != -1)
+ {
+ char enough[1000];
+ if (ptsname_r (fd, enough, sizeof (enough)) != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[2];
+ if (ptsname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+ close (fd);
+ }
+
+#if PATH_MAX > 0
+ confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf));
+# if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[1];
+ confstr (_CS_GNU_LIBC_VERSION, smallbuf, sizeof (largebuf));
+ CHK_FAIL_END
+# endif
+#endif
+
+ gid_t grpslarge[5];
+ int ngr = getgroups (5, grpslarge);
+ asm volatile ("" : : "r" (ngr));
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[1];
+ ngr = getgroups (5, (gid_t *) smallbuf);
+ asm volatile ("" : : "r" (ngr));
+ CHK_FAIL_END
+#endif
+
+ fd = open (_PATH_TTY, O_RDONLY);
+ if (fd != -1)
+ {
+ char enough[1000];
+ if (ttyname_r (fd, enough, sizeof (enough)) != 0)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[2];
+ if (ttyname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0)
+ FAIL ();
+ CHK_FAIL_END
+#endif
+ close (fd);
+ }
+
+ char hostnamelarge[1000];
+ gethostname (hostnamelarge, sizeof (hostnamelarge));
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[1];
+ gethostname (smallbuf, sizeof (hostnamelarge));
+ CHK_FAIL_END
+#endif
+
+ char loginlarge[1000];
+ getlogin_r (loginlarge, sizeof (hostnamelarge));
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[1];
+ getlogin_r (smallbuf, sizeof (loginlarge));
+ CHK_FAIL_END
+#endif
+
+ char domainnamelarge[1000];
+ int res = getdomainname (domainnamelarge, sizeof (domainnamelarge));
+ asm volatile ("" : : "r" (res));
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ char smallbuf[1];
+ res = getdomainname (smallbuf, sizeof (domainnamelarge));
+ asm volatile ("" : : "r" (res));
+ CHK_FAIL_END
+#endif
+
return ret;
}
diff --git a/debug/tst-lfschk1.c b/debug/tst-lfschk1.c
new file mode 100644
index 0000000000..f3e6d47d5e
--- /dev/null
+++ b/debug/tst-lfschk1.c
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include "tst-chk1.c"
diff --git a/debug/tst-lfschk2.c b/debug/tst-lfschk2.c
new file mode 100644
index 0000000000..95d4db1d32
--- /dev/null
+++ b/debug/tst-lfschk2.c
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include "tst-chk2.c"
diff --git a/debug/tst-lfschk3.c b/debug/tst-lfschk3.c
new file mode 100644
index 0000000000..50a1ae1258
--- /dev/null
+++ b/debug/tst-lfschk3.c
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include "tst-chk3.c"
diff --git a/debug/ttyname_r_chk.c b/debug/ttyname_r_chk.c
new file mode 100644
index 0000000000..9b06d5a718
--- /dev/null
+++ b/debug/ttyname_r_chk.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2005 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 <unistd.h>
+
+
+int
+__ttyname_r_chk (int fd, char *buf, size_t buflen, size_t nreal)
+{
+ if (buflen > nreal)
+ __chk_fail ();
+
+ return __ttyname_r (fd, buf, buflen);
+}
diff --git a/debug/vfprintf_chk.c b/debug/vfprintf_chk.c
index c8e7c3bf3f..bd2796eaf7 100644
--- a/debug/vfprintf_chk.c
+++ b/debug/vfprintf_chk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -24,7 +24,7 @@
/* Write formatted output to FP from the format string FORMAT. */
int
-__vfprintf_chk (FILE *fp, int flag, const char *format, va_list ap)
+___vfprintf_chk (FILE *fp, int flag, const char *format, va_list ap)
{
int done;
@@ -40,3 +40,5 @@ __vfprintf_chk (FILE *fp, int flag, const char *format, va_list ap)
return done;
}
+ldbl_hidden_def (___vfprintf_chk, __vfprintf_chk)
+ldbl_strong_alias (___vfprintf_chk, __vfprintf_chk)
diff --git a/debug/vfwprintf_chk.c b/debug/vfwprintf_chk.c
new file mode 100644
index 0000000000..a2612d53e9
--- /dev/null
+++ b/debug/vfwprintf_chk.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005, 2006
+ 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 <wchar.h>
+#include "../libio/libioP.h"
+
+
+/* Write formatted output to FP from the format string FORMAT. */
+int
+__vfwprintf_chk (FILE *fp, int flag, const wchar_t *format, va_list ap)
+{
+ int done;
+
+ _IO_acquire_lock (fp);
+ if (flag > 0)
+ fp->_flags2 |= _IO_FLAGS2_FORTIFY;
+
+ done = _IO_vfwprintf (fp, format, ap);
+
+ if (flag > 0)
+ fp->_flags2 &= ~_IO_FLAGS2_FORTIFY;
+ _IO_release_lock (fp);
+
+ return done;
+}
+libc_hidden_def (__vfwprintf_chk)
diff --git a/debug/vprintf_chk.c b/debug/vprintf_chk.c
index 1fd5bcd849..68a63ee7f9 100644
--- a/debug/vprintf_chk.c
+++ b/debug/vprintf_chk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -24,7 +24,7 @@
/* Write formatted output to stdout from the format string FORMAT. */
int
-__vprintf_chk (int flag, const char *format, va_list ap)
+___vprintf_chk (int flag, const char *format, va_list ap)
{
int done;
@@ -40,3 +40,4 @@ __vprintf_chk (int flag, const char *format, va_list ap)
return done;
}
+ldbl_strong_alias (___vprintf_chk, __vprintf_chk)
diff --git a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c
index a0fd4ebfdc..c46937ff6f 100644
--- a/debug/vsnprintf_chk.c
+++ b/debug/vsnprintf_chk.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991, 1995, 1997, 1998, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1997, 1998, 2004, 2006
+ 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
@@ -27,8 +28,8 @@ extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
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)
+___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
@@ -67,4 +68,5 @@ __vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
*sf.f._sbf._f._IO_write_ptr = '\0';
return ret;
}
-libc_hidden_def (__vsnprintf_chk)
+ldbl_hidden_def (___vsnprintf_chk, __vsnprintf_chk)
+ldbl_strong_alias (___vsnprintf_chk, __vsnprintf_chk)
diff --git a/debug/vsprintf_chk.c b/debug/vsprintf_chk.c
index f41c5fc64b..6538064dce 100644
--- a/debug/vsprintf_chk.c
+++ b/debug/vsprintf_chk.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1994, 1997, 1999-2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1997, 1999-2003, 2004, 2006
+ 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
@@ -61,8 +62,8 @@ static const struct _IO_jump_t _IO_str_chk_jumps =
int
-__vsprintf_chk (char *s, int flags, size_t slen, const char *format,
- va_list args)
+___vsprintf_chk (char *s, int flags, size_t slen, const char *format,
+ va_list args)
{
_IO_strfile f;
int ret;
@@ -88,4 +89,5 @@ __vsprintf_chk (char *s, int flags, size_t slen, const char *format,
*f._sbf._f._IO_write_ptr = '\0';
return ret;
}
-libc_hidden_def (__vsprintf_chk)
+ldbl_hidden_def (___vsprintf_chk, __vsprintf_chk)
+ldbl_strong_alias (___vsprintf_chk, __vsprintf_chk)
diff --git a/debug/vswprintf_chk.c b/debug/vswprintf_chk.c
new file mode 100644
index 0000000000..f9a50c6e5d
--- /dev/null
+++ b/debug/vswprintf_chk.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 1991,1995,1997,1998,2004,2005 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 <wchar.h>
+#include "../libio/libioP.h"
+#include "../libio/strfile.h"
+
+
+/* Write formatted output into S, according to the format
+ string FORMAT, writing no more than MAXLEN characters. */
+/* VARARGS5 */
+int
+__vswprintf_chk (wchar_t *s, size_t maxlen, int flags, size_t slen,
+ const wchar_t *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_wstrnfile sf;
+ struct _IO_wide_data wd;
+ 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 (__builtin_expect (maxlen == 0, 0))
+ /* Since we have to write at least the terminating L'\0' a buffer
+ length of zero always makes the function fail. */
+ return -1;
+
+ _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstrn_jumps);
+ _IO_fwide (&sf.f._sbf._f, 1);
+ s[0] = L'\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_FORTIFY;
+
+ _IO_wstr_init_static (&sf.f._sbf._f, s, maxlen - 1, s);
+ ret = _IO_vfwprintf ((_IO_FILE *) &sf.f._sbf, format, args);
+
+ if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf)
+ /* ISO C99 requires swprintf/vswprintf to return an error if the
+ output does not fit int he provided buffer. */
+ return -1;
+
+ /* Terminate the string. */
+ *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0';
+
+ return ret;
+}
+libc_hidden_def (__vswprintf_chk)
diff --git a/debug/vwprintf_chk.c b/debug/vwprintf_chk.c
new file mode 100644
index 0000000000..3b959b2968
--- /dev/null
+++ b/debug/vwprintf_chk.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005
+ 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 <wchar.h>
+#include "../libio/libioP.h"
+
+
+/* Write formatted output to stdout from the format string FORMAT. */
+int
+__vwprintf_chk (int flag, const wchar_t *format, va_list ap)
+{
+ int done;
+
+ _IO_acquire_lock (stdout);
+ if (flag > 0)
+ stdout->_flags2 |= _IO_FLAGS2_FORTIFY;
+
+ done = _IO_vfwprintf (stdout, format, ap);
+
+ if (flag > 0)
+ stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY;
+ _IO_release_lock (stdout);
+
+ return done;
+}
diff --git a/debug/warning-nop.c b/debug/warning-nop.c
new file mode 100644
index 0000000000..8f2f66e16a
--- /dev/null
+++ b/debug/warning-nop.c
@@ -0,0 +1,53 @@
+/* Dummy nop functions to elicit link-time warnings.
+ Copyright (C) 2005 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 <sys/cdefs.h>
+
+static void
+nop (void)
+{
+}
+
+/* Don't insert any other #include's before this #undef! */
+
+#undef __warndecl
+#define __warndecl(name, msg) \
+ extern void name (void) __attribute__ ((alias ("nop"))) attribute_hidden; \
+ link_warning (name, msg)
+
+#undef __USE_FORTIFY_LEVEL
+#define __USE_FORTIFY_LEVEL 99
+
+/* Following here we need an #include for each public header file
+ that uses __warndecl. */
+
+/* Define away to avoid warnings with compilers that do not have these
+ builtins. */
+#define __builtin___memcpy_chk(dest, src, len, bos) NULL
+#define __builtin___memmove_chk(dest, src, len, bos) NULL
+#define __builtin___mempcpy_chk(dest, src, len, bos) NULL
+#define __builtin___memset_chk(dest, ch, len, bos) NULL
+#define __builtin___stpcpy_chk(dest, src, bos) NULL
+#define __builtin___strcat_chk(dest, src, bos) NULL
+#define __builtin___strcpy_chk(dest, src, bos) NULL
+#define __builtin___strncat_chk(dest, src, len, bos) NULL
+#define __builtin___strncpy_chk(dest, src, len, bos) NULL
+#define __builtin_object_size(bos, level) 0
+
+#include <string.h>
diff --git a/debug/wcpcpy_chk.c b/debug/wcpcpy_chk.c
new file mode 100644
index 0000000000..c48ec68ccc
--- /dev/null
+++ b/debug/wcpcpy_chk.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
+
+ 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 <wchar.h>
+
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+
+/* Copy SRC to DEST, returning the address of the terminating L'\0' in
+ DEST. Check for overflows. */
+wchar_t *
+__wcpcpy_chk (wchar_t *dest, const wchar_t *src, size_t destlen)
+{
+ wchar_t *wcp = (wchar_t *) dest - 1;
+ wint_t c;
+ const ptrdiff_t off = src - dest + 1;
+
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = wcp[off];
+ *++wcp = c;
+ }
+ while (c != L'\0');
+
+ return wcp;
+}
diff --git a/debug/wcpncpy_chk.c b/debug/wcpncpy_chk.c
new file mode 100644
index 0000000000..ea1340191a
--- /dev/null
+++ b/debug/wcpncpy_chk.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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 <wchar.h>
+
+
+/* Copy no more than N wide-characters of SRC to DEST. */
+wchar_t *
+__wcpncpy_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen)
+{
+ if (__builtin_expect (destlen < n, 0))
+ __chk_fail ();
+
+ /* This function is not often enough used to justify not using a
+ tail call. */
+ return __wcpncpy (dest, src, n);
+}
diff --git a/debug/wcrtomb_chk.c b/debug/wcrtomb_chk.c
new file mode 100644
index 0000000000..228430f373
--- /dev/null
+++ b/debug/wcrtomb_chk.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2005 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 <langinfo.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <locale/localeinfo.h>
+
+
+size_t
+__wcrtomb_chk (char *s, wchar_t wchar, mbstate_t *ps, size_t buflen)
+{
+ /* We do not have to implement the full wctomb semantics since we
+ know that S cannot be NULL when we come here. */
+ if (buflen < MB_CUR_MAX)
+ __chk_fail ();
+
+ return __wcrtomb (s, wchar, ps);
+}
diff --git a/debug/wcscat_chk.c b/debug/wcscat_chk.c
new file mode 100644
index 0000000000..eef04519fd
--- /dev/null
+++ b/debug/wcscat_chk.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1995, 1996, 1997, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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 <wchar.h>
+
+
+/* Append SRC on the end of DEST. Check for overflows. */
+wchar_t *
+__wcscat_chk (wchar_t *dest, const wchar_t *src, size_t destlen)
+{
+ register wchar_t *s1 = dest;
+ register const wchar_t *s2 = src;
+ wchar_t c;
+
+ /* Find the end of the string. */
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *s1++;
+ }
+ while (c != L'\0');
+
+ /* Make S1 point before the next character, so we can increment
+ it while memory is read (wins on pipelined cpus). */
+ s1 -= 2;
+ ++destlen;
+
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *s2++;
+ *++s1 = c;
+ }
+ while (c != L'\0');
+
+ return dest;
+}
diff --git a/debug/wcscpy_chk.c b/debug/wcscpy_chk.c
new file mode 100644
index 0000000000..93b78cd01c
--- /dev/null
+++ b/debug/wcscpy_chk.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1995, 1996, 1997, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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 <wchar.h>
+
+
+/* Copy SRC to DEST. */
+wchar_t *
+__wcscpy_chk (wchar_t *dest, const wchar_t *src, size_t n)
+{
+ wint_t c;
+ wchar_t *wcp;
+
+ if (__alignof__ (wchar_t) >= sizeof (wchar_t))
+ {
+ const ptrdiff_t off = dest - src - 1;
+
+ wcp = (wchar_t *) src;
+
+ do
+ {
+ if (__builtin_expect (n-- == 0, 0))
+ __chk_fail ();
+ c = *wcp++;
+ wcp[off] = c;
+ }
+ while (c != L'\0');
+ }
+ else
+ {
+ wcp = dest;
+
+ do
+ {
+ if (__builtin_expect (n-- == 0, 0))
+ __chk_fail ();
+ c = *src++;
+ *wcp++ = c;
+ }
+ while (c != L'\0');
+ }
+
+ return dest;
+}
diff --git a/debug/wcsncat_chk.c b/debug/wcsncat_chk.c
new file mode 100644
index 0000000000..b28773ff27
--- /dev/null
+++ b/debug/wcsncat_chk.c
@@ -0,0 +1,96 @@
+/* Copyright (C) 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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 <wchar.h>
+
+
+/* Append no more than N wide-character of SRC onto DEST. */
+wchar_t *
+__wcsncat_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen)
+{
+ wchar_t c;
+ wchar_t * const s = dest;
+
+ /* Find the end of DEST. */
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *dest++;
+ }
+ while (c != L'\0');
+
+ /* Make DEST point before next character, so we can increment
+ it while memory is read (wins on pipelined cpus). */
+ ++destlen;
+ dest -= 2;
+
+ if (n >= 4)
+ {
+ size_t n4 = n >> 2;
+ do
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *src++;
+ *++dest = c;
+ if (c == L'\0')
+ return s;
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *src++;
+ *++dest = c;
+ if (c == L'\0')
+ return s;
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *src++;
+ *++dest = c;
+ if (c == L'\0')
+ return s;
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *src++;
+ *++dest = c;
+ if (c == L'\0')
+ return s;
+ } while (--n4 > 0);
+ n &= 3;
+ }
+
+ while (n > 0)
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ c = *src++;
+ *++dest = c;
+ if (c == L'\0')
+ return s;
+ n--;
+ }
+
+ if (c != L'\0')
+ {
+ if (__builtin_expect (destlen-- == 0, 0))
+ __chk_fail ();
+ *++dest = L'\0';
+ }
+
+ return s;
+}
diff --git a/debug/wcsncpy_chk.c b/debug/wcsncpy_chk.c
new file mode 100644
index 0000000000..199e4b01ab
--- /dev/null
+++ b/debug/wcsncpy_chk.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1995, 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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 <wchar.h>
+
+
+/* Copy no more than N wide-characters of SRC to DEST. */
+wchar_t *
+__wcsncpy_chk (wchar_t *dest, const wchar_t *src, size_t n, size_t destlen)
+{
+ if (__builtin_expect (destlen < n, 0))
+ __chk_fail ();
+
+ /* This function is not often enough used to justify not using a
+ tail call. */
+ return __wcsncpy (dest, src, n);
+}
diff --git a/debug/wcsnrtombs_chk.c b/debug/wcsnrtombs_chk.c
new file mode 100644
index 0000000000..67644bd557
--- /dev/null
+++ b/debug/wcsnrtombs_chk.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 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 <locale.h>
+#include <wchar.h>
+
+
+size_t
+__wcsnrtombs_chk (char *dst, __const wchar_t **src, size_t nwc, size_t len,
+ mbstate_t *ps, size_t dstlen)
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ return __wcsnrtombs (dst, src, nwc, len, ps);
+}
diff --git a/debug/wcsrtombs_chk.c b/debug/wcsrtombs_chk.c
new file mode 100644
index 0000000000..9334267bae
--- /dev/null
+++ b/debug/wcsrtombs_chk.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 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 <locale.h>
+#include <wchar.h>
+
+
+size_t
+__wcsrtombs_chk (char *dst, __const wchar_t **src, size_t len,
+ mbstate_t *ps, size_t dstlen)
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ return __wcsrtombs (dst, src, len, ps);
+}
diff --git a/debug/wcstombs_chk.c b/debug/wcstombs_chk.c
new file mode 100644
index 0000000000..0da48f9803
--- /dev/null
+++ b/debug/wcstombs_chk.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 2005 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 <locale.h>
+#include <string.h>
+#include <wchar.h>
+
+
+size_t
+__wcstombs_chk (char *dst, __const wchar_t *src, size_t len, size_t dstlen)
+{
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail ();
+
+ mbstate_t state;
+
+ memset (&state, '\0', sizeof state);
+
+ /* Return how many we wrote (or maybe an error). */
+ return __wcsrtombs (dst, &src, len, &state);
+}
diff --git a/debug/wctomb_chk.c b/debug/wctomb_chk.c
new file mode 100644
index 0000000000..d0366346b8
--- /dev/null
+++ b/debug/wctomb_chk.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 2005 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 <locale.h>
+#include <stdlib.h>
+#include <wcsmbs/wcsmbsload.h>
+
+
+extern mbstate_t __no_r_state attribute_hidden; /* Defined in mbtowc.c. */
+
+
+int
+__wctomb_chk (char *s, wchar_t wchar, size_t buflen)
+{
+ /* We do not have to implement the full wctomb semantics since we
+ know that S cannot be NULL when we come here. */
+ if (buflen < MB_CUR_MAX)
+ __chk_fail ();
+
+ return __wcrtomb (s, wchar, &__no_r_state);
+}
diff --git a/debug/wmemcpy_chk.c b/debug/wmemcpy_chk.c
new file mode 100644
index 0000000000..eeee927e91
--- /dev/null
+++ b/debug/wmemcpy_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1996, 1997, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.org>, 1996.
+
+ 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 <wchar.h>
+#include <string.h>
+
+
+wchar_t *
+__wmemcpy_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1)
+{
+ if (__builtin_expect (ns1 < n, 0))
+ __chk_fail ();
+ return (wchar_t *) memcpy ((char *) s1, (char *) s2, n * sizeof (wchar_t));
+}
diff --git a/debug/wmemmove_chk.c b/debug/wmemmove_chk.c
new file mode 100644
index 0000000000..da0446eb28
--- /dev/null
+++ b/debug/wmemmove_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1996, 1997, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
+
+ 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 <wchar.h>
+#include <string.h>
+
+
+wchar_t *
+__wmemmove_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1)
+{
+ if (__builtin_expect (ns1 < n, 0))
+ __chk_fail ();
+ return (wchar_t *) memmove ((char *) s1, (char *) s2, n * sizeof (wchar_t));
+}
diff --git a/debug/wmempcpy_chk.c b/debug/wmempcpy_chk.c
new file mode 100644
index 0000000000..52c629a354
--- /dev/null
+++ b/debug/wmempcpy_chk.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.org>, 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. */
+
+#include <wchar.h>
+#include <string.h>
+
+
+wchar_t *
+__wmempcpy_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1)
+{
+ if (__builtin_expect (ns1 < n, 0))
+ __chk_fail ();
+ return (wchar_t *) __mempcpy ((char *) s1, (char *) s2,
+ n * sizeof (wchar_t));
+}
diff --git a/debug/wmemset_chk.c b/debug/wmemset_chk.c
new file mode 100644
index 0000000000..5ed88e83a2
--- /dev/null
+++ b/debug/wmemset_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1996,97,99,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.org>, 1996.
+
+ 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 <wchar.h>
+
+
+wchar_t *
+__wmemset_chk (wchar_t *s, wchar_t c, size_t n, size_t dstlen)
+{
+ if (__builtin_expect (dstlen < n, 0))
+ __chk_fail ();
+
+ return wmemset (s, c, n);
+}
diff --git a/debug/wprintf_chk.c b/debug/wprintf_chk.c
new file mode 100644
index 0000000000..e0a82617ad
--- /dev/null
+++ b/debug/wprintf_chk.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2005
+ 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 <wchar.h>
+#include "../libio/libioP.h"
+
+
+/* Write formatted output to stdout from the format string FORMAT. */
+int
+__wprintf_chk (int flag, const wchar_t *format, ...)
+{
+ va_list ap;
+ int done;
+
+ _IO_acquire_lock (stdout);
+ if (flag > 0)
+ stdout->_flags2 |= _IO_FLAGS2_FORTIFY;
+
+ va_start (ap, format);
+ done = _IO_vfwprintf (stdout, format, ap);
+ va_end (ap);
+
+ if (flag > 0)
+ stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY;
+ _IO_release_lock (stdout);
+
+ return done;
+}
diff --git a/debug/xtrace.sh b/debug/xtrace.sh
index 4ce8888490..c913c76d21 100755
--- a/debug/xtrace.sh
+++ b/debug/xtrace.sh
@@ -1,5 +1,5 @@
#! @BASH@
-# Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1999, 2001-2006, 2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Ulrich Drepper <drepper@gnu.org>, 1999.
@@ -18,8 +18,8 @@
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA.
-pcprofileso=@SLIBDIR@/libpcprofile.so
-pcprofiledump=@BINDIR@/pcprofiledump
+pcprofileso='@SLIBDIR@/libpcprofile.so'
+pcprofiledump='@BINDIR@/pcprofiledump'
TEXTDOMAIN=libc
# Print usage message.
@@ -64,7 +64,7 @@ do_version() {
printf $"Copyright (C) %s Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-" "2004"
+" "2006"
printf $"Written by %s.
" "Ulrich Drepper"
exit 0
@@ -107,7 +107,7 @@ while test $# -gt 0; do
--d=* | --da=* | --dat=* | --data=*)
data=${1##*=}
;;
- -? | --h | --he | --hel | --help)
+ -\? | --h | --he | --hel | --help)
do_help
;;
-V | --v | --ve | --ver | --vers | --versi | --versio | --version)
@@ -161,32 +161,32 @@ if test -n "$data"; then
while read fct; do
read file
if test "$fct" != '??' -a "$file" != '??:0'; then
- format_line $fct $file
+ format_line "$fct" "$file"
fi
done
else
- fifo=$(mktemp -u ${TMPDIR:-/tmp}/xtrace.XXXXXX)
+ fifo=$(mktemp -ut xtrace.XXXXXX) || exit
+ trap 'rm -f "$fifo"; exit 1' HUP INT QUIT TERM PIPE
mkfifo -m 0600 $fifo || exit 1
- trap 'rm $fifo; exit 1' SIGINT SIGTERM SIGPIPE
# Now start the program and let it write to the FIFO.
$TERMINAL_PROG -T "xtrace - $program $*" -e /bin/sh -c "LD_PRELOAD=$pcprofileso PCPROFILE_OUTPUT=$fifo $program $*; read < $fifo" &
termpid=$!
- $pcprofiledump -u $fifo |
+ $pcprofiledump -u "$fifo" |
while read line; do
- echo $line |
+ echo "$line" |
sed 's/this = \([^,]*\).*/\1/' |
- addr2line -fC -e $program
+ addr2line -fC -e "$program"
done |
while read fct; do
read file
if test "$fct" != '??' -a "$file" != '??:0'; then
- format_line $fct $file
+ format_line "$fct" "$file"
fi
done
read -p "Press return here to close $TERMINAL_PROG($program)."
- echo > $fifo
- rm $fifo
+ echo > "$fifo"
+ rm "$fifo"
fi
exit 0