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