GIT update of git://sourceware.org/git/glibc.git/release/2.19/master from glibc-2.19

diff --git a/ChangeLog b/ChangeLog
index 81c393a..a81d623 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,645 @@
+2015-02-12  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #17964]
+	* sysdeps/powerpc/fpu/e_sqrt.c (__slow_ieee754_sqrt): Use
+	__builtin_fma instead of relying on contraction of a * b + c.
+
+2015-01-28  Adhemerval Zanellla  <azanella@linux.vnet.ibm.com>
+
+	[BZ #16576]
+	* sysdeps/powerpc/fpu/math_private.h [__CPU_HAS_FSQRT]: Remove define
+	and use _ARCH_PPCSQ instead.
+	(__ieee754_sqrt): Likewise.
+	(__ieee754_sqrtf): Likewise.
+	* sysdeps/powerpc/fpu/e_sqrt.c (__slow_ieee754_sqrt): Build only if
+	_ARCH_PPCSQ is defined.
+	(__ieee754_sqrt): Use _ARCH_PPCSQ to select wheter to use hardware
+	fsqrt instruction.
+	* sysdeps/powerpc/fpu/e_sqrtf.c (__ieee754_sqrtf): Build only if
+	_ARCH_PPCSQ is defined.
+	(__ieee754_sqrtf): Use _ARCH_PPCSQ to select wheter to use hardware
+	fsqrts instruction.
+	* sysdeps/powerpc/powerpc64/fpu/e_sqrt.c: Remove file.
+
+2016-08-15  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #20435]
+	* ports/sysdeps/unix/sysv/linux/arm/setcontext.S (__startcontext):
+	Mark as .cantunwind.
+
+2015-02-24  Eric Rannaud  <e@nanocritical.com>
+
+	[BZ #17523]
+	* io/fcntl.h (__OPEN_NEEDS_MODE): New macro.
+	* io/bits/fcntl2.h (open): Use it.
+	(openat): Likewise.
+	* io/open.c (__libc_open): Likewise.
+	* io/open64.c (__libc_open64): Likewise.
+	* io/open64_2.c (__open64_2): Likewise.
+	* io/open_2.c (__open_2): Likewise.
+	* io/openat.c (__openat): Likewise.
+	* io/openat64.c (__openat64): Likewise.
+	* io/openat64_2.c (__openat64_2): Likewise.
+	* io/openat_2.c (__openat_2): Likewise.
+	* sysdeps/mach/hurd/open.c (__libc_open): Likewise.
+	* sysdeps/mach/hurd/openat.c (__openat): Likewise.
+	* sysdeps/posix/open64.c (__libc_open64): Likewise.
+	* sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Likewise.
+	* ports/sysdeps/unix/sysv/linux/generic/open.c (__libc_open): Likewise.
+	(__open_nocancel): Likewise.
+	* ports/sysdeps/unix/sysv/linux/generic/open64.c (__libc_open64):
+	Likewise.
+	* sysdeps/unix/sysv/linux/open64.c (__libc_open64): Likewise.
+	* sysdeps/unix/sysv/linux/openat.c (__OPENAT): Likewise.
+
+2016-07-11  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #19018]
+	* stdlib/cxa_thread_atexit_impl.c (__cxa_thread_atexit_impl):
+	Mangle function pointer before storing it.
+	(__call_tls_dtors): Demangle function pointer before calling it.
+
+2016-07-11  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #18928]
+	* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove
+	_dl_pointer_guard member.
+	* elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard
+	initializer.
+	(security_init): Always set up pointer guard.
+	(process_envvars): Do not process LD_POINTER_GUARD.
+
+2016-07-11  Leonhard Holz  <leonhard.holz@web.de>
+
+	[BZ #16009]
+	* string/strxfrm_l.c (STRXFRM): Allocate fixed size cache for
+	weights and rules. Use do_xfrm_cached if data fits in cache,
+	do_xfrm otherwise.  Moved former main loop to...
+	* (do_xfrm_cached): New function.
+	* (do_xfrm): Non-caching version of do_xfrm_cached. Uses
+	find_idx, find_position and stack_push.
+	* (find_idx): New function.
+	* (find_position): Likewise.
+	* localedata/sort-test.sh: Added test run for do_xfrm.
+	* localedata/xfrm-test.c (main): Added command line option
+	-nocache to run the test with strings that are too large for
+	the STRXFRM cache.
+
+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-03-25  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #19791]
+	* resolv/res_send.c (close_and_return_error): New function.
+	(send_dg): Initialize *resplen2 after reopen failure.  Call
+	close_and_return_error for error returns.  On error paths without
+	__res_iclose, initialze *resplen2 explicitly.  Update comment for
+	successful return.
+
+2016-02-15  Carlos O'Donell  <carlos@redhat.com>
+
+	[BZ #18665]
+	* resolv/nss_dns/dns-host.c (gaih_getanswer_slice): Always set
+	*herrno_p.
+	(gaih_getanswer): Document functional behviour. Return tryagain
+	if any result is tryagain.
+	* resolv/res_query.c (__libc_res_nsearch): Set buffer size to zero
+	when freed.
+	* resolv/res_send.c: Add copyright text.
+	(__libc_res_nsend): Document that MAXPACKET is expected.
+	(send_vc): Document. Remove buffer reuse.
+	(send_dg): Document. Remove buffer reuse. Set *thisanssizp to set the
+	size of the buffer. Add Dprint for truncated UDP buffer.
+
+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-28  Stefan Liebler  <stli@linux.vnet.ibm.com>
+
+	[BZ #18508]
+	* stdlib/Makefile ($(objpfx)tst-makecontext3):
+	Depend on $(libdl).
+	* stdlib/tst-makecontext.c (cf): Test if _Unwind_Backtrace
+	is not called infinitely times.
+	(backtrace_helper): New function.
+	(trace_arg): New struct.
+	(st1): Enlarge stack size.
+	* sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S:
+	(__makecontext_ret): Omit cfi_startproc and cfi_endproc.
+	* sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S:
+	Likewise.
+
+2016-04-28  Stefan Liebler  <stli@linux.vnet.ibm.com>
+
+	[BZ #18080]
+	* sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
+	(__setcontext): Use SIG_SETMASK instead of SIG_BLOCK.
+	* sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S
+	(__setcontext): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
+	(__swapcontext): Use SIG_SETMASK instead of SIG_BLOCK.
+	Call rt_sigprocmask syscall one time to set new signal mask
+	and retrieve the current signal mask instead of two calls.
+	* sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
+	(__swapcontext): Likewise.
+	* stdlib/Makefile (tests): Add new testcase tst-setcontext2.
+	* stdlib/tst-setcontext2.c: New file.
+
+2016-04-01  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #19879]
+	CVE-2016-3075
+	* resolv/nss_dns/dns-network.c (_nss_dns_getnetbyname_r): Do not
+	copy name.
+
+2016-02-12  Florian Weimer  <fweimer@redhat.com>
+
+	* misc/bug18240.c (do_test): Set RLIMIT_AS.
+
+2016-01-27  Paul Eggert  <eggert@cs.ucla.edu>
+
+	[BZ #18240]
+	* misc/hsearch_r.c (isprime, __hcreate_r): Protect against
+	unsigned int wraparound.
+
+2016-01-27  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #18240]
+	* misc/bug18240.c: New test.
+	* misc/Makefile (tests): Add it.
+
+2015-08-25  Ondřej Bílka  <neleai@seznam.cz>
+
+	[BZ #18240]
+	* misc/hsearch_r.c (__hcreate_r): Handle overflow.
+
+2015-09-26  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+	[BZ #18985]
+	* time/strftime_l.c (a_wkday, f_wkday, a_month, f_month): Range check.
+	(__strftime_internal): Likewise.
+	* time/tst-strftime.c (do_bz18985): New test.
+	(do_test): Call it.
+
+2015-08-08  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+	[BZ #17905]
+	* catgets/Makefile (tst-catgets-mem): New test.
+	* catgets/catgets.c (catopen): Don't use unbounded alloca.
+	* catgets/open_catalog.c (__open_catalog): Likewise.
+	* catgets/tst-catgets.c (do_bz17905): Test unbounded alloca.
+
+2015-12-20  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	[BZ #16758]
+	* nscd/netgroupcache.c (addinnetgrX): Succeed if triplet has
+	blank values.
+
+	[BZ #16759]
+	* inet/getnetgrent_r.c (get_nonempty_val): New function.
+	(nscd_getnetgrent): Use it.
+
+	[BZ #16760]
+	* nscd/netgroupcache.c (addgetnetgrentX): Use memmove instead
+	of stpcpy.
+
+2015-11-24  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #17062]
+	* posix/fnmatch_loop.c (FCT): Rerrange loop for skipping over rest
+	of a bracket expr not to run off the end of the string.
+	* posix/Makefile (tests): Add tst-fnmatch3.
+	* posix/tst-fnmatch3.c: New file.
+
+2015-04-29  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #18007]
+	* nss/nss_files/files-XXX.c (CONCAT): Always enable stayopen.
+	(CVE-2014-8121)
+	* nss/tst-nss-getpwent.c: New file.
+	* nss/Makefile (tests): Add new test.
+
+2015-02-22  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+	[BZ #17269]
+	* libio/wstrops.c (_IO_wstr_overflow): Guard against integer overflow
+	(enlarge_userbuf): Likewise.
+
+2015-02-26  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #18032]
+	* posix/fnmatch_loop.c (FCT): Remove extra increment when skipping
+	over collating symbol inside a bracket expression.  Minor cleanup.
+
+2014-06-23  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #17079]
+	* nss/nss_files/files-XXX.c (get_contents): Store overflow marker
+	before reading the next line.
+
+2015-10-02  Andreas Schwab  <schwab@suse.de>
+
+	* sysdeps/posix/getaddrinfo.c (gaih_inet): Advance address pointer
+	when skipping over non-matching result from nscd.
+
+2015-09-11  Alan Modra  <amodra@gmail.com>
+
+	[BZ #17153]
+	* elf/elf.h (DT_PPC64_NUM): Correct value.
+	* NEWS: Add to fixed bug list.
+
+2014-03-20  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #16743]
+	* sysdeps/posix/getaddrinfo.c (gaih_inet): Properly skip over
+	non-matching result from nscd.
+
+2015-04-21  Arjun Shankar  <arjun.is@lostca.se>
+
+	[BZ #18287]
+	* resolv/nss_dns/dns-host.c (getanswer_r): Adjust buffer length
+	based on padding.  (CVE-2015-1781)
+
+2014-12-11  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #16657]
+	* nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Use
+	FORCE_ELISION instead of DO_ELISION.
+	* nptl/sysdeps/unix/sysv/linux/x86/force-elision.h (DO_ELISION):
+	Remove.
+
+2013-07-29  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	[BZ #17213]
+	* sysdeps/powerpc/powerpc64/entry.h: Fix TEXT_START definition for
+	powerpc64le.
+
+2014-11-11  Renlin Li  <Renlin.Li@arm.com>
+
+	[BZ #17555]
+	* ports/sysdeps/aarch64/start.S (_start): Delete x29 overwritten
+	assignment.
+
+2014-09-03  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17325]
+	* iconvdata/ibm1364.c (BODY): Fix check for sentinel.
+	* iconvdata/ibm932.c (BODY): Replace invalid sentinel check with
+	assert.
+	* iconvdata/ibm933.c (BODY): Fix check for sentinel.
+	* iconvdata/ibm935.c (BODY): Likewise.
+	* iconvdata/ibm937.c (BODY): Likewise.
+	* iconvdata/ibm939.c (BODY): Likewise.
+	* iconvdata/ibm943.c (BODY): Replace invalid sentinel check with
+	assert.
+	* iconvdata/Makefile (iconv-test.out): Pass module list to test
+	script.
+	* iconvdata/run-iconv-test.sh: New test loop for checking for
+	decoder crashers.
+
+2014-08-26  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17187]
+	* iconv/gconv_trans.c (struct known_trans, search_tree, lock,
+	trans_compare, open_translit, __gconv_translit_find):
+	Remove module loading code.
+
+2014-08-01  Stefan Liebler  <stli@linux.vnet.ibm.com>
+
+	* NEWS: Explain the s390 jmp_buf / ucontext_t ABI change
+	reversal.
+
+2014-07-31  Stefan Liebler  <stli@linux.vnet.ibm.com>
+
+	* sysdeps/s390/Makefile: Delete file.
+	* sysdeps/s390/Versions (GLIBC_2.19): Remove __setjmp.
+	* sysdeps/s390/__longjmp.c: Delete file.
+	* sysdeps/s390/bits/setjmp.h (__s390_jmp_buf):
+	Remove fields __flags and __reserved.
+	* sysdeps/s390/longjmp.c: Include setjmp/longjmp.c
+	and add versioning.
+	* sysdeps/s390/rtld-__longjmp.c: Delete file.
+	* sysdeps/s390/rtld-global-offsets.sym: Likewise.
+	* sysdeps/s390/rtld-setjmp.S: Likewise.
+	* sysdeps/s390/s390-32/__longjmp-common.c: Move to ...
+	* sysdeps/s390/s390-32/__longjmp.c: ... here.
+	* sysdeps/s390/s390-32/setjmp-common.S: Move to ...
+	* sysdeps/s390/s390-32/setjmp.S: ... here.
+	Add versioning.
+	(__sigsetjmp): Remove setting __flags field.
+	* sysdeps/s390/s390-64/__longjmp-common.c:Move to ...
+	* sysdeps/s390/s390-64/__longjmp.c: ... here.
+	* sysdeps/s390/s390-64/setjmp-common.S: Move to ...
+	* sysdeps/s390/s390-64/setjmp.S: ... here.
+	Add versioning.
+	(__sigsetjmp): Remove setting __flags field.
+	* sysdeps/s390/setjmp.S: Delete file.
+	* sysdeps/s390/sigjmp.c: Likewise.
+	* sysdeps/s390/v1-longjmp.c: Likewise.
+	* sysdeps/s390/v1-setjmp.h: Likewise.
+	* sysdeps/s390/v1-sigjmp.c: Likewise.
+	* sysdeps/unix/sysv/linux/s390/Makefile (sysdep_routines):
+	Remove v1-longjmp_chk.
+	* sysdeps/unix/sysv/linux/s390/getcontext.S: Delete file.
+	* sysdeps/unix/sysv/linux/s390/longjmp_chk.c:
+	Include debug/longjmp_chk.c and add versioning.
+	* nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c:
+	Include nptl/sysdeps/pthread/pt-longjmp.c and add versioning.
+	* sysdeps/unix/sysv/linux/s390/rtld-getcontext.S: Delete file.
+	* sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c:
+	Include __longjmp.c.
+	* sysdeps/unix/sysv/linux/s390/s390-32/getcontext-common.S:
+	Move to ...
+	* sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S: ... here.
+	(__getcontext): Remove setting __flags field.
+	Add versioning.
+	* sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S:
+	DonÂt restore upper high grps.
+	* sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S:
+	Likewise.
+	(__swapcontext): Remove setting uc_flags field.
+	* sysdeps/unix/sysv/linux/s390/s390-32/ucontext_i.sym:
+	Delete file.
+	* sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c:
+	Include __longjmp.c.
+	* sysdeps/unix/sysv/linux/s390/s390-64/getcontext-common.S:
+	Move to ...
+	* sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S: ... here.
+	(__getcontext): Remove setting __flags field.
+	Add versioning.
+	* sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S:
+	(__swapcontext): Remove setting uc_flags field.
+	* unix/sysv/linux/s390/s390-64/ucontext_i.sym: Delete file.
+	* sysdeps/unix/sysv/linux/s390/sys/ucontext.h (ucontext):
+	Remove fields uc_high_gprs and __reserved.
+	* sysdeps/unix/sysv/linux/s390/ucontext_i.sym:
+	New file with reverted content.
+	* sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c: Delete file.
+	* sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist:
+	Regenerated.
+	* sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist:
+	Regenerated.
+
+2014-07-02  Florian Weimer  <fweimer@redhat.com>
+
+	* manual/locale.texi (Locale Names): New section documenting
+	locale name syntax.  Adjust menu and node chaining accordingly.
+	(Choosing Locale): Reference Locale Names, Locale Categories.
+	Mention setting LC_ALL=C.  Reflect that name syntax is now
+	documented.
+	(Locale Categories): New section title.  Reference Locale Names.
+	LC_ALL is an environment variable, but not a category.
+	(Setting the Locale): Remove "locale -a" invocation and LOCPATH
+	description, now in Locale Name.  Reference that section.  Locale
+	name syntax is now documented.
+
+2014-07-02  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17137]
+	* locale/findlocale.c (name_present, valid_locale_name): New
+	functions.
+	(_nl_find_locale): Use the loc_name variable to store name
+	candidates.  Call name_present and valid_locale_name to check and
+	validate locale names.  Return an error if the locale is invalid.
+
+2014-07-02  Florian Weimer  <fweimer@redhat.com>
+
+	* locale/setlocale.c (setlocale): Use strdup for allocating
+	composite name copy.
+
+2014-05-26  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	[BZ #16878]
+	* nscd/netgroupcache.c (addgetnetgrentX): Look for
+	NSS_STATUS_TRYAGAIN to indicate insufficient buffer space.
+	* nscd/nss_files/files-netgrp.c (_nss_netgroup_parseline): Use
+	NSS_STATUS_TRYAGAIN to indicate insufficient buffer space.
+
+2014-03-12  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	[BZ #16695]
+	* nscd/netgroupcache.c (addgetnetgrentX): Factor in space for
+	key in the buffer.
+
+2014-06-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	[BZ #16046]
+	* elf/tst-dl-iter-static.c: New file.
+	* elf/Makefile (tests-static): Add tst-dl-iter-static.
+
+2014-06-20  Andreas Schwab  <schwab@linux-m68k.org>
+
+	[BZ #17069]
+	* posix/regcomp.c (parse_reg_exp): Deallocate partially
+	constructed tree before returning error.
+	* posix/bug-regexp36.c: Expand test case.
+
+2014-06-19  Andreas Schwab  <schwab@linux-m68k.org>
+
+	[BZ #17069]
+	* posix/regcomp.c (parse_expression): Deallocate partially
+	constructed tree before returning error.
+	* posix/Makefile.c (tests): Add bug-regex36.
+	(generated): Add bug-regex36.mtrace.
+	(tests-special): Add $(objpfx)bug-regex36-mem.out
+	(bug-regex36-ENV): New variable.
+	($(objpfx)bug-regex36-mem.out): New rule.
+	* posix/bug-regex36.c: New file.
+
+2014-06-03  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #15946]
+	* resolv/res_send.c (send_dg): Reload file descriptor after
+	calling reopen.
+
+2014-02-18  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #16574]
+	* resolv/res_send.c (send_vc): Add parameter ansp2_malloced.
+	Store non-zero if the second buffer was newly allocated.
+	(send_dg): Likewise.
+	(__libc_res_nsend): Add parameter ansp2_malloced and pass it down
+	to send_vc and send_dg.
+	(res_nsend): Pass NULL for ansp2_malloced.
+	* resolv/res_query.c (__libc_res_nquery): Add parameter
+	answerp2_malloced and pass it down to __libc_res_nsend.
+	(res_nquery): Pass additional NULL to __libc_res_nquery.
+	(__libc_res_nsearch): Add parameter answerp2_malloced and pass it
+	down to __libc_res_nquery and __libc_res_nquerydomain.  Deallocate
+	second answer buffer if answerp2_malloced was set.
+	(res_nsearch): Pass additional NULL to __libc_res_nsearch.
+	(__libc_res_nquerydomain): Add parameter
+	answerp2_malloced and pass it down to __libc_res_nquery.
+	(res_nquerydomain): Pass additional NULL to
+	__libc_res_nquerydomain.
+	* resolv/nss_dns/dns-network.c (_nss_dns_getnetbyname_r): Pass
+	additional NULL to __libc_res_nsend and __libc_res_nquery.
+	* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname3_r): Pass
+	additional NULL to __libc_res_nsearch.
+	(_nss_dns_gethostbyname4_r): Revert last change.  Use new
+	parameter of __libc_res_nsearch to check for separately allocated
+	second buffer.
+	(_nss_dns_gethostbyaddr2_r): Pass additional NULL to
+	__libc_res_nquery.
+	* resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Pass
+	additional NULL to __libc_res_nquery.
+	* resolv/gethnamaddr.c (gethostbyname2): Pass additional NULL to
+	__libc_res_nsearch.
+	(gethostbyaddr): Pass additional NULL to __libc_res_nquery.
+	* include/resolv.h: Update prototypes of __libc_res_nquery,
+	__libc_res_nsearch, __libc_res_nsend.
+
+2014-02-13  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #16574]
+	* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname4_r): Free the
+	second answer buffer if it was separately allocated.
+
+2014-05-12  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #16932]
+	* nis/nss_nis/nis-hosts.c (internal_gethostbyname2_r)
+	(_nss_nis_gethostbyname4_r): Return error if item length is larger
+	than maximum RPC packet size.
+	* nis/nss_nis/nis-initgroups.c (initgroups_netid): Likewise.
+	* nis/nss_nis/nis-network.c (_nss_nis_getnetbyname_r): Likewise.
+	* nis/nss_nis/nis-service.c (_nss_nis_getservbyname_r)
+	(_nss_nis_getservbyport_r): Likewise.
+
+2014-06-21  Allan McRae  <allan@archlinux.org>
+
+	* NEWS: Mention CVE-2014-4043.
+
+2014-06-12  Stefan Liebler  <stli@linux.vnet.ibm.com>
+
+	* posix/spawn_faction_addopen.c: Include string.h.
+
+2014-06-11  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17048]
+	* posix/spawn_int.h (struct __spawn_action): Make the path string
+	non-const to support deallocation.
+	* posix/spawn_faction_addopen.c
+	(posix_spawn_file_actions_addopen): Make a copy of the pathname.
+	* posix/spawn_faction_destroy.c
+	(posix_spawn_file_actions_destroy): Adjust comment.  Deallocate
+	path in all spawn_do_open actions.
+	* posix/tst-spawn.c (do_test): Exercise the copy operation in
+	posix_spawn_file_actions_addopen.
+
+2014-06-03  Guo Yixuan  <culu.gyx@gmail.com>
+
+	[BZ #16882]
+	* nptl/sysdeps/sparc/sparc32/pthread_spin_lock.S
+	(pthread_spin_lock): Branch out of spin loop to proper location.
+	* nptl/sysdeps/sparc/sparc64/pthread_spin_lock.S
+	(pthread_spin_lock): Likewise.
+
+	* nptl/tst-spin4.c: New test.
+	* nptl/Makefile (tests): Add tst-spin4.
+
+2014-05-17  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	[BZ #16958]
+	* sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S: Add missing
+	membar to avoid block loads/stores to overlap previous stores.
+
+2014-05-13  Sami Kerola  <kerolasa@iki.fi>
+
+	* timezone/Makefile ($(objpfx)tzselect): Use zonedir instead
+	current working directory
+
+2014-05-16  Allan McRae  <allan@archlinux.org>
+
+	* po/sv.po: Update Swedish translation from translation project.
+
+2014-05-16  Aurelien Jarno  <aurelien@aurel32.net>
+
+	[BZ #16943]
+	* sysdeps/unix/sysv/linux/sparc/bits/resource.h: Declare prlimit
+	and prlimit64.
+
+2014-05-06  Aurelien Jarno  <aurelien@aurel32.net>
+
+        [BZ# 16916]
+        * sysdeps/unix/sysv/linux/sparc/bits/eventfd.h (EFD_SEMAPHORE):
+        Define.
+
+2014-05-04  Allan McRae  <allan@archlinux.org>
+
+	* po/eo.po: Update Esperanto translation from translation project.
+
+2014-05-01  David S. Miller  <davem@davemloft.net>
+
+	[BZ #16885]
+	* sysdeps/sparc/sparc64/strcmp.S: Fix end comparison handling when
+	multiple zero bytes exist at the end of a string.
+	Reported by Aurelien Jarno <aurelien@aurel32.net>
+
+	* string/test-strcmp.c (check): Add explicit test for situations where
+	there are multiple zero bytes after the first.
+
+2014-02-27  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	[BZ #16623]
+	* sysdeps/ieee754/dbl-64/s_sin.c (__sin): Preserve sign of A
+	and DA.
+	(__cos): Likewise.
+
+2014-02-12  Dylan Alex Simon  <dylan@dylex.net>
+
+	[BZ #16545]
+	* sysdeps/x86_64/fpu/libm-test-ulps: Update on AMD family 21h
+	model 1.
+
 2014-02-06  Carlos O'Donell  <carlos@redhat.com>
 
 	[BZ #16529]
diff --git a/NEWS b/NEWS
index 98b479e..bdbf52b 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,104 @@ See the end for copying conditions.
 Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
 using `glibc' in the "product" field.
 
+Version 2.19.1
+
+* The following bugs are resolved with this release:
+
+  15946, 16009, 16545, 16574, 16576, 16623, 16657, 16695, 16743, 16758,
+  16759, 16760, 16878, 16882, 16885, 16916, 16932, 16943, 16958, 17048,
+  17062, 17069, 17079, 17137, 17153, 17213, 17263, 17269, 17325, 17523,
+  17555, 17905, 17964, 18007, 18032, 18080, 18240, 18287, 18508, 18665,
+  18905, 18928, 19018, 19779, 19791, 19879, 20010, 20112.
+
+* A buffer overflow in gethostbyname_r and related functions performing DNS
+  requests has been fixed.  If the NSS functions were called with a
+  misaligned buffer, the buffer length change due to pointer alignment was
+  not taken into account.  This could result in application crashes or,
+  potentially arbitrary code execution, using crafted, but syntactically
+  valid DNS responses.  (CVE-2015-1781)
+
+* Reverted change of ABI data structures for s390 and s390x:
+  On s390 and s390x the size of struct ucontext and jmp_buf was increased in
+  2.19. This change is reverted in 2.19.1 and 2.20. The introduced 2.19 symbol
+  versions of getcontext, setjmp, _setjmp, __sigsetjmp, longjmp, _longjmp,
+  siglongjmp are preserved pointing straight to the same implementation as the
+  old ones. Given that, new callers will simply provide a too-big buffer to
+  these functions. Any applications/libraries out there that embed jmp_buf or
+  ucontext_t in an ABI-relevant data structure that have already been rebuilt
+  against 2.19 headers will have to rebuilt again. This is necessary in any
+  case to revert the breakage in their ABI caused by the glibc change.
+
+* CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
+  copy the path argument.  This allowed programs to cause posix_spawn to
+  deference a dangling pointer, or use an unexpected pathname argument if
+  the string was modified after the posix_spawn_file_actions_addopen
+  invocation.
+
+* Locale names, including those obtained from environment variables (LANG
+  and the LC_* variables), are more tightly checked for proper syntax.
+  setlocale will now fail (with EINVAL) for locale names that are overly
+  long, contain slashes without starting with a slash, or contain ".." path
+  components. (CVE-2014-0475)  Previously, some valid locale names were
+  silently replaced with the "C" locale when running in AT_SECURE mode
+  (e.g., in a SUID program).  This is no longer necessary because of the
+  additional checks.
+
+* Support for loadable gconv transliteration modules has been removed.
+  The support for transliteration modules has been non-functional for
+  over a decade, and the removal is prompted by security defects.  The
+  normal gconv conversion modules are still supported.  Transliteration
+  with //TRANSLIT is still possible, and the //IGNORE specifier
+  continues to be  supported. (CVE-2014-5119)
+
+* Decoding a crafted input sequence in the character sets IBM933, IBM935,
+  IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
+  resulting a denial-of-service security vulnerability in applications which
+  use functions related to iconv. (CVE-2014-6040)
+
+* CVE-2014-8121 The NSS files backend would reset the file pointer used by
+  the get*ent functions if any of the query functions for the same database
+  are used during the iteration, causing a denial-of-service condition in
+  some applications.
+
+* The getnetbyname implementation in nss_dns had a potentially unbounded
+  alloca call (in the form of a call to strdupa), leading to a stack
+  overflow (stack exhaustion) and a crash if getnetbyname is invoked
+  on a very long name.  (CVE-2016-3075)
+
+* 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)
+
+* 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
+  the functions send_dg (send datagram) and send_vc (send TCP) for the
+  NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC
+  family.  The use of AF_UNSPEC triggers the low-level resolver code to
+  send out two parallel queries for A and AAAA.  A mismanagement of the
+  buffers used for those queries could result in the response of a query
+  writing beyond the alloca allocated buffer created by
+  _nss_dns_gethostbyname4_r.  Buffer management is simplified to remove
+  the overflow.  Thanks to the Google Security Team and Red Hat for
+  reporting the security impact of this issue, and Robert Holiday of
+  Ciena for reporting the related bug 18665. (CVE-2015-7547)
+
+* 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)
+
+* 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)
+
 Version 2.19
 
 * The following bugs are resolved with this release:
diff --git a/catgets/Makefile b/catgets/Makefile
index c95442d..8c39e3d 100644
--- a/catgets/Makefile
+++ b/catgets/Makefile
@@ -45,14 +45,14 @@ catgets-CPPFLAGS := -DNLSPATH='"$(msgcatdir)/%L/%N:$(msgcatdir)/%L/LC_MESSAGES/%
 CPPFLAGS-gencat = -DNOT_IN_libc
 
 generated = de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \
-	    test-gencat.h
+	    test-gencat.h tst-catgets.mtrace tst-catgets-mem.out
 generated-dirs = de
 
-tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de
+tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace
 
 ifeq ($(run-built-tests),yes)
 tests: $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
-       $(objpfx)test-gencat.out
+       $(objpfx)test-gencat.out $(objpfx)tst-catgets-mem.out
 # This test just checks whether the program produces any error or not.
 # The result is not tested.
 $(objpfx)test1.cat: test1.msg $(objpfx)gencat
@@ -80,4 +80,9 @@ $(objpfx)test-gencat.out: test-gencat.sh $(objpfx)test-gencat \
 $(objpfx)sample.SJIS.cat: sample.SJIS $(objpfx)gencat
 	GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
 	$(built-program-cmd) -H $(objpfx)test-gencat.h < $(word 1,$^) > $@
+
+$(objpfx)tst-catgets-mem.out: $(objpfx)tst-catgets.out
+	$(common-objpfx)malloc/mtrace $(objpfx)tst-catgets.mtrace > $@; \
+	$(evaluate-test)
+
 endif
diff --git a/catgets/catgets.c b/catgets/catgets.c
index eac2827..820c0f6 100644
--- a/catgets/catgets.c
+++ b/catgets/catgets.c
@@ -16,7 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <alloca.h>
 #include <errno.h>
 #include <locale.h>
 #include <nl_types.h>
@@ -35,6 +34,7 @@ catopen (const char *cat_name, int flag)
   __nl_catd result;
   const char *env_var = NULL;
   const char *nlspath = NULL;
+  char *tmp = NULL;
 
   if (strchr (cat_name, '/') == NULL)
     {
@@ -54,7 +54,10 @@ catopen (const char *cat_name, int flag)
 	{
 	  /* Append the system dependent directory.  */
 	  size_t len = strlen (nlspath) + 1 + sizeof NLSPATH;
-	  char *tmp = alloca (len);
+	  tmp = malloc (len);
+
+	  if (__glibc_unlikely (tmp == NULL))
+	    return (nl_catd) -1;
 
 	  __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
 	  nlspath = tmp;
@@ -65,16 +68,18 @@ catopen (const char *cat_name, int flag)
 
   result = (__nl_catd) malloc (sizeof (*result));
   if (result == NULL)
-    /* We cannot get enough memory.  */
-    return (nl_catd) -1;
-
-  if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
+    {
+      /* We cannot get enough memory.  */
+      result = (nl_catd) -1;
+    }
+  else if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
     {
       /* Couldn't open the file.  */
       free ((void *) result);
-      return (nl_catd) -1;
+      result = (nl_catd) -1;
     }
 
+  free (tmp);
   return (nl_catd) result;
 }
 
diff --git a/catgets/open_catalog.c b/catgets/open_catalog.c
index bc44f98..5fa4011 100644
--- a/catgets/open_catalog.c
+++ b/catgets/open_catalog.c
@@ -47,6 +47,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
   size_t tab_size;
   const char *lastp;
   int result = -1;
+  char *buf = NULL;
 
   if (strchr (cat_name, '/') != NULL || nlspath == NULL)
     fd = open_not_cancel_2 (cat_name, O_RDONLY);
@@ -57,23 +58,23 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
   if (__builtin_expect (bufact + (n) >= bufmax, 0))			      \
     {									      \
       char *old_buf = buf;						      \
-      bufmax += 256 + (n);						      \
-      buf = (char *) alloca (bufmax);					      \
-      memcpy (buf, old_buf, bufact);					      \
+      bufmax += (bufmax < 256 + (n)) ? 256 + (n) : bufmax;		      \
+      buf = realloc (buf, bufmax);					      \
+      if (__glibc_unlikely (buf == NULL))				      \
+	{								      \
+	  free (old_buf);						      \
+	  return -1;							      \
+	}								      \
     }
 
       /* The RUN_NLSPATH variable contains a colon separated list of
 	 descriptions where we expect to find catalogs.  We have to
 	 recognize certain % substitutions and stop when we found the
 	 first existing file.  */
-      char *buf;
       size_t bufact;
-      size_t bufmax;
+      size_t bufmax = 0;
       size_t len;
 
-      buf = NULL;
-      bufmax = 0;
-
       fd = -1;
       while (*run_nlspath != '\0')
 	{
@@ -188,7 +189,10 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
 
   /* Avoid dealing with directories and block devices */
   if (__builtin_expect (fd, 0) < 0)
-    return -1;
+    {
+      free (buf);
+      return -1;
+    }
 
   if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) < 0)
     goto close_unlock_return;
@@ -325,6 +329,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
   /* Release the lock again.  */
  close_unlock_return:
   close_not_cancel_no_status (fd);
+  free (buf);
 
   return result;
 }
diff --git a/catgets/tst-catgets.c b/catgets/tst-catgets.c
index fdaa834..25ef056 100644
--- a/catgets/tst-catgets.c
+++ b/catgets/tst-catgets.c
@@ -1,7 +1,10 @@
+#include <assert.h>
 #include <mcheck.h>
 #include <nl_types.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+#include <sys/resource.h>
 
 
 static const char *msgs[] =
@@ -12,6 +15,33 @@ static const char *msgs[] =
 };
 #define nmsgs (sizeof (msgs) / sizeof (msgs[0]))
 
+
+/* Test for unbounded alloca.  */
+static int
+do_bz17905 (void)
+{
+  char *buf;
+  struct rlimit rl;
+  nl_catd result;
+
+  const int sz = 1024 * 1024;
+
+  getrlimit (RLIMIT_STACK, &rl);
+  rl.rlim_cur = sz;
+  setrlimit (RLIMIT_STACK, &rl);
+
+  buf = malloc (sz + 1);
+  memset (buf, 'A', sz);
+  buf[sz] = '\0';
+  setenv ("NLSPATH", buf, 1);
+
+  result = catopen (buf, NL_CAT_LOCALE);
+  assert (result == (nl_catd) -1);
+
+  free (buf);
+  return 0;
+}
+
 #define ROUNDS 5
 
 int
@@ -62,5 +92,6 @@ main (void)
 	}
     }
 
+  result += do_bz17905 ();
   return result;
 }
diff --git a/elf/Makefile b/elf/Makefile
index 4c58fc9..b9da0b8 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -123,7 +123,7 @@ tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 \
 	tst-auxv
 tests-static = tst-tls1-static tst-tls2-static tst-stackguard1-static \
 	       tst-leaks1-static tst-array1-static tst-array5-static \
-	       tst-ptrguard1-static
+	       tst-ptrguard1-static tst-dl-iter-static
 ifeq (yes,$(build-shared))
 tests-static += tst-tls9-static
 tst-tls9-static-ENV = \
diff --git a/elf/elf.h b/elf/elf.h
index 40e87b2..78815e8 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -2283,7 +2283,7 @@ typedef Elf32_Addr Elf32_Conflict;
 #define DT_PPC64_OPD	(DT_LOPROC + 1)
 #define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
 #define DT_PPC64_OPT	(DT_LOPROC + 3)
-#define DT_PPC64_NUM    3
+#define DT_PPC64_NUM    4
 
 /* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry.  */
 #define PPC64_OPT_TLS		1
diff --git a/elf/rtld.c b/elf/rtld.c
index 6dcbabc..375c47d 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -162,7 +162,6 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
     ._dl_hwcap_mask = HWCAP_IMPORTANT,
     ._dl_lazy = 1,
     ._dl_fpu_control = _FPU_DEFAULT,
-    ._dl_pointer_guard = 1,
     ._dl_pagesize = EXEC_PAGESIZE,
     ._dl_inhibit_cache = 0,
 
@@ -857,15 +856,12 @@ security_init (void)
 #endif
 
   /* Set up the pointer guard as well, if necessary.  */
-  if (GLRO(dl_pointer_guard))
-    {
-      uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
-							     stack_chk_guard);
+  uintptr_t pointer_chk_guard
+    = _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
 #ifdef THREAD_SET_POINTER_GUARD
-      THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+  THREAD_SET_POINTER_GUARD (pointer_chk_guard);
 #endif
-      __pointer_chk_guard_local = pointer_chk_guard;
-    }
+  __pointer_chk_guard_local = pointer_chk_guard;
 
   /* We do not need the _dl_random value anymore.  The less
      information we leave behind, the better, so clear the
@@ -2605,9 +2601,6 @@ process_envvars (enum mode *modep)
 	      GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
 	      break;
 	    }
-
-	  if (memcmp (envline, "POINTER_GUARD", 13) == 0)
-	    GLRO(dl_pointer_guard) = envline[14] != '0';
 	  break;
 
 	case 14:
diff --git a/elf/tst-dl-iter-static.c b/elf/tst-dl-iter-static.c
new file mode 100644
index 0000000..7303d7c
--- /dev/null
+++ b/elf/tst-dl-iter-static.c
@@ -0,0 +1,47 @@
+/* BZ #16046 dl_iterate_phdr static executable test.
+   Copyright (C) 2014 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 <link.h>
+
+/* Check that the link map of the static executable itself is iterated
+   over exactly once.  */
+
+static int
+callback (struct dl_phdr_info *info, size_t size, void *data)
+{
+  int *count = data;
+
+  if (info->dlpi_name[0] == '\0')
+    (*count)++;
+
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  int count = 0;
+  int status;
+
+  status = dl_iterate_phdr (callback, &count);
+
+  return status || count != 1;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
index 1e25854..e0835fc 100644
--- a/iconv/gconv_trans.c
+++ b/iconv/gconv_trans.c
@@ -238,181 +238,12 @@ __gconv_transliterate (struct __gconv_step *step,
   return __GCONV_ILLEGAL_INPUT;
 }
 
-
-/* Structure to represent results of found (or not) transliteration
-   modules.  */
-struct known_trans
-{
-  /* This structure must remain the first member.  */
-  struct trans_struct info;
-
-  char *fname;
-  void *handle;
-  int open_count;
-};
-
-
-/* Tree with results of previous calls to __gconv_translit_find.  */
-static void *search_tree;
-
-/* We modify global data.   */
-__libc_lock_define_initialized (static, lock);
-
-
-/* Compare two transliteration entries.  */
-static int
-trans_compare (const void *p1, const void *p2)
-{
-  const struct known_trans *s1 = (const struct known_trans *) p1;
-  const struct known_trans *s2 = (const struct known_trans *) p2;
-
-  return strcmp (s1->info.name, s2->info.name);
-}
-
-
-/* Open (maybe reopen) the module named in the struct.  Get the function
-   and data structure pointers we need.  */
-static int
-open_translit (struct known_trans *trans)
-{
-  __gconv_trans_query_fct queryfct;
-
-  trans->handle = __libc_dlopen (trans->fname);
-  if (trans->handle == NULL)
-    /* Not available.  */
-    return 1;
-
-  /* Find the required symbol.  */
-  queryfct = __libc_dlsym (trans->handle, "gconv_trans_context");
-  if (queryfct == NULL)
-    {
-      /* We cannot live with that.  */
-    close_and_out:
-      __libc_dlclose (trans->handle);
-      trans->handle = NULL;
-      return 1;
-    }
-
-  /* Get the context.  */
-  if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames)
-      != 0)
-    goto close_and_out;
-
-  /* Of course we also have to have the actual function.  */
-  trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans");
-  if (trans->info.trans_fct == NULL)
-    goto close_and_out;
-
-  /* Now the optional functions.  */
-  trans->info.trans_init_fct =
-    __libc_dlsym (trans->handle, "gconv_trans_init");
-  trans->info.trans_context_fct =
-    __libc_dlsym (trans->handle, "gconv_trans_context");
-  trans->info.trans_end_fct =
-    __libc_dlsym (trans->handle, "gconv_trans_end");
-
-  trans->open_count = 1;
-
-  return 0;
-}
-
-
 int
 internal_function
 __gconv_translit_find (struct trans_struct *trans)
 {
-  struct known_trans **found;
-  const struct path_elem *runp;
-  int res = 1;
-
-  /* We have to have a name.  */
-  assert (trans->name != NULL);
-
-  /* Acquire the lock.  */
-  __libc_lock_lock (lock);
-
-  /* See whether we know this module already.  */
-  found = __tfind (trans, &search_tree, trans_compare);
-  if (found != NULL)
-    {
-      /* Is this module available?  */
-      if ((*found)->handle != NULL)
-	{
-	  /* Maybe we have to reopen the file.  */
-	  if ((*found)->handle != (void *) -1)
-	    /* The object is not unloaded.  */
-	    res = 0;
-	  else if (open_translit (*found) == 0)
-	    {
-	      /* Copy the data.  */
-	      *trans = (*found)->info;
-	      (*found)->open_count++;
-	      res = 0;
-	    }
-	}
-    }
-  else
-    {
-      size_t name_len = strlen (trans->name) + 1;
-      int need_so = 0;
-      struct known_trans *newp;
-
-      /* We have to continue looking for the module.  */
-      if (__gconv_path_elem == NULL)
-	__gconv_get_path ();
-
-      /* See whether we have to append .so.  */
-      if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0)
-	need_so = 1;
-
-      /* Create a new entry.  */
-      newp = (struct known_trans *) malloc (sizeof (struct known_trans)
-					    + (__gconv_max_path_elem_len
-					       + name_len + 3)
-					    + name_len);
-      if (newp != NULL)
-	{
-	  char *cp;
-
-	  /* Clear the struct.  */
-	  memset (newp, '\0', sizeof (struct known_trans));
-
-	  /* Store a copy of the module name.  */
-	  newp->info.name = cp = (char *) (newp + 1);
-	  cp = __mempcpy (cp, trans->name, name_len);
-
-	  newp->fname = cp;
-
-	  /* Search in all the directories.  */
-	  for (runp = __gconv_path_elem; runp->name != NULL; ++runp)
-	    {
-	      cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name),
-			      trans->name, name_len);
-	      if (need_so)
-		memcpy (cp, ".so", sizeof (".so"));
-
-	      if (open_translit (newp) == 0)
-		{
-		  /* We found a module.  */
-		  res = 0;
-		  break;
-		}
-	    }
-
-	  if (res)
-	    newp->fname = NULL;
-
-	  /* In any case we'll add the entry to our search tree.  */
-	  if (__tsearch (newp, &search_tree, trans_compare) == NULL)
-	    {
-	      /* Yickes, this should not happen.  Unload the object.  */
-	      res = 1;
-	      /* XXX unload here.  */
-	    }
-	}
-    }
-
-  __libc_lock_unlock (lock);
-
-  return res;
+  /* Transliteration module loading has been removed because it never
+     worked as intended and suffered from a security vulnerability.
+     Consequently, this function always fails.  */
+  return 1;
 }
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 5c2154e..3165d27 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -299,6 +299,7 @@ $(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
 $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
 			 $(addprefix $(objpfx),$(modules.so)) \
 			 $(common-objdir)/iconv/iconv_prog TESTS
+	iconv_modules="$(modules)" \
 	$(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@
 
 $(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c
index 373d49a..e9ea405 100644
--- a/iconvdata/ibm1364.c
+++ b/iconvdata/ibm1364.c
@@ -220,7 +220,8 @@ enum
 	  ++rp2;							      \
 									      \
 	uint32_t res;							      \
-	if (__builtin_expect (ch < rp2->start, 0)			      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
+	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = DB_TO_UCS4[ch + rp2->idx],			      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
 	  {								      \
diff --git a/iconvdata/ibm932.c b/iconvdata/ibm932.c
index 4ceeaae..a3f2583 100644
--- a/iconvdata/ibm932.c
+++ b/iconvdata/ibm932.c
@@ -73,11 +73,12 @@
 	  }								      \
 									      \
 	ch = (ch * 0x100) + inptr[1];					      \
+	/* ch was less than 0xfd.  */					      \
+	assert (ch < 0xfd00);						      \
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
-	    || __builtin_expect (ch < rp2->start, 0)			      \
+	if (__builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm932db_to_ucs4[ch + rp2->idx],		      \
 	    __builtin_expect (res, '\1') == 0 && ch !=0))		      \
 	  {								      \
diff --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
index 4723df4..7323df4 100644
--- a/iconvdata/ibm933.c
+++ b/iconvdata/ibm933.c
@@ -161,7 +161,7 @@ enum
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
 	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm933db_to_ucs4[ch + rp2->idx],		      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
diff --git a/iconvdata/ibm935.c b/iconvdata/ibm935.c
index 1ed311b..1af85df 100644
--- a/iconvdata/ibm935.c
+++ b/iconvdata/ibm935.c
@@ -161,7 +161,7 @@ enum
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
 	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm935db_to_ucs4[ch + rp2->idx],		      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
diff --git a/iconvdata/ibm937.c b/iconvdata/ibm937.c
index 1edaf62..a979bf4 100644
--- a/iconvdata/ibm937.c
+++ b/iconvdata/ibm937.c
@@ -161,7 +161,7 @@ enum
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
 	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm937db_to_ucs4[ch + rp2->idx],		      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
diff --git a/iconvdata/ibm939.c b/iconvdata/ibm939.c
index b40c486..93582bf 100644
--- a/iconvdata/ibm939.c
+++ b/iconvdata/ibm939.c
@@ -161,7 +161,7 @@ enum
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
 	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm939db_to_ucs4[ch + rp2->idx],		      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
diff --git a/iconvdata/ibm943.c b/iconvdata/ibm943.c
index 495e379..815c3d4 100644
--- a/iconvdata/ibm943.c
+++ b/iconvdata/ibm943.c
@@ -74,11 +74,12 @@
 	  }								      \
 									      \
 	ch = (ch * 0x100) + inptr[1];					      \
+	/* ch was less than 0xfd.  */					      \
+	assert (ch < 0xfd00);						      \
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
-	    || __builtin_expect (ch < rp2->start, 0)			      \
+	if (__builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm943db_to_ucs4[ch + rp2->idx],		      \
 	    __builtin_expect (res, '\1') == 0 && ch !=0))		      \
 	  {								      \
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index e23f60d..565600a 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -188,6 +188,24 @@ while read utf8 from filename; do
 
 done < TESTS2
 
+# Check for crashes in decoders.
+printf '\016\377\377\377\377\377\377\377' > $temp1
+for from in $iconv_modules ; do
+    echo $ac_n "test decoder $from $ac_c"
+    PROG=`eval echo $ICONV`
+    if $PROG < $temp1 >/dev/null 2>&1 ; then
+	: # fall through
+    else
+	status=$?
+	if test $status -gt 1 ; then
+	    echo "/FAILED"
+	    failed=1
+	    continue
+	fi
+    fi
+    echo "OK"
+done
+
 exit $failed
 # Local Variables:
 #  mode:shell-script
diff --git a/include/resolv.h b/include/resolv.h
index 87b3598..3904cb7 100644
--- a/include/resolv.h
+++ b/include/resolv.h
@@ -48,11 +48,11 @@ libc_hidden_proto (__res_randomid)
 libc_hidden_proto (__res_state)
 
 int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
-		       u_char **, u_char **, int *, int *);
+		       u_char **, u_char **, int *, int *, int *);
 int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
-			u_char **, u_char **, int *, int *);
+			u_char **, u_char **, int *, int *, int *);
 int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
-		      u_char *, int, u_char **, u_char **, int *, int *)
+		      u_char *, int, u_char **, u_char **, int *, int *, int *)
   attribute_hidden;
 
 libresolv_hidden_proto (_sethtent)
diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
index 62cdfda..f6d064d 100644
--- a/inet/getnetgrent_r.c
+++ b/inet/getnetgrent_r.c
@@ -235,6 +235,14 @@ endnetgrent (void)
 }
 
 #ifdef USE_NSCD
+static const char *
+get_nonempty_val (const char *in)
+{
+  if (*in == '\0')
+    return NULL;
+  return in;
+}
+
 static enum nss_status
 nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
 		  int *errnop)
@@ -243,11 +251,11 @@ nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
     return NSS_STATUS_UNAVAIL;
 
   datap->type = triple_val;
-  datap->val.triple.host = datap->cursor;
+  datap->val.triple.host = get_nonempty_val (datap->cursor);
   datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
-  datap->val.triple.user = datap->cursor;
+  datap->val.triple.user = get_nonempty_val (datap->cursor);
   datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
-  datap->val.triple.domain = datap->cursor;
+  datap->val.triple.domain = get_nonempty_val (datap->cursor);
   datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
 
   return NSS_STATUS_SUCCESS;
diff --git a/io/bits/fcntl2.h b/io/bits/fcntl2.h
index 4f13b10..bb8d233 100644
--- a/io/bits/fcntl2.h
+++ b/io/bits/fcntl2.h
@@ -20,7 +20,7 @@
 # error "Never include <bits/fcntl2.h> directly; use <fcntl.h> instead."
 #endif
 
-/* Check that calls to open and openat with O_CREAT set have an
+/* Check that calls to open and openat with O_CREAT or O_TMPFILE set have an
    appropriate third/fourth parameter.  */
 #ifndef __USE_FILE_OFFSET64
 extern int __open_2 (const char *__path, int __oflag) __nonnull ((1));
@@ -35,7 +35,7 @@ extern int __REDIRECT (__open_alias, (const char *__path, int __oflag, ...),
 __errordecl (__open_too_many_args,
 	     "open can be called either with 2 or 3 arguments, not more");
 __errordecl (__open_missing_mode,
-	     "open with O_CREAT in second argument needs 3 arguments");
+	     "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
 
 __fortify_function int
 open (const char *__path, int __oflag, ...)
@@ -45,7 +45,7 @@ open (const char *__path, int __oflag, ...)
 
   if (__builtin_constant_p (__oflag))
     {
-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 	{
 	  __open_missing_mode ();
 	  return __open_2 (__path, __oflag);
@@ -67,7 +67,7 @@ extern int __REDIRECT (__open64_alias, (const char *__path, int __oflag,
 __errordecl (__open64_too_many_args,
 	     "open64 can be called either with 2 or 3 arguments, not more");
 __errordecl (__open64_missing_mode,
-	     "open64 with O_CREAT in second argument needs 3 arguments");
+	     "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
 
 __fortify_function int
 open64 (const char *__path, int __oflag, ...)
@@ -77,7 +77,7 @@ open64 (const char *__path, int __oflag, ...)
 
   if (__builtin_constant_p (__oflag))
     {
-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 	{
 	  __open64_missing_mode ();
 	  return __open64_2 (__path, __oflag);
@@ -111,7 +111,7 @@ extern int __REDIRECT (__openat_alias, (int __fd, const char *__path,
 __errordecl (__openat_too_many_args,
 	     "openat can be called either with 3 or 4 arguments, not more");
 __errordecl (__openat_missing_mode,
-	     "openat with O_CREAT in third argument needs 4 arguments");
+	     "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
 
 __fortify_function int
 openat (int __fd, const char *__path, int __oflag, ...)
@@ -121,7 +121,7 @@ openat (int __fd, const char *__path, int __oflag, ...)
 
   if (__builtin_constant_p (__oflag))
     {
-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 	{
 	  __openat_missing_mode ();
 	  return __openat_2 (__fd, __path, __oflag);
@@ -145,7 +145,7 @@ extern int __REDIRECT (__openat64_alias, (int __fd, const char *__path,
 __errordecl (__openat64_too_many_args,
 	     "openat64 can be called either with 3 or 4 arguments, not more");
 __errordecl (__openat64_missing_mode,
-	     "openat64 with O_CREAT in third argument needs 4 arguments");
+	     "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
 
 __fortify_function int
 openat64 (int __fd, const char *__path, int __oflag, ...)
@@ -155,7 +155,7 @@ openat64 (int __fd, const char *__path, int __oflag, ...)
 
   if (__builtin_constant_p (__oflag))
     {
-      if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+      if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
 	{
 	  __openat64_missing_mode ();
 	  return __openat64_2 (__fd, __path, __oflag);
diff --git a/io/fcntl.h b/io/fcntl.h
index 28d83ae..16f792e 100644
--- a/io/fcntl.h
+++ b/io/fcntl.h
@@ -34,6 +34,15 @@ __BEGIN_DECLS
    numbers and flag bits for `open', `fcntl', et al.  */
 #include <bits/fcntl.h>
 
+/* Detect if open needs mode as a third argument (or for openat as a fourth
+   argument).  */
+#ifdef __O_TMPFILE
+# define __OPEN_NEEDS_MODE(oflag) \
+  (((oflag) & O_CREAT) != 0 || ((oflag) & __O_TMPFILE) == __O_TMPFILE)
+#else
+# define __OPEN_NEEDS_MODE(oflag) (((oflag) & O_CREAT) != 0)
+#endif
+
 /* POSIX.1-2001 specifies that these types are defined by <fcntl.h>.
    Earlier POSIX standards permitted any type ending in `_t' to be defined
    by any POSIX header, so we don't conditionalize the definitions here.  */
@@ -160,8 +169,9 @@ typedef __pid_t pid_t;
 extern int fcntl (int __fd, int __cmd, ...);
 
 /* Open FILE and return a new file descriptor for it, or -1 on error.
-   OFLAG determines the type of access used.  If O_CREAT is on OFLAG,
-   the third argument is taken as a `mode_t', the mode of the created file.
+   OFLAG determines the type of access used.  If O_CREAT or O_TMPFILE is set
+   in OFLAG, the third argument is taken as a `mode_t', the mode of the
+   created file.
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
diff --git a/io/open.c b/io/open.c
index 24aa380..d1df5c3 100644
--- a/io/open.c
+++ b/io/open.c
@@ -23,7 +23,7 @@
 #include <stdio.h>
 
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open (file, oflag)
@@ -38,7 +38,7 @@ __libc_open (file, oflag)
       return -1;
     }
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start(arg, oflag);
diff --git a/io/open64.c b/io/open64.c
index 3f3d2e8..def4e0b 100644
--- a/io/open64.c
+++ b/io/open64.c
@@ -21,7 +21,7 @@
 #include <stddef.h>
 #include <stdio.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open64 (file, oflag)
@@ -36,7 +36,7 @@ __libc_open64 (file, oflag)
       return -1;
     }
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/io/open64_2.c b/io/open64_2.c
index 7cafbba..dced8ab 100644
--- a/io/open64_2.c
+++ b/io/open64_2.c
@@ -22,8 +22,8 @@
 int
 __open64_2 (const char *file, int oflag)
 {
-  if (oflag & O_CREAT)
-    __fortify_fail ("invalid open64 call: O_CREAT without mode");
+  if (__OPEN_NEEDS_MODE (oflag))
+    __fortify_fail ("invalid open64 call: O_CREAT or O_TMPFILE without mode");
 
   return __open64 (file, oflag);
 }
diff --git a/io/open_2.c b/io/open_2.c
index 65d2c1c..d5b3afe 100644
--- a/io/open_2.c
+++ b/io/open_2.c
@@ -22,8 +22,8 @@
 int
 __open_2 (const char *file, int oflag)
 {
-  if (oflag & O_CREAT)
-    __fortify_fail ("invalid open call: O_CREAT without mode");
+  if (__OPEN_NEEDS_MODE (oflag))
+    __fortify_fail ("invalid open call: O_CREAT or O_TMPFILE without mode");
 
   return __open (file, oflag);
 }
diff --git a/io/openat.c b/io/openat.c
index 2d82270..f3ac8a7 100644
--- a/io/openat.c
+++ b/io/openat.c
@@ -30,7 +30,7 @@ int __have_atfcts;
 #endif
 
 /* Open FILE with access OFLAG.  Interpret relative paths relative to
-   the directory associated with FD.  If OFLAG includes O_CREAT, a
+   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
    third argument is the file protection.  */
 int
 __openat (fd, file, oflag)
@@ -60,7 +60,7 @@ __openat (fd, file, oflag)
 	}
     }
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/io/openat64.c b/io/openat64.c
index c0c4e19..d104bc1 100644
--- a/io/openat64.c
+++ b/io/openat64.c
@@ -23,7 +23,7 @@
 #include <sys/stat.h>
 
 /* Open FILE with access OFLAG.  Interpret relative paths relative to
-   the directory associated with FD.  If OFLAG includes O_CREAT, a
+   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
    third argument is the file protection.  */
 int
 __openat64 (fd, file, oflag)
@@ -53,7 +53,7 @@ __openat64 (fd, file, oflag)
 	}
     }
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/io/openat64_2.c b/io/openat64_2.c
index 6cfea6a..9c22a28 100644
--- a/io/openat64_2.c
+++ b/io/openat64_2.c
@@ -22,8 +22,8 @@
 int
 __openat64_2 (int fd, const char *file, int oflag)
 {
-  if (oflag & O_CREAT)
-    __fortify_fail ("invalid openat64 call: O_CREAT without mode");
+  if (__OPEN_NEEDS_MODE (oflag))
+    __fortify_fail ("invalid openat64 call: O_CREAT or O_TMPFILE without mode");
 
   return __openat64 (fd, file, oflag);
 }
diff --git a/io/openat_2.c b/io/openat_2.c
index 9e38c14..d15d1e9 100644
--- a/io/openat_2.c
+++ b/io/openat_2.c
@@ -22,8 +22,8 @@
 int
 __openat_2 (int fd, const char *file, int oflag)
 {
-  if (oflag & O_CREAT)
-    __fortify_fail ("invalid openat call: O_CREAT without mode");
+  if (__OPEN_NEEDS_MODE (oflag))
+    __fortify_fail ("invalid openat call: O_CREAT or O_TMPFILE without mode");
 
   return __openat (fd, file, oflag);
 }
diff --git a/libio/wstrops.c b/libio/wstrops.c
index 399a377..9218d4a 100644
--- a/libio/wstrops.c
+++ b/libio/wstrops.c
@@ -95,8 +95,11 @@ _IO_wstr_overflow (fp, c)
 	  wchar_t *old_buf = fp->_wide_data->_IO_buf_base;
 	  size_t old_wblen = _IO_wblen (fp);
 	  _IO_size_t new_size = 2 * old_wblen + 100;
-	  if (new_size < old_wblen)
+
+	  if (__glibc_unlikely (new_size < old_wblen)
+	      || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
 	    return EOF;
+
 	  new_buf
 	    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
 									* sizeof (wchar_t));
@@ -186,6 +189,9 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
     return 1;
 
   _IO_size_t newsize = offset + 100;
+  if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t)))
+    return 1;
+
   wchar_t *oldbuf = wd->_IO_buf_base;
   wchar_t *newbuf
     = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
diff --git a/locale/findlocale.c b/locale/findlocale.c
index 0c42b99..faeee61 100644
--- a/locale/findlocale.c
+++ b/locale/findlocale.c
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <assert.h>
+#include <errno.h>
 #include <locale.h>
 #include <stdlib.h>
 #include <string.h>
@@ -57,6 +58,45 @@ struct loaded_l10nfile *_nl_locale_file_list[__LC_LAST];
 
 const char _nl_default_locale_path[] attribute_hidden = LOCALEDIR;
 
+/* Checks if the name is actually present, that is, not NULL and not
+   empty.  */
+static inline int
+name_present (const char *name)
+{
+  return name != NULL && name[0] != '\0';
+}
+
+/* Checks that the locale name neither extremely long, nor contains a
+   ".." path component (to prevent directory traversal).  */
+static inline int
+valid_locale_name (const char *name)
+{
+  /* Not set.  */
+  size_t namelen = strlen (name);
+  /* Name too long.  The limit is arbitrary and prevents stack overflow
+     issues later.  */
+  if (__glibc_unlikely (namelen > 255))
+    return 0;
+  /* Directory traversal attempt.  */
+  static const char slashdot[4] = {'/', '.', '.', '/'};
+  if (__glibc_unlikely (memmem (name, namelen,
+				slashdot, sizeof (slashdot)) != NULL))
+    return 0;
+  if (namelen == 2 && __glibc_unlikely (name[0] == '.' && name [1] == '.'))
+    return 0;
+  if (namelen >= 3
+      && __glibc_unlikely (((name[0] == '.'
+			     && name[1] == '.'
+			     && name[2] == '/')
+			    || (name[namelen - 3] == '/'
+				&& name[namelen - 2] == '.'
+				&& name[namelen - 1] == '.'))))
+    return 0;
+  /* If there is a slash in the name, it must start with one.  */
+  if (__glibc_unlikely (memchr (name, '/', namelen) != NULL) && name[0] != '/')
+    return 0;
+  return 1;
+}
 
 struct __locale_data *
 internal_function
@@ -65,7 +105,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
 {
   int mask;
   /* Name of the locale for this category.  */
-  char *loc_name;
+  char *loc_name = (char *) *name;
   const char *language;
   const char *modifier;
   const char *territory;
@@ -73,31 +113,39 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
   const char *normalized_codeset;
   struct loaded_l10nfile *locale_file;
 
-  if ((*name)[0] == '\0')
+  if (loc_name[0] == '\0')
     {
       /* The user decides which locale to use by setting environment
 	 variables.  */
-      *name = getenv ("LC_ALL");
-      if (*name == NULL || (*name)[0] == '\0')
-	*name = getenv (_nl_category_names.str
+      loc_name = getenv ("LC_ALL");
+      if (!name_present (loc_name))
+	loc_name = getenv (_nl_category_names.str
 			+ _nl_category_name_idxs[category]);
-      if (*name == NULL || (*name)[0] == '\0')
-	*name = getenv ("LANG");
+      if (!name_present (loc_name))
+	loc_name = getenv ("LANG");
+      if (!name_present (loc_name))
+	loc_name = (char *) _nl_C_name;
     }
 
-  if (*name == NULL || (*name)[0] == '\0'
-      || (__builtin_expect (__libc_enable_secure, 0)
-	  && strchr (*name, '/') != NULL))
-    *name = (char *) _nl_C_name;
+  /* We used to fall back to the C locale if the name contains a slash
+     character '/', but we now check for directory traversal in
+     valid_locale_name, so this is no longer necessary.  */
 
-  if (__builtin_expect (strcmp (*name, _nl_C_name), 1) == 0
-      || __builtin_expect (strcmp (*name, _nl_POSIX_name), 1) == 0)
+  if (__builtin_expect (strcmp (loc_name, _nl_C_name), 1) == 0
+      || __builtin_expect (strcmp (loc_name, _nl_POSIX_name), 1) == 0)
     {
       /* We need not load anything.  The needed data is contained in
 	 the library itself.  */
       *name = (char *) _nl_C_name;
       return _nl_C[category];
     }
+  else if (!valid_locale_name (loc_name))
+    {
+      __set_errno (EINVAL);
+      return NULL;
+    }
+
+  *name = loc_name;
 
   /* We really have to load some data.  First we try the archive,
      but only if there was no LOCPATH environment variable specified.  */
diff --git a/locale/setlocale.c b/locale/setlocale.c
index b70fa6c..a4c5983 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -272,6 +272,8 @@ setlocale (int category, const char *locale)
 	 of entries of the form `CATEGORY=VALUE'.  */
       const char *newnames[__LC_LAST];
       struct __locale_data *newdata[__LC_LAST];
+      /* Copy of the locale argument, for in-place splitting.  */
+      char *locale_copy = NULL;
 
       /* Set all name pointers to the argument name.  */
       for (category = 0; category < __LC_LAST; ++category)
@@ -281,7 +283,13 @@ setlocale (int category, const char *locale)
       if (__builtin_expect (strchr (locale, ';') != NULL, 0))
 	{
 	  /* This is a composite name.  Make a copy and split it up.  */
-	  char *np = strdupa (locale);
+	  locale_copy = strdup (locale);
+	  if (__glibc_unlikely (locale_copy == NULL))
+	    {
+	      __libc_rwlock_unlock (__libc_setlocale_lock);
+	      return NULL;
+	    }
+	  char *np = locale_copy;
 	  char *cp;
 	  int cnt;
 
@@ -299,6 +307,7 @@ setlocale (int category, const char *locale)
 		{
 		error_return:
 		  __libc_rwlock_unlock (__libc_setlocale_lock);
+		  free (locale_copy);
 
 		  /* Bogus category name.  */
 		  ERROR_RETURN;
@@ -391,8 +400,9 @@ setlocale (int category, const char *locale)
       /* Critical section left.  */
       __libc_rwlock_unlock (__libc_setlocale_lock);
 
-      /* Free the resources (the locale path variable).  */
+      /* Free the resources.  */
       free (locale_path);
+      free (locale_copy);
 
       return composite;
     }
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index a570767..ff7ecb6 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-02  Florian Weimer  <fweimer@redhat.com>
+
+	* tst-setlocale3.c: New file.
+	* Makefile (tests): Add tst-setlocale3.
+	(tst-setlocale3-ENV): New variable.
+
 2013-12-26  Chris Leonard  <cjl@sugarlabs.org>
 
 	* locales/sa_IN: Add lang_name.
diff --git a/localedata/Makefile b/localedata/Makefile
index 7d157bf..d179765 100644
--- a/localedata/Makefile
+++ b/localedata/Makefile
@@ -77,7 +77,7 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl            \
 
 tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
 	tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
-	tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2
+	tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3
 tests-static = bug-setlocale1-static
 tests += $(tests-static)
 ifeq (yes,$(build-shared))
@@ -276,7 +276,7 @@ tst-xlocale2-ENV = $(TEST_MBWC_ENV)
 tst-strfmon1-ENV = $(TEST_MBWC_ENV)
 tst-strptime-ENV = $(TEST_MBWC_ENV)
 
-tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-JP
+tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-
 
 bug-iconv-trans-ENV = LOCPATH=$(common-objpfx)localedata
 
@@ -292,6 +292,7 @@ bug-setlocale1-ARGS = -- $(host-test-program-cmd)
 bug-setlocale1-static-ENV = $(bug-setlocale1-ENV)
 bug-setlocale1-static-ARGS = $(bug-setlocale1-ARGS)
 tst-setlocale2-ENV = LOCPATH=$(common-objpfx)localedata
+tst-setlocale3-ENV = LOCPATH=$(common-objpfx)localedata
 
 $(objdir)/iconvdata/gconv-modules:
 	$(MAKE) -C ../iconvdata subdir=iconvdata $@
diff --git a/localedata/sort-test.sh b/localedata/sort-test.sh
index 8a7ca89..b01a78e 100644
--- a/localedata/sort-test.sh
+++ b/localedata/sort-test.sh
@@ -49,11 +49,17 @@ for l in $lang; do
    ${common_objpfx}localedata/xfrm-test $id < $cns.in \
    > ${common_objpfx}localedata/$cns.xout || here=1
   cmp -s $cns.in ${common_objpfx}localedata/$cns.xout || here=1
+  LOCPATH=${common_objpfx}localedata GCONV_PATH=${common_objpfx}/iconvdata \
+   LC_ALL=$l ${test_program_prefix} \
+   ${common_objpfx}localedata/xfrm-test $id -nocache < $cns.in \
+   > ${common_objpfx}localedata/$cns.nocache.xout || here=1
+  cmp -s $cns.in ${common_objpfx}localedata/$cns.nocache.xout || here=1
   if test $here -eq 0; then
     echo "$l xfrm-test OK"
   else
     echo "$l xfrm-test FAIL"
     diff -u $cns.in ${common_objpfx}localedata/$cns.xout | sed 's/^/  /'
+    diff -u $cns.in ${common_objpfx}localedata/$cns.nocache.xout | sed 's/^/  /'
     status=1
   fi
 done
diff --git a/localedata/tst-setlocale3.c b/localedata/tst-setlocale3.c
new file mode 100644
index 0000000..e3b21a9
--- /dev/null
+++ b/localedata/tst-setlocale3.c
@@ -0,0 +1,203 @@
+/* Regression test for setlocale invalid environment variable handling.
+   Copyright (C) 2014 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 <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* The result of setlocale may be overwritten by subsequent calls, so
+   this wrapper makes a copy.  */
+static char *
+setlocale_copy (int category, const char *locale)
+{
+  const char *result = setlocale (category, locale);
+  if (result == NULL)
+    return NULL;
+  return strdup (result);
+}
+
+static char *de_locale;
+
+static void
+setlocale_fail (const char *envstring)
+{
+  setenv ("LC_CTYPE", envstring, 1);
+  if (setlocale (LC_CTYPE, "") != NULL)
+    {
+      printf ("unexpected setlocale success for \"%s\" locale\n", envstring);
+      exit (1);
+    }
+  const char *newloc = setlocale (LC_CTYPE, NULL);
+  if (strcmp (newloc, de_locale) != 0)
+    {
+      printf ("failed setlocale call \"%s\" changed locale to \"%s\"\n",
+	      envstring, newloc);
+      exit (1);
+    }
+}
+
+static void
+setlocale_success (const char *envstring)
+{
+  setenv ("LC_CTYPE", envstring, 1);
+  char *newloc = setlocale_copy (LC_CTYPE, "");
+  if (newloc == NULL)
+    {
+      printf ("setlocale for \"%s\": %m\n", envstring);
+      exit (1);
+    }
+  if (strcmp (newloc, de_locale) == 0)
+    {
+      printf ("setlocale with LC_CTYPE=\"%s\" left locale at \"%s\"\n",
+	      envstring, de_locale);
+      exit (1);
+    }
+  if (setlocale (LC_CTYPE, de_locale) == NULL)
+    {
+      printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n",
+	      de_locale, envstring);
+      exit (1);
+    }
+  char *newloc2 = setlocale_copy (LC_CTYPE, newloc);
+  if (newloc2 == NULL)
+    {
+      printf ("restoring locale \"%s\" following \"%s\": %m\n",
+	      newloc, envstring);
+      exit (1);
+    }
+  if (strcmp (newloc, newloc2) != 0)
+    {
+      printf ("representation of locale \"%s\" changed from \"%s\" to \"%s\"",
+	      envstring, newloc, newloc2);
+      exit (1);
+    }
+  free (newloc);
+  free (newloc2);
+
+  if (setlocale (LC_CTYPE, de_locale) == NULL)
+    {
+      printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n",
+	      de_locale, envstring);
+      exit (1);
+    }
+}
+
+/* Checks that a known-good locale still works if LC_ALL contains a
+   value which should be ignored.  */
+static void
+setlocale_ignore (const char *to_ignore)
+{
+  const char *fr_locale = "fr_FR.UTF-8";
+  setenv ("LC_CTYPE", fr_locale, 1);
+  char *expected_locale = setlocale_copy (LC_CTYPE, "");
+  if (expected_locale == NULL)
+    {
+      printf ("setlocale with LC_CTYPE=\"%s\" failed: %m\n", fr_locale);
+      exit (1);
+    }
+  if (setlocale (LC_CTYPE, de_locale) == NULL)
+    {
+      printf ("failed to restore locale: %m\n");
+      exit (1);
+    }
+  unsetenv ("LC_CTYPE");
+
+  setenv ("LC_ALL", to_ignore, 1);
+  setenv ("LC_CTYPE", fr_locale, 1);
+  const char *actual_locale = setlocale (LC_CTYPE, "");
+  if (actual_locale == NULL)
+    {
+      printf ("setlocale with LC_ALL, LC_CTYPE=\"%s\" failed: %m\n",
+	      fr_locale);
+      exit (1);
+    }
+  if (strcmp (actual_locale, expected_locale) != 0)
+    {
+      printf ("setlocale under LC_ALL failed: got \"%s\", expected \"%s\"\n",
+	      actual_locale, expected_locale);
+      exit (1);
+    }
+  unsetenv ("LC_CTYPE");
+  setlocale_success (fr_locale);
+  unsetenv ("LC_ALL");
+  free (expected_locale);
+}
+
+static int
+do_test (void)
+{
+  /* The glibc test harness sets this environment variable
+     uncondionally.  */
+  unsetenv ("LC_ALL");
+
+  de_locale = setlocale_copy (LC_CTYPE, "de_DE.UTF-8");
+  if (de_locale == NULL)
+    {
+      printf ("setlocale (LC_CTYPE, \"de_DE.UTF-8\"): %m\n");
+      return 1;
+    }
+  setlocale_success ("C");
+  setlocale_success ("en_US.UTF-8");
+  setlocale_success ("/en_US.UTF-8");
+  setlocale_success ("//en_US.UTF-8");
+  setlocale_ignore ("");
+
+  setlocale_fail ("does-not-exist");
+  setlocale_fail ("/");
+  setlocale_fail ("/../localedata/en_US.UTF-8");
+  setlocale_fail ("en_US.UTF-8/");
+  setlocale_fail ("en_US.UTF-8/..");
+  setlocale_fail ("en_US.UTF-8/../en_US.UTF-8");
+  setlocale_fail ("../localedata/en_US.UTF-8");
+  {
+    size_t large_length = 1024;
+    char *large_name = malloc (large_length + 1);
+    if (large_name == NULL)
+      {
+	puts ("malloc failure");
+	return 1;
+      }
+    memset (large_name, '/', large_length);
+    const char *suffix = "en_US.UTF-8";
+    strcpy (large_name + large_length - strlen (suffix), suffix);
+    setlocale_fail (large_name);
+    free (large_name);
+  }
+  {
+    size_t huge_length = 64 * 1024 * 1024;
+    char *huge_name = malloc (huge_length + 1);
+    if (huge_name == NULL)
+      {
+	puts ("malloc failure");
+	return 1;
+      }
+    memset (huge_name, 'X', huge_length);
+    huge_name[huge_length] = '\0';
+    /* Construct a composite locale specification. */
+    const char *prefix = "LC_CTYPE=de_DE.UTF-8;LC_TIME=";
+    memcpy (huge_name, prefix, strlen (prefix));
+    setlocale_fail (huge_name);
+    free (huge_name);
+  }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/localedata/xfrm-test.c b/localedata/xfrm-test.c
index d2aba7d..5cf29f6 100644
--- a/localedata/xfrm-test.c
+++ b/localedata/xfrm-test.c
@@ -23,7 +23,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
+/* Keep in sync with string/strxfrm_l.c.  */
+#define SMALL_STR_SIZE 4095
 
 struct lines
 {
@@ -37,6 +40,7 @@ int
 main (int argc, char *argv[])
 {
   int result = 0;
+  bool nocache = false;
   size_t nstrings, nstrings_max;
   struct lines *strings;
   char *line = NULL;
@@ -44,7 +48,18 @@ main (int argc, char *argv[])
   size_t n;
 
   if (argc < 2)
-    error (1, 0, "usage: %s <random seed>", argv[0]);
+    error (1, 0, "usage: %s <random seed> [-nocache]", argv[0]);
+
+  if (argc == 3)
+    {
+      if (strcmp (argv[2], "-nocache") == 0)
+	nocache = true;
+      else
+	{
+	  printf ("Unknown option %s!\n", argv[2]);
+	  exit (1);
+	}
+    }
 
   setlocale (LC_ALL, "");
 
@@ -59,9 +74,9 @@ main (int argc, char *argv[])
 
   while (1)
     {
-      char saved, *newp;
-      int needed;
-      int l;
+      char saved, *word, *newp;
+      size_t l, line_len, needed;
+
       if (getline (&line, &len, stdin) < 0)
 	break;
 
@@ -83,10 +98,35 @@ main (int argc, char *argv[])
 
       saved = line[l];
       line[l] = '\0';
-      needed = strxfrm (NULL, line, 0);
+
+      if (nocache)
+	{
+	  line_len = strlen (line);
+	  word = malloc (line_len + SMALL_STR_SIZE + 1);
+	  if (word == NULL)
+	    {
+	      printf ("malloc failed: %m\n");
+	      exit (1);
+	    }
+	  memset (word, ' ', SMALL_STR_SIZE);
+	  memcpy (word + SMALL_STR_SIZE, line, line_len);
+	  word[line_len + SMALL_STR_SIZE] = '\0';
+	}
+      else
+        word = line;
+
+      needed = strxfrm (NULL, word, 0);
       newp = malloc (needed + 1);
-      strxfrm (newp, line, needed + 1);
+      if (newp == NULL)
+	{
+	  printf ("malloc failed: %m\n");
+	  exit (1);
+	}
+      strxfrm (newp, word, needed + 1);
       strings[nstrings].xfrm = newp;
+
+      if (nocache)
+	free (word);
       line[l] = saved;
       ++nstrings;
     }
diff --git a/manual/examples/mkdirent.c b/manual/examples/mkdirent.c
new file mode 100644
index 0000000..f8400f4
diff --git a/misc/Makefile b/misc/Makefile
index b039182..ad9e921 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -76,7 +76,8 @@ install-lib := libg.a
 gpl2lgpl := error.c error.h
 
 tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
-	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
+	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \
+	 bug18240
 ifeq ($(run-built-tests),yes)
 tests: $(objpfx)tst-error1-mem
 endif
diff --git a/misc/bug18240.c b/misc/bug18240.c
new file mode 100644
index 0000000..773586e
--- /dev/null
+++ b/misc/bug18240.c
@@ -0,0 +1,97 @@
+/* Test integer wraparound in hcreate.
+   Copyright (C) 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 <errno.h>
+#include <limits.h>
+#include <search.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+
+static void
+test_size (size_t size)
+{
+  int res = hcreate (size);
+  if (res == 0)
+    {
+      if (errno == ENOMEM)
+        return;
+      printf ("error: hcreate (%zu): %m\n", size);
+      exit (1);
+    }
+  char *keys[100];
+  for (int i = 0; i < 100; ++i)
+    {
+      if (asprintf (keys + i, "%d", i) < 0)
+        {
+          printf ("error: asprintf: %m\n");
+          exit (1);
+        }
+      ENTRY e = { keys[i], (char *) "value" };
+      if (hsearch (e, ENTER) == NULL)
+        {
+          printf ("error: hsearch (\"%s\"): %m\n", keys[i]);
+          exit (1);
+        }
+    }
+  hdestroy ();
+
+  for (int i = 0; i < 100; ++i)
+    free (keys[i]);
+}
+
+static int
+do_test (void)
+{
+  /* Limit the size of the process, so that memory allocation will
+     fail without impacting the entire system.  */
+  {
+    struct rlimit limit;
+    if (getrlimit (RLIMIT_AS, &limit) != 0)
+      {
+        printf ("getrlimit (RLIMIT_AS) failed: %m\n");
+        return 1;
+      }
+    long target = 100 * 1024 * 1024;
+    if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target)
+      {
+        limit.rlim_cur = target;
+        if (setrlimit (RLIMIT_AS, &limit) != 0)
+          {
+            printf ("setrlimit (RLIMIT_AS) failed: %m\n");
+            return 1;
+          }
+      }
+  }
+
+  test_size (500);
+  test_size (-1);
+  test_size (-3);
+  test_size (INT_MAX - 2);
+  test_size (INT_MAX - 1);
+  test_size (INT_MAX);
+  test_size (((unsigned) INT_MAX) + 1);
+  test_size (UINT_MAX - 2);
+  test_size (UINT_MAX - 1);
+  test_size (UINT_MAX);
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/misc/hsearch_r.c b/misc/hsearch_r.c
index 81c27d8..af55212 100644
--- a/misc/hsearch_r.c
+++ b/misc/hsearch_r.c
@@ -19,7 +19,7 @@
 #include <errno.h>
 #include <malloc.h>
 #include <string.h>
-
+#include <stdint.h>
 #include <search.h>
 
 /* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
@@ -46,15 +46,12 @@ static int
 isprime (unsigned int number)
 {
   /* no even number will be passed */
-  unsigned int div = 3;
-
-  while (div * div < number && number % div != 0)
-    div += 2;
-
-  return number % div != 0;
+  for (unsigned int div = 3; div <= number / div; div += 2)
+    if (number % div == 0)
+      return 0;
+  return 1;
 }
 
-
 /* Before using the hash table we must allocate memory for it.
    Test for an existing table are done. We allocate one element
    more as the found prime number says. This is done for more effective
@@ -81,10 +78,19 @@ hcreate_r (nel, htab)
      use will not work.  */
   if (nel < 3)
     nel = 3;
-  /* Change nel to the first prime number not smaller as nel. */
-  nel |= 1;      /* make odd */
-  while (!isprime (nel))
-    nel += 2;
+
+  /* Change nel to the first prime number in the range [nel, UINT_MAX - 2],
+     The '- 2' means 'nel += 2' cannot overflow.  */
+  for (nel |= 1; ; nel += 2)
+    {
+      if (UINT_MAX - 2 < nel)
+	{
+	  __set_errno (ENOMEM);
+	  return 0;
+	}
+      if (isprime (nel))
+	break;
+    }
 
   htab->size = nel;
   htab->filled = 0;
diff --git a/misc/sys/xattr.h b/misc/sys/xattr.h
index 929cd87..796df90 100644
--- a/misc/sys/xattr.h
+++ b/misc/sys/xattr.h
@@ -26,6 +26,7 @@ __BEGIN_DECLS
 
 /* The following constants should be used for the fifth parameter of
    `*setxattr'.  */
+#ifndef __USE_KERNEL_XATTR_DEFS
 enum
 {
   XATTR_CREATE = 1,	/* set value, fail if attr already exists.  */
@@ -33,6 +34,7 @@ enum
   XATTR_REPLACE = 2	/* set value, fail if attr does not exist.  */
 #define XATTR_REPLACE	XATTR_REPLACE
 };
+#endif
 
 /* Set the attribute NAME of the file pointed to by PATH to VALUE (which
    is SIZE bytes long).  Return 0 on success, -1 for errors.  */
diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c
index f73a0ec..3006a99 100644
--- a/nis/nss_nis/nis-hosts.c
+++ b/nis/nss_nis/nis-hosts.c
@@ -270,6 +270,13 @@ internal_gethostbyname2_r (const char *name, int af, struct hostent *host,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
@@ -461,6 +468,13 @@ _nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
diff --git a/nis/nss_nis/nis-initgroups.c b/nis/nss_nis/nis-initgroups.c
index 30bc90f..dd8c765 100644
--- a/nis/nss_nis/nis-initgroups.c
+++ b/nis/nss_nis/nis-initgroups.c
@@ -150,6 +150,13 @@ initgroups_netid (uid_t uid, gid_t group, long int *start, long int *size,
 		  gid_t **groupsp, long int limit, int *errnop,
 		  const char *domainname)
 {
+  /* Limit domainname length to the maximum size of an RPC packet.  */
+  if (strlen (domainname) > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   /* Prepare the key.  The form is "unix.UID@DOMAIN" with the UID and
      DOMAIN field filled in appropriately.  */
   char key[sizeof ("unix.@") + sizeof (uid_t) * 3 + strlen (domainname)];
diff --git a/nis/nss_nis/nis-network.c b/nis/nss_nis/nis-network.c
index da28860..6a82302 100644
--- a/nis/nss_nis/nis-network.c
+++ b/nis/nss_nis/nis-network.c
@@ -179,6 +179,13 @@ _nss_nis_getnetbyname_r (const char *name, struct netent *net, char *buffer,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c
index fd79d3f..4991ed3 100644
--- a/nis/nss_nis/nis-service.c
+++ b/nis/nss_nis/nis-service.c
@@ -271,6 +271,13 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol,
   /* If the protocol is given, we could try if our NIS server knows
      about services.byservicename map. If yes, we only need one query.  */
   size_t keylen = strlen (name) + (protocol ? 1 + strlen (protocol) : 0);
+  /* Limit key length to the maximum size of an RPC packet.  */
+  if (keylen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char key[keylen + 1];
 
   /* key is: "name/proto" */
@@ -355,6 +362,13 @@ _nss_nis_getservbyport_r (int port, const char *protocol,
      Otherwise try first port/tcp, then port/udp and then fallback
      to sequential scanning of services.byname.  */
   const char *proto = protocol != NULL ? protocol : "tcp";
+  /* Limit protocol name length to the maximum size of an RPC packet.  */
+  if (strlen (proto) > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   do
     {
       /* key is: "port/proto" */
diff --git a/nptl/Makefile b/nptl/Makefile
index 57cc8c6..aa4a444 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -208,7 +208,7 @@ tests = tst-typesizes \
 	tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
 	tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
 	tst-mutexpi9 \
-	tst-spin1 tst-spin2 tst-spin3 \
+	tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
 	tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
 	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 4d5f75d..1157320 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -26,8 +26,8 @@
 #define lll_trylock_elision(a,t) lll_trylock(a)
 #endif
 
-#ifndef DO_ELISION
-#define DO_ELISION(m) 0
+#ifndef FORCE_ELISION
+#define FORCE_ELISION(m, s)
 #endif
 
 /* We don't force elision in trylock, because this can lead to inconsistent
@@ -69,7 +69,7 @@ __pthread_mutex_trylock (mutex)
       break;
 
     case PTHREAD_MUTEX_TIMED_ELISION_NP:
-    elision:
+    elision: __attribute__((unused))
       if (lll_trylock_elision (mutex->__data.__lock,
 			       mutex->__data.__elision) != 0)
         break;
@@ -77,8 +77,7 @@ __pthread_mutex_trylock (mutex)
       return 0;
 
     case PTHREAD_MUTEX_TIMED_NP:
-      if (DO_ELISION (mutex))
-	goto elision;
+      FORCE_ELISION (mutex, goto elision);
       /*FALL THROUGH*/
     case PTHREAD_MUTEX_ADAPTIVE_NP:
     case PTHREAD_MUTEX_ERRORCHECK_NP:
diff --git a/nptl/sysdeps/sparc/sparc32/pthread_spin_lock.S b/nptl/sysdeps/sparc/sparc32/pthread_spin_lock.S
index ea863d7..3accc69 100644
--- a/nptl/sysdeps/sparc/sparc32/pthread_spin_lock.S
+++ b/nptl/sysdeps/sparc/sparc32/pthread_spin_lock.S
@@ -19,11 +19,11 @@
 
 	.text
 ENTRY(pthread_spin_lock)
-	ldstub		[%o0], %g1
+1:	ldstub		[%o0], %g1
 	orcc		%g1, 0x0, %g0
 	bne,a		2f
 	 ldub		[%o0], %g1
-1:	retl
+	retl
 	 mov		0, %o0
 2:	orcc		%g1, 0x0, %g0
 	bne,a		2b
diff --git a/nptl/sysdeps/sparc/sparc64/pthread_spin_lock.S b/nptl/sysdeps/sparc/sparc64/pthread_spin_lock.S
index 0f849b2..aec6654 100644
--- a/nptl/sysdeps/sparc/sparc64/pthread_spin_lock.S
+++ b/nptl/sysdeps/sparc/sparc64/pthread_spin_lock.S
@@ -19,10 +19,10 @@
 
 	.text
 ENTRY(pthread_spin_lock)
-	ldstub		[%o0], %g1
+1:	ldstub		[%o0], %g1
 	brnz,pn		%g1, 2f
 	 membar		#StoreLoad | #StoreStore
-1:	retl
+	retl
 	 mov		0, %o0
 2:	ldub		[%o0], %g1
 	brnz,pt		%g1, 2b
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c b/nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
index 801432c..2a71c1a 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -15,49 +15,30 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.
 
-   This is a copy of pthread/pt-longjmp.c made for extending the
-   jmpbuf structure on System z.  */
+   Versioned copy of nptl/pt-longjmp.c modified for versioning
+   the reverted jmpbuf extension.  */
 
-#include <setjmp.h>
-#include <stdlib.h>
-#include <bits/wordsize.h>
-#include "pthreadP.h"
 #include  <shlib-compat.h>
-#if defined SHARED && SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_19)
-
-/* The __v1 version prototypes are declared in v1-setjmp.h which
-   cannot be included together with setjmp.h.  So we put the
-   prototypes here manually.  */
-extern void __v1__libc_siglongjmp (sigjmp_buf env, int val)
-     __attribute__ ((noreturn));
-extern void __v1__libc_longjmp (sigjmp_buf env, int val)
-     __attribute__ ((noreturn));
-
-void __v1_siglongjmp (sigjmp_buf env, int val)
-{
-  __v1__libc_siglongjmp (env, val);
-}
-
-void __v1_longjmp (jmp_buf env, int val)
-{
-  __v1__libc_longjmp (env, val);
-}
-
-compat_symbol (libpthread, __v1_longjmp, longjmp, GLIBC_2_0);
-compat_symbol (libpthread, __v1_siglongjmp, siglongjmp, GLIBC_2_0);
-#endif /* defined SHARED && SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_19))  */
-
-void
-__v2_longjmp (jmp_buf env, int val)
-{
-  __libc_longjmp (env, val);
-}
-
-void
-__v2_siglongjmp (jmp_buf env, int val)
-{
-  __libc_siglongjmp (env, val);
-}
-
-versioned_symbol (libpthread, __v2_longjmp, longjmp, GLIBC_2_19);
-versioned_symbol (libpthread, __v2_siglongjmp, siglongjmp, GLIBC_2_19);
+
+#if defined SHARED && SHLIB_COMPAT (libpthread, GLIBC_2_19, GLIBC_2_20)
+	/* we need a unique name in case of symbol versioning.  */
+# define longjmp __v1longjmp
+#endif /* defined SHARED && SHLIB_COMPAT (libpthread, GLIBC_2_19, GLIBC_2_20))  */
+
+#include <nptl/sysdeps/pthread/pt-longjmp.c>
+
+#if defined SHARED && SHLIB_COMPAT (libpthread, GLIBC_2_19, GLIBC_2_20)
+/* In glibc release 2.19 new versions of longjmp-functions were introduced,
+   but were reverted before 2.20. Thus both versions are the same function.  */
+
+# undef longjmp
+
+strong_alias (__v1longjmp, __v2longjmp)
+versioned_symbol (libpthread, __v1longjmp, longjmp, GLIBC_2_0);
+compat_symbol (libpthread, __v2longjmp, longjmp, GLIBC_2_19);
+
+weak_alias (siglongjmp, __v1siglongjmp)
+weak_alias (siglongjmp, __v2siglongjmp)
+versioned_symbol (libpthread, __v1siglongjmp, siglongjmp, GLIBC_2_0);
+compat_symbol (libpthread, __v2siglongjmp, siglongjmp, GLIBC_2_19);
+#endif /* defined SHARED && SHLIB_COMPAT (libpthread, GLIBC_2_19, GLIBC_2_20))  */
diff --git a/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h b/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h
index 945f886..a767cf1 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h
@@ -16,11 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-/* Check for elision on this lock without upgrading.  */
-#define DO_ELISION(m)							\
-  (__pthread_force_elision						\
-   && (m->__data.__kind & PTHREAD_MUTEX_NO_ELISION_NP) == 0)		\
-
 /* Automatically enable elision for existing user lock kinds.  */
 #define FORCE_ELISION(m, s)						\
   if (__pthread_force_elision						\
diff --git a/nptl/tst-spin4.c b/nptl/tst-spin4.c
new file mode 100644
index 0000000..5b23a17
--- /dev/null
+++ b/nptl/tst-spin4.c
@@ -0,0 +1,109 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int count = 0;
+
+static void *
+thread_add_one (void *arg)
+{
+  int tmp;
+  pthread_spinlock_t *lock = (pthread_spinlock_t *) arg;
+
+  /* When do_test holds the lock for 1 sec, the two thread will be
+     in contention for the lock. */
+  if (pthread_spin_lock (lock) != 0)
+    {
+      puts ("thread_add_one(): spin_lock failed");
+      pthread_exit ((void *) 1l);
+    }
+
+  /* sleep 1s before modifying count */
+  tmp = count;
+  sleep (1);
+  count = tmp + 1;
+
+  if (pthread_spin_unlock (lock) != 0)
+    {
+      puts ("thread_add_one(): spin_unlock failed");
+      pthread_exit ((void *) 1l);
+    }
+
+  return NULL;
+}
+
+static int
+do_test (void)
+{
+  pthread_t thr1, thr2;
+  pthread_spinlock_t lock;
+  int tmp;
+
+  if (pthread_spin_init (&lock, PTHREAD_PROCESS_PRIVATE) != 0)
+    {
+      puts ("spin_init failed");
+      return 1;
+    }
+
+  if (pthread_spin_lock (&lock) != 0)
+    {
+      puts ("1st spin_lock failed");
+      return 1;
+    }
+
+  if (pthread_create (&thr1, NULL, thread_add_one, (void *) &lock) != 0)
+    {
+      puts ("1st pthread_create failed");
+      return 1;
+    }
+
+  if (pthread_create (&thr2, NULL, thread_add_one, (void *) &lock) != 0)
+    {
+      puts ("2nd pthread_create failed");
+      return 1;
+    }
+
+  /* sleep 1s before modifying count */
+  tmp = count;
+  sleep (1);
+  count = tmp + 1;
+
+  if (pthread_spin_unlock (&lock) != 0)
+    {
+      puts ("1st spin_unlock failed");
+      return 1;
+    }
+
+  void *status;
+  if (pthread_join (thr1, &status) != 0)
+    {
+      puts ("1st pthread_join failed");
+      return 1;
+    }
+  if (status != NULL)
+    {
+      puts ("failure in the 1st thread");
+      return 1;
+    }
+  if (pthread_join (thr2, &status) != 0)
+    {
+      puts ("2nd pthread_join failed");
+      return 1;
+    }
+  if (status != NULL)
+    {
+      puts ("failure in the 2nd thread");
+      return 1;
+    }
+
+  if (count != 3)
+    {
+      printf ("count is %d, should be 3\n", count);
+      return 1;
+    }
+  return 0;
+}
+
+#define TIMEOUT 5
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index be01fe8..c61d10b 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -202,12 +202,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 		  {
 		    int e;
 		    status = getfct.f (&data, buffer + buffilled,
-				       buflen - buffilled, &e);
-		    if (status == NSS_STATUS_RETURN
-			|| status == NSS_STATUS_NOTFOUND)
-		      /* This was either the last one for this group or the
-			 group was empty.  Look at next group if available.  */
-		      break;
+				       buflen - buffilled - req->key_len, &e);
 		    if (status == NSS_STATUS_SUCCESS)
 		      {
 			if (data.type == triple_val)
@@ -216,6 +211,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 			    const char *nuser = data.val.triple.user;
 			    const char *ndomain = data.val.triple.domain;
 
+			    size_t hostlen = strlen (nhost ?: "") + 1;
+			    size_t userlen = strlen (nuser ?: "") + 1;
+			    size_t domainlen = strlen (ndomain ?: "") + 1;
+
 			    if (nhost == NULL || nuser == NULL || ndomain == NULL
 				|| nhost > nuser || nuser > ndomain)
 			      {
@@ -233,9 +232,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 				     : last + strlen (last) + 1 - buffer);
 
 				/* We have to make temporary copies.  */
-				size_t hostlen = strlen (nhost ?: "") + 1;
-				size_t userlen = strlen (nuser ?: "") + 1;
-				size_t domainlen = strlen (ndomain ?: "") + 1;
 				size_t needed = hostlen + userlen + domainlen;
 
 				if (buflen - req->key_len - bufused < needed)
@@ -269,9 +265,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 			      }
 
 			    char *wp = buffer + buffilled;
-			    wp = stpcpy (wp, nhost) + 1;
-			    wp = stpcpy (wp, nuser) + 1;
-			    wp = stpcpy (wp, ndomain) + 1;
+			    wp = memmove (wp, nhost ?: "", hostlen);
+			    wp += hostlen;
+			    wp = memmove (wp, nuser ?: "", userlen);
+			    wp += userlen;
+			    wp = memmove (wp, ndomain ?: "", domainlen);
+			    wp += domainlen;
 			    buffilled = wp - buffer;
 			    ++nentries;
 			  }
@@ -322,11 +321,18 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 			      }
 			  }
 		      }
-		    else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
+		    else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
 		      {
 			buflen *= 2;
 			buffer = xrealloc (buffer, buflen);
 		      }
+		    else if (status == NSS_STATUS_RETURN
+			     || status == NSS_STATUS_NOTFOUND
+			     || status == NSS_STATUS_UNAVAIL)
+		      /* This was either the last one for this group or the
+			 group was empty or the NSS module had an internal
+			 failure.  Look at next group if available.  */
+		      break;
 		  }
 
 	      enum nss_status (*endfct) (struct __netgrent *);
@@ -560,15 +566,19 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
 	{
 	  bool success = true;
 
-	  if (host != NULL)
+	  /* For the host, user and domain in each triplet, we assume success
+	     if the value is blank because that is how the wildcard entry to
+	     match anything is stored in the netgroup cache.  */
+	  if (host != NULL && *triplets != '\0')
 	    success = strcmp (host, triplets) == 0;
 	  triplets = (const char *) rawmemchr (triplets, '\0') + 1;
 
-	  if (success && user != NULL)
+	  if (success && user != NULL && *triplets != '\0')
 	    success = strcmp (user, triplets) == 0;
 	  triplets = (const char *) rawmemchr (triplets, '\0') + 1;
 
-	  if (success && (domain == NULL || strcmp (domain, triplets) == 0))
+	  if (success && (domain == NULL || *triplets == '\0'
+			  || strcmp (domain, triplets) == 0))
 	    {
 	      dataset->resp.result = 1;
 	      break;
diff --git a/nss/Makefile b/nss/Makefile
index c8880c0..3f9d2d0 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -37,7 +37,7 @@ install-bin             := getent makedb
 makedb-modules = xmalloc hash-string
 extra-objs		+= $(makedb-modules:=.o)
 
-tests			= test-netdb tst-nss-test1 test-digits-dots
+tests			= test-netdb tst-nss-test1 test-digits-dots tst-nss-getpwent
 xtests			= bug-erange
 
 include ../Makeconfig
diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
index 36242f9..3b90f7e 100644
--- a/nss/nss_files/files-XXX.c
+++ b/nss/nss_files/files-XXX.c
@@ -134,7 +134,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stayopen)
 
   __libc_lock_lock (lock);
 
-  status = internal_setent (stayopen);
+  status = internal_setent (1);
 
   if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
     {
@@ -198,10 +198,12 @@ get_contents (char *linebuf, size_t len, FILE *stream)
     {
       int curlen = ((remaining_len > (size_t) INT_MAX) ? INT_MAX
 		    : remaining_len);
-      char *p = fgets_unlocked (curbuf, curlen, stream);
 
+      /* Terminate the line so that we can test for overflow.  */
       ((unsigned char *) curbuf)[curlen - 1] = 0xff;
 
+      char *p = fgets_unlocked (curbuf, curlen, stream);
+
       /* EOF or read error.  */
       if (p == NULL)
         return gcr_error;
diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c
index 34eae4c..bc0b367 100644
--- a/nss/nss_files/files-netgrp.c
+++ b/nss/nss_files/files-netgrp.c
@@ -252,7 +252,7 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
   if (cp - host > buflen)
     {
       *errnop = ERANGE;
-      status = NSS_STATUS_UNAVAIL;
+      status = NSS_STATUS_TRYAGAIN;
     }
   else
     {
diff --git a/nss/tst-nss-getpwent.c b/nss/tst-nss-getpwent.c
new file mode 100644
index 0000000..f2e8abc
--- /dev/null
+++ b/nss/tst-nss-getpwent.c
@@ -0,0 +1,118 @@
+/* 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/>.  */
+
+#include <pwd.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+do_test (void)
+{
+  /* Count the number of entries in the password database, and fetch
+     data from the first and last entries.  */
+  size_t count = 0;
+  struct passwd * pw;
+  char *first_name = NULL;
+  uid_t first_uid = 0;
+  char *last_name = NULL;
+  uid_t last_uid = 0;
+  setpwent ();
+  while ((pw  = getpwent ()) != NULL)
+    {
+      if (first_name == NULL)
+	{
+	  first_name = strdup (pw->pw_name);
+	  if (first_name == NULL)
+	    {
+	      printf ("strdup: %m\n");
+	      return 1;
+	    }
+	  first_uid = pw->pw_uid;
+	}
+
+      free (last_name);
+      last_name = strdup (pw->pw_name);
+      if (last_name == NULL)
+	{
+	  printf ("strdup: %m\n");
+	  return 1;
+	}
+      last_uid = pw->pw_uid;
+      ++count;
+    }
+  endpwent ();
+
+  if (count == 0)
+    {
+      printf ("No entries in the password database.\n");
+      return 0;
+    }
+
+  /* Try again, this time interleaving with name-based and UID-based
+     lookup operations.  The counts do not match if the interleaved
+     lookups affected the enumeration.  */
+  size_t new_count = 0;
+  setpwent ();
+  while ((pw  = getpwent ()) != NULL)
+    {
+      if (new_count == count)
+	{
+	  printf ("Additional entry in the password database.\n");
+	  return 1;
+	}
+      ++new_count;
+      struct passwd *pw2 = getpwnam (first_name);
+      if (pw2 == NULL)
+	{
+	  printf ("getpwnam (%s) failed: %m\n", first_name);
+	  return 1;
+	}
+      pw2 = getpwnam (last_name);
+      if (pw2 == NULL)
+	{
+	  printf ("getpwnam (%s) failed: %m\n", last_name);
+	  return 1;
+	}
+      pw2 = getpwuid (first_uid);
+      if (pw2 == NULL)
+	{
+	  printf ("getpwuid (%llu) failed: %m\n",
+		  (unsigned long long) first_uid);
+	  return 1;
+	}
+      pw2 = getpwuid (last_uid);
+      if (pw2 == NULL)
+	{
+	  printf ("getpwuid (%llu) failed: %m\n",
+		  (unsigned long long) last_uid);
+	  return 1;
+	}
+    }
+  endpwent ();
+  if (new_count < count)
+    {
+      printf ("Missing entry in the password database.\n");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/po/eo.po b/po/eo.po
index d01582d..f6ea766 100644
--- a/po/eo.po
+++ b/po/eo.po
@@ -10,7 +10,7 @@ msgstr ""
 "Project-Id-Version: libc 2.18.90.20140105\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2014-01-05 17:40+1000\n"
-"PO-Revision-Date: 2014-01-08 21:23+0100\n"
+"PO-Revision-Date: 2014-04-22 22:50+0200\n"
 "Last-Translator: Benno Schulenberg <benno@vertaalt.nl>\n"
 "Language-Team: Esperanto <translation-team-eo@lists.sourceforge.net>\n"
 "Language: eo\n"
@@ -967,7 +967,7 @@ msgstr "mankas dosieraj argumentoj"
 #. TRANS expected to already exist.
 #: elf/ldd.bash.in:147 sysdeps/gnu/errlist.c:36
 msgid "No such file or directory"
-msgstr "Dosiero aü dosierujo ne ekzistas"
+msgstr "Dosiero aŭ dosierujo ne ekzistas"
 
 #: elf/ldd.bash.in:150 inet/rcmd.c:488
 msgid "not regular file"
@@ -992,7 +992,7 @@ msgstr "eraro: vi ne havas permeson legi"
 #: elf/pldd-xx.c:105
 #, c-format
 msgid "cannot find program header of process"
-msgstr ""
+msgstr "ne eblas trovi programĉapon de procezo"
 
 #: elf/pldd-xx.c:110
 #, c-format
@@ -1055,7 +1055,7 @@ msgstr "ne eblas malfermi %s/task"
 #: elf/pldd.c:145
 #, c-format
 msgid "cannot prepare reading %s/task"
-msgstr ""
+msgstr "ne eblas prepari legado de %s/task"
 
 #: elf/pldd.c:158
 #, c-format
@@ -1070,7 +1070,7 @@ msgstr ""
 #: elf/pldd.c:261
 #, c-format
 msgid "cannot get information about process %lu"
-msgstr ""
+msgstr "ne eblas ekhavi informon pri procezo %lu"
 
 #: elf/pldd.c:274
 #, c-format
@@ -1080,7 +1080,7 @@ msgstr "procezo %lu ne estas ELF-programo"
 #: elf/readelflib.c:34
 #, c-format
 msgid "file %s is truncated\n"
-msgstr ""
+msgstr "dosiero %s trunkiĝis\n"
 
 #: elf/readelflib.c:66
 #, c-format
@@ -1105,7 +1105,7 @@ msgstr ""
 #: elf/readelflib.c:108
 #, c-format
 msgid "more than one dynamic segment\n"
-msgstr ""
+msgstr "pli ol unu dinamika segmento\n"
 
 #: elf/readlib.c:96
 #, c-format
@@ -1191,7 +1191,7 @@ msgstr ""
 
 #: elf/sotruss.ksh:46
 msgid "Mandatory arguments to long options are also mandatory for any corresponding\\nshort options.\\n"
-msgstr ""
+msgstr "Endaj argumentoj por longaj opcioj ankaŭ endas por korespondaj mallongaj opcioj.\\n"
 
 #: elf/sotruss.ksh:55
 msgid "%s: option requires an argument -- '%s'\\n"
@@ -1576,7 +1576,7 @@ msgstr "malsukcesis eltrovi statinformon"
 
 #: inet/rcmd.c:493
 msgid "cannot open"
-msgstr ""
+msgstr "ne eblas malfermi"
 
 #: inet/rcmd.c:495
 msgid "fstat failed"
@@ -5788,7 +5788,7 @@ msgstr "Eraro de en-eligo"
 #. TRANS computer.
 #: sysdeps/gnu/errlist.c:82
 msgid "No such device or address"
-msgstr "Tiu aparato aü adreso ne ekzistas"
+msgstr "Tiu aparato aŭ adreso ne ekzistas"
 
 #. TRANS Argument list too long; used when the arguments passed to a new program
 #. TRANS being executed with one of the @code{exec} functions (@pxref{Executing a
@@ -6311,7 +6311,7 @@ msgstr "Ne subtenatas"
 #. TRANS or an incomplete sequence of bytes or the given wide character is invalid.
 #: sysdeps/gnu/errlist.c:931
 msgid "Invalid or incomplete multibyte or wide character"
-msgstr "Nevalida aü nekompleta plurbajta aü larĝa signo"
+msgstr "Nevalida aŭ nekompleta plurbajta aŭ larĝa signo"
 
 #. TRANS On @gnuhurdsystems{}, servers supporting the @code{term} protocol return
 #. TRANS this error for certain operations when the caller is not in the
diff --git a/po/sv.po b/po/sv.po
index beeb071..5f2fb07 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: libc 2.18.90.20140105\n"
 "POT-Creation-Date: 2014-01-05 17:40+1000\n"
-"PO-Revision-Date: 2014-01-09 10:33+0100\n"
+"PO-Revision-Date: 2014-05-06 18:15+0200\n"
 "Last-Translator: Jan Djärv <jan.h.d@swipnet.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -883,7 +883,7 @@ msgstr "bibliotek %s och %s i katalog %s har samma \"soname\" men olika typ."
 #: elf/ldconfig.c:1072
 #, c-format
 msgid "Warning: ignoring configuration file that cannot be opened: %s"
-msgstr "Varning: Ignorerar konfigurationsfil som inte kan öppnas: %s"
+msgstr "Varning: ignorerar konfigurationsfil som inte kan öppnas: %s"
 
 #: elf/ldconfig.c:1138
 #, c-format
@@ -4104,7 +4104,7 @@ msgstr "Skapa inte barnprocess, visa meddelanden på nuvarande tty"
 
 #: nscd/nscd.c:120
 msgid "Do not fork, but otherwise behave like a daemon"
-msgstr "Skapa inte brnprocess, men i allt annat uppträd som en demon"
+msgstr "Skapa inte barnprocess, men i allt annat uppträd som en demon"
 
 #: nscd/nscd.c:121
 msgid "NUMBER"
@@ -4630,7 +4630,7 @@ msgstr "problem när \"%s\" lästes"
 #: nss/makedb.c:799
 #, c-format
 msgid "failed to write new database file"
-msgstr "misslyckades med att skriva databasfil"
+msgstr "misslyckades med att skriva ny databasfil"
 
 #: nss/makedb.c:812
 #, c-format
@@ -5496,7 +5496,7 @@ msgstr "-Y sökväg\t\tkatalog för att hitta C preprocessorn (cpp)\n"
 #: sunrpc/rpc_main.c:1445
 #, c-format
 msgid "-5\t\tSysVr4 compatibility mode\n"
-msgstr "-5\t\tSysVr4 kompabilitetsläge\n"
+msgstr "-5\t\tSysVr4-kompatibilitetsläge\n"
 
 #: sunrpc/rpc_main.c:1446
 #, c-format
@@ -6812,7 +6812,7 @@ msgid ""
 "\n"
 "Report bugs to %s.\n"
 msgstr ""
-"%s: användning är %s [ --version ] [ --help ] [ -{vV} ] [ -{ct} [start,]slut] zonnamn ...\n"
+"%s: användning: %s [ --version ] [ --help ] [ -{vV} ] [ -{ct} [start,]slut] zonnamn ...\n"
 "Rapportera fel till %s.\n"
 "Rapportera fel eller synpunkter på översättningen till <tp-sv@listor.tp-sv.se>.\n"
 
diff --git a/ports/ChangeLog.aarch64 b/ports/ChangeLog.aarch64
index 6d4ab47..1dfc50b 100644
--- a/ports/ChangeLog.aarch64
+++ b/ports/ChangeLog.aarch64
@@ -1,3 +1,9 @@
+2014-05-21  Richard Henderson  <rth@redhat.com>
+
+	* sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+	(SINGLE_THREAD_P): Use the correct width load.  Fold an add
+	into the ldr offset.
+
 2014-01-22  Marcus Shawcroft  <marcus.shawcroft@arm.com>
 
 	* sysdeps/aarch64/libm-test-ulps: Regenerated.
diff --git a/ports/sysdeps/aarch64/start.S b/ports/sysdeps/aarch64/start.S
index 35d603a..69b45ea 100644
--- a/ports/sysdeps/aarch64/start.S
+++ b/ports/sysdeps/aarch64/start.S
@@ -47,7 +47,6 @@ _start:
 	/* Create an initial frame with 0 LR and FP */
 	mov	x29, #0
 	mov	x30, #0
-	mov	x29, sp
 
 	/* Setup rtld_fini in argument register */
 	mov	x5, x0
diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
index f6903b5..fed1dcb 100644
--- a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
@@ -162,9 +162,8 @@ extern int __local_multiple_threads attribute_hidden;
 #  else
 #   define SINGLE_THREAD_P						\
   adrp	x16, __local_multiple_threads;					\
-  add	x16, x16, #:lo12:__local_multiple_threads;			\
-  ldr	x16, [x16];							\
-  cmp	x16, 0;
+  ldr	w16, [x16, :lo12:__local_multiple_threads];			\
+  cmp	w16, 0;
 #  endif
 # else
 /*  There is no __local_multiple_threads for librt, so use the TCB.  */
@@ -180,12 +179,12 @@ extern int __local_multiple_threads attribute_hidden;
   cfi_rel_offset (x30, 8);						\
   bl	__read_tp;							\
   sub	x0, x0, PTHREAD_SIZEOF;						\
-  ldr	x16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET];			\
+  ldr	w16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET];			\
   ldp	x0, x30, [sp], 16;						\
   cfi_restore (x0);							\
   cfi_restore (x30);							\
   cfi_adjust_cfa_offset (-16);						\
-  cmp	x16, 0
+  cmp	w16, 0
 #   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
 #  endif
 # endif
diff --git a/ports/sysdeps/unix/sysv/linux/arm/setcontext.S b/ports/sysdeps/unix/sysv/linux/arm/setcontext.S
index 7b9b511..7da16a9 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/setcontext.S
+++ b/ports/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/ports/sysdeps/unix/sysv/linux/generic/open.c b/ports/sysdeps/unix/sysv/linux/generic/open.c
index 4f73fa0..b4c6834 100644
--- a/ports/sysdeps/unix/sysv/linux/generic/open.c
+++ b/ports/sysdeps/unix/sysv/linux/generic/open.c
@@ -22,14 +22,14 @@
 #include <stdio.h>
 #include <sysdep-cancel.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
@@ -59,7 +59,7 @@ __open_nocancel (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/ports/sysdeps/unix/sysv/linux/generic/open64.c b/ports/sysdeps/unix/sysv/linux/generic/open64.c
index 93d79e3..faea4df 100644
--- a/ports/sysdeps/unix/sysv/linux/generic/open64.c
+++ b/ports/sysdeps/unix/sysv/linux/generic/open64.c
@@ -22,14 +22,14 @@
 #include <stdio.h>
 #include <sysdep-cancel.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open64 (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/posix/Makefile b/posix/Makefile
index 6709900..8f6e6b5 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -86,7 +86,7 @@ tests		:= tstgetopt testfnm runtests runptests	     \
 		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
 		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
 		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
-		   tst-pathconf tst-getaddrinfo4
+		   tst-pathconf tst-getaddrinfo4 bug-regex36 tst-fnmatch3
 xtests		:= bug-ga2
 ifeq (yes,$(build-shared))
 test-srcs	:= globtest
@@ -110,7 +110,7 @@ generated := $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
 	     tst-pcre-mem tst-pcre.mtrace tst-boost-mem tst-boost.mtrace \
 	     bug-ga2.mtrace bug-ga2-mem bug-glob2.mtrace bug-glob2-mem \
 	     tst-vfork3-mem tst-vfork3.mtrace getconf.speclist \
-	     tst-fnmatch-mem tst-fnmatch.mtrace
+	     tst-fnmatch-mem tst-fnmatch.mtrace bug-regex36.mtrace
 
 include ../Rules
 
@@ -260,6 +260,12 @@ bug-regex31-ENV = MALLOC_TRACE=$(objpfx)bug-regex31.mtrace
 $(objpfx)bug-regex31-mem: $(objpfx)bug-regex31.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex31.mtrace > $@
 
+bug-regex36-ENV = MALLOC_TRACE=$(objpfx)bug-regex36.mtrace
+
+$(objpfx)bug-regex36-mem.out: $(objpfx)bug-regex36.out
+	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex36.mtrace > $@; \
+	$(evaluate-test)
+
 tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace
 
 $(objpfx)tst-vfork3-mem: $(objpfx)tst-vfork3.out
diff --git a/posix/bug-glob2.c b/posix/bug-glob2.c
index 8e21deb..3f9c620 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/bug-regex36.c b/posix/bug-regex36.c
new file mode 100644
index 0000000..59e2b6d
--- /dev/null
+++ b/posix/bug-regex36.c
@@ -0,0 +1,29 @@
+/* Test regcomp not leaking memory on parse errors
+   Copyright (C) 2014 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 <mcheck.h>
+#include <regex.h>
+
+int
+main (int argc, char **argv)
+{
+  regex_t r;
+  mtrace ();
+  regcomp (&r, "[a]\\|[a]\\{-2,}", 0);
+  regfree (&r);
+}
diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c
index f79d051..733cccb 100644
--- a/posix/fnmatch_loop.c
+++ b/posix/fnmatch_loop.c
@@ -899,11 +899,8 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 
 	  matched:
 	    /* Skip the rest of the [...] that already matched.  */
-	    do
+	    while ((c = *p++) != L (']'))
 	      {
-	      ignore_next:
-		c = *p++;
-
 		if (c == L('\0'))
 		  /* [... (unterminated) loses.  */
 		  return FNM_NOMATCH;
@@ -931,12 +928,11 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 
 			if (c < L('a') || c >= L('z'))
 			  {
-			    p = startp;
-			    goto ignore_next;
+			    p = startp - 2;
+			    break;
 			  }
 		      }
 		    p += 2;
-		    c = *p++;
 		  }
 		else if (c == L('[') && *p == L('='))
 		  {
@@ -947,25 +943,21 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 		    if (c != L('=') || p[1] != L(']'))
 		      return FNM_NOMATCH;
 		    p += 2;
-		    c = *p++;
 		  }
 		else if (c == L('[') && *p == L('.'))
 		  {
-		    ++p;
 		    while (1)
 		      {
 			c = *++p;
-			if (c == '\0')
+			if (c == L('\0'))
 			  return FNM_NOMATCH;
 
-			if (*p == L('.') && p[1] == L(']'))
+			if (c == L('.') && p[1] == L(']'))
 			  break;
 		      }
 		    p += 2;
-		    c = *p++;
 		  }
 	      }
-	    while (c != L(']'));
 	    if (not)
 	      return FNM_NOMATCH;
 	  }
diff --git a/posix/glob.c b/posix/glob.c
index f143108..ae3b8b7 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 (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
-		{
-		  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/regcomp.c b/posix/regcomp.c
index 921d0f4..076eca3 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -2154,7 +2154,11 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
 	{
 	  branch = parse_branch (regexp, preg, token, syntax, nest, err);
 	  if (BE (*err != REG_NOERROR && branch == NULL, 0))
-	    return NULL;
+	    {
+	      if (tree != NULL)
+		postorder (tree, free_tree, NULL);
+	      return NULL;
+	    }
 	}
       else
 	branch = NULL;
@@ -2415,14 +2419,21 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
   while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
 	 || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
     {
-      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
+      bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && dup_tree == NULL, 0))
+	{
+	  if (tree != NULL)
+	    postorder (tree, free_tree, NULL);
+	  return NULL;
+	}
+      tree = dup_tree;
       /* In BRE consecutive duplications are not allowed.  */
       if ((syntax & RE_CONTEXT_INVALID_DUP)
 	  && (token->type == OP_DUP_ASTERISK
 	      || token->type == OP_OPEN_DUP_NUM))
 	{
+	  if (tree != NULL)
+	    postorder (tree, free_tree, NULL);
 	  *err = REG_BADRPT;
 	  return NULL;
 	}
diff --git a/posix/spawn_faction_addopen.c b/posix/spawn_faction_addopen.c
index 47f6242..eba158c 100644
--- a/posix/spawn_faction_addopen.c
+++ b/posix/spawn_faction_addopen.c
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include <spawn.h>
 #include <unistd.h>
+#include <string.h>
 
 #include "spawn_int.h"
 
@@ -35,17 +36,24 @@ posix_spawn_file_actions_addopen (posix_spawn_file_actions_t *file_actions,
   if (fd < 0 || fd >= maxfd)
     return EBADF;
 
+  char *path_copy = strdup (path);
+  if (path_copy == NULL)
+    return ENOMEM;
+
   /* Allocate more memory if needed.  */
   if (file_actions->__used == file_actions->__allocated
       && __posix_spawn_file_actions_realloc (file_actions) != 0)
-    /* This can only mean we ran out of memory.  */
-    return ENOMEM;
+    {
+      /* This can only mean we ran out of memory.  */
+      free (path_copy);
+      return ENOMEM;
+    }
 
   /* Add the new value.  */
   rec = &file_actions->__actions[file_actions->__used];
   rec->tag = spawn_do_open;
   rec->action.open_action.fd = fd;
-  rec->action.open_action.path = path;
+  rec->action.open_action.path = path_copy;
   rec->action.open_action.oflag = oflag;
   rec->action.open_action.mode = mode;
 
diff --git a/posix/spawn_faction_destroy.c b/posix/spawn_faction_destroy.c
index 4d165aa..1b87010 100644
--- a/posix/spawn_faction_destroy.c
+++ b/posix/spawn_faction_destroy.c
@@ -18,11 +18,29 @@
 #include <spawn.h>
 #include <stdlib.h>
 
-/* Initialize data structure for file attribute for `spawn' call.  */
+#include "spawn_int.h"
+
+/* Deallocate the file actions.  */
 int
 posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
 {
-  /* Free the memory allocated.  */
+  /* Free the paths in the open actions.  */
+  for (int i = 0; i < file_actions->__used; ++i)
+    {
+      struct __spawn_action *sa = &file_actions->__actions[i];
+      switch (sa->tag)
+	{
+	case spawn_do_open:
+	  free (sa->action.open_action.path);
+	  break;
+	case spawn_do_close:
+	case spawn_do_dup2:
+	  /* No cleanup required.  */
+	  break;
+	}
+    }
+
+  /* Free the array of actions.  */
   free (file_actions->__actions);
   return 0;
 }
diff --git a/posix/spawn_int.h b/posix/spawn_int.h
index 5609e58..861e3b4 100644
--- a/posix/spawn_int.h
+++ b/posix/spawn_int.h
@@ -22,7 +22,7 @@ struct __spawn_action
     struct
     {
       int fd;
-      const char *path;
+      char *path;
       int oflag;
       mode_t mode;
     } open_action;
diff --git a/posix/tst-fnmatch3.c b/posix/tst-fnmatch3.c
new file mode 100644
index 0000000..2a83c1b
--- /dev/null
+++ b/posix/tst-fnmatch3.c
@@ -0,0 +1,30 @@
+/* Test for fnmatch not reading past the end of the pattern.
+   Copyright (C) 2014 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 <fnmatch.h>
+
+int
+do_test (void)
+{
+  const char *pattern = "[[:alpha:]'[:alpha:]\0]";
+
+  return fnmatch (pattern, "a", 0) != FNM_NOMATCH;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/tst-gnuglob.c b/posix/tst-gnuglob.c
index 1c72357..48c7527 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/posix/tst-spawn.c b/posix/tst-spawn.c
index 84cecf2..6cd874a 100644
--- a/posix/tst-spawn.c
+++ b/posix/tst-spawn.c
@@ -168,6 +168,7 @@ do_test (int argc, char *argv[])
   char fd2name[18];
   char fd3name[18];
   char fd4name[18];
+  char *name3_copy;
   char *spargv[12];
   int i;
 
@@ -222,9 +223,15 @@ do_test (int argc, char *argv[])
    if (posix_spawn_file_actions_addclose (&actions, fd1) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose");
    /* We want to open the third file.  */
-   if (posix_spawn_file_actions_addopen (&actions, fd3, name3,
+   name3_copy = strdup (name3);
+   if (name3_copy == NULL)
+     error (EXIT_FAILURE, errno, "strdup");
+   if (posix_spawn_file_actions_addopen (&actions, fd3, name3_copy,
 					 O_RDONLY, 0666) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen");
+   /* Overwrite the name to check that a copy has been made.  */
+   memset (name3_copy, 'X', strlen (name3_copy));
+
    /* We dup the second descriptor.  */
    fd4 = MAX (2, MAX (fd1, MAX (fd2, fd3))) + 1;
    if (posix_spawn_file_actions_adddup2 (&actions, fd2, fd4) != 0)
@@ -253,6 +260,7 @@ do_test (int argc, char *argv[])
    /* Cleanup.  */
    if (posix_spawn_file_actions_destroy (&actions) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy");
+   free (name3_copy);
 
   /* Wait for the child.  */
   if (waitpid (pid, &status, 0) != pid)
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index 1fd8f92..c73a0dc 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -621,7 +621,7 @@ gethostbyname2(name, af)
 	buf.buf = origbuf = (querybuf *) alloca (1024);
 
 	if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
-				    &buf.ptr, NULL, NULL, NULL)) < 0) {
+				    &buf.ptr, NULL, NULL, NULL, NULL)) < 0) {
 		if (buf.buf != origbuf)
 			free (buf.buf);
 		Dprintf("res_nsearch failed (%d)\n", n);
@@ -716,12 +716,12 @@ gethostbyaddr(addr, len, af)
 	buf.buf = orig_buf = (querybuf *) alloca (1024);
 
 	n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
-			      &buf.ptr, NULL, NULL, NULL);
+			      &buf.ptr, NULL, NULL, NULL, NULL);
 	if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
 		strcpy(qp, "ip6.int");
 		n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
 				      buf.buf != orig_buf ? MAXPACKET : 1024,
-				      &buf.ptr, NULL, NULL, NULL);
+				      &buf.ptr, NULL, NULL, NULL, NULL);
 	}
 	if (n < 0) {
 		if (buf.buf != orig_buf)
diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c
index a9db232..e8c112c 100644
--- a/resolv/nss_dns/dns-canon.c
+++ b/resolv/nss_dns/dns-canon.c
@@ -62,7 +62,7 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen,
     {
       int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
 				 buf, sizeof (buf), &ansp.ptr, NULL, NULL,
-				 NULL);
+				 NULL, NULL);
       if (r > 0)
 	{
 	  /* We need to decode the response.  Just one question record.
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index f8f192e..63029d9 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -190,7 +190,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
   host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
 
   n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
-			  1024, &host_buffer.ptr, NULL, NULL, NULL);
+			  1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
   if (n < 0)
     {
       switch (errno)
@@ -225,7 +225,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
 	n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
 				host_buffer.buf != orig_host_buffer
 				? MAXPACKET : 1024, &host_buffer.ptr,
-				NULL, NULL, NULL);
+				NULL, NULL, NULL, NULL);
 
       if (n < 0)
 	{
@@ -308,13 +308,20 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
   u_char *ans2p = NULL;
   int nans2p = 0;
   int resplen2 = 0;
+  int ans2p_malloced = 0;
 
   int olderr = errno;
   enum nss_status status;
   int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
 			      host_buffer.buf->buf, 2048, &host_buffer.ptr,
-			      &ans2p, &nans2p, &resplen2);
-  if (n < 0)
+			      &ans2p, &nans2p, &resplen2, &ans2p_malloced);
+  if (n >= 0)
+    {
+      status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
+			       resplen2, name, pat, buffer, buflen,
+			       errnop, herrnop, ttlp);
+    }
+  else
     {
       switch (errno)
 	{
@@ -341,16 +348,11 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 	*errnop = EAGAIN;
       else
 	__set_errno (olderr);
-
-      if (host_buffer.buf != orig_host_buffer)
-	free (host_buffer.buf);
-
-      return status;
     }
 
-  status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
-			  resplen2, name, pat, buffer, buflen,
-			  errnop, herrnop, ttlp);
+  /* Check whether ans2p was separately allocated.  */
+  if (ans2p_malloced)
+    free (ans2p);
 
   if (host_buffer.buf != orig_host_buffer)
     free (host_buffer.buf);
@@ -460,7 +462,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
 	  strcpy (qp, "].ip6.arpa");
 	  n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
 				 host_buffer.buf->buf, 1024, &host_buffer.ptr,
-				 NULL, NULL, NULL);
+				 NULL, NULL, NULL, NULL);
 	  if (n >= 0)
 	    goto got_it_already;
 	}
@@ -481,14 +483,14 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
     }
 
   n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
-			 1024, &host_buffer.ptr, NULL, NULL, NULL);
+			 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
   if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
     {
       strcpy (qp, "ip6.int");
       n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
 			     host_buffer.buf != orig_host_buffer
 			     ? MAXPACKET : 1024, &host_buffer.ptr,
-			     NULL, NULL, NULL);
+			     NULL, NULL, NULL, NULL);
     }
   if (n < 0)
     {
@@ -613,7 +615,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
   int have_to_map = 0;
   uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
   buffer += pad;
-  if (__builtin_expect (buflen < sizeof (struct host_data) + pad, 0))
+  buflen = buflen > pad ? buflen - pad : 0;
+  if (__builtin_expect (buflen < sizeof (struct host_data), 0))
     {
       /* The buffer is too small.  */
     too_small:
@@ -1049,7 +1052,10 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
   int h_namelen = 0;
 
   if (ancount == 0)
-    return NSS_STATUS_NOTFOUND;
+    {
+      *h_errnop = HOST_NOT_FOUND;
+      return NSS_STATUS_NOTFOUND;
+    }
 
   while (ancount-- > 0 && cp < end_of_message && had_error == 0)
     {
@@ -1226,7 +1232,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
   /* Special case here: if the resolver sent a result but it only
      contains a CNAME while we are looking for a T_A or T_AAAA record,
      we fail with NOTFOUND instead of TRYAGAIN.  */
-  return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
+  if (canon != NULL)
+    {
+      *h_errnop = HOST_NOT_FOUND;
+      return NSS_STATUS_NOTFOUND;
+    }
+
+  *h_errnop = NETDB_INTERNAL;
+  return NSS_STATUS_TRYAGAIN;
 }
 
 
@@ -1240,11 +1253,101 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
 
   enum nss_status status = NSS_STATUS_NOTFOUND;
 
+  /* Combining the NSS status of two distinct queries requires some
+     compromise and attention to symmetry (A or AAAA queries can be
+     returned in any order).  What follows is a breakdown of how this
+     code is expected to work and why. We discuss only SUCCESS,
+     TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
+     that apply (though RETURN and MERGE exist).  We make a distinction
+     between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
+     A recoverable TRYAGAIN is almost always due to buffer size issues
+     and returns ERANGE in errno and the caller is expected to retry
+     with a larger buffer.
+
+     Lastly, you may be tempted to make significant changes to the
+     conditions in this code to bring about symmetry between responses.
+     Please don't change anything without due consideration for
+     expected application behaviour.  Some of the synthesized responses
+     aren't very well thought out and sometimes appear to imply that
+     IPv4 responses are always answer 1, and IPv6 responses are always
+     answer 2, but that's not true (see the implementation of send_dg
+     and send_vc to see response can arrive in any order, particularly
+     for UDP). However, we expect it holds roughly enough of the time
+     that this code works, but certainly needs to be fixed to make this
+     a more robust implementation.
+
+     ----------------------------------------------
+     | Answer 1 Status /   | Synthesized | Reason |
+     | Answer 2 Status     | Status      |        |
+     |--------------------------------------------|
+     | SUCCESS/SUCCESS     | SUCCESS     | [1]    |
+     | SUCCESS/TRYAGAIN    | TRYAGAIN    | [5]    |
+     | SUCCESS/TRYAGAIN'   | SUCCESS     | [1]    |
+     | SUCCESS/NOTFOUND    | SUCCESS     | [1]    |
+     | SUCCESS/UNAVAIL     | SUCCESS     | [1]    |
+     | TRYAGAIN/SUCCESS    | TRYAGAIN    | [2]    |
+     | TRYAGAIN/TRYAGAIN   | TRYAGAIN    | [2]    |
+     | TRYAGAIN/TRYAGAIN'  | TRYAGAIN    | [2]    |
+     | TRYAGAIN/NOTFOUND   | TRYAGAIN    | [2]    |
+     | TRYAGAIN/UNAVAIL    | TRYAGAIN    | [2]    |
+     | TRYAGAIN'/SUCCESS   | SUCCESS     | [3]    |
+     | TRYAGAIN'/TRYAGAIN  | TRYAGAIN    | [3]    |
+     | TRYAGAIN'/TRYAGAIN' | TRYAGAIN'   | [3]    |
+     | TRYAGAIN'/NOTFOUND  | TRYAGAIN'   | [3]    |
+     | TRYAGAIN'/UNAVAIL   | UNAVAIL     | [3]    |
+     | NOTFOUND/SUCCESS    | SUCCESS     | [3]    |
+     | NOTFOUND/TRYAGAIN   | TRYAGAIN    | [3]    |
+     | NOTFOUND/TRYAGAIN'  | TRYAGAIN'   | [3]    |
+     | NOTFOUND/NOTFOUND   | NOTFOUND    | [3]    |
+     | NOTFOUND/UNAVAIL    | UNAVAIL     | [3]    |
+     | UNAVAIL/SUCCESS     | UNAVAIL     | [4]    |
+     | UNAVAIL/TRYAGAIN    | UNAVAIL     | [4]    |
+     | UNAVAIL/TRYAGAIN'   | UNAVAIL     | [4]    |
+     | UNAVAIL/NOTFOUND    | UNAVAIL     | [4]    |
+     | UNAVAIL/UNAVAIL     | UNAVAIL     | [4]    |
+     ----------------------------------------------
+
+     [1] If the first response is a success we return success.
+	 This ignores the state of the second answer and in fact
+	 incorrectly sets errno and h_errno to that of the second
+	 answer.  However because the response is a success we ignore
+	 *errnop and *h_errnop (though that means you touched errno on
+	 success).  We are being conservative here and returning the
+	 likely IPv4 response in the first answer as a success.
+
+     [2] If the first response is a recoverable TRYAGAIN we return
+	 that instead of looking at the second response.  The
+	 expectation here is that we have failed to get an IPv4 response
+	 and should retry both queries.
+
+     [3] If the first response was not a SUCCESS and the second
+	 response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
+	 or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
+	 result from the second response, otherwise the first responses
+	 status is used.  Again we have some odd side-effects when the
+	 second response is NOTFOUND because we overwrite *errnop and
+	 *h_errnop that means that a first answer of NOTFOUND might see
+	 its *errnop and *h_errnop values altered.  Whether it matters
+	 in practice that a first response NOTFOUND has the wrong
+	 *errnop and *h_errnop is undecided.
+
+     [4] If the first response is UNAVAIL we return that instead of
+	 looking at the second response.  The expectation here is that
+	 it will have failed similarly e.g. configuration failure.
+
+     [5] Testing this code is complicated by the fact that truncated
+	 second response buffers might be returned as SUCCESS if the
+	 first answer is a SUCCESS.  To fix this we add symmetry to
+	 TRYAGAIN with the second response.  If the second response
+	 is a recoverable error we now return TRYAGIN even if the first
+	 response was SUCCESS.  */
+
   if (anslen1 > 0)
     status = gaih_getanswer_slice(answer1, anslen1, qname,
 				  &pat, &buffer, &buflen,
 				  errnop, h_errnop, ttlp,
 				  &first);
+
   if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
        || (status == NSS_STATUS_TRYAGAIN
 	   /* We want to look at the second answer in case of an
@@ -1260,8 +1363,15 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
 						     &pat, &buffer, &buflen,
 						     errnop, h_errnop, ttlp,
 						     &first);
+      /* Use the second response status in some cases.  */
       if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
 	status = status2;
+      /* Do not return a truncated second response (unless it was
+	 unavoidable e.g. unrecoverable TRYAGAIN).  */
+      if (status == NSS_STATUS_SUCCESS
+	  && (status2 == NSS_STATUS_TRYAGAIN
+	      && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
+	status = NSS_STATUS_TRYAGAIN;
     }
 
   return status;
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
index 8e80a60..37de664 100644
--- a/resolv/nss_dns/dns-network.c
+++ b/resolv/nss_dns/dns-network.c
@@ -118,18 +118,15 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
   } net_buffer;
   querybuf *orig_net_buffer;
   int anslen;
-  char *qbuf;
   enum nss_status status;
 
   if (__res_maybe_init (&_res, 0) == -1)
     return NSS_STATUS_UNAVAIL;
 
-  qbuf = strdupa (name);
-
   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
 
-  anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
-			       1024, &net_buffer.ptr, NULL, NULL, NULL);
+  anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
+			       1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
   if (anslen < 0)
     {
       /* Nothing found.  */
@@ -205,7 +202,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result,
   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
 
   anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
-			      1024, &net_buffer.ptr, NULL, NULL, NULL);
+			      1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
   if (anslen < 0)
     {
       /* Nothing found.  */
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 1325f97..6f5280d 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -98,7 +98,7 @@ static int
 __libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
 			int class, int type, u_char *answer, int anslen,
 			u_char **answerp, u_char **answerp2, int *nanswerp2,
-			int *resplen2);
+			int *resplen2, int *answerp2_malloced);
 
 /*
  * Formulate a normal query, send, and await answer.
@@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp,
 		  u_char **answerp,	/* if buffer needs to be enlarged */
 		  u_char **answerp2,
 		  int *nanswerp2,
-		  int *resplen2)
+		  int *resplen2,
+		  int *answerp2_malloced)
 {
 	HEADER *hp = (HEADER *) answer;
 	HEADER *hp2;
@@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp,
 	}
 	assert (answerp == NULL || (void *) *answerp == (void *) answer);
 	n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
-			     anslen, answerp, answerp2, nanswerp2, resplen2);
+			     anslen, answerp, answerp2, nanswerp2, resplen2,
+			     answerp2_malloced);
 	if (use_malloc)
 		free (buf);
 	if (n < 0) {
@@ -316,7 +318,7 @@ res_nquery(res_state statp,
 	   int anslen)		/* size of answer buffer */
 {
 	return __libc_res_nquery(statp, name, class, type, answer, anslen,
-				 NULL, NULL, NULL, NULL);
+				 NULL, NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nquery)
 
@@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp,
 		   u_char **answerp,
 		   u_char **answerp2,
 		   int *nanswerp2,
-		   int *resplen2)
+		   int *resplen2,
+		   int *answerp2_malloced)
 {
 	const char *cp, * const *domain;
 	HEADER *hp = (HEADER *) answer;
@@ -360,7 +363,7 @@ __libc_res_nsearch(res_state statp,
 	if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
 		return (__libc_res_nquery(statp, cp, class, type, answer,
 					  anslen, answerp, answerp2,
-					  nanswerp2, resplen2));
+					  nanswerp2, resplen2, answerp2_malloced));
 
 #ifdef DEBUG
 	if (statp->options & RES_DEBUG)
@@ -377,7 +380,8 @@ __libc_res_nsearch(res_state statp,
 	if (dots >= statp->ndots || trailing_dot) {
 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
 					      answer, anslen, answerp,
-					      answerp2, nanswerp2, resplen2);
+					      answerp2, nanswerp2, resplen2,
+					      answerp2_malloced);
 		if (ret > 0 || trailing_dot)
 			return (ret);
 		saved_herrno = h_errno;
@@ -386,11 +390,12 @@ __libc_res_nsearch(res_state statp,
 			answer = *answerp;
 			anslen = MAXPACKET;
 		}
-		if (answerp2
-		    && (*answerp2 < answer || *answerp2 >= answer + anslen))
+		if (answerp2 && *answerp2_malloced)
 		  {
 		    free (*answerp2);
 		    *answerp2 = NULL;
+		    *nanswerp2 = 0;
+		    *answerp2_malloced = 0;
 		  }
 	}
 
@@ -417,7 +422,7 @@ __libc_res_nsearch(res_state statp,
 						      class, type,
 						      answer, anslen, answerp,
 						      answerp2, nanswerp2,
-						      resplen2);
+						      resplen2, answerp2_malloced);
 			if (ret > 0)
 				return (ret);
 
@@ -425,12 +430,12 @@ __libc_res_nsearch(res_state statp,
 				answer = *answerp;
 				anslen = MAXPACKET;
 			}
-			if (answerp2
-			    && (*answerp2 < answer
-				|| *answerp2 >= answer + anslen))
+			if (answerp2 && *answerp2_malloced)
 			  {
 			    free (*answerp2);
 			    *answerp2 = NULL;
+			    *nanswerp2 = 0;
+			    *answerp2_malloced = 0;
 			  }
 
 			/*
@@ -486,7 +491,8 @@ __libc_res_nsearch(res_state statp,
 	    && !(tried_as_is || root_on_list)) {
 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
 					      answer, anslen, answerp,
-					      answerp2, nanswerp2, resplen2);
+					      answerp2, nanswerp2, resplen2,
+					      answerp2_malloced);
 		if (ret > 0)
 			return (ret);
 	}
@@ -498,10 +504,12 @@ __libc_res_nsearch(res_state statp,
 	 * else send back meaningless H_ERRNO, that being the one from
 	 * the last DNSRCH we did.
 	 */
-	if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
+	if (answerp2 && *answerp2_malloced)
 	  {
 	    free (*answerp2);
 	    *answerp2 = NULL;
+	    *nanswerp2 = 0;
+	    *answerp2_malloced = 0;
 	  }
 	if (saved_herrno != -1)
 		RES_SET_H_ERRNO(statp, saved_herrno);
@@ -521,7 +529,7 @@ res_nsearch(res_state statp,
 	    int anslen)		/* size of answer */
 {
 	return __libc_res_nsearch(statp, name, class, type, answer,
-				  anslen, NULL, NULL, NULL, NULL);
+				  anslen, NULL, NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nsearch)
 
@@ -539,7 +547,8 @@ __libc_res_nquerydomain(res_state statp,
 			u_char **answerp,
 			u_char **answerp2,
 			int *nanswerp2,
-			int *resplen2)
+			int *resplen2,
+			int *answerp2_malloced)
 {
 	char nbuf[MAXDNAME];
 	const char *longname = nbuf;
@@ -581,7 +590,7 @@ __libc_res_nquerydomain(res_state statp,
 	}
 	return (__libc_res_nquery(statp, longname, class, type, answer,
 				  anslen, answerp, answerp2, nanswerp2,
-				  resplen2));
+				  resplen2, answerp2_malloced));
 }
 
 int
@@ -593,7 +602,8 @@ res_nquerydomain(res_state statp,
 	    int anslen)		/* size of answer */
 {
 	return __libc_res_nquerydomain(statp, name, domain, class, type,
-				       answer, anslen, NULL, NULL, NULL, NULL);
+				       answer, anslen, NULL, NULL, NULL, NULL,
+				       NULL);
 }
 libresolv_hidden_def (res_nquerydomain)
 
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 7f2e85f..11d0bbd 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -1,3 +1,20 @@
+/* Copyright (C) 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) 1985, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
@@ -186,12 +203,12 @@ evNowTime(struct timespec *res) {
 static int		send_vc(res_state, const u_char *, int,
 				const u_char *, int,
 				u_char **, int *, int *, int, u_char **,
-				u_char **, int *, int *);
+				u_char **, int *, int *, int *);
 static int		send_dg(res_state, const u_char *, int,
 				const u_char *, int,
 				u_char **, int *, int *, int,
 				int *, int *, u_char **,
-				u_char **, int *, int *);
+				u_char **, int *, int *, int *);
 #ifdef DEBUG
 static void		Aerror(const res_state, FILE *, const char *, int,
 			       const struct sockaddr *);
@@ -343,7 +360,7 @@ int
 __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 		 const u_char *buf2, int buflen2,
 		 u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
-		 int *nansp2, int *resplen2)
+		 int *nansp2, int *resplen2, int *ansp2_malloced)
 {
   int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
 
@@ -360,6 +377,8 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 #ifdef USE_HOOKS
 	if (__builtin_expect (statp->qhook || statp->rhook, 0)) {
 		if (anssiz < MAXPACKET && ansp) {
+			/* Always allocate MAXPACKET, callers expect
+			   this specific size.  */
 			u_char *buf = malloc (MAXPACKET);
 			if (buf == NULL)
 				return (-1);
@@ -546,7 +565,8 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 			try = statp->retry;
 			n = send_vc(statp, buf, buflen, buf2, buflen2,
 				    &ans, &anssiz, &terrno,
-				    ns, ansp, ansp2, nansp2, resplen2);
+				    ns, ansp, ansp2, nansp2, resplen2,
+				    ansp2_malloced);
 			if (n < 0)
 				return (-1);
 			if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -556,7 +576,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 			n = send_dg(statp, buf, buflen, buf2, buflen2,
 				    &ans, &anssiz, &terrno,
 				    ns, &v_circuit, &gotsomewhere, ansp,
-				    ansp2, nansp2, resplen2);
+				    ansp2, nansp2, resplen2, ansp2_malloced);
 			if (n < 0)
 				return (-1);
 			if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -646,26 +666,105 @@ res_nsend(res_state statp,
 	  const u_char *buf, int buflen, u_char *ans, int anssiz)
 {
   return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
-			  NULL, NULL, NULL, NULL);
+			  NULL, NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nsend)
 
 /* Private */
 
+/* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2
+   is not NULL, and return zero.  */
+static int
+__attribute__ ((warn_unused_result))
+close_and_return_error (res_state statp, int *resplen2)
+{
+  __res_iclose(statp, false);
+  if (resplen2 != NULL)
+    *resplen2 = 0;
+  return 0;
+}
+
+/* The send_vc function is responsible for sending a DNS query over TCP
+   to the nameserver numbered NS from the res_state STATP i.e.
+   EXT(statp).nssocks[ns].  The function supports sending both IPv4 and
+   IPv6 queries at the same serially on the same socket.
+
+   Please note that for TCP there is no way to disable sending both
+   queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
+   and sends the queries serially and waits for the result after each
+   sent query.  This implemetnation should be corrected to honour these
+   options.
+
+   Please also note that for TCP we send both queries over the same
+   socket one after another.  This technically violates best practice
+   since the server is allowed to read the first query, respond, and
+   then close the socket (to service another client).  If the server
+   does this, then the remaining second query in the socket data buffer
+   will cause the server to send the client an RST which will arrive
+   asynchronously and the client's OS will likely tear down the socket
+   receive buffer resulting in a potentially short read and lost
+   response data.  This will force the client to retry the query again,
+   and this process may repeat until all servers and connection resets
+   are exhausted and then the query will fail.  It's not known if this
+   happens with any frequency in real DNS server implementations.  This
+   implementation should be corrected to use two sockets by default for
+   parallel queries.
+
+   The query stored in BUF of BUFLEN length is sent first followed by
+   the query stored in BUF2 of BUFLEN2 length.  Queries are sent
+   serially on the same socket.
+
+   Answers to the query are stored firstly in *ANSP up to a max of
+   *ANSSIZP bytes.  If more than *ANSSIZP bytes are needed and ANSCP
+   is non-NULL (to indicate that modifying the answer buffer is allowed)
+   then malloc is used to allocate a new response buffer and ANSCP and
+   ANSP will both point to the new buffer.  If more than *ANSSIZP bytes
+   are needed but ANSCP is NULL, then as much of the response as
+   possible is read into the buffer, but the results will be truncated.
+   When truncation happens because of a small answer buffer the DNS
+   packets header feild TC will bet set to 1, indicating a truncated
+   message and the rest of the socket data will be read and discarded.
+
+   Answers to the query are stored secondly in *ANSP2 up to a max of
+   *ANSSIZP2 bytes, with the actual response length stored in
+   *RESPLEN2.  If more than *ANSSIZP bytes are needed and ANSP2
+   is non-NULL (required for a second query) then malloc is used to
+   allocate a new response buffer, *ANSSIZP2 is set to the new buffer
+   size and *ANSP2_MALLOCED is set to 1.
+
+   The ANSP2_MALLOCED argument will eventually be removed as the
+   change in buffer pointer can be used to detect the buffer has
+   changed and that the caller should use free on the new buffer.
+
+   Note that the answers may arrive in any order from the server and
+   therefore the first and second answer buffers may not correspond to
+   the first and second queries.
+
+   It is not supported to call this function with a non-NULL ANSP2
+   but a NULL ANSCP.  Put another way, you can call send_vc with a
+   single unmodifiable buffer or two modifiable buffers, but no other
+   combination is supported.
+
+   It is the caller's responsibility to free the malloc allocated
+   buffers by detecting that the pointers have changed from their
+   original values i.e. *ANSCP or *ANSP2 has changed.
+
+   If errors are encountered then *TERRNO is set to an appropriate
+   errno value and a zero result is returned for a recoverable error,
+   and a less-than zero result is returned for a non-recoverable error.
+
+   If no errors are encountered then *TERRNO is left unmodified and
+   a the length of the first response in bytes is returned.  */
 static int
 send_vc(res_state statp,
 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
 	u_char **ansp, int *anssizp,
 	int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
-	int *resplen2)
+	int *resplen2, int *ansp2_malloced)
 {
 	const HEADER *hp = (HEADER *) buf;
 	const HEADER *hp2 = (HEADER *) buf2;
-	u_char *ans = *ansp;
-	int orig_anssizp = *anssizp;
-	// XXX REMOVE
-	// int anssiz = *anssizp;
-	HEADER *anhp = (HEADER *) ans;
+	HEADER *anhp = (HEADER *) *ansp;
 	struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
 	int truncating, connreset, resplen, n;
 	struct iovec iov[4];
@@ -741,6 +840,8 @@ send_vc(res_state statp,
 	 * Receive length & response
 	 */
 	int recvresp1 = 0;
+	/* Skip the second response if there is no second query.
+	   To do that we mark the second response as received.  */
 	int recvresp2 = buf2 == NULL;
 	uint16_t rlen16;
  read_len:
@@ -777,33 +878,14 @@ send_vc(res_state statp,
 	u_char **thisansp;
 	int *thisresplenp;
 	if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
+		/* We have not received any responses
+		   yet or we only have one response to
+		   receive.  */
 		thisanssizp = anssizp;
 		thisansp = anscp ?: ansp;
 		assert (anscp != NULL || ansp2 == NULL);
 		thisresplenp = &resplen;
 	} else {
-		if (*anssizp != MAXPACKET) {
-			/* No buffer allocated for the first
-			   reply.  We can try to use the rest
-			   of the user-provided buffer.  */
-#ifdef _STRING_ARCH_unaligned
-			*anssizp2 = orig_anssizp - resplen;
-			*ansp2 = *ansp + resplen;
-#else
-			int aligned_resplen
-			  = ((resplen + __alignof__ (HEADER) - 1)
-			     & ~(__alignof__ (HEADER) - 1));
-			*anssizp2 = orig_anssizp - aligned_resplen;
-			*ansp2 = *ansp + aligned_resplen;
-#endif
-		} else {
-			/* The first reply did not fit into the
-			   user-provided buffer.  Maybe the second
-			   answer will.  */
-			*anssizp2 = orig_anssizp;
-			*ansp2 = *ansp;
-		}
-
 		thisanssizp = anssizp2;
 		thisansp = ansp2;
 		thisresplenp = resplen2;
@@ -811,10 +893,14 @@ send_vc(res_state statp,
 	anhp = (HEADER *) *thisansp;
 
 	*thisresplenp = rlen;
-	if (rlen > *thisanssizp) {
-		/* Yes, we test ANSCP here.  If we have two buffers
-		   both will be allocatable.  */
-		if (__builtin_expect (anscp != NULL, 1)) {
+	/* Is the answer buffer too small?  */
+	if (*thisanssizp < rlen) {
+		/* If the current buffer is non-NULL and it's not
+		   pointing at the static user-supplied buffer then
+		   we can reallocate it.  */
+		if (thisansp != NULL && thisansp != ansp) {
+			/* Always allocate MAXPACKET, callers expect
+			   this specific size.  */
 			u_char *newp = malloc (MAXPACKET);
 			if (newp == NULL) {
 				*terrno = ENOMEM;
@@ -823,7 +909,12 @@ send_vc(res_state statp,
 			}
 			*thisanssizp = MAXPACKET;
 			*thisansp = newp;
+			if (thisansp == ansp2)
+			  *ansp2_malloced = 1;
 			anhp = (HEADER *) newp;
+			/* A uint16_t can't be larger than MAXPACKET
+			   thus it's safe to allocate MAXPACKET but
+			   read RLEN bytes instead.  */
 			len = rlen;
 		} else {
 			Dprint(statp->options & RES_DEBUG,
@@ -987,17 +1078,75 @@ reopen (res_state statp, int *terrno, int ns)
 	return 1;
 }
 
+/* The send_dg function is responsible for sending a DNS query over UDP
+   to the nameserver numbered NS from the res_state STATP i.e.
+   EXT(statp).nssocks[ns].  The function supports IPv4 and IPv6 queries
+   along with the ability to send the query in parallel for both stacks
+   (default) or serially (RES_SINGLKUP).  It also supports serial lookup
+   with a close and reopen of the socket used to talk to the server
+   (RES_SNGLKUPREOP) to work around broken name servers.
+
+   The query stored in BUF of BUFLEN length is sent first followed by
+   the query stored in BUF2 of BUFLEN2 length.  Queries are sent
+   in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
+
+   Answers to the query are stored firstly in *ANSP up to a max of
+   *ANSSIZP bytes.  If more than *ANSSIZP bytes are needed and ANSCP
+   is non-NULL (to indicate that modifying the answer buffer is allowed)
+   then malloc is used to allocate a new response buffer and ANSCP and
+   ANSP will both point to the new buffer.  If more than *ANSSIZP bytes
+   are needed but ANSCP is NULL, then as much of the response as
+   possible is read into the buffer, but the results will be truncated.
+   When truncation happens because of a small answer buffer the DNS
+   packets header feild TC will bet set to 1, indicating a truncated
+   message, while the rest of the UDP packet is discarded.
+
+   Answers to the query are stored secondly in *ANSP2 up to a max of
+   *ANSSIZP2 bytes, with the actual response length stored in
+   *RESPLEN2.  If more than *ANSSIZP bytes are needed and ANSP2
+   is non-NULL (required for a second query) then malloc is used to
+   allocate a new response buffer, *ANSSIZP2 is set to the new buffer
+   size and *ANSP2_MALLOCED is set to 1.
+
+   The ANSP2_MALLOCED argument will eventually be removed as the
+   change in buffer pointer can be used to detect the buffer has
+   changed and that the caller should use free on the new buffer.
+
+   Note that the answers may arrive in any order from the server and
+   therefore the first and second answer buffers may not correspond to
+   the first and second queries.
+
+   It is not supported to call this function with a non-NULL ANSP2
+   but a NULL ANSCP.  Put another way, you can call send_vc with a
+   single unmodifiable buffer or two modifiable buffers, but no other
+   combination is supported.
+
+   It is the caller's responsibility to free the malloc allocated
+   buffers by detecting that the pointers have changed from their
+   original values i.e. *ANSCP or *ANSP2 has changed.
+
+   If an answer is truncated because of UDP datagram DNS limits then
+   *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
+   the caller to retry with TCP.  The value *GOTSOMEWHERE is set to 1
+   if any progress was made reading a response from the nameserver and
+   is used by the caller to distinguish between ECONNREFUSED and
+   ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
+
+   If errors are encountered then *TERRNO is set to an appropriate
+   errno value and a zero result is returned for a recoverable error,
+   and a less-than zero result is returned for a non-recoverable error.
+
+   If no errors are encountered then *TERRNO is left unmodified and
+   a the length of the first response in bytes is returned.  */
 static int
 send_dg(res_state statp,
 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
 	u_char **ansp, int *anssizp,
 	int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
-	u_char **ansp2, int *anssizp2, int *resplen2)
+	u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
 {
 	const HEADER *hp = (HEADER *) buf;
 	const HEADER *hp2 = (HEADER *) buf2;
-	u_char *ans = *ansp;
-	int orig_anssizp = *anssizp;
 	struct timespec now, timeout, finish;
 	struct pollfd pfd[1];
 	int ptimeout;
@@ -1022,7 +1171,11 @@ send_dg(res_state statp,
  retry_reopen:
 	retval = reopen (statp, terrno, ns);
 	if (retval <= 0)
-		return retval;
+	  {
+	    if (resplen2 != NULL)
+	      *resplen2 = 0;
+	    return retval;
+	  }
  retry:
 	evNowTime(&now);
 	evConsTime(&timeout, seconds, 0);
@@ -1030,11 +1183,11 @@ send_dg(res_state statp,
 	int need_recompute = 0;
 	int nwritten = 0;
 	int recvresp1 = 0;
+	/* Skip the second response if there is no second query.
+           To do that we mark the second response as received.  */
 	int recvresp2 = buf2 == NULL;
 	pfd[0].fd = EXT(statp).nssocks[ns];
 	pfd[0].events = POLLOUT;
-	if (resplen2 != NULL)
-	  *resplen2 = 0;
  wait:
 	if (need_recompute) {
 	recompute_resend:
@@ -1042,9 +1195,7 @@ send_dg(res_state statp,
 		if (evCmpTime(finish, now) <= 0) {
 		poll_err_out:
 			Perror(statp, stderr, "poll", errno);
-		err_out:
-			__res_iclose(statp, false);
-			return (0);
+			return close_and_return_error (statp, resplen2);
 		}
 		evSubTime(&timeout, &finish, &now);
 		need_recompute = 0;
@@ -1091,7 +1242,9 @@ send_dg(res_state statp,
 		  }
 
 		*gotsomewhere = 1;
-		return (0);
+		if (resplen2 != NULL)
+		  *resplen2 = 0;
+		return 0;
 	}
 	if (n < 0) {
 		if (errno == EINTR)
@@ -1159,7 +1312,7 @@ send_dg(res_state statp,
 
 		      fail_sendmmsg:
 			Perror(statp, stderr, "sendmmsg", errno);
-			goto err_out;
+			return close_and_return_error (statp, resplen2);
 		      }
 		  }
 		else
@@ -1177,7 +1330,7 @@ send_dg(res_state statp,
 		      if (errno == EINTR || errno == EAGAIN)
 			goto recompute_resend;
 		      Perror(statp, stderr, "send", errno);
-		      goto err_out;
+		      return close_and_return_error (statp, resplen2);
 		    }
 		  just_one:
 		    if (nwritten != 0 || buf2 == NULL || single_request)
@@ -1193,53 +1346,56 @@ send_dg(res_state statp,
 		int *thisresplenp;
 
 		if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
+			/* We have not received any responses
+			   yet or we only have one response to
+			   receive.  */
 			thisanssizp = anssizp;
 			thisansp = anscp ?: ansp;
 			assert (anscp != NULL || ansp2 == NULL);
 			thisresplenp = &resplen;
 		} else {
-			if (*anssizp != MAXPACKET) {
-				/* No buffer allocated for the first
-				   reply.  We can try to use the rest
-				   of the user-provided buffer.  */
-#ifdef _STRING_ARCH_unaligned
-				*anssizp2 = orig_anssizp - resplen;
-				*ansp2 = *ansp + resplen;
-#else
-				int aligned_resplen
-				  = ((resplen + __alignof__ (HEADER) - 1)
-				     & ~(__alignof__ (HEADER) - 1));
-				*anssizp2 = orig_anssizp - aligned_resplen;
-				*ansp2 = *ansp + aligned_resplen;
-#endif
-			} else {
-				/* The first reply did not fit into the
-				   user-provided buffer.  Maybe the second
-				   answer will.  */
-				*anssizp2 = orig_anssizp;
-				*ansp2 = *ansp;
-			}
-
 			thisanssizp = anssizp2;
 			thisansp = ansp2;
 			thisresplenp = resplen2;
 		}
 
 		if (*thisanssizp < MAXPACKET
-		    /* Yes, we test ANSCP here.  If we have two buffers
-		       both will be allocatable.  */
-		    && anscp
+		    /* If the current buffer is non-NULL and it's not
+		       pointing at the static user-supplied buffer then
+		       we can reallocate it.  */
+		    && (thisansp != NULL && thisansp != ansp)
 #ifdef FIONREAD
+		    /* Is the size too small?  */
 		    && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
 			|| *thisanssizp < *thisresplenp)
 #endif
                     ) {
+			/* Always allocate MAXPACKET, callers expect
+			   this specific size.  */
 			u_char *newp = malloc (MAXPACKET);
 			if (newp != NULL) {
-				*anssizp = MAXPACKET;
-				*thisansp = ans = newp;
+				*thisanssizp = MAXPACKET;
+				*thisansp = newp;
+				if (thisansp == ansp2)
+				  *ansp2_malloced = 1;
 			}
 		}
+		/* We could end up with truncation if anscp was NULL
+		   (not allowed to change caller's buffer) and the
+		   response buffer size is too small.  This isn't a
+		   reliable way to detect truncation because the ioctl
+		   may be an inaccurate report of the UDP message size.
+		   Therefore we use this only to issue debug output.
+		   To do truncation accurately with UDP we need
+		   MSG_TRUNC which is only available on Linux.  We
+		   can abstract out the Linux-specific feature in the
+		   future to detect truncation.  */
+		if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
+			Dprint(statp->options & RES_DEBUG,
+			       (stdout, ";; response may be truncated (UDP)\n")
+			);
+		}
+
 		HEADER *anhp = (HEADER *) *thisansp;
 		socklen_t fromlen = sizeof(struct sockaddr_in6);
 		assert (sizeof(from) <= fromlen);
@@ -1252,7 +1408,7 @@ send_dg(res_state statp,
 				goto wait;
 			}
 			Perror(statp, stderr, "recvfrom", errno);
-			goto err_out;
+			return close_and_return_error (statp, resplen2);
 		}
 		*gotsomewhere = 1;
 		if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) {
@@ -1263,7 +1419,7 @@ send_dg(res_state statp,
 			       (stdout, ";; undersized: %d\n",
 				*thisresplenp));
 			*terrno = EMSGSIZE;
-			goto err_out;
+			return close_and_return_error (statp, resplen2);
 		}
 		if ((recvresp1 || hp->id != anhp->id)
 		    && (recvresp2 || hp2->id != anhp->id)) {
@@ -1312,7 +1468,7 @@ send_dg(res_state statp,
 				? *thisanssizp : *thisresplenp);
 			/* record the error */
 			statp->_flags |= RES_F_EDNS0ERR;
-			goto err_out;
+			return close_and_return_error (statp, resplen2);
 	}
 #endif
 		if (!(statp->options & RES_INSECURE2)
@@ -1364,10 +1520,10 @@ send_dg(res_state statp,
 			  }
 
 		next_ns:
-			__res_iclose(statp, false);
 			/* don't retry if called from dig */
 			if (!statp->pfcode)
-				return (0);
+			  return close_and_return_error (statp, resplen2);
+			__res_iclose(statp, false);
 		}
 		if (anhp->rcode == NOERROR && anhp->ancount == 0
 		    && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) {
@@ -1389,6 +1545,8 @@ send_dg(res_state statp,
 			__res_iclose(statp, false);
 			// XXX if we have received one reply we could
 			// XXX use it and not repeat it over TCP...
+			if (resplen2 != NULL)
+			  *resplen2 = 0;
 			return (1);
 		}
 		/* Mark which reply we received.  */
@@ -1404,20 +1562,22 @@ send_dg(res_state statp,
 					__res_iclose (statp, false);
 					retval = reopen (statp, terrno, ns);
 					if (retval <= 0)
-						return retval;
+					  {
+					    if (resplen2 != NULL)
+					      *resplen2 = 0;
+					    return retval;
+					  }
+					pfd[0].fd = EXT(statp).nssocks[ns];
 				}
 			}
 			goto wait;
 		}
-		/*
-		 * All is well, or the error is fatal.  Signal that the
-		 * next nameserver ought not be tried.
-		 */
+		/* All is well.  We have received both responses (if
+		   two responses were requested).  */
 		return (resplen);
-	} else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
-		/* Something went wrong.  We can stop trying.  */
-		goto err_out;
-	}
+	} else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
+	  /* Something went wrong.  We can stop trying.  */
+	  return close_and_return_error (statp, resplen2);
 	else {
 		/* poll should not have returned > 0 in this case.  */
 		abort ();
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 1be16eb..8a34b83 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -64,11 +64,11 @@ test-srcs	:= tst-fmtmsg
 tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-canon test-canon2 tst-strtoll tst-environ	    \
 		   tst-xpg-basename tst-random tst-random2 tst-bsearch	    \
-		   tst-limits tst-rand48 bug-strtod tst-setcontext	    \
-		   test-a64l tst-qsort tst-system testmb2 bug-strtod2	    \
-		   tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
-		   tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2	    \
-		   tst-makecontext2 tst-strtod6 tst-unsetenv1		    \
+		   tst-limits tst-rand48 bug-strtod tst-setcontext          \
+		   tst-setcontext2 test-a64l tst-qsort tst-system testmb2   \
+		   bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3  \
+		   tst-rand48-2 tst-makecontext tst-strtod4 tst-strtod5     \
+		   tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1    \
 		   tst-makecontext3 bug-getcontext bug-fmtmsg1		    \
 		   tst-secure-getenv tst-strtod-overflow tst-strtod-round   \
 		   tst-tininess tst-strtod-underflow tst-tls-atexit
@@ -164,3 +164,5 @@ tst-tls-atexit-lib.so-no-z-defs = yes
 $(objpfx)tst-tls-atexit: $(common-objpfx)nptl/libpthread.so \
 			 $(common-objpfx)dlfcn/libdl.so
 $(objpfx)tst-tls-atexit.out: $(objpfx)tst-tls-atexit-lib.so
+
+$(objpfx)tst-makecontext: $(libdl)
diff --git a/stdlib/cxa_thread_atexit_impl.c b/stdlib/cxa_thread_atexit_impl.c
index d2f88d3..6030e5f 100644
--- a/stdlib/cxa_thread_atexit_impl.c
+++ b/stdlib/cxa_thread_atexit_impl.c
@@ -42,6 +42,10 @@ static __thread struct link_map *lm_cache;
 int
 __cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
 {
+#ifdef PTR_MANGLE
+  PTR_MANGLE (func);
+#endif
+
   /* Prepend.  */
   struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
   new->func = func;
@@ -83,9 +87,13 @@ __call_tls_dtors (void)
   while (tls_dtor_list)
     {
       struct dtor_list *cur = tls_dtor_list;
-      tls_dtor_list = tls_dtor_list->next;
+      dtor_func func = cur->func;
+#ifdef PTR_DEMANGLE
+      PTR_DEMANGLE (func);
+#endif
 
-      cur->func (cur->obj);
+      tls_dtor_list = tls_dtor_list->next;
+      func (cur->obj);
 
       __rtld_lock_lock_recursive (GL(dl_load_lock));
 
diff --git a/stdlib/tst-makecontext.c b/stdlib/tst-makecontext.c
index 7968a6d..ef1e27a 100644
--- a/stdlib/tst-makecontext.c
+++ b/stdlib/tst-makecontext.c
@@ -19,23 +19,62 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <ucontext.h>
+#include <assert.h>
+#include <unwind.h>
+#include <dlfcn.h>
+#include <gnu/lib-names.h>
 
 ucontext_t ucp;
-char st1[8192];
+char st1[16384];
 __thread int thr;
 
 int somevar = -76;
 long othervar = -78L;
 
+struct trace_arg
+{
+  int cnt, size;
+};
+
+static _Unwind_Reason_Code
+backtrace_helper (struct _Unwind_Context *ctx, void *a)
+{
+  struct trace_arg *arg = a;
+  if (++arg->cnt == arg->size)
+    return _URC_END_OF_STACK;
+  return _URC_NO_REASON;
+}
+
 void
 cf (int i)
 {
+  struct trace_arg arg = { .size = 100, .cnt = -1 };
+  void *handle;
+  _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
+
   if (i != othervar || thr != 94)
     {
       printf ("i %d thr %d\n", i, thr);
       exit (1);
     }
 
+  /* Test if callback function of _Unwind_Backtrace is not called infinitely
+     times. See Bug 18508 or gcc bug "Bug 66303 - runtime.Caller() returns
+     infinitely deep stack frames on s390x.".
+     The go runtime calls backtrace_full() in
+     <gcc-src>/libbacktrace/backtrace.c, which uses _Unwind_Backtrace().  */
+  handle = dlopen (LIBGCC_S_SO, RTLD_LAZY);
+  if (handle != NULL)
+    {
+      unwind_backtrace = dlsym (handle, "_Unwind_Backtrace");
+      if (unwind_backtrace != NULL)
+	{
+	  unwind_backtrace (backtrace_helper, &arg);
+	  assert (arg.cnt != -1 && arg.cnt < 100);
+	}
+      dlclose (handle);
+    }
+
   /* Since uc_link below has been set to NULL, setcontext is supposed to
      terminate the process normally after this function returns.  */
 }
diff --git a/stdlib/tst-setcontext2.c b/stdlib/tst-setcontext2.c
new file mode 100644
index 0000000..8582cc0
--- /dev/null
+++ b/stdlib/tst-setcontext2.c
@@ -0,0 +1,230 @@
+/* Testcase checks, if setcontext(), swapcontext() restores signal-mask
+   and if pending signals are delivered after those calls.
+   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/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+volatile int global;
+volatile sig_atomic_t handlerCalled;
+
+static void
+check (const char *funcName)
+{
+  sigset_t set;
+
+  /* check if SIGUSR2 is unblocked after setcontext-call.  */
+  sigprocmask (SIG_BLOCK, NULL, &set);
+
+  if (sigismember (&set, SIGUSR2) != 0)
+    {
+      printf ("FAIL: SIGUSR2 is blocked after %s.\n", funcName);
+      exit (1);
+    }
+
+  if (sigismember (&set, SIGUSR1) != 1)
+    {
+      printf ("FAIL: SIGUSR1 is not blocked after %s.\n", funcName);
+      exit (1);
+    }
+}
+
+static void
+signalmask (int how, int signum)
+{
+  sigset_t set;
+  sigemptyset (&set);
+  sigaddset (&set, signum);
+  if (sigprocmask (how, &set, NULL) != 0)
+    {
+      printf ("FAIL: sigprocmaks (%d, %d, NULL): %m\n", how, signum);
+      exit (1);
+    }
+}
+
+static void
+signalpending (int signum, const char *msg)
+{
+  sigset_t set;
+  sigemptyset (&set);
+  if (sigpending (&set) != 0)
+    {
+      printf ("FAIL: sigpending: %m\n");
+      exit (1);
+    }
+  if (sigismember (&set, SIGUSR2) != 1)
+    {
+      printf ("FAIL: Signal %d is not pending %s\n", signum, msg);
+      exit (1);
+    }
+}
+
+static void
+handler (int __attribute__ ((unused)) signum)
+{
+  handlerCalled ++;
+}
+
+static int
+do_test (void)
+{
+  ucontext_t ctx, oldctx;
+  struct sigaction action;
+  pid_t pid;
+
+  pid = getpid ();
+
+  /* unblock SIGUSR2 */
+  signalmask (SIG_UNBLOCK, SIGUSR2);
+
+  /* block SIGUSR1 */
+  signalmask (SIG_BLOCK, SIGUSR1);
+
+  /* register handler for SIGUSR2  */
+  action.sa_flags = 0;
+  action.sa_handler = handler;
+  sigemptyset (&action.sa_mask);
+  sigaction (SIGUSR2, &action, NULL);
+
+  if (getcontext (&ctx) != 0)
+    {
+      printf ("FAIL: getcontext: %m\n");
+      exit (1);
+    }
+
+  global++;
+
+  if (global == 1)
+    {
+      puts ("after getcontext");
+
+      /* block SIGUSR2  */
+      signalmask (SIG_BLOCK, SIGUSR2);
+
+      /* send SIGUSR2 to me  */
+      handlerCalled = 0;
+      kill (pid, SIGUSR2);
+
+      /* was SIGUSR2 handler called?  */
+      if (handlerCalled != 0)
+	{
+	  puts ("FAIL: signal handler was called, but signal was blocked.");
+	  exit (1);
+	}
+
+      /* is SIGUSR2 pending?  */
+      signalpending (SIGUSR2, "before setcontext");
+
+      /* SIGUSR2 will be unblocked by setcontext-call.  */
+      if (setcontext (&ctx) != 0)
+	{
+	  printf ("FAIL: setcontext: %m\n");
+	  exit (1);
+	}
+    }
+  else if (global == 2)
+    {
+      puts ("after setcontext");
+
+      /* check SIGUSR1/2  */
+      check ("setcontext");
+
+      /* was SIGUSR2 handler called? */
+      if (handlerCalled != 1)
+	{
+	  puts ("FAIL: signal handler was not called after setcontext.");
+	  exit (1);
+	}
+
+      /* block SIGUSR2 */
+      signalmask (SIG_BLOCK, SIGUSR2);
+
+      /* send SIGUSR2 to me  */
+      handlerCalled = 0;
+      kill (pid, SIGUSR2);
+
+      /* was SIGUSR2 handler called?  */
+      if (handlerCalled != 0)
+	{
+	  puts ("FAIL: signal handler was called, but signal was blocked.");
+	  exit (1);
+	}
+
+      /* is SIGUSR2 pending?  */
+      signalpending (SIGUSR2, "before swapcontext");
+
+      if (swapcontext (&oldctx, &ctx) != 0)
+	{
+	  printf ("FAIL: swapcontext: %m\n");
+	  exit (1);
+	}
+
+      puts ("after returned from swapcontext");
+
+      if (global != 3)
+	{
+	  puts ("FAIL: returned from swapcontext without ctx-context called.");
+	  exit (1);
+	}
+
+      puts ("test succeeded");
+      return 0;
+    }
+  else if ( global != 3 )
+    {
+      puts ("FAIL: 'global' not incremented three times");
+      exit (1);
+    }
+
+  puts ("after swapcontext");
+  /* check SIGUSR1/2  */
+  check ("swapcontext");
+
+  /* was SIGUSR2 handler called? */
+  if (handlerCalled != 1)
+    {
+      puts ("FAIL: signal handler was not called after swapcontext.");
+      exit (1);
+    }
+
+  /* check sigmask in old context of swapcontext-call  */
+  if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
+    {
+      puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask.");
+      exit (1);
+    }
+
+  if (sigismember (&oldctx.uc_sigmask, SIGUSR1) != 1)
+    {
+      puts ("FAIL: SIGUSR1 is not blocked in oldctx.uc_sigmaks.");
+      exit (1);
+    }
+
+  /* change to old context, which was gathered by swapcontext() call.  */
+  setcontext (&oldctx);
+
+  puts ("FAIL: returned from setcontext (&oldctx)");
+  exit (1);
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/string/strxfrm_l.c b/string/strxfrm_l.c
index 04b9338..e496550 100644
--- a/string/strxfrm_l.c
+++ b/string/strxfrm_l.c
@@ -40,8 +40,23 @@
 #define CONCAT(a,b) CONCAT1(a,b)
 #define CONCAT1(a,b) a##b
 
+/* Maximum string size that is calculated with cached indices.  Right now this
+   is an arbitrary value open to optimizations.  SMALL_STR_SIZE * 4 has to be
+   lower than __MAX_ALLOCA_CUTOFF.  Keep localedata/xfrm-test.c in sync.  */
+#define SMALL_STR_SIZE 4095
+
 #include "../locale/localeinfo.h"
 
+/* Group locale data for shorter parameter lists.  */
+typedef struct
+{
+  uint_fast32_t nrules;
+  unsigned char *rulesets;
+  USTRING_TYPE *weights;
+  int32_t *table;
+  USTRING_TYPE *extra;
+  int32_t *indirect;
+} locale_data_t;
 
 #ifndef WIDE_CHAR_VERSION
 
@@ -80,115 +95,330 @@ utf8_encode (char *buf, int val)
 }
 #endif
 
-
-size_t
-STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
+/* Find next weight and rule index.  Inlined since called for every char.  */
+static __always_inline size_t
+find_idx (const USTRING_TYPE **us, int32_t *weight_idx,
+	  unsigned char *rule_idx, const locale_data_t *l_data, const int pass)
 {
-  struct __locale_data *current = l->__locales[LC_COLLATE];
-  uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
-  /* We don't assign the following values right away since it might be
-     unnecessary in case there are no rules.  */
-  const unsigned char *rulesets;
-  const int32_t *table;
-  const USTRING_TYPE *weights;
-  const USTRING_TYPE *extra;
-  const int32_t *indirect;
-  uint_fast32_t pass;
-  size_t needed;
-  size_t last_needed;
-  const USTRING_TYPE *usrc;
-  size_t srclen = STRLEN (src);
-  int32_t *idxarr;
-  unsigned char *rulearr;
-  size_t idxmax;
-  size_t idxcnt;
-  int use_malloc;
+  /* Prepare variables required by findidx().  */
+  int32_t *table = l_data->table;
+  int32_t *indirect = l_data->indirect;
+  USTRING_TYPE *extra = l_data->extra;
 
 #include WEIGHT_H
+  int32_t tmp = findidx (us, -1);
+  *rule_idx = tmp >> 24;
+  int32_t idx = tmp & 0xffffff;
+  size_t len = l_data->weights[idx++];
 
-  if (nrules == 0)
+  /* Skip over indices of previous levels.  */
+  for (int i = 0; i < pass; i++)
     {
-      if (n != 0)
-	STPNCPY (dest, src, MIN (srclen + 1, n));
-
-      return srclen;
+      idx += len;
+      len = l_data->weights[idx++];
     }
 
-  rulesets = (const unsigned char *)
-    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
-  table = (const int32_t *)
-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
-  weights = (const USTRING_TYPE *)
-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
-  extra = (const USTRING_TYPE *)
-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
-  indirect = (const int32_t *)
-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
-  use_malloc = 0;
+  *weight_idx = idx;
+  return len;
+}
 
-  assert (((uintptr_t) table) % __alignof__ (table[0]) == 0);
-  assert (((uintptr_t) weights) % __alignof__ (weights[0]) == 0);
-  assert (((uintptr_t) extra) % __alignof__ (extra[0]) == 0);
-  assert (((uintptr_t) indirect) % __alignof__ (indirect[0]) == 0);
+static int
+find_position (const USTRING_TYPE *us, const locale_data_t *l_data,
+	       const int pass)
+{
+  int32_t weight_idx;
+  unsigned char rule_idx;
+  const USTRING_TYPE *usrc = us;
 
-  /* Handle an empty string as a special case.  */
-  if (srclen == 0)
-    {
-      if (n != 0)
-	*dest = L('\0');
-      return 0;
-    }
+  find_idx (&usrc, &weight_idx, &rule_idx, l_data, pass);
+  return l_data->rulesets[rule_idx * l_data->nrules + pass] & sort_position;
+}
 
-  /* We need the elements of the string as unsigned values since they
-     are used as indeces.  */
-  usrc = (const USTRING_TYPE *) src;
-
-  /* Perform the first pass over the string and while doing this find
-     and store the weights for each character.  Since we want this to
-     be as fast as possible we are using `alloca' to store the temporary
-     values.  But since there is no limit on the length of the string
-     we have to use `malloc' if the string is too long.  We should be
-     very conservative here.  */
-  if (! __libc_use_alloca ((srclen + 1) * (sizeof (int32_t) + 1)))
-    {
-      idxarr = (int32_t *) malloc ((srclen + 1) * (sizeof (int32_t) + 1));
-      rulearr = (unsigned char *) &idxarr[srclen];
-
-      if (idxarr == NULL)
-	/* No memory.  Well, go with the stack then.
-
-	   XXX Once this implementation is stable we will handle this
-	   differently.  Instead of precomputing the indeces we will
-	   do this in time.  This means, though, that this happens for
-	   every pass again.  */
-	goto try_stack;
-      use_malloc = 1;
-    }
-  else
+/* Do the transformation.  */
+static size_t
+do_xfrm (const USTRING_TYPE *usrc, STRING_TYPE *dest, size_t n,
+	 const locale_data_t *l_data)
+{
+  int32_t weight_idx;
+  unsigned char rule_idx;
+  uint_fast32_t pass;
+  size_t needed = 0;
+  size_t last_needed;
+
+  /* Now the passes over the weights.  */
+  for (pass = 0; pass < l_data->nrules; ++pass)
     {
-    try_stack:
-      idxarr = (int32_t *) alloca (srclen * sizeof (int32_t));
-      rulearr = (unsigned char *) alloca (srclen + 1);
+      size_t backw_len = 0;
+      last_needed = needed;
+      const USTRING_TYPE *cur = usrc;
+      const USTRING_TYPE *backw_start = NULL;
+
+       /* We assume that if a rule has defined `position' in one section
+         this is true for all of them.  */
+      int position = find_position (cur, l_data, pass);
+
+      if (position == 0)
+	{
+	  while (*cur != L('\0'))
+	    {
+	      const USTRING_TYPE *pos = cur;
+	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
+				     pass);
+	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
+
+	      if ((rule & sort_forward) != 0)
+		{
+		  /* Handle the pushed backward sequence.  */
+		  if (backw_start != NULL)
+		    {
+		      for (size_t i = backw_len; i > 0; )
+			{
+			  int32_t weight_idx;
+			  unsigned char rule_idx;
+			  size_t len = find_idx (&backw_start, &weight_idx,
+						 &rule_idx, l_data, pass);
+			  if (needed + i < n)
+			    for (size_t j = len; j > 0; j--)
+			      dest[needed + i - j] =
+				l_data->weights[weight_idx++];
+
+			  i -= len;
+			}
+
+		      needed += backw_len;
+		      backw_start = NULL;
+		      backw_len = 0;
+		    }
+
+		  /* Now handle the forward element.  */
+		  if (needed + len < n)
+		    while (len-- > 0)
+		      dest[needed++] = l_data->weights[weight_idx++];
+		  else
+		    /* No more characters fit into the buffer.  */
+		    needed += len;
+		}
+	      else
+		{
+		  /* Remember start of the backward sequence & track length.  */
+		  if (backw_start == NULL)
+		    backw_start = pos;
+		  backw_len += len;
+		}
+	    }
+
+
+	  /* Handle the pushed backward sequence.  */
+	  if (backw_start != NULL)
+	    {
+	      for (size_t i = backw_len; i > 0; )
+		{
+		  size_t len = find_idx (&backw_start, &weight_idx, &rule_idx,
+					 l_data, pass);
+		  if (needed + i < n)
+		    for (size_t j = len; j > 0; j--)
+		      dest[needed + i - j] =
+			l_data->weights[weight_idx++];
+
+		  i -= len;
+		}
+
+	      needed += backw_len;
+	    }
+	}
+      else
+	{
+	  int val = 1;
+#ifndef WIDE_CHAR_VERSION
+	  char buf[7];
+	  size_t buflen;
+#endif
+	  size_t i;
+
+	  while (*cur != L('\0'))
+	    {
+	      const USTRING_TYPE *pos = cur;
+	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
+				     pass);
+	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
+
+	      if ((rule & sort_forward) != 0)
+		{
+		  /* Handle the pushed backward sequence.  */
+		  if (backw_start != NULL)
+		    {
+		      for (size_t p = backw_len; p > 0; p--)
+			{
+			  size_t len;
+			  int32_t weight_idx;
+			  unsigned char rule_idx;
+			  const USTRING_TYPE *backw_cur = backw_start;
+
+			  /* To prevent a warning init the used vars.  */
+			  len = find_idx (&backw_cur, &weight_idx,
+					  &rule_idx, l_data, pass);
+
+			  for (i = 1; i < p; i++)
+			    len = find_idx (&backw_cur, &weight_idx,
+					    &rule_idx, l_data, pass);
+
+			  if (len != 0)
+			    {
+#ifdef WIDE_CHAR_VERSION
+			      if (needed + 1 + len < n)
+				{
+				  dest[needed] = val;
+				  for (i = 0; i < len; ++i)
+				    dest[needed + 1 + i] =
+				      l_data->weights[weight_idx + i];
+				}
+			      needed += 1 + len;
+#else
+			      buflen = utf8_encode (buf, val);
+			      if (needed + buflen + len < n)
+				{
+				  for (i = 0; i < buflen; ++i)
+				    dest[needed + i] = buf[i];
+				  for (i = 0; i < len; ++i)
+				    dest[needed + buflen + i] =
+				      l_data->weights[weight_idx + i];
+				}
+			      needed += buflen + len;
+#endif
+			      val = 1;
+			    }
+			  else
+			    ++val;
+			}
+
+		      backw_start = NULL;
+		      backw_len = 0;
+		    }
+
+		  /* Now handle the forward element.  */
+		  if (len != 0)
+		    {
+#ifdef WIDE_CHAR_VERSION
+		      if (needed + 1 + len < n)
+			{
+			  dest[needed] = val;
+			  for (i = 0; i < len; ++i)
+			    dest[needed + 1 + i] =
+			      l_data->weights[weight_idx + i];
+			}
+		      needed += 1 + len;
+#else
+		      buflen = utf8_encode (buf, val);
+		      if (needed + buflen + len < n)
+			{
+			  for (i = 0; i < buflen; ++i)
+			    dest[needed + i] = buf[i];
+			  for (i = 0; i < len; ++i)
+			    dest[needed + buflen + i] =
+			      l_data->weights[weight_idx + i];
+			}
+		      needed += buflen + len;
+#endif
+		      val = 1;
+		    }
+		  else
+		    ++val;
+		}
+	      else
+		{
+		  /* Remember start of the backward sequence & track length.  */
+		  if (backw_start == NULL)
+		    backw_start = pos;
+		  backw_len++;
+		}
+	    }
+
+	  /* Handle the pushed backward sequence.  */
+	  if (backw_start != NULL)
+	    {
+	      for (size_t p = backw_len; p > 0; p--)
+		{
+		  size_t len;
+		  int32_t weight_idx;
+		  unsigned char rule_idx;
+		  const USTRING_TYPE *backw_cur = backw_start;
+
+		  /* To prevent a warning init the used vars.  */
+		  len = find_idx (&backw_cur, &weight_idx,
+				  &rule_idx, l_data, pass);
+
+		  for (i = 1; i < p; i++)
+		    len = find_idx (&backw_cur, &weight_idx,
+				    &rule_idx, l_data, pass);
+
+		  if (len != 0)
+		    {
+#ifdef WIDE_CHAR_VERSION
+		      if (needed + 1 + len < n)
+			{
+			  dest[needed] = val;
+			  for (i = 0; i < len; ++i)
+			    dest[needed + 1 + i] =
+			      l_data->weights[weight_idx + i];
+			}
+		      needed += 1 + len;
+#else
+		      buflen = utf8_encode (buf, val);
+		      if (needed + buflen + len < n)
+			{
+			  for (i = 0; i < buflen; ++i)
+			    dest[needed + i] = buf[i];
+			  for (i = 0; i < len; ++i)
+			    dest[needed + buflen + i] =
+			      l_data->weights[weight_idx + i];
+			}
+		      needed += buflen + len;
+#endif
+		      val = 1;
+		    }
+		  else
+		    ++val;
+		}
+	    }
+	}
+
+      /* Finally store the byte to separate the passes or terminate
+	 the string.  */
+      if (needed < n)
+	dest[needed] = pass + 1 < l_data->nrules ? L('\1') : L('\0');
+      ++needed;
     }
 
-  idxmax = 0;
-  do
+  /* This is a little optimization: many collation specifications have
+     a `position' rule at the end and if no non-ignored character
+     is found the last \1 byte is immediately followed by a \0 byte
+     signalling this.  We can avoid the \1 byte(s).  */
+  if (needed > 2 && needed == last_needed + 1)
     {
-      int32_t tmp = findidx (&usrc, -1);
-      rulearr[idxmax] = tmp >> 24;
-      idxarr[idxmax] = tmp & 0xffffff;
-
-      ++idxmax;
+      /* Remove the \1 byte.  */
+      if (--needed <= n)
+	dest[needed - 1] = L('\0');
     }
-  while (*usrc != L('\0'));
 
-  /* This element is only read, the value never used but to determine
-     another value which then is ignored.  */
-  rulearr[idxmax] = '\0';
+  /* Return the number of bytes/words we need, but don't count the NUL
+     byte/word at the end.  */
+  return needed - 1;
+}
+
+/* Do the transformation using weight-index and rule cache.  */
+static size_t
+do_xfrm_cached (STRING_TYPE *dest, size_t n, const locale_data_t *l_data,
+		size_t idxmax, int32_t *idxarr, const unsigned char *rulearr)
+{
+  uint_fast32_t nrules = l_data->nrules;
+  unsigned char *rulesets = l_data->rulesets;
+  USTRING_TYPE *weights = l_data->weights;
+  uint_fast32_t pass;
+  size_t needed = 0;
+  size_t last_needed;
+  size_t idxcnt;
 
-  /* Now the passes over the weights.  We now use the indeces we found
-     before.  */
-  needed = 0;
+  /* Now the passes over the weights.  */
   for (pass = 0; pass < nrules; ++pass)
     {
       size_t backw_stop = ~0ul;
@@ -434,14 +664,91 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
 	dest[needed - 1] = L('\0');
     }
 
-  /* Free the memory if needed.  */
-  if (use_malloc)
-    free (idxarr);
-
   /* Return the number of bytes/words we need, but don't count the NUL
      byte/word at the end.  */
   return needed - 1;
 }
+
+size_t
+STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
+{
+  locale_data_t l_data;
+  struct __locale_data *current = l->__locales[LC_COLLATE];
+  l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
+
+  /* Handle byte comparison case.  */
+  if (l_data.nrules == 0)
+    {
+      size_t srclen = STRLEN (src);
+
+      if (n != 0)
+	STPNCPY (dest, src, MIN (srclen + 1, n));
+
+      return srclen;
+    }
+
+  /* Handle an empty string, code hereafter relies on strlen (src) > 0.  */
+  if (*src == L('\0'))
+    {
+      if (n != 0)
+	*dest = L('\0');
+      return 0;
+    }
+
+  /* Get the locale data.  */
+  l_data.rulesets = (unsigned char *)
+    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
+  l_data.table = (int32_t *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
+  l_data.weights = (USTRING_TYPE *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
+  l_data.extra = (USTRING_TYPE *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
+  l_data.indirect = (int32_t *)
+    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
+
+  assert (((uintptr_t) l_data.table) % __alignof__ (l_data.table[0]) == 0);
+  assert (((uintptr_t) l_data.weights) % __alignof__ (l_data.weights[0]) == 0);
+  assert (((uintptr_t) l_data.extra) % __alignof__ (l_data.extra[0]) == 0);
+  assert (((uintptr_t) l_data.indirect) % __alignof__ (l_data.indirect[0]) == 0);
+
+  /* We need the elements of the string as unsigned values since they
+     are used as indeces.  */
+  const USTRING_TYPE *usrc = (const USTRING_TYPE *) src;
+
+  /* Allocate cache for small strings on the stack and fill it with weight and
+     rule indices.  If the cache size is not sufficient, continue with the
+     uncached xfrm version.  */
+  size_t idxmax = 0;
+  const USTRING_TYPE *cur = usrc;
+  int32_t *idxarr = alloca (SMALL_STR_SIZE * sizeof (int32_t));
+  unsigned char *rulearr = alloca (SMALL_STR_SIZE + 1);
+  /* Prepare variables required by findidx().  */
+  int32_t *table = l_data.table;
+  int32_t *indirect = l_data.indirect;
+  USTRING_TYPE *extra = l_data.extra;
+#include WEIGHT_H
+
+  do
+    {
+      int32_t tmp = findidx (&cur, -1);
+      rulearr[idxmax] = tmp >> 24;
+      idxarr[idxmax] = tmp & 0xffffff;
+
+      ++idxmax;
+    }
+  while (*cur != L('\0') && idxmax < SMALL_STR_SIZE);
+
+  /* This element is only read, the value never used but to determine
+     another value which then is ignored.  */
+  rulearr[idxmax] = '\0';
+
+  /* Do the transformation.  */
+  if (*cur == L('\0'))
+    return do_xfrm_cached (dest, n, &l_data, idxmax, idxarr, rulearr);
+  else
+    return do_xfrm (usrc, dest, n, &l_data);
+}
 libc_hidden_def (STRXFRM)
 
 #ifndef WIDE_CHAR_VERSION
diff --git a/string/test-strcmp.c b/string/test-strcmp.c
index b395dc7..fcd059f 100644
--- a/string/test-strcmp.c
+++ b/string/test-strcmp.c
@@ -329,6 +329,34 @@ check (void)
 		FOR_EACH_IMPL (impl, 0)
 		check_result (impl, s1 + i1, s2 + i2, exp_result);
       }
+
+  /* Test cases where there are multiple zero bytes after the first.  */
+
+  for (size_t i = 0; i < 16 + 1; i++)
+    {
+      s1[i] = 0x00;
+      s2[i] = 0x00;
+    }
+
+  for (size_t i = 0; i < 16; i++)
+    {
+      int exp_result;
+
+      for (int val = 0x01; val < 0x100; val++)
+	{
+	  for (size_t j = 0; j < i; j++)
+	    {
+	      s1[j] = val;
+	      s2[j] = val;
+	    }
+
+	  s2[i] = val;
+
+	  exp_result = SIMPLE_STRCMP (s1, s2);
+	  FOR_EACH_IMPL (impl, 0)
+	    check_result (impl, s1, s2, exp_result);
+	}
+    }
 }
 
 
diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
index 1b6a20b..81d5637 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/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index ffeb093..9d767b6 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -590,9 +590,6 @@ struct rtld_global_ro
   /* List of auditing interfaces.  */
   struct audit_ifaces *_dl_audit;
   unsigned int _dl_naudit;
-
-  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
-  EXTERN int _dl_pointer_guard;
 };
 # define __rtld_global_attribute__
 # ifdef IS_IN_rtld
diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
index 6105e9f..50109b8 100644
--- a/sysdeps/ieee754/dbl-64/s_sin.c
+++ b/sysdeps/ieee754/dbl-64/s_sin.c
@@ -447,19 +447,21 @@ __sin (double x)
 	    }
 	  else
 	    {
+	      double t;
 	      if (a > 0)
 		{
 		  m = 1;
+		  t = a;
 		  db = da;
 		}
 	      else
 		{
 		  m = 0;
-		  a = -a;
+		  t = -a;
 		  db = -da;
 		}
-	      u.x = big + a;
-	      y = a - (u.x - big);
+	      u.x = big + t;
+	      y = t - (u.x - big);
 	      res = do_sin (u, y, db, &cor);
 	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
 	      retval = ((res == res + cor) ? ((m) ? res : -res)
@@ -671,19 +673,21 @@ __cos (double x)
 	    }
 	  else
 	    {
+	      double t;
 	      if (a > 0)
 		{
 		  m = 1;
+		  t = a;
 		  db = da;
 		}
 	      else
 		{
 		  m = 0;
-		  a = -a;
+		  t = -a;
 		  db = -da;
 		}
-	      u.x = big + a;
-	      y = a - (u.x - big);
+	      u.x = big + t;
+	      y = t - (u.x - big);
 	      res = do_sin (u, y, db, &cor);
 	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
 	      retval = ((res == res + cor) ? ((m) ? res : -res)
diff --git a/sysdeps/mach/hurd/open.c b/sysdeps/mach/hurd/open.c
index 7d9b2de..f003d03 100644
--- a/sysdeps/mach/hurd/open.c
+++ b/sysdeps/mach/hurd/open.c
@@ -22,7 +22,7 @@
 #include <hurd.h>
 #include <hurd/fd.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open (const char *file, int oflag, ...)
@@ -30,7 +30,7 @@ __libc_open (const char *file, int oflag, ...)
   mode_t mode;
   io_t port;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/sysdeps/mach/hurd/openat.c b/sysdeps/mach/hurd/openat.c
index 318cb22..83ffe13 100644
--- a/sysdeps/mach/hurd/openat.c
+++ b/sysdeps/mach/hurd/openat.c
@@ -26,7 +26,7 @@
 #include <hurd/fd.h>
 
 /* Open FILE with access OFLAG.  Interpret relative paths relative to
-   the directory associated with FD.  If OFLAG includes O_CREAT, a
+   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
    third argument is the file protection.  */
 int
 __openat (fd, file, oflag)
@@ -37,7 +37,7 @@ __openat (fd, file, oflag)
   mode_t mode;
   io_t port;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 8218237..df6ce8b 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
+		      /* We found data, convert it.  */
+		      if (!convert_hostent_to_gaih_addrtuple
+			  (req, AF_INET, h, &addrmem))
 			{
-			  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)
-			{
-			  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
@@ -712,6 +720,18 @@ gaih_inet (const char *name, const struct gaih_service *service,
 		    {
 		      socklen_t size = (air->family[i] == AF_INET
 					? INADDRSZ : IN6ADDRSZ);
+
+		      if (!((air->family[i] == AF_INET
+			     && req->ai_family == AF_INET6
+			     && (req->ai_flags & AI_V4MAPPED) != 0)
+			    || req->ai_family == AF_UNSPEC
+			    || air->family[i] == req->ai_family))
+			{
+			  /* Skip over non-matching result.  */
+			  addrs += size;
+			  continue;
+			}
+
 		      if (*pat == NULL)
 			{
 			  *pat = addrfree++;
diff --git a/sysdeps/posix/open64.c b/sysdeps/posix/open64.c
index 64d192a..4b7ec36 100644
--- a/sysdeps/posix/open64.c
+++ b/sysdeps/posix/open64.c
@@ -19,14 +19,14 @@
 #include <stdarg.h>
 #include <sysdep-cancel.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open64 (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/sysdeps/powerpc/fpu/e_sqrt.c b/sysdeps/powerpc/fpu/e_sqrt.c
index 0368e57..022d71b 100644
--- a/sysdeps/powerpc/fpu/e_sqrt.c
+++ b/sysdeps/powerpc/fpu/e_sqrt.c
@@ -24,6 +24,7 @@
 #include <sysdep.h>
 #include <ldsodefs.h>
 
+#ifndef _ARCH_PPCSQ
 static const double almost_half = 0.5000000000000001;	/* 0.5 + 2^-53 */
 static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
 static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
@@ -98,38 +99,41 @@ __slow_ieee754_sqrt (double x)
 	  /* Here we have three Newton-Raphson iterations each of a
 	     division and a square root and the remainder of the
 	     argument reduction, all interleaved.   */
-	  sd = -(sg * sg - sx);
+	  sd = -__builtin_fma (sg, sg, -sx);
 	  fsgi = (xi0 + 0x40000000) >> 1 & 0x7ff00000;
 	  sy2 = sy + sy;
-	  sg = sy * sd + sg;	/* 16-bit approximation to sqrt(sx). */
+	  sg = __builtin_fma (sy, sd, sg);	/* 16-bit approximation to
+						   sqrt(sx). */
 
 	  /* schedule the INSERT_WORDS (fsg, fsgi, 0) to get separation
 	     between the store and the load.  */
 	  INSERT_WORDS (fsg, fsgi, 0);
 	  iw_u.parts.msw = fsgi;
 	  iw_u.parts.lsw = (0);
-	  e = -(sy * sg - almost_half);
-	  sd = -(sg * sg - sx);
+	  e = -__builtin_fma (sy, sg, -almost_half);
+	  sd = -__builtin_fma (sg, sg, -sx);
 	  if ((xi0 & 0x7ff00000) == 0)
 	    goto denorm;
-	  sy = sy + e * sy2;
-	  sg = sg + sy * sd;	/* 32-bit approximation to sqrt(sx).  */
+	  sy = __builtin_fma (e, sy2, sy);
+	  sg = __builtin_fma (sy, sd, sg);	/* 32-bit approximation to
+						   sqrt(sx).  */
 	  sy2 = sy + sy;
 	  /* complete the INSERT_WORDS (fsg, fsgi, 0) operation.  */
 	  fsg = iw_u.value;
-	  e = -(sy * sg - almost_half);
-	  sd = -(sg * sg - sx);
-	  sy = sy + e * sy2;
+	  e = -__builtin_fma (sy, sg, -almost_half);
+	  sd = -__builtin_fma (sg, sg, -sx);
+	  sy = __builtin_fma (e, sy2, sy);
 	  shx = sx * fsg;
-	  sg = sg + sy * sd;	/* 64-bit approximation to sqrt(sx),
-				   but perhaps rounded incorrectly.  */
+	  sg = __builtin_fma (sy, sd, sg);	/* 64-bit approximation to
+						   sqrt(sx), but perhaps
+						   rounded incorrectly.  */
 	  sy2 = sy + sy;
 	  g = sg * fsg;
-	  e = -(sy * sg - almost_half);
-	  d = -(g * sg - shx);
-	  sy = sy + e * sy2;
+	  e = -__builtin_fma (sy, sg, -almost_half);
+	  d = -__builtin_fma (g, sg, -shx);
+	  sy = __builtin_fma (e, sy2, sy);
 	  fesetenv_register (fe);
-	  return g + sy * d;
+	  return __builtin_fma (sy, d, g);
 	denorm:
 	  /* For denormalised numbers, we normalise, calculate the
 	     square root, and return an adjusted result.  */
@@ -152,6 +156,7 @@ __slow_ieee754_sqrt (double x)
     }
   return f_wash (x);
 }
+#endif /* _ARCH_PPCSQ  */
 
 #undef __ieee754_sqrt
 double
@@ -159,16 +164,11 @@ __ieee754_sqrt (double x)
 {
   double z;
 
-  /* If the CPU is 64-bit we can use the optional FP instructions.  */
-  if (__CPU_HAS_FSQRT)
-    {
-      /* Volatile is required to prevent the compiler from moving the
-	 fsqrt instruction above the branch.  */
-      __asm __volatile ("	fsqrt	%0,%1\n"
-				:"=f" (z):"f" (x));
-    }
-  else
-    z = __slow_ieee754_sqrt (x);
+#ifdef _ARCH_PPCSQ
+  asm ("fsqrt %0,%1\n" :"=f" (z):"f" (x));
+#else
+  z = __slow_ieee754_sqrt (x);
+#endif
 
   return z;
 }
diff --git a/sysdeps/powerpc/fpu/e_sqrtf.c b/sysdeps/powerpc/fpu/e_sqrtf.c
index fcc74ae..7d2bfb7 100644
--- a/sysdeps/powerpc/fpu/e_sqrtf.c
+++ b/sysdeps/powerpc/fpu/e_sqrtf.c
@@ -24,6 +24,7 @@
 #include <sysdep.h>
 #include <ldsodefs.h>
 
+#ifndef _ARCH_PPCSQ
 static const float almost_half = 0.50000006;	/* 0.5 + 2^-24 */
 static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
 static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
@@ -128,6 +129,7 @@ __slow_ieee754_sqrtf (float x)
     }
   return f_washf (x);
 }
+#endif /* _ARCH_PPCSQ  */
 
 #undef __ieee754_sqrtf
 float
@@ -135,16 +137,11 @@ __ieee754_sqrtf (float x)
 {
   double z;
 
-  /* If the CPU is 64-bit we can use the optional FP instructions.  */
-  if (__CPU_HAS_FSQRT)
-    {
-      /* Volatile is required to prevent the compiler from moving the
-	 fsqrt instruction above the branch.  */
-      __asm __volatile ("	fsqrts	%0,%1\n"
-				:"=f" (z):"f" (x));
-    }
-  else
-    z = __slow_ieee754_sqrtf (x);
+#ifdef _ARCH_PPCSQ
+  asm ("fsqrts	%0,%1\n" :"=f" (z):"f" (x));
+#else
+  z = __slow_ieee754_sqrtf (x);
+#endif
 
   return z;
 }
diff --git a/sysdeps/powerpc/fpu/math_private.h b/sysdeps/powerpc/fpu/math_private.h
index dde153d..9048715 100644
--- a/sysdeps/powerpc/fpu/math_private.h
+++ b/sysdeps/powerpc/fpu/math_private.h
@@ -25,26 +25,17 @@
 #include <fenv_private.h>
 #include_next <math_private.h>
 
-# if __WORDSIZE == 64 || defined _ARCH_PWR4
-#  define __CPU_HAS_FSQRT 1
-# else
-#  define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
-# endif
-
 extern double __slow_ieee754_sqrt (double);
 extern __always_inline double
 __ieee754_sqrt (double __x)
 {
   double __z;
 
-  if (__CPU_HAS_FSQRT)
-    {
-      /* Volatile is required to prevent the compiler from moving the
-         fsqrt instruction above the branch.  */
-      __asm __volatile ("fsqrt	%0,%1" : "=f" (__z) : "f" (__x));
-    }
-  else
-     __z = __slow_ieee754_sqrt(__x);
+#ifdef _ARCH_PPCSQ
+   asm ("fsqrt	%0,%1" : "=f" (__z) : "f" (__x));
+#else
+   __z = __slow_ieee754_sqrt(__x);
+#endif
 
   return __z;
 }
@@ -55,14 +46,11 @@ __ieee754_sqrtf (float __x)
 {
   float __z;
 
-  if (__CPU_HAS_FSQRT)
-    {
-      /* Volatile is required to prevent the compiler from moving the
-         fsqrts instruction above the branch.  */
-      __asm __volatile ("fsqrts	%0,%1" : "=f" (__z) : "f" (__x));
-    }
-  else
-     __z = __slow_ieee754_sqrtf(__x);
+#ifdef _ARCH_PPCSQ
+  asm ("fsqrts	%0,%1" : "=f" (__z) : "f" (__x));
+#else
+   __z = __slow_ieee754_sqrtf(__x);
+#endif
 
   return __z;
 }
diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h
index 76ead1d..30553c1 100644
--- a/sysdeps/powerpc/powerpc64/entry.h
+++ b/sysdeps/powerpc/powerpc64/entry.h
@@ -23,6 +23,7 @@ extern void _start (void);
 
 #define ENTRY_POINT _start
 
+#if _CALL_ELF != 2
 /* We have to provide a special declaration.  */
 #define ENTRY_POINT_DECL(class) class void _start (void);
 
@@ -33,3 +34,4 @@ extern void _start (void);
 #define TEXT_START \
   ({ extern unsigned long int _start_as_data[] asm ("_start");  \
      _start_as_data[0]; })
+#endif
diff --git a/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c b/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c
deleted file mode 100644
index 08d5f69..0000000
--- a/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Double-precision floating point square root.
-   Copyright (C) 1997-2014 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 <math.h>
-#include <math_private.h>
-
-#undef __ieee754_sqrt
-double
-__ieee754_sqrt (double x)
-{
-  double z;
-  __asm __volatile ("fsqrt %0,%1" : "=f" (z) : "f" (x));
-  return z;
-}
-strong_alias (__ieee754_sqrt, __sqrt_finite)
diff --git a/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c b/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c
deleted file mode 100644
index 598e7cb..0000000
--- a/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Single-precision floating point square root.
-   Copyright (C) 1997-2014 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 <math.h>
-#include <math_private.h>
-
-#undef __ieee754_sqrtf
-float
-__ieee754_sqrtf (float x)
-{
-  double z;
-  __asm ("fsqrts %0,%1" : "=f" (z) : "f" (x));
-  return z;
-}
-strong_alias (__ieee754_sqrtf, __sqrtf_finite)
diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
deleted file mode 100644
index 42978dc..0000000
--- a/sysdeps/s390/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-ifeq ($(subdir),setjmp)
-ifeq (yes,$(build-shared))
-sysdep_routines += v1-longjmp v1-sigjmp
-endif
-endif
-
-ifeq ($(subdir),csu)
-gen-as-const-headers += rtld-global-offsets.sym
-endif
diff --git a/sysdeps/s390/Versions b/sysdeps/s390/Versions
index 156abc7..8417623 100644
--- a/sysdeps/s390/Versions
+++ b/sysdeps/s390/Versions
@@ -1,12 +1,8 @@
 libc {
   GLIBC_2.19 {
-    setjmp; _setjmp; __setjmp; __sigsetjmp;
+    setjmp; _setjmp; __sigsetjmp;
     longjmp; _longjmp; siglongjmp;
   }
-  GLIBC_PRIVATE {
-    __v1__libc_longjmp; __v1__libc_siglongjmp;
-    __v2__libc_longjmp; __v2__libc_siglongjmp;
-  }
 }
 
 ld {
diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c
deleted file mode 100644
index e4acd31..0000000
--- a/sysdeps/s390/__longjmp.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2013 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 <libc-symbols.h>
-#include <shlib-compat.h>
-
-#define __longjmp  __v2__longjmp
-#include "__longjmp-common.c"
-#undef __longjmp
-strong_alias (__v2__longjmp, __longjmp)
-
-#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19)
-# undef __longjmp
-# define __V1_JMPBUF
-# define __longjmp  __v1__longjmp
-# include "__longjmp-common.c"
-#endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19) */
diff --git a/sysdeps/s390/bits/setjmp.h b/sysdeps/s390/bits/setjmp.h
index 25eaf10..0071a9d 100644
--- a/sysdeps/s390/bits/setjmp.h
+++ b/sysdeps/s390/bits/setjmp.h
@@ -40,10 +40,6 @@ typedef struct __s390_jmp_buf
   /* We save fpu registers 4 and 6.  */
   long __fpregs[4];
 # endif
-#ifndef __V1_JMPBUF
-  unsigned long __flags;
-  char __reserved[128];
-#endif
 } __jmp_buf[1];
 
 #endif
diff --git a/sysdeps/s390/longjmp.c b/sysdeps/s390/longjmp.c
index c758d14..601f077 100644
--- a/sysdeps/s390/longjmp.c
+++ b/sysdeps/s390/longjmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -15,50 +15,28 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.
 
-   Versioned copy of sysdeps/generic/longjmp.c modified for extended
-   jmpbuf.  */
+   Versioned copy of setjmp/longjmp.c modified for versioning
+   the reverted jmpbuf extension.  */
 
 #include <shlib-compat.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <signal.h>
 
-extern void __v2__longjmp (__jmp_buf __env, int __val)
-     __attribute__ ((__noreturn__));
-extern void __v2__libc_longjmp (sigjmp_buf env, int val)
-     __attribute__ ((__noreturn__));
-libc_hidden_proto (__v2__libc_longjmp)
-
-/* Set the signal mask to the one specified in ENV, and jump
-   to the position specified in ENV, causing the setjmp
-   call there to return VAL, or 1 if VAL is 0.  */
-void
-__v2__libc_siglongjmp (sigjmp_buf env, int val)
-{
-  /* Perform any cleanups needed by the frames being unwound.  */
-  _longjmp_unwind (env, val);
-
-  if (env[0].__mask_was_saved)
-    /* Restore the saved signal mask.  */
-    (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask,
-			  (sigset_t *) NULL);
-
-  /* Call the machine-dependent function to restore machine state.  */
-  __v2__longjmp (env[0].__jmpbuf, val ?: 1);
-}
-
-#ifndef __v2__longjmp
-strong_alias (__v2__libc_siglongjmp, __v2__libc_longjmp)
-libc_hidden_def (__v2__libc_longjmp)
-weak_alias (__v2__libc_siglongjmp, __v2_longjmp)
-weak_alias (__v2__libc_siglongjmp, __v2longjmp)
-weak_alias (__v2__libc_siglongjmp, __v2siglongjmp)
-
-/* These will be used by libpthread only.  */
-versioned_symbol (libc, __v2__libc_longjmp, __libc_longjmp, GLIBC_PRIVATE);
-versioned_symbol (libc, __v2__libc_siglongjmp, __libc_siglongjmp, GLIBC_PRIVATE);
-
-versioned_symbol (libc, __v2_longjmp, _longjmp, GLIBC_2_19);
-versioned_symbol (libc, __v2longjmp, longjmp, GLIBC_2_19);
-versioned_symbol (libc, __v2siglongjmp, siglongjmp, GLIBC_2_19);
-#endif /* ifndef __v2__longjmp */
+#include <setjmp/longjmp.c>
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+/* In glibc release 2.19 new versions of longjmp-functions were introduced,
+   but were reverted before 2.20. Thus both versions are the same function.  */
+weak_alias (__libc_siglongjmp, __v1_longjmp)
+weak_alias (__libc_siglongjmp, __v2_longjmp)
+versioned_symbol (libc, __v1_longjmp, _longjmp, GLIBC_2_0);
+compat_symbol (libc, __v2_longjmp, _longjmp, GLIBC_2_19);
+
+weak_alias (__libc_siglongjmp, __v1longjmp)
+weak_alias (__libc_siglongjmp, __v2longjmp)
+versioned_symbol (libc, __v1longjmp, longjmp, GLIBC_2_0);
+compat_symbol (libc, __v2longjmp, longjmp, GLIBC_2_19);
+
+weak_alias (__libc_siglongjmp, __v1siglongjmp)
+weak_alias (__libc_siglongjmp, __v2siglongjmp)
+versioned_symbol (libc, __v1siglongjmp, siglongjmp, GLIBC_2_0);
+compat_symbol (libc, __v2siglongjmp, siglongjmp, GLIBC_2_19);
+#endif /* SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)  */
diff --git a/sysdeps/s390/rtld-__longjmp.c b/sysdeps/s390/rtld-__longjmp.c
deleted file mode 100644
index 5e9f739..0000000
--- a/sysdeps/s390/rtld-__longjmp.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2013 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/>.  */
-
-/* Build a non-versioned object for rtld-*.  */
-# include "__longjmp-common.c"
diff --git a/sysdeps/s390/rtld-global-offsets.sym b/sysdeps/s390/rtld-global-offsets.sym
deleted file mode 100644
index ff4e97f..0000000
--- a/sysdeps/s390/rtld-global-offsets.sym
+++ /dev/null
@@ -1,7 +0,0 @@
-#define SHARED 1
-
-#include <ldsodefs.h>
-
-#define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem)
-
-RTLD_GLOBAL_RO_DL_HWCAP_OFFSET	rtld_global_ro_offsetof (_dl_hwcap)
diff --git a/sysdeps/s390/rtld-setjmp.S b/sysdeps/s390/rtld-setjmp.S
deleted file mode 100644
index 4011011..0000000
--- a/sysdeps/s390/rtld-setjmp.S
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Extendible version of setjmp for System z
-   Copyright (C) 2013 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/>.  */
-
-/* Build a non-versioned object for rtld-*.  */
-# include "setjmp-common.S"
diff --git a/sysdeps/s390/s390-32/__longjmp-common.c b/sysdeps/s390/s390-32/__longjmp-common.c
deleted file mode 100644
index f78ef65..0000000
--- a/sysdeps/s390/s390-32/__longjmp-common.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (C) 2000-2014 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
-
-   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 <errno.h>
-#include <sysdep.h>
-#include <setjmp.h>
-#include <bits/setjmp.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-/* Jump to the position specified by ENV, causing the
-   setjmp call there to return VAL, or 1 if VAL is 0.  */
-attribute_hidden void
-__longjmp (__jmp_buf env, int val)
-{
-#ifdef PTR_DEMANGLE
-  uintptr_t guard = THREAD_GET_POINTER_GUARD ();
-# ifdef CHECK_SP
-  CHECK_SP (env, guard);
-# endif
-#elif defined CHECK_SP
-  CHECK_SP (env, 0);
-#endif
-  register int r2 __asm ("%r2") = val == 0 ? 1 : val;
-#ifdef PTR_DEMANGLE
-  register uintptr_t r3 __asm ("%r3") = guard;
-  register void *r1 __asm ("%r1") = (void *) env;
-#endif
-  /* Restore registers and jump back.  */
-  asm volatile ("ld   %%f6,48(%1)\n\t"
-		"ld   %%f4,40(%1)\n\t"
-#ifdef PTR_DEMANGLE
-		"lm   %%r6,%%r13,0(%1)\n\t"
-		"lm   %%r4,%%r5,32(%1)\n\t"
-		"xr   %%r4,%2\n\t"
-		"xr   %%r5,%2\n\t"
-		"lr   %%r15,%%r5\n\t"
-		"br   %%r4"
-#else
-		"lm   %%r6,%%r15,0(%1)\n\t"
-		"br   %%r14"
-#endif
-		: : "r" (r2),
-#ifdef PTR_DEMANGLE
-		    "r" (r1), "r" (r3)
-#else
-		    "a" (env)
-#endif
-		);
-
-  /* Avoid `volatile function does return' warnings.  */
-  for (;;);
-}
diff --git a/sysdeps/s390/s390-32/__longjmp.c b/sysdeps/s390/s390-32/__longjmp.c
new file mode 100644
index 0000000..5d46e21
--- /dev/null
+++ b/sysdeps/s390/s390-32/__longjmp.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 2000-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+   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 <errno.h>
+#include <sysdep.h>
+#include <setjmp.h>
+#include <bits/setjmp.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Jump to the position specified by ENV, causing the
+   setjmp call there to return VAL, or 1 if VAL is 0.  */
+void
+__longjmp (__jmp_buf env, int val)
+{
+#ifdef PTR_DEMANGLE
+  uintptr_t guard = THREAD_GET_POINTER_GUARD ();
+# ifdef CHECK_SP
+  CHECK_SP (env, guard);
+# endif
+#elif defined CHECK_SP
+  CHECK_SP (env, 0);
+#endif
+  register int r2 __asm ("%r2") = val == 0 ? 1 : val;
+#ifdef PTR_DEMANGLE
+  register uintptr_t r3 __asm ("%r3") = guard;
+  register void *r1 __asm ("%r1") = (void *) env;
+#endif
+  /* Restore registers and jump back.  */
+  asm volatile ("ld   %%f6,48(%1)\n\t"
+		"ld   %%f4,40(%1)\n\t"
+#ifdef PTR_DEMANGLE
+		"lm   %%r6,%%r13,0(%1)\n\t"
+		"lm   %%r4,%%r5,32(%1)\n\t"
+		"xr   %%r4,%2\n\t"
+		"xr   %%r5,%2\n\t"
+		"lr   %%r15,%%r5\n\t"
+		"br   %%r4"
+#else
+		"lm   %%r6,%%r15,0(%1)\n\t"
+		"br   %%r14"
+#endif
+		: : "r" (r2),
+#ifdef PTR_DEMANGLE
+		    "r" (r1), "r" (r3)
+#else
+		    "a" (env)
+#endif
+		);
+
+  /* Avoid `volatile function does return' warnings.  */
+  for (;;);
+}
diff --git a/sysdeps/s390/s390-32/setjmp-common.S b/sysdeps/s390/s390-32/setjmp-common.S
deleted file mode 100644
index d7bb720..0000000
--- a/sysdeps/s390/s390-32/setjmp-common.S
+++ /dev/null
@@ -1,84 +0,0 @@
-/* setjmp for s390, ELF version.
-   Copyright (C) 2000-2014 Free Software Foundation, Inc.
-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
-   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 <sysdep.h>
-#define _ASM
-#define _SETJMP_H
-#include <bits/setjmp.h>
-
-	/* We include the BSD entry points here as well but we make
-	   them weak.  */
-ENTRY (setjmp)
-	.weak C_SYMBOL_NAME (setjmp)
-	lhi    %r3,1                /* second argument of one */
-	j      0f                   /* branch relativ to __sigsetjmp */
-END (setjmp)
-
-	/* Binary compatibility entry point.  */
-ENTRY(_setjmp)
-	.weak  C_SYMBOL_NAME (_setjmp)
-	lhi    %r3,0                /* second argument of zero */
-	j      0f                   /* branch relativ to __sigsetjmp */
-END (_setjmp)
-libc_hidden_def (_setjmp)
-
-ENTRY(__setjmp)
-	lhi    %r3,0                /* second argument of zero */
-	j      0f                   /* branch relativ to __sigsetjmp */
-END (__setjmp)
-
-ENTRY(__sigsetjmp)
-0:
-#ifdef PTR_MANGLE
-	stm    %r6,%r13,0(%r2)      /* store registers in jmp_buf */
-	lr     %r4,%r14
-	lr     %r5,%r15
-	PTR_MANGLE (%r4, %r1)
-	PTR_MANGLE2 (%r5, %r1)
-	stm    %r4,%r5,32(%r2)
-#else
-	stm    %r6,%r15,0(%r2)      /* store registers in jmp_buf */
-#endif
-#ifndef __V1_JMPBUF
-	lhi    %r4,0
-	st     %r4,56(%r2)         /* Set __flags to 0.  */
-#endif
-	std    %f4,40(%r2)
-	std    %f6,48(%r2)
-#if defined NOT_IN_libc && defined IS_IN_rtld
-	/* In ld.so we never save the signal mask.  */
-	lhi    %r2,0
-	br     %r14
-#elif defined PIC
-	/* We cannot use the PLT, because it requires that %r12 be set, but
-	   we can't save and restore our caller's value.  Instead, we do an
-	   indirect jump through the GOT. */
-	basr   %r1,0
-0:      al     %r1,1f-0b(0,%r1) /* get address of global offset table */
-				/* get address of __sigjmp_save from got */
-	l      %r1,__sigjmp_save@GOT12(0,%r1)
-	br     %r1
-1:      .long  _GLOBAL_OFFSET_TABLE_ - 0b
-#else
-	basr   %r1,0
-0:      l      %r1,1f-0b(0,%r1)   /* load address of __sigjmp_save */
-	br     %r1                /* tail-call __sigjmp_save */
-1:      .long  __sigjmp_save
-#endif
-END (__sigsetjmp)
diff --git a/sysdeps/s390/s390-32/setjmp.S b/sysdeps/s390/s390-32/setjmp.S
new file mode 100644
index 0000000..e940d71
--- /dev/null
+++ b/sysdeps/s390/s390-32/setjmp.S
@@ -0,0 +1,111 @@
+/* setjmp for s390, ELF version.
+   Copyright (C) 2000-2014 Free Software Foundation, Inc.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+   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 <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+#include <shlib-compat.h>
+
+#if !defined IS_IN_rtld
+# if defined SHARED &&  SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+	/* we need a unique name in case of symbol versioning.  */
+#  define __sigsetjmp __v1__sigsetjmp
+# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)  */
+#endif /* !defined IS_IN_rtld  */
+
+	/* We include the BSD entry points here as well but we make
+	   them weak.  */
+ENTRY (setjmp)
+	.weak C_SYMBOL_NAME (setjmp)
+	lhi    %r3,1                /* second argument of one */
+	j      .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
+END (setjmp)
+
+	/* Binary compatibility entry point.  */
+ENTRY(_setjmp)
+	.weak  C_SYMBOL_NAME (_setjmp)
+	lhi    %r3,0                /* second argument of zero */
+	j      .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
+END (_setjmp)
+libc_hidden_def (_setjmp)
+
+ENTRY(__setjmp)
+	lhi    %r3,0                /* second argument of zero */
+	j      .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
+END (__setjmp)
+
+ENTRY(__sigsetjmp)
+.Linternal_sigsetjmp:
+#ifdef PTR_MANGLE
+	stm    %r6,%r13,0(%r2)      /* store registers in jmp_buf */
+	lr     %r4,%r14
+	lr     %r5,%r15
+	PTR_MANGLE (%r4, %r1)
+	PTR_MANGLE2 (%r5, %r1)
+	stm    %r4,%r5,32(%r2)
+#else
+	stm    %r6,%r15,0(%r2)      /* store registers in jmp_buf */
+#endif
+	std    %f4,40(%r2)
+	std    %f6,48(%r2)
+#if defined NOT_IN_libc && defined IS_IN_rtld
+	/* In ld.so we never save the signal mask.  */
+	lhi    %r2,0
+	br     %r14
+#elif defined PIC
+	/* We cannot use the PLT, because it requires that %r12 be set, but
+	   we can't save and restore our caller's value.  Instead, we do an
+	   indirect jump through the GOT. */
+	basr   %r1,0
+.L0:    al     %r1,.L1 - .L0(0,%r1) /* get address of global offset table */
+				    /* get address of __sigjmp_save from got */
+	l      %r1,__sigjmp_save@GOT12(0,%r1)
+	br     %r1
+.L1:    .long  _GLOBAL_OFFSET_TABLE_ - .L0
+#else
+	basr   %r1,0
+.L0:    l      %r1,.L1-.L0(0,%r1)   /* load address of __sigjmp_save */
+	br     %r1                  /* tail-call __sigjmp_save */
+.L1:    .long  __sigjmp_save
+#endif
+END (__sigsetjmp)
+
+#if !defined IS_IN_rtld
+# if defined SHARED &&  SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+/* In glibc release 2.19 new versions of setjmp-functions were introduced,
+   but were reverted before 2.20. Thus both versions are the same function.  */
+
+#  undef __sigsetjmp
+
+weak_alias (setjmp, __v1setjmp);
+weak_alias (setjmp, __v2setjmp);
+versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0);
+compat_symbol (libc, __v2setjmp, setjmp, GLIBC_2_19);
+
+weak_alias (_setjmp, __v1_setjmp);
+weak_alias (_setjmp, __v2_setjmp);
+versioned_symbol (libc, __v1_setjmp, _setjmp, GLIBC_2_0);
+compat_symbol (libc, __v2_setjmp, _setjmp, GLIBC_2_19);
+
+strong_alias (__v1__sigsetjmp, __v2__sigsetjmp);
+versioned_symbol (libc, __v1__sigsetjmp, __sigsetjmp, GLIBC_2_0);
+compat_symbol (libc, __v2__sigsetjmp, __sigsetjmp, GLIBC_2_19);
+# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)  */
+#endif /* if !defined IS_IN_rtld  */
diff --git a/sysdeps/s390/s390-64/__longjmp-common.c b/sysdeps/s390/s390-64/__longjmp-common.c
deleted file mode 100644
index 46cabb6..0000000
--- a/sysdeps/s390/s390-64/__longjmp-common.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
-
-   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 <errno.h>
-#include <sysdep.h>
-#include <setjmp.h>
-#include <bits/setjmp.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-/* Jump to the position specified by ENV, causing the
-   setjmp call there to return VAL, or 1 if VAL is 0.  */
-attribute_hidden void
-__longjmp (__jmp_buf env, int val)
-{
-#ifdef PTR_DEMANGLE
-  uintptr_t guard = THREAD_GET_POINTER_GUARD ();
-# ifdef CHECK_SP
-  CHECK_SP (env, guard);
-# endif
-#elif defined CHECK_SP
-  CHECK_SP (env, 0);
-#endif
-  register long int r2 __asm ("%r2") = val == 0 ? 1 : val;
-#ifdef PTR_DEMANGLE
-  register uintptr_t r3 __asm ("%r3") = guard;
-  register void *r1 __asm ("%r1") = (void *) env;
-#endif
-  /* Restore registers and jump back.  */
-  asm volatile ("ld    %%f8,80(%1)\n\t"
-		"ld    %%f9,88(%1)\n\t"
-		"ld    %%f10,96(%1)\n\t"
-		"ld    %%f11,104(%1)\n\t"
-		"ld    %%f12,112(%1)\n\t"
-		"ld    %%f13,120(%1)\n\t"
-		"ld    %%f14,128(%1)\n\t"
-		"ld    %%f15,136(%1)\n\t"
-#ifdef PTR_DEMANGLE
-		"lmg  %%r6,%%r13,0(%1)\n\t"
-		"lmg  %%r4,%%r5,64(%1)\n\t"
-		"xgr  %%r4,%2\n\t"
-		"xgr  %%r5,%2\n\t"
-		"lgr  %%r15,%%r5\n\t"
-		"br   %%r4"
-#else
-		"lmg  %%r6,%%r15,0(%1)\n\t"
-		"br   %%r14"
-#endif
-		: : "r" (r2),
-#ifdef PTR_DEMANGLE
-		    "r" (r1), "r" (r3)
-#else
-		    "a" (env)
-#endif
-		);
-
-  /* Avoid `volatile function does return' warnings.  */
-  for (;;);
-}
diff --git a/sysdeps/s390/s390-64/__longjmp.c b/sysdeps/s390/s390-64/__longjmp.c
new file mode 100644
index 0000000..168ebf5
--- /dev/null
+++ b/sysdeps/s390/s390-64/__longjmp.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+   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 <errno.h>
+#include <sysdep.h>
+#include <setjmp.h>
+#include <bits/setjmp.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Jump to the position specified by ENV, causing the
+   setjmp call there to return VAL, or 1 if VAL is 0.  */
+void
+__longjmp (__jmp_buf env, int val)
+{
+#ifdef PTR_DEMANGLE
+  uintptr_t guard = THREAD_GET_POINTER_GUARD ();
+# ifdef CHECK_SP
+  CHECK_SP (env, guard);
+# endif
+#elif defined CHECK_SP
+  CHECK_SP (env, 0);
+#endif
+  register long int r2 __asm ("%r2") = val == 0 ? 1 : val;
+#ifdef PTR_DEMANGLE
+  register uintptr_t r3 __asm ("%r3") = guard;
+  register void *r1 __asm ("%r1") = (void *) env;
+#endif
+  /* Restore registers and jump back.  */
+  asm volatile ("ld    %%f8,80(%1)\n\t"
+		"ld    %%f9,88(%1)\n\t"
+		"ld    %%f10,96(%1)\n\t"
+		"ld    %%f11,104(%1)\n\t"
+		"ld    %%f12,112(%1)\n\t"
+		"ld    %%f13,120(%1)\n\t"
+		"ld    %%f14,128(%1)\n\t"
+		"ld    %%f15,136(%1)\n\t"
+#ifdef PTR_DEMANGLE
+		"lmg  %%r6,%%r13,0(%1)\n\t"
+		"lmg  %%r4,%%r5,64(%1)\n\t"
+		"xgr  %%r4,%2\n\t"
+		"xgr  %%r5,%2\n\t"
+		"lgr  %%r15,%%r5\n\t"
+		"br   %%r4"
+#else
+		"lmg  %%r6,%%r15,0(%1)\n\t"
+		"br   %%r14"
+#endif
+		: : "r" (r2),
+#ifdef PTR_DEMANGLE
+		    "r" (r1), "r" (r3)
+#else
+		    "a" (env)
+#endif
+		);
+
+  /* Avoid `volatile function does return' warnings.  */
+  for (;;);
+}
diff --git a/sysdeps/s390/s390-64/setjmp-common.S b/sysdeps/s390/s390-64/setjmp-common.S
deleted file mode 100644
index 9cdcae4..0000000
--- a/sysdeps/s390/s390-64/setjmp-common.S
+++ /dev/null
@@ -1,79 +0,0 @@
-/* setjmp for 64 bit S/390, ELF version.
-   Copyright (C) 2001-2014 Free Software Foundation, Inc.
-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
-   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 <sysdep.h>
-#define _ASM
-#define _SETJMP_H
-#include <bits/setjmp.h>
-
-	/* We include the BSD entry points here as well but we make
-	   them weak.  */
-ENTRY (setjmp)
-	.weak C_SYMBOL_NAME (setjmp)
-        lghi   %r3,1                /* Second argument of one.  */
-        j      0f                   /* Branch relativ to __sigsetjmp.  */
-END (setjmp)
-
-	/* Binary compatibility entry point.  */
-ENTRY(_setjmp)
-        .weak  C_SYMBOL_NAME (_setjmp)
-        slgr   %r3,%r3              /* Second argument of zero.  */
-        j      0f                   /* Branch relativ to __sigsetjmp.  */
-END (_setjmp)
-libc_hidden_def (_setjmp)
-
-ENTRY(__setjmp)
-        slgr   %r3,%r3              /* Second argument of zero.  */
-        j      0f                   /* Branch relativ to __sigsetjmp.  */
-END (__setjmp)
-
-ENTRY(__sigsetjmp)
-0:
-#ifdef PTR_MANGLE
-	stmg   %r6,%r13,0(%r2)      /* Store registers in jmp_buf.  */
-	lgr    %r4,%r14
-	lgr    %r5,%r15
-	PTR_MANGLE (%r4, %r1)
-	PTR_MANGLE2 (%r5, %r1)
-	stmg   %r4,%r5,64(%r2)
-#else
-        stmg   %r6,%r15,0(%r2)      /* Store registers in jmp_buf.  */
-#endif
-#ifndef __V1_JMPBUF
-	lghi   %r4,0
-	stg    %r4,144(%r2)         /* Set __flags to 0.  */
-#endif
-	std    %f8,80(%r2)
-	std    %f9,88(%r2)
-	std    %f10,96(%r2)
-	std    %f11,104(%r2)
-	std    %f12,112(%r2)
-	std    %f13,120(%r2)
-	std    %f14,128(%r2)
-	std    %f15,136(%r2)
-#if defined NOT_IN_libc && defined IS_IN_rtld
-	/* In ld.so we never save the signal mask.  */
-	lghi   %r2,0
-	br     %r14
-#elif defined PIC
-        jg     __sigjmp_save@PLT    /* Branch to PLT of __sigsetjmp.  */
-#else
-	jg     __sigjmp_save
-#endif
-END (__sigsetjmp)
diff --git a/sysdeps/s390/s390-64/setjmp.S b/sysdeps/s390/s390-64/setjmp.S
new file mode 100644
index 0000000..7cbb9e8
--- /dev/null
+++ b/sysdeps/s390/s390-64/setjmp.S
@@ -0,0 +1,106 @@
+/* setjmp for 64 bit S/390, ELF version.
+   Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+   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 <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+#include <shlib-compat.h>
+
+#if !defined IS_IN_rtld
+# if defined SHARED &&  SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+	/* we need a unique name in case of symbol versioning.  */
+#  define __sigsetjmp __v1__sigsetjmp
+# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)  */
+#endif /* !defined IS_IN_rtld  */
+
+	/* We include the BSD entry points here as well but we make
+	   them weak.  */
+ENTRY (setjmp)
+	.weak C_SYMBOL_NAME (setjmp)
+        lghi   %r3,1                /* Second argument of one.  */
+        j      .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp.  */
+END (setjmp)
+
+	/* Binary compatibility entry point.  */
+ENTRY(_setjmp)
+        .weak  C_SYMBOL_NAME (_setjmp)
+        slgr   %r3,%r3              /* Second argument of zero.  */
+        j      .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp.  */
+END (_setjmp)
+libc_hidden_def (_setjmp)
+
+ENTRY(__setjmp)
+        slgr   %r3,%r3              /* Second argument of zero.  */
+        j      .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp.  */
+END (__setjmp)
+
+ENTRY(__sigsetjmp)
+.Linternal_sigsetjmp:
+#ifdef PTR_MANGLE
+	stmg   %r6,%r13,0(%r2)      /* Store registers in jmp_buf.  */
+	lgr    %r4,%r14
+	lgr    %r5,%r15
+	PTR_MANGLE (%r4, %r1)
+	PTR_MANGLE2 (%r5, %r1)
+	stmg   %r4,%r5,64(%r2)
+#else
+        stmg   %r6,%r15,0(%r2)      /* Store registers in jmp_buf.  */
+#endif
+	std    %f8,80(%r2)
+	std    %f9,88(%r2)
+	std    %f10,96(%r2)
+	std    %f11,104(%r2)
+	std    %f12,112(%r2)
+	std    %f13,120(%r2)
+	std    %f14,128(%r2)
+	std    %f15,136(%r2)
+#if defined NOT_IN_libc && defined IS_IN_rtld
+	/* In ld.so we never save the signal mask.  */
+	lghi   %r2,0
+	br     %r14
+#elif defined PIC
+        jg     __sigjmp_save@PLT    /* Branch to PLT of __sigsetjmp.  */
+#else
+	jg     __sigjmp_save
+#endif
+END (__sigsetjmp)
+
+#if !defined IS_IN_rtld
+# if defined SHARED &&  SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+/* In glibc release 2.19 new versions of setjmp-functions were introduced,
+   but were reverted before 2.20. Thus both versions are the same function.  */
+
+#  undef __sigsetjmp
+
+weak_alias (setjmp, __v1setjmp);
+weak_alias (setjmp, __v2setjmp);
+versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0);
+compat_symbol (libc, __v2setjmp, setjmp, GLIBC_2_19);
+
+weak_alias (_setjmp, __v1_setjmp);
+weak_alias (_setjmp, __v2_setjmp);
+versioned_symbol (libc, __v1_setjmp, _setjmp, GLIBC_2_0);
+compat_symbol (libc, __v2_setjmp, _setjmp, GLIBC_2_19);
+
+strong_alias (__v1__sigsetjmp, __v2__sigsetjmp);
+versioned_symbol (libc, __v1__sigsetjmp, __sigsetjmp, GLIBC_2_0);
+compat_symbol (libc, __v2__sigsetjmp, __sigsetjmp, GLIBC_2_19);
+# endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)  */
+#endif /* if !defined IS_IN_rtld  */
diff --git a/sysdeps/s390/setjmp.S b/sysdeps/s390/setjmp.S
deleted file mode 100644
index 2ec621a..0000000
--- a/sysdeps/s390/setjmp.S
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Extendible version of setjmp for System z
-   Copyright (C) 2013 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 <libc-symbols.h>
-#include <shlib-compat.h>
-
-versioned_symbol (libc, __v2setjmp, setjmp, GLIBC_2_19)
-versioned_symbol (libc, __v2_setjmp, _setjmp, GLIBC_2_19)
-versioned_symbol (libc, __v2__setjmp, __setjmp, GLIBC_2_19)
-versioned_symbol (libc, __v2__sigsetjmp, __sigsetjmp, GLIBC_2_19)
-#define setjmp __v2setjmp
-#define _setjmp __v2_setjmp
-#define __setjmp __v2__setjmp
-#define __sigsetjmp __v2__sigsetjmp
-#define __sigjmp_save __v2__sigjmp_save
-
-#include "setjmp-common.S"
-
-#undef setjmp
-#undef _setjmp
-#undef __setjmp
-#undef __sigsetjmp
-#undef __sigjmp_save
-libc_hidden_ver (__v2setjmp, setjmp)
-libc_hidden_ver (__v2_setjmp, _setjmp)
-libc_hidden_ver (__v2__setjmp, __setjmp)
-libc_hidden_ver (__v2__sigsetjmp, __sigsetjmp)
-
-#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19)
-compat_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0)
-compat_symbol (libc, __v1_setjmp, _setjmp, GLIBC_2_0)
-compat_symbol (libc, __v1__setjmp, __setjmp, GLIBC_2_0)
-compat_symbol (libc, __v1__sigsetjmp, __sigsetjmp, GLIBC_2_0)
-# define setjmp __v1setjmp
-# define _setjmp __v1_setjmp
-# define __setjmp __v1__setjmp
-# define __sigsetjmp __v1__sigsetjmp
-# define __sigjmp_save __v1__sigjmp_save
-# define __V1_JMPBUF
-
-# include "setjmp-common.S"
-
-# undef setjmp
-# undef _setjmp
-# undef __setjmp
-# undef __sigsetjmp
-# undef __sigjmp_save
-
-#endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19) */
diff --git a/sysdeps/s390/sigjmp.c b/sysdeps/s390/sigjmp.c
deleted file mode 100644
index f7b5a6f..0000000
--- a/sysdeps/s390/sigjmp.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (C) 1992-2013 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 <stddef.h>
-#include <setjmp.h>
-#include <signal.h>
-
-/* This function is called by the `sigsetjmp' macro
-   before doing a `__setjmp' on ENV[0].__jmpbuf.
-   Always return zero.  */
-
-int
-__v2__sigjmp_save (sigjmp_buf env, int savemask)
-{
-  env[0].__mask_was_saved = (savemask &&
-			     __sigprocmask (SIG_BLOCK, (sigset_t *) NULL,
-					    &env[0].__saved_mask) == 0);
-
-  return 0;
-}
diff --git a/sysdeps/s390/v1-longjmp.c b/sysdeps/s390/v1-longjmp.c
deleted file mode 100644
index 82252c9..0000000
--- a/sysdeps/s390/v1-longjmp.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (C) 2013 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/>.
-
-   Versioned copy of sysdeps/generic/longjmp.c modified for extended
-   jmpbuf.  */
-
-#include <shlib-compat.h>
-#include <stddef.h>
-#include <signal.h>
-#include "v1-setjmp.h"
-
-#if !defined NOT_INT_libc && defined SHARED
-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19)
-
-void
-__v1__libc_siglongjmp (__v1__sigjmp_buf env, int val)
-{
-  /* Perform any cleanups needed by the frames being unwound.  */
-  _longjmp_unwind (env, val);
-
-  if (env[0].__mask_was_saved)
-    /* Restore the saved signal mask.  */
-    (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask,
-			  (sigset_t *) NULL);
-
-  /* Call the machine-dependent function to restore machine state.  */
-  __v1__longjmp (env[0].__jmpbuf, val ?: 1);
-}
-
-#  ifndef __v1__longjmp
-strong_alias (__v1__libc_siglongjmp, __v1__libc_longjmp)
-libc_hidden_def (__v1__libc_longjmp)
-weak_alias (__v1__libc_siglongjmp, __v1_longjmp)
-weak_alias (__v1__libc_siglongjmp, __v1longjmp)
-weak_alias (__v1__libc_siglongjmp, __v1siglongjmp)
-
-compat_symbol (libc, __v1_longjmp, _longjmp, GLIBC_2_0);
-compat_symbol (libc, __v1longjmp, longjmp, GLIBC_2_0);
-compat_symbol (libc, __v1siglongjmp, siglongjmp, GLIBC_2_0);
-
-#  endif /* ifndef __v1__longjmp */
-# endif /* SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19) */
-#endif /* if !defined NOT_INT_libc && defined SHARED */
diff --git a/sysdeps/s390/v1-setjmp.h b/sysdeps/s390/v1-setjmp.h
deleted file mode 100644
index a4a6b76..0000000
--- a/sysdeps/s390/v1-setjmp.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (C) 1991-2013 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/>.  */
-
-/*
- *	ISO C99 Standard: 7.13 Nonlocal jumps	<setjmp.h>
- */
-
-#ifndef	_V1_SETJMP_H
-#define	_V1_SETJMP_H	1
-
-#include <features.h>
-
-__BEGIN_DECLS
-
-#define __V1_JMPBUF
-#define _SETJMP_H
-#include <bits/setjmp.h>		/* Get `__jmp_buf'.  */
-
-#ifndef _ASM
-
-#include <bits/sigset.h>		/* Get `__sigset_t'.  */
-
-
-/* Calling environment, plus possibly a saved signal mask.  */
-typedef struct __v1__jmp_buf_tag
-  {
-    /* NOTE: The machine-dependent definitions of `__sigsetjmp'
-       assume that a `jmp_buf' begins with a `__jmp_buf' and that
-       `__mask_was_saved' follows it.  Do not move these members
-       or add others before it.  */
-    __jmp_buf __jmpbuf;		/* Calling environment.  */
-    int __mask_was_saved;	/* Saved the signal mask?  */
-    __sigset_t __saved_mask;	/* Saved signal mask.  */
-  } __v1__jmp_buf[1];
-
-
-/* Store the calling environment in ENV, also saving the signal mask.
-   Return 0.  */
-extern int __v1setjmp (__v1__jmp_buf __env);
-
-/* Store the calling environment in ENV, also saving the
-   signal mask if SAVEMASK is nonzero.  Return 0.
-   This is the internal name for `sigsetjmp'.  */
-extern int __v1__sigsetjmp (struct __v1__jmp_buf_tag __env[1],
-			       int __savemask);
-
-/* Store the calling environment in ENV, not saving the signal mask.
-   Return 0.  */
-extern int __v1_setjmp (struct __v1__jmp_buf_tag __env[1]);
-
-/* Jump to the environment saved in ENV, making the
-   `setjmp' call there return VAL, or 1 if VAL is 0.  */
-extern void __v1longjmp (struct __v1__jmp_buf_tag __env[1], int __val)
-     __attribute__ ((__noreturn__));
-
-/* Same.  Usually `_longjmp' is used with `_setjmp', which does not save
-   the signal mask.  But it is how ENV was saved that determines whether
-   `longjmp' restores the mask; `_longjmp' is just an alias.  */
-extern void __v1_longjmp (struct __v1__jmp_buf_tag __env[1], int __val)
-     __attribute__ ((__noreturn__));
-
-/* Use the same type for `jmp_buf' and `sigjmp_buf'.
-   The `__mask_was_saved' flag determines whether
-   or not `longjmp' will restore the signal mask.  */
-typedef struct __v1__jmp_buf_tag __v1__sigjmp_buf[1];
-
-/* Jump to the environment saved in ENV, making the
-   sigsetjmp call there return VAL, or 1 if VAL is 0.
-   Restore the signal mask if that sigsetjmp call saved it.
-   This is just an alias `longjmp'.  */
-extern void __v1siglongjmp (__v1__sigjmp_buf __env, int __val)
-     __attribute__ ((__noreturn__));
-
-/* Internal machine-dependent function to restore context sans signal mask.  */
-extern void __v1__longjmp (__jmp_buf __env, int __val)
-     __attribute__ ((__noreturn__));
-
-/* Internal function to possibly save the current mask of blocked signals
-   in ENV, and always set the flag saying whether or not it was saved.
-   This is used by the machine-dependent definition of `__sigsetjmp'.
-   Always returns zero, for convenience.  */
-extern int __v1__sigjmp_save (__v1__jmp_buf __env, int __savemask);
-
-extern void _longjmp_unwind (__v1__jmp_buf env, int val);
-
-extern void __v1__libc_siglongjmp (__v1__sigjmp_buf env, int val)
-          __attribute__ ((noreturn));
-
-extern void __v1__libc_longjmp (__v1__sigjmp_buf env, int val)
-     __attribute__ ((noreturn));
-
-libc_hidden_proto (__v1__libc_longjmp)
-libc_hidden_proto (__v1_setjmp)
-libc_hidden_proto (__v1__sigsetjmp)
-#endif /* !_ASM */
-
-#endif /* ifndef _V1_SETJMP_H */
diff --git a/sysdeps/s390/v1-sigjmp.c b/sysdeps/s390/v1-sigjmp.c
deleted file mode 100644
index b624d16..0000000
--- a/sysdeps/s390/v1-sigjmp.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (C) 1992-2013 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/>.
-
-   Copied from setjmp/sigjmp.c for extending jmp_buf.  */
-
-#include <bits/wordsize.h>
-#include <shlib-compat.h>
-
-#if !defined NOT_IN_libc && defined SHARED
-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19)
-#  include <stddef.h>
-#  include <v1-setjmp.h>
-#  include <signal.h>
-
-/* This function is called by the `sigsetjmp' macro
-   before doing a `__setjmp' on ENV[0].__jmpbuf.
-   Always return zero.  */
-
-int
-__v1__sigjmp_save (__v1__sigjmp_buf env, int savemask)
-{
-  env[0].__mask_was_saved = (savemask &&
-			     __sigprocmask (SIG_BLOCK, (sigset_t *) NULL,
-					    &env[0].__saved_mask) == 0);
-
-  return 0;
-}
-
-# endif /* SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19) */
-#endif /* !NOT_IN_libc && SHARED  */
diff --git a/sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S b/sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S
index b43a9e3..a1a9642 100644
--- a/sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S
+++ b/sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S
@@ -211,6 +211,7 @@ ENTRY(__memcpy_niagara2)
 	 */
 	VISEntryHalf
 
+	membar		#Sync
 	alignaddr	%o1, %g0, %g0
 
 	add		%o1, (64 - 1), %o4
diff --git a/sysdeps/sparc/sparc64/strcmp.S b/sysdeps/sparc/sparc64/strcmp.S
index 8925396..f32b0fc 100644
--- a/sysdeps/sparc/sparc64/strcmp.S
+++ b/sysdeps/sparc/sparc64/strcmp.S
@@ -121,6 +121,37 @@ ENTRY(strcmp)
 	movleu	%xcc, -1, %o0
 	srlx	rTMP1, 7, rTMP1
 
+	/* In order not to be influenced by bytes after the zero byte, we
+	 * have to retain only the highest bit in the mask for the comparison
+	 * with rSTRXOR to work properly.
+	 */
+	mov	0, rTMP2
+	andcc	rTMP1, 0x0100, %g0
+
+	movne	%xcc, 8, rTMP2
+	sllx	rTMP1, 63 - 16, %o1
+
+	movrlz	%o1, 16, rTMP2
+	sllx	rTMP1, 63 - 24, %o1
+
+	movrlz	%o1, 24, rTMP2
+	sllx	rTMP1, 63 - 32, %o1
+
+	movrlz	%o1, 32, rTMP2
+	sllx	rTMP1, 63 - 40, %o1
+
+	movrlz	%o1, 40, rTMP2
+	sllx	rTMP1, 63 - 48, %o1
+
+	movrlz	%o1, 48, rTMP2
+	sllx	rTMP1, 63 - 56, %o1
+
+	movrlz	%o1, 56, rTMP2
+
+	srlx	rTMP1, rTMP2, rTMP1
+
+	sllx	rTMP1, rTMP2, rTMP1
+
 	cmp	rTMP1, rSTRXOR
 	retl
 	 movgu	%xcc, 0, %o0
diff --git a/sysdeps/unix/sysv/linux/dl-openat64.c b/sysdeps/unix/sysv/linux/dl-openat64.c
index 9d00b45..5ac16a2 100644
--- a/sysdeps/unix/sysv/linux/dl-openat64.c
+++ b/sysdeps/unix/sysv/linux/dl-openat64.c
@@ -28,7 +28,7 @@ openat64 (dfd, file, oflag)
      const char *file;
      int oflag;
 {
-  assert ((oflag & O_CREAT) == 0);
+  assert (!__OPEN_NEEDS_MODE (oflag));
 
 #ifdef __NR_openat
   return INLINE_SYSCALL (openat, 3, dfd, file, oflag | O_LARGEFILE);
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/open64.c b/sysdeps/unix/sysv/linux/open64.c
index 0d63806..6d91b21 100644
--- a/sysdeps/unix/sysv/linux/open64.c
+++ b/sysdeps/unix/sysv/linux/open64.c
@@ -21,14 +21,14 @@
 #include <stdio.h>
 #include <sysdep-cancel.h>
 
-/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
    a third argument is the file protection.  */
 int
 __libc_open64 (const char *file, int oflag, ...)
 {
   int mode = 0;
 
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/sysdeps/unix/sysv/linux/openat.c b/sysdeps/unix/sysv/linux/openat.c
index 9bb8ace..5a75f52 100644
--- a/sysdeps/unix/sysv/linux/openat.c
+++ b/sysdeps/unix/sysv/linux/openat.c
@@ -148,8 +148,8 @@ OPENAT_NOT_CANCEL (fd, file, oflag, mode)
 
 
 /* Open FILE with access OFLAG.  Interpret relative paths relative to
-   the directory associated with FD.  If OFLAG includes O_CREAT, a
-   third argument is the file protection.  */
+   the directory associated with FD.  If OFLAG includes O_CREAT or
+   O_TMPFILE, a fourth argument is the file protection.  */
 int
 __OPENAT (fd, file, oflag)
      int fd;
@@ -157,7 +157,7 @@ __OPENAT (fd, file, oflag)
      int oflag;
 {
   mode_t mode = 0;
-  if (oflag & O_CREAT)
+  if (__OPEN_NEEDS_MODE (oflag))
     {
       va_list arg;
       va_start (arg, oflag);
diff --git a/sysdeps/unix/sysv/linux/s390/Makefile b/sysdeps/unix/sysv/linux/s390/Makefile
index f91179d..45b1922 100644
--- a/sysdeps/unix/sysv/linux/s390/Makefile
+++ b/sysdeps/unix/sysv/linux/s390/Makefile
@@ -16,9 +16,3 @@ endif
 ifeq ($(subdir),elf)
 sysdep_routines += dl-vdso
 endif
-
-ifeq ($(subdir),debug)
-ifeq (yes,$(build-shared))
-sysdep_routines += v1-longjmp_chk
-endif
-endif
diff --git a/sysdeps/unix/sysv/linux/s390/getcontext.S b/sysdeps/unix/sysv/linux/s390/getcontext.S
deleted file mode 100644
index 5edbf95..0000000
--- a/sysdeps/unix/sysv/linux/s390/getcontext.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Extendible version of getcontext for System z
-   Copyright (C) 2013 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 <libc-symbols.h>
-#include <shlib-compat.h>
-
-versioned_symbol (libc, __v2getcontext, getcontext, GLIBC_2_19)
-#define __getcontext __v2getcontext
-
-#include "getcontext-common.S"
-
-#undef __getcontext
-
-libc_hidden_ver (__v2getcontext, getcontext)
-
-#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_19)
-# define __V1_UCONTEXT
-compat_symbol (libc, __v1getcontext, getcontext, GLIBC_2_1)
-# define __getcontext __v1getcontext
-# include "getcontext-common.S"
-# undef __getcontext
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/s390/longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/longjmp_chk.c
index 10f542d..02c96c2 100644
--- a/sysdeps/unix/sysv/linux/s390/longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/s390/longjmp_chk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -15,30 +15,34 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.
 
-   This is a copy of debug/longjmp_chk.c extended for symbol
-   versioning.  */
+   Versioned copy of debug/longjmp_chk.c modified for versioning
+   the reverted jmpbuf extension.  */
 
 #include <shlib-compat.h>
-#include <setjmp.h>
 
-/* This place is the only user of these functions.  */
-extern void ____v2__longjmp_chk (__jmp_buf __env, int __val)
+#if !defined NOT_IN_libc && defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+/* this is a copy from debug/longjmp_chk.c because we need an unique name
+   for __longjmp_chk, but it is already named via a define
+   for __libc_siglongjmp in debug/longjmp_chk.c.  */
+# include <setjmp.h>
+
+// XXX Should move to include/setjmp.h
+extern void ____longjmp_chk (__jmp_buf __env, int __val)
      __attribute__ ((__noreturn__));
 
-#if defined NOT_IN_libc
+# define __longjmp ____longjmp_chk
+# define __libc_siglongjmp __v1__longjmp_chk
 
-# define __v2__longjmp ____longjmp_chk
-# define __v2__libc_siglongjmp __longjmp_chk
+# include <setjmp/longjmp.c>
 
-# include <longjmp.c>
+/* In glibc release 2.19 a new versions of __longjmp_chk was introduced,
+   but was reverted before 2.20. Thus both versions are the same function.  */
+strong_alias (__v1__longjmp_chk, __v2__longjmp_chk);
+versioned_symbol (libc, __v1__longjmp_chk, __longjmp_chk, GLIBC_2_11);
+compat_symbol (libc, __v2__longjmp_chk, __longjmp_chk, GLIBC_2_19);
 
 #else
 
-# define __v2__longjmp ____v2__longjmp_chk
-# define __v2__libc_siglongjmp __v2__libc_siglongjmp_chk
-
-# include <longjmp.c>
-
-versioned_symbol (libc, __v2__libc_siglongjmp_chk, __longjmp_chk, GLIBC_2_19);
+# include <debug/longjmp_chk.c>
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/s390/rtld-getcontext.S b/sysdeps/unix/sysv/linux/s390/rtld-getcontext.S
deleted file mode 100644
index 653f2b6..0000000
--- a/sysdeps/unix/sysv/linux/s390/rtld-getcontext.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2013 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/>.  */
-
-/* Build a non-versioned object for rtld-*.  */
-#include "getcontext-common.S"
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
index a1b7a6a..e74f335 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
@@ -26,8 +26,8 @@
 #include <stdint.h>
 #include <signal.h>
 #include <sys/syscall.h>
-#include <libc-symbols.h>
-#include <shlib-compat.h>
+
+#define __longjmp ____longjmp_chk
 
 #define CHECK_SP(env, guard) \
   do									\
@@ -51,22 +51,4 @@
 	}								\
     } while (0)
 
-
-#if defined NOT_IN_libc
-/* Build a non-versioned object for rtld-*.  */
-# define __longjmp ____longjmp_chk
-# include "__longjmp-common.c"
-
-#else /* !NOT_IN_libc */
-# define __longjmp  ____v2__longjmp_chk
-# include "__longjmp-common.c"
-
-# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_11, GLIBC_2_19)
-#  undef __longjmp
-#  define __V1_JMPBUF
-#  define __longjmp  ____v1__longjmp_chk
-#  include "__longjmp-common.c"
-#  undef __longjmp
-
-# endif
-#endif /* !NOT_IN_libc */
+#include "__longjmp.c"
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
index 83cf0d8..67ea206 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
@@ -17,6 +17,14 @@
 
 #include <sysdep.h>
 
+/* We do not want .eh_frame info so that __makecontext_ret stops unwinding
+   if backtrace was called within a context created by makecontext. (There
+   is also no .eh_frame info for _start or thread_start.)  */
+#undef cfi_startproc
+#define cfi_startproc
+#undef cfi_endproc
+#define cfi_endproc
+
 ENTRY(__makecontext_ret)
 	basr  %r14,%r7
 	ltr   %r8,%r8			/* Check whether uc_link is 0.  */
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/getcontext-common.S b/sysdeps/unix/sysv/linux/s390/s390-32/getcontext-common.S
deleted file mode 100644
index 4992030..0000000
--- a/sysdeps/unix/sysv/linux/s390/s390-32/getcontext-common.S
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
-
-   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 <sysdep.h>
-#include <features.h>
-
-#include "rtld-global-offsets.h"
-#include "ucontext_i.h"
-
-/*  __getcontext (const ucontext_t *ucp)
-
-  Saves the machine context in UCP such that when it is activated,
-  it appears as if __getcontext() returned again.
-
-  This implementation is intended to be used for *synchronous* context
-  switches only.  Therefore, it does not have to save anything
-  other than the PRESERVED state.  */
-
-ENTRY(__getcontext)
-	lr      %r1,%r2
-
-	/* rt_sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask, sigsetsize).  */
-	la      %r2,SIG_BLOCK
-	slr	%r3,%r3
-	la      %r4,SC_MASK(%r1)
-	lhi	%r5,_NSIG8
-	svc	SYS_ify(rt_sigprocmask)
-
-	/* Store fpu context.  */
-	stfpc   SC_FPC(%r1)
-	std     %f0,SC_FPRS(%r1)
-	std     %f1,SC_FPRS+8(%r1)
-	std     %f2,SC_FPRS+16(%r1)
-	std     %f3,SC_FPRS+24(%r1)
-	std     %f4,SC_FPRS+32(%r1)
-	std     %f5,SC_FPRS+40(%r1)
-	std     %f6,SC_FPRS+48(%r1)
-	std     %f7,SC_FPRS+56(%r1)
-	std     %f8,SC_FPRS+64(%r1)
-	std     %f9,SC_FPRS+72(%r1)
-	std     %f10,SC_FPRS+80(%r1)
-	std     %f11,SC_FPRS+88(%r1)
-	std     %f12,SC_FPRS+96(%r1)
-	std     %f13,SC_FPRS+104(%r1)
-	std     %f14,SC_FPRS+112(%r1)
-	std     %f15,SC_FPRS+120(%r1)
-
-	lhi	%r2,0
-#ifndef __V1_UCONTEXT
-	bras	%r3,0f
-# ifdef IS_IN_rtld
-  /* Within ld.so we can do slightly better by addressing dl_hwap
-     relative to GOT start.  */
-1:	.long	_GLOBAL_OFFSET_TABLE_ - 1b
-	.long	C_SYMBOL_NAME(_rtld_global_ro)@GOTOFF
-0:	l	%r4,0(%r3)
-	la	%r4,0(%r3,%r4)
-	l	%r5,4(%r3)
-	/* _dl_hwcap is 64 bit and we need the lower 32.  */
-	l	%r3,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(%r4,%r5)
-# elif PIC
-1:	.long	_GLOBAL_OFFSET_TABLE_ - 1b
-	.long	C_SYMBOL_NAME(_rtld_global_ro)@GOT
-0:	l	%r4,0(%r3)
-	la	%r4,0(%r3,%r4)  /* GOT pointer -> r4 */
-	l	%r5,4(%r3)      /* GOT offset -> r5 */
-	l	%r5,0(%r4,%r5)  /* GOT slot -> r5 */
-	l	%r3,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(%r5)
-# else
-	.long	C_SYMBOL_NAME(_dl_hwcap)
-0:	l	%r3,0(%r3)
-	l	%r3,0(%r3)
-# endif
-	tml	%r3,512 /* HWCAP_S390_HIGH_GPRS */
-	jz	2f
-	/* highgprs implies zarch so stmh/oill is ok here.  */
-	.machine "z900"
-	.machinemode "zarch_nohighgprs"
-	stmh	%r0,%r15,SC_HIGHGPRS(%r1)
-	oill	%r2,1 /* UCONTEXT_UC_FLAGS_HIGH_GPRS */
-#endif
-2:	st	%r2,SC_FLGS(%r1)
-
-	/* Set __getcontext return value to 0.  */
-	slr     %r2,%r2
-
-	/* Store access registers.  */
-	stam    %a0,%a15,SC_ACRS(%r1)
-
-	/* Store general purpose registers.  */
-	stm     %r0,%r15,SC_GPRS(%r1)
-
-	/* Return.  */
-	br	%r14
-END(__getcontext)
-
-weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S
new file mode 100644
index 0000000..f35bc5c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S
@@ -0,0 +1,86 @@
+/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+   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 <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+#include <shlib-compat.h>
+
+/*  __getcontext (const ucontext_t *ucp)
+
+  Saves the machine context in UCP such that when it is activated,
+  it appears as if __getcontext() returned again.
+
+  This implementation is intended to be used for *synchronous* context
+  switches only.  Therefore, it does not have to save anything
+  other than the PRESERVED state.  */
+
+ENTRY(__getcontext)
+	lr      %r1,%r2
+
+	/* rt_sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask, sigsetsize).  */
+	la      %r2,SIG_BLOCK
+	slr	%r3,%r3
+	la	%r4,SC_MASK(%r1)
+	lhi	%r5,_NSIG8
+	svc	SYS_ify(rt_sigprocmask)
+
+	/* Store fpu context.  */
+	stfpc   SC_FPC(%r1)
+	std     %f0,SC_FPRS(%r1)
+	std     %f1,SC_FPRS+8(%r1)
+	std     %f2,SC_FPRS+16(%r1)
+	std     %f3,SC_FPRS+24(%r1)
+	std     %f4,SC_FPRS+32(%r1)
+	std     %f5,SC_FPRS+40(%r1)
+	std     %f6,SC_FPRS+48(%r1)
+	std     %f7,SC_FPRS+56(%r1)
+	std     %f8,SC_FPRS+64(%r1)
+	std     %f9,SC_FPRS+72(%r1)
+	std     %f10,SC_FPRS+80(%r1)
+	std     %f11,SC_FPRS+88(%r1)
+	std     %f12,SC_FPRS+96(%r1)
+	std     %f13,SC_FPRS+104(%r1)
+	std     %f14,SC_FPRS+112(%r1)
+	std     %f15,SC_FPRS+120(%r1)
+
+	/* Set __getcontext return value to 0.  */
+	slr     %r2,%r2
+
+	/* Store access registers.  */
+	stam    %a0,%a15,SC_ACRS(%r1)
+
+	/* Store general purpose registers.  */
+	stm     %r0,%r15,SC_GPRS(%r1)
+
+	/* Return.  */
+	br	%r14
+END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+/* In glibc release 2.19 a new version of getcontext was introduced,
+   but was reverted before 2.20. Thus both versions are the same function.  */
+weak_alias (__getcontext, __v1__getcontext)
+weak_alias (__getcontext, __v2__getcontext)
+versioned_symbol (libc, __v1__getcontext, getcontext, GLIBC_2_1)
+compat_symbol (libc, __v2__getcontext, getcontext, GLIBC_2_19)
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
index 03f2e83..0194f0b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
@@ -1777,7 +1777,6 @@ GLIBC_2.18
 GLIBC_2.19
  GLIBC_2.19 A
  __longjmp_chk F
- __setjmp F
  __sigsetjmp F
  _longjmp F
  _setjmp F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
index fbe8b77..b263773 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
@@ -34,7 +34,7 @@ ENTRY(__setcontext)
 	lr	%r1,%r2
 
 	/* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize).  */
-	la      %r2,SIG_BLOCK
+	la      %r2,SIG_SETMASK
 	la	%r3,SC_MASK(%r1)
 	slr	%r4,%r4
 	lhi	%r5,_NSIG8
@@ -62,16 +62,8 @@ ENTRY(__setcontext)
 	/* Don't touch %a0, used for thread purposes.  */
 	lam	%a1,%a15,SC_ACRS+4(%r1)
 
-	/* Restore the upper halfs if available.  */
-	l	%r2,SC_FLGS(%r1)
-	tml	%r2,1   /* UCONTEXT_UC_FLAGS_HIGH_GPRS */
-	jz	0f
-	.machine	"z900"
-	.machinemode	"zarch_nohighgprs"
-	lmh	%r0,%r15,SC_HIGHGPRS(%r1)
-
 	/* Load general purpose registers.  */
-0:	lm	%r0,%r15,SC_GPRS(%r1)
+	lm	%r0,%r15,SC_GPRS(%r1)
 
 	/* Return.  */
 	br	%r14
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
index 41ede4b..8f9cfd8 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
@@ -24,7 +24,7 @@
 /*  __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
 
   Saves the machine context in oucp such that when it is activated,
-  it appears as if __swapcontextt() returned again, restores the
+  it appears as if __swapcontext() returned again, restores the
   machine context in ucp and thereby resumes execution in that
   context.
 
@@ -39,13 +39,6 @@ ENTRY(__swapcontext)
 	lr	%r1,%r2
 	lr      %r0,%r3
 
-	/* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask).  */
-	la      %r2,SIG_BLOCK
-	slr	%r3,%r3
-	la	%r4,SC_MASK(%r1)
-	lhi	%r5,_NSIG8
-	svc	SYS_ify(rt_sigprocmask)
-
 	/* Store fpu context.  */
 	stfpc   SC_FPC(%r1)
 	std     %f0,SC_FPRS(%r1)
@@ -65,32 +58,21 @@ ENTRY(__swapcontext)
 	std     %f14,SC_FPRS+112(%r1)
 	std     %f15,SC_FPRS+120(%r1)
 
-	/* Store access registers.  */
-	stam    %a0,%a15,SC_ACRS(%r1)
-
 	/* Set __swapcontext return value to 0.  */
 	slr     %r2,%r2
 
+	/* Store access registers.  */
+	stam    %a0,%a15,SC_ACRS(%r1)
+
 	/* Store general purpose registers.  */
 	stm     %r0,%r15,SC_GPRS(%r1)
 
-	/* Copy uc_flags into the new ucontext_t.  */
+	/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask,
+	   sigsetsize).  */
+	la      %r2,SIG_SETMASK
 	lr	%r5,%r0
-	l	%r2,SC_FLGS(%r5)
-	st	%r2,SC_FLGS(%r1)
-
-	/* Save/restore the upper halfs if necessary.  */
-	tml	%r2,1   /* UCONTEXT_UC_FLAGS_HIGH_GPRS */
-	jz	0f
-	.machine	"z900"
-	.machinemode	"zarch_nohighgprs"
-	stmh	%r0,%r15,SC_HIGHGPRS(%r1)
-	lmh	%r0,%r15,SC_HIGHGPRS(%r5)
-
-	/* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize).  */
-0:	la      %r2,SIG_BLOCK
-	la      %r3,SC_MASK(%r5)
-	slr	%r4,%r4
+	la	%r3,SC_MASK(%r5)
+	la	%r4,SC_MASK(%r1)
 	lhi	%r5,_NSIG8
 	svc	SYS_ify(rt_sigprocmask)
 
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/ucontext_i.sym b/sysdeps/unix/sysv/linux/s390/s390-32/ucontext_i.sym
deleted file mode 100644
index 705c7ab..0000000
--- a/sysdeps/unix/sysv/linux/s390/s390-32/ucontext_i.sym
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stddef.h>
-#include <signal.h>
-#include <sys/ucontext.h>
-
---
-
-SIG_BLOCK
-SIG_UNBLOCK
-SIG_SETMASK
-
-_NSIG8          (_NSIG / 8)
-
-#define ucontext(member)	offsetof (ucontext_t, member)
-#define mcontext(member)	ucontext (uc_mcontext.member)
-
-SC_FLGS		ucontext (uc_flags)
-SC_LINK		ucontext (uc_link)
-SC_STCK		ucontext (uc_stack.ss_sp)
-SC_STSZ		ucontext (uc_stack.ss_size)
-SC_PSW		mcontext (psw)
-SC_GPRS		mcontext (gregs)
-SC_ACRS		mcontext (aregs)
-SC_FPC		mcontext (fpregs.fpc)
-SC_FPRS		mcontext (fpregs.fprs)
-SC_MASK		ucontext (uc_sigmask)
-SC_HIGHGPRS	ucontext (uc_high_gprs)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
index bc27b08..a3b1375 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
@@ -26,8 +26,8 @@
 #include <stdint.h>
 #include <signal.h>
 #include <sys/syscall.h>
-#include <libc-symbols.h>
-#include <shlib-compat.h>
+
+#define __longjmp ____longjmp_chk
 
 #define CHECK_SP(env, guard) \
   do									\
@@ -51,23 +51,4 @@
 	}								\
     } while (0)
 
-
-#if defined NOT_IN_libc
-/* Build a non-versioned object for rtld-*.  */
-# define __longjmp ____longjmp_chk
-# include "__longjmp-common.c"
-
-#else /* !NOT_IN_libc */
-# define __longjmp  ____v2__longjmp_chk
-# include "__longjmp-common.c"
-# undef __longjmp
-
-# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_11, GLIBC_2_19)
-#  undef __longjmp
-#  define __V1_JMPBUF
-#  define __longjmp  ____v1__longjmp_chk
-#  include "__longjmp-common.c"
-#  undef __longjmp
-
-# endif
-#endif /* !NOT_IN_libc */
+#include "__longjmp.c"
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
index 71ecbab..a2bf3ca 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
@@ -17,6 +17,14 @@
 
 #include <sysdep.h>
 
+/* We do not want .eh_frame info so that __makecontext_ret stops unwinding
+   if backtrace was called within a context created by makecontext. (There
+   is also no .eh_frame info for _start or thread_start.)  */
+#undef cfi_startproc
+#define cfi_startproc
+#undef cfi_endproc
+#define cfi_endproc
+
 ENTRY(__makecontext_ret)
 	basr	%r14,%r7
 	ltgr	%r8,%r8			/* Check whether uc_link is 0.  */
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/getcontext-common.S b/sysdeps/unix/sysv/linux/s390/s390-64/getcontext-common.S
deleted file mode 100644
index 3e61e30..0000000
--- a/sysdeps/unix/sysv/linux/s390/s390-64/getcontext-common.S
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
-
-   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 <sysdep.h>
-#include <features.h>
-
-#include "ucontext_i.h"
-
-/*  __getcontext (const ucontext_t *ucp)
-
-  Saves the machine context in UCP such that when it is activated,
-  it appears as if __getcontext() returned again.
-
-  This implementation is intended to be used for *synchronous* context
-  switches only.  Therefore, it does not have to save anything
-  other than the PRESERVED state.  */
-
-ENTRY(__getcontext)
-	lgr     %r1,%r2
-
-	/* rt_sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask, sigsetsize).  */
-	la      %r2,SIG_BLOCK
-	slgr	%r3,%r3
-	la	%r4,SC_MASK(%r1)
-	lghi	%r5,_NSIG8
-	svc	SYS_ify(rt_sigprocmask)
-
-	/* Store fpu context.  */
-	stfpc   SC_FPC(%r1)
-	std     %f0,SC_FPRS(%r1)
-	std     %f1,SC_FPRS+8(%r1)
-	std     %f2,SC_FPRS+16(%r1)
-	std     %f3,SC_FPRS+24(%r1)
-	std     %f4,SC_FPRS+32(%r1)
-	std     %f5,SC_FPRS+40(%r1)
-	std     %f6,SC_FPRS+48(%r1)
-	std     %f7,SC_FPRS+56(%r1)
-	std     %f8,SC_FPRS+64(%r1)
-	std     %f9,SC_FPRS+72(%r1)
-	std     %f10,SC_FPRS+80(%r1)
-	std     %f11,SC_FPRS+88(%r1)
-	std     %f12,SC_FPRS+96(%r1)
-	std     %f13,SC_FPRS+104(%r1)
-	std     %f14,SC_FPRS+112(%r1)
-	std     %f15,SC_FPRS+120(%r1)
-
-	/* Set __getcontext return value to 0.  */
-	slgr    %r2,%r2
-
-	/* Store the version number into the uc_flags field.  So far
-	   we do not make use of the reserved bytes so we store a zero.  */
-	stg	%r2,SC_FLGS(%r1)
-
-	/* Store access registers.  */
-	stam    %a0,%a15,SC_ACRS(%r1)
-
-	/* Store general purpose registers.  */
-	stmg    %r0,%r15,SC_GPRS(%r1)
-
-	/* Return.  */
-	br	%r14
-END(__getcontext)
-
-weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S
new file mode 100644
index 0000000..26a1c51
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S
@@ -0,0 +1,86 @@
+/* Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+   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 <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+#include <shlib-compat.h>
+
+/*  __getcontext (const ucontext_t *ucp)
+
+  Saves the machine context in UCP such that when it is activated,
+  it appears as if __getcontext() returned again.
+
+  This implementation is intended to be used for *synchronous* context
+  switches only.  Therefore, it does not have to save anything
+  other than the PRESERVED state.  */
+
+ENTRY(__getcontext)
+	lgr     %r1,%r2
+
+	/* rt_sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask, sigsetsize).  */
+	la      %r2,SIG_BLOCK
+	slgr	%r3,%r3
+	la	%r4,SC_MASK(%r1)
+	lghi	%r5,_NSIG8
+	svc	SYS_ify(rt_sigprocmask)
+
+	/* Store fpu context.  */
+	stfpc   SC_FPC(%r1)
+	std     %f0,SC_FPRS(%r1)
+	std     %f1,SC_FPRS+8(%r1)
+	std     %f2,SC_FPRS+16(%r1)
+	std     %f3,SC_FPRS+24(%r1)
+	std     %f4,SC_FPRS+32(%r1)
+	std     %f5,SC_FPRS+40(%r1)
+	std     %f6,SC_FPRS+48(%r1)
+	std     %f7,SC_FPRS+56(%r1)
+	std     %f8,SC_FPRS+64(%r1)
+	std     %f9,SC_FPRS+72(%r1)
+	std     %f10,SC_FPRS+80(%r1)
+	std     %f11,SC_FPRS+88(%r1)
+	std     %f12,SC_FPRS+96(%r1)
+	std     %f13,SC_FPRS+104(%r1)
+	std     %f14,SC_FPRS+112(%r1)
+	std     %f15,SC_FPRS+120(%r1)
+
+	/* Set __getcontext return value to 0.  */
+	slgr    %r2,%r2
+
+	/* Store access registers.  */
+	stam    %a0,%a15,SC_ACRS(%r1)
+
+	/* Store general purpose registers.  */
+	stmg    %r0,%r15,SC_GPRS(%r1)
+
+	/* Return.  */
+	br	%r14
+END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
+/* In glibc release 2.19 a new version of getcontext was introduced,
+   but was reverted before 2.20. Thus both versions are the same function.  */
+weak_alias (__getcontext, __v1__getcontext)
+weak_alias (__getcontext, __v2__getcontext)
+versioned_symbol (libc, __v1__getcontext, getcontext, GLIBC_2_1)
+compat_symbol (libc, __v2__getcontext, getcontext, GLIBC_2_19)
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
index 4576fc8..807f702 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
@@ -98,7 +98,6 @@ GLIBC_2.18
 GLIBC_2.19
  GLIBC_2.19 A
  __longjmp_chk F
- __setjmp F
  __sigsetjmp F
  _longjmp F
  _setjmp F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S
index 83df5ce..1464e6a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S
@@ -34,7 +34,7 @@ ENTRY(__setcontext)
 	lgr	%r1,%r2
 
 	/* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL).  */
-	la      %r2,SIG_BLOCK
+	la      %r2,SIG_SETMASK
 	la	%r3,SC_MASK(%r1)
 	slgr	%r4,%r4
 	lghi	%r5,_NSIG8
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
index ac74b6b..8346fd5 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
@@ -24,7 +24,7 @@
 /*  __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
 
   Saves the machine context in oucp such that when it is activated,
-  it appears as if __swapcontextt() returned again, restores the
+  it appears as if __swapcontext() returned again, restores the
   machine context in ucp and thereby resumes execution in that
   context.
 
@@ -39,13 +39,6 @@ ENTRY(__swapcontext)
 	lgr	%r1,%r2
 	lgr     %r0,%r3
 
-	/* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask).  */
-	la      %r2,SIG_BLOCK
-	slgr	%r3,%r3
-	la	%r4,SC_MASK(%r1)
-	lghi	%r5,_NSIG8
-	svc	SYS_ify(rt_sigprocmask)
-
 	/* Store fpu context.  */
 	stfpc   SC_FPC(%r1)
 	std     %f0,SC_FPRS(%r1)
@@ -65,24 +58,21 @@ ENTRY(__swapcontext)
 	std     %f14,SC_FPRS+112(%r1)
 	std     %f15,SC_FPRS+120(%r1)
 
+	/* Set __swapcontext return value to 0.  */
+	slgr     %r2,%r2
+
 	/* Store access registers.  */
 	stam    %a0,%a15,SC_ACRS(%r1)
 
-	/* Set __swapcontext return value to 0.  */
-	slgr	%r2,%r2
-
 	/* Store general purpose registers.  */
 	stmg    %r0,%r15,SC_GPRS(%r1)
 
-	/* Copy uc_flags into the new ucontext_t.  */
+	/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask,
+	   sigsetsize).  */
+	la      %r2,SIG_SETMASK
 	lgr	%r5,%r0
-	lg	%r2,SC_FLGS(%r5)
-	stg	%r2,SC_FLGS(%r1)
-
-	/* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize).  */
-	la      %r2,SIG_BLOCK
 	la	%r3,SC_MASK(%r5)
-	slgr	%r4,%r4
+	la	%r4,SC_MASK(%r1)
 	lghi	%r5,_NSIG8
 	svc	SYS_ify(rt_sigprocmask)
 
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/ucontext_i.sym b/sysdeps/unix/sysv/linux/s390/s390-64/ucontext_i.sym
deleted file mode 100644
index 6cc9f19..0000000
--- a/sysdeps/unix/sysv/linux/s390/s390-64/ucontext_i.sym
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <stddef.h>
-#include <signal.h>
-#include <sys/ucontext.h>
-
---
-
-SIG_BLOCK
-SIG_UNBLOCK
-SIG_SETMASK
-
-_NSIG8          (_NSIG / 8)
-
-#define ucontext(member)	offsetof (ucontext_t, member)
-#define mcontext(member)	ucontext (uc_mcontext.member)
-
-SC_FLGS		ucontext (uc_flags)
-SC_LINK		ucontext (uc_link)
-SC_STCK		ucontext (uc_stack.ss_sp)
-SC_STSZ		ucontext (uc_stack.ss_size)
-SC_PSW		mcontext (psw)
-SC_GPRS		mcontext (gregs)
-SC_ACRS		mcontext (aregs)
-SC_FPC		mcontext (fpregs.fpc)
-SC_FPRS		mcontext (fpregs.fprs)
-SC_MASK		ucontext (uc_sigmask)
diff --git a/sysdeps/unix/sysv/linux/s390/sys/ucontext.h b/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
index f04bf84..d528cb1 100644
--- a/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
+++ b/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
@@ -64,15 +64,6 @@ typedef struct
     fpreg_t fprs[16];
   } fpregset_t;
 
-/* Bit is set if the uc_high_gprs field contains the upper halfs of
-   the 64 bit general purpose registers.  Since the uc_high_gprs field
-   is only available in the 32 bit version of ucontext_t it will never
-   be set for 64 bit.  */
-#define UCONTEXT_UC_FLAGS_HIGH_GPRS (1UL << 0)
-
-/* A new uc_flags constant will be defined when actually making use of
-   the reserved space: UCONTEXT_UCFLAGS_RESERVED (1UL << 1).  */
-
 /* Context to describe whole processor state.  */
 typedef struct
   {
@@ -90,10 +81,6 @@ struct ucontext
     stack_t uc_stack;
     mcontext_t uc_mcontext;
     __sigset_t uc_sigmask;
-#ifndef __s390x__
-    unsigned long uc_high_gprs[16];
-#endif
-    char __reserved[512];
   };
 
 
diff --git a/sysdeps/unix/sysv/linux/s390/ucontext_i.sym b/sysdeps/unix/sysv/linux/s390/ucontext_i.sym
new file mode 100644
index 0000000..6cc9f19
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/ucontext_i.sym
@@ -0,0 +1,25 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_UNBLOCK
+SIG_SETMASK
+
+_NSIG8          (_NSIG / 8)
+
+#define ucontext(member)	offsetof (ucontext_t, member)
+#define mcontext(member)	ucontext (uc_mcontext.member)
+
+SC_FLGS		ucontext (uc_flags)
+SC_LINK		ucontext (uc_link)
+SC_STCK		ucontext (uc_stack.ss_sp)
+SC_STSZ		ucontext (uc_stack.ss_size)
+SC_PSW		mcontext (psw)
+SC_GPRS		mcontext (gregs)
+SC_ACRS		mcontext (aregs)
+SC_FPC		mcontext (fpregs.fpc)
+SC_FPRS		mcontext (fpregs.fprs)
+SC_MASK		ucontext (uc_sigmask)
diff --git a/sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c
deleted file mode 100644
index bd80acf..0000000
--- a/sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (C) 2013 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 went into a separate source file since we would otherwise be
-   needed to include two different versions of setjmp.h into the same
-   file.  */
-
-#include <shlib-compat.h>
-
-#if !defined NOT_IN_libc && defined SHARED
-# if SHLIB_COMPAT (libc, GLIBC_2_11, GLIBC_2_19)
-
-#  define __v1__longjmp ____v1__longjmp_chk
-#  define __v1__libc_siglongjmp __v1__libc_siglongjmp_chk
-
-#  include <v1-longjmp.c>
-
-compat_symbol (libc, __v1__libc_siglongjmp_chk, __longjmp_chk, GLIBC_2_11);
-
-# endif
-#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/eventfd.h b/sysdeps/unix/sysv/linux/sparc/bits/eventfd.h
index c81ddff..4d3ae3b 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/eventfd.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/eventfd.h
@@ -22,6 +22,8 @@
 /* Flags for eventfd.  */
 enum
   {
+    EFD_SEMAPHORE = 0x000001,
+#define EFD_SEMAPHORE EFD_SEMAPHORE
     EFD_CLOEXEC = 0x400000,
 #define EFD_CLOEXEC EFD_CLOEXEC
     EFD_NONBLOCK = 0x004000
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/resource.h b/sysdeps/unix/sysv/linux/sparc/bits/resource.h
index aa201fe..518264f 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/resource.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/resource.h
@@ -252,3 +252,30 @@ enum __priority_which
   PRIO_USER = 2			/* WHO is a user ID.  */
 #define PRIO_USER PRIO_USER
 };
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+/* Modify and return resource limits of a process atomically.  */
+# ifndef __USE_FILE_OFFSET64
+extern int prlimit (__pid_t __pid, enum __rlimit_resource __resource,
+		    const struct rlimit *__new_limit,
+		    struct rlimit *__old_limit) __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (prlimit, (__pid_t __pid,
+				     enum __rlimit_resource __resource,
+				     const struct rlimit *__new_limit,
+				     struct rlimit *__old_limit), prlimit64);
+#  else
+#   define prlimit prlimit64
+#  endif
+# endif
+# ifdef __USE_LARGEFILE64
+extern int prlimit64 (__pid_t __pid, enum __rlimit_resource __resource,
+		      const struct rlimit64 *__new_limit,
+		      struct rlimit64 *__old_limit) __THROW;
+# endif
+#endif
+
+__END_DECLS
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index 207b6c0..25c112f 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -8445,9 +8445,14 @@ double: 1
 float: 2
 idouble: 1
 ifloat: 2
+Test "Real part of: ctan (0xcp-4 + 0x1.4p+0 i)":
+float: 1
+ifloat: 1
 Test "Imaginary part of: ctan (0xcp-4 + 0x1.4p+0 i)":
 double: 1
+float: 1
 idouble: 1
+ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "Real part of: ctan (0xf.ffffffffffff8p+1020 + 0x1p+0 i)":
@@ -8766,9 +8771,14 @@ double: 1
 float: 2
 idouble: 1
 ifloat: 2
+Test "Real part of: ctan_tonearest (0xcp-4 + 0x1.4p+0 i)":
+float: 1
+ifloat: 1
 Test "Imaginary part of: ctan_tonearest (0xcp-4 + 0x1.4p+0 i)":
 double: 1
+float: 1
 idouble: 1
+ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "Real part of: ctan_tonearest (0xf.ffffffffffff8p+1020 + 0x1p+0 i)":
@@ -9289,9 +9299,9 @@ ildouble: 1
 ldouble: 1
 Test "Real part of: ctanh (-0x2p+0 - 0x3p+0 i)":
 double: 1
-float: 1
+float: 2
 idouble: 1
-ifloat: 1
+ifloat: 2
 ildouble: 1
 ldouble: 1
 Test "Imaginary part of: ctanh (-0x2p+0 - 0x3p+0 i)":
@@ -9647,9 +9657,9 @@ ildouble: 1
 ldouble: 1
 Test "Real part of: ctanh_tonearest (-0x2p+0 - 0x3p+0 i)":
 double: 1
-float: 1
+float: 2
 idouble: 1
-ifloat: 1
+ifloat: 2
 ildouble: 1
 ldouble: 1
 Test "Imaginary part of: ctanh_tonearest (-0x2p+0 - 0x3p+0 i)":
@@ -9815,7 +9825,9 @@ float: 1
 ifloat: 1
 Test "Real part of: ctanh_towardzero (-0x2p+0 - 0x3p+0 i)":
 double: 2
+float: 1
 idouble: 2
+ifloat: 1
 Test "Imaginary part of: ctanh_towardzero (-0x2p+0 - 0x3p+0 i)":
 double: 1
 float: 1
@@ -10089,9 +10101,9 @@ ildouble: 1
 ldouble: 1
 Test "Real part of: ctanh_upward (0x1p+0 + 0x8p+124 i)":
 double: 1
-float: 1
+float: 2
 idouble: 1
-ifloat: 1
+ifloat: 2
 Test "Imaginary part of: ctanh_upward (0x1p+0 + 0x8p+124 i)":
 double: 2
 float: 1
@@ -10128,7 +10140,9 @@ ifloat: 1
 ildouble: 2
 ldouble: 2
 Test "Imaginary part of: ctanh_upward (0x2.dp+4 + 0x1p+0 i)":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
@@ -10260,6 +10274,9 @@ idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "Real part of: ctanh_upward (0xcp-4 + 0x1.4p+0 i)":
+float: 1
+ifloat: 1
 Test "Imaginary part of: ctanh_upward (0xcp-4 + 0x1.4p+0 i)":
 float: 2
 ifloat: 2
@@ -10312,6 +10329,9 @@ ldouble: 1
 Test "erfc (0x7.fffd6p+0)":
 float: 1
 ifloat: 1
+Test "erfc (0xcp-4)":
+float: 1
+ifloat: 1
 
 # exp10
 Test "exp10 (-0x1.31p+8)":
@@ -11206,7 +11226,9 @@ idouble: 1
 ildouble: 1
 ldouble: 1
 Test "jn (4, 0x2.67a2a8p+0)":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
@@ -11232,7 +11254,9 @@ idouble: 2
 ildouble: 1
 ldouble: 1
 Test "jn (5, 0x2.67a2a8p+0)":
+double: 1
 float: 2
+idouble: 1
 ifloat: 2
 Test "jn (6, 0x2.67a2a4p+0)":
 double: 2
@@ -12932,7 +12956,9 @@ ildouble: 1
 ldouble: 1
 Test "tgamma (-0x4.fffff8p+0)":
 double: 1
+float: 1
 idouble: 1
+ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "tgamma (-0x4.ffffffffffffcp+0)":
@@ -12946,9 +12972,9 @@ ildouble: 1
 ldouble: 1
 Test "tgamma (-0x5.000008p+0)":
 double: 1
-float: 1
+float: 2
 idouble: 1
-ifloat: 1
+ifloat: 2
 ildouble: 1
 ldouble: 1
 Test "tgamma (-0x5.8p+0)":
@@ -13086,9 +13112,9 @@ double: 1
 idouble: 1
 Test "tgamma (-0x9.8p+0)":
 double: 1
-float: 1
+float: 2
 idouble: 1
-ifloat: 1
+ifloat: 2
 ildouble: 2
 ldouble: 2
 Test "tgamma (-0x9.ffffffffffff8p+0)":
@@ -13322,6 +13348,8 @@ float: 1
 idouble: 1
 ifloat: 1
 Test "tgamma (0x4.fffff8p+0)":
+float: 1
+ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "tgamma (0x4.ffffffffffffcp+0)":
@@ -13340,8 +13368,8 @@ Test "tgamma (0x5.0000000000004p+0)":
 double: 1
 idouble: 1
 Test "tgamma (0x5.000008p+0)":
-float: 2
-ifloat: 2
+float: 3
+ifloat: 3
 ildouble: 1
 ldouble: 1
 Test "tgamma (0x5.8p+0)":
@@ -13453,7 +13481,9 @@ double: 1
 idouble: 1
 Test "tgamma (0x9.8p+0)":
 double: 1
+float: 1
 idouble: 1
+ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "tgamma (0x9p+0)":
@@ -13506,18 +13536,26 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "y0 (0x1p-20)":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 Test "y0 (0x1p-40)":
 double: 1
 float: 1
 idouble: 1
 ifloat: 1
+Test "y0 (0x1p-60)":
+float: 1
+ifloat: 1
 Test "y0 (0x1p-80)":
 double: 1
 float: 1
 idouble: 1
 ifloat: 1
+Test "y0 (0x2p+0)":
+double: 1
+idouble: 1
 Test "y0 (0x2p-4)":
 ildouble: 1
 ldouble: 1
@@ -13547,7 +13585,9 @@ float: 1
 ifloat: 1
 Test "y0 (0x4p-72)":
 double: 1
+float: 1
 idouble: 1
+ifloat: 1
 Test "y0 (0x8p+0)":
 double: 1
 float: 1
@@ -13556,7 +13596,9 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "y0 (0xap+0)":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 Test "y0 (0xf.ffffffffffff8p+1020)":
 double: 1
@@ -13638,6 +13680,9 @@ idouble: 2
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "yn (0, 0x2p+0)":
+double: 1
+idouble: 1
 Test "yn (0, 0x2p-4)":
 ildouble: 1
 ldouble: 1
@@ -13649,7 +13694,9 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "yn (0, 0xap+0)":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 Test "yn (1, 0x1.8p+0)":
 float: 1
@@ -13682,9 +13729,9 @@ float: 2
 idouble: 1
 ifloat: 2
 Test "yn (10, 0x2p+0)":
-double: 2
+double: 3
 float: 1
-idouble: 2
+idouble: 3
 ifloat: 1
 Test "yn (10, 0x2p-4)":
 double: 1
@@ -13701,9 +13748,9 @@ Test "yn (10, 0x8p-972)":
 ildouble: 1
 ldouble: 1
 Test "yn (10, 0xap+0)":
-double: 1
+double: 2
 float: 1
-idouble: 1
+idouble: 2
 ifloat: 1
 Test "yn (10, 0xcp-4)":
 double: 1
diff --git a/time/strftime_l.c b/time/strftime_l.c
index dfb7b4c..29c7cdd 100644
--- a/time/strftime_l.c
+++ b/time/strftime_l.c
@@ -509,13 +509,17 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
      only a few elements.  Dereference the pointers only if the format
      requires this.  Then it is ok to fail if the pointers are invalid.  */
 # define a_wkday \
-  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
+  ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6			     \
+		     ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)))
 # define f_wkday \
