about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-07-15 10:32:45 +0000
committerUlrich Drepper <drepper@redhat.com>2005-07-15 10:32:45 +0000
commit8215c9ecf27714c7ec607aba0085383ef923777a (patch)
treeff0127a461256dba9379940e5d33f08928aa4dcf
parentf45729d8cd80b082c7724883aa9c6c858d0082f9 (diff)
downloadglibc-8215c9ecf27714c7ec607aba0085383ef923777a.tar.gz
glibc-8215c9ecf27714c7ec607aba0085383ef923777a.tar.xz
glibc-8215c9ecf27714c7ec607aba0085383ef923777a.zip
* wcsmbs/bits/wchar2.h: New file.
	* include/bits/wchar2.h: New file.
	* wcsmbs/wchar.h: Include <bits/wchar2.h> if fortification is
	requested.
	* wcsmbs/wcsncpy.c: Add __wcsncpy alias.
	* string/bits/string3.h: Add fortified stpncpy definitions.
	* sysdeps/generic/stpncpy_chk.c: New file.
	* libio/vswprintf.c: Move _IO_wstrnfile definition to strfile.h.
	Export _IO_wstrn_jumps.
	* libio/strfile.h: Define _IO_wstrnfile and declare _IO_wstrn_jumps.
	* include/wchar.h: Declare __wcsncpy and __vswprintf_chk.
	* debug/fgetws_chk.c: New file.
	* debug/fgetws_u_chk.c: New file.
	* debug/fwprintf_chk.c: New file.
	* debug/swprintf_chk.c: New file.
	* debug/vfwprintf_chk.c: New file.
	* debug/vswprintf_chk.c: New file.
	* debug/vwprintf_chk.c: New file.
	* debug/wcpcpy_chk.c: New file.
	* debug/wcpncpy_chk.c: New file.
	* debug/wcscat_chk.c: New file.
	* debug/wcscpy_chk.c: New file.
	* debug/wcsncat_chk.c: New file.
	* debug/wcsncpy_chk.c: New file.
	* debug/wmemcpy_chk.c: New file.
	* debug/wmemmove_chk.c: New file.
	* debug/wmempcpy_chk.c: New file.
	* debug/wmemset_chk.c: New file.
	* debug/wprintf_chk.c: New file.
	* debug/tst-chk1.c: Add tests for new functions.
	* debug/Versions: Export new functions.
	* debug/Makefile (routines): Add new functions.
