about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-09-29 19:10:50 +0000
committerJakub Jelinek <jakub@redhat.com>2007-09-29 19:10:50 +0000
commit441097af93882803bbb3296dd1fdbdd4a7773deb (patch)
treea221d657b763bcf793ea407fcd8b81d91ac06a5a
parent62beba6902f315a14113c26ed3e068342e101399 (diff)
downloadglibc-cvs/fedora-glibc-2_6_90-16.tar.gz
glibc-cvs/fedora-glibc-2_6_90-16.tar.xz
glibc-cvs/fedora-glibc-2_6_90-16.zip
Updated to fedora-glibc-20070929T1859 cvs/fedora-glibc-2_6_90-16
-rw-r--r--ChangeLog140
-rw-r--r--debug/tst-chk1.c22
-rw-r--r--elf/dl-close.c6
-rw-r--r--elf/dl-deps.c100
-rw-r--r--elf/dl-fini.c4
-rw-r--r--elf/dl-lookup.c156
-rw-r--r--elf/dl-open.c2
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in11
-rw-r--r--iconv/iconv_open.c49
-rw-r--r--iconvdata/Makefile8
-rw-r--r--iconvdata/TESTS3
-rw-r--r--iconvdata/gconv-modules9
-rw-r--r--iconvdata/koi8-r.c4
-rw-r--r--iconvdata/koi8-ru.c29
-rw-r--r--iconvdata/mac-centraleurope.c29
-rwxr-xr-xiconvdata/tst-tables.sh2
-rw-r--r--include/link.h7
-rw-r--r--intl/dcigettext.c35
-rw-r--r--intl/gettextP.h1
-rw-r--r--intl/loadmsgcat.c4
-rw-r--r--libio/bits/stdio2.h82
-rw-r--r--localedata/ChangeLog12
-rw-r--r--localedata/charmaps/KOI8-RU264
-rw-r--r--localedata/charmaps/MAC-CENTRALEUROPE261
-rw-r--r--localedata/locales/de_CH5
-rw-r--r--misc/sys/cdefs.h13
-rw-r--r--posix/bits/unistd.h224
-rw-r--r--posix/regcomp.c5
-rw-r--r--resolv/ns_print.c49
-rw-r--r--socket/bits/socket2.h36
-rw-r--r--stdlib/bits/stdlib.h65
-rw-r--r--string/stratcliff.c322
-rw-r--r--sysdeps/generic/ldsodefs.h4
-rw-r--r--sysdeps/posix/getaddrinfo.c2
-rw-r--r--sysdeps/x86_64/cacheinfo.c76
-rw-r--r--sysdeps/x86_64/memcpy.S338
-rw-r--r--wcsmbs/Makefile3
-rw-r--r--wcsmbs/bits/wchar2.h228
-rw-r--r--wcsmbs/wcsatcliff.c20
-rw-r--r--wcsmbs/wcsnlen.c13
41 files changed, 2074 insertions, 573 deletions
diff --git a/ChangeLog b/ChangeLog
index 5015171f72..90fbcf68f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,143 @@
+2007-09-24  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/generic/ldsodefs.h (struct dl_scope_free_list): Store
+	void * pointers instead of struct link_map **.
+	(_dl_scope_free): Change argument type to void *.
+	* include/link.h (struct link_map): Change type of l_reldeps
+	to struct link_map_reldeps, move l_reldepsact into that
+	struct too.
+	* elf/dl-deps.c: Include atomic.h.
+	(_dl_map_object_deps): Only change l->l_initfini when it is
+	fully populated, use _dl_scope_free for freeing it.  Optimize
+	removal of libs from reldeps by using l_reserved flag, when
+	some removal is needed, allocate a new list instead of
+	reallocating and free the old with _dl_scope_free.  Adjust
+	for l_reldeps and l_reldepsact changes.
+	* elf/dl-lookup.c (add_dependency): Likewise.  Reorganize to allow
+	searching in l_initfini and l_reldeps without holding dl_load_lock.
+	* elf/dl-fini.c (_dl_sort_fini): Adjust for l_reldeps and
+	l_reldepsact changes.
+	* elf/dl-close.c (_dl_close_worker): Likewise.
+	* elf/dl-open.c (_dl_scope_free): Change argument type to void *.
+
+2007-09-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* iconvdata/Makefile (modules): Add KOI8-RU.
+	(distribute): Add koi8-ru.c.
+	(gen-8bit-gap-modules): Add koi8-ru.
+	* iconvdata/koi8-ru.c: New file.
+	* iconvdata/gconv-modules: Add entries for KOI8-RU.
+	* iconvdata/TESTS: Likewise.
+	* iconvdata/tst-tables.sh: Likewise.
+
+	* iconvdata/koi8-r.c (HAS_HOLES): Define to 0.
+
+2007-09-26  Jakub Jelinek  <jakub@redhat.com>
+
+	* misc/sys/cdefs.h (__warndecl, __errordecl): For GCC 4.3+ define
+	with __warning__/__error__ attributes.
+	(__warnattr): Define.
+	* stdlib/bits/stdlib.h (__realpath_chk_warn, __ptsname_r_chk_warn,
+	__mbstowcs_chk_warn, __wcstombs_chk_warn): New aliases with
+	__warnattr.
+	(realpath, ptsname_r, mbstowcs, wcstombs): Call __*_chk_warn instead
+	of __*_chk if compile time detectable overflow is found.
+	* libio/bits/stdio2.h (__fgets_chk_warn, __fread_chk_warn,
+	__fgets_unlocked_chk_warn, __fread_unlocked_chk_warn): New aliases
+	with __warnattr.
+	(fgets, fread, fgets_unlocked, fread_unlocked): Call __*_chk_warn
+	instead of __*_chk if compile time detectable overflow is found.
+	(__gets_alias): Rename to...
+	(__gets_warn): ... this.  Add __warnattr.
+	(gets): Call __gets_warn instead of __gets_alias.
+	* socket/bits/socket2.h (__recv_chk_warn, __recvfrom_chk_warn): New
+	aliases with __warnattr.
+	(recv, recvfrom): Call __*_chk_warn instead of __*_chk if compile
+	time detectable overflow is found.
+	* posix/bits/unistd.h (__read_chk_warn, __pread_chk_warn,
+	__pread64_chk_warn, __readlink_chk_warn, __readlinkat_chk_warn,
+	__getcwd_chk_warn, __confstr_chk_warn, __getgroups_chk_warn,
+	__ttyname_r_chk_warn, __getlogin_r_chk_warn, __gethostname_chk_warn,
+	__getdomainname_chk_warn): New aliases with __warnattr.
+	(read, pread, pread64, readlink, readlinkat, getcwd, confstr,
+	getgroups, ttyname_r, getlogin_r, gethostname, getdomainname): Call
+	__*_chk_warn instead of __*_chk if compile time detectable overflow
+	is found.
+	(__getgroups_chk): Rename argument to __listlen from listlen.
+	(__getwd_alias): Rename to...
+	(__getwd_warn): ... this.  Add __warnattr.
+	(getwd): Call __getwd_warn instead of __getwd_alias.
+	* wcsmbs/bits/wchar2.h (__wmemcpy_chk_warn, __wmemmove_chk_warn,
+	__wmempcpy_chk_warn, __wmemset_chk_warn, __wcsncpy_chk_warn,
+	__wcpncpy_chk_warn, __fgetws_chk_warn, __fgetws_unlocked_chk_warn,
+	__mbsrtowcs_chk_warn, __wcsrtombs_chk_warn, __mbsnrtowcs_chk_warn,
+	__wcsnrtombs_chk_warn): New aliases with __warnattr.
+	(wmemcpy, wmemmove, wmempcpy, wmemset, mbsrtowcs, wcsrtombs,
+	mbsnrtowcs, wcsnrtombs): Call __*_chk_warn instead of __*_chk if
+	compile time detectable overflow is found.
+	(wcsncpy, wcpncpy): Likewise.  For constant __n fix check whether
+	to use __*_chk or not.
+	(fgetws, fgetws_unlocked): Divide __bos by sizeof (wchar_t), both
+	in comparisons which function should be called and in __*_chk*
+	arguments.  Call __*_chk_warn instead of __*_chk if compile time
+	detectable overflow is found.
+	(swprintf, vswprintf): Divide __bos by sizeof (wchar_t) in
+	__*_chk argument.
+	* debug/tst-chk1.c (do_test): Add a few more tests.
+
+2007-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #5058]
+	* intl/gettextP.h (struct loaded_domain): Add conversions_lock member.
+	* intl/loadmsgcat.c (_nl_load_domain): Initialize conversions_lock.
+	(_nl_unload_domain): Finalize conversions_lock.
+	* intl/dcigettext.c (_nl_find_msg): Take conversions_lock before
+	handling table of known conversions.
+
+2007-09-24  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/posix/getaddrinfo.c (getaddrinfo): Use
+	close_not_cancel_no_status instead of close.
+
+2007-09-13  Aurelien Jarno  <aurelien@aurel32.net>
+
+	[BZ #5028]
+	* posix/regcomp.c (lookup_collation_sequence_value): Check that
+	nrules != 0 for multibyte chars.
+
+2007-09-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* resolv/ns_print.c (ns_sprintrrf): Handle ns_t_a6 and ns_t_opt.
+	Provide better error message in case the type is unknown.
+
+	[BZ #4963]
+	* wcsmbs/wcsnlen.c: Don't reference before checking the length.
+	* string/stratcliff.c: Make usable to test wide char functions.
+	* wcsmbs/wcsatcliff.c: New file.
+	* wcsmbs/Makefiel (tests): Add wcsatcliff.
+
+	[BZ #4972]
+	* iconvdata/Makefile (modules): Add MAC-CENTRALEUROPE.
+	(distribute): Add mac-centraleurope.c.
+	(gen-8bit-gap-modules): Add mac-centraleurope.
+	* iconvdata/mac-centraleurope.c: New file.
+	* iconvdata/gconv-modules: Add entries for MAC-CENTRALEUROPE.
+	* iconvdata/TESTS: Likewise.
+	* iconvdata/tst-tables.sh: Likewise.
+
+	[BZ #5043]
+	* iconv/iconv_open.c (iconv_open): For large codeset names use malloc.
+
+2007-09-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/cacheinfo.c (__x86_64_data_cache_size_half): Renamed
+	from __x86_64_core_cache_size_half.
+	(init_cacheinfo): Compute shared cache size for AMD processors with
+	shared L3 correctly.
+	* sysdeps/x86_64/memcpy.S: Adjust for __x86_64_data_cache_size_half
+	name change.
+	Patch in large parts by Evandro Menezes.
+
 2007-09-19  Ulrich Drepper  <drepper@redhat.com>
 
 	* elf/dl-lookup.c (add_dependency): Handle failing memory
diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
index 881f2b5899..e982409e7f 100644
--- a/debug/tst-chk1.c
+++ b/debug/tst-chk1.c
@@ -320,6 +320,14 @@ do_test (void)
   CHK_FAIL_START
   snprintf (buf + 8, l0 + 3, "%d", num2);
   CHK_FAIL_END
+
+  CHK_FAIL_START
+  swprintf (wbuf + 8, 3, L"%d", num1);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  swprintf (wbuf + 8, l0 + 3, L"%d", num1);
+  CHK_FAIL_END
 # endif
 
   memcpy (buf, str1 + 2, l0 + 9);
@@ -517,11 +525,15 @@ do_test (void)
   CHK_FAIL_END
 
   CHK_FAIL_START
+  wmemcpy (wbuf + 9, 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);
+  wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
   CHK_FAIL_END
 
   CHK_FAIL_START
@@ -541,6 +553,14 @@ do_test (void)
   CHK_FAIL_END
 
   CHK_FAIL_START
+  wcsncpy (wbuf + 9, L"XABCDEFGH", 8);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
+  wcpncpy (wbuf + 9, L"XABCDEFGH", 8);
+  CHK_FAIL_END
+
+  CHK_FAIL_START
   wcpncpy (wbuf + 6, L"cd", l0 + 5);
   CHK_FAIL_END
 
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 67188bb6c1..264e13a8ee 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -203,9 +203,9 @@ _dl_close_worker (struct link_map *map)
 	}
       /* And the same for relocation dependencies.  */
       if (l->l_reldeps != NULL)
-	for (unsigned int j = 0; j < l->l_reldepsact; ++j)
+	for (unsigned int j = 0; j < l->l_reldeps->act; ++j)
 	  {
-	    struct link_map *jmap = l->l_reldeps[j];
+	    struct link_map *jmap = l->l_reldeps->list[j];
 
 	    if (jmap->l_idx != IDX_STILL_USED)
 	      {
@@ -497,7 +497,7 @@ _dl_close_worker (struct link_map *map)
       THREAD_GSCOPE_WAIT ();
 
       /* Now we can free any queued old scopes.  */
-      struct dl_scope_free_list *fsl  = GL(dl_scope_free_list);
+      struct dl_scope_free_list *fsl = GL(dl_scope_free_list);
       if (fsl != NULL)
 	while (fsl->count > 0)
 	  free (fsl->list[--fsl->count]);
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 4ec984e15b..34c6024efa 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -1,5 +1,6 @@
 /* Load the dependencies of a mapped object.
-   Copyright (C) 1996-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1996-2003, 2004, 2005, 2006, 2007
+   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
@@ -17,6 +18,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <atomic.h>
 #include <assert.h>
 #include <dlfcn.h>
 #include <errno.h>
@@ -465,15 +467,17 @@ _dl_map_object_deps (struct link_map *map,
 	{
 	  needed[nneeded++] = NULL;
 
-	  l->l_initfini = (struct link_map **)
+	  struct link_map **l_initfini = (struct link_map **)
 	    malloc ((2 * nneeded + 1) * sizeof needed[0]);
-	  if (l->l_initfini == NULL)
+	  if (l_initfini == NULL)
 	    _dl_signal_error (ENOMEM, map->l_name, NULL,
 			      N_("cannot allocate dependency list"));
-	  l->l_initfini[0] = l;
-	  memcpy (&l->l_initfini[1], needed, nneeded * sizeof needed[0]);
-	  memcpy (&l->l_initfini[nneeded + 1], l->l_initfini,
+	  l_initfini[0] = l;
+	  memcpy (&l_initfini[1], needed, nneeded * sizeof needed[0]);
+	  memcpy (&l_initfini[nneeded + 1], l_initfini,
 		  nneeded * sizeof needed[0]);
+	  atomic_write_barrier ();
+	  l->l_initfini = l_initfini;
 	}
 
       /* If we have no auxiliary objects just go on to the next map.  */
@@ -487,25 +491,26 @@ _dl_map_object_deps (struct link_map *map,
   if (errno == 0 && errno_saved != 0)
     __set_errno (errno_saved);
 
+  struct link_map **old_l_initfini = NULL;
   if (map->l_initfini != NULL && map->l_type == lt_loaded)
     {
       /* This object was previously loaded as a dependency and we have
 	 a separate l_initfini list.  We don't need it anymore.  */
       assert (map->l_searchlist.r_list == NULL);
-      free (map->l_initfini);
+      old_l_initfini = map->l_initfini;
     }
 
   /* Store the search list we built in the object.  It will be used for
      searches in the scope of this object.  */
-  map->l_initfini =
+  struct link_map **l_initfini =
     (struct link_map **) malloc ((2 * nlist + 1)
 				 * sizeof (struct link_map *));
-  if (map->l_initfini == NULL)
+  if (l_initfini == NULL)
     _dl_signal_error (ENOMEM, map->l_name, NULL,
 		      N_("cannot allocate symbol search list"));
 
 
-  map->l_searchlist.r_list = &map->l_initfini[nlist + 1];
+  map->l_searchlist.r_list = &l_initfini[nlist + 1];
   map->l_searchlist.r_nlist = nlist;
 
   for (nlist = 0, runp = known; runp; runp = runp->next)
@@ -546,10 +551,10 @@ _dl_map_object_deps (struct link_map *map,
 Filters not supported with LD_TRACE_PRELINKING"));
 	    }
 
-	  cnt = _dl_build_local_scope (map->l_initfini, l);
+	  cnt = _dl_build_local_scope (l_initfini, l);
 	  assert (cnt <= nlist);
 	  for (j = 0; j < cnt; j++)
-	    map->l_initfini[j]->l_reserved = 0;
+	    l_initfini[j]->l_reserved = 0;
 
 	  l->l_local_scope[0] =
 	    (struct r_scope_elem *) malloc (sizeof (struct r_scope_elem)
@@ -561,35 +566,50 @@ Filters not supported with LD_TRACE_PRELINKING"));
 	  l->l_local_scope[0]->r_nlist = cnt;
 	  l->l_local_scope[0]->r_list =
 	    (struct link_map **) (l->l_local_scope[0] + 1);
-	  memcpy (l->l_local_scope[0]->r_list, map->l_initfini,
+	  memcpy (l->l_local_scope[0]->r_list, l_initfini,
 		  cnt * sizeof (struct link_map *));
 	}
     }
 
   /* Maybe we can remove some relocation dependencies now.  */
   assert (map->l_searchlist.r_list[0] == map);
-  for (i = 0; i < map->l_reldepsact; ++i)
+  struct link_map_reldeps *l_reldeps = NULL;
+  if (map->l_reldeps != NULL)
     {
-      unsigned int j;
+      for (i = 1; i < nlist; ++i)
+	map->l_searchlist.r_list[i]->l_reserved = 1;
 
-      for (j = 1; j < nlist; ++j)
-	if (map->l_searchlist.r_list[j] == map->l_reldeps[i])
+      struct link_map **list = &map->l_reldeps->list[0];
+      for (i = 0; i < map->l_reldeps->act; ++i)
+	if (list[i]->l_reserved)
 	  {
-	    /* A direct or transitive dependency is also on the list
-	       of relocation dependencies.  Remove the latter.  */
-	    for (j = i + 1; j < map->l_reldepsact; ++j)
-	      map->l_reldeps[j - 1] = map->l_reldeps[j];
-
-	    --map->l_reldepsact;
-
-	    /* Account for the '++i' performed by the 'for'.  */
-	    --i;
-	    break;
+	    /* Need to allocate new array of relocation dependencies.  */
+	    struct link_map_reldeps *l_reldeps;
+	    l_reldeps = malloc (sizeof (*l_reldeps)
+	    			+ map->l_reldepsmax
+				  * sizeof (struct link_map *));
+	    if (l_reldeps == NULL)
+	      /* Bad luck, keep the reldeps duplicated between
+		 map->l_reldeps->list and map->l_initfini lists.  */
+	      ;
+	    else
+	      {
+		unsigned int j = i;
+		memcpy (&l_reldeps->list[0], &list[0],
+			i * sizeof (struct link_map *));
+		for (i = i + 1; i < map->l_reldeps->act; ++i)
+		  if (!list[i]->l_reserved)
+		    l_reldeps->list[j++] = list[i];
+		l_reldeps->act = j;
+	      }
 	  }
+
+      for (i = 1; i < nlist; ++i)
+	map->l_searchlist.r_list[i]->l_reserved = 0;
     }
 
   /* Now determine the order in which the initialization has to happen.  */
-  memcpy (map->l_initfini, map->l_searchlist.r_list,
+  memcpy (l_initfini, map->l_searchlist.r_list,
 	  nlist * sizeof (struct link_map *));
   /* We can skip looking for the binary itself which is at the front
      of the search list.  Look through the list backward so that circular
@@ -602,7 +622,7 @@ Filters not supported with LD_TRACE_PRELINKING"));
 
       /* Find the place in the initfini list where the map is currently
 	 located.  */
-      for (j = 1; map->l_initfini[j] != l; ++j)
+      for (j = 1; l_initfini[j] != l; ++j)
 	;
 
       /* Find all object for which the current one is a dependency and
@@ -611,19 +631,18 @@ Filters not supported with LD_TRACE_PRELINKING"));
 	{
 	  struct link_map **runp;
 
-	  runp = map->l_initfini[k]->l_initfini;
+	  runp = l_initfini[k]->l_initfini;
 	  if (runp != NULL)
 	    {
 	      while (*runp != NULL)
 		if (__builtin_expect (*runp++ == l, 0))
 		  {
-		    struct link_map *here = map->l_initfini[k];
+		    struct link_map *here = l_initfini[k];
 
 		    /* Move it now.  */
-		    memmove (&map->l_initfini[j] + 1,
-			     &map->l_initfini[j],
+		    memmove (&l_initfini[j] + 1, &l_initfini[j],
 			     (k - j) * sizeof (struct link_map *));
-		    map->l_initfini[j] = here;
+		    l_initfini[j] = here;
 
 		    /* Don't insert further matches before the last
 		       entry moved to the front.  */
@@ -635,7 +654,18 @@ Filters not supported with LD_TRACE_PRELINKING"));
 	}
     }
   /* Terminate the list of dependencies.  */
-  map->l_initfini[nlist] = NULL;
+  l_initfini[nlist] = NULL;
+  atomic_write_barrier ();
+  map->l_initfini = l_initfini;
+  if (l_reldeps != NULL)
+    {
+      atomic_write_barrier ();
+      void *old_l_reldeps = map->l_reldeps;
+      map->l_reldeps = l_reldeps;
+      _dl_scope_free (old_l_reldeps);
+    }
+  if (old_l_initfini != NULL)
+    _dl_scope_free (old_l_initfini);
 
   if (errno_reason)
     _dl_signal_error (errno_reason == -1 ? 0 : errno_reason, objname,
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index 3cd7e7bbff..273bc3a99d 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -82,8 +82,8 @@ _dl_sort_fini (struct link_map *l, struct link_map **maps, size_t nmaps,
 
 	    if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
 	      {
-		unsigned int m = maps[k]->l_reldepsact;
-		struct link_map **relmaps = maps[k]->l_reldeps;
+		unsigned int m = maps[k]->l_reldeps->act;
+		struct link_map **relmaps = &maps[k]->l_reldeps->list[0];
 
 		while (m-- > 0)
 		  {
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index c529007ca1..92dc7b226a 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -88,20 +88,50 @@ static int
 internal_function
 add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
 {
-  struct link_map **list;
   struct link_map *runp;
-  unsigned int act;
   unsigned int i;
   int result = 0;
-  unsigned long long int serial;
 
   /* Avoid self-references and references to objects which cannot be
      unloaded anyway.  */
   if (undef_map == map)
     return 0;
 
+  /* Avoid references to objects which cannot be unloaded anyway.  */
+  assert (map->l_type == lt_loaded);
+  if ((map->l_flags_1 & DF_1_NODELETE) != 0)
+    return 0;
+
+  struct link_map_reldeps *l_reldeps
+    = atomic_forced_read (undef_map->l_reldeps);
+
+  /* Make sure l_reldeps is read before l_initfini.  */
+  atomic_read_barrier ();
+
+  /* Determine whether UNDEF_MAP already has a reference to MAP.  First
+     look in the normal dependencies.  */
+  struct link_map **l_initfini = atomic_forced_read (undef_map->l_initfini);
+  if (l_initfini != NULL)
+    {
+      for (i = 0; l_initfini[i] != NULL; ++i)
+	if (l_initfini[i] == map)
+	  return 0;
+    }
+
+  /* No normal dependency.  See whether we already had to add it
+     to the special list of dynamic dependencies.  */
+  unsigned int l_reldepsact = 0;
+  if (l_reldeps != NULL)
+    {
+      struct link_map **list = &l_reldeps->list[0];
+      l_reldepsact = l_reldeps->act;
+      for (i = 0; i < l_reldepsact; ++i)
+	if (list[i] == map)
+	  return 0;
+    }
+
   /* Save serial number of the target MAP.  */
-  serial = map->l_serial;
+  unsigned long long serial = map->l_serial;
 
   /* Make sure nobody can unload the object while we are at it.  */
   if (__builtin_expect (flags & DL_LOOKUP_GSCOPE_LOCK, 0))
@@ -110,38 +140,52 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
 	 here, that can result in ABBA deadlock.  */
       THREAD_GSCOPE_RESET_FLAG ();
       __rtld_lock_lock_recursive (GL(dl_load_lock));
-      THREAD_GSCOPE_SET_FLAG ();
       /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
 	 it can e.g. point to unallocated memory.  So avoid the optimizer
 	 treating the above read from MAP->l_serial as ensurance it
 	 can safely dereference it.  */
       map = atomic_forced_read (map);
-    }
-  else
-    __rtld_lock_lock_recursive (GL(dl_load_lock));
 
-  /* From this point on it is unsafe to dereference MAP, until it
-     has been found in one of the lists.  */
+      /* From this point on it is unsafe to dereference MAP, until it
+	 has been found in one of the lists.  */
 
-  /* Determine whether UNDEF_MAP already has a reference to MAP.  First
-     look in the normal dependencies.  */
-  if (undef_map->l_initfini != NULL)
-    {
-      list = undef_map->l_initfini;
+      /* Redo the l_initfini check in case undef_map's l_initfini
+	 changed in the mean time.  */
+      if (undef_map->l_initfini != l_initfini
+	  && undef_map->l_initfini != NULL)
+	{
+	  l_initfini = undef_map->l_initfini;
+	  for (i = 0; l_initfini[i] != NULL; ++i)
+	    if (l_initfini[i] == map)
+	      goto out_check;
+	}
 
-      for (i = 0; list[i] != NULL; ++i)
-	if (list[i] == map)
-	  goto out_check;
+      /* Redo the l_reldeps check if undef_map's l_reldeps changed in
+	 the mean time.  */
+      if (undef_map->l_reldeps != NULL)
+	{
+	  if (undef_map->l_reldeps != l_reldeps)
+	    {
+	      struct link_map **list = &undef_map->l_reldeps->list[0];
+	      l_reldepsact = undef_map->l_reldeps->act;
+	      for (i = 0; i < l_reldepsact; ++i)
+		if (list[i] == map)
+		  goto out_check;
+	    }
+	  else if (undef_map->l_reldeps->act > l_reldepsact)
+	    {
+	      struct link_map **list
+		= &undef_map->l_reldeps->list[0];
+	      i = l_reldepsact;
+	      l_reldepsact = undef_map->l_reldeps->act;
+	      for (; i < l_reldepsact; ++i)
+		if (list[i] == map)
+		  goto out_check;
+	    }
+	}
     }
-
-  /* No normal dependency.  See whether we already had to add it
-     to the special list of dynamic dependencies.  */
-  list = undef_map->l_reldeps;
-  act = undef_map->l_reldepsact;
-
-  for (i = 0; i < act; ++i)
-    if (list[i] == map)
-      goto out_check;
+  else
+    __rtld_lock_lock_recursive (GL(dl_load_lock));
 
   /* The object is not yet in the dependency list.  Before we add
      it make sure just one more time the object we are about to
@@ -161,8 +205,8 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
       if (map->l_serial != serial)
 	goto out_check;
 
-      /* Avoid references to objects which cannot be unloaded anyway.  */
-      assert (map->l_type == lt_loaded);
+      /* Redo the NODELETE check, as when dl_load_lock wasn't held
+	 yet this could have changed.  */
       if ((map->l_flags_1 & DF_1_NODELETE) != 0)
 	goto out;
 
@@ -177,33 +221,46 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
 	}
 
       /* Add the reference now.  */
-      if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
+      if (__builtin_expect (l_reldepsact >= undef_map->l_reldepsmax, 0))
 	{
 	  /* Allocate more memory for the dependency list.  Since this
 	     can never happen during the startup phase we can use
 	     `realloc'.  */
-	  void *newp;
-
-	  undef_map->l_reldepsmax += 5;
-	  newp = realloc (undef_map->l_reldeps,
-			  undef_map->l_reldepsmax
-			  * sizeof (struct link_map *));
+	  struct link_map_reldeps *newp;
+	  unsigned int max
+	    = undef_map->l_reldepsmax ? undef_map->l_reldepsmax * 2 : 10;
 
-	  if (__builtin_expect (newp != NULL, 1))
-	    undef_map->l_reldeps = (struct link_map **) newp;
+	  newp = malloc (sizeof (*newp) + max * sizeof (struct link_map *));
+	  if (newp == NULL)
+	    {
+	      /* If we didn't manage to allocate memory for the list this is
+		 no fatal problem.  We simply make sure the referenced object
+		 cannot be unloaded.  This is semantically the correct
+		 behavior.  */
+	      map->l_flags_1 |= DF_1_NODELETE;
+	      goto out;
+	    }
 	  else
-	    /* Correct the addition.  */
-	    undef_map->l_reldepsmax -= 5;
+	    {
+	      if (l_reldepsact)
+		memcpy (&newp->list[0], &undef_map->l_reldeps->list[0],
+			l_reldepsact * sizeof (struct link_map *));
+	      newp->list[l_reldepsact] = map;
+	      newp->act = l_reldepsact + 1;
+	      atomic_write_barrier ();
+	      void *old = undef_map->l_reldeps;
+	      undef_map->l_reldeps = newp;
+	      undef_map->l_reldepsmax = max;
+	      if (old)
+		_dl_scope_free (old);
+	    }
 	}
-
-      /* If we didn't manage to allocate memory for the list this is
-	 no fatal mistake.  We simply make sure the referenced object
-	 cannot be unloaded.  This is semantically the correct
-	 behavior.  */
-      if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
-	undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
       else
-	map->l_flags_1 |= DF_1_NODELETE;
+	{
+	  undef_map->l_reldeps->list[l_reldepsact] = map;
+	  atomic_write_barrier ();
+	  undef_map->l_reldeps->act = l_reldepsact + 1;
+	}
 
       /* Display information if we are debugging.  */
       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
@@ -223,6 +280,9 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
   /* Release the lock.  */
   __rtld_lock_unlock_recursive (GL(dl_load_lock));
 
+  if (__builtin_expect (flags & DL_LOOKUP_GSCOPE_LOCK, 0))
+    THREAD_GSCOPE_SET_FLAG ();
+
   return result;
 
  out_check:
diff --git a/elf/dl-open.c b/elf/dl-open.c
index fda3219ae2..f825aa0437 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -166,7 +166,7 @@ add_to_global (struct link_map *new)
 }
 
 int
-_dl_scope_free (struct r_scope_elem **old)
+_dl_scope_free (void *old)
 {
   struct dl_scope_free_list *fsl;
 #define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0]))
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 525270a5d5..fa022f3404 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-f8
-fedora-sync-date := 2007-09-20 00:07 UTC
-fedora-sync-tag := fedora-glibc-20070920T0007
+fedora-sync-date := 2007-09-29 18:59 UTC
+fedora-sync-tag := fedora-glibc-20070929T1859
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 0c3c3c4dd2..77bcca7199 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 15
+%define glibcrelease 16
 %define run_glibc_tests 1
 %define auxarches i586 i686 athlon sparcv9v sparc64v alphaev6
 %define xenarches i686 athlon
@@ -1010,6 +1010,15 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Sat Sep 29 2007 Jakub Jelinek <jakub@redhat.com> 2.6.90-16
+- misc fixes (BZ#4963, BZ#4972, BZ#5028, BZ#5043, BZ#5058)
+- improve -D_FORTIFY_SOURCE{,=2} diagnostic through warning/error
+  attributes
+- fix wcscpy, wcpcpy, fgetws, fgetws_unlocked, swprintf and vswprintf
+  fortification inlines
+- fix a scalability issue with lazy binding in heavily multithreaded
+  programs
+
 * Thu Sep 20 2007 Jakub Jelinek <jakub@redhat.com> 2.6.90-15
 - $5$ (SHA-256) and $6$ (SHA-512) support in crypt
   (#228697, #249477, #173834)
diff --git a/iconv/iconv_open.c b/iconv/iconv_open.c
index fc94fa5fe0..e4fed93ecb 100644
--- a/iconv/iconv_open.c
+++ b/iconv/iconv_open.c
@@ -18,8 +18,10 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <alloca.h>
 #include <errno.h>
 #include <iconv.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -30,28 +32,49 @@
 iconv_t
 iconv_open (const char *tocode, const char *fromcode)
 {
-  char *tocode_conv;
-  char *fromcode_conv;
-  size_t tocode_len;
-  size_t fromcode_len;
-  __gconv_t cd;
-  int res;
-
   /* Normalize the name.  We remove all characters beside alpha-numeric,
      '_', '-', '/', '.', and ':'.  */
-  tocode_len = strlen (tocode);
-  tocode_conv = (char *) alloca (tocode_len + 3);
+  size_t tocode_len = strlen (tocode) + 3;
+  char *tocode_conv;
+  bool tocode_usealloca = __libc_use_alloca (tocode_len);
+  if (tocode_usealloca)
+    tocode_conv = (char *) alloca (tocode_len);
+  else
+    {
+      tocode_conv = (char *) malloc (tocode_len);
+      if (tocode_conv == NULL)
+	return (iconv_t) -1;
+    }
   strip (tocode_conv, tocode);
   tocode = (tocode_conv[2] == '\0' && tocode[0] != '\0'
 	    ? upstr (tocode_conv, tocode) : tocode_conv);
 
-  fromcode_len = strlen (fromcode);
-  fromcode_conv = (char *) alloca (fromcode_len + 3);
+  size_t fromcode_len = strlen (fromcode) + 3;
+  char *fromcode_conv;
+  bool fromcode_usealloca = __libc_use_alloca (fromcode_len);
+  if (fromcode_usealloca)
+    fromcode_conv = (char *) alloca (fromcode_len);
+  else
+    {
+      fromcode_conv = (char *) malloc (fromcode_len);
+      if (fromcode_conv == NULL)
+	{
+	  if (! tocode_usealloca)
+	    free (tocode_conv);
+	  return (iconv_t) -1;
+	}
+    }
   strip (fromcode_conv, fromcode);
   fromcode = (fromcode_conv[2] == '\0' && fromcode[0] != '\0'
 	      ? upstr (fromcode_conv, fromcode) : fromcode_conv);
 
-  res = __gconv_open (tocode, fromcode, &cd, 0);
+  __gconv_t cd;
+  int res = __gconv_open (tocode, fromcode, &cd, 0);
+
+  if (! fromcode_usealloca)
+    free (fromcode_conv);
+  if (! tocode_usealloca)
+    free (tocode_conv);
 
   if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK)
     {
@@ -59,7 +82,7 @@ iconv_open (const char *tocode, const char *fromcode)
       if (res == __GCONV_NOCONV || res == __GCONV_NODB)
 	__set_errno (EINVAL);
 
-      return (iconv_t) -1;
+      cd = (iconv_t) -1;
     }
 
   return (iconv_t) cd;
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 26bf61ed5e..8256bca2fc 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -58,7 +58,8 @@ modules	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
 	   IBM1142 IBM1143 IBM1144 IBM1145 IBM1146 IBM1147 IBM1148 	 \
 	   IBM1149 IBM1166 IBM1167 IBM4517 IBM4899 IBM4909 IBM4971 	 \
 	   IBM5347 IBM9030 IBM9066 IBM9448 IBM12712 IBM16804             \
-	   IBM1364 IBM1371 IBM1388 IBM1390 IBM1399 ISO_11548-1 MIK BRF
+	   IBM1364 IBM1371 IBM1388 IBM1390 IBM1399 ISO_11548-1 MIK BRF	 \
+	   MAC-CENTRALEUROPE KOI8-RU
 
 modules.so := $(addsuffix .so, $(modules))
 
@@ -197,7 +198,7 @@ distribute := gconv-modules extra-module.mk gap.awk gaptab.awk gconv.map    \
 	      ibm12712.c ibm12712.h ibm16804.c ibm16804.h                   \
 	      ibm1364.c ibm1364.h ibm1371.c ibm1371.h ibm1388.c ibm1388.h   \
 	      ibm1390.c ibm1390.h ibm1399.c ibm1399.h iso_11548-1.c mik.c   \
-	      brf.c
+	      brf.c mac-centraleurope.c
 
 # We build the transformation modules only when we build shared libs.
 ifeq (yes,$(build-shared))
@@ -238,7 +239,8 @@ gen-8bit-gap-modules := koi8-r latin-greek latin-greek-1 ibm256 ibm273	   \
 			iso8859-13 iso8859-14 iso8859-15 mac-uk sami-ws2   \
 			iso-ir-197 tis-620 koi8-u ibm874 cp10007 koi8-t	   \
 			georgian-ps georgian-academy iso-ir-209 mac-sami   \
-			iso8859-11 ibm866nav pt154 rk1048 mik brf
+			iso8859-11 ibm866nav pt154 rk1048 mik brf \
+			mac-centraleurope koi8-ru
 
 gen-special-modules := iso8859-7jp
 
diff --git a/iconvdata/TESTS b/iconvdata/TESTS
index 2743cc1ff6..4e1fdcd264 100644
--- a/iconvdata/TESTS
+++ b/iconvdata/TESTS
@@ -167,3 +167,6 @@ IBM1399			IBM1399			N	UTF8
 ISO_11548-1		ISO_11548-1		-	UTF8
 MIK			MIK			Y	UTF8
 BRF			BRF			-	UTF8
+MAC-SAMI		MAC-SAMI		Y	UTF8
+MAC-CENTRALEUROPE	MAC-CENTRALEUROPE	Y	UTF8
+KOI8-RU			KOI8-RU			Y	UTF8
diff --git a/iconvdata/gconv-modules b/iconvdata/gconv-modules
index 8d4667fc8a..ae4cf5fdc9 100644
--- a/iconvdata/gconv-modules
+++ b/iconvdata/gconv-modules
@@ -1911,3 +1911,12 @@ module	INTERNAL		MIK//			MIK		1
 #	from			to			module		cost
 module	BRF//			INTERNAL		BRF		1
 module	INTERNAL		BRF//			BRF		1
+
+#	from			to			module		cost
+alias	CP1282//		MAC-CENTRALEUROPE//
+module	MAC-CENTRALEUROPE//	INTERNAL		MAC-CENTRALEUROPE 1
+module	INTERNAL		MAC-CENTRALEUROPE//	MAC-CENTRALEUROPE 1
+
+#	from			to			module		cost
+module	KOI8-RU//		INTERNAL		KOI8-RU		1
+module	INTERNAL		KOI8-RU//		KOI8-RU		1
diff --git a/iconvdata/koi8-r.c b/iconvdata/koi8-r.c
index 88fe157a03..2e7934d0b0 100644
--- a/iconvdata/koi8-r.c
+++ b/iconvdata/koi8-r.c
@@ -1,5 +1,5 @@
 /* Conversion from and to KOI8-R.
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -24,6 +24,6 @@
 #define TABLES <koi8-r.h>
 
 #define CHARSET_NAME	"KOI8-R//"
-#define HAS_HOLES	1	/* Not all 256 character are defined.  */
+#define HAS_HOLES	0	/* All 256 character are defined.  */
 
 #include <8bit-gap.c>
diff --git a/iconvdata/koi8-ru.c b/iconvdata/koi8-ru.c
new file mode 100644
index 0000000000..ce1b1cff59
--- /dev/null
+++ b/iconvdata/koi8-ru.c
@@ -0,0 +1,29 @@
+/* Conversion from and to KOI8-RU.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 20077.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdint.h>
+
+/* Specify the conversion table.  */
+#define TABLES <koi8-ru.h>
+
+#define CHARSET_NAME	"KOI8-RU//"
+#define HAS_HOLES	0	/* All 256 character are defined.  */
+
+#include <8bit-gap.c>
diff --git a/iconvdata/mac-centraleurope.c b/iconvdata/mac-centraleurope.c
new file mode 100644
index 0000000000..41bcf39556
--- /dev/null
+++ b/iconvdata/mac-centraleurope.c
@@ -0,0 +1,29 @@
+/* Conversion from and to MAC-CENTRALEUROPE.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdint.h>
+
+/* Get the conversion table.  */
+#define TABLES <mac-centraleurope.h>
+
+#define CHARSET_NAME	"MAC-CENTRALEUROPE//"
+#define HAS_HOLES	0	/* All 256 character are defined.  */
+
+#include <8bit-gap.c>
diff --git a/iconvdata/tst-tables.sh b/iconvdata/tst-tables.sh
index be1e8832a5..b9eecd0683 100755
--- a/iconvdata/tst-tables.sh
+++ b/iconvdata/tst-tables.sh
@@ -209,6 +209,8 @@ cat <<EOF |
   RK1048
   MIK
   BRF
+  MAC-CENTRALEUROPE
+  KOI8-RU
   #
   # Multibyte encodings come here
   #
diff --git a/include/link.h b/include/link.h
index b373eeaf59..16980ef664 100644
--- a/include/link.h
+++ b/include/link.h
@@ -240,8 +240,11 @@ struct link_map
 
     /* List of the dependencies introduced through symbol binding.  */
     unsigned int l_reldepsmax;
-    unsigned int l_reldepsact;
-    struct link_map **l_reldeps;
+    struct link_map_reldeps
+      {
+	unsigned int act;
+	struct link_map *list[];
+      } *l_reldeps;
 
     /* Various flag words.  */
     ElfW(Word) l_feature_1;
diff --git a/intl/dcigettext.c b/intl/dcigettext.c
index ad2835f930..55dcaabd80 100644
--- a/intl/dcigettext.c
+++ b/intl/dcigettext.c
@@ -850,6 +850,9 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
       /* We are supposed to do a conversion.  */
       const char *encoding = get_output_charset (domainbinding);
 
+      /* Protect against reallocation of the table.  */
+      __libc_rwlock_rdlock (domain->conversions_lock);
+
       /* Search whether a table with converted translations for this
 	 encoding has already been allocated.  */
       size_t nconversions = domain->nconversions;
@@ -866,8 +869,25 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
 	    }
 	}
 
+      __libc_rwlock_unlock (domain->conversions_lock);
+
       if (convd == NULL)
 	{
+	  /* We have to allocate a new conversions table.  */
+	  __libc_rwlock_wrlock (domain->conversions_lock);
+
+	  /* Maybe in the meantime somebody added the translation.
+	     Recheck.  */
+	  for (i = nconversions; i > 0; )
+	    {
+	      i--;
+	      if (strcmp (domain->conversions[i].encoding, encoding) == 0)
+		{
+		  convd = &domain->conversions[i];
+		  goto found_convd;
+		}
+	    }
+
 	  /* Allocate a table for the converted translations for this
 	     encoding.  */
 	  struct converted_domain *new_conversions =
@@ -876,9 +896,13 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
 		     (nconversions + 1) * sizeof (struct converted_domain));
 
 	  if (__builtin_expect (new_conversions == NULL, 0))
-	    /* Nothing we can do, no more memory.  We cannot use the
-	       translation because it might be encoded incorrectly.  */
-	    return (char *) -1;
+	    {
+	      /* Nothing we can do, no more memory.  We cannot use the
+		 translation because it might be encoded incorrectly.  */
+	    unlock_fail:
+	      __libc_rwlock_unlock (domain->conversions_lock);
+	      return (char *) -1;
+	    }
 
 	  domain->conversions = new_conversions;
 
@@ -887,7 +911,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
 	  if (__builtin_expect (encoding == NULL, 0))
 	    /* Nothing we can do, no more memory.  We cannot use the
 	       translation because it might be encoded incorrectly.  */
-	    return (char *) -1;
+	    goto unlock_fail;
 
 	  convd = &new_conversions[nconversions];
 	  convd->encoding = encoding;
@@ -989,6 +1013,9 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
 	  convd->conv_tab = NULL;
 	  /* Here domain->conversions is still == new_conversions.  */
 	  domain->nconversions++;
+
+	found_convd:
+	  __libc_rwlock_unlock (domain->conversions_lock);
 	}
 
       if (
diff --git a/intl/gettextP.h b/intl/gettextP.h
index f680a9a0a1..f1aa329e47 100644
--- a/intl/gettextP.h
+++ b/intl/gettextP.h
@@ -147,6 +147,7 @@ struct loaded_domain
   /* Cache of charset conversions of the translated strings.  */
   struct converted_domain *conversions;
   size_t nconversions;
+  __libc_rwlock_define (, conversions_lock);
 
   const struct expression *plural;
   unsigned long int nplurals;
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index 1c47475ec6..537fd6013c 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -1,5 +1,5 @@
 /* Load needed message catalogs.
-   Copyright (C) 1995-2005 Free Software Foundation, Inc.
+   Copyright (C) 1995-2005, 2007 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
@@ -1252,6 +1252,7 @@ _nl_load_domain (domain_file, domainbinding)
   /* No caches of converted translations so far.  */
   domain->conversions = NULL;
   domain->nconversions = 0;
+  __libc_rwlock_init (domain->conversions_lock);
 
   /* Get the header entry and look for a plural specification.  */
   nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
@@ -1290,6 +1291,7 @@ _nl_unload_domain (domain)
     }
   if (domain->conversions != NULL)
     free (domain->conversions);
+  __libc_rwlock_fini (domain->conversions_lock);
 
   if (domain->malloced)
     free (domain->malloced);
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
index 841a0ff6aa..8889540689 100644
--- a/libio/bits/stdio2.h
+++ b/libio/bits/stdio2.h
@@ -131,14 +131,16 @@ vfprintf (FILE *__restrict __stream,
 #endif
 
 extern char *__gets_chk (char *__str, size_t) __wur;
-extern char *__REDIRECT (__gets_alias, (char *__str), gets) __wur;
+extern char *__REDIRECT (__gets_warn, (char *__str), gets)
+     __wur __warnattr ("please use fgets or getline instead, gets can't "
+		       "specify buffer size");
 
 __extern_always_inline __wur char *
 gets (char *__str)
 {
   if (__bos (__str) != (size_t) -1)
     return __gets_chk (__str, __bos (__str));
-  return __gets_alias (__str);
+  return __gets_warn (__str);
 }
 
 extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
@@ -146,13 +148,23 @@ extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
 extern char *__REDIRECT (__fgets_alias,
 			 (char *__restrict __s, int __n,
 			  FILE *__restrict __stream), fgets) __wur;
+extern char *__REDIRECT (__fgets_chk_warn,
+			 (char *__restrict __s, size_t __size, int __n,
+			  FILE *__restrict __stream), __fgets_chk)
+     __wur __warnattr ("fgets called with bigger size than length "
+		       "of destination buffer");
 
 __extern_always_inline __wur char *
 fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
 {
-  if (__bos (__s) != (size_t) -1
-      && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
-    return __fgets_chk (__s, __bos (__s), __n, __stream);
+  if (__bos (__s) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n) || __n <= 0)
+	return __fgets_chk (__s, __bos (__s), __n, __stream);
+
+      if ((size_t) __n > __bos (__s))
+	return __fgets_chk_warn (__s, __bos (__s), __n, __stream);
+    }
   return __fgets_alias (__s, __n, __stream);
 }
 
@@ -163,17 +175,28 @@ extern size_t __REDIRECT (__fread_alias,
 			  (void *__restrict __ptr, size_t __size,
 			   size_t __n, FILE *__restrict __stream),
 			  fread) __wur;
+extern size_t __REDIRECT (__fread_chk_warn,
+			  (void *__restrict __ptr, size_t __ptrlen,
+			   size_t __size, size_t __n,
+			   FILE *__restrict __stream),
+			  __fread_chk)
+     __wur __warnattr ("fread called with bigger size * nmemb than length "
+		       "of destination buffer");
 
 __extern_always_inline __wur size_t
 fread (void *__restrict __ptr, size_t __size, size_t __n,
        FILE *__restrict __stream)
 {
-  if (__bos0 (__ptr) != (size_t) -1
-      && (!__builtin_constant_p (__size)
+  if (__bos0 (__ptr) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__size)
 	  || !__builtin_constant_p (__n)
-	  || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))
-	  || __size * __n > __bos0 (__ptr)))
-    return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
+	  || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)))
+	return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
+
+      if (__size * __n > __bos0 (__ptr))
+	return __fread_chk_warn (__ptr, __bos0 (__ptr), __size, __n, __stream);
+    }
   return __fread_alias (__ptr, __size, __n, __stream);
 }
 
@@ -183,13 +206,23 @@ extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size,
 extern char *__REDIRECT (__fgets_unlocked_alias,
 			 (char *__restrict __s, int __n,
 			  FILE *__restrict __stream), fgets_unlocked) __wur;
+extern char *__REDIRECT (__fgets_unlocked_chk_warn,
+			 (char *__restrict __s, size_t __size, int __n,
+			  FILE *__restrict __stream), __fgets_unlocked_chk)
+     __wur __warnattr ("fgets_unlocked called with bigger size than length "
+		       "of destination buffer");
 
 __extern_always_inline __wur char *
 fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
 {
-  if (__bos (__s) != (size_t) -1
-      && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
-    return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream);
+  if (__bos (__s) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n) || __n <= 0)
+	return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream);
+
+      if ((size_t) __n > __bos (__s))
+	return __fgets_unlocked_chk_warn (__s, __bos (__s), __n, __stream);
+    }
   return __fgets_unlocked_alias (__s, __n, __stream);
 }
 #endif