-  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
+  ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6			     \
+		     ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)))
 # define a_month \
-  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
+  ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11			     \
+		     ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)))
 # define f_month \
-  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
+  ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11			     \
+		     ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)))
 # define ampm \
   ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11		      \
 				 ? NLW(PM_STR) : NLW(AM_STR)))
@@ -525,8 +529,10 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
 # define ap_len STRLEN (ampm)
 #else
 # if !HAVE_STRFTIME
-#  define f_wkday (weekday_name[tp->tm_wday])
-#  define f_month (month_name[tp->tm_mon])
+#  define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6	\
+		   ? "?" : weekday_name[tp->tm_wday])
+#  define f_month (tp->tm_mon < 0 || tp->tm_mon > 11	\
+		   ? "?" : month_name[tp->tm_mon])
 #  define a_wkday f_wkday
 #  define a_month f_month
 #  define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
@@ -1320,7 +1326,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
 		  *tzset_called = true;
 		}
 # endif
-	      zone = tzname[tp->tm_isdst];
+	      zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?";
 	    }
 #endif
 	  if (! zone)
diff --git a/time/tst-strftime.c b/time/tst-strftime.c
index 374fba4..af3ff72 100644
--- a/time/tst-strftime.c
+++ b/time/tst-strftime.c
@@ -4,6 +4,56 @@
 #include <time.h>
 
 