-rw-r--r--ChangeLog35
-rw-r--r--debug/Makefile17
-rw-r--r--debug/Versions5
-rw-r--r--debug/fgetws_chk.c54
-rw-r--r--debug/fgetws_u_chk.c61
-rw-r--r--debug/fwprintf_chk.c45
-rw-r--r--debug/swprintf_chk.c37
-rw-r--r--debug/tst-chk1.c247
-rw-r--r--debug/vfwprintf_chk.c42
-rw-r--r--debug/vswprintf_chk.c75
-rw-r--r--debug/vwprintf_chk.c43
-rw-r--r--debug/wcpcpy_chk.c45
-rw-r--r--debug/wcpncpy_chk.c33
-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/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
-rw-r--r--include/bits/wchar2.h1
-rw-r--r--include/wchar.h9
-rw-r--r--libio/strfile.h13
-rw-r--r--libio/vswprintf.c13
-rw-r--r--string/bits/string3.h16
-rw-r--r--sysdeps/generic/stpncpy_chk.c85
-rw-r--r--wcsmbs/bits/wchar2.h288
-rw-r--r--wcsmbs/wchar.h7
-rw-r--r--wcsmbs/wcsncpy.c5
31 files changed, 1563 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index e0c8ec2f40..3e9cc2270c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2005-07-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* wcsmbs/bits/wchar2.h: New file.
+	* include/bits/wchar2.h: New file.
+	* wcsmbs/wchar.h: Include <bits/wchar2.h> if fortification is
+	requested.
+	* wcsmbs/wcsncpy.c: Add __wcsncpy alias.
+	* string/bits/string3.h: Add fortified stpncpy definitions.
+	* sysdeps/generic/stpncpy_chk.c: New file.
+	* libio/vswprintf.c: Move _IO_wstrnfile definition to strfile.h.
+	Export _IO_wstrn_jumps.
+	* libio/strfile.h: Define _IO_wstrnfile and declare _IO_wstrn_jumps.
+	* include/wchar.h: Declare __wcsncpy and __vswprintf_chk.
+	* debug/fgetws_chk.c: New file.
+	* debug/fgetws_u_chk.c: New file.
+	* debug/fwprintf_chk.c: New file.
+	* debug/swprintf_chk.c: New file.
+	* debug/vfwprintf_chk.c: New file.
+	* debug/vswprintf_chk.c: New file.
+	* debug/vwprintf_chk.c: New file.
+	* debug/wcpcpy_chk.c: New file.
+	* debug/wcpncpy_chk.c: New file.
+	* debug/wcscat_chk.c: New file.
+	* debug/wcscpy_chk.c: New file.
+	* debug/wcsncat_chk.c: New file.
+	* debug/wcsncpy_chk.c: New file.
+	* debug/wmemcpy_chk.c: New file.
+	* debug/wmemmove_chk.c: New file.
+	* debug/wmempcpy_chk.c: New file.
+	* debug/wmemset_chk.c: New file.
+	* debug/wprintf_chk.c: New file.
+	* debug/tst-chk1.c: Add tests for new functions.
+	* debug/Versions: Export new functions.
+	* debug/Makefile (routines): Add new functions.
+
 2005-07-13  Ulrich Drepper  <drepper@redhat.com>
 
 	* nscd/nscd_helper.c: Add a few __builtin_expect.
diff --git a/debug/Makefile b/debug/Makefile
index 51a9c9d42a..3f18359a74 100644
--- a/debug/Makefile
+++ b/debug/Makefile
@@ -26,13 +26,18 @@ distribute = sigcontextinfo.h register-dump.h frame.h
 
 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 fgets_chk fgets_u_chk \
 	    read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
 	    readlink_chk getwd_chk getcwd_chk realpath_chk ptsname_r_chk \
-	    wctomb_chk stack_chk_fail \
+	    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 \
+	    stack_chk_fail \
 	    $(static-only-routines)
 static-only-routines := warning-nop stack_chk_fail_local
 
@@ -48,6 +53,14 @@ 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
diff --git a/debug/Versions b/debug/Versions
index 53fe6c02b0..0953c7733b 100644
--- a/debug/Versions
+++ b/debug/Versions
@@ -24,6 +24,11 @@ libc {
     __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;
 
     __stack_chk_fail;
   }
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/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/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 ba50973868..a83bd843c6 100644
--- a/debug/tst-chk1.c
+++ b/debug/tst-chk1.c
@@ -25,9 +25,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <wchar.h>
 #include <sys/socket.h>
 #include <sys/un.h>
-#include <unistd.h>
 
 char *temp_filename;
 static void do_prepare (void);
@@ -72,6 +73,7 @@ handler (int sig)
 }
 
 char buf[10];
+wchar_t wbuf[10];
 volatile size_t l0;
 volatile char *p;
 const char *str1 = "JIHGFEDCBA";
@@ -79,6 +81,11 @@ 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;
@@ -123,6 +130,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
@@ -138,7 +146,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);
@@ -169,7 +178,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);
@@ -187,20 +197,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 (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEDX98", 10))
+  if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEcd67", 10))
+    FAIL ();
+
+  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);
@@ -224,14 +238,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
@@ -282,6 +298,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
 