@@ -203,17 +236,30 @@ extern size_t __REDIRECT (__fread_unlocked_alias,
 			  (void *__restrict __ptr, size_t __size,
 			   size_t __n, FILE *__restrict __stream),
 			  fread_unlocked) __wur;
+extern size_t __REDIRECT (__fread_unlocked_chk_warn,
+			  (void *__restrict __ptr, size_t __ptrlen,
+			   size_t __size, size_t __n,
+			   FILE *__restrict __stream),
+			  __fread_unlocked_chk)
+     __wur __warnattr ("fread_unlocked called with bigger size * nmemb than "
+		       "length of destination buffer");
 
 __extern_always_inline __wur size_t
 fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
 		FILE *__restrict __stream)
 {
-  if (__bos0 (__ptr) != (size_t) -1
-      && (!__builtin_constant_p (__size)
+  if (__bos0 (__ptr) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__size)
 	  || !__builtin_constant_p (__n)
-	  || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))
-	  || __size * __n > __bos0 (__ptr)))
-    return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
+	  || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)))
+	return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n,
+				     __stream);
+
+      if (__size * __n > __bos0 (__ptr))
+	return __fread_unlocked_chk_warn (__ptr, __bos0 (__ptr), __size, __n,
+					  __stream);
+    }
 
 # ifdef __USE_EXTERN_INLINES
   if (__builtin_constant_p (__size)
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index 7d39671a07..8312856633 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,15 @@
+2007-09-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* charmaps/KOI8-RU: New file.
+
+2007-09-23  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4556]
+	* locales/de_CH: Fix d_fmt.
+
+	[BZ #4972]
+	* charmaps/MAC-CENTRALEUROPE: New file.
+
 2007-08-24  Ulrich Drepper  <drepper@redhat.com>
 
 	[BZ #3842]
diff --git a/localedata/charmaps/KOI8-RU b/localedata/charmaps/KOI8-RU
new file mode 100644
index 0000000000..ce9857f667
--- /dev/null
+++ b/localedata/charmaps/KOI8-RU
@@ -0,0 +1,264 @@
+<code_set_name> KOI8-RU
+<comment_char> %
+<escape_char> /
+% version: 1.0
+%  source: Draft RFC rfc-draft-koi8-ru.txt
+
+CHARMAP
+<U0000>     /x00         NULL (NUL)
+<U0001>     /x01         START OF HEADING (SOH)
+<U0002>     /x02         START OF TEXT (STX)
+<U0003>     /x03         END OF TEXT (ETX)
+<U0004>     /x04         END OF TRANSMISSION (EOT)
+<U0005>     /x05         ENQUIRY (ENQ)
+<U0006>     /x06         ACKNOWLEDGE (ACK)
+<U0007>     /x07         BELL (BEL)
+<U0008>     /x08         BACKSPACE (BS)
+<U0009>     /x09         CHARACTER TABULATION (HT)
+<U000A>     /x0a         LINE FEED (LF)
+<U000B>     /x0b         LINE TABULATION (VT)
+<U000C>     /x0c         FORM FEED (FF)
+<U000D>     /x0d         CARRIAGE RETURN (CR)
+<U000E>     /x0e         SHIFT OUT (SO)
+<U000F>     /x0f         SHIFT IN (SI)
+<U0010>     /x10         DATALINK ESCAPE (DLE)
+<U0011>     /x11         DEVICE CONTROL ONE (DC1)
+<U0012>     /x12         DEVICE CONTROL TWO (DC2)
+<U0013>     /x13         DEVICE CONTROL THREE (DC3)
+<U0014>     /x14         DEVICE CONTROL FOUR (DC4)
+<U0015>     /x15         NEGATIVE ACKNOWLEDGE (NAK)
+<U0016>     /x16         SYNCHRONOUS IDLE (SYN)
+<U0017>     /x17         END OF TRANSMISSION BLOCK (ETB)
+<U0018>     /x18         CANCEL (CAN)
+<U0019>     /x19         END OF MEDIUM (EM)
+<U001A>     /x1a         SUBSTITUTE (SUB)
+<U001B>     /x1b         ESCAPE (ESC)
+<U001C>     /x1c         FILE SEPARATOR (IS4)
+<U001D>     /x1d         GROUP SEPARATOR (IS3)
+<U001E>     /x1e         RECORD SEPARATOR (IS2)
+<U001F>     /x1f         UNIT SEPARATOR (IS1)
+<U0020>     /x20         SPACE
+<U0021>     /x21         EXCLAMATION MARK
+<U0022>     /x22         QUOTATION MARK
+<U0023>     /x23         NUMBER SIGN
+<U0024>     /x24         DOLLAR SIGN
+<U0025>     /x25         PERCENT SIGN
+<U0026>     /x26         AMPERSAND
+<U0027>     /x27         APOSTROPHE
+<U0028>     /x28         LEFT PARENTHESIS
+<U0029>     /x29         RIGHT PARENTHESIS
+<U002A>     /x2a         ASTERISK
+<U002B>     /x2b         PLUS SIGN
+<U002C>     /x2c         COMMA
+<U002D>     /x2d         HYPHEN-MINUS
+<U002E>     /x2e         FULL STOP
+<U002F>     /x2f         SOLIDUS
+<U0030>     /x30         DIGIT ZERO
+<U0031>     /x31         DIGIT ONE
+<U0032>     /x32         DIGIT TWO
+<U0033>     /x33         DIGIT THREE
+<U0034>     /x34         DIGIT FOUR
+<U0035>     /x35         DIGIT FIVE
+<U0036>     /x36         DIGIT SIX
+<U0037>     /x37         DIGIT SEVEN
+<U0038>     /x38         DIGIT EIGHT
+<U0039>     /x39         DIGIT NINE
+<U003A>     /x3a         COLON
+<U003B>     /x3b         SEMICOLON
+<U003C>     /x3c         LESS-THAN SIGN
+<U003D>     /x3d         EQUALS SIGN
+<U003E>     /x3e         GREATER-THAN SIGN
+<U003F>     /x3f         QUESTION MARK
+<U0040>     /x40         COMMERCIAL AT
+<U0041>     /x41         LATIN CAPITAL LETTER A
+<U0042>     /x42         LATIN CAPITAL LETTER B
+<U0043>     /x43         LATIN CAPITAL LETTER C
+<U0044>     /x44         LATIN CAPITAL LETTER D
+<U0045>     /x45         LATIN CAPITAL LETTER E
+<U0046>     /x46         LATIN CAPITAL LETTER F
+<U0047>     /x47         LATIN CAPITAL LETTER G
+<U0048>     /x48         LATIN CAPITAL LETTER H
+<U0049>     /x49         LATIN CAPITAL LETTER I
+<U004A>     /x4a         LATIN CAPITAL LETTER J
+<U004B>     /x4b         LATIN CAPITAL LETTER K
+<U004C>     /x4c         LATIN CAPITAL LETTER L
+<U004D>     /x4d         LATIN CAPITAL LETTER M
+<U004E>     /x4e         LATIN CAPITAL LETTER N
+<U004F>     /x4f         LATIN CAPITAL LETTER O
+<U0050>     /x50         LATIN CAPITAL LETTER P
+<U0051>     /x51         LATIN CAPITAL LETTER Q
+<U0052>     /x52         LATIN CAPITAL LETTER R
+<U0053>     /x53         LATIN CAPITAL LETTER S
+<U0054>     /x54         LATIN CAPITAL LETTER T
+<U0055>     /x55         LATIN CAPITAL LETTER U
+<U0056>     /x56         LATIN CAPITAL LETTER V
+<U0057>     /x57         LATIN CAPITAL LETTER W
+<U0058>     /x58         LATIN CAPITAL LETTER X
+<U0059>     /x59         LATIN CAPITAL LETTER Y
+<U005A>     /x5a         LATIN CAPITAL LETTER Z
+<U005B>     /x5b         LEFT SQUARE BRACKET
+<U005C>     /x5c         REVERSE SOLIDUS
+<U005D>     /x5d         RIGHT SQUARE BRACKET
+<U005E>     /x5e         CIRCUMFLEX ACCENT
+<U005F>     /x5f         LOW LINE
+<U0060>     /x60         GRAVE ACCENT
+<U0061>     /x61         LATIN SMALL LETTER A
+<U0062>     /x62         LATIN SMALL LETTER B
+<U0063>     /x63         LATIN SMALL LETTER C
+<U0064>     /x64         LATIN SMALL LETTER D
+<U0065>     /x65         LATIN SMALL LETTER E
+<U0066>     /x66         LATIN SMALL LETTER F
+<U0067>     /x67         LATIN SMALL LETTER G
+<U0068>     /x68         LATIN SMALL LETTER H
+<U0069>     /x69         LATIN SMALL LETTER I
+<U006A>     /x6a         LATIN SMALL LETTER J
+<U006B>     /x6b         LATIN SMALL LETTER K
+<U006C>     /x6c         LATIN SMALL LETTER L
+<U006D>     /x6d         LATIN SMALL LETTER M
+<U006E>     /x6e         LATIN SMALL LETTER N
+<U006F>     /x6f         LATIN SMALL LETTER O
+<U0070>     /x70         LATIN SMALL LETTER P
+<U0071>     /x71         LATIN SMALL LETTER Q
+<U0072>     /x72         LATIN SMALL LETTER R
+<U0073>     /x73         LATIN SMALL LETTER S
+<U0074>     /x74         LATIN SMALL LETTER T
+<U0075>     /x75         LATIN SMALL LETTER U
+<U0076>     /x76         LATIN SMALL LETTER V
+<U0077>     /x77         LATIN SMALL LETTER W
+<U0078>     /x78         LATIN SMALL LETTER X
+<U0079>     /x79         LATIN SMALL LETTER Y
+<U007A>     /x7a         LATIN SMALL LETTER Z
+<U007B>     /x7b         LEFT CURLY BRACKET
+<U007C>     /x7c         VERTICAL LINE
+<U007D>     /x7d         RIGHT CURLY BRACKET
+<U007E>     /x7e         TILDE
+<U007F>     /x7f         DELETE (DEL)
+<U2500>     /x80         BOX DRAWINGS LIGHT HORIZONTAL
+<U2502>     /x81         BOX DRAWINGS LIGHT VERTICAL
+<U250C>     /x82         BOX DRAWINGS LIGHT DOWN AND RIGHT
+<U2510>     /x83         BOX DRAWINGS LIGHT DOWN AND LEFT
+<U2514>     /x84         BOX DRAWINGS LIGHT UP AND RIGHT
+<U2518>     /x85         BOX DRAWINGS LIGHT UP AND LEFT
+<U251C>     /x86         BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+<U2524>     /x87         BOX DRAWINGS LIGHT VERTICAL AND LEFT
+<U252C>     /x88         BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+<U2534>     /x89         BOX DRAWINGS LIGHT UP AND HORIZONTAL
+<U253C>     /x8a         BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+<U2580>     /x8b         UPPER HALF BLOCK
+<U2584>     /x8c         LOWER HALF BLOCK
+<U2588>     /x8d         FULL BLOCK
+<U258C>     /x8e         LEFT HALF BLOCK
+<U2590>     /x8f         RIGHT HALF BLOCK
+<U2591>     /x90         LIGHT SHADE
+<U2592>     /x91         MEDIUM SHADE
+<U2593>     /x92         DARK SHADE
+<U201C>     /x93         LEFT DOUBLE QUOTATION MARK
+<U25A0>     /x94         BLACK SQUARE
+<U2219>     /x95         BULLET OPERATOR
+<U201D>     /x96         RIGHT DOUBLE QUOTATION MARK
+<U2014>     /x97         EM DASH
+<U2116>     /x98         NUMERO SIGN
+<U2122>     /x99         TRADE MARK SIGN
+<U00A0>     /x9a         NO-BREAK SPACE
+<U00BB>     /x9b         RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+<U00AE>     /x9c         REGISTERED SIGN
+<U00AB>     /x9d         LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+<U00B7>     /x9e         MIDDLE DOT
+<U00A4>     /x9f         CURRENCY SIGN
+<U2550>     /xa0         BOX DRAWINGS DOUBLE HORIZONTAL
+<U2551>     /xa1         BOX DRAWINGS DOUBLE VERTICAL
+<U2552>     /xa2         BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+<U0451>     /xa3         CYRILLIC SMALL LETTER IO
+<U0454>     /xa4         CYRILLIC SMALL LETTER UKRAINIAN IE
+<U2554>     /xa5         BOX DRAWINGS DOUBLE DOWN AND RIGHT
+<U0456>     /xa6         CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+<U0457>     /xa7         CYRILLIC SMALL LETTER YI
+<U2557>     /xa8         BOX DRAWINGS DOUBLE DOWN AND LEFT
+<U2558>     /xa9         BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+<U2559>     /xaa         BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+<U255A>     /xab         BOX DRAWINGS DOUBLE UP AND RIGHT
+<U255B>     /xac         BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+<U0491>     /xad         CYRILLIC SMALL LETTER GHE WITH UPTURN
+<U045E>     /xae         CYRILLIC SMALL LETTER SHORT U
+<U255E>     /xaf         BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+<U255F>     /xb0         BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+<U2560>     /xb1         BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+<U2561>     /xb2         BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+<U0401>     /xb3         CYRILLIC CAPITAL LETTER IO
+<U0404>     /xb4         CYRILLIC CAPITAL LETTER UKRAINIAN IE
+<U2563>     /xb5         BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+<U0406>     /xb6         CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+<U0407>     /xb7         CYRILLIC CAPITAL LETTER YI
+<U2566>     /xb8         BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+<U2567>     /xb9         BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+<U2568>     /xba         BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+<U2569>     /xbb         BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+<U256A>     /xbc         BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+<U0490>     /xbd         CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+<U040E>     /xbe         CYRILLIC CAPITAL LETTER SHORT U
+<U00A9>     /xbf         COPYRIGHT SIGN
+<U044E>     /xc0         CYRILLIC SMALL LETTER YU
+<U0430>     /xc1         CYRILLIC SMALL LETTER A
+<U0431>     /xc2         CYRILLIC SMALL LETTER BE
+<U0446>     /xc3         CYRILLIC SMALL LETTER TSE
+<U0434>     /xc4         CYRILLIC SMALL LETTER DE
+<U0435>     /xc5         CYRILLIC SMALL LETTER IE
+<U0444>     /xc6         CYRILLIC SMALL LETTER EF
+<U0433>     /xc7         CYRILLIC SMALL LETTER GHE
+<U0445>     /xc8         CYRILLIC SMALL LETTER HA
+<U0438>     /xc9         CYRILLIC SMALL LETTER I
+<U0439>     /xca         CYRILLIC SMALL LETTER SHORT I
+<U043A>     /xcb         CYRILLIC SMALL LETTER KA
+<U043B>     /xcc         CYRILLIC SMALL LETTER EL
+<U043C>     /xcd         CYRILLIC SMALL LETTER EM
+<U043D>     /xce         CYRILLIC SMALL LETTER EN
+<U043E>     /xcf         CYRILLIC SMALL LETTER O
+<U043F>     /xd0         CYRILLIC SMALL LETTER PE
+<U044F>     /xd1         CYRILLIC SMALL LETTER YA
+<U0440>     /xd2         CYRILLIC SMALL LETTER ER
+<U0441>     /xd3         CYRILLIC SMALL LETTER ES
+<U0442>     /xd4         CYRILLIC SMALL LETTER TE
+<U0443>     /xd5         CYRILLIC SMALL LETTER U
+<U0436>     /xd6         CYRILLIC SMALL LETTER ZHE
+<U0432>     /xd7         CYRILLIC SMALL LETTER VE
+<U044C>     /xd8         CYRILLIC SMALL LETTER SOFT SIGN
+<U044B>     /xd9         CYRILLIC SMALL LETTER YERU
+<U0437>     /xda         CYRILLIC SMALL LETTER ZE
+<U0448>     /xdb         CYRILLIC SMALL LETTER SHA
+<U044D>     /xdc         CYRILLIC SMALL LETTER E
+<U0449>     /xdd         CYRILLIC SMALL LETTER SHCHA
+<U0447>     /xde         CYRILLIC SMALL LETTER CHE
+<U044A>     /xdf         CYRILLIC SMALL LETTER HARD SIGN
+<U042E>     /xe0         CYRILLIC CAPITAL LETTER YU
+<U0410>     /xe1         CYRILLIC CAPITAL LETTER A
+<U0411>     /xe2         CYRILLIC CAPITAL LETTER BE
+<U0426>     /xe3         CYRILLIC CAPITAL LETTER TSE
+<U0414>     /xe4         CYRILLIC CAPITAL LETTER DE
+<U0415>     /xe5         CYRILLIC CAPITAL LETTER IE
+<U0424>     /xe6         CYRILLIC CAPITAL LETTER EF
+<U0413>     /xe7         CYRILLIC CAPITAL LETTER GHE
+<U0425>     /xe8         CYRILLIC CAPITAL LETTER HA
+<U0418>     /xe9         CYRILLIC CAPITAL LETTER I
+<U0419>     /xea         CYRILLIC CAPITAL LETTER SHORT I
+<U041A>     /xeb         CYRILLIC CAPITAL LETTER KA
+<U041B>     /xec         CYRILLIC CAPITAL LETTER EL
+<U041C>     /xed         CYRILLIC CAPITAL LETTER EM
+<U041D>     /xee         CYRILLIC CAPITAL LETTER EN
+<U041E>     /xef         CYRILLIC CAPITAL LETTER O
+<U041F>     /xf0         CYRILLIC CAPITAL LETTER PE
+<U042F>     /xf1         CYRILLIC CAPITAL LETTER YA
+<U0420>     /xf2         CYRILLIC CAPITAL LETTER ER
+<U0421>     /xf3         CYRILLIC CAPITAL LETTER ES
+<U0422>     /xf4         CYRILLIC CAPITAL LETTER TE
+<U0423>     /xf5         CYRILLIC CAPITAL LETTER U
+<U0416>     /xf6         CYRILLIC CAPITAL LETTER ZHE
+<U0412>     /xf7         CYRILLIC CAPITAL LETTER VE
+<U042C>     /xf8         CYRILLIC CAPITAL LETTER SOFT SIGN
+<U042B>     /xf9         CYRILLIC CAPITAL LETTER YERU
+<U0417>     /xfa         CYRILLIC CAPITAL LETTER ZE
+<U0428>     /xfb         CYRILLIC CAPITAL LETTER SHA
+<U042D>     /xfc         CYRILLIC CAPITAL LETTER E
+<U0429>     /xfd         CYRILLIC CAPITAL LETTER SHCHA
+<U0427>     /xfe         CYRILLIC CAPITAL LETTER CHE
+<U042A>     /xff         CYRILLIC CAPITAL LETTER HARD SIGN
+END CHARMAP
diff --git a/localedata/charmaps/MAC-CENTRALEUROPE b/localedata/charmaps/MAC-CENTRALEUROPE
new file mode 100644
index 0000000000..386cfe9160
--- /dev/null
+++ b/localedata/charmaps/MAC-CENTRALEUROPE
@@ -0,0 +1,261 @@
+<code_set_name> MAC_CENTRALEUROPE
+<comment> %
+<escape_char> /
+
+%alias CP1282
+<U0000>     /x00         NULL
+<U0001>     /x01         START OF HEADING
+<U0002>     /x02         START OF TEXT
+<U0003>     /x03         END OF TEXT
+<U0004>     /x04         END OF TRANSMISSION
+<U0005>     /x05         ENQUIRY
+<U0006>     /x06         ACKNOWLEDGE
+<U0007>     /x07         BELL
+<U0008>     /x08         BACKSPACE
+<U0009>     /x09         HORIZONTAL TABULATION
+<U000A>     /x0a         LINE FEED
+<U000B>     /x0b         VERTICAL TABULATION
+<U000C>     /x0c         FORM FEED
+<U000D>     /x0d         CARRIAGE RETURN
+<U000E>     /x0e         SHIFT OUT
+<U000F>     /x0f         SHIFT IN
+<U0010>     /x10         DATA LINK ESCAPE
+<U0011>     /x11         DEVICE CONTROL ONE
+<U0012>     /x12         DEVICE CONTROL TWO
+<U0013>     /x13         DEVICE CONTROL THREE
+<U0014>     /x14         DEVICE CONTROL FOUR
+<U0015>     /x15         NEGATIVE ACKNOWLEDGE
+<U0016>     /x16         SYNCHRONOUS IDLE
+<U0017>     /x17         END OF TRANSMISSION BLOCK
+<U0018>     /x18         CANCEL
+<U0019>     /x19         END OF MEDIUM
+<U001A>     /x1a         SUBSTITUTE
+<U001B>     /x1b         ESCAPE
+<U001C>     /x1c         FILE SEPARATOR
+<U001D>     /x1d         GROUP SEPARATOR
+<U001E>     /x1e         RECORD SEPARATOR
+<U001F>     /x1f         UNIT SEPARATOR
+<U0020>     /x20         SPACE
+<U0021>     /x21         EXCLAMATION MARK
+<U0022>     /x22         QUOTATION MARK
+<U0023>     /x23         NUMBER SIGN
+<U0024>     /x24         DOLLAR SIGN
+<U0025>     /x25         PERCENT SIGN
+<U0026>     /x26         AMPERSAND
+<U0027>     /x27         APOSTROPHE
+<U0028>     /x28         LEFT PARENTHESIS
+<U0029>     /x29         RIGHT PARENTHESIS
+<U002A>     /x2a         ASTERISK
+<U002B>     /x2b         PLUS SIGN
+<U002C>     /x2c         COMMA
+<U002D>     /x2d         HYPHEN-MINUS
+<U002E>     /x2e         FULL STOP
+<U002F>     /x2f         SOLIDUS
+<U0030>     /x30         DIGIT ZERO
+<U0031>     /x31         DIGIT ONE
+<U0032>     /x32         DIGIT TWO
+<U0033>     /x33         DIGIT THREE
+<U0034>     /x34         DIGIT FOUR
+<U0035>     /x35         DIGIT FIVE
+<U0036>     /x36         DIGIT SIX
+<U0037>     /x37         DIGIT SEVEN
+<U0038>     /x38         DIGIT EIGHT
+<U0039>     /x39         DIGIT NINE
+<U003A>     /x3a         COLON
+<U003B>     /x3b         SEMICOLON
+<U003C>     /x3c         LESS-THAN SIGN
+<U003D>     /x3d         EQUALS SIGN
+<U003E>     /x3e         GREATER-THAN SIGN
+<U003F>     /x3f         QUESTION MARK
+<U0040>     /x40         COMMERCIAL AT
+<U0041>     /x41         LATIN CAPITAL LETTER A
+<U0042>     /x42         LATIN CAPITAL LETTER B
+<U0043>     /x43         LATIN CAPITAL LETTER C
+<U0044>     /x44         LATIN CAPITAL LETTER D
+<U0045>     /x45         LATIN CAPITAL LETTER E
+<U0046>     /x46         LATIN CAPITAL LETTER F
+<U0047>     /x47         LATIN CAPITAL LETTER G
+<U0048>     /x48         LATIN CAPITAL LETTER H
+<U0049>     /x49         LATIN CAPITAL LETTER I
+<U004A>     /x4a         LATIN CAPITAL LETTER J
+<U004B>     /x4b         LATIN CAPITAL LETTER K
+<U004C>     /x4c         LATIN CAPITAL LETTER L
+<U004D>     /x4d         LATIN CAPITAL LETTER M
+<U004E>     /x4e         LATIN CAPITAL LETTER N
+<U004F>     /x4f         LATIN CAPITAL LETTER O
+<U0050>     /x50         LATIN CAPITAL LETTER P
+<U0051>     /x51         LATIN CAPITAL LETTER Q
+<U0052>     /x52         LATIN CAPITAL LETTER R
+<U0053>     /x53         LATIN CAPITAL LETTER S
+<U0054>     /x54         LATIN CAPITAL LETTER T
+<U0055>     /x55         LATIN CAPITAL LETTER U
+<U0056>     /x56         LATIN CAPITAL LETTER V
+<U0057>     /x57         LATIN CAPITAL LETTER W
+<U0058>     /x58         LATIN CAPITAL LETTER X
+<U0059>     /x59         LATIN CAPITAL LETTER Y
+<U005A>     /x5a         LATIN CAPITAL LETTER Z
+<U005B>     /x5b         LEFT SQUARE BRACKET
+<U005C>     /x5c         REVERSE SOLIDUS
+<U005D>     /x5d         RIGHT SQUARE BRACKET
+<U005E>     /x5e         CIRCUMFLEX ACCENT
+<U005F>     /x5f         LOW LINE
+<U0060>     /x60         GRAVE ACCENT
+<U0061>     /x61         LATIN SMALL LETTER A
+<U0062>     /x62         LATIN SMALL LETTER B
+<U0063>     /x63         LATIN SMALL LETTER C
+<U0064>     /x64         LATIN SMALL LETTER D
+<U0065>     /x65         LATIN SMALL LETTER E
+<U0066>     /x66         LATIN SMALL LETTER F
+<U0067>     /x67         LATIN SMALL LETTER G
+<U0068>     /x68         LATIN SMALL LETTER H
+<U0069>     /x69         LATIN SMALL LETTER I
+<U006A>     /x6a         LATIN SMALL LETTER J
+<U006B>     /x6b         LATIN SMALL LETTER K
+<U006C>     /x6c         LATIN SMALL LETTER L
+<U006D>     /x6d         LATIN SMALL LETTER M
+<U006E>     /x6e         LATIN SMALL LETTER N
+<U006F>     /x6f         LATIN SMALL LETTER O
+<U0070>     /x70         LATIN SMALL LETTER P
+<U0071>     /x71         LATIN SMALL LETTER Q
+<U0072>     /x72         LATIN SMALL LETTER R
+<U0073>     /x73         LATIN SMALL LETTER S
+<U0074>     /x74         LATIN SMALL LETTER T
+<U0075>     /x75         LATIN SMALL LETTER U
+<U0076>     /x76         LATIN SMALL LETTER V
+<U0077>     /x77         LATIN SMALL LETTER W
+<U0078>     /x78         LATIN SMALL LETTER X
+<U0079>     /x79         LATIN SMALL LETTER Y
+<U007A>     /x7a         LATIN SMALL LETTER Z
+<U007B>     /x7b         LEFT CURLY BRACKET
+<U007C>     /x7c         VERTICAL LINE
+<U007D>     /x7d         RIGHT CURLY BRACKET
+<U007E>     /x7e         TILDE
+<U007F>     /x7f         DELETE
+<U00C4>     /x80         LATIN CAPITAL LETTER A WITH DIAERESIS
+<U0100>     /x81         LATIN CAPITAL LETTER A WITH MACRON
+<U0101>     /x82         LATIN SMALL LETTER A WITH MACRON
+<U00C9>     /x83         LATIN CAPITAL LETTER E WITH ACUTE
+<U0104>     /x84         LATIN CAPITAL LETTER A WITH OGONEK
+<U00D6>     /x85         LATIN CAPITAL LETTER O WITH DIAERESIS
+<U00DC>     /x86         LATIN CAPITAL LETTER U WITH DIAERESIS
+<U00E1>     /x87         LATIN SMALL LETTER A WITH ACUTE
+<U0105>     /x88         LATIN SMALL LETTER A WITH OGONEK
+<U010C>     /x89         LATIN CAPITAL LETTER C WITH CARON
+<U00E4>     /x8a         LATIN SMALL LETTER A WITH DIAERESIS
+<U010D>     /x8b         LATIN SMALL LETTER C WITH CARON
+<U0106>     /x8c         LATIN CAPITAL LETTER C WITH ACUTE
+<U0107>     /x8d         LATIN SMALL LETTER C WITH ACUTE
+<U00E9>     /x8e         LATIN SMALL LETTER E WITH ACUTE
+<U0179>     /x8f         LATIN CAPITAL LETTER Z WITH ACUTE
+<U017A>     /x90         LATIN SMALL LETTER Z WITH ACUTE
+<U010E>     /x91         LATIN CAPITAL LETTER D WITH CARON
+<U00ED>     /x92         LATIN SMALL LETTER I WITH ACUTE
+<U010F>     /x93         LATIN SMALL LETTER D WITH CARON
+<U0112>     /x94         LATIN CAPITAL LETTER E WITH MACRON
+<U0113>     /x95         LATIN SMALL LETTER E WITH MACRON
+<U0116>     /x96         LATIN CAPITAL LETTER E WITH DOT ABOVE
+<U00F3>     /x97         LATIN SMALL LETTER O WITH ACUTE
+<U0117>     /x98         LATIN SMALL LETTER E WITH DOT ABOVE
+<U00F4>     /x99         LATIN SMALL LETTER O WITH CIRCUMFLEX
+<U00F6>     /x9a         LATIN SMALL LETTER O WITH DIAERESIS
+<U00F5>     /x9b         LATIN SMALL LETTER O WITH TILDE
+<U00FA>     /x9c         LATIN SMALL LETTER U WITH ACUTE
+<U011A>     /x9d         LATIN CAPITAL LETTER E WITH CARON
+<U011B>     /x9e         LATIN SMALL LETTER E WITH CARON
+<U00FC>     /x9f         LATIN SMALL LETTER U WITH DIAERESIS
+<U2020>     /xa0         DAGGER
+<U00B0>     /xa1         DEGREE SIGN
+<U0118>     /xa2         LATIN CAPITAL LETTER E WITH OGONEK
+<U00A3>     /xa3         POUND SIGN
+<U00A7>     /xa4         SECTION SIGN
+<U2022>     /xa5         BULLET
+<U00B6>     /xa6         PILCROW SIGN
+<U00DF>     /xa7         LATIN SMALL LETTER SHARP S
+<U00AE>     /xa8         REGISTERED SIGN
+<U00A9>     /xa9         COPYRIGHT SIGN
+<U2122>     /xaa         TRADE MARK SIGN
+<U0119>     /xab         LATIN SMALL LETTER E WITH OGONEK
+<U00A8>     /xac         DIAERESIS
+<U2260>     /xad         NOT EQUAL TO
+<U0123>     /xae         LATIN SMALL LETTER G WITH CEDILLA
+<U012E>     /xaf         LATIN CAPITAL LETTER I WITH OGONEK
+<U012F>     /xb0         LATIN SMALL LETTER I WITH OGONEK
+<U012A>     /xb1         LATIN CAPITAL LETTER I WITH MACRON
+<U2264>     /xb2         LESS-THAN OR EQUAL TO
+<U2265>     /xb3         GREATER-THAN OR EQUAL TO
+<U012B>     /xb4         LATIN SMALL LETTER I WITH MACRON
+<U0136>     /xb5         LATIN CAPITAL LETTER K WITH CEDILLA
+<U2202>     /xb6         PARTIAL DIFFERENTIAL
+<U2211>     /xb7         N-ARY SUMMATION
+<U0142>     /xb8         LATIN SMALL LETTER L WITH STROKE
+<U013B>     /xb9         LATIN CAPITAL LETTER L WITH CEDILLA
+<U013C>     /xba         LATIN SMALL LETTER L WITH CEDILLA
+<U013D>     /xbb         LATIN CAPITAL LETTER L WITH CARON
+<U013E>     /xbc         LATIN SMALL LETTER L WITH CARON
+<U0139>     /xbd         LATIN CAPITAL LETTER L WITH ACUTE
+<U013A>     /xbe         LATIN SMALL LETTER L WITH ACUTE
+<U0145>     /xbf         LATIN CAPITAL LETTER N WITH CEDILLA
+<U0146>     /xc0         LATIN SMALL LETTER N WITH CEDILLA
+<U0143>     /xc1         LATIN CAPITAL LETTER N WITH ACUTE
+<U00AC>     /xc2         NOT SIGN
+<U221A>     /xc3         SQUARE ROOT
+<U0144>     /xc4         LATIN SMALL LETTER N WITH ACUTE
+<U0147>     /xc5         LATIN CAPITAL LETTER N WITH CARON
+<U2206>     /xc6         INCREMENT
+<U00AB>     /xc7         LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+<U00BB>     /xc8         RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+<U2026>     /xc9         HORIZONTAL ELLIPSIS
+<U00A0>     /xca         NO-BREAK SPACE
+<U0148>     /xcb         LATIN SMALL LETTER N WITH CARON
+<U0150>     /xcc         LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+<U00D5>     /xcd         LATIN CAPITAL LETTER O WITH TILDE
+<U0151>     /xce         LATIN SMALL LETTER O WITH DOUBLE ACUTE
+<U014C>     /xcf         LATIN CAPITAL LETTER O WITH MACRON
+<U2013>     /xd0         EN DASH
+<U2014>     /xd1         EM DASH
+<U201C>     /xd2         LEFT DOUBLE QUOTATION MARK
+<U201D>     /xd3         RIGHT DOUBLE QUOTATION MARK
+<U2018>     /xd4         LEFT SINGLE QUOTATION MARK
+<U2019>     /xd5         RIGHT SINGLE QUOTATION MARK
+<U00F7>     /xd6         DIVISION SIGN
+<U25CA>     /xd7         LOZENGE
+<U014D>     /xd8         LATIN SMALL LETTER O WITH MACRON
+<U0154>     /xd9         LATIN CAPITAL LETTER R WITH ACUTE
+<U0155>     /xda         LATIN SMALL LETTER R WITH ACUTE
+<U0158>     /xdb         LATIN CAPITAL LETTER R WITH CARON
+<U2039>     /xdc         SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+<U203A>     /xdd         SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+<U0159>     /xde         LATIN SMALL LETTER R WITH CARON
+<U0156>     /xdf         LATIN CAPITAL LETTER R WITH CEDILLA
+<U0157>     /xe0         LATIN SMALL LETTER R WITH CEDILLA
+<U0160>     /xe1         LATIN CAPITAL LETTER S WITH CARON
+<U201A>     /xe2         SINGLE LOW-9 QUOTATION MARK
+<U201E>     /xe3         DOUBLE LOW-9 QUOTATION MARK
+<U0161>     /xe4         LATIN SMALL LETTER S WITH CARON
+<U015A>     /xe5         LATIN CAPITAL LETTER S WITH ACUTE
+<U015B>     /xe6         LATIN SMALL LETTER S WITH ACUTE
+<U00C1>     /xe7         LATIN CAPITAL LETTER A WITH ACUTE
+<U0164>     /xe8         LATIN CAPITAL LETTER T WITH CARON
+<U0165>     /xe9         LATIN SMALL LETTER T WITH CARON
+<U00CD>     /xea         LATIN CAPITAL LETTER I WITH ACUTE
+<U017D>     /xeb         LATIN CAPITAL LETTER Z WITH CARON
+<U017E>     /xec         LATIN SMALL LETTER Z WITH CARON
+<U016A>     /xed         LATIN CAPITAL LETTER U WITH MACRON
+<U00D3>     /xee         LATIN CAPITAL LETTER O WITH ACUTE
+<U00D4>     /xef         LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+<U016B>     /xf0         LATIN SMALL LETTER U WITH MACRON
+<U016E>     /xf1         LATIN CAPITAL LETTER U WITH RING ABOVE
+<U00DA>     /xf2         LATIN CAPITAL LETTER U WITH ACUTE
+<U016F>     /xf3         LATIN SMALL LETTER U WITH RING ABOVE
+<U0170>     /xf4         LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+<U0171>     /xf5         LATIN SMALL LETTER U WITH DOUBLE ACUTE
+<U0172>     /xf6         LATIN CAPITAL LETTER U WITH OGONEK
+<U0173>     /xf7         LATIN SMALL LETTER U WITH OGONEK
+<U00DD>     /xf8         LATIN CAPITAL LETTER Y WITH ACUTE
+<U00FD>     /xf9         LATIN SMALL LETTER Y WITH ACUTE
+<U0137>     /xfa         LATIN SMALL LETTER K WITH CEDILLA
+<U017B>     /xfb         LATIN CAPITAL LETTER Z WITH DOT ABOVE
+<U0141>     /xfc         LATIN CAPITAL LETTER L WITH STROKE
+<U017C>     /xfd         LATIN SMALL LETTER Z WITH DOT ABOVE
+<U0122>     /xfe         LATIN CAPITAL LETTER G WITH CEDILLA
+<U02C7>     /xff         CARON
diff --git a/localedata/locales/de_CH b/localedata/locales/de_CH
index 84963b56fd..170a797d3d 100644
--- a/localedata/locales/de_CH
+++ b/localedata/locales/de_CH
@@ -15,7 +15,6 @@ escape_char  /
 % Date: 1996-10-15
 % Users: general
 % Repertoiremap: mnemonic.ds
-% Charset: ISO-8859-1
 % Distribution and use is free, also
 % for commercial purposes.
 
@@ -30,7 +29,7 @@ fax        ""
 language   "German"
 territory  "Switzerland"
 revision   "1.0"
-date       "2000-06-29"
+date       "2007-09-23"
 %
 category  "de_CH:2000";LC_IDENTIFICATION
 category  "de_CH:2000";LC_CTYPE
@@ -114,7 +113,7 @@ mon     "<U004A><U0061><U006E><U0075><U0061><U0072>";/
         "<U004E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
         "<U0044><U0065><U007A><U0065><U006D><U0062><U0065><U0072>"
 d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
-d_fmt   "<U0025><U0059><U002D><U0025><U006D><U002D><U0025><U0064>"
+d_fmt   "<U0025><U0064><U002E><U0025><U006D><U002E><U0025><U0059>"
 t_fmt   "<U0025><U0054>"
 am_pm   "";""
 t_fmt_ampm ""
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 6056dbab6a..a18eb2d87e 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -131,9 +131,18 @@
 /* Fortify support.  */
 #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
 #define __bos0(ptr) __builtin_object_size (ptr, 0)
-#define __warndecl(name, msg) extern void name (void)
-#define __errordecl(name, msg) extern void name (void)
 
+#if __GNUC_PREREQ (4,3)
+# define __warndecl(name, msg) \
+  extern void name (void) __attribute__((__warning__ (msg)))
+# define __warnattr(msg) __attribute__((__warning__ (msg)))
+# define __errordecl(name, msg) \
+  extern void name (void) __attribute__((__error__ (msg)))
+#else
+# define __warndecl(name, msg) extern void name (void)
+# define __warnattr(msg)
+# define __errordecl(name, msg) extern void name (void)
+#endif
 
 /* Support for flexible arrays.  */
 #if __GNUC_PREREQ (2,97)
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
index 331e8ea3b9..efd7f75a50 100644
--- a/posix/bits/unistd.h
+++ b/posix/bits/unistd.h
@@ -25,13 +25,23 @@ extern ssize_t __read_chk (int __fd, void *__buf, size_t __nbytes,
 			   size_t __buflen) __wur;
 extern ssize_t __REDIRECT (__read_alias, (int __fd, void *__buf,
 					  size_t __nbytes), read) __wur;
+extern ssize_t __REDIRECT (__read_chk_warn,
+			   (int __fd, void *__buf, size_t __nbytes,
+			    size_t __buflen), __read_chk)
+     __wur __warnattr ("read called with bigger length than size of "
+		       "the destination buffer");
 
 __extern_always_inline __wur ssize_t
 read (int __fd, void *__buf, size_t __nbytes)
 {
-  if (__bos0 (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__nbytes) || __nbytes > __bos0 (__buf)))
-    return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf));
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__nbytes))
+	return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf));
+
+      if (__nbytes > __bos0 (__buf))
+	return __read_chk_warn (__fd, __buf, __nbytes, __bos0 (__buf));
+    }
   return __read_alias (__fd, __buf, __nbytes);
 }
 
