aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>2016-10-14 14:29:35 -0300
committerTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>2016-10-14 14:29:35 -0300
commitf502fe68475123fc1e9aa57b5bacba6ed5b11f9f (patch)
tree760d54dcfc73dd12a1c1c68a15c6a37bd3b5fcae
parentfb336c7471eef7ded5a7889cac9e031ce7fc28fd (diff)
parente07eca6a72d21a5a37ba33df7b126609db048c41 (diff)
downloadglibc-f502fe68475123fc1e9aa57b5bacba6ed5b11f9f.zip
glibc-f502fe68475123fc1e9aa57b5bacba6ed5b11f9f.tar.gz
glibc-f502fe68475123fc1e9aa57b5bacba6ed5b11f9f.tar.bz2
Merge branch release/2.22/master into ibm/2.22/master
-rw-r--r--ChangeLog312
-rw-r--r--NEWS33
-rw-r--r--argp/argp-fmtstream.h19
-rw-r--r--argp/argp.h42
-rw-r--r--hesiod/Makefile2
-rw-r--r--hesiod/hesiod.c87
-rw-r--r--hesiod/hesiod.h34
-rw-r--r--hesiod/hesiod_p.h26
-rw-r--r--hesiod/nss_hesiod/hesiod-grp.c8
-rw-r--r--hesiod/nss_hesiod/hesiod-init.c38
-rw-r--r--hesiod/nss_hesiod/hesiod-proto.c5
-rw-r--r--hesiod/nss_hesiod/hesiod-pwd.c5
-rw-r--r--hesiod/nss_hesiod/hesiod-service.c5
-rw-r--r--hesiod/nss_hesiod/nss_hesiod.h20
-rw-r--r--libio/iofopncook.c49
-rw-r--r--malloc/Makefile4
-rw-r--r--malloc/arena.c170
-rw-r--r--malloc/malloc.c11
-rw-r--r--malloc/tst-malloc-thread-exit.c218
-rw-r--r--manual/examples/mkdirent.c42
-rw-r--r--manual/pattern.texi39
-rw-r--r--math/atest-exp2.c5
-rw-r--r--nis/nis_call.c20
-rw-r--r--nis/nss_nis/nis-initgroups.c16
-rw-r--r--nptl/pt-fork.c43
-rw-r--r--nptl/tst-once5.cc2
-rw-r--r--nss/nss_db/db-XXX.c12
-rw-r--r--posix/bug-glob2.c16
-rw-r--r--posix/glob.c243
-rw-r--r--posix/tst-gnuglob.c2
-rw-r--r--resolv/base64.c4
-rw-r--r--stdlib/setenv.c26
-rw-r--r--string/tst-endian.c23
-rw-r--r--sunrpc/clnt_udp.c10
-rw-r--r--sysdeps/hppa/start.S2
-rw-r--r--sysdeps/ia64/nptl/Makefile1
-rw-r--r--sysdeps/ieee754/dbl-64/atnat2.h4
-rw-r--r--sysdeps/ieee754/dbl-64/uexp.h2
-rw-r--r--sysdeps/ieee754/dbl-64/upow.h2
-rw-r--r--sysdeps/ieee754/flt-32/e_log10f.c2
-rw-r--r--sysdeps/ieee754/flt-32/k_rem_pio2f.c4
-rw-r--r--sysdeps/ieee754/flt-32/s_cosf.c2
-rw-r--r--sysdeps/ieee754/ldbl-128/e_lgammal_r.c1
-rw-r--r--sysdeps/ieee754/ldbl-128/s_erfl.c1
-rw-r--r--sysdeps/ieee754/ldbl-128/s_log1pl.c1
-rw-r--r--sysdeps/mips/Makefile1
-rw-r--r--sysdeps/mips/nptl/Makefile1
-rw-r--r--sysdeps/posix/getaddrinfo.c130
-rw-r--r--sysdeps/s390/nptl/Makefile1
-rw-r--r--sysdeps/unix/alpha/Makefile1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/Makefile1
-rw-r--r--sysdeps/unix/sysv/linux/arm/setcontext.S7
-rw-r--r--sysdeps/unix/sysv/linux/dl-openat64.c5
-rw-r--r--sysdeps/unix/sysv/linux/i386/Makefile1
-rw-r--r--sysdeps/unix/sysv/linux/i386/glob64.c22
-rw-r--r--sysdeps/unix/sysv/linux/ia64/Makefile1
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/Makefile3
-rw-r--r--sysdeps/unix/sysv/linux/mips/vfork.S14
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/s390/Makefile1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S10
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S10
-rw-r--r--sysdeps/unix/sysv/linux/tile/Makefile1
-rw-r--r--timezone/private.h10
65 files changed, 1281 insertions, 556 deletions
diff --git a/ChangeLog b/ChangeLog
index 3d88d79..b67fcff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,318 @@
* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
(lll_unlock_elision): Likewise
+2016-08-17 Florian Weimer <fweimer@redhat.com>
+
+ Reduce time to expected nptl/tst-once5 failure.
+ * nptl/tst-once5.cc (TIMEOUT): Define.
+
+2016-08-18 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #16907]
+ * argp/argp.h: Switch to __BEGIN_DECLS and __END_DECLS.
+ (__THROW, __NTH, __attribute__, __restrict): Remove definitions.
+ * argp/argp-fmtstream.h: Add __BEGIN_DECLS and __END_DECLS.
+ (__attribute__): Remove definition.
+
+2016-06-11 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #20222]
+ * libio/iofopncook.c (_IO_cookie_read): Demangle callback pointer.
+ (_IO_cookie_write): Likewise.
+ (_IO_cookie_seek): Likewise.
+ (_IO_cookie_close): Likewise.
+ (_IO_old_cookie_seek): Likewise.
+ (set_callbacks): New function.
+ (_IO_cookie_init): Call set_callbacks to copy callbacks.
+
+2016-03-29 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #19837]
+ * nss/nss_db/db-XXX.c (_nss_db_getENTNAME_r): Propagate ERANGE
+ error if parse_line fails.
+
+2016-06-11 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #20237]
+ * nss/nss_db/db-XXX.c (set*ent): Reset entidx to NULL.
+ (get*ent): Set entidx to NULL during initialization. If entidx is
+ NULL, start iteration from the beginning.
+
+2016-06-30 Andreas Schwab <schwab@suse.de>
+
+ [BZ #20262]
+ * nis/nss_nis/nis-initgroups.c (_nss_nis_initgroups_dyn): Return
+ NSS_STATUS_SUCCESS when done. Return NSS_STATUS_TRYAGAIN when out
+ of memory.
+
+2016-08-15 Andreas Schwab <schwab@suse.de>
+
+ [BZ #20435]
+ * sysdeps/unix/sysv/linux/arm/setcontext.S (__startcontext): Mark
+ as .cantunwind.
+
+2016-06-21 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #20284]
+ * malloc/arena.c (reused_arena): Do not return NULL if we start
+ out with a non-corrupted arena.
+
+2016-08-17 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #20452]
+ Avoid additional copies of objects in libc.a in static libraries.
+ * sysdeps/ia64/nptl/Makefile (libpthread-shared-only-routines):
+ Add ptw-sysdep, ptw-sigblock, ptw-sigprocmask.
+ * sysdeps/mips/Makefile (librt-shared-only-routines): Add
+ rt-sysdep.
+ * sysdeps/mips/nptl/Makefile (libpthread-shared-only-routines):
+ Add nptl-sysdep.
+ * sysdeps/s390/nptl/Makefile (libpthread-shared-only-routines):
+ Add ptw-sysdep.
+ * sysdeps/unix/alpha/Makefile (librt-shared-only-routines): Add
+ rt-sysdep.
+ * sysdeps/unix/sysv/linux/alpha/Makefile
+ (libpthread-shared-only-routines): Add ptw-sysdep,
+ ptw-sigprocmask, ptw-rt_sigaction.
+ * sysdeps/unix/sysv/linux/ia64/Makefile
+ (librt-shared-only-routines): Add rt-sysdep.
+ * sysdeps/unix/sysv/linux/i386/Makefile
+ (libpthread-shared-only-routines): Add libc-do-syscall.
+ * sysdeps/unix/sysv/linux/microblaze/Makefile
+ (libpthread-shared-only-routines): Add sysdep.
+ * sysdeps/unix/sysv/linux/powerpc/Makefile
+ (librt-shared-only-routines): Add rt-sysdep.
+ (libpthread-shared-only-routines): Add sysdep.
+ * sysdeps/unix/sysv/linux/s390/Makefile
+ (librt-shared-only-routines): Add rt-sysdep.
+ * sysdeps/unix/sysv/linux/sparc/Makefile
+ (librt-shared-only-routines): Add rt-sysdep.
+ (libpthread-shared-only-routines): Add sysdep.
+ * sysdeps/unix/sysv/linux/tile/Makefile
+ (libpthread-shared-only-routines): Likewise.
+
+2016-08-02 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #20370]
+ * malloc/arena.c (get_free_list): Update comment. Assert that
+ arenas on the free list have no attached threads.
+ (remove_from_free_list): New function.
+ (reused_arena): Call it.
+
+2016-06-30 John David Anglin <danglin@gcc.gnu.org>
+
+ [BZ #20277]
+ * sysdeps/hppa/start.S (_start): Correct loading of global pointer
+ when SHARED is defined.
+
+2016-06-21 Aurelien Jarno <aurelien@aurel32.net>
+
+ * sysdeps/unix/sysv/linux/mips/vfork.S (__vfork): Rename into
+ __libc_vfork.
+ (__vfork) [IS_IN (libc)]: Remove alias.
+ (__libc_vfork) [IS_IN (libc)]: Define as an alias.
+ * sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise.
+
+2016-06-18 Aurelien Jarno <aurelien@aurel32.net>
+
+ * sysdeps/unix/sysv/linux/mips/vfork.S (__vfork): Conditionalize
+ hidden_def, weak_alias and strong_alias on [IS_IN (libc)].
+ * sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise.
+
+2016-01-22 Stefan Liebler <stli@linux.vnet.ibm.com>
+
+ * string/tst-endian.c: Include <libc-internal.h>.
+ (do_test): Ignore tautological-compare warnings around
+ "htobeXX (beXXtoh (i)) != i" and
+ "htoleXX (leXXtoh (i)) != i" if-statements.
+
+2015-12-18 Torvald Riegel <triegel@redhat.com>
+
+ * math/atest-exp2.c (mp_exp_m1): Remove.
+
+2016-06-02 Florian Weimer <fweimer@redhat.com>
+
+ * sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Convert to
+ ISO-style variadic function definition.
+
+2015-12-11 Steve Ellcey <sellcey@imgtec.com>
+
+ * sysdeps/ieee754/flt-32/k_rem_pio2f.c (__kernel_rem_pio2f):
+ Fix indentation.
+
+2015-09-18 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * resolv/base64.c (rcsid): Remove unused static.
+ * sysdeps/ieee754/dbl-64/atnat2.h (qpi1): Remove unused
+ static. (tqpi1): Likewise.
+ * sysdeps/ieee754/dbl-64/uexp.h (one): Likewise.
+ * sysdeps/ieee754/dbl-64/upow.h (sqrt_2): Likewise.
+ * sysdeps/ieee754/flt-32/e_log10f.c (one): Likewise.
+ * sysdeps/ieee754/flt-32/s_cosf.c (one): Likewise.
+ * sysdeps/ieee754/ldbl-128/e_lgammal_r.c (zero): Likewise.
+ * sysdeps/ieee754/ldbl-128/s_erfl.c (half): Likewise.
+ * sysdeps/ieee754/ldbl-128/s_log1pl.c (maxlog): Likewise.
+ * timezone/private.h (time_t_min): Likewise. (time_t_max):
+ Likewise.
+
+2016-04-15 Yvan Roux <yvan.roux@linaro.org>
+
+ * stdlib/setenv.c (unsetenv): Fix ambiguous 'else'.
+ * nis/nis_call.c (nis_server_cache_add): Likewise.
+
+2016-06-01 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #19861]
+ Do not use IFUNC resolver with potentially unrelocated symbol.
+ * nptl/pt-fork.c [HAVE_IFUNC]: Remove.
+ (DEFINE_FORK): Remove macro and inline definition.
+ (fork_alias): Renamed from fork_ifunc.
+ (__fork_alias): Renamed from __fork_ifunc.
+
+2016-05-23 Florian Weimer <fweimer@redhat.com>
+
+ CVE-2016-4429
+ [BZ #20112]
+ * sunrpc/clnt_udp.c (clntudp_call): Use malloc/free for the error
+ payload.
+
+2016-05-02 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #19573]
+ * hesiod/Makefile (libnss_hesiod-routines): Remove hesiod-init.
+ * hesiod/nss_hesiod/hesiod-init.c: Remove file.
+ * hesiod/nss_hesiod/nss_hesiod.h: Likewise.
+ * hesiod/hesiod.h (__hesiod_res_get, __hesiod_res_set): Remove.
+ (hesiod_init, hesiod_end, hesiod_to_bind, hesiod_resolve)
+ (hesiod_free_list): Mark as hidden.
+ * hesiod/hesiod_p (struct hesiod_p): Remove res, free_res,
+ res_set, res_get.
+ * hesiod/hesiod.c: Remove unnecessary forward declarations.
+ (init, __hesiod_res_get, __hesiod_res_set): Remove.
+ (hesiod_init): Remove obsolete res_ninit call.
+ (hesiod_end): Do not free resolver state. Do not invoke callback.
+ (hesiod_bind): Do not call init.
+ (get_txt_records): Use res_mkquery, res_send instead of
+ res_nmkquery, res_nsend.
+ * hesiod/nss_hesiod/hesiod-grp.c (lookup): Call hesiod_init
+ instead of _nss_hesiod_init.
+ (_nss_hesiod_initgroups_dyn): Likewise.
+ * hesiod/nss_hesiod/hesiod-proto.c (lookup): Likewise.
+ * hesiod/nss_hesiod/hesiod-pwd.c (lookup): Likewise.
+ * hesiod/nss_hesiod/hesiod-service.c (lookup): Likewise.
+
+2016-05-02 Florian Weimer <fweimer@redhat.com>
+
+ * hesiod/hesiod.h: Remove RCS keyword.
+ * hesiod/hesiod_p.h: Likewise.
+ * hesiod/hesiod.c: Likewise.
+
+2016-04-29 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #20010]
+ CVE-2016-3706
+ * sysdeps/posix/getaddrinfo.c
+ (convert_hostent_to_gaih_addrtuple): New function.
+ (gethosts): Call convert_hostent_to_gaih_addrtuple.
+ (gaih_inet): Use convert_hostent_to_gaih_addrtuple to convert
+ AF_INET data.
+
+2016-05-04 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #19779]
+ CVE-2016-1234
+ Avoid copying names of directory entries.
+ * posix/glob.c (DIRENT_MUST_BE, DIRENT_MIGHT_BE_SYMLINK)
+ (DIRENT_MIGHT_BE_DIR, CONVERT_D_INO, CONVERT_D_TYPE)
+ (CONVERT_DIRENT_DIRENT64, REAL_DIR_ENTRY): Remove macros.
+ (struct readdir_result): New type.
+ (D_TYPE_TO_RESULT, D_INO_TO_RESULT, READDIR_RESULT_INITIALIZER)
+ (GL_READDIR): New macros.
+ (readdir_result_might_be_symlink, readdir_result_might_be_dir)
+ (convert_dirent, convert_dirent64): New functions.
+ (glob_in_dir): Use struct readdir_result. Call convert_dirent or
+ convert_dirent64. Adjust references to the readdir result.
+ * sysdeps/unix/sysv/linux/i386/glob64.c:
+ (convert_dirent, GL_READDIR): Redefine for second file inclusion.
+ * posix/bug-glob2.c (LONG_NAME): Define.
+ (filesystem): Add LONG_NAME.
+ (my_DIR): Increase the size of room_for_dirent.
+
+2016-04-29 Florian Weimer <fweimer@redhat.com>
+
+ glob: Simplify and document the interface for the GLOB_ALTDIRFUNC
+ callback function gl_readdir.
+ * posix/glob.c (NAMELEN, CONVERT_D_NAMLEN): Remove.
+ (CONVERT_DIRENT_DIRENT64): Use strcpy instead of memcpy.
+ (glob_in_dir): Remove len. Use strdup instead of malloc and
+ memcpy to copy the name.
+ * manual/pattern.texi (Calling Glob): Document requirements for
+ implementations of the gl_readdir callback function.
+ * manual/examples/mkdirent.c: New example.
+ * posix/bug-glob2.c (my_readdir): Set d_ino to 1 unconditionally,
+ per the manual guidance.
+ * posix/tst-gnuglob.c (my_readdir): Likewise.
+
+2016-04-13 Florian Weimer <fweimer@redhat.com>
+
+ * malloc/arena.c (list_lock): Update comment.
+
+2016-04-13 Florian Weimer <fweimer@redhat.com>
+
+ * malloc/tst-malloc-thread-exit.c: Include test-skeleton.c early.
+ (do_test): Limit the number of arenas, so that we can use fewer
+ outer threads. Limit timeout to 3 seconds, in preparation for a
+ larger TIMEOUT value.
+
+2016-04-13 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #19182]
+ * malloc/arena.c (list_lock): Document lock ordering requirements.
+ (free_list_lock): New lock.
+ (ptmalloc_lock_all): Comment on free_list_lock.
+ (ptmalloc_unlock_all2): Reinitialize free_list_lock.
+ (detach_arena): Update comment. free_list_lock is now needed.
+ (_int_new_arena): Use free_list_lock around detach_arena call.
+ Acquire arena lock after list_lock. Add comment, including FIXME
+ about incorrect synchronization.
+ (get_free_list): Switch to free_list_lock.
+ (reused_arena): Acquire free_list_lock around detach_arena call
+ and attached threads counter update. Add two FIXMEs about
+ incorrect synchronization.
+ (arena_thread_freeres): Switch to free_list_lock.
+ * malloc/malloc.c (struct malloc_state): Update comments to
+ mention free_list_lock.
+
+2016-04-13 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #19243]
+ * malloc/arena.c (get_free_list): Remove assert and adjust
+ reference count handling. Add comment about reused_arena
+ interaction.
+ (reused_arena): Add comments abount get_free_list interaction.
+ * malloc/tst-malloc-thread-exit.c: New file.
+ * malloc/Makefile (tests): Add tst-malloc-thread-exit.
+ (tst-malloc-thread-exit): Link against libpthread.
+
+2016-04-13 Florian Weimer <fweimer@redhat.com>
+
+ [BZ# 19048]
+ * malloc/malloc.c (struct malloc_state): Update comment. Add
+ attached_threads member.
+ (main_arena): Initialize attached_threads.
+ * malloc/arena.c (list_lock): Update comment.
+ (ptmalloc_lock_all, ptmalloc_unlock_all): Likewise.
+ (ptmalloc_unlock_all2): Reinitialize arena reference counts.
+ (deattach_arena): New function.
+ (_int_new_arena): Initialize arena reference count and deattach
+ replaced arena.
+ (get_free_list, reused_arena): Update reference count and deattach
+ replaced arena.
+ (arena_thread_freeres): Update arena reference count and only put
+ unreferenced arenas on the free list.
+
2016-04-12 Paul E. Murphy <murphyp@linux.vnet.ibm.com>
[BZ #19853]
diff --git a/NEWS b/NEWS
index 2a43aec..a19f656 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,12 @@ using `glibc' in the "product" field.
Version 2.22.1
+* On ARM EABI (32-bit), generating a backtrace for execution contexts which
+ have been created with makecontext could fail to terminate due to a
+ missing .cantunwind annotation. This has been observed to lead to a hang
+ (denial of service) in some Go applications compiled with gccgo. Reported
+ by Andreas Schwab. (CVE-2016-6323)
+
* A stack-based buffer overflow was found in libresolv when invoked from
libnss_dns, allowing specially crafted DNS responses to seize control
of execution flow in the DNS client. The buffer overflow occurs in
@@ -24,8 +30,9 @@ Version 2.22.1
* The following bugs are resolved with this release:
17905, 18420, 18421, 18480, 18589, 18743, 18778, 18781, 18787, 18796,
- 18870, 18887, 18921, 18928, 18969, 18985, 19003, 19018, 19058, 19174,
- 19178, 19590, 19682, 19791, 19822, 19853, 19879.
+ 18870, 18887, 18921, 18928, 18969, 18985, 19003, 19018, 19048, 19058,
+ 19174, 19178, 19182, 19243, 19573, 19590, 19682, 19791, 19822, 19853,
+ 19879, 19779, 20010, 20112, 20277.
* The getnetbyname implementation in nss_dns had a potentially unbounded
alloca call (in the form of a call to strdupa), leading to a stack
@@ -34,6 +41,28 @@ Version 2.22.1
* The LD_POINTER_GUARD environment variable can no longer be used to
disable the pointer guard feature. It is always enabled.
+
+* A defect in the malloc implementation, present since glibc 2.15 (2012) or
+ glibc 2.10 via --enable-experimental-malloc (2009), could result in the
+ unnecessary serialization of memory allocation requests across threads.
+ The defect is now corrected. Users should see a substantial increase in
+ the concurent throughput of allocation requests for applications which
+ trigger this bug. Affected applications typically create create and
+ destroy threads frequently. (Bug 19048 was reported and analyzed by
+ Ericsson.)
+
+* The glob function suffered from a stack-based buffer overflow when it was
+ called with the GLOB_ALTDIRFUNC flag and encountered a long file name.
+ Reported by Alexander Cherepanov. (CVE-2016-1234)
+
+* Previously, getaddrinfo copied large amounts of address data to the stack,
+ even after the fix for CVE-2013-4458 has been applied, potentially
+ resulting in a stack overflow. getaddrinfo now uses a heap allocation
+ instead. Reported by Michael Petlan. (CVE-2016-3706)
+
+* The Sun RPC UDP client could exhaust all available stack space when
+ flooded with crafted ICMP and UDP messages. Reported by Aldy Hernandez'
+ alloca plugin for GCC. (CVE-2016-4429)
Version 2.22
diff --git a/argp/argp-fmtstream.h b/argp/argp-fmtstream.h
index 6dd087a..8f8192a 100644
--- a/argp/argp-fmtstream.h
+++ b/argp/argp-fmtstream.h
@@ -29,21 +29,6 @@
#include <string.h>
#include <unistd.h>
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || \
- defined __STRICT_ANSI__
-# define __attribute__(Spec) /* empty */
-# endif
-/* The __-protected variants of `format' and `printf' attributes
- are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || \
- defined __STRICT_ANSI__
-# define __format__ format
-# define __printf__ printf
-# endif
-#endif
-
#if defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)
/* line_wrap_stream is available, so use that. */
#define ARGP_FMTSTREAM_USE_LINEWRAP
@@ -111,6 +96,8 @@ struct argp_fmtstream
typedef struct argp_fmtstream *argp_fmtstream_t;
+__BEGIN_DECLS
+
/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
written on it with LMARGIN spaces and limits them to RMARGIN columns
total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
@@ -297,6 +284,8 @@ __argp_fmtstream_point (argp_fmtstream_t __fs)
#endif /* __OPTIMIZE__ */
+__END_DECLS
+
#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
#endif /* argp-fmtstream.h */
diff --git a/argp/argp.h b/argp/argp.h
index 40bf5e6..0771921 100644
--- a/argp/argp.h
+++ b/argp/argp.h
@@ -28,48 +28,12 @@
#define __need_error_t
#include <errno.h>
-#ifndef __THROW
-# define __THROW
-#endif
-#ifndef __NTH
-# define __NTH(fct) fct __THROW
-#endif
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || \
- defined __STRICT_ANSI__
-# define __attribute__(Spec) /* empty */
-# endif
-/* The __-protected variants of `format' and `printf' attributes
- are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || \
- defined __STRICT_ANSI__
-# define __format__ format
-# define __printf__ printf
-# endif
-#endif
-
-/* GCC 2.95 and later have "__restrict"; C99 compilers have
- "restrict", and "configure" may have defined "restrict". */
-#ifndef __restrict
-# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
-# if defined restrict || 199901L <= __STDC_VERSION__
-# define __restrict restrict
-# else
-# define __restrict
-# endif
-# endif
-#endif
-
#ifndef __error_t_defined
typedef int error_t;
# define __error_t_defined
#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
/* A description of a particular option. A pointer to an array of
these is passed in the OPTIONS field of an argp structure. Each option
@@ -590,8 +554,6 @@ __NTH (__option_is_end (const struct argp_option *__opt))
# endif
#endif /* Use extern inlines. */
-#ifdef __cplusplus
-}
-#endif
+__END_DECLS
#endif /* argp.h */
diff --git a/hesiod/Makefile b/hesiod/Makefile
index ac0bc01..cdd7730 100644
--- a/hesiod/Makefile
+++ b/hesiod/Makefile
@@ -28,7 +28,7 @@ extra-libs-others = $(extra-libs)
subdir-dirs = nss_hesiod
vpath %.c nss_hesiod
-libnss_hesiod-routines := hesiod hesiod-grp hesiod-init hesiod-proto \
+libnss_hesiod-routines := hesiod hesiod-grp hesiod-proto \
hesiod-pwd hesiod-service
# Build only shared library
libnss_hesiod-inhibit-o = $(filter-out .os,$(object-suffixes))
diff --git a/hesiod/hesiod.c b/hesiod/hesiod.c
index 657dabe..5b13b3f 100644
--- a/hesiod/hesiod.c
+++ b/hesiod/hesiod.c
@@ -1,6 +1,19 @@
-#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$BINDId: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie Exp $";
-#endif
+/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
@@ -52,18 +65,9 @@ static const char rcsid[] = "$BINDId: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie
/* Forward */
-int hesiod_init(void **context);
-void hesiod_end(void *context);
-char * hesiod_to_bind(void *context, const char *name,
- const char *type);
-char ** hesiod_resolve(void *context, const char *name,
- const char *type);
-void hesiod_free_list(void *context, char **list);
-
static int parse_config_file(struct hesiod_p *ctx, const char *filename);
static char ** get_txt_records(struct hesiod_p *ctx, int class,
const char *name);
-static int init(struct hesiod_p *ctx);
/* Public */
@@ -82,7 +86,6 @@ hesiod_init(void **context) {
ctx->LHS = NULL;
ctx->RHS = NULL;
- ctx->res = NULL;
/* Set default query classes. */
ctx->classes[0] = C_IN;
ctx->classes[1] = C_HS;
@@ -131,11 +134,6 @@ hesiod_init(void **context) {
goto cleanup;
}
-#if 0
- if (res_ninit(ctx->res) < 0)
- goto cleanup;
-#endif
-
*context = ctx;
return (0);
@@ -152,12 +150,8 @@ hesiod_end(void *context) {
struct hesiod_p *ctx = (struct hesiod_p *) context;
int save_errno = errno;
- if (ctx->res)
- res_nclose(ctx->res);
free(ctx->RHS);
free(ctx->LHS);
- if (ctx->res && ctx->free_res)
- (*ctx->free_res)(ctx->res);
free(ctx);
__set_errno(save_errno);
}
@@ -232,10 +226,6 @@ hesiod_resolve(void *context, const char *name, const char *type) {
if (bindname == NULL)
return (NULL);
- if (init(ctx) == -1) {
- free(bindname);
- return (NULL);
- }
retvec = get_txt_records(ctx, ctx->classes[0], bindname);
@@ -365,13 +355,13 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
/*
* Construct the query and send it.
*/
- n = res_nmkquery(ctx->res, QUERY, name, class, T_TXT, NULL, 0,
+ n = res_mkquery(QUERY, name, class, T_TXT, NULL, 0,
NULL, qbuf, MAX_HESRESP);
if (n < 0) {
__set_errno(EMSGSIZE);
return (NULL);
}
- n = res_nsend(ctx->res, qbuf, n, abuf, MAX_HESRESP);
+ n = res_send(qbuf, n, abuf, MAX_HESRESP);
if (n < 0) {
__set_errno(ECONNREFUSED);
return (NULL);
@@ -464,44 +454,3 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
free(list);
return (NULL);
}
-
-struct __res_state *
-__hesiod_res_get(void *context) {
- struct hesiod_p *ctx = context;
-
- if (!ctx->res) {
- struct __res_state *res;
- res = (struct __res_state *)calloc(1, sizeof *res);
- if (res == NULL)
- return (NULL);
- __hesiod_res_set(ctx, res, free);
- }
-
- return (ctx->res);
-}
-
-void
-__hesiod_res_set(void *context, struct __res_state *res,
- void (*free_res)(void *)) {
- struct hesiod_p *ctx = context;
-
- if (ctx->res && ctx->free_res) {
- res_nclose(ctx->res);
- (*ctx->free_res)(ctx->res);
- }
-
- ctx->res = res;
- ctx->free_res = free_res;
-}
-
-static int
-init(struct hesiod_p *ctx) {
-
- if (!ctx->res && !__hesiod_res_get(ctx))
- return (-1);
-
- if (__res_maybe_init (ctx->res, 0) == -1)
- return (-1);
-
- return (0);
-}
diff --git a/hesiod/hesiod.h b/hesiod/hesiod.h
index 82fce30..c4f5356 100644
--- a/hesiod/hesiod.h
+++ b/hesiod/hesiod.h
@@ -1,3 +1,20 @@
+/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
@@ -19,22 +36,15 @@
* This file is primarily maintained by <tytso@mit.edu> and <ghudson@mit.edu>.
*/
-/*
- * $BINDId: hesiod.h,v 1.7 1999/01/08 19:22:45 vixie Exp $
- */
-
#ifndef _HESIOD_H_INCLUDED
#define _HESIOD_H_INCLUDED
-int hesiod_init (void **context);
-void hesiod_end (void *context);
+int hesiod_init (void **context) attribute_hidden;
+void hesiod_end (void *context) attribute_hidden;
char * hesiod_to_bind (void *context, const char *name,
- const char *type);
+ const char *type) attribute_hidden;
char ** hesiod_resolve (void *context, const char *name,
- const char *type);
-void hesiod_free_list (void *context, char **list);
-struct __res_state * __hesiod_res_get (void *context);
-void __hesiod_res_set (void *context, struct __res_state *,
- void (*)(void *));
+ const char *type) attribute_hidden;
+void hesiod_free_list (void *context, char **list) attribute_hidden;
#endif /*_HESIOD_H_INCLUDED*/
diff --git a/hesiod/hesiod_p.h b/hesiod/hesiod_p.h
index 5010d71..1d6d826 100644
--- a/hesiod/hesiod_p.h
+++ b/hesiod/hesiod_p.h
@@ -1,3 +1,20 @@
+/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
@@ -20,10 +37,6 @@
*/
/*
- * $BINDId: hesiod_p.h,v 1.9 1999/01/08 19:24:39 vixie Exp $
- */
-
-/*
* hesiod_p.h -- private definitions for the hesiod library
*/
@@ -36,11 +49,6 @@
struct hesiod_p {
char * LHS; /* normally ".ns" */
char * RHS; /* AKA the default hesiod domain */
- struct __res_state * res; /* resolver context */
- void (*free_res)(void *);
- void (*res_set)(struct hesiod_p *, struct __res_state *,
- void (*)(void *));
- struct __res_state * (*res_get)(struct hesiod_p *);
int classes[2]; /* The class search order. */
};
diff --git a/hesiod/nss_hesiod/hesiod-grp.c b/hesiod/nss_hesiod/hesiod-grp.c
index 0909a85..6ccb3bb 100644
--- a/hesiod/nss_hesiod/hesiod-grp.c
+++ b/hesiod/nss_hesiod/hesiod-grp.c
@@ -26,8 +26,6 @@
#include <string.h>
#include <sys/param.h>
-#include "nss_hesiod.h"
-
/* Get the declaration of the parser function. */
#define ENTNAME grent
#define STRUCTURE group
@@ -58,8 +56,7 @@ lookup (const char *name, const char *type, struct group *grp,
size_t len;
int olderr = errno;
- context = _nss_hesiod_init ();
- if (context == NULL)
+ if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, name, type);
@@ -179,8 +176,7 @@ _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
gid_t *groups = *groupsp;
int save_errno;
- context = _nss_hesiod_init ();
- if (context == NULL)
+ if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, user, "grplist");
diff --git a/hesiod/nss_hesiod/hesiod-init.c b/hesiod/nss_hesiod/hesiod-init.c
deleted file mode 100644
index 755d3ad..0000000
--- a/hesiod/nss_hesiod/hesiod-init.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 2000.
-
- 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <sys/cdefs.h> /* Needs to come before <hesiod.h>. */
-#include <hesiod.h>
-#include <resolv.h>
-#include <stddef.h>
-
-#include "nss_hesiod.h"
-
-void *
-_nss_hesiod_init (void)
-{
- void *context;
-
- if (hesiod_init (&context) == -1)
- return NULL;
-
- /* Use the default (per-thread) resolver state. */
- __hesiod_res_set (context, &_res, NULL);
-
- return context;
-}
diff --git a/hesiod/nss_hesiod/hesiod-proto.c b/hesiod/nss_hesiod/hesiod-proto.c
index 4073ee3..fcb09d1 100644
--- a/hesiod/nss_hesiod/hesiod-proto.c
+++ b/hesiod/nss_hesiod/hesiod-proto.c
@@ -25,8 +25,6 @@
#include <stdlib.h>
#include <string.h>
-#include "nss_hesiod.h"
-
/* Declare a parser for Hesiod protocol entries. Although the format
of the entries is identical to those in /etc/protocols, here is no
predefined parser for us to use. */
@@ -68,8 +66,7 @@ lookup (const char *name, const char *type, struct protoent *proto,
int found;
int olderr = errno;
- context = _nss_hesiod_init ();
- if (context == NULL)
+ if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, name, type);
diff --git a/hesiod/nss_hesiod/hesiod-pwd.c b/hesiod/nss_hesiod/hesiod-pwd.c
index 94a8666..948a575 100644
--- a/hesiod/nss_hesiod/hesiod-pwd.c
+++ b/hesiod/nss_hesiod/hesiod-pwd.c
@@ -24,8 +24,6 @@
#include <stdlib.h>
#include <string.h>
-#include "nss_hesiod.h"
-
/* Get the declaration of the parser function. */
#define ENTNAME pwent
#define STRUCTURE passwd
@@ -56,8 +54,7 @@ lookup (const char *name, const char *type, struct passwd *pwd,
size_t len;
int olderr = errno;
- context = _nss_hesiod_init ();
- if (context == NULL)
+ if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, name, type);
diff --git a/hesiod/nss_hesiod/hesiod-service.c b/hesiod/nss_hesiod/hesiod-service.c
index 0e53b77..dc89c2d 100644
--- a/hesiod/nss_hesiod/hesiod-service.c
+++ b/hesiod/nss_hesiod/hesiod-service.c
@@ -25,8 +25,6 @@
#include <stdlib.h>
#include <string.h>
-#include "nss_hesiod.h"
-
/* Hesiod uses a format for service entries that differs from the
traditional format. We therefore declare our own parser. */
@@ -69,8 +67,7 @@ lookup (const char *name, const char *type, const char *protocol,
int found;
int olderr = errno;
- context = _nss_hesiod_init ();
- if (context == NULL)
+ if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, name, type);
diff --git a/hesiod/nss_hesiod/nss_hesiod.h b/hesiod/nss_hesiod/nss_hesiod.h
deleted file mode 100644
index 79115e0..0000000
--- a/hesiod/nss_hesiod/nss_hesiod.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 2000.
-
- 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, see
- <http://www.gnu.org/licenses/>. */
-
-/* Initialize a Hesiod context. */
-extern void *_nss_hesiod_init (void);
diff --git a/libio/iofopncook.c b/libio/iofopncook.c
index b845d29..3aad3d3 100644
--- a/libio/iofopncook.c
+++ b/libio/iofopncook.c
@@ -46,11 +46,13 @@ _IO_cookie_read (fp, buf, size)
_IO_ssize_t size;
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
+ cookie_read_function_t *read_cb = cfile->__io_functions.read;
+ PTR_DEMANGLE (read_cb);
- if (cfile->__io_functions.read == NULL)
+ if (read_cb == NULL)
return -1;
- return cfile->__io_functions.read (cfile->__cookie, buf, size);
+ return read_cb (cfile->__cookie, buf, size);
}
static _IO_ssize_t
@@ -60,14 +62,16 @@ _IO_cookie_write (fp, buf, size)
_IO_ssize_t size;
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
+ cookie_write_function_t *write_cb = cfile->__io_functions.write;
+ PTR_DEMANGLE (write_cb);
- if (cfile->__io_functions.write == NULL)
+ if (write_cb == NULL)
{
fp->_flags |= _IO_ERR_SEEN;
return 0;
}
- _IO_ssize_t n = cfile->__io_functions.write (cfile->__cookie, buf, size);
+ _IO_ssize_t n = write_cb (cfile->__cookie, buf, size);
if (n < size)
fp->_flags |= _IO_ERR_SEEN;
@@ -81,9 +85,11 @@ _IO_cookie_seek (fp, offset, dir)
int dir;
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
+ cookie_seek_function_t *seek_cb = cfile->__io_functions.seek;
+ PTR_DEMANGLE (seek_cb);
- return ((cfile->__io_functions.seek == NULL
- || (cfile->__io_functions.seek (cfile->__cookie, &offset, dir)
+ return ((seek_cb == NULL
+ || (seek_cb (cfile->__cookie, &offset, dir)
== -1)
|| offset == (_IO_off64_t) -1)
? _IO_pos_BAD : offset);
@@ -94,11 +100,13 @@ _IO_cookie_close (fp)
_IO_FILE *fp;
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
+ cookie_close_function_t *close_cb = cfile->__io_functions.close;
+ PTR_DEMANGLE (close_cb);
- if (cfile->__io_functions.close == NULL)
+ if (close_cb == NULL)
return 0;
- return cfile->__io_functions.close (cfile->__cookie);
+ return close_cb (cfile->__cookie);
}
@@ -140,6 +148,19 @@ static const struct _IO_jump_t _IO_cookie_jumps = {
};
+/* Copy the callbacks from SOURCE to *TARGET, with pointer
+ mangling. */
+static void
+set_callbacks (_IO_cookie_io_functions_t *target,
+ _IO_cookie_io_functions_t source)
+{
+ PTR_MANGLE (source.read);
+ PTR_MANGLE (source.write);
+ PTR_MANGLE (source.seek);
+ PTR_MANGLE (source.close);
+ *target = source;
+}
+
void
_IO_cookie_init (struct _IO_cookie_file *cfile, int read_write,
void *cookie, _IO_cookie_io_functions_t io_functions)
@@ -148,7 +169,7 @@ _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write,
_IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps;
cfile->__cookie = cookie;
- cfile->__io_functions = io_functions;
+ set_callbacks (&cfile->__io_functions, io_functions);
_IO_file_init (&cfile->__fp);
@@ -223,14 +244,14 @@ _IO_old_cookie_seek (fp, offset, dir)
int dir;
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
- int (*seek) (_IO_FILE *, _IO_off_t, int);
- int ret;
+ int (*seek_cb) (_IO_FILE *, _IO_off_t, int)
+ = (int (*) (_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;;
+ PTR_DEMANGLE (seek_cb);
- seek = (int (*)(_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;
- if (seek == NULL)
+ if (seek_cb == NULL)
return _IO_pos_BAD;
- ret = seek (cfile->__cookie, offset, dir);
+ int ret = seek_cb (cfile->__cookie, offset, dir);
return (ret == -1) ? _IO_pos_BAD : ret;
}
diff --git a/malloc/Makefile b/malloc/Makefile
index 67ed293..aa0579c 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -28,7 +28,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \
tst-malloc-usable tst-realloc tst-posix_memalign \
tst-pvalloc tst-memalign tst-mallopt tst-scratch_buffer \
- tst-malloc-backtrace
+ tst-malloc-backtrace tst-malloc-thread-exit
test-srcs = tst-mtrace
routines = malloc morecore mcheck mtrace obstack \
@@ -47,6 +47,8 @@ libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
$(objpfx)tst-malloc-backtrace: $(common-objpfx)nptl/libpthread.so \
$(common-objpfx)nptl/libpthread_nonshared.a
+$(objpfx)tst-malloc-thread-exit: $(common-objpfx)nptl/libpthread.so \
+ $(common-objpfx)nptl/libpthread_nonshared.a
# These should be removed by `make clean'.
extra-objs = mcheck-init.o libmcheck.a
diff --git a/malloc/arena.c b/malloc/arena.c
index 21ecc5a1..5350992 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -67,10 +67,30 @@ extern int sanity_check_heap_info_alignment[(sizeof (heap_info)
/* Thread specific data */
static tsd_key_t arena_key;
-static mutex_t list_lock = MUTEX_INITIALIZER;
+
+/* Arena free list. free_list_lock synchronizes access to the
+ free_list variable below, and the next_free and attached_threads
+ members of struct malloc_state objects. No other locks must be
+ acquired after free_list_lock has been acquired. */
+
+static mutex_t free_list_lock = MUTEX_INITIALIZER;
static size_t narenas = 1;
static mstate free_list;
+/* list_lock prevents concurrent writes to the next member of struct
+ malloc_state objects.
+
+ Read access to the next member is supposed to synchronize with the
+ atomic_write_barrier and the write to the next member in
+ _int_new_arena. This suffers from data races; see the FIXME
+ comments in _int_new_arena and reused_arena.
+
+ list_lock also prevents concurrent forks. At the time list_lock is
+ acquired, no arena lock must have been acquired, but it is
+ permitted to acquire arena locks subsequently, while list_lock is
+ acquired. */
+static mutex_t list_lock = MUTEX_INITIALIZER;
+
/* Mapped memory in non-main arenas (reliable only for NO_THREADS). */
static unsigned long arena_mem;
@@ -210,6 +230,9 @@ ptmalloc_lock_all (void)
if (__malloc_initialized < 1)
return;
+ /* We do not acquire free_list_lock here because we completely
+ reconstruct free_list in ptmalloc_unlock_all2. */
+
if (mutex_trylock (&list_lock))
{
void *my_arena;
@@ -233,7 +256,10 @@ ptmalloc_lock_all (void)
save_free_hook = __free_hook;
__malloc_hook = malloc_atfork;
__free_hook = free_atfork;
- /* Only the current thread may perform malloc/free calls now. */
+ /* Only the current thread may perform malloc/free calls now.
+ save_arena will be reattached to the current thread, in
+ ptmalloc_lock_all, so save_arena->attached_threads is not
+ updated. */
tsd_getspecific (arena_key, save_arena);
tsd_setspecific (arena_key, ATFORK_ARENA_PTR);
out:
@@ -251,6 +277,9 @@ ptmalloc_unlock_all (void)
if (--atfork_recursive_cntr != 0)
return;
+ /* Replace ATFORK_ARENA_PTR with save_arena.
+ save_arena->attached_threads was not changed in ptmalloc_lock_all
+ and is still correct. */
tsd_setspecific (arena_key, save_arena);
__malloc_hook = save_malloc_hook;
__free_hook = save_free_hook;
@@ -282,12 +311,20 @@ ptmalloc_unlock_all2 (void)
tsd_setspecific (arena_key, save_arena);
__malloc_hook = save_malloc_hook;
__free_hook = save_free_hook;
+
+ /* Push all arenas to the free list, except save_arena, which is
+ attached to the current thread. */
+ mutex_init (&free_list_lock);
+ if (save_arena != NULL)
+ ((mstate) save_arena)->attached_threads = 1;
free_list = NULL;
for (ar_ptr = &main_arena;; )
{
mutex_init (&ar_ptr->mutex);
if (ar_ptr != save_arena)
{
+ /* This arena is no longer attached to any thread. */
+ ar_ptr->attached_threads = 0;
ar_ptr->next_free = free_list;
free_list = ar_ptr;
}
@@ -295,6 +332,7 @@ ptmalloc_unlock_all2 (void)
if (ar_ptr == &main_arena)
break;
}
+
mutex_init (&list_lock);
atfork_recursive_cntr = 0;
}
@@ -721,6 +759,22 @@ heap_trim (heap_info *heap, size_t pad)
/* Create a new arena with initial size "size". */
+/* If REPLACED_ARENA is not NULL, detach it from this thread. Must be
+ called while free_list_lock is held. */
+static void
+detach_arena (mstate replaced_arena)
+{
+ if (replaced_arena != NULL)
+ {
+ assert (replaced_arena->attached_threads > 0);
+ /* The current implementation only detaches from main_arena in
+ case of allocation failure. This means that it is likely not
+ beneficial to put the arena on free_list even if the
+ reference count reaches zero. */
+ --replaced_arena->attached_threads;
+ }
+}
+
static mstate
_int_new_arena (size_t size)
{
@@ -742,6 +796,7 @@ _int_new_arena (size_t size)
}
a = h->ar_ptr = (mstate) (h + 1);
malloc_init_state (a);
+ a->attached_threads = 1;
/*a->next = NULL;*/
a->system_mem = a->max_system_mem = h->size;
arena_mem += h->size;
@@ -755,34 +810,66 @@ _int_new_arena (size_t size)
set_head (top (a), (((char *) h + h->size) - ptr) | PREV_INUSE);
LIBC_PROBE (memory_arena_new, 2, a, size);
+ mstate replaced_arena;
+ tsd_getspecific (arena_key, replaced_arena);
tsd_setspecific (arena_key, (void *) a);
mutex_init (&a->mutex);
- (void) mutex_lock (&a->mutex);
(void) mutex_lock (&list_lock);
/* Add the new arena to the global list. */
a->next = main_arena.next;
+ /* FIXME: The barrier is an attempt to synchronize with read access
+ in reused_arena, which does not acquire list_lock while
+ traversing the list. */
atomic_write_barrier ();
main_arena.next = a;
(void) mutex_unlock (&list_lock);
+ (void) mutex_lock (&free_list_lock);
+ detach_arena (replaced_arena);
+ (void) mutex_unlock (&free_list_lock);
+
+ /* Lock this arena. NB: Another thread may have been attached to
+ this arena because the arena is now accessible from the
+ main_arena.next list and could have been picked by reused_arena.
+ This can only happen for the last arena created (before the arena
+ limit is reached). At this point, some arena has to be attached
+ to two threads. We could acquire the arena lock before list_lock
+ to make it less likely that reused_arena picks this new arena,
+ but this could result in a deadlock with ptmalloc_lock_all. */
+
+ (void) mutex_lock (&a->mutex);
+
return a;
}
+/* Remove an arena from free_list. */
static mstate
get_free_list (void)
{
+ mstate replaced_arena;
mstate result = free_list;
+
+ tsd_getspecific (arena, replaced_arena);
+
if (result != NULL)
{
- (void) mutex_lock (&list_lock);
+ (void) mutex_lock (&free_list_lock);
result = free_list;
if (result != NULL)
- free_list = result->next_free;
- (void) mutex_unlock (&list_lock);
+ {
+ free_list = result->next_free;
+
+ /* The arena will be attached to this thread. */
+ assert (result->attached_threads == 0);
+ result->attached_threads = 1;
+
+ detach_arena (replaced_arena);
+ }
+ (void) mutex_unlock (&free_list_lock);
if (result != NULL)
{
@@ -795,6 +882,26 @@ get_free_list (void)
return result;
}
+/* Remove the arena from the free list (if it is present).
+ free_list_lock must have been acquired by the caller. */
+static void
+remove_from_free_list (mstate arena)
+{
+ mstate *previous = &free_list;
+ for (mstate p = free_list; p != NULL; p = p->next_free)
+ {
+ assert (p->attached_threads == 0);
+ if (p == arena)
+ {
+ /* Remove the requested arena from the list. */
+ *previous = p->next_free;
+ break;
+ }
+ else
+ previous = &p->next_free;
+ }
+}
+
/* Lock and return an arena that can be reused for memory allocation.
Avoid AVOID_ARENA as we have already failed to allocate memory in
it and it is currently locked. */
@@ -802,16 +909,20 @@ static mstate
reused_arena (mstate avoid_arena)
{
mstate result;
+ /* FIXME: Access to next_to_use suffers from data races. */
static mstate next_to_use;
if (next_to_use == NULL)
next_to_use = &main_arena;
+ /* Iterate over all arenas (including those linked from
+ free_list). */
result = next_to_use;
do
{
if (!arena_is_corrupt (result) && !mutex_trylock (&result->mutex))
goto out;
+ /* FIXME: This is a data race, see _int_new_arena. */
result = result->next;
}
while (result != next_to_use);
@@ -827,19 +938,40 @@ reused_arena (mstate avoid_arena)
{
result = result->next;
if (result == begin)
- break;
+ /* We looped around the arena list. We could not find any
+ arena that was either not corrupted or not the one we
+ wanted to avoid. */
+ return NULL;
}
- /* We could not find any arena that was either not corrupted or not the one
- we wanted to avoid. */
- if (result == begin || result == avoid_arena)
- return NULL;
-
/* No arena available without contention. Wait for the next in line. */
LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena);
(void) mutex_lock (&result->mutex);
out:
+ /* Attach the arena to the current thread. */
+ {
+ mstate replaced_arena;
+
+ tsd_getspecific (arena, replaced_arena);
+ (void) mutex_lock (&free_list_lock);
+ detach_arena (replaced_arena);
+
+ /* We may have picked up an arena on the free list. We need to
+ preserve the invariant that no arena on the free list has a
+ positive attached_threads counter (otherwise,
+ arena_thread_freeres cannot use the counter to determine if the
+ arena needs to be put on the free list). We unconditionally
+ remove the selected arena from the free list. The caller of
+ reused_arena checked the free list and observed it to be empty,
+ so the list is very short. */
+ remove_from_free_list (result);
+
+ ++result->attached_threads;
+
+ (void) mutex_unlock (&free_list_lock);
+ }
+
LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena);
tsd_setspecific (arena_key, (void *) result);
next_to_use = result->next;
@@ -932,10 +1064,16 @@ arena_thread_freeres (void)
if (a != NULL)
{
- (void) mutex_lock (&list_lock);
- a->next_free = free_list;
- free_list = a;
- (void) mutex_unlock (&list_lock);
+ (void) mutex_lock (&free_list_lock);
+ /* If this was the last attached thread for this arena, put the
+ arena on the free list. */
+ assert (a->attached_threads > 0);
+ if (--a->attached_threads == 0)
+ {
+ a->next_free = free_list;
+ free_list = a;
+ }
+ (void) mutex_unlock (&free_list_lock);
}
}
text_set_element (__libc_thread_subfreeres, arena_thread_freeres);
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 452f036..5c84e62 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1709,9 +1709,15 @@ struct malloc_state
/* Linked list */
struct malloc_state *next;
- /* Linked list for free arenas. */
+ /* Linked list for free arenas. Access to this field is serialized
+ by free_list_lock in arena.c. */
struct malloc_state *next_free;
+ /* Number of threads attached to this arena. 0 if the arena is on
+ the free list. Access to this field is serialized by
+ free_list_lock in arena.c. */
+ INTERNAL_SIZE_T attached_threads;
+
/* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
@@ -1755,7 +1761,8 @@ struct malloc_par
static struct malloc_state main_arena =
{
.mutex = MUTEX_INITIALIZER,
- .next = &main_arena
+ .next = &main_arena,
+ .attached_threads = 1
};
/* There is only one instance of the malloc parameters. */
diff --git a/malloc/tst-malloc-thread-exit.c b/malloc/tst-malloc-thread-exit.c
new file mode 100644
index 0000000..7bce012
--- /dev/null
+++ b/malloc/tst-malloc-thread-exit.c
@@ -0,0 +1,218 @@
+/* Test malloc with concurrent thread termination.
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This thread spawns a number of outer threads, equal to the arena
+ limit. The outer threads run a loop which start and join two
+ different kinds of threads: the first kind allocates (attaching an
+ arena to the thread; malloc_first_thread) and waits, the second
+ kind waits and allocates (wait_first_threads). Both kinds of
+ threads exit immediately after waiting. The hope is that this will
+ exhibit races in thread termination and arena management,
+ particularly related to the arena free list. */
+
+#include <errno.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int do_test (void);
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+static bool termination_requested;
+static int inner_thread_count = 4;
+static size_t malloc_size = 32;
+
+static void
+__attribute__ ((noinline, noclone))
+unoptimized_free (void *ptr)
+{
+ free (ptr);
+}
+
+static void *
+malloc_first_thread (void * closure)
+{
+ pthread_barrier_t *barrier = closure;
+ void *ptr = malloc (malloc_size);
+ if (ptr == NULL)
+ {
+ printf ("error: malloc: %m\n");
+ abort ();
+ }
+ int ret = pthread_barrier_wait (barrier);
+ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ errno = ret;
+ printf ("error: pthread_barrier_wait: %m\n");
+ abort ();
+ }
+ unoptimized_free (ptr);
+ return NULL;
+}
+
+static void *
+wait_first_thread (void * closure)
+{
+ pthread_barrier_t *barrier = closure;
+ int ret = pthread_barrier_wait (barrier);
+ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ errno = ret;
+ printf ("error: pthread_barrier_wait: %m\n");
+ abort ();
+ }
+ void *ptr = malloc (malloc_size);
+ if (ptr == NULL)
+ {
+ printf ("error: malloc: %m\n");
+ abort ();
+ }
+ unoptimized_free (ptr);
+ return NULL;
+}
+
+static void *
+outer_thread (void *closure)
+{
+ pthread_t *threads = calloc (sizeof (*threads), inner_thread_count);
+ if (threads == NULL)
+ {
+ printf ("error: calloc: %m\n");
+ abort ();
+ }
+
+ while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
+ {
+ pthread_barrier_t barrier;
+ int ret = pthread_barrier_init (&barrier, NULL, inner_thread_count + 1);
+ if (ret != 0)
+ {
+ errno = ret;
+ printf ("pthread_barrier_init: %m\n");
+ abort ();
+ }
+ for (int i = 0; i < inner_thread_count; ++i)
+ {
+ void *(*func) (void *);
+ if ((i % 2) == 0)
+ func = malloc_first_thread;
+ else
+ func = wait_first_thread;
+ ret = pthread_create (threads + i, NULL, func, &barrier);
+ if (ret != 0)
+ {
+ errno = ret;
+ printf ("error: pthread_create: %m\n");
+ abort ();
+ }
+ }
+ ret = pthread_barrier_wait (&barrier);
+ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ errno = ret;
+ printf ("pthread_wait: %m\n");
+ abort ();
+ }
+ for (int i = 0; i < inner_thread_count; ++i)
+ {
+ ret = pthread_join (threads[i], NULL);
+ if (ret != 0)
+ {
+ ret = errno;
+ printf ("error: pthread_join: %m\n");
+ abort ();
+ }
+ }
+ ret = pthread_barrier_destroy (&barrier);
+ if (ret != 0)
+ {
+ ret = errno;
+ printf ("pthread_barrier_destroy: %m\n");
+ abort ();
+ }
+ }
+
+ free (threads);
+
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+ /* The number of threads should be smaller than the number of
+ arenas, so that there will be some free arenas to add to the
+ arena free list. */
+ enum { outer_thread_count = 2 };
+ if (mallopt (M_ARENA_MAX, 8) == 0)
+ {
+ printf ("error: mallopt (M_ARENA_MAX) failed\n");
+ return 1;
+ }
+
+ /* Leave some room for shutting down all threads gracefully. */
+ int timeout = 3;
+ if (timeout > TIMEOUT)
+ timeout = TIMEOUT - 1;
+
+ pthread_t *threads = calloc (sizeof (*threads), outer_thread_count);
+ if (threads == NULL)
+ {
+ printf ("error: calloc: %m\n");
+ abort ();
+ }
+
+ for (long i = 0; i < outer_thread_count; ++i)
+ {
+ int ret = pthread_create (threads + i, NULL, outer_thread, NULL);
+ if (ret != 0)
+ {
+ errno = ret;
+ printf ("error: pthread_create: %m\n");
+ abort ();
+ }
+ }
+
+ struct timespec ts = {timeout, 0};
+ if (nanosleep (&ts, NULL))
+ {
+ printf ("error: error: nanosleep: %m\n");
+ abort ();
+ }
+
+ __atomic_store_n (&termination_requested, true, __ATOMIC_RELAXED);
+
+ for (long i = 0; i < outer_thread_count; ++i)
+ {
+ int ret = pthread_join (threads[i], NULL);
+ if (ret != 0)
+ {
+ errno = ret;
+ printf ("error: pthread_join: %m\n");
+ abort ();
+ }
+ }
+ free (threads);
+
+ return 0;
+}
diff --git a/manual/examples/mkdirent.c b/manual/examples/mkdirent.c
new file mode 100644
index 0000000..f8400f4
--- /dev/null
+++ b/manual/examples/mkdirent.c
@@ -0,0 +1,42 @@
+/* Example for creating a struct dirent object for use with glob.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <dirent.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct dirent *
+mkdirent (const char *name)
+{
+ size_t dirent_size = offsetof (struct dirent, d_name) + 1;
+ size_t name_length = strlen (name);
+ size_t total_size = dirent_size + name_length;
+ if (total_size < dirent_size)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ struct dirent *result = malloc (total_size);
+ if (result == NULL)
+ return NULL;
+ result->d_type = DT_UNKNOWN;
+ result->d_ino = 1; /* Do not skip this entry. */
+ memcpy (result->d_name, name, name_length + 1);
+ return result;
+}
diff --git a/manual/pattern.texi b/manual/pattern.texi
index d1b9275..565e7eb 100644
--- a/manual/pattern.texi
+++ b/manual/pattern.texi
@@ -237,7 +237,44 @@ function used to read the contents of a directory. It is used if the
@code{GLOB_ALTDIRFUNC} bit is set in the flag parameter. The type of
this field is @w{@code{struct dirent *(*) (void *)}}.
-This is a GNU extension.
+An implementation of @code{gl_readdir} needs to initialize the following
+members of the @code{struct dirent} object:
+
+@table @code
+@item d_type
+This member should be set to the file type of the entry if it is known.
+Otherwise, the value @code{DT_UNKNOWN} can be used. The @code{glob}
+function may use the specified file type to avoid callbacks in cases
+where the file type indicates that the data is not required.
+
+@item d_ino
+This member needs to be non-zero, otherwise @code{glob} may skip the
+current entry and call the @code{gl_readdir} callback function again to
+retrieve another entry.
+
+@item d_name
+This member must be set to the name of the entry. It must be
+null-terminated.
+@end table
+
+The example below shows how to allocate a @code{struct dirent} object
+containing a given name.
+
+@smallexample
+@include mkdirent.c.texi
+@end smallexample
+
+The @code{glob} function reads the @code{struct dirent} members listed
+above and makes a copy of the file name in the @code{d_name} member
+immediately after the @code{gl_readdir} callback function returns.
+Future invocations of any of the callback functions may dealloacte or
+reuse the buffer. It is the responsibility of the caller of the
+@code{glob} function to allocate and deallocate the buffer, around the
+call to @code{glob} or using the callback functions. For example, an
+application could allocate the buffer in the @code{gl_readdir} callback
+function, and deallocate it in the @code{gl_closedir} callback function.
+
+The @code{gl_readdir} member is a GNU extension.
@item gl_opendir
The address of an alternative implementation of the @code{opendir}
diff --git a/math/atest-exp2.c b/math/atest-exp2.c
index 307c741..ffa73b1 100644
--- a/math/atest-exp2.c
+++ b/math/atest-exp2.c
@@ -53,11 +53,6 @@ static const mp1 mp_exp1 = {
a784d904, 5190cfef, 324e7738, 926cfbe5, f4bf8d8d, 8c31d763)
};
-static const mp1 mp_exp_m1 = {
- CONSTSZ (0, 5e2d58d8, b3bcdf1a, badec782, 9054f90d, da9805aa, b56c7733,
- 3024b9d0, a507daed, b16400bf, 472b4215, b8245b66, 9d90d27a)
-};
-
static const mp1 mp_log2 = {
CONSTSZ (0, b17217f7, d1cf79ab, c9e3b398, 03f2f6af, 40f34326, 7298b62d,
8a0d175b, 8baafa2b, e7b87620, 6debac98, 559552fb, 4afa1b10)
diff --git a/nis/nis_call.c b/nis/nis_call.c
index 970415b..d98c385 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -680,16 +680,18 @@ nis_server_cache_add (const_nis_name name, int search_parent,
/* Choose which entry should be evicted from the cache. */
loc = &nis_server_cache[0];
if (*loc != NULL)
- for (i = 1; i < 16; ++i)
- if (nis_server_cache[i] == NULL)
- {
+ {
+ for (i = 1; i < 16; ++i)
+ if (nis_server_cache[i] == NULL)
+ {
+ loc = &nis_server_cache[i];
+ break;
+ }
+ else if ((*loc)->uses > nis_server_cache[i]->uses
+ || ((*loc)->uses == nis_server_cache[i]->uses
+ && (*loc)->expires > nis_server_cache[i]->expires))
loc = &nis_server_cache[i];
- break;
- }
- else if ((*loc)->uses > nis_server_cache[i]->uses
- || ((*loc)->uses == nis_server_cache[i]->uses
- && (*loc)->expires > nis_server_cache[i]->expires))
- loc = &nis_server_cache[i];
+ }
old = *loc;
*loc = new;
diff --git a/nis/nss_nis/nis-initgroups.c b/nis/nss_nis/nis-initgroups.c
index ed5c26b..5845b6d 100644
--- a/nis/nss_nis/nis-initgroups.c
+++ b/nis/nss_nis/nis-initgroups.c
@@ -266,7 +266,7 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
tmpbuf = __alloca (buflen);
- do
+ while (1)
{
while ((status =
internal_getgrent_r (&grpbuf, tmpbuf, buflen, errnop,
@@ -275,8 +275,11 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen);
if (status != NSS_STATUS_SUCCESS)
- goto done;
-
+ {
+ if (status == NSS_STATUS_NOTFOUND)
+ status = NSS_STATUS_SUCCESS;
+ goto done;
+ }
g = &grpbuf;
if (g->gr_gid != group)
@@ -304,7 +307,11 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
newgroups = realloc (groups, newsize * sizeof (*groups));
if (newgroups == NULL)
- goto done;
+ {
+ status = NSS_STATUS_TRYAGAIN;
+ *errnop = errno;
+ goto done;
+ }
*groupsp = groups = newgroups;
*size = newsize;
}
@@ -316,7 +323,6 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
}
}
}
- while (status == NSS_STATUS_SUCCESS);
done:
while (intern.start != NULL)
diff --git a/nptl/pt-fork.c b/nptl/pt-fork.c
index fd6544b..325ff2b6 100644
--- a/nptl/pt-fork.c
+++ b/nptl/pt-fork.c
@@ -25,33 +25,14 @@
the historical ABI requires it. For static linking, there is no need to
provide anything here--the libc version will be linked in. For shared
library ABI compatibility, there must be __fork and fork symbols in
- libpthread.so; so we define them using IFUNC to redirect to the libc
- function. */
+ libpthread.so.
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
-
-# if HAVE_IFUNC
-
-static __typeof (fork) *
-__attribute__ ((used))
-fork_resolve (void)
-{
- return &__libc_fork;
-}
+ With an IFUNC resolver, it would be possible to avoid the
+ indirection, but the IFUNC resolver might run before the
+ __libc_fork symbol has been relocated, in which case the IFUNC
+ resolver would not be able to provide the correct address. */
-# ifdef HAVE_ASM_SET_DIRECTIVE
-# define DEFINE_FORK(name) \
- asm (".set " #name ", fork_resolve\n" \
- ".globl " #name "\n" \
- ".type " #name ", %gnu_indirect_function");
-# else
-# define DEFINE_FORK(name) \
- asm (#name " = fork_resolve\n" \
- ".globl " #name "\n" \
- ".type " #name ", %gnu_indirect_function");
-# endif
-
-# else /* !HAVE_IFUNC */
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
static pid_t __attribute__ ((used))
fork_compat (void)
@@ -59,14 +40,10 @@ fork_compat (void)
return __libc_fork ();
}
-# define DEFINE_FORK(name) strong_alias (fork_compat, name)
-
-# endif /* HAVE_IFUNC */
-
-DEFINE_FORK (fork_ifunc)
-compat_symbol (libpthread, fork_ifunc, fork, GLIBC_2_0);
+strong_alias (fork_compat, fork_alias)
+compat_symbol (libpthread, fork_alias, fork, GLIBC_2_0);
-DEFINE_FORK (__fork_ifunc)
-compat_symbol (libpthread, __fork_ifunc, __fork, GLIBC_2_0);
+strong_alias (fork_compat, __fork_alias)
+compat_symbol (libpthread, __fork_alias, __fork, GLIBC_2_0);
#endif
diff --git a/nptl/tst-once5.cc b/nptl/tst-once5.cc
index 60bc78a..a6985b0 100644
--- a/nptl/tst-once5.cc
+++ b/nptl/tst-once5.cc
@@ -76,5 +76,7 @@ do_test (void)
return result;
}
+// The test currently hangs and is XFAILed. Reduce the timeout.
+#define TIMEOUT 1
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
diff --git a/nss/nss_db/db-XXX.c b/nss/nss_db/db-XXX.c
index 4a0766a..e13287a 100644
--- a/nss/nss_db/db-XXX.c
+++ b/nss/nss_db/db-XXX.c
@@ -77,7 +77,7 @@ CONCAT(_nss_db_set,ENTNAME) (int stayopen)
keep_db |= stayopen;
/* Reset the sequential index. */
- entidx = (const char *) state.header + state.header->valstroffset;
+ entidx = NULL;
}
__libc_lock_unlock (lock);
@@ -253,8 +253,14 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
H_ERRNO_SET (NETDB_INTERNAL);
goto out;
}
+ entidx = NULL;
}
+ /* Start from the beginning if freshly initialized or reset
+ requested by set*ent. */
+ if (entidx == NULL)
+ entidx = (const char *) state.header + state.header->valstroffset;
+
status = NSS_STATUS_UNAVAIL;
if (state.header != MAP_FAILED)
{
@@ -288,8 +294,8 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
}
if (err < 0)
{
- H_ERRNO_SET (HOST_NOT_FOUND);
- status = NSS_STATUS_NOTFOUND;
+ H_ERRNO_SET (NETDB_INTERNAL);
+ status = NSS_STATUS_TRYAGAIN;
break;
}
diff --git a/posix/bug-glob2.c b/posix/bug-glob2.c
index 1f302fe..e2964b2 100644
--- a/posix/bug-glob2.c
+++ b/posix/bug-glob2.c
@@ -40,6 +40,17 @@
# define PRINTF(fmt, args...)
#endif
+#define LONG_NAME \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
static struct
{
@@ -58,6 +69,7 @@ static struct
{ ".", 3, DT_DIR, 0755 },
{ "..", 3, DT_DIR, 0755 },
{ "a", 3, DT_REG, 0644 },
+ { LONG_NAME, 3, DT_REG, 0644 },
{ "unreadable", 2, DT_DIR, 0111 },
{ ".", 3, DT_DIR, 0111 },
{ "..", 3, DT_DIR, 0755 },
@@ -75,7 +87,7 @@ typedef struct
int level;
int idx;
struct dirent d;
- char room_for_dirent[NAME_MAX];
+ char room_for_dirent[sizeof (LONG_NAME)];
} my_DIR;
@@ -193,7 +205,7 @@ my_readdir (void *gdir)
return NULL;
}
- dir->d.d_ino = dir->idx;
+ dir->d.d_ino = 1; /* glob should not skip this entry. */
#ifdef _DIRENT_HAVE_D_TYPE
dir->d.d_type = filesystem[dir->idx].type;
diff --git a/posix/glob.c b/posix/glob.c
index d65e55d..60fa6c5 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -24,7 +24,9 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <stdbool.h>
#include <stddef.h>
+#include <stdint.h>
/* Outcomment the following line for production quality code. */
/* #define NDEBUG 1 */
@@ -57,10 +59,8 @@
#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
@@ -75,82 +75,8 @@
# endif /* HAVE_VMSDIR_H */
#endif
-
-/* In GNU systems, <dirent.h> defines this macro for us. */
-#ifdef _D_NAMLEN
-# undef NAMLEN
-# define NAMLEN(d) _D_NAMLEN(d)
-#endif
-
-/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
- if the `d_type' member for `struct dirent' is available.
- HAVE_STRUCT_DIRENT_D_TYPE plays the same role in GNULIB. */
-#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
-/* True if the directory entry D must be of type T. */
-# define DIRENT_MUST_BE(d, t) ((d)->d_type == (t))
-
-/* True if the directory entry D might be a symbolic link. */
-# define DIRENT_MIGHT_BE_SYMLINK(d) \
- ((d)->d_type == DT_UNKNOWN || (d)->d_type == DT_LNK)
-
-/* True if the directory entry D might be a directory. */
-# define DIRENT_MIGHT_BE_DIR(d) \
- ((d)->d_type == DT_DIR || DIRENT_MIGHT_BE_SYMLINK (d))
-
-#else /* !HAVE_D_TYPE */
-# define DIRENT_MUST_BE(d, t) false
-# define DIRENT_MIGHT_BE_SYMLINK(d) true
-# define DIRENT_MIGHT_BE_DIR(d) true
-#endif /* HAVE_D_TYPE */
-
-/* If the system has the `struct dirent64' type we use it internally. */
-#if defined _LIBC && !defined COMPILE_GLOB64
-# if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
-# define CONVERT_D_NAMLEN(d64, d32)
-# else
-# define CONVERT_D_NAMLEN(d64, d32) \
- (d64)->d_namlen = (d32)->d_namlen;
-# endif
-
-# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
-# define CONVERT_D_INO(d64, d32)
-# else
-# define CONVERT_D_INO(d64, d32) \
- (d64)->d_ino = (d32)->d_ino;
-# endif
-
-# ifdef _DIRENT_HAVE_D_TYPE
-# define CONVERT_D_TYPE(d64, d32) \
- (d64)->d_type = (d32)->d_type;
-# else
-# define CONVERT_D_TYPE(d64, d32)
-# endif
-
-# define CONVERT_DIRENT_DIRENT64(d64, d32) \
- memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1); \
- CONVERT_D_NAMLEN (d64, d32) \
- CONVERT_D_INO (d64, d32) \
- CONVERT_D_TYPE (d64, d32)
-#endif
-
-
-#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
-/* Posix does not require that the d_ino field be present, and some
- systems do not provide it. */
-# define REAL_DIR_ENTRY(dp) 1
-#else
-# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
-#endif /* POSIX */
-
#include <stdlib.h>
#include <string.h>
-
-/* NAME_MAX is usually defined in <dirent.h> or <limits.h>. */
-#include <limits.h>
-#ifndef NAME_MAX
-# define NAME_MAX (sizeof (((struct dirent *) 0)->d_name))
-#endif
-
#include <alloca.h>
#ifdef _LIBC
@@ -195,8 +121,111 @@
static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
+/* A representation of a directory entry which does not depend on the
+ layout of struct dirent, or the size of ino_t. */
+struct readdir_result
+{
+ const char *name;
+# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
+ uint8_t type;
+# endif
+ bool skip_entry;
+};
+
+# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
+/* Initializer based on the d_type member of struct dirent. */
+# define D_TYPE_TO_RESULT(source) (source)->d_type,
+
+/* True if the directory entry D might be a symbolic link. */
+static bool
+readdir_result_might_be_symlink (struct readdir_result d)
+{
+ return d.type == DT_UNKNOWN || d.type == DT_LNK;
+}
+
+/* True if the directory entry D might be a directory. */
+static bool
+readdir_result_might_be_dir (struct readdir_result d)
+{
+ return d.type == DT_DIR || readdir_result_might_be_symlink (d);
+}
+# else /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
+# define D_TYPE_TO_RESULT(source)
+
+/* If we do not have type information, symbolic links and directories
+ are always a possibility. */
+
+static bool
+readdir_result_might_be_symlink (struct readdir_result d)
+{
+ return true;
+}
+
+static bool
+readdir_result_might_be_dir (struct readdir_result d)
+{
+ return true;
+}
+
+# endif /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
+
+# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
+/* Initializer for skip_entry. POSIX does not require that the d_ino
+ field be present, and some systems do not provide it. */
+# define D_INO_TO_RESULT(source) false,
+# else
+# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
+# endif
+
+/* Construct an initializer for a struct readdir_result object from a
+ struct dirent *. No copy of the name is made. */
+#define READDIR_RESULT_INITIALIZER(source) \
+ { \
+ source->d_name, \
+ D_TYPE_TO_RESULT (source) \
+ D_INO_TO_RESULT (source) \
+ }
+
#endif /* !defined _LIBC || !defined GLOB_ONLY_P */
+/* Call gl_readdir on STREAM. This macro can be overridden to reduce
+ type safety if an old interface version needs to be supported. */
+#ifndef GL_READDIR
+# define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
+#endif
+
+/* Extract name and type from directory entry. No copy of the name is
+ made. If SOURCE is NULL, result name is NULL. Keep in sync with
+ convert_dirent64 below. */
+static struct readdir_result
+convert_dirent (const struct dirent *source)
+{
+ if (source == NULL)
+ {
+ struct readdir_result result = { NULL, };
+ return result;
+ }
+ struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
+ return result;
+}
+
+#ifndef COMPILE_GLOB64
+/* Like convert_dirent, but works on struct dirent64 instead. Keep in
+ sync with convert_dirent above. */
+static struct readdir_result
+convert_dirent64 (const struct dirent64 *source)
+{
+ if (source == NULL)
+ {
+ struct readdir_result result = { NULL, };
+ return result;
+ }
+ struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
+ return result;
+}
+#endif
+
+
#ifndef attribute_hidden
# define attribute_hidden
#endif
@@ -1561,56 +1590,36 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
while (1)
{
- const char *name;
- size_t len;
-#if defined _LIBC && !defined COMPILE_GLOB64
- struct dirent64 *d;
- union
- {
- struct dirent64 d64;
- char room [offsetof (struct dirent64, d_name[0])
- + NAME_MAX + 1];
- }
- d64buf;
-
- if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
- {
- struct dirent *d32 = (*pglob->gl_readdir) (stream);
- if (d32 != NULL)
- {
- CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
- d = &d64buf.d64;
- }
- else
- d = NULL;
- }
- else
- d = __readdir64 (stream);
+ struct readdir_result d;
+ {
+ if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
+ d = convert_dirent (GL_READDIR (pglob, stream));
+ else
+ {
+#ifdef COMPILE_GLOB64
+ d = convert_dirent (__readdir (stream));
#else
- struct dirent *d = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
- ? ((struct dirent *)
- (*pglob->gl_readdir) (stream))
- : __readdir (stream));
+ d = convert_dirent64 (__readdir64 (stream));
#endif
- if (d == NULL)
+ }
+ }
+ if (d.name == NULL)
break;
- if (! REAL_DIR_ENTRY (d))
+ if (d.skip_entry)
continue;
/* If we shall match only directories use the information
provided by the dirent call if possible. */
- if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
+ if ((flags & GLOB_ONLYDIR) && !readdir_result_might_be_dir (d))
continue;
- name = d->d_name;
-
- if (fnmatch (pattern, name, fnm_flags) == 0)
+ if (fnmatch (pattern, d.name, fnm_flags) == 0)
{
/* If the file we found is a symlink we have to
make sure the target file exists. */
- if (!DIRENT_MIGHT_BE_SYMLINK (d)
- || link_exists_p (dfd, directory, dirlen, name, pglob,
- flags))
+ if (!readdir_result_might_be_symlink (d)
+ || link_exists_p (dfd, directory, dirlen, d.name,
+ pglob, flags))
{
if (cur == names->count)
{
@@ -1630,12 +1639,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
names = newnames;
cur = 0;
}
- len = NAMLEN (d);
- names->name[cur] = (char *) malloc (len + 1);
+ names->name[cur] = strdup (d.name);
if (names->name[cur] == NULL)
goto memory_error;
- *((char *) mempcpy (names->name[cur++], name, len))
- = '\0';
+ ++cur;
++nfound;
}
}
diff --git a/posix/tst-gnuglob.c b/posix/tst-gnuglob.c
index d444999..b8cc042 100644
--- a/posix/tst-gnuglob.c
+++ b/posix/tst-gnuglob.c
@@ -211,7 +211,7 @@ my_readdir (void *gdir)
return NULL;
}
- dir->d.d_ino = dir->idx;
+ dir->d.d_ino = 1; /* glob should not skip this entry. */
#ifdef _DIRENT_HAVE_D_TYPE
dir->d.d_type = filesystem[dir->idx].type;
diff --git a/resolv/base64.c b/resolv/base64.c
index ea584ed..519e5d2 100644
--- a/resolv/base64.c
+++ b/resolv/base64.c
@@ -40,10 +40,6 @@
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
-#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$BINDId: base64.c,v 8.7 1999/10/13 16:39:33 vixie Exp $";
-#endif /* not lint */
-
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
diff --git a/stdlib/setenv.c b/stdlib/setenv.c
index b9e0ba8..7a87d64 100644
--- a/stdlib/setenv.c
+++ b/stdlib/setenv.c
@@ -289,18 +289,20 @@ unsetenv (name)
ep = __environ;
if (ep != NULL)
while (*ep != NULL)
- if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
- {
- /* Found it. Remove this pointer by moving later ones back. */
- char **dp = ep;
-
- do
- dp[0] = dp[1];
- while (*dp++);
- /* Continue the loop in case NAME appears again. */
- }
- else
- ++ep;
+ {
+ if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
+ {
+ /* Found it. Remove this pointer by moving later ones back. */
+ char **dp = ep;
+
+ do
+ dp[0] = dp[1];
+ while (*dp++);
+ /* Continue the loop in case NAME appears again. */
+ }
+ else
+ ++ep;
+ }
UNLOCK;
diff --git a/string/tst-endian.c b/string/tst-endian.c
index 8684bb2..7d39131 100644
--- a/string/tst-endian.c
+++ b/string/tst-endian.c
@@ -3,6 +3,20 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
+#include <libc-internal.h>
+
+#if __GNUC_PREREQ (6, 0)
+/* GCC 6.0 warns on big endian systems about:
+ htobeXX (beXXtoh (i)) != i
+ warning: self-comparison always evaluates to false [-Wtautological-compare]
+ because htobeXX(x) and beXXtoh(x) is defined to (x)
+ in string/endian.h on big endian systems.
+ The same applies to htoleXX/leXXtoh on little endian systems. */
+# define DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE() \
+ DIAG_IGNORE_NEEDS_COMMENT (6, "-Wtautological-compare")
+#else
+# define DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE()
+#endif
static int
do_test (void)
@@ -13,6 +27,8 @@ do_test (void)
{
if (i < UINT64_C (65536))
{
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE ();
if (htobe16 (be16toh (i)) != i)
{
printf ("htobe16 (be16toh (%" PRIx64 ")) == %" PRIx16 "\n",
@@ -25,6 +41,7 @@ do_test (void)
i, (uint16_t) htole16 (le16toh (i)));
result = 1;
}
+ DIAG_POP_NEEDS_COMMENT;
uint16_t n[2];
n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_16 (i);
@@ -45,6 +62,8 @@ do_test (void)
if (i < UINT64_C (4294967296))
{
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE ();
if (htobe32 (be32toh (i)) != i)
{
printf ("htobe32 (be32toh (%" PRIx64 ")) == %" PRIx32 "\n",
@@ -57,6 +76,7 @@ do_test (void)
i, (uint32_t) htole32 (le32toh (i)));
result = 1;
}
+ DIAG_POP_NEEDS_COMMENT;
uint32_t n[2];
n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_32 (i);
@@ -75,6 +95,8 @@ do_test (void)
}
}
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_NEEDS_COMMENT_TAUTOLOGICAL_COMPARE ();
if (htobe64 (be64toh (i)) != i)
{
printf ("htobe64 (be64toh (%" PRIx64 ")) == %" PRIx64 "\n",
@@ -87,6 +109,7 @@ do_test (void)
i, htole64 (le64toh (i)));
result = 1;
}
+ DIAG_POP_NEEDS_COMMENT;
uint64_t n[2];
n[__BYTE_ORDER == __LITTLE_ENDIAN] = bswap_64 (i);
diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
index 6ffa5f2..c818caf 100644
--- a/sunrpc/clnt_udp.c
+++ b/sunrpc/clnt_udp.c
@@ -420,9 +420,15 @@ send_again:
struct sock_extended_err *e;
struct sockaddr_in err_addr;
struct iovec iov;
- char *cbuf = (char *) alloca (outlen + 256);
+ char *cbuf = malloc (outlen + 256);
int ret;
+ if (cbuf == NULL)
+ {
+ cu->cu_error.re_errno = errno;
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+
iov.iov_base = cbuf + 256;
iov.iov_len = outlen;
msg.msg_name = (void *) &err_addr;
@@ -447,10 +453,12 @@ send_again:
cmsg = CMSG_NXTHDR (&msg, cmsg))
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
{
+ free (cbuf);
e = (struct sock_extended_err *) CMSG_DATA(cmsg);
cu->cu_error.re_errno = e->ee_errno;
return (cu->cu_error.re_status = RPC_CANTRECV);
}
+ free (cbuf);
}
#endif
do
diff --git a/sysdeps/hppa/start.S b/sysdeps/hppa/start.S
index cc4f243..d20caba 100644
--- a/sysdeps/hppa/start.S
+++ b/sysdeps/hppa/start.S
@@ -131,8 +131,10 @@ _start:
stw %sp, -60(%sp)
#ifdef SHARED
+ /* load global */
addil LT'.Lp__global, %r19
ldw RT'.Lp__global(%r1), %dp
+ ldw 0(%dp), %dp
#else
/* load global */
ldil L%$global$, %dp
diff --git a/sysdeps/ia64/nptl/Makefile b/sysdeps/ia64/nptl/Makefile
index fd8abbc..84e0b8b 100644
--- a/sysdeps/ia64/nptl/Makefile
+++ b/sysdeps/ia64/nptl/Makefile
@@ -21,4 +21,5 @@ endif
ifeq ($(subdir),nptl)
libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask
+libpthread-shared-only-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask
endif
diff --git a/sysdeps/ieee754/dbl-64/atnat2.h b/sysdeps/ieee754/dbl-64/atnat2.h
index e0d65af..82943f9 100644
--- a/sysdeps/ieee754/dbl-64/atnat2.h
+++ b/sysdeps/ieee754/dbl-64/atnat2.h
@@ -65,10 +65,8 @@
/**/ hpi1 = {{0x3c91a626, 0x33145c07} }, /* pi/2-hpi */
/**/ mhpi = {{0xbff921fb, 0x54442d18} }, /* -pi/2 */
/**/ qpi = {{0x3fe921fb, 0x54442d18} }, /* pi/4 */
-/**/ qpi1 = {{0x3c81a626, 0x33145c07} }, /* pi/4-qpi */
/**/ mqpi = {{0xbfe921fb, 0x54442d18} }, /* -pi/4 */
/**/ tqpi = {{0x4002d97c, 0x7f3321d2} }, /* 3pi/4 */
-/**/ tqpi1 = {{0x3c9a7939, 0x4c9e8a0a} }, /* 3pi/4-tqpi */
/**/ mtqpi = {{0xc002d97c, 0x7f3321d2} }, /* -3pi/4 */
/**/ u1 = {{0x3c314c2a, 0x00000000} }, /* 9.377e-19 */
/**/ u2 = {{0x3bf955e4, 0x00000000} }, /* 8.584e-20 */
@@ -129,10 +127,8 @@
/**/ hpi1 = {{0x33145c07, 0x3c91a626} }, /* pi/2-hpi */
/**/ mhpi = {{0x54442d18, 0xbff921fb} }, /* -pi/2 */
/**/ qpi = {{0x54442d18, 0x3fe921fb} }, /* pi/4 */
-/**/ qpi1 = {{0x33145c07, 0x3c81a626} }, /* pi/4-qpi */
/**/ mqpi = {{0x54442d18, 0xbfe921fb} }, /* -pi/4 */
/**/ tqpi = {{0x7f3321d2, 0x4002d97c} }, /* 3pi/4 */
-/**/ tqpi1 = {{0x4c9e8a0a, 0x3c9a7939} }, /* 3pi/4-tqpi */
/**/ mtqpi = {{0x7f3321d2, 0xc002d97c} }, /* -3pi/4 */
/**/ u1 = {{0x00000000, 0x3c314c2a} }, /* 9.377e-19 */
/**/ u2 = {{0x00000000, 0x3bf955e4} }, /* 8.584e-20 */
diff --git a/sysdeps/ieee754/dbl-64/uexp.h b/sysdeps/ieee754/dbl-64/uexp.h
index 6817eaf..42b21f2 100644
--- a/sysdeps/ieee754/dbl-64/uexp.h
+++ b/sysdeps/ieee754/dbl-64/uexp.h
@@ -29,7 +29,7 @@
#include "mydefs.h"
-const static double one = 1.0, zero = 0.0, hhuge = 1.0e300, tiny = 1.0e-300,
+const static double zero = 0.0, hhuge = 1.0e300, tiny = 1.0e-300,
err_0 = 1.000014, err_1 = 0.000016;
const static int4 bigint = 0x40862002,
badint = 0x40876000,smallint = 0x3C8fffff;
diff --git a/sysdeps/ieee754/dbl-64/upow.h b/sysdeps/ieee754/dbl-64/upow.h
index c8569a9..b4911e5 100644
--- a/sysdeps/ieee754/dbl-64/upow.h
+++ b/sysdeps/ieee754/dbl-64/upow.h
@@ -34,7 +34,6 @@
/**/ nZERO = {{0x80000000, 0}}, /* -0.0 */
/**/ INF = {{0x7ff00000, 0x00000000}}, /* INF */
/**/ nINF = {{0xfff00000, 0x00000000}}, /* -INF */
-/**/ sqrt_2 = {{0x3ff6a09e, 0x667f3bcc}}, /* sqrt(2) */
/**/ ln2a = {{0x3fe62e42, 0xfefa3800}}, /* ln(2) 43 bits */
/**/ ln2b = {{0x3d2ef357, 0x93c76730}}, /* ln(2)-ln2a */
/**/ bigu = {{0x4297ffff, 0xfffffd2c}}, /* 1.5*2**42 -724*2**-10 */
@@ -48,7 +47,6 @@
/**/ nZERO = {{0, 0x80000000}}, /* -0.0 */
/**/ INF = {{0x00000000, 0x7ff00000}}, /* INF */
/**/ nINF = {{0x00000000, 0xfff00000}}, /* -INF */
-/**/ sqrt_2 = {{0x667f3bcc, 0x3ff6a09e}}, /* sqrt(2) */
/**/ ln2a = {{0xfefa3800, 0x3fe62e42}}, /* ln(2) 43 bits */
/**/ ln2b = {{0x93c76730, 0x3d2ef357}}, /* ln(2)-ln2a */
/**/ bigu = {{0xfffffd2c, 0x4297ffff}}, /* 1.5*2**42 -724*2**-10 */
diff --git a/sysdeps/ieee754/flt-32/e_log10f.c b/sysdeps/ieee754/flt-32/e_log10f.c
index 96f0e81..1daeef7 100644
--- a/sysdeps/ieee754/flt-32/e_log10f.c
+++ b/sysdeps/ieee754/flt-32/e_log10f.c
@@ -22,8 +22,6 @@ ivln10 = 4.3429449201e-01, /* 0x3ede5bd9 */
log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */
log10_2lo = 7.9034151668e-07; /* 0x355427db */
-static const float zero = 0.0;
-
float
__ieee754_log10f(float x)
{
diff --git a/sysdeps/ieee754/flt-32/k_rem_pio2f.c b/sysdeps/ieee754/flt-32/k_rem_pio2f.c
index 6f14d5b..153ebca 100644
--- a/sysdeps/ieee754/flt-32/k_rem_pio2f.c
+++ b/sysdeps/ieee754/flt-32/k_rem_pio2f.c
@@ -65,7 +65,9 @@ int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32
/* compute q[0],q[1],...q[jk] */
for (i=0;i<=jk;i++) {
- for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+ for(j=0,fw=0.0;j<=jx;j++)
+ fw += x[j]*f[jx+i-j];
+ q[i] = fw;
}
jz = jk;
diff --git a/sysdeps/ieee754/flt-32/s_cosf.c b/sysdeps/ieee754/flt-32/s_cosf.c
index 864ab27..0affd40 100644
--- a/sysdeps/ieee754/flt-32/s_cosf.c
+++ b/sysdeps/ieee754/flt-32/s_cosf.c
@@ -21,8 +21,6 @@ static char rcsid[] = "$NetBSD: s_cosf.c,v 1.4 1995/05/10 20:47:03 jtc Exp $";
#include <math.h>
#include <math_private.h>
-static const float one=1.0;
-
#ifndef COSF
# define COSF_FUNC __cosf
#else
diff --git a/sysdeps/ieee754/ldbl-128/e_lgammal_r.c b/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
index d8a5e5b..c5c59ae 100644
--- a/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
+++ b/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
@@ -82,7 +82,6 @@ DIAG_IGNORE_NEEDS_COMMENT (4.6, "-Woverflow");
static const long double MAXLGM = 1.0485738685148938358098967157129705071571E4928L;
DIAG_POP_NEEDS_COMMENT;
static const long double one = 1.0L;
-static const long double zero = 0.0L;
static const long double huge = LDBL_MAX;
/* log gamma(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x P(1/x^2)
diff --git a/sysdeps/ieee754/ldbl-128/s_erfl.c b/sysdeps/ieee754/ldbl-128/s_erfl.c
index fa4609f..08c80a3 100644
--- a/sysdeps/ieee754/ldbl-128/s_erfl.c
+++ b/sysdeps/ieee754/ldbl-128/s_erfl.c
@@ -140,7 +140,6 @@ deval (long double x, const long double *p, int n)
static const long double
tiny = 1e-4931L,
- half = 0.5L,
one = 1.0L,
two = 2.0L,
/* 2/sqrt(pi) - 1 */
diff --git a/sysdeps/ieee754/ldbl-128/s_log1pl.c b/sysdeps/ieee754/ldbl-128/s_log1pl.c
index ff759bc..9609550 100644
--- a/sysdeps/ieee754/ldbl-128/s_log1pl.c
+++ b/sysdeps/ieee754/ldbl-128/s_log1pl.c
@@ -117,7 +117,6 @@ static const long double C2 = 1.428606820309417232121458176568075500134E-6L;
static const long double sqrth = 0.7071067811865475244008443621048490392848L;
/* ln (2^16384 * (1 - 2^-113)) */
-static const long double maxlog = 1.1356523406294143949491931077970764891253E4L;
static const long double zero = 0.0L;
long double
diff --git a/sysdeps/mips/Makefile b/sysdeps/mips/Makefile
index 463b121..4dfaaa8 100644
--- a/sysdeps/mips/Makefile
+++ b/sysdeps/mips/Makefile
@@ -9,6 +9,7 @@ endif
ifeq ($(subdir),rt)
librt-sysdep_routines += rt-sysdep
+librt-shared-only-routines += rt-sysdep
endif
ifeq ($(subdir),debug)
diff --git a/sysdeps/mips/nptl/Makefile b/sysdeps/mips/nptl/Makefile
index 46baad5..4a710ee 100644
--- a/sysdeps/mips/nptl/Makefile
+++ b/sysdeps/mips/nptl/Makefile
@@ -21,4 +21,5 @@ endif
ifeq ($(subdir),nptl)
libpthread-sysdep_routines += nptl-sysdep
+libpthread-shared-only-routines += nptl-sysdep
endif
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 31bb7e6..715e858 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -168,9 +168,58 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
return 0;
}
+/* Convert struct hostent to a list of struct gaih_addrtuple objects.
+ h_name is not copied, and the struct hostent object must not be
+ deallocated prematurely. *RESULT must be NULL or a pointer to an
+ object allocated using malloc, which is freed. */
+static bool
+convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
+ int family,
+ struct hostent *h,
+ struct gaih_addrtuple **result)
+{
+ free (*result);
+ *result = NULL;
+
+ /* Count the number of addresses in h->h_addr_list. */
+ size_t count = 0;
+ for (char **p = h->h_addr_list; *p != NULL; ++p)
+ ++count;
+
+ /* Report no data if no addresses are available, or if the incoming
+ address size is larger than what we can store. */
+ if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
+ return true;
+
+ struct gaih_addrtuple *array = calloc (count, sizeof (*array));
+ if (array == NULL)
+ return false;
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ if (family == AF_INET && req->ai_family == AF_INET6)
+ {
+ /* Perform address mapping. */
+ array[i].family = AF_INET6;
+ memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
+ array[i].addr[2] = htonl (0xffff);
+ }
+ else
+ {
+ array[i].family = family;
+ memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
+ }
+ array[i].next = array + i + 1;
+ }
+ array[0].name = h->h_name;
+ array[count - 1].next = NULL;
+
+ *result = array;
+ return true;
+}
+
#define gethosts(_family, _type) \
{ \
- int i; \
int herrno; \
struct hostent th; \
struct hostent *h; \
@@ -219,36 +268,23 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
} \
else if (h != NULL) \
{ \
- for (i = 0; h->h_addr_list[i]; i++) \
+ /* Make sure that addrmem can be freed. */ \
+ if (!malloc_addrmem) \
+ addrmem = NULL; \
+ if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
{ \
- if (*pat == NULL) \
- { \
- *pat = __alloca (sizeof (struct gaih_addrtuple)); \
- (*pat)->scopeid = 0; \
- } \
- uint32_t *addr = (*pat)->addr; \
- (*pat)->next = NULL; \
- (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
- if (_family == AF_INET && req->ai_family == AF_INET6) \
- { \
- (*pat)->family = AF_INET6; \
- addr[3] = *(uint32_t *) h->h_addr_list[i]; \
- addr[2] = htonl (0xffff); \
- addr[1] = 0; \
- addr[0] = 0; \
- } \
- else \
- { \
- (*pat)->family = _family; \
- memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
- } \
- pat = &((*pat)->next); \
+ _res.options |= old_res_options & RES_USE_INET6; \
+ result = -EAI_SYSTEM; \
+ goto free_and_return; \
} \
+ *pat = addrmem; \
+ /* The conversion uses malloc unconditionally. */ \
+ malloc_addrmem = true; \
\
if (localcanon != NULL && canon == NULL) \
canon = strdupa (localcanon); \
\
- if (_family == AF_INET6 && i > 0) \
+ if (_family == AF_INET6 && *pat != NULL) \
got_ipv6 = true; \
} \
}
@@ -612,44 +648,16 @@ gaih_inet (const char *name, const struct gaih_service *service,
{
if (h != NULL)
{
- int i;
- /* We found data, count the number of addresses. */
- for (i = 0; h->h_addr_list[i]; ++i)
- ;
- if (i > 0 && *pat != NULL)
- --i;
-
- if (__libc_use_alloca (alloca_used
- + i * sizeof (struct gaih_addrtuple)))
- addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
- alloca_used);
- else
- {
- addrmem = malloc (i
- * sizeof (struct gaih_addrtuple));
- if (addrmem == NULL)
- {
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- malloc_addrmem = true;
- }
-
- /* Now convert it into the list. */
- struct gaih_addrtuple *addrfree = addrmem;
- for (i = 0; h->h_addr_list[i]; ++i)
+ /* We found data, convert it. */
+ if (!convert_hostent_to_gaih_addrtuple
+ (req, AF_INET, h, &addrmem))
{
- if (*pat == NULL)
- {
- *pat = addrfree++;
- (*pat)->scopeid = 0;
- }
- (*pat)->next = NULL;
- (*pat)->family = AF_INET;
- memcpy ((*pat)->addr, h->h_addr_list[i],
- h->h_length);
- pat = &((*pat)->next);
+ result = -EAI_MEMORY;
+ goto free_and_return;
}
+ *pat = addrmem;
+ /* The conversion uses malloc unconditionally. */
+ malloc_addrmem = true;
}
}
else
diff --git a/sysdeps/s390/nptl/Makefile b/sysdeps/s390/nptl/Makefile
index 1333260..d105648 100644
--- a/sysdeps/s390/nptl/Makefile
+++ b/sysdeps/s390/nptl/Makefile
@@ -21,4 +21,5 @@ endif
ifeq ($(subdir),nptl)
libpthread-routines += ptw-sysdep
+libpthread-shared-only-routines += ptw-sysdep
endif
diff --git a/sysdeps/unix/alpha/Makefile b/sysdeps/unix/alpha/Makefile
index 441aa02..0660847 100644
--- a/sysdeps/unix/alpha/Makefile
+++ b/sysdeps/unix/alpha/Makefile
@@ -1,3 +1,4 @@
ifeq ($(subdir),rt)
librt-sysdep_routines += rt-sysdep
+librt-shared-only-routines += rt-sysdep
endif
diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
index 3769bef..6e56125 100644
--- a/sysdeps/unix/sysv/linux/alpha/Makefile
+++ b/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -41,4 +41,5 @@ endif # math
ifeq ($(subdir),nptl)
# pull in __syscall_error routine, __sigprocmask, __syscall_rt_sigaction
libpthread-routines += ptw-sysdep ptw-sigprocmask ptw-rt_sigaction
+libpthread-shared-only-routines += ptw-sysdep ptw-sigprocmask ptw-rt_sigaction
endif
diff --git a/sysdeps/unix/sysv/linux/arm/setcontext.S b/sysdeps/unix/sysv/linux/arm/setcontext.S
index 24c7294..926b65a 100644
--- a/sysdeps/unix/sysv/linux/arm/setcontext.S
+++ b/sysdeps/unix/sysv/linux/arm/setcontext.S
@@ -86,12 +86,19 @@ weak_alias(__setcontext, setcontext)
/* Called when a makecontext() context returns. Start the
context in R4 or fall through to exit(). */
+ /* Unwind descriptors are looked up based on PC - 2, so we have to
+ make sure to mark the instruction preceding the __startcontext
+ label as .cantunwind. */
+ .fnstart
+ .cantunwind
+ nop
ENTRY(__startcontext)
movs r0, r4
bne PLTJMP(__setcontext)
@ New context was 0 - exit
b PLTJMP(HIDDEN_JUMPTARGET(exit))
+ .fnend
END(__startcontext)
#ifdef PIC
diff --git a/sysdeps/unix/sysv/linux/dl-openat64.c b/sysdeps/unix/sysv/linux/dl-openat64.c
index 732097d..ae15e3a 100644
--- a/sysdeps/unix/sysv/linux/dl-openat64.c
+++ b/sysdeps/unix/sysv/linux/dl-openat64.c
@@ -23,10 +23,7 @@
int
-openat64 (dfd, file, oflag)
- int dfd;
- const char *file;
- int oflag;
+openat64 (int dfd, const char *file, int oflag, ...)
{
assert (!__OPEN_NEEDS_MODE (oflag));
diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
index 80da593..b365c97 100644
--- a/sysdeps/unix/sysv/linux/i386/Makefile
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
@@ -18,6 +18,7 @@ endif
# libpthread uses six-argument inline syscalls.
ifeq ($(subdir),nptl)
libpthread-sysdep_routines += libc-do-syscall
+libpthread-shared-only-routines += libc-do-syscall
endif
ifeq ($(subdir),resource)
diff --git a/sysdeps/unix/sysv/linux/i386/glob64.c b/sysdeps/unix/sysv/linux/i386/glob64.c
index b4fcd1a..802c957 100644
--- a/sysdeps/unix/sysv/linux/i386/glob64.c
+++ b/sysdeps/unix/sysv/linux/i386/glob64.c
@@ -1,3 +1,21 @@
+/* Two glob variants with 64-bit support, for dirent64 and __olddirent64.
+ Copyright (C) 1998-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
#include <dirent.h>
#include <glob.h>
#include <sys/stat.h>
@@ -38,11 +56,15 @@ int __old_glob64 (const char *__pattern, int __flags,
#undef dirent
#define dirent __old_dirent64
+#undef GL_READDIR
+# define GL_READDIR(pglob, stream) \
+ ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
#undef __readdir
#define __readdir(dirp) __old_readdir64 (dirp)
#undef glob
#define glob(pattern, flags, errfunc, pglob) \
__old_glob64 (pattern, flags, errfunc, pglob)
+#define convert_dirent __old_convert_dirent
#define glob_in_dir __old_glob_in_dir
#define GLOB_ATTRIBUTE attribute_compat_text_section
diff --git a/sysdeps/unix/sysv/linux/ia64/Makefile b/sysdeps/unix/sysv/linux/ia64/Makefile
index 1de62c5..4d6766d 100644
--- a/sysdeps/unix/sysv/linux/ia64/Makefile
+++ b/sysdeps/unix/sysv/linux/ia64/Makefile
@@ -19,6 +19,7 @@ endif
ifeq ($(subdir),rt)
librt-routines += rt-sysdep
+librt-shared-only-routines += rt-sysdep
endif
ifeq ($(subdir),nptl)
diff --git a/sysdeps/unix/sysv/linux/microblaze/Makefile b/sysdeps/unix/sysv/linux/microblaze/Makefile
index 44a838f..d178bc6 100644
--- a/sysdeps/unix/sysv/linux/microblaze/Makefile
+++ b/sysdeps/unix/sysv/linux/microblaze/Makefile
@@ -5,4 +5,5 @@ endif
ifeq ($(subdir),nptl)
# pull in __syscall_error routine
libpthread-routines += sysdep
-endif \ No newline at end of file
+libpthread-shared-only-routines += sysdep
+endif
diff --git a/sysdeps/unix/sysv/linux/mips/vfork.S b/sysdeps/unix/sysv/linux/mips/vfork.S
index 8915bea..e06c4e9 100644
--- a/sysdeps/unix/sysv/linux/mips/vfork.S
+++ b/sysdeps/unix/sysv/linux/mips/vfork.S
@@ -31,13 +31,13 @@
LOCALSZ= 1
FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
GPOFF= FRAMESZ-(1*SZREG)
-NESTED(__vfork,FRAMESZ,sp)
+NESTED(__libc_vfork,FRAMESZ,sp)
#ifdef __PIC__
SETUP_GP
#endif
PTR_SUBU sp, FRAMESZ
cfi_adjust_cfa_offset (FRAMESZ)
- SETUP_GP64_REG (a5, __vfork)
+ SETUP_GP64_REG (a5, __libc_vfork)
#ifdef __PIC__
SAVE_GP (GPOFF)
#endif
@@ -104,8 +104,10 @@ L(error):
RESTORE_GP64_REG
j __syscall_error
#endif
- END(__vfork)
+ END(__libc_vfork)
-libc_hidden_def(__vfork)
-weak_alias (__vfork, vfork)
-strong_alias (__vfork, __libc_vfork)
+#if IS_IN (libc)
+weak_alias (__libc_vfork, vfork)
+strong_alias (__libc_vfork, __vfork)
+libc_hidden_def (__vfork)
+#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index c89ed9e..2cfb46e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -8,6 +8,7 @@ abi-64-v2-condition := __WORDSIZE == 64 && _CALL_ELF == 2
ifeq ($(subdir),rt)
librt-routines += rt-sysdep
+librt-shared-only-routines += rt-sysdep
endif
ifeq ($(subdir),stdlib)
@@ -34,4 +35,5 @@ ifeq ($(subdir),nptl)
libpthread-routines += sysdep
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
elision-trylock
+libpthread-shared-only-routines += sysdep
endif
diff --git a/sysdeps/unix/sysv/linux/s390/Makefile b/sysdeps/unix/sysv/linux/s390/Makefile
index 497ffd5..f8ed013 100644
--- a/sysdeps/unix/sysv/linux/s390/Makefile
+++ b/sysdeps/unix/sysv/linux/s390/Makefile
@@ -6,6 +6,7 @@ abi-64-condition := __WORDSIZE == 64
ifeq ($(subdir),rt)
librt-routines += rt-sysdep
+librt-shared-only-routines += rt-sysdep
endif
ifeq ($(subdir),stdlib)
diff --git a/sysdeps/unix/sysv/linux/sparc/Makefile b/sysdeps/unix/sysv/linux/sparc/Makefile
index e67aecf..a67d199 100644
--- a/sysdeps/unix/sysv/linux/sparc/Makefile
+++ b/sysdeps/unix/sysv/linux/sparc/Makefile
@@ -6,6 +6,7 @@ abi-64-condition := __WORDSIZE == 64
ifeq ($(subdir),rt)
librt-routines += rt-sysdep
+librt-shared-only-routines += rt-sysdep
endif
ifeq ($(subdir),sysvipc)
@@ -15,4 +16,5 @@ endif
ifeq ($(subdir),nptl)
# pull in __syscall_error routine
libpthread-routines += sysdep
+libpthread-shared-only-routines += sysdep
endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
index e71ecbc..c42ba9b 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
@@ -21,7 +21,7 @@
.text
.globl __syscall_error
-ENTRY(__vfork)
+ENTRY(__libc_vfork)
ld [%g7 + PID], %o5
cmp %o5, 0
bne 1f
@@ -42,8 +42,10 @@ ENTRY(__vfork)
st %o5, [%g7 + PID]
1: retl
nop
-END(__vfork)
+END(__libc_vfork)
+#if IS_IN (libc)
+weak_alias (__libc_vfork, vfork)
+strong_alias (__libc_vfork, __vfork)
libc_hidden_def (__vfork)
-weak_alias (__vfork, vfork)
-strong_alias (__vfork, __libc_vfork)
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S b/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
index 6939ba3..506490c 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
@@ -21,7 +21,7 @@
.text
.globl __syscall_error
-ENTRY(__vfork)
+ENTRY(__libc_vfork)
ld [%g7 + PID], %o5
sethi %hi(0x80000000), %o3
cmp %o5, 0
@@ -42,8 +42,10 @@ ENTRY(__vfork)
st %o5, [%g7 + PID]
1: retl
nop
-END(__vfork)
+END(__libc_vfork)
+#if IS_IN (libc)
+weak_alias (__libc_vfork, vfork)
+strong_alias (__libc_vfork, __vfork)
libc_hidden_def (__vfork)
-weak_alias (__vfork, vfork)
-strong_alias (__vfork, __libc_vfork)
+#endif
diff --git a/sysdeps/unix/sysv/linux/tile/Makefile b/sysdeps/unix/sysv/linux/tile/Makefile
index 1c1cfff..43acea3 100644
--- a/sysdeps/unix/sysv/linux/tile/Makefile
+++ b/sysdeps/unix/sysv/linux/tile/Makefile
@@ -25,4 +25,5 @@ endif
ifeq ($(subdir),nptl)
# pull in __syscall_error routine
libpthread-routines += sysdep
+libpthread-shared-only-routines += sysdep
endif
diff --git a/timezone/private.h b/timezone/private.h
index 4e8f4ae..ed19e06 100644
--- a/timezone/private.h
+++ b/timezone/private.h
@@ -326,16 +326,6 @@ const char * scheck(const char * string, const char * format);
#define TYPE_SIGNED(type) (((type) -1) < 0)
#endif /* !defined TYPE_SIGNED */
-/* The minimum and maximum finite time values. */
-static time_t const time_t_min =
- (TYPE_SIGNED(time_t)
- ? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)
- : 0);
-static time_t const time_t_max =
- (TYPE_SIGNED(time_t)
- ? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
- : -1);
-
#ifndef INT_STRLEN_MAXIMUM
/*
** 302 / 1000 is log10(2.0) rounded up.