@@ -352,6 +372,215 @@ 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 ();
+
+  /* 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
+  p = 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
+  p = 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
+  p = 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
+  p = 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
diff --git a/debug/vfwprintf_chk.c b/debug/vfwprintf_chk.c
new file mode 100644
index 0000000000..d4af557ae4
--- /dev/null
+++ b/debug/vfwprintf_chk.c
@@ -0,0 +1,42 @@
+/* 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
+__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;
+}
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/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/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/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/include/bits/wchar2.h b/include/bits/wchar2.h
new file mode 100644
index 0000000000..a18dccfc55
--- /dev/null
+++ b/include/bits/wchar2.h
@@ -0,0 +1 @@
+#include <wcsmbs/bits/wchar2.h>
diff --git a/include/wchar.h b/include/wchar.h
index 0f91114c41..e8079e6d80 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -82,6 +82,8 @@ extern size_t __wcsnrtombs (char *__restrict __dst,
 			    __const wchar_t **__restrict __src,
 			    size_t __nwc, size_t __len,
 			    __mbstate_t *__restrict __ps);
+extern wchar_t *__wcsncpy (wchar_t *__restrict __dest,
+			 __const wchar_t *__restrict __src, size_t __n);
 extern wchar_t *__wcpcpy (wchar_t *__dest, __const wchar_t *__src);
 extern wchar_t *__wcpncpy (wchar_t *__dest, __const wchar_t *__src,
 			   size_t __n);
@@ -112,6 +114,13 @@ extern int __vfwprintf (__FILE *__restrict __s,
      /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
 
 
+extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
+			    int __flag, size_t __s_len,
+			    __const wchar_t *__restrict __format,
+			    __gnuc_va_list __arg)
+     /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
+libc_hidden_proto (__vswprintf_chk)
+
 /* Internal functions.  */
 extern size_t __mbsrtowcs_l (wchar_t *dst, const char **src, size_t len,
 			     mbstate_t *ps, __locale_t l) attribute_hidden;
diff --git a/libio/strfile.h b/libio/strfile.h
index b91111a9d6..53a36a3db8 100644
--- a/libio/strfile.h
+++ b/libio/strfile.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999, 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
@@ -73,3 +73,14 @@ typedef struct
 } _IO_strnfile;
 
 extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
+
+
+typedef struct
+{
+  _IO_strfile f;
+  /* This is used for the characters which do not fit in the buffer
+     provided by the user.  */
+  wchar_t overflow_buf[64];
+} _IO_wstrnfile;
+
+extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden;
diff --git a/libio/vswprintf.c b/libio/vswprintf.c
index 42168aade4..eda8495241 100644
--- a/libio/vswprintf.c
+++ b/libio/vswprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994,1997,1999-2002,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1994,1997,1999-2002,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
@@ -29,15 +29,6 @@
 #include "strfile.h"
 
 
-typedef struct
-{
-  _IO_strfile f;
-  /* This is used for the characters which do not fit in the buffer
-     provided by the user.  */
-  wchar_t overflow_buf[64];
-} _IO_wstrnfile;
-
-
 static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) __THROW;
 
 static wint_t
@@ -75,7 +66,7 @@ _IO_wstrn_overflow (fp, c)
 }
 
 
-static const struct _IO_jump_t _IO_wstrn_jumps =
+const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden =
 {
   JUMP_INIT_DUMMY,
   JUMP_INIT(finish, _IO_wstr_finish),
diff --git a/string/bits/string3.h b/string/bits/string3.h
index bcda42a232..4271e5f148 100644
--- a/string/bits/string3.h
+++ b/string/bits/string3.h
@@ -144,6 +144,22 @@ __strncpy_ichk (char *__restrict __dest, const char *__restrict __src,
 }
 
 
+// XXX We have no corresponding builtin yet.
+extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
+			    size_t __destlen) __THROW;
+extern char *__REDIRECT (__stpncpy_alias, (char *__dest, const char *__src,
+					   size_t __n), stpncpy)__THROW;
+
+extern __always_inline char *
+stpncpy (char *__dest, const char *__src, size_t __n)
+{
+  if (__bos (__dest) != (size_t) -1
+      && (!__builtin_constant_p (__n) || __n <= __bos (__dest)))
+    return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
+  return __stpncpy_alias (__dest, __src, __n);
+}
+
+
 #define strcat(dest, src) \
   ((__bos (dest) != (size_t) -1)					\
    ? __builtin___strcat_chk (dest, src, __bos (dest))			\
diff --git a/sysdeps/generic/stpncpy_chk.c b/sysdeps/generic/stpncpy_chk.c
new file mode 100644
index 0000000000..d136339dea
--- /dev/null
+++ b/sysdeps/generic/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/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
new file mode 100644
index 0000000000..5d5b102649
--- /dev/null
+++ b/wcsmbs/bits/wchar2.h
@@ -0,0 +1,288 @@
+/* Checking macros for wchar functions.
+   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.  */
+
+#ifndef _WCHAR_H
+# error "Never include <bits/wchar.h> directly; use <wchar.h> instead."
+#endif
+
+
+extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1,
+			       __const wchar_t *__restrict __s2, size_t __n,
+			       size_t __ns1) __THROW;
+extern wchar_t *__REDIRECT (__wmemcpy_alias, (wchar_t *__restrict __s1,
+					      __const wchar_t *__restrict __s2,
+					      size_t __n), wmemcpy) __THROW;
+
+extern __always_inline wchar_t *
+wmemcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
+	 size_t __n)
+{
+  if (__bos0 (__s1) != (size_t) -1)
+    return __wmemcpy_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+  return __wmemcpy_alias (__s1, __s2, __n);
+}
+
+
+extern wchar_t *__wmemmove_chk (wchar_t *__s1, __const wchar_t *__s2,
+				size_t __n, size_t __ns1) __THROW;
+extern wchar_t *__REDIRECT (__wmemmove_alias, (wchar_t *__s1,
+					       __const wchar_t *__s2,
+					       size_t __n), wmemmove) __THROW;
+
+extern __always_inline wchar_t *
+wmemmove (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
+	  size_t __n)
+{
+  if (__bos0 (__s1) != (size_t) -1)
+    return __wmemmove_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+  return __wmemmove_alias (__s1, __s2, __n);
+}
+
+
+#ifdef __USE_GNU
+extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1,
+				__const wchar_t *__restrict __s2, size_t __n,
+				size_t __ns1) __THROW;
+extern wchar_t *__REDIRECT (__wmempcpy_alias,
+			    (wchar_t *__restrict __s1,
+			     __const wchar_t *__restrict __s2,
+			     size_t __n), wmempcpy) __THROW;
+
+extern __always_inline wchar_t *
+wmempcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
+	  size_t __n)
+{
+  if (__bos0 (__s1) != (size_t) -1)
+    return __wmempcpy_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+  return __wmempcpy_alias (__s1, __s2, __n);
+}
+#endif
+
+
+extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
+			       size_t __ns) __THROW;
+extern wchar_t *__REDIRECT (__wmemset_alias, (wchar_t *__s, wchar_t __c,
+					      size_t __n), wmemset) __THROW;
+
+extern __always_inline wchar_t *
+wmemset (wchar_t *__restrict __s, wchar_t __c, size_t __n)
+{
+  if (__bos0 (__s) != (size_t) -1)
+    return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t));
+  return __wmemset_alias (__s, __c, __n);
+}
+
+
+extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest,
+			      __const wchar_t *__restrict __src,
+			      size_t __n) __THROW;
+extern wchar_t *__REDIRECT (__wcscpy_alias,
+			    (wchar_t *__restrict __dest,
+			     __const wchar_t *__restrict __src), wcscpy)
+  __THROW;
+
+extern __always_inline wchar_t *
+wcscpy (wchar_t *__dest, __const wchar_t *__src)
+{
+  if (__bos (__dest) != (size_t) -1)
+    return __wcscpy_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
+  return __wcscpy_alias (__dest, __src);
+}
+
+
+extern wchar_t *__wcpcpy_chk (wchar_t *__dest, __const wchar_t *__src,
+			      size_t __destlen) __THROW;
+extern wchar_t *__REDIRECT (__wcpcpy_alias, (wchar_t *__dest,
+					     __const wchar_t *__src), wcpcpy)
+  __THROW;
+
+extern __always_inline wchar_t *
+wcpcpy (wchar_t *__dest, __const wchar_t *__src)
+{
+  if (__bos (__dest) != (size_t) -1)
+    return __wcpcpy_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
+  return __wcpcpy_alias (__dest, __src);
+}
+
+
+extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest,
+			       __const wchar_t *__restrict __src, size_t __n,
+			       size_t __destlen) __THROW;
+extern wchar_t *__REDIRECT (__wcsncpy_alias,
+			    (wchar_t *__restrict __dest,
+			     __const wchar_t *__restrict __src, size_t __n),
+			    wcsncpy) __THROW;
+
+extern __always_inline wchar_t *
+wcsncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n)
+{
+  if (__bos (__dest) != (size_t) -1
+      && (!__builtin_constant_p (__n) || __bos (__dest) >= __n))
+    return __wcsncpy_chk (__dest, __src, __n,
+			  __bos (__dest) / sizeof (wchar_t));
+  return __wcsncpy_alias (__dest, __src, __n);
+}
+
+
+extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest,
+			       __const wchar_t *__restrict __src, size_t __n,
+			       size_t __destlen) __THROW;
+extern wchar_t *__REDIRECT (__wcpncpy_alias,
+			    (wchar_t *__restrict __dest,
+			     __const wchar_t *__restrict __src, size_t __n),
+			    wcpncpy) __THROW;
+
+extern __always_inline wchar_t *
+wcpncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n)
+{
+  if (__bos (__dest) != (size_t) -1
+      && (!__builtin_constant_p (__n) || __bos (__dest) >= __n))
+    return __wcpncpy_chk (__dest, __src, __n,
+			  __bos (__dest) / sizeof (wchar_t));
+  return __wcpncpy_alias (__dest, __src, __n);
+}
+
+
+extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest,
+			      __const wchar_t *__restrict __src,
+			      size_t __destlen) __THROW;
+extern wchar_t *__REDIRECT (__wcscat_alias,
+			    (wchar_t *__restrict __dest,
+			     __const wchar_t *__restrict __src), wcscat)
+  __THROW;
+
+extern __always_inline wchar_t *
+wcscat (wchar_t *__dest, __const wchar_t *__src)
+{
+  if (__bos (__dest) != (size_t) -1)
+    return __wcscat_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
+  return __wcscat_alias (__dest, __src);
+}
+
+
+extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest,
+			       __const wchar_t *__restrict __src,
+			       size_t __n, size_t __destlen) __THROW;
+extern wchar_t *__REDIRECT (__wcsncat_alias,
+			    (wchar_t *__restrict __dest,
+			     __const wchar_t *__restrict __src, size_t __n),
+			    wcsncat) __THROW;
+
+extern __always_inline wchar_t *
+wcsncat (wchar_t *__dest, __const wchar_t *__src, size_t __n)
+{
+  if (__bos (__dest) != (size_t) -1)
+    return __wcsncat_chk (__dest, __src, __n,
+			  __bos (__dest) / sizeof (wchar_t));
+  return __wcsncat_alias (__dest, __src, __n);
+}
+
+
+extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n,
+			   int __flag, size_t __s_len,
+			   __const wchar_t *__restrict __format, ...)
+     __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */;
+
+/* XXX We might want to have support in gcc for swprintf.  */
+#define swprintf(s, n, format, ...) \
+  (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1			      \
+   ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), format,	      \
+		     __VA_ARGS__)					      \
+   : swprintf (s, n, format, __VA_ARGS__))
+
+
+extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
+			    int __flag, size_t __s_len,
+			    __const wchar_t *__restrict __format,
+			    __gnuc_va_list __arg)
+     __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
+extern int __REDIRECT (__vswprintf_alias,
+		       (wchar_t *__restrict __s, size_t __n,
+			__const wchar_t *__restrict __format,
+			__gnuc_va_list __arg), vswprintf)
+     __THROW /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
+
+
+extern __always_inline int
+vswprintf (wchar_t *__s, size_t __n, __const wchar_t *__format,
+	   __gnuc_va_list __arg)
+{
+  if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
+    return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s),
+			    __format, __arg);
+  return vswprintf (__s, __n, __format, __arg);
+}
+
+
+#if __USE_FORTIFY_LEVEL > 1
+
+extern int __fwprintf_chk (FILE *__restrict __stream, int __flag,
+			   __const wchar_t *__restrict __format, ...);
+extern int __wprintf_chk (int __flag, __const wchar_t *__restrict __format,
+			  ...);
+extern int __vfwprintf_chk (FILE *__restrict __stream, int __flag,
+			    __const wchar_t *__restrict __format,
+			    _G_va_list __ap);
+extern int __vwprintf_chk (int __flag, __const wchar_t *__restrict __format,
+			   _G_va_list __ap);
+
+# define wprintf(...) \
+  __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
+# define fwprintf(stream, ...) \
+  __fwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
+# define vwprintf(format, ap) \
+  __vwprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
+# define vfwprintf(stream, format, ap) \
+  __vfwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
+
+#endif
+
+extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
+			      FILE *__restrict __stream) __wur;
+extern wchar_t *__REDIRECT (__fgetws_alias,
+			    (wchar_t *__restrict __s, int __n,
+			     FILE *__restrict __stream), fgetws) __wur;
+
+extern __always_inline __wur wchar_t *
+fgetws (wchar_t *__restrict __s, int __n, FILE *__restrict __stream)
+{
+  if (__bos (__s) != (size_t) -1
+      && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
+    return __fgetws_chk (__s, __bos (__s), __n, __stream);
+  return __fgetws_alias (__s, __n, __stream);
+}
+
+#ifdef __USE_GNU
+extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size,
+				       int __n, FILE *__restrict __stream)
+  __wur;
+extern wchar_t *__REDIRECT (__fgetws_unlocked_alias,
+			    (wchar_t *__restrict __s, int __n,
+			     FILE *__restrict __stream), fgetws_unlocked)
+  __wur;
+
+extern __always_inline __wur wchar_t *
+fgetws_unlocked (wchar_t *__restrict __s, int __n, FILE *__restrict __stream)
+{
+  if (__bos (__s) != (size_t) -1
+      && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
+    return __fgetws_unlocked_chk (__s, __bos (__s), __n, __stream);
+  return __fgetws_unlocked_alias (__s, __n, __stream);
+}
+#endif
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index fe4ee80bff..0c02dcc574 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -833,6 +833,13 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
 # include <wctype.h>
 #endif
 
+
+/* Define some macros helping to catch buffer overflows.  */
+#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+# include <bits/wchar2.h>
+#endif
+
+
 __END_DECLS
 
 #endif	/* _WCHAR_H defined */
diff --git a/wcsmbs/wcsncpy.c b/wcsmbs/wcsncpy.c
index 8469d94d79..06a20d2333 100644
--- a/wcsmbs/wcsncpy.c
+++ b/wcsmbs/wcsncpy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* 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.
 
@@ -22,7 +22,7 @@
 
 /* Copy no more than N wide-characters of SRC to DEST.	*/
 wchar_t *
-wcsncpy (dest, src, n)
+__wcsncpy (dest, src, n)
      wchar_t *dest;
      const wchar_t *src;
      size_t n;
@@ -84,3 +84,4 @@ wcsncpy (dest, src, n)
 
   return s;
 }
+weak_alias (__wcsncpy, wcsncpy)