@@ -46,23 +56,47 @@ extern ssize_t __REDIRECT (__pread_alias,
 extern ssize_t __REDIRECT (__pread64_alias,
 			   (int __fd, void *__buf, size_t __nbytes,
 			    __off64_t __offset), pread64) __wur;
+extern ssize_t __REDIRECT (__pread_chk_warn,
+			   (int __fd, void *__buf, size_t __nbytes,
+			    __off_t __offset, size_t __bufsize), __pread_chk)
+     __wur __warnattr ("pread called with bigger length than size of "
+		       "the destination buffer");
+extern ssize_t __REDIRECT (__pread64_chk_warn,
+			   (int __fd, void *__buf, size_t __nbytes,
+			    __off64_t __offset, size_t __bufsize),
+			    __pread64_chk)
+     __wur __warnattr ("pread64 called with bigger length than size of "
+		       "the destination buffer");
 
 # ifndef __USE_FILE_OFFSET64
 __extern_always_inline __wur ssize_t
 pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset)
 {
-  if (__bos0 (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__nbytes) || __nbytes > __bos0 (__buf)))
-    return __pread_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__nbytes))
+	return __pread_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+      if ( __nbytes > __bos0 (__buf))
+	return __pread_chk_warn (__fd, __buf, __nbytes, __offset,
+				 __bos0 (__buf));
+    }
   return __pread_alias (__fd, __buf, __nbytes, __offset);
 }
 # else
 __extern_always_inline __wur ssize_t
 pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
 {
-  if (__bos0 (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__nbytes) || __nbytes > __bos0 (__buf)))
-    return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__nbytes))
+	return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+      if ( __nbytes > __bos0 (__buf))
+	return __pread64_chk_warn (__fd, __buf, __nbytes, __offset,
+				   __bos0 (__buf));
+    }
+
   return __pread64_alias (__fd, __buf, __nbytes, __offset);
 }
 # endif
@@ -71,9 +105,16 @@ pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
 __extern_always_inline __wur ssize_t
 pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
 {
-  if (__bos0 (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__nbytes) || __nbytes > __bos0 (__buf)))
-    return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__nbytes))
+	return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+      if ( __nbytes > __bos0 (__buf))
+	return __pread64_chk_warn (__fd, __buf, __nbytes, __offset,
+				   __bos0 (__buf));
+    }
+
   return __pread64_alias (__fd, __buf, __nbytes, __offset);
 }
 # endif
@@ -88,14 +129,25 @@ extern ssize_t __REDIRECT_NTH (__readlink_alias,
 			       (__const char *__restrict __path,
 				char *__restrict __buf, size_t __len), readlink)
      __nonnull ((1, 2)) __wur;
+extern ssize_t __REDIRECT_NTH (__readlink_chk_warn,
+			       (__const char *__restrict __path,
+				char *__restrict __buf, size_t __len,
+				size_t __buflen), __readlink_chk)
+     __nonnull ((1, 2)) __wur __warnattr ("readlink called with bigger length "
+					  "than size of destination buffer");
 
 __extern_always_inline __nonnull ((1, 2)) __wur ssize_t
 __NTH (readlink (__const char *__restrict __path, char *__restrict __buf,
 		 size_t __len))
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__len) || __len > __bos (__buf)))
-    return __readlink_chk (__path, __buf, __len, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __readlink_chk (__path, __buf, __len, __bos (__buf));
+
+      if ( __len > __bos (__buf))
+	return __readlink_chk_warn (__path, __buf, __len, __bos (__buf));
+    }
   return __readlink_alias (__path, __buf, __len);
 }
 #endif