+static int
+do_bz18985 (void)
+{
+  char buf[1000];
+  struct tm ttm;
+  int rc, ret = 0;
+
+  memset (&ttm, 1, sizeof (ttm));
+  ttm.tm_zone = NULL;  /* Dereferenced directly if non-NULL.  */
+  rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm);
+
+  if (rc == 66)
+    {
+      const char expected[]
+	= "? ? ? ? ? ? 16843009 16843009:16843009:16843009 16844909 +467836 ?";
+      if (0 != strcmp (buf, expected))
+	{
+	  printf ("expected:\n  %s\ngot:\n  %s\n", expected, buf);
+	  ret += 1;
+	}
+    }
+  else
+    {
+      printf ("expected 66, got %d\n", rc);
+      ret += 1;
+    }
+
+  /* Check negative values as well.  */
+  memset (&ttm, 0xFF, sizeof (ttm));
+  ttm.tm_zone = NULL;  /* Dereferenced directly if non-NULL.  */
+  rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm);
+
+  if (rc == 30)
+    {
+      const char expected[] = "? ? ? ? ? ? -1 -1:-1:-1 1899  ";
+      if (0 != strcmp (buf, expected))
+	{
+	  printf ("expected:\n  %s\ngot:\n  %s\n", expected, buf);
+	  ret += 1;
+	}
+    }
+  else
+    {
+      printf ("expected 30, got %d\n", rc);
+      ret += 1;
+    }
+
+  return ret;
+}
+
 static struct
 {
   const char *fmt;
@@ -104,7 +154,7 @@ do_test (void)
 	}
     }
 
-  return result;
+  return result + do_bz18985 ();
 }
 
 #define TEST_FUNCTION do_test ()
diff --git a/timezone/Makefile b/timezone/Makefile
index f5fb424..58e7f50 100644
--- a/timezone/Makefile
+++ b/timezone/Makefile
@@ -114,7 +114,7 @@ $(testdata)/Asia/Tokyo: asia $(zic-deps)
 
 $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
 	sed -e 's|/bin/bash|$(KSH)|g' \
-	    -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \
+	    -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
 	    -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
 	    -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
 	    -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \
