[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r1383 - in /trunk: libc/ libc/csu/ libc/elf/ libc/iconvdata/ libc/iconvdata/testdata/ libc/include/ libc/locale/ libc/locale...
- To: commits@xxxxxxxxxx
- Subject: [commits] r1383 - in /trunk: libc/ libc/csu/ libc/elf/ libc/iconvdata/ libc/iconvdata/testdata/ libc/include/ libc/locale/ libc/locale...
- From: joseph@xxxxxxxxxx
- Date: Mon, 05 Feb 2007 17:59:45 -0000
Author: joseph
Date: Mon Feb 5 09:59:45 2007
New Revision: 1383
Log:
Merge changes between r1192 and r1382 from /fsf/trunk.
Added:
trunk/libc/iconvdata/brf.c
- copied unchanged from r1382, fsf/trunk/libc/iconvdata/brf.c
trunk/libc/iconvdata/testdata/BRF
- copied unchanged from r1382, fsf/trunk/libc/iconvdata/testdata/BRF
trunk/libc/iconvdata/testdata/BRF..UTF8
- copied unchanged from r1382, fsf/trunk/libc/iconvdata/testdata/BRF..UTF8
trunk/libc/localedata/charmaps/BRF
- copied unchanged from r1382, fsf/trunk/libc/localedata/charmaps/BRF
trunk/libc/stdio-common/bug17.c
- copied unchanged from r1382, fsf/trunk/libc/stdio-common/bug17.c
trunk/libc/string/strerror_l.c
- copied unchanged from r1382, fsf/trunk/libc/string/strerror_l.c
trunk/ports/sysdeps/powerpc/nofpu/fenv_libc.h
- copied unchanged from r1382, fsf/trunk/ports/sysdeps/powerpc/nofpu/fenv_libc.h
trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/msgctl.c
- copied unchanged from r1382, fsf/trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/msgctl.c
trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/semctl.c
- copied unchanged from r1382, fsf/trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/semctl.c
trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/shmctl.c
- copied unchanged from r1382, fsf/trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/shmctl.c
Removed:
trunk/libc/soft-fp/fenv_libc.h
Modified:
trunk/libc/ChangeLog
trunk/libc/NEWS
trunk/libc/csu/libc-start.c
trunk/libc/elf/dl-lookup.c
trunk/libc/elf/dl-minimal.c
trunk/libc/elf/dl-runtime.c
trunk/libc/elf/dl-sym.c
trunk/libc/iconvdata/Makefile
trunk/libc/iconvdata/TESTS
trunk/libc/iconvdata/gconv-modules
trunk/libc/iconvdata/tst-tables.sh
trunk/libc/include/locale.h
trunk/libc/locale/uselocale.c
trunk/libc/localedata/ChangeLog
trunk/libc/math/basic-test.c
trunk/libc/math/test-misc.c
trunk/libc/misc/hsearch_r.c
trunk/libc/nptl/ChangeLog
trunk/libc/nptl/forward.c
trunk/libc/nptl/pthread_join.c
trunk/libc/nptl/sysdeps/pthread/bits/libc-lock.h
trunk/libc/nptl/sysdeps/pthread/pthread-functions.h
trunk/libc/nptl/sysdeps/pthread/setxid.h
trunk/libc/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c
trunk/libc/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
trunk/libc/nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c
trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
trunk/libc/nptl/tst-initializers1.c
trunk/libc/nscd/cache.c
trunk/libc/nscd/connections.c
trunk/libc/nscd/nscd-client.h
trunk/libc/nscd/nscd_getai.c
trunk/libc/nscd/nscd_getgr_r.c
trunk/libc/nscd/nscd_gethst_r.c
trunk/libc/nscd/nscd_getpw_r.c
trunk/libc/nscd/nscd_getserv_r.c
trunk/libc/nscd/nscd_helper.c
trunk/libc/nscd/nscd_initgroups.c
trunk/libc/po/sv.po
trunk/libc/scripts/gen-as-const.awk
trunk/libc/soft-fp/op-common.h
trunk/libc/stdio-common/Makefile
trunk/libc/stdio-common/_itoa.c
trunk/libc/stdio-common/_itoa.h
trunk/libc/stdio-common/_itowa.c
trunk/libc/string/Makefile
trunk/libc/string/Versions
trunk/libc/string/string.h
trunk/libc/sysdeps/generic/ldsodefs.h
trunk/libc/sysdeps/i386/bits/byteswap.h
trunk/libc/sysdeps/i386/dl-trampoline.S
trunk/libc/sysdeps/ieee754/ldbl-128ibm/s_ceill.c
trunk/libc/sysdeps/ieee754/ldbl-128ibm/s_copysignl.c
trunk/libc/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c
trunk/libc/sysdeps/ieee754/ldbl-128ibm/s_floorl.c
trunk/libc/sysdeps/ieee754/ldbl-128ibm/s_roundl.c
trunk/libc/sysdeps/ieee754/ldbl-128ibm/s_truncl.c
trunk/libc/sysdeps/posix/system.c
trunk/libc/sysdeps/unix/sysv/linux/fatal-prepare.h
trunk/libc/sysdeps/unix/sysv/linux/getdents.c
trunk/libc/sysdeps/unix/sysv/linux/i386/sysdep.h
trunk/libc/sysdeps/unix/sysv/linux/sys/personality.h
trunk/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h
trunk/libc/sysdeps/x86_64/bits/byteswap.h
trunk/libc/wcsmbs/wchar.h
trunk/ports/ChangeLog.arm
trunk/ports/ChangeLog.hppa
trunk/ports/ChangeLog.mips
trunk/ports/ChangeLog.powerpc
trunk/ports/sysdeps/hppa/dl-trampoline.S
trunk/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
trunk/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
trunk/ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h
trunk/ports/sysdeps/unix/sysv/linux/mips/mips64/syscalls.list
Modified: trunk/libc/ChangeLog
==============================================================================
--- trunk/libc/ChangeLog (original)
+++ trunk/libc/ChangeLog Mon Feb 5 09:59:45 2007
@@ -1,3 +1,222 @@
+2007-02-03 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * po/sv.po: Update from translation team.
+
+2007-02-02 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * nscd/nscd_helper.c (open_socket): Minor size optimization.
+
+2007-02-02 Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * include/locale.h (__uselocale): Add libc_hidden_proto.
+ * locale/uselocale.c (__uselocale): Add libc_hidden_def.
+
+ * nscd/nscd_helper.c (open_socket): Use __gettimeofday instead of
+ gettimeofday.
+
+2007-02-01 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/unix/sysv/linux/i386/sysdep.h (PTR_MANGLE): Roll value before
+ returning.
+ (PTR_DEMANGLE): Real definition now that it's not the same as
+ PRT_MANGLE anymore.
+ * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise.
+
+ * string/strerror_l.c: New file.
+ * string/Makefile (routines): Add strerror_l.
+ * string/string.h: Declare strerror_l.
+ * string/Versions: Export strerror_l for GLIBC_2.6.
+
+2007-01-31 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * nscd/nscd_helper.c (open_socket): Now takes request type and key
+ as parameter. Construct request record. Try sending request
+ before the first poll use, it usually succeeds. Adjust all
+ callers.
+ * nscd/nscd-client.h: Define MAXKEYLEN.
+ * nscd/connections.c (nscd_run): Don't define MAXKEYLEN here.
+
+2007-01-31 Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * nscd/nscd-client.h (__nscd_cache_search): Remove const qualifier
+ from return value.
+ * nscd/nscd_helper.c: Include string.h.
+ (__nscd_cache_search): Remove const qualifier from return value.
+ On strict alignment architectures check hash entry and data head
+ alignment.
+ * nscd/nscd_getpw_r.c (nscd_getpw_r): Don't crash or fail because
+ mmapped data during GC cycle contains garbage. If
+ __nscd_drop_map_ref fails, decrement mapped->counter when returning
+ error or if retrying with NO_MAPPING, only __nscd_unmap if counter
+ dropped to 0.
+ * nscd/nscd_getgr_r.c (nscd_getgr_r): Likewise.
+ * nscd/nscd_initgroups.c (__nscd_getgrouplist): Likewise.
+ * nscd/nscd_gethst_r.c (nscd_gethst_r): Likewise.
+ * nscd/nscd_getai.c (__nscd_getai): Likewise.
+ * nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise.
+
+2007-01-30 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * misc/hsearch_r.c (hdestroy_r): Remove unnecessary test.
+
+2007-01-26 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/i386/dl-trampoline.S (_dl_runtime_profile): Use register
+ names not numbers in cfi_*.
+
+2007-01-26 Andreas Jaeger <aj@xxxxxxx>
+
+ * sysdeps/unix/sysv/linux/sys/personality.h (ADDR_NO_RANDOMIZE,
+ ADDR_LIMIT_3GB, PER_LINUX_32BIT, PER_LINUX32_3GB): Add.
+ Correct values of PER_HPUX and PER_OSF4.
+
+2007-01-24 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * elf/dl-minimal.c: Undefine _itoa first.
+ * stdio-common/_itoa.h: Define _itoa and _fitoa for 64-bit platforms.
+ * malloc/mtrace.c: Revert last change.
+ * posix/wordexp.c: Likewise.
+
+2007-01-24 Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * sysdeps/i386/bits/byteswap.h (__bswap_32): Add __nocona__, __core2__
+ and __geode__ to the list of i486+ CPUs.
+ * sysdeps/x86_64/bits/byteswap.h (__bswap_32): Likewise.
+
+2007-01-23 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * stdio-common/_itoa.c: Include <limits.h>.
+ * stdio-common/_itowa.c: Likewise.
+
+2007-01-22 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * stdio-common/_itowa.c: Don't compile _itowa for 64-bit
+ platforms.
+ * stdio-common/_itoa.c: Don't compile in _itoa and _fitoa for
+ 64-bit platforms.
+ * malloc/mtrace.c (tr_where): Use _fitoa_word instead of _fitoa if
+ possible.
+ * posix/wordexp.c (parse_arith): Use _itoa_word instead of _itoa
+ if possible.
+
+ [BZ #3902]
+ * stdio-common/_itoa.c (_itoa): Make sure at least a zero is emitted.
+ * stdio-common/Makefile (tests): Add bug17.
+ * stdio-common/bug17.c: New file.
+
+2007-01-19 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * iconvdata/brf.c: New file.
+ * iconvdata/testdata/BRF: New file.
+ * iconvdata/testdata/BRF..UTF8: New file.
+ Contributed by Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>.
+ * iconvdata/Makefile: Add rules to build BRF.
+ * iconvdata/TESTS: Add BRF entry.
+ * iconvdata/gconv-modules: Likewise.
+ * iconvdata/tst-tables.sh: Likewise.
+
+2007-01-18 Anton Nikishaev <anton.nik@xxxxxxxxx>
+
+ * wcsmbs/wchar.h (wcstoll): Fix comment, function returns value of
+ type `long long int', not `long int'.
+ (wcstoq): Likewise.
+
+2007-01-18 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * scripts/gen-as-const.awk: Add cast to long to avoid int promotion
+ of values on 64-bit platforms which are too large.
+
+2007-01-12 Steven Munroe <sjmunroe@xxxxxxxxxx>
+ Joe Kerian <jkerian@xxxxxxxxxxxxx>
+
+ [BZ #2749]
+ * sysdeps/ieee754/ldbl-128ibm/s_copysignl.c: Include
+ <math_ldbl_opt.h>. Remove weak_alias. Use long_double_symbol macro.
+ (__copysignl): Use signbit() for comparison.
+ * sysdeps/ieee754/ldbl-128ibm/s_fabsl.c (__fabsl): Correct parms for
+ SET_LDOUBLE_WORDS64.
+
+ [BZ #2423, #2749]
+ * sysdeps/ieee754/ldbl-128ibm/s_ceill.c: Don't include <fenv_libc.h>.
+ (__ceill): Remove calls to fegetround(), fesetround().
+ * sysdeps/ieee754/ldbl-128ibm/s_floorl.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/s_roundl.c: Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/s_truncl.c: Likewise.
+
+2007-01-17 Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * nscd/nscd_getserv_r.c (nscd_getserv_r): Fix pastos.
+
+ * sysdeps/unix/sysv/linux/getdents.c (offsetof): Remove.
+
+2007-01-17 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/unix/sysv/linux/fatal-prepare.h: Use PTHFCT_CALL to
+ demangle pointer.
+ * csu/libc-start.c: Likewise.
+
+2007-01-16 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/posix/system.c: Remove NO_WAITPID support, it cannot
+ really work anyway.
+
+2007-01-15 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * nscd/connections.c (servinfo): Renamed to reqinfo. Change all
+ users.
+ (handle_request): Remove unnecessary tests.
+
+ * nscd/cache.c (cache_add): Record the failure to add to the cache.
+
+2007-01-15 Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * soft-fp/op-common.h (FP_TRUNC): When truncating a NaN, clear
+ workbits in semi-raw fraction.
+
+ * math/test-misc.c: Add new tests.
+
+2007-01-14 Steven Munroe <sjmunroe@xxxxxxxxxx>
+
+ * math/basic-test.c: Include test-skeleton.c.
+ (TEST_TRUNC): Define.
+ (truncdfsf_test, trunctfsf_test, trunctfdf_test): New.
+ (main): Rename to ...
+ (do_test): ...this. Run new tests.
+ (TEST_FUNCTION): Define.
+
+2006-10-05 Steven Munroe <sjmunroe@xxxxxxxxxx>
+ Joe Kerian <jkerian@xxxxxxxxxxxxx>
+
+ [BZ #2749]
+ * soft-fp/op-4.h (__FP_FRAC_SUB_3, __FP_FRAC_SUB_4): Correct borrow
+ handling for high words.
+ * soft-fp/op-common.h (_FP_OVERFLOW_SEMIRAW): Always set inexact
+ and overflow for infinity.
+
+2007-01-15 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * nscd/connections.c (handle_request): Add a __builtin_expect.
+
+ * nscd/connections.c (serv2db): Change type into structure which
+ also says whether this is a request for data. Renamed to
+ servinfo. All users changed.
+ (handle_request): Much simpler test whether we should search the cache.
+
+ * nscd/connections.c (handle_request): Fix thinko in selinux test
+ invocation.
+
+ * sysdeps/generic/ldsodefs.h: Define DL_LOOKUP_SCOPE_LOCK.
+ * elf/dl-lookup.c (add_dependency): If scope map is locked, unlock
+ it before getting dl_load_lock and then relock.
+ (_dl_lookup_symbol_x): Pass flags to add_dependency.
+ When rerunning _dl_lookup_symbol_x, compute symbol_scope again in
+ case we unlocked the scope.
+ * elf/dl-runtime.c (_dl_fixup): Pass DL_LOOKUP_SCOPE_LOCK to
+ _dl_lookup_symbol_x in case we locked the scope.
+ (_dl_profile_fixup): Likewise.
+ * elf/dl-sym.c (do_sym): In flags passed to call_dl_lookup, also
+ set DL_LOOKUP_SCOPE_LOCK.
+
2007-01-13 Ulrich Drepper <drepper@xxxxxxxxxx>
* inet/Makefile: Define CFLAGS-getsrvbynm_r.c and
Modified: trunk/libc/NEWS
==============================================================================
--- trunk/libc/NEWS (original)
+++ trunk/libc/NEWS Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes. 2007-1-13
+GNU C Library NEWS -- history of user-visible changes. 2007-2-1
Copyright (C) 1992-2006, 2007 Free Software Foundation, Inc.
See the end for copying conditions.
@@ -8,6 +8,8 @@
Version 2.6
* New Linux interfaces: epoll_pwait.
+
+* New generic interfaces: strerror_l.
* nscd can now cache the services database. Implemented by Ulrich Drepper.
Modified: trunk/libc/csu/libc-start.c
==============================================================================
--- trunk/libc/csu/libc-start.c (original)
+++ trunk/libc/csu/libc-start.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998-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
@@ -225,7 +225,7 @@
{
/* Remove the thread-local data. */
# ifdef SHARED
- __libc_pthread_functions.ptr__nptl_deallocate_tsd ();
+ PTHFCT_CALL (ptr__nptl_deallocate_tsd, ());
# else
extern void __nptl_deallocate_tsd (void) __attribute ((weak));
__nptl_deallocate_tsd ();
@@ -235,7 +235,8 @@
terminate the entire process. */
result = 0;
# ifdef SHARED
- unsigned int *const ptr = __libc_pthread_functions.ptr_nthreads;
+ unsigned int *ptr = __libc_pthread_functions.ptr_nthreads;
+ PTR_DEMANGLE (ptr);
# else
extern unsigned int __nptl_nthreads __attribute ((weak));
unsigned int *const ptr = &__nptl_nthreads;
Modified: trunk/libc/elf/dl-lookup.c
==============================================================================
--- trunk/libc/elf/dl-lookup.c (original)
+++ trunk/libc/elf/dl-lookup.c Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* Look up a symbol in the loaded objects.
- Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1995-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
@@ -25,6 +25,7 @@
#include <ldsodefs.h>
#include <dl-hash.h>
#include <dl-machine.h>
+#include <sysdep-cancel.h>
#include <bits/libc-lock.h>
#include <tls.h>
@@ -85,7 +86,7 @@
/* Add extra dependency on MAP to UNDEF_MAP. */
static int
internal_function
-add_dependency (struct link_map *undef_map, struct link_map *map)
+add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
{
struct link_map **list;
struct link_map *runp;
@@ -98,8 +99,18 @@
if (undef_map == map)
return 0;
- /* Make sure nobody can unload the object while we are at it. */
- __rtld_lock_lock_recursive (GL(dl_load_lock));
+ /* Make sure nobody can unload the object while we are at it.
+ If we hold a scope lock drop it now to avoid ABBA locking problems. */
+ if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0 && !RTLD_SINGLE_THREAD_P)
+ {
+ __rtld_mrlock_unlock (undef_map->l_scope_lock);
+
+ __rtld_lock_lock_recursive (GL(dl_load_lock));
+
+ __rtld_mrlock_lock (undef_map->l_scope_lock);
+ }
+ else
+ __rtld_lock_lock_recursive (GL(dl_load_lock));
/* Avoid references to objects which cannot be unloaded anyway. */
if (map->l_type != lt_loaded
@@ -226,9 +237,10 @@
bump_num_relocations ();
- /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed if we look
- up a versioned symbol. */
- assert (version == NULL || flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY);
+ /* No other flag than DL_LOOKUP_ADD_DEPENDENCY and DL_LOOKUP_SCOPE_LOCK
+ is allowed if we look up a versioned symbol. */
+ assert (version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY
+ | DL_LOOKUP_SCOPE_LOCK)) == 0);
size_t i = 0;
if (__builtin_expect (skip_map != NULL, 0))
@@ -338,12 +350,13 @@
runtime lookups. */
&& (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
/* Add UNDEF_MAP to the dependencies. */
- && add_dependency (undef_map, current_value.m) < 0)
+ && add_dependency (undef_map, current_value.m, flags) < 0)
/* Something went wrong. Perhaps the object we tried to reference
was just removed. Try finding another definition. */
return _dl_lookup_symbol_x (undef_name, undef_map, ref,
- symbol_scope, version, type_class,
- flags, skip_map);
+ (flags & DL_LOOKUP_SCOPE_LOCK) == 0
+ ? symbol_scope : undef_map->l_scope, version,
+ type_class, flags, skip_map);
/* The object is used. */
current_value.m->l_used = 1;
Modified: trunk/libc/elf/dl-minimal.c
==============================================================================
--- trunk/libc/elf/dl-minimal.c (original)
+++ trunk/libc/elf/dl-minimal.c Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* Minimal replacements for basic facilities used in the dynamic linker.
- Copyright (C) 1995-1998,2000-2002,2004,2005,2006
+ Copyright (C) 1995-1998,2000-2002,2004-2006,2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -283,6 +283,7 @@
}
+#undef _itoa
/* We always use _itoa instead of _itoa_word in ld.so since the former
also has to be present and it is never about speed when these
functions are used. */
Modified: trunk/libc/elf/dl-runtime.c
==============================================================================
--- trunk/libc/elf/dl-runtime.c (original)
+++ trunk/libc/elf/dl-runtime.c Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* On-demand PLT fixup for shared objects.
- Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+ Copyright (C) 1995-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
@@ -93,14 +93,20 @@
version = NULL;
}
+ /* We need to keep the scope around so do some locking. This is
+ not necessary for objects which cannot be unloaded or when
+ we are not using any threads (yet). */
+ int flags = DL_LOOKUP_ADD_DEPENDENCY;
if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P)
- __rtld_mrlock_lock (l->l_scope_lock);
-
- result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
- l->l_scope, version, ELF_RTYPE_CLASS_PLT,
- DL_LOOKUP_ADD_DEPENDENCY, NULL);
-
- if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P)
+ {
+ __rtld_mrlock_lock (l->l_scope_lock);
+ flags |= DL_LOOKUP_SCOPE_LOCK;
+ }
+
+ result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope,
+ version, ELF_RTYPE_CLASS_PLT, flags, NULL);
+
+ if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0)
__rtld_mrlock_unlock (l->l_scope_lock);
/* Currently result contains the base load address (or link map)
@@ -181,15 +187,21 @@
version = NULL;
}
+ /* We need to keep the scope around so do some locking. This is
+ not necessary for objects which cannot be unloaded or when
+ we are not using any threads (yet). */
+ int flags = DL_LOOKUP_ADD_DEPENDENCY;
if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P)
- __rtld_mrlock_lock (l->l_scope_lock);
-
- result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, &defsym,
- l->l_scope, version,
- ELF_RTYPE_CLASS_PLT,
- DL_LOOKUP_ADD_DEPENDENCY, NULL);
-
- if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P)
+ {
+ __rtld_mrlock_lock (l->l_scope_lock);
+ flags |= DL_LOOKUP_SCOPE_LOCK;
+ }
+
+ result = _dl_lookup_symbol_x (strtab + refsym->st_name, l,
+ &defsym, l->l_scope, version,
+ ELF_RTYPE_CLASS_PLT, flags, NULL);
+
+ if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0)
__rtld_mrlock_unlock (l->l_scope_lock);
/* Currently result contains the base load address (or link map)
Modified: trunk/libc/elf/dl-sym.c
==============================================================================
--- trunk/libc/elf/dl-sym.c (original)
+++ trunk/libc/elf/dl-sym.c Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* Look up a symbol in a shared object loaded by `dlopen'.
- Copyright (C) 1999,2000,2001,2002,2004,2006 Free Software Foundation, Inc.
+ Copyright (C) 1999-2002,2004,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
@@ -126,7 +126,7 @@
args.name = name;
args.map = match;
args.vers = vers;
- args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY;
+ args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_SCOPE_LOCK;
args.refp = &ref;
const char *objname;
Modified: trunk/libc/iconvdata/Makefile
==============================================================================
--- trunk/libc/iconvdata/Makefile (original)
+++ trunk/libc/iconvdata/Makefile Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-# Copyright (C) 1997-2004,2005,2006 Free Software Foundation, Inc.
+# Copyright (C) 1997-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
@@ -58,7 +58,7 @@
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
+ IBM1364 IBM1371 IBM1388 IBM1390 IBM1399 ISO_11548-1 MIK BRF
modules.so := $(addsuffix .so, $(modules))
@@ -196,7 +196,8 @@
ibm9030.c ibm9030.h ibm9066.c ibm9066.h ibm9448.c ibm9448.h \
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
+ ibm1390.c ibm1390.h ibm1399.c ibm1399.h iso_11548-1.c mik.c \
+ brf.c
# We build the transformation modules only when we build shared libs.
ifeq (yes,$(build-shared))
@@ -237,7 +238,7 @@
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
+ iso8859-11 ibm866nav pt154 rk1048 mik brf
gen-special-modules := iso8859-7jp
Modified: trunk/libc/iconvdata/TESTS
==============================================================================
--- trunk/libc/iconvdata/TESTS (original)
+++ trunk/libc/iconvdata/TESTS Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
# Available tests for iconv(1) (and therefore iconv(3)) in GNU libc.
-# Copyright (C) 1998-2002, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1998-2002, 2005, 2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 1998.
#
@@ -166,3 +166,4 @@
IBM1399 IBM1399 N UTF8
ISO_11548-1 ISO_11548-1 - UTF8
MIK MIK Y UTF8
+BRF BRF - UTF8
Modified: trunk/libc/iconvdata/gconv-modules
==============================================================================
--- trunk/libc/iconvdata/gconv-modules (original)
+++ trunk/libc/iconvdata/gconv-modules Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
# GNU libc iconv configuration.
-# Copyright (C) 1997-2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1997-2004, 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
@@ -1907,3 +1907,7 @@
# from to module cost
module MIK// INTERNAL MIK 1
module INTERNAL MIK// MIK 1
+
+# from to module cost
+module BRF// INTERNAL BRF 1
+module INTERNAL BRF// BRF 1
Modified: trunk/libc/iconvdata/tst-tables.sh
==============================================================================
--- trunk/libc/iconvdata/tst-tables.sh (original)
+++ trunk/libc/iconvdata/tst-tables.sh Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 2000,2001,2002,2003,2004,2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Bruno Haible <haible@xxxxxxxxxxxxxx>, 2000.
#
@@ -208,6 +208,7 @@
PT154
RK1048
MIK
+ BRF
#
# Multibyte encodings come here
#
Modified: trunk/libc/include/locale.h
==============================================================================
--- trunk/libc/include/locale.h (original)
+++ trunk/libc/include/locale.h Mon Feb 5 09:59:45 2007
@@ -4,6 +4,7 @@
extern __typeof (uselocale) __uselocale;
libc_hidden_proto (setlocale)
+libc_hidden_proto (__uselocale)
/* This has to be changed whenever a new locale is defined. */
#define __LC_LAST 13
Modified: trunk/libc/locale/uselocale.c
==============================================================================
--- trunk/libc/locale/uselocale.c (original)
+++ trunk/libc/locale/uselocale.c Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* uselocale -- fetch and set the current per-thread locale
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 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
@@ -70,4 +70,5 @@
return oldloc == &_nl_global_locale ? LC_GLOBAL_LOCALE : oldloc;
}
+libc_hidden_def (__uselocale)
weak_alias (__uselocale, uselocale)
Modified: trunk/libc/localedata/ChangeLog
==============================================================================
--- trunk/libc/localedata/ChangeLog (original)
+++ trunk/libc/localedata/ChangeLog Mon Feb 5 09:59:45 2007
@@ -1,3 +1,8 @@
+2007-01-19 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * charmaps/BRF: New file.
+ Contributed by Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>.
+
2006-12-05 Jakub Jelinek <jakub@xxxxxxxxxx>
* locales/cs_CZ (LC_TIME): Change d_fmt to %e.%m.%Y from %-d.%-m.%Y.
Modified: trunk/libc/math/basic-test.c
==============================================================================
--- trunk/libc/math/basic-test.c (original)
+++ trunk/libc/math/basic-test.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@xxxxxxx>, 1999.
@@ -44,7 +44,7 @@
\
zero_var = 0.0; \
one_var = 1.0; \
- NaN_var = zero_var/zero_var; \
+ NaN_var = zero_var / zero_var; \
Inf_var = one_var / zero_var; \
\
(void) &zero_var; \
@@ -103,21 +103,51 @@
check (#FLOAT " isinf (-HUGE_VALx) == -1", isinf (x1) == -1); \
}
+#define TEST_TRUNC(NAME, FLOAT, DOUBLE) \
+void \
+NAME (void) \
+{ \
+ volatile DOUBLE Inf_var, NaN_var, zero_var, one_var; \
+ FLOAT x1, x2; \
+ \
+ zero_var = 0.0; \
+ one_var = 1.0; \
+ NaN_var = zero_var / zero_var; \
+ Inf_var = one_var / zero_var; \
+ \
+ (void) &NaN_var; \
+ (void) &Inf_var; \
+ \
+ x1 = (FLOAT) NaN_var; \
+ check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") NaN", isnan (x1) != 0); \
+ x2 = (FLOAT) Inf_var; \
+ check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") Inf", isinf (x2) != 0); \
+}
+
TEST_FUNC (float_test, float, nanf, FLT_EPSILON, HUGE_VALF)
TEST_FUNC (double_test, double, nan, DBL_EPSILON, HUGE_VAL)
+TEST_TRUNC (truncdfsf_test, float, double)
#ifndef NO_LONG_DOUBLE
TEST_FUNC (ldouble_test, long double, nanl, LDBL_EPSILON, HUGE_VALL)
+TEST_TRUNC (trunctfsf_test, float, long double)
+TEST_TRUNC (trunctfdf_test, double, long double)
#endif
int
-main (void)
+do_test (void)
{
float_test ();
double_test ();
+ truncdfsf_test();
#ifndef NO_LONG_DOUBLE
ldouble_test ();
+ trunctfsf_test();
+ trunctfdf_test();
#endif
return errors != 0;
}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Modified: trunk/libc/math/test-misc.c
==============================================================================
--- trunk/libc/math/test-misc.c (original)
+++ trunk/libc/math/test-misc.c Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* Miscellaneous tests which don't fit anywhere else.
- Copyright (C) 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2004, 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
@@ -44,7 +44,6 @@
}
}
-# if __GNUC__ >= 3 || __GNUC_MINOR__ >= 96
{
long double x;
long double m;
@@ -52,17 +51,17 @@
int e;
int i;
-# if LDBL_MANT_DIG == 64
+# if LDBL_MANT_DIG == 64
m = 0xf.fffffffffffffffp-4L;
-# elif LDBL_MANT_DIG == 106
+# elif LDBL_MANT_DIG == 106
/* This has to match the mantissa of LDBL_MAX which actually does have a
missing bit in the middle. */
m = 0x1.fffffffffffff7ffffffffffff8p-1L;
-# elif LDBL_MANT_DIG == 113
+# elif LDBL_MANT_DIG == 113
m = 0x1.ffffffffffffffffffffffffffffp-1L;
-# else
-# error "Please adjust"
-# endif
+# else
+# error "Please adjust"
+# endif
for (i = LDBL_MAX_EXP, x = LDBL_MAX; i >= LDBL_MIN_EXP; --i, x /= 2.0L)
{
@@ -106,9 +105,8 @@
}
}
-# endif
-
-#if 0
+
+# if 0
{
int e;
long double r = frexpl (LDBL_MIN * LDBL_EPSILON, &e);
@@ -126,7 +124,7 @@
result = 1;
}
}
-#endif
+# endif
#endif
{
@@ -1183,5 +1181,59 @@
}
#endif
+ volatile float f1 = FLT_MAX;
+ volatile float f2 = FLT_MAX / 2;
+ (void) &f1;
+ (void) &f2;
+ feclearexcept (FE_ALL_EXCEPT);
+ f2 += f1;
+ int fe = fetestexcept (FE_ALL_EXCEPT);
+ if (fe != (FE_OVERFLOW | FE_INEXACT))
+ {
+ printf ("float overflow test failed: %x\n", fe);
+ result = 1;
+ }
+
+ volatile double d1 = DBL_MAX;
+ volatile double d2 = DBL_MAX / 2;
+ (void) &d1;
+ (void) &d2;
+ feclearexcept (FE_ALL_EXCEPT);
+ d2 += d1;
+ fe = fetestexcept (FE_ALL_EXCEPT);
+ if (fe != (FE_OVERFLOW | FE_INEXACT))
+ {
+ printf ("double overflow test failed: %x\n", fe);
+ result = 1;
+ }
+
+#ifndef NO_LONG_DOUBLE
+ volatile long double ld1 = LDBL_MAX;
+ volatile long double ld2 = LDBL_MAX / 2;
+ (void) &ld1;
+ (void) &ld2;
+ feclearexcept (FE_ALL_EXCEPT);
+ ld2 += ld1;
+ fe = fetestexcept (FE_ALL_EXCEPT);
+ if (fe != (FE_OVERFLOW | FE_INEXACT))
+ {
+ printf ("long double overflow test failed: %x\n", fe);
+ result = 1;
+ }
+#endif
+
+#if !defined NO_LONG_DOUBLE && LDBL_MANT_DIG == 113
+ volatile long double ld3 = 0x1.0000000000010000000100000001p+1;
+ volatile long double ld4 = 0x1.0000000000000000000000000001p+1;
+ (void) &ld3;
+ (void) &ld4;
+ ld3 -= ld4;
+ if (ld3 != 0x1.0p-47)
+ {
+ printf ("long double subtraction test failed %.28La\n", ld3);
+ result = 1;
+ }
+#endif
+
return result;
}
Modified: trunk/libc/misc/hsearch_r.c
==============================================================================
--- trunk/libc/misc/hsearch_r.c (original)
+++ trunk/libc/misc/hsearch_r.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1996,1997,2002,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995-1997,2002,2005,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxxxxxx>, 1993.
@@ -110,9 +110,8 @@
return;
}
- if (htab->table != NULL)
- /* free used memory */
- free (htab->table);
+ /* Free used memory. */
+ free (htab->table);
/* the sign for an existing table is an value != NULL in htable */
htab->table = NULL;
Modified: trunk/libc/nptl/ChangeLog
==============================================================================
--- trunk/libc/nptl/ChangeLog (original)
+++ trunk/libc/nptl/ChangeLog Mon Feb 5 09:59:45 2007
@@ -1,3 +1,26 @@
+2007-01-18 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * tst-initializers1.c: We want to test the initializers as seen
+ outside of libc, so undefined _LIBC.
+
+ * pthread_join.c (cleanup): Avoid warning.
+
+2007-01-17 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+ (__lll_timedwait_tid): Add unwind info.
+
+ * sysdeps/unix/sysv/linux/libc_pthread_init.c: Don't just copy the
+ function table, mangle the pointers.
+ * sysdeps/pthread/pthread-functions.h: Define PTHFCT_CALL.
+ * forward.c: Use PTHFCT_CALL and __libc_pthread_functions_init.
+ * sysdeps/pthread/bits/libc-lock.h: When using __libc_pthread_functions
+ demangle pointers before use.
+ * sysdeps/unix/sysv/linux/s390/jmp-unwind.c: Use PTHFCT_CALL to
+ demangle pointer.
+ * sysdeps/unix/sysv/linux/jmp-unwind.c: Likewise.
+ * sysdeps/pthread/setxid.h: Likewise.
+
2007-01-12 Ulrich Drepper <drepper@xxxxxxxxxx>
* tst-rwlock7.c: Show some more information in case of correct
Modified: trunk/libc/nptl/forward.c
==============================================================================
--- trunk/libc/nptl/forward.c (original)
+++ trunk/libc/nptl/forward.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -29,16 +29,17 @@
/* Pointers to the libc functions. */
struct pthread_functions __libc_pthread_functions attribute_hidden;
+int __libc_pthread_functions_init attribute_hidden;
#define FORWARD2(name, rettype, decl, params, defaction) \
rettype \
name decl \
{ \
- if (__libc_pthread_functions.ptr_##name == NULL) \
+ if (!__libc_pthread_functions_init) \
defaction; \
\
- return __libc_pthread_functions.ptr_##name params; \
+ return PTHFCT_CALL (ptr_##name, params); \
}
#define FORWARD(name, decl, params, defretval) \
Modified: trunk/libc/nptl/pthread_join.c
==============================================================================
--- trunk/libc/nptl/pthread_join.c (original)
+++ trunk/libc/nptl/pthread_join.c Mon Feb 5 09:59:45 2007
@@ -30,8 +30,8 @@
/* If we already changed the waiter ID, reset it. The call cannot
fail for any reason but the thread not having done that yet so
there is no reason for a loop. */
- atomic_compare_and_exchange_bool_acq ((struct pthread **) arg, NULL,
- THREAD_SELF);
+ (void) atomic_compare_and_exchange_bool_acq ((struct pthread **) arg, NULL,
+ THREAD_SELF);
}
Modified: trunk/libc/nptl/sysdeps/pthread/bits/libc-lock.h
==============================================================================
--- trunk/libc/nptl/sysdeps/pthread/bits/libc-lock.h (original)
+++ trunk/libc/nptl/sysdeps/pthread/bits/libc-lock.h Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* libc-internal interface for mutex locks. NPTL version.
- Copyright (C) 1996-2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1996-2003, 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
@@ -150,13 +150,17 @@
/* Call thread functions through the function pointer table. */
#if defined SHARED && !defined NOT_IN_libc
-# define PTF(NAME) __libc_pthread_functions.ptr_##NAME
+# define PTFAVAIL(NAME) __libc_pthread_functions_init
# define __libc_ptf_call(FUNC, ARGS, ELSE) \
- (PTF(FUNC) != NULL ? PTF(FUNC) ARGS : ELSE)
-#else
-# define PTF(NAME) NAME
+ (__libc_pthread_functions_init ? PTHFCT_CALL (ptr_##FUNC, ARGS) : ELSE)
+# define __libc_ptf_call_always(FUNC, ARGS) \
+ PTHFCT_CALL (ptr_##FUNC, ARGS)
+#else
+# define PTFAVAIL(NAME) (NAME != NULL)
# define __libc_ptf_call(FUNC, ARGS, ELSE) \
__libc_maybe_call (FUNC, ARGS, ELSE)
+# define __libc_ptf_call_always(FUNC, ARGS) \
+ FUNC ARGS
#endif
@@ -353,8 +357,9 @@
/* Call handler iff the first call. */
#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
do { \
- if (PTF(__pthread_once) != NULL) \
- PTF(__pthread_once) (&(ONCE_CONTROL), INIT_FUNCTION); \
+ if (PTFAVAIL (__pthread_once)) \
+ __libc_ptf_call_always (__pthread_once, (&(ONCE_CONTROL), \
+ INIT_FUNCTION)); \
else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \
INIT_FUNCTION (); \
(ONCE_CONTROL) |= 2; \
@@ -380,9 +385,10 @@
{ struct _pthread_cleanup_buffer _buffer; \
int _avail; \
if (DOIT) { \
- _avail = PTF(_pthread_cleanup_push_defer) != NULL; \
+ _avail = PTFAVAIL (_pthread_cleanup_push_defer); \
if (_avail) { \
- PTF(_pthread_cleanup_push_defer) (&_buffer, FCT, ARG); \
+ __libc_ptf_call_always (_pthread_cleanup_push_defer, (&_buffer, FCT, \
+ ARG)); \
} else { \
_buffer.__routine = (FCT); \
_buffer.__arg = (ARG); \
@@ -394,7 +400,7 @@
/* End critical region with cleanup. */
#define __libc_cleanup_region_end(DOIT) \
if (_avail) { \
- PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT); \
+ __libc_ptf_call_always (_pthread_cleanup_pop_restore, (&_buffer, DOIT));\
} else if (DOIT) \
_buffer.__routine (_buffer.__arg); \
}
@@ -402,7 +408,7 @@
/* Sometimes we have to exit the block in the middle. */
#define __libc_cleanup_end(DOIT) \
if (_avail) { \
- PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT); \
+ __libc_ptf_call_always (_pthread_cleanup_pop_restore, (&_buffer, DOIT));\
} else if (DOIT) \
_buffer.__routine (_buffer.__arg)
Modified: trunk/libc/nptl/sysdeps/pthread/pthread-functions.h
==============================================================================
--- trunk/libc/nptl/sysdeps/pthread/pthread-functions.h (original)
+++ trunk/libc/nptl/sysdeps/pthread/pthread-functions.h Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2003.
@@ -23,6 +23,7 @@
#include <pthread.h>
#include <setjmp.h>
#include <internaltypes.h>
+#include <sysdep.h>
struct xid_command;
@@ -100,5 +101,12 @@
/* Variable in libc.so. */
extern struct pthread_functions __libc_pthread_functions attribute_hidden;
+extern int __libc_pthread_functions_init attribute_hidden;
+
+#define PTHFCT_CALL(fct, params) \
+ ({ __typeof (__libc_pthread_functions.fct) __p; \
+ __p = __libc_pthread_functions.fct; \
+ PTR_DEMANGLE (__p); \
+ __p params; })
#endif /* pthread-functions.h */
Modified: trunk/libc/nptl/sysdeps/pthread/setxid.h
==============================================================================
--- trunk/libc/nptl/sysdeps/pthread/setxid.h (original)
+++ trunk/libc/nptl/sysdeps/pthread/setxid.h Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 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
@@ -33,13 +33,12 @@
# define INLINE_SETXID_SYSCALL(name, nr, args...) \
({ \
int __result; \
- if (__builtin_expect (__libc_pthread_functions.ptr__nptl_setxid \
- != NULL, 0)) \
+ if (__builtin_expect (__libc_pthread_functions_init, 0)) \
{ \
struct xid_command __cmd; \
__cmd.syscall_no = __NR_##name; \
__SETXID_##nr (__cmd, args); \
- __result = __libc_pthread_functions.ptr__nptl_setxid (&__cmd); \
+ __result = PTHFCT_CALL (ptr__nptl_setxid, (&__cmd)); \
} \
else \
__result = INLINE_SYSCALL (name, nr, args); \
Modified: trunk/libc/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c
==============================================================================
--- trunk/libc/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c (original)
+++ trunk/libc/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* Clean up stack frames unwound by longjmp. Linux version.
- Copyright (C) 1995, 1997, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 2002, 2003, 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
@@ -29,11 +29,11 @@
_longjmp_unwind (jmp_buf env, int val)
{
#ifdef SHARED
-# define fptr __libc_pthread_functions.ptr___pthread_cleanup_upto
+ if (__libc_pthread_functions_init)
+ PTHFCT_CALL (ptr___pthread_cleanup_upto, (env->__jmpbuf,
+ CURRENT_STACK_FRAME));
#else
-# define fptr __pthread_cleanup_upto
+ if (__pthread_cleanup_upto != NULL)
+ __pthread_cleanup_upto (env->__jmpbuf, CURRENT_STACK_FRAME);
#endif
-
- if (fptr != NULL)
- fptr (env->__jmpbuf, CURRENT_STACK_FRAME);
}
Modified: trunk/libc/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
==============================================================================
--- trunk/libc/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c (original)
+++ trunk/libc/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -25,6 +25,7 @@
#include <string.h>
#include <pthreadP.h>
#include <bits/libc-lock.h>
+#include <sysdep.h>
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
@@ -46,11 +47,29 @@
__register_atfork (NULL, NULL, reclaim, NULL);
#ifdef SHARED
- /* We copy the content of the variable pointed to by the FUNCTIONS
- parameter to one in libc.so since this means access to the array
- can be done with one memory access instead of two. */
- memcpy (&__libc_pthread_functions, functions,
- sizeof (__libc_pthread_functions));
+ /* Copy the function pointers into an array in libc. This enables
+ access with just one memory reference but moreso, it prevents
+ hijacking the function pointers with just one pointer change. We
+ "encrypt" the function pointers since we cannot write-protect the
+ array easily enough. */
+ union ptrhack
+ {
+ struct pthread_functions pf;
+ void *parr[1];
+ } const *src;
+ union ptrhack *dest;
+# define NPTRS (sizeof (struct pthread_functions) / sizeof (void *))
+
+ src = (const void *) functions;
+ dest = (void *) &__libc_pthread_functions;
+
+ for (size_t cnt = 0; cnt < NPTRS; ++cnt)
+ {
+ void *p = src->parr[cnt];
+ PTR_MANGLE (p);
+ dest->parr[cnt] = p;
+ }
+ __libc_pthread_functions_init = 1;
#endif
#ifndef TLS_MULTIPLE_THREADS_IN_TCB
@@ -61,7 +80,7 @@
#ifdef SHARED
libc_freeres_fn (freeres_libptread)
{
- if (__libc_pthread_functions.ptr_freeres != NULL)
- __libc_pthread_functions.ptr_freeres ();
+ if (__libc_pthread_functions_init)
+ PTHFCT_CALL (ptr_freeres, ());
}
#endif
Modified: trunk/libc/nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c
==============================================================================
--- trunk/libc/nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c (original)
+++ trunk/libc/nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c Mon Feb 5 09:59:45 2007
@@ -1,5 +1,5 @@
/* Clean up stack frames unwound by longjmp. Linux/s390 version.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 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
@@ -28,14 +28,13 @@
void
_longjmp_unwind (jmp_buf env, int val)
{
-#ifdef SHARED
-# define fptr __libc_pthread_functions.ptr___pthread_cleanup_upto
-#else
-# define fptr __pthread_cleanup_upto
-#endif
-
unsigned char local_var;
- if (fptr != NULL)
- fptr (env->__jmpbuf, &local_var);
+#ifdef SHARED
+ if (__libc_pthread_functions_init)
+ PTHFCT_CALL (ptr___pthread_cleanup_upto, (env->__jmpbuf, &local_var));
+#else
+ if (__pthread_cleanup_upto != NULL)
+ __pthread_cleanup_upto (env->__jmpbuf, &local_var);
+#endif
}
Modified: trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
==============================================================================
--- trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S (original)
+++ trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -269,13 +269,19 @@
.hidden __lll_timedwait_tid
.align 16
__lll_timedwait_tid:
+ cfi_startproc
pushq %r12
+ cfi_adjust_cfa_offset(8)
pushq %r13
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r12, -16)
+ cfi_offset(%r13, -24)
movq %rdi, %r12
movq %rsi, %r13
subq $16, %rsp
+ cfi_adjust_cfa_offset(16)
/* Get current time. */
2: movq %rsp, %rdi
@@ -319,14 +325,21 @@
4: xorl %eax, %eax
8: addq $16, %rsp
+ cfi_adjust_cfa_offset(-16)
popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
popq %r12
- retq
-
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+ retq
+
+ cfi_adjust_cfa_offset(32)
1: cmpq $-ETIMEDOUT, %rax
jne 2b
6: movl $ETIMEDOUT, %eax
jmp 8b
+ cfi_endproc
.size __lll_timedwait_tid,.-__lll_timedwait_tid
#endif
Modified: trunk/libc/nptl/tst-initializers1.c
==============================================================================
--- trunk/libc/nptl/tst-initializers1.c (original)
+++ trunk/libc/nptl/tst-initializers1.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@xxxxxxxxxx>, 2005.
@@ -16,6 +16,9 @@
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. */
+
+/* We test the code undef conditions outside of glibc. */
+#undef _LIBC
#include <pthread.h>
Modified: trunk/libc/nscd/cache.c
==============================================================================
--- trunk/libc/nscd/cache.c (original)
+++ trunk/libc/nscd/cache.c Mon Feb 5 09:59:45 2007
@@ -153,7 +153,10 @@
newp = mempool_alloc (table, sizeof (struct hashentry));
/* If we cannot allocate memory, just do not do anything. */
if (newp == NULL)
- return -1;
+ {
+ ++table->head->addfailed;
+ return -1;
+ }
newp->type = type;
newp->first = first;
Modified: trunk/libc/nscd/connections.c
==============================================================================
--- trunk/libc/nscd/connections.c (original)
+++ trunk/libc/nscd/connections.c Mon Feb 5 09:59:45 2007
@@ -181,24 +181,31 @@
/* Mapping of request type to database. */
-static struct database_dyn *const serv2db[LASTREQ] =
-{
- [GETPWBYNAME] = &dbs[pwddb],
- [GETPWBYUID] = &dbs[pwddb],
- [GETGRBYNAME] = &dbs[grpdb],
- [GETGRBYGID] = &dbs[grpdb],
- [GETHOSTBYNAME] = &dbs[hstdb],
- [GETHOSTBYNAMEv6] = &dbs[hstdb],
- [GETHOSTBYADDR] = &dbs[hstdb],
- [GETHOSTBYADDRv6] = &dbs[hstdb],
- [GETFDPW] = &dbs[pwddb],
- [GETFDGR] = &dbs[grpdb],
- [GETFDHST] = &dbs[hstdb],
- [GETAI] = &dbs[hstdb],
- [INITGROUPS] = &dbs[grpdb],
- [GETSERVBYNAME] = &dbs[servdb],
- [GETSERVBYPORT] = &dbs[servdb],
- [GETFDSERV] = &dbs[servdb]
+static struct
+{
+ bool data_request;
+ struct database_dyn *db;
+} const reqinfo[LASTREQ] =
+{
+ [GETPWBYNAME] = { true, &dbs[pwddb] },
+ [GETPWBYUID] = { true, &dbs[pwddb] },
+ [GETGRBYNAME] = { true, &dbs[grpdb] },
+ [GETGRBYGID] = { true, &dbs[grpdb] },
+ [GETHOSTBYNAME] = { true, &dbs[hstdb] },
+ [GETHOSTBYNAMEv6] = { true, &dbs[hstdb] },
+ [GETHOSTBYADDR] = { true, &dbs[hstdb] },
+ [GETHOSTBYADDRv6] = { true, &dbs[hstdb] },
+ [SHUTDOWN] = { false, NULL },
+ [GETSTAT] = { false, NULL },
+ [SHUTDOWN] = { false, NULL },
+ [GETFDPW] = { false, &dbs[pwddb] },
+ [GETFDGR] = { false, &dbs[grpdb] },
+ [GETFDHST] = { false, &dbs[hstdb] },
+ [GETAI] = { true, &dbs[hstdb] },
+ [INITGROUPS] = { true, &dbs[grpdb] },
+ [GETSERVBYNAME] = { true, &dbs[servdb] },
+ [GETSERVBYPORT] = { true, &dbs[servdb] },
+ [GETFDSERV] = { false, &dbs[servdb] }
};
@@ -385,7 +392,7 @@
/* Make sure the record is for this type of service. */
if (here->type >= LASTREQ
- || serv2db[here->type] != &dbs[dbnr])
+ || reqinfo[here->type].db != &dbs[dbnr])
goto fail;
/* Validate boolean field value. */
@@ -933,24 +940,14 @@
return;
}
- /* Make the SELinux check before we go on to the standard checks. We
- need to verify that the request type is valid, since it has not
- yet been checked at this point. */
- if (selinux_enabled
- && __builtin_expect (req->type >= GETPWBYNAME, 1)
- && __builtin_expect (req->type < LASTREQ, 1)
- && __builtin_expect (req->type < SHUTDOWN || req->type > INVALIDATE, 1)
- && nscd_request_avc_has_perm (fd, req->type) != 0)
+ /* Make the SELinux check before we go on to the standard checks. */
+ if (selinux_enabled && nscd_request_avc_has_perm (fd, req->type) != 0)
return;
- struct database_dyn *db = serv2db[req->type];
-
- // XXX Clean up so that each new command need not introduce a
- // XXX new conditional.
- if ((__builtin_expect (req->type, GETPWBYNAME) >= GETPWBYNAME
- && __builtin_expect (req->type, GETHOSTBYADDRv6) <= GETHOSTBYADDRv6)
- || req->type == GETAI || req->type == INITGROUPS
- || req->type == GETSERVBYNAME || req->type == GETSERVBYPORT)
+ struct database_dyn *db = reqinfo[req->type].db;
+
+ /* See whether we can service the request from the cache. */
+ if (__builtin_expect (reqinfo[req->type].data_request, true))
{
if (__builtin_expect (debug_level, 0) > 0)
{
@@ -968,7 +965,7 @@
}
/* Is this service enabled? */
- if (!db->enabled)
+ if (__builtin_expect (!db->enabled, 0))
{
/* No, sent the prepared record. */
if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
@@ -1149,7 +1146,7 @@
case GETFDHST:
case GETFDSERV:
#ifdef SCM_RIGHTS
- send_ro_fd (serv2db[req->type], key, fd);
+ send_ro_fd (reqinfo[req->type].db, key, fd);
#endif
break;
@@ -1433,7 +1430,6 @@
/* It should not be possible to crash the nscd with a silly
request (i.e., a terribly large key). We limit the size to 1kb. */
-#define MAXKEYLEN 1024
if (__builtin_expect (req.key_len, 1) < 0
|| __builtin_expect (req.key_len, 1) > MAXKEYLEN)
{
Modified: trunk/libc/nscd/nscd-client.h
==============================================================================
--- trunk/libc/nscd/nscd-client.h (original)
+++ trunk/libc/nscd/nscd-client.h Mon Feb 5 09:59:45 2007
@@ -43,6 +43,9 @@
/* Path for the configuration file. */
#define _PATH_NSCDCONF "/etc/nscd.conf"
+
+/* Maximu allowed length for the key. */
+#define MAXKEYLEN 1024
/* Available services. */
@@ -323,10 +326,10 @@
/* Search the mapped database. */
-extern const struct datahead *__nscd_cache_search (request_type type,
- const char *key,
- size_t keylen,
- const struct mapped_database *mapped);
+extern struct datahead *__nscd_cache_search (request_type type,
+ const char *key,
+ size_t keylen,
+ const struct mapped_database *mapped);
/* Wrappers around read, readv and write that only read/write less than LEN
bytes on error or EOF. */
Modified: trunk/libc/nscd/nscd_getai.c
==============================================================================
--- trunk/libc/nscd/nscd_getai.c (original)
+++ trunk/libc/nscd/nscd_getai.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2004.
@@ -42,6 +42,7 @@
{
size_t keylen = strlen (key) + 1;
int gc_cycle;
+ int nretries = 0;
/* If the mapping is available, try to search there instead of
communicating with the nscd. */
@@ -50,49 +51,53 @@
&gc_cycle);
retry:;
- const ai_response_header *ai_resp = NULL;
struct nscd_ai_result *resultbuf = NULL;
const char *recend = (const char *) ~UINTMAX_C (0);
char *respdata = NULL;
int retval = -1;
int sock = -1;
+ ai_response_header ai_resp;
if (mapped != NO_MAPPING)
{
- const struct datahead *found = __nscd_cache_search (GETAI, key, keylen,
- mapped);
+ struct datahead *found = __nscd_cache_search (GETAI, key, keylen,
+ mapped);
if (found != NULL)
{
- ai_resp = &found->data[0].aidata;
- respdata = (char *) (ai_resp + 1);
+ respdata = (char *) (&found->data[0].aidata + 1);
+ ai_resp = found->data[0].aidata;
recend = (const char *) found->data + found->recsize;
+ /* Now check if we can trust ai_resp fields. If GC is
+ in progress, it can contain anything. */
+ if (mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out;
+ }
}
}
/* If we do not have the cache mapped, try to get the data over the
socket. */
- ai_response_header ai_resp_mem;
- if (ai_resp == NULL)
- {
- sock = __nscd_open_socket (key, keylen, GETAI, &ai_resp_mem,
- sizeof (ai_resp_mem));
+ if (respdata == NULL)
+ {
+ sock = __nscd_open_socket (key, keylen, GETAI, &ai_resp,
+ sizeof (ai_resp));
if (sock == -1)
{
/* nscd not running or wrong version. */
__nss_not_use_nscd_hosts = 1;
goto out;
}
-
- ai_resp = &ai_resp_mem;
- }
-
- if (ai_resp->found == 1)
- {
- size_t datalen = ai_resp->naddrs + ai_resp->addrslen + ai_resp->canonlen;
-
- /* This check is really only affects the case where the data
+ }
+
+ if (ai_resp.found == 1)
+ {
+ size_t datalen = ai_resp.naddrs + ai_resp.addrslen + ai_resp.canonlen;
+
+ /* This check really only affects the case where the data
comes from the mapped cache. */
- if ((char *) (ai_resp + 1) + datalen > recend)
+ if (respdata + datalen > recend)
{
assert (sock == -1);
goto out;
@@ -108,10 +113,10 @@
}
/* Set up the data structure, including pointers. */
- resultbuf->naddrs = ai_resp->naddrs;
+ resultbuf->naddrs = ai_resp.naddrs;
resultbuf->addrs = (char *) (resultbuf + 1);
- resultbuf->family = (uint8_t *) (resultbuf->addrs + ai_resp->addrslen);
- if (ai_resp->canonlen != 0)
+ resultbuf->family = (uint8_t *) (resultbuf->addrs + ai_resp.addrslen);
+ if (ai_resp.canonlen != 0)
resultbuf->canon = (char *) (resultbuf->family + resultbuf->naddrs);
else
resultbuf->canon = NULL;
@@ -137,10 +142,13 @@
/* Try to detect corrupt databases. */
if (resultbuf->canon != NULL
- && resultbuf->canon[ai_resp->canonlen - 1] != '\0')
+ && resultbuf->canon[ai_resp.canonlen - 1] != '\0')
/* We cannot use the database. */
{
- free (resultbuf);
+ if (mapped->head->gc_cycle != gc_cycle)
+ retval = -2;
+ else
+ free (resultbuf);
goto out_close;
}
@@ -150,7 +158,7 @@
}
else
{
- if (__builtin_expect (ai_resp->found == -1, 0))
+ if (__builtin_expect (ai_resp.found == -1, 0))
{
/* The daemon does not cache this database. */
__nss_not_use_nscd_hosts = 1;
@@ -158,7 +166,7 @@
}
/* Store the error number. */
- *h_errnop = ai_resp->error;
+ *h_errnop = ai_resp.error;
/* The `errno' to some value != ERANGE. */
__set_errno (ENOENT);
@@ -170,22 +178,25 @@
if (sock != -1)
close_not_cancel_no_status (sock);
out:
- if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+ if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
/* When we come here this means there has been a GC cycle while we
were looking for the data. This means the data might have been
inconsistent. Retry if possible. */
- if ((gc_cycle & 1) != 0)
+ if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
{
/* nscd is just running gc now. Disable using the mapping. */
- __nscd_unmap (mapped);
+ if (atomic_decrement_val (&mapped->counter) == 0)
+ __nscd_unmap (mapped);
mapped = NO_MAPPING;
}
- *result = NULL;
- free (resultbuf);
-
- goto retry;
+ if (retval != -1)
+ {
+ *result = NULL;
+ free (resultbuf);
+ goto retry;
+ }
}
return retval;
Modified: trunk/libc/nscd/nscd_getgr_r.c
==============================================================================
--- trunk/libc/nscd/nscd_getgr_r.c (original)
+++ trunk/libc/nscd/nscd_getgr_r.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998-2000, 2002-2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2000, 2002-2005, 2006, 2007
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@xxxxxxxxxxxxxxxx>, 1998.
@@ -88,6 +89,7 @@
struct group **result)
{
int gc_cycle;
+ int nretries = 0;
const uint32_t *len = NULL;
size_t lensize = 0;
@@ -97,55 +99,59 @@
&__gr_map_handle,
&gc_cycle);
retry:;
- const gr_response_header *gr_resp = NULL;
const char *gr_name = NULL;
size_t gr_name_len = 0;
int retval = -1;
const char *recend = (const char *) ~UINTMAX_C (0);
+ gr_response_header gr_resp;
if (mapped != NO_MAPPING)
{
- const struct datahead *found = __nscd_cache_search (type, key, keylen,
- mapped);
+ struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
if (found != NULL)
{
- gr_resp = &found->data[0].grdata;
- len = (const uint32_t *) (gr_resp + 1);
- /* The alignment is always sufficient. */
+ len = (const uint32_t *) (&found->data[0].grdata + 1);
+ gr_resp = found->data[0].grdata;
+ gr_name = ((const char *) len
+ + gr_resp.gr_mem_cnt * sizeof (uint32_t));
+ gr_name_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
+ recend = (const char *) found->data + found->recsize;
+ /* Now check if we can trust gr_resp fields. If GC is
+ in progress, it can contain anything. */
+ if (mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out;
+ }
+
+ /* The alignment is always sufficient, unless GC is in progress. */
assert (((uintptr_t) len & (__alignof__ (*len) - 1)) == 0);
- gr_name = ((const char *) len
- + gr_resp->gr_mem_cnt * sizeof (uint32_t));
- gr_name_len = gr_resp->gr_name_len + gr_resp->gr_passwd_len;
- recend = (const char *) found->data + found->recsize;
- }
- }
-
- gr_response_header gr_resp_mem;
+ }
+ }
+
int sock = -1;
- if (gr_resp == NULL)
- {
- sock = __nscd_open_socket (key, keylen, type, &gr_resp_mem,
- sizeof (gr_resp_mem));
+ if (gr_name == NULL)
+ {
+ sock = __nscd_open_socket (key, keylen, type, &gr_resp,
+ sizeof (gr_resp));
if (sock == -1)
{
__nss_not_use_nscd_group = 1;
goto out;
}
-
- gr_resp = &gr_resp_mem;
}
/* No value found so far. */
*result = NULL;
- if (__builtin_expect (gr_resp->found == -1, 0))
+ if (__builtin_expect (gr_resp.found == -1, 0))
{
/* The daemon does not cache this database. */
__nss_not_use_nscd_group = 1;
goto out_close;
}
- if (gr_resp->found == 1)
+ if (gr_resp.found == 1)
{
struct iovec vec[2];
char *p = buffer;
@@ -157,8 +163,8 @@
align the pointer. */
align = ((__alignof__ (char *) - (p - ((char *) 0)))
& (__alignof__ (char *) - 1));
- total_len = (align + (1 + gr_resp->gr_mem_cnt) * sizeof (char *)
- + gr_resp->gr_name_len + gr_resp->gr_passwd_len);
+ total_len = (align + (1 + gr_resp.gr_mem_cnt) * sizeof (char *)
+ + gr_resp.gr_name_len + gr_resp.gr_passwd_len);
if (__builtin_expect (buflen < total_len, 0))
{
no_room:
@@ -170,16 +176,16 @@
p += align;
resultbuf->gr_mem = (char **) p;
- p += (1 + gr_resp->gr_mem_cnt) * sizeof (char *);
+ p += (1 + gr_resp.gr_mem_cnt) * sizeof (char *);
/* Set pointers for strings. */
resultbuf->gr_name = p;
- p += gr_resp->gr_name_len;
+ p += gr_resp.gr_name_len;
resultbuf->gr_passwd = p;
- p += gr_resp->gr_passwd_len;
+ p += gr_resp.gr_passwd_len;
/* Fill in what we know now. */
- resultbuf->gr_gid = gr_resp->gr_gid;
+ resultbuf->gr_gid = gr_resp.gr_gid;
/* Read the length information, group name, and password. */
if (gr_name == NULL)
@@ -187,17 +193,17 @@
/* Allocate array to store lengths. */
if (lensize == 0)
{
- lensize = gr_resp->gr_mem_cnt * sizeof (uint32_t);
+ lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t);
len = (uint32_t *) alloca (lensize);
}
- else if (gr_resp->gr_mem_cnt * sizeof (uint32_t) > lensize)
+ else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize)
len = extend_alloca (len, lensize,
- gr_resp->gr_mem_cnt * sizeof (uint32_t));
+ gr_resp.gr_mem_cnt * sizeof (uint32_t));
vec[0].iov_base = (void *) len;
- vec[0].iov_len = gr_resp->gr_mem_cnt * sizeof (uint32_t);
+ vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t);
vec[1].iov_base = resultbuf->gr_name;
- vec[1].iov_len = gr_resp->gr_name_len + gr_resp->gr_passwd_len;
+ vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
total_len = vec[0].iov_len + vec[1].iov_len;
/* Get this data. */
@@ -209,14 +215,14 @@
/* We already have the data. Just copy the group name and
password. */
memcpy (resultbuf->gr_name, gr_name,
- gr_resp->gr_name_len + gr_resp->gr_passwd_len);
+ gr_resp.gr_name_len + gr_resp.gr_passwd_len);
/* Clear the terminating entry. */
- resultbuf->gr_mem[gr_resp->gr_mem_cnt] = NULL;
+ resultbuf->gr_mem[gr_resp.gr_mem_cnt] = NULL;
/* Prepare reading the group members. */
total_len = 0;
- for (cnt = 0; cnt < gr_resp->gr_mem_cnt; ++cnt)
+ for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
{
resultbuf->gr_mem[cnt] = p;
total_len += len[cnt];
@@ -224,9 +230,25 @@
}
if (__builtin_expect (gr_name + gr_name_len + total_len > recend, 0))
- goto out_close;
+ {
+ /* len array might contain garbage during nscd GC cycle,
+ retry rather than fail in that case. */
+ if (gr_name != NULL && mapped->head->gc_cycle != gc_cycle)
+ retval = -2;
+ goto out_close;
+ }
if (__builtin_expect (total_len > buflen, 0))
- goto no_room;
+ {
+ /* len array might contain garbage during nscd GC cycle,
+ retry rather than fail in that case. */
+ if (gr_name != NULL && mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out_close;
+ }
+ else
+ goto no_room;
+ }
retval = 0;
if (gr_name == NULL)
@@ -248,14 +270,14 @@
/* Try to detect corrupt databases. */
if (resultbuf->gr_name[gr_name_len - 1] != '\0'
- || resultbuf->gr_passwd[gr_resp->gr_passwd_len - 1] != '\0'
- || ({for (cnt = 0; cnt < gr_resp->gr_mem_cnt; ++cnt)
+ || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0'
+ || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
break;
- cnt < gr_resp->gr_mem_cnt; }))
+ cnt < gr_resp.gr_mem_cnt; }))
{
/* We cannot use the database. */
- retval = -1;
+ retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
goto out_close;
}
@@ -274,19 +296,21 @@
if (sock != -1)
close_not_cancel_no_status (sock);
out:
- if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+ if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
/* When we come here this means there has been a GC cycle while we
were looking for the data. This means the data might have been
inconsistent. Retry if possible. */
- if ((gc_cycle & 1) != 0)
+ if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
{
/* nscd is just running gc now. Disable using the mapping. */
- __nscd_unmap (mapped);
+ if (atomic_decrement_val (&mapped->counter) == 0)
+ __nscd_unmap (mapped);
mapped = NO_MAPPING;
}
- goto retry;
+ if (retval != -1)
+ goto retry;
}
return retval;
Modified: trunk/libc/nscd/nscd_gethst_r.c
==============================================================================
--- trunk/libc/nscd/nscd_gethst_r.c (original)
+++ trunk/libc/nscd/nscd_gethst_r.c Mon Feb 5 09:59:45 2007
@@ -113,7 +113,6 @@
&gc_cycle);
retry:;
- const hst_response_header *hst_resp = NULL;
const char *h_name = NULL;
const uint32_t *aliases_len = NULL;
const char *addr_list = NULL;
@@ -121,18 +120,27 @@
int retval = -1;
const char *recend = (const char *) ~UINTMAX_C (0);
int sock = -1;
+ hst_response_header hst_resp;
if (mapped != NO_MAPPING)
{
- const struct datahead *found = __nscd_cache_search (type, key, keylen,
- mapped);
+ /* No const qualifier, as it can change during garbage collection. */
+ struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
if (found != NULL)
{
- hst_resp = &found->data[0].hstdata;
- h_name = (char *) (hst_resp + 1);
- aliases_len = (uint32_t *) (h_name + hst_resp->h_name_len);
+ h_name = (char *) (&found->data[0].hstdata + 1);
+ hst_resp = found->data[0].hstdata;
+ aliases_len = (uint32_t *) (h_name + hst_resp.h_name_len);
addr_list = ((char *) aliases_len
- + hst_resp->h_aliases_cnt * sizeof (uint32_t));
- addr_list_len = hst_resp->h_addr_list_cnt * INADDRSZ;
+ + hst_resp.h_aliases_cnt * sizeof (uint32_t));
+ addr_list_len = hst_resp.h_addr_list_cnt * INADDRSZ;
+ recend = (const char *) found->data + found->recsize;
+ /* Now check if we can trust hst_resp fields. If GC is
+ in progress, it can contain anything. */
+ if (mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out;
+ }
#ifndef _STRING_ARCH_unaligned
/* The aliases_len array in the mapped database might very
@@ -142,51 +150,47 @@
if (((uintptr_t) aliases_len & (__alignof__ (*aliases_len) - 1))
!= 0)
{
- uint32_t *tmp = alloca (hst_resp->h_aliases_cnt
+ uint32_t *tmp = alloca (hst_resp.h_aliases_cnt
* sizeof (uint32_t));
aliases_len = memcpy (tmp, aliases_len,
- hst_resp->h_aliases_cnt
+ hst_resp.h_aliases_cnt
* sizeof (uint32_t));
}
#endif
if (type != GETHOSTBYADDR && type != GETHOSTBYNAME)
{
- if (hst_resp->h_length == INADDRSZ)
+ if (hst_resp.h_length == INADDRSZ)
addr_list += addr_list_len;
- addr_list_len = hst_resp->h_addr_list_cnt * IN6ADDRSZ;
- }
- recend = (const char *) found->data + found->recsize;
+ addr_list_len = hst_resp.h_addr_list_cnt * IN6ADDRSZ;
+ }
if (__builtin_expect ((const char *) addr_list + addr_list_len
> recend, 0))
- goto out_close;
- }
- }
-
- hst_response_header hst_resp_mem;
- if (hst_resp == NULL)
- {
- sock = __nscd_open_socket (key, keylen, type, &hst_resp_mem,
- sizeof (hst_resp_mem));
+ goto out;
+ }
+ }
+
+ if (h_name == NULL)
+ {
+ sock = __nscd_open_socket (key, keylen, type, &hst_resp,
+ sizeof (hst_resp));
if (sock == -1)
{
__nss_not_use_nscd_hosts = 1;
goto out;
}
-
- hst_resp = &hst_resp_mem;
}
/* No value found so far. */
*result = NULL;
- if (__builtin_expect (hst_resp->found == -1, 0))
+ if (__builtin_expect (hst_resp.found == -1, 0))
{
/* The daemon does not cache this database. */
__nss_not_use_nscd_hosts = 1;
goto out_close;
}
- if (hst_resp->found == 1)
+ if (hst_resp.found == 1)
{
char *cp = buffer;
uintptr_t align1;
@@ -201,15 +205,15 @@
align the pointer and the base of the h_addr_list pointers. */
align1 = ((__alignof__ (char *) - (cp - ((char *) 0)))
& (__alignof__ (char *) - 1));
- align2 = ((__alignof__ (char *) - ((cp + align1 + hst_resp->h_name_len)
+ align2 = ((__alignof__ (char *) - ((cp + align1 + hst_resp.h_name_len)
- ((char *) 0)))
& (__alignof__ (char *) - 1));
- if (buflen < (align1 + hst_resp->h_name_len + align2
- + ((hst_resp->h_aliases_cnt + hst_resp->h_addr_list_cnt
+ if (buflen < (align1 + hst_resp.h_name_len + align2
+ + ((hst_resp.h_aliases_cnt + hst_resp.h_addr_list_cnt
+ 2)
* sizeof (char *))
- + hst_resp->h_addr_list_cnt * (type == AF_INET
- ? INADDRSZ : IN6ADDRSZ)))
+ + hst_resp.h_addr_list_cnt * (type == AF_INET
+ ? INADDRSZ : IN6ADDRSZ)))
{
no_room:
*h_errnop = NETDB_INTERNAL;
@@ -221,12 +225,12 @@
/* Prepare the result as far as we can. */
resultbuf->h_aliases = (char **) cp;
- cp += (hst_resp->h_aliases_cnt + 1) * sizeof (char *);
+ cp += (hst_resp.h_aliases_cnt + 1) * sizeof (char *);
resultbuf->h_addr_list = (char **) cp;
- cp += (hst_resp->h_addr_list_cnt + 1) * sizeof (char *);
+ cp += (hst_resp.h_addr_list_cnt + 1) * sizeof (char *);
resultbuf->h_name = cp;
- cp += hst_resp->h_name_len + align2;
+ cp += hst_resp.h_name_len + align2;
if (type == GETHOSTBYADDR || type == GETHOSTBYNAME)
{
@@ -238,7 +242,7 @@
resultbuf->h_addrtype = AF_INET6;
resultbuf->h_length = IN6ADDRSZ;
}
- for (cnt = 0; cnt < hst_resp->h_addr_list_cnt; ++cnt)
+ for (cnt = 0; cnt < hst_resp.h_addr_list_cnt; ++cnt)
{
resultbuf->h_addr_list[cnt] = cp;
cp += resultbuf->h_length;
@@ -250,47 +254,47 @@
struct iovec vec[4];
vec[0].iov_base = resultbuf->h_name;
- vec[0].iov_len = hst_resp->h_name_len;
- total_len = hst_resp->h_name_len;
+ vec[0].iov_len = hst_resp.h_name_len;
+ total_len = hst_resp.h_name_len;
n = 1;
- if (hst_resp->h_aliases_cnt > 0)
- {
- aliases_len = alloca (hst_resp->h_aliases_cnt
+ if (hst_resp.h_aliases_cnt > 0)
+ {
+ aliases_len = alloca (hst_resp.h_aliases_cnt
* sizeof (uint32_t));
vec[n].iov_base = (void *) aliases_len;
- vec[n].iov_len = hst_resp->h_aliases_cnt * sizeof (uint32_t);
-
- total_len += hst_resp->h_aliases_cnt * sizeof (uint32_t);
+ vec[n].iov_len = hst_resp.h_aliases_cnt * sizeof (uint32_t);
+
+ total_len += hst_resp.h_aliases_cnt * sizeof (uint32_t);
++n;
}
if (type == GETHOSTBYADDR || type == GETHOSTBYNAME)
{
vec[n].iov_base = resultbuf->h_addr_list[0];
- vec[n].iov_len = hst_resp->h_addr_list_cnt * INADDRSZ;
-
- total_len += hst_resp->h_addr_list_cnt * INADDRSZ;
+ vec[n].iov_len = hst_resp.h_addr_list_cnt * INADDRSZ;
+
+ total_len += hst_resp.h_addr_list_cnt * INADDRSZ;
++n;
}
else
{
- if (hst_resp->h_length == INADDRSZ)
+ if (hst_resp.h_length == INADDRSZ)
{
- ignore = alloca (hst_resp->h_addr_list_cnt * INADDRSZ);
+ ignore = alloca (hst_resp.h_addr_list_cnt * INADDRSZ);
vec[n].iov_base = ignore;
- vec[n].iov_len = hst_resp->h_addr_list_cnt * INADDRSZ;
-
- total_len += hst_resp->h_addr_list_cnt * INADDRSZ;
+ vec[n].iov_len = hst_resp.h_addr_list_cnt * INADDRSZ;
+
+ total_len += hst_resp.h_addr_list_cnt * INADDRSZ;
++n;
}
vec[n].iov_base = resultbuf->h_addr_list[0];
- vec[n].iov_len = hst_resp->h_addr_list_cnt * IN6ADDRSZ;
-
- total_len += hst_resp->h_addr_list_cnt * IN6ADDRSZ;
+ vec[n].iov_len = hst_resp.h_addr_list_cnt * IN6ADDRSZ;
+
+ total_len += hst_resp.h_addr_list_cnt * IN6ADDRSZ;
++n;
}
@@ -300,13 +304,13 @@
}
else
{
- memcpy (resultbuf->h_name, h_name, hst_resp->h_name_len);
+ memcpy (resultbuf->h_name, h_name, hst_resp.h_name_len);
memcpy (resultbuf->h_addr_list[0], addr_list, addr_list_len);
}
/* Now we also can read the aliases. */
total_len = 0;
- for (cnt = 0; cnt < hst_resp->h_aliases_cnt; ++cnt)
+ for (cnt = 0; cnt < hst_resp.h_aliases_cnt; ++cnt)
{
resultbuf->h_aliases[cnt] = cp;
cp += aliases_len[cnt];
@@ -316,10 +320,25 @@
if (__builtin_expect ((const char *) addr_list + addr_list_len
+ total_len > recend, 0))
- goto out_close;
+ {
+ /* aliases_len array might contain garbage during nscd GC cycle,
+ retry rather than fail in that case. */
+ if (addr_list != NULL && mapped->head->gc_cycle != gc_cycle)
+ retval = -2;
+ goto out_close;
+ }
/* See whether this would exceed the buffer capacity. */
if (__builtin_expect (cp > buffer + buflen, 0))
- goto no_room;
+ {
+ /* aliases_len array might contain garbage during nscd GC cycle,
+ retry rather than fail in that case. */
+ if (addr_list != NULL && mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out_close;
+ }
+ goto no_room;
+ }
/* And finally read the aliases. */
if (addr_list == NULL)
@@ -338,14 +357,18 @@
(const char *) addr_list + addr_list_len, total_len);
/* Try to detect corrupt databases. */
- if (resultbuf->h_name[hst_resp->h_name_len - 1] != '\0'
- || ({for (cnt = 0; cnt < hst_resp->h_aliases_cnt; ++cnt)
+ if (resultbuf->h_name[hst_resp.h_name_len - 1] != '\0'
+ || ({for (cnt = 0; cnt < hst_resp.h_aliases_cnt; ++cnt)
if (resultbuf->h_aliases[cnt][aliases_len[cnt] - 1]
!= '\0')
break;
- cnt < hst_resp->h_aliases_cnt; }))
- /* We cannot use the database. */
- goto out_close;
+ cnt < hst_resp.h_aliases_cnt; }))
+ {
+ /* We cannot use the database. */
+ if (mapped->head->gc_cycle != gc_cycle)
+ retval = -2;
+ goto out_close;
+ }
retval = 0;
*result = resultbuf;
@@ -354,7 +377,7 @@
else
{
/* Store the error number. */
- *h_errnop = hst_resp->error;
+ *h_errnop = hst_resp.error;
/* The `errno' to some value != ERANGE. */
__set_errno (ENOENT);
@@ -366,19 +389,21 @@
if (sock != -1)
close_not_cancel_no_status (sock);
out:
- if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+ if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
/* When we come here this means there has been a GC cycle while we
were looking for the data. This means the data might have been
inconsistent. Retry if possible. */
- if ((gc_cycle & 1) != 0 || ++nretries == 5)
+ if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
{
/* nscd is just running gc now. Disable using the mapping. */
- __nscd_unmap (mapped);
+ if (atomic_decrement_val (&mapped->counter) == 0)
+ __nscd_unmap (mapped);
mapped = NO_MAPPING;
}
- goto retry;
+ if (retval != -1)
+ goto retry;
}
return retval;
Modified: trunk/libc/nscd/nscd_getpw_r.c
==============================================================================
--- trunk/libc/nscd/nscd_getpw_r.c (original)
+++ trunk/libc/nscd/nscd_getpw_r.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998, 1999, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2003, 2004, 2005, 2007
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@xxxxxxxxxxxxxxxx>, 1998.
@@ -88,76 +89,81 @@
struct passwd **result)
{
int gc_cycle;
+ int nretries = 0;
+
/* If the mapping is available, try to search there instead of
communicating with the nscd. */
struct mapped_database *mapped;
mapped = __nscd_get_map_ref (GETFDPW, "passwd", &map_handle, &gc_cycle);
retry:;
- const pw_response_header *pw_resp = NULL;
const char *pw_name = NULL;
int retval = -1;
const char *recend = (const char *) ~UINTMAX_C (0);
+ pw_response_header pw_resp;
if (mapped != NO_MAPPING)
{
- const struct datahead *found = __nscd_cache_search (type, key, keylen,
- mapped);
+ struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
if (found != NULL)
{
- pw_resp = &found->data[0].pwdata;
- pw_name = (const char *) (pw_resp + 1);
+ pw_name = (const char *) (&found->data[0].pwdata + 1);
+ pw_resp = found->data[0].pwdata;
recend = (const char *) found->data + found->recsize;
- }
- }
-
- pw_response_header pw_resp_mem;
+ /* Now check if we can trust pw_resp fields. If GC is
+ in progress, it can contain anything. */
+ if (mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out;
+ }
+ }
+ }
+
int sock = -1;
- if (pw_resp == NULL)
- {
- sock = __nscd_open_socket (key, keylen, type, &pw_resp_mem,
- sizeof (pw_resp_mem));
+ if (pw_name == NULL)
+ {
+ sock = __nscd_open_socket (key, keylen, type, &pw_resp,
+ sizeof (pw_resp));
if (sock == -1)
{
__nss_not_use_nscd_passwd = 1;
goto out;
}
-
- pw_resp = &pw_resp_mem;
}
/* No value found so far. */
*result = NULL;
- if (__builtin_expect (pw_resp->found == -1, 0))
+ if (__builtin_expect (pw_resp.found == -1, 0))
{
/* The daemon does not cache this database. */
__nss_not_use_nscd_passwd = 1;
goto out_close;
}
- if (pw_resp->found == 1)
+ if (pw_resp.found == 1)
{
/* Set the information we already have. */
- resultbuf->pw_uid = pw_resp->pw_uid;
- resultbuf->pw_gid = pw_resp->pw_gid;
+ resultbuf->pw_uid = pw_resp.pw_uid;
+ resultbuf->pw_gid = pw_resp.pw_gid;
char *p = buffer;
/* get pw_name */
resultbuf->pw_name = p;
- p += pw_resp->pw_name_len;
+ p += pw_resp.pw_name_len;
/* get pw_passwd */
resultbuf->pw_passwd = p;
- p += pw_resp->pw_passwd_len;
+ p += pw_resp.pw_passwd_len;
/* get pw_gecos */
resultbuf->pw_gecos = p;
- p += pw_resp->pw_gecos_len;
+ p += pw_resp.pw_gecos_len;
/* get pw_dir */
resultbuf->pw_dir = p;
- p += pw_resp->pw_dir_len;
+ p += pw_resp.pw_dir_len;
/* get pw_pshell */
resultbuf->pw_shell = p;
- p += pw_resp->pw_shell_len;
+ p += pw_resp.pw_shell_len;
ssize_t total = p - buffer;
if (__builtin_expect (pw_name + total > recend, 0))
@@ -189,14 +195,14 @@
memcpy (resultbuf->pw_name, pw_name, total);
/* Try to detect corrupt databases. */
- if (resultbuf->pw_name[pw_resp->pw_name_len - 1] != '\0'
- || resultbuf->pw_passwd[pw_resp->pw_passwd_len - 1] != '\0'
- || resultbuf->pw_gecos[pw_resp->pw_gecos_len - 1] != '\0'
- || resultbuf->pw_dir[pw_resp->pw_dir_len - 1] != '\0'
- || resultbuf->pw_shell[pw_resp->pw_shell_len - 1] != '\0')
+ if (resultbuf->pw_name[pw_resp.pw_name_len - 1] != '\0'
+ || resultbuf->pw_passwd[pw_resp.pw_passwd_len - 1] != '\0'
+ || resultbuf->pw_gecos[pw_resp.pw_gecos_len - 1] != '\0'
+ || resultbuf->pw_dir[pw_resp.pw_dir_len - 1] != '\0'
+ || resultbuf->pw_shell[pw_resp.pw_shell_len - 1] != '\0')
{
/* We cannot use the database. */
- retval = -1;
+ retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
goto out_close;
}
@@ -215,19 +221,21 @@
if (sock != -1)
close_not_cancel_no_status (sock);
out:
- if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+ if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
/* When we come here this means there has been a GC cycle while we
were looking for the data. This means the data might have been
inconsistent. Retry if possible. */
- if ((gc_cycle & 1) != 0)
+ if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
{
/* nscd is just running gc now. Disable using the mapping. */
- __nscd_unmap (mapped);
+ if (atomic_decrement_val (&mapped->counter) == 0)
+ __nscd_unmap (mapped);
mapped = NO_MAPPING;
}
- goto retry;
+ if (retval != -1)
+ goto retry;
}
return retval;
Modified: trunk/libc/nscd/nscd_getserv_r.c
==============================================================================
--- trunk/libc/nscd/nscd_getserv_r.c (original)
+++ trunk/libc/nscd/nscd_getserv_r.c Mon Feb 5 09:59:45 2007
@@ -93,7 +93,6 @@
"/", 1), proto ?: "", protolen + 1);
retry:;
- const serv_response_header *serv_resp = NULL;
const char *s_name = NULL;
const char *s_proto = NULL;
const uint32_t *aliases_len = NULL;
@@ -101,19 +100,32 @@
int retval = -1;
const char *recend = (const char *) ~UINTMAX_C (0);
int sock = -1;
+ serv_response_header serv_resp;
+
if (mapped != NO_MAPPING)
{
- const struct datahead *found = __nscd_cache_search (type, key, keylen,
- mapped);
+ struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
if (found != NULL)
{
- serv_resp = &found->data[0].servdata;
- s_name = (char *) (serv_resp + 1);
- s_proto = s_name + serv_resp->s_name_len;
- aliases_len = (uint32_t *) (s_proto + serv_resp->s_proto_len);
+ s_name = (char *) (&found->data[0].servdata + 1);
+ serv_resp = found->data[0].servdata;
+ s_proto = s_name + serv_resp.s_name_len;
+ aliases_len = (uint32_t *) (s_proto + serv_resp.s_proto_len);
aliases_list = ((char *) aliases_len
- + serv_resp->s_aliases_cnt * sizeof (uint32_t));
+ + serv_resp.s_aliases_cnt * sizeof (uint32_t));
+ recend = (const char *) found->data + found->recsize;
+ /* Now check if we can trust serv_resp fields. If GC is
+ in progress, it can contain anything. */
+ if (mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out;
+ }
+ if (__builtin_expect ((const char *) aliases_len
+ + serv_resp.s_aliases_cnt * sizeof (uint32_t)
+ > recend, 0))
+ goto out;
#ifndef _STRING_ARCH_unaligned
/* The aliases_len array in the mapped database might very
@@ -123,46 +135,38 @@
if (((uintptr_t) aliases_len & (__alignof__ (*aliases_len) - 1))
!= 0)
{
- uint32_t *tmp = alloca (hst_resp->h_aliases_cnt
+ uint32_t *tmp = alloca (serv_resp.s_aliases_cnt
* sizeof (uint32_t));
aliases_len = memcpy (tmp, aliases_len,
- hst_resp->h_aliases_cnt
+ serv_resp.s_aliases_cnt
* sizeof (uint32_t));
}
#endif
- recend = (const char *) found->data + found->recsize;
- if (__builtin_expect ((const char *) aliases_len
- + serv_resp->s_aliases_cnt * sizeof (uint32_t)
- > recend, 0))
- goto out_close;
- }
- }
-
- serv_response_header serv_resp_mem;
- if (serv_resp == NULL)
- {
- sock = __nscd_open_socket (key, keylen, type, &serv_resp_mem,
- sizeof (serv_resp_mem));
+ }
+ }
+
+ if (s_name == NULL)
+ {
+ sock = __nscd_open_socket (key, keylen, type, &serv_resp,
+ sizeof (serv_resp));
if (sock == -1)
{
__nss_not_use_nscd_services = 1;
goto out;
}
-
- serv_resp = &serv_resp_mem;
}
/* No value found so far. */
*result = NULL;
- if (__builtin_expect (serv_resp->found == -1, 0))
+ if (__builtin_expect (serv_resp.found == -1, 0))
{
/* The daemon does not cache this database. */
__nss_not_use_nscd_services = 1;
goto out_close;
}
- if (serv_resp->found == 1)
+ if (serv_resp.found == 1)
{
char *cp = buf;
uintptr_t align1;
@@ -176,13 +180,13 @@
align the pointer and the base of the h_addr_list pointers. */
align1 = ((__alignof__ (char *) - (cp - ((char *) 0)))
& (__alignof__ (char *) - 1));
- align2 = ((__alignof__ (char *) - ((cp + align1 + serv_resp->s_name_len
- + serv_resp->s_proto_len)
+ align2 = ((__alignof__ (char *) - ((cp + align1 + serv_resp.s_name_len
+ + serv_resp.s_proto_len)
- ((char *) 0)))
& (__alignof__ (char *) - 1));
- if (buflen < (align1 + serv_resp->s_name_len + serv_resp->s_proto_len
+ if (buflen < (align1 + serv_resp.s_name_len + serv_resp.s_proto_len
+ align2
- + (serv_resp->s_aliases_cnt + 1) * sizeof (char *)))
+ + (serv_resp.s_aliases_cnt + 1) * sizeof (char *)))
{
no_room:
__set_errno (ERANGE);
@@ -193,31 +197,31 @@
/* Prepare the result as far as we can. */
resultbuf->s_aliases = (char **) cp;
- cp += (serv_resp->s_aliases_cnt + 1) * sizeof (char *);
+ cp += (serv_resp.s_aliases_cnt + 1) * sizeof (char *);
resultbuf->s_name = cp;
- cp += serv_resp->s_name_len;
+ cp += serv_resp.s_name_len;
resultbuf->s_proto = cp;
- cp += serv_resp->s_proto_len + align2;
- resultbuf->s_port = serv_resp->s_port;
+ cp += serv_resp.s_proto_len + align2;
+ resultbuf->s_port = serv_resp.s_port;
if (s_name == NULL)
{
struct iovec vec[2];
vec[0].iov_base = resultbuf->s_name;
- vec[0].iov_len = serv_resp->s_name_len + serv_resp->s_proto_len;
+ vec[0].iov_len = serv_resp.s_name_len + serv_resp.s_proto_len;
total_len = vec[0].iov_len;
n = 1;
- if (serv_resp->s_aliases_cnt > 0)
- {
- aliases_len = alloca (serv_resp->s_aliases_cnt
+ if (serv_resp.s_aliases_cnt > 0)
+ {
+ aliases_len = alloca (serv_resp.s_aliases_cnt
* sizeof (uint32_t));
vec[n].iov_base = (void *) aliases_len;
- vec[n].iov_len = serv_resp->s_aliases_cnt * sizeof (uint32_t);
-
- total_len += serv_resp->s_aliases_cnt * sizeof (uint32_t);
+ vec[n].iov_len = serv_resp.s_aliases_cnt * sizeof (uint32_t);
+
+ total_len += serv_resp.s_aliases_cnt * sizeof (uint32_t);
++n;
}
@@ -226,11 +230,11 @@
}
else
memcpy (resultbuf->s_name, s_name,
- serv_resp->s_name_len + serv_resp->s_proto_len);
+ serv_resp.s_name_len + serv_resp.s_proto_len);
/* Now we also can read the aliases. */
total_len = 0;
- for (cnt = 0; cnt < serv_resp->s_aliases_cnt; ++cnt)
+ for (cnt = 0; cnt < serv_resp.s_aliases_cnt; ++cnt)
{
resultbuf->s_aliases[cnt] = cp;
cp += aliases_len[cnt];
@@ -240,10 +244,26 @@
if (__builtin_expect ((const char *) aliases_list + total_len > recend,
0))
- goto out_close;
+ {
+ /* aliases_len array might contain garbage during nscd GC cycle,
+ retry rather than fail in that case. */
+ if (aliases_list != NULL && mapped->head->gc_cycle != gc_cycle)
+ retval = -2;
+ goto out_close;
+ }
+
/* See whether this would exceed the buffer capacity. */
if (__builtin_expect (cp > buf + buflen, 0))
- goto no_room;
+ {
+ /* aliases_len array might contain garbage during nscd GC cycle,
+ retry rather than fail in that case. */
+ if (aliases_list != NULL && mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out_close;
+ }
+ goto no_room;
+ }
/* And finally read the aliases. */
if (aliases_list == NULL)
@@ -261,15 +281,19 @@
memcpy (resultbuf->s_aliases[0], aliases_list, total_len);
/* Try to detect corrupt databases. */
- if (resultbuf->s_name[serv_resp->s_name_len - 1] != '\0'
- || resultbuf->s_proto[serv_resp->s_proto_len - 1] != '\0'
- || ({for (cnt = 0; cnt < serv_resp->s_aliases_cnt; ++cnt)
+ if (resultbuf->s_name[serv_resp.s_name_len - 1] != '\0'
+ || resultbuf->s_proto[serv_resp.s_proto_len - 1] != '\0'
+ || ({for (cnt = 0; cnt < serv_resp.s_aliases_cnt; ++cnt)
if (resultbuf->s_aliases[cnt][aliases_len[cnt] - 1]
!= '\0')
break;
- cnt < serv_resp->s_aliases_cnt; }))
- /* We cannot use the database. */
- goto out_close;
+ cnt < serv_resp.s_aliases_cnt; }))
+ {
+ /* We cannot use the database. */
+ if (mapped->head->gc_cycle != gc_cycle)
+ retval = -2;
+ goto out_close;
+ }
retval = 0;
*result = resultbuf;
@@ -287,19 +311,21 @@
if (sock != -1)
close_not_cancel_no_status (sock);
out:
- if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+ if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
{
/* When we come here this means there has been a GC cycle while we
were looking for the data. This means the data might have been
inconsistent. Retry if possible. */
- if ((gc_cycle & 1) != 0 || ++nretries == 5)
+ if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
{
/* nscd is just running gc now. Disable using the mapping. */
- __nscd_unmap (mapped);
+ if (atomic_decrement_val (&mapped->counter) == 0)
+ __nscd_unmap (mapped);
mapped = NO_MAPPING;
}
- goto retry;
+ if (retval != -1)
+ goto retry;
}
return retval;
Modified: trunk/libc/nscd/nscd_helper.c
==============================================================================
--- trunk/libc/nscd/nscd_helper.c (original)
+++ trunk/libc/nscd/nscd_helper.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2002,2003,2004,2005,2006,2007
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 1998.
@@ -21,6 +22,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
+#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
@@ -95,16 +97,20 @@
static int
-open_socket (void)
+open_socket (request_type type, const char *key, size_t keylen)
{
int sock = __socket (PF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
return -1;
+ struct
+ {
+ request_header req;
+ char key[keylen];
+ } reqdata;
+
/* Make socket non-blocking. */
- int fl = __fcntl (sock, F_GETFL);
- if (fl != -1)
- __fcntl (sock, F_SETFL, fl | O_NONBLOCK);
+ __fcntl (sock, F_SETFL, O_RDWR | O_NONBLOCK);
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
@@ -113,13 +119,56 @@
&& errno != EINPROGRESS)
goto out;
- struct pollfd fds[1];
- fds[0].fd = sock;
- fds[0].events = POLLOUT | POLLERR | POLLHUP;
- if (__poll (fds, 1, 5 * 1000) > 0)
- /* Success. We do not check for success of the connect call here.
- If it failed, the following operations will fail. */
- return sock;
+ reqdata.req.version = NSCD_VERSION;
+ reqdata.req.type = type;
+ reqdata.req.key_len = keylen;
+
+ memcpy (reqdata.key, key, keylen);
+
+ bool first_try = true;
+ struct timeval tvend;
+ /* Fake initializing tvend. */
+ asm ("" : "=m" (tvend));
+ while (1)
+ {
+#ifndef MSG_NOSIGNAL
+# define MSG_NOSIGNAL 0
+#endif
+ ssize_t wres = TEMP_FAILURE_RETRY (__send (sock, &reqdata,
+ sizeof (reqdata),
+ MSG_NOSIGNAL));
+ if (__builtin_expect (wres == (ssize_t) sizeof (reqdata), 1))
+ /* We managed to send the request. */
+ return sock;
+
+ if (wres != -1 || errno != EAGAIN)
+ /* Something is really wrong, no chance to continue. */
+ break;
+
+ /* The daemon is busy wait for it. */
+ int to;
+ struct timeval now;
+ (void) __gettimeofday (&now, NULL);
+ if (first_try)
+ {
+ tvend.tv_usec = now.tv_usec;
+ tvend.tv_sec = now.tv_sec + 5;
+ to = 5 * 1000;
+ first_try = false;
+ }
+ else
+ to = ((tvend.tv_sec - now.tv_sec) * 1000
+ + (tvend.tv_usec - now.tv_usec) / 1000);
+
+ struct pollfd fds[1];
+ fds[0].fd = sock;
+ fds[0].events = POLLOUT | POLLERR | POLLHUP;
+ if (__poll (fds, 1, to) <= 0)
+ /* The connection timed out or broke down. */
+ break;
+
+ /* We try to write again. */
+ }
out:
close_not_cancel_no_status (sock);
@@ -179,36 +228,15 @@
int saved_errno = errno;
int mapfd = -1;
-
- /* Send the request. */
- struct
- {
- request_header req;
- char key[keylen];
- } reqdata;
-
- int sock = open_socket ();
+ char resdata[keylen];
+
+ /* Open a socket and send the request. */
+ int sock = open_socket (type, key, keylen);
if (sock < 0)
goto out;
- reqdata.req.version = NSCD_VERSION;
- reqdata.req.type = type;
- reqdata.req.key_len = keylen;
- memcpy (reqdata.key, key, keylen);
-
-# ifndef MSG_NOSIGNAL
-# define MSG_NOSIGNAL 0
-# endif
- if (__builtin_expect (TEMP_FAILURE_RETRY (__send (sock, &reqdata,
- sizeof (reqdata),
- MSG_NOSIGNAL))
- != sizeof (reqdata), 0))
- /* We cannot even write the request. */
- goto out_close2;
-
/* Room for the data sent along with the file descriptor. We expect
the key name back. */
-# define resdata reqdata.key
struct iovec iov[1];
iov[0].iov_base = resdata;
iov[0].iov_len = keylen;
@@ -362,7 +390,10 @@
}
-const struct datahead *
+/* Don't return const struct datahead *, as eventhough the record
+ is normally constant, it can change arbitrarily during nscd
+ garbage collection. */
+struct datahead *
__nscd_cache_search (request_type type, const char *key, size_t keylen,
const struct mapped_database *mapped)
{
@@ -374,15 +405,31 @@
{
struct hashentry *here = (struct hashentry *) (mapped->data + work);
+#ifndef _STRING_ARCH_unaligned
+ /* Although during garbage collection when moving struct hashentry
+ records around we first copy from old to new location and then
+ adjust pointer from previous hashentry to it, there is no barrier
+ between those memory writes. It is very unlikely to hit it,
+ so check alignment only if a misaligned load can crash the
+ application. */
+ if ((uintptr_t) here & (__alignof__ (*here) - 1))
+ return NULL;
+#endif
+
if (type == here->type
&& keylen == here->len
- && here->key + here->len <= datasize
+ && here->key + keylen <= datasize
&& memcmp (key, mapped->data + here->key, keylen) == 0
&& here->packet + sizeof (struct datahead) <= datasize)
{
/* We found the entry. Increment the appropriate counter. */
- const struct datahead *dh
+ struct datahead *dh
= (struct datahead *) (mapped->data + here->packet);
+
+#ifndef _STRING_ARCH_unaligned
+ if ((uintptr_t) dh & (__alignof__ (*dh) - 1))
+ return NULL;
+#endif
/* See whether we must ignore the entry or whether something
is wrong because garbage collection is in progress. */
@@ -402,28 +449,22 @@
__nscd_open_socket (const char *key, size_t keylen, request_type type,
void *response, size_t responselen)
{
+ /* This should never happen and it is something the nscd daemon
+ enforces, too. He it helps to limit the amount of stack
+ used. */
+ if (keylen > MAXKEYLEN)
+ return -1;
+
int saved_errno = errno;
- int sock = open_socket ();
+ int sock = open_socket (type, key, keylen);
if (sock >= 0)
{
- request_header req;
- req.version = NSCD_VERSION;
- req.type = type;
- req.key_len = keylen;
-
- struct iovec vec[2];
- vec[0].iov_base = &req;
- vec[0].iov_len = sizeof (request_header);
- vec[1].iov_base = (void *) key;
- vec[1].iov_len = keylen;
-
- ssize_t nbytes = TEMP_FAILURE_RETRY (__writev (sock, vec, 2));
- if (nbytes == (ssize_t) (sizeof (request_header) + keylen)
- /* Wait for data. */
- && wait_on_socket (sock) > 0)
- {
- nbytes = TEMP_FAILURE_RETRY (__read (sock, response, responselen));
+ /* Wait for data. */
+ if (wait_on_socket (sock) > 0)
+ {
+ ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response,
+ responselen));
if (nbytes == (ssize_t) responselen)
return sock;
}
Modified: trunk/libc/nscd/nscd_initgroups.c
==============================================================================
--- trunk/libc/nscd/nscd_initgroups.c (original)
+++ trunk/libc/nscd/nscd_initgroups.c Mon Feb 5 09:59:45 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2004.
@@ -39,6 +39,7 @@
{
size_t userlen = strlen (user) + 1;
int gc_cycle;
+ int nretries = 0;
/* If the mapping is available, try to search there instead of
communicating with the nscd. */
@@ -46,44 +47,49 @@
mapped = __nscd_get_map_ref (GETFDGR, "group", &__gr_map_handle, &gc_cycle);
retry:;
- const initgr_response_header *initgr_resp = NULL;
char *respdata = NULL;
int retval = -1;
int sock = -1;
+ initgr_response_header initgr_resp;
if (mapped != NO_MAPPING)
{
- const struct datahead *found = __nscd_cache_search (INITGROUPS, user,
- userlen, mapped);
+ struct datahead *found = __nscd_cache_search (INITGROUPS, user,
+ userlen, mapped);
if (found != NULL)
{
- initgr_resp = &found->data[0].initgrdata;
- respdata = (char *) (initgr_resp + 1);
+ respdata = (char *) (&found->data[0].initgrdata + 1);
+ initgr_resp = found->data[0].initgrdata;
char *recend = (char *) found->data + found->recsize;
- if (respdata + initgr_resp->ngrps * sizeof (int32_t) > recend)
+ /* Now check if we can trust initgr_resp fields. If GC is
+ in progress, it can contain anything. */
+ if (mapped->head->gc_cycle != gc_cycle)
+ {
+ retval = -2;
+ goto out;
+ }
+
+ if (respdata + initgr_resp.ngrps * sizeof (int32_t) > recend)
goto out;
}
}
/* If we do not have the cache mapped, try to get the data over the
socket. */
- initgr_response_header initgr_resp_mem;
[... 1654 lines stripped ...]