@@ -110,14 +162,27 @@ extern ssize_t __REDIRECT_NTH (__readlinkat_alias,
 				char *__restrict __buf, size_t __len),
 			       readlinkat)
      __nonnull ((2, 3)) __wur;
+extern ssize_t __REDIRECT_NTH (__readlinkat_chk_warn,
+			       (int __fd, __const char *__restrict __path,
+				char *__restrict __buf, size_t __len,
+				size_t __buflen), __readlinkat_chk)
+     __nonnull ((2, 3)) __wur __warnattr ("readlinkat called with bigger "
+					  "length than size of destination "
+					  "buffer");
 
 __extern_always_inline __nonnull ((2, 3)) __wur ssize_t
 __NTH (readlinkat (int __fd, __const char *__restrict __path,
 		   char *__restrict __buf, size_t __len))
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__len) || __len > __bos (__buf)))
-    return __readlinkat_chk (__fd, __path, __buf, __len, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __readlinkat_chk (__fd, __path, __buf, __len, __bos (__buf));
+
+      if (__len > __bos (__buf))
+	return __readlinkat_chk_warn (__fd, __path, __buf, __len,
+				      __bos (__buf));
+    }
   return __readlinkat_alias (__fd, __path, __buf, __len);
 }
 #endif
@@ -126,28 +191,39 @@ extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen)
      __THROW __wur;
 extern char *__REDIRECT_NTH (__getcwd_alias,
 			     (char *__buf, size_t __size), getcwd) __wur;
+extern char *__REDIRECT_NTH (__getcwd_chk_warn,
+			     (char *__buf, size_t __size, size_t __buflen),
+			     __getcwd_chk)
+     __wur __warnattr ("getcwd caller with bigger length than size of "
+		       "destination buffer");
 
 __extern_always_inline __wur char *
 __NTH (getcwd (char *__buf, size_t __size))
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__size) || __size > __bos (__buf)))
-    return __getcwd_chk (__buf, __size, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__size))
+	return __getcwd_chk (__buf, __size, __bos (__buf));
+
+      if (__size > __bos (__buf))
+	return __getcwd_chk_warn (__buf, __size, __bos (__buf));
+    }
   return __getcwd_alias (__buf, __size);
 }
 
 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 extern char *__getwd_chk (char *__buf, size_t buflen)
      __THROW __nonnull ((1)) __wur;
-extern char *__REDIRECT_NTH (__getwd_alias, (char *__buf), getwd)
-     __nonnull ((1)) __wur;
+extern char *__REDIRECT_NTH (__getwd_warn, (char *__buf), getwd)
+     __nonnull ((1)) __wur __warnattr ("please use getcwd instead, as getwd "
+				       "doesn't specify buffer size");
 
 __extern_always_inline __nonnull ((1)) __attribute_deprecated__ __wur char *
 __NTH (getwd (char *__buf))
 {
   if (__bos (__buf) != (size_t) -1)
     return __getwd_chk (__buf, __bos (__buf));
-  return __getwd_alias (__buf);
+  return __getwd_warn (__buf);
 }
 #endif
 
@@ -155,29 +231,48 @@ extern size_t __confstr_chk (int __name, char *__buf, size_t __len,
 			     size_t __buflen) __THROW;
 extern size_t __REDIRECT_NTH (__confstr_alias, (int __name, char *__buf,
 						size_t __len), confstr);
+extern size_t __REDIRECT_NTH (__confstr_chk_warn,
+			      (int __name, char *__buf, size_t __len,
+			       size_t __buflen), __confstr_chk)
+     __warnattr ("confstr called with bigger length than size of destination "
+		 "buffer");
 
 __extern_always_inline size_t
 __NTH (confstr (int __name, char *__buf, size_t __len))
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__len) || __bos (__buf) < __len))
-    return __confstr_chk (__name, __buf, __len, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __confstr_chk (__name, __buf, __len, __bos (__buf));
+
+      if (__bos (__buf) < __len)
+	return __confstr_chk_warn (__name, __buf, __len, __bos (__buf));
+    }
   return __confstr_alias (__name, __buf, __len);
 }
 
 
-extern int __getgroups_chk (int __size, __gid_t __list[], size_t listlen)
+extern int __getgroups_chk (int __size, __gid_t __list[], size_t __listlen)
      __THROW __wur;
 extern int __REDIRECT_NTH (__getgroups_alias, (int __size, __gid_t __list[]),
 			   getgroups) __wur;
+extern int __REDIRECT_NTH (__getgroups_chk_warn,
+			   (int __size, __gid_t __list[], size_t __listlen),
+			   __getgroups_chk)
+     __wur __warnattr ("getgroups called with bigger group count than what "
+		       "can fit into destination buffer");
 
 __extern_always_inline int
 __NTH (getgroups (int __size, __gid_t __list[]))
 {
-  if (__bos (__list) != (size_t) -1
-      && (!__builtin_constant_p (__size)
-	  || __size * sizeof (__gid_t) > __bos (__list)))
-    return __getgroups_chk (__size, __list, __bos (__list));
+  if (__bos (__list) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__size))
+	return __getgroups_chk (__size, __list, __bos (__list));
+
+      if (__size * sizeof (__gid_t) > __bos (__list))
+	return __getgroups_chk_warn (__size, __list, __bos (__list));
+    }
   return __getgroups_alias (__size, __list);
 }
 
@@ -187,13 +282,23 @@ extern int __ttyname_r_chk (int __fd, char *__buf, size_t __buflen,
 extern int __REDIRECT_NTH (__ttyname_r_alias, (int __fd, char *__buf,
 					       size_t __buflen), ttyname_r)
      __nonnull ((2));
+extern int __REDIRECT_NTH (__ttyname_r_chk_warn,
+			   (int __fd, char *__buf, size_t __buflen,
+			    size_t __nreal), __ttyname_r_chk)
+     __nonnull ((2)) __warnattr ("ttyname_r called with bigger buflen than "
+				 "size of destination buffer");
 
 __extern_always_inline int
 __NTH (ttyname_r (int __fd, char *__buf, size_t __buflen))
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
-    return __ttyname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __ttyname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+
+      if (__buflen > __bos (__buf))
+	return __ttyname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf));
+    }
   return __ttyname_r_alias (__fd, __buf, __buflen);
 }
 
@@ -203,13 +308,23 @@ extern int __getlogin_r_chk (char *__buf, size_t __buflen, size_t __nreal)
      __nonnull ((1));
 extern int __REDIRECT (__getlogin_r_alias, (char *__buf, size_t __buflen),
 		       getlogin_r) __nonnull ((1));
+extern int __REDIRECT (__getlogin_r_chk_warn,
+		       (char *__buf, size_t __buflen, size_t __nreal),
+		       __getlogin_r_chk)
+     __nonnull ((1)) __warnattr ("getlogin_r called with bigger buflen than "
+				 "size of destination buffer");
 
 __extern_always_inline int
 getlogin_r (char *__buf, size_t __buflen)
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
-    return __getlogin_r_chk (__buf, __buflen, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __getlogin_r_chk (__buf, __buflen, __bos (__buf));
+
+      if (__buflen > __bos (__buf))
+	return __getlogin_r_chk_warn (__buf, __buflen, __bos (__buf));
+    }
   return __getlogin_r_alias (__buf, __buflen);
 }
 #endif
@@ -220,13 +335,23 @@ extern int __gethostname_chk (char *__buf, size_t __buflen, size_t __nreal)
      __THROW __nonnull ((1));
 extern int __REDIRECT_NTH (__gethostname_alias, (char *__buf, size_t __buflen),
 			   gethostname) __nonnull ((1));
+extern int __REDIRECT_NTH (__gethostname_chk_warn,
+			   (char *__buf, size_t __buflen, size_t __nreal),
+			   __gethostname_chk)
+     __nonnull ((1)) __warnattr ("gethostname called with bigger buflen than "
+				 "size of destination buffer");
 
 __extern_always_inline int
 __NTH (gethostname (char *__buf, size_t __buflen))
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
-    return __gethostname_chk (__buf, __buflen, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __gethostname_chk (__buf, __buflen, __bos (__buf));
+
+      if (__buflen > __bos (__buf))
+	return __gethostname_chk_warn (__buf, __buflen, __bos (__buf));
+    }
   return __gethostname_alias (__buf, __buflen);
 }
 #endif
@@ -238,13 +363,24 @@ extern int __getdomainname_chk (char *__buf, size_t __buflen, size_t __nreal)
 extern int __REDIRECT_NTH (__getdomainname_alias, (char *__buf,
 						   size_t __buflen),
 			   getdomainname) __nonnull ((1)) __wur;
+extern int __REDIRECT_NTH (__getdomainname_chk_warn,
+			   (char *__buf, size_t __buflen, size_t __nreal),
+			   __getdomainname_chk)
+     __nonnull ((1)) __wur __warnattr ("getdomainname called with bigger "
+				       "buflen than size of destination "
+				       "buffer");
 
 __extern_always_inline int
 __NTH (getdomainname (char *__buf, size_t __buflen))
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
-    return __getdomainname_chk (__buf, __buflen, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __getdomainname_chk (__buf, __buflen, __bos (__buf));
+
+      if (__buflen > __bos (__buf))
+	return __getdomainname_chk_warn (__buf, __buflen, __bos (__buf));
+    }
   return __getdomainname_alias (__buf, __buflen);
 }
 #endif
diff --git a/posix/regcomp.c b/posix/regcomp.c
index e99fd74924..129546c32c 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -2747,7 +2747,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
       return elem;
     }
 
-  /* Local function for parse_bracket_exp used in _LIBC environement.
+  /* Local function for parse_bracket_exp used in _LIBC environment.
      Look up the collation sequence value of BR_ELEM.
      Return the value if succeeded, UINT_MAX otherwise.  */
 
@@ -2771,7 +2771,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 	}
       else if (br_elem->type == MB_CHAR)
 	{
-	  return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+	  if (nrules != 0)
+	    return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
 	}
       else if (br_elem->type == COLL_SYM)
 	{
diff --git a/resolv/ns_print.c b/resolv/ns_print.c
index 12b2e67ea6..b0b7a1046e 100644
--- a/resolv/ns_print.c
+++ b/resolv/ns_print.c
@@ -112,6 +112,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
 
 	const char *comment;
 	char tmp[100];
+	char errbuf[40];
 	int len, x;
 
 	/*
@@ -174,11 +175,11 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
 		rdata += len;
 		T(addstr(" ", 1, &buf, &buflen));
 
-		    
+
 		/* Second word, optional in ISDN records. */
 		if (type == ns_t_isdn && rdata == edata)
 			break;
-		    
+
 		T(len = charstr(rdata, edata, &buf, &buflen));
 		if (len == 0)
 			goto formerr;
@@ -596,7 +597,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
 			}
 			else
 				leader = " ";
-	
+
 			for (n = 0; n < len; n += 48) {
 				T(addstr(leader, strlen(leader),
 					 &buf, &buflen));
@@ -625,8 +626,48 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
 		break;
 	    }
 
+	case ns_t_a6: {
+		struct in6_addr a;
+		int pbyte, pbit;
+
+		/* prefix length */
+		if (rdlen == 0U) goto formerr;
+		len = SPRINTF((tmp, "%d ", *rdata));
+		T(addstr(tmp, len, &buf, &buflen));
+		pbit = *rdata;
+		if (pbit > 128) goto formerr;
+		pbyte = (pbit & ~7) / 8;
+		rdata++;
+
+		/* address suffix: provided only when prefix len != 128 */
+		if (pbit < 128) {
+			if (rdata + pbyte >= edata) goto formerr;
+			memset(&a, 0, sizeof(a));
+			memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
+			(void) inet_ntop(AF_INET6, &a, buf, buflen);
+			addlen(strlen(buf), &buf, &buflen);
+			rdata += sizeof(a) - pbyte;
+		}
+
+		/* prefix name: provided only when prefix len > 0 */
+		if (pbit == 0)
+			break;
+		if (rdata >= edata) goto formerr;
+		T(addstr(" ", 1, &buf, &buflen));
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_opt: {
+		len = SPRINTF((tmp, "%u bytes", class));
+		T(addstr(tmp, len, &buf, &buflen));
+		break;
+	    }
+
 	default:
-		comment = "unknown RR type";
+		snprintf (errbuf, sizeof (errbuf), "unknown RR type %d", type);
+		comment = errbuf;
 		goto hexify;
 	}
 	return (buf - obuf);
diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h
index 9fac75669c..5c4cb47a6d 100644
--- a/socket/bits/socket2.h
+++ b/socket/bits/socket2.h
@@ -25,13 +25,23 @@ extern ssize_t __recv_chk (int __fd, void *__buf, size_t __n, size_t __buflen,
 			   int __flags);
 extern ssize_t __REDIRECT (__recv_alias, (int __fd, void *__buf, size_t __n,
 					  int __flags), recv);
+extern ssize_t __REDIRECT (__recv_chk_warn,
+			   (int __fd, void *__buf, size_t __n, size_t __buflen,
+			    int __flags), __recv_chk)
+     __warnattr ("recv called with bigger length than size of destination "
+		 "buffer");
 
 __extern_always_inline ssize_t
 recv (int __fd, void *__buf, size_t __n, int __flags)
 {
-  if (__bos0 (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__n) || __n > __bos0 (__buf)))
-    return __recv_chk (__fd, __buf, __n, __bos0 (__buf), __flags);
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n))
+	return __recv_chk (__fd, __buf, __n, __bos0 (__buf), __flags);
+
+      if (__n > __bos0 (__buf))
+	return __recv_chk_warn (__fd, __buf, __n, __bos0 (__buf), __flags);
+    }
   return __recv_alias (__fd, __buf, __n, __flags);
 }
 
@@ -43,14 +53,26 @@ extern ssize_t __REDIRECT (__recvfrom_alias,
 			   (int __fd, void *__restrict __buf, size_t __n,
 			    int __flags, __SOCKADDR_ARG __addr,
 			    socklen_t *__restrict __addr_len), recvfrom);
+extern ssize_t __REDIRECT (__recvfrom_chk_warn,
+			   (int __fd, void *__restrict __buf, size_t __n,
+			    size_t __buflen, int __flags,
+			    __SOCKADDR_ARG __addr,
+			    socklen_t *__restrict __addr_len), __recvfrom_chk)
+     __warnattr ("recvfrom called with bigger length than size of "
+		 "destination buffer");
 
 __extern_always_inline ssize_t
 recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags,
 	  __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len)
 {
-  if (__bos0 (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__n) || __n > __bos0 (__buf)))
-    return __recvfrom_chk (__fd, __buf, __n, __bos0 (__buf), __flags,
-			   __addr, __addr_len);
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n))
+	return __recvfrom_chk (__fd, __buf, __n, __bos0 (__buf), __flags,
+			       __addr, __addr_len);
+      if (__n > __bos0 (__buf))
+	return __recvfrom_chk_warn (__fd, __buf, __n, __bos0 (__buf), __flags,
+				    __addr, __addr_len);
+    }
   return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len);
 }
diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
index 7ee7bf5587..f6af5e518c 100644
--- a/stdlib/bits/stdlib.h
+++ b/stdlib/bits/stdlib.h
@@ -27,12 +27,24 @@ extern char *__realpath_chk (__const char *__restrict __name,
 extern char *__REDIRECT_NTH (__realpath_alias,
 			     (__const char *__restrict __name,
 			      char *__restrict __resolved), realpath) __wur;
+extern char *__REDIRECT_NTH (__realpath_chk_warn,
+			     (__const char *__restrict __name,
+			      char *__restrict __resolved,
+			      size_t __resolvedlen), __realpath_chk) __wur
+     __warnattr ("second argument of realpath must be either NULL or at "
+		 "least PATH_MAX bytes long buffer");
 
 __extern_always_inline __wur char *
 __NTH (realpath (__const char *__restrict __name, char *__restrict __resolved))
 {
   if (__bos (__resolved) != (size_t) -1)
-    return __realpath_chk (__name, __resolved, __bos (__resolved));
+    {
+#if defined _LIBC_LIMITS_H_ && defined PATH_MAX
+      if (__bos (__resolved) < PATH_MAX)
+	return __realpath_chk_warn (__name, __resolved, __bos (__resolved));
+#endif
+      return __realpath_chk (__name, __resolved, __bos (__resolved));
+    }
 
   return __realpath_alias (__name, __resolved);
 }
@@ -43,13 +55,22 @@ extern int __ptsname_r_chk (int __fd, char *__buf, size_t __buflen,
 extern int __REDIRECT_NTH (__ptsname_r_alias, (int __fd, char *__buf,
 					       size_t __buflen), ptsname_r)
      __nonnull ((2));
+extern int __REDIRECT_NTH (__ptsname_r_chk_warn,
+			   (int __fd, char *__buf, size_t __buflen,
+			    size_t __nreal), __ptsname_r_chk)
+     __nonnull ((2)) __warnattr ("ptsname_r called with buflen bigger than "
+				 "size of buf");
 
 __extern_always_inline int
 __NTH (ptsname_r (int __fd, char *__buf, size_t __buflen))
 {
-  if (__bos (__buf) != (size_t) -1
-      && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
-    return __ptsname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __ptsname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+      if (__buflen > __bos (__buf))
+	return __ptsname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf));
+    }
   return __ptsname_r_alias (__fd, __buf, __buflen);
 }
 
@@ -82,16 +103,27 @@ extern size_t __REDIRECT_NTH (__mbstowcs_alias,
 			      (wchar_t *__restrict __dst,
 			       __const char *__restrict __src,
 			       size_t __len), mbstowcs);
+extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn,
+			      (wchar_t *__restrict __dst,
+			       __const char *__restrict __src,
+			       size_t __len, size_t __dstlen), __mbstowcs_chk)
+     __warnattr ("mbstowcs called with dst buffer smaller than len "
+		 "* sizeof (wchar_t)");
 
 __extern_always_inline size_t
 __NTH (mbstowcs (wchar_t *__restrict __dst, __const char *__restrict __src,
 		 size_t __len))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len)
-	  || __len > __bos (__dst) / sizeof (wchar_t)))
-    return __mbstowcs_chk (__dst, __src, __len,
-			   __bos (__dst) / sizeof (wchar_t));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __mbstowcs_chk (__dst, __src, __len,
+			       __bos (__dst) / sizeof (wchar_t));
+
+      if (__len > __bos (__dst) / sizeof (wchar_t))
+	return __mbstowcs_chk_warn (__dst, __src, __len,
+				     __bos (__dst) / sizeof (wchar_t));
+    }
   return __mbstowcs_alias (__dst, __src, __len);
 }
 
@@ -103,13 +135,22 @@ extern size_t __REDIRECT_NTH (__wcstombs_alias,
 			      (char *__restrict __dst,
 			       __const wchar_t *__restrict __src,
 			       size_t __len), wcstombs);
+extern size_t __REDIRECT_NTH (__wcstombs_chk_warn,
+			      (char *__restrict __dst,
+			       __const wchar_t *__restrict __src,
+			       size_t __len, size_t __dstlen), __wcstombs_chk)
+     __warnattr ("wcstombs called with dst buffer smaller than len");
 
 __extern_always_inline size_t
 __NTH (wcstombs (char *__restrict __dst, __const wchar_t *__restrict __src,
 		 size_t __len))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len) || __len > __bos (__dst)))
-    return __wcstombs_chk (__dst, __src, __len, __bos (__dst));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __wcstombs_chk (__dst, __src, __len, __bos (__dst));
+      if (__len > __bos (__dst))
+	return __wcstombs_chk_warn (__dst, __src, __len, __bos (__dst));
+    }
   return __wcstombs_alias (__dst, __src, __len);
 }
diff --git a/string/stratcliff.c b/string/stratcliff.c
index 6377c6ed76..77fe2bcca9 100644
--- a/string/stratcliff.c
+++ b/string/stratcliff.c
@@ -1,5 +1,5 @@
 /* Test for string function add boundaries of usable memory.
-   Copyright (C) 1996,1997,1999-2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1996,1997,1999-2002,2003,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -31,20 +31,40 @@
 #include <sys/mman.h>
 #include <sys/param.h>
 
-#ifndef MAX
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#ifndef CHAR
+# define L(c) c
+# define CHAR char
+# define MEMSET memset
+# define STRLEN strlen
+# define STRNLEN strnlen
+# define STRCHR strchr
+# define STRRCHR strrchr
+# define STRCPY strcpy
+# define STRNCPY strncpy
+# define MEMCMP memcmp
+# define STPCPY stpcpy
+# define STPNCPY stpncpy
+# define MEMCPY memcpy
+# define MEMPCPY mempcpy
 #endif
 
-int
-main (int argc, char *argv[])
+
+#define STRINGIFY(s) STRINGIFY2 (s)
+#define STRINGIFY2(s) #s
+
+
+static int
+do_test (void)
 {
   int size = sysconf (_SC_PAGESIZE);
-  char *adr, *dest;
+  int nchars = size / sizeof (CHAR);
+  CHAR *adr;
+  CHAR *dest;
   int result = 0;
 
-  adr = (char *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
+  adr = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
 		       MAP_PRIVATE | MAP_ANON, -1, 0);
-  dest = (char *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
+  dest = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
 			MAP_PRIVATE | MAP_ANON, -1, 0);
   if (adr == MAP_FAILED || dest == MAP_FAILED)
     {
@@ -60,270 +80,310 @@ main (int argc, char *argv[])
     {
       int inner, middle, outer;
 
-      mprotect(adr, size, PROT_NONE);
-      mprotect(adr + 2 * size, size, PROT_NONE);
-      adr += size;
+      mprotect (adr, size, PROT_NONE);
+      mprotect (adr + 2 * nchars, size, PROT_NONE);
+      adr += nchars;
 
-      mprotect(dest, size, PROT_NONE);
-      mprotect(dest + 2 * size, size, PROT_NONE);
-      dest += size;
+      mprotect (dest, size, PROT_NONE);
+      mprotect (dest + 2 * nchars, size, PROT_NONE);
+      dest += nchars;
 
-      memset (adr, 'T', size);
+      MEMSET (adr, L('T'), nchars);
 
-      /* strlen test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      /* strlen/wcslen test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
         {
-          for (inner = MAX (outer, size - 64); inner < size; ++inner)
+          for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
 	    {
-	      adr[inner] = '\0';
+	      adr[inner] = L('\0');
 
-	      if (strlen (&adr[outer]) != (size_t) (inner - outer))
+	      if (STRLEN (&adr[outer]) != (size_t) (inner - outer))
 		{
-		  printf ("strlen flunked for outer = %d, inner = %d\n",
-			  outer, inner);
+		  printf ("%s flunked for outer = %d, inner = %d\n",
+			  STRINGIFY (STRLEN), outer, inner);
 		  result = 1;
 		}
 
-	      adr[inner] = 'T';
+	      adr[inner] = L('T');
 	    }
         }
 
-      /* strchr test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      /* strnlen/wcsnlen test */
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
         {
-	  for (middle = MAX (outer, size - 64); middle < size; ++middle)
+          for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
 	    {
-	      for (inner = middle; inner < size; ++inner)
+	      adr[inner] = L('\0');
+
+	      if (STRNLEN (&adr[outer], inner - outer + 1)
+		  != (size_t) (inner - outer))
 		{
-		  char *cp;
-		  adr[middle] = 'V';
-		  adr[inner] = '\0';
+		  printf ("%s flunked for outer = %d, inner = %d\n",
+			  STRINGIFY (STRNLEN), outer, inner);
+		  result = 1;
+		}
 
-		  cp = strchr (&adr[outer], 'V');
+	      adr[inner] = L('T');
+	    }
+        }
+      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
+        {
+          for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
+	    {
+	      if (STRNLEN (&adr[outer], inner - outer + 1)
+		  != (size_t) (inner - outer + 1))
+		{
+		  printf ("%s flunked bounded for outer = %d, inner = %d\n",
+			  STRINGIFY (STRNLEN), outer, inner);
+		  result = 1;
+		}
+	    }
+        }
+
+      /* strchr/wcschr test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+        {
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
+	    {
+	      for (inner = middle; inner < nchars; ++inner)
+		{
+		  adr[middle] = L('V');
+		  adr[inner] = L('\0');
+
+		  CHAR *cp = STRCHR (&adr[outer], L('V'));
 
 		  if ((inner == middle && cp != NULL)
 		      || (inner != middle
 			  && (cp - &adr[outer]) != middle - outer))
 		    {
-		      printf ("strchr flunked for outer = %d, middle = %d, "
-			      "inner = %d\n", outer, middle, inner);
+		      printf ("%s flunked for outer = %d, middle = %d, "
+			      "inner = %d\n",
+			      STRINGIFY (STRCHR), outer, middle, inner);
 		      result = 1;
 		    }
 
-		  adr[inner] = 'T';
-		  adr[middle] = 'T';
+		  adr[inner] = L('T');
+		  adr[middle] = L('T');
 		}
 	    }
         }
 
       /* Special test.  */
-      adr[size - 1] = '\0';
-      if (strchr (&adr[size - 1], '\n') != NULL)
+      adr[nchars - 1] = L('\0');
+      if (STRCHR (&adr[nchars - 1], L('\n')) != NULL)
 	{
-	  puts ("strchr flunked for test of empty string at end of page");
+	  printf ("%s flunked test of empty string at end of page\n",
+		  STRINGIFY (STRCHR));
 	  result = 1;
 	}
 
-      /* strrchr test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      /* strrchr/wcsrchr test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
         {
-	  for (middle = MAX (outer, size - 64); middle < size; ++middle)
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
 	    {
-	      for (inner = middle; inner < size; ++inner)
+	      for (inner = middle; inner < nchars; ++inner)
 		{
-		  char *cp;
-		  adr[middle] = 'V';
-		  adr[inner] = '\0';
+		  adr[middle] = L('V');
+		  adr[inner] = L('\0');
 
-		  cp = strrchr (&adr[outer], 'V');
+		  CHAR *cp = STRRCHR (&adr[outer], L('V'));
 
 		  if ((inner == middle && cp != NULL)
 		      || (inner != middle
 			  && (cp - &adr[outer]) != middle - outer))
 		    {
-		      printf ("strrchr flunked for outer = %d, middle = %d, "
-			      "inner = %d\n", outer, middle, inner);
+		      printf ("%s flunked for outer = %d, middle = %d, "
+			      "inner = %d\n",
+			      STRINGIFY (STRRCHR), outer, middle, inner);
 		      result = 1;
 		    }
 
-		  adr[inner] = 'T';
-		  adr[middle] = 'T';
+		  adr[inner] = L('T');
+		  adr[middle] = L('T');
 		}
 	    }
         }
 
+      /* This function only exists for single-byte characters.  */
+#ifndef WCSTEST
       /* rawmemchr test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
         {
-	  for (middle = MAX (outer, size - 64); middle < size; ++middle)
+	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
 	    {
-	      char *cp;
-	      adr[middle] = 'V';
+	      adr[middle] = L('V');
 
-	      cp = rawmemchr (&adr[outer], 'V');
+	      CHAR *cp = rawmemchr (&adr[outer], L('V'));
 
 	      if (cp - &adr[outer] != middle - outer)
 		{
-		  printf ("rawmemchr flunked for outer = %d, middle = %d\n",
-			  outer, middle);
+		  printf ("%s flunked for outer = %d, middle = %d\n",
+			  STRINGIFY (rawmemchr), outer, middle);
 		  result = 1;
 		}
 
-	      adr[middle] = 'T';
+	      adr[middle] = L('T');
 	    }
         }
+#endif
 
-      /* strcpy test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      /* strcpy/wcscpy test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
         {
-          for (inner = MAX (outer, size - 64); inner < size; ++inner)
+          for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
 	    {
-	      adr[inner] = '\0';
+	      adr[inner] = L('\0');
 
-	      if (strcpy (dest, &adr[outer]) != dest
-		  || strlen (dest) != (size_t) (inner - outer))
+	      if (STRCPY (dest, &adr[outer]) != dest
+		  || STRLEN (dest) != (size_t) (inner - outer))
 		{
-		  printf ("strcpy flunked for outer = %d, inner = %d\n",
-			  outer, inner);
+		  printf ("%s flunked for outer = %d, inner = %d\n",
+			  STRINGIFY (STRCPY), outer, inner);
 		  result = 1;
 		}
 
-	      adr[inner] = 'T';
+	      adr[inner] = L('T');
 	    }
         }
 
       /* strncpy tests */
-      adr[size-1] = 'T';
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      adr[nchars - 1] = L('T');
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
 	{
 	  size_t len;
 
-	  for (len = 0; len < size - outer; ++len)
+	  for (len = 0; len < nchars - outer; ++len)
 	    {
-	      if (strncpy (dest, &adr[outer], len) != dest
-		  || memcmp (dest, &adr[outer], len) != 0)
+	      if (STRNCPY (dest, &adr[outer], len) != dest
+		  || MEMCMP (dest, &adr[outer], len) != 0)
 		{
-		  printf ("outer strncpy flunked for outer = %d, len = %Zd\n",
-			  outer, len);
+		  printf ("outer %s flunked for outer = %d, len = %Zd\n",
+			  STRINGIFY (STRNCPY), outer, len);
 		  result = 1;
 		}
 	    }
         }
-      adr[size-1] = '\0';
+      adr[nchars - 1] = L('\0');
 
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
         {
-          for (inner = MAX (outer, size - 64); inner < size; ++inner)
+          for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
 	    {
 	      size_t len;
 
-	      adr[inner] = '\0';
+	      adr[inner] = L('\0');
 
-	      for (len = 0; len < size - outer + 64; ++len)
+	      for (len = 0; len < nchars - outer + 64; ++len)
 		{
-		  if (strncpy (dest, &adr[outer], len) != dest
-		      || memcmp (dest, &adr[outer],
+		  if (STRNCPY (dest, &adr[outer], len) != dest
+		      || MEMCMP (dest, &adr[outer],
 				 MIN (inner - outer, len)) != 0
 		      || (inner - outer < len
-			  && strlen (dest) != (inner - outer)))
+			  && STRLEN (dest) != (inner - outer)))
 		    {
-		      printf ("strncpy flunked for outer = %d, inner = %d, len = %Zd\n",
-			      outer, inner, len);
+		      printf ("%s flunked for outer = %d, inner = %d, "
+			      "len = %Zd\n",
+			      STRINGIFY (STRNCPY), outer, inner, len);
 		      result = 1;
 		    }
-		  if (strncpy (dest + 1, &adr[outer], len) != dest + 1
-		      || memcmp (dest + 1, &adr[outer],
+		  if (STRNCPY (dest + 1, &adr[outer], len) != dest + 1
+		      || MEMCMP (dest + 1, &adr[outer],
 				 MIN (inner - outer, len)) != 0
 		      || (inner - outer < len
-			  && strlen (dest + 1) != (inner - outer)))
+			  && STRLEN (dest + 1) != (inner - outer)))
 		    {
-		      printf ("strncpy+1 flunked for outer = %d, inner = %d, len = %Zd\n",
-			      outer, inner, len);
+		      printf ("%s+1 flunked for outer = %d, inner = %d, "
+			      "len = %Zd\n",
+			      STRINGIFY (STRNCPY), outer, inner, len);
 		      result = 1;
 		    }
 		}
 
-	      adr[inner] = 'T';
+	      adr[inner] = L('T');
 	    }
         }
 
-      /* stpcpy test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      /* stpcpy/wcpcpy test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
         {
-          for (inner = MAX (outer, size - 64); inner < size; ++inner)
+          for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
 	    {
-	      adr[inner] = '\0';
+	      adr[inner] = L('\0');
 
-	      if ((stpcpy (dest, &adr[outer]) - dest) != inner - outer)
+	      if ((STPCPY (dest, &adr[outer]) - dest) != inner - outer)
 		{
-		  printf ("stpcpy flunked for outer = %d, inner = %d\n",
-			  outer, inner);
+		  printf ("%s flunked for outer = %d, inner = %d\n",
+			  STRINGIFY (STPCPY), outer, inner);
 		  result = 1;
 		}
 
-	      adr[inner] = 'T';
+	      adr[inner] = L('T');
 	    }
         }
 
-      /* stpncpy test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+      /* stpncpy/wcpncpy test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
         {
-          for (middle = MAX (outer, size - 64); middle < size; ++middle)
+          for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
 	    {
-	      adr[middle] = '\0';
+	      adr[middle] = L('\0');
 
-	      for (inner = 0; inner < size - outer; ++ inner)
+	      for (inner = 0; inner < nchars - outer; ++ inner)
 		{
-		  if ((stpncpy (dest, &adr[outer], inner) - dest)
+		  if ((STPNCPY (dest, &adr[outer], inner) - dest)
 		      != MIN (inner, middle - outer))
 		    {
-		      printf ("stpncpy flunked for outer = %d, middle = %d, "
-			      "inner = %d\n", outer, middle, inner);
+		      printf ("%s flunked for outer = %d, middle = %d, "
+			      "inner = %d\n",
+			      STRINGIFY (STPNCPY), outer, middle, inner);
 		      result = 1;
 		    }
 		}
 
-	      adr[middle] = 'T';
+	      adr[middle] = L('T');
 	    }
         }
 
-      /* memcpy test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
-	for (inner = 0; inner < size - outer; ++inner)
-	  if (memcpy (dest, &adr[outer], inner) !=  dest)
+      /* memcpy/wmemcpy test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	for (inner = 0; inner < nchars - outer; ++inner)
+	  if (MEMCPY (dest, &adr[outer], inner) !=  dest)
 	    {
-	      printf ("memcpy flunked for outer = %d, inner = %d\n",
-		      outer, inner);
+	      printf ("%s flunked for outer = %d, inner = %d\n",
+		      STRINGIFY (MEMCPY), outer, inner);
 	      result = 1;
 	    }
 
-      /* mempcpy test */
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
-	for (inner = 0; inner < size - outer; ++inner)
-	  if (mempcpy (dest, &adr[outer], inner) !=  dest + inner)
+      /* mempcpy/wmempcpy test */
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	for (inner = 0; inner < nchars - outer; ++inner)
+	  if (MEMPCPY (dest, &adr[outer], inner) !=  dest + inner)
 	    {
-	      printf ("mempcpy flunked for outer = %d, inner = %d\n",
-		      outer, inner);
+	      printf ("%s flunked for outer = %d, inner = %d\n",
+		      STRINGIFY (MEMPCPY), outer, inner);
 	      result = 1;
 	    }
 
+      /* This function only exists for single-byte characters.  */
+#ifndef WCSTEST
       /* memccpy test */
-      memset (adr, '\0', size);
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
-	for (inner = 0; inner < size - outer; ++inner)
-	  if (memccpy (dest, &adr[outer], '\1', inner) != NULL)
+      memset (adr, '\0', nchars);
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	for (inner = 0; inner < nchars - outer; ++inner)
+	  if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL)
 	    {
 	      printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
 		      outer, inner);
 	      result = 1;
 	    }
-      for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
-	for (middle = 0; middle < size - outer; ++middle)
+      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
+	for (middle = 0; middle < nchars - outer; ++middle)
 	  {
-	    memset (dest, '\2', middle + 1);
+	    memset (dest, L('\2'), middle + 1);
 	    for (inner = 0; inner < middle; ++inner)
 	      {
-		adr[outer + inner] = '\1';
+		adr[outer + inner] = L('\1');
 
 		if (memccpy (dest, &adr[outer], '\1', middle + 128)
 		    !=  dest + inner + 1)
@@ -333,17 +393,21 @@ memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
 			    outer, middle, inner);
 		    result = 1;
 		  }
-		else if (dest[inner + 1] != '\2')
+		else if (dest[inner + 1] != L('\2'))
 		  {
 		    printf ("\
 memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
 			    outer, middle, inner);
 		    result = 1;
 		  }
-		adr[outer + inner] = '\0';
+		adr[outer + inner] = L('\0');
 	      }
 	  }
+#endif
     }
 
   return result;
 }
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 147bffb96f..958a099b82 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -491,7 +491,7 @@ struct rtld_global
   EXTERN struct dl_scope_free_list
   {
     size_t count;
-    struct r_scope_elem **list[50];
+    void *list[50];
   } *_dl_scope_free_list;
 #ifdef SHARED
 };
@@ -1058,7 +1058,7 @@ extern void *_dl_open (const char *name, int mode, const void *caller,
 /* Free or queue for freeing scope OLD.  If other threads might be
    in the middle of _dl_fixup, _dl_profile_fixup or dl*sym using the
    old scope, OLD can't be freed until no thread is using it.  */
-extern int _dl_scope_free (struct r_scope_elem **old) attribute_hidden;
+extern int _dl_scope_free (void *) attribute_hidden;
 
 /* Add module to slot information data.  */
 extern void _dl_add_to_slotinfo (struct link_map  *l) attribute_hidden;
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index b668936095..221b41dd00 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1975,7 +1975,7 @@ getaddrinfo (const char *name, const char *service,
 		{
 		  if (fd != -1)
 		  close_retry:
-		    close (fd);
+		    close_not_cancel_no_status (fd);
 		  af = q->ai_family;
 		  fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
 		}
diff --git a/sysdeps/x86_64/cacheinfo.c b/sysdeps/x86_64/cacheinfo.c
index 793dc2d357..5b92bd5849 100644
--- a/sysdeps/x86_64/cacheinfo.c
+++ b/sysdeps/x86_64/cacheinfo.c
@@ -398,13 +398,13 @@ __cache_sysconf (int name)
 }
 
 
-/* Half the core cache size for use in memory and string routines, typically
-   L1 size. */
-long int __x86_64_core_cache_size_half attribute_hidden = 32 * 1024 / 2;
+/* Half the data cache size for use in memory and string routines, typically
+   L1 size.  */
+long int __x86_64_data_cache_size_half attribute_hidden = 32 * 1024 / 2;
 /* Shared cache size for use in memory and string routines, typically
-   L2 or L3 size. */
+   L2 or L3 size.  */
 long int __x86_64_shared_cache_size_half attribute_hidden = 1024 * 1024 / 2;
-/* PREFETCHW support flag for use in memory and string routines. */
+/* PREFETCHW support flag for use in memory and string routines.  */
 int __x86_64_prefetchw attribute_hidden;
 
 
@@ -419,7 +419,7 @@ init_cacheinfo (void)
   unsigned int edx;
   int max_cpuid;
   int max_cpuid_ex;
-  long int core = -1;
+  long int data = -1;
   long int shared = -1;
   unsigned int level;
   unsigned int threads = 0;
@@ -431,26 +431,26 @@ init_cacheinfo (void)
   /* This spells out "GenuineIntel".  */
   if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
     {
-      core = handle_intel (_SC_LEVEL1_DCACHE_SIZE, max_cpuid);
+      data = handle_intel (_SC_LEVEL1_DCACHE_SIZE, max_cpuid);
 
-      /* Try L3 first. */
+      /* Try L3 first.  */
       level  = 3;
       shared = handle_intel (_SC_LEVEL3_CACHE_SIZE, max_cpuid);
 
       if (shared <= 0)
         {
-	  /* Try L2 otherwise. */
+	  /* Try L2 otherwise.  */
           level  = 2;
           shared = handle_intel (_SC_LEVEL2_CACHE_SIZE, max_cpuid);
 	}
 
       /* Figure out the number of logical threads that share the
-	 highest cache level. */
+	 highest cache level.  */
       if (max_cpuid >= 4)
         {
 	  int i = 0;
 
-	  /* Query until desired cache level is enumerated. */
+	  /* Query until desired cache level is enumerated.  */
 	  do
 	    {
               asm volatile ("cpuid"
@@ -463,7 +463,7 @@ init_cacheinfo (void)
 	}
       else
         {
-	  /* Assume that all logical threads share the highest cache level. */
+	  /* Assume that all logical threads share the highest cache level.  */
           asm volatile ("cpuid"
 		        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
 		        : "0" (1));
@@ -472,33 +472,73 @@ init_cacheinfo (void)
 	}
 
       /* Cap usage of highest cache level to the number of supported
-	 threads. */
+	 threads.  */
       if (shared > 0 && threads > 0)
         shared /= threads;
     }
   /* This spells out "AuthenticAMD".  */
   else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
     {
-      core   = handle_amd (_SC_LEVEL1_DCACHE_SIZE);
-      shared = handle_amd (_SC_LEVEL2_CACHE_SIZE);
+      data   = handle_amd (_SC_LEVEL1_DCACHE_SIZE);
+      long int core = handle_amd (_SC_LEVEL2_CACHE_SIZE);
+      shared = handle_amd (_SC_LEVEL3_CACHE_SIZE);
 
+      /* Get maximum extended function. */
       asm volatile ("cpuid"
 		    : "=a" (max_cpuid_ex), "=b" (ebx), "=c" (ecx), "=d" (edx)
 		    : "0" (0x80000000));
 
+      if (shared <= 0)
+	/* No shared L3 cache.  All we have is the L2 cache.  */
+	shared = core;
+      else
+	{
+	  /* Figure out the number of logical threads that share L3.  */
+	  if (max_cpuid_ex >= 0x80000008)
+	    {
+	      /* Get width of APIC ID.  */
+	      asm volatile ("cpuid"
+			    : "=a" (max_cpuid_ex), "=b" (ebx), "=c" (ecx),
+			      "=d" (edx)
+			    : "0" (0x80000008));
+	      threads = 1 << ((ecx >> 12) & 0x0f);
+	    }
+
+	  if (threads == 0)
+	    {
+	      /* If APIC ID width is not available, use logical
+		 processor count.  */
+	      asm volatile ("cpuid"
+			    : "=a" (max_cpuid_ex), "=b" (ebx), "=c" (ecx),
+			      "=d" (edx)
+			    : "0" (0x00000001));
+
+	      if ((edx & (1 << 28)) != 0)
+		threads = (ebx >> 16) & 0xff;
+	    }
+
+	  /* Cap usage of highest cache level to the number of
+	     supported threads.  */
+	  if (threads > 0)
+	    shared /= threads;
+
+	  /* Account for exclusive L2 and L3 caches.  */
+	  shared += core;
+	}
+
       if (max_cpuid_ex >= 0x80000001)
 	{
 	  asm volatile ("cpuid"
 			: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
 			: "0" (0x80000001));
-	  /*  PREFETCHW     || 3DNow! */
+	  /*  PREFETCHW     || 3DNow!  */
 	  if ((ecx & 0x100) || (edx & 0x80000000))
 	    __x86_64_prefetchw = -1;
 	}
     }
 
-  if (core > 0)
-    __x86_64_core_cache_size_half = core / 2;
+  if (data > 0)
+    __x86_64_data_cache_size_half = data / 2;
 
   if (shared > 0)
     __x86_64_shared_cache_size_half = shared / 2;
diff --git a/sysdeps/x86_64/memcpy.S b/sysdeps/x86_64/memcpy.S
index 231329864f..b25646b8c5 100644
--- a/sysdeps/x86_64/memcpy.S
+++ b/sysdeps/x86_64/memcpy.S
@@ -114,15 +114,15 @@ L(1d):					/* 16-byte loop */
 	.p2align 4
 
 L(1loop):
-	movq	  (%rsi), %rcx
-	movq	8 (%rsi), %r8
-	movq	%rcx,   (%rdi)
-	movq	 %r8, 8 (%rdi)
+	movq	 (%rsi), %rcx
+	movq	8(%rsi), %r8
+	movq	%rcx,  (%rdi)
+	movq	 %r8, 8(%rdi)
 
 	subl	$16, %edx
 
-	leaq	16 (%rsi), %rsi
-	leaq	16 (%rdi), %rdi
+	leaq	16(%rsi), %rsi
+	leaq	16(%rdi), %rdi
 
 	jnz	L(1loop)
 
@@ -140,19 +140,19 @@ L(exit):				/* exit */
 
 L(1after):
 #ifndef USE_AS_MEMPCPY
-	movq	%rax, RETVAL (%rsp)	/* save return value */
+	movq	%rax, RETVAL(%rsp)	/* save return value */
 #endif
 
 /* Align to the natural word size. */
 
 L(aligntry):
-	movl	%esi, %ecx      	/* align by destination */
+	movl	%esi, %ecx      	/* align by source */
 
 	andl	$7, %ecx
 	jz	L(alignafter)  		/* already aligned */
 
 L(align):		      		/* align */
-	leaq	-8 (%rcx, %rdx), %rdx	/* calculate remaining bytes */
+	leaq	-8(%rcx, %rdx), %rdx	/* calculate remaining bytes */
 	subl	$8, %ecx
 
 	.p2align 4
@@ -163,8 +163,8 @@ L(alignloop):				/* 1-byte alignment loop */
 
 	incl	%ecx
 
-	leaq	1 (%rsi), %rsi
-	leaq	1 (%rdi), %rdi
+	leaq	1(%rsi), %rsi
+	leaq	1(%rdi), %rdi
 
 	jnz	L(alignloop)
 
@@ -172,7 +172,7 @@ L(alignloop):				/* 1-byte alignment loop */
 
 L(alignafter):
 
-/* Loop to handle mid-sized blocks. */
+/* Handle mid-sized blocks. */
 
 L(32try):				/* up to 1KB */
 	cmpq	$1024, %rdx
@@ -188,15 +188,15 @@ L(32):					/* 32-byte loop */
 L(32loop):
 	decl	%ecx
 
-	movq	(%rsi), %rax
-	movq	 8 (%rsi), %r8
-	movq	16 (%rsi), %r9
-	movq	24 (%rsi), %r10
+	movq	  (%rsi), %rax
+	movq	 8(%rsi), %r8
+	movq	16(%rsi), %r9
+	movq	24(%rsi), %r10
 
-	movq	%rax, (%rdi)
-	movq	 %r8,  8 (%rdi)
-	movq	 %r9, 16 (%rdi)
-	movq	%r10, 24 (%rdi)
+	movq	%rax,   (%rdi)
+	movq	 %r8,  8(%rdi)
+	movq	 %r9, 16(%rdi)
+	movq	%r10, 24(%rdi)
 
 	leaq	32(%rsi), %rsi
 	leaq	32(%rdi), %rdi
@@ -205,18 +205,18 @@ L(32loop):
 
 	decl	%ecx
 
-	movq	   (%rsi), %rax
-	movq	 8 (%rsi), %r8
-	movq	16 (%rsi), %r9
-	movq	24 (%rsi), %r10
+	movq	  (%rsi), %rax
+	movq	 8(%rsi), %r8
+	movq	16(%rsi), %r9
+	movq	24(%rsi), %r10
 
-	movq	%rax,    (%rdi)
-	movq	 %r8,  8 (%rdi)
-	movq	 %r9, 16 (%rdi)
-	movq	%r10, 24 (%rdi)
+	movq	%rax,   (%rdi)
+	movq	 %r8,  8(%rdi)
+	movq	 %r9, 16(%rdi)
+	movq	%r10, 24(%rdi)
 
-	leaq	32 (%rsi), %rsi
-	leaq	32 (%rdi), %rdi
+	leaq	32(%rsi), %rsi
+	leaq	32(%rdi), %rdi
 
 	jnz	L(32loop)
 
@@ -229,9 +229,9 @@ L(32skip):
 
 	movq	%rdi, %rax
 #else
-	movq	RETVAL (%rsp), %rax
+	movq	RETVAL(%rsp), %rax
 	jnz	L(1)
-	
+
 	rep
 #endif
 	retq				/* exit */
@@ -245,11 +245,11 @@ L(32after):
 	larger blocks are excluded when building for RTLD.
 */
 
-/* Handle large blocks smaller than 1/2 L1. */
+/* Handle blocks smaller than 1/2 L1. */
 
 L(fasttry):				/* first 1/2 L1 */
 #ifndef NOT_IN_libc			/* only up to this algorithm outside of libc.so */
-	movq	__x86_64_core_cache_size_half (%rip), %r11
+	movq	__x86_64_data_cache_size_half(%rip), %r11
 	cmpq	%rdx, %r11		/* calculate the smaller of */
 	cmovaq	%rdx, %r11		/* remaining bytes and 1/2 L1 */
 #endif
@@ -282,7 +282,7 @@ L(fastskip):
 
 	movq	%rdi, %rax
 #else
-	movq	RETVAL (%rsp), %rax
+	movq	RETVAL(%rsp), %rax
 	jnz	L(1)
 
 	rep
@@ -308,16 +308,16 @@ L(pre):					/* 64-byte with prefetching */
 	shrq	$6, %rcx
 	jz	L(preskip)
 
-	movq	%r14, SAVE0 (%rsp)
+	movq	%r14, SAVE0(%rsp)
 	cfi_rel_offset (%r14, SAVE0)
-	movq	%r13, SAVE1 (%rsp)
+	movq	%r13, SAVE1(%rsp)
 	cfi_rel_offset (%r13, SAVE1)
-	movq	%r12, SAVE2 (%rsp)
+	movq	%r12, SAVE2(%rsp)
 	cfi_rel_offset (%r12, SAVE2)
-	movq	%rbx, SAVE3 (%rsp)
+	movq	%rbx, SAVE3(%rsp)
 	cfi_rel_offset (%rbx, SAVE3)
 
-	cmpl	$0, __x86_64_prefetchw (%rip)
+	cmpl	$0, __x86_64_prefetchw(%rip)
 	jz	L(preloop)		/* check if PREFETCHW OK */
 
 	.p2align 4
@@ -339,45 +339,45 @@ L(prewloop):				/* cache-line in state M */
 	prefetcht0	 0 + 896 (%rsi)
 	prefetcht0	64 + 896 (%rsi)
 
-	movq	%rax,    (%rdi)
-	movq	%rbx,  8 (%rdi)
-	movq	 %r9, 16 (%rdi)
-	movq	%r10, 24 (%rdi)
-	movq	%r11, 32 (%rdi)
-	movq	%r12, 40 (%rdi)
-	movq	%r13, 48 (%rdi)
-	movq	%r14, 56 (%rdi)
+	movq	%rax,   (%rdi)
+	movq	%rbx,  8(%rdi)
+	movq	 %r9, 16(%rdi)
+	movq	%r10, 24(%rdi)
+	movq	%r11, 32(%rdi)
+	movq	%r12, 40(%rdi)
+	movq	%r13, 48(%rdi)
+	movq	%r14, 56(%rdi)
 
-	leaq	64 (%rsi), %rsi
-	leaq	64 (%rdi), %rdi
+	leaq	64(%rsi), %rsi
+	leaq	64(%rdi), %rdi
 
 	jz	L(prebail)
 
 	decq	%rcx
 
-	movq	   (%rsi), %rax
-	movq	 8 (%rsi), %rbx
-	movq	16 (%rsi), %r9
-	movq	24 (%rsi), %r10
-	movq	32 (%rsi), %r11
-	movq	40 (%rsi), %r12
-	movq	48 (%rsi), %r13
-	movq	56 (%rsi), %r14
-
-	movq	%rax,    (%rdi)
-	movq	%rbx,  8 (%rdi)
-	movq	 %r9, 16 (%rdi)
-	movq	%r10, 24 (%rdi)
-	movq	%r11, 32 (%rdi)
-	movq	%r12, 40 (%rdi)
-	movq	%r13, 48 (%rdi)
-	movq	%r14, 56 (%rdi)
-
-	prefetchw	896 - 64 (%rdi)
-	prefetchw	896 -  0 (%rdi)
-
-	leaq	64 (%rsi), %rsi
-	leaq	64 (%rdi), %rdi
+	movq	  (%rsi), %rax
+	movq	 8(%rsi), %rbx
+	movq	16(%rsi), %r9
+	movq	24(%rsi), %r10
+	movq	32(%rsi), %r11
+	movq	40(%rsi), %r12
+	movq	48(%rsi), %r13
+	movq	56(%rsi), %r14
+
+	movq	%rax,   (%rdi)
+	movq	%rbx,  8(%rdi)
+	movq	 %r9, 16(%rdi)
+	movq	%r10, 24(%rdi)
+	movq	%r11, 32(%rdi)
+	movq	%r12, 40(%rdi)
+	movq	%r13, 48(%rdi)
+	movq	%r14, 56(%rdi)
+
+	prefetchw	896 - 64(%rdi)
+	prefetchw	896 -  0(%rdi)
+
+	leaq	64(%rsi), %rsi
+	leaq	64(%rdi), %rdi
 
 	jnz	L(prewloop)
 	jmp	L(prebail)
@@ -389,26 +389,26 @@ L(prewloop):				/* cache-line in state M */
 L(preloop):				/* cache-line in state E */
 	decq	%rcx
 
-	movq	   (%rsi), %rax
-	movq	 8 (%rsi), %rbx
-	movq	16 (%rsi), %r9
-	movq	24 (%rsi), %r10
-	movq	32 (%rsi), %r11
-	movq	40 (%rsi), %r12
-	movq	48 (%rsi), %r13
-	movq	56 (%rsi), %r14
-
-	prefetcht0	896 +  0 (%rsi)
-	prefetcht0	896 + 64 (%rsi)
-
-	movq	%rax,    (%rdi)
-	movq	%rbx,  8 (%rdi)
-	movq	 %r9, 16 (%rdi)
-	movq	%r10, 24 (%rdi)
-	movq	%r11, 32 (%rdi)
-	movq	%r12, 40 (%rdi)
-	movq	%r13, 48 (%rdi)
-	movq	%r14, 56 (%rdi)
+	movq	  (%rsi), %rax
+	movq	 8(%rsi), %rbx
+	movq	16(%rsi), %r9
+	movq	24(%rsi), %r10
+	movq	32(%rsi), %r11
+	movq	40(%rsi), %r12
+	movq	48(%rsi), %r13
+	movq	56(%rsi), %r14
+
+	prefetcht0	896 +  0(%rsi)
+	prefetcht0	896 + 64(%rsi)
+
+	movq	%rax,   (%rdi)
+	movq	%rbx,  8(%rdi)
+	movq	 %r9, 16(%rdi)
+	movq	%r10, 24(%rdi)
+	movq	%r11, 32(%rdi)
+	movq	%r12, 40(%rdi)
+	movq	%r13, 48(%rdi)
+	movq	%r14, 56(%rdi)
 
 	leaq	64 (%rsi), %rsi
 	leaq	64 (%rdi), %rdi
@@ -417,40 +417,40 @@ L(preloop):				/* cache-line in state E */
 
 	decq	%rcx
 
-	movq	   (%rsi), %rax
-	movq	 8 (%rsi), %rbx
-	movq	16 (%rsi), %r9
-	movq	24 (%rsi), %r10
-	movq	32 (%rsi), %r11
-	movq	40 (%rsi), %r12
-	movq	48 (%rsi), %r13
-	movq	56 (%rsi), %r14
-
-	prefetcht0	896 - 64 (%rdi)
-	prefetcht0	896 -  0 (%rdi)
-
-	movq	%rax,    (%rdi)
-	movq	%rbx,  8 (%rdi)
-	movq	 %r9, 16 (%rdi)
-	movq	%r10, 24 (%rdi)
-	movq	%r11, 32 (%rdi)
-	movq	%r12, 40 (%rdi)
-	movq	%r13, 48 (%rdi)
-	movq	%r14, 56 (%rdi)
-
-	leaq	64 (%rsi), %rsi
-	leaq	64 (%rdi), %rdi
+	movq	  (%rsi), %rax
+	movq	 8(%rsi), %rbx
+	movq	16(%rsi), %r9
+	movq	24(%rsi), %r10
+	movq	32(%rsi), %r11
+	movq	40(%rsi), %r12
+	movq	48(%rsi), %r13
+	movq	56(%rsi), %r14
+
+	prefetcht0	896 - 64(%rdi)
+	prefetcht0	896 -  0(%rdi)
+
+	movq	%rax,   (%rdi)
+	movq	%rbx,  8(%rdi)
+	movq	 %r9, 16(%rdi)
+	movq	%r10, 24(%rdi)
+	movq	%r11, 32(%rdi)
+	movq	%r12, 40(%rdi)
+	movq	%r13, 48(%rdi)
+	movq	%r14, 56(%rdi)
+
+	leaq	64(%rsi), %rsi
+	leaq	64(%rdi), %rdi
 
 	jnz	L(preloop)
 
 L(prebail):
-	movq	SAVE3 (%rsp), %rbx
+	movq	SAVE3(%rsp), %rbx
 	cfi_restore (%rbx)
-	movq	SAVE2 (%rsp), %r12
+	movq	SAVE2(%rsp), %r12
 	cfi_restore (%r12)
-	movq	SAVE1 (%rsp), %r13
+	movq	SAVE1(%rsp), %r13
 	cfi_restore (%r13)
-	movq	SAVE0 (%rsp), %r14
+	movq	SAVE0(%rsp), %r14
 	cfi_restore (%r14)
 
 /*       .p2align 4 */
@@ -466,7 +466,7 @@ L(preskip):
 
 	movq	%rdi, %rax
 #else
-	movq	RETVAL (%rsp), %rax
+	movq	RETVAL(%rsp), %rax
 	jnz	L(1)
 
 	rep
@@ -477,7 +477,7 @@ L(preskip):
 
 L(preafter):
 
-/* Loop to handle huge blocks. */
+/* Handle huge blocks. */
 
 L(NTtry):
 
@@ -486,69 +486,69 @@ L(NT):					/* non-temporal 128-byte */
 	shrq	$7, %rcx
 	jz	L(NTskip)
 
-	movq	%r14, SAVE0 (%rsp)
+	movq	%r14, SAVE0(%rsp)
 	cfi_rel_offset (%r14, SAVE0)
-	movq	%r13, SAVE1 (%rsp)
+	movq	%r13, SAVE1(%rsp)
 	cfi_rel_offset (%r13, SAVE1)
-	movq	%r12, SAVE2 (%rsp)
+	movq	%r12, SAVE2(%rsp)
 	cfi_rel_offset (%r12, SAVE2)
 
        .p2align 4
 
 L(NTloop):
-	prefetchnta	768 (%rsi)
-	prefetchnta	832 (%rsi)
+	prefetchnta	768(%rsi)
+	prefetchnta	832(%rsi)
 
 	decq	%rcx
 
-	movq	   (%rsi), %rax
-	movq	 8 (%rsi), %r8
-	movq	16 (%rsi), %r9
-	movq	24 (%rsi), %r10
-	movq	32 (%rsi), %r11
-	movq	40 (%rsi), %r12
-	movq	48 (%rsi), %r13
-	movq	56 (%rsi), %r14
-
-	movntiq	%rax,    (%rdi)
-	movntiq	 %r8,  8 (%rdi)
-	movntiq	 %r9, 16 (%rdi)
-	movntiq	%r10, 24 (%rdi)
-	movntiq	%r11, 32 (%rdi)
-	movntiq	%r12, 40 (%rdi)
-	movntiq	%r13, 48 (%rdi)
-	movntiq	%r14, 56 (%rdi)
-
-	movq	 64 (%rsi), %rax
-	movq	 72 (%rsi), %r8
-	movq	 80 (%rsi), %r9
-	movq	 88 (%rsi), %r10
-	movq	 96 (%rsi), %r11
-	movq	104 (%rsi), %r12
-	movq	112 (%rsi), %r13
-	movq	120 (%rsi), %r14
-
-	movntiq	%rax,  64 (%rdi)
-	movntiq	 %r8,  72 (%rdi)
-	movntiq	 %r9,  80 (%rdi)
-	movntiq	%r10,  88 (%rdi)
-	movntiq	%r11,  96 (%rdi)
-	movntiq	%r12, 104 (%rdi)
-	movntiq	%r13, 112 (%rdi)
-	movntiq	%r14, 120 (%rdi)
-
-	leaq	128 (%rsi), %rsi
-	leaq	128 (%rdi), %rdi
+	movq	  (%rsi), %rax
+	movq	 8(%rsi), %r8
+	movq	16(%rsi), %r9
+	movq	24(%rsi), %r10
+	movq	32(%rsi), %r11
+	movq	40(%rsi), %r12
+	movq	48(%rsi), %r13
+	movq	56(%rsi), %r14
+
+	movntiq	%rax,   (%rdi)
+	movntiq	 %r8,  8(%rdi)
+	movntiq	 %r9, 16(%rdi)
+	movntiq	%r10, 24(%rdi)
+	movntiq	%r11, 32(%rdi)
+	movntiq	%r12, 40(%rdi)
+	movntiq	%r13, 48(%rdi)
+	movntiq	%r14, 56(%rdi)
+
+	movq	 64(%rsi), %rax
+	movq	 72(%rsi), %r8
+	movq	 80(%rsi), %r9
+	movq	 88(%rsi), %r10
+	movq	 96(%rsi), %r11
+	movq	104(%rsi), %r12
+	movq	112(%rsi), %r13
+	movq	120(%rsi), %r14
+
+	movntiq	%rax,  64(%rdi)
+	movntiq	 %r8,  72(%rdi)
+	movntiq	 %r9,  80(%rdi)
+	movntiq	%r10,  88(%rdi)
+	movntiq	%r11,  96(%rdi)
+	movntiq	%r12, 104(%rdi)
+	movntiq	%r13, 112(%rdi)
+	movntiq	%r14, 120(%rdi)
+
+	leaq	128(%rsi), %rsi
+	leaq	128(%rdi), %rdi
 
 	jnz	L(NTloop)
 
 	sfence				/* serialize memory stores */
 
-	movq	SAVE2 (%rsp), %r12
+	movq	SAVE2(%rsp), %r12
 	cfi_restore (%r12)
-	movq	SAVE1 (%rsp), %r13
+	movq	SAVE1(%rsp), %r13
 	cfi_restore (%r13)
-	movq	SAVE0 (%rsp), %r14
+	movq	SAVE0(%rsp), %r14
 	cfi_restore (%r14)
 
 L(NTskip):
@@ -558,7 +558,7 @@ L(NTskip):
 
 	movq	%rdi, %rax
 #else
-	movq	RETVAL (%rsp), %rax
+	movq	RETVAL(%rsp), %rax
 	jnz	L(1)
 
 	rep
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 4afbc4cac4..907bb25580 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -43,7 +43,8 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
 	    isoc99_swscanf isoc99_vswscanf
 
 tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
-	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2
+	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
+	 wcsatcliff
 
 include ../Rules
 
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
index e1b7c13023..0c940d7221 100644
--- a/wcsmbs/bits/wchar2.h
+++ b/wcsmbs/bits/wchar2.h
@@ -29,13 +29,27 @@ extern wchar_t *__REDIRECT_NTH (__wmemcpy_alias,
 				(wchar_t *__restrict __s1,
 				 __const wchar_t *__restrict __s2, size_t __n),
 				wmemcpy);
+extern wchar_t *__REDIRECT_NTH (__wmemcpy_chk_warn,
+				(wchar_t *__restrict __s1,
+				 __const wchar_t *__restrict __s2, size_t __n,
+				 size_t __ns1), __wmemcpy_chk)
+     __warnattr ("wmemcpy called with length bigger than size of destination "
+		 "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (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));
+    {
+      if (!__builtin_constant_p (__n))
+	return __wmemcpy_chk (__s1, __s2, __n,
+			      __bos0 (__s1) / sizeof (wchar_t));
+
+      if (__n > __bos0 (__s1) / sizeof (wchar_t))
+	return __wmemcpy_chk_warn (__s1, __s2, __n,
+				   __bos0 (__s1) / sizeof (wchar_t));
+    }
   return __wmemcpy_alias (__s1, __s2, __n);
 }
 
@@ -45,13 +59,27 @@ extern wchar_t *__wmemmove_chk (wchar_t *__s1, __const wchar_t *__s2,
 extern wchar_t *__REDIRECT_NTH (__wmemmove_alias, (wchar_t *__s1,
 						   __const wchar_t *__s2,
 						   size_t __n), wmemmove);
+extern wchar_t *__REDIRECT_NTH (__wmemmove_chk_warn,
+				(wchar_t *__restrict __s1,
+				 __const wchar_t *__restrict __s2, size_t __n,
+				 size_t __ns1), __wmemmove_chk)
+     __warnattr ("wmemmove called with length bigger than size of destination "
+		 "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (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));
+    {
+      if (!__builtin_constant_p (__n))
+	return __wmemmove_chk (__s1, __s2, __n,
+			       __bos0 (__s1) / sizeof (wchar_t));
+
+      if (__n > __bos0 (__s1) / sizeof (wchar_t))
+	return __wmemmove_chk_warn (__s1, __s2, __n,
+				    __bos0 (__s1) / sizeof (wchar_t));
+    }
   return __wmemmove_alias (__s1, __s2, __n);
 }
 
@@ -64,13 +92,27 @@ extern wchar_t *__REDIRECT_NTH (__wmempcpy_alias,
 				(wchar_t *__restrict __s1,
 				 __const wchar_t *__restrict __s2,
 				 size_t __n), wmempcpy);
+extern wchar_t *__REDIRECT_NTH (__wmempcpy_chk_warn,
+				(wchar_t *__restrict __s1,
+				 __const wchar_t *__restrict __s2, size_t __n,
+				 size_t __ns1), __wmempcpy_chk)
+     __warnattr ("wmempcpy called with length bigger than size of destination "
+		 "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (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));
+    {
+      if (!__builtin_constant_p (__n))
+	return __wmempcpy_chk (__s1, __s2, __n,
+			       __bos0 (__s1) / sizeof (wchar_t));
+
+      if (__n > __bos0 (__s1) / sizeof (wchar_t))
+	return __wmempcpy_chk_warn (__s1, __s2, __n,
+				    __bos0 (__s1) / sizeof (wchar_t));
+    }
   return __wmempcpy_alias (__s1, __s2, __n);
 }
 #endif
@@ -80,12 +122,24 @@ extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
 			       size_t __ns) __THROW;
 extern wchar_t *__REDIRECT_NTH (__wmemset_alias, (wchar_t *__s, wchar_t __c,
 						  size_t __n), wmemset);
+extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn,
+				(wchar_t *__s, wchar_t __c, size_t __n,
+				 size_t __ns), __wmemset_chk)
+     __warnattr ("wmemset called with length bigger than size of destination "
+		 "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (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));
+    {
+      if (!__builtin_constant_p (__n))
+	return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t));
+
+      if (__n > __bos0 (__s) / sizeof (wchar_t))
+	return __wmemset_chk_warn (__s, __c, __n,
+				   __bos0 (__s) / sizeof (wchar_t));
+    }
   return __wmemset_alias (__s, __c, __n);
 }
 
@@ -128,14 +182,25 @@ extern wchar_t *__REDIRECT_NTH (__wcsncpy_alias,
 				(wchar_t *__restrict __dest,
 				 __const wchar_t *__restrict __src,
 				 size_t __n), wcsncpy);
+extern wchar_t *__REDIRECT_NTH (__wcsncpy_chk_warn,
+				(wchar_t *__restrict __dest,
+				 __const wchar_t *__restrict __src,
+				 size_t __n, size_t __destlen), __wcsncpy_chk)
+     __warnattr ("wcsncpy called with length bigger than size of destination "
+		 "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (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));
+  if (__bos (__dest) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n))
+	return __wcsncpy_chk (__dest, __src, __n,
+			      __bos (__dest) / sizeof (wchar_t));
+      if (__n > __bos (__dest) / sizeof (wchar_t))
+	return __wcsncpy_chk_warn (__dest, __src, __n,
+				   __bos (__dest) / sizeof (wchar_t));
+    }
   return __wcsncpy_alias (__dest, __src, __n);
 }
 
@@ -147,14 +212,25 @@ extern wchar_t *__REDIRECT_NTH (__wcpncpy_alias,
 				(wchar_t *__restrict __dest,
 				 __const wchar_t *__restrict __src,
 				 size_t __n), wcpncpy);
+extern wchar_t *__REDIRECT_NTH (__wcpncpy_chk_warn,
+				(wchar_t *__restrict __dest,
+				 __const wchar_t *__restrict __src,
+				 size_t __n, size_t __destlen), __wcpncpy_chk)
+     __warnattr ("wcpncpy called with length bigger than size of destination "
+		 "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (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));
+  if (__bos (__dest) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n))
+	return __wcpncpy_chk (__dest, __src, __n,
+			      __bos (__dest) / sizeof (wchar_t));
+      if (__n > __bos (__dest) / sizeof (wchar_t))
+	return __wcpncpy_chk_warn (__dest, __src, __n,
+				   __bos (__dest) / sizeof (wchar_t));
+    }
   return __wcpncpy_alias (__dest, __src, __n);
 }
 
@@ -209,7 +285,8 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
 		 __const wchar_t *__restrict __fmt, ...))
 {
   if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
-    return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s),
+    return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+			   __bos (__s) / sizeof (wchar_t),
 			   __fmt, __va_arg_pack ());
   return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
 }
@@ -217,7 +294,8 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
 /* XXX We might want to have support in gcc for swprintf.  */
 # define swprintf(s, n, ...) \
   (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1			      \
-   ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), __VA_ARGS__)   \
+   ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1,			      \
+		     __bos (s) / sizeof (wchar_t), __VA_ARGS__)		      \
    : swprintf (s, n, __VA_ARGS__))
 #endif
 
@@ -237,8 +315,8 @@ __NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
 		  __const wchar_t *__restrict __fmt, __gnuc_va_list __ap))
 {
   if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
-    return __vswprintf_chk (__s, __n,  __USE_FORTIFY_LEVEL - 1, __bos (__s),
-			    __fmt, __ap);
+    return __vswprintf_chk (__s, __n,  __USE_FORTIFY_LEVEL - 1,
+			    __bos (__s) / sizeof (wchar_t), __fmt, __ap);
   return __vswprintf_alias (__s, __n, __fmt, __ap);
 }
 
@@ -295,13 +373,25 @@ extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
 extern wchar_t *__REDIRECT (__fgetws_alias,
 			    (wchar_t *__restrict __s, int __n,
 			     __FILE *__restrict __stream), fgetws) __wur;
+extern wchar_t *__REDIRECT (__fgetws_chk_warn,
+			    (wchar_t *__restrict __s, size_t __size, int __n,
+			     __FILE *__restrict __stream), __fgetws_chk)
+     __wur __warnattr ("fgetws called with bigger size than length "
+		       "of destination buffer");
 
 __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);
+  if (__bos (__s) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n) || __n <= 0)
+	return __fgetws_chk (__s, __bos (__s) / sizeof (wchar_t),
+			     __n, __stream);
+
+      if ((size_t) __n > __bos (__s) / sizeof (wchar_t))
+	return __fgetws_chk_warn (__s, __bos (__s) / sizeof (wchar_t),
+				  __n, __stream);
+    }
   return __fgetws_alias (__s, __n, __stream);
 }
 
@@ -313,13 +403,26 @@ extern wchar_t *__REDIRECT (__fgetws_unlocked_alias,
 			    (wchar_t *__restrict __s, int __n,
 			     __FILE *__restrict __stream), fgetws_unlocked)
   __wur;
+extern wchar_t *__REDIRECT (__fgetws_unlocked_chk_warn,
+			    (wchar_t *__restrict __s, size_t __size, int __n,
+			     __FILE *__restrict __stream),
+			    __fgetws_unlocked_chk)
+     __wur __warnattr ("fgetws_unlocked called with bigger size than length "
+		       "of destination buffer");
 
 __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);
+  if (__bos (__s) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n) || __n <= 0)
+	return __fgetws_unlocked_chk (__s, __bos (__s) / sizeof (wchar_t),
+				      __n, __stream);
+
+      if ((size_t) __n > __bos (__s) / sizeof (wchar_t))
+	return __fgetws_unlocked_chk_warn (__s, __bos (__s) / sizeof (wchar_t),
+					   __n, __stream);
+    }
   return __fgetws_unlocked_alias (__s, __n, __stream);
 }
 #endif
@@ -356,16 +459,28 @@ extern size_t __REDIRECT_NTH (__mbsrtowcs_alias,
 			       __const char **__restrict __src,
 			       size_t __len, mbstate_t *__restrict __ps),
 			      mbsrtowcs);
+extern size_t __REDIRECT_NTH (__mbsrtowcs_chk_warn,
+			      (wchar_t *__restrict __dst,
+			       __const char **__restrict __src,
+			       size_t __len, mbstate_t *__restrict __ps,
+			       size_t __dstlen), __mbsrtowcs_chk)
+     __warnattr ("mbsrtowcs called with dst buffer smaller than len "
+		 "* sizeof (wchar_t)");
 
 __extern_always_inline size_t
 __NTH (mbsrtowcs (wchar_t *__restrict __dst, __const char **__restrict __src,
 		  size_t __len, mbstate_t *__restrict __ps))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len)
-	  || __len > __bos (__dst) / sizeof (wchar_t)))
-    return __mbsrtowcs_chk (__dst, __src, __len, __ps,
-			    __bos (__dst) / sizeof (wchar_t));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __mbsrtowcs_chk (__dst, __src, __len, __ps,
+				__bos (__dst) / sizeof (wchar_t));
+
+      if (__len > __bos (__dst) / sizeof (wchar_t))
+	return __mbsrtowcs_chk_warn (__dst, __src, __len, __ps,
+				     __bos (__dst) / sizeof (wchar_t));
+    }
   return __mbsrtowcs_alias (__dst, __src, __len, __ps);
 }
 
@@ -379,14 +494,25 @@ extern size_t __REDIRECT_NTH (__wcsrtombs_alias,
 			       __const wchar_t **__restrict __src,
 			       size_t __len, mbstate_t *__restrict __ps),
 			      wcsrtombs);
+extern size_t __REDIRECT_NTH (__wcsrtombs_chk_warn,
+			      (char *__restrict __dst,
+			       __const wchar_t **__restrict __src,
+			       size_t __len, mbstate_t *__restrict __ps,
+			       size_t __dstlen), __wcsrtombs_chk)
+    __warnattr ("wcsrtombs called with dst buffer smaller than len");
 
 __extern_always_inline size_t
 __NTH (wcsrtombs (char *__restrict __dst, __const wchar_t **__restrict __src,
 		  size_t __len, mbstate_t *__restrict __ps))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len) || __len > __bos (__dst)))
-    return __wcsrtombs_chk (__dst, __src, __len, __ps, __bos (__dst));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __wcsrtombs_chk (__dst, __src, __len, __ps, __bos (__dst));
+
+      if (__len > __bos (__dst))
+	return __wcsrtombs_chk_warn (__dst, __src, __len, __ps, __bos (__dst));
+    }
   return __wcsrtombs_alias (__dst, __src, __len, __ps);
 }
 
@@ -401,16 +527,28 @@ extern size_t __REDIRECT_NTH (__mbsnrtowcs_alias,
 			       __const char **__restrict __src, size_t __nmc,
 			       size_t __len, mbstate_t *__restrict __ps),
 			      mbsnrtowcs);
+extern size_t __REDIRECT_NTH (__mbsnrtowcs_chk_warn,
+			      (wchar_t *__restrict __dst,
+			       __const char **__restrict __src, size_t __nmc,
+			       size_t __len, mbstate_t *__restrict __ps,
+			       size_t __dstlen), __mbsnrtowcs_chk)
+     __warnattr ("mbsnrtowcs called with dst buffer smaller than len "
+		 "* sizeof (wchar_t)");
 
 __extern_always_inline size_t
 __NTH (mbsnrtowcs (wchar_t *__restrict __dst, __const char **__restrict __src,
 		   size_t __nmc, size_t __len, mbstate_t *__restrict __ps))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len)
-	  || __len > __bos (__dst) / sizeof (wchar_t)))
-    return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps,
-			     __bos (__dst) / sizeof (wchar_t));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps,
+				 __bos (__dst) / sizeof (wchar_t));
+
+      if (__len > __bos (__dst) / sizeof (wchar_t))
+	return __mbsnrtowcs_chk_warn (__dst, __src, __nmc, __len, __ps,
+				      __bos (__dst) / sizeof (wchar_t));
+    }
   return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps);
 }
 
@@ -425,14 +563,28 @@ extern size_t __REDIRECT_NTH (__wcsnrtombs_alias,
 			       __const wchar_t **__restrict __src,
 			       size_t __nwc, size_t __len,
 			       mbstate_t *__restrict __ps), wcsnrtombs);
+extern size_t __REDIRECT_NTH (__wcsnrtombs_chk_warn,
+			      (char *__restrict __dst,
+			       __const wchar_t **__restrict __src,
+			       size_t __nwc, size_t __len,
+			       mbstate_t *__restrict __ps,
+			       size_t __dstlen), __wcsnrtombs_chk)
+     __warnattr ("wcsnrtombs called with dst buffer smaller than len");
 
 __extern_always_inline size_t
 __NTH (wcsnrtombs (char *__restrict __dst, __const wchar_t **__restrict __src,
 		   size_t __nwc, size_t __len, mbstate_t *__restrict __ps))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len) || __len > __bos (__dst)))
-    return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps, __bos (__dst));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps,
+				 __bos (__dst));
+
+      if (__len > __bos (__dst))
+	return __wcsnrtombs_chk_warn (__dst, __src, __nwc, __len, __ps,
+				      __bos (__dst));
+    }
   return __wcsnrtombs_alias (__dst, __src, __nwc, __len, __ps);
 }
 #endif
diff --git a/wcsmbs/wcsatcliff.c b/wcsmbs/wcsatcliff.c
new file mode 100644
index 0000000000..22db60763f
--- /dev/null
+++ b/wcsmbs/wcsatcliff.c
@@ -0,0 +1,20 @@
+#include <wchar.h>
+
+#define WCSTEST 1
+#define L(c) L##c
+#define CHAR wchar_t
+#define MEMSET wmemset
+#define STRLEN wcslen
+#define STRNLEN wcsnlen
+#define STRCHR wcschr
+#define STRRCHR wcsrchr
+#define STRCPY wcscpy
+#define STRNCPY wcsncpy
+#define MEMCMP wmemcmp
+#define STPCPY wcpcpy
+#define STPNCPY wcpncpy
+#define MEMCPY wmemcpy
+#define MEMPCPY wmempcpy
+
+
+#include "../string/stratcliff.c"
diff --git a/wcsmbs/wcsnlen.c b/wcsmbs/wcsnlen.c
index 3cfbccad91..94abf1e574 100644
--- a/wcsmbs/wcsnlen.c
+++ b/wcsmbs/wcsnlen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -28,13 +28,16 @@ __wcsnlen (s, maxlen)
 {
   size_t len = 0;
 
-  while (s[len] != L'\0' && maxlen > 0)
+  while (maxlen > 0 && s[len] != L'\0')
     {
-      if (s[++len] == L'\0' || --maxlen == 0)
+      ++len;
+      if (--maxlen == 0 || s[len] == L'\0')
 	return len;
-      if (s[++len] == L'\0' || --maxlen == 0)
+      ++len;
+      if (--maxlen == 0 || s[len] == L'\0')
 	return len;
-      if (s[++len] == L'\0' || --maxlen == 0)
+      ++len;
+      if (--maxlen == 0 || s[len] == L'\0')
 	return len;
       ++len;
       --maxlen;