diff --git a/SOURCES/glibc-aa64-commonpagesize-64k.patch b/SOURCES/glibc-aa64-commonpagesize-64k.patch
new file mode 100644
index 0000000..20ca912
--- /dev/null
+++ b/SOURCES/glibc-aa64-commonpagesize-64k.patch
@@ -0,0 +1,11 @@
+--- glibc-2.17-c758a686.orig/ports/sysdeps/aarch64/preconfigure	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/preconfigure	2014-05-12 14:29:52.007239252 -0400
+@@ -8,7 +8,7 @@
+ case "$machine" in
+ aarch64*)
+ 	# Parameters to allow auto-detection of -z relro.
+-	libc_commonpagesize=0x1000
++	libc_commonpagesize=0x10000
+ 	libc_relro_required=yes
+ 	;;
+ esac
diff --git a/SOURCES/glibc-aa64-setcontext.patch b/SOURCES/glibc-aa64-setcontext.patch
new file mode 100644
index 0000000..da20a54
--- /dev/null
+++ b/SOURCES/glibc-aa64-setcontext.patch
@@ -0,0 +1,220 @@
+Backport
+
+37d350073888887637aa67dddf988d9c4b226032 \
+  aarch64: Re-implement setcontext without rt_sigreturn syscall
+03ea4d9b6916857e3c2a021f55d2a853cb837398 \
+  [AArch64] Simplify getcontext pstate initialization.
+6e445a3d2bdf152ebf57d1c92bfea1828e070743 \
+  [AArch64] Ensure getcontext() initializes PSTATE.
+
+
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S b/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S
+index aff2e32..70b2e32 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S
+@@ -1,6 +1,6 @@
+ /* Save current context.
+ 
+-   Copyright (C) 2009-2012 Free Software Foundation, Inc.
++   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ 
+    This file is part of the GNU C Library.
+ 
+@@ -53,6 +53,9 @@ ENTRY(__getcontext)
+ 	mov	x2, sp
+ 	str     x2, [x0, oSP]
+ 
++	/* Initialize the pstate.  */
++	str	xzr, [x0, oPSTATE]
++
+ 	/* Figure out where to place the first context extension
+ 	   block.  */
+ 	add     x2, x0, #oEXTENSION
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S b/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S
+index a98f67f..f45a655 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S
+@@ -1,6 +1,6 @@
+ /* Set current context.
+ 
+-   Copyright (C) 2009-2012 Free Software Foundation, Inc.
++   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ 
+    This file is part of the GNU C Library.
+ 
+@@ -22,68 +22,108 @@
+ #include "ucontext_i.h"
+ #include "ucontext-internal.h"
+ 
+-/* int setcontext (const ucontext_t *ucp) */
++/*  int __setcontext (const ucontext_t *ucp)
+ 
+-	.text
+-
+-ENTRY(__setcontext)
+-
+-	/* Create a signal frame on the stack:
+-
+-		fp
+-		lr
+-		...
+-	   sp-> rt_sigframe
+-	 */
+-
+-	stp     x29, x30, [sp, -16]!
+-	cfi_adjust_cfa_offset (16)
+-	cfi_rel_offset (x29, 0)
+-	cfi_rel_offset (x30, 8)
+-
+-        mov     x29, sp
+-	cfi_def_cfa_register (x29)
+-
+-	/* Allocate space for the sigcontext.  */
+-	mov	w3, #((RT_SIGFRAME_SIZE + SP_ALIGN_SIZE) & SP_ALIGN_MASK)
+-	sub	sp, sp,	x3
++  Restores the machine context in UCP and thereby resumes execution
++  in that context.
+ 
+-	/* Compute the base address of the ucontext structure.  */
+-	add	x1, sp, #RT_SIGFRAME_UCONTEXT
++  This implementation is intended to be used for *synchronous* context
++  switches only.  Therefore, it does not have to restore anything
++  other than the PRESERVED state.  */
+ 
+-	/* Only ucontext is required in the frame, *copy* it in.  */
+-
+-#if UCONTEXT_SIZE % 16
+-#error The implementation of setcontext.S assumes sizeof(ucontext_t) % 16 == 0
+-#endif
+-
+-	mov	x2, #UCONTEXT_SIZE / 16
+-0:
+-	ldp	x3, x4, [x0], #16
+-	stp	x3, x4, [x1], #16
+-	sub	x2, x2, 1
+-	cbnz	x2, 0b
++	.text
+ 
+-	/* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe.  */
+-	mov	x8, SYS_ify (rt_sigreturn)
++ENTRY (__setcontext)
++	/* Save a copy of UCP.  */
++	mov	x9, x0
++
++	/* Set the signal mask with
++	   rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8).  */
++	mov	x0, #SIG_SETMASK
++	add	x1, x9, #UCONTEXT_SIGMASK
++	mov	x2, #0
++	mov	x3, #_NSIG8
++	mov	x8, SYS_ify (rt_sigprocmask)
+ 	svc	0
+-
+-	/* Ooops we failed.  Recover the stack */
+-
+-	mov	sp, x29
+-	cfi_def_cfa_register (sp)
+-
+-        ldp     x29, x30, [sp], 16
+-	cfi_adjust_cfa_offset (16)
+-	cfi_restore (x29)
+-	cfi_restore (x30)
+-	b	C_SYMBOL_NAME(__syscall_error)
+-
++	cbz	x0, 1f
++	b	C_SYMBOL_NAME (__syscall_error)
++1:
++	/* Restore the general purpose registers.  */
++	mov	x0, x9
++	cfi_def_cfa (x0, 0)
++	cfi_offset (x18, oX0 + 18 * SZREG)
++	cfi_offset (x19, oX0 + 19 * SZREG)
++	cfi_offset (x20, oX0 + 20 * SZREG)
++	cfi_offset (x21, oX0 + 21 * SZREG)
++	cfi_offset (x22, oX0 + 22 * SZREG)
++	cfi_offset (x23, oX0 + 23 * SZREG)
++	cfi_offset (x24, oX0 + 24 * SZREG)
++	cfi_offset (x25, oX0 + 25 * SZREG)
++	cfi_offset (x26, oX0 + 26 * SZREG)
++	cfi_offset (x27, oX0 + 27 * SZREG)
++	cfi_offset (x28, oX0 + 28 * SZREG)
++	cfi_offset (x29, oX0 + 29 * SZREG)
++	cfi_offset (x30, oX0 + 30 * SZREG)
++
++	cfi_offset ( d8, oV0 + 8 * SZVREG)
++	cfi_offset ( d9, oV0 + 9 * SZVREG)
++	cfi_offset (d10, oV0 + 10 * SZVREG)
++	cfi_offset (d11, oV0 + 11 * SZVREG)
++	cfi_offset (d12, oV0 + 12 * SZVREG)
++	cfi_offset (d13, oV0 + 13 * SZVREG)
++	cfi_offset (d14, oV0 + 14 * SZVREG)
++	cfi_offset (d15, oV0 + 15 * SZVREG)
++	ldp	x18, x19, [x0, oX0 + 18 * SZREG]
++	ldp	x20, x21, [x0, oX0 + 20 * SZREG]
++	ldp	x22, x23, [x0, oX0 + 22 * SZREG]
++	ldp	x24, x25, [x0, oX0 + 24 * SZREG]
++	ldp	x26, x27, [x0, oX0 + 26 * SZREG]
++	ldp	x28, x29, [x0, oX0 + 28 * SZREG]
++	ldr     x30,      [x0, oX0 + 30 * SZREG]
++	ldr     x2, [x0, oSP]
++	mov	sp, x2
++
++	/* Check for FP SIMD context.  We don't support restoring
++	   contexts created by the kernel, so this context must have
++	   been created by getcontext.  Hence we can rely on the
++	   first extension block being the FP SIMD context.  */
++	add     x2, x0, #oEXTENSION
++
++	mov	w3, #(FPSIMD_MAGIC & 0xffff)
++	movk	w3, #(FPSIMD_MAGIC >> 16), lsl #16
++	ldr	w1, [x2, #oHEAD + oMAGIC]
++	cmp	w1, w3
++	b.ne	2f
++
++	/* Restore the FP SIMD context.  */
++	add	x3, x2, #oV0 + 8 * SZVREG
++	ldp	 d8,  d9, [x3], #2 * SZVREG
++	ldp	d10, d11, [x3], #2 * SZVREG
++	ldp	d12, d13, [x3], #2 * SZVREG
++	ldp	d14, d15, [x3], #2 * SZVREG
++
++	add	x3, x2, oFPSR
++
++	ldr	w4, [x3]
++	msr	fpsr, x4
++
++	ldr	w4, [x3, oFPCR - oFPSR]
++	msr	fpcr, x4
++
++2:
++	ldr     x16, [x0, oPC]
++	/* Restore arg registers.  */
++	ldp	x2, x3, [x0, oX0 + 2 * SZREG]
++	ldp	x4, x5, [x0, oX0 + 4 * SZREG]
++	ldp	x6, x7, [x0, oX0 + 6 * SZREG]
++	ldp	x0, x1, [x0, oX0 + 0 * SZREG]
++	/* Jump to the new pc value.  */
++	br	x16
+ PSEUDO_END (__setcontext)
+ weak_alias (__setcontext, setcontext)
+ 
+-ENTRY(__startcontext)
++ENTRY (__startcontext)
+ 	mov	x0, x19
+ 	cbnz	x0, __setcontext
+-1:	b       HIDDEN_JUMPTARGET(_exit)
+-END(__startcontext)
++1:	b       HIDDEN_JUMPTARGET (_exit)
++END (__startcontext)
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym b/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
+index 1afff78..ab3930c 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
+@@ -37,6 +37,7 @@ STACK_FLAGS			stack (ss_flags)
+ oX0				mcontext (regs)
+ oSP				mcontext (sp)
+ oPC				mcontext (pc)
++oPSTATE				mcontext (pstate)
+ oEXTENSION                      mcontext (__reserved)
+ 
+ #define fpsimd_context(member)  offsetof (struct fpsimd_context, member)
diff --git a/SOURCES/glibc-aarch64-add-ptr_mangle-support.patch b/SOURCES/glibc-aarch64-add-ptr_mangle-support.patch
new file mode 100644
index 0000000..a7d5497
--- /dev/null
+++ b/SOURCES/glibc-aarch64-add-ptr_mangle-support.patch
@@ -0,0 +1,233 @@
+commit 9188b6818a3d1a6e6d89bf10fa4aea27a591494c
+Author: Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
+Date:   Wed Jan 1 17:47:14 2014 +0000
+
+    [AArch64] Pointer mangling support for AArch64.
+
+diff --git a/ports/sysdeps/aarch64/__longjmp.S b/ports/sysdeps/aarch64/__longjmp.S
+index 250f2af..2d38bbf 100644
+--- a/ports/sysdeps/aarch64/__longjmp.S
++++ b/ports/sysdeps/aarch64/__longjmp.S
+@@ -50,8 +50,12 @@ ENTRY (__longjmp)
+ 	ldp	x23, x24, [x0, #JB_X23<<3]
+ 	ldp	x25, x26, [x0, #JB_X25<<3]
+ 	ldp	x27, x28, [x0, #JB_X27<<3]
++#ifdef PTR_DEMANGLE
++	ldp	x29,  x4, [x0, #JB_X29<<3]
++	PTR_DEMANGLE (x30, x4, x3, x2)
++#else
+ 	ldp	x29, x30, [x0, #JB_X29<<3]
+-
++#endif
+ 	ldp	 d8,  d9, [x0, #JB_D8<<3]
+ 	ldp	d10, d11, [x0, #JB_D10<<3]
+ 	ldp	d12, d13, [x0, #JB_D12<<3]
+@@ -87,8 +91,12 @@ ENTRY (__longjmp)
+ 	cfi_same_value(d13)
+ 	cfi_same_value(d14)
+ 	cfi_same_value(d15)
+-
+-	ldr	x5,  [x0, #JB_SP<<3]
++#ifdef PTR_DEMANGLE
++	ldr	x4, [x0, #JB_SP<<3]
++	PTR_DEMANGLE (x5, x4, x3, x2)
++#else
++	ldr	x5, [x0, #JB_SP<<3]
++#endif
+ 	mov	sp, x5
+ 	cmp	x1, #0
+ 	mov	x0, #1
+diff --git a/ports/sysdeps/aarch64/jmpbuf-offsets.h b/ports/sysdeps/aarch64/jmpbuf-offsets.h
+index 84c2ccc..bcf2afa 100644
+--- a/ports/sysdeps/aarch64/jmpbuf-offsets.h
++++ b/ports/sysdeps/aarch64/jmpbuf-offsets.h
+@@ -39,6 +39,22 @@
+ #define JB_D14		 20
+ #define JB_D15		 21
+ 
++#ifndef  __ASSEMBLER__
++#include <setjmp.h>
++#include <stdint.h>
++#include <sysdep.h>
++
++static inline uintptr_t __attribute__ ((unused))
++_jmpbuf_sp (__jmp_buf jmpbuf)
++{
++  uintptr_t sp = jmpbuf[JB_SP];
++#ifdef PTR_DEMANGLE
++  PTR_DEMANGLE (sp);
++#endif
++  return sp;
++}
++#endif
++
+ /* Helper for generic ____longjmp_chk(). */
+ #define JB_FRAME_ADDRESS(buf) \
+-  ((void *) (buf[JB_SP]))
++  ((void *) _jmpbuf_sp (buf))
+diff --git a/ports/sysdeps/aarch64/jmpbuf-unwind.h b/ports/sysdeps/aarch64/jmpbuf-unwind.h
+index 22c6c2b..39a5dc2 100644
+--- a/ports/sysdeps/aarch64/jmpbuf-unwind.h
++++ b/ports/sysdeps/aarch64/jmpbuf-unwind.h
+@@ -29,16 +29,6 @@
+ #define _JMPBUF_CFA_UNWINDS_ADJ(jmpbuf, context, adj) \
+   _JMPBUF_UNWINDS_ADJ (jmpbuf, (void *) _Unwind_GetCFA (context), adj)
+ 
+-static inline uintptr_t __attribute__ ((unused))
+-_jmpbuf_sp (__jmp_buf jmpbuf)
+-{
+-  uintptr_t sp = jmpbuf[JB_SP];
+-#ifdef PTR_DEMANGLE
+-  PTR_DEMANGLE (sp);
+-#endif
+-  return sp;
+-}
+-
+ #define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+   ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+ 
+diff --git a/ports/sysdeps/aarch64/setjmp.S b/ports/sysdeps/aarch64/setjmp.S
+index cb94e01..5822abd 100644
+--- a/ports/sysdeps/aarch64/setjmp.S
++++ b/ports/sysdeps/aarch64/setjmp.S
+@@ -39,13 +39,25 @@ ENTRY (__sigsetjmp)
+ 	stp	x23, x24, [x0, #JB_X23<<3]
+ 	stp	x25, x26, [x0, #JB_X25<<3]
+ 	stp	x27, x28, [x0, #JB_X27<<3]
++
++#ifdef PTR_MANGLE
++	PTR_MANGLE (x4, x30, x3, x2)
++	stp	x29,  x4, [x0, #JB_X29<<3]
++#else
+ 	stp	x29, x30, [x0, #JB_X29<<3]
++#endif
+ 	stp	 d8,  d9, [x0, #JB_D8<<3]
+ 	stp	d10, d11, [x0, #JB_D10<<3]
+ 	stp	d12, d13, [x0, #JB_D12<<3]
+ 	stp	d14, d15, [x0, #JB_D14<<3]
++#ifdef PTR_MANGLE
++	mov	x4, sp
++	PTR_MANGLE (x5, x4, x3, x2)
++	str	x5, [x0, #JB_SP<<3]
++#else
+ 	mov	x2,  sp
+ 	str	x2,  [x0, #JB_SP<<3]
++#endif
+ #if defined NOT_IN_libc && defined IS_IN_rtld
+ 	/* In ld.so we never save the signal mask */
+ 	mov	w0, #0
+diff --git a/ports/sysdeps/aarch64/sysdep.h b/ports/sysdeps/aarch64/sysdep.h
+index 0dd597a..7169ba7 100644
+--- a/ports/sysdeps/aarch64/sysdep.h
++++ b/ports/sysdeps/aarch64/sysdep.h
+@@ -78,6 +78,17 @@
+ # define L(name)         .L##name
+ #endif
+ 
++/* Load or store to/from a pc-relative EXPR into/from R, using T.  */
++#define LDST_PCREL(OP, R, T, EXPR)  \
++	adrp	T, EXPR;	    \
++	OP	R, [T, #:lo12:EXPR];\
++
++/* Load or store to/from a got-relative EXPR into/from R, using T.  */
++#define LDST_GLOBAL(OP, R, T, EXPR)     \
++	adrp	T, :got:EXPR;		\
++	ldr	T, [T, #:got_lo12:EXPR];\
++	OP	R, [T];
++
+ /* Since C identifiers are not normally prefixed with an underscore
+    on this system, the asm identifier `syscall_error' intrudes on the
+    C name space.  Make sure we use an innocuous name.  */
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+index f3f0ada..5ccf1da 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+@@ -371,8 +371,44 @@ __local_syscall_error:						\
+ 
+ #endif	/* __ASSEMBLER__ */
+ 
+-/* Pointer mangling is not yet supported for AArch64.  */
+-#define PTR_MANGLE(var) (void) (var)
+-#define PTR_DEMANGLE(var) (void) (var)
++/* Pointer mangling is supported for AArch64.  */
++#if (defined NOT_IN_libc && defined IS_IN_rtld) || \
++  (!defined SHARED && (!defined NOT_IN_libc || defined IS_IN_libpthread))
++# ifdef __ASSEMBLER__
++#  define PTR_MANGLE(dst, src, guard, tmp)                                \
++  LDST_PCREL (ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local)); \
++  PTR_MANGLE2 (dst, src, guard)
++/* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
++#  define PTR_MANGLE2(dst, src, guard)\
++  eor dst, src, guard
++#  define PTR_DEMANGLE(dst, src, guard, tmp)\
++  PTR_MANGLE (dst, src, guard, tmp)
++#  define PTR_DEMANGLE2(dst, src, guard)\
++  PTR_MANGLE2 (dst, src, guard)
++# else
++extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
++#  define PTR_MANGLE(var) \
++  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
++#  define PTR_DEMANGLE(var)     PTR_MANGLE (var)
++# endif
++#else
++# ifdef __ASSEMBLER__
++#  define PTR_MANGLE(dst, src, guard, tmp)                             \
++  LDST_GLOBAL (ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard));   \
++  PTR_MANGLE2 (dst, src, guard)
++/* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
++#  define PTR_MANGLE2(dst, src, guard)\
++  eor dst, src, guard
++#  define PTR_DEMANGLE(dst, src, guard, tmp)\
++  PTR_MANGLE (dst, src, guard, tmp)
++#  define PTR_DEMANGLE2(dst, src, guard)\
++  PTR_MANGLE2 (dst, src, guard)
++# else
++extern uintptr_t __pointer_chk_guard attribute_relro;
++#  define PTR_MANGLE(var) \
++  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
++#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
++# endif
++#endif
+ 
+ #endif /* linux/aarch64/sysdep.h */
+commit 0b1f8e35640f5b3f7af11764ade3ff060211c309
+Author: Carlos O'Donell <carlos@redhat.com>
+Date:   Mon Sep 23 01:44:38 2013 -0400
+
+    BZ #15754: Fix test case for ARM.
+    
+    Statically built binaries use __pointer_chk_guard_local,
+    while dynamically built binaries use __pointer_chk_guard.
+    Provide the right definition depending on the test case
+    we are building.
+
+hiff --git a/elf/Makefile b/elf/Makefile
+index cb8da93..27d249b 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -1019,6 +1019,9 @@ tst-stackguard1-ARGS = --command "$(host-test-program-cmd) --child"
+ tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child"
+ 
+ tst-ptrguard1-ARGS = --command "$(host-built-program-cmd) --child"
++# When built statically, the pointer guard interface uses
++# __pointer_chk_guard_local.
++CFLAGS-tst-ptrguard1-static.c = -DPTRGUARD_LOCAL
+ tst-ptrguard1-static-ARGS = --command "$(objpfx)tst-ptrguard1-static --child"
+ 
+ $(objpfx)tst-leaks1: $(libdl)
+diff --git a/sysdeps/generic/stackguard-macros.h b/sysdeps/generic/stackguard-macros.h
+index 4fa3d96..b4a6b23 100644
+--- a/sysdeps/generic/stackguard-macros.h
++++ b/sysdeps/generic/stackguard-macros.h
+@@ -3,5 +3,10 @@
+ extern uintptr_t __stack_chk_guard;
+ #define STACK_CHK_GUARD __stack_chk_guard
+ 
++#ifdef PTRGUARD_LOCAL
+ extern uintptr_t __pointer_chk_guard_local;
+-#define POINTER_CHK_GUARD __pointer_chk_guard_local
++# define POINTER_CHK_GUARD __pointer_chk_guard_local
++#else
++extern uintptr_t __pointer_chk_guard;
++# define POINTER_CHK_GUARD __pointer_chk_guard
++#endif
diff --git a/SOURCES/glibc-aarch64-dont-alloc-static-tls-for-TLS_DESC.patch b/SOURCES/glibc-aarch64-dont-alloc-static-tls-for-TLS_DESC.patch
new file mode 100644
index 0000000..314249f
--- /dev/null
+++ b/SOURCES/glibc-aarch64-dont-alloc-static-tls-for-TLS_DESC.patch
@@ -0,0 +1,33 @@
+diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
+index 997c860..44154c0 100644
+--- a/ports/sysdeps/aarch64/dl-machine.h
++++ b/ports/sysdeps/aarch64/dl-machine.h
+@@ -294,21 +294,25 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
+ #ifndef RTLD_BOOTSTRAP
+ # ifndef SHARED
+ 		CHECK_STATIC_TLS (map, sym_map);
++		  {
++		    td->arg = (void*)(sym->st_value + sym_map->l_tls_offset
++				      + reloc->r_addend);
++		    td->entry = _dl_tlsdesc_return;
++		  }
+ # else
+-		if (!TRY_STATIC_TLS (map, sym_map))
+ 		  {
+ 		    td->arg = _dl_make_tlsdesc_dynamic
+ 		      (sym_map, sym->st_value + reloc->r_addend);
+ 		    td->entry = _dl_tlsdesc_dynamic;
+ 		  }
+-		else
+ # endif
+-#endif
++#else
+ 		  {
+ 		    td->arg = (void*)(sym->st_value + sym_map->l_tls_offset
+ 				      + reloc->r_addend);
+ 		    td->entry = _dl_tlsdesc_return;
+ 		  }
++#endif
+ 	      }
+ 	    break;
+ 	  }
diff --git a/SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch b/SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch
new file mode 100644
index 0000000..bb4ede0
--- /dev/null
+++ b/SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch
@@ -0,0 +1,122 @@
+commit 302949e2940a9da3f6364a1574619e621b7e1e71
+Author: Marcus Shawcroft <marcus.shawcroft@arm.com>
+Date:   Fri Mar 7 14:05:20 2014 +0000
+
+    [PATCH] [AArch64] Optional trapping exceptions support.
+    
+    Trapping exceptions in AArch64 are optional.  The relevant exception
+    control bits in FPCR are are defined as RES0 hence the absence of
+    support can be detected by reading back the FPCR and comparing with
+    the desired value.
+
+--- a/ports/sysdeps/aarch64/fpu/feenablxcpt.c
++++ b/ports/sysdeps/aarch64/fpu/feenablxcpt.c
+@@ -35,5 +35,18 @@ feenableexcept (int excepts)
+ 
+   _FPU_SETCW (fpcr);
+ 
++  /* Trapping exceptions are optional in AArch64 the relevant enable
++     bits in FPCR are RES0 hence the absence of support can be
++     detected by reading back the FPCR and comparing with the required
++     value.  */
++  if (excepts)
++    {
++      fpu_control_t updated_fpcr;
++
++      _FPU_GETCW (updated_fpcr);
++      if (((updated_fpcr >> FE_EXCEPT_SHIFT) & excepts) != excepts)
++	return -1;
++    }
++
+   return original_excepts;
+ }
+--- a/ports/sysdeps/aarch64/fpu/fesetenv.c
++++ b/ports/sysdeps/aarch64/fpu/fesetenv.c
+@@ -24,6 +24,7 @@ fesetenv (const fenv_t *envp)
+ {
+   fpu_control_t fpcr;
+   fpu_fpsr_t fpsr;
++  fpu_control_t updated_fpcr;
+ 
+   _FPU_GETCW (fpcr);
+   _FPU_GETFPSR (fpsr);
+@@ -51,6 +52,15 @@ fesetenv (const fenv_t *envp)
+ 
+   _FPU_SETCW (fpcr);
+ 
++  /* Trapping exceptions are optional in AArch64 the relevant enable
++     bits in FPCR are RES0 hence the absence of support can be
++     detected by reading back the FPCR and comparing with the required
++     value.  */
++
++  _FPU_GETCW (updated_fpcr);
++  if ((updated_fpcr & fpcr) != fpcr)
++    return 1;
++
+   return 0;
+ }
+ 
+commit 423a7160af7fcffc61aac5e2e36d0b6b5b083214
+Author: Wilco <wdijkstr@arm.com>
+Date:   Thu Apr 17 09:39:27 2014 +0100
+
+    Add fenv test support for targets which don't have FP traps.
+
+(removed unnecessary code to limit it to test-fenv.c --kyle)
+
+--- a/math/test-fenv.c
++++ b/math/test-fenv.c
+@@ -233,14 +234,9 @@ feenv_nomask_test (const char *flag_name, int fe_exc)
+ #if defined FE_NOMASK_ENV
+   int status;
+   pid_t pid;
+-  fenv_t saved;
+ 
+-  fegetenv (&saved);
+-  errno = 0;
+-  fesetenv (FE_NOMASK_ENV);
+-  status = errno;
+-  fesetenv (&saved);
+-  if (status == ENOSYS)
++  if (1
++      && fesetenv (FE_NOMASK_ENV) != 0)
+     {
+       printf ("Test: not testing FE_NOMASK_ENV, it isn't implemented.\n");
+       return;
+@@ -349,7 +345,13 @@ feexcp_nomask_test (const char *flag_name, int fe_exc)
+   int status;
+   pid_t pid;
+ 
+-  printf ("Test: after fedisableexcept (%s) processes will abort\n",
++  if (1 && feenableexcept (fe_exc) == -1)
++    {
++      printf ("Test: not testing feenableexcept, it isn't implemented.\n");
++      return;
++    }
++
++  printf ("Test: after feenableexcept (%s) processes will abort\n",
+ 	  flag_name);
+   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
+   pid = fork ();
+@@ -470,7 +472,6 @@ feenable_test (const char *flag_name, int fe_exc)
+ {
+   int excepts;
+ 
+-
+   printf ("Tests for feenableexcepts etc. with flag %s\n", flag_name);
+ 
+   /* First disable all exceptions.  */
+@@ -488,8 +489,12 @@ feenable_test (const char *flag_name, int fe_exc)
+ 	      flag_name, excepts);
+       ++count_errors;
+     }
+-
+   excepts = feenableexcept (fe_exc);
++  if (1 && excepts == -1)
++    {
++      printf ("Test: not testing feenableexcept, it isn't implemented.\n");
++      return;
++    }
+   if (excepts == -1)
+     {
+       printf ("Test: feenableexcept (%s) failed\n", flag_name);
diff --git a/SOURCES/glibc-aarch64-ifunc.patch b/SOURCES/glibc-aarch64-ifunc.patch
new file mode 100644
index 0000000..bd6425e
--- /dev/null
+++ b/SOURCES/glibc-aarch64-ifunc.patch
@@ -0,0 +1,216 @@
+diff --git a/elf/elf.h b/elf/elf.h
+index 8686fd5..2b10581 100644
+--- a/elf/elf.h
++++ b/elf/elf.h
+@@ -2327,6 +2327,117 @@ typedef Elf32_Addr Elf32_Conflict;
+ #define R_AARCH64_NONE            0	/* No relocation.  */
+ #define R_AARCH64_ABS64         257	/* Direct 64 bit. */
+ #define R_AARCH64_ABS32         258	/* Direct 32 bit.  */
++#define R_AARCH64_ABS16         259	/* Direct 16-bit.  */
++#define R_AARCH64_PREL64        260	/* PC-relative 64-bit.  */
++#define R_AARCH64_PREL32        261	/* PC-relative 32-bit.  */
++#define R_AARCH64_PREL16        262	/* PC-relative 16-bit.  */
++#define R_AARCH64_MOVW_UABS_G0  263	/* Dir. MOVZ imm. from bits 15:0.  */
++#define R_AARCH64_MOVW_UABS_G0_NC 264	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_UABS_G1  265	/* Dir. MOVZ imm. from bits 31:16.  */
++#define R_AARCH64_MOVW_UABS_G1_NC 266	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_UABS_G2  267	/* Dir. MOVZ imm. from bits 47:32.  */
++#define R_AARCH64_MOVW_UABS_G2_NC 268	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_UABS_G3  269	/* Dir. MOV{K,Z} imm. from 63:48.  */
++#define R_AARCH64_MOVW_SABS_G0  270	/* Dir. MOV{N,Z} imm. from 15:0.  */
++#define R_AARCH64_MOVW_SABS_G1  271	/* Dir. MOV{N,Z} imm. from 31:16.  */
++#define R_AARCH64_MOVW_SABS_G2  272	/* Dir. MOV{N,Z} imm. from 47:32.  */
++#define R_AARCH64_LD_PREL_LO19  273	/* PC-rel. LD imm. from bits 20:2.  */
++#define R_AARCH64_ADR_PREL_LO21 274	/* PC-rel. ADR imm. from bits 20:0.  */
++#define R_AARCH64_ADR_PREL_PG_HI21 275	/* Page-rel. ADRP imm. from 32:12.  */
++#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check.  */
++#define R_AARCH64_ADD_ABS_LO12_NC 277	/* Dir. ADD imm. from bits 11:0.  */
++#define R_AARCH64_LDST8_ABS_LO12_NC 278	/* Likewise for LD/ST; no check. */
++#define R_AARCH64_TSTBR14       279	/* PC-rel. TBZ/TBNZ imm. from 15:2.  */
++#define R_AARCH64_CONDBR19      280	/* PC-rel. cond. br. imm. from 20:2. */
++#define R_AARCH64_JUMP26        282	/* PC-rel. B imm. from bits 27:2.  */
++#define R_AARCH64_CALL26        283	/* Likewise for CALL.  */
++#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1.  */
++#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2.  */
++#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3.  */
++#define R_AARCH64_MOVW_PREL_G0  287	/* PC-rel. MOV{N,Z} imm. from 15:0.  */
++#define R_AARCH64_MOVW_PREL_G0_NC 288	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_PREL_G1  289	/* PC-rel. MOV{N,Z} imm. from 31:16. */
++#define R_AARCH64_MOVW_PREL_G1_NC 290	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_PREL_G2  291	/* PC-rel. MOV{N,Z} imm. from 47:32. */
++#define R_AARCH64_MOVW_PREL_G2_NC 292	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_PREL_G3  293	/* PC-rel. MOV{N,Z} imm. from 63:48. */
++#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4.  */
++#define R_AARCH64_MOVW_GOTOFF_G0 300	/* GOT-rel. off. MOV{N,Z} imm. 15:0. */
++#define R_AARCH64_MOVW_GOTOFF_G0_NC 301	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_GOTOFF_G1 302	/* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
++#define R_AARCH64_MOVW_GOTOFF_G1_NC 303	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_GOTOFF_G2 304	/* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
++#define R_AARCH64_MOVW_GOTOFF_G2_NC 305	/* Likewise for MOVK; no check.  */
++#define R_AARCH64_MOVW_GOTOFF_G3 306	/* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
++#define R_AARCH64_GOTREL64      307	/* GOT-relative 64-bit.  */
++#define R_AARCH64_GOTREL32      308	/* GOT-relative 32-bit.  */
++#define R_AARCH64_GOT_LD_PREL19 309	/* PC-rel. GOT off. load imm. 20:2.  */
++#define R_AARCH64_LD64_GOTOFF_LO15 310	/* GOT-rel. off. LD/ST imm. 14:3.  */
++#define R_AARCH64_ADR_GOT_PAGE  311	/* P-page-rel. GOT off. ADRP 32:12.  */
++#define R_AARCH64_LD64_GOT_LO12_NC 312	/* Dir. GOT off. LD/ST imm. 11:3.  */
++#define R_AARCH64_LD64_GOTPAGE_LO15 313	/* GOT-page-rel. GOT off. LD/ST 14:3 */
++#define R_AARCH64_TLSGD_ADR_PREL21 512	/* PC-relative ADR imm. 20:0.  */
++#define R_AARCH64_TLSGD_ADR_PAGE21 513	/* page-rel. ADRP imm. 32:12.  */
++#define R_AARCH64_TLSGD_ADD_LO12_NC 514	/* direct ADD imm. from 11:0.  */
++#define R_AARCH64_TLSGD_MOVW_G1 515	/* GOT-rel. MOV{N,Z} 31:16.  */
++#define R_AARCH64_TLSGD_MOVW_G0_NC 516	/* GOT-rel. MOVK imm. 15:0.  */
++#define R_AARCH64_TLSLD_ADR_PREL21 517	/* Like 512; local dynamic model.  */
++#define R_AARCH64_TLSLD_ADR_PAGE21 518	/* Like 513; local dynamic model.  */
++#define R_AARCH64_TLSLD_ADD_LO12_NC 519	/* Like 514; local dynamic model.  */
++#define R_AARCH64_TLSLD_MOVW_G1 520	/* Like 515; local dynamic model.  */
++#define R_AARCH64_TLSLD_MOVW_G0_NC 521	/* Like 516; local dynamic model.  */
++#define R_AARCH64_TLSLD_LD_PREL19 522	/* TLS PC-rel. load imm. 20:2.  */
++#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32.  */
++#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16.  */
++#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check.  */
++#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0.  */
++#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check.  */
++#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
++#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0.  */
++#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check.  */
++#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0.  */
++#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check.  */
++#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1.  */
++#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check.  */
++#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2.  */
++#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check.  */
++#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3.  */
++#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check.  */
++#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16.  */
++#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0.  */
++#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12.  */
++#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3.  */
++#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2.  */
++#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32.  */
++#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16.  */
++#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check.  */
++#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0.  */
++#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check.  */
++#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12.  */
++#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0.  */
++#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check.  */
++#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0.  */
++#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
++#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1.  */
++#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check.  */
++#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2.  */
++#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check.  */
++#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3.  */
++#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check.  */
++#define R_AARCH64_TLSDESC_LD_PREL19 560	/* PC-rel. load immediate 20:2.  */
++#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0.  */
++#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12.  */
++#define R_AARCH64_TLSDESC_LD64_LO12 563	/* Direct LD off. from 11:3.  */
++#define R_AARCH64_TLSDESC_ADD_LO12 564	/* Direct ADD imm. from 11:0.  */
++#define R_AARCH64_TLSDESC_OFF_G1 565	/* GOT-rel. MOV{N,Z} imm. 31:16.  */
++#define R_AARCH64_TLSDESC_OFF_G0_NC 566	/* GOT-rel. MOVK imm. 15:0; no ck.  */
++#define R_AARCH64_TLSDESC_LDR   567	/* Relax LDR.  */
++#define R_AARCH64_TLSDESC_ADD   568	/* Relax ADD.  */
++#define R_AARCH64_TLSDESC_CALL  569	/* Relax BLR.  */
++#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4.  */
++#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check.  */
++#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
++#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check.  */
+ #define R_AARCH64_COPY         1024	/* Copy symbol at runtime.  */
+ #define R_AARCH64_GLOB_DAT     1025	/* Create GOT entry.  */
+ #define R_AARCH64_JUMP_SLOT    1026	/* Create PLT entry.  */
+@@ -2335,6 +2446,7 @@ typedef Elf32_Addr Elf32_Conflict;
+ #define R_AARCH64_TLS_DTPREL64 1029	/* Module-relative offset, 64 bit.  */
+ #define R_AARCH64_TLS_TPREL64  1030	/* TP-relative offset, 64 bit.  */
+ #define R_AARCH64_TLSDESC      1031	/* TLS Descriptor.  */
++#define R_AARCH64_IRELATIVE    1032	/* STT_GNU_IFUNC relocation.  */
+ 
+ /* ARM relocs.  */
+ 
+diff --git a/ports/sysdeps/aarch64/dl-irel.h b/ports/sysdeps/aarch64/dl-irel.h
+index 32dee0f..9a48dc2 100644
+--- a/ports/sysdeps/aarch64/dl-irel.h
++++ b/ports/sysdeps/aarch64/dl-irel.h
+@@ -1,6 +1,6 @@
+ /* Machine-dependent ELF indirect relocation inline functions.
+    AArch64 version.
+-   Copyright (C) 2012 Free Software Foundation, Inc.
++   Copyright (C) 2012-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
+@@ -22,15 +22,31 @@
+ 
+ #include <stdio.h>
+ #include <unistd.h>
++#include <ldsodefs.h>
+ 
+-/* AArch64 does not yet implement IFUNC support.  However since
+-   2011-06-20 provision of a elf_ifunc_invoke has been mandatory.  */
++#define ELF_MACHINE_IRELA       1
+ 
+ static inline ElfW(Addr)
+ __attribute ((always_inline))
+ elf_ifunc_invoke (ElfW(Addr) addr)
+ {
+-  return ((ElfW(Addr) (*) (void)) (addr)) ();
++  return ((ElfW(Addr) (*) (unsigned long int)) (addr)) (GLRO(dl_hwcap));
++}
++
++static inline void
++__attribute ((always_inline))
++elf_irela (const ElfW(Rela) *reloc)
++{
++  ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset;
++  const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
++
++  if (__glibc_likely (r_type == R_AARCH64_IRELATIVE))
++    {
++      ElfW(Addr) value = elf_ifunc_invoke (reloc->r_addend);
++      *reloc_addr = value;
++    }
++  else
++    __libc_fatal ("unexpected reloc type in static binary");
+ }
+ 
+ #endif
+diff --git a/ports/sysdeps/aarch64/dl-machine.h b/ports/sysdeps/aarch64/dl-machine.h
+index b1878a7..1db5a5b 100644
+--- a/ports/sysdeps/aarch64/dl-machine.h
++++ b/ports/sysdeps/aarch64/dl-machine.h
+@@ -23,6 +23,7 @@
+ 
+ #include <tls.h>
+ #include <dl-tlsdesc.h>
++#include <dl-irel.h>
+ 
+ /* Return nonzero iff ELF header is compatible with the running host.  */
+ static inline int __attribute__ ((unused))
+@@ -336,6 +337,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
+ 	    }
+ 	  break;
+ 
++	case R_AARCH64_IRELATIVE:
++	  value = map->l_addr + reloc->r_addend;
++	  value = elf_ifunc_invoke (value);
++	  *reloc_addr = value;
++	  break;
++
+ 	default:
+ 	  _dl_reloc_bad_type (map, r_type, 0);
+ 	  break;
+@@ -379,6 +386,13 @@ elf_machine_lazy_rel (struct link_map *map,
+       td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
+ 			  + map->l_addr);
+     }
++  else if (__glibc_unlikely (r_type == R_AARCH64_IRELATIVE))
++    {
++      ElfW(Addr) value = map->l_addr + reloc->r_addend;
++      if (__glibc_likely (!skip_ifunc))
++	value = elf_ifunc_invoke (value);
++      *reloc_addr = value;
++    }
+   else
+     _dl_reloc_bad_type (map, r_type, 1);
+ }
diff --git a/SOURCES/glibc-aarch64-rh1076760.patch b/SOURCES/glibc-aarch64-rh1076760.patch
new file mode 100644
index 0000000..d860868
--- /dev/null
+++ b/SOURCES/glibc-aarch64-rh1076760.patch
@@ -0,0 +1,20 @@
+--- a/ports/sysdeps/aarch64/nptl/tls.h
++++ b/ports/sysdeps/aarch64/nptl/tls.h
+@@ -63,7 +63,7 @@ typedef struct
+ # define TLS_INIT_TCB_SIZE	sizeof (tcbhead_t)
+ 
+ /* Alignment requirements for the initial TCB.  */
+-# define TLS_INIT_TCB_ALIGN	__alignof__ (tcbhead_t)
++# define TLS_INIT_TCB_ALIGN	__alignof__ (struct pthread)
+ 
+ /* This is the size of the TCB.  */
+ # define TLS_TCB_SIZE		sizeof (tcbhead_t)
+@@ -72,7 +72,7 @@ typedef struct
+ # define TLS_PRE_TCB_SIZE	sizeof (struct pthread)
+ 
+ /* Alignment requirements for the TCB.  */
+-# define TLS_TCB_ALIGN		__alignof__ (tcbhead_t)
++# define TLS_TCB_ALIGN		__alignof__ (struct pthread)
+ 
+ /* Install the dtv pointer.  The pointer passed is to the element with
+    index -1 which contain the length.  */
diff --git a/SOURCES/glibc-aarch64-syscall-rewrite.patch b/SOURCES/glibc-aarch64-syscall-rewrite.patch
new file mode 100644
index 0000000..2833e2d
--- /dev/null
+++ b/SOURCES/glibc-aarch64-syscall-rewrite.patch
@@ -0,0 +1,540 @@
+From 9a7cb556eef7cb75b31d0bc05f73c6338dfd8e49 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth@redhat.com>
+Date: Fri, 30 May 2014 13:57:04 -0400
+Subject: [PATCH] aarch64: Backport syscall rewrite
+
+From commits:
+a60339aaff82beadea6f580e587d64052cb5e3b8 Fix handling of nocancel syscall...
+3612eb8f25d978e7e4ac536a34098091f737161c Merge rtld_errno offset w/ mem ref
+a6b3657be6bc5067aeec98d990f60765361c6557 Merge __local_multiple_threads ofs...
+c69abcee726a6f63d9e5e8f0d9dcc79374ee3ef8 Fix DO_CALL block comment
+6e6c2d01ebb1ef839675c7151d2a114f53663386 Remove DOARGS/UNDOARGS macros
+ca3cfa40c16ef34c74951a07a57cfcbcd58898b1 Tidy syscall error check
+af4e8ef9443e258ebeb0ddf3c5c9579f24dfacd5 Tabify sysdep-cancel.h
+a8b4f04ad7dff4f39797a7ab7f8babda54266026 Share code in sysdep-cancel.h
+645d44abe3ca6253a9d4762f092e4a1b9d294b11 Pass regno parameter to SINGLE_THREAD_P
+b5be4597716eff94149f5529c8eb2cd3b4296188 Improve syscall-cancel stack frame
+74f31c18593111725478a991b395ae45661985a3 Fix error return from __ioctl
+f0712b543eaddeca8fc6d7a8eb6b5b8d24105ce2 Remove PSEUDO_RET
+
+And a not-yet-committed cleanup to clone.S.
+---
+ ports/sysdeps/unix/sysv/linux/aarch64/clone.S      |  51 +++---
+ ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S      |  13 +-
+ .../unix/sysv/linux/aarch64/nptl/localplt.data     |   1 -
+ .../unix/sysv/linux/aarch64/nptl/sysdep-cancel.h   | 189 +++++++--------------
+ ports/sysdeps/unix/sysv/linux/aarch64/syscall.S    |   4 +-
+ ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h     |  84 ++-------
+ ports/sysdeps/unix/sysv/linux/aarch64/vfork.S      |   4 +-
+ 7 files changed, 108 insertions(+), 238 deletions(-)
+
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/clone.S b/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
+index 8be1464..d5c31f3 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
+@@ -39,46 +39,43 @@
+  */
+         .text
+ ENTRY(__clone)
++	/* Save args for the child.  */
++	mov	x10, x0
++	mov	x11, x2
++	mov	x12, x3
++	
+ 	/* Sanity check args.  */
+-	cbz	x0, 1f
+-	cbz	x1, 1f
+-	/* Insert the args onto the new stack.  */
+-	stp	x0, x3, [x1, #-16]!	/* Fn, arg.  */
++	mov	x0, #-EINVAL
++	cbz	x10, .Lsyscall_error
++	cbz	x1, .Lsyscall_error
+ 
+ 	/* Do the system call.  */
++	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
+ 	mov	x0, x2                  /* flags  */
+-
+ 	/* New sp is already in x1.  */
+ 	mov	x2, x4			/* ptid  */
+ 	mov	x3, x5			/* tls  */
+ 	mov	x4, x6			/* ctid  */
+ 
+-#ifdef RESET_PID
+-	/* We rely on the kernel preserving the argument regsiters across a
+-	   each system call so that we can inspect the flags against after
+-	   the clone call.  */
+-	mov	x5, x0
+-#endif
+-
+ 	mov	x8, #SYS_ify(clone)
+-	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
+ 	svc	0x0
+-	cfi_endproc
+ 	cmp	x0, #0
+-	beq	2f
+-	blt	C_SYMBOL_NAME(__syscall_error)
++	beq	thread_start
++	blt	.Lsyscall_error
+ 	RET
+-1:	mov	x0, #-EINVAL
+-	b	syscall_error
++PSEUDO_END (__clone)
+ 
+-2:
++	.align	4
++	.type	thread_start, %function
++thread_start:
+ 	cfi_startproc
+ 	cfi_undefined (x30)
+ 	mov	x29, 0
++
+ #ifdef RESET_PID
+-	tbnz	x5, #CLONE_THREAD_BIT, 3f
++	tbnz	x11, #CLONE_THREAD_BIT, 3f
+ 	mov	x0, #-1
+-	tbnz	x5, #CLONE_VM_BIT, 2f
++	tbnz	x11, #CLONE_VM_BIT, 2f
+ 	mov	x8, #SYS_ify(getpid)
+ 	svc	0x0
+ 2:
+@@ -86,18 +83,16 @@ ENTRY(__clone)
+ 	sub	x1, x1, #PTHREAD_SIZEOF
+ 	str	w0, [x1, #PTHREAD_PID_OFFSET]
+ 	str	w0, [x1, #PTHREAD_TID_OFFSET]
+-
+ 3:
+ #endif
+-	/* Pick the function arg and call address from the stack and
+-	   execute.  */
+-	ldp	x1, x0, [sp], #16
+-	blr	x1
++
++	/* Pick the function arg execute.  */
++	mov	x0, x12
++	blr	x10
+ 
+ 	/* We are done, pass the return value through x0.  */
+ 	b	HIDDEN_JUMPTARGET(_exit)
+ 	cfi_endproc
+-	cfi_startproc
+-PSEUDO_END (__clone)
++	.size	thread_start, .-thread_start
+ 
+ weak_alias (__clone, clone)
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S b/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
+index f01fb84..be6c026 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
+@@ -20,13 +20,12 @@
+ 
+ 	.text
+ ENTRY(__ioctl)
+-	movz	x8, #__NR_ioctl
+-        sxtw	x0, w0
+-        svc	#0x0
+-	cmn	x0, #0x1, lsl #12
+-	b.hi	C_SYMBOL_NAME(__syscall_error)
++	mov	x8, #__NR_ioctl
++	sxtw	x0, w0
++	svc	#0x0
++	cmn	x0, #4095
++	b.cs	.Lsyscall_error
+ 	ret
+-
+-	PSEUDO_END (__ioctl)
++PSEUDO_END (__ioctl)
+ 
+ weak_alias (__ioctl, ioctl)
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
+index 84af95d..dfca9a7 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
+@@ -12,4 +12,3 @@ libm.so: matherr
+ libm.so: __signbit
+ libm.so: __signbitf
+ libm.so: __signbitl
+-libpthread.so: __errno_location
+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 e0e5cc0..a3b9284 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+@@ -26,119 +26,60 @@
+ 
+ # undef PSEUDO
+ # define PSEUDO(name, syscall_name, args)				\
+-  .section ".text";							\
+-  .type __##syscall_name##_nocancel,%function;				\
+-  .globl __##syscall_name##_nocancel;					\
+-  __##syscall_name##_nocancel:						\
+-    cfi_startproc;							\
+-    DO_CALL (syscall_name, args);					\
+-    PSEUDO_RET;								\
+-    cfi_endproc;							\
+-    .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	\
+-  ENTRY (name);								\
+-    SINGLE_THREAD_P;							\
+-    DOARGS_##args;							\
+-    bne .Lpseudo_cancel;						\
+-    DO_CALL (syscall_name, 0);						\
+-    UNDOARGS_##args;							\
+-    cmn x0, 4095;							\
+-    PSEUDO_RET;								\
+-  .Lpseudo_cancel:							\
+-    DOCARGS_##args;	/* save syscall args etc. around CENABLE.  */	\
+-    CENABLE;								\
+-    mov x16, x0;	/* put mask in safe place.  */			\
+-    UNDOCARGS_##args;	/* restore syscall args.  */			\
+-    mov x8, SYS_ify (syscall_name);	/* do the call.  */		\
+-    svc	0;								\
+-    str x0, [sp, -16]!;	/* save syscall return value.  */		\
+-    cfi_adjust_cfa_offset (16);						\
+-    mov x0, x16;	 /* get mask back.  */				\
+-    CDISABLE;								\
+-    ldr x0, [sp], 16;							\
+-    cfi_adjust_cfa_offset (-16);					\
+-    ldr x30, [sp], 16;							\
+-    cfi_adjust_cfa_offset (-16);					\
+-    cfi_restore (x30);							\
+-    UNDOARGS_##args;							\
+-    cmn x0, 4095;
+-
+-# define DOCARGS_0							\
+-	str x30, [sp, -16]!;						\
+-	cfi_adjust_cfa_offset (16);					\
+-	cfi_rel_offset (x30, 0)
++	.section ".text";						\
++ENTRY (__##syscall_name##_nocancel);					\
++.Lpseudo_nocancel:							\
++	DO_CALL (syscall_name, args);					\
++.Lpseudo_finish:							\
++	cmn	x0, 4095;						\
++	b.cs	.Lsyscall_error;					\
++	.subsection 2;							\
++	.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
++ENTRY (name);								\
++	SINGLE_THREAD_P(16);						\
++	cbz	w16, .Lpseudo_nocancel;					\
++	/* Setup common stack frame no matter the number of args.	\
++	   Also save the first arg, since it's basically free.  */	\
++	stp	x30, x0, [sp, -64]!;					\
++	cfi_adjust_cfa_offset (64);					\
++	cfi_rel_offset (x30, 0);					\
++	DOCARGS_##args;		/* save syscall args around CENABLE.  */ \
++	CENABLE;							\
++	mov	x16, x0;	/* save mask around syscall.  */	\
++	UNDOCARGS_##args;	/* restore syscall args.  */		\
++	DO_CALL (syscall_name, args);					\
++	str	x0, [sp, 8];	/* save result around CDISABLE.  */	\
++	mov	x0, x16;	/* restore mask for CDISABLE.  */	\
++	CDISABLE;							\
++	/* Break down the stack frame, restoring result at once.  */	\
++	ldp	x30, x0, [sp], 64;					\
++	cfi_adjust_cfa_offset (-64);					\
++	cfi_restore (x30);						\
++	b	.Lpseudo_finish;					\
++	cfi_endproc;							\
++	.size	name, .-name;						\
++	.previous
++
++# undef PSEUDO_END
++# define PSEUDO_END(name)						\
++	SYSCALL_ERROR_HANDLER;						\
++	cfi_endproc
++
++# define DOCARGS_0
++# define DOCARGS_1
++# define DOCARGS_2	str x1, [sp, 16]
++# define DOCARGS_3	stp x1, x2, [sp, 16]
++# define DOCARGS_4	DOCARGS_3; str x3, [sp, 32]
++# define DOCARGS_5	DOCARGS_3; stp x3, x4, [sp, 32]
++# define DOCARGS_6	DOCARGS_5; str x5, [sp, 48]
+ 
+ # define UNDOCARGS_0
+-
+-# define DOCARGS_1							\
+-	DOCARGS_0;							\
+-	str x0, [sp, -16]!;						\
+-	cfi_adjust_cfa_offset (16);					\
+-	cfi_rel_offset (x0, 0)
+-
+-# define UNDOCARGS_1							\
+-	ldr x0, [sp], 16;						\
+-	cfi_restore (x0);						\
+-	cfi_adjust_cfa_offset (-16);					\
+-
+-# define DOCARGS_2							\
+-	DOCARGS_1;							\
+-	str x1, [sp, -16]!;						\
+-	cfi_adjust_cfa_offset (16);					\
+-	cfi_rel_offset (x1, 0)
+-
+-# define UNDOCARGS_2							\
+-	ldr x1, [sp], 16;						\
+-	cfi_restore (x1);						\
+-	cfi_adjust_cfa_offset (-16);					\
+-	UNDOCARGS_1
+-
+-# define DOCARGS_3							\
+-	DOCARGS_2;							\
+-	str x2, [sp, -16]!;						\
+-	cfi_adjust_cfa_offset (16);					\
+-	cfi_rel_offset (x2, 0)
+-
+-# define UNDOCARGS_3							\
+-	ldr x2, [sp], 16;						\
+-	cfi_restore (x2);						\
+-	cfi_adjust_cfa_offset (-16);					\
+-	UNDOCARGS_2
+-
+-# define DOCARGS_4							\
+-	DOCARGS_3;							\
+-	str x3, [sp, -16]!;						\
+-	cfi_adjust_cfa_offset (16);					\
+-	cfi_rel_offset (x3, 0)
+-
+-# define UNDOCARGS_4							\
+-	ldr x3, [sp], 16;						\
+-	cfi_restore (x3);						\
+-	cfi_adjust_cfa_offset (-16);					\
+-	UNDOCARGS_3
+-
+-# define DOCARGS_5							\
+-	DOCARGS_4;							\
+-	str x4, [sp, -16]!;						\
+-	cfi_adjust_cfa_offset (16);					\
+-	cfi_rel_offset (x4, 0)
+-
+-# define UNDOCARGS_5							\
+-	ldr x4, [sp], 16;						\
+-	cfi_restore (x4);						\
+-	cfi_adjust_cfa_offset (-16);					\
+-	UNDOCARGS_4
+-
+-# define DOCARGS_6							\
+-	DOCARGS_5;							\
+-	str x5, [sp, -16]!;						\
+-	cfi_adjust_cfa_offset (16);					\
+-	cfi_rel_offset (x5, 0)
+-
+-# define UNDOCARGS_6							\
+-	ldr x5, [sp], 16;						\
+-	cfi_restore (x5);						\
+-	cfi_adjust_cfa_offset (-16);					\
+-	UNDOCARGS_5
++# define UNDOCARGS_1	ldr x0, [sp, 8]
++# define UNDOCARGS_2	ldp x0, x1, [sp, 8]
++# define UNDOCARGS_3	UNDOCARGS_1; ldp x1, x2, [sp, 16]
++# define UNDOCARGS_4	UNDOCARGS_2; ldp x2, x3, [sp, 24]
++# define UNDOCARGS_5	UNDOCARGS_3; ldp x3, x4, [sp, 32]
++# define UNDOCARGS_6	UNDOCARGS_4; ldp x4, x5, [sp, 40]
+ 
+ # ifdef IS_IN_libpthread
+ #  define CENABLE	bl __pthread_enable_asynccancel
+@@ -160,11 +101,9 @@
+ extern int __local_multiple_threads attribute_hidden;
+ #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+ #  else
+-#   define SINGLE_THREAD_P						\
+-  adrp	x16, __local_multiple_threads;					\
+-  add	x16, x16, #:lo12:__local_multiple_threads;			\
+-  ldr	x16, [x16];							\
+-  cmp	x16, 0;
++#   define SINGLE_THREAD_P(R)						\
++	adrp	x##R, __local_multiple_threads;				\
++	ldr	w##R, [x##R, :lo12:__local_multiple_threads]
+ #  endif
+ # else
+ /*  There is no __local_multiple_threads for librt, so use the TCB.  */
+@@ -173,20 +112,10 @@ extern int __local_multiple_threads attribute_hidden;
+   __builtin_expect (THREAD_GETMEM (THREAD_SELF,				\
+ 				   header.multiple_threads) == 0, 1)
+ #  else
+-#   define SINGLE_THREAD_P						\
+-  stp	x0, x30, [sp, -16]!;						\
+-  cfi_adjust_cfa_offset (16);						\
+-  cfi_rel_offset (x0, 0);						\
+-  cfi_rel_offset (x30, 8);						\
+-  bl	__read_tp;							\
+-  sub	x0, x0, PTHREAD_SIZEOF;						\
+-  ldr	x16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET];			\
+-  ldp	x0, x30, [sp], 16;						\
+-  cfi_restore (x0);							\
+-  cfi_restore (x30);							\
+-  cfi_adjust_cfa_offset (-16);						\
+-  cmp	x16, 0
+-#   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
++#   define SINGLE_THREAD_P(R)						\
++	mrs	x##R, tpidr_el0;					\
++	sub	x##R, x##R, PTHREAD_SIZEOF;				\
++	ldr	w##R, [x##R, PTHREAD_MULTIPLE_THREADS_OFFSET]
+ #  endif
+ # endif
+ 
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S b/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
+index 574fdf1..fac6416 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
+@@ -37,8 +37,6 @@ ENTRY (syscall)
+ 	mov	x6, x7
+ 	svc	0x0
+ 	cmn	x0, #4095
+-	b.cs	1f
++	b.cs	.Lsyscall_error
+ 	RET
+-1:
+-	b	SYSCALL_ERROR
+ PSEUDO_END (syscall)
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+index 713bf7d..9961c03 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+@@ -58,19 +58,8 @@
+   .text;								      \
+   ENTRY (name);								      \
+     DO_CALL (syscall_name, args);					      \
+-    cmn x0, #4095;
+-
+-/* Notice the use of 'RET' instead of 'ret' the assembler is case
+-   insensitive and eglibc already uses the preprocessor symbol 'ret'
+-   so we use the upper case 'RET' to force through a ret instruction
+-   to the assembler */
+-# define PSEUDO_RET							      \
+-    b.cs 1f;								      \
+-    RET;								      \
+-    1:                                                                        \
+-    b SYSCALL_ERROR
+-# undef ret
+-# define ret PSEUDO_RET
++    cmn x0, #4095;							      \
++    b.cs .Lsyscall_error
+ 
+ # undef	PSEUDO_END
+ # define PSEUDO_END(name)						      \
+@@ -83,15 +72,7 @@
+   ENTRY (name);								      \
+     DO_CALL (syscall_name, args);
+ 
+-/* Notice the use of 'RET' instead of 'ret' the assembler is case
+-   insensitive and eglibc already uses the preprocessor symbol 'ret'
+-   so we use the upper case 'RET' to force through a ret instruction
+-   to the assembler */
+-# define PSEUDO_RET_NOERRNO						      \
+-    RET;
+-
+-# undef ret_NOERRNO
+-# define ret_NOERRNO PSEUDO_RET_NOERRNO
++# define ret_NOERRNO ret
+ 
+ # undef	PSEUDO_END_NOERRNO
+ # define PSEUDO_END_NOERRNO(name)					      \
+@@ -109,47 +90,38 @@
+ # define PSEUDO_END_ERRVAL(name) \
+   END (name)
+ 
+-# define ret_ERRVAL PSEUDO_RET_NOERRNO
++# define ret_ERRVAL ret
+ 
++# define SYSCALL_ERROR  .Lsyscall_error
+ # if NOT_IN_libc
+-#  define SYSCALL_ERROR __local_syscall_error
+ #  if RTLD_PRIVATE_ERRNO
+ #   define SYSCALL_ERROR_HANDLER				\
+-__local_syscall_error:						\
++.Lsyscall_error:						\
+ 	adrp	x1, C_SYMBOL_NAME(rtld_errno);			\
+-	add	x1, x1, #:lo12:C_SYMBOL_NAME(rtld_errno);	\
+ 	neg     w0, w0;						\
+-	str     w0, [x1];					\
++	str     w0, [x1, :lo12:C_SYMBOL_NAME(rtld_errno)];	\
+ 	mov	x0, -1;						\
+ 	RET;
+ #  else
+ 
+ #   define SYSCALL_ERROR_HANDLER				\
+-__local_syscall_error:						\
+-	stp     x29, x30, [sp, -32]!;				\
+-	cfi_adjust_cfa_offset (32);				\
+-	cfi_rel_offset (x29, 0);				\
+-	cfi_rel_offset (x30, 8);				\
+-        add     x29, sp, 0;					\
+-        str     x19, [sp,16];					\
+-	neg	x19, x0;					\
+-	bl	C_SYMBOL_NAME(__errno_location);		\
+-	str	x19, [x0];					\
++.Lsyscall_error:						\
++	adrp	x1, :gottprel:errno;				\
++	neg	w2, w0;						\
++	ldr	x1, [x1, :gottprel_lo12:errno];			\
++	mrs	x3, tpidr_el0;					\
+ 	mov	x0, -1;						\
+-        ldr     x19, [sp,16];					\
+-        ldp     x29, x30, [sp], 32;				\
+-	cfi_adjust_cfa_offset (-32);				\
+-	cfi_restore (x29);					\
+-	cfi_restore (x30);					\
++	str	w2, [x1, x3];					\
+ 	RET;
+ #  endif
+ # else
+-#  define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
+-#  define SYSCALL_ERROR __syscall_error
++#  define SYSCALL_ERROR_HANDLER					\
++.Lsyscall_error:						\
++	b	__syscall_error;
+ # endif
+ 
+ /* Linux takes system call args in registers:
+-	syscall number	in the SVC instruction
++	syscall number	x8
+ 	arg 1		x0
+ 	arg 2		x1
+ 	arg 3		x2
+@@ -177,28 +149,8 @@ __local_syscall_error:						\
+ 
+ # undef	DO_CALL
+ # define DO_CALL(syscall_name, args)		\
+-    DOARGS_##args				\
+     mov x8, SYS_ify (syscall_name);		\
+-    svc 0;					\
+-    UNDOARGS_##args
+-
+-# define DOARGS_0 /* nothing */
+-# define DOARGS_1 /* nothing */
+-# define DOARGS_2 /* nothing */
+-# define DOARGS_3 /* nothing */
+-# define DOARGS_4 /* nothing */
+-# define DOARGS_5 /* nothing */
+-# define DOARGS_6 /* nothing */
+-# define DOARGS_7 /* nothing */
+-
+-# define UNDOARGS_0 /* nothing */
+-# define UNDOARGS_1 /* nothing */
+-# define UNDOARGS_2 /* nothing */
+-# define UNDOARGS_3 /* nothing */
+-# define UNDOARGS_4 /* nothing */
+-# define UNDOARGS_5 /* nothing */
+-# define UNDOARGS_6 /* nothing */
+-# define UNDOARGS_7 /* nothing */
++    svc 0
+ 
+ #else /* not __ASSEMBLER__ */
+ 
+diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S b/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
+index f2dc49b..3fb68b9 100644
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
+@@ -38,10 +38,8 @@ ENTRY (__vfork)
+ 	RESTORE_PID
+ #endif
+ 	cmn	x0, #4095
+-	b.cs    1f
++	b.cs    .Lsyscall_error
+ 	RET
+-1:
+-	b	SYSCALL_ERROR
+ 
+ PSEUDO_END (__vfork)
+ libc_hidden_def (__vfork)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-cs-path.patch b/SOURCES/glibc-cs-path.patch
new file mode 100644
index 0000000..982f8ff
--- /dev/null
+++ b/SOURCES/glibc-cs-path.patch
@@ -0,0 +1,6 @@
+diff -pruN a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h
+--- a/sysdeps/unix/confstr.h	2012-12-25 08:32:13.000000000 +0530
++++ b/sysdeps/unix/confstr.h	2014-09-05 20:02:55.698275219 +0530
+@@ -1 +1 @@
+-#define	CS_PATH	"/bin:/usr/bin"
++#define	CS_PATH	"/usr/bin"
diff --git a/SOURCES/glibc-fix-test-write-buf-size.patch b/SOURCES/glibc-fix-test-write-buf-size.patch
new file mode 100644
index 0000000..69ab522
--- /dev/null
+++ b/SOURCES/glibc-fix-test-write-buf-size.patch
@@ -0,0 +1,54 @@
+# This patch fixes tst-cancel4, tst-cancel5, tst-cancelx4 and tst-cancelx5
+# failures on newer kernels where the write buffers are larger. 
+#
+# commit e7074e4c5edb0acaa979ea08e533736f906a9d68
+# Author: David S. Miller <davem@davemloft.net>
+# Date:   Tue Jul 23 02:31:37 2013 -0700
+# 
+#     Increase nptl test case buffer size so we really block on current Linux kernels.
+#     
+#         * tst-cancel4.c (WRITE_BUFFER_SIZE): Increase to 16384.
+# 
+# commit 135529b443631f840cc66d0cc395f79c416434d9
+# Author: David S. Miller <davem@davemloft.net>
+# Date:   Tue Jul 23 11:31:39 2013 -0700
+# 
+#     Remove Linux kernel version ambiguity in comment added by previous commit.
+#     
+#         * tst-cancel4.c (WRITE_BUFFER_SIZE): Adjust comment.
+# 
+diff -urN glibc-2.17-c758a686.next/nptl/tst-cancel4.c glibc-2.17-c758a686.new/nptl/tst-cancel4.c
+--- glibc-2.17-c758a686.next/nptl/tst-cancel4.c	2014-07-25 22:07:09.130021164 -0400
++++ glibc-2.17-c758a686.new/nptl/tst-cancel4.c	2014-07-25 22:12:07.580022919 -0400
+@@ -83,7 +83,30 @@
+ # define IPC_ADDVAL 0
+ #endif
+ 
+-#define WRITE_BUFFER_SIZE 4096
++/* The WRITE_BUFFER_SIZE value needs to be choosen such that if we set
++   the socket send buffer size to '1', a write of this size on that
++   socket will block.
++
++   The Linux kernel imposes a minimum send socket buffer size which
++   has changed over the years.  As of Linux 3.10 the value is:
++
++     2 * (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff)))
++
++   which is attempting to make sure that with standard MTUs,
++   TCP can always queue up at least 2 full sized packets.
++
++   Furthermore, there is logic in the socket send paths that
++   will allow one more packet (of any size) to be queued up as
++   long as some socket buffer space remains.   Blocking only
++   occurs when we try to queue up a new packet and the send
++   buffer space has already been fully consumed.
++
++   Therefore we must set this value to the largest possible value of
++   the formula above (and since it depends upon the size of "struct
++   sk_buff", it is dependent upon machine word size etc.) plus some
++   slack space.  */
++
++#define WRITE_BUFFER_SIZE 16384
+ 
+ /* Cleanup handling test.  */
+ static int cl_called;
diff --git a/SOURCES/glibc-gmake.patch b/SOURCES/glibc-gmake.patch
new file mode 100644
index 0000000..29a1cd6
--- /dev/null
+++ b/SOURCES/glibc-gmake.patch
@@ -0,0 +1,37 @@
+#
+# BZ #16037
+#
+# Allow building glibc with make version 4.0 or greater.
+# This facilitates testing and QE on non-RHEL environments during
+# patch development.
+#
+# commit 28d708c44bc47b56f6551ff285f78edcf61c208a
+# Author: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
+# Date:   Thu Oct 31 12:37:50 2013 +1000
+#
+#    Accept make versions 4.0 and greater
+#
+diff -urN glibc-2.17-c758a686/configure glibc-2.17-c758a686.mod/configure
+--- glibc-2.17-c758a686/configure	2015-01-15 16:32:14.983435268 -0500
++++ glibc-2.17-c758a686.mod/configure	2015-01-15 16:32:45.396495266 -0500
+@@ -4991,7 +4991,7 @@
+   ac_prog_version=`$MAKE --version 2>&1 | sed -n 's/^.*GNU Make[^0-9]*\([0-9][0-9.]*\).*$/\1/p'`
+   case $ac_prog_version in
+     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
+-    3.79* | 3.[89]*)
++    3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*)
+        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
+     *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
+ 
+diff -urN glibc-2.17-c758a686/configure.in glibc-2.17-c758a686.mod/configure.in
+--- glibc-2.17-c758a686/configure.in	2015-01-15 16:32:14.781441511 -0500
++++ glibc-2.17-c758a686.mod/configure.in	2015-01-15 16:32:34.970817501 -0500
+@@ -945,7 +945,7 @@
+   critic_missing="$critic_missing gcc")
+ AC_CHECK_PROG_VER(MAKE, gnumake gmake make, --version,
+   [GNU Make[^0-9]*\([0-9][0-9.]*\)],
+-  [3.79* | 3.[89]*], critic_missing="$critic_missing make")
++  [3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*], critic_missing="$critic_missing make")
+ 
+ AC_CHECK_PROG_VER(MSGFMT, gnumsgfmt gmsgfmt msgfmt, --version,
+   [GNU gettext.* \([0-9]*\.[0-9.]*\)],
diff --git a/SOURCES/glibc-manual-update.patch b/SOURCES/glibc-manual-update.patch
new file mode 100644
index 0000000..6f35371
--- /dev/null
+++ b/SOURCES/glibc-manual-update.patch
@@ -0,0 +1,19408 @@
+#
+# Synchronize RHEL 7.1 manual with upstream manual.
+#
+# Include updates that don't impact material differences
+# between the upstream master and 2.17-based RHEL implemenation.
+#
+diff -urN glibc-2.17-c758a686/manual/argp.texi glibc/manual/argp.texi
+--- glibc-2.17-c758a686/manual/argp.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/argp.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -36,6 +36,35 @@
+ @comment argp.h
+ @comment GNU
+ @deftypefun {error_t} argp_parse (const struct argp *@var{argp}, int @var{argc}, char **@var{argv}, unsigned @var{flags}, int *@var{arg_index}, void *@var{input})
++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtslocale{} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
++@c Optionally alloca()tes standard help options, initializes the parser,
++@c then parses individual args in a loop, and then finalizes.
++@c  parser_init
++@c   calc_sizes ok
++@c    option_is_end ok
++@c   malloc @ascuheap @acsmem
++@c   parser_convert @mtslocale
++@c    convert_options @mtslocale
++@c     option_is_end ok
++@c     option_is_short ok
++@c      isprint, but locale may change within the loop
++@c     find_long_option ok
++@c   group_parse
++@c    group->parser (from argp->parser)
++@c  parser_parse_next
++@c   getopt_long(_only)_r many issues, same as non_r minus @mtasurace
++@c   parser_parse_arg
++@c    group_parse dup
++@c   parser_parse_opt
++@c    group_parse dup
++@c    argp_error dup @mtasurace:argpbuf @mtsenv @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
++@c    dgettext (bad key error) dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c  parser_finalize
++@c   group_parse
++@c   fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem]
++@c   dgettext dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c   arg_state_help
++@c   free dup @ascuhelp @acsmem
+ The @code{argp_parse} function parses the arguments in @var{argv}, of
+ length @var{argc}, using the argp parser @var{argp}.  @xref{Argp
+ Parsers}.  Passing a null pointer for @var{argp} is the same as using
+@@ -660,6 +689,8 @@
+ @comment argp.h
+ @comment GNU
+ @deftypefun void argp_usage (const struct argp_state *@var{state})
++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
++@c Just calls argp_state_help with stderr and ARGP_HELP_STD_USAGE.
+ Outputs the standard usage message for the argp parser referred to by
+ @var{state} to @code{@var{state}->err_stream} and terminate the program
+ with @code{exit (argp_err_exit_status)}.  @xref{Argp Global Variables}.
+@@ -669,6 +700,13 @@
+ @comment argp.h
+ @comment GNU
+ @deftypefun void argp_error (const struct argp_state *@var{state}, const char *@var{fmt}, @dots{})
++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
++@c Lock stream, vasprintf the formatted message into a buffer, print the
++@c buffer prefixed by the short program name (in libc,
++@c argp_short_program_name is a macro that expands to
++@c program_invocation_short_name), releases the buffer, then call
++@c argp_state_help with stream and ARGP_HELP_STD_ERR, unlocking the
++@c stream at the end.
+ Prints the printf format string @var{fmt} and following args, preceded
+ by the program name and @samp{:}, and followed by a @w{@samp{Try @dots{}
+ --help}} message, and terminates the program with an exit status of
+@@ -679,6 +717,12 @@
+ @comment argp.h
+ @comment GNU
+ @deftypefun void argp_failure (const struct argp_state *@var{state}, int @var{status}, int @var{errnum}, const char *@var{fmt}, @dots{})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}}
++@c Lock stream, write out the short program name, vasprintf the optional
++@c formatted message to a buffer, print the buffer prefixed by colon and
++@c blank, release the buffer, call strerror_r with an automatic buffer,
++@c print it out after colon and blank, put[w]c a line break, unlock the
++@c stream, then exit unless ARGP_NO_EXIT.
+ Similar to the standard gnu error-reporting function @code{error}, this
+ prints the program name and @samp{:}, the printf format string
+ @var{fmt}, and the appropriate following args.  If it is non-zero, the
+@@ -695,6 +739,142 @@
+ @comment argp.h
+ @comment GNU
+ @deftypefun void argp_state_help (const struct argp_state *@var{state}, FILE *@var{stream}, unsigned @var{flags})
++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
++@c Just calls _help with the short program name and optionally exit.
++@c The main problems in _help, besides the usual issues with stream I/O
++@c and translation, are the use of a static buffer (uparams, thus
++@c @mtasurace:argpbuf) that makes the whole thing thread-unsafe, reading
++@c from the environment for ARGP_HELP_FMT, accessing the locale object
++@c multiple times.
++
++@c _help @mtsenv @mtasurace:argpbuf @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
++@c  dgettext @ascuintl
++@c  flockfile @aculock
++@c  funlockfile @aculock
++@c  fill_in_uparams @mtsenv @mtasurace:argpbuf @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
++@c   argp_failure dup (status = errnum = 0)
++@c   atoi dup @mtslocale
++@c  argp_hol @ascuheap @acsmem
++@c   make_hol @ascuheap @acsmem
++@c   hol_add_cluster @ascuheap @acsmem
++@c   hol_append @ascuheap @acsmem
++@c  hol_set_group ok
++@c   hol_find_entry ok
++@c  hol_sort @mtslocale @acucorrupt
++@c   qsort dup @acucorrupt
++@c    hol_entry_qcmp @mtslocale
++@c     hol_entry_cmp @mtslocale
++@c      group_cmp ok
++@c      hol_cluster_cmp ok
++@c       group_cmp ok
++@c      hol_entry_first_short @mtslocale
++@c       hol_entry_short_iterate [@mtslocale]
++@c        until_short ok
++@c         oshort ok
++@c          isprint ok
++@c      odoc ok
++@c      hol_entry_first_long ok
++@c      canon_doc_option @mtslocale
++@c      tolower dup
++@c  hol_usage @mtslocale @ascuintl @ascuheap @acsmem
++@c   hol_entry_short_iterate ok
++@c    add_argless_short_opt ok
++@c   argp_fmtstream_printf dup
++@c   hol_entry_short_iterate @mtslocale @ascuintl @ascuheap @acsmem
++@c    usage_argful_short_opt @mtslocale @ascuintl @ascuheap @acsmem
++@c     dgettext dup
++@c     argp_fmtstream_printf dup
++@c   hol_entry_long_iterate @mtslocale @ascuintl @ascuheap @acsmem
++@c    usage_long_opt @mtslocale @ascuintl @ascuheap @acsmem
++@c     dgettext dup
++@c     argp_fmtstream_printf dup
++@c  hol_help @mtslocale @mtasurace:argpbuf @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
++@c   hol_entry_help @mtslocale @mtasurace:argpbuf @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
++@c    argp_fmtstream_set_lmargin dup
++@c    argp_fmtstream_wmargin dup
++@c    argp_fmtstream_set_wmargin dup
++@c    comma @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
++@c     argp_fmtstream_putc dup
++@c     hol_cluster_is_child ok
++@c     argp_fmtstream_wmargin dup
++@c     print_header dup
++@c     argp_fmtstream_set_wmargin dup
++@c     argp_fmtstream_puts dup
++@c     indent_to dup
++@c    argp_fmtstream_putc dup
++@c    arg @mtslocale @ascuheap @acsmem
++@c     argp_fmtstream_printf dup
++@c    odoc dup
++@c    argp_fmtstream_puts dup
++@c    argp_fmtstream_printf dup
++@c    print_header @mtslocale @mtasurace:argpbuf @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
++@c     dgettext dup
++@c     filter_doc dup
++@c     argp_fmtstream_putc dup
++@c     indent_to dup
++@c     argp_fmtstream_set_lmargin dup
++@c     argp_fmtstream_set_wmargin dup
++@c     argp_fmtstream_puts dup
++@c     free dup
++@c    filter_doc dup
++@c    argp_fmtstream_point dup
++@c    indent_to @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
++@c     argp_fmtstream_point dup
++@c     argp_fmtstream_putc dup
++@c   dgettext dup
++@c   filter_doc dup
++@c   argp_fmtstream_putc dup
++@c   argp_fmtstream_puts dup
++@c   free dup
++@c  hol_free @ascuheap @acsmem
++@c   free dup
++@c  argp_args_levels ok
++@c  argp_args_usage @mtslocale @ascuintl @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
++@c   dgettext dup
++@c   filter_doc ok
++@c    argp_input ok
++@c    argp->help_filter
++@c   space @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
++@c    argp_fmtstream_point dup
++@c    argp_fmtstream_rmargin @mtslocale @asucorrupt @acucorrupt @aculock
++@c     argp_fmtstream_update dup
++@c    argp_fmtstream_putc dup
++@c   argp_fmtstream_write dup
++@c   free dup
++@c  argp_doc @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
++@c   dgettext @ascuintl
++@c   strndup @ascuheap @acsmem
++@c   argp_input dup
++@c   argp->help_filter
++@c   argp_fmtstream_putc @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
++@c    argp_fmtstream_ensure dup
++@c   argp_fmtstream_write dup
++@c   argp_fmtstream_puts dup
++@c   argp_fmtstream_point @mtslocale @asucorrupt @acucorrupt @aculock
++@c    argp_fmtstream_update dup
++@c   argp_fmtstream_lmargin dup
++@c   free dup
++@c  argp_make_fmtstream @ascuheap @acsmem
++@c  argp_fmtstream_free @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
++@c   argp_fmtstream_update @mtslocale @asucorrupt @acucorrupt @aculock
++@c    put[w]c_unlocked dup
++@c    isblank in loop @mtslocale
++@c    fxprintf @aculock
++@c   fxprintf @aculock
++@c   free dup
++@c  argp_fmtstream_set_wmargin @mtslocale @asucorrupt @acucorrupt @aculock
++@c   argp_fmtstream_update dup
++@c  argp_fmtstream_printf @mtslocale @ascuheap @acsmem
++@c   argp_fmtstream_ensure dup
++@c   vsnprintf dup
++@c  argp_fmtstream_set_lmargin @mtslocale @asucorrupt @acucorrupt @aculock
++@c   argp_fmtstream_update dup
++@c  argp_fmtstream_puts @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
++@c   argp_fmtstream_write @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
++@c    argp_fmtstream_ensure @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
++@c     argp_fmtstream_update dup
++@c     fxprintf @aculock
++@c     realloc @ascuheap @acsmem
+ Outputs a help message for the argp parser referred to by @var{state},
+ to @var{stream}.  The @var{flags} argument determines what sort of help
+ message is produced.  @xref{Argp Help Flags}.
+@@ -928,6 +1108,8 @@
+ @comment argp.h
+ @comment GNU
+ @deftypefun void argp_help (const struct argp *@var{argp}, FILE *@var{stream}, unsigned @var{flags}, char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
++@c Just calls _help.
+ This outputs a help message for the argp parser @var{argp} to
+ @var{stream}.  The type of messages printed will be determined by
+ @var{flags}.
+diff -urN glibc-2.17-c758a686/manual/arith.texi glibc/manual/arith.texi
+--- glibc-2.17-c758a686/manual/arith.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/arith.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -160,6 +160,8 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun div_t div (int @var{numerator}, int @var{denominator})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Functions in this section are pure, and thus safe.
+ This function @code{div} computes the quotient and remainder from
+ the division of @var{numerator} by @var{denominator}, returning the
+ result in a structure of type @code{div_t}.
+@@ -199,6 +201,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun ldiv_t ldiv (long int @var{numerator}, long int @var{denominator})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{ldiv} function is similar to @code{div}, except that the
+ arguments are of type @code{long int} and the result is returned as a
+ structure of type @code{ldiv_t}.
+@@ -225,6 +228,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun lldiv_t lldiv (long long int @var{numerator}, long long int @var{denominator})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{lldiv} function is like the @code{div} function, but the
+ arguments are of type @code{long long int} and the result is returned as
+ a structure of type @code{lldiv_t}.
+@@ -256,6 +260,7 @@
+ @comment inttypes.h
+ @comment ISO
+ @deftypefun imaxdiv_t imaxdiv (intmax_t @var{numerator}, intmax_t @var{denominator})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{imaxdiv} function is like the @code{div} function, but the
+ arguments are of type @code{intmax_t} and the result is returned as
+ a structure of type @code{imaxdiv_t}.
+@@ -318,6 +323,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn {Macro} int fpclassify (@emph{float-type} @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is a generic macro which works on all floating-point types and
+ which returns a value of type @code{int}.  The possible values are:
+ 
+@@ -354,6 +360,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn {Macro} int isfinite (@emph{float-type} @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns a nonzero value if @var{x} is finite: not plus or
+ minus infinity, and not NaN.  It is equivalent to
+ 
+@@ -368,6 +375,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn {Macro} int isnormal (@emph{float-type} @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns a nonzero value if @var{x} is finite and normalized.
+ It is equivalent to
+ 
+@@ -379,6 +387,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn {Macro} int isnan (@emph{float-type} @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns a nonzero value if @var{x} is NaN.  It is equivalent
+ to
+ 
+@@ -387,6 +396,15 @@
+ @end smallexample
+ @end deftypefn
+ 
++@comment math.h
++@comment GNU
++@deftypefn {Macro} int issignaling (@emph{float-type} @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++This macro returns a nonzero value if @var{x} is a signaling NaN
++(sNaN).  It is based on draft TS 18661 and currently enabled as a GNU
++extension.
++@end deftypefn
++
+ Another set of floating-point classification functions was provided by
+ BSD.  @Theglibc{} also supports these functions; however, we
+ recommend that you use the ISO C99 macros in new code.  Those are standard
+@@ -402,6 +420,7 @@
+ @comment math.h
+ @comment BSD
+ @deftypefunx int isinfl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function returns @code{-1} if @var{x} represents negative infinity,
+ @code{1} if @var{x} represents positive infinity, and @code{0} otherwise.
+ @end deftypefun
+@@ -415,6 +434,7 @@
+ @comment math.h
+ @comment BSD
+ @deftypefunx int isnanl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function returns a nonzero value if @var{x} is a ``not a number''
+ value, and zero otherwise.
+ 
+@@ -437,6 +457,7 @@
+ @comment math.h
+ @comment BSD
+ @deftypefunx int finitel (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function returns a nonzero value if @var{x} is finite or a ``not a
+ number'' value, and zero otherwise.
+ @end deftypefun
+@@ -489,7 +510,8 @@
+ is called when certain exceptions occur inside math library functions.
+ However, the Unix98 standard deprecates this interface.  We support it
+ for historical compatibility, but recommend that you do not use it in
+-new programs.
++new programs.  When this interface is used, exceptions may not be
++raised.
+ 
+ @noindent
+ The exceptions defined in @w{IEEE 754} are:
+@@ -705,6 +727,14 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int feclearexcept (int @var{excepts})
++@safety{@prelim{}@mtsafe{}@assafe{@assposix{}}@acsafe{@acsposix{}}}
++@c The other functions in this section that modify FP status register
++@c mostly do so with non-atomic load-modify-store sequences, but since
++@c the register is thread-specific, this should be fine, and safe for
++@c cancellation.  As long as the FP environment is restored before the
++@c signal handler returns control to the interrupted thread (like any
++@c kernel should do), the functions are also safe for use in signal
++@c handlers.
+ This function clears all of the supported exception flags indicated by
+ @var{excepts}.
+ 
+@@ -715,6 +745,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int feraiseexcept (int @var{excepts})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function raises the supported exceptions indicated by
+ @var{excepts}.  If more than one exception bit in @var{excepts} is set
+ the order in which the exceptions are raised is undefined except that
+@@ -730,6 +761,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int fetestexcept (int @var{excepts})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Test whether the exception flags indicated by the parameter @var{except}
+ are currently set.  If any of them are, a nonzero value is returned
+ which specifies which exceptions are set.  Otherwise the result is zero.
+@@ -766,6 +798,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int fegetexceptflag (fexcept_t *@var{flagp}, int @var{excepts})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function stores in the variable pointed to by @var{flagp} an
+ implementation-defined value representing the current setting of the
+ exception flags indicated by @var{excepts}.
+@@ -777,6 +810,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int fesetexceptflag (const fexcept_t *@var{flagp}, int @var{excepts})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function restores the flags for the exceptions indicated by
+ @var{excepts} to the values stored in the variable pointed to by
+ @var{flagp}.
+@@ -798,7 +832,8 @@
+ Many of the math functions are defined only over a subset of the real or
+ complex numbers.  Even if they are mathematically defined, their result
+ may be larger or smaller than the range representable by their return
+-type.  These are known as @dfn{domain errors}, @dfn{overflows}, and
++type without loss of accuracy.  These are known as @dfn{domain errors},
++@dfn{overflows}, and
+ @dfn{underflows}, respectively.  Math functions do several things when
+ one of these errors occurs.  In this manual we will refer to the
+ complete response as @dfn{signalling} a domain error, overflow, or
+@@ -808,11 +843,20 @@
+ exception and returns NaN.  It also sets @var{errno} to @code{EDOM};
+ this is for compatibility with old systems that do not support @w{IEEE
+ 754} exception handling.  Likewise, when overflow occurs, math
+-functions raise the overflow exception and return @math{@infinity{}} or
+-@math{-@infinity{}} as appropriate.  They also set @var{errno} to
+-@code{ERANGE}.  When underflow occurs, the underflow exception is
+-raised, and zero (appropriately signed) is returned.  @var{errno} may be
+-set to @code{ERANGE}, but this is not guaranteed.
++functions raise the overflow exception and, in the default rounding
++mode, return @math{@infinity{}} or @math{-@infinity{}} as appropriate
++(in other rounding modes, the largest finite value of the appropriate
++sign is returned when appropriate for that rounding mode).  They also
++set @var{errno} to @code{ERANGE} if returning @math{@infinity{}} or
++@math{-@infinity{}}; @var{errno} may or may not be set to
++@code{ERANGE} when a finite value is returned on overflow.  When
++underflow occurs, the underflow exception is raised, and zero
++(appropriately signed) or a subnormal value, as appropriate for the
++mathematical result of the function and the rounding mode, is
++returned.  @var{errno} may be set to @code{ERANGE}, but this is not
++guaranteed; it is intended that @theglibc{} should set it when the
++underflow is to an appropriately signed zero, but not necessarily for
++other underflows.
+ 
+ Some of the math functions are defined mathematically to result in a
+ complex value over parts of their domains.  The most familiar example of
+@@ -932,6 +976,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int fegetround (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns the currently selected rounding mode, represented by one of the
+ values of the defined rounding mode macros.
+ @end deftypefun
+@@ -942,6 +987,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int fesetround (int @var{round})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Changes the currently selected rounding mode to @var{round}.  If
+ @var{round} does not correspond to one of the supported rounding modes
+ nothing is changed.  @code{fesetround} returns zero if it changed the
+@@ -986,6 +1032,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int fegetenv (fenv_t *@var{envp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Store the floating-point environment in the variable pointed to by
+ @var{envp}.
+ 
+@@ -996,6 +1043,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int feholdexcept (fenv_t *@var{envp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Store the current floating-point environment in the object pointed to by
+ @var{envp}.  Then clear all exception flags, and set the FPU to trap no
+ exceptions.  Not all FPUs support trapping no exceptions; if
+@@ -1034,6 +1082,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int fesetenv (const fenv_t *@var{envp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Set the floating-point environment to that described by @var{envp}.
+ 
+ The function returns zero in case the operation was successful, a
+@@ -1043,6 +1092,7 @@
+ @comment fenv.h
+ @comment ISO
+ @deftypefun int feupdateenv (const fenv_t *@var{envp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Like @code{fesetenv}, this function sets the floating-point environment
+ to that described by @var{envp}.  However, if any exceptions were
+ flagged in the status word before @code{feupdateenv} was called, they
+@@ -1063,6 +1113,7 @@
+ @comment fenv.h
+ @comment GNU
+ @deftypefun int feenableexcept (int @var{excepts})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This functions enables traps for each of the exceptions as indicated by
+ the parameter @var{except}.  The individual exceptions are described in
+ @ref{Status bit operations}.  Only the specified exceptions are
+@@ -1075,6 +1126,7 @@
+ @comment fenv.h
+ @comment GNU
+ @deftypefun int fedisableexcept (int @var{excepts})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This functions disables traps for each of the exceptions as indicated by
+ the parameter @var{except}.  The individual exceptions are described in
+ @ref{Status bit operations}.  Only the specified exceptions are
+@@ -1086,7 +1138,8 @@
+ 
+ @comment fenv.h
+ @comment GNU
+-@deftypefun int fegetexcept (int @var{excepts})
++@deftypefun int fegetexcept (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The function returns a bitmask of all currently enabled exceptions.  It
+ returns @code{-1} in case of failure.
+ @end deftypefun
+@@ -1138,6 +1191,7 @@
+ @comment inttypes.h
+ @comment ISO
+ @deftypefunx intmax_t imaxabs (intmax_t @var{number})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the absolute value of @var{number}.
+ 
+ Most computers use a two's complement integer representation, in which
+@@ -1159,6 +1213,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} fabsl (long double @var{number})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function returns the absolute value of the floating-point number
+ @var{number}.
+ @end deftypefun
+@@ -1172,6 +1227,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {long double} cabsl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the absolute  value of the complex number @var{z}
+ (@pxref{Complex Numbers}).  The absolute value of a complex number is:
+ 
+@@ -1181,7 +1237,7 @@
+ 
+ This function should always be used instead of the direct formula
+ because it takes special care to avoid losing precision.  It may also
+-take advantage of hardware support for this operation. See @code{hypot}
++take advantage of hardware support for this operation.  See @code{hypot}
+ in @ref{Exponents and Logarithms}.
+ @end deftypefun
+ 
+@@ -1209,12 +1265,13 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} frexpl (long double @var{value}, int *@var{exponent})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are used to split the number @var{value}
+ into a normalized fraction and an exponent.
+ 
+ If the argument @var{value} is not zero, the return value is @var{value}
+-times a power of two, and is always in the range 1/2 (inclusive) to 1
+-(exclusive).  The corresponding exponent is stored in
++times a power of two, and its magnitude is always in the range 1/2
++(inclusive) to 1 (exclusive).  The corresponding exponent is stored in
+ @code{*@var{exponent}}; the return value multiplied by 2 raised to this
+ exponent equals the original number @var{value}.
+ 
+@@ -1234,6 +1291,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} ldexpl (long double @var{value}, int @var{exponent})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the result of multiplying the floating-point
+ number @var{value} by 2 raised to the power @var{exponent}.  (It can
+ be used to reassemble floating-point numbers that were taken apart
+@@ -1248,51 +1306,55 @@
+ 
+ @comment math.h
+ @comment BSD
+-@deftypefun double scalb (double @var{value}, int @var{exponent})
++@deftypefun double scalb (double @var{value}, double @var{exponent})
+ @comment math.h
+ @comment BSD
+-@deftypefunx float scalbf (float @var{value}, int @var{exponent})
++@deftypefunx float scalbf (float @var{value}, float @var{exponent})
+ @comment math.h
+ @comment BSD
+-@deftypefunx {long double} scalbl (long double @var{value}, int @var{exponent})
++@deftypefunx {long double} scalbl (long double @var{value}, long double @var{exponent})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{scalb} function is the BSD name for @code{ldexp}.
+ @end deftypefun
+ 
+ @comment math.h
+ @comment BSD
+-@deftypefun {long long int} scalbn (double @var{x}, int @var{n})
++@deftypefun double scalbn (double @var{x}, int @var{n})
+ @comment math.h
+ @comment BSD
+-@deftypefunx {long long int} scalbnf (float @var{x}, int @var{n})
++@deftypefunx float scalbnf (float @var{x}, int @var{n})
+ @comment math.h
+ @comment BSD
+-@deftypefunx {long long int} scalbnl (long double @var{x}, int @var{n})
++@deftypefunx {long double} scalbnl (long double @var{x}, int @var{n})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{scalbn} is identical to @code{scalb}, except that the exponent
+ @var{n} is an @code{int} instead of a floating-point number.
+ @end deftypefun
+ 
+ @comment math.h
+ @comment BSD
+-@deftypefun {long long int} scalbln (double @var{x}, long int @var{n})
++@deftypefun double scalbln (double @var{x}, long int @var{n})
+ @comment math.h
+ @comment BSD
+-@deftypefunx {long long int} scalblnf (float @var{x}, long int @var{n})
++@deftypefunx float scalblnf (float @var{x}, long int @var{n})
+ @comment math.h
+ @comment BSD
+-@deftypefunx {long long int} scalblnl (long double @var{x}, long int @var{n})
++@deftypefunx {long double} scalblnl (long double @var{x}, long int @var{n})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{scalbln} is identical to @code{scalb}, except that the exponent
+ @var{n} is a @code{long int} instead of a floating-point number.
+ @end deftypefun
+ 
+ @comment math.h
+ @comment BSD
+-@deftypefun {long long int} significand (double @var{x})
++@deftypefun double significand (double @var{x})
+ @comment math.h
+ @comment BSD
+-@deftypefunx {long long int} significandf (float @var{x})
++@deftypefunx float significandf (float @var{x})
+ @comment math.h
+ @comment BSD
+-@deftypefunx {long long int} significandl (long double @var{x})
++@deftypefunx {long double} significandl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{significand} returns the mantissa of @var{x} scaled to the range
+ @math{[1, 2)}.
+ It is equivalent to @w{@code{scalb (@var{x}, (double) -ilogb (@var{x}))}}.
+@@ -1307,7 +1369,7 @@
+ 
+ @pindex math.h
+ The functions listed here perform operations such as rounding and
+-truncation of floating-point values. Some of these functions convert
++truncation of floating-point values.  Some of these functions convert
+ floating point numbers to integer values.  They are all declared in
+ @file{math.h}.
+ 
+@@ -1327,6 +1389,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} ceill (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions round @var{x} upwards to the nearest integer,
+ returning that value as a @code{double}.  Thus, @code{ceil (1.5)}
+ is @code{2.0}.
+@@ -1341,6 +1404,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} floorl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions round @var{x} downwards to the nearest
+ integer, returning that value as a @code{double}.  Thus, @code{floor
+ (1.5)} is @code{1.0} and @code{floor (-1.5)} is @code{-2.0}.
+@@ -1355,6 +1419,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} truncl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{trunc} functions round @var{x} towards zero to the nearest
+ integer (returned in floating-point format).  Thus, @code{trunc (1.5)}
+ is @code{1.0} and @code{trunc (-1.5)} is @code{-1.0}.
+@@ -1369,6 +1434,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} rintl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions round @var{x} to an integer value according to the
+ current rounding mode.  @xref{Floating Point Parameters}, for
+ information about the various rounding modes.  The default
+@@ -1389,6 +1455,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} nearbyintl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the same value as the @code{rint} functions, but
+ do not raise the inexact exception if @var{x} is not an integer.
+ @end deftypefun
+@@ -1402,6 +1469,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} roundl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are similar to @code{rint}, but they round halfway
+ cases away from zero instead of to the nearest integer (or other
+ current rounding mode).
+@@ -1416,6 +1484,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long int} lrintl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are just like @code{rint}, but they return a
+ @code{long int} instead of a floating-point number.
+ @end deftypefun
+@@ -1429,6 +1498,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long long int} llrintl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are just like @code{rint}, but they return a
+ @code{long long int} instead of a floating-point number.
+ @end deftypefun
+@@ -1442,6 +1512,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long int} lroundl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are just like @code{round}, but they return a
+ @code{long int} instead of a floating-point number.
+ @end deftypefun
+@@ -1455,6 +1526,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long long int} llroundl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are just like @code{round}, but they return a
+ @code{long long int} instead of a floating-point number.
+ @end deftypefun
+@@ -1469,6 +1541,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} modfl (long double @var{value}, long double *@var{integer-part})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions break the argument @var{value} into an integer part and a
+ fractional part (between @code{-1} and @code{1}, exclusive).  Their sum
+ equals @var{value}.  Each of the parts has the same sign as @var{value},
+@@ -1495,6 +1568,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} fmodl (long double @var{numerator}, long double @var{denominator})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute the remainder from the division of
+ @var{numerator} by @var{denominator}.  Specifically, the return value is
+ @code{@var{numerator} - @w{@var{n} * @var{denominator}}}, where @var{n}
+@@ -1517,6 +1591,7 @@
+ @comment math.h
+ @comment BSD
+ @deftypefunx {long double} dreml (long double @var{numerator}, long double @var{denominator})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are like @code{fmod} except that they round the
+ internal quotient @var{n} to the nearest integer instead of towards zero
+ to an integer.  For example, @code{drem (6.5, 2.3)} returns @code{-0.4},
+@@ -1540,6 +1615,7 @@
+ @comment math.h
+ @comment BSD
+ @deftypefunx {long double} remainderl (long double @var{numerator}, long double @var{denominator})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is another name for @code{drem}.
+ @end deftypefun
+ 
+@@ -1561,6 +1637,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} copysignl (long double @var{x}, long double @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return @var{x} but with the sign of @var{y}.  They work
+ even if @var{x} or @var{y} are NaN or zero.  Both of these can carry a
+ sign (although not all implementations support it) and this is one of
+@@ -1576,6 +1653,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefun int signbit (@emph{float-type} @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{signbit} is a generic macro which can work on all floating-point
+ types.  It returns a nonzero value if the value of @var{x} has its sign
+ bit set.
+@@ -1594,6 +1672,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} nextafterl (long double @var{x}, long double @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{nextafter} function returns the next representable neighbor of
+ @var{x} in the direction towards @var{y}.  The size of the step between
+ @var{x} and the result depends on the type of the result.  If
+@@ -1617,6 +1696,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} nexttowardl (long double @var{x}, long double @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are identical to the corresponding versions of
+ @code{nextafter} except that their second argument is a @code{long
+ double}.
+@@ -1632,6 +1712,8 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} nanl (const char *@var{tagp})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c The unsafe-but-ruled-safe locale use comes from strtod.
+ The @code{nan} function returns a representation of NaN, provided that
+ NaN is supported by the target platform.
+ @code{nan ("@var{n-char-sequence}")} is equivalent to
+@@ -1666,6 +1748,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn Macro int isgreater (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro determines whether the argument @var{x} is greater than
+ @var{y}.  It is equivalent to @code{(@var{x}) > (@var{y})}, but no
+ exception is raised if @var{x} or @var{y} are NaN.
+@@ -1674,6 +1757,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn Macro int isgreaterequal (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro determines whether the argument @var{x} is greater than or
+ equal to @var{y}.  It is equivalent to @code{(@var{x}) >= (@var{y})}, but no
+ exception is raised if @var{x} or @var{y} are NaN.
+@@ -1682,6 +1766,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn Macro int isless (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro determines whether the argument @var{x} is less than @var{y}.
+ It is equivalent to @code{(@var{x}) < (@var{y})}, but no exception is
+ raised if @var{x} or @var{y} are NaN.
+@@ -1690,6 +1775,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn Macro int islessequal (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro determines whether the argument @var{x} is less than or equal
+ to @var{y}.  It is equivalent to @code{(@var{x}) <= (@var{y})}, but no
+ exception is raised if @var{x} or @var{y} are NaN.
+@@ -1698,6 +1784,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn Macro int islessgreater (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro determines whether the argument @var{x} is less or greater
+ than @var{y}.  It is equivalent to @code{(@var{x}) < (@var{y}) ||
+ (@var{x}) > (@var{y})} (although it only evaluates @var{x} and @var{y}
+@@ -1710,6 +1797,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefn Macro int isunordered (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro determines whether its arguments are unordered.  In other
+ words, it is true if @var{x} or @var{y} are NaN, and false otherwise.
+ @end deftypefn
+@@ -1743,6 +1831,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} fminl (long double @var{x}, long double @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fmin} function returns the lesser of the two values @var{x}
+ and @var{y}.  It is similar to the expression
+ @smallexample
+@@ -1763,6 +1852,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} fmaxl (long double @var{x}, long double @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fmax} function returns the greater of the two values @var{x}
+ and @var{y}.
+ 
+@@ -1779,6 +1869,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} fdiml (long double @var{x}, long double @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fdim} function returns the positive difference between
+ @var{x} and @var{y}.  The positive difference is @math{@var{x} -
+ @var{y}} if @var{x} is greater than @var{y}, and @math{0} otherwise.
+@@ -1796,6 +1887,7 @@
+ @comment ISO
+ @deftypefunx {long double} fmal (long double @var{x}, long double @var{y}, long double @var{z})
+ @cindex butterfly
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fma} function performs floating-point multiply-add.  This is
+ the operation @math{(@var{x} @mul{} @var{y}) + @var{z}}, but the
+ intermediate result is not rounded to the destination type.  This can
+@@ -1925,6 +2017,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {long double} creall (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the real part of the complex number @var{z}.
+ @end deftypefun
+ 
+@@ -1937,6 +2030,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {long double} cimagl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the imaginary part of the complex number @var{z}.
+ @end deftypefun
+ 
+@@ -1949,6 +2043,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} conjl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the conjugate value of the complex number
+ @var{z}.  The conjugate of a complex number has the same real part and a
+ negated imaginary part.  In other words, @samp{conj(a + bi) = a + -bi}.
+@@ -1963,6 +2058,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {long double} cargl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the argument of the complex number @var{z}.
+ The argument of a complex number is the angle in the complex plane
+ between the positive real axis and a line passing through zero and the
+@@ -1981,8 +2077,9 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} cprojl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the projection of the complex value @var{z} onto
+-the Riemann sphere.  Values with a infinite imaginary part are projected
++the Riemann sphere.  Values with an infinite imaginary part are projected
+ to positive infinity on the real axis, even if the real part is NaN.  If
+ the real part is infinite, the result is equivalent to
+ 
+@@ -2026,6 +2123,15 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun {long int} strtol (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c strtol uses the thread-local pointer to the locale in effect, and
++@c strtol_l loads the LC_NUMERIC locale data from it early on and once,
++@c but if the locale is the global locale, and another thread calls
++@c setlocale in a way that modifies the pointer to the LC_CTYPE locale
++@c category, the behavior of e.g. IS*, TOUPPER will vary throughout the
++@c execution of the function, because they re-read the locale data from
++@c the given locale pointer.  We solved this by documenting setlocale as
++@c MT-Unsafe.
+ The @code{strtol} (``string-to-long'') function converts the initial
+ part of @var{string} to a signed integer, which is returned as a value
+ of type @code{long int}.
+@@ -2089,6 +2195,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {long int} wcstol (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstol} function is equivalent to the @code{strtol} function
+ in nearly all aspects but handles wide character strings.
+ 
+@@ -2098,6 +2205,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun {unsigned long int} strtoul (const char *retrict @var{string}, char **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{strtoul} (``string-to-unsigned-long'') function is like
+ @code{strtol} except it converts to an @code{unsigned long int} value.
+ The syntax is the same as described above for @code{strtol}.  The value
+@@ -2116,6 +2224,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {unsigned long int} wcstoul (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstoul} function is equivalent to the @code{strtoul} function
+ in nearly all aspects but handles wide character strings.
+ 
+@@ -2125,6 +2234,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun {long long int} strtoll (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{strtoll} function is like @code{strtol} except that it returns
+ a @code{long long int} value, and accepts numbers with a correspondingly
+ larger range.
+@@ -2141,6 +2251,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {long long int} wcstoll (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstoll} function is equivalent to the @code{strtoll} function
+ in nearly all aspects but handles wide character strings.
+ 
+@@ -2150,12 +2261,14 @@
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun {long long int} strtoq (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ @code{strtoq} (``string-to-quad-word'') is the BSD name for @code{strtoll}.
+ @end deftypefun
+ 
+ @comment wchar.h
+ @comment GNU
+ @deftypefun {long long int} wcstoq (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstoq} function is equivalent to the @code{strtoq} function
+ in nearly all aspects but handles wide character strings.
+ 
+@@ -2165,6 +2278,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun {unsigned long long int} strtoull (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{strtoull} function is related to @code{strtoll} the same way
+ @code{strtoul} is related to @code{strtol}.
+ 
+@@ -2174,6 +2288,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {unsigned long long int} wcstoull (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstoull} function is equivalent to the @code{strtoull} function
+ in nearly all aspects but handles wide character strings.
+ 
+@@ -2183,12 +2298,14 @@
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun {unsigned long long int} strtouq (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ @code{strtouq} is the BSD name for @code{strtoull}.
+ @end deftypefun
+ 
+ @comment wchar.h
+ @comment GNU
+ @deftypefun {unsigned long long int} wcstouq (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstouq} function is equivalent to the @code{strtouq} function
+ in nearly all aspects but handles wide character strings.
+ 
+@@ -2198,6 +2315,7 @@
+ @comment inttypes.h
+ @comment ISO
+ @deftypefun intmax_t strtoimax (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{strtoimax} function is like @code{strtol} except that it returns
+ a @code{intmax_t} value, and accepts numbers of a corresponding range.
+ 
+@@ -2214,6 +2332,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun intmax_t wcstoimax (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstoimax} function is equivalent to the @code{strtoimax} function
+ in nearly all aspects but handles wide character strings.
+ 
+@@ -2223,6 +2342,7 @@
+ @comment inttypes.h
+ @comment ISO
+ @deftypefun uintmax_t strtoumax (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{strtoumax} function is related to @code{strtoimax}
+ the same way that @code{strtoul} is related to @code{strtol}.
+ 
+@@ -2233,6 +2353,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun uintmax_t wcstoumax (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstoumax} function is equivalent to the @code{strtoumax} function
+ in nearly all aspects but handles wide character strings.
+ 
+@@ -2242,6 +2363,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun {long int} atol (const char *@var{string})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ This function is similar to the @code{strtol} function with a @var{base}
+ argument of @code{10}, except that it need not detect overflow errors.
+ The @code{atol} function is provided mostly for compatibility with
+@@ -2251,6 +2373,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun int atoi (const char *@var{string})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ This function is like @code{atol}, except that it returns an @code{int}.
+ The @code{atoi} function is also considered obsolete; use @code{strtol}
+ instead.
+@@ -2259,6 +2382,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun {long long int} atoll (const char *@var{string})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ This function is similar to @code{atol}, except it returns a @code{long
+ long int}.
+ 
+@@ -2323,6 +2447,35 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun double strtod (const char *restrict @var{string}, char **restrict @var{tailptr})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c Besides the unsafe-but-ruled-safe locale uses, this uses a lot of
++@c mpn, but it's all safe.
++@c
++@c round_and_return
++@c   get_rounding_mode ok
++@c   mpn_add_1 ok
++@c   mpn_rshift ok
++@c   MPN_ZERO ok
++@c   MPN2FLOAT -> mpn_construct_(float|double|long_double) ok
++@c str_to_mpn
++@c   mpn_mul_1 -> umul_ppmm ok
++@c   mpn_add_1 ok
++@c mpn_lshift_1 -> mpn_lshift ok
++@c STRTOF_INTERNAL
++@c   MPN_VAR ok
++@c   SET_MANTISSA ok
++@c   STRNCASECMP ok, wide and narrow
++@c   round_and_return ok
++@c   mpn_mul ok
++@c     mpn_addmul_1 ok
++@c     ... mpn_sub
++@c   mpn_lshift ok
++@c   udiv_qrnnd ok
++@c   count_leading_zeros ok
++@c   add_ssaaaa ok
++@c   sub_ddmmss ok
++@c   umul_ppmm ok
++@c   mpn_submul_1 ok
+ The @code{strtod} (``string-to-double'') function converts the initial
+ part of @var{string} to a floating-point number, which is returned as a
+ value of type @code{double}.
+@@ -2408,6 +2561,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefunx {long double} strtold (const char *@var{string}, char **@var{tailptr})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ These functions are analogous to @code{strtod}, but return @code{float}
+ and @code{long double} values respectively.  They report errors in the
+ same way as @code{strtod}.  @code{strtof} can be substantially faster
+@@ -2427,6 +2581,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefunx {long double} wcstold (const wchar_t *@var{string}, wchar_t **@var{tailptr})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ The @code{wcstod}, @code{wcstof}, and @code{wcstol} functions are
+ equivalent in nearly all aspect to the @code{strtod}, @code{strtof}, and
+ @code{strtold} functions but it handles wide character string.
+@@ -2439,6 +2594,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun double atof (const char *@var{string})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ This function is similar to the @code{strtod} function, except that it
+ need not detect overflow and underflow errors.  The @code{atof} function
+ is provided mostly for compatibility with existing code; using
+@@ -2447,7 +2603,8 @@
+ 
+ @Theglibc{} also provides @samp{_l} versions of these functions,
+ which take an additional argument, the locale to use in conversion.
+-@xref{Parsing of Integers}.
++
++See also @ref{Parsing of Integers}.
+ 
+ @node System V Number Conversion
+ @section Old-fashioned System V number-to-string functions
+@@ -2465,9 +2622,10 @@
+ @comment stdlib.h
+ @comment SVID, Unix98
+ @deftypefun {char *} ecvt (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
++@safety{@prelim{}@mtunsafe{@mtasurace{:ecvt}}@asunsafe{}@acsafe{}}
+ The function @code{ecvt} converts the floating-point number @var{value}
+ to a string with at most @var{ndigit} decimal digits.  The
+-returned string contains no decimal point or sign. The first digit of
++returned string contains no decimal point or sign.  The first digit of
+ the string is non-zero (unless @var{value} is actually zero) and the
+ last digit is rounded to nearest.  @code{*@var{decpt}} is set to the
+ index in the string of the first digit after the decimal point.
+@@ -2490,6 +2648,7 @@
+ @comment stdlib.h
+ @comment SVID, Unix98
+ @deftypefun {char *} fcvt (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
++@safety{@prelim{}@mtunsafe{@mtasurace{:fcvt}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The function @code{fcvt} is like @code{ecvt}, but @var{ndigit} specifies
+ the number of digits after the decimal point.  If @var{ndigit} is less
+ than zero, @var{value} is rounded to the @math{@var{ndigit}+1}'th place to the
+@@ -2508,6 +2667,9 @@
+ @comment stdlib.h
+ @comment SVID, Unix98
+ @deftypefun {char *} gcvt (double @var{value}, int @var{ndigit}, char *@var{buf})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c gcvt calls sprintf, that ultimately calls vfprintf, which malloc()s
++@c args_value if it's too large, but gcvt never exercises this path.
+ @code{gcvt} is functionally equivalent to @samp{sprintf(buf, "%*g",
+ ndigit, value}.  It is provided only for compatibility's sake.  It
+ returns @var{buf}.
+@@ -2522,6 +2684,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun {char *} qecvt (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
++@safety{@prelim{}@mtunsafe{@mtasurace{:qecvt}}@asunsafe{}@acsafe{}}
+ This function is equivalent to @code{ecvt} except that it takes a
+ @code{long double} for the first parameter and that @var{ndigit} is
+ restricted by the precision of a @code{long double}.
+@@ -2530,6 +2693,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun {char *} qfcvt (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
++@safety{@prelim{}@mtunsafe{@mtasurace{:qfcvt}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This function is equivalent to @code{fcvt} except that it
+ takes a @code{long double} for the first parameter and that @var{ndigit} is
+ restricted by the precision of a @code{long double}.
+@@ -2538,6 +2702,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun {char *} qgcvt (long double @var{value}, int @var{ndigit}, char *@var{buf})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is equivalent to @code{gcvt} except that it takes a
+ @code{long double} for the first parameter and that @var{ndigit} is
+ restricted by the precision of a @code{long double}.
+@@ -2558,6 +2723,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int ecvt_r (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{ecvt_r} function is the same as @code{ecvt}, except
+ that it places its result into the user-specified buffer pointed to by
+ @var{buf}, with length @var{len}.  The return value is @code{-1} in
+@@ -2569,6 +2735,7 @@
+ @comment stdlib.h
+ @comment SVID, Unix98
+ @deftypefun int fcvt_r (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fcvt_r} function is the same as @code{fcvt}, except that it
+ places its result into the user-specified buffer pointed to by
+ @var{buf}, with length @var{len}.  The return value is @code{-1} in
+@@ -2580,6 +2747,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int qecvt_r (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{qecvt_r} function is the same as @code{qecvt}, except
+ that it places its result into the user-specified buffer pointed to by
+ @var{buf}, with length @var{len}.  The return value is @code{-1} in
+@@ -2591,6 +2759,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int qfcvt_r (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{qfcvt_r} function is the same as @code{qfcvt}, except
+ that it places its result into the user-specified buffer pointed to by
+ @var{buf}, with length @var{len}.  The return value is @code{-1} in
+diff -urN glibc-2.17-c758a686/manual/charset.texi glibc/manual/charset.texi
+--- glibc-2.17-c758a686/manual/charset.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/charset.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -504,6 +504,14 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int mbsinit (const mbstate_t *@var{ps})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c ps is dereferenced once, unguarded.  This would call for @mtsrace:ps,
++@c but since a single word-sized field is (atomically) accessed, any
++@c race here would be harmless.  Other functions that take an optional
++@c mbstate_t* argument named ps are marked with @mtasurace:<func>/!ps,
++@c to indicate that the function uses a static buffer if ps is NULL.
++@c These could also have been marked with @mtsrace:ps, but we'll omit
++@c that for brevity, for it's somewhat redundant with the @mtasurace.
+ The @code{mbsinit} function determines whether the state object pointed
+ to by @var{ps} is in the initial state.  If @var{ps} is a null pointer or
+ the object is in the initial state the return value is nonzero.  Otherwise
+@@ -559,6 +567,14 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun wint_t btowc (int @var{c})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c Calls btowc_fct or __fct; reads from locale, and from the
++@c get_gconv_fcts result multiple times.  get_gconv_fcts calls
++@c __wcsmbs_load_conv to initialize the ctype if it's null.
++@c wcsmbs_load_conv takes a non-recursive wrlock before allocating
++@c memory for the fcts structure, initializing it, and then storing it
++@c in the locale object.  The initialization involves dlopening and a
++@c lot more.
+ The @code{btowc} function (``byte to wide character'') converts a valid
+ single byte character @var{c} in the initial shift state into the wide
+ character equivalent using the conversion rules from the currently
+@@ -615,6 +631,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int wctob (wint_t @var{c})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{wctob} function (``wide character to byte'') takes as the
+ parameter a valid wide character.  If the multibyte representation for
+ this character in the initial state is exactly one byte long, the return
+@@ -634,6 +651,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t mbrtowc (wchar_t *restrict @var{pwc}, const char *restrict @var{s}, size_t @var{n}, mbstate_t *restrict @var{ps})
++@safety{@prelim{}@mtunsafe{@mtasurace{:mbrtowc/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ @cindex stateful
+ The @code{mbrtowc} function (``multibyte restartable to wide
+ character'') converts the next multibyte character in the string pointed
+@@ -728,6 +746,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t mbrlen (const char *restrict @var{s}, size_t @var{n}, mbstate_t *@var{ps})
++@safety{@prelim{}@mtunsafe{@mtasurace{:mbrlen/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{mbrlen} function (``multibyte restartable length'') computes
+ the number of at most @var{n} bytes starting at @var{s}, which form the
+ next valid and complete multibyte character.
+@@ -786,7 +805,7 @@
+ This function simply calls @code{mbrlen} for each multibyte character
+ in the string and counts the number of function calls.  Please note that
+ we here use @code{MB_LEN_MAX} as the size argument in the @code{mbrlen}
+-call.  This is acceptable since a) this value is larger then the length of
++call.  This is acceptable since a) this value is larger than the length of
+ the longest multibyte character sequence and b) we know that the string
+ @var{s} ends with a NUL byte, which cannot be part of any other multibyte
+ character sequence but the one representing the NUL wide character.
+@@ -811,6 +830,50 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t wcrtomb (char *restrict @var{s}, wchar_t @var{wc}, mbstate_t *restrict @var{ps})
++@safety{@prelim{}@mtunsafe{@mtasurace{:wcrtomb/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c wcrtomb uses a static, non-thread-local unguarded state variable when
++@c PS is NULL.  When a state is passed in, and it's not used
++@c concurrently in other threads, this function behaves safely as long
++@c as gconv modules don't bring MT safety issues of their own.
++@c Attempting to load gconv modules or to build conversion chains in
++@c signal handlers may encounter gconv databases or caches in a
++@c partially-updated state, and asynchronous cancellation may leave them
++@c in such states, besides leaking the lock that guards them.
++@c get_gconv_fcts ok
++@c    wcsmbs_load_conv ok
++@c      norm_add_slashes ok
++@c      wcsmbs_getfct ok
++@c        gconv_find_transform ok
++@c          gconv_read_conf (libc_once)
++@c          gconv_lookup_cache ok
++@c            find_module_idx ok
++@c            find_module ok
++@c              gconv_find_shlib (ok)
++@c              ->init_fct (assumed ok)
++@c            gconv_get_builtin_trans ok
++@c            gconv_release_step ok
++@c          do_lookup_alias ok
++@c          find_derivation ok
++@c            derivation_lookup ok
++@c            increment_counter ok
++@c              gconv_find_shlib ok
++@c              step->init_fct (assumed ok)
++@c            gen_steps ok
++@c              gconv_find_shlib ok
++@c                dlopen (presumed ok)
++@c                dlsym (presumed ok)
++@c              step->init_fct (assumed ok)
++@c              step->end_fct (assumed ok)
++@c              gconv_get_builtin_trans ok
++@c              gconv_release_step ok
++@c            add_derivation ok
++@c      gconv_close_transform ok
++@c        gconv_release_step ok
++@c          step->end_fct (assumed ok)
++@c          gconv_release_shlib ok
++@c            dlclose (presumed ok)
++@c        gconv_release_cache ok
++@c  ->tomb->__fct (assumed ok)
+ The @code{wcrtomb} function (``wide character restartable to
+ multibyte'') converts a single wide character into a multibyte string
+ corresponding to that wide character.
+@@ -955,8 +1018,9 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t mbsrtowcs (wchar_t *restrict @var{dst}, const char **restrict @var{src}, size_t @var{len}, mbstate_t *restrict @var{ps})
++@safety{@prelim{}@mtunsafe{@mtasurace{:mbsrtowcs/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{mbsrtowcs} function (``multibyte string restartable to wide
+-character string'') converts an NUL-terminated multibyte character
++character string'') converts a NUL-terminated multibyte character
+ string at @code{*@var{src}} into an equivalent wide character string,
+ including the NUL wide character at the end.  The conversion is started
+ using the state information from the object pointed to by @var{ps} or
+@@ -1039,6 +1103,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t wcsrtombs (char *restrict @var{dst}, const wchar_t **restrict @var{src}, size_t @var{len}, mbstate_t *restrict @var{ps})
++@safety{@prelim{}@mtunsafe{@mtasurace{:wcsrtombs/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{wcsrtombs} function (``wide character string restartable to
+ multibyte string'') converts the NUL-terminated wide character string at
+ @code{*@var{src}} into an equivalent multibyte character string and
+@@ -1084,6 +1149,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun size_t mbsnrtowcs (wchar_t *restrict @var{dst}, const char **restrict @var{src}, size_t @var{nmc}, size_t @var{len}, mbstate_t *restrict @var{ps})
++@safety{@prelim{}@mtunsafe{@mtasurace{:mbsnrtowcs/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{mbsnrtowcs} function is very similar to the @code{mbsrtowcs}
+ function.  All the parameters are the same except for @var{nmc}, which is
+ new.  The return value is the same as for @code{mbsrtowcs}.
+@@ -1136,6 +1202,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun size_t wcsnrtombs (char *restrict @var{dst}, const wchar_t **restrict @var{src}, size_t @var{nwc}, size_t @var{len}, mbstate_t *restrict @var{ps})
++@safety{@prelim{}@mtunsafe{@mtasurace{:wcsnrtombs/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{wcsnrtombs} function implements the conversion from wide
+ character strings to multibyte character strings.  It is similar to
+ @code{wcsrtombs} but, just like @code{mbsnrtowcs}, it takes an extra
+@@ -1280,6 +1347,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun int mbtowc (wchar_t *restrict @var{result}, const char *restrict @var{string}, size_t @var{size})
++@safety{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{mbtowc} (``multibyte to wide character'') function when called
+ with non-null @var{string} converts the first multibyte character
+ beginning at @var{string} to its corresponding wide character code.  It
+@@ -1314,6 +1382,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun int wctomb (char *@var{string}, wchar_t @var{wchar})
++@safety{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{wctomb} (``wide character to multibyte'') function converts
+ the wide character code @var{wchar} to its corresponding multibyte
+ character sequence, and stores the result in bytes starting at
+@@ -1353,6 +1422,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun int mblen (const char *@var{string}, size_t @var{size})
++@safety{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{mblen} function with a non-null @var{string} argument returns
+ the number of bytes that make up the multibyte character beginning at
+ @var{string}, never examining more than @var{size} bytes.  (The idea is
+@@ -1391,6 +1461,9 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun size_t mbstowcs (wchar_t *@var{wstring}, const char *@var{string}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c Odd...  Although this was supposed to be non-reentrant, the internal
++@c state is not a static buffer, but an automatic variable.
+ The @code{mbstowcs} (``multibyte string to wide character string'')
+ function converts the null-terminated string of multibyte characters
+ @var{string} to an array of wide character codes, storing not more than
+@@ -1431,6 +1504,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun size_t wcstombs (char *@var{string}, const wchar_t *@var{wstring}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+ The @code{wcstombs} (``wide character string to multibyte string'')
+ function converts the null-terminated wide character array @var{wstring}
+ into a string containing multibyte characters, storing not more than
+@@ -1618,6 +1692,16 @@
+ @comment iconv.h
+ @comment XPG2
+ @deftypefun iconv_t iconv_open (const char *@var{tocode}, const char *@var{fromcode})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c Calls malloc if tocode and/or fromcode are too big for alloca.  Calls
++@c strip and upstr on both, then gconv_open.  strip and upstr call
++@c isalnum_l and toupper_l with the C locale.  gconv_open may MT-safely
++@c tokenize toset, replace unspecified codesets with the current locale
++@c (possibly two different accesses), and finally it calls
++@c gconv_find_transform and initializes the gconv_t result with all the
++@c steps in the conversion sequence, running each one's initializer,
++@c destructing and releasing them all if anything fails.
++
+ The @code{iconv_open} function has to be used before starting a
+ conversion.  The two parameters this function takes determine the
+ source and destination character set for the conversion, and if the
+@@ -1625,7 +1709,7 @@
+ function returns a handle.
+ 
+ If the wanted conversion is not available, the @code{iconv_open} function
+-returns @code{(iconv_t) -1}. In this case the global variable
++returns @code{(iconv_t) -1}.  In this case the global variable
+ @code{errno} can have the following values:
+ 
+ @table @code
+@@ -1682,6 +1766,12 @@
+ @comment iconv.h
+ @comment XPG2
+ @deftypefun int iconv_close (iconv_t @var{cd})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c Calls gconv_close to destruct and release each of the conversion
++@c steps, release the gconv_t object, then call gconv_close_transform.
++@c Access to the gconv_t object is not guarded, but calling iconv_close
++@c concurrently with any other use is undefined.
++
+ The @code{iconv_close} function frees all resources associated with the
+ handle @var{cd}, which must have been returned by a successful call to
+ the @code{iconv_open} function.
+@@ -1708,6 +1798,10 @@
+ @comment iconv.h
+ @comment XPG2
+ @deftypefun size_t iconv (iconv_t @var{cd}, char **@var{inbuf}, size_t *@var{inbytesleft}, char **@var{outbuf}, size_t *@var{outbytesleft})
++@safety{@prelim{}@mtsafe{@mtsrace{:cd}}@assafe{}@acunsafe{@acucorrupt{}}}
++@c Without guarding access to the iconv_t object pointed to by cd, call
++@c the conversion function to convert inbuf or flush the internal
++@c conversion state.
+ @cindex stateful
+ The @code{iconv} function converts the text in the input buffer
+ according to the rules associated with the descriptor @var{cd} and
+@@ -1744,7 +1838,7 @@
+ Therefore an @code{iconv} call to reset the state should always be
+ performed if some protocol requires this for the output text.
+ 
+-The conversion stops for one of three reasons. The first is that all
++The conversion stops for one of three reasons.  The first is that all
+ characters from the input buffer are converted.  This actually can mean
+ two things: either all bytes from the input buffer are consumed or
+ there are some bytes at the end of the buffer that possibly can form a
+@@ -2039,7 +2133,7 @@
+ 
+ Unfortunately, the answer is: there is no general solution.  On some
+ systems guessing might help.  On those systems most character sets can
+-convert to and from UTF-8 encoded @w{ISO 10646} or Unicode text. Beside
++convert to and from UTF-8 encoded @w{ISO 10646} or Unicode text.  Beside
+ this only some very system-specific methods can help.  Since the
+ conversion functions come from loadable modules and these modules must
+ be stored somewhere in the filesystem, one @emph{could} try to find them
+@@ -2239,7 +2333,7 @@
+ 
+ So far this section has described how modules are located and considered
+ to be used.  What remains to be described is the interface of the modules
+-so that one can write new ones. This section describes the interface as
++so that one can write new ones.  This section describes the interface as
+ it is in use in January 1999.  The interface will change a bit in the
+ future but, with luck, only in an upwardly compatible way.
+ 
+@@ -2485,7 +2579,7 @@
+ same size, the minimum and maximum values are the same.
+ 
+ @item __stateful
+-This element must be initialized to an nonzero value if the source
++This element must be initialized to a nonzero value if the source
+ character set is stateful.  Otherwise it must be zero.
+ @end table
+ 
+@@ -2824,7 +2918,7 @@
+           /* @r{Run the conversion loop.  @code{status} is set}
+              @r{appropriately afterwards.}  */
+ 
+-          /* @r{If this is the last step, leave the loop. There is}
++          /* @r{If this is the last step, leave the loop.  There is}
+              @r{nothing we can do.}  */
+           if (data->__is_last)
+             @{
+diff -urN glibc-2.17-c758a686/manual/check-safety.sh glibc/manual/check-safety.sh
+--- glibc-2.17-c758a686/manual/check-safety.sh	1969-12-31 19:00:00.000000000 -0500
++++ glibc/manual/check-safety.sh	2014-09-12 16:10:06.044792719 -0400
+@@ -0,0 +1,119 @@
++#! /bin/sh
++
++# Copyright 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/>.
++
++
++# Check that the @safety notes are self-consistent, i.e., that they're
++# in proper order (mt then as then ac), that remarks appear within
++# corresponding sections (mt within mt, etc), that unsafety always has
++# an explicit reason and when there's a reason for unsafety it's not
++# safe, and that there aren't duplicates remarks.
++
++
++success=:
++
++# If no arguments are given, take all *.texi files in the current directory.
++test $# != 0 || set *.texi
++
++# Check that all safety remarks have entries for all of MT, AS and AC,
++# in this order, with an optional prelim note before them.
++grep -n '^@safety' "$@" |
++grep -v ':@safety{\(@prelim{}\)\?@mt\(un\)\?safe{.*}'\
++'@as\(un\)\?safe{.*}@ac\(un\)\?safe{.*}}' &&
++success=false
++
++# Check that @mt-started notes appear within @mtsafe or @mtunsafe,
++# that @as-started notes appear within @assafe or @asunsafe, and that
++# @ac-started notes appear within @acsafe or @acunsafe.  Also check
++# that @mt, @as and @ac are followed by an s (for safe) or u (for
++# unsafe), but let @mt have as, ac or asc before [su], and let @as
++# have a c (for cancel) before [su].  Also make sure blanks separate
++# each of the annotations.
++grep -n '^@safety' "$@" |
++grep -v ':@safety{\(@prelim{}\)\?'\
++'@mt\(un\)\?safe{\(@mt\(asc\?\|ac\)\?[su][^ ]*}\)\?'\
++'\( @mt\(asc\?\|ac\)\?[su][^ ]*}\)*}'\
++'@as\(un\)\?safe{\(@asc\?[su][^ ]*}\)\?'\
++'\( @asc\?[su][^ ]*}\)*}'\
++'@ac\(un\)\?safe{\(@ac[su][^ ]*}\)\?'\
++'\( @ac[su][^ ]*}\)*}}' &&
++success=false
++
++# Make sure safety lines marked as @mtsafe do not contain any
++# MT-Unsafe remark; that would be @mtu, but there could be as, ac or
++# asc between mt and u.
++grep -n '^@safety.*@mtsafe' "$@" |
++grep '@mt\(asc\?\|ac\)?u' "$@" &&
++success=false
++
++# Make sure @mtunsafe lines contain at least one @mtu remark (with
++# optional as, ac or asc between mt and u).
++grep -n '^@safety.*@mtunsafe' "$@" |
++grep -v '@mtunsafe{.*@mt\(asc\?\|ac\)\?u' &&
++success=false
++
++# Make sure safety lines marked as @assafe do not contain any AS-Unsafe
++# remark, which could be @asu or @mtasu note (with an optional c
++# between as and u in both cases).
++grep -n '^@safety.*@assafe' "$@" |
++grep '@\(mt\)\?asc\?u' &&
++success=false
++
++# Make sure @asunsafe lines contain at least one @asu remark (which
++# could be @ascu, or @mtasu or even @mtascu).
++grep -n '^@safety.*@asunsafe' "$@" |
++grep -v '@mtasc\?u.*@asunsafe\|@asunsafe{.*@asc\?u' &&
++success=false
++
++# Make sure safety lines marked as @acsafe do not contain any
++# AC-Unsafe remark, which could be @acu, @ascu or even @mtacu or
++# @mtascu.
++grep -n '^@safety.*@acsafe' "$@" |
++grep '@\(mt\)\?as\?cu' &&
++success=false
++
++# Make sure @acunsafe lines contain at least one @acu remark (possibly
++# implied by @ascu, @mtacu or @mtascu).
++grep -n '^@safety.*@acunsafe' "$@" |
++grep -v '@\(mtas\?\|as\)cu.*@acunsafe\|@acunsafe{.*@acu' &&
++success=false
++
++# Make sure there aren't duplicate remarks in the same safety note.
++grep -n '^@safety' "$@" |
++grep '[^:]\(@\(mt\|a[sc]\)[^ {]*{[^ ]*}\).*[^:]\1' &&
++success=false
++
++# Check that comments containing safety remarks do not contain {}s,
++# that all @mt remarks appear before @as remarks, that in turn appear
++# before @ac remarks, all properly blank-separated, and that an
++# optional comment about exclusions is between []s at the end of the
++# line.
++grep -n '^@c \+[^@ ]\+\( dup\)\?'\
++'\( @\(mt\|a[sc]\)[^ ]*\)*\( \[.*\]\)\?$' "$@" |
++grep -v ':@c *[^@{}]*\( @mt[^ {}]*\)*'\
++'\( @as[^ {}]*\)*\( @ac[^ {}]*\)*\( \[.*\]\)\?$' &&
++success=false
++
++# Check that comments containing safety remarks do not contain
++# duplicate remarks.
++grep -n '^@c \+[^@ ]\+\( dup\)\?'\
++'\( @\(mt\|a[sc]\)[^ ]*\)*\( \[.*\]\)\?$' "$@" |
++grep '[^:]\(@\(mt\|a[sc]\)[^ ]*\) \(.*[^:]\)\?\1\($\| \)' &&
++success=false
++
++$success
+diff -urN glibc-2.17-c758a686/manual/conf.texi glibc/manual/conf.texi
+--- glibc-2.17-c758a686/manual/conf.texi	2014-09-12 16:08:17.965070383 -0400
++++ glibc/manual/conf.texi	2014-09-12 16:10:06.047792712 -0400
+@@ -114,7 +114,7 @@
+ 
+ @comment limits.h
+ @comment POSIX.1
+-@deftypevr Macro int SSIZE_MAX
++@deftypevr Macro ssize_t SSIZE_MAX
+ The largest value that can fit in an object of type @code{ssize_t}.
+ Effectively, this is the limit on the number of bytes that can be read
+ or written in a single operation.
+@@ -288,6 +288,17 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun {long int} sysconf (int @var{parameter})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c Some parts of the implementation open /proc and /sys files and dirs
++@c to collect system details, using fd and stream I/O depending on the
++@c case.  _SC_TZNAME_MAX calls __tzname_max, that (while holding a lock)
++@c calls tzset_internal, that calls getenv if it's called the first
++@c time; there are free and strdup calls in there too.  The returned max
++@c value may change over time for TZNAME_MAX, depending on selected
++@c timezones; NPROCS, NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES,
++@c NGROUPS_MAX, SIGQUEUE_MAX, depending on variable values read from
++@c /proc at each call, and from rlimit-obtained values CHILD_MAX,
++@c OPEN_MAX, ARG_MAX, SIGQUEUE_MAX.
+ This function is used to inquire about runtime system parameters.  The
+ @var{parameter} argument should be one of the @samp{_SC_} symbols listed
+ below.
+@@ -1121,7 +1132,7 @@
+ have on @emph{any} POSIX system.  @xref{File Minimums}.
+ 
+ @cindex limits, link count of files
+-@comment limits.h
++@comment limits.h (optional)
+ @comment POSIX.1
+ @deftypevr Macro int LINK_MAX
+ The uniform system limit (if any) for the number of names for a given
+@@ -1348,6 +1359,11 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun {long int} pathconf (const char *@var{filename}, int @var{parameter})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c When __statfs_link_max finds an ext* filesystem, it may read
++@c /proc/mounts or similar as a mntent stream.
++@c __statfs_chown_restricted may read from
++@c /proc/sys/fs/xfs/restrict_chown as a file descriptor.
+ This function is used to inquire about the limits that apply to
+ the file named @var{filename}.
+ 
+@@ -1375,6 +1391,8 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun {long int} fpathconf (int @var{filedes}, int @var{parameter})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c Same caveats as pathconf.
+ This is just like @code{pathconf} except that an open file descriptor
+ is used to specify the file for which information is requested, instead
+ of a file name.
+@@ -1624,6 +1642,7 @@
+ @comment unistd.h
+ @comment POSIX.2
+ @deftypefun size_t confstr (int @var{parameter}, char *@var{buf}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function reads the value of a string-valued system parameter,
+ storing the string into @var{len} bytes of memory space starting at
+ @var{buf}.  The @var{parameter} argument should be one of the
+diff -urN glibc-2.17-c758a686/manual/crypt.texi glibc/manual/crypt.texi
+--- glibc-2.17-c758a686/manual/crypt.texi	2014-09-12 16:08:18.169069859 -0400
++++ glibc/manual/crypt.texi	2014-09-12 16:10:06.042792724 -0400
+@@ -30,15 +30,15 @@
+ and the other based on the Data Encryption Standard (DES) that is
+ compatible with Unix systems.
+ 
+-@cindex AUTH_DES
++@vindex AUTH_DES
+ @cindex FIPS 140-2
+ It also provides support for Secure RPC, and some library functions that
+-can be used to perform normal DES encryption. The use of DES when
+-using @code{AUTH_DES} in Secure RPC for authentication as provided by
+-@theglibc{} is not FIPS 140-2 compliant nor is any other use of DES
+-within @theglibc{}. It is recommended that Secure RPC should not be used
+-for systems that need to be FIPS 140-2 compliant since all forms of
+-supported authentication use normal DES.
++can be used to perform normal DES encryption.  The @code{AUTH_DES}
++authentication flavor in Secure RPC, as provided by @theglibc{},
++uses DES and does not comply with FIPS 140-2 nor does any other use of DES
++within @theglibc{}.  It is recommended that Secure RPC should not be used
++for systems that need to comply with FIPS 140-2 since all flavors of
++encrypted authentication use normal DES.
+ 
+ @menu
+ * Legal Problems::              This software can get you locked up, or worse.
+@@ -99,6 +99,13 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun {char *} getpass (const char *@var{prompt})
++@safety{@prelim{}@mtunsafe{@mtasuterm{}}@asunsafe{@ascuheap{} @asulock{} @asucorrupt{}}@acunsafe{@acuterm{} @aculock{} @acucorrupt{}}}
++@c This function will attempt to create a stream for terminal I/O, but
++@c will fallback to stdio/stderr.  It attempts to change the terminal
++@c mode in a thread-unsafe way, write out the prompt, read the password,
++@c then restore the terminal mode.  It has a cleanup to close the stream
++@c in case of (synchronous) cancellation, but not to restore the
++@c terminal mode.
+ 
+ @code{getpass} outputs @var{prompt}, then reads a string in from the
+ terminal without echoing it.  It tries to connect to the real terminal,
+@@ -134,6 +141,13 @@
+ @comment crypt.h
+ @comment BSD, SVID
+ @deftypefun {char *} crypt (const char *@var{key}, const char *@var{salt})
++@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
++@c Besides the obvious problem of returning a pointer into static
++@c storage, the DES initializer takes an internal lock with the usual
++@c set of problems for AS- and AC-Safety.  The FIPS mode checker and the
++@c NSS implementations of may leak file descriptors if canceled.  The
++@c The MD5, SHA256 and SHA512 implementations will malloc on long keys,
++@c and NSS relies on dlopening, which brings about another can of worms.
+ 
+ The @code{crypt} function takes a password, @var{key}, as a string, and
+ a @var{salt} character array which is described below, and returns a
+@@ -195,6 +209,9 @@
+ @comment crypt.h
+ @comment GNU
+ @deftypefun {char *} crypt_r (const char *@var{key}, const char *@var{salt}, {struct crypt_data *} @var{data})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
++@c Compared with crypt, this function fixes the @mtasurace:crypt
++@c problem, but nothing else.
+ 
+ The @code{crypt_r} function does the same thing as @code{crypt}, but
+ takes an extra parameter which includes space for its result (among
+@@ -241,6 +258,11 @@
+ @comment crypt.h
+ @comment BSD, SVID
+ @deftypefun void setkey (const char *@var{key})
++@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
++@c The static buffer stores the key, making it fundamentally
++@c thread-unsafe.  The locking issues are only in the initialization
++@c path; cancelling the initialization will leave the lock held, it
++@c would otherwise repeat the initialization on the next call.
+ 
+ The @code{setkey} function sets an internal data structure to be an
+ expanded form of @var{key}.  @var{key} is specified as an array of 64
+@@ -252,6 +274,8 @@
+ @comment crypt.h
+ @comment BSD, SVID
+ @deftypefun void encrypt (char *@var{block}, int @var{edflag})
++@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
++@c Same issues as setkey.
+ 
+ The @code{encrypt} function encrypts @var{block} if
+ @var{edflag} is 0, otherwise it decrypts @var{block}, using a key
+@@ -265,9 +289,11 @@
+ @comment crypt.h
+ @comment GNU
+ @deftypefun void setkey_r (const char *@var{key}, {struct crypt_data *} @var{data})
++@c @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
+ @comment crypt.h
+ @comment GNU
+ @deftypefunx void encrypt_r (char *@var{block}, int @var{edflag}, {struct crypt_data *} @var{data})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
+ 
+ These are reentrant versions of @code{setkey} and @code{encrypt}.  The
+ only difference is the extra parameter, which stores the expanded
+@@ -282,6 +308,7 @@
+ @comment rpc/des_crypt.h
+ @comment SUNRPC
+ @deftypefun int ecb_crypt (char *@var{key}, char *@var{blocks}, unsigned @var{len}, unsigned @var{mode})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ The function @code{ecb_crypt} encrypts or decrypts one or more blocks
+ using DES.  Each block is encrypted independently.
+@@ -356,6 +383,7 @@
+ @comment rpc/des_crypt.h
+ @comment SUNRPC
+ @deftypefun int DES_FAILED (int @var{err})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns 1 if @var{err} is a `success' result code from
+ @code{ecb_crypt} or @code{cbc_crypt}, and 0 otherwise.
+ @end deftypefun
+@@ -363,6 +391,7 @@
+ @comment rpc/des_crypt.h
+ @comment SUNRPC
+ @deftypefun int cbc_crypt (char *@var{key}, char *@var{blocks}, unsigned @var{len}, unsigned @var{mode}, char *@var{ivec})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ The function @code{cbc_crypt} encrypts or decrypts one or more blocks
+ using DES in Cipher Block Chaining mode.
+@@ -389,6 +418,7 @@
+ @comment rpc/des_crypt.h
+ @comment SUNRPC
+ @deftypefun void des_setparity (char *@var{key})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ The function @code{des_setparity} changes the 64-bit @var{key}, stored
+ packed in 8-bit bytes, to have odd parity by altering the low bits of
+diff -urN glibc-2.17-c758a686/manual/ctype.texi glibc/manual/ctype.texi
+--- glibc-2.17-c758a686/manual/ctype.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/ctype.texi	2014-09-12 16:10:06.042792724 -0400
+@@ -66,6 +66,16 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int islower (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c The is* macros call __ctype_b_loc to get the ctype array from the
++@c current locale, and then index it by c.  __ctype_b_loc reads from
++@c thread-local memory the (indirect) pointer to the ctype array, which
++@c may involve one word access to the global locale object, if that's
++@c the active locale for the thread, and the array, being part of the
++@c locale data, is undeletable, so there's no thread-safety issue.  We
++@c might want to mark these with @mtslocale to flag to callers that
++@c changing locales might affect them, even if not these simpler
++@c functions.
+ Returns true if @var{c} is a lower-case letter.  The letter need not be
+ from the Latin alphabet, any alphabet representable is valid.
+ @end deftypefun
+@@ -74,6 +84,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isupper (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is an upper-case letter.  The letter need not be
+ from the Latin alphabet, any alphabet representable is valid.
+ @end deftypefun
+@@ -82,6 +93,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isalpha (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is an alphabetic character (a letter).  If
+ @code{islower} or @code{isupper} is true of a character, then
+ @code{isalpha} is also true.
+@@ -97,6 +109,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isdigit (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a decimal digit (@samp{0} through @samp{9}).
+ @end deftypefun
+ 
+@@ -104,6 +117,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isalnum (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is an alphanumeric character (a letter or
+ number); in other words, if either @code{isalpha} or @code{isdigit} is
+ true of a character, then @code{isalnum} is also true.
+@@ -113,6 +127,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isxdigit (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a hexadecimal digit.
+ Hexadecimal digits include the normal decimal digits @samp{0} through
+ @samp{9} and the letters @samp{A} through @samp{F} and
+@@ -123,6 +138,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int ispunct (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a punctuation character.
+ This means any printing character that is not alphanumeric or a space
+ character.
+@@ -132,6 +148,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isspace (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a @dfn{whitespace} character.  In the standard
+ @code{"C"} locale, @code{isspace} returns true for only the standard
+ whitespace characters:
+@@ -161,6 +178,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isblank (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a blank character; that is, a space or a tab.
+ This function was originally a GNU extension, but was added in @w{ISO C99}.
+ @end deftypefun
+@@ -169,6 +187,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isgraph (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a graphic character; that is, a character
+ that has a glyph associated with it.  The whitespace characters are not
+ considered graphic.
+@@ -178,6 +197,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int isprint (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a printing character.  Printing characters
+ include all the graphic characters, plus the space (@samp{ }) character.
+ @end deftypefun
+@@ -186,6 +206,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int iscntrl (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a control character (that is, a character that
+ is not a printing character).
+ @end deftypefun
+@@ -194,6 +215,7 @@
+ @comment ctype.h
+ @comment SVID, BSD
+ @deftypefun int isascii (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns true if @var{c} is a 7-bit @code{unsigned char} value that fits
+ into the US/UK ASCII character set.  This function is a BSD extension
+ and is also an SVID extension.
+@@ -227,6 +249,10 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int tolower (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c The to* macros/functions call different functions that use different
++@c arrays than those of__ctype_b_loc, but the access patterns and
++@c thus safety guarantees are the same.
+ If @var{c} is an upper-case letter, @code{tolower} returns the corresponding
+ lower-case letter.  If @var{c} is not an upper-case letter,
+ @var{c} is returned unchanged.
+@@ -235,6 +261,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int toupper (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If @var{c} is a lower-case letter, @code{toupper} returns the corresponding
+ upper-case letter.  Otherwise @var{c} is returned unchanged.
+ @end deftypefun
+@@ -242,6 +269,7 @@
+ @comment ctype.h
+ @comment SVID, BSD
+ @deftypefun int toascii (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function converts @var{c} to a 7-bit @code{unsigned char} value
+ that fits into the US/UK ASCII character set, by clearing the high-order
+ bits.  This function is a BSD extension and is also an SVID extension.
+@@ -250,6 +278,7 @@
+ @comment ctype.h
+ @comment SVID
+ @deftypefun int _tolower (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is identical to @code{tolower}, and is provided for compatibility
+ with the SVID.  @xref{SVID}.@refill
+ @end deftypefun
+@@ -257,6 +286,7 @@
+ @comment ctype.h
+ @comment SVID
+ @deftypefun int _toupper (int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is identical to @code{toupper}, and is provided for compatibility
+ with the SVID.
+ @end deftypefun
+@@ -303,6 +333,18 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun wctype_t wctype (const char *@var{property})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c Although the source code of wctype contains multiple references to
++@c the locale, that could each reference different locale_data objects
++@c should the global locale object change while active, the compiler can
++@c and does combine them all into a single dereference that resolves
++@c once to the LCTYPE locale object used throughout the function, so it
++@c is safe in (optimized) practice, if not in theory, even when the
++@c locale changes.  Ideally we'd explicitly save the resolved
++@c locale_data object to make it visibly safe instead of safe only under
++@c compiler optimizations, but given the decision that setlocale is
++@c MT-Unsafe, all this would afford us would be the ability to not mark
++@c this function with @mtslocale.
+ The @code{wctype} returns a value representing a class of wide
+ characters which is identified by the string @var{property}.  Beside
+ some standard properties each locale can define its own ones.  In case
+@@ -331,6 +373,8 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswctype (wint_t @var{wc}, wctype_t @var{desc})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c The compressed lookup table returned by wctype is read-only.
+ This function returns a nonzero value if @var{wc} is in the character
+ class specified by @var{desc}.  @var{desc} must previously be returned
+ by a successful call to @code{wctype}.
+@@ -350,6 +394,16 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswalnum (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c The implicit wctype call in the isw* functions is actually an
++@c optimized version because the category has a known offset, but the
++@c wctype is equally safe when optimized, unsafe with changing locales
++@c if not optimized (thus @mtslocale).  Since it's not a macro, we
++@c always optimize, and the locale can't change in any MT-Safe way, it's
++@c fine.  The test whether wc is ASCII to use the non-wide is*
++@c macro/function doesn't bring any other safety issues: the test does
++@c not depend on the locale, and each path after the decision resolves
++@c the locale object only once.
+ This function returns a nonzero value if @var{wc} is an alphanumeric
+ character (a letter or number); in other words, if either @code{iswalpha}
+ or @code{iswdigit} is true of a character, then @code{iswalnum} is also
+@@ -370,6 +424,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswalpha (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is an alphabetic character (a letter).  If
+ @code{iswlower} or @code{iswupper} is true of a character, then
+ @code{iswalpha} is also true.
+@@ -394,6 +449,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswcntrl (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a control character (that is, a character that
+ is not a printing character).
+ 
+@@ -412,6 +468,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswdigit (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a digit (e.g., @samp{0} through @samp{9}).
+ Please note that this function does not only return a nonzero value for
+ @emph{decimal} digits, but for all kinds of digits.  A consequence is
+@@ -442,6 +499,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswgraph (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a graphic character; that is, a character
+ that has a glyph associated with it.  The whitespace characters are not
+ considered graphic.
+@@ -461,6 +519,7 @@
+ @comment ctype.h
+ @comment ISO
+ @deftypefun int iswlower (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a lower-case letter.  The letter need not be
+ from the Latin alphabet, any alphabet representable is valid.
+ 
+@@ -479,6 +538,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswprint (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a printing character.  Printing characters
+ include all the graphic characters, plus the space (@samp{ }) character.
+ 
+@@ -497,6 +557,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswpunct (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a punctuation character.
+ This means any printing character that is not alphanumeric or a space
+ character.
+@@ -516,6 +577,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswspace (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a @dfn{whitespace} character.  In the standard
+ @code{"C"} locale, @code{iswspace} returns true for only the standard
+ whitespace characters:
+@@ -555,6 +617,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswupper (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is an upper-case letter.  The letter need not be
+ from the Latin alphabet, any alphabet representable is valid.
+ 
+@@ -573,6 +636,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswxdigit (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a hexadecimal digit.
+ Hexadecimal digits include the normal decimal digits @samp{0} through
+ @samp{9} and the letters @samp{A} through @samp{F} and
+@@ -597,6 +661,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun int iswblank (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ Returns true if @var{wc} is a blank character; that is, a space or a tab.
+ This function was originally a GNU extension, but was added in @w{ISO C99}.
+ It is declared in @file{wchar.h}.
+@@ -691,6 +756,8 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun wctrans_t wctrans (const char *@var{property})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c Similar implementation, same caveats as wctype.
+ The @code{wctrans} function has to be used to find out whether a named
+ mapping is defined in the current locale selected for the
+ @code{LC_CTYPE} category.  If the returned value is non-zero, you can use
+@@ -713,6 +780,8 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun wint_t towctrans (wint_t @var{wc}, wctrans_t @var{desc})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Same caveats as iswctype.
+ @code{towctrans} maps the input character @var{wc}
+ according to the rules of the mapping for which @var{desc} is a
+ descriptor, and returns the value it finds.  @var{desc} must be
+@@ -730,6 +799,9 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun wint_t towlower (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c Same caveats as iswalnum, just using a wctrans rather than a wctype
++@c table.
+ If @var{wc} is an upper-case letter, @code{towlower} returns the corresponding
+ lower-case letter.  If @var{wc} is not an upper-case letter,
+ @var{wc} is returned unchanged.
+@@ -749,6 +821,7 @@
+ @comment wctype.h
+ @comment ISO
+ @deftypefun wint_t towupper (wint_t @var{wc})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ If @var{wc} is a lower-case letter, @code{towupper} returns the corresponding
+ upper-case letter.  Otherwise @var{wc} is returned unchanged.
+ 
+diff -urN glibc-2.17-c758a686/manual/debug.texi glibc/manual/debug.texi
+--- glibc-2.17-c758a686/manual/debug.texi	2014-09-12 16:08:17.824070745 -0400
++++ glibc/manual/debug.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -1,5 +1,5 @@
+ @node Debugging Support
+-@c @node Debugging Support, Internal Probes, Cryptographic Functions, Top
++@c @node Debugging Support, POSIX Threads, Cryptographic Functions, Top
+ @c %MENU% Functions to help debugging applications
+ @chapter Debugging support
+ 
+@@ -36,6 +36,16 @@
+ @comment execinfo.h
+ @comment GNU
+ @deftypefun int backtrace (void **@var{buffer}, int @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{} @ascuheap{} @ascudlopen{} @ascuplugin{} @asulock{}}@acunsafe{@acuinit{} @acsmem{} @aculock{} @acsfd{}}}
++@c The generic implementation just does pointer chasing within the local
++@c stack, without any guarantees that this will handle signal frames
++@c correctly, so it's AS-Unsafe to begin with.  However, most (all?)
++@c arches defer to libgcc_s's _Unwind_* implementation, dlopening
++@c libgcc_s.so to that end except in a static version of libc.
++@c libgcc_s's implementation may in turn defer to libunwind.  We can't
++@c assume those implementations are AS- or AC-safe, but even if we
++@c could, our own initialization path isn't, and libgcc's implementation
++@c calls malloc and performs internal locking, so...
+ The @code{backtrace} function obtains a backtrace for the current
+ thread, as a list of pointers, and places the information into
+ @var{buffer}.  The argument @var{size} should be the number of
+@@ -56,6 +66,17 @@
+ @comment execinfo.h
+ @comment GNU
+ @deftypefun {char **} backtrace_symbols (void *const *@var{buffer}, int @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @aculock{}}}
++@c Collects info returned by _dl_addr in an auto array, allocates memory
++@c for the whole return buffer with malloc then sprintfs into it storing
++@c pointers to the strings into the array entries in the buffer.
++@c _dl_addr takes the recursive dl_load_lock then calls
++@c _dl_find_dso_for_object and determine_info.
++@c _dl_find_dso_for_object calls _dl-addr_inside_object.
++@c All of them are safe as long as the lock is held.
++@c @asucorrupt?  It doesn't look like the dynamic loader's data
++@c structures could be in an inconsistent state that would cause
++@c malfunction here.
+ The @code{backtrace_symbols} function translates the information
+ obtained from the @code{backtrace} function into an array of strings.
+ The argument @var{buffer} should be a pointer to an array of addresses
+@@ -88,6 +109,11 @@
+ @comment execinfo.h
+ @comment GNU
+ @deftypefun void backtrace_symbols_fd (void *const *@var{buffer}, int @var{size}, int @var{fd})
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
++@c Single loop of _dl_addr over addresses, collecting info into an iovec
++@c written out with a writev call per iteration.  Addresses and offsets
++@c are converted to hex in auto buffers, so the only potential issue
++@c here is leaking the dl lock in case of cancellation.
+ The @code{backtrace_symbols_fd} function performs the same translation
+ as the function @code{backtrace_symbols} function.  Instead of returning
+ the strings to the caller, it writes the strings to the file descriptor
+diff -urN glibc-2.17-c758a686/manual/errno.texi glibc/manual/errno.texi
+--- glibc-2.17-c758a686/manual/errno.texi	2014-09-12 16:08:17.752070930 -0400
++++ glibc/manual/errno.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -1293,6 +1293,9 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strerror (int @var{errnum})
++@safety{@prelim{}@mtunsafe{@mtasurace{:strerror}}@asunsafe{@ascuheap{} @ascuintl{}}@acunsafe{@acsmem{}}}
++@c Calls strerror_r with a static buffer allocated with malloc on the
++@c first use.
+ The @code{strerror} function maps the error code (@pxref{Checking for
+ Errors}) specified by the @var{errnum} argument to a descriptive error
+ message string.  The return value is a pointer to this string.
+@@ -1310,10 +1313,11 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {char *} strerror_r (int @var{errnum}, char *@var{buf}, size_t @var{n})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuintl{}}@acunsafe{}}
+ The @code{strerror_r} function works like @code{strerror} but instead of
+ returning the error message in a statically allocated buffer shared by
+ all threads in the process, it returns a private copy for the
+-thread. This might be either some permanent global data or a message
++thread.  This might be either some permanent global data or a message
+ string in the user supplied buffer starting at @var{buf} with the
+ length of @var{n} bytes.
+ 
+@@ -1331,6 +1335,10 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun void perror (const char *@var{message})
++@safety{@prelim{}@mtsafe{@mtasurace{:stderr}}@asunsafe{@asucorrupt{} @ascuintl{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c Besides strerror_r's and some of fprintf's issues, if stderr is not
++@c oriented yet, create a new stream with a dup of stderr's fd and write
++@c to that instead of stderr, to avoid orienting it.
+ This function prints an error message to the stream @code{stderr};
+ see @ref{Standard Streams}.  The orientation of @code{stderr} is not
+ changed.
+@@ -1442,6 +1450,13 @@
+ @comment error.h
+ @comment GNU
+ @deftypefun void error (int @var{status}, int @var{errnum}, const char *@var{format}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @asuheap{} @asuintl{}}@acsafe{}}
++@c Cancellation is disabled throughout the execution.  It flushes stdout
++@c and then holds a lock on stderr while printing the program name and
++@c then running error_tail.  The non-wide case just runs vfprintf; the
++@c wide case converts the message to an alloca/malloc-allocated buffer
++@c with mbsrtowcs, then prints it with vfwprintf.  Afterwards,
++@c print_errno_message calls strerror_r and fxprintf.
+ The @code{error} function can be used to report general problems during
+ program execution.  The @var{format} argument is a format string just
+ like those given to the @code{printf} family of functions.  The
+@@ -1477,6 +1492,15 @@
+ @comment error.h
+ @comment GNU
+ @deftypefun void error_at_line (int @var{status}, int @var{errnum}, const char *@var{fname}, unsigned int @var{lineno}, const char *@var{format}, @dots{})
++@safety{@prelim{}@mtunsafe{@mtasurace{:error_at_line/error_one_per_line} @mtslocale{}}@asunsafe{@asucorrupt{} @asuheap{} @asuintl{}}@acunsafe{@acucorrupt{/error_one_per_line}}}
++@c The error_one_per_line variable is accessed (without any form of
++@c synchronization, but since it's an int used once, it should be safe
++@c enough) and, if this mode is enabled, static variables used to hold
++@c the last printed file name and line number are accessed and modified
++@c without synchronization; the update is not atomic and it occurs
++@c before disabling cancellation, so it can be interrupted after only
++@c one of the two variables is modified.  After that, it's very much
++@c like error.
+ 
+ The @code{error_at_line} function is very similar to the @code{error}
+ function.  The only difference are the additional parameters @var{fname}
+@@ -1508,7 +1532,7 @@
+ 
+ @comment error.h
+ @comment GNU
+-@deftypevar {void (*) error_print_progname } (void)
++@deftypevar {void (*error_print_progname)} (void)
+ If the @code{error_print_progname} variable is defined to a non-zero
+ value the function pointed to is called by @code{error} or
+ @code{error_at_line}.  It is expected to print the program name or do
+@@ -1582,6 +1606,8 @@
+ @comment err.h
+ @comment BSD
+ @deftypefun void warn (const char *@var{format}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c Just calls vwarn with the va_list.
+ The @code{warn} function is roughly equivalent to a call like
+ @smallexample
+   error (0, errno, format, @r{the parameters})
+@@ -1594,14 +1620,21 @@
+ @comment err.h
+ @comment BSD
+ @deftypefun void vwarn (const char *@var{format}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c While holding stderr's recursive lock, it prints the programname, the
++@c given message, and the error string with fw?printf's %m.  When the
++@c stream is wide, convert_and_print converts the format string to an
++@c alloca/malloc-created buffer using mbsrtowcs and then calls fwprintf.
+ The @code{vwarn} function is just like @code{warn} except that the
+ parameters for the handling of the format string @var{format} are passed
+-in as an value of type @code{va_list}.
++in as a value of type @code{va_list}.
+ @end deftypefun
+ 
+ @comment err.h
+ @comment BSD
+ @deftypefun void warnx (const char *@var{format}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c Same as warn, but without the strerror translation issues.
+ The @code{warnx} function is roughly equivalent to a call like
+ @smallexample
+   error (0, 0, format, @r{the parameters})
+@@ -1615,14 +1648,18 @@
+ @comment err.h
+ @comment BSD
+ @deftypefun void vwarnx (const char *@var{format}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c Same as vwarn, but without the strerror translation issues.
+ The @code{vwarnx} function is just like @code{warnx} except that the
+ parameters for the handling of the format string @var{format} are passed
+-in as an value of type @code{va_list}.
++in as a value of type @code{va_list}.
+ @end deftypefun
+ 
+ @comment err.h
+ @comment BSD
+ @deftypefun void err (int @var{status}, const char *@var{format}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c Same as warn followed by exit.
+ The @code{err} function is roughly equivalent to a call like
+ @smallexample
+   error (status, errno, format, @r{the parameters})
+@@ -1635,14 +1672,18 @@
+ @comment err.h
+ @comment BSD
+ @deftypefun void verr (int @var{status}, const char *@var{format}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c Same as vwarn followed by exit.
+ The @code{verr} function is just like @code{err} except that the
+ parameters for the handling of the format string @var{format} are passed
+-in as an value of type @code{va_list}.
++in as a value of type @code{va_list}.
+ @end deftypefun
+ 
+ @comment err.h
+ @comment BSD
+ @deftypefun void errx (int @var{status}, const char *@var{format}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c Same as warnx followed by exit.
+ The @code{errx} function is roughly equivalent to a call like
+ @smallexample
+   error (status, 0, format, @r{the parameters})
+@@ -1657,7 +1698,9 @@
+ @comment err.h
+ @comment BSD
+ @deftypefun void verrx (int @var{status}, const char *@var{format}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c Same as vwarnx followed by exit.
+ The @code{verrx} function is just like @code{errx} except that the
+ parameters for the handling of the format string @var{format} are passed
+-in as an value of type @code{va_list}.
++in as a value of type @code{va_list}.
+ @end deftypefun
+diff -urN glibc-2.17-c758a686/manual/examples/add.c glibc/manual/examples/add.c
+--- glibc-2.17-c758a686/manual/examples/add.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/add.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Example of a Variadic Function
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/argp-ex1.c glibc/manual/examples/argp-ex1.c
+--- glibc-2.17-c758a686/manual/examples/argp-ex1.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/argp-ex1.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Argp example #1 -- a minimal program using argp
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/argp-ex2.c glibc/manual/examples/argp-ex2.c
+--- glibc-2.17-c758a686/manual/examples/argp-ex2.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/argp-ex2.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Argp example #2 -- a pretty minimal program using argp
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/argp-ex3.c glibc/manual/examples/argp-ex3.c
+--- glibc-2.17-c758a686/manual/examples/argp-ex3.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/argp-ex3.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Argp example #3 -- a program with options and arguments using argp
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/argp-ex4.c glibc/manual/examples/argp-ex4.c
+--- glibc-2.17-c758a686/manual/examples/argp-ex4.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/argp-ex4.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Argp example #4 -- a program with somewhat more complicated options
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/atexit.c glibc/manual/examples/atexit.c
+--- glibc-2.17-c758a686/manual/examples/atexit.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/atexit.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Cleanups on Exit
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/db.c glibc/manual/examples/db.c
+--- glibc-2.17-c758a686/manual/examples/db.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/db.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* User and Group Database Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/dir2.c glibc/manual/examples/dir2.c
+--- glibc-2.17-c758a686/manual/examples/dir2.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/dir2.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Simple Program to List a Directory, Mark II
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/dir.c glibc/manual/examples/dir.c
+--- glibc-2.17-c758a686/manual/examples/dir.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/dir.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Simple Program to List a Directory
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/execinfo.c glibc/manual/examples/execinfo.c
+--- glibc-2.17-c758a686/manual/examples/execinfo.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/execinfo.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Obtain a backtrace and print it.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/filecli.c glibc/manual/examples/filecli.c
+--- glibc-2.17-c758a686/manual/examples/filecli.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/filecli.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Example of Reading Datagrams
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/filesrv.c glibc/manual/examples/filesrv.c
+--- glibc-2.17-c758a686/manual/examples/filesrv.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/filesrv.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Datagram Socket Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/fmtmsgexpl.c glibc/manual/examples/fmtmsgexpl.c
+--- glibc-2.17-c758a686/manual/examples/fmtmsgexpl.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/fmtmsgexpl.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* How to use fmtmsg and addseverity.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/genpass.c glibc/manual/examples/genpass.c
+--- glibc-2.17-c758a686/manual/examples/genpass.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/genpass.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Encrypting Passwords
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/inetcli.c glibc/manual/examples/inetcli.c
+--- glibc-2.17-c758a686/manual/examples/inetcli.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/inetcli.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Byte Stream Socket Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/inetsrv.c glibc/manual/examples/inetsrv.c
+--- glibc-2.17-c758a686/manual/examples/inetsrv.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/inetsrv.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Byte Stream Connection Server Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/isockad.c glibc/manual/examples/isockad.c
+--- glibc-2.17-c758a686/manual/examples/isockad.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/isockad.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Internet Socket Example using sockaddr_in.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/longopt.c glibc/manual/examples/longopt.c
+--- glibc-2.17-c758a686/manual/examples/longopt.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/longopt.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Example of Parsing Long Options with getopt_long.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/memopen.c glibc/manual/examples/memopen.c
+--- glibc-2.17-c758a686/manual/examples/memopen.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/memopen.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* String Streams
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/memstrm.c glibc/manual/examples/memstrm.c
+--- glibc-2.17-c758a686/manual/examples/memstrm.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/memstrm.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* open_memstream example.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/mkfsock.c glibc/manual/examples/mkfsock.c
+--- glibc-2.17-c758a686/manual/examples/mkfsock.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/mkfsock.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Example of Local-Namespace Sockets
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+@@ -45,13 +45,12 @@
+ 
+   /* The size of the address is
+      the offset of the start of the filename,
+-     plus its length,
+-     plus one for the terminating null byte.
++     plus its length (not including the terminating null byte).
+      Alternatively you can just do:
+      size = SUN_LEN (&name);
+   */
+   size = (offsetof (struct sockaddr_un, sun_path)
+-	  + strlen (name.sun_path) + 1);
++	  + strlen (name.sun_path));
+ 
+   if (bind (sock, (struct sockaddr *) &name, size) < 0)
+     {
+diff -urN glibc-2.17-c758a686/manual/examples/mkisock.c glibc/manual/examples/mkisock.c
+--- glibc-2.17-c758a686/manual/examples/mkisock.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/mkisock.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Internet Socket Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/mygetpass.c glibc/manual/examples/mygetpass.c
+--- glibc-2.17-c758a686/manual/examples/mygetpass.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/mygetpass.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Reading Passwords
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/pipe.c glibc/manual/examples/pipe.c
+--- glibc-2.17-c758a686/manual/examples/pipe.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/pipe.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Creating a Pipe
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/popen.c glibc/manual/examples/popen.c
+--- glibc-2.17-c758a686/manual/examples/popen.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/popen.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Pipe to a Subprocess
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/rprintf.c glibc/manual/examples/rprintf.c
+--- glibc-2.17-c758a686/manual/examples/rprintf.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/rprintf.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Printf Extension Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/search.c glibc/manual/examples/search.c
+--- glibc-2.17-c758a686/manual/examples/search.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/search.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Searching and Sorting Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/select.c glibc/manual/examples/select.c
+--- glibc-2.17-c758a686/manual/examples/select.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/select.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Waiting for Input or Output
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/setjmp.c glibc/manual/examples/setjmp.c
+--- glibc-2.17-c758a686/manual/examples/setjmp.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/setjmp.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Introduction to Non-Local Exits
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/sigh1.c glibc/manual/examples/sigh1.c
+--- glibc-2.17-c758a686/manual/examples/sigh1.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/sigh1.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Signal Handlers that Return
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/sigusr.c glibc/manual/examples/sigusr.c
+--- glibc-2.17-c758a686/manual/examples/sigusr.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/sigusr.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Using kill for Communication
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/stpcpy.c glibc/manual/examples/stpcpy.c
+--- glibc-2.17-c758a686/manual/examples/stpcpy.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/stpcpy.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* stpcpy example.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/strdupa.c glibc/manual/examples/strdupa.c
+--- glibc-2.17-c758a686/manual/examples/strdupa.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/strdupa.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* strdupa example.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/strftim.c glibc/manual/examples/strftim.c
+--- glibc-2.17-c758a686/manual/examples/strftim.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/strftim.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Time Functions Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/strncat.c glibc/manual/examples/strncat.c
+--- glibc-2.17-c758a686/manual/examples/strncat.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/strncat.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* strncat example.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/subopt.c glibc/manual/examples/subopt.c
+--- glibc-2.17-c758a686/manual/examples/subopt.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/subopt.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Parsing of Suboptions Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/swapcontext.c glibc/manual/examples/swapcontext.c
+--- glibc-2.17-c758a686/manual/examples/swapcontext.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/swapcontext.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Complete Context Control
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/termios.c glibc/manual/examples/termios.c
+--- glibc-2.17-c758a686/manual/examples/termios.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/termios.c	2014-09-12 16:10:06.046792714 -0400
+@@ -1,5 +1,5 @@
+ /* Noncanonical Mode Example
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/testopt.c glibc/manual/examples/testopt.c
+--- glibc-2.17-c758a686/manual/examples/testopt.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/testopt.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Example of Parsing Arguments with getopt.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/testpass.c glibc/manual/examples/testpass.c
+--- glibc-2.17-c758a686/manual/examples/testpass.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/testpass.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* Verify a password.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/examples/timeval_subtract.c glibc/manual/examples/timeval_subtract.c
+--- glibc-2.17-c758a686/manual/examples/timeval_subtract.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/examples/timeval_subtract.c	2014-09-12 16:10:06.047792712 -0400
+@@ -1,5 +1,5 @@
+ /* struct timeval subtraction.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+diff -urN glibc-2.17-c758a686/manual/filesys.texi glibc/manual/filesys.texi
+--- glibc-2.17-c758a686/manual/filesys.texi	2014-09-12 16:08:17.966070381 -0400
++++ glibc/manual/filesys.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -58,6 +58,25 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun {char *} getcwd (char *@var{buffer}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c If buffer is NULL, this function calls malloc and realloc, and, in
++@c case of error, free.  Linux offers a getcwd syscall that we use on
++@c GNU/Linux systems, but it may fail if the pathname is too long.  As a
++@c fallback, and on other systems, the generic implementation opens each
++@c parent directory with opendir, which allocates memory for the
++@c directory stream with malloc.  If a fstatat64 syscall is not
++@c available, very deep directory trees may also have to malloc to build
++@c longer sequences of ../../../... than those supported by a global
++@c const read-only string.
++
++@c linux/__getcwd
++@c  posix/__getcwd
++@c   malloc/realloc/free if buffer is NULL, or if dir is too deep
++@c   lstat64 -> see its own entry
++@c   fstatat64
++@c     direct syscall if possible, alloca+snprintf+*stat64 otherwise
++@c   openat64_not_cancel_3, close_not_cancel_no_status
++@c   __fdopendir, __opendir, __readdir, rewinddir
+ The @code{getcwd} function returns an absolute file name representing
+ the current working directory, storing it in the character array
+ @var{buffer} that you provide.  The @var{size} argument is how you tell
+@@ -116,6 +135,9 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefn {Deprecated Function} {char *} getwd (char *@var{buffer})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @ascuintl{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c Besides the getcwd safety issues, it calls strerror_r on error, which
++@c brings in all of the i18n issues.
+ This is similar to @code{getcwd}, but has no way to specify the size of
+ the buffer.  @Theglibc{} provides @code{getwd} only
+ for backwards compatibility with BSD.
+@@ -130,6 +152,9 @@
+ @comment unistd.h
+ @comment GNU
+ @deftypefun {char *} get_current_dir_name (void)
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c Besides getcwd, which this function calls as a fallback, it calls
++@c getenv, with the potential thread-safety issues that brings about.
+ @vindex PWD
+ This @code{get_current_dir_name} function is basically equivalent to
+ @w{@code{getcwd (NULL, 0)}}.  The only difference is that the value of
+@@ -145,6 +170,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int chdir (const char *@var{filename})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is used to set the process's working directory to
+ @var{filename}.
+ 
+@@ -158,6 +184,7 @@
+ @comment unistd.h
+ @comment XPG
+ @deftypefun int fchdir (int @var{filedes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is used to set the process's working directory to
+ directory associated with the file descriptor @var{filedes}.
+ 
+@@ -294,12 +321,14 @@
+ @comment dirent.h
+ @comment BSD
+ @deftypefun int IFTODT (mode_t @var{mode})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This returns the @code{d_type} value corresponding to @var{mode}.
+ @end deftypefun
+ 
+ @comment dirent.h
+ @comment BSD
+ @deftypefun mode_t DTTOIF (int @var{dtype})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This returns the @code{st_mode} value corresponding to @var{dtype}.
+ @end deftypefun
+ @end table
+@@ -342,6 +371,9 @@
+ @comment dirent.h
+ @comment POSIX.1
+ @deftypefun {DIR *} opendir (const char *@var{dirname})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c Besides the safe syscall, we have to allocate the DIR object with
++@c __alloc_dir, that calls malloc.
+ The @code{opendir} function opens and returns a directory stream for
+ reading the directory whose file name is @var{dirname}.  The stream has
+ type @code{DIR *}.
+@@ -381,6 +413,8 @@
+ @comment dirent.h
+ @comment GNU
+ @deftypefun {DIR *} fdopendir (int @var{fd})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c The DIR object is allocated with __alloc_dir, that calls malloc.
+ The @code{fdopendir} function works just like @code{opendir} but
+ instead of taking a file name and opening a file descriptor for the
+ directory the caller is required to provide a file descriptor.  This
+@@ -425,6 +459,7 @@
+ @comment dirent.h
+ @comment GNU
+ @deftypefun int dirfd (DIR *@var{dirstream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The function @code{dirfd} returns the file descriptor associated with
+ the directory stream @var{dirstream}.  This descriptor can be used until
+ the directory is closed with @code{closedir}.  If the directory stream
+@@ -443,6 +478,12 @@
+ @comment dirent.h
+ @comment POSIX.1
+ @deftypefun {struct dirent *} readdir (DIR *@var{dirstream})
++@safety{@prelim{}@mtunsafe{@mtasurace{:dirstream}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c This function holds dirstream's non-recursive lock, which brings
++@c about the usual issues with locks and async signals and cancellation,
++@c but the lock taking is not enough to make the returned value safe to
++@c use, since it points to a stream's internal buffer that can be
++@c overwritten by subsequent calls or even released by closedir.
+ This function reads the next entry from the directory.  It normally
+ returns a pointer to a structure containing information about the
+ file.  This structure is associated with the @var{dirstream} handle
+@@ -478,6 +519,7 @@
+ @comment dirent.h
+ @comment GNU
+ @deftypefun int readdir_r (DIR *@var{dirstream}, struct dirent *@var{entry}, struct dirent **@var{result})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+ This function is a version of @code{readdir} which performs internal
+ locking.  Like @code{readdir} it returns the next entry from the
+ directory.  To prevent conflicts between simultaneously running
+@@ -549,6 +591,7 @@
+ @comment dirent.h
+ @comment LFS
+ @deftypefun {struct dirent64 *} readdir64 (DIR *@var{dirstream})
++@safety{@prelim{}@mtunsafe{@mtasurace{:dirstream}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+ The @code{readdir64} function is just like the @code{readdir} function
+ except that it returns a pointer to a record of type @code{struct
+ dirent64}.  Some of the members of this data type (notably @code{d_ino})
+@@ -560,6 +603,7 @@
+ @comment dirent.h
+ @comment LFS
+ @deftypefun int readdir64_r (DIR *@var{dirstream}, struct dirent64 *@var{entry}, struct dirent64 **@var{result})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+ The @code{readdir64_r} function is equivalent to the @code{readdir_r}
+ function except that it takes parameters of base type @code{struct
+ dirent64} instead of @code{struct dirent} in the second and third
+@@ -570,6 +614,10 @@
+ @comment dirent.h
+ @comment POSIX.1
+ @deftypefun int closedir (DIR *@var{dirstream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{/hurd}}@acunsafe{@acsmem{} @acsfd{} @aculock{/hurd}}}
++@c No synchronization in the posix implementation, only in the hurd
++@c one.  This is regarded as safe because it is undefined behavior if
++@c other threads could still be using the dir stream while it's closed.
+ This function closes the directory stream @var{dirstream}.  It returns
+ @code{0} on success and @code{-1} on failure.
+ 
+@@ -609,6 +657,7 @@
+ @comment dirent.h
+ @comment POSIX.1
+ @deftypefun void rewinddir (DIR *@var{dirstream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+ The @code{rewinddir} function is used to reinitialize the directory
+ stream @var{dirstream}, so that if you call @code{readdir} it
+ returns information about the first entry in the directory again.  This
+@@ -622,6 +671,10 @@
+ @comment dirent.h
+ @comment BSD
+ @deftypefun {long int} telldir (DIR *@var{dirstream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/bsd} @asulock{/bsd}}@acunsafe{@acsmem{/bsd} @aculock{/bsd}}}
++@c The implementation is safe on most platforms, but on BSD it uses
++@c cookies, buckets and records, and the global array of pointers to
++@c dynamically allocated records is guarded by a non-recursive lock.
+ The @code{telldir} function returns the file position of the directory
+ stream @var{dirstream}.  You can use this value with @code{seekdir} to
+ restore the directory stream to that position.
+@@ -630,6 +683,10 @@
+ @comment dirent.h
+ @comment BSD
+ @deftypefun void seekdir (DIR *@var{dirstream}, long int @var{pos})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/bsd} @asulock{/bsd}}@acunsafe{@acsmem{/bsd} @aculock{/bsd}}}
++@c The implementation is safe on most platforms, but on BSD it uses
++@c cookies, buckets and records, and the global array of pointers to
++@c dynamically allocated records is guarded by a non-recursive lock.
+ The @code{seekdir} function sets the file position of the directory
+ stream @var{dirstream} to @var{pos}.  The value @var{pos} must be the
+ result of a previous call to @code{telldir} on this particular stream;
+@@ -648,7 +705,20 @@
+ 
+ @comment dirent.h
+ @comment BSD/SVID
+-@deftypefun int scandir (const char *@var{dir}, struct dirent ***@var{namelist}, int (*@var{selector}) (const struct dirent *), int (*@var{cmp}) (const void *, const void *))
++@deftypefun int scandir (const char *@var{dir}, struct dirent ***@var{namelist}, int (*@var{selector}) (const struct dirent *), int (*@var{cmp}) (const struct dirent **, const struct dirent **))
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c The scandir function calls __opendirat, __readdir, and __closedir to
++@c go over the named dir; malloc and realloc to allocate the namelist
++@c and copies of each selected dirent, besides the selector, if given,
++@c and qsort and the cmp functions if the latter is given.  In spite of
++@c the cleanup handler that releases memory and the file descriptor in
++@c case of synchronous cancellation, an asynchronous cancellation may
++@c still leak memory and a file descriptor.  Although readdir is unsafe
++@c in general, the use of an internal dir stream for sequential scanning
++@c of the directory with copying of dirents before subsequent calls
++@c makes the use safe, and the fact that the dir stream is private to
++@c each scandir call does away with the lock issues in readdir and
++@c closedir.
+ 
+ The @code{scandir} function scans the contents of the directory selected
+ by @var{dir}.  The result in *@var{namelist} is an array of pointers to
+@@ -678,7 +748,9 @@
+ 
+ @comment dirent.h
+ @comment BSD/SVID
+-@deftypefun int alphasort (const void *@var{a}, const void *@var{b})
++@deftypefun int alphasort (const struct dirent **@var{a}, const struct dirent **@var{b})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c Calls strcoll.
+ The @code{alphasort} function behaves like the @code{strcoll} function
+ (@pxref{String/Array Comparison}).  The difference is that the arguments
+ are not string pointers but instead they are of type
+@@ -690,7 +762,10 @@
+ 
+ @comment dirent.h
+ @comment GNU
+-@deftypefun int versionsort (const void *@var{a}, const void *@var{b})
++@deftypefun int versionsort (const struct dirent **@var{a}, const struct dirent **@var{b})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c Calls strverscmp, which will accesses the locale object multiple
++@c times.
+ The @code{versionsort} function is like @code{alphasort} except that it
+ uses the @code{strverscmp} function internally.
+ @end deftypefun
+@@ -702,7 +777,9 @@
+ 
+ @comment dirent.h
+ @comment GNU
+-@deftypefun int scandir64 (const char *@var{dir}, struct dirent64 ***@var{namelist}, int (*@var{selector}) (const struct dirent64 *), int (*@var{cmp}) (const void *, const void *))
++@deftypefun int scandir64 (const char *@var{dir}, struct dirent64 ***@var{namelist}, int (*@var{selector}) (const struct dirent64 *), int (*@var{cmp}) (const struct dirent64 **, const struct dirent64 **))
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c See scandir.
+ The @code{scandir64} function works like the @code{scandir} function
+ except that the directory entries it returns are described by elements
+ of type @w{@code{struct dirent64}}.  The function pointed to by
+@@ -720,7 +797,9 @@
+ 
+ @comment dirent.h
+ @comment GNU
+-@deftypefun int alphasort64 (const void *@var{a}, const void *@var{b})
++@deftypefun int alphasort64 (const struct dirent64 **@var{a}, const struct dirent **@var{b})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c See alphasort.
+ The @code{alphasort64} function behaves like the @code{strcoll} function
+ (@pxref{String/Array Comparison}).  The difference is that the arguments
+ are not string pointers but instead they are of type
+@@ -732,7 +811,9 @@
+ 
+ @comment dirent.h
+ @comment GNU
+-@deftypefun int versionsort64 (const void *@var{a}, const void *@var{b})
++@deftypefun int versionsort64 (const struct dirent64 **@var{a}, const struct dirent64 **@var{b})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c See versionsort.
+ The @code{versionsort64} function is like @code{alphasort64}, excepted that it
+ uses the @code{strverscmp} function internally.
+ @end deftypefun
+@@ -812,7 +893,7 @@
+ file does not exist.  The situation for @code{nftw} is different.
+ 
+ This value is only available if the program is compiled with
+-@code{_BSD_SOURCE} or @code{_XOPEN_EXTENDED} defined before including
++@code{_XOPEN_EXTENDED} defined before including
+ the first header.  The original SVID systems do not have symbolic links.
+ @end vtable
+ 
+@@ -913,6 +994,8 @@
+ @comment ftw.h
+ @comment SVID
+ @deftypefun int ftw (const char *@var{filename}, __ftw_func_t @var{func}, int @var{descriptors})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c see nftw for safety details
+ The @code{ftw} function calls the callback function given in the
+ parameter @var{func} for every item which is found in the directory
+ specified by @var{filename} and all directories below.  The function
+@@ -963,6 +1046,7 @@
+ @comment ftw.h
+ @comment Unix98
+ @deftypefun int ftw64 (const char *@var{filename}, __ftw64_func_t @var{func}, int @var{descriptors})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
+ This function is similar to @code{ftw} but it can work on filesystems
+ with large files.  File information is reported using a variable of type
+ @code{struct stat64} which is passed by reference to the callback
+@@ -976,6 +1060,17 @@
+ @comment ftw.h
+ @comment XPG4.2
+ @deftypefun int nftw (const char *@var{filename}, __nftw_func_t @var{func}, int @var{descriptors}, int @var{flag})
++@safety{@prelim{}@mtsafe{@mtasscwd{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{} @acscwd{}}}
++@c ftw_startup calls alloca, malloc, free, xstat/lxstat, tdestroy, and ftw_dir
++@c  if FTW_CHDIR, call open, and fchdir, or chdir and getcwd
++@c ftw_dir calls open_dir_stream, readdir64, process_entry, closedir
++@c  if FTW_CHDIR, also calls fchdir
++@c open_dir_stream calls malloc, realloc, readdir64, free, closedir,
++@c  then openat64_not_cancel_3 and fdopendir or opendir, then dirfd.
++@c process_entry may cal realloc, fxstatat/lxstat/xstat, ftw_dir, and
++@c  find_object (tsearch) and add_object (tfind).
++@c Since each invocation of *ftw uses its own private search tree, none
++@c  of the search tree concurrency issues apply.
+ The @code{nftw} function works like the @code{ftw} functions.  They call
+ the callback function @var{func} for all items found in the directory
+ @var{filename} and below.  At most @var{descriptors} file descriptors
+@@ -1036,6 +1131,7 @@
+ @comment ftw.h
+ @comment Unix98
+ @deftypefun int nftw64 (const char *@var{filename}, __nftw64_func_t @var{func}, int @var{descriptors}, int @var{flag})
++@safety{@prelim{}@mtsafe{@mtasscwd{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{} @acscwd{}}}
+ This function is similar to @code{nftw} but it can work on filesystems
+ with large files.  File information is reported using a variable of type
+ @code{struct stat64} which is passed by reference to the callback
+@@ -1079,6 +1175,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int link (const char *@var{oldname}, const char *@var{newname})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{link} function makes a new link to the existing file named by
+ @var{oldname}, under the new name @var{newname}.
+ 
+@@ -1186,6 +1283,7 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int symlink (const char *@var{oldname}, const char *@var{newname})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{symlink} function makes a symbolic link to @var{oldname} named
+ @var{newname}.
+ 
+@@ -1222,7 +1320,8 @@
+ 
+ @comment unistd.h
+ @comment BSD
+-@deftypefun int readlink (const char *@var{filename}, char *@var{buffer}, size_t @var{size})
++@deftypefun ssize_t readlink (const char *@var{filename}, char *@var{buffer}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{readlink} function gets the value of the symbolic link
+ @var{filename}.  The file name that the link points to is copied into
+ @var{buffer}.  This file name string is @emph{not} null-terminated;
+@@ -1282,6 +1381,8 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun {char *} canonicalize_file_name (const char *@var{name})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c Calls realpath.
+ 
+ The @code{canonicalize_file_name} function returns the absolute name of
+ the file named by @var{name} which contains no @code{.}, @code{..}
+@@ -1323,6 +1424,8 @@
+ @comment stdlib.h
+ @comment XPG
+ @deftypefun {char *} realpath (const char *restrict @var{name}, char *restrict @var{resolved})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c Calls malloc, realloc, getcwd, lxstat64, readlink, alloca.
+ 
+ A call to @code{realpath} where the @var{resolved} parameter is
+ @code{NULL} behaves exactly like @code{canonicalize_file_name}.  The
+@@ -1362,6 +1465,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int unlink (const char *@var{filename})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{unlink} function deletes the file name @var{filename}.  If
+ this is a file's sole name, the file itself is also deleted.  (Actually,
+ if any process has the file open when this happens, deletion is
+@@ -1404,6 +1508,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int rmdir (const char *@var{filename})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @cindex directories, deleting
+ @cindex deleting a directory
+ The @code{rmdir} function deletes a directory.  The directory must be
+@@ -1431,6 +1536,8 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int remove (const char *@var{filename})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Calls unlink and rmdir.
+ This is the @w{ISO C} function to remove a file.  It works like
+ @code{unlink} for files and like @code{rmdir} for directories.
+ @code{remove} is declared in @file{stdio.h}.
+@@ -1446,6 +1553,10 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int rename (const char *@var{oldname}, const char *@var{newname})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c In the absence of a rename syscall, there's an emulation with link
++@c and unlink, but it's racy, even more so if newname exists and is
++@c unlinked first.
+ The @code{rename} function renames the file @var{oldname} to
+ @var{newname}.  The file formerly accessible under the name
+ @var{oldname} is afterwards accessible as @var{newname} instead.  (If
+@@ -1541,6 +1652,7 @@
+ @comment sys/stat.h
+ @comment POSIX.1
+ @deftypefun int mkdir (const char *@var{filename}, mode_t @var{mode})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{mkdir} function creates a new, empty directory with name
+ @var{filename}.
+ 
+@@ -1882,6 +1994,7 @@
+ @comment sys/stat.h
+ @comment POSIX.1
+ @deftypefun int stat (const char *@var{filename}, struct stat *@var{buf})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{stat} function returns information about the attributes of the
+ file named by @w{@var{filename}} in the structure pointed to by @var{buf}.
+ 
+@@ -1908,8 +2021,9 @@
+ @comment sys/stat.h
+ @comment Unix98
+ @deftypefun int stat64 (const char *@var{filename}, struct stat64 *@var{buf})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{stat} but it is also able to work on
+-files larger then @math{2^31} bytes on 32-bit systems.  To be able to do
++files larger than @math{2^31} bytes on 32-bit systems.  To be able to do
+ this the result is stored in a variable of type @code{struct stat64} to
+ which @var{buf} must point.
+ 
+@@ -1921,6 +2035,7 @@
+ @comment sys/stat.h
+ @comment POSIX.1
+ @deftypefun int fstat (int @var{filedes}, struct stat *@var{buf})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fstat} function is like @code{stat}, except that it takes an
+ open file descriptor as an argument instead of a file name.
+ @xref{Low-Level I/O}.
+@@ -1942,6 +2057,7 @@
+ @comment sys/stat.h
+ @comment Unix98
+ @deftypefun int fstat64 (int @var{filedes}, struct stat64 *@var{buf})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{fstat} but is able to work on large
+ files on 32-bit platforms.  For large files the file descriptor
+ @var{filedes} should be obtained by @code{open64} or @code{creat64}.
+@@ -1953,9 +2069,16 @@
+ replaces the interface for small files on 32-bit machines.
+ @end deftypefun
+ 
++@c fstatat will call alloca and snprintf if the syscall is not
++@c available.
++@c @safety{@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++
+ @comment sys/stat.h
+ @comment BSD
+ @deftypefun int lstat (const char *@var{filename}, struct stat *@var{buf})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct system call through lxstat, sometimes with an xstat conv call
++@c afterwards.
+ The @code{lstat} function is like @code{stat}, except that it does not
+ follow symbolic links.  If @var{filename} is the name of a symbolic
+ link, @code{lstat} returns information about the link itself; otherwise
+@@ -1969,8 +2092,11 @@
+ @comment sys/stat.h
+ @comment Unix98
+ @deftypefun int lstat64 (const char *@var{filename}, struct stat64 *@var{buf})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct system call through lxstat64, sometimes with an xstat conv
++@c call afterwards.
+ This function is similar to @code{lstat} but it is also able to work on
+-files larger then @math{2^31} bytes on 32-bit systems.  To be able to do
++files larger than @math{2^31} bytes on 32-bit systems.  To be able to do
+ this the result is stored in a variable of type @code{struct stat64} to
+ which @var{buf} must point.
+ 
+@@ -2007,12 +2133,14 @@
+ @comment sys/stat.h
+ @comment POSIX
+ @deftypefn Macro int S_ISDIR (mode_t @var{m})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns non-zero if the file is a directory.
+ @end deftypefn
+ 
+ @comment sys/stat.h
+ @comment POSIX
+ @deftypefn Macro int S_ISCHR (mode_t @var{m})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns non-zero if the file is a character special file (a
+ device like a terminal).
+ @end deftypefn
+@@ -2020,6 +2148,7 @@
+ @comment sys/stat.h
+ @comment POSIX
+ @deftypefn Macro int S_ISBLK (mode_t @var{m})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns non-zero if the file is a block special file (a device
+ like a disk).
+ @end deftypefn
+@@ -2027,12 +2156,14 @@
+ @comment sys/stat.h
+ @comment POSIX
+ @deftypefn Macro int S_ISREG (mode_t @var{m})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns non-zero if the file is a regular file.
+ @end deftypefn
+ 
+ @comment sys/stat.h
+ @comment POSIX
+ @deftypefn Macro int S_ISFIFO (mode_t @var{m})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns non-zero if the file is a FIFO special file, or a
+ pipe.  @xref{Pipes and FIFOs}.
+ @end deftypefn
+@@ -2040,6 +2171,7 @@
+ @comment sys/stat.h
+ @comment GNU
+ @deftypefn Macro int S_ISLNK (mode_t @var{m})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns non-zero if the file is a symbolic link.
+ @xref{Symbolic Links}.
+ @end deftypefn
+@@ -2047,6 +2179,7 @@
+ @comment sys/stat.h
+ @comment GNU
+ @deftypefn Macro int S_ISSOCK (mode_t @var{m})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns non-zero if the file is a socket.  @xref{Sockets}.
+ @end deftypefn
+ 
+@@ -2129,6 +2262,7 @@
+ @comment sys/stat.h
+ @comment POSIX
+ @deftypefn Macro int S_TYPEISMQ (struct stat *@var{s})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If the system implement POSIX message queues as distinct objects and the
+ file is a message queue object, this macro returns a non-zero value.
+ In all other cases the result is zero.
+@@ -2137,6 +2271,7 @@
+ @comment sys/stat.h
+ @comment POSIX
+ @deftypefn Macro int S_TYPEISSEM (struct stat *@var{s})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If the system implement POSIX semaphores as distinct objects and the
+ file is a semaphore object, this macro returns a non-zero value.
+ In all other cases the result is zero.
+@@ -2145,8 +2280,9 @@
+ @comment sys/stat.h
+ @comment POSIX
+ @deftypefn Macro int S_TYPEISSHM (struct stat *@var{s})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If the system implement POSIX shared memory objects as distinct objects
+-and the file is an shared memory object, this macro returns a non-zero
++and the file is a shared memory object, this macro returns a non-zero
+ value.  In all other cases the result is zero.
+ @end deftypefn
+ 
+@@ -2189,6 +2325,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int chown (const char *@var{filename}, uid_t @var{owner}, gid_t @var{group})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{chown} function changes the owner of the file @var{filename} to
+ @var{owner}, and its group owner to @var{group}.
+ 
+@@ -2222,7 +2359,8 @@
+ 
+ @comment unistd.h
+ @comment BSD
+-@deftypefun int fchown (int @var{filedes}, int @var{owner}, int @var{group})
++@deftypefun int fchown (int @var{filedes}, uid_t @var{owner}, gid_t @var{group})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is like @code{chown}, except that it changes the owner of the open
+ file with descriptor @var{filedes}.
+ 
+@@ -2502,6 +2641,7 @@
+ @comment sys/stat.h
+ @comment POSIX.1
+ @deftypefun mode_t umask (mode_t @var{mask})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{umask} function sets the file creation mask of the current
+ process to @var{mask}, and returns the previous value of the file
+ creation mask.
+@@ -2527,6 +2667,7 @@
+ @comment sys/stat.h
+ @comment GNU
+ @deftypefun mode_t getumask (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Return the current value of the file creation mask for the current
+ process.  This function is a GNU extension and is only available on
+ @gnuhurdsystems{}.
+@@ -2535,6 +2676,7 @@
+ @comment sys/stat.h
+ @comment POSIX.1
+ @deftypefun int chmod (const char *@var{filename}, mode_t @var{mode})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{chmod} function sets the access permission bits for the file
+ named by @var{filename} to @var{mode}.
+ 
+@@ -2574,7 +2716,8 @@
+ 
+ @comment sys/stat.h
+ @comment BSD
+-@deftypefun int fchmod (int @var{filedes}, int @var{mode})
++@deftypefun int fchmod (int @var{filedes}, mode_t @var{mode})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is like @code{chmod}, except that it changes the permissions of the
+ currently open file given by @var{filedes}.
+ 
+@@ -2645,6 +2788,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int access (const char *@var{filename}, int @var{how})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{access} function checks to see whether the file named by
+ @var{filename} can be accessed in the way specified by the @var{how}
+ argument.  The @var{how} argument either can be the bitwise OR of the
+@@ -2746,7 +2890,7 @@
+ need to include the header file @file{utime.h} to use this facility.
+ @pindex utime.h
+ 
+-@comment time.h
++@comment utime.h
+ @comment POSIX.1
+ @deftp {Data Type} {struct utimbuf}
+ The @code{utimbuf} structure is used with the @code{utime} function to
+@@ -2762,9 +2906,12 @@
+ @end table
+ @end deftp
+ 
+-@comment time.h
++@comment utime.h
+ @comment POSIX.1
+ @deftypefun int utime (const char *@var{filename}, const struct utimbuf *@var{times})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c In the absence of a utime syscall, it non-atomically converts times
++@c to a struct timeval and calls utimes.
+ This function is used to modify the file times associated with the file
+ named @var{filename}.
+ 
+@@ -2815,7 +2962,11 @@
+ 
+ @comment sys/time.h
+ @comment BSD
+-@deftypefun int utimes (const char *@var{filename}, struct timeval @var{tvp}@t{[2]})
++@deftypefun int utimes (const char *@var{filename}, const struct timeval @var{tvp}@t{[2]})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c In the absence of a utimes syscall, it non-atomically converts tvp
++@c to struct timespec array and issues a utimensat syscall, or to
++@c struct utimbuf and calls utime.
+ This function sets the file access and modification times of the file
+ @var{filename}.  The new file access time is specified by
+ @code{@var{tvp}[0]}, and the new modification time by
+@@ -2829,7 +2980,10 @@
+ 
+ @comment sys/time.h
+ @comment BSD
+-@deftypefun int lutimes (const char *@var{filename}, struct timeval @var{tvp}@t{[2]})
++@deftypefun int lutimes (const char *@var{filename}, const struct timeval @var{tvp}@t{[2]})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Since there's no lutimes syscall, it non-atomically converts tvp
++@c to struct timespec array and issues a utimensat syscall.
+ This function is like @code{utimes}, except that it does not follow
+ symbolic links.  If @var{filename} is the name of a symbolic link,
+ @code{lutimes} sets the file access and modification times of the
+@@ -2845,7 +2999,11 @@
+ 
+ @comment sys/time.h
+ @comment BSD
+-@deftypefun int futimes (int @var{fd}, struct timeval @var{tvp}@t{[2]})
++@deftypefun int futimes (int @var{fd}, const struct timeval @var{tvp}@t{[2]})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Since there's no futimes syscall, it non-atomically converts tvp
++@c to struct timespec array and issues a utimensat syscall, falling back
++@c to utimes on a /proc/self/fd symlink.
+ This function is like @code{utimes}, except that it takes an open file
+ descriptor as an argument instead of a file name.  @xref{Low-Level
+ I/O}.  This function comes from FreeBSD, and is not available on all
+@@ -2900,6 +3058,8 @@
+ @comment unistd.h
+ @comment X/Open
+ @deftypefun int truncate (const char *@var{filename}, off_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c In the absence of a truncate syscall, we use open and ftruncate.
+ 
+ The @code{truncate} function changes the size of @var{filename} to
+ @var{length}.  If @var{length} is shorter than the previous length, data
+@@ -2944,6 +3104,8 @@
+ @comment unistd.h
+ @comment Unix98
+ @deftypefun int truncate64 (const char *@var{name}, off64_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c In the absence of a syscall, try truncate if length fits.
+ This function is similar to the @code{truncate} function.  The
+ difference is that the @var{length} argument is 64 bits wide even on 32
+ bits machines, which allows the handling of files with sizes up to
+@@ -2957,6 +3119,7 @@
+ @comment unistd.h
+ @comment POSIX
+ @deftypefun int ftruncate (int @var{fd}, off_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ This is like @code{truncate}, but it works on a file descriptor @var{fd}
+ for an opened file instead of a file name to identify the object.  The
+@@ -3021,6 +3184,8 @@
+ @comment unistd.h
+ @comment Unix98
+ @deftypefun int ftruncate64 (int @var{id}, off64_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c In the absence of a syscall, try ftruncate if length fits.
+ This function is similar to the @code{ftruncate} function.  The
+ difference is that the @var{length} argument is 64 bits wide even on 32
+ bits machines which allows the handling of files with sizes up to
+@@ -3082,7 +3247,11 @@
+ 
+ @comment sys/stat.h
+ @comment BSD
+-@deftypefun int mknod (const char *@var{filename}, int @var{mode}, int @var{dev})
++@deftypefun int mknod (const char *@var{filename}, mode_t @var{mode}, dev_t @var{dev})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Instead of issuing the syscall directly, we go through xmknod.
++@c Although the internal xmknod takes a dev_t*, that could lead to
++@c @mtsrace races, it's passed a pointer to mknod's dev.
+ The @code{mknod} function makes a special file with name @var{filename}.
+ The @var{mode} specifies the mode of the file, and may include the various
+ special file bits, such as @code{S_IFCHR} (for a character special file)
+@@ -3134,6 +3303,20 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun {FILE *} tmpfile (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
++@c The unsafety issues are those of fdopen, plus @acsfd because of the
++@c open.
++@c __path_search (internal buf, !dir, const pfx, !try_tmpdir) ok
++@c  libc_secure_genenv only if try_tmpdir
++@c  xstat64, strlen, strcmp, sprintf
++@c __gen_tempname (internal tmpl, __GT_FILE) ok
++@c  strlen, memcmp, getpid, open/mkdir/lxstat64 ok
++@c  HP_TIMING_NOW if available ok
++@c  gettimeofday (!tz) first time, or every time if no HP_TIMING_NOW ok
++@c  static value is used and modified without synchronization ok
++@c   but the use is as a source of non-cryptographic randomness
++@c   with retries in case of collision, so it should be safe
++@c unlink, fdopen
+ This function creates a temporary binary file for update mode, as if by
+ calling @code{fopen} with mode @code{"wb+"}.  The file is deleted
+ automatically when it is closed or when the program terminates.  (On
+@@ -3150,9 +3333,10 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun {FILE *} tmpfile64 (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
+ This function is similar to @code{tmpfile}, but the stream it returns a
+ pointer to was opened using @code{tmpfile64}.  Therefore this stream can
+-be used for files larger then @math{2^31} bytes on 32-bit machines.
++be used for files larger than @math{2^31} bytes on 32-bit machines.
+ 
+ Please note that the return type is still @code{FILE *}.  There is no
+ special @code{FILE} type for the LFS interface.
+@@ -3165,6 +3349,11 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun {char *} tmpnam (char *@var{result})
++@safety{@prelim{}@mtunsafe{@mtasurace{:tmpnam/!result}}@asunsafe{}@acsafe{}}
++@c The passed-in buffer should not be modified concurrently with the
++@c call.
++@c __path_search (static or passed-in buf, !dir, !pfx, !try_tmpdir) ok
++@c __gen_tempname (internal tmpl, __GT_NOCREATE) ok
+ This function constructs and returns a valid file name that does not
+ refer to any existing file.  If the @var{result} argument is a null
+ pointer, the return value is a pointer to an internal static string,
+@@ -3189,6 +3378,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun {char *} tmpnam_r (char *@var{result})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is nearly identical to the @code{tmpnam} function, except
+ that if @var{result} is a null pointer it returns a null pointer.
+ 
+@@ -3225,6 +3415,13 @@
+ @comment stdio.h
+ @comment SVID
+ @deftypefun {char *} tempnam (const char *@var{dir}, const char *@var{prefix})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c There's no way (short of being setuid) to avoid getenv("TMPDIR"),
++@c even with a non-NULL dir.
++@c
++@c __path_search (internal buf, dir, pfx, try_tmpdir) unsafe getenv
++@c __gen_tempname (internal tmpl, __GT_NOCREATE) ok
++@c strdup
+ This function generates a unique temporary file name.  If @var{prefix}
+ is not a null pointer, up to five characters of this string are used as
+ a prefix for the file name.  The return value is a string newly
+@@ -3288,6 +3485,8 @@
+ @comment stdlib.h
+ @comment Unix
+ @deftypefun {char *} mktemp (char *@var{template})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c __gen_tempname (caller tmpl, __GT_NOCREATE) ok
+ The @code{mktemp} function generates a unique file name by modifying
+ @var{template} as described above.  If successful, it returns
+ @var{template} as modified.  If @code{mktemp} cannot find a unique file
+@@ -3306,6 +3505,8 @@
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun int mkstemp (char *@var{template})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
++@c __gen_tempname (caller tmpl, __GT_FILE) ok
+ The @code{mkstemp} function generates a unique file name just as
+ @code{mktemp} does, but it also opens the file for you with @code{open}
+ (@pxref{Opening and Closing Files}).  If successful, it modifies
+@@ -3328,6 +3529,8 @@
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun {char *} mkdtemp (char *@var{template})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c __gen_tempname (caller tmpl, __GT_DIR) ok
+ The @code{mkdtemp} function creates a directory with a unique name.  If
+ it succeeds, it overwrites @var{template} with the name of the
+ directory, and returns @var{template}.  As with @code{mktemp} and
+@@ -3349,3 +3552,23 @@
+ @xref{Creating Directories}.
+ 
+ The @code{mkdtemp} function comes from OpenBSD.
++
++@c FIXME these are undocumented:
++@c faccessat
++@c fchmodat
++@c fchownat
++@c futimesat
++@c fstatat (there's a commented-out safety assessment for this one)
++@c linkat
++@c mkdirat
++@c mkfifoat
++@c name_to_handle_at
++@c openat
++@c open_by_handle_at
++@c readlinkat
++@c renameat
++@c scandirat
++@c symlinkat
++@c unlinkat
++@c utimensat
++@c mknodat
+diff -urN glibc-2.17-c758a686/manual/freemanuals.texi glibc/manual/freemanuals.texi
+--- glibc-2.17-c758a686/manual/freemanuals.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/freemanuals.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -1,4 +1,7 @@
+-@appendix Free Software Needs Free Documentation
++@c freemanuals.texi - blurb for free documentation.
++@c This file is intended to be included within another document,
++@c hence no sectioning command or @node.
++
+ @cindex free documentation
+ 
+ The biggest deficiency in the free software community today is not in
+diff -urN glibc-2.17-c758a686/manual/getopt.texi glibc/manual/getopt.texi
+--- glibc-2.17-c758a686/manual/getopt.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/getopt.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -59,7 +59,29 @@
+ 
+ @comment unistd.h
+ @comment POSIX.2
+-@deftypefun int getopt (int @var{argc}, char **@var{argv}, const char *@var{options})
++@deftypefun int getopt (int @var{argc}, char *const *@var{argv}, const char *@var{options})
++@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
++@c Swapping elements of passed-in argv may be partial in case of
++@c cancellation.  Gettext brings about a whole lot of AS and AC safety
++@c issues.  The getopt API involves returning values in the
++@c non-thread-specific optarg variable, which adds another thread-safety
++@c issue.  Given print_errors, it may output errors to stderr, which may
++@c self-deadlock, leak locks, or encounter (in a signal handler) or
++@c leave (in case of cancellation) stderr in an inconsistent state.
++@c Various implicit, indirect uses of malloc, in uses of memstream and
++@c asprintf for error-printing, bring about the usual malloc issues.
++@c (The explicit use of malloc in a conditional situation in
++@c _getopt_initialize is never exercised in glibc.)
++@c
++@c _getopt_internal
++@c  _getopt_internal_r
++@c   gettext
++@c   _getopt_initialize
++@c    getenv
++@c    malloc if USE_NONOPTION_FLAGS, never defined in libc
++@c   open_memstream
++@c   lockfile, unlockfile, __fxprintf -> stderr
++@c   asprintf
+ The @code{getopt} function gets the next option argument from the
+ argument list specified by the @var{argv} and @var{argc} arguments.
+ Normally these values come directly from the arguments received by
+@@ -225,6 +247,8 @@
+ @comment getopt.h
+ @comment GNU
+ @deftypefun int getopt_long (int @var{argc}, char *const *@var{argv}, const char *@var{shortopts}, const struct option *@var{longopts}, int *@var{indexptr})
++@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
++@c Same issues as getopt.
+ Decode options from the vector @var{argv} (whose length is @var{argc}).
+ The argument @var{shortopts} describes the short options to accept, just as
+ it does in @code{getopt}.  The argument @var{longopts} describes the long
+@@ -278,6 +302,8 @@
+ @comment getopt.h
+ @comment GNU
+ @deftypefun int getopt_long_only (int @var{argc}, char *const *@var{argv}, const char *@var{shortopts}, const struct option *@var{longopts}, int *@var{indexptr})
++@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
++@c Same issues as getopt.
+ 
+ The @code{getopt_long_only} function is equivalent to the
+ @code{getopt_long} function but it allows to specify the user of the
+diff -urN glibc-2.17-c758a686/manual/install-plain.texi glibc/manual/install-plain.texi
+--- glibc-2.17-c758a686/manual/install-plain.texi	1969-12-31 19:00:00.000000000 -0500
++++ glibc/manual/install-plain.texi	2014-09-12 16:10:06.046792714 -0400
+@@ -0,0 +1,5 @@
++@c This is for making the `INSTALL' file for the distribution.
++@c Makeinfo ignores it when processing the file from the include.
++@setfilename INSTALL
++@set plain
++@include install.texi
+diff -urN glibc-2.17-c758a686/manual/install.texi glibc/manual/install.texi
+--- glibc-2.17-c758a686/manual/install.texi	2014-09-12 16:08:17.783070851 -0400
++++ glibc/manual/install.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -1,10 +1,10 @@
+-@c This is for making the `INSTALL' file for the distribution.
+-@c Makeinfo ignores it when processing the file from the include.
+-@setfilename INSTALL
+ @include macros.texi
+ @include pkgvers.texi
+ 
++@ifclear plain
+ @node Installation, Maintenance, Library Summary, Top
++@end ifclear
++
+ @c %MENU% How to install the GNU C Library
+ @appendix Installing @theglibc{}
+ 
+@@ -21,6 +21,7 @@
+ You will need recent versions of several GNU tools: definitely GCC and
+ GNU Make, and possibly others.  @xref{Tools for Compilation}, below.
+ 
++@ifclear plain
+ @menu
+ * Configuring and compiling::   How to compile and test GNU libc.
+ * Running make install::        How to install it once you've got it
+@@ -29,6 +30,7 @@
+ * Linux::                       Specific advice for GNU/Linux systems.
+ * Reporting Bugs::              So they'll get fixed.
+ @end menu
++@end ifclear
+ 
+ @node Configuring and compiling
+ @appendixsec Configuring and compiling @theglibc{}
+@@ -138,11 +140,6 @@
+ Don't build libraries with profiling information.  You may want to use
+ this option if you don't plan to do profiling.
+ 
+-@item --disable-versioning
+-Don't compile the shared libraries with symbol version information.
+-Doing this will make the resulting library incompatible with old
+-binaries, so it's not recommended.
+-
+ @item --enable-static-nss
+ Compile static versions of the NSS (Name Service Switch) libraries.
+ This is not recommended because it defeats the purpose of NSS; a program
+@@ -155,6 +152,14 @@
+ prevented though there generally is no reason since it creates
+ compatibility problems.
+ 
++@item --enable-hardcoded-path-in-tests
++By default, dynamic tests are linked to run with the installed C library.
++This option hardcodes the newly built C library path in dynamic tests
++so that they can be invoked directly.
++
++@item --enable-lock-elision=yes
++Enable lock elision for pthread mutexes by default.
++
+ @pindex pt_chown
+ @findex grantpt
+ @item --enable-pt_chown
+@@ -180,11 +185,11 @@
+ 
+ If you only specify @samp{--host}, @code{configure} will prepare for a
+ native compile but use what you specify instead of guessing what your
+-system is. This is most useful to change the CPU submodel.  For example,
+-if @code{configure} guesses your machine as @code{i586-pc-linux-gnu} but
+-you want to compile a library for 386es, give
+-@samp{--host=i386-pc-linux-gnu} or just @samp{--host=i386-linux} and add
+-the appropriate compiler flags (@samp{-mcpu=i386} will do the trick) to
++system is.  This is most useful to change the CPU submodel.  For example,
++if @code{configure} guesses your machine as @code{i686-pc-linux-gnu} but
++you want to compile a library for 586es, give
++@samp{--host=i586-pc-linux-gnu} or just @samp{--host=i586-linux} and add
++the appropriate compiler flags (@samp{-mcpu=i586} will do the trick) to
+ @var{CFLAGS}.
+ 
+ If you specify just @samp{--build}, @code{configure} will get confused.
+@@ -230,6 +235,12 @@
+ system such as @file{/etc/passwd}, @file{/etc/nsswitch.conf} and others.
+ These files must all contain correct and sensible content.
+ 
++Normally, @code{make check} will run all the tests before reporting
++all problems found and exiting with error status if any problems
++occurred.  You can specify @samp{stop-on-test-failure=y} when running
++@code{make check} to make the test run stop and exit with an error
++status immediately when a failure occurs.
++
+ To format the @cite{GNU C Library Reference Manual} for printing, type
+ @w{@code{make dvi}}.  You need a working @TeX{} installation to do
+ this.  The distribution builds the on-line formatted version of the
+@@ -264,13 +275,15 @@
+ In general, when testing @theglibc{}, @samp{test-wrapper} may be set
+ to the name and arguments of any program to run newly built binaries.
+ This program must preserve the arguments to the binary being run, its
+-working directory, all environment variables set as part of testing
+-and the standard input, output and error file descriptors.  If
++working directory and the standard input, output and error file
++descriptors.  If
+ @samp{@var{test-wrapper} env} will not work to run a program with
+ environment variables set, then @samp{test-wrapper-env} must be set to
+ a program that runs a newly built program with environment variable
+ assignments in effect, those assignments being specified as
+-@samp{@var{var}=@var{value}} before the name of the program to be run.
++@samp{@var{var}=@var{value}} before the name of the program to be
++run.  If multiple assignments to the same variable are specified,
++the last assignment specified must take precedence.
+ 
+ 
+ @node Running make install
+@@ -278,7 +291,7 @@
+ @cindex installing
+ 
+ To install the library and its header files, and the Info files of the
+-manual, type @code{env LANGUAGE=C LC_ALL=C make install}.  This will
++manual, type @code{make install}.  This will
+ build things, if necessary, before installing them; however, you should
+ still compile everything first.  If you are installing @theglibc{} as your
+ primary C library, we recommend that you shut the system down to
+@@ -317,14 +330,11 @@
+ well.
+ 
+ One auxiliary program, @file{/usr/libexec/pt_chown}, is installed setuid
+-@code{root}.  This program is invoked by the @code{grantpt} function; it
+-sets the permissions on a pseudoterminal so it can be used by the
+-calling process.  This means programs like @code{xterm} and
+-@code{screen} do not have to be setuid to get a pty.  (There may be
+-other reasons why they need privileges.)  If you are using a
+-Linux kernel with the @code{devptsfs} or @code{devfs} filesystems
+-providing pty slaves, you don't need this program; otherwise you do.
+-The source for @file{pt_chown} is in @file{login/programs/pt_chown.c}.
++@code{root} if the @samp{--enable-pt_chown} configuration option is used.
++This program is invoked by the @code{grantpt} function; it sets the
++permissions on a pseudoterminal so it can be used by the calling process.
++If you are using a Linux kernel with the @code{devpts} filesystem enabled
++and mounted at @file{/dev/pts}, you don't need this program.
+ 
+ After installation you might want to configure the timezone and locale
+ installation of your system.  @Theglibc{} comes with a locale
+@@ -362,9 +372,9 @@
+ bugs or lack features.
+ 
+ @item
+-GCC 4.3 or newer, GCC 4.6 recommended
++GCC 4.4 or newer, GCC 4.6 recommended
+ 
+-GCC 4.3 or higher is required; as of this writing, GCC 4.6 is the
++GCC 4.4 or higher is required; as of this writing, GCC 4.6 is the
+ compiler we advise to use to build @theglibc{}.
+ 
+ You can use whatever compiler you like to compile programs that use
+@@ -388,10 +398,11 @@
+ mechanism for the info files is not present or works differently.
+ 
+ @item
+-GNU @code{awk} 3.0, or higher
++GNU @code{awk} 3.1.2, or higher
+ 
+-@code{Awk} is used in several places to generate files.
+-@code{gawk} 3.0 is known to work.
++@code{awk} is used in several places to generate files.
++Some @code{gawk} extensions are used, including the @code{asorti}
++function, which was introduced in version 3.1.2 of @code{gawk}.
+ 
+ @item
+ Perl 5
+@@ -412,7 +423,7 @@
+ @end itemize
+ 
+ @noindent
+-If you change any of the @file{configure.in} files you will also need
++If you change any of the @file{configure.ac} files you will also need
+ 
+ @itemize @bullet
+ @item
+@@ -436,7 +447,7 @@
+ @cindex kernel header files
+ 
+ If you are installing @theglibc{} on @gnulinuxsystems{}, you need to have
+-the header files from a 2.6.19.1 or newer kernel around for reference.
++the header files from a 2.6.32 or newer kernel around for reference.
+ These headers must be installed using @samp{make headers_install}; the
+ headers present in the kernel source directory are not suitable for
+ direct use by @theglibc{}.  You do not need to use that kernel, just have
+diff -urN glibc-2.17-c758a686/manual/intro.texi glibc/manual/intro.texi
+--- glibc-2.17-c758a686/manual/intro.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/intro.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -159,6 +159,14 @@
+ These include utilities for dealing with regular expressions and other
+ pattern matching facilities (@pxref{Pattern Matching}).
+ 
++@menu
++* POSIX Safety Concepts::       Safety concepts from POSIX.
++* Unsafe Features::             Features that make functions unsafe.
++* Conditionally Safe Features:: Features that make functions unsafe
++                                 in the absence of workarounds.
++* Other Safety Remarks::        Additional safety features and remarks.
++@end menu
++
+ @comment Roland sez:
+ @comment The GNU C library as it stands conforms to 1003.2 draft 11, which
+ @comment specifies:
+@@ -172,6 +180,725 @@
+ @comment <wordexp.h> (not yet implemented)
+ @comment confstr
+ 
++@node POSIX Safety Concepts, Unsafe Features, , POSIX
++@subsubsection POSIX Safety Concepts
++@cindex POSIX Safety Concepts
++
++This manual documents various safety properties of @glibcadj{}
++functions, in lines that follow their prototypes and look like:
++
++@sampsafety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++
++The properties are assessed according to the criteria set forth in the
++POSIX standard for such safety contexts as Thread-, Async-Signal- and
++Async-Cancel- -Safety.  Intuitive definitions of these properties,
++attempting to capture the meaning of the standard definitions, follow.
++
++@itemize @bullet
++
++@item
++@cindex MT-Safe
++@cindex Thread-Safe
++@code{MT-Safe} or Thread-Safe functions are safe to call in the presence
++of other threads.  MT, in MT-Safe, stands for Multi Thread.
++
++Being MT-Safe does not imply a function is atomic, nor that it uses any
++of the memory synchronization mechanisms POSIX exposes to users.  It is
++even possible that calling MT-Safe functions in sequence does not yield
++an MT-Safe combination.  For example, having a thread call two MT-Safe
++functions one right after the other does not guarantee behavior
++equivalent to atomic execution of a combination of both functions, since
++concurrent calls in other threads may interfere in a destructive way.
++
++Whole-program optimizations that could inline functions across library
++interfaces may expose unsafe reordering, and so performing inlining
++across the @glibcadj{} interface is not recommended.  The documented
++MT-Safety status is not guaranteed under whole-program optimization.
++However, functions defined in user-visible headers are designed to be
++safe for inlining.
++
++
++@item
++@cindex AS-Safe
++@cindex Async-Signal-Safe
++@code{AS-Safe} or Async-Signal-Safe functions are safe to call from
++asynchronous signal handlers.  AS, in AS-Safe, stands for Asynchronous
++Signal.
++
++Many functions that are AS-Safe may set @code{errno}, or modify the
++floating-point environment, because their doing so does not make them
++unsuitable for use in signal handlers.  However, programs could
++misbehave should asynchronous signal handlers modify this thread-local
++state, and the signal handling machinery cannot be counted on to
++preserve it.  Therefore, signal handlers that call functions that may
++set @code{errno} or modify the floating-point environment @emph{must}
++save their original values, and restore them before returning.
++
++
++@item
++@cindex AC-Safe
++@cindex Async-Cancel-Safe
++@code{AC-Safe} or Async-Cancel-Safe functions are safe to call when
++asynchronous cancellation is enabled.  AC in AC-Safe stands for
++Asynchronous Cancellation.
++
++The POSIX standard defines only three functions to be AC-Safe, namely
++@code{pthread_cancel}, @code{pthread_setcancelstate}, and
++@code{pthread_setcanceltype}.  At present @theglibc{} provides no
++guarantees beyond these three functions, but does document which
++functions are presently AC-Safe.  This documentation is provided for use
++by @theglibc{} developers.
++
++Just like signal handlers, cancellation cleanup routines must configure
++the floating point environment they require.  The routines cannot assume
++a floating point environment, particularly when asynchronous
++cancellation is enabled.  If the configuration of the floating point
++environment cannot be performed atomically then it is also possible that
++the environment encountered is internally inconsistent.
++
++
++@item
++@cindex MT-Unsafe
++@cindex Thread-Unsafe
++@cindex AS-Unsafe
++@cindex Async-Signal-Unsafe
++@cindex AC-Unsafe
++@cindex Async-Cancel-Unsafe
++@code{MT-Unsafe}, @code{AS-Unsafe}, @code{AC-Unsafe} functions are not
++safe to call within the safety contexts described above.  Calling them
++within such contexts invokes undefined behavior.
++
++Functions not explicitly documented as safe in a safety context should
++be regarded as Unsafe.
++
++
++@item
++@cindex Preliminary
++@code{Preliminary} safety properties are documented, indicating these
++properties may @emph{not} be counted on in future releases of
++@theglibc{}.
++
++Such preliminary properties are the result of an assessment of the
++properties of our current implementation, rather than of what is
++mandated and permitted by current and future standards.
++
++Although we strive to abide by the standards, in some cases our
++implementation is safe even when the standard does not demand safety,
++and in other cases our implementation does not meet the standard safety
++requirements.  The latter are most likely bugs; the former, when marked
++as @code{Preliminary}, should not be counted on: future standards may
++require changes that are not compatible with the additional safety
++properties afforded by the current implementation.
++
++Furthermore, the POSIX standard does not offer a detailed definition of
++safety.  We assume that, by ``safe to call'', POSIX means that, as long
++as the program does not invoke undefined behavior, the ``safe to call''
++function behaves as specified, and does not cause other functions to
++deviate from their specified behavior.  We have chosen to use its loose
++definitions of safety, not because they are the best definitions to use,
++but because choosing them harmonizes this manual with POSIX.
++
++Please keep in mind that these are preliminary definitions and
++annotations, and certain aspects of the definitions are still under
++discussion and might be subject to clarification or change.
++
++Over time, we envision evolving the preliminary safety notes into stable
++commitments, as stable as those of our interfaces.  As we do, we will
++remove the @code{Preliminary} keyword from safety notes.  As long as the
++keyword remains, however, they are not to be regarded as a promise of
++future behavior.
++
++
++@end itemize
++
++Other keywords that appear in safety notes are defined in subsequent
++sections.
++
++
++@node Unsafe Features, Conditionally Safe Features, POSIX Safety Concepts, POSIX
++@subsubsection Unsafe Features
++@cindex Unsafe Features
++
++Functions that are unsafe to call in certain contexts are annotated with
++keywords that document their features that make them unsafe to call.
++AS-Unsafe features in this section indicate the functions are never safe
++to call when asynchronous signals are enabled.  AC-Unsafe features
++indicate they are never safe to call when asynchronous cancellation is
++enabled.  There are no MT-Unsafe marks in this section.
++
++@itemize @bullet
++
++@item @code{lock}
++@cindex lock
++
++Functions marked with @code{lock} as an AS-Unsafe feature may be
++interrupted by a signal while holding a non-recursive lock.  If the
++signal handler calls another such function that takes the same lock, the
++result is a deadlock.
++
++Functions annotated with @code{lock} as an AC-Unsafe feature may, if
++cancelled asynchronously, fail to release a lock that would have been
++released if their execution had not been interrupted by asynchronous
++thread cancellation.  Once a lock is left taken, attempts to take that
++lock will block indefinitely.
++
++
++@item @code{corrupt}
++@cindex corrupt
++
++Functions marked with @code{corrupt} as an AS-Unsafe feature may corrupt
++data structures and misbehave when they interrupt, or are interrupted
++by, another such function.  Unlike functions marked with @code{lock},
++these take recursive locks to avoid MT-Safety problems, but this is not
++enough to stop a signal handler from observing a partially-updated data
++structure.  Further corruption may arise from the interrupted function's
++failure to notice updates made by signal handlers.
++
++Functions marked with @code{corrupt} as an AC-Unsafe feature may leave
++data structures in a corrupt, partially updated state.  Subsequent uses
++of the data structure may misbehave.
++
++@c A special case, probably not worth documenting separately, involves
++@c reallocing, or even freeing pointers.  Any case involving free could
++@c be easily turned into an ac-safe leak by resetting the pointer before
++@c releasing it; I don't think we have any case that calls for this sort
++@c of fixing.  Fixing the realloc cases would require a new interface:
++@c instead of @code{ptr=realloc(ptr,size)} we'd have to introduce
++@c @code{acsafe_realloc(&ptr,size)} that would modify ptr before
++@c releasing the old memory.  The ac-unsafe realloc could be implemented
++@c in terms of an internal interface with this semantics (say
++@c __acsafe_realloc), but since realloc can be overridden, the function
++@c we call to implement realloc should not be this internal interface,
++@c but another internal interface that calls __acsafe_realloc if realloc
++@c was not overridden, and calls the overridden realloc with async
++@c cancel disabled.  --lxoliva
++
++
++@item @code{heap}
++@cindex heap
++
++Functions marked with @code{heap} may call heap memory management
++functions from the @code{malloc}/@code{free} family of functions and are
++only as safe as those functions.  This note is thus equivalent to:
++
++@sampsafety{@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++
++
++@c Check for cases that should have used plugin instead of or in
++@c addition to this.  Then, after rechecking gettext, adjust i18n if
++@c needed.
++@item @code{dlopen}
++@cindex dlopen
++
++Functions marked with @code{dlopen} use the dynamic loader to load
++shared libraries into the current execution image.  This involves
++opening files, mapping them into memory, allocating additional memory,
++resolving symbols, applying relocations and more, all of this while
++holding internal dynamic loader locks.
++
++The locks are enough for these functions to be AS- and AC-Unsafe, but
++other issues may arise.  At present this is a placeholder for all
++potential safety issues raised by @code{dlopen}.
++
++@c dlopen runs init and fini sections of the module; does this mean
++@c dlopen always implies plugin?
++
++
++@item @code{plugin}
++@cindex plugin
++
++Functions annotated with @code{plugin} may run code from plugins that
++may be external to @theglibc{}.  Such plugin functions are assumed to be
++MT-Safe, AS-Unsafe and AC-Unsafe.  Examples of such plugins are stack
++@cindex NSS
++unwinding libraries, name service switch (NSS) and character set
++@cindex iconv
++conversion (iconv) back-ends.
++
++Although the plugins mentioned as examples are all brought in by means
++of dlopen, the @code{plugin} keyword does not imply any direct
++involvement of the dynamic loader or the @code{libdl} interfaces, those
++are covered by @code{dlopen}.  For example, if one function loads a
++module and finds the addresses of some of its functions, while another
++just calls those already-resolved functions, the former will be marked
++with @code{dlopen}, whereas the latter will get the @code{plugin}.  When
++a single function takes all of these actions, then it gets both marks.
++
++
++@item @code{i18n}
++@cindex i18n
++
++Functions marked with @code{i18n} may call internationalization
++functions of the @code{gettext} family and will be only as safe as those
++functions.  This note is thus equivalent to:
++
++@sampsafety{@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascudlopen{}}@acunsafe{@acucorrupt{}}}
++
++
++@item @code{timer}
++@cindex timer
++
++Functions marked with @code{timer} use the @code{alarm} function or
++similar to set a time-out for a system call or a long-running operation.
++In a multi-threaded program, there is a risk that the time-out signal
++will be delivered to a different thread, thus failing to interrupt the
++intended thread.  Besides being MT-Unsafe, such functions are always
++AS-Unsafe, because calling them in signal handlers may interfere with
++timers set in the interrupted code, and AC-Unsafe, because there is no
++safe way to guarantee an earlier timer will be reset in case of
++asynchronous cancellation.
++
++@end itemize
++
++
++@node Conditionally Safe Features, Other Safety Remarks, Unsafe Features, POSIX
++@subsubsection Conditionally Safe Features
++@cindex Conditionally Safe Features
++
++For some features that make functions unsafe to call in certain
++contexts, there are known ways to avoid the safety problem other than
++refraining from calling the function altogether.  The keywords that
++follow refer to such features, and each of their definitions indicate
++how the whole program needs to be constrained in order to remove the
++safety problem indicated by the keyword.  Only when all the reasons that
++make a function unsafe are observed and addressed, by applying the
++documented constraints, does the function become safe to call in a
++context.
++
++@itemize @bullet
++
++@item @code{init}
++@cindex init
++
++Functions marked with @code{init} as an MT-Unsafe feature perform
++MT-Unsafe initialization when they are first called.
++
++Calling such a function at least once in single-threaded mode removes
++this specific cause for the function to be regarded as MT-Unsafe.  If no
++other cause for that remains, the function can then be safely called
++after other threads are started.
++
++Functions marked with @code{init} as an AS- or AC-Unsafe feature use the
++internal @code{libc_once} machinery or similar to initialize internal
++data structures.
++
++If a signal handler interrupts such an initializer, and calls any
++function that also performs @code{libc_once} initialization, it will
++deadlock if the thread library has been loaded.
++
++Furthermore, if an initializer is partially complete before it is
++canceled or interrupted by a signal whose handler requires the same
++initialization, some or all of the initialization may be performed more
++than once, leaking resources or even resulting in corrupt internal data.
++
++Applications that need to call functions marked with @code{init} as an
++AS- or AC-Unsafe feature should ensure the initialization is performed
++before configuring signal handlers or enabling cancellation, so that the
++AS- and AC-Safety issues related with @code{libc_once} do not arise.
++
++@c We may have to extend the annotations to cover conditions in which
++@c initialization may or may not occur, since an initial call in a safe
++@c context is no use if the initialization doesn't take place at that
++@c time: it doesn't remove the risk for later calls.
++
++
++@item @code{race}
++@cindex race
++
++Functions annotated with @code{race} as an MT-Safety issue operate on
++objects in ways that may cause data races or similar forms of
++destructive interference out of concurrent execution.  In some cases,
++the objects are passed to the functions by users; in others, they are
++used by the functions to return values to users; in others, they are not
++even exposed to users.
++
++We consider access to objects passed as (indirect) arguments to
++functions to be data race free.  The assurance of data race free objects
++is the caller's responsibility.  We will not mark a function as
++MT-Unsafe or AS-Unsafe if it misbehaves when users fail to take the
++measures required by POSIX to avoid data races when dealing with such
++objects.  As a general rule, if a function is documented as reading from
++an object passed (by reference) to it, or modifying it, users ought to
++use memory synchronization primitives to avoid data races just as they
++would should they perform the accesses themselves rather than by calling
++the library function.  @code{FILE} streams are the exception to the
++general rule, in that POSIX mandates the library to guard against data
++races in many functions that manipulate objects of this specific opaque
++type.  We regard this as a convenience provided to users, rather than as
++a general requirement whose expectations should extend to other types.
++
++In order to remind users that guarding certain arguments is their
++responsibility, we will annotate functions that take objects of certain
++types as arguments.  We draw the line for objects passed by users as
++follows: objects whose types are exposed to users, and that users are
++expected to access directly, such as memory buffers, strings, and
++various user-visible @code{struct} types, do @emph{not} give reason for
++functions to be annotated with @code{race}.  It would be noisy and
++redundant with the general requirement, and not many would be surprised
++by the library's lack of internal guards when accessing objects that can
++be accessed directly by users.
++
++As for objects that are opaque or opaque-like, in that they are to be
++manipulated only by passing them to library functions (e.g.,
++@code{FILE}, @code{DIR}, @code{obstack}, @code{iconv_t}), there might be
++additional expectations as to internal coordination of access by the
++library.  We will annotate, with @code{race} followed by a colon and the
++argument name, functions that take such objects but that do not take
++care of synchronizing access to them by default.  For example,
++@code{FILE} stream @code{unlocked} functions will be annotated, but
++those that perform implicit locking on @code{FILE} streams by default
++will not, even though the implicit locking may be disabled on a
++per-stream basis.
++
++In either case, we will not regard as MT-Unsafe functions that may
++access user-supplied objects in unsafe ways should users fail to ensure
++the accesses are well defined.  The notion prevails that users are
++expected to safeguard against data races any user-supplied objects that
++the library accesses on their behalf.
++
++@c The above describes @mtsrace; @mtasurace is described below.
++
++This user responsibility does not apply, however, to objects controlled
++by the library itself, such as internal objects and static buffers used
++to return values from certain calls.  When the library doesn't guard
++them against concurrent uses, these cases are regarded as MT-Unsafe and
++AS-Unsafe (although the @code{race} mark under AS-Unsafe will be omitted
++as redundant with the one under MT-Unsafe).  As in the case of
++user-exposed objects, the mark may be followed by a colon and an
++identifier.  The identifier groups all functions that operate on a
++certain unguarded object; users may avoid the MT-Safety issues related
++with unguarded concurrent access to such internal objects by creating a
++non-recursive mutex related with the identifier, and always holding the
++mutex when calling any function marked as racy on that identifier, as
++they would have to should the identifier be an object under user
++control.  The non-recursive mutex avoids the MT-Safety issue, but it
++trades one AS-Safety issue for another, so use in asynchronous signals
++remains undefined.
++
++When the identifier relates to a static buffer used to hold return
++values, the mutex must be held for as long as the buffer remains in use
++by the caller.  Many functions that return pointers to static buffers
++offer reentrant variants that store return values in caller-supplied
++buffers instead.  In some cases, such as @code{tmpname}, the variant is
++chosen not by calling an alternate entry point, but by passing a
++non-@code{NULL} pointer to the buffer in which the returned values are
++to be stored.  These variants are generally preferable in multi-threaded
++programs, although some of them are not MT-Safe because of other
++internal buffers, also documented with @code{race} notes.
++
++
++@item @code{const}
++@cindex const
++
++Functions marked with @code{const} as an MT-Safety issue non-atomically
++modify internal objects that are better regarded as constant, because a
++substantial portion of @theglibc{} accesses them without
++synchronization.  Unlike @code{race}, that causes both readers and
++writers of internal objects to be regarded as MT-Unsafe and AS-Unsafe,
++this mark is applied to writers only.  Writers remain equally MT- and
++AS-Unsafe to call, but the then-mandatory constness of objects they
++modify enables readers to be regarded as MT-Safe and AS-Safe (as long as
++no other reasons for them to be unsafe remain), since the lack of
++synchronization is not a problem when the objects are effectively
++constant.
++
++The identifier that follows the @code{const} mark will appear by itself
++as a safety note in readers.  Programs that wish to work around this
++safety issue, so as to call writers, may use a non-recursve
++@code{rwlock} associated with the identifier, and guard @emph{all} calls
++to functions marked with @code{const} followed by the identifier with a
++write lock, and @emph{all} calls to functions marked with the identifier
++by itself with a read lock.  The non-recursive locking removes the
++MT-Safety problem, but it trades one AS-Safety problem for another, so
++use in asynchronous signals remains undefined.
++
++@c But what if, instead of marking modifiers with const:id and readers
++@c with just id, we marked writers with race:id and readers with ro:id?
++@c Instead of having to define each instance of “id”, we'd have a
++@c general pattern governing all such “id”s, wherein race:id would
++@c suggest the need for an exclusive/write lock to make the function
++@c safe, whereas ro:id would indicate “id” is expected to be read-only,
++@c but if any modifiers are called (while holding an exclusive lock),
++@c then ro:id-marked functions ought to be guarded with a read lock for
++@c safe operation.  ro:env or ro:locale, for example, seems to convey
++@c more clearly the expectations and the meaning, than just env or
++@c locale.
++
++
++@item @code{sig}
++@cindex sig
++
++Functions marked with @code{sig} as a MT-Safety issue (that implies an
++identical AS-Safety issue, omitted for brevity) may temporarily install
++a signal handler for internal purposes, which may interfere with other
++uses of the signal, identified after a colon.
++
++This safety problem can be worked around by ensuring that no other uses
++of the signal will take place for the duration of the call.  Holding a
++non-recursive mutex while calling all functions that use the same
++temporary signal; blocking that signal before the call and resetting its
++handler afterwards is recommended.
++
++There is no safe way to guarantee the original signal handler is
++restored in case of asynchronous cancellation, therefore so-marked
++functions are also AC-Unsafe.
++
++@c fixme: at least deferred cancellation should get it right, and would
++@c obviate the restoring bit below, and the qualifier above.
++
++Besides the measures recommended to work around the MT- and AS-Safety
++problem, in order to avert the cancellation problem, disabling
++asynchronous cancellation @emph{and} installing a cleanup handler to
++restore the signal to the desired state and to release the mutex are
++recommended.
++
++
++@item @code{term}
++@cindex term
++
++Functions marked with @code{term} as an MT-Safety issue may change the
++terminal settings in the recommended way, namely: call @code{tcgetattr},
++modify some flags, and then call @code{tcsetattr}; this creates a window
++in which changes made by other threads are lost.  Thus, functions marked
++with @code{term} are MT-Unsafe.  The same window enables changes made by
++asynchronous signals to be lost.  These functions are also AS-Unsafe,
++but the corresponding mark is omitted as redundant.
++
++It is thus advisable for applications using the terminal to avoid
++concurrent and reentrant interactions with it, by not using it in signal
++handlers or blocking signals that might use it, and holding a lock while
++calling these functions and interacting with the terminal.  This lock
++should also be used for mutual exclusion with functions marked with
++@code{@mtasurace{:tcattr(fd)}}, where @var{fd} is a file descriptor for
++the controlling terminal.  The caller may use a single mutex for
++simplicity, or use one mutex per terminal, even if referenced by
++different file descriptors.
++
++Functions marked with @code{term} as an AC-Safety issue are supposed to
++restore terminal settings to their original state, after temporarily
++changing them, but they may fail to do so if cancelled.
++
++@c fixme: at least deferred cancellation should get it right, and would
++@c obviate the restoring bit below, and the qualifier above.
++
++Besides the measures recommended to work around the MT- and AS-Safety
++problem, in order to avert the cancellation problem, disabling
++asynchronous cancellation @emph{and} installing a cleanup handler to
++restore the terminal settings to the original state and to release the
++mutex are recommended.
++
++
++@end itemize
++
++
++@node Other Safety Remarks, , Conditionally Safe Features, POSIX
++@subsubsection Other Safety Remarks
++@cindex Other Safety Remarks
++
++Additional keywords may be attached to functions, indicating features
++that do not make a function unsafe to call, but that may need to be
++taken into account in certain classes of programs:
++
++@itemize @bullet
++
++@item @code{locale}
++@cindex locale
++
++Functions annotated with @code{locale} as an MT-Safety issue read from
++the locale object without any form of synchronization.  Functions
++annotated with @code{locale} called concurrently with locale changes may
++behave in ways that do not correspond to any of the locales active
++during their execution, but an unpredictable mix thereof.
++
++We do not mark these functions as MT- or AS-Unsafe, however, because
++functions that modify the locale object are marked with
++@code{const:locale} and regarded as unsafe.  Being unsafe, the latter
++are not to be called when multiple threads are running or asynchronous
++signals are enabled, and so the locale can be considered effectively
++constant in these contexts, which makes the former safe.
++
++@c Should the locking strategy suggested under @code{const} be used,
++@c failure to guard locale uses is not as fatal as data races in
++@c general: unguarded uses will @emph{not} follow dangling pointers or
++@c access uninitialized, unmapped or recycled memory.  Each access will
++@c read from a consistent locale object that is or was active at some
++@c point during its execution.  Without synchronization, however, it
++@c cannot even be assumed that, after a change in locale, earlier
++@c locales will no longer be used, even after the newly-chosen one is
++@c used in the thread.  Nevertheless, even though unguarded reads from
++@c the locale will not violate type safety, functions that access the
++@c locale multiple times may invoke all sorts of undefined behavior
++@c because of the unexpected locale changes.
++
++
++@item @code{env}
++@cindex env
++
++Functions marked with @code{env} as an MT-Safety issue access the
++environment with @code{getenv} or similar, without any guards to ensure
++safety in the presence of concurrent modifications.
++
++We do not mark these functions as MT- or AS-Unsafe, however, because
++functions that modify the environment are all marked with
++@code{const:env} and regarded as unsafe.  Being unsafe, the latter are
++not to be called when multiple threads are running or asynchronous
++signals are enabled, and so the environment can be considered
++effectively constant in these contexts, which makes the former safe.
++
++
++@item @code{hostid}
++@cindex hostid
++
++The function marked with @code{hostid} as an MT-Safety issue reads from
++the system-wide data structures that hold the ``host ID'' of the
++machine.  These data structures cannot generally be modified atomically.
++Since it is expected that the ``host ID'' will not normally change, the
++function that reads from it (@code{gethostid}) is regarded as safe,
++whereas the function that modifies it (@code{sethostid}) is marked with
++@code{@mtasuconst{:@mtshostid{}}}, indicating it may require special
++care if it is to be called.  In this specific case, the special care
++amounts to system-wide (not merely intra-process) coordination.
++
++
++@item @code{sigintr}
++@cindex sigintr
++
++Functions marked with @code{sigintr} as an MT-Safety issue access the
++@code{_sigintr} internal data structure without any guards to ensure
++safety in the presence of concurrent modifications.
++
++We do not mark these functions as MT- or AS-Unsafe, however, because
++functions that modify the this data structure are all marked with
++@code{const:sigintr} and regarded as unsafe.  Being unsafe, the latter
++are not to be called when multiple threads are running or asynchronous
++signals are enabled, and so the data structure can be considered
++effectively constant in these contexts, which makes the former safe.
++
++
++@item @code{fd}
++@cindex fd
++
++Functions annotated with @code{fd} as an AC-Safety issue may leak file
++descriptors if asynchronous thread cancellation interrupts their
++execution.
++
++Functions that allocate or deallocate file descriptors will generally be
++marked as such.  Even if they attempted to protect the file descriptor
++allocation and deallocation with cleanup regions, allocating a new
++descriptor and storing its number where the cleanup region could release
++it cannot be performed as a single atomic operation.  Similarly,
++releasing the descriptor and taking it out of the data structure
++normally responsible for releasing it cannot be performed atomically.
++There will always be a window in which the descriptor cannot be released
++because it was not stored in the cleanup handler argument yet, or it was
++already taken out before releasing it.  It cannot be taken out after
++release: an open descriptor could mean either that the descriptor still
++has to be closed, or that it already did so but the descriptor was
++reallocated by another thread or signal handler.
++
++Such leaks could be internally avoided, with some performance penalty,
++by temporarily disabling asynchronous thread cancellation.  However,
++since callers of allocation or deallocation functions would have to do
++this themselves, to avoid the same sort of leak in their own layer, it
++makes more sense for the library to assume they are taking care of it
++than to impose a performance penalty that is redundant when the problem
++is solved in upper layers, and insufficient when it is not.
++
++This remark by itself does not cause a function to be regarded as
++AC-Unsafe.  However, cumulative effects of such leaks may pose a
++problem for some programs.  If this is the case, suspending asynchronous
++cancellation for the duration of calls to such functions is recommended.
++
++
++@item @code{mem}
++@cindex mem
++
++Functions annotated with @code{mem} as an AC-Safety issue may leak
++memory if asynchronous thread cancellation interrupts their execution.
++
++The problem is similar to that of file descriptors: there is no atomic
++interface to allocate memory and store its address in the argument to a
++cleanup handler, or to release it and remove its address from that
++argument, without at least temporarily disabling asynchronous
++cancellation, which these functions do not do.
++
++This remark does not by itself cause a function to be regarded as
++generally AC-Unsafe.  However, cumulative effects of such leaks may be
++severe enough for some programs that disabling asynchronous cancellation
++for the duration of calls to such functions may be required.
++
++
++@item @code{cwd}
++@cindex cwd
++
++Functions marked with @code{cwd} as an MT-Safety issue may temporarily
++change the current working directory during their execution, which may
++cause relative pathnames to be resolved in unexpected ways in other
++threads or within asynchronous signal or cancellation handlers.
++
++This is not enough of a reason to mark so-marked functions as MT- or
++AS-Unsafe, but when this behavior is optional (e.g., @code{nftw} with
++@code{FTW_CHDIR}), avoiding the option may be a good alternative to
++using full pathnames or file descriptor-relative (e.g. @code{openat})
++system calls.
++
++
++@item @code{!posix}
++@cindex !posix
++
++This remark, as an MT-, AS- or AC-Safety note to a function, indicates
++the safety status of the function is known to differ from the specified
++status in the POSIX standard.  For example, POSIX does not require a
++function to be Safe, but our implementation is, or vice-versa.
++
++For the time being, the absence of this remark does not imply the safety
++properties we documented are identical to those mandated by POSIX for
++the corresponding functions.
++
++
++@item @code{:identifier}
++@cindex :identifier
++
++Annotations may sometimes be followed by identifiers, intended to group
++several functions that e.g. access the data structures in an unsafe way,
++as in @code{race} and @code{const}, or to provide more specific
++information, such as naming a signal in a function marked with
++@code{sig}.  It is envisioned that it may be applied to @code{lock} and
++@code{corrupt} as well in the future.
++
++In most cases, the identifier will name a set of functions, but it may
++name global objects or function arguments, or identifiable properties or
++logical components associated with them, with a notation such as
++e.g. @code{:buf(arg)} to denote a buffer associated with the argument
++@var{arg}, or @code{:tcattr(fd)} to denote the terminal attributes of a
++file descriptor @var{fd}.
++
++The most common use for identifiers is to provide logical groups of
++functions and arguments that need to be protected by the same
++synchronization primitive in order to ensure safe operation in a given
++context.
++
++
++@item @code{/condition}
++@cindex /condition
++
++Some safety annotations may be conditional, in that they only apply if a
++boolean expression involving arguments, global variables or even the
++underlying kernel evaluates evaluates to true.  Such conditions as
++@code{/hurd} or @code{/!linux!bsd} indicate the preceding marker only
++applies when the underlying kernel is the HURD, or when it is neither
++Linux nor a BSD kernel, respectively.  @code{/!ps} and
++@code{/one_per_line} indicate the preceding marker only applies when
++argument @var{ps} is NULL, or global variable @var{one_per_line} is
++nonzero.
++
++When all marks that render a function unsafe are adorned with such
++conditions, and none of the named conditions hold, then the function can
++be regarded as safe.
++
++
++@end itemize
++
+ 
+ @node Berkeley Unix, SVID, POSIX, Standards and Portability
+ @subsection Berkeley Unix
+@@ -556,19 +1283,59 @@
+ Here is an overview of the contents of the remaining chapters of
+ this manual.
+ 
++@c The chapter overview ordering is:
++@c Error Reporting (2)
++@c Virtual Memory Allocation and Paging (3)
++@c Character Handling (4)
++@c Strings and Array Utilities (5)
++@c Character Set Handling (6)
++@c Locales and Internationalization (7)
++@c Searching and Sorting (9)
++@c Pattern Matching (10)
++@c Input/Output Overview (11)
++@c Input/Output on Streams (12)
++@c Low-level Input/Ooutput (13)
++@c File System Interface (14)
++@c Pipes and FIFOs (15)
++@c Sockets (16)
++@c Low-Level Terminal Interface (17)
++@c Syslog (18)
++@c Mathematics (19)
++@c Aritmetic Functions (20)
++@c Date and Time (21)
++@c Non-Local Exist (23)
++@c Signal Handling (24)
++@c The Basic Program/System Interface (25)
++@c Processes (26)
++@c Job Control (28)
++@c System Databases and Name Service Switch (29)
++@c Users and Groups (30) -- References `User Database' and `Group Database'
++@c System Management (31)
++@c System Configuration Parameters (32)
++@c C Language Facilities in the Library (AA)
++@c Summary of Library Facilities (AB)
++@c Installing (AC)
++@c Library Maintenance (AD)
++
++@c The following chapters need overview text to be added:
++@c Message Translation (8)
++@c Resource Usage And Limitations (22)
++@c Inter-Process Communication (27)
++@c DES Encryption and Password Handling (33)
++@c Debugging support (34)
++@c POSIX Threads (35)
++@c Internal Probes (36)
++@c Platform-specific facilities (AE)
++@c Contributors to (AF)
++@c Free Software Needs Free Documentation (AG)
++@c GNU Lesser General Public License (AH)
++@c GNU Free Documentation License (AI)
++
+ @itemize @bullet
+ @item
+ @ref{Error Reporting}, describes how errors detected by the library
+ are reported.
+ 
+-@item
+-@ref{Language Features}, contains information about library support for
+-standard parts of the C language, including things like the @code{sizeof}
+-operator and the symbolic constant @code{NULL}, how to write functions
+-accepting variable numbers of arguments, and constants describing the
+-ranges and other properties of the numerical types.  There is also a simple
+-debugging mechanism which allows you to put assertions in your code, and
+-have diagnostic messages printed if the tests fail.
+ 
+ @item
+ @ref{Memory}, describes @theglibc{}'s facilities for managing and
+@@ -588,6 +1355,26 @@
+ byte arrays, including operations such as copying and comparison.
+ 
+ @item
++@ref{Character Set Handling}, contains information about manipulating
++characters and strings using character sets larger than will fit in
++the usual @code{char} data type.
++
++@item
++@ref{Locales}, describes how selecting a particular country
++or language affects the behavior of the library.  For example, the locale
++affects collation sequences for strings and how monetary values are
++formatted.
++
++@item
++@ref{Searching and Sorting}, contains information about functions
++for searching and sorting arrays.  You can use these functions on any
++kind of array by providing an appropriate comparison function.
++
++@item
++@ref{Pattern Matching}, presents functions for matching regular expressions
++and shell file name patterns, and for expanding words as the shell does.
++
++@item
+ @ref{I/O Overview}, gives an overall look at the input and output
+ facilities in the library, and contains information about basic concepts
+ such as file names.
+@@ -639,30 +1426,10 @@
+ numbers from strings.
+ 
+ @item
+-@ref{Searching and Sorting}, contains information about functions
+-for searching and sorting arrays.  You can use these functions on any
+-kind of array by providing an appropriate comparison function.
+-
+-@item
+-@ref{Pattern Matching}, presents functions for matching regular expressions
+-and shell file name patterns, and for expanding words as the shell does.
+-
+-@item
+ @ref{Date and Time}, describes functions for measuring both calendar time
+ and CPU time, as well as functions for setting alarms and timers.
+ 
+ @item
+-@ref{Character Set Handling}, contains information about manipulating
+-characters and strings using character sets larger than will fit in
+-the usual @code{char} data type.
+-
+-@item
+-@ref{Locales}, describes how selecting a particular country
+-or language affects the behavior of the library.  For example, the locale
+-affects collation sequences for strings and how monetary values are
+-formatted.
+-
+-@item
+ @ref{Non-Local Exits}, contains descriptions of the @code{setjmp} and
+ @code{longjmp} functions.  These functions provide a facility for
+ @code{goto}-like jumps which can jump from one function to another.
+@@ -708,6 +1475,15 @@
+ compatibility with POSIX.
+ 
+ @item
++@ref{Language Features}, contains information about library support for
++standard parts of the C language, including things like the @code{sizeof}
++operator and the symbolic constant @code{NULL}, how to write functions
++accepting variable numbers of arguments, and constants describing the
++ranges and other properties of the numerical types.  There is also a simple
++debugging mechanism which allows you to put assertions in your code, and
++have diagnostic messages printed if the tests fail.
++
++@item
+ @ref{Library Summary}, gives a summary of all the functions, variables, and
+ macros in the library, with complete data types and function prototypes,
+ and says what standard or system each is derived from.
+diff -urN glibc-2.17-c758a686/manual/ipc.texi glibc/manual/ipc.texi
+--- glibc-2.17-c758a686/manual/ipc.texi	1969-12-31 19:00:00.000000000 -0500
++++ glibc/manual/ipc.texi	2014-09-12 16:10:06.047792712 -0400
+@@ -0,0 +1,116 @@
++@node Inter-Process Communication, Job Control, Processes, Top
++@c %MENU% All about inter-process communication
++@chapter Inter-Process Communication
++@cindex ipc
++
++This chapter describes the @glibcadj{} inter-process communication primitives.
++
++@menu
++* Semaphores::	Support for creating and managing semaphores
++@end menu
++
++@node Semaphores
++@section Semaphores
++
++@Theglibc{} implements the semaphore APIs as defined in POSIX and
++System V.  Semaphores can be used by multiple processes to coordinate shared
++resources.  The following is a complete list of the semaphore functions provided
++by @theglibc{}.
++
++@c Need descriptions for all of these functions.
++
++@subsection System V Semaphores
++@deftypefun int semctl (int @var{semid}, int @var{semnum}, int @var{cmd});
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{/linux}}}
++@c syscall(ipc) ok
++@c
++@c AC-unsafe because we need to translate the new kernel
++@c semid_ds buf into the userspace layout.  Cancellation
++@c at that point results in an inconsistent userspace
++@c semid_ds.
++@end deftypefun
++
++@deftypefun int semget (key_t @var{key}, int @var{nsems}, int @var{semflg});
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c syscall(ipc) ok
++@end deftypefun
++
++@deftypefun int semop (int @var{semid}, struct sembuf *@var{sops}, size_t @var{nsops});
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c syscall(ipc) ok
++@end deftypefun
++
++@deftypefun int semtimedop (int @var{semid}, struct sembuf *@var{sops}, size_t @var{nsops}, const struct timespec *@var{timeout});
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c syscall(ipc) ok
++@end deftypefun
++
++@subsection POSIX Semaphores
++
++@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value});
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
++@c Does not atomically update sem_t therefore AC-unsafe
++@c because it can leave sem_t partially initialized.
++@end deftypefun
++
++@deftypefun int sem_destroy (sem_t *@var{sem});
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Function does nothing and is therefore always safe.
++@end deftypefun
++
++@deftypefun sem_t *sem_open (const char *@var{name}, int @var{oflag}, ...);
++@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acuinit{}}}
++@c pthread_once asuinit
++@c
++@c We are AC-Unsafe becuase we use pthread_once to initialize
++@c a global variable that holds the location of the mounted
++@c shmfs on Linux.
++@end deftypefun
++
++@deftypefun int sem_close (sem_t *@var{sem});
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c lll_lock asulock aculock
++@c twalk mtsrace{:root}
++@c
++@c We are AS-unsafe because we take a non-recursive lock.
++@c We are AC-unsafe because several internal data structures
++@c are not updated atomically.
++@end deftypefun
++
++@deftypefun int sem_unlink (const char *@var{name});
++@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acucorrupt{}}}
++@c pthread_once asuinit acucorrupt aculock
++@c mempcpy acucorrupt
++@end deftypefun
++
++@deftypefun int sem_wait (sem_t *@var{sem});
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
++@c atomic_increment (nwaiters) acucorrupt
++@c
++@c Given the use atomic operations this function seems
++@c to be AS-safe.  It is AC-unsafe because there is still
++@c a window between atomic_decrement and the pthread_push
++@c of the handler that undoes that operation.  A cancellation
++@c at that point would fail to remove the process from the
++@c waiters count.
++@end deftypefun
++
++@deftypefun int sem_timedwait (sem_t *@var{sem}, const struct timespec *@var{abstime});
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
++@c Same safety issues as sem_wait.
++@end deftypefun
++
++@deftypefun int sem_trywait (sem_t *@var{sem});
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c All atomic operations are safe in all contexts.
++@end deftypefun
++
++@deftypefun int sem_post (sem_t *@var{sem});
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Same safety as sem_trywait.
++@end deftypefun
++
++@deftypefun int sem_getvalue (sem_t *@var{sem}, int *@var{sval});
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Atomic write of a value is safe in all contexts.
++@end deftypefun
+diff -urN glibc-2.17-c758a686/manual/job.texi glibc/manual/job.texi
+--- glibc-2.17-c758a686/manual/job.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/job.texi	2014-09-12 16:10:06.048792709 -0400
+@@ -1,4 +1,4 @@
+-@node Job Control, Name Service Switch, Processes, Top
++@node Job Control, Name Service Switch, Inter-Process Communication, Top
+ @c %MENU% All about process groups and sessions
+ @chapter Job Control
+ 
+@@ -1039,6 +1039,10 @@
+ @comment stdio.h
+ @comment POSIX.1
+ @deftypefun {char *} ctermid (char *@var{string})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This function is a stub by default; the actual implementation, for
++@c posix systems, returns an internal buffer if passed a NULL string,
++@c but the internal buffer is always set to /dev/tty.
+ The @code{ctermid} function returns a string containing the file name of
+ the controlling terminal for the current process.  If @var{string} is
+ not a null pointer, it should be an array that can hold at least
+@@ -1075,6 +1079,12 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun pid_t setsid (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is usually a direct syscall, but if a syscall is not available,
++@c we use a stub, or Hurd- and BSD-specific implementations.  The former
++@c uses a mutex and a hurd critical section, and the latter issues a few
++@c syscalls, so both seem safe, the locking on Hurd is safe because of
++@c the critical section.
+ The @code{setsid} function creates a new session.  The calling process
+ becomes the session leader, and is put in a new process group whose
+ process group ID is the same as the process ID of that process.  There
+@@ -1098,6 +1108,8 @@
+ @comment unistd.h
+ @comment SVID
+ @deftypefun pid_t getsid (pid_t @var{pid})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Stub or direct syscall, except on hurd, where it is equally safe.
+ 
+ The @code{getsid} function returns the process group ID of the session
+ leader of the specified process.  If a @var{pid} is @code{0}, the
+@@ -1118,39 +1130,21 @@
+ @end table
+ @end deftypefun
+ 
+-The @code{getpgrp} function has two definitions: one derived from BSD
+-Unix, and one from the POSIX.1 standard.  The feature test macros you
+-have selected (@pxref{Feature Test Macros}) determine which definition
+-you get.  Specifically, you get the BSD version if you define
+-@code{_BSD_SOURCE}; otherwise, you get the POSIX version if you define
+-@code{_POSIX_SOURCE} or @code{_GNU_SOURCE}.  Programs written for old
+-BSD systems will not include @file{unistd.h}, which defines
+-@code{getpgrp} specially under @code{_BSD_SOURCE}.  You must link such
+-programs with the @code{-lbsd-compat} option to get the BSD definition.@refill
+-@pindex -lbsd-compat
+-@pindex bsd-compat
+-@cindex BSD compatibility library
+-
+ @comment unistd.h
+ @comment POSIX.1
+-@deftypefn {POSIX.1 Function} pid_t getpgrp (void)
+-The POSIX.1 definition of @code{getpgrp} returns the process group ID of
++@deftypefun pid_t getpgrp (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++The @code{getpgrp} function returns the process group ID of
+ the calling process.
+-@end deftypefn
+-
+-@comment unistd.h
+-@comment BSD
+-@deftypefn {BSD Function} pid_t getpgrp (pid_t @var{pid})
+-The BSD definition of @code{getpgrp} returns the process group ID of the
+-process @var{pid}.  You can supply a value of @code{0} for the @var{pid}
+-argument to get information about the calling process.
+-@end deftypefn
++@end deftypefun
+ 
+ @comment unistd.h
+-@comment SVID
+-@deftypefn {System V Function} int getpgid (pid_t @var{pid})
++@comment POSIX.1
++@deftypefun int getpgid (pid_t @var{pid})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Stub or direct syscall, except on hurd, where it is equally safe.
+ 
+-@code{getpgid} is the same as the BSD function @code{getpgrp}.  It
++The @code{getpgid} function
+ returns the process group ID of the process @var{pid}.  You can supply a
+ value of @code{0} for the @var{pid} argument to get information about
+ the calling process.
+@@ -1166,11 +1160,13 @@
+ process group ID of the process with ID @var{pid} from the calling
+ process.
+ @end table
+-@end deftypefn
++@end deftypefun
+ 
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int setpgid (pid_t @var{pid}, pid_t @var{pgid})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Stub or direct syscall, except on hurd, where it is equally safe.
+ The @code{setpgid} function puts the process @var{pid} into the process
+ group @var{pgid}.  As a special case, either @var{pid} or @var{pgid} can
+ be zero to indicate the process ID of the calling process.
+@@ -1208,6 +1204,8 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int setpgrp (pid_t @var{pid}, pid_t @var{pgid})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall or setpgid wrapper.
+ This is the BSD Unix name for @code{setpgid}.  Both functions do exactly
+ the same thing.
+ @end deftypefun
+@@ -1230,6 +1228,8 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun pid_t tcgetpgrp (int @var{filedes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Stub, or ioctl on BSD and GNU/Linux.
+ This function returns the process group ID of the foreground process
+ group associated with the terminal open on descriptor @var{filedes}.
+ 
+@@ -1258,6 +1258,8 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int tcsetpgrp (int @var{filedes}, pid_t @var{pgid})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Stub, or ioctl on BSD and GNU/Linux.
+ This function is used to set a terminal's foreground process group ID.
+ The argument @var{filedes} is a descriptor which specifies the terminal;
+ @var{pgid} specifies the process group.  The calling process must be a
+@@ -1297,6 +1299,8 @@
+ @comment termios.h
+ @comment Unix98
+ @deftypefun pid_t tcgetsid (int @var{fildes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Ioctl call, if available, or tcgetpgrp followed by getsid.
+ This function is used to obtain the process group ID of the session
+ for which the terminal specified by @var{fildes} is the controlling terminal.
+ If the call is successful the group ID is returned.  Otherwise the
+diff -urN glibc-2.17-c758a686/manual/lang.texi glibc/manual/lang.texi
+--- glibc-2.17-c758a686/manual/lang.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/lang.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -51,6 +51,8 @@
+ @comment assert.h
+ @comment ISO
+ @deftypefn Macro void assert (int @var{expression})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
++@c assert_fail_base calls asprintf, and fflushes stderr.
+ Verify the programmer's belief that @var{expression} is nonzero at
+ this point in the program.
+ 
+@@ -91,6 +93,8 @@
+ @comment assert.h
+ @comment GNU
+ @deftypefn Macro void assert_perror (int @var{errnum})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
++@c assert_fail_base calls asprintf, and fflushes stderr.
+ Similar to @code{assert}, but verifies that @var{errnum} is zero.
+ 
+ If @code{NDEBUG} is not defined, @code{assert_perror} tests the value of
+@@ -423,6 +427,8 @@
+ @comment stdarg.h
+ @comment ISO
+ @deftypefn {Macro} void va_start (va_list @var{ap}, @var{last-required})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is no longer provided by glibc, but rather by the compiler.
+ This macro initializes the argument pointer variable @var{ap} to point
+ to the first of the optional arguments of the current function;
+ @var{last-required} must be the last required argument to the function.
+@@ -431,6 +437,11 @@
+ @comment stdarg.h
+ @comment ISO
+ @deftypefn {Macro} @var{type} va_arg (va_list @var{ap}, @var{type})
++@safety{@prelim{}@mtsafe{@mtsrace{:ap}}@assafe{}@acunsafe{@acucorrupt{}}}
++@c This is no longer provided by glibc, but rather by the compiler.
++@c Unlike the other va_ macros, that either start/end the lifetime of
++@c the va_list object or don't modify it, this one modifies ap, and it
++@c may leave it in a partially updated state.
+ The @code{va_arg} macro returns the value of the next optional argument,
+ and modifies the value of @var{ap} to point to the subsequent argument.
+ Thus, successive uses of @code{va_arg} return successive optional
+@@ -445,6 +456,8 @@
+ @comment stdarg.h
+ @comment ISO
+ @deftypefn {Macro} void va_end (va_list @var{ap})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is no longer provided by glibc, but rather by the compiler.
+ This ends the use of @var{ap}.  After a @code{va_end} call, further
+ @code{va_arg} calls with the same @var{ap} may not work.  You should invoke
+ @code{va_end} before returning from the function in which @code{va_start}
+@@ -466,6 +479,8 @@
+ @comment ISO
+ @deftypefn {Macro} void va_copy (va_list @var{dest}, va_list @var{src})
+ @deftypefnx {Macro} void __va_copy (va_list @var{dest}, va_list @var{src})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is no longer provided by glibc, but rather by the compiler.
+ The @code{va_copy} macro allows copying of objects of type
+ @code{va_list} even if this is not an integral type.  The argument pointer
+ in @var{dest} is initialized to point to the same argument as the
+@@ -1212,7 +1227,9 @@
+ @comment stddef.h
+ @comment ISO
+ @deftypefn {Macro} size_t offsetof (@var{type}, @var{member})
+-This expands to a integer constant expression that is the offset of the
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is no longer provided by glibc, but rather by the compiler.
++This expands to an integer constant expression that is the offset of the
+ structure member named @var{member} in the structure type @var{type}.
+ For example, @code{offsetof (struct s, elem)} is the offset, in bytes,
+ of the member @code{elem} in a @code{struct s}.
+diff -urN glibc-2.17-c758a686/manual/libc.texinfo glibc/manual/libc.texinfo
+--- glibc-2.17-c758a686/manual/libc.texinfo	2014-09-12 16:08:17.677071123 -0400
++++ glibc/manual/libc.texinfo	2014-09-12 16:10:25.996741462 -0400
+@@ -7,7 +7,7 @@
+ @include macros.texi
+ 
+ @comment Tell install-info what to do.
+-@dircategory Libraries
++@dircategory Software libraries
+ @direntry
+ * Libc: (libc).                 C library.
+ @end direntry
+@@ -46,7 +46,7 @@
+ @value{VERSION} @value{PKGVERSION}.
+ @end ifclear
+ 
+-Copyright @copyright{} 1993--2012 Free Software Foundation, Inc.
++Copyright @copyright{} 1993--2014 Free Software Foundation, Inc.
+ 
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version
+@@ -118,6 +118,7 @@
+ @include chapters.texi
+ 
+ @node Free Manuals, Copying, Contributors, Top
++@appendix Free Software Needs Free Documentation
+ @include freemanuals.texi
+ 
+ @node Copying, Documentation License, Free Manuals, Top
+diff -urN glibc-2.17-c758a686/manual/libc-texinfo.sh glibc/manual/libc-texinfo.sh
+--- glibc-2.17-c758a686/manual/libc-texinfo.sh	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/libc-texinfo.sh	2014-09-12 16:10:06.042792724 -0400
+@@ -91,9 +91,11 @@
+ * Variable Index::               Index of variables and variable-like macros.
+ * File Index::                   Index of programs and files.
+ 
++ @detailmenu
+  --- The Detailed Node Listing ---
+ EOF
+  cat ${OUTDIR}lmenu.$$
++ echo '@end detailmenu'
+  echo '@end menu'; } >${OUTDIR}top-menu.texi.$$
+ mv -f ${OUTDIR}top-menu.texi.$$ ${OUTDIR}top-menu.texi
+ 
+diff -urN glibc-2.17-c758a686/manual/libdl.texi glibc/manual/libdl.texi
+--- glibc-2.17-c758a686/manual/libdl.texi	1969-12-31 19:00:00.000000000 -0500
++++ glibc/manual/libdl.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -0,0 +1,10 @@
++@c FIXME these are undocumented:
++@c dladdr
++@c dladdr1
++@c dlclose
++@c dlerror
++@c dlinfo
++@c dlmopen
++@c dlopen
++@c dlsym
++@c dlvsym
+diff -urN glibc-2.17-c758a686/manual/llio.texi glibc/manual/llio.texi
+--- glibc-2.17-c758a686/manual/llio.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/llio.texi	2014-09-12 16:10:06.047792712 -0400
+@@ -78,6 +82,7 @@
+ @comment fcntl.h
+ @comment POSIX.1
+ @deftypefun int open (const char *@var{filename}, int @var{flags}[, mode_t @var{mode}])
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ The @code{open} function creates and returns a new file descriptor for
+ the file named by @var{filename}.  Initially, the file position
+ indicator for the file is at the beginning of the file.  The argument
+@@ -164,6 +169,7 @@
+ @comment fcntl.h
+ @comment Unix98
+ @deftypefun int open64 (const char *@var{filename}, int @var{flags}[, mode_t @var{mode}])
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ This function is similar to @code{open}.  It returns a file descriptor
+ which can be used to access the file named by @var{filename}.  The only
+ difference is that on 32 bit systems the file is opened in the
+@@ -178,6 +184,7 @@
+ @comment fcntl.h
+ @comment POSIX.1
+ @deftypefn {Obsolete function} int creat (const char *@var{filename}, mode_t @var{mode})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ This function is obsolete.  The call:
+ 
+ @smallexample
+@@ -202,6 +209,7 @@
+ @comment fcntl.h
+ @comment Unix98
+ @deftypefn {Obsolete function} int creat64 (const char *@var{filename}, mode_t @var{mode})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ This function is similar to @code{creat}.  It returns a file descriptor
+ which can be used to access the file named by @var{filename}.  The only
+ the difference is that on 32 bit systems the file is opened in the
+@@ -219,6 +227,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int close (int @var{filedes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ The function @code{close} closes the file descriptor @var{filedes}.
+ Closing a file has the following consequences:
+ 
+@@ -300,6 +309,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun ssize_t read (int @var{filedes}, void *@var{buffer}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{read} function reads up to @var{size} bytes from the file
+ with descriptor @var{filedes}, storing the results in the @var{buffer}.
+ (This is not necessarily a character string, and no terminating null
+@@ -395,6 +405,10 @@
+ @comment unistd.h
+ @comment Unix98
+ @deftypefun ssize_t pread (int @var{filedes}, void *@var{buffer}, size_t @var{size}, off_t @var{offset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is usually a safe syscall.  The sysdeps/posix fallback emulation
++@c is not MT-Safe because it uses lseek, read and lseek back, but is it
++@c used anywhere?
+ The @code{pread} function is similar to the @code{read} function.  The
+ first three arguments are identical, and the return values and error
+ codes also correspond.
+@@ -430,6 +444,10 @@
+ @comment unistd.h
+ @comment Unix98
+ @deftypefun ssize_t pread64 (int @var{filedes}, void *@var{buffer}, size_t @var{size}, off64_t @var{offset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is usually a safe syscall.  The sysdeps/posix fallback emulation
++@c is not MT-Safe because it uses lseek64, read and lseek64 back, but is
++@c it used anywhere?
+ This function is similar to the @code{pread} function.  The difference
+ is that the @var{offset} parameter is of type @code{off64_t} instead of
+ @code{off_t} which makes it possible on 32 bit machines to address
+@@ -447,6 +465,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun ssize_t write (int @var{filedes}, const void *@var{buffer}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{write} function writes up to @var{size} bytes from
+ @var{buffer} to the file with descriptor @var{filedes}.  The data in
+ @var{buffer} is not necessarily a character string and a null character is
+@@ -557,6 +576,10 @@
+ @comment unistd.h
+ @comment Unix98
+ @deftypefun ssize_t pwrite (int @var{filedes}, const void *@var{buffer}, size_t @var{size}, off_t @var{offset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is usually a safe syscall.  The sysdeps/posix fallback emulation
++@c is not MT-Safe because it uses lseek, write and lseek back, but is it
++@c used anywhere?
+ The @code{pwrite} function is similar to the @code{write} function.  The
+ first three arguments are identical, and the return values and error codes
+ also correspond.
+@@ -592,6 +615,10 @@
+ @comment unistd.h
+ @comment Unix98
+ @deftypefun ssize_t pwrite64 (int @var{filedes}, const void *@var{buffer}, size_t @var{size}, off64_t @var{offset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is usually a safe syscall.  The sysdeps/posix fallback emulation
++@c is not MT-Safe because it uses lseek64, write and lseek64 back, but
++@c is it used anywhere?
+ This function is similar to the @code{pwrite} function.  The difference
+ is that the @var{offset} parameter is of type @code{off64_t} instead of
+ @code{off_t} which makes it possible on 32 bit machines to address
+@@ -624,6 +651,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun off_t lseek (int @var{filedes}, off_t @var{offset}, int @var{whence})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{lseek} function is used to change the file position of the
+ file with descriptor @var{filedes}.
+ 
+@@ -713,6 +741,7 @@
+ @comment unistd.h
+ @comment Unix98
+ @deftypefun off64_t lseek64 (int @var{filedes}, off64_t @var{offset}, int @var{whence})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to the @code{lseek} function.  The difference
+ is that the @var{offset} parameter is of type @code{off64_t} instead of
+ @code{off_t} which makes it possible on 32 bit machines to address
+@@ -825,6 +854,7 @@
+ @comment stdio.h
+ @comment POSIX.1
+ @deftypefun {FILE *} fdopen (int @var{filedes}, const char *@var{opentype})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}}
+ The @code{fdopen} function returns a new stream for the file descriptor
+ @var{filedes}.
+ 
+@@ -853,6 +883,7 @@
+ @comment stdio.h
+ @comment POSIX.1
+ @deftypefun int fileno (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function returns the file descriptor associated with the stream
+ @var{stream}.  If an error is detected (for example, if the @var{stream}
+ is not valid) or if @var{stream} does not do I/O to a file,
+@@ -862,6 +893,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int fileno_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fileno_unlocked} function is equivalent to the @code{fileno}
+ function except that it does not implicitly lock the stream if the state
+ is @code{FSETLOCKING_INTERNAL}.
+@@ -1055,7 +1087,7 @@
+ @comment BSD
+ @deftp {Data Type} {struct iovec}
+ 
+-The @code{iovec} structure describes a buffer. It contains two fields:
++The @code{iovec} structure describes a buffer.  It contains two fields:
+ 
+ @table @code
+ 
+@@ -1071,6 +1103,11 @@
+ @comment sys/uio.h
+ @comment BSD
+ @deftypefun ssize_t readv (int @var{filedes}, const struct iovec *@var{vector}, int @var{count})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c The fallback sysdeps/posix implementation, used even on GNU/Linux
++@c with old kernels that lack a full readv/writev implementation, may
++@c malloc the buffer into which data is read, if the total read size is
++@c too large for alloca.
+ 
+ The @code{readv} function reads data from @var{filedes} and scatters it
+ into the buffers described in @var{vector}, which is taken to be
+@@ -1089,6 +1126,11 @@
+ @comment sys/uio.h
+ @comment BSD
+ @deftypefun ssize_t writev (int @var{filedes}, const struct iovec *@var{vector}, int @var{count})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c The fallback sysdeps/posix implementation, used even on GNU/Linux
++@c with old kernels that lack a full readv/writev implementation, may
++@c malloc the buffer from which data is written, if the total write size
++@c is too large for alloca.
+ 
+ The @code{writev} function gathers data from the buffers described in
+ @var{vector}, which is taken to be @var{count} structures long, and writes
+@@ -1103,8 +1145,8 @@
+ 
+ @end deftypefun
+ 
+-@c Note - I haven't read this anywhere. I surmised it from my knowledge
+-@c of computer science. Thus, there could be subtleties I'm missing.
++@c Note - I haven't read this anywhere.  I surmised it from my knowledge
++@c of computer science.  Thus, there could be subtleties I'm missing.
+ 
+ Note that if the buffers are small (under about 1kB), high-level streams
+ may be easier to use than these functions.  However, @code{readv} and
+@@ -1149,6 +1191,7 @@
+ @comment sys/mman.h
+ @comment POSIX
+ @deftypefun {void *} mmap (void *@var{address}, size_t @var{length}, int @var{protect}, int @var{flags}, int @var{filedes}, off_t @var{offset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ The @code{mmap} function creates a new mapping, connected to bytes
+ (@var{offset}) to (@var{offset} + @var{length} - 1) in the file open on
+@@ -1156,8 +1199,8 @@
+ is created, which is not removed by closing the file.
+ 
+ @var{address} gives a preferred starting address for the mapping.
+-@code{NULL} expresses no preference. Any previous mapping at that
+-address is automatically removed. The address you give may still be
++@code{NULL} expresses no preference.  Any previous mapping at that
++address is automatically removed.  The address you give may still be
+ changed, unless you use the @code{MAP_FIXED} flag.
+ 
+ @vindex PROT_READ
+@@ -1221,13 +1264,13 @@
+ 
+ @c Linux has some other MAP_ options, which I have not discussed here.
+ @c MAP_DENYWRITE, MAP_EXECUTABLE and MAP_GROWSDOWN don't seem applicable to
+-@c user programs (and I don't understand the last two). MAP_LOCKED does
++@c user programs (and I don't understand the last two).  MAP_LOCKED does
+ @c not appear to be implemented.
+ 
+ @end vtable
+ 
+-@code{mmap} returns the address of the new mapping, or @math{-1} for an
+-error.
++@code{mmap} returns the address of the new mapping, or
++@code{MAP_FAILED} for an error.
+ 
+ Possible errors include:
+ 
+@@ -1268,6 +1311,9 @@
+ @comment sys/mman.h
+ @comment LFS
+ @deftypefun {void *} mmap64 (void *@var{address}, size_t @var{length}, int @var{protect}, int @var{flags}, int @var{filedes}, off64_t @var{offset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c The page_shift auto detection when MMAP2_PAGE_SHIFT is -1 (it never
++@c is) would be thread-unsafe.
+ The @code{mmap64} function is equivalent to the @code{mmap} function but
+ the @var{offset} parameter is of type @code{off64_t}.  On 32-bit systems
+ this allows the file associated with the @var{filedes} descriptor to be
+@@ -1284,6 +1330,7 @@
+ @comment sys/mman.h
+ @comment POSIX
+ @deftypefun int munmap (void *@var{addr}, size_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ @code{munmap} removes any memory maps from (@var{addr}) to (@var{addr} +
+ @var{length}).  @var{length} should be the length of the mapping.
+@@ -1310,6 +1357,7 @@
+ @comment sys/mman.h
+ @comment POSIX
+ @deftypefun int msync (void *@var{address}, size_t @var{length}, int @var{flags})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ When using shared mappings, the kernel can write the file at any time
+ before the mapping is removed.  To be certain data has actually been
+@@ -1357,17 +1405,18 @@
+ @comment sys/mman.h
+ @comment GNU
+ @deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ This function can be used to change the size of an existing memory
+ area. @var{address} and @var{length} must cover a region entirely mapped
+-in the same @code{mmap} statement. A new mapping with the same
++in the same @code{mmap} statement.  A new mapping with the same
+ characteristics will be returned with the length @var{new_length}.
+ 
+-One option is possible, @code{MREMAP_MAYMOVE}. If it is given in
++One option is possible, @code{MREMAP_MAYMOVE}.  If it is given in
+ @var{flags}, the system may remove the existing mapping and create a new
+ one of the desired length in another location.
+ 
+-The address of the resulting mapping is returned, or @math{-1}. Possible
++The address of the resulting mapping is returned, or @math{-1}.  Possible
+ error codes include:
+ 
+ @table @code
+@@ -1405,6 +1454,7 @@
+ @comment sys/mman.h
+ @comment POSIX
+ @deftypefun int madvise (void *@var{addr}, size_t @var{length}, int @var{advice})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ This function can be used to provide the system with @var{advice} about
+ the intended usage patterns of the memory region starting at @var{addr}
+@@ -1418,11 +1468,11 @@
+ The region should receive no further special treatment.
+ 
+ @item MADV_RANDOM
+-The region will be accessed via random page references. The kernel
++The region will be accessed via random page references.  The kernel
+ should page-in the minimal number of pages for each page fault.
+ 
+ @item MADV_SEQUENTIAL
+-The region will be accessed via sequential page references. This
++The region will be accessed via sequential page references.  This
+ may cause the kernel to aggressively read-ahead, expecting further
+ sequential references after any page fault within this region.
+ 
+@@ -1471,6 +1521,58 @@
+ @end table
+ @end deftypefun
+ 
++@comment sys/mman.h
++@comment POSIX
++@deftypefn Function int shm_open (const char *@var{name}, int @var{oflag}, mode_t @var{mode})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asuinit{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c shm_open @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd
++@c  libc_once(where_is_shmfs) @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd
++@c   where_is_shmfs @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    statfs dup ok
++@c    setmntent dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c    getmntent_r dup @mtslocale @ascuheap @aculock @acsmem [no @asucorrupt @acucorrupt; exclusive stream]
++@c    strcmp dup ok
++@c    strlen dup ok
++@c    malloc dup @ascuheap @acsmem
++@c    mempcpy dup ok
++@c    endmntent dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c  strlen dup ok
++@c  strchr dup ok
++@c  mempcpy dup ok
++@c  open dup @acsfd
++@c  fcntl dup ok
++@c  close dup @acsfd
++
++This function returns a file descriptor that can be used to allocate shared
++memory via mmap.  Unrelated processes can use same @var{name} to create or
++open existing shared memory objects.
++
++A @var{name} argument specifies the shared memory object to be opened.
++In @theglibc{} it must be a string smaller than @code{NAME_MAX} bytes starting
++with an optional slash but containing no other slashes.
++
++The semantics of @var{oflag} and @var{mode} arguments is same as in @code{open}.
++
++@code{shm_open} returns the file descriptor on success or @math{-1} on error.
++On failure @code{errno} is set.
++@end deftypefn
++
++@deftypefn Function int shm_unlink (const char *@var{name})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asuinit{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c shm_unlink @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd
++@c  libc_once(where_is_shmfs) dup @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd
++@c  strlen dup ok
++@c  strchr dup ok
++@c  mempcpy dup ok
++@c  unlink dup ok
++
++This function is inverse of @code{shm_open} and removes the object with
++the given @var{name} previously created by @code{shm_open}.
++
++@code{shm_unlink} returns @math{0} on success or @math{-1} on error.
++On failure @code{errno} is set.
++@end deftypefn
++
+ @node Waiting for I/O
+ @section Waiting for Input or Output
+ @cindex waiting for input or output
+@@ -1531,6 +1633,7 @@
+ @comment sys/types.h
+ @comment BSD
+ @deftypefn Macro void FD_ZERO (fd_set *@var{set})
++@safety{@prelim{}@mtsafe{@mtsrace{:set}}@assafe{}@acsafe{}}
+ This macro initializes the file descriptor set @var{set} to be the
+ empty set.
+ @end deftypefn
+@@ -1538,6 +1641,9 @@
+ @comment sys/types.h
+ @comment BSD
+ @deftypefn Macro void FD_SET (int @var{filedes}, fd_set *@var{set})
++@safety{@prelim{}@mtsafe{@mtsrace{:set}}@assafe{}@acsafe{}}
++@c Setting a bit isn't necessarily atomic, so there's a potential race
++@c here if set is not used exclusively.
+ This macro adds @var{filedes} to the file descriptor set @var{set}.
+ 
+ The @var{filedes} parameter must not have side effects since it is
+@@ -1547,6 +1653,9 @@
+ @comment sys/types.h
+ @comment BSD
+ @deftypefn Macro void FD_CLR (int @var{filedes}, fd_set *@var{set})
++@safety{@prelim{}@mtsafe{@mtsrace{:set}}@assafe{}@acsafe{}}
++@c Setting a bit isn't necessarily atomic, so there's a potential race
++@c here if set is not used exclusively.
+ This macro removes @var{filedes} from the file descriptor set @var{set}.
+ 
+ The @var{filedes} parameter must not have side effects since it is
+@@ -1556,6 +1665,7 @@
+ @comment sys/types.h
+ @comment BSD
+ @deftypefn Macro int FD_ISSET (int @var{filedes}, const fd_set *@var{set})
++@safety{@prelim{}@mtsafe{@mtsrace{:set}}@assafe{}@acsafe{}}
+ This macro returns a nonzero value (true) if @var{filedes} is a member
+ of the file descriptor set @var{set}, and zero (false) otherwise.
+ 
+@@ -1568,6 +1678,10 @@
+ @comment sys/types.h
+ @comment BSD
+ @deftypefun int select (int @var{nfds}, fd_set *@var{read-fds}, fd_set *@var{write-fds}, fd_set *@var{except-fds}, struct timeval *@var{timeout})
++@safety{@prelim{}@mtsafe{@mtsrace{:read-fds} @mtsrace{:write-fds} @mtsrace{:except-fds}}@assafe{}@acsafe{}}
++@c The select syscall is preferred, but pselect6 may be used instead,
++@c which requires converting timeout to a timespec and back.  The
++@c conversions are not atomic.
+ The @code{select} function blocks the calling process until there is
+ activity on any of the specified sets of file descriptors, or until the
+ timeout period has expired.
+@@ -1669,15 +1783,14 @@
+ 
+ @comment unistd.h
+ @comment X/Open
+-@deftypefun int sync (void)
++@deftypefun void sync (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ A call to this function will not return as long as there is data which
+ has not been written to the device.  All dirty buffers in the kernel will
+ be written and so an overall consistent system can be achieved (if no
+ other process in parallel writes data).
+ 
+ A prototype for @code{sync} can be found in @file{unistd.h}.
+-
+-The return value is zero to indicate no error.
+ @end deftypefun
+ 
+ Programs more often want to ensure that data written to a given file is
+@@ -1687,6 +1800,7 @@
+ @comment unistd.h
+ @comment POSIX
+ @deftypefun int fsync (int @var{fildes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fsync} function can be used to make sure all data associated with
+ the open file @var{fildes} is written to the device associated with the
+ descriptor.  The function call does not return unless all actions have
+@@ -1724,6 +1838,7 @@
+ @comment unistd.h
+ @comment POSIX
+ @deftypefun int fdatasync (int @var{fildes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ When a call to the @code{fdatasync} function returns, it is ensured
+ that all of the file data is written to the device.  For all pending I/O
+ operations, the parts guaranteeing data integrity finished.
+@@ -1925,6 +2040,158 @@
+ @comment aio.h
+ @comment POSIX.1b
+ @deftypefun int aio_read (struct aiocb *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
++@c Calls aio_enqueue_request.
++@c aio_enqueue_request @asulock @ascuheap @aculock @acsmem
++@c  pthread_self ok
++@c  pthread_getschedparam @asulock @aculock
++@c   lll_lock (pthread descriptor's lock) @asulock @aculock
++@c   sched_getparam ok
++@c   sched_getscheduler ok
++@c   lll_unlock @aculock
++@c  pthread_mutex_lock (aio_requests_mutex) @asulock @aculock
++@c  get_elem @ascuheap @acsmem [@asucorrupt @acucorrupt]
++@c   realloc @ascuheap @acsmem
++@c   calloc @ascuheap @acsmem
++@c  aio_create_helper_thread @asulock @ascuheap @aculock @acsmem
++@c   pthread_attr_init ok
++@c   pthread_attr_setdetachstate ok
++@c   pthread_get_minstack ok
++@c   pthread_attr_setstacksize ok
++@c   sigfillset ok
++@c    memset ok
++@c    sigdelset ok
++@c   SYSCALL rt_sigprocmask ok
++@c   pthread_create @asulock @ascuheap @aculock @acsmem
++@c    lll_lock (default_pthread_attr_lock) @asulock @aculock
++@c    alloca/malloc @ascuheap @acsmem
++@c    lll_unlock @aculock
++@c    allocate_stack @asulock @ascuheap @aculock @acsmem
++@c     getpagesize dup
++@c     lll_lock (default_pthread_attr_lock) @asulock @aculock
++@c     lll_unlock @aculock
++@c     _dl_allocate_tls @ascuheap @acsmem
++@c      _dl_allocate_tls_storage @ascuheap @acsmem
++@c       memalign @ascuheap @acsmem
++@c       memset ok
++@c       allocate_dtv dup
++@c       free @ascuheap @acsmem
++@c      allocate_dtv @ascuheap @acsmem
++@c       calloc @ascuheap @acsmem
++@c       INSTALL_DTV ok
++@c     list_add dup
++@c     get_cached_stack
++@c      lll_lock (stack_cache_lock) @asulock @aculock
++@c      list_for_each ok
++@c      list_entry dup
++@c      FREE_P dup
++@c      stack_list_del dup
++@c      stack_list_add dup
++@c      lll_unlock @aculock
++@c      _dl_allocate_tls_init ok
++@c       GET_DTV ok
++@c     mmap ok
++@c     atomic_increment_val ok
++@c     munmap ok
++@c     change_stack_perm ok
++@c      mprotect ok
++@c     mprotect ok
++@c     stack_list_del dup
++@c     _dl_deallocate_tls dup
++@c     munmap ok
++@c    THREAD_COPY_STACK_GUARD ok
++@c    THREAD_COPY_POINTER_GUARD ok
++@c    atomic_exchange_acq ok
++@c    lll_futex_wake ok
++@c    deallocate_stack @asulock @ascuheap @aculock @acsmem
++@c     lll_lock (state_cache_lock) @asulock @aculock
++@c     stack_list_del ok
++@c      atomic_write_barrier ok
++@c      list_del ok
++@c      atomic_write_barrier ok
++@c     queue_stack @ascuheap @acsmem
++@c      stack_list_add ok
++@c       atomic_write_barrier ok
++@c       list_add ok
++@c       atomic_write_barrier ok
++@c      free_stacks @ascuheap @acsmem
++@c       list_for_each_prev_safe ok
++@c       list_entry ok
++@c       FREE_P ok
++@c       stack_list_del dup
++@c       _dl_deallocate_tls dup
++@c       munmap ok
++@c     _dl_deallocate_tls @ascuheap @acsmem
++@c      free @ascuheap @acsmem
++@c     lll_unlock @aculock
++@c    create_thread @asulock @ascuheap @aculock @acsmem
++@c     td_eventword
++@c     td_eventmask
++@c     do_clone @asulock @ascuheap @aculock @acsmem
++@c      PREPARE_CREATE ok
++@c      lll_lock (pd->lock) @asulock @aculock
++@c      atomic_increment ok
++@c      clone ok
++@c      atomic_decrement ok
++@c      atomic_exchange_acq ok
++@c      lll_futex_wake ok
++@c      deallocate_stack dup
++@c      sched_setaffinity ok
++@c      tgkill ok
++@c      sched_setscheduler ok
++@c     atomic_compare_and_exchange_bool_acq ok
++@c     nptl_create_event ok
++@c     lll_unlock (pd->lock) @aculock
++@c    free @ascuheap @acsmem
++@c   pthread_attr_destroy ok (cpuset won't be set, so free isn't called)
++@c  add_request_to_runlist ok
++@c  pthread_cond_signal ok
++@c  aio_free_request ok
++@c  pthread_mutex_unlock @aculock
++
++@c (in the new thread, initiated with clone)
++@c    start_thread ok
++@c     HP_TIMING_NOW ok
++@c     ctype_init @mtslocale
++@c     atomic_exchange_acq ok
++@c     lll_futex_wake ok
++@c     sigemptyset ok
++@c     sigaddset ok
++@c     setjmp ok
++@c     CANCEL_ASYNC -> pthread_enable_asynccancel ok
++@c      do_cancel ok
++@c       pthread_unwind ok
++@c        Unwind_ForcedUnwind or longjmp ok [@ascuheap @acsmem?]
++@c     lll_lock @asulock @aculock
++@c     lll_unlock @asulock @aculock
++@c     CANCEL_RESET -> pthread_disable_asynccancel ok
++@c      lll_futex_wait ok
++@c     ->start_routine ok -----
++@c     call_tls_dtors @asulock @ascuheap @aculock @acsmem
++@c      user-supplied dtor
++@c      rtld_lock_lock_recursive (dl_load_lock) @asulock @aculock
++@c      rtld_lock_unlock_recursive @aculock
++@c      free @ascuheap @acsmem
++@c     nptl_deallocate_tsd @ascuheap @acsmem
++@c      tsd user-supplied dtors ok
++@c      free @ascuheap @acsmem
++@c     libc_thread_freeres
++@c      libc_thread_subfreeres ok
++@c     atomic_decrement_and_test ok
++@c     td_eventword ok
++@c     td_eventmask ok
++@c     atomic_compare_exchange_bool_acq ok
++@c     nptl_death_event ok
++@c     lll_robust_dead ok
++@c     getpagesize ok
++@c     madvise ok
++@c     free_tcb @asulock @ascuheap @aculock @acsmem
++@c      free @ascuheap @acsmem
++@c      deallocate_stack @asulock @ascuheap @aculock @acsmem
++@c     lll_futex_wait ok
++@c     exit_thread_inline ok
++@c      syscall(exit) ok
++
+ This function initiates an asynchronous read operation.  It
+ immediately returns after the operation was enqueued or when an
+ error was encountered.
+@@ -1989,7 +2256,8 @@
+ 
+ @comment aio.h
+ @comment Unix98
+-@deftypefun int aio_read64 (struct aiocb *@var{aiocbp})
++@deftypefun int aio_read64 (struct aiocb64 *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+ This function is similar to the @code{aio_read} function.  The only
+ difference is that on @w{32 bit} machines, the file descriptor should
+ be opened in the large file mode.  Internally, @code{aio_read64} uses
+@@ -2008,13 +2276,14 @@
+ @comment aio.h
+ @comment POSIX.1b
+ @deftypefun int aio_write (struct aiocb *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+ This function initiates an asynchronous write operation.  The function
+ call immediately returns after the operation was enqueued or if before
+ this happens an error was encountered.
+ 
+ The first @code{aiocbp->aio_nbytes} bytes from the buffer starting at
+ @code{aiocbp->aio_buf} are written to the file for which
+-@code{aiocbp->aio_fildes} is an descriptor, starting at the absolute
++@code{aiocbp->aio_fildes} is a descriptor, starting at the absolute
+ position @code{aiocbp->aio_offset} in the file.
+ 
+ If prioritized I/O is supported by the platform, the
+@@ -2073,7 +2342,8 @@
+ 
+ @comment aio.h
+ @comment Unix98
+-@deftypefun int aio_write64 (struct aiocb *@var{aiocbp})
++@deftypefun int aio_write64 (struct aiocb64 *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+ This function is similar to the @code{aio_write} function.  The only
+ difference is that on @w{32 bit} machines the file descriptor should
+ be opened in the large file mode.  Internally @code{aio_write64} uses
+@@ -2095,6 +2365,12 @@
+ @comment aio.h
+ @comment POSIX.1b
+ @deftypefun int lio_listio (int @var{mode}, struct aiocb *const @var{list}[], int @var{nent}, struct sigevent *@var{sig})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
++@c Call lio_listio_internal, that takes the aio_requests_mutex lock and
++@c enqueues each request.  Then, it waits for notification or prepares
++@c for it before releasing the lock.  Even though it performs memory
++@c allocation and locking of its own, it doesn't add any classes of
++@c safety issues that aren't already covered by aio_enqueue_request.
+ The @code{lio_listio} function can be used to enqueue an arbitrary
+ number of read and write requests at one time.  The requests can all be
+ meant for the same file, all for different files or every solution in
+@@ -2177,7 +2453,8 @@
+ 
+ @comment aio.h
+ @comment Unix98
+-@deftypefun int lio_listio64 (int @var{mode}, struct aiocb *const @var{list}, int @var{nent}, struct sigevent *@var{sig})
++@deftypefun int lio_listio64 (int @var{mode}, struct aiocb64 *const @var{list}[], int @var{nent}, struct sigevent *@var{sig})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+ This function is similar to the @code{lio_listio} function.  The only
+ difference is that on @w{32 bit} machines, the file descriptor should
+ be opened in the large file mode.  Internally, @code{lio_listio64} uses
+@@ -2206,6 +2483,7 @@
+ @comment aio.h
+ @comment POSIX.1b
+ @deftypefun int aio_error (const struct aiocb *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function determines the error state of the request described by the
+ @code{struct aiocb} variable pointed to by @var{aiocbp}.  If the
+ request has not yet terminated the value returned is always
+@@ -2227,6 +2505,7 @@
+ @comment aio.h
+ @comment Unix98
+ @deftypefun int aio_error64 (const struct aiocb64 *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{aio_error} with the only difference
+ that the argument is a reference to a variable of type @code{struct
+ aiocb64}.
+@@ -2239,7 +2518,8 @@
+ 
+ @comment aio.h
+ @comment POSIX.1b
+-@deftypefun ssize_t aio_return (const struct aiocb *@var{aiocbp})
++@deftypefun ssize_t aio_return (struct aiocb *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function can be used to retrieve the return status of the operation
+ carried out by the request described in the variable pointed to by
+ @var{aiocbp}.  As long as the error status of this request as returned
+@@ -2262,7 +2542,8 @@
+ 
+ @comment aio.h
+ @comment Unix98
+-@deftypefun int aio_return64 (const struct aiocb64 *@var{aiocbp})
++@deftypefun ssize_t aio_return64 (struct aiocb64 *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{aio_return} with the only difference
+ that the argument is a reference to a variable of type @code{struct
+ aiocb64}.
+@@ -2291,6 +2572,9 @@
+ @comment aio.h
+ @comment POSIX.1b
+ @deftypefun int aio_fsync (int @var{op}, struct aiocb *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
++@c After fcntl to check that the FD is open, it calls
++@c aio_enqueue_request.
+ Calling this function forces all I/O operations operating queued at the
+ time of the function call operating on the file descriptor
+ @code{aiocbp->aio_fildes} into the synchronized I/O completion state
+@@ -2322,8 +2606,7 @@
+ @item EAGAIN
+ The request could not be enqueued due to temporary lack of resources.
+ @item EBADF
+-The file descriptor @code{aiocbp->aio_fildes} is not valid or not open
+-for writing.
++The file descriptor @code{@var{aiocbp}->aio_fildes} is not valid.
+ @item EINVAL
+ The implementation does not support I/O synchronization or the @var{op}
+ parameter is other than @code{O_DSYNC} and @code{O_SYNC}.
+@@ -2339,6 +2622,7 @@
+ @comment aio.h
+ @comment Unix98
+ @deftypefun int aio_fsync64 (int @var{op}, struct aiocb64 *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+ This function is similar to @code{aio_fsync} with the only difference
+ that the argument is a reference to a variable of type @code{struct
+ aiocb64}.
+@@ -2365,6 +2649,9 @@
+ @comment aio.h
+ @comment POSIX.1b
+ @deftypefun int aio_suspend (const struct aiocb *const @var{list}[], int @var{nent}, const struct timespec *@var{timeout})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c Take aio_requests_mutex, set up waitlist and requestlist, wait
++@c for completion or timeout, and release the mutex.
+ When calling this function, the calling thread is suspended until at
+ least one of the requests pointed to by the @var{nent} elements of the
+ array @var{list} has completed.  If any of the requests has already
+@@ -2403,6 +2690,7 @@
+ @comment aio.h
+ @comment Unix98
+ @deftypefun int aio_suspend64 (const struct aiocb64 *const @var{list}[], int @var{nent}, const struct timespec *@var{timeout})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+ This function is similar to @code{aio_suspend} with the only difference
+ that the argument is a reference to a variable of type @code{struct
+ aiocb64}.
+@@ -2430,6 +2718,16 @@
+ @comment aio.h
+ @comment POSIX.1b
+ @deftypefun int aio_cancel (int @var{fildes}, struct aiocb *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
++@c After fcntl to check the fd is open, hold aio_requests_mutex, call
++@c aio_find_req_fd, aio_remove_request, then aio_notify and
++@c aio_free_request each request before releasing the lock.
++@c aio_notify calls aio_notify_only and free, besides cond signal or
++@c similar.  aio_notify_only calls pthread_attr_init,
++@c pthread_attr_setdetachstate, malloc, pthread_create,
++@c notify_func_wrapper, aio_sigqueue, getpid, raise.
++@c notify_func_wraper calls aio_start_notify_thread, free and then the
++@c notifier function.
+ The @code{aio_cancel} function can be used to cancel one or more
+ outstanding requests.  If the @var{aiocbp} parameter is @code{NULL}, the
+ function tries to cancel all of the outstanding requests which would process
+@@ -2477,6 +2775,7 @@
+ @comment aio.h
+ @comment Unix98
+ @deftypefun int aio_cancel64 (int @var{fildes}, struct aiocb64 *@var{aiocbp})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+ This function is similar to @code{aio_cancel} with the only difference
+ that the argument is a reference to a variable of type @code{struct
+ aiocb64}.
+@@ -2532,6 +2831,8 @@
+ @comment aio.h
+ @comment GNU
+ @deftypefun void aio_init (const struct aioinit *@var{init})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c All changes to global objects are guarded by aio_requests_mutex.
+ This function must be called before any other AIO function.  Calling it
+ is completely voluntary, as it is only meant to help the AIO
+ implementation perform better.
+@@ -2566,6 +2867,7 @@
+ @comment fcntl.h
+ @comment POSIX.1
+ @deftypefun int fcntl (int @var{filedes}, int @var{command}, @dots{})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{fcntl} function performs the operation specified by
+ @var{command} on the file descriptor @var{filedes}.  Some commands
+ require additional arguments to be supplied.  These additional arguments
+@@ -2592,7 +2894,7 @@
+ Set flags associated with the open file.  @xref{File Status Flags}.
+ 
+ @item F_GETLK
+-Get a file lock.  @xref{File Locks}.
++Test a file lock.  @xref{File Locks}.
+ 
+ @item F_SETLK
+ Set or clear a file lock.  @xref{File Locks}.
+@@ -2648,6 +2962,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int dup (int @var{old})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function copies descriptor @var{old} to the first available
+ descriptor number (the first number not currently open).  It is
+ equivalent to @code{fcntl (@var{old}, F_DUPFD, 0)}.
+@@ -2656,6 +2971,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int dup2 (int @var{old}, int @var{new})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function copies the descriptor @var{old} to descriptor number
+ @var{new}.
+ 
+@@ -2929,19 +3245,19 @@
+ But most programs will want to be portable to other POSIX.1 systems and
+ should use the POSIX.1 names above instead.
+ 
+-@comment fcntl.h
++@comment fcntl.h (optional)
+ @comment GNU
+ @deftypevr Macro int O_READ
+ Open the file for reading.  Same as @code{O_RDONLY}; only defined on GNU.
+ @end deftypevr
+ 
+-@comment fcntl.h
++@comment fcntl.h (optional)
+ @comment GNU
+ @deftypevr Macro int O_WRITE
+ Open the file for writing.  Same as @code{O_WRONLY}; only defined on GNU.
+ @end deftypevr
+ 
+-@comment fcntl.h
++@comment fcntl.h (optional)
+ @comment GNU
+ @deftypevr Macro int O_EXEC
+ Open the file for executing.  Only defined on GNU.
+@@ -3045,7 +3361,7 @@
+ The following three file name translation flags exist only on
+ @gnuhurdsystems{}.
+ 
+-@comment fcntl.h
++@comment fcntl.h (optional)
+ @comment GNU
+ @deftypevr Macro int O_IGNORE_CTTY
+ Do not recognize the named file as the controlling terminal, even if it
+@@ -3054,7 +3370,7 @@
+ @xref{Job Control}.
+ @end deftypevr
+ 
+-@comment fcntl.h
++@comment fcntl.h (optional)
+ @comment GNU
+ @deftypevr Macro int O_NOLINK
+ If the named file is a symbolic link, open the link itself instead of
+@@ -3063,7 +3379,7 @@
+ @cindex symbolic link, opening
+ @end deftypevr
+ 
+-@comment fcntl.h
++@comment fcntl.h (optional)
+ @comment GNU
+ @deftypevr Macro int O_NOTRANS
+ If the named file is specially translated, do not invoke the translator.
+@@ -3095,7 +3411,7 @@
+ The remaining operating modes are BSD extensions.  They exist only
+ on some systems.  On other systems, these macros are not defined.
+ 
+-@comment fcntl.h
++@comment fcntl.h (optional)
+ @comment BSD
+ @deftypevr Macro int O_SHLOCK
+ Acquire a shared lock on the file, as with @code{flock}.
+@@ -3106,7 +3422,7 @@
+ the lock on the new file first.
+ @end deftypevr
+ 
+-@comment fcntl.h
++@comment fcntl.h (optional)
+ @comment BSD
+ @deftypevr Macro int O_EXLOCK
+ Acquire an exclusive lock on the file, as with @code{flock}.
+@@ -3599,7 +4134,7 @@
+ @gnusystems{} can handle most input/output operations on many different
+ devices and objects in terms of a few file primitives - @code{read},
+ @code{write} and @code{lseek}.  However, most devices also have a few
+-peculiar operations which do not fit into this model. Such as:
++peculiar operations which do not fit into this model.  Such as:
+ 
+ @itemize @bullet
+ 
+@@ -3634,6 +4169,7 @@
+ @comment sys/ioctl.h
+ @comment BSD
+ @deftypefun int ioctl (int @var{filedes}, int @var{command}, @dots{})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ The @code{ioctl} function performs the generic I/O operation
+ @var{command} on @var{filedes}.
+@@ -3653,3 +4189,6 @@
+ Most IOCTLs are OS-specific and/or only used in special system utilities,
+ and are thus beyond the scope of this document.  For an example of the use
+ of an IOCTL, see @ref{Out-of-Band Data}.
++
++@c FIXME this is undocumented:
++@c dup3
+diff -urN glibc-2.17-c758a686/manual/locale.texi glibc/manual/locale.texi
+--- glibc-2.17-c758a686/manual/locale.texi	2014-09-12 16:08:18.266069610 -0400
++++ glibc/manual/locale.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -231,6 +231,136 @@
+ @comment locale.h
+ @comment ISO
+ @deftypefun {char *} setlocale (int @var{category}, const char *@var{locale})
++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtslocale{}} @mtsenv{}}@asunsafe{@asuinit{} @asulock{} @ascuheap{} @asucorrupt{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c Uses of the global locale object are unguarded in functions that
++@c ought to be MT-Safe, so we're ruling out the use of this function
++@c once threads are started.  It takes a write lock itself, but it may
++@c return a pointer loaded from the global locale object after releasing
++@c the lock, or before taking it.
++@c setlocale @mtasuconst:@mtslocale @mtsenv @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock
++@c  libc_rwlock_wrlock @asulock @aculock
++@c  libc_rwlock_unlock @aculock
++@c  getenv LOCPATH @mtsenv
++@c  malloc @ascuheap @acsmem
++@c  free @ascuheap @acsmem
++@c  new_composite_name ok
++@c  setdata ok
++@c  setname ok
++@c  _nl_find_locale @mtsenv @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock
++@c   getenv LC_ALL and LANG @mtsenv
++@c   _nl_load_locale_from_archive @ascuheap @acucorrupt @acsmem @acsfd
++@c    sysconf _SC_PAGE_SIZE ok
++@c    _nl_normalize_codeset @ascuheap @acsmem
++@c     isalnum_l ok (C locale)
++@c     isdigit_l ok (C locale)
++@c     malloc @ascuheap @acsmem
++@c     tolower_l ok (C locale)
++@c    open_not_cancel_2 @acsfd
++@c    fxstat64 ok
++@c    close_not_cancel_no_status ok
++@c    __mmap64 @acsmem
++@c    calculate_head_size ok
++@c    __munmap ok
++@c    compute_hashval ok
++@c    qsort dup @acucorrupt
++@c     rangecmp ok
++@c    malloc @ascuheap @acsmem
++@c    strdup @ascuheap @acsmem
++@c    _nl_intern_locale_data @ascuheap @acsmem
++@c     malloc @ascuheap @acsmem
++@c     free @ascuheap @acsmem
++@c   _nl_expand_alias @ascuheap @asulock @acsmem @acsfd @aculock
++@c    libc_lock_lock @asulock @aculock
++@c    bsearch ok
++@c     alias_compare ok
++@c      strcasecmp ok
++@c    read_alias_file @ascuheap @asulock @acsmem @acsfd @aculock
++@c     fopen @ascuheap @asulock @acsmem @acsfd @aculock
++@c     fsetlocking ok
++@c     feof_unlocked ok
++@c     fgets_unlocked ok
++@c     isspace ok (locale mutex is locked)
++@c     extend_alias_table @ascuheap @acsmem
++@c      realloc @ascuheap @acsmem
++@c     realloc @ascuheap @acsmem
++@c     fclose @ascuheap @asulock @acsmem @acsfd @aculock
++@c     qsort @ascuheap @acsmem
++@c      alias_compare dup
++@c    libc_lock_unlock @aculock
++@c   _nl_explode_name @ascuheap @acsmem
++@c    _nl_find_language ok
++@c    _nl_normalize_codeset dup @ascuheap @acsmem
++@c   _nl_make_l10nflist @ascuheap @acsmem
++@c    malloc @ascuheap @acsmem
++@c    free @ascuheap @acsmem
++@c    __argz_stringify ok
++@c    __argz_count ok
++@c    __argz_next ok
++@c   _nl_load_locale @ascuheap @acsmem @acsfd
++@c    open_not_cancel_2 @acsfd
++@c    __fxstat64 ok
++@c    close_not_cancel_no_status ok
++@c    mmap @acsmem
++@c    malloc @ascuheap @acsmem
++@c    read_not_cancel ok
++@c    free @ascuheap @acsmem
++@c    _nl_intern_locale_data dup @ascuheap @acsmem
++@c    munmap ok
++@c   __gconv_compare_alias @asuinit @ascuheap @asucorrupt @asulock @acsmem@acucorrupt @acsfd @aculock
++@c    __gconv_read_conf @asuinit @ascuheap @asucorrupt @asulock @acsmem@acucorrupt @acsfd @aculock
++@c     (libc_once-initializes gconv_cache and gconv_path_envvar; they're
++@c      never modified afterwards)
++@c     __gconv_load_cache @ascuheap @acsmem @acsfd
++@c      getenv GCONV_PATH @mtsenv
++@c      open_not_cancel @acsfd
++@c      __fxstat64 ok
++@c      close_not_cancel_no_status ok
++@c      mmap @acsmem
++@c      malloc @ascuheap @acsmem
++@c      __read ok
++@c      free @ascuheap @acsmem
++@c      munmap ok
++@c     __gconv_get_path @asulock @ascuheap @aculock @acsmem @acsfd
++@c      getcwd @ascuheap @acsmem @acsfd
++@c      libc_lock_lock @asulock @aculock
++@c      malloc @ascuheap @acsmem
++@c      strtok_r ok
++@c      libc_lock_unlock @aculock
++@c     read_conf_file @ascuheap @asucorrupt @asulock @acsmem @acucorrupt @acsfd @aculock
++@c      fopen @ascuheap @asulock @acsmem @acsfd @aculock
++@c      fsetlocking ok
++@c      feof_unlocked ok
++@c      getdelim @ascuheap @asucorrupt @acsmem @acucorrupt
++@c      isspace_l ok (C locale)
++@c      add_alias
++@c       isspace_l ok (C locale)
++@c       toupper_l ok (C locale)
++@c       add_alias2 dup @ascuheap @acucorrupt @acsmem
++@c      add_module @ascuheap @acsmem
++@c       isspace_l ok (C locale)
++@c       toupper_l ok (C locale)
++@c       strtol ok (@mtslocale but we hold the locale lock)
++@c       tfind __gconv_alias_db ok
++@c        __gconv_alias_compare dup ok
++@c       calloc @ascuheap @acsmem
++@c       insert_module dup @ascuheap
++@c     __tfind ok (because the tree is read only by then)
++@c      __gconv_alias_compare dup ok
++@c     insert_module @ascuheap
++@c      free @ascuheap
++@c     add_alias2 @ascuheap @acucorrupt @acsmem
++@c      detect_conflict ok, reads __gconv_modules_db
++@c      malloc @ascuheap @acsmem
++@c      tsearch __gconv_alias_db @ascuheap @acucorrupt @acsmem [exclusive tree, no @mtsrace]
++@c       __gconv_alias_compare ok
++@c      free @ascuheap
++@c    __gconv_compare_alias_cache ok
++@c     find_module_idx ok
++@c    do_lookup_alias ok
++@c     __tfind ok (because the tree is read only by then)
++@c      __gconv_alias_compare ok
++@c   strndup @ascuheap @acsmem
++@c   strcasecmp_l ok (C locale)
+ The function @code{setlocale} sets the current locale for category
+ @var{category} to @var{locale}.
+ 
+@@ -496,6 +626,10 @@
+ @comment locale.h
+ @comment ISO
+ @deftypefun {struct lconv *} localeconv (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:localeconv} @mtslocale{}}@asunsafe{}@acsafe{}}
++@c This function reads from multiple components of the locale object,
++@c without synchronization, while writing to the static buffer it uses
++@c as the return value.
+ The @code{localeconv} function returns a pointer to a structure whose
+ components contain information about how numeric and monetary values
+ should be formatted in the current locale.
+@@ -762,6 +896,9 @@
+ @comment langinfo.h
+ @comment XOPEN
+ @deftypefun {char *} nl_langinfo (nl_item @var{item})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c It calls _nl_langinfo_l with the current locale, which returns a
++@c pointer into constant strings defined in locale data structures.
+ The @code{nl_langinfo} function can be used to access individual
+ elements of the locale categories.  Unlike the @code{localeconv}
+ function, which returns all the information, @code{nl_langinfo}
+@@ -1056,6 +1193,11 @@
+ numbers according to these rules.
+ 
+ @deftypefun ssize_t strfmon (char *@var{s}, size_t @var{maxsize}, const char *@var{format}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c It (and strfmon_l) both call vstrfmon_l, which, besides accessing the
++@c locale object passed to it, accesses the active locale through
++@c isdigit (but to_digit assumes ASCII digits only).  It may call
++@c __printf_fp (@mtslocale @ascuheap @acsmem) and guess_grouping (safe).
+ The @code{strfmon} function is similar to the @code{strftime} function
+ in that it takes a buffer, its size, a format string,
+ and values to write into the buffer as text in a form specified
+@@ -1267,6 +1409,10 @@
+ @comment GNU
+ @comment stdlib.h
+ @deftypefun int rpmatch (const char *@var{response})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c Calls nl_langinfo with YESEXPR and NOEXPR, triggering @mtslocale but
++@c it's regcomp and regexec that bring in all of the safety issues.
++@c regfree is also called, but it doesn't introduce any further issues.
+ The function @code{rpmatch} checks the string in @var{response} whether
+ or not it is a correct yes-or-no answer and if yes, which one.  The
+ check uses the @code{YESEXPR} and @code{NOEXPR} data in the
+@@ -1318,5 +1464,5 @@
+   free (line);
+ @end smallexample
+ 
+-Note that the loop continues until an read error is detected or until a
++Note that the loop continues until a read error is detected or until a
+ definitive (positive or negative) answer is read.
+diff -urN glibc-2.17-c758a686/manual/macros.texi glibc/manual/macros.texi
+--- glibc-2.17-c758a686/manual/macros.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/macros.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -35,16 +35,225 @@
+ GNU/Linux and GNU/Hurd systems
+ @end macro
+ 
+-@c Descrption applying to GNU/Hurd systems; that is, systems using the
++@c Description applying to GNU/Hurd systems; that is, systems using the
+ @c GNU Hurd with the GNU C Library.
+ @macro gnuhurdsystems
+ GNU/Hurd systems
+ @end macro
+ 
+-@c Descrption applying to GNU/Linux systems; that is, systems using
++@c Description applying to GNU/Linux systems; that is, systems using
+ @c the Linux kernel with the GNU C Library.
+ @macro gnulinuxsystems
+ GNU/Linux systems
+ @end macro
+ 
++@c Document the safety functions as preliminary.  It does NOT expand its
++@c comments.
++@macro prelim {comments}
++Preliminary:
++
++@end macro
++@c Document a function as thread safe.
++@macro mtsafe {comments}
++| MT-Safe \comments\
++
++@end macro
++@c Document a function as thread unsafe.
++@macro mtunsafe {comments}
++| MT-Unsafe \comments\
++
++@end macro
++@c Document a function as safe for use in asynchronous signal handlers.
++@macro assafe {comments}
++| AS-Safe \comments\
++
++@end macro
++@c Document a function as unsafe for use in asynchronous signal
++@c handlers.  This distinguishes unmarked functions, for which this
++@c property has not been assessed, from those that have been analyzed.
++@macro asunsafe {comments}
++| AS-Unsafe \comments\
++
++@end macro
++@c Document a function as safe for use when asynchronous cancellation is
++@c enabled.
++@macro acsafe {comments}
++| AC-Safe \comments\
++
++@end macro
++@c Document a function as unsafe for use when asynchronous cancellation
++@c is enabled.  This distinguishes unmarked functions, for which this
++@c property has not been assessed, from those that have been analyzed.
++@macro acunsafe {comments}
++| AC-Unsafe \comments\
++
++@end macro
++@c Format safety properties without referencing the section of the
++@c definitions.  To be used in the definitions of the properties
++@c themselves.
++@macro sampsafety {notes}
++@noindent
++\notes\|
++
++
++@end macro
++@c Format the safety properties of a function.
++@macro safety {notes}
++\notes\| @xref{POSIX Safety Concepts}.
++
++
++@end macro
++@c Function is MT- and AS-Unsafe due to an internal race.
++@macro mtasurace {comments}
++race\comments\
++@end macro
++@c Function is AS-Unsafe due to an internal race.
++@macro asurace {comments}
++race\comments\
++@end macro
++@c Function is MT-Safe, but with potential race on user-supplied object
++@c of opaque type.
++@macro mtsrace {comments}
++race\comments\
++@end macro
++@c Function is MT- and AS-Unsafe for modifying an object that is decreed
++@c MT-constant due to MT-Unsafe accesses elsewhere.
++@macro mtasuconst {comments}
++const\comments\
++@end macro
++@c Function accesses the assumed-constant locale object.
++@macro mtslocale {comments}
++locale\comments\
++@end macro
++@c Function accesses the assumed-constant environment.
++@macro mtsenv {comments}
++env\comments\
++@end macro
++@c Function accesses the assumed-constant hostid.
++@macro mtshostid {comments}
++hostid\comments\
++@end macro
++@c Function accesses the assumed-constant _sigintr variable.
++@macro mtssigintr {comments}
++sigintr\comments\
++@end macro
++@c Function performs MT-Unsafe initialization at the first call.
++@macro mtuinit {comments}
++init\comments\
++@end macro
++@c Function performs libc_once AS-Unsafe initialization.
++@macro asuinit {comments}
++init\comments\
++@end macro
++@c Function performs libc_once AC-Unsafe initialization.
++@macro acuinit {comments}
++init\comments\
++@end macro
++@c Function is AS-Unsafe because it takes a non-recursive mutex that may
++@c already be held by the function interrupted by the signal.
++@macro asulock {comments}
++lock\comments\
++@end macro
++@c Function is AC-Unsafe because it may fail to release a mutex.
++@macro aculock {comments}
++lock\comments\
++@end macro
++@c Function is AS-Unsafe because some data structure may be inconsistent
++@c due to an ongoing updated interrupted by a signal.
++@macro asucorrupt {comments}
++corrupt\comments\
++@end macro
++@c Function is AC-Unsafe because some data structure may be left
++@c inconsistent when cancelled.
++@macro acucorrupt {comments}
++corrupt\comments\
++@end macro
++@c Function is AS- and AC-Unsafe because of malloc/free.
++@macro ascuheap {comments}
++heap\comments\
++@end macro
++@c Function is AS-Unsafe because of malloc/free.
++@macro asuheap {comments}
++heap\comments\
++@end macro
++@c Function is AS- and AC-Unsafe because of dlopen/dlclose.
++@macro ascudlopen {comments}
++dlopen\comments\
++@end macro
++@c Function is AS- and AC-Unsafe because of unknown plugins.
++@macro ascuplugin {comments}
++plugin\comments\
++@end macro
++@c Function is AS- and AC-Unsafe because of i18n.
++@macro ascuintl {comments}
++i18n\comments\
++@end macro
++@c Function is AS--Unsafe because of i18n.
++@macro asuintl {comments}
++i18n\comments\
++@end macro
++@c Function may leak file descriptors if async-cancelled.
++@macro acsfd {comments}
++fd\comments\
++@end macro
++@c Function may leak memory if async-cancelled.
++@macro acsmem {comments}
++mem\comments\
++@end macro
++@c Function is unsafe due to temporary overriding a signal handler.
++@macro mtascusig {comments}
++sig\comments\
++@end macro
++@c Function is MT- and AS-Unsafe due to temporarily changing attributes
++@c of the controlling terminal.
++@macro mtasuterm {comments}
++term\comments\
++@end macro
++@c Function is AC-Unsafe for failing to restore attributes of the
++@c controlling terminal.
++@macro acuterm {comments}
++term\comments\
++@end macro
++@c Function sets timers atomically.
++@macro mtstimer {comments}
++timer\comments\
++@end macro
++@c Function sets and restores timers.
++@macro mtascutimer {comments}
++timer\comments\
++@end macro
++@c Function temporarily changes the current working directory.
++@macro mtasscwd {comments}
++cwd\comments\
++@end macro
++@c Function may fail to restore to the original current working
++@c directory after temporarily changing it.
++@macro acscwd {comments}
++cwd\comments\
++@end macro
++@c Function is MT-Safe while POSIX says it needn't be MT-Safe.
++@macro mtsposix {comments}
++!posix\comments\
++@end macro
++@c Function is MT-Unsafe while POSIX says it should be MT-Safe.
++@macro mtuposix {comments}
++!posix\comments\
++@end macro
++@c Function is AS-Safe while POSIX says it needn't be AS-Safe.
++@macro assposix {comments}
++!posix\comments\
++@end macro
++@c Function is AS-Unsafe while POSIX says it should be AS-Safe.
++@macro asuposix {comments}
++!posix\comments\
++@end macro
++@c Function is AC-Safe while POSIX says it needn't be AC-Safe.
++@macro acsposix {comments}
++!posix\comments\
++@end macro
++@c Function is AC-Unsafe while POSIX says it should be AC-Safe.
++@macro acuposix {comments}
++!posix\comments\
++@end macro
++
+ @end ifclear
+diff -urN glibc-2.17-c758a686/manual/maint.texi glibc/manual/maint.texi
+--- glibc-2.17-c758a686/manual/maint.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/maint.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -316,7 +316,7 @@
+ The top-level @file{configure} script uses the shell @code{.} command to
+ read the @file{configure} file in each system-dependent directory
+ chosen, in order.  The @file{configure} files are often generated from
+-@file{configure.in} files using Autoconf.
++@file{configure.ac} files using Autoconf.
+ 
+ A system-dependent @file{configure} script will usually add things to
+ the shell variables @samp{DEFS} and @samp{config_vars}; see the
+@@ -329,14 +329,14 @@
+ just @w{@samp{--with-@var{package}}} (no argument), then it sets
+ @w{@samp{with_@var{package}}} to @samp{yes}.
+ 
+-@item configure.in
++@item configure.ac
+ 
+ This file is an Autoconf input fragment to be processed into the file
+ @file{configure} in this subdirectory.  @xref{Introduction,,,
+ autoconf.info, Autoconf: Generating Automatic Configuration Scripts},
+ for a description of Autoconf.  You should write either @file{configure}
+-or @file{configure.in}, but not both.  The first line of
+-@file{configure.in} should invoke the @code{m4} macro
++or @file{configure.ac}, but not both.  The first line of
++@file{configure.ac} should invoke the @code{m4} macro
+ @samp{GLIBC_PROVIDES}.  This macro does several @code{AC_PROVIDE} calls
+ for Autoconf macros which are used by the top-level @file{configure}
+ script; without this, those macros might be invoked again unnecessarily
+@@ -424,7 +424,7 @@
+ files specific to those machine architectures, but not specific to any
+ particular operating system.  There might be subdirectories for
+ specializations of those architectures, such as
+-@w{@file{sysdeps/m68k/68020}}. Code which is specific to the
++@w{@file{sysdeps/m68k/68020}}.  Code which is specific to the
+ floating-point coprocessor used with a particular machine should go in
+ @w{@file{sysdeps/@var{machine}/fpu}}.
+ 
+diff -urN glibc-2.17-c758a686/manual/Makefile glibc/manual/Makefile
+--- glibc-2.17-c758a686/manual/Makefile	2014-09-12 16:08:17.823070748 -0400
++++ glibc/manual/Makefile	2014-09-12 16:10:06.045792717 -0400
+@@ -1,5 +1,4 @@
+-# Copyright (C) 1992-2012
+-#	Free Software Foundation, Inc.
++# Copyright (C) 1992-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
+@@ -20,14 +19,10 @@
+ 
+ subdir := manual
+ 
+-# Allow override
+-INSTALL_INFO = install-info
++include ../Makeconfig
+ 
+ .PHONY: dvi pdf info html
+ 
+-# Get glibc's configuration info.
+-include ../Makeconfig
+-
+ dvi: $(objpfx)libc.dvi
+ pdf: $(objpfx)libc.pdf
+ 
+@@ -42,8 +37,8 @@
+ 		       intro errno memory ctype string charset locale	\
+ 		       message search pattern io stdio llio filesys	\
+ 		       pipe socket terminal syslog math arith time	\
+-		       resource setjmp signal startup process job nss	\
+-		       users sysinfo conf crypt debug probes)
++		       resource setjmp signal startup process ipc job	\
++		       nss users sysinfo conf crypt debug threads probes)
+ add-chapters = $(wildcard $(foreach d, $(add-ons), ../$d/$d.texi))
+ appendices = lang.texi header.texi install.texi maint.texi platform.texi \
+ 	     contrib.texi
+@@ -89,6 +84,7 @@
+ $(objpfx)summary.texi: $(objpfx)stamp-summary ;
+ $(objpfx)stamp-summary: summary.awk $(filter-out $(objpfx)summary.texi, \
+ 					$(texis-path))
++	-$(SHELL) ./check-safety.sh $(filter-out $(objpfx)%, $(texis-path))
+ 	$(AWK) -f $^ | sort -t'' -df -k 1,1 | tr '\014' '\012' \
+ 		> $(objpfx)summary-tmp
+ 	$(move-if-change) $(objpfx)summary-tmp $(objpfx)summary.texi
+@@ -145,8 +141,7 @@
+ 	mv -f $@.new $@
+ 
+ $(objpfx)%.info: %.texinfo
+-	LANGUAGE=C LC_ALL=C $(MAKEINFO) -P $(objpfx) --output=`basename $@` $<
+-	mv `basename $@`* $(objpfx)
++	LANGUAGE=C LC_ALL=C $(MAKEINFO) -P $(objpfx) --output=$@ $<
+ 
+ $(objpfx)%.dvi: %.texinfo
+ 	cd $(objpfx);$(TEXI2DVI) -I $(shell cd $(<D) && pwd) --output=$@ \
+@@ -159,19 +154,19 @@
+ 
+ # Distribution.
+ minimal-dist = summary.awk texis.awk tsort.awk libc-texinfo.sh libc.texinfo \
+-	       libm-err.texi stamp-libm-err				    \
++	       libm-err.texi stamp-libm-err check-safety.sh		    \
+ 	       $(filter-out summary.texi, $(nonexamples))		    \
+ 	       $(patsubst %.c.texi,examples/%.c, $(examples))
+ 
+ indices = cp fn pg tp vr ky
+-generated-dirs := libc
+-generated = libc.dvi libc.pdf libc.tmp libc.info*			    \
+-	stubs								    \
+-	texis summary.texi stamp-summary *.c.texi			    \
+-	$(foreach index,$(indices),libc.$(index) libc.$(index)s)	    \
+-	libc.log libc.aux libc.toc					    \
+-	$(libc-texi-generated)						    \
+-	stamp-libm-err stamp-version
++generated-dirs += libc
++generated += libc.dvi libc.pdf libc.tmp libc.info*			      \
++	     stubs							      \
++	     texis summary.texi stamp-summary *.c.texi			      \
++	     $(foreach index,$(indices),libc.$(index) libc.$(index)s)	      \
++	     libc.log libc.aux libc.toc					      \
++	     $(libc-texi-generated)					      \
++	     stamp-libm-err stamp-version
+ 
+ include ../Rules
+ 
+diff -urN glibc-2.17-c758a686/manual/math.texi glibc/manual/math.texi
+--- glibc-2.17-c758a686/manual/math.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/math.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -157,6 +157,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} sinl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the sine of @var{x}, where @var{x} is given in
+ radians.  The return value is in the range @code{-1} to @code{1}.
+ @end deftypefun
+@@ -170,6 +171,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} cosl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the cosine of @var{x}, where @var{x} is given in
+ radians.  The return value is in the range @code{-1} to @code{1}.
+ @end deftypefun
+@@ -183,6 +185,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} tanl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the tangent of @var{x}, where @var{x} is given in
+ radians.
+ 
+@@ -205,6 +208,7 @@
+ @comment math.h
+ @comment GNU
+ @deftypefunx void sincosl (long double @var{x}, long double *@var{sinx}, long double *@var{cosx})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the sine of @var{x} in @code{*@var{sinx}} and the
+ cosine of @var{x} in @code{*@var{cos}}, where @var{x} is given in
+ radians.  Both values, @code{*@var{sinx}} and @code{*@var{cosx}}, are in
+@@ -233,6 +237,9 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} csinl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c There are calls to nan* that could trigger @mtslocale if they didn't get
++@c empty strings.
+ These functions return the complex sine of @var{z}.
+ The mathematical definition of the complex sine is
+ 
+@@ -253,6 +260,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} ccosl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the complex cosine of @var{z}.
+ The mathematical definition of the complex cosine is
+ 
+@@ -273,6 +281,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} ctanl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the complex tangent of @var{z}.
+ The mathematical definition of the complex tangent is
+ 
+@@ -307,6 +316,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} asinl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute the arc sine of @var{x}---that is, the value whose
+ sine is @var{x}.  The value is in units of radians.  Mathematically,
+ there are infinitely many such values; the one actually returned is the
+@@ -326,6 +336,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} acosl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute the arc cosine of @var{x}---that is, the value
+ whose cosine is @var{x}.  The value is in units of radians.
+ Mathematically, there are infinitely many such values; the one actually
+@@ -345,6 +356,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} atanl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute the arc tangent of @var{x}---that is, the value
+ whose tangent is @var{x}.  The value is in units of radians.
+ Mathematically, there are infinitely many such values; the one actually
+@@ -360,6 +372,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} atan2l (long double @var{y}, long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function computes the arc tangent of @var{y}/@var{x}, but the signs
+ of both arguments are used to determine the quadrant of the result, and
+ @var{x} is permitted to be zero.  The return value is given in radians
+@@ -388,6 +401,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} casinl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute the complex arc sine of @var{z}---that is, the
+ value whose sine is @var{z}.  The value returned is in radians.
+ 
+@@ -404,6 +418,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} cacosl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute the complex arc cosine of @var{z}---that is, the
+ value whose cosine is @var{z}.  The value returned is in radians.
+ 
+@@ -421,6 +436,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} catanl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute the complex arc tangent of @var{z}---that is,
+ the value whose tangent is @var{z}.  The value is in units of radians.
+ @end deftypefun
+@@ -441,6 +457,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} expl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute @code{e} (the base of natural logarithms) raised
+ to the power @var{x}.
+ 
+@@ -457,6 +474,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} exp2l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute @code{2} raised to the power @var{x}.
+ Mathematically, @code{exp2 (x)} is the same as @code{exp (x * log (2))}.
+ @end deftypefun
+@@ -479,6 +497,7 @@
+ @comment math.h
+ @comment GNU
+ @deftypefunx {long double} pow10l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute @code{10} raised to the power @var{x}.
+ Mathematically, @code{exp10 (x)} is the same as @code{exp (x * log (10))}.
+ 
+@@ -496,6 +515,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} logl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions compute the natural logarithm of @var{x}.  @code{exp (log
+ (@var{x}))} equals @var{x}, exactly in mathematics and approximately in
+ C.
+@@ -514,6 +534,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} log10l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the base-10 logarithm of @var{x}.
+ @code{log10 (@var{x})} equals @code{log (@var{x}) / log (10)}.
+ 
+@@ -528,6 +549,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} log2l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the base-2 logarithm of @var{x}.
+ @code{log2 (@var{x})} equals @code{log (@var{x}) / log (2)}.
+ @end deftypefun
+@@ -541,6 +563,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} logbl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions extract the exponent of @var{x} and return it as a
+ floating-point value.  If @code{FLT_RADIX} is two, @code{logb} is equal
+ to @code{floor (log2 (x))}, except it's probably faster.
+@@ -560,6 +583,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx int ilogbl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions are equivalent to the corresponding @code{logb}
+ functions except that they return signed integer values.
+ @end deftypefun
+@@ -619,6 +643,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} powl (long double @var{base}, long double @var{power})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These are general exponentiation functions, returning @var{base} raised
+ to @var{power}.
+ 
+@@ -638,6 +663,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} sqrtl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the nonnegative square root of @var{x}.
+ 
+ If @var{x} is negative, @code{sqrt} signals a domain error.
+@@ -654,6 +680,7 @@
+ @comment math.h
+ @comment BSD
+ @deftypefunx {long double} cbrtl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the cube root of @var{x}.  They cannot
+ fail; every representable real value has a representable real cube root.
+ @end deftypefun
+@@ -667,6 +694,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} hypotl (long double @var{x}, long double @var{y})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return @code{sqrt (@var{x}*@var{x} +
+ @var{y}*@var{y})}.  This is the length of the hypotenuse of a right
+ triangle with sides of length @var{x} and @var{y}, or the distance
+@@ -684,6 +712,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} expm1l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return a value equivalent to @code{exp (@var{x}) - 1}.
+ They are computed in a way that is accurate even if @var{x} is
+ near zero---a case where @code{exp (@var{x}) - 1} would be inaccurate owing
+@@ -699,6 +728,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} log1pl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions returns a value equivalent to @w{@code{log (1 + @var{x})}}.
+ They are computed in a way that is accurate even if @var{x} is
+ near zero.
+@@ -719,6 +749,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} cexpl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return @code{e} (the base of natural
+ logarithms) raised to the power of @var{z}.
+ Mathematically, this corresponds to the value
+@@ -740,6 +771,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} clogl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the natural logarithm of @var{z}.
+ Mathematically, this corresponds to the value
+ 
+@@ -766,8 +798,9 @@
+ @comment complex.h
+ @comment GNU
+ @deftypefunx {complex long double} clog10l (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the base 10 logarithm of the complex value
+-@var{z}. Mathematically, this corresponds to the value
++@var{z}.  Mathematically, this corresponds to the value
+ 
+ @ifnottex
+ @math{log (z) = log10 (cabs (z)) + I * carg (z)}
+@@ -788,6 +821,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} csqrtl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the complex square root of the argument @var{z}.  Unlike
+ the real-valued functions, they are defined for all values of @var{z}.
+ @end deftypefun
+@@ -801,6 +835,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} cpowl (complex long double @var{base}, complex long double @var{power})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return @var{base} raised to the power of
+ @var{power}.  This is equivalent to @w{@code{cexp (y * clog (x))}}
+ @end deftypefun
+@@ -821,6 +856,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} sinhl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the hyperbolic sine of @var{x}, defined
+ mathematically as @w{@code{(exp (@var{x}) - exp (-@var{x})) / 2}}.  They
+ may signal overflow if @var{x} is too large.
+@@ -835,6 +871,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} coshl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These function return the hyperbolic cosine of @var{x},
+ defined mathematically as @w{@code{(exp (@var{x}) + exp (-@var{x})) / 2}}.
+ They may signal overflow if @var{x} is too large.
+@@ -849,6 +886,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} tanhl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the hyperbolic tangent of @var{x},
+ defined mathematically as @w{@code{sinh (@var{x}) / cosh (@var{x})}}.
+ They may signal overflow if @var{x} is too large.
+@@ -868,6 +906,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} csinhl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the complex hyperbolic sine of @var{z}, defined
+ mathematically as @w{@code{(exp (@var{z}) - exp (-@var{z})) / 2}}.
+ @end deftypefun
+@@ -881,6 +920,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} ccoshl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the complex hyperbolic cosine of @var{z}, defined
+ mathematically as @w{@code{(exp (@var{z}) + exp (-@var{z})) / 2}}.
+ @end deftypefun
+@@ -894,6 +934,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} ctanhl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the complex hyperbolic tangent of @var{z},
+ defined mathematically as @w{@code{csinh (@var{z}) / ccosh (@var{z})}}.
+ @end deftypefun
+@@ -910,6 +951,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} asinhl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the inverse hyperbolic sine of @var{x}---the
+ value whose hyperbolic sine is @var{x}.
+ @end deftypefun
+@@ -923,6 +965,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} acoshl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the inverse hyperbolic cosine of @var{x}---the
+ value whose hyperbolic cosine is @var{x}.  If @var{x} is less than
+ @code{1}, @code{acosh} signals a domain error.
+@@ -937,6 +980,7 @@
+ @comment math.h
+ @comment ISO
+ @deftypefunx {long double} atanhl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the inverse hyperbolic tangent of @var{x}---the
+ value whose hyperbolic tangent is @var{x}.  If the absolute value of
+ @var{x} is greater than @code{1}, @code{atanh} signals a domain error;
+@@ -954,6 +998,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} casinhl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the inverse complex hyperbolic sine of
+ @var{z}---the value whose complex hyperbolic sine is @var{z}.
+ @end deftypefun
+@@ -967,6 +1012,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} cacoshl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the inverse complex hyperbolic cosine of
+ @var{z}---the value whose complex hyperbolic cosine is @var{z}.  Unlike
+ the real-valued functions, there are no restrictions on the value of @var{z}.
+@@ -981,6 +1027,7 @@
+ @comment complex.h
+ @comment ISO
+ @deftypefunx {complex long double} catanhl (complex long double @var{z})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ These functions return the inverse complex hyperbolic tangent of
+ @var{z}---the value whose complex hyperbolic tangent is @var{z}.  Unlike
+ the real-valued functions, there are no restrictions on the value of
+@@ -1005,6 +1052,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} erfl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{erf} returns the error function of @var{x}.  The error
+ function is defined as
+ @tex
+@@ -1026,6 +1074,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} erfcl (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{erfc} returns @code{1.0 - erf(@var{x})}, but computed in a
+ fashion that avoids round-off error when @var{x} is large.
+ @end deftypefun
+@@ -1039,6 +1088,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} lgammal (long double @var{x})
++@safety{@prelim{}@mtunsafe{@mtasurace{:signgam}}@asunsafe{}@acsafe{}}
+ @code{lgamma} returns the natural logarithm of the absolute value of
+ the gamma function of @var{x}.  The gamma function is defined as
+ @tex
+@@ -1077,6 +1127,7 @@
+ @comment math.h
+ @comment XPG
+ @deftypefunx {long double} lgammal_r (long double @var{x}, int *@var{signp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{lgamma_r} is just like @code{lgamma}, but it stores the sign of
+ the intermediate result in the variable pointed to by @var{signp}
+ instead of in the @var{signgam} global.  This means it is reentrant.
+@@ -1091,6 +1142,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} gammal (long double @var{x})
++@safety{@prelim{}@mtunsafe{@mtasurace{:signgam}}@asunsafe{}@acsafe{}}
+ These functions exist for compatibility reasons.  They are equivalent to
+ @code{lgamma} etc.  It is better to use @code{lgamma} since for one the
+ name reflects better the actual computation, moreover @code{lgamma} is
+@@ -1106,6 +1158,7 @@
+ @comment math.h
+ @comment XPG, ISO
+ @deftypefunx {long double} tgammal (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{tgamma} applies the gamma function to @var{x}.  The gamma
+ function is defined as
+ @tex
+@@ -1129,6 +1182,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} j0l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{j0} returns the Bessel function of the first kind of order 0 of
+ @var{x}.  It may signal underflow if @var{x} is too large.
+ @end deftypefun
+@@ -1142,6 +1196,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} j1l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{j1} returns the Bessel function of the first kind of order 1 of
+ @var{x}.  It may signal underflow if @var{x} is too large.
+ @end deftypefun
+@@ -1155,6 +1210,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} jnl (int @var{n}, long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{jn} returns the Bessel function of the first kind of order
+ @var{n} of @var{x}.  It may signal underflow if @var{x} is too large.
+ @end deftypefun
+@@ -1168,6 +1224,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} y0l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{y0} returns the Bessel function of the second kind of order 0 of
+ @var{x}.  It may signal underflow if @var{x} is too large.  If @var{x}
+ is negative, @code{y0} signals a domain error; if it is zero,
+@@ -1183,6 +1240,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} y1l (long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{y1} returns the Bessel function of the second kind of order 1 of
+ @var{x}.  It may signal underflow if @var{x} is too large.  If @var{x}
+ is negative, @code{y1} signals a domain error; if it is zero,
+@@ -1198,6 +1256,7 @@
+ @comment math.h
+ @comment SVID
+ @deftypefunx {long double} ynl (int @var{n}, long double @var{x})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{yn} returns the Bessel function of the second kind of order @var{n} of
+ @var{x}.  It may signal underflow if @var{x} is too large.  If @var{x}
+ is negative, @code{yn} signals a domain error; if it is zero,
+@@ -1227,10 +1286,80 @@
+ @noindent
+ where @math{p} is the number of bits in the mantissa of the
+ floating-point number representation.  Ideally the error for all
+-functions is always less than 0.5ulps.  Using rounding bits this is also
+-possible and normally implemented for the basic operations.  To achieve
+-the same for the complex math functions requires a lot more work and
+-this has not yet been done.
++functions is always less than 0.5ulps in round-to-nearest mode.  Using
++rounding bits this is also
++possible and normally implemented for the basic operations.  Except
++for certain functions such as @code{sqrt}, @code{fma} and @code{rint}
++whose results are fully specified by reference to corresponding IEEE
++754 floating-point operations, and conversions between strings and
++floating point, @theglibc{} does not aim for correctly rounded results
++for functions in the math library, and does not aim for correctness in
++whether ``inexact'' exceptions are raised.  Instead, the goals for
++accuracy of functions without fully specified results are as follows;
++some functions have bugs meaning they do not meet these goals in all
++cases.  In future, @theglibc{} may provide some other correctly
++rounding functions under the names such as @code{crsin} proposed for
++an extension to ISO C.
++
++@itemize @bullet
++
++@item
++Each function with a floating-point result behaves as if it computes
++an infinite-precision result that is within a few ulp (in both real
++and complex parts, for functions with complex results) of the
++mathematically correct value of the function (interpreted together
++with ISO C or POSIX semantics for the function in question) at the
++exact value passed as the input.  Exceptions are raised appropriately
++for this value and in accordance with IEEE 754 / ISO C / POSIX
++semantics, and it is then rounded according to the current rounding
++direction to the result that is returned to the user.  @code{errno}
++may also be set (@pxref{Math Error Reporting}).
++
++@item
++For the IBM @code{long double} format, as used on PowerPC GNU/Linux,
++the accuracy goal is weaker for input values not exactly representable
++in 106 bits of precision; it is as if the input value is some value
++within 0.5ulp of the value actually passed, where ``ulp'' is
++interpreted in terms of a fixed-precision 106-bit mantissa, but not
++necessarily the exact value actually passed with discontiguous
++mantissa bits.
++
++@item
++Functions behave as if the infinite-precision result computed is zero,
++infinity or NaN if and only if that is the mathematically correct
++infinite-precision result.  They behave as if the infinite-precision
++result computed always has the same sign as the mathematically correct
++result.
++
++@item
++If the mathematical result is more than a few ulp above the overflow
++threshold for the current rounding direction, the value returned is
++the appropriate overflow value for the current rounding direction,
++with the overflow exception raised.
++
++@item
++If the mathematical result has magnitude well below half the least
++subnormal magnitude, the returned value is either zero or the least
++subnormal (in each case, with the correct sign), according to the
++current rounding direction and with the underflow exception raised.
++
++@item
++Where the mathematical result underflows and is not exactly
++representable as a floating-point value, the underflow exception is
++raised (so there may be spurious underflow exceptions in cases where
++the underflowing result is exact, but not missing underflow exceptions
++in cases where it is inexact).
++
++@item
++@Theglibc{} does not aim for functions to satisfy other properties of
++the underlying mathematical function, such as monotonicity, where not
++implied by the above goals.
++
++@item
++All the above applies to both real and complex parts, for complex
++functions.
++
++@end itemize
+ 
+ Therefore many of the functions in the math library have errors.  The
+ table lists the maximum error for each function which is exposed by one
+@@ -1314,6 +1443,8 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun int rand (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c Just calls random.
+ The @code{rand} function returns the next pseudo-random number in the
+ series.  The value ranges from @code{0} to @code{RAND_MAX}.
+ @end deftypefun
+@@ -1321,6 +1452,8 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun void srand (unsigned int @var{seed})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c Alias to srandom.
+ This function establishes @var{seed} as the seed for a new series of
+ pseudo-random numbers.  If you call @code{rand} before a seed has been
+ established with @code{srand}, it uses the value @code{1} as a default
+@@ -1337,6 +1470,7 @@
+ @comment stdlib.h
+ @comment POSIX.1
+ @deftypefun int rand_r (unsigned int *@var{seed})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function returns a random number in the range 0 to @code{RAND_MAX}
+ just as @code{rand} does.  However, all its state is stored in the
+ @var{seed} argument.  This means the RNG's state can only have as many
+@@ -1363,8 +1497,11 @@
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun {long int} random (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c Takes a lock and calls random_r with an automatic variable and the
++@c global state, while holding a lock.
+ This function returns the next pseudo-random number in the sequence.
+-The value returned ranges from @code{0} to @code{RAND_MAX}.
++The value returned ranges from @code{0} to @code{2147483647}.
+ 
+ @strong{NB:} Temporarily this function was defined to return a
+ @code{int32_t} value to indicate that the return value always contains
+@@ -1376,6 +1513,11 @@
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun void srandom (unsigned int @var{seed})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c Takes a lock and calls srandom_r with an automatic variable and a
++@c static buffer.  There's no MT-safety issue because the static buffer
++@c is internally protected by a lock, although other threads may modify
++@c the set state before it is used.
+ The @code{srandom} function sets the state of the random number
+ generator based on the integer @var{seed}.  If you supply a @var{seed} value
+ of @code{1}, this will cause @code{random} to reproduce the default set
+@@ -1387,7 +1529,8 @@
+ 
+ @comment stdlib.h
+ @comment BSD
+-@deftypefun {void *} initstate (unsigned int @var{seed}, void *@var{state}, size_t @var{size})
++@deftypefun {char *} initstate (unsigned int @var{seed}, char *@var{state}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+ The @code{initstate} function is used to initialize the random number
+ generator state.  The argument @var{state} is an array of @var{size}
+ bytes, used to hold the state information.  It is initialized based on
+@@ -1401,7 +1544,8 @@
+ 
+ @comment stdlib.h
+ @comment BSD
+-@deftypefun {void *} setstate (void *@var{state})
++@deftypefun {char *} setstate (char *@var{state})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+ The @code{setstate} function restores the random number state
+ information @var{state}.  The argument must have been the result of
+ a previous call to @var{initstate} or @var{setstate}.
+@@ -1442,6 +1586,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int random_r (struct random_data *restrict @var{buf}, int32_t *restrict @var{result})
++@safety{@prelim{}@mtsafe{@mtsrace{:buf}}@assafe{}@acunsafe{@acucorrupt{}}}
+ The @code{random_r} function behaves exactly like the @code{random}
+ function except that it uses and modifies the state in the object
+ pointed to by the first parameter instead of the global state.
+@@ -1450,6 +1595,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int srandom_r (unsigned int @var{seed}, struct random_data *@var{buf})
++@safety{@prelim{}@mtsafe{@mtsrace{:buf}}@assafe{}@acunsafe{@acucorrupt{}}}
+ The @code{srandom_r} function behaves exactly like the @code{srandom}
+ function except that it uses and modifies the state in the object
+ pointed to by the second parameter instead of the global state.
+@@ -1458,6 +1604,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int initstate_r (unsigned int @var{seed}, char *restrict @var{statebuf}, size_t @var{statelen}, struct random_data *restrict @var{buf})
++@safety{@prelim{}@mtsafe{@mtsrace{:buf}}@assafe{}@acunsafe{@acucorrupt{}}}
+ The @code{initstate_r} function behaves exactly like the @code{initstate}
+ function except that it uses and modifies the state in the object
+ pointed to by the fourth parameter instead of the global state.
+@@ -1466,6 +1613,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int setstate_r (char *restrict @var{statebuf}, struct random_data *restrict @var{buf})
++@safety{@prelim{}@mtsafe{@mtsrace{:buf}}@assafe{}@acunsafe{@acucorrupt{}}}
+ The @code{setstate_r} function behaves exactly like the @code{setstate}
+ function except that it uses and modifies the state in the object
+ pointed to by the first parameter instead of the global state.
+@@ -1512,6 +1660,12 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun double drand48 (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
++@c Uses of the static state buffer are not guarded by a lock (thus
++@c @mtasurace:drand48), so they may be found or left at a
++@c partially-updated state in case of calls from within signal handlers
++@c or cancellation.  None of this will break safety rules or invoke
++@c undefined behavior, but it may affect randomness.
+ This function returns a @code{double} value in the range of @code{0.0}
+ to @code{1.0} (exclusive).  The random bits are determined by the global
+ state of the random number generator in the C library.
+@@ -1525,6 +1679,9 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun double erand48 (unsigned short int @var{xsubi}[3])
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
++@c The static buffer is just initialized with default parameters, which
++@c are later read to advance the state held in xsubi.
+ This function returns a @code{double} value in the range of @code{0.0}
+ to @code{1.0} (exclusive), similarly to @code{drand48}.  The argument is
+ an array describing the state of the random number generator.
+@@ -1537,6 +1694,7 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun {long int} lrand48 (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
+ The @code{lrand48} function returns an integer value in the range of
+ @code{0} to @code{2^31} (exclusive).  Even if the size of the @code{long
+ int} type can take more than 32 bits, no higher numbers are returned.
+@@ -1547,6 +1705,7 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun {long int} nrand48 (unsigned short int @var{xsubi}[3])
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
+ This function is similar to the @code{lrand48} function in that it
+ returns a number in the range of @code{0} to @code{2^31} (exclusive) but
+ the state of the random number generator used to produce the random bits
+@@ -1561,6 +1720,7 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun {long int} mrand48 (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
+ The @code{mrand48} function is similar to @code{lrand48}.  The only
+ difference is that the numbers returned are in the range @code{-2^31} to
+ @code{2^31} (exclusive).
+@@ -1569,6 +1729,7 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun {long int} jrand48 (unsigned short int @var{xsubi}[3])
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
+ The @code{jrand48} function is similar to @code{nrand48}.  The only
+ difference is that the numbers returned are in the range @code{-2^31} to
+ @code{2^31} (exclusive).  For the @code{xsubi} parameter the same
+@@ -1582,6 +1743,7 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun void srand48 (long int @var{seedval})
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
+ The @code{srand48} function sets the most significant 32 bits of the
+ internal state of the random number generator to the least
+ significant 32 bits of the @var{seedval} parameter.  The lower 16 bits
+@@ -1601,6 +1763,7 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun {unsigned short int *} seed48 (unsigned short int @var{seed16v}[3])
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
+ The @code{seed48} function initializes all 48 bits of the state of the
+ internal random number generator from the contents of the parameter
+ @var{seed16v}.  Here the lower 16 bits of the first element of
+@@ -1628,6 +1791,7 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun void lcong48 (unsigned short int @var{param}[7])
++@safety{@prelim{}@mtunsafe{@mtasurace{:drand48}}@asunsafe{}@acunsafe{@acucorrupt{}}}
+ The @code{lcong48} function allows the user to change the complete state
+ of the random number generator.  Unlike @code{srand48} and
+ @code{seed48}, this function also changes the constants in the
+@@ -1660,6 +1824,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int drand48_r (struct drand48_data *@var{buffer}, double *@var{result})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ This function is equivalent to the @code{drand48} function with the
+ difference that it does not modify the global random number generator
+ parameters but instead the parameters in the buffer supplied through the
+@@ -1677,6 +1842,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int erand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, double *@var{result})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ The @code{erand48_r} function works like @code{erand48}, but in addition
+ it takes an argument @var{buffer} which describes the random number
+ generator.  The state of the random number generator is taken from the
+@@ -1692,7 +1858,8 @@
+ 
+ @comment stdlib.h
+ @comment GNU
+-@deftypefun int lrand48_r (struct drand48_data *@var{buffer}, double *@var{result})
++@deftypefun int lrand48_r (struct drand48_data *@var{buffer}, long int *@var{result})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ This function is similar to @code{lrand48}, but in addition it takes a
+ pointer to a buffer describing the state of the random number generator
+ just like @code{drand48}.
+@@ -1707,6 +1874,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int nrand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, long int *@var{result})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ The @code{nrand48_r} function works like @code{nrand48} in that it
+ produces a random number in the range @code{0} to @code{2^31}.  But instead
+ of using the global parameters for the congruential formula it uses the
+@@ -1722,7 +1890,8 @@
+ 
+ @comment stdlib.h
+ @comment GNU
+-@deftypefun int mrand48_r (struct drand48_data *@var{buffer}, double *@var{result})
++@deftypefun int mrand48_r (struct drand48_data *@var{buffer}, long int *@var{result})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ This function is similar to @code{mrand48} but like the other reentrant
+ functions it uses the random number generator described by the value in
+ the buffer pointed to by @var{buffer}.
+@@ -1737,6 +1906,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int jrand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, long int *@var{result})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ The @code{jrand48_r} function is similar to @code{jrand48}.  Like the
+ other reentrant functions of this function family it uses the
+ congruential formula parameters from the buffer pointed to by
+@@ -1771,6 +1941,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int srand48_r (long int @var{seedval}, struct drand48_data *@var{buffer})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ The description of the random number generator represented by the
+ information in @var{buffer} is initialized similarly to what the function
+ @code{srand48} does.  The state is initialized from the parameter
+@@ -1786,6 +1957,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int seed48_r (unsigned short int @var{seed16v}[3], struct drand48_data *@var{buffer})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ This function is similar to @code{srand48_r} but like @code{seed48} it
+ initializes all 48 bits of the state from the parameter @var{seed16v}.
+ 
+@@ -1802,6 +1974,7 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int lcong48_r (unsigned short int @var{param}[7], struct drand48_data *@var{buffer})
++@safety{@prelim{}@mtsafe{@mtsrace{:buffer}}@assafe{}@acunsafe{@acucorrupt{}}}
+ This function initializes all aspects of the random number generator
+ described in @var{buffer} with the data in @var{param}.  Here it is
+ especially true that the function does more than just copying the
+diff -urN glibc-2.17-c758a686/manual/memory.texi glibc/manual/memory.texi
+--- glibc-2.17-c758a686/manual/memory.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/memory.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -302,6 +302,245 @@
+ @comment malloc.h stdlib.h
+ @comment ISO
+ @deftypefun {void *} malloc (size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c Malloc hooks and __morecore pointers, as well as such parameters as
++@c max_n_mmaps and max_mmapped_mem, are accessed without guards, so they
++@c could pose a thread safety issue; in order to not declare malloc
++@c MT-unsafe, it's modifying the hooks and parameters while multiple
++@c threads are active that is regarded as unsafe.  An arena's next field
++@c is initialized and never changed again, except for main_arena's,
++@c that's protected by list_lock; next_free is only modified while
++@c list_lock is held too.  All other data members of an arena, as well
++@c as the metadata of the memory areas assigned to it, are only modified
++@c while holding the arena's mutex (fastbin pointers use catomic ops
++@c because they may be modified by free without taking the arena's
++@c lock).  Some reassurance was needed for fastbins, for it wasn't clear
++@c how they were initialized.  It turns out they are always
++@c zero-initialized: main_arena's, for being static data, and other
++@c arena's, for being just-mmapped memory.
++
++@c Leaking file descriptors and memory in case of cancellation is
++@c unavoidable without disabling cancellation, but the lock situation is
++@c a bit more complicated: we don't have fallback arenas for malloc to
++@c be safe to call from within signal handlers.  Error-checking mutexes
++@c or trylock could enable us to try and use alternate arenas, even with
++@c -DPER_THREAD (enabled by default), but supporting interruption
++@c (cancellation or signal handling) while holding the arena list mutex
++@c would require more work; maybe blocking signals and disabling async
++@c cancellation while manipulating the arena lists?
++
++@c __libc_malloc @asulock @aculock @acsfd @acsmem
++@c  force_reg ok
++@c  *malloc_hook unguarded
++@c  arena_lookup ok
++@c   tsd_getspecific ok, TLS
++@c  arena_lock @asulock @aculock @acsfd @acsmem
++@c   mutex_lock @asulock @aculock
++@c   arena_get2 @asulock @aculock @acsfd @acsmem
++@c    get_free_list @asulock @aculock
++@c     mutex_lock (list_lock) dup @asulock @aculock
++@c     mutex_unlock (list_lock) dup @aculock
++@c     mutex_lock (arena lock) dup @asulock @aculock [returns locked]
++@c     tsd_setspecific ok, TLS
++@c    __get_nprocs ext ok @acsfd
++@c    NARENAS_FROM_NCORES ok
++@c    catomic_compare_and_exchange_bool_acq ok
++@c    _int_new_arena ok @asulock @aculock @acsmem
++@c     new_heap ok @acsmem
++@c      mmap ok @acsmem
++@c      munmap ok @acsmem
++@c      mprotect ok
++@c     chunk2mem ok
++@c     set_head ok
++@c     tsd_setspecific dup ok
++@c     mutex_init ok
++@c     mutex_lock (just-created mutex) ok, returns locked
++@c     mutex_lock (list_lock) dup @asulock @aculock
++@c     atomic_write_barrier ok
++@c     mutex_unlock (list_lock) @aculock
++@c    catomic_decrement ok
++@c    reused_arena @asulock @aculock
++@c      reads&writes next_to_use and iterates over arena next without guards
++@c      those are harmless as long as we don't drop arenas from the
++@c      NEXT list, and we never do; when a thread terminates,
++@c      arena_thread_freeres prepends the arena to the free_list
++@c      NEXT_FREE list, but NEXT is never modified, so it's safe!
++@c     mutex_trylock (arena lock) @asulock @aculock
++@c     mutex_lock (arena lock) dup @asulock @aculock
++@c     tsd_setspecific dup ok
++@c  _int_malloc @acsfd @acsmem
++@c   checked_request2size ok
++@c    REQUEST_OUT_OF_RANGE ok
++@c    request2size ok
++@c   get_max_fast ok
++@c   fastbin_index ok
++@c   fastbin ok
++@c   catomic_compare_and_exhange_val_acq ok
++@c   malloc_printerr dup @mtsenv
++@c     if we get to it, we're toast already, undefined behavior must have
++@c     been invoked before
++@c    libc_message @mtsenv [no leaks with cancellation disabled]
++@c     FATAL_PREPARE ok
++@c      pthread_setcancelstate disable ok
++@c     libc_secure_getenv @mtsenv
++@c      getenv @mtsenv
++@c     open_not_cancel_2 dup @acsfd
++@c     strchrnul ok
++@c     WRITEV_FOR_FATAL ok
++@c      writev ok
++@c     mmap ok @acsmem
++@c     munmap ok @acsmem
++@c     BEFORE_ABORT @acsfd
++@c      backtrace ok
++@c      write_not_cancel dup ok
++@c      backtrace_symbols_fd @aculock
++@c      open_not_cancel_2 dup @acsfd
++@c      read_not_cancel dup ok
++@c      close_not_cancel_no_status dup @acsfd
++@c     abort ok
++@c    itoa_word ok
++@c    abort ok
++@c   check_remalloced_chunk ok/disabled
++@c   chunk2mem dup ok
++@c   alloc_perturb ok
++@c   in_smallbin_range ok
++@c   smallbin_index ok
++@c   bin_at ok
++@c   last ok
++@c   malloc_consolidate ok
++@c    get_max_fast dup ok
++@c    clear_fastchunks ok
++@c    unsorted_chunks dup ok
++@c    fastbin dup ok
++@c    atomic_exchange_acq ok
++@c    check_inuse_chunk dup ok/disabled
++@c    chunk_at_offset dup ok
++@c    chunksize dup ok
++@c    inuse_bit_at_offset dup ok
++@c    unlink dup ok
++@c    clear_inuse_bit_at_offset dup ok
++@c    in_smallbin_range dup ok
++@c    set_head dup ok
++@c    malloc_init_state ok
++@c     bin_at dup ok
++@c     set_noncontiguous dup ok
++@c     set_max_fast dup ok
++@c     initial_top ok
++@c      unsorted_chunks dup ok
++@c    check_malloc_state ok/disabled
++@c   set_inuse_bit_at_offset ok
++@c   check_malloced_chunk ok/disabled
++@c   largebin_index ok
++@c   have_fastchunks ok
++@c   unsorted_chunks ok
++@c    bin_at ok
++@c   chunksize ok
++@c   chunk_at_offset ok
++@c   set_head ok
++@c   set_foot ok
++@c   mark_bin ok
++@c    idx2bit ok
++@c   first ok
++@c   unlink ok
++@c    malloc_printerr dup ok
++@c    in_smallbin_range dup ok
++@c   idx2block ok
++@c   idx2bit dup ok
++@c   next_bin ok
++@c   sysmalloc @acsfd @acsmem
++@c    MMAP @acsmem
++@c    set_head dup ok
++@c    check_chunk ok/disabled
++@c    chunk2mem dup ok
++@c    chunksize dup ok
++@c    chunk_at_offset dup ok
++@c    heap_for_ptr ok
++@c    grow_heap ok
++@c     mprotect ok
++@c    set_head dup ok
++@c    new_heap @acsmem
++@c     MMAP dup @acsmem
++@c     munmap @acsmem
++@c    top ok
++@c    set_foot dup ok
++@c    contiguous ok
++@c    MORECORE ok
++@c     *__morecore ok unguarded
++@c      __default_morecore
++@c       sbrk ok
++@c    force_reg dup ok
++@c    *__after_morecore_hook unguarded
++@c    set_noncontiguous ok
++@c    malloc_printerr dup ok
++@c    _int_free (have_lock) @acsfd @acsmem [@asulock @aculock]
++@c     chunksize dup ok
++@c     mutex_unlock dup @aculock/!have_lock
++@c     malloc_printerr dup ok
++@c     check_inuse_chunk ok/disabled
++@c     chunk_at_offset dup ok
++@c     mutex_lock dup @asulock @aculock/@have_lock
++@c     chunk2mem dup ok
++@c     free_perturb ok
++@c     set_fastchunks ok
++@c      catomic_and ok
++@c     fastbin_index dup ok
++@c     fastbin dup ok
++@c     catomic_compare_and_exchange_val_rel ok
++@c     chunk_is_mmapped ok
++@c     contiguous dup ok
++@c     prev_inuse ok
++@c     unlink dup ok
++@c     inuse_bit_at_offset dup ok
++@c     clear_inuse_bit_at_offset ok
++@c     unsorted_chunks dup ok
++@c     in_smallbin_range dup ok
++@c     set_head dup ok
++@c     set_foot dup ok
++@c     check_free_chunk ok/disabled
++@c     check_chunk dup ok/disabled
++@c     have_fastchunks dup ok
++@c     malloc_consolidate dup ok
++@c     systrim ok
++@c      MORECORE dup ok
++@c      *__after_morecore_hook dup unguarded
++@c      set_head dup ok
++@c      check_malloc_state ok/disabled
++@c     top dup ok
++@c     heap_for_ptr dup ok
++@c     heap_trim @acsfd @acsmem
++@c      top dup ok
++@c      chunk_at_offset dup ok
++@c      prev_chunk ok
++@c      chunksize dup ok
++@c      prev_inuse dup ok
++@c      delete_heap @acsmem
++@c       munmap dup @acsmem
++@c      unlink dup ok
++@c      set_head dup ok
++@c      shrink_heap @acsfd
++@c       check_may_shrink_heap @acsfd
++@c        open_not_cancel_2 @acsfd
++@c        read_not_cancel ok
++@c        close_not_cancel_no_status @acsfd
++@c       MMAP dup ok
++@c       madvise ok
++@c     munmap_chunk @acsmem
++@c      chunksize dup ok
++@c      chunk_is_mmapped dup ok
++@c      chunk2mem dup ok
++@c      malloc_printerr dup ok
++@c      munmap dup @acsmem
++@c    check_malloc_state ok/disabled
++@c  arena_get_retry @asulock @aculock @acsfd @acsmem
++@c   mutex_unlock dup @aculock
++@c   mutex_lock dup @asulock @aculock
++@c   arena_get2 dup @asulock @aculock @acsfd @acsmem
++@c  mutex_unlock @aculock
++@c  mem2chunk ok
++@c  chunk_is_mmapped ok
++@c  arena_for_chunk ok
++@c   chunk_non_main_arena ok
++@c   heap_for_ptr ok
+ This function returns a pointer to a newly allocated block @var{size}
+ bytes long, or a null pointer if the block could not be allocated.
+ @end deftypefun
+@@ -355,7 +594,7 @@
+ void *
+ xmalloc (size_t size)
+ @{
+-  register void *value = malloc (size);
++  void *value = malloc (size);
+   if (value == 0)
+     fatal ("virtual memory exhausted");
+   return value;
+@@ -371,7 +610,7 @@
+ char *
+ savestring (const char *ptr, size_t len)
+ @{
+-  register char *value = (char *) xmalloc (len + 1);
++  char *value = (char *) xmalloc (len + 1);
+   value[len] = '\0';
+   return (char *) memcpy (value, ptr, len);
+ @}
+@@ -380,10 +619,10 @@
+ 
+ The block that @code{malloc} gives you is guaranteed to be aligned so
+ that it can hold any type of data.  On @gnusystems{}, the address is
+-always a multiple of eight on most systems, and a multiple of 16 on
++always a multiple of eight on 32-bit systems, and a multiple of 16 on
+ 64-bit systems.  Only rarely is any higher boundary (such as a page
+-boundary) necessary; for those cases, use @code{memalign},
+-@code{posix_memalign} or @code{valloc} (@pxref{Aligned Memory Blocks}).
++boundary) necessary; for those cases, use @code{aligned_alloc} or
++@code{posix_memalign} (@pxref{Aligned Memory Blocks}).
+ 
+ Note that the memory located after the end of the block is likely to be
+ in use for something else; perhaps a block already allocated by another
+@@ -407,6 +646,21 @@
+ @comment malloc.h stdlib.h
+ @comment ISO
+ @deftypefun void free (void *@var{ptr})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c __libc_free @asulock @aculock @acsfd @acsmem
++@c   releasing memory into fastbins modifies the arena without taking
++@c   its mutex, but catomic operations ensure safety.  If two (or more)
++@c   threads are running malloc and have their own arenas locked when
++@c   each gets a signal whose handler free()s large (non-fastbin-able)
++@c   blocks from each other's arena, we deadlock; this is a more general
++@c   case of @asulock.
++@c  *__free_hook unguarded
++@c  mem2chunk ok
++@c  chunk_is_mmapped ok, chunk bits not modified after allocation
++@c  chunksize ok
++@c  munmap_chunk dup @acsmem
++@c  arena_for_chunk dup ok
++@c  _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
+ The @code{free} function deallocates the block of memory pointed at
+ by @var{ptr}.
+ @end deftypefun
+@@ -414,6 +668,8 @@
+ @comment stdlib.h
+ @comment Sun
+ @deftypefun void cfree (void *@var{ptr})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c alias to free
+ This function does the same thing as @code{free}.  It's provided for
+ backward compatibility with SunOS; you should use @code{free} instead.
+ @end deftypefun
+@@ -471,6 +727,48 @@
+ @comment malloc.h stdlib.h
+ @comment ISO
+ @deftypefun {void *} realloc (void *@var{ptr}, size_t @var{newsize})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c It may call the implementations of malloc and free, so all of their
++@c issues arise, plus the realloc hook, also accessed without guards.
++
++@c __libc_realloc @asulock @aculock @acsfd @acsmem
++@c  *__realloc_hook unguarded
++@c  __libc_free dup @asulock @aculock @acsfd @acsmem
++@c  __libc_malloc dup @asulock @aculock @acsfd @acsmem
++@c  mem2chunk dup ok
++@c  chunksize dup ok
++@c  malloc_printerr dup ok
++@c  checked_request2size dup ok
++@c  chunk_is_mmapped dup ok
++@c  mremap_chunk
++@c   chunksize dup ok
++@c   __mremap ok
++@c   set_head dup ok
++@c  MALLOC_COPY ok
++@c   memcpy ok
++@c  munmap_chunk dup @acsmem
++@c  arena_for_chunk dup ok
++@c  mutex_lock (arena mutex) dup @asulock @aculock
++@c  _int_realloc @acsfd @acsmem
++@c   malloc_printerr dup ok
++@c   check_inuse_chunk dup ok/disabled
++@c   chunk_at_offset dup ok
++@c   chunksize dup ok
++@c   set_head_size dup ok
++@c   chunk_at_offset dup ok
++@c   set_head dup ok
++@c   chunk2mem dup ok
++@c   inuse dup ok
++@c   unlink dup ok
++@c   _int_malloc dup @acsfd @acsmem
++@c   mem2chunk dup ok
++@c   MALLOC_COPY dup ok
++@c   _int_free (have_lock) dup @acsfd @acsmem
++@c   set_inuse_bit_at_offset dup ok
++@c   set_head dup ok
++@c  mutex_unlock (arena mutex) dup @aculock
++@c  _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
++
+ The @code{realloc} function changes the size of the block whose address is
+ @var{ptr} to be @var{newsize}.
+ 
+@@ -502,7 +800,7 @@
+ void *
+ xrealloc (void *ptr, size_t size)
+ @{
+-  register void *value = realloc (ptr, size);
++  void *value = realloc (ptr, size);
+   if (value == 0)
+     fatal ("Virtual memory exhausted");
+   return value;
+@@ -530,6 +828,25 @@
+ @comment malloc.h stdlib.h
+ @comment ISO
+ @deftypefun {void *} calloc (size_t @var{count}, size_t @var{eltsize})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c Same caveats as malloc.
++
++@c __libc_calloc @asulock @aculock @acsfd @acsmem
++@c  *__malloc_hook dup unguarded
++@c  memset dup ok
++@c  arena_get @asulock @aculock @acsfd @acsmem
++@c   arena_lookup dup ok
++@c   arena_lock dup @asulock @aculock @acsfd @acsmem
++@c  top dup ok
++@c  chunksize dup ok
++@c  heap_for_ptr dup ok
++@c  _int_malloc dup @acsfd @acsmem
++@c  arena_get_retry dup @asulock @aculock @acsfd @acsmem
++@c  mutex_unlock dup @aculock
++@c  mem2chunk dup ok
++@c  chunk_is_mmapped dup ok
++@c  MALLOC_ZERO ok
++@c   memset dup ok
+ This function allocates a block long enough to contain a vector of
+ @var{count} elements, each of size @var{eltsize}.  Its contents are
+ cleared to zero before @code{calloc} returns.
+@@ -616,28 +933,89 @@
+ The address of a block returned by @code{malloc} or @code{realloc} in
+ @gnusystems{} is always a multiple of eight (or sixteen on 64-bit
+ systems).  If you need a block whose address is a multiple of a higher
+-power of two than that, use @code{memalign}, @code{posix_memalign}, or
+-@code{valloc}.  @code{memalign} is declared in @file{malloc.h} and
+-@code{posix_memalign} is declared in @file{stdlib.h}.
+-
+-With @theglibc{}, you can use @code{free} to free the blocks that
+-@code{memalign}, @code{posix_memalign}, and @code{valloc} return.  That
+-does not work in BSD, however---BSD does not provide any way to free
+-such blocks.
++power of two than that, use @code{aligned_alloc} or @code{posix_memalign}.
++@code{aligned_alloc} and @code{posix_memalign} are declared in
++@file{stdlib.h}.
++
++@comment stdlib.h
++@deftypefun {void *} aligned_alloc (size_t @var{alignment}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c Alias to memalign.
++The @code{aligned_alloc} function allocates a block of @var{size} bytes whose
++address is a multiple of @var{alignment}.  The @var{alignment} must be a
++power of two and @var{size} must be a multiple of @var{alignment}.
++
++The @code{aligned_alloc} function returns a null pointer on error and sets
++@code{errno} to one of the following values:
++
++@table @code
++@item ENOMEM
++There was insufficient memory available to satisfy the request.
++
++@item EINVAL
++@var{alignment} is not a power of two.
++
++This function was introduced in @w{ISO C11} and hence may have better
++portability to modern non-POSIX systems than @code{posix_memalign}.
++@end table
++
++@end deftypefun
+ 
+ @comment malloc.h
+ @comment BSD
+ @deftypefun {void *} memalign (size_t @var{boundary}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c Same issues as malloc.  The padding bytes are safely freed in
++@c _int_memalign, with the arena still locked.
++
++@c __libc_memalign @asulock @aculock @acsfd @acsmem
++@c  *__memalign_hook dup unguarded
++@c  __libc_malloc dup @asulock @aculock @acsfd @acsmem
++@c  arena_get dup @asulock @aculock @acsfd @acsmem
++@c  _int_memalign @acsfd @acsmem
++@c   _int_malloc dup @acsfd @acsmem
++@c   checked_request2size dup ok
++@c   mem2chunk dup ok
++@c   chunksize dup ok
++@c   chunk_is_mmapped dup ok
++@c   set_head dup ok
++@c   chunk2mem dup ok
++@c   set_inuse_bit_at_offset dup ok
++@c   set_head_size dup ok
++@c   _int_free (have_lock) dup @acsfd @acsmem
++@c   chunk_at_offset dup ok
++@c   check_inuse_chunk dup ok
++@c  arena_get_retry dup @asulock @aculock @acsfd @acsmem
++@c  mutex_unlock dup @aculock
+ The @code{memalign} function allocates a block of @var{size} bytes whose
+ address is a multiple of @var{boundary}.  The @var{boundary} must be a
+ power of two!  The function @code{memalign} works by allocating a
+ somewhat larger block, and then returning an address within the block
+ that is on the specified boundary.
++
++The @code{memalign} function returns a null pointer on error and sets
++@code{errno} to one of the following values:
++
++@table @code
++@item ENOMEM
++There was insufficient memory available to satisfy the request.
++
++@item EINVAL
++@var{alignment} is not a power of two.
++
++@end table
++
++The @code{memalign} function is obsolete and @code{aligned_alloc} or
++@code{posix_memalign} should be used instead.
+ @end deftypefun
+ 
+ @comment stdlib.h
+ @comment POSIX
+ @deftypefun int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c Calls memalign unless the requirements are not met (powerof2 macro is
++@c safe given an automatic variable as an argument) or there's a
++@c memalign hook (accessed unguarded, but safely).
+ The @code{posix_memalign} function is similar to the @code{memalign}
+ function in that it returns a buffer of @var{size} bytes aligned to a
+ multiple of @var{alignment}.  But it adds one requirement to the
+@@ -647,13 +1025,58 @@
+ If the function succeeds in allocation memory a pointer to the allocated
+ memory is returned in @code{*@var{memptr}} and the return value is zero.
+ Otherwise the function returns an error value indicating the problem.
++The possible error values returned are:
++
++@table @code
++@item ENOMEM
++There was insufficient memory available to satisfy the request.
+ 
+-This function was introduced in POSIX 1003.1d.
++@item EINVAL
++@var{alignment} is not a power of two multiple of @code{sizeof (void *)}.
++
++@end table
++
++This function was introduced in POSIX 1003.1d.  Although this function is
++superseded by @code{aligned_alloc}, it is more portable to older POSIX
++systems that do not support @w{ISO C11}.
+ @end deftypefun
+ 
+ @comment malloc.h stdlib.h
+ @comment BSD
+ @deftypefun {void *} valloc (size_t @var{size})
++@safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{} @acsfd{} @acsmem{}}}
++@c __libc_valloc @mtuinit @asuinit @asulock @aculock @acsfd @acsmem
++@c  ptmalloc_init (once) @mtsenv @asulock @aculock @acsfd @acsmem
++@c   _dl_addr @asucorrupt? @aculock
++@c    __rtld_lock_lock_recursive (dl_load_lock) @asucorrupt? @aculock
++@c    _dl_find_dso_for_object ok, iterates over dl_ns and its _ns_loaded objs
++@c      the ok above assumes no partial updates on dl_ns and _ns_loaded
++@c      that could confuse a _dl_addr call in a signal handler
++@c     _dl_addr_inside_object ok
++@c    determine_info ok
++@c    __rtld_lock_unlock_recursive (dl_load_lock) @aculock
++@c   thread_atfork @asulock @aculock @acsfd @acsmem
++@c    __register_atfork @asulock @aculock @acsfd @acsmem
++@c     lll_lock (__fork_lock) @asulock @aculock
++@c     fork_handler_alloc @asulock @aculock @acsfd @acsmem
++@c      calloc dup @asulock @aculock @acsfd @acsmem
++@c     __linkin_atfork ok
++@c      catomic_compare_and_exchange_bool_acq ok
++@c     lll_unlock (__fork_lock) @aculock
++@c   *_environ @mtsenv
++@c   next_env_entry ok
++@c   strcspn dup ok
++@c   __libc_mallopt dup @mtasuconst:mallopt [setting mp_]
++@c   __malloc_check_init @mtasuconst:malloc_hooks [setting hooks]
++@c   *__malloc_initialize_hook unguarded, ok
++@c  *__memalign_hook dup ok, unguarded
++@c  arena_get dup @asulock @aculock @acsfd @acsmem
++@c  _int_valloc @acsfd @acsmem
++@c   malloc_consolidate dup ok
++@c   _int_memalign dup @acsfd @acsmem
++@c  arena_get_retry dup @asulock @aculock @acsfd @acsmem
++@c  _int_memalign dup @acsfd @acsmem
++@c  mutex_unlock dup @aculock
+ Using @code{valloc} is like using @code{memalign} and passing the page size
+ as the value of the second argument.  It is implemented like this:
+ 
+@@ -667,6 +1090,9 @@
+ 
+ @ref{Query Memory Parameters} for more information about the memory
+ subsystem.
++
++The @code{valloc} function is obsolete and @code{aligned_alloc} or
++@code{posix_memalign} should be used instead.
+ @end deftypefun
+ 
+ @node Malloc Tunable Parameters
+@@ -678,30 +1104,34 @@
+ @pindex malloc.h
+ 
+ @deftypefun int mallopt (int @var{param}, int @var{value})
++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
++@c __libc_mallopt @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
++@c  ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
++@c  mutex_lock (main_arena->mutex) @asulock @aculock
++@c  malloc_consolidate dup ok
++@c  set_max_fast ok
++@c  mutex_unlock dup @aculock
++
+ When calling @code{mallopt}, the @var{param} argument specifies the
+ parameter to be set, and @var{value} the new value to be set.  Possible
+ choices for @var{param}, as defined in @file{malloc.h}, are:
+ 
+ @table @code
+-@item M_TRIM_THRESHOLD
+-This is the minimum size (in bytes) of the top-most, releasable chunk
+-that will cause @code{sbrk} to be called with a negative argument in
+-order to return memory to the system.
+-@item M_TOP_PAD
+-This parameter determines the amount of extra memory to obtain from the
+-system when a call to @code{sbrk} is required.  It also specifies the
+-number of bytes to retain when shrinking the heap by calling @code{sbrk}
+-with a negative argument.  This provides the necessary hysteresis in
+-heap size such that excessive amounts of system calls can be avoided.
++@comment TODO: @item M_ARENA_MAX
++@comment       - Document ARENA_MAX env var.
++@comment TODO: @item M_ARENA_TEST
++@comment       - Document ARENA_TEST env var.
++@comment TODO: @item M_CHECK_ACTION
++@item M_MMAP_MAX
++The maximum number of chunks to allocate with @code{mmap}.  Setting this
++to zero disables all use of @code{mmap}.
+ @item M_MMAP_THRESHOLD
+ All chunks larger than this value are allocated outside the normal
+ heap, using the @code{mmap} system call.  This way it is guaranteed
+ that the memory for these chunks can be returned to the system on
+ @code{free}.  Note that requests smaller than this threshold might still
+ be allocated via @code{mmap}.
+-@item M_MMAP_MAX
+-The maximum number of chunks to allocate with @code{mmap}.  Setting this
+-to zero disables all use of @code{mmap}.
++@comment TODO: @item M_MXFAST
+ @item M_PERTURB
+ If non-zero, memory blocks are filled with values depending on some
+ low order bits of this parameter when they are allocated (except when
+@@ -710,6 +1140,16 @@
+ guarantee that the freed block will have any specific values.  It only
+ guarantees that the content the block had before it was freed will be
+ overwritten.
++@item M_TOP_PAD
++This parameter determines the amount of extra memory to obtain from the
++system when a call to @code{sbrk} is required.  It also specifies the
++number of bytes to retain when shrinking the heap by calling @code{sbrk}
++with a negative argument.  This provides the necessary hysteresis in
++heap size such that excessive amounts of system calls can be avoided.
++@item M_TRIM_THRESHOLD
++This is the minimum size (in bytes) of the top-most, releasable chunk
++that will cause @code{sbrk} to be called with a negative argument in
++order to return memory to the system.
+ @end table
+ 
+ @end deftypefun
+@@ -728,6 +1168,17 @@
+ @comment mcheck.h
+ @comment GNU
+ @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status}))
++@safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
++@c The hooks must be set up before malloc is first used, which sort of
++@c implies @mtuinit/@asuinit but since the function is a no-op if malloc
++@c was already used, that doesn't pose any safety issues.  The actual
++@c problem is with the hooks, designed for single-threaded
++@c fully-synchronous operation: they manage an unguarded linked list of
++@c allocated blocks, and get temporarily overwritten before calling the
++@c allocation functions recursively while holding the old hooks.  There
++@c are no guards for thread safety, and inconsistent hooks may be found
++@c within signal handlers or left behind in case of cancellation.
++
+ Calling @code{mcheck} tells @code{malloc} to perform occasional
+ consistency checks.  These will catch things such as writing
+ past the end of a block that was allocated with @code{malloc}.
+@@ -770,6 +1221,18 @@
+ @end deftypefun
+ 
+ @deftypefun {enum mcheck_status} mprobe (void *@var{pointer})
++@safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
++@c The linked list of headers may be modified concurrently by other
++@c threads, and it may find a partial update if called from a signal
++@c handler.  It's mostly read only, so cancelling it might be safe, but
++@c it will modify global state that, if cancellation hits at just the
++@c right spot, may be left behind inconsistent.  This path is only taken
++@c if checkhdr finds an inconsistency.  If the inconsistency could only
++@c occur because of earlier undefined behavior, that wouldn't be an
++@c additional safety issue problem, but because of the other concurrency
++@c issues in the mcheck hooks, the apparent inconsistency could be the
++@c result of mcheck's own internal data race.  So, AC-Unsafe it is.
++
+ The @code{mprobe} function lets you explicitly check for inconsistencies
+ in a particular allocated block.  You must have already called
+ @code{mcheck} at the beginning of the program, to do its occasional
+@@ -896,16 +1359,18 @@
+ @comment malloc.h
+ @comment GNU
+ @defvar __memalign_hook
+-The value of this variable is a pointer to function that @code{memalign}
+-uses whenever it is called.  You should define this function to look
+-like @code{memalign}; that is, like:
++The value of this variable is a pointer to function that @code{aligned_alloc},
++@code{memalign}, @code{posix_memalign} and @code{valloc} use whenever they
++are called.  You should define this function to look like @code{aligned_alloc};
++that is, like:
+ 
+ @smallexample
+ void *@var{function} (size_t @var{alignment}, size_t @var{size}, const void *@var{caller})
+ @end smallexample
+ 
+ The value of @var{caller} is the return address found on the stack when
+-the @code{memalign} function was called.  This value allows you to trace the
++the @code{aligned_alloc}, @code{memalign}, @code{posix_memalign} or
++@code{valloc} functions are called.  This value allows you to trace the
+ memory consumption of the program.
+ @end defvar
+ 
+@@ -1082,6 +1547,24 @@
+ @comment malloc.h
+ @comment SVID
+ @deftypefun {struct mallinfo} mallinfo (void)
++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
++@c Accessing mp_.n_mmaps and mp_.max_mmapped_mem, modified with atomics
++@c but non-atomically elsewhere, may get us inconsistent results.  We
++@c mark the statistics as unsafe, rather than the fast-path functions
++@c that collect the possibly inconsistent data.
++
++@c __libc_mallinfo @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
++@c  ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
++@c  mutex_lock dup @asulock @aculock
++@c  int_mallinfo @mtasuconst:mallopt [mp_ access on main_arena]
++@c   malloc_consolidate dup ok
++@c   check_malloc_state dup ok/disabled
++@c   chunksize dup ok
++@c   fastbin dupo ok
++@c   bin_at dup ok
++@c   last dup ok
++@c  mutex_unlock @aculock
++
+ This function returns information about the current dynamic memory usage
+ in a structure of type @code{struct mallinfo}.
+ @end deftypefun
+@@ -1112,6 +1595,14 @@
+ Allocate a block of @var{size} bytes, starting on a page boundary.
+ @xref{Aligned Memory Blocks}.
+ 
++@item void *aligned_alloc (size_t @var{size}, size_t @var{alignment})
++Allocate a block of @var{size} bytes, starting on an address that is a
++multiple of @var{alignment}.  @xref{Aligned Memory Blocks}.
++
++@item int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
++Allocate a block of @var{size} bytes, starting on an address that is a
++multiple of @var{alignment}.  @xref{Aligned Memory Blocks}.
++
+ @item void *memalign (size_t @var{size}, size_t @var{boundary})
+ Allocate a block of @var{size} bytes, starting on an address that is a
+ multiple of @var{boundary}.  @xref{Aligned Memory Blocks}.
+@@ -1134,7 +1625,8 @@
+ A pointer to a function that @code{free} uses whenever it is called.
+ 
+ @item void (*__memalign_hook) (size_t @var{size}, size_t @var{alignment}, const void *@var{caller})
+-A pointer to a function that @code{memalign} uses whenever it is called.
++A pointer to a function that @code{aligned_alloc}, @code{memalign},
++@code{posix_memalign} and @code{valloc} use whenever they are called.
+ 
+ @item struct mallinfo mallinfo (void)
+ Return information about the current dynamic memory usage.
+@@ -1171,6 +1663,20 @@
+ @comment mcheck.h
+ @comment GNU
+ @deftypefun void mtrace (void)
++@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c Like the mcheck hooks, these are not designed with thread safety in
++@c mind, because the hook pointers are temporarily modified without
++@c regard to other threads, signals or cancellation.
++
++@c mtrace @mtuinit @mtasurace:mtrace @mtsenv @asuinit @ascuheap @asucorrupt @acuinit @acucorrupt @aculock @acsfd @acsmem
++@c  __libc_secure_getenv dup @mtsenv
++@c  malloc dup @ascuheap @acsmem
++@c  fopen dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c  fcntl dup ok
++@c  setvbuf dup @aculock
++@c  fprintf dup (on newly-created stream) @aculock
++@c  __cxa_atexit (once) dup @asulock @aculock @acsmem
++@c  free dup @ascuheap @acsmem
+ When the @code{mtrace} function is called it looks for an environment
+ variable named @code{MALLOC_TRACE}.  This variable is supposed to
+ contain a valid file name.  The user must have write access.  If the
+@@ -1194,6 +1700,11 @@
+ @comment mcheck.h
+ @comment GNU
+ @deftypefun void muntrace (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
++
++@c muntrace @mtasurace:mtrace @mtslocale @asucorrupt @ascuheap @acucorrupt @acsmem @aculock @acsfd
++@c  fprintf (fputs) dup @mtslocale @asucorrupt @ascuheap @acsmem @aculock @acucorrupt
++@c  fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
+ The @code{muntrace} function can be called after @code{mtrace} was used
+ to enable tracing the @code{malloc} calls.  If no (successful) call of
+ @code{mtrace} was made @code{muntrace} does nothing.
+@@ -1505,6 +2016,20 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun int obstack_init (struct obstack *@var{obstack-ptr})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{@acsmem{}}}
++@c obstack_init @mtsrace:obstack-ptr @acsmem
++@c  _obstack_begin @acsmem
++@c    chunkfun = obstack_chunk_alloc (suggested malloc)
++@c    freefun = obstack_chunk_free (suggested free)
++@c   *chunkfun @acsmem
++@c    obstack_chunk_alloc user-supplied
++@c   *obstack_alloc_failed_handler user-supplied
++@c    -> print_and_abort (default)
++@c
++@c print_and_abort
++@c  _ dup @ascuintl
++@c  fxprintf dup @asucorrupt @aculock @acucorrupt
++@c  exit @acucorrupt?
+ Initialize obstack @var{obstack-ptr} for allocation of objects.  This
+ function calls the obstack's @code{obstack_chunk_alloc} function.  If
+ allocation of memory fails, the function pointed to by
+@@ -1560,6 +2085,10 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun {void *} obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_alloc @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_blank dup @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
+ This allocates an uninitialized block of @var{size} bytes in an obstack
+ and returns its address.  Here @var{obstack-ptr} specifies which obstack
+ to allocate the block in; it is the address of the @code{struct obstack}
+@@ -1594,6 +2123,10 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun {void *} obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_copy @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_grow dup @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
+ This allocates a block and initializes it by copying @var{size}
+ bytes of data starting at @var{address}.  It calls
+ @code{obstack_alloc_failed_handler} if allocation of memory by
+@@ -1603,6 +2136,10 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun {void *} obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_copy0 @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_grow0 dup @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
+ Like @code{obstack_copy}, but appends an extra byte containing a null
+ character.  This extra byte is not counted in the argument @var{size}.
+ @end deftypefun
+@@ -1635,6 +2172,10 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}}
++@c obstack_free @mtsrace:obstack-ptr @acucorrupt
++@c  (obstack_free) @mtsrace:obstack-ptr @acucorrupt
++@c   *freefun dup user-supplied
+ If @var{object} is a null pointer, everything allocated in the obstack
+ is freed.  Otherwise, @var{object} must be the address of an object
+ allocated in the obstack.  Then @var{object} is freed, along with
+@@ -1739,6 +2280,13 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_blank @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  _obstack_newchunk @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c   *chunkfun dup @acsmem
++@c   *obstack_alloc_failed_handler dup user-supplied
++@c   *freefun
++@c  obstack_blank_fast dup @mtsrace:obstack-ptr
+ The most basic function for adding to a growing object is
+ @code{obstack_blank}, which adds space without initializing it.
+ @end deftypefun
+@@ -1746,6 +2294,10 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  memcpy ok
+ To add a block of initialized space, use @code{obstack_grow}, which is
+ the growing-object analogue of @code{obstack_copy}.  It adds @var{size}
+ bytes of data to the growing object, copying the contents from
+@@ -1755,6 +2307,12 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_grow0 @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c   (no sequence point between storing NUL and incrementing next_free)
++@c   (multiple changes to next_free => @acucorrupt)
++@c  _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  memcpy ok
+ This is the growing-object analogue of @code{obstack_copy0}.  It adds
+ @var{size} bytes copied from @var{data}, followed by an additional null
+ character.
+@@ -1763,6 +2321,10 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_1grow @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_1grow_fast dup @mtsrace:obstack-ptr @acucorrupt @acsmem
+ To add one character at a time, use the function @code{obstack_1grow}.
+ It adds a single byte containing @var{c} to the growing object.
+ @end deftypefun
+@@ -1770,6 +2332,10 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_ptr_grow (struct obstack *@var{obstack-ptr}, void *@var{data})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_ptr_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_ptr_grow_fast dup @mtsrace:obstack-ptr
+ Adding the value of a pointer one can use the function
+ @code{obstack_ptr_grow}.  It adds @code{sizeof (void *)} bytes
+ containing the value of @var{data}.
+@@ -1778,6 +2344,10 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_int_grow (struct obstack *@var{obstack-ptr}, int @var{data})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_int_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c  obstack_int_grow_fast dup @mtsrace:obstack-ptr
+ A single value of type @code{int} can be added by using the
+ @code{obstack_int_grow} function.  It adds @code{sizeof (int)} bytes to
+ the growing object and initializes them with the value of @var{data}.
+@@ -1786,6 +2356,8 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun {void *} obstack_finish (struct obstack *@var{obstack-ptr})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}}
++@c obstack_finish @mtsrace:obstack-ptr @acucorrupt
+ When you are finished growing the object, use the function
+ @code{obstack_finish} to close it off and return its final address.
+ 
+@@ -1805,6 +2377,7 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
+ This function returns the current size of the growing object, in bytes.
+ Remember to call this function @emph{before} finishing the object.
+ After it is finished, @code{obstack_object_size} will return zero.
+@@ -1848,6 +2421,7 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun int obstack_room (struct obstack *@var{obstack-ptr})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
+ This returns the number of bytes that can be added safely to the current
+ growing object (or to an object about to be started) in obstack
+ @var{obstack} using the fast growth functions.
+@@ -1859,6 +2433,9 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{c})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c obstack_1grow_fast @mtsrace:obstack-ptr @acucorrupt @acsmem
++@c   (no sequence point between copying c and incrementing next_free)
+ The function @code{obstack_1grow_fast} adds one byte containing the
+ character @var{c} to the growing object in obstack @var{obstack-ptr}.
+ @end deftypefun
+@@ -1866,6 +2443,8 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_ptr_grow_fast (struct obstack *@var{obstack-ptr}, void *@var{data})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
++@c obstack_ptr_grow_fast @mtsrace:obstack-ptr
+ The function @code{obstack_ptr_grow_fast} adds @code{sizeof (void *)}
+ bytes containing the value of @var{data} to the growing object in
+ obstack @var{obstack-ptr}.
+@@ -1874,6 +2453,8 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_int_grow_fast (struct obstack *@var{obstack-ptr}, int @var{data})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
++@c obstack_int_grow_fast @mtsrace:obstack-ptr
+ The function @code{obstack_int_grow_fast} adds @code{sizeof (int)} bytes
+ containing the value of @var{data} to the growing object in obstack
+ @var{obstack-ptr}.
+@@ -1882,6 +2463,8 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
++@c obstack_blank_fast @mtsrace:obstack-ptr
+ The function @code{obstack_blank_fast} adds @var{size} bytes to the
+ growing object in obstack @var{obstack-ptr} without initializing them.
+ @end deftypefun
+@@ -1909,7 +2492,7 @@
+       int room = obstack_room (obstack);
+       if (room == 0)
+         @{
+-          /* @r{Not enough room. Add one character slowly,}
++          /* @r{Not enough room.  Add one character slowly,}
+              @r{which may copy to a new chunk and make room.}  */
+           obstack_1grow (obstack, *ptr++);
+           len--;
+@@ -1940,6 +2523,7 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}}
+ This function returns the tentative address of the beginning of the
+ currently growing object in @var{obstack-ptr}.  If you finish the object
+ immediately, it will have that address.  If you make it larger first, it
+@@ -1953,6 +2537,7 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}}
+ This function returns the address of the first free byte in the current
+ chunk of obstack @var{obstack-ptr}.  This is the end of the currently
+ growing object.  If no object is growing, @code{obstack_next_free}
+@@ -1962,6 +2547,8 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
++@c dup
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
+ This function returns the size in bytes of the currently growing object.
+ This is equivalent to
+ 
+@@ -1986,6 +2573,7 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The value is a bit mask; a bit that is 1 indicates that the corresponding
+ bit in the address of an object should be 0.  The mask value should be one
+ less than a power of 2; the effect is that all object addresses are
+@@ -2053,6 +2641,7 @@
+ @comment obstack.h
+ @comment GNU
+ @deftypefn Macro int obstack_chunk_size (struct obstack *@var{obstack-ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This returns the chunk size of the given obstack.
+ @end deftypefn
+ 
+@@ -2172,6 +2761,7 @@
+ @comment stdlib.h
+ @comment GNU, BSD
+ @deftypefun {void *} alloca (size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The return value of @code{alloca} is the address of a block of @var{size}
+ bytes of memory, allocated in the stack frame of the calling function.
+ @end deftypefun
+@@ -2354,6 +2944,7 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int brk (void *@var{addr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ @code{brk} sets the high end of the calling process' data segment to
+ @var{addr}.
+@@ -2396,6 +2987,8 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun void *sbrk (ptrdiff_t @var{delta})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++
+ This function is the same as @code{brk} except that you specify the new
+ end of the data segment as an offset @var{delta} from the current end
+ and on success the return value is the address of the resulting end of
+@@ -2535,6 +3128,7 @@
+ @comment sys/mman.h
+ @comment POSIX.1b
+ @deftypefun int mlock (const void *@var{addr}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ @code{mlock} locks a range of the calling process' virtual pages.
+ 
+@@ -2588,6 +3182,7 @@
+ @comment sys/mman.h
+ @comment POSIX.1b
+ @deftypefun int munlock (const void *@var{addr}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ @code{munlock} unlocks a range of the calling process' virtual pages.
+ 
+@@ -2600,6 +3195,7 @@
+ @comment sys/mman.h
+ @comment POSIX.1b
+ @deftypefun int mlockall (int @var{flags})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ @code{mlockall} locks all the pages in a process' virtual memory address
+ space, and/or any that are added to it in the future.  This includes the
+@@ -2676,6 +3272,7 @@
+ @comment sys/mman.h
+ @comment POSIX.1b
+ @deftypefun int munlockall (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ @code{munlockall} unlocks every page in the calling process' virtual
+ address space and turn off @code{MCL_FUTURE} future locking mode.
+diff -urN glibc-2.17-c758a686/manual/message.texi glibc/manual/message.texi
+--- glibc-2.17-c758a686/manual/message.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/message.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -2,9 +2,9 @@
+ @c %MENU% How to make the program speak the user's language
+ @chapter Message Translation
+ 
+-The program's interface with the human should be designed in a way to
+-ease the human the task.  One of the possibilities is to use messages in
+-whatever language the user prefers.
++The program's interface with the user should be designed to ease the user's
++task.  One way to ease the user's task is to use messages in whatever
++language the user prefers.
+ 
+ Printing messages in different languages can be implemented in different
+ ways.  One could add all the different languages in the source code and
+@@ -40,7 +40,7 @@
+ @end itemize
+ 
+ The two approaches mainly differ in the implementation of this last
+-step.  The design decisions made for this influences the whole rest.
++step.  Decisions made in the last step influence the rest of the design.
+ 
+ @menu
+ * Message catalogs a la X/Open::  The @code{catgets} family of functions.
+@@ -86,7 +86,32 @@
+ @comment nl_types.h
+ @comment X/Open
+ @deftypefun nl_catd catopen (const char *@var{cat_name}, int @var{flag})
+-The @code{catgets} function tries to locate the message data file names
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c catopen @mtsenv @ascuheap @acsmem
++@c  strchr ok
++@c  setlocale(,NULL) ok
++@c  getenv @mtsenv
++@c  strlen ok
++@c  alloca ok
++@c  stpcpy ok
++@c  malloc @ascuheap @acsmem
++@c  __open_catalog @ascuheap @acsmem
++@c   strchr ok
++@c   open_not_cancel_2 @acsfd
++@c   strlen ok
++@c   ENOUGH ok
++@c    alloca ok
++@c    memcpy ok
++@c   fxstat64 ok
++@c   __set_errno ok
++@c   mmap @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c   read_not_cancel ok
++@c   free dup @ascuheap @acsmem
++@c   munmap ok
++@c   close_not_cancel_no_status ok
++@c  free @ascuheap @acsmem
++The @code{catopen} function tries to locate the message data file names
+ @var{cat_name} and loads it when found.  The return value is of an
+ opaque type and can be used in calls to the other functions to refer to
+ this loaded catalog.
+@@ -243,6 +268,7 @@
+ 
+ 
+ @deftypefun {char *} catgets (nl_catd @var{catalog_desc}, int @var{set}, int @var{message}, const char *@var{string})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The function @code{catgets} has to be used to access the massage catalog
+ previously opened using the @code{catopen} function.  The
+ @var{catalog_desc} parameter must be a value previously returned by
+@@ -281,6 +307,11 @@
+ Usage}).
+ 
+ @deftypefun int catclose (nl_catd @var{catalog_desc})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c catclose @ascuheap @acucorrupt @acsmem
++@c  __set_errno ok
++@c  munmap ok
++@c  free @ascuheap @acsmem
+ The @code{catclose} function can be used to free the resources
+ associated with a message catalog which previously was opened by a call
+ to @code{catopen}.  If the resources can be successfully freed the
+@@ -803,12 +834,14 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} gettext (const char *@var{msgid})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c Wrapper for dcgettext.
+ The @code{gettext} function searches the currently selected message
+ catalogs for a string which is equal to @var{msgid}.  If there is such a
+ string available it is returned.  Otherwise the argument string
+ @var{msgid} is returned.
+ 
+-Please note that all though the return value is @code{char *} the
++Please note that although the return value is @code{char *} the
+ returned string must not be changed.  This broken type results from the
+ history of the function and does not reflect the way the function should
+ be used.
+@@ -850,6 +883,8 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} dgettext (const char *@var{domainname}, const char *@var{msgid})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c Wrapper for dcgettext.
+ The @code{dgettext} functions acts just like the @code{gettext}
+ function.  It only takes an additional first argument @var{domainname}
+ which guides the selection of the message catalogs which are searched
+@@ -864,6 +899,102 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} dcgettext (const char *@var{domainname}, const char *@var{msgid}, int @var{category})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c dcgettext @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c  dcigettext @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c   libc_rwlock_rdlock @asulock @aculock
++@c   current_locale_name ok [protected from @mtslocale]
++@c   tfind ok
++@c   libc_rwlock_unlock ok
++@c   plural_lookup ok
++@c    plural_eval ok
++@c    rawmemchr ok
++@c   DETERMINE_SECURE ok, nothing
++@c   strcmp ok
++@c   strlen ok
++@c   getcwd @ascuheap @acsmem @acsfd
++@c   strchr ok
++@c   stpcpy ok
++@c   category_to_name ok
++@c   guess_category_value @mtsenv
++@c    getenv @mtsenv
++@c    current_locale_name dup ok [protected from @mtslocale by dcigettext]
++@c    strcmp ok
++@c   ENABLE_SECURE ok
++@c   _nl_find_domain @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c    libc_rwlock_rdlock dup @asulock @aculock
++@c    _nl_make_l10nflist dup @ascuheap @acsmem
++@c    libc_rwlock_unlock dup ok
++@c    _nl_load_domain @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c     libc_lock_lock_recursive @aculock
++@c     libc_lock_unlock_recursive @aculock
++@c     open->open_not_cancel_2 @acsfd
++@c     fstat ok
++@c     mmap dup @acsmem
++@c     close->close_not_cancel_no_status @acsfd
++@c     malloc dup @ascuheap @acsmem
++@c     read->read_not_cancel ok
++@c     munmap dup @acsmem
++@c     W dup ok
++@c     strlen dup ok
++@c     get_sysdep_segment_value ok
++@c     memcpy dup ok
++@c     hash_string dup ok
++@c     free dup @ascuheap @acsmem
++@c     libc_rwlock_init ok
++@c     _nl_find_msg dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c     libc_rwlock_fini ok
++@c     EXTRACT_PLURAL_EXPRESSION @ascuheap @acsmem
++@c      strstr dup ok
++@c      isspace ok
++@c      strtoul ok
++@c      PLURAL_PARSE @ascuheap @acsmem
++@c       malloc dup @ascuheap @acsmem
++@c       free dup @ascuheap @acsmem
++@c      INIT_GERMANIC_PLURAL ok, nothing
++@c        the pre-C99 variant is @acucorrupt [protected from @mtuinit by dcigettext]
++@c    _nl_expand_alias dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c    _nl_explode_name dup @ascuheap @acsmem
++@c    libc_rwlock_wrlock dup @asulock @aculock
++@c    free dup @asulock @aculock @acsfd @acsmem
++@c   _nl_find_msg @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c    _nl_load_domain dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
++@c    strlen ok
++@c    hash_string ok
++@c    W ok
++@c     SWAP ok
++@c      bswap_32 ok
++@c    strcmp ok
++@c    get_output_charset @mtsenv @ascuheap @acsmem
++@c     getenv dup @mtsenv
++@c     strlen dup ok
++@c     malloc dup @ascuheap @acsmem
++@c     memcpy dup ok
++@c    libc_rwlock_rdlock dup @asulock @aculock
++@c    libc_rwlock_unlock dup ok
++@c    libc_rwlock_wrlock dup @asulock @aculock
++@c    realloc @ascuheap @acsmem
++@c    strdup @ascuheap @acsmem
++@c    strstr ok
++@c    strcspn ok
++@c    mempcpy dup ok
++@c    norm_add_slashes dup ok
++@c    gconv_open @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c     [protected from @mtslocale by dcigettext locale lock]
++@c    free dup @ascuheap @acsmem
++@c    libc_lock_lock @asulock @aculock
++@c    calloc @ascuheap @acsmem
++@c    gconv dup @acucorrupt [protected from @mtsrace and @asucorrupt by lock]
++@c    libc_lock_unlock ok
++@c   malloc @ascuheap @acsmem
++@c   mempcpy ok
++@c   memcpy ok
++@c   strcpy ok
++@c   libc_rwlock_wrlock @asulock @aculock
++@c   tsearch @ascuheap @acucorrupt @acsmem [protected from @mtsrace and @asucorrupt]
++@c    transcmp ok
++@c     strmp dup ok
++@c   free @ascuheap @acsmem
+ The @code{dcgettext} adds another argument to those which
+ @code{dgettext} takes.  This argument @var{category} specifies the last
+ piece of information needed to localize the message catalog.  I.e., the
+@@ -967,7 +1098,7 @@
+ second best choice to fall back on the language of the developer and
+ simply not translate any message.  Instead a user might be better able
+ to read the messages in another language and so the user of the program
+-should be able to define an precedence order of languages.
++should be able to define a precedence order of languages.
+ @end itemize
+ 
+ We can divide the configuration actions in two parts: the one is
+@@ -988,6 +1119,13 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} textdomain (const char *@var{domainname})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
++@c textdomain @asulock @ascuheap @aculock @acsmem
++@c  libc_rwlock_wrlock @asulock @aculock
++@c  strcmp ok
++@c  strdup @ascuheap @acsmem
++@c  free @ascuheap @acsmem
++@c  libc_rwlock_unlock ok
+ The @code{textdomain} function sets the default domain, which is used in
+ all future @code{gettext} calls, to @var{domainname}.  Please note that
+ @code{dgettext} and @code{dcgettext} calls are not influenced if the
+@@ -1019,6 +1157,14 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} bindtextdomain (const char *@var{domainname}, const char *@var{dirname})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c bindtextdomain @ascuheap @acsmem
++@c  set_binding_values @ascuheap @acsmem
++@c   libc_rwlock_wrlock dup @asulock @aculock
++@c   strcmp dup ok
++@c   strdup dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c   malloc dup @ascuheap @acsmem
+ The @code{bindtextdomain} function can be used to specify the directory
+ which contains the message catalogs for domain @var{domainname} for the
+ different languages.  To be correct, this is the directory where the
+@@ -1114,7 +1260,7 @@
+ extended @code{gettext} interface should be used.
+ 
+ These extra functions are taking instead of the one key string two
+-strings and an numerical argument.  The idea behind this is that using
++strings and a numerical argument.  The idea behind this is that using
+ the numerical argument and the first string as a key, the implementation
+ can select using rules specified by the translator the right plural
+ form.  The two string arguments then will be used to provide a return
+@@ -1134,6 +1280,8 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} ngettext (const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c Wrapper for dcngettext.
+ The @code{ngettext} function is similar to the @code{gettext} function
+ as it finds the message catalogs in the same way.  But it takes two
+ extra arguments.  The @var{msgid1} parameter must contain the singular
+@@ -1157,6 +1305,8 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} dngettext (const char *@var{domain}, const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c Wrapper for dcngettext.
+ The @code{dngettext} is similar to the @code{dgettext} function in the
+ way the message catalog is selected.  The difference is that it takes
+ two extra parameter to provide the correct plural form.  These two
+@@ -1166,6 +1316,8 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} dcngettext (const char *@var{domain}, const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n}, int @var{category})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c Wrapper for dcigettext.
+ The @code{dcngettext} is similar to the @code{dcgettext} function in the
+ way the message catalog is selected.  The difference is that it takes
+ two extra parameter to provide the correct plural form.  These two
+@@ -1422,6 +1574,9 @@
+ @comment libintl.h
+ @comment GNU
+ @deftypefun {char *} bind_textdomain_codeset (const char *@var{domainname}, const char *@var{codeset})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c bind_textdomain_codeset @ascuheap @acsmem
++@c  set_binding_values dup @ascuheap @acsmem
+ The @code{bind_textdomain_codeset} function can be used to specify the
+ output character set for message catalogs for domain @var{domainname}.
+ The @var{codeset} argument must be a valid codeset name which can be used
+@@ -1429,7 +1584,7 @@
+ 
+ If the @var{codeset} parameter is the null pointer,
+ @code{bind_textdomain_codeset} returns the currently selected codeset
+-for the domain with the name @var{domainname}. It returns @code{NULL} if
++for the domain with the name @var{domainname}.  It returns @code{NULL} if
+ no codeset has yet been selected.
+ 
+ The @code{bind_textdomain_codeset} function can be used several times.
+@@ -1441,7 +1596,8 @@
+ allocated internally in the function and must not be changed by the
+ user.  If the system went out of core during the execution of
+ @code{bind_textdomain_codeset}, the return value is @code{NULL} and the
+-global variable @var{errno} is set accordingly.  @end deftypefun
++global variable @var{errno} is set accordingly.
++@end deftypefun
+ 
+ 
+ @node GUI program problems
+diff -urN glibc-2.17-c758a686/manual/nss.texi glibc/manual/nss.texi
+--- glibc-2.17-c758a686/manual/nss.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/nss.texi	2014-09-12 16:10:25.996741462 -0400
+@@ -10,7 +10,7 @@
+ using files (e.g., @file{/etc/passwd}), but other nameservices (like the
+ Network Information Service (NIS) and the Domain Name Service (DNS))
+ became popular, and were hacked into the C library, usually with a fixed
+-search order (@pxref{frobnicate, , ,jargon, The Jargon File}).
++search order.
+ 
+ @Theglibc{} contains a cleaner solution of this problem.  It is
+ designed after a method used by Sun Microsystems in the C library of
+diff -urN glibc-2.17-c758a686/manual/pattern.texi glibc/manual/pattern.texi
+--- glibc-2.17-c758a686/manual/pattern.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/pattern.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -28,6 +28,38 @@
+ @comment fnmatch.h
+ @comment POSIX.2
+ @deftypefun int fnmatch (const char *@var{pattern}, const char *@var{string}, int @var{flags})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c fnmatch @mtsenv @mtslocale @ascuheap @acsmem
++@c  strnlen dup ok
++@c  mbsrtowcs
++@c  memset dup ok
++@c  malloc dup @ascuheap @acsmem
++@c  mbsinit dup ok
++@c  free dup @ascuheap @acsmem
++@c  FCT = internal_fnwmatch @mtsenv @mtslocale @ascuheap @acsmem
++@c   FOLD @mtslocale
++@c    towlower @mtslocale
++@c   EXT @mtsenv @mtslocale @ascuheap @acsmem
++@c    STRLEN = wcslen dup ok
++@c    getenv @mtsenv
++@c    malloc dup @ascuheap @acsmem
++@c    MEMPCPY = wmempcpy dup ok
++@c    FCT dup @mtsenv @mtslocale @ascuheap @acsmem
++@c    STRCAT = wcscat dup ok
++@c    free dup @ascuheap @acsmem
++@c   END @mtsenv
++@c    getenv @mtsenv
++@c   MEMCHR = wmemchr dup ok
++@c   getenv @mtsenv
++@c   IS_CHAR_CLASS = is_char_class @mtslocale
++@c    wctype @mtslocale
++@c   BTOWC ok
++@c   ISWCTYPE ok
++@c   auto findidx dup ok
++@c   elem_hash dup ok
++@c   memcmp dup ok
++@c   collseq_table_lookup dup ok
++@c   NO_LEADING_PERIOD ok
+ This function tests whether the string @var{string} matches the pattern
+ @var{pattern}.  It returns @code{0} if they do match; otherwise, it
+ returns the nonzero value @code{FNM_NOMATCH}.  The arguments
+@@ -36,11 +68,8 @@
+ The argument @var{flags} is a combination of flag bits that alter the
+ details of matching.  See below for a list of the defined flags.
+ 
+-In @theglibc{}, @code{fnmatch} cannot experience an ``error''---it
+-always returns an answer for whether the match succeeds.  However, other
+-implementations of @code{fnmatch} might sometimes report ``errors''.
+-They would do so by returning nonzero values that are not equal to
+-@code{FNM_NOMATCH}.
++In @theglibc{}, @code{fnmatch} might sometimes report ``errors'' by
++returning nonzero values that are not equal to @code{FNM_NOMATCH}.
+ @end deftypefun
+ 
+ These are the available flags for the @var{flags} argument:
+@@ -234,6 +263,12 @@
+ (*) (const char *,} @w{struct stat *)}}.
+ 
+ This is a GNU extension.
++
++@item gl_flags
++The flags used when @code{glob} was called.  In addition, @code{GLOB_MAGCHAR}
++might be set.  See @ref{Flags for Globbing} for more details.
++
++This is a GNU extension.
+ @end table
+ @end deftp
+ 
+@@ -312,12 +347,75 @@
+ (*) (const char *,} @w{struct stat64 *)}}.
+ 
+ This is a GNU extension.
++
++@item gl_flags
++The flags used when @code{glob} was called.  In addition, @code{GLOB_MAGCHAR}
++might be set.  See @ref{Flags for Globbing} for more details.
++
++This is a GNU extension.
+ @end table
+ @end deftp
+ 
+ @comment glob.h
+ @comment POSIX.2
+ @deftypefun int glob (const char *@var{pattern}, int @var{flags}, int (*@var{errfunc}) (const char *@var{filename}, int @var{error-code}), glob_t *@var{vector-ptr})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c glob @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  strlen dup ok
++@c  strchr dup ok
++@c  malloc dup @ascuheap @acsmem
++@c  mempcpy dup ok
++@c  next_brace_sub ok
++@c  free dup @ascuheap @acsmem
++@c  globfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
++@c  glob_pattern_p ok
++@c   glob_pattern_type dup ok
++@c  getenv dup @mtsenv
++@c  GET_LOGIN_NAME_MAX ok
++@c  getlogin_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  GETPW_R_SIZE_MAX ok
++@c  getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  memcpy dup ok
++@c  memchr dup ok
++@c  *pglob->gl_stat user-supplied
++@c  stat64 dup ok
++@c  S_ISDIR dup ok
++@c  strdup dup @ascuheap @acsmem
++@c  glob_pattern_type ok
++@c  glob_in_dir @mtsenv @mtslocale @asucorrupt @ascuheap @acucorrupt @acsfd @acsmem
++@c   strlen dup ok
++@c   glob_pattern_type dup ok
++@c   malloc dup @ascuheap @acsmem
++@c   mempcpy dup ok
++@c   *pglob->gl_stat user-supplied
++@c   stat64 dup ok
++@c   free dup @ascuheap @acsmem
++@c   *pglob->gl_opendir user-supplied
++@c   opendir dup @ascuheap @acsmem @acsfd
++@c   dirfd dup ok
++@c   *pglob->gl_readdir user-supplied
++@c   CONVERT_DIRENT_DIRENT64 ok
++@c   readdir64 ok [protected by exclusive use of the stream]
++@c   REAL_DIR_ENTRY ok
++@c   DIRENT_MIGHT_BE_DIR ok
++@c   fnmatch dup @mtsenv @mtslocale @ascuheap @acsmem
++@c   DIRENT_MIGHT_BE_SYMLINK ok
++@c   link_exists_p ok
++@c    link_exists2_p ok
++@c     strlen dup ok
++@c     mempcpy dup ok
++@c     *pglob->gl_stat user-supplied
++@c    fxstatat64 dup ok
++@c   realloc dup @ascuheap @acsmem
++@c   pglob->gl_closedir user-supplied
++@c   closedir @ascuheap @acsmem @acsfd
++@c  prefix_array dup @asucorrupt @ascuheap @acucorrupt @acsmem
++@c   strlen dup ok
++@c   malloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c   mempcpy dup ok
++@c  strcpy dup ok
+ The function @code{glob} does globbing using the pattern @var{pattern}
+ in the current directory.  It puts the result in a newly allocated
+ vector, and stores the size and address of this vector into
+@@ -389,6 +487,8 @@
+ @comment glob.h
+ @comment GNU
+ @deftypefun int glob64 (const char *@var{pattern}, int @var{flags}, int (*@var{errfunc}) (const char *@var{filename}, int @var{error-code}), glob64_t *@var{vector-ptr})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c Same code as glob, but with glob64_t #defined as glob_t.
+ The @code{glob64} function was added as part of the Large File Summit
+ extensions but is not part of the original LFS proposal.  The reason for
+ this is simple: it is not necessary.  The necessity for a @code{glob64}
+@@ -408,10 +508,12 @@
+ @node Flags for Globbing
+ @subsection Flags for Globbing
+ 
+-This section describes the flags that you can specify in the
++This section describes the standard flags that you can specify in the
+ @var{flags} argument to @code{glob}.  Choose the flags you want,
+ and combine them with the C bitwise OR operator @code{|}.
+ 
++Note that there are @ref{More Flags for Globbing} available as GNU extensions.
++
+ @vtable @code
+ @comment glob.h
+ @comment POSIX.2
+@@ -481,13 +583,6 @@
+ 
+ @comment glob.h
+ @comment POSIX.2
+-@item GLOB_NOSORT
+-Don't sort the file names; return them in no particular order.
+-(In practice, the order will depend on the order of the entries in
+-the directory.)  The only reason @emph{not} to sort is to save time.
+-
+-@comment glob.h
+-@comment POSIX.2
+ @item GLOB_NOESCAPE
+ Don't treat the @samp{\} character specially in patterns.  Normally,
+ @samp{\} quotes the following character, turning off its special meaning
+@@ -500,6 +595,13 @@
+ @code{glob} does its work by calling the function @code{fnmatch}
+ repeatedly.  It handles the flag @code{GLOB_NOESCAPE} by turning on the
+ @code{FNM_NOESCAPE} flag in calls to @code{fnmatch}.
++
++@comment glob.h
++@comment POSIX.2
++@item GLOB_NOSORT
++Don't sort the file names; return them in no particular order.
++(In practice, the order will depend on the order of the entries in
++the directory.)  The only reason @emph{not} to sort is to save time.
+ @end vtable
+ 
+ @node More Flags for Globbing
+@@ -651,6 +753,9 @@
+ @comment glob.h
+ @comment POSIX.2
+ @deftypefun void globfree (glob_t *@var{pglob})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c globfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
++@c  free dup @ascuheap @acsmem
+ The @code{globfree} function frees all resources allocated by previous
+ calls to @code{glob} associated with the object pointed to by
+ @var{pglob}.  This function should be called whenever the currently used
+@@ -660,6 +765,7 @@
+ @comment glob.h
+ @comment GNU
+ @deftypefun void globfree64 (glob64_t *@var{pglob})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+ This function is equivalent to @code{globfree} but it frees records of
+ type @code{glob64_t} which were allocated by @code{glob64}.
+ @end deftypefun
+@@ -722,6 +828,250 @@
+ @comment regex.h
+ @comment POSIX.2
+ @deftypefun int regcomp (regex_t *restrict @var{compiled}, const char *restrict @var{pattern}, int @var{cflags})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c All of the issues have to do with memory allocation and multi-byte
++@c character handling present in the input string, or implied by ranges
++@c or inverted character classes.
++@c (re_)malloc @ascuheap @acsmem
++@c re_compile_internal @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  (re_)realloc @ascuheap @acsmem [no @asucorrupt @acucorrupt for we zero the buffer]
++@c  init_dfa @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   (re_)malloc @ascuheap @acsmem
++@c   calloc @ascuheap @acsmem
++@c   _NL_CURRENT ok
++@c   _NL_CURRENT_WORD ok
++@c   btowc @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  libc_lock_init ok
++@c  re_string_construct @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   re_string_construct_common ok
++@c   re_string_realloc_buffers @ascuheap @acsmem
++@c    (re_)realloc dup @ascuheap @acsmem
++@c   build_wcs_upper_buffer @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    isascii ok
++@c    mbsinit ok
++@c    toupper ok
++@c    mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    iswlower @mtslocale
++@c    towupper @mtslocale
++@c    wcrtomb dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    (re_)malloc dup @ascuheap @acsmem
++@c   build_upper_buffer ok (@mtslocale but optimized)
++@c    islower ok
++@c    toupper ok
++@c   build_wcs_buffer @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   re_string_translate_buffer ok
++@c  parse @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   fetch_token @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    peek_token @mtslocale
++@c     re_string_eoi ok
++@c     re_string_peek_byte ok
++@c     re_string_cur_idx ok
++@c     re_string_length ok
++@c     re_string_peek_byte_case @mtslocale
++@c      re_string_peek_byte dup ok
++@c      re_string_is_single_byte_char ok
++@c      isascii ok
++@c      re_string_peek_byte dup ok
++@c     re_string_wchar_at ok
++@c     re_string_skip_bytes ok
++@c    re_string_skip_bytes dup ok
++@c   parse_reg_exp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    parse_branch @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c     parse_expression @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c      create_token_tree dup @ascuheap @acsmem
++@c      re_string_eoi dup ok
++@c      re_string_first_byte ok
++@c      fetch_token dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c      create_tree dup @ascuheap @acsmem
++@c      parse_sub_exp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       fetch_token dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       parse_reg_exp dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       postorder() @ascuheap @acsmem
++@c        free_tree @ascuheap @acsmem
++@c         free_token dup @ascuheap @acsmem
++@c       create_tree dup @ascuheap @acsmem
++@c      parse_bracket_exp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       _NL_CURRENT dup ok
++@c       _NL_CURRENT_WORD dup ok
++@c       calloc dup @ascuheap @acsmem
++@c       (re_)free dup @ascuheap @acsmem
++@c       peek_token_bracket ok
++@c        re_string_eoi dup ok
++@c        re_string_peek_byte dup ok
++@c        re_string_first_byte dup ok
++@c        re_string_cur_idx dup ok
++@c        re_string_length dup ok
++@c        re_string_skip_bytes dup ok
++@c       bitset_set ok
++@c       re_string_skip_bytes ok
++@c       parse_bracket_element @mtslocale
++@c        re_string_char_size_at ok
++@c        re_string_wchar_at dup ok
++@c        re_string_skip_bytes dup ok
++@c        parse_bracket_symbol @mtslocale
++@c         re_string_eoi dup ok
++@c         re_string_fetch_byte_case @mtslocale
++@c          re_string_fetch_byte ok
++@c          re_string_first_byte dup ok
++@c          isascii ok
++@c          re_string_char_size_at dup ok
++@c          re_string_skip_bytes dup ok
++@c         re_string_fetch_byte dup ok
++@c         re_string_peek_byte dup ok
++@c         re_string_skip_bytes dup ok
++@c        peek_token_bracket dup ok
++@c       auto build_range_exp @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c        auto lookup_collation_sequence_value @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c         btowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c         collseq_table_lookup ok
++@c         auto seek_collating_symbol_entry dup ok
++@c        (re_)realloc dup @ascuheap @acsmem
++@c        collseq_table_lookup dup ok
++@c       bitset_set dup ok
++@c       (re_)realloc dup @ascuheap @acsmem
++@c       build_equiv_class @mtslocale @ascuheap @acsmem
++@c        _NL_CURRENT ok
++@c        auto findidx ok
++@c        bitset_set dup ok
++@c        (re_)realloc dup @ascuheap @acsmem
++@c       auto build_collating_symbol @ascuheap @acsmem
++@c        auto seek_collating_symbol_entry ok
++@c        bitset_set dup ok
++@c        (re_)realloc dup @ascuheap @acsmem
++@c       build_charclass @mtslocale @ascuheap @acsmem
++@c        (re_)realloc dup @ascuheap @acsmem
++@c        bitset_set dup ok
++@c        isalnum ok
++@c        iscntrl ok
++@c        isspace ok
++@c        isalpha ok
++@c        isdigit ok
++@c        isprint ok
++@c        isupper ok
++@c        isblank ok
++@c        isgraph ok
++@c        ispunct ok
++@c        isxdigit ok
++@c       bitset_not ok
++@c       bitset_mask ok
++@c       create_token_tree dup @ascuheap @acsmem
++@c       create_tree dup @ascuheap @acsmem
++@c       free_charset dup @ascuheap @acsmem
++@c      init_word_char @mtslocale
++@c       isalnum ok
++@c      build_charclass_op @mtslocale @ascuheap @acsmem
++@c       calloc dup @ascuheap @acsmem
++@c       build_charclass dup @mtslocale @ascuheap @acsmem
++@c       (re_)free dup @ascuheap @acsmem
++@c       free_charset dup @ascuheap @acsmem
++@c       bitset_set dup ok
++@c       bitset_not dup ok
++@c       bitset_mask dup ok
++@c       create_token_tree dup @ascuheap @acsmem
++@c       create_tree dup @ascuheap @acsmem
++@c      parse_dup_op @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       re_string_cur_idx dup ok
++@c       fetch_number @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c        fetch_token dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       re_string_set_index ok
++@c       postorder() @ascuheap @acsmem
++@c        free_tree dup @ascuheap @acsmem
++@c        mark_opt_subexp ok
++@c       duplicate_tree @ascuheap @acsmem
++@c        create_token_tree dup @ascuheap @acsmem
++@c       create_tree dup @ascuheap @acsmem
++@c     postorder() @ascuheap @acsmem
++@c      free_tree dup @ascuheap @acsmem
++@c    fetch_token dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    parse_branch dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    create_tree dup @ascuheap @acsmem
++@c   create_tree @ascuheap @acsmem
++@c    create_token_tree @ascuheap @acsmem
++@c     (re_)malloc dup @ascuheap @acsmem
++@c  analyze @ascuheap @acsmem
++@c   (re_)malloc dup @ascuheap @acsmem
++@c   preorder() @ascuheap @acsmem
++@c    optimize_subexps ok
++@c    calc_next ok
++@c    link_nfa_nodes @ascuheap @acsmem
++@c     re_node_set_init_1 @ascuheap @acsmem
++@c      (re_)malloc dup @ascuheap @acsmem
++@c     re_node_set_init_2 @ascuheap @acsmem
++@c      (re_)malloc dup @ascuheap @acsmem
++@c   postorder() @ascuheap @acsmem
++@c    lower_subexps @ascuheap @acsmem
++@c     lower_subexp @ascuheap @acsmem
++@c      create_tree dup @ascuheap @acsmem
++@c    calc_first @ascuheap @acsmem
++@c     re_dfa_add_node @ascuheap @acsmem
++@c      (re_)realloc dup @ascuheap @acsmem
++@c      re_node_set_init_empty ok
++@c   calc_eclosure @ascuheap @acsmem
++@c    calc_eclosure_iter @ascuheap @acsmem
++@c     re_node_set_alloc @ascuheap @acsmem
++@c      (re_)malloc dup @ascuheap @acsmem
++@c     duplicate_node_closure @ascuheap @acsmem
++@c      re_node_set_empty ok
++@c      duplicate_node @ascuheap @acsmem
++@c       re_dfa_add_node dup @ascuheap @acsmem
++@c      re_node_set_insert @ascuheap @acsmem
++@c       (re_)realloc dup @ascuheap @acsmem
++@c      search_duplicated_node ok
++@c     re_node_set_merge @ascuheap @acsmem
++@c      (re_)realloc dup @ascuheap @acsmem
++@c     re_node_set_free @ascuheap @acsmem
++@c      (re_)free dup @ascuheap @acsmem
++@c     re_node_set_insert dup @ascuheap @acsmem
++@c    re_node_set_free dup @ascuheap @acsmem
++@c   calc_inveclosure @ascuheap @acsmem
++@c    re_node_set_init_empty dup ok
++@c    re_node_set_insert_last @ascuheap @acsmem
++@c     (re_)realloc dup @ascuheap @acsmem
++@c  optimize_utf8 ok
++@c  create_initial_state @ascuheap @acsmem
++@c   re_node_set_init_copy @ascuheap @acsmem
++@c    (re_)malloc dup @ascuheap @acsmem
++@c    re_node_set_init_empty dup ok
++@c   re_node_set_contains ok
++@c   re_node_set_merge dup @ascuheap @acsmem
++@c   re_acquire_state_context @ascuheap @acsmem
++@c    calc_state_hash ok
++@c    re_node_set_compare ok
++@c    create_cd_newstate @ascuheap @acsmem
++@c     calloc dup @ascuheap @acsmem
++@c     re_node_set_init_copy dup @ascuheap @acsmem
++@c     (re_)free dup @ascuheap @acsmem
++@c     free_state @ascuheap @acsmem
++@c      re_node_set_free dup @ascuheap @acsmem
++@c      (re_)free dup @ascuheap @acsmem
++@c     NOT_SATISFY_PREV_CONSTRAINT ok
++@c     re_node_set_remove_at ok
++@c     register_state @ascuheap @acsmem
++@c      re_node_set_alloc dup @ascuheap @acsmem
++@c      re_node_set_insert_last dup @ascuheap @acsmem
++@c      (re_)realloc dup @ascuheap @acsmem
++@c   re_node_set_free dup @ascuheap @acsmem
++@c  free_workarea_compile @ascuheap @acsmem
++@c   (re_)free dup @ascuheap @acsmem
++@c  re_string_destruct @ascuheap @acsmem
++@c   (re_)free dup @ascuheap @acsmem
++@c  free_dfa_content @ascuheap @acsmem
++@c   free_token @ascuheap @acsmem
++@c    free_charset @ascuheap @acsmem
++@c     (re_)free dup @ascuheap @acsmem
++@c    (re_)free dup @ascuheap @acsmem
++@c   (re_)free dup @ascuheap @acsmem
++@c   re_node_set_free dup @ascuheap @acsmem
++@c re_compile_fastmap @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  re_compile_fastmap_iter @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   re_set_fastmap ok
++@c    tolower ok
++@c   mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   wcrtomb dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   towlower @mtslocale
++@c   _NL_CURRENT ok
++@c (re_)free @ascuheap @acsmem
+ The function @code{regcomp} ``compiles'' a regular expression into a
+ data structure that you can use with @code{regexec} to match against a
+ string.  The compiled regular expression format is designed for
+@@ -871,6 +1221,247 @@
+ @comment regex.h
+ @comment POSIX.2
+ @deftypefun int regexec (const regex_t *restrict @var{compiled}, const char *restrict @var{string}, size_t @var{nmatch}, regmatch_t @var{matchptr}[restrict], int @var{eflags})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c libc_lock_lock @asulock @aculock
++@c re_search_internal @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  re_string_allocate @ascuheap @acsmem
++@c   re_string_construct_common dup ok
++@c   re_string_realloc_buffers dup @ascuheap @acsmem
++@c  match_ctx_init @ascuheap @acsmem
++@c   (re_)malloc dup @ascuheap @acsmem
++@c  re_string_byte_at ok
++@c  re_string_first_byte dup ok
++@c  check_matching @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   re_string_cur_idx dup ok
++@c   acquire_init_state_context dup @ascuheap @acsmem
++@c    re_string_context_at ok
++@c     re_string_byte_at dup ok
++@c     bitset_contain ok
++@c    re_acquire_state_context dup @ascuheap @acsmem
++@c   check_subexp_matching_top @ascuheap @acsmem
++@c    match_ctx_add_subtop @ascuheap @acsmem
++@c     (re_)realloc dup @ascuheap @acsmem
++@c     calloc dup @ascuheap @acsmem
++@c   transit_state_bkref @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    re_string_cur_idx dup ok
++@c    re_string_context_at dup ok
++@c    NOT_SATISFY_NEXT_CONSTRAINT ok
++@c    get_subexp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c     re_string_get_buffer ok
++@c     search_cur_bkref_entry ok
++@c     clean_state_log_if_needed @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c      extend_buffers @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       re_string_realloc_buffers dup @ascuheap @acsmem
++@c       (re_)realloc dup @ascuheap @acsmem
++@c       build_wcs_upper_buffer dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       build_upper_buffer dup ok (@mtslocale but optimized)
++@c       build_wcs_buffer dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       re_string_translate_buffer dup ok
++@c     get_subexp_sub @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c      check_arrival @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c       (re_)realloc dup @ascuheap @acsmem
++@c       re_string_context_at dup ok
++@c       re_node_set_init_1 dup @ascuheap @acsmem
++@c       check_arrival_expand_ecl @ascuheap @acsmem
++@c        re_node_set_alloc dup @ascuheap @acsmem
++@c        find_subexp_node ok
++@c        re_node_set_merge dup @ascuheap @acsmem
++@c        re_node_set_free dup @ascuheap @acsmem
++@c        check_arrival_expand_ecl_sub @ascuheap @acsmem
++@c         re_node_set_contains dup ok
++@c         re_node_set_insert dup @ascuheap @acsmem
++@c       re_node_set_free dup @ascuheap @acsmem
++@c       re_node_set_init_copy dup @ascuheap @acsmem
++@c       re_node_set_init_empty dup ok
++@c       expand_bkref_cache @ascuheap @acsmem
++@c        search_cur_bkref_entry dup ok
++@c        re_node_set_contains dup ok
++@c        re_node_set_init_1 dup @ascuheap @acsmem
++@c        check_arrival_expand_ecl dup @ascuheap @acsmem
++@c        re_node_set_merge dup @ascuheap @acsmem
++@c        re_node_set_init_copy dup @ascuheap @acsmem
++@c        re_node_set_insert dup @ascuheap @acsmem
++@c        re_node_set_free dup @ascuheap @acsmem
++@c        re_acquire_state @ascuheap @acsmem
++@c         calc_state_hash dup ok
++@c         re_node_set_compare dup ok
++@c         create_ci_newstate @ascuheap @acsmem
++@c          calloc dup @ascuheap @acsmem
++@c          re_node_set_init_copy dup @ascuheap @acsmem
++@c          (re_)free dup @ascuheap @acsmem
++@c          register_state dup @ascuheap @acsmem
++@c          free_state dup @ascuheap @acsmem
++@c       re_acquire_state_context dup @ascuheap @acsmem
++@c       re_node_set_merge dup @ascuheap @acsmem
++@c       check_arrival_add_next_nodes @mtslocale @ascuheap @acsmem
++@c        re_node_set_init_empty dup ok
++@c        check_node_accept_bytes @mtslocale @ascuheap @acsmem
++@c         re_string_byte_at dup ok
++@c         re_string_char_size_at dup ok
++@c         re_string_elem_size_at @mtslocale
++@c          _NL_CURRENT_WORD dup ok
++@c          _NL_CURRENT dup ok
++@c          auto findidx dup ok
++@c         _NL_CURRENT_WORD dup ok
++@c         _NL_CURRENT dup ok
++@c         collseq_table_lookup dup ok
++@c         find_collation_sequence_value @mtslocale
++@c          _NL_CURRENT_WORD dup ok
++@c          _NL_CURRENT dup ok
++@c         auto findidx dup ok
++@c         wcscoll @mtslocale @ascuheap @acsmem
++@c        re_node_set_empty dup ok
++@c        re_node_set_merge dup @ascuheap @acsmem
++@c        re_node_set_free dup @ascuheap @acsmem
++@c        re_node_set_insert dup @ascuheap @acsmem
++@c        re_acquire_state dup @ascuheap @acsmem
++@c        check_node_accept ok
++@c         re_string_byte_at dup ok
++@c         bitset_contain dup ok
++@c         re_string_context_at dup ok
++@c         NOT_SATISFY_NEXT_CONSTRAINT dup ok
++@c      match_ctx_add_entry @ascuheap @acsmem
++@c       (re_)realloc dup @ascuheap @acsmem
++@c       (re_)free dup @ascuheap @acsmem
++@c      clean_state_log_if_needed dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c     extend_buffers dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c     find_subexp_node dup ok
++@c     calloc dup @ascuheap @acsmem
++@c     check_arrival dup ***
++@c     match_ctx_add_sublast @ascuheap @acsmem
++@c      (re_)realloc dup @ascuheap @acsmem
++@c    re_acquire_state_context dup @ascuheap @acsmem
++@c    re_node_set_init_union @ascuheap @acsmem
++@c     (re_)malloc dup @ascuheap @acsmem
++@c     re_node_set_init_copy dup @ascuheap @acsmem
++@c     re_node_set_init_empty dup ok
++@c    re_node_set_free dup @ascuheap @acsmem
++@c    check_subexp_matching_top dup @ascuheap @acsmem
++@c   check_halt_state_context ok
++@c    re_string_context_at dup ok
++@c    check_halt_node_context ok
++@c     NOT_SATISFY_NEXT_CONSTRAINT dup ok
++@c   re_string_eoi dup ok
++@c   extend_buffers dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   transit_state @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    transit_state_mb @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c     re_string_context_at dup ok
++@c     NOT_SATISFY_NEXT_CONSTRAINT dup ok
++@c     check_node_accept_bytes dup @mtslocale @ascuheap @acsmem
++@c     re_string_cur_idx dup ok
++@c     clean_state_log_if_needed @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c     re_node_set_init_union dup @ascuheap @acsmem
++@c     re_acquire_state_context dup @ascuheap @acsmem
++@c    re_string_fetch_byte dup ok
++@c    re_string_context_at dup ok
++@c    build_trtable @ascuheap @acsmem
++@c     (re_)malloc dup @ascuheap @acsmem
++@c     group_nodes_into_DFAstates @ascuheap @acsmem
++@c      bitset_empty dup ok
++@c      bitset_set dup ok
++@c      bitset_merge dup ok
++@c      bitset_set_all ok
++@c      bitset_clear ok
++@c      bitset_contain dup ok
++@c      bitset_copy ok
++@c      re_node_set_init_copy dup @ascuheap @acsmem
++@c      re_node_set_insert dup @ascuheap @acsmem
++@c      re_node_set_init_1 dup @ascuheap @acsmem
++@c      re_node_set_free dup @ascuheap @acsmem
++@c     re_node_set_alloc dup @ascuheap @acsmem
++@c     malloc dup @ascuheap @acsmem
++@c     free dup @ascuheap @acsmem
++@c     re_node_set_free dup @ascuheap @acsmem
++@c     bitset_empty ok
++@c     re_node_set_empty dup ok
++@c     re_node_set_merge dup @ascuheap @acsmem
++@c     re_acquire_state_context dup @ascuheap @acsmem
++@c     bitset_merge ok
++@c     calloc dup @ascuheap @acsmem
++@c     bitset_contain dup ok
++@c   merge_state_with_log @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    re_string_cur_idx dup ok
++@c    re_node_set_init_union dup @ascuheap @acsmem
++@c    re_string_context_at dup ok
++@c    re_node_set_free dup @ascuheap @acsmem
++@c    check_subexp_matching_top @ascuheap @acsmem
++@c     match_ctx_add_subtop dup @ascuheap @acsmem
++@c    transit_state_bkref dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   find_recover_state
++@c    re_string_cur_idx dup ok
++@c    re_string_skip_bytes dup ok
++@c    merge_state_with_log dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  check_halt_state_context dup ok
++@c  prune_impossible_nodes @mtslocale @ascuheap @acsmem
++@c   (re_)malloc dup @ascuheap @acsmem
++@c   sift_ctx_init ok
++@c    re_node_set_init_empty dup ok
++@c   sift_states_backward @mtslocale @ascuheap @acsmem
++@c    re_node_set_init_1 dup @ascuheap @acsmem
++@c    update_cur_sifted_state @mtslocale @ascuheap @acsmem
++@c     add_epsilon_src_nodes @ascuheap @acsmem
++@c      re_acquire_state dup @ascuheap @acsmem
++@c      re_node_set_alloc dup @ascuheap @acsmem
++@c      re_node_set_merge dup @ascuheap @acsmem
++@c      re_node_set_add_intersect @ascuheap @acsmem
++@c       (re_)realloc dup @ascuheap @acsmem
++@c     check_subexp_limits @ascuheap @acsmem
++@c      sub_epsilon_src_nodes @ascuheap @acsmem
++@c       re_node_set_init_empty dup ok
++@c       re_node_set_contains dup ok
++@c       re_node_set_add_intersect dup @ascuheap @acsmem
++@c       re_node_set_free dup @ascuheap @acsmem
++@c       re_node_set_remove_at dup ok
++@c      re_node_set_contains dup ok
++@c     re_acquire_state dup @ascuheap @acsmem
++@c     sift_states_bkref @mtslocale @ascuheap @acsmem
++@c      search_cur_bkref_entry dup ok
++@c      check_dst_limits ok
++@c       search_cur_bkref_entry dup ok
++@c       check_dst_limits_calc_pos ok
++@c        check_dst_limits_calc_pos_1 ok
++@c      re_node_set_init_copy dup @ascuheap @acsmem
++@c      re_node_set_insert dup @ascuheap @acsmem
++@c      sift_states_backward dup @mtslocale @ascuheap @acsmem
++@c      merge_state_array dup @ascuheap @acsmem
++@c      re_node_set_remove ok
++@c       re_node_set_contains dup ok
++@c       re_node_set_remove_at dup ok
++@c      re_node_set_free dup @ascuheap @acsmem
++@c    re_node_set_free dup @ascuheap @acsmem
++@c    re_node_set_empty dup ok
++@c    build_sifted_states @mtslocale @ascuheap @acsmem
++@c     sift_states_iter_mb @mtslocale @ascuheap @acsmem
++@c      check_node_accept_bytes dup @mtslocale @ascuheap @acsmem
++@c     check_node_accept dup ok
++@c     check_dst_limits dup ok
++@c     re_node_set_insert dup @ascuheap @acsmem
++@c   re_node_set_free dup @ascuheap @acsmem
++@c   check_halt_state_context dup ok
++@c   merge_state_array @ascuheap @acsmem
++@c    re_node_set_init_union dup @ascuheap @acsmem
++@c    re_acquire_state dup @ascuheap @acsmem
++@c    re_node_set_free dup @ascuheap @acsmem
++@c   (re_)free dup @ascuheap @acsmem
++@c  set_regs @ascuheap @acsmem
++@c   (re_)malloc dup @ascuheap @acsmem
++@c   re_node_set_init_empty dup ok
++@c   free_fail_stack_return @ascuheap @acsmem
++@c    re_node_set_free dup @ascuheap @acsmem
++@c    (re_)free dup @ascuheap @acsmem
++@c   update_regs ok
++@c   re_node_set_free dup @ascuheap @acsmem
++@c   pop_fail_stack @ascuheap @acsmem
++@c    re_node_set_free dup @ascuheap @acsmem
++@c    (re_)free dup @ascuheap @acsmem
++@c   (re_)free dup @ascuheap @acsmem
++@c  (re_)free dup @ascuheap @acsmem
++@c  match_ctx_free @ascuheap @acsmem
++@c   match_ctx_clean @ascuheap @acsmem
++@c    (re_)free dup @ascuheap @acsmem
++@c   (re_)free dup @ascuheap @acsmem
++@c  re_string_destruct dup @ascuheap @acsmem
++@c libc_lock_unlock @aculock
+ This function tries to match the compiled regular expression
+ @code{*@var{compiled}} against @var{string}.
+ 
+@@ -1033,6 +1624,9 @@
+ @comment regex.h
+ @comment POSIX.2
+ @deftypefun void regfree (regex_t *@var{compiled})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c (re_)free dup @ascuheap @acsmem
++@c free_dfa_content dup @ascuheap @acsmem
+ Calling @code{regfree} frees all the storage that @code{*@var{compiled}}
+ points to.  This includes various internal fields of the @code{regex_t}
+ structure that aren't documented in this manual.
+@@ -1050,6 +1644,8 @@
+ @comment regex.h
+ @comment POSIX.2
+ @deftypefun size_t regerror (int @var{errcode}, const regex_t *restrict @var{compiled}, char *restrict @var{buffer}, size_t @var{length})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c regerror calls gettext, strcmp and mempcpy or memcpy.
+ This function produces an error message string for the error code
+ @var{errcode}, and stores the string in @var{length} bytes of memory
+ starting at @var{buffer}.  For the @var{compiled} argument, supply the
+@@ -1215,6 +1811,145 @@
+ @comment wordexp.h
+ @comment POSIX.2
+ @deftypefun int wordexp (const char *@var{words}, wordexp_t *@var{word-vector-ptr}, int @var{flags})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasuconst{:@mtsenv{}} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuintl{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c wordexp @mtasurace:utent @mtasuconst:@mtsenv @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  w_newword ok
++@c  wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
++@c  calloc dup @ascuheap @acsmem
++@c  getenv dup @mtsenv
++@c  strcpy dup ok
++@c  parse_backslash @ascuheap @acsmem
++@c   w_addchar dup @ascuheap @acsmem
++@c  parse_dollars @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   w_addchar dup @ascuheap @acsmem
++@c   parse_arith @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    w_newword dup ok
++@c    parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    parse_backtick dup @ascuplugin @ascuheap @aculock @acsfd @acsmem
++@c    parse_qtd_backslash dup @ascuheap @acsmem
++@c    eval_expr @mtslocale
++@c     eval_expr_multidiv @mtslocale
++@c      eval_expr_val @mtslocale
++@c       isspace dup @mtslocale
++@c       eval_expr dup @mtslocale
++@c      isspace dup @mtslocale
++@c     isspace dup @mtslocale
++@c    free dup @ascuheap @acsmem
++@c    w_addchar dup @ascuheap @acsmem
++@c    w_addstr dup @ascuheap @acsmem
++@c    itoa_word dup ok
++@c   parse_comm @ascuplugin @ascuheap @aculock @acsfd @acsmem
++@c    w_newword dup ok
++@c    pthread_setcancelstate @ascuplugin @ascuheap @acsmem
++@c      (disable cancellation around exec_comm; it may do_cancel the
++@c       second time, if async cancel is enabled)
++@c     THREAD_ATOMIC_CMPXCHG_VAL dup ok
++@c     CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS dup ok
++@c     do_cancel @ascuplugin @ascuheap @acsmem
++@c      THREAD_ATOMIC_BIT_SET dup ok
++@c      pthread_unwind @ascuplugin @ascuheap @acsmem
++@c       Unwind_ForcedUnwind if available @ascuplugin @ascuheap @acsmem
++@c       libc_unwind_longjmp otherwise
++@c       cleanups
++@c    exec_comm @ascuplugin @ascuheap @aculock @acsfd @acsmem
++@c     pipe2 dup ok
++@c     pipe dup ok
++@c     fork dup @ascuplugin @aculock
++@c     close dup @acsfd
++@c     on child: exec_comm_child -> exec or abort
++@c     waitpid dup ok
++@c     read dup ok
++@c     w_addmem dup @ascuheap @acsmem
++@c     strchr dup ok
++@c     w_addword dup @ascuheap @acsmem
++@c     w_newword dup ok
++@c     w_addchar dup @ascuheap @acsmem
++@c     free dup @ascuheap @acsmem
++@c     kill dup ok
++@c    free dup @ascuheap @acsmem
++@c   parse_param @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c     reads from __libc_argc and __libc_argv without guards
++@c    w_newword dup ok
++@c    isalpha dup @mtslocale^^
++@c    w_addchar dup @ascuheap @acsmem
++@c    isalnum dup @mtslocale^^
++@c    isdigit dup @mtslocale^^
++@c    strchr dup ok
++@c    itoa_word dup ok
++@c    atoi dup @mtslocale
++@c    getpid dup ok
++@c    w_addstr dup @ascuheap @acsmem
++@c    free dup @ascuheap @acsmem
++@c    strlen dup ok
++@c    malloc dup @ascuheap @acsmem
++@c    stpcpy dup ok
++@c    w_addword dup @ascuheap @acsmem
++@c    strdup dup @ascuheap @acsmem
++@c    getenv dup @mtsenv
++@c    parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    parse_tilde dup @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    fnmatch dup @mtsenv @mtslocale @ascuheap @acsmem
++@c    mempcpy dup ok
++@c    _ dup @ascuintl
++@c    fxprintf dup @aculock
++@c    setenv dup @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
++@c    strspn dup ok
++@c    strcspn dup ok
++@c  parse_backtick @ascuplugin @ascuheap @aculock @acsfd @acsmem
++@c   w_newword dup ok
++@c   exec_comm dup @ascuplugin @ascuheap @aculock @acsfd @acsmem
++@c   free dup @ascuheap @acsmem
++@c   parse_qtd_backslash dup @ascuheap @acsmem
++@c   parse_backslash dup @ascuheap @acsmem
++@c   w_addchar dup @ascuheap @acsmem
++@c  parse_dquote @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   parse_backtick dup @ascuplugin @ascuheap @aculock @acsfd @acsmem
++@c   parse_qtd_backslash dup @ascuheap @acsmem
++@c   w_addchar dup @ascuheap @acsmem
++@c  w_addword dup @ascuheap @acsmem
++@c   strdup dup @ascuheap @acsmem
++@c   realloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  parse_squote dup @ascuheap @acsmem
++@c   w_addchar dup @ascuheap @acsmem
++@c  parse_tilde @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   strchr dup ok
++@c   w_addchar dup @ascuheap @acsmem
++@c   getenv dup @mtsenv
++@c   w_addstr dup @ascuheap @acsmem
++@c    strlen dup ok
++@c    w_addmem dup @ascuheap @acsmem
++@c     realloc dup @ascuheap @acsmem
++@c     free dup @ascuheap @acsmem
++@c     mempcpy dup ok
++@c   getuid dup ok
++@c   getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  parse_glob @mtasurace:utent @mtasuconst:@mtsenv @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   strchr dup ok
++@c   parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   parse_qtd_backslash @ascuheap @acsmem
++@c    w_addchar dup @ascuheap @acsmem
++@c   parse_backslash dup @ascuheap @acsmem
++@c   w_addchar dup @ascuheap @acsmem
++@c   w_addword dup @ascuheap @acsmem
++@c   w_newword dup ok
++@c   do_parse_glob @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem
++@c    glob dup @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem [auto glob_t avoids @asucorrupt @acucorrupt]
++@c    w_addstr dup @ascuheap @acsmem
++@c    w_addchar dup @ascuheap @acsmem
++@c    globfree dup @ascuheap @acsmem [auto glob_t avoids @asucorrupt @acucorrupt]
++@c    free dup @ascuheap @acsmem
++@c    w_newword dup ok
++@c    strdup dup @ascuheap @acsmem
++@c    w_addword dup @ascuheap @acsmem
++@c   wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
++@c  strchr dup ok
++@c  w_addchar dup @ascuheap @acsmem
++@c   realloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
+ Perform word expansion on the string @var{words}, putting the result in
+ a newly allocated vector, and store the size and address of this vector
+ into @code{*@var{word-vector-ptr}}.  The argument @var{flags} is a
+@@ -1278,6 +2013,9 @@
+ @comment wordexp.h
+ @comment POSIX.2
+ @deftypefun void wordfree (wordexp_t *@var{word-vector-ptr})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
++@c  free dup @ascuheap @acsmem
+ Free the storage used for the word-strings and vector that
+ @code{*@var{word-vector-ptr}} points to.  This does not free the
+ structure @code{*@var{word-vector-ptr}} itself---only the other
+diff -urN glibc-2.17-c758a686/manual/pipe.texi glibc/manual/pipe.texi
+--- glibc-2.17-c758a686/manual/pipe.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/pipe.texi	2014-09-12 16:10:06.048792709 -0400
+@@ -56,6 +56,8 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int pipe (int @var{filedes}@t{[2]})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
++@c On Linux, syscall pipe2.  On HURD, call socketpair.
+ The @code{pipe} function creates a pipe and puts the file descriptors
+ for the reading and writing ends of the pipe (respectively) into
+ @code{@var{filedes}[0]} and @code{@var{filedes}[1]}.
+@@ -108,6 +110,41 @@
+ @comment stdio.h
+ @comment POSIX.2, SVID, BSD
+ @deftypefun {FILE *} popen (const char *@var{command}, const char *@var{mode})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c popen @ascuheap @asucorrupt @acucorrupt @aculock @acsfd @acsmem
++@c  malloc dup @ascuheap @acsmem
++@c  _IO_init ok
++@c   _IO_no_init ok
++@c    _IO_old_init ok
++@c     _IO_lock_init ok
++@c  _IO_new_file_init @asucorrupt @acucorrupt @aculock @acsfd
++@c   _IO_link_in @asucorrupt @acucorrupt @aculock @acsfd
++@c     the linked list is guarded by a recursive lock;
++@c     it may get corrupted with async signals and cancellation
++@c    _IO_lock_lock dup @aculock
++@c    _IO_flockfile dup @aculock
++@c    _IO_funlockfile dup @aculock
++@c    _IO_lock_unlock dup @aculock
++@c  _IO_new_proc_open @asucorrupt @acucorrupt @aculock @acsfd
++@c    the linked list is guarded by a recursive lock;
++ @c   it may get corrupted with async signals and cancellation
++@c   _IO_file_is_open ok
++@c   pipe2 dup @acsfd
++@c   pipe dup @acsfd
++@c   _IO_fork=fork @aculock
++@c   _IO_close=close_not_cancel dup @acsfd
++@c   fcntl dup ok
++@c   _IO_lock_lock @aculock
++@c   _IO_lock_unlock @aculock
++@c   _IO_mask_flags ok [no @mtasurace:stream, nearly but sufficiently exclusive access]
++@c  _IO_un_link @asucorrupt @acucorrupt @aculock @acsfd
++@c    the linked list is guarded by a recursive lock;
++@c    it may get corrupted with async signals and cancellation
++@c   _IO_lock_lock dup @aculock
++@c   _IO_flockfile dup @aculock
++@c   _IO_funlockfile dup @aculock
++@c   _IO_lock_unlock dup @aculock
++@c  free dup @ascuheap @acsmem
+ The @code{popen} function is closely related to the @code{system}
+ function; see @ref{Running a Command}.  It executes the shell command
+ @var{command} as a subprocess.  However, instead of waiting for the
+@@ -131,6 +168,77 @@
+ @comment stdio.h
+ @comment POSIX.2, SVID, BSD
+ @deftypefun int pclose (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @ascuplugin{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c Although the stream cannot be used after the call, even in case of
++@c async cancellation, because the stream must not be used after pclose
++@c is called, other stdio linked lists and their locks may be left in
++@c corrupt states; that's where the corrupt and lock annotations come
++@c from.
++@c
++@c pclose @ascuheap @ascuplugin @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  _IO_new_fclose @ascuheap @ascuplugin @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd
++@c   _IO_acquire_lock dup @aculock
++@c    _IO_flockfile dup @aculock
++@c   _IO_file_close_it @ascuheap @ascuplugin @asucorrupt @aculock @acucorrupt @acsfd @acsmem
++@c    _IO_file_is_open dup ok
++@c    _IO_do_flush @asucorrupt @ascuplugin @acucorrupt
++@c     _IO_do_write @asucorrupt @acucorrupt
++@c      new_do_write @asucorrupt @acucorrupt
++@c       _IO_SYSSEEK ok
++@c        lseek64 dup ok
++@c       _IO_SYSWRITE ok
++@c        write_not_cancel dup ok
++@c        write dup ok
++@c       _IO_adjust_column ok
++@c       _IO_setg dup @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
++@c     _IO_wdo_write @asucorrupt @ascuplugin @acucorrupt
++@c      _IO_new_do_write=_IO_do_write dup @asucorrupt @acucorrupt
++@c      *cc->__codecvt_do_out @ascuplugin
++@c      _IO_wsetg dup @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
++@c    _IO_unsave_markers @ascuheap @asucorrupt @acucorrupt @acsmem
++@c     _IO_have_backup dup ok
++@c     _IO_free_backup_area dup @ascuheap @asucorrupt @acucorrupt @acsmem
++@c    _IO_SYSCLOSE @aculock @acucorrupt @acsfd
++@c     _IO_lock_lock dup @aculock
++@c     _IO_close=close_not_cancel dup @acsfd
++@c     _IO_lock_unlock dup @aculock
++@c     _IO_waitpid=waitpid_not_cancel dup ok
++@c    _IO_have_wbackup ok
++@c    _IO_free_wbackup_area @ascuheap @asucorrupt @acucorrupt @acsmem
++@c     _IO_in_backup dup ok
++@c     _IO_switch_to_main_wget_area @asucorrupt @acucorrupt
++@c     free dup @ascuheap @acsmem
++@c    _IO_wsetb @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
++@c    _IO_wsetg @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
++@c    _IO_wsetp @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
++@c    _IO_setb @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
++@c    _IO_setg @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
++@c    _IO_setp @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
++@c    _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd
++@c   _IO_release_lock dup @aculock
++@c    _IO_funlockfile dup @aculock
++@c   _IO_FINISH @ascuheap @ascuplugin @asucorrupt @acucorrupt @aculock @acsfd @acsmem
++@c    _IO_new_file_finish @ascuheap @ascuplugin @asucorrupt @acucorrupt @aculock @acsfd @acsmem
++@c     _IO_file_is_open dup ok
++@c     _IO_do_flush dup @ascuplugin @asucorrupt @acucorrupt
++@c     _IO_SYSCLOSE dup @aculock @acucorrupt @acsfd
++@c     _IO_default_finish @ascuheap @asucorrupt @acucorrupt @aculock @acsfd @acsmem
++@c      FREE_BUF @acsmem
++@c       munmap dup @acsmem
++@c      free dup @ascuheap @acsmem
++@c      _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd
++@c      _IO_lock_fini ok
++@c       libc_lock_fini_recursive ok
++@c   libc_lock_lock dup @asulock @aculock
++@c   gconv_release_step ok
++@c   libc_lock_unlock dup @asulock @aculock
++@c   _IO_have_backup ok
++@c   _IO_free_backup_area @ascuheap @asucorrupt @acucorrupt @acsmem
++@c    _IO_in_backup ok
++@c    _IO_switch_to_main_get_area @asucorrupt @acucorrupt
++@c    free dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
+ The @code{pclose} function is used to close a stream created by @code{popen}.
+ It waits for the child process to terminate and returns its status value,
+ as for the @code{system} function.
+@@ -168,6 +276,8 @@
+ @comment sys/stat.h
+ @comment POSIX.1
+ @deftypefun int mkfifo (const char *@var{filename}, mode_t @var{mode})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On generic Posix, calls xmknod.
+ The @code{mkfifo} function makes a FIFO special file with name
+ @var{filename}.  The @var{mode} argument is used to set the file's
+ permissions; see @ref{Setting Permissions}.
+diff -urN glibc-2.17-c758a686/manual/platform.texi glibc/manual/platform.texi
+--- glibc-2.17-c758a686/manual/platform.texi	2014-09-12 16:08:17.865070640 -0400
++++ glibc/manual/platform.texi	2014-09-12 16:10:06.046792714 -0400
+@@ -15,6 +15,7 @@
+ operating system are declared in @file{sys/platform/ppc.h}.
+ 
+ @deftypefun {uint64_t} __ppc_get_timebase (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Read the current value of the Time Base Register.
+ 
+ The @dfn{Time Base Register} is a 64-bit register that stores a monotonically
+@@ -28,6 +29,17 @@
+ @end deftypefun
+ 
+ @deftypefun {uint64_t} __ppc_get_timebase_freq (void)
++@safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asucorrupt{:init}}@acunsafe{@acucorrupt{:init}}}
++@c __ppc_get_timebase_freq=__get_timebase_freq @mtuinit @acsfd
++@c  __get_clockfreq @mtuinit @asucorrupt:init @acucorrupt:init @acsfd
++@c    the initialization of the static timebase_freq is not exactly
++@c    safe, because hp_timing_t cannot be atomically set up.
++@c   syscall:get_tbfreq ok
++@c   open dup @acsfd
++@c   read dup ok
++@c   memcpy dup ok
++@c   memmem dup ok
++@c   close dup @acsfd
+ Read the current frequency at which the Time Base Register is updated.
+ 
+ This frequency is not related to the processor clock or the bus clock.
+@@ -42,17 +54,20 @@
+ Section 3.2}.
+ 
+ @deftypefun {void} __ppc_yield (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Provide a hint that performance will probably be improved if shared resources
+ dedicated to the executing processor are released for use by other processors.
+ @end deftypefun
+ 
+ @deftypefun {void} __ppc_mdoio (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Provide a hint that performance will probably be improved if shared resources
+ dedicated to the executing processor are released until all outstanding storage
+ accesses to caching-inhibited storage have been completed.
+ @end deftypefun
+ 
+ @deftypefun {void} __ppc_mdoom (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Provide a hint that performance will probably be improved if shared resources
+ dedicated to the executing processor are released until all outstanding storage
+ accesses to cacheable storage for which the data is not in the cache have been
+@@ -60,6 +75,7 @@
+ @end deftypefun
+ 
+ @deftypefun {void} __ppc_set_ppr_med (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Set the Program Priority Register to medium value (default).
+ 
+ The @dfn{Program Priority Register} (PPR) is a 64-bit register that controls
+@@ -73,9 +89,11 @@
+ @end deftypefun
+ 
+ @deftypefun {void} __ppc_set_ppr_low (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Set the Program Priority Register to low value.
+ @end deftypefun
+ 
+ @deftypefun {void} __ppc_set_ppr_med_low (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Set the Program Priority Register to medium low value.
+ @end deftypefun
+diff -urN glibc-2.17-c758a686/manual/process.texi glibc/manual/process.texi
+--- glibc-2.17-c758a686/manual/process.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/process.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -1,4 +1,4 @@
+-@node Processes, Job Control, Program Basics, Top
++@node Processes, Inter-Process Communication, Program Basics, Top
+ @c %MENU% How to create processes and run other programs
+ @chapter Processes
+ 
+@@ -55,6 +55,43 @@
+ @comment ISO
+ @deftypefun int system (const char *@var{command})
+ @pindex sh
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
++@c system @ascuplugin @ascuheap @asulock @aculock @acsmem
++@c  do_system @ascuplugin @ascuheap @asulock @aculock @acsmem
++@c   sigemptyset dup ok
++@c   libc_lock_lock @asulock @aculock
++@c   ADD_REF ok
++@c   sigaction dup ok
++@c   SUB_REF ok
++@c   libc_lock_unlock @aculock
++@c   sigaddset dup ok
++@c   sigprocmask dup ok
++@c   CLEANUP_HANDLER @ascuplugin @ascuheap @acsmem
++@c    libc_cleanup_region_start @ascuplugin @ascuheap @acsmem
++@c     pthread_cleanup_push_defer @ascuplugin @ascuheap @acsmem
++@c      CANCELLATION_P @ascuplugin @ascuheap @acsmem
++@c       CANCEL_ENABLED_AND_CANCELED ok
++@c       do_cancel @ascuplugin @ascuheap @acsmem
++@c    cancel_handler ok
++@c     kill syscall ok
++@c     waitpid dup ok
++@c     libc_lock_lock ok
++@c     sigaction dup ok
++@c     libc_lock_unlock ok
++@c   FORK ok
++@c    clone syscall ok
++@c   waitpid dup ok
++@c   CLEANUP_RESET ok
++@c    libc_cleanup_region_end ok
++@c     pthread_cleanup_pop_restore ok
++@c  SINGLE_THREAD_P ok
++@c  LIBC_CANCEL_ASYNC @ascuplugin @ascuheap @acsmem
++@c   libc_enable_asynccancel @ascuplugin @ascuheap @acsmem
++@c    CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS dup ok
++@c    do_cancel dup @ascuplugin @ascuheap @acsmem
++@c  LIBC_CANCEL_RESET ok
++@c   libc_disable_asynccancel ok
++@c    lll_futex_wait dup ok
+ This function executes @var{command} as a shell command.  In @theglibc{},
+ it always uses the default shell @code{sh} to run the command.
+ In particular, it searches the directories in @code{PATH} to find
+@@ -157,12 +194,14 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun pid_t getpid (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{getpid} function returns the process ID of the current process.
+ @end deftypefun
+ 
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun pid_t getppid (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{getppid} function returns the process ID of the parent of the
+ current process.
+ @end deftypefun
+@@ -177,6 +216,19 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun pid_t fork (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}}
++@c The nptl/.../linux implementation safely collects fork_handlers into
++@c an alloca()ed linked list and increments ref counters; it uses atomic
++@c ops and retries, avoiding locking altogether.  It then takes the
++@c IO_list lock, resets the thread-local pid, and runs fork.  The parent
++@c restores the thread-local pid, releases the lock, and runs parent
++@c handlers, decrementing the ref count and signaling futex wait if
++@c requested by unregister_atfork.  The child bumps the fork generation,
++@c sets the thread-local pid, resets cpu clocks, initializes the robust
++@c mutex list, the stream locks, the IO_list lock, the dynamic loader
++@c lock, runs the child handlers, reseting ref counters to 1, and
++@c initializes the fork lock.  These are all safe, unless atfork
++@c handlers themselves are unsafe.
+ The @code{fork} function creates a new process.
+ 
+ If the operation is successful, there are then both parent and child
+@@ -242,6 +294,9 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun pid_t vfork (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}}
++@c The vfork implementation proper is a safe syscall, but it may fall
++@c back to fork if the vfork syscall is not available.
+ The @code{vfork} function is similar to @code{fork} but on some systems
+ it is more efficient; however, there are restrictions you must follow to
+ use it safely.
+@@ -287,6 +342,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int execv (const char *@var{filename}, char *const @var{argv}@t{[]})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{execv} function executes the file named by @var{filename} as a
+ new process image.
+ 
+@@ -305,6 +361,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int execl (const char *@var{filename}, const char *@var{arg0}, @dots{})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is similar to @code{execv}, but the @var{argv} strings are
+ specified individually instead of as an array.  A null pointer must be
+ passed as the last such argument.
+@@ -313,6 +370,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int execve (const char *@var{filename}, char *const @var{argv}@t{[]}, char *const @var{env}@t{[]})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is similar to @code{execv}, but permits you to specify the environment
+ for the new program explicitly as the @var{env} argument.  This should
+ be an array of strings in the same format as for the @code{environ}
+@@ -322,6 +380,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int execle (const char *@var{filename}, const char *@var{arg0}, @dots{}, char *const @var{env}@t{[]})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is similar to @code{execl}, but permits you to specify the
+ environment for the new program explicitly.  The environment argument is
+ passed following the null pointer that marks the last @var{argv}
+@@ -332,6 +391,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int execvp (const char *@var{filename}, char *const @var{argv}@t{[]})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The @code{execvp} function is similar to @code{execv}, except that it
+ searches the directories listed in the @code{PATH} environment variable
+ (@pxref{Standard Environment}) to find the full file name of a
+@@ -345,6 +405,7 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int execlp (const char *@var{filename}, const char *@var{arg0}, @dots{})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This function is like @code{execl}, except that it performs the same
+ file name searching as the @code{execvp} function.
+ @end deftypefun
+@@ -462,6 +523,7 @@
+ @comment sys/wait.h
+ @comment POSIX.1
+ @deftypefun pid_t waitpid (pid_t @var{pid}, int *@var{status-ptr}, int @var{options})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{waitpid} function is used to request status information from a
+ child process whose process ID is @var{pid}.  Normally, the calling
+ process is suspended until the child process makes status information
+@@ -565,6 +627,7 @@
+ @comment sys/wait.h
+ @comment POSIX.1
+ @deftypefun pid_t wait (int *@var{status-ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is a simplified version of @code{waitpid}, and is used to wait
+ until any one child process terminates.  The call:
+ 
+@@ -591,6 +654,7 @@
+ @comment sys/wait.h
+ @comment BSD
+ @deftypefun pid_t wait4 (pid_t @var{pid}, int *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If @var{usage} is a null pointer, @code{wait4} is equivalent to
+ @code{waitpid (@var{pid}, @var{status-ptr}, @var{options})}.
+ 
+@@ -643,6 +707,7 @@
+ @comment sys/wait.h
+ @comment POSIX.1
+ @deftypefn Macro int WIFEXITED (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns a nonzero value if the child process terminated
+ normally with @code{exit} or @code{_exit}.
+ @end deftypefn
+@@ -650,6 +715,7 @@
+ @comment sys/wait.h
+ @comment POSIX.1
+ @deftypefn Macro int WEXITSTATUS (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If @code{WIFEXITED} is true of @var{status}, this macro returns the
+ low-order 8 bits of the exit status value from the child process.
+ @xref{Exit Status}.
+@@ -658,6 +724,7 @@
+ @comment sys/wait.h
+ @comment POSIX.1
+ @deftypefn Macro int WIFSIGNALED (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns a nonzero value if the child process terminated
+ because it received a signal that was not handled.
+ @xref{Signal Handling}.
+@@ -666,6 +733,7 @@
+ @comment sys/wait.h
+ @comment POSIX.1
+ @deftypefn Macro int WTERMSIG (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If @code{WIFSIGNALED} is true of @var{status}, this macro returns the
+ signal number of the signal that terminated the child process.
+ @end deftypefn
+@@ -673,6 +741,7 @@
+ @comment sys/wait.h
+ @comment BSD
+ @deftypefn Macro int WCOREDUMP (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns a nonzero value if the child process terminated
+ and produced a core dump.
+ @end deftypefn
+@@ -680,12 +749,14 @@
+ @comment sys/wait.h
+ @comment POSIX.1
+ @deftypefn Macro int WIFSTOPPED (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro returns a nonzero value if the child process is stopped.
+ @end deftypefn
+ 
+ @comment sys/wait.h
+ @comment POSIX.1
+ @deftypefn Macro int WSTOPSIG (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If @code{WIFSTOPPED} is true of @var{status}, this macro returns the
+ signal number of the signal that caused the child process to stop.
+ @end deftypefn
+@@ -739,6 +810,7 @@
+ @comment sys/wait.h
+ @comment BSD
+ @deftypefun pid_t wait3 (union wait *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ If @var{usage} is a null pointer, @code{wait3} is equivalent to
+ @code{waitpid (-1, @var{status-ptr}, @var{options})}.
+ 
+diff -urN glibc-2.17-c758a686/manual/resource.texi glibc/manual/resource.texi
+--- glibc-2.17-c758a686/manual/resource.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/resource.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -25,6 +25,8 @@
+ @comment sys/resource.h
+ @comment BSD
+ @deftypefun int getrusage (int @var{processes}, struct rusage *@var{rusage})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On HURD, this calls task_info 3 times.  On UNIX, it's a syscall.
+ This function reports resource usage totals for processes specified by
+ @var{processes}, storing the information in @code{*@var{rusage}}.
+ 
+@@ -129,9 +131,11 @@
+ @code{vtimes} and its @code{vtimes} data structure are declared in
+ @file{sys/vtimes.h}.
+ @pindex sys/vtimes.h
+-@comment vtimes.h
+ 
+-@deftypefun int vtimes (struct vtimes @var{current}, struct vtimes @var{child})
++@comment sys/vtimes.h
++@deftypefun int vtimes (struct vtimes *@var{current}, struct vtimes *@var{child})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Calls getrusage twice.
+ 
+ @code{vtimes} reports resource usage totals for a process.
+ 
+@@ -223,6 +227,8 @@
+ @comment sys/resource.h
+ @comment BSD
+ @deftypefun int getrlimit (int @var{resource}, struct rlimit *@var{rlp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on most systems.
+ Read the current and maximum limits for the resource @var{resource}
+ and store them in @code{*@var{rlp}}.
+ 
+@@ -237,6 +243,8 @@
+ @comment sys/resource.h
+ @comment Unix98
+ @deftypefun int getrlimit64 (int @var{resource}, struct rlimit64 *@var{rlp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on most systems, wrapper to getrlimit otherwise.
+ This function is similar to @code{getrlimit} but its second parameter is
+ a pointer to a variable of type @code{struct rlimit64}, which allows it
+ to read values which wouldn't fit in the member of a @code{struct
+@@ -250,6 +258,8 @@
+ @comment sys/resource.h
+ @comment BSD
+ @deftypefun int setrlimit (int @var{resource}, const struct rlimit *@var{rlp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on most systems; lock-taking critical section on HURD.
+ Store the current and maximum limits for the resource @var{resource}
+ in @code{*@var{rlp}}.
+ 
+@@ -275,6 +285,8 @@
+ @comment sys/resource.h
+ @comment Unix98
+ @deftypefun int setrlimit64 (int @var{resource}, const struct rlimit64 *@var{rlp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Wrapper for setrlimit or direct syscall.
+ This function is similar to @code{setrlimit} but its second parameter is
+ a pointer to a variable of type @code{struct rlimit64} which allows it
+ to set values which wouldn't fit in the member of a @code{struct
+@@ -419,7 +431,7 @@
+ 
+ @comment sys/resource.h
+ @comment BSD
+-@deftypevr Constant int RLIM_INFINITY
++@deftypevr Constant rlim_t RLIM_INFINITY
+ This constant stands for a value of ``infinity'' when supplied as
+ the limit value in @code{setrlimit}.
+ @end deftypevr
+@@ -433,7 +445,10 @@
+ 
+ @comment ulimit.h
+ @comment BSD
+-@deftypefun int ulimit (int @var{cmd}, @dots{})
++@deftypefun {long int} ulimit (int @var{cmd}, @dots{})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Wrapper for getrlimit, setrlimit or
++@c sysconf(_SC_OPEN_MAX)->getdtablesize->getrlimit.
+ 
+ @code{ulimit} gets the current limit or sets the current and maximum
+ limit for a particular resource for the calling process according to the
+@@ -480,6 +495,10 @@
+ @comment sys/vlimit.h
+ @comment BSD
+ @deftypefun int vlimit (int @var{resource}, int @var{limit})
++@safety{@prelim{}@mtunsafe{@mtasurace{:setrlimit}}@asunsafe{}@acsafe{}}
++@c It calls getrlimit and modifies the rlim_cur field before calling
++@c setrlimit.  There's a window for a concurrent call to setrlimit that
++@c modifies e.g. rlim_max, which will be lost if running as super-user.
+ 
+ @code{vlimit} sets the current limit for a resource for a process.
+ 
+@@ -778,6 +797,8 @@
+ @comment sched.h
+ @comment POSIX
+ @deftypefun int sched_setscheduler (pid_t @var{pid}, int @var{policy}, const struct sched_param *@var{param})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, Linux only.
+ 
+ This function sets both the absolute priority and the scheduling policy
+ for a process.
+@@ -848,6 +869,8 @@
+ @comment sched.h
+ @comment POSIX
+ @deftypefun int sched_getscheduler (pid_t @var{pid})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, Linux only.
+ 
+ This function returns the scheduling policy assigned to the process with
+ Process ID (pid) @var{pid}, or the calling process if @var{pid} is zero.
+@@ -881,6 +904,8 @@
+ @comment sched.h
+ @comment POSIX
+ @deftypefun int sched_setparam (pid_t @var{pid}, const struct sched_param *@var{param})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, Linux only.
+ 
+ This function sets a process' absolute priority.
+ 
+@@ -893,7 +918,9 @@
+ 
+ @comment sched.h
+ @comment POSIX
+-@deftypefun int sched_getparam (pid_t @var{pid}, const struct sched_param *@var{param})
++@deftypefun int sched_getparam (pid_t @var{pid}, struct sched_param *@var{param})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, Linux only.
+ 
+ This function returns a process' absolute priority.
+ 
+@@ -922,7 +949,9 @@
+ 
+ @comment sched.h
+ @comment POSIX
+-@deftypefun int sched_get_priority_min (int *@var{policy})
++@deftypefun int sched_get_priority_min (int @var{policy})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, Linux only.
+ 
+ This function returns the lowest absolute priority value that is
+ allowable for a process with scheduling policy @var{policy}.
+@@ -942,7 +971,9 @@
+ 
+ @comment sched.h
+ @comment POSIX
+-@deftypefun int sched_get_priority_max (int *@var{policy})
++@deftypefun int sched_get_priority_max (int @var{policy})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, Linux only.
+ 
+ This function returns the highest absolute priority value that is
+ allowable for a process that with scheduling policy @var{policy}.
+@@ -963,6 +994,8 @@
+ @comment sched.h
+ @comment POSIX
+ @deftypefun int sched_rr_get_interval (pid_t @var{pid}, struct timespec *@var{interval})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, Linux only.
+ 
+ This function returns the length of the quantum (time slice) used with
+ the Round Robin scheduling policy, if it is used, for the process with
+@@ -987,6 +1020,8 @@
+ @comment sched.h
+ @comment POSIX
+ @deftypefun int sched_yield (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on Linux; alias to swtch on HURD.
+ 
+ This function voluntarily gives up the process' claim on the CPU.
+ 
+@@ -1045,7 +1080,7 @@
+ about.
+ 
+ But just to be clear about the scope of this scheduling: Any time a
+-process with a absolute priority of 0 and a process with an absolute
++process with an absolute priority of 0 and a process with an absolute
+ priority higher than 0 are ready to run at the same time, the one with
+ absolute priority 0 does not run.  If it's already running when the
+ higher priority ready-to-run process comes into existence, it stops
+@@ -1138,6 +1173,8 @@
+ @comment sys/resource.h
+ @comment BSD,POSIX
+ @deftypefun int getpriority (int @var{class}, int @var{id})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on UNIX.  On HURD, calls _hurd_priority_which_map.
+ Return the nice value of a set of processes; @var{class} and @var{id}
+ specify which ones (see below).  If the processes specified do not all
+ have the same nice value, this returns the lowest value that any of them
+@@ -1165,6 +1202,8 @@
+ @comment sys/resource.h
+ @comment BSD,POSIX
+ @deftypefun int setpriority (int @var{class}, int @var{id}, int @var{niceval})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on UNIX.  On HURD, calls _hurd_priority_which_map.
+ Set the nice value of a set of processes to @var{niceval}; @var{class}
+ and @var{id} specify which ones (see below).
+ 
+@@ -1222,6 +1261,11 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int nice (int @var{increment})
++@safety{@prelim{}@mtunsafe{@mtasurace{:setpriority}}@asunsafe{}@acsafe{}}
++@c Calls getpriority before and after setpriority, using the result of
++@c the first call to compute the argument for setpriority.  This creates
++@c a window for a concurrent setpriority (or nice) call to be lost or
++@c exhibit surprising behavior.
+ Increment the nice value of the calling process by @var{increment}.
+ The return value is the new nice value on success, and @code{-1} on
+ failure.  In the case of failure, @code{errno} will be set to the
+@@ -1319,6 +1363,10 @@
+ @comment sched.h
+ @comment GNU
+ @deftypefn Macro void CPU_ZERO (cpu_set_t *@var{set})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c CPU_ZERO ok
++@c  __CPU_ZERO_S ok
++@c   memset dup ok
+ This macro initializes the CPU set @var{set} to be the empty set.
+ 
+ This macro is a GNU extension and is defined in @file{sched.h}.
+@@ -1327,6 +1375,11 @@
+ @comment sched.h
+ @comment GNU
+ @deftypefn Macro void CPU_SET (int @var{cpu}, cpu_set_t *@var{set})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c CPU_SET ok
++@c  __CPU_SET_S ok
++@c   __CPUELT ok
++@c   __CPUMASK ok
+ This macro adds @var{cpu} to the CPU set @var{set}.
+ 
+ The @var{cpu} parameter must not have side effects since it is
+@@ -1338,6 +1391,11 @@
+ @comment sched.h
+ @comment GNU
+ @deftypefn Macro void CPU_CLR (int @var{cpu}, cpu_set_t *@var{set})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c CPU_CLR ok
++@c  __CPU_CLR_S ok
++@c   __CPUELT dup ok
++@c   __CPUMASK dup ok
+ This macro removes @var{cpu} from the CPU set @var{set}.
+ 
+ The @var{cpu} parameter must not have side effects since it is
+@@ -1349,6 +1407,11 @@
+ @comment sched.h
+ @comment GNU
+ @deftypefn Macro int CPU_ISSET (int @var{cpu}, const cpu_set_t *@var{set})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c CPU_ISSET ok
++@c  __CPU_ISSET_S ok
++@c   __CPUELT dup ok
++@c   __CPUMASK dup ok
+ This macro returns a nonzero value (true) if @var{cpu} is a member
+ of the CPU set @var{set}, and zero (false) otherwise.
+ 
+@@ -1365,6 +1428,9 @@
+ @comment sched.h
+ @comment GNU
+ @deftypefun int sched_getaffinity (pid_t @var{pid}, size_t @var{cpusetsize}, cpu_set_t *@var{cpuset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Wrapped syscall to zero out past the kernel cpu set size; Linux
++@c only.
+ 
+ This functions stores the CPU affinity mask for the process or thread
+ with the ID @var{pid} in the @var{cpusetsize} bytes long bitmap
+@@ -1393,6 +1459,9 @@
+ @comment sched.h
+ @comment GNU
+ @deftypefun int sched_setaffinity (pid_t @var{pid}, size_t @var{cpusetsize}, const cpu_set_t *@var{cpuset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Wrapped syscall to detect attempts to set bits past the kernel cpu
++@c set size; Linux only.
+ 
+ This function installs the @var{cpusetsize} bytes long affinity mask
+ pointed to by @var{cpuset} for the process or thread with the ID @var{pid}.
+@@ -1516,6 +1585,9 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int getpagesize (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Obtained from the aux vec at program startup time.  GNU/Linux/m68k is
++@c the exception, with the possibility of a syscall.
+ The @code{getpagesize} function returns the page size of the process.
+ This value is fixed for the runtime of the process but can vary in
+ different runs of the application.
+@@ -1559,6 +1631,8 @@
+ @comment sys/sysinfo.h
+ @comment GNU
+ @deftypefun {long int} get_phys_pages (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c This fopens a /proc file and scans it for the requested information.
+ The @code{get_phys_pages} function returns the total number of pages of
+ physical the system has.  To get the amount of memory this number has to
+ be multiplied by the page size.
+@@ -1569,7 +1643,8 @@
+ @comment sys/sysinfo.h
+ @comment GNU
+ @deftypefun {long int} get_avphys_pages (void)
+-The @code{get_phys_pages} function returns the number of available pages of
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++The @code{get_avphys_pages} function returns the number of available pages of
+ physical the system has.  To get the amount of memory this number has to
+ be multiplied by the page size.
+ 
+@@ -1614,6 +1689,9 @@
+ @comment sys/sysinfo.h
+ @comment GNU
+ @deftypefun int get_nprocs_conf (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c This function reads from from /sys using dir streams (single user, so
++@c no @mtasurace issue), and on some arches, from /proc using streams.
+ The @code{get_nprocs_conf} function returns the number of processors the
+ operating system configured.
+ 
+@@ -1623,6 +1701,8 @@
+ @comment sys/sysinfo.h
+ @comment GNU
+ @deftypefun int get_nprocs (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
++@c This function reads from /proc using file descriptor I/O.
+ The @code{get_nprocs} function returns the number of available processors.
+ 
+ This function is a GNU extension.
+@@ -1638,8 +1718,12 @@
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun int getloadavg (double @var{loadavg}[], int @var{nelem})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
++@c Calls host_info on HURD; on Linux, opens /proc/loadavg, reads from
++@c it, closes it, without cancellation point, and calls strtod_l with
++@c the C locale to convert the strings to doubles.
+ This function gets the 1, 5 and 15 minute load averages of the
+-system. The values are placed in @var{loadavg}.  @code{getloadavg} will
++system.  The values are placed in @var{loadavg}.  @code{getloadavg} will
+ place at most @var{nelem} elements into the array but never more than
+ three elements.  The return value is the number of elements written to
+ @var{loadavg}, or -1 on error.
+diff -urN glibc-2.17-c758a686/manual/search.texi glibc/manual/search.texi
+--- glibc-2.17-c758a686/manual/search.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/search.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -71,7 +71,8 @@
+ 
+ @comment search.h
+ @comment SVID
+-@deftypefun {void *} lfind (const void *@var{key}, void *@var{base}, size_t *@var{nmemb}, size_t @var{size}, comparison_fn_t @var{compar})
++@deftypefun {void *} lfind (const void *@var{key}, const void *@var{base}, size_t *@var{nmemb}, size_t @var{size}, comparison_fn_t @var{compar})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{lfind} function searches in the array with @code{*@var{nmemb}}
+ elements of @var{size} bytes pointed to by @var{base} for an element
+ which matches the one pointed to by @var{key}.  The function pointed to
+@@ -90,6 +91,21 @@
+ @comment search.h
+ @comment SVID
+ @deftypefun {void *} lsearch (const void *@var{key}, void *@var{base}, size_t *@var{nmemb}, size_t @var{size}, comparison_fn_t @var{compar})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c A signal handler that interrupted an insertion and performed an
++@c insertion itself would leave the array in a corrupt state (e.g. one
++@c new element initialized twice, with parts of both initializations
++@c prevailing, and another uninitialized element), but this is just a
++@c special case of races on user-controlled objects, that have to be
++@c avoided by users.
++
++@c In case of cancellation, we know the array won't be left in a corrupt
++@c state; the new element is initialized before the element count is
++@c incremented, and the compiler can't reorder these operations because
++@c it can't know that they don't alias.  So, we'll either cancel after
++@c the increment and the initialization are both complete, or the
++@c increment won't have taken place, and so how far the initialization
++@c got doesn't matter.
+ The @code{lsearch} function is similar to the @code{lfind} function.  It
+ searches the given array for an element and returns it if found.  The
+ difference is that if no matching element is found the @code{lsearch}
+@@ -113,6 +129,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun {void *} bsearch (const void *@var{key}, const void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{bsearch} function searches the sorted array @var{array} for an object
+ that is equivalent to @var{key}.  The array contains @var{count} elements,
+ each of which is of size @var{size} bytes.
+@@ -146,6 +163,7 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun void qsort (void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare})
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
+ The @var{qsort} function sorts the array @var{array}.  The array contains
+ @var{count} elements, each of which is of size @var{size}.
+ 
+@@ -256,6 +274,9 @@
+ @comment search.h
+ @comment SVID
+ @deftypefun int hcreate (size_t @var{nel})
++@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c hcreate @mtasurace:hsearch @ascuheap @acucorrupt @acsmem
++@c  hcreate_r dup @mtsrace:htab @ascuheap @acucorrupt @acsmem
+ The @code{hcreate} function creates a hashing table which can contain at
+ least @var{nel} elements.  There is no possibility to grow this table so
+ it is necessary to choose the value for @var{nel} wisely.  The method
+@@ -270,7 +291,7 @@
+ The weakest aspect of this function is that there can be at most one
+ hashing table used through the whole program.  The table is allocated
+ in local memory out of control of the programmer.  As an extension @theglibc{}
+-provides an additional set of functions with an reentrant
++provides an additional set of functions with a reentrant
+ interface which provide a similar interface but which allow to keep
+ arbitrarily many hashing tables.
+ 
+@@ -285,6 +306,9 @@
+ @comment search.h
+ @comment SVID
+ @deftypefun void hdestroy (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c hdestroy @mtasurace:hsearch @ascuheap @acucorrupt @acsmem
++@c  hdestroy_r dup @mtsrace:htab @ascuheap @acucorrupt @acsmem
+ The @code{hdestroy} function can be used to free all the resources
+ allocated in a previous call of @code{hcreate}.  After a call to this
+ function it is again possible to call @code{hcreate} and allocate a new
+@@ -328,6 +352,9 @@
+ @comment search.h
+ @comment SVID
+ @deftypefun {ENTRY *} hsearch (ENTRY @var{item}, ACTION @var{action})
++@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{}@acunsafe{@acucorrupt{/action==ENTER}}}
++@c hsearch @mtasurace:hsearch @acucorrupt/action==ENTER
++@c  hsearch_r dup @mtsrace:htab @acucorrupt/action==ENTER
+ To search in a hashing table created using @code{hcreate} the
+ @code{hsearch} function must be used.  This function can perform simple
+ search for an element (if @var{action} has the @code{FIND}) or it can
+@@ -358,6 +385,24 @@
+ @comment search.h
+ @comment GNU
+ @deftypefun int hcreate_r (size_t @var{nel}, struct hsearch_data *@var{htab})
++@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c Unlike the lsearch array, the htab is (at least in part) opaque, so
++@c let's make it absolutely clear that ensuring exclusive access is a
++@c caller responsibility.
++
++@c Cancellation is unlikely to leave the htab in a corrupt state: the
++@c last field to be initialized is the one that tells whether the entire
++@c data structure was initialized, and there's a function call (calloc)
++@c in between that will often ensure all other fields are written before
++@c the table.  However, should this call be inlined (say with LTO), this
++@c assumption may not hold.  The calloc call doesn't cross our library
++@c interface barrier, so let's consider this could happen and mark this
++@c with @acucorrupt.  It's no safety loss, since we already have
++@c @ascuheap anyway...
++
++@c hcreate_r @mtsrace:htab @ascuheap @acucorrupt @acsmem
++@c  isprime ok
++@c  calloc dup @ascuheap @acsmem
+ The @code{hcreate_r} function initializes the object pointed to by
+ @var{htab} to contain a hashing table with at least @var{nel} elements.
+ So this function is equivalent to the @code{hcreate} function except
+@@ -376,6 +421,16 @@
+ @comment search.h
+ @comment GNU
+ @deftypefun void hdestroy_r (struct hsearch_data *@var{htab})
++@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c The table is released while the table pointer still points to it.
++@c Async cancellation is thus unsafe, but it already was because we call
++@c free().  Using the table in a handler while it's being released would
++@c also be dangerous, but calling free() already makes it unsafe, and
++@c the requirement on the caller to ensure exclusive access already
++@c guarantees this doesn't happen, so we don't get @asucorrupt.
++
++@c hdestroy_r @mtsrace:htab @ascuheap @acucorrupt @acsmem
++@c  free dup @ascuheap @acsmem
+ The @code{hdestroy_r} function frees all resources allocated by the
+ @code{hcreate_r} function for this very same object @var{htab}.  As for
+ @code{hdestroy} it is the programs responsibility to free the strings
+@@ -385,6 +440,13 @@
+ @comment search.h
+ @comment GNU
+ @deftypefun int hsearch_r (ENTRY @var{item}, ACTION @var{action}, ENTRY **@var{retval}, struct hsearch_data *@var{htab})
++@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@assafe{}@acunsafe{@acucorrupt{/action==ENTER}}}
++@c Callers have to ensure mutual exclusion; insertion, if cancelled,
++@c leaves the table in a corrupt state.
++
++@c hsearch_r @mtsrace:htab @acucorrupt/action==ENTER
++@c  strlen dup ok
++@c  strcmp dup ok
+ The @code{hsearch_r} function is equivalent to @code{hsearch}.  The
+ meaning of the first two arguments is identical.  But instead of
+ operating on a single global hashing table the function works on the
+@@ -401,7 +463,7 @@
+ 
+ @table @code
+ @item ENOMEM
+-The table is filled and @code{hsearch_r} was called with an so far
++The table is filled and @code{hsearch_r} was called with a so far
+ unknown key and @var{action} set to @code{ENTER}.
+ @item ESRCH
+ The @var{action} parameter is @code{FIND} and no corresponding element
+@@ -436,6 +498,12 @@
+ @comment search.h
+ @comment SVID
+ @deftypefun {void *} tsearch (const void *@var{key}, void **@var{rootp}, comparison_fn_t @var{compar})
++@safety{@prelim{}@mtsafe{@mtsrace{:rootp}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c The tree is not modified in a thread-safe manner, and rotations may
++@c leave the tree in an inconsistent state that could be observed in an
++@c asynchronous signal handler (except for the caller-synchronization
++@c requirement) or after asynchronous cancellation of the thread
++@c performing the rotation or the insertion.
+ The @code{tsearch} function searches in the tree pointed to by
+ @code{*@var{rootp}} for an element matching @var{key}.  The function
+ pointed to by @var{compar} is used to determine whether two elements
+@@ -465,6 +533,7 @@
+ @comment search.h
+ @comment SVID
+ @deftypefun {void *} tfind (const void *@var{key}, void *const *@var{rootp}, comparison_fn_t @var{compar})
++@safety{@prelim{}@mtsafe{@mtsrace{:rootp}}@assafe{}@acsafe{}}
+ The @code{tfind} function is similar to the @code{tsearch} function.  It
+ locates an element matching the one pointed to by @var{key} and returns
+ a pointer to this element.  But if no matching element is available no
+@@ -479,6 +548,7 @@
+ @comment search.h
+ @comment SVID
+ @deftypefun {void *} tdelete (const void *@var{key}, void **@var{rootp}, comparison_fn_t @var{compar})
++@safety{@prelim{}@mtsafe{@mtsrace{:rootp}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+ To remove a specific element matching @var{key} from the tree
+ @code{tdelete} can be used.  It locates the matching element using the
+ same method as @code{tfind}.  The corresponding element is then removed
+@@ -492,6 +562,7 @@
+ @comment search.h
+ @comment GNU
+ @deftypefun void tdestroy (void *@var{vroot}, __free_fn_t @var{freefct})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ If the complete search tree has to be removed one can use
+ @code{tdestroy}.  It frees all resources allocated by the @code{tsearch}
+ function to generate the tree pointed to by @var{vroot}.
+@@ -546,6 +617,7 @@
+ @comment search.h
+ @comment SVID
+ @deftypefun void twalk (const void *@var{root}, __action_fn_t @var{action})
++@safety{@prelim{}@mtsafe{@mtsrace{:root}}@assafe{}@acsafe{}}
+ For each node in the tree with a node pointed to by @var{root}, the
+ @code{twalk} function calls the function provided by the parameter
+ @var{action}.  For leaf nodes the function is called exactly once with
+diff -urN glibc-2.17-c758a686/manual/setjmp.texi glibc/manual/setjmp.texi
+--- glibc-2.17-c758a686/manual/setjmp.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/setjmp.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -107,6 +107,10 @@
+ @comment setjmp.h
+ @comment ISO
+ @deftypefn Macro int setjmp (jmp_buf @var{state})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c _setjmp ok
++@c  __sigsetjmp(!savemask) ok
++@c   __sigjmp_save(!savemask) ok, does not call sigprocmask
+ When called normally, @code{setjmp} stores information about the
+ execution state of the program in @var{state} and returns zero.  If
+ @code{longjmp} is later used to perform a non-local exit to this
+@@ -116,6 +120,20 @@
+ @comment setjmp.h
+ @comment ISO
+ @deftypefun void longjmp (jmp_buf @var{state}, int @var{value})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}}
++@c __libc_siglongjmp @ascuplugin @asucorrupt @asulock/hurd @acucorrupt @aculock/hurd
++@c  _longjmp_unwind @ascuplugin @asucorrupt @acucorrupt
++@c   __pthread_cleanup_upto @ascuplugin @asucorrupt @acucorrupt
++@c     plugins may be unsafe themselves, but even if they weren't, this
++@c     function isn't robust WRT async signals and cancellation:
++@c     cleanups aren't taken off the stack right away, only after all
++@c     cleanups have been run.  This means that async-cancelling
++@c     longjmp, or interrupting longjmp with an async signal handler
++@c     that calls longjmp may run the same cleanups multiple times.
++@c    _JMPBUF_UNWINDS_ADJ ok
++@c    *cleanup_buf->__routine @ascuplugin
++@c  sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd
++@c  __longjmp ok
+ This function restores current execution to the state saved in
+ @var{state}, and continues execution from the call to @code{setjmp} that
+ established that return point.  Returning from @code{setjmp} by means of
+@@ -141,7 +159,7 @@
+ statement (such as @samp{if}, @samp{switch}, or @samp{while}).
+ 
+ @item
+-As one operand of a equality or comparison operator that appears as the
++As one operand of an equality or comparison operator that appears as the
+ test expression of a selection or iteration statement.  The other
+ operand must be an integer constant expression.
+ 
+@@ -199,6 +217,11 @@
+ @comment setjmp.h
+ @comment POSIX.1
+ @deftypefun int sigsetjmp (sigjmp_buf @var{state}, int @var{savesigs})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c sigsetjmp @asulock/hurd @aculock/hurd
++@c  __sigsetjmp(savemask) @asulock/hurd @aculock/hurd
++@c   __sigjmp_save(savemask) @asulock/hurd @aculock/hurd
++@c    sigprocmask(SIG_BLOCK probe) dup @asulock/hurd @aculock/hurd
+ This is similar to @code{setjmp}.  If @var{savesigs} is nonzero, the set
+ of blocked signals is saved in @var{state} and will be restored if a
+ @code{siglongjmp} is later performed with this @var{state}.
+@@ -207,6 +230,8 @@
+ @comment setjmp.h
+ @comment POSIX.1
+ @deftypefun void siglongjmp (sigjmp_buf @var{state}, int @var{value})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}}
++@c Alias to longjmp.
+ This is similar to @code{longjmp} except for the type of its @var{state}
+ argument.  If the @code{sigsetjmp} call that set this @var{state} used a
+ nonzero @var{savesigs} flag, @code{siglongjmp} also restores the set of
+@@ -237,7 +262,7 @@
+ @comment SVID
+ @deftp {Data Type} ucontext_t
+ 
+-The @code{ucontext_t} type is defined as a structure with as least the
++The @code{ucontext_t} type is defined as a structure with at least the
+ following elements:
+ 
+ @table @code
+@@ -267,6 +292,10 @@
+ @comment ucontext.h
+ @comment SVID
+ @deftypefun int getcontext (ucontext_t *@var{ucp})
++@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}}
++@c Linux-only implementations in assembly, including sigprocmask
++@c syscall.  A few cases call the sigprocmask function, but that's safe
++@c too.  The ppc case is implemented in terms of a swapcontext syscall.
+ The @code{getcontext} function initializes the variable pointed to by
+ @var{ucp} with the context of the calling thread.  The context contains
+ the content of the registers, the signal mask, and the current stack.
+@@ -278,25 +307,26 @@
+ @end deftypefun
+ 
+ The @code{getcontext} function is similar to @code{setjmp} but it does
+-not provide an indication of whether the function returns for the first
+-time or whether the initialized context was used and the execution is
+-resumed at just that point.  If this is necessary the user has to take
+-determine this herself.  This must be done carefully since the context
+-contains registers which might contain register variables.  This is a
+-good situation to define variables with @code{volatile}.
++not provide an indication of whether @code{getcontext} is returning for
++the first time or whether an initialized context has just been restored.
++If this is necessary the user has to determine this herself.  This must
++be done carefully since the context contains registers which might contain
++register variables.  This is a good situation to define variables with
++@code{volatile}.
+ 
+ Once the context variable is initialized it can be used as is or it can
+-be modified.  The latter is normally done to implement co-routines or
+-similar constructs.  The @code{makecontext} function is what has to be
+-used to do that.
++be modified using the @code{makecontext} function.  The latter is normally
++done when implementing co-routines or similar constructs.
+ 
+ @comment ucontext.h
+ @comment SVID
+ @deftypefun void makecontext (ucontext_t *@var{ucp}, void (*@var{func}) (void), int @var{argc}, @dots{})
++@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}}
++@c Linux-only implementations mostly in assembly, nothing unsafe.
+ 
+-The @var{ucp} parameter passed to the @code{makecontext} shall be
++The @var{ucp} parameter passed to @code{makecontext} shall be
+ initialized by a call to @code{getcontext}.  The context will be
+-modified to in a way so that if the context is resumed it will start by
++modified in a way such that if the context is resumed it will start by
+ calling the function @code{func} which gets @var{argc} integer arguments
+ passed.  The integer arguments which are to be passed should follow the
+ @var{argc} parameter in the call to @code{makecontext}.
+@@ -316,7 +346,7 @@
+ While allocating the memory for the stack one has to be careful.  Most
+ modern processors keep track of whether a certain memory region is
+ allowed to contain code which is executed or not.  Data segments and
+-heap memory is normally not tagged to allow this.  The result is that
++heap memory are normally not tagged to allow this.  The result is that
+ programs would fail.  Examples for such code include the calling
+ sequences the GNU C compiler generates for calls to nested functions.
+ Safe ways to allocate stacks correctly include using memory on the
+@@ -332,13 +362,22 @@
+ allocated for the stack and the size of the memory region is stored in
+ @code{ss_size}.  There are implements out there which require
+ @code{ss_sp} to be set to the value the stack pointer will have (which
+-can depending on the direction the stack grows be different).  This
++can, depending on the direction the stack grows, be different).  This
+ difference makes the @code{makecontext} function hard to use and it
+ requires detection of the platform at compile time.
+ 
+ @comment ucontext.h
+ @comment SVID
+ @deftypefun int setcontext (const ucontext_t *@var{ucp})
++@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
++@c Linux-only implementations mostly in assembly.  Some ports use
++@c sigreturn or swapcontext syscalls; others restore the signal mask
++@c first and then proceed restore other registers in userland, which
++@c leaves a window for cancellation or async signals with misaligned or
++@c otherwise corrupt stack.  ??? Switching to a different stack, or even
++@c to an earlier state on the same stack, may conflict with pthread
++@c cleanups.  This is not quite MT-Unsafe, it's a different kind of
++@c safety issue.
+ 
+ The @code{setcontext} function restores the context described by
+ @var{ucp}.  The context is not modified and can be reused as often as
+@@ -357,6 +396,9 @@
+ terminates normally with an exit status value of @code{EXIT_SUCCESS}
+ (@pxref{Program Termination}).
+ 
++If the context was created by a call to a signal handler or from any
++other source then the behaviour of @code{setcontext} is unspecified.
++
+ Since the context contains information about the stack no two threads
+ should use the same context at the same time.  The result in most cases
+ would be disastrous.
+@@ -372,6 +414,10 @@
+ @comment ucontext.h
+ @comment SVID
+ @deftypefun int swapcontext (ucontext_t *restrict @var{oucp}, const ucontext_t *restrict @var{ucp})
++@safety{@prelim{}@mtsafe{@mtsrace{:oucp} @mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
++@c Linux-only implementations mostly in assembly.  Some ports call or
++@c inline getcontext and/or setcontext, adjusting the saved context in
++@c between, so we inherit the potential issues of both.
+ 
+ The @code{swapcontext} function is similar to @code{setcontext} but
+ instead of just replacing the current context the latter is first saved
+@@ -385,15 +431,15 @@
+ If @code{swapcontext} succeeds the function does not return unless the
+ context @var{oucp} is used without prior modification by
+ @code{makecontext}.  The return value in this case is @code{0}.  If the
+-function fails it returns @code{-1} and set @var{errno} accordingly.
++function fails it returns @code{-1} and sets @var{errno} accordingly.
+ @end deftypefun
+ 
+ @heading Example for SVID Context Handling
+ 
+ The easiest way to use the context handling functions is as a
+ replacement for @code{setjmp} and @code{longjmp}.  The context contains
+-on most platforms more information which might lead to less surprises
+-but this also means using these functions is more expensive (beside
++on most platforms more information which may lead to fewer surprises
++but this also means using these functions is more expensive (besides
+ being less portable).
+ 
+ @smallexample
+@@ -440,11 +486,11 @@
+ This an example how the context functions can be used to implement
+ co-routines or cooperative multi-threading.  All that has to be done is
+ to call every once in a while @code{swapcontext} to continue running a
+-different context.  It is not allowed to do the context switching from
+-the signal handler directly since neither @code{setcontext} nor
+-@code{swapcontext} are functions which can be called from a signal
+-handler.  But setting a variable in the signal handler and checking it
+-in the body of the functions which are executed.  Since
+-@code{swapcontext} is saving the current context it is possible to have
+-multiple different scheduling points in the code.  Execution will always
+-resume where it was left.
++different context.  It is not recommended to do the context switching from
++the signal handler directly since leaving the signal handler via
++@code{setcontext} if the signal was delivered during code that was not
++asynchronous signal safe could lead to problems. Setting a variable in
++the signal handler and checking it in the body of the functions which
++are executed is a safer approach.  Since @code{swapcontext} is saving the
++current context it is possible to have multiple different scheduling points
++in the code.  Execution will always resume where it was left.
+diff -urN glibc-2.17-c758a686/manual/signal.texi glibc/manual/signal.texi
+--- glibc-2.17-c758a686/manual/signal.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/signal.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -889,6 +889,20 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {char *} strsignal (int @var{signum})
++@safety{@prelim{}@mtunsafe{@mtasurace{:strsignal} @mtslocale{}}@asunsafe{@asuinit{} @ascuintl{} @asucorrupt{} @ascuheap{}}@acunsafe{@acuinit{} @acucorrupt{} @acsmem{}}}
++@c strsignal @mtasurace:strsignal @mtslocale @asuinit @ascuintl @asucorrupt @ascuheap @acucorrupt @acsmem
++@c   uses a static buffer if tsd key creation fails
++@c  [once] init
++@c   libc_key_create ok
++@c    pthread_key_create dup ok
++@c  getbuffer @asucorrupt @ascuheap @acsmem
++@c   libc_getspecific ok
++@c    pthread_getspecific dup ok
++@c   malloc dup @ascuheap @acsmem
++@c   libc_setspecific @asucorrupt @ascuheap @acucorrupt @acsmem
++@c    pthread_setspecific dup @asucorrupt @ascuheap @acucorrupt @acsmem
++@c  snprintf dup @mtslocale @ascuheap @acsmem
++@c  _ @ascuintl
+ This function returns a pointer to a statically-allocated string
+ containing a message describing the signal @var{signum}.  You
+ should not modify the contents of this string; and, since it can be
+@@ -903,6 +917,12 @@
+ @comment signal.h
+ @comment BSD
+ @deftypefun void psignal (int @var{signum}, const char *@var{message})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuintl{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}}
++@c psignal @mtslocale @asucorrupt @ascuintl @ascuheap @aculock @acucorrupt @acsmem
++@c  _ @ascuintl
++@c  fxprintf @asucorrupt @aculock @acucorrupt
++@c  asprintf @mtslocale @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
+ This function prints a message describing the signal @var{signum} to the
+ standard error output stream @code{stderr}; see @ref{Standard Streams}.
+ 
+@@ -972,6 +992,12 @@
+ @comment signal.h
+ @comment ISO
+ @deftypefun sighandler_t signal (int @var{signum}, sighandler_t @var{action})
++@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
++@c signal ok
++@c  sigemptyset dup ok
++@c  sigaddset dup ok
++@c  sigismember dup ok
++@c  sigaction dup ok
+ The @code{signal} function establishes @var{action} as the action for
+ the signal @var{signum}.
+ 
+@@ -1094,6 +1120,10 @@
+ @comment signal.h
+ @comment GNU
+ @deftypefun sighandler_t sysv_signal (int @var{signum}, sighandler_t @var{action})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c sysv_signal ok
++@c  sigemptyset dup ok
++@c  sigaction dup ok
+ The @code{sysv_signal} implements the behavior of the standard
+ @code{signal} function as found on SVID systems.  The difference to BSD
+ systems is that the handler is deinstalled after a delivery of a signal.
+@@ -1106,6 +1136,8 @@
+ @comment signal.h
+ @comment SVID
+ @deftypefun sighandler_t ssignal (int @var{signum}, sighandler_t @var{action})
++@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
++@c Aliases signal and bsd_signal.
+ The @code{ssignal} function does the same thing as @code{signal}; it is
+ provided only for compatibility with SVID.
+ @end deftypefun
+@@ -1172,6 +1204,7 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigaction (int @var{signum}, const struct sigaction *restrict @var{action}, struct sigaction *restrict @var{old-action})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @var{action} argument is used to set up a new action for the signal
+ @var{signum}, while the @var{old-action} argument is used to return
+ information about the action previously associated with this symbol.
+@@ -2168,6 +2194,14 @@
+ @comment signal.h
+ @comment ISO
+ @deftypefun int raise (int @var{signum})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c raise ok
++@c [posix]
++@c  getpid dup ok
++@c  kill dup ok
++@c [linux]
++@c  syscall(gettid) ok
++@c  syscall(tgkill) ok
+ The @code{raise} function sends the signal @var{signum} to the calling
+ process.  It returns zero if successful and a nonzero value if it fails.
+ About the only reason for failure would be if the value of @var{signum}
+@@ -2177,6 +2211,8 @@
+ @comment signal.h
+ @comment SVID
+ @deftypefun int gsignal (int @var{signum})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Aliases raise.
+ The @code{gsignal} function does the same thing as @code{raise}; it is
+ provided only for compatibility with SVID.
+ @end deftypefun
+@@ -2269,6 +2305,11 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int kill (pid_t @var{pid}, int @var{signum})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c The hurd implementation is not a critical section, so it's not
++@c immediately obvious that, in case of cancellation, it won't leak
++@c ports or the memory allocated by proc_getpgrppids when pid <= 0.
++@c Since none of these make it AC-Unsafe, I'm leaving them out.
+ The @code{kill} function sends the signal @var{signum} to the process
+ or process group specified by @var{pid}.  Besides the signals listed in
+ @ref{Standard Signals}, @var{signum} can also have a value of zero to
+@@ -2325,6 +2366,8 @@
+ @comment signal.h
+ @comment BSD
+ @deftypefun int killpg (int @var{pgid}, int @var{signum})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Calls kill with -pgid.
+ This is similar to @code{kill}, but sends signal @var{signum} to the
+ process group @var{pgid}.  This function is provided for compatibility
+ with BSD; using @code{kill} to do this is more portable.
+@@ -2497,6 +2540,8 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigemptyset (sigset_t *@var{set})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Just memsets all of set to zero.
+ This function initializes the signal set @var{set} to exclude all of the
+ defined signals.  It always returns @code{0}.
+ @end deftypefun
+@@ -2504,6 +2549,7 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigfillset (sigset_t *@var{set})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function initializes the signal set @var{set} to include
+ all of the defined signals.  Again, the return value is @code{0}.
+ @end deftypefun
+@@ -2511,6 +2557,7 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigaddset (sigset_t *@var{set}, int @var{signum})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function adds the signal @var{signum} to the signal set @var{set}.
+ All @code{sigaddset} does is modify @var{set}; it does not block or
+ unblock any signals.
+@@ -2527,6 +2574,7 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigdelset (sigset_t *@var{set}, int @var{signum})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function removes the signal @var{signum} from the signal set
+ @var{set}.  All @code{sigdelset} does is modify @var{set}; it does not
+ block or unblock any signals.  The return value and error conditions are
+@@ -2538,6 +2586,7 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigismember (const sigset_t *@var{set}, int @var{signum})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{sigismember} function tests whether the signal @var{signum} is
+ a member of the signal set @var{set}.  It returns @code{1} if the signal
+ is in the set, @code{0} if not, and @code{-1} if there is an error.
+@@ -2566,7 +2615,7 @@
+ 
+ Note that you must not use @code{sigprocmask} in multi-threaded processes,
+ because each thread has its own signal mask and there is no single process
+-signal mask. According to POSIX, the behavior of @code{sigprocmask} in a
++signal mask.  According to POSIX, the behavior of @code{sigprocmask} in a
+ multi-threaded process is ``unspecified''.
+ Instead, use @code{pthread_sigmask}.
+ @ifset linuxthreads
+@@ -2576,6 +2625,10 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigprocmask (int @var{how}, const sigset_t *restrict @var{set}, sigset_t *restrict @var{oldset})
++@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/bsd(SIG_UNBLOCK)}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c This takes the hurd_self_sigstate-returned object's lock on HURD.  On
++@c BSD, SIG_UNBLOCK is emulated with two sigblock calls, which
++@c introduces a race window.
+ The @code{sigprocmask} function is used to examine or change the calling
+ process's signal mask.  The @var{how} argument determines how the signal
+ mask is changed, and must be one of the following values:
+@@ -2759,6 +2812,10 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigpending (sigset_t *@var{set})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c Direct rt_sigpending syscall on most systems.  On hurd, calls
++@c hurd_self_sigstate, it copies the sigstate's pending while holding
++@c its lock.
+ The @code{sigpending} function stores information about pending signals
+ in @var{set}.  If there is a pending signal that is blocked from
+ delivery, then that signal is a member of the returned set.  (You can
+@@ -2921,7 +2978,18 @@
+ 
+ @comment unistd.h
+ @comment POSIX.1
+-@deftypefun int pause ()
++@deftypefun int pause (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c  The signal mask read by sigprocmask may be overridden by another
++@c  thread or by a signal handler before we call sigsuspend.  Is this a
++@c  safety issue?  Probably not.
++@c pause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
++@c [ports/linux/generic]
++@c  syscall_pause ok
++@c [posix]
++@c  sigemptyset dup ok
++@c  sigprocmask(SIG_BLOCK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)]
++@c  sigsuspend dup @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
+ The @code{pause} function suspends program execution until a signal
+ arrives whose action is either to execute a handler function, or to
+ terminate the process.
+@@ -3017,6 +3085,18 @@
+ @comment signal.h
+ @comment POSIX.1
+ @deftypefun int sigsuspend (const sigset_t *@var{set})
++@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c sigsuspend @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
++@c [posix] @mtasurace:sigprocmask/!bsd!linux
++@c   saving and restoring the procmask is racy
++@c  sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)]
++@c  pause @asulock/hurd @aculock/hurd
++@c [bsd]
++@c  sigismember dup ok
++@c  sigmask dup ok
++@c  sigpause dup ok [no @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd]
++@c [linux]
++@c  do_sigsuspend ok
+ This function replaces the process's signal mask with @var{set} and then
+ suspends the process until a signal is delivered whose action is either
+ to terminate the process or invoke a signal handling function.  In other
+@@ -3150,6 +3230,9 @@
+ @comment signal.h
+ @comment XPG
+ @deftypefun int sigaltstack (const stack_t *restrict @var{stack}, stack_t *restrict @var{oldstack})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c Syscall on Linux and BSD; the HURD implementation takes a lock on
++@c the hurd_self_sigstate-returned struct.
+ The @code{sigaltstack} function specifies an alternate stack for use
+ during signal handling.  When a signal is received by the process and
+ its action indicates that the signal stack is used, the system arranges
+@@ -3195,7 +3278,9 @@
+ 
+ @comment signal.h
+ @comment BSD
+-@deftypefun int sigstack (const struct sigstack *@var{stack}, struct sigstack *@var{oldstack})
++@deftypefun int sigstack (struct sigstack *@var{stack}, struct sigstack *@var{oldstack})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c Lossy and dangerous (no size limit) wrapper for sigaltstack.
+ The @code{sigstack} function specifies an alternate stack for use during
+ signal handling.  When a signal is received by the process and its
+ action indicates that the signal stack is used, the system arranges a
+@@ -3301,6 +3386,13 @@
+ @comment signal.h
+ @comment BSD
+ @deftypefun int sigvec (int @var{signum}, const struct sigvec *@var{action}, struct sigvec *@var{old-action})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This is mostly a safe wrapper for sigaction.  The exception are
++@c systems that lack SA_RESETHAND, in which a signal handler wrapper is
++@c used that calls sigaction to reset the handler before calling the
++@c user-supplied handler; it's unlikely that this emulation is used
++@c anywhere, for user-supplied flags and mask don't seem to be used
++@c the way one would expect.
+ This function is the equivalent of @code{sigaction} (@pxref{Advanced Signal
+ Handling}); it installs the action @var{action} for the signal @var{signum},
+ returning information about the previous action in effect for that signal
+@@ -3310,6 +3402,14 @@
+ @comment signal.h
+ @comment BSD
+ @deftypefun int siginterrupt (int @var{signum}, int @var{failflag})
++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtssigintr{}}}@asunsafe{}@acunsafe{@acucorrupt{}}}
++@c This calls sigaction twice, once to get the current sigaction for the
++@c specified signal, another to apply the flags change.  This could
++@c override the effects of a concurrent sigaction call.  It also
++@c modifies without any guards the global _sigintr variable, that
++@c bsd_signal reads from, and it may leave _sigintr modified without
++@c overriding the active handler if cancelled between the two
++@c operations.
+ This function specifies which approach to use when certain primitives
+ are interrupted by handling signal @var{signum}.  If @var{failflag} is
+ false, signal @var{signum} restarts primitives.  If @var{failflag} is
+@@ -3323,6 +3423,8 @@
+ @comment signal.h
+ @comment BSD
+ @deftypefn Macro int sigmask (int @var{signum})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c This just shifts signum.
+ This macro returns a signal mask that has the bit for signal @var{signum}
+ set.  You can bitwise-OR the results of several calls to @code{sigmask}
+ together to specify more than one signal.  For example,
+@@ -3339,6 +3441,11 @@
+ @comment signal.h
+ @comment BSD
+ @deftypefun int sigblock (int @var{mask})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c On most POSIX systems, this is a wrapper for sigprocmask(SIG_BLOCK).
++@c The exception are BSD systems other than 4.4, where it is a syscall.
++@c sigblock @asulock/hurd @aculock/hurd
++@c  sigprocmask(SIG_BLOCK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)]
+ This function is equivalent to @code{sigprocmask} (@pxref{Process Signal
+ Mask}) with a @var{how} argument of @code{SIG_BLOCK}: it adds the
+ signals specified by @var{mask} to the calling process's set of blocked
+@@ -3348,6 +3455,11 @@
+ @comment signal.h
+ @comment BSD
+ @deftypefun int sigsetmask (int @var{mask})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c On most POSIX systems, this is a wrapper for sigprocmask(SIG_SETMASK).
++@c The exception are BSD systems other than 4.4, where it is a syscall.
++@c sigsetmask @asulock/hurd @aculock/hurd
++@c  sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)]
+ This function equivalent to @code{sigprocmask} (@pxref{Process
+ Signal Mask}) with a @var{how} argument of @code{SIG_SETMASK}: it sets
+ the calling process's signal mask to @var{mask}.  The return value is
+@@ -3357,6 +3469,15 @@
+ @comment signal.h
+ @comment BSD
+ @deftypefun int sigpause (int @var{mask})
++@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
++@c sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
++@c [posix]
++@c  __sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
++@c   do_sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
++@c    sigprocmask(0) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)]
++@c    sigdelset dup ok
++@c    sigset_set_old_mask dup ok
++@c    sigsuspend dup @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
+ This function is the equivalent of @code{sigsuspend} (@pxref{Waiting
+ for a Signal}):  it sets the calling process's signal mask to @var{mask},
+ and waits for a signal to arrive.  On return the previous set of blocked
+diff -urN glibc-2.17-c758a686/manual/socket.texi glibc/manual/socket.texi
+--- glibc-2.17-c758a686/manual/socket.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/socket.texi	2014-09-12 16:10:06.046792714 -0400
+@@ -394,6 +394,8 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int bind (int @var{socket}, struct sockaddr *@var{addr}, socklen_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, except on Hurd.
+ The @code{bind} function assigns an address to the socket
+ @var{socket}.  The @var{addr} and @var{length} arguments specify the
+ address; the detailed format of the address depends on the namespace.
+@@ -442,6 +444,9 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int getsockname (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsmem{/hurd}}}
++@c Direct syscall, except on Hurd, where it seems like it might leak
++@c VM if cancelled.
+ The @code{getsockname} function returns information about the
+ address of the socket @var{socket} in the locations specified by the
+ @var{addr} and @var{length-ptr} arguments.  Note that the
+@@ -501,6 +506,14 @@
+ @comment net/if.h
+ @comment IPv6 basic API
+ @deftypefun {unsigned int} if_nametoindex (const char *@var{ifname})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c It opens a socket to use ioctl on the fd to get the index.
++@c opensock may call socket and access multiple times until it finds a
++@c socket family that works.  The Linux implementation has a potential
++@c concurrency issue WRT last_type and last_family not being updated
++@c atomically, but it is harmless; the generic implementation, OTOH,
++@c takes a lock, which makes all callers AS- and AC-Unsafe.
++@c  opensock @asulock @aculock @acsfd
+ This function yields the interface index corresponding to a particular
+ name.  If no interface exists with the name given, it returns 0.
+ @end deftypefun
+@@ -508,6 +521,9 @@
+ @comment net/if.h
+ @comment IPv6 basic API
+ @deftypefun {char *} if_indextoname (unsigned int @var{ifindex}, char *@var{ifname})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c It opens a socket with opensock to use ioctl on the fd to get the
++@c name from the index.
+ This function maps an interface index to its corresponding name.  The
+ returned name is placed in the buffer pointed to by @code{ifname}, which
+ must be at least @code{IFNAMSIZ} bytes in length.  If the index was
+@@ -534,6 +550,39 @@
+ @comment net/if.h
+ @comment IPv6 basic API
+ @deftypefun {struct if_nameindex *} if_nameindex (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{/hurd}}@acunsafe{@aculock{/hurd} @acsfd{} @acsmem{}}}
++@c if_nameindex @ascuheap @asulock/hurd @aculock/hurd @acsfd @acsmem
++@c  [linux]
++@c   netlink_open @acsfd @acsmem/hurd
++@c    socket dup @acsfd
++@c    memset dup ok
++@c    bind dup ok
++@c    netlink_close dup @acsfd
++@c    getsockname dup @acsmem/hurd
++@c   netlink_request @ascuheap @acsmem
++@c    getpagesize dup ok
++@c    malloc dup @ascuheap @acsmem
++@c    netlink_sendreq ok
++@c     memset dup ok
++@c     sendto dup ok
++@c    recvmsg dup ok
++@c    memcpy dup ok
++@c    free dup @ascuheap @acsmem
++@c   netlink_free_handle @ascuheap @acsmem
++@c    free dup @ascuheap @acsmem
++@c   netlink_close @acsfd
++@c    close dup @acsfd
++@c   malloc dup @asuheap @acsmem
++@c   strndup @ascuheap @acsmem
++@c   if_freenameindex @ascuheap @acsmem
++@c  [hurd]
++@c   opensock dup @asulock @aculock @acsfd
++@c   hurd_socket_server ok
++@c   pfinet_siocgifconf ok
++@c   malloc @ascuheap @acsmem
++@c   strdup @ascuheap @acsmem
++@c   ioctl dup ok
++@c   free @ascuheap @acsmem
+ This function returns an array of @code{if_nameindex} structures, one
+ for every interface that is present.  The end of the list is indicated
+ by a structure with an interface of 0 and a null name pointer.  If an
+@@ -546,6 +595,9 @@
+ @comment net/if.h
+ @comment IPv6 basic API
+ @deftypefun void if_freenameindex (struct if_nameindex *@var{ptr})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c if_freenameindex @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
+ This function frees the structure returned by an earlier call to
+ @code{if_nameindex}.
+ @end deftypefun
+@@ -660,6 +712,7 @@
+ @comment sys/un.h
+ @comment BSD
+ @deftypefn {Macro} int SUN_LEN (@emph{struct sockaddr_un *} @var{ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The macro computes the length of socket address in the local namespace.
+ @end deftypefn
+ 
+@@ -689,7 +742,7 @@
+ To create a socket in the IPv4 Internet namespace, use the symbolic name
+ @code{PF_INET} of this namespace as the @var{namespace} argument to
+ @code{socket} or @code{socketpair}.  For IPv6 addresses you need the
+-macro @code{PF_INET6}. These macros are defined in @file{sys/socket.h}.
++macro @code{PF_INET6}.  These macros are defined in @file{sys/socket.h}.
+ @pindex sys/socket.h
+ 
+ @comment sys/socket.h
+@@ -726,12 +779,12 @@
+ * Internet Address Formats::    How socket addresses are specified in the
+                                  Internet namespace.
+ * Host Addresses::	        All about host addresses of Internet host.
+-* Protocols Database::		Referring to protocols by name.
+ * Ports::			Internet port numbers.
+ * Services Database::           Ports may have symbolic names.
+ * Byte Order::		        Different hosts may use different byte
+                                  ordering conventions; you need to
+                                  canonicalize host address and port number.
++* Protocols Database::		Referring to protocols by name.
+ * Inet Example::	        Putting it all together.
+ @end menu
+ 
+@@ -1035,6 +1088,13 @@
+ @comment arpa/inet.h
+ @comment BSD
+ @deftypefun int inet_aton (const char *@var{name}, struct in_addr *@var{addr})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c inet_aton @mtslocale
++@c  isdigit dup @mtslocale
++@c  strtoul dup @mtslocale
++@c  isascii dup @mtslocale
++@c  isspace dup @mtslocale
++@c  htonl dup ok
+ This function converts the IPv4 Internet host address @var{name}
+ from the standard numbers-and-dots notation into binary data and stores
+ it in the @code{struct in_addr} that @var{addr} points to.
+@@ -1044,10 +1104,13 @@
+ @comment arpa/inet.h
+ @comment BSD
+ @deftypefun {uint32_t} inet_addr (const char *@var{name})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c inet_addr @mtslocale
++@c  inet_aton dup @mtslocale
+ This function converts the IPv4 Internet host address @var{name} from the
+ standard numbers-and-dots notation into binary data.  If the input is
+ not valid, @code{inet_addr} returns @code{INADDR_NONE}.  This is an
+-obsolete interface to @code{inet_aton}, described immediately above. It
++obsolete interface to @code{inet_aton}, described immediately above.  It
+ is obsolete because @code{INADDR_NONE} is a valid address
+ (255.255.255.255), and @code{inet_aton} provides a cleaner way to
+ indicate error return.
+@@ -1056,9 +1119,15 @@
+ @comment arpa/inet.h
+ @comment BSD
+ @deftypefun {uint32_t} inet_network (const char *@var{name})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c inet_network @mtslocale
++@c  isdigit dup @mtslocale
++@c  isxdigit dup @mtslocale
++@c  tolower dup @mtslocale
++@c  isspace dup @mtslocale
+ This function extracts the network number from the address @var{name},
+-given in the standard numbers-and-dots notation. The returned address is
+-in host order. If the input is not valid, @code{inet_network} returns
++given in the standard numbers-and-dots notation.  The returned address is
++in host order.  If the input is not valid, @code{inet_network} returns
+ @code{-1}.
+ 
+ The function works only with traditional IPv4 class A, B and C network
+@@ -1069,6 +1138,10 @@
+ @comment arpa/inet.h
+ @comment BSD
+ @deftypefun {char *} inet_ntoa (struct in_addr @var{addr})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asurace{}}@acsafe{}}
++@c inet_ntoa @mtslocale @asurace
++@c   writes to a thread-local static buffer
++@c  snprintf @mtslocale [no @ascuheap or @acsmem]
+ This function converts the IPv4 Internet host address @var{addr} to a
+ string in the standard numbers-and-dots notation.  The return value is
+ a pointer into a statically-allocated buffer.  Subsequent calls will
+@@ -1087,6 +1160,9 @@
+ @comment arpa/inet.h
+ @comment BSD
+ @deftypefun {struct in_addr} inet_makeaddr (uint32_t @var{net}, uint32_t @var{local})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c inet_makeaddr ok
++@c  htonl dup ok
+ This function makes an IPv4 Internet host address by combining the network
+ number @var{net} with the local-address-within-network number
+ @var{local}.
+@@ -1095,6 +1171,11 @@
+ @comment arpa/inet.h
+ @comment BSD
+ @deftypefun uint32_t inet_lnaof (struct in_addr @var{addr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c inet_lnaof ok
++@c  ntohl dup ok
++@c  IN_CLASSA ok
++@c  IN_CLASSB ok
+ This function returns the local-address-within-network part of the
+ Internet host address @var{addr}.
+ 
+@@ -1106,6 +1187,11 @@
+ @comment arpa/inet.h
+ @comment BSD
+ @deftypefun uint32_t inet_netof (struct in_addr @var{addr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c inet_netof ok
++@c  ntohl dup ok
++@c  IN_CLASSA ok
++@c  IN_CLASSB ok
+ This function returns the network number part of the Internet host
+ address @var{addr}.
+ 
+@@ -1117,6 +1203,16 @@
+ @comment arpa/inet.h
+ @comment IPv6 basic API
+ @deftypefun int inet_pton (int @var{af}, const char *@var{cp}, void *@var{buf})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c inet_pton @mtslocale
++@c  inet_pton4 ok
++@c   memcpy dup ok
++@c  inet_pton6 @mtslocale
++@c   memset dup ok
++@c   tolower dup @mtslocale
++@c   strchr dup ok
++@c   inet_pton4 dup ok
++@c   memcpy dup ok
+ This function converts an Internet address (either IPv4 or IPv6) from
+ presentation (textual) to network (binary) format.  @var{af} should be
+ either @code{AF_INET} or @code{AF_INET6}, as appropriate for the type of
+@@ -1127,7 +1223,17 @@
+ 
+ @comment arpa/inet.h
+ @comment IPv6 basic API
+-@deftypefun {const char *} inet_ntop (int @var{af}, const void *@var{cp}, char *@var{buf}, size_t @var{len})
++@deftypefun {const char *} inet_ntop (int @var{af}, const void *@var{cp}, char *@var{buf}, socklen_t @var{len})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c inet_ntop @mtslocale
++@c  inet_ntop4 @mtslocale
++@c   sprintf dup @mtslocale [no @ascuheap or @acsmem]
++@c   strcpy dup ok
++@c  inet_ntop6 @mtslocale
++@c   memset dup ok
++@c   inet_ntop4 dup @mtslocale
++@c   sprintf dup @mtslocale [no @ascuheap or @acsmem]
++@c   strcpy dup ok
+ This function converts an Internet address (either IPv4 or IPv6) from
+ network (binary) to presentation (textual) form.  @var{af} should be
+ either @code{AF_INET} or @code{AF_INET6}, as appropriate.  @var{cp} is a
+@@ -1211,6 +1317,71 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct hostent *} gethostbyname (const char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
++@c gethostbyname @mtasurace:hostbyname @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  nss_hostname_digits_dots @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   res_maybe_init(!preinit) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    res_iclose @acsuheap @acsmem @acsfd
++@c     close_not_cancel_no_status dup @acsfd
++@c     free dup @acsuheap @acsmem
++@c    res_vinit @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c     res_randomid ok
++@c      getpid dup ok
++@c     getenv dup @mtsenv
++@c     strncpy dup ok
++@c     fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c     fsetlocking dup ok [no concurrent uses]
++@c     fgets_unlocked dup ok [no concurrent uses]
++@c     MATCH ok
++@c      strncmp dup ok
++@c     strpbrk dup ok
++@c     strchr dup ok
++@c     inet_aton dup @mtslocale
++@c     htons dup
++@c     inet_pton dup @mtslocale
++@c     malloc dup @ascuheap @acsmem
++@c     IN6_IS_ADDR_LINKLOCAL ok
++@c      htonl dup ok
++@c     IN6_IS_ADDR_MC_LINKLOCAL ok
++@c     if_nametoindex dup @asulock @aculock @acsfd
++@c     strtoul dup @mtslocale
++@c     ISSORTMASK ok
++@c      strchr dup ok
++@c     isascii dup @mtslocale
++@c     isspace dup @mtslocale
++@c     net_mask ok
++@c      ntohl dup ok
++@c      IN_CLASSA dup ok
++@c      htonl dup ok
++@c      IN_CLASSB dup ok
++@c     res_setoptions @mtslocale
++@c      strncmp dup ok
++@c      atoi dup @mtslocale
++@c     fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c     inet_makeaddr dup ok
++@c     gethostname dup ok
++@c     strcpy dup ok
++@c     rawmemchr dup ok
++@c    res_ninit @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c     res_vinit dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   isdigit dup @mtslocale
++@c   isxdigit dup @mtslocale
++@c   strlen dup ok
++@c   realloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c   memset dup ok
++@c   inet_aton dup @mtslocale
++@c   inet_pton dup @mtslocale
++@c   strcpy dup ok
++@c   memcpy dup ok
++@c   strchr dup ok
++@c  gethostbyname_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c  set_h_errno ok
+ The @code{gethostbyname} function returns information about the host
+ named @var{name}.  If the lookup fails, it returns a null pointer.
+ @end deftypefun
+@@ -1218,6 +1389,16 @@
+ @comment netdb.h
+ @comment IPv6 Basic API
+ @deftypefun {struct hostent *} gethostbyname2 (const char *@var{name}, int @var{af})
++@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname2} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
++@c gethostbyname2 @mtasurace:hostbyname2 @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  gethostbyname2_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c  set_h_errno dup ok
+ The @code{gethostbyname2} function is like @code{gethostbyname}, but
+ allows the caller to specify the desired address family (e.g.@:
+ @code{AF_INET} or @code{AF_INET6}) of the result.
+@@ -1225,11 +1406,20 @@
+ 
+ @comment netdb.h
+ @comment BSD
+-@deftypefun {struct hostent *} gethostbyaddr (const char *@var{addr}, size_t @var{length}, int @var{format})
++@deftypefun {struct hostent *} gethostbyaddr (const void *@var{addr}, socklen_t @var{length}, int @var{format})
++@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyaddr} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
++@c gethostbyaddr @mtasurace:hostbyaddr @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  gethostbyaddr_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c  set_h_errno dup ok
+ The @code{gethostbyaddr} function returns information about the host
+ with Internet address @var{addr}.  The parameter @var{addr} is not
+ really a pointer to char - it can be a pointer to an IPv4 or an IPv6
+-address. The @var{length} argument is the size (in bytes) of the address
++address.  The @var{length} argument is the size (in bytes) of the address
+ at @var{addr}.  @var{format} specifies the address format; for an IPv4
+ Internet address, specify a value of @code{AF_INET}; for an IPv6
+ Internet address, use @code{AF_INET6}.
+@@ -1282,6 +1472,76 @@
+ @comment netdb.h
+ @comment GNU
+ @deftypefun int gethostbyname_r (const char *restrict @var{name}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
++@c gethostbyname_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  nscd_gethostbyname_r @mtsenv @ascuheap @acsfd @acsmem
++@c   nscd_gethst_r @mtsenv @ascuheap @acsfd @acsmem
++@c    getenv dup @mtsenv
++@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
++@c    nscd_cache_search dup ok
++@c    memcpy dup ok
++@c    nscd_open_socket dup @acsfd
++@c    readvall dup ok
++@c    readall dup ok
++@c    close_not_cancel_no_status dup @acsfd
++@c    nscd_drop_map_ref dup @ascuheap @acsmem
++@c    nscd_unmap dup @ascuheap @acsmem
++@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  res_hconf_init @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
++@c   res_hconf.c:do_init @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
++@c    memset dup ok
++@c    getenv dup @mtsenv
++@c    fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c    fsetlocking dup ok [no concurrent uses]
++@c    fgets_unlocked dup ok [no concurrent uses]
++@c    strchrnul dup ok
++@c    res_hconf.c:parse_line @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
++@c     skip_ws dup @mtslocale
++@c     skip_string dup @mtslocale
++@c     strncasecmp dup @mtslocale
++@c     strlen dup ok
++@c     asprintf dup @mtslocale @ascuheap @acsmem
++@c     fxprintf dup @asucorrupt @aculock @acucorrupt
++@c     free dup @ascuheap @acsmem
++@c     arg_trimdomain_list dup @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
++@c     arg_spoof dup @mtslocale
++@c     arg_bool dup @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
++@c     isspace dup @mtslocale
++@c    fclose dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c    arg_spoof @mtslocale
++@c     skip_string @mtslocale
++@c      isspace dup @mtslocale
++@c     strncasecmp dup @mtslocale
++@c    arg_bool @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
++@c     strncasecmp dup @mtslocale
++@c     asprintf dup @mtslocale @ascuheap @acsmem
++@c     fxprintf dup @asucorrupt @aculock @acucorrupt
++@c     free dup @ascuheap @acsmem
++@c    arg_trimdomain_list @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
++@c     skip_string dup @mtslocale
++@c     asprintf dup @mtslocale @ascuheap @acsmem
++@c     fxprintf dup @asucorrupt @aculock @acucorrupt
++@c     free dup @ascuheap @acsmem
++@c     strndup dup @ascuheap @acsmem
++@c     skip_ws @mtslocale
++@c      isspace dup @mtslocale
++@c  nss_hosts_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_database_lookup dup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
++@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_gethostbyname_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  res_hconf_reorder_addrs @asulock @ascuheap @aculock @acsmem @acsfd
++@c   socket dup @acsfd
++@c   libc_lock_lock dup @asulock @aculock
++@c   ifreq @ascuheap @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c   if_nextreq dup ok
++@c   ioctl dup ok
++@c   realloc dup @ascuheap @acsmem
++@c   if_freereq dup @acsmem
++@c   libc_lock_unlock dup @aculock
++@c   close dup @acsfd
+ The @code{gethostbyname_r} function returns information about the host
+ named @var{name}.  The caller must pass a pointer to an object of type
+ @code{struct hostent} in the @var{result_buf} parameter.  In addition
+@@ -1290,37 +1550,42 @@
+ parameters.
+ 
+ A pointer to the buffer, in which the result is stored, is available in
+-@code{*@var{result}} after the function call successfully returned.  If
+-an error occurs or if no entry is found, the pointer @code{*@var{result}}
+-is a null pointer.  Success is signalled by a zero return value.  If the
+-function failed the return value is an error number.  In addition to the
+-errors defined for @code{gethostbyname} it can also be @code{ERANGE}.
+-In this case the call should be repeated with a larger buffer.
+-Additional error information is not stored in the global variable
+-@code{h_errno} but instead in the object pointed to by @var{h_errnop}.
++@code{*@var{result}} after the function call successfully returned.  The
++buffer passed as the @var{buf} parameter can be freed only once the caller
++has finished with the result hostent struct, or has copied it including all
++the other memory that it points to.  If an error occurs or if no entry is
++found, the pointer @code{*@var{result}} is a null pointer.  Success is
++signalled by a zero return value.  If the function failed the return value
++is an error number.  In addition to the errors defined for
++@code{gethostbyname} it can also be @code{ERANGE}.  In this case the call
++should be repeated with a larger buffer.  Additional error information is
++not stored in the global variable @code{h_errno} but instead in the object
++pointed to by @var{h_errnop}.
+ 
+ Here's a small example:
+ @smallexample
+ struct hostent *
+ gethostname (char *host)
+ @{
+-  struct hostent hostbuf, *hp;
++  struct hostent *hostbuf, *hp;
+   size_t hstbuflen;
+   char *tmphstbuf;
+   int res;
+   int herr;
+ 
++  hostbuf = malloc (sizeof (struct hostent));
+   hstbuflen = 1024;
+-  /* Allocate buffer, remember to free it to avoid memory leakage.  */
+   tmphstbuf = malloc (hstbuflen);
+ 
+-  while ((res = gethostbyname_r (host, &hostbuf, tmphstbuf, hstbuflen,
++  while ((res = gethostbyname_r (host, hostbuf, tmphstbuf, hstbuflen,
+                                  &hp, &herr)) == ERANGE)
+     @{
+       /* Enlarge the buffer.  */
+       hstbuflen *= 2;
+       tmphstbuf = realloc (tmphstbuf, hstbuflen);
+     @}
++
++  free (tmphstbuf);
+   /*  Check for errors.  */
+   if (res || hp == NULL)
+     return NULL;
+@@ -1332,6 +1597,17 @@
+ @comment netdb.h
+ @comment GNU
+ @deftypefun int gethostbyname2_r (const char *@var{name}, int @var{af}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
++@c gethostbyname2_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  nscd_gethostbyname2_r @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
++@c   nscd_gethst_r dup @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
++@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  res_hconf_init dup @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
++@c  nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_gethostbyname2_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  res_hconf_reorder_addrs dup @asulock @ascuheap @aculock @acsmem @acsfd
+ The @code{gethostbyname2_r} function is like @code{gethostbyname_r}, but
+ allows the caller to specify the desired address family (e.g.@:
+ @code{AF_INET} or @code{AF_INET6}) for the result.
+@@ -1339,11 +1615,26 @@
+ 
+ @comment netdb.h
+ @comment GNU
+-@deftypefun int gethostbyaddr_r (const char *@var{addr}, size_t @var{length}, int @var{format}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
++@deftypefun int gethostbyaddr_r (const void *@var{addr}, socklen_t @var{length}, int @var{format}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
++@c gethostbyaddr_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
++@c  memcmp dup ok
++@c  nscd_gethostbyaddr_r @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
++@c   nscd_gethst_r dup @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
++@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  res_hconf_init dup @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
++@c  nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_gethostbyaddr_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  res_hconf_reorder_addrs dup @asulock @ascuheap @aculock @acsmem @acsfd
++@c  res_hconf_trim_domains @mtslocale
++@c   res_hconf_trim_domain @mtslocale
++@c    strlen dup ok
++@c    strcasecmp dup @mtslocale
+ The @code{gethostbyaddr_r} function returns information about the host
+ with Internet address @var{addr}.  The parameter @var{addr} is not
+ really a pointer to char - it can be a pointer to an IPv4 or an IPv6
+-address. The @var{length} argument is the size (in bytes) of the address
++address.  The @var{length} argument is the size (in bytes) of the address
+ at @var{addr}.  @var{format} specifies the address format; for an IPv4
+ Internet address, specify a value of @code{AF_INET}; for an IPv6
+ Internet address, use @code{AF_INET6}.
+@@ -1362,6 +1653,18 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void sethostent (int @var{stayopen})
++@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c sethostent @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_setent(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   set_h_errno dup ok
++@c   setup(nss_hosts_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    *lookup_fct = nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:hostent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock dup @aculock
+ This function opens the hosts database to begin scanning it.  You can
+ then call @code{gethostent} to read the entries.
+ 
+@@ -1377,6 +1680,27 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct hostent *} gethostent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtasurace{:hostentbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c gethostent @mtasurace:hostent @mtasurace:hostentbuf @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent(gethostent_r) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c   *func = gethostent_r dup @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   realloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c gethostent_r @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent_r(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   setup(nss_hosts_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:hostent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *sfct.f @mtasurace:hostent @ascuplugin
++@c  libc_lock_unlock dup @aculock
++
+ This function returns the next entry in the hosts database.  It
+ returns a null pointer if there are no more entries.
+ @end deftypefun
+@@ -1384,6 +1708,15 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void endhostent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c endhostent @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock @asulock @aculock
++@c  nss_endent(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:hostent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock @aculock
+ This function closes the hosts database.
+ @end deftypefun
+ 
+@@ -1483,6 +1816,34 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct servent *} getservbyname (const char *@var{name}, const char *@var{proto})
++@safety{@prelim{}@mtunsafe{@mtasurace{:servbyname} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getservbyname =~ getpwuid @mtasurace:servbyname @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  getservbyname_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getservbyname_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  nscd_getservbyname_r @ascuheap @acsfd @acsmem
++@c   nscd_getserv_r @ascuheap @acsfd @acsmem
++@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
++@c    strlen dup ok
++@c    malloc dup @ascuheap @acsmem
++@c    mempcpy dup ok
++@c    memcpy dup ok
++@c    nscd_cache_search dup ok
++@c    nscd_open_socket dup @acsfd
++@c    readvall dup ok
++@c    readall dup ok
++@c    close_not_cancel_no_status dup @acsfd
++@c    nscd_drop_map_ref dup @ascuheap @acsmem
++@c    nscd_unmap dup @ascuheap @acsmem
++@c    free dup @ascuheap @acsmem
++@c  nss_services_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_getservbyname_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ The @code{getservbyname} function returns information about the
+ service named @var{name} using protocol @var{proto}.  If it can't find
+ such a service, it returns a null pointer.
+@@ -1494,6 +1855,21 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct servent *} getservbyport (int @var{port}, const char *@var{proto})
++@safety{@prelim{}@mtunsafe{@mtasurace{:servbyport} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getservbyport =~ getservbyname @mtasurace:servbyport @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  getservbyport_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getservbyport_r =~ getservbyname_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  nscd_getservbyport_r @ascuheap @acsfd @acsmem
++@c   nscd_getserv_r dup @ascuheap @acsfd @acsmem
++@c  nss_services_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_getservbyport_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ The @code{getservbyport} function returns information about the
+ service at port @var{port} using protocol @var{proto}.  If it can't
+ find such a service, it returns a null pointer.
+@@ -1507,6 +1883,16 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void setservent (int @var{stayopen})
++@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c setservent @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_setent(nss_services_lookup2) @mtasurace:servenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   setup(nss_services_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    *lookup_fct = nss_services_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:servent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock dup @aculock
+ This function opens the services database to begin scanning it.
+ 
+ If the @var{stayopen} argument is nonzero, this sets a flag so that
+@@ -1519,6 +1905,25 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct servent *} getservent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtasurace{:serventbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getservent @mtasurace:servent @mtasurace:serventbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent(getservent_r) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c   *func = getservent_r dup @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   realloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getservent_r @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent_r(nss_services_lookup2) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   setup(nss_services_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:servent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *sfct.f @mtasurace:servent @ascuplugin
++@c  libc_lock_unlock dup @aculock
+ This function returns the next entry in the services database.  If
+ there are no more entries, it returns a null pointer.
+ @end deftypefun
+@@ -1526,6 +1931,14 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void endservent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c endservent @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock @asulock @aculock
++@c  nss_endent(nss_services_lookup2) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   setup(nss_services_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:servent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock @aculock
+ This function closes the services database.
+ @end deftypefun
+ 
+@@ -1571,6 +1984,11 @@
+ @comment netinet/in.h
+ @comment BSD
+ @deftypefun {uint16_t} htons (uint16_t @var{hostshort})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c htons ok
++@c  bswap_16 ok
++@c   bswap_constant_16 ok
++
+ This function converts the @code{uint16_t} integer @var{hostshort} from
+ host byte order to network byte order.
+ @end deftypefun
+@@ -1578,6 +1996,8 @@
+ @comment netinet/in.h
+ @comment BSD
+ @deftypefun {uint16_t} ntohs (uint16_t @var{netshort})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Alias to htons.
+ This function converts the @code{uint16_t} integer @var{netshort} from
+ network byte order to host byte order.
+ @end deftypefun
+@@ -1585,6 +2005,9 @@
+ @comment netinet/in.h
+ @comment BSD
+ @deftypefun {uint32_t} htonl (uint32_t @var{hostlong})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c htonl ok
++@c  bswap_32 dup ok
+ This function converts the @code{uint32_t} integer @var{hostlong} from
+ host byte order to network byte order.
+ 
+@@ -1594,6 +2017,8 @@
+ @comment netinet/in.h
+ @comment BSD
+ @deftypefun {uint32_t} ntohl (uint32_t @var{netlong})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Alias to htonl.
+ This function converts the @code{uint32_t} integer @var{netlong} from
+ network byte order to host byte order.
+ 
+@@ -1658,6 +2083,20 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct protoent *} getprotobyname (const char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasurace{:protobyname} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getprotobyname =~ getpwuid @mtasurace:protobyname @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  getprotobyname_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getprotobyname_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   no nscd support
++@c  nss_protocols_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_getprotobyname_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ The @code{getprotobyname} function returns information about the
+ network protocol named @var{name}.  If there is no such protocol, it
+ returns a null pointer.
+@@ -1666,6 +2105,20 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct protoent *} getprotobynumber (int @var{protocol})
++@safety{@prelim{}@mtunsafe{@mtasurace{:protobynumber} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getprotobynumber =~ getpwuid @mtasurace:protobynumber @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  getprotobynumber_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getprotobynumber_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   no nscd support
++@c  nss_protocols_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_getprotobynumber_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ The @code{getprotobynumber} function returns information about the
+ network protocol with number @var{protocol}.  If there is no such
+ protocol, it returns a null pointer.
+@@ -1678,6 +2131,16 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void setprotoent (int @var{stayopen})
++@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c setprotoent @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_setent(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   setup(nss_protocols_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    *lookup_fct = nss_protocols_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:protoent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock dup @aculock
+ This function opens the protocols database to begin scanning it.
+ 
+ If the @var{stayopen} argument is nonzero, this sets a flag so that
+@@ -1690,6 +2153,25 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct protoent *} getprotoent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtasurace{:protoentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getprotoent @mtasurace:protoent @mtasurace:protoentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent(getprotoent_r) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c   *func = getprotoent_r dup @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   realloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getprotoent_r @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent_r(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   setup(nss_protocols_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:servent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *sfct.f @mtasurace:protoent @ascuplugin
++@c  libc_lock_unlock dup @aculock
+ This function returns the next entry in the protocols database.  It
+ returns a null pointer if there are no more entries.
+ @end deftypefun
+@@ -1697,6 +2179,14 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void endprotoent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c endprotoent @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock @asulock @aculock
++@c  nss_endent(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   setup(nss_protocols_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:protoent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock @aculock
+ This function closes the protocols database.
+ @end deftypefun
+ 
+@@ -1766,6 +2256,7 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int socket (int @var{namespace}, int @var{style}, int @var{protocol})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ This function creates a socket and specifies communication style
+ @var{style}, which should be one of the socket styles listed in
+ @ref{Communication Styles}.  The @var{namespace} argument specifies
+@@ -1828,6 +2319,7 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int shutdown (int @var{socket}, int @var{how})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{shutdown} function shuts down the connection of socket
+ @var{socket}.  The argument @var{how} specifies what action to
+ perform:
+@@ -1879,6 +2371,7 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int socketpair (int @var{namespace}, int @var{style}, int @var{protocol}, int @var{filedes}@t{[2]})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ This function creates a socket pair, returning the file descriptors in
+ @code{@var{filedes}[0]} and @code{@var{filedes}[1]}.  The socket pair
+ is a full-duplex communications channel, so that both reading and writing
+@@ -1972,6 +2465,7 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int connect (int @var{socket}, struct sockaddr *@var{addr}, socklen_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{connect} function initiates a connection from the socket
+ with file descriptor @var{socket} to the socket whose address is
+ specified by the @var{addr} and @var{length} arguments.  (This socket
+@@ -2071,6 +2565,7 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int listen (int @var{socket}, int @var{n})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ The @code{listen} function enables the socket @var{socket} to accept
+ connections, thus making it a server socket.
+ 
+@@ -2123,6 +2618,7 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int accept (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length_ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+ This function is used to accept a connection request on the server
+ socket @var{socket}.
+ 
+@@ -2181,6 +2677,7 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int getpeername (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{getpeername} function returns the address of the socket that
+ @var{socket} is connected to; it stores the address in the memory space
+ specified by @var{addr} and @var{length-ptr}.  It stores the length of
+@@ -2248,7 +2745,8 @@
+ 
+ @comment sys/socket.h
+ @comment BSD
+-@deftypefun int send (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags})
++@deftypefun ssize_t send (int @var{socket}, const void *@var{buffer}, size_t @var{size}, int @var{flags})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{send} function is like @code{write}, but with the additional
+ flags @var{flags}.  The possible values of @var{flags} are described
+ in @ref{Socket Data Options}.
+@@ -2315,7 +2813,8 @@
+ 
+ @comment sys/socket.h
+ @comment BSD
+-@deftypefun int recv (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags})
++@deftypefun ssize_t recv (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{recv} function is like @code{read}, but with the additional
+ flags @var{flags}.  The possible values of @var{flags} are described
+ in @ref{Socket Data Options}.
+@@ -2643,7 +3142,8 @@
+ 
+ @comment sys/socket.h
+ @comment BSD
+-@deftypefun int sendto (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t @var{length})
++@deftypefun ssize_t sendto (int @var{socket}, const void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{sendto} function transmits the data in the @var{buffer}
+ through the socket @var{socket} to the destination address specified
+ by the @var{addr} and @var{length} arguments.  The @var{size} argument
+@@ -2678,7 +3178,8 @@
+ 
+ @comment sys/socket.h
+ @comment BSD
+-@deftypefun int recvfrom (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr})
++@deftypefun ssize_t recvfrom (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{recvfrom} function reads one packet from the socket
+ @var{socket} into the buffer @var{buffer}.  The @var{size} argument
+ specifies the maximum number of bytes to be read.
+@@ -2725,7 +3226,8 @@
+ 
+ @comment sys/socket.h
+ @comment BSD
+-@deftypefun int sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags})
++@deftypefun ssize_t sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ This function is defined as a cancellation point in multi-threaded
+ programs, so one has to be prepared for this and make sure that
+@@ -2736,7 +3238,8 @@
+ 
+ @comment sys/socket.h
+ @comment BSD
+-@deftypefun int recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags})
++@deftypefun ssize_t recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ This function is defined as a cancellation point in multi-threaded
+ programs, so one has to be prepared for this and make sure that
+@@ -2924,6 +3427,7 @@
+ @comment sys/socket.h
+ @comment BSD
+ @deftypefun int getsockopt (int @var{socket}, int @var{level}, int @var{optname}, void *@var{optval}, socklen_t *@var{optlen-ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{getsockopt} function gets information about the value of
+ option @var{optname} at level @var{level} for socket @var{socket}.
+ 
+@@ -2953,7 +3457,8 @@
+ 
+ @comment sys/socket.h
+ @comment BSD
+-@deftypefun int setsockopt (int @var{socket}, int @var{level}, int @var{optname}, void *@var{optval}, socklen_t @var{optlen})
++@deftypefun int setsockopt (int @var{socket}, int @var{level}, int @var{optname}, const void *@var{optval}, socklen_t @var{optlen})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is used to set the socket option @var{optname} at level
+ @var{level} for socket @var{socket}.  The value of the option is passed
+ in the buffer @var{optval} of size @var{optlen}.
+@@ -3150,6 +3655,21 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct netent *} getnetbyname (const char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasurace{:netbyname} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getnetbyname =~ getpwuid @mtasurace:netbyname @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  getnetbyname_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getnetbyname_r =~ getpwuid_r @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   no nscd support
++@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  nss_networks_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_getnetbyname_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ The @code{getnetbyname} function returns information about the network
+ named @var{name}.  It returns a null pointer if there is no such
+ network.
+@@ -3157,7 +3677,21 @@
+ 
+ @comment netdb.h
+ @comment BSD
+-@deftypefun {struct netent *} getnetbyaddr (unsigned long int @var{net}, int @var{type})
++@deftypefun {struct netent *} getnetbyaddr (uint32_t @var{net}, int @var{type})
++@safety{@prelim{}@mtunsafe{@mtasurace{:netbyaddr} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getnetbyaddr =~ getpwuid @mtasurace:netbyaddr @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  getnetbyaddr_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getnetbyaddr_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   no nscd support
++@c  nss_networks_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_getnetbyaddr_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ The @code{getnetbyaddr} function returns information about the network
+ of type @var{type} with number @var{net}.  You should specify a value of
+ @code{AF_INET} for the @var{type} argument for Internet networks.
+@@ -3173,6 +3707,17 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void setnetent (int @var{stayopen})
++@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c setnetent @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_setent(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   setup(nss_networks_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    *lookup_fct = nss_networks_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:netent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock dup @aculock
+ This function opens and rewinds the networks database.
+ 
+ If the @var{stayopen} argument is nonzero, this sets a flag so that
+@@ -3185,6 +3730,26 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun {struct netent *} getnetent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtasurace{:netentbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getnetent @mtasurace:netent @mtasurace:netentbuf @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent(getnetent_r) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c   *func = getnetent_r dup @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   realloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
++@c
++@c getnetent_r @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent_r(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   setup(nss_networks_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:servent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *sfct.f @mtasurace:netent @ascuplugin
++@c  libc_lock_unlock dup @aculock
+ This function returns the next entry in the networks database.  It
+ returns a null pointer if there are no more entries.
+ @end deftypefun
+@@ -3192,5 +3757,14 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void endnetent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c endnetent @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock @asulock @aculock
++@c  nss_endent(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   setup(nss_networks_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:netent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock @aculock
+ This function closes the networks database.
+ @end deftypefun
+diff -urN glibc-2.17-c758a686/manual/startup.texi glibc/manual/startup.texi
+--- glibc-2.17-c758a686/manual/startup.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/startup.texi	2014-09-12 16:10:06.042792724 -0400
+@@ -41,7 +41,7 @@
+ * Program Termination::         Telling the system you're done; return status
+ @end menu
+ 
+-@node Program Arguments
++@node Program Arguments, Environment Variables, , Program Basics
+ @section Program Arguments
+ @cindex program arguments
+ @cindex command line arguments
+@@ -220,7 +220,12 @@
+ available.
+ 
+ @comment stdlib.h
+-@deftypefun int getsubopt (char **@var{optionp}, const char* const *@var{tokens}, char **@var{valuep})
++@deftypefun int getsubopt (char **@var{optionp}, char *const *@var{tokens}, char **@var{valuep})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c getsubopt ok
++@c  strchrnul dup ok
++@c  memchr dup ok
++@c  strncmp dup ok
+ 
+ The @var{optionp} parameter must be a pointer to a variable containing
+ the address of the string to process.  When the function returns the
+@@ -258,7 +263,7 @@
+ @end smallexample
+ 
+ 
+-@node Environment Variables
++@node Environment Variables, Auxiliary Vector, Program Arguments, Program Basics
+ @section Environment Variables
+ 
+ @cindex environment variable
+@@ -322,6 +327,8 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun {char *} getenv (const char *@var{name})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@assafe{}@acsafe{}}
++@c Unguarded access to __environ.
+ This function returns a string that is the value of the environment
+ variable @var{name}.  You must not modify this string.  In some non-Unix
+ systems not using @theglibc{}, it might be overwritten by subsequent
+@@ -333,6 +340,8 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun {char *} secure_getenv (const char *@var{name})
++@safety{@prelim{}@mtsafe{@mtsenv{}}@assafe{}@acsafe{}}
++@c Calls getenv unless secure mode is enabled.
+ This function is similar to @code{getenv}, but it returns a null
+ pointer if the environment is untrusted.  This happens when the
+ program file has SUID or SGID bits set.  General-purpose libraries
+@@ -346,6 +355,13 @@
+ @comment stdlib.h
+ @comment SVID
+ @deftypefun int putenv (char *@var{string})
++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c putenv @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
++@c  strchr dup ok
++@c  strndup dup @ascuheap @acsmem
++@c  add_to_environ dup @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
++@c  free dup @ascuheap @acsmem
++@c  unsetenv dup @mtasuconst:@mtsenv @asulock @aculock
+ The @code{putenv} function adds or removes definitions from the environment.
+ If the @var{string} is of the form @samp{@var{name}=@var{value}}, the
+ definition is added to the environment.  Otherwise, the @var{string} is
+@@ -358,20 +374,37 @@
+ The difference to the @code{setenv} function is that the exact string
+ given as the parameter @var{string} is put into the environment.  If the
+ user should change the string after the @code{putenv} call this will
+-reflect in automatically in the environment.  This also requires that
+-@var{string} is no automatic variable which scope is left before the
++reflect automatically in the environment.  This also requires that
++@var{string} not be an automatic variable whose scope is left before the
+ variable is removed from the environment.  The same applies of course to
+ dynamically allocated variables which are freed later.
+ 
+-This function is part of the extended Unix interface.  Since it was also
+-available in old SVID libraries you should define either
+-@var{_XOPEN_SOURCE} or @var{_SVID_SOURCE} before including any header.
++This function is part of the extended Unix interface.  You should define
++@var{_XOPEN_SOURCE} before including any header.
+ @end deftypefun
+ 
+ 
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun int setenv (const char *@var{name}, const char *@var{value}, int @var{replace})
++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c setenv @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
++@c  add_to_environ @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
++@c   strlen dup ok
++@c   libc_lock_lock @asulock @aculock
++@c   strncmp dup ok
++@c   realloc dup @ascuheap @acsmem
++@c   libc_lock_unlock @aculock
++@c   malloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c   mempcpy dup ok
++@c   memcpy dup ok
++@c   KNOWN_VALUE ok
++@c    tfind(strcmp) [no @mtsrace guarded access]
++@c     strcmp dup ok
++@c   STORE_VALUE @ascuheap @acucorrupt @acsmem
++@c    tsearch(strcmp) @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt guarded access makes for mtsafe and @asulock]
++@c     strcmp dup ok
+ The @code{setenv} function can be used to add a new definition to the
+ environment.  The entry with the name @var{name} is replaced by the
+ value @samp{@var{name}=@var{value}}.  Please note that this is also true
+@@ -395,6 +428,13 @@
+ @comment stdlib.h
+ @comment BSD
+ @deftypefun int unsetenv (const char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c unsetenv @mtasuconst:@mtsenv @asulock @aculock
++@c  strchr dup ok
++@c  strlen dup ok
++@c  libc_lock_lock @asulock @aculock
++@c  strncmp dup ok
++@c  libc_lock_unlock @aculock
+ Using this function one can remove an entry completely from the
+ environment.  If the environment contains an entry with the key
+ @var{name} this whole entry is removed.  A call to this function is
+@@ -418,6 +458,11 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int clearenv (void)
++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
++@c clearenv @mtasuconst:@mtsenv @ascuheap @asulock @aculock @acsmem
++@c  libc_lock_lock @asulock @aculock
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock @aculock
+ The @code{clearenv} function removes all entries from the environment.
+ Using @code{putenv} and @code{setenv} new entries can be added again
+ later.
+@@ -622,10 +667,13 @@
+ @subsection Definition of @code{getauxval}
+ @comment sys/auxv.h
+ @deftypefun {unsigned long int} getauxval (unsigned long int @var{type})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Reads from hwcap or iterates over constant auxv.
+ This function is used to inquire about the entries in the auxiliary
+ vector.  The @var{type} argument should be one of the @samp{AT_} symbols
+ defined in @file{elf.h}.  If a matching entry is found, the value is
+-returned; if the entry is not found, zero is returned.
++returned; if the entry is not found, zero is returned and @code{errno} is
++set to @code{ENOENT}.
+ @end deftypefun
+ 
+ For some platforms, the key @code{AT_HWCAP} is the easiest way to inquire
+@@ -677,6 +725,7 @@
+ @comment unistd.h
+ @comment ???
+ @deftypefun {long int} syscall (long int @var{sysno}, @dots{})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ @code{syscall} performs a generic system call.
+ 
+@@ -782,6 +831,10 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun void exit (int @var{status})
++@safety{@prelim{}@mtunsafe{@mtasurace{:exit}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
++@c Access to the atexit/on_exit list, the libc_atexit hook and tls dtors
++@c is not guarded.  Streams must be flushed, and that triggers the usual
++@c AS and AC issues with streams.
+ The @code{exit} function tells the system that the program is done, which
+ causes it to terminate the process.
+ 
+@@ -898,6 +951,15 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun int atexit (void (*@var{function}) (void))
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
++@c atexit @ascuheap @asulock @aculock @acsmem
++@c  cxa_atexit @ascuheap @asulock @aculock @acsmem
++@c   __internal_atexit @ascuheap @asulock @aculock @acsmem
++@c    __new_exitfn @ascuheap @asulock @aculock @acsmem
++@c     __libc_lock_lock @asulock @aculock
++@c     calloc dup @ascuheap @acsmem
++@c     __libc_lock_unlock @aculock
++@c    atomic_write_barrier dup ok
+ The @code{atexit} function registers the function @var{function} to be
+ called at normal program termination.  The @var{function} is called with
+ no arguments.
+@@ -909,6 +971,10 @@
+ @comment stdlib.h
+ @comment SunOS
+ @deftypefun int on_exit (void (*@var{function})(int @var{status}, void *@var{arg}), void *@var{arg})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
++@c on_exit @ascuheap @asulock @aculock @acsmem
++@c  new_exitfn dup @ascuheap @asulock @aculock @acsmem
++@c  atomic_write_barrier dup ok
+ This function is a somewhat more powerful variant of @code{atexit}.  It
+ accepts two arguments, a function @var{function} and an arbitrary
+ pointer @var{arg}.  At normal program termination, the @var{function} is
+@@ -940,6 +1006,10 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun void abort (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
++@c The implementation takes a recursive lock and attempts to support
++@c calls from signal handlers, but if we're in the middle of flushing or
++@c using streams, we may encounter them in inconsistent states.
+ The @code{abort} function causes abnormal program termination.  This
+ does not execute cleanup functions registered with @code{atexit} or
+ @code{on_exit}.
+@@ -967,6 +1037,9 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun void _exit (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall (exit_group or exit); calls __task_terminate on hurd,
++@c and abort in the generic posix implementation.
+ The @code{_exit} function is the primitive for causing a process to
+ terminate with status @var{status}.  Calling this function does not
+ execute cleanup functions registered with @code{atexit} or
+@@ -976,6 +1049,8 @@
+ @comment stdlib.h
+ @comment ISO
+ @deftypefun void _Exit (int @var{status})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Alias for _exit.
+ The @code{_Exit} function is the @w{ISO C} equivalent to @code{_exit}.
+ The @w{ISO C} committee members were not sure whether the definitions of
+ @code{_exit} and @code{_Exit} were compatible so they have not used the
+diff -urN glibc-2.17-c758a686/manual/stdio.texi glibc/manual/stdio.texi
+--- glibc-2.17-c758a686/manual/stdio.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/stdio.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -148,6 +148,8 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun {FILE *} fopen (const char *@var{filename}, const char *@var{opentype})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
++@c fopen may leak the list lock if cancelled within _IO_link_in.
+ The @code{fopen} function opens a stream for I/O to the file
+ @var{filename}, and returns a pointer to the stream.
+ 
+@@ -265,9 +267,10 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun {FILE *} fopen64 (const char *@var{filename}, const char *@var{opentype})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
+ This function is similar to @code{fopen} but the stream it returns a
+ pointer for is opened using @code{open64}.  Therefore this stream can be
+-used even on files larger then @math{2^31} bytes on 32 bit machines.
++used even on files larger than @math{2^31} bytes on 32 bit machines.
+ 
+ Please note that the return type is still @code{FILE *}.  There is no
+ special @code{FILE} type for the LFS interface.
+@@ -294,6 +297,16 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun {FILE *} freopen (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsfd{}}}
++@c Like most I/O operations, this one is guarded by a recursive lock,
++@c released even upon cancellation, but cancellation may leak file
++@c descriptors and leave the stream in an inconsistent state (e.g.,
++@c still bound to the closed descriptor).  Also, if the stream is
++@c part-way through a significant update (say running freopen) when a
++@c signal handler calls freopen again on the same stream, the result is
++@c likely to be an inconsistent stream, and the possibility of closing
++@c twice file descriptor number that the stream used to use, the second
++@c time when it might have already been reused by another thread.
+ This function is like a combination of @code{fclose} and @code{fopen}.
+ It first closes the stream referred to by @var{stream}, ignoring any
+ errors that are detected in the process.  (Because errors are ignored,
+@@ -320,6 +333,7 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun {FILE *} freopen64 (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsfd{}}}
+ This function is similar to @code{freopen}.  The only difference is that
+ on 32 bit machine the stream returned is able to read beyond the
+ @math{2^31} bytes limits imposed by the normal interface.  It should be
+@@ -341,6 +355,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun int __freadable (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{__freadable} function determines whether the stream
+ @var{stream} was opened to allow reading.  In this case the return value
+ is nonzero.  For write-only streams the function returns zero.
+@@ -351,6 +366,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun int __fwritable (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{__fwritable} function determines whether the stream
+ @var{stream} was opened to allow writing.  In this case the return value
+ is nonzero.  For read-only streams the function returns zero.
+@@ -364,6 +380,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun int __freading (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{__freading} function determines whether the stream
+ @var{stream} was last read from or whether it is opened read-only.  In
+ this case the return value is nonzero, otherwise it is zero.
+@@ -377,6 +394,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun int __fwriting (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{__fwriting} function determines whether the stream
+ @var{stream} was last written to or whether it is opened write-only.  In
+ this case the return value is nonzero, otherwise it is zero.
+@@ -396,6 +414,21 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fclose (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c After fclose, it is undefined behavior to use the stream it points
++@c to.  Therefore, one must only call fclose when the stream is
++@c otherwise unused.  Concurrent uses started before will complete
++@c successfully because of the lock, which makes it MT-Safe.  Calling it
++@c from a signal handler is perfectly safe if the stream is known to be
++@c no longer used, which is a precondition for fclose to be safe in the
++@c first place; since this is no further requirement, fclose is safe for
++@c use in async signals too.  After calling fclose, you can no longer
++@c use the stream, not even to fclose it again, so its memory and file
++@c descriptor may leak if fclose is canceled before @c releasing them.
++@c That the stream must be unused and it becomes unused after the call
++@c is what would enable fclose to be AS- and AC-Safe while freopen
++@c isn't.  However, because of the possibility of leaving __gconv_lock
++@c taken upon cancellation, AC-Safety is lost.
+ This function causes @var{stream} to be closed and the connection to
+ the corresponding file to be broken.  Any buffered output is written
+ and any buffered input is discarded.  The @code{fclose} function returns
+@@ -418,6 +451,12 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int fcloseall (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:streams}}@asunsafe{}@acsafe{}}
++@c Like fclose, using any previously-opened streams after fcloseall is
++@c undefined.  However, the implementation of fcloseall isn't equivalent
++@c to calling fclose for all streams: it just flushes and unbuffers all
++@c streams, without any locking.  It's the flushing without locking that
++@c makes it unsafe.
+ This function causes all open streams of the process to be closed and
+ the connection to corresponding files to be broken.  All buffered data
+ is written and any buffered input is discarded.  The @code{fcloseall}
+@@ -474,6 +513,9 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun void flockfile (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
++@c There's no way to tell whether the lock was acquired before or after
++@c cancellation so as to unlock only when appropriate.
+ The @code{flockfile} function acquires the internal locking object
+ associated with the stream @var{stream}.  This ensures that no other
+ thread can explicitly through @code{flockfile}/@code{ftrylockfile} or
+@@ -485,6 +527,7 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun int ftrylockfile (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
+ The @code{ftrylockfile} function tries to acquire the internal locking
+ object associated with the stream @var{stream} just like
+ @code{flockfile}.  But unlike @code{flockfile} this function does not
+@@ -496,8 +539,9 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun void funlockfile (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
+ The @code{funlockfile} function releases the internal locking object of
+-the stream @var{stream}. The stream must have been locked before by a
++the stream @var{stream}.  The stream must have been locked before by a
+ call to @code{flockfile} or a successful call of @code{ftrylockfile}.
+ The implicit locking performed by the stream operations do not count.
+ The @code{funlockfile} function does not return an error status and the
+@@ -621,6 +665,15 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun int __fsetlocking (FILE *@var{stream}, int @var{type})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asulock{}}@acsafe{}}
++@c Changing the implicit-locking status of a stream while it's in use by
++@c another thread may cause a lock to be implicitly acquired and not
++@c released, or vice-versa.  This function should probably hold the lock
++@c while changing this setting, to make sure we don't change it while
++@c there are any concurrent uses.  Meanwhile, callers should acquire the
++@c lock themselves to be safe, and even concurrent uses with external
++@c locking will be fine, as long as functions that require external
++@c locking are not called without holding locks.
+ 
+ The @code{__fsetlocking} function can be used to select whether the
+ stream operations will implicitly acquire the locking object of the
+@@ -725,6 +778,10 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int fwide (FILE *@var{stream}, int @var{mode})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{}}}
++@c Querying is always safe, but changing the stream when it's in use
++@c upthread may be problematic.  Like most lock-acquiring functions,
++@c this one may leak the lock if canceled.
+ 
+ The @code{fwide} function can be used to set and query the state of the
+ orientation of the stream @var{stream}.  If the @var{mode} parameter has
+@@ -811,6 +868,16 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fputc (int @var{c}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
++@c If the stream is in use when interrupted by a signal, the recursive
++@c lock won't help ensure the stream is consistent; indeed, if fputc
++@c gets a signal precisely before the post-incremented _IO_write_ptr
++@c value is stored, we may overwrite the interrupted write.  Conversely,
++@c depending on compiler optimizations, the incremented _IO_write_ptr
++@c may be stored before the character is stored in the buffer,
++@c corrupting the stream if async cancel hits between the two stores.
++@c There may be other reasons for AS- and AC-unsafety in the overflow
++@c cases.
+ The @code{fputc} function converts the character @var{c} to type
+ @code{unsigned char}, and writes it to the stream @var{stream}.
+ @code{EOF} is returned if a write error occurs; otherwise the
+@@ -820,6 +887,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun wint_t fputwc (wchar_t @var{wc}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+ The @code{fputwc} function writes the wide character @var{wc} to the
+ stream @var{stream}.  @code{WEOF} is returned if a write error occurs;
+ otherwise the character @var{wc} is returned.
+@@ -828,13 +896,18 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun int fputc_unlocked (int @var{c}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
++@c The unlocked functions can't possibly satisfy the MT-Safety
++@c requirements on their own, because they require external locking for
++@c safety.
+ The @code{fputc_unlocked} function is equivalent to the @code{fputc}
+ function except that it does not implicitly lock the stream.
+ @end deftypefun
+ 
+ @comment wchar.h
+ @comment POSIX
+-@deftypefun wint_t fputwc_unlocked (wint_t @var{wc}, FILE *@var{stream})
++@deftypefun wint_t fputwc_unlocked (wchar_t @var{wc}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fputwc_unlocked} function is equivalent to the @code{fputwc}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -844,6 +917,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int putc (int @var{c}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+ This is just like @code{fputc}, except that most systems implement it as
+ a macro, making it faster.  One consequence is that it may evaluate the
+ @var{stream} argument more than once, which is an exception to the
+@@ -854,6 +928,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun wint_t putwc (wchar_t @var{wc}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+ This is just like @code{fputwc}, except that it can be implement as
+ a macro, making it faster.  One consequence is that it may evaluate the
+ @var{stream} argument more than once, which is an exception to the
+@@ -864,6 +939,7 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun int putc_unlocked (int @var{c}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{putc_unlocked} function is equivalent to the @code{putc}
+ function except that it does not implicitly lock the stream.
+ @end deftypefun
+@@ -871,6 +947,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun wint_t putwc_unlocked (wchar_t @var{wc}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{putwc_unlocked} function is equivalent to the @code{putwc}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -880,6 +957,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int putchar (int @var{c})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+ The @code{putchar} function is equivalent to @code{putc} with
+ @code{stdout} as the value of the @var{stream} argument.
+ @end deftypefun
+@@ -887,6 +965,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun wint_t putwchar (wchar_t @var{wc})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+ The @code{putwchar} function is equivalent to @code{putwc} with
+ @code{stdout} as the value of the @var{stream} argument.
+ @end deftypefun
+@@ -894,6 +973,7 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun int putchar_unlocked (int @var{c})
++@safety{@prelim{}@mtunsafe{@mtasurace{:stdout}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{putchar_unlocked} function is equivalent to the @code{putchar}
+ function except that it does not implicitly lock the stream.
+ @end deftypefun
+@@ -901,6 +981,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun wint_t putwchar_unlocked (wchar_t @var{wc})
++@safety{@prelim{}@mtunsafe{@mtasurace{:stdout}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{putwchar_unlocked} function is equivalent to the @code{putwchar}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -910,6 +991,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fputs (const char *@var{s}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+ The function @code{fputs} writes the string @var{s} to the stream
+ @var{stream}.  The terminating null character is not written.
+ This function does @emph{not} add a newline character, either.
+@@ -933,6 +1015,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int fputws (const wchar_t *@var{ws}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+ The function @code{fputws} writes the wide character string @var{ws} to
+ the stream @var{stream}.  The terminating null character is not written.
+ This function does @emph{not} add a newline character, either.  It
+@@ -945,6 +1028,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int fputs_unlocked (const char *@var{s}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fputs_unlocked} function is equivalent to the @code{fputs}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -954,6 +1038,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun int fputws_unlocked (const wchar_t *@var{ws}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fputws_unlocked} function is equivalent to the @code{fputws}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -963,6 +1048,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int puts (const char *@var{s})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{puts} function writes the string @var{s} to the stream
+ @code{stdout} followed by a newline.  The terminating null character of
+ the string is not written.  (Note that @code{fputs} does @emph{not}
+@@ -982,6 +1068,7 @@
+ @comment stdio.h
+ @comment SVID
+ @deftypefun int putw (int @var{w}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function writes the word @var{w} (that is, an @code{int}) to
+ @var{stream}.  It is provided for compatibility with SVID, but we
+ recommend you use @code{fwrite} instead (@pxref{Block Input/Output}).
+@@ -1014,6 +1101,11 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fgetc (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
++@c Same caveats as fputc, but instead of losing a write in case of async
++@c signals, we may read the same character more than once, and the
++@c stream may be left in odd states due to cancellation in the underflow
++@c cases.
+ This function reads the next character as an @code{unsigned char} from
+ the stream @var{stream} and returns its value, converted to an
+ @code{int}.  If an end-of-file condition or read error occurs,
+@@ -1023,6 +1115,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun wint_t fgetwc (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function reads the next wide character from the stream @var{stream}
+ and returns its value.  If an end-of-file condition or read error
+ occurs, @code{WEOF} is returned instead.
+@@ -1031,6 +1124,7 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun int fgetc_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fgetc_unlocked} function is equivalent to the @code{fgetc}
+ function except that it does not implicitly lock the stream.
+ @end deftypefun
+@@ -1038,6 +1132,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun wint_t fgetwc_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fgetwc_unlocked} function is equivalent to the @code{fgetwc}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -1047,6 +1142,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int getc (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This is just like @code{fgetc}, except that it is permissible (and
+ typical) for it to be implemented as a macro that evaluates the
+ @var{stream} argument more than once.  @code{getc} is often highly
+@@ -1057,6 +1153,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun wint_t getwc (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This is just like @code{fgetwc}, except that it is permissible for it to
+ be implemented as a macro that evaluates the @var{stream} argument more
+ than once.  @code{getwc} can be highly optimized, so it is usually the
+@@ -1066,6 +1163,7 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun int getc_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{getc_unlocked} function is equivalent to the @code{getc}
+ function except that it does not implicitly lock the stream.
+ @end deftypefun
+@@ -1073,6 +1171,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun wint_t getwc_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{getwc_unlocked} function is equivalent to the @code{getwc}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -1082,6 +1181,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int getchar (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{getchar} function is equivalent to @code{getc} with @code{stdin}
+ as the value of the @var{stream} argument.
+ @end deftypefun
+@@ -1089,6 +1189,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun wint_t getwchar (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{getwchar} function is equivalent to @code{getwc} with @code{stdin}
+ as the value of the @var{stream} argument.
+ @end deftypefun
+@@ -1096,6 +1197,7 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun int getchar_unlocked (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:stdin}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{getchar_unlocked} function is equivalent to the @code{getchar}
+ function except that it does not implicitly lock the stream.
+ @end deftypefun
+@@ -1103,6 +1205,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun wint_t getwchar_unlocked (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:stdin}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{getwchar_unlocked} function is equivalent to the @code{getwchar}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -1145,6 +1248,7 @@
+ @comment stdio.h
+ @comment SVID
+ @deftypefun int getw (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function reads a word (that is, an @code{int}) from @var{stream}.
+ It's provided for compatibility with SVID.  We recommend you use
+ @code{fread} instead (@pxref{Block Input/Output}).  Unlike @code{getc},
+@@ -1173,6 +1277,12 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun ssize_t getline (char **@var{lineptr}, size_t *@var{n}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}}
++@c Besides the usual possibility of getting an inconsistent stream in a
++@c signal handler or leaving it inconsistent in case of cancellation,
++@c the possibility of leaving a dangling pointer upon cancellation
++@c between reallocing the buffer at *lineptr and updating the pointer
++@c brings about another case of @acucorrupt.
+ This function reads an entire line from @var{stream}, storing the text
+ (including the newline and a terminating null character) in a buffer
+ and storing the buffer address in @code{*@var{lineptr}}.
+@@ -1188,7 +1298,8 @@
+ 
+ If you set @code{*@var{lineptr}} to a null pointer, and @code{*@var{n}}
+ to zero, before the call, then @code{getline} allocates the initial
+-buffer for you by calling @code{malloc}.
++buffer for you by calling @code{malloc}.  This buffer remains allocated
++even if @code{getline} encounters errors and is unable to read any bytes.
+ 
+ In either case, when @code{getline} returns,  @code{*@var{lineptr}} is
+ a @code{char *} which points to the text of the line.
+@@ -1208,6 +1319,8 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun ssize_t getdelim (char **@var{lineptr}, size_t *@var{n}, int @var{delimiter}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}}
++@c See the getline @acucorrupt note.
+ This function is like @code{getline} except that the character which
+ tells it to stop reading is not necessarily newline.  The argument
+ @var{delimiter} specifies the delimiter character; @code{getdelim} keeps
+@@ -1232,6 +1345,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun {char *} fgets (char *@var{s}, int @var{count}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{fgets} function reads characters from the stream @var{stream}
+ up to and including a newline character and stores them in the string
+ @var{s}, adding a null character to mark the end of the string.  You
+@@ -1255,6 +1369,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} fgetws (wchar_t *@var{ws}, int @var{count}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{fgetws} function reads wide characters from the stream
+ @var{stream} up to and including a newline character and stores them in
+ the string @var{ws}, adding a null wide character to mark the end of the
+@@ -1280,6 +1395,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun {char *} fgets_unlocked (char *@var{s}, int @var{count}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fgets_unlocked} function is equivalent to the @code{fgets}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -1289,6 +1405,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun {wchar_t *} fgetws_unlocked (wchar_t *@var{ws}, int @var{count}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fgetws_unlocked} function is equivalent to the @code{fgetws}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -1298,6 +1415,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefn {Deprecated function} {char *} gets (char *@var{s})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The function @code{gets} reads characters from the stream @code{stdin}
+ up to the next newline character, and stores them in the string @var{s}.
+ The newline character is discarded (note that this differs from the
+@@ -1388,6 +1506,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int ungetc (int @var{c}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{ungetc} function pushes back the character @var{c} onto the
+ input stream @var{stream}.  So the next input from @var{stream} will
+ read @var{c} before anything else.
+@@ -1425,6 +1544,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun wint_t ungetwc (wint_t @var{wc}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{ungetwc} function behaves just like @code{ungetc} just that it
+ pushes back a wide character.
+ @end deftypefun
+@@ -1483,6 +1603,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun size_t fread (void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function reads up to @var{count} objects of size @var{size} into
+ the array @var{data}, from the stream @var{stream}.  It returns the
+ number of objects actually read, which might be less than @var{count} if
+@@ -1498,6 +1619,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun size_t fread_unlocked (void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fread_unlocked} function is equivalent to the @code{fread}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -1507,6 +1629,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun size_t fwrite (const void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function writes up to @var{count} objects of size @var{size} from
+ the array @var{data}, to the stream @var{stream}.  The return value is
+ normally @var{count}, if the call succeeds.  Any other value indicates
+@@ -1516,6 +1639,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun size_t fwrite_unlocked (const void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fwrite_unlocked} function is equivalent to the @code{fwrite}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -1670,7 +1794,7 @@
+ 
+ @defvr Macro NL_ARGMAX
+ The value of @code{NL_ARGMAX} is the maximum value allowed for the
+-specification of an positional parameter in a @code{printf} call.  The
++specification of a positional parameter in a @code{printf} call.  The
+ actual value in effect at runtime can be retrieved by using
+ @code{sysconf} using the @code{_SC_NL_ARGMAX} parameter @pxref{Sysconf
+ Definition}.
+@@ -2257,6 +2381,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int printf (const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ The @code{printf} function prints the optional arguments under the
+ control of the template string @var{template} to the stream
+ @code{stdout}.  It returns the number of characters printed, or a
+@@ -2266,6 +2391,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int wprintf (const wchar_t *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ The @code{wprintf} function prints the optional arguments under the
+ control of the wide template string @var{template} to the stream
+ @code{stdout}.  It returns the number of wide characters printed, or a
+@@ -2275,6 +2401,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fprintf (FILE *@var{stream}, const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This function is just like @code{printf}, except that the output is
+ written to the stream @var{stream} instead of @code{stdout}.
+ @end deftypefun
+@@ -2282,6 +2409,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int fwprintf (FILE *@var{stream}, const wchar_t *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This function is just like @code{wprintf}, except that the output is
+ written to the stream @var{stream} instead of @code{stdout}.
+ @end deftypefun
+@@ -2289,6 +2417,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int sprintf (char *@var{s}, const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is like @code{printf}, except that the output is stored in the character
+ array @var{s} instead of written to a stream.  A null character is written
+ to mark the end of the string.
+@@ -2313,6 +2442,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun int swprintf (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is like @code{wprintf}, except that the output is stored in the
+ wide character array @var{ws} instead of written to a stream.  A null
+ wide character is written to mark the end of the string.  The @var{size}
+@@ -2330,13 +2460,14 @@
+ parameters.  @code{swprintf} in fact corresponds to the @code{snprintf}
+ function.  Since the @code{sprintf} function can be dangerous and should
+ be avoided the @w{ISO C} committee refused to make the same mistake
+-again and decided to not define an function exactly corresponding to
++again and decided to not define a function exactly corresponding to
+ @code{sprintf}.
+ @end deftypefun
+ 
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int snprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The @code{snprintf} function is similar to @code{sprintf}, except that
+ the @var{size} argument specifies the maximum number of characters to
+ produce.  The trailing null character is counted towards this limit, so
+@@ -2407,6 +2538,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int asprintf (char **@var{ptr}, const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This function is similar to @code{sprintf}, except that it dynamically
+ allocates a string (as with @code{malloc}; @pxref{Unconstrained
+ Allocation}) to hold the output, instead of putting the output in a
+@@ -2416,7 +2548,7 @@
+ location.
+ 
+ The return value is the number of characters allocated for the buffer, or
+-less than zero if an error occurred. Usually this means that the buffer
++less than zero if an error occurred.  Usually this means that the buffer
+ could not be allocated.
+ 
+ Here is how to use @code{asprintf} to get the same result as the
+@@ -2439,6 +2571,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int obstack_printf (struct obstack *@var{obstack}, const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+ This function is similar to @code{asprintf}, except that it uses the
+ obstack @var{obstack} to allocate the space.  @xref{Obstacks}.
+ 
+@@ -2509,6 +2642,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int vprintf (const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This function is similar to @code{printf} except that, instead of taking
+ a variable number of arguments directly, it takes an argument list
+ pointer @var{ap}.
+@@ -2517,6 +2651,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int vwprintf (const wchar_t *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This function is similar to @code{wprintf} except that, instead of taking
+ a variable number of arguments directly, it takes an argument list
+ pointer @var{ap}.
+@@ -2525,6 +2660,48 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int vfprintf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
++@c Although vfprintf sets up a cleanup region to release the lock on the
++@c output stream, it doesn't use it to release args_value or string in
++@c case of cancellation.  This doesn't make it unsafe, but cancelling it
++@c may leak memory.  The unguarded use of __printf_function_table is
++@c also of concern for all callers.
++@c _itoa ok
++@c   _udiv_qrnnd_preinv ok
++@c group_number ok
++@c _i18n_number_rewrite
++@c   __wctrans ok
++@c   __towctrans @mtslocale
++@c   __wcrtomb ok? dup below
++@c   outdigit_value ok
++@c   outdigitwc_value ok
++@c outchar ok
++@c outstring ok
++@c PAD ok
++@c __printf_fp @mtslocale @ascuheap @acsmem
++@c __printf_fphex @mtslocale
++@c __readonly_area
++@c   [GNU/Linux] fopen, strtoul, free
++@c __strerror_r ok if no translation, check otherwise
++@c __btowc ? gconv-modules
++@c __wcrtomb ok (not using internal state) gconv-modules
++@c ARGCHECK
++@c UNBUFFERED_P (tested before taking the stream lock)
++@c buffered_vfprintf ok
++@c __find_spec(wc|mb)
++@c read_int
++@c __libc_use_alloca
++@c process_arg
++@c process_string_arg
++@c extend_alloca
++@c __parse_one_spec(wc|mb)
++@c *__printf_arginfo_table unguarded
++@c __printf_va_arg_table-> unguarded
++@c *__printf_function_table unguarded
++@c done_add
++@c printf_unknown
++@c   outchar
++@c   _itoa_word
+ This is the equivalent of @code{fprintf} with the variable argument list
+ specified directly as for @code{vprintf}.
+ @end deftypefun
+@@ -2532,6 +2709,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int vfwprintf (FILE *@var{stream}, const wchar_t *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This is the equivalent of @code{fwprintf} with the variable argument list
+ specified directly as for @code{vwprintf}.
+ @end deftypefun
+@@ -2539,6 +2717,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int vsprintf (char *@var{s}, const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is the equivalent of @code{sprintf} with the variable argument list
+ specified directly as for @code{vprintf}.
+ @end deftypefun
+@@ -2546,6 +2725,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun int vswprintf (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is the equivalent of @code{swprintf} with the variable argument list
+ specified directly as for @code{vwprintf}.
+ @end deftypefun
+@@ -2553,6 +2733,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int vsnprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is the equivalent of @code{snprintf} with the variable argument list
+ specified directly as for @code{vprintf}.
+ @end deftypefun
+@@ -2560,6 +2741,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int vasprintf (char **@var{ptr}, const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The @code{vasprintf} function is the equivalent of @code{asprintf} with the
+ variable argument list specified directly as for @code{vprintf}.
+ @end deftypefun
+@@ -2567,6 +2749,10 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int obstack_vprintf (struct obstack *@var{obstack}, const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtsrace{:obstack} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c The obstack is not guarded by mutexes, it might be at an inconsistent
++@c state within a signal handler, and it could be left at an
++@c inconsistent state in case of cancellation.
+ The @code{obstack_vprintf} function is the equivalent of
+ @code{obstack_printf} with the variable argument list specified directly
+ as for @code{vprintf}.@refill
+@@ -2639,6 +2825,7 @@
+ @comment printf.h
+ @comment GNU
+ @deftypefun size_t parse_printf_format (const char *@var{template}, size_t @var{n}, int *@var{argtypes})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ This function returns information about the number and types of
+ arguments expected by the @code{printf} template string @var{template}.
+ The information is stored in the array @var{argtypes}; each element of
+@@ -2879,6 +3066,12 @@
+ @comment printf.h
+ @comment GNU
+ @deftypefun int register_printf_function (int @var{spec}, printf_function @var{handler-function}, printf_arginfo_function @var{arginfo-function})
++@safety{@prelim{}@mtunsafe{@mtasuconst{:printfext}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}}
++@c This function is guarded by the global non-recursive libc lock, but
++@c users of the variables it sets aren't, and those should be MT-Safe,
++@c so we're ruling out the use of this extension with threads.  Calling
++@c it from a signal handler may self-deadlock, and cancellation may
++@c leave the lock held, besides leaking allocated memory.
+ This function defines the conversion specifier character @var{spec}.
+ Thus, if @var{spec} is @code{'Y'}, it defines the conversion @samp{%Y}.
+ You can redefine the built-in conversions like @samp{%s}, but flag
+@@ -3125,6 +3318,12 @@
+ @comment printf.h
+ @comment GNU
+ @deftypefun int printf_size (FILE *@var{fp}, const struct printf_info *@var{info}, const void *const *@var{args})
++@safety{@prelim{}@mtsafe{@mtsrace{:fp} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @acucorrupt{}}}
++@c This is meant to be called by vfprintf, that should hold the lock on
++@c the stream, but if this function is called directly, output will be
++@c racy, besides the uses of the global locale object while other
++@c threads may be changing it and the possbility of leaving the stream
++@c object in an inconsistent state in case of cancellation.
+ Print a given floating point number as for the format @code{%f} except
+ that there is a postfix character indicating the divisor for the
+ number to make this less than 1000.  There are two possible divisors:
+@@ -3183,6 +3382,7 @@
+ @comment printf.h
+ @comment GNU
+ @deftypefun int printf_size_info (const struct printf_info *@var{info}, size_t @var{n}, int *@var{argtypes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function will return in @var{argtypes} the information about the
+ used parameters in the way the @code{vfprintf} implementation expects
+ it.  The format always takes one argument.
+@@ -3672,7 +3872,7 @@
+ To read in characters that belong to an arbitrary set of your choice,
+ use the @samp{%[} conversion.  You specify the set between the @samp{[}
+ character and a following @samp{]} character, using the same syntax used
+-in regular expressions.  As special cases:
++in regular expressions for explicit sets of characters.  As special cases:
+ 
+ @itemize @bullet
+ @item
+@@ -3692,6 +3892,10 @@
+ The @samp{%[} conversion does not skip over initial whitespace
+ characters.
+ 
++Note that the @dfn{character class} syntax available in character sets
++that appear inside regular expressions (such as @samp{[:alpha:]}) is
++@emph{not} available in the @samp{%[} conversion.
++
+ Here are some examples of @samp{%[} conversions and what they mean:
+ 
+ @table @samp
+@@ -3799,6 +4003,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int scanf (const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ The @code{scanf} function reads formatted input from the stream
+ @code{stdin} under the control of the template string @var{template}.
+ The optional arguments are pointers to the places which receive the
+@@ -3813,6 +4018,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int wscanf (const wchar_t *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ The @code{wscanf} function reads formatted input from the stream
+ @code{stdin} under the control of the template string @var{template}.
+ The optional arguments are pointers to the places which receive the
+@@ -3827,6 +4033,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fscanf (FILE *@var{stream}, const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This function is just like @code{scanf}, except that the input is read
+ from the stream @var{stream} instead of @code{stdin}.
+ @end deftypefun
+@@ -3834,6 +4041,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int fwscanf (FILE *@var{stream}, const wchar_t *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This function is just like @code{wscanf}, except that the input is read
+ from the stream @var{stream} instead of @code{stdin}.
+ @end deftypefun
+@@ -3841,6 +4049,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int sscanf (const char *@var{s}, const char *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is like @code{scanf}, except that the characters are taken from the
+ null-terminated string @var{s} instead of from a stream.  Reaching the
+ end of the string is treated as an end-of-file condition.
+@@ -3853,7 +4062,8 @@
+ 
+ @comment wchar.h
+ @comment ISO
+-@deftypefun int swscanf (const wchar_t *@var{ws}, const char *@var{template}, @dots{})
++@deftypefun int swscanf (const wchar_t *@var{ws}, const wchar_t *@var{template}, @dots{})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is like @code{wscanf}, except that the characters are taken from the
+ null-terminated string @var{ws} instead of from a stream.  Reaching the
+ end of the string is treated as an end-of-file condition.
+@@ -3880,6 +4090,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int vscanf (const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This function is similar to @code{scanf}, but instead of taking
+ a variable number of arguments directly, it takes an argument list
+ pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}).
+@@ -3888,6 +4099,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int vwscanf (const wchar_t *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This function is similar to @code{wscanf}, but instead of taking
+ a variable number of arguments directly, it takes an argument list
+ pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}).
+@@ -3896,6 +4108,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int vfscanf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This is the equivalent of @code{fscanf} with the variable argument list
+ specified directly as for @code{vscanf}.
+ @end deftypefun
+@@ -3903,6 +4116,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int vfwscanf (FILE *@var{stream}, const wchar_t *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+ This is the equivalent of @code{fwscanf} with the variable argument list
+ specified directly as for @code{vwscanf}.
+ @end deftypefun
+@@ -3910,6 +4124,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int vsscanf (const char *@var{s}, const char *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is the equivalent of @code{sscanf} with the variable argument list
+ specified directly as for @code{vscanf}.
+ @end deftypefun
+@@ -3917,6 +4132,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int vswscanf (const wchar_t *@var{s}, const wchar_t *@var{template}, va_list @var{ap})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This is the equivalent of @code{swscanf} with the variable argument list
+ specified directly as for @code{vwscanf}.
+ @end deftypefun
+@@ -3966,6 +4182,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int feof (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
+ The @code{feof} function returns nonzero if and only if the end-of-file
+ indicator for the stream @var{stream} is set.
+ 
+@@ -3975,6 +4192,9 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int feof_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c There isn't much of a thread unsafety risk in reading a flag word and
++@c testing a bit in it.
+ The @code{feof_unlocked} function is equivalent to the @code{feof}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -3986,6 +4206,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int ferror (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
+ The @code{ferror} function returns nonzero if and only if the error
+ indicator for the stream @var{stream} is set, indicating that an error
+ has occurred on a previous operation on the stream.
+@@ -3996,6 +4217,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun int ferror_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{ferror_unlocked} function is equivalent to the @code{ferror}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -4023,6 +4245,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun void clearerr (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
+ This function clears the end-of-file and error indicators for the
+ stream @var{stream}.
+ 
+@@ -4033,6 +4256,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun void clearerr_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@assafe{}@acsafe{}}
+ The @code{clearerr_unlocked} function is equivalent to the @code{clearerr}
+ function except that it does not implicitly lock the stream.
+ 
+@@ -4146,6 +4370,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun {long int} ftell (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function returns the current file position of the stream
+ @var{stream}.
+ 
+@@ -4158,6 +4383,7 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun off_t ftello (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{ftello} function is similar to @code{ftell}, except that it
+ returns a value of type @code{off_t}.  Systems which support this type
+ use it to describe all file positions, unlike the POSIX specification
+@@ -4181,6 +4407,7 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun off64_t ftello64 (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function is similar to @code{ftello} with the only difference that
+ the return value is of type @code{off64_t}.  This also requires that the
+ stream @var{stream} was opened using either @code{fopen64},
+@@ -4196,6 +4423,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fseek (FILE *@var{stream}, long int @var{offset}, int @var{whence})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{fseek} function is used to change the file position of the
+ stream @var{stream}.  The value of @var{whence} must be one of the
+ constants @code{SEEK_SET}, @code{SEEK_CUR}, or @code{SEEK_END}, to
+@@ -4215,6 +4443,7 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun int fseeko (FILE *@var{stream}, off_t @var{offset}, int @var{whence})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function is similar to @code{fseek} but it corrects a problem with
+ @code{fseek} in a system with POSIX types.  Using a value of type
+ @code{long int} for the offset is not compatible with POSIX.
+@@ -4238,6 +4467,7 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun int fseeko64 (FILE *@var{stream}, off64_t @var{offset}, int @var{whence})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function is similar to @code{fseeko} with the only difference that
+ the @var{offset} parameter is of type @code{off64_t}.  This also
+ requires that the stream @var{stream} was opened using either
+@@ -4286,6 +4516,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun void rewind (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{rewind} function positions the stream @var{stream} at the
+ beginning of the file.  It is equivalent to calling @code{fseek} or
+ @code{fseeko} on the @var{stream} with an @var{offset} argument of
+@@ -4407,6 +4638,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fgetpos (FILE *@var{stream}, fpos_t *@var{position})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function stores the value of the file position indicator for the
+ stream @var{stream} in the @code{fpos_t} object pointed to by
+ @var{position}.  If successful, @code{fgetpos} returns zero; otherwise
+@@ -4421,6 +4653,7 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun int fgetpos64 (FILE *@var{stream}, fpos64_t *@var{position})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function is similar to @code{fgetpos} but the file position is
+ returned in a variable of type @code{fpos64_t} to which @var{position}
+ points.
+@@ -4433,6 +4666,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fsetpos (FILE *@var{stream}, const fpos_t *@var{position})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function sets the file position indicator for the stream @var{stream}
+ to the position @var{position}, which must have been set by a previous
+ call to @code{fgetpos} on the same stream.  If successful, @code{fsetpos}
+@@ -4449,6 +4683,7 @@
+ @comment stdio.h
+ @comment Unix98
+ @deftypefun int fsetpos64 (FILE *@var{stream}, const fpos64_t *@var{position})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function is similar to @code{fsetpos} but the file position used
+ for positioning is provided in a variable of type @code{fpos64_t} to
+ which @var{position} points.
+@@ -4560,6 +4795,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int fflush (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function causes any buffered output on @var{stream} to be delivered
+ to the file.  If @var{stream} is a null pointer, then
+ @code{fflush} causes buffered output on @emph{all} open output streams
+@@ -4572,6 +4808,7 @@
+ @comment stdio.h
+ @comment POSIX
+ @deftypefun int fflush_unlocked (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{fflush_unlocked} function is equivalent to the @code{fflush}
+ function except that it does not implicitly lock the stream.
+ @end deftypefun
+@@ -4588,6 +4825,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun void _flushlbf (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ The @code{_flushlbf} function flushes all line buffered streams
+ currently opened.
+ 
+@@ -4609,6 +4847,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun void __fpurge (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+ The @code{__fpurge} function causes the buffer of the stream
+ @var{stream} to be emptied.  If the stream is currently in read mode all
+ input in the buffer is lost.  If the stream is in output mode the
+@@ -4633,6 +4872,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun int setvbuf (FILE *@var{stream}, char *@var{buf}, int @var{mode}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function is used to specify that the stream @var{stream} should
+ have the buffering mode @var{mode}, which can be either @code{_IOFBF}
+ (for full buffering), @code{_IOLBF} (for line buffering), or
+@@ -4710,6 +4950,7 @@
+ @comment stdio.h
+ @comment ISO
+ @deftypefun void setbuf (FILE *@var{stream}, char *@var{buf})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ If @var{buf} is a null pointer, the effect of this function is
+ equivalent to calling @code{setvbuf} with a @var{mode} argument of
+ @code{_IONBF}.  Otherwise, it is equivalent to calling @code{setvbuf}
+@@ -4723,6 +4964,7 @@
+ @comment stdio.h
+ @comment BSD
+ @deftypefun void setbuffer (FILE *@var{stream}, char *@var{buf}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ If @var{buf} is a null pointer, this function makes @var{stream} unbuffered.
+ Otherwise, it makes @var{stream} fully buffered using @var{buf} as the
+ buffer.  The @var{size} argument specifies the length of @var{buf}.
+@@ -4734,6 +4976,7 @@
+ @comment stdio.h
+ @comment BSD
+ @deftypefun void setlinebuf (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+ This function makes @var{stream} be line buffered, and allocates the
+ buffer for you.
+ 
+@@ -4748,6 +4991,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun int __flbf (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{__flbf} function will return a nonzero value in case the
+ stream @var{stream} is line buffered.  Otherwise the return value is
+ zero.
+@@ -4761,6 +5005,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun size_t __fbufsize (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acsafe{}}
+ The @code{__fbufsize} function return the size of the buffer in the
+ stream @var{stream}.  This value can be used to optimize the use of the
+ stream.
+@@ -4771,6 +5016,7 @@
+ @comment stdio_ext.h
+ @comment GNU
+ @deftypefun size_t __fpending (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acsafe{}}
+ The @code{__fpending}
+ function returns the number of bytes currently in the output buffer.
+ For wide-oriented stream the measuring unit is wide characters.  This
+@@ -4818,6 +5064,10 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun {FILE *} fmemopen (void *@var{buf}, size_t @var{size}, const char *@var{opentype})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}}
++@c Unlike open_memstream, fmemopen does (indirectly) call _IO_link_in,
++@c bringing with it additional potential for async trouble with
++@c list_all_lock.
+ This function opens a stream that allows the access specified by the
+ @var{opentype} argument, that reads from or writes to the buffer specified
+ by the argument @var{buf}.  This array must be at least @var{size} bytes long.
+@@ -4870,6 +5120,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun {FILE *} open_memstream (char **@var{ptr}, size_t *@var{sizeloc})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This function opens a stream for writing to a buffer.  The buffer is
+ allocated dynamically and grown as necessary, using @code{malloc}.
+ After you've closed the stream, this buffer is your responsibility to
+@@ -4985,6 +5236,7 @@
+ @comment stdio.h
+ @comment GNU
+ @deftypefun {FILE *} fopencookie (void *@var{cookie}, const char *@var{opentype}, cookie_io_functions_t @var{io-functions})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}}
+ This function actually creates the stream for communicating with the
+ @var{cookie} using the functions in the @var{io-functions} argument.
+ The @var{opentype} argument is interpreted as for @code{fopen};
+@@ -5053,26 +5305,26 @@
+ 
+ @comment stdio.h
+ @comment GNU
+-@deftp {Data Type} cookie_read_function
++@deftp {Data Type} cookie_read_function_t
+ This is the data type that the read function for a custom stream should have.
+ If you declare the function as shown above, this is the type it will have.
+ @end deftp
+ 
+ @comment stdio.h
+ @comment GNU
+-@deftp {Data Type} cookie_write_function
++@deftp {Data Type} cookie_write_function_t
+ The data type of the write function for a custom stream.
+ @end deftp
+ 
+ @comment stdio.h
+ @comment GNU
+-@deftp {Data Type} cookie_seek_function
++@deftp {Data Type} cookie_seek_function_t
+ The data type of the seek function for a custom stream.
+ @end deftp
+ 
+ @comment stdio.h
+ @comment GNU
+-@deftp {Data Type} cookie_close_function
++@deftp {Data Type} cookie_close_function_t
+ The data type of the close function for a custom stream.
+ @end deftp
+ 
+@@ -5166,6 +5418,7 @@
+ @comment fmtmsg.h
+ @comment XPG
+ @deftypefun int fmtmsg (long int @var{classification}, const char *@var{label}, int @var{severity}, const char *@var{text}, const char *@var{action}, const char *@var{tag})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acsafe{}}
+ Display a message described by its parameters on the device(s) specified
+ in the @var{classification} parameter.  The @var{label} parameter
+ identifies the source of the message.  The string should consist of two
+@@ -5306,6 +5559,7 @@
+ but this is toilsome.
+ 
+ @deftypefun int addseverity (int @var{severity}, const char *@var{string})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
+ This function allows the introduction of new severity classes which can be
+ addressed by the @var{severity} parameter of the @code{fmtmsg} function.
+ The @var{severity} parameter of @code{addseverity} must match the value
+diff -urN glibc-2.17-c758a686/manual/string.texi glibc/manual/string.texi
+--- glibc-2.17-c758a686/manual/string.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/string.texi	2014-09-12 16:10:06.045792717 -0400
+@@ -200,7 +200,7 @@
+ @cindex parameter promotion
+ Some of the memory and string functions take single characters as
+ arguments.  Since a value of type @code{char} is automatically promoted
+-into an value of type @code{int} when used as a parameter, the functions
++into a value of type @code{int} when used as a parameter, the functions
+ are declared with @code{int} as the type of the parameter in question.
+ In case of the wide character function the situation is similarly: the
+ parameter type for a single wide character is @code{wint_t} and not
+@@ -219,6 +219,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun size_t strlen (const char *@var{s})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{strlen} function returns the length of the null-terminated
+ string @var{s} in bytes.  (In other words, it returns the offset of the
+ terminating null character within the array.)
+@@ -285,6 +286,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t wcslen (const wchar_t *@var{ws})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{wcslen} function is the wide character equivalent to
+ @code{strlen}.  The return value is the number of wide characters in the
+ wide character string pointed to by @var{ws} (this is also the offset of
+@@ -300,6 +302,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun size_t strnlen (const char *@var{s}, size_t @var{maxlen})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{strnlen} function returns the length of the string @var{s} in
+ bytes if this length is smaller than @var{maxlen} bytes.  Otherwise it
+ returns @var{maxlen}.  Therefore this function is equivalent to
+@@ -322,6 +325,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun size_t wcsnlen (const wchar_t *@var{ws}, size_t @var{maxlen})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{wcsnlen} is the wide character equivalent to @code{strnlen}.  The
+ @var{maxlen} parameter specifies the maximum number of wide characters.
+ 
+@@ -367,6 +371,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {void *} memcpy (void *restrict @var{to}, const void *restrict @var{from}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{memcpy} function copies @var{size} bytes from the object
+ beginning at @var{from} into the object beginning at @var{to}.  The
+ behavior of this function is undefined if the two arrays @var{to} and
+@@ -388,6 +393,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wmemcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{wmemcpy} function copies @var{size} wide characters from the object
+ beginning at @var{wfrom} into the object beginning at @var{wto}.  The
+ behavior of this function is undefined if the two arrays @var{wto} and
+@@ -413,6 +419,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {void *} mempcpy (void *restrict @var{to}, const void *restrict @var{from}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{mempcpy} function is nearly identical to the @code{memcpy}
+ function.  It copies @var{size} bytes from the object beginning at
+ @code{from} into the object pointed to by @var{to}.  But instead of
+@@ -440,6 +447,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun {wchar_t *} wmempcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{wmempcpy} function is nearly identical to the @code{wmemcpy}
+ function.  It copies @var{size} wide characters from the object
+ beginning at @code{wfrom} into the object pointed to by @var{wto}.  But
+@@ -468,6 +476,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {void *} memmove (void *@var{to}, const void *@var{from}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{memmove} copies the @var{size} bytes at @var{from} into the
+ @var{size} bytes at @var{to}, even if those two blocks of space
+ overlap.  In the case of overlap, @code{memmove} is careful to copy the
+@@ -479,7 +488,8 @@
+ 
+ @comment wchar.h
+ @comment ISO
+-@deftypefun {wchar_t *} wmemmove (wchar *@var{wto}, const wchar_t *@var{wfrom}, size_t @var{size})
++@deftypefun {wchar_t *} wmemmove (wchar_t *@var{wto}, const wchar_t *@var{wfrom}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{wmemmove} copies the @var{size} wide characters at @var{wfrom}
+ into the @var{size} wide characters at @var{wto}, even if those two
+ blocks of space overlap.  In the case of overlap, @code{memmove} is
+@@ -507,6 +517,7 @@
+ @comment string.h
+ @comment SVID
+ @deftypefun {void *} memccpy (void *restrict @var{to}, const void *restrict @var{from}, int @var{c}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function copies no more than @var{size} bytes from @var{from} to
+ @var{to}, stopping if a byte matching @var{c} is found.  The return
+ value is a pointer into @var{to} one byte past where @var{c} was copied,
+@@ -517,6 +528,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {void *} memset (void *@var{block}, int @var{c}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function copies the value of @var{c} (converted to an
+ @code{unsigned char}) into each of the first @var{size} bytes of the
+ object beginning at @var{block}.  It returns the value of @var{block}.
+@@ -525,6 +537,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wmemset (wchar_t *@var{block}, wchar_t @var{wc}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function copies the value of @var{wc} into each of the first
+ @var{size} wide characters of the object beginning at @var{block}.  It
+ returns the value of @var{block}.
+@@ -533,6 +546,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strcpy (char *restrict @var{to}, const char *restrict @var{from})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This copies characters from the string @var{from} (up to and including
+ the terminating null character) into the string @var{to}.  Like
+ @code{memcpy}, this function has undefined results if the strings
+@@ -542,6 +556,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wcscpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This copies wide characters from the string @var{wfrom} (up to and
+ including the terminating null wide character) into the string
+ @var{wto}.  Like @code{wmemcpy}, this function has undefined results if
+@@ -551,6 +566,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strncpy (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{strcpy} but always copies exactly
+ @var{size} characters into @var{to}.
+ 
+@@ -576,6 +592,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wcsncpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{wcscpy} but always copies exactly
+ @var{size} wide characters into @var{wto}.
+ 
+@@ -602,6 +619,7 @@
+ @comment string.h
+ @comment SVID
+ @deftypefun {char *} strdup (const char *@var{s})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This function copies the null-terminated string @var{s} into a newly
+ allocated string.  The string is allocated using @code{malloc}; see
+ @ref{Unconstrained Allocation}.  If @code{malloc} cannot allocate space
+@@ -612,6 +630,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun {wchar_t *} wcsdup (const wchar_t *@var{ws})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This function copies the null-terminated wide character string @var{ws}
+ into a newly allocated string.  The string is allocated using
+ @code{malloc}; see @ref{Unconstrained Allocation}.  If @code{malloc}
+@@ -625,6 +644,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {char *} strndup (const char *@var{s}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ This function is similar to @code{strdup} but always copies at most
+ @var{size} characters into the newly allocated string.
+ 
+@@ -642,6 +662,7 @@
+ @comment string.h
+ @comment Unknown origin
+ @deftypefun {char *} stpcpy (char *restrict @var{to}, const char *restrict @var{from})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is like @code{strcpy}, except that it returns a pointer to
+ the end of the string @var{to} (that is, the address of the terminating
+ null character @code{to + strlen (from)}) rather than the beginning.
+@@ -664,6 +685,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun {wchar_t *} wcpcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is like @code{wcscpy}, except that it returns a pointer to
+ the end of the string @var{wto} (that is, the address of the terminating
+ null character @code{wto + strlen (wfrom)}) rather than the beginning.
+@@ -679,10 +701,11 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {char *} stpncpy (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{stpcpy} but copies always exactly
+ @var{size} characters into @var{to}.
+ 
+-If the length of @var{from} is more then @var{size}, then @code{stpncpy}
++If the length of @var{from} is more than @var{size}, then @code{stpncpy}
+ copies just the first @var{size} characters and returns a pointer to the
+ character directly following the one which was copied last.  Note that in
+ this case there is no null terminator written into @var{to}.
+@@ -704,10 +727,11 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun {wchar_t *} wcpncpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{wcpcpy} but copies always exactly
+ @var{wsize} characters into @var{wto}.
+ 
+-If the length of @var{wfrom} is more then @var{size}, then
++If the length of @var{wfrom} is more than @var{size}, then
+ @code{wcpncpy} copies just the first @var{size} wide characters and
+ returns a pointer to the wide character directly following the last
+ non-null wide character which was copied last.  Note that in this case
+@@ -731,6 +755,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefn {Macro} {char *} strdupa (const char *@var{s})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This macro is similar to @code{strdup} but allocates the new string
+ using @code{alloca} instead of @code{malloc} (@pxref{Variable Size
+ Automatic}).  This means of course the returned string has the same
+@@ -757,6 +782,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefn {Macro} {char *} strndupa (const char *@var{s}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is similar to @code{strndup} but like @code{strdupa} it
+ allocates the new string using @code{alloca}
+ @pxref{Variable Size Automatic}.  The same advantages and limitations
+@@ -772,6 +798,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strcat (char *restrict @var{to}, const char *restrict @var{from})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{strcat} function is similar to @code{strcpy}, except that the
+ characters from @var{from} are concatenated or appended to the end of
+ @var{to}, instead of overwriting it.  That is, the first character from
+@@ -794,6 +821,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wcscat (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{wcscat} function is similar to @code{wcscpy}, except that the
+ characters from @var{wfrom} are concatenated or appended to the end of
+ @var{wto}, instead of overwriting it.  That is, the first character from
+@@ -942,6 +970,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strncat (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is like @code{strcat} except that not more than @var{size}
+ characters from @var{from} are appended to the end of @var{to}.  A
+ single null character is also always appended to @var{to}, so the total
+@@ -955,8 +984,8 @@
+ char *
+ strncat (char *to, const char *from, size_t size)
+ @{
+-  to[strlen (to) + size] = '\0';
+-  strncpy (to + strlen (to), from, size);
++  memcpy (to + strlen (to), from, strnlen (from, size));
++  to[strlen (to) + strnlen (from, size)] = '\0';
+   return to;
+ @}
+ @end group
+@@ -968,6 +997,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wcsncat (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is like @code{wcscat} except that not more than @var{size}
+ characters from @var{from} are appended to the end of @var{to}.  A
+ single null character is also always appended to @var{to}, so the total
+@@ -982,8 +1012,8 @@
+ wcsncat (wchar_t *restrict wto, const wchar_t *restrict wfrom,
+          size_t size)
+ @{
+-  wto[wcslen (to) + size] = L'\0';
+-  wcsncpy (wto + wcslen (wto), wfrom, size);
++  memcpy (wto + wcslen (wto), wfrom, wcsnlen (wfrom, size) * sizeof (wchar_t));
++  wto[wcslen (to) + wcsnlen (wfrom, size)] = '\0';
+   return wto;
+ @}
+ @end group
+@@ -1012,6 +1042,7 @@
+ @comment string.h
+ @comment BSD
+ @deftypefun void bcopy (const void *@var{from}, void *@var{to}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is a partially obsolete alternative for @code{memmove}, derived from
+ BSD.  Note that it is not quite equivalent to @code{memmove}, because the
+ arguments are not in the same order and there is no return value.
+@@ -1020,6 +1051,7 @@
+ @comment string.h
+ @comment BSD
+ @deftypefun void bzero (void *@var{block}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is a partially obsolete alternative for @code{memset}, derived from
+ BSD.  Note that it is not as general as @code{memset}, because the only
+ value it can store is zero.
+@@ -1055,6 +1087,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun int memcmp (const void *@var{a1}, const void *@var{a2}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The function @code{memcmp} compares the @var{size} bytes of memory
+ beginning at @var{a1} against the @var{size} bytes of memory beginning
+ at @var{a2}.  The value returned has the same sign as the difference
+@@ -1065,9 +1098,10 @@
+ @code{0}.
+ @end deftypefun
+ 
+-@comment wcjar.h
++@comment wchar.h
+ @comment ISO
+ @deftypefun int wmemcmp (const wchar_t *@var{a1}, const wchar_t *@var{a2}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The function @code{wmemcmp} compares the @var{size} wide characters
+ beginning at @var{a1} against the @var{size} wide characters beginning
+ at @var{a2}.  The value returned is smaller than or larger than zero
+@@ -1120,6 +1154,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun int strcmp (const char *@var{s1}, const char *@var{s2})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{strcmp} function compares the string @var{s1} against
+ @var{s2}, returning a value that has the same sign as the difference
+ between the first differing pair of characters (interpreted as
+@@ -1139,6 +1174,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int wcscmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ The @code{wcscmp} function compares the wide character string @var{ws1}
+ against @var{ws2}.  The value returned is smaller than or larger than zero
+@@ -1159,6 +1195,11 @@
+ @comment string.h
+ @comment BSD
+ @deftypefun int strcasecmp (const char *@var{s1}, const char *@var{s2})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c Although this calls tolower multiple times, it's a macro, and
++@c strcasecmp is optimized so that the locale pointer is read only once.
++@c There are some asm implementations too, for which the single-read
++@c from locale TLS pointers also applies.
+ This function is like @code{strcmp}, except that differences in case are
+ ignored.  How uppercase and lowercase characters are related is
+ determined by the currently selected locale.  In the standard @code{"C"}
+@@ -1171,7 +1212,10 @@
+ 
+ @comment wchar.h
+ @comment GNU
+-@deftypefun int wcscasecmp (const wchar_t *@var{ws1}, const wchar_T *@var{ws2})
++@deftypefun int wcscasecmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c Since towlower is not a macro, the locale object may be read multiple
++@c times.
+ This function is like @code{wcscmp}, except that differences in case are
+ ignored.  How uppercase and lowercase characters are related is
+ determined by the currently selected locale.  In the standard @code{"C"}
+@@ -1185,6 +1229,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun int strncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is the similar to @code{strcmp}, except that no more than
+ @var{size} characters are compared.  In other words, if the two
+ strings are the same in their first @var{size} characters, the
+@@ -1194,6 +1239,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int wcsncmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function is the similar to @code{wcscmp}, except that no more than
+ @var{size} wide characters are compared.  In other words, if the two
+ strings are the same in their first @var{size} wide characters, the
+@@ -1203,6 +1249,7 @@
+ @comment string.h
+ @comment BSD
+ @deftypefun int strncasecmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ This function is like @code{strncmp}, except that differences in case
+ are ignored.  Like @code{strcasecmp}, it is locale dependent how
+ uppercase and lowercase characters are related.
+@@ -1214,6 +1261,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun int wcsncasecmp (const wchar_t *@var{ws1}, const wchar_t *@var{s2}, size_t @var{n})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+ This function is like @code{wcsncmp}, except that differences in case
+ are ignored.  Like @code{wcscasecmp}, it is locale dependent how
+ uppercase and lowercase characters are related.
+@@ -1247,6 +1295,8 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun int strverscmp (const char *@var{s1}, const char *@var{s2})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c Calls isdigit multiple times, locale may change in between.
+ The @code{strverscmp} function compares the string @var{s1} against
+ @var{s2}, considering them as holding indices/version numbers.  The
+ return value follows the same conventions as found in the
+@@ -1258,7 +1308,7 @@
+ mode, where each sequence of digits is taken as a whole.  If we reach the
+ end of these two parts without noticing a difference, we return to the
+ standard comparison mode.  There are two types of numeric parts:
+-"integral" and "fractional" (those  begin with a '0'). The types
++"integral" and "fractional" (those  begin with a '0').  The types
+ of the numeric parts affect the way we sort them:
+ 
+ @itemize @bullet
+@@ -1297,6 +1347,7 @@
+ @comment string.h
+ @comment BSD
+ @deftypefun int bcmp (const void *@var{a1}, const void *@var{a2}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is an obsolete alias for @code{memcmp}, derived from BSD.
+ @end deftypefun
+ 
+@@ -1343,6 +1394,9 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun int strcoll (const char *@var{s1}, const char *@var{s2})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c Calls strcoll_l with the current locale, which dereferences only the
++@c LC_COLLATE data pointer.
+ The @code{strcoll} function is similar to @code{strcmp} but uses the
+ collating sequence of the current locale for collation (the
+ @code{LC_COLLATE} locale).
+@@ -1351,6 +1405,8 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun int wcscoll (const wchar_t *@var{ws1}, const wchar_t *@var{ws2})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c Same as strcoll, but calling wcscoll_l.
+ The @code{wcscoll} function is similar to @code{wcscmp} but uses the
+ collating sequence of the current locale for collation (the
+ @code{LC_COLLATE} locale).
+@@ -1370,7 +1426,7 @@
+ compare_elements (const void *v1, const void *v2)
+ @{
+   char * const *p1 = v1;
+-  char * const *p1 = v2;
++  char * const *p2 = v2;
+ 
+   return strcoll (*p1, *p2);
+ @}
+@@ -1391,6 +1447,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun size_t strxfrm (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The function @code{strxfrm} transforms the string @var{from} using the
+ collation transformation determined by the locale currently selected for
+ collation, and stores the transformed string in the array @var{to}.  Up
+@@ -1420,6 +1477,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t wcsxfrm (wchar_t *restrict @var{wto}, const wchar_t *@var{wfrom}, size_t @var{size})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The function @code{wcsxfrm} transforms wide character string @var{wfrom}
+ using the collation transformation determined by the locale currently
+ selected for collation, and stores the transformed string in the array
+@@ -1514,8 +1572,8 @@
+     @}
+ 
+   /* @r{Sort @code{temp_array} by comparing transformed strings.} */
+-  qsort (temp_array, sizeof (struct sorter),
+-         nstrings, compare_elements);
++  qsort (temp_array, nstrings,
++         sizeof (struct sorter), compare_elements);
+ 
+   /* @r{Put the elements back in the permanent array}
+      @r{in their sorted order.} */
+@@ -1579,6 +1637,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {void *} memchr (const void *@var{block}, int @var{c}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function finds the first occurrence of the byte @var{c} (converted
+ to an @code{unsigned char}) in the initial @var{size} bytes of the
+ object beginning at @var{block}.  The return value is a pointer to the
+@@ -1588,6 +1647,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wmemchr (const wchar_t *@var{block}, wchar_t @var{wc}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function finds the first occurrence of the wide character @var{wc}
+ in the initial @var{size} wide characters of the object beginning at
+ @var{block}.  The return value is a pointer to the located wide
+@@ -1597,6 +1657,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {void *} rawmemchr (const void *@var{block}, int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Often the @code{memchr} function is used with the knowledge that the
+ byte @var{c} is available in the memory block specified by the
+ parameters.  But this means that the @var{size} parameter is not really
+@@ -1627,6 +1688,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {void *} memrchr (const void *@var{block}, int @var{c}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The function @code{memrchr} is like @code{memchr}, except that it searches
+ backwards from the end of the block defined by @var{block} and @var{size}
+ (instead of forwards from the front).
+@@ -1637,6 +1699,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strchr (const char *@var{string}, int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{strchr} function finds the first occurrence of the character
+ @var{c} (converted to a @code{char}) in the null-terminated string
+ beginning at @var{string}.  The return value is a pointer to the located
+@@ -1663,6 +1726,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wcschr (const wchar_t *@var{wstring}, int @var{wc})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{wcschr} function finds the first occurrence of the wide
+ character @var{wc} in the null-terminated wide character string
+ beginning at @var{wstring}.  The return value is a pointer to the
+@@ -1678,6 +1742,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {char *} strchrnul (const char *@var{string}, int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{strchrnul} is the same as @code{strchr} except that if it does
+ not find the character, it returns a pointer to string's terminating
+ null character rather than a null pointer.
+@@ -1688,6 +1753,7 @@
+ @comment wchar.h
+ @comment GNU
+ @deftypefun {wchar_t *} wcschrnul (const wchar_t *@var{wstring}, wchar_t @var{wc})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{wcschrnul} is the same as @code{wcschr} except that if it does not
+ find the wide character, it returns a pointer to wide character string's
+ terminating null wide character rather than a null pointer.
+@@ -1723,6 +1789,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strrchr (const char *@var{string}, int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The function @code{strrchr} is like @code{strchr}, except that it searches
+ backwards from the end of the string @var{string} (instead of forwards
+ from the front).
+@@ -1737,6 +1804,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wcsrchr (const wchar_t *@var{wstring}, wchar_t @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The function @code{wcsrchr} is like @code{wcschr}, except that it searches
+ backwards from the end of the string @var{wstring} (instead of forwards
+ from the front).
+@@ -1745,6 +1813,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strstr (const char *@var{haystack}, const char *@var{needle})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is like @code{strchr}, except that it searches @var{haystack} for a
+ substring @var{needle} rather than just a single character.  It
+ returns a pointer into the string @var{haystack} that is the first
+@@ -1763,6 +1832,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wcsstr (const wchar_t *@var{haystack}, const wchar_t *@var{needle})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is like @code{wcschr}, except that it searches @var{haystack} for a
+ substring @var{needle} rather than just a single wide character.  It
+ returns a pointer into the string @var{haystack} that is the first wide
+@@ -1773,7 +1843,8 @@
+ @comment wchar.h
+ @comment XPG
+ @deftypefun {wchar_t *} wcswcs (const wchar_t *@var{haystack}, const wchar_t *@var{needle})
+-@code{wcswcs} is an deprecated alias for @code{wcsstr}.  This is the
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@code{wcswcs} is a deprecated alias for @code{wcsstr}.  This is the
+ name originally used in the X/Open Portability Guide before the
+ @w{Amendment 1} to @w{ISO C90} was published.
+ @end deftypefun
+@@ -1782,6 +1853,9 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {char *} strcasestr (const char *@var{haystack}, const char *@var{needle})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c There may be multiple calls of strncasecmp, each accessing the locale
++@c object independently.
+ This is like @code{strstr}, except that it ignores case in searching for
+ the substring.   Like @code{strcasecmp}, it is locale dependent how
+ uppercase and lowercase characters are related.
+@@ -1800,6 +1874,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {void *} memmem (const void *@var{haystack}, size_t @var{haystack-len},@*const void *@var{needle}, size_t @var{needle-len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This is like @code{strstr}, but @var{needle} and @var{haystack} are byte
+ arrays rather than null-terminated strings.  @var{needle-len} is the
+ length of @var{needle} and @var{haystack-len} is the length of
+@@ -1811,6 +1886,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun size_t strspn (const char *@var{string}, const char *@var{skipset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{strspn} (``string span'') function returns the length of the
+ initial substring of @var{string} that consists entirely of characters that
+ are members of the set specified by the string @var{skipset}.  The order
+@@ -1831,6 +1907,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t wcsspn (const wchar_t *@var{wstring}, const wchar_t *@var{skipset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{wcsspn} (``wide character string span'') function returns the
+ length of the initial substring of @var{wstring} that consists entirely
+ of wide characters that are members of the set specified by the string
+@@ -1841,6 +1918,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun size_t strcspn (const char *@var{string}, const char *@var{stopset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{strcspn} (``string complement span'') function returns the length
+ of the initial substring of @var{string} that consists entirely of characters
+ that are @emph{not} members of the set specified by the string @var{stopset}.
+@@ -1862,6 +1940,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun size_t wcscspn (const wchar_t *@var{wstring}, const wchar_t *@var{stopset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{wcscspn} (``wide character string complement span'') function
+ returns the length of the initial substring of @var{wstring} that
+ consists entirely of wide characters that are @emph{not} members of the
+@@ -1873,6 +1952,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strpbrk (const char *@var{string}, const char *@var{stopset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{strpbrk} (``string pointer break'') function is related to
+ @code{strcspn}, except that it returns a pointer to the first character
+ in @var{string} that is a member of the set @var{stopset} instead of the
+@@ -1897,6 +1977,7 @@
+ @comment wchar.h
+ @comment ISO
+ @deftypefun {wchar_t *} wcspbrk (const wchar_t *@var{wstring}, const wchar_t *@var{stopset})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{wcspbrk} (``wide character string pointer break'') function is
+ related to @code{wcscspn}, except that it returns a pointer to the first
+ wide character in @var{wstring} that is a member of the set
+@@ -1910,6 +1991,7 @@
+ @comment string.h
+ @comment BSD
+ @deftypefun {char *} index (const char *@var{string}, int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{index} is another name for @code{strchr}; they are exactly the same.
+ New code should always use @code{strchr} since this name is defined in
+ @w{ISO C} while @code{index} is a BSD invention which never was available
+@@ -1919,6 +2001,7 @@
+ @comment string.h
+ @comment BSD
+ @deftypefun {char *} rindex (const char *@var{string}, int @var{c})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{rindex} is another name for @code{strrchr}; they are exactly the same.
+ New code should always use @code{strrchr} since this name is defined in
+ @w{ISO C} while @code{rindex} is a BSD invention which never was available
+@@ -1940,6 +2023,7 @@
+ @comment string.h
+ @comment ISO
+ @deftypefun {char *} strtok (char *restrict @var{newstring}, const char *restrict @var{delimiters})
++@safety{@prelim{}@mtunsafe{@mtasurace{:strtok}}@asunsafe{}@acsafe{}}
+ A string can be split into tokens by making a series of calls to the
+ function @code{strtok}.
+ 
+@@ -1978,7 +2062,8 @@
+ 
+ @comment wchar.h
+ @comment ISO
+-@deftypefun {wchar_t *} wcstok (wchar_t *@var{newstring}, const char *@var{delimiters})
++@deftypefun {wchar_t *} wcstok (wchar_t *@var{newstring}, const wchar_t *@var{delimiters}, wchar_t **@var{save_ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ A string can be split into tokens by making a series of calls to the
+ function @code{wcstok}.
+ 
+@@ -1986,11 +2071,8 @@
+ the first call only.  The @code{wcstok} function uses this to set up
+ some internal state information.  Subsequent calls to get additional
+ tokens from the same wide character string are indicated by passing a
+-null pointer as the @var{newstring} argument.  Calling @code{wcstok}
+-with another non-null @var{newstring} argument reinitializes the state
+-information.  It is guaranteed that no other library function ever calls
+-@code{wcstok} behind your back (which would mess up this internal state
+-information).
++null pointer as the @var{newstring} argument, which causes the pointer
++previously stored in @var{save_ptr} to be used instead.
+ 
+ The @var{delimiters} argument is a wide character string that specifies
+ a set of delimiters that may surround the token being extracted.  All
+@@ -1999,8 +2081,10 @@
+ delimiters marks the beginning of the next token.  The end of the token
+ is found by looking for the next wide character that is a member of the
+ delimiter set.  This wide character in the original wide character
+-string @var{newstring} is overwritten by a null wide character, and the
+-pointer to the beginning of the token in @var{newstring} is returned.
++string @var{newstring} is overwritten by a null wide character, the
++pointer past the overwritten wide character is saved in @var{save_ptr},
++and the pointer to the beginning of the token in @var{newstring} is
++returned.
+ 
+ On the next call to @code{wcstok}, the searching begins at the next
+ wide character beyond the one that marked the end of the previous token.
+@@ -2010,11 +2094,6 @@
+ If the end of the wide character string @var{newstring} is reached, or
+ if the remainder of string consists only of delimiter wide characters,
+ @code{wcstok} returns a null pointer.
+-
+-Note that ``character'' is here used in the sense of byte.  In a string
+-using a multibyte character encoding (abstract) character consisting of
+-more than one byte are not treated as an entity.  Each byte is treated
+-separately.  The function is not locale-dependent.
+ @end deftypefun
+ 
+ @strong{Warning:} Since @code{strtok} and @code{wcstok} alter the string
+@@ -2039,7 +2118,7 @@
+ structure, then it is error-prone to modify the data structure
+ temporarily.
+ 
+-The functions @code{strtok} and @code{wcstok} are not reentrant.
++The function @code{strtok} is not reentrant, whereas @code{wcstok} is.
+ @xref{Nonreentrancy}, for a discussion of where and why reentrancy is
+ important.
+ 
+@@ -2075,13 +2154,15 @@
+ @comment string.h
+ @comment POSIX
+ @deftypefun {char *} strtok_r (char *@var{newstring}, const char *@var{delimiters}, char **@var{save_ptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Just like @code{strtok}, this function splits the string into several
+ tokens which can be accessed by successive calls to @code{strtok_r}.
+-The difference is that the information about the next token is stored in
+-the space pointed to by the third argument, @var{save_ptr}, which is a
+-pointer to a string pointer.  Calling @code{strtok_r} with a null
+-pointer for @var{newstring} and leaving @var{save_ptr} between the calls
+-unchanged does the job without hindering reentrancy.
++The difference is that, as in @code{wcstok}, the information about the
++next token is stored in the space pointed to by the third argument,
++@var{save_ptr}, which is a pointer to a string pointer.  Calling
++@code{strtok_r} with a null pointer for @var{newstring} and leaving
++@var{save_ptr} between the calls unchanged does the job without
++hindering reentrancy.
+ 
+ This function is defined in POSIX.1 and can be found on many systems
+ which support multi-threading.
+@@ -2090,6 +2171,7 @@
+ @comment string.h
+ @comment BSD
+ @deftypefun {char *} strsep (char **@var{string_ptr}, const char *@var{delimiter})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function has a similar functionality as @code{strtok_r} with the
+ @var{newstring} argument replaced by the @var{save_ptr} argument.  The
+ initialization of the moving pointer has to be done by the user.
+@@ -2141,6 +2223,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {char *} basename (const char *@var{filename})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The GNU version of the @code{basename} function returns the last
+ component of the path in @var{filename}.  This function is the preferred
+ usage, since it does not modify the argument, @var{filename}, and
+@@ -2175,8 +2258,9 @@
+ 
+ @comment libgen.h
+ @comment XPG
+-@deftypefun {char *} basename (char *@var{path})
+-This is the standard XPG defined @code{basename}. It is similar in
++@deftypefun {char *} basename (const char *@var{path})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++This is the standard XPG defined @code{basename}.  It is similar in
+ spirit to the GNU version, but may modify the @var{path} by removing
+ trailing '/' characters.  If the @var{path} is made up entirely of '/'
+ characters, then "/" will be returned.  Also, if @var{path} is
+@@ -2211,6 +2295,7 @@
+ @comment libgen.h
+ @comment XPG
+ @deftypefun {char *} dirname (char *@var{path})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{dirname} function is the compliment to the XPG version of
+ @code{basename}.  It returns the parent directory of the file specified
+ by @var{path}.  If @var{path} is @code{NULL}, an empty string, or
+@@ -2233,6 +2318,8 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {char *} strfry (char *@var{string})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Calls initstate_r, time, getpid, strlen, and random_r.
+ 
+ @code{strfry} creates a pseudorandom anagram of a string, replacing the
+ input with the anagram in place.  For each position in the string,
+@@ -2268,6 +2355,7 @@
+ @comment string.h
+ @comment GNU
+ @deftypefun {void *} memfrob (void *@var{mem}, size_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ 
+ @code{memfrob} transforms (frobnicates) each byte of the data structure
+ at @var{mem}, which is @var{length} bytes long, by bitwise exclusive
+@@ -2291,13 +2379,14 @@
+ 
+ To store or transfer binary data in environments which only support text
+ one has to encode the binary data by mapping the input bytes to
+-characters in the range allowed for storing or transfering.  SVID
++characters in the range allowed for storing or transferring.  SVID
+ systems (and nowadays XPG compliant systems) provide minimal support for
+ this task.
+ 
+ @comment stdlib.h
+ @comment XPG
+ @deftypefun {char *} l64a (long int @var{n})
++@safety{@prelim{}@mtunsafe{@mtasurace{:l64a}}@asunsafe{}@acsafe{}}
+ This function encodes a 32-bit input value using characters from the
+ basic character set.  It returns a pointer to a 7 character buffer which
+ contains an encoded version of @var{n}.  To encode a series of bytes the
+@@ -2373,6 +2462,7 @@
+ @comment stdlib.h
+ @comment XPG
+ @deftypefun {long int} a64l (const char *@var{string})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The parameter @var{string} should contain a string which was produced by
+ a call to @code{l64a}.  The function processes at least 6 characters of
+ this string, and decodes the characters it finds according to the table
+@@ -2459,6 +2549,7 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {error_t} argz_create (char *const @var{argv}[], char **@var{argz}, size_t *@var{argz_len})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The @code{argz_create} function converts the Unix-style argument vector
+ @var{argv} (a vector of pointers to normal C strings, terminated by
+ @code{(char *)0}; @pxref{Program Arguments}) into an argz vector with
+@@ -2468,6 +2559,7 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {error_t} argz_create_sep (const char *@var{string}, int @var{sep}, char **@var{argz}, size_t *@var{argz_len})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The @code{argz_create_sep} function converts the null-terminated string
+ @var{string} into an argz vector (returned in @var{argz} and
+ @var{argz_len}) by splitting it into elements at every occurrence of the
+@@ -2477,13 +2569,15 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {size_t} argz_count (const char *@var{argz}, size_t @var{arg_len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ Returns the number of elements in the argz vector @var{argz} and
+ @var{argz_len}.
+ @end deftypefun
+ 
+ @comment argz.h
+ @comment GNU
+-@deftypefun {void} argz_extract (char *@var{argz}, size_t @var{argz_len}, char **@var{argv})
++@deftypefun {void} argz_extract (const char *@var{argz}, size_t @var{argz_len}, char **@var{argv})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{argz_extract} function converts the argz vector @var{argz} and
+ @var{argz_len} into a Unix-style argument vector stored in @var{argv},
+ by putting pointers to every element in @var{argz} into successive
+@@ -2501,6 +2595,7 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {void} argz_stringify (char *@var{argz}, size_t @var{len}, int @var{sep})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{argz_stringify} converts @var{argz} into a normal string with
+ the elements separated by the character @var{sep}, by replacing each
+ @code{'\0'} inside @var{argz} (except the last one, which terminates the
+@@ -2511,6 +2606,8 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {error_t} argz_add (char **@var{argz}, size_t *@var{argz_len}, const char *@var{str})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c Calls strlen and argz_append.
+ The @code{argz_add} function adds the string @var{str} to the end of the
+ argz vector @code{*@var{argz}}, and updates @code{*@var{argz}} and
+ @code{*@var{argz_len}} accordingly.
+@@ -2519,6 +2616,7 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {error_t} argz_add_sep (char **@var{argz}, size_t *@var{argz_len}, const char *@var{str}, int @var{delim})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The @code{argz_add_sep} function is similar to @code{argz_add}, but
+ @var{str} is split into separate elements in the result at occurrences of
+ the character @var{delim}.  This is useful, for instance, for
+@@ -2529,6 +2627,7 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {error_t} argz_append (char **@var{argz}, size_t *@var{argz_len}, const char *@var{buf}, size_t @var{buf_len})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The @code{argz_append} function appends @var{buf_len} bytes starting at
+ @var{buf} to the argz vector @code{*@var{argz}}, reallocating
+ @code{*@var{argz}} to accommodate it, and adding @var{buf_len} to
+@@ -2538,6 +2637,8 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {void} argz_delete (char **@var{argz}, size_t *@var{argz_len}, char *@var{entry})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c Calls free if no argument is left.
+ If @var{entry} points to the beginning of one of the elements in the
+ argz vector @code{*@var{argz}}, the @code{argz_delete} function will
+ remove this entry and reallocate @code{*@var{argz}}, modifying
+@@ -2549,6 +2650,8 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun {error_t} argz_insert (char **@var{argz}, size_t *@var{argz_len}, char *@var{before}, const char *@var{entry})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c Calls argz_add or realloc and memmove.
+ The @code{argz_insert} function inserts the string @var{entry} into the
+ argz vector @code{*@var{argz}} at a point just before the existing
+ element pointed to by @var{before}, reallocating @code{*@var{argz}} and
+@@ -2561,7 +2664,8 @@
+ 
+ @comment argz.h
+ @comment GNU
+-@deftypefun {char *} argz_next (char *@var{argz}, size_t @var{argz_len}, const char *@var{entry})
++@deftypefun {char *} argz_next (const char *@var{argz}, size_t @var{argz_len}, const char *@var{entry})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{argz_next} function provides a convenient way of iterating
+ over the elements in the argz vector @var{argz}.  It returns a pointer
+ to the next element in @var{argz} after the element @var{entry}, or
+@@ -2595,6 +2699,7 @@
+ @comment argz.h
+ @comment GNU
+ @deftypefun error_t argz_replace (@w{char **@var{argz}, size_t *@var{argz_len}}, @w{const char *@var{str}, const char *@var{with}}, @w{unsigned *@var{replace_count}})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ Replace any occurrences of the string @var{str} in @var{argz} with
+ @var{with}, reallocating @var{argz} as necessary.  If
+ @var{replace_count} is non-zero, @code{*@var{replace_count}} will be
+@@ -2630,6 +2735,7 @@
+ @comment envz.h
+ @comment GNU
+ @deftypefun {char *} envz_entry (const char *@var{envz}, size_t @var{envz_len}, const char *@var{name})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{envz_entry} function finds the entry in @var{envz} with the name
+ @var{name}, and returns a pointer to the whole entry---that is, the argz
+ element which begins with @var{name} followed by a @code{'='} character.  If
+@@ -2639,6 +2745,7 @@
+ @comment envz.h
+ @comment GNU
+ @deftypefun {char *} envz_get (const char *@var{envz}, size_t @var{envz_len}, const char *@var{name})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{envz_get} function finds the entry in @var{envz} with the name
+ @var{name} (like @code{envz_entry}), and returns a pointer to the value
+ portion of that entry (following the @code{'='}).  If there is no entry with
+@@ -2648,6 +2755,9 @@
+ @comment envz.h
+ @comment GNU
+ @deftypefun {error_t} envz_add (char **@var{envz}, size_t *@var{envz_len}, const char *@var{name}, const char *@var{value})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
++@c Calls envz_remove, which calls enz_entry and argz_delete, and then
++@c argz_add or equivalent code that reallocs and appends name=value.
+ The @code{envz_add} function adds an entry to @code{*@var{envz}}
+ (updating @code{*@var{envz}} and @code{*@var{envz_len}}) with the name
+ @var{name}, and value @var{value}.  If an entry with the same name
+@@ -2659,6 +2769,7 @@
+ @comment envz.h
+ @comment GNU
+ @deftypefun {error_t} envz_merge (char **@var{envz}, size_t *@var{envz_len}, const char *@var{envz2}, size_t @var{envz2_len}, int @var{override})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+ The @code{envz_merge} function adds each entry in @var{envz2} to @var{envz},
+ as if with @code{envz_add}, updating @code{*@var{envz}} and
+ @code{*@var{envz_len}}.  If @var{override} is true, then values in @var{envz2}
+@@ -2672,6 +2783,10 @@
+ @comment envz.h
+ @comment GNU
+ @deftypefun {void} envz_strip (char **@var{envz}, size_t *@var{envz_len})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{envz_strip} function removes any null entries from @var{envz},
+ updating @code{*@var{envz}} and @code{*@var{envz_len}}.
+ @end deftypefun
++
++@c FIXME this are undocumented:
++@c strcasecmp_l @safety{@mtsafe{}@assafe{}@acsafe{}} see strcasecmp
+diff -urN glibc-2.17-c758a686/manual/summary.awk glibc/manual/summary.awk
+--- glibc-2.17-c758a686/manual/summary.awk	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/summary.awk	2014-09-12 16:10:06.042792724 -0400
+@@ -1,5 +1,5 @@
+ # awk script to create summary.texinfo from the library texinfo files.
+-# Copyright (C) 1992, 1993, 1997, 2001 Free Software Foundation, Inc.
++# Copyright (C) 1992-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
+diff -urN glibc-2.17-c758a686/manual/sysinfo.texi glibc/manual/sysinfo.texi
+--- glibc-2.17-c758a686/manual/sysinfo.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/sysinfo.texi	2014-09-12 16:10:06.048792709 -0400
+@@ -91,6 +91,9 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int gethostname (char *@var{name}, size_t @var{size})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on unix; implemented in terms of uname on posix and of
++@c hurd_get_host_config on hurd.
+ This function returns the host name of the system on which it is called,
+ in the array @var{name}.  The @var{size} argument specifies the size of
+ this array, in bytes.  Note that this is @emph{not} the DNS hostname.
+@@ -121,6 +124,9 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int sethostname (const char *@var{name}, size_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on unix; implemented in terms of hurd_set_host_config
++@c on hurd.
+ The @code{sethostname} function sets the host name of the system that
+ calls it to @var{name}, a string with length @var{length}.  Only
+ privileged processes are permitted to do this.
+@@ -145,6 +151,8 @@
+ @comment unistd.h
+ @comment ???
+ @deftypefun int getdomainnname (char *@var{name}, size_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Syscalls uname, then strlen and memcpy.
+ @cindex NIS domain name
+ @cindex YP domain name
+ 
+@@ -159,6 +167,8 @@
+ @comment unistd.h
+ @comment ???
+ @deftypefun int setdomainname (const char *@var{name}, size_t @var{length})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall.
+ @cindex NIS domain name
+ @cindex YP domain name
+ 
+@@ -173,6 +183,10 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun {long int} gethostid (void)
++@safety{@prelim{}@mtsafe{@mtshostid{} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
++@c On HURD, calls _hurd_get_host_config and strtol.  On Linux, open
++@c HOSTIDFILE, reads an int32_t and closes; if that fails, it calls
++@c gethostname and gethostbyname_r to use the h_addr.
+ This function returns the ``host ID'' of the machine the program is
+ running on.  By convention, this is usually the primary Internet IP address
+ of that machine, converted to a @w{@code{long int}}.  However, on some
+@@ -190,6 +204,7 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int sethostid (long int @var{id})
++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtshostid{}}}@asunsafe{}@acunsafe{@acucorrupt{} @acsfd{}}}
+ The @code{sethostid} function sets the ``host ID'' of the host machine
+ to @var{id}.  Only privileged processes are permitted to do this.  Usually
+ it happens just once, at system boot time.
+@@ -226,7 +241,7 @@
+ 
+ As a bonus, @code{uname} also gives some information identifying the
+ particular system your program is running on.  This is the same information
+-which you can get with functions targetted to this purpose described in
++which you can get with functions targeted to this purpose described in
+ @ref{Host Identification}.
+ 
+ 
+@@ -296,6 +311,10 @@
+ @comment sys/utsname.h
+ @comment POSIX.1
+ @deftypefun int uname (struct utsname *@var{info})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall on unix; the posix fallback is to call gethostname and
++@c then fills in the other fields with constants; on HURD, it calls
++@c proc_uname and then gethostname.
+ The @code{uname} function fills in the structure pointed to by
+ @var{info} with information about the operating system and host machine.
+ A non-negative value indicates that the data was successfully stored.
+@@ -471,6 +490,12 @@
+ @comment fstab.h
+ @comment BSD
+ @deftypefun int setfsent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent}}@asunsafe{@ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c setfsent @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
++@c  fstab_init(1) @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
++@c   malloc dup @ascuheap @acsmem
++@c   rewind dup @asucorrupt @acucorrupt [no @aculock]
++@c   setmntent dup @ascuheap @asulock @acsmem @acsfd @aculock
+ This function makes sure that the internal read pointer for the
+ @file{fstab} file is at the beginning of the file.  This is done by
+ either opening the file or resetting the read pointer.
+@@ -486,6 +511,9 @@
+ @comment fstab.h
+ @comment BSD
+ @deftypefun void endfsent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent}}@asunsafe{@ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c endfsent @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
++@c  endmntent dup @ascuheap @asulock @aculock @acsmem @acsfd
+ This function makes sure that all resources acquired by a prior call to
+ @code{setfsent} (explicitly or implicitly by calling @code{getfsent}) are
+ freed.
+@@ -494,6 +522,13 @@
+ @comment fstab.h
+ @comment BSD
+ @deftypefun {struct fstab *} getfsent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c getfsent @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem
++@c  fstab_init(0) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
++@c  fstab_fetch @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
++@c   getmntent_r dup @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
++@c  fstab_convert @mtasurace:fsent
++@c   hasmntopt dup ok
+ This function returns the next entry of the @file{fstab} file.  If this
+ is the first call to any of the functions handling @file{fstab} since
+ program start or the last call of @code{endfsent}, the file will be
+@@ -508,6 +543,12 @@
+ @comment fstab.h
+ @comment BSD
+ @deftypefun {struct fstab *} getfsspec (const char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c getffsspec @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem
++@c  fstab_init(1) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
++@c  fstab_fetch dup @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
++@c  strcmp dup ok
++@c  fstab_convert dup @mtasurace:fsent
+ This function returns the next entry of the @file{fstab} file which has
+ a string equal to @var{name} pointed to by the @code{fs_spec} element.
+ Since there is normally exactly one entry for each special device it
+@@ -525,6 +566,12 @@
+ @comment fstab.h
+ @comment BSD
+ @deftypefun {struct fstab *} getfsfile (const char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c getffsfile @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem
++@c  fstab_init(1) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
++@c  fstab_fetch dup @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
++@c  strcmp dup ok
++@c  fstab_convert dup @mtasurace:fsent
+ This function returns the next entry of the @file{fstab} file which has
+ a string equal to @var{name} pointed to by the @code{fs_file} element.
+ Since there is normally exactly one entry for each mount point it
+@@ -640,6 +687,13 @@
+ @comment mntent.h
+ @comment BSD
+ @deftypefun {FILE *} setmntent (const char *@var{file}, const char *@var{mode})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
++@c setmntent @ascuheap @asulock @acsmem @acsfd @aculock
++@c  strlen dup ok
++@c  mempcpy dup ok
++@c  memcpy dup ok
++@c  fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c  fsetlocking dup ok [no @mtasurace:stream @asulock: exclusive stream]
+ The @code{setmntent} function prepares the file named @var{FILE} which
+ must be in the format of a @file{fstab} and @file{mtab} file for the
+ upcoming processing through the other functions of the family.  The
+@@ -655,6 +709,9 @@
+ @comment mntent.h
+ @comment BSD
+ @deftypefun int endmntent (FILE *@var{stream})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c endmntent @ascuheap @asulock @aculock @acsmem @acsfd
++@c  fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
+ This function takes for the @var{stream} parameter a file handle which
+ previously was returned from the @code{setmntent} call.
+ @code{endmntent} closes the stream and frees all resources.
+@@ -666,6 +723,12 @@
+ @comment mntent.h
+ @comment BSD
+ @deftypefun {struct mntent *} getmntent (FILE *@var{stream})
++@safety{@prelim{}@mtunsafe{@mtasurace{:mntentbuf} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asuinit{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsmem{}}}
++@c getmntent @mtasurace:mntentbuf @mtslocale @asucorrupt @ascuheap @asuinit @acuinit @acucorrupt @aculock @acsmem
++@c  libc_once @ascuheap @asuinit @acuinit @acsmem
++@c   allocate @ascuheap @acsmem
++@c    malloc dup @ascuheap @acsmem
++@c  getmntent_r dup @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
+ The @code{getmntent} function takes as the parameter a file handle
+ previously returned by successful call to @code{setmntent}.  It returns
+ a pointer to a static variable of type @code{struct mntent} which is
+@@ -691,7 +754,17 @@
+ 
+ @comment mntent.h
+ @comment BSD
+-@deftypefun {struct mntent *} getmntent_r (FILE *@var{stream}, struct mentent *@var{result}, char *@var{buffer}, int @var{bufsize})
++@deftypefun {struct mntent *} getmntent_r (FILE *@var{stream}, struct mntent *@var{result}, char *@var{buffer}, int @var{bufsize})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
++@c getmntent_r @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
++@c  flockfile dup @aculock
++@c  fgets_unlocked dup @asucorrupt @acucorrupt [locked, so no @mtsrace:stream]
++@c  funlockfile dup @aculock
++@c  strchr dup ok
++@c  strspn dup ok
++@c  strsep dup ok
++@c  decode_name ok
++@c  sscanf dup @mtslocale @ascuheap @acsmem
+ The @code{getmntent_r} function is the reentrant variant of
+ @code{getmntent}.  It also returns the next entry from the file and
+ returns a pointer.  The actual variable the values are stored in is not
+@@ -717,6 +790,12 @@
+ @comment mntent.h
+ @comment BSD
+ @deftypefun int addmntent (FILE *@var{stream}, const struct mntent *@var{mnt})
++@safety{@prelim{}@mtunsafe{@mtasurace{:stream} @mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
++@c addmntent @mtasurace:stream @mtslocale @asucorrupt @acucorrupt
++@c  fseek dup @asucorrupt @acucorrupt [no @aculock]
++@c  encode_name ok
++@c  fprintf dup @mtslocale @asucorrupt @acucorrupt [no @ascuheap @acsmem, no @aculock]
++@c  fflush dup @asucorrupt @acucorrupt [no @aculock]
+ The @code{addmntent} function allows adding a new entry to the file
+ previously opened with @code{setmntent}.  The new entries are always
+ appended.  I.e., even if the position of the file descriptor is not at
+@@ -740,6 +819,11 @@
+ @comment mntent.h
+ @comment BSD
+ @deftypefun {char *} hasmntopt (const struct mntent *@var{mnt}, const char *@var{opt})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c hasmntopt ok
++@c  strlen dup ok
++@c  strstr dup ok
++@c  strchr dup ok
+ This function can be used to check whether the string pointed to by the
+ @code{mnt_opts} element of the variable pointed to by @var{mnt} contains
+ the option @var{opt}.  If this is true a pointer to the beginning of the
+@@ -778,6 +862,8 @@
+ @comment sys/mount.h
+ @comment SVID, BSD
+ @deftypefun {int} mount (const char *@var{special_file}, const char *@var{dir}, const char *@var{fstype}, unsigned long int @var{options}, const void *@var{data})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall.
+ 
+ @code{mount} mounts or remounts a filesystem.  The two operations are
+ quite different and are merged rather unnaturally into this one function.
+@@ -982,6 +1068,8 @@
+ @comment sys/mount.h
+ @comment GNU
+ @deftypefun {int} umount2 (const char *@var{file}, int @var{flags})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall.
+ 
+ @code{umount2} unmounts a filesystem.
+ 
+@@ -1047,6 +1135,8 @@
+ @comment sys/mount.h
+ @comment SVID, GNU
+ @deftypefun {int} umount (const char *@var{file})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall or wrapper for umount2.
+ 
+ @code{umount} does the same thing as @code{umount2} with @var{flags} set
+ to zeroes.  It is more widely available than @code{umount2} but since it
+@@ -1062,11 +1152,13 @@
+ This section describes the @code{sysctl} function, which gets and sets
+ a variety of system parameters.
+ 
+-The symbols used in this section are declared in the file @file{sysctl.h}.
++The symbols used in this section are declared in the file @file{sys/sysctl.h}.
+ 
+-@comment sysctl.h
++@comment sys/sysctl.h
+ @comment BSD
+ @deftypefun int sysctl (int *@var{names}, int @var{nlen}, void *@var{oldval}, size_t *@var{oldlenp}, void *@var{newval}, size_t @var{newlen})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct syscall, Linux only.
+ 
+ @code{sysctl} gets or sets a specified system parameter.  There are so
+ many of these parameters that it is not practical to list them all here,
+@@ -1090,7 +1182,7 @@
+ a particular parameter, you specify a path through the structure in a
+ way analogous to specifying the pathname of a file.  Each component of
+ the path is specified by an integer and each of these integers has a
+-macro defined for it by @file{sysctl.h}.  @var{names} is the path, in
++macro defined for it by @file{sys/sysctl.h}.  @var{names} is the path, in
+ the form of an array of integers.  Each component of the path is one
+ element of the array, in order.  @var{nlen} is the number of components
+ in the path.
+diff -urN glibc-2.17-c758a686/manual/syslog.texi glibc/manual/syslog.texi
+--- glibc-2.17-c758a686/manual/syslog.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/syslog.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -147,6 +147,17 @@
+ @comment syslog.h
+ @comment BSD
+ @deftypefun void openlog (const char *@var{ident}, int @var{option}, int @var{facility})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c openlog @asulock @aculock @acsfd
++@c  libc_lock_lock @asulock @aculock
++@c  openlog_internal @acsfd [always guarded by syslog_lock, so no race]
++@c   strncpy dup ok
++@c   socket dup @acsfd
++@c   fcntl dup ok
++@c   connect dup ok
++@c   close dup @acsfd
++@c  cancel_handler(NULL) @aculock
++@c   libc_lock_unlock @aculock
+ 
+ @code{openlog} opens or reopens a connection to Syslog in preparation
+ for submitting messages.
+@@ -275,7 +286,39 @@
+ @c syslog() is implemented as a call to vsyslog().
+ @comment syslog.h
+ @comment BSD
+-@deftypefun void syslog (int @var{facility_priority}, char *@var{format}, @dots{})
++@deftypefun void syslog (int @var{facility_priority}, const char *@var{format}, @dots{})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c syslog @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  va_start dup ok
++@c  vsyslog_chk @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   syslog(INTERNALLOG) dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   open_memstream @ascuheap @acsmem
++@c   stpcpy dup ok
++@c   getpid dup ok
++@c   mempcpy dup ok
++@c   fsetlocking [no @mtasurace:stream @asulock for exclusive stream]
++@c   fprintf @mtslocale @ascuheap @acsmem [no @asucorrupt @aculock @acucorrupt on temp memstream]
++@c   time dup ok
++@c   localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   strftime_l(C) dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   ftell dup ok [no @asucorrupt @aculock @acucorrupt on temp memstream]
++@c   fputs_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream]
++@c   putc_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream]
++@c   vfprintf/vfprintf_chk dup @mtslocale @ascuheap @acsmem [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream]
++@c   fclose dup @ascuheap @acsmem [no @asulock @aculock @acsfd on caller-locked memstream]
++@c   writev dup ok
++@c   libc_lock_lock dup @asulock @aculock
++@c   memset dup ok
++@c   sigemptyset dup ok
++@c   sigaction(SIGPIPE) dup @mtasusig:PIPE @acusig:PIPE
++@c   openlog_internal dup @acsfd
++@c   send dup ok
++@c   closelog_internal dup @acsfd
++@c   open dup @acsfd
++@c   dprintf dup ok
++@c   libc_lock_unlock @asulock @aculock
++@c   free dup @acsuheap @acsmem
++@c  va_end dup ok
+ 
+ @code{syslog} submits a message to the Syslog facility.  It does this by
+ writing to the Unix domain socket @code{/dev/log}.
+@@ -403,7 +446,10 @@
+ 
+ @comment syslog.h
+ @comment BSD
+-@deftypefun void vsyslog (int @var{facility_priority}, char *@var{format}, va_list @var{arglist})
++@deftypefun void vsyslog (int @var{facility_priority}, const char *@var{format}, va_list @var{arglist})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c vsyslog @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  vsyslog_chk dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+ 
+ This is functionally identical to @code{syslog}, with the BSD style variable
+ length argument.
+@@ -420,6 +466,13 @@
+ @comment syslog.h
+ @comment BSD
+ @deftypefun void closelog (void)
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c closelog @asulock @aculock @acsfd
++@c  libc_lock_lock @asulock @aculock
++@c  closelog_internal @acsfd [always guarded by syslog_lock, so no race]
++@c   close dup@acsfd
++@c  cancel_handler(NULL) @aculock
++@c   libc_lock_unlock @aculock
+ 
+ @code{closelog} closes the current Syslog connection, if there is one.
+ This includes closing the @file{/dev/log} socket, if it is open.
+@@ -450,6 +503,10 @@
+ @comment syslog.h
+ @comment BSD
+ @deftypefun int setlogmask (int @var{mask})
++@safety{@prelim{}@mtunsafe{@mtasurace{:LogMask}}@asunsafe{}@acsafe{}}
++@c Read and modify are not guarded by syslog_lock, so concurrent changes
++@c or even uses are undefined.  This should use an atomic swap instead,
++@c at least for modifications.
+ 
+ @code{setlogmask} sets a mask (the ``logmask'') that determines which
+ future @code{syslog} calls shall be ignored.  If a program has not
+diff -urN glibc-2.17-c758a686/manual/terminal.texi glibc/manual/terminal.texi
+--- glibc-2.17-c758a686/manual/terminal.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/terminal.texi	2014-09-12 16:10:06.047792712 -0400
+@@ -44,6 +44,9 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int isatty (int @var{filedes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c isatty ok
++@c  tcgetattr dup ok
+ This function returns @code{1} if @var{filedes} is a file descriptor
+ associated with an open terminal device, and @math{0} otherwise.
+ @end deftypefun
+@@ -55,6 +58,20 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun {char *} ttyname (int @var{filedes})
++@safety{@prelim{}@mtunsafe{@mtasurace{:ttyname}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c ttyname @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
++@c  isatty dup ok
++@c  fstat dup ok
++@c  memcpy dup ok
++@c  getttyname @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
++@c   opendir @ascuheap @acsmem @acsfd
++@c   readdir ok [protected by exclusive access]
++@c   strcmp dup ok
++@c   free dup @asulock @aculock @acsfd @acsmem
++@c   malloc dup @asulock @aculock @acsfd @acsmem
++@c   closedir @ascuheap @acsmem @acsfd
++@c   mempcpy dup ok
++@c   stat dup ok
+ If the file descriptor @var{filedes} is associated with a terminal
+ device, the @code{ttyname} function returns a pointer to a
+ statically-allocated, null-terminated string containing the file name of
+@@ -65,6 +82,18 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int ttyname_r (int @var{filedes}, char *@var{buf}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
++@c ttyname_r @ascuheap @acsmem @acsfd
++@c  isatty dup ok
++@c  fstat dup ok
++@c  memcpy dup ok
++@c  getttyname_r @ascuheap @acsmem @acsfd
++@c   opendir @ascuheap @acsmem @acsfd
++@c   readdir ok [protected by exclusive access]
++@c   strcmp dup ok
++@c   closedir @ascuheap @acsmem @acsfd
++@c   stpncpy dup ok
++@c   stat dup ok
+ The @code{ttyname_r} function is similar to the @code{ttyname} function
+ except that it places its result into the user-specified buffer starting
+ at @var{buf} with length @var{len}.
+@@ -264,6 +293,9 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun int tcgetattr (int @var{filedes}, struct termios *@var{termios-p})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Converting the kernel-returned termios data structure to the userland
++@c format does not ensure atomic or consistent writing.
+ This function is used to examine the attributes of the terminal
+ device with file descriptor @var{filedes}.  The attributes are returned
+ in the structure that @var{termios-p} points to.
+@@ -284,6 +316,9 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun int tcsetattr (int @var{filedes}, int @var{when}, const struct termios *@var{termios-p})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Converting the incoming termios data structure to the kernel format
++@c does not ensure atomic or consistent reading.
+ This function sets the attributes of the terminal device with file
+ descriptor @var{filedes}.  The new attributes are taken from the
+ structure that @var{termios-p} points to.
+@@ -621,7 +656,7 @@
+ of characters, carriage return followed by linefeed.
+ @end deftypevr
+ 
+-@comment termios.h
++@comment termios.h (optional)
+ @comment BSD
+ @deftypevr Macro tcflag_t OXTABS
+ If this bit is set, convert tab characters on output into the appropriate
+@@ -630,7 +665,7 @@
+ @gnulinuxsystems{} it is available as @code{XTABS}.
+ @end deftypevr
+ 
+-@comment termios.h
++@comment termios.h (optional)
+ @comment BSD
+ @deftypevr Macro tcflag_t ONOEOT
+ If this bit is set, discard @kbd{C-d} characters (code @code{004}) on
+@@ -962,7 +997,7 @@
+ While this bit is set, all output is discarded.  @xref{Other Special}.
+ @end deftypevr
+ 
+-@comment termios.h
++@comment termios.h (optional)
+ @comment BSD
+ @deftypevr Macro tcflag_t NOKERNINFO
+ Setting this bit disables handling of the STATUS character.
+@@ -1016,6 +1051,10 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun speed_t cfgetospeed (const struct termios *@var{termios-p})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct access to a single termios field, except on Linux, where
++@c multiple accesses may take place.  No worries either way, callers
++@c must ensure mutual exclusion on such non-opaque types.
+ This function returns the output line speed stored in the structure
+ @code{*@var{termios-p}}.
+ @end deftypefun
+@@ -1023,6 +1062,7 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun speed_t cfgetispeed (const struct termios *@var{termios-p})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function returns the input line speed stored in the structure
+ @code{*@var{termios-p}}.
+ @end deftypefun
+@@ -1030,6 +1070,7 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun int cfsetospeed (struct termios *@var{termios-p}, speed_t @var{speed})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function stores @var{speed} in @code{*@var{termios-p}} as the output
+ speed.  The normal return value is @math{0}; a value of @math{-1}
+ indicates an error.  If @var{speed} is not a speed, @code{cfsetospeed}
+@@ -1039,6 +1080,7 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun int cfsetispeed (struct termios *@var{termios-p}, speed_t @var{speed})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ This function stores @var{speed} in @code{*@var{termios-p}} as the input
+ speed.  The normal return value is @math{0}; a value of @math{-1}
+ indicates an error.  If @var{speed} is not a speed, @code{cfsetospeed}
+@@ -1048,6 +1090,14 @@
+ @comment termios.h
+ @comment BSD
+ @deftypefun int cfsetspeed (struct termios *@var{termios-p}, speed_t @var{speed})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c There's no guarantee that the two calls are atomic, but since this is
++@c not an opaque type, callers ought to ensure mutual exclusion to the
++@c termios object.
++
++@c cfsetspeed ok
++@c  cfsetispeed ok
++@c  cfsetospeed ok
+ This function stores @var{speed} in @code{*@var{termios-p}} as both the
+ input and output speeds.  The normal return value is @math{0}; a value
+ of @math{-1} indicates an error.  If @var{speed} is not a speed,
+@@ -1625,6 +1675,10 @@
+ @comment termios.h
+ @comment BSD
+ @deftypefun void cfmakeraw (struct termios *@var{termios-p})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c There's no guarantee the changes are atomic, but since this is not an
++@c opaque type, callers ought to ensure mutual exclusion to the termios
++@c object.
+ This function provides an easy way to set up @code{*@var{termios-p}} for
+ what has traditionally been called ``raw mode'' in BSD.  This uses
+ noncanonical input, and turns off most processing to give an unmodified
+@@ -1678,6 +1732,8 @@
+ @comment sgtty.h
+ @comment BSD
+ @deftypefun int gtty (int @var{filedes}, struct sgttyb *@var{attributes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct ioctl, BSD only.
+ This function gets the attributes of a terminal.
+ 
+ @code{gtty} sets *@var{attributes} to describe the terminal attributes
+@@ -1686,7 +1742,9 @@
+ 
+ @comment sgtty.h
+ @comment BSD
+-@deftypefun int stty (int @var{filedes}, struct sgttyb *@var{attributes})
++@deftypefun int stty (int @var{filedes}, const struct sgttyb *@var{attributes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct ioctl, BSD only.
+ 
+ This function sets the attributes of a terminal.
+ 
+@@ -1710,6 +1768,12 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun int tcsendbreak (int @var{filedes}, int @var{duration})
++@safety{@prelim{}@mtunsafe{@mtasurace{:tcattr(filedes)/bsd}}@asunsafe{}@acunsafe{@acucorrupt{/bsd}}}
++@c On Linux, this calls just one out of two ioctls; on BSD, it's two
++@c ioctls with a select (for the delay only) in between, the first
++@c setting and the latter clearing the break status.  The BSD
++@c implementation may leave the break enabled if cancelled, and threads
++@c and signals may cause the break to be interrupted before requested.
+ This function generates a break condition by transmitting a stream of
+ zero bits on the terminal associated with the file descriptor
+ @var{filedes}.  The duration of the break is controlled by the
+@@ -1738,6 +1802,8 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun int tcdrain (int @var{filedes})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct ioctl.
+ The @code{tcdrain} function waits until all queued
+ output to the terminal @var{filedes} has been transmitted.
+ 
+@@ -1772,6 +1838,8 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun int tcflush (int @var{filedes}, int @var{queue})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Direct ioctl.
+ The @code{tcflush} function is used to clear the input and/or output
+ queues associated with the terminal file @var{filedes}.  The @var{queue}
+ argument specifies which queue(s) to clear, and can be one of the
+@@ -1822,6 +1890,11 @@
+ @comment termios.h
+ @comment POSIX.1
+ @deftypefun int tcflow (int @var{filedes}, int @var{action})
++@safety{@prelim{}@mtunsafe{@mtasurace{:tcattr(filedes)/bsd}}@asunsafe{}@acsafe{}}
++@c Direct ioctl on Linux.  On BSD, the TCO* actions are a single ioctl,
++@c whereas the TCI actions first call tcgetattr and then write to the fd
++@c the c_cc character corresponding to the action; there's a window for
++@c another thread to change the xon/xoff characters.
+ The @code{tcflow} function is used to perform operations relating to
+ XON/XOFF flow control on the terminal file specified by @var{filedes}.
+ 
+@@ -1931,6 +2004,14 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int getpt (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
++@c On BSD, tries to open multiple potential pty names, returning on the
++@c first success.  On Linux, try posix_openpt first, then fallback to
++@c the BSD implementation.  The posix implementation opens the ptmx
++@c device, checks with statfs that /dev/pts is a devpts or that /dev is
++@c a devfs, and returns the fd; static variables devpts_mounted and
++@c have_no_dev_ptmx are safely initialized so as to avoid repeated
++@c tests.
+ The @code{getpt} function returns a new file descriptor for the next
+ available master pseudo-terminal.  The normal return value from
+ @code{getpt} is a non-negative integer file descriptor.  In the case of
+@@ -1948,6 +2029,32 @@
+ @comment stdlib.h
+ @comment SVID, XPG4.2
+ @deftypefun int grantpt (int @var{filedes})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c grantpt @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  unix/grantpt:pts_name @acsuheap @acsmem
++@c   ptsname_internal dup ok (but this is Linux-only!)
++@c   memchr dup ok
++@c   realloc dup @acsuheap @acsmem
++@c   malloc dup @acsuheap @acsmem
++@c   free dup @acsuheap @acsmem
++@c  fcntl dup ok
++@c  getuid dup ok
++@c  chown dup ok
++@c  sysconf(_SC_GETGR_R_SIZE_MAX) ok
++@c  getgrnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  getgid dup ok
++@c  chmod dup ok
++@c  fork dup @aculock
++@c  [child]
++@c   setrlimit
++@c   dup2
++@c   CLOSE_ALL_FDS
++@c   execle
++@c   _exit
++@c  waitpid dup ok
++@c  WIFEXITED dup ok
++@c  WEXITSTATUS dup ok
++@c  free dup @ascuheap @acsmem
+ The @code{grantpt} function changes the ownership and access permission
+ of the slave pseudo-terminal device corresponding to the master
+ pseudo-terminal device associated with the file descriptor
+@@ -1985,6 +2092,13 @@
+ @comment stdlib.h
+ @comment SVID, XPG4.2
+ @deftypefun int unlockpt (int @var{filedes})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/bsd}}@acunsafe{@acsmem{} @acsfd{}}}
++@c unlockpt @ascuheap/bsd @acsmem @acsfd
++@c /bsd
++@c  ptsname_r dup @ascuheap @acsmem @acsfd
++@c  revoke ok (syscall)
++@c /linux
++@c  ioctl dup ok
+ The @code{unlockpt} function unlocks the slave pseudo-terminal device
+ corresponding to the master pseudo-terminal device associated with the
+ file descriptor @var{filedes}.  On many systems, the slave can only be
+@@ -2008,6 +2122,9 @@
+ @comment stdlib.h
+ @comment SVID, XPG4.2
+ @deftypefun {char *} ptsname (int @var{filedes})
++@safety{@prelim{}@mtunsafe{@mtasurace{:ptsname}}@asunsafe{@ascuheap{/bsd}}@acunsafe{@acsmem{} @acsfd{}}}
++@c ptsname @mtasurace:ptsname @ascuheap/bsd @acsmem @acsfd
++@c  ptsname_r dup @ascuheap/bsd @acsmem @acsfd
+ If the file descriptor @var{filedes} is associated with a
+ master pseudo-terminal device, the @code{ptsname} function returns a
+ pointer to a statically-allocated, null-terminated string containing the
+@@ -2018,6 +2135,37 @@
+ @comment stdlib.h
+ @comment GNU
+ @deftypefun int ptsname_r (int @var{filedes}, char *@var{buf}, size_t @var{len})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/bsd}}@acunsafe{@acsmem{} @acsfd{}}}
++@c ptsname_r @ascuheap/bsd @acsmem @acsfd
++@c /hurd
++@c  term_get_peername ok
++@c  strlen dup ok
++@c  memcpy dup ok
++@c /bsd
++@c  isatty dup ok
++@c  strlen dup ok
++@c  ttyname_r dup @ascuheap @acsmem @acsfd
++@c  stat dup ok
++@c /linux
++@c  ptsname_internal ok
++@c   isatty dup ok
++@c   ioctl dup ok
++@c   strlen dup ok
++@c   itoa_word dup ok
++@c   stpcpy dup ok
++@c   memcpy dup ok
++@c   fxstat64 dup ok
++@c   MASTER_P ok
++@c    major ok
++@c     gnu_dev_major ok
++@c    minor ok
++@c     gnu_dev_minor ok
++@c   minor dup ok
++@c   xstat64 dup ok
++@c   S_ISCHR dup ok
++@c   SLAVE_P ok
++@c    major dup ok
++@c    minor dup ok
+ The @code{ptsname_r} function is similar to the @code{ptsname} function
+ except that it places its result into the user-specified buffer starting
+ at @var{buf} with length @var{len}.
+@@ -2083,6 +2231,22 @@
+ @comment pty.h
+ @comment BSD
+ @deftypefun int openpty (int *@var{amaster}, int *@var{aslave}, char *@var{name}, const struct termios *@var{termp}, const struct winsize *@var{winp})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c openpty @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  getpt @acsfd
++@c  grantpt @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  unlockpt dup @ascuheap/bsd @acsmem @acsfd
++@c  openpty:pts_name @acsuheap @acsmem @acsfd
++@c   ptsname_r dup @ascuheap/bsd @acsmem @acsfd
++@c   realloc dup @acsuheap @acsmem
++@c   malloc dup @acsuheap @acsmem
++@c   free dup @acsuheap @acsmem
++@c  open dup @acsfd
++@c  free dup @acsuheap @acsmem
++@c  tcsetattr dup ok
++@c  ioctl dup ok
++@c  strcpy dup ok
++@c  close dup @acsfd
+ This function allocates and opens a pseudo-terminal pair, returning the
+ file descriptor for the master in @var{*amaster}, and the file
+ descriptor for the slave in @var{*aslave}.  If the argument @var{name}
+@@ -2114,6 +2278,16 @@
+ @comment pty.h
+ @comment BSD
+ @deftypefun int forkpty (int *@var{amaster}, char *@var{name}, const struct termios *@var{termp}, const struct winsize *@var{winp})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c forkpty @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  openpty dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  fork dup @aculock
++@c  close dup @acsfd
++@c  /child
++@c   close dup @acsfd
++@c   login_tty dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
++@c   _exit dup ok
++@c  close dup @acsfd
+ This function is similar to the @code{openpty} function, but in
+ addition, forks a new process (@pxref{Creating a Process}) and makes the
+ newly opened slave pseudo-terminal device the controlling terminal
+diff -urN glibc-2.17-c758a686/manual/texinfo.tex glibc/manual/texinfo.tex
+--- glibc-2.17-c758a686/manual/texinfo.tex	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/texinfo.tex	2014-09-12 16:10:06.047792712 -0400
+@@ -3,11 +3,11 @@
+ % Load plain if necessary, i.e., if running under initex.
+ \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+ %
+-\def\texinfoversion{2012-01-19.16}
++\def\texinfoversion{2014-05-05.10}
+ %
+ % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+ % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+-% 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
++% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+ %
+ % This texinfo.tex file is free software: you can redistribute it and/or
+ % modify it under the terms of the GNU General Public License as
+@@ -24,13 +24,14 @@
+ %
+ % As a special exception, when this file is read by TeX when processing
+ % a Texinfo source document, you may use the result without
+-% restriction.  (This has been our intent since Texinfo was invented.)
++% restriction. This Exception is an additional permission under section 7
++% of the GNU General Public License, version 3 ("GPLv3").
+ %
+ % Please try the latest version of texinfo.tex before submitting bug
+ % reports; you can get the latest version from:
+-%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+-%   ftp://tug.org/tex/texinfo.tex
+-%     (and all CTAN mirrors, see http://www.ctan.org).
++%   http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
++%   http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
++%   http://www.gnu.org/software/texinfo/ (the Texinfo home page)
+ % The texinfo.tex in any given distribution could well be out
+ % of date, so if that's what you're using, please check.
+ %
+@@ -280,9 +281,9 @@
+   \toks6=\expandafter{\prevsectiondefs}%
+   \toks8=\expandafter{\lastcolordefs}%
+   \mark{%
+-                   \the\toks0 \the\toks2
+-      \noexpand\or \the\toks4 \the\toks6
+-    \noexpand\else \the\toks8
++                   \the\toks0 \the\toks2  % 0: top marks (\last...)
++      \noexpand\or \the\toks4 \the\toks6  % 1: bottom marks (default, \prev...)
++    \noexpand\else \the\toks8             % 2: color marks
+   }%
+ }
+ % \topmark doesn't work for the very first chapter (after the title
+@@ -321,10 +322,13 @@
+   %
+   % Do this outside of the \shipout so @code etc. will be expanded in
+   % the headline as they should be, not taken literally (outputting ''code).
++  \def\commmonheadfootline{\let\hsize=\pagewidth \texinfochars}
++  %
+   \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+-  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
++  \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}%
++  %
+   \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+-  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
++  \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}%
+   %
+   {%
+     % Have to do this stuff outside the \shipout because we want it to
+@@ -594,7 +598,7 @@
+ \def\:{\spacefactor=1000 }
+ 
+ % @* forces a line break.
+-\def\*{\hfil\break\hbox{}\ignorespaces}
++\def\*{\unskip\hfil\break\hbox{}\ignorespaces}
+ 
+ % @/ allows a line break.
+ \let\/=\allowbreak
+@@ -887,7 +891,7 @@
+ \def\popthisfilestack{\errthisfilestackempty}
+ \def\errthisfilestackempty{\errmessage{Internal error:
+   the stack of filenames is empty.}}
+-
++%
+ \def\thisfile{}
+ 
+ % @center line
+@@ -895,36 +899,46 @@
+ %
+ \parseargdef\center{%
+   \ifhmode
+-    \let\next\centerH
++    \let\centersub\centerH
+   \else
+-    \let\next\centerV
++    \let\centersub\centerV
+   \fi
+-  \next{\hfil \ignorespaces#1\unskip \hfil}%
++  \centersub{\hfil \ignorespaces#1\unskip \hfil}%
++  \let\centersub\relax % don't let the definition persist, just in case
+ }
+-\def\centerH#1{%
+-  {%
+-    \hfil\break
+-    \advance\hsize by -\leftskip
+-    \advance\hsize by -\rightskip
+-    \line{#1}%
+-    \break
+-  }%
++\def\centerH#1{{%
++  \hfil\break
++  \advance\hsize by -\leftskip
++  \advance\hsize by -\rightskip
++  \line{#1}%
++  \break
++}}
++%
++\newcount\centerpenalty
++\def\centerV#1{%
++  % The idea here is the same as in \startdefun, \cartouche, etc.: if
++  % @center is the first thing after a section heading, we need to wipe
++  % out the negative parskip inserted by \sectionheading, but still
++  % prevent a page break here.
++  \centerpenalty = \lastpenalty
++  \ifnum\centerpenalty>10000 \vskip\parskip \fi
++  \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi
++  \line{\kern\leftskip #1\kern\rightskip}%
+ }
+-\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+ 
+ % @sp n   outputs n lines of vertical space
+-
++%
+ \parseargdef\sp{\vskip #1\baselineskip}
+ 
+ % @comment ...line which is ignored...
+ % @c is the same as @comment
+ % @ignore ... @end ignore  is another way to write a comment
+-
++%
+ \def\comment{\begingroup \catcode`\^^M=\other%
+ \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+ \commentxxx}
+ {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+-
++%
+ \let\c=\comment
+ 
+ % @paragraphindent NCHARS
+@@ -1097,7 +1111,7 @@
+ % for display in the outlines, and in other places.  Thus, we have to
+ % double any backslashes.  Otherwise, a name like "\node" will be
+ % interpreted as a newline (\n), followed by o, d, e.  Not good.
+-% 
++%
+ % See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+ % related messages.  The final outcome is that it is up to the TeX user
+ % to double the backslashes and otherwise make the string valid, so
+@@ -1107,7 +1121,7 @@
+ % #1 is a control sequence in which to do the replacements,
+ % which we \xdef.
+ \def\txiescapepdf#1{%
+-  \ifx\pdfescapestring\relax
++  \ifx\pdfescapestring\thisisundefined
+     % No primitive available; should we give a warning or log?
+     % Many times it won't matter.
+   \else
+@@ -1124,10 +1138,12 @@
+ 
+ \ifpdf
+   %
+-  % Color manipulation macros based on pdfcolor.tex,
++  % Color manipulation macros using ideas from pdfcolor.tex,
+   % except using rgb instead of cmyk; the latter is said to render as a
+   % very dark gray on-screen and a very dark halftone in print, instead
+-  % of actual black.
++  % of actual black. The dark red here is dark enough to print on paper as
++  % nearly black, but still distinguishable for online viewing.  We use
++  % black by default, though.
+   \def\rgbDarkRed{0.50 0.09 0.12}
+   \def\rgbBlack{0 0 0}
+   %
+@@ -1173,8 +1189,8 @@
+   %
+   % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+   \def\dopdfimage#1#2#3{%
+-    \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+-    \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
++    \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
++    \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+     %
+     % pdftex (and the PDF format) support .pdf, .png, .jpg (among
+     % others).  Let's try in that order, PDF first since if
+@@ -1212,8 +1228,8 @@
+     \else
+       \immediate\pdfximage
+     \fi
+-      \ifdim \wd0 >0pt width \imagewidth \fi
+-      \ifdim \wd2 >0pt height \imageheight \fi
++      \ifdim \wd0 >0pt width \pdfimagewidth \fi
++      \ifdim \wd2 >0pt height \pdfimageheight \fi
+       \ifnum\pdftexversion<13
+          #1.\pdfimgext
+        \else
+@@ -1237,10 +1253,9 @@
+   % used to mark target names; must be expandable.
+   \def\pdfmkpgn#1{#1}
+   %
+-  % by default, use a color that is dark enough to print on paper as
+-  % nearly black, but still distinguishable for online viewing.
+-  \def\urlcolor{\rgbDarkRed}
+-  \def\linkcolor{\rgbDarkRed}
++  % by default, use black for everything.
++  \def\urlcolor{\rgbBlack}
++  \def\linkcolor{\rgbBlack}
+   \def\endlink{\setcolor{\maincolor}\pdfendlink}
+   %
+   % Adding outlines to PDF; macros for calculating structure of outlines
+@@ -1357,12 +1372,17 @@
+   \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+     \ifx\PP\D\let\nextsp\relax
+     \else\let\nextsp\skipspaces
+-      \ifx\p\space\else\addtokens{\filename}{\PP}%
+-        \advance\filenamelength by 1
+-      \fi
++      \addtokens{\filename}{\PP}%
++      \advance\filenamelength by 1
+     \fi
+     \nextsp}
+-  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
++  \def\getfilename#1{%
++    \filenamelength=0
++    % If we don't expand the argument now, \skipspaces will get
++    % snagged on things like "@value{foo}".
++    \edef\temp{#1}%
++    \expandafter\skipspaces\temp|\relax
++  }
+   \ifnum\pdftexversion < 14
+     \let \startlink \pdfannotlink
+   \else
+@@ -1459,9 +1479,6 @@
+ \def\ttsl{\setfontstyle{ttsl}}
+ 
+ 
+-% Default leading.
+-\newdimen\textleading  \textleading = 13.2pt
+-
+ % Set the baselineskip to #1, and the lineskip and strut size
+ % correspondingly.  There is no deep meaning behind these magic numbers
+ % used as factors; they just match (closely enough) what Knuth defined.
+@@ -1473,6 +1490,7 @@
+ % can get a sort of poor man's double spacing by redefining this.
+ \def\baselinefactor{1}
+ %
++\newdimen\textleading
+ \def\setleading#1{%
+   \dimen0 = #1\relax
+   \normalbaselineskip = \baselinefactor\dimen0
+@@ -1745,18 +1763,24 @@
+ \fi\fi
+ 
+ 
+-% Set the font macro #1 to the font named #2, adding on the
+-% specified font prefix (normally `cm').
++% Set the font macro #1 to the font named \fontprefix#2.
+ % #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+-% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+-% empty to omit).
++% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit).
++% Example:
++% #1 = \textrm
++% #2 = \rmshape
++% #3 = 10
++% #4 = \mainmagstep
++% #5 = OT1
++%
+ \def\setfont#1#2#3#4#5{%
+   \font#1=\fontprefix#2#3 scaled #4
+   \csname cmap#5\endcsname#1%
+ }
+ % This is what gets called when #5 of \setfont is empty.
+ \let\cmap\gobble
+-% emacs-page end of cmaps
++%
++% (end of cmaps)
+ 
+ % Use cm as the default font prefix.
+ % To specify the font prefix, you must define \fontprefix
+@@ -1766,7 +1790,7 @@
+ \fi
+ % Support font families that don't use the same naming scheme as CM.
+ \def\rmshape{r}
+-\def\rmbshape{bx}               %where the normal face is bold
++\def\rmbshape{bx}               % where the normal face is bold
+ \def\bfshape{b}
+ \def\bxshape{bx}
+ \def\ttshape{tt}
+@@ -1781,8 +1805,7 @@
+ \def\scshape{csc}
+ \def\scbshape{csc}
+ 
+-% Definitions for a main text size of 11pt.  This is the default in
+-% Texinfo.
++% Definitions for a main text size of 11pt.  (The default in Texinfo.)
+ %
+ \def\definetextfontsizexi{%
+ % Text fonts (11.2pt, magstep1).
+@@ -1907,7 +1930,7 @@
+ \textleading = 13.2pt % line spacing for 11pt CM
+ \textfonts            % reset the current fonts
+ \rm
+-} % end of 11pt text font size definitions
++} % end of 11pt text font size definitions, \definetextfontsizexi
+ 
+ 
+ % Definitions to make the main text be 10pt Computer Modern, with
+@@ -2039,7 +2062,7 @@
+ \textleading = 12pt   % line spacing for 10pt CM
+ \textfonts            % reset the current fonts
+ \rm
+-} % end of 10pt text font size definitions
++} % end of 10pt text font size definitions, \definetextfontsizex
+ 
+ 
+ % We provide the user-level command
+@@ -2123,7 +2146,7 @@
+   \let\tenttsl=\secttsl
+   \def\curfontsize{sec}%
+   \def\lsize{subsec}\def\lllsize{reduced}%
+-  \resetmathfonts \setleading{16pt}}
++  \resetmathfonts \setleading{17pt}}
+ \def\subsecfonts{%
+   \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+   \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+@@ -2254,8 +2277,6 @@
+ 
+ \gdef\markupsetcodequoteleft{\let`\codequoteleft}
+ \gdef\markupsetcodequoteright{\let'\codequoteright}
+-
+-\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft}
+ }
+ 
+ \let\markupsetuplqcode \markupsetcodequoteleft
+@@ -2264,6 +2285,9 @@
+ \let\markupsetuplqexample \markupsetcodequoteleft
+ \let\markupsetuprqexample \markupsetcodequoteright
+ %
++\let\markupsetuplqkbd     \markupsetcodequoteleft
++\let\markupsetuprqkbd     \markupsetcodequoteright
++%
+ \let\markupsetuplqsamp \markupsetcodequoteleft
+ \let\markupsetuprqsamp \markupsetcodequoteright
+ %
+@@ -2273,8 +2297,6 @@
+ \let\markupsetuplqverbatim \markupsetcodequoteleft
+ \let\markupsetuprqverbatim \markupsetcodequoteright
+ 
+-\let\markupsetuplqkbd \markupsetnoligaturesquoteleft
+-
+ % Allow an option to not use regular directed right quote/apostrophe
+ % (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
+ % The undirected quote is ugly, so don't make it the default, but it
+@@ -2359,13 +2381,14 @@
+   \ifx\next,%
+   \else\ifx\next-%
+   \else\ifx\next.%
++  \else\ifx\next\.%
++  \else\ifx\next\comma%
+   \else\ptexslash
+-  \fi\fi\fi
++  \fi\fi\fi\fi\fi
+   \aftersmartic
+ }
+ 
+-% like \smartslanted except unconditionally uses \ttsl, and no ic.
+-% @var is set to this for defun arguments.
++% Unconditional use \ttsl, and no ic.  @var is set to this for defuns.
+ \def\ttslanted#1{{\ttsl #1}}
+ 
+ % @cite is like \smartslanted except unconditionally use \sl.  We never want
+@@ -2430,34 +2453,12 @@
+ % @samp.
+ \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
+ 
+-% definition of @key that produces a lozenge.  Doesn't adjust to text size.
+-%\setfont\keyrm\rmshape{8}{1000}{OT1}
+-%\font\keysy=cmsy9
+-%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+-%  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+-%    \vbox{\hrule\kern-0.4pt
+-%     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+-%    \kern-0.4pt\hrule}%
+-%  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+-
+-% definition of @key with no lozenge.  If the current font is already
+-% monospace, don't change it; that way, we respect @kbdinputstyle.  But
+-% if it isn't monospace, then use \tt.
+-%
+-\def\key#1{{\setupmarkupstyle{key}%
+-  \nohyphenation
+-  \ifmonospace\else\tt\fi
+-  #1}\null}
+-
+-% ctrl is no longer a Texinfo command.
+-\def\ctrl #1{{\tt \rawbackslash \hat}#1}
++% @indicateurl is \samp, that is, with quotes.
++\let\indicateurl=\samp
+ 
+-% @file, @option are the same as @samp.
+-\let\file=\samp
+-\let\option=\samp
+-
+-% @code is a modification of @t,
+-% which makes spaces the same size as normal in the surrounding text.
++% @code (and similar) prints in typewriter, but with spaces the same
++% size as normal in the surrounding text, without hyphenation, etc.
++% This is a subroutine for that.
+ \def\tclose#1{%
+   {%
+     % Change normal interword space to be same as for the current font.
+@@ -2480,14 +2481,14 @@
+ }
+ 
+ % We *must* turn on hyphenation at `-' and `_' in @code.
++% (But see \codedashfinish below.)
+ % Otherwise, it is too hard to avoid overfull hboxes
+ % in the Emacs manual, the Library manual, etc.
+-
++%
+ % Unfortunately, TeX uses one parameter (\hyphenchar) to control
+ % both hyphenation at - and hyphenation within words.
+ % We must therefore turn them both off (\tclose does that)
+-% and arrange explicitly to hyphenate at a dash.
+-%  -- rms.
++% and arrange explicitly to hyphenate at a dash. -- rms.
+ {
+   \catcode`\-=\active \catcode`\_=\active
+   \catcode`\'=\active \catcode`\`=\active
+@@ -2501,17 +2502,38 @@
+      \let-\codedash
+      \let_\codeunder
+     \else
+-     \let-\realdash
++     \let-\normaldash
+      \let_\realunder
+     \fi
++    % Given -foo (with a single dash), we do not want to allow a break
++    % after the hyphen.
++    \global\let\codedashprev=\codedash
++    %
+     \codex
+   }
++  %
++  \gdef\codedash{\futurelet\next\codedashfinish}
++  \gdef\codedashfinish{%
++    \normaldash % always output the dash character itself.
++    %
++    % Now, output a discretionary to allow a line break, unless
++    % (a) the next character is a -, or
++    % (b) the preceding character is a -.
++    % E.g., given --posix, we do not want to allow a break after either -.
++    % Given --foo-bar, we do want to allow a break between the - and the b.
++    \ifx\next\codedash \else
++      \ifx\codedashprev\codedash
++      \else \discretionary{}{}{}\fi
++    \fi
++    % we need the space after the = for the case when \next itself is a
++    % space token; it would get swallowed otherwise.  As in @code{- a}.
++    \global\let\codedashprev= \next
++  }
+ }
+-
++\def\normaldash{-}
++%
+ \def\codex #1{\tclose{#1}\endgroup}
+ 
+-\def\realdash{-}
+-\def\codedash{-\discretionary{}{}{}}
+ \def\codeunder{%
+   % this is all so @math{@code{var_name}+1} can work.  In math mode, _
+   % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+@@ -2525,9 +2547,9 @@
+ }
+ 
+ % An additional complication: the above will allow breaks after, e.g.,
+-% each of the four underscores in __typeof__.  This is undesirable in
+-% some manuals, especially if they don't have long identifiers in
+-% general.  @allowcodebreaks provides a way to control this.
++% each of the four underscores in __typeof__.  This is bad.
++% @allowcodebreaks provides a document-level way to turn breaking at -
++% and _ on and off.
+ %
+ \newif\ifallowcodebreaks  \allowcodebreakstrue
+ 
+@@ -2546,37 +2568,28 @@
+   \fi\fi
+ }
+ 
+-% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+-% second argument specifying the text to display and an optional third
+-% arg as text to display instead of (rather than in addition to) the url
+-% itself.  First (mandatory) arg is the url.
+-% (This \urefnobreak definition isn't used now, leaving it for a while
+-% for comparison.)
+-\def\urefnobreak#1{\dourefnobreak #1,,,\finish}
+-\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup
+-  \unsepspaces
+-  \pdfurl{#1}%
+-  \setbox0 = \hbox{\ignorespaces #3}%
+-  \ifdim\wd0 > 0pt
+-    \unhbox0 % third arg given, show only that
+-  \else
+-    \setbox0 = \hbox{\ignorespaces #2}%
+-    \ifdim\wd0 > 0pt
+-      \ifpdf
+-        \unhbox0             % PDF: 2nd arg given, show only it
+-      \else
+-        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+-      \fi
+-    \else
+-      \code{#1}% only url given, so show it
+-    \fi
+-  \fi
+-  \endlink
+-\endgroup}
++% For @command, @env, @file, @option quotes seem unnecessary,
++% so use \code rather than \samp.
++\let\command=\code
++\let\env=\code
++\let\file=\code
++\let\option=\code
+ 
+-% This \urefbreak definition is the active one.
++% @uref (abbreviation for `urlref') aka @url takes an optional
++% (comma-separated) second argument specifying the text to display and
++% an optional third arg as text to display instead of (rather than in
++% addition to) the url itself.  First (mandatory) arg is the url.
++
++% TeX-only option to allow changing PDF output to show only the second
++% arg (if given), and not the url (which is then just the link target).
++\newif\ifurefurlonlylink
++
++% The main macro is \urefbreak, which allows breaking at expected
++% places within the url.  (There used to be another version, which
++% didn't support automatic breaking.)
+ \def\urefbreak{\begingroup \urefcatcodes \dourefbreak}
+ \let\uref=\urefbreak
++%
+ \def\dourefbreak#1{\urefbreakfinish #1,,,\finish}
+ \def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example
+   \unsepspaces
+@@ -2585,12 +2598,19 @@
+   \ifdim\wd0 > 0pt
+     \unhbox0 % third arg given, show only that
+   \else
+-    \setbox0 = \hbox{\ignorespaces #2}%
++    \setbox0 = \hbox{\ignorespaces #2}% look for second arg
+     \ifdim\wd0 > 0pt
+       \ifpdf
+-        \unhbox0             % PDF: 2nd arg given, show only it
++        \ifurefurlonlylink
++          % PDF plus option to not display url, show just arg
++          \unhbox0
++        \else
++          % PDF, normally display both arg and url for consistency,
++          % visibility, if the pdf is eventually used to print, etc.
++          \unhbox0\ (\urefcode{#1})%
++        \fi
+       \else
+-        \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url
++        \unhbox0\ (\urefcode{#1})% DVI, always show arg and url
+       \fi
+     \else
+       \urefcode{#1}% only url given, so show it
+@@ -2630,8 +2650,10 @@
+ % we put a little stretch before and after the breakable chars, to help
+ % line breaking of long url's.  The unequal skips make look better in
+ % cmtt at least, especially for dots.
+-\def\urefprestretch{\urefprebreak \hskip0pt plus.13em }
+-\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em }
++\def\urefprestretchamount{.13em}
++\def\urefpoststretchamount{.1em}
++\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax}
++\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax}
+ %
+ \def\urefcodeamp{\urefprestretch \&\urefpoststretch}
+ \def\urefcodedot{\urefprestretch .\urefpoststretch}
+@@ -2692,10 +2714,6 @@
+   \let\email=\uref
+ \fi
+ 
+-% @kbd is like @code, except that if the argument is just one @key command,
+-% then @kbd has no effect.
+-\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}}
+-
+ % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+ %   `example' (@kbd uses ttsl only inside of @example and friends),
+ %   or `code' (@kbd uses normal tty font always).
+@@ -2719,16 +2737,36 @@
+ % Default is `distinct'.
+ \kbdinputstyle distinct
+ 
++% @kbd is like @code, except that if the argument is just one @key command,
++% then @kbd has no effect.
++\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}}
++
+ \def\xkey{\key}
+-\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+-\ifx\one\xkey\ifx\threex\three \key{#2}%
+-\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+-\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi}
++\def\kbdsub#1#2#3\par{%
++  \def\one{#1}\def\three{#3}\def\threex{??}%
++  \ifx\one\xkey\ifx\threex\three \key{#2}%
++  \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
++  \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
++}
+ 
+-% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+-\let\indicateurl=\code
+-\let\env=\code
+-\let\command=\code
++% definition of @key that produces a lozenge.  Doesn't adjust to text size.
++%\setfont\keyrm\rmshape{8}{1000}{OT1}
++%\font\keysy=cmsy9
++%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
++%  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
++%    \vbox{\hrule\kern-0.4pt
++%     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
++%    \kern-0.4pt\hrule}%
++%  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
++
++% definition of @key with no lozenge.  If the current font is already
++% monospace, don't change it; that way, we respect @kbdinputstyle.  But
++% if it isn't monospace, then use \tt.
++%
++\def\key#1{{\setupmarkupstyle{key}%
++  \nohyphenation
++  \ifmonospace\else\tt\fi
++  #1}\null}
+ 
+ % @clicksequence{File @click{} Open ...}
+ \def\clicksequence#1{\begingroup #1\endgroup}
+@@ -2836,6 +2874,9 @@
+   }
+ }
+ 
++% ctrl is no longer a Texinfo command, but leave this definition for fun.
++\def\ctrl #1{{\tt \rawbackslash \hat}#1}
++
+ % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
+ % Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
+ % except specified as a normal braced arg, so no newlines to worry about.
+@@ -2847,6 +2888,15 @@
+   \def\inlinefmtname{#1}%
+   \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi
+ }
++%
++% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if
++% FMTNAME is tex, else ELSE-TEXT.
++\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish}
++\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{%
++  \def\inlinefmtname{#1}%
++  \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi
++}
++%
+ % For raw, must switch into @tex before parsing the argument, to avoid
+ % setting catcodes prematurely.  Doing it this way means that, for
+ % example, @inlineraw{html, foo{bar} gets a parse error instead of being
+@@ -2863,6 +2913,23 @@
+   \endgroup % close group opened by \tex.
+ }
+ 
++% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set.
++%
++\long\def\inlineifset#1{\doinlineifset #1,\finish}
++\long\def\doinlineifset#1,#2,\finish{%
++  \def\inlinevarname{#1}%
++  \expandafter\ifx\csname SET\inlinevarname\endcsname\relax
++  \else\ignorespaces#2\fi
++}
++
++% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set.
++%
++\long\def\inlineifclear#1{\doinlineifclear #1,\finish}
++\long\def\doinlineifclear#1,#2,\finish{%
++  \def\inlinevarname{#1}%
++  \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi
++}
++
+ 
+ \message{glyphs,}
+ % and logos.
+@@ -3126,12 +3193,17 @@
+   % hopefully nobody will notice/care.
+   \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+   \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+-  \ifx\curfontstyle\bfstylename
+-    % bold:
+-    \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+-  \else
+-    % regular:
+-    \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
++  \ifmonospace
++    % typewriter:
++    \font\thisecfont = ectt\ecsize \space at \nominalsize
++  \else
++    \ifx\curfontstyle\bfstylename
++      % bold:
++      \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
++    \else
++      % regular:
++      \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
++    \fi
+   \fi
+   \thisecfont
+ }
+@@ -3244,6 +3316,20 @@
+   \finishedtitlepagetrue
+ }
+ 
++% Settings used for typesetting titles: no hyphenation, no indentation,
++% don't worry much about spacing, ragged right.  This should be used
++% inside a \vbox, and fonts need to be set appropriately first.  Because
++% it is always used for titles, nothing else, we call \rmisbold.  \par
++% should be specified before the end of the \vbox, since a vbox is a group.
++%
++\def\raggedtitlesettings{%
++  \rmisbold
++  \hyphenpenalty=10000
++  \parindent=0pt
++  \tolerance=5000
++  \ptexraggedright
++}
++
+ % Macros to be used within @titlepage:
+ 
+ \let\subtitlerm=\tenrm
+@@ -3251,7 +3337,7 @@
+ 
+ \parseargdef\title{%
+   \checkenv\titlepage
+-  \leftline{\titlefonts\rmisbold #1}
++  \vbox{\titlefonts \raggedtitlesettings #1\par}%
+   % print a rule at the page bottom also.
+   \finishedtitlepagefalse
+   \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+@@ -3599,7 +3685,7 @@
+   \parskip=\smallskipamount
+   \ifdim\parskip=0pt \parskip=2pt \fi
+   %
+-  % Try typesetting the item mark that if the document erroneously says
++  % Try typesetting the item mark so that if the document erroneously says
+   % something like @itemize @samp (intending @table), there's an error
+   % right away at the @itemize.  It's not the best error message in the
+   % world, but it's better than leaving it to the @item.  This means if
+@@ -3850,18 +3936,22 @@
+ 
+ % multitable-only commands.
+ %
+-% @headitem starts a heading row, which we typeset in bold.
+-% Assignments have to be global since we are inside the implicit group
+-% of an alignment entry.  \everycr resets \everytab so we don't have to
++% @headitem starts a heading row, which we typeset in bold.  Assignments
++% have to be global since we are inside the implicit group of an
++% alignment entry.  \everycr below resets \everytab so we don't have to
+ % undo it ourselves.
+ \def\headitemfont{\b}% for people to use in the template row; not changeable
+ \def\headitem{%
+   \checkenv\multitable
+   \crcr
++  \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings
+   \global\everytab={\bf}% can't use \headitemfont since the parsing differs
+   \the\everytab % for the first item
+ }%
+ %
++% default for tables with no headings.
++\let\headitemcrhook=\relax
++%
+ % A \tab used to include \hskip1sp.  But then the space in a template
+ % line is not enough.  That is bad.  So let's go back to just `&' until
+ % we again encounter the problem the 1sp was intended to solve.
+@@ -3892,15 +3982,15 @@
+   %
+   \everycr = {%
+     \noalign{%
+-      \global\everytab={}%
++      \global\everytab={}% Reset from possible headitem.
+       \global\colcount=0 % Reset the column counter.
+-      % Check for saved footnotes, etc.
++      %
++      % Check for saved footnotes, etc.:
+       \checkinserts
+-      % Keeps underfull box messages off when table breaks over pages.
+-      %\filbreak
+-	% Maybe so, but it also creates really weird page breaks when the
+-	% table breaks over pages. Wouldn't \vfil be better?  Wait until the
+-	% problem manifests itself, so it can be fixed for real --karl.
++      %
++      % Perhaps a \nobreak, then reset:
++      \headitemcrhook
++      \global\let\headitemcrhook=\relax
+     }%
+   }%
+   %
+@@ -4139,7 +4229,7 @@
+ \def\value{\begingroup\makevalueexpandable\valuexxx}
+ \def\valuexxx#1{\expandablevalue{#1}\endgroup}
+ {
+-  \catcode`\- = \active \catcode`\_ = \active
++  \catcode`\-=\active \catcode`\_=\active
+   %
+   \gdef\makevalueexpandable{%
+     \let\value = \expandablevalue
+@@ -4148,7 +4238,7 @@
+     % ..., but we might end up with active ones in the argument if
+     % we're called from @code, as @code{@value{foo-bar_}}, though.
+     % So \let them to their normal equivalents.
+-    \let-\realdash \let_\normalunderscore
++    \let-\normaldash \let_\normalunderscore
+   }
+ }
+ 
+@@ -4160,6 +4250,11 @@
+ % it will fail (although perhaps we could fix that with sufficient work
+ % to do a one-level expansion on the result, instead of complete).
+ %
++% Unfortunately, this has the consequence that when _ is in the *value*
++% of an @set, it does not print properly in the roman fonts (get the cmr
++% dot accent at position 126 instead).  No fix comes to mind, and it's
++% been this way since 2003 or earlier, so just ignore it.
++%
+ \def\expandablevalue#1{%
+   \expandafter\ifx\csname SET#1\endcsname\relax
+     {[No value for ``#1'']}%
+@@ -4172,7 +4267,8 @@
+ % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+ % with @set.
+ %
+-% To get special treatment of `@end ifset,' call \makeond and the redefine.
++% To get the special treatment we need for `@end ifset,' we call
++% \makecond and then redefine.
+ %
+ \makecond{ifset}
+ \def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+@@ -4188,7 +4284,7 @@
+ }
+ \def\ifsetfail{\doignore{ifset}}
+ 
+-% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
++% @ifclear VAR ... @end executes the `...' iff VAR has never been
+ % defined with @set, or has been undefined with @clear.
+ %
+ % The `\else' inside the `\doifset' parameter is a trick to reuse the
+@@ -4199,6 +4295,35 @@
+ \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+ \def\ifclearfail{\doignore{ifclear}}
+ 
++% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written
++% without the @) is in fact defined.  We can only feasibly check at the
++% TeX level, so something like `mathcode' is going to considered
++% defined even though it is not a Texinfo command.
++%
++\makecond{ifcommanddefined}
++\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}}
++%
++\def\doifcmddefined#1#2{{%
++    \makevalueexpandable
++    \let\next=\empty
++    \expandafter\ifx\csname #2\endcsname\relax
++      #1% If not defined, \let\next as above.
++    \fi
++    \expandafter
++  }\next
++}
++\def\ifcmddefinedfail{\doignore{ifcommanddefined}}
++
++% @ifcommandnotdefined CMD ... handled similar to @ifclear above.
++\makecond{ifcommandnotdefined}
++\def\ifcommandnotdefined{%
++  \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}}
++\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}}
++
++% Set the `txicommandconditionals' variable, so documents have a way to
++% test if the @ifcommand...defined conditionals are available.
++\set txicommandconditionals
++
+ % @dircategory CATEGORY  -- specify a category of the dir file
+ % which this file should belong to.  Ignore this in TeX.
+ \let\dircategory=\comment
+@@ -4307,7 +4432,7 @@
+   % complicated, when \tex is in effect and \{ is a \delimiter again.
+   % We can't use \lbracecmd and \rbracecmd because texindex assumes
+   % braces and backslashes are used only as delimiters.  Perhaps we
+-  % should define @lbrace and @rbrace commands a la @comma.
++  % should use @lbracechar and @rbracechar?
+   \def\{{{\tt\char123}}%
+   \def\}{{\tt\char125}}%
+   %
+@@ -4328,8 +4453,7 @@
+   % @end macro
+   % ...
+   % @funindex commtest
+-  %
+-  % The above is not enough to reproduce the bug, but it gives the flavor.
++  % This is not enough to reproduce the bug, but it gives the flavor.
+   %
+   % Sample whatsit resulting:
+   % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+@@ -4435,6 +4559,7 @@
+   \definedummyword\guillemetright
+   \definedummyword\guilsinglleft
+   \definedummyword\guilsinglright
++  \definedummyword\lbracechar
+   \definedummyword\leq
+   \definedummyword\minus
+   \definedummyword\ogonek
+@@ -4447,6 +4572,7 @@
+   \definedummyword\quoteleft
+   \definedummyword\quoteright
+   \definedummyword\quotesinglbase
++  \definedummyword\rbracechar
+   \definedummyword\result
+   \definedummyword\textdegree
+   %
+@@ -4498,6 +4624,7 @@
+   \definedummyword\t
+   %
+   % Commands that take arguments.
++  \definedummyword\abbr
+   \definedummyword\acronym
+   \definedummyword\anchor
+   \definedummyword\cite
+@@ -4509,7 +4636,9 @@
+   \definedummyword\emph
+   \definedummyword\env
+   \definedummyword\file
++  \definedummyword\image
+   \definedummyword\indicateurl
++  \definedummyword\inforef
+   \definedummyword\kbd
+   \definedummyword\key
+   \definedummyword\math
+@@ -4525,8 +4654,21 @@
+   \definedummyword\verb
+   \definedummyword\w
+   \definedummyword\xref
++  %
++  % Consider:
++  %   @macro mkind{arg1,arg2}
++  %   @cindex \arg2\
++  %   @end macro
++  %   @mkind{foo, bar}
++  % The space after the comma will end up in the temporary definition
++  % that we make for arg2 (see \parsemargdef ff.).  We want all this to be
++  % expanded for the sake of the index, so we end up just seeing "bar".
++  \let\xeatspaces = \eatspaces
+ }
+ 
++% For testing: output @{ and @} in index sort strings as \{ and \}.
++\newif\ifusebracesinindexes
++
+ % \indexnofonts is used when outputting the strings to sort the index
+ % by, and when constructing control sequence names.  It eliminates all
+ % control sequences and just writes whatever the best ASCII sort string
+@@ -4555,8 +4697,16 @@
+   % Unfortunately, texindex is not prepared to handle braces in the
+   % content at all.  So for index sorting, we map @{ and @} to strings
+   % starting with |, since that ASCII character is between ASCII { and }.
+-  \def\{{|a}%
+-  \def\}{|b}%
++  \ifusebracesinindexes
++    \def\lbracechar{\lbracecmd}%
++    \def\rbracechar{\rbracecmd}%
++  \else
++    \def\lbracechar{|a}%
++    \def\rbracechar{|b}%
++  \fi
++  \let\{=\lbracechar
++  \let\}=\rbracechar
++  %
+   %
+   % Non-English letters.
+   \def\AA{AA}%
+@@ -4732,10 +4882,9 @@
+ %
+ % ..., ready, GO:
+ %
+-\def\safewhatsit#1{%
+-\ifhmode
++\def\safewhatsit#1{\ifhmode
+   #1%
+-\else
++ \else
+   % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+   \whatsitskip = \lastskip
+   \edef\lastskipmacro{\the\lastskip}%
+@@ -4759,7 +4908,6 @@
+     % to re-insert the same penalty (values >10000 are used for various
+     % signals); since we just inserted a non-discardable item, any
+     % following glue (such as a \parskip) would be a breakpoint.  For example:
+-    %
+     %   @deffn deffn-whatever
+     %   @vindex index-whatever
+     %   Description.
+@@ -4772,8 +4920,7 @@
+     % (the whatsit from the \write), so we must insert a \nobreak.
+     \nobreak\vskip\whatsitskip
+   \fi
+-\fi
+-}
++\fi}
+ 
+ % The index entry written in the file actually looks like
+ %  \entry {sortstring}{page}{topic}
+@@ -5520,14 +5667,6 @@
+ 
+ % Define @majorheading, @heading and @subheading
+ 
+-% NOTE on use of \vbox for chapter headings, section headings, and such:
+-%       1) We use \vbox rather than the earlier \line to permit
+-%          overlong headings to fold.
+-%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+-%          heading is obnoxious; this forbids it.
+-%       3) Likewise, headings look best if no \parindent is used, and
+-%          if justification is not attempted.  Hence \raggedright.
+-
+ \def\majorheading{%
+   {\advance\chapheadingskip by 10pt \chapbreak }%
+   \parsearg\chapheadingzzz
+@@ -5535,10 +5674,8 @@
+ 
+ \def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+ \def\chapheadingzzz#1{%
+-  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+-                    \parindent=0pt\ptexraggedright
+-                    \rmisbold #1\hfill}}%
+-  \bigskip \par\penalty 200\relax
++  \vbox{\chapfonts \raggedtitlesettings #1\par}%
++  \nobreak\bigskip \nobreak
+   \suppressfirstparagraphindent
+ }
+ 
+@@ -5697,8 +5834,7 @@
+     %
+     % Typeset the actual heading.
+     \nobreak % Avoid page breaks at the interline glue.
+-    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+-          \hangindent=\wd0 \centerparametersmaybe
++    \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe
+           \unhbox0 #1\par}%
+   }%
+   \nobreak\bigskip % no page break after a chapter title
+@@ -5720,18 +5856,18 @@
+ \def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+ %
+ \def\unnchfopen #1{%
+-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+-                       \parindent=0pt\ptexraggedright
+-                       \rmisbold #1\hfill}}\bigskip \par\nobreak
++  \chapoddpage
++  \vbox{\chapfonts \raggedtitlesettings #1\par}%
++  \nobreak\bigskip\nobreak
+ }
+ \def\chfopen #1#2{\chapoddpage {\chapfonts
+ \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+ \par\penalty 5000 %
+ }
+ \def\centerchfopen #1{%
+-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+-                       \parindent=0pt
+-                       \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak
++  \chapoddpage
++  \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}%
++  \nobreak\bigskip \nobreak
+ }
+ \def\CHAPFopen{%
+   \global\let\chapmacro=\chfopen
+@@ -5822,7 +5958,7 @@
+     %
+     % Now the second mark, after the heading break.  No break points
+     % between here and the heading.
+-    \let\prevsectiondefs=\lastsectiondefs
++    \global\let\prevsectiondefs=\lastsectiondefs
+     \domark
+     %
+     % Only insert the space after the number if we have a section number.
+@@ -5876,14 +6012,15 @@
+   %
+   % We'll almost certainly start a paragraph next, so don't let that
+   % glue accumulate.  (Not a breakpoint because it's preceded by a
+-  % discardable item.)
++  % discardable item.)  However, when a paragraph is not started next
++  % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out
++  % or the negative glue will cause weirdly wrong output, typically
++  % obscuring the section heading with something else.
+   \vskip-\parskip
+   %
+-  % This is purely so the last item on the list is a known \penalty >
+-  % 10000.  This is so \startdefun can avoid allowing breakpoints after
+-  % section headings.  Otherwise, it would insert a valid breakpoint between:
+-  %   @section sec-whatever
+-  %   @deffn def-whatever
++  % This is so the last item on the main vertical list is a known
++  % \penalty > 10000, so \startdefun, etc., can recognize the situation
++  % and do the needful.
+   \penalty 10001
+ }
+ 
+@@ -6188,8 +6325,8 @@
+   \catcode `\|=\other
+   \catcode `\<=\other
+   \catcode `\>=\other
+-  \catcode`\`=\other
+-  \catcode`\'=\other
++  \catcode `\`=\other
++  \catcode `\'=\other
+   \escapechar=`\\
+   %
+   % ' is active in math mode (mathcode"8000).  So reset it, and all our
+@@ -6213,7 +6350,7 @@
+   \let\/=\ptexslash
+   \let\*=\ptexstar
+   \let\t=\ptext
+-  \expandafter \let\csname top\endcsname=\ptextop  % outer
++  \expandafter \let\csname top\endcsname=\ptextop  % we've made it outer
+   \let\frenchspacing=\plainfrenchspacing
+   %
+   \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+@@ -6297,13 +6434,11 @@
+ 				% side, and for 6pt waste from
+ 				% each corner char, and rule thickness
+   \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+-  % Flag to tell @lisp, etc., not to narrow margin.
+-  \let\nonarrowing = t%
+   %
+   % If this cartouche directly follows a sectioning command, we need the
+   % \parskip glue (backspaced over by default) or the cartouche can
+   % collide with the section heading.
+-  \ifnum\lastpenalty>10000 \vskip\parskip \fi
++  \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
+   %
+   \vbox\bgroup
+       \baselineskip=0pt\parskip=0pt\lineskip=0pt
+@@ -6338,7 +6473,7 @@
+ \newdimen\nonfillparindent
+ \def\nonfillstart{%
+   \aboveenvbreak
+-  \hfuzz = 12pt % Don't be fussy
++  \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy
+   \sepspaces % Make spaces be word-separators rather than space tokens.
+   \let\par = \lisppar % don't ignore blank lines
+   \obeylines % each line of input is a line of output
+@@ -6465,9 +6600,13 @@
+ 
+ 
+ % @raggedright does more-or-less normal line breaking but no right
+-% justification.  From plain.tex.
++% justification.  From plain.tex.  Don't stretch around special
++% characters in urls in this environment, since the stretch at the right
++% should be enough.
+ \envdef\raggedright{%
+-  \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax
++  \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax
++  \def\urefprestretchamount{0pt}%
++  \def\urefpoststretchamount{0pt}%
+ }
+ \let\Eraggedright\par
+ 
+@@ -6496,16 +6635,9 @@
+ \makedispenvdef{quotation}{\quotationstart}
+ %
+ \def\quotationstart{%
+-  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+-  \parindent=0pt
+-  %
+-  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
++  \indentedblockstart % same as \indentedblock, but increase right margin too.
+   \ifx\nonarrowing\relax
+-    \advance\leftskip by \lispnarrowing
+     \advance\rightskip by \lispnarrowing
+-    \exdentamount = \lispnarrowing
+-  \else
+-    \let\nonarrowing = \relax
+   \fi
+   \parsearg\quotationlabel
+ }
+@@ -6531,6 +6663,32 @@
+   \fi
+ }
+ 
++% @indentedblock is like @quotation, but indents only on the left and
++% has no optional argument.
++%
++\makedispenvdef{indentedblock}{\indentedblockstart}
++%
++\def\indentedblockstart{%
++  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
++  \parindent=0pt
++  %
++  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
++  \ifx\nonarrowing\relax
++    \advance\leftskip by \lispnarrowing
++    \exdentamount = \lispnarrowing
++  \else
++    \let\nonarrowing = \relax
++  \fi
++}
++
++% Keep a nonzero parskip for the environment, since we're doing normal filling.
++%
++\def\Eindentedblock{%
++  \par
++  {\parskip=0pt \afterenvbreak}%
++}
++\def\Esmallindentedblock{\Eindentedblock}
++
+ 
+ % LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+ % If we want to allow any <char> as delimiter,
+@@ -7009,7 +7167,10 @@
+   \df \sl \hyphenchar\font=0
+   %
+   % On the other hand, if an argument has two dashes (for instance), we
+-  % want a way to get ttsl.  Let's try @var for that.
++  % want a way to get ttsl.  We used to recommend @var for that, so
++  % leave the code in, but it's strange for @var to lead to typewriter.
++  % Nowadays we recommend @code, since the difference between a ttsl hyphen
++  % and a tt hyphen is pretty tiny.  @code also disables ?` !`.
+   \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
+   #1%
+   \sl\hyphenchar\font=45
+@@ -7338,7 +7499,7 @@
+ 
+ % Parse the optional {params} list.  Set up \paramno and \paramlist
+ % so \defmacro knows what to do.  Define \macarg.BLAH for each BLAH
+-% in the params list to some hook where the argument si to be expanded.  If
++% in the params list to some hook where the argument is to be expanded.  If
+ % there are less than 10 arguments that hook is to be replaced by ##N where N
+ % is the position in that list, that is to say the macro arguments are to be
+ % defined `a la TeX in the macro body.
+@@ -7793,7 +7954,7 @@
+   \fi\fi
+ }
+ 
+-
++% 
+ % @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
+ % the node name, #2 the name of the Info cross-reference, #3 the printed
+ % node name, #4 the name of the Info file, #5 the name of the printed
+@@ -7803,16 +7964,21 @@
+ \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+ \def\ref#1{\xrefX[#1,,,,,,,]}
+ %
+-\newbox\topbox
++\newbox\toprefbox
+ \newbox\printedrefnamebox
++\newbox\infofilenamebox
+ \newbox\printedmanualbox
+ %
+ \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+   \unsepspaces
+   %
++  % Get args without leading/trailing spaces.
+   \def\printedrefname{\ignorespaces #3}%
+   \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+   %
++  \def\infofilename{\ignorespaces #4}%
++  \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
++  %
+   \def\printedmanual{\ignorespaces #5}%
+   \setbox\printedmanualbox  = \hbox{\printedmanual\unskip}%
+   %
+@@ -7845,12 +8011,20 @@
+   \ifpdf
+     {\indexnofonts
+      \turnoffactive
++     \makevalueexpandable
+      % This expands tokens, so do it after making catcode changes, so _
+-     % etc. don't get their TeX definitions.
++     % etc. don't get their TeX definitions.  This ignores all spaces in
++     % #4, including (wrongly) those in the middle of the filename.
+      \getfilename{#4}%
+      %
++     % This (wrongly) does not take account of leading or trailing
++     % spaces in #1, which should be ignored.
+      \edef\pdfxrefdest{#1}%
+-     \txiescapepdf\pdfxrefdest
++     \ifx\pdfxrefdest\empty
++       \def\pdfxrefdest{Top}% no empty targets
++     \else
++       \txiescapepdf\pdfxrefdest  % escape PDF special chars
++     \fi
+      %
+      \leavevmode
+      \startlink attr{/Border [0 0 0]}%
+@@ -7883,7 +8057,7 @@
+       \printedrefname
+     \fi
+     %
+-    % if the user also gave the printed manual name (fifth arg), append
++    % If the user also gave the printed manual name (fifth arg), append
+     % "in MANUALNAME".
+     \ifdim \wd\printedmanualbox > 0pt
+       \space \putwordin{} \cite{\printedmanual}%
+@@ -7898,32 +8072,20 @@
+     % this is a loss.  Therefore, we give the text of the node name
+     % again, so it is as if TeX is seeing it for the first time.
+     %
+-    % Cross-manual reference.  Only include the "Section ``foo'' in" if
+-    % the foo is neither missing or Top.  Thus, @xref{,,,foo,The Foo Manual}
+-    % outputs simply "see The Foo Manual".
+     \ifdim \wd\printedmanualbox > 0pt
+-      % What is the 7sp about?  The idea is that we also want to omit
+-      % the Section part if we would be printing "Top", since they are
+-      % clearly trying to refer to the whole manual.  But, this being
+-      % TeX, we can't easily compare strings while ignoring the possible
+-      % spaces before and after in the input.  By adding the arbitrary
+-      % 7sp, we make it much less likely that a real node name would
+-      % happen to have the same width as "Top" (e.g., in a monospaced font).
+-      % I hope it will never happen in practice.
++      % Cross-manual reference with a printed manual name.
+       %
+-      % For the same basic reason, we retypeset the "Top" at every
+-      % reference, since the current font is indeterminate.
++      \crossmanualxref{\cite{\printedmanual\unskip}}%
++    %
++    \else\ifdim \wd\infofilenamebox > 0pt
++      % Cross-manual reference with only an info filename (arg 4), no
++      % printed manual name (arg 5).  This is essentially the same as
++      % the case above; we output the filename, since we have nothing else.
+       %
+-      \setbox\topbox = \hbox{Top\kern7sp}%
+-      \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+-      \ifdim \wd2 > 7sp
+-        \ifdim \wd2 = \wd\topbox \else
+-          \putwordSection{} ``\printedrefname'' \putwordin{}\space
+-        \fi
+-      \fi
+-      \cite{\printedmanual}%
++      \crossmanualxref{\code{\infofilename\unskip}}%
++    %
+     \else
+-      % Reference in this manual.
++      % Reference within this manual.
+       %
+       % _ (for example) has to be the character _ for the purposes of the
+       % control sequence corresponding to the node, but it has to expand
+@@ -7944,11 +8106,37 @@
+       %
+       % output the `page 3'.
+       \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+-    \fi
++    \fi\fi
+   \fi
+   \endlink
+ \endgroup}
+ 
++% Output a cross-manual xref to #1.  Used just above (twice).
++%
++% Only include the text "Section ``foo'' in" if the foo is neither
++% missing or Top.  Thus, @xref{,,,foo,The Foo Manual} outputs simply
++% "see The Foo Manual", the idea being to refer to the whole manual.
++%
++% But, this being TeX, we can't easily compare our node name against the
++% string "Top" while ignoring the possible spaces before and after in
++% the input.  By adding the arbitrary 7sp below, we make it much less
++% likely that a real node name would have the same width as "Top" (e.g.,
++% in a monospaced font).  Hopefully it will never happen in practice.
++%
++% For the same basic reason, we retypeset the "Top" at every
++% reference, since the current font is indeterminate.
++%
++\def\crossmanualxref#1{%
++  \setbox\toprefbox = \hbox{Top\kern7sp}%
++  \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
++  \ifdim \wd2 > 7sp  % nonempty?
++    \ifdim \wd2 = \wd\toprefbox \else  % same as Top?
++      \putwordSection{} ``\printedrefname'' \putwordin{}\space
++    \fi
++  \fi
++  #1%
++}
++
+ % This macro is called from \xrefX for the `[nodename]' part of xref
+ % output.  It's a separate macro only so it can be changed more easily,
+ % since square brackets don't work well in some documents.  Particularly
+@@ -8173,6 +8361,7 @@
+ \gdef\footnote{%
+   \let\indent=\ptexindent
+   \let\noindent=\ptexnoindent
++  %
+   \global\advance\footnoteno by \@ne
+   \edef\thisfootno{$^{\the\footnoteno}$}%
+   %
+@@ -8196,6 +8385,11 @@
+ %
+ \gdef\dofootnote{%
+   \insert\footins\bgroup
++  %
++  % Nested footnotes are not supported in TeX, that would take a lot
++  % more work.  (\startsavinginserts does not suffice.)
++  \let\footnote=\errfootnote
++  %
+   % We want to typeset this text as a normal paragraph, even if the
+   % footnote reference occurs in (for example) a display environment.
+   % So reset some parameters.
+@@ -8233,13 +8427,19 @@
+ }
+ }%end \catcode `\@=11
+ 
++\def\errfootnote{%
++  \errhelp=\EMsimple
++  \errmessage{Nested footnotes not supported in texinfo.tex,
++    even though they work in makeinfo; sorry}
++}
++
+ % In case a @footnote appears in a vbox, save the footnote text and create
+ % the real \insert just after the vbox finished.  Otherwise, the insertion
+ % would be lost.
+ % Similarly, if a @footnote appears inside an alignment, save the footnote
+ % text to a box and make the \insert when a row of the table is finished.
+ % And the same can be done for other insert classes.  --kasal, 16nov03.
+-
++%
+ % Replace the \insert primitive by a cheating macro.
+ % Deeper inside, just make sure that the saved insertions are not spilled
+ % out prematurely.
+@@ -8316,7 +8516,7 @@
+   it from ftp://tug.org/tex/epsf.tex.}
+ %
+ \def\image#1{%
+-  \ifx\epsfbox\thisiundefined
++  \ifx\epsfbox\thisisundefined
+     \ifwarnednoepsf \else
+       \errhelp = \noepsfhelp
+       \errmessage{epsf.tex not found, images will be ignored}%
+@@ -8340,6 +8540,13 @@
+   % If the image is by itself, center it.
+   \ifvmode
+     \imagevmodetrue
++  \else \ifx\centersub\centerV
++    % for @center @image, we need a vbox so we can have our vertical space
++    \imagevmodetrue
++    \vbox\bgroup % vbox has better behavior than vtop herev
++  \fi\fi
++  %
++  \ifimagevmode
+     \nobreak\medskip
+     % Usually we'll have text after the image which will insert
+     % \parskip glue, so insert it here too to equalize the space
+@@ -8349,9 +8556,13 @@
+   \fi
+   %
+   % Leave vertical mode so that indentation from an enclosing
+-  % environment such as @quotation is respected.  On the other hand, if
+-  % it's at the top level, we don't want the normal paragraph indentation.
+-  \noindent
++  %  environment such as @quotation is respected.
++  % However, if we're at the top level, we don't want the
++  %  normal paragraph indentation.
++  % On the other hand, if we are in the case of @center @image, we don't
++  %  want to start a paragraph, which will create a hsize-width box and
++  %  eradicate the centering.
++  \ifx\centersub\centerV\else \noindent \fi
+   %
+   % Output the image.
+   \ifpdf
+@@ -8363,7 +8574,10 @@
+     \epsfbox{#1.eps}%
+   \fi
+   %
+-  \ifimagevmode \medskip \fi  % space after the standalone image
++  \ifimagevmode
++    \medskip  % space after a standalone image
++  \fi
++  \ifx\centersub\centerV \egroup \fi
+ \endgroup}
+ 
+ 
+@@ -9793,11 +10007,9 @@
+ \catcode`\"=\active
+ \def\activedoublequote{{\tt\char34}}
+ \let"=\activedoublequote
+-\catcode`\~=\active
+-\def~{{\tt\char126}}
++\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde
+ \chardef\hat=`\^
+-\catcode`\^=\active
+-\def^{{\tt \hat}}
++\catcode`\^=\active \def\activehat{{\tt \hat}} \let^ = \activehat
+ 
+ \catcode`\_=\active
+ \def_{\ifusingtt\normalunderscore\_}
+@@ -9807,16 +10019,26 @@
+ 
+ \catcode`\|=\active
+ \def|{{\tt\char124}}
++
+ \chardef \less=`\<
+-\catcode`\<=\active
+-\def<{{\tt \less}}
++\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless
+ \chardef \gtr=`\>
+-\catcode`\>=\active
+-\def>{{\tt \gtr}}
+-\catcode`\+=\active
+-\def+{{\tt \char 43}}
+-\catcode`\$=\active
+-\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
++\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr
++\catcode`\+=\active \def+{{\tt \char 43}}
++\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
++
++% used for headline/footline in the output routine, in case the page
++% breaks in the middle of an @tex block.
++\def\texinfochars{%
++  \let< = \activeless
++  \let> = \activegtr
++  \let~ = \activetilde
++  \let^ = \activehat
++  \markupsetuplqdefault \markupsetuprqdefault
++  \let\b = \strong
++  \let\i = \smartitalic
++  % in principle, all other definitions in \tex have to be undone too.
++}
+ 
+ % If a .fmt file is being used, characters that might appear in a file
+ % name cannot be active until we have parsed the command line.
+@@ -9866,22 +10088,26 @@
+ @gdef@otherbackslash{@let\=@realbackslash}
+ 
+ % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+-% the literal character `\'.
++% the literal character `\'.  Also revert - to its normal character, in
++% case the active - from code has slipped in.
+ %
+-@def@normalturnoffactive{%
+-  @let"=@normaldoublequote
+-  @let$=@normaldollar %$ font-lock fix
+-  @let+=@normalplus
+-  @let<=@normalless
+-  @let>=@normalgreater
+-  @let\=@normalbackslash
+-  @let^=@normalcaret
+-  @let_=@normalunderscore
+-  @let|=@normalverticalbar
+-  @let~=@normaltilde
+-  @markupsetuplqdefault
+-  @markupsetuprqdefault
+-  @unsepspaces
++{@catcode`- = @active
++ @gdef@normalturnoffactive{%
++   @let-=@normaldash
++   @let"=@normaldoublequote
++   @let$=@normaldollar %$ font-lock fix
++   @let+=@normalplus
++   @let<=@normalless
++   @let>=@normalgreater
++   @let\=@normalbackslash
++   @let^=@normalcaret
++   @let_=@normalunderscore
++   @let|=@normalverticalbar
++   @let~=@normaltilde
++   @markupsetuplqdefault
++   @markupsetuprqdefault
++   @unsepspaces
++ }
+ }
+ 
+ % Make _ and + \other characters, temporarily.
+diff -urN glibc-2.17-c758a686/manual/threads.texi glibc/manual/threads.texi
+--- glibc-2.17-c758a686/manual/threads.texi	1969-12-31 19:00:00.000000000 -0500
++++ glibc/manual/threads.texi	2014-09-12 16:10:06.042792724 -0400
+@@ -0,0 +1,254 @@
++@node POSIX Threads
++@c @node POSIX Threads, Internal Probes, Cryptographic Functions, Top
++@chapter POSIX Threads
++@c %MENU% POSIX Threads
++@cindex pthreads
++
++This chapter describes the @glibcadj{} POSIX Thread implementation.
++
++@menu
++* Thread-specific Data::          Support for creating and
++				  managing thread-specific data
++* Non-POSIX Extensions::          Additional functions to extend
++				  POSIX Thread functionality
++@end menu
++
++@node Thread-specific Data
++@section Thread-specific Data
++
++The @glibcadj{} implements functions to allow users to create and manage
++data specific to a thread.  Such data may be destroyed at thread exit,
++if a destructor is provided.  The following functions are defined:
++
++@comment pthread.h
++@comment POSIX
++@deftypefun int pthread_key_create (pthread_key_t *@var{key}, void (*@var{destructor})(void*))
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c pthread_key_create ok
++@c  KEY_UNUSED ok
++@c  KEY_USABLE ok
++Create a thread-specific data key for the calling thread, referenced by
++@var{key}.
++
++Objects declared with the C++11 @code{thread_local} keyword are destroyed
++before thread-specific data, so they should not be used in thread-specific
++data destructors or even as members of the thread-specific data, since the
++latter is passed as an argument to the destructor function.
++@end deftypefun
++
++@comment pthread.h
++@comment POSIX
++@deftypefun int pthread_key_delete (pthread_key_t @var{key})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c pthread_key_delete ok
++@c   This uses atomic compare and exchange to increment the seq number
++@c   after testing it's not a KEY_UNUSED seq number.
++@c  KEY_UNUSED dup ok
++Destroy the thread-specific data @var{key} in the calling thread.  The
++destructor for the thread-specific data is not called during destruction, nor
++is it called during thread exit.
++@end deftypefun
++
++@comment pthread.h
++@comment POSIX
++@deftypefun void *pthread_getspecific (pthread_key_t @var{key})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c pthread_getspecific ok
++Return the thread-specific data associated with @var{key} in the calling
++thread.
++@end deftypefun
++
++@comment pthread.h
++@comment POSIX
++@deftypefun int pthread_setspecific (pthread_key_t @var{key}, const void *@var{value})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
++@c pthread_setspecific @asucorrupt @ascuheap @acucorrupt @acsmem
++@c   a level2 block may be allocated by a signal handler after
++@c   another call already made a decision to allocate it, thus losing
++@c   the allocated value.  the seq number is updated before the
++@c   value, which might cause an earlier-generation value to seem
++@c   current if setspecific is cancelled or interrupted by a signal
++@c  KEY_UNUSED ok
++@c  calloc dup @ascuheap @acsmem
++Associate the thread-specific @var{value} with @var{key} in the calling thread.
++@end deftypefun
++
++
++@node Non-POSIX Extensions
++@section Non-POSIX Extensions
++
++In addition to implementing the POSIX API for threads, @theglibc{} provides
++additional functions and interfaces to provide functionality not specified in
++the standard.
++
++@menu
++* Default Thread Attributes::             Setting default attributes for
++					  threads in a process.
++@end menu
++
++@node Default Thread Attributes
++@subsection Setting Process-wide defaults for thread attributes
++
++@Theglibc{} provides non-standard API functions to set and get the default
++attributes used in the creation of threads in a process.
++
++@comment pthread.h
++@comment GNU
++@deftypefun int pthread_getattr_default_np (pthread_attr_t *@var{attr})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c Takes lock around read from default_pthread_attr.
++Get the default attribute values and set @var{attr} to match.  This
++function returns @math{0} on success and a non-zero error code on
++failure.
++@end deftypefun
++
++@comment pthread.h
++@comment GNU
++@deftypefun int pthread_setattr_default_np (pthread_attr_t *@var{attr})
++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
++@c pthread_setattr_default_np @ascuheap @asulock @aculock @acsmem
++@c  check_sched_policy_attr ok
++@c  check_sched_priority_attr ok
++@c   sched_get_priority_min dup ok
++@c   sched_get_priority_max dup ok
++@c  check_cpuset_attr ok
++@c   determine_cpumask_size ok
++@c  check_stacksize_attr ok
++@c  lll_lock @asulock @aculock
++@c  free dup @ascuheap @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  memcpy dup ok
++@c  lll_unlock @asulock @aculock
++Set the default attribute values to match the values in @var{attr}.  The
++function returns @math{0} on success and a non-zero error code on failure.
++The following error codes are defined for this function:
++
++@table @code
++@item EINVAL
++At least one of the values in @var{attr} does not qualify as valid for the
++attributes or the stack address is set in the attribute.
++@item ENOMEM
++The system does not have sufficient memory.
++@end table
++@end deftypefun
++
++@c FIXME these are undocumented:
++@c pthread_atfork
++@c pthread_attr_destroy
++@c pthread_attr_getaffinity_np
++@c pthread_attr_getdetachstate
++@c pthread_attr_getguardsize
++@c pthread_attr_getinheritsched
++@c pthread_attr_getschedparam
++@c pthread_attr_getschedpolicy
++@c pthread_attr_getscope
++@c pthread_attr_getstack
++@c pthread_attr_getstackaddr
++@c pthread_attr_getstacksize
++@c pthread_attr_init
++@c pthread_attr_setaffinity_np
++@c pthread_attr_setdetachstate
++@c pthread_attr_setguardsize
++@c pthread_attr_setinheritsched
++@c pthread_attr_setschedparam
++@c pthread_attr_setschedpolicy
++@c pthread_attr_setscope
++@c pthread_attr_setstack
++@c pthread_attr_setstackaddr
++@c pthread_attr_setstacksize
++@c pthread_barrierattr_destroy
++@c pthread_barrierattr_getpshared
++@c pthread_barrierattr_init
++@c pthread_barrierattr_setpshared
++@c pthread_barrier_destroy
++@c pthread_barrier_init
++@c pthread_barrier_wait
++@c pthread_cancel
++@c pthread_cleanup_push
++@c pthread_cleanup_pop
++@c pthread_condattr_destroy
++@c pthread_condattr_getclock
++@c pthread_condattr_getpshared
++@c pthread_condattr_init
++@c pthread_condattr_setclock
++@c pthread_condattr_setpshared
++@c pthread_cond_broadcast
++@c pthread_cond_destroy
++@c pthread_cond_init
++@c pthread_cond_signal
++@c pthread_cond_timedwait
++@c pthread_cond_wait
++@c pthread_create
++@c pthread_detach
++@c pthread_equal
++@c pthread_exit
++@c pthread_getaffinity_np
++@c pthread_getattr_np
++@c pthread_getconcurrency
++@c pthread_getcpuclockid
++@c pthread_getname_np
++@c pthread_getschedparam
++@c pthread_join
++@c pthread_kill
++@c pthread_kill_other_threads_np
++@c pthread_mutexattr_destroy
++@c pthread_mutexattr_getkind_np
++@c pthread_mutexattr_getprioceiling
++@c pthread_mutexattr_getprotocol
++@c pthread_mutexattr_getpshared
++@c pthread_mutexattr_getrobust
++@c pthread_mutexattr_getrobust_np
++@c pthread_mutexattr_gettype
++@c pthread_mutexattr_init
++@c pthread_mutexattr_setkind_np
++@c pthread_mutexattr_setprioceiling
++@c pthread_mutexattr_setprotocol
++@c pthread_mutexattr_setpshared
++@c pthread_mutexattr_setrobust
++@c pthread_mutexattr_setrobust_np
++@c pthread_mutexattr_settype
++@c pthread_mutex_consistent
++@c pthread_mutex_consistent_np
++@c pthread_mutex_destroy
++@c pthread_mutex_getprioceiling
++@c pthread_mutex_init
++@c pthread_mutex_lock
++@c pthread_mutex_setprioceiling
++@c pthread_mutex_timedlock
++@c pthread_mutex_trylock
++@c pthread_mutex_unlock
++@c pthread_once
++@c pthread_rwlockattr_destroy
++@c pthread_rwlockattr_getkind_np
++@c pthread_rwlockattr_getpshared
++@c pthread_rwlockattr_init
++@c pthread_rwlockattr_setkind_np
++@c pthread_rwlockattr_setpshared
++@c pthread_rwlock_destroy
++@c pthread_rwlock_init
++@c pthread_rwlock_rdlock
++@c pthread_rwlock_timedrdlock
++@c pthread_rwlock_timedwrlock
++@c pthread_rwlock_tryrdlock
++@c pthread_rwlock_trywrlock
++@c pthread_rwlock_unlock
++@c pthread_rwlock_wrlock
++@c pthread_self
++@c pthread_setaffinity_np
++@c pthread_setcancelstate
++@c pthread_setcanceltype
++@c pthread_setconcurrency
++@c pthread_setname_np
++@c pthread_setschedparam
++@c pthread_setschedprio
++@c pthread_sigmask
++@c pthread_sigqueue
++@c pthread_spin_destroy
++@c pthread_spin_init
++@c pthread_spin_lock
++@c pthread_spin_trylock
++@c pthread_spin_unlock
++@c pthread_testcancel
++@c pthread_timedjoin_np
++@c pthread_tryjoin_np
++@c pthread_yield
+diff -urN glibc-2.17-c758a686/manual/time.texi glibc/manual/time.texi
+--- glibc-2.17-c758a686/manual/time.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/time.texi	2014-09-12 16:10:06.044792719 -0400
+@@ -79,6 +79,7 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun double difftime (time_t @var{time1}, time_t @var{time0})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{difftime} function returns the number of seconds of elapsed
+ time between calendar time @var{time1} and calendar time @var{time0}, as
+ a value of type @code{double}.  The difference ignores leap seconds
+@@ -246,6 +247,12 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun clock_t clock (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On Hurd, this calls task_info twice and adds user and system time
++@c from both basic and thread time info structs.  On generic posix,
++@c calls times and adds utime and stime.  On bsd, calls getrusage and
++@c safely converts stime and utime to clock.  On linux, calls
++@c clock_gettime.
+ This function returns the calling process' current CPU time.  If the CPU
+ time is not available or cannot be represented, @code{clock} returns the
+ value @code{(clock_t)(-1)}.
+@@ -310,6 +317,12 @@
+ @comment sys/times.h
+ @comment POSIX.1
+ @deftypefun clock_t times (struct tms *@var{buffer})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On HURD, this calls task_info twice, for basic and thread times info,
++@c adding user and system times into tms, and then gettimeofday, to
++@c compute the real time.  On BSD, it calls getclktck, getrusage (twice)
++@c and time.  On Linux, it's a syscall with special handling to account
++@c for clock_t counts that look like error values.
+ The @code{times} function stores the processor time information for
+ the calling process in @var{buffer}.
+ 
+@@ -409,6 +422,7 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun time_t time (time_t *@var{result})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{time} function returns the current calendar time as a value of
+ type @code{time_t}.  If the argument @var{result} is not a null pointer,
+ the calendar time value is also stored in @code{*@var{result}}.  If the
+@@ -420,7 +434,9 @@
+ @c Linux.
+ @comment time.h
+ @comment SVID, XPG
+-@deftypefun int stime (time_t *@var{newtime})
++@deftypefun int stime (const time_t *@var{newtime})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On unix, this is implemented in terms of settimeofday.
+ @code{stime} sets the system clock, i.e., it tells the system that the
+ current calendar time is @var{newtime}, where @code{newtime} is
+ interpreted as described in the above definition of @code{time_t}.
+@@ -475,6 +491,12 @@
+ @comment sys/time.h
+ @comment BSD
+ @deftypefun int gettimeofday (struct timeval *@var{tp}, struct timezone *@var{tzp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On most GNU/Linux systems this is a direct syscall, but the posix/
++@c implementation (not used on GNU/Linux or GNU/Hurd) relies on time and
++@c localtime_r, saving and restoring tzname in an unsafe manner.
++@c On some GNU/Linux variants, ifunc resolvers are used in shared libc
++@c for vdso resolution.  ifunc-vdso-revisit.
+ The @code{gettimeofday} function returns the current calendar time as
+ the elapsed time since the epoch in the @code{struct timeval} structure
+ indicated by @var{tp}.  (@pxref{Elapsed Time} for a description of
+@@ -498,6 +520,9 @@
+ @comment sys/time.h
+ @comment BSD
+ @deftypefun int settimeofday (const struct timeval *@var{tp}, const struct timezone *@var{tzp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On HURD, it calls host_set_time with a privileged port.  On other
++@c unix systems, it's a syscall.
+ The @code{settimeofday} function sets the current calendar time in the
+ system clock according to the arguments.  As for @code{gettimeofday},
+ the calendar time is represented as the elapsed time since the epoch.
+@@ -539,6 +564,10 @@
+ @comment sys/time.h
+ @comment BSD
+ @deftypefun int adjtime (const struct timeval *@var{delta}, struct timeval *@var{olddelta})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On hurd and mach, call host_adjust_time with a privileged port.  On
++@c Linux, it's implemented in terms of adjtimex.  On other unixen, it's
++@c a syscall.
+ This function speeds up or slows down the system clock in order to make
+ a gradual adjustment.  This ensures that the calendar time reported by
+ the system clock is always monotonically increasing, which might not
+@@ -577,6 +606,8 @@
+ @comment sys/timex.h
+ @comment GNU
+ @deftypefun int adjtimex (struct timex *@var{timex})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c It's a syscall, only available on linux.
+ 
+ @code{adjtimex} is functionally identical to @code{ntp_adjtime}.
+ @xref{High Accuracy Clock}.
+@@ -674,6 +705,10 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun {struct tm *} localtime (const time_t *@var{time})
++@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c Calls tz_convert with a static buffer.
++@c localtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+ The @code{localtime} function converts the simple time pointed to by
+ @var{time} to broken-down time representation, expressed relative to the
+ user's specified time zone.
+@@ -687,9 +722,8 @@
+ as a broken-down time; typically this is because the year cannot fit into
+ an @code{int}.
+ 
+-Calling @code{localtime} has one other effect: it sets the variable
+-@code{tzname} with information about the current time zone.  @xref{Time
+-Zone Functions}.
++Calling @code{localtime} also sets the current time zone as if
++@code{tzset} were called.  @xref{Time Zone Functions}.
+ @end deftypefun
+ 
+ Using the @code{localtime} function is a big problem in multi-threaded
+@@ -699,6 +733,87 @@
+ @comment time.h
+ @comment POSIX.1c
+ @deftypefun {struct tm *} localtime_r (const time_t *@var{time}, struct tm *@var{resultp})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c localtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  tz_convert(use_localtime) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   libc_lock_lock dup @asulock @aculock
++@c   tzset_internal @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c     always called with tzset_lock held
++@c     sets static is_initialized before initialization;
++@c     reads and sets old_tz; sets tz_rules.
++@c     some of the issues only apply on the first call.
++@c     subsequent calls only trigger these when called by localtime;
++@c     otherwise, they're ok.
++@c    getenv dup @mtsenv
++@c    strcmp dup ok
++@c    strdup @ascuheap
++@c    tzfile_read @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c     memcmp dup ok
++@c     strstr dup ok
++@c     getenv dup @mtsenv
++@c     asprintf dup @mtslocale @ascuheap @acsmem
++@c     stat64 dup ok
++@c     fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c     fileno dup ok
++@c     fstat64 dup ok
++@c     fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c     free dup @ascuheap @acsmem
++@c     fsetlocking dup ok [no @mtasurace:stream @asulock, exclusive]
++@c     fread_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt]
++@c     memcpy dup ok
++@c     decode ok
++@c      bswap_32 dup ok
++@c     fseek dup ok [no @mtasurace:stream @asucorrupt @acucorrupt]
++@c     ftello dup ok [no @mtasurace:stream @asucorrupt @acucorrupt]
++@c     malloc dup @ascuheap @acsmem
++@c     decode64 ok
++@c      bswap_64 dup ok
++@c     getc_unlocked ok [no @mtasurace:stream @asucorrupt @acucorrupt]
++@c     tzstring dup @ascuheap @acsmem
++@c     compute_tzname_max dup ok [guarded by tzset_lock]
++@c    memset dup ok
++@c    update_vars ok [guarded by tzset_lock]
++@c      sets daylight, timezone, tzname and tzname_cur_max;
++@c      called only with tzset_lock held, unless tzset_parse_tz
++@c      (internal, but not static) gets called by users; given the its
++@c      double-underscore-prefixed name, this interface violation could
++@c      be regarded as undefined behavior.
++@c     strlen ok
++@c    tzset_parse_tz @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c     sscanf dup @mtslocale @ascuheap @acsmem
++@c     isalnum dup @mtsenv
++@c     tzstring @ascuheap @acsmem
++@c       reads and changes tzstring_list without synchronization, but
++@c       only called with tzset_lock held (save for interface violations)
++@c      strlen dup ok
++@c      malloc dup @ascuheap @acsmem
++@c      strcpy dup ok
++@c     isdigit dup @mtslocale
++@c     compute_offset ok
++@c     tzfile_default @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c       sets tzname, timezone, types, zone_names, rule_*off, etc; no guards
++@c      strlen dup ok
++@c      tzfile_read dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c      mempcpy dup ok
++@c      compute_tzname_max ok [if guarded by tzset_lock]
++@c        iterates over zone_names; no guards
++@c     free dup @ascuheap @acsmem
++@c     strtoul dup @mtslocale
++@c     update_vars dup ok
++@c   tzfile_compute(use_localtime) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c     sets tzname; no guards.  with !use_localtime, as in gmtime, it's ok
++@c    tzstring dup @acsuheap @acsmem
++@c    tzset_parse_tz dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    offtime dup ok
++@c    tz_compute dup ok
++@c    strcmp dup ok
++@c   offtime ok
++@c    isleap dup ok
++@c   tz_compute ok
++@c    compute_change ok
++@c     isleap ok
++@c   libc_lock_unlock dup @aculock
++
+ The @code{localtime_r} function works just like the @code{localtime}
+ function.  It takes a pointer to a variable containing a simple time
+ and converts it to the broken-down time format.
+@@ -715,6 +830,9 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun {struct tm *} gmtime (const time_t *@var{time})
++@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c gmtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+ This function is similar to @code{localtime}, except that the broken-down
+ time is expressed as Coordinated Universal Time (UTC) (formerly called
+ Greenwich Mean Time (GMT)) rather than relative to a local time zone.
+@@ -728,6 +846,15 @@
+ @comment time.h
+ @comment POSIX.1c
+ @deftypefun {struct tm *} gmtime_r (const time_t *@var{time}, struct tm *@var{resultp})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c You'd think tz_convert could avoid some safety issues with
++@c !use_localtime, but no such luck: tzset_internal will always bring
++@c about all possible AS and AC problems when it's first called.
++@c Calling any of localtime,gmtime_r once would run the initialization
++@c and avoid the heap, mem and fd issues in gmtime* in subsequent calls,
++@c but the unsafe locking would remain.
++@c gmtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  tz_convert(gmtime_r) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+ This function is similar to @code{localtime_r}, except that it converts
+ just like @code{gmtime} the given time as Coordinated Universal Time.
+ 
+@@ -739,30 +866,58 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun time_t mktime (struct tm *@var{brokentime})
+-The @code{mktime} function is used to convert a broken-down time structure
+-to a simple time representation.  It also ``normalizes'' the contents of
+-the broken-down time structure, by filling in the day of week and day of
+-year based on the other date and time components.
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c mktime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   passes a static localtime_offset to mktime_internal; it is read
++@c   once, used as an initial guess, and updated at the end, but not
++@c   used except as a guess for subsequent calls, so it should be safe.
++@c   Even though a compiler might delay the load and perform it multiple
++@c   times (bug 16346), there are at least two unconditional uses of the
++@c   auto variable in which the first load is stored, separated by a
++@c   call to an external function, and a conditional change of the
++@c   variable before the external call, so refraining from allocating a
++@c   local variable at the first load would be a very bad optimization.
++@c  tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  mktime_internal(localtime_r) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   ydhms_diff ok
++@c   ranged_convert(localtime_r) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    *convert = localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    time_t_avg dup ok
++@c   guess_time_tm dup ok
++@c    ydhms_diff dup ok
++@c    time_t_add_ok ok
++@c     time_t_avg ok
++@c   isdst_differ ok
++@c   time_t_int_add_ok ok
++The @code{mktime} function converts a broken-down time structure to a
++simple time representation.  It also normalizes the contents of the
++broken-down time structure, and fills in some components based on the
++values of the others.
+ 
+ The @code{mktime} function ignores the specified contents of the
+-@code{tm_wday} and @code{tm_yday} members of the broken-down time
++@code{tm_wday}, @code{tm_yday}, @code{tm_gmtoff}, and @code{tm_zone}
++members of the broken-down time
+ structure.  It uses the values of the other components to determine the
+ calendar time; it's permissible for these components to have
+ unnormalized values outside their normal ranges.  The last thing that
+ @code{mktime} does is adjust the components of the @var{brokentime}
+-structure (including the @code{tm_wday} and @code{tm_yday}).
++structure, including the members that were initially ignored.
+ 
+ If the specified broken-down time cannot be represented as a simple time,
+ @code{mktime} returns a value of @code{(time_t)(-1)} and does not modify
+ the contents of @var{brokentime}.
+ 
+-Calling @code{mktime} also sets the variable @code{tzname} with
+-information about the current time zone.  @xref{Time Zone Functions}.
++Calling @code{mktime} also sets the current time zone as if
++@code{tzset} were called; @code{mktime} uses this information instead
++of @var{brokentime}'s initial @code{tm_gmtoff} and @code{tm_zone}
++members.  @xref{Time Zone Functions}.
+ @end deftypefun
+ 
+ @comment time.h
+ @comment ???
+ @deftypefun time_t timelocal (struct tm *@var{brokentime})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c Alias to mktime.
+ 
+ @code{timelocal} is functionally identical to @code{mktime}, but more
+ mnemonically named.  Note that it is the inverse of the @code{localtime}
+@@ -776,6 +931,19 @@
+ @comment time.h
+ @comment ???
+ @deftypefun time_t timegm (struct tm *@var{brokentime})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c timegm @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   gmtime_offset triggers the same caveats as localtime_offset in mktime.
++@c   although gmtime_r, as called by mktime, might save some issues,
++@c   tzset calls tzset_internal with always, which forces
++@c   reinitialization, so all issues may arise.
++@c  tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  mktime_internal(gmtime_r) @asulock @aculock
++@c ..gmtime_r @asulock @aculock
++@c    ... dup ok
++@c    tz_convert(!use_localtime) @asulock @aculock
++@c     ... dup @asulock @aculock
++@c     tzfile_compute(!use_localtime) ok
+ 
+ @code{timegm} is functionally identical to @code{mktime} except it
+ always takes the input values to be Coordinated Universal Time (UTC)
+@@ -837,6 +1005,8 @@
+ @comment sys/timex.h
+ @comment GNU
+ @deftypefun int ntp_gettime (struct ntptimeval *@var{tptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Wrapper for adjtimex.
+ The @code{ntp_gettime} function sets the structure pointed to by
+ @var{tptr} to current values.  The elements of the structure afterwards
+ contain the values the timer implementation in the kernel assumes.  They
+@@ -954,6 +1124,8 @@
+ @comment sys/timex.h
+ @comment GNU
+ @deftypefun int ntp_adjtime (struct timex *@var{tptr})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Alias to adjtimex syscall.
+ The @code{ntp_adjtime} function sets the structure specified by
+ @var{tptr} to current values.
+ 
+@@ -1008,6 +1180,13 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun {char *} asctime (const struct tm *@var{brokentime})
++@safety{@prelim{}@mtunsafe{@mtasurace{:asctime} @mtslocale{}}@asunsafe{}@acsafe{}}
++@c asctime @mtasurace:asctime @mtslocale
++@c   Uses a static buffer.
++@c  asctime_internal @mtslocale
++@c   snprintf dup @mtslocale [no @acsuheap @acsmem]
++@c   ab_day_name @mtslocale
++@c   ab_month_name @mtslocale
+ The @code{asctime} function converts the broken-down time value that
+ @var{brokentime} points to into a string in a standard format:
+ 
+@@ -1031,6 +1210,9 @@
+ @comment time.h
+ @comment POSIX.1c
+ @deftypefun {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
++@c asctime_r @mtslocale
++@c  asctime_internal dup @mtslocale
+ This function is similar to @code{asctime} but instead of placing the
+ result in a static buffer it writes the string in the buffer pointed to
+ by the parameter @var{buffer}.  This buffer should have room
+@@ -1045,6 +1227,10 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun {char *} ctime (const time_t *@var{time})
++@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c ctime @mtasurace:tmbuf @mtasurace:asctime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  localtime dup @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  asctime dup @mtasurace:asctime @mtslocale
+ The @code{ctime} function is similar to @code{asctime}, except that you
+ specify the calendar time argument as a @code{time_t} simple time value
+ rather than in broken-down local time format.  It is equivalent to
+@@ -1053,13 +1239,17 @@
+ asctime (localtime (@var{time}))
+ @end smallexample
+ 
+-@code{ctime} sets the variable @code{tzname}, because @code{localtime}
+-does so.  @xref{Time Zone Functions}.
++Calling @code{ctime} also sets the current time zone as if
++@code{tzset} were called.  @xref{Time Zone Functions}.
+ @end deftypefun
+ 
+ @comment time.h
+ @comment POSIX.1c
+ @deftypefun {char *} ctime_r (const time_t *@var{time}, char *@var{buffer})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c ctime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  asctime_r dup @mtslocale
+ This function is similar to @code{ctime}, but places the result in the
+ string pointed to by @var{buffer}.  It is equivalent to (written using
+ gcc extensions, @pxref{Statement Exprs,,,gcc,Porting and Using gcc}):
+@@ -1077,17 +1267,75 @@
+ @comment time.h
+ @comment ISO
+ @deftypefun size_t strftime (char *@var{s}, size_t @var{size}, const char *@var{template}, const struct tm *@var{brokentime})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c strftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  strftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   strftime_internal @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    add ok
++@c     memset_zero dup ok
++@c     memset_space dup ok
++@c    strlen dup ok
++@c    mbrlen @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd [no @mtasurace:mbstate/!ps]
++@c    mbsinit dup ok
++@c    cpy ok
++@c     add dup ok
++@c     memcpy_lowcase ok
++@c      TOLOWER ok
++@c       tolower_l ok
++@c     memcpy_uppcase ok
++@c      TOUPPER ok
++@c       toupper_l ok
++@c     MEMCPY ok
++@c      memcpy dup ok
++@c    ISDIGIT ok
++@c    STRLEN ok
++@c     strlen dup ok
++@c    strftime_internal dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    TOUPPER dup ok
++@c    nl_get_era_entry @ascuheap @asulock @acsmem @aculock
++@c     nl_init_era_entries @ascuheap @asulock @acsmem @aculock
++@c      libc_rwlock_wrlock dup @asulock @aculock
++@c      malloc dup @ascuheap @acsmem
++@c      memset dup ok
++@c      free dup @ascuheap @acsmem
++@c      realloc dup @ascuheap @acsmem
++@c      memcpy dup ok
++@c      strchr dup ok
++@c      wcschr dup ok
++@c      libc_rwlock_unlock dup @asulock @aculock
++@c     ERA_DATE_CMP ok
++@c    DO_NUMBER ok
++@c    DO_NUMBER_SPACEPAD ok
++@c    nl_get_alt_digit @ascuheap @asulock @acsmem @aculock
++@c     libc_rwlock_wrlock dup @asulock @aculock
++@c     nl_init_alt_digit @ascuheap @acsmem
++@c      malloc dup @ascuheap @acsmem
++@c      memset dup ok
++@c      strchr dup ok
++@c     libc_rwlock_unlock dup @aculock
++@c    memset_space ok
++@c     memset dup ok
++@c    memset_zero ok
++@c     memset dup ok
++@c    mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    iso_week_days ok
++@c    isleap ok
++@c    tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    gmtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    tm_diff ok
+ This function is similar to the @code{sprintf} function (@pxref{Formatted
+ Input}), but the conversion specifications that can appear in the format
+ template @var{template} are specialized for printing components of the date
+ and time @var{brokentime} according to the locale currently specified for
+-time conversion (@pxref{Locales}).
++time conversion (@pxref{Locales}) and the current time zone
++(@pxref{Time Zone Functions}).
+ 
+ Ordinary characters appearing in the @var{template} are copied to the
+ output string @var{s}; this can include multibyte character sequences.
+ Conversion specifiers are introduced by a @samp{%} character, followed
+ by an optional flag which can be one of the following.  These flags
+-are all GNU extensions. The first three affect only the output of
++are all GNU extensions.  The first three affect only the output of
+ numbers:
+ 
+ @table @code
+@@ -1392,9 +1640,10 @@
+ If @var{s} is a null pointer, @code{strftime} does not actually write
+ anything, but instead returns the number of characters it would have written.
+ 
+-According to POSIX.1 every call to @code{strftime} implies a call to
+-@code{tzset}.  So the contents of the environment variable @code{TZ}
+-is examined before any output is produced.
++Calling @code{strftime} also sets the current time zone as if
++@code{tzset} were called; @code{strftime} uses this information
++instead of @var{brokentime}'s @code{tm_gmtoff} and @code{tm_zone}
++members.  @xref{Time Zone Functions}.
+ 
+ For an example of @code{strftime}, see @ref{Time Functions Example}.
+ @end deftypefun
+@@ -1402,6 +1651,53 @@
+ @comment time.h
+ @comment ISO/Amend1
+ @deftypefun size_t wcsftime (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, const struct tm *@var{brokentime})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
++@c wcsftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c  wcsftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c   wcsftime_internal @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    add ok
++@c     memset_zero dup ok
++@c     memset_space dup ok
++@c    wcslen dup ok
++@c    cpy ok
++@c     add dup ok
++@c     memcpy_lowcase ok
++@c      TOLOWER ok
++@c       towlower_l dup ok
++@c     memcpy_uppcase ok
++@c      TOUPPER ok
++@c       towupper_l dup ok
++@c     MEMCPY ok
++@c      wmemcpy dup ok
++@c    widen @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c     memset dup ok
++@c     mbsrtowcs_l @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd [no @mtasurace:mbstate/!ps]
++@c    ISDIGIT ok
++@c    STRLEN ok
++@c     wcslen dup ok
++@c    wcsftime_internal dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
++@c    TOUPPER dup ok
++@c    nl_get_era_entry dup @ascuheap @asulock @acsmem @aculock
++@c    DO_NUMBER ok
++@c    DO_NUMBER_SPACEPAD ok
++@c    nl_get_walt_digit dup @ascuheap @asulock @acsmem @aculock
++@c     libc_rwlock_wrlock dup @asulock @aculock
++@c     nl_init_alt_digit dup @ascuheap @acsmem
++@c     malloc dup @ascuheap @acsmem
++@c     memset dup ok
++@c     wcschr dup ok
++@c     libc_rwlock_unlock dup @aculock
++@c    memset_space ok
++@c     wmemset dup ok
++@c    memset_zero ok
++@c     wmemset dup ok
++@c    mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    iso_week_days ok
++@c    isleap ok
++@c    tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    gmtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    tm_diff ok
+ The @code{wcsftime} function is equivalent to the @code{strftime}
+ function with the difference that it operates on wide character
+ strings.  The buffer where the result is stored, pointed to by @var{s},
+@@ -1452,6 +1748,32 @@
+ @comment time.h
+ @comment XPG4
+ @deftypefun {char *} strptime (const char *@var{s}, const char *@var{fmt}, struct tm *@var{tp})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c strptime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  strptime_internal @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   memset dup ok
++@c   ISSPACE ok
++@c    isspace_l dup ok
++@c   match_char ok
++@c   match_string ok
++@c    strlen dup ok
++@c    strncasecmp_l dup ok
++@c   strcmp dup ok
++@c   recursive @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c    strptime_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   get_number ok
++@c    ISSPACE dup ok
++@c   localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   nl_select_era_entry @ascuheap @asulock @acsmem @aculock
++@c    nl_init_era_entries dup @ascuheap @asulock @acsmem @aculock
++@c   get_alt_number dup @ascuheap @asulock @acsmem @aculock
++@c    nl_parse_alt_digit dup @ascuheap @asulock @acsmem @aculock
++@c     libc_rwlock_wrlock dup @asulock @aculock
++@c     nl_init_alt_digit dup @ascuheap @acsmem
++@c     libc_rwlock_unlock dup @aculock
++@c    get_number dup ok
++@c   day_of_the_week ok
++@c   day_of_the_year ok
+ The @code{strptime} function parses the input string @var{s} according
+ to the format string @var{fmt} and stores its results in the
+ structure @var{tp}.
+@@ -1865,6 +2187,9 @@
+ @comment time.h
+ @comment Unix98
+ @deftypefun {struct tm *} getdate (const char *@var{string})
++@safety{@prelim{}@mtunsafe{@mtasurace{:getdate} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c getdate @mtasurace:getdate @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  getdate_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+ The interface to @code{getdate} is the simplest possible for a function
+ to parse a string and return the value.  @var{string} is the input
+ string and the result is returned in a statically-allocated variable.
+@@ -1976,6 +2301,30 @@
+ @comment time.h
+ @comment GNU
+ @deftypefun int getdate_r (const char *@var{string}, struct tm *@var{tp})
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c getdate_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  getenv dup @mtsenv
++@c  stat64 dup ok
++@c  access dup ok
++@c  fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c  fsetlocking dup ok [no @mtasurace:stream @asulock, exclusive]
++@c  isspace dup @mtslocale
++@c  strlen dup ok
++@c  malloc dup @ascuheap @acsmem
++@c  fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c  memcpy dup ok
++@c  getline dup @ascuheap @acsmem [no @asucorrupt @aculock @acucorrupt, exclusive]
++@c  strptime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  feof_unlocked dup ok
++@c  free dup @ascuheap @acsmem
++@c  ferror_unlocked dup dup ok
++@c  time dup ok
++@c  localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  first_wday @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c   memset dup ok
++@c   mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  check_mday ok
++@c  mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+ The @code{getdate_r} function is the reentrant counterpart of
+ @code{getdate}.  It does not use the global variable @code{getdate_err}
+ to signal an error, but instead returns an error code.  The same error
+@@ -2037,7 +2386,7 @@
+ [@code{+}|@code{-}]@var{hh}[@code{:}@var{mm}[@code{:}@var{ss}]].  This
+ is positive if the local time zone is west of the Prime Meridian and
+ negative if it is east.  The hour must be between @code{0} and
+-@code{23}, and the minute and seconds between @code{0} and @code{59}.
++@code{24}, and the minute and seconds between @code{0} and @code{59}.
+ 
+ For example, here is how we would specify Eastern Standard Time, but
+ without any Daylight Saving Time alternative:
+@@ -2082,17 +2431,51 @@
+ 
+ The @var{time} fields specify when, in the local time currently in
+ effect, the change to the other time occurs.  If omitted, the default is
+-@code{02:00:00}.
+-
+-For example, here is how you would specify the Eastern time zone in the
+-United States, including the appropriate Daylight Saving Time and its dates
+-of applicability.  The normal offset from UTC is 5 hours; since this is
++@code{02:00:00}.  The hours part of the time fields can range from
++@minus{}167 through 167; this is an extension to POSIX.1, which allows
++only the range 0 through 24.
++
++Here are some example @code{TZ} values, including the appropriate
++Daylight Saving Time and its dates of applicability.  In North
++American Eastern Standard Time (EST) and Eastern Daylight Time (EDT),
++the normal offset from UTC is 5 hours; since this is
+ west of the prime meridian, the sign is positive.  Summer time begins on
+-the first Sunday in April at 2:00am, and ends on the last Sunday in October
++March's second Sunday at 2:00am, and ends on November's first Sunday
+ at 2:00am.
+ 
+ @smallexample
+-EST+5EDT,M4.1.0/2,M10.5.0/2
++EST+5EDT,M3.2.0/2,M11.1.0/2
++@end smallexample
++
++Israel Standard Time (IST) and Israel Daylight Time (IDT) are 2 hours
++ahead of the prime meridian in winter, springing forward an hour on
++March's fourth Thursday at 26:00 (i.e., 02:00 on the first Friday on or
++after March 23), and falling back on October's last Sunday at 02:00.
++
++@smallexample
++IST-2IDT,M3.4.4/26,M10.5.0
++@end smallexample
++
++Western Argentina Summer Time (WARST) is 3 hours behind the prime
++meridian all year.  There is a dummy fall-back transition on December
++31 at 25:00 daylight saving time (i.e., 24:00 standard time,
++equivalent to January 1 at 00:00 standard time), and a simultaneous
++spring-forward transition on January 1 at 00:00 standard time, so
++daylight saving time is in effect all year and the initial @code{WART}
++is a placeholder.
++
++@smallexample
++WART4WARST,J1/0,J365/25
++@end smallexample
++
++Western Greenland Time (WGT) and Western Greenland Summer Time (WGST)
++are 3 hours behind UTC in the winter.  Its clocks follow the European
++Union rules of springing forward by one hour on March's last Sunday at
++01:00 UTC (@minus{}02:00 local time) and falling back on October's
++last Sunday at 01:00 UTC (@minus{}01:00 local time).
++
++@smallexample
++WGT3WGST,M3.5.0/-2,M10.5.0/-1
+ @end smallexample
+ 
+ The schedule of Daylight Saving Time in any particular jurisdiction has
+@@ -2177,6 +2560,11 @@
+ @comment time.h
+ @comment POSIX.1
+ @deftypefun void tzset (void)
++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c tzset @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  tzset_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  libc_lock_unlock dup @aculock
+ The @code{tzset} function initializes the @code{tzname} variable from
+ the value of the @code{TZ} environment variable.  It is not usually
+ necessary for your program to call this function, because it is called
+@@ -2314,7 +2702,16 @@
+ 
+ @comment sys/time.h
+ @comment BSD
+-@deftypefun int setitimer (int @var{which}, struct itimerval *@var{new}, struct itimerval *@var{old})
++@deftypefun int setitimer (int @var{which}, const struct itimerval *@var{new}, struct itimerval *@var{old})
++@safety{@prelim{}@mtsafe{@mtstimer{}}@assafe{}@acsafe{}}
++@c This function is marked with @mtstimer because the same set of timers
++@c is shared by all threads of a process, so calling it in one thread
++@c may interfere with timers set by another thread.  This interference
++@c is not regarded as destructive, because the interface specification
++@c makes this overriding while returning the previous value the expected
++@c behavior, and the kernel will serialize concurrent calls so that the
++@c last one prevails, with each call getting the timer information from
++@c the timer installed by the previous call in that serialization.
+ The @code{setitimer} function sets the timer specified by @var{which}
+ according to @var{new}.  The @var{which} argument can have a value of
+ @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL}, or @code{ITIMER_PROF}.
+@@ -2335,6 +2732,7 @@
+ @comment sys/time.h
+ @comment BSD
+ @deftypefun int getitimer (int @var{which}, struct itimerval *@var{old})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{getitimer} function stores information about the timer specified
+ by @var{which} in the structure pointed at by @var{old}.
+ 
+@@ -2367,6 +2765,8 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun {unsigned int} alarm (unsigned int @var{seconds})
++@safety{@prelim{}@mtsafe{@mtstimer{}}@assafe{}@acsafe{}}
++@c Wrapper for setitimer.
+ The @code{alarm} function sets the real-time timer to expire in
+ @var{seconds} seconds.  If you want to cancel any existing alarm, you
+ can do this by calling @code{alarm} with a @var{seconds} argument of
+@@ -2426,6 +2826,10 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun {unsigned int} sleep (unsigned int @var{seconds})
++@safety{@prelim{}@mtunsafe{@mtascusig{:SIGCHLD/linux}}@asunsafe{}@acunsafe{}}
++@c On Mach, it uses ports and calls time.  On generic posix, it calls
++@c nanosleep.  On Linux, it temporarily blocks SIGCHLD, which is MT- and
++@c AS-Unsafe, and in a way that makes it AC-Unsafe (C-unsafe, even!).
+ The @code{sleep} function waits for @var{seconds} or until a signal
+ is delivered, whichever happens first.
+ 
+@@ -2470,6 +2874,9 @@
+ @comment time.h
+ @comment POSIX.1
+ @deftypefun int nanosleep (const struct timespec *@var{requested_time}, struct timespec *@var{remaining})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c On Linux, it's a syscall.  On Mach, it calls gettimeofday and uses
++@c ports.
+ If resolution to seconds is not enough the @code{nanosleep} function can
+ be used.  As the name suggests the sleep interval can be specified in
+ nanoseconds.  The actual elapsed time of the sleep interval might be
+diff -urN glibc-2.17-c758a686/manual/tsort.awk glibc/manual/tsort.awk
+--- glibc-2.17-c758a686/manual/tsort.awk	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/tsort.awk	2014-09-12 16:10:06.043792722 -0400
+@@ -1,6 +1,6 @@
+ #! /usr/bin/awk -f
+ # Generate topologically sorted list of manual chapters.
+-# (C) Copyright 1998, 1999 Free Software Foundation, Inc.
++# Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ # Written by Ulrich Drepper <drepper@cygnus.com>, 1998.
+ 
+ BEGIN {
+diff -urN glibc-2.17-c758a686/manual/users.texi glibc/manual/users.texi
+--- glibc-2.17-c758a686/manual/users.texi	2012-12-24 22:02:13.000000000 -0500
++++ glibc/manual/users.texi	2014-09-12 16:10:06.043792722 -0400
+@@ -71,7 +71,7 @@
+ @cindex group ID
+ Users are classified in @dfn{groups}.  Each user name belongs to one
+ @dfn{default group} and may also belong to any number of
+-@dfn{supplementary groups}. Users who are members of the same group can
++@dfn{supplementary groups}.  Users who are members of the same group can
+ share resources (such as files) that are not accessible to users who are
+ not a member of that group.  Each group has a @dfn{group name} and
+ @dfn{group ID}.  @xref{Group Database}, for how to find information
+@@ -221,30 +221,37 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun uid_t getuid (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++@c Atomic syscall, except on hurd, where it takes a lock within a hurd
++@c critical section.
+ The @code{getuid} function returns the real user ID of the process.
+ @end deftypefun
+ 
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun gid_t getgid (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{getgid} function returns the real group ID of the process.
+ @end deftypefun
+ 
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun uid_t geteuid (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{geteuid} function returns the effective user ID of the process.
+ @end deftypefun
+ 
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun gid_t getegid (void)
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{getegid} function returns the effective group ID of the process.
+ @end deftypefun
+ 
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int getgroups (int @var{count}, gid_t *@var{groups})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ The @code{getgroups} function is used to inquire about the supplementary
+ group IDs of the process.  Up to @var{count} of these group IDs are
+ stored in the array @var{groups}; the return value from the function is
+@@ -291,6 +298,34 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int seteuid (uid_t @var{neweuid})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c seteuid @asulock @aculock
++@c  INLINE_SETXID_SYSCALL @asulock @aculock
++@c    This may be just a unix syscall, or the ugliness below used by
++@c    nptl to propagate the syscall to all cloned processes used to
++@c    implement threads.
++@c   nptl_setxid @asulock @aculock
++@c     while holding the stack_alloc_lock, mark with SETXID_BITMASK all
++@c     threads that are not exiting, signal them until no thread remains
++@c     marked, clear the marks and run the syscall, then release the lock.
++@c    lll_lock @asulock @aculock
++@c    list_for_each ok
++@c    list_entry ok
++@c    setxid_mark_thread ok
++@c      if a thread is initializing, wait for it to be cloned.
++@c      mark it with SETXID_BITMASK if it's not exiting
++@c    setxid_signal_thread ok
++@c      if a thread is marked with SETXID_BITMASK,
++@c        send it the SIGSETXID signal
++@c    setxid_unmark_thread ok
++@c      clear SETXID_BITMASK and release the futex if SETXID_BITMASK is
++@c      set.
++@c    <syscall> ok
++@c    lll_unlock @aculock
++@c
++@c  sighandler_setxid ok
++@c    issue the syscall, clear SETXID_BITMASK, release the futex, and
++@c    wake up the signaller loop if the counter reached zero.
+ This function sets the effective user ID of a process to @var{neweuid},
+ provided that the process is allowed to change its effective user ID.  A
+ privileged process (effective user ID zero) can change its effective
+@@ -318,6 +353,9 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int setuid (uid_t @var{newuid})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c setuid @asulock @aculock
++@c  INLINE_SETXID_SYSCALL dup @asulock @aculock
+ If the calling process is privileged, this function sets both the real
+ and effective user ID of the process to @var{newuid}.  It also deletes
+ the file user ID of the process, if any.  @var{newuid} may be any
+@@ -334,6 +372,9 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int setreuid (uid_t @var{ruid}, uid_t @var{euid})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c setreuid @asulock @aculock
++@c  INLINE_SETXID_SYSCALL dup @asulock @aculock
+ This function sets the real user ID of the process to @var{ruid} and the
+ effective user ID to @var{euid}.  If @var{ruid} is @code{-1}, it means
+ not to change the real user ID; likewise if @var{euid} is @code{-1}, it
+@@ -369,6 +410,9 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int setegid (gid_t @var{newgid})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c setegid @asulock @aculock
++@c  INLINE_SETXID_SYSCALL dup @asulock @aculock
+ This function sets the effective group ID of the process to
+ @var{newgid}, provided that the process is allowed to change its group
+ ID.  Just as with @code{seteuid}, if the process is privileged it may
+@@ -388,6 +432,9 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun int setgid (gid_t @var{newgid})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c setgid @asulock @aculock
++@c  INLINE_SETXID_SYSCALL dup @asulock @aculock
+ This function sets both the real and effective group ID of the process
+ to @var{newgid}, provided that the process is privileged.  It also
+ deletes the file group ID, if any.
+@@ -402,6 +449,9 @@
+ @comment unistd.h
+ @comment BSD
+ @deftypefun int setregid (gid_t @var{rgid}, gid_t @var{egid})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c setregid @asulock @aculock
++@c  INLINE_SETXID_SYSCALL dup @asulock @aculock
+ This function sets the real group ID of the process to @var{rgid} and
+ the effective group ID to @var{egid}.  If @var{rgid} is @code{-1}, it
+ means not to change the real group ID; likewise if @var{egid} is
+@@ -437,7 +487,10 @@
+ 
+ @comment grp.h
+ @comment BSD
+-@deftypefun int setgroups (size_t @var{count}, gid_t *@var{groups})
++@deftypefun int setgroups (size_t @var{count}, const gid_t *@var{groups})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
++@c setgroups @asulock @aculock
++@c  INLINE_SETXID_SYSCALL dup @asulock @aculock
+ This function sets the process's supplementary group IDs.  It can only
+ be called from privileged processes.  The @var{count} argument specifies
+ the number of group IDs in the array @var{groups}.
+@@ -455,6 +508,36 @@
+ @comment grp.h
+ @comment BSD
+ @deftypefun int initgroups (const char *@var{user}, gid_t @var{group})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}}
++@c initgroups @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  sysconf(_SC_NGROUPS_MAX) dup @acsfd
++@c  MIN dup ok
++@c  malloc @ascuheap @acsmem
++@c  internal_getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nscd_getgrouplist @ascuheap @acsfd @acsmem
++@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
++@c    nscd_cache_search dup ok
++@c    nscd_open_socket dup @acsfd
++@c    realloc dup @ascuheap @acsmem
++@c    readall dup ok
++@c    memcpy dup ok
++@c    close_not_cancel_no_status dup @acsfd
++@c    nscd_drop_map_ref dup @ascuheap @acsmem
++@c    nscd_unmap dup @ascuheap @acsmem
++@c   nss_database_lookup dup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
++@c   nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   compat_call @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    sysconf(_SC_GETGR_R_SIZE_MAX) ok
++@c    nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    *getgrent_fct @ascuplugin
++@c    *setgrent_fct @ascuplugin
++@c    *endgrent_fct @ascuplugin
++@c    realloc dup @ascuheap @acsmem
++@c    free dup @ascuheap @acsmem
++@c   *initgroups_dyn_fct @ascuplugin
++@c   nss_next_action dup ok
++@c  setgroups dup @asulock @aculock
++@c  free dup @ascuheap @acsmem
+ The @code{initgroups} function sets the process's supplementary group
+ IDs to be the normal default for the user name @var{user}.  The group
+ @var{group} is automatically included.
+@@ -476,6 +559,13 @@
+ @comment grp.h
+ @comment BSD
+ @deftypefun int getgrouplist (const char *@var{user}, gid_t @var{group}, gid_t *@var{groups}, int *@var{ngroups})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}}
++@c getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  MAX dup ok
++@c  malloc dup @ascuheap @acsmem
++@c  internal_getgrouplist dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  memcpy dup ok
++@c  free dup @ascuheap @acsmem
+ The @code{getgrouplist} function scans the group database for all the
+ groups @var{user} belongs to.  Up to *@var{ngroups} group IDs
+ corresponding to these groups are stored in the array @var{groups}; the
+@@ -740,7 +830,7 @@
+ Be cautious about using the @code{exec} functions in combination with
+ changing the effective user ID.  Don't let users of your program execute
+ arbitrary programs under a changed user ID.  Executing a shell is
+-especially bad news. Less obviously, the @code{execlp} and @code{execvp}
++especially bad news.  Less obviously, the @code{execlp} and @code{execvp}
+ functions are a potential risk (since the program they execute depends
+ on the user's @code{PATH} environment variable).
+ 
+@@ -792,6 +882,41 @@
+ @comment unistd.h
+ @comment POSIX.1
+ @deftypefun {char *} getlogin (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:getlogin} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getlogin (linux) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  getlogin_r_loginuid dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  getlogin_fd0 (unix) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem
++@c    uses static buffer name => @mtasurace:getlogin
++@c   ttyname_r dup @ascuheap @acsmem @acsfd
++@c   strncpy dup ok
++@c   setutent dup @mtasurace:utent @asulock @aculock @acsfd
++@c   getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
++@c   endutent dup @mtasurace:utent @asulock @aculock
++@c   libc_lock_unlock dup ok
++@c   strlen dup ok
++@c   memcpy dup ok
++@c
++@c getlogin_r (linux) @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  getlogin_r_loginuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   open_not_cancel_2 dup @acsfd
++@c   read_not_cancel dup ok
++@c   close_not_cancel_no_status dup @acsfd
++@c   strtoul @mtslocale
++@c   getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   realloc dup @asulock @aculock @acsfd @acsmem
++@c   strlen dup ok
++@c   memcpy dup ok
++@c   free dup @asulock @aculock @acsfd @acsmem
++@c  getlogin_r_fd0 (unix) @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsmem @acsfd
++@c   ttyname_r dup @ascuheap @acsmem @acsfd
++@c   strncpy dup ok
++@c   libc_lock_lock dup @asulock @aculock
++@c   *libc_utmp_jump_table->setutent dup @mtasurace:utent @acsfd
++@c   *libc_utmp_jump_table->getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer
++@c   *libc_utmp_jump_table->endutent dup @mtasurace:utent @asulock @aculock
++@c   libc_lock_unlock dup ok
++@c   strlen dup ok
++@c   memcpy dup ok
+ The @code{getlogin} function returns a pointer to a string containing the
+ name of the user logged in on the controlling terminal of the process,
+ or a null pointer if this information cannot be determined.  The string
+@@ -802,6 +927,11 @@
+ @comment stdio.h
+ @comment POSIX.1
+ @deftypefun {char *} cuserid (char *@var{string})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c cuserid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  geteuid dup ok
++@c  getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  strncpy dup ok
+ The @code{cuserid} function returns a pointer to a string containing a
+ user name associated with the effective ID of the process.  If
+ @var{string} is not a null pointer, it should be an array that can hold
+@@ -1013,6 +1143,22 @@
+ @comment utmp.h
+ @comment SVID
+ @deftypefun void setutent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c Besides the static variables in utmp_file.c, there's the jump_table.
++@c They're both modified while holding a lock, but other threads may
++@c cause the variables to be modified between calling this function and
++@c others that rely on the internal state it sets up.
++
++@c setutent @mtasurace:utent @asulock @aculock @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  *libc_utmp_jump_table->setutent @mtasurace:utent @acsfd
++@c   setutent_unknown @mtasurace:utent @acsfd
++@c    *libc_utmp_file_functions.setutent = setutent_file @mtasurace:utent @acsfd
++@c      open_not_cancel_2 dup @acsfd
++@c      fcntl_not_cancel dup ok
++@c      close_not_cancel_no_status dup @acsfd
++@c      lseek64 dup ok
++@c  libc_lock_unlock dup ok
+ This function opens the user accounting database to begin scanning it.
+ You can then call @code{getutent}, @code{getutid} or @code{getutline} to
+ read entries and @code{pututline} to write entries.
+@@ -1024,6 +1170,14 @@
+ @comment utmp.h
+ @comment SVID
+ @deftypefun {struct utmp *} getutent (void)
++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasurace{:utentbuf} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c The static buffer that holds results is allocated with malloc at
++@c the first call; the test is not thread-safe, so multiple concurrent
++@c calls could malloc multiple buffers.
++
++@c getutent @mtuinit @mtasurace:utent @mtasurace:utentbuf @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem
++@c  malloc @asulock @aculock @acsfd @acsmem
++@c  getutent_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
+ The @code{getutent} function reads the next entry from the user
+ accounting database.  It returns a pointer to the entry, which is
+ statically allocated and may be overwritten by subsequent calls to
+@@ -1037,12 +1191,27 @@
+ @comment utmp.h
+ @comment SVID
+ @deftypefun void endutent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c endutent @mtasurace:utent @asulock @aculock @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  *libc_utmp_jump_table->endutent @mtasurace:utent @acsfd
++@c   endutent_unknown ok
++@c   endutent_file @mtasurace:utent @acsfd
++@c    close_not_cancel_no_status dup @acsfd
++@c  libc_lock_unlock dup ok
+ This function closes the user accounting database.
+ @end deftypefun
+ 
+ @comment utmp.h
+ @comment SVID
+ @deftypefun {struct utmp *} getutid (const struct utmp *@var{id})
++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
++@c Same caveats as getutline.
++@c
++@c getutid @mtuinit @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsmem @acsfd
++@c   uses a static buffer malloced on the first call
++@c  malloc dup @ascuheap @acsmem
++@c  getutid_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
+ This function searches forward from the current point in the database
+ for an entry that matches @var{id}.  If the @code{ut_type} member of the
+ @var{id} structure is one of @code{RUN_LVL}, @code{BOOT_TIME},
+@@ -1073,6 +1242,14 @@
+ @comment utmp.h
+ @comment SVID
+ @deftypefun {struct utmp *} getutline (const struct utmp *@var{line})
++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c The static buffer that holds results is allocated with malloc at
++@c the first call; the test is not thread-safe, so multiple concurrent
++@c calls could malloc multiple buffers.
++
++@c getutline @mtuinit @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem
++@c  malloc @asulock @aculock @acsfd @acsmem
++@c  getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
+ This function searches forward from the current point in the database
+ until it finds an entry whose @code{ut_type} value is
+ @code{LOGIN_PROCESS} or @code{USER_PROCESS}, and whose @code{ut_line}
+@@ -1095,6 +1272,29 @@
+ @comment utmp.h
+ @comment SVID
+ @deftypefun {struct utmp *} pututline (const struct utmp *@var{utmp})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  *libc_utmp_jump_table->pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd
++@c   pututline_unknown @mtasurace:utent @acsfd
++@c    setutent_unknown dup @mtasurace:utent @acsfd
++@c   pututline_file @mtascusig:ALRM @mtascutimer @acsfd
++@c    TRANSFORM_UTMP_FILE_NAME ok
++@c     strcmp dup ok
++@c     acesss dup ok
++@c    open_not_cancel_2 dup @acsfd
++@c    fcntl_not_cancel dup ok
++@c    close_not_cancel_no_status dup @acsfd
++@c    llseek dup ok
++@c    dup2 dup ok
++@c    utmp_equal dup ok
++@c    internal_getut_r dup @mtascusig:ALRM @mtascutimer
++@c    LOCK_FILE dup @mtascusig:ALRM @mtasctimer
++@c    LOCKING_FAILED dup ok
++@c    ftruncate64 dup ok
++@c    write_not_cancel dup ok
++@c    UNLOCK_FILE dup @mtasctimer
++@c  libc_lock_unlock dup @aculock
+ The @code{pututline} function inserts the entry @code{*@var{utmp}} at
+ the appropriate place in the user accounting database.  If it finds that
+ it is not already at the correct place in the database, it uses
+@@ -1125,6 +1325,27 @@
+ @comment utmp.h
+ @comment GNU
+ @deftypefun int getutent_r (struct utmp *@var{buffer}, struct utmp **@var{result})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  *libc_utmp_jump_table->getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd
++@c   getutent_r_unknown @mtasurace:utent @acsfd
++@c    setutent_unknown dup @mtasurace:utent @acsfd
++@c   getutent_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer
++@c    LOCK_FILE @mtascusig:ALRM @mtascutimer
++@c     alarm dup @mtascutimer
++@c     sigemptyset dup ok
++@c     sigaction dup ok
++@c     memset dup ok
++@c     fcntl_not_cancel dup ok
++@c    LOCKING_FAILED ok
++@c    read_not_cancel dup ok
++@c    UNLOCK_FILE @mtascutimer
++@c     fcntl_not_cancel dup ok
++@c     alarm dup @mtascutimer
++@c     sigaction dup ok
++@c    memcpy dup ok
++@c  libc_lock_unlock dup ok
+ The @code{getutent_r} is equivalent to the @code{getutent} function.  It
+ returns the next entry from the database.  But instead of storing the
+ information in a static buffer it stores it in the buffer pointed to by
+@@ -1142,6 +1363,22 @@
+ @comment utmp.h
+ @comment GNU
+ @deftypefun int getutid_r (const struct utmp *@var{id}, struct utmp *@var{buffer}, struct utmp **@var{result})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  *libc_utmp_jump_table->getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd
++@c   getutid_r_unknown @mtasurace:utent @acsfd
++@c    setutent_unknown dup @mtasurace:utent @acsfd
++@c   getutid_r_file @mtascusig:ALRM @mtascutimer
++@c    internal_getut_r @mtascusig:ALRM @mtascutimer
++@c     LOCK_FILE dup @mtascusig:ALRM @mtascutimer
++@c     LOCKING_FAILED dup ok
++@c     read_not_cancel dup ok
++@c     utmp_equal ok
++@c      strncmp dup ok
++@c     UNLOCK_FILE dup @mtascutimer
++@c    memcpy dup ok
++@c  libc_lock_unlock dup @aculock
+ This function retrieves just like @code{getutid} the next entry matching
+ the information stored in @var{id}.  But the result is stored in the
+ buffer pointed to by the parameter @var{buffer}.
+@@ -1157,6 +1394,28 @@
+ @comment utmp.h
+ @comment GNU
+ @deftypefun int getutline_r (const struct utmp *@var{line}, struct utmp *@var{buffer}, struct utmp **@var{result})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
++@c getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  *libc_utmp_jump_table->getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd
++@c   getutline_r_unknown @mtasurace:utent @acsfd
++@c    setutent_unknown dup @mtasurace:utent @acsfd
++@c   getutline_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer
++@c    LOCK_FILE @mtascusig:ALRM @mtascutimer
++@c     alarm dup @mtascutimer
++@c     sigemptyset dup ok
++@c     sigaction dup ok
++@c     memset dup ok
++@c     fcntl_not_cancel dup ok
++@c    LOCKING_FAILED ok
++@c    read_not_cancel dup ok
++@c    strncmp dup ok
++@c    UNLOCK_FILE @mtascutimer
++@c     fcntl_not_cancel dup ok
++@c     alarm dup @mtascutimer
++@c     sigaction dup ok
++@c    memcpy dup ok
++@c  libc_lock_unlock dup ok
+ This function retrieves just like @code{getutline} the next entry
+ matching the information stored in @var{line}.  But the result is stored
+ in the buffer pointed to by the parameter @var{buffer}.
+@@ -1180,6 +1439,14 @@
+ @comment utmp.h
+ @comment SVID
+ @deftypefun int utmpname (const char *@var{file})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
++@c utmpname @mtasurace:utent @asulock @ascuheap @aculock @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  *libc_utmp_jump_table->endutent dup @mtasurace:utent
++@c  strcmp dup ok
++@c  free dup @ascuheap @acsmem
++@c  strdup dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
+ The @code{utmpname} function changes the name of the database to be
+ examined to @var{file}, and closes any previously opened database.  By
+ default @code{getutent}, @code{getutid}, @code{getutline} and
+@@ -1208,6 +1475,18 @@
+ @comment utmp.h
+ @comment SVID
+ @deftypefun void updwtmp (const char *@var{wtmp_file}, const struct utmp *@var{utmp})
++@safety{@prelim{}@mtunsafe{@mtascusig{:ALRM} @mtascutimer{}}@asunsafe{}@acunsafe{@acsfd{}}}
++@c updwtmp @mtascusig:ALRM @mtascutimer @acsfd
++@c  TRANSFORM_UTMP_FILE_NAME dup ok
++@c  *libc_utmp_file_functions->updwtmp = updwtmp_file @mtascusig:ALRM @mtascutimer @acsfd
++@c   open_not_cancel_2 dup @acsfd
++@c   LOCK_FILE dup @mtascusig:ALRM @mtascutimer
++@c   LOCKING_FAILED dup ok
++@c   lseek64 dup ok
++@c   ftruncate64 dup ok
++@c   write_not_cancel dup ok
++@c   UNLOCK_FILE dup @mtascutimer
++@c   close_not_cancel_no_status dup @acsfd
+ The @code{updwtmp} function appends the entry *@var{utmp} to the
+ database specified by @var{wtmp_file}.  For possible values for the
+ @var{wtmp_file} argument see the @code{utmpname} function.
+@@ -1330,6 +1609,7 @@
+ @comment utmpx.h
+ @comment XPG4.2
+ @deftypefun void setutxent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
+ This function is similar to @code{setutent}.  In @theglibc{} it is
+ simply an alias for @code{setutent}.
+ @end deftypefun
+@@ -1337,6 +1617,7 @@
+ @comment utmpx.h
+ @comment XPG4.2
+ @deftypefun {struct utmpx *} getutxent (void)
++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+ The @code{getutxent} function is similar to @code{getutent}, but returns
+ a pointer to a @code{struct utmpx} instead of @code{struct utmp}.  In
+ @theglibc{} it simply is an alias for @code{getutent}.
+@@ -1345,6 +1626,7 @@
+ @comment utmpx.h
+ @comment XPG4.2
+ @deftypefun void endutxent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+ This function is similar to @code{endutent}.  In @theglibc{} it is
+ simply an alias for @code{endutent}.
+ @end deftypefun
+@@ -1352,6 +1634,7 @@
+ @comment utmpx.h
+ @comment XPG4.2
+ @deftypefun {struct utmpx *} getutxid (const struct utmpx *@var{id})
++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+ This function is similar to @code{getutid}, but uses @code{struct utmpx}
+ instead of @code{struct utmp}.  In @theglibc{} it is simply an alias
+ for @code{getutid}.
+@@ -1360,6 +1643,7 @@
+ @comment utmpx.h
+ @comment XPG4.2
+ @deftypefun {struct utmpx *} getutxline (const struct utmpx *@var{line})
++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+ This function is similar to @code{getutid}, but uses @code{struct utmpx}
+ instead of @code{struct utmp}.  In @theglibc{} it is simply an alias
+ for @code{getutline}.
+@@ -1368,6 +1652,7 @@
+ @comment utmpx.h
+ @comment XPG4.2
+ @deftypefun {struct utmpx *} pututxline (const struct utmpx *@var{utmp})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
+ The @code{pututxline} function is functionally identical to
+ @code{pututline}, but uses @code{struct utmpx} instead of @code{struct
+ utmp}.  In @theglibc{}, @code{pututxline} is simply an alias for
+@@ -1377,6 +1662,7 @@
+ @comment utmpx.h
+ @comment XPG4.2
+ @deftypefun int utmpxname (const char *@var{file})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+ The @code{utmpxname} function is functionally identical to
+ @code{utmpname}.  In @theglibc{}, @code{utmpxname} is simply an
+ alias for @code{utmpname}.
+@@ -1391,6 +1677,7 @@
+ @comment utmp.h
+ @comment GNU
+ @deftypefun int getutmp (const struct utmpx *@var{utmpx}, struct utmp *@var{utmp})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{getutmp} copies the information, insofar as the structures are
+ compatible, from @var{utmpx} to @var{utmp}.
+ @end deftypefun
+@@ -1399,6 +1686,7 @@
+ @comment utmp.h
+ @comment GNU
+ @deftypefun int getutmpx (const struct utmp *@var{utmp}, struct utmpx *@var{utmpx})
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @code{getutmpx} copies the information, insofar as the structures are
+ compatible, from @var{utmp} to @var{utmpx}.
+ @end deftypefun
+@@ -1418,6 +1706,17 @@
+ @comment utmp.h
+ @comment BSD
+ @deftypefun int login_tty (int @var{filedes})
++@safety{@prelim{}@mtunsafe{@mtasurace{:ttyname}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c If this function is canceled, it may have succeeded in redirecting
++@c only some of the standard streams to the newly opened terminal.
++@c Should there be a safety annotation for this?
++@c login_tty @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
++@c  setsid dup ok
++@c  ioctl dup ok
++@c  ttyname dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
++@c  close dup @acsfd
++@c  open dup @acsfd
++@c  dup2 dup ok
+ This function makes @var{filedes} the controlling terminal of the
+ current process, redirects standard input, standard output and
+ standard error output to this terminal, and closes @var{filedes}.
+@@ -1429,6 +1728,24 @@
+ @comment utmp.h
+ @comment BSD
+ @deftypefun void login (const struct utmp *@var{entry})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsfd{} @acsmem{}}}
++@c login @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @ascuheap @aculock @acucorrupt @acsfd @acsmem
++@c  getpid dup ok
++@c  tty_name @ascuheap @acucorrupt @acsmem @acsfd
++@c   ttyname_r dup @ascuheap @acsmem @acsfd
++@c   memchr dup ok
++@c   realloc dup @ascuheap @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  strncmp dup ok
++@c  basename dup ok
++@c  strncpy dup ok
++@c  utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem
++@c  setutent dup @mtasurace:utent @asulock @aculock @acsfd
++@c  pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
++@c  endutent dup @mtasurace:utent @asulock @aculock
++@c  free dup @ascuheap @acsmem
++@c  updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd
+ The @code{login} functions inserts an entry into the user accounting
+ database.  The @code{ut_line} member is set to the name of the terminal
+ on standard input.  If standard input is not a terminal @code{login}
+@@ -1444,6 +1761,17 @@
+ @comment utmp.h
+ @comment BSD
+ @deftypefun int logout (const char *@var{ut_line})
++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
++@c logout @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @ascuheap @aculock @acsfd @acsmem
++@c  utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem
++@c  setutent dup @mtasurace:utent @asulock @aculock @acsfd
++@c  strncpy dup ok
++@c  getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
++@c  bzero dup ok
++@c  gettimeofday dup ok
++@c  time dup ok
++@c  pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
++@c  endutent dup @mtasurace:utent @asulock @aculock
+ This function modifies the user accounting database to indicate that the
+ user on @var{ut_line} has logged out.
+ 
+@@ -1454,6 +1782,14 @@
+ @comment utmp.h
+ @comment BSD
+ @deftypefun void logwtmp (const char *@var{ut_line}, const char *@var{ut_name}, const char *@var{ut_host})
++@safety{@prelim{}@mtunsafe{@mtascusig{:ALRM} @mtascutimer{}}@asunsafe{}@acunsafe{@acsfd{}}}
++@c logwtmp @mtascusig:ALRM @mtascutimer @acsfd
++@c  memset dup ok
++@c  getpid dup ok
++@c  strncpy dup ok
++@c  gettimeofday dup ok
++@c  time dup ok
++@c  updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd
+ The @code{logwtmp} function appends an entry to the user accounting log
+ file, for the current time and the information provided in the
+ @var{ut_line}, @var{ut_name} and @var{ut_host} arguments.
+@@ -1535,6 +1871,14 @@
+ @comment pwd.h
+ @comment POSIX.1
+ @deftypefun {struct passwd *} getpwuid (uid_t @var{uid})
++@safety{@prelim{}@mtunsafe{@mtasurace{:pwuid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getpwuid @mtasurace:pwuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
+ This function returns a pointer to a statically-allocated structure
+ containing information about the user whose user ID is @var{uid}.  This
+ structure may be overwritten on subsequent calls to @code{getpwuid}.
+@@ -1546,6 +1890,208 @@
+ @comment pwd.h
+ @comment POSIX.1c
+ @deftypefun int getpwuid_r (uid_t @var{uid}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  nscd_getpwuid_r @ascuheap @acsfd @acsmem
++@c   itoa_word dup ok
++@c   nscd_getpw_r @ascuheap @acsfd @acsmem
++@c    nscd_get_map_ref @ascuheap @acsfd @acsmem
++@c     nscd_acquire_maplock ok
++@c     nscd_get_mapping @ascuheap @acsfd @acsmem
++@c      open_socket dup @acsfd
++@c      memset dup ok
++@c      wait_on_socket dup ok
++@c      recvmsg dup ok
++@c      strcmp dup ok
++@c      fstat64 dup ok
++@c      mmap dup @acsmem
++@c      munmap dup @acsmem
++@c      malloc dup @ascuheap @acsmem
++@c      close dup ok
++@c      nscd_unmap dup @ascuheap @acsmem
++@c    nscd_cache_search ok
++@c     nis_hash ok
++@c     memcmp dup ok
++@c    nscd_open_socket @acsfd
++@c     open_socket @acsfd
++@c      socket dup @acsfd
++@c      fcntl dup ok
++@c      strcpy dup ok
++@c      connect dup ok
++@c      send dup ok
++@c      gettimeofday dup ok
++@c      poll dup ok
++@c      close_not_cancel_no_status dup @acsfd
++@c     wait_on_socket dup ok
++@c     read dup ok
++@c     close_not_cancel_no_status dup @acsfd
++@c    readall ok
++@c     read dup ok
++@c     wait_on_socket ok
++@c      poll dup ok
++@c      gettimeofday dup ok
++@c    memcpy dup ok
++@c    close_not_cancel_no_status dup @acsfd
++@c    nscd_drop_map_ref @ascuheap @acsmem
++@c     nscd_unmap dup @ascuheap @acsmem
++@c    nscd_unmap @ascuheap @acsmem
++@c     munmap dup ok
++@c     free dup @ascuheap @acsmem
++@c  nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_database_lookup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
++@c    libc_lock_lock @asulock @aculock
++@c    libc_lock_unlock @aculock
++@c    nss_parse_file @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
++@c     fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c     fsetlocking dup ok [no concurrent uses]
++@c     malloc dup @asulock @aculock @acsfd @acsmem
++@c     fclose dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c     getline dup @ascuheap @aculock @acucorrupt @acsmem
++@c     strchrnul dup ok
++@c     nss_getline @mtslocale @ascuheap @acsmem
++@c      isspace @mtslocale^^
++@c      strlen dup ok
++@c      malloc dup @asulock @aculock @acsfd @acsmem
++@c      memcpy dup ok
++@c      nss_parse_service_list dup @mtslocale^, @ascuheap @acsmem
++@c     feof_unlocked dup ok
++@c     free dup @asulock @aculock @acsfd @acsmem
++@c    strcmp dup ok
++@c    nss_parse_service_list @mtslocale^, @ascuheap @acsmem
++@c     isspace @mtslocale^^
++@c     malloc dup @asulock @aculock @acsfd @acsmem
++@c     mempcpy dup ok
++@c     strncasecmp dup ok
++@c     free dup @asulock @aculock @acsfd @acsmem
++@c    malloc dup @asulock @aculock @acsfd @acsmem
++@c   nss_lookup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    nss_lookup_function @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c     libc_lock_lock @asulock @aculock
++@c     tsearch @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking]
++@c      known_compare ok
++@c       strcmp dup ok
++@c     malloc dup @ascuheap @acsmem
++@c     tdelete @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking]
++@c     free dup @ascuheap @acsmem
++@c     nss_load_library @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem
++@c      nss_new_service @ascuheap @acsmem
++@c       strcmp dup ok
++@c       malloc dup @ascuheap @acsmem
++@c      strlen dup ok
++@c      stpcpy dup ok
++@c      libc_dlopen @ascudlopen @ascuheap @asulock @aculock @acsfd @acsmem
++@c      libc_dlsym dup @asulock @aculock @acsfd @acsmem
++@c      *ifct(*nscd_init_cb) @ascuplugin
++@c     stpcpy dup ok
++@c     libc_dlsym dup @asulock @aculock @acsfd @acsmem
++@c     libc_lock_unlock dup ok
++@c    nss_next_action ok
++@c  *fct.l -> _nss_*_getpwuid_r @ascuplugin
++@c  nss_next2 @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_next_action dup ok
++@c   nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++
++@c _nss_files_getpwuid_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  internal_setent @ascuheap @asulock @aculock @acsmem @acsfd
++@c   fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c   fileno dup ok
++@c   fcntl dup ok
++@c   fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c   rewind dup @aculock [stream guarded by non-recursive pwent lock]
++@c  internal_getent @mtslocale^
++@c   fgets_unlocked dup ok [stream guarded by non-recursive pwent lock]
++@c   isspace dup @mtslocale^^
++@c   _nss_files_parse_pwent = parse_line ok
++@c    strpbrk dup ok
++@c  internal_endent @ascuheap @asulock @aculock @acsmem @acsfd
++@c   fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c  libc_lock_unlock dup @aculock
++
++@c _nss_nis_getpwuid_r ... not fully reviewed (assumed) @asuinit @asulock @acucorrupt @aculock
++@c  yp_get_default_domain @asulock @aculock
++@c   libc_lock_lock dup @asulock @aculock
++@c   getdomainname dup ok
++@c   strcmp dup ok
++@c   libc_lock_unlock dup @aculock
++@c  snprintf dup @ascuheap @acsmem
++@c  yp_match
++@c   do_ypcall_tr(xdr_ypreq_key,xdr_ypresp_val)
++@c    do_ypcall(xdr_ypreq_key,xdr_ypresp_val)
++@c     libc_lock_lock @asulock @aculock
++@c     strcmp
++@c     yp_bind
++@c     ypclnt_call
++@c      clnt_call
++@c      clnt_perror
++@c     libc_lock_unlock @aculock
++@c     yp_unbind_locked
++@c     yp_unbind
++@c      strcmp dup ok
++@c      calloc dup @asulock @aculock @acsfd @acsmem
++@c      yp_bind_file
++@c       strlen dup ok
++@c       snprintf dup @ascuheap @acsmem
++@c       open dup @acsfd [cancelpt]
++@c       pread dup [cancelpt]
++@c       yp_bind_client_create
++@c       close dup @acsfd [cancelpt]
++@c      yp_bind_ypbindprog
++@c       clnttcp_create
++@c       clnt_destroy
++@c       clnt_call(xdr_domainname,xdr_ypbind_resp)
++@c       memset dup ok
++@c       yp_bind_client_create
++@c      free dup @asulock @aculock @acsfd @acsmem
++@c     calloc dup @asulock @aculock @acsfd @acsmem
++@c     free dup @asulock @aculock @acsfd @acsmem
++@c    ypprot_err
++@c   memcpy dup ok
++@c   xdr_free(xdr_ypresp_val)
++@c    xdr_ypresp_val
++@c     xdr_ypstat
++@c      xdr_enum
++@c       XDR_PUTLONG
++@c        *x_putlong
++@c       XDR_GETLONG
++@c        *x_getlong
++@c       xdr_long
++@c        XDR_PUTLONG dup
++@c        XDR_GETLONG dup
++@c       xdr_short
++@c        XDR_PUTLONG dup
++@c        XDR_GETLONG dup
++@c     xdr_valdat
++@c      xdr_bytes
++@c       xdr_u_int
++@c        XDR_PUTLONG dup
++@c        XDR_GETLONG dup
++@c       mem_alloc @ascuheap @acsmem
++@c        malloc dup @ascuheap @acsmem
++@c       xdr_opaque
++@c        XDR_GETBYTES
++@c         *x_getbytes
++@c        XDR_PUTBYTES
++@c         *x_putbytes
++@c       mem_free @ascuheap @acsmem
++@c        free dup @ascuheap @acsmem
++@c  yperr2nss ok
++@c  strchr dup ok
++@c  _nls_default_nss @asuinit @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
++@c   init @asuinit^, @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
++@c    fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
++@c    fsetlocking ok [no concurrent uses]
++@c    feof_unlocked dup ok
++@c    getline dup @ascuheap @aculock @acucorrupt @acsmem
++@c    isspace dup @mtslocale^^
++@c    strncmp dup ok
++@c    free dup @asulock @acsmem @acsfd @aculock
++@c    fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c  free dup @asulock @acsmem @acsfd @aculock
++@c  mempcpy dup ok
++@c  strncpy dup ok
++@c  isspace dup @mtslocale^^
++@c  _nss_files_parse_pwent ok
+ This function is similar to @code{getpwuid} in that it returns
+ information about the user whose user ID is @var{uid}.  However, it
+ fills the user supplied structure pointed to by @var{result_buf} with
+@@ -1568,6 +2114,14 @@
+ @comment pwd.h
+ @comment POSIX.1
+ @deftypefun {struct passwd *} getpwnam (const char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasurace{:pwnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getpwnam @mtasurace:pwnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
+ This function returns a pointer to a statically-allocated structure
+ containing information about the user whose user name is @var{name}.
+ This structure may be overwritten on subsequent calls to
+@@ -1579,6 +2133,25 @@
+ @comment pwd.h
+ @comment POSIX.1c
+ @deftypefun int getpwnam_r (const char *@var{name}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getpwnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  nscd_getpwnam_r @ascuheap @asulock @aculock @acsfd @acsmem
++@c   strlen dup ok
++@c   nscd_getpw_r dup @ascuheap @asulock @aculock @acsfd @acsmem
++@c  nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c
++@c _nss_files_getpwnam_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
++@c  libc_lock_lock dup @asulock @aculock
++@c  internal_setent dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c  internal_getent dup @mtslocale^
++@c  strcmp dup ok
++@c  internal_endent dup @ascuheap @asulock @aculock @acsmem @acsfd
++@c  libc_lock_unlock dup @aculock
++@c
++@c _nss_*_getpwnam_r (assumed) @asuinit @asulock @acucorrupt @aculock
++
+ This function is similar to @code{getpwnam} in that is returns
+ information about the user whose user name is @var{name}.  However, like
+ @code{getpwuid_r}, it fills the user supplied buffers in
+@@ -1603,6 +2176,16 @@
+ @comment pwd.h
+ @comment SVID
+ @deftypefun {struct passwd *} fgetpwent (FILE *@var{stream})
++@safety{@prelim{}@mtunsafe{@mtasurace{:fpwent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}}
++@c fgetpwent @mtasurace:fpwent @asucorrupt @asulock @acucorrupt @aculock
++@c  fgetpos dup @asucorrupt @aculock @acucorrupt
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  fgetpwent_r dup @asucorrupt @acucorrupt @aculock
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  fsetpos dup @asucorrupt @aculock @acucorrupt
++@c  libc_lock_unlock dup @aculock
+ This function reads the next user entry from @var{stream} and returns a
+ pointer to the entry.  The structure is statically allocated and is
+ rewritten on subsequent calls to @code{fgetpwent}.  You must copy the
+@@ -1615,6 +2198,14 @@
+ @comment pwd.h
+ @comment GNU
+ @deftypefun int fgetpwent_r (FILE *@var{stream}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
++@c fgetpwent_r @asucorrupt @acucorrupt @aculock
++@c  flockfile dup @aculock
++@c  fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking]
++@c  feof_unlocked dup ok
++@c  funlockfile dup @aculock
++@c  isspace dup @mtslocale^^
++@c  parse_line dup ok
+ This function is similar to @code{fgetpwent} in that it reads the next
+ user entry from @var{stream}.  But the result is returned in the
+ structure pointed to by @var{result_buf}.  The
+@@ -1637,6 +2228,17 @@
+ @comment pwd.h
+ @comment SVID, BSD
+ @deftypefun void setpwent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c setpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock @asulock @aculock
++@c  nss_setent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    ** resolv's res_maybe_init not called here
++@c   setup(nss_passwd_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    *lookup_fct = nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:pwent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock @aculock
+ This function initializes a stream which @code{getpwent} and
+ @code{getpwent_r} use to read the user database.
+ @end deftypefun
+@@ -1644,6 +2246,15 @@
+ @comment pwd.h
+ @comment POSIX.1
+ @deftypefun {struct passwd *} getpwent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtasurace{:pwentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getpwent @mtasurace:pwent @mtasurace:pwentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent(getpwent_r) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c   *func = getpwent_r dup @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   realloc dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
+ The @code{getpwent} function reads the next entry from the stream
+ initialized by @code{setpwent}.  It returns a pointer to the entry.  The
+ structure is statically allocated and is rewritten on subsequent calls
+@@ -1655,7 +2266,21 @@
+ 
+ @comment pwd.h
+ @comment GNU
+-@deftypefun int getpwent_r (struct passwd *@var{result_buf}, char *@var{buffer}, int @var{buflen}, struct passwd **@var{result})
++@deftypefun int getpwent_r (struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
++@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c The static buffer here is not the result_buf, but rather the
++@c variables that keep track of what nss backend we've last used, and
++@c whatever internal state the nss backend uses to keep track of the
++@c last read entry.
++@c getpwent_r @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nss_getent_r(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:pwent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *sfct.f @mtasurace:pwent @ascuplugin
++@c  libc_lock_unlock dup @aculock
+ This function is similar to @code{getpwent} in that it returns the next
+ entry from the stream initialized by @code{setpwent}.  Like
+ @code{fgetpwent_r}, it uses the user-supplied buffers in
+@@ -1668,6 +2293,15 @@
+ @comment pwd.h
+ @comment SVID, BSD
+ @deftypefun void endpwent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c endpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock @asulock @aculock
++@c  nss_endent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    ** resolv's res_maybe_init not called here
++@c   setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct.f @mtasurace:pwent @ascuplugin
++@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_unlock @aculock
+ This function closes the internal stream used by @code{getpwent} or
+ @code{getpwent_r}.
+ @end deftypefun
+@@ -1678,6 +2312,9 @@
+ @comment pwd.h
+ @comment SVID
+ @deftypefun int putpwent (const struct passwd *@var{p}, FILE *@var{stream})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
++@c putpwent @mtslocale @asucorrupt @aculock @acucorrupt
++@c  fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem]
+ This function writes the user entry @code{*@var{p}} to the stream
+ @var{stream}, in the format used for the standard user database
+ file.  The return value is zero on success and nonzero on failure.
+@@ -1751,6 +2388,9 @@
+ @comment grp.h
+ @comment POSIX.1
+ @deftypefun {struct group *} getgrgid (gid_t @var{gid})
++@safety{@prelim{}@mtunsafe{@mtasurace{:grgid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getgrgid =~ getpwuid dup @mtasurace:grgid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  getgrgid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ This function returns a pointer to a statically-allocated structure
+ containing information about the group whose group ID is @var{gid}.
+ This structure may be overwritten by subsequent calls to
+@@ -1762,6 +2402,26 @@
+ @comment grp.h
+ @comment POSIX.1c
+ @deftypefun int getgrgid_r (gid_t @var{gid}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getgrgid_r =~ getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  nscd_getgrgid_r @ascuheap @acsfd @acsmem
++@c   itoa_word dup ok
++@c   nscd_getgr_r @ascuheap @acsfd @acsmem
++@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
++@c    nscd_cache_search dup ok
++@c    nscd_open_socket dup @acsfd
++@c    readvall ok
++@c     readv dup ok
++@c     memcpy dup ok
++@c      wait_on_socket dup ok
++@c    memcpy dup ok
++@c    readall dup ok
++@c    close_not_cancel_no_status dup @acsfd
++@c    nscd_drop_map_ref dup @ascuheap @acsmem
++@c    nscd_unmap dup @ascuheap @acsmem
++@c  nss_group_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l -> _nss_*_getgrgid_r @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ This function is similar to @code{getgrgid} in that it returns
+ information about the group whose group ID is @var{gid}.  However, it
+ fills the user supplied structure pointed to by @var{result_buf} with
+@@ -1783,6 +2443,9 @@
+ @comment grp.h
+ @comment SVID, BSD
+ @deftypefun {struct group *} getgrnam (const char *@var{name})
++@safety{@prelim{}@mtunsafe{@mtasurace{:grnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getgrnam =~ getpwnam dup @mtasurace:grnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  getgrnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ This function returns a pointer to a statically-allocated structure
+ containing information about the group whose group name is @var{name}.
+ This structure may be overwritten by subsequent calls to
+@@ -1794,6 +2457,14 @@
+ @comment grp.h
+ @comment POSIX.1c
+ @deftypefun int getgrnam_r (const char *@var{name}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getgrnam_r =~ getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  nscd_getgrnam_r @ascuheap @asulock @aculock @acsfd @acsmem
++@c   strlen dup ok
++@c   nscd_getgr_r dup @ascuheap @asulock @aculock @acsfd @acsmem
++@c  nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *fct.l @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ This function is similar to @code{getgrnam} in that is returns
+ information about the group whose group name is @var{name}.  Like
+ @code{getgrgid_r}, it uses the user supplied buffers in
+@@ -1817,6 +2488,16 @@
+ @comment grp.h
+ @comment SVID
+ @deftypefun {struct group *} fgetgrent (FILE *@var{stream})
++@safety{@prelim{}@mtunsafe{@mtasurace{:fgrent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}}
++@c fgetgrent @mtasurace:fgrent @asucorrupt @asulock @acucorrupt @aculock
++@c  fgetpos dup @asucorrupt @aculock @acucorrupt
++@c  libc_lock_lock dup @asulock @aculock
++@c  malloc dup @ascuheap @acsmem
++@c  fgetgrent_r dup @asucorrupt @acucorrupt @aculock
++@c  realloc dup @ascuheap @acsmem
++@c  free dup @ascuheap @acsmem
++@c  fsetpos dup @asucorrupt @aculock @acucorrupt
++@c  libc_lock_unlock dup @aculock
+ The @code{fgetgrent} function reads the next entry from @var{stream}.
+ It returns a pointer to the entry.  The structure is statically
+ allocated and is overwritten on subsequent calls to @code{fgetgrent}.  You
+@@ -1830,6 +2511,14 @@
+ @comment grp.h
+ @comment GNU
+ @deftypefun int fgetgrent_r (FILE *@var{stream}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
++@c fgetgrent_r @asucorrupt @acucorrupt @aculock
++@c  flockfile dup @aculock
++@c  fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking]
++@c  feof_unlocked dup ok
++@c  funlockfile dup @aculock
++@c  isspace dup @mtslocale^^
++@c  parse_line dup ok
+ This function is similar to @code{fgetgrent} in that it reads the next
+ user entry from @var{stream}.  But the result is returned in the
+ structure pointed to by @var{result_buf}.  The first @var{buflen} bytes
+@@ -1852,6 +2541,9 @@
+ @comment grp.h
+ @comment SVID, BSD
+ @deftypefun void setgrent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c setgrent =~ setpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c ...*lookup_fct = nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ This function initializes a stream for reading from the group data base.
+ You use this stream by calling @code{getgrent} or @code{getgrent_r}.
+ @end deftypefun
+@@ -1859,6 +2551,9 @@
+ @comment grp.h
+ @comment SVID, BSD
+ @deftypefun {struct group *} getgrent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtasurace{:grentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getgrent =~ getpwent dup @mtasurace:grent @mtasurace:grentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *func = getgrent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ The @code{getgrent} function reads the next entry from the stream
+ initialized by @code{setgrent}.  It returns a pointer to the entry.  The
+ structure is statically allocated and is overwritten on subsequent calls
+@@ -1869,6 +2564,8 @@
+ @comment grp.h
+ @comment GNU
+ @deftypefun int getgrent_r (struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
++@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getgrent_r =~ getpwent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ This function is similar to @code{getgrent} in that it returns the next
+ entry from the stream initialized by @code{setgrent}.  Like
+ @code{fgetgrent_r}, it places the result in user-supplied buffers
+@@ -1882,6 +2579,8 @@
+ @comment grp.h
+ @comment SVID, BSD
+ @deftypefun void endgrent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c endgrent =~ endpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ This function closes the internal stream used by @code{getgrent} or
+ @code{getgrent_r}.
+ @end deftypefun
+@@ -1966,6 +2665,40 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun int setnetgrent (const char *@var{netgroup})
++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c setnetgrent @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  nscd_setnetgrent @ascuheap @acsfd @acsmem
++@c   __nscd_setnetgrent @ascuheap @acsfd @acsmem
++@c    strlen dup ok
++@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
++@c    nscd_cache_search dup ok
++@c    nscd_open_socket dup @acsfd
++@c    malloc dup @ascuheap @acsmem
++@c    readall dup ok
++@c    free dup @ascuheap @acsmem
++@c    close_not_cancel_no_status dup @acsfd
++@c    nscd_drop_map_ref dup @ascuheap @acsmem
++@c    nscd_unmap dup @ascuheap @acsmem
++@c  internal_setnetgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   free_memory dup @ascuheap @acsmem
++@c    free dup @ascuheap @acsmem
++@c   internal_setnetgrent_reuse @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c     nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c     *endfct @ascuplugin
++@c    (netgroup::)setup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c     nss_netgroup_lookup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c      nss_netgroup_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c     nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    *fct.f @ascuplugin
++@c    nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c    *endfct @ascuplugin
++@c    strlen dup ok
++@c    malloc dup @ascuheap @acsmem
++@c    memcpy dup ok
++@c  libc_lock_unlock dup @aculock
+ A call to this function initializes the internal state of the library to
+ allow following calls of the @code{getnetgrent} to iterate over all entries
+ in the netgroup with name @var{netgroup}.
+@@ -1991,6 +2724,12 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun int getnetgrent (char **@var{hostp}, char **@var{userp}, char **@var{domainp})
++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtasurace{:netgrentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getnetgrent @mtasurace:netgrent @mtasurace:netgrentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   uses unsafely a static buffer allocated within a libc_once call
++@c  allocate (libc_once) @ascuheap @acsmem
++@c   malloc dup @ascuheap @acsmem
++@c  getnetgrent_r dup @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+ This function returns the next unprocessed entry of the currently
+ selected netgroup.  The string pointers, in which addresses are passed in
+ the arguments @var{hostp}, @var{userp}, and @var{domainp}, will contain
+@@ -2005,7 +2744,20 @@
+ 
+ @comment netdb.h
+ @comment GNU
+-@deftypefun int getnetgrent_r (char **@var{hostp}, char **@var{userp}, char **@var{domainp}, char *@var{buffer}, int @var{buflen})
++@deftypefun int getnetgrent_r (char **@var{hostp}, char **@var{userp}, char **@var{domainp}, char *@var{buffer}, size_t @var{buflen})
++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c getnetgrent_r @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  internal_getnetgrent_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   *fct @ascuplugin
++@c   nscd_getnetgrent ok
++@c    rawmemchr dup ok
++@c   internal_setnetgrent_reuse dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   strcmp dup ok
++@c   malloc dup @ascuheap @acsmem
++@c   memcpy dup ok
++@c  libc_lock_unlock dup @aculock
+ This function is similar to @code{getnetgrent} with only one exception:
+ the strings the three string pointers @var{hostp}, @var{userp}, and
+ @var{domainp} point to, are placed in the buffer of @var{buflen} bytes
+@@ -2024,6 +2776,13 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun void endnetgrent (void)
++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c endnetgrent @mtasurace:netgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  libc_lock_lock dup @asulock @aculock
++@c  internal_endnetgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c   free_memory dup @ascuheap @acsmem
++@c  libc_lock_unlock dup @aculock
+ This function frees all buffers which were allocated to process the last
+ selected netgroup.  As a result all string pointers returned by calls
+ to @code{getnetgrent} are invalid afterwards.
+@@ -2039,6 +2798,37 @@
+ @comment netdb.h
+ @comment BSD
+ @deftypefun int innetgr (const char *@var{netgroup}, const char *@var{host}, const char *@var{user}, const char *@var{domain})
++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
++@c This function does not use the static data structure that the
++@c *netgrent* ones do, but since each nss must maintains internal state
++@c to support iteration and concurrent iteration will interfere
++@c destructively, we regard this internal state as a static buffer.
++@c getnetgrent_r iteration in each nss backend.
++@c innetgr @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  nscd_innetgr @ascuheap @acsfd @acsmem
++@c   strlen dup ok
++@c   malloc dup @ascuheap @acsmem
++@c   stpcpy dup ok
++@c   nscd_get_map_ref dup @ascuheap @acsfd @acsmem
++@c   nscd_cache_search dup ok
++@c   nscd_open_socket dup @acsfd
++@c   close_not_cancel_no_status dup @acsfd
++@c   nscd_drop_map_ref dup @ascuheap @acsmem
++@c   nscd_unmap dup @ascuheap @acsmem
++@c   free dup @ascuheap @acsmem
++@c  memset dup ok
++@c  (netgroup::)setup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *setfct.f @ascuplugin
++@c  nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  *getfct @ascuplugin
++@c  strcmp dup ok
++@c  strlen dup ok
++@c  malloc dup @ascuheap @acsmem
++@c  memcpy dup ok
++@c  strcasecmp dup
++@c  *endfct @ascuplugin
++@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
++@c  free_memory dup @ascuheap @acsmem
+ This function tests whether the triple specified by the parameters
+ @var{hostp}, @var{userp}, and @var{domainp} is part of the netgroup
+ @var{netgroup}.  Using this function has the advantage that
+@@ -2062,3 +2852,7 @@
+ itself is not found, the netgroup does not contain the triple or
+ internal errors occurred.
+ @end deftypefun
++
++@c FIXME these are undocumented:
++@c setresgid
++@c setresuid
diff --git a/SOURCES/glibc-power-libm-test-ulps.patch b/SOURCES/glibc-power-libm-test-ulps.patch
new file mode 100644
index 0000000..2b7d277
--- /dev/null
+++ b/SOURCES/glibc-power-libm-test-ulps.patch
@@ -0,0 +1,21 @@
+#
+# On POWER this patch also fixes test-ildoubl and test-ldouble failures where tan
+# rounded toward zero had acceptable 1 ULP error. Upstream is using 3 ULP, but
+# we prefer to keep the bound tighter unless we have a reason not to.
+#
+# This is the generic power version of this patch that applies cleanly when the
+# ppc64le patches are not being applied. See glibc-ppc64le-46.patch for the ppc64le
+# version.
+#
+--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps	2014-07-26 20:28:21.120919701 -0400
++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps	2014-07-26 20:47:17.657901758 -0400
+@@ -2641,6 +2641,9 @@
+ ifloat: 1
+ ildouble: 2
+ ldouble: 2
++Test "tan_towardzero (2) == -2.1850398632615189916433061023136825434320":
++ildouble: 1
++ldouble: 1
+ Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261":
+ float: 1
+ ifloat: 1
diff --git a/SOURCES/glibc-powerpc-ldbl_high.patch b/SOURCES/glibc-powerpc-ldbl_high.patch
new file mode 100644
index 0000000..b0b1c5b
--- /dev/null
+++ b/SOURCES/glibc-powerpc-ldbl_high.patch
@@ -0,0 +1,13 @@
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-27 19:59:00.000000000 -0500
+@@ -190,6 +190,9 @@
+ # define ldbl_unpack default_ldbl_unpack
+ #endif
+ 
++/* Extract high double.  */
++#define ldbl_high(x) ((double) x)
++
+ /* Convert a finite long double to canonical form.
+    Does not handle +/-Inf properly.  */
+ static inline void
diff --git a/SOURCES/glibc-ppc64le-01.patch b/SOURCES/glibc-ppc64le-01.patch
new file mode 100644
index 0000000..ef7afd6
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-01.patch
@@ -0,0 +1,83 @@
+# commit 1695c7737655241e1773bdddc93e82c22d8d1584
+# Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+# Date:   Tue Feb 4 09:48:47 2014 -0200
+#
+#     abilist-pattern configurability
+#    
+#     This patch creates implicit rules to match the abifiles if
+#     abilist-pattern is defined in the architecture Makefile. This allows
+#     machine specific Makefiles to define different abifiles names
+#     (for instance *-le.abilist for powerpc64le).
+#
+diff -urN glibc-2.17-c758a686.orig/Makerules glibc-2.17-c758a686.new/Makerules
+--- glibc-2.17-c758a686.orig/Makerules	2014-06-02 15:29:42.000000000 +0000
++++ glibc-2.17-c758a686.new/Makerules	2014-06-02 15:25:21.000000000 +0000
+@@ -1152,6 +1152,14 @@
+ 	LC_ALL=C $(OBJDUMP) --dynamic-syms $< > $@T
+ 	mv -f $@T $@
+ 
++# A sysdeps/.../Makefile can set abilist-pattern to something like
++# %-foo.abilist to look for libc-foo.abilist instead of libc.abilist.
++# This makes sense if multiple ABIs can be most cleanly supported by a
++# configuration without using separate sysdeps directories for each.
++ifdef abilist-pattern
++vpath $(abilist-pattern) $(+sysdep_dirs)
++endif
++
+ vpath %.abilist $(+sysdep_dirs)
+ 
+ # The .PRECIOUS rule prevents the files built by an implicit rule whose
+@@ -1161,18 +1169,42 @@
+ .PRECIOUS: %.symlist
+ generated += $(extra-libs:=.symlist)
+ 
++ifdef abilist-pattern
++check-abi-%: $(common-objpfx)config.make $(abilist-pattern) $(objpfx)%.symlist
++	$(check-abi-pattern)
++check-abi-%: $(common-objpfx)config.make $(abilist-pattern) \
++	     $(common-objpfx)%.symlist
++	$(check-abi-pattern)
++endif
+ check-abi-%: $(common-objpfx)config.make %.abilist $(objpfx)%.symlist
+ 	$(check-abi)
+ check-abi-%: $(common-objpfx)config.make %.abilist $(common-objpfx)%.symlist
+ 	$(check-abi)
++define check-abi-pattern
++	diff -p -U 0 $(filter $(abilist-pattern),$^) $(filter %.symlist,$^)
++endef
+ define check-abi
+ 	diff -p -U 0 $(filter %.abilist,$^) $(filter %.symlist,$^)
+ endef
+ 
++ifdef abilist-pattern
++update-abi-%: $(objpfx)%.symlist $(abilist-pattern)
++	$(update-abi-pattern)
++update-abi-%: $(common-objpfx)%.symlist $(abilist-pattern)
++	$(update-abi-pattern)
++endif
+ update-abi-%: $(objpfx)%.symlist %.abilist
+ 	$(update-abi)
+ update-abi-%: $(common-objpfx)%.symlist %.abilist
+ 	$(update-abi)
++define update-abi-pattern
++@if cmp -s $^ 2> /dev/null; \
++ then \
++      echo '+++ $(filter $(abilist-pattern),$^) is unchanged'; \
++ else cp -f $^; \
++      echo '*** Now check $(filter $(abilist-pattern),$^) changes for correctness ***'; \
++ fi
++endef
+ define update-abi
+ @if cmp -s $^ 2> /dev/null; \
+  then \
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/Makefile glibc-2.17-c758a686.new/sysdeps/powerpc/Makefile
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/Makefile	2014-06-02 15:29:42.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/powerpc/Makefile	2014-06-02 15:25:21.000000000 +0000
+@@ -27,3 +27,7 @@
+ sysdep_headers += sys/platform/ppc.h
+ tests += test-gettimebase
+ endif
++
++ifneq (,$(filter %le,$(config-machine)))
++abilist-pattern = %-le.abilist
++endif
diff --git a/SOURCES/glibc-ppc64le-02.patch b/SOURCES/glibc-ppc64le-02.patch
new file mode 100644
index 0000000..0dcac9c
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-02.patch
@@ -0,0 +1,3197 @@
+# co`mmit c01603f763003cec55234ac757c7a934652caa55
+# Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+# Date:   Tue Feb 4 09:49:34 2014 -0200
+#
+#     PowerPC: powerpc64le abilist for 2.17
+#    
+#     This patch is the abifiles for powerpc64le based on GLIBC 2.17.
+#
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/ld-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/ld-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/ld-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/ld-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,11 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ __libc_memalign F
++ __libc_stack_end D 0x8
++ __tls_get_addr F
++ _dl_mcount F
++ _r_debug D 0x28
++ calloc F
++ free F
++ malloc F
++ realloc F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libBrokenLocale-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libBrokenLocale-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libBrokenLocale-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libBrokenLocale-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,3 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ __ctype_get_mb_cur_max F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libanl-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libanl-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libanl-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libanl-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,6 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ gai_cancel F
++ gai_error F
++ gai_suspend F
++ getaddrinfo_a F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,2168 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ _Exit F
++ _IO_2_1_stderr_ D 0xe0
++ _IO_2_1_stdin_ D 0xe0
++ _IO_2_1_stdout_ D 0xe0
++ _IO_adjust_column F
++ _IO_adjust_wcolumn F
++ _IO_default_doallocate F
++ _IO_default_finish F
++ _IO_default_pbackfail F
++ _IO_default_uflow F
++ _IO_default_xsgetn F
++ _IO_default_xsputn F
++ _IO_do_write F
++ _IO_doallocbuf F
++ _IO_fclose F
++ _IO_fdopen F
++ _IO_feof F
++ _IO_ferror F
++ _IO_fflush F
++ _IO_fgetpos F
++ _IO_fgetpos64 F
++ _IO_fgets F
++ _IO_file_attach F
++ _IO_file_close F
++ _IO_file_close_it F
++ _IO_file_doallocate F
++ _IO_file_finish F
++ _IO_file_fopen F
++ _IO_file_init F
++ _IO_file_jumps D 0xa8
++ _IO_file_open F
++ _IO_file_overflow F
++ _IO_file_read F
++ _IO_file_seek F
++ _IO_file_seekoff F
++ _IO_file_setbuf F
++ _IO_file_stat F
++ _IO_file_sync F
++ _IO_file_underflow F
++ _IO_file_write F
++ _IO_file_xsputn F
++ _IO_flockfile F
++ _IO_flush_all F
++ _IO_flush_all_linebuffered F
++ _IO_fopen F
++ _IO_fprintf F
++ _IO_fputs F
++ _IO_fread F
++ _IO_free_backup_area F
++ _IO_free_wbackup_area F
++ _IO_fsetpos F
++ _IO_fsetpos64 F
++ _IO_ftell F
++ _IO_ftrylockfile F
++ _IO_funlockfile F
++ _IO_fwrite F
++ _IO_getc F
++ _IO_getline F
++ _IO_getline_info F
++ _IO_gets F
++ _IO_init F
++ _IO_init_marker F
++ _IO_init_wmarker F
++ _IO_iter_begin F
++ _IO_iter_end F
++ _IO_iter_file F
++ _IO_iter_next F
++ _IO_least_wmarker F
++ _IO_link_in F
++ _IO_list_all D 0x8
++ _IO_list_lock F
++ _IO_list_resetlock F
++ _IO_list_unlock F
++ _IO_marker_delta F
++ _IO_marker_difference F
++ _IO_padn F
++ _IO_peekc_locked F
++ _IO_popen F
++ _IO_printf F
++ _IO_proc_close F
++ _IO_proc_open F
++ _IO_putc F
++ _IO_puts F
++ _IO_remove_marker F
++ _IO_seekmark F
++ _IO_seekoff F
++ _IO_seekpos F
++ _IO_seekwmark F
++ _IO_setb F
++ _IO_setbuffer F
++ _IO_setvbuf F
++ _IO_sgetn F
++ _IO_sprintf F
++ _IO_sputbackc F
++ _IO_sputbackwc F
++ _IO_sscanf F
++ _IO_str_init_readonly F
++ _IO_str_init_static F
++ _IO_str_overflow F
++ _IO_str_pbackfail F
++ _IO_str_seekoff F
++ _IO_str_underflow F
++ _IO_sungetc F
++ _IO_sungetwc F
++ _IO_switch_to_get_mode F
++ _IO_switch_to_main_wget_area F
++ _IO_switch_to_wbackup_area F
++ _IO_switch_to_wget_mode F
++ _IO_un_link F
++ _IO_ungetc F
++ _IO_unsave_markers F
++ _IO_unsave_wmarkers F
++ _IO_vfprintf F
++ _IO_vfscanf F
++ _IO_vsprintf F
++ _IO_wdefault_doallocate F
++ _IO_wdefault_finish F
++ _IO_wdefault_pbackfail F
++ _IO_wdefault_uflow F
++ _IO_wdefault_xsgetn F
++ _IO_wdefault_xsputn F
++ _IO_wdo_write F
++ _IO_wdoallocbuf F
++ _IO_wfile_jumps D 0xa8
++ _IO_wfile_overflow F
++ _IO_wfile_seekoff F
++ _IO_wfile_sync F
++ _IO_wfile_underflow F
++ _IO_wfile_xsputn F
++ _IO_wmarker_delta F
++ _IO_wsetb F
++ __adjtimex F
++ __after_morecore_hook D 0x8
++ __argz_count F
++ __argz_next F
++ __argz_stringify F
++ __asprintf F
++ __asprintf_chk F
++ __assert F
++ __assert_fail F
++ __assert_perror_fail F
++ __backtrace F
++ __backtrace_symbols F
++ __backtrace_symbols_fd F
++ __bsd_getpgrp F
++ __bzero F
++ __check_rhosts_file D 0x4
++ __chk_fail F
++ __clone F
++ __close F
++ __cmsg_nxthdr F
++ __confstr_chk F
++ __connect F
++ __ctype_b_loc F
++ __ctype_get_mb_cur_max F
++ __ctype_tolower_loc F
++ __ctype_toupper_loc F
++ __curbrk D 0x8
++ __cxa_at_quick_exit F
++ __cxa_atexit F
++ __cxa_finalize F
++ __cyg_profile_func_enter F
++ __cyg_profile_func_exit F
++ __daylight D 0x4
++ __dcgettext F
++ __default_morecore F
++ __dgettext F
++ __dprintf_chk F
++ __dup2 F
++ __duplocale F
++ __endmntent F
++ __environ D 0x8
++ __errno_location F
++ __fbufsize F
++ __fcntl F
++ __fdelt_chk F
++ __fdelt_warn F
++ __ffs F
++ __fgets_chk F
++ __fgets_unlocked_chk F
++ __fgetws_chk F
++ __fgetws_unlocked_chk F
++ __finite F
++ __finitef F
++ __finitel F
++ __flbf F
++ __fork F
++ __fpending F
++ __fprintf_chk F
++ __fpu_control D 0x4
++ __fpurge F
++ __fread_chk F
++ __fread_unlocked_chk F
++ __freadable F
++ __freading F
++ __free_hook D 0x8
++ __freelocale F
++ __fsetlocking F
++ __fwprintf_chk F
++ __fwritable F
++ __fwriting F
++ __fxstat F
++ __fxstat64 F
++ __fxstatat F
++ __fxstatat64 F
++ __getauxval F
++ __getcwd_chk F
++ __getdelim F
++ __getdomainname_chk F
++ __getgroups_chk F
++ __gethostname_chk F
++ __getlogin_r_chk F
++ __getmntent_r F
++ __getpagesize F
++ __getpgid F
++ __getpid F
++ __gets_chk F
++ __gettimeofday F
++ __getwd_chk F
++ __gmtime_r F
++ __h_errno_location F
++ __isalnum_l F
++ __isalpha_l F
++ __isascii_l F
++ __isblank_l F
++ __iscntrl_l F
++ __isctype F
++ __isdigit_l F
++ __isgraph_l F
++ __isinf F
++ __isinff F
++ __isinfl F
++ __islower_l F
++ __isnan F
++ __isnanf F
++ __isnanl F
++ __isoc99_fscanf F
++ __isoc99_fwscanf F
++ __isoc99_scanf F
++ __isoc99_sscanf F
++ __isoc99_swscanf F
++ __isoc99_vfscanf F
++ __isoc99_vfwscanf F
++ __isoc99_vscanf F
++ __isoc99_vsscanf F
++ __isoc99_vswscanf F
++ __isoc99_vwscanf F
++ __isoc99_wscanf F
++ __isprint_l F
++ __ispunct_l F
++ __isspace_l F
++ __isupper_l F
++ __iswalnum_l F
++ __iswalpha_l F
++ __iswblank_l F
++ __iswcntrl_l F
++ __iswctype F
++ __iswctype_l F
++ __iswdigit_l F
++ __iswgraph_l F
++ __iswlower_l F
++ __iswprint_l F
++ __iswpunct_l F
++ __iswspace_l F
++ __iswupper_l F
++ __iswxdigit_l F
++ __isxdigit_l F
++ __ivaliduser F
++ __key_decryptsession_pk_LOCAL D 0x8
++ __key_encryptsession_pk_LOCAL D 0x8
++ __key_gendes_LOCAL D 0x8
++ __libc_allocate_rtsig F
++ __libc_calloc F
++ __libc_current_sigrtmax F
++ __libc_current_sigrtmin F
++ __libc_free F
++ __libc_freeres F
++ __libc_init_first F
++ __libc_mallinfo F
++ __libc_malloc F
++ __libc_mallopt F
++ __libc_memalign F
++ __libc_pvalloc F
++ __libc_realloc F
++ __libc_sa_len F
++ __libc_start_main F
++ __libc_valloc F
++ __longjmp_chk F
++ __lseek F
++ __lxstat F
++ __lxstat64 F
++ __malloc_hook D 0x8
++ __malloc_initialize_hook D 0x8
++ __mbrlen F
++ __mbrtowc F
++ __mbsnrtowcs_chk F
++ __mbsrtowcs_chk F
++ __mbstowcs_chk F
++ __memalign_hook D 0x8
++ __memcpy_chk F
++ __memmove_chk F
++ __mempcpy F
++ __mempcpy_chk F
++ __mempcpy_small F
++ __memset_chk F
++ __monstartup F
++ __morecore D 0x8
++ __nanosleep F
++ __newlocale F
++ __nl_langinfo_l F
++ __nldbl__IO_fprintf F
++ __nldbl__IO_printf F
++ __nldbl__IO_sprintf F
++ __nldbl__IO_sscanf F
++ __nldbl__IO_vfprintf F
++ __nldbl__IO_vfscanf F
++ __nldbl__IO_vsprintf F
++ __nldbl___asprintf F
++ __nldbl___asprintf_chk F
++ __nldbl___dprintf_chk F
++ __nldbl___fprintf_chk F
++ __nldbl___fwprintf_chk F
++ __nldbl___isoc99_fscanf F
++ __nldbl___isoc99_fwscanf F
++ __nldbl___isoc99_scanf F
++ __nldbl___isoc99_sscanf F
++ __nldbl___isoc99_swscanf F
++ __nldbl___isoc99_vfscanf F
++ __nldbl___isoc99_vfwscanf F
++ __nldbl___isoc99_vscanf F
++ __nldbl___isoc99_vsscanf F
++ __nldbl___isoc99_vswscanf F
++ __nldbl___isoc99_vwscanf F
++ __nldbl___isoc99_wscanf F
++ __nldbl___obstack_printf_chk F
++ __nldbl___obstack_vprintf_chk F
++ __nldbl___printf_chk F
++ __nldbl___printf_fp F
++ __nldbl___snprintf_chk F
++ __nldbl___sprintf_chk F
++ __nldbl___strfmon_l F
++ __nldbl___swprintf_chk F
++ __nldbl___syslog_chk F
++ __nldbl___vasprintf_chk F
++ __nldbl___vdprintf_chk F
++ __nldbl___vfprintf_chk F
++ __nldbl___vfscanf F
++ __nldbl___vfwprintf_chk F
++ __nldbl___vprintf_chk F
++ __nldbl___vsnprintf F
++ __nldbl___vsnprintf_chk F
++ __nldbl___vsprintf_chk F
++ __nldbl___vsscanf F
++ __nldbl___vstrfmon F
++ __nldbl___vstrfmon_l F
++ __nldbl___vswprintf_chk F
++ __nldbl___vsyslog_chk F
++ __nldbl___vwprintf_chk F
++ __nldbl___wprintf_chk F
++ __nldbl_asprintf F
++ __nldbl_dprintf F
++ __nldbl_fprintf F
++ __nldbl_fscanf F
++ __nldbl_fwprintf F
++ __nldbl_fwscanf F
++ __nldbl_obstack_printf F
++ __nldbl_obstack_vprintf F
++ __nldbl_printf F
++ __nldbl_printf_size F
++ __nldbl_scanf F
++ __nldbl_snprintf F
++ __nldbl_sprintf F
++ __nldbl_sscanf F
++ __nldbl_strfmon F
++ __nldbl_strfmon_l F
++ __nldbl_swprintf F
++ __nldbl_swscanf F
++ __nldbl_syslog F
++ __nldbl_vasprintf F
++ __nldbl_vdprintf F
++ __nldbl_vfprintf F
++ __nldbl_vfscanf F
++ __nldbl_vfwprintf F
++ __nldbl_vfwscanf F
++ __nldbl_vprintf F
++ __nldbl_vscanf F
++ __nldbl_vsnprintf F
++ __nldbl_vsprintf F
++ __nldbl_vsscanf F
++ __nldbl_vswprintf F
++ __nldbl_vswscanf F
++ __nldbl_vsyslog F
++ __nldbl_vwprintf F
++ __nldbl_vwscanf F
++ __nldbl_wprintf F
++ __nldbl_wscanf F
++ __nss_configure_lookup F
++ __nss_database_lookup F
++ __nss_group_lookup F
++ __nss_hostname_digits_dots F
++ __nss_hosts_lookup F
++ __nss_next F
++ __nss_passwd_lookup F
++ __obstack_printf_chk F
++ __obstack_vprintf_chk F
++ __open F
++ __open64 F
++ __open64_2 F
++ __open_2 F
++ __openat64_2 F
++ __openat_2 F
++ __overflow F
++ __pipe F
++ __poll F
++ __poll_chk F
++ __posix_getopt F
++ __ppc_get_timebase_freq F
++ __ppoll_chk F
++ __pread64 F
++ __pread64_chk F
++ __pread_chk F
++ __printf_chk F
++ __printf_fp F
++ __profile_frequency F
++ __progname D 0x8
++ __progname_full D 0x8
++ __ptsname_r_chk F
++ __pwrite64 F
++ __rawmemchr F
++ __rcmd_errstr D 0x8
++ __read F
++ __read_chk F
++ __readlink_chk F
++ __readlinkat_chk F
++ __realloc_hook D 0x8
++ __realpath_chk F
++ __recv_chk F
++ __recvfrom_chk F
++ __register_atfork F
++ __res_init F
++ __res_nclose F
++ __res_ninit F
++ __res_randomid F
++ __res_state F
++ __rpc_thread_createerr F
++ __rpc_thread_svc_fdset F
++ __rpc_thread_svc_max_pollfd F
++ __rpc_thread_svc_pollfd F
++ __sbrk F
++ __sched_cpualloc F
++ __sched_cpucount F
++ __sched_cpufree F
++ __sched_get_priority_max F
++ __sched_get_priority_min F
++ __sched_getparam F
++ __sched_getscheduler F
++ __sched_setscheduler F
++ __sched_yield F
++ __select F
++ __send F
++ __setmntent F
++ __setpgid F
++ __sigaction F
++ __sigaddset F
++ __sigdelset F
++ __sigismember F
++ __signbit F
++ __signbitf F
++ __signbitl F
++ __sigpause F
++ __sigsetjmp F
++ __sigsuspend F
++ __snprintf_chk F
++ __sprintf_chk F
++ __stack_chk_fail F
++ __statfs F
++ __stpcpy F
++ __stpcpy_chk F
++ __stpcpy_small F
++ __stpncpy F
++ __stpncpy_chk F
++ __strcasecmp F
++ __strcasecmp_l F
++ __strcasestr F
++ __strcat_chk F
++ __strcoll_l F
++ __strcpy_chk F
++ __strcpy_small F
++ __strcspn_c1 F
++ __strcspn_c2 F
++ __strcspn_c3 F
++ __strdup F
++ __strerror_r F
++ __strfmon_l F
++ __strftime_l F
++ __strncasecmp_l F
++ __strncat_chk F
++ __strncpy_chk F
++ __strndup F
++ __strpbrk_c2 F
++ __strpbrk_c3 F
++ __strsep_1c F
++ __strsep_2c F
++ __strsep_3c F
++ __strsep_g F
++ __strspn_c1 F
++ __strspn_c2 F
++ __strspn_c3 F
++ __strtod_internal F
++ __strtod_l F
++ __strtof_internal F
++ __strtof_l F
++ __strtok_r F
++ __strtok_r_1c F
++ __strtol_internal F
++ __strtol_l F
++ __strtold_internal F
++ __strtold_l F
++ __strtoll_internal F
++ __strtoll_l F
++ __strtoul_internal F
++ __strtoul_l F
++ __strtoull_internal F
++ __strtoull_l F
++ __strverscmp F
++ __strxfrm_l F
++ __swprintf_chk F
++ __sysconf F
++ __sysctl F
++ __syslog_chk F
++ __sysv_signal F
++ __timezone D 0x8
++ __toascii_l F
++ __tolower_l F
++ __toupper_l F
++ __towctrans F
++ __towctrans_l F
++ __towlower_l F
++ __towupper_l F
++ __ttyname_r_chk F
++ __tzname D 0x10
++ __uflow F
++ __underflow F
++ __uselocale F
++ __vasprintf_chk F
++ __vdprintf_chk F
++ __vfork F
++ __vfprintf_chk F
++ __vfscanf F
++ __vfwprintf_chk F
++ __vprintf_chk F
++ __vsnprintf F
++ __vsnprintf_chk F
++ __vsprintf_chk F
++ __vsscanf F
++ __vswprintf_chk F
++ __vsyslog_chk F
++ __vwprintf_chk F
++ __wait F
++ __waitpid F
++ __wcpcpy_chk F
++ __wcpncpy_chk F
++ __wcrtomb_chk F
++ __wcscasecmp_l F
++ __wcscat_chk F
++ __wcscoll_l F
++ __wcscpy_chk F
++ __wcsftime_l F
++ __wcsncasecmp_l F
++ __wcsncat_chk F
++ __wcsncpy_chk F
++ __wcsnrtombs_chk F
++ __wcsrtombs_chk F
++ __wcstod_internal F
++ __wcstod_l F
++ __wcstof_internal F
++ __wcstof_l F
++ __wcstol_internal F
++ __wcstol_l F
++ __wcstold_internal F
++ __wcstold_l F
++ __wcstoll_internal F
++ __wcstoll_l F
++ __wcstombs_chk F
++ __wcstoul_internal F
++ __wcstoul_l F
++ __wcstoull_internal F
++ __wcstoull_l F
++ __wcsxfrm_l F
++ __wctomb_chk F
++ __wctrans_l F
++ __wctype_l F
++ __wmemcpy_chk F
++ __wmemmove_chk F
++ __wmempcpy_chk F
++ __wmemset_chk F
++ __woverflow F
++ __wprintf_chk F
++ __write F
++ __wuflow F
++ __wunderflow F
++ __xmknod F
++ __xmknodat F
++ __xpg_basename F
++ __xpg_sigpause F
++ __xpg_strerror_r F
++ __xstat F
++ __xstat64 F
++ _authenticate F
++ _dl_mcount_wrapper F
++ _dl_mcount_wrapper_check F
++ _environ D 0x8
++ _exit F
++ _flushlbf F
++ _libc_intl_domainname D 0x5
++ _longjmp F
++ _mcleanup F
++ _mcount F
++ _nl_default_dirname D 0x12
++ _nl_domain_bindings D 0x8
++ _nl_msg_cat_cntr D 0x4
++ _null_auth D 0x18
++ _obstack_allocated_p F
++ _obstack_begin F
++ _obstack_begin_1 F
++ _obstack_free F
++ _obstack_memory_used F
++ _obstack_newchunk F
++ _res D 0x238
++ _res_hconf D 0x48
++ _rpc_dtablesize F
++ _seterr_reply F
++ _setjmp F
++ _sys_errlist D 0x438
++ _sys_nerr D 0x4
++ _sys_siglist D 0x208
++ _tolower F
++ _toupper F
++ a64l F
++ abort F
++ abs F
++ accept F
++ accept4 F
++ access F
++ acct F
++ addmntent F
++ addseverity F
++ adjtime F
++ adjtimex F
++ advance F
++ alarm F
++ aligned_alloc F
++ alphasort F
++ alphasort64 F
++ argp_err_exit_status D 0x4
++ argp_error F
++ argp_failure F
++ argp_help F
++ argp_parse F
++ argp_program_bug_address D 0x8
++ argp_program_version D 0x8
++ argp_program_version_hook D 0x8
++ argp_state_help F
++ argp_usage F
++ argz_add F
++ argz_add_sep F
++ argz_append F
++ argz_count F
++ argz_create F
++ argz_create_sep F
++ argz_delete F
++ argz_extract F
++ argz_insert F
++ argz_next F
++ argz_replace F
++ argz_stringify F
++ asctime F
++ asctime_r F
++ asprintf F
++ atof F
++ atoi F
++ atol F
++ atoll F
++ authdes_create F
++ authdes_getucred F
++ authdes_pk_create F
++ authnone_create F
++ authunix_create F
++ authunix_create_default F
++ backtrace F
++ backtrace_symbols F
++ backtrace_symbols_fd F
++ basename F
++ bcmp F
++ bcopy F
++ bdflush F
++ bind F
++ bind_textdomain_codeset F
++ bindresvport F
++ bindtextdomain F
++ brk F
++ bsd_signal F
++ bsearch F
++ btowc F
++ bzero F
++ c16rtomb F
++ c32rtomb F
++ calloc F
++ callrpc F
++ canonicalize_file_name F
++ capget F
++ capset F
++ catclose F
++ catgets F
++ catopen F
++ cbc_crypt F
++ cfgetispeed F
++ cfgetospeed F
++ cfmakeraw F
++ cfree F
++ cfsetispeed F
++ cfsetospeed F
++ cfsetspeed F
++ chdir F
++ chflags F
++ chmod F
++ chown F
++ chroot F
++ clearenv F
++ clearerr F
++ clearerr_unlocked F
++ clnt_broadcast F
++ clnt_create F
++ clnt_pcreateerror F
++ clnt_perrno F
++ clnt_perror F
++ clnt_spcreateerror F
++ clnt_sperrno F
++ clnt_sperror F
++ clntraw_create F
++ clnttcp_create F
++ clntudp_bufcreate F
++ clntudp_create F
++ clntunix_create F
++ clock F
++ clock_adjtime F
++ clock_getcpuclockid F
++ clock_getres F
++ clock_gettime F
++ clock_nanosleep F
++ clock_settime F
++ clone F
++ close F
++ closedir F
++ closelog F
++ confstr F
++ connect F
++ copysign F
++ copysignf F
++ copysignl F
++ creat F
++ creat64 F
++ create_module F
++ ctermid F
++ ctime F
++ ctime_r F
++ cuserid F
++ daemon F
++ daylight D 0x4
++ dcgettext F
++ dcngettext F
++ delete_module F
++ des_setparity F
++ dgettext F
++ difftime F
++ dirfd F
++ dirname F
++ div F
++ dl_iterate_phdr F
++ dngettext F
++ dprintf F
++ drand48 F
++ drand48_r F
++ dup F
++ dup2 F
++ dup3 F
++ duplocale F
++ dysize F
++ eaccess F
++ ecb_crypt F
++ ecvt F
++ ecvt_r F
++ endaliasent F
++ endfsent F
++ endgrent F
++ endhostent F
++ endmntent F
++ endnetent F
++ endnetgrent F
++ endprotoent F
++ endpwent F
++ endrpcent F
++ endservent F
++ endsgent F
++ endspent F
++ endttyent F
++ endusershell F
++ endutent F
++ endutxent F
++ environ D 0x8
++ envz_add F
++ envz_entry F
++ envz_get F
++ envz_merge F
++ envz_remove F
++ envz_strip F
++ epoll_create F
++ epoll_create1 F
++ epoll_ctl F
++ epoll_pwait F
++ epoll_wait F
++ erand48 F
++ erand48_r F
++ err F
++ error F
++ error_at_line F
++ error_message_count D 0x4
++ error_one_per_line D 0x4
++ error_print_progname D 0x8
++ errx F
++ ether_aton F
++ ether_aton_r F
++ ether_hostton F
++ ether_line F
++ ether_ntoa F
++ ether_ntoa_r F
++ ether_ntohost F
++ euidaccess F
++ eventfd F
++ eventfd_read F
++ eventfd_write F
++ execl F
++ execle F
++ execlp F
++ execv F
++ execve F
++ execvp F
++ execvpe F
++ exit F
++ faccessat F
++ fallocate F
++ fallocate64 F
++ fanotify_init F
++ fanotify_mark F
++ fattach F
++ fchdir F
++ fchflags F
++ fchmod F
++ fchmodat F
++ fchown F
++ fchownat F
++ fclose F
++ fcloseall F
++ fcntl F
++ fcvt F
++ fcvt_r F
++ fdatasync F
++ fdetach F
++ fdopen F
++ fdopendir F
++ feof F
++ feof_unlocked F
++ ferror F
++ ferror_unlocked F
++ fexecve F
++ fflush F
++ fflush_unlocked F
++ ffs F
++ ffsl F
++ ffsll F
++ fgetc F
++ fgetc_unlocked F
++ fgetgrent F
++ fgetgrent_r F
++ fgetpos F
++ fgetpos64 F
++ fgetpwent F
++ fgetpwent_r F
++ fgets F
++ fgets_unlocked F
++ fgetsgent F
++ fgetsgent_r F
++ fgetspent F
++ fgetspent_r F
++ fgetwc F
++ fgetwc_unlocked F
++ fgetws F
++ fgetws_unlocked F
++ fgetxattr F
++ fileno F
++ fileno_unlocked F
++ finite F
++ finitef F
++ finitel F
++ flistxattr F
++ flock F
++ flockfile F
++ fmemopen F
++ fmtmsg F
++ fnmatch F
++ fopen F
++ fopen64 F
++ fopencookie F
++ fork F
++ fpathconf F
++ fprintf F
++ fputc F
++ fputc_unlocked F
++ fputs F
++ fputs_unlocked F
++ fputwc F
++ fputwc_unlocked F
++ fputws F
++ fputws_unlocked F
++ fread F
++ fread_unlocked F
++ free F
++ freeaddrinfo F
++ freeifaddrs F
++ freelocale F
++ fremovexattr F
++ freopen F
++ freopen64 F
++ frexp F
++ frexpf F
++ frexpl F
++ fscanf F
++ fseek F
++ fseeko F
++ fseeko64 F
++ fsetpos F
++ fsetpos64 F
++ fsetxattr F
++ fstatfs F
++ fstatfs64 F
++ fstatvfs F
++ fstatvfs64 F
++ fsync F
++ ftell F
++ ftello F
++ ftello64 F
++ ftime F
++ ftok F
++ ftruncate F
++ ftruncate64 F
++ ftrylockfile F
++ fts_children F
++ fts_close F
++ fts_open F
++ fts_read F
++ fts_set F
++ ftw F
++ ftw64 F
++ funlockfile F
++ futimens F
++ futimes F
++ futimesat F
++ fwide F
++ fwprintf F
++ fwrite F
++ fwrite_unlocked F
++ fwscanf F
++ gai_strerror F
++ gcvt F
++ get_avphys_pages F
++ get_current_dir_name F
++ get_kernel_syms F
++ get_myaddress F
++ get_nprocs F
++ get_nprocs_conf F
++ get_phys_pages F
++ getaddrinfo F
++ getaliasbyname F
++ getaliasbyname_r F
++ getaliasent F
++ getaliasent_r F
++ getauxval F
++ getc F
++ getc_unlocked F
++ getchar F
++ getchar_unlocked F
++ getcontext F
++ getcwd F
++ getdate F
++ getdate_err D 0x4
++ getdate_r F
++ getdelim F
++ getdirentries F
++ getdirentries64 F
++ getdomainname F
++ getdtablesize F
++ getegid F
++ getenv F
++ geteuid F
++ getfsent F
++ getfsfile F
++ getfsspec F
++ getgid F
++ getgrent F
++ getgrent_r F
++ getgrgid F
++ getgrgid_r F
++ getgrnam F
++ getgrnam_r F
++ getgrouplist F
++ getgroups F
++ gethostbyaddr F
++ gethostbyaddr_r F
++ gethostbyname F
++ gethostbyname2 F
++ gethostbyname2_r F
++ gethostbyname_r F
++ gethostent F
++ gethostent_r F
++ gethostid F
++ gethostname F
++ getifaddrs F
++ getipv4sourcefilter F
++ getitimer F
++ getline F
++ getloadavg F
++ getlogin F
++ getlogin_r F
++ getmntent F
++ getmntent_r F
++ getmsg F
++ getnameinfo F
++ getnetbyaddr F
++ getnetbyaddr_r F
++ getnetbyname F
++ getnetbyname_r F
++ getnetent F
++ getnetent_r F
++ getnetgrent F
++ getnetgrent_r F
++ getnetname F
++ getopt F
++ getopt_long F
++ getopt_long_only F
++ getpagesize F
++ getpass F
++ getpeername F
++ getpgid F
++ getpgrp F
++ getpid F
++ getpmsg F
++ getppid F
++ getpriority F
++ getprotobyname F
++ getprotobyname_r F
++ getprotobynumber F
++ getprotobynumber_r F
++ getprotoent F
++ getprotoent_r F
++ getpt F
++ getpublickey F
++ getpw F
++ getpwent F
++ getpwent_r F
++ getpwnam F
++ getpwnam_r F
++ getpwuid F
++ getpwuid_r F
++ getresgid F
++ getresuid F
++ getrlimit F
++ getrlimit64 F
++ getrpcbyname F
++ getrpcbyname_r F
++ getrpcbynumber F
++ getrpcbynumber_r F
++ getrpcent F
++ getrpcent_r F
++ getrpcport F
++ getrusage F
++ gets F
++ getsecretkey F
++ getservbyname F
++ getservbyname_r F
++ getservbyport F
++ getservbyport_r F
++ getservent F
++ getservent_r F
++ getsgent F
++ getsgent_r F
++ getsgnam F
++ getsgnam_r F
++ getsid F
++ getsockname F
++ getsockopt F
++ getsourcefilter F
++ getspent F
++ getspent_r F
++ getspnam F
++ getspnam_r F
++ getsubopt F
++ gettext F
++ gettimeofday F
++ getttyent F
++ getttynam F
++ getuid F
++ getusershell F
++ getutent F
++ getutent_r F
++ getutid F
++ getutid_r F
++ getutline F
++ getutline_r F
++ getutmp F
++ getutmpx F
++ getutxent F
++ getutxid F
++ getutxline F
++ getw F
++ getwc F
++ getwc_unlocked F
++ getwchar F
++ getwchar_unlocked F
++ getwd F
++ getxattr F
++ glob F
++ glob64 F
++ glob_pattern_p F
++ globfree F
++ globfree64 F
++ gmtime F
++ gmtime_r F
++ gnu_dev_major F
++ gnu_dev_makedev F
++ gnu_dev_minor F
++ gnu_get_libc_release F
++ gnu_get_libc_version F
++ grantpt F
++ group_member F
++ gsignal F
++ gtty F
++ h_errlist D 0x28
++ h_nerr D 0x4
++ hasmntopt F
++ hcreate F
++ hcreate_r F
++ hdestroy F
++ hdestroy_r F
++ herror F
++ host2netname F
++ hsearch F
++ hsearch_r F
++ hstrerror F
++ htonl F
++ htons F
++ iconv F
++ iconv_close F
++ iconv_open F
++ if_freenameindex F
++ if_indextoname F
++ if_nameindex F
++ if_nametoindex F
++ imaxabs F
++ imaxdiv F
++ in6addr_any D 0x10
++ in6addr_loopback D 0x10
++ index F
++ inet6_opt_append F
++ inet6_opt_find F
++ inet6_opt_finish F
++ inet6_opt_get_val F
++ inet6_opt_init F
++ inet6_opt_next F
++ inet6_opt_set_val F
++ inet6_option_alloc F
++ inet6_option_append F
++ inet6_option_find F
++ inet6_option_init F
++ inet6_option_next F
++ inet6_option_space F
++ inet6_rth_add F
++ inet6_rth_getaddr F
++ inet6_rth_init F
++ inet6_rth_reverse F
++ inet6_rth_segments F
++ inet6_rth_space F
++ inet_addr F
++ inet_aton F
++ inet_lnaof F
++ inet_makeaddr F
++ inet_netof F
++ inet_network F
++ inet_nsap_addr F
++ inet_nsap_ntoa F
++ inet_ntoa F
++ inet_ntop F
++ inet_pton F
++ init_module F
++ initgroups F
++ initstate F
++ initstate_r F
++ innetgr F
++ inotify_add_watch F
++ inotify_init F
++ inotify_init1 F
++ inotify_rm_watch F
++ insque F
++ ioctl F
++ iruserok F
++ iruserok_af F
++ isalnum F
++ isalnum_l F
++ isalpha F
++ isalpha_l F
++ isascii F
++ isastream F
++ isatty F
++ isblank F
++ isblank_l F
++ iscntrl F
++ iscntrl_l F
++ isctype F
++ isdigit F
++ isdigit_l F
++ isfdtype F
++ isgraph F
++ isgraph_l F
++ isinf F
++ isinff F
++ isinfl F
++ islower F
++ islower_l F
++ isnan F
++ isnanf F
++ isnanl F
++ isprint F
++ isprint_l F
++ ispunct F
++ ispunct_l F
++ isspace F
++ isspace_l F
++ isupper F
++ isupper_l F
++ iswalnum F
++ iswalnum_l F
++ iswalpha F
++ iswalpha_l F
++ iswblank F
++ iswblank_l F
++ iswcntrl F
++ iswcntrl_l F
++ iswctype F
++ iswctype_l F
++ iswdigit F
++ iswdigit_l F
++ iswgraph F
++ iswgraph_l F
++ iswlower F
++ iswlower_l F
++ iswprint F
++ iswprint_l F
++ iswpunct F
++ iswpunct_l F
++ iswspace F
++ iswspace_l F
++ iswupper F
++ iswupper_l F
++ iswxdigit F
++ iswxdigit_l F
++ isxdigit F
++ isxdigit_l F
++ jrand48 F
++ jrand48_r F
++ key_decryptsession F
++ key_decryptsession_pk F
++ key_encryptsession F
++ key_encryptsession_pk F
++ key_gendes F
++ key_get_conv F
++ key_secretkey_is_set F
++ key_setnet F
++ key_setsecret F
++ kill F
++ killpg F
++ klogctl F
++ l64a F
++ labs F
++ lchmod F
++ lchown F
++ lckpwdf F
++ lcong48 F
++ lcong48_r F
++ ldexp F
++ ldexpf F
++ ldexpl F
++ ldiv F
++ lfind F
++ lgetxattr F
++ link F
++ linkat F
++ listen F
++ listxattr F
++ llabs F
++ lldiv F
++ llistxattr F
++ llseek F
++ loc1 D 0x8
++ loc2 D 0x8
++ localeconv F
++ localtime F
++ localtime_r F
++ lockf F
++ lockf64 F
++ locs D 0x8
++ longjmp F
++ lrand48 F
++ lrand48_r F
++ lremovexattr F
++ lsearch F
++ lseek F
++ lseek64 F
++ lsetxattr F
++ lutimes F
++ madvise F
++ makecontext F
++ mallinfo F
++ malloc F
++ malloc_get_state F
++ malloc_info F
++ malloc_set_state F
++ malloc_stats F
++ malloc_trim F
++ malloc_usable_size F
++ mallopt F
++ mallwatch D 0x8
++ mblen F
++ mbrlen F
++ mbrtoc16 F
++ mbrtoc32 F
++ mbrtowc F
++ mbsinit F
++ mbsnrtowcs F
++ mbsrtowcs F
++ mbstowcs F
++ mbtowc F
++ mcheck F
++ mcheck_check_all F
++ mcheck_pedantic F
++ memalign F
++ memccpy F
++ memchr F
++ memcmp F
++ memcpy F
++ memfrob F
++ memmem F
++ memmove F
++ mempcpy F
++ memrchr F
++ memset F
++ mincore F
++ mkdir F
++ mkdirat F
++ mkdtemp F
++ mkfifo F
++ mkfifoat F
++ mkostemp F
++ mkostemp64 F
++ mkostemps F
++ mkostemps64 F
++ mkstemp F
++ mkstemp64 F
++ mkstemps F
++ mkstemps64 F
++ mktemp F
++ mktime F
++ mlock F
++ mlockall F
++ mmap F
++ mmap64 F
++ modf F
++ modff F
++ modfl F
++ moncontrol F
++ monstartup F
++ mount F
++ mprobe F
++ mprotect F
++ mrand48 F
++ mrand48_r F
++ mremap F
++ msgctl F
++ msgget F
++ msgrcv F
++ msgsnd F
++ msync F
++ mtrace F
++ munlock F
++ munlockall F
++ munmap F
++ muntrace F
++ name_to_handle_at F
++ nanosleep F
++ netname2host F
++ netname2user F
++ newlocale F
++ nfsservctl F
++ nftw F
++ nftw64 F
++ ngettext F
++ nice F
++ nl_langinfo F
++ nl_langinfo_l F
++ nrand48 F
++ nrand48_r F
++ ntohl F
++ ntohs F
++ ntp_adjtime F
++ ntp_gettime F
++ ntp_gettimex F
++ obstack_alloc_failed_handler D 0x8
++ obstack_exit_failure D 0x4
++ obstack_free F
++ obstack_printf F
++ obstack_vprintf F
++ on_exit F
++ open F
++ open64 F
++ open_by_handle_at F
++ open_memstream F
++ open_wmemstream F
++ openat F
++ openat64 F
++ opendir F
++ openlog F
++ optarg D 0x8
++ opterr D 0x4
++ optind D 0x4
++ optopt D 0x4
++ parse_printf_format F
++ passwd2des F
++ pathconf F
++ pause F
++ pclose F
++ perror F
++ personality F
++ pipe F
++ pipe2 F
++ pivot_root F
++ pmap_getmaps F
++ pmap_getport F
++ pmap_rmtcall F
++ pmap_set F
++ pmap_unset F
++ poll F
++ popen F
++ posix_fadvise F
++ posix_fadvise64 F
++ posix_fallocate F
++ posix_fallocate64 F
++ posix_madvise F
++ posix_memalign F
++ posix_openpt F
++ posix_spawn F
++ posix_spawn_file_actions_addclose F
++ posix_spawn_file_actions_adddup2 F
++ posix_spawn_file_actions_addopen F
++ posix_spawn_file_actions_destroy F
++ posix_spawn_file_actions_init F
++ posix_spawnattr_destroy F
++ posix_spawnattr_getflags F
++ posix_spawnattr_getpgroup F
++ posix_spawnattr_getschedparam F
++ posix_spawnattr_getschedpolicy F
++ posix_spawnattr_getsigdefault F
++ posix_spawnattr_getsigmask F
++ posix_spawnattr_init F
++ posix_spawnattr_setflags F
++ posix_spawnattr_setpgroup F
++ posix_spawnattr_setschedparam F
++ posix_spawnattr_setschedpolicy F
++ posix_spawnattr_setsigdefault F
++ posix_spawnattr_setsigmask F
++ posix_spawnp F
++ ppoll F
++ prctl F
++ pread F
++ pread64 F
++ preadv F
++ preadv64 F
++ printf F
++ printf_size F
++ printf_size_info F
++ prlimit F
++ prlimit64 F
++ process_vm_readv F
++ process_vm_writev F
++ profil F
++ program_invocation_name D 0x8
++ program_invocation_short_name D 0x8
++ pselect F
++ psiginfo F
++ psignal F
++ pthread_attr_destroy F
++ pthread_attr_getdetachstate F
++ pthread_attr_getinheritsched F
++ pthread_attr_getschedparam F
++ pthread_attr_getschedpolicy F
++ pthread_attr_getscope F
++ pthread_attr_init F
++ pthread_attr_setdetachstate F
++ pthread_attr_setinheritsched F
++ pthread_attr_setschedparam F
++ pthread_attr_setschedpolicy F
++ pthread_attr_setscope F
++ pthread_cond_broadcast F
++ pthread_cond_destroy F
++ pthread_cond_init F
++ pthread_cond_signal F
++ pthread_cond_timedwait F
++ pthread_cond_wait F
++ pthread_condattr_destroy F
++ pthread_condattr_init F
++ pthread_equal F
++ pthread_exit F
++ pthread_getschedparam F
++ pthread_mutex_destroy F
++ pthread_mutex_init F
++ pthread_mutex_lock F
++ pthread_mutex_unlock F
++ pthread_self F
++ pthread_setcancelstate F
++ pthread_setcanceltype F
++ pthread_setschedparam F
++ ptrace F
++ ptsname F
++ ptsname_r F
++ putc F
++ putc_unlocked F
++ putchar F
++ putchar_unlocked F
++ putenv F
++ putgrent F
++ putmsg F
++ putpmsg F
++ putpwent F
++ puts F
++ putsgent F
++ putspent F
++ pututline F
++ pututxline F
++ putw F
++ putwc F
++ putwc_unlocked F
++ putwchar F
++ putwchar_unlocked F
++ pvalloc F
++ pwrite F
++ pwrite64 F
++ pwritev F
++ pwritev64 F
++ qecvt F
++ qecvt_r F
++ qfcvt F
++ qfcvt_r F
++ qgcvt F
++ qsort F
++ qsort_r F
++ query_module F
++ quick_exit F
++ quotactl F
++ raise F
++ rand F
++ rand_r F
++ random F
++ random_r F
++ rawmemchr F
++ rcmd F
++ rcmd_af F
++ re_comp F
++ re_compile_fastmap F
++ re_compile_pattern F
++ re_exec F
++ re_match F
++ re_match_2 F
++ re_search F
++ re_search_2 F
++ re_set_registers F
++ re_set_syntax F
++ re_syntax_options D 0x8
++ read F
++ readahead F
++ readdir F
++ readdir64 F
++ readdir64_r F
++ readdir_r F
++ readlink F
++ readlinkat F
++ readv F
++ realloc F
++ realpath F
++ reboot F
++ recv F
++ recvfrom F
++ recvmmsg F
++ recvmsg F
++ regcomp F
++ regerror F
++ regexec F
++ regfree F
++ register_printf_function F
++ register_printf_modifier F
++ register_printf_specifier F
++ register_printf_type F
++ registerrpc F
++ remap_file_pages F
++ remove F
++ removexattr F
++ remque F
++ rename F
++ renameat F
++ revoke F
++ rewind F
++ rewinddir F
++ rexec F
++ rexec_af F
++ rexecoptions D 0x4
++ rindex F
++ rmdir F
++ rpc_createerr D 0x20
++ rpmatch F
++ rresvport F
++ rresvport_af F
++ rtime F
++ ruserok F
++ ruserok_af F
++ ruserpass F
++ sbrk F
++ scalbn F
++ scalbnf F
++ scalbnl F
++ scandir F
++ scandir64 F
++ scandirat F
++ scandirat64 F
++ scanf F
++ sched_get_priority_max F
++ sched_get_priority_min F
++ sched_getaffinity F
++ sched_getcpu F
++ sched_getparam F
++ sched_getscheduler F
++ sched_rr_get_interval F
++ sched_setaffinity F
++ sched_setparam F
++ sched_setscheduler F
++ sched_yield F
++ secure_getenv F
++ seed48 F
++ seed48_r F
++ seekdir F
++ select F
++ semctl F
++ semget F
++ semop F
++ semtimedop F
++ send F
++ sendfile F
++ sendfile64 F
++ sendmmsg F
++ sendmsg F
++ sendto F
++ setaliasent F
++ setbuf F
++ setbuffer F
++ setcontext F
++ setdomainname F
++ setegid F
++ setenv F
++ seteuid F
++ setfsent F
++ setfsgid F
++ setfsuid F
++ setgid F
++ setgrent F
++ setgroups F
++ sethostent F
++ sethostid F
++ sethostname F
++ setipv4sourcefilter F
++ setitimer F
++ setjmp F
++ setlinebuf F
++ setlocale F
++ setlogin F
++ setlogmask F
++ setmntent F
++ setnetent F
++ setnetgrent F
++ setns F
++ setpgid F
++ setpgrp F
++ setpriority F
++ setprotoent F
++ setpwent F
++ setregid F
++ setresgid F
++ setresuid F
++ setreuid F
++ setrlimit F
++ setrlimit64 F
++ setrpcent F
++ setservent F
++ setsgent F
++ setsid F
++ setsockopt F
++ setsourcefilter F
++ setspent F
++ setstate F
++ setstate_r F
++ settimeofday F
++ setttyent F
++ setuid F
++ setusershell F
++ setutent F
++ setutxent F
++ setvbuf F
++ setxattr F
++ sgetsgent F
++ sgetsgent_r F
++ sgetspent F
++ sgetspent_r F
++ shmat F
++ shmctl F
++ shmdt F
++ shmget F
++ shutdown F
++ sigaction F
++ sigaddset F
++ sigaltstack F
++ sigandset F
++ sigblock F
++ sigdelset F
++ sigemptyset F
++ sigfillset F
++ siggetmask F
++ sighold F
++ sigignore F
++ siginterrupt F
++ sigisemptyset F
++ sigismember F
++ siglongjmp F
++ signal F
++ signalfd F
++ sigorset F
++ sigpause F
++ sigpending F
++ sigprocmask F
++ sigqueue F
++ sigrelse F
++ sigreturn F
++ sigset F
++ sigsetmask F
++ sigstack F
++ sigsuspend F
++ sigtimedwait F
++ sigvec F
++ sigwait F
++ sigwaitinfo F
++ sleep F
++ snprintf F
++ sockatmark F
++ socket F
++ socketpair F
++ splice F
++ sprintf F
++ sprofil F
++ srand F
++ srand48 F
++ srand48_r F
++ srandom F
++ srandom_r F
++ sscanf F
++ ssignal F
++ sstk F
++ statfs F
++ statfs64 F
++ statvfs F
++ statvfs64 F
++ stderr D 0x8
++ stdin D 0x8
++ stdout D 0x8
++ step F
++ stime F
++ stpcpy F
++ stpncpy F
++ strcasecmp F
++ strcasecmp_l F
++ strcasestr F
++ strcat F
++ strchr F
++ strchrnul F
++ strcmp F
++ strcoll F
++ strcoll_l F
++ strcpy F
++ strcspn F
++ strdup F
++ strerror F
++ strerror_l F
++ strerror_r F
++ strfmon F
++ strfmon_l F
++ strfry F
++ strftime F
++ strftime_l F
++ strlen F
++ strncasecmp F
++ strncasecmp_l F
++ strncat F
++ strncmp F
++ strncpy F
++ strndup F
++ strnlen F
++ strpbrk F
++ strptime F
++ strptime_l F
++ strrchr F
++ strsep F
++ strsignal F
++ strspn F
++ strstr F
++ strtod F
++ strtod_l F
++ strtof F
++ strtof_l F
++ strtoimax F
++ strtok F
++ strtok_r F
++ strtol F
++ strtol_l F
++ strtold F
++ strtold_l F
++ strtoll F
++ strtoll_l F
++ strtoq F
++ strtoul F
++ strtoul_l F
++ strtoull F
++ strtoull_l F
++ strtoumax F
++ strtouq F
++ strverscmp F
++ strxfrm F
++ strxfrm_l F
++ stty F
++ svc_exit F
++ svc_fdset D 0x80
++ svc_getreq F
++ svc_getreq_common F
++ svc_getreq_poll F
++ svc_getreqset F
++ svc_max_pollfd D 0x4
++ svc_pollfd D 0x8
++ svc_register F
++ svc_run F
++ svc_sendreply F
++ svc_unregister F
++ svcauthdes_stats D 0x18
++ svcerr_auth F
++ svcerr_decode F
++ svcerr_noproc F
++ svcerr_noprog F
++ svcerr_progvers F
++ svcerr_systemerr F
++ svcerr_weakauth F
++ svcfd_create F
++ svcraw_create F
++ svctcp_create F
++ svcudp_bufcreate F
++ svcudp_create F
++ svcudp_enablecache F
++ svcunix_create F
++ svcunixfd_create F
++ swab F
++ swapcontext F
++ swapoff F
++ swapon F
++ swprintf F
++ swscanf F
++ symlink F
++ symlinkat F
++ sync F
++ sync_file_range F
++ syncfs F
++ sys_errlist D 0x438
++ sys_nerr D 0x4
++ sys_sigabbrev D 0x208
++ sys_siglist D 0x208
++ syscall F
++ sysconf F
++ sysctl F
++ sysinfo F
++ syslog F
++ system F
++ sysv_signal F
++ tcdrain F
++ tcflow F
++ tcflush F
++ tcgetattr F
++ tcgetpgrp F
++ tcgetsid F
++ tcsendbreak F
++ tcsetattr F
++ tcsetpgrp F
++ tdelete F
++ tdestroy F
++ tee F
++ telldir F
++ tempnam F
++ textdomain F
++ tfind F
++ time F
++ timegm F
++ timelocal F
++ timerfd_create F
++ timerfd_gettime F
++ timerfd_settime F
++ times F
++ timespec_get F
++ timezone D 0x8
++ tmpfile F
++ tmpfile64 F
++ tmpnam F
++ tmpnam_r F
++ toascii F
++ tolower F
++ tolower_l F
++ toupper F
++ toupper_l F
++ towctrans F
++ towctrans_l F
++ towlower F
++ towlower_l F
++ towupper F
++ towupper_l F
++ tr_break F
++ truncate F
++ truncate64 F
++ tsearch F
++ ttyname F
++ ttyname_r F
++ ttyslot F
++ twalk F
++ tzname D 0x10
++ tzset F
++ ualarm F
++ ulckpwdf F
++ ulimit F
++ umask F
++ umount F
++ umount2 F
++ uname F
++ ungetc F
++ ungetwc F
++ unlink F
++ unlinkat F
++ unlockpt F
++ unsetenv F
++ unshare F
++ updwtmp F
++ updwtmpx F
++ uselib F
++ uselocale F
++ user2netname F
++ usleep F
++ ustat F
++ utime F
++ utimensat F
++ utimes F
++ utmpname F
++ utmpxname F
++ valloc F
++ vasprintf F
++ vdprintf F
++ verr F
++ verrx F
++ versionsort F
++ versionsort64 F
++ vfork F
++ vfprintf F
++ vfscanf F
++ vfwprintf F
++ vfwscanf F
++ vhangup F
++ vlimit F
++ vmsplice F
++ vprintf F
++ vscanf F
++ vsnprintf F
++ vsprintf F
++ vsscanf F
++ vswprintf F
++ vswscanf F
++ vsyslog F
++ vtimes F
++ vwarn F
++ vwarnx F
++ vwprintf F
++ vwscanf F
++ wait F
++ wait3 F
++ wait4 F
++ waitid F
++ waitpid F
++ warn F
++ warnx F
++ wcpcpy F
++ wcpncpy F
++ wcrtomb F
++ wcscasecmp F
++ wcscasecmp_l F
++ wcscat F
++ wcschr F
++ wcschrnul F
++ wcscmp F
++ wcscoll F
++ wcscoll_l F
++ wcscpy F
++ wcscspn F
++ wcsdup F
++ wcsftime F
++ wcsftime_l F
++ wcslen F
++ wcsncasecmp F
++ wcsncasecmp_l F
++ wcsncat F
++ wcsncmp F
++ wcsncpy F
++ wcsnlen F
++ wcsnrtombs F
++ wcspbrk F
++ wcsrchr F
++ wcsrtombs F
++ wcsspn F
++ wcsstr F
++ wcstod F
++ wcstod_l F
++ wcstof F
++ wcstof_l F
++ wcstoimax F
++ wcstok F
++ wcstol F
++ wcstol_l F
++ wcstold F
++ wcstold_l F
++ wcstoll F
++ wcstoll_l F
++ wcstombs F
++ wcstoq F
++ wcstoul F
++ wcstoul_l F
++ wcstoull F
++ wcstoull_l F
++ wcstoumax F
++ wcstouq F
++ wcswcs F
++ wcswidth F
++ wcsxfrm F
++ wcsxfrm_l F
++ wctob F
++ wctomb F
++ wctrans F
++ wctrans_l F
++ wctype F
++ wctype_l F
++ wcwidth F
++ wmemchr F
++ wmemcmp F
++ wmemcpy F
++ wmemmove F
++ wmempcpy F
++ wmemset F
++ wordexp F
++ wordfree F
++ wprintf F
++ write F
++ writev F
++ wscanf F
++ xdecrypt F
++ xdr_accepted_reply F
++ xdr_array F
++ xdr_authdes_cred F
++ xdr_authdes_verf F
++ xdr_authunix_parms F
++ xdr_bool F
++ xdr_bytes F
++ xdr_callhdr F
++ xdr_callmsg F
++ xdr_char F
++ xdr_cryptkeyarg F
++ xdr_cryptkeyarg2 F
++ xdr_cryptkeyres F
++ xdr_des_block F
++ xdr_double F
++ xdr_enum F
++ xdr_float F
++ xdr_free F
++ xdr_getcredres F
++ xdr_hyper F
++ xdr_int F
++ xdr_int16_t F
++ xdr_int32_t F
++ xdr_int64_t F
++ xdr_int8_t F
++ xdr_key_netstarg F
++ xdr_key_netstres F
++ xdr_keybuf F
++ xdr_keystatus F
++ xdr_long F
++ xdr_longlong_t F
++ xdr_netnamestr F
++ xdr_netobj F
++ xdr_opaque F
++ xdr_opaque_auth F
++ xdr_pmap F
++ xdr_pmaplist F
++ xdr_pointer F
++ xdr_quad_t F
++ xdr_reference F
++ xdr_rejected_reply F
++ xdr_replymsg F
++ xdr_rmtcall_args F
++ xdr_rmtcallres F
++ xdr_short F
++ xdr_sizeof F
++ xdr_string F
++ xdr_u_char F
++ xdr_u_hyper F
++ xdr_u_int F
++ xdr_u_long F
++ xdr_u_longlong_t F
++ xdr_u_quad_t F
++ xdr_u_short F
++ xdr_uint16_t F
++ xdr_uint32_t F
++ xdr_uint64_t F
++ xdr_uint8_t F
++ xdr_union F
++ xdr_unixcred F
++ xdr_vector F
++ xdr_void F
++ xdr_wrapstring F
++ xdrmem_create F
++ xdrrec_create F
++ xdrrec_endofrecord F
++ xdrrec_eof F
++ xdrrec_skiprecord F
++ xdrstdio_create F
++ xencrypt F
++ xprt_register F
++ xprt_unregister F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libcrypt-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libcrypt-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libcrypt-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libcrypt-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,9 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ crypt F
++ crypt_r F
++ encrypt F
++ encrypt_r F
++ fcrypt F
++ setkey F
++ setkey_r F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libdl-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libdl-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libdl-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libdl-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,11 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ dladdr F
++ dladdr1 F
++ dlclose F
++ dlerror F
++ dlinfo F
++ dlmopen F
++ dlopen F
++ dlsym F
++ dlvsym F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,402 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ _LIB_VERSION D 0x4
++ __acos_finite F
++ __acosf_finite F
++ __acosh_finite F
++ __acoshf_finite F
++ __acoshl_finite F
++ __acosl_finite F
++ __asin_finite F
++ __asinf_finite F
++ __asinl_finite F
++ __atan2_finite F
++ __atan2f_finite F
++ __atan2l_finite F
++ __atanh_finite F
++ __atanhf_finite F
++ __atanhl_finite F
++ __clog10 F
++ __clog10f F
++ __clog10l F
++ __cosh_finite F
++ __coshf_finite F
++ __coshl_finite F
++ __exp10_finite F
++ __exp10f_finite F
++ __exp10l_finite F
++ __exp2_finite F
++ __exp2f_finite F
++ __exp2l_finite F
++ __exp_finite F
++ __expf_finite F
++ __expl_finite F
++ __fe_dfl_env D 0x8
++ __fe_enabled_env D 0x8
++ __fe_nomask_env F
++ __fe_nonieee_env D 0x8
++ __finite F
++ __finitef F
++ __finitel F
++ __fmod_finite F
++ __fmodf_finite F
++ __fmodl_finite F
++ __fpclassify F
++ __fpclassifyf F
++ __fpclassifyl F
++ __gamma_r_finite F
++ __gammaf_r_finite F
++ __gammal_r_finite F
++ __hypot_finite F
++ __hypotf_finite F
++ __hypotl_finite F
++ __j0_finite F
++ __j0f_finite F
++ __j0l_finite F
++ __j1_finite F
++ __j1f_finite F
++ __j1l_finite F
++ __jn_finite F
++ __jnf_finite F
++ __jnl_finite F
++ __lgamma_r_finite F
++ __lgammaf_r_finite F
++ __lgammal_r_finite F
++ __log10_finite F
++ __log10f_finite F
++ __log10l_finite F
++ __log2_finite F
++ __log2f_finite F
++ __log2l_finite F
++ __log_finite F
++ __logf_finite F
++ __logl_finite F
++ __nldbl_nexttowardf F
++ __pow_finite F
++ __powf_finite F
++ __powl_finite F
++ __remainder_finite F
++ __remainderf_finite F
++ __remainderl_finite F
++ __scalb_finite F
++ __scalbf_finite F
++ __scalbl_finite F
++ __signbit F
++ __signbitf F
++ __signbitl F
++ __sinh_finite F
++ __sinhf_finite F
++ __sinhl_finite F
++ __sqrt_finite F
++ __sqrtf_finite F
++ __sqrtl_finite F
++ __y0_finite F
++ __y0f_finite F
++ __y0l_finite F
++ __y1_finite F
++ __y1f_finite F
++ __y1l_finite F
++ __yn_finite F
++ __ynf_finite F
++ __ynl_finite F
++ acos F
++ acosf F
++ acosh F
++ acoshf F
++ acoshl F
++ acosl F
++ asin F
++ asinf F
++ asinh F
++ asinhf F
++ asinhl F
++ asinl F
++ atan F
++ atan2 F
++ atan2f F
++ atan2l F
++ atanf F
++ atanh F
++ atanhf F
++ atanhl F
++ atanl F
++ cabs F
++ cabsf F
++ cabsl F
++ cacos F
++ cacosf F
++ cacosh F
++ cacoshf F
++ cacoshl F
++ cacosl F
++ carg F
++ cargf F
++ cargl F
++ casin F
++ casinf F
++ casinh F
++ casinhf F
++ casinhl F
++ casinl F
++ catan F
++ catanf F
++ catanh F
++ catanhf F
++ catanhl F
++ catanl F
++ cbrt F
++ cbrtf F
++ cbrtl F
++ ccos F
++ ccosf F
++ ccosh F
++ ccoshf F
++ ccoshl F
++ ccosl F
++ ceil F
++ ceilf F
++ ceill F
++ cexp F
++ cexpf F
++ cexpl F
++ cimag F
++ cimagf F
++ cimagl F
++ clog F
++ clog10 F
++ clog10f F
++ clog10l F
++ clogf F
++ clogl F
++ conj F
++ conjf F
++ conjl F
++ copysign F
++ copysignf F
++ copysignl F
++ cos F
++ cosf F
++ cosh F
++ coshf F
++ coshl F
++ cosl F
++ cpow F
++ cpowf F
++ cpowl F
++ cproj F
++ cprojf F
++ cprojl F
++ creal F
++ crealf F
++ creall F
++ csin F
++ csinf F
++ csinh F
++ csinhf F
++ csinhl F
++ csinl F
++ csqrt F
++ csqrtf F
++ csqrtl F
++ ctan F
++ ctanf F
++ ctanh F
++ ctanhf F
++ ctanhl F
++ ctanl F
++ drem F
++ dremf F
++ dreml F
++ erf F
++ erfc F
++ erfcf F
++ erfcl F
++ erff F
++ erfl F
++ exp F
++ exp10 F
++ exp10f F
++ exp10l F
++ exp2 F
++ exp2f F
++ exp2l F
++ expf F
++ expl F
++ expm1 F
++ expm1f F
++ expm1l F
++ fabs F
++ fabsf F
++ fabsl F
++ fdim F
++ fdimf F
++ fdiml F
++ feclearexcept F
++ fedisableexcept F
++ feenableexcept F
++ fegetenv F
++ fegetexcept F
++ fegetexceptflag F
++ fegetround F
++ feholdexcept F
++ feraiseexcept F
++ fesetenv F
++ fesetexceptflag F
++ fesetround F
++ fetestexcept F
++ feupdateenv F
++ finite F
++ finitef F
++ finitel F
++ floor F
++ floorf F
++ floorl F
++ fma F
++ fmaf F
++ fmal F
++ fmax F
++ fmaxf F
++ fmaxl F
++ fmin F
++ fminf F
++ fminl F
++ fmod F
++ fmodf F
++ fmodl F
++ frexp F
++ frexpf F
++ frexpl F
++ gamma F
++ gammaf F
++ gammal F
++ hypot F
++ hypotf F
++ hypotl F
++ ilogb F
++ ilogbf F
++ ilogbl F
++ j0 F
++ j0f F
++ j0l F
++ j1 F
++ j1f F
++ j1l F
++ jn F
++ jnf F
++ jnl F
++ ldexp F
++ ldexpf F
++ ldexpl F
++ lgamma F
++ lgamma_r F
++ lgammaf F
++ lgammaf_r F
++ lgammal F
++ lgammal_r F
++ llrint F
++ llrintf F
++ llrintl F
++ llround F
++ llroundf F
++ llroundl F
++ log F
++ log10 F
++ log10f F
++ log10l F
++ log1p F
++ log1pf F
++ log1pl F
++ log2 F
++ log2f F
++ log2l F
++ logb F
++ logbf F
++ logbl F
++ logf F
++ logl F
++ lrint F
++ lrintf F
++ lrintl F
++ lround F
++ lroundf F
++ lroundl F
++ matherr F
++ modf F
++ modff F
++ modfl F
++ nan F
++ nanf F
++ nanl F
++ nearbyint F
++ nearbyintf F
++ nearbyintl F
++ nextafter F
++ nextafterf F
++ nextafterl F
++ nexttoward F
++ nexttowardf F
++ nexttowardl F
++ pow F
++ pow10 F
++ pow10f F
++ pow10l F
++ powf F
++ powl F
++ remainder F
++ remainderf F
++ remainderl F
++ remquo F
++ remquof F
++ remquol F
++ rint F
++ rintf F
++ rintl F
++ round F
++ roundf F
++ roundl F
++ scalb F
++ scalbf F
++ scalbl F
++ scalbln F
++ scalblnf F
++ scalblnl F
++ scalbn F
++ scalbnf F
++ scalbnl F
++ signgam D 0x4
++ significand F
++ significandf F
++ significandl F
++ sin F
++ sincos F
++ sincosf F
++ sincosl F
++ sinf F
++ sinh F
++ sinhf F
++ sinhl F
++ sinl F
++ sqrt F
++ sqrtf F
++ sqrtl F
++ tan F
++ tanf F
++ tanh F
++ tanhf F
++ tanhl F
++ tanl F
++ tgamma F
++ tgammaf F
++ tgammal F
++ trunc F
++ truncf F
++ truncl F
++ y0 F
++ y0f F
++ y0l F
++ y1 F
++ y1f F
++ y1l F
++ yn F
++ ynf F
++ ynl F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libnsl-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libnsl-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libnsl-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libnsl-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,123 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ __free_fdresult F
++ __nis_default_access F
++ __nis_default_group F
++ __nis_default_owner F
++ __nis_default_ttl F
++ __nis_finddirectory F
++ __nis_hash F
++ __nisbind_connect F
++ __nisbind_create F
++ __nisbind_destroy F
++ __nisbind_next F
++ __yp_check F
++ nis_add F
++ nis_add_entry F
++ nis_addmember F
++ nis_checkpoint F
++ nis_clone_directory F
++ nis_clone_object F
++ nis_clone_result F
++ nis_creategroup F
++ nis_destroy_object F
++ nis_destroygroup F
++ nis_dir_cmp F
++ nis_domain_of F
++ nis_domain_of_r F
++ nis_first_entry F
++ nis_free_directory F
++ nis_free_object F
++ nis_free_request F
++ nis_freenames F
++ nis_freeresult F
++ nis_freeservlist F
++ nis_freetags F
++ nis_getnames F
++ nis_getservlist F
++ nis_ismember F
++ nis_leaf_of F
++ nis_leaf_of_r F
++ nis_lerror F
++ nis_list F
++ nis_local_directory F
++ nis_local_group F
++ nis_local_host F
++ nis_local_principal F
++ nis_lookup F
++ nis_mkdir F
++ nis_modify F
++ nis_modify_entry F
++ nis_name_of F
++ nis_name_of_r F
++ nis_next_entry F
++ nis_perror F
++ nis_ping F
++ nis_print_directory F
++ nis_print_entry F
++ nis_print_group F
++ nis_print_group_entry F
++ nis_print_link F
++ nis_print_object F
++ nis_print_result F
++ nis_print_rights F
++ nis_print_table F
++ nis_read_obj F
++ nis_remove F
++ nis_remove_entry F
++ nis_removemember F
++ nis_rmdir F
++ nis_servstate F
++ nis_sperrno F
++ nis_sperror F
++ nis_sperror_r F
++ nis_stats F
++ nis_verifygroup F
++ nis_write_obj F
++ readColdStartFile F
++ writeColdStartFile F
++ xdr_cback_data F
++ xdr_domainname F
++ xdr_keydat F
++ xdr_mapname F
++ xdr_obj_p F
++ xdr_peername F
++ xdr_valdat F
++ xdr_yp_buf F
++ xdr_ypall F
++ xdr_ypbind_binding F
++ xdr_ypbind_resp F
++ xdr_ypbind_resptype F
++ xdr_ypbind_setdom F
++ xdr_ypdelete_args F
++ xdr_ypmap_parms F
++ xdr_ypmaplist F
++ xdr_yppush_status F
++ xdr_yppushresp_xfr F
++ xdr_ypreq_key F
++ xdr_ypreq_nokey F
++ xdr_ypreq_xfr F
++ xdr_ypresp_all F
++ xdr_ypresp_key_val F
++ xdr_ypresp_maplist F
++ xdr_ypresp_master F
++ xdr_ypresp_order F
++ xdr_ypresp_val F
++ xdr_ypresp_xfr F
++ xdr_ypstat F
++ xdr_ypupdate_args F
++ xdr_ypxfrstat F
++ yp_all F
++ yp_bind F
++ yp_first F
++ yp_get_default_domain F
++ yp_maplist F
++ yp_master F
++ yp_match F
++ yp_next F
++ yp_order F
++ yp_unbind F
++ yp_update F
++ ypbinderr_string F
++ yperr_string F
++ ypprot_err F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libpthread-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libpthread-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libpthread-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libpthread-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,224 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ _IO_flockfile F
++ _IO_ftrylockfile F
++ _IO_funlockfile F
++ __close F
++ __connect F
++ __errno_location F
++ __fcntl F
++ __fork F
++ __h_errno_location F
++ __libc_allocate_rtsig F
++ __libc_current_sigrtmax F
++ __libc_current_sigrtmin F
++ __lseek F
++ __nanosleep F
++ __open F
++ __open64 F
++ __pread64 F
++ __pthread_cleanup_routine F
++ __pthread_getspecific F
++ __pthread_key_create F
++ __pthread_mutex_destroy F
++ __pthread_mutex_init F
++ __pthread_mutex_lock F
++ __pthread_mutex_trylock F
++ __pthread_mutex_unlock F
++ __pthread_mutexattr_destroy F
++ __pthread_mutexattr_init F
++ __pthread_mutexattr_settype F
++ __pthread_once F
++ __pthread_register_cancel F
++ __pthread_register_cancel_defer F
++ __pthread_rwlock_destroy F
++ __pthread_rwlock_init F
++ __pthread_rwlock_rdlock F
++ __pthread_rwlock_tryrdlock F
++ __pthread_rwlock_trywrlock F
++ __pthread_rwlock_unlock F
++ __pthread_rwlock_wrlock F
++ __pthread_setspecific F
++ __pthread_unregister_cancel F
++ __pthread_unregister_cancel_restore F
++ __pthread_unwind_next F
++ __pwrite64 F
++ __read F
++ __res_state F
++ __send F
++ __sigaction F
++ __vfork F
++ __wait F
++ __write F
++ _pthread_cleanup_pop F
++ _pthread_cleanup_pop_restore F
++ _pthread_cleanup_push F
++ _pthread_cleanup_push_defer F
++ accept F
++ close F
++ connect F
++ fcntl F
++ flockfile F
++ fork F
++ fsync F
++ ftrylockfile F
++ funlockfile F
++ longjmp F
++ lseek F
++ lseek64 F
++ msync F
++ nanosleep F
++ open F
++ open64 F
++ pause F
++ pread F
++ pread64 F
++ pthread_attr_destroy F
++ pthread_attr_getaffinity_np F
++ pthread_attr_getdetachstate F
++ pthread_attr_getguardsize F
++ pthread_attr_getinheritsched F
++ pthread_attr_getschedparam F
++ pthread_attr_getschedpolicy F
++ pthread_attr_getscope F
++ pthread_attr_getstack F
++ pthread_attr_getstackaddr F
++ pthread_attr_getstacksize F
++ pthread_attr_init F
++ pthread_attr_setaffinity_np F
++ pthread_attr_setdetachstate F
++ pthread_attr_setguardsize F
++ pthread_attr_setinheritsched F
++ pthread_attr_setschedparam F
++ pthread_attr_setschedpolicy F
++ pthread_attr_setscope F
++ pthread_attr_setstack F
++ pthread_attr_setstackaddr F
++ pthread_attr_setstacksize F
++ pthread_barrier_destroy F
++ pthread_barrier_init F
++ pthread_barrier_wait F
++ pthread_barrierattr_destroy F
++ pthread_barrierattr_getpshared F
++ pthread_barrierattr_init F
++ pthread_barrierattr_setpshared F
++ pthread_cancel F
++ pthread_cond_broadcast F
++ pthread_cond_destroy F
++ pthread_cond_init F
++ pthread_cond_signal F
++ pthread_cond_timedwait F
++ pthread_cond_wait F
++ pthread_condattr_destroy F
++ pthread_condattr_getclock F
++ pthread_condattr_getpshared F
++ pthread_condattr_init F
++ pthread_condattr_setclock F
++ pthread_condattr_setpshared F
++ pthread_create F
++ pthread_detach F
++ pthread_equal F
++ pthread_exit F
++ pthread_getaffinity_np F
++ pthread_getattr_np F
++ pthread_getconcurrency F
++ pthread_getcpuclockid F
++ pthread_getname_np F
++ pthread_getschedparam F
++ pthread_getspecific F
++ pthread_join F
++ pthread_key_create F
++ pthread_key_delete F
++ pthread_kill F
++ pthread_kill_other_threads_np F
++ pthread_mutex_consistent F
++ pthread_mutex_consistent_np F
++ pthread_mutex_destroy F
++ pthread_mutex_getprioceiling F
++ pthread_mutex_init F
++ pthread_mutex_lock F
++ pthread_mutex_setprioceiling F
++ pthread_mutex_timedlock F
++ pthread_mutex_trylock F
++ pthread_mutex_unlock F
++ pthread_mutexattr_destroy F
++ pthread_mutexattr_getkind_np F
++ pthread_mutexattr_getprioceiling F
++ pthread_mutexattr_getprotocol F
++ pthread_mutexattr_getpshared F
++ pthread_mutexattr_getrobust F
++ pthread_mutexattr_getrobust_np F
++ pthread_mutexattr_gettype F
++ pthread_mutexattr_init F
++ pthread_mutexattr_setkind_np F
++ pthread_mutexattr_setprioceiling F
++ pthread_mutexattr_setprotocol F
++ pthread_mutexattr_setpshared F
++ pthread_mutexattr_setrobust F
++ pthread_mutexattr_setrobust_np F
++ pthread_mutexattr_settype F
++ pthread_once F
++ pthread_rwlock_destroy F
++ pthread_rwlock_init F
++ pthread_rwlock_rdlock F
++ pthread_rwlock_timedrdlock F
++ pthread_rwlock_timedwrlock F
++ pthread_rwlock_tryrdlock F
++ pthread_rwlock_trywrlock F
++ pthread_rwlock_unlock F
++ pthread_rwlock_wrlock F
++ pthread_rwlockattr_destroy F
++ pthread_rwlockattr_getkind_np F
++ pthread_rwlockattr_getpshared F
++ pthread_rwlockattr_init F
++ pthread_rwlockattr_setkind_np F
++ pthread_rwlockattr_setpshared F
++ pthread_self F
++ pthread_setaffinity_np F
++ pthread_setcancelstate F
++ pthread_setcanceltype F
++ pthread_setconcurrency F
++ pthread_setname_np F
++ pthread_setschedparam F
++ pthread_setschedprio F
++ pthread_setspecific F
++ pthread_sigmask F
++ pthread_sigqueue F
++ pthread_spin_destroy F
++ pthread_spin_init F
++ pthread_spin_lock F
++ pthread_spin_trylock F
++ pthread_spin_unlock F
++ pthread_testcancel F
++ pthread_timedjoin_np F
++ pthread_tryjoin_np F
++ pthread_yield F
++ pwrite F
++ pwrite64 F
++ raise F
++ read F
++ recv F
++ recvfrom F
++ recvmsg F
++ sem_close F
++ sem_destroy F
++ sem_getvalue F
++ sem_init F
++ sem_open F
++ sem_post F
++ sem_timedwait F
++ sem_trywait F
++ sem_unlink F
++ sem_wait F
++ send F
++ sendmsg F
++ sendto F
++ sigaction F
++ siglongjmp F
++ sigwait F
++ system F
++ tcdrain F
++ vfork F
++ wait F
++ waitpid F
++ write F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libresolv-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libresolv-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libresolv-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libresolv-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,93 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ __b64_ntop F
++ __b64_pton F
++ __dn_comp F
++ __dn_count_labels F
++ __dn_expand F
++ __dn_skipname F
++ __fp_nquery F
++ __fp_query F
++ __fp_resstat F
++ __hostalias F
++ __loc_aton F
++ __loc_ntoa F
++ __p_cdname F
++ __p_cdnname F
++ __p_class F
++ __p_class_syms D 0xa8
++ __p_fqname F
++ __p_fqnname F
++ __p_option F
++ __p_query F
++ __p_rcode F
++ __p_secstodate F
++ __p_time F
++ __p_type F
++ __p_type_syms D 0x450
++ __putlong F
++ __putshort F
++ __res_close F
++ __res_dnok F
++ __res_hnok F
++ __res_hostalias F
++ __res_isourserver F
++ __res_mailok F
++ __res_mkquery F
++ __res_nameinquery F
++ __res_nmkquery F
++ __res_nquery F
++ __res_nquerydomain F
++ __res_nsearch F
++ __res_nsend F
++ __res_ownok F
++ __res_queriesmatch F
++ __res_query F
++ __res_querydomain F
++ __res_search F
++ __res_send F
++ __sym_ntop F
++ __sym_ntos F
++ __sym_ston F
++ _gethtbyaddr F
++ _gethtbyname F
++ _gethtbyname2 F
++ _gethtent F
++ _getlong F
++ _getshort F
++ _res_opcodes D 0x80
++ _sethtent F
++ inet_net_ntop F
++ inet_net_pton F
++ inet_neta F
++ ns_datetosecs F
++ ns_format_ttl F
++ ns_get16 F
++ ns_get32 F
++ ns_initparse F
++ ns_makecanon F
++ ns_msg_getflag F
++ ns_name_compress F
++ ns_name_ntol F
++ ns_name_ntop F
++ ns_name_pack F
++ ns_name_pton F
++ ns_name_rollback F
++ ns_name_skip F
++ ns_name_uncompress F
++ ns_name_unpack F
++ ns_parse_ttl F
++ ns_parserr F
++ ns_put16 F
++ ns_put32 F
++ ns_samedomain F
++ ns_samename F
++ ns_skiprr F
++ ns_sprintrr F
++ ns_sprintrrf F
++ ns_subdomain F
++ res_gethostbyaddr F
++ res_gethostbyname F
++ res_gethostbyname2 F
++ res_send_setqhook F
++ res_send_setrhook F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librt-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librt-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librt-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librt-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,37 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ __mq_open_2 F
++ aio_cancel F
++ aio_cancel64 F
++ aio_error F
++ aio_error64 F
++ aio_fsync F
++ aio_fsync64 F
++ aio_init F
++ aio_read F
++ aio_read64 F
++ aio_return F
++ aio_return64 F
++ aio_suspend F
++ aio_suspend64 F
++ aio_write F
++ aio_write64 F
++ lio_listio F
++ lio_listio64 F
++ mq_close F
++ mq_getattr F
++ mq_notify F
++ mq_open F
++ mq_receive F
++ mq_send F
++ mq_setattr F
++ mq_timedreceive F
++ mq_timedsend F
++ mq_unlink F
++ shm_open F
++ shm_unlink F
++ timer_create F
++ timer_delete F
++ timer_getoverrun F
++ timer_gettime F
++ timer_settime F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libthread_db-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libthread_db-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libthread_db-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libthread_db-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,42 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ td_init F
++ td_log F
++ td_symbol_list F
++ td_ta_clear_event F
++ td_ta_delete F
++ td_ta_enable_stats F
++ td_ta_event_addr F
++ td_ta_event_getmsg F
++ td_ta_get_nthreads F
++ td_ta_get_ph F
++ td_ta_get_stats F
++ td_ta_map_id2thr F
++ td_ta_map_lwp2thr F
++ td_ta_new F
++ td_ta_reset_stats F
++ td_ta_set_event F
++ td_ta_setconcurrency F
++ td_ta_thr_iter F
++ td_ta_tsd_iter F
++ td_thr_clear_event F
++ td_thr_dbresume F
++ td_thr_dbsuspend F
++ td_thr_event_enable F
++ td_thr_event_getmsg F
++ td_thr_get_info F
++ td_thr_getfpregs F
++ td_thr_getgregs F
++ td_thr_getxregs F
++ td_thr_getxregsize F
++ td_thr_set_event F
++ td_thr_setfpregs F
++ td_thr_setgregs F
++ td_thr_setprio F
++ td_thr_setsigpending F
++ td_thr_setxregs F
++ td_thr_sigsetmask F
++ td_thr_tls_get_addr F
++ td_thr_tlsbase F
++ td_thr_tsd F
++ td_thr_validate F
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libutil-le.abilist glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libutil-le.abilist
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libutil-le.abilist	1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.17-c758a686.new/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libutil-le.abilist	2014-06-02 15:22:40.000000000 +0000
+@@ -0,0 +1,8 @@
++GLIBC_2.17
++ GLIBC_2.17 A
++ forkpty F
++ login F
++ login_tty F
++ logout F
++ logwtmp F
++ openpty F
diff --git a/SOURCES/glibc-ppc64le-03.patch b/SOURCES/glibc-ppc64le-03.patch
new file mode 100644
index 0000000..0280c65
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-03.patch
@@ -0,0 +1,1617 @@
+# commit 9e54314bb06aace405553552f7e7b7d8c172968c
+# Author: Joseph Myers <joseph@codesourcery.com>
+# Date:   Thu Jun 6 19:02:09 2013 +0000
+# 
+#     Update miscellaneous scripts from upstream.
+# 
+diff -urN glibc-2.17-c758a686.orig/scripts/config.guess glibc-2.17-c758a686.diff/scripts/config.guess
+--- glibc-2.17-c758a686.orig/scripts/config.guess	2014-05-26 15:59:45.000000000 -0500
++++ glibc-2.17-c758a686.diff/scripts/config.guess	2014-05-26 16:01:00.000000000 -0500
+@@ -1,14 +1,12 @@
+ #! /bin/sh
+ # Attempt to guess a canonical system name.
+-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+-#   2011, 2012 Free Software Foundation, Inc.
++#   Copyright 1992-2013 Free Software Foundation, Inc.
+ 
+-timestamp='2012-09-25'
++timestamp='2013-11-29'
+ 
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful, but
+@@ -22,19 +20,17 @@
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
+-
+-
+-# Originally written by Per Bothner.  Please send patches (context
+-# diff format) to <config-patches@gnu.org> and include a ChangeLog
+-# entry.
++# the same distribution terms that you use for the rest of that
++# program.  This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ #
+-# This script attempts to guess a canonical system name similar to
+-# config.sub.  If it succeeds, it prints the system name on stdout, and
+-# exits with 0.  Otherwise, it exits with 1.
++# Originally written by Per Bothner.
+ #
+ # You can get the latest version of this script from:
+ # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
++#
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++
+ 
+ me=`echo "$0" | sed -e 's,.*/,,'`
+ 
+@@ -54,9 +50,7 @@
+ GNU config.guess ($timestamp)
+ 
+ Originally written by Per Bothner.
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+-Free Software Foundation, Inc.
++Copyright 1992-2013 Free Software Foundation, Inc.
+ 
+ This is free software; see the source for copying conditions.  There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -138,6 +132,27 @@
+ UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+ 
++case "${UNAME_SYSTEM}" in
++Linux|GNU|GNU/*)
++	# If the system lacks a compiler, then just pick glibc.
++	# We could probably try harder.
++	LIBC=gnu
++
++	eval $set_cc_for_build
++	cat <<-EOF > $dummy.c
++	#include <features.h>
++	#if defined(__UCLIBC__)
++	LIBC=uclibc
++	#elif defined(__dietlibc__)
++	LIBC=dietlibc
++	#else
++	LIBC=gnu
++	#endif
++	EOF
++	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
++	;;
++esac
++
+ # Note: order is significant - the case branches are not exclusive.
+ 
+ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+@@ -859,21 +874,21 @@
+ 	exit ;;
+     *:GNU:*:*)
+ 	# the GNU system
+-	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
++	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ 	exit ;;
+     *:GNU/*:*:*)
+ 	# other systems with GNU libc and userland
+-	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
++	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ 	exit ;;
+     i*86:Minix:*:*)
+ 	echo ${UNAME_MACHINE}-pc-minix
+ 	exit ;;
+     aarch64:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     aarch64_be:Linux:*:*)
+ 	UNAME_MACHINE=aarch64_be
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     alpha:Linux:*:*)
+ 	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+@@ -886,59 +901,54 @@
+ 	  EV68*) UNAME_MACHINE=alphaev68 ;;
+ 	esac
+ 	objdump --private-headers /bin/sh | grep -q ld.so.1
+-	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
++	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    arc:Linux:*:* | arceb:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     arm*:Linux:*:*)
+ 	eval $set_cc_for_build
+ 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ 	    | grep -q __ARM_EABI__
+ 	then
+-	    echo ${UNAME_MACHINE}-unknown-linux-gnu
++	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	else
+ 	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ 		| grep -q __ARM_PCS_VFP
+ 	    then
+-		echo ${UNAME_MACHINE}-unknown-linux-gnueabi
++		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ 	    else
+-		echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
++		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ 	    fi
+ 	fi
+ 	exit ;;
+     avr32*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     cris:Linux:*:*)
+-	echo ${UNAME_MACHINE}-axis-linux-gnu
++	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ 	exit ;;
+     crisv32:Linux:*:*)
+-	echo ${UNAME_MACHINE}-axis-linux-gnu
++	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ 	exit ;;
+     frv:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     hexagon:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     i*86:Linux:*:*)
+-	LIBC=gnu
+-	eval $set_cc_for_build
+-	sed 's/^	//' << EOF >$dummy.c
+-	#ifdef __dietlibc__
+-	LIBC=dietlibc
+-	#endif
+-EOF
+-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+-	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
++	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ 	exit ;;
+     ia64:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     m32r*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     m68*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     mips:Linux:*:* | mips64:Linux:*:*)
+ 	eval $set_cc_for_build
+@@ -957,54 +967,63 @@
+ 	#endif
+ EOF
+ 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+-	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
++	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ 	;;
++    or1k:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
+     or32:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     padre:Linux:*:*)
+-	echo sparc-unknown-linux-gnu
++	echo sparc-unknown-linux-${LIBC}
+ 	exit ;;
+     parisc64:Linux:*:* | hppa64:Linux:*:*)
+-	echo hppa64-unknown-linux-gnu
++	echo hppa64-unknown-linux-${LIBC}
+ 	exit ;;
+     parisc:Linux:*:* | hppa:Linux:*:*)
+ 	# Look for CPU level
+ 	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+-	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+-	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+-	  *)    echo hppa-unknown-linux-gnu ;;
++	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
++	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
++	  *)    echo hppa-unknown-linux-${LIBC} ;;
+ 	esac
+ 	exit ;;
+     ppc64:Linux:*:*)
+-	echo powerpc64-unknown-linux-gnu
++	echo powerpc64-unknown-linux-${LIBC}
+ 	exit ;;
+     ppc:Linux:*:*)
+-	echo powerpc-unknown-linux-gnu
++	echo powerpc-unknown-linux-${LIBC}
++	exit ;;
++    ppc64le:Linux:*:*)
++	echo powerpc64le-unknown-linux-${LIBC}
++	exit ;;
++    ppcle:Linux:*:*)
++	echo powerpcle-unknown-linux-${LIBC}
+ 	exit ;;
+     s390:Linux:*:* | s390x:Linux:*:*)
+-	echo ${UNAME_MACHINE}-ibm-linux
++	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ 	exit ;;
+     sh64*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     sh*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     sparc:Linux:*:* | sparc64:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     tile*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     vax:Linux:*:*)
+-	echo ${UNAME_MACHINE}-dec-linux-gnu
++	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ 	exit ;;
+     x86_64:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     xtensa*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     i*86:DYNIX/ptx:4*:*)
+ 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+@@ -1237,19 +1256,31 @@
+ 	exit ;;
+     *:Darwin:*:*)
+ 	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+-	case $UNAME_PROCESSOR in
+-	    i386)
+-		eval $set_cc_for_build
+-		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+-		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+-		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+-		      grep IS_64BIT_ARCH >/dev/null
+-		  then
+-		      UNAME_PROCESSOR="x86_64"
+-		  fi
+-		fi ;;
+-	    unknown) UNAME_PROCESSOR=powerpc ;;
+-	esac
++	eval $set_cc_for_build
++	if test "$UNAME_PROCESSOR" = unknown ; then
++	    UNAME_PROCESSOR=powerpc
++	fi
++	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
++	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
++		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
++		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
++		    grep IS_64BIT_ARCH >/dev/null
++		then
++		    case $UNAME_PROCESSOR in
++			i386) UNAME_PROCESSOR=x86_64 ;;
++			powerpc) UNAME_PROCESSOR=powerpc64 ;;
++		    esac
++		fi
++	    fi
++	elif test "$UNAME_PROCESSOR" = i386 ; then
++	    # Avoid executing cc on OS X 10.9, as it ships with a stub
++	    # that puts up a graphical alert prompting to install
++	    # developer tools.  Any system running Mac OS X 10.7 or
++	    # later (Darwin 11 and later) is required to have a 64-bit
++	    # processor. This is not true of the ARM version of Darwin
++	    # that Apple uses in portable devices.
++	    UNAME_PROCESSOR=x86_64
++	fi
+ 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ 	exit ;;
+     *:procnto*:*:* | *:QNX:[0123456789]*:*)
+diff -urN glibc-2.17-c758a686.orig/scripts/config.sub glibc-2.17-c758a686.diff/scripts/config.sub
+--- glibc-2.17-c758a686.orig/scripts/config.sub	2014-05-26 15:59:45.000000000 -0500
++++ glibc-2.17-c758a686.diff/scripts/config.sub	2014-05-26 16:00:52.000000000 -0500
+@@ -1,24 +1,18 @@
+ #! /bin/sh
+ # Configuration validation subroutine script.
+-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+-#   2011, 2012 Free Software Foundation, Inc.
+-
+-timestamp='2012-08-18'
+-
+-# This file is (in principle) common to ALL GNU software.
+-# The presence of a machine in this file suggests that SOME GNU software
+-# can handle that machine.  It does not imply ALL GNU software can.
+-#
+-# This file is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++#   Copyright 1992-2013 Free Software Foundation, Inc.
++
++timestamp='2013-10-01'
++
++# This file is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU General Public License for more details.
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++# General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, see <http://www.gnu.org/licenses/>.
+@@ -26,11 +20,12 @@
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
++# the same distribution terms that you use for the rest of that
++# program.  This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ 
+ 
+-# Please send patches to <config-patches@gnu.org>.  Submit a context
+-# diff and a properly formatted GNU ChangeLog entry.
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+ #
+ # Configuration subroutine to validate and canonicalize a configuration type.
+ # Supply the specified configuration type as an argument.
+@@ -73,9 +68,7 @@
+ version="\
+ GNU config.sub ($timestamp)
+ 
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+-Free Software Foundation, Inc.
++Copyright 1992-2013 Free Software Foundation, Inc.
+ 
+ This is free software; see the source for copying conditions.  There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -156,7 +149,7 @@
+ 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+-	-apple | -axis | -knuth | -cray | -microblaze)
++	-apple | -axis | -knuth | -cray | -microblaze*)
+ 		os=
+ 		basic_machine=$1
+ 		;;
+@@ -259,10 +252,12 @@
+ 	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ 	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ 	| am33_2.0 \
+-	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+-        | be32 | be64 \
++	| arc | arceb \
++	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
++	| avr | avr32 \
++	| be32 | be64 \
+ 	| bfin \
+-	| c4x | clipper \
++	| c4x | c8051 | clipper \
+ 	| d10v | d30v | dlx | dsp16xx \
+ 	| epiphany \
+ 	| fido | fr30 | frv \
+@@ -270,10 +265,11 @@
+ 	| hexagon \
+ 	| i370 | i860 | i960 | ia64 \
+ 	| ip2k | iq2000 \
++	| k1om \
+ 	| le32 | le64 \
+ 	| lm32 \
+ 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+-	| maxq | mb | microblaze | mcore | mep | metag \
++	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ 	| mips | mipsbe | mipseb | mipsel | mipsle \
+ 	| mips16 \
+ 	| mips64 | mips64el \
+@@ -291,16 +287,17 @@
+ 	| mipsisa64r2 | mipsisa64r2el \
+ 	| mipsisa64sb1 | mipsisa64sb1el \
+ 	| mipsisa64sr71k | mipsisa64sr71kel \
++	| mipsr5900 | mipsr5900el \
+ 	| mipstx39 | mipstx39el \
+ 	| mn10200 | mn10300 \
+ 	| moxie \
+ 	| mt \
+ 	| msp430 \
+ 	| nds32 | nds32le | nds32be \
+-	| nios | nios2 \
++	| nios | nios2 | nios2eb | nios2el \
+ 	| ns16k | ns32k \
+ 	| open8 \
+-	| or32 \
++	| or1k | or32 \
+ 	| pdp10 | pdp11 | pj | pjl \
+ 	| powerpc | powerpc64 | powerpc64le | powerpcle \
+ 	| pyramid \
+@@ -328,7 +325,7 @@
+ 	c6x)
+ 		basic_machine=tic6x-unknown
+ 		;;
+-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
++	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ 		basic_machine=$basic_machine-unknown
+ 		os=-none
+ 		;;
+@@ -370,13 +367,13 @@
+ 	| aarch64-* | aarch64_be-* \
+ 	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ 	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
++	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+ 	| avr-* | avr32-* \
+ 	| be32-* | be64-* \
+ 	| bfin-* | bs2000-* \
+ 	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+-	| clipper-* | craynv-* | cydra-* \
++	| c8051-* | clipper-* | craynv-* | cydra-* \
+ 	| d10v-* | d30v-* | dlx-* \
+ 	| elxsi-* \
+ 	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+@@ -385,11 +382,13 @@
+ 	| hexagon-* \
+ 	| i*86-* | i860-* | i960-* | ia64-* \
+ 	| ip2k-* | iq2000-* \
++	| k1om-* \
+ 	| le32-* | le64-* \
+ 	| lm32-* \
+ 	| m32c-* | m32r-* | m32rle-* \
+ 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
++	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
++	| microblaze-* | microblazeel-* \
+ 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ 	| mips16-* \
+ 	| mips64-* | mips64el-* \
+@@ -407,12 +406,13 @@
+ 	| mipsisa64r2-* | mipsisa64r2el-* \
+ 	| mipsisa64sb1-* | mipsisa64sb1el-* \
+ 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
++	| mipsr5900-* | mipsr5900el-* \
+ 	| mipstx39-* | mipstx39el-* \
+ 	| mmix-* \
+ 	| mt-* \
+ 	| msp430-* \
+ 	| nds32-* | nds32le-* | nds32be-* \
+-	| nios-* | nios2-* \
++	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+ 	| none-* | np1-* | ns16k-* | ns32k-* \
+ 	| open8-* \
+ 	| orion-* \
+@@ -788,7 +788,7 @@
+ 		basic_machine=ns32k-utek
+ 		os=-sysv
+ 		;;
+-	microblaze)
++	microblaze*)
+ 		basic_machine=microblaze-xilinx
+ 		;;
+ 	mingw64)
+@@ -796,7 +796,7 @@
+ 		os=-mingw64
+ 		;;
+ 	mingw32)
+-		basic_machine=i386-pc
++		basic_machine=i686-pc
+ 		os=-mingw32
+ 		;;
+ 	mingw32ce)
+@@ -832,7 +832,7 @@
+ 		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ 		;;
+ 	msys)
+-		basic_machine=i386-pc
++		basic_machine=i686-pc
+ 		os=-msys
+ 		;;
+ 	mvs)
+@@ -1023,7 +1023,11 @@
+ 		basic_machine=i586-unknown
+ 		os=-pw32
+ 		;;
+-	rdos)
++	rdos | rdos64)
++		basic_machine=x86_64-pc
++		os=-rdos
++		;;
++	rdos32)
+ 		basic_machine=i386-pc
+ 		os=-rdos
+ 		;;
+@@ -1350,7 +1354,7 @@
+ 	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ 	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ 	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+-	      | -sym* | -kopensolaris* \
++	      | -sym* | -kopensolaris* | -plan9* \
+ 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ 	      | -aos* | -aros* \
+ 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+@@ -1496,9 +1500,6 @@
+ 	-aros*)
+ 		os=-aros
+ 		;;
+-	-kaos*)
+-		os=-kaos
+-		;;
+ 	-zvmoe)
+ 		os=-zvmoe
+ 		;;
+@@ -1547,6 +1548,9 @@
+ 	c4x-* | tic4x-*)
+ 		os=-coff
+ 		;;
++	c8051-*)
++		os=-elf
++		;;
+ 	hexagon-*)
+ 		os=-elf
+ 		;;
+@@ -1590,6 +1594,9 @@
+ 	mips*-*)
+ 		os=-elf
+ 		;;
++	or1k-*)
++		os=-elf
++		;;
+ 	or32-*)
+ 		os=-coff
+ 		;;
+diff -urN glibc-2.17-c758a686.orig/scripts/install-sh glibc-2.17-c758a686.diff/scripts/install-sh
+--- glibc-2.17-c758a686.orig/scripts/install-sh	2014-05-26 15:59:45.000000000 -0500
++++ glibc-2.17-c758a686.diff/scripts/install-sh	2014-05-26 16:00:34.000000000 -0500
+@@ -1,250 +1,527 @@
+-#! /bin/sh
+-#
++#!/bin/sh
+ # install - install a program, script, or datafile
+-# This comes from X11R5 (mit/util/scripts/install.sh).
++
++scriptversion=2011-11-20.07; # UTC
++
++# This originates from X11R5 (mit/util/scripts/install.sh), which was
++# later released in X11R6 (xc/config/util/install.sh) with the
++# following copyright and license.
++#
++# Copyright (C) 1994 X Consortium
++#
++# Permission is hereby granted, free of charge, to any person obtaining a copy
++# of this software and associated documentation files (the "Software"), to
++# deal in the Software without restriction, including without limitation the
++# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++# sell copies of the Software, and to permit persons to whom the Software is
++# furnished to do so, subject to the following conditions:
++#
++# The above copyright notice and this permission notice shall be included in
++# all copies or substantial portions of the Software.
++#
++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
++# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
++# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
++# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++#
++# Except as contained in this notice, the name of the X Consortium shall not
++# be used in advertising or otherwise to promote the sale, use or other deal-
++# ings in this Software without prior written authorization from the X Consor-
++# tium.
+ #
+-# Copyright 1991 by the Massachusetts Institute of Technology
+ #
+-# Permission to use, copy, modify, distribute, and sell this software and its
+-# documentation for any purpose is hereby granted without fee, provided that
+-# the above copyright notice appear in all copies and that both that
+-# copyright notice and this permission notice appear in supporting
+-# documentation, and that the name of M.I.T. not be used in advertising or
+-# publicity pertaining to distribution of the software without specific,
+-# written prior permission.  M.I.T. makes no representations about the
+-# suitability of this software for any purpose.  It is provided "as is"
+-# without express or implied warranty.
++# FSF changes to this file are in the public domain.
+ #
+ # Calling this script install-sh is preferred over install.sh, to prevent
+-# `make' implicit rules from creating a file called install from it
++# 'make' implicit rules from creating a file called install from it
+ # when there is no Makefile.
+ #
+ # This script is compatible with the BSD install script, but was written
+-# from scratch.  It can only install one file at a time, a restriction
+-# shared with many OS's install programs.
++# from scratch.
+ 
++nl='
++'
++IFS=" ""	$nl"
+ 
+ # set DOITPROG to echo to test this script
+ 
+ # Don't use :- since 4.3BSD and earlier shells don't like it.
+-doit="${DOITPROG-}"
+-
+-
+-# put in absolute paths if you don't have them in your path; or use env. vars.
+-
+-mvprog="${MVPROG-mv}"
+-cpprog="${CPPROG-cp}"
+-chmodprog="${CHMODPROG-chmod}"
+-chownprog="${CHOWNPROG-chown}"
+-chgrpprog="${CHGRPPROG-chgrp}"
+-stripprog="${STRIPPROG-strip}"
+-rmprog="${RMPROG-rm}"
+-mkdirprog="${MKDIRPROG-mkdir}"
+-
+-transformbasename=""
+-transform_arg=""
+-instcmd="$mvprog"
+-chmodcmd="$chmodprog 0755"
+-chowncmd=""
+-chgrpcmd=""
+-stripcmd=""
+-rmcmd="$rmprog -f"
+-mvcmd="$mvprog"
+-src=""
+-dst=""
+-dir_arg=""
+-
+-while [ x"$1" != x ]; do
+-    case $1 in
+-	-c) instcmd="$cpprog"
+-	    shift
+-	    continue;;
+-
+-	-d) dir_arg=true
+-	    shift
+-	    continue;;
+-
+-	-m) chmodcmd="$chmodprog $2"
+-	    shift
+-	    shift
+-	    continue;;
+-
+-	-o) chowncmd="$chownprog $2"
+-	    shift
+-	    shift
+-	    continue;;
+-
+-	-g) chgrpcmd="$chgrpprog $2"
+-	    shift
+-	    shift
+-	    continue;;
+-
+-	-s) stripcmd="$stripprog"
+-	    shift
+-	    continue;;
+-
+-	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+-	    shift
+-	    continue;;
+-
+-	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+-	    shift
+-	    continue;;
+-
+-	*)  if [ x"$src" = x ]
+-	    then
+-		src=$1
+-	    else
+-		# this colon is to work around a 386BSD /bin/sh bug
+-		:
+-		dst=$1
+-	    fi
+-	    shift
+-	    continue;;
+-    esac
+-done
+-
+-if [ x"$src" = x ]
+-then
+-	echo "install:	no input file specified"
+-	exit 1
++doit=${DOITPROG-}
++if test -z "$doit"; then
++  doit_exec=exec
+ else
+-	true
++  doit_exec=$doit
+ fi
+ 
+-if [ x"$dir_arg" != x ]; then
+-	dst=$src
+-	src=""
+-	
+-	if [ -d $dst ]; then
+-		instcmd=:
+-	else
+-		instcmd=mkdir
+-	fi
+-else
++# Put in absolute file names if you don't have them in your path;
++# or use environment vars.
+ 
+-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+-# might cause directories to be created, which would be especially bad 
+-# if $src (and thus $dsttmp) contains '*'.
+-
+-	if [ -f $src -o -d $src ]
+-	then
+-		true
+-	else
+-		echo "install:  $src does not exist"
+-		exit 1
+-	fi
+-	
+-	if [ x"$dst" = x ]
+-	then
+-		echo "install:	no destination specified"
+-		exit 1
+-	else
+-		true
+-	fi
+-
+-# If destination is a directory, append the input filename; if your system
+-# does not like double slashes in filenames, you may need to add some logic
+-
+-	if [ -d $dst ]
+-	then
+-		dst="$dst"/`basename $src`
+-	else
+-		true
+-	fi
+-fi
+-
+-## this sed command emulates the dirname command
+-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
++chgrpprog=${CHGRPPROG-chgrp}
++chmodprog=${CHMODPROG-chmod}
++chownprog=${CHOWNPROG-chown}
++cmpprog=${CMPPROG-cmp}
++cpprog=${CPPROG-cp}
++mkdirprog=${MKDIRPROG-mkdir}
++mvprog=${MVPROG-mv}
++rmprog=${RMPROG-rm}
++stripprog=${STRIPPROG-strip}
++
++posix_glob='?'
++initialize_posix_glob='
++  test "$posix_glob" != "?" || {
++    if (set -f) 2>/dev/null; then
++      posix_glob=
++    else
++      posix_glob=:
++    fi
++  }
++'
+ 
+-# Make sure that the destination directory exists.
+-#  this part is taken from Noah Friedman's mkinstalldirs script
++posix_mkdir=
+ 
+-# Skip lots of stat calls in the usual case.
+-if [ ! -d "$dstdir" ]; then
+-defaultIFS='	
+-'
+-IFS="${IFS-${defaultIFS}}"
++# Desired mode of installed file.
++mode=0755
+ 
+-oIFS="${IFS}"
+-# Some sh's can't handle IFS=/ for some reason.
+-IFS='%'
+-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+-IFS="${oIFS}"
+-
+-pathcomp=''
+-
+-while [ $# -ne 0 ] ; do
+-	pathcomp="${pathcomp}${1}"
+-	shift
+-
+-	if [ ! -d "${pathcomp}" ] ;
+-        then
+-		$mkdirprog "${pathcomp}"
+-	else
+-		true
+-	fi
++chgrpcmd=
++chmodcmd=$chmodprog
++chowncmd=
++mvcmd=$mvprog
++rmcmd="$rmprog -f"
++stripcmd=
+ 
+-	pathcomp="${pathcomp}/"
++src=
++dst=
++dir_arg=
++dst_arg=
++
++copy_on_change=false
++no_target_directory=
++
++usage="\
++Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
++   or: $0 [OPTION]... SRCFILES... DIRECTORY
++   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
++   or: $0 [OPTION]... -d DIRECTORIES...
++
++In the 1st form, copy SRCFILE to DSTFILE.
++In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
++In the 4th, create DIRECTORIES.
++
++Options:
++     --help     display this help and exit.
++     --version  display version info and exit.
++
++  -c            (ignored)
++  -C            install only if different (preserve the last data modification time)
++  -d            create directories instead of installing files.
++  -g GROUP      $chgrpprog installed files to GROUP.
++  -m MODE       $chmodprog installed files to MODE.
++  -o USER       $chownprog installed files to USER.
++  -s            $stripprog installed files.
++  -t DIRECTORY  install into DIRECTORY.
++  -T            report an error if DSTFILE is a directory.
++
++Environment variables override the default commands:
++  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
++  RMPROG STRIPPROG
++"
++
++while test $# -ne 0; do
++  case $1 in
++    -c) ;;
++
++    -C) copy_on_change=true;;
++
++    -d) dir_arg=true;;
++
++    -g) chgrpcmd="$chgrpprog $2"
++	shift;;
++
++    --help) echo "$usage"; exit $?;;
++
++    -m) mode=$2
++	case $mode in
++	  *' '* | *'	'* | *'
++'*	  | *'*'* | *'?'* | *'['*)
++	    echo "$0: invalid mode: $mode" >&2
++	    exit 1;;
++	esac
++	shift;;
++
++    -o) chowncmd="$chownprog $2"
++	shift;;
++
++    -s) stripcmd=$stripprog;;
++
++    -t) dst_arg=$2
++	# Protect names problematic for 'test' and other utilities.
++	case $dst_arg in
++	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
++	esac
++	shift;;
++
++    -T) no_target_directory=true;;
++
++    --version) echo "$0 $scriptversion"; exit $?;;
++
++    --)	shift
++	break;;
++
++    -*)	echo "$0: invalid option: $1" >&2
++	exit 1;;
++
++    *)  break;;
++  esac
++  shift
+ done
++
++if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
++  # When -d is used, all remaining arguments are directories to create.
++  # When -t is used, the destination is already specified.
++  # Otherwise, the last argument is the destination.  Remove it from $@.
++  for arg
++  do
++    if test -n "$dst_arg"; then
++      # $@ is not empty: it contains at least $arg.
++      set fnord "$@" "$dst_arg"
++      shift # fnord
++    fi
++    shift # arg
++    dst_arg=$arg
++    # Protect names problematic for 'test' and other utilities.
++    case $dst_arg in
++      -* | [=\(\)!]) dst_arg=./$dst_arg;;
++    esac
++  done
+ fi
+ 
+-if [ x"$dir_arg" != x ]
+-then
+-	$doit $instcmd $dst &&
+-
+-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+-else
++if test $# -eq 0; then
++  if test -z "$dir_arg"; then
++    echo "$0: no input file specified." >&2
++    exit 1
++  fi
++  # It's OK to call 'install-sh -d' without argument.
++  # This can happen when creating conditional directories.
++  exit 0
++fi
+ 
+-# If we're going to rename the final executable, determine the name now.
++if test -z "$dir_arg"; then
++  do_exit='(exit $ret); exit $ret'
++  trap "ret=129; $do_exit" 1
++  trap "ret=130; $do_exit" 2
++  trap "ret=141; $do_exit" 13
++  trap "ret=143; $do_exit" 15
++
++  # Set umask so as not to create temps with too-generous modes.
++  # However, 'strip' requires both read and write access to temps.
++  case $mode in
++    # Optimize common cases.
++    *644) cp_umask=133;;
++    *755) cp_umask=22;;
++
++    *[0-7])
++      if test -z "$stripcmd"; then
++	u_plus_rw=
++      else
++	u_plus_rw='% 200'
++      fi
++      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
++    *)
++      if test -z "$stripcmd"; then
++	u_plus_rw=
++      else
++	u_plus_rw=,u+rw
++      fi
++      cp_umask=$mode$u_plus_rw;;
++  esac
++fi
+ 
+-	if [ x"$transformarg" = x ] 
+-	then
+-		dstfile=`basename $dst`
++for src
++do
++  # Protect names problematic for 'test' and other utilities.
++  case $src in
++    -* | [=\(\)!]) src=./$src;;
++  esac
++
++  if test -n "$dir_arg"; then
++    dst=$src
++    dstdir=$dst
++    test -d "$dstdir"
++    dstdir_status=$?
++  else
++
++    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
++    # might cause directories to be created, which would be especially bad
++    # if $src (and thus $dsttmp) contains '*'.
++    if test ! -f "$src" && test ! -d "$src"; then
++      echo "$0: $src does not exist." >&2
++      exit 1
++    fi
++
++    if test -z "$dst_arg"; then
++      echo "$0: no destination specified." >&2
++      exit 1
++    fi
++    dst=$dst_arg
++
++    # If destination is a directory, append the input filename; won't work
++    # if double slashes aren't ignored.
++    if test -d "$dst"; then
++      if test -n "$no_target_directory"; then
++	echo "$0: $dst_arg: Is a directory" >&2
++	exit 1
++      fi
++      dstdir=$dst
++      dst=$dstdir/`basename "$src"`
++      dstdir_status=0
++    else
++      # Prefer dirname, but fall back on a substitute if dirname fails.
++      dstdir=`
++	(dirname "$dst") 2>/dev/null ||
++	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++	     X"$dst" : 'X\(//\)[^/]' \| \
++	     X"$dst" : 'X\(//\)$' \| \
++	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
++	echo X"$dst" |
++	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
++		   s//\1/
++		   q
++		 }
++		 /^X\(\/\/\)[^/].*/{
++		   s//\1/
++		   q
++		 }
++		 /^X\(\/\/\)$/{
++		   s//\1/
++		   q
++		 }
++		 /^X\(\/\).*/{
++		   s//\1/
++		   q
++		 }
++		 s/.*/./; q'
++      `
++
++      test -d "$dstdir"
++      dstdir_status=$?
++    fi
++  fi
++
++  obsolete_mkdir_used=false
++
++  if test $dstdir_status != 0; then
++    case $posix_mkdir in
++      '')
++	# Create intermediate dirs using mode 755 as modified by the umask.
++	# This is like FreeBSD 'install' as of 1997-10-28.
++	umask=`umask`
++	case $stripcmd.$umask in
++	  # Optimize common cases.
++	  *[2367][2367]) mkdir_umask=$umask;;
++	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
++
++	  *[0-7])
++	    mkdir_umask=`expr $umask + 22 \
++	      - $umask % 100 % 40 + $umask % 20 \
++	      - $umask % 10 % 4 + $umask % 2
++	    `;;
++	  *) mkdir_umask=$umask,go-w;;
++	esac
++
++	# With -d, create the new directory with the user-specified mode.
++	# Otherwise, rely on $mkdir_umask.
++	if test -n "$dir_arg"; then
++	  mkdir_mode=-m$mode
+ 	else
+-		dstfile=`basename $dst $transformbasename | 
+-			sed $transformarg`$transformbasename
++	  mkdir_mode=
+ 	fi
+ 
+-# don't allow the sed command to completely eliminate the filename
++	posix_mkdir=false
++	case $umask in
++	  *[123567][0-7][0-7])
++	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
++	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
++	    ;;
++	  *)
++	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
++	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
++
++	    if (umask $mkdir_umask &&
++		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
++	    then
++	      if test -z "$dir_arg" || {
++		   # Check for POSIX incompatibilities with -m.
++		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
++		   # other-writable bit of parent directory when it shouldn't.
++		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
++		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
++		   case $ls_ld_tmpdir in
++		     d????-?r-*) different_mode=700;;
++		     d????-?--*) different_mode=755;;
++		     *) false;;
++		   esac &&
++		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
++		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
++		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
++		   }
++		 }
++	      then posix_mkdir=:
++	      fi
++	      rmdir "$tmpdir/d" "$tmpdir"
++	    else
++	      # Remove any dirs left behind by ancient mkdir implementations.
++	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
++	    fi
++	    trap '' 0;;
++	esac;;
++    esac
+ 
+-	if [ x"$dstfile" = x ] 
+-	then
+-		dstfile=`basename $dst`
++    if
++      $posix_mkdir && (
++	umask $mkdir_umask &&
++	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
++      )
++    then :
++    else
++
++      # The umask is ridiculous, or mkdir does not conform to POSIX,
++      # or it failed possibly due to a race condition.  Create the
++      # directory the slow way, step by step, checking for races as we go.
++
++      case $dstdir in
++	/*) prefix='/';;
++	[-=\(\)!]*) prefix='./';;
++	*)  prefix='';;
++      esac
++
++      eval "$initialize_posix_glob"
++
++      oIFS=$IFS
++      IFS=/
++      $posix_glob set -f
++      set fnord $dstdir
++      shift
++      $posix_glob set +f
++      IFS=$oIFS
++
++      prefixes=
++
++      for d
++      do
++	test X"$d" = X && continue
++
++	prefix=$prefix$d
++	if test -d "$prefix"; then
++	  prefixes=
+ 	else
+-		true
++	  if $posix_mkdir; then
++	    (umask=$mkdir_umask &&
++	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
++	    # Don't fail if two instances are running concurrently.
++	    test -d "$prefix" || exit 1
++	  else
++	    case $prefix in
++	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
++	      *) qprefix=$prefix;;
++	    esac
++	    prefixes="$prefixes '$qprefix'"
++	  fi
+ 	fi
++	prefix=$prefix/
++      done
+ 
+-# Make a temp file name in the proper directory.
+-
+-	dsttmp=$dstdir/#inst.$$#
+-
+-# Move or copy the file name to the temp name
+-
+-	$doit $instcmd $src $dsttmp &&
+-
+-	trap "rm -f ${dsttmp}" 0 &&
+-
+-# and set any options; do chmod last to preserve setuid bits
+-
+-# If any of these fail, we abort the whole thing.  If we want to
+-# ignore errors from any of these, just make sure not to ignore
+-# errors from the above "$doit $instcmd $src $dsttmp" command.
+-
+-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+-
+-# Now rename the file to the real destination.
+-
+-	$doit $rmcmd -f $dstdir/$dstfile &&
+-	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+-
+-fi &&
++      if test -n "$prefixes"; then
++	# Don't fail if two instances are running concurrently.
++	(umask $mkdir_umask &&
++	 eval "\$doit_exec \$mkdirprog $prefixes") ||
++	  test -d "$dstdir" || exit 1
++	obsolete_mkdir_used=true
++      fi
++    fi
++  fi
++
++  if test -n "$dir_arg"; then
++    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
++    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
++    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
++      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
++  else
++
++    # Make a couple of temp file names in the proper directory.
++    dsttmp=$dstdir/_inst.$$_
++    rmtmp=$dstdir/_rm.$$_
++
++    # Trap to clean up those temp files at exit.
++    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
++
++    # Copy the file name to the temp name.
++    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
++
++    # and set any options; do chmod last to preserve setuid bits.
++    #
++    # If any of these fail, we abort the whole thing.  If we want to
++    # ignore errors from any of these, just make sure not to ignore
++    # errors from the above "$doit $cpprog $src $dsttmp" command.
++    #
++    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
++    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
++    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
++    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
++
++    # If -C, don't bother to copy if it wouldn't change the file.
++    if $copy_on_change &&
++       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
++       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
++
++       eval "$initialize_posix_glob" &&
++       $posix_glob set -f &&
++       set X $old && old=:$2:$4:$5:$6 &&
++       set X $new && new=:$2:$4:$5:$6 &&
++       $posix_glob set +f &&
++
++       test "$old" = "$new" &&
++       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
++    then
++      rm -f "$dsttmp"
++    else
++      # Rename the file to the real destination.
++      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
++
++      # The rename failed, perhaps because mv can't rename something else
++      # to itself, or perhaps because mv is so ancient that it does not
++      # support -f.
++      {
++	# Now remove or move aside any old file at destination location.
++	# We try this two ways since rm can't unlink itself on some
++	# systems and the destination file might be busy for other
++	# reasons.  In this case, the final cleanup might fail but the new
++	# file should still install successfully.
++	{
++	  test ! -f "$dst" ||
++	  $doit $rmcmd -f "$dst" 2>/dev/null ||
++	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
++	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
++	  } ||
++	  { echo "$0: cannot unlink or rename $dst" >&2
++	    (exit 1); exit 1
++	  }
++	} &&
++
++	# Now rename the file to the real destination.
++	$doit $mvcmd "$dsttmp" "$dst"
++      }
++    fi || exit 1
+ 
++    trap '' 0
++  fi
++done
+ 
+-exit 0
++# Local variables:
++# eval: (add-hook 'write-file-hooks 'time-stamp)
++# time-stamp-start: "scriptversion="
++# time-stamp-format: "%:y-%02m-%02d.%02H"
++# time-stamp-time-zone: "UTC"
++# time-stamp-end: "; # UTC"
++# End:
+diff -urN glibc-2.17-c758a686.orig/scripts/mkinstalldirs glibc-2.17-c758a686.diff/scripts/mkinstalldirs
+--- glibc-2.17-c758a686.orig/scripts/mkinstalldirs	2014-05-26 15:59:45.000000000 -0500
++++ glibc-2.17-c758a686.diff/scripts/mkinstalldirs	2014-05-26 16:00:34.000000000 -0500
+@@ -1,38 +1,162 @@
+ #! /bin/sh
+ # mkinstalldirs --- make directory hierarchy
+-# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+-# Created: 1993-05-16
+-# Public domain
+ 
++scriptversion=2009-04-28.21; # UTC
++
++# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
++# Created: 1993-05-16
++# Public domain.
++#
++# This file is maintained in Automake, please report
++# bugs to <bug-automake@gnu.org> or send patches to
++# <automake-patches@gnu.org>.
++
++nl='
++'
++IFS=" ""	$nl"
+ errstatus=0
++dirmode=
++
++usage="\
++Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
++
++Create each directory DIR (with mode MODE, if specified), including all
++leading file name components.
++
++Report bugs to <bug-automake@gnu.org>."
++
++# process command line arguments
++while test $# -gt 0 ; do
++  case $1 in
++    -h | --help | --h*)         # -h for help
++      echo "$usage"
++      exit $?
++      ;;
++    -m)                         # -m PERM arg
++      shift
++      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
++      dirmode=$1
++      shift
++      ;;
++    --version)
++      echo "$0 $scriptversion"
++      exit $?
++      ;;
++    --)                         # stop option processing
++      shift
++      break
++      ;;
++    -*)                         # unknown option
++      echo "$usage" 1>&2
++      exit 1
++      ;;
++    *)                          # first non-opt arg
++      break
++      ;;
++  esac
++done
+ 
+ for file
+ do
+-   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+-   shift
++  if test -d "$file"; then
++    shift
++  else
++    break
++  fi
++done
++
++case $# in
++  0) exit 0 ;;
++esac
++
++# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
++# mkdir -p a/c at the same time, both will detect that a is missing,
++# one will create a, then the other will try to create a and die with
++# a "File exists" error.  This is a problem when calling mkinstalldirs
++# from a parallel make.  We use --version in the probe to restrict
++# ourselves to GNU mkdir, which is thread-safe.
++case $dirmode in
++  '')
++    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
++      echo "mkdir -p -- $*"
++      exec mkdir -p -- "$@"
++    else
++      # On NextStep and OpenStep, the 'mkdir' command does not
++      # recognize any option.  It will interpret all options as
++      # directories to create, and then abort because '.' already
++      # exists.
++      test -d ./-p && rmdir ./-p
++      test -d ./--version && rmdir ./--version
++    fi
++    ;;
++  *)
++    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
++       test ! -d ./--version; then
++      echo "mkdir -m $dirmode -p -- $*"
++      exec mkdir -m "$dirmode" -p -- "$@"
++    else
++      # Clean up after NextStep and OpenStep mkdir.
++      for d in ./-m ./-p ./--version "./$dirmode";
++      do
++        test -d $d && rmdir $d
++      done
++    fi
++    ;;
++esac
+ 
+-   pathcomp=
+-   for d
+-   do
+-     pathcomp="$pathcomp$d"
+-     case "$pathcomp" in
+-       -* ) pathcomp=./$pathcomp ;;
+-     esac
+-
+-     if test ! -d "$pathcomp"; then
+-        echo "mkdir $pathcomp" 1>&2
+-
+-        mkdir "$pathcomp" || lasterr=$?
+-
+-        if test ! -d "$pathcomp"; then
+-  	  errstatus=$lasterr
+-        fi
+-     fi
++for file
++do
++  case $file in
++    /*) pathcomp=/ ;;
++    *)  pathcomp= ;;
++  esac
++  oIFS=$IFS
++  IFS=/
++  set fnord $file
++  shift
++  IFS=$oIFS
++
++  for d
++  do
++    test "x$d" = x && continue
++
++    pathcomp=$pathcomp$d
++    case $pathcomp in
++      -*) pathcomp=./$pathcomp ;;
++    esac
++
++    if test ! -d "$pathcomp"; then
++      echo "mkdir $pathcomp"
++
++      mkdir "$pathcomp" || lasterr=$?
++
++      if test ! -d "$pathcomp"; then
++	errstatus=$lasterr
++      else
++	if test ! -z "$dirmode"; then
++	  echo "chmod $dirmode $pathcomp"
++	  lasterr=
++	  chmod "$dirmode" "$pathcomp" || lasterr=$?
++
++	  if test ! -z "$lasterr"; then
++	    errstatus=$lasterr
++	  fi
++	fi
++      fi
++    fi
+ 
+-     pathcomp="$pathcomp/"
+-   done
++    pathcomp=$pathcomp/
++  done
+ done
+ 
+ exit $errstatus
+ 
+-# mkinstalldirs ends here
++# Local Variables:
++# mode: shell-script
++# sh-indentation: 2
++# eval: (add-hook 'write-file-hooks 'time-stamp)
++# time-stamp-start: "scriptversion="
++# time-stamp-format: "%:y-%02m-%02d.%02H"
++# time-stamp-time-zone: "UTC"
++# time-stamp-end: "; # UTC"
++# End:
+diff -urN glibc-2.17-c758a686.orig/scripts/move-if-change glibc-2.17-c758a686.diff/scripts/move-if-change
+--- glibc-2.17-c758a686.orig/scripts/move-if-change	2014-05-26 15:59:45.000000000 -0500
++++ glibc-2.17-c758a686.diff/scripts/move-if-change	2014-05-26 16:00:34.000000000 -0500
+@@ -1,17 +1,83 @@
+ #!/bin/sh
+ # Like mv $1 $2, but if the files are the same, just delete $1.
+-# Status is 0 if $2 is changed, 1 otherwise.
+-if
+-test -r $2
+-then
+-if
+-cmp -s $1 $2
+-then
+-echo $2 is unchanged
+-rm -f $1
++# Status is zero if successful, nonzero otherwise.
++
++VERSION='2012-01-06 07:23'; # UTC
++# The definition above must lie within the first 8 lines in order
++# for the Emacs time-stamp write hook (at end) to update it.
++# If you change this file with Emacs, please let the write hook
++# do its job.  Otherwise, update this string manually.
++
++# Copyright (C) 2002-2013 Free Software Foundation, Inc.
++
++# This program is free software: you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation, either version 3 of the License, or
++# (at your option) any later version.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++
++usage="usage: $0 SOURCE DEST"
++
++help="$usage
++  or:  $0 OPTION
++If SOURCE is different than DEST, then move it to DEST; else remove SOURCE.
++
++  --help     display this help and exit
++  --version  output version information and exit
++
++The variable CMPPROG can be used to specify an alternative to 'cmp'.
++
++Report bugs to <bug-gnulib@gnu.org>."
++
++version=`expr "$VERSION" : '\([^ ]*\)'`
++version="move-if-change (gnulib) $version
++Copyright (C) 2011 Free Software Foundation, Inc.
++License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
++This is free software: you are free to change and redistribute it.
++There is NO WARRANTY, to the extent permitted by law."
++
++cmpprog=${CMPPROG-cmp}
++
++for arg
++do
++  case $arg in
++    --help | --hel | --he | --h)
++      exec echo "$help" ;;
++    --version | --versio | --versi | --vers | --ver | --ve | --v)
++      exec echo "$version" ;;
++    --)
++      shift
++      break ;;
++    -*)
++      echo "$0: invalid option: $arg" >&2
++      exit 1 ;;
++    *)
++      break ;;
++  esac
++done
++
++test $# -eq 2 || { echo "$0: $usage" >&2; exit 1; }
++
++if test -r "$2" && $cmpprog -- "$1" "$2" >/dev/null; then
++  rm -f -- "$1"
+ else
+-mv -f $1 $2
+-fi
+-else
+-mv -f $1 $2
++  if mv -f -- "$1" "$2"; then :; else
++    # Ignore failure due to a concurrent move-if-change.
++    test -r "$2" && $cmpprog -- "$1" "$2" >/dev/null && rm -f -- "$1"
++  fi
+ fi
++
++## Local Variables:
++## eval: (add-hook 'write-file-hooks 'time-stamp)
++## time-stamp-start: "VERSION='"
++## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
++## time-stamp-time-zone: "UTC"
++## time-stamp-end: "'; # UTC"
++## End:
diff --git a/SOURCES/glibc-ppc64le-04.patch b/SOURCES/glibc-ppc64le-04.patch
new file mode 100644
index 0000000..2afd9f3
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-04.patch
@@ -0,0 +1,676 @@
+# commit 9605ca6c085a749f29b6866a3e00bce1ba1a2698
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:12:56 2013 +0930
+# 
+#     IBM long double mechanical changes to support little-endian
+#     http://sourceware.org/ml/libc-alpha/2013-07/msg00001.html
+#     
+#     This patch starts the process of supporting powerpc64 little-endian
+#     long double in glibc.  IBM long double is an array of two ieee
+#     doubles, so making union ibm_extended_long_double reflect this fact is
+#     the correct way to access fields of the doubles.
+#     
+#         * sysdeps/ieee754/ldbl-128ibm/ieee754.h
+#         (union ibm_extended_long_double): Define as an array of ieee754_double.
+#         (IBM_EXTENDED_LONG_DOUBLE_BIAS): Delete.
+#         * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c: Update all references
+#         to ibm_extended_long_double and IBM_EXTENDED_LONG_DOUBLE_BIAS.
+#         * sysdeps/ieee754/ldbl-128ibm/e_exp10l.c: Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_expl.c: Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c: Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h: Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c: Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c: Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/strtold_l.c: Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c	2014-05-26 21:08:10.000000000 -0500
+@@ -36,9 +36,9 @@
+   else if (arg > LDBL_MAX_10_EXP + 1)
+     return LDBL_MAX * LDBL_MAX;
+ 
+-  u.d = arg;
+-  arg_high = u.dd[0];
+-  arg_low = u.dd[1];
++  u.ld = arg;
++  arg_high = u.d[0].d;
++  arg_low = u.d[1].d;
+   exp_high = arg_high * log10_high;
+   exp_low = arg_high * log10_low + arg_low * M_LN10l;
+   return __ieee754_expl (exp_high) * __ieee754_expl (exp_low);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_expl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_expl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_expl.c	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_expl.c	2014-05-26 21:08:10.000000000 -0500
+@@ -162,39 +162,39 @@
+       x = x + xl;
+ 
+       /* Compute ex2 = 2^n_0 e^(argtable[tval1]) e^(argtable[tval2]).  */
+-      ex2_u.d = __expl_table[T_EXPL_RES1 + tval1]
+-		* __expl_table[T_EXPL_RES2 + tval2];
++      ex2_u.ld = (__expl_table[T_EXPL_RES1 + tval1]
++		  * __expl_table[T_EXPL_RES2 + tval2]);
+       n_i = (int)n;
+       /* 'unsafe' is 1 iff n_1 != 0.  */
+       unsafe = fabsl(n_i) >= -LDBL_MIN_EXP - 1;
+-      ex2_u.ieee.exponent += n_i >> unsafe;
++      ex2_u.d[0].ieee.exponent += n_i >> unsafe;
+       /* Fortunately, there are no subnormal lowpart doubles in
+ 	 __expl_table, only normal values and zeros.
+ 	 But after scaling it can be subnormal.  */
+-      exponent2 = ex2_u.ieee.exponent2 + (n_i >> unsafe);
+-      if (ex2_u.ieee.exponent2 == 0)
+-	/* assert ((ex2_u.ieee.mantissa2|ex2_u.ieee.mantissa3) == 0) */;
++      exponent2 = ex2_u.d[1].ieee.exponent + (n_i >> unsafe);
++      if (ex2_u.d[1].ieee.exponent == 0)
++	/* assert ((ex2_u.d[1].ieee.mantissa0|ex2_u.d[1].ieee.mantissa1) == 0) */;
+       else if (exponent2 > 0)
+-	ex2_u.ieee.exponent2 = exponent2;
++	ex2_u.d[1].ieee.exponent = exponent2;
+       else if (exponent2 <= -54)
+ 	{
+-	  ex2_u.ieee.exponent2 = 0;
+-	  ex2_u.ieee.mantissa2 = 0;
+-	  ex2_u.ieee.mantissa3 = 0;
++	  ex2_u.d[1].ieee.exponent = 0;
++	  ex2_u.d[1].ieee.mantissa0 = 0;
++	  ex2_u.d[1].ieee.mantissa1 = 0;
+ 	}
+       else
+ 	{
+ 	  static const double
+ 	    two54 = 1.80143985094819840000e+16, /* 4350000000000000 */
+ 	    twom54 = 5.55111512312578270212e-17; /* 3C90000000000000 */
+-	  ex2_u.dd[1] *= two54;
+-	  ex2_u.ieee.exponent2 += n_i >> unsafe;
+-	  ex2_u.dd[1] *= twom54;
++	  ex2_u.d[1].d *= two54;
++	  ex2_u.d[1].ieee.exponent += n_i >> unsafe;
++	  ex2_u.d[1].d *= twom54;
+ 	}
+ 
+       /* Compute scale = 2^n_1.  */
+-      scale_u.d = 1.0L;
+-      scale_u.ieee.exponent += n_i - (n_i >> unsafe);
++      scale_u.ld = 1.0L;
++      scale_u.d[0].ieee.exponent += n_i - (n_i >> unsafe);
+ 
+       /* Approximate e^x2 - 1, using a seventh-degree polynomial,
+ 	 with maximum error in [-2^-16-2^-53,2^-16+2^-53]
+@@ -204,7 +204,7 @@
+       /* Return result.  */
+       fesetenv (&oldenv);
+ 
+-      result = x22 * ex2_u.d + ex2_u.d;
++      result = x22 * ex2_u.ld + ex2_u.ld;
+ 
+       /* Now we can test whether the result is ultimate or if we are unsure.
+ 	 In the later case we should probably call a mpn based routine to give
+@@ -238,7 +238,7 @@
+       if (!unsafe)
+ 	return result;
+       else
+-	return result * scale_u.d;
++	return result * scale_u.ld;
+     }
+   /* Exceptional cases:  */
+   else if (isless (x, himark))
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/ieee754.h glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/ieee754.h
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/ieee754.h	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/ieee754.h	2014-05-26 21:08:10.000000000 -0500
+@@ -180,29 +180,9 @@
+ 
+ union ibm_extended_long_double
+   {
+-    long double d;
+-    double dd[2];
+-
+-    /* This is the IBM extended format long double.  */
+-    struct
+-      { /* Big endian.  There is no other.  */
+-
+-	unsigned int negative:1;
+-	unsigned int exponent:11;
+-	/* Together Mantissa0-3 comprise the mantissa.  */
+-	unsigned int mantissa0:20;
+-	unsigned int mantissa1:32;
+-
+-	unsigned int negative2:1;
+-	unsigned int exponent2:11;
+-	/* There is an implied 1 here?  */
+-	/* Together these comprise the mantissa.  */
+-	unsigned int mantissa2:20;
+-	unsigned int mantissa3:32;
+-      } ieee;
+-   };
+-
+-#define IBM_EXTENDED_LONG_DOUBLE_BIAS 0x3ff /* Added to exponent.  */
++    long double ld;
++    union ieee754_double d[2];
++  };
+ 
+ __END_DECLS
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c	2014-05-26 21:08:10.000000000 -0500
+@@ -36,22 +36,22 @@
+   union ibm_extended_long_double u;
+   unsigned long long hi, lo;
+   int ediff;
+-  u.d = value;
++  u.ld = value;
+ 
+-  *is_neg = u.ieee.negative;
+-  *expt = (int) u.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS;
++  *is_neg = u.d[0].ieee.negative;
++  *expt = (int) u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS;
+ 
+-  lo = ((long long) u.ieee.mantissa2 << 32) | u.ieee.mantissa3;
+-  hi = ((long long) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
++  lo = ((long long) u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;
++  hi = ((long long) u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;
+   /* If the lower double is not a denomal or zero then set the hidden
+      53rd bit.  */
+-  if (u.ieee.exponent2 > 0)
++  if (u.d[1].ieee.exponent > 0)
+     {
+       lo |= 1LL << 52;
+ 
+       /* The lower double is normalized separately from the upper.  We may
+ 	 need to adjust the lower manitissa to reflect this.  */
+-      ediff = u.ieee.exponent - u.ieee.exponent2;
++      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;
+       if (ediff > 53)
+ 	lo = lo >> (ediff-53);
+     }
+@@ -59,8 +59,8 @@
+      difference between the long double and the rounded high double
+      value.  This is indicated by a differnce between the signs of the
+      high and low doubles.  */
+-  if ((u.ieee.negative != u.ieee.negative2)
+-      && ((u.ieee.exponent2 != 0) && (lo != 0L)))
++  if ((u.d[0].ieee.negative != u.d[1].ieee.negative)
++      && ((u.d[1].ieee.exponent != 0) && (lo != 0L)))
+     {
+       lo = (1ULL << 53) - lo;
+       if (hi == 0LL)
+@@ -92,7 +92,7 @@
+ #define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \
+ 			   - (LDBL_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB)))
+ 
+-  if (u.ieee.exponent == 0)
++  if (u.d[0].ieee.exponent == 0)
+     {
+       /* A biased exponent of zero is a special case.
+ 	 Either it is a zero or it is a denormal number.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-26 21:08:10.000000000 -0500
+@@ -14,28 +14,28 @@
+      as bit 53 of the mantissa.  */
+   uint64_t hi, lo;
+   int ediff;
+-  union ibm_extended_long_double eldbl;
+-  eldbl.d = x;
+-  *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS;
++  union ibm_extended_long_double u;
++  u.ld = x;
++  *exp = u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS;
+ 
+-  lo = ((int64_t)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3;
+-  hi = ((int64_t)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1;
++  lo = ((uint64_t)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;
++  hi = ((uint64_t)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;
+   /* If the lower double is not a denomal or zero then set the hidden
+      53rd bit.  */
+-  if (eldbl.ieee.exponent2 > 0x001)
++  if (u.d[1].ieee.exponent > 0x001)
+     {
+       lo |= (1ULL << 52);
+       lo = lo << 7; /* pre-shift lo to match ieee854.  */
+       /* The lower double is normalized separately from the upper.  We
+ 	 may need to adjust the lower manitissa to reflect this.  */
+-      ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2;
++      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;
+       if (ediff > 53)
+ 	lo = lo >> (ediff-53);
+       hi |= (1ULL << 52);
+     }
+   
+-  if ((eldbl.ieee.negative != eldbl.ieee.negative2)
+-      && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL)))
++  if ((u.d[0].ieee.negative != u.d[1].ieee.negative)
++      && ((u.d[1].ieee.exponent != 0) && (lo != 0LL)))
+     {
+       hi--;
+       lo = (1ULL << 60) - lo;
+@@ -58,10 +58,10 @@
+   unsigned long hidden2, lzcount;
+   unsigned long long hi, lo;
+ 
+-  u.ieee.negative = sign;
+-  u.ieee.negative2 = sign;
+-  u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+-  u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS;
++  u.d[0].ieee.negative = sign;
++  u.d[1].ieee.negative = sign;
++  u.d[0].ieee.exponent = exp + IEEE754_DOUBLE_BIAS;
++  u.d[1].ieee.exponent = exp-53 + IEEE754_DOUBLE_BIAS;
+   /* Expect 113 bits (112 bits + hidden) right justified in two longs.
+      The low order 53 bits (52 + hidden) go into the lower double */ 
+   lo = (lo64 >> 7)& ((1ULL << 53) - 1);
+@@ -78,7 +78,7 @@
+       if (hidden2)
+ 	{
+ 	  hi++;
+-	  u.ieee.negative2 = !sign;
++	  u.d[1].ieee.negative = !sign;
+ 	  lo = (1ULL << 53) - lo;
+ 	}
+       /* The hidden bit of the lo mantissa is zero so we need to
+@@ -94,32 +94,32 @@
+       lzcount = lzcount - 11;
+       if (lzcount > 0)
+ 	{
+-	  int expnt2 = u.ieee.exponent2 - lzcount;
++	  int expnt2 = u.d[1].ieee.exponent - lzcount;
+ 	  if (expnt2 >= 1)
+ 	    {
+ 	      /* Not denormal.  Normalize and set low exponent.  */
+ 	      lo = lo << lzcount;
+-	      u.ieee.exponent2 = expnt2;
++	      u.d[1].ieee.exponent = expnt2;
+ 	    }
+ 	  else
+ 	    {
+ 	      /* Is denormal.  */
+ 	      lo = lo << (lzcount + expnt2);
+-	      u.ieee.exponent2 = 0;
++	      u.d[1].ieee.exponent = 0;
+ 	    }
+ 	}
+     }
+   else
+     {
+-      u.ieee.negative2 = 0;
+-      u.ieee.exponent2 = 0;
++      u.d[1].ieee.negative = 0;
++      u.d[1].ieee.exponent = 0;
+     }
+ 
+-  u.ieee.mantissa3 = lo & ((1ULL << 32) - 1);
+-  u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1);
+-  u.ieee.mantissa1 = hi & ((1ULL << 32) - 1);
+-  u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1);
+-  return u.d;
++  u.d[1].ieee.mantissa1 = lo & ((1ULL << 32) - 1);
++  u.d[1].ieee.mantissa0 = (lo >> 32) & ((1ULL << 20) - 1);
++  u.d[0].ieee.mantissa1 = hi & ((1ULL << 32) - 1);
++  u.d[0].ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1);
++  return u.ld;
+ }
+   
+ /* Handy utility functions to pack/unpack/cononicalize and find the nearbyint
+@@ -128,18 +128,18 @@
+ default_ldbl_pack (double a, double aa)
+ {
+   union ibm_extended_long_double u;
+-  u.dd[0] = a;
+-  u.dd[1] = aa;
+-  return u.d;
++  u.d[0].d = a;
++  u.d[1].d = aa;
++  return u.ld;
+ }
+ 
+ static inline void
+ default_ldbl_unpack (long double l, double *a, double *aa)
+ {
+   union ibm_extended_long_double u;
+-  u.d = l;
+-  *a = u.dd[0];
+-  *aa = u.dd[1];
++  u.ld = l;
++  *a = u.d[0].d;
++  *aa = u.d[1].d;
+ }
+ 
+ #ifndef ldbl_pack
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c	2014-05-26 21:08:10.000000000 -0500
+@@ -34,11 +34,11 @@
+   unsigned long long hi, lo;
+   int exponent2;
+ 
+-  u.ieee.negative = sign;
+-  u.ieee.negative2 = sign;
+-  u.ieee.exponent = expt + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+-  u.ieee.exponent2 = 0;
+-  exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS;
++  u.d[0].ieee.negative = sign;
++  u.d[1].ieee.negative = sign;
++  u.d[0].ieee.exponent = expt + IEEE754_DOUBLE_BIAS;
++  u.d[1].ieee.exponent = 0;
++  exponent2 = expt - 53 + IEEE754_DOUBLE_BIAS;
+ 
+ #if BITS_PER_MP_LIMB == 32
+   /* The low order 53 bits (52 + hidden) go into the lower double */
+@@ -74,15 +74,15 @@
+       else
+ 	lzcount = lzcount + 42;
+ 
+-      if (lzcount > u.ieee.exponent)
++      if (lzcount > u.d[0].ieee.exponent)
+ 	{
+-	  lzcount = u.ieee.exponent;
+-	  u.ieee.exponent = 0;
++	  lzcount = u.d[0].ieee.exponent;
++	  u.d[0].ieee.exponent = 0;
+ 	  exponent2 -= lzcount;
+ 	}
+       else
+ 	{
+-	  u.ieee.exponent -= (lzcount - 1);
++	  u.d[0].ieee.exponent -= (lzcount - 1);
+ 	  exponent2 -= (lzcount - 1);
+ 	}
+ 
+@@ -112,9 +112,9 @@
+ 	    {
+ 	      if ((hi & (1LL << 53)) != 0)
+ 		hi -= 1LL << 52;
+-	      u.ieee.exponent++;
++	      u.d[0].ieee.exponent++;
+ 	    }
+-	  u.ieee.negative2 = !sign;
++	  u.d[1].ieee.negative = !sign;
+ 	  lo = (1LL << 53) - lo;
+ 	}
+ 
+@@ -135,17 +135,17 @@
+ 	  exponent2 = exponent2 - lzcount;
+ 	}
+       if (exponent2 > 0)
+-	u.ieee.exponent2 = exponent2;
++	u.d[1].ieee.exponent = exponent2;
+       else
+ 	lo >>= 1 - exponent2;
+     }
+   else
+-    u.ieee.negative2 = 0;
++    u.d[1].ieee.negative = 0;
+ 
+-  u.ieee.mantissa3 = lo & 0xffffffffLL;
+-  u.ieee.mantissa2 = (lo >> 32) & 0xfffff;
+-  u.ieee.mantissa1 = hi & 0xffffffffLL;
+-  u.ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1);
++  u.d[1].ieee.mantissa1 = lo & 0xffffffffLL;
++  u.d[1].ieee.mantissa0 = (lo >> 32) & 0xfffff;
++  u.d[0].ieee.mantissa1 = hi & 0xffffffffLL;
++  u.d[0].ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1);
+ 
+-  return u.d;
++  return u.ld;
+ }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2014-05-26 21:08:10.000000000 -0500
+@@ -27,31 +27,31 @@
+       unsigned long long int num0, num1;				      \
+       unsigned long long hi, lo;					      \
+       int ediff;							      \
+-      union ibm_extended_long_double eldbl;				      \
+-      eldbl.d = fpnum.ldbl.d;						      \
++      union ibm_extended_long_double u;					      \
++      u.ld = fpnum.ldbl.d;						      \
+ 									      \
+       assert (sizeof (long double) == 16);				      \
+ 									      \
+-      lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3;    \
+-      hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1;    \
++      lo = ((long long)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;  \
++      hi = ((long long)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;  \
+       lo <<= 7; /* pre-shift lo to match ieee854.  */			      \
+       /* If the lower double is not a denomal or zero then set the hidden     \
+ 	 53rd bit.  */							      \
+-      if (eldbl.ieee.exponent2 != 0)					      \
++      if (u.d[1].ieee.exponent != 0)					      \
+ 	lo |= (1ULL << (52 + 7));					      \
+       else								      \
+ 	lo <<= 1;							      \
+       /* The lower double is normalized separately from the upper.  We	      \
+ 	 may need to adjust the lower manitissa to reflect this.  */	      \
+-      ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2;		      \
++      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;		      \
+       if (ediff > 53 + 63)						      \
+ 	lo = 0;								      \
+       else if (ediff > 53)						      \
+ 	lo = lo >> (ediff - 53);					      \
+-      else if (eldbl.ieee.exponent2 == 0 && ediff < 53)			      \
++      else if (u.d[1].ieee.exponent == 0 && ediff < 53)			      \
+ 	lo = lo << (53 - ediff);					      \
+-      if (eldbl.ieee.negative != eldbl.ieee.negative2			      \
+-	  && (eldbl.ieee.exponent2 != 0 || lo != 0L))			      \
++      if (u.d[0].ieee.negative != u.d[1].ieee.negative			      \
++	  && (u.d[1].ieee.exponent != 0 || lo != 0L))			      \
+ 	{								      \
+ 	  lo = (1ULL << 60) - lo;					      \
+ 	  if (hi == 0L)							      \
+@@ -59,7 +59,7 @@
+ 	      /* we have a borrow from the hidden bit, so shift left 1.  */   \
+ 	      hi = 0xffffffffffffeLL | (lo >> 59);			      \
+ 	      lo = 0xfffffffffffffffLL & (lo << 1);			      \
+-	      eldbl.ieee.exponent--;					      \
++	      u.d[0].ieee.exponent--;					      \
+ 	    }								      \
+ 	  else								      \
+ 	    hi--;							      \
+@@ -110,9 +110,9 @@
+ 	  *--wnumstr = L'0';						      \
+ 	}								      \
+ 									      \
+-      leading = eldbl.ieee.exponent == 0 ? '0' : '1';			      \
++      leading = u.d[0].ieee.exponent == 0 ? '0' : '1';			      \
+ 									      \
+-      exponent = eldbl.ieee.exponent;					      \
++      exponent = u.d[0].ieee.exponent;					      \
+ 									      \
+       if (exponent == 0)						      \
+ 	{								      \
+@@ -122,18 +122,18 @@
+ 	    {								      \
+ 	      /* This is a denormalized number.  */			      \
+ 	      expnegative = 1;						      \
+-	      exponent = IBM_EXTENDED_LONG_DOUBLE_BIAS - 1;		      \
++	      exponent = IEEE754_DOUBLE_BIAS - 1;			      \
+ 	    }								      \
+ 	}								      \
+-      else if (exponent >= IBM_EXTENDED_LONG_DOUBLE_BIAS)		      \
++      else if (exponent >= IEEE754_DOUBLE_BIAS)				      \
+ 	{								      \
+ 	  expnegative = 0;						      \
+-	  exponent -= IBM_EXTENDED_LONG_DOUBLE_BIAS;			      \
++	  exponent -= IEEE754_DOUBLE_BIAS;				      \
+ 	}								      \
+       else								      \
+ 	{								      \
+ 	  expnegative = 1;						      \
+-	  exponent = -(exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS);	      \
++	  exponent = -(exponent - IEEE754_DOUBLE_BIAS);			      \
+ 	}								      \
+ } while (0)
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c	2014-05-26 21:08:10.000000000 -0500
+@@ -33,11 +33,11 @@
+   fenv_t env;
+   static const long double TWO52 = 4503599627370496.0L;
+   union ibm_extended_long_double u;
+-  u.d = x;
++  u.ld = x;
+ 
+-  if (fabs (u.dd[0]) < TWO52)
++  if (fabs (u.d[0].d) < TWO52)
+     {
+-      double high = u.dd[0];
++      double high = u.d[0].d;
+       feholdexcept (&env);
+       if (high > 0.0)
+ 	{
+@@ -51,11 +51,11 @@
+ 	  high += TWO52;
+           if (high == 0.0) high = -0.0;
+ 	}
+-      u.dd[0] = high;
+-      u.dd[1] = 0.0;
++      u.d[0].d = high;
++      u.d[1].d = 0.0;
+       fesetenv (&env);
+     }
+-  else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0)
++  else if (fabs (u.d[1].d) < TWO52 && u.d[1].d != 0.0)
+     {
+       double high, low, tau;
+       /* In this case we have to round the low double and handle any
+@@ -64,55 +64,55 @@
+          may already be rounded and the low double may have the
+          opposite sign to compensate.  */
+       feholdexcept (&env);
+-      if (u.dd[0] > 0.0)
++      if (u.d[0].d > 0.0)
+ 	{
+-	  if (u.dd[1] > 0.0)
++	  if (u.d[1].d > 0.0)
+ 	    {
+ 	      /* If the high/low doubles are the same sign then simply
+ 	         round the low double.  */
+-	      high = u.dd[0];
+-	      low = u.dd[1];
++	      high = u.d[0].d;
++	      low = u.d[1].d;
+ 	    }
+-	  else if (u.dd[1] < 0.0)
++	  else if (u.d[1].d < 0.0)
+ 	    {
+ 	      /* Else the high double is pre rounded and we need to
+ 	         adjust for that.  */
+ 
+-	      tau = __nextafter (u.dd[0], 0.0);
+-	      tau = (u.dd[0] - tau) * 2.0;
+-	      high = u.dd[0] - tau;
+-	      low = u.dd[1] + tau;
++	      tau = __nextafter (u.d[0].d, 0.0);
++	      tau = (u.d[0].d - tau) * 2.0;
++	      high = u.d[0].d - tau;
++	      low = u.d[1].d + tau;
+ 	    }
+ 	  low += TWO52;
+ 	  low -= TWO52;
+ 	}
+-      else if (u.dd[0] < 0.0)
++      else if (u.d[0].d < 0.0)
+ 	{
+-	  if (u.dd[1] < 0.0)
++	  if (u.d[1].d < 0.0)
+ 	    {
+ 	      /* If the high/low doubles are the same sign then simply
+ 	         round the low double.  */
+-	      high = u.dd[0];
+-	      low = u.dd[1];
++	      high = u.d[0].d;
++	      low = u.d[1].d;
+ 	    }
+-	  else if (u.dd[1] > 0.0)
++	  else if (u.d[1].d > 0.0)
+ 	    {
+ 	      /* Else the high double is pre rounded and we need to
+ 	         adjust for that.  */
+-	      tau = __nextafter (u.dd[0], 0.0);
+-	      tau = (u.dd[0] - tau) * 2.0;
+-	      high = u.dd[0] - tau;
+-	      low = u.dd[1] + tau;
++	      tau = __nextafter (u.d[0].d, 0.0);
++	      tau = (u.d[0].d - tau) * 2.0;
++	      high = u.d[0].d - tau;
++	      low = u.d[1].d + tau;
+ 	    }
+ 	  low = TWO52 - low;
+ 	  low = -(low - TWO52);
+ 	}
+-      u.dd[0] = high + low;
+-      u.dd[1] = high - u.dd[0] + low;
++      u.d[0].d = high + low;
++      u.d[1].d = high - u.d[0].d + low;
+       fesetenv (&env);
+     }
+ 
+-  return u.d;
++  return u.ld;
+ }
+ 
+ long_double_symbol (libm, __nearbyintl, nearbyintl);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/strtold_l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/strtold_l.c	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/strtold_l.c	2014-05-26 21:12:01.000000000 -0500
+@@ -43,12 +43,11 @@
+ #define FLOAT_HUGE_VAL	HUGE_VALL
+ # define SET_MANTISSA(flt, mant) \
+   do { union ibm_extended_long_double u;				      \
+-       u.d = (flt);							      \
+-       if ((mant & 0xfffffffffffffULL) == 0)				      \
+-	 mant = 0x8000000000000ULL;					      \
+-       u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff;			      \
+-       u.ieee.mantissa1 = (mant) & 0xffffffff;				      \
+-       (flt) = u.d;							      \
++       u.ld = (flt);							      \
++       u.d[0].ieee_nan.mantissa0 = (mant) >> 32;				      \
++       u.d[0].ieee_nan.mantissa1 = (mant);				   	      \
++       if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0)	      \
++         (flt) = u.ld;							      \
+   } while (0)
+ 
+ #include <strtod_l.c>
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c	2014-05-26 21:08:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c	2014-05-26 21:08:10.000000000 -0500
+@@ -89,23 +89,23 @@
+   double vals[12];
+   SET_RESTORE_ROUND (FE_TONEAREST);
+   union ibm_extended_long_double xu, yu;
+-  xu.d = x;
+-  yu.d = y;
+-  if (fabs (xu.dd[1]) < 0x1p-500)
+-    xu.dd[1] = 0.0;
+-  if (fabs (yu.dd[1]) < 0x1p-500)
+-    yu.dd[1] = 0.0;
+-  mul_split (&vals[1], &vals[0], xu.dd[0], xu.dd[0]);
+-  mul_split (&vals[3], &vals[2], xu.dd[0], xu.dd[1]);
++  xu.ld = x;
++  yu.ld = y;
++  if (fabs (xu.d[1].d) < 0x1p-500)
++    xu.d[1].d = 0.0;
++  if (fabs (yu.d[1].d) < 0x1p-500)
++    yu.d[1].d = 0.0;
++  mul_split (&vals[1], &vals[0], xu.d[0].d, xu.d[0].d);
++  mul_split (&vals[3], &vals[2], xu.d[0].d, xu.d[1].d);
+   vals[2] *= 2.0;
+   vals[3] *= 2.0;
+-  mul_split (&vals[5], &vals[4], xu.dd[1], xu.dd[1]);
+-  mul_split (&vals[7], &vals[6], yu.dd[0], yu.dd[0]);
+-  mul_split (&vals[9], &vals[8], yu.dd[0], yu.dd[1]);
++  mul_split (&vals[5], &vals[4], xu.d[1].d, xu.d[1].d);
++  mul_split (&vals[7], &vals[6], yu.d[0].d, yu.d[0].d);
++  mul_split (&vals[9], &vals[8], yu.d[0].d, yu.d[1].d);
+   vals[8] *= 2.0;
+   vals[9] *= 2.0;
+-  mul_split (&vals[11], &vals[10], yu.dd[1], yu.dd[1]);
+-  if (xu.dd[0] >= 0.75)
++  mul_split (&vals[11], &vals[10], yu.d[1].d, yu.d[1].d);
++  if (xu.d[0].d >= 0.75)
+     vals[1] -= 1.0;
+   else
+     {
diff --git a/SOURCES/glibc-ppc64le-05.patch b/SOURCES/glibc-ppc64le-05.patch
new file mode 100644
index 0000000..6469158
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-05.patch
@@ -0,0 +1,486 @@
+# commit 4cf69995e26e16005d4e3843ad4d18c75cf21a04
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:19:44 2013 +0930
+# 
+#     Fix for [BZ #15680] IBM long double inaccuracy
+#     http://sourceware.org/ml/libc-alpha/2013-06/msg00919.html
+#     
+#     I discovered a number of places where denormals and other corner cases
+#     were being handled wrongly.
+#     
+#     - printf_fphex.c: Testing for the low double exponent being zero is
+#     unnecessary.  If the difference in exponents is less than 53 then the
+#     high double exponent must be nearing the low end of its range, and the
+#     low double exponent hit rock bottom.
+#     
+#     - ldbl2mpn.c: A denormal (ie. exponent of zero) value is treated as
+#     if the exponent was one, so shift mantissa left by one.  Code handling
+#     normalisation of the low double mantissa lacked a test for shift count
+#     greater than bits in type being shifted, and lacked anything to handle
+#     the case where the difference in exponents is less than 53 as in
+#     printf_fphex.c.
+#     
+#     - math_ldbl.h (ldbl_extract_mantissa): Same as above, but worse, with
+#     code testing for exponent > 1 for some reason, probably a typo for >= 1.
+#     
+#     - math_ldbl.h (ldbl_insert_mantissa): Round the high double as per
+#     mpn2ldbl.c (hi is odd or explicit mantissas non-zero) so that the
+#     number we return won't change when applying ldbl_canonicalize().
+#     Add missing overflow checks and normalisation of high mantissa.
+#     Correct misleading comment: "The hidden bit of the lo mantissa is
+#     zero" is not always true as can be seen from the code rounding the hi
+#     mantissa.  Also by inspection, lzcount can never be less than zero so
+#     remove that test.  Lastly, masking bitfields to their widths can be
+#     left to the compiler.
+#     
+#     - mpn2ldbl.c: The overflow checks here on rounding of high double were
+#     just plain wrong.  Incrementing the exponent must be accompanied by a
+#     shift right of the mantissa to keep the value unchanged.  Above notes
+#     for ldbl_insert_mantissa are also relevant.
+#     
+#         [BZ #15680]
+#         * sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c: Comment fix.
+#         * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
+#         (PRINT_FPHEX_LONG_DOUBLE): Tidy code by moving -53 into ediff
+#         calculation.  Remove unnecessary test for denormal exponent.
+#         * sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c (__mpn_extract_long_double):
+#         Correct handling of denormals.  Avoid undefined shift behaviour.
+#         Correct normalisation of low mantissa when low double is denormal.
+#         * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
+#         (ldbl_extract_mantissa): Likewise.  Comment.  Use uint64_t* for hi64.
+#         (ldbl_insert_mantissa): Make both hi64 and lo64 parms uint64_t.
+#         Correct normalisation of low mantissa.  Test for overflow of high
+#         mantissa and normalise.
+#         (ldbl_nearbyint): Use more readable constant for two52.
+#         * sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
+#         (__mpn_construct_long_double): Fix test for overflow of high
+#         mantissa and correct normalisation.  Avoid undefined shift.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c	2014-05-27 19:13:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c	2014-05-27 19:14:45.000000000 -0500
+@@ -243,7 +243,7 @@
+      We split the 113 bits of the mantissa into 5 24bit integers
+      stored in a double array.  */
+   /* Make the IBM extended format 105 bit mantissa look like the ieee854 112
+-     bit mantissa so the next operatation will give the correct result.  */
++     bit mantissa so the next operation will give the correct result.  */
+   ldbl_extract_mantissa (&ixd, &lxd, &exp, x);
+   exp = exp - 23;
+   /* This is faster than doing this in floating point, because we
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c	2014-05-27 19:13:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c	2014-05-27 19:14:45.000000000 -0500
+@@ -36,6 +36,7 @@
+   union ibm_extended_long_double u;
+   unsigned long long hi, lo;
+   int ediff;
++
+   u.ld = value;
+ 
+   *is_neg = u.d[0].ieee.negative;
+@@ -43,27 +44,36 @@
+ 
+   lo = ((long long) u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;
+   hi = ((long long) u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;
+-  /* If the lower double is not a denomal or zero then set the hidden
++
++  /* If the lower double is not a denormal or zero then set the hidden
+      53rd bit.  */
+-  if (u.d[1].ieee.exponent > 0)
+-    {
+-      lo |= 1LL << 52;
++  if (u.d[1].ieee.exponent != 0)
++    lo |= 1ULL << 52;
++  else
++    lo = lo << 1;
+ 
+-      /* The lower double is normalized separately from the upper.  We may
+-	 need to adjust the lower manitissa to reflect this.  */
+-      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;
+-      if (ediff > 53)
+-	lo = lo >> (ediff-53);
++  /* The lower double is normalized separately from the upper.  We may
++     need to adjust the lower manitissa to reflect this.  */
++  ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53;
++  if (ediff > 0)
++    {
++      if (ediff < 64)
++	lo = lo >> ediff;
++      else
++	lo = 0;
+     }
++  else if (ediff < 0)
++    lo = lo << -ediff;
++
+   /* The high double may be rounded and the low double reflects the
+      difference between the long double and the rounded high double
+      value.  This is indicated by a differnce between the signs of the
+      high and low doubles.  */
+-  if ((u.d[0].ieee.negative != u.d[1].ieee.negative)
+-      && ((u.d[1].ieee.exponent != 0) && (lo != 0L)))
++  if (u.d[0].ieee.negative != u.d[1].ieee.negative
++      && lo != 0)
+     {
+       lo = (1ULL << 53) - lo;
+-      if (hi == 0LL)
++      if (hi == 0)
+ 	{
+ 	  /* we have a borrow from the hidden bit, so shift left 1.  */
+ 	  hi = 0x0ffffffffffffeLL | (lo >> 51);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-27 19:13:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-27 19:51:13.000000000 -0500
+@@ -13,77 +13,118 @@
+      the number before the decimal point and the second implicit bit
+      as bit 53 of the mantissa.  */
+   uint64_t hi, lo;
+-  int ediff;
+   union ibm_extended_long_double u;
++
+   u.ld = x;
+   *exp = u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS;
+ 
+   lo = ((uint64_t)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;
+   hi = ((uint64_t)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;
+-  /* If the lower double is not a denomal or zero then set the hidden
+-     53rd bit.  */
+-  if (u.d[1].ieee.exponent > 0x001)
+-    {
+-      lo |= (1ULL << 52);
+-      lo = lo << 7; /* pre-shift lo to match ieee854.  */
+-      /* The lower double is normalized separately from the upper.  We
+-	 may need to adjust the lower manitissa to reflect this.  */
+-      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;
+-      if (ediff > 53)
+-	lo = lo >> (ediff-53);
+-      hi |= (1ULL << 52);
+-    }
+   
+-  if ((u.d[0].ieee.negative != u.d[1].ieee.negative)
+-      && ((u.d[1].ieee.exponent != 0) && (lo != 0LL)))
++  if (u.d[0].ieee.exponent != 0)
+     {
+-      hi--;
+-      lo = (1ULL << 60) - lo;
+-      if (hi < (1ULL << 52))
++      int ediff;
++
++      /* If not a denormal or zero then we have an implicit 53rd bit.  */
++      hi |= (uint64_t) 1 << 52;
++
++      if (u.d[1].ieee.exponent != 0)
++	lo |= (uint64_t) 1 << 52;
++      else
++	/* A denormal is to be interpreted as having a biased exponent
++	   of 1.  */
++	lo = lo << 1;
++
++      /* We are going to shift 4 bits out of hi later, because we only
++	 want 48 bits in *hi64.  That means we want 60 bits in lo, but
++	 we currently only have 53.  Shift the value up.  */
++      lo = lo << 7;
++
++      /* The lower double is normalized separately from the upper.
++	 We may need to adjust the lower mantissa to reflect this.
++	 The difference between the exponents can be larger than 53
++	 when the low double is much less than 1ULP of the upper
++	 (in which case there are significant bits, all 0's or all
++	 1's, between the two significands).  The difference between
++	 the exponents can be less than 53 when the upper double
++	 exponent is nearing its minimum value (in which case the low
++	 double is denormal ie. has an exponent of zero).  */
++      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53;
++      if (ediff > 0)
+ 	{
+-	  /* we have a borrow from the hidden bit, so shift left 1.  */
+-	  hi = (hi << 1) | (lo >> 59);
+-	  lo = 0xfffffffffffffffLL & (lo << 1);
+-	  *exp = *exp - 1;
++	  if (ediff < 64)
++	    lo = lo >> ediff;
++	  else
++	    lo = 0;
++	}
++      else if (ediff < 0)
++	lo = lo << -ediff;
++
++      if (u.d[0].ieee.negative != u.d[1].ieee.negative
++	  && lo != 0)
++	{
++	  hi--;
++	  lo = ((uint64_t) 1 << 60) - lo;
++	  if (hi < (uint64_t) 1 << 52)
++	    {
++	      /* We have a borrow from the hidden bit, so shift left 1.  */
++	      hi = (hi << 1) | (lo >> 59);
++	      lo = (((uint64_t) 1 << 60) - 1) & (lo << 1);
++	      *exp = *exp - 1;
++	    }
+ 	}
+     }
++  else
++    /* If the larger magnitude double is denormal then the smaller
++       one must be zero.  */
++    hi = hi << 1;
++
+   *lo64 = (hi << 60) | lo;
+   *hi64 = hi >> 4;
+ }
+ 
+ static inline long double
+-ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64)
++ldbl_insert_mantissa (int sign, int exp, int64_t hi64, uint64_t lo64)
+ {
+   union ibm_extended_long_double u;
+-  unsigned long hidden2, lzcount;
+-  unsigned long long hi, lo;
++  int expnt2;
++  uint64_t hi, lo;
+ 
+   u.d[0].ieee.negative = sign;
+   u.d[1].ieee.negative = sign;
+   u.d[0].ieee.exponent = exp + IEEE754_DOUBLE_BIAS;
+-  u.d[1].ieee.exponent = exp-53 + IEEE754_DOUBLE_BIAS;
++  u.d[1].ieee.exponent = 0;
++  expnt2 = exp - 53 + IEEE754_DOUBLE_BIAS;
++ 
+   /* Expect 113 bits (112 bits + hidden) right justified in two longs.
+      The low order 53 bits (52 + hidden) go into the lower double */ 
+-  lo = (lo64 >> 7)& ((1ULL << 53) - 1);
+-  hidden2 = (lo64 >> 59) &  1ULL;
++  lo = (lo64 >> 7) & (((uint64_t) 1 << 53) - 1);
+   /* The high order 53 bits (52 + hidden) go into the upper double */
+-  hi = (lo64 >> 60) & ((1ULL << 11) - 1);
+-  hi |= (hi64 << 4);
++  hi = lo64 >> 60;
++  hi |= hi64 << 4;
+ 
+-  if (lo != 0LL)
++  if (lo != 0)
+     {
+-      /* hidden2 bit of low double controls rounding of the high double.
+-	 If hidden2 is '1' then round up hi and adjust lo (2nd mantissa)
++      int lzcount;
++
++      /* hidden bit of low double controls rounding of the high double.
++	 If hidden is '1' and either the explicit mantissa is non-zero
++	 or hi is odd, then round up hi and adjust lo (2nd mantissa)
+ 	 plus change the sign of the low double to compensate.  */
+-      if (hidden2)
++      if ((lo & ((uint64_t) 1 << 52)) != 0
++	  && ((hi & 1) != 0 || (lo & (((uint64_t) 1 << 52) - 1)) != 0))
+ 	{
+ 	  hi++;
++	  if ((hi & ((uint64_t) 1 << 53)) != 0)
++	    {
++	      hi = hi >> 1;
++	      u.d[0].ieee.exponent++;
++	    }
+ 	  u.d[1].ieee.negative = !sign;
+-	  lo = (1ULL << 53) - lo;
++	  lo = ((uint64_t) 1 << 53) - lo;
+ 	}
+-      /* The hidden bit of the lo mantissa is zero so we need to
+-	 normalize the it for the low double.  Shift it left until the
+-	 hidden bit is '1' then adjust the 2nd exponent accordingly.  */ 
++      /* Normalize the low double.  Shift the mantissa left until
++	 the hidden bit is '1' and adjust the exponent accordingly.  */
+ 
+       if (sizeof (lo) == sizeof (long))
+ 	lzcount = __builtin_clzl (lo);
+@@ -91,34 +132,30 @@
+ 	lzcount = __builtin_clzl ((long) (lo >> 32));
+       else
+ 	lzcount = __builtin_clzl ((long) lo) + 32;
+-      lzcount = lzcount - 11;
+-      if (lzcount > 0)
++      lzcount = lzcount - (64 - 53);
++      lo <<= lzcount;
++      expnt2 -= lzcount;
++
++      if (expnt2 >= 1)
++	/* Not denormal.  */
++	u.d[1].ieee.exponent = expnt2;
++      else
+ 	{
+-	  int expnt2 = u.d[1].ieee.exponent - lzcount;
+-	  if (expnt2 >= 1)
+-	    {
+-	      /* Not denormal.  Normalize and set low exponent.  */
+-	      lo = lo << lzcount;
+-	      u.d[1].ieee.exponent = expnt2;
+-	    }
++	  /* Is denormal.  Note that biased exponent of 0 is treated
++	     as if it was 1, hence the extra shift.  */
++	  if (expnt2 > -53)
++	    lo >>= 1 - expnt2;
+ 	  else
+-	    {
+-	      /* Is denormal.  */
+-	      lo = lo << (lzcount + expnt2);
+-	      u.d[1].ieee.exponent = 0;
+-	    }
++	    lo = 0;
+ 	}
+     }
+   else
+-    {
+-      u.d[1].ieee.negative = 0;
+-      u.d[1].ieee.exponent = 0;
+-    }
++    u.d[1].ieee.negative = 0;
+ 
+-  u.d[1].ieee.mantissa1 = lo & ((1ULL << 32) - 1);
+-  u.d[1].ieee.mantissa0 = (lo >> 32) & ((1ULL << 20) - 1);
+-  u.d[0].ieee.mantissa1 = hi & ((1ULL << 32) - 1);
+-  u.d[0].ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1);
++  u.d[1].ieee.mantissa1 = lo;
++  u.d[1].ieee.mantissa0 = lo >> 32;
++  u.d[0].ieee.mantissa1 = hi;
++  u.d[0].ieee.mantissa0 = hi >> 32;
+   return u.ld;
+ }
+   
+@@ -133,6 +170,10 @@
+   return u.ld;
+ }
+ 
++/* To suit our callers we return *hi64 and *lo64 as if they came from
++   an ieee854 112 bit mantissa, that is, 48 bits in *hi64 (plus one
++   implicit bit) and 64 bits in *lo64.  */
++
+ static inline void
+ default_ldbl_unpack (long double l, double *a, double *aa)
+ {
+@@ -162,13 +203,13 @@
+   *aa = xl;
+ }
+ 
+-/* Simple inline nearbyint (double) function .
++/* Simple inline nearbyint (double) function.
+    Only works in the default rounding mode
+    but is useful in long double rounding functions.  */
+ static inline double
+ ldbl_nearbyint (double a)
+ {
+-  double two52 = 0x10000000000000LL;
++  double two52 = 0x1p52;
+ 
+   if (__builtin_expect ((__builtin_fabs (a) < two52), 1))
+     {
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c	2014-05-27 19:13:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c	2014-05-27 19:14:45.000000000 -0500
+@@ -70,9 +70,9 @@
+       else
+ 	lzcount = __builtin_clzl ((long) val) + 32;
+       if (hi)
+-	lzcount = lzcount - 11;
++	lzcount = lzcount - (64 - 53);
+       else
+-	lzcount = lzcount + 42;
++	lzcount = lzcount + 53 - (64 - 53);
+ 
+       if (lzcount > u.d[0].ieee.exponent)
+ 	{
+@@ -98,29 +98,27 @@
+ 	}
+     }
+ 
+-  if (lo != 0L)
++  if (lo != 0)
+     {
+-      /* hidden2 bit of low double controls rounding of the high double.
+-	 If hidden2 is '1' and either the explicit mantissa is non-zero
++      /* hidden bit of low double controls rounding of the high double.
++	 If hidden is '1' and either the explicit mantissa is non-zero
+ 	 or hi is odd, then round up hi and adjust lo (2nd mantissa)
+ 	 plus change the sign of the low double to compensate.  */
+       if ((lo & (1LL << 52)) != 0
+-	  && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1))))
++	  && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)) != 0))
+ 	{
+ 	  hi++;
+-	  if ((hi & ((1LL << 52) - 1)) == 0)
++	  if ((hi & (1LL << 53)) != 0)
+ 	    {
+-	      if ((hi & (1LL << 53)) != 0)
+-		hi -= 1LL << 52;
++	      hi >>= 1;
+ 	      u.d[0].ieee.exponent++;
+ 	    }
+ 	  u.d[1].ieee.negative = !sign;
+ 	  lo = (1LL << 53) - lo;
+ 	}
+ 
+-      /* The hidden bit of the lo mantissa is zero so we need to normalize
+-	 it for the low double.  Shift it left until the hidden bit is '1'
+-	 then adjust the 2nd exponent accordingly.  */
++      /* Normalize the low double.  Shift the mantissa left until
++	 the hidden bit is '1' and adjust the exponent accordingly.  */
+ 
+       if (sizeof (lo) == sizeof (long))
+ 	lzcount = __builtin_clzl (lo);
+@@ -128,24 +126,24 @@
+ 	lzcount = __builtin_clzl ((long) (lo >> 32));
+       else
+ 	lzcount = __builtin_clzl ((long) lo) + 32;
+-      lzcount = lzcount - 11;
+-      if (lzcount > 0)
+-	{
+-	  lo = lo << lzcount;
+-	  exponent2 = exponent2 - lzcount;
+-	}
++      lzcount = lzcount - (64 - 53);
++      lo <<= lzcount;
++      exponent2 -= lzcount;
++
+       if (exponent2 > 0)
+ 	u.d[1].ieee.exponent = exponent2;
+-      else
++      else if (exponent2 > -53)
+ 	lo >>= 1 - exponent2;
++      else
++	lo = 0;
+     }
+   else
+     u.d[1].ieee.negative = 0;
+ 
+-  u.d[1].ieee.mantissa1 = lo & 0xffffffffLL;
+-  u.d[1].ieee.mantissa0 = (lo >> 32) & 0xfffff;
+-  u.d[0].ieee.mantissa1 = hi & 0xffffffffLL;
+-  u.d[0].ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1);
++  u.d[1].ieee.mantissa1 = lo;
++  u.d[1].ieee.mantissa0 = lo >> 32;
++  u.d[0].ieee.mantissa1 = hi;
++  u.d[0].ieee.mantissa0 = hi >> 32;
+ 
+   return u.ld;
+ }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2014-05-27 19:13:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2014-05-27 19:14:45.000000000 -0500
+@@ -43,15 +43,15 @@
+ 	lo <<= 1;							      \
+       /* The lower double is normalized separately from the upper.  We	      \
+ 	 may need to adjust the lower manitissa to reflect this.  */	      \
+-      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent;		      \
+-      if (ediff > 53 + 63)						      \
++      ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53;		      \
++      if (ediff > 63)							      \
+ 	lo = 0;								      \
+-      else if (ediff > 53)						      \
+-	lo = lo >> (ediff - 53);					      \
+-      else if (u.d[1].ieee.exponent == 0 && ediff < 53)			      \
+-	lo = lo << (53 - ediff);					      \
++      else if (ediff > 0)						      \
++	lo = lo >> ediff;						      \
++      else if (ediff < 0)						      \
++	lo = lo << -ediff;						      \
+       if (u.d[0].ieee.negative != u.d[1].ieee.negative			      \
+-	  && (u.d[1].ieee.exponent != 0 || lo != 0L))			      \
++	  && lo != 0)							      \
+ 	{								      \
+ 	  lo = (1ULL << 60) - lo;					      \
+ 	  if (hi == 0L)							      \
diff --git a/SOURCES/glibc-ppc64le-06.patch b/SOURCES/glibc-ppc64le-06.patch
new file mode 100644
index 0000000..9bdc8cc
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-06.patch
@@ -0,0 +1,652 @@
+# commit 1b6adf888de14675bc3207578dcb7132ed5f8ecc
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:21:58 2013 +0930
+# 
+#     PowerPC floating point little-endian [1 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00081.html
+#     
+#     This is the first of a series of patches to ban ieee854_long_double
+#     and the ieee854_long_double macros when using IBM long double.  union
+#     ieee854_long_double just isn't correct for IBM long double, especially
+#     when little-endian, and pretending it is OK has allowed a number of
+#     bugs to remain undetected in sysdeps/ieee754/ldbl-128ibm/.
+#     
+#     This changes the few places in generic code that use it.
+#     
+#         * stdio-common/printf_size.c (__printf_size): Don't use
+#         union ieee854_long_double in fpnum union.
+#         * stdio-common/printf_fphex.c (__printf_fphex): Likewise.  Use
+#         signbit macro to retrieve sign from long double.
+#         * stdio-common/printf_fp.c (___printf_fp): Use signbit macro to
+#         retrieve sign from long double.
+#         * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c: Adjust for fpnum change.
+#         * sysdeps/ieee754/ldbl-128/printf_fphex.c: Likewise.
+#         * sysdeps/ieee754/ldbl-96/printf_fphex.c: Likewise.
+#         * sysdeps/x86_64/fpu/printf_fphex.c: Likewise.
+#         * math/test-misc.c (main): Don't use union ieee854_long_double.
+#     ports/
+#         * sysdeps/ia64/fpu/printf_fphex.c: Adjust for fpnum change.
+# 
+diff -urN glibc-2.17-c758a686.orig/math/test-misc.c glibc-2.17-c758a686.diff/math/test-misc.c
+--- glibc-2.17-c758a686.orig/math/test-misc.c	2014-05-27 19:53:22.000000000 -0500
++++ glibc-2.17-c758a686.diff/math/test-misc.c	2014-05-27 19:53:45.000000000 -0500
+@@ -721,300 +721,161 @@
+ 
+ #ifndef NO_LONG_DOUBLE
+   {
+-    union ieee854_long_double v1;
+-    union ieee854_long_double v2;
+-    long double ld;
++    long double v1, v2;
+ 
+-    v1.d = ld = LDBL_MIN;
+-    if (fpclassify (ld) != FP_NORMAL)
++    v1 = LDBL_MIN;
++    if (fpclassify (v1) != FP_NORMAL)
+       {
+-	printf ("fpclassify (LDBL_MIN) failed: %d\n", fpclassify (ld));
++	printf ("fpclassify (LDBL_MIN) failed: %d (%La)\n",
++		fpclassify (v1), v1);
+ 	result = 1;
+       }
+-    ld = nextafterl (ld, LDBL_MIN / 2.0);
+-    if (fpclassify (ld) != FP_SUBNORMAL)
++    v2 = nextafterl (v1, LDBL_MIN / 2.0);
++    if (fpclassify (v2) != FP_SUBNORMAL)
+       {
+ 	printf ("fpclassify (LDBL_MIN-epsilon) failed: %d (%La)\n",
+-		fpclassify (ld), ld);
++		fpclassify (v2), v2);
+ 	result = 1;
+       }
+-    v2.d = ld = nextafterl (ld, LDBL_MIN);
+-    if (fpclassify (ld) != FP_NORMAL)
++    v2 = nextafterl (v2, LDBL_MIN);
++    if (fpclassify (v2) != FP_NORMAL)
+       {
+ 	printf ("fpclassify (LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n",
+-		fpclassify (ld), ld);
++		fpclassify (v2), v2);
+ 	result = 1;
+       }
+ 
+-    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
++    if (v1 != v2)
+       {
+-	printf ("LDBL_MIN: mantissa0 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa0, v2.ieee.mantissa0);
+-	result = 1;
+-      }
+-    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+-      {
+-	printf ("LDBL_MIN: mantissa1 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa1, v2.ieee.mantissa1);
+-	result = 1;
+-      }
+-    if (v1.ieee.exponent != v2.ieee.exponent)
+-      {
+-	printf ("LDBL_MIN: exponent differs: %4x vs %4x\n",
+-		v1.ieee.exponent, v2.ieee.exponent);
+-	result = 1;
+-      }
+-    if (v1.ieee.negative != v2.ieee.negative)
+-      {
+-	printf ("LDBL_MIN: negative differs: %d vs %d\n",
+-		v1.ieee.negative, v2.ieee.negative);
++	printf ("LDBL_MIN-epsilon+epsilon != LDBL_MIN: %La vs %La\n", v2, v1);
+ 	result = 1;
+       }
+ 
+-    v1.d = ld = -LDBL_MIN;
+-    if (fpclassify (ld) != FP_NORMAL)
++    v1 = -LDBL_MIN;
++    if (fpclassify (v1) != FP_NORMAL)
+       {
+-	printf ("fpclassify (-LDBL_MIN) failed: %d\n", fpclassify (ld));
++	printf ("fpclassify (-LDBL_MIN) failed: %d (%La)\n",
++		fpclassify (v1), v1);
+ 	result = 1;
+       }
+-    ld = nextafterl (ld, -LDBL_MIN / 2.0);
+-    if (fpclassify (ld) != FP_SUBNORMAL)
++    v2 = nextafterl (v1, -LDBL_MIN / 2.0);
++    if (fpclassify (v2) != FP_SUBNORMAL)
+       {
+ 	printf ("fpclassify (-LDBL_MIN-epsilon) failed: %d (%La)\n",
+-		fpclassify (ld), ld);
++		fpclassify (v2), v2);
+ 	result = 1;
+       }
+-    v2.d = ld = nextafterl (ld, -LDBL_MIN);
+-    if (fpclassify (ld) != FP_NORMAL)
++    v2 = nextafterl (v2, -LDBL_MIN);
++    if (fpclassify (v2) != FP_NORMAL)
+       {
+ 	printf ("fpclassify (-LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n",
+-		fpclassify (ld), ld);
++		fpclassify (v2), v2);
+ 	result = 1;
+       }
+ 
+-    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
++    if (v1 != v2)
+       {
+-	printf ("-LDBL_MIN: mantissa0 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa0, v2.ieee.mantissa0);
+-	result = 1;
+-      }
+-    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+-      {
+-	printf ("-LDBL_MIN: mantissa1 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa1, v2.ieee.mantissa1);
+-	result = 1;
+-      }
+-    if (v1.ieee.exponent != v2.ieee.exponent)
+-      {
+-	printf ("-LDBL_MIN: exponent differs: %4x vs %4x\n",
+-		v1.ieee.exponent, v2.ieee.exponent);
+-	result = 1;
+-      }
+-    if (v1.ieee.negative != v2.ieee.negative)
+-      {
+-	printf ("-LDBL_MIN: negative differs: %d vs %d\n",
+-		v1.ieee.negative, v2.ieee.negative);
++	printf ("-LDBL_MIN-epsilon+epsilon != -LDBL_MIN: %La vs %La\n", v2, v1);
+ 	result = 1;
+       }
+ 
+-    ld = LDBL_MAX;
+-    if (fpclassify (ld) != FP_NORMAL)
++    v1 = LDBL_MAX;
++    if (fpclassify (v1) != FP_NORMAL)
+       {
+-	printf ("fpclassify (LDBL_MAX) failed: %d\n", fpclassify (ld));
++	printf ("fpclassify (LDBL_MAX) failed: %d (%La)\n",
++		fpclassify (v1), v1);
+ 	result = 1;
+       }
+-    ld = nextafterl (ld, INFINITY);
+-    if (fpclassify (ld) != FP_INFINITE)
++    v2 = nextafterl (v1, INFINITY);
++    if (fpclassify (v2) != FP_INFINITE)
+       {
+-	printf ("fpclassify (LDBL_MAX+epsilon) failed: %d\n", fpclassify (ld));
++	printf ("fpclassify (LDBL_MAX+epsilon) failed: %d (%La)\n",
++		fpclassify (v2), v2);
+ 	result = 1;
+       }
+ 
+-    ld = -LDBL_MAX;
+-    if (fpclassify (ld) != FP_NORMAL)
++    v1 = -LDBL_MAX;
++    if (fpclassify (v1) != FP_NORMAL)
+       {
+-	printf ("fpclassify (-LDBL_MAX) failed: %d\n", fpclassify (ld));
++	printf ("fpclassify (-LDBL_MAX) failed: %d (%La)\n",
++		fpclassify (v1), v1);
+ 	result = 1;
+       }
+-    ld = nextafterl (ld, -INFINITY);
+-    if (fpclassify (ld) != FP_INFINITE)
++    v2 = nextafterl (v1, -INFINITY);
++    if (fpclassify (v2) != FP_INFINITE)
+       {
+-	printf ("fpclassify (-LDBL_MAX-epsilon) failed: %d\n",
+-		fpclassify (ld));
++	printf ("fpclassify (-LDBL_MAX-epsilon) failed: %d (%La)\n",
++		fpclassify (v2), v2);
+ 	result = 1;
+       }
+ 
+-    v1.d = ld = 0.0625;
+-    ld = nextafterl (ld, 0.0);
+-    v2.d = ld = nextafterl (ld, 1.0);
++    v1 = 0.0625;
++    v2 = nextafterl (v1, 0.0);
++    v2 = nextafterl (v2, 1.0);
+ 
+-    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+-      {
+-	printf ("0.0625L down: mantissa0 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa0, v2.ieee.mantissa0);
+-	result = 1;
+-      }
+-    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+-      {
+-	printf ("0.0625L down: mantissa1 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa1, v2.ieee.mantissa1);
+-	result = 1;
+-      }
+-    if (v1.ieee.exponent != v2.ieee.exponent)
+-      {
+-	printf ("0.0625L down: exponent differs: %4x vs %4x\n",
+-		v1.ieee.exponent, v2.ieee.exponent);
+-	result = 1;
+-      }
+-    if (v1.ieee.negative != v2.ieee.negative)
++    if (v1 != v2)
+       {
+-	printf ("0.0625L down: negative differs: %d vs %d\n",
+-		v1.ieee.negative, v2.ieee.negative);
++	printf ("0.0625L-epsilon+epsilon != 0.0625L: %La vs %La\n", v2, v1);
+ 	result = 1;
+       }
+ 
+-    v1.d = ld = 0.0625;
+-    ld = nextafterl (ld, 1.0);
+-    v2.d = ld = nextafterl (ld, 0.0);
++    v1 = 0.0625;
++    v2 = nextafterl (v1, 1.0);
++    v2 = nextafterl (v2, 0.0);
+ 
+-    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+-      {
+-	printf ("0.0625L up: mantissa0 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa0, v2.ieee.mantissa0);
+-	result = 1;
+-      }
+-    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+-      {
+-	printf ("0.0625L up: mantissa1 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa1, v2.ieee.mantissa1);
+-	result = 1;
+-      }
+-    if (v1.ieee.exponent != v2.ieee.exponent)
++    if (v1 != v2)
+       {
+-	printf ("0.0625L up: exponent differs: %4x vs %4x\n",
+-		v1.ieee.exponent, v2.ieee.exponent);
+-	result = 1;
+-      }
+-    if (v1.ieee.negative != v2.ieee.negative)
+-      {
+-	printf ("0.0625L up: negative differs: %d vs %d\n",
+-		v1.ieee.negative, v2.ieee.negative);
++	printf ("0.0625L+epsilon-epsilon != 0.0625L: %La vs %La\n", v2, v1);
+ 	result = 1;
+       }
+ 
+-    v1.d = ld = -0.0625;
+-    ld = nextafterl (ld, 0.0);
+-    v2.d = ld = nextafterl (ld, -1.0);
++    v1 = -0.0625;
++    v2 = nextafterl (v1, 0.0);
++    v2 = nextafterl (v2, -1.0);
+ 
+-    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+-      {
+-	printf ("-0.0625L up: mantissa0 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa0, v2.ieee.mantissa0);
+-	result = 1;
+-      }
+-    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+-      {
+-	printf ("-0.0625L up: mantissa1 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa1, v2.ieee.mantissa1);
+-	result = 1;
+-      }
+-    if (v1.ieee.exponent != v2.ieee.exponent)
++    if (v1 != v2)
+       {
+-	printf ("-0.0625L up: exponent differs: %4x vs %4x\n",
+-		v1.ieee.exponent, v2.ieee.exponent);
+-	result = 1;
+-      }
+-    if (v1.ieee.negative != v2.ieee.negative)
+-      {
+-	printf ("-0.0625L up: negative differs: %d vs %d\n",
+-		v1.ieee.negative, v2.ieee.negative);
++	printf ("-0.0625L+epsilon-epsilon != -0.0625L: %La vs %La\n", v2, v1);
+ 	result = 1;
+       }
+ 
+-    v1.d = ld = -0.0625;
+-    ld = nextafterl (ld, -1.0);
+-    v2.d = ld = nextafterl (ld, 0.0);
++    v1 = -0.0625;
++    v2 = nextafterl (v1, -1.0);
++    v2 = nextafterl (v2, 0.0);
+ 
+-    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+-      {
+-	printf ("-0.0625L down: mantissa0 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa0, v2.ieee.mantissa0);
+-	result = 1;
+-      }
+-    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
++    if (v1 != v2)
+       {
+-	printf ("-0.0625L down: mantissa1 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa1, v2.ieee.mantissa1);
+-	result = 1;
+-      }
+-    if (v1.ieee.exponent != v2.ieee.exponent)
+-      {
+-	printf ("-0.0625L down: exponent differs: %4x vs %4x\n",
+-		v1.ieee.exponent, v2.ieee.exponent);
+-	result = 1;
+-      }
+-    if (v1.ieee.negative != v2.ieee.negative)
+-      {
+-	printf ("-0.0625L down: negative differs: %d vs %d\n",
+-		v1.ieee.negative, v2.ieee.negative);
++	printf ("-0.0625L-epsilon+epsilon != -0.0625L: %La vs %La\n", v2, v1);
+ 	result = 1;
+       }
+ 
+-    v1.d = ld = 0.0;
+-    ld = nextafterl (ld, 1.0);
+-    v2.d = nextafterl (ld, -1.0);
++    v1 = 0.0;
++    v2 = nextafterl (v1, 1.0);
++    v2 = nextafterl (v2, -1.0);
+ 
+-    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+-      {
+-	printf ("0.0L up: mantissa0 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa0, v2.ieee.mantissa0);
+-	result = 1;
+-      }
+-    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+-      {
+-	printf ("0.0L up: mantissa1 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa1, v2.ieee.mantissa1);
+-	result = 1;
+-      }
+-    if (v1.ieee.exponent != v2.ieee.exponent)
++    if (v1 != v2)
+       {
+-	printf ("0.0L up: exponent differs: %4x vs %4x\n",
+-		v1.ieee.exponent, v2.ieee.exponent);
++	printf ("0.0+epsilon-epsilon != 0.0L: %La vs %La\n", v2, v1);
+ 	result = 1;
+       }
+-    if (0 != v2.ieee.negative)
++    if (signbit (v2))
+       {
+-	printf ("0.0L up: negative differs: 0 vs %d\n",
+-		v2.ieee.negative);
++	printf ("0.0+epsilon-epsilon is negative\n");
+ 	result = 1;
+       }
+ 
+-    v1.d = ld = 0.0;
+-    ld = nextafterl (ld, -1.0);
+-    v2.d = nextafterl (ld, 1.0);
++    v1 = 0.0;
++    v2 = nextafterl (v1, -1.0);
++    v2 = nextafterl (v2, 1.0);
+ 
+-    if (v1.ieee.mantissa0 != v2.ieee.mantissa0)
+-      {
+-	printf ("0.0L down: mantissa0 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa0, v2.ieee.mantissa0);
+-	result = 1;
+-      }
+-    if (v1.ieee.mantissa1 != v2.ieee.mantissa1)
+-      {
+-	printf ("0.0L down: mantissa1 differs: %8x vs %8x\n",
+-		v1.ieee.mantissa1, v2.ieee.mantissa1);
+-	result = 1;
+-      }
+-    if (v1.ieee.exponent != v2.ieee.exponent)
++    if (v1 != v2)
+       {
+-	printf ("0.0L down: exponent differs: %4x vs %4x\n",
+-		v1.ieee.exponent, v2.ieee.exponent);
++	printf ("0.0-epsilon+epsilon != 0.0L: %La vs %La\n", v2, v1);
+ 	result = 1;
+       }
+-    if (1 != v2.ieee.negative)
++    if (!signbit (v2))
+       {
+-	printf ("0.0L down: negative differs: 1 vs %d\n",
+-		v2.ieee.negative);
++	printf ("0.0-epsilon+epsilon is positive\n");
+ 	result = 1;
+       }
+ 
+diff -urN glibc-2.17-c758a686.orig/ports/sysdeps/ia64/fpu/printf_fphex.c glibc-2.17-c758a686.diff/ports/sysdeps/ia64/fpu/printf_fphex.c
+--- glibc-2.17-c758a686.orig/ports/sysdeps/ia64/fpu/printf_fphex.c	2014-05-27 19:53:21.000000000 -0500
++++ glibc-2.17-c758a686.diff/ports/sysdeps/ia64/fpu/printf_fphex.c	2014-05-27 19:53:45.000000000 -0500
+@@ -25,9 +25,11 @@
+       /* The "strange" 80 bit format on ia64 has an explicit		      \
+ 	 leading digit in the 64 bit mantissa.  */			      \
+       unsigned long long int num;					      \
++      union ieee854_long_double u;					      \
++      u.d = fpnum.ldbl;							      \
+ 									      \
+-      num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32	      \
+-	     | fpnum.ldbl.ieee.mantissa1);				      \
++      num = (((unsigned long long int) u.ieee.mantissa0) << 32		      \
++	     | u.ieee.mantissa1);					      \
+ 									      \
+       zero_mantissa = num == 0;						      \
+ 									      \
+@@ -49,8 +51,8 @@
+ 									      \
+       /* We have 3 bits from the mantissa in the leading nibble.	      \
+ 	 Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'.  */      \
+-      exponent = fpnum.ldbl.ieee.exponent;				      \
+-									     \
++      exponent = u.ieee.exponent;					      \
++									      \
+       if (exponent == 0)						      \
+ 	{								      \
+ 	  if (zero_mantissa)						      \
+diff -urN glibc-2.17-c758a686.orig/stdio-common/printf_fp.c glibc-2.17-c758a686.diff/stdio-common/printf_fp.c
+--- glibc-2.17-c758a686.orig/stdio-common/printf_fp.c	2014-05-27 19:53:22.000000000 -0500
++++ glibc-2.17-c758a686.diff/stdio-common/printf_fp.c	2014-05-27 19:53:45.000000000 -0500
+@@ -335,8 +335,7 @@
+       int res;
+       if (__isnanl (fpnum.ldbl))
+ 	{
+-	  union ieee854_long_double u = { .d = fpnum.ldbl };
+-	  is_neg = u.ieee.negative != 0;
++	  is_neg = signbit (fpnum.ldbl);
+ 	  if (isupper (info->spec))
+ 	    {
+ 	      special = "NAN";
+diff -urN glibc-2.17-c758a686.orig/stdio-common/printf_fphex.c glibc-2.17-c758a686.diff/stdio-common/printf_fphex.c
+--- glibc-2.17-c758a686.orig/stdio-common/printf_fphex.c	2014-05-27 19:53:22.000000000 -0500
++++ glibc-2.17-c758a686.diff/stdio-common/printf_fphex.c	2014-05-27 19:53:45.000000000 -0500
+@@ -93,7 +93,7 @@
+   union
+     {
+       union ieee754_double dbl;
+-      union ieee854_long_double ldbl;
++      long double ldbl;
+     }
+   fpnum;
+ 
+@@ -162,12 +162,11 @@
+ #ifndef __NO_LONG_DOUBLE_MATH
+   if (info->is_long_double && sizeof (long double) > sizeof (double))
+     {
+-      fpnum.ldbl.d = *(const long double *) args[0];
++      fpnum.ldbl = *(const long double *) args[0];
+ 
+       /* Check for special values: not a number or infinity.  */
+-      if (__isnanl (fpnum.ldbl.d))
++      if (__isnanl (fpnum.ldbl))
+ 	{
+-	  negative = fpnum.ldbl.ieee.negative != 0;
+ 	  if (isupper (info->spec))
+ 	    {
+ 	      special = "NAN";
+@@ -181,8 +180,7 @@
+ 	}
+       else
+ 	{
+-	  int res = __isinfl (fpnum.ldbl.d);
+-	  if (res)
++	  if (__isinfl (fpnum.ldbl))
+ 	    {
+ 	      if (isupper (info->spec))
+ 		{
+@@ -194,11 +192,9 @@
+ 		  special = "inf";
+ 		  wspecial = L"inf";
+ 		}
+-	      negative = res < 0;
+ 	    }
+-	  else
+-	    negative = signbit (fpnum.ldbl.d);
+ 	}
++      negative = signbit (fpnum.ldbl);
+     }
+   else
+ #endif	/* no long double */
+diff -urN glibc-2.17-c758a686.orig/stdio-common/printf_size.c glibc-2.17-c758a686.diff/stdio-common/printf_size.c
+--- glibc-2.17-c758a686.orig/stdio-common/printf_size.c	2014-05-27 19:53:22.000000000 -0500
++++ glibc-2.17-c758a686.diff/stdio-common/printf_size.c	2014-05-27 19:53:45.000000000 -0500
+@@ -103,7 +103,7 @@
+   union
+     {
+       union ieee754_double dbl;
+-      union ieee854_long_double ldbl;
++      long double ldbl;
+     }
+   fpnum;
+   const void *ptr = &fpnum;
+@@ -123,25 +123,25 @@
+ #ifndef __NO_LONG_DOUBLE_MATH
+   if (info->is_long_double && sizeof (long double) > sizeof (double))
+     {
+-      fpnum.ldbl.d = *(const long double *) args[0];
++      fpnum.ldbl = *(const long double *) args[0];
+ 
+       /* Check for special values: not a number or infinity.  */
+-      if (__isnanl (fpnum.ldbl.d))
++      if (__isnanl (fpnum.ldbl))
+ 	{
+ 	  special = "nan";
+ 	  wspecial = L"nan";
+ 	  // fpnum_sign = 0;	Already zero
+ 	}
+-      else if ((res = __isinfl (fpnum.ldbl.d)))
++      else if ((res = __isinfl (fpnum.ldbl)))
+ 	{
+ 	  fpnum_sign = res;
+ 	  special = "inf";
+ 	  wspecial = L"inf";
+ 	}
+       else
+-	while (fpnum.ldbl.d >= divisor && tag[1] != '\0')
++	while (fpnum.ldbl >= divisor && tag[1] != '\0')
+ 	  {
+-	    fpnum.ldbl.d /= divisor;
++	    fpnum.ldbl /= divisor;
+ 	    ++tag;
+ 	  }
+     }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128/printf_fphex.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128/printf_fphex.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128/printf_fphex.c	2014-05-27 19:53:20.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128/printf_fphex.c	2014-05-27 19:53:45.000000000 -0500
+@@ -24,13 +24,15 @@
+ 	 digits we use only the implicit digits for the number before	      \
+ 	 the decimal point.  */						      \
+       unsigned long long int num0, num1;				      \
++      union ieee854_long_double u;					      \
++      u.d = fpnum.ldbl;							      \
+ 									      \
+       assert (sizeof (long double) == 16);				      \
+ 									      \
+-      num0 = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32      \
+-	     | fpnum.ldbl.ieee.mantissa1);				      \
+-      num1 = (((unsigned long long int) fpnum.ldbl.ieee.mantissa2) << 32      \
+-	     | fpnum.ldbl.ieee.mantissa3);				      \
++      num0 = (((unsigned long long int) u.ieee.mantissa0) << 32		      \
++	     | u.ieee.mantissa1);					      \
++      num1 = (((unsigned long long int) u.ieee.mantissa2) << 32		      \
++	     | u.ieee.mantissa3);					      \
+ 									      \
+       zero_mantissa = (num0|num1) == 0;					      \
+ 									      \
+@@ -75,9 +77,9 @@
+ 	  *--wnumstr = L'0';						      \
+ 	}								      \
+ 									      \
+-      leading = fpnum.ldbl.ieee.exponent == 0 ? '0' : '1';		      \
++      leading = u.ieee.exponent == 0 ? '0' : '1';			      \
+ 									      \
+-      exponent = fpnum.ldbl.ieee.exponent;				      \
++      exponent = u.ieee.exponent;					      \
+ 									      \
+       if (exponent == 0)						      \
+ 	{								      \
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2014-05-27 19:53:20.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c	2014-05-27 19:53:45.000000000 -0500
+@@ -28,14 +28,14 @@
+       unsigned long long hi, lo;					      \
+       int ediff;							      \
+       union ibm_extended_long_double u;					      \
+-      u.ld = fpnum.ldbl.d;						      \
++      u.ld = fpnum.ldbl;						      \
+ 									      \
+       assert (sizeof (long double) == 16);				      \
+ 									      \
+       lo = ((long long)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1;  \
+       hi = ((long long)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1;  \
+       lo <<= 7; /* pre-shift lo to match ieee854.  */			      \
+-      /* If the lower double is not a denomal or zero then set the hidden     \
++      /* If the lower double is not a denormal or zero then set the hidden    \
+ 	 53rd bit.  */							      \
+       if (u.d[1].ieee.exponent != 0)					      \
+ 	lo |= (1ULL << (52 + 7));					      \
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-96/printf_fphex.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-96/printf_fphex.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-96/printf_fphex.c	2014-05-27 19:53:20.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-96/printf_fphex.c	2014-05-27 19:53:45.000000000 -0500
+@@ -25,11 +25,13 @@
+       /* The "strange" 80 bit format on ix86 and m68k has an explicit	      \
+ 	 leading digit in the 64 bit mantissa.  */			      \
+       unsigned long long int num;					      \
++      union ieee854_long_double u;					      \
++      u.d = fpnum.ldbl;							      \
+ 									      \
+       assert (sizeof (long double) == 12);				      \
+ 									      \
+-      num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32	      \
+-	     | fpnum.ldbl.ieee.mantissa1);				      \
++      num = (((unsigned long long int) u.ieee.mantissa0) << 32		      \
++	     | u.ieee.mantissa1);					      \
+ 									      \
+       zero_mantissa = num == 0;						      \
+ 									      \
+@@ -62,7 +64,7 @@
+ 									      \
+       /* We have 3 bits from the mantissa in the leading nibble.	      \
+ 	 Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'.  */      \
+-      exponent = fpnum.ldbl.ieee.exponent;				      \
++      exponent = u.ieee.exponent;					      \
+ 									      \
+       if (exponent == 0)						      \
+ 	{								      \
+diff -urN glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/printf_fphex.c glibc-2.17-c758a686.diff/sysdeps/x86_64/fpu/printf_fphex.c
+--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/printf_fphex.c	2014-05-27 19:53:20.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/x86_64/fpu/printf_fphex.c	2014-05-27 19:53:45.000000000 -0500
+@@ -25,10 +25,11 @@
+       /* The "strange" 80 bit format on ix86 and m68k has an explicit	      \
+ 	 leading digit in the 64 bit mantissa.  */			      \
+       unsigned long long int num;					      \
++      union ieee854_long_double u;					      \
++      u.d = fpnum.ldbl;							      \
+ 									      \
+-									      \
+-      num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32	      \
+-	     | fpnum.ldbl.ieee.mantissa1);				      \
++      num = (((unsigned long long int) u.ieee.mantissa0) << 32		      \
++	     | u.ieee.mantissa1);					      \
+ 									      \
+       zero_mantissa = num == 0;						      \
+ 									      \
+@@ -61,7 +62,7 @@
+ 									      \
+       /* We have 3 bits from the mantissa in the leading nibble.	      \
+ 	 Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'.  */      \
+-      exponent = fpnum.ldbl.ieee.exponent;				      \
++      exponent = u.ieee.exponent;					      \
+ 									      \
+       if (exponent == 0)						      \
+ 	{								      \
diff --git a/SOURCES/glibc-ppc64le-07.patch b/SOURCES/glibc-ppc64le-07.patch
new file mode 100644
index 0000000..2185d36
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-07.patch
@@ -0,0 +1,651 @@
+# commit 4ebd120cd983c8d2ac7a234884b3ac6805d82973
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:24:05 2013 +0930
+# 
+#     PowerPC floating point little-endian [2 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00082.html
+#     
+#     This patch replaces occurrences of GET_LDOUBLE_* and SET_LDOUBLE_*
+#     macros, and union ieee854_long_double_shape_type in ldbl-128ibm/,
+#     and a stray one in the 32-bit fpu support.  These files have no
+#     significant changes apart from rewriting the long double bit access.
+#     
+#         * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h (ldbl_high): Define.
+#         * sysdeps/ieee754/ldbl-128ibm/e_acoshl.c (__ieee754_acoshl): Rewrite
+#         all uses of ieee854 long double macros and unions.
+#         * sysdeps/ieee754/ldbl-128ibm/e_acosl.c (__ieee754_acosl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_asinl.c (__ieee754_asinl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_atanhl.c (__ieee754_atanhl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_coshl.c (__ieee754_coshl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_log2l.c (__ieee754_log2l): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c (__ieee754_rem_pio2l):
+#         Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_sinhl.c (__ieee754_sinhl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/k_cosl.c (__kernel_cosl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/k_sincosl.c (__kernel_sincosl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/k_sinl.c (__kernel_sinl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_asinhl.c (__asinhl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_atanl.c (__atanl): Likewise.
+#         Simplify sign and nan test too.
+#         * sysdeps/ieee754/ldbl-128ibm/s_cosl.c (__cosl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_fabsl.c (__fabsl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_finitel.c (___finitel): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c (___fpclassifyl):
+#         Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_isnanl.c (___isnanl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c (__issignalingl):
+#         Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_logbl.c (__logbl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_signbitl.c (___signbitl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_sincosl.c (__sincosl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_sinl.c (__sinl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_tanl.c (__tanl): Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c (__logbl): Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -36,8 +36,12 @@
+ {
+ 	long double t;
+ 	int64_t hx;
+-	u_int64_t lx;
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
++	uint64_t lx;
++	double xhi, xlo;
++
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
+ 	if(hx<0x3ff0000000000000LL) {		/* x < 1 */
+ 	    return (x-x)/(x-x);
+ 	} else if(hx >=0x41b0000000000000LL) {	/* x > 2**28 */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_acosl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_acosl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_acosl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_acosl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -151,26 +151,25 @@
+ long double
+ __ieee754_acosl (long double x)
+ {
+-  long double z, r, w, p, q, s, t, f2;
+-  ieee854_long_double_shape_type u;
++  long double a, z, r, w, p, q, s, t, f2;
+ 
+-  u.value = __builtin_fabsl (x);
+-  if (u.value == 1.0L)
++  a = __builtin_fabsl (x);
++  if (a == 1.0L)
+     {
+       if (x > 0.0L)
+ 	return 0.0;		/* acos(1) = 0  */
+       else
+ 	return (2.0 * pio2_hi) + (2.0 * pio2_lo);	/* acos(-1)= pi */
+     }
+-  else if (u.value > 1.0L)
++  else if (a > 1.0L)
+     {
+       return (x - x) / (x - x);	/* acos(|x| > 1) is NaN */
+     }
+-  if (u.value < 0.5L)
++  if (a < 0.5L)
+     {
+-      if (u.value < 6.938893903907228e-18L)	/* |x| < 2**-57 */
++      if (a < 6.938893903907228e-18L)	/* |x| < 2**-57 */
+ 	return pio2_hi + pio2_lo;
+-      if (u.value < 0.4375L)
++      if (a < 0.4375L)
+ 	{
+ 	  /* Arcsine of x.  */
+ 	  z = x * x;
+@@ -199,7 +198,7 @@
+ 	  return z;
+ 	}
+       /* .4375 <= |x| < .5 */
+-      t = u.value - 0.4375L;
++      t = a - 0.4375L;
+       p = ((((((((((P10 * t
+ 		    + P9) * t
+ 		   + P8) * t
+@@ -230,9 +229,9 @@
+ 	r = acosr4375 + r;
+       return r;
+     }
+-  else if (u.value < 0.625L)
++  else if (a < 0.625L)
+     {
+-      t = u.value - 0.5625L;
++      t = a - 0.5625L;
+       p = ((((((((((rS10 * t
+ 		    + rS9) * t
+ 		   + rS8) * t
+@@ -264,7 +263,9 @@
+     }
+   else
+     {				/* |x| >= .625 */
+-      z = (one - u.value) * 0.5;
++      double shi, slo;
++
++      z = (one - a) * 0.5;
+       s = __ieee754_sqrtl (z);
+       /* Compute an extended precision square root from
+ 	 the Newton iteration  s -> 0.5 * (s + z / s).
+@@ -273,12 +274,11 @@
+ 	  Express s = f1 + f2 where f1 * f1 is exactly representable.
+ 	  w = (z - s^2)/2s = (z - f1^2 - 2 f1 f2 - f2^2)/2s .
+ 	  s + w has extended precision.  */
+-      u.value = s;
+-      u.parts32.w2 = 0;
+-      u.parts32.w3 = 0;
+-      f2 = s - u.value;
+-      w = z - u.value * u.value;
+-      w = w - 2.0 * u.value * f2;
++      ldbl_unpack (s, &shi, &slo);
++      a = shi;
++      f2 = slo;
++      w = z - a * a;
++      w = w - 2.0 * a * f2;
+       w = w - f2 * f2;
+       w = w / (2.0 * s);
+       /* Arcsine of s.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_asinl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_asinl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_asinl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_asinl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -131,19 +131,18 @@
+ long double
+ __ieee754_asinl (long double x)
+ {
+-  long double t, w, p, q, c, r, s;
++  long double a, t, w, p, q, c, r, s;
+   int flag;
+-  ieee854_long_double_shape_type u;
+ 
+   flag = 0;
+-  u.value = __builtin_fabsl (x);
+-  if (u.value == 1.0L)	/* |x|>= 1 */
++  a = __builtin_fabsl (x);
++  if (a == 1.0L)	/* |x|>= 1 */
+     return x * pio2_hi + x * pio2_lo;	/* asin(1)=+-pi/2 with inexact */
+-  else if (u.value >= 1.0L)
++  else if (a >= 1.0L)
+     return (x - x) / (x - x);	/* asin(|x|>1) is NaN */
+-  else if (u.value < 0.5L)
++  else if (a < 0.5L)
+     {
+-      if (u.value < 6.938893903907228e-18L) /* |x| < 2**-57 */
++      if (a < 6.938893903907228e-18L) /* |x| < 2**-57 */
+ 	{
+ 	  if (huge + x > one)
+ 	    return x;		/* return x with inexact if x!=0 */
+@@ -155,9 +154,9 @@
+ 	  flag = 1;
+ 	}
+     }
+-  else if (u.value < 0.625L)
++  else if (a < 0.625L)
+     {
+-      t = u.value - 0.5625;
++      t = a - 0.5625;
+       p = ((((((((((rS10 * t
+ 		    + rS9) * t
+ 		   + rS8) * t
+@@ -190,7 +189,7 @@
+   else
+     {
+       /* 1 > |x| >= 0.625 */
+-      w = one - u.value;
++      w = one - a;
+       t = w * 0.5;
+     }
+ 
+@@ -223,17 +222,14 @@
+     }
+ 
+   s = __ieee754_sqrtl (t);
+-  if (u.value > 0.975L)
++  if (a > 0.975L)
+     {
+       w = p / q;
+       t = pio2_hi - (2.0 * (s + s * w) - pio2_lo);
+     }
+   else
+     {
+-      u.value = s;
+-      u.parts32.w3 = 0;
+-      u.parts32.w2 = 0;
+-      w = u.value;
++      w = ldbl_high (s);
+       c = (t - w * w) / (s + w);
+       r = p / q;
+       p = 2.0 * s * r - (pio2_lo - 2.0 * c);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -40,8 +40,10 @@
+ {
+ 	long double t;
+ 	int64_t hx,ix;
+-	u_int64_t lx __attribute__ ((unused));
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
++	double xhi;
++
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (hx, xhi);
+ 	ix = hx&0x7fffffffffffffffLL;
+ 	if (ix >= 0x3ff0000000000000LL) { /* |x|>=1 */
+ 	    if (ix > 0x3ff0000000000000LL)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_coshl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_coshl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_coshl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_coshl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -41,9 +41,11 @@
+ {
+ 	long double t,w;
+ 	int64_t ix;
++	double xhi;
+ 
+     /* High word of |x|. */
+-	GET_LDOUBLE_MSW64(ix,x);
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (ix, xhi);
+ 	ix &= 0x7fffffffffffffffLL;
+ 
+     /* x is INF or NaN */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_log2l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_log2l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_log2l.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_log2l.c	2014-05-27 19:59:00.000000000 -0500
+@@ -177,11 +177,13 @@
+   long double z;
+   long double y;
+   int e;
+-  int64_t hx, lx;
++  int64_t hx;
++  double xhi;
+ 
+ /* Test for domain */
+-  GET_LDOUBLE_WORDS64 (hx, lx, x);
+-  if (((hx & 0x7fffffffffffffffLL) | (lx & 0x7fffffffffffffffLL)) == 0)
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
++  if ((hx & 0x7fffffffffffffffLL) == 0)
+     return (-1.0L / (x - x));
+   if (hx < 0)
+     return (x - x) / (x - x);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c	2014-05-27 19:59:00.000000000 -0500
+@@ -200,10 +200,11 @@
+   double tx[8];
+   int exp;
+   int64_t n, ix, hx, ixd;
+-  u_int64_t lx __attribute__ ((unused));
+   u_int64_t lxd;
++  double xhi;
+ 
+-  GET_LDOUBLE_WORDS64 (hx, lx, x);
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
+   ix = hx & 0x7fffffffffffffffLL;
+   if (ix <= 0x3fe921fb54442d10LL)	/* x in <-pi/4, pi/4> */
+     {
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -38,9 +38,11 @@
+ {
+ 	long double t,w,h;
+ 	int64_t ix,jx;
++	double xhi;
+ 
+     /* High word of |x|. */
+-	GET_LDOUBLE_MSW64(jx,x);
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (jx, xhi);
+ 	ix = jx&0x7fffffffffffffffLL;
+ 
+     /* x is INF or NaN */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/k_cosl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/k_cosl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/k_cosl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/k_cosl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -81,8 +81,11 @@
+ {
+   long double h, l, z, sin_l, cos_l_m1;
+   int64_t ix;
+-  u_int32_t tix, hix, index;
+-  GET_LDOUBLE_MSW64 (ix, x);
++  uint32_t tix, hix, index;
++  double xhi, hhi;
++
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (ix, xhi);
+   tix = ((u_int64_t)ix) >> 32;
+   tix &= ~0x80000000;			/* tix = |x|'s high 32 bits */
+   if (tix < 0x3fc30000)			/* |x| < 0.1484375 */
+@@ -136,7 +139,8 @@
+ 	case 2: index = (hix - 0x3fc30000) >> 14; break;
+ 	}
+ */
+-      SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
++      INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32);
++      h = hhi;
+       l = y - (h - x);
+       z = l * l;
+       sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -100,9 +100,12 @@
+ {
+   long double h, l, z, sin_l, cos_l_m1;
+   int64_t ix;
+-  u_int32_t tix, hix, index;
+-  GET_LDOUBLE_MSW64 (ix, x);
+-  tix = ((u_int64_t)ix) >> 32;
++  uint32_t tix, hix, index;
++  double xhi, hhi;
++
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (ix, xhi);
++  tix = ((uint64_t)ix) >> 32;
+   tix &= ~0x80000000;			/* tix = |x|'s high 32 bits */
+   if (tix < 0x3fc30000)			/* |x| < 0.1484375 */
+     {
+@@ -164,7 +167,8 @@
+ 	case 2: index = (hix - 0x3fc30000) >> 14; break;
+ 	}
+ */
+-      SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
++      INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32);
++      h = hhi;
+       if (iy)
+ 	l = y - (h - x);
+       else
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/k_sinl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/k_sinl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/k_sinl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/k_sinl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -82,7 +82,10 @@
+   long double h, l, z, sin_l, cos_l_m1;
+   int64_t ix;
+   u_int32_t tix, hix, index;
+-  GET_LDOUBLE_MSW64 (ix, x);
++  double xhi, hhi;
++
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (ix, xhi);
+   tix = ((u_int64_t)ix) >> 32;
+   tix &= ~0x80000000;			/* tix = |x|'s high 32 bits */
+   if (tix < 0x3fc30000)			/* |x| < 0.1484375 */
+@@ -132,7 +135,8 @@
+ 	case 2: index = (hix - 0x3fc30000) >> 14; break;
+ 	}
+ */
+-      SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
++      INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32);
++      h = hhi;
+       if (iy)
+ 	l = (ix < 0 ? -y : y) - (h - x);
+       else
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -38,7 +38,10 @@
+ {
+ 	long double t,w;
+ 	int64_t hx,ix;
+-	GET_LDOUBLE_MSW64(hx,x);
++	double xhi;
++
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (hx, xhi);
+ 	ix = hx&0x7fffffffffffffffLL;
+ 	if(ix>=0x7ff0000000000000LL) return x+x;	/* x is inf or NaN */
+ 	if(ix< 0x3e20000000000000LL) {	/* |x|<2**-29 */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_atanl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_atanl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_atanl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_atanl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -173,23 +173,20 @@
+ long double
+ __atanl (long double x)
+ {
+-  int k, sign;
++  int32_t k, sign, lx;
+   long double t, u, p, q;
+-  ieee854_long_double_shape_type s;
++  double xhi;
+ 
+-  s.value = x;
+-  k = s.parts32.w0;
+-  if (k & 0x80000000)
+-    sign = 1;
+-  else
+-    sign = 0;
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS (k, lx, xhi);
++  sign = k & 0x80000000;
+ 
+   /* Check for IEEE special cases.  */
+   k &= 0x7fffffff;
+   if (k >= 0x7ff00000)
+     {
+       /* NaN. */
+-      if ((k & 0xfffff) | s.parts32.w1 )
++      if (((k - 0x7ff00000) | lx) != 0)
+ 	return (x + x);
+ 
+       /* Infinity. */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_cosl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_cosl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_cosl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_cosl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -53,9 +53,11 @@
+ {
+ 	long double y[2],z=0.0L;
+ 	int64_t n, ix;
++	double xhi;
+ 
+     /* High word of x. */
+-	GET_LDOUBLE_MSW64(ix,x);
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (ix, xhi);
+ 
+     /* |x| ~< pi/4 */
+ 	ix &= 0x7fffffffffffffffLL;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -29,10 +29,16 @@
+ long double __fabsl(long double x)
+ {
+ 	u_int64_t hx, lx;
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
++	double xhi, xlo;
++
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
+ 	lx = lx ^ ( hx & 0x8000000000000000LL );
+ 	hx = hx & 0x7fffffffffffffffLL;
+-	SET_LDOUBLE_WORDS64(x,hx,lx);
++	INSERT_WORDS64 (xhi, hx);
++	INSERT_WORDS64 (xlo, lx);
++	x = ldbl_pack (xhi, xlo);
+ 	return x;
+ }
+ long_double_symbol (libm, __fabsl, fabsl);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_finitel.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_finitel.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_finitel.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_finitel.c	2014-05-27 19:59:00.000000000 -0500
+@@ -29,10 +29,14 @@
+ int
+ ___finitel (long double x)
+ {
+-	int64_t hx;
+-	GET_LDOUBLE_MSW64(hx,x);
+-	return (int)((u_int64_t)((hx&0x7fffffffffffffffLL)
+-				 -0x7ff0000000000000LL)>>63);
++  uint64_t hx;
++  double xhi;
++
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
++  hx &= 0x7fffffffffffffffLL;
++  hx -= 0x7ff0000000000000LL;
++  return hx >> 63;
+ }
+ hidden_ver (___finitel, __finitel)
+ weak_alias (___finitel, ____finitel)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -46,8 +46,10 @@
+ {
+   u_int64_t hx, lx;
+   int retval = FP_NORMAL;
++  double xhi, xlo;
+ 
+-  GET_LDOUBLE_WORDS64 (hx, lx, x);
++  ldbl_unpack (x, &xhi, &xlo);
++  EXTRACT_WORDS64 (hx, xhi);
+   if ((hx & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL) {
+       /* +/-NaN or +/-Inf */
+       if (hx & 0x000fffffffffffffULL) {
+@@ -65,6 +67,7 @@
+ 	      retval = FP_NORMAL;
+ 	  } else {
+ 	      if ((hx & 0x7ff0000000000000ULL) == 0x0360000000000000ULL) {
++		  EXTRACT_WORDS64 (lx, xlo);
+ 		  if ((lx & 0x7fffffffffffffff)	/* lower is non-zero */
+ 		  && ((lx^hx) & 0x8000000000000000ULL)) { /* and sign differs */
+ 		      /* +/- denormal */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c	2014-05-27 19:59:00.000000000 -0500
+@@ -29,12 +29,14 @@
+ int
+ ___isnanl (long double x)
+ {
+-	int64_t hx;
+-	int64_t lx __attribute__ ((unused));
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
+-	hx &= 0x7fffffffffffffffLL;
+-	hx = 0x7ff0000000000000LL - hx;
+-	return (int)((u_int64_t)hx>>63);
++  uint64_t hx;
++  double xhi;
++
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
++  hx &= 0x7fffffffffffffffLL;
++  hx = 0x7ff0000000000000LL - hx;
++  return (int) (hx >> 63);
+ }
+ hidden_ver (___isnanl, __isnanl)
+ #ifndef IS_IN_libm
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_logbl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_logbl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_logbl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_logbl.c	2014-05-27 19:59:19.000000000 -0500
+@@ -27,9 +27,10 @@
+ __logbl (long double x)
+ {
+   int64_t hx, rhx;
+-  int64_t lx __attribute__ ((unused));
++  double xhi;
+ 
+-  GET_LDOUBLE_WORDS64 (hx, lx, x);
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
+   hx &= 0x7fffffffffffffffLL;	/* high |x| */
+   if (hx == 0)
+     return -1.0 / fabs (x);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c	2014-05-27 19:59:19.000000000 -0500
+@@ -25,8 +25,10 @@
+ ___signbitl (long double x)
+ {
+   int64_t e;
++  double xhi;
+ 
+-  GET_LDOUBLE_MSW64 (e, x);
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (e, xhi);
+   return e < 0;
+ }
+ #ifdef IS_IN_libm
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c	2014-05-27 19:59:19.000000000 -0500
+@@ -27,9 +27,11 @@
+ __sincosl (long double x, long double *sinx, long double *cosx)
+ {
+   int64_t ix;
++  double xhi;
+ 
+   /* High word of x. */
+-  GET_LDOUBLE_MSW64 (ix, x);
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (ix, xhi);
+ 
+   /* |x| ~< pi/4 */
+   ix &= 0x7fffffffffffffffLL;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_sinl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_sinl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_sinl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_sinl.c	2014-05-27 19:59:19.000000000 -0500
+@@ -53,9 +53,11 @@
+ {
+ 	long double y[2],z=0.0L;
+ 	int64_t n, ix;
++	double xhi;
+ 
+     /* High word of x. */
+-	GET_LDOUBLE_MSW64(ix,x);
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (ix, xhi);
+ 
+     /* |x| ~< pi/4 */
+ 	ix &= 0x7fffffffffffffffLL;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_tanl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_tanl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_tanl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_tanl.c	2014-05-27 19:59:19.000000000 -0500
+@@ -53,9 +53,11 @@
+ {
+ 	long double y[2],z=0.0L;
+ 	int64_t n, ix;
++	double xhi;
+ 
+     /* High word of x. */
+-	GET_LDOUBLE_MSW64(ix,x);
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (ix, xhi);
+ 
+     /* |x| ~< pi/4 */
+ 	ix &= 0x7fffffffffffffffLL;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c	2014-05-27 19:58:07.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c	2014-05-27 19:59:19.000000000 -0500
+@@ -35,14 +35,14 @@
+ long double
+ __logbl (long double x)
+ {
+-  double xh, xl;
++  double xh;
+   double ret;
+ 
+   if (__builtin_expect (x == 0.0L, 0))
+     /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF].  */
+     return -1.0L / __builtin_fabsl (x);
+ 
+-  ldbl_unpack (x, &xh, &xl);
++  xh = ldbl_high (x);
+   /* ret = x & 0x7ff0000000000000;  */
+   asm (
+     "xxland %x0,%x1,%x2\n"
+@@ -58,9 +58,9 @@
+     {
+       /* POSIX specifies that denormal number is treated as
+          though it were normalized.  */
+-      int64_t lx, hx;
++      int64_t hx;
+ 
+-      GET_LDOUBLE_WORDS64 (hx, lx, x);
++      EXTRACT_WORDS64 (hx, xh);
+       return (long double) (-1023 - (__builtin_clzll (hx) - 12));
+     }
+   /* Test to avoid logb_downward (0.0) == -0.0.  */
diff --git a/SOURCES/glibc-ppc64le-08.patch b/SOURCES/glibc-ppc64le-08.patch
new file mode 100644
index 0000000..5cdba90
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-08.patch
@@ -0,0 +1,1235 @@
+# commit 765714cafcad7e6168518c61111f07bd955a9fee
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:24:58 2013 +0930
+# 
+#     PowerPC floating point little-endian [3 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00083.html
+#     
+#     Further replacement of ieee854 macros and unions.  These files also
+#     have some optimisations for comparison against 0.0L, infinity and nan.
+#     Since the ABI specifies that the high double of an IBM long double
+#     pair is the value rounded to double, a high double of 0.0 means the
+#     low double must also be 0.0.  The ABI also says that infinity and
+#     nan are encoded in the high double, with the low double unspecified.
+#     This means that tests for 0.0L, +/-Infinity and +/-NaN need only check
+#     the high double.
+#     
+#         * sysdeps/ieee754/ldbl-128ibm/e_atan2l.c (__ieee754_atan2l): Rewrite
+#         all uses of ieee854 long double macros and unions.  Simplify tests
+#         for long doubles that are fully specified by the high double.
+#         * sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c (__ieee754_gammal_r):
+#         Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c (__ieee754_ilogbl): Likewise.
+#         Remove dead code too.
+#         * sysdeps/ieee754/ldbl-128ibm/e_jnl.c (__ieee754_jnl): Likewise.
+#         (__ieee754_ynl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_log10l.c (__ieee754_log10l): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_logl.c (__ieee754_logl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/e_powl.c (__ieee754_powl): Likewise.
+#         Remove dead code too.
+#         * sysdeps/ieee754/ldbl-128ibm/k_tanl.c (__kernel_tanl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_expm1l.c (__expm1l): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_frexpl.c (__frexpl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c (__isinf_nsl): Likewise.
+#         Simplify.
+#         * sysdeps/ieee754/ldbl-128ibm/s_isinfl.c (___isinfl): Likewise.
+#         Simplify.
+#         * sysdeps/ieee754/ldbl-128ibm/s_log1pl.c (__log1pl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_modfl.c (__modfl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c (__nextafterl): Likewise.
+#         Comment on variable precision.
+#         * sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c (__nexttoward): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c (__nexttowardf):
+#         Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_remquol.c (__remquol): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c (__scalblnl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c (__scalbnl): Likewise.
+#         * sysdeps/ieee754/ldbl-128ibm/s_tanhl.c (__tanhl): Likewise.
+#         * sysdeps/powerpc/fpu/libm-test-ulps: Adjust tan_towardzero ulps.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c	2014-05-27 23:05:55.000000000 -0500
+@@ -56,11 +56,15 @@
+ {
+ 	long double z;
+ 	int64_t k,m,hx,hy,ix,iy;
+-	u_int64_t lx,ly;
++	uint64_t lx;
++	double xhi, xlo, yhi;
+ 
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
+ 	ix = hx&0x7fffffffffffffffLL;
+-	GET_LDOUBLE_WORDS64(hy,ly,y);
++	yhi = ldbl_high (y);
++	EXTRACT_WORDS64 (hy, yhi);
+ 	iy = hy&0x7fffffffffffffffLL;
+ 	if(((ix)>0x7ff0000000000000LL)||
+ 	   ((iy)>0x7ff0000000000000LL))	/* x or y is NaN */
+@@ -70,7 +74,7 @@
+ 	m = ((hy>>63)&1)|((hx>>62)&2);	/* 2*sign(x)+sign(y) */
+ 
+     /* when y = 0 */
+-	if((iy|(ly&0x7fffffffffffffffLL))==0) {
++	if(iy==0) {
+ 	    switch(m) {
+ 		case 0:
+ 		case 1: return y;	/* atan(+-0,+anything)=+-0 */
+@@ -79,7 +83,7 @@
+ 	    }
+ 	}
+     /* when x = 0 */
+-	if((ix|(lx&0x7fffffffffffffff))==0) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;
++	if(ix==0) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;
+ 
+     /* when x is INF */
+ 	if(ix==0x7ff0000000000000LL) {
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c	2014-05-27 23:05:55.000000000 -0500
+@@ -29,11 +29,12 @@
+      and the exp function.  But due to the required boundary
+      conditions we must check some values separately.  */
+   int64_t hx;
+-  u_int64_t lx;
++  double xhi;
+ 
+-  GET_LDOUBLE_WORDS64 (hx, lx, x);
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
+ 
+-  if (((hx | lx) & 0x7fffffffffffffffLL) == 0)
++  if ((hx & 0x7fffffffffffffffLL) == 0)
+     {
+       /* Return value for x == 0 is Inf with divide by zero exception.  */
+       *signgamp = 0;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -31,26 +31,24 @@
+ 
+ int __ieee754_ilogbl(long double x)
+ {
+-	int64_t hx,lx;
++	int64_t hx;
+ 	int ix;
++	double xhi;
+ 
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (hx, xhi);
+ 	hx &= 0x7fffffffffffffffLL;
+ 	if(hx <= 0x0010000000000000LL) {
+-	    if((hx|(lx&0x7fffffffffffffffLL))==0)
++	    if(hx==0)
+ 		return FP_ILOGB0;	/* ilogbl(0) = FP_ILOGB0 */
+ 	    else			/* subnormal x */
+-		if(hx==0) {
+-		    for (ix = -1043; lx>0; lx<<=1) ix -=1;
+-		} else {
+-		    for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1;
+-		}
++		for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1;
+ 	    return ix;
+ 	}
+ 	else if (hx<0x7ff0000000000000LL) return (hx>>52)-0x3ff;
+ 	else if (FP_ILOGBNAN != INT_MAX) {
+ 	    /* ISO C99 requires ilogbl(+-Inf) == INT_MAX.  */
+-	    if (((hx^0x7ff0000000000000LL)|lx) == 0)
++	    if (hx==0x7ff0000000000000LL)
+ 		return INT_MAX;
+ 	}
+ 	return FP_ILOGBNAN;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_jnl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_jnl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_jnl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -70,26 +70,25 @@
+ long double
+ __ieee754_jnl (int n, long double x)
+ {
+-  u_int32_t se;
++  uint32_t se, lx;
+   int32_t i, ix, sgn;
+   long double a, b, temp, di;
+   long double z, w;
+-  ieee854_long_double_shape_type u;
++  double xhi;
+ 
+ 
+   /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+    * Thus, J(-n,x) = J(n,-x)
+    */
+ 
+-  u.value = x;
+-  se = u.parts32.w0;
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS (se, lx, xhi);
+   ix = se & 0x7fffffff;
+ 
+   /* if J(n,NaN) is NaN */
+   if (ix >= 0x7ff00000)
+     {
+-      if ((u.parts32.w0 & 0xfffff) | u.parts32.w1
+-	  | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3)
++      if (((ix - 0x7ff00000) | lx) != 0)
+ 	return x + x;
+     }
+ 
+@@ -298,21 +297,20 @@
+ long double
+ __ieee754_ynl (int n, long double x)
+ {
+-  u_int32_t se;
++  uint32_t se, lx;
+   int32_t i, ix;
+   int32_t sign;
+   long double a, b, temp;
+-  ieee854_long_double_shape_type u;
++  double xhi;
+ 
+-  u.value = x;
+-  se = u.parts32.w0;
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS (se, lx, xhi);
+   ix = se & 0x7fffffff;
+ 
+   /* if Y(n,NaN) is NaN */
+   if (ix >= 0x7ff00000)
+     {
+-      if ((u.parts32.w0 & 0xfffff) | u.parts32.w1
+-	  | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3)
++      if (((ix - 0x7ff00000) | lx) != 0)
+ 	return x + x;
+     }
+   if (x <= 0.0L)
+@@ -377,14 +375,16 @@
+       a = __ieee754_y0l (x);
+       b = __ieee754_y1l (x);
+       /* quit if b is -inf */
+-      u.value = b;
+-      se = u.parts32.w0 & 0xfff00000;
++      xhi = ldbl_high (b);
++      GET_HIGH_WORD (se, xhi);
++      se &= 0xfff00000;
+       for (i = 1; i < n && se != 0xfff00000; i++)
+ 	{
+ 	  temp = b;
+ 	  b = ((long double) (i + i) / x) * b - a;
+-	  u.value = b;
+-	  se = u.parts32.w0 & 0xfff00000;
++	  xhi = ldbl_high (b);
++	  GET_HIGH_WORD (se, xhi);
++	  se &= 0xfff00000;
+ 	  a = temp;
+ 	}
+     }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_log10l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_log10l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_log10l.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_log10l.c	2014-05-27 23:05:55.000000000 -0500
+@@ -182,11 +182,13 @@
+   long double z;
+   long double y;
+   int e;
+-  int64_t hx, lx;
++  int64_t hx;
++  double xhi;
+ 
+ /* Test for domain */
+-  GET_LDOUBLE_WORDS64 (hx, lx, x);
+-  if (((hx & 0x7fffffffffffffffLL) | (lx & 0x7fffffffffffffffLL)) == 0)
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
++  if ((hx & 0x7fffffffffffffffLL) == 0)
+     return (-1.0L / (x - x));
+   if (hx < 0)
+     return (x - x) / (x - x);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_logl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_logl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_logl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_logl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -185,18 +185,20 @@
+ long double
+ __ieee754_logl(long double x)
+ {
+-  long double z, y, w;
+-  ieee854_long_double_shape_type u, t;
++  long double z, y, w, t;
+   unsigned int m;
+   int k, e;
++  double xhi;
++  uint32_t hx, lx;
+ 
+-  u.value = x;
+-  m = u.parts32.w0;
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS (hx, lx, xhi);
++  m = hx;
+ 
+   /* Check for IEEE special cases.  */
+   k = m & 0x7fffffff;
+   /* log(0) = -infinity. */
+-  if ((k | u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0)
++  if ((k | lx) == 0)
+     {
+       return -0.5L / ZERO;
+     }
+@@ -216,7 +218,7 @@
+     {
+       z = x - 1.0L;
+       k = 64;
+-      t.value  = 1.0L;
++      t = 1.0L;
+       e = 0;
+     }
+   else
+@@ -233,10 +235,8 @@
+ 	  k = (m - 0xff000) >> 13;
+ 	  /* t is the argument 0.5 + (k+26)/128
+ 	     of the nearest item to u in the lookup table.  */
+-	  t.parts32.w0 = 0x3ff00000 + (k << 13);
+-	  t.parts32.w1 = 0;
+-	  t.parts32.w2 = 0;
+-	  t.parts32.w3 = 0;
++	  INSERT_WORDS (xhi, 0x3ff00000 + (k << 13), 0);
++	  t = xhi;
+ 	  w0 += 0x100000;
+ 	  e -= 1;
+ 	  k += 64;
+@@ -244,17 +244,15 @@
+       else
+ 	{
+ 	  k = (m - 0xfe000) >> 14;
+-	  t.parts32.w0 = 0x3fe00000 + (k << 14);
+-	  t.parts32.w1 = 0;
+-	  t.parts32.w2 = 0;
+-	  t.parts32.w3 = 0;
++	  INSERT_WORDS (xhi, 0x3fe00000 + (k << 14), 0);
++	  t = xhi;
+ 	}
+-      u.value = __scalbnl (u.value, ((int) ((w0 - u.parts32.w0) * 2)) >> 21);
++      x = __scalbnl (x, ((int) ((w0 - hx) * 2)) >> 21);
+       /* log(u) = log( t u/t ) = log(t) + log(u/t)
+ 	 log(t) is tabulated in the lookup table.
+ 	 Express log(u/t) = log(1+z),  where z = u/t - 1 = (u-t)/t.
+ 	 cf. Cody & Waite. */
+-      z = (u.value - t.value) / t.value;
++      z = (x - t) / t;
+     }
+   /* Series expansion of log(1+z).  */
+   w = z * z;
+@@ -275,7 +273,7 @@
+   y += e * ln2b;  /* Base 2 exponent offset times ln(2).  */
+   y += z;
+   y += logtbl[k-26]; /* log(t) - (t-1) */
+-  y += (t.value - 1.0L);
++  y += (t - 1.0L);
+   y += e * ln2a;
+   return y;
+ }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_powl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_powl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_powl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_powl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -151,37 +151,32 @@
+   long double y1, t1, t2, r, s, t, u, v, w;
+   long double s2, s_h, s_l, t_h, t_l, ay;
+   int32_t i, j, k, yisint, n;
+-  u_int32_t ix, iy;
+-  int32_t hx, hy;
+-  ieee854_long_double_shape_type o, p, q;
++  uint32_t ix, iy;
++  int32_t hx, hy, hax;
++  double ohi, xhi, xlo, yhi, ylo;
++  uint32_t lx, ly, lj;
+ 
+-  p.value = x;
+-  hx = p.parts32.w0;
++  ldbl_unpack (x, &xhi, &xlo);
++  EXTRACT_WORDS (hx, lx, xhi);
+   ix = hx & 0x7fffffff;
+ 
+-  q.value = y;
+-  hy = q.parts32.w0;
++  ldbl_unpack (y, &yhi, &ylo);
++  EXTRACT_WORDS (hy, ly, yhi);
+   iy = hy & 0x7fffffff;
+ 
+-
+   /* y==zero: x**0 = 1 */
+-  if ((iy | q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0)
++  if ((iy | ly) == 0)
+     return one;
+ 
+   /* 1.0**y = 1; -1.0**+-Inf = 1 */
+   if (x == one)
+     return one;
+-  if (x == -1.0L && iy == 0x7ff00000
+-      && (q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0)
++  if (x == -1.0L && ((iy - 0x7ff00000) | ly) == 0)
+     return one;
+ 
+   /* +-NaN return x+y */
+-  if ((ix > 0x7ff00000)
+-      || ((ix == 0x7ff00000)
+-	  && ((p.parts32.w1 | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) != 0))
+-      || (iy > 0x7ff00000)
+-      || ((iy == 0x7ff00000)
+-	  && ((q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) != 0)))
++  if ((ix >= 0x7ff00000 && ((ix - 0x7ff00000) | lx) != 0)
++      || (iy >= 0x7ff00000 && ((iy - 0x7ff00000) | ly) != 0))
+     return x + y;
+ 
+   /* determine if y is an odd int when x < 0
+@@ -192,7 +187,10 @@
+   yisint = 0;
+   if (hx < 0)
+     {
+-      if ((q.parts32.w2 & 0x7fffffff) >= 0x43400000)	/* Low part >= 2^53 */
++      uint32_t low_ye;
++
++      GET_HIGH_WORD (low_ye, ylo);
++      if ((low_ye & 0x7fffffff) >= 0x43400000)	/* Low part >= 2^53 */
+ 	yisint = 2;		/* even integer y */
+       else if (iy >= 0x3ff00000)	/* 1.0 */
+ 	{
+@@ -207,42 +205,43 @@
+ 	}
+     }
+ 
++  ax = fabsl (x);
++
+   /* special value of y */
+-  if ((q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0)
++  if (ly == 0)
+     {
+-      if (iy == 0x7ff00000 && q.parts32.w1 == 0)	/* y is +-inf */
++      if (iy == 0x7ff00000)	/* y is +-inf */
+ 	{
+-	  if (((ix - 0x3ff00000) | p.parts32.w1
+-	       | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) == 0)
+-	    return y - y;	/* inf**+-1 is NaN */
+-	  else if (ix > 0x3ff00000 || fabsl (x) > 1.0L)
++	  if (ax > one)
+ 	    /* (|x|>1)**+-inf = inf,0 */
+ 	    return (hy >= 0) ? y : zero;
+ 	  else
+ 	    /* (|x|<1)**-,+inf = inf,0 */
+ 	    return (hy < 0) ? -y : zero;
+ 	}
+-      if (iy == 0x3ff00000)
+-	{			/* y is  +-1 */
+-	  if (hy < 0)
+-	    return one / x;
+-	  else
+-	    return x;
+-	}
+-      if (hy == 0x40000000)
+-	return x * x;		/* y is  2 */
+-      if (hy == 0x3fe00000)
+-	{			/* y is  0.5 */
+-	  if (hx >= 0)		/* x >= +0 */
+-	    return __ieee754_sqrtl (x);
++      if (ylo == 0.0)
++	{
++	  if (iy == 0x3ff00000)
++	    {			/* y is  +-1 */
++	      if (hy < 0)
++		return one / x;
++	      else
++		return x;
++	    }
++	  if (hy == 0x40000000)
++	    return x * x;		/* y is  2 */
++	  if (hy == 0x3fe00000)
++	    {			/* y is  0.5 */
++	      if (hx >= 0)		/* x >= +0 */
++		return __ieee754_sqrtl (x);
++	    }
+ 	}
+     }
+ 
+-  ax = fabsl (x);
+   /* special value of x */
+-  if ((p.parts32.w1 | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) == 0)
++  if (lx == 0)
+     {
+-      if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000)
++      if (ix == 0x7ff00000 || ix == 0 || (ix == 0x3ff00000 && xlo == 0.0))
+ 	{
+ 	  z = ax;		/*x is +-0,+-inf,+-1 */
+ 	  if (hy < 0)
+@@ -294,8 +293,8 @@
+     {
+       ax *= two113;
+       n -= 113;
+-      o.value = ax;
+-      ix = o.parts32.w0;
++      ohi = ldbl_high (ax);
++      GET_HIGH_WORD (ix, ohi);
+     }
+   n += ((ix) >> 20) - 0x3ff;
+   j = ix & 0x000fffff;
+@@ -312,26 +311,19 @@
+       ix -= 0x00100000;
+     }
+ 
+-  o.value = ax;
+-  o.value = __scalbnl (o.value, ((int) ((ix - o.parts32.w0) * 2)) >> 21);
+-  ax = o.value;
++  ohi = ldbl_high (ax);
++  GET_HIGH_WORD (hax, ohi);
++  ax = __scalbnl (ax, ((int) ((ix - hax) * 2)) >> 21);
+ 
+   /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+   u = ax - bp[k];		/* bp[0]=1.0, bp[1]=1.5 */
+   v = one / (ax + bp[k]);
+   s = u * v;
+-  s_h = s;
++  s_h = ldbl_high (s);
+ 
+-  o.value = s_h;
+-  o.parts32.w3 = 0;
+-  o.parts32.w2 = 0;
+-  s_h = o.value;
+   /* t_h=ax+bp[k] High */
+   t_h = ax + bp[k];
+-  o.value = t_h;
+-  o.parts32.w3 = 0;
+-  o.parts32.w2 = 0;
+-  t_h = o.value;
++  t_h = ldbl_high (t_h);
+   t_l = ax - (t_h - bp[k]);
+   s_l = v * ((u - s_h * t_h) - s_h * t_l);
+   /* compute log(ax) */
+@@ -342,30 +334,21 @@
+   r += s_l * (s_h + s);
+   s2 = s_h * s_h;
+   t_h = 3.0 + s2 + r;
+-  o.value = t_h;
+-  o.parts32.w3 = 0;
+-  o.parts32.w2 = 0;
+-  t_h = o.value;
++  t_h = ldbl_high (t_h);
+   t_l = r - ((t_h - 3.0) - s2);
+   /* u+v = s*(1+...) */
+   u = s_h * t_h;
+   v = s_l * t_h + t_l * s;
+   /* 2/(3log2)*(s+...) */
+   p_h = u + v;
+-  o.value = p_h;
+-  o.parts32.w3 = 0;
+-  o.parts32.w2 = 0;
+-  p_h = o.value;
++  p_h = ldbl_high (p_h);
+   p_l = v - (p_h - u);
+   z_h = cp_h * p_h;		/* cp_h+cp_l = 2/(3*log2) */
+   z_l = cp_l * p_h + p_l * cp + dp_l[k];
+   /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+   t = (long double) n;
+   t1 = (((z_h + z_l) + dp_h[k]) + t);
+-  o.value = t1;
+-  o.parts32.w3 = 0;
+-  o.parts32.w2 = 0;
+-  t1 = o.value;
++  t1 = ldbl_high (t1);
+   t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
+ 
+   /* s (sign of result -ve**odd) = -1 else = 1 */
+@@ -374,21 +357,16 @@
+     s = -one;			/* (-ve)**(odd int) */
+ 
+   /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+-  y1 = y;
+-  o.value = y1;
+-  o.parts32.w3 = 0;
+-  o.parts32.w2 = 0;
+-  y1 = o.value;
++  y1 = ldbl_high (y);
+   p_l = (y - y1) * t1 + y * t2;
+   p_h = y1 * t1;
+   z = p_l + p_h;
+-  o.value = z;
+-  j = o.parts32.w0;
++  ohi = ldbl_high (z);
++  EXTRACT_WORDS (j, lj, ohi);
+   if (j >= 0x40d00000) /* z >= 16384 */
+     {
+       /* if z > 16384 */
+-      if (((j - 0x40d00000) | o.parts32.w1
+-	| (o.parts32.w2 & 0x7fffffff) | o.parts32.w3) != 0)
++      if (((j - 0x40d00000) | lj) != 0)
+ 	return s * huge * huge;	/* overflow */
+       else
+ 	{
+@@ -399,8 +377,7 @@
+   else if ((j & 0x7fffffff) >= 0x40d01b90)	/* z <= -16495 */
+     {
+       /* z < -16495 */
+-      if (((j - 0xc0d01bc0) | o.parts32.w1
+-	 | (o.parts32.w2 & 0x7fffffff) | o.parts32.w3) != 0)
++      if (((j - 0xc0d01bc0) | lj) != 0)
+ 	return s * tiny * tiny;	/* underflow */
+       else
+ 	{
+@@ -419,10 +396,7 @@
+       p_h -= t;
+     }
+   t = p_l + p_h;
+-  o.value = t;
+-  o.parts32.w3 = 0;
+-  o.parts32.w2 = 0;
+-  t = o.value;
++  t = ldbl_high (t);
+   u = t * lg2_h;
+   v = (p_l - (t - p_h)) * lg2 + t * lg2_l;
+   z = u + v;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/k_tanl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/k_tanl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/k_tanl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/k_tanl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -85,17 +85,17 @@
+ __kernel_tanl (long double x, long double y, int iy)
+ {
+   long double z, r, v, w, s;
+-  int32_t ix, sign;
+-  ieee854_long_double_shape_type u, u1;
++  int32_t ix, sign, hx, lx;
++  double xhi;
+ 
+-  u.value = x;
+-  ix = u.parts32.w0 & 0x7fffffff;
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS (hx, lx, xhi);
++  ix = hx & 0x7fffffff;
+   if (ix < 0x3c600000)		/* x < 2**-57 */
+     {
+-      if ((int) x == 0)
+-	{			/* generate inexact */
+-	  if ((ix | u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3
+-	       | (iy + 1)) == 0)
++      if ((int) x == 0)		/* generate inexact */
++	{
++	  if ((ix | lx | (iy + 1)) == 0)
+ 	    return one / fabs (x);
+ 	  else
+ 	    return (iy == 1) ? x : -one / x;
+@@ -103,7 +103,7 @@
+     }
+   if (ix >= 0x3fe59420) /* |x| >= 0.6743316650390625 */
+     {
+-      if ((u.parts32.w0 & 0x80000000) != 0)
++      if ((hx & 0x80000000) != 0)
+ 	{
+ 	  x = -x;
+ 	  y = -y;
+@@ -139,15 +139,13 @@
+     {				/* if allow error up to 2 ulp,
+ 				   simply return -1.0/(x+r) here */
+       /*  compute -1.0/(x+r) accurately */
+-      u1.value = w;
+-      u1.parts32.w2 = 0;
+-      u1.parts32.w3 = 0;
+-      v = r - (u1.value - x);		/* u1+v = r+x */
++      long double u1, z1;
++
++      u1 = ldbl_high (w);
++      v = r - (u1 - x);		/* u1+v = r+x */
+       z = -1.0 / w;
+-      u.value = z;
+-      u.parts32.w2 = 0;
+-      u.parts32.w3 = 0;
+-      s = 1.0 + u.value * u1.value;
+-      return u.value + z * (s + u.value * v);
++      z1 = ldbl_high (z);
++      s = 1.0 + z1 * u1;
++      return z1 + z * (s + z1 * v);
+     }
+ }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c	2014-05-27 23:05:55.000000000 -0500
+@@ -92,19 +92,19 @@
+ __expm1l (long double x)
+ {
+   long double px, qx, xx;
+-  int32_t ix, sign;
+-  ieee854_long_double_shape_type u;
++  int32_t ix, lx, sign;
+   int k;
++  double xhi;
+ 
+   /* Detect infinity and NaN.  */
+-  u.value = x;
+-  ix = u.parts32.w0;
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS (ix, lx, xhi);
+   sign = ix & 0x80000000;
+   ix &= 0x7fffffff;
+   if (ix >= 0x7ff00000)
+     {
+       /* Infinity. */
+-      if (((ix & 0xfffff) | u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0)
++      if (((ix - 0x7ff00000) | lx) == 0)
+ 	{
+ 	  if (sign)
+ 	    return -1.0L;
+@@ -116,7 +116,7 @@
+     }
+ 
+   /* expm1(+- 0) = +- 0.  */
+-  if ((ix == 0) && (u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0)
++  if ((ix | lx) == 0)
+     return x;
+ 
+   /* Overflow.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -36,16 +36,21 @@
+ 
+ long double __frexpl(long double x, int *eptr)
+ {
+-	u_int64_t hx, lx, ix, ixl;
++	uint64_t hx, lx, ix, ixl;
+ 	int64_t explo;
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
++	double xhi, xlo;
++
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
+ 	ixl = 0x7fffffffffffffffULL&lx;
+ 	ix =  0x7fffffffffffffffULL&hx;
+ 	*eptr = 0;
+-	if(ix>=0x7ff0000000000000ULL||((ix|ixl)==0)) return x;	/* 0,inf,nan */
++	if(ix>=0x7ff0000000000000ULL||ix==0) return x;	/* 0,inf,nan */
+ 	if (ix<0x0010000000000000ULL) {		/* subnormal */
+ 	    x *= two107;
+-	    GET_LDOUBLE_MSW64(hx,x);
++	    xhi = ldbl_high (x);
++	    EXTRACT_WORDS64 (hx, xhi);
+ 	    ix = hx&0x7fffffffffffffffULL;
+ 	    *eptr = -107;
+ 	}
+@@ -54,7 +59,7 @@
+ 	if (ixl != 0ULL) {
+ 	  explo = (ixl>>52) - (ix>>52) + 0x3fe;
+ 	  if ((ixl&0x7ff0000000000000ULL) == 0LL) {
+-	    /* the lower double is a denomal so we need to correct its
++	    /* the lower double is a denormal so we need to correct its
+ 	       mantissa and perhaps its exponent.  */
+ 	    int cnt;
+ 
+@@ -73,7 +78,9 @@
+ 	  lx = 0ULL;
+ 
+ 	hx = (hx&0x800fffffffffffffULL) | 0x3fe0000000000000ULL;
+-	SET_LDOUBLE_WORDS64(x,hx,lx);
++	INSERT_WORDS64 (xhi, hx);
++	INSERT_WORDS64 (xlo, lx);
++	x = ldbl_pack (xhi, xlo);
+ 	return x;
+ }
+ #ifdef IS_IN_libm
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -1,6 +1,7 @@
+ /*
+  * __isinf_nsl(x) returns != 0 if x is ±inf, else 0;
+  * no branching!
++ * slightly dodgy in relying on signed shift right copying sign bit
+  */
+ 
+ #include <math.h>
+@@ -9,8 +10,14 @@
+ int
+ __isinf_nsl (long double x)
+ {
+-	int64_t hx,lx;
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
+-	return !((lx & 0x7fffffffffffffffLL)
+-		 | ((hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL));
++  double xhi;
++  int64_t hx, mask;
++
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
++
++  mask = (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL;
++  mask |= -mask;
++  mask >>= 63;
++  return ~mask;
+ }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -11,6 +11,7 @@
+ /*
+  * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
+  * no branching!
++ * slightly dodgy in relying on signed shift right copying sign bit
+  */
+ 
+ #include <math.h>
+@@ -20,12 +21,16 @@
+ int
+ ___isinfl (long double x)
+ {
+-	int64_t hx,lx;
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
+-	lx = (lx & 0x7fffffffffffffffLL);
+-	lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL;
+-	lx |= -lx;
+-	return ~(lx >> 63) & (hx >> 62);
++  double xhi;
++  int64_t hx, mask;
++
++  xhi = ldbl_high (x);
++  EXTRACT_WORDS64 (hx, xhi);
++
++  mask = (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL;
++  mask |= -mask;
++  mask >>= 63;
++  return ~mask & (hx >> 62);
+ }
+ hidden_ver (___isinfl, __isinfl)
+ #ifndef IS_IN_libm
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -126,19 +126,18 @@
+ __log1pl (long double xm1)
+ {
+   long double x, y, z, r, s;
+-  ieee854_long_double_shape_type u;
+-  int32_t hx;
++  double xhi;
++  int32_t hx, lx;
+   int e;
+ 
+   /* Test for NaN or infinity input. */
+-  u.value = xm1;
+-  hx = u.parts32.w0;
++  xhi = ldbl_high (xm1);
++  EXTRACT_WORDS (hx, lx, xhi);
+   if (hx >= 0x7ff00000)
+     return xm1;
+ 
+   /* log1p(+- 0) = +- 0.  */
+-  if (((hx & 0x7fffffff) == 0)
+-      && (u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0)
++  if (((hx & 0x7fffffff) | lx) == 0)
+     return xm1;
+ 
+   x = xm1 + 1.0L;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_modfl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_modfl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_modfl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_modfl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -37,43 +37,54 @@
+ {
+ 	int64_t i0,i1,j0;
+ 	u_int64_t i;
+-	GET_LDOUBLE_WORDS64(i0,i1,x);
++	double xhi, xlo;
++
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (i0, xhi);
++	EXTRACT_WORDS64 (i1, xlo);
+ 	i1 &= 0x000fffffffffffffLL;
+ 	j0 = ((i0>>52)&0x7ff)-0x3ff;	/* exponent of x */
+ 	if(j0<52) {			/* integer part in high x */
+ 	    if(j0<0) {			/* |x|<1 */
+ 		/* *iptr = +-0 */
+-	        SET_LDOUBLE_WORDS64(*iptr,i0&0x8000000000000000ULL,0);
++		INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL);
++		*iptr = xhi;
+ 		return x;
+ 	    } else {
+ 		i = (0x000fffffffffffffLL)>>j0;
+ 		if(((i0&i)|(i1&0x7fffffffffffffffLL))==0) {		/* x is integral */
+ 		    *iptr = x;
+ 		    /* return +-0 */
+-		    SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
++		    INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL);
++		    x = xhi;
+ 		    return x;
+ 		} else {
+-		    SET_LDOUBLE_WORDS64(*iptr,i0&(~i),0);
++		    INSERT_WORDS64 (xhi, i0&(~i));
++		    *iptr = xhi;
+ 		    return x - *iptr;
+ 		}
+ 	    }
+ 	} else if (j0>103) {		/* no fraction part */
+ 	    *iptr = x*one;
+ 	    /* We must handle NaNs separately.  */
+-	    if (j0 == 0x400 && ((i0 & 0x000fffffffffffffLL) | i1))
++	    if ((i0 & 0x7fffffffffffffffLL) > 0x7ff0000000000000LL)
+ 	      return x*one;
+ 	    /* return +-0 */
+-	    SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
++	    INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL);
++	    x = xhi;
+ 	    return x;
+ 	} else {			/* fraction part in low x */
+ 	    i = -1ULL>>(j0-52);
+ 	    if((i1&i)==0) { 		/* x is integral */
+ 		*iptr = x;
+ 		/* return +-0 */
+-		SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
++		INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL);
++		x = xhi;
+ 		return x;
+ 	    } else {
+-		SET_LDOUBLE_WORDS64(*iptr,i0,i1&(~i));
++		INSERT_WORDS64 (xhi, i0);
++		INSERT_WORDS64 (xlo, i1&(~i));
++		*iptr = ldbl_pack (xhi, xlo);
+ 		return x - *iptr;
+ 	    }
+ 	}
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -30,27 +30,28 @@
+ 
+ long double __nextafterl(long double x, long double y)
+ {
+-	int64_t hx,hy,ihx,ihy,ilx;
+-	u_int64_t lx;
+-	u_int64_t ly __attribute__ ((unused));
++	int64_t hx,hy,ihx,ihy;
++	uint64_t lx;
++	double xhi, xlo, yhi;
+ 
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
+-	GET_LDOUBLE_WORDS64(hy,ly,y);
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
++	yhi = ldbl_high (y);
++	EXTRACT_WORDS64 (hy, yhi);
+ 	ihx = hx&0x7fffffffffffffffLL;		/* |hx| */
+-	ilx = lx&0x7fffffffffffffffLL;		/* |lx| */
+ 	ihy = hy&0x7fffffffffffffffLL;		/* |hy| */
+ 
+-	if((((ihx&0x7ff0000000000000LL)==0x7ff0000000000000LL)&&
+-	    ((ihx&0x000fffffffffffffLL)!=0)) ||   /* x is nan */
+-	   (((ihy&0x7ff0000000000000LL)==0x7ff0000000000000LL)&&
+-	    ((ihy&0x000fffffffffffffLL)!=0)))     /* y is nan */
++	if((ihx>0x7ff0000000000000LL) ||	/* x is nan */
++	   (ihy>0x7ff0000000000000LL))		/* y is nan */
+ 	    return x+y; /* signal the nan */
+ 	if(x==y)
+ 	    return y;		/* x=y, return y */
+-	if(ihx == 0 && ilx == 0) {			/* x == 0 */
+-	    long double u;
++	if(ihx == 0) {				/* x == 0 */
++	    long double u;			/* return +-minsubnormal */
+ 	    hy = (hy & 0x8000000000000000ULL) | 1;
+-	    SET_LDOUBLE_WORDS64(x,hy,0ULL);/* return +-minsubnormal */
++	    INSERT_WORDS64 (yhi, hy);
++	    x = yhi;
+ 	    u = math_opt_barrier (x);
+ 	    u = u * u;
+ 	    math_force_eval (u);		/* raise underflow flag */
+@@ -59,10 +60,16 @@
+ 	
+ 	long double u;
+ 	if(x > y) {	/* x > y, x -= ulp */
++	    /* This isn't the largest magnitude correctly rounded
++	       long double as you can see from the lowest mantissa
++	       bit being zero.  It is however the largest magnitude
++	       long double with a 106 bit mantissa, and nextafterl
++	       is insane with variable precision.  So to make
++	       nextafterl sane we assume 106 bit precision.  */
+ 	    if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL))
+ 	      return x+x;	/* overflow, return -inf */
+ 	    if (hx >= 0x7ff0000000000000LL) {
+-	      SET_LDOUBLE_WORDS64(u,0x7fefffffffffffffLL,0x7c8ffffffffffffeLL);
++	      u = 0x1.fffffffffffff7ffffffffffff8p+1023L;
+ 	      return u;
+ 	    }
+ 	    if(ihx <= 0x0360000000000000LL) {  /* x <= LDBL_MIN */
+@@ -77,16 +84,19 @@
+ 	      return x;
+ 	    }
+ 	    if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
+-	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL);
++	      INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52));
++	      u = yhi;
+ 	      u *= 0x1.0000000000000p-105L;
+-	    } else
+-	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL);
++	    } else {
++	      INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52));
++	      u = yhi;
++	    }
+ 	    return x - u;
+ 	} else {				/* x < y, x += ulp */
+ 	    if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL))
+ 	      return x+x;	/* overflow, return +inf */
+-	    if ((u_int64_t) hx >= 0xfff0000000000000ULL) {
+-	      SET_LDOUBLE_WORDS64(u,0xffefffffffffffffLL,0xfc8ffffffffffffeLL);
++	    if ((uint64_t) hx >= 0xfff0000000000000ULL) {
++	      u = -0x1.fffffffffffff7ffffffffffff8p+1023L;
+ 	      return u;
+ 	    }
+ 	    if(ihx <= 0x0360000000000000LL) {  /* x <= LDBL_MIN */
+@@ -103,10 +113,13 @@
+ 	      return x;
+ 	    }
+ 	    if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
+-	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL);
++	      INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52));
++	      u = yhi;
+ 	      u *= 0x1.0000000000000p-105L;
+-	    } else
+-	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL);
++	    } else {
++	      INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52));
++	      u = yhi;
++	    }
+ 	    return x + u;
+ 	}
+ }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c	2014-05-27 23:10:26.000000000 -0500
+@@ -34,23 +34,23 @@
+ {
+ 	int32_t hx,ix;
+ 	int64_t hy,iy;
+-	u_int32_t lx;
+-	u_int64_t ly,uly;
++	uint32_t lx;
++	double yhi;
++
+ 
+ 	EXTRACT_WORDS(hx,lx,x);
+-	GET_LDOUBLE_WORDS64(hy,ly,y);
++	yhi = ldbl_high (y);
++	EXTRACT_WORDS64(hy,yhi);
+ 	ix = hx&0x7fffffff;		/* |x| */
+ 	iy = hy&0x7fffffffffffffffLL;	/* |y| */
+-	uly = ly&0x7fffffffffffffffLL;	/* |y| */
+ 
+ 	if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
+-	   ((iy>=0x7ff0000000000000LL)&&((iy-0x7ff0000000000000LL)|uly)!=0))
+-	   						    /* y is nan */
++	   iy>0x7ff0000000000000LL)			    /* y is nan */
+ 	   return x+y;
+ 	if((long double) x==y) return y;	/* x=y, return y */
+ 	if((ix|lx)==0) {			/* x == 0 */
+ 	    double u;
+-	    INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
++	    INSERT_WORDS(x,(uint32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
+ 	    u = math_opt_barrier (x);
+ 	    u = u * u;
+ 	    math_force_eval (u);		/* raise underflow flag */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c	2014-05-27 23:05:55.000000000 -0500
+@@ -27,16 +27,16 @@
+ {
+ 	int32_t hx,ix;
+ 	int64_t hy,iy;
+-	u_int64_t ly, uly;
++	double yhi;
+ 
+ 	GET_FLOAT_WORD(hx,x);
+-	GET_LDOUBLE_WORDS64(hy,ly,y);
++	yhi = ldbl_high (y);
++	EXTRACT_WORDS64 (hy, yhi);
+ 	ix = hx&0x7fffffff;		/* |x| */
+ 	iy = hy&0x7fffffffffffffffLL;	/* |y| */
+-	uly = ly&0x7fffffffffffffffLL;	/* |y| */
+ 
+ 	if((ix>0x7f800000) ||   /* x is nan */
+-	   ((iy>=0x7ff0000000000000LL)&&((iy-0x7ff0000000000000LL)|uly)!=0))
++	   (iy>0x7ff0000000000000LL))
+ 				/* y is nan */
+ 	   return x+y;
+ 	if((long double) x==y) return y;	/* x=y, return y */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_remquol.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_remquol.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_remquol.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_remquol.c	2014-05-27 23:05:55.000000000 -0500
+@@ -33,20 +33,24 @@
+   int64_t hx,hy;
+   u_int64_t sx,lx,ly,qs;
+   int cquo;
++  double xhi, xlo, yhi, ylo;
+ 
+-  GET_LDOUBLE_WORDS64 (hx, lx, x);
+-  GET_LDOUBLE_WORDS64 (hy, ly, y);
++  ldbl_unpack (x, &xhi, &xlo);
++  EXTRACT_WORDS64 (hx, xhi);
++  EXTRACT_WORDS64 (lx, xlo);
++  ldbl_unpack (y, &yhi, &ylo);
++  EXTRACT_WORDS64 (hy, yhi);
++  EXTRACT_WORDS64 (ly, ylo);
+   sx = hx & 0x8000000000000000ULL;
+   qs = sx ^ (hy & 0x8000000000000000ULL);
+   hy &= 0x7fffffffffffffffLL;
+   hx &= 0x7fffffffffffffffLL;
+ 
+   /* Purge off exception values.  */
+-  if ((hy | (ly & 0x7fffffffffffffff)) == 0)
++  if (hy == 0)
+     return (x * y) / (x * y); 			/* y = 0 */
+   if ((hx >= 0x7ff0000000000000LL)		/* x not finite */
+-      || ((hy >= 0x7ff0000000000000LL)		/* y is NaN */
+-	  && (((hy - 0x7ff0000000000000LL) | ly) != 0)))
++      || (hy > 0x7ff0000000000000LL))		/* y is NaN */
+     return (x * y) / (x * y);
+ 
+   if (hy <= 0x7fbfffffffffffffLL)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c	2014-05-27 23:15:30.000000000 -0500
+@@ -41,11 +41,15 @@
+ {
+ 	int64_t k,l,hx,lx;
+ 	union { int64_t i; double d; } u;
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
++	double xhi, xlo;
++
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
+ 	k = (hx>>52)&0x7ff;		/* extract exponent */
+ 	l = (lx>>52)&0x7ff;
+ 	if (k==0) {				/* 0 or subnormal x */
+-	    if (((hx|lx)&0x7fffffffffffffffULL)==0) return x; /* +-0 */
++	    if ((hx&0x7fffffffffffffffULL)==0) return x; /* +-0 */
+ 	    u.i = hx;
+ 	    u.d *= two54;
+ 	    hx = u.i;
+@@ -61,7 +65,9 @@
+ 	if (k > 0) {				/* normal result */
+ 	    hx = (hx&0x800fffffffffffffULL)|(k<<52);
+ 	    if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */
+-	    	SET_LDOUBLE_WORDS64(x,hx,lx);
++		INSERT_WORDS64 (xhi, hx);
++		INSERT_WORDS64 (xlo, lx);
++		x = ldbl_pack (xhi, xlo);
+ 	    	return x;
+ 	    }
+ 	    if (l == 0) { /* low part subnormal */
+@@ -81,14 +87,19 @@
+ 	    	u.d *= twom54;
+ 	    	lx = u.i;
+ 	    }
+-	    SET_LDOUBLE_WORDS64(x,hx,lx);
++	    INSERT_WORDS64 (xhi, hx);
++	    INSERT_WORDS64 (xlo, lx);
++	    x = ldbl_pack (xhi, xlo);
+ 	    return x;
+ 	}
+ 	if (k <= -54)
+ 	  return tiny*__copysignl(tiny,x); 	/*underflow*/
+ 	k += 54;				/* subnormal result */
+ 	lx &= 0x8000000000000000ULL;
+-	SET_LDOUBLE_WORDS64(x,(hx&0x800fffffffffffffULL)|(k<<52),lx);
++	hx &= 0x800fffffffffffffULL;
++	INSERT_WORDS64 (xhi, hx|(k<<52));
++	INSERT_WORDS64 (xlo, lx);
++	x = ldbl_pack (xhi, xlo);
+ 	return x*twolm54;
+ }
+ long_double_symbol (libm, __scalblnl, scalblnl);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c	2014-05-27 23:16:25.000000000 -0500
+@@ -41,11 +41,15 @@
+ {
+ 	int64_t k,l,hx,lx;
+ 	union { int64_t i; double d; } u;
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
++	double xhi, xlo;
++
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
+ 	k = (hx>>52)&0x7ff;		/* extract exponent */
+ 	l = (lx>>52)&0x7ff;
+ 	if (k==0) {				/* 0 or subnormal x */
+-	    if (((hx|lx)&0x7fffffffffffffffULL)==0) return x; /* +-0 */
++	    if ((hx&0x7fffffffffffffffULL)==0) return x; /* +-0 */
+ 	    u.i = hx;
+ 	    u.d *= two54;
+ 	    hx = u.i;
+@@ -61,7 +65,9 @@
+ 	if (k > 0) {				/* normal result */
+ 	    hx = (hx&0x800fffffffffffffULL)|(k<<52);
+ 	    if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */
+-	    	SET_LDOUBLE_WORDS64(x,hx,lx);
++		INSERT_WORDS64 (xhi, hx);
++		INSERT_WORDS64 (xlo, lx);
++		x = ldbl_pack (xhi, xlo);
+ 	    	return x;
+ 	    }
+ 	    if (l == 0) { /* low part subnormal */
+@@ -81,14 +87,19 @@
+ 	    	u.d *= twom54;
+ 	    	lx = u.i;
+ 	    }
+-	    SET_LDOUBLE_WORDS64(x,hx,lx);
++	    INSERT_WORDS64 (xhi, hx);
++	    INSERT_WORDS64 (xlo, lx);
++	    x = ldbl_pack (xhi, xlo);
+ 	    return x;
+ 	}
+ 	if (k <= -54)
+ 	  return tiny*__copysignl(tiny,x); 	/*underflow*/
+ 	k += 54;				/* subnormal result */
+ 	lx &= 0x8000000000000000ULL;
+-	SET_LDOUBLE_WORDS64(x,(hx&0x800fffffffffffffULL)|(k<<52),lx);
++	hx &= 0x800fffffffffffffULL;
++	INSERT_WORDS64 (xhi, hx|(k<<52));
++	INSERT_WORDS64 (xlo, lx);
++	x = ldbl_pack (xhi, xlo);
+ 	return x*twolm54;
+ }
+ #ifdef IS_IN_libm
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c	2014-05-27 23:05:55.000000000 -0500
+@@ -47,10 +47,12 @@
+ long double __tanhl(long double x)
+ {
+ 	long double t,z;
+-	int64_t jx,ix,lx;
++	int64_t jx,ix;
++	double xhi;
+ 
+     /* High word of |x|. */
+-	GET_LDOUBLE_WORDS64(jx,lx,x);
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (jx, xhi);
+ 	ix = jx&0x7fffffffffffffffLL;
+ 
+     /* x is INF or NaN */
+@@ -61,7 +63,7 @@
+ 
+     /* |x| < 22 */
+ 	if (ix < 0x4036000000000000LL) {		/* |x|<22 */
+-	    if ((ix | (lx&0x7fffffffffffffffLL)) == 0)
++	    if (ix == 0)
+ 		return x;		/* x == +-0 */
+ 	    if (ix<0x3c60000000000000LL) 	/* |x|<2**-57 */
+ 		return x*(one+x);    	/* tanh(small) = small */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/libm-test-ulps glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/libm-test-ulps
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/libm-test-ulps	2014-05-27 23:05:51.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/libm-test-ulps	2014-05-27 23:08:26.000000000 -0500
+@@ -2641,6 +2641,9 @@
+ ifloat: 1
+ ildouble: 2
+ ldouble: 2
++Test "tan_towardzero (2)":
++ildouble: 1
++ldouble: 1
+ Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261":
+ float: 1
+ ifloat: 1
diff --git a/SOURCES/glibc-ppc64le-09.patch b/SOURCES/glibc-ppc64le-09.patch
new file mode 100644
index 0000000..838c0e8
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-09.patch
@@ -0,0 +1,567 @@
+# commit 650ef4bd7976e36831cba22d838b567d3b5f6e8f
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:25:51 2013 +0930
+# 
+#     PowerPC floating point little-endian [4 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00084.html
+#     
+#     Another batch of ieee854 macros and union replacement.  These four
+#     files also have bugs fixed with this patch.  The fact that the two
+#     doubles in an IBM long double may have different signs means that
+#     negation and absolute value operations can't just twiddle one sign bit
+#     as you can with ieee864 style extended double.  fmodl, remainderl,
+#     erfl and erfcl all had errors of this type.  erfl also returned +1 for
+#     large magnitude negative input where it should return -1.  The hypotl
+#     error is innocuous since the value adjusted twice is only used as a
+#     flag.  The e_hypotl.c tests for large "a" and small "b" are mutually
+#     exclusive because we've already exited when x/y > 2**120.  That allows
+#     some further small simplifications.
+#     
+#         [BZ #15734], [BZ #15735]
+#         * sysdeps/ieee754/ldbl-128ibm/e_fmodl.c (__ieee754_fmodl): Rewrite
+#         all uses of ieee875 long double macros and unions.  Simplify test
+#         for 0.0L.  Correct |x|<|y| and |x|=|y| test.  Use
+#         ldbl_extract_mantissa value for ix,iy exponents.  Properly
+#         normalize after ldbl_extract_mantissa, and don't add hidden bit
+#         already handled.  Don't treat low word of ieee854 mantissa like
+#         low word of IBM long double and mask off bit when testing for
+#         zero.
+#         * sysdeps/ieee754/ldbl-128ibm/e_hypotl.c (__ieee754_hypotl): Rewrite
+#         all uses of ieee875 long double macros and unions.  Simplify tests
+#         for 0.0L and inf.  Correct double adjustment of k.  Delete dead code
+#         adjusting ha,hb.  Simplify code setting kld.  Delete two600 and
+#         two1022, instead use their values.  Recognise that tests for large
+#         "a" and small "b" are mutually exclusive.  Rename vars.  Comment.
+#         * sysdeps/ieee754/ldbl-128ibm/e_remainderl.c (__ieee754_remainderl):
+#         Rewrite all uses of ieee875 long double macros and unions.  Simplify
+#         test for 0.0L and nan.  Correct negation.
+#         * sysdeps/ieee754/ldbl-128ibm/s_erfl.c (__erfl): Rewrite all uses of
+#         ieee875 long double macros and unions.  Correct output for large
+#         magnitude x.  Correct absolute value calculation.
+#         (__erfcl): Likewise.
+#         * math/libm-test.inc: Add tests for errors discovered in IBM long
+#         double versions of fmodl, remainderl, erfl and erfcl.
+# 
+diff -urN glibc-2.17-c758a686.orig/math/libm-test.inc glibc-2.17-c758a686.diff/math/libm-test.inc
+--- glibc-2.17-c758a686.orig/math/libm-test.inc	2014-05-27 20:02:29.000000000 -0500
++++ glibc-2.17-c758a686.diff/math/libm-test.inc	2014-05-27 20:09:59.000000000 -0500
+@@ -4040,6 +4040,10 @@
+   TEST_f_f (erf, 2.0L, 0.995322265018952734162069256367252929L);
+   TEST_f_f (erf, 4.125L, 0.999999994576599200434933994687765914L);
+   TEST_f_f (erf, 27.0L, 1.0L);
++#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 54
++  /* The input is not exactly representable as a double.  */
++  TEST_f_f (erf, -0x1.fffffffffffff8p-2L, -0.5204998778130465132916303345518417673509L);
++#endif
+ 
+   END (erf);
+ }
+@@ -4071,6 +4075,10 @@
+   TEST_f_f (erfc, 0x1.ffa002p+2L, 1.233585992097580296336099501489175967033e-29L);
+   TEST_f_f (erfc, 0x1.ffffc8p+2L, 1.122671365033056305522366683719541099329e-29L);
+ #ifdef TEST_LDOUBLE
++# if LDBL_MANT_DIG >= 54
++  /* The input is not exactly representable as a double.  */
++  TEST_f_f (erfc, -0x1.fffffffffffff8p-2L, 1.52049987781304651329163033455184176735L);
++# endif
+   /* The result can only be represented in long double.  */
+ # if LDBL_MIN_10_EXP < -319
+   TEST_f_f (erfc, 27.0L, 0.523704892378925568501606768284954709e-318L);
+@@ -5634,6 +5642,13 @@
+ #if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381
+   TEST_ff_f (fmod, 0x0.fffffffffffffffep-16382L, 0x1p-16445L, plus_zero);
+ #endif
++#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 56
++  TEST_ff_f (fmod, -0x1.00000000000004p+0L, 0x1.fffffffffffff8p-1L, -0x1p-53L);
++  TEST_ff_f (fmod, 0x1.fffffffffffffap-1L, 0x1.fffffffffffff8p-1L, 0x1p-56L);
++  TEST_ff_f (fmod, -0x1.fffffffffffffap-1L, 0x1.fffffffffffff8p-1L, -0x1p-56L);
++  TEST_ff_f (fmod, 0x1.fffffffffffffap-1L, -0x1.fffffffffffff8p-1L, 0x1p-56L);
++  TEST_ff_f (fmod, -0x1.fffffffffffffap-1L, -0x1.fffffffffffff8p-1L, -0x1p-56L);
++#endif
+ 
+   END (fmod);
+ }
+@@ -8642,6 +8657,9 @@
+   TEST_ff_f (remainder, -1.625, -1.0, 0.375);
+   TEST_ff_f (remainder, 5.0, 2.0, 1.0);
+   TEST_ff_f (remainder, 3.0, 2.0, -1.0);
++#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 56
++  TEST_ff_f (remainder, -0x1.80000000000002p1L, 2.0, 0x1.fffffffffffff8p-1L);
++#endif
+ 
+   END (remainder);
+ }
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c	2014-05-27 20:02:27.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c	2014-05-27 20:04:08.000000000 -0500
+@@ -27,76 +27,83 @@
+ long double
+ __ieee754_fmodl (long double x, long double y)
+ {
+-	int64_t n,hx,hy,hz,ix,iy,sx, i;
+-	u_int64_t lx,ly,lz;
+-	int temp;
+-
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
+-	GET_LDOUBLE_WORDS64(hy,ly,y);
++	int64_t hx, hy, hz, sx, sy;
++	uint64_t lx, ly, lz;
++	int n, ix, iy;
++	double xhi, xlo, yhi, ylo;
++
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
++	ldbl_unpack (y, &yhi, &ylo);
++	EXTRACT_WORDS64 (hy, yhi);
++	EXTRACT_WORDS64 (ly, ylo);
+ 	sx = hx&0x8000000000000000ULL;		/* sign of x */
+-	hx ^=sx;				/* |x| */
+-	hy &= 0x7fffffffffffffffLL;		/* |y| */
++	hx ^= sx;				/* |x| */
++	sy = hy&0x8000000000000000ULL;		/* sign of y */
++	hy ^= sy;				/* |y| */
+ 
+     /* purge off exception values */
+-	if(__builtin_expect((hy|(ly&0x7fffffffffffffff))==0 ||
++	if(__builtin_expect(hy==0 ||
+ 			    (hx>=0x7ff0000000000000LL)|| /* y=0,or x not finite */
+ 			    (hy>0x7ff0000000000000LL),0))	/* or y is NaN */
+ 	    return (x*y)/(x*y);
+-	if(__builtin_expect(hx<=hy,0)) {
+-	    if((hx<hy)||(lx<ly)) return x;	/* |x|<|y| return x */
+-	    if(lx==ly)
+-		return Zero[(u_int64_t)sx>>63];	/* |x|=|y| return x*0*/
++	if (__builtin_expect (hx <= hy, 0))
++	  {
++	    /* If |x| < |y| return x.  */
++	    if (hx < hy)
++	      return x;
++	    /* At this point the absolute value of the high doubles of
++	       x and y must be equal.  */
++	    /* If the low double of y is the same sign as the high
++	       double of y (ie. the low double increases |y|)...  */
++	    if (((ly ^ sy) & 0x8000000000000000LL) == 0
++		/* ... then a different sign low double to high double
++		   for x or same sign but lower magnitude...  */
++		&& (int64_t) (lx ^ sx) < (int64_t) (ly ^ sy))
++	      /* ... means |x| < |y|.  */
++	      return x;
++	    /* If the low double of x differs in sign to the high
++	       double of x (ie. the low double decreases |x|)...  */
++	    if (((lx ^ sx) & 0x8000000000000000LL) != 0
++		/* ... then a different sign low double to high double
++		   for y with lower magnitude (we've already caught
++		   the same sign for y case above)...  */
++		&& (int64_t) (lx ^ sx) > (int64_t) (ly ^ sy))
++	      /* ... means |x| < |y|.  */
++	      return x;
++	    /* If |x| == |y| return x*0.  */
++	    if ((lx ^ sx) == (ly ^ sy))
++	      return Zero[(uint64_t) sx >> 63];
+ 	}
+ 
+-    /* determine ix = ilogb(x) */
+-	if(__builtin_expect(hx<0x0010000000000000LL,0)) {	/* subnormal x */
+-	    if(hx==0) {
+-		for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+-	    } else {
+-		for (ix = -1022, i=(hx<<11); i>0; i<<=1) ix -=1;
+-	    }
+-	} else ix = (hx>>52)-0x3ff;
+-
+-    /* determine iy = ilogb(y) */
+-	if(__builtin_expect(hy<0x0010000000000000LL,0)) {	/* subnormal y */
+-	    if(hy==0) {
+-		for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+-	    } else {
+-		for (iy = -1022, i=(hy<<11); i>0; i<<=1) iy -=1;
+-	    }
+-	} else iy = (hy>>52)-0x3ff;
+-
+     /* Make the IBM extended format 105 bit mantissa look like the ieee854 112
+        bit mantissa so the following operations will give the correct
+        result.  */
+-	ldbl_extract_mantissa(&hx, &lx, &temp, x);
+-	ldbl_extract_mantissa(&hy, &ly, &temp, y);
++	ldbl_extract_mantissa(&hx, &lx, &ix, x);
++	ldbl_extract_mantissa(&hy, &ly, &iy, y);
+ 
+-    /* set up {hx,lx}, {hy,ly} and align y to x */
+-	if(__builtin_expect(ix >= -1022, 1))
+-	    hx = 0x0001000000000000LL|(0x0000ffffffffffffLL&hx);
+-	else {		/* subnormal x, shift x to normal */
+-	    n = -1022-ix;
+-	    if(n<=63) {
+-		hx = (hx<<n)|(lx>>(64-n));
+-		lx <<= n;
+-	    } else {
+-		hx = lx<<(n-64);
+-		lx = 0;
+-	    }
+-	}
+-	if(__builtin_expect(iy >= -1022, 1))
+-	    hy = 0x0001000000000000LL|(0x0000ffffffffffffLL&hy);
+-	else {		/* subnormal y, shift y to normal */
+-	    n = -1022-iy;
+-	    if(n<=63) {
+-		hy = (hy<<n)|(ly>>(64-n));
+-		ly <<= n;
+-	    } else {
+-		hy = ly<<(n-64);
+-		ly = 0;
+-	    }
+-	}
++	if (__builtin_expect (ix == -IEEE754_DOUBLE_BIAS, 0))
++	  {
++	    /* subnormal x, shift x to normal.  */
++	    while ((hx & (1LL << 48)) == 0)
++	      {
++		hx = (hx << 1) | (lx >> 63);
++		lx = lx << 1;
++		ix -= 1;
++	      }
++	  }
++
++	if (__builtin_expect (iy == -IEEE754_DOUBLE_BIAS, 0))
++	  {
++	    /* subnormal y, shift y to normal.  */
++	    while ((hy & (1LL << 48)) == 0)
++	      {
++		hy = (hy << 1) | (ly >> 63);
++		ly = ly << 1;
++		iy -= 1;
++	      }
++	  }
+ 
+     /* fix point fmod */
+ 	n = ix - iy;
+@@ -104,7 +111,7 @@
+ 	    hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ 	    if(hz<0){hx = hx+hx+(lx>>63); lx = lx+lx;}
+ 	    else {
+-		if((hz|(lz&0x7fffffffffffffff))==0)		/* return sign(x)*0 */
++		if((hz|lz)==0)		/* return sign(x)*0 */
+ 		    return Zero[(u_int64_t)sx>>63];
+ 		hx = hz+hz+(lz>>63); lx = lz+lz;
+ 	    }
+@@ -113,7 +120,7 @@
+ 	if(hz>=0) {hx=hz;lx=lz;}
+ 
+     /* convert back to floating value and restore the sign */
+-	if((hx|(lx&0x7fffffffffffffff))==0)			/* return sign(x)*0 */
++	if((hx|lx)==0)			/* return sign(x)*0 */
+ 	    return Zero[(u_int64_t)sx>>63];
+ 	while(hx<0x0001000000000000LL) {	/* normalize x */
+ 	    hx = hx+hx+(lx>>63); lx = lx+lx;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c	2014-05-27 20:02:27.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c	2014-05-27 20:04:08.000000000 -0500
+@@ -45,76 +45,84 @@
+ #include <math.h>
+ #include <math_private.h>
+ 
+-static const long double two600 = 0x1.0p+600L;
+-static const long double two1022 = 0x1.0p+1022L;
+-
+ long double
+ __ieee754_hypotl(long double x, long double y)
+ {
+-	long double a,b,t1,t2,y1,y2,w,kld;
++	long double a,b,a1,a2,b1,b2,w,kld;
+ 	int64_t j,k,ha,hb;
++	double xhi, yhi, hi, lo;
+ 
+-	GET_LDOUBLE_MSW64(ha,x);
++	xhi = ldbl_high (x);
++	EXTRACT_WORDS64 (ha, xhi);
++	yhi = ldbl_high (y);
++	EXTRACT_WORDS64 (hb, yhi);
+ 	ha &= 0x7fffffffffffffffLL;
+-	GET_LDOUBLE_MSW64(hb,y);
+ 	hb &= 0x7fffffffffffffffLL;
+ 	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ 	a = fabsl(a);	/* a <- |a| */
+ 	b = fabsl(b);	/* b <- |b| */
+-	if((ha-hb)>0x780000000000000LL) {return a+b;} /* x/y > 2**120 */
++	if((ha-hb)>0x0780000000000000LL) {return a+b;} /* x/y > 2**120 */
+ 	k=0;
+ 	kld = 1.0L;
+ 	if(ha > 0x5f30000000000000LL) {	/* a>2**500 */
+ 	   if(ha >= 0x7ff0000000000000LL) {	/* Inf or NaN */
+-	       u_int64_t low;
+ 	       w = a+b;			/* for sNaN */
+-	       GET_LDOUBLE_LSW64(low,a);
+-	       if(((ha&0xfffffffffffffLL)|(low&0x7fffffffffffffffLL))==0)
++	       if(ha == 0x7ff0000000000000LL)
+ 		 w = a;
+-	       GET_LDOUBLE_LSW64(low,b);
+-	       if(((hb^0x7ff0000000000000LL)|(low&0x7fffffffffffffffLL))==0)
++	       if(hb == 0x7ff0000000000000LL)
+ 		 w = b;
+ 	       return w;
+ 	   }
+ 	   /* scale a and b by 2**-600 */
+-	   ha -= 0x2580000000000000LL; hb -= 0x2580000000000000LL; k += 600;
+-	   a /= two600;
+-	   b /= two600;
+-	   k += 600;
+-	   kld = two600;
++	   a *= 0x1p-600L;
++	   b *= 0x1p-600L;
++	   k = 600;
++	   kld = 0x1p+600L;
+ 	}
+-	if(hb < 0x23d0000000000000LL) {	/* b < 2**-450 */
++	else if(hb < 0x23d0000000000000LL) {	/* b < 2**-450 */
+ 	    if(hb <= 0x000fffffffffffffLL) {	/* subnormal b or 0 */
+-		u_int64_t low;
+-		GET_LDOUBLE_LSW64(low,b);
+-		if((hb|(low&0x7fffffffffffffffLL))==0) return a;
+-		t1=two1022;	/* t1=2^1022 */
+-		b *= t1;
+-		a *= t1;
+-		k -= 1022;
+-		kld = kld / two1022;
++		if(hb==0) return a;
++		a *= 0x1p+1022L;
++		b *= 0x1p+1022L;
++		k = -1022;
++		kld = 0x1p-1022L;
+ 	    } else {		/* scale a and b by 2^600 */
+-		ha += 0x2580000000000000LL;	/* a *= 2^600 */
+-		hb += 0x2580000000000000LL;	/* b *= 2^600 */
+-		k -= 600;
+-		a *= two600;
+-		b *= two600;
+-		kld = kld / two600;
++		a *= 0x1p+600L;
++		b *= 0x1p+600L;
++		k = -600;
++		kld = 0x1p-600L;
+ 	    }
+ 	}
+     /* medium size a and b */
+ 	w = a-b;
+ 	if (w>b) {
+-	    SET_LDOUBLE_WORDS64(t1,ha,0);
+-	    t2 = a-t1;
+-	    w  = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
++	    ldbl_unpack (a, &hi, &lo);
++	    a1 = hi;
++	    a2 = lo;
++	    /* a*a + b*b
++	       = (a1+a2)*a + b*b
++	       = a1*a + a2*a + b*b
++	       = a1*(a1+a2) + a2*a + b*b
++	       = a1*a1 + a1*a2 + a2*a + b*b
++	       = a1*a1 + a2*(a+a1) + b*b  */
++	    w  = __ieee754_sqrtl(a1*a1-(b*(-b)-a2*(a+a1)));
+ 	} else {
+ 	    a  = a+a;
+-	    SET_LDOUBLE_WORDS64(y1,hb,0);
+-	    y2 = b - y1;
+-	    SET_LDOUBLE_WORDS64(t1,ha+0x0010000000000000LL,0);
+-	    t2 = a - t1;
+-	    w  = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
++	    ldbl_unpack (b, &hi, &lo);
++	    b1 = hi;
++	    b2 = lo;
++	    ldbl_unpack (a, &hi, &lo);
++	    a1 = hi;
++	    a2 = lo;
++	    /* a*a + b*b
++	       = a*a + (a-b)*(a-b) - (a-b)*(a-b) + b*b
++	       = a*a + w*w  - (a*a - 2*a*b + b*b) + b*b
++	       = w*w + 2*a*b
++	       = w*w + (a1+a2)*b
++	       = w*w + a1*b + a2*b
++	       = w*w + a1*(b1+b2) + a2*b
++	       = w*w + a1*b1 + a1*b2 + a2*b  */
++	    w  = __ieee754_sqrtl(a1*b1-(w*(-w)-(a1*b2+a2*b)));
+ 	}
+ 	if(k!=0)
+ 	    return w*kld;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c	2014-05-27 20:02:27.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c	2014-05-27 20:04:08.000000000 -0500
+@@ -33,18 +33,22 @@
+ 	int64_t hx,hp;
+ 	u_int64_t sx,lx,lp;
+ 	long double p_half;
++	double xhi, xlo, phi, plo;
+ 
+-	GET_LDOUBLE_WORDS64(hx,lx,x);
+-	GET_LDOUBLE_WORDS64(hp,lp,p);
++	ldbl_unpack (x, &xhi, &xlo);
++	EXTRACT_WORDS64 (hx, xhi);
++	EXTRACT_WORDS64 (lx, xlo);
++	ldbl_unpack (p, &phi, &plo);
++	EXTRACT_WORDS64 (hp, phi);
++	EXTRACT_WORDS64 (lp, plo);
+ 	sx = hx&0x8000000000000000ULL;
+ 	hp &= 0x7fffffffffffffffLL;
+ 	hx &= 0x7fffffffffffffffLL;
+ 
+     /* purge off exception values */
+-	if((hp|(lp&0x7fffffffffffffff))==0) return (x*p)/(x*p);	/* p = 0 */
++	if(hp==0) return (x*p)/(x*p);	/* p = 0 */
+ 	if((hx>=0x7ff0000000000000LL)||			/* x not finite */
+-	  ((hp>=0x7ff0000000000000LL)&&			/* p is NaN */
+-	  (((hp-0x7ff0000000000000LL)|lp)!=0)))
++	   (hp>0x7ff0000000000000LL))			/* p is NaN */
+ 	    return (x*p)/(x*p);
+ 
+ 
+@@ -64,8 +68,8 @@
+ 		if(x>=p_half) x -= p;
+ 	    }
+ 	}
+-	GET_LDOUBLE_MSW64(hx,x);
+-	SET_LDOUBLE_MSW64(x,hx^sx);
++	if (sx)
++	  x = -x;
+ 	return x;
+ }
+ strong_alias (__ieee754_remainderl, __remainderl_finite)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_erfl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_erfl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_erfl.c	2014-05-27 20:02:27.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/s_erfl.c	2014-05-27 20:04:08.000000000 -0500
+@@ -760,16 +760,16 @@
+ __erfl (long double x)
+ {
+   long double a, y, z;
+-  int32_t i, ix, sign;
+-  ieee854_long_double_shape_type u;
++  int32_t i, ix, hx;
++  double xhi;
+ 
+-  u.value = x;
+-  sign = u.parts32.w0;
+-  ix = sign & 0x7fffffff;
++  xhi = ldbl_high (x);
++  GET_HIGH_WORD (hx, xhi);
++  ix = hx & 0x7fffffff;
+ 
+   if (ix >= 0x7ff00000)
+     {				/* erf(nan)=nan */
+-      i = ((sign & 0xfff00000) >> 31) << 1;
++      i = ((uint32_t) hx >> 31) << 1;
+       return (long double) (1 - i) + one / x;	/* erf(+-inf)=+-1 */
+     }
+ 
+@@ -778,7 +778,7 @@
+       if (ix >= 0x4039A0DE)
+ 	{
+ 	/* __erfcl (x) underflows if x > 25.6283 */
+-	  if (sign)
++	  if ((hx & 0x80000000) == 0)
+ 	    return one-tiny;
+ 	  else
+ 	    return tiny-one;
+@@ -789,8 +789,9 @@
+ 	  return (one - y);
+ 	}
+     }
+-  u.parts32.w0 = ix;
+-  a = u.value;
++  a = x;
++  if ((hx & 0x80000000) != 0)
++    a = -a;
+   z = x * x;
+   if (ix < 0x3fec0000)  /* a < 0.875 */
+     {
+@@ -814,7 +815,7 @@
+       y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2);
+     }
+ 
+-  if (sign & 0x80000000) /* x < 0 */
++  if (hx & 0x80000000) /* x < 0 */
+     y = -y;
+   return( y );
+ }
+@@ -824,18 +825,18 @@
+ __erfcl (long double x)
+ {
+   long double y, z, p, r;
+-  int32_t i, ix, sign;
+-  ieee854_long_double_shape_type u;
+-
+-  u.value = x;
+-  sign = u.parts32.w0;
+-  ix = sign & 0x7fffffff;
+-  u.parts32.w0 = ix;
++  int32_t i, ix;
++  uint32_t hx;
++  double xhi;
++
++  xhi = ldbl_high (x);
++  GET_HIGH_WORD (hx, xhi);
++  ix = hx & 0x7fffffff;
+ 
+   if (ix >= 0x7ff00000)
+     {				/* erfc(nan)=nan */
+       /* erfc(+-inf)=0,2 */
+-      return (long double) (((u_int32_t) sign >> 31) << 1) + one / x;
++      return (long double) ((hx >> 31) << 1) + one / x;
+     }
+ 
+   if (ix < 0x3fd00000) /* |x| <1/4 */
+@@ -846,7 +847,8 @@
+     }
+   if (ix < 0x3ff40000) /* 1.25 */
+     {
+-      x = u.value;
++      if ((hx & 0x80000000) != 0)
++	x = -x;
+       i = 8.0 * x;
+       switch (i)
+ 	{
+@@ -891,7 +893,7 @@
+ 	  y += C20a;
+ 	  break;
+ 	}
+-      if (sign & 0x80000000)
++      if (hx & 0x80000000)
+ 	y = 2.0L - y;
+       return y;
+     }
+@@ -899,10 +901,11 @@
+   if (ix < 0x405ac000)
+     {
+       /* x < -9 */
+-      if ((ix >= 0x40220000) && (sign & 0x80000000))
++      if (hx >= 0xc0220000)
+ 	return two - tiny;
+ 
+-      x = fabsl (x);
++      if ((hx & 0x80000000) != 0)
++	x = -x;
+       z = one / (x * x);
+       i = 8.0 / x;
+       switch (i)
+@@ -933,21 +936,17 @@
+ 	  p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8);
+ 	  break;
+ 	}
+-      u.value = x;
+-      u.parts32.w3 = 0;
+-      u.parts32.w2 = 0;
+-      u.parts32.w1 &= 0xf8000000;
+-      z = u.value;
++      z = (float) x;
+       r = __ieee754_expl (-z * z - 0.5625) *
+ 	__ieee754_expl ((z - x) * (z + x) + p);
+-      if ((sign & 0x80000000) == 0)
++      if ((hx & 0x80000000) == 0)
+ 	return r / x;
+       else
+ 	return two - r / x;
+     }
+   else
+     {
+-      if ((sign & 0x80000000) == 0)
++      if ((hx & 0x80000000) == 0)
+ 	return tiny * tiny;
+       else
+ 	return two - tiny;
diff --git a/SOURCES/glibc-ppc64le-10.patch b/SOURCES/glibc-ppc64le-10.patch
new file mode 100644
index 0000000..87e7637
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-10.patch
@@ -0,0 +1,91 @@
+# commit 32c301dfc9b786453e59b61fe4a821a89e1a206b
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:26:39 2013 +0930
+# 
+#     PowerPC floating point little-endian [5 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00085.html
+#     
+#     Rid ourselves of ieee854.
+#     
+#         * sysdeps/ieee754/ldbl-128ibm/ieee754.h (union ieee854_long_double):
+#         Delete.
+#         (IEEE854_LONG_DOUBLE_BIAS): Delete.
+#         * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h: Don't include ieee854
+#         version of math_ldbl.h.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/ieee754.h glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/ieee754.h
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/ieee754.h	2014-05-27 22:10:43.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/ieee754.h	2014-05-27 22:11:10.000000000 -0500
+@@ -112,61 +112,6 @@
+ #define IEEE754_DOUBLE_BIAS	0x3ff /* Added to exponent.  */
+ 
+ 
+-union ieee854_long_double
+-  {
+-    long double d;
+-
+-    /* This is the IEEE 854 quad-precision format.  */
+-    struct
+-      {
+-#if	__BYTE_ORDER == __BIG_ENDIAN
+-	unsigned int negative:1;
+-	unsigned int exponent:15;
+-	/* Together these comprise the mantissa.  */
+-	unsigned int mantissa0:16;
+-	unsigned int mantissa1:32;
+-	unsigned int mantissa2:32;
+-	unsigned int mantissa3:32;
+-#endif				/* Big endian.  */
+-#if	__BYTE_ORDER == __LITTLE_ENDIAN
+-	/* Together these comprise the mantissa.  */
+-	unsigned int mantissa3:32;
+-	unsigned int mantissa2:32;
+-	unsigned int mantissa1:32;
+-	unsigned int mantissa0:16;
+-	unsigned int exponent:15;
+-	unsigned int negative:1;
+-#endif				/* Little endian.  */
+-      } ieee;
+-
+-    /* This format makes it easier to see if a NaN is a signalling NaN.  */
+-    struct
+-      {
+-#if	__BYTE_ORDER == __BIG_ENDIAN
+-	unsigned int negative:1;
+-	unsigned int exponent:15;
+-	unsigned int quiet_nan:1;
+-	/* Together these comprise the mantissa.  */
+-	unsigned int mantissa0:15;
+-	unsigned int mantissa1:32;
+-	unsigned int mantissa2:32;
+-	unsigned int mantissa3:32;
+-#else
+-	/* Together these comprise the mantissa.  */
+-	unsigned int mantissa3:32;
+-	unsigned int mantissa2:32;
+-	unsigned int mantissa1:32;
+-	unsigned int mantissa0:15;
+-	unsigned int quiet_nan:1;
+-	unsigned int exponent:15;
+-	unsigned int negative:1;
+-#endif
+-      } ieee_nan;
+-  };
+-
+-#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent.  */
+-
+-
+ /* IBM extended format for long double.
+ 
+    Each long double is made up of two IEEE doubles.  The value of the
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-27 22:10:43.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h	2014-05-27 22:11:10.000000000 -0500
+@@ -2,7 +2,6 @@
+ #error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
+ #endif
+ 
+-#include <sysdeps/ieee754/ldbl-128/math_ldbl.h>
+ #include <ieee754.h>
+   
+ static inline void
diff --git a/SOURCES/glibc-ppc64le-11.patch b/SOURCES/glibc-ppc64le-11.patch
new file mode 100644
index 0000000..0b4c25a
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-11.patch
@@ -0,0 +1,113 @@
+# commit 62a728aeff93507ce5975f245a5f1d2046fb4503
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:27:19 2013 +0930
+# 
+#     PowerPC floating point little-endian [6 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-07/msg00197.html
+#     
+#     A rewrite to make this code correct for little-endian.
+#     
+#         * sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c (mynumber): Replace
+#         union 32-bit int array member with 64-bit int array.
+#         (t515, tm256): Double rather than long double.
+#         (__ieee754_sqrtl): Rewrite using 64-bit arithmetic.
+#
+diff -urN glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c
+--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c	2014-05-27 22:20:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c	2014-05-27 22:21:39.000000000 -0500
+@@ -34,15 +34,13 @@
+ 
+ #include <math_private.h>
+ 
+-typedef unsigned int int4;
+-typedef union {int4 i[4]; long double x; double d[2]; } mynumber;
++typedef union {int64_t i[2]; long double x; double d[2]; } mynumber;
+ 
+-static const  mynumber
+-  t512 = {{0x5ff00000, 0x00000000, 0x00000000, 0x00000000 }},  /* 2^512  */
+-  tm256 = {{0x2ff00000, 0x00000000, 0x00000000, 0x00000000 }};  /* 2^-256 */
+ static const double
+-two54 = 1.80143985094819840000e+16, /* 0x4350000000000000 */
+-twom54 = 5.55111512312578270212e-17; /* 0x3C90000000000000 */
++  t512 = 0x1p512,
++  tm256 = 0x1p-256,
++  two54 = 0x1p54,	/* 0x4350000000000000 */
++  twom54 = 0x1p-54;	/* 0x3C90000000000000 */
+ 
+ /*********************************************************************/
+ /* An ultimate sqrt routine. Given an IEEE double machine number x   */
+@@ -54,56 +52,53 @@
+   static const long double big = 134217728.0, big1 = 134217729.0;
+   long double t,s,i;
+   mynumber a,c;
+-  int4 k, l, m;
+-  int n;
++  uint64_t k, l;
++  int64_t m, n;
+   double d;
+ 
+   a.x=x;
+-  k=a.i[0] & 0x7fffffff;
++  k=a.i[0] & INT64_C(0x7fffffffffffffff);
+   /*----------------- 2^-1022  <= | x |< 2^1024  -----------------*/
+-  if (k>0x000fffff && k<0x7ff00000) {
++  if (k>INT64_C(0x000fffff00000000) && k<INT64_C(0x7ff0000000000000)) {
+     if (x < 0) return (big1-big1)/(big-big);
+-    l = (k&0x001fffff)|0x3fe00000;
+-    if (((a.i[2] & 0x7fffffff) | a.i[3]) != 0) {
+-      n = (int) ((l - k) * 2) >> 21;
+-      m = (a.i[2] >> 20) & 0x7ff;
++    l = (k&INT64_C(0x001fffffffffffff))|INT64_C(0x3fe0000000000000);
++    if ((a.i[1] & INT64_C(0x7fffffffffffffff)) != 0) {
++      n = (int64_t) ((l - k) * 2) >> 53;
++      m = (a.i[1] >> 52) & 0x7ff;
+       if (m == 0) {
+ 	a.d[1] *= two54;
+-	m = ((a.i[2] >> 20) & 0x7ff) - 54;
++	m = ((a.i[1] >> 52) & 0x7ff) - 54;
+       }
+       m += n;
+-      if ((int) m > 0)
+-	a.i[2] = (a.i[2] & 0x800fffff) | (m << 20);
+-      else if ((int) m <= -54) {
+-	a.i[2] &= 0x80000000;
+-	a.i[3] = 0;
++      if (m > 0)
++	a.i[1] = (a.i[1] & INT64_C(0x800fffffffffffff)) | (m << 52);
++      else if (m <= -54) {
++	a.i[1] &= INT64_C(0x8000000000000000);
+       } else {
+ 	m += 54;
+-	a.i[2] = (a.i[2] & 0x800fffff) | (m << 20);
++	a.i[1] = (a.i[1] & INT64_C(0x800fffffffffffff)) | (m << 52);
+ 	a.d[1] *= twom54;
+       }
+     }
+     a.i[0] = l;
+     s = a.x;
+     d = __ieee754_sqrt (a.d[0]);
+-    c.i[0] = 0x20000000+((k&0x7fe00000)>>1);
++    c.i[0] = INT64_C(0x2000000000000000)+((k&INT64_C(0x7fe0000000000000))>>1);
+     c.i[1] = 0;
+-    c.i[2] = 0;
+-    c.i[3] = 0;
+     i = d;
+     t = 0.5L * (i + s / i);
+     i = 0.5L * (t + s / t);
+     return c.x * i;
+   }
+   else {
+-    if (k>=0x7ff00000) {
+-      if (a.i[0] == 0xfff00000 && a.i[1] == 0)
++    if (k>=INT64_C(0x7ff0000000000000)) {
++      if (a.i[0] == INT64_C(0xfff0000000000000))
+ 	return (big1-big1)/(big-big); /* sqrt (-Inf) = NaN.  */
+       return x; /* sqrt (NaN) = NaN, sqrt (+Inf) = +Inf.  */
+     }
+     if (x == 0) return x;
+     if (x < 0) return (big1-big1)/(big-big);
+-    return tm256.x*__ieee754_sqrtl(x*t512.x);
++    return tm256*__ieee754_sqrtl(x*t512);
+   }
+ }
+ strong_alias (__ieee754_sqrtl, __sqrtl_finite)
diff --git a/SOURCES/glibc-ppc64le-12.patch b/SOURCES/glibc-ppc64le-12.patch
new file mode 100644
index 0000000..6d24e2e
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-12.patch
@@ -0,0 +1,75 @@
+# commit 2ca85d2bbbaa60b9c83bf1f57a2801c84e0a3625
+# Author: Anton Blanchard <anton@au1.ibm.com>
+# Date:   Sat Aug 17 18:28:06 2013 +0930
+# 
+#     PowerPC floating point little-endian [7 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00086.html
+#     
+#         * sysdeps/powerpc/bits/mathinline.h (__signbitf): Use builtin.
+#         (__signbit): Likewise.  Correct for little-endian.
+#         (__signbitl): Call __signbit.
+#         (lrint): Correct for little-endian.
+#         (lrintf): Call lrint.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/bits/mathinline.h glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/bits/mathinline.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/bits/mathinline.h	2014-05-27 22:28:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/bits/mathinline.h	2014-05-27 22:28:37.000000000 -0500
+@@ -62,21 +62,28 @@
+ __MATH_INLINE int
+ __NTH (__signbitf (float __x))
+ {
++#if __GNUC_PREREQ (4, 0)
++  return __builtin_signbitf (__x);
++#else
+   __extension__ union { float __f; int __i; } __u = { __f: __x };
+   return __u.__i < 0;
++#endif
+ }
+ __MATH_INLINE int
+ __NTH (__signbit (double __x))
+ {
+-  __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
+-  return __u.__i[0] < 0;
++#if __GNUC_PREREQ (4, 0)
++  return __builtin_signbit (__x);
++#else
++  __extension__ union { double __d; long long __i; } __u = { __d: __x };
++  return __u.__i < 0;
++#endif
+ }
+ #  ifdef __LONG_DOUBLE_128__
+ __MATH_INLINE int
+ __NTH (__signbitl (long double __x))
+ {
+-  __extension__ union { long double __d; int __i[4]; } __u = { __d: __x };
+-  return __u.__i[0] < 0;
++  return __signbit ((double) __x);
+ }
+ #  endif
+ # endif
+@@ -93,22 +100,17 @@
+ {
+   union {
+     double __d;
+-    int __ll[2];
++    long long __ll;
+   } __u;
+   __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x));
+-  return __u.__ll[1];
++  return __u.__ll;
+ }
+ 
+ __MATH_INLINE long int lrintf (float __x) __THROW;
+ __MATH_INLINE long int
+ __NTH (lrintf (float __x))
+ {
+-  union {
+-    double __d;
+-    int __ll[2];
+-  } __u;
+-  __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x));
+-  return __u.__ll[1];
++  return lrint ((double) __x);
+ }
+ # endif
+ 
diff --git a/SOURCES/glibc-ppc64le-13.patch b/SOURCES/glibc-ppc64le-13.patch
new file mode 100644
index 0000000..3001174
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-13.patch
@@ -0,0 +1,283 @@
+# commit 4a28b3ca4bc52d9a3ac0d9edb53d3de510e1b77c
+# Author: Anton Blanchard <anton@au1.ibm.com>
+# Date:   Sat Aug 17 18:28:55 2013 +0930
+# 
+#     PowerPC floating point little-endian [8 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-07/msg00199.html
+#     
+#     Corrects floating-point environment code for little-endian.
+#     
+#         * sysdeps/powerpc/fpu/fenv_libc.h (fenv_union_t): Replace int
+#         array with long long.
+#         * sysdeps/powerpc/fpu/e_sqrt.c (__slow_ieee754_sqrt): Adjust.
+#         * sysdeps/powerpc/fpu/e_sqrtf.c (__slow_ieee754_sqrtf): Adjust.
+#         * sysdeps/powerpc/fpu/fclrexcpt.c (__feclearexcept): Adjust.
+#         * sysdeps/powerpc/fpu/fedisblxcpt.c (fedisableexcept): Adjust.
+#         * sysdeps/powerpc/fpu/feenablxcpt.c (feenableexcept): Adjust.
+#         * sysdeps/powerpc/fpu/fegetexcept.c (__fegetexcept): Adjust.
+#         * sysdeps/powerpc/fpu/feholdexcpt.c (feholdexcept): Adjust.
+#         * sysdeps/powerpc/fpu/fesetenv.c (__fesetenv): Adjust.
+#         * sysdeps/powerpc/fpu/feupdateenv.c (__feupdateenv): Adjust.
+#         * sysdeps/powerpc/fpu/fgetexcptflg.c (__fegetexceptflag): Adjust.
+#         * sysdeps/powerpc/fpu/fraiseexcpt.c (__feraiseexcept): Adjust.
+#         * sysdeps/powerpc/fpu/fsetexcptflg.c (__fesetexceptflag): Adjust.
+#         * sysdeps/powerpc/fpu/ftestexcept.c (fetestexcept): Adjust.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/e_sqrt.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/e_sqrt.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/e_sqrt.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/e_sqrt.c	2014-05-27 22:31:43.000000000 -0500
+@@ -145,7 +145,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       x = a_nan.value;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/e_sqrtf.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/e_sqrtf.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/e_sqrtf.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/e_sqrtf.c	2014-05-27 22:31:43.000000000 -0500
+@@ -121,7 +121,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       x = a_nan.value;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fclrexcpt.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fclrexcpt.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fclrexcpt.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fclrexcpt.c	2014-05-27 22:31:43.000000000 -0500
+@@ -28,8 +28,8 @@
+   u.fenv = fegetenv_register ();
+ 
+   /* Clear the relevant bits.  */
+-  u.l[1] = u.l[1] & ~((-(excepts >> (31 - FPSCR_VX) & 1) & FE_ALL_INVALID)
+-		      | (excepts & FPSCR_STICKY_BITS));
++  u.l = u.l & ~((-(excepts >> (31 - FPSCR_VX) & 1) & FE_ALL_INVALID)
++		| (excepts & FPSCR_STICKY_BITS));
+ 
+   /* Put the new state in effect.  */
+   fesetenv_register (u.fenv);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fedisblxcpt.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fedisblxcpt.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fedisblxcpt.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fedisblxcpt.c	2014-05-27 22:31:43.000000000 -0500
+@@ -32,15 +32,15 @@
+ 
+   fe.fenv = fegetenv_register ();
+   if (excepts & FE_INEXACT)
+-    fe.l[1] &= ~(1 << (31 - FPSCR_XE));
++    fe.l &= ~(1 << (31 - FPSCR_XE));
+   if (excepts & FE_DIVBYZERO)
+-    fe.l[1] &= ~(1 << (31 - FPSCR_ZE));
++    fe.l &= ~(1 << (31 - FPSCR_ZE));
+   if (excepts & FE_UNDERFLOW)
+-    fe.l[1] &= ~(1 << (31 - FPSCR_UE));
++    fe.l &= ~(1 << (31 - FPSCR_UE));
+   if (excepts & FE_OVERFLOW)
+-    fe.l[1] &= ~(1 << (31 - FPSCR_OE));
++    fe.l &= ~(1 << (31 - FPSCR_OE));
+   if (excepts & FE_INVALID)
+-    fe.l[1] &= ~(1 << (31 - FPSCR_VE));
++    fe.l &= ~(1 << (31 - FPSCR_VE));
+   fesetenv_register (fe.fenv);
+ 
+   new = __fegetexcept ();
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/feenablxcpt.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/feenablxcpt.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/feenablxcpt.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/feenablxcpt.c	2014-05-27 22:31:43.000000000 -0500
+@@ -32,15 +32,15 @@
+ 
+   fe.fenv = fegetenv_register ();
+   if (excepts & FE_INEXACT)
+-    fe.l[1] |= (1 << (31 - FPSCR_XE));
++    fe.l |= (1 << (31 - FPSCR_XE));
+   if (excepts & FE_DIVBYZERO)
+-    fe.l[1] |= (1 << (31 - FPSCR_ZE));
++    fe.l |= (1 << (31 - FPSCR_ZE));
+   if (excepts & FE_UNDERFLOW)
+-    fe.l[1] |= (1 << (31 - FPSCR_UE));
++    fe.l |= (1 << (31 - FPSCR_UE));
+   if (excepts & FE_OVERFLOW)
+-    fe.l[1] |= (1 << (31 - FPSCR_OE));
++    fe.l |= (1 << (31 - FPSCR_OE));
+   if (excepts & FE_INVALID)
+-    fe.l[1] |= (1 << (31 - FPSCR_VE));
++    fe.l |= (1 << (31 - FPSCR_VE));
+   fesetenv_register (fe.fenv);
+ 
+   new = __fegetexcept ();
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fegetexcept.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fegetexcept.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fegetexcept.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fegetexcept.c	2014-05-27 22:31:43.000000000 -0500
+@@ -27,15 +27,15 @@
+ 
+   fe.fenv = fegetenv_register ();
+ 
+-  if (fe.l[1] & (1 << (31 - FPSCR_XE)))
++  if (fe.l & (1 << (31 - FPSCR_XE)))
+       result |= FE_INEXACT;
+-  if (fe.l[1] & (1 << (31 - FPSCR_ZE)))
++  if (fe.l & (1 << (31 - FPSCR_ZE)))
+       result |= FE_DIVBYZERO;
+-  if (fe.l[1] & (1 << (31 - FPSCR_UE)))
++  if (fe.l & (1 << (31 - FPSCR_UE)))
+       result |= FE_UNDERFLOW;
+-  if (fe.l[1] & (1 << (31 - FPSCR_OE)))
++  if (fe.l & (1 << (31 - FPSCR_OE)))
+       result |= FE_OVERFLOW;
+-  if (fe.l[1] & (1 << (31 - FPSCR_VE)))
++  if (fe.l & (1 << (31 - FPSCR_VE)))
+       result |= FE_INVALID;
+ 
+   return result;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/feholdexcpt.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/feholdexcpt.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/feholdexcpt.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/feholdexcpt.c	2014-05-27 22:33:09.000000000 -0500
+@@ -30,13 +30,12 @@
+ 
+   /* Clear everything except for the rounding modes and non-IEEE arithmetic
+      flag.  */
+-  new.l[1] = old.l[1] & 7;
+-  new.l[0] = old.l[0];
++  new.l = old.l & 0xffffffff00000007LL;
+   
+   /* If the old env had any eabled exceptions, then mask SIGFPE in the
+      MSR FE0/FE1 bits.  This may allow the FPU to run faster because it
+      always takes the default action and can not generate SIGFPE. */
+-  if ((old.l[1] & _FPU_MASK_ALL) != 0)
++  if ((old.l & _FPU_MASK_ALL) != 0)
+     (void)__fe_mask_env ();
+ 
+   /* Put the new state in effect.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fenv_libc.h glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fenv_libc.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fenv_libc.h	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fenv_libc.h	2014-05-27 22:31:43.000000000 -0500
+@@ -69,7 +69,7 @@
+ typedef union
+ {
+   fenv_t fenv;
+-  unsigned int l[2];
++  unsigned long long l;
+ } fenv_union_t;
+ 
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fesetenv.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fesetenv.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fesetenv.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fesetenv.c	2014-05-27 22:35:18.000000000 -0500
+@@ -36,14 +36,14 @@
+      exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put the
+      hardware into "precise mode" and may cause the FPU to run slower on some
+      hardware.  */
+-  if ((old.l[1] & _FPU_MASK_ALL) == 0 && (new.l[1] & _FPU_MASK_ALL) != 0)
++  if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0)
+     (void)__fe_nomask_env ();
+   
+   /* If the old env had any enabled exceptions and the new env has no enabled
+      exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+      FPU to run faster because it always takes the default action and can not 
+      generate SIGFPE. */
+-  if ((old.l[1] & _FPU_MASK_ALL) != 0 && (new.l[1] & _FPU_MASK_ALL) == 0)
++  if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0)
+     (void)__fe_mask_env ();
+     
+   fesetenv_register (*envp);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/feupdateenv.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/feupdateenv.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/feupdateenv.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/feupdateenv.c	2014-05-27 22:34:23.000000000 -0500
+@@ -36,20 +36,20 @@
+   /* Restore rounding mode and exception enable from *envp and merge
+      exceptions.  Leave fraction rounded/inexact and FP result/CC bits
+      unchanged.  */
+-  new.l[1] = (old.l[1] & 0x1FFFFF00) | (new.l[1] & 0x1FF80FFF);
++  new.l = (old.l & 0xffffffff1fffff00LL) | (new.l & 0x1ff80fff);
+   
+   /* If the old env has no eabled exceptions and the new env has any enabled
+      exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put
+      the hardware into "precise mode" and may cause the FPU to run slower on
+      some hardware.  */
+-  if ((old.l[1] & _FPU_MASK_ALL) == 0 && (new.l[1] & _FPU_MASK_ALL) != 0)
++  if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0)
+     (void)__fe_nomask_env ();
+   
+   /* If the old env had any eabled exceptions and the new env has no enabled
+      exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+      FPU to run faster because it always takes the default action and can not 
+      generate SIGFPE. */
+-  if ((old.l[1] & _FPU_MASK_ALL) != 0 && (new.l[1] & _FPU_MASK_ALL) == 0)
++  if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0)
+     (void)__fe_mask_env ();
+ 
+   /* Atomically enable and raise (if appropriate) exceptions set in `new'. */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fgetexcptflg.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fgetexcptflg.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fgetexcptflg.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fgetexcptflg.c	2014-05-27 22:31:43.000000000 -0500
+@@ -28,7 +28,7 @@
+   u.fenv = fegetenv_register ();
+ 
+   /* Return (all of) it.  */
+-  *flagp = u.l[1] & excepts & FE_ALL_EXCEPT;
++  *flagp = u.l & excepts & FE_ALL_EXCEPT;
+ 
+   /* Success.  */
+   return 0;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fraiseexcpt.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fraiseexcpt.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fraiseexcpt.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fraiseexcpt.c	2014-05-27 22:31:43.000000000 -0500
+@@ -34,11 +34,11 @@
+   u.fenv = fegetenv_register ();
+ 
+   /* Add the exceptions */
+-  u.l[1] = (u.l[1]
+-	    | (excepts & FPSCR_STICKY_BITS)
+-	    /* Turn FE_INVALID into FE_INVALID_SOFTWARE.  */
+-	    | (excepts >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT))
+-	       & FE_INVALID_SOFTWARE));
++  u.l = (u.l
++	 | (excepts & FPSCR_STICKY_BITS)
++	 /* Turn FE_INVALID into FE_INVALID_SOFTWARE.  */
++	 | (excepts >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT))
++	    & FE_INVALID_SOFTWARE));
+ 
+   /* Store the new status word (along with the rest of the environment),
+      triggering any appropriate exceptions.  */
+@@ -50,7 +50,7 @@
+ 	 don't have FE_INVALID_SOFTWARE implemented.  Detect this
+ 	 case and raise FE_INVALID_SNAN instead.  */
+       u.fenv = fegetenv_register ();
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ 	set_fpscr_bit (FPSCR_VXSNAN);
+     }
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fsetexcptflg.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fsetexcptflg.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fsetexcptflg.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fsetexcptflg.c	2014-05-27 22:31:43.000000000 -0500
+@@ -32,10 +32,10 @@
+   flag = *flagp & excepts;
+ 
+   /* Replace the exception status */
+-  u.l[1] = ((u.l[1] & ~(FPSCR_STICKY_BITS & excepts))
+-	    | (flag & FPSCR_STICKY_BITS)
+-	    | (flag >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT))
+-	       & FE_INVALID_SOFTWARE));
++  u.l = ((u.l & ~(FPSCR_STICKY_BITS & excepts))
++	 | (flag & FPSCR_STICKY_BITS)
++	 | (flag >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT))
++	    & FE_INVALID_SOFTWARE));
+ 
+   /* Store the new status word (along with the rest of the environment).
+      This may cause floating-point exceptions if the restored state
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/ftestexcept.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/ftestexcept.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/ftestexcept.c	2014-05-27 22:31:42.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/ftestexcept.c	2014-05-27 22:31:43.000000000 -0500
+@@ -28,6 +28,6 @@
+ 
+   /* The FE_INVALID bit is dealt with correctly by the hardware, so we can
+      just:  */
+-  return u.l[1] & excepts;
++  return u.l & excepts;
+ }
+ libm_hidden_def (fetestexcept)
diff --git a/SOURCES/glibc-ppc64le-14.patch b/SOURCES/glibc-ppc64le-14.patch
new file mode 100644
index 0000000..434d25d
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-14.patch
@@ -0,0 +1,120 @@
+# commit 603e84104cdc709c8e7dcbac54b9a585bf8dff78
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:29:43 2013 +0930
+# 
+#     PowerPC floating point little-endian [9 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-07/msg00200.html
+#     
+#     This works around the fact that vsx is disabled in current
+#     little-endian gcc.  Also, float constants take 4 bytes in memory
+#     vs. 16 bytes for vector constants, and we don't need to write one lot
+#     of masks for double (register format) and another for float (mem
+#     format).
+#     
+#         * sysdeps/powerpc/fpu/s_float_bitwise.h (__float_and_test28): Don't
+#         use vector int constants.
+#         (__float_and_test24, __float_and8, __float_get_exp): Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/s_float_bitwise.h glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/s_float_bitwise.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/s_float_bitwise.h	2014-05-27 22:37:18.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/s_float_bitwise.h	2014-05-27 22:37:20.000000000 -0500
+@@ -23,18 +23,19 @@
+ #include <math_private.h>
+ 
+ /* Returns (int)(num & 0x7FFFFFF0 == value) */
+-static inline
+-int __float_and_test28 (float num, float value)
++static inline int
++__float_and_test28 (float num, float value)
+ {
+   float ret;
+ #ifdef _ARCH_PWR7
+-  vector int mask = (vector int) {
+-    0x7ffffffe, 0x00000000, 0x00000000, 0x0000000
+-  };
++  union {
++    int i;
++    float f;
++  } mask = { .i = 0x7ffffff0 };
+   __asm__ (
+-  /* the 'f' constrain is use on mask because we just need
++  /* the 'f' constraint is used on mask because we just need
+    * to compare floats, not full vector */
+-    "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask)
++    "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f)
+   );
+ #else
+   int32_t inum;
+@@ -46,16 +47,17 @@
+ }
+ 
+ /* Returns (int)(num & 0x7FFFFF00 == value) */
+-static inline
+-int __float_and_test24 (float num, float value)
++static inline int
++__float_and_test24 (float num, float value)
+ {
+   float ret;
+ #ifdef _ARCH_PWR7
+-  vector int mask = (vector int) {
+-    0x7fffffe0, 0x00000000, 0x00000000, 0x0000000
+-  };
++  union {
++    int i;
++    float f;
++  } mask = { .i = 0x7fffff00 };
+   __asm__ (
+-    "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask)
++    "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f)
+   );
+ #else
+   int32_t inum;
+@@ -67,16 +69,17 @@
+ }
+ 
+ /* Returns (float)(num & 0x7F800000) */
+-static inline
+-float __float_and8 (float num)
++static inline float
++__float_and8 (float num)
+ {
+   float ret;
+ #ifdef _ARCH_PWR7
+-  vector int mask = (vector int) {
+-    0x7ff00000, 0x00000000, 0x00000000, 0x00000000
+-  };
++  union {
++    int i;
++    float f;
++  } mask = { .i = 0x7f800000 };
+   __asm__ (
+-    "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask)
++    "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f)
+   );
+ #else
+   int32_t inum;
+@@ -88,17 +91,18 @@
+ }
+ 
+ /* Returns ((int32_t)(num & 0x7F800000) >> 23) */
+-static inline
+-int32_t __float_get_exp (float num)
++static inline int32_t
++__float_get_exp (float num)
+ {
+   int32_t inum;
+ #ifdef _ARCH_PWR7
+   float ret;
+-  vector int mask = (vector int) {
+-    0x7ff00000, 0x00000000, 0x00000000, 0x00000000
+-  };
++  union {
++    int i;
++    float f;
++  } mask = { .i = 0x7f800000 };
+   __asm__ (
+-    "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask)
++    "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f)
+   );
+   GET_FLOAT_WORD(inum, ret);
+ #else
diff --git a/SOURCES/glibc-ppc64le-15.patch b/SOURCES/glibc-ppc64le-15.patch
new file mode 100644
index 0000000..a81d9a8
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-15.patch
@@ -0,0 +1,119 @@
+# commit da13146da10360436941e843834c90a9aef5fd7a
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:30:23 2013 +0930
+# 
+#     PowerPC floating point little-endian [10 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-07/msg00201.html
+#     
+#     These two functions oddly test x+1>0 when a double x is >= 0.0, and
+#     similarly when x is negative.  I don't see the point of that since the
+#     test should always be true.  I also don't see any need to convert x+1
+#     to integer rather than simply using xr+1.  Note that the standard
+#     allows these functions to return any value when the input is outside
+#     the range of long long, but it's not too hard to prevent xr+1
+#     overflowing so that's what I've done.
+#     
+#     (With rounding mode FE_UPWARD, x+1 can be a lot more than what you
+#     might naively expect, but perhaps that situation was covered by the
+#     x - xrf < 1.0 test.)
+#     
+#         * sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite.
+#         * sysdeps/powerpc/fpu/s_llroundf.c (__llroundf): Rewrite.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/s_llround.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/s_llround.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/s_llround.c	2014-05-27 22:38:55.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/s_llround.c	2014-05-27 22:38:58.000000000 -0500
+@@ -19,29 +19,28 @@
+ #include <math.h>
+ #include <math_ldbl_opt.h>
+ 
+-/* I think that what this routine is supposed to do is round a value
+-   to the nearest integer, with values exactly on the boundary rounded
+-   away from zero.  */
+-/* This routine relies on (long long)x, when x is out of range of a long long,
+-   clipping to MAX_LLONG or MIN_LLONG.  */
++/* Round to the nearest integer, with values exactly on a 0.5 boundary
++   rounded away from zero, regardless of the current rounding mode.
++   If (long long)x, when x is out of range of a long long, clips at
++   LLONG_MAX or LLONG_MIN, then this implementation also clips.  */
+ 
+ long long int
+ __llround (double x)
+ {
+-  double xrf;
+-  long long int xr;
+-  xr = (long long int) x;
+-  xrf = (double) xr;
++  long long xr = (long long) x;
++  double xrf = (double) xr;
++
+   if (x >= 0.0)
+-    if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0)
+-      return x+1;
+-    else
+-      return x;
++    {
++      if (x - xrf >= 0.5)
++	xr += (long long) ((unsigned long long) xr + 1) > 0;
++    }
+   else
+-    if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0)
+-      return x-1;
+-    else
+-      return x;
++    {
++      if (xrf - x >= 0.5)
++	xr -= (long long) ((unsigned long long) xr - 1) < 0;
++    }
++  return xr;
+ }
+ weak_alias (__llround, llround)
+ #ifdef NO_LONG_DOUBLE
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/s_llroundf.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/s_llroundf.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/s_llroundf.c	2014-05-27 22:38:55.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/s_llroundf.c	2014-05-27 22:38:58.000000000 -0500
+@@ -18,28 +18,27 @@
+ 
+ #include <math.h>
+ 
+-/* I think that what this routine is supposed to do is round a value
+-   to the nearest integer, with values exactly on the boundary rounded
+-   away from zero.  */
+-/* This routine relies on (long long)x, when x is out of range of a long long,
+-   clipping to MAX_LLONG or MIN_LLONG.  */
++/* Round to the nearest integer, with values exactly on a 0.5 boundary
++   rounded away from zero, regardless of the current rounding mode.
++   If (long long)x, when x is out of range of a long long, clips at
++   LLONG_MAX or LLONG_MIN, then this implementation also clips.  */
+ 
+ long long int
+ __llroundf (float x)
+ {
+-  float xrf;
+-  long long int xr;
+-  xr = (long long int) x;
+-  xrf = (float) xr;
++  long long xr = (long long) x;
++  float xrf = (float) xr;
++
+   if (x >= 0.0)
+-    if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0)
+-      return x+1;
+-    else
+-      return x;
++    {
++      if (x - xrf >= 0.5)
++	xr += (long long) ((unsigned long long) xr + 1) > 0;
++    }
+   else
+-    if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0)
+-      return x-1;
+-    else
+-      return x;
++    {
++      if (xrf - x >= 0.5)
++	xr -= (long long) ((unsigned long long) xr - 1) < 0;
++    }
++  return xr;
+ }
+ weak_alias (__llroundf, llroundf)
diff --git a/SOURCES/glibc-ppc64le-16.patch b/SOURCES/glibc-ppc64le-16.patch
new file mode 100644
index 0000000..038710c
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-16.patch
@@ -0,0 +1,163 @@
+# commit 9c008155b7d5d1bd81d909497850a2ece28aec50
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:31:05 2013 +0930
+# 
+#     PowerPC floating point little-endian [11 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-07/msg00202.html
+#     
+#     Another little-endian fix.
+#     
+#         * sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Rewrite using
+#         64-bit int/double union.
+#         (_FPU_SETCW): Likewise.
+#         * sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise.
+#         (_SET_DI_FPSCR, _GET_SI_FPSCR, _SET_SI_FPSCR): Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fpu_control.h glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fpu_control.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/fpu_control.h	2014-05-27 22:40:18.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/fpu_control.h	2014-05-27 22:43:40.000000000 -0500
+@@ -45,22 +45,26 @@
+ #define _FPU_IEEE     0x000000f0
+ 
+ /* Type of the control word.  */
+-typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
++typedef unsigned int fpu_control_t;
+ 
+ /* Macros for accessing the hardware control word.  */
+-#define _FPU_GETCW(__cw) ( { \
+-  union { double d; fpu_control_t cw[2]; } \
+-    tmp __attribute__ ((__aligned__(8))); \
+-  __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \
+-  (__cw)=tmp.cw[1]; \
+-  tmp.cw[1]; } )
+-#define _FPU_SETCW(__cw) { \
+-  union { double d; fpu_control_t cw[2]; } \
+-    tmp __attribute__ ((__aligned__(8))); \
+-  tmp.cw[0] = 0xFFF80000; /* More-or-less arbitrary; this is a QNaN. */ \
+-  tmp.cw[1] = __cw; \
+-  __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \
+-}
++#define _FPU_GETCW(cw)						\
++  ({union { double __d; unsigned long long __ll; } __u;		\
++    register double __fr;					\
++    __asm__ ("mffs %0" : "=f" (__fr));				\
++    __u.__d = __fr;						\
++    (cw) = (fpu_control_t) __u.__ll;				\
++    (fpu_control_t) __u.__ll;					\
++  })
++
++#define _FPU_SETCW(cw)						\
++  { union { double __d; unsigned long long __ll; } __u;		\
++    register double __fr;					\
++    __u.__ll = 0xfff80000LL << 32; /* This is a QNaN.  */	\
++    __u.__ll |= (cw) & 0xffffffffLL;				\
++    __fr = __u.__d;						\
++    __asm__ ("mtfsf 255,%0" : : "f" (__fr));			\
++  }
+ 
+ /* Default control word set at startup.  */
+ extern fpu_control_t __fpu_control;
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c	2014-05-27 22:40:18.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c	2014-05-27 22:40:21.000000000 -0500
+@@ -83,7 +83,7 @@
+   return 0;
+ }
+ 
+-typedef unsigned long long di_fpscr_t __attribute__ ((__mode__ (__DI__)));
++typedef unsigned int di_fpscr_t __attribute__ ((__mode__ (__DI__)));
+ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
+ 
+ #define _FPSCR_RESERVED 0xfffffff8ffffff04ULL
+@@ -95,50 +95,51 @@
+ #define _FPSCR_TEST1_RN  0x0000000000000002ULL
+ 
+ /* Macros for accessing the hardware control word on Power6[x].  */
+-# define _GET_DI_FPSCR(__fpscr) ({					     \
+-   union { double d;							     \
+-           di_fpscr_t fpscr; }						     \
+-     tmp __attribute__ ((__aligned__(8)));				     \
+-   __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0");		     \
+-   (__fpscr)=tmp.fpscr;							     \
+-   tmp.fpscr; })
++#define _GET_DI_FPSCR(__fpscr)						\
++  ({union { double d; di_fpscr_t fpscr; } u;				\
++    register double fr;							\
++    __asm__ ("mffs %0" : "=f" (fr));					\
++    u.d = fr;								\
++    (__fpscr) = u.fpscr;						\
++    u.fpscr;								\
++  })
+ 
+-/* We make sure to zero fp0 after we use it in order to prevent stale data
++/* We make sure to zero fp after we use it in order to prevent stale data
+    in an fp register from making a test-case pass erroneously.  */
+-# define _SET_DI_FPSCR(__fpscr) {					     \
+-  union { double d; di_fpscr_t fpscr; }					     \
+-    tmp __attribute__ ((__aligned__(8)));				     \
+-  tmp.fpscr = __fpscr;							     \
+-  /* Set the entire 64-bit FPSCR.  */					     \
+-  __asm__ ("lfd%U0 0,%0; "						     \
+-	   ".machine push; "						     \
+-	   ".machine \"power6\"; "					     \
+-	   "mtfsf 255,0,1,0; "						     \
+-	   ".machine pop" : : "m" (tmp.d) : "fr0");			     \
+-  tmp.d = 0;								     \
+-  __asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0");			     \
+-}
+-
+-# define _GET_SI_FPSCR(__fpscr) ({					     \
+-   union { double d;							     \
+-           si_fpscr_t cw[2]; }						     \
+-     tmp __attribute__ ((__aligned__(8)));				     \
+-   __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0");		     \
+-   (__fpscr)=tmp.cw[1];							     \
+-   tmp.cw[0]; })
++# define _SET_DI_FPSCR(__fpscr)						\
++  { union { double d; di_fpscr_t fpscr; } u;				\
++    register double fr;							\
++    u.fpscr = __fpscr;							\
++    fr = u.d;								\
++    /* Set the entire 64-bit FPSCR.  */					\
++    __asm__ (".machine push; "						\
++	     ".machine \"power6\"; "					\
++	     "mtfsf 255,%0,1,0; "					\
++	     ".machine pop" : : "f" (fr));				\
++    fr = 0.0;								\
++  }
++
++# define _GET_SI_FPSCR(__fpscr)						\
++  ({union { double d; di_fpscr_t fpscr; } u;				\
++    register double fr;							\
++    __asm__ ("mffs %0" : "=f" (fr));					\
++    u.d = fr;								\
++    (__fpscr) = (si_fpscr_t) u.fpscr;					\
++    (si_fpscr_t) u.fpscr;						\
++  })
+ 
+-/* We make sure to zero fp0 after we use it in order to prevent stale data
++/* We make sure to zero fp after we use it in order to prevent stale data
+    in an fp register from making a test-case pass erroneously.  */
+-# define _SET_SI_FPSCR(__fpscr) {					     \
+-  union { double d; si_fpscr_t fpscr[2]; }				     \
+-    tmp __attribute__ ((__aligned__(8)));				     \
+-  /* More-or-less arbitrary; this is a QNaN. */				     \
+-  tmp.fpscr[0] = 0xFFF80000;						     \
+-  tmp.fpscr[1] = __fpscr;						     \
+-  __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0");		     \
+-  tmp.d = 0;								     \
+-  __asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0");			     \
+-}
++# define _SET_SI_FPSCR(__fpscr)						\
++  { union { double d; di_fpscr_t fpscr; } u;				\
++    register double fr;							\
++    /* More-or-less arbitrary; this is a QNaN. */			\
++    u.fpscr = 0xfff80000ULL << 32;					\
++    u.fpscr |= __fpscr & 0xffffffffULL;					\
++    fr = u.d;								\
++    __asm__ ("mtfsf 255,%0" : : "f" (fr));				\
++    fr = 0.0;								\
++  }
+ 
+ void prime_special_regs(int which)
+ {
diff --git a/SOURCES/glibc-ppc64le-17.patch b/SOURCES/glibc-ppc64le-17.patch
new file mode 100644
index 0000000..1a0e30d
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-17.patch
@@ -0,0 +1,312 @@
+# commit 7b88401f3b25325b1381798a0eccb3efe7751fec
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:31:45 2013 +0930
+# 
+#     PowerPC floating point little-endian [12 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00087.html
+#     
+#     Fixes for little-endian in 32-bit assembly.
+#     
+#         * sysdeps/powerpc/sysdep.h (LOWORD, HIWORD, HISHORT): Define.
+#         * sysdeps/powerpc/powerpc32/fpu/s_copysign.S: Load little-endian
+#         words of double from correct stack offsets.
+#         * sysdeps/powerpc/powerpc32/fpu/s_copysignl.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/fpu/s_lrint.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/fpu/s_lround.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S: Use HISHORT.
+#         * sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_copysign.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_copysign.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_copysign.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_copysign.S	2014-05-27 22:45:46.000000000 -0500
+@@ -29,7 +29,7 @@
+ 	stwu	r1,-16(r1)
+ 	cfi_adjust_cfa_offset (16)
+ 	stfd	fp2,8(r1)
+-	lwz	r3,8(r1)
++	lwz	r3,8+HIWORD(r1)
+ 	cmpwi   r3,0
+ 	addi    r1,r1,16
+ 	cfi_adjust_cfa_offset (-16)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S	2014-05-27 22:45:46.000000000 -0500
+@@ -30,7 +30,7 @@
+ 	fmr	fp0,fp1
+ 	fabs	fp1,fp1
+ 	fcmpu	cr7,fp0,fp1
+-	lwz	r3,8(r1)
++	lwz	r3,8+HIWORD(r1)
+ 	cmpwi	cr6,r3,0
+ 	addi	r1,r1,16
+ 	cfi_adjust_cfa_offset (-16)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_lrint.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_lrint.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_lrint.S	2014-05-27 22:45:46.000000000 -0500
+@@ -24,10 +24,10 @@
+ 	stwu	r1,-16(r1)
+ 	fctiw	fp13,fp1
+ 	stfd	fp13,8(r1)
+-	nop	/* Insure the following load is in a different dispatch group */
++	nop	/* Ensure the following load is in a different dispatch group */
+ 	nop	/* to avoid pipe stall on POWER4&5.  */
+ 	nop
+-	lwz	r3,12(r1)
++	lwz	r3,8+LOWORD(r1)
+ 	addi	r1,r1,16
+ 	blr
+ 	END (__lrint)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_lround.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_lround.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_lround.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_lround.S	2014-05-27 22:45:46.000000000 -0500
+@@ -67,7 +67,7 @@
+ 	nop	/* Ensure the following load is in a different dispatch  */
+ 	nop	/* group to avoid pipe stall on POWER4&5.  */
+ 	nop
+-	lwz	r3,12(r1)	/* Load return as integer.  */
++	lwz	r3,8+LOWORD(r1)	/* Load return as integer.  */
+ .Lout:
+ 	addi	r1,r1,16
+ 	blr
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S	2014-05-27 22:48:09.000000000 -0500
+@@ -29,8 +29,8 @@
+ 	nop	/* Insure the following load is in a different dispatch group */
+ 	nop	/* to avoid pipe stall on POWER4&5.  */
+ 	nop
+-	lwz	r3,8(r1)
+-	lwz	r4,12(r1)
++	lwz	r3,8+HIWORD(r1)
++	lwz	r4,8+LOWORD(r1)
+ 	addi	r1,r1,16	
+ 	blr
+ 	END (__llrint)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S	2014-05-27 22:48:44.000000000 -0500
+@@ -28,8 +28,8 @@
+ 	nop	/* Insure the following load is in a different dispatch group */
+ 	nop	/* to avoid pipe stall on POWER4&5.  */
+ 	nop
+-	lwz	r3,8(r1)
+-	lwz	r4,12(r1)
++	lwz	r3,8+HIWORD(r1)
++	lwz	r4,8+LOWORD(r1)
+ 	addi	r1,r1,16	
+ 	blr
+ 	END (__llrintf)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S	2014-05-27 22:45:46.000000000 -0500
+@@ -27,8 +27,8 @@
+ 	ori	r1,r1,0
+ 	stfd	fp1,24(r1)	/* copy FPR to GPR */
+ 	ori	r1,r1,0
+-	lwz	r4,24(r1)
+-	lwz	r5,28(r1)
++	lwz	r4,24+HIWORD(r1)
++	lwz	r5,24+LOWORD(r1)
+ 	lis	r0,0x7ff0	/* const long r0 0x7ff00000 00000000 */
+ 	clrlwi	r4,r4,1		/* x = fabs(x) */
+ 	cmpw	cr7,r4,r0	/* if (fabs(x) =< inf) */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S	2014-05-27 22:45:46.000000000 -0500
+@@ -39,8 +39,8 @@
+ 	nop	/* Ensure the following load is in a different dispatch  */
+ 	nop	/* group to avoid pipe stall on POWER4&5.  */
+ 	nop
+-	lwz	r4,12(r1)
+-	lwz	r3,8(r1)
++	lwz	r3,8+HIWORD(r1)
++	lwz	r4,8+LOWORD(r1)
+ 	addi	r1,r1,16
+ 	blr
+ 	END (__llround)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S	2014-05-27 22:45:46.000000000 -0500
+@@ -38,7 +38,7 @@
+ 	nop	/* Ensure the following load is in a different dispatch  */
+ 	nop	/* group to avoid pipe stall on POWER4&5.  */
+ 	nop
+-	lwz	r3,12(r1)
++	lwz	r3,8+LOWORD(r1)
+ 	addi	r1,r1,16
+ 	blr
+ 	END (__lround)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S	2014-05-27 22:45:46.000000000 -0500
+@@ -27,8 +27,8 @@
+ 	ori	r1,r1,0
+ 	stfd	fp1,24(r1)	/* copy FPR to GPR */
+ 	ori	r1,r1,0
+-	lwz	r4,24(r1)
+-	lwz	r5,28(r1)
++	lwz	r4,24+HIWORD(r1)
++	lwz	r5,24+LOWORD(r1)
+ 	lis	r0,0x7ff0	/* const long r0 0x7ff00000 00000000 */
+ 	clrlwi	r4,r4,1		/* x = fabs(x) */
+ 	cmpw	cr7,r4,r0	/* if (fabs(x) =< inf) */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S	2014-05-27 22:46:52.000000000 -0500
+@@ -29,8 +29,8 @@
+ /* Insure the following load is in a different dispatch group by
+    inserting "group ending nop".  */
+ 	ori	r1,r1,0
+-	lwz	r3,8(r1)
+-	lwz	r4,12(r1)
++	lwz	r3,8+HIWORD(r1)
++	lwz	r4,8+LOWORD(r1)
+ 	addi	r1,r1,16	
+ 	blr
+ 	END (__llrint)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S	2014-05-27 22:47:29.000000000 -0500
+@@ -28,8 +28,8 @@
+ /* Insure the following load is in a different dispatch group by
+    inserting "group ending nop".  */
+ 	ori	r1,r1,0
+-	lwz	r3,8(r1)
+-	lwz	r4,12(r1)
++	lwz	r3,8+HIWORD(r1)
++	lwz	r4,8+LOWORD(r1)
+ 	addi	r1,r1,16	
+ 	blr
+ 	END (__llrintf)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S	2014-05-27 22:45:46.000000000 -0500
+@@ -39,8 +39,8 @@
+ /* Insure the following load is in a different dispatch group by
+    inserting "group ending nop".  */
+ 	ori	r1,r1,0
+-	lwz	r4,12(r1)
+-	lwz	r3,8(r1)
++	lwz	r3,8+HIWORD(r1)
++	lwz	r4,8+LOWORD(r1)
+ 	addi	r1,r1,16
+ 	blr
+ 	END (__llround)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S	2014-05-27 22:45:46.000000000 -0500
+@@ -54,9 +54,8 @@
+ 	stfd    fp1,8(r1)     /* Transfer FP to GPR's.  */
+ 
+ 	ori	2,2,0	      /* Force a new dispatch group.  */
+-	lhz     r0,8(r1)      /* Fetch the upper portion of the high word of
+-			      the FP value (where the exponent and sign bits
+-			      are).  */
++	lhz	r0,8+HISHORT(r1) /* Fetch the upper 16 bits of the FP value
++				    (biased exponent and sign bit).  */
+ 	clrlwi	r0,r0,17      /* r0 = abs(r0).  */
+ 	addi	r1,r1,16      /* Reset the stack pointer.  */
+ 	cmpwi	cr7,r0,0x7ff0 /* r4 == 0x7ff0?.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S	2014-05-27 22:45:46.000000000 -0500
+@@ -48,14 +48,13 @@
+ 	li	r3,0
+ 	bflr    29	      /* If not INF, return.  */
+ 
+-	/* Either we have -INF/+INF or a denormal.  */
++	/* Either we have +INF or -INF.  */
+ 
+ 	stwu    r1,-16(r1)    /* Allocate stack space.  */
+ 	stfd    fp1,8(r1)     /* Transfer FP to GPR's.  */
+ 	ori	2,2,0	      /* Force a new dispatch group.  */
+-	lhz	r4,8(r1)      /* Fetch the upper portion of the high word of
+-			      the FP value (where the exponent and sign bits
+-			      are).  */
++	lhz	r4,8+HISHORT(r1) /* Fetch the upper 16 bits of the FP value
++				    (biased exponent and sign bit).  */
+ 	addi	r1,r1,16      /* Reset the stack pointer.  */
+ 	cmpwi	cr7,r4,0x7ff0 /* r4 == 0x7ff0?  */
+ 	li	r3,1
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S	2014-05-27 22:45:46.000000000 -0500
+@@ -53,8 +53,8 @@
+ 	stwu	r1,-16(r1)    /* Allocate stack space.  */
+ 	stfd	fp1,8(r1)     /* Transfer FP to GPR's.  */
+ 	ori	2,2,0	      /* Force a new dispatch group.  */
+-	lwz     r4,8(r1)      /* Load the upper half of the FP value.  */
+-	lwz     r5,12(r1)     /* Load the lower half of the FP value.  */
++	lwz     r4,8+HIWORD(r1) /* Load the upper half of the FP value.  */
++	lwz     r5,8+LOWORD(r1) /* Load the lower half of the FP value.  */
+ 	addi	r1,r1,16      /* Reset the stack pointer.  */
+ 	lis     r0,0x7ff0     /* Load the upper portion for an INF/NaN.  */
+ 	clrlwi  r4,r4,1	      /* r4 = abs(r4).  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S	2014-05-27 22:45:46.000000000 -0500
+@@ -39,10 +39,8 @@
+ 
+ 	stfd    fp1,-16(r1)   /* Transfer FP to GPR's.  */
+ 	ori	2,2,0	      /* Force a new dispatch group.  */
+-
+-	lhz     r4,-16(r1)    /* Fetch the upper portion of the high word of
+-			      the FP value (where the exponent and sign bits
+-			      are).  */
++	lhz     r4,-16+HISHORT(r1)  /* Fetch the upper 16 bits of the FP value
++				    (biased exponent and sign bit).  */
+ 	clrlwi  r4,r4,17      /* r4 = abs(r4).  */
+ 	cmpwi   cr7,r4,0x7ff0 /* r4 == 0x7ff0?  */
+ 	bltlr   cr7	      /* LT means finite, other non-finite.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S	2014-05-27 22:45:46.000000000 -0500
+@@ -38,9 +38,8 @@
+ 
+ 	stfd    fp1,-16(r1)   /* Transfer FP to GPR's.  */
+ 	ori	2,2,0	      /* Force a new dispatch group.  */
+-	lhz	r4,-16(r1)    /* Fetch the upper portion of the high word of
+-			      the FP value (where the exponent and sign bits
+-			      are).  */
++	lhz	r4,-16+HISHORT(r1)  /* Fetch the upper 16 bits of the FP value
++				    (biased exponent and sign bit).  */
+ 	cmpwi	cr7,r4,0x7ff0 /* r4 == 0x7ff0?  */
+ 	li	r3,1
+ 	beqlr   cr7	      /* EQ means INF, otherwise -INF.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/sysdep.h glibc-2.17-c758a686.diff/sysdeps/powerpc/sysdep.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/sysdep.h	2014-05-27 22:45:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/sysdep.h	2014-05-27 22:45:46.000000000 -0500
+@@ -144,6 +144,21 @@
+ 
+ #define VRSAVE	256
+ 
++/* The 32-bit words of a 64-bit dword are at these offsets in memory.  */
++#if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
++# define LOWORD 0
++# define HIWORD 4
++#else
++# define LOWORD 4
++# define HIWORD 0
++#endif
++
++/* The high 16-bit word of a 64-bit dword is at this offset in memory.  */
++#if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
++# define HISHORT 6
++#else
++# define HISHORT 0
++#endif
+ 
+ /* This seems to always be the case on PPC.  */
+ #define ALIGNARG(log2) log2
diff --git a/SOURCES/glibc-ppc64le-18.patch b/SOURCES/glibc-ppc64le-18.patch
new file mode 100644
index 0000000..58b86c7
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-18.patch
@@ -0,0 +1,81 @@
+# commit 6a31fe7f9cce72b69fce8fe499a2c6ad492c2311
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:32:18 2013 +0930
+# 
+#     PowerPC floating point little-endian [13 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00088.html
+#     
+#         * sysdeps/powerpc/powerpc32/fpu/s_roundf.S: Increase alignment of
+#         constants to usual value for .cst8 section, and remove redundant
+#         high address load.
+#         * sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S: Use float
+#         constant for 0x1p52.  Load little-endian words of double from
+#         correct stack offsets.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_roundf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_roundf.S	2014-05-27 22:50:13.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/s_roundf.S	2014-05-27 22:50:13.000000000 -0500
+@@ -19,7 +19,7 @@
+ #include <sysdep.h>
+ 
+ 	.section	.rodata.cst8,"aM",@progbits,8
+-	.align	2
++	.align	3
+ .LC0:	/* 2**23 */
+ 	.long 0x4b000000
+ .LC1:	/* 0.5 */
+@@ -60,7 +60,6 @@
+ #ifdef SHARED
+ 	lfs	fp10,.LC1-.LC0(r9)
+ #else
+-	lis	r9,.LC1@ha
+ 	lfs	fp10,.LC1@l(r9)
+ #endif
+ 	ble-	cr6,.L4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S	2014-05-27 22:50:13.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S	2014-05-27 22:50:13.000000000 -0500
+@@ -19,12 +19,10 @@
+ #include <sysdep.h>
+ #include <math_ldbl_opt.h>
+ 
+- .section .rodata.cst12,"aM",@progbits,12
++ .section .rodata.cst8,"aM",@progbits,8
+  .align 3
+- .LC0:   /* 0x1.0000000000000p+52 == 2^52 */
+-	.long 0x43300000
+-	.long 0x00000000
+-	.long 0x3f000000 /* Use this for 0.5  */
++ .LC0:	.long (52+127)<<23 /* 0x1p+52  */
++	.long (-1+127)<<23 /* 0.5  */
+ 
+ 	.section	".text"
+ 
+@@ -57,12 +55,12 @@
+ 	addi	r9,r9,.LC0-got_label@l
+ 	mtlr	r11
+ 	cfi_same_value (lr)
+-	lfd	fp9,0(r9)
+-	lfs	fp10,8(r9)
++	lfs	fp9,0(r9)
++	lfs	fp10,4(r9)
+ #else
+ 	lis r9,.LC0@ha
+-	lfd fp9,.LC0@l(r9)	/* Load 2^52 into fpr9.  */
+-	lfs fp10,.LC0@l+8(r9)	/* Load 0.5 into fpr10.  */
++	lfs fp9,.LC0@l(r9)	/* Load 2^52 into fpr9.  */
++	lfs fp10,.LC0@l+4(r9)	/* Load 0.5 into fpr10.  */
+ #endif
+ 	fabs	fp2,fp1		/* Get the absolute value of x.  */
+ 	fsub	fp12,fp10,fp10	/* Compute 0.0 into fpr12.  */
+@@ -80,8 +78,8 @@
+ 	nop
+ 	nop
+ 	nop
+-	lwz	r4,12(r1)	/* Load return as integer.  */
+-	lwz	r3,8(r1)
++	lwz	r3,8+HIWORD(r1)	/* Load return as integer.  */
++	lwz	r4,8+LOWORD(r1)
+ .Lout:
+ 	addi	r1,r1,16
+ 	blr
diff --git a/SOURCES/glibc-ppc64le-19.patch b/SOURCES/glibc-ppc64le-19.patch
new file mode 100644
index 0000000..48652a0
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-19.patch
@@ -0,0 +1,110 @@
+# commit 76a66d510a3737674563133a420f4fd22da42c1b
+# Author: Anton Blanchard <anton@au1.ibm.com>
+# Date:   Sat Aug 17 18:33:02 2013 +0930
+# 
+#     PowerPC floating point little-endian [14 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-07/msg00205.html
+#     
+#     These all wrongly specified float constants in a 64-bit word.
+#     
+#         * sysdeps/powerpc/powerpc64/fpu/s_ceilf.S: Correct float constants
+#         for little-endian.
+#         * sysdeps/powerpc/powerpc64/fpu/s_floorf.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/fpu/s_rintf.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/fpu/s_roundf.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/fpu/s_truncf.S: Likewise.
+#
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S	2014-05-27 22:52:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S	2014-05-27 22:52:18.000000000 -0500
+@@ -19,8 +19,10 @@
+ #include <sysdep.h>
+ 
+ 	.section	".toc","aw"
++	.p2align 3
+ .LC0:	/* 2**23 */
+-	.tc FD_4b000000_0[TC],0x4b00000000000000
++	.long 0x4b000000
++	.long 0x0
+ 	.section	".text"
+ 
+ EALIGN (__ceilf, 4, 0)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_floorf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_floorf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_floorf.S	2014-05-27 22:52:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_floorf.S	2014-05-27 22:52:18.000000000 -0500
+@@ -19,8 +19,10 @@
+ #include <sysdep.h>
+ 
+ 	.section	".toc","aw"
++	.p2align 3
+ .LC0:	/* 2**23 */
+-	.tc FD_4b000000_0[TC],0x4b00000000000000
++	.long 0x4b000000
++	.long 0x0
+ 	.section	".text"
+ 
+ EALIGN (__floorf, 4, 0)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S	2014-05-27 22:52:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S	2014-05-27 22:52:18.000000000 -0500
+@@ -26,8 +26,10 @@
+ /* float [fp1] nearbyintf(float [fp1]) */
+ 
+ 	.section	".toc","aw"
++	.p2align 3
+ .LC0:	/* 2**23 */
+-	.tc FD_4b000000_0[TC],0x4b00000000000000
++	.long 0x4b000000
++	.long 0x0
+ 	.section	".text"
+ 
+ EALIGN (__nearbyintf, 4, 0)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_rintf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_rintf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_rintf.S	2014-05-27 22:52:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_rintf.S	2014-05-27 22:52:18.000000000 -0500
+@@ -19,8 +19,10 @@
+ #include <sysdep.h>
+ 
+ 	.section	".toc","aw"
++	.p2align 3
+ .LC0:	/* 2**23 */
+-	.tc FD_4b000000_0[TC],0x4b00000000000000
++	.long 0x4b000000
++	.long 0x0
+ 	.section	".text"
+ 
+ EALIGN (__rintf, 4, 0)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_roundf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_roundf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_roundf.S	2014-05-27 22:52:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_roundf.S	2014-05-27 22:52:18.000000000 -0500
+@@ -19,10 +19,12 @@
+ #include <sysdep.h>
+ 
+ 	.section	".toc","aw"
++	.p2align 3
+ .LC0:	/* 2**23 */
+-	.tc FD_4b000000_0[TC],0x4b00000000000000
++	.long 0x4b000000
+ .LC1:	/* 0.5 */
+-	.tc FD_3f000000_0[TC],0x3f00000000000000
++	.long 0x3f000000
++
+ 	.section	".text"
+ 	
+ /* float [fp1] roundf  (float x [fp1])
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_truncf.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_truncf.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_truncf.S	2014-05-27 22:52:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_truncf.S	2014-05-27 22:52:18.000000000 -0500
+@@ -19,8 +19,10 @@
+ #include <sysdep.h>
+ 
+ 	.section	".toc","aw"
++	.p2align 3
+ .LC0:	/* 2**23 */
+-	.tc FD_4b000000_0[TC],0x4b00000000000000
++	.long 0x4b000000
++	.long 0x0
+ 	.section	".text"
+ 	
+ /* float [fp1] truncf (float x [fp1])
diff --git a/SOURCES/glibc-ppc64le-20.patch b/SOURCES/glibc-ppc64le-20.patch
new file mode 100644
index 0000000..ce9af06
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-20.patch
@@ -0,0 +1,43 @@
+# commit fef13a78ea30d4c26d6bab48d731ebe864ee31b0
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:33:45 2013 +0930
+# 
+#     PowerPC floating point little-endian [15 of 15]
+#     http://sourceware.org/ml/libc-alpha/2013-07/msg00206.html
+#     
+#     The union loses when little-endian.
+#     
+#         * sysdeps/powerpc/powerpc32/power4/hp-timing.h (HP_TIMING_NOW):
+#         Don't use a union to pack hi/low value.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/hp-timing.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/hp-timing.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/hp-timing.h	2014-05-27 22:53:37.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/hp-timing.h	2014-05-27 22:53:39.000000000 -0500
+@@ -87,18 +87,15 @@
+ 
+ #define HP_TIMING_NOW(Var)						\
+   do {									\
+-        union { long long ll; long ii[2]; } _var;			\
+-	long tmp;							\
+-        __asm__ __volatile__ (						\
+-		"1:	mfspr	%0,269;"				\
+-		"	mfspr	%1,268;"				\
+-		"	mfspr	%2,269;"				\
+-		"	cmpw	%0,%2;"					\
+-		"	bne	1b;"					\
+-		: "=r" (_var.ii[0]), "=r" (_var.ii[1]) , "=r" (tmp)	\
+-		: : "cr0"						\
+-		);							\
+-	Var = _var.ll;							\
++    unsigned int hi, lo, tmp;						\
++    __asm__ __volatile__ ("1:	mfspr	%0,269;"			\
++			  "	mfspr	%1,268;"			\
++			  "	mfspr	%2,269;"			\
++			  "	cmpw	%0,%2;"				\
++			  "	bne	1b;"				\
++			  : "=&r" (hi), "=&r" (lo), "=&r" (tmp)		\
++			  : : "cr0");					\
++    Var = ((hp_timing_t) hi << 32) | lo;				\
+   } while (0)
+ 
+ 
diff --git a/SOURCES/glibc-ppc64le-21.patch b/SOURCES/glibc-ppc64le-21.patch
new file mode 100644
index 0000000..84384d8
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-21.patch
@@ -0,0 +1,294 @@
+# commit be1e5d311342e08ae1f8013342df27b7ded2c156
+# Author: Anton Blanchard <anton@au1.ibm.com>
+# Date:   Sat Aug 17 18:34:40 2013 +0930
+# 
+#     PowerPC LE setjmp/longjmp
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00089.html
+#     
+#     Little-endian fixes for setjmp/longjmp.  When writing these I noticed
+#     the setjmp code corrupts the non volatile VMX registers when using an
+#     unaligned buffer.  Anton fixed this, and also simplified it quite a
+#     bit.
+#     
+#     The current code uses boilerplate for the case where we want to store
+#     16 bytes to an unaligned address.  For that we have to do a
+#     read/modify/write of two aligned 16 byte quantities.  In our case we
+#     are storing a bunch of back to back data (consective VMX registers),
+#     and only the start and end of the region need the read/modify/write.
+#     
+#         [BZ #15723]
+#         * sysdeps/powerpc/jmpbuf-offsets.h: Comment fix.
+#         * sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S: Correct
+#         _dl_hwcap access for little-endian.
+#         * sysdeps/powerpc/powerpc32/fpu/setjmp-common.S: Likewise.  Don't
+#         destroy vmx regs when saving unaligned.
+#         * sysdeps/powerpc/powerpc64/__longjmp-common.S: Correct CR load.
+#         * sysdeps/powerpc/powerpc64/setjmp-common.S: Likewise CR save.  Don't
+#         destroy vmx regs when saving unaligned.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/jmpbuf-offsets.h glibc-2.17-c758a686.diff/sysdeps/powerpc/jmpbuf-offsets.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/jmpbuf-offsets.h	2014-05-27 22:55:23.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/jmpbuf-offsets.h	2014-05-27 22:55:27.000000000 -0500
+@@ -21,12 +21,10 @@
+ #define JB_LR     2  /* The address we will return to */
+ #if __WORDSIZE == 64
+ # define JB_GPRS   3  /* GPRs 14 through 31 are saved, 18*2 words total.  */
+-# define JB_CR     21 /* Condition code registers with the VRSAVE at */
+-                       /* offset 172 (low half of the double word.  */
++# define JB_CR     21 /* Shared dword with VRSAVE.  CR word at offset 172.  */
+ # define JB_FPRS   22 /* FPRs 14 through 31 are saved, 18*2 words total.  */
+ # define JB_SIZE   (64 * 8) /* As per PPC64-VMX ABI.  */
+-# define JB_VRSAVE 21 /* VRSAVE shares a double word with the CR at offset */
+-                       /* 168 (high half of the double word).  */
++# define JB_VRSAVE 21 /* Shared dword with CR.  VRSAVE word at offset 168.  */
+ # define JB_VRS    40 /* VRs 20 through 31 are saved, 12*4 words total.  */
+ #else
+ # define JB_GPRS   3  /* GPRs 14 through 31 are saved, 18 in total.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S	2014-05-27 22:55:23.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S	2014-05-27 22:55:27.000000000 -0500
+@@ -46,16 +46,16 @@
+ #   endif
+ 	mtlr    r6
+ 	cfi_same_value (lr)
+-	lwz     r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r5)
++	lwz     r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r5)
+ #  else
+ 	lwz     r5,_dl_hwcap@got(r5)
+ 	mtlr    r6
+ 	cfi_same_value (lr)
+-	lwz     r5,4(r5)
++	lwz     r5,LOWORD(r5)
+ #  endif
+ # else
+-	lis	r5,(_dl_hwcap+4)@ha
+-	lwz     r5,(_dl_hwcap+4)@l(r5)
++	lis	r5,(_dl_hwcap+LOWORD)@ha
++	lwz     r5,(_dl_hwcap+LOWORD)@l(r5)
+ # endif
+ 	andis.	r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ 	beq	L(no_vmx)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S	2014-05-27 22:55:23.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S	2014-05-27 22:55:27.000000000 -0500
+@@ -97,14 +97,14 @@
+ #   else
+ 	lwz     r5,_rtld_global_ro@got(r5)
+ #   endif
+-	lwz     r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r5)
++	lwz     r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r5)
+ #  else
+ 	lwz     r5,_dl_hwcap@got(r5)
+-	lwz     r5,4(r5)
++	lwz     r5,LOWORD(r5)
+ #  endif
+ # else
+-	lis	r6,(_dl_hwcap+4)@ha
+-	lwz     r5,(_dl_hwcap+4)@l(r6)
++	lis	r6,(_dl_hwcap+LOWORD)@ha
++	lwz     r5,(_dl_hwcap+LOWORD)@l(r6)
+ # endif
+ 	andis.	r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ 	beq	L(no_vmx)
+@@ -114,44 +114,43 @@
+ 	stw	r0,((JB_VRSAVE)*4)(3)
+ 	addi	r6,r5,16
+ 	beq+	L(aligned_save_vmx)
++
+ 	lvsr	v0,0,r5
+-	vspltisb v1,-1         /* set v1 to all 1's */
+-	vspltisb v2,0          /* set v2 to all 0's */
+-	vperm   v3,v2,v1,v0   /* v3 contains shift mask with num all 1 bytes on left = misalignment  */
+-
+-
+-	/* Special case for v20 we need to preserve what is in save area below v20 before obliterating it */
+-	lvx     v5,0,r5
+-	vperm   v20,v20,v20,v0
+-	vsel    v5,v5,v20,v3
+-	vsel    v20,v20,v2,v3
+-	stvx    v5,0,r5
+-
+-#define save_2vmx_partial(savevr,prev_savevr,hivr,shiftvr,maskvr,savegpr,addgpr) \
+-	addi    addgpr,addgpr,32; \
+-	vperm   savevr,savevr,savevr,shiftvr; \
+-	vsel    hivr,prev_savevr,savevr,maskvr; \
+-	stvx    hivr,0,savegpr;
+-
+-	save_2vmx_partial(v21,v20,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v22,v21,v5,v0,v3,r5,r6)
+-	save_2vmx_partial(v23,v22,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v24,v23,v5,v0,v3,r5,r6)
+-	save_2vmx_partial(v25,v24,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v26,v25,v5,v0,v3,r5,r6)
+-	save_2vmx_partial(v27,v26,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v28,v27,v5,v0,v3,r5,r6)
+-	save_2vmx_partial(v29,v28,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v30,v29,v5,v0,v3,r5,r6)
+-
+-	/* Special case for r31 we need to preserve what is in save area above v31 before obliterating it */
+-	addi    r5,r5,32
+-	vperm   v31,v31,v31,v0
+-	lvx     v4,0,r5
+-	vsel    v5,v30,v31,v3
+-	stvx    v5,0,r6
+-	vsel    v4,v31,v4,v3
+-	stvx    v4,0,r5
++	lvsl	v1,0,r5
++	addi	r6,r5,-16
++
++# define save_misaligned_vmx(savevr,prevvr,shiftvr,tmpvr,savegpr,addgpr) \
++	addi	addgpr,addgpr,32;					 \
++	vperm	tmpvr,prevvr,savevr,shiftvr;				 \
++	stvx	tmpvr,0,savegpr
++
++	/*
++	 * We have to be careful not to corrupt the data below v20 and
++	 * above v31. To keep things simple we just rotate both ends in
++	 * the opposite direction to our main permute so we can use
++	 * the common macro.
++	 */
++
++	/* load and rotate data below v20 */
++	lvx	v2,0,r5
++	vperm	v2,v2,v2,v1
++	save_misaligned_vmx(v20,v2,v0,v3,r5,r6)
++	save_misaligned_vmx(v21,v20,v0,v3,r6,r5)
++	save_misaligned_vmx(v22,v21,v0,v3,r5,r6)
++	save_misaligned_vmx(v23,v22,v0,v3,r6,r5)
++	save_misaligned_vmx(v24,v23,v0,v3,r5,r6)
++	save_misaligned_vmx(v25,v24,v0,v3,r6,r5)
++	save_misaligned_vmx(v26,v25,v0,v3,r5,r6)
++	save_misaligned_vmx(v27,v26,v0,v3,r6,r5)
++	save_misaligned_vmx(v28,v27,v0,v3,r5,r6)
++	save_misaligned_vmx(v29,v28,v0,v3,r6,r5)
++	save_misaligned_vmx(v30,v29,v0,v3,r5,r6)
++	save_misaligned_vmx(v31,v30,v0,v3,r6,r5)
++	/* load and rotate data above v31 */
++	lvx	v2,0,r6
++	vperm	v2,v2,v2,v1
++	save_misaligned_vmx(v2,v31,v0,v3,r5,r6)
++
+ 	b	L(no_vmx)
+ 
+ L(aligned_save_vmx):
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/__longjmp-common.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/__longjmp-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/__longjmp-common.S	2014-05-27 22:55:23.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/__longjmp-common.S	2014-05-27 22:55:27.000000000 -0500
+@@ -60,7 +60,7 @@
+ 	beq	L(no_vmx)
+ 	la	r5,((JB_VRS)*8)(3)
+ 	andi.	r6,r5,0xf
+-	lwz	r0,((JB_VRSAVE)*8)(3)
++	lwz	r0,((JB_VRSAVE)*8)(3)	/* 32-bit VRSAVE.  */
+ 	mtspr	VRSAVE,r0
+ 	beq+	L(aligned_restore_vmx)
+ 	addi    r6,r5,16
+@@ -156,7 +156,7 @@
+ 	lfd fp21,((JB_FPRS+7)*8)(r3)
+ 	ld r22,((JB_GPRS+8)*8)(r3)
+ 	lfd fp22,((JB_FPRS+8)*8)(r3)
+-	ld r0,(JB_CR*8)(r3)
++	lwz r0,((JB_CR*8)+4)(r3)	/* 32-bit CR.  */
+ 	ld r23,((JB_GPRS+9)*8)(r3)
+ 	lfd fp23,((JB_FPRS+9)*8)(r3)
+ 	ld r24,((JB_GPRS+10)*8)(r3)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/setjmp-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp-common.S	2014-05-27 22:55:23.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/setjmp-common.S	2014-05-27 22:55:27.000000000 -0500
+@@ -98,7 +98,7 @@
+ 	mfcr r0
+ 	std  r16,((JB_GPRS+2)*8)(3)
+ 	stfd fp16,((JB_FPRS+2)*8)(3)
+-	std  r0,(JB_CR*8)(3)
++	stw  r0,((JB_CR*8)+4)(3)	/* 32-bit CR.  */
+ 	std  r17,((JB_GPRS+3)*8)(3)
+ 	stfd fp17,((JB_FPRS+3)*8)(3)
+ 	std  r18,((JB_GPRS+4)*8)(3)
+@@ -142,50 +142,46 @@
+ 	la	r5,((JB_VRS)*8)(3)
+ 	andi.	r6,r5,0xf
+ 	mfspr	r0,VRSAVE
+-	stw	r0,((JB_VRSAVE)*8)(3)
++	stw	r0,((JB_VRSAVE)*8)(3)	/* 32-bit VRSAVE.  */
+ 	addi	r6,r5,16
+ 	beq+	L(aligned_save_vmx)
++
+ 	lvsr	v0,0,r5
+-	vspltisb v1,-1         /* set v1 to all 1's */
+-	vspltisb v2,0          /* set v2 to all 0's */
+-	vperm   v3,v2,v1,v0   /* v3 contains shift mask with num all 1 bytes
+-				 on left = misalignment  */
+-
+-
+-	/* Special case for v20 we need to preserve what is in save area
+-	   below v20 before obliterating it */
+-	lvx     v5,0,r5
+-	vperm   v20,v20,v20,v0
+-	vsel    v5,v5,v20,v3
+-	vsel    v20,v20,v2,v3
+-	stvx    v5,0,r5
+-
+-# define save_2vmx_partial(savevr,prev_savevr,hivr,shiftvr,maskvr,savegpr,addgpr) \
+-	addi    addgpr,addgpr,32; \
+-	vperm   savevr,savevr,savevr,shiftvr; \
+-	vsel    hivr,prev_savevr,savevr,maskvr; \
+-	stvx    hivr,0,savegpr;
+-
+-	save_2vmx_partial(v21,v20,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v22,v21,v5,v0,v3,r5,r6)
+-	save_2vmx_partial(v23,v22,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v24,v23,v5,v0,v3,r5,r6)
+-	save_2vmx_partial(v25,v24,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v26,v25,v5,v0,v3,r5,r6)
+-	save_2vmx_partial(v27,v26,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v28,v27,v5,v0,v3,r5,r6)
+-	save_2vmx_partial(v29,v28,v5,v0,v3,r6,r5)
+-	save_2vmx_partial(v30,v29,v5,v0,v3,r5,r6)
+-
+-	/* Special case for r31 we need to preserve what is in save area
+-	   above v31 before obliterating it */
+-	addi    r5,r5,32
+-	vperm   v31,v31,v31,v0
+-	lvx     v4,0,r5
+-	vsel    v5,v30,v31,v3
+-	stvx    v5,0,r6
+-	vsel    v4,v31,v4,v3
+-	stvx    v4,0,r5
++	lvsl	v1,0,r5
++	addi	r6,r5,-16
++
++# define save_misaligned_vmx(savevr,prevvr,shiftvr,tmpvr,savegpr,addgpr) \
++	addi	addgpr,addgpr,32;					 \
++	vperm	tmpvr,prevvr,savevr,shiftvr;				 \
++	stvx	tmpvr,0,savegpr
++
++	/*
++	 * We have to be careful not to corrupt the data below v20 and
++	 * above v31. To keep things simple we just rotate both ends in
++	 * the opposite direction to our main permute so we can use
++	 * the common macro.
++	 */
++
++	/* load and rotate data below v20 */
++	lvx	v2,0,r5
++	vperm	v2,v2,v2,v1
++	save_misaligned_vmx(v20,v2,v0,v3,r5,r6)
++	save_misaligned_vmx(v21,v20,v0,v3,r6,r5)
++	save_misaligned_vmx(v22,v21,v0,v3,r5,r6)
++	save_misaligned_vmx(v23,v22,v0,v3,r6,r5)
++	save_misaligned_vmx(v24,v23,v0,v3,r5,r6)
++	save_misaligned_vmx(v25,v24,v0,v3,r6,r5)
++	save_misaligned_vmx(v26,v25,v0,v3,r5,r6)
++	save_misaligned_vmx(v27,v26,v0,v3,r6,r5)
++	save_misaligned_vmx(v28,v27,v0,v3,r5,r6)
++	save_misaligned_vmx(v29,v28,v0,v3,r6,r5)
++	save_misaligned_vmx(v30,v29,v0,v3,r5,r6)
++	save_misaligned_vmx(v31,v30,v0,v3,r6,r5)
++	/* load and rotate data above v31 */
++	lvx	v2,0,r6
++	vperm	v2,v2,v2,v1
++	save_misaligned_vmx(v2,v31,v0,v3,r5,r6)
++
+ 	b	L(no_vmx)
+ 
+ L(aligned_save_vmx):
diff --git a/SOURCES/glibc-ppc64le-22.patch b/SOURCES/glibc-ppc64le-22.patch
new file mode 100644
index 0000000..fc7c310
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-22.patch
@@ -0,0 +1,228 @@
+# commit 9b874b2f1eb2550e39d3e9c38772e64a767e9de2
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:35:40 2013 +0930
+# 
+#     PowerPC ugly symbol versioning
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00090.html
+#     
+#     This patch fixes symbol versioning in setjmp/longjmp.  The existing
+#     code uses raw versions, which results in wrong symbol versioning when
+#     you want to build glibc with a base version of 2.19 for LE.
+#     
+#     Note that the merging the 64-bit and 32-bit versions in novmx-lonjmp.c
+#     and pt-longjmp.c doesn't result in GLIBC_2.0 versions for 64-bit, due
+#     to the base in shlib_versions.
+#     
+#         * sysdeps/powerpc/longjmp.c: Use proper symbol versioning macros.
+#         * sysdeps/powerpc/novmx-longjmp.c: Likewise.
+#         * sysdeps/powerpc/powerpc32/bsd-_setjmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/bsd-setjmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/fpu/__longjmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/fpu/setjmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/mcount.c: Likewise.
+#         * sysdeps/powerpc/powerpc32/setjmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/setjmp.S: Likewise.
+#         * nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c glibc-2.17-c758a686.diff/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c
+--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c	2014-05-27 23:22:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c	2014-05-27 23:23:44.000000000 -0500
+@@ -41,13 +41,8 @@
+   __novmx__libc_longjmp (env, val);
+ }
+ 
+-# if __WORDSIZE == 64
+-symbol_version (__novmx_longjmp,longjmp,GLIBC_2.3);
+-symbol_version (__novmx_siglongjmp,siglongjmp,GLIBC_2.3);
+-# else
+-symbol_version (__novmx_longjmp,longjmp,GLIBC_2.0);
+-symbol_version (__novmx_siglongjmp,siglongjmp,GLIBC_2.0);
+-# endif
++compat_symbol (libpthread, __novmx_longjmp, longjmp, GLIBC_2_0);
++compat_symbol (libpthread, __novmx_siglongjmp, siglongjmp, GLIBC_2_0);
+ #endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4))  */ 
+ 
+ void
+@@ -62,5 +57,5 @@
+   __libc_siglongjmp (env, val);
+ }
+ 
+-versioned_symbol (libc, __vmx_longjmp, longjmp, GLIBC_2_3_4);
+-versioned_symbol (libc, __vmx_siglongjmp, siglongjmp, GLIBC_2_3_4);
++versioned_symbol (libpthread, __vmx_longjmp, longjmp, GLIBC_2_3_4);
++versioned_symbol (libpthread, __vmx_siglongjmp, siglongjmp, GLIBC_2_3_4);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/longjmp.c glibc-2.17-c758a686.diff/sysdeps/powerpc/longjmp.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/longjmp.c	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/longjmp.c	2014-05-27 23:22:12.000000000 -0500
+@@ -56,6 +56,6 @@
+ 
+ default_symbol_version (__vmx__libc_longjmp, __libc_longjmp, GLIBC_PRIVATE);
+ default_symbol_version (__vmx__libc_siglongjmp, __libc_siglongjmp, GLIBC_PRIVATE);
+-default_symbol_version (__vmx_longjmp, _longjmp, GLIBC_2.3.4);
+-default_symbol_version (__vmxlongjmp, longjmp, GLIBC_2.3.4);
+-default_symbol_version (__vmxsiglongjmp, siglongjmp, GLIBC_2.3.4);
++versioned_symbol (libc, __vmx_longjmp, _longjmp, GLIBC_2_3_4);
++versioned_symbol (libc, __vmxlongjmp, longjmp, GLIBC_2_3_4);
++versioned_symbol (libc, __vmxsiglongjmp, siglongjmp, GLIBC_2_3_4);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/novmx-longjmp.c glibc-2.17-c758a686.diff/sysdeps/powerpc/novmx-longjmp.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/novmx-longjmp.c	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/novmx-longjmp.c	2014-05-27 23:22:12.000000000 -0500
+@@ -51,13 +51,7 @@
+ weak_alias (__novmx__libc_siglongjmp, __novmxlongjmp)
+ weak_alias (__novmx__libc_siglongjmp, __novmxsiglongjmp)
+ 
+-# if __WORDSIZE == 64
+-symbol_version (__novmx_longjmp,_longjmp,GLIBC_2.3);
+-symbol_version (__novmxlongjmp,longjmp,GLIBC_2.3);
+-symbol_version (__novmxsiglongjmp,siglongjmp,GLIBC_2.3);
+-# else
+-symbol_version (__novmx_longjmp,_longjmp,GLIBC_2.0);
+-symbol_version (__novmxlongjmp,longjmp,GLIBC_2.0);
+-symbol_version (__novmxsiglongjmp,siglongjmp,GLIBC_2.0);
+-# endif
++compat_symbol (libc, __novmx_longjmp, _longjmp, GLIBC_2_0);
++compat_symbol (libc, __novmxlongjmp, longjmp, GLIBC_2_0);
++compat_symbol (libc, __novmxsiglongjmp, siglongjmp, GLIBC_2_0);
+ #endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4))  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/bsd-_setjmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/bsd-_setjmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/bsd-_setjmp.S	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/bsd-_setjmp.S	2014-05-27 23:22:12.000000000 -0500
+@@ -32,7 +32,7 @@
+ /* Build a versioned object for libc.  */
+ 
+ # if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+-symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.0);
++compat_symbol (libc, __novmx_setjmp, _setjmp, GLIBC_2_0);
+ 
+ ENTRY (BP_SYM (__novmx_setjmp))
+ 	li r4,0			/* Set second argument to 0.  */
+@@ -41,7 +41,7 @@
+ libc_hidden_def (__novmx_setjmp)
+ # endif /* defined SHARED  && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) */
+ 
+-default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
++versioned_symbol (libc, __vmx_setjmp, _setjmp, GLIBC_2_3_4)
+ /* __GI__setjmp prototype is needed for ntpl i.e. _setjmp is defined
+    as a libc_hidden_proto & is used in sysdeps/generic/libc-start.c
+    if HAVE_CLEANUP_JMP_BUF is defined */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/bsd-setjmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/bsd-setjmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/bsd-setjmp.S	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/bsd-setjmp.S	2014-05-27 23:22:12.000000000 -0500
+@@ -27,7 +27,7 @@
+ 	b __novmx__sigsetjmp@local
+ END (__novmxsetjmp)
+ strong_alias (__novmxsetjmp, __novmx__setjmp)
+-symbol_version (__novmxsetjmp, setjmp, GLIBC_2.0)
++compat_symbol (libc, __novmxsetjmp, setjmp, GLIBC_2_0)
+ 
+ #endif  /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) ) */
+ 
+@@ -37,4 +37,4 @@
+ END (__vmxsetjmp)
+ strong_alias (__vmxsetjmp, __vmx__setjmp)
+ strong_alias (__vmx__setjmp, __setjmp)
+-default_symbol_version (__vmxsetjmp,setjmp,GLIBC_2.3.4)
++versioned_symbol (libc, __vmxsetjmp, setjmp, GLIBC_2_3_4)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/__longjmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/__longjmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/__longjmp.S	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/__longjmp.S	2014-05-27 23:22:12.000000000 -0500
+@@ -26,14 +26,14 @@
+ 
+ #else /* !NOT_IN_libc */
+ /* Build a versioned object for libc.  */
+-default_symbol_version (__vmx__longjmp,__longjmp,GLIBC_2.3.4);
++versioned_symbol (libc, __vmx__longjmp, __longjmp, GLIBC_2_3_4);
+ # define __longjmp  __vmx__longjmp
+ # include "__longjmp-common.S"
+ 
+ # if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+ #  define __NO_VMX__
+ #  undef JB_SIZE
+-symbol_version (__novmx__longjmp,__longjmp,GLIBC_2.0);
++compat_symbol (libc, __novmx__longjmp, __longjmp, GLIBC_2_0);
+ #  undef __longjmp
+ #  define __longjmp  __novmx__longjmp
+ #  include "__longjmp-common.S"
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/setjmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/setjmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/setjmp.S	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/fpu/setjmp.S	2014-05-27 23:22:12.000000000 -0500
+@@ -26,7 +26,7 @@
+ 
+ #else /* !NOT_IN_libc */
+ /* Build a versioned object for libc.  */
+-default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4)
++versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4)
+ # define __sigsetjmp __vmx__sigsetjmp
+ # define __sigjmp_save __vmx__sigjmp_save
+ # include "setjmp-common.S"
+@@ -36,7 +36,7 @@
+ #  undef __sigsetjmp
+ #  undef __sigjmp_save
+ #  undef JB_SIZE
+-symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.0)
++compat_symbol (libc, __novmx__sigsetjmp, __sigsetjmp, GLIBC_2_0)
+ #  define __sigsetjmp __novmx__sigsetjmp
+ #  define __sigjmp_save __novmx__sigjmp_save
+ #  include "setjmp-common.S"
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/mcount.c glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/mcount.c
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/mcount.c	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/mcount.c	2014-05-27 23:22:12.000000000 -0500
+@@ -9,7 +9,7 @@
+ /* __mcount_internal was added in glibc 2.15 with version GLIBC_PRIVATE,
+    but it should have been put in version GLIBC_2.15.  Mark the
+    GLIBC_PRIVATE version obsolete and add it to GLIBC_2.16 instead.  */
+-default_symbol_version (___mcount_internal, __mcount_internal, GLIBC_2.16);
++versioned_symbol (libc, ___mcount_internal, __mcount_internal, GLIBC_2_16);
+ 
+ #if SHLIB_COMPAT (libc, GLIBC_2_15, GLIBC_2_16)
+ strong_alias (___mcount_internal, ___mcount_internal_private);
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/setjmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/setjmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/setjmp.S	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/setjmp.S	2014-05-27 23:22:12.000000000 -0500
+@@ -25,7 +25,7 @@
+ 
+ #else /* !NOT_IN_libc */
+ /* Build a versioned object for libc.  */
+-default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4)
++versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4)
+ # define __sigsetjmp __vmx__sigsetjmp
+ # define __sigjmp_save __vmx__sigjmp_save
+ # include "setjmp-common.S"
+@@ -35,7 +35,7 @@
+ #  undef __sigsetjmp
+ #  undef __sigjmp_save
+ #  undef JB_SIZE
+-symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.0)
++compat_symbol (libc, __novmx__sigsetjmp, __sigsetjmp, GLIBC_2_0)
+ #  define __sigsetjmp __novmx__sigsetjmp
+ #  define __sigjmp_save __novmx__sigjmp_save
+ #  include "setjmp-common.S"
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/setjmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp.S	2014-05-27 23:22:10.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/setjmp.S	2014-05-27 23:22:12.000000000 -0500
+@@ -26,9 +26,9 @@
+ 
+ #else /* !NOT_IN_libc */
+ /* Build a versioned object for libc.  */
+-default_symbol_version (__vmxsetjmp, setjmp, GLIBC_2.3.4)
+-default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
+-default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4)
++versioned_symbol (libc, __vmxsetjmp, setjmp, GLIBC_2_3_4)
++versioned_symbol (libc, __vmx_setjmp, _setjmp, GLIBC_2_3_4)
++versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4)
+ # define setjmp __vmxsetjmp
+ # define _setjmp __vmx_setjmp
+ # define __sigsetjmp __vmx__sigsetjmp
+@@ -44,9 +44,9 @@
+ #  undef __sigjmp_save
+ #  undef JB_SIZE
+ #  define __NO_VMX__
+-symbol_version (__novmxsetjmp, setjmp, GLIBC_2.3)
+-symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.3);
+-symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.3)
++compat_symbol (libc, __novmxsetjmp, setjmp, GLIBC_2_3)
++compat_symbol (libc, __novmx_setjmp,_setjmp, GLIBC_2_3);
++compat_symbol (libc, __novmx__sigsetjmp,__sigsetjmp, GLIBC_2_3)
+ #  define setjmp __novmxsetjmp
+ #  define _setjmp __novmx_setjmp
+ #  define __sigsetjmp __novmx__sigsetjmp
diff --git a/SOURCES/glibc-ppc64le-23.patch b/SOURCES/glibc-ppc64le-23.patch
new file mode 100644
index 0000000..b8c1892
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-23.patch
@@ -0,0 +1,102 @@
+# commit 02f04a6c7fea2b474b026bbce721d8c658d71fda
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:36:11 2013 +0930
+# 
+#     PowerPC LE _dl_hwcap access
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00091.html
+#     
+#     More LE support, correcting word accesses to _dl_hwcap.
+#     
+#         * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S: Use
+#         HIWORD/LOWORD.
+#         * sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S: Ditto.
+#         * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S: Ditto.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S	2014-05-27 23:25:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S	2014-05-27 23:25:38.000000000 -0500
+@@ -151,15 +151,15 @@
+ #   ifdef SHARED
+ 	lwz     r7,_rtld_global_ro@got(r7)
+ 	mtlr    r8
+-	lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7)
++	lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7)
+ #   else
+ 	lwz     r7,_dl_hwcap@got(r7)
+ 	mtlr    r8
+-	lwz     r7,4(r7)
++	lwz     r7,LOWORD(r7)
+ #   endif
+ #  else
+-	lis	r7,(_dl_hwcap+4)@ha
+-	lwz     r7,(_dl_hwcap+4)@l(r7)
++	lis	r7,(_dl_hwcap+LOWORD)@ha
++	lwz     r7,(_dl_hwcap+LOWORD)@l(r7)
+ #  endif
+ 	andis.	r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S	2014-05-27 23:25:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S	2014-05-27 23:25:38.000000000 -0500
+@@ -79,15 +79,15 @@
+ # ifdef SHARED
+ 	lwz     r7,_rtld_global_ro@got(r7)
+ 	mtlr    r8
+-	lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7)
++	lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7)
+ # else
+ 	lwz     r7,_dl_hwcap@got(r7)
+ 	mtlr    r8
+-	lwz     r7,4(r7)
++	lwz     r7,LOWORD(r7)
+ # endif
+ #else
+-	lis	r7,(_dl_hwcap+4)@ha
+-	lwz     r7,(_dl_hwcap+4)@l(r7)
++	lis	r7,(_dl_hwcap+LOWORD)@ha
++	lwz     r7,(_dl_hwcap+LOWORD)@l(r7)
+ #endif
+ 
+ #ifdef __CONTEXT_ENABLE_FPRS
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S	2014-05-27 23:25:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S	2014-05-27 23:25:38.000000000 -0500
+@@ -152,15 +152,15 @@
+ #  ifdef SHARED
+ 	lwz     r7,_rtld_global_ro@got(r7)
+ 	mtlr    r8
+-	lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7)
++	lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7)
+ #  else
+ 	lwz     r7,_dl_hwcap@got(r7)
+ 	mtlr    r8
+-	lwz     r7,4(r7)
++	lwz     r7,LOWORD(r7)
+ #  endif
+ # else
+-	lis	r7,(_dl_hwcap+4)@ha
+-	lwz     r7,(_dl_hwcap+4)@l(r7)
++	lis	r7,(_dl_hwcap+LOWORD)@ha
++	lwz     r7,(_dl_hwcap+LOWORD)@l(r7)
+ # endif
+ 
+ # ifdef __CONTEXT_ENABLE_VRS
+@@ -308,14 +308,14 @@
+ 	mtlr    r8
+ #   ifdef SHARED
+ 	lwz     r7,_rtld_global_ro@got(r7)
+-	lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7)
++	lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7)
+ #   else
+ 	lwz     r7,_dl_hwcap@got(r7)
+-	lwz     r7,4(r7)
++	lwz     r7,LOWORD(r7)
+ #   endif
+ #  else
+-	lis	r7,(_dl_hwcap+4)@ha
+-	lwz     r7,(_dl_hwcap+4)@l(r7)
++	lis	r7,(_dl_hwcap+LOWORD)@ha
++	lwz     r7,(_dl_hwcap+LOWORD)@l(r7)
+ #  endif
+ 	andis.	r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ 	la	r10,(_UC_VREGS)(r31)
diff --git a/SOURCES/glibc-ppc64le-24.patch b/SOURCES/glibc-ppc64le-24.patch
new file mode 100644
index 0000000..46f7e54
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-24.patch
@@ -0,0 +1,55 @@
+# commit 0b2c2ace3601d5d59cf89130b16840e7f132f7a6
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:36:45 2013 +0930
+# 
+#     PowerPC makecontext
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00092.html
+#     
+#     Use conditional form of branch and link to avoid destroying the cpu
+#     link stack used to predict blr return addresses.
+#     
+#         * sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: Use
+#         conditional form of branch and link when obtaining pc.
+#         * sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S	2014-05-28 12:25:49.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S	2014-05-28 12:25:51.000000000 -0500
+@@ -47,7 +47,9 @@
+ #ifdef PIC
+ 	mflr	r0
+ 	cfi_register(lr,r0)
+-	bl	1f
++	/* Use this conditional form of branch and link to avoid destroying
++	   the cpu link stack used to predict blr return addresses.  */
++	bcl	20,31,1f
+ 1:	mflr	r6
+ 	addi	r6,r6,L(exitcode)-1b
+ 	mtlr	r0
+@@ -136,7 +138,9 @@
+ #ifdef PIC
+ 	mflr	r0
+ 	cfi_register(lr,r0)
+-	bl	1f
++	/* Use this conditional form of branch and link to avoid destroying
++	   the cpu link stack used to predict blr return addresses.  */
++	bcl	20,31,1f
+ 1:	mflr	r6
+ 	addi	r6,r6,L(novec_exitcode)-1b
+ 	mtlr	r0
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S	2014-05-28 12:25:49.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S	2014-05-28 12:25:51.000000000 -0500
+@@ -124,8 +124,10 @@
+ 
+   /* If the target function returns we need to do some cleanup.  We use a
+      code trick to get the address of our cleanup function into the link
+-     register.  Do not add any code between here and L(exitcode).  */
+-  bl  L(gotexitcodeaddr);
++     register.  Do not add any code between here and L(exitcode).
++     Use this conditional form of branch and link to avoid destroying
++     the cpu link stack used to predict blr return addresses.  */
++  bcl	20,31,L(gotexitcodeaddr);
+ 
+ 	/* This is the helper code which gets called if a function which
+ 	   is registered with 'makecontext' returns.  In this case we
diff --git a/SOURCES/glibc-ppc64le-25.patch b/SOURCES/glibc-ppc64le-25.patch
new file mode 100644
index 0000000..05b22e7
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-25.patch
@@ -0,0 +1,411 @@
+# commit db9b4570c5dc550074140ac1d1677077fba29a26
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:40:11 2013 +0930
+# 
+#     PowerPC LE strlen
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00097.html
+#     
+#     This is the first of nine patches adding little-endian support to the
+#     existing optimised string and memory functions.  I did spend some
+#     time with a power7 simulator looking at cycle by cycle behaviour for
+#     memchr, but most of these patches have not been run on cpu simulators
+#     to check that we are going as fast as possible.  I'm sure PowerPC can
+#     do better.  However, the little-endian support mostly leaves main
+#     loops unchanged, so I'm banking on previous authors having done a
+#     good job on big-endian..  As with most code you stare at long enough,
+#     I found some improvements for big-endian too.
+#     
+#     Little-endian support for strlen.  Like most of the string functions,
+#     I leave the main word or multiple-word loops substantially unchanged,
+#     just needing to modify the tail.
+#     
+#     Removing the branch in the power7 functions is just a tidy.  .align
+#     produces a branch anyway.  Modifying regs in the non-power7 functions
+#     is to suit the new little-endian tail.
+#     
+#         * sysdeps/powerpc/powerpc64/power7/strlen.S (strlen): Add little-endian
+#         support.  Don't branch over align.
+#         * sysdeps/powerpc/powerpc32/power7/strlen.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/strlen.S (strlen): Add little-endian support.
+#         Rearrange tmp reg use to suit.  Comment.
+#         * sysdeps/powerpc/powerpc32/strlen.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strlen.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strlen.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strlen.S	2014-05-28 12:28:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strlen.S	2014-05-28 12:28:45.000000000 -0500
+@@ -31,7 +31,11 @@
+ 	li	r0,0	      /* Word with null chars to use with cmpb.  */
+ 	li	r5,-1	      /* MASK = 0xffffffffffffffff.  */
+ 	lwz	r12,0(r4)     /* Load word from memory.  */
++#ifdef __LITTLE_ENDIAN__
++	slw	r5,r5,r6
++#else
+ 	srw	r5,r5,r6      /* MASK = MASK >> padding.  */
++#endif
+ 	orc	r9,r12,r5     /* Mask bits that are not part of the string.  */
+ 	cmpb	r10,r9,r0     /* Check for null bytes in WORD1.  */
+ 	cmpwi	cr7,r10,0     /* If r10 == 0, no null's have been found.  */
+@@ -49,9 +53,6 @@
+ 	cmpb	r10,r12,r0
+ 	cmpwi	cr7,r10,0
+ 	bne	cr7,L(done)
+-	b	L(loop)	      /* We branch here (rather than falling through)
+-				 to skip the nops due to heavy alignment
+-				 of the loop below.  */
+ 
+ 	/* Main loop to look for the end of the string.  Since it's a
+ 	   small loop (< 8 instructions), align it to 32-bytes.  */
+@@ -88,9 +89,15 @@
+ 	   0xff in the same position as the null byte in the original
+ 	   word from the string.  Use that to calculate the length.  */
+ L(done):
+-	cntlzw	r0,r10	      /* Count leading zeroes before the match.  */
++#ifdef __LITTLE_ENDIAN__
++	addi	r9, r10, -1   /* Form a mask from trailing zeros.  */
++	andc	r9, r9, r10
++	popcntw r0, r9	      /* Count the bits in the mask.  */
++#else
++	cntlzw	r0,r10	      /* Count leading zeros before the match.  */
++#endif
+ 	subf	r5,r3,r4
+-	srwi	r0,r0,3	      /* Convert leading zeroes to bytes.  */
++	srwi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r5,r0      /* Compute final length.  */
+ 	blr
+ END (BP_SYM (strlen))
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strlen.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strlen.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strlen.S	2014-05-28 12:28:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strlen.S	2014-05-28 12:32:24.000000000 -0500
+@@ -31,7 +31,12 @@
+       1 is subtracted you get a value in the range 0x00-0x7f, none of which
+       have their high bit set. The expression here is
+       (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
+-      there were no 0x00 bytes in the word.
++      there were no 0x00 bytes in the word.  You get 0x80 in bytes that
++      match, but possibly false 0x80 matches in the next more significant
++      byte to a true match due to carries.  For little-endian this is
++      of no consequence since the least significant match is the one
++      we're interested in, but big-endian needs method 2 to find which
++      byte matches.
+ 
+    2) Given a word 'x', we can test to see _which_ byte was zero by
+       calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
+@@ -74,7 +79,7 @@
+ 
+ ENTRY (BP_SYM (strlen))
+ 
+-#define rTMP1	r0
++#define rTMP4	r0
+ #define rRTN	r3	/* incoming STR arg, outgoing result */
+ #define rSTR	r4	/* current string position */
+ #define rPADN	r5	/* number of padding bits we prepend to the
+@@ -84,9 +89,9 @@
+ #define rWORD1	r8	/* current string word */
+ #define rWORD2	r9	/* next string word */
+ #define rMASK	r9	/* mask for first string word */
+-#define rTMP2	r10
+-#define rTMP3	r11
+-#define rTMP4	r12
++#define rTMP1	r10
++#define rTMP2	r11
++#define rTMP3	r12
+ 
+ 	CHECK_BOUNDS_LOW (rRTN, rTMP1, rTMP2)
+ 
+@@ -96,15 +101,20 @@
+ 	lwz	rWORD1, 0(rSTR)
+ 	li	rMASK, -1
+ 	addi	r7F7F, r7F7F, 0x7f7f
+-/* That's the setup done, now do the first pair of words.
+-   We make an exception and use method (2) on the first two words, to reduce
+-   overhead.  */
++/* We use method (2) on the first two words, because rFEFE isn't
++   required which reduces setup overhead.  Also gives a faster return
++   for small strings on big-endian due to needing to recalculate with
++   method (2) anyway.  */
++#ifdef __LITTLE_ENDIAN__
++	slw	rMASK, rMASK, rPADN
++#else
+ 	srw	rMASK, rMASK, rPADN
++#endif
+ 	and	rTMP1, r7F7F, rWORD1
+ 	or	rTMP2, r7F7F, rWORD1
+ 	add	rTMP1, rTMP1, r7F7F
+-	nor	rTMP1, rTMP2, rTMP1
+-	and.	rWORD1, rTMP1, rMASK
++	nor	rTMP3, rTMP2, rTMP1
++	and.	rTMP3, rTMP3, rMASK
+ 	mtcrf	0x01, rRTN
+ 	bne	L(done0)
+ 	lis	rFEFE, -0x101
+@@ -113,11 +123,12 @@
+ 	bt	29, L(loop)
+ 
+ /* Handle second word of pair.  */
++/* Perhaps use method (1) here for little-endian, saving one instruction?  */
+ 	lwzu	rWORD1, 4(rSTR)
+ 	and	rTMP1, r7F7F, rWORD1
+ 	or	rTMP2, r7F7F, rWORD1
+ 	add	rTMP1, rTMP1, r7F7F
+-	nor.	rWORD1, rTMP2, rTMP1
++	nor.	rTMP3, rTMP2, rTMP1
+ 	bne	L(done0)
+ 
+ /* The loop.  */
+@@ -131,29 +142,53 @@
+ 	add	rTMP3, rFEFE, rWORD2
+ 	nor	rTMP4, r7F7F, rWORD2
+ 	bne	L(done1)
+-	and.	rTMP1, rTMP3, rTMP4
++	and.	rTMP3, rTMP3, rTMP4
+ 	beq	L(loop)
+ 
++#ifndef __LITTLE_ENDIAN__
+ 	and	rTMP1, r7F7F, rWORD2
+ 	add	rTMP1, rTMP1, r7F7F
+-	andc	rWORD1, rTMP4, rTMP1
++	andc	rTMP3, rTMP4, rTMP1
+ 	b	L(done0)
+ 
+ L(done1):
+ 	and	rTMP1, r7F7F, rWORD1
+ 	subi	rSTR, rSTR, 4
+ 	add	rTMP1, rTMP1, r7F7F
+-	andc	rWORD1, rTMP2, rTMP1
++	andc	rTMP3, rTMP2, rTMP1
+ 
+ /* When we get to here, rSTR points to the first word in the string that
+-   contains a zero byte, and the most significant set bit in rWORD1 is in that
+-   byte.  */
++   contains a zero byte, and rTMP3 has 0x80 for bytes that are zero,
++   and 0x00 otherwise.  */
+ L(done0):
+-	cntlzw	rTMP3, rWORD1
++	cntlzw	rTMP3, rTMP3
+ 	subf	rTMP1, rRTN, rSTR
+ 	srwi	rTMP3, rTMP3, 3
+ 	add	rRTN, rTMP1, rTMP3
+ 	/* GKM FIXME: check high bound.  */
+ 	blr
++#else
++
++L(done0):
++	addi	rTMP1, rTMP3, -1	/* Form a mask from trailing zeros.  */
++	andc	rTMP1, rTMP1, rTMP3
++	cntlzw	rTMP1, rTMP1		/* Count bits not in the mask.  */
++	subf	rTMP3, rRTN, rSTR
++	subfic	rTMP1, rTMP1, 32-7
++	srwi	rTMP1, rTMP1, 3
++	add	rRTN, rTMP1, rTMP3
++	blr
++
++L(done1):
++	addi	rTMP3, rTMP1, -1
++	andc	rTMP3, rTMP3, rTMP1
++	cntlzw	rTMP3, rTMP3
++	subf	rTMP1, rRTN, rSTR
++	subfic	rTMP3, rTMP3, 32-7-32
++	srawi	rTMP3, rTMP3, 3
++	add	rRTN, rTMP1, rTMP3
++	blr
++#endif
++
+ END (BP_SYM (strlen))
+ libc_hidden_builtin_def (strlen)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strlen.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strlen.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strlen.S	2014-05-28 12:28:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strlen.S	2014-05-28 12:28:45.000000000 -0500
+@@ -32,7 +32,11 @@
+ 				 with cmpb.  */
+ 	li	r5,-1	      /* MASK = 0xffffffffffffffff.  */
+ 	ld	r12,0(r4)     /* Load doubleword from memory.  */
++#ifdef __LITTLE_ENDIAN__
++	sld	r5,r5,r6
++#else
+ 	srd	r5,r5,r6      /* MASK = MASK >> padding.  */
++#endif
+ 	orc	r9,r12,r5     /* Mask bits that are not part of the string.  */
+ 	cmpb	r10,r9,r0     /* Check for null bytes in DWORD1.  */
+ 	cmpdi	cr7,r10,0     /* If r10 == 0, no null's have been found.  */
+@@ -50,9 +54,6 @@
+ 	cmpb	r10,r12,r0
+ 	cmpdi	cr7,r10,0
+ 	bne	cr7,L(done)
+-	b	L(loop)	      /* We branch here (rather than falling through)
+-				 to skip the nops due to heavy alignment
+-				 of the loop below.  */
+ 
+ 	/* Main loop to look for the end of the string.  Since it's a
+ 	   small loop (< 8 instructions), align it to 32-bytes.  */
+@@ -89,9 +90,15 @@
+ 	   0xff in the same position as the null byte in the original
+ 	   doubleword from the string.  Use that to calculate the length.  */
+ L(done):
+-	cntlzd	r0,r10	      /* Count leading zeroes before the match.  */
++#ifdef __LITTLE_ENDIAN__
++	addi	r9, r10, -1   /* Form a mask from trailing zeros.  */
++	andc	r9, r9, r10
++	popcntd r0, r9	      /* Count the bits in the mask.  */
++#else
++	cntlzd	r0,r10	      /* Count leading zeros before the match.  */
++#endif
+ 	subf	r5,r3,r4
+-	srdi	r0,r0,3	      /* Convert leading zeroes to bytes.  */
++	srdi	r0,r0,3	      /* Convert leading/trailing zeros to bytes.  */
+ 	add	r3,r5,r0      /* Compute final length.  */
+ 	blr
+ END (BP_SYM (strlen))
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strlen.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strlen.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strlen.S	2014-05-28 12:28:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strlen.S	2014-05-28 12:38:17.000000000 -0500
+@@ -31,7 +31,12 @@
+       1 is subtracted you get a value in the range 0x00-0x7f, none of which
+       have their high bit set. The expression here is
+       (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
+-      there were no 0x00 bytes in the word.
++      there were no 0x00 bytes in the word.  You get 0x80 in bytes that
++      match, but possibly false 0x80 matches in the next more significant
++      byte to a true match due to carries.  For little-endian this is
++      of no consequence since the least significant match is the one
++      we're interested in, but big-endian needs method 2 to find which
++      byte matches.
+ 
+    2) Given a word 'x', we can test to see _which_ byte was zero by
+       calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
+@@ -64,7 +69,7 @@
+    Answer:
+    1) Added a Data Cache Block Touch early to prefetch the first 128 
+    byte cache line. Adding dcbt instructions to the loop would not be 
+-   effective since most strings will be shorter than the cache line.*/
++   effective since most strings will be shorter than the cache line.  */
+ 
+ /* Some notes on register usage: Under the SVR4 ABI, we can use registers
+    0 and 3 through 12 (so long as we don't call any procedures) without
+@@ -80,7 +85,7 @@
+ ENTRY (BP_SYM (strlen))
+ 	CALL_MCOUNT 1
+ 
+-#define rTMP1	r0
++#define rTMP4	r0
+ #define rRTN	r3	/* incoming STR arg, outgoing result */
+ #define rSTR	r4	/* current string position */
+ #define rPADN	r5	/* number of padding bits we prepend to the
+@@ -90,9 +95,9 @@
+ #define rWORD1	r8	/* current string doubleword */
+ #define rWORD2	r9	/* next string doubleword */
+ #define rMASK	r9	/* mask for first string doubleword */
+-#define rTMP2	r10
+-#define rTMP3	r11
+-#define rTMP4	r12
++#define rTMP1	r10
++#define rTMP2	r11
++#define rTMP3	r12
+ 
+ /* Note:  The Bounded pointer support in this code is broken.  This code
+    was inherited from PPC32 and that support was never completed.
+@@ -109,30 +114,36 @@
+ 	addi	r7F7F, r7F7F, 0x7f7f
+ 	li	rMASK, -1
+ 	insrdi	r7F7F, r7F7F, 32, 0
+-/* That's the setup done, now do the first pair of doublewords.
+-   We make an exception and use method (2) on the first two doublewords, 
+-   to reduce overhead.  */
+-	srd	rMASK, rMASK, rPADN
++/* We use method (2) on the first two doublewords, because rFEFE isn't
++   required which reduces setup overhead.  Also gives a faster return
++   for small strings on big-endian due to needing to recalculate with
++   method (2) anyway.  */
++#ifdef __LITTLE_ENDIAN__
++	sld	rMASK, rMASK, rPADN
++#else
++ 	srd	rMASK, rMASK, rPADN
++#endif
+ 	and	rTMP1, r7F7F, rWORD1
+ 	or	rTMP2, r7F7F, rWORD1
+ 	lis	rFEFE, -0x101
+ 	add	rTMP1, rTMP1, r7F7F
+ 	addi	rFEFE, rFEFE, -0x101
+-	nor	rTMP1, rTMP2, rTMP1
+-	and.	rWORD1, rTMP1, rMASK
++	nor	rTMP3, rTMP2, rTMP1
++	and.	rTMP3, rTMP3, rMASK
+ 	mtcrf	0x01, rRTN
+ 	bne	L(done0)
+-	sldi  rTMP1, rFEFE, 32
+-	add  rFEFE, rFEFE, rTMP1
++	sldi	rTMP1, rFEFE, 32
++	add	rFEFE, rFEFE, rTMP1
+ /* Are we now aligned to a doubleword boundary?  */
+ 	bt	28, L(loop)
+ 
+ /* Handle second doubleword of pair.  */
++/* Perhaps use method (1) here for little-endian, saving one instruction?  */
+ 	ldu	rWORD1, 8(rSTR)
+ 	and	rTMP1, r7F7F, rWORD1
+ 	or	rTMP2, r7F7F, rWORD1
+ 	add	rTMP1, rTMP1, r7F7F
+-	nor.	rWORD1, rTMP2, rTMP1
++	nor.	rTMP3, rTMP2, rTMP1
+ 	bne	L(done0)
+ 
+ /* The loop.  */
+@@ -146,29 +157,53 @@
+ 	add	rTMP3, rFEFE, rWORD2
+ 	nor	rTMP4, r7F7F, rWORD2
+ 	bne	L(done1)
+-	and.	rTMP1, rTMP3, rTMP4
++	and.	rTMP3, rTMP3, rTMP4
+ 	beq	L(loop)
+ 
++#ifndef __LITTLE_ENDIAN__
+ 	and	rTMP1, r7F7F, rWORD2
+ 	add	rTMP1, rTMP1, r7F7F
+-	andc	rWORD1, rTMP4, rTMP1
++	andc	rTMP3, rTMP4, rTMP1
+ 	b	L(done0)
+ 
+ L(done1):
+ 	and	rTMP1, r7F7F, rWORD1
+ 	subi	rSTR, rSTR, 8
+ 	add	rTMP1, rTMP1, r7F7F
+-	andc	rWORD1, rTMP2, rTMP1
++	andc	rTMP3, rTMP2, rTMP1
+ 
+ /* When we get to here, rSTR points to the first doubleword in the string that
+-   contains a zero byte, and the most significant set bit in rWORD1 is in that
+-   byte.  */
++   contains a zero byte, and rTMP3 has 0x80 for bytes that are zero, and 0x00
++   otherwise.  */
+ L(done0):
+-	cntlzd	rTMP3, rWORD1
++	cntlzd	rTMP3, rTMP3
+ 	subf	rTMP1, rRTN, rSTR
+ 	srdi	rTMP3, rTMP3, 3
+ 	add	rRTN, rTMP1, rTMP3
+ 	/* GKM FIXME: check high bound.  */
+ 	blr
++#else
++
++L(done0):
++	addi	rTMP1, rTMP3, -1	/* Form a mask from trailing zeros.  */
++	andc	rTMP1, rTMP1, rTMP3
++	cntlzd	rTMP1, rTMP1		/* Count bits not in the mask.  */
++	subf	rTMP3, rRTN, rSTR
++	subfic	rTMP1, rTMP1, 64-7
++	srdi	rTMP1, rTMP1, 3
++	add	rRTN, rTMP1, rTMP3
++	blr
++
++L(done1):
++	addi	rTMP3, rTMP1, -1
++	andc	rTMP3, rTMP3, rTMP1
++	cntlzd	rTMP3, rTMP3
++	subf	rTMP1, rRTN, rSTR
++	subfic	rTMP3, rTMP3, 64-7-64
++	sradi	rTMP3, rTMP3, 3
++	add	rRTN, rTMP1, rTMP3
++	blr
++#endif
++
+ END (BP_SYM (strlen))
+ libc_hidden_builtin_def (strlen)
diff --git a/SOURCES/glibc-ppc64le-26.patch b/SOURCES/glibc-ppc64le-26.patch
new file mode 100644
index 0000000..c07373a
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-26.patch
@@ -0,0 +1,379 @@
+# commit 33ee81de05e83ce12f32a491270bb4c1611399c7
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:40:48 2013 +0930
+# 
+#     PowerPC LE strnlen
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00098.html
+#     
+#     The existing strnlen code has a number of defects, so this patch is more
+#     than just adding little-endian support.  The changes here are similar to
+#     those for memchr.
+#     
+#         * sysdeps/powerpc/powerpc64/power7/strnlen.S (strnlen): Add
+#         little-endian support.  Remove unnecessary "are we done" tests.
+#         Handle "s" wrapping around zero and extremely large "size".
+#         Correct main loop count.  Handle single left-over word from main
+#         loop inline rather than by using small_loop.  Correct comments.
+#         Delete "zero" tail, use "end_max" instead.
+#         * sysdeps/powerpc/powerpc32/power7/strnlen.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strnlen.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strnlen.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strnlen.S	2014-05-28 12:40:17.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strnlen.S	2014-05-28 12:44:52.000000000 -0500
+@@ -30,51 +30,47 @@
+ 	add	r7,r3,r4      /* Calculate the last acceptable address.  */
+ 	cmplwi	r4,16
+ 	li	r0,0	      /* Word with null chars.  */
++	addi	r7,r7,-1
+ 	ble	L(small_range)
+ 
+-	cmplw	cr7,r3,r7     /* Is the address equal or less than r3?  If
+-				 it's equal or less, it means size is either 0
+-				 or a negative number.  */
+-	ble	cr7,L(proceed)
+-
+-	li	r7,-1	      /* Make r11 the biggest if r4 <= 0.  */
+-L(proceed):
+ 	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
+ 	lwz	r12,0(r8)     /* Load word from memory.  */
+ 	cmpb	r10,r12,r0    /* Check for null bytes in DWORD1.  */
++#ifdef __LITTLE_ENDIAN__
++	srw	r10,r10,r6
++	slw	r10,r10,r6
++#else
+ 	slw	r10,r10,r6
+ 	srw	r10,r10,r6
++#endif
+ 	cmplwi	cr7,r10,0     /* If r10 == 0, no null's have been found.  */
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,4
+-	cmplw	cr6,r9,r7
+-	bge	cr6,L(end_max)
+-
++	clrrwi	r7,r7,2       /* Address of last word.  */
+ 	mtcrf   0x01,r8
+ 	/* Are we now aligned to a doubleword boundary?  If so, skip to
+ 	   the main loop.  Otherwise, go through the alignment code.  */
+ 
+ 	bt	29,L(loop_setup)
+ 
+-	/* Handle DWORD2 of pair.  */
++	/* Handle WORD2 of pair.  */
+ 	lwzu	r12,4(r8)
+ 	cmpb	r10,r12,r0
+ 	cmplwi	cr7,r10,0
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,4
+-	cmplw	cr6,r9,r7
+-	bge	cr6,L(end_max)
+-
+ L(loop_setup):
+-	sub	r5,r7,r9
++	/* The last word we want to read in the loop below is the one
++	   containing the last byte of the string, ie. the word at
++	   (s + size - 1) & ~3, or r7.  The first word read is at
++	   r8 + 4, we read 2 * cnt words, so the last word read will
++	   be at r8 + 4 + 8 * cnt - 4.  Solving for cnt gives
++	   cnt = (r7 - r8) / 8  */
++	sub	r5,r7,r8
+ 	srwi	r6,r5,3	      /* Number of loop iterations.  */
+ 	mtctr	r6	      /* Setup the counter.  */
+-	b	L(loop)
+-	/* Main loop to look for the null byte backwards in the string.  Since
++
++	/* Main loop to look for the null byte in the string.  Since
+ 	   it's a small loop (< 8 instructions), align it to 32-bytes.  */
+ 	.p2align  5
+ L(loop):
+@@ -90,15 +86,18 @@
+ 	cmplwi	cr7,r5,0
+ 	bne	cr7,L(found)
+ 	bdnz	L(loop)
+-	/* We're here because the counter reached 0, and that means we
+-	   didn't have any matches for null in the whole range.  Just return
+-	   the original size.  */
+-	addi	r9,r8,4
+-	cmplw	cr6,r9,r7
+-	blt	cr6,L(loop_small)
++
++	/* We may have one more word to read.  */
++	cmplw	cr6,r8,r7
++	beq	cr6,L(end_max)
++
++	lwzu	r12,4(r8)
++	cmpb	r10,r12,r0
++	cmplwi	cr6,r10,0
++	bne	cr6,L(done)
+ 
+ L(end_max):
+-	sub	r3,r7,r3
++	mr	r3,r4
+ 	blr
+ 
+ 	/* OK, one (or both) of the words contains a null byte.  Check
+@@ -123,49 +122,56 @@
+ 	   We need to make sure the null char is *before* the end of the
+ 	   range.  */
+ L(done):
+-	cntlzw	r0,r10	      /* Count leading zeroes before the match.  */
+-	srwi	r0,r0,3	      /* Convert leading zeroes to bytes.  */
+-	add	r9,r8,r0
+-	sub	r6,r9,r3      /* Length until the match.  */
+-	cmplw	r9,r7
+-	bgt	L(end_max)
+-	mr	r3,r6
+-	blr
+-
+-	.align	4
+-L(zero):
+-	li	r3,0
++#ifdef __LITTLE_ENDIAN__
++	addi	r0,r10,-1
++	andc	r0,r0,r10
++	popcntw	r0,r0
++#else
++	cntlzw	r0,r10	      /* Count leading zeros before the match.  */
++#endif
++	sub	r3,r8,r3
++	srwi	r0,r0,3	      /* Convert leading/trailing zeros to bytes.  */
++	add	r3,r3,r0      /* Length until the match.  */
++	cmplw	r3,r4
++	blelr
++	mr	r3,r4
+ 	blr
+ 
+-/* Deals with size <= 32.  */
++/* Deals with size <= 16.  */
+ 	.align	4
+ L(small_range):
+ 	cmplwi	r4,0
+-	beq	L(zero)
++	beq	L(end_max)
++
++	clrrwi	r7,r7,2       /* Address of last word.  */
+ 
+ 	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
+ 	lwz	r12,0(r8)     /* Load word from memory.  */
+ 	cmpb	r10,r12,r0    /* Check for null bytes in WORD1.  */
++#ifdef __LITTLE_ENDIAN__
++	srw	r10,r10,r6
++	slw	r10,r10,r6
++#else
+ 	slw	r10,r10,r6
+ 	srw	r10,r10,r6
++#endif
+ 	cmplwi	cr7,r10,0
+ 	bne	cr7,L(done)
+ 
+-	addi    r9,r8,4
+-	cmplw	r9,r7
+-	bge	L(end_max)
+-	b	L(loop_small)
++	cmplw	r8,r7
++	beq	L(end_max)
+ 
+ 	.p2align  5
+ L(loop_small):
+ 	lwzu	r12,4(r8)
+ 	cmpb	r10,r12,r0
+-	addi	r9,r8,4
+ 	cmplwi	cr6,r10,0
+ 	bne	cr6,L(done)
+-	cmplw	r9,r7
+-	bge	L(end_max)
+-	b	L(loop_small)
++	cmplw	r8,r7
++	bne	L(loop_small)
++	mr	r3,r4
++	blr
++
+ END (BP_SYM (__strnlen))
+ weak_alias (BP_SYM (__strnlen), BP_SYM(strnlen))
+ libc_hidden_builtin_def (strnlen)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strnlen.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strnlen.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strnlen.S	2014-05-28 12:40:17.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strnlen.S	2014-05-28 13:24:41.000000000 -0500
+@@ -26,33 +26,29 @@
+ ENTRY (BP_SYM (__strnlen))
+ 	CALL_MCOUNT 2
+ 	dcbt	0,r3
+-	clrrdi  r8,r3,3
++	clrrdi	r8,r3,3
+ 	add	r7,r3,r4      /* Calculate the last acceptable address.  */
+ 	cmpldi	r4,32
+ 	li	r0,0	      /* Doubleword with null chars.  */
++	addi	r7,r7,-1
++
+ 	/* If we have less than 33 bytes to search, skip to a faster code.  */
+ 	ble	L(small_range)
+ 
+-	cmpld	cr7,r3,r7    /* Is the address equal or less than r3?  If
+-				it's equal or less, it means size is either 0
+-				or a negative number.  */
+-	ble	cr7,L(proceed)
+-
+-	li	r7,-1	      /* Make r11 the biggest if r4 <= 0.  */
+-L(proceed):
+ 	rlwinm	r6,r3,3,26,28 /* Calculate padding.  */
+ 	ld	r12,0(r8)     /* Load doubleword from memory.  */
+ 	cmpb	r10,r12,r0    /* Check for null bytes in DWORD1.  */
++#ifdef __LITTLE_ENDIAN__
++	srd	r10,r10,r6
++	sld	r10,r10,r6
++#else
+ 	sld	r10,r10,r6
+ 	srd	r10,r10,r6
++#endif
+ 	cmpldi	cr7,r10,0     /* If r10 == 0, no null's have been found.  */
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,8
+-	cmpld	cr6,r9,r7
+-	bge	cr6,L(end_max)
+-
++	clrrdi	r7,r7,3       /* Address of last doubleword.  */
+ 	mtcrf   0x01,r8
+ 	/* Are we now aligned to a quadword boundary?  If so, skip to
+ 	   the main loop.  Otherwise, go through the alignment code.  */
+@@ -65,17 +61,18 @@
+ 	cmpldi	cr7,r10,0
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,8
+-	cmpld	cr6,r9,r7
+-	bge	cr6,L(end_max)
+-
+ L(loop_setup):
+-	sub	r5,r7,r9
++	/* The last dword we want to read in the loop below is the one
++	   containing the last byte of the string, ie. the dword at
++	   (s + size - 1) & ~7, or r7.  The first dword read is at
++	   r8 + 8, we read 2 * cnt dwords, so the last dword read will
++	   be at r8 + 8 + 16 * cnt - 8.  Solving for cnt gives
++	   cnt = (r7 - r8) / 16  */
++	sub	r5,r7,r8
+ 	srdi	r6,r5,4	      /* Number of loop iterations.  */
+ 	mtctr	r6	      /* Setup the counter.  */
+-	b	L(loop)
+-	/* Main loop to look for the null byte backwards in the string.  Since
++
++	/* Main loop to look for the null byte in the string.  Since
+ 	   it's a small loop (< 8 instructions), align it to 32-bytes.  */
+ 	.p2align  5
+ L(loop):
+@@ -91,15 +88,18 @@
+ 	cmpldi	cr7,r5,0
+ 	bne	cr7,L(found)
+ 	bdnz	L(loop)
+-	/* We're here because the counter reached 0, and that means we
+-	   didn't have any matches for null in the whole range.  Just return
+-	   the original size.  */
+-	addi	r9,r8,8
+-	cmpld	cr6,r9,r7
+-	blt	cr6,L(loop_small)
++
++	/* We may have one more dword to read.  */
++	cmpld	cr6,r8,r7
++	beq	cr6,L(end_max)
++
++	ldu	r12,8(r8)
++	cmpb	r10,r12,r0
++	cmpldi	cr6,r10,0
++	bne	cr6,L(done)
+ 
+ L(end_max):
+-	sub	r3,r7,r3
++	mr	r3,r4
+ 	blr
+ 
+ 	/* OK, one (or both) of the doublewords contains a null byte.  Check
+@@ -121,52 +121,59 @@
+ 	/* r10 has the output of the cmpb instruction, that is, it contains
+ 	   0xff in the same position as the null byte in the original
+ 	   doubleword from the string.  Use that to calculate the length.
+-	   We need to make sure the null char is *before* the start of the
+-	   range (since we're going backwards).  */
++	   We need to make sure the null char is *before* the end of the
++	   range.  */
+ L(done):
+-	cntlzd	r0,r10	      /* Count leading zeroes before the match.  */
+-	srdi	r0,r0,3	      /* Convert leading zeroes to bytes.  */
+-	add	r9,r8,r0
+-	sub	r6,r9,r3      /* Length until the match.  */
+-	cmpld	r9,r7
+-	bgt	L(end_max)
+-	mr	r3,r6
+-	blr
+-
+-	.align	4
+-L(zero):
+-	li	r3,0
++#ifdef __LITTLE_ENDIAN__
++	addi	r0,r10,-1
++	andc	r0,r0,r10
++	popcntd	r0,r0
++#else
++	cntlzd	r0,r10	      /* Count leading zeros before the match.  */
++#endif
++	sub	r3,r8,r3
++	srdi	r0,r0,3	      /* Convert leading/trailing zeros to bytes.  */
++	add	r3,r3,r0      /* Length until the match.  */
++	cmpld	r3,r4
++	blelr
++	mr	r3,r4
+ 	blr
+ 
+ /* Deals with size <= 32.  */
+ 	.align	4
+ L(small_range):
+ 	cmpldi	r4,0
+-	beq	L(zero)
++	beq	L(end_max)
++
++	clrrdi	r7,r7,3       /* Address of last doubleword.  */
+ 
+ 	rlwinm	r6,r3,3,26,28 /* Calculate padding.  */
+-	ld	r12,0(r8)     /* Load word from memory.  */
++	ld	r12,0(r8)     /* Load doubleword from memory.  */
+ 	cmpb	r10,r12,r0    /* Check for null bytes in DWORD1.  */
++#ifdef __LITTLE_ENDIAN__
++	srd	r10,r10,r6
++	sld	r10,r10,r6
++#else
+ 	sld	r10,r10,r6
+ 	srd	r10,r10,r6
++#endif
+ 	cmpldi	cr7,r10,0
+ 	bne	cr7,L(done)
+ 
+-	addi    r9,r8,8
+-	cmpld	r9,r7
+-	bge	L(end_max)
+-	b	L(loop_small)
++	cmpld	r8,r7
++	beq	L(end_max)
+ 
+ 	.p2align  5
+ L(loop_small):
+ 	ldu	r12,8(r8)
+ 	cmpb	r10,r12,r0
+-	addi	r9,r8,8
+ 	cmpldi	cr6,r10,0
+ 	bne	cr6,L(done)
+-	cmpld	r9,r7
+-	bge	L(end_max)
+-	b	L(loop_small)
++	cmpld	r8,r7
++	bne	L(loop_small)
++	mr	r3,r4
++	blr
++
+ END (BP_SYM (__strnlen))
+ weak_alias (BP_SYM (__strnlen), BP_SYM(strnlen))
+ libc_hidden_builtin_def (strnlen)
diff --git a/SOURCES/glibc-ppc64le-27.patch b/SOURCES/glibc-ppc64le-27.patch
new file mode 100644
index 0000000..26e97bb
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-27.patch
@@ -0,0 +1,861 @@
+# commit 8a7413f9b036da83ffde491a37d9d2340bc321a7
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:41:17 2013 +0930
+# 
+#     PowerPC LE strcmp and strncmp
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00099.html
+#     
+#     More little-endian support.  I leave the main strcmp loops unchanged,
+#     (well, except for renumbering rTMP to something other than r0 since
+#     it's needed in an addi insn) and modify the tail for little-endian.
+#     
+#     I noticed some of the big-endian tail code was a little untidy so have
+#     cleaned that up too.
+#     
+#         * sysdeps/powerpc/powerpc64/strcmp.S (rTMP2): Define as r0.
+#         (rTMP): Define as r11.
+#         (strcmp): Add little-endian support.  Optimise tail.
+#         * sysdeps/powerpc/powerpc32/strcmp.S: Similarly.
+#         * sysdeps/powerpc/powerpc64/strncmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/strncmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power4/strncmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power4/strncmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power7/strncmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/strncmp.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/strncmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/strncmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/strncmp.S	2014-05-28 13:26:59.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/strncmp.S	2014-05-28 13:27:02.000000000 -0500
+@@ -26,7 +26,7 @@
+ 
+ EALIGN (BP_SYM(strncmp), 4, 0)
+ 
+-#define rTMP	r0
++#define rTMP2	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -42,6 +42,7 @@
+ #define r7F7F	r9	/* constant 0x7f7f7f7f */
+ #define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f) */
+ #define rBITDIF	r11	/* bits that differ in s1 & s2 words */
++#define rTMP	r12
+ 
+ 	dcbt	0,rSTR1
+ 	or	rTMP, rSTR2, rSTR1
+@@ -80,12 +81,45 @@
+    we don't compare two strings as different because of gunk beyond
+    the end of the strings...  */
+ 
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	slwi	rTMP, rTMP, 1
++	addi    rTMP2, rTMP, -1
++	andc    rTMP2, rTMP2, rTMP
++	and	rWORD2, rWORD2, rTMP2		/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rldimi	rTMP2, rWORD2, 24, 32
++	rldimi	rTMP, rWORD1, 24, 32
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr+
++	ori	rRTN, rTMP2, 1
++	blr
++
++L(different):
++	lwz	rWORD1, -4(rSTR1)
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rldimi	rTMP2, rWORD2, 24, 32
++	rldimi	rTMP, rWORD1, 24, 32
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr+
++	ori	rRTN, rTMP2, 1
++	blr
++
++#else
+ L(endstring):
+ 	and	rTMP, r7F7F, rWORD1
+ 	beq	cr1, L(equal)
+ 	add	rTMP, rTMP, r7F7F
+ 	xor.	rBITDIF, rWORD1, rWORD2
+-
+ 	andc	rNEG, rNEG, rTMP
+ 	blt-	L(highbit)
+ 	cntlzw	rBITDIF, rBITDIF
+@@ -93,28 +127,20 @@
+ 	addi	rNEG, rNEG, 7
+ 	cmpw	cr1, rNEG, rBITDIF
+ 	sub	rRTN, rWORD1, rWORD2
+-	blt-	cr1, L(equal)
+-	srawi	rRTN, rRTN, 31
+-	ori	rRTN, rRTN, 1
+-	blr
++	bgelr+	cr1
+ L(equal):
+ 	li	rRTN, 0
+ 	blr
+ 
+ L(different):
+-	lwzu	rWORD1, -4(rSTR1)
++	lwz	rWORD1, -4(rSTR1)
+ 	xor.	rBITDIF, rWORD1, rWORD2
+ 	sub	rRTN, rWORD1, rWORD2
+-	blt-	L(highbit)
+-	srawi	rRTN, rRTN, 31
+-	ori	rRTN, rRTN, 1
+-	blr
++	bgelr+
+ L(highbit):
+-	srwi	rWORD2, rWORD2, 24
+-	srwi	rWORD1, rWORD1, 24
+-	sub	rRTN, rWORD1, rWORD2
++	ori	rRTN, rWORD2, 1
+ 	blr
+-
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+ 	.align 4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strncmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strncmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strncmp.S	2014-05-28 13:26:59.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strncmp.S	2014-05-28 13:27:02.000000000 -0500
+@@ -28,7 +28,7 @@
+ 
+ EALIGN (BP_SYM(strncmp),5,0)
+ 
+-#define rTMP	r0
++#define rTMP2	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -44,6 +44,7 @@
+ #define r7F7F	r9	/* constant 0x7f7f7f7f */
+ #define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f) */
+ #define rBITDIF	r11	/* bits that differ in s1 & s2 words */
++#define rTMP	r12
+ 
+ 	dcbt	0,rSTR1
+ 	nop
+@@ -83,13 +84,45 @@
+ /* OK. We've hit the end of the string. We need to be careful that
+    we don't compare two strings as different because of gunk beyond
+    the end of the strings...  */
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	slwi	rTMP, rTMP, 1
++	addi    rTMP2, rTMP, -1
++	andc    rTMP2, rTMP2, rTMP
++	and	rWORD2, rWORD2, rTMP2		/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rldimi	rTMP2, rWORD2, 24, 32
++	rldimi	rTMP, rWORD1, 24, 32
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr
++	ori	rRTN, rTMP2, 1
++	blr
++
++L(different):
++	lwz	rWORD1, -4(rSTR1)
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rldimi	rTMP2, rWORD2, 24, 32
++	rldimi	rTMP, rWORD1, 24, 32
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr
++	ori	rRTN, rTMP2, 1
++	blr
+ 
++#else
+ L(endstring):
+ 	and	rTMP,r7F7F,rWORD1
+ 	beq	cr1,L(equal)
+ 	add	rTMP,rTMP,r7F7F
+ 	xor.	rBITDIF,rWORD1,rWORD2
+-
+ 	andc	rNEG,rNEG,rTMP
+ 	blt	L(highbit)
+ 	cntlzw	rBITDIF,rBITDIF
+@@ -97,28 +130,20 @@
+ 	addi	rNEG,rNEG,7
+ 	cmpw	cr1,rNEG,rBITDIF
+ 	sub	rRTN,rWORD1,rWORD2
+-	blt	cr1,L(equal)
+-	srawi	rRTN,rRTN,31
+-	ori	rRTN,rRTN,1
+-	blr
++	bgelr	cr1
+ L(equal):
+ 	li	rRTN,0
+ 	blr
+ 
+ L(different):
+-	lwzu	rWORD1,-4(rSTR1)
++	lwz	rWORD1,-4(rSTR1)
+ 	xor.	rBITDIF,rWORD1,rWORD2
+ 	sub	rRTN,rWORD1,rWORD2
+-	blt	L(highbit)
+-	srawi	rRTN,rRTN,31
+-	ori	rRTN,rRTN,1
+-	blr
++	bgelr
+ L(highbit):
+-	srwi	rWORD2,rWORD2,24
+-	srwi	rWORD1,rWORD1,24
+-	sub	rRTN,rWORD1,rWORD2
++	ori	rRTN, rWORD2, 1
+ 	blr
+-
++#endif
+ 
+ /* Oh well. In this case, we just do a byte-by-byte comparison.  */
+ 	.align	4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strcmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strcmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strcmp.S	2014-05-28 13:26:59.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strcmp.S	2014-05-28 13:27:02.000000000 -0500
+@@ -26,7 +26,7 @@
+ 
+ EALIGN (BP_SYM (strcmp), 4, 0)
+ 
+-#define rTMP	r0
++#define rTMP2	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -40,6 +40,7 @@
+ #define r7F7F	r8	/* constant 0x7f7f7f7f */
+ #define rNEG	r9	/* ~(word in s1 | 0x7f7f7f7f) */
+ #define rBITDIF	r10	/* bits that differ in s1 & s2 words */
++#define rTMP	r11
+ 
+ 	CHECK_BOUNDS_LOW (rSTR1, rTMP, rHIGH1)
+ 	CHECK_BOUNDS_LOW (rSTR2, rTMP, rHIGH2)
+@@ -64,10 +65,45 @@
+ 	and.	rTMP, rTMP, rNEG
+ 	cmpw	cr1, rWORD1, rWORD2
+ 	beq+	L(g0)
+-L(endstring):
++
+ /* OK. We've hit the end of the string. We need to be careful that
+    we don't compare two strings as different because of gunk beyond
+    the end of the strings...  */
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	addi    rTMP2, rTMP, -1
++	andc    rTMP2, rTMP2, rTMP
++	rlwimi	rTMP2, rTMP2, 1, 0, 30
++	and	rWORD2, rWORD2, rTMP2		/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rlwimi	rTMP2, rWORD2, 24, 0, 7
++	rlwimi	rTMP, rWORD1, 24, 0, 7
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr+
++	ori	rRTN, rTMP2, 1
++	blr
++
++L(different):
++	lwz	rWORD1, -4(rSTR1)
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rlwimi	rTMP2, rWORD2, 24, 0, 7
++	rlwimi	rTMP, rWORD1, 24, 0, 7
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr+
++	ori	rRTN, rTMP2, 1
++	blr
++
++#else
++L(endstring):
+ 	and	rTMP, r7F7F, rWORD1
+ 	beq	cr1, L(equal)
+ 	add	rTMP, rTMP, r7F7F
+@@ -94,7 +130,7 @@
+ 	ori	rRTN, rWORD2, 1
+ 	/* GKM FIXME: check high bounds.  */
+ 	blr
+-
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+ 	.align 4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strncmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strncmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strncmp.S	2014-05-28 13:26:59.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strncmp.S	2014-05-28 13:27:02.000000000 -0500
+@@ -26,7 +26,7 @@
+ 
+ EALIGN (BP_SYM(strncmp), 4, 0)
+ 
+-#define rTMP	r0
++#define rTMP2	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -40,6 +40,7 @@
+ #define r7F7F	r9	/* constant 0x7f7f7f7f */
+ #define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f) */
+ #define rBITDIF	r11	/* bits that differ in s1 & s2 words */
++#define rTMP	r12
+ 
+ 	dcbt	0,rSTR1
+ 	or	rTMP, rSTR2, rSTR1
+@@ -78,12 +79,45 @@
+    we don't compare two strings as different because of gunk beyond
+    the end of the strings...  */
+ 
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	slwi	rTMP, rTMP, 1
++	addi    rTMP2, rTMP, -1
++	andc    rTMP2, rTMP2, rTMP
++	and	rWORD2, rWORD2, rTMP2		/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rlwimi	rTMP2, rWORD2, 24, 0, 7
++	rlwimi	rTMP, rWORD1, 24, 0, 7
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr+
++	ori	rRTN, rTMP2, 1
++	blr
++
++L(different):
++	lwz	rWORD1, -4(rSTR1)
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rlwimi	rTMP2, rWORD2, 24, 0, 7
++	rlwimi	rTMP, rWORD1, 24, 0, 7
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr+
++	ori	rRTN, rTMP2, 1
++	blr
++
++#else
+ L(endstring):
+ 	and	rTMP, r7F7F, rWORD1
+ 	beq	cr1, L(equal)
+ 	add	rTMP, rTMP, r7F7F
+ 	xor.	rBITDIF, rWORD1, rWORD2
+-
+ 	andc	rNEG, rNEG, rTMP
+ 	blt-	L(highbit)
+ 	cntlzw	rBITDIF, rBITDIF
+@@ -91,28 +125,20 @@
+ 	addi	rNEG, rNEG, 7
+ 	cmpw	cr1, rNEG, rBITDIF
+ 	sub	rRTN, rWORD1, rWORD2
+-	blt-	cr1, L(equal)
+-	srawi	rRTN, rRTN, 31
+-	ori	rRTN, rRTN, 1
+-	blr
++	bgelr+	cr1
+ L(equal):
+ 	li	rRTN, 0
+ 	blr
+ 
+ L(different):
+-	lwzu	rWORD1, -4(rSTR1)
++	lwz	rWORD1, -4(rSTR1)
+ 	xor.	rBITDIF, rWORD1, rWORD2
+ 	sub	rRTN, rWORD1, rWORD2
+-	blt-	L(highbit)
+-	srawi	rRTN, rRTN, 31
+-	ori	rRTN, rRTN, 1
+-	blr
++	bgelr+
+ L(highbit):
+-	srwi	rWORD2, rWORD2, 24
+-	srwi	rWORD1, rWORD1, 24
+-	sub	rRTN, rWORD1, rWORD2
++	ori	rRTN, rWORD2, 1
+ 	blr
+-
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+ 	.align 4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power4/strncmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power4/strncmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power4/strncmp.S	2014-05-28 13:26:59.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power4/strncmp.S	2014-05-28 13:27:02.000000000 -0500
+@@ -27,7 +27,7 @@
+ EALIGN (BP_SYM(strncmp), 4, 0)
+ 	CALL_MCOUNT 3
+ 
+-#define rTMP	r0
++#define rTMP2	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -43,6 +43,7 @@
+ #define r7F7F	r9	/* constant 0x7f7f7f7f7f7f7f7f */
+ #define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
+ #define rBITDIF	r11	/* bits that differ in s1 & s2 words */
++#define rTMP	r12
+ 
+ 	dcbt	0,rSTR1
+ 	or	rTMP, rSTR2, rSTR1
+@@ -84,12 +85,59 @@
+    we don't compare two strings as different because of gunk beyond
+    the end of the strings...  */
+ 
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	addi    rTMP2, rTMP, -1
++	beq	cr1, L(equal)
++	andc    rTMP2, rTMP2, rTMP
++	rldimi	rTMP2, rTMP2, 1, 0
++	and	rWORD2, rWORD2, rTMP2	/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	cmpd	cr1, rWORD1, rWORD2
++	beq	cr1, L(equal)
++	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
++	neg	rNEG, rBITDIF
++	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
++	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
++	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
++	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
++	sld	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
++	ori	rRTN, rRTN, 1
++	blr
++L(equal):
++	li	rRTN, 0
++	blr
++
++L(different):
++	ld	rWORD1, -8(rSTR1)
++	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
++	neg	rNEG, rBITDIF
++	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
++	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
++	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
++	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
++	sld	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63
++	ori	rRTN, rRTN, 1
++	blr
++L(highbit):
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
++	blr
++
++#else
+ L(endstring):
+ 	and	rTMP, r7F7F, rWORD1
+ 	beq	cr1, L(equal)
+ 	add	rTMP, rTMP, r7F7F
+ 	xor.	rBITDIF, rWORD1, rWORD2
+-
+ 	andc	rNEG, rNEG, rTMP
+ 	blt-	L(highbit)
+ 	cntlzd	rBITDIF, rBITDIF
+@@ -98,7 +146,7 @@
+ 	cmpd	cr1, rNEG, rBITDIF
+ 	sub	rRTN, rWORD1, rWORD2
+ 	blt-	cr1, L(equal)
+-	sradi	rRTN, rRTN, 63
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
+ 	ori	rRTN, rRTN, 1
+ 	blr
+ L(equal):
+@@ -106,7 +154,7 @@
+ 	blr
+ 
+ L(different):
+-	ldu	rWORD1, -8(rSTR1)
++	ld	rWORD1, -8(rSTR1)
+ 	xor.	rBITDIF, rWORD1, rWORD2
+ 	sub	rRTN, rWORD1, rWORD2
+ 	blt-	L(highbit)
+@@ -114,11 +162,10 @@
+ 	ori	rRTN, rRTN, 1
+ 	blr
+ L(highbit):
+-	srdi	rWORD2, rWORD2, 56
+-	srdi	rWORD1, rWORD1, 56
+-	sub	rRTN, rWORD1, rWORD2
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
+ 	blr
+-
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+ 	.align 4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strncmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strncmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strncmp.S	2014-05-28 13:26:59.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strncmp.S	2014-05-28 13:27:02.000000000 -0500
+@@ -29,7 +29,7 @@
+ EALIGN (BP_SYM(strncmp),5,0)
+ 	CALL_MCOUNT 3
+ 
+-#define rTMP	r0
++#define rTMP2	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -45,6 +45,7 @@
+ #define r7F7F	r9	/* constant 0x7f7f7f7f7f7f7f7f */
+ #define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
+ #define rBITDIF	r11	/* bits that differ in s1 & s2 words */
++#define rTMP	r12
+ 
+ 	dcbt	0,rSTR1
+ 	nop
+@@ -88,12 +89,57 @@
+    we don't compare two strings as different because of gunk beyond
+    the end of the strings...  */
+ 
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	addi    rTMP2, rTMP, -1
++	beq	cr1, L(equal)
++	andc    rTMP2, rTMP2, rTMP
++	rldimi	rTMP2, rTMP2, 1, 0
++	and	rWORD2, rWORD2, rTMP2	/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	cmpd	cr1, rWORD1, rWORD2
++	beq	cr1, L(equal)
++	cmpb	rBITDIF, rWORD1, rWORD2	/* 0xff on equal bytes.  */
++	addi	rNEG, rBITDIF, 1
++	orc	rNEG, rNEG, rBITDIF	/* 0's below LS differing byte.  */
++	sldi	rNEG, rNEG, 8		/* 1's above LS differing byte.  */
++	andc	rWORD1, rWORD1, rNEG	/* mask off MS bytes.  */
++	andc	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt	L(highbit)
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
++	ori	rRTN, rRTN, 1
++	blr
++L(equal):
++	li	rRTN, 0
++	blr
++
++L(different):
++	ld	rWORD1, -8(rSTR1)
++	cmpb	rBITDIF, rWORD1, rWORD2	/* 0xff on equal bytes.  */
++	addi	rNEG, rBITDIF, 1
++	orc	rNEG, rNEG, rBITDIF	/* 0's below LS differing byte.  */
++	sldi	rNEG, rNEG, 8		/* 1's above LS differing byte.  */
++	andc	rWORD1, rWORD1, rNEG	/* mask off MS bytes.  */
++	andc	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt	L(highbit)
++	sradi	rRTN, rRTN, 63
++	ori	rRTN, rRTN, 1
++	blr
++L(highbit):
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
++	blr
++
++#else
+ L(endstring):
+ 	and	rTMP,r7F7F,rWORD1
+ 	beq	cr1,L(equal)
+ 	add	rTMP,rTMP,r7F7F
+ 	xor.	rBITDIF,rWORD1,rWORD2
+-
+ 	andc	rNEG,rNEG,rTMP
+ 	blt	L(highbit)
+ 	cntlzd	rBITDIF,rBITDIF
+@@ -102,7 +148,7 @@
+ 	cmpd	cr1,rNEG,rBITDIF
+ 	sub	rRTN,rWORD1,rWORD2
+ 	blt	cr1,L(equal)
+-	sradi	rRTN,rRTN,63
++	sradi	rRTN,rRTN,63		/* must return an int.  */
+ 	ori	rRTN,rRTN,1
+ 	blr
+ L(equal):
+@@ -110,7 +156,7 @@
+ 	blr
+ 
+ L(different):
+-	ldu	rWORD1,-8(rSTR1)
++	ld	rWORD1,-8(rSTR1)
+ 	xor.	rBITDIF,rWORD1,rWORD2
+ 	sub	rRTN,rWORD1,rWORD2
+ 	blt	L(highbit)
+@@ -118,11 +164,10 @@
+ 	ori	rRTN,rRTN,1
+ 	blr
+ L(highbit):
+-	srdi	rWORD2,rWORD2,56
+-	srdi	rWORD1,rWORD1,56
+-	sub	rRTN,rWORD1,rWORD2
++	sradi	rRTN,rWORD2,63
++	ori	rRTN,rRTN,1
+ 	blr
+-
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+ 	.align	4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strcmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strcmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strcmp.S	2014-05-28 13:26:59.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strcmp.S	2014-05-28 13:37:15.000000000 -0500
+@@ -27,7 +27,7 @@
+ EALIGN (BP_SYM(strcmp), 4, 0)
+ 	CALL_MCOUNT 2
+ 
+-#define rTMP	r0
++#define rTMP2	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -46,6 +46,7 @@
+ #define r7F7F	r8	/* constant 0x7f7f7f7f7f7f7f7f */
+ #define rNEG	r9	/* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
+ #define rBITDIF	r10	/* bits that differ in s1 & s2 words */
++#define rTMP	r11
+ 
+ 	CHECK_BOUNDS_LOW (rSTR1, rTMP, rHIGH1)
+ 	CHECK_BOUNDS_LOW (rSTR2, rTMP, rHIGH2)
+@@ -72,19 +73,66 @@
+ 	ldu	rWORD2, 8(rSTR2)
+ L(g1):	add	rTMP, rFEFE, rWORD1
+ 	nor	rNEG, r7F7F, rWORD1
+-
+ 	and.	rTMP, rTMP, rNEG
+ 	cmpd	cr1, rWORD1, rWORD2
+ 	beq+	L(g0)
+-L(endstring):
++
+ /* OK. We've hit the end of the string. We need to be careful that
+    we don't compare two strings as different because of gunk beyond
+    the end of the strings...  */
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	addi    rTMP2, rTMP, -1
++	beq	cr1, L(equal)
++	andc    rTMP2, rTMP2, rTMP
++	rldimi	rTMP2, rTMP2, 1, 0
++	and	rWORD2, rWORD2, rTMP2	/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	cmpd	cr1, rWORD1, rWORD2
++	beq	cr1, L(equal)
++	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
++	neg	rNEG, rBITDIF
++	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
++	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
++	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
++	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
++	sld	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
++	ori	rRTN, rRTN, 1
++	blr
++L(equal):
++	li	rRTN, 0
++	blr
++
++L(different):
++	ld	rWORD1, -8(rSTR1)
++	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
++	neg	rNEG, rBITDIF
++	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
++	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
++	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
++	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
++	sld	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63
++	ori	rRTN, rRTN, 1
++	blr
++L(highbit):
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
++	blr
++
++#else
++L(endstring):
+ 	and	rTMP, r7F7F, rWORD1
+ 	beq	cr1, L(equal)
+ 	add	rTMP, rTMP, r7F7F
+ 	xor.	rBITDIF, rWORD1, rWORD2
+-
+ 	andc	rNEG, rNEG, rTMP
+ 	blt-	L(highbit)
+ 	cntlzd	rBITDIF, rBITDIF
+@@ -93,7 +141,7 @@
+ 	cmpd	cr1, rNEG, rBITDIF
+ 	sub	rRTN, rWORD1, rWORD2
+ 	blt-	cr1, L(equal)
+-	sradi	rRTN, rRTN, 63
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
+ 	ori	rRTN, rRTN, 1
+ 	blr
+ L(equal):
+@@ -110,12 +158,11 @@
+ 	ori	rRTN, rRTN, 1
+ 	blr
+ L(highbit):
+-	srdi	rWORD2, rWORD2, 56
+-	srdi	rWORD1, rWORD1, 56
+-	sub	rRTN, rWORD1, rWORD2
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
+ 	/* GKM FIXME: check high bounds.  */
+ 	blr
+-
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+ 	.align 4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strncmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strncmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strncmp.S	2014-05-28 13:26:59.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strncmp.S	2014-05-28 13:38:31.000000000 -0500
+@@ -27,7 +27,7 @@
+ EALIGN (BP_SYM(strncmp), 4, 0)
+ 	CALL_MCOUNT 3
+ 
+-#define rTMP	r0
++#define rTMP2	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -41,6 +41,7 @@
+ #define r7F7F	r9	/* constant 0x7f7f7f7f7f7f7f7f */
+ #define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
+ #define rBITDIF	r11	/* bits that differ in s1 & s2 words */
++#define rTMP	r12
+ 
+ 	dcbt	0,rSTR1
+ 	or	rTMP, rSTR2, rSTR1
+@@ -81,13 +82,60 @@
+ /* OK. We've hit the end of the string. We need to be careful that
+    we don't compare two strings as different because of gunk beyond
+    the end of the strings...  */
+-	
++
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	addi    rTMP2, rTMP, -1
++	beq	cr1, L(equal)
++	andc    rTMP2, rTMP2, rTMP
++	rldimi	rTMP2, rTMP2, 1, 0
++	and	rWORD2, rWORD2, rTMP2	/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	cmpd	cr1, rWORD1, rWORD2
++	beq	cr1, L(equal)
++	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
++	neg	rNEG, rBITDIF
++	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
++	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
++	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
++	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
++	sld	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
++	ori	rRTN, rRTN, 1
++	blr
++L(equal):
++	li	rRTN, 0
++	blr
++
++L(different):
++	ld	rWORD1, -8(rSTR1)
++	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
++	neg	rNEG, rBITDIF
++	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
++	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
++	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
++	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
++	sld	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63
++	ori	rRTN, rRTN, 1
++	blr
++L(highbit):
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
++	blr
++
++#else
+ L(endstring):
+ 	and	rTMP, r7F7F, rWORD1
+ 	beq	cr1, L(equal)
+ 	add	rTMP, rTMP, r7F7F
+ 	xor.	rBITDIF, rWORD1, rWORD2
+-
+ 	andc	rNEG, rNEG, rTMP
+ 	blt-	L(highbit)
+ 	cntlzd	rBITDIF, rBITDIF
+@@ -96,7 +144,7 @@
+ 	cmpd	cr1, rNEG, rBITDIF
+ 	sub	rRTN, rWORD1, rWORD2
+ 	blt-	cr1, L(equal)
+-	sradi	rRTN, rRTN, 63
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
+ 	ori	rRTN, rRTN, 1
+ 	blr
+ L(equal):
+@@ -104,7 +152,7 @@
+ 	blr
+ 
+ L(different):
+-	ldu	rWORD1, -8(rSTR1)
++	ld	rWORD1, -8(rSTR1)
+ 	xor.	rBITDIF, rWORD1, rWORD2
+ 	sub	rRTN, rWORD1, rWORD2
+ 	blt-	L(highbit)
+@@ -112,11 +160,10 @@
+ 	ori	rRTN, rRTN, 1
+ 	blr
+ L(highbit):
+-	srdi	rWORD2, rWORD2, 56
+-	srdi	rWORD1, rWORD1, 56
+-	sub	rRTN, rWORD1, rWORD2
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
+ 	blr
+-
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+ 	.align 4
diff --git a/SOURCES/glibc-ppc64le-28.patch b/SOURCES/glibc-ppc64le-28.patch
new file mode 100644
index 0000000..787c39a
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-28.patch
@@ -0,0 +1,167 @@
+# commit 43b84013714c46e6dcae4a5564c5527777ad5e08
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:45:31 2013 +0930
+# 
+#     PowerPC LE strcpy
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00100.html
+#     
+#     The strcpy changes for little-endian are quite straight-forward, just
+#     a matter of rotating the last word differently.
+#     
+#     I'll note that the powerpc64 version of stpcpy is just begging to be
+#     converted to use 64-bit loads and stores..
+#     
+#         * sysdeps/powerpc/powerpc64/strcpy.S: Add little-endian support:
+#         * sysdeps/powerpc/powerpc32/strcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/stpcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/stpcpy.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/stpcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/stpcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/stpcpy.S	2014-05-28 13:40:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/stpcpy.S	2014-05-28 13:40:01.000000000 -0500
+@@ -74,7 +74,22 @@
+ 
+ 	mr	rALT, rWORD
+ /* We've hit the end of the string.  Do the rest byte-by-byte.  */
+-L(g1):	rlwinm.	rTMP, rALT, 8, 24, 31
++L(g1):
++#ifdef __LITTLE_ENDIAN__
++	rlwinm.	rTMP, rALT, 0, 24, 31
++	stbu	rALT, 4(rDEST)
++	beqlr-
++	rlwinm.	rTMP, rALT, 24, 24, 31
++	stbu	rTMP, 1(rDEST)
++	beqlr-
++	rlwinm.	rTMP, rALT, 16, 24, 31
++	stbu	rTMP, 1(rDEST)
++	beqlr-
++	rlwinm	rTMP, rALT, 8, 24, 31
++	stbu	rTMP, 1(rDEST)
++	blr
++#else
++	rlwinm.	rTMP, rALT, 8, 24, 31
+ 	stbu	rTMP, 4(rDEST)
+ 	beqlr-
+ 	rlwinm.	rTMP, rALT, 16, 24, 31
+@@ -87,6 +102,7 @@
+ 	CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
+ 	STORE_RETURN_VALUE (rDEST)
+ 	blr
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte copy.  */
+ 	.align 4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strcpy.S	2014-05-28 13:40:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strcpy.S	2014-05-28 13:40:01.000000000 -0500
+@@ -78,7 +78,22 @@
+ 
+ 	mr	rALT, rWORD
+ /* We've hit the end of the string.  Do the rest byte-by-byte.  */
+-L(g1):	rlwinm.	rTMP, rALT, 8, 24, 31
++L(g1):
++#ifdef __LITTLE_ENDIAN__
++	rlwinm.	rTMP, rALT, 0, 24, 31
++	stb	rALT, 4(rDEST)
++	beqlr-
++	rlwinm.	rTMP, rALT, 24, 24, 31
++	stb	rTMP, 5(rDEST)
++	beqlr-
++	rlwinm.	rTMP, rALT, 16, 24, 31
++	stb	rTMP, 6(rDEST)
++	beqlr-
++	rlwinm	rTMP, rALT, 8, 24, 31
++	stb	rTMP, 7(rDEST)
++	blr
++#else
++	rlwinm.	rTMP, rALT, 8, 24, 31
+ 	stb	rTMP, 4(rDEST)
+ 	beqlr-
+ 	rlwinm.	rTMP, rALT, 16, 24, 31
+@@ -90,6 +105,7 @@
+ 	stb	rALT, 7(rDEST)
+ 	/* GKM FIXME: check high bound.  */
+ 	blr
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte copy.  */
+ 	.align 4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/stpcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/stpcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/stpcpy.S	2014-05-28 13:40:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/stpcpy.S	2014-05-28 13:40:01.000000000 -0500
+@@ -75,7 +75,22 @@
+ 
+ 	mr	rALT, rWORD
+ /* We've hit the end of the string.  Do the rest byte-by-byte.  */
+-L(g1):	rlwinm.	rTMP, rALT, 8, 24, 31
++L(g1):
++#ifdef __LITTLE_ENDIAN__
++	rlwinm.	rTMP, rALT, 0, 24, 31
++	stbu	rALT, 4(rDEST)
++	beqlr-
++	rlwinm.	rTMP, rALT, 24, 24, 31
++	stbu	rTMP, 1(rDEST)
++	beqlr-
++	rlwinm.	rTMP, rALT, 16, 24, 31
++	stbu	rTMP, 1(rDEST)
++	beqlr-
++	rlwinm	rTMP, rALT, 8, 24, 31
++	stbu	rTMP, 1(rDEST)
++	blr
++#else
++	rlwinm.	rTMP, rALT, 8, 24, 31
+ 	stbu	rTMP, 4(rDEST)
+ 	beqlr-
+ 	rlwinm.	rTMP, rALT, 16, 24, 31
+@@ -88,6 +103,7 @@
+ 	CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
+ 	STORE_RETURN_VALUE (rDEST)
+ 	blr
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte copy.  */
+ 	.align 4
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strcpy.S	2014-05-28 13:40:01.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strcpy.S	2014-05-28 13:40:01.000000000 -0500
+@@ -90,6 +90,32 @@
+ 	mr	rALT, rWORD
+ /* We've hit the end of the string.  Do the rest byte-by-byte.  */
+ L(g1):
++#ifdef __LITTLE_ENDIAN__
++	extrdi.	rTMP, rALT, 8, 56
++	stb	rALT, 8(rDEST)
++	beqlr-
++	extrdi.	rTMP, rALT, 8, 48
++	stb	rTMP, 9(rDEST)
++	beqlr-
++	extrdi.	rTMP, rALT, 8, 40
++	stb	rTMP, 10(rDEST)
++	beqlr-
++	extrdi.	rTMP, rALT, 8, 32
++	stb	rTMP, 11(rDEST)
++	beqlr-
++	extrdi.	rTMP, rALT, 8, 24
++	stb	rTMP, 12(rDEST)
++	beqlr-
++	extrdi.	rTMP, rALT, 8, 16
++	stb	rTMP, 13(rDEST)
++	beqlr-
++	extrdi.	rTMP, rALT, 8, 8
++	stb	rTMP, 14(rDEST)
++	beqlr-
++	extrdi	rTMP, rALT, 8, 0
++	stb	rTMP, 15(rDEST)
++	blr
++#else
+ 	extrdi.	rTMP, rALT, 8, 0
+ 	stb	rTMP, 8(rDEST)
+ 	beqlr-
+@@ -114,6 +140,7 @@
+ 	stb	rALT, 15(rDEST)
+ 	/* GKM FIXME: check high bound.  */
+ 	blr
++#endif
+ 
+ /* Oh well.  In this case, we just do a byte-by-byte copy.  */
+ 	.align 4
diff --git a/SOURCES/glibc-ppc64le-29.patch b/SOURCES/glibc-ppc64le-29.patch
new file mode 100644
index 0000000..2064770
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-29.patch
@@ -0,0 +1,636 @@
+# commit 664318c3eb07032e2bfcf47cb2aa3c89280c19e7
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:46:05 2013 +0930
+# 
+#     PowerPC LE strchr
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00101.html
+#     
+#     Adds little-endian support to optimised strchr assembly.  I've also
+#     tweaked the big-endian code a little.  In power7/strchr.S there's a
+#     check in the tail of the function that we didn't match 0 before
+#     finding a c match, done by comparing leading zero counts.  It's just
+#     as valid, and quicker, to compare the raw output from cmpb.
+#     
+#     Another little tweak is to use rldimi/insrdi in place of rlwimi for
+#     the power7 strchr functions.  Since rlwimi is cracked, it is a few
+#     cycles slower.  rldimi can be used on the 32-bit power7 functions
+#     too.
+#     
+#         * sysdeps/powerpc/powerpc64/power7/strchr.S (strchr): Add little-endian
+#         support.  Correct typos, formatting.  Optimize tail.  Use insrdi
+#         rather than rlwimi.
+#         * sysdeps/powerpc/powerpc32/power7/strchr.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power7/strchrnul.S (__strchrnul): Add
+#         little-endian support.  Correct typos.
+#         * sysdeps/powerpc/powerpc32/power7/strchrnul.S: Likewise.  Use insrdi
+#         rather than rlwimi.
+#         * sysdeps/powerpc/powerpc64/strchr.S (rTMP4, rTMP5): Define.  Use
+#         in loop and entry code to keep "and." results.
+#         (strchr): Add little-endian support.  Comment.  Move cntlzd
+#         earlier in tail.
+#         * sysdeps/powerpc/powerpc32/strchr.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strchr.S	2014-05-28 13:41:50.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strchr.S	2014-05-28 13:41:54.000000000 -0500
+@@ -37,8 +37,8 @@
+ 	beq	cr7,L(null_match)
+ 
+ 	/* Replicate byte to word.  */
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	insrdi	r4,r4,8,48
++	insrdi	r4,r4,16,32
+ 
+ 	/* Now r4 has a word of c bytes and r0 has
+ 	   a word of null bytes.  */
+@@ -48,11 +48,17 @@
+ 
+ 	/* Move the words left and right to discard the bits that are
+ 	   not part of the string and to bring them back as zeros.  */
+-
++#ifdef __LITTLE_ENDIAN__
++	srw	r10,r10,r6
++	srw	r11,r11,r6
++	slw	r10,r10,r6
++	slw	r11,r11,r6
++#else
+ 	slw	r10,r10,r6
+ 	slw	r11,r11,r6
+ 	srw	r10,r10,r6
+ 	srw	r11,r11,r6
++#endif
+ 	or	r5,r10,r11    /* OR the results to speed things up.  */
+ 	cmpwi	cr7,r5,0      /* If r5 == 0, no c or null bytes
+ 				 have been found.  */
+@@ -67,7 +73,7 @@
+ 
+ 	/* Handle WORD2 of pair.  */
+ 	lwzu	r12,4(r8)
+-	cmpb    r10,r12,r4
++	cmpb	r10,r12,r4
+ 	cmpb	r11,r12,r0
+ 	or	r5,r10,r11
+ 	cmpwi	cr7,r5,0
+@@ -102,22 +108,31 @@
+ 	bne	cr6,L(done)
+ 
+ 	/* The c/null byte must be in the second word.  Adjust the address
+-	   again and move the result of cmpb to r10 so we can calculate the
+-	   pointer.  */
++	   again and move the result of cmpb to r10/r11 so we can calculate
++	   the pointer.  */
+ 
+ 	mr	r10,r6
+ 	mr	r11,r7
+ 	addi	r8,r8,4
+ 
+-	/* r5 has the output of the cmpb instruction, that is, it contains
++	/* r10/r11 have the output of the cmpb instructions, that is,
+ 	   0xff in the same position as the c/null byte in the original
+ 	   word from the string.  Use that to calculate the pointer.  */
+ L(done):
+-	cntlzw	r4,r10	      /* Count leading zeroes before c matches.  */
+-	cntlzw	r0,r11	      /* Count leading zeroes before null matches.  */
+-	cmplw	cr7,r4,r0
++#ifdef __LITTLE_ENDIAN__
++	addi    r3,r10,-1
++	andc    r3,r3,r10
++	popcntw	r0,r3
++	addi    r4,r11,-1
++	andc    r4,r4,r11
++	cmplw	cr7,r3,r4
++	bgt	cr7,L(no_match)
++#else
++	cntlzw	r0,r10	      /* Count leading zeros before c matches.  */
++	cmplw	cr7,r11,r10
+ 	bgt	cr7,L(no_match)
+-	srwi	r0,r4,3	      /* Convert leading zeroes to bytes.  */
++#endif
++	srwi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r8,r0      /* Return address of the matching c byte
+ 				 or null in case c was not found.  */
+ 	blr
+@@ -135,10 +150,14 @@
+ 	cmpb	r5,r12,r0     /* Compare each byte against null bytes.  */
+ 
+ 	/* Move the words left and right to discard the bits that are
+-	   not part of the string and to bring them back as zeros.  */
+-
++	   not part of the string and bring them back as zeros.  */
++#ifdef __LITTLE_ENDIAN__
++	srw	r5,r5,r6
++	slw	r5,r5,r6
++#else
+ 	slw	r5,r5,r6
+ 	srw	r5,r5,r6
++#endif
+ 	cmpwi	cr7,r5,0      /* If r10 == 0, no c or null bytes
+ 				 have been found.  */
+ 	bne	cr7,L(done_null)
+@@ -193,7 +212,13 @@
+ 	   0xff in the same position as the null byte in the original
+ 	   word from the string.  Use that to calculate the pointer.  */
+ L(done_null):
++#ifdef __LITTLE_ENDIAN__
++	addi    r0,r5,-1
++	andc    r0,r0,r5
++	popcntw	r0,r0
++#else
+ 	cntlzw	r0,r5	      /* Count leading zeros before the match.  */
++#endif
+ 	srwi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r8,r0      /* Return address of the matching null byte.  */
+ 	blr
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strchrnul.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strchrnul.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strchrnul.S	2014-05-28 13:41:50.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/strchrnul.S	2014-05-28 13:41:54.000000000 -0500
+@@ -29,8 +29,8 @@
+ 	clrrwi	r8,r3,2	      /* Align the address to word boundary.  */
+ 
+ 	/* Replicate byte to word.  */
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	insrdi	r4,r4,8,48
++	insrdi	r4,r4,16,32
+ 
+ 	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
+ 	lwz	r12,0(r8)     /* Load word from memory.  */
+@@ -45,10 +45,17 @@
+ 
+ 	/* Move the words left and right to discard the bits that are
+ 	   not part of the string and bring them back as zeros.  */
++#ifdef __LITTLE_ENDIAN__
++	srw	r10,r10,r6
++	srw	r9,r9,r6
++	slw	r10,r10,r6
++	slw	r9,r9,r6
++#else
+ 	slw	r10,r10,r6
+ 	slw	r9,r9,r6
+ 	srw	r10,r10,r6
+ 	srw	r9,r9,r6
++#endif
+ 	or	r5,r9,r10     /* OR the results to speed things up.  */
+ 	cmpwi	cr7,r5,0      /* If r5 == 0, no c or null bytes
+ 				 have been found.  */
+@@ -56,7 +63,7 @@
+ 
+ 	mtcrf   0x01,r8
+ 
+-	/* Are we now aligned to a quadword boundary?  If so, skip to
++	/* Are we now aligned to a doubleword boundary?  If so, skip to
+ 	   the main loop.  Otherwise, go through the alignment code.  */
+ 
+ 	bt	29,L(loop)
+@@ -78,7 +85,7 @@
+ 	   single register for speed.  This is an attempt
+ 	   to speed up the null-checking process for bigger strings.  */
+ 	lwz	r12,4(r8)
+-	lwzu     r11,8(r8)
++	lwzu	r11,8(r8)
+ 	cmpb	r10,r12,r0
+ 	cmpb	r9,r12,r4
+ 	cmpb	r6,r11,r0
+@@ -97,9 +104,9 @@
+ 	addi	r8,r8,-4
+ 	bne	cr6,L(done)
+ 
+-	/* The c/null byte must be in the second word.  Adjust the
+-	   address again and move the result of cmpb to r10 so we can calculate
+-	   the pointer.  */
++	/* The c/null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to r5 so we can calculate the
++	   pointer.  */
+ 	mr	r5,r10
+ 	addi	r8,r8,4
+ 
+@@ -107,7 +114,13 @@
+ 	   0xff in the same position as the c/null byte in the original
+ 	   word from the string.  Use that to calculate the pointer.  */
+ L(done):
++#ifdef __LITTLE_ENDIAN__
++	addi    r0,r5,-1
++	andc    r0,r0,r5
++	popcntw	r0,r0
++#else
+ 	cntlzw	r0,r5	      /* Count leading zeros before the match.  */
++#endif
+ 	srwi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r8,r0      /* Return address of matching c/null byte.  */
+ 	blr
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/strchr.S	2014-05-28 13:41:50.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/strchr.S	2014-05-28 13:57:31.000000000 -0500
+@@ -44,6 +44,8 @@
+ #define rIGN	r10	/* number of bits we should ignore in the first word */
+ #define rMASK	r11	/* mask with the bits to ignore set to 0 */
+ #define rTMP3	r12
++#define rTMP4	rIGN
++#define rTMP5	rMASK
+ 
+ 	CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2)
+ 	STORE_RETURN_BOUNDS (rTMP1, rTMP2)
+@@ -59,53 +61,74 @@
+ 	addi	r7F7F, r7F7F, 0x7f7f
+ /* Test the first (partial?) word.  */
+ 	lwz	rWORD, 0(rSTR)
++#ifdef __LITTLE_ENDIAN__
++	slw	rMASK, rMASK, rIGN
++#else
+ 	srw	rMASK, rMASK, rIGN
++#endif
+ 	orc	rWORD, rWORD, rMASK
+ 	add	rTMP1, rFEFE, rWORD
+ 	nor	rTMP2, r7F7F, rWORD
+-	and.	rTMP1, rTMP1, rTMP2
++	and.	rTMP4, rTMP1, rTMP2
+ 	xor	rTMP3, rCHR, rWORD
+ 	orc	rTMP3, rTMP3, rMASK
+ 	b	L(loopentry)
+ 
+ /* The loop.  */
+ 
+-L(loop):lwzu rWORD, 4(rSTR)
+-	and.	rTMP1, rTMP1, rTMP2
++L(loop):
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP5, rTMP1, rTMP2
+ /* Test for 0.	*/
+-	add	rTMP1, rFEFE, rWORD
+-	nor	rTMP2, r7F7F, rWORD
++	add	rTMP1, rFEFE, rWORD /* x - 0x01010101.  */
++	nor	rTMP2, r7F7F, rWORD /* ~(x | 0x7f7f7f7f) == ~x & 0x80808080.  */
+ 	bne	L(foundit)
+-	and.	rTMP1, rTMP1, rTMP2
++	and.	rTMP4, rTMP1, rTMP2 /* (x - 0x01010101) & ~x & 0x80808080.  */
+ /* Start test for the bytes we're looking for.  */
+ 	xor	rTMP3, rCHR, rWORD
+ L(loopentry):
+ 	add	rTMP1, rFEFE, rTMP3
+ 	nor	rTMP2, r7F7F, rTMP3
+ 	beq	L(loop)
++
+ /* There is a zero byte in the word, but may also be a matching byte (either
+    before or after the zero byte).  In fact, we may be looking for a
+-   zero byte, in which case we return a match.  We guess that this hasn't
+-   happened, though.  */
+-L(missed):
+-	and.	rTMP1, rTMP1, rTMP2
++   zero byte, in which case we return a match.  */
++	and.	rTMP5, rTMP1, rTMP2
+ 	li	rRTN, 0
+ 	STORE_RETURN_VALUE (rSTR)
+ 	beqlr
+-/* It did happen. Decide which one was first...
+-   I'm not sure if this is actually faster than a sequence of
+-   rotates, compares, and branches (we use it anyway because it's shorter).  */
++/* At this point:
++   rTMP5 bytes are 0x80 for each match of c, 0 otherwise.
++   rTMP4 bytes are 0x80 for each match of 0, 0 otherwise.
++   But there may be false matches in the next most significant byte from
++   a true match due to carries.  This means we need to recalculate the
++   matches using a longer method for big-endian.  */
++#ifdef __LITTLE_ENDIAN__
++	addi	rTMP1, rTMP5, -1
++	andc	rTMP1, rTMP1, rTMP5
++	cntlzw	rCLZB, rTMP1
++	addi	rTMP2, rTMP4, -1
++	andc	rTMP2, rTMP2, rTMP4
++	cmplw	rTMP1, rTMP2
++	bgtlr
++	subfic	rCLZB, rCLZB, 32-7
++#else
++/* I think we could reduce this by two instructions by keeping the "nor"
++   results from the loop for reuse here.  See strlen.S tail.  Similarly
++   one instruction could be pruned from L(foundit).  */
+ 	and	rFEFE, r7F7F, rWORD
+-	or	rMASK, r7F7F, rWORD
++	or	rTMP5, r7F7F, rWORD
+ 	and	rTMP1, r7F7F, rTMP3
+-	or	rIGN, r7F7F, rTMP3
++	or	rTMP4, r7F7F, rTMP3
+ 	add	rFEFE, rFEFE, r7F7F
+ 	add	rTMP1, rTMP1, r7F7F
+-	nor	rWORD, rMASK, rFEFE
+-	nor	rTMP2, rIGN, rTMP1
++	nor	rWORD, rTMP5, rFEFE
++	nor	rTMP2, rTMP4, rTMP1
++	cntlzw	rCLZB, rTMP2
+ 	cmplw	rWORD, rTMP2
+ 	bgtlr
+-	cntlzw	rCLZB, rTMP2
++#endif
+ 	srwi	rCLZB, rCLZB, 3
+ 	add	rRTN, rSTR, rCLZB
+ 	CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge)
+@@ -113,13 +136,21 @@
+ 	blr
+ 
+ L(foundit):
++#ifdef __LITTLE_ENDIAN__
++	addi	rTMP1, rTMP5, -1
++	andc	rTMP1, rTMP1, rTMP5
++	cntlzw	rCLZB, rTMP1
++	subfic	rCLZB, rCLZB, 32-7-32
++	srawi	rCLZB, rCLZB, 3
++#else
+ 	and	rTMP1, r7F7F, rTMP3
+-	or	rIGN, r7F7F, rTMP3
++	or	rTMP4, r7F7F, rTMP3
+ 	add	rTMP1, rTMP1, r7F7F
+-	nor	rTMP2, rIGN, rTMP1
++	nor	rTMP2, rTMP4, rTMP1
+ 	cntlzw	rCLZB, rTMP2
+ 	subi	rSTR, rSTR, 4
+ 	srwi	rCLZB, rCLZB, 3
++#endif
+ 	add	rRTN, rSTR, rCLZB
+ 	CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge)
+ 	STORE_RETURN_VALUE (rSTR)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strchr.S	2014-05-28 13:41:50.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strchr.S	2014-05-28 13:41:54.000000000 -0500
+@@ -37,8 +37,8 @@
+ 	beq	cr7,L(null_match)
+ 
+ 	/* Replicate byte to doubleword.  */
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	insrdi	r4,r4,8,48
++	insrdi	r4,r4,16,32
+ 	insrdi  r4,r4,32,0
+ 
+ 	/* Now r4 has a doubleword of c bytes and r0 has
+@@ -49,11 +49,17 @@
+ 
+ 	/* Move the doublewords left and right to discard the bits that are
+ 	   not part of the string and bring them back as zeros.  */
+-
++#ifdef __LITTLE_ENDIAN__
++	srd	r10,r10,r6
++	srd	r11,r11,r6
++	sld	r10,r10,r6
++	sld	r11,r11,r6
++#else
+ 	sld	r10,r10,r6
+ 	sld	r11,r11,r6
+ 	srd	r10,r10,r6
+ 	srd	r11,r11,r6
++#endif
+ 	or	r5,r10,r11    /* OR the results to speed things up.  */
+ 	cmpdi	cr7,r5,0      /* If r5 == 0, no c or null bytes
+ 				 have been found.  */
+@@ -110,15 +116,24 @@
+ 	mr	r11,r7
+ 	addi	r8,r8,8
+ 
+-	/* r5 has the output of the cmpb instruction, that is, it contains
++	/* r10/r11 have the output of the cmpb instructions, that is,
+ 	   0xff in the same position as the c/null byte in the original
+ 	   doubleword from the string.  Use that to calculate the pointer.  */
+ L(done):
+-	cntlzd	r4,r10	      /* Count leading zeroes before c matches.  */
+-	cntlzd	r0,r11	      /* Count leading zeroes before null matches.  */
+-	cmpld	cr7,r4,r0
++#ifdef __LITTLE_ENDIAN__
++	addi    r3,r10,-1
++	andc    r3,r3,r10
++	popcntd	r0,r3
++	addi    r4,r11,-1
++	andc    r4,r4,r11
++	cmpld	cr7,r3,r4
+ 	bgt	cr7,L(no_match)
+-	srdi	r0,r4,3	      /* Convert leading zeroes to bytes.  */
++#else
++	cntlzd	r0,r10	      /* Count leading zeros before c matches.  */
++	cmpld	cr7,r11,r10
++	bgt	cr7,L(no_match)
++#endif
++	srdi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r8,r0      /* Return address of the matching c byte
+ 				 or null in case c was not found.  */
+ 	blr
+@@ -137,9 +152,13 @@
+ 
+ 	/* Move the doublewords left and right to discard the bits that are
+ 	   not part of the string and bring them back as zeros.  */
+-
++#ifdef __LITTLE_ENDIAN__
++	srd	r5,r5,r6
++	sld	r5,r5,r6
++#else
+ 	sld	r5,r5,r6
+ 	srd	r5,r5,r6
++#endif
+ 	cmpdi	cr7,r5,0      /* If r10 == 0, no c or null bytes
+ 				 have been found.  */
+ 	bne	cr7,L(done_null)
+@@ -194,7 +213,13 @@
+ 	   0xff in the same position as the null byte in the original
+ 	   doubleword from the string.  Use that to calculate the pointer.  */
+ L(done_null):
++#ifdef __LITTLE_ENDIAN__
++	addi    r0,r5,-1
++	andc    r0,r0,r5
++	popcntd	r0,r0
++#else
+ 	cntlzd	r0,r5	      /* Count leading zeros before the match.  */
++#endif
+ 	srdi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r8,r0      /* Return address of the matching null byte.  */
+ 	blr
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strchrnul.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strchrnul.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/strchrnul.S	2014-05-28 13:41:50.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/strchrnul.S	2014-05-28 13:41:54.000000000 -0500
+@@ -29,8 +29,8 @@
+ 	clrrdi	r8,r3,3	      /* Align the address to doubleword boundary.  */
+ 
+ 	/* Replicate byte to doubleword.  */
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	insrdi	r4,r4,8,48
++	insrdi	r4,r4,16,32
+ 	insrdi	r4,r4,32,0
+ 
+ 	rlwinm	r6,r3,3,26,28 /* Calculate padding.  */
+@@ -46,10 +46,17 @@
+ 
+ 	/* Move the doublewords left and right to discard the bits that are
+ 	   not part of the string and to bring them back as zeros.  */
++#ifdef __LITTLE_ENDIAN__
++	srd	r10,r10,r6
++	srd	r9,r9,r6
++	sld	r10,r10,r6
++	sld	r9,r9,r6
++#else
+ 	sld	r10,r10,r6
+ 	sld	r9,r9,r6
+ 	srd	r10,r10,r6
+ 	srd	r9,r9,r6
++#endif
+ 	or	r5,r9,r10     /* OR the results to speed things up.  */
+ 	cmpdi	cr7,r5,0      /* If r5 == 0, no c or null bytes
+ 				 have been found.  */
+@@ -99,7 +106,7 @@
+ 	bne	cr6,L(done)
+ 
+ 	/* The c/null byte must be in the second doubleword.  Adjust the
+-	   address again and move the result of cmpb to r10 so we can calculate
++	   address again and move the result of cmpb to r5 so we can calculate
+ 	   the pointer.  */
+ 	mr	r5,r10
+ 	addi	r8,r8,8
+@@ -108,7 +115,13 @@
+ 	   0xff in the same position as the c/null byte in the original
+ 	   doubleword from the string.  Use that to calculate the pointer.  */
+ L(done):
++#ifdef __LITTLE_ENDIAN__
++	addi    r0,r5,-1
++	andc    r0,r0,r5
++	popcntd	r0,r0
++#else
+ 	cntlzd	r0,r5	      /* Count leading zeros before the match.  */
++#endif
+ 	srdi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r8,r0      /* Return address of matching c/null byte.  */
+ 	blr
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/strchr.S	2014-05-28 13:41:50.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/strchr.S	2014-05-28 14:04:47.000000000 -0500
+@@ -50,14 +50,16 @@
+ #define rIGN	r10	/* number of bits we should ignore in the first word */
+ #define rMASK	r11	/* mask with the bits to ignore set to 0 */
+ #define rTMP3	r12
++#define rTMP4	rIGN
++#define rTMP5	rMASK
+ 
+ 	CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2)
+ 	STORE_RETURN_BOUNDS (rTMP1, rTMP2)
+ 
+ 	dcbt	0,rRTN
+-	rlwimi	rCHR, rCHR, 8, 16, 23
++	insrdi	rCHR, rCHR, 8, 48
+ 	li	rMASK, -1
+-	rlwimi	rCHR, rCHR, 16, 0, 15
++	insrdi	rCHR, rCHR, 16, 32
+ 	rlwinm	rIGN, rRTN, 3, 26, 28
+ 	insrdi	rCHR, rCHR, 32, 0
+ 	lis	rFEFE, -0x101
+@@ -70,53 +72,74 @@
+ 	add	rFEFE, rFEFE, rTMP1
+ /* Test the first (partial?) word.  */
+ 	ld	rWORD, 0(rSTR)
++#ifdef __LITTLE_ENDIAN__
++	sld	rMASK, rMASK, rIGN
++#else
+ 	srd	rMASK, rMASK, rIGN
++#endif
+ 	orc	rWORD, rWORD, rMASK
+ 	add	rTMP1, rFEFE, rWORD
+ 	nor	rTMP2, r7F7F, rWORD
+-	and.	rTMP1, rTMP1, rTMP2
++	and.	rTMP4, rTMP1, rTMP2
+ 	xor	rTMP3, rCHR, rWORD
+ 	orc	rTMP3, rTMP3, rMASK
+ 	b	L(loopentry)
+ 
+ /* The loop.  */
+ 
+-L(loop):ldu rWORD, 8(rSTR)
+-	and.	rTMP1, rTMP1, rTMP2
++L(loop):
++	ldu	rWORD, 8(rSTR)
++	and.	rTMP5, rTMP1, rTMP2
+ /* Test for 0.	*/
+-	add	rTMP1, rFEFE, rWORD
+-	nor	rTMP2, r7F7F, rWORD
++	add	rTMP1, rFEFE, rWORD /* x - 0x01010101.  */
++	nor	rTMP2, r7F7F, rWORD /* ~(x | 0x7f7f7f7f) == ~x & 0x80808080.  */
+ 	bne	L(foundit)
+-	and.	rTMP1, rTMP1, rTMP2
++	and.	rTMP4, rTMP1, rTMP2 /* (x - 0x01010101) & ~x & 0x80808080.  */
+ /* Start test for the bytes we're looking for.  */
+ 	xor	rTMP3, rCHR, rWORD
+ L(loopentry):
+ 	add	rTMP1, rFEFE, rTMP3
+ 	nor	rTMP2, r7F7F, rTMP3
+ 	beq	L(loop)
++
+ /* There is a zero byte in the word, but may also be a matching byte (either
+    before or after the zero byte).  In fact, we may be looking for a
+-   zero byte, in which case we return a match.  We guess that this hasn't
+-   happened, though.  */
+-L(missed):
+-	and.	rTMP1, rTMP1, rTMP2
++   zero byte, in which case we return a match.  */
++	and.	rTMP5, rTMP1, rTMP2
+ 	li	rRTN, 0
+ 	STORE_RETURN_VALUE (rSTR)
+ 	beqlr
+-/* It did happen. Decide which one was first...
+-   I'm not sure if this is actually faster than a sequence of
+-   rotates, compares, and branches (we use it anyway because it's shorter).  */
++/* At this point:
++   rTMP5 bytes are 0x80 for each match of c, 0 otherwise.
++   rTMP4 bytes are 0x80 for each match of 0, 0 otherwise.
++   But there may be false matches in the next most significant byte from
++   a true match due to carries.  This means we need to recalculate the
++   matches using a longer method for big-endian.  */
++#ifdef __LITTLE_ENDIAN__
++	addi	rTMP1, rTMP5, -1
++	andc	rTMP1, rTMP1, rTMP5
++	cntlzd	rCLZB, rTMP1
++	addi	rTMP2, rTMP4, -1
++	andc	rTMP2, rTMP2, rTMP4
++	cmpld	rTMP1, rTMP2
++	bgtlr
++	subfic	rCLZB, rCLZB, 64-7
++#else
++/* I think we could reduce this by two instructions by keeping the "nor"
++   results from the loop for reuse here.  See strlen.S tail.  Similarly
++   one instruction could be pruned from L(foundit).  */
+ 	and	rFEFE, r7F7F, rWORD
+-	or	rMASK, r7F7F, rWORD
++	or	rTMP5, r7F7F, rWORD
+ 	and	rTMP1, r7F7F, rTMP3
+-	or	rIGN, r7F7F, rTMP3
++	or	rTMP4, r7F7F, rTMP3
+ 	add	rFEFE, rFEFE, r7F7F
+ 	add	rTMP1, rTMP1, r7F7F
+-	nor	rWORD, rMASK, rFEFE
+-	nor	rTMP2, rIGN, rTMP1
++	nor	rWORD, rTMP5, rFEFE
++	nor	rTMP2, rTMP4, rTMP1
++	cntlzd	rCLZB, rTMP2
+ 	cmpld	rWORD, rTMP2
+ 	bgtlr
+-	cntlzd	rCLZB, rTMP2
++#endif
+ 	srdi	rCLZB, rCLZB, 3
+ 	add	rRTN, rSTR, rCLZB
+ 	CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, tdlge)
+@@ -124,13 +147,21 @@
+ 	blr
+ 
+ L(foundit):
++#ifdef __LITTLE_ENDIAN__
++	addi	rTMP1, rTMP5, -1
++	andc	rTMP1, rTMP1, rTMP5
++	cntlzd	rCLZB, rTMP1
++	subfic	rCLZB, rCLZB, 64-7-64
++	sradi	rCLZB, rCLZB, 3
++#else
+ 	and	rTMP1, r7F7F, rTMP3
+-	or	rIGN, r7F7F, rTMP3
++	or	rTMP4, r7F7F, rTMP3
+ 	add	rTMP1, rTMP1, r7F7F
+-	nor	rTMP2, rIGN, rTMP1
++	nor	rTMP2, rTMP4, rTMP1
+ 	cntlzd	rCLZB, rTMP2
+ 	subi	rSTR, rSTR, 8
+ 	srdi	rCLZB, rCLZB, 3
++#endif
+ 	add	rRTN, rSTR, rCLZB
+ 	CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, tdlge)
+ 	STORE_RETURN_VALUE (rSTR)
diff --git a/SOURCES/glibc-ppc64le-30.patch b/SOURCES/glibc-ppc64le-30.patch
new file mode 100644
index 0000000..5ef4766
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-30.patch
@@ -0,0 +1,7383 @@
+# commit fe6e95d7171eba5f3e07848f081676fae4e86322
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:46:47 2013 +0930
+# 
+#     PowerPC LE memcmp
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00102.html
+#     
+#     This is a rather large patch due to formatting and renaming.  The
+#     formatting changes were to make it possible to compare power7 and
+#     power4 versions of memcmp.  Using different register defines came
+#     about while I was wrestling with the code, trying to find spare
+#     registers at one stage.  I found it much simpler if we refer to a reg
+#     by the same name throughout a function, so it's better if short-term
+#     multiple use regs like rTMP are referred to using their register
+#     number.  I made the cr field usage changes when attempting to reload
+#     rWORDn regs in the exit path to byte swap before comparing when
+#     little-endian.  That proved a bad idea due to the pipelining involved
+#     in the main loop;  Offsets to reload the regs were different first
+#     time around the loop..  Anyway, I left the cr field usage changes in
+#     place for consistency.
+#     
+#     Aside from these more-or-less cosmetic changes, I fixed a number of
+#     places where an early exit path restores regs unnecessarily, removed
+#     some dead code, and optimised one or two exits.
+#     
+#         * sysdeps/powerpc/powerpc64/power7/memcmp.S: Add little-endian support.
+#         Formatting.  Consistently use rXXX register defines or rN defines.
+#         Use early exit labels that avoid restoring unused non-volatile regs.
+#         Make cr field use more consistent with rWORDn compares.  Rename
+#         regs used as shift registers for unaligned loop, using rN defines
+#         for short lifetime/multiple use regs.
+#         * sysdeps/powerpc/powerpc64/power4/memcmp.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/memcmp.S: Likewise.  Exit with
+#         addi 1,1,64 to pop stack frame.  Simplify return value code.
+#         * sysdeps/powerpc/powerpc32/power4/memcmp.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/memcmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/memcmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/memcmp.S	2014-05-28 19:22:37.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/memcmp.S	2014-05-28 23:55:52.000000000 -0500
+@@ -1,4 +1,4 @@
+-/* Optimized strcmp implementation for PowerPC64.
++/* Optimized strcmp implementation for PowerPC32.
+    Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -20,13 +20,14 @@
+ #include <bp-sym.h>
+ #include <bp-asm.h>
+ 
+-/* int [r3] memcmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
+-
++/* int [r3] memcmp (const char *s1 [r3],
++		    const char *s2 [r4],
++		    size_t size [r5])  */
++ 
+ 	.machine power4
+ EALIGN (BP_SYM(memcmp), 4, 0)
+ 	CALL_MCOUNT
+ 
+-#define rTMP	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -37,33 +38,32 @@
+ #define rWORD4	r9	/* next word in s2 */
+ #define rWORD5	r10	/* next word in s1 */
+ #define rWORD6	r11	/* next word in s2 */
+-#define rBITDIF	r12	/* bits that differ in s1 & s2 words */
+ #define rWORD7	r30	/* next word in s1 */
+ #define rWORD8	r31	/* next word in s2 */
+ 
+-	xor	rTMP, rSTR2, rSTR1
++	xor	r0, rSTR2, rSTR1
+ 	cmplwi	cr6, rN, 0
+ 	cmplwi	cr1, rN, 12
+-	clrlwi.	rTMP, rTMP, 30
+-	clrlwi	rBITDIF, rSTR1, 30
+-	cmplwi	cr5, rBITDIF, 0
++	clrlwi.	r0, r0, 30
++	clrlwi	r12, rSTR1, 30
++	cmplwi	cr5, r12, 0
+ 	beq-	cr6, L(zeroLength)
+-	dcbt	0,rSTR1
+-	dcbt	0,rSTR2
++	dcbt	0, rSTR1
++	dcbt	0, rSTR2
+ /* If less than 8 bytes or not aligned, use the unaligned
+    byte loop.  */
+ 	blt	cr1, L(bytealigned)
+-        stwu    1,-64(1)
++	stwu	1, -64(r1)
+ 	cfi_adjust_cfa_offset(64)
+-        stw     r31,48(1)	
+-	cfi_offset(31,(48-64))
+-        stw     r30,44(1)	
+-	cfi_offset(30,(44-64))
++	stw	rWORD8, 48(r1)
++	cfi_offset(rWORD8, (48-64))
++	stw	rWORD7, 44(r1)
++	cfi_offset(rWORD7, (44-64))
+ 	bne	L(unaligned)
+ /* At this point we know both strings have the same alignment and the
+-   compare length is at least 8 bytes.  rBITDIF contains the low order
++   compare length is at least 8 bytes.  r12 contains the low order
+    2 bits of rSTR1 and cr5 contains the result of the logical compare
+-   of rBITDIF to 0.  If rBITDIF == 0 then we are already word 
++   of r12 to 0.  If r12 == 0 then we are already word
+    aligned and can perform the word aligned loop.
+   
+    Otherwise we know the two strings have the same alignment (but not
+@@ -72,74 +72,95 @@
+    eliminate bits preceeding the first byte.  Since we want to join the
+    normal (word aligned) compare loop, starting at the second word,
+    we need to adjust the length (rN) and special case the loop
+-   versioning for the first word. This insures that the loop count is
++   versioning for the first word. This ensures that the loop count is
+    correct and the first word (shifted) is in the expected register pair. */
+-	.align 4
++	.align	4
+ L(samealignment):
+ 	clrrwi	rSTR1, rSTR1, 2
+ 	clrrwi	rSTR2, rSTR2, 2
+ 	beq	cr5, L(Waligned)
+-	add	rN, rN, rBITDIF
+-	slwi	r11, rBITDIF, 3
+-	srwi	rTMP, rN, 4	 /* Divide by 16 */
+-	andi.	rBITDIF, rN, 12  /* Get the word remainder */
++	add	rN, rN, r12
++	slwi	rWORD6, r12, 3
++	srwi	r0, rN, 4	/* Divide by 16 */
++	andi.	r12, rN, 12	/* Get the word remainder */
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 0(rSTR1)
+ 	lwz	rWORD2, 0(rSTR2)
+-	cmplwi	cr1, rBITDIF, 8
++#endif
++	cmplwi	cr1, r12, 8
+ 	cmplwi	cr7, rN, 16
+ 	clrlwi	rN, rN, 30
+ 	beq	L(dPs4)
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
+ 	bgt	cr1, L(dPs3)
+ 	beq	cr1, L(dPs2)
+ 
+ /* Remainder is 4 */
+-	.align 3
++	.align	3
+ L(dsP1):
+-	slw	rWORD5, rWORD1, r11
+-	slw	rWORD6, rWORD2, r11
++	slw	rWORD5, rWORD1, rWORD6
++	slw	rWORD6, rWORD2, rWORD6
+ 	cmplw	cr5, rWORD5, rWORD6
+ 	blt	cr7, L(dP1x)
+ /* Do something useful in this cycle since we have to branch anyway.  */
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 4(rSTR1)
+ 	lwz	rWORD2, 4(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ 	b	L(dP1e)
+ /* Remainder is 8 */
+-	.align 4
++	.align	4
+ L(dPs2):
+-	slw	rWORD5, rWORD1, r11
+-	slw	rWORD6, rWORD2, r11
++	slw	rWORD5, rWORD1, rWORD6
++	slw	rWORD6, rWORD2, rWORD6
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	blt	cr7, L(dP2x)
+ /* Do something useful in this cycle since we have to branch anyway.  */
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD7, 4(rSTR1)
+ 	lwz	rWORD8, 4(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+ 	b	L(dP2e)
+ /* Remainder is 12 */
+-	.align 4
++	.align	4
+ L(dPs3):
+-	slw	rWORD3, rWORD1, r11
+-	slw	rWORD4, rWORD2, r11
++	slw	rWORD3, rWORD1, rWORD6
++	slw	rWORD4, rWORD2, rWORD6
+ 	cmplw	cr1, rWORD3, rWORD4
+ 	b	L(dP3e)
+ /* Count is a multiple of 16, remainder is 0 */
+-	.align 4
++	.align	4
+ L(dPs4):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+-	slw	rWORD1, rWORD1, r11
+-	slw	rWORD2, rWORD2, r11
+-	cmplw	cr0, rWORD1, rWORD2
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++	slw	rWORD1, rWORD1, rWORD6
++	slw	rWORD2, rWORD2, rWORD6
++	cmplw	cr7, rWORD1, rWORD2
+ 	b	L(dP4e)
+ 
+ /* At this point we know both strings are word aligned and the
+    compare length is at least 8 bytes.  */
+-	.align 4
++	.align	4
+ L(Waligned):
+-	andi.	rBITDIF, rN, 12  /* Get the word remainder */
+-	srwi	rTMP, rN, 4	 /* Divide by 16 */
+-	cmplwi	cr1, rBITDIF, 8
++	andi.	r12, rN, 12	/* Get the word remainder */
++	srwi	r0, rN, 4	/* Divide by 16 */
++	cmplwi	cr1, r12, 8
+ 	cmplwi	cr7, rN, 16
+ 	clrlwi	rN, rN, 30
+ 	beq	L(dP4)
+@@ -147,177 +168,352 @@
+ 	beq	cr1, L(dP2)
+ 		
+ /* Remainder is 4 */
+-	.align 4
++	.align	4
+ L(dP1):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
+ /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early
+    (8-15 byte compare), we want to use only volatile registers.  This
+    means we can avoid restoring non-volatile registers since we did not
+    change any on the early exit path.  The key here is the non-early
+    exit path only cares about the condition code (cr5), not about which 
+    register pair was used.  */
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 0(rSTR1)
+ 	lwz	rWORD6, 0(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD5, rWORD6
+ 	blt	cr7, L(dP1x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 4(rSTR1)
+ 	lwz	rWORD2, 4(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ L(dP1e):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 8(rSTR1)
+ 	lwz	rWORD4, 8(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 12(rSTR1)
+ 	lwz	rWORD6, 12(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
+-	bne	cr5, L(dLcr5)
+-	bne	cr0, L(dLcr0)
+-	
++	bne	cr5, L(dLcr5x)
++	bne	cr7, L(dLcr7x)
++
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwzu	rWORD7, 16(rSTR1)
+ 	lwzu	rWORD8, 16(rSTR2)
++#endif
+ 	bne	cr1, L(dLcr1)
+ 	cmplw	cr5, rWORD7, rWORD8
+ 	bdnz	L(dLoop)
+ 	bne	cr6, L(dLcr6)
+-        lwz     r30,44(1)
+-        lwz     r31,48(1)
+-	.align 3
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++	.align	3
+ L(dP1x):
+ 	slwi.	r12, rN, 3
+-	bne	cr5, L(dLcr5)
++	bne	cr5, L(dLcr5x)
+ 	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+-        lwz     1,0(1)
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bne	L(d00)
+ 	li	rRTN, 0
+ 	blr
+ 		
+ /* Remainder is 8 */
+-	.align 4
++	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dP2):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 0(rSTR1)
+ 	lwz	rWORD6, 0(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	blt	cr7, L(dP2x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD7, 4(rSTR1)
+ 	lwz	rWORD8, 4(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+ L(dP2e):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 8(rSTR1)
+ 	lwz	rWORD2, 8(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 12(rSTR1)
+ 	lwz	rWORD4, 12(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 4
+ 	addi	rSTR2, rSTR2, 4
++#endif
+ 	bne	cr6, L(dLcr6)
+ 	bne	cr5, L(dLcr5)
+ 	b	L(dLoop2)
+ /* Again we are on a early exit path (16-23 byte compare), we want to
+    only use volatile registers and avoid restoring non-volatile
+    registers.  */
+-	.align 4
++	.align	4
+ L(dP2x):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 4(rSTR1)
+ 	lwz	rWORD4, 4(rSTR2)
+-	cmplw	cr5, rWORD3, rWORD4
++#endif
++	cmplw	cr1, rWORD3, rWORD4
+ 	slwi.	r12, rN, 3
+-	bne	cr6, L(dLcr6)
++	bne	cr6, L(dLcr6x)
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 4
+ 	addi	rSTR2, rSTR2, 4
+-	bne	cr5, L(dLcr5)
++#endif
++	bne	cr1, L(dLcr1x)
+ 	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+-        lwz     1,0(1)
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bne	L(d00)
+ 	li	rRTN, 0
+ 	blr
+ 		
+ /* Remainder is 12 */
+-	.align 4
++	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dP3):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 0(rSTR1)
+ 	lwz	rWORD4, 0(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
+ L(dP3e):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 4(rSTR1)
+ 	lwz	rWORD6, 4(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	blt	cr7, L(dP3x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD7, 8(rSTR1)
+ 	lwz	rWORD8, 8(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 12(rSTR1)
+ 	lwz	rWORD2, 12(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 8
+ 	addi	rSTR2, rSTR2, 8
++#endif
+ 	bne	cr1, L(dLcr1)
+ 	bne	cr6, L(dLcr6)
+ 	b	L(dLoop1)
+ /* Again we are on a early exit path (24-31 byte compare), we want to
+    only use volatile registers and avoid restoring non-volatile
+    registers.  */
+-	.align 4
++	.align	4
+ L(dP3x):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 8(rSTR1)
+ 	lwz	rWORD2, 8(rSTR2)
+-	cmplw	cr5, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ 	slwi.	r12, rN, 3
+-	bne	cr1, L(dLcr1)
++	bne	cr1, L(dLcr1x)
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 8
+ 	addi	rSTR2, rSTR2, 8
+-	bne	cr6, L(dLcr6)
++#endif
++	bne	cr6, L(dLcr6x)
+ 	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+-	bne	cr5, L(dLcr5)
+-        lwz     1,0(1)
++	bne	cr7, L(dLcr7x)
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bne	L(d00)
+ 	li	rRTN, 0
+ 	blr
+ 	
+ /* Count is a multiple of 16, remainder is 0 */
+-	.align 4
++	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dP4):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 0(rSTR1)
+ 	lwz	rWORD2, 0(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ L(dP4e):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 4(rSTR1)
+ 	lwz	rWORD4, 4(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 8(rSTR1)
+ 	lwz	rWORD6, 8(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwzu	rWORD7, 12(rSTR1)
+ 	lwzu	rWORD8, 12(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+-	bne	cr0, L(dLcr0)
++	bne	cr7, L(dLcr7)
+ 	bne	cr1, L(dLcr1)
+ 	bdz-	L(d24)		/* Adjust CTR as we start with +4 */
+ /* This is the primary loop */
+-	.align 4
++	.align	4
+ L(dLoop):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 4(rSTR1)
+ 	lwz	rWORD2, 4(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
+ 	bne	cr6, L(dLcr6)
+ L(dLoop1):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 8(rSTR1)
+ 	lwz	rWORD4, 8(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	bne	cr5, L(dLcr5)
+ L(dLoop2):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 12(rSTR1)
+ 	lwz	rWORD6, 12(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+-	bne	cr0, L(dLcr0)
++	bne	cr7, L(dLcr7)
+ L(dLoop3):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwzu	rWORD7, 16(rSTR1)
+ 	lwzu	rWORD8, 16(rSTR2)
++#endif
+ 	bne-	cr1, L(dLcr1)
+-	cmplw	cr0, rWORD1, rWORD2
++	cmplw	cr7, rWORD1, rWORD2
+ 	bdnz+	L(dLoop)	
+ 	
+ L(dL4):
+@@ -327,7 +523,7 @@
+ 	bne	cr5, L(dLcr5)
+ 	cmplw	cr5, rWORD7, rWORD8
+ L(d44):
+-	bne	cr0, L(dLcr0)
++	bne	cr7, L(dLcr7)
+ L(d34):
+ 	bne	cr1, L(dLcr1)
+ L(d24):
+@@ -336,69 +532,82 @@
+ 	slwi.	r12, rN, 3
+ 	bne	cr5, L(dLcr5) 
+ L(d04):
+-        lwz     r30,44(1)
+-        lwz     r31,48(1)
+-        lwz     1,0(1)
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+ 	beq	L(zeroLength)
+ /* At this point we have a remainder of 1 to 3 bytes to compare.  Since
+    we are aligned it is safe to load the whole word, and use
+-   shift right to eliminate bits beyond the compare length. */ 
++   shift right to eliminate bits beyond the compare length.  */
+ L(d00):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 4(rSTR1)
+ 	lwz	rWORD2, 4(rSTR2) 
++#endif
+ 	srw	rWORD1, rWORD1, rN
+ 	srw	rWORD2, rWORD2, rN
+-        cmplw   rWORD1,rWORD2
+-        li      rRTN,0
+-        beqlr
+-        li      rRTN,1
+-        bgtlr
+-        li      rRTN,-1
+-        blr
+-
+-	.align 4
+-L(dLcr0):
+-        lwz     r30,44(1)
+-        lwz     r31,48(1)
++	sub	rRTN, rWORD1, rWORD2
++	blr
++
++	.align	4
++	cfi_adjust_cfa_offset(64)
++L(dLcr7):
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++L(dLcr7x):
+ 	li	rRTN, 1
+-        lwz     1,0(1)
+-	bgtlr	cr0
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
++	bgtlr	cr7
+ 	li	rRTN, -1
+ 	blr
+-	.align 4
++	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dLcr1):
+-        lwz     r30,44(1)
+-        lwz     r31,48(1)
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++L(dLcr1x):
+ 	li	rRTN, 1
+-        lwz     1,0(1)
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bgtlr	cr1
+ 	li	rRTN, -1
+ 	blr
+-	.align 4
++	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dLcr6):
+-        lwz     r30,44(1)
+-        lwz     r31,48(1)
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++L(dLcr6x):
+ 	li	rRTN, 1
+-        lwz     1,0(1)
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bgtlr	cr6
+ 	li	rRTN, -1
+ 	blr
+-	.align 4
++	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dLcr5):
+-        lwz     r30,44(1)
+-        lwz     r31,48(1)
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
+ L(dLcr5x):
+ 	li	rRTN, 1
+-        lwz     1,0(1)
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bgtlr	cr5
+ 	li	rRTN, -1
+ 	blr
+ 	
+-	.align 4
++	.align	4
+ L(bytealigned):
+-	cfi_adjust_cfa_offset(-64)
+-	mtctr   rN	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	rN	/* Power4 wants mtctr 1st in dispatch group */
+ 
+ /* We need to prime this loop.  This loop is swing modulo scheduled
+    to avoid pipe delays.  The dependent instruction latencies (load to 
+@@ -413,7 +622,7 @@
+ 	lbz	rWORD1, 0(rSTR1)
+ 	lbz	rWORD2, 0(rSTR2)
+ 	bdz-	L(b11)
+-	cmplw	cr0, rWORD1, rWORD2
++	cmplw	cr7, rWORD1, rWORD2
+ 	lbz	rWORD3, 1(rSTR1)
+ 	lbz	rWORD4, 1(rSTR2)
+ 	bdz-	L(b12)
+@@ -421,11 +630,11 @@
+ 	lbzu	rWORD5, 2(rSTR1)
+ 	lbzu	rWORD6, 2(rSTR2)
+ 	bdz-	L(b13)
+-	.align 4
++	.align	4
+ L(bLoop):
+ 	lbzu	rWORD1, 1(rSTR1)
+ 	lbzu	rWORD2, 1(rSTR2)
+-	bne-	cr0, L(bLcr0)
++	bne-	cr7, L(bLcr7)
+ 
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	bdz-	L(b3i)
+@@ -434,7 +643,7 @@
+ 	lbzu	rWORD4, 1(rSTR2)
+ 	bne-	cr1, L(bLcr1)
+ 
+-	cmplw	cr0, rWORD1, rWORD2
++	cmplw	cr7, rWORD1, rWORD2
+ 	bdz-	L(b2i)
+ 
+ 	lbzu	rWORD5, 1(rSTR1)
+@@ -451,23 +660,23 @@
+    tested.  In this case we must complete the pending operations
+    before returning.  */
+ L(b1i):
+-	bne-	cr0, L(bLcr0)
++	bne-	cr7, L(bLcr7)
+ 	bne-	cr1, L(bLcr1)
+ 	b	L(bx56)
+-	.align 4
++	.align	4
+ L(b2i):
+ 	bne-	cr6, L(bLcr6)
+-	bne-	cr0, L(bLcr0)
++	bne-	cr7, L(bLcr7)
+ 	b	L(bx34)
+-	.align 4
++	.align	4
+ L(b3i):
+ 	bne-	cr1, L(bLcr1)
+ 	bne-	cr6, L(bLcr6)
+ 	b	L(bx12)
+-	.align 4
+-L(bLcr0):
++	.align	4
++L(bLcr7):
+ 	li	rRTN, 1
+-	bgtlr	cr0
++	bgtlr	cr7
+ 	li	rRTN, -1
+ 	blr
+ L(bLcr1):
+@@ -482,36 +691,31 @@
+ 	blr
+ 
+ L(b13):
+-	bne-	cr0, L(bx12)
++	bne-	cr7, L(bx12)
+ 	bne-	cr1, L(bx34)
+ L(bx56):
+ 	sub	rRTN, rWORD5, rWORD6
+ 	blr
+ 	nop
+ L(b12):
+-	bne-	cr0, L(bx12)
++	bne-	cr7, L(bx12)
+ L(bx34):	
+ 	sub	rRTN, rWORD3, rWORD4
+ 	blr
+-
+ L(b11):
+ L(bx12):
+ 	sub	rRTN, rWORD1, rWORD2
+ 	blr
+-
+-	.align 4 
+-L(zeroLengthReturn):
+-
++	.align	4
+ L(zeroLength):
+ 	li	rRTN, 0
+ 	blr
+ 
+-	cfi_adjust_cfa_offset(64)
+-	.align 4
++	.align	4
+ /* At this point we know the strings have different alignment and the
+-   compare length is at least 8 bytes.  rBITDIF contains the low order
++   compare length is at least 8 bytes.  r12 contains the low order
+    2 bits of rSTR1 and cr5 contains the result of the logical compare
+-   of rBITDIF to 0.  If rBITDIF == 0 then rStr1 is word aligned and can 
++   of r12 to 0.  If r12 == 0 then rStr1 is word aligned and can
+    perform the Wunaligned loop.
+   
+    Otherwise we know that rSTR1 is not aready word aligned yet.
+@@ -520,79 +724,88 @@
+    eliminate bits preceeding the first byte.  Since we want to join the
+    normal (Wualigned) compare loop, starting at the second word,
+    we need to adjust the length (rN) and special case the loop
+-   versioning for the first W. This insures that the loop count is
++   versioning for the first W. This ensures that the loop count is
+    correct and the first W (shifted) is in the expected resister pair.  */
+ #define rSHL		r29	/* Unaligned shift left count.  */
+ #define rSHR		r28	/* Unaligned shift right count.  */
+-#define rB		r27	/* Left rotation temp for rWORD2.  */
+-#define rD		r26	/* Left rotation temp for rWORD4.  */
+-#define rF		r25	/* Left rotation temp for rWORD6.  */
+-#define rH		r24	/* Left rotation temp for rWORD8.  */
+-#define rA		r0	/* Right rotation temp for rWORD2.  */
+-#define rC		r12	/* Right rotation temp for rWORD4.  */
+-#define rE		r0	/* Right rotation temp for rWORD6.  */
+-#define rG		r12	/* Right rotation temp for rWORD8.  */
++#define rWORD8_SHIFT	r27	/* Left rotation temp for rWORD2.  */
++#define rWORD2_SHIFT	r26	/* Left rotation temp for rWORD4.  */
++#define rWORD4_SHIFT	r25	/* Left rotation temp for rWORD6.  */
++#define rWORD6_SHIFT	r24	/* Left rotation temp for rWORD8.  */
++	cfi_adjust_cfa_offset(64)
+ L(unaligned):
+-	stw     r29,40(r1)	
+-	cfi_offset(r29,(40-64))	
++	stw	rSHL, 40(r1)
++	cfi_offset(rSHL, (40-64))
+ 	clrlwi	rSHL, rSTR2, 30
+-        stw     r28,36(r1)	
+-	cfi_offset(r28,(36-64))
++	stw	rSHR, 36(r1)
++	cfi_offset(rSHR, (36-64))
+ 	beq	cr5, L(Wunaligned)
+-        stw     r27,32(r1)	
+-	cfi_offset(r27,(32-64))
++	stw	rWORD8_SHIFT, 32(r1)
++	cfi_offset(rWORD8_SHIFT, (32-64))
+ /* Adjust the logical start of rSTR2 to compensate for the extra bits
+    in the 1st rSTR1 W.  */
+-	sub	r27, rSTR2, rBITDIF
++	sub	rWORD8_SHIFT, rSTR2, r12
+ /* But do not attempt to address the W before that W that contains
+    the actual start of rSTR2.  */
+ 	clrrwi	rSTR2, rSTR2, 2
+-        stw     r26,28(r1)	
+-	cfi_offset(r26,(28-64))
+-/* Compute the left/right shift counts for the unalign rSTR2,
++	stw	rWORD2_SHIFT, 28(r1)
++	cfi_offset(rWORD2_SHIFT, (28-64))
++/* Compute the left/right shift counts for the unaligned rSTR2,
+    compensating for the logical (W aligned) start of rSTR1.  */ 
+-	clrlwi	rSHL, r27, 30
++	clrlwi	rSHL, rWORD8_SHIFT, 30
+ 	clrrwi	rSTR1, rSTR1, 2	
+-        stw     r25,24(r1)	
+-	cfi_offset(r25,(24-64))
++	stw	rWORD4_SHIFT, 24(r1)
++	cfi_offset(rWORD4_SHIFT, (24-64))
+ 	slwi	rSHL, rSHL, 3
+-	cmplw	cr5, r27, rSTR2
+-	add	rN, rN, rBITDIF
+-	slwi	r11, rBITDIF, 3
+-        stw     r24,20(r1)	
+-	cfi_offset(r24,(20-64))
++	cmplw	cr5, rWORD8_SHIFT, rSTR2
++	add	rN, rN, r12
++	slwi	rWORD6, r12, 3
++	stw	rWORD6_SHIFT, 20(r1)
++	cfi_offset(rWORD6_SHIFT, (20-64))
+ 	subfic	rSHR, rSHL, 32
+-	srwi	rTMP, rN, 4      /* Divide by 16 */
+-	andi.	rBITDIF, rN, 12  /* Get the W remainder */
++	srwi	r0, rN, 4	/* Divide by 16 */
++	andi.	r12, rN, 12	/* Get the W remainder */
+ /* We normally need to load 2 Ws to start the unaligned rSTR2, but in
+    this special case those bits may be discarded anyway.  Also we
+    must avoid loading a W where none of the bits are part of rSTR2 as
+    this may cross a page boundary and cause a page fault.  */
+ 	li	rWORD8, 0
+ 	blt	cr5, L(dus0)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD8, 0(rSTR2)
+-	la	rSTR2, 4(rSTR2)
++	addi	rSTR2, rSTR2, 4
++#endif
+ 	slw	rWORD8, rWORD8, rSHL
+ 
+ L(dus0):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 0(rSTR1)
+ 	lwz	rWORD2, 0(rSTR2)
+-	cmplwi	cr1, rBITDIF, 8
++#endif
++	cmplwi	cr1, r12, 8
+ 	cmplwi	cr7, rN, 16
+-	srw	rG, rWORD2, rSHR
++	srw	r12, rWORD2, rSHR
+ 	clrlwi	rN, rN, 30
+ 	beq	L(duPs4)
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+-	or	rWORD8, rG, rWORD8
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++	or	rWORD8, r12, rWORD8
+ 	bgt	cr1, L(duPs3)
+ 	beq	cr1, L(duPs2)
+ 
+ /* Remainder is 4 */
+-	.align 4
++	.align	4
+ L(dusP1):
+-	slw	rB, rWORD2, rSHL
+-	slw	rWORD7, rWORD1, r11
+-	slw	rWORD8, rWORD8, r11
++	slw	rWORD8_SHIFT, rWORD2, rSHL
++	slw	rWORD7, rWORD1, rWORD6
++	slw	rWORD8, rWORD8, rWORD6
+ 	bge	cr7, L(duP1e)
+ /* At this point we exit early with the first word compare
+    complete and remainder of 0 to 3 bytes.  See L(du14) for details on
+@@ -602,95 +815,133 @@
+ 	bne	cr5, L(duLcr5)
+ 	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD2, 4(rSTR2)
+-	srw	rA, rWORD2, rSHR
++#endif
++	srw	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ /* Remainder is 8 */
+-	.align 4
++	.align	4
+ L(duPs2):
+-	slw	rH, rWORD2, rSHL
+-	slw	rWORD5, rWORD1, r11
+-	slw	rWORD6, rWORD8, r11
++	slw	rWORD6_SHIFT, rWORD2, rSHL
++	slw	rWORD5, rWORD1, rWORD6
++	slw	rWORD6, rWORD8, rWORD6
+ 	b	L(duP2e)
+ /* Remainder is 12 */
+-	.align 4
++	.align	4
+ L(duPs3):
+-	slw	rF, rWORD2, rSHL
+-	slw	rWORD3, rWORD1, r11
+-	slw	rWORD4, rWORD8, r11
++	slw	rWORD4_SHIFT, rWORD2, rSHL
++	slw	rWORD3, rWORD1, rWORD6
++	slw	rWORD4, rWORD8, rWORD6
+ 	b	L(duP3e)
+ /* Count is a multiple of 16, remainder is 0 */
+-	.align 4
++	.align	4
+ L(duPs4):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+-	or	rWORD8, rG, rWORD8
+-	slw	rD, rWORD2, rSHL
+-	slw	rWORD1, rWORD1, r11
+-	slw	rWORD2, rWORD8, r11
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++	or	rWORD8, r12, rWORD8
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	slw	rWORD1, rWORD1, rWORD6
++	slw	rWORD2, rWORD8, rWORD6
+ 	b	L(duP4e)
+ 
+ /* At this point we know rSTR1 is word aligned and the
+    compare length is at least 8 bytes.  */
+-	.align 4
++	.align	4
+ L(Wunaligned):
+-        stw     r27,32(r1)	
+-	cfi_offset(r27,(32-64))
++	stw	rWORD8_SHIFT, 32(r1)
++	cfi_offset(rWORD8_SHIFT, (32-64))
+ 	clrrwi	rSTR2, rSTR2, 2
+-        stw     r26,28(r1)	
+-	cfi_offset(r26,(28-64))
+-	srwi	rTMP, rN, 4	 /* Divide by 16 */
+-        stw     r25,24(r1)	
+-	cfi_offset(r25,(24-64))
+-	andi.	rBITDIF, rN, 12  /* Get the W remainder */
+-        stw     r24,20(r1)	
+-	cfi_offset(r24,(20-64))
++	stw	rWORD2_SHIFT, 28(r1)
++	cfi_offset(rWORD2_SHIFT, (28-64))
++	srwi	r0, rN, 4	/* Divide by 16 */
++	stw	rWORD4_SHIFT, 24(r1)
++	cfi_offset(rWORD4_SHIFT, (24-64))
++	andi.	r12, rN, 12	/* Get the W remainder */
++	stw	rWORD6_SHIFT, 20(r1)
++	cfi_offset(rWORD6_SHIFT, (20-64))
+ 	slwi	rSHL, rSHL, 3
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD6, 0(rSTR2)
+ 	lwzu	rWORD8, 4(rSTR2)
+-	cmplwi	cr1, rBITDIF, 8
++#endif
++	cmplwi	cr1, r12, 8
+ 	cmplwi	cr7, rN, 16
+ 	clrlwi	rN, rN, 30
+ 	subfic	rSHR, rSHL, 32
+-	slw	rH, rWORD6, rSHL
++	slw	rWORD6_SHIFT, rWORD6, rSHL
+ 	beq	L(duP4)
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
+ 	bgt	cr1, L(duP3)
+ 	beq	cr1, L(duP2)
+ 		
+ /* Remainder is 4 */
+-	.align 4
++	.align	4
+ L(duP1):
+-	srw	rG, rWORD8, rSHR
++	srw	r12, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	addi	rSTR1, rSTR1, 4
++#else
+ 	lwz	rWORD7, 0(rSTR1)
+-	slw	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++#endif
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	blt	cr7, L(duP1x)
+ L(duP1e):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 4(rSTR1)
+ 	lwz	rWORD2, 4(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+-	srw	rA, rWORD2, rSHR
+-	slw	rD, rWORD2, rSHL
+-	or	rWORD2, rA, rB
++	srw	r0, rWORD2, rSHR
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 8(rSTR1)
+ 	lwz	rWORD4, 8(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
+-	srw	rC, rWORD4, rSHR
+-	slw	rF, rWORD4, rSHL
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++	srw	r12, rWORD4, rSHR
++	slw	rWORD4_SHIFT, rWORD4, rSHL
+ 	bne	cr5, L(duLcr5)
+-	or	rWORD4, rC, rD
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 12(rSTR1)
+ 	lwz	rWORD6, 12(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
+-	srw	rE, rWORD6, rSHR
+-	slw	rH, rWORD6, rSHL
+-	bne	cr0, L(duLcr0)
+-	or	rWORD6, rE, rF
++	srw	r0, rWORD6, rSHR
++	slw	rWORD6_SHIFT, rWORD6, rSHL
++	bne	cr7, L(duLcr7)
++	or	rWORD6, r0, rWORD4_SHIFT
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	b	L(duLoop3)	
+-	.align 4
++	.align	4
+ /* At this point we exit early with the first word compare
+    complete and remainder of 0 to 3 bytes.  See L(du14) for details on
+    how we handle the remaining bytes.  */
+@@ -700,186 +951,321 @@
+ 	bne	cr5, L(duLcr5)
+ 	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
+-	ld	rWORD2, 8(rSTR2)
+-	srw	rA, rWORD2, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD2, 8(rSTR2)
++#endif
++	srw	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ /* Remainder is 8 */
+-	.align 4
++	.align	4
+ L(duP2):
+-	srw	rE, rWORD8, rSHR
++	srw	r0, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	addi	rSTR1, rSTR1, 4
++#else
+ 	lwz	rWORD5, 0(rSTR1)
+-	or	rWORD6, rE, rH
+-	slw	rH, rWORD8, rSHL
++#endif
++	or	rWORD6, r0, rWORD6_SHIFT
++	slw	rWORD6_SHIFT, rWORD8, rSHL
+ L(duP2e):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD7, 4(rSTR1)
+ 	lwz	rWORD8, 4(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
+-	srw	rG, rWORD8, rSHR
+-	slw	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++	srw	r12, rWORD8, rSHR
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	blt	cr7, L(duP2x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 8(rSTR1)
+ 	lwz	rWORD2, 8(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+ 	bne	cr6, L(duLcr6)
+-	srw	rA, rWORD2, rSHR
+-	slw	rD, rWORD2, rSHL
+-	or	rWORD2, rA, rB
++	srw	r0, rWORD2, rSHR
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 12(rSTR1)
+ 	lwz	rWORD4, 12(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ 	bne	cr5, L(duLcr5)
+-	srw	rC, rWORD4, rSHR
+-	slw	rF, rWORD4, rSHL
+-	or	rWORD4, rC, rD
++	srw	r12, rWORD4, rSHR
++	slw	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 4
+ 	addi	rSTR2, rSTR2, 4
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
+ 	b	L(duLoop2)
+-	.align 4
++	.align	4
+ L(duP2x):
+ 	cmplw	cr5, rWORD7, rWORD8
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 4
+ 	addi	rSTR2, rSTR2, 4
++#endif
+ 	bne	cr6, L(duLcr6)
+ 	slwi.	rN, rN, 3
+ 	bne	cr5, L(duLcr5)
+ 	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD2, 4(rSTR2)
+-	srw	rA, rWORD2, rSHR
++#endif
++	srw	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ 		
+ /* Remainder is 12 */
+-	.align 4
++	.align	4
+ L(duP3):
+-	srw	rC, rWORD8, rSHR
++	srw	r12, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	addi	rSTR1, rSTR1, 4
++#else
+ 	lwz	rWORD3, 0(rSTR1)
+-	slw	rF, rWORD8, rSHL
+-	or	rWORD4, rC, rH
++#endif
++	slw	rWORD4_SHIFT, rWORD8, rSHL
++	or	rWORD4, r12, rWORD6_SHIFT
+ L(duP3e):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 4(rSTR1)
+ 	lwz	rWORD6, 4(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
+-	srw	rE, rWORD6, rSHR
+-	slw	rH, rWORD6, rSHL
+-	or	rWORD6, rE, rF
++	srw	r0, rWORD6, rSHR
++	slw	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD7, 8(rSTR1)
+ 	lwz	rWORD8, 8(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	bne	cr1, L(duLcr1)
+-	srw	rG, rWORD8, rSHR
+-	slw	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++	srw	r12, rWORD8, rSHR
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	blt	cr7, L(duP3x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 12(rSTR1)
+ 	lwz	rWORD2, 12(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+ 	bne	cr6, L(duLcr6)
+-	srw	rA, rWORD2, rSHR
+-	slw	rD, rWORD2, rSHL
+-	or	rWORD2, rA, rB
++	srw	r0, rWORD2, rSHR
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 8
+ 	addi	rSTR2, rSTR2, 8
+-	cmplw	cr0, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ 	b	L(duLoop1)
+-	.align 4
++	.align	4
+ L(duP3x):
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 8
+ 	addi	rSTR2, rSTR2, 8
++#endif
++#if 0
++/* Huh?  We've already branched on cr1!  */
+ 	bne	cr1, L(duLcr1)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+ 	bne	cr6, L(duLcr6)
+ 	slwi.	rN, rN, 3
+ 	bne	cr5, L(duLcr5)
+ 	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD2, 4(rSTR2)
+-	srw	rA, rWORD2, rSHR
++#endif
++	srw	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ 	
+ /* Count is a multiple of 16, remainder is 0 */
+-	.align 4
++	.align	4
+ L(duP4):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+-	srw	rA, rWORD8, rSHR
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++	srw	r0, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	addi	rSTR1, rSTR1, 4
++#else
+ 	lwz	rWORD1, 0(rSTR1)
+-	slw	rD, rWORD8, rSHL
+-	or	rWORD2, rA, rH
++#endif
++	slw	rWORD2_SHIFT, rWORD8, rSHL
++	or	rWORD2, r0, rWORD6_SHIFT
+ L(duP4e):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 4(rSTR1)
+ 	lwz	rWORD4, 4(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
+-	srw	rC, rWORD4, rSHR
+-	slw	rF, rWORD4, rSHL
+-	or	rWORD4, rC, rD
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++	srw	r12, rWORD4, rSHR
++	slw	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 8(rSTR1)
+ 	lwz	rWORD6, 8(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
+-	bne	cr0, L(duLcr0)
+-	srw	rE, rWORD6, rSHR
+-	slw	rH, rWORD6, rSHL
+-	or	rWORD6, rE, rF
++	bne	cr7, L(duLcr7)
++	srw	r0, rWORD6, rSHR
++	slw	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwzu	rWORD7, 12(rSTR1)
+ 	lwzu	rWORD8, 12(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	bne	cr1, L(duLcr1)
+-	srw	rG, rWORD8, rSHR
+-	slw	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++	srw	r12, rWORD8, rSHR
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	cmplw	cr5, rWORD7, rWORD8
+ 	bdz-	L(du24)		/* Adjust CTR as we start with +4 */
+ /* This is the primary loop */
+-	.align 4
++	.align	4
+ L(duLoop):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD1, 4(rSTR1)
+ 	lwz	rWORD2, 4(rSTR2)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
+ 	bne	cr6, L(duLcr6)
+-	srw	rA, rWORD2, rSHR
+-	slw	rD, rWORD2, rSHL
+-	or	rWORD2, rA, rB
++	srw	r0, rWORD2, rSHR
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
+ L(duLoop1):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD3, 8(rSTR1)
+ 	lwz	rWORD4, 8(rSTR2)
++#endif
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	bne	cr5, L(duLcr5)
+-	srw	rC, rWORD4, rSHR
+-	slw	rF, rWORD4, rSHL
+-	or	rWORD4, rC, rD
++	srw	r12, rWORD4, rSHR
++	slw	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
+ L(duLoop2):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD5, 12(rSTR1)
+ 	lwz	rWORD6, 12(rSTR2)
++#endif
+ 	cmplw	cr5, rWORD7, rWORD8
+-	bne	cr0, L(duLcr0)
+-	srw	rE, rWORD6, rSHR
+-	slw	rH, rWORD6, rSHL
+-	or	rWORD6, rE, rF
++	bne	cr7, L(duLcr7)
++	srw	r0, rWORD6, rSHR
++	slw	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
+ L(duLoop3):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwzu	rWORD7, 16(rSTR1)
+ 	lwzu	rWORD8, 16(rSTR2)
+-	cmplw	cr0, rWORD1, rWORD2
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ 	bne-	cr1, L(duLcr1)
+-	srw	rG, rWORD8, rSHR
+-	slw	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++	srw	r12, rWORD8, rSHR
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	bdnz+	L(duLoop)	
+ 	
+ L(duL4):
++#if 0
++/* Huh?  We've already branched on cr1!  */
+ 	bne	cr1, L(duLcr1)
++#endif
+ 	cmplw	cr1, rWORD3, rWORD4
+ 	bne	cr6, L(duLcr6)
+ 	cmplw	cr6, rWORD5, rWORD6
+ 	bne	cr5, L(duLcr5)
+ 	cmplw	cr5, rWORD7, rWORD8
+ L(du44):
+-	bne	cr0, L(duLcr0)
++	bne	cr7, L(duLcr7)
+ L(du34):
+ 	bne	cr1, L(duLcr1)
+ L(du24):
+@@ -889,95 +1275,101 @@
+ 	bne	cr5, L(duLcr5)
+ /* At this point we have a remainder of 1 to 3 bytes to compare.  We use
+    shift right to eliminate bits beyond the compare length. 
++   This allows the use of word subtract to compute the final result.
+ 
+    However it may not be safe to load rWORD2 which may be beyond the 
+    string length. So we compare the bit length of the remainder to
+    the right shift count (rSHR). If the bit count is less than or equal
+    we do not need to load rWORD2 (all significant bits are already in
+-   rB).  */
++   rWORD8_SHIFT).  */
+ 	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
+ 	lwz	rWORD2, 4(rSTR2)
+-	srw	rA, rWORD2, rSHR
+-	.align 4
++#endif
++	srw	r0, rWORD2, rSHR
++	.align	4
+ L(dutrim):
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++#else
+ 	lwz	rWORD1, 4(rSTR1)
+-        lwz     r31,48(1)
++#endif
++	lwz	rWORD8, 48(r1)
+ 	subfic	rN, rN, 32	/* Shift count is 32 - (rN * 8).  */ 
+-	or	rWORD2, rA, rB
+-        lwz     r30,44(1)
+-        lwz     r29,40(r1)
++	or	rWORD2, r0, rWORD8_SHIFT
++	lwz	rWORD7, 44(r1)
++	lwz	rSHL, 40(r1)
+ 	srw	rWORD1, rWORD1, rN
+ 	srw	rWORD2, rWORD2, rN
+-        lwz     r28,36(r1)	
+-        lwz     r27,32(r1)
+-        cmplw   rWORD1,rWORD2
+-        li      rRTN,0
+-        beq     L(dureturn26)
+-        li      rRTN,1
+-        bgt     L(dureturn26)
+-        li      rRTN,-1
+-	b    L(dureturn26)
+-	.align 4
+-L(duLcr0):
+-        lwz     r31,48(1)
+-        lwz     r30,44(1)
+-	li	rRTN, 1
+-	bgt	cr0, L(dureturn29)	
+-	lwz     r29,40(r1)
+-        lwz     r28,36(r1)	
++	lwz	rSHR, 36(r1)
++	lwz	rWORD8_SHIFT, 32(r1)
++	sub	rRTN, rWORD1, rWORD2
++	b	L(dureturn26)
++	.align	4
++L(duLcr7):
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
++	li	rRTN, 1
++	bgt	cr7, L(dureturn29)
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
+ 	li	rRTN, -1
+ 	b	L(dureturn27)
+-	.align 4
++	.align	4
+ L(duLcr1):
+-        lwz     r31,48(1)
+-        lwz     r30,44(1)
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
+ 	li	rRTN, 1
+ 	bgt	cr1, L(dureturn29)	
+-        lwz     r29,40(r1)
+-        lwz     r28,36(r1)	
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
+ 	li	rRTN, -1
+ 	b	L(dureturn27)
+-	.align 4
++	.align	4
+ L(duLcr6):
+-        lwz     r31,48(1)
+-        lwz     r30,44(1)
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
+ 	li	rRTN, 1
+ 	bgt	cr6, L(dureturn29)	
+-        lwz     r29,40(r1)
+-        lwz     r28,36(r1)	
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
+ 	li	rRTN, -1
+ 	b	L(dureturn27)
+-	.align 4
++	.align	4
+ L(duLcr5):
+-        lwz     r31,48(1)
+-        lwz     r30,44(1)
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
+ 	li	rRTN, 1
+ 	bgt	cr5, L(dureturn29)	
+-        lwz     r29,40(r1)
+-        lwz     r28,36(r1)	
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
+ 	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	3
+ L(duZeroReturn):
+-	li	rRTN,0
++	li	rRTN, 0
+ 	.align	4
+ L(dureturn):
+-        lwz     r31,48(1)
+-        lwz     r30,44(1)
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
+ L(dureturn29):	
+-        lwz     r29,40(r1)
+-        lwz     r28,36(r1)	
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
+ L(dureturn27):	
+-        lwz     r27,32(r1)
++	lwz	rWORD8_SHIFT, 32(r1)
+ L(dureturn26):	
+-        lwz     r26,28(r1)
++	lwz	rWORD2_SHIFT, 28(r1)
+ L(dureturn25):	
+-        lwz     r25,24(r1)
+-        lwz     r24,20(r1)
+-        lwz     1,0(1)
++	lwz	rWORD4_SHIFT, 24(r1)
++	lwz	rWORD6_SHIFT, 20(r1)
++	addi	1, 1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	blr
+ END (BP_SYM (memcmp))
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memcmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memcmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memcmp.S	2014-05-28 19:22:37.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memcmp.S	2014-05-28 21:44:57.000000000 -0500
+@@ -25,10 +25,9 @@
+ 		    size_t size [r5])  */
+ 
+ 	.machine power7
+-EALIGN (BP_SYM(memcmp),4,0)
++EALIGN (BP_SYM(memcmp), 4, 0)
+ 	CALL_MCOUNT
+ 
+-#define rTMP	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+@@ -39,35 +38,32 @@
+ #define rWORD4	r9	/* next word in s2 */
+ #define rWORD5	r10	/* next word in s1 */
+ #define rWORD6	r11	/* next word in s2 */
+-#define rBITDIF	r12	/* bits that differ in s1 & s2 words */
+ #define rWORD7	r30	/* next word in s1 */
+ #define rWORD8	r31	/* next word in s2 */
+ 
+-	xor	rTMP,rSTR2,rSTR1
+-	cmplwi	cr6,rN,0
+-	cmplwi	cr1,rN,12
+-	clrlwi.	rTMP,rTMP,30
+-	clrlwi	rBITDIF,rSTR1,30
+-	cmplwi	cr5,rBITDIF,0
+-	beq-	cr6,L(zeroLength)
+-	dcbt	0,rSTR1
+-	dcbt	0,rSTR2
+-
+-	/* If less than 8 bytes or not aligned, use the unaligned
+-	   byte loop.  */
+-
+-	blt	cr1,L(bytealigned)
+-	stwu	1,-64(1)
++	xor	r0, rSTR2, rSTR1
++	cmplwi	cr6, rN, 0
++	cmplwi	cr1, rN, 12
++	clrlwi.	r0, r0, 30
++	clrlwi	r12, rSTR1, 30
++	cmplwi	cr5, r12, 0
++	beq-	cr6, L(zeroLength)
++	dcbt	0, rSTR1
++	dcbt	0, rSTR2
++/* If less than 8 bytes or not aligned, use the unaligned
++   byte loop.  */
++	blt	cr1, L(bytealigned)
++	stwu	1, -64(r1)
+ 	cfi_adjust_cfa_offset(64)
+-	stw	r31,48(1)
+-	cfi_offset(31,(48-64))
+-	stw	r30,44(1)
+-	cfi_offset(30,(44-64))
++	stw	rWORD8, 48(r1)
++	cfi_offset(rWORD8, (48-64))
++	stw	rWORD7, 44(r1)
++	cfi_offset(rWORD7, (44-64))
+ 	bne	L(unaligned)
+ /* At this point we know both strings have the same alignment and the
+-   compare length is at least 8 bytes.  rBITDIF contains the low order
++   compare length is at least 8 bytes.  r12 contains the low order
+    2 bits of rSTR1 and cr5 contains the result of the logical compare
+-   of rBITDIF to 0.  If rBITDIF == 0 then we are already word
++   of r12 to 0.  If r12 == 0 then we are already word
+    aligned and can perform the word aligned loop.
+ 
+    Otherwise we know the two strings have the same alignment (but not
+@@ -76,332 +72,541 @@
+    eliminate bits preceeding the first byte.  Since we want to join the
+    normal (word aligned) compare loop, starting at the second word,
+    we need to adjust the length (rN) and special case the loop
+-   versioning for the first word. This insures that the loop count is
++   versioning for the first word. This ensures that the loop count is
+    correct and the first word (shifted) is in the expected register pair. */
+ 	.align	4
+ L(samealignment):
+-	clrrwi	rSTR1,rSTR1,2
+-	clrrwi	rSTR2,rSTR2,2
+-	beq	cr5,L(Waligned)
+-	add	rN,rN,rBITDIF
+-	slwi	r11,rBITDIF,3
+-	srwi	rTMP,rN,4	/* Divide by 16 */
+-	andi.	rBITDIF,rN,12	/* Get the word remainder */
+-	lwz	rWORD1,0(rSTR1)
+-	lwz	rWORD2,0(rSTR2)
+-	cmplwi	cr1,rBITDIF,8
+-	cmplwi	cr7,rN,16
+-	clrlwi	rN,rN,30
++	clrrwi	rSTR1, rSTR1, 2
++	clrrwi	rSTR2, rSTR2, 2
++	beq	cr5, L(Waligned)
++	add	rN, rN, r12
++	slwi	rWORD6, r12, 3
++	srwi	r0, rN, 4	/* Divide by 16 */
++	andi.	r12, rN, 12	/* Get the word remainder */
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++#endif
++	cmplwi	cr1, r12, 8
++	cmplwi	cr7, rN, 16
++	clrlwi	rN, rN, 30
+ 	beq	L(dPs4)
+-	mtctr	rTMP
+-	bgt	cr1,L(dPs3)
+-	beq	cr1,L(dPs2)
++	mtctr	r0
++	bgt	cr1, L(dPs3)
++	beq	cr1, L(dPs2)
+ 
+ /* Remainder is 4 */
+ 	.align	3
+ L(dsP1):
+-	slw	rWORD5,rWORD1,r11
+-	slw	rWORD6,rWORD2,r11
+-	cmplw	cr5,rWORD5,rWORD6
+-	blt	cr7,L(dP1x)
++	slw	rWORD5, rWORD1, rWORD6
++	slw	rWORD6, rWORD2, rWORD6
++	cmplw	cr5, rWORD5, rWORD6
++	blt	cr7, L(dP1x)
+ /* Do something useful in this cycle since we have to branch anyway.  */
+-	lwz	rWORD1,4(rSTR1)
+-	lwz	rWORD2,4(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 4(rSTR1)
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ 	b	L(dP1e)
+ /* Remainder is 8 */
+ 	.align	4
+ L(dPs2):
+-	slw	rWORD5,rWORD1,r11
+-	slw	rWORD6,rWORD2,r11
+-	cmplw	cr6,rWORD5,rWORD6
+-	blt	cr7,L(dP2x)
++	slw	rWORD5, rWORD1, rWORD6
++	slw	rWORD6, rWORD2, rWORD6
++	cmplw	cr6, rWORD5, rWORD6
++	blt	cr7, L(dP2x)
+ /* Do something useful in this cycle since we have to branch anyway.  */
+-	lwz	rWORD7,4(rSTR1)
+-	lwz	rWORD8,4(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD7, 4(rSTR1)
++	lwz	rWORD8, 4(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
+ 	b	L(dP2e)
+ /* Remainder is 12 */
+ 	.align	4
+ L(dPs3):
+-	slw	rWORD3,rWORD1,r11
+-	slw	rWORD4,rWORD2,r11
+-	cmplw	cr1,rWORD3,rWORD4
++	slw	rWORD3, rWORD1, rWORD6
++	slw	rWORD4, rWORD2, rWORD6
++	cmplw	cr1, rWORD3, rWORD4
+ 	b	L(dP3e)
+ /* Count is a multiple of 16, remainder is 0 */
+ 	.align	4
+ L(dPs4):
+-	mtctr	rTMP
+-	slw	rWORD1,rWORD1,r11
+-	slw	rWORD2,rWORD2,r11
+-	cmplw	cr0,rWORD1,rWORD2
++	mtctr	r0
++	slw	rWORD1, rWORD1, rWORD6
++	slw	rWORD2, rWORD2, rWORD6
++	cmplw	cr7, rWORD1, rWORD2
+ 	b	L(dP4e)
+ 
+ /* At this point we know both strings are word aligned and the
+    compare length is at least 8 bytes.  */
+ 	.align	4
+ L(Waligned):
+-	andi.	rBITDIF,rN,12	/* Get the word remainder */
+-	srwi	rTMP,rN,4	/* Divide by 16 */
+-	cmplwi	cr1,rBITDIF,8
+-	cmplwi	cr7,rN,16
+-	clrlwi	rN,rN,30
++	andi.	r12, rN, 12	/* Get the word remainder */
++	srwi	r0, rN, 4	/* Divide by 16 */
++	cmplwi	cr1, r12, 8
++	cmplwi	cr7, rN, 16
++	clrlwi	rN, rN, 30
+ 	beq	L(dP4)
+-	bgt	cr1,L(dP3)
+-	beq	cr1,L(dP2)
++	bgt	cr1, L(dP3)
++	beq	cr1, L(dP2)
+ 
+ /* Remainder is 4 */
+ 	.align	4
+ L(dP1):
+-	mtctr	rTMP
++	mtctr	r0
+ /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early
+    (8-15 byte compare), we want to use only volatile registers.  This
+    means we can avoid restoring non-volatile registers since we did not
+    change any on the early exit path.  The key here is the non-early
+    exit path only cares about the condition code (cr5), not about which
+    register pair was used.  */
+-	lwz	rWORD5,0(rSTR1)
+-	lwz	rWORD6,0(rSTR2)
+-	cmplw	cr5,rWORD5,rWORD6
+-	blt	cr7,L(dP1x)
+-	lwz	rWORD1,4(rSTR1)
+-	lwz	rWORD2,4(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 0(rSTR1)
++	lwz	rWORD6, 0(rSTR2)
++#endif
++	cmplw	cr5, rWORD5, rWORD6
++	blt	cr7, L(dP1x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 4(rSTR1)
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ L(dP1e):
+-	lwz	rWORD3,8(rSTR1)
+-	lwz	rWORD4,8(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
+-	lwz	rWORD5,12(rSTR1)
+-	lwz	rWORD6,12(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	bne	cr5,L(dLcr5)
+-	bne	cr0,L(dLcr0)
+-
+-	lwzu	rWORD7,16(rSTR1)
+-	lwzu	rWORD8,16(rSTR2)
+-	bne	cr1,L(dLcr1)
+-	cmplw	cr5,rWORD7,rWORD8
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 8(rSTR1)
++	lwz	rWORD4, 8(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 12(rSTR1)
++	lwz	rWORD6, 12(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++	bne	cr5, L(dLcr5x)
++	bne	cr7, L(dLcr7x)
++
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwzu	rWORD7, 16(rSTR1)
++	lwzu	rWORD8, 16(rSTR2)
++#endif
++	bne	cr1, L(dLcr1)
++	cmplw	cr5, rWORD7, rWORD8
+ 	bdnz	L(dLoop)
+-	bne	cr6,L(dLcr6)
+-	lwz	r30,44(1)
+-	lwz	r31,48(1)
++	bne	cr6, L(dLcr6)
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
+ 	.align	3
+ L(dP1x):
+-	slwi.	r12,rN,3
+-	bne	cr5,L(dLcr5)
+-	subfic	rN,r12,32	/* Shift count is 32 - (rN * 8).  */
+-	lwz	1,0(1)
++	slwi.	r12, rN, 3
++	bne	cr5, L(dLcr5x)
++	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bne	L(d00)
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+ /* Remainder is 8 */
+ 	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dP2):
+-	mtctr	rTMP
+-	lwz	rWORD5,0(rSTR1)
+-	lwz	rWORD6,0(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	blt	cr7,L(dP2x)
+-	lwz	rWORD7,4(rSTR1)
+-	lwz	rWORD8,4(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
++	mtctr	r0
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 0(rSTR1)
++	lwz	rWORD6, 0(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++	blt	cr7, L(dP2x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD7, 4(rSTR1)
++	lwz	rWORD8, 4(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
+ L(dP2e):
+-	lwz	rWORD1,8(rSTR1)
+-	lwz	rWORD2,8(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
+-	lwz	rWORD3,12(rSTR1)
+-	lwz	rWORD4,12(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
+-	addi	rSTR1,rSTR1,4
+-	addi	rSTR2,rSTR2,4
+-	bne	cr6,L(dLcr6)
+-	bne	cr5,L(dLcr5)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 8(rSTR1)
++	lwz	rWORD2, 8(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 12(rSTR1)
++	lwz	rWORD4, 12(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#endif
++	bne	cr6, L(dLcr6)
++	bne	cr5, L(dLcr5)
+ 	b	L(dLoop2)
+ /* Again we are on a early exit path (16-23 byte compare), we want to
+    only use volatile registers and avoid restoring non-volatile
+    registers.  */
+ 	.align	4
+ L(dP2x):
+-	lwz	rWORD3,4(rSTR1)
+-	lwz	rWORD4,4(rSTR2)
+-	cmplw	cr5,rWORD3,rWORD4
+-	slwi.	r12,rN,3
+-	bne	cr6,L(dLcr6)
+-	addi	rSTR1,rSTR1,4
+-	addi	rSTR2,rSTR2,4
+-	bne	cr5,L(dLcr5)
+-	subfic	rN,r12,32	/* Shift count is 32 - (rN * 8).  */
+-	lwz	1,0(1)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++	slwi.	r12, rN, 3
++	bne	cr6, L(dLcr6x)
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#endif
++	bne	cr1, L(dLcr1x)
++	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bne	L(d00)
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+ /* Remainder is 12 */
+ 	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dP3):
+-	mtctr	rTMP
+-	lwz	rWORD3,0(rSTR1)
+-	lwz	rWORD4,0(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
++	mtctr	r0
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 0(rSTR1)
++	lwz	rWORD4, 0(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
+ L(dP3e):
+-	lwz	rWORD5,4(rSTR1)
+-	lwz	rWORD6,4(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	blt	cr7,L(dP3x)
+-	lwz	rWORD7,8(rSTR1)
+-	lwz	rWORD8,8(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
+-	lwz	rWORD1,12(rSTR1)
+-	lwz	rWORD2,12(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
+-	addi	rSTR1,rSTR1,8
+-	addi	rSTR2,rSTR2,8
+-	bne	cr1,L(dLcr1)
+-	bne	cr6,L(dLcr6)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 4(rSTR1)
++	lwz	rWORD6, 4(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++	blt	cr7, L(dP3x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD7, 8(rSTR1)
++	lwz	rWORD8, 8(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 12(rSTR1)
++	lwz	rWORD2, 12(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#endif
++	bne	cr1, L(dLcr1)
++	bne	cr6, L(dLcr6)
+ 	b	L(dLoop1)
+ /* Again we are on a early exit path (24-31 byte compare), we want to
+    only use volatile registers and avoid restoring non-volatile
+    registers.  */
+ 	.align	4
+ L(dP3x):
+-	lwz	rWORD1,8(rSTR1)
+-	lwz	rWORD2,8(rSTR2)
+-	cmplw	cr5,rWORD1,rWORD2
+-	slwi.	r12,rN,3
+-	bne	cr1,L(dLcr1)
+-	addi	rSTR1,rSTR1,8
+-	addi	rSTR2,rSTR2,8
+-	bne	cr6,L(dLcr6)
+-	subfic	rN,r12,32	/* Shift count is 32 - (rN * 8).  */
+-	bne	cr5,L(dLcr5)
+-	lwz	1,0(1)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 8(rSTR1)
++	lwz	rWORD2, 8(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++	slwi.	r12, rN, 3
++	bne	cr1, L(dLcr1x)
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#endif
++	bne	cr6, L(dLcr6x)
++	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
++	bne	cr7, L(dLcr7x)
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bne	L(d00)
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+ /* Count is a multiple of 16, remainder is 0 */
+ 	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dP4):
+-	mtctr	rTMP
+-	lwz	rWORD1,0(rSTR1)
+-	lwz	rWORD2,0(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
++	mtctr	r0
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ L(dP4e):
+-	lwz	rWORD3,4(rSTR1)
+-	lwz	rWORD4,4(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
+-	lwz	rWORD5,8(rSTR1)
+-	lwz	rWORD6,8(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	lwzu	rWORD7,12(rSTR1)
+-	lwzu	rWORD8,12(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
+-	bne	cr0,L(dLcr0)
+-	bne	cr1,L(dLcr1)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 8(rSTR1)
++	lwz	rWORD6, 8(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwzu	rWORD7, 12(rSTR1)
++	lwzu	rWORD8, 12(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
++	bne	cr7, L(dLcr7)
++	bne	cr1, L(dLcr1)
+ 	bdz-	L(d24)		/* Adjust CTR as we start with +4 */
+ /* This is the primary loop */
+ 	.align	4
+ L(dLoop):
+-	lwz	rWORD1,4(rSTR1)
+-	lwz	rWORD2,4(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
+-	bne	cr6,L(dLcr6)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 4(rSTR1)
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++	bne	cr6, L(dLcr6)
+ L(dLoop1):
+-	lwz	rWORD3,8(rSTR1)
+-	lwz	rWORD4,8(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	bne	cr5,L(dLcr5)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 8(rSTR1)
++	lwz	rWORD4, 8(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++	bne	cr5, L(dLcr5)
+ L(dLoop2):
+-	lwz	rWORD5,12(rSTR1)
+-	lwz	rWORD6,12(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
+-	bne	cr0,L(dLcr0)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 12(rSTR1)
++	lwz	rWORD6, 12(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
++	bne	cr7, L(dLcr7)
+ L(dLoop3):
+-	lwzu	rWORD7,16(rSTR1)
+-	lwzu	rWORD8,16(rSTR2)
+-	bne	cr1,L(dLcr1)
+-	cmplw	cr0,rWORD1,rWORD2
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwzu	rWORD7, 16(rSTR1)
++	lwzu	rWORD8, 16(rSTR2)
++#endif
++	bne	cr1, L(dLcr1)
++	cmplw	cr7, rWORD1, rWORD2
+ 	bdnz	L(dLoop)
+ 
+ L(dL4):
+-	cmplw	cr1,rWORD3,rWORD4
+-	bne	cr6,L(dLcr6)
+-	cmplw	cr6,rWORD5,rWORD6
+-	bne	cr5,L(dLcr5)
+-	cmplw	cr5,rWORD7,rWORD8
++	cmplw	cr1, rWORD3, rWORD4
++	bne	cr6, L(dLcr6)
++	cmplw	cr6, rWORD5, rWORD6
++	bne	cr5, L(dLcr5)
++	cmplw	cr5, rWORD7, rWORD8
+ L(d44):
+-	bne	cr0,L(dLcr0)
++	bne	cr7, L(dLcr7)
+ L(d34):
+-	bne	cr1,L(dLcr1)
++	bne	cr1, L(dLcr1)
+ L(d24):
+-	bne	cr6,L(dLcr6)
++	bne	cr6, L(dLcr6)
+ L(d14):
+-	slwi.	r12,rN,3
+-	bne	cr5,L(dLcr5)
++	slwi.	r12, rN, 3
++	bne	cr5, L(dLcr5)
+ L(d04):
+-	lwz	r30,44(1)
+-	lwz	r31,48(1)
+-	lwz	1,0(1)
+-	subfic	rN,r12,32	/* Shift count is 32 - (rN * 8).  */
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
++	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+ 	beq	L(zeroLength)
+ /* At this point we have a remainder of 1 to 3 bytes to compare.  Since
+    we are aligned it is safe to load the whole word, and use
+-   shift right to eliminate bits beyond the compare length. */
++   shift right to eliminate bits beyond the compare length.  */
+ L(d00):
+-	lwz	rWORD1,4(rSTR1)
+-	lwz	rWORD2,4(rSTR2)
+-	srw	rWORD1,rWORD1,rN
+-	srw	rWORD2,rWORD2,rN
+-	cmplw	rWORD1,rWORD2
+-	li	rRTN,0
+-	beqlr
+-	li	rRTN,1
+-	bgtlr
+-	li	rRTN,-1
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 4(rSTR1)
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	srw	rWORD1, rWORD1, rN
++	srw	rWORD2, rWORD2, rN
++	sub	rRTN, rWORD1, rWORD2
+ 	blr
+ 
+ 	.align	4
+-L(dLcr0):
+-	lwz	r30,44(1)
+-	lwz	r31,48(1)
+-	li	rRTN,1
+-	lwz	1,0(1)
+-	bgtlr	cr0
+-	li	rRTN,-1
++	cfi_adjust_cfa_offset(64)
++L(dLcr7):
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++L(dLcr7x):
++	li	rRTN, 1
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
++	bgtlr	cr7
++	li	rRTN, -1
+ 	blr
+ 	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dLcr1):
+-	lwz	r30,44(1)
+-	lwz	r31,48(1)
+-	li	rRTN,1
+-	lwz	1,0(1)
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++L(dLcr1x):
++	li	rRTN, 1
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bgtlr	cr1
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ 	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dLcr6):
+-	lwz	r30,44(1)
+-	lwz	r31,48(1)
+-	li	rRTN,1
+-	lwz	1,0(1)
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
++L(dLcr6x):
++	li	rRTN, 1
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bgtlr	cr6
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ 	.align	4
++	cfi_adjust_cfa_offset(64)
+ L(dLcr5):
+-	lwz	r30,44(1)
+-	lwz	r31,48(1)
++	lwz	rWORD7, 44(r1)
++	lwz	rWORD8, 48(r1)
+ L(dLcr5x):
+-	li	rRTN,1
+-	lwz	1,0(1)
++	li	rRTN, 1
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	bgtlr	cr5
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ 
+ 	.align	4
+ L(bytealigned):
+-	cfi_adjust_cfa_offset(-64)
+ 	mtctr	rN
+ 
+ /* We need to prime this loop.  This loop is swing modulo scheduled
+@@ -413,38 +618,39 @@
+ 
+    So we must precondition some registers and condition codes so that
+    we don't exit the loop early on the first iteration.  */
+-	lbz	rWORD1,0(rSTR1)
+-	lbz	rWORD2,0(rSTR2)
++
++	lbz	rWORD1, 0(rSTR1)
++	lbz	rWORD2, 0(rSTR2)
+ 	bdz	L(b11)
+-	cmplw	cr0,rWORD1,rWORD2
+-	lbz	rWORD3,1(rSTR1)
+-	lbz	rWORD4,1(rSTR2)
++	cmplw	cr7, rWORD1, rWORD2
++	lbz	rWORD3, 1(rSTR1)
++	lbz	rWORD4, 1(rSTR2)
+ 	bdz	L(b12)
+-	cmplw	cr1,rWORD3,rWORD4
+-	lbzu	rWORD5,2(rSTR1)
+-	lbzu	rWORD6,2(rSTR2)
++	cmplw	cr1, rWORD3, rWORD4
++	lbzu	rWORD5, 2(rSTR1)
++	lbzu	rWORD6, 2(rSTR2)
+ 	bdz	L(b13)
+ 	.align	4
+ L(bLoop):
+-	lbzu	rWORD1,1(rSTR1)
+-	lbzu	rWORD2,1(rSTR2)
+-	bne	cr0,L(bLcr0)
++	lbzu	rWORD1, 1(rSTR1)
++	lbzu	rWORD2, 1(rSTR2)
++	bne	cr7, L(bLcr7)
+ 
+-	cmplw	cr6,rWORD5,rWORD6
++	cmplw	cr6, rWORD5, rWORD6
+ 	bdz	L(b3i)
+ 
+-	lbzu	rWORD3,1(rSTR1)
+-	lbzu	rWORD4,1(rSTR2)
+-	bne	cr1,L(bLcr1)
++	lbzu	rWORD3, 1(rSTR1)
++	lbzu	rWORD4, 1(rSTR2)
++	bne	cr1, L(bLcr1)
+ 
+-	cmplw	cr0,rWORD1,rWORD2
++	cmplw	cr7, rWORD1, rWORD2
+ 	bdz	L(b2i)
+ 
+-	lbzu	rWORD5,1(rSTR1)
+-	lbzu	rWORD6,1(rSTR2)
+-	bne	cr6,L(bLcr6)
++	lbzu	rWORD5, 1(rSTR1)
++	lbzu	rWORD6, 1(rSTR2)
++	bne	cr6, L(bLcr6)
+ 
+-	cmplw	cr1,rWORD3,rWORD4
++	cmplw	cr1, rWORD3, rWORD4
+ 	bdnz	L(bLoop)
+ 
+ /* We speculatively loading bytes before we have tested the previous
+@@ -454,67 +660,62 @@
+    tested.  In this case we must complete the pending operations
+    before returning.  */
+ L(b1i):
+-	bne	cr0,L(bLcr0)
+-	bne	cr1,L(bLcr1)
++	bne	cr7, L(bLcr7)
++	bne	cr1, L(bLcr1)
+ 	b	L(bx56)
+ 	.align	4
+ L(b2i):
+-	bne	cr6,L(bLcr6)
+-	bne	cr0,L(bLcr0)
++	bne	cr6, L(bLcr6)
++	bne	cr7, L(bLcr7)
+ 	b	L(bx34)
+ 	.align	4
+ L(b3i):
+-	bne	cr1,L(bLcr1)
+-	bne	cr6,L(bLcr6)
++	bne	cr1, L(bLcr1)
++	bne	cr6, L(bLcr6)
+ 	b	L(bx12)
+ 	.align	4
+-L(bLcr0):
+-	li	rRTN,1
+-	bgtlr	cr0
+-	li	rRTN,-1
++L(bLcr7):
++	li	rRTN, 1
++	bgtlr	cr7
++	li	rRTN, -1
+ 	blr
+ L(bLcr1):
+-	li	rRTN,1
++	li	rRTN, 1
+ 	bgtlr	cr1
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ L(bLcr6):
+-	li	rRTN,1
++	li	rRTN, 1
+ 	bgtlr	cr6
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ 
+ L(b13):
+-	bne	cr0,L(bx12)
+-	bne	cr1,L(bx34)
++	bne	cr7, L(bx12)
++	bne	cr1, L(bx34)
+ L(bx56):
+-	sub	rRTN,rWORD5,rWORD6
++	sub	rRTN, rWORD5, rWORD6
+ 	blr
+ 	nop
+ L(b12):
+-	bne	cr0,L(bx12)
++	bne	cr7, L(bx12)
+ L(bx34):
+-	sub	rRTN,rWORD3,rWORD4
++	sub	rRTN, rWORD3, rWORD4
+ 	blr
+-
+ L(b11):
+ L(bx12):
+-	sub	rRTN,rWORD1,rWORD2
++	sub	rRTN, rWORD1, rWORD2
+ 	blr
+-
+ 	.align	4
+-L(zeroLengthReturn):
+-
+ L(zeroLength):
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+-	cfi_adjust_cfa_offset(64)
+ 	.align	4
+ /* At this point we know the strings have different alignment and the
+-   compare length is at least 8 bytes.  rBITDIF contains the low order
++   compare length is at least 8 bytes.  r12 contains the low order
+    2 bits of rSTR1 and cr5 contains the result of the logical compare
+-   of rBITDIF to 0.  If rBITDIF == 0 then rStr1 is word aligned and can
++   of r12 to 0.  If r12 == 0 then rStr1 is word aligned and can
+    perform the Wunaligned loop.
+ 
+    Otherwise we know that rSTR1 is not aready word aligned yet.
+@@ -523,465 +724,654 @@
+    eliminate bits preceeding the first byte.  Since we want to join the
+    normal (Wualigned) compare loop, starting at the second word,
+    we need to adjust the length (rN) and special case the loop
+-   versioning for the first W. This insures that the loop count is
++   versioning for the first W. This ensures that the loop count is
+    correct and the first W (shifted) is in the expected resister pair.  */
+ #define rSHL		r29	/* Unaligned shift left count.  */
+ #define rSHR		r28	/* Unaligned shift right count.  */
+-#define rB		r27	/* Left rotation temp for rWORD2.  */
+-#define rD		r26	/* Left rotation temp for rWORD4.  */
+-#define rF		r25	/* Left rotation temp for rWORD6.  */
+-#define rH		r24	/* Left rotation temp for rWORD8.  */
+-#define rA		r0	/* Right rotation temp for rWORD2.  */
+-#define rC		r12	/* Right rotation temp for rWORD4.  */
+-#define rE		r0	/* Right rotation temp for rWORD6.  */
+-#define rG		r12	/* Right rotation temp for rWORD8.  */
++#define rWORD8_SHIFT	r27	/* Left rotation temp for rWORD2.  */
++#define rWORD2_SHIFT	r26	/* Left rotation temp for rWORD4.  */
++#define rWORD4_SHIFT	r25	/* Left rotation temp for rWORD6.  */
++#define rWORD6_SHIFT	r24	/* Left rotation temp for rWORD8.  */
++	cfi_adjust_cfa_offset(64)
+ L(unaligned):
+-	stw	r29,40(r1)
+-	cfi_offset(r29,(40-64))
+-	clrlwi	rSHL,rSTR2,30
+-	stw	r28,36(r1)
+-	cfi_offset(r28,(36-64))
+-	beq	cr5,L(Wunaligned)
+-	stw	r27,32(r1)
+-	cfi_offset(r27,(32-64))
++	stw	rSHL, 40(r1)
++	cfi_offset(rSHL, (40-64))
++	clrlwi	rSHL, rSTR2, 30
++	stw	rSHR, 36(r1)
++	cfi_offset(rSHR, (36-64))
++	beq	cr5, L(Wunaligned)
++	stw	rWORD8_SHIFT, 32(r1)
++	cfi_offset(rWORD8_SHIFT, (32-64))
+ /* Adjust the logical start of rSTR2 to compensate for the extra bits
+    in the 1st rSTR1 W.  */
+-	sub	r27,rSTR2,rBITDIF
++	sub	rWORD8_SHIFT, rSTR2, r12
+ /* But do not attempt to address the W before that W that contains
+    the actual start of rSTR2.  */
+-	clrrwi	rSTR2,rSTR2,2
+-	stw	r26,28(r1)
+-	cfi_offset(r26,(28-64))
+-/* Compute the left/right shift counts for the unalign rSTR2,
++	clrrwi	rSTR2, rSTR2, 2
++	stw	rWORD2_SHIFT, 28(r1)
++	cfi_offset(rWORD2_SHIFT, (28-64))
++/* Compute the left/right shift counts for the unaligned rSTR2,
+    compensating for the logical (W aligned) start of rSTR1.  */
+-	clrlwi	rSHL,r27,30
+-	clrrwi	rSTR1,rSTR1,2
+-	stw	r25,24(r1)
+-	cfi_offset(r25,(24-64))
+-	slwi	rSHL,rSHL,3
+-	cmplw	cr5,r27,rSTR2
+-	add	rN,rN,rBITDIF
+-	slwi	r11,rBITDIF,3
+-	stw	r24,20(r1)
+-	cfi_offset(r24,(20-64))
+-	subfic	rSHR,rSHL,32
+-	srwi	rTMP,rN,4	/* Divide by 16 */
+-	andi.	rBITDIF,rN,12	/* Get the W remainder */
++	clrlwi	rSHL, rWORD8_SHIFT, 30
++	clrrwi	rSTR1, rSTR1, 2
++	stw	rWORD4_SHIFT, 24(r1)
++	cfi_offset(rWORD4_SHIFT, (24-64))
++	slwi	rSHL, rSHL, 3
++	cmplw	cr5, rWORD8_SHIFT, rSTR2
++	add	rN, rN, r12
++	slwi	rWORD6, r12, 3
++	stw	rWORD6_SHIFT, 20(r1)
++	cfi_offset(rWORD6_SHIFT, (20-64))
++	subfic	rSHR, rSHL, 32
++	srwi	r0, rN, 4	/* Divide by 16 */
++	andi.	r12, rN, 12	/* Get the W remainder */
+ /* We normally need to load 2 Ws to start the unaligned rSTR2, but in
+    this special case those bits may be discarded anyway.  Also we
+    must avoid loading a W where none of the bits are part of rSTR2 as
+    this may cross a page boundary and cause a page fault.  */
+-	li	rWORD8,0
+-	blt	cr5,L(dus0)
+-	lwz	rWORD8,0(rSTR2)
+-	la	rSTR2,4(rSTR2)
+-	slw	rWORD8,rWORD8,rSHL
++	li	rWORD8, 0
++	blt	cr5, L(dus0)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD8, 0(rSTR2)
++	addi	rSTR2, rSTR2, 4
++#endif
++	slw	rWORD8, rWORD8, rSHL
+ 
+ L(dus0):
+-	lwz	rWORD1,0(rSTR1)
+-	lwz	rWORD2,0(rSTR2)
+-	cmplwi	cr1,rBITDIF,8
+-	cmplwi	cr7,rN,16
+-	srw	rG,rWORD2,rSHR
+-	clrlwi	rN,rN,30
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++#endif
++	cmplwi	cr1, r12, 8
++	cmplwi	cr7, rN, 16
++	srw	r12, rWORD2, rSHR
++	clrlwi	rN, rN, 30
+ 	beq	L(duPs4)
+-	mtctr	rTMP
+-	or	rWORD8,rG,rWORD8
+-	bgt	cr1,L(duPs3)
+-	beq	cr1,L(duPs2)
++	mtctr	r0
++	or	rWORD8, r12, rWORD8
++	bgt	cr1, L(duPs3)
++	beq	cr1, L(duPs2)
+ 
+ /* Remainder is 4 */
+ 	.align	4
+ L(dusP1):
+-	slw	rB,rWORD2,rSHL
+-	slw	rWORD7,rWORD1,r11
+-	slw	rWORD8,rWORD8,r11
+-	bge	cr7,L(duP1e)
++	slw	rWORD8_SHIFT, rWORD2, rSHL
++	slw	rWORD7, rWORD1, rWORD6
++	slw	rWORD8, rWORD8, rWORD6
++	bge	cr7, L(duP1e)
+ /* At this point we exit early with the first word compare
+    complete and remainder of 0 to 3 bytes.  See L(du14) for details on
+    how we handle the remaining bytes.  */
+-	cmplw	cr5,rWORD7,rWORD8
+-	slwi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
+-	cmplw	cr7,rN,rSHR
++	cmplw	cr5, rWORD7, rWORD8
++	slwi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
++	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	lwz	rWORD2,4(rSTR2)
+-	srw	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	srw	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ /* Remainder is 8 */
+ 	.align	4
+ L(duPs2):
+-	slw	rH,rWORD2,rSHL
+-	slw	rWORD5,rWORD1,r11
+-	slw	rWORD6,rWORD8,r11
++	slw	rWORD6_SHIFT, rWORD2, rSHL
++	slw	rWORD5, rWORD1, rWORD6
++	slw	rWORD6, rWORD8, rWORD6
+ 	b	L(duP2e)
+ /* Remainder is 12 */
+ 	.align	4
+ L(duPs3):
+-	slw	rF,rWORD2,rSHL
+-	slw	rWORD3,rWORD1,r11
+-	slw	rWORD4,rWORD8,r11
++	slw	rWORD4_SHIFT, rWORD2, rSHL
++	slw	rWORD3, rWORD1, rWORD6
++	slw	rWORD4, rWORD8, rWORD6
+ 	b	L(duP3e)
+ /* Count is a multiple of 16, remainder is 0 */
+ 	.align	4
+ L(duPs4):
+-	mtctr	rTMP
+-	or	rWORD8,rG,rWORD8
+-	slw	rD,rWORD2,rSHL
+-	slw	rWORD1,rWORD1,r11
+-	slw	rWORD2,rWORD8,r11
++	mtctr	r0
++	or	rWORD8, r12, rWORD8
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	slw	rWORD1, rWORD1, rWORD6
++	slw	rWORD2, rWORD8, rWORD6
+ 	b	L(duP4e)
+ 
+ /* At this point we know rSTR1 is word aligned and the
+    compare length is at least 8 bytes.  */
+ 	.align	4
+ L(Wunaligned):
+-	stw	r27,32(r1)
+-	cfi_offset(r27,(32-64))
+-	clrrwi	rSTR2,rSTR2,2
+-	stw	r26,28(r1)
+-	cfi_offset(r26,(28-64))
+-	srwi	rTMP,rN,4	/* Divide by 16 */
+-	stw	r25,24(r1)
+-	cfi_offset(r25,(24-64))
+-	andi.	rBITDIF,rN,12	/* Get the W remainder */
+-	stw	r24,20(r1)
+-	cfi_offset(r24,(24-64))
+-	slwi	rSHL,rSHL,3
+-	lwz	rWORD6,0(rSTR2)
+-	lwzu	rWORD8,4(rSTR2)
+-	cmplwi	cr1,rBITDIF,8
+-	cmplwi	cr7,rN,16
+-	clrlwi	rN,rN,30
+-	subfic	rSHR,rSHL,32
+-	slw	rH,rWORD6,rSHL
++	stw	rWORD8_SHIFT, 32(r1)
++	cfi_offset(rWORD8_SHIFT, (32-64))
++	clrrwi	rSTR2, rSTR2, 2
++	stw	rWORD2_SHIFT, 28(r1)
++	cfi_offset(rWORD2_SHIFT, (28-64))
++	srwi	r0, rN, 4	/* Divide by 16 */
++	stw	rWORD4_SHIFT, 24(r1)
++	cfi_offset(rWORD4_SHIFT, (24-64))
++	andi.	r12, rN, 12	/* Get the W remainder */
++	stw	rWORD6_SHIFT, 20(r1)
++	cfi_offset(rWORD6_SHIFT, (20-64))
++	slwi	rSHL, rSHL, 3
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD6, 0(rSTR2)
++	lwzu	rWORD8, 4(rSTR2)
++#endif
++	cmplwi	cr1, r12, 8
++	cmplwi	cr7, rN, 16
++	clrlwi	rN, rN, 30
++	subfic	rSHR, rSHL, 32
++	slw	rWORD6_SHIFT, rWORD6, rSHL
+ 	beq	L(duP4)
+-	mtctr	rTMP
+-	bgt	cr1,L(duP3)
+-	beq	cr1,L(duP2)
++	mtctr	r0
++	bgt	cr1, L(duP3)
++	beq	cr1, L(duP2)
+ 
+ /* Remainder is 4 */
+ 	.align	4
+ L(duP1):
+-	srw	rG,rWORD8,rSHR
+-	lwz	rWORD7,0(rSTR1)
+-	slw	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
+-	blt	cr7,L(duP1x)
++	srw	r12, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	addi	rSTR1, rSTR1, 4
++#else
++	lwz	rWORD7, 0(rSTR1)
++#endif
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	blt	cr7, L(duP1x)
+ L(duP1e):
+-	lwz	rWORD1,4(rSTR1)
+-	lwz	rWORD2,4(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
+-	srw	rA,rWORD2,rSHR
+-	slw	rD,rWORD2,rSHL
+-	or	rWORD2,rA,rB
+-	lwz	rWORD3,8(rSTR1)
+-	lwz	rWORD4,8(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
+-	srw	rC,rWORD4,rSHR
+-	slw	rF,rWORD4,rSHL
+-	bne	cr5,L(duLcr5)
+-	or	rWORD4,rC,rD
+-	lwz	rWORD5,12(rSTR1)
+-	lwz	rWORD6,12(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
+-	srw	rE,rWORD6,rSHR
+-	slw	rH,rWORD6,rSHL
+-	bne	cr0,L(duLcr0)
+-	or	rWORD6,rE,rF
+-	cmplw	cr6,rWORD5,rWORD6
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 4(rSTR1)
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
++	srw	r0, rWORD2, rSHR
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 8(rSTR1)
++	lwz	rWORD4, 8(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++	srw	r12, rWORD4, rSHR
++	slw	rWORD4_SHIFT, rWORD4, rSHL
++	bne	cr5, L(duLcr5)
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 12(rSTR1)
++	lwz	rWORD6, 12(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++	srw	r0, rWORD6, rSHR
++	slw	rWORD6_SHIFT, rWORD6, rSHL
++	bne	cr7, L(duLcr7)
++	or	rWORD6, r0, rWORD4_SHIFT
++	cmplw	cr6, rWORD5, rWORD6
+ 	b	L(duLoop3)
+ 	.align	4
+ /* At this point we exit early with the first word compare
+    complete and remainder of 0 to 3 bytes.  See L(du14) for details on
+    how we handle the remaining bytes.  */
+ L(duP1x):
+-	cmplw	cr5,rWORD7,rWORD8
+-	slwi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
+-	cmplw	cr7,rN,rSHR
++	cmplw	cr5, rWORD7, rWORD8
++	slwi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
++	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	ld	rWORD2,8(rSTR2)
+-	srw	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD2, 8(rSTR2)
++#endif
++	srw	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ /* Remainder is 8 */
+ 	.align	4
+ L(duP2):
+-	srw	rE,rWORD8,rSHR
+-	lwz	rWORD5,0(rSTR1)
+-	or	rWORD6,rE,rH
+-	slw	rH,rWORD8,rSHL
++	srw	r0, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	addi	rSTR1, rSTR1, 4
++#else
++	lwz	rWORD5, 0(rSTR1)
++#endif
++	or	rWORD6, r0, rWORD6_SHIFT
++	slw	rWORD6_SHIFT, rWORD8, rSHL
+ L(duP2e):
+-	lwz	rWORD7,4(rSTR1)
+-	lwz	rWORD8,4(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	srw	rG,rWORD8,rSHR
+-	slw	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
+-	blt	cr7,L(duP2x)
+-	lwz	rWORD1,8(rSTR1)
+-	lwz	rWORD2,8(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
+-	bne	cr6,L(duLcr6)
+-	srw	rA,rWORD2,rSHR
+-	slw	rD,rWORD2,rSHL
+-	or	rWORD2,rA,rB
+-	lwz	rWORD3,12(rSTR1)
+-	lwz	rWORD4,12(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
+-	bne	cr5,L(duLcr5)
+-	srw	rC,rWORD4,rSHR
+-	slw	rF,rWORD4,rSHL
+-	or	rWORD4,rC,rD
+-	addi	rSTR1,rSTR1,4
+-	addi	rSTR2,rSTR2,4
+-	cmplw	cr1,rWORD3,rWORD4
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD7, 4(rSTR1)
++	lwz	rWORD8, 4(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++	srw	r12, rWORD8, rSHR
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	blt	cr7, L(duP2x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 8(rSTR1)
++	lwz	rWORD2, 8(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
++	bne	cr6, L(duLcr6)
++	srw	r0, rWORD2, rSHR
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 12(rSTR1)
++	lwz	rWORD4, 12(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++	bne	cr5, L(duLcr5)
++	srw	r12, rWORD4, rSHR
++	slw	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#endif
++	cmplw	cr1, rWORD3, rWORD4
+ 	b	L(duLoop2)
+ 	.align	4
+ L(duP2x):
+-	cmplw	cr5,rWORD7,rWORD8
+-	addi	rSTR1,rSTR1,4
+-	addi	rSTR2,rSTR2,4
+-	bne	cr6,L(duLcr6)
+-	slwi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
+-	cmplw	cr7,rN,rSHR
++	cmplw	cr5, rWORD7, rWORD8
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#endif
++	bne	cr6, L(duLcr6)
++	slwi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
++	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	lwz	rWORD2,4(rSTR2)
+-	srw	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	srw	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ 
+ /* Remainder is 12 */
+ 	.align	4
+ L(duP3):
+-	srw	rC,rWORD8,rSHR
+-	lwz	rWORD3,0(rSTR1)
+-	slw	rF,rWORD8,rSHL
+-	or	rWORD4,rC,rH
++	srw	r12, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	addi	rSTR1, rSTR1, 4
++#else
++	lwz	rWORD3, 0(rSTR1)
++#endif
++	slw	rWORD4_SHIFT, rWORD8, rSHL
++	or	rWORD4, r12, rWORD6_SHIFT
+ L(duP3e):
+-	lwz	rWORD5,4(rSTR1)
+-	lwz	rWORD6,4(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
+-	srw	rE,rWORD6,rSHR
+-	slw	rH,rWORD6,rSHL
+-	or	rWORD6,rE,rF
+-	lwz	rWORD7,8(rSTR1)
+-	lwz	rWORD8,8(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	bne	cr1,L(duLcr1)
+-	srw	rG,rWORD8,rSHR
+-	slw	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
+-	blt	cr7,L(duP3x)
+-	lwz	rWORD1,12(rSTR1)
+-	lwz	rWORD2,12(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
+-	bne	cr6,L(duLcr6)
+-	srw	rA,rWORD2,rSHR
+-	slw	rD,rWORD2,rSHL
+-	or	rWORD2,rA,rB
+-	addi	rSTR1,rSTR1,8
+-	addi	rSTR2,rSTR2,8
+-	cmplw	cr0,rWORD1,rWORD2
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 4(rSTR1)
++	lwz	rWORD6, 4(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++	srw	r0, rWORD6, rSHR
++	slw	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD7, 8(rSTR1)
++	lwz	rWORD8, 8(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++	bne	cr1, L(duLcr1)
++	srw	r12, rWORD8, rSHR
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	blt	cr7, L(duP3x)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 12(rSTR1)
++	lwz	rWORD2, 12(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
++	bne	cr6, L(duLcr6)
++	srw	r0, rWORD2, rSHR
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#endif
++	cmplw	cr7, rWORD1, rWORD2
+ 	b	L(duLoop1)
+ 	.align	4
+ L(duP3x):
+-	addi	rSTR1,rSTR1,8
+-	addi	rSTR2,rSTR2,8
+-	bne	cr1,L(duLcr1)
+-	cmplw	cr5,rWORD7,rWORD8
+-	bne	cr6,L(duLcr6)
+-	slwi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
+-	cmplw	cr7,rN,rSHR
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#endif
++#if 0
++/* Huh?  We've already branched on cr1!  */
++	bne	cr1, L(duLcr1)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
++	bne	cr6, L(duLcr6)
++	slwi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
++	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	lwz	rWORD2,4(rSTR2)
+-	srw	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	srw	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ 
+ /* Count is a multiple of 16, remainder is 0 */
+ 	.align	4
+ L(duP4):
+-	mtctr	rTMP
+-	srw	rA,rWORD8,rSHR
+-	lwz	rWORD1,0(rSTR1)
+-	slw	rD,rWORD8,rSHL
+-	or	rWORD2,rA,rH
++	mtctr	r0
++	srw	r0, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	addi	rSTR1, rSTR1, 4
++#else
++	lwz	rWORD1, 0(rSTR1)
++#endif
++	slw	rWORD2_SHIFT, rWORD8, rSHL
++	or	rWORD2, r0, rWORD6_SHIFT
+ L(duP4e):
+-	lwz	rWORD3,4(rSTR1)
+-	lwz	rWORD4,4(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
+-	srw	rC,rWORD4,rSHR
+-	slw	rF,rWORD4,rSHL
+-	or	rWORD4,rC,rD
+-	lwz	rWORD5,8(rSTR1)
+-	lwz	rWORD6,8(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
+-	bne	cr0,L(duLcr0)
+-	srw	rE,rWORD6,rSHR
+-	slw	rH,rWORD6,rSHL
+-	or	rWORD6,rE,rF
+-	lwzu	rWORD7,12(rSTR1)
+-	lwzu	rWORD8,12(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	bne	cr1,L(duLcr1)
+-	srw	rG,rWORD8,rSHR
+-	slw	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
+-	cmplw	cr5,rWORD7,rWORD8
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++	srw	r12, rWORD4, rSHR
++	slw	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 8(rSTR1)
++	lwz	rWORD6, 8(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++	bne	cr7, L(duLcr7)
++	srw	r0, rWORD6, rSHR
++	slw	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwzu	rWORD7, 12(rSTR1)
++	lwzu	rWORD8, 12(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++	bne	cr1, L(duLcr1)
++	srw	r12, rWORD8, rSHR
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	cmplw	cr5, rWORD7, rWORD8
+ 	bdz	L(du24)		/* Adjust CTR as we start with +4 */
+ /* This is the primary loop */
+ 	.align	4
+ L(duLoop):
+-	lwz	rWORD1,4(rSTR1)
+-	lwz	rWORD2,4(rSTR2)
+-	cmplw	cr1,rWORD3,rWORD4
+-	bne	cr6,L(duLcr6)
+-	srw	rA,rWORD2,rSHR
+-	slw	rD,rWORD2,rSHL
+-	or	rWORD2,rA,rB
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD1, 4(rSTR1)
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++	bne	cr6, L(duLcr6)
++	srw	r0, rWORD2, rSHR
++	slw	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
+ L(duLoop1):
+-	lwz	rWORD3,8(rSTR1)
+-	lwz	rWORD4,8(rSTR2)
+-	cmplw	cr6,rWORD5,rWORD6
+-	bne	cr5,L(duLcr5)
+-	srw	rC,rWORD4,rSHR
+-	slw	rF,rWORD4,rSHL
+-	or	rWORD4,rC,rD
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD3, 0, rSTR1
++	lwbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD3, 8(rSTR1)
++	lwz	rWORD4, 8(rSTR2)
++#endif
++	cmplw	cr6, rWORD5, rWORD6
++	bne	cr5, L(duLcr5)
++	srw	r12, rWORD4, rSHR
++	slw	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
+ L(duLoop2):
+-	lwz	rWORD5,12(rSTR1)
+-	lwz	rWORD6,12(rSTR2)
+-	cmplw	cr5,rWORD7,rWORD8
+-	bne	cr0,L(duLcr0)
+-	srw	rE,rWORD6,rSHR
+-	slw	rH,rWORD6,rSHL
+-	or	rWORD6,rE,rF
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD5, 0, rSTR1
++	lwbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD5, 12(rSTR1)
++	lwz	rWORD6, 12(rSTR2)
++#endif
++	cmplw	cr5, rWORD7, rWORD8
++	bne	cr7, L(duLcr7)
++	srw	r0, rWORD6, rSHR
++	slw	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
+ L(duLoop3):
+-	lwzu	rWORD7,16(rSTR1)
+-	lwzu	rWORD8,16(rSTR2)
+-	cmplw	cr0,rWORD1,rWORD2
+-	bne	cr1,L(duLcr1)
+-	srw	rG,rWORD8,rSHR
+-	slw	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD7, 0, rSTR1
++	lwbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 4
++	addi	rSTR2, rSTR2, 4
++#else
++	lwzu	rWORD7, 16(rSTR1)
++	lwzu	rWORD8, 16(rSTR2)
++#endif
++	cmplw	cr7, rWORD1, rWORD2
++	bne	cr1, L(duLcr1)
++	srw	r12, rWORD8, rSHR
++	slw	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	bdnz	L(duLoop)
+ 
+ L(duL4):
+-	bne	cr1,L(duLcr1)
+-	cmplw	cr1,rWORD3,rWORD4
+-	bne	cr6,L(duLcr6)
+-	cmplw	cr6,rWORD5,rWORD6
+-	bne	cr5,L(duLcr5)
+-	cmplw	cr5,rWORD7,rWORD8
++#if 0
++/* Huh?  We've already branched on cr1!  */
++	bne	cr1, L(duLcr1)
++#endif
++	cmplw	cr1, rWORD3, rWORD4
++	bne	cr6, L(duLcr6)
++	cmplw	cr6, rWORD5, rWORD6
++	bne	cr5, L(duLcr5)
++	cmplw	cr5, rWORD7, rWORD8
+ L(du44):
+-	bne	cr0,L(duLcr0)
++	bne	cr7, L(duLcr7)
+ L(du34):
+-	bne	cr1,L(duLcr1)
++	bne	cr1, L(duLcr1)
+ L(du24):
+-	bne	cr6,L(duLcr6)
++	bne	cr6, L(duLcr6)
+ L(du14):
+-	slwi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
++	slwi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
+ /* At this point we have a remainder of 1 to 3 bytes to compare.  We use
+    shift right to eliminate bits beyond the compare length.
++   This allows the use of word subtract to compute the final result.
+ 
+    However it may not be safe to load rWORD2 which may be beyond the
+    string length. So we compare the bit length of the remainder to
+    the right shift count (rSHR). If the bit count is less than or equal
+    we do not need to load rWORD2 (all significant bits are already in
+-   rB).  */
+-	cmplw	cr7,rN,rSHR
++   rWORD8_SHIFT).  */
++	cmplw	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	lwz	rWORD2,4(rSTR2)
+-	srw	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 4
++#else
++	lwz	rWORD2, 4(rSTR2)
++#endif
++	srw	r0, rWORD2, rSHR
+ 	.align	4
+ L(dutrim):
+-	lwz	rWORD1,4(rSTR1)
+-	lwz	r31,48(1)
+-	subfic	rN,rN,32	/* Shift count is 32 - (rN * 8).  */
+-	or	rWORD2,rA,rB
+-	lwz	r30,44(1)
+-	lwz	r29,40(r1)
+-	srw	rWORD1,rWORD1,rN
+-	srw	rWORD2,rWORD2,rN
+-	lwz	r28,36(r1)
+-	lwz	r27,32(r1)
+-	cmplw	rWORD1,rWORD2
+-	li	rRTN,0
+-	beq	L(dureturn26)
+-	li	rRTN,1
+-	bgt	L(dureturn26)
+-	li	rRTN,-1
++#ifdef __LITTLE_ENDIAN__
++	lwbrx	rWORD1, 0, rSTR1
++#else
++	lwz	rWORD1, 4(rSTR1)
++#endif
++	lwz	rWORD8, 48(r1)
++	subfic	rN, rN, 32	/* Shift count is 32 - (rN * 8).  */
++	or	rWORD2, r0, rWORD8_SHIFT
++	lwz	rWORD7, 44(r1)
++	lwz	rSHL, 40(r1)
++	srw	rWORD1, rWORD1, rN
++	srw	rWORD2, rWORD2, rN
++	lwz	rSHR, 36(r1)
++	lwz	rWORD8_SHIFT, 32(r1)
++	sub	rRTN, rWORD1, rWORD2
+ 	b	L(dureturn26)
+ 	.align	4
+-L(duLcr0):
+-	lwz	r31,48(1)
+-	lwz	r30,44(1)
+-	li	rRTN,1
+-	bgt	cr0,L(dureturn29)
+-	lwz	r29,40(r1)
+-	lwz	r28,36(r1)
+-	li	rRTN,-1
++L(duLcr7):
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
++	li	rRTN, 1
++	bgt	cr7, L(dureturn29)
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
++	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	4
+ L(duLcr1):
+-	lwz	r31,48(1)
+-	lwz	r30,44(1)
+-	li	rRTN,1
+-	bgt	cr1,L(dureturn29)
+-	lwz	r29,40(r1)
+-	lwz	r28,36(r1)
+-	li	rRTN,-1
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
++	li	rRTN, 1
++	bgt	cr1, L(dureturn29)
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
++	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	4
+ L(duLcr6):
+-	lwz	r31,48(1)
+-	lwz	r30,44(1)
+-	li	rRTN,1
+-	bgt	cr6,L(dureturn29)
+-	lwz	r29,40(r1)
+-	lwz	r28,36(r1)
+-	li	rRTN,-1
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
++	li	rRTN, 1
++	bgt	cr6, L(dureturn29)
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
++	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	4
+ L(duLcr5):
+-	lwz	r31,48(1)
+-	lwz	r30,44(1)
+-	li	rRTN,1
+-	bgt	cr5,L(dureturn29)
+-	lwz	r29,40(r1)
+-	lwz	r28,36(r1)
+-	li	rRTN,-1
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
++	li	rRTN, 1
++	bgt	cr5, L(dureturn29)
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
++	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	3
+ L(duZeroReturn):
+-	li	rRTN,0
++	li	rRTN, 0
+ 	.align	4
+ L(dureturn):
+-	lwz	r31,48(1)
+-	lwz	r30,44(1)
++	lwz	rWORD8, 48(r1)
++	lwz	rWORD7, 44(r1)
+ L(dureturn29):
+-	lwz	r29,40(r1)
+-	lwz	r28,36(r1)
++	lwz	rSHL, 40(r1)
++	lwz	rSHR, 36(r1)
+ L(dureturn27):
+-	lwz	r27,32(r1)
++	lwz	rWORD8_SHIFT, 32(r1)
+ L(dureturn26):
+-	lwz	r26,28(r1)
++	lwz	rWORD2_SHIFT, 28(r1)
+ L(dureturn25):
+-	lwz	r25,24(r1)
+-	lwz	r24,20(r1)
+-	lwz	1,0(1)
++	lwz	rWORD4_SHIFT, 24(r1)
++	lwz	rWORD6_SHIFT, 20(r1)
++	addi	r1, r1, 64
++	cfi_adjust_cfa_offset(-64)
+ 	blr
+ END (BP_SYM (memcmp))
++
+ libc_hidden_builtin_def (memcmp)
+ weak_alias (memcmp,bcmp)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power4/memcmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power4/memcmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power4/memcmp.S	2014-05-28 19:22:37.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power4/memcmp.S	2014-05-29 09:35:25.000000000 -0500
+@@ -1,5 +1,5 @@
+-/* Optimized strcmp implementation for PowerPC64.
+-   Copyright (C) 2003, 2006, 2011 Free Software Foundation, Inc.
++/* Optimized memcmp implementation for PowerPC64.
++   Copyright (C) 2003-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
+@@ -17,307 +17,492 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+-/* int [r3] memcmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
++/* int [r3] memcmp (const char *s1 [r3],
++		    const char *s2 [r4],
++		    size_t size [r5])  */
+ 
+ 	.machine power4
+-EALIGN (BP_SYM(memcmp), 4, 0)
++EALIGN (memcmp, 4, 0)
+ 	CALL_MCOUNT 3
+ 
+-#define rTMP	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+ #define rN	r5	/* max string length */
+-/* Note:  The Bounded pointer support in this code is broken.  This code
+-   was inherited from PPC32 and that support was never completed.
+-   Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
+ #define rWORD1	r6	/* current word in s1 */
+ #define rWORD2	r7	/* current word in s2 */
+ #define rWORD3	r8	/* next word in s1 */
+ #define rWORD4	r9	/* next word in s2 */
+ #define rWORD5	r10	/* next word in s1 */
+ #define rWORD6	r11	/* next word in s2 */
+-#define rBITDIF	r12	/* bits that differ in s1 & s2 words */
+ #define rWORD7	r30	/* next word in s1 */
+ #define rWORD8	r31	/* next word in s2 */
+ 
+-	xor	rTMP, rSTR2, rSTR1
++	xor	r0, rSTR2, rSTR1
+ 	cmpldi	cr6, rN, 0
+ 	cmpldi	cr1, rN, 12
+-	clrldi.	rTMP, rTMP, 61
+-	clrldi	rBITDIF, rSTR1, 61
+-	cmpldi	cr5, rBITDIF, 0
++	clrldi.	r0, r0, 61
++	clrldi	r12, rSTR1, 61
++	cmpldi	cr5, r12, 0
+ 	beq-	cr6, L(zeroLength)
+-	dcbt	0,rSTR1
+-	dcbt	0,rSTR2
+-/* If less than 8 bytes or not aligned, use the unalligned
++	dcbt	0, rSTR1
++	dcbt	0, rSTR2
++/* If less than 8 bytes or not aligned, use the unaligned
+    byte loop.  */
+ 	blt	cr1, L(bytealigned)
+-	std	rWORD8,-8(r1)	
+-	cfi_offset(rWORD8,-8)
+-	std	rWORD7,-16(r1)	
+-	cfi_offset(rWORD7,-16)
++	std	rWORD8, -8(r1)
++	cfi_offset(rWORD8, -8)
++	std	rWORD7, -16(r1)
++	cfi_offset(rWORD7, -16)
+ 	bne	L(unaligned)
+ /* At this point we know both strings have the same alignment and the
+-   compare length is at least 8 bytes.  rBITDIF containes the low order
++   compare length is at least 8 bytes.  r12 contains the low order
+    3 bits of rSTR1 and cr5 contains the result of the logical compare
+-   of rBITDIF to 0.  If rBITDIF == 0 then we are already double word 
+-   aligned and can perform the DWaligned loop.
+-  
++   of r12 to 0.  If r12 == 0 then we are already double word
++   aligned and can perform the DW aligned loop.
++
+    Otherwise we know the two strings have the same alignment (but not
+-   yet DW).  So we can force the string addresses to the next lower DW
+-   boundary and special case this first DW word using shift left to
+-   ellimiate bits preceeding the first byte.  Since we want to join the
+-   normal (DWaligned) compare loop, starting at the second double word,
++   yet DW).  So we force the string addresses to the next lower DW
++   boundary and special case this first DW using shift left to
++   eliminate bits preceding the first byte.  Since we want to join the
++   normal (DW aligned) compare loop, starting at the second double word,
+    we need to adjust the length (rN) and special case the loop
+-   versioning for the first DW. This insures that the loop count is
+-   correct and the first DW (shifted) is in the expected resister pair.  */
+-	.align 4
++   versioning for the first DW. This ensures that the loop count is
++   correct and the first DW (shifted) is in the expected register pair.  */
++	.align	4
+ L(samealignment):
+ 	clrrdi	rSTR1, rSTR1, 3
+ 	clrrdi	rSTR2, rSTR2, 3
+ 	beq	cr5, L(DWaligned)
+-	add	rN, rN, rBITDIF
+-	sldi	r11, rBITDIF, 3
+-	srdi	rTMP, rN, 5	/* Divide by 32 */
+-	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
++	add	rN, rN, r12
++	sldi	rWORD6, r12, 3
++	srdi	r0, rN, 5	/* Divide by 32 */
++	andi.	r12, rN, 24	/* Get the DW remainder */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 0(rSTR1)
+ 	ld	rWORD2, 0(rSTR2)
+-	cmpldi	cr1, rBITDIF, 16
++#endif
++	cmpldi	cr1, r12, 16
+ 	cmpldi	cr7, rN, 32
+ 	clrldi	rN, rN, 61
+ 	beq	L(dPs4)
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
+ 	bgt	cr1, L(dPs3)
+ 	beq	cr1, L(dPs2)
+ 
+ /* Remainder is 8 */
+-	.align 3
++	.align	3
+ L(dsP1):
+-	sld	rWORD5, rWORD1, r11
+-	sld	rWORD6, rWORD2, r11
++	sld	rWORD5, rWORD1, rWORD6
++	sld	rWORD6, rWORD2, rWORD6
+ 	cmpld	cr5, rWORD5, rWORD6
+ 	blt	cr7, L(dP1x)
+ /* Do something useful in this cycle since we have to branch anyway.  */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 8(rSTR1)
+ 	ld	rWORD2, 8(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ 	b	L(dP1e)
+ /* Remainder is 16 */
+-	.align 4
++	.align	4
+ L(dPs2):
+-	sld	rWORD5, rWORD1, r11
+-	sld	rWORD6, rWORD2, r11
++	sld	rWORD5, rWORD1, rWORD6
++	sld	rWORD6, rWORD2, rWORD6
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	blt	cr7, L(dP2x)
+ /* Do something useful in this cycle since we have to branch anyway.  */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD7, 8(rSTR1)
+ 	ld	rWORD8, 8(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+ 	b	L(dP2e)
+ /* Remainder is 24 */
+-	.align 4
++	.align	4
+ L(dPs3):
+-	sld	rWORD3, rWORD1, r11
+-	sld	rWORD4, rWORD2, r11
++	sld	rWORD3, rWORD1, rWORD6
++	sld	rWORD4, rWORD2, rWORD6
+ 	cmpld	cr1, rWORD3, rWORD4
+ 	b	L(dP3e)
+ /* Count is a multiple of 32, remainder is 0 */
+-	.align 4
++	.align	4
+ L(dPs4):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+-	sld	rWORD1, rWORD1, r11
+-	sld	rWORD2, rWORD2, r11
+-	cmpld	cr0, rWORD1, rWORD2
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++	sld	rWORD1, rWORD1, rWORD6
++	sld	rWORD2, rWORD2, rWORD6
++	cmpld	cr7, rWORD1, rWORD2
+ 	b	L(dP4e)
+ 
+ /* At this point we know both strings are double word aligned and the
+    compare length is at least 8 bytes.  */
+-	.align 4
++	.align	4
+ L(DWaligned):
+-	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
+-	srdi	rTMP, rN, 5	/* Divide by 32 */
+-	cmpldi	cr1, rBITDIF, 16
++	andi.	r12, rN, 24	/* Get the DW remainder */
++	srdi	r0, rN, 5	/* Divide by 32 */
++	cmpldi	cr1, r12, 16
+ 	cmpldi	cr7, rN, 32
+ 	clrldi	rN, rN, 61
+ 	beq	L(dP4)
+ 	bgt	cr1, L(dP3)
+ 	beq	cr1, L(dP2)
+-		
++
+ /* Remainder is 8 */
+-	.align 4
++	.align	4
+ L(dP1):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
+ /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early
+-   (8-15 byte compare), we want to use only volitile registers.  This
+-   means we can avoid restoring non-volitile registers since we did not
++   (8-15 byte compare), we want to use only volatile registers.  This
++   means we can avoid restoring non-volatile registers since we did not
+    change any on the early exit path.  The key here is the non-early
+-   exit path only cares about the condition code (cr5), not about which 
++   exit path only cares about the condition code (cr5), not about which
+    register pair was used.  */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 0(rSTR1)
+ 	ld	rWORD6, 0(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD5, rWORD6
+ 	blt	cr7, L(dP1x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 8(rSTR1)
+ 	ld	rWORD2, 8(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ L(dP1e):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 16(rSTR1)
+ 	ld	rWORD4, 16(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 24(rSTR1)
+ 	ld	rWORD6, 24(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
+-	bne	cr5, L(dLcr5)
+-	bne	cr0, L(dLcr0)
+-	
++	bne	cr5, L(dLcr5x)
++	bne	cr7, L(dLcr7x)
++
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ldu	rWORD7, 32(rSTR1)
+ 	ldu	rWORD8, 32(rSTR2)
++#endif
+ 	bne	cr1, L(dLcr1)
+ 	cmpld	cr5, rWORD7, rWORD8
+ 	bdnz	L(dLoop)
+ 	bne	cr6, L(dLcr6)
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	.align 3
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++	.align	3
+ L(dP1x):
+ 	sldi.	r12, rN, 3
+-	bne	cr5, L(dLcr5)
++	bne	cr5, L(dLcr5x)
+ 	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+ 	bne	L(d00)
+ 	li	rRTN, 0
+ 	blr
+-		
++
+ /* Remainder is 16 */
+-	.align 4
++	.align	4
+ L(dP2):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 0(rSTR1)
+ 	ld	rWORD6, 0(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	blt	cr7, L(dP2x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD7, 8(rSTR1)
+ 	ld	rWORD8, 8(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+ L(dP2e):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 16(rSTR1)
+ 	ld	rWORD2, 16(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 24(rSTR1)
+ 	ld	rWORD4, 24(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 8
+ 	addi	rSTR2, rSTR2, 8
++#endif
+ 	bne	cr6, L(dLcr6)
+ 	bne	cr5, L(dLcr5)
+ 	b	L(dLoop2)
+ /* Again we are on a early exit path (16-23 byte compare), we want to
+-   only use volitile registers and avoid restoring non-volitile
++   only use volatile registers and avoid restoring non-volatile
+    registers.  */
+-	.align 4
++	.align	4
+ L(dP2x):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 8(rSTR1)
+ 	ld	rWORD4, 8(rSTR2)
+-	cmpld	cr5, rWORD3, rWORD4
++#endif
++	cmpld	cr1, rWORD3, rWORD4
+ 	sldi.	r12, rN, 3
+-	bne	cr6, L(dLcr6)
++	bne	cr6, L(dLcr6x)
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 8
+ 	addi	rSTR2, rSTR2, 8
+-	bne	cr5, L(dLcr5)
++#endif
++	bne	cr1, L(dLcr1x)
+ 	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+ 	bne	L(d00)
+ 	li	rRTN, 0
+ 	blr
+-		
++
+ /* Remainder is 24 */
+-	.align 4
++	.align	4
+ L(dP3):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 0(rSTR1)
+ 	ld	rWORD4, 0(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
+ L(dP3e):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 8(rSTR1)
+ 	ld	rWORD6, 8(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	blt	cr7, L(dP3x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD7, 16(rSTR1)
+ 	ld	rWORD8, 16(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 24(rSTR1)
+ 	ld	rWORD2, 24(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 16
+ 	addi	rSTR2, rSTR2, 16
++#endif
+ 	bne	cr1, L(dLcr1)
+ 	bne	cr6, L(dLcr6)
+ 	b	L(dLoop1)
+ /* Again we are on a early exit path (24-31 byte compare), we want to
+-   only use volitile registers and avoid restoring non-volitile
++   only use volatile registers and avoid restoring non-volatile
+    registers.  */
+-	.align 4
++	.align	4
+ L(dP3x):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 16(rSTR1)
+ 	ld	rWORD2, 16(rSTR2)
+-	cmpld	cr5, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ 	sldi.	r12, rN, 3
+-	bne	cr1, L(dLcr1)
++	bne	cr1, L(dLcr1x)
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 16
+ 	addi	rSTR2, rSTR2, 16
+-	bne	cr6, L(dLcr6)
++#endif
++	bne	cr6, L(dLcr6x)
+ 	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+-	bne	cr5, L(dLcr5)
++	bne	cr7, L(dLcr7x)
+ 	bne	L(d00)
+ 	li	rRTN, 0
+ 	blr
+-	
++
+ /* Count is a multiple of 32, remainder is 0 */
+-	.align 4
++	.align	4
+ L(dP4):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 0(rSTR1)
+ 	ld	rWORD2, 0(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ L(dP4e):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 8(rSTR1)
+ 	ld	rWORD4, 8(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 16(rSTR1)
+ 	ld	rWORD6, 16(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ldu	rWORD7, 24(rSTR1)
+ 	ldu	rWORD8, 24(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+-	bne	cr0, L(dLcr0)
++	bne	cr7, L(dLcr7)
+ 	bne	cr1, L(dLcr1)
+ 	bdz-	L(d24)		/* Adjust CTR as we start with +4 */
+ /* This is the primary loop */
+-	.align 4
++	.align	4
+ L(dLoop):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 8(rSTR1)
+ 	ld	rWORD2, 8(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
+ 	bne	cr6, L(dLcr6)
+ L(dLoop1):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 16(rSTR1)
+ 	ld	rWORD4, 16(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	bne	cr5, L(dLcr5)
+ L(dLoop2):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 24(rSTR1)
+ 	ld	rWORD6, 24(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+-	bne	cr0, L(dLcr0)
++	bne	cr7, L(dLcr7)
+ L(dLoop3):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ldu	rWORD7, 32(rSTR1)
+ 	ldu	rWORD8, 32(rSTR2)
++#endif
+ 	bne-	cr1, L(dLcr1)
+-	cmpld	cr0, rWORD1, rWORD2
+-	bdnz+	L(dLoop)	
+-	
++	cmpld	cr7, rWORD1, rWORD2
++	bdnz+	L(dLoop)
++
+ L(dL4):
+ 	cmpld	cr1, rWORD3, rWORD4
+ 	bne	cr6, L(dLcr6)
+@@ -325,84 +510,98 @@
+ 	bne	cr5, L(dLcr5)
+ 	cmpld	cr5, rWORD7, rWORD8
+ L(d44):
+-	bne	cr0, L(dLcr0)
++	bne	cr7, L(dLcr7)
+ L(d34):
+ 	bne	cr1, L(dLcr1)
+ L(d24):
+ 	bne	cr6, L(dLcr6)
+ L(d14):
+ 	sldi.	r12, rN, 3
+-	bne	cr5, L(dLcr5) 
++	bne	cr5, L(dLcr5)
+ L(d04):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
+ 	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+ 	beq	L(zeroLength)
+ /* At this point we have a remainder of 1 to 7 bytes to compare.  Since
+    we are aligned it is safe to load the whole double word, and use
+-   shift right double to elliminate bits beyond the compare length.  */ 
++   shift right double to eliminate bits beyond the compare length.  */
+ L(d00):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 8(rSTR1)
+-	ld	rWORD2, 8(rSTR2) 
++	ld	rWORD2, 8(rSTR2)
++#endif
+ 	srd	rWORD1, rWORD1, rN
+ 	srd	rWORD2, rWORD2, rN
+-	cmpld	cr5, rWORD1, rWORD2
+- 	bne	cr5, L(dLcr5x)
++	cmpld	cr7, rWORD1, rWORD2
++	bne	cr7, L(dLcr7x)
+ 	li	rRTN, 0
+ 	blr
+-	.align 4
+-L(dLcr0):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++
++	.align	4
++L(dLcr7):
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++L(dLcr7x):
+ 	li	rRTN, 1
+-	bgtlr	cr0
++	bgtlr	cr7
+ 	li	rRTN, -1
+ 	blr
+-	.align 4
++	.align	4
+ L(dLcr1):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++L(dLcr1x):
+ 	li	rRTN, 1
+ 	bgtlr	cr1
+ 	li	rRTN, -1
+ 	blr
+-	.align 4
++	.align	4
+ L(dLcr6):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++L(dLcr6x):
+ 	li	rRTN, 1
+ 	bgtlr	cr6
+ 	li	rRTN, -1
+ 	blr
+-	.align 4
++	.align	4
+ L(dLcr5):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
+ L(dLcr5x):
+ 	li	rRTN, 1
+ 	bgtlr	cr5
+ 	li	rRTN, -1
+ 	blr
+-	
+-	.align 4
++
++	.align	4
+ L(bytealigned):
+-	mtctr   rN	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	rN	/* Power4 wants mtctr 1st in dispatch group */
++#if 0
++/* Huh?  We've already branched on cr6!  */
+ 	beq-	cr6, L(zeroLength)
++#endif
+ 
+ /* We need to prime this loop.  This loop is swing modulo scheduled
+-   to avoid pipe delays.  The dependent instruction latencies (load to 
++   to avoid pipe delays.  The dependent instruction latencies (load to
+    compare to conditional branch) is 2 to 3 cycles.  In this loop each
+    dispatch group ends in a branch and takes 1 cycle.  Effectively
+-   the first iteration of the loop only serves to load operands and 
+-   branches based on compares are delayed until the next loop. 
++   the first iteration of the loop only serves to load operands and
++   branches based on compares are delayed until the next loop.
+ 
+    So we must precondition some registers and condition codes so that
+    we don't exit the loop early on the first iteration.  */
+-   
++
+ 	lbz	rWORD1, 0(rSTR1)
+ 	lbz	rWORD2, 0(rSTR2)
+ 	bdz-	L(b11)
+-	cmpld	cr0, rWORD1, rWORD2
++	cmpld	cr7, rWORD1, rWORD2
+ 	lbz	rWORD3, 1(rSTR1)
+ 	lbz	rWORD4, 1(rSTR2)
+ 	bdz-	L(b12)
+@@ -410,20 +609,20 @@
+ 	lbzu	rWORD5, 2(rSTR1)
+ 	lbzu	rWORD6, 2(rSTR2)
+ 	bdz-	L(b13)
+-	.align 4
++	.align	4
+ L(bLoop):
+ 	lbzu	rWORD1, 1(rSTR1)
+ 	lbzu	rWORD2, 1(rSTR2)
+-	bne-	cr0, L(bLcr0)
++	bne-	cr7, L(bLcr7)
+ 
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	bdz-	L(b3i)
+-	
++
+ 	lbzu	rWORD3, 1(rSTR1)
+ 	lbzu	rWORD4, 1(rSTR2)
+ 	bne-	cr1, L(bLcr1)
+ 
+-	cmpld	cr0, rWORD1, rWORD2
++	cmpld	cr7, rWORD1, rWORD2
+ 	bdz-	L(b2i)
+ 
+ 	lbzu	rWORD5, 1(rSTR1)
+@@ -432,31 +631,31 @@
+ 
+ 	cmpld	cr1, rWORD3, rWORD4
+ 	bdnz+	L(bLoop)
+-	
++
+ /* We speculatively loading bytes before we have tested the previous
+    bytes.  But we must avoid overrunning the length (in the ctr) to
+-   prevent these speculative loads from causing a segfault.  In this 
++   prevent these speculative loads from causing a segfault.  In this
+    case the loop will exit early (before the all pending bytes are
+    tested.  In this case we must complete the pending operations
+    before returning.  */
+ L(b1i):
+-	bne-	cr0, L(bLcr0)
++	bne-	cr7, L(bLcr7)
+ 	bne-	cr1, L(bLcr1)
+ 	b	L(bx56)
+-	.align 4
++	.align	4
+ L(b2i):
+ 	bne-	cr6, L(bLcr6)
+-	bne-	cr0, L(bLcr0)
++	bne-	cr7, L(bLcr7)
+ 	b	L(bx34)
+-	.align 4
++	.align	4
+ L(b3i):
+ 	bne-	cr1, L(bLcr1)
+ 	bne-	cr6, L(bLcr6)
+ 	b	L(bx12)
+-	.align 4
+-L(bLcr0):
++	.align	4
++L(bLcr7):
+ 	li	rRTN, 1
+-	bgtlr	cr0
++	bgtlr	cr7
+ 	li	rRTN, -1
+ 	blr
+ L(bLcr1):
+@@ -471,116 +670,121 @@
+ 	blr
+ 
+ L(b13):
+-	bne-	cr0, L(bx12)
++	bne-	cr7, L(bx12)
+ 	bne-	cr1, L(bx34)
+ L(bx56):
+ 	sub	rRTN, rWORD5, rWORD6
+ 	blr
+ 	nop
+ L(b12):
+-	bne-	cr0, L(bx12)
+-L(bx34):	
++	bne-	cr7, L(bx12)
++L(bx34):
+ 	sub	rRTN, rWORD3, rWORD4
+ 	blr
+ L(b11):
+ L(bx12):
+ 	sub	rRTN, rWORD1, rWORD2
+ 	blr
+-	.align 4 
+-L(zeroLengthReturn):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	.align	4
+ L(zeroLength):
+ 	li	rRTN, 0
+ 	blr
+ 
+-	.align 4
++	.align	4
+ /* At this point we know the strings have different alignment and the
+-   compare length is at least 8 bytes.  rBITDIF containes the low order
++   compare length is at least 8 bytes.  r12 contains the low order
+    3 bits of rSTR1 and cr5 contains the result of the logical compare
+-   of rBITDIF to 0.  If rBITDIF == 0 then rStr1 is double word 
++   of r12 to 0.  If r12 == 0 then rStr1 is double word
+    aligned and can perform the DWunaligned loop.
+-  
+-   Otherwise we know that rSTR1 is not aready DW aligned yet.
++
++   Otherwise we know that rSTR1 is not already DW aligned yet.
+    So we can force the string addresses to the next lower DW
+-   boundary and special case this first DW word using shift left to
+-   ellimiate bits preceeding the first byte.  Since we want to join the
++   boundary and special case this first DW using shift left to
++   eliminate bits preceding the first byte.  Since we want to join the
+    normal (DWaligned) compare loop, starting at the second double word,
+    we need to adjust the length (rN) and special case the loop
+-   versioning for the first DW. This insures that the loop count is
++   versioning for the first DW. This ensures that the loop count is
+    correct and the first DW (shifted) is in the expected resister pair.  */
+-#define rSHL	r29	/* Unaligned shift left count.  */
+-#define rSHR	r28	/* Unaligned shift right count.  */
+-#define rB		r27	/* Left rotation temp for rWORD2.  */
+-#define rD		r26	/* Left rotation temp for rWORD4.  */
+-#define rF		r25	/* Left rotation temp for rWORD6.  */
+-#define rH		r24	/* Left rotation temp for rWORD8.  */
+-#define rA		r0	/* Right rotation temp for rWORD2.  */
+-#define rC		r12	/* Right rotation temp for rWORD4.  */
+-#define rE		r0	/* Right rotation temp for rWORD6.  */
+-#define rG		r12	/* Right rotation temp for rWORD8.  */
++#define rSHL		r29	/* Unaligned shift left count.  */
++#define rSHR		r28	/* Unaligned shift right count.  */
++#define rWORD8_SHIFT	r27	/* Left rotation temp for rWORD2.  */
++#define rWORD2_SHIFT	r26	/* Left rotation temp for rWORD4.  */
++#define rWORD4_SHIFT	r25	/* Left rotation temp for rWORD6.  */
++#define rWORD6_SHIFT	r24	/* Left rotation temp for rWORD8.  */
+ L(unaligned):
+-	std	r29,-24(r1)	
+-	cfi_offset(r29,-24)
++	std	rSHL, -24(r1)
++	cfi_offset(rSHL, -24)
+ 	clrldi	rSHL, rSTR2, 61
+ 	beq-	cr6, L(duzeroLength)
+-	std	r28,-32(r1)	
+-	cfi_offset(r28,-32)
++	std	rSHR, -32(r1)
++	cfi_offset(rSHR, -32)
+ 	beq	cr5, L(DWunaligned)
+-	std	r27,-40(r1)	
+-	cfi_offset(r27,-40)
+-/* Adjust the logical start of rSTR2 ro compensate for the extra bits
++	std	rWORD8_SHIFT, -40(r1)
++	cfi_offset(rWORD8_SHIFT, -40)
++/* Adjust the logical start of rSTR2 to compensate for the extra bits
+    in the 1st rSTR1 DW.  */
+-	sub	r27, rSTR2, rBITDIF
++	sub	rWORD8_SHIFT, rSTR2, r12
+ /* But do not attempt to address the DW before that DW that contains
+    the actual start of rSTR2.  */
+ 	clrrdi	rSTR2, rSTR2, 3
+-	std	r26,-48(r1)	
+-	cfi_offset(r26,-48)
+-/* Compute the leaft/right shift counts for the unalign rSTR2,
+-   compensating for the logical (DW aligned) start of rSTR1.  */ 
+-	clrldi	rSHL, r27, 61
+-	clrrdi	rSTR1, rSTR1, 3	
+-	std	r25,-56(r1)	
+-	cfi_offset(r25,-56)
++	std	rWORD2_SHIFT, -48(r1)
++	cfi_offset(rWORD2_SHIFT, -48)
++/* Compute the left/right shift counts for the unaligned rSTR2,
++   compensating for the logical (DW aligned) start of rSTR1.  */
++	clrldi	rSHL, rWORD8_SHIFT, 61
++	clrrdi	rSTR1, rSTR1, 3
++	std	rWORD4_SHIFT, -56(r1)
++	cfi_offset(rWORD4_SHIFT, -56)
+ 	sldi	rSHL, rSHL, 3
+-	cmpld	cr5, r27, rSTR2
+-	add	rN, rN, rBITDIF
+-	sldi	r11, rBITDIF, 3
+-	std	r24,-64(r1)	
+-	cfi_offset(r24,-64)
++	cmpld	cr5, rWORD8_SHIFT, rSTR2
++	add	rN, rN, r12
++	sldi	rWORD6, r12, 3
++	std	rWORD6_SHIFT, -64(r1)
++	cfi_offset(rWORD6_SHIFT, -64)
+ 	subfic	rSHR, rSHL, 64
+-	srdi	rTMP, rN, 5	/* Divide by 32 */
+-	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
++	srdi	r0, rN, 5	/* Divide by 32 */
++	andi.	r12, rN, 24	/* Get the DW remainder */
+ /* We normally need to load 2 DWs to start the unaligned rSTR2, but in
+    this special case those bits may be discarded anyway.  Also we
+    must avoid loading a DW where none of the bits are part of rSTR2 as
+    this may cross a page boundary and cause a page fault.  */
+ 	li	rWORD8, 0
+ 	blt	cr5, L(dus0)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD8, 0(rSTR2)
+-	la	rSTR2, 8(rSTR2)
++	addi	rSTR2, rSTR2, 8
++#endif
+ 	sld	rWORD8, rWORD8, rSHL
+ 
+ L(dus0):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 0(rSTR1)
+ 	ld	rWORD2, 0(rSTR2)
+-	cmpldi	cr1, rBITDIF, 16
++#endif
++	cmpldi	cr1, r12, 16
+ 	cmpldi	cr7, rN, 32
+-	srd	rG, rWORD2, rSHR
++	srd	r12, rWORD2, rSHR
+ 	clrldi	rN, rN, 61
+ 	beq	L(duPs4)
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+-	or	rWORD8, rG, rWORD8
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++	or	rWORD8, r12, rWORD8
+ 	bgt	cr1, L(duPs3)
+ 	beq	cr1, L(duPs2)
+ 
+ /* Remainder is 8 */
+-	.align 4
++	.align	4
+ L(dusP1):
+-	sld	rB, rWORD2, rSHL
+-	sld	rWORD7, rWORD1, r11
+-	sld	rWORD8, rWORD8, r11
++	sld	rWORD8_SHIFT, rWORD2, rSHL
++	sld	rWORD7, rWORD1, rWORD6
++	sld	rWORD8, rWORD8, rWORD6
+ 	bge	cr7, L(duP1e)
+ /* At this point we exit early with the first double word compare
+    complete and remainder of 0 to 7 bytes.  See L(du14) for details on
+@@ -590,95 +794,133 @@
+ 	bne	cr5, L(duLcr5)
+ 	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD2, 8(rSTR2)
+-	srd	rA, rWORD2, rSHR
++#endif
++	srd	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ /* Remainder is 16 */
+-	.align 4
++	.align	4
+ L(duPs2):
+-	sld	rH, rWORD2, rSHL
+-	sld	rWORD5, rWORD1, r11
+-	sld	rWORD6, rWORD8, r11
++	sld	rWORD6_SHIFT, rWORD2, rSHL
++	sld	rWORD5, rWORD1, rWORD6
++	sld	rWORD6, rWORD8, rWORD6
+ 	b	L(duP2e)
+ /* Remainder is 24 */
+-	.align 4
++	.align	4
+ L(duPs3):
+-	sld	rF, rWORD2, rSHL
+-	sld	rWORD3, rWORD1, r11
+-	sld	rWORD4, rWORD8, r11
++	sld	rWORD4_SHIFT, rWORD2, rSHL
++	sld	rWORD3, rWORD1, rWORD6
++	sld	rWORD4, rWORD8, rWORD6
+ 	b	L(duP3e)
+ /* Count is a multiple of 32, remainder is 0 */
+-	.align 4
++	.align	4
+ L(duPs4):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+-	or	rWORD8, rG, rWORD8
+-	sld	rD, rWORD2, rSHL
+-	sld	rWORD1, rWORD1, r11
+-	sld	rWORD2, rWORD8, r11
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++	or	rWORD8, r12, rWORD8
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	sld	rWORD1, rWORD1, rWORD6
++	sld	rWORD2, rWORD8, rWORD6
+ 	b	L(duP4e)
+ 
+ /* At this point we know rSTR1 is double word aligned and the
+    compare length is at least 8 bytes.  */
+-	.align 4
++	.align	4
+ L(DWunaligned):
+-	std	r27,-40(r1)	
+-	cfi_offset(r27,-40)
++	std	rWORD8_SHIFT, -40(r1)
++	cfi_offset(rWORD8_SHIFT, -40)
+ 	clrrdi	rSTR2, rSTR2, 3
+-	std	r26,-48(r1)	
+-	cfi_offset(r26,-48)
+-	srdi	rTMP, rN, 5	/* Divide by 32 */
+-	std	r25,-56(r1)	
+-	cfi_offset(r25,-56)
+-	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
+-	std	r24,-64(r1)	
+-	cfi_offset(r24,-64)
++	std	rWORD2_SHIFT, -48(r1)
++	cfi_offset(rWORD2_SHIFT, -48)
++	srdi	r0, rN, 5	/* Divide by 32 */
++	std	rWORD4_SHIFT, -56(r1)
++	cfi_offset(rWORD4_SHIFT, -56)
++	andi.	r12, rN, 24	/* Get the DW remainder */
++	std	rWORD6_SHIFT, -64(r1)
++	cfi_offset(rWORD6_SHIFT, -64)
+ 	sldi	rSHL, rSHL, 3
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD6, 0(rSTR2)
+ 	ldu	rWORD8, 8(rSTR2)
+-	cmpldi	cr1, rBITDIF, 16
++#endif
++	cmpldi	cr1, r12, 16
+ 	cmpldi	cr7, rN, 32
+ 	clrldi	rN, rN, 61
+ 	subfic	rSHR, rSHL, 64
+-	sld	rH, rWORD6, rSHL
++	sld	rWORD6_SHIFT, rWORD6, rSHL
+ 	beq	L(duP4)
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
+ 	bgt	cr1, L(duP3)
+ 	beq	cr1, L(duP2)
+-		
++
+ /* Remainder is 8 */
+-	.align 4
++	.align	4
+ L(duP1):
+-	srd	rG, rWORD8, rSHR
++	srd	r12, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	addi	rSTR1, rSTR1, 8
++#else
+ 	ld	rWORD7, 0(rSTR1)
+-	sld	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++#endif
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	blt	cr7, L(duP1x)
+ L(duP1e):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 8(rSTR1)
+ 	ld	rWORD2, 8(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+-	srd	rA, rWORD2, rSHR
+-	sld	rD, rWORD2, rSHL
+-	or	rWORD2, rA, rB
++	srd	r0, rWORD2, rSHR
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 16(rSTR1)
+ 	ld	rWORD4, 16(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
+-	srd	rC, rWORD4, rSHR
+-	sld	rF, rWORD4, rSHL
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++	srd	r12, rWORD4, rSHR
++	sld	rWORD4_SHIFT, rWORD4, rSHL
+ 	bne	cr5, L(duLcr5)
+-	or	rWORD4, rC, rD
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 24(rSTR1)
+ 	ld	rWORD6, 24(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
+-	srd	rE, rWORD6, rSHR
+-	sld	rH, rWORD6, rSHL
+-	bne	cr0, L(duLcr0)
+-	or	rWORD6, rE, rF
++	srd	r0, rWORD6, rSHR
++	sld	rWORD6_SHIFT, rWORD6, rSHL
++	bne	cr7, L(duLcr7)
++	or	rWORD6, r0, rWORD4_SHIFT
+ 	cmpld	cr6, rWORD5, rWORD6
+-	b	L(duLoop3)	
+-	.align 4
++	b	L(duLoop3)
++	.align	4
+ /* At this point we exit early with the first double word compare
+    complete and remainder of 0 to 7 bytes.  See L(du14) for details on
+    how we handle the remaining bytes.  */
+@@ -688,186 +930,321 @@
+ 	bne	cr5, L(duLcr5)
+ 	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD2, 8(rSTR2)
+-	srd	rA, rWORD2, rSHR
++#endif
++	srd	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ /* Remainder is 16 */
+-	.align 4
++	.align	4
+ L(duP2):
+-	srd	rE, rWORD8, rSHR
++	srd	r0, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	addi	rSTR1, rSTR1, 8
++#else
+ 	ld	rWORD5, 0(rSTR1)
+-	or	rWORD6, rE, rH
+-	sld	rH, rWORD8, rSHL
++#endif
++	or	rWORD6, r0, rWORD6_SHIFT
++	sld	rWORD6_SHIFT, rWORD8, rSHL
+ L(duP2e):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD7, 8(rSTR1)
+ 	ld	rWORD8, 8(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
+-	srd	rG, rWORD8, rSHR
+-	sld	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++	srd	r12, rWORD8, rSHR
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	blt	cr7, L(duP2x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 16(rSTR1)
+ 	ld	rWORD2, 16(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+ 	bne	cr6, L(duLcr6)
+-	srd	rA, rWORD2, rSHR
+-	sld	rD, rWORD2, rSHL
+-	or	rWORD2, rA, rB
++	srd	r0, rWORD2, rSHR
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 24(rSTR1)
+ 	ld	rWORD4, 24(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ 	bne	cr5, L(duLcr5)
+-	srd	rC, rWORD4, rSHR
+-	sld	rF, rWORD4, rSHL
+-	or	rWORD4, rC, rD
++	srd	r12, rWORD4, rSHR
++	sld	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 8
+ 	addi	rSTR2, rSTR2, 8
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
+ 	b	L(duLoop2)
+-	.align 4
++	.align	4
+ L(duP2x):
+ 	cmpld	cr5, rWORD7, rWORD8
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 8
+ 	addi	rSTR2, rSTR2, 8
++#endif
+ 	bne	cr6, L(duLcr6)
+ 	sldi.	rN, rN, 3
+ 	bne	cr5, L(duLcr5)
+ 	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD2, 8(rSTR2)
+-	srd	rA, rWORD2, rSHR
++#endif
++	srd	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+-		
++
+ /* Remainder is 24 */
+-	.align 4
++	.align	4
+ L(duP3):
+-	srd	rC, rWORD8, rSHR
++	srd	r12, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	addi	rSTR1, rSTR1, 8
++#else
+ 	ld	rWORD3, 0(rSTR1)
+-	sld	rF, rWORD8, rSHL
+-	or	rWORD4, rC, rH
++#endif
++	sld	rWORD4_SHIFT, rWORD8, rSHL
++	or	rWORD4, r12, rWORD6_SHIFT
+ L(duP3e):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 8(rSTR1)
+ 	ld	rWORD6, 8(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
+-	srd	rE, rWORD6, rSHR
+-	sld	rH, rWORD6, rSHL
+-	or	rWORD6, rE, rF
++	srd	r0, rWORD6, rSHR
++	sld	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD7, 16(rSTR1)
+ 	ld	rWORD8, 16(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	bne	cr1, L(duLcr1)
+-	srd	rG, rWORD8, rSHR
+-	sld	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++	srd	r12, rWORD8, rSHR
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	blt	cr7, L(duP3x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 24(rSTR1)
+ 	ld	rWORD2, 24(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+ 	bne	cr6, L(duLcr6)
+-	srd	rA, rWORD2, rSHR
+-	sld	rD, rWORD2, rSHL
+-	or	rWORD2, rA, rB
++	srd	r0, rWORD2, rSHR
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 16
+ 	addi	rSTR2, rSTR2, 16
+-	cmpld	cr0, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ 	b	L(duLoop1)
+-	.align 4
++	.align	4
+ L(duP3x):
++#ifndef __LITTLE_ENDIAN__
+ 	addi	rSTR1, rSTR1, 16
+ 	addi	rSTR2, rSTR2, 16
++#endif
++#if 0
++/* Huh?  We've already branched on cr1!  */
+ 	bne	cr1, L(duLcr1)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+ 	bne	cr6, L(duLcr6)
+ 	sldi.	rN, rN, 3
+ 	bne	cr5, L(duLcr5)
+ 	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD2, 8(rSTR2)
+-	srd	rA, rWORD2, rSHR
++#endif
++	srd	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+-	
++
+ /* Count is a multiple of 32, remainder is 0 */
+-	.align 4
++	.align	4
+ L(duP4):
+-	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+-	srd	rA, rWORD8, rSHR
++	mtctr	r0	/* Power4 wants mtctr 1st in dispatch group */
++	srd	r0, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	addi	rSTR1, rSTR1, 8
++#else
+ 	ld	rWORD1, 0(rSTR1)
+-	sld	rD, rWORD8, rSHL
+-	or	rWORD2, rA, rH
++#endif
++	sld	rWORD2_SHIFT, rWORD8, rSHL
++	or	rWORD2, r0, rWORD6_SHIFT
+ L(duP4e):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 8(rSTR1)
+ 	ld	rWORD4, 8(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
+-	srd	rC, rWORD4, rSHR
+-	sld	rF, rWORD4, rSHL
+-	or	rWORD4, rC, rD
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++	srd	r12, rWORD4, rSHR
++	sld	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 16(rSTR1)
+ 	ld	rWORD6, 16(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
+-	bne	cr0, L(duLcr0)
+-	srd	rE, rWORD6, rSHR
+-	sld	rH, rWORD6, rSHL
+-	or	rWORD6, rE, rF
++	bne	cr7, L(duLcr7)
++	srd	r0, rWORD6, rSHR
++	sld	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ldu	rWORD7, 24(rSTR1)
+ 	ldu	rWORD8, 24(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	bne	cr1, L(duLcr1)
+-	srd	rG, rWORD8, rSHR
+-	sld	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
++	srd	r12, rWORD8, rSHR
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	cmpld	cr5, rWORD7, rWORD8
+ 	bdz-	L(du24)		/* Adjust CTR as we start with +4 */
+ /* This is the primary loop */
+-	.align 4
++	.align	4
+ L(duLoop):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD1, 8(rSTR1)
+ 	ld	rWORD2, 8(rSTR2)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
+ 	bne	cr6, L(duLcr6)
+-	srd	rA, rWORD2, rSHR
+-	sld	rD, rWORD2, rSHL
+-	or	rWORD2, rA, rB
++	srd	r0, rWORD2, rSHR
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
+ L(duLoop1):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD3, 16(rSTR1)
+ 	ld	rWORD4, 16(rSTR2)
++#endif
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	bne	cr5, L(duLcr5)
+-	srd	rC, rWORD4, rSHR
+-	sld	rF, rWORD4, rSHL
+-	or	rWORD4, rC, rD
++	srd	r12, rWORD4, rSHR
++	sld	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
+ L(duLoop2):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD5, 24(rSTR1)
+ 	ld	rWORD6, 24(rSTR2)
++#endif
+ 	cmpld	cr5, rWORD7, rWORD8
+-	bne	cr0, L(duLcr0)
+-	srd	rE, rWORD6, rSHR
+-	sld	rH, rWORD6, rSHL
+-	or	rWORD6, rE, rF
++	bne	cr7, L(duLcr7)
++	srd	r0, rWORD6, rSHR
++	sld	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
+ L(duLoop3):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ldu	rWORD7, 32(rSTR1)
+ 	ldu	rWORD8, 32(rSTR2)
+-	cmpld	cr0, rWORD1, rWORD2
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ 	bne-	cr1, L(duLcr1)
+-	srd	rG, rWORD8, rSHR
+-	sld	rB, rWORD8, rSHL
+-	or	rWORD8, rG, rH
+-	bdnz+	L(duLoop)	
+-	
++	srd	r12, rWORD8, rSHR
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	bdnz+	L(duLoop)
++
+ L(duL4):
++#if 0
++/* Huh?  We've already branched on cr1!  */
+ 	bne	cr1, L(duLcr1)
++#endif
+ 	cmpld	cr1, rWORD3, rWORD4
+ 	bne	cr6, L(duLcr6)
+ 	cmpld	cr6, rWORD5, rWORD6
+ 	bne	cr5, L(duLcr5)
+ 	cmpld	cr5, rWORD7, rWORD8
+ L(du44):
+-	bne	cr0, L(duLcr0)
++	bne	cr7, L(duLcr7)
+ L(du34):
+ 	bne	cr1, L(duLcr1)
+ L(du24):
+@@ -876,106 +1253,113 @@
+ 	sldi.	rN, rN, 3
+ 	bne	cr5, L(duLcr5)
+ /* At this point we have a remainder of 1 to 7 bytes to compare.  We use
+-   shift right double to elliminate bits beyond the compare length. 
+-   This allows the use of double word subtract to compute the final
+-   result.
++   shift right double to eliminate bits beyond the compare length.
+ 
+-   However it may not be safe to load rWORD2 which may be beyond the 
++   However it may not be safe to load rWORD2 which may be beyond the
+    string length. So we compare the bit length of the remainder to
+    the right shift count (rSHR). If the bit count is less than or equal
+    we do not need to load rWORD2 (all significant bits are already in
+-   rB).  */
++   rWORD8_SHIFT).  */
+ 	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA, 0
++	li	r0, 0
+ 	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
+ 	ld	rWORD2, 8(rSTR2)
+-	srd	rA, rWORD2, rSHR
+-	.align 4
++#endif
++	srd	r0, rWORD2, rSHR
++	.align	4
+ L(dutrim):
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++#else
+ 	ld	rWORD1, 8(rSTR1)
+-	ld	rWORD8,-8(r1)
+-	subfic	rN, rN, 64	/* Shift count is 64 - (rN * 8).  */ 
+-	or	rWORD2, rA, rB
+-	ld	rWORD7,-16(r1)	
+-	ld	r29,-24(r1)
++#endif
++	ld	rWORD8, -8(r1)
++	subfic	rN, rN, 64	/* Shift count is 64 - (rN * 8).  */
++	or	rWORD2, r0, rWORD8_SHIFT
++	ld	rWORD7, -16(r1)
++	ld	rSHL, -24(r1)
+ 	srd	rWORD1, rWORD1, rN
+ 	srd	rWORD2, rWORD2, rN
+-	ld	r28,-32(r1)	
+-	ld	r27,-40(r1)
++	ld	rSHR, -32(r1)
++	ld	rWORD8_SHIFT, -40(r1)
+ 	li	rRTN, 0
+-	cmpld	cr0, rWORD1, rWORD2	
+-	ld	r26,-48(r1)
+-	ld	r25,-56(r1)
+- 	beq	cr0, L(dureturn24)
+-	li	rRTN, 1
+-	ld	r24,-64(r1)
+-	bgtlr	cr0
+-	li	rRTN, -1
+-	blr
+-	.align 4
+-L(duLcr0):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	li	rRTN, 1
+-	bgt	cr0, L(dureturn29)	
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
++	cmpld	cr7, rWORD1, rWORD2
++	ld	rWORD2_SHIFT, -48(r1)
++	ld	rWORD4_SHIFT, -56(r1)
++	beq	cr7, L(dureturn24)
++	li	rRTN, 1
++	ld	rWORD6_SHIFT, -64(r1)
++	bgtlr	cr7
++	li	rRTN, -1
++	blr
++	.align	4
++L(duLcr7):
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++	li	rRTN, 1
++	bgt	cr7, L(dureturn29)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
+ 	li	rRTN, -1
+ 	b	L(dureturn27)
+-	.align 4
++	.align	4
+ L(duLcr1):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
+ 	li	rRTN, 1
+-	bgt	cr1, L(dureturn29)	
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
++	bgt	cr1, L(dureturn29)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
+ 	li	rRTN, -1
+ 	b	L(dureturn27)
+-	.align 4
++	.align	4
+ L(duLcr6):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
+ 	li	rRTN, 1
+-	bgt	cr6, L(dureturn29)	
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
++	bgt	cr6, L(dureturn29)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
+ 	li	rRTN, -1
+ 	b	L(dureturn27)
+-	.align 4
++	.align	4
+ L(duLcr5):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
+ 	li	rRTN, 1
+-	bgt	cr5, L(dureturn29)	
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
++	bgt	cr5, L(dureturn29)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
+ 	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	3
+ L(duZeroReturn):
+-	li	rRTN,0
++	li	rRTN, 0
+ 	.align	4
+ L(dureturn):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-L(dureturn29):	
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
+-L(dureturn27):	
+-	ld	r27,-40(r1)
+-L(dureturn26):	
+-	ld	r26,-48(r1)
+-L(dureturn25):	
+-	ld	r25,-56(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++L(dureturn29):
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
++L(dureturn27):
++	ld	rWORD8_SHIFT, -40(r1)
++L(dureturn26):
++	ld	rWORD2_SHIFT, -48(r1)
++L(dureturn25):
++	ld	rWORD4_SHIFT, -56(r1)
+ L(dureturn24):
+-	ld	r24,-64(r1)
++	ld	rWORD6_SHIFT, -64(r1)
+ 	blr
+ L(duzeroLength):
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+-END (BP_SYM (memcmp))
++END (memcmp)
+ libc_hidden_builtin_def (memcmp)
+ weak_alias (memcmp, bcmp)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memcmp.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memcmp.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memcmp.S	2014-05-28 19:22:37.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memcmp.S	2014-05-29 09:35:08.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Optimized memcmp implementation for POWER7/PowerPC64.
+-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
++   Copyright (C) 2010-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
+@@ -17,379 +17,576 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+ /* int [r3] memcmp (const char *s1 [r3],
+ 		    const char *s2 [r4],
+ 		    size_t size [r5])  */
+ 
+ 	.machine power7
+-EALIGN (BP_SYM(memcmp),4,0)
++EALIGN (memcmp, 4, 0)
+ 	CALL_MCOUNT 3
+ 
+-#define rTMP	r0
+ #define rRTN	r3
+ #define rSTR1	r3	/* first string arg */
+ #define rSTR2	r4	/* second string arg */
+ #define rN	r5	/* max string length */
+-/* Note:  The Bounded pointer support in this code is broken.  This code
+-   was inherited from PPC32 and that support was never completed.
+-   Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
+ #define rWORD1	r6	/* current word in s1 */
+ #define rWORD2	r7	/* current word in s2 */
+ #define rWORD3	r8	/* next word in s1 */
+ #define rWORD4	r9	/* next word in s2 */
+ #define rWORD5	r10	/* next word in s1 */
+ #define rWORD6	r11	/* next word in s2 */
+-#define rBITDIF	r12	/* bits that differ in s1 & s2 words */
+ #define rWORD7	r30	/* next word in s1 */
+ #define rWORD8	r31	/* next word in s2 */
+ 
+-	xor	rTMP,rSTR2,rSTR1
+-	cmpldi	cr6,rN,0
+-	cmpldi	cr1,rN,12
+-	clrldi.	rTMP,rTMP,61
+-	clrldi	rBITDIF,rSTR1,61
+-	cmpldi	cr5,rBITDIF,0
+-	beq-	cr6,L(zeroLength)
+-	dcbt	0,rSTR1
+-	dcbt	0,rSTR2
+-/* If less than 8 bytes or not aligned, use the unalligned
++	xor	r0, rSTR2, rSTR1
++	cmpldi	cr6, rN, 0
++	cmpldi	cr1, rN, 12
++	clrldi.	r0, r0, 61
++	clrldi	r12, rSTR1, 61
++	cmpldi	cr5, r12, 0
++	beq-	cr6, L(zeroLength)
++	dcbt	0, rSTR1
++	dcbt	0, rSTR2
++/* If less than 8 bytes or not aligned, use the unaligned
+    byte loop.  */
+-	blt	cr1,L(bytealigned)
+-	std	rWORD8,-8(r1)
+-	cfi_offset(rWORD8,-8)
+-	std	rWORD7,-16(r1)
+-	cfi_offset(rWORD7,-16)
++	blt	cr1, L(bytealigned)
++	std	rWORD8, -8(r1)
++	cfi_offset(rWORD8, -8)
++	std	rWORD7, -16(r1)
++	cfi_offset(rWORD7, -16)
+ 	bne	L(unaligned)
+ /* At this point we know both strings have the same alignment and the
+-   compare length is at least 8 bytes.  rBITDIF containes the low order
++   compare length is at least 8 bytes.  r12 contains the low order
+    3 bits of rSTR1 and cr5 contains the result of the logical compare
+-   of rBITDIF to 0.  If rBITDIF == 0 then we are already double word
+-   aligned and can perform the DWaligned loop.
++   of r12 to 0.  If r12 == 0 then we are already double word
++   aligned and can perform the DW aligned loop.
+ 
+    Otherwise we know the two strings have the same alignment (but not
+-   yet DW).  So we can force the string addresses to the next lower DW
+-   boundary and special case this first DW word using shift left to
+-   ellimiate bits preceeding the first byte.  Since we want to join the
+-   normal (DWaligned) compare loop, starting at the second double word,
++   yet DW).  So we force the string addresses to the next lower DW
++   boundary and special case this first DW using shift left to
++   eliminate bits preceding the first byte.  Since we want to join the
++   normal (DW aligned) compare loop, starting at the second double word,
+    we need to adjust the length (rN) and special case the loop
+-   versioning for the first DW. This insures that the loop count is
+-   correct and the first DW (shifted) is in the expected resister pair.  */
++   versioning for the first DW. This ensures that the loop count is
++   correct and the first DW (shifted) is in the expected register pair.  */
+ 	.align	4
+ L(samealignment):
+-	clrrdi	rSTR1,rSTR1,3
+-	clrrdi	rSTR2,rSTR2,3
+-	beq	cr5,L(DWaligned)
+-	add	rN,rN,rBITDIF
+-	sldi	r11,rBITDIF,3
+-	srdi	rTMP,rN,5	/* Divide by 32 */
+-	andi.	rBITDIF,rN,24	/* Get the DW remainder */
+-	ld	rWORD1,0(rSTR1)
+-	ld	rWORD2,0(rSTR2)
+-	cmpldi	cr1,rBITDIF,16
+-	cmpldi	cr7,rN,32
+-	clrldi	rN,rN,61
++	clrrdi	rSTR1, rSTR1, 3
++	clrrdi	rSTR2, rSTR2, 3
++	beq	cr5, L(DWaligned)
++	add	rN, rN, r12
++	sldi	rWORD6, r12, 3
++	srdi	r0, rN, 5	/* Divide by 32 */
++	andi.	r12, rN, 24	/* Get the DW remainder */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++#endif
++	cmpldi	cr1, r12, 16
++	cmpldi	cr7, rN, 32
++	clrldi	rN, rN, 61
+ 	beq	L(dPs4)
+-	mtctr	rTMP
+-	bgt	cr1,L(dPs3)
+-	beq	cr1,L(dPs2)
++	mtctr	r0
++	bgt	cr1, L(dPs3)
++	beq	cr1, L(dPs2)
+ 
+ /* Remainder is 8 */
+ 	.align	3
+ L(dsP1):
+-	sld	rWORD5,rWORD1,r11
+-	sld	rWORD6,rWORD2,r11
+-	cmpld	cr5,rWORD5,rWORD6
+-	blt	cr7,L(dP1x)
++	sld	rWORD5, rWORD1, rWORD6
++	sld	rWORD6, rWORD2, rWORD6
++	cmpld	cr5, rWORD5, rWORD6
++	blt	cr7, L(dP1x)
+ /* Do something useful in this cycle since we have to branch anyway.  */
+-	ld	rWORD1,8(rSTR1)
+-	ld	rWORD2,8(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 8(rSTR1)
++	ld	rWORD2, 8(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ 	b	L(dP1e)
+ /* Remainder is 16 */
+ 	.align	4
+ L(dPs2):
+-	sld	rWORD5,rWORD1,r11
+-	sld	rWORD6,rWORD2,r11
+-	cmpld	cr6,rWORD5,rWORD6
+-	blt	cr7,L(dP2x)
++	sld	rWORD5, rWORD1, rWORD6
++	sld	rWORD6, rWORD2, rWORD6
++	cmpld	cr6, rWORD5, rWORD6
++	blt	cr7, L(dP2x)
+ /* Do something useful in this cycle since we have to branch anyway.  */
+-	ld	rWORD7,8(rSTR1)
+-	ld	rWORD8,8(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD7, 8(rSTR1)
++	ld	rWORD8, 8(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
+ 	b	L(dP2e)
+ /* Remainder is 24 */
+ 	.align	4
+ L(dPs3):
+-	sld	rWORD3,rWORD1,r11
+-	sld	rWORD4,rWORD2,r11
+-	cmpld	cr1,rWORD3,rWORD4
++	sld	rWORD3, rWORD1, rWORD6
++	sld	rWORD4, rWORD2, rWORD6
++	cmpld	cr1, rWORD3, rWORD4
+ 	b	L(dP3e)
+ /* Count is a multiple of 32, remainder is 0 */
+ 	.align	4
+ L(dPs4):
+-	mtctr	rTMP
+-	sld	rWORD1,rWORD1,r11
+-	sld	rWORD2,rWORD2,r11
+-	cmpld	cr0,rWORD1,rWORD2
++	mtctr	r0
++	sld	rWORD1, rWORD1, rWORD6
++	sld	rWORD2, rWORD2, rWORD6
++	cmpld	cr7, rWORD1, rWORD2
+ 	b	L(dP4e)
+ 
+ /* At this point we know both strings are double word aligned and the
+    compare length is at least 8 bytes.  */
+ 	.align	4
+ L(DWaligned):
+-	andi.	rBITDIF,rN,24	/* Get the DW remainder */
+-	srdi	rTMP,rN,5	/* Divide by 32 */
+-	cmpldi	cr1,rBITDIF,16
+-	cmpldi	cr7,rN,32
+-	clrldi	rN,rN,61
++	andi.	r12, rN, 24	/* Get the DW remainder */
++	srdi	r0, rN, 5	/* Divide by 32 */
++	cmpldi	cr1, r12, 16
++	cmpldi	cr7, rN, 32
++	clrldi	rN, rN, 61
+ 	beq	L(dP4)
+-	bgt	cr1,L(dP3)
+-	beq	cr1,L(dP2)
++	bgt	cr1, L(dP3)
++	beq	cr1, L(dP2)
+ 
+ /* Remainder is 8 */
+ 	.align	4
+ L(dP1):
+-	mtctr	rTMP
++	mtctr	r0
+ /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early
+-   (8-15 byte compare), we want to use only volitile registers.  This
+-   means we can avoid restoring non-volitile registers since we did not
++   (8-15 byte compare), we want to use only volatile registers.  This
++   means we can avoid restoring non-volatile registers since we did not
+    change any on the early exit path.  The key here is the non-early
+    exit path only cares about the condition code (cr5), not about which
+    register pair was used.  */
+-	ld	rWORD5,0(rSTR1)
+-	ld	rWORD6,0(rSTR2)
+-	cmpld	cr5,rWORD5,rWORD6
+-	blt	cr7,L(dP1x)
+-	ld	rWORD1,8(rSTR1)
+-	ld	rWORD2,8(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 0(rSTR1)
++	ld	rWORD6, 0(rSTR2)
++#endif
++	cmpld	cr5, rWORD5, rWORD6
++	blt	cr7, L(dP1x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 8(rSTR1)
++	ld	rWORD2, 8(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ L(dP1e):
+-	ld	rWORD3,16(rSTR1)
+-	ld	rWORD4,16(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
+-	ld	rWORD5,24(rSTR1)
+-	ld	rWORD6,24(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	bne	cr5,L(dLcr5)
+-	bne	cr0,L(dLcr0)
+-
+-	ldu	rWORD7,32(rSTR1)
+-	ldu	rWORD8,32(rSTR2)
+-	bne	cr1,L(dLcr1)
+-	cmpld	cr5,rWORD7,rWORD8
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 16(rSTR1)
++	ld	rWORD4, 16(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 24(rSTR1)
++	ld	rWORD6, 24(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++	bne	cr5, L(dLcr5x)
++	bne	cr7, L(dLcr7x)
++
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ldu	rWORD7, 32(rSTR1)
++	ldu	rWORD8, 32(rSTR2)
++#endif
++	bne	cr1, L(dLcr1)
++	cmpld	cr5, rWORD7, rWORD8
+ 	bdnz	L(dLoop)
+-	bne	cr6,L(dLcr6)
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	bne	cr6, L(dLcr6)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
+ 	.align	3
+ L(dP1x):
+-	sldi.	r12,rN,3
+-	bne	cr5,L(dLcr5)
+-	subfic	rN,r12,64	/* Shift count is 64 - (rN * 8).  */
++	sldi.	r12, rN, 3
++	bne	cr5, L(dLcr5x)
++	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+ 	bne	L(d00)
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+ /* Remainder is 16 */
+ 	.align	4
+ L(dP2):
+-	mtctr	rTMP
+-	ld	rWORD5,0(rSTR1)
+-	ld	rWORD6,0(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	blt	cr7,L(dP2x)
+-	ld	rWORD7,8(rSTR1)
+-	ld	rWORD8,8(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
++	mtctr	r0
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 0(rSTR1)
++	ld	rWORD6, 0(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++	blt	cr7, L(dP2x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD7, 8(rSTR1)
++	ld	rWORD8, 8(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
+ L(dP2e):
+-	ld	rWORD1,16(rSTR1)
+-	ld	rWORD2,16(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
+-	ld	rWORD3,24(rSTR1)
+-	ld	rWORD4,24(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
+-	addi	rSTR1,rSTR1,8
+-	addi	rSTR2,rSTR2,8
+-	bne	cr6,L(dLcr6)
+-	bne	cr5,L(dLcr5)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 16(rSTR1)
++	ld	rWORD2, 16(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 24(rSTR1)
++	ld	rWORD4, 24(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#endif
++	bne	cr6, L(dLcr6)
++	bne	cr5, L(dLcr5)
+ 	b	L(dLoop2)
+ /* Again we are on a early exit path (16-23 byte compare), we want to
+-   only use volitile registers and avoid restoring non-volitile
++   only use volatile registers and avoid restoring non-volatile
+    registers.  */
+ 	.align	4
+ L(dP2x):
+-	ld	rWORD3,8(rSTR1)
+-	ld	rWORD4,8(rSTR2)
+-	cmpld	cr5,rWORD3,rWORD4
+-	sldi.	r12,rN,3
+-	bne	cr6,L(dLcr6)
+-	addi	rSTR1,rSTR1,8
+-	addi	rSTR2,rSTR2,8
+-	bne	cr5,L(dLcr5)
+-	subfic	rN,r12,64	/* Shift count is 64 - (rN * 8).  */
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++	sldi.	r12, rN, 3
++	bne	cr6, L(dLcr6x)
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#endif
++	bne	cr1, L(dLcr1x)
++	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+ 	bne	L(d00)
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+ /* Remainder is 24 */
+ 	.align	4
+ L(dP3):
+-	mtctr	rTMP
+-	ld	rWORD3,0(rSTR1)
+-	ld	rWORD4,0(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
++	mtctr	r0
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 0(rSTR1)
++	ld	rWORD4, 0(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
+ L(dP3e):
+-	ld	rWORD5,8(rSTR1)
+-	ld	rWORD6,8(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	blt	cr7,L(dP3x)
+-	ld	rWORD7,16(rSTR1)
+-	ld	rWORD8,16(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
+-	ld	rWORD1,24(rSTR1)
+-	ld	rWORD2,24(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
+-	addi	rSTR1,rSTR1,16
+-	addi	rSTR2,rSTR2,16
+-	bne	cr1,L(dLcr1)
+-	bne	cr6,L(dLcr6)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 8(rSTR1)
++	ld	rWORD6, 8(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++	blt	cr7, L(dP3x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD7, 16(rSTR1)
++	ld	rWORD8, 16(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 24(rSTR1)
++	ld	rWORD2, 24(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 16
++	addi	rSTR2, rSTR2, 16
++#endif
++	bne	cr1, L(dLcr1)
++	bne	cr6, L(dLcr6)
+ 	b	L(dLoop1)
+ /* Again we are on a early exit path (24-31 byte compare), we want to
+-   only use volitile registers and avoid restoring non-volitile
++   only use volatile registers and avoid restoring non-volatile
+    registers.  */
+ 	.align	4
+ L(dP3x):
+-	ld	rWORD1,16(rSTR1)
+-	ld	rWORD2,16(rSTR2)
+-	cmpld	cr5,rWORD1,rWORD2
+-	sldi.	r12,rN,3
+-	bne	cr1,L(dLcr1)
+-	addi	rSTR1,rSTR1,16
+-	addi	rSTR2,rSTR2,16
+-	bne	cr6,L(dLcr6)
+-	subfic	rN,r12,64	/* Shift count is 64 - (rN * 8).  */
+-	bne	cr5,L(dLcr5)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 16(rSTR1)
++	ld	rWORD2, 16(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++	sldi.	r12, rN, 3
++	bne	cr1, L(dLcr1x)
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 16
++	addi	rSTR2, rSTR2, 16
++#endif
++	bne	cr6, L(dLcr6x)
++	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
++	bne	cr7, L(dLcr7x)
+ 	bne	L(d00)
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+ /* Count is a multiple of 32, remainder is 0 */
+ 	.align	4
+ L(dP4):
+-	mtctr	rTMP
+-	ld	rWORD1,0(rSTR1)
+-	ld	rWORD2,0(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
++	mtctr	r0
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ L(dP4e):
+-	ld	rWORD3,8(rSTR1)
+-	ld	rWORD4,8(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
+-	ld	rWORD5,16(rSTR1)
+-	ld	rWORD6,16(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	ldu	rWORD7,24(rSTR1)
+-	ldu	rWORD8,24(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
+-	bne	cr0,L(dLcr0)
+-	bne	cr1,L(dLcr1)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 16(rSTR1)
++	ld	rWORD6, 16(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ldu	rWORD7, 24(rSTR1)
++	ldu	rWORD8, 24(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
++	bne	cr7, L(dLcr7)
++	bne	cr1, L(dLcr1)
+ 	bdz-	L(d24)		/* Adjust CTR as we start with +4 */
+ /* This is the primary loop */
+ 	.align	4
+ L(dLoop):
+-	ld	rWORD1,8(rSTR1)
+-	ld	rWORD2,8(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
+-	bne	cr6,L(dLcr6)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 8(rSTR1)
++	ld	rWORD2, 8(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++	bne	cr6, L(dLcr6)
+ L(dLoop1):
+-	ld	rWORD3,16(rSTR1)
+-	ld	rWORD4,16(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	bne	cr5,L(dLcr5)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 16(rSTR1)
++	ld	rWORD4, 16(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++	bne	cr5, L(dLcr5)
+ L(dLoop2):
+-	ld	rWORD5,24(rSTR1)
+-	ld	rWORD6,24(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
+-	bne	cr0,L(dLcr0)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 24(rSTR1)
++	ld	rWORD6, 24(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
++	bne	cr7, L(dLcr7)
+ L(dLoop3):
+-	ldu	rWORD7,32(rSTR1)
+-	ldu	rWORD8,32(rSTR2)
+-	bne	cr1,L(dLcr1)
+-	cmpld	cr0,rWORD1,rWORD2
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ldu	rWORD7, 32(rSTR1)
++	ldu	rWORD8, 32(rSTR2)
++#endif
++	bne	cr1, L(dLcr1)
++	cmpld	cr7, rWORD1, rWORD2
+ 	bdnz	L(dLoop)
+ 
+ L(dL4):
+-	cmpld	cr1,rWORD3,rWORD4
+-	bne	cr6,L(dLcr6)
+-	cmpld	cr6,rWORD5,rWORD6
+-	bne	cr5,L(dLcr5)
+-	cmpld	cr5,rWORD7,rWORD8
++	cmpld	cr1, rWORD3, rWORD4
++	bne	cr6, L(dLcr6)
++	cmpld	cr6, rWORD5, rWORD6
++	bne	cr5, L(dLcr5)
++	cmpld	cr5, rWORD7, rWORD8
+ L(d44):
+-	bne	cr0,L(dLcr0)
++	bne	cr7, L(dLcr7)
+ L(d34):
+-	bne	cr1,L(dLcr1)
++	bne	cr1, L(dLcr1)
+ L(d24):
+-	bne	cr6,L(dLcr6)
++	bne	cr6, L(dLcr6)
+ L(d14):
+-	sldi.	r12,rN,3
+-	bne	cr5,L(dLcr5)
++	sldi.	r12, rN, 3
++	bne	cr5, L(dLcr5)
+ L(d04):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	subfic	rN,r12,64	/* Shift count is 64 - (rN * 8).  */
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+ 	beq	L(zeroLength)
+ /* At this point we have a remainder of 1 to 7 bytes to compare.  Since
+    we are aligned it is safe to load the whole double word, and use
+-   shift right double to elliminate bits beyond the compare length.  */
++   shift right double to eliminate bits beyond the compare length.  */
+ L(d00):
+-	ld	rWORD1,8(rSTR1)
+-	ld	rWORD2,8(rSTR2)
+-	srd	rWORD1,rWORD1,rN
+-	srd	rWORD2,rWORD2,rN
+-	cmpld	cr5,rWORD1,rWORD2
+-	bne	cr5,L(dLcr5x)
+-	li	rRTN,0
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 8(rSTR1)
++	ld	rWORD2, 8(rSTR2)
++#endif
++	srd	rWORD1, rWORD1, rN
++	srd	rWORD2, rWORD2, rN
++	cmpld	cr7, rWORD1, rWORD2
++	bne	cr7, L(dLcr7x)
++	li	rRTN, 0
+ 	blr
++
+ 	.align	4
+-L(dLcr0):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	li	rRTN,1
+-	bgtlr	cr0
+-	li	rRTN,-1
++L(dLcr7):
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++L(dLcr7x):
++	li	rRTN, 1
++	bgtlr	cr7
++	li	rRTN, -1
+ 	blr
+ 	.align	4
+ L(dLcr1):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	li	rRTN,1
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++L(dLcr1x):
++	li	rRTN, 1
+ 	bgtlr	cr1
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ 	.align	4
+ L(dLcr6):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	li	rRTN,1
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++L(dLcr6x):
++	li	rRTN, 1
+ 	bgtlr	cr6
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ 	.align	4
+ L(dLcr5):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
+ L(dLcr5x):
+-	li	rRTN,1
++	li	rRTN, 1
+ 	bgtlr	cr5
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ 
+ 	.align	4
+ L(bytealigned):
+ 	mtctr	rN
+-	beq	cr6,L(zeroLength)
++#if 0
++/* Huh?  We've already branched on cr6!  */
++	beq	cr6, L(zeroLength)
++#endif
+ 
+ /* We need to prime this loop.  This loop is swing modulo scheduled
+    to avoid pipe delays.  The dependent instruction latencies (load to
+@@ -401,38 +598,38 @@
+    So we must precondition some registers and condition codes so that
+    we don't exit the loop early on the first iteration.  */
+ 
+-	lbz	rWORD1,0(rSTR1)
+-	lbz	rWORD2,0(rSTR2)
++	lbz	rWORD1, 0(rSTR1)
++	lbz	rWORD2, 0(rSTR2)
+ 	bdz	L(b11)
+-	cmpld	cr0,rWORD1,rWORD2
+-	lbz	rWORD3,1(rSTR1)
+-	lbz	rWORD4,1(rSTR2)
++	cmpld	cr7, rWORD1, rWORD2
++	lbz	rWORD3, 1(rSTR1)
++	lbz	rWORD4, 1(rSTR2)
+ 	bdz	L(b12)
+-	cmpld	cr1,rWORD3,rWORD4
+-	lbzu	rWORD5,2(rSTR1)
+-	lbzu	rWORD6,2(rSTR2)
++	cmpld	cr1, rWORD3, rWORD4
++	lbzu	rWORD5, 2(rSTR1)
++	lbzu	rWORD6, 2(rSTR2)
+ 	bdz	L(b13)
+ 	.align	4
+ L(bLoop):
+-	lbzu	rWORD1,1(rSTR1)
+-	lbzu	rWORD2,1(rSTR2)
+-	bne	cr0,L(bLcr0)
++	lbzu	rWORD1, 1(rSTR1)
++	lbzu	rWORD2, 1(rSTR2)
++	bne	cr7, L(bLcr7)
+ 
+-	cmpld	cr6,rWORD5,rWORD6
++	cmpld	cr6, rWORD5, rWORD6
+ 	bdz	L(b3i)
+ 
+-	lbzu	rWORD3,1(rSTR1)
+-	lbzu	rWORD4,1(rSTR2)
+-	bne	cr1,L(bLcr1)
++	lbzu	rWORD3, 1(rSTR1)
++	lbzu	rWORD4, 1(rSTR2)
++	bne	cr1, L(bLcr1)
+ 
+-	cmpld	cr0,rWORD1,rWORD2
++	cmpld	cr7, rWORD1, rWORD2
+ 	bdz	L(b2i)
+ 
+-	lbzu	rWORD5,1(rSTR1)
+-	lbzu	rWORD6,1(rSTR2)
+-	bne	cr6,L(bLcr6)
++	lbzu	rWORD5, 1(rSTR1)
++	lbzu	rWORD6, 1(rSTR2)
++	bne	cr6, L(bLcr6)
+ 
+-	cmpld	cr1,rWORD3,rWORD4
++	cmpld	cr1, rWORD3, rWORD4
+ 	bdnz	L(bLoop)
+ 
+ /* We speculatively loading bytes before we have tested the previous
+@@ -442,542 +639,727 @@
+    tested.  In this case we must complete the pending operations
+    before returning.  */
+ L(b1i):
+-	bne	cr0,L(bLcr0)
+-	bne	cr1,L(bLcr1)
++	bne	cr7, L(bLcr7)
++	bne	cr1, L(bLcr1)
+ 	b	L(bx56)
+ 	.align	4
+ L(b2i):
+-	bne	cr6,L(bLcr6)
+-	bne	cr0,L(bLcr0)
++	bne	cr6, L(bLcr6)
++	bne	cr7, L(bLcr7)
+ 	b	L(bx34)
+ 	.align	4
+ L(b3i):
+-	bne	cr1,L(bLcr1)
+-	bne	cr6,L(bLcr6)
++	bne	cr1, L(bLcr1)
++	bne	cr6, L(bLcr6)
+ 	b	L(bx12)
+ 	.align	4
+-L(bLcr0):
+-	li	rRTN,1
+-	bgtlr	cr0
+-	li	rRTN,-1
++L(bLcr7):
++	li	rRTN, 1
++	bgtlr	cr7
++	li	rRTN, -1
+ 	blr
+ L(bLcr1):
+-	li	rRTN,1
++	li	rRTN, 1
+ 	bgtlr	cr1
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ L(bLcr6):
+-	li	rRTN,1
++	li	rRTN, 1
+ 	bgtlr	cr6
+-	li	rRTN,-1
++	li	rRTN, -1
+ 	blr
+ 
+ L(b13):
+-	bne	cr0,L(bx12)
+-	bne	cr1,L(bx34)
++	bne	cr7, L(bx12)
++	bne	cr1, L(bx34)
+ L(bx56):
+-	sub	rRTN,rWORD5,rWORD6
++	sub	rRTN, rWORD5, rWORD6
+ 	blr
+ 	nop
+ L(b12):
+-	bne	cr0,L(bx12)
++	bne	cr7, L(bx12)
+ L(bx34):
+-	sub	rRTN,rWORD3,rWORD4
++	sub	rRTN, rWORD3, rWORD4
+ 	blr
+ L(b11):
+ L(bx12):
+-	sub	rRTN,rWORD1,rWORD2
++	sub	rRTN, rWORD1, rWORD2
+ 	blr
+ 	.align	4
+-L(zeroLengthReturn):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+ L(zeroLength):
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+ 	.align	4
+ /* At this point we know the strings have different alignment and the
+-   compare length is at least 8 bytes.  rBITDIF containes the low order
++   compare length is at least 8 bytes.  r12 contains the low order
+    3 bits of rSTR1 and cr5 contains the result of the logical compare
+-   of rBITDIF to 0.  If rBITDIF == 0 then rStr1 is double word
++   of r12 to 0.  If r12 == 0 then rStr1 is double word
+    aligned and can perform the DWunaligned loop.
+ 
+-   Otherwise we know that rSTR1 is not aready DW aligned yet.
++   Otherwise we know that rSTR1 is not already DW aligned yet.
+    So we can force the string addresses to the next lower DW
+-   boundary and special case this first DW word using shift left to
+-   ellimiate bits preceeding the first byte.  Since we want to join the
++   boundary and special case this first DW using shift left to
++   eliminate bits preceding the first byte.  Since we want to join the
+    normal (DWaligned) compare loop, starting at the second double word,
+    we need to adjust the length (rN) and special case the loop
+-   versioning for the first DW. This insures that the loop count is
++   versioning for the first DW. This ensures that the loop count is
+    correct and the first DW (shifted) is in the expected resister pair.  */
+-#define rSHL	r29	/* Unaligned shift left count.  */
+-#define rSHR	r28	/* Unaligned shift right count.  */
+-#define rB		r27	/* Left rotation temp for rWORD2.  */
+-#define rD		r26	/* Left rotation temp for rWORD4.  */
+-#define rF		r25	/* Left rotation temp for rWORD6.  */
+-#define rH		r24	/* Left rotation temp for rWORD8.  */
+-#define rA		r0	/* Right rotation temp for rWORD2.  */
+-#define rC		r12	/* Right rotation temp for rWORD4.  */
+-#define rE		r0	/* Right rotation temp for rWORD6.  */
+-#define rG		r12	/* Right rotation temp for rWORD8.  */
++#define rSHL		r29	/* Unaligned shift left count.  */
++#define rSHR		r28	/* Unaligned shift right count.  */
++#define rWORD8_SHIFT	r27	/* Left rotation temp for rWORD2.  */
++#define rWORD2_SHIFT	r26	/* Left rotation temp for rWORD4.  */
++#define rWORD4_SHIFT	r25	/* Left rotation temp for rWORD6.  */
++#define rWORD6_SHIFT	r24	/* Left rotation temp for rWORD8.  */
+ L(unaligned):
+-	std	r29,-24(r1)
+-	cfi_offset(r29,-24)
+-	clrldi	rSHL,rSTR2,61
+-	beq	cr6,L(duzeroLength)
+-	std	r28,-32(r1)
+-	cfi_offset(r28,-32)
+-	beq	cr5,L(DWunaligned)
+-	std	r27,-40(r1)
+-	cfi_offset(r27,-40)
+-/* Adjust the logical start of rSTR2 ro compensate for the extra bits
++	std	rSHL, -24(r1)
++	cfi_offset(rSHL, -24)
++	clrldi	rSHL, rSTR2, 61
++	beq	cr6, L(duzeroLength)
++	std	rSHR, -32(r1)
++	cfi_offset(rSHR, -32)
++	beq	cr5, L(DWunaligned)
++	std	rWORD8_SHIFT, -40(r1)
++	cfi_offset(rWORD8_SHIFT, -40)
++/* Adjust the logical start of rSTR2 to compensate for the extra bits
+    in the 1st rSTR1 DW.  */
+-	sub	r27,rSTR2,rBITDIF
++	sub	rWORD8_SHIFT, rSTR2, r12
+ /* But do not attempt to address the DW before that DW that contains
+    the actual start of rSTR2.  */
+-	clrrdi	rSTR2,rSTR2,3
+-	std	r26,-48(r1)
+-	cfi_offset(r26,-48)
+-/* Compute the leaft/right shift counts for the unalign rSTR2,
++	clrrdi	rSTR2, rSTR2, 3
++	std	rWORD2_SHIFT, -48(r1)
++	cfi_offset(rWORD2_SHIFT, -48)
++/* Compute the left/right shift counts for the unaligned rSTR2,
+    compensating for the logical (DW aligned) start of rSTR1.  */
+-	clrldi	rSHL,r27,61
+-	clrrdi	rSTR1,rSTR1,3
+-	std	r25,-56(r1)
+-	cfi_offset(r25,-56)
+-	sldi	rSHL,rSHL,3
+-	cmpld	cr5,r27,rSTR2
+-	add	rN,rN,rBITDIF
+-	sldi	r11,rBITDIF,3
+-	std	r24,-64(r1)
+-	cfi_offset(r24,-64)
+-	subfic	rSHR,rSHL,64
+-	srdi	rTMP,rN,5	/* Divide by 32 */
+-	andi.	rBITDIF,rN,24	/* Get the DW remainder */
++	clrldi	rSHL, rWORD8_SHIFT, 61
++	clrrdi	rSTR1, rSTR1, 3
++	std	rWORD4_SHIFT, -56(r1)
++	cfi_offset(rWORD4_SHIFT, -56)
++	sldi	rSHL, rSHL, 3
++	cmpld	cr5, rWORD8_SHIFT, rSTR2
++	add	rN, rN, r12
++	sldi	rWORD6, r12, 3
++	std	rWORD6_SHIFT, -64(r1)
++	cfi_offset(rWORD6_SHIFT, -64)
++	subfic	rSHR, rSHL, 64
++	srdi	r0, rN, 5	/* Divide by 32 */
++	andi.	r12, rN, 24	/* Get the DW remainder */
+ /* We normally need to load 2 DWs to start the unaligned rSTR2, but in
+    this special case those bits may be discarded anyway.  Also we
+    must avoid loading a DW where none of the bits are part of rSTR2 as
+    this may cross a page boundary and cause a page fault.  */
+-	li	rWORD8,0
+-	blt	cr5,L(dus0)
+-	ld	rWORD8,0(rSTR2)
+-	la	rSTR2,8(rSTR2)
+-	sld	rWORD8,rWORD8,rSHL
++	li	rWORD8, 0
++	blt	cr5, L(dus0)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD8, 0(rSTR2)
++	addi	rSTR2, rSTR2, 8
++#endif
++	sld	rWORD8, rWORD8, rSHL
+ 
+ L(dus0):
+-	ld	rWORD1,0(rSTR1)
+-	ld	rWORD2,0(rSTR2)
+-	cmpldi	cr1,rBITDIF,16
+-	cmpldi	cr7,rN,32
+-	srd	rG,rWORD2,rSHR
+-	clrldi	rN,rN,61
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++#endif
++	cmpldi	cr1, r12, 16
++	cmpldi	cr7, rN, 32
++	srd	r12, rWORD2, rSHR
++	clrldi	rN, rN, 61
+ 	beq	L(duPs4)
+-	mtctr	rTMP
+-	or	rWORD8,rG,rWORD8
+-	bgt	cr1,L(duPs3)
+-	beq	cr1,L(duPs2)
++	mtctr	r0
++	or	rWORD8, r12, rWORD8
++	bgt	cr1, L(duPs3)
++	beq	cr1, L(duPs2)
+ 
+ /* Remainder is 8 */
+ 	.align	4
+ L(dusP1):
+-	sld	rB,rWORD2,rSHL
+-	sld	rWORD7,rWORD1,r11
+-	sld	rWORD8,rWORD8,r11
+-	bge	cr7,L(duP1e)
++	sld	rWORD8_SHIFT, rWORD2, rSHL
++	sld	rWORD7, rWORD1, rWORD6
++	sld	rWORD8, rWORD8, rWORD6
++	bge	cr7, L(duP1e)
+ /* At this point we exit early with the first double word compare
+    complete and remainder of 0 to 7 bytes.  See L(du14) for details on
+    how we handle the remaining bytes.  */
+-	cmpld	cr5,rWORD7,rWORD8
+-	sldi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
+-	cmpld	cr7,rN,rSHR
++	cmpld	cr5, rWORD7, rWORD8
++	sldi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
++	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	ld	rWORD2,8(rSTR2)
+-	srd	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD2, 8(rSTR2)
++#endif
++	srd	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ /* Remainder is 16 */
+ 	.align	4
+ L(duPs2):
+-	sld	rH,rWORD2,rSHL
+-	sld	rWORD5,rWORD1,r11
+-	sld	rWORD6,rWORD8,r11
++	sld	rWORD6_SHIFT, rWORD2, rSHL
++	sld	rWORD5, rWORD1, rWORD6
++	sld	rWORD6, rWORD8, rWORD6
+ 	b	L(duP2e)
+ /* Remainder is 24 */
+ 	.align	4
+ L(duPs3):
+-	sld	rF,rWORD2,rSHL
+-	sld	rWORD3,rWORD1,r11
+-	sld	rWORD4,rWORD8,r11
++	sld	rWORD4_SHIFT, rWORD2, rSHL
++	sld	rWORD3, rWORD1, rWORD6
++	sld	rWORD4, rWORD8, rWORD6
+ 	b	L(duP3e)
+ /* Count is a multiple of 32, remainder is 0 */
+ 	.align	4
+ L(duPs4):
+-	mtctr	rTMP
+-	or	rWORD8,rG,rWORD8
+-	sld	rD,rWORD2,rSHL
+-	sld	rWORD1,rWORD1,r11
+-	sld	rWORD2,rWORD8,r11
++	mtctr	r0
++	or	rWORD8, r12, rWORD8
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	sld	rWORD1, rWORD1, rWORD6
++	sld	rWORD2, rWORD8, rWORD6
+ 	b	L(duP4e)
+ 
+ /* At this point we know rSTR1 is double word aligned and the
+    compare length is at least 8 bytes.  */
+ 	.align	4
+ L(DWunaligned):
+-	std	r27,-40(r1)
+-	cfi_offset(r27,-40)
+-	clrrdi	rSTR2,rSTR2,3
+-	std	r26,-48(r1)
+-	cfi_offset(r26,-48)
+-	srdi	rTMP,rN,5	/* Divide by 32 */
+-	std	r25,-56(r1)
+-	cfi_offset(r25,-56)
+-	andi.	rBITDIF,rN,24	/* Get the DW remainder */
+-	std	r24,-64(r1)
+-	cfi_offset(r24,-64)
+-	sldi	rSHL,rSHL,3
+-	ld	rWORD6,0(rSTR2)
+-	ldu	rWORD8,8(rSTR2)
+-	cmpldi	cr1,rBITDIF,16
+-	cmpldi	cr7,rN,32
+-	clrldi	rN,rN,61
+-	subfic	rSHR,rSHL,64
+-	sld	rH,rWORD6,rSHL
++	std	rWORD8_SHIFT, -40(r1)
++	cfi_offset(rWORD8_SHIFT, -40)
++	clrrdi	rSTR2, rSTR2, 3
++	std	rWORD2_SHIFT, -48(r1)
++	cfi_offset(rWORD2_SHIFT, -48)
++	srdi	r0, rN, 5	/* Divide by 32 */
++	std	rWORD4_SHIFT, -56(r1)
++	cfi_offset(rWORD4_SHIFT, -56)
++	andi.	r12, rN, 24	/* Get the DW remainder */
++	std	rWORD6_SHIFT, -64(r1)
++	cfi_offset(rWORD6_SHIFT, -64)
++	sldi	rSHL, rSHL, 3
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD6, 0(rSTR2)
++	ldu	rWORD8, 8(rSTR2)
++#endif
++	cmpldi	cr1, r12, 16
++	cmpldi	cr7, rN, 32
++	clrldi	rN, rN, 61
++	subfic	rSHR, rSHL, 64
++	sld	rWORD6_SHIFT, rWORD6, rSHL
+ 	beq	L(duP4)
+-	mtctr	rTMP
+-	bgt	cr1,L(duP3)
+-	beq	cr1,L(duP2)
++	mtctr	r0
++	bgt	cr1, L(duP3)
++	beq	cr1, L(duP2)
+ 
+ /* Remainder is 8 */
+ 	.align	4
+ L(duP1):
+-	srd	rG,rWORD8,rSHR
+-	ld	rWORD7,0(rSTR1)
+-	sld	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
+-	blt	cr7,L(duP1x)
++	srd	r12, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	addi	rSTR1, rSTR1, 8
++#else
++	ld	rWORD7, 0(rSTR1)
++#endif
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	blt	cr7, L(duP1x)
+ L(duP1e):
+-	ld	rWORD1,8(rSTR1)
+-	ld	rWORD2,8(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
+-	srd	rA,rWORD2,rSHR
+-	sld	rD,rWORD2,rSHL
+-	or	rWORD2,rA,rB
+-	ld	rWORD3,16(rSTR1)
+-	ld	rWORD4,16(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
+-	srd	rC,rWORD4,rSHR
+-	sld	rF,rWORD4,rSHL
+-	bne	cr5,L(duLcr5)
+-	or	rWORD4,rC,rD
+-	ld	rWORD5,24(rSTR1)
+-	ld	rWORD6,24(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
+-	srd	rE,rWORD6,rSHR
+-	sld	rH,rWORD6,rSHL
+-	bne	cr0,L(duLcr0)
+-	or	rWORD6,rE,rF
+-	cmpld	cr6,rWORD5,rWORD6
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 8(rSTR1)
++	ld	rWORD2, 8(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
++	srd	r0, rWORD2, rSHR
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 16(rSTR1)
++	ld	rWORD4, 16(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++	srd	r12, rWORD4, rSHR
++	sld	rWORD4_SHIFT, rWORD4, rSHL
++	bne	cr5, L(duLcr5)
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 24(rSTR1)
++	ld	rWORD6, 24(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++	srd	r0, rWORD6, rSHR
++	sld	rWORD6_SHIFT, rWORD6, rSHL
++	bne	cr7, L(duLcr7)
++	or	rWORD6, r0, rWORD4_SHIFT
++	cmpld	cr6, rWORD5, rWORD6
+ 	b	L(duLoop3)
+ 	.align	4
+ /* At this point we exit early with the first double word compare
+    complete and remainder of 0 to 7 bytes.  See L(du14) for details on
+    how we handle the remaining bytes.  */
+ L(duP1x):
+-	cmpld	cr5,rWORD7,rWORD8
+-	sldi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
+-	cmpld	cr7,rN,rSHR
++	cmpld	cr5, rWORD7, rWORD8
++	sldi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
++	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	ld	rWORD2,8(rSTR2)
+-	srd	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD2, 8(rSTR2)
++#endif
++	srd	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ /* Remainder is 16 */
+ 	.align	4
+ L(duP2):
+-	srd	rE,rWORD8,rSHR
+-	ld	rWORD5,0(rSTR1)
+-	or	rWORD6,rE,rH
+-	sld	rH,rWORD8,rSHL
++	srd	r0, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	addi	rSTR1, rSTR1, 8
++#else
++	ld	rWORD5, 0(rSTR1)
++#endif
++	or	rWORD6, r0, rWORD6_SHIFT
++	sld	rWORD6_SHIFT, rWORD8, rSHL
+ L(duP2e):
+-	ld	rWORD7,8(rSTR1)
+-	ld	rWORD8,8(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	srd	rG,rWORD8,rSHR
+-	sld	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
+-	blt	cr7,L(duP2x)
+-	ld	rWORD1,16(rSTR1)
+-	ld	rWORD2,16(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
+-	bne	cr6,L(duLcr6)
+-	srd	rA,rWORD2,rSHR
+-	sld	rD,rWORD2,rSHL
+-	or	rWORD2,rA,rB
+-	ld	rWORD3,24(rSTR1)
+-	ld	rWORD4,24(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
+-	bne	cr5,L(duLcr5)
+-	srd	rC,rWORD4,rSHR
+-	sld	rF,rWORD4,rSHL
+-	or	rWORD4,rC,rD
+-	addi	rSTR1,rSTR1,8
+-	addi	rSTR2,rSTR2,8
+-	cmpld	cr1,rWORD3,rWORD4
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD7, 8(rSTR1)
++	ld	rWORD8, 8(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++	srd	r12, rWORD8, rSHR
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	blt	cr7, L(duP2x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 16(rSTR1)
++	ld	rWORD2, 16(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
++	bne	cr6, L(duLcr6)
++	srd	r0, rWORD2, rSHR
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 24(rSTR1)
++	ld	rWORD4, 24(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++	bne	cr5, L(duLcr5)
++	srd	r12, rWORD4, rSHR
++	sld	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#endif
++	cmpld	cr1, rWORD3, rWORD4
+ 	b	L(duLoop2)
+ 	.align	4
+ L(duP2x):
+-	cmpld	cr5,rWORD7,rWORD8
+-	addi	rSTR1,rSTR1,8
+-	addi	rSTR2,rSTR2,8
+-	bne	cr6,L(duLcr6)
+-	sldi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
+-	cmpld	cr7,rN,rSHR
++	cmpld	cr5, rWORD7, rWORD8
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#endif
++	bne	cr6, L(duLcr6)
++	sldi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
++	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	ld	rWORD2,8(rSTR2)
+-	srd	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD2, 8(rSTR2)
++#endif
++	srd	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ 
+ /* Remainder is 24 */
+ 	.align	4
+ L(duP3):
+-	srd	rC,rWORD8,rSHR
+-	ld	rWORD3,0(rSTR1)
+-	sld	rF,rWORD8,rSHL
+-	or	rWORD4,rC,rH
++	srd	r12, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	addi	rSTR1, rSTR1, 8
++#else
++	ld	rWORD3, 0(rSTR1)
++#endif
++	sld	rWORD4_SHIFT, rWORD8, rSHL
++	or	rWORD4, r12, rWORD6_SHIFT
+ L(duP3e):
+-	ld	rWORD5,8(rSTR1)
+-	ld	rWORD6,8(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
+-	srd	rE,rWORD6,rSHR
+-	sld	rH,rWORD6,rSHL
+-	or	rWORD6,rE,rF
+-	ld	rWORD7,16(rSTR1)
+-	ld	rWORD8,16(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	bne	cr1,L(duLcr1)
+-	srd	rG,rWORD8,rSHR
+-	sld	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
+-	blt	cr7,L(duP3x)
+-	ld	rWORD1,24(rSTR1)
+-	ld	rWORD2,24(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
+-	bne	cr6,L(duLcr6)
+-	srd	rA,rWORD2,rSHR
+-	sld	rD,rWORD2,rSHL
+-	or	rWORD2,rA,rB
+-	addi	rSTR1,rSTR1,16
+-	addi	rSTR2,rSTR2,16
+-	cmpld	cr0,rWORD1,rWORD2
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 8(rSTR1)
++	ld	rWORD6, 8(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++	srd	r0, rWORD6, rSHR
++	sld	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD7, 16(rSTR1)
++	ld	rWORD8, 16(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++	bne	cr1, L(duLcr1)
++	srd	r12, rWORD8, rSHR
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	blt	cr7, L(duP3x)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 24(rSTR1)
++	ld	rWORD2, 24(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
++	bne	cr6, L(duLcr6)
++	srd	r0, rWORD2, rSHR
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 16
++	addi	rSTR2, rSTR2, 16
++#endif
++	cmpld	cr7, rWORD1, rWORD2
+ 	b	L(duLoop1)
+ 	.align	4
+ L(duP3x):
+-	addi	rSTR1,rSTR1,16
+-	addi	rSTR2,rSTR2,16
+-	bne	cr1,L(duLcr1)
+-	cmpld	cr5,rWORD7,rWORD8
+-	bne	cr6,L(duLcr6)
+-	sldi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
+-	cmpld	cr7,rN,rSHR
++#ifndef __LITTLE_ENDIAN__
++	addi	rSTR1, rSTR1, 16
++	addi	rSTR2, rSTR2, 16
++#endif
++#if 0
++/* Huh?  We've already branched on cr1!  */
++	bne	cr1, L(duLcr1)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
++	bne	cr6, L(duLcr6)
++	sldi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
++	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	ld	rWORD2,8(rSTR2)
+-	srd	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD2, 8(rSTR2)
++#endif
++	srd	r0, rWORD2, rSHR
+ 	b	L(dutrim)
+ 
+ /* Count is a multiple of 32, remainder is 0 */
+ 	.align	4
+ L(duP4):
+-	mtctr	rTMP
+-	srd	rA,rWORD8,rSHR
+-	ld	rWORD1,0(rSTR1)
+-	sld	rD,rWORD8,rSHL
+-	or	rWORD2,rA,rH
++	mtctr	r0
++	srd	r0, rWORD8, rSHR
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	addi	rSTR1, rSTR1, 8
++#else
++	ld	rWORD1, 0(rSTR1)
++#endif
++	sld	rWORD2_SHIFT, rWORD8, rSHL
++	or	rWORD2, r0, rWORD6_SHIFT
+ L(duP4e):
+-	ld	rWORD3,8(rSTR1)
+-	ld	rWORD4,8(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
+-	srd	rC,rWORD4,rSHR
+-	sld	rF,rWORD4,rSHL
+-	or	rWORD4,rC,rD
+-	ld	rWORD5,16(rSTR1)
+-	ld	rWORD6,16(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
+-	bne	cr0,L(duLcr0)
+-	srd	rE,rWORD6,rSHR
+-	sld	rH,rWORD6,rSHL
+-	or	rWORD6,rE,rF
+-	ldu	rWORD7,24(rSTR1)
+-	ldu	rWORD8,24(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	bne	cr1,L(duLcr1)
+-	srd	rG,rWORD8,rSHR
+-	sld	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
+-	cmpld	cr5,rWORD7,rWORD8
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++	srd	r12, rWORD4, rSHR
++	sld	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 16(rSTR1)
++	ld	rWORD6, 16(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++	bne	cr7, L(duLcr7)
++	srd	r0, rWORD6, rSHR
++	sld	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ldu	rWORD7, 24(rSTR1)
++	ldu	rWORD8, 24(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++	bne	cr1, L(duLcr1)
++	srd	r12, rWORD8, rSHR
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
++	cmpld	cr5, rWORD7, rWORD8
+ 	bdz	L(du24)		/* Adjust CTR as we start with +4 */
+ /* This is the primary loop */
+ 	.align	4
+ L(duLoop):
+-	ld	rWORD1,8(rSTR1)
+-	ld	rWORD2,8(rSTR2)
+-	cmpld	cr1,rWORD3,rWORD4
+-	bne	cr6,L(duLcr6)
+-	srd	rA,rWORD2,rSHR
+-	sld	rD,rWORD2,rSHL
+-	or	rWORD2,rA,rB
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD1, 8(rSTR1)
++	ld	rWORD2, 8(rSTR2)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++	bne	cr6, L(duLcr6)
++	srd	r0, rWORD2, rSHR
++	sld	rWORD2_SHIFT, rWORD2, rSHL
++	or	rWORD2, r0, rWORD8_SHIFT
+ L(duLoop1):
+-	ld	rWORD3,16(rSTR1)
+-	ld	rWORD4,16(rSTR2)
+-	cmpld	cr6,rWORD5,rWORD6
+-	bne	cr5,L(duLcr5)
+-	srd	rC,rWORD4,rSHR
+-	sld	rF,rWORD4,rSHL
+-	or	rWORD4,rC,rD
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD3, 0, rSTR1
++	ldbrx	rWORD4, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD3, 16(rSTR1)
++	ld	rWORD4, 16(rSTR2)
++#endif
++	cmpld	cr6, rWORD5, rWORD6
++	bne	cr5, L(duLcr5)
++	srd	r12, rWORD4, rSHR
++	sld	rWORD4_SHIFT, rWORD4, rSHL
++	or	rWORD4, r12, rWORD2_SHIFT
+ L(duLoop2):
+-	ld	rWORD5,24(rSTR1)
+-	ld	rWORD6,24(rSTR2)
+-	cmpld	cr5,rWORD7,rWORD8
+-	bne	cr0,L(duLcr0)
+-	srd	rE,rWORD6,rSHR
+-	sld	rH,rWORD6,rSHL
+-	or	rWORD6,rE,rF
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD5, 0, rSTR1
++	ldbrx	rWORD6, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD5, 24(rSTR1)
++	ld	rWORD6, 24(rSTR2)
++#endif
++	cmpld	cr5, rWORD7, rWORD8
++	bne	cr7, L(duLcr7)
++	srd	r0, rWORD6, rSHR
++	sld	rWORD6_SHIFT, rWORD6, rSHL
++	or	rWORD6, r0, rWORD4_SHIFT
+ L(duLoop3):
+-	ldu	rWORD7,32(rSTR1)
+-	ldu	rWORD8,32(rSTR2)
+-	cmpld	cr0,rWORD1,rWORD2
+-	bne-	cr1,L(duLcr1)
+-	srd	rG,rWORD8,rSHR
+-	sld	rB,rWORD8,rSHL
+-	or	rWORD8,rG,rH
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD7, 0, rSTR1
++	ldbrx	rWORD8, 0, rSTR2
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++#else
++	ldu	rWORD7, 32(rSTR1)
++	ldu	rWORD8, 32(rSTR2)
++#endif
++	cmpld	cr7, rWORD1, rWORD2
++	bne	cr1, L(duLcr1)
++	srd	r12, rWORD8, rSHR
++	sld	rWORD8_SHIFT, rWORD8, rSHL
++	or	rWORD8, r12, rWORD6_SHIFT
+ 	bdnz	L(duLoop)
+ 
+ L(duL4):
+-	bne	cr1,L(duLcr1)
+-	cmpld	cr1,rWORD3,rWORD4
+-	bne	cr6,L(duLcr6)
+-	cmpld	cr6,rWORD5,rWORD6
+-	bne	cr5,L(duLcr5)
+-	cmpld	cr5,rWORD7,rWORD8
++#if 0
++/* Huh?  We've already branched on cr1!  */
++	bne	cr1, L(duLcr1)
++#endif
++	cmpld	cr1, rWORD3, rWORD4
++	bne	cr6, L(duLcr6)
++	cmpld	cr6, rWORD5, rWORD6
++	bne	cr5, L(duLcr5)
++	cmpld	cr5, rWORD7, rWORD8
+ L(du44):
+-	bne	cr0,L(duLcr0)
++	bne	cr7, L(duLcr7)
+ L(du34):
+-	bne	cr1,L(duLcr1)
++	bne	cr1, L(duLcr1)
+ L(du24):
+-	bne	cr6,L(duLcr6)
++	bne	cr6, L(duLcr6)
+ L(du14):
+-	sldi.	rN,rN,3
+-	bne	cr5,L(duLcr5)
++	sldi.	rN, rN, 3
++	bne	cr5, L(duLcr5)
+ /* At this point we have a remainder of 1 to 7 bytes to compare.  We use
+-   shift right double to elliminate bits beyond the compare length.
+-   This allows the use of double word subtract to compute the final
+-   result.
++   shift right double to eliminate bits beyond the compare length.
+ 
+    However it may not be safe to load rWORD2 which may be beyond the
+    string length. So we compare the bit length of the remainder to
+    the right shift count (rSHR). If the bit count is less than or equal
+    we do not need to load rWORD2 (all significant bits are already in
+-   rB).  */
+-	cmpld	cr7,rN,rSHR
++   rWORD8_SHIFT).  */
++	cmpld	cr7, rN, rSHR
+ 	beq	L(duZeroReturn)
+-	li	rA,0
+-	ble	cr7,L(dutrim)
+-	ld	rWORD2,8(rSTR2)
+-	srd	rA,rWORD2,rSHR
++	li	r0, 0
++	ble	cr7, L(dutrim)
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD2, 0, rSTR2
++	addi	rSTR2, rSTR2, 8
++#else
++	ld	rWORD2, 8(rSTR2)
++#endif
++	srd	r0, rWORD2, rSHR
+ 	.align	4
+ L(dutrim):
+-	ld	rWORD1,8(rSTR1)
+-	ld	rWORD8,-8(r1)
+-	subfic	rN,rN,64	/* Shift count is 64 - (rN * 8).  */
+-	or	rWORD2,rA,rB
+-	ld	rWORD7,-16(r1)
+-	ld	r29,-24(r1)
+-	srd	rWORD1,rWORD1,rN
+-	srd	rWORD2,rWORD2,rN
+-	ld	r28,-32(r1)
+-	ld	r27,-40(r1)
+-	li	rRTN,0
+-	cmpld	cr0,rWORD1,rWORD2
+-	ld	r26,-48(r1)
+-	ld	r25,-56(r1)
+-	beq	cr0,L(dureturn24)
+-	li	rRTN,1
+-	ld	r24,-64(r1)
+-	bgtlr	cr0
+-	li	rRTN,-1
+-	blr
+-	.align	4
+-L(duLcr0):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	li	rRTN,1
+-	bgt	cr0,L(dureturn29)
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
+-	li	rRTN,-1
++#ifdef __LITTLE_ENDIAN__
++	ldbrx	rWORD1, 0, rSTR1
++#else
++	ld	rWORD1, 8(rSTR1)
++#endif
++	ld	rWORD8, -8(r1)
++	subfic	rN, rN, 64	/* Shift count is 64 - (rN * 8).  */
++	or	rWORD2, r0, rWORD8_SHIFT
++	ld	rWORD7, -16(r1)
++	ld	rSHL, -24(r1)
++	srd	rWORD1, rWORD1, rN
++	srd	rWORD2, rWORD2, rN
++	ld	rSHR, -32(r1)
++	ld	rWORD8_SHIFT, -40(r1)
++	li	rRTN, 0
++	cmpld	cr7, rWORD1, rWORD2
++	ld	rWORD2_SHIFT, -48(r1)
++	ld	rWORD4_SHIFT, -56(r1)
++	beq	cr7, L(dureturn24)
++	li	rRTN, 1
++	ld	rWORD6_SHIFT, -64(r1)
++	bgtlr	cr7
++	li	rRTN, -1
++	blr
++	.align	4
++L(duLcr7):
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++	li	rRTN, 1
++	bgt	cr7, L(dureturn29)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
++	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	4
+ L(duLcr1):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	li	rRTN,1
+-	bgt	cr1,L(dureturn29)
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
+-	li	rRTN,-1
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++	li	rRTN, 1
++	bgt	cr1, L(dureturn29)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
++	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	4
+ L(duLcr6):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	li	rRTN,1
+-	bgt	cr6,L(dureturn29)
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
+-	li	rRTN,-1
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++	li	rRTN, 1
++	bgt	cr6, L(dureturn29)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
++	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	4
+ L(duLcr5):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
+-	li	rRTN,1
+-	bgt	cr5,L(dureturn29)
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
+-	li	rRTN,-1
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
++	li	rRTN, 1
++	bgt	cr5, L(dureturn29)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
++	li	rRTN, -1
+ 	b	L(dureturn27)
+ 	.align	3
+ L(duZeroReturn):
+-	li	rRTN,0
++	li	rRTN, 0
+ 	.align	4
+ L(dureturn):
+-	ld	rWORD8,-8(r1)
+-	ld	rWORD7,-16(r1)
++	ld	rWORD8, -8(r1)
++	ld	rWORD7, -16(r1)
+ L(dureturn29):
+-	ld	r29,-24(r1)
+-	ld	r28,-32(r1)
++	ld	rSHL, -24(r1)
++	ld	rSHR, -32(r1)
+ L(dureturn27):
+-	ld	r27,-40(r1)
++	ld	rWORD8_SHIFT, -40(r1)
+ L(dureturn26):
+-	ld	r26,-48(r1)
++	ld	rWORD2_SHIFT, -48(r1)
+ L(dureturn25):
+-	ld	r25,-56(r1)
++	ld	rWORD4_SHIFT, -56(r1)
+ L(dureturn24):
+-	ld	r24,-64(r1)
++	ld	rWORD6_SHIFT, -64(r1)
+ 	blr
+ L(duzeroLength):
+-	li	rRTN,0
++	li	rRTN, 0
+ 	blr
+ 
+-END (BP_SYM (memcmp))
++END (memcmp)
+ libc_hidden_builtin_def (memcmp)
+-weak_alias (memcmp,bcmp)
++weak_alias (memcmp, bcmp)
diff --git a/SOURCES/glibc-ppc64le-31.patch b/SOURCES/glibc-ppc64le-31.patch
new file mode 100644
index 0000000..e32bfa3
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-31.patch
@@ -0,0 +1,2943 @@
+# commit 759cfef3ac4c07dba1ece0bbc1207e099348816d
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:47:22 2013 +0930
+# 
+#     PowerPC LE memcpy
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00103.html
+#     
+#     LIttle-endian support for memcpy.  I spent some time cleaning up the
+#     64-bit power7 memcpy, in order to avoid the extra alignment traps
+#     power7 takes for little-endian.  It probably would have been better
+#     to copy the linux kernel version of memcpy.
+#     
+#         * sysdeps/powerpc/powerpc32/power4/memcpy.S: Add little endian support.
+#         * sysdeps/powerpc/powerpc32/power6/memcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/memcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/mempcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/memcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power4/memcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power6/memcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power7/memcpy.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power7/mempcpy.S: Likewise.  Make better
+#         use of regs.  Use power7 mtocrf.  Tidy function tails.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/memcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/memcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/memcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/memcpy.S	2014-05-29 13:04:56.000000000 -0500
+@@ -205,15 +205,28 @@
+     blt   cr6,5f
+     srwi  7,6,16
+     bgt	  cr6,3f
++#ifdef __LITTLE_ENDIAN__
++    sth   7,0(3)
++#else
+     sth   6,0(3)
++#endif
+     b     7f
+     .align  4
+ 3:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,24
++    stb   6,0(3)
++    sth   7,1(3)
++#else
+     stb   7,0(3)
+     sth   6,1(3)
++#endif
+     b     7f
+     .align  4
+ 5:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,8
++#endif
+     stb   6,0(3)
+ 7:
+     cmplwi	cr1,10,16
+@@ -341,13 +354,23 @@
+     bf      30,1f
+ 
+     /* there are at least two words to copy, so copy them */
++#ifdef __LITTLE_ENDIAN__
++    srw   0,6,10
++    slw   8,7,9
++#else
+     slw   0,6,10  /* shift 1st src word to left align it in R0 */
+     srw   8,7,9   /* shift 2nd src word to right align it in R8 */
++#endif
+     or    0,0,8   /* or them to get word to store */
+     lwz   6,8(5)  /* load the 3rd src word */
+     stw   0,0(4)  /* store the 1st dst word */
++#ifdef __LITTLE_ENDIAN__
++    srw   0,7,10
++    slw   8,6,9
++#else
+     slw   0,7,10  /* now left align 2nd src word into R0 */
+     srw   8,6,9   /* shift 3rd src word to right align it in R8 */
++#endif
+     or    0,0,8   /* or them to get word to store */
+     lwz   7,12(5)
+     stw   0,4(4)  /* store the 2nd dst word */
+@@ -355,8 +378,13 @@
+     addi  5,5,16
+     bf    31,4f
+     /* there is a third word to copy, so copy it */
++#ifdef __LITTLE_ENDIAN__
++    srw   0,6,10
++    slw   8,7,9
++#else
+     slw   0,6,10  /* shift 3rd src word to left align it in R0 */
+     srw   8,7,9   /* shift 4th src word to right align it in R8 */
++#endif
+     or    0,0,8   /* or them to get word to store */
+     stw   0,0(4)  /* store 3rd dst word */
+     mr    6,7
+@@ -366,8 +394,13 @@
+     b     4f
+     .align 4
+ 1:
++#ifdef __LITTLE_ENDIAN__
++    srw     0,6,10
++    slw     8,7,9
++#else
+     slw     0,6,10  /* shift 1st src word to left align it in R0 */
+     srw     8,7,9   /* shift 2nd src word to right align it in R8 */
++#endif
+     addi  5,5,8
+     or    0,0,8   /* or them to get word to store */
+     bf    31,4f
+@@ -380,23 +413,43 @@
+     .align  4
+ 4:
+     /* copy 16 bytes at a time */
++#ifdef __LITTLE_ENDIAN__
++    srw   0,6,10
++    slw   8,7,9
++#else
+     slw   0,6,10
+     srw   8,7,9
++#endif
+     or    0,0,8
+     lwz   6,0(5)
+     stw   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srw   0,7,10
++    slw   8,6,9
++#else
+     slw   0,7,10
+     srw   8,6,9
++#endif
+     or    0,0,8
+     lwz   7,4(5)
+     stw   0,4(4)
++#ifdef __LITTLE_ENDIAN__
++    srw   0,6,10
++    slw   8,7,9
++#else
+     slw   0,6,10
+     srw   8,7,9
++#endif
+     or    0,0,8
+     lwz   6,8(5)
+     stw   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srw   0,7,10
++    slw   8,6,9
++#else
+     slw   0,7,10
+     srw   8,6,9
++#endif
+     or    0,0,8
+     lwz   7,12(5)
+     stw   0,12(4)
+@@ -405,8 +458,13 @@
+     bdnz+ 4b
+ 8:
+     /* calculate and store the final word */
++#ifdef __LITTLE_ENDIAN__
++    srw   0,6,10
++    slw   8,7,9
++#else
+     slw   0,6,10
+     srw   8,7,9
++#endif
+     or    0,0,8
+     stw   0,0(4)
+ 3:
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/memcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/memcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/memcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/memcpy.S	2014-05-29 13:04:56.000000000 -0500
+@@ -221,15 +221,28 @@
+     blt   cr6,5f
+     srwi  7,6,16
+     bgt	  cr6,3f
++#ifdef __LITTLE_ENDIAN__
++    sth   7,0(3)
++#else
+     sth   6,0(3)
++#endif
+     b     7f
+     .align  4
+ 3:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,24
++    stb   6,0(3)
++    sth   7,1(3)
++#else
+     stb   7,0(3)
+     sth   6,1(3)
++#endif
+     b     7f
+     .align  4
+ 5:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,8
++#endif
+     stb   6,0(3)
+ 7:
+     cmplwi	cr1,10,16
+@@ -579,7 +592,11 @@
+     lwz     6,-1(4)
+     cmplwi  cr6,31,4
+     srwi    8,31,5    /* calculate the 32 byte loop count */
++#ifdef __LITTLE_ENDIAN__
++    srwi    6,6,8
++#else
+     slwi    6,6,8
++#endif
+     clrlwi  31,31,27   /* The remaining bytes, < 32.  */
+     blt     cr5,L(wdu1_32tail)
+     mtctr   8
+@@ -587,8 +604,12 @@
+ 
+     lwz   8,3(4)
+     lwz   7,4(4)
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,24,32
++#else
+ /*  Equivalent to: srwi   8,8,32-8;  or    6,6,8 */
+     rlwimi 6,8,8,(32-8),31
++#endif
+     b      L(wdu1_loop32x)
+     .align  4
+ L(wdu1_loop32):
+@@ -597,8 +618,12 @@
+     lwz   7,4(4)
+     stw   10,-8(3)
+     stw   11,-4(3)
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,24,32
++#else
+ /*  Equivalent to  srwi   8,8,32-8; or    6,6,8 */
+     rlwimi 6,8,8,(32-8),31
++#endif
+ L(wdu1_loop32x):
+     lwz   10,8(4)
+     lwz   11,12(4)
+@@ -615,7 +640,11 @@
+     stw   6,16(3)
+     stw   7,20(3)
+     addi  3,3,32
++#ifdef __LITTLE_ENDIAN__
++    srwi  6,8,8
++#else
+     slwi  6,8,8
++#endif
+     bdnz+ L(wdu1_loop32)
+     stw   10,-8(3)
+     stw   11,-4(3)
+@@ -626,8 +655,12 @@
+     blt     cr6,L(wdu_4tail)
+     /* calculate and store the final word */
+     lwz   8,3(4)
+-/*  Equivalent to: srwi   8,8,32-9;  or    6,6,8  */
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,24,32
++#else
++/*  Equivalent to: srwi   8,8,32-8;  or    6,6,8  */
+     rlwimi 6,8,8,(32-8),31
++#endif
+     b     L(wdu_32tailx)
+ 
+ L(wdu2_32):
+@@ -635,7 +668,11 @@
+     lwz     6,-2(4)
+     cmplwi  cr6,31,4
+     srwi    8,31,5    /* calculate the 32 byte loop count */
++#ifdef __LITTLE_ENDIAN__
++    srwi    6,6,16
++#else
+     slwi    6,6,16
++#endif
+     clrlwi  31,31,27   /* The remaining bytes, < 32.  */
+     blt     cr5,L(wdu2_32tail)
+     mtctr   8
+@@ -643,8 +680,11 @@
+ 
+     lwz   8,2(4)
+     lwz   7,4(4)
+-/*  Equivalent to: srwi   8,8,32-8;  or    6,6,8 */
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,16,32
++#else
+     rlwimi 6,8,16,(32-16),31
++#endif
+     b      L(wdu2_loop32x)
+     .align  4
+ L(wdu2_loop32):
+@@ -653,8 +693,11 @@
+     lwz   7,4(4)
+     stw   10,-8(3)
+     stw   11,-4(3)
+-/*  Equivalent to  srwi   8,8,32-8; or    6,6,8 */
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,16,32
++#else
+     rlwimi 6,8,16,(32-16),31
++#endif
+ L(wdu2_loop32x):
+     lwz   10,8(4)
+     lwz   11,12(4)
+@@ -672,7 +715,11 @@
+     stw   6,16(3)
+     stw   7,20(3)
+     addi  3,3,32
++#ifdef __LITTLE_ENDIAN__
++    srwi  6,8,16
++#else
+     slwi  6,8,16
++#endif
+     bdnz+ L(wdu2_loop32)
+     stw   10,-8(3)
+     stw   11,-4(3)
+@@ -683,8 +730,11 @@
+     blt     cr6,L(wdu_4tail)
+     /* calculate and store the final word */
+     lwz   8,2(4)
+-/*  Equivalent to: srwi   8,8,32-9;  or    6,6,8  */
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,16,32
++#else
+     rlwimi 6,8,16,(32-16),31
++#endif
+     b     L(wdu_32tailx)
+ 
+ L(wdu3_32):
+@@ -692,7 +742,11 @@
+     lwz     6,-3(4)
+     cmplwi  cr6,31,4
+     srwi    8,31,5    /* calculate the 32 byte loop count */
++#ifdef __LITTLE_ENDIAN__
++    srwi    6,6,24
++#else
+     slwi    6,6,24
++#endif
+     clrlwi  31,31,27   /* The remaining bytes, < 32.  */
+     blt     cr5,L(wdu3_32tail)
+     mtctr   8
+@@ -700,8 +754,11 @@
+ 
+     lwz   8,1(4)
+     lwz   7,4(4)
+-/*  Equivalent to: srwi   8,8,32-8;  or    6,6,8 */
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,8,32
++#else
+     rlwimi 6,8,24,(32-24),31
++#endif
+     b      L(wdu3_loop32x)
+     .align  4
+ L(wdu3_loop32):
+@@ -710,8 +767,11 @@
+     lwz   7,4(4)
+     stw   10,-8(3)
+     stw   11,-4(3)
+-/*  Equivalent to  srwi   8,8,32-8; or    6,6,8 */
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,8,32
++#else
+     rlwimi 6,8,24,(32-24),31
++#endif
+ L(wdu3_loop32x):
+     lwz   10,8(4)
+     lwz   11,12(4)
+@@ -728,7 +788,11 @@
+     stw   6,16(3)
+     stw   7,20(3)
+     addi  3,3,32
++#ifdef __LITTLE_ENDIAN__
++    srwi  6,8,24
++#else
+     slwi  6,8,24
++#endif
+     bdnz+ L(wdu3_loop32)
+     stw   10,-8(3)
+     stw   11,-4(3)
+@@ -739,8 +803,11 @@
+     blt     cr6,L(wdu_4tail)
+     /* calculate and store the final word */
+     lwz   8,1(4)
+-/*  Equivalent to: srwi   8,8,32-9;  or    6,6,8  */
++#ifdef __LITTLE_ENDIAN__
++    rldimi 6,8,8,32
++#else
+     rlwimi 6,8,24,(32-24),31
++#endif
+     b     L(wdu_32tailx)
+     .align  4
+ L(wdu_32tailx):
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memcpy.S	2014-05-29 13:04:56.000000000 -0500
+@@ -385,7 +385,7 @@
+ 
+ 	beq    L(copy_GE_32_unaligned_cont)
+ 
+-	/* SRC is not quadword aligned, get it aligned.  */
++	/* DST is not quadword aligned, get it aligned.  */
+ 
+ 	mtcrf   0x01,0
+ 	subf    31,0,5
+@@ -437,13 +437,21 @@
+ 	mr      11,12
+ 	mtcrf   0x01,9
+ 	cmplwi  cr6,9,1
++#ifdef __LITTLE_ENDIAN__
++	lvsr    5,0,12
++#else
+ 	lvsl    5,0,12
++#endif
+ 	lvx     3,0,12
+ 	bf      31,L(setup_unaligned_loop)
+ 
+ 	/* Copy another 16 bytes to align to 32-bytes due to the loop .  */
+ 	lvx     4,12,6
++#ifdef __LITTLE_ENDIAN__
++	vperm   6,4,3,5
++#else
+ 	vperm   6,3,4,5
++#endif
+ 	addi    11,12,16
+ 	addi    10,3,16
+ 	stvx    6,0,3
+@@ -463,11 +471,17 @@
+ 	vector instructions though.  */
+ 
+ 	lvx	4,11,6	      /* vr4 = r11+16.  */
+-	vperm   6,3,4,5	      /* Merge the correctly-aligned portions
+-			      of vr3/vr4 into vr6.  */
++#ifdef __LITTLE_ENDIAN__
++	vperm   6,4,3,5
++#else
++	vperm   6,3,4,5
++#endif
+ 	lvx	3,11,7	      /* vr3 = r11+32.  */
+-	vperm   10,4,3,5      /* Merge the correctly-aligned portions
+-			      of vr3/vr4 into vr10.  */
++#ifdef __LITTLE_ENDIAN__
++	vperm   10,3,4,5
++#else
++	vperm   10,4,3,5
++#endif
+ 	addi    11,11,32
+ 	stvx    6,0,10
+ 	stvx    10,10,6
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/mempcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/mempcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/mempcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/mempcpy.S	2014-05-29 13:04:56.000000000 -0500
+@@ -327,7 +327,7 @@
+ 
+ 	beq	L(copy_GE_32_unaligned_cont)
+ 
+-	/* SRC is not quadword aligned, get it aligned.  */
++	/* DST is not quadword aligned, get it aligned.  */
+ 
+ 	mtcrf	0x01,0
+ 	subf	31,0,5
+@@ -379,13 +379,21 @@
+ 	mr	11,12
+ 	mtcrf	0x01,9
+ 	cmplwi	cr6,9,1
+-	lvsl	5,0,12
++#ifdef __LITTLE_ENDIAN__
++	lvsr    5,0,12
++#else
++	lvsl    5,0,12
++#endif
+ 	lvx	3,0,12
+ 	bf	31,L(setup_unaligned_loop)
+ 
+ 	/* Copy another 16 bytes to align to 32-bytes due to the loop .  */
+ 	lvx	4,12,6
+-	vperm	6,3,4,5
++#ifdef __LITTLE_ENDIAN__
++	vperm   6,4,3,5
++#else
++	vperm   6,3,4,5
++#endif
+ 	addi	11,12,16
+ 	addi	10,3,16
+ 	stvx	6,0,3
+@@ -405,11 +413,17 @@
+ 	vector instructions though.  */
+ 
+ 	lvx	4,11,6	      /* vr4 = r11+16.  */
+-	vperm	6,3,4,5	      /* Merge the correctly-aligned portions
+-				 of vr3/vr4 into vr6.  */
++#ifdef __LITTLE_ENDIAN__
++	vperm   6,4,3,5
++#else
++	vperm   6,3,4,5
++#endif
+ 	lvx	3,11,7	      /* vr3 = r11+32.  */
+-	vperm	10,4,3,5      /* Merge the correctly-aligned portions
+-				 of vr3/vr4 into vr10.  */
++#ifdef __LITTLE_ENDIAN__
++	vperm   10,3,4,5
++#else
++	vperm   10,4,3,5
++#endif
+ 	addi	11,11,32
+ 	stvx	6,0,10
+ 	stvx	10,10,6
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/memcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/memcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/memcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/memcpy.S	2014-05-29 13:04:56.000000000 -0500
+@@ -214,15 +214,28 @@
+     blt   cr6,5f
+     srdi  7,6,16
+     bgt	  cr6,3f
++#ifdef __LITTLE_ENDIAN__
++    sth   7,0(3)
++#else
+     sth   6,0(3)
++#endif
+     b     7f
+     .align  4
+ 3:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,24
++    stb   6,0(3)
++    sth   7,1(3)
++#else
+     stb   7,0(3)
+     sth   6,1(3)
++#endif
+     b     7f
+     .align  4
+ 5:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,8
++#endif
+     stb   6,0(3)
+ 7:
+     cmpldi	cr1,10,16
+@@ -330,7 +343,11 @@
+     ld    7,8(5)
+     subfic  9,10,64
+     beq   2f
++#ifdef __LITTLE_ENDIAN__
++    srd   0,6,10
++#else
+     sld   0,6,10
++#endif
+     cmpldi  11,1
+     mr    6,7
+     addi  4,4,-8
+@@ -338,15 +355,25 @@
+     b     1f
+ 2:  addi  5,5,8
+     .align  4
++#ifdef __LITTLE_ENDIAN__
++0:  srd   0,6,10
++    sld   8,7,9
++#else
+ 0:  sld   0,6,10
+     srd   8,7,9
++#endif
+     cmpldi  11,2
+     ld    6,8(5)
+     or    0,0,8
+     addi  11,11,-2
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srd   0,7,10
++1:  sld   8,6,9
++#else
+     sld   0,7,10
+ 1:  srd   8,6,9
++#endif
+     or    0,0,8
+     beq   8f
+     ld    7,16(5)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power4/memcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power4/memcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power4/memcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power4/memcpy.S	2014-05-29 13:05:51.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Optimized memcpy implementation for PowerPC64.
+-   Copyright (C) 2003, 2006, 2011 Free Software Foundation, Inc.
++   Copyright (C) 2003-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
+@@ -17,26 +17,24 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+ /* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
+    Returns 'dst'.
+ 
+-   Memcpy handles short copies (< 32-bytes) using a binary move blocks 
+-   (no loops) of lwz/stw.  The tail (remaining 1-3) bytes is handled 
+-   with the appropriate combination of byte and halfword load/stores. 
+-   There is minimal effort to optimize the alignment of short moves.  
++   Memcpy handles short copies (< 32-bytes) using a binary move blocks
++   (no loops) of lwz/stw.  The tail (remaining 1-3) bytes is handled
++   with the appropriate combination of byte and halfword load/stores.
++   There is minimal effort to optimize the alignment of short moves.
+    The 64-bit implementations of POWER3 and POWER4 do a reasonable job
+-   of handling unligned load/stores that do not cross 32-byte boundries.
++   of handling unaligned load/stores that do not cross 32-byte boundaries.
+ 
+    Longer moves (>= 32-bytes) justify the effort to get at least the
+    destination doubleword (8-byte) aligned.  Further optimization is
+-   posible when both source and destination are doubleword aligned.
++   possible when both source and destination are doubleword aligned.
+    Each case has a optimized unrolled loop.   */
+ 
+ 	.machine power4
+-EALIGN (BP_SYM (memcpy), 5, 0)
++EALIGN (memcpy, 5, 0)
+ 	CALL_MCOUNT 3
+ 
+     cmpldi cr1,5,31
+@@ -44,20 +42,20 @@
+     std   3,-16(1)
+     std   31,-8(1)
+     cfi_offset(31,-8)
+-    andi. 11,3,7	/* check alignement of dst.  */
++    andi. 11,3,7	/* check alignment of dst.  */
+     clrldi 0,0,61	/* Number of bytes until the 1st doubleword of dst.  */
+-    clrldi 10,4,61	/* check alignement of src.  */
++    clrldi 10,4,61	/* check alignment of src.  */
+     cmpldi cr6,5,8
+     ble-  cr1,.L2	/* If move < 32 bytes use short move code.  */
+-    cmpld cr6,10,11     
++    cmpld cr6,10,11
+     mr    12,4
+     srdi  9,5,3		/* Number of full double words remaining.  */
+     mtcrf 0x01,0
+     mr    31,5
+     beq   .L0
+-  
++
+     subf  31,0,5
+-  /* Move 0-7 bytes as needed to get the destination doubleword alligned.  */
++  /* Move 0-7 bytes as needed to get the destination doubleword aligned.  */
+ 1:  bf    31,2f
+     lbz   6,0(12)
+     addi  12,12,1
+@@ -74,17 +72,17 @@
+     stw   6,0(3)
+     addi  3,3,4
+ 0:
+-    clrldi 10,12,61	/* check alignement of src again.  */     
++    clrldi 10,12,61	/* check alignment of src again.  */
+     srdi  9,31,3	/* Number of full double words remaining.  */
+-    
+-  /* Copy doublewords from source to destination, assumpting the
++
++  /* Copy doublewords from source to destination, assuming the
+      destination is aligned on a doubleword boundary.
+ 
+      At this point we know there are at least 25 bytes left (32-7) to copy.
+-     The next step is to determine if the source is also doubleword aligned. 
++     The next step is to determine if the source is also doubleword aligned.
+      If not branch to the unaligned move code at .L6. which uses
+      a load, shift, store strategy.
+-     
++
+      Otherwise source and destination are doubleword aligned, and we can
+      the optimized doubleword copy loop.  */
+ .L0:
+@@ -97,14 +95,14 @@
+      Use a unrolled loop to copy 4 doubleword (32-bytes) per iteration.
+      If the copy is not an exact multiple of 32 bytes, 1-3
+      doublewords are copied as needed to set up the main loop.  After
+-     the main loop exits there may be a tail of 1-7 bytes. These byte are 
++     the main loop exits there may be a tail of 1-7 bytes. These byte are
+      copied a word/halfword/byte at a time as needed to preserve alignment.  */
+ 
+     srdi  8,31,5
+     cmpldi	cr1,9,4
+     cmpldi	cr6,11,0
+     mr    11,12
+-    
++
+     bf    30,1f
+     ld    6,0(12)
+     ld    7,8(12)
+@@ -115,7 +113,7 @@
+     addi  10,3,16
+     bf    31,4f
+     ld    0,16(12)
+-    std   0,16(3)    
++    std   0,16(3)
+     blt   cr1,3f
+     addi  11,12,24
+     addi  10,3,24
+@@ -129,7 +127,7 @@
+     addi  11,12,8
+     std   6,0(3)
+     addi  10,3,8
+-    
++
+     .align  4
+ 4:
+     ld    6,0(11)
+@@ -144,7 +142,7 @@
+     std   0,24(10)
+     addi  10,10,32
+     bdnz  4b
+-3:  
++3:
+ 
+     rldicr 0,31,0,60
+     mtcrf 0x01,31
+@@ -152,9 +150,9 @@
+ .L9:
+     add   3,3,0
+     add   12,12,0
+-    
++
+ /*  At this point we have a tail of 0-7 bytes and we know that the
+-    destiniation is double word aligned.  */
++    destination is double word aligned.  */
+ 4:  bf    29,2f
+     lwz   6,0(12)
+     addi  12,12,4
+@@ -173,29 +171,29 @@
+     ld 31,-8(1)
+     ld 3,-16(1)
+     blr
+-       
+-/* Copy up to 31 bytes.  This divided into two cases 0-8 bytes and 9-31 
+-   bytes.  Each case is handled without loops, using binary (1,2,4,8) 
+-   tests.  
+-   
++
++/* Copy up to 31 bytes.  This divided into two cases 0-8 bytes and 9-31
++   bytes.  Each case is handled without loops, using binary (1,2,4,8)
++   tests.
++
+    In the short (0-8 byte) case no attempt is made to force alignment
+-   of either source or destination.  The hardware will handle the 
+-   unaligned load/stores with small delays for crossing 32- 64-byte, and 
++   of either source or destination.  The hardware will handle the
++   unaligned load/stores with small delays for crossing 32- 64-byte, and
+    4096-byte boundaries. Since these short moves are unlikely to be
+-   unaligned or cross these boundaries, the overhead to force 
++   unaligned or cross these boundaries, the overhead to force
+    alignment is not justified.
+-   
++
+    The longer (9-31 byte) move is more likely to cross 32- or 64-byte
+    boundaries.  Since only loads are sensitive to the 32-/64-byte
+-   boundaries it is more important to align the source then the 
++   boundaries it is more important to align the source then the
+    destination.  If the source is not already word aligned, we first
+-   move 1-3 bytes as needed.  Since we are only word aligned we don't 
+-   use double word load/stores to insure that all loads are aligned. 
++   move 1-3 bytes as needed.  Since we are only word aligned we don't
++   use double word load/stores to insure that all loads are aligned.
+    While the destination and stores may still be unaligned, this
+    is only an issue for page (4096 byte boundary) crossing, which
+    should be rare for these short moves.  The hardware handles this
+-   case automatically with a small delay.  */ 
+-   
++   case automatically with a small delay.  */
++
+     .align  4
+ .L2:
+     mtcrf 0x01,5
+@@ -216,15 +214,28 @@
+     blt   cr6,5f
+     srdi  7,6,16
+     bgt	  cr6,3f
++#ifdef __LITTLE_ENDIAN__
++    sth   7,0(3)
++#else
+     sth   6,0(3)
++#endif
+     b     7f
+     .align  4
+ 3:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,24
++    stb   6,0(3)
++    sth   7,1(3)
++#else
+     stb   7,0(3)
+     sth   6,1(3)
++#endif
+     b     7f
+     .align  4
+ 5:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,8
++#endif
+     stb   6,0(3)
+ 7:
+     cmpldi	cr1,10,16
+@@ -258,11 +269,11 @@
+     lwz   6,0(12)
+     addi  12,12,4
+     stw   6,0(3)
+-    addi  3,3,4    
++    addi  3,3,4
+ 2:  /* Move 2-3 bytes.  */
+     bf    30,1f
+     lhz   6,0(12)
+-    sth   6,0(3) 
++    sth   6,0(3)
+     bf    31,0f
+     lbz   7,2(12)
+     stb   7,2(3)
+@@ -283,8 +294,8 @@
+     mr    12,4
+     bne   cr6,4f
+ /* Would have liked to use use ld/std here but the 630 processors are
+-   slow for load/store doubles that are not at least word aligned.  
+-   Unaligned Load/Store word execute with only a 1 cycle penaltity.  */
++   slow for load/store doubles that are not at least word aligned.
++   Unaligned Load/Store word execute with only a 1 cycle penalty.  */
+     lwz   6,0(4)
+     lwz   7,4(4)
+     stw   6,0(3)
+@@ -299,14 +310,14 @@
+ 6:
+     bf    30,5f
+     lhz   7,4(4)
+-    sth   7,4(3) 
++    sth   7,4(3)
+     bf    31,0f
+     lbz   8,6(4)
+     stb   8,6(3)
+     ld 3,-16(1)
+     blr
+     .align  4
+-5:  
++5:
+     bf    31,0f
+     lbz   6,4(4)
+     stb   6,4(3)
+@@ -336,13 +347,23 @@
+     bf      30,1f
+ 
+     /* there are at least two DWs to copy */
++#ifdef __LITTLE_ENDIAN__
++    srd     0,6,10
++    sld     8,7,9
++#else
+     sld     0,6,10
+     srd     8,7,9
++#endif
+     or      0,0,8
+     ld      6,16(5)
+     std     0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srd     0,7,10
++    sld     8,6,9
++#else
+     sld     0,7,10
+     srd     8,6,9
++#endif
+     or      0,0,8
+     ld      7,24(5)
+     std     0,8(4)
+@@ -351,8 +372,13 @@
+     blt     cr6,8f  /* if total DWs = 3, then bypass loop */
+     bf      31,4f
+     /* there is a third DW to copy */
++#ifdef __LITTLE_ENDIAN__
++    srd     0,6,10
++    sld     8,7,9
++#else
+     sld     0,6,10
+     srd     8,7,9
++#endif
+     or      0,0,8
+     std     0,0(4)
+     mr      6,7
+@@ -363,8 +389,13 @@
+     b       4f
+     .align 4
+ 1:
++#ifdef __LITTLE_ENDIAN__
++    srd     0,6,10
++    sld     8,7,9
++#else
+     sld     0,6,10
+     srd     8,7,9
++#endif
+     addi    5,5,16
+     or      0,0,8
+     bf      31,4f
+@@ -375,23 +406,44 @@
+     addi    4,4,8
+     .align 4
+ /* copy 32 bytes at a time */
+-4:  sld   0,6,10
++4:
++#ifdef __LITTLE_ENDIAN__
++    srd   0,6,10
++    sld   8,7,9
++#else
++    sld   0,6,10
+     srd   8,7,9
++#endif
+     or    0,0,8
+     ld    6,0(5)
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srd   0,7,10
++    sld   8,6,9
++#else
+     sld   0,7,10
+     srd   8,6,9
++#endif
+     or    0,0,8
+     ld    7,8(5)
+     std   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srd   0,6,10
++    sld   8,7,9
++#else
+     sld   0,6,10
+     srd   8,7,9
++#endif
+     or    0,0,8
+     ld    6,16(5)
+     std   0,16(4)
++#ifdef __LITTLE_ENDIAN__
++    srd   0,7,10
++    sld   8,6,9
++#else
+     sld   0,7,10
+     srd   8,6,9
++#endif
+     or    0,0,8
+     ld    7,24(5)
+     std   0,24(4)
+@@ -401,9 +453,14 @@
+     .align 4
+ 8:
+     /* calculate and store the final DW */
++#ifdef __LITTLE_ENDIAN__
++    srd   0,6,10
++    sld   8,7,9
++#else
+     sld   0,6,10
+     srd   8,7,9
+-    or    0,0,8  
++#endif
++    or    0,0,8
+     std   0,0(4)
+ 3:
+     rldicr 0,31,0,60
+@@ -413,5 +470,5 @@
+     ld 31,-8(1)
+     ld 3,-16(1)
+     blr
+-END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS)
++END_GEN_TB (memcpy,TB_TOCLESS)
+ libc_hidden_builtin_def (memcpy)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power6/memcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power6/memcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power6/memcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power6/memcpy.S	2014-05-29 13:05:27.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Optimized memcpy implementation for PowerPC64.
+-   Copyright (C) 2003, 2006, 2007, 2011 Free Software Foundation, Inc.
++   Copyright (C) 2003-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
+@@ -17,52 +17,50 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+ /* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
+    Returns 'dst'.
+ 
+-   Memcpy handles short copies (< 32-bytes) using a binary move blocks 
+-   (no loops) of lwz/stw.  The tail (remaining 1-3) bytes is handled 
+-   with the appropriate combination of byte and halfword load/stores. 
+-   There is minimal effort to optimize the alignment of short moves.  
++   Memcpy handles short copies (< 32-bytes) using a binary move blocks
++   (no loops) of lwz/stw.  The tail (remaining 1-3) bytes is handled
++   with the appropriate combination of byte and halfword load/stores.
++   There is minimal effort to optimize the alignment of short moves.
+    The 64-bit implementations of POWER3 and POWER4 do a reasonable job
+-   of handling unligned load/stores that do not cross 32-byte boundries.
++   of handling unaligned load/stores that do not cross 32-byte boundaries.
+ 
+    Longer moves (>= 32-bytes) justify the effort to get at least the
+    destination doubleword (8-byte) aligned.  Further optimization is
+-   posible when both source and destination are doubleword aligned.
+-   Each case has a optimized unrolled loop.  
+-     
+-   For POWER6 unaligned loads will take a 20+ cycle hicup for any
++   possible when both source and destination are doubleword aligned.
++   Each case has a optimized unrolled loop.
++
++   For POWER6 unaligned loads will take a 20+ cycle hiccup for any
+    L1 cache miss that crosses a 32- or 128-byte boundary.  Store
+-   is more forgiving and does not take a hicup until page or 
+-   segment boundaries.  So we require doubleword alignment for 
++   is more forgiving and does not take a hiccup until page or
++   segment boundaries.  So we require doubleword alignment for
+    the source but may take a risk and only require word alignment
+    for the destination.  */
+ 
+ 	.machine	"power6"
+-EALIGN (BP_SYM (memcpy), 7, 0)
++EALIGN (memcpy, 7, 0)
+ 	CALL_MCOUNT 3
+ 
+     cmpldi cr1,5,31
+     neg   0,3
+     std   3,-16(1)
+     std   31,-8(1)
+-    andi. 11,3,7	/* check alignement of dst.  */
++    andi. 11,3,7	/* check alignment of dst.  */
+     clrldi 0,0,61	/* Number of bytes until the 1st doubleword of dst.  */
+-    clrldi 10,4,61	/* check alignement of src.  */
++    clrldi 10,4,61	/* check alignment of src.  */
+     cmpldi cr6,5,8
+     ble-  cr1,.L2	/* If move < 32 bytes use short move code.  */
+     mtcrf 0x01,0
+-    cmpld cr6,10,11  
++    cmpld cr6,10,11
+     srdi  9,5,3		/* Number of full double words remaining.  */
+     beq   .L0
+-  
++
+     subf  5,0,5
+-  /* Move 0-7 bytes as needed to get the destination doubleword alligned.
+-     Duplicate some code to maximize fall-throught and minimize agen delays.  */
++  /* Move 0-7 bytes as needed to get the destination doubleword aligned.
++     Duplicate some code to maximize fall-through and minimize agen delays.  */
+ 1:  bf    31,2f
+     lbz   6,0(4)
+     stb   6,0(3)
+@@ -78,7 +76,7 @@
+     lwz   6,1(4)
+     stw   6,1(3)
+     b     0f
+-    
++
+ 2:  bf    30,4f
+     lhz   6,0(4)
+     sth   6,0(3)
+@@ -86,26 +84,26 @@
+     lwz   6,2(4)
+     stw   6,2(3)
+     b     0f
+-    
++
+ 4:  bf    29,0f
+     lwz   6,0(4)
+     stw   6,0(3)
+-0: 
++0:
+ /* Add the number of bytes until the 1st doubleword of dst to src and dst.  */
+     add   4,4,0
+     add   3,3,0
+-    
+-    clrldi 10,4,61	/* check alignement of src again.  */     
++
++    clrldi 10,4,61	/* check alignment of src again.  */
+     srdi  9,5,3	/* Number of full double words remaining.  */
+-    
+-  /* Copy doublewords from source to destination, assumpting the
++
++  /* Copy doublewords from source to destination, assuming the
+      destination is aligned on a doubleword boundary.
+ 
+      At this point we know there are at least 25 bytes left (32-7) to copy.
+-     The next step is to determine if the source is also doubleword aligned. 
++     The next step is to determine if the source is also doubleword aligned.
+      If not branch to the unaligned move code at .L6. which uses
+      a load, shift, store strategy.
+-     
++
+      Otherwise source and destination are doubleword aligned, and we can
+      the optimized doubleword copy loop.  */
+     .align  4
+@@ -123,14 +121,14 @@
+      the main loop exits there may be a tail of 1-7 bytes. These byte
+      are copied a word/halfword/byte at a time as needed to preserve
+      alignment.
+-     
++
+      For POWER6 the L1 is store-through and the L2 is store-in.  The
+      L2 is clocked at half CPU clock so we can store 16 bytes every
+      other cycle.  POWER6 also has a load/store bypass so we can do
+-     load, load, store, store every 2 cycles.  
+-     
++     load, load, store, store every 2 cycles.
++
+      The following code is sensitive to cache line alignment.  Do not
+-     make any change with out first making sure thay don't result in
++     make any change with out first making sure they don't result in
+      splitting ld/std pairs across a cache line.  */
+ 
+     mtcrf 0x02,5
+@@ -273,7 +271,7 @@
+     std   8,16+96(10)
+     std   0,24+96(10)
+     ble   cr5,L(das_loop_e)
+-    
++
+     mtctr   12
+     .align  4
+ L(das_loop2):
+@@ -326,10 +324,10 @@
+     .align  4
+ L(das_tail):
+     beq   cr1,0f
+-    
++
+ L(das_tail2):
+ /*  At this point we have a tail of 0-7 bytes and we know that the
+-    destiniation is double word aligned.  */
++    destination is double word aligned.  */
+ 4:  bf    29,2f
+     lwz   6,0(4)
+     stw   6,0(3)
+@@ -344,7 +342,7 @@
+     lbz   6,4(4)
+     stb   6,4(3)
+     b     0f
+-  
++
+ 2:  bf    30,1f
+     lhz   6,0(4)
+     sth   6,0(3)
+@@ -352,7 +350,7 @@
+     lbz   6,2(4)
+     stb   6,2(3)
+     b     0f
+-    
++
+ 1:  bf    31,0f
+     lbz   6,0(4)
+     stb   6,0(3)
+@@ -361,7 +359,7 @@
+     ld 3,-16(1)
+     blr
+ 
+-/* Copy up to 31 bytes.  This divided into two cases 0-8 bytes and 9-31 
++/* Copy up to 31 bytes.  This divided into two cases 0-8 bytes and 9-31
+    bytes.  Each case is handled without loops, using binary (1,2,4,8)
+    tests.
+ 
+@@ -402,15 +400,28 @@
+     blt   cr6,5f
+     srdi  7,6,16
+     bgt	  cr6,3f
++#ifdef __LITTLE_ENDIAN__
++    sth   7,0(3)
++#else
+     sth   6,0(3)
++#endif
+     b     7f
+     .align  4
+ 3:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,24
++    stb   6,0(3)
++    sth   7,1(3)
++#else
+     stb   7,0(3)
+     sth   6,1(3)
++#endif
+     b     7f
+     .align  4
+ 5:
++#ifdef __LITTLE_ENDIAN__
++    rotlwi 6,6,8
++#endif
+     stb   6,0(3)
+ 7:
+     cmpldi	cr1,10,16
+@@ -421,7 +432,7 @@
+ /* At least 6 bytes left and the source is word aligned.  This allows
+    some speculative loads up front.  */
+ /* We need to special case the fall-through because the biggest delays
+-   are due to address computation not being ready in time for the 
++   are due to address computation not being ready in time for the
+    AGEN.  */
+     lwz   6,0(12)
+     lwz   7,4(12)
+@@ -452,7 +463,7 @@
+     ld    3,-16(1)
+     blr
+     .align  4
+-L(dus_tail16p8):  /* less then 8 bytes left.  */
++L(dus_tail16p8):  /* less than 8 bytes left.  */
+     beq   cr1,L(dus_tailX) /* exactly 16 bytes, early exit.  */
+     cmpldi	cr1,10,20
+     bf    29,L(dus_tail16p2)
+@@ -466,7 +477,7 @@
+     ld    3,-16(1)
+     blr
+     .align  4
+-L(dus_tail16p4):  /* less then 4 bytes left.  */
++L(dus_tail16p4):  /* less than 4 bytes left.  */
+     addi  12,12,24
+     addi  3,3,24
+     bgt   cr0,L(dus_tail2)
+@@ -474,7 +485,7 @@
+     ld    3,-16(1)
+     blr
+     .align  4
+-L(dus_tail16p2):  /* 16 bytes moved, less then 4 bytes left.  */
++L(dus_tail16p2):  /* 16 bytes moved, less than 4 bytes left.  */
+     addi  12,12,16
+     addi  3,3,16
+     b     L(dus_tail2)
+@@ -499,7 +510,7 @@
+     ld    3,-16(1)
+     blr
+     .align  4
+-L(dus_tail8p4):  /* less then 4 bytes left.  */
++L(dus_tail8p4):  /* less than 4 bytes left.  */
+     addi  12,12,8
+     addi  3,3,8
+     bgt   cr1,L(dus_tail2)
+@@ -510,14 +521,14 @@
+     .align  4
+ L(dus_tail4):  /* Move 4 bytes.  */
+ /*  r6 already loaded speculatively.  If we are here we know there is
+-    more then 4 bytes left.  So there is no need to test.  */
++    more than 4 bytes left.  So there is no need to test.  */
+     addi  12,12,4
+     stw   6,0(3)
+     addi  3,3,4
+ L(dus_tail2):  /* Move 2-3 bytes.  */
+     bf    30,L(dus_tail1)
+     lhz   6,0(12)
+-    sth   6,0(3) 
++    sth   6,0(3)
+     bf    31,L(dus_tailX)
+     lbz   7,2(12)
+     stb   7,2(3)
+@@ -537,7 +548,7 @@
+ .LE8:
+     mr    12,4
+     bne   cr6,L(dus_4)
+-/* Exactly 8 bytes.  We may cross a 32-/128-byte boundry and take a ~20
++/* Exactly 8 bytes.  We may cross a 32-/128-byte boundary and take a ~20
+    cycle delay.  This case should be rare and any attempt to avoid this
+    would take most of 20 cycles any way.  */
+     ld   6,0(4)
+@@ -552,7 +563,7 @@
+     stw   6,0(3)
+     bf    30,L(dus_5)
+     lhz   7,4(4)
+-    sth   7,4(3) 
++    sth   7,4(3)
+     bf    31,L(dus_0)
+     lbz   8,6(4)
+     stb   8,6(3)
+@@ -590,20 +601,31 @@
+     bge     cr0, L(du4_do)
+     blt     cr5, L(du1_do)
+     beq     cr5, L(du2_do)
+-    b       L(du3_do) 
+-       
++    b       L(du3_do)
++
+     .align 4
+ L(du1_do):
+     bf      30,L(du1_1dw)
+ 
+     /* there are at least two DWs to copy */
++    /* FIXME: can combine last shift and "or" into "rldimi" */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 8
++    sldi     8,7, 64-8
++#else
+     sldi     0,6, 8
+     srdi     8,7, 64-8
++#endif
+     or      0,0,8
+     ld      6,16(5)
+     std     0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,7, 8
++    sldi     8,6, 64-8
++#else
+     sldi     0,7, 8
+     srdi     8,6, 64-8
++#endif
+     or      0,0,8
+     ld      7,24(5)
+     std     0,8(4)
+@@ -612,8 +634,13 @@
+     blt     cr6,L(du1_fini)  /* if total DWs = 3, then bypass loop */
+     bf      31,L(du1_loop)
+     /* there is a third DW to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 8
++    sldi     8,7, 64-8
++#else
+     sldi     0,6, 8
+     srdi     8,7, 64-8
++#endif
+     or      0,0,8
+     std     0,0(4)
+     mr      6,7
+@@ -624,8 +651,13 @@
+     b       L(du1_loop)
+     .align 4
+ L(du1_1dw):
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 8
++    sldi     8,7, 64-8
++#else
+     sldi     0,6, 8
+     srdi     8,7, 64-8
++#endif
+     addi    5,5,16
+     or      0,0,8
+     bf      31,L(du1_loop)
+@@ -637,23 +669,43 @@
+     .align 4
+ /* copy 32 bytes at a time */
+ L(du1_loop):
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 8
++    sldi   8,7, 64-8
++#else
+     sldi   0,6, 8
+     srdi   8,7, 64-8
++#endif
+     or    0,0,8
+     ld    6,0(5)
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 8
++    sldi   8,6, 64-8
++#else
+     sldi   0,7, 8
+     srdi   8,6, 64-8
++#endif
+     or    0,0,8
+     ld    7,8(5)
+     std   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 8
++    sldi   8,7, 64-8
++#else
+     sldi   0,6, 8
+     srdi   8,7, 64-8
++#endif
+     or    0,0,8
+     ld    6,16(5)
+     std   0,16(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 8
++    sldi   8,6, 64-8
++#else
+     sldi   0,7, 8
+     srdi   8,6, 64-8
++#endif
+     or    0,0,8
+     ld    7,24(5)
+     std   0,24(4)
+@@ -663,9 +715,14 @@
+     .align 4
+ L(du1_fini):
+     /* calculate and store the final DW */
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 8
++    sldi   8,7, 64-8
++#else
+     sldi   0,6, 8
+     srdi   8,7, 64-8
+-    or    0,0,8  
++#endif
++    or    0,0,8
+     std   0,0(4)
+     b     L(du_done)
+ 
+@@ -674,13 +731,23 @@
+     bf      30,L(du2_1dw)
+ 
+     /* there are at least two DWs to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 16
++    sldi     8,7, 64-16
++#else
+     sldi     0,6, 16
+     srdi     8,7, 64-16
++#endif
+     or      0,0,8
+     ld      6,16(5)
+     std     0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,7, 16
++    sldi     8,6, 64-16
++#else
+     sldi     0,7, 16
+     srdi     8,6, 64-16
++#endif
+     or      0,0,8
+     ld      7,24(5)
+     std     0,8(4)
+@@ -689,8 +756,13 @@
+     blt     cr6,L(du2_fini)  /* if total DWs = 3, then bypass loop */
+     bf      31,L(du2_loop)
+     /* there is a third DW to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 16
++    sldi     8,7, 64-16
++#else
+     sldi     0,6, 16
+     srdi     8,7, 64-16
++#endif
+     or      0,0,8
+     std     0,0(4)
+     mr      6,7
+@@ -701,8 +773,13 @@
+     b       L(du2_loop)
+     .align 4
+ L(du2_1dw):
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 16
++    sldi     8,7, 64-16
++#else
+     sldi     0,6, 16
+     srdi     8,7, 64-16
++#endif
+     addi    5,5,16
+     or      0,0,8
+     bf      31,L(du2_loop)
+@@ -714,23 +791,43 @@
+     .align 4
+ /* copy 32 bytes at a time */
+ L(du2_loop):
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 16
++    sldi   8,7, 64-16
++#else
+     sldi   0,6, 16
+     srdi   8,7, 64-16
++#endif
+     or    0,0,8
+     ld    6,0(5)
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 16
++    sldi   8,6, 64-16
++#else
+     sldi   0,7, 16
+     srdi   8,6, 64-16
++#endif
+     or    0,0,8
+     ld    7,8(5)
+     std   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 16
++    sldi   8,7, 64-16
++#else
+     sldi   0,6, 16
+     srdi   8,7, 64-16
++#endif
+     or    0,0,8
+     ld    6,16(5)
+     std   0,16(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 16
++    sldi   8,6, 64-16
++#else
+     sldi   0,7, 16
+     srdi   8,6, 64-16
++#endif
+     or    0,0,8
+     ld    7,24(5)
+     std   0,24(4)
+@@ -740,9 +837,14 @@
+     .align 4
+ L(du2_fini):
+     /* calculate and store the final DW */
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 16
++    sldi   8,7, 64-16
++#else
+     sldi   0,6, 16
+     srdi   8,7, 64-16
+-    or    0,0,8  
++#endif
++    or    0,0,8
+     std   0,0(4)
+     b     L(du_done)
+ 
+@@ -751,13 +853,23 @@
+     bf      30,L(du3_1dw)
+ 
+     /* there are at least two DWs to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 24
++    sldi     8,7, 64-24
++#else
+     sldi     0,6, 24
+     srdi     8,7, 64-24
++#endif
+     or      0,0,8
+     ld      6,16(5)
+     std     0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,7, 24
++    sldi     8,6, 64-24
++#else
+     sldi     0,7, 24
+     srdi     8,6, 64-24
++#endif
+     or      0,0,8
+     ld      7,24(5)
+     std     0,8(4)
+@@ -766,8 +878,13 @@
+     blt     cr6,L(du3_fini)  /* if total DWs = 3, then bypass loop */
+     bf      31,L(du3_loop)
+     /* there is a third DW to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 24
++    sldi     8,7, 64-24
++#else
+     sldi     0,6, 24
+     srdi     8,7, 64-24
++#endif
+     or      0,0,8
+     std     0,0(4)
+     mr      6,7
+@@ -778,8 +895,13 @@
+     b       L(du3_loop)
+     .align 4
+ L(du3_1dw):
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 24
++    sldi     8,7, 64-24
++#else
+     sldi     0,6, 24
+     srdi     8,7, 64-24
++#endif
+     addi    5,5,16
+     or      0,0,8
+     bf      31,L(du3_loop)
+@@ -791,23 +913,43 @@
+     .align 4
+ /* copy 32 bytes at a time */
+ L(du3_loop):
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 24
++    sldi   8,7, 64-24
++#else
+     sldi   0,6, 24
+     srdi   8,7, 64-24
++#endif
+     or    0,0,8
+     ld    6,0(5)
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 24
++    sldi   8,6, 64-24
++#else
+     sldi   0,7, 24
+     srdi   8,6, 64-24
++#endif
+     or    0,0,8
+     ld    7,8(5)
+     std   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 24
++    sldi   8,7, 64-24
++#else
+     sldi   0,6, 24
+     srdi   8,7, 64-24
++#endif
+     or    0,0,8
+     ld    6,16(5)
+     std   0,16(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 24
++    sldi   8,6, 64-24
++#else
+     sldi   0,7, 24
+     srdi   8,6, 64-24
++#endif
+     or    0,0,8
+     ld    7,24(5)
+     std   0,24(4)
+@@ -817,9 +959,14 @@
+     .align 4
+ L(du3_fini):
+     /* calculate and store the final DW */
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 24
++    sldi   8,7, 64-24
++#else
+     sldi   0,6, 24
+     srdi   8,7, 64-24
+-    or    0,0,8  
++#endif
++    or    0,0,8
+     std   0,0(4)
+     b     L(du_done)
+ 
+@@ -834,13 +981,23 @@
+     bf      30,L(du4_1dw)
+ 
+     /* there are at least two DWs to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 32
++    sldi     8,7, 64-32
++#else
+     sldi     0,6, 32
+     srdi     8,7, 64-32
++#endif
+     or      0,0,8
+     ld      6,16(5)
+     std     0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,7, 32
++    sldi     8,6, 64-32
++#else
+     sldi     0,7, 32
+     srdi     8,6, 64-32
++#endif
+     or      0,0,8
+     ld      7,24(5)
+     std     0,8(4)
+@@ -849,8 +1006,13 @@
+     blt     cr6,L(du4_fini)  /* if total DWs = 3, then bypass loop */
+     bf      31,L(du4_loop)
+     /* there is a third DW to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 32
++    sldi     8,7, 64-32
++#else
+     sldi     0,6, 32
+     srdi     8,7, 64-32
++#endif
+     or      0,0,8
+     std     0,0(4)
+     mr      6,7
+@@ -861,8 +1023,13 @@
+     b       L(du4_loop)
+     .align 4
+ L(du4_1dw):
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 32
++    sldi     8,7, 64-32
++#else
+     sldi     0,6, 32
+     srdi     8,7, 64-32
++#endif
+     addi    5,5,16
+     or      0,0,8
+     bf      31,L(du4_loop)
+@@ -874,23 +1041,43 @@
+     .align 4
+ /* copy 32 bytes at a time */
+ L(du4_loop):
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 32
++    sldi   8,7, 64-32
++#else
+     sldi   0,6, 32
+     srdi   8,7, 64-32
++#endif
+     or    0,0,8
+     ld    6,0(5)
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 32
++    sldi   8,6, 64-32
++#else
+     sldi   0,7, 32
+     srdi   8,6, 64-32
++#endif
+     or    0,0,8
+     ld    7,8(5)
+     std   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 32
++    sldi   8,7, 64-32
++#else
+     sldi   0,6, 32
+     srdi   8,7, 64-32
++#endif
+     or    0,0,8
+     ld    6,16(5)
+     std   0,16(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 32
++    sldi   8,6, 64-32
++#else
+     sldi   0,7, 32
+     srdi   8,6, 64-32
++#endif
+     or    0,0,8
+     ld    7,24(5)
+     std   0,24(4)
+@@ -900,9 +1087,14 @@
+     .align 4
+ L(du4_fini):
+     /* calculate and store the final DW */
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 32
++    sldi   8,7, 64-32
++#else
+     sldi   0,6, 32
+     srdi   8,7, 64-32
+-    or    0,0,8  
++#endif
++    or    0,0,8
+     std   0,0(4)
+     b     L(du_done)
+ 
+@@ -911,13 +1103,23 @@
+     bf      30,L(du5_1dw)
+ 
+     /* there are at least two DWs to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 40
++    sldi     8,7, 64-40
++#else
+     sldi     0,6, 40
+     srdi     8,7, 64-40
++#endif
+     or      0,0,8
+     ld      6,16(5)
+     std     0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,7, 40
++    sldi     8,6, 64-40
++#else
+     sldi     0,7, 40
+     srdi     8,6, 64-40
++#endif
+     or      0,0,8
+     ld      7,24(5)
+     std     0,8(4)
+@@ -926,8 +1128,13 @@
+     blt     cr6,L(du5_fini)  /* if total DWs = 3, then bypass loop */
+     bf      31,L(du5_loop)
+     /* there is a third DW to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 40
++    sldi     8,7, 64-40
++#else
+     sldi     0,6, 40
+     srdi     8,7, 64-40
++#endif
+     or      0,0,8
+     std     0,0(4)
+     mr      6,7
+@@ -938,8 +1145,13 @@
+     b       L(du5_loop)
+     .align 4
+ L(du5_1dw):
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 40
++    sldi     8,7, 64-40
++#else
+     sldi     0,6, 40
+     srdi     8,7, 64-40
++#endif
+     addi    5,5,16
+     or      0,0,8
+     bf      31,L(du5_loop)
+@@ -951,23 +1163,43 @@
+     .align 4
+ /* copy 32 bytes at a time */
+ L(du5_loop):
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 40
++    sldi   8,7, 64-40
++#else
+     sldi   0,6, 40
+     srdi   8,7, 64-40
++#endif
+     or    0,0,8
+     ld    6,0(5)
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 40
++    sldi   8,6, 64-40
++#else
+     sldi   0,7, 40
+     srdi   8,6, 64-40
++#endif
+     or    0,0,8
+     ld    7,8(5)
+     std   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 40
++    sldi   8,7, 64-40
++#else
+     sldi   0,6, 40
+     srdi   8,7, 64-40
++#endif
+     or    0,0,8
+     ld    6,16(5)
+     std   0,16(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 40
++    sldi   8,6, 64-40
++#else
+     sldi   0,7, 40
+     srdi   8,6, 64-40
++#endif
+     or    0,0,8
+     ld    7,24(5)
+     std   0,24(4)
+@@ -977,9 +1209,14 @@
+     .align 4
+ L(du5_fini):
+     /* calculate and store the final DW */
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 40
++    sldi   8,7, 64-40
++#else
+     sldi   0,6, 40
+     srdi   8,7, 64-40
+-    or    0,0,8  
++#endif
++    or    0,0,8
+     std   0,0(4)
+     b     L(du_done)
+ 
+@@ -988,13 +1225,23 @@
+     bf      30,L(du6_1dw)
+ 
+     /* there are at least two DWs to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 48
++    sldi     8,7, 64-48
++#else
+     sldi     0,6, 48
+     srdi     8,7, 64-48
++#endif
+     or      0,0,8
+     ld      6,16(5)
+     std     0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,7, 48
++    sldi     8,6, 64-48
++#else
+     sldi     0,7, 48
+     srdi     8,6, 64-48
++#endif
+     or      0,0,8
+     ld      7,24(5)
+     std     0,8(4)
+@@ -1003,8 +1250,13 @@
+     blt     cr6,L(du6_fini)  /* if total DWs = 3, then bypass loop */
+     bf      31,L(du6_loop)
+     /* there is a third DW to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 48
++    sldi     8,7, 64-48
++#else
+     sldi     0,6, 48
+     srdi     8,7, 64-48
++#endif
+     or      0,0,8
+     std     0,0(4)
+     mr      6,7
+@@ -1015,8 +1267,13 @@
+     b       L(du6_loop)
+     .align 4
+ L(du6_1dw):
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 48
++    sldi     8,7, 64-48
++#else
+     sldi     0,6, 48
+     srdi     8,7, 64-48
++#endif
+     addi    5,5,16
+     or      0,0,8
+     bf      31,L(du6_loop)
+@@ -1028,23 +1285,43 @@
+     .align 4
+ /* copy 32 bytes at a time */
+ L(du6_loop):
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 48
++    sldi   8,7, 64-48
++#else
+     sldi   0,6, 48
+     srdi   8,7, 64-48
++#endif
+     or    0,0,8
+     ld    6,0(5)
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 48
++    sldi   8,6, 64-48
++#else
+     sldi   0,7, 48
+     srdi   8,6, 64-48
++#endif
+     or    0,0,8
+     ld    7,8(5)
+     std   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 48
++    sldi   8,7, 64-48
++#else
+     sldi   0,6, 48
+     srdi   8,7, 64-48
++#endif
+     or    0,0,8
+     ld    6,16(5)
+     std   0,16(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 48
++    sldi   8,6, 64-48
++#else
+     sldi   0,7, 48
+     srdi   8,6, 64-48
++#endif
+     or    0,0,8
+     ld    7,24(5)
+     std   0,24(4)
+@@ -1054,9 +1331,14 @@
+     .align 4
+ L(du6_fini):
+     /* calculate and store the final DW */
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 48
++    sldi   8,7, 64-48
++#else
+     sldi   0,6, 48
+     srdi   8,7, 64-48
+-    or    0,0,8  
++#endif
++    or    0,0,8
+     std   0,0(4)
+     b     L(du_done)
+ 
+@@ -1065,13 +1347,23 @@
+     bf      30,L(du7_1dw)
+ 
+     /* there are at least two DWs to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 56
++    sldi     8,7, 64-56
++#else
+     sldi     0,6, 56
+     srdi     8,7, 64-56
++#endif
+     or      0,0,8
+     ld      6,16(5)
+     std     0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,7, 56
++    sldi     8,6, 64-56
++#else
+     sldi     0,7, 56
+     srdi     8,6, 64-56
++#endif
+     or      0,0,8
+     ld      7,24(5)
+     std     0,8(4)
+@@ -1080,8 +1372,13 @@
+     blt     cr6,L(du7_fini)  /* if total DWs = 3, then bypass loop */
+     bf      31,L(du7_loop)
+     /* there is a third DW to copy */
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 56
++    sldi     8,7, 64-56
++#else
+     sldi     0,6, 56
+     srdi     8,7, 64-56
++#endif
+     or      0,0,8
+     std     0,0(4)
+     mr      6,7
+@@ -1092,8 +1389,13 @@
+     b       L(du7_loop)
+     .align 4
+ L(du7_1dw):
++#ifdef __LITTLE_ENDIAN__
++    srdi     0,6, 56
++    sldi     8,7, 64-56
++#else
+     sldi     0,6, 56
+     srdi     8,7, 64-56
++#endif
+     addi    5,5,16
+     or      0,0,8
+     bf      31,L(du7_loop)
+@@ -1105,23 +1407,43 @@
+     .align 4
+ /* copy 32 bytes at a time */
+ L(du7_loop):
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 56
++    sldi   8,7, 64-56
++#else
+     sldi   0,6, 56
+     srdi   8,7, 64-56
++#endif
+     or    0,0,8
+     ld    6,0(5)
+     std   0,0(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 56
++    sldi   8,6, 64-56
++#else
+     sldi   0,7, 56
+     srdi   8,6, 64-56
++#endif
+     or    0,0,8
+     ld    7,8(5)
+     std   0,8(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 56
++    sldi   8,7, 64-56
++#else
+     sldi   0,6, 56
+     srdi   8,7, 64-56
++#endif
+     or    0,0,8
+     ld    6,16(5)
+     std   0,16(4)
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,7, 56
++    sldi   8,6, 64-56
++#else
+     sldi   0,7, 56
+     srdi   8,6, 64-56
++#endif
+     or    0,0,8
+     ld    7,24(5)
+     std   0,24(4)
+@@ -1131,12 +1453,17 @@
+     .align 4
+ L(du7_fini):
+     /* calculate and store the final DW */
++#ifdef __LITTLE_ENDIAN__
++    srdi   0,6, 56
++    sldi   8,7, 64-56
++#else
+     sldi   0,6, 56
+     srdi   8,7, 64-56
+-    or    0,0,8  
++#endif
++    or    0,0,8
+     std   0,0(4)
+     b     L(du_done)
+-    
++
+     .align 4
+ L(du_done):
+     rldicr 0,31,0,60
+@@ -1144,9 +1471,9 @@
+     beq   cr1,0f	/* If the tail is 0 bytes we are done!  */
+ 
+     add   3,3,0
+-    add   12,12,0    
++    add   12,12,0
+ /*  At this point we have a tail of 0-7 bytes and we know that the
+-    destiniation is double word aligned.  */
++    destination is double word aligned.  */
+ 4:  bf    29,2f
+     lwz   6,0(12)
+     addi  12,12,4
+@@ -1165,5 +1492,5 @@
+     ld 31,-8(1)
+     ld 3,-16(1)
+     blr
+-END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS)
++END_GEN_TB (memcpy,TB_TOCLESS)
+ libc_hidden_builtin_def (memcpy)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memcpy.S	2014-05-29 13:05:40.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Optimized memcpy implementation for PowerPC64/POWER7.
+-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
++   Copyright (C) 2010-2014 Free Software Foundation, Inc.
+    Contributed by Luis Machado <luisgpm@br.ibm.com>.
+    This file is part of the GNU C Library.
+ 
+@@ -18,425 +18,366 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+ 
+ /* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
+    Returns 'dst'.  */
+ 
++#define dst 11		/* Use r11 so r3 kept unchanged.  */
++#define src 4
++#define cnt 5
++
+ 	.machine power7
+-EALIGN (BP_SYM (memcpy), 5, 0)
++EALIGN (memcpy, 5, 0)
+ 	CALL_MCOUNT 3
+ 
+-	cmpldi  cr1,5,31
++	cmpldi	cr1,cnt,31
+ 	neg	0,3
+-	std	3,-16(1)
+-	std	31,-8(1)
+-	cfi_offset(31,-8)
+ 	ble	cr1, L(copy_LT_32)  /* If move < 32 bytes use short move
+ 				    code.  */
+ 
+-	andi.   11,3,7	      /* Check alignment of DST.  */
+-
++#ifdef __LITTLE_ENDIAN__
++/* In little-endian mode, power7 takes an alignment trap on any lxvd2x
++   or stxvd2x crossing a 32-byte boundary, so ensure the aligned_copy
++   loop is only used for quadword aligned copies.  */
++	andi.	10,3,15
++	clrldi	11,4,60
++#else
++	andi.	10,3,7		/* Check alignment of DST.  */
++	clrldi	11,4,61		/* Check alignment of SRC.  */
++#endif
++	cmpld	cr6,10,11	/* SRC and DST alignments match?  */
+ 
+-	clrldi  10,4,61       /* Check alignment of SRC.  */
+-	cmpld   cr6,10,11     /* SRC and DST alignments match?  */
+-	mr	12,4
+-	mr	31,5
++	mr	dst,3
+ 	bne	cr6,L(copy_GE_32_unaligned)
++	beq	L(aligned_copy)
+ 
+-	srdi    9,5,3	      /* Number of full quadwords remaining.  */
+-
+-	beq    L(copy_GE_32_aligned_cont)
+-
+-	clrldi  0,0,61
+-	mtcrf   0x01,0
+-	subf    31,0,5
+-
+-	/* Get the SRC aligned to 8 bytes.  */
+-
+-1:	bf	31,2f
+-	lbz	6,0(12)
+-	addi    12,12,1
+-	stb	6,0(3)
+-	addi    3,3,1
+-2:	bf      30,4f
+-	lhz     6,0(12)
+-	addi    12,12,2
+-	sth     6,0(3)
+-	addi    3,3,2
+-4:	bf      29,0f
+-	lwz     6,0(12)
+-	addi    12,12,4
+-	stw     6,0(3)
+-	addi    3,3,4
+-0:
+-	clrldi  10,12,61      /* Check alignment of SRC again.  */
+-	srdi    9,31,3	      /* Number of full doublewords remaining.  */
+-
+-L(copy_GE_32_aligned_cont):
+-
+-	clrldi  11,31,61
+-	mtcrf   0x01,9
+-
+-	srdi    8,31,5
+-	cmpldi  cr1,9,4
+-	cmpldi  cr6,11,0
+-	mr	11,12
++	mtocrf	0x01,0
++#ifdef __LITTLE_ENDIAN__
++	clrldi	0,0,60
++#else
++	clrldi	0,0,61
++#endif
+ 
+-	/* Copy 1~3 doublewords so the main loop starts
+-	at a multiple of 32 bytes.  */
+-
+-	bf	30,1f
+-	ld      6,0(12)
+-	ld      7,8(12)
+-	addi    11,12,16
+-	mtctr   8
+-	std     6,0(3)
+-	std     7,8(3)
+-	addi    10,3,16
+-	bf      31,4f
+-	ld      0,16(12)
+-	std     0,16(3)
+-	blt     cr1,3f
+-	addi    11,12,24
+-	addi    10,3,24
+-	b       4f
+-
+-	.align  4
+-1:	/* Copy 1 doubleword and set the counter.  */
+-	mr	10,3
+-	mtctr   8
+-	bf      31,4f
+-	ld      6,0(12)
+-	addi    11,12,8
+-	std     6,0(3)
+-	addi    10,3,8
++/* Get the DST and SRC aligned to 8 bytes (16 for little-endian).  */
++1:
++	bf	31,2f
++	lbz	6,0(src)
++	addi	src,src,1
++	stb	6,0(dst)
++	addi	dst,dst,1
++2:
++	bf	30,4f
++	lhz	6,0(src)
++	addi	src,src,2
++	sth	6,0(dst)
++	addi	dst,dst,2
++4:
++	bf	29,8f
++	lwz	6,0(src)
++	addi	src,src,4
++	stw	6,0(dst)
++	addi	dst,dst,4
++8:
++#ifdef __LITTLE_ENDIAN__
++	bf	28,16f
++	ld	6,0(src)
++	addi	src,src,8
++	std	6,0(dst)
++	addi	dst,dst,8
++16:
++#endif
++	subf	cnt,0,cnt
+ 
++/* Main aligned copy loop. Copies 128 bytes at a time. */
+ L(aligned_copy):
+-	/* Main aligned copy loop. Copies up to 128-bytes at a time. */
+-	.align  4
+-4:
+-	/* check for any 32-byte or 64-byte lumps that are outside of a
+-	   nice 128-byte range.  R8 contains the number of 32-byte
+-	   lumps, so drop this into the CR, and use the SO/EQ bits to help
+-	   handle the 32- or 64- byte lumps.  Then handle the rest with an
+-	   unrolled 128-bytes-at-a-time copy loop. */
+-	mtocrf	1,8
+-	li	6,16	# 16() index
+-	li	7,32	# 32() index
+-	li	8,48	# 48() index
+-
+-L(aligned_32byte):
+-	/* if the SO bit (indicating a 32-byte lump) is not set, move along. */
+-	bns	cr7,L(aligned_64byte)
+-	lxvd2x	6,0,11
+-	lxvd2x	7,11,6
+-	addi	11,11,32
+-	stxvd2x	6,0,10
+-	stxvd2x	7,10,6
+-	addi	10,10,32
+-
+-L(aligned_64byte):
+-	/* if the EQ bit (indicating a 64-byte lump) is not set, move along. */
+-	bne	cr7,L(aligned_128setup)
+-	lxvd2x	6,0,11
+-	lxvd2x	7,11,6
+-	lxvd2x	8,11,7
+-	lxvd2x	9,11,8
+-	addi	11,11,64
+-	stxvd2x	6,0,10
+-	stxvd2x	7,10,6
+-	stxvd2x	8,10,7
+-	stxvd2x	9,10,8
+-	addi	10,10,64
+-
+-L(aligned_128setup):
+-	/* Set up for the 128-byte at a time copy loop.  */
+-	srdi	8,31,7
+-	cmpdi	8,0	# Any 4x lumps left?
+-	beq	3f	# if not, move along.
+-	lxvd2x	6,0,11
+-	lxvd2x	7,11,6
+-	mtctr	8	# otherwise, load the ctr and begin.
+-	li	8,48	# 48() index
++	li	6,16
++	li	7,32
++	li	8,48
++	mtocrf	0x02,cnt
++	srdi	12,cnt,7
++	cmpdi	12,0
++	beq	L(aligned_tail)
++	lxvd2x	6,0,src
++	lxvd2x	7,src,6
++	mtctr	12
+ 	b	L(aligned_128loop)
+ 
++	.align  4
+ L(aligned_128head):
+ 	/* for the 2nd + iteration of this loop. */
+-	lxvd2x	6,0,11
+-	lxvd2x	7,11,6
++	lxvd2x	6,0,src
++	lxvd2x	7,src,6
+ L(aligned_128loop):
+-	lxvd2x	8,11,7
+-	lxvd2x	9,11,8
+-	stxvd2x	6,0,10
+-	addi	11,11,64
+-	stxvd2x	7,10,6
+-	stxvd2x	8,10,7
+-	stxvd2x	9,10,8
+-	lxvd2x	6,0,11
+-	lxvd2x	7,11,6
+-	addi	10,10,64
+-	lxvd2x	8,11,7
+-	lxvd2x	9,11,8
+-	addi	11,11,64
+-	stxvd2x	6,0,10
+-	stxvd2x	7,10,6
+-	stxvd2x	8,10,7
+-	stxvd2x	9,10,8
+-	addi	10,10,64
++	lxvd2x	8,src,7
++	lxvd2x	9,src,8
++	stxvd2x	6,0,dst
++	addi	src,src,64
++	stxvd2x	7,dst,6
++	stxvd2x	8,dst,7
++	stxvd2x	9,dst,8
++	lxvd2x	6,0,src
++	lxvd2x	7,src,6
++	addi	dst,dst,64
++	lxvd2x	8,src,7
++	lxvd2x	9,src,8
++	addi	src,src,64
++	stxvd2x	6,0,dst
++	stxvd2x	7,dst,6
++	stxvd2x	8,dst,7
++	stxvd2x	9,dst,8
++	addi	dst,dst,64
+ 	bdnz	L(aligned_128head)
+ 
+-3:
+-	/* Check for tail bytes.  */
+-	rldicr  0,31,0,60
+-	mtcrf   0x01,31
+-	beq	cr6,0f
+-
+-.L9:
+-	add	3,3,0
+-	add	12,12,0
+-
+-	/*  At this point we have a tail of 0-7 bytes and we know that the
+-	destination is doubleword-aligned.  */
+-4:	/* Copy 4 bytes.  */
+-	bf	29,2f
+-
+-	lwz     6,0(12)
+-	addi    12,12,4
+-	stw     6,0(3)
+-	addi    3,3,4
+-2:	/* Copy 2 bytes.  */
+-	bf	30,1f
+-
+-	lhz     6,0(12)
+-	addi    12,12,2
+-	sth     6,0(3)
+-	addi    3,3,2
+-1:	/* Copy 1 byte.  */
+-	bf	31,0f
+-
+-	lbz	6,0(12)
+-	stb	6,0(3)
+-0:	/* Return original DST pointer.  */
+-	ld	31,-8(1)
+-	ld	3,-16(1)
++L(aligned_tail):
++	mtocrf	0x01,cnt
++	bf	25,32f
++	lxvd2x	6,0,src
++	lxvd2x	7,src,6
++	lxvd2x	8,src,7
++	lxvd2x	9,src,8
++	addi	src,src,64
++	stxvd2x	6,0,dst
++	stxvd2x	7,dst,6
++	stxvd2x	8,dst,7
++	stxvd2x	9,dst,8
++	addi	dst,dst,64
++32:
++	bf	26,16f
++	lxvd2x	6,0,src
++	lxvd2x	7,src,6
++	addi	src,src,32
++	stxvd2x	6,0,dst
++	stxvd2x	7,dst,6
++	addi	dst,dst,32
++16:
++	bf	27,8f
++	lxvd2x	6,0,src
++	addi	src,src,16
++	stxvd2x	6,0,dst
++	addi	dst,dst,16
++8:
++	bf	28,4f
++	ld	6,0(src)
++	addi	src,src,8
++	std     6,0(dst)
++	addi	dst,dst,8
++4:	/* Copies 4~7 bytes.  */
++	bf	29,L(tail2)
++	lwz	6,0(src)
++	stw     6,0(dst)
++	bf      30,L(tail5)
++	lhz     7,4(src)
++	sth     7,4(dst)
++	bflr	31
++	lbz     8,6(src)
++	stb     8,6(dst)
++	/* Return original DST pointer.  */
+ 	blr
+ 
+-	/* Handle copies of 0~31 bytes.  */
+-	.align  4
++
++/* Handle copies of 0~31 bytes.  */
++	.align	4
+ L(copy_LT_32):
+-	cmpldi  cr6,5,8
+-	mr	12,4
+-	mtcrf   0x01,5
++	mr	dst,3
++	cmpldi	cr6,cnt,8
++	mtocrf	0x01,cnt
+ 	ble	cr6,L(copy_LE_8)
+ 
+ 	/* At least 9 bytes to go.  */
+ 	neg	8,4
+-	clrrdi  11,4,2
+-	andi.   0,8,3
+-	cmpldi  cr1,5,16
+-	mr	10,5
++	andi.	0,8,3
++	cmpldi	cr1,cnt,16
+ 	beq	L(copy_LT_32_aligned)
+ 
+-	/* Force 4-bytes alignment for SRC.  */
+-	mtocrf  0x01,0
+-	subf    10,0,5
+-2:	bf	30,1f
+-
+-	lhz	6,0(12)
+-	addi    12,12,2
+-	sth	6,0(3)
+-	addi    3,3,2
+-1:	bf	31,L(end_4bytes_alignment)
+-
+-	lbz	6,0(12)
+-	addi    12,12,1
+-	stb	6,0(3)
+-	addi    3,3,1
++	/* Force 4-byte alignment for SRC.  */
++	mtocrf	0x01,0
++	subf	cnt,0,cnt
++2:
++	bf	30,1f
++	lhz	6,0(src)
++	addi	src,src,2
++	sth	6,0(dst)
++	addi	dst,dst,2
++1:
++	bf	31,L(end_4bytes_alignment)
++	lbz	6,0(src)
++	addi	src,src,1
++	stb	6,0(dst)
++	addi	dst,dst,1
+ 
+-	.align  4
++	.align	4
+ L(end_4bytes_alignment):
+-	cmpldi  cr1,10,16
+-	mtcrf   0x01,10
++	cmpldi	cr1,cnt,16
++	mtocrf	0x01,cnt
+ 
+ L(copy_LT_32_aligned):
+ 	/* At least 6 bytes to go, and SRC is word-aligned.  */
+ 	blt	cr1,8f
+ 
+ 	/* Copy 16 bytes.  */
+-	lwz	6,0(12)
+-	lwz     7,4(12)
+-	stw     6,0(3)
+-	lwz     8,8(12)
+-	stw     7,4(3)
+-	lwz     6,12(12)
+-	addi    12,12,16
+-	stw     8,8(3)
+-	stw     6,12(3)
+-	addi    3,3,16
++	lwz	6,0(src)
++	lwz	7,4(src)
++	stw	6,0(dst)
++	lwz	8,8(src)
++	stw	7,4(dst)
++	lwz	6,12(src)
++	addi	src,src,16
++	stw	8,8(dst)
++	stw	6,12(dst)
++	addi	dst,dst,16
+ 8:	/* Copy 8 bytes.  */
+-	bf	28,4f
++	bf	28,L(tail4)
++	lwz	6,0(src)
++	lwz	7,4(src)
++	addi	src,src,8
++	stw	6,0(dst)
++	stw	7,4(dst)
++	addi	dst,dst,8
++
++	.align	4
++/* Copies 4~7 bytes.  */
++L(tail4):
++	bf	29,L(tail2)
++	lwz	6,0(src)
++	stw	6,0(dst)
++	bf	30,L(tail5)
++	lhz	7,4(src)
++	sth	7,4(dst)
++	bflr	31
++	lbz	8,6(src)
++	stb	8,6(dst)
++	/* Return original DST pointer.  */
++	blr
+ 
+-	lwz     6,0(12)
+-	lwz     7,4(12)
+-	addi    12,12,8
+-	stw     6,0(3)
+-	stw     7,4(3)
+-	addi    3,3,8
+-4:	/* Copy 4 bytes.  */
+-	bf	29,2f
+-
+-	lwz     6,0(12)
+-	addi    12,12,4
+-	stw     6,0(3)
+-	addi    3,3,4
+-2:	/* Copy 2-3 bytes.  */
++	.align	4
++/* Copies 2~3 bytes.  */
++L(tail2):
+ 	bf	30,1f
+-
+-	lhz     6,0(12)
+-	sth     6,0(3)
+-	bf      31,0f
+-	lbz     7,2(12)
+-	stb     7,2(3)
+-	ld	3,-16(1)
++	lhz	6,0(src)
++	sth	6,0(dst)
++	bflr	31
++	lbz	7,2(src)
++	stb	7,2(dst)
+ 	blr
+ 
+-	.align  4
+-1:	/* Copy 1 byte.  */
+-	bf	31,0f
++	.align	4
++L(tail5):
++	bflr	31
++	lbz	6,4(src)
++	stb	6,4(dst)
++	blr
+ 
+-	lbz	6,0(12)
+-	stb	6,0(3)
+-0:	/* Return original DST pointer.  */
+-	ld	3,-16(1)
++	.align	4
++1:
++	bflr	31
++	lbz	6,0(src)
++	stb	6,0(dst)
++	/* Return original DST pointer.  */
+ 	blr
+ 
+-	/* Handles copies of 0~8 bytes.  */
+-	.align  4
++
++/* Handles copies of 0~8 bytes.  */
++	.align	4
+ L(copy_LE_8):
+-	bne	cr6,4f
++	bne	cr6,L(tail4)
+ 
+ 	/* Though we could've used ld/std here, they are still
+ 	slow for unaligned cases.  */
+ 
+-	lwz	6,0(4)
+-	lwz     7,4(4)
+-	stw     6,0(3)
+-	stw     7,4(3)
+-	ld      3,-16(1)      /* Return original DST pointers.  */
++	lwz	6,0(src)
++	lwz	7,4(src)
++	stw	6,0(dst)
++	stw	7,4(dst)
+ 	blr
+ 
+-	.align  4
+-4:	/* Copies 4~7 bytes.  */
+-	bf	29,2b
+ 
+-	lwz	6,0(4)
+-	stw     6,0(3)
+-	bf      30,5f
+-	lhz     7,4(4)
+-	sth     7,4(3)
+-	bf      31,0f
+-	lbz     8,6(4)
+-	stb     8,6(3)
+-	ld	3,-16(1)
+-	blr
+-
+-	.align  4
+-5:	/* Copy 1 byte.  */
+-	bf	31,0f
+-
+-	lbz	6,4(4)
+-	stb	6,4(3)
+-
+-0:	/* Return original DST pointer.  */
+-	ld	3,-16(1)
+-	blr
+-
+-	/* Handle copies of 32+ bytes where DST is aligned (to quadword) but
+-	SRC is not.  Use aligned quadword loads from SRC, shifted to realign
+-	the data, allowing for aligned DST stores.  */
+-	.align  4
++/* Handle copies of 32+ bytes where DST is aligned (to quadword) but
++   SRC is not.	Use aligned quadword loads from SRC, shifted to realign
++   the data, allowing for aligned DST stores.  */
++	.align	4
+ L(copy_GE_32_unaligned):
+-	clrldi  0,0,60	      /* Number of bytes until the 1st
+-			      quadword.  */
+-	andi.   11,3,15       /* Check alignment of DST (against
+-			      quadwords).  */
+-	srdi    9,5,4	      /* Number of full quadwords remaining.  */
++	clrldi	0,0,60	      /* Number of bytes until the 1st dst quadword.  */
++#ifndef __LITTLE_ENDIAN__
++	andi.	10,3,15	      /* Check alignment of DST (against quadwords).  */
++#endif
++	srdi	9,cnt,4	      /* Number of full quadwords remaining.  */
+ 
+ 	beq	L(copy_GE_32_unaligned_cont)
+ 
+-	/* SRC is not quadword aligned, get it aligned.  */
++	/* DST is not quadword aligned, get it aligned.  */
+ 
+-	mtcrf   0x01,0
+-	subf    31,0,5
++	mtocrf	0x01,0
++	subf	cnt,0,cnt
+ 
+ 	/* Vector instructions work best when proper alignment (16-bytes)
+ 	is present.  Move 0~15 bytes as needed to get DST quadword-aligned.  */
+-1:	/* Copy 1 byte.  */
++1:
+ 	bf	31,2f
+-
+-	lbz	6,0(12)
+-	addi    12,12,1
+-	stb	6,0(3)
+-	addi    3,3,1
+-2:	/* Copy 2 bytes.  */
++	lbz	6,0(src)
++	addi	src,src,1
++	stb	6,0(dst)
++	addi	dst,dst,1
++2:
+ 	bf	30,4f
+-
+-	lhz     6,0(12)
+-	addi    12,12,2
+-	sth     6,0(3)
+-	addi    3,3,2
+-4:	/* Copy 4 bytes.  */
++	lhz	6,0(src)
++	addi	src,src,2
++	sth	6,0(dst)
++	addi	dst,dst,2
++4:
+ 	bf	29,8f
+-
+-	lwz     6,0(12)
+-	addi    12,12,4
+-	stw     6,0(3)
+-	addi    3,3,4
+-8:	/* Copy 8 bytes.  */
++	lwz	6,0(src)
++	addi	src,src,4
++	stw	6,0(dst)
++	addi	dst,dst,4
++8:
+ 	bf	28,0f
+-
+-	ld	6,0(12)
+-	addi    12,12,8
+-	std	6,0(3)
+-	addi    3,3,8
++	ld	6,0(src)
++	addi	src,src,8
++	std	6,0(dst)
++	addi	dst,dst,8
+ 0:
+-	clrldi  10,12,60      /* Check alignment of SRC.  */
+-	srdi    9,31,4	      /* Number of full quadwords remaining.  */
++	srdi	9,cnt,4	      /* Number of full quadwords remaining.  */
+ 
+ 	/* The proper alignment is present, it is OK to copy the bytes now.  */
+ L(copy_GE_32_unaligned_cont):
+ 
+ 	/* Setup two indexes to speed up the indexed vector operations.  */
+-	clrldi  11,31,60
+-	li      6,16	      /* Index for 16-bytes offsets.  */
++	clrldi	10,cnt,60
++	li	6,16	      /* Index for 16-bytes offsets.  */
+ 	li	7,32	      /* Index for 32-bytes offsets.  */
+-	cmpldi  cr1,11,0
+-	srdi    8,31,5	      /* Setup the loop counter.  */
+-	mr      10,3
+-	mr      11,12
+-	mtcrf   0x01,9
+-	cmpldi  cr6,9,1
+-	lvsl    5,0,12
+-	lvx     3,0,12
+-	bf      31,L(setup_unaligned_loop)
+-
+-	/* Copy another 16 bytes to align to 32-bytes due to the loop .  */
+-	lvx     4,12,6
+-	vperm   6,3,4,5
+-	addi    11,12,16
+-	addi    10,3,16
+-	stvx    6,0,3
++	cmpldi	cr1,10,0
++	srdi	8,cnt,5	      /* Setup the loop counter.  */
++	mtocrf	0x01,9
++	cmpldi	cr6,9,1
++#ifdef __LITTLE_ENDIAN__
++	lvsr	5,0,src
++#else
++	lvsl	5,0,src
++#endif
++	lvx	3,0,src
++	li	0,0
++	bf	31,L(setup_unaligned_loop)
++
++	/* Copy another 16 bytes to align to 32-bytes due to the loop.  */
++	lvx	4,src,6
++#ifdef __LITTLE_ENDIAN__
++	vperm	6,4,3,5
++#else
++	vperm	6,3,4,5
++#endif
++	addi	src,src,16
++	stvx	6,0,dst
++	addi	dst,dst,16
+ 	vor	3,4,4
++	clrrdi	0,src,60
+ 
+ L(setup_unaligned_loop):
+-	mtctr   8
+-	ble     cr6,L(end_unaligned_loop)
++	mtctr	8
++	ble	cr6,L(end_unaligned_loop)
+ 
+ 	/* Copy 32 bytes at a time using vector instructions.  */
+-	.align  4
++	.align	4
+ L(unaligned_loop):
+ 
+ 	/* Note: vr6/vr10 may contain data that was already copied,
+@@ -444,63 +385,56 @@
+ 	some portions again. This is faster than having unaligned
+ 	vector instructions though.  */
+ 
+-	lvx	4,11,6	      /* vr4 = r11+16.  */
+-	vperm   6,3,4,5	      /* Merge the correctly-aligned portions
+-			      of vr3/vr4 into vr6.  */
+-	lvx	3,11,7	      /* vr3 = r11+32.  */
+-	vperm   10,4,3,5      /* Merge the correctly-aligned portions
+-			      of vr3/vr4 into vr10.  */
+-	addi    11,11,32
+-	stvx    6,0,10
+-	stvx    10,10,6
+-	addi    10,10,32
+-
++	lvx	4,src,6
++#ifdef __LITTLE_ENDIAN__
++	vperm	6,4,3,5
++#else
++	vperm	6,3,4,5
++#endif
++	lvx	3,src,7
++#ifdef __LITTLE_ENDIAN__
++	vperm	10,3,4,5
++#else
++	vperm	10,4,3,5
++#endif
++	addi	src,src,32
++	stvx	6,0,dst
++	stvx	10,dst,6
++	addi	dst,dst,32
+ 	bdnz	L(unaligned_loop)
+ 
+-	.align  4
++	clrrdi	0,src,60
++
++	.align	4
+ L(end_unaligned_loop):
+ 
+ 	/* Check for tail bytes.  */
+-	rldicr  0,31,0,59
+-	mtcrf   0x01,31
+-	beq	cr1,0f
++	mtocrf	0x01,cnt
++	beqlr	cr1
+ 
+-	add	3,3,0
+-	add	12,12,0
++	add	src,src,0
+ 
+ 	/*  We have 1~15 tail bytes to copy, and DST is quadword aligned.  */
+-8:	/* Copy 8 bytes.  */
++	/* Copy 8 bytes.  */
+ 	bf	28,4f
+-
+-	lwz	6,0(12)
+-	lwz	7,4(12)
+-	addi    12,12,8
+-	stw	6,0(3)
+-	stw	7,4(3)
+-	addi    3,3,8
+-4:	/* Copy 4 bytes.  */
+-	bf	29,2f
+-
+-	lwz	6,0(12)
+-	addi    12,12,4
+-	stw	6,0(3)
+-	addi    3,3,4
+-2:	/* Copy 2~3 bytes.  */
+-	bf	30,1f
+-
+-	lhz	6,0(12)
+-	addi    12,12,2
+-	sth	6,0(3)
+-	addi    3,3,2
+-1:	/* Copy 1 byte.  */
+-	bf	31,0f
+-
+-	lbz	6,0(12)
+-	stb	6,0(3)
+-0:	/* Return original DST pointer.  */
+-	ld	31,-8(1)
+-	ld	3,-16(1)
++	lwz	6,0(src)
++	lwz	7,4(src)
++	addi	src,src,8
++	stw	6,0(dst)
++	stw	7,4(dst)
++	addi	dst,dst,8
++4:	/* Copy 4~7 bytes.  */
++	bf	29,L(tail2)
++	lwz	6,0(src)
++	stw	6,0(dst)
++	bf	30,L(tail5)
++	lhz	7,4(src)
++	sth	7,4(dst)
++	bflr	31
++	lbz	8,6(src)
++	stb	8,6(dst)
++	/* Return original DST pointer.  */
+ 	blr
+ 
+-END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS)
++END_GEN_TB (memcpy,TB_TOCLESS)
+ libc_hidden_builtin_def (memcpy)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/mempcpy.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/mempcpy.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/mempcpy.S	2014-05-29 13:04:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/mempcpy.S	2014-05-29 13:04:56.000000000 -0500
+@@ -367,13 +367,21 @@
+ 	mr	11,12
+ 	mtcrf	0x01,9
+ 	cmpldi	cr6,9,1
+-	lvsl	5,0,12
++#ifdef __LITTLE_ENDIAN__
++	lvsr    5,0,12
++#else
++	lvsl    5,0,12
++#endif
+ 	lvx	3,0,12
+ 	bf	31,L(setup_unaligned_loop)
+ 
+ 	/* Copy another 16 bytes to align to 32-bytes due to the loop .  */
+ 	lvx	4,12,6
+-	vperm	6,3,4,5
++#ifdef __LITTLE_ENDIAN__
++	vperm   6,4,3,5
++#else
++	vperm   6,3,4,5
++#endif
+ 	addi	11,12,16
+ 	addi	10,3,16
+ 	stvx	6,0,3
+@@ -393,11 +401,17 @@
+ 	vector instructions though.  */
+ 
+ 	lvx	4,11,6	      /* vr4 = r11+16.  */
+-	vperm	6,3,4,5	      /* Merge the correctly-aligned portions
+-				 of vr3/vr4 into vr6.  */
++#ifdef __LITTLE_ENDIAN__
++	vperm   6,4,3,5
++#else
++	vperm   6,3,4,5
++#endif
+ 	lvx	3,11,7	      /* vr3 = r11+32.  */
+-	vperm	10,4,3,5      /* Merge the correctly-aligned portions
+-				 of vr3/vr4 into vr10.  */
++#ifdef __LITTLE_ENDIAN__
++	vperm   10,3,4,5
++#else
++	vperm   10,4,3,5
++#endif
+ 	addi	11,11,32
+ 	stvx	6,0,10
+ 	stvx	10,10,6
diff --git a/SOURCES/glibc-ppc64le-32.patch b/SOURCES/glibc-ppc64le-32.patch
new file mode 100644
index 0000000..9da593b
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-32.patch
@@ -0,0 +1,272 @@
+# commit 3be87c77d24c4456ccca4034363b6d1814cd0c84
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:47:59 2013 +0930
+# 
+#     PowerPC LE memset
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00104.html
+#     
+#     One of the things I noticed when looking at power7 timing is that rlwimi
+#     is cracked and the two resulting insns have a register dependency.
+#     That makes it a little slower than the equivalent rldimi.
+#     
+#         * sysdeps/powerpc/powerpc64/memset.S: Replace rlwimi with
+#             insrdi.  Formatting.
+#         * sysdeps/powerpc/powerpc64/power4/memset.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power6/memset.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power7/memset.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power4/memset.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power6/memset.S: Likewise.
+#         * sysdeps/powerpc/powerpc32/power7/memset.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/memset.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/memset.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/memset.S	2014-05-29 13:07:41.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power4/memset.S	2014-05-29 13:07:46.000000000 -0500
+@@ -52,7 +52,7 @@
+ 
+ /* Align to word boundary.  */
+ 	cmplwi	cr5, rLEN, 31
+-	rlwimi	rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword.  */
++	insrdi	rCHR, rCHR, 8, 48     /* Replicate byte to halfword.  */
+ 	beq+	L(aligned)
+ 	mtcrf	0x01, rMEMP0
+ 	subfic	rALIGN, rALIGN, 4
+@@ -67,7 +67,7 @@
+ /* Handle the case of size < 31.  */
+ L(aligned):
+ 	mtcrf	0x01, rLEN
+-	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
++	insrdi	rCHR, rCHR, 16, 32    /* Replicate halfword to word.  */
+ 	ble	cr5, L(medium)
+ /* Align to 32-byte boundary.  */
+ 	andi.	rALIGN, rMEMP, 0x1C
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/memset.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/memset.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/memset.S	2014-05-29 13:07:41.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power6/memset.S	2014-05-29 13:07:46.000000000 -0500
+@@ -50,7 +50,7 @@
+ 	ble-	cr1, L(small)
+ /* Align to word boundary.  */
+ 	cmplwi	cr5, rLEN, 31
+-	rlwimi	rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword.  */
++	insrdi	rCHR, rCHR, 8, 48	/* Replicate byte to halfword.  */
+ 	beq+	L(aligned)
+ 	mtcrf	0x01, rMEMP0
+ 	subfic	rALIGN, rALIGN, 4
+@@ -66,7 +66,7 @@
+ /* Handle the case of size < 31.  */
+ L(aligned):
+ 	mtcrf	0x01, rLEN
+-	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
++	insrdi	rCHR, rCHR, 16, 32	/* Replicate halfword to word.  */
+ 	ble	cr5, L(medium)
+ /* Align to 32-byte boundary.  */
+ 	andi.	rALIGN, rMEMP, 0x1C
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memset.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memset.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memset.S	2014-05-29 13:07:41.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memset.S	2014-05-29 13:07:46.000000000 -0500
+@@ -37,8 +37,8 @@
+ 	cfi_offset(31,-8)
+ 
+ 	/* Replicate byte to word.  */
+-	rlwimi	4,4,8,16,23
+-	rlwimi	4,4,16,0,15
++	insrdi	4,4,8,48
++	insrdi	4,4,16,32
+ 
+ 	ble	cr6,L(small)	/* If length <= 8, use short copy code.  */
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/memset.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/memset.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/memset.S	2014-05-29 13:07:41.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/memset.S	2014-05-29 13:07:46.000000000 -0500
+@@ -73,14 +73,14 @@
+ 
+ /* Align to doubleword boundary.  */
+ 	cmpldi	cr5, rLEN, 31
+-	rlwimi	rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword.  */
++	insrdi	rCHR, rCHR, 8, 48	/* Replicate byte to halfword.  */
+ 	beq+	L(aligned2)
+ 	mtcrf	0x01, rMEMP0
+ 	subfic	rALIGN, rALIGN, 8
+ 	cror	28,30,31		/* Detect odd word aligned.  */
+ 	add	rMEMP, rMEMP, rALIGN
+ 	sub	rLEN, rLEN, rALIGN
+-	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
++	insrdi	rCHR, rCHR, 16, 32	/* Replicate halfword to word.  */
+ 	bt	29, L(g4)
+ /* Process the even word of doubleword.  */
+ 	bf+	31, L(g2)
+@@ -102,14 +102,14 @@
+ 
+ /* Handle the case of size < 31.  */
+ L(aligned2):
+-	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
++	insrdi	rCHR, rCHR, 16, 32	/* Replicate halfword to word.  */
+ L(aligned):
+ 	mtcrf	0x01, rLEN
+ 	ble	cr5, L(medium)
+ /* Align to 32-byte boundary.  */
+ 	andi.	rALIGN, rMEMP, 0x18
+ 	subfic	rALIGN, rALIGN, 0x20
+-	insrdi	rCHR,rCHR,32,0 /* Replicate word to double word. */
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word. */
+ 	beq	L(caligned)
+ 	mtcrf	0x01, rALIGN
+ 	add	rMEMP, rMEMP, rALIGN
+@@ -230,7 +230,7 @@
+ /* Memset of 0-31 bytes.  */
+ 	.align 5
+ L(medium):
+-	insrdi	rCHR,rCHR,32,0 /* Replicate word to double word.  */
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word.  */
+ 	cmpldi	cr1, rLEN, 16
+ L(medium_tail2):
+ 	add	rMEMP, rMEMP, rLEN
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power4/memset.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power4/memset.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power4/memset.S	2014-05-29 13:07:41.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power4/memset.S	2014-05-29 13:07:46.000000000 -0500
+@@ -68,14 +68,14 @@
+ 
+ /* Align to doubleword boundary.  */
+ 	cmpldi	cr5, rLEN, 31
+-	rlwimi	rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword.  */
++	insrdi	rCHR, rCHR, 8, 48	/* Replicate byte to halfword.  */
+ 	beq+	L(aligned2)
+ 	mtcrf	0x01, rMEMP0
+ 	subfic	rALIGN, rALIGN, 8
+ 	cror	28,30,31		/* Detect odd word aligned.  */
+ 	add	rMEMP, rMEMP, rALIGN
+ 	sub	rLEN, rLEN, rALIGN
+-	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
++	insrdi	rCHR, rCHR, 16, 32	/* Replicate halfword to word.  */
+ 	bt	29, L(g4)
+ /* Process the even word of doubleword.  */
+ 	bf+	31, L(g2)
+@@ -97,14 +97,14 @@
+ 
+ /* Handle the case of size < 31.  */
+ L(aligned2):
+-	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
++	insrdi	rCHR, rCHR, 16, 32	/* Replicate halfword to word.  */
+ L(aligned):
+ 	mtcrf	0x01, rLEN
+ 	ble	cr5, L(medium)
+ /* Align to 32-byte boundary.  */
+ 	andi.	rALIGN, rMEMP, 0x18
+ 	subfic	rALIGN, rALIGN, 0x20
+-	insrdi	rCHR,rCHR,32,0 /* Replicate word to double word. */
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word. */
+ 	beq	L(caligned)
+ 	mtcrf	0x01, rALIGN
+ 	add	rMEMP, rMEMP, rALIGN
+@@ -164,24 +164,24 @@
+ L(getCacheAligned):
+ 	cmpldi	cr1,rLEN,32
+ 	andi.	rTMP,rMEMP,127
+-	blt		cr1,L(handletail32)
+-	beq		L(cacheAligned)
++	blt	cr1,L(handletail32)
++	beq	L(cacheAligned)
+ 	addi	rMEMP,rMEMP,32
+ 	addi	rLEN,rLEN,-32
+-	std		rCHR,-32(rMEMP)
+-	std		rCHR,-24(rMEMP)
+-	std		rCHR,-16(rMEMP)
+-	std		rCHR,-8(rMEMP)
+-	b		L(getCacheAligned)
++	std	rCHR,-32(rMEMP)
++	std	rCHR,-24(rMEMP)
++	std	rCHR,-16(rMEMP)
++	std	rCHR,-8(rMEMP)
++	b	L(getCacheAligned)
+ 
+ /* Now we are aligned to the cache line and can use dcbz.  */
+ L(cacheAligned):
+ 	cmpld	cr1,rLEN,rCLS
+-	blt		cr1,L(handletail32)
++	blt	cr1,L(handletail32)
+ 	dcbz	0,rMEMP
+ 	subf	rLEN,rCLS,rLEN
+-	add		rMEMP,rMEMP,rCLS
+-	b		L(cacheAligned)
++	add	rMEMP,rMEMP,rCLS
++	b	L(cacheAligned)
+ 
+ /* We are here because the cache line size was set and was not 32-bytes
+    and the remainder (rLEN) is less than the actual cache line size.
+@@ -218,7 +218,7 @@
+ /* Memset of 0-31 bytes.  */
+ 	.align 5
+ L(medium):
+-	insrdi	rCHR,rCHR,32,0 /* Replicate word to double word.  */
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word.  */
+ 	cmpldi	cr1, rLEN, 16
+ L(medium_tail2):
+ 	add	rMEMP, rMEMP, rLEN
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power6/memset.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power6/memset.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power6/memset.S	2014-05-29 13:07:41.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power6/memset.S	2014-05-29 13:07:46.000000000 -0500
+@@ -65,14 +65,14 @@
+ 
+ /* Align to doubleword boundary.  */
+ 	cmpldi	cr5, rLEN, 31
+-	rlwimi	rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword.  */
++	insrdi	rCHR, rCHR, 8, 48	/* Replicate byte to halfword.  */
+ 	beq+	L(aligned2)
+ 	mtcrf	0x01, rMEMP0
+ 	subfic	rALIGN, rALIGN, 8
+ 	cror	28,30,31		/* Detect odd word aligned.  */
+ 	add	rMEMP, rMEMP, rALIGN
+ 	sub	rLEN, rLEN, rALIGN
+-	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
++	insrdi	rCHR, rCHR, 16, 32	/* Replicate halfword to word.  */
+ 	bt	29, L(g4)
+ /* Process the even word of doubleword.  */
+ 	bf+	31, L(g2)
+@@ -94,14 +94,14 @@
+ 
+ /* Handle the case of size < 31.  */
+ L(aligned2):
+-	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
++	insrdi	rCHR, rCHR, 16, 32	/* Replicate halfword to word.  */
+ L(aligned):
+ 	mtcrf	0x01, rLEN
+ 	ble	cr5, L(medium)
+ /* Align to 32-byte boundary.  */
+ 	andi.	rALIGN, rMEMP, 0x18
+ 	subfic	rALIGN, rALIGN, 0x20
+-	insrdi	rCHR,rCHR,32,0 /* Replicate word to double word. */
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word. */
+ 	beq	L(caligned)
+ 	mtcrf	0x01, rALIGN
+ 	add	rMEMP, rMEMP, rALIGN
+@@ -362,7 +362,7 @@
+ /* Memset of 0-31 bytes.  */
+ 	.align 5
+ L(medium):
+-	insrdi	rCHR,rCHR,32,0 /* Replicate word to double word.  */
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word.  */
+ 	cmpldi	cr1, rLEN, 16
+ L(medium_tail2):
+ 	add	rMEMP, rMEMP, rLEN
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memset.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memset.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memset.S	2014-05-29 13:07:41.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memset.S	2014-05-29 13:07:46.000000000 -0500
+@@ -34,8 +34,8 @@
+ 	mr	10,3
+ 
+ 	/* Replicate byte to word.  */
+-	rlwimi	4,4,8,16,23
+-	rlwimi	4,4,16,0,15
++	insrdi	4,4,8,48
++	insrdi	4,4,16,32
+ 	ble	cr6,L(small)	/* If length <= 8, use short copy code.  */
+ 
+ 	neg	0,3
+@@ -323,7 +323,7 @@
+ 	clrldi	0,0,62
+ 	beq	L(medium_aligned)
+ 
+-	/* Force 4-bytes alignment for SRC.  */
++	/* Force 4-bytes alignment for DST.  */
+ 	mtocrf	0x01,0
+ 	subf	5,0,5
+ 1:	/* Copy 1 byte.  */
diff --git a/SOURCES/glibc-ppc64le-33.patch b/SOURCES/glibc-ppc64le-33.patch
new file mode 100644
index 0000000..4be8975
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-33.patch
@@ -0,0 +1,1255 @@
+# commit 466b03933234017473c12dd1d92bda5e7fe49df7
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:48:36 2013 +0930
+# 
+#     PowerPC LE memchr and memrchr
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00105.html
+#     
+#     Like strnlen, memchr and memrchr had a number of defects fixed by this
+#     patch as well as adding little-endian support.  The first one I
+#     noticed was that the entry to the main loop needlessly checked for
+#     "are we done yet?" when we know the size is large enough that we can't
+#     be done.  The second defect I noticed was that the main loop count was
+#     wrong, which in turn meant that the small loop needed to handle an
+#     extra word.  Thirdly, there is nothing to say that the string can't
+#     wrap around zero, except of course that we'd normally hit a segfault
+#     on trying to read from address zero.  Fixing that simplified a number
+#     of places:
+#     
+#     -   /* Are we done already?  */
+#     -   addi    r9,r8,8
+#     -   cmpld   r9,r7
+#     -   bge     L(null)
+#     
+#     becomes
+#     
+#     +   cmpld   r8,r7
+#     +   beqlr
+#     
+#     However, the exit gets an extra test because I test for being on the
+#     last word then if so whether the byte offset is less than the end.
+#     Overall, the change is a win.
+#     
+#     Lastly, memrchr used the wrong cache hint.
+#     
+#         * sysdeps/powerpc/powerpc64/power7/memchr.S: Replace rlwimi with
+#         insrdi.  Make better use of reg selection to speed exit slightly.
+#         Schedule entry path a little better.  Remove useless "are we done"
+#         checks on entry to main loop.  Handle wrapping around zero address.
+#         Correct main loop count.  Handle single left-over word from main
+#         loop inline rather than by using loop_small.  Remove extra word
+#         case in loop_small caused by wrong loop count.  Add little-endian
+#         support.
+#         * sysdeps/powerpc/powerpc32/power7/memchr.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power7/memrchr.S: Likewise.  Use proper
+#         cache hint.
+#         * sysdeps/powerpc/powerpc32/power7/memrchr.S: Likewise.
+#         * sysdeps/powerpc/powerpc64/power7/rawmemchr.S: Add little-endian
+#         support.  Avoid rlwimi.
+#         * sysdeps/powerpc/powerpc32/power7/rawmemchr.S: Likewise.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memchr.S	2014-05-29 13:09:17.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memchr.S	2014-05-29 13:13:37.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Optimized memchr implementation for PowerPC32/POWER7 using cmpb insn.
+-   Copyright (C) 2010-2012 Free Software Foundation, Inc.
++   Copyright (C) 2010-2014 Free Software Foundation, Inc.
+    Contributed by Luis Machado <luisgpm@br.ibm.com>.
+    This file is part of the GNU C Library.
+ 
+@@ -18,116 +18,118 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+ /* int [r3] memchr (char *s [r3], int byte [r4], int size [r5])  */
+ 	.machine  power7
+-ENTRY (BP_SYM (__memchr))
++ENTRY (__memchr)
+ 	CALL_MCOUNT
+ 	dcbt	0,r3
+ 	clrrwi  r8,r3,2
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	insrwi	r4,r4,8,16    /* Replicate byte to word.  */
+ 	add	r7,r3,r5      /* Calculate the last acceptable address.  */
++	insrwi	r4,r4,16,0
+ 	cmplwi	r5,16
++	li	r9, -1
++	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
++	addi	r7,r7,-1
++#ifdef __LITTLE_ENDIAN__
++	slw	r9,r9,r6
++#else
++	srw	r9,r9,r6
++#endif
+ 	ble	L(small_range)
+ 
+-	cmplw	cr7,r3,r7     /* Compare the starting address (r3) with the
+-				 ending address (r7).  If (r3 >= r7), the size
+-				 passed in is zero or negative.  */
+-	ble	cr7,L(proceed)
+-
+-	li	r7,-1	      /* Artificially set our ending address (r7)
+-				 such that we will exit early. */
+-L(proceed):
+-	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
+-	cmpli	cr6,r6,0      /* cr6 == Do we have padding?  */
+ 	lwz	r12,0(r8)     /* Load word from memory.  */
+-	cmpb	r10,r12,r4    /* Check for BYTE's in WORD1.  */
+-	beq	cr6,L(proceed_no_padding)
+-	slw	r10,r10,r6
+-	srw	r10,r10,r6
+-L(proceed_no_padding):
+-	cmplwi	cr7,r10,0     /* If r10 == 0, no BYTEs have been found.  */
++	cmpb	r3,r12,r4     /* Check for BYTEs in WORD1.  */
++	and	r3,r3,r9
++	clrlwi	r5,r7,30      /* Byte count - 1 in last word.  */
++	clrrwi	r7,r7,2       /* Address of last word.  */
++	cmplwi	cr7,r3,0      /* If r3 == 0, no BYTEs have been found.  */
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,4
+-	cmplw	cr6,r9,r7
+-	bge	cr6,L(null)
+-
+ 	mtcrf   0x01,r8
+ 	/* Are we now aligned to a doubleword boundary?  If so, skip to
+ 	   the main loop.  Otherwise, go through the alignment code.  */
+-
+ 	bt	29,L(loop_setup)
+ 
+ 	/* Handle WORD2 of pair.  */
+ 	lwzu	r12,4(r8)
+-	cmpb	r10,r12,r4
+-	cmplwi	cr7,r10,0
++	cmpb	r3,r12,r4
++	cmplwi	cr7,r3,0
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,4
+-	cmplw	cr6,r9,r7
+-	bge	cr6,L(null)
+-
+ L(loop_setup):
+-	sub	r5,r7,r9
+-	srwi	r6,r5,3	      /* Number of loop iterations.  */
++	/* The last word we want to read in the loop below is the one
++	   containing the last byte of the string, ie. the word at
++	   (s + size - 1) & ~3, or r7.  The first word read is at
++	   r8 + 4, we read 2 * cnt words, so the last word read will
++	   be at r8 + 4 + 8 * cnt - 4.  Solving for cnt gives
++	   cnt = (r7 - r8) / 8  */
++	sub	r6,r7,r8
++	srwi	r6,r6,3	      /* Number of loop iterations.  */
+ 	mtctr	r6            /* Setup the counter.  */
+-	b	L(loop)
+-	/* Main loop to look for BYTE backwards in the string.  Since
+-	   it's a small loop (< 8 instructions), align it to 32-bytes.  */
+-	.p2align  5
++
++	/* Main loop to look for BYTE in the string.  Since
++	   it's a small loop (8 instructions), align it to 32-bytes.  */
++	.align	5
+ L(loop):
+ 	/* Load two words, compare and merge in a
+ 	   single register for speed.  This is an attempt
+ 	   to speed up the byte-checking process for bigger strings.  */
+ 	lwz	r12,4(r8)
+ 	lwzu	r11,8(r8)
+-	cmpb	r10,r12,r4
++	cmpb	r3,r12,r4
+ 	cmpb	r9,r11,r4
+-	or	r5,r9,r10     /* Merge everything in one word.  */
+-	cmplwi	cr7,r5,0
++	or	r6,r9,r3      /* Merge everything in one word.  */
++	cmplwi	cr7,r6,0
+ 	bne	cr7,L(found)
+ 	bdnz	L(loop)
+ 
+-	/* We're here because the counter reached 0, and that means we
+-	   didn't have any matches for BYTE in the whole range.  */
+-	subi	r11,r7,4
+-	cmplw	cr6,r8,r11
+-	blt	cr6,L(loop_small)
+-	b	L(null)
++	/* We may have one more dword to read.  */
++	cmplw	r8,r7
++	beqlr
+ 
++	lwzu	r12,4(r8)
++	cmpb	r3,r12,r4
++	cmplwi	cr6,r3,0
++	bne	cr6,L(done)
++	blr
++
++	.align	4
++L(found):
+ 	/* OK, one (or both) of the words contains BYTE.  Check
+ 	   the first word and decrement the address in case the first
+ 	   word really contains BYTE.  */
+-	.align	4
+-L(found):
+-	cmplwi	cr6,r10,0
++	cmplwi	cr6,r3,0
+ 	addi	r8,r8,-4
+ 	bne	cr6,L(done)
+ 
+ 	/* BYTE must be in the second word.  Adjust the address
+-	   again and move the result of cmpb to r10 so we can calculate the
++	   again and move the result of cmpb to r3 so we can calculate the
+ 	   pointer.  */
+ 
+-	mr	r10,r9
++	mr	r3,r9
+ 	addi	r8,r8,4
+ 
+-	/* r10 has the output of the cmpb instruction, that is, it contains
++	/* r3 has the output of the cmpb instruction, that is, it contains
+ 	   0xff in the same position as BYTE in the original
+ 	   word from the string.  Use that to calculate the pointer.
+ 	   We need to make sure BYTE is *before* the end of the range.  */
+ L(done):
+-	cntlzw	r0,r10	      /* Count leading zeroes before the match.  */
+-	srwi	r0,r0,3	      /* Convert leading zeroes to bytes.  */
++#ifdef __LITTLE_ENDIAN__
++	addi    r0,r3,-1
++	andc    r0,r0,r3
++	popcntw	r0,r0	      /* Count trailing zeros.  */
++#else
++	cntlzw	r0,r3	      /* Count leading zeros before the match.  */
++#endif
++	cmplw	r8,r7         /* Are we on the last word?  */
++	srwi	r0,r0,3	      /* Convert leading/trailing zeros to bytes.  */
+ 	add	r3,r8,r0
+-	cmplw	r3,r7
+-	bge	L(null)
++	cmplw	cr7,r0,r5     /* If on the last dword, check byte offset.  */
++	bnelr
++	blelr	cr7
++	li	r3,0
+ 	blr
+ 
+ 	.align	4
+@@ -139,69 +141,44 @@
+ 	.align	4
+ L(small_range):
+ 	cmplwi	r5,0
+-	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
+-	beq	L(null)       /* This branch is for the cmplwi r5,0 above */
++	beq	L(null)
+ 	lwz	r12,0(r8)     /* Load word from memory.  */
+-	cmplwi	cr6,r6,0      /* cr6 == Do we have padding?  */
+-	cmpb	r10,r12,r4    /* Check for BYTE in DWORD1.  */
+-	beq	cr6,L(small_no_padding)
+-	slw	r10,r10,r6
+-	srw	r10,r10,r6
+-L(small_no_padding):
+-	cmplwi	cr7,r10,0
++	cmpb	r3,r12,r4     /* Check for BYTE in DWORD1.  */
++	and	r3,r3,r9
++	cmplwi	cr7,r3,0
++	clrlwi	r5,r7,30      /* Byte count - 1 in last word.  */
++	clrrwi	r7,r7,2       /* Address of last word.  */
++	cmplw	r8,r7         /* Are we done already?  */
+ 	bne	cr7,L(done)
++	beqlr
+ 
+-	/* Are we done already?  */
+-	addi    r9,r8,4
+-	cmplw	r9,r7
+-	bge	L(null)
+-
+-L(loop_small):                /* loop_small has been unrolled.  */
+ 	lwzu	r12,4(r8)
+-	cmpb	r10,r12,r4
+-	addi	r9,r8,4
+-	cmplwi	cr6,r10,0
+-	cmplw	r9,r7
++	cmpb	r3,r12,r4
++	cmplwi	cr6,r3,0
++	cmplw	r8,r7
+ 	bne	cr6,L(done)
+-	bge	L(null)
++	beqlr
+ 
+ 	lwzu	r12,4(r8)
+-	cmpb	r10,r12,r4
+-	addi	r9,r8,4
+-	cmplwi	cr6,r10,0
+-	cmplw	r9,r7
++	cmpb	r3,r12,r4
++	cmplwi	cr6,r3,0
++	cmplw	r8,r7
+ 	bne	cr6,L(done)
+-	bge	L(null)
++	beqlr
+ 
+ 	lwzu	r12,4(r8)
+-	cmpb	r10,r12,r4
+-	addi	r9,r8,4
+-	cmplwi	cr6,r10,0
+-	cmplw	r9,r7
++	cmpb	r3,r12,r4
++	cmplwi	cr6,r3,0
++	cmplw	r8,r7
+ 	bne	cr6,L(done)
+-	bge	L(null)
++	beqlr
+ 
+ 	lwzu	r12,4(r8)
+-	cmpb	r10,r12,r4
+-	addi	r9,r8,4
+-	cmplwi	cr6,r10,0
+-	cmplw	r9,r7
++	cmpb	r3,r12,r4
++	cmplwi	cr6,r3,0
+ 	bne	cr6,L(done)
+-	bge	L(null)
+-
+-	/* For most cases we will never get here.  Under some combinations of
+-	   padding + length there is a leftover word that still needs to be
+-	   checked.  */
+-	lwzu	r12,4(r8)
+-	cmpb	r10,r12,r4
+-	addi	r9,r8,4
+-	cmplwi	cr6,r10,0
+-	bne	cr6,L(done)
+-
+-	/* save a branch and exit directly */
+-	li	r3,0
+ 	blr
+ 
+-END (BP_SYM (__memchr))
+-weak_alias (BP_SYM (__memchr), BP_SYM(memchr))
++END (__memchr)
++weak_alias (__memchr, memchr)
+ libc_hidden_builtin_def (memchr)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memrchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memrchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memrchr.S	2014-05-29 13:09:17.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/memrchr.S	2014-05-29 13:13:47.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Optimized memrchr implementation for PowerPC32/POWER7 using cmpb insn.
+-   Copyright (C) 2010 Free Software Foundation, Inc.
++   Copyright (C) 2010-2014 Free Software Foundation, Inc.
+    Contributed by Luis Machado <luisgpm@br.ibm.com>.
+    This file is part of the GNU C Library.
+ 
+@@ -18,124 +18,136 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+ /* int [r3] memrchr (char *s [r3], int byte [r4], int size [r5])  */
+ 	.machine  power7
+-ENTRY (BP_SYM (__memrchr))
++ENTRY (__memrchr)
+ 	CALL_MCOUNT
+-	dcbt	0,r3
+-	mr	r7,r3
+-	add	r3,r7,r5      /* Calculate the last acceptable address.  */
+-	cmplw	cr7,r3,r7     /* Is the address equal or less than r3?  */
++	add	r7,r3,r5      /* Calculate the last acceptable address.  */
++	neg	r0,r7
++	addi	r7,r7,-1
++	mr	r10,r3
++	clrrwi	r6,r7,7
++	li	r9,3<<5
++	dcbt	r9,r6,16      /* Stream hint, decreasing addresses.  */
+ 
+ 	/* Replicate BYTE to word.  */
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
+-	bge	cr7,L(proceed)
+-
+-	li	r3,-1	      /* Make r11 the biggest if r4 <= 0.  */
+-L(proceed):
++	insrwi	r4,r4,8,16
++	insrwi	r4,r4,16,0
+ 	li	r6,-4
+-	addi	r9,r3,-1
+-	clrrwi  r8,r9,2
+-	addi	r8,r8,4
+-	neg	r0,r3
++	li	r9,-1
+ 	rlwinm	r0,r0,3,27,28 /* Calculate padding.  */
+-
++	clrrwi	r8,r7,2
++	srw	r9,r9,r0
+ 	cmplwi	r5,16
++	clrrwi	r0,r10,2
+ 	ble	L(small_range)
+ 
+-	lwbrx	r12,r8,r6     /* Load reversed word from memory.  */
+-	cmpb	r10,r12,r4    /* Check for BYTE in WORD1.  */
+-	slw	r10,r10,r0
+-	srw	r10,r10,r0
+-	cmplwi	cr7,r10,0     /* If r10 == 0, no BYTE's have been found.  */
++#ifdef __LITTLE_ENDIAN__
++	lwzx	r12,0,r8
++#else
++	lwbrx	r12,0,r8      /* Load reversed word from memory.  */
++#endif
++	cmpb	r3,r12,r4     /* Check for BYTE in WORD1.  */
++	and	r3,r3,r9
++	cmplwi	cr7,r3,0      /* If r3 == 0, no BYTEs have been found.  */
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,-4
+-	cmplw	cr6,r9,r7
+-	ble	cr6,L(null)
+-
+ 	mtcrf   0x01,r8
+ 	/* Are we now aligned to a doubleword boundary?  If so, skip to
+ 	   the main loop.  Otherwise, go through the alignment code.  */
+-	mr	r8,r9
+-	bt	29,L(loop_setup)
++	bf	29,L(loop_setup)
+ 
+ 	/* Handle WORD2 of pair.  */
++#ifdef __LITTLE_ENDIAN__
++	lwzx	r12,r8,r6
++#else
+ 	lwbrx	r12,r8,r6
+-	cmpb	r10,r12,r4
+-	cmplwi	cr7,r10,0
+-	bne	cr7,L(done)
+-
+-	/* Are we done already?  */
++#endif
+ 	addi	r8,r8,-4
+-	cmplw	cr6,r8,r7
+-	ble	cr6,L(null)
++	cmpb	r3,r12,r4
++	cmplwi	cr7,r3,0
++	bne	cr7,L(done)
+ 
+ L(loop_setup):
+-	li	r0,-8
+-	sub	r5,r8,r7
+-	srwi	r9,r5,3	      /* Number of loop iterations.  */
++	/* The last word we want to read in the loop below is the one
++	   containing the first byte of the string, ie. the word at
++	   s & ~3, or r0.  The first word read is at r8 - 4, we
++	   read 2 * cnt words, so the last word read will be at
++	   r8 - 4 - 8 * cnt + 4.  Solving for cnt gives
++	   cnt = (r8 - r0) / 8  */
++	sub	r5,r8,r0
++	addi	r8,r8,-4
++	srwi	r9,r5,3       /* Number of loop iterations.  */
+ 	mtctr	r9	      /* Setup the counter.  */
+-	b	L(loop)
+-	/* Main loop to look for BYTE backwards in the string.  Since it's a
+-	   small loop (< 8 instructions), align it to 32-bytes.  */
+-	.p2align  5
++
++	/* Main loop to look for BYTE backwards in the string.
++	   FIXME: Investigate whether 32 byte align helps with this
++	   9 instruction loop.  */
++	.align	5
+ L(loop):
+ 	/* Load two words, compare and merge in a
+ 	   single register for speed.  This is an attempt
+ 	   to speed up the byte-checking process for bigger strings.  */
+ 
+-	lwbrx	r12,r8,r6
+-	lwbrx	r11,r8,r0
+-	addi	r8,r8,-4
+-	cmpb	r10,r12,r4
++#ifdef __LITTLE_ENDIAN__
++	lwzx	r12,0,r8
++	lwzx	r11,r8,r6
++#else
++	lwbrx	r12,0,r8
++	lwbrx	r11,r8,r6
++#endif
++	cmpb	r3,r12,r4
+ 	cmpb	r9,r11,r4
+-	or	r5,r9,r10     /* Merge everything in one word.  */
++	or	r5,r9,r3      /* Merge everything in one word.  */
+ 	cmplwi	cr7,r5,0
+ 	bne	cr7,L(found)
+-	addi	r8,r8,-4
++	addi	r8,r8,-8
+ 	bdnz	L(loop)
+-	/* We're here because the counter reached 0, and that means we
+-	   didn't have any matches for BYTE in the whole range.  Just return
+-	   the original range.  */
+-	addi	r9,r8,4
+-	cmplw	cr6,r9,r7
+-	bgt	cr6,L(loop_small)
+-	b	L(null)
+ 
+-	/* OK, one (or both) of the words contains BYTE.  Check
+-	   the first word and decrement the address in case the first
+-	   word really contains BYTE.  */
++	/* We may have one more word to read.  */
++	cmplw	r8,r0
++	bnelr
++
++#ifdef __LITTLE_ENDIAN__
++	lwzx	r12,0,r8
++#else
++	lwbrx	r12,0,r8
++#endif
++	cmpb	r3,r12,r4
++	cmplwi	cr7,r3,0
++	bne	cr7,L(done)
++	blr
++
+ 	.align	4
+ L(found):
+-	cmplwi	cr6,r10,0
+-	addi	r8,r8,4
++	/* OK, one (or both) of the words contains BYTE.  Check
++	   the first word.  */
++	cmplwi	cr6,r3,0
+ 	bne	cr6,L(done)
+ 
+ 	/* BYTE must be in the second word.  Adjust the address
+-	   again and move the result of cmpb to r10 so we can calculate the
++	   again and move the result of cmpb to r3 so we can calculate the
+ 	   pointer.  */
+ 
+-	mr	r10,r9
++	mr	r3,r9
+ 	addi	r8,r8,-4
+ 
+-	/* r10 has the output of the cmpb instruction, that is, it contains
++	/* r3 has the output of the cmpb instruction, that is, it contains
+ 	   0xff in the same position as BYTE in the original
+ 	   word from the string.  Use that to calculate the pointer.
+ 	   We need to make sure BYTE is *before* the end of the
+ 	   range.  */
+ L(done):
+-	cntlzw	r0,r10	      /* Count leading zeroes before the match.  */
+-	srwi	r6,r0,3	      /* Convert leading zeroes to bytes.  */
+-	addi	r0,r6,1
++	cntlzw	r9,r3	      /* Count leading zeros before the match.  */
++	cmplw	r8,r0         /* Are we on the last word?  */
++	srwi	r6,r9,3	      /* Convert leading zeros to bytes.  */
++	addi	r0,r6,-3
+ 	sub	r3,r8,r0
+-	cmplw	r3,r7
+-	blt	L(null)
++	cmplw	cr7,r3,r10
++	bnelr
++	bgelr	cr7
++	li	r3,0
+ 	blr
+ 
+ 	.align	4
+@@ -149,29 +161,36 @@
+ 	cmplwi	r5,0
+ 	beq	L(null)
+ 
+-	lwbrx	r12,r8,r6     /* Load reversed word from memory.  */
+-	cmpb	r10,r12,r4    /* Check for null bytes in WORD1.  */
+-	slw	r10,r10,r0
+-	srw	r10,r10,r0
+-	cmplwi	cr7,r10,0
++#ifdef __LITTLE_ENDIAN__
++	lwzx	r12,0,r8
++#else
++	lwbrx	r12,0,r8      /* Load reversed word from memory.  */
++#endif
++	cmpb	r3,r12,r4     /* Check for BYTE in WORD1.  */
++	and	r3,r3,r9
++	cmplwi	cr7,r3,0
+ 	bne	cr7,L(done)
+ 
++	/* Are we done already?  */
++	cmplw	r8,r0
+ 	addi	r8,r8,-4
+-	cmplw	r8,r7
+-	ble	L(null)
+-	b	L(loop_small)
++	beqlr
+ 
+-	.p2align  5
++	.align	5
+ L(loop_small):
+-	lwbrx	r12,r8,r6
+-	cmpb	r10,r12,r4
+-	cmplwi	cr6,r10,0
+-	bne	cr6,L(done)
++#ifdef __LITTLE_ENDIAN__
++	lwzx	r12,0,r8
++#else
++	lwbrx	r12,0,r8
++#endif
++	cmpb	r3,r12,r4
++	cmplw	r8,r0
++	cmplwi	cr7,r3,0
++	bne	cr7,L(done)
+ 	addi	r8,r8,-4
+-	cmplw	r8,r7
+-	ble	L(null)
+-	b	L(loop_small)
++	bne	L(loop_small)
++	blr
+ 
+-END (BP_SYM (__memrchr))
+-weak_alias (BP_SYM (__memrchr), BP_SYM(memrchr))
++END (__memrchr)
++weak_alias (__memrchr, memrchr)
+ libc_hidden_builtin_def (memrchr)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/rawmemchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/rawmemchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/rawmemchr.S	2014-05-29 13:09:17.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc32/power7/rawmemchr.S	2014-05-29 13:09:19.000000000 -0500
+@@ -29,16 +29,21 @@
+ 	clrrwi	r8,r3,2	      /* Align the address to word boundary.  */
+ 
+ 	/* Replicate byte to word.  */
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	rldimi	r4,r4,8,48
++	rldimi	r4,r4,16,32
+ 
+ 	/* Now r4 has a word of c bytes.  */
+ 
+ 	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
+ 	lwz	r12,0(r8)     /* Load word from memory.  */
+ 	cmpb	r5,r12,r4     /* Compare each byte against c byte.  */
++#ifdef __LITTLE_ENDIAN__
++	srw	r5,r5,r6
++	slw	r5,r5,r6
++#else
+ 	slw	r5,r5,r6      /* Move left to discard ignored bits.  */
+ 	srw	r5,r5,r6      /* Bring the bits back as zeros.  */
++#endif
+ 	cmpwi	cr7,r5,0      /* If r5 == 0, no c bytes have been found.  */
+ 	bne	cr7,L(done)
+ 
+@@ -92,8 +97,14 @@
+ 	   word from the string.  Use that fact to find out what is
+ 	   the position of the byte inside the string.  */
+ L(done):
++#ifdef __LITTLE_ENDIAN__
++	addi    r0,r5,-1
++	andc    r0,r0,r5
++	popcntw	r0,r0
++#else
+ 	cntlzw	r0,r5	      /* Count leading zeros before the match.  */
+-	srwi	r0,r0,3	      /* Convert leading zeroes to bytes.  */
++#endif
++	srwi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r8,r0      /* Return address of the matching char.  */
+ 	blr
+ END (BP_SYM (__rawmemchr))
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memchr.S	2014-05-29 13:09:17.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memchr.S	2014-05-29 13:13:57.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Optimized memchr implementation for PowerPC64/POWER7 using cmpb insn.
+-   Copyright (C) 2010-2012 Free Software Foundation, Inc.
++   Copyright (C) 2010-2014 Free Software Foundation, Inc.
+    Contributed by Luis Machado <luisgpm@br.ibm.com>.
+    This file is part of the GNU C Library.
+ 
+@@ -18,118 +18,119 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+ /* int [r3] memchr (char *s [r3], int byte [r4], int size [r5])  */
+ 	.machine  power7
+-ENTRY (BP_SYM (__memchr))
+-	CALL_MCOUNT 2
++ENTRY (__memchr)
++	CALL_MCOUNT 3
+ 	dcbt	0,r3
+ 	clrrdi  r8,r3,3
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	insrdi	r4,r4,8,48
+ 	add	r7,r3,r5      /* Calculate the last acceptable address.  */
++	insrdi	r4,r4,16,32
+ 	cmpldi	r5,32
++	li	r9, -1
++	rlwinm	r6,r3,3,26,28 /* Calculate padding.  */
+ 	insrdi  r4,r4,32,0
++	addi	r7,r7,-1
++#ifdef __LITTLE_ENDIAN__
++	sld	r9,r9,r6
++#else
++	srd	r9,r9,r6
++#endif
+ 	ble	L(small_range)
+ 
+-	cmpld	cr7,r3,r7     /* Compare the starting address (r3) with the
+-				 ending address (r7).  If (r3 >= r7),
+-				 the size passed in was zero or negative.  */
+-	ble	cr7,L(proceed)
+-
+-	li	r7,-1         /* Artificially set our ending address (r7)
+-				 such that we will exit early.  */
+-
+-L(proceed):
+-	rlwinm	r6,r3,3,26,28 /* Calculate padding.  */
+-	cmpldi	cr6,r6,0      /* cr6 == Do we have padding?  */
+ 	ld	r12,0(r8)     /* Load doubleword from memory.  */
+-	cmpb	r10,r12,r4    /* Check for BYTEs in DWORD1.  */
+-	beq	cr6,L(proceed_no_padding)
+-	sld	r10,r10,r6
+-	srd	r10,r10,r6
+-L(proceed_no_padding):
+-	cmpldi	cr7,r10,0     /* Does r10 indicate we got a hit?  */
++	cmpb	r3,r12,r4     /* Check for BYTEs in DWORD1.  */
++	and	r3,r3,r9
++	clrldi	r5,r7,61      /* Byte count - 1 in last dword.  */
++	clrrdi	r7,r7,3       /* Address of last doubleword.  */
++	cmpldi	cr7,r3,0      /* Does r3 indicate we got a hit?  */
+ 	bne	cr7,L(done)
+ 
+-	/* See if we are at the last acceptable address yet.  */
+-	addi	r9,r8,8
+-	cmpld	cr6,r9,r7
+-	bge	cr6,L(null)
+-
+ 	mtcrf   0x01,r8
+ 	/* Are we now aligned to a quadword boundary?  If so, skip to
+ 	   the main loop.  Otherwise, go through the alignment code.  */
+-
+ 	bt	28,L(loop_setup)
+ 
+ 	/* Handle DWORD2 of pair.  */
+ 	ldu	r12,8(r8)
+-	cmpb	r10,r12,r4
+-	cmpldi	cr7,r10,0
++	cmpb	r3,r12,r4
++	cmpldi	cr7,r3,0
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,8
+-	cmpld	cr6,r9,r7
+-	bge	cr6,L(null)
+-
+ L(loop_setup):
+-	sub	r5,r7,r9
+-	srdi	r6,r5,4	      /* Number of loop iterations.  */
++	/* The last dword we want to read in the loop below is the one
++	   containing the last byte of the string, ie. the dword at
++	   (s + size - 1) & ~7, or r7.  The first dword read is at
++	   r8 + 8, we read 2 * cnt dwords, so the last dword read will
++	   be at r8 + 8 + 16 * cnt - 8.  Solving for cnt gives
++	   cnt = (r7 - r8) / 16  */
++	sub	r6,r7,r8
++	srdi	r6,r6,4	      /* Number of loop iterations.  */
+ 	mtctr	r6            /* Setup the counter.  */
+-	b	L(loop)
+-	/* Main loop to look for BYTE backwards in the string.  Since
+-	   it's a small loop (< 8 instructions), align it to 32-bytes.  */
+-	.p2align  5
++
++	/* Main loop to look for BYTE in the string.  Since
++	   it's a small loop (8 instructions), align it to 32-bytes.  */
++	.align	5
+ L(loop):
+ 	/* Load two doublewords, compare and merge in a
+ 	   single register for speed.  This is an attempt
+ 	   to speed up the byte-checking process for bigger strings.  */
+ 	ld	r12,8(r8)
+ 	ldu	r11,16(r8)
+-	cmpb	r10,r12,r4
++	cmpb	r3,r12,r4
+ 	cmpb	r9,r11,r4
+-	or	r5,r9,r10     /* Merge everything in one doubleword.  */
+-	cmpldi	cr7,r5,0
++	or	r6,r9,r3      /* Merge everything in one doubleword.  */
++	cmpldi	cr7,r6,0
+ 	bne	cr7,L(found)
+ 	bdnz	L(loop)
+ 
+-	/* We're here because the counter reached 0, and that means we
+-	   didn't have any matches for BYTE in the whole range.  */
+-	subi	r11,r7,8
+-	cmpld	cr6,r8,r11
+-	blt	cr6,L(loop_small)
+-	b	L(null)
++	/* We may have one more dword to read.  */
++	cmpld	r8,r7
++	beqlr
+ 
++	ldu	r12,8(r8)
++	cmpb	r3,r12,r4
++	cmpldi	cr6,r3,0
++	bne	cr6,L(done)
++	blr
++
++	.align	4
++L(found):
+ 	/* OK, one (or both) of the doublewords contains BYTE.  Check
+ 	   the first doubleword and decrement the address in case the first
+ 	   doubleword really contains BYTE.  */
+-	.align	4
+-L(found):
+-	cmpldi	cr6,r10,0
++	cmpldi	cr6,r3,0
+ 	addi	r8,r8,-8
+ 	bne	cr6,L(done)
+ 
+ 	/* BYTE must be in the second doubleword.  Adjust the address
+-	   again and move the result of cmpb to r10 so we can calculate the
++	   again and move the result of cmpb to r3 so we can calculate the
+ 	   pointer.  */
+ 
+-	mr	r10,r9
++	mr	r3,r9
+ 	addi	r8,r8,8
+ 
+-	/* r10 has the output of the cmpb instruction, that is, it contains
++	/* r3 has the output of the cmpb instruction, that is, it contains
+ 	   0xff in the same position as BYTE in the original
+ 	   doubleword from the string.  Use that to calculate the pointer.
+ 	   We need to make sure BYTE is *before* the end of the range.  */
+ L(done):
+-	cntlzd	r0,r10	      /* Count leading zeroes before the match.  */
+-	srdi	r0,r0,3	      /* Convert leading zeroes to bytes.  */
++#ifdef __LITTLE_ENDIAN__
++	addi    r0,r3,-1
++	andc    r0,r0,r3
++	popcntd	r0,r0	      /* Count trailing zeros.  */
++#else
++	cntlzd	r0,r3	      /* Count leading zeros before the match.  */
++#endif
++	cmpld	r8,r7         /* Are we on the last dword?  */
++	srdi	r0,r0,3	      /* Convert leading/trailing zeros to bytes.  */
+ 	add	r3,r8,r0
+-	cmpld	r3,r7
+-	bge	L(null)
++	cmpld	cr7,r0,r5     /* If on the last dword, check byte offset.  */
++	bnelr
++	blelr	cr7
++	li	r3,0
+ 	blr
+ 
+ 	.align	4
+@@ -141,67 +142,44 @@
+ 	.align	4
+ L(small_range):
+ 	cmpldi	r5,0
+-	rlwinm	r6,r3,3,26,28 /* Calculate padding.  */
+-	beq	L(null)       /* This branch is for the cmpldi r5,0 above.  */
++	beq	L(null)
+ 	ld	r12,0(r8)     /* Load word from memory.  */
+-	cmpldi	cr6,r6,0      /* cr6 == Do we have padding?  */
+-	cmpb	r10,r12,r4    /* Check for BYTE in DWORD1.  */
+-			      /* If no padding, skip the shifts.  */
+-	beq	cr6,L(small_no_padding)
+-	sld	r10,r10,r6
+-	srd	r10,r10,r6
+-L(small_no_padding):
+-	cmpldi	cr7,r10,0
++	cmpb	r3,r12,r4     /* Check for BYTE in DWORD1.  */
++	and	r3,r3,r9
++	cmpldi	cr7,r3,0
++	clrldi	r5,r7,61      /* Byte count - 1 in last dword.  */
++	clrrdi	r7,r7,3       /* Address of last doubleword.  */
++	cmpld	r8,r7         /* Are we done already?  */
+ 	bne	cr7,L(done)
+-
+-	/* Are we done already?  */
+-	addi    r9,r8,8
+-	cmpld	r9,r7
+-	bge	L(null)
+-	/* If we're not done, drop through into loop_small.  */
+-
+-L(loop_small):                /* loop_small has been unrolled.  */
+-	ldu	r12,8(r8)
+-	cmpb	r10,r12,r4
+-	addi	r9,r8,8
+-	cmpldi	cr6,r10,0
+-	cmpld	r9,r7
+-	bne	cr6,L(done)   /* Found something.  */
+-	bge	L(null)       /* Hit end of string (length).  */
++	beqlr
+ 
+ 	ldu	r12,8(r8)
+-	cmpb	r10,r12,r4
+-	addi	r9,r8,8
+-	cmpldi	cr6,r10,0
+-	cmpld	r9,r7
++	cmpb	r3,r12,r4
++	cmpldi	cr6,r3,0
++	cmpld	r8,r7
+ 	bne	cr6,L(done)   /* Found something.  */
+-	bge	L(null)
++	beqlr		      /* Hit end of string (length).  */
+ 
+ 	ldu	r12,8(r8)
+-	subi	r11,r7,8
+-	cmpb	r10,r12,r4
+-	cmpldi	cr6,r10,0
+-	ori	r2,r2,0       /* Force a dispatch group.  */
++	cmpb	r3,r12,r4
++	cmpldi	cr6,r3,0
++	cmpld	r8,r7
+ 	bne	cr6,L(done)
++	beqlr
+ 
+-	cmpld	r8,r11        /* At end of range?  */
+-	bge	L(null)
+-
+-	/* For most cases we will never get here.  Under some combinations of
+-	   padding + length there is a leftover double that still needs to be
+-	   checked.  */
+-	ldu	r12,8(r8)
+-	cmpb	r10,r12,r4
+-	addi	r9,r8,8
+-	cmpldi	cr6,r10,0
+-	cmpld	r9,r7
+-	bne	cr6,L(done)   /* Found something.  */
++	ldu	r12,8(r8)
++	cmpb	r3,r12,r4
++	cmpldi	cr6,r3,0
++	cmpld	r8,r7
++	bne	cr6,L(done)
++	beqlr
+ 
+-	/* Save a branch and exit directly.  */
+-	li	r3,0
++	ldu	r12,8(r8)
++	cmpb	r3,r12,r4
++	cmpldi	cr6,r3,0
++	bne	cr6,L(done)
+ 	blr
+ 
+-
+-END (BP_SYM (__memchr))
+-weak_alias (BP_SYM (__memchr), BP_SYM(memchr))
++END (__memchr)
++weak_alias (__memchr, memchr)
+ libc_hidden_builtin_def (memchr)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memrchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memrchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/memrchr.S	2014-05-29 13:09:17.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/memrchr.S	2014-05-29 13:14:06.000000000 -0500
+@@ -1,5 +1,5 @@
+ /* Optimized memrchr implementation for PowerPC64/POWER7 using cmpb insn.
+-   Copyright (C) 2010 Free Software Foundation, Inc.
++   Copyright (C) 2010-2014 Free Software Foundation, Inc.
+    Contributed by Luis Machado <luisgpm@br.ibm.com>.
+    This file is part of the GNU C Library.
+ 
+@@ -18,125 +18,137 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <sysdep.h>
+-#include <bp-sym.h>
+-#include <bp-asm.h>
+ 
+ /* int [r3] memrchr (char *s [r3], int byte [r4], int size [r5])  */
+ 	.machine  power7
+-ENTRY (BP_SYM (__memrchr))
+-	CALL_MCOUNT
+-	dcbt	0,r3
+-	mr	r7,r3
+-	add	r3,r7,r5      /* Calculate the last acceptable address.  */
+-	cmpld	cr7,r3,r7     /* Is the address equal or less than r3?  */
++ENTRY (__memrchr)
++	CALL_MCOUNT 3
++	add	r7,r3,r5      /* Calculate the last acceptable address.  */
++	neg	r0,r7
++	addi	r7,r7,-1
++	mr	r10,r3
++	clrrdi	r6,r7,7
++	li	r9,3<<5
++	dcbt	r9,r6,8       /* Stream hint, decreasing addresses.  */
+ 
+ 	/* Replicate BYTE to doubleword.  */
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	insrdi	r4,r4,8,48
++	insrdi	r4,r4,16,32
+ 	insrdi  r4,r4,32,0
+-	bge	cr7,L(proceed)
+-
+-	li	r3,-1	      /* Make r11 the biggest if r4 <= 0.  */
+-L(proceed):
+ 	li	r6,-8
+-	addi	r9,r3,-1
+-	clrrdi  r8,r9,3
+-	addi	r8,r8,8
+-	neg	r0,r3
++	li	r9,-1
+ 	rlwinm	r0,r0,3,26,28 /* Calculate padding.  */
+-
++	clrrdi	r8,r7,3
++	srd	r9,r9,r0
+ 	cmpldi	r5,32
++	clrrdi	r0,r10,3
+ 	ble	L(small_range)
+ 
+-	ldbrx	r12,r8,r6     /* Load reversed doubleword from memory.  */
+-	cmpb	r10,r12,r4    /* Check for BYTE in DWORD1.  */
+-	sld	r10,r10,r0
+-	srd	r10,r10,r0
+-	cmpldi	cr7,r10,0     /* If r10 == 0, no BYTE's have been found.  */
++#ifdef __LITTLE_ENDIAN__
++	ldx	r12,0,r8
++#else
++	ldbrx	r12,0,r8      /* Load reversed doubleword from memory.  */
++#endif
++	cmpb	r3,r12,r4     /* Check for BYTE in DWORD1.  */
++	and	r3,r3,r9
++	cmpldi	cr7,r3,0      /* If r3 == 0, no BYTEs have been found.  */
+ 	bne	cr7,L(done)
+ 
+-	/* Are we done already?  */
+-	addi	r9,r8,-8
+-	cmpld	cr6,r9,r7
+-	ble	cr6,L(null)
+-
+ 	mtcrf   0x01,r8
+-	/* Are we now aligned to a doubleword boundary?  If so, skip to
++	/* Are we now aligned to a quadword boundary?  If so, skip to
+ 	   the main loop.  Otherwise, go through the alignment code.  */
+-	mr	r8,r9
+-	bt	28,L(loop_setup)
++	bf	28,L(loop_setup)
+ 
+ 	/* Handle DWORD2 of pair.  */
++#ifdef __LITTLE_ENDIAN__
++	ldx	r12,r8,r6
++#else
+ 	ldbrx	r12,r8,r6
+-	cmpb	r10,r12,r4
+-	cmpldi	cr7,r10,0
+-	bne	cr7,L(done)
+-
+-	/* Are we done already.  */
++#endif
+ 	addi	r8,r8,-8
+-	cmpld	cr6,r8,r7
+-	ble	cr6,L(null)
++	cmpb	r3,r12,r4
++	cmpldi	cr7,r3,0
++	bne	cr7,L(done)
+ 
+ L(loop_setup):
+-	li	r0,-16
+-	sub	r5,r8,r7
+-	srdi	r9,r5,4	      /* Number of loop iterations.  */
++	/* The last dword we want to read in the loop below is the one
++	   containing the first byte of the string, ie. the dword at
++	   s & ~7, or r0.  The first dword read is at r8 - 8, we
++	   read 2 * cnt dwords, so the last dword read will be at
++	   r8 - 8 - 16 * cnt + 8.  Solving for cnt gives
++	   cnt = (r8 - r0) / 16  */
++	sub	r5,r8,r0
++	addi	r8,r8,-8
++	srdi	r9,r5,4       /* Number of loop iterations.  */
+ 	mtctr	r9	      /* Setup the counter.  */
+-	b	L(loop)
+-	/* Main loop to look for BYTE backwards in the string.  Since it's a
+-	   small loop (< 8 instructions), align it to 32-bytes.  */
+-	.p2align  5
++
++	/* Main loop to look for BYTE backwards in the string.
++	   FIXME: Investigate whether 32 byte align helps with this
++	   9 instruction loop.  */
++	.align	5
+ L(loop):
+ 	/* Load two doublewords, compare and merge in a
+ 	   single register for speed.  This is an attempt
+ 	   to speed up the byte-checking process for bigger strings.  */
+ 
+-	ldbrx	r12,r8,r6
+-	ldbrx	r11,r8,r0
+-	addi	r8,r8,-8
+-	cmpb	r10,r12,r4
++#ifdef __LITTLE_ENDIAN__
++	ldx	r12,0,r8
++	ldx	r11,r8,r6
++#else
++	ldbrx	r12,0,r8
++	ldbrx	r11,r8,r6
++#endif
++	cmpb	r3,r12,r4
+ 	cmpb	r9,r11,r4
+-	or	r5,r9,r10     /* Merge everything in one doubleword.  */
++	or	r5,r9,r3      /* Merge everything in one doubleword.  */
+ 	cmpldi	cr7,r5,0
+ 	bne	cr7,L(found)
+-	addi	r8,r8,-8
++	addi	r8,r8,-16
+ 	bdnz	L(loop)
+-	/* We're here because the counter reached 0, and that means we
+-	   didn't have any matches for BYTE in the whole range.  Just return
+-	   the original range.  */
+-	addi	r9,r8,8
+-	cmpld	cr6,r9,r7
+-	bgt	cr6,L(loop_small)
+-	b	L(null)
+-
+-	/* OK, one (or both) of the words contains BYTE.  Check
+-	   the first word and decrement the address in case the first
+-	   word really contains BYTE.  */
++
++	/* We may have one more word to read.  */
++	cmpld	r8,r0
++	bnelr
++
++#ifdef __LITTLE_ENDIAN__
++	ldx	r12,0,r8
++#else
++	ldbrx	r12,0,r8
++#endif
++	cmpb	r3,r12,r4
++	cmpldi	cr7,r3,0
++	bne	cr7,L(done)
++	blr
++
+ 	.align	4
+ L(found):
+-	cmpldi	cr6,r10,0
+-	addi	r8,r8,8
++	/* OK, one (or both) of the dwords contains BYTE.  Check
++	   the first dword.  */
++	cmpldi	cr6,r3,0
+ 	bne	cr6,L(done)
+ 
+ 	/* BYTE must be in the second word.  Adjust the address
+-	   again and move the result of cmpb to r10 so we can calculate the
++	   again and move the result of cmpb to r3 so we can calculate the
+ 	   pointer.  */
+ 
+-	mr	r10,r9
++	mr	r3,r9
+ 	addi	r8,r8,-8
+ 
+-	/* r10 has the output of the cmpb instruction, that is, it contains
+-	   0xff in the same position as the BYTE in the original
++	/* r3 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as BYTE in the original
+ 	   word from the string.  Use that to calculate the pointer.
+ 	   We need to make sure BYTE is *before* the end of the
+ 	   range.  */
+ L(done):
+-	cntlzd	r0,r10	      /* Count leading zeroes before the match.  */
+-	srdi	r6,r0,3	      /* Convert leading zeroes to bytes.  */
+-	addi	r0,r6,1
++	cntlzd	r9,r3	      /* Count leading zeros before the match.  */
++	cmpld	r8,r0         /* Are we on the last word?  */
++	srdi	r6,r9,3	      /* Convert leading zeros to bytes.  */
++	addi	r0,r6,-7
+ 	sub	r3,r8,r0
+-	cmpld	r3,r7
+-	blt	L(null)
++	cmpld	cr7,r3,r10
++	bnelr
++	bgelr	cr7
++	li	r3,0
+ 	blr
+ 
+ 	.align	4
+@@ -150,30 +162,36 @@
+ 	cmpldi	r5,0
+ 	beq	L(null)
+ 
+-	ldbrx	r12,r8,r6     /* Load reversed doubleword from memory.  */
+-	cmpb	r10,r12,r4    /* Check for BYTE in DWORD1.  */
+-	sld	r10,r10,r0
+-	srd	r10,r10,r0
+-	cmpldi	cr7,r10,0
++#ifdef __LITTLE_ENDIAN__
++	ldx	r12,0,r8
++#else
++	ldbrx	r12,0,r8      /* Load reversed doubleword from memory.  */
++#endif
++	cmpb	r3,r12,r4     /* Check for BYTE in DWORD1.  */
++	and	r3,r3,r9
++	cmpldi	cr7,r3,0
+ 	bne	cr7,L(done)
+ 
+ 	/* Are we done already?  */
++	cmpld	r8,r0
+ 	addi	r8,r8,-8
+-	cmpld	r8,r7
+-	ble	L(null)
+-	b	L(loop_small)
++	beqlr
+ 
+-	.p2align  5
++	.align	5
+ L(loop_small):
+-	ldbrx	r12,r8,r6
+-	cmpb	r10,r12,r4
+-	cmpldi	cr6,r10,0
+-	bne	cr6,L(done)
++#ifdef __LITTLE_ENDIAN__
++	ldx	r12,0,r8
++#else
++	ldbrx	r12,0,r8
++#endif
++	cmpb	r3,r12,r4
++	cmpld	r8,r0
++	cmpldi	cr7,r3,0
++	bne	cr7,L(done)
+ 	addi	r8,r8,-8
+-	cmpld	r8,r7
+-	ble	L(null)
+-	b	L(loop_small)
++	bne	L(loop_small)
++	blr
+ 
+-END (BP_SYM (__memrchr))
+-weak_alias (BP_SYM (__memrchr), BP_SYM(memrchr))
++END (__memrchr)
++weak_alias (__memrchr, memrchr)
+ libc_hidden_builtin_def (memrchr)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/rawmemchr.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/rawmemchr.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/rawmemchr.S	2014-05-29 13:09:17.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/power7/rawmemchr.S	2014-05-29 13:09:19.000000000 -0500
+@@ -29,8 +29,8 @@
+ 	clrrdi	r8,r3,3	      /* Align the address to doubleword boundary.  */
+ 
+ 	/* Replicate byte to doubleword.  */
+-	rlwimi	r4,r4,8,16,23
+-	rlwimi	r4,r4,16,0,15
++	insrdi	r4,r4,8,48
++	insrdi	r4,r4,16,32
+ 	insrdi	r4,r4,32,0
+ 
+ 	/* Now r4 has a doubleword of c bytes.  */
+@@ -38,8 +38,13 @@
+ 	rlwinm	r6,r3,3,26,28 /* Calculate padding.  */
+ 	ld	r12,0(r8)     /* Load doubleword from memory.  */
+ 	cmpb	r5,r12,r4     /* Compare each byte against c byte.  */
++#ifdef __LITTLE_ENDIAN__
++	srd	r5,r5,r6
++	sld	r5,r5,r6
++#else
+ 	sld	r5,r5,r6      /* Move left to discard ignored bits.  */
+ 	srd	r5,r5,r6      /* Bring the bits back as zeros.  */
++#endif
+ 	cmpdi	cr7,r5,0      /* If r5 == 0, no c bytes have been found.  */
+ 	bne	cr7,L(done)
+ 
+@@ -93,8 +98,14 @@
+ 	   doubleword from the string.  Use that fact to find out what is
+ 	   the position of the byte inside the string.  */
+ L(done):
++#ifdef __LITTLE_ENDIAN__
++	addi    r0,r5,-1
++	andc    r0,r0,r5
++	popcntd	r0,r0	      /* Count trailing zeros.  */
++#else
+ 	cntlzd	r0,r5	      /* Count leading zeros before the match.  */
+-	srdi	r0,r0,3	      /* Convert leading zeroes to bytes.  */
++#endif
++	srdi	r0,r0,3	      /* Convert leading zeros to bytes.  */
+ 	add	r3,r8,r0      /* Return address of the matching char.  */
+ 	blr
+ END (BP_SYM (__rawmemchr))
diff --git a/SOURCES/glibc-ppc64le-34.patch b/SOURCES/glibc-ppc64le-34.patch
new file mode 100644
index 0000000..9324023
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-34.patch
@@ -0,0 +1,68 @@
+# commit 8f9ebb08af1368962d9f24c4cfacb55cf8eee560
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Thu Oct 3 14:03:03 2013 +0930
+# 
+#     PowerPC LE configury
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00096.html
+#     
+#     This adds the basic configury bits for powerpc64le and powerpcle.
+#     
+#         * configure.in: Map powerpc64le and powerpcle to base_machine/machine.
+#         * configure: Regenerate.
+#         * nptl/shlib-versions: Powerpc*le starts at 2.18.
+#         * shlib-versions: Likewise.
+# 
+# commit 0ff8246327401ae8779e2697d5c7348611cdbf8a
+# Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+# Date:   Tue Feb 4 09:49:08 2014 -0200
+# 
+#     PowerPC: Change powerpc64le start ABI to 2.17.
+# 
+diff -urN glibc-2.17-c758a686.orig/configure glibc-2.17-c758a686.diff/configure
+--- glibc-2.17-c758a686.orig/configure	2014-05-26 19:52:31.000000000 -0500
++++ glibc-2.17-c758a686.diff/configure	2014-05-26 19:54:13.000000000 -0500
+@@ -4195,8 +4195,8 @@
+ # base_machine, we don't change it.
+ test -n "$base_machine" || case "$machine" in
+ i[34567]86)	base_machine=i386 machine=i386/$machine ;;
+-powerpc)	base_machine=powerpc machine=powerpc/powerpc32 ;;
+-powerpc64)	base_machine=powerpc machine=powerpc/powerpc64 ;;
++powerpc64*)	base_machine=powerpc machine=powerpc/powerpc64 ;;
++powerpc*)	base_machine=powerpc machine=powerpc/powerpc32 ;;
+ s390)           base_machine=s390 machine=s390/s390-32 ;;
+ s390x)          base_machine=s390 machine=s390/s390-64 ;;
+ sh3*)		base_machine=sh machine=sh/sh3 ;;
+diff -urN glibc-2.17-c758a686.orig/configure.in glibc-2.17-c758a686.diff/configure.in
+--- glibc-2.17-c758a686.orig/configure.in	2014-05-26 19:52:30.000000000 -0500
++++ glibc-2.17-c758a686.diff/configure.in	2014-05-26 19:54:45.000000000 -0500
+@@ -549,8 +549,8 @@
+ # base_machine, we don't change it.
+ test -n "$base_machine" || case "$machine" in
+ i[34567]86)	base_machine=i386 machine=i386/$machine ;;
+-powerpc)	base_machine=powerpc machine=powerpc/powerpc32 ;;
+-powerpc64)	base_machine=powerpc machine=powerpc/powerpc64 ;;
++powerpc64*)	base_machine=powerpc machine=powerpc/powerpc64 ;;
++powerpc*)	base_machine=powerpc machine=powerpc/powerpc32 ;;
+ s390)           base_machine=s390 machine=s390/s390-32 ;;
+ s390x)          base_machine=s390 machine=s390/s390-64 ;;
+ sh3*)		base_machine=sh machine=sh/sh3 ;;
+diff -urN glibc-2.17-c758a686.orig/nptl/shlib-versions glibc-2.17-c758a686.diff/nptl/shlib-versions
+--- glibc-2.17-c758a686.orig/nptl/shlib-versions	2014-05-26 19:52:31.000000000 -0500
++++ glibc-2.17-c758a686.diff/nptl/shlib-versions	2014-05-26 19:53:31.000000000 -0500
+@@ -2,4 +2,5 @@
+ sh.*-.*-linux.*		libpthread=0		GLIBC_2.2
+ s390x-.*-linux.*	libpthread=0		GLIBC_2.2
+ powerpc64-.*-linux.*	libpthread=0		GLIBC_2.3
++powerpc.*le-.*-linux.*	libpthread=0		GLIBC_2.17
+ .*-.*-linux.*		libpthread=0
+diff -urN glibc-2.17-c758a686.orig/shlib-versions glibc-2.17-c758a686.diff/shlib-versions
+--- glibc-2.17-c758a686.orig/shlib-versions	2014-05-26 19:52:31.000000000 -0500
++++ glibc-2.17-c758a686.diff/shlib-versions	2014-05-26 19:53:31.000000000 -0500
+@@ -23,6 +23,7 @@
+ 
+ s390x-.*-linux.*        DEFAULT			GLIBC_2.2
+ powerpc64-.*-linux.*	DEFAULT			GLIBC_2.3
++powerpc.*le-.*-linux.*	DEFAULT			GLIBC_2.17
+ .*-.*-gnu-gnu.*		DEFAULT			GLIBC_2.2.6
+ 
+ # Configuration		ABI			Identifier for ABI data files
diff --git a/SOURCES/glibc-ppc64le-35.patch b/SOURCES/glibc-ppc64le-35.patch
new file mode 100644
index 0000000..53c8233
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-35.patch
@@ -0,0 +1,106 @@
+# commit 5162e7dd96efcd9b45c1dc1471a964d45278b1e1
+# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+# Date:   Wed Dec 4 06:41:52 2013 -0600
+# 
+#     PowerPC64: Fix incorrect CFI in *context routines
+#     
+#     The context established by "makecontext" has a link register pointing
+#     back to an error path within the makecontext routine.  This is currently
+#     covered by the CFI FDE for makecontext itself, which is simply wrong
+#     for the stack frame *inside* the context.  When trying to unwind (e.g.
+#     doing a backtrace) in a routine inside a context created by makecontext,
+#     this can lead to uninitialized stack slots being accessed, causing the
+#     unwinder to crash in the worst case.
+#     
+#     Similarly, during parts of the "setcontext" routine, when the stack
+#     pointer has already been switched to point to the new context, the
+#     address range is still covered by the CFI FDE for setcontext.  When
+#     trying to unwind in that situation (e.g. backtrace from an async
+#     signal handler for profiling), it is again possible that the unwinder
+#     crashes.
+#     
+#     Theses are all problems in existing code, but the changes in stack
+#     frame layout appear to make the "worst case" much more likely in
+#     the ELFv2 ABI context.  This causes regressions e.g. in the libgo
+#     testsuite on ELFv2.
+#     
+#     This patch fixes this by ending the makecontext/setcontext FDEs
+#     before those problematic parts of the assembler, similar to what
+#     is already done on other platforms.   This fixes the libgo
+#     regression on ELFv2.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S	2014-05-29 13:16:16.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S	2014-05-29 13:16:17.000000000 -0500
+@@ -129,6 +129,10 @@
+      the cpu link stack used to predict blr return addresses.  */
+   bcl	20,31,L(gotexitcodeaddr);
+ 
++  /* End FDE now, because while executing on the context's stack
++     the unwind info would be wrong otherwise.  */
++  cfi_endproc
++
+ 	/* This is the helper code which gets called if a function which
+ 	   is registered with 'makecontext' returns.  In this case we
+ 	   have to install the context listed in the uc_link element of
+@@ -157,6 +161,11 @@
+ #endif
+ 	b    L(do_exit)
+ 
++  /* Re-establish FDE for the rest of the actual makecontext routine.  */
++  cfi_startproc
++  cfi_offset (lr, FRAME_LR_SAVE)
++  cfi_adjust_cfa_offset (128)
++
+   /* The address of the exit code is in the link register.  Store the lr
+      in the ucontext as LNK so the target function will return to our
+      exit code.  */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S	2014-05-29 13:16:16.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S	2014-05-29 13:16:17.000000000 -0500
+@@ -129,6 +129,10 @@
+   lfd  fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
+   lfd  fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
+ 
++  /* End FDE now, because the unwind info would be wrong while
++     we're reloading registers to switch to the new context.  */
++  cfi_endproc
++
+   ld   r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
+   ld   r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
+   mtlr r0
+@@ -177,6 +181,11 @@
+   ld   r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
+   bctr
+ 
++  /* Re-establish FDE for the rest of the actual setcontext routine.  */
++  cfi_startproc
++  cfi_offset (lr, FRAME_LR_SAVE)
++  cfi_adjust_cfa_offset (128)
++
+ L(nv_error_exit):
+   ld   r0,128+FRAME_LR_SAVE(r1)
+   addi r1,r1,128
+@@ -403,6 +412,10 @@
+   lfd  fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
+   lfd  fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
+ 
++  /* End FDE now, because the unwind info would be wrong while
++     we're reloading registers to switch to the new context.  */
++  cfi_endproc
++
+   ld   r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
+   ld   r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
+   mtlr r0
+@@ -451,6 +464,11 @@
+   ld   r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
+   bctr
+ 
++  /* Re-establish FDE for the rest of the actual setcontext routine.  */
++  cfi_startproc
++  cfi_offset (lr, FRAME_LR_SAVE)
++  cfi_adjust_cfa_offset (128)
++
+ L(error_exit):
+   ld   r0,128+FRAME_LR_SAVE(r1)
+   addi r1,r1,128
diff --git a/SOURCES/glibc-ppc64le-36.patch b/SOURCES/glibc-ppc64le-36.patch
new file mode 100644
index 0000000..007f2be
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-36.patch
@@ -0,0 +1,105 @@
+# commit 7ec07d9a7b501f1b7d740fda02ba5f39d6d684e5
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Wed Dec 4 06:44:06 2013 -0600
+# 
+#     PowerPC64: Report overflow on @h and @ha relocations
+#     
+#     This patch updates glibc in accordance with the binutils patch checked in here:
+#     https://sourceware.org/ml/binutils/2013-10/msg00372.html
+#     
+#     This changes the various R_PPC64_..._HI and _HA relocations to report
+#     32-bit overflows.  The motivation is that existing uses of @h / @ha
+#     are to build up 32-bit offsets (for the "medium model" TOC access
+#     that GCC now defaults to), and we'd really like to see failures at
+#     link / load time rather than silent truncations.
+#     
+#     For those rare cases where a modifier is needed to build up a 64-bit
+#     constant, new relocations _HIGH / _HIGHA are supported.
+#     
+#     The patch also fixes a bug in overflow checking for the R_PPC64_ADDR30
+#     and R_PPC64_ADDR32 relocations.
+# 
+diff -urN glibc-2.17-c758a686.orig/elf/elf.h glibc-2.17-c758a686.diff/elf/elf.h
+--- glibc-2.17-c758a686.orig/elf/elf.h	2014-05-29 13:17:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/elf/elf.h	2014-05-29 13:17:35.000000000 -0500
+@@ -2243,6 +2243,17 @@
+ #define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel@highera */
+ #define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel@highest */
+ #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel@highesta */
++#define R_PPC64_TLSGD		107 /* none	(sym+add)@tlsgd */
++#define R_PPC64_TLSLD		108 /* none	(sym+add)@tlsld */
++#define R_PPC64_TOCSAVE		109 /* none */
++
++/* Added when HA and HI relocs were changed to report overflows.  */
++#define R_PPC64_ADDR16_HIGH	110
++#define R_PPC64_ADDR16_HIGHA	111
++#define R_PPC64_TPREL16_HIGH	112
++#define R_PPC64_TPREL16_HIGHA	113
++#define R_PPC64_DTPREL16_HIGH	114
++#define R_PPC64_DTPREL16_HIGHA	115
+ 
+ /* GNU extension to support local ifunc.  */
+ #define R_PPC64_JMP_IREL	247
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 13:17:34.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 13:17:35.000000000 -0500
+@@ -663,11 +663,25 @@
+ 
+     case R_PPC64_TPREL16_HI:
+       value = elf_machine_tprel (map, sym_map, sym, reloc);
++      if (dont_expect (value + 0x80000000 >= 0x100000000LL))
++	_dl_reloc_overflow (map, "R_PPC64_TPREL16_HI", reloc_addr, refsym);
++      *(Elf64_Half *) reloc_addr = PPC_HI (value);
++      break;
++
++    case R_PPC64_TPREL16_HIGH:
++      value = elf_machine_tprel (map, sym_map, sym, reloc);
+       *(Elf64_Half *) reloc_addr = PPC_HI (value);
+       break;
+ 
+     case R_PPC64_TPREL16_HA:
+       value = elf_machine_tprel (map, sym_map, sym, reloc);
++      if (dont_expect (value + 0x80008000 >= 0x100000000LL))
++	_dl_reloc_overflow (map, "R_PPC64_TPREL16_HA", reloc_addr, refsym);
++      *(Elf64_Half *) reloc_addr = PPC_HA (value);
++      break;
++
++    case R_PPC64_TPREL16_HIGHA:
++      value = elf_machine_tprel (map, sym_map, sym, reloc);
+       *(Elf64_Half *) reloc_addr = PPC_HA (value);
+       break;
+ 
+@@ -703,17 +717,23 @@
+       break;
+ 
+     case R_PPC64_ADDR16_HI:
++      if (dont_expect (value + 0x80000000 >= 0x100000000LL))
++	_dl_reloc_overflow (map, "R_PPC64_ADDR16_HI", reloc_addr, refsym);
++    case R_PPC64_ADDR16_HIGH:
+       *(Elf64_Half *) reloc_addr = PPC_HI (value);
+       break;
+ 
+     case R_PPC64_ADDR16_HA:
++      if (dont_expect (value + 0x80008000 >= 0x100000000LL))
++	_dl_reloc_overflow (map, "R_PPC64_ADDR16_HA", reloc_addr, refsym);
++    case R_PPC64_ADDR16_HIGHA:
+       *(Elf64_Half *) reloc_addr = PPC_HA (value);
+       break;
+ 
+     case R_PPC64_ADDR30:
+       {
+ 	Elf64_Addr delta = value - (Elf64_Xword) reloc_addr;
+-	if (dont_expect ((delta + 0x80000000) >= 0x10000000
++	if (dont_expect ((delta + 0x80000000) >= 0x100000000LL
+ 			 || (delta & 3) != 0))
+ 	  _dl_reloc_overflow (map, "R_PPC64_ADDR30", reloc_addr, refsym);
+ 	BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0xfffffffc);
+@@ -762,7 +782,7 @@
+       return;
+ 
+     case R_PPC64_ADDR32:
+-      if (dont_expect ((value + 0x80000000) >= 0x10000000))
++      if (dont_expect ((value + 0x80000000) >= 0x100000000LL))
+ 	_dl_reloc_overflow (map, "R_PPC64_ADDR32", reloc_addr, refsym);
+       *(Elf64_Word *) reloc_addr = value;
+       return;
diff --git a/SOURCES/glibc-ppc64le-37.patch b/SOURCES/glibc-ppc64le-37.patch
new file mode 100644
index 0000000..b96ceaa
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-37.patch
@@ -0,0 +1,31 @@
+# commit b525166bb93b060e1146f0263b76a9c1e7455b06
+# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+# Date:   Wed Dec 4 06:45:56 2013 -0600
+# 
+#     PowerPC64: Add __private_ss field to TCB header
+#     
+#     The TCB header on Intel contains a field __private_ss that is used
+#     to efficiently implement the -fsplit-stack GCC feature.
+#     
+#     In order to prepare for a possible future implementation of that
+#     feature on powerpc64, we'd like to reserve a similar field in
+#     the TCB header as well.  (It would be good if this went in with
+#     or before the ELFv2 patches to ensure that this field will be
+#     available always in the ELFv2 environment.)
+#     
+#     The field needs to be added at the front of tcbhead_t structure
+#     to avoid changing the ABI; see the recent discussion when adding
+#     the EBB fields.
+# 
+diff -urN glibc-2.17-c758a686.orig/nptl/sysdeps/powerpc/tls.h glibc-2.17-c758a686.diff/nptl/sysdeps/powerpc/tls.h
+--- glibc-2.17-c758a686.orig/nptl/sysdeps/powerpc/tls.h	2014-05-29 13:19:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/nptl/sysdeps/powerpc/tls.h	2014-05-29 13:19:25.000000000 -0500
+@@ -61,6 +61,8 @@
+    are private.  */
+ typedef struct
+ {
++  /* GCC split stack support.  */
++  void *__private_ss;
+   /* Reservation for the Event-Based Branching ABI.  */
+   uintptr_t ebb_handler;
+   uintptr_t ebb_ctx_pointer;
diff --git a/SOURCES/glibc-ppc64le-38.patch b/SOURCES/glibc-ppc64le-38.patch
new file mode 100644
index 0000000..443c9bf
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-38.patch
@@ -0,0 +1,262 @@
+# commit d31beafa8e4ca69faa4cf362784796ef17299341
+# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+# Date:   Wed Dec 4 06:49:15 2013 -0600
+# 
+#     PowerPC64 ELFv2 ABI 1/6: Code refactoring
+#     
+#     This is the first patch to support the new ELFv2 ABI in glibc.
+#     
+#     As preparation, this patch simply refactors some of the powerpc64 assembler
+#     code to move all code related to creating function descriptors (.opd section)
+#     or using function descriptors (function pointer call) into a central place
+#     in sysdep.h.
+#     
+#     Note that most locations creating .opd entries were already using macros
+#     in sysdep.h, this patch simply extends this to the remaining places.
+#     
+#     No relevant change in generated code expected.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/crti.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/crti.S	2014-05-29 13:56:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/crti.S	2014-05-29 13:56:37.000000000 -0500
+@@ -60,18 +60,8 @@
+ .LC0:
+ 	.tc PREINIT_FUNCTION[TC], PREINIT_FUNCTION
+ #endif
+-	.type BODY_LABEL (_init), @function
+-	.globl _init
+-	.section ".opd", "aw"
+-	.align 3
+-_init:	OPD_ENT (_init)
+-#ifdef HAVE_ASM_GLOBAL_DOT_NAME
+-	.globl BODY_LABEL (_init)
+-	.size _init, 24
+-#else
+-	.type _init, @function
+-#endif
+ 	.section ".init", "ax", @progbits
++	ENTRY_2(_init)
+ 	.align ALIGNARG (2)
+ BODY_LABEL (_init):
+ 	mflr 0
+@@ -87,18 +77,8 @@
+ 	nop
+ 1:
+ 
+-	.type BODY_LABEL (_fini), @function
+-	.globl _fini
+-	.section ".opd", "aw"
+-	.align 3
+-_fini:	OPD_ENT (_fini)
+-#ifdef HAVE_ASM_GLOBAL_DOT_NAME
+-	.globl BODY_LABEL (_fini)
+-	.size _fini, 24
+-#else
+-	.type _fini, @function
+-#endif
+ 	.section ".fini", "ax", @progbits
++	ENTRY_2(_fini)
+ 	.align ALIGNARG (2)
+ BODY_LABEL (_fini):
+ 	mflr 0
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 13:56:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 13:56:37.000000000 -0500
+@@ -122,14 +122,7 @@
+ #define RTLD_START \
+   asm (".pushsection \".text\"\n"					\
+ "	.align	2\n"							\
+-"	.type	" BODY_PREFIX "_start,@function\n"			\
+-"	.pushsection \".opd\",\"aw\"\n"					\
+-"	.align	3\n"							\
+-"	.globl	_start\n"						\
+ "	" ENTRY_2(_start) "\n"						\
+-"_start:\n"								\
+-"	" OPD_ENT(_start) "\n"						\
+-"	.popsection\n"							\
+ BODY_PREFIX "_start:\n"							\
+ /* We start with the following on the stack, from top:			\
+    argc (4 bytes);							\
+@@ -154,11 +147,6 @@
+ ".LT__start_name_end:\n"						\
+ "	.align 2\n"							\
+ "	" END_2(_start) "\n"						\
+-"	.globl	_dl_start_user\n"					\
+-"	.pushsection \".opd\",\"aw\"\n"					\
+-"_dl_start_user:\n"							\
+-"	" OPD_ENT(_dl_start_user) "\n"					\
+-"	.popsection\n"							\
+ "	.pushsection	\".toc\",\"aw\"\n"				\
+ DL_STARTING_UP_DEF							\
+ ".LC__rtld_local:\n"							\
+@@ -170,7 +158,6 @@
+ ".LC__dl_fini:\n"							\
+ "	.tc _dl_fini[TC],_dl_fini\n"					\
+ "	.popsection\n"							\
+-"	.type	" BODY_PREFIX "_dl_start_user,@function\n"		\
+ "	" ENTRY_2(_dl_start_user) "\n"					\
+ /* Now, we do our main work of calling initialisation procedures.	\
+    The ELF ABI doesn't say anything about parameters for these,		\
+@@ -228,10 +215,7 @@
+ /* Now, call the start function descriptor at r30...  */		\
+ "	.globl	._dl_main_dispatch\n"					\
+ "._dl_main_dispatch:\n"							\
+-"	ld	0,0(30)\n"						\
+-"	ld	2,8(30)\n"						\
+-"	mtctr	0\n"							\
+-"	ld	11,16(30)\n"						\
++"	" PPC64_LOAD_FUNCPTR(30) "\n"					\
+ "	bctr\n"								\
+ ".LT__dl_start_user:\n"							\
+ "	.long 0\n"							\
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-trampoline.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 13:56:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 13:56:37.000000000 -0500
+@@ -71,12 +71,8 @@
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+ 	mtcrf	0xFF,r0
+-/* Load the target address, toc and static chain reg from the function
+-   descriptor returned by fixup.  */
+-	ld	r0,0(r3)
+-	ld	r2,8(r3)
+-	mtctr	r0
+-	ld	r11,16(r3)
++/* Prepare for calling the function returned by fixup.  */
++	PPC64_LOAD_FUNCPTR r3
+ 	ld	r3,INT_PARMS+0(r1)
+ /* Unwind the stack frame, and jump.  */
+ 	addi	r1,r1,FRAME_SIZE
+@@ -322,13 +318,9 @@
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+ 	mtcrf	0xFF,r0
+-/* Load the target address, toc and static chain reg from the function
+-   descriptor returned by fixup.  */
+-	ld	r0,0(r3)
+-	ld	r2,8(r3)
+-	ld	r11,16(r3)
++/* Prepare for calling the function returned by fixup.  */
++	PPC64_LOAD_FUNCPTR r3
+ 	ld	r3,INT_PARMS+0(r1)
+-	mtctr	r0
+ /* Load the floating point registers.  */
+ 	lfd	fp1,FPR_PARMS+0(r1)
+ 	lfd	fp2,FPR_PARMS+8(r1)
+@@ -386,14 +378,10 @@
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+ 	mtcrf	0xFF,r0
+-/* Load the target address, toc and static chain reg from the function
+-   descriptor returned by fixup.  */
+-	ld	r0,0(r3)
++/* Prepare for calling the function returned by fixup.  */
+ 	std	r2,40(r1)
+-	ld	r2,8(r3)
+-	ld	r11,16(r3)
++	PPC64_LOAD_FUNCPTR r3
+ 	ld	r3,INT_PARMS+0(r1)
+-	mtctr	r0
+ /* Load the floating point registers.  */
+ 	lfd	fp1,FPR_PARMS+0(r1)
+ 	lfd	fp2,FPR_PARMS+8(r1)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/sysdep.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/sysdep.h	2014-05-29 13:56:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/sysdep.h	2014-05-29 13:56:37.000000000 -0500
+@@ -74,6 +74,14 @@
+ #endif
+ 	.endm
+ 
++/* Macro to prepare for calling via a function pointer.  */
++	.macro PPC64_LOAD_FUNCPTR PTR
++	ld      r12,0(\PTR)
++	ld      r2,8(\PTR)
++	mtctr   r12
++	ld      r11,16(\PTR)
++	.endm
++
+ #ifdef USE_PPC64_OVERLAPPING_OPD
+ # define OPD_ENT(name)	.quad BODY_LABEL (name), .TOC.@tocbase
+ #else
+@@ -81,7 +89,6 @@
+ #endif
+ 
+ #define ENTRY_1(name)	\
+-	.section	".text";		\
+ 	.type BODY_LABEL(name),@function;	\
+ 	.globl name;				\
+ 	.section ".opd","aw";			\
+@@ -110,6 +117,7 @@
+ #endif
+ 
+ #define ENTRY(name)	\
++	.section	".text";		\
+ 	ENTRY_2(name)				\
+ 	.align ALIGNARG(2);			\
+ BODY_LABEL(name):				\
+@@ -127,6 +135,7 @@
+ /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+    past a 2^alignt boundary.  */
+ #define EALIGN(name, alignt, words) \
++	.section	".text";		\
+ 	ENTRY_2(name)				\
+ 	.align ALIGNARG(alignt);		\
+ 	EALIGN_W_##words;			\
+@@ -286,24 +295,42 @@
+ 
+ #else /* !__ASSEMBLER__ */
+ 
++#define PPC64_LOAD_FUNCPTR(ptr) \
++	"ld 	12,0(" #ptr ");\n"					\
++	"ld	2,8(" #ptr ");\n"					\
++	"mtctr	12;\n"							\
++	"ld	11,16(" #ptr ");"
++
+ #ifdef USE_PPC64_OVERLAPPING_OPD
+ # define OPD_ENT(name)	".quad " BODY_PREFIX #name ", .TOC.@tocbase;"
+ #else
+ # define OPD_ENT(name)	".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0;"
+ #endif
+ 
++#define ENTRY_1(name)	\
++	".type   " BODY_PREFIX #name ",@function;\n"			\
++	".globl " #name ";\n"						\
++	".pushsection \".opd\",\"aw\";\n"				\
++	".align  3;\n"							\
++#name ":\n"								\
++	OPD_ENT (name) "\n"						\
++	".popsection;"
++
+ #ifdef HAVE_ASM_GLOBAL_DOT_NAME
+ # define DOT_PREFIX "."
+ # define BODY_PREFIX "."
+ # define ENTRY_2(name)	\
+ 	".globl " BODY_PREFIX #name ";\n"				\
++	ENTRY_1(name) "\n"						\
+ 	".size  " #name ", 24;"
+ # define END_2(name)	\
+ 	".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
+ #else
+ # define DOT_PREFIX ""
+ # define BODY_PREFIX ".LY"
+-# define ENTRY_2(name) ".type " #name ",@function;"
++# define ENTRY_2(name)	\
++	".type " #name ",@function;\n"					\
++	ENTRY_1(name)
+ # define END_2(name)	\
+ 	".size " #name ",.-" BODY_PREFIX #name ";\n"			\
+ 	".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S	2014-05-29 13:56:35.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S	2014-05-29 13:56:37.000000000 -0500
+@@ -104,9 +104,7 @@
+ 
+ 	std	r2,40(r1)
+ 	/* Call procedure.  */
+-	ld	r0,0(r30)
+-	ld	r2,8(r30)
+-	mtctr	r0
++	PPC64_LOAD_FUNCPTR r30
+ 	mr	r3,r31
+ 	bctrl
+ 	ld	r2,40(r1)
diff --git a/SOURCES/glibc-ppc64le-39.patch b/SOURCES/glibc-ppc64le-39.patch
new file mode 100644
index 0000000..b3a258c
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-39.patch
@@ -0,0 +1,508 @@
+# commit 696caf1d002ff059ddd20fd5eaccd76229c14850
+# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+# Date:   Wed Dec 4 06:51:11 2013 -0600
+# 
+#     PowerPC64 ELFv2 ABI 2/6: Remove function descriptors
+#     
+#     This patch adds support for the ELFv2 ABI feature to remove function
+#     descriptors.  See this GCC patch for in-depth discussion:
+#     http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01141.html
+#     
+#     This mostly involves two types of changes: updating assembler source
+#     files to the new logic, and updating the dynamic loader.
+#     
+#     After the refactoring in the previous patch, most of the assembler source
+#     changes can be handled simply by providing ELFv2 versions of the
+#     macros in sysdep.h.   One somewhat non-obvious change is in __GI__setjmp:
+#     this used to "fall through" to the immediately following __setjmp ENTRY
+#     point.  This is no longer safe in the ELFv2 since ENTRY defines both
+#     a global and a local entry point, and you cannot simply fall through
+#     to a global entry point as it requires r12 to be set up.
+#     
+#     Also, makecontext needs to be updated to set up registers according to
+#     the new ABI for calling into the context's start routine.
+#     
+#     The dynamic linker changes mostly consist of removing special code
+#     to handle function descriptors.  We also need to support the new PLT
+#     and glink format used by the the ELFv2 linker, see:
+#     https://sourceware.org/ml/binutils/2013-10/msg00376.html
+#     
+#     In addition, the dynamic linker now verifies that the dynamic libraries
+#     it loads match its own ABI.
+#     
+#     The hack in VDSO_IFUNC_RET to "synthesize" a function descriptor
+#     for vDSO routines is also no longer necessary for ELFv2.
+# 
+diff -urN glibc-2.17-c758a686.orig/elf/elf.h glibc-2.17-c758a686.diff/elf/elf.h
+--- glibc-2.17-c758a686.orig/elf/elf.h	2014-05-29 13:58:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/elf/elf.h	2014-05-29 13:58:25.000000000 -0500
+@@ -2263,6 +2263,12 @@
+ #define R_PPC64_REL16_HI	251	/* half16   (sym+add-.)@h */
+ #define R_PPC64_REL16_HA	252	/* half16   (sym+add-.)@ha */
+ 
++/* e_flags bits specifying ABI.
++   1 for original function descriptor using ABI,
++   2 for revised ABI without function descriptors,
++   0 for unspecified or not using any features affected by the differences.  */
++#define EF_PPC64_ABI	3
++
+ /* PowerPC64 specific values for the Dyn d_tag field.  */
+ #define DT_PPC64_GLINK  (DT_LOPROC + 0)
+ #define DT_PPC64_OPD	(DT_LOPROC + 1)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/crti.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/crti.S	2014-05-29 13:58:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/crti.S	2014-05-29 13:58:25.000000000 -0500
+@@ -64,6 +64,7 @@
+ 	ENTRY_2(_init)
+ 	.align ALIGNARG (2)
+ BODY_LABEL (_init):
++	LOCALENTRY(_init)
+ 	mflr 0
+ 	std 0, 16(r1)
+ 	stdu r1, -112(r1)
+@@ -81,6 +82,7 @@
+ 	ENTRY_2(_fini)
+ 	.align ALIGNARG (2)
+ BODY_LABEL (_fini):
++	LOCALENTRY(_fini)
+ 	mflr 0
+ 	std 0, 16(r1)
+ 	stdu r1, -112(r1)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-irel.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-irel.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-irel.h	2014-05-29 13:58:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-irel.h	2014-05-29 13:58:25.000000000 -0500
+@@ -50,7 +50,11 @@
+     {
+       Elf64_Addr *const reloc_addr = (void *) reloc->r_offset;
+       Elf64_Addr value = elf_ifunc_invoke(reloc->r_addend);
++#if _CALL_ELF != 2
+       *(Elf64_FuncDesc *) reloc_addr = *(Elf64_FuncDesc *) value;
++#else
++      *reloc_addr = value;
++#endif
+     }
+   else
+     __libc_fatal ("unexpected reloc type in static binary");
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 13:58:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 14:05:46.000000000 -0500
+@@ -31,6 +31,7 @@
+    in l_info array.  */
+ #define DT_PPC64(x) (DT_PPC64_##x - DT_LOPROC + DT_NUM)
+ 
++#if _CALL_ELF != 2
+ /* A PowerPC64 function descriptor.  The .plt (procedure linkage
+    table) and .opd (official procedure descriptor) sections are
+    arrays of these.  */
+@@ -40,6 +41,7 @@
+   Elf64_Addr fd_toc;
+   Elf64_Addr fd_aux;
+ } Elf64_FuncDesc;
++#endif
+ 
+ #define ELF_MULT_MACHINES_SUPPORTED
+ 
+@@ -47,6 +49,18 @@
+ static inline int
+ elf_machine_matches_host (const Elf64_Ehdr *ehdr)
+ {
++  /* Verify that the binary matches our ABI version.  */
++  if ((ehdr->e_flags & EF_PPC64_ABI) != 0)
++    {
++#if _CALL_ELF != 2
++      if ((ehdr->e_flags & EF_PPC64_ABI) != 1)
++        return 0;
++#else
++      if ((ehdr->e_flags & EF_PPC64_ABI) != 2)
++        return 0;
++#endif
++    }
++
+   return ehdr->e_machine == EM_PPC64;
+ }
+ 
+@@ -124,6 +138,7 @@
+ "	.align	2\n"							\
+ "	" ENTRY_2(_start) "\n"						\
+ BODY_PREFIX "_start:\n"							\
++"	" LOCALENTRY(_start) "\n"						\
+ /* We start with the following on the stack, from top:			\
+    argc (4 bytes);							\
+    arguments for program (terminated by NULL);				\
+@@ -165,6 +180,7 @@
+    Changing these is strongly discouraged (not least because argc is	\
+    passed by value!).  */						\
+ BODY_PREFIX "_dl_start_user:\n"						\
++"	" LOCALENTRY(_dl_start_user) "\n"				\
+ /* the address of _start in r30.  */					\
+ "	mr	30,3\n"							\
+ /* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28.  */		\
+@@ -256,8 +272,22 @@
+    relocations behave "normally", ie. always use the real address
+    like PLT relocations.  So always set ELF_RTYPE_CLASS_PLT.  */
+ 
++#if _CALL_ELF != 2
+ #define elf_machine_type_class(type) \
+   (ELF_RTYPE_CLASS_PLT | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
++#else
++/* And now that you have read that large comment, you can disregard it
++   all for ELFv2.  ELFv2 does need the special SHN_UNDEF treatment.  */
++#define IS_PPC64_TLS_RELOC(R)						\
++  (((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA)		\
++   || ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA))
++
++#define elf_machine_type_class(type) \
++  ((((type) == R_PPC64_JMP_SLOT					\
++     || (type) == R_PPC64_ADDR24				\
++     || IS_PPC64_TLS_RELOC (type)) * ELF_RTYPE_CLASS_PLT)	\
++   | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
++#endif
+ 
+ /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
+ #define ELF_MACHINE_JMP_SLOT	R_PPC64_JMP_SLOT
+@@ -266,8 +296,19 @@
+ #define ELF_MACHINE_NO_REL 1
+ 
+ /* Stuff for the PLT.  */
++#if _CALL_ELF != 2
+ #define PLT_INITIAL_ENTRY_WORDS 3
++#define PLT_ENTRY_WORDS 3
+ #define GLINK_INITIAL_ENTRY_WORDS 8
++/* The first 32k entries of glink can set an index and branch using two
++   instructions; past that point, glink uses three instructions.  */
++#define GLINK_ENTRY_WORDS(I) (((I) < 0x8000)? 2 : 3)
++#else
++#define PLT_INITIAL_ENTRY_WORDS 2
++#define PLT_ENTRY_WORDS 1
++#define GLINK_INITIAL_ENTRY_WORDS 8
++#define GLINK_ENTRY_WORDS(I) 1
++#endif
+ 
+ #define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory")
+ #define PPC_DCBT(where) asm volatile ("dcbt 0,%0" : : "r"(where) : "memory")
+@@ -312,17 +353,12 @@
+ 
+       if (lazy)
+ 	{
+-	  /* The function descriptor of the appropriate trampline
+-	     routine is used to set the 1st and 2nd doubleword of the
+-	     plt_reserve.  */
+-	  Elf64_FuncDesc *resolve_fd;
+ 	  Elf64_Word glink_offset;
+-	  /* the plt_reserve area is the 1st 3 doublewords of the PLT */
+-	  Elf64_FuncDesc *plt_reserve = (Elf64_FuncDesc *) plt;
+ 	  Elf64_Word offset;
++	  Elf64_Addr dlrr;
+ 
+-	  resolve_fd = (Elf64_FuncDesc *) (profile ? _dl_profile_resolve
+-					   : _dl_runtime_resolve);
++	  dlrr = (Elf64_Addr) (profile ? _dl_profile_resolve
++				       : _dl_runtime_resolve);
+ 	  if (profile && GLRO(dl_profile) != NULL
+ 	      && _dl_name_match_p (GLRO(dl_profile), map))
+ 	    /* This is the object we are looking for.  Say that we really
+@@ -330,20 +366,33 @@
+ 	    GL(dl_profile_map) = map;
+ 
+ 
++#if _CALL_ELF != 2
+ 	  /* We need to stuff the address/TOC of _dl_runtime_resolve
+ 	     into doublewords 0 and 1 of plt_reserve.  Then we need to
+ 	     stuff the map address into doubleword 2 of plt_reserve.
+ 	     This allows the GLINK0 code to transfer control to the
+ 	     correct trampoline which will transfer control to fixup
+ 	     in dl-machine.c.  */
+-	  plt_reserve->fd_func = resolve_fd->fd_func;
+-	  plt_reserve->fd_toc  = resolve_fd->fd_toc;
+-	  plt_reserve->fd_aux  = (Elf64_Addr) map;
++	  {
++	    /* The plt_reserve area is the 1st 3 doublewords of the PLT.  */
++	    Elf64_FuncDesc *plt_reserve = (Elf64_FuncDesc *) plt;
++	    Elf64_FuncDesc *resolve_fd = (Elf64_FuncDesc *) dlrr;
++	    plt_reserve->fd_func = resolve_fd->fd_func;
++	    plt_reserve->fd_toc  = resolve_fd->fd_toc;
++	    plt_reserve->fd_aux  = (Elf64_Addr) map;
+ #ifdef RTLD_BOOTSTRAP
+-	  /* When we're bootstrapping, the opd entry will not have
+-	     been relocated yet.  */
+-	  plt_reserve->fd_func += l_addr;
+-	  plt_reserve->fd_toc  += l_addr;
++	    /* When we're bootstrapping, the opd entry will not have
++	       been relocated yet.  */
++	    plt_reserve->fd_func += l_addr;
++	    plt_reserve->fd_toc  += l_addr;
++#endif
++	  }
++#else
++	  /* When we don't have function descriptors, the first doubleword
++	     of the PLT holds the address of _dl_runtime_resolve, and the
++	     second doubleword holds the map address.  */
++	  plt[0] = dlrr;
++	  plt[1] = (Elf64_Addr) map;
+ #endif
+ 
+ 	  /* Set up the lazy PLT entries.  */
+@@ -354,14 +403,8 @@
+ 	    {
+ 
+ 	      plt[offset] = (Elf64_Xword) &glink[glink_offset];
+-	      offset += 3;
+-	      /* The first 32k entries of glink can set an index and
+-		 branch using two instructions;  Past that point,
+-		 glink uses three instructions.  */
+-	      if (i < 0x8000)
+-		glink_offset += 2;
+-	      else
+-		glink_offset += 3;
++	      offset += PLT_ENTRY_WORDS;
++	      glink_offset += GLINK_ENTRY_WORDS (i);
+ 	    }
+ 
+ 	  /* Now, we've modified data.  We need to write the changes from
+@@ -389,6 +432,7 @@
+ 		       const Elf64_Rela *reloc,
+ 		       Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
+ {
++#if _CALL_ELF != 2
+   Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
+   Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
+   Elf64_Addr offset = 0;
+@@ -426,6 +470,9 @@
+   plt->fd_func = rel->fd_func + offset;
+   PPC_DCBST (&plt->fd_func);
+   PPC_ISYNC;
++#else
++  *reloc_addr = finaladdr;
++#endif
+ 
+   return finaladdr;
+ }
+@@ -433,6 +480,7 @@
+ static inline void __attribute__ ((always_inline))
+ elf_machine_plt_conflict (Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
+ {
++#if _CALL_ELF != 2
+   Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
+   Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
+ 
+@@ -443,6 +491,9 @@
+   PPC_DCBST (&plt->fd_aux);
+   PPC_DCBST (&plt->fd_toc);
+   PPC_SYNC;
++#else
++  *reloc_addr = finaladdr;
++#endif
+ }
+ 
+ /* Return the final value of a plt relocation.  */
+@@ -512,6 +563,7 @@
+ resolve_ifunc (Elf64_Addr value,
+ 	       const struct link_map *map, const struct link_map *sym_map)
+ {
++#if _CALL_ELF != 2
+ #ifndef RESOLVE_CONFLICT_FIND_MAP
+   /* The function we are calling may not yet have its opd entry relocated.  */
+   Elf64_FuncDesc opd;
+@@ -529,6 +581,7 @@
+       value = (Elf64_Addr) &opd;
+     }
+ #endif
++#endif
+   return ((Elf64_Addr (*) (unsigned long int)) value) (GLRO(dl_hwcap));
+ }
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/setjmp-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp-common.S	2014-05-29 13:58:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/setjmp-common.S	2014-05-29 14:00:27.000000000 -0500
+@@ -55,21 +55,22 @@
+    that saves r2 since the call won't go via a plt call stub.  See
+    bugz #269.  __GI__setjmp is used in csu/libc-start.c when
+    HAVE_CLEANUP_JMP_BUF is defined.  */
+-ENTRY (BP_SYM (__GI__setjmp))
++ENTRY (__GI__setjmp)
+ 	std r2,40(r1)		/* Save the callers TOC in the save area.  */
+-	cfi_endproc
+-END_2 (BP_SYM (__GI__setjmp))
+-/* Fall thru. */
++	CALL_MCOUNT 1
++	li r4,0			/* Set second argument to 0.  */
++	b JUMPTARGET (GLUE(__sigsetjmp,_ent))
++END (__GI__setjmp)
+ #endif
+ 
+-ENTRY (BP_SYM (_setjmp))
++ENTRY (_setjmp)
+ 	CALL_MCOUNT 1
+ 	li r4,0			/* Set second argument to 0.  */
+ 	b JUMPTARGET (GLUE(__sigsetjmp,_ent))
+-END (BP_SYM (_setjmp))
++END (_setjmp)
+ libc_hidden_def (_setjmp)
+ 
+-ENTRY (BP_SYM (__sigsetjmp))
++ENTRY (__sigsetjmp)
+ 	CALL_MCOUNT 2
+ JUMPTARGET(GLUE(__sigsetjmp,_ent)):
+ 	CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
+@@ -215,18 +216,18 @@
+ 	li	r3,0
+ 	blr
+ #elif defined SHARED
+-	b	JUMPTARGET (BP_SYM (__sigjmp_save))
++	b	JUMPTARGET (__sigjmp_save)
+ #else
+ 	mflr	r0
+ 	std	r0,16(r1)
+ 	stdu	r1,-112(r1)
+ 	cfi_adjust_cfa_offset(112)
+ 	cfi_offset(lr,16)
+-	bl	JUMPTARGET (BP_SYM (__sigjmp_save))
++	bl	JUMPTARGET (__sigjmp_save)
+ 	nop
+ 	ld	r0,112+16(r1)
+ 	addi	r1,r1,112
+ 	mtlr	r0
+ 	blr
+ #endif
+-END (BP_SYM (__sigsetjmp))
++END (__sigsetjmp)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/sysdep.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/sysdep.h	2014-05-29 13:58:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/sysdep.h	2014-05-29 13:58:25.000000000 -0500
+@@ -74,6 +74,8 @@
+ #endif
+ 	.endm
+ 
++#if _CALL_ELF != 2
++
+ /* Macro to prepare for calling via a function pointer.  */
+ 	.macro PPC64_LOAD_FUNCPTR PTR
+ 	ld      r12,0(\PTR)
+@@ -115,13 +117,37 @@
+ 	.size name,.-BODY_LABEL(name);		\
+ 	.size BODY_LABEL(name),.-BODY_LABEL(name);
+ #endif
++#define LOCALENTRY(name)
++
++#else /* _CALL_ELF */
++
++/* Macro to prepare for calling via a function pointer.  */
++	.macro PPC64_LOAD_FUNCPTR PTR
++	mr	r12,\PTR
++	mtctr   r12
++	.endm
++
++#define DOT_LABEL(X) X
++#define BODY_LABEL(X) X
++#define ENTRY_2(name)	\
++	.globl name;				\
++	.type name,@function;
++#define END_2(name)	\
++	.size name,.-name;
++#define LOCALENTRY(name)	\
++1:      addis	r2,r12,.TOC.-1b@ha; \
++        addi	r2,r2,.TOC.-1b@l; \
++	.localentry name,.-name;
++
++#endif /* _CALL_ELF */
+ 
+ #define ENTRY(name)	\
+ 	.section	".text";		\
+ 	ENTRY_2(name)				\
+ 	.align ALIGNARG(2);			\
+ BODY_LABEL(name):				\
+-	cfi_startproc;
++	cfi_startproc;				\
++	LOCALENTRY(name)
+ 
+ #define EALIGN_W_0  /* No words to insert.  */
+ #define EALIGN_W_1  nop
+@@ -140,7 +166,8 @@
+ 	.align ALIGNARG(alignt);		\
+ 	EALIGN_W_##words;			\
+ BODY_LABEL(name):				\
+-	cfi_startproc;
++	cfi_startproc;				\
++	LOCALENTRY(name)
+ 
+ /* Local labels stripped out by the linker.  */
+ #undef L
+@@ -295,6 +322,8 @@
+ 
+ #else /* !__ASSEMBLER__ */
+ 
++#if _CALL_ELF != 2
++
+ #define PPC64_LOAD_FUNCPTR(ptr) \
+ 	"ld 	12,0(" #ptr ");\n"					\
+ 	"ld	2,8(" #ptr ");\n"					\
+@@ -335,5 +364,26 @@
+ 	".size " #name ",.-" BODY_PREFIX #name ";\n"			\
+ 	".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
+ #endif
++#define LOCALENTRY(name)
++
++#else /* _CALL_ELF */
++
++#define PPC64_LOAD_FUNCPTR(ptr) \
++	"mr	12," #ptr ";\n"						\
++	"mtctr 	12;"
++
++#define DOT_PREFIX ""
++#define BODY_PREFIX ""
++#define ENTRY_2(name)	\
++	".type " #name ",@function;\n"					\
++	".globl " #name ";"
++#define END_2(name)	\
++	".size " #name ",.-" #name ";"
++#define LOCALENTRY(name)	\
++	"1: addis 2,12,.TOC.-1b@ha;\n"					\
++	"addi	2,2,.TOC.-1b@l;\n"					\
++	".localentry " #name ",.-" #name ";"
++
++#endif /* _CALL_ELF */
+ 
+ #endif	/* __ASSEMBLER__ */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h	2014-05-29 13:58:24.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h	2014-05-29 13:58:25.000000000 -0500
+@@ -23,6 +23,8 @@
+ 
+ /* Now define our stuff.  */
+ 
++#if _CALL_ELF != 2
++
+ static __always_inline bool
+ _dl_ppc64_is_opd_sym (const struct link_map *l, const ElfW(Sym) *sym)
+ {
+@@ -73,4 +75,6 @@
+ #define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \
+   _dl_ppc64_addr_sym_match (L, SYM, MATCHSYM, ADDR)
+ 
++#endif
++
+ #endif /* ldsodefs.h */
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S	2014-05-29 13:58:24.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S	2014-05-29 13:58:25.000000000 -0500
+@@ -111,6 +111,7 @@
+ 
+ L(noparms):
+ 
++#if _CALL_ELF != 2
+   /* Load the function address and TOC from the function descriptor
+      and store them in the ucontext as NIP and r2.  Store the 3rd
+      field of the function descriptor into the ucontext as r11 in case
+@@ -121,6 +122,12 @@
+   std   r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
+   std   r10,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
+   std   r9,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
++#else
++  /* In the ELFv2 ABI, the function pointer is already the address.
++     Store it as NIP and r12 as required by the ABI.  */
++  std   r4,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
++  std   r4,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
++#endif
+ 
+   /* If the target function returns we need to do some cleanup.  We use a
+      code trick to get the address of our cleanup function into the link
diff --git a/SOURCES/glibc-ppc64le-40.patch b/SOURCES/glibc-ppc64le-40.patch
new file mode 100644
index 0000000..8b2c532
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-40.patch
@@ -0,0 +1,159 @@
+# commit 122b66defdb9e4ded3ccc5c2b290f0520c6fa3cd
+# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+# Date:   Wed Dec 4 06:52:40 2013 -0600
+# 
+#     PowerPC64 ELFv2 ABI 3/6: PLT local entry point optimization
+#     
+#     This is a follow-on to the previous patch to support the ELFv2 ABI in the
+#     dynamic loader, split off into its own patch since it is just an optional
+#     optimization.
+#     
+#     In the ELFv2 ABI, most functions define both a global and a local entry
+#     point; the local entry requires r2 to be already set up by the caller
+#     to point to the callee's TOC; while the global entry does not require
+#     the caller to know about the callee's TOC, but it needs to set up r12
+#     to the callee's entry point address.
+#     
+#     Now, when setting up a PLT slot, the dynamic linker will usually need
+#     to enter the target function's global entry point.  However, if the
+#     linker can prove that the target function is in the same DSO as the
+#     PLT slot itself, and the whole DSO only uses a single TOC (which the
+#     linker will let ld.so know via a DT_PPC64_OPT entry), then it is
+#     possible to actually enter the local entry point address into the
+#     PLT slot, for a slight improvement in performance.
+#     
+#     Note that this uncovered a problem on the first call via _dl_runtime_resolve,
+#     because that routine neglected to restore the caller's TOC before calling
+#     the target function for the first time, since it assumed that function
+#     would always reload its own TOC anyway ...
+# 
+diff -urN glibc-2.17-c758a686.orig/elf/elf.h glibc-2.17-c758a686.diff/elf/elf.h
+--- glibc-2.17-c758a686.orig/elf/elf.h	2014-05-29 14:08:44.000000000 -0500
++++ glibc-2.17-c758a686.diff/elf/elf.h	2014-05-29 14:08:44.000000000 -0500
+@@ -2273,8 +2273,19 @@
+ #define DT_PPC64_GLINK  (DT_LOPROC + 0)
+ #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
+ 
++/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry.  */
++#define PPC64_OPT_TLS		1
++#define PPC64_OPT_MULTI_TOC	2
++
++/* PowerPC64 specific values for the Elf64_Sym st_other field.  */
++#define STO_PPC64_LOCAL_BIT	5
++#define STO_PPC64_LOCAL_MASK	(7 << STO_PPC64_LOCAL_BIT)
++#define PPC64_LOCAL_ENTRY_OFFSET(other)				\
++ (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
++
+ 
+ /* ARM specific declarations */
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 14:08:40.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 14:08:44.000000000 -0500
+@@ -425,6 +425,42 @@
+   return lazy;
+ }
+ 
++#if _CALL_ELF == 2
++/* If the PLT entry whose reloc is 'reloc' resolves to a function in
++   the same object, return the target function's local entry point
++   offset if usable.  */
++static inline Elf64_Addr __attribute__ ((always_inline))
++ppc64_local_entry_offset (struct link_map *map, lookup_t sym_map,
++			  const Elf64_Rela *reloc)
++{
++  const Elf64_Sym *symtab;
++  const Elf64_Sym *sym;
++
++  /* If the target function is in a different object, we cannot
++     use the local entry point.  */
++  if (sym_map != map)
++    return 0;
++
++  /* If the linker inserted multiple TOCs, we cannot use the
++     local entry point.  */
++  if (map->l_info[DT_PPC64(OPT)]
++      && (map->l_info[DT_PPC64(OPT)]->d_un.d_val & PPC64_OPT_MULTI_TOC))
++    return 0;
++
++  /* Otherwise, we can use the local entry point.  Retrieve its offset
++     from the symbol's ELF st_other field.  */
++  symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
++  sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
++
++  /* If the target function is an ifunc then the local entry offset is
++     for the resolver, not the final destination.  */
++  if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
++    return 0;
++
++  return PPC64_LOCAL_ENTRY_OFFSET (sym->st_other);
++}
++#endif
++
+ /* Change the PLT entry whose reloc is 'reloc' to call the actual
+    routine.  */
+ static inline Elf64_Addr __attribute__ ((always_inline))
+@@ -471,6 +507,7 @@
+   PPC_DCBST (&plt->fd_func);
+   PPC_ISYNC;
+ #else
++  finaladdr += ppc64_local_entry_offset (map, sym_map, reloc);
+   *reloc_addr = finaladdr;
+ #endif
+ 
+@@ -478,7 +515,9 @@
+ }
+ 
+ static inline void __attribute__ ((always_inline))
+-elf_machine_plt_conflict (Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
++elf_machine_plt_conflict (struct link_map *map, lookup_t sym_map,
++			  const Elf64_Rela *reloc,
++			  Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
+ {
+ #if _CALL_ELF != 2
+   Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
+@@ -492,6 +531,7 @@
+   PPC_DCBST (&plt->fd_toc);
+   PPC_SYNC;
+ #else
++  finaladdr += ppc64_local_entry_offset (map, sym_map, reloc);
+   *reloc_addr = finaladdr;
+ #endif
+ }
+@@ -641,7 +681,7 @@
+       /* Fall thru */
+     case R_PPC64_JMP_SLOT:
+ #ifdef RESOLVE_CONFLICT_FIND_MAP
+-      elf_machine_plt_conflict (reloc_addr, value);
++      elf_machine_plt_conflict (map, sym_map, reloc, reloc_addr, value);
+ #else
+       elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value);
+ #endif
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-trampoline.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 14:08:40.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 14:08:44.000000000 -0500
+@@ -74,6 +74,10 @@
+ /* Prepare for calling the function returned by fixup.  */
+ 	PPC64_LOAD_FUNCPTR r3
+ 	ld	r3,INT_PARMS+0(r1)
++#if _CALL_ELF == 2
++/* Restore the caller's TOC in case we jump to a local entry point.  */
++	ld	r2,FRAME_SIZE+40(r1)
++#endif
+ /* Unwind the stack frame, and jump.  */
+ 	addi	r1,r1,FRAME_SIZE
+ 	bctr
+@@ -321,6 +325,10 @@
+ /* Prepare for calling the function returned by fixup.  */
+ 	PPC64_LOAD_FUNCPTR r3
+ 	ld	r3,INT_PARMS+0(r1)
++#if _CALL_ELF == 2
++/* Restore the caller's TOC in case we jump to a local entry point.  */
++	ld	r2,FRAME_SIZE+40(r1)
++#endif
+ /* Load the floating point registers.  */
+ 	lfd	fp1,FPR_PARMS+0(r1)
+ 	lfd	fp2,FPR_PARMS+8(r1)
diff --git a/SOURCES/glibc-ppc64le-41.patch b/SOURCES/glibc-ppc64le-41.patch
new file mode 100644
index 0000000..7789e3e
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-41.patch
@@ -0,0 +1,764 @@
+# commit 8b8a692cfd7d80f1ee7c8b9ab356a259367dd187
+# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+# Date:   Wed Dec 4 06:55:03 2013 -0600
+# 
+#     PowerPC64 ELFv2 ABI 4/6: Stack frame layout changes
+#     
+#     This updates glibc for the changes in the ELFv2 relating to the
+#     stack frame layout.  These are described in more detail here:
+#     http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01149.html
+#     http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01146.html
+#     
+#     Specifically, the "compiler and linker doublewords" were removed,
+#     which has the effect that the save slot for the TOC register is
+#     now at offset 24 rather than 40 to the stack pointer.
+#     
+#     In addition, a function may now no longer necessarily assume that
+#     its caller has set up a 64-byte register save area its use.
+#     
+#     To address the first change, the patch goes through all assembler
+#     files and replaces immediate offsets in instructions accessing the
+#     ABI-defined stack slots by symbolic offsets.  Those already were
+#     defined in ucontext_i.sym and used in some of the context routines,
+#     but that doesn't really seem like the right place for those defines.
+#     
+#     The patch instead defines those symbolic offsets in sysdeps.h,
+#     in two variants for the old and new ABI, and uses them systematically
+#     in all assembler files, not just the context routines.
+#     
+#     The second change only affected a few assembler files that used
+#     the save area to temporarily store some registers.  In those
+#     cases where this happens within a leaf function, this patch
+#     changes the code to store those registers to the "red zone"
+#     below the stack pointer.  Otherwise, the functions already allocate
+#     a stack frame, and the patch changes them to add extra space in
+#     these frames as temporary space for the ELFv2 ABI.
+# 
+diff -urN glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h glibc-2.17-c758a686.diff/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h	2014-05-29 14:10:00.000000000 -0500
++++ glibc-2.17-c758a686.diff/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h	2014-05-29 14:10:00.000000000 -0500
+@@ -31,6 +31,14 @@
+ #  define DASHDASHPFX(str) __##str
+ # endif
+ 
++#if _CALL_ELF == 2
++#define CANCEL_FRAMESIZE (FRAME_MIN_SIZE+16+48)
++#define CANCEL_PARM_SAVE (FRAME_MIN_SIZE+16)
++#else
++#define CANCEL_FRAMESIZE (FRAME_MIN_SIZE+16)
++#define CANCEL_PARM_SAVE (CANCEL_FRAMESIZE+FRAME_PARM_SAVE)
++#endif
++
+ # undef PSEUDO
+ # define PSEUDO(name, syscall_name, args)				\
+   .section ".text";							\
+@@ -44,52 +52,52 @@
+     PSEUDO_RET;								\
+   .size DASHDASHPFX(syscall_name##_nocancel),.-DASHDASHPFX(syscall_name##_nocancel);	\
+   .Lpseudo_cancel:							\
+-    stdu 1,-128(1);							\
+-    cfi_adjust_cfa_offset (128);					\
++    stdu 1,-CANCEL_FRAMESIZE(1);					\
++    cfi_adjust_cfa_offset (CANCEL_FRAMESIZE);				\
+     mflr 9;								\
+-    std  9,128+16(1);							\
+-    cfi_offset (lr, 16);						\
++    std  9,CANCEL_FRAMESIZE+FRAME_LR_SAVE(1);				\
++    cfi_offset (lr, FRAME_LR_SAVE);					\
+     DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
+     CENABLE;								\
+-    std  3,112(1);	/* store CENABLE return value (MASK).  */	\
++    std  3,FRAME_MIN_SIZE(1); /* store CENABLE return value (MASK).  */	\
+     UNDOCARGS_##args;	/* restore syscall args.  */			\
+     DO_CALL (SYS_ify (syscall_name));					\
+     mfcr 0;		/* save CR/R3 around CDISABLE.  */		\
+-    std  3,120(1);							\
+-    std  0,128+8(1);							\
+-    cfi_offset (cr, 8);							\
+-    ld   3,112(1);	/* pass MASK to CDISABLE.  */			\
++    std  3,FRAME_MIN_SIZE+8(1);						\
++    std  0,CANCEL_FRAMESIZE+FRAME_CR_SAVE(1);				\
++    cfi_offset (cr, FRAME_CR_SAVE);					\
++    ld   3,FRAME_MIN_SIZE(1); /* pass MASK to CDISABLE.  */		\
+     CDISABLE;								\
+-    ld   9,128+16(1);							\
+-    ld   0,128+8(1);	/* restore CR/R3. */				\
+-    ld   3,120(1);							\
++    ld   9,CANCEL_FRAMESIZE+FRAME_LR_SAVE(1);				\
++    ld   0,CANCEL_FRAMESIZE+FRAME_CR_SAVE(1); /* restore CR/R3. */	\
++    ld   3,FRAME_MIN_SIZE+8(1);						\
+     mtlr 9;								\
+     mtcr 0;								\
+-    addi 1,1,128;							\
+-    cfi_adjust_cfa_offset (-128);					\
++    addi 1,1,CANCEL_FRAMESIZE;						\
++    cfi_adjust_cfa_offset (-CANCEL_FRAMESIZE);				\
+     cfi_restore (lr);							\
+     cfi_restore (cr)
+ 
+ # define DOCARGS_0
+ # define UNDOCARGS_0
+ 
+-# define DOCARGS_1	std 3,128+48(1); DOCARGS_0
+-# define UNDOCARGS_1	ld 3,128+48(1); UNDOCARGS_0
++# define DOCARGS_1	std 3,CANCEL_PARM_SAVE(1); DOCARGS_0
++# define UNDOCARGS_1	ld 3,CANCEL_PARM_SAVE(1); UNDOCARGS_0
+ 
+-# define DOCARGS_2	std 4,128+56(1); DOCARGS_1
+-# define UNDOCARGS_2	ld 4,128+56(1); UNDOCARGS_1
++# define DOCARGS_2	std 4,CANCEL_PARM_SAVE+8(1); DOCARGS_1
++# define UNDOCARGS_2	ld 4,CANCEL_PARM_SAVE+8(1); UNDOCARGS_1
+ 
+-# define DOCARGS_3	std 5,128+64(1); DOCARGS_2
+-# define UNDOCARGS_3	ld 5,128+64(1); UNDOCARGS_2
++# define DOCARGS_3	std 5,CANCEL_PARM_SAVE+16(1); DOCARGS_2
++# define UNDOCARGS_3	ld 5,CANCEL_PARM_SAVE+16(1); UNDOCARGS_2
+ 
+-# define DOCARGS_4	std 6,128+72(1); DOCARGS_3
+-# define UNDOCARGS_4	ld 6,128+72(1); UNDOCARGS_3
++# define DOCARGS_4	std 6,CANCEL_PARM_SAVE+24(1); DOCARGS_3
++# define UNDOCARGS_4	ld 6,CANCEL_PARM_SAVE+24(1); UNDOCARGS_3
+ 
+-# define DOCARGS_5	std 7,128+80(1); DOCARGS_4
+-# define UNDOCARGS_5	ld 7,128+80(1); UNDOCARGS_4
++# define DOCARGS_5	std 7,CANCEL_PARM_SAVE+32(1); DOCARGS_4
++# define UNDOCARGS_5	ld 7,CANCEL_PARM_SAVE+32(1); UNDOCARGS_4
+ 
+-# define DOCARGS_6	std 8,128+88(1); DOCARGS_5
+-# define UNDOCARGS_6	ld 8,128+88(1); UNDOCARGS_5
++# define DOCARGS_6	std 8,CANCEL_PARM_SAVE+40(1); DOCARGS_5
++# define UNDOCARGS_6	ld 8,CANCEL_PARM_SAVE+40(1); UNDOCARGS_5
+ 
+ # ifdef IS_IN_libpthread
+ #  ifdef SHARED
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/__longjmp-common.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/__longjmp-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/__longjmp-common.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/__longjmp-common.S	2014-05-29 14:10:00.000000000 -0500
+@@ -133,7 +133,7 @@
+ 	ld r14,((JB_GPRS+0)*8)(r3)
+ 	lfd fp14,((JB_FPRS+0)*8)(r3)
+ #if defined SHARED && !defined IS_IN_rtld
+-	std r2,40(r1)	/* Restore the callers TOC save area.  */
++	std r2,FRAME_TOC_SAVE(r1)	/* Restore the callers TOC save area.  */
+ #endif
+ 	ld r15,((JB_GPRS+1)*8)(r3)
+ 	lfd fp15,((JB_FPRS+1)*8)(r3)
+@@ -151,7 +151,7 @@
+ 	PTR_DEMANGLE2 (r0, r25)
+ #endif
+ 	mtlr r0
+-/* 	std r2,40(r1)	Restore the TOC save area.  */
++/* 	std r2,FRAME_TOC_SAVE(r1)	Restore the TOC save area.  */
+ 	ld r21,((JB_GPRS+7)*8)(r3)
+ 	lfd fp21,((JB_FPRS+7)*8)(r3)
+ 	ld r22,((JB_GPRS+8)*8)(r3)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/crti.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/crti.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/crti.S	2014-05-29 14:10:00.000000000 -0500
+@@ -66,8 +66,8 @@
+ BODY_LABEL (_init):
+ 	LOCALENTRY(_init)
+ 	mflr 0
+-	std 0, 16(r1)
+-	stdu r1, -112(r1)
++	std 0, FRAME_LR_SAVE(r1)
++	stdu r1, -FRAME_MIN_SIZE_PARM(r1)
+ #if PREINIT_FUNCTION_WEAK
+ 	addis r9, r2, .LC0@toc@ha
+ 	ld r0, .LC0@toc@l(r9)
+@@ -84,5 +84,5 @@
+ BODY_LABEL (_fini):
+ 	LOCALENTRY(_fini)
+ 	mflr 0
+-	std 0, 16(r1)
+-	stdu r1, -112(r1)
++	std 0, FRAME_LR_SAVE(r1)
++	stdu r1, -FRAME_MIN_SIZE_PARM(r1)
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/crtn.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/crtn.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/crtn.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/crtn.S	2014-05-29 14:10:00.000000000 -0500
+@@ -39,13 +39,13 @@
+ #include <sysdep.h>
+ 
+ 	.section .init,"ax",@progbits
+-	addi r1, r1, 112
+-	ld r0, 16(r1)
++	addi r1, r1, FRAME_MIN_SIZE_PARM
++	ld r0, FRAME_LR_SAVE(r1)
+ 	mtlr r0
+ 	blr
+ 
+ 	.section .fini,"ax",@progbits
+-	addi r1, r1, 112
+-	ld r0, 16(r1)
++	addi r1, r1, FRAME_MIN_SIZE_PARM
++	ld r0, FRAME_LR_SAVE(r1)
+ 	mtlr r0
+ 	blr
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-trampoline.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 14:10:00.000000000 -0500
+@@ -26,13 +26,13 @@
+    parm1 (r3) and the index (r0) need to be converted to an offset
+    (index * 24) in parm2 (r4).  */
+ 
+-#define FRAME_SIZE 176
++#define FRAME_SIZE (FRAME_MIN_SIZE+64)
+ /* We need to save the registers used to pass parameters, ie. r3 thru
+    r10;  Use local var space rather than the parameter save area,
+    because gcc as of 2010/05 doesn't allocate a proper stack frame for
+    a function that makes no calls except for __tls_get_addr and we
+    might be here resolving the __tls_get_addr call.  */
+-#define INT_PARMS 112
++#define INT_PARMS FRAME_MIN_SIZE
+ EALIGN(_dl_runtime_resolve, 4, 0)
+ 	stdu	r1,-FRAME_SIZE(r1)
+ 	cfi_adjust_cfa_offset (FRAME_SIZE)
+@@ -48,25 +48,25 @@
+ 	mflr	r0
+ 	std	r8,INT_PARMS+40(r1)
+ /* Store the LR in the LR Save area.  */
+-	std	r0,FRAME_SIZE+16(r1)
+-	cfi_offset (lr, 16)
++	std	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
++	cfi_offset (lr, FRAME_LR_SAVE)
+ 	mfcr	r0
+ 	std	r9,INT_PARMS+48(r1)
+ 	std	r10,INT_PARMS+56(r1)
+ /* I'm almost certain we don't have to save cr...  be safe.  */
+-	std	r0,FRAME_SIZE+8(r1)
++	std	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	bl	JUMPTARGET(_dl_fixup)
+ #ifndef SHARED
+ 	nop
+ #endif
+ /* Put the registers back.  */
+-	ld	r0,FRAME_SIZE+16(r1)
++	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
+ 	ld	r10,INT_PARMS+56(r1)
+ 	ld	r9,INT_PARMS+48(r1)
+ 	ld	r8,INT_PARMS+40(r1)
+ 	ld	r7,INT_PARMS+32(r1)
+ 	mtlr	r0
+-	ld	r0,FRAME_SIZE+8(r1)
++	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	ld	r6,INT_PARMS+24(r1)
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+@@ -76,7 +76,7 @@
+ 	ld	r3,INT_PARMS+0(r1)
+ #if _CALL_ELF == 2
+ /* Restore the caller's TOC in case we jump to a local entry point.  */
+-	ld	r2,FRAME_SIZE+40(r1)
++	ld	r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
+ #endif
+ /* Unwind the stack frame, and jump.  */
+ 	addi	r1,r1,FRAME_SIZE
+@@ -86,6 +86,7 @@
+ #undef INT_PARMS
+ 
+ 	/* Stack layout:
++	   (Note: some of these are not required for the ELFv2 ABI.)
+ 	  +592   previous backchain
+ 	  +584   spill_r31
+ 	  +576   spill_r30
+@@ -147,10 +148,11 @@
+ 	  +64    parm3
+ 	  +56    parm2
+ 	  +48    parm1
+-	 * Parameter save area, Allocated by the call, at least 8 double words
+-	  +40    TOC save area
+-	  +32    Reserved for linker
+-	  +24    Reserved for compiler
++	 * Parameter save area
++	 * (v1 ABI: Allocated by the call, at least 8 double words)
++	  +40    v1 ABI: TOC save area
++	  +32    v1 ABI: Reserved for linker
++	  +24    v1 ABI: Reserved for compiler / v2 ABI: TOC save area
+ 	  +16    LR save area
+ 	  +8     CR save area
+ 	r1+0     stack back chain
+@@ -206,15 +208,15 @@
+ /* Store the LR in the LR Save area of the previous frame.  */
+ /* XXX Do we have to do this?  */
+ 	la	r8,FRAME_SIZE(r1)
+-	std	r5,FRAME_SIZE+16(r1)
+-	cfi_offset (lr, 16)
++	std	r5,FRAME_SIZE+FRAME_LR_SAVE(r1)
++	cfi_offset (lr, FRAME_LR_SAVE)
+ 	std	r5,CALLING_LR(r1)
+ 	mfcr	r0
+ 	std	r9,INT_PARMS+48(r1)
+ 	std	r10,INT_PARMS+56(r1)
+ 	std	r8,CALLING_SP(r1)
+ /* I'm almost certain we don't have to save cr...  be safe.  */
+-	std	r0,FRAME_SIZE+8(r1)
++	std	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	ld	r12,.LC__dl_hwcap@toc(r2)
+ #ifdef SHARED
+ 	/* Load _rtld_local_ro._dl_hwcap.  */
+@@ -311,13 +313,13 @@
+ 	lvx	v12,r11,r10
+ 	lvx	v13,r11,r9
+ L(restoreFXR):
+-	ld	r0,FRAME_SIZE+16(r1)
++	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
+ 	ld	r10,INT_PARMS+56(r1)
+ 	ld	r9,INT_PARMS+48(r1)
+ 	ld	r8,INT_PARMS+40(r1)
+ 	ld	r7,INT_PARMS+32(r1)
+ 	mtlr	r0
+-	ld	r0,FRAME_SIZE+8(r1)
++	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	ld	r6,INT_PARMS+24(r1)
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+@@ -327,7 +329,7 @@
+ 	ld	r3,INT_PARMS+0(r1)
+ #if _CALL_ELF == 2
+ /* Restore the caller's TOC in case we jump to a local entry point.  */
+-	ld	r2,FRAME_SIZE+40(r1)
++	ld	r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
+ #endif
+ /* Load the floating point registers.  */
+ 	lfd	fp1,FPR_PARMS+0(r1)
+@@ -375,19 +377,19 @@
+ 	lvx	v12,r11,r10
+ 	lvx	v13,r11,r9
+ L(restoreFXR2):
+-	ld	r0,FRAME_SIZE+16(r1)
++	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
+ 	ld	r10,INT_PARMS+56(r1)
+ 	ld	r9,INT_PARMS+48(r1)
+ 	ld	r8,INT_PARMS+40(r1)
+ 	ld	r7,INT_PARMS+32(r1)
+ 	mtlr	r0
+-	ld	r0,FRAME_SIZE+8(r1)
++	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	ld	r6,INT_PARMS+24(r1)
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+ 	mtcrf	0xFF,r0
+ /* Prepare for calling the function returned by fixup.  */
+-	std	r2,40(r1)
++	std	r2,FRAME_TOC_SAVE(r1)
+ 	PPC64_LOAD_FUNCPTR r3
+ 	ld	r3,INT_PARMS+0(r1)
+ /* Load the floating point registers.  */
+@@ -406,7 +408,7 @@
+ 	lfd	fp13,FPR_PARMS+96(r1)
+ /* Call the target function.  */
+ 	bctrl
+-	ld	r2,40(r1)
++	ld	r2,FRAME_TOC_SAVE(r1)
+ 	lwz	r12,VR_VRSAVE(r1)
+ /* But return here and store the return values.  */
+ 	std	r3,INT_RTN(r1)
+@@ -441,7 +443,7 @@
+ 	beq	L(pltexitreturn)
+ 	lvx	v2,0,r10
+ L(pltexitreturn):
+-	ld	r0,FRAME_SIZE+16(r1)
++	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
+ 	ld	r31,584(r1)
+ 	ld	r30,576(r1)
+ 	mtlr	r0
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/ppc-mcount.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/ppc-mcount.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/ppc-mcount.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/ppc-mcount.S	2014-05-29 14:10:00.000000000 -0500
+@@ -24,16 +24,16 @@
+ ENTRY(_mcount)
+ 	mflr		 r4
+ 	ld		 r11, 0(r1)
+-	stdu		 r1,-112(r1)
+-	cfi_adjust_cfa_offset (112)
+-	std		 r4, 128(r1)
+-	cfi_offset (lr, 16)
+-	ld		 r3, 16(r11)
++	stdu		 r1,-FRAME_MIN_SIZE(r1)
++	cfi_adjust_cfa_offset (FRAME_MIN_SIZE)
++	std		 r4, FRAME_MIN_SIZE+FRAME_LR_SAVE(r1)
++	cfi_offset (lr, FRAME_LR_SAVE)
++	ld		 r3, FRAME_LR_SAVE(r11)
+ 	bl		 JUMPTARGET(__mcount_internal)
+ 	nop
+-	ld		 r0, 128(r1)
++	ld		 r0, FRAME_MIN_SIZE+FRAME_LR_SAVE(r1)
+ 	mtlr		 r0
+-	addi		 r1,r1,112
++	addi		 r1,r1,FRAME_MIN_SIZE
+ 	blr
+ END(_mcount)
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/setjmp-common.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp-common.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/setjmp-common.S	2014-05-29 14:10:00.000000000 -0500
+@@ -56,7 +56,7 @@
+    bugz #269.  __GI__setjmp is used in csu/libc-start.c when
+    HAVE_CLEANUP_JMP_BUF is defined.  */
+ ENTRY (__GI__setjmp)
+-	std r2,40(r1)		/* Save the callers TOC in the save area.  */
++	std r2,FRAME_TOC_SAVE(r1)		/* Save the callers TOC in the save area.  */
+ 	CALL_MCOUNT 1
+ 	li r4,0			/* Set second argument to 0.  */
+ 	b JUMPTARGET (GLUE(__sigsetjmp,_ent))
+@@ -83,7 +83,7 @@
+ #endif
+ 	mflr r0
+ #if defined SHARED && !defined IS_IN_rtld
+-	ld   r5,40(r1)	/* Retrieve the callers TOC.  */
++	ld   r5,FRAME_TOC_SAVE(r1)	/* Retrieve the callers TOC.  */
+ 	std  r5,(JB_GPR2*8)(3)
+ #else
+ 	std  r2,(JB_GPR2*8)(3)
+@@ -219,14 +219,14 @@
+ 	b	JUMPTARGET (__sigjmp_save)
+ #else
+ 	mflr	r0
+-	std	r0,16(r1)
+-	stdu	r1,-112(r1)
+-	cfi_adjust_cfa_offset(112)
+-	cfi_offset(lr,16)
++	std	r0,FRAME_LR_SAVE(r1)
++	stdu	r1,-FRAME_MIN_SIZE(r1)
++	cfi_adjust_cfa_offset(FRAME_MIN_SIZE)
++	cfi_offset(lr,FRAME_LR_SAVE)
+ 	bl	JUMPTARGET (__sigjmp_save)
+ 	nop
+-	ld	r0,112+16(r1)
+-	addi	r1,r1,112
++	ld	r0,FRAME_MIN_SIZE+FRAME_LR_SAVE(r1)
++	addi	r1,r1,FRAME_MIN_SIZE
+ 	mtlr	r0
+ 	blr
+ #endif
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/sysdep.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/sysdep.h	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/sysdep.h	2014-05-29 14:10:00.000000000 -0500
+@@ -20,25 +20,67 @@
+ 
+ #ifdef __ASSEMBLER__
+ 
++/* Stack frame offsets.  */
++#if _CALL_ELF != 2
++#define FRAME_MIN_SIZE		112
++#define FRAME_MIN_SIZE_PARM	112
++#define FRAME_BACKCHAIN		0
++#define FRAME_CR_SAVE		8
++#define FRAME_LR_SAVE		16
++#define FRAME_TOC_SAVE		40
++#define FRAME_PARM_SAVE		48
++#define FRAME_PARM1_SAVE	48
++#define FRAME_PARM2_SAVE	56
++#define FRAME_PARM3_SAVE	64
++#define FRAME_PARM4_SAVE	72
++#define FRAME_PARM5_SAVE	80
++#define FRAME_PARM6_SAVE	88
++#define FRAME_PARM7_SAVE	96
++#define FRAME_PARM8_SAVE	104
++#define FRAME_PARM9_SAVE	112
++#else
++#define FRAME_MIN_SIZE		32
++#define FRAME_MIN_SIZE_PARM	96
++#define FRAME_BACKCHAIN		0
++#define FRAME_CR_SAVE		8
++#define FRAME_LR_SAVE		16
++#define FRAME_TOC_SAVE		24
++#define FRAME_PARM_SAVE		32
++#define FRAME_PARM1_SAVE	32
++#define FRAME_PARM2_SAVE	40
++#define FRAME_PARM3_SAVE	48
++#define FRAME_PARM4_SAVE	56
++#define FRAME_PARM5_SAVE	64
++#define FRAME_PARM6_SAVE	72
++#define FRAME_PARM7_SAVE	80
++#define FRAME_PARM8_SAVE	88
++#define FRAME_PARM9_SAVE	96
++#endif
++
+ /* Support macros for CALL_MCOUNT.  */
++#if _CALL_ELF == 2
++#define call_mcount_parm_offset (-64)
++#else
++#define call_mcount_parm_offset FRAME_PARM_SAVE
++#endif
+ 	.macro SAVE_ARG NARG
+ 	.if \NARG
+ 	SAVE_ARG \NARG-1
+-	std	2+\NARG,40+8*(\NARG)(1)
++	std	2+\NARG,call_mcount_parm_offset-8+8*(\NARG)(1)
+ 	.endif
+ 	.endm
+ 
+ 	.macro REST_ARG NARG
+ 	.if \NARG
+ 	REST_ARG \NARG-1
+-	ld	2+\NARG,112+40+8*(\NARG)(1)
++	ld	2+\NARG,FRAME_MIN_SIZE_PARM+call_mcount_parm_offset-8+8*(\NARG)(1)
+ 	.endif
+ 	.endm
+ 
+ 	.macro CFI_SAVE_ARG NARG
+ 	.if \NARG
+ 	CFI_SAVE_ARG \NARG-1
+-	cfi_offset(2+\NARG,40+8*(\NARG))
++	cfi_offset(2+\NARG,call_mcount_parm_offset-8+8*(\NARG))
+ 	.endif
+ 	.endm
+ 
+@@ -55,20 +97,20 @@
+ #ifdef	PROF
+ 	mflr	r0
+ 	SAVE_ARG \NARG
+-	std	r0,16(r1)
+-	stdu	r1,-112(r1)
+-	cfi_adjust_cfa_offset(112)
+-	cfi_offset(lr,16)
++	std	r0,FRAME_LR_SAVE(r1)
++	stdu	r1,-FRAME_MIN_SIZE_PARM(r1)
++	cfi_adjust_cfa_offset(FRAME_MIN_SIZE_PARM)
++	cfi_offset(lr,FRAME_LR_SAVE)
+ 	CFI_SAVE_ARG \NARG
+ 	bl	JUMPTARGET (_mcount)
+ #ifndef SHARED
+ 	nop
+ #endif
+-	ld	r0,128(r1)
++	ld	r0,FRAME_MIN_SIZE_PARM+FRAME_LR_SAVE(r1)
+ 	REST_ARG \NARG
+ 	mtlr	r0
+-	addi	r1,r1,112
+-	cfi_adjust_cfa_offset(-112)
++	addi	r1,r1,FRAME_MIN_SIZE_PARM
++	cfi_adjust_cfa_offset(-FRAME_MIN_SIZE_PARM)
+ 	cfi_restore(lr)
+ 	CFI_REST_ARG \NARG
+ #endif
+@@ -267,15 +309,15 @@
+     .else; \
+ .Local_syscall_error: \
+     mflr 0; \
+-    std 0,16(1); \
+-    stdu 1,-112(1); \
+-    cfi_adjust_cfa_offset(112); \
+-    cfi_offset(lr,16); \
++    std 0,FRAME_LR_SAVE(1); \
++    stdu 1,-FRAME_MIN_SIZE(1); \
++    cfi_adjust_cfa_offset(FRAME_MIN_SIZE); \
++    cfi_offset(lr,FRAME_LR_SAVE); \
+     bl JUMPTARGET(__syscall_error); \
+     nop; \
+-    ld 0,112+16(1); \
+-    addi 1,1,112; \
+-    cfi_adjust_cfa_offset(-112); \
++    ld 0,FRAME_MIN_SIZE+FRAME_LR_SAVE(1); \
++    addi 1,1,FRAME_MIN_SIZE; \
++    cfi_adjust_cfa_offset(-FRAME_MIN_SIZE); \
+     mtlr 0; \
+     cfi_restore(lr); \
+     blr; \
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S	2014-05-29 14:10:00.000000000 -0500
+@@ -33,24 +33,24 @@
+ 	cmpld	reg, r1;				\
+ 	bge+	.Lok;					\
+ 	mflr	r0;					\
+-	std	r0,16(r1);				\
++	std	r0,FRAME_LR_SAVE(r1);			\
+ 	mr	r31,r3;					\
+ 	mr	r30,r4;					\
+-	stdu	r1,-144(r1);				\
++	stdu	r1,-FRAME_MIN_SIZE-32(r1);		\
+ 	cfi_remember_state;				\
+-	cfi_adjust_cfa_offset (144);			\
+-	cfi_offset (lr, 16);				\
++	cfi_adjust_cfa_offset (FRAME_MIN_SIZE+32);	\
++	cfi_offset (lr, FRAME_LR_SAVE);			\
+ 	li	r3,0;					\
+-	addi	r4,r1,112;				\
++	addi	r4,r1,FRAME_MIN_SIZE;			\
+ 	li	r0,__NR_sigaltstack;			\
+ 	sc;						\
+ 	/* Without working sigaltstack we cannot perform the test.  */ \
+ 	bso	.Lok2;					\
+-	lwz	r0,112+8(r1);				\
++	lwz	r0,FRAME_MIN_SIZE+8(r1);		\
+ 	andi.	r4,r0,1;				\
+ 	beq	.Lfail;					\
+-	ld	r0,112+16(r1);				\
+-	ld	r4,112(r1);				\
++	ld	r0,FRAME_MIN_SIZE+16(r1);		\
++	ld	r4,FRAME_MIN_SIZE(r1);			\
+ 	add	r4,r4,r0;				\
+ 	sub	r3,r3,reg;				\
+ 	cmpld	r3,r0;					\
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S	2014-05-29 14:10:00.000000000 -0500
+@@ -31,9 +31,9 @@
+ 	CALL_MCOUNT 1
+ 	DISCARD_BOUNDS (r3)	/* the bounds are meaningless, so toss 'em.  */
+ 
+-	std	r3,48(r1)
++	std	r3,-8(r1)
+ 	DO_CALL(SYS_ify(brk))
+-	ld	r6,48(r1)
++	ld	r6,-8(r1)
+ 	ld	r5,.LC__curbrk@toc(r2)
+ 	std     r3,0(r5)
+ 	cmpld   r6,r3
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S	2014-05-29 14:10:00.000000000 -0500
+@@ -45,22 +45,22 @@
+ 	cror	cr0*4+eq,cr1*4+eq,cr0*4+eq
+ 	beq-	cr0,L(badargs)
+ 
+-	/* Save some regs in parm save area.  */
++	/* Save some regs in the "red zone".  */
+ #ifdef RESET_PID
+-	std	r29,48(r1)
++	std	r29,-24(r1)
+ #endif
+-	std	r30,56(r1)
+-	std	r31,64(r1)
++	std	r30,-16(r1)
++	std	r31,-8(r1)
+ #ifdef RESET_PID
+-	cfi_offset(r29,48)
++	cfi_offset(r29,-24)
+ #endif
+-	cfi_offset(r30,56)
+-	cfi_offset(r31,64)
++	cfi_offset(r30,-16)
++	cfi_offset(r31,-8)
+ 
+ 	/* Set up stack frame for child.  */
+ 	clrrdi	r4,r4,4
+ 	li	r0,0
+-	stdu	r0,-112(r4) /* min stack frame is 112 bytes per ABI */
++	stdu	r0,-FRAME_MIN_SIZE_PARM(r4)
+ 
+ 	/* Save fn, args, stack across syscall.  */
+ 	mr	r30,r3			/* Function in r30.  */
+@@ -102,12 +102,12 @@
+ L(oldpid):
+ #endif
+ 
+-	std	r2,40(r1)
++	std	r2,FRAME_TOC_SAVE(r1)
+ 	/* Call procedure.  */
+ 	PPC64_LOAD_FUNCPTR r30
+ 	mr	r3,r31
+ 	bctrl
+-	ld	r2,40(r1)
++	ld	r2,FRAME_TOC_SAVE(r1)
+ 	/* Call _exit with result from procedure.  */
+ #ifdef SHARED
+ 	b	JUMPTARGET(__GI__exit)
+@@ -126,15 +126,15 @@
+ L(parent):
+ 	/* Parent.  Restore registers & return.  */
+ #ifdef RESET_PID
+-	cfi_offset(r29,48)
++	cfi_offset(r29,-24)
+ #endif
+-	cfi_offset(r30,56)
+-	cfi_offset(r31,64)
++	cfi_offset(r30,-16)
++	cfi_offset(r31,-8)
+ #ifdef RESET_PID
+-	ld	r29,48(r1)
++	ld	r29,-24(r1)
+ #endif
+-	ld	r30,56(r1)
+-	ld	r31,64(r1)
++	ld	r30,-16(r1)
++	ld	r31,-8(r1)
+ #ifdef RESET_PID
+ 	cfi_restore(r29)
+ #endif
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S	2014-05-29 14:10:00.000000000 -0500
+@@ -46,8 +46,13 @@
+ # endif
+ #endif
+ 
+-#define FRAMESIZE 128
+-#define stackblock FRAMESIZE+48 /* offset to parm save area.  */
++#if _CALL_ELF == 2
++#define FRAMESIZE (FRAME_MIN_SIZE+16+64)
++#define stackblock (FRAME_MIN_SIZE+16)
++#else
++#define FRAMESIZE (FRAME_MIN_SIZE+16)
++#define stackblock (FRAMESIZE+FRAME_PARM_SAVE) /* offset to parm save area.  */
++#endif
+ 
+ 	.text
+ ENTRY(__socket)
+@@ -98,22 +103,22 @@
+ .Lsocket_cancel:
+ 	cfi_adjust_cfa_offset(FRAMESIZE)
+ 	mflr	r9
+-	std	r9,FRAMESIZE+16(r1)
+-	cfi_offset (lr, 16)
++	std	r9,FRAMESIZE+FRAME_LR_SAVE(r1)
++	cfi_offset (lr, FRAME_LR_SAVE)
+ 	CENABLE
+-	std	r3,120(r1)
++	std	r3,FRAME_MIN_SIZE+8(r1)
+ 	li	r3,P(SOCKOP_,socket)
+ 	addi	r4,r1,stackblock
+ 	DO_CALL(SYS_ify(socketcall))
+ 	mfcr	r0
+-	std	r3,112(r1)
+-	std	r0,FRAMESIZE+8(r1)
+-	cfi_offset (cr, 8)
+-	ld  	r3,120(r1)
++	std	r3,FRAME_MIN_SIZE(r1)
++	std	r0,FRAMESIZE+FRAME_CR_SAVE(r1)
++	cfi_offset (cr, FRAME_CR_SAVE)
++	ld  	r3,FRAME_MIN_SIZE+8(r1)
+ 	CDISABLE
+-	ld	r4,FRAMESIZE+16(r1)
+-	ld	r0,FRAMESIZE+8(r1)
+-	ld	r3,112(r1)
++	ld	r4,FRAMESIZE+FRAME_LR_SAVE(r1)
++	ld	r0,FRAMESIZE+FRAME_CR_SAVE(r1)
++	ld	r3,FRAME_MIN_SIZE(r1)
+ 	mtlr	r4
+ 	mtcr	r0
+ 	addi	r1,r1,FRAMESIZE
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym	2014-05-29 14:09:56.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym	2014-05-29 14:10:00.000000000 -0500
+@@ -8,27 +8,6 @@
+ SIG_SETMASK
+ 
+ 
+--- Offsets of the fields in the powerpc64 ABI stack frame.
+--- XXX Do these correspond to some struct?
+-
+-FRAME_BACKCHAIN		0
+-FRAME_CR_SAVE		8
+-FRAME_LR_SAVE		16
+-FRAME_COMPILER_DW	24
+-FRAME_LINKER_DW		32
+-FRAME_TOC_SAVE		40
+-FRAME_PARM_SAVE		48
+-FRAME_PARM1_SAVE	48
+-FRAME_PARM2_SAVE	56
+-FRAME_PARM3_SAVE	64
+-FRAME_PARM4_SAVE	72
+-FRAME_PARM5_SAVE	80
+-FRAME_PARM6_SAVE	88
+-FRAME_PARM7_SAVE	96
+-FRAME_PARM8_SAVE	104
+-FRAME_PARM9_SAVE	112
+-
+-
+ -- Offsets of the fields in the ucontext_t structure.
+ #define ucontext(member)	offsetof (ucontext_t, member)
+ #define mcontext(member)	ucontext (uc_mcontext.member)
diff --git a/SOURCES/glibc-ppc64le-42.patch b/SOURCES/glibc-ppc64le-42.patch
new file mode 100644
index 0000000..4126f2a
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-42.patch
@@ -0,0 +1,404 @@
+# commit 61cd8fe4017c251617dd300818917e61a12ab48e
+# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+# Date:   Wed Dec 4 06:59:37 2013 -0600
+# 
+#     PowerPC64 ELFv2 ABI 5/6: LD_AUDIT interface changes
+#     
+#     The ELFv2 ABI changes the calling convention by passing and returning
+#     structures in registers in more cases than the old ABI:
+#     http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html
+#     http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html
+#     
+#     For the most part, this does not affect glibc, since glibc assembler
+#     files do not use structure parameters / return values.  However, one
+#     place is affected: the LD_AUDIT interface provides a structure to
+#     the audit routine that contains all registers holding function
+#     argument and return values for the intercepted PLT call.
+#     
+#     Since the new ABI now sometimes uses registers to return values
+#     that were never used for this purpose in the old ABI, this structure
+#     has to be extended.  To force audit routines to be modified for the
+#     new ABI if necessary, the patch defines v2 variants of the la_ppc64
+#     types and routines.
+#     
+#     In addition, the patch contains two unrelated changes to the
+#     PLT trampoline routines: it fixes a bug where FPR return values
+#     were stored in the wrong place, and it removes the unnecessary
+#     save/restore of CR.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/bits/link.h glibc-2.17-c758a686.diff/sysdeps/powerpc/bits/link.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/bits/link.h	2014-05-29 14:11:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/bits/link.h	2014-05-29 14:11:20.000000000 -0500
+@@ -63,7 +63,7 @@
+ 
+ __END_DECLS
+ 
+-#else
++#elif _CALL_ELF != 2
+ 
+ /* Registers for entry into PLT on PPC64.  */
+ typedef struct La_ppc64_regs
+@@ -107,4 +107,48 @@
+ 
+ __END_DECLS
+ 
++#else
++
++/* Registers for entry into PLT on PPC64 in the ELFv2 ABI.  */
++typedef struct La_ppc64v2_regs
++{
++  uint64_t lr_reg[8];
++  double lr_fp[13];
++  uint32_t __padding;
++  uint32_t lr_vrsave;
++  uint32_t lr_vreg[12][4] __attribute__ ((aligned (16)));
++  uint64_t lr_r1;
++  uint64_t lr_lr;
++} La_ppc64v2_regs;
++
++/* Return values for calls from PLT on PPC64 in the ELFv2 ABI.  */
++typedef struct La_ppc64v2_retval
++{
++  uint64_t lrv_r3;
++  uint64_t lrv_r4;
++  double lrv_fp[10];
++  uint32_t lrv_vreg[8][4] __attribute__ ((aligned (16)));
++} La_ppc64v2_retval;
++
++
++__BEGIN_DECLS
++
++extern Elf64_Addr la_ppc64v2_gnu_pltenter (Elf64_Sym *__sym,
++					   unsigned int __ndx,
++					   uintptr_t *__refcook,
++					   uintptr_t *__defcook,
++					   La_ppc64v2_regs *__regs,
++					   unsigned int *__flags,
++					   const char *__symname,
++					   long int *__framesizep);
++extern unsigned int la_ppc64v2_gnu_pltexit (Elf64_Sym *__sym,
++					    unsigned int __ndx,
++					    uintptr_t *__refcook,
++					    uintptr_t *__defcook,
++					    const La_ppc64v2_regs *__inregs,
++					    La_ppc64v2_retval *__outregs,
++					    const char *__symname);
++
++__END_DECLS
++
+ #endif
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/ldsodefs.h glibc-2.17-c758a686.diff/sysdeps/powerpc/ldsodefs.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/ldsodefs.h	2014-05-29 14:11:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/ldsodefs.h	2014-05-29 14:11:20.000000000 -0500
+@@ -25,6 +25,8 @@
+ struct La_ppc32_retval;
+ struct La_ppc64_regs;
+ struct La_ppc64_retval;
++struct La_ppc64v2_regs;
++struct La_ppc64v2_retval;
+ 
+ #define ARCH_PLTENTER_MEMBERS						\
+     Elf32_Addr (*ppc32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, \
+@@ -34,7 +36,12 @@
+     Elf64_Addr (*ppc64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *, \
+ 				      uintptr_t *, struct La_ppc64_regs *, \
+ 				      unsigned int *, const char *name,	\
+-				      long int *framesizep)
++				      long int *framesizep);		\
++    Elf64_Addr (*ppc64v2_gnu_pltenter) (Elf64_Sym *, unsigned int,	\
++					uintptr_t *,  uintptr_t *,	\
++					struct La_ppc64v2_regs *,	\
++					unsigned int *, const char *name, \
++					long int *framesizep)
+ 
+ #define ARCH_PLTEXIT_MEMBERS						\
+     unsigned int (*ppc32_gnu_pltexit) (Elf32_Sym *, unsigned int,	\
+@@ -47,7 +54,14 @@
+ 				       uintptr_t *,			\
+ 				       uintptr_t *,			\
+ 				       const struct La_ppc64_regs *,	\
+-				       struct La_ppc64_retval *, const char *)
++				       struct La_ppc64_retval *,	\
++				       const char *);			\
++    unsigned int (*ppc64v2_gnu_pltexit) (Elf64_Sym *, unsigned int,	\
++					 uintptr_t *,			\
++					 uintptr_t *,			\
++					 const struct La_ppc64v2_regs *,\
++					 struct La_ppc64v2_retval *,	\
++					 const char *)
+ 
+ #include_next <ldsodefs.h>
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 14:11:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-machine.h	2014-05-29 14:11:20.000000000 -0500
+@@ -546,8 +546,13 @@
+ 
+ 
+ /* Names of the architecture-specific auditing callback functions.  */
++#if _CALL_ELF != 2
+ #define ARCH_LA_PLTENTER ppc64_gnu_pltenter
+ #define ARCH_LA_PLTEXIT ppc64_gnu_pltexit
++#else
++#define ARCH_LA_PLTENTER ppc64v2_gnu_pltenter
++#define ARCH_LA_PLTEXIT ppc64v2_gnu_pltexit
++#endif
+ 
+ #endif /* dl_machine_h */
+ 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-trampoline.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 14:11:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/dl-trampoline.S	2014-05-29 14:11:20.000000000 -0500
+@@ -50,11 +50,8 @@
+ /* Store the LR in the LR Save area.  */
+ 	std	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
+ 	cfi_offset (lr, FRAME_LR_SAVE)
+-	mfcr	r0
+ 	std	r9,INT_PARMS+48(r1)
+ 	std	r10,INT_PARMS+56(r1)
+-/* I'm almost certain we don't have to save cr...  be safe.  */
+-	std	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	bl	JUMPTARGET(_dl_fixup)
+ #ifndef SHARED
+ 	nop
+@@ -66,11 +63,9 @@
+ 	ld	r8,INT_PARMS+40(r1)
+ 	ld	r7,INT_PARMS+32(r1)
+ 	mtlr	r0
+-	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	ld	r6,INT_PARMS+24(r1)
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+-	mtcrf	0xFF,r0
+ /* Prepare for calling the function returned by fixup.  */
+ 	PPC64_LOAD_FUNCPTR r3
+ 	ld	r3,INT_PARMS+0(r1)
+@@ -85,18 +80,30 @@
+ #undef FRAME_SIZE
+ #undef INT_PARMS
+ 
+-	/* Stack layout:
+-	   (Note: some of these are not required for the ELFv2 ABI.)
+-	  +592   previous backchain
+-	  +584   spill_r31
+-	  +576   spill_r30
+-	  +560   v1
+-	  +552   fp4
+-	  +544   fp3
+-	  +536   fp2
+-	  +528   fp1
+-	  +520   r4
+-	  +512   r3
++	/* Stack layout:		ELFv2 ABI.
++					+752   previous backchain
++					+744   spill_r31
++					+736   spill_r30
++					+720   v8
++					+704   v7
++					+688   v6
++					+672   v5
++					+656   v4
++					+640   v3
++					+624   v2
++					+608   v1
++					+600   fp10
++	  ELFv1 ABI			+592   fp9
++	  +592   previous backchain	+584   fp8
++	  +584   spill_r31		+576   fp7
++	  +576   spill_r30		+568   fp6
++	  +560   v1			+560   fp5
++	  +552   fp4			+552   fp4
++	  +544   fp3			+544   fp3
++	  +536   fp2			+536   fp2
++	  +528   fp1			+528   fp1
++	  +520   r4			+520   r4
++	  +512   r3			+512   r3
+ 	   return values
+           +504   free
+ 	  +496   stackframe
+@@ -157,10 +164,15 @@
+ 	  +8     CR save area
+ 	r1+0     stack back chain
+ 	*/
+-#define FRAME_SIZE 592
++#if _CALL_ELF == 2
++# define FRAME_SIZE 752
++# define VR_RTN 608
++#else
++# define FRAME_SIZE 592
++# define VR_RTN 560
++#endif
+ #define INT_RTN 512
+ #define FPR_RTN 528
+-#define VR_RTN 560
+ #define STACK_FRAME 496
+ #define CALLING_LR 488
+ #define CALLING_SP 480
+@@ -205,18 +217,14 @@
+ 	mflr	r5
+ 	std	r7,INT_PARMS+32(r1)
+ 	std	r8,INT_PARMS+40(r1)
+-/* Store the LR in the LR Save area of the previous frame.  */
+-/* XXX Do we have to do this?  */
++/* Store the LR in the LR Save area.  */
+ 	la	r8,FRAME_SIZE(r1)
+ 	std	r5,FRAME_SIZE+FRAME_LR_SAVE(r1)
+ 	cfi_offset (lr, FRAME_LR_SAVE)
+ 	std	r5,CALLING_LR(r1)
+-	mfcr	r0
+ 	std	r9,INT_PARMS+48(r1)
+ 	std	r10,INT_PARMS+56(r1)
+ 	std	r8,CALLING_SP(r1)
+-/* I'm almost certain we don't have to save cr...  be safe.  */
+-	std	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	ld	r12,.LC__dl_hwcap@toc(r2)
+ #ifdef SHARED
+ 	/* Load _rtld_local_ro._dl_hwcap.  */
+@@ -319,11 +327,9 @@
+ 	ld	r8,INT_PARMS+40(r1)
+ 	ld	r7,INT_PARMS+32(r1)
+ 	mtlr	r0
+-	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	ld	r6,INT_PARMS+24(r1)
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+-	mtcrf	0xFF,r0
+ /* Prepare for calling the function returned by fixup.  */
+ 	PPC64_LOAD_FUNCPTR r3
+ 	ld	r3,INT_PARMS+0(r1)
+@@ -346,10 +352,11 @@
+ 	lfd	fp12,FPR_PARMS+88(r1)
+ 	lfd	fp13,FPR_PARMS+96(r1)
+ /* Unwind the stack frame, and jump.  */
+-	ld	r31,584(r1)
+-	ld	r30,576(r1)
++	ld	r31,FRAME_SIZE-8(r1)
++	ld	r30,FRAME_SIZE-16(r1)
+ 	addi	r1,r1,FRAME_SIZE
+ 	bctr
++
+ L(do_pltexit):
+ 	la	r10,(VR_PARMS+0)(r1)
+ 	la	r9,(VR_PARMS+16)(r1)
+@@ -383,11 +390,9 @@
+ 	ld	r8,INT_PARMS+40(r1)
+ 	ld	r7,INT_PARMS+32(r1)
+ 	mtlr	r0
+-	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
+ 	ld	r6,INT_PARMS+24(r1)
+ 	ld	r5,INT_PARMS+16(r1)
+ 	ld	r4,INT_PARMS+8(r1)
+-	mtcrf	0xFF,r0
+ /* Prepare for calling the function returned by fixup.  */
+ 	std	r2,FRAME_TOC_SAVE(r1)
+ 	PPC64_LOAD_FUNCPTR r3
+@@ -413,16 +418,37 @@
+ /* But return here and store the return values.  */
+ 	std	r3,INT_RTN(r1)
+ 	std	r4,INT_RTN+8(r1)
+-	stfd	fp1,FPR_PARMS+0(r1)
+-	stfd	fp2,FPR_PARMS+8(r1)
++	stfd	fp1,FPR_RTN+0(r1)
++	stfd	fp2,FPR_RTN+8(r1)
+ 	cmpdi	cr0,r12,0
+ 	la	r10,VR_RTN(r1)
+-	stfd	fp3,FPR_PARMS+16(r1)
+-	stfd	fp4,FPR_PARMS+24(r1)
++	stfd	fp3,FPR_RTN+16(r1)
++	stfd	fp4,FPR_RTN+24(r1)
++#if _CALL_ELF == 2
++	la	r12,VR_RTN+16(r1)
++	stfd	fp5,FPR_RTN+32(r1)
++	stfd	fp6,FPR_RTN+40(r1)
++	li	r5,32
++	li	r6,64
++	stfd	fp7,FPR_RTN+48(r1)
++	stfd	fp8,FPR_RTN+56(r1)
++	stfd	fp9,FPR_RTN+64(r1)
++	stfd	fp10,FPR_RTN+72(r1)
++#endif
+ 	mr	r3,r31
+ 	mr	r4,r30
+ 	beq	L(callpltexit)
+ 	stvx	v2,0,r10
++#if _CALL_ELF == 2
++	stvx	v3,0,r12
++	stvx	v4,r5,r10
++	stvx	v5,r5,r12
++	addi	r5,r5,64
++	stvx	v6,r6,r10
++	stvx	v7,r6,r12
++	stvx	v8,r5,r10
++	stvx	v9,r5,r12
++#endif
+ L(callpltexit):
+ 	addi	r5,r1,INT_PARMS
+ 	addi	r6,r1,INT_RTN
+@@ -434,18 +460,39 @@
+ 	lwz	r12,VR_VRSAVE(r1)
+ 	ld	r3,INT_RTN(r1)
+ 	ld	r4,INT_RTN+8(r1)
+-	lfd	fp1,FPR_PARMS+0(r1)
+-	lfd	fp2,FPR_PARMS+8(r1)
++	lfd	fp1,FPR_RTN+0(r1)
++	lfd	fp2,FPR_RTN+8(r1)
+ 	cmpdi	cr0,r12,0
+-	la	r10,VR_RTN(r1)
+-	lfd	fp3,FPR_PARMS+16(r1)
+-	lfd	fp4,FPR_PARMS+24(r1)
++	la	r11,VR_RTN(r1)
++	lfd	fp3,FPR_RTN+16(r1)
++	lfd	fp4,FPR_RTN+24(r1)
++#if _CALL_ELF == 2
++	la	r12,VR_RTN+16(r1)
++	lfd	fp5,FPR_RTN+32(r1)
++	lfd	fp6,FPR_RTN+40(r1)
++	li	r30,32
++	li	r31,64
++	lfd	fp7,FPR_RTN+48(r1)
++	lfd	fp8,FPR_RTN+56(r1)
++	lfd	fp9,FPR_RTN+64(r1)
++	lfd	fp10,FPR_RTN+72(r1)
++#endif
+ 	beq	L(pltexitreturn)
+-	lvx	v2,0,r10
++	lvx	v2,0,r11
++#if _CALL_ELF == 2
++	lvx	v3,0,r12
++	lvx	v4,r30,r11
++	lvx	v5,r30,r12
++	addi	r30,r30,64
++	lvx	v6,r31,r11
++	lvx	v7,r31,r12
++	lvx	v8,r30,r11
++	lvx	v9,r30,r12
++#endif
+ L(pltexitreturn):
+ 	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
+-	ld	r31,584(r1)
+-	ld	r30,576(r1)
++	ld	r31,FRAME_SIZE-8(r1)
++	ld	r30,FRAME_SIZE-16(r1)
+ 	mtlr	r0
+ 	ld	r1,0(r1)
+ 	blr
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/tst-audit.h glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/tst-audit.h
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/tst-audit.h	2014-05-29 14:11:12.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/tst-audit.h	2014-05-29 14:11:20.000000000 -0500
+@@ -18,8 +18,16 @@
+    License along with the GNU C Library.  If not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#if _CALL_ELF != 2
+ #define pltenter la_ppc64_gnu_pltenter
+ #define pltexit la_ppc64_gnu_pltexit
+ #define La_regs La_ppc64_regs
+ #define La_retval La_ppc64_retval
+ #define int_retval lrv_r3
++#else
++#define pltenter la_ppc64v2_gnu_pltenter
++#define pltexit la_ppc64v2_gnu_pltexit
++#define La_regs La_ppc64v2_regs
++#define La_retval La_ppc64v2_retval
++#define int_retval lrv_r3
++#endif
diff --git a/SOURCES/glibc-ppc64le-43.patch b/SOURCES/glibc-ppc64le-43.patch
new file mode 100644
index 0000000..1df936f
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-43.patch
@@ -0,0 +1,248 @@
+# commit 5b118558f9fb0620508d51c34c2cb5ba4f1f01c2
+# Author: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+# Date:   Wed Dec 4 07:08:48 2013 -0600
+# 
+#     PowerPC64 ELFv2 ABI 6/6: Bump ld.so soname version number
+#     
+#     To avoid having a ELFv2 binary accidentally picking up an old ABI ld.so,
+#     this patch bumps the soname to ld64.so.2.
+#     
+#     In theory (or for testing purposes) this will also allow co-installing
+#     ld.so versions for both ABIs on the same system.  Note that the kernel
+#     will already be able to load executables of both ABIs.  However, there
+#     is currently no plan to use that theoretical possibility in a any
+#     supported distribution environment ...
+#     
+#     Note that in order to check which ABI to use, we need to invoke the
+#     compiler to check the _CALL_ELF macro; this is done in a new configure
+#     check in sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac,
+#     replacing the hard-coded value of default-abi in the Makefile.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/Makefile glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/Makefile
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/Makefile	2014-05-29 14:12:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/Makefile	2014-05-29 14:12:30.000000000 -0500
+@@ -1,9 +1,12 @@
+-abi-variants := 32 64
++abi-variants := 32 64-v1 64-v2
+ abi-32-options := -U__powerpc64__
+ abi-32-condition := __WORDSIZE == 32
+-abi-64-options := -D__powerpc64__
+-abi-64-condition := __WORDSIZE == 64
+-abi-64-ld-soname := ld64.so.1
++abi-64-v1-options := -D__powerpc64__ -U_CALL_ELF -D_CALL_ELF=1
++abi-64-v1-condition := __WORDSIZE == 64 && _CALL_ELF != 2
++abi-64-v1-ld-soname := ld64.so.1
++abi-64-v2-options := -D__powerpc64__ -U_CALL_ELF -D_CALL_ELF=2
++abi-64-v2-condition := __WORDSIZE == 64 && _CALL_ELF == 2
++abi-64-v2-ld-soname := ld64.so.2
+ 
+ ifeq ($(subdir),rt)
+ librt-routines += rt-sysdep
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/ldconfig.h glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/ldconfig.h
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/ldconfig.h	2014-05-29 14:12:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/ldconfig.h	2014-05-29 14:12:30.000000000 -0500
+@@ -20,7 +20,8 @@
+ 
+ #define SYSDEP_KNOWN_INTERPRETER_NAMES \
+   { "/lib/ld.so.1", FLAG_ELF_LIBC6 },	\
+-  { "/lib64/ld64.so.1", FLAG_ELF_LIBC6 },
++  { "/lib64/ld64.so.1", FLAG_ELF_LIBC6 }, \
++  { "/lib64/ld64.so.2", FLAG_ELF_LIBC6 },
+ #define SYSDEP_KNOWN_LIBRARY_NAMES \
+   { "libc.so.6", FLAG_ELF_LIBC6 },	\
+   { "libm.so.6", FLAG_ELF_LIBC6 },
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile	2014-05-29 14:12:25.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile	1969-12-31 18:00:00.000000000 -0600
+@@ -1,2 +0,0 @@
+-# See Makeconfig regarding the use of default-abi.
+-default-abi := 64
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure	2014-05-29 14:12:30.000000000 -0500
+@@ -0,0 +1,166 @@
++# This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
++ # Local configure fragment for sysdeps/unix/sysv/linux/powerpc/powerpc64/.
++
++# Define default-abi according to compiler flags.
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
++$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
++if ${ac_cv_path_GREP+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -z "$GREP"; then
++  ac_path_GREP_found=false
++  # Loop through the user's path and test for each of PROGNAME-LIST
++  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_prog in grep ggrep; do
++    for ac_exec_ext in '' $ac_executable_extensions; do
++      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
++      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
++# Check for GNU ac_path_GREP and select it if it is found.
++  # Check for GNU $ac_path_GREP
++case `"$ac_path_GREP" --version 2>&1` in
++*GNU*)
++  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
++*)
++  ac_count=0
++  $as_echo_n 0123456789 >"conftest.in"
++  while :
++  do
++    cat "conftest.in" "conftest.in" >"conftest.tmp"
++    mv "conftest.tmp" "conftest.in"
++    cp "conftest.in" "conftest.nl"
++    $as_echo 'GREP' >> "conftest.nl"
++    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
++    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
++    as_fn_arith $ac_count + 1 && ac_count=$as_val
++    if test $ac_count -gt ${ac_path_GREP_max-0}; then
++      # Best one so far, save it but keep looking for a better one
++      ac_cv_path_GREP="$ac_path_GREP"
++      ac_path_GREP_max=$ac_count
++    fi
++    # 10*(2^10) chars as input seems more than enough
++    test $ac_count -gt 10 && break
++  done
++  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
++esac
++
++      $ac_path_GREP_found && break 3
++    done
++  done
++  done
++IFS=$as_save_IFS
++  if test -z "$ac_cv_path_GREP"; then
++    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
++  fi
++else
++  ac_cv_path_GREP=$GREP
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
++$as_echo "$ac_cv_path_GREP" >&6; }
++ GREP="$ac_cv_path_GREP"
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
++$as_echo_n "checking for egrep... " >&6; }
++if ${ac_cv_path_EGREP+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
++   then ac_cv_path_EGREP="$GREP -E"
++   else
++     if test -z "$EGREP"; then
++  ac_path_EGREP_found=false
++  # Loop through the user's path and test for each of PROGNAME-LIST
++  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_prog in egrep; do
++    for ac_exec_ext in '' $ac_executable_extensions; do
++      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
++      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
++# Check for GNU ac_path_EGREP and select it if it is found.
++  # Check for GNU $ac_path_EGREP
++case `"$ac_path_EGREP" --version 2>&1` in
++*GNU*)
++  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
++*)
++  ac_count=0
++  $as_echo_n 0123456789 >"conftest.in"
++  while :
++  do
++    cat "conftest.in" "conftest.in" >"conftest.tmp"
++    mv "conftest.tmp" "conftest.in"
++    cp "conftest.in" "conftest.nl"
++    $as_echo 'EGREP' >> "conftest.nl"
++    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
++    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
++    as_fn_arith $ac_count + 1 && ac_count=$as_val
++    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
++      # Best one so far, save it but keep looking for a better one
++      ac_cv_path_EGREP="$ac_path_EGREP"
++      ac_path_EGREP_max=$ac_count
++    fi
++    # 10*(2^10) chars as input seems more than enough
++    test $ac_count -gt 10 && break
++  done
++  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
++esac
++
++      $ac_path_EGREP_found && break 3
++    done
++  done
++  done
++IFS=$as_save_IFS
++  if test -z "$ac_cv_path_EGREP"; then
++    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
++  fi
++else
++  ac_cv_path_EGREP=$EGREP
++fi
++
++   fi
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
++$as_echo "$ac_cv_path_EGREP" >&6; }
++ EGREP="$ac_cv_path_EGREP"
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the PowerPC64 ELFv2 ABI" >&5
++$as_echo_n "checking whether the compiler is using the PowerPC64 ELFv2 ABI... " >&6; }
++if ${libc_cv_ppc64_elfv2_abi+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#if _CALL_ELF == 2
++                      yes
++                     #endif
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "yes" >/dev/null 2>&1; then :
++  libc_cv_ppc64_elfv2_abi=yes
++else
++  libc_cv_ppc64_elfv2_abi=no
++fi
++rm -f conftest*
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ppc64_elfv2_abi" >&5
++$as_echo "$libc_cv_ppc64_elfv2_abi" >&6; }
++if test $libc_cv_ppc64_elfv2_abi = yes; then
++  config_vars="$config_vars
++default-abi = 64-v2"
++else
++  config_vars="$config_vars
++default-abi = 64-v1"
++fi
+diff -urN glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac
+--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.17-c758a686.diff/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac	2014-05-29 14:12:30.000000000 -0500
+@@ -0,0 +1,15 @@
++GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
++# Local configure fragment for sysdeps/unix/sysv/linux/powerpc/powerpc64/.
++
++# Define default-abi according to compiler flags.
++AC_CACHE_CHECK([whether the compiler is using the PowerPC64 ELFv2 ABI],
++  [libc_cv_ppc64_elfv2_abi],
++  [AC_EGREP_CPP(yes,[#if _CALL_ELF == 2
++                      yes
++                     #endif
++  ], libc_cv_ppc64_elfv2_abi=yes, libc_cv_ppc64_elfv2_abi=no)])
++if test $libc_cv_ppc64_elfv2_abi = yes; then
++  LIBC_CONFIG_VAR([default-abi], [64-v2])
++else
++  LIBC_CONFIG_VAR([default-abi], [64-v1])
++fi
diff --git a/SOURCES/glibc-ppc64le-44.patch b/SOURCES/glibc-ppc64le-44.patch
new file mode 100644
index 0000000..70f31e6
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-44.patch
@@ -0,0 +1,26 @@
+# commit c859b32e9d76afe8a3f20bb9528961a573c06937
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Tue Apr 1 14:07:42 2014 +1030
+# 
+#     Fix s_copysign stack temp for PowerPC64 ELFv2
+# 
+#         [BZ #16786]
+#         * sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Don't trash stack.
+# 
+diff -urN glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_copysign.S glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
+--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_copysign.S	2014-05-29 14:13:47.000000000 -0500
++++ glibc-2.17-c758a686.diff/sysdeps/powerpc/powerpc64/fpu/s_copysign.S	2014-05-29 14:13:50.000000000 -0500
+@@ -27,11 +27,11 @@
+ /* double [f1] copysign (double [f1] x, double [f2] y);
+    copysign(x,y) returns a value with the magnitude of x and
+    with the sign bit of y.  */
+-	stfd	fp2,56(r1)
++	stfd	fp2,-8(r1)
+ 	nop
+ 	nop
+ 	nop
+-	ld	r3,56(r1)
++	ld	r3,-8(r1)
+ 	cmpdi   r3,0
+ 	blt     L(0)
+ 	fabs    fp1,fp1
diff --git a/SOURCES/glibc-ppc64le-45.patch b/SOURCES/glibc-ppc64le-45.patch
new file mode 100644
index 0000000..e531534
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-45.patch
@@ -0,0 +1,33 @@
+#
+# For PPC64LE only!
+#
+# This is fixed upstream by the removal of Versions.def
+# and auto-generation of the SHLIB_COMPAT required entries.
+# See: https://sourceware.org/ml/libc-alpha/2014-02/msg00818.html
+# Backporting that infrastructure to RHEL 7.x is too much work
+# at this junction for little reward. Instead we simply fix up
+# the Versions.def to include GLIBC_2.3 which is used by
+# nptl/old_pthread_atfork.c, otherwise ppc64le will get
+# pthread_atfork in libpthread.so.0 when it should not.
+#
+# The ABI testing for libpthread.so now passes for ppc64le.
+#
+diff -urN glibc-2.17-c758a686.orig/Versions.def glibc-2.17-c758a686.new/Versions.def
+--- glibc-2.17-c758a686.orig/Versions.def	2014-06-02 21:13:12.000000000 +0000
++++ glibc-2.17-c758a686.new/Versions.def	2014-06-02 21:14:38.000000000 +0000
+@@ -92,6 +92,7 @@
+   GLIBC_2.2
+   GLIBC_2.2.3
+   GLIBC_2.2.6
++  GLIBC_2.3
+   GLIBC_2.3.2
+   GLIBC_2.3.3
+   GLIBC_2.3.4
+@@ -99,6 +100,7 @@
+   GLIBC_2.6
+   GLIBC_2.11
+   GLIBC_2.12
++  GLIBC_2.17
+   GLIBC_PRIVATE
+ }
+ libresolv {
diff --git a/SOURCES/glibc-ppc64le-46.patch b/SOURCES/glibc-ppc64le-46.patch
new file mode 100644
index 0000000..41f7457
--- /dev/null
+++ b/SOURCES/glibc-ppc64le-46.patch
@@ -0,0 +1,22 @@
+#
+# On POWER this patch also fixes test-ildoubl and test-ldouble failures where tan
+# rounded toward zero had acceptable 1 ULP error. Upstream is using 3 ULP, but
+# we prefer to keep the bound tighter unless we have a reason not to.
+#
+# This is the ppc64le version which is required becuase it applies *after* another
+# ppc64le patch that touches the same ULPs file. See glibc-power-libm-test-ulps.patch
+# for the ppc64/ppc version.
+#
+diff -urN glibc-2.17-c758a686.next/sysdeps/powerpc/fpu/libm-test-ulps glibc-2.17-c758a686.new/sysdeps/powerpc/fpu/libm-test-ulps
+--- glibc-2.17-c758a686.next/sysdeps/powerpc/fpu/libm-test-ulps	2014-07-25 22:07:06.280020855 -0400
++++ glibc-2.17-c758a686.new/sysdeps/powerpc/fpu/libm-test-ulps	2014-07-25 22:26:54.650021033 -0400
+@@ -2644,6 +2644,9 @@
+ Test "tan_towardzero (2)":
+ ildouble: 1
+ ldouble: 1
++Test "tan_towardzero (2) == -2.1850398632615189916433061023136825434320":
++ildouble: 1
++ldouble: 1
+ Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261":
+ float: 1
+ ifloat: 1
diff --git a/SOURCES/glibc-rh1028652.patch b/SOURCES/glibc-rh1028652.patch
index 4c642a9..5b484da 100644
--- a/SOURCES/glibc-rh1028652.patch
+++ b/SOURCES/glibc-rh1028652.patch
@@ -2,6 +2,38 @@
 # Upstream power patch to increase MINSIGSTKSZ and SIGSTKSZ to
 # account for the kernel signal frame size increase.
 #
+# commit f7c399cff5bd04ee9dc117fb6b0f39597dc047c6
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Sat Aug 17 18:37:18 2013 +0930
+# 
+#     PowerPC SIGSTKSZ
+#     http://sourceware.org/ml/libc-alpha/2013-08/msg00093.html
+#     
+#     This copies the sparc version of sigstack.h, which gives powerpc
+#      #define MINSIGSTKSZ     4096
+#      #define SIGSTKSZ        16384
+#     
+#     Before the VSX changes, struct rt_sigframe size was 1920 plus 128 for
+#     __SIGNAL_FRAMESIZE giving ppc64 exactly the default MINSIGSTKSZ of
+#     2048.
+#     
+#     After VSX, ucontext increased by 256 bytes.  Oops, we're over
+#     MINSIGSTKSZ, so powerpc has been using the wrong value for quite a
+#     while.  Add another ucontext for TM and rt_sigframe is now at 3872,
+#     giving actual MINSIGSTKSZ of 4000.
+#     
+#     The glibc testcase that I was looking at was tst-cancel21, which
+#     allocates 2*SIGSTKSZ (not because the test is trying to be
+#     conservative, but because the test actually has nested signal stack
+#     frames).  We blew the allocation by 48 bytes when using current
+#     mainline gcc to compile glibc (le ppc64).
+#     
+#     The required stack depth in _dl_lookup_symbol_x from the top of the
+#     next signal frame was 10944 bytes.  I guess you'd want to add 288 to
+#     that, implying an actual SIGSTKSZ of 11232.
+#     
+#         * sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h: New file.
+# 
 diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h b/sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h
 new file mode 100644
 index 0000000..33be9e8
diff --git a/SOURCES/glibc-rh1067755.patch b/SOURCES/glibc-rh1067755.patch
new file mode 100644
index 0000000..ac0e93f
--- /dev/null
+++ b/SOURCES/glibc-rh1067755.patch
@@ -0,0 +1,123 @@
+diff --git a/elf/tst-stackguard1.c b/elf/tst-stackguard1.c
+index 2b4fd9a..fba60bd 100644
+--- a/elf/tst-stackguard1.c
++++ b/elf/tst-stackguard1.c
+@@ -23,6 +23,7 @@
+ #include <string.h>
+ #include <sys/wait.h>
+ #include <stackguard-macros.h>
++#include <tls.h>
+ #include <unistd.h>
+ 
+ static const char *command;
+diff --git a/include/errno.h b/include/errno.h
+index 98c6080..f1b93a8 100644
+--- a/include/errno.h
++++ b/include/errno.h
+@@ -17,7 +17,7 @@
+ #  define errno rtld_errno
+ extern int rtld_errno attribute_hidden;
+ 
+-# else
++# elif !defined NOT_IN_libc || defined IN_LIB
+ 
+ #  include <tls.h>
+ 
+@@ -29,7 +29,7 @@ extern int rtld_errno attribute_hidden;
+ #  endif
+ extern __thread int errno attribute_tls_model_ie;
+ 
+-# endif	/* RTLD_PRIVATE_ERRNO */
++# endif	/* !NOT_IN_libc || IN_LIB */
+ 
+ # define __set_errno(val) (errno = (val))
+ 
+diff --git a/include/netdb.h b/include/netdb.h
+index 3f2ae06..8a569ba 100644
+--- a/include/netdb.h
++++ b/include/netdb.h
+@@ -3,18 +3,20 @@
+ 
+ #ifndef _ISOMAC
+ /* Macros for accessing h_errno from inside libc.  */
+-# undef  h_errno
+-# ifdef _LIBC_REENTRANT
+-#  include <tls.h>
+-#  ifndef NOT_IN_libc
+-#   define h_errno __libc_h_errno
+-#  else
+-#   define h_errno h_errno	/* For #ifndef h_errno tests.  */
+-#  endif
++# if !defined NOT_IN_libc || defined IN_LIB
++#  undef  h_errno
++#  ifdef _LIBC_REENTRANT
++#   include <tls.h>
++#   ifndef NOT_IN_libc
++#    define h_errno __libc_h_errno
++#   else
++#    define h_errno h_errno	/* For #ifndef h_errno tests.  */
++#   endif
+ extern __thread int h_errno attribute_tls_model_ie;
+-# else
++#  else
+ extern int h_errno;
+-# endif	/* _LIBC_REENTRANT */
++#  endif	/* _LIBC_REENTRANT */
++# endif /* !NOT_IN_libc || IN_LIB */
+ # define __set_h_errno(x) (h_errno = (x))
+ 
+ libc_hidden_proto (hstrerror)
+diff --git a/nptl/tst-cancel14.c b/nptl/tst-cancel14.c
+index fbaed49..ca9042d 100644
+--- a/nptl/tst-cancel14.c
++++ b/nptl/tst-cancel14.c
+@@ -23,6 +23,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <sys/time.h>
+ 
+ 
+ static pthread_barrier_t bar;
+diff --git a/nptl/tst-cancel15.c b/nptl/tst-cancel15.c
+index 0119cc7..3f320ad 100644
+--- a/nptl/tst-cancel15.c
++++ b/nptl/tst-cancel15.c
+@@ -23,6 +23,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <sys/time.h>
+ 
+ 
+ static pthread_barrier_t bar;
+diff --git a/nptl/tst-mutex9.c b/nptl/tst-mutex9.c
+index adb3b61..1d689bd 100644
+--- a/nptl/tst-mutex9.c
++++ b/nptl/tst-mutex9.c
+@@ -18,10 +18,13 @@
+ 
+ #include <errno.h>
+ #include <pthread.h>
++#include <stdint.h>
+ #include <stdio.h>
++#include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/mman.h>
++#include <sys/time.h>
+ #include <sys/wait.h>
+ 
+ 
+diff --git a/nptl/tst-stackguard1.c b/nptl/tst-stackguard1.c
+index f0f707f..57a48ad 100644
+--- a/nptl/tst-stackguard1.c
++++ b/nptl/tst-stackguard1.c
+@@ -24,6 +24,7 @@
+ #include <string.h>
+ #include <sys/wait.h>
+ #include <stackguard-macros.h>
++#include <tls.h>
+ #include <unistd.h>
+ 
+ static const char *command;
diff --git a/SOURCES/glibc-rh1070458.patch b/SOURCES/glibc-rh1070458.patch
new file mode 100644
index 0000000..7842271
--- /dev/null
+++ b/SOURCES/glibc-rh1070458.patch
@@ -0,0 +1,124 @@
+Backport of commit f8b4877a75765b14432a6f83ead11dcecc5b1985
+Author: Marcus Shawcroft <marcus.shawcroft@linaro.org>
+Date:   Fri Jul 26 08:29:17 2013 +0100
+
+    [AArch64] Provide symbol version for _mcount.
+
+2013-07-26  Marcus Shawcroft  <marcus.shawcroft@linaro.org>
+
+       * sysdeps/aarch64/Versions: New file.
+       * sysdeps/aarch64/machine-gmon.h: New file.
+       * sysdeps/aarch64/mcount.c: New file.
+       * sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist (_mcount): Add.
+
+
+
+diff -ruNp a/ports/sysdeps/aarch64/machine-gmon.h b/ports/sysdeps/aarch64/machine-gmon.h
+--- a/ports/sysdeps/aarch64/machine-gmon.h	2012-12-24 22:02:13.000000000 -0500
++++ b/ports/sysdeps/aarch64/machine-gmon.h	2014-03-27 12:06:51.361046886 -0400
+@@ -1,5 +1,5 @@
+-/* Copyright (C) 2011-2012 Free Software Foundation, Inc.
+-
++/* AArch64 definitions for profiling support.
++   Copyright (C) 1996-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
+@@ -13,13 +13,22 @@
+    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
++   License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#define _MCOUNT_DECL(from, self) \
+- void __mcount_internal (u_long from, u_long self)
+-
+-/* Call __mcount_internal with our the return PC for our caller, and
+-   the return PC our caller will return to.  Empty since we use an
+-   assembly stub instead. */
+-#define MCOUNT
++/* Accept 'frompc' address as argument from the function that calls
++   __mcount for profiling.  Use  __builtin_return_address (0)
++   for the 'selfpc' address.  */
++
++#include <sysdep.h>
++
++static void mcount_internal (u_long frompc, u_long selfpc);
++
++#define _MCOUNT_DECL(frompc, selfpc) \
++static inline void mcount_internal (u_long frompc, u_long selfpc)
++
++#define MCOUNT                                                    \
++void __mcount (void *frompc)                                      \
++{                                                                 \
++  mcount_internal ((u_long) frompc, (u_long) RETURN_ADDRESS (0)); \
++}
+diff -ruNp a/ports/sysdeps/aarch64/mcount.c b/ports/sysdeps/aarch64/mcount.c
+--- a/ports/sysdeps/aarch64/mcount.c	1969-12-31 19:00:00.000000000 -0500
++++ b/ports/sysdeps/aarch64/mcount.c	2014-03-27 11:54:54.435418262 -0400
+@@ -0,0 +1,33 @@
++/* 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 <shlib-compat.h>
++
++#include <gmon/mcount.c>
++
++/* We forgot to add _mcount in glibc 2.17.  We added it in 2.18
++   therefore we want it to be added with version GLIBC_2_18.  However,
++   setting the version is not straight forward because a generic
++   Version file includes an earlier 2.xx version for each this symbol
++   and the linker uses the first version it sees.  */
++
++#if SHLIB_COMPAT (libc, GLIBC_2_17, GLIBC_2_18)
++versioned_symbol (libc, __mcount, _mcount, GLIBC_2_18);
++#else
++strong_alias (__mcount, _mcount);
++#endif
+diff -ruNp a/ports/sysdeps/aarch64/Versions b/ports/sysdeps/aarch64/Versions
+--- a/ports/sysdeps/aarch64/Versions	1969-12-31 19:00:00.000000000 -0500
++++ b/ports/sysdeps/aarch64/Versions	2014-03-27 11:54:54.435418262 -0400
+@@ -0,0 +1,5 @@
++libc {
++  GLIBC_2.18 {
++    _mcount;
++  }
++}
+diff -ruNp a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist
+--- a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist	2012-12-24 22:02:13.000000000 -0500
++++ b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist	2014-03-27 11:54:54.495412015 -0400
+@@ -2077,3 +2077,6 @@ GLIBC_2.17
+  xencrypt F
+  xprt_register F
+  xprt_unregister F
++GLIBC_2.18
++ GLIBC_2.18 A
++ _mcount F
+diff -ruNp a/Versions.def b/Versions.def
+--- a/Versions.def	2012-12-24 22:02:13.000000000 -0500
++++ b/Versions.def	2014-03-27 11:54:54.535407851 -0400
+@@ -34,6 +34,7 @@ libc {
+   GLIBC_2.15
+   GLIBC_2.16
+   GLIBC_2.17
++  GLIBC_2.18
+   HURD_CTHREADS_0.3
+ %ifdef EXPORT_UNWIND_FIND_FDE
+   GCC_3.0
diff --git a/SOURCES/glibc-rh1070471.patch b/SOURCES/glibc-rh1070471.patch
new file mode 100644
index 0000000..cd3f329
--- /dev/null
+++ b/SOURCES/glibc-rh1070471.patch
@@ -0,0 +1,53 @@
+Backport of commit 052aff95782fefe9c63566471063e8b20836bfb8
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Wed Jan 23 00:42:51 2013 +0000
+
+    Make bits/wchar.h correct for all architectures (bug 15036).
+
+2013-01-23  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #15036]
+	* bits/wchar.h (__WCHAR_MAX): Define based on __WCHAR_MAX__, or
+	based on [L'\0' - 1 > 0] if [!__WCHAR_MAX__].
+	(__WCHAR_MIN): Likewise, using __WCHAR_MIN__.
+	* sysdeps/unix/sysv/linux/x86/bits/wchar.h: Remove.
+
+
+
+diff -ruNp a/bits/wchar.h b/bits/wchar.h
+--- a/bits/wchar.h	2012-12-24 22:02:13.000000000 -0500
++++ b/bits/wchar.h	2014-03-27 14:53:45.940914030 -0400
+@@ -19,7 +19,31 @@
+ #ifndef _BITS_WCHAR_H
+ #define _BITS_WCHAR_H	1
+ 
+-#define __WCHAR_MIN	(-2147483647 - 1)
+-#define __WCHAR_MAX	(2147483647)
++/* The fallback definitions, for when __WCHAR_MAX__ or __WCHAR_MIN__
++   are not defined, give the right value and type as long as both int
++   and wchar_t are 32-bit types.  Adding L'\0' to a constant value
++   ensures that the type is correct; it is necessary to use (L'\0' +
++   0) rather than just L'\0' so that the type in C++ is the promoted
++   version of wchar_t rather than the distinct wchar_t type itself.
++   Because wchar_t in preprocessor #if expressions is treated as
++   intmax_t or uintmax_t, the expression (L'\0' - 1) would have the
++   wrong value for WCHAR_MAX in such expressions and so cannot be used
++   to define __WCHAR_MAX in the unsigned case.  */
++
++#ifdef __WCHAR_MAX__
++# define __WCHAR_MAX	__WCHAR_MAX__
++#elif L'\0' - 1 > 0
++# define __WCHAR_MAX	(0xffffffffu + L'\0')
++#else
++# define __WCHAR_MAX	(0x7fffffff + L'\0')
++#endif
++
++#ifdef __WCHAR_MIN__
++# define __WCHAR_MIN	__WCHAR_MIN__
++#elif L'\0' - 1 > 0
++# define __WCHAR_MIN	(L'\0' + 0)
++#else
++# define __WCHAR_MIN	(-__WCHAR_MAX - 1)
++#endif
+ 
+ #endif	/* bits/wchar.h */
diff --git a/SOURCES/glibc-rh1073667.patch b/SOURCES/glibc-rh1073667.patch
new file mode 100644
index 0000000..fec4dcd
--- /dev/null
+++ b/SOURCES/glibc-rh1073667.patch
@@ -0,0 +1,91 @@
+commit e39adf43c7d1979884dd304ed1250baf1f78fadc
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Mon May 20 10:19:31 2013 +0200
+
+    AArch64: Don't clobber argument for tail call to __sigjmp_save in sigsetjmp
+
+diff --git a/ports/sysdeps/aarch64/setjmp.S b/ports/sysdeps/aarch64/setjmp.S
+index cff81c7..10e0709 100644
+--- a/ports/sysdeps/aarch64/setjmp.S
++++ b/ports/sysdeps/aarch64/setjmp.S
+@@ -44,8 +44,14 @@ ENTRY (__sigsetjmp)
+ 	stp	d10, d11, [x0, #JB_D10<<3]
+ 	stp	d12, d13, [x0, #JB_D12<<3]
+ 	stp	d14, d15, [x0, #JB_D14<<3]
+-	mov	x1,  sp
+-	str	x1,  [x0, #JB_SP<<3]
++	mov	x2,  sp
++	str	x2,  [x0, #JB_SP<<3]
++#if defined NOT_IN_libc && defined IS_IN_rtld
++	/* In ld.so we never save the signal mask */
++	mov	w0, #0
++	RET
++#else
+ 	b	C_SYMBOL_NAME(__sigjmp_save)
++#endif
+ END (__sigsetjmp)
+ hidden_def (__sigsetjmp)
+diff --git a/setjmp/Makefile b/setjmp/Makefile
+index 6124333..913359c 100644
+--- a/setjmp/Makefile
++++ b/setjmp/Makefile
+@@ -25,7 +25,8 @@ headers	:= setjmp.h bits/setjmp.h bits/setjmp2.h
+ routines	:= setjmp sigjmp bsd-setjmp bsd-_setjmp \
+ 		   longjmp __longjmp jmp-unwind
+ 
+-tests		:= tst-setjmp jmpbug bug269-setjmp
++tests		:= tst-setjmp jmpbug bug269-setjmp \
++		   tst-sigsetjmp
+ 
+ 
+ include ../Rules
+diff --git a/setjmp/tst-sigsetjmp.c b/setjmp/tst-sigsetjmp.c
+new file mode 100644
+index 0000000..467c26a
+--- /dev/null
++++ b/setjmp/tst-sigsetjmp.c
+@@ -0,0 +1,44 @@
++/* 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/>.  */
++
++/* Test case for BZ #15493 */
++
++#include <stdlib.h>
++#include <signal.h>
++#include <setjmp.h>
++
++static int
++do_test (void)
++{
++  sigjmp_buf sj;
++  sigset_t m;
++
++  sigemptyset (&m);
++  sigprocmask (SIG_SETMASK, &m, NULL);
++  if (sigsetjmp (sj, 0) == 0)
++    {
++      sigaddset (&m, SIGUSR1);
++      sigprocmask (SIG_SETMASK, &m, NULL);
++      siglongjmp (sj, 1);
++      return EXIT_FAILURE;
++    }
++  sigprocmask (SIG_SETMASK, NULL, &m);
++  return sigismember (&m, SIGUSR1) ? EXIT_SUCCESS : EXIT_FAILURE;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
diff --git a/SOURCES/glibc-rh1077389-p1.patch b/SOURCES/glibc-rh1077389-p1.patch
new file mode 100644
index 0000000..40835b0
--- /dev/null
+++ b/SOURCES/glibc-rh1077389-p1.patch
@@ -0,0 +1,78 @@
+#
+# commit 76a9b9986141b1a7d9fd290c349d27fcee780c7a
+# Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+# Date:   Thu Nov 7 05:34:22 2013 -0600
+# 
+#     PowerPC: Fix vDSO missing ODP entries
+#    
+#     This patch fixes the vDSO symbol used directed in IFUNC resolver where
+#     they do not have an associated ODP entry leading to undefined behavior
+#     in some cases. It adds an artificial OPD static entry to such cases
+#     and set its TOC to non 0 to avoid triggering lazy resolutions.
+#
+diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
+--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h	2015-01-15 16:05:08.853681325 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h	2015-01-15 16:06:11.451747716 -0500
+@@ -34,12 +34,32 @@
+ 
+ extern void *__vdso_time;
+ 
+-/* This macro is needed for PPC64 to return a skeleton OPD entry of a vDSO
+-   symbol.  This works because _dl_vdso_vsym always return the function
+-   address, and no vDSO symbols use the TOC or chain pointers from the OPD
+-   so we can allow them to be garbage.  */
+-#if defined(__PPC64__) || defined(__powerpc64__)
+-#define VDSO_IFUNC_RET(value)  ((void *) &(value))
++/* The correct solution is for _dl_vdso_vsym to return the address of the OPD
++   for the kernel VDSO function.  That address would then be stored in the
++   __vdso_* variables and returned as the result of the IFUNC resolver function.
++   Yet, the kernel does not contain any OPD entries for the VDSO functions
++   (incomplete implementation).  However, PLT relocations for IFUNCs still expect
++   the address of an OPD to be returned from the IFUNC resolver function (since
++   PLT entries on PPC64 are just copies of OPDs).  The solution for now is to
++   create an artificial static OPD for each VDSO function returned by a resolver
++   function.  The TOC value is set to a non-zero value to avoid triggering lazy
++   symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT
++   sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW.  None
++   of the kernel VDSO routines use the TOC or AUX values so any non-zero value
++   will work.  Note that function pointer comparisons will not use this artificial
++   static OPD since those are resolved via ADDR64 relocations and will point at
++   the non-IFUNC default OPD for the symbol.  Lastly, because the IFUNC relocations
++   are processed immediately at startup the resolver functions and this code need
++   not be thread-safe, but if the caller writes to a PLT slot it must do so in a
++   thread-safe manner with all the required barriers.  */
++#if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2
++#define VDSO_IFUNC_RET(value)                            \
++  ({                                                     \
++    static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \
++    vdso_opd.fd_func = (Elf64_Addr)value;                \
++    &vdso_opd;                                           \
++  })
++
+ #else
+ #define VDSO_IFUNC_RET(value)  ((void *) (value))
+ #endif
+diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c	2015-01-15 16:05:08.912679502 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c	2015-01-15 16:06:11.451747716 -0500
+@@ -21,6 +21,7 @@
+ 
+ # include <dl-vdso.h>
+ # include <bits/libc-vdso.h>
++# include <dl-machine.h>
+ 
+ void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+ 
+diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/time.c
+--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c	2015-01-15 16:05:08.912679502 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/time.c	2015-01-15 16:06:11.451747716 -0500
+@@ -20,7 +20,9 @@
+ 
+ # include <time.h>
+ # include <sysdep.h>
++# include <dl-vdso.h>
+ # include <bits/libc-vdso.h>
++# include <dl-machine.h>
+ 
+ void *time_ifunc (void) asm ("time");
+ 
diff --git a/SOURCES/glibc-rh1077389-p2.patch b/SOURCES/glibc-rh1077389-p2.patch
new file mode 100644
index 0000000..5e31595
--- /dev/null
+++ b/SOURCES/glibc-rh1077389-p2.patch
@@ -0,0 +1,53 @@
+#
+# commit d98720e07f67fbeec00f9e1347840404240d3c48
+# Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+# Date:   Mon Jan 20 12:29:51 2014 -0600
+# 
+#     PowerPC: Fix gettimeofday ifunc selection
+#     
+#     The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where
+#     __vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal
+#     version used within GLIBC) to use the system call version instead of the vDSO one.
+#     This patch changes the check if vDSO is available to get its value directly
+#     instead of rely on __vdso_gettimeofday.
+#     
+#     This patch changes it by getting the vDSO value directly.
+#     
+#     It fixes BZ#16431.
+# 
+diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c	2015-01-15 16:07:59.167420456 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c	2015-01-15 16:07:41.408969001 -0500
+@@ -34,9 +34,12 @@
+ void *
+ gettimeofday_ifunc (void)
+ {
++  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
++
+   /* If the vDSO is not available we fall back syscall.  */
+-  return (__vdso_gettimeofday ? VDSO_IFUNC_RET (__vdso_gettimeofday)
+-	  : __gettimeofday_syscall);
++  void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
++  return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
++	  : (void*)__gettimeofday_syscall);
+ }
+ asm (".type __gettimeofday, %gnu_indirect_function");
+ 
+diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/time.c
+--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c	2015-01-15 16:07:59.168420425 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/unix/sysv/linux/powerpc/time.c	2015-01-15 16:07:41.408969001 -0500
+@@ -45,9 +45,12 @@
+ void *
+ time_ifunc (void)
+ {
++  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
++
+   /* If the vDSO is not available we fall back to the syscall.  */
+-  return (__vdso_time ? VDSO_IFUNC_RET (__vdso_time)
+-	  : time_syscall);
++  void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615);
++  return (vdso_time ? VDSO_IFUNC_RET (vdso_time)
++	  : (void*)time_syscall);
+ }
+ asm (".type time, %gnu_indirect_function");
+ 
diff --git a/SOURCES/glibc-rh1078225.patch b/SOURCES/glibc-rh1078225.patch
new file mode 100644
index 0000000..f2eaa16
--- /dev/null
+++ b/SOURCES/glibc-rh1078225.patch
@@ -0,0 +1,46 @@
+From 3a3acb6afc753475675b5724f206e619d0c9590d Mon Sep 17 00:00:00 2001
+From: Tom Tromey <tromey@redhat.com>
+Date: Mon, 20 Jan 2014 12:58:03 +0000
+Subject: [PATCH] [AArch64] BZ #16169 Add CFI directives to clone.S
+
+[BZ #16169] Add CFI directives to the AArch64 clone.S implementation
+and ensure that the FP in the child is zero'd in order to comply with
+AAPCS.
+---
+ NEWS                                          |    8 ++++----
+ ports/ChangeLog.aarch64                       |    6 ++++++
+ ports/sysdeps/unix/sysv/linux/aarch64/clone.S |    7 ++++++-
+ 3 files changed, 16 insertions(+), 5 deletions(-)
+
+Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
+===================================================================
+--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
+@@ -63,6 +63,7 @@ ENTRY(__clone)
+ 	mov	x8, #SYS_ify(clone)
+ 	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
+ 	svc	0x0
++	cfi_endproc
+ 	cmp	x0, #0
+ 	beq	2f
+ 	blt	C_SYMBOL_NAME(__syscall_error)
+@@ -71,6 +72,9 @@ ENTRY(__clone)
+ 	b	syscall_error
+ 
+ 2:
++	cfi_startproc
++	cfi_undefined (x30)
++	mov	x29, 0
+ #ifdef RESET_PID
+ 	tbnz	x5, #CLONE_THREAD_BIT, 3f
+ 	mov	x0, #-1
+@@ -92,7 +96,8 @@ ENTRY(__clone)
+ 
+ 	/* We are done, pass the return value through x0.  */
+ 	b	HIDDEN_JUMPTARGET(_exit)
+-
++	cfi_endproc
++	cfi_startproc
+ PSEUDO_END (__clone)
+ 
+ weak_alias (__clone, clone)
diff --git a/SOURCES/glibc-rh1080766.patch b/SOURCES/glibc-rh1080766.patch
new file mode 100644
index 0000000..50b4109
--- /dev/null
+++ b/SOURCES/glibc-rh1080766.patch
@@ -0,0 +1,57 @@
+commit fbd6b5a4052316f7eb03c4617eebfaafc59dcc06
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Thu Mar 27 07:15:22 2014 +0530
+
+    Fix nscd lookup for innetgr when netgroup has wildcards (BZ #16758)
+    
+    nscd works correctly when the request in innetgr is a wildcard,
+    i.e. when one or more of host, user or domain parameters is NULL.
+    However, it does not work when the the triplet in the netgroup
+    definition has a wildcard.  This is easy to reproduce for a triplet
+    defined as follows:
+    
+        foonet (,foo,)
+    
+    Here, an innetgr call that looks like this:
+    
+        innetgr ("foonet", "foohost", "foo", NULL);
+    
+    should succeed and so should:
+    
+        innetgr ("foonet", NULL, "foo", "foodomain");
+    
+    It does succeed with nscd disabled, but not with nscd enabled.  This
+    fix adds this additional check for all three parts of the triplet so
+    that it gives the correct result.
+    
+    	[BZ #16758]
+    	* nscd/netgroupcache.c (addinnetgrX): Succeed if triplet has
+    	blank values.
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 5ba1e1f..5d15aa4 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -560,15 +560,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/SOURCES/glibc-rh1083644.patch b/SOURCES/glibc-rh1083644.patch
new file mode 100644
index 0000000..60a0ece
--- /dev/null
+++ b/SOURCES/glibc-rh1083644.patch
@@ -0,0 +1,63 @@
+commit ea7d8b95e2fcb81f68b04ed7787a3dbda023991a
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Thu Mar 27 19:48:15 2014 +0530
+
+    Avoid overlapping addresses to stpcpy calls in nscd (BZ #16760)
+    
+    Calls to stpcpy from nscd netgroups code will have overlapping source
+    and destination when all three values in the returned triplet are
+    non-NULL and in the expected (host,user,domain) order.  This is seen
+    in valgrind as:
+    
+    ==3181== Source and destination overlap in stpcpy(0x19973b48, 0x19973b48)
+    ==3181==    at 0x4C2F30A: stpcpy (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
+    ==3181==    by 0x12567A: addgetnetgrentX (string3.h:111)
+    ==3181==    by 0x12722D: addgetnetgrent (netgroupcache.c:665)
+    ==3181==    by 0x11114C: nscd_run_worker (connections.c:1338)
+    ==3181==    by 0x4E3C102: start_thread (pthread_create.c:309)
+    ==3181==    by 0x59B81AC: clone (clone.S:111)
+    ==3181==
+    
+    Fix this by using memmove instead of stpcpy.
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 5d15aa4..820d823 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -216,6 +216,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 +237,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 +270,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;
+ 			  }
diff --git a/SOURCES/glibc-rh1083646.patch b/SOURCES/glibc-rh1083646.patch
new file mode 100644
index 0000000..2210609
--- /dev/null
+++ b/SOURCES/glibc-rh1083646.patch
@@ -0,0 +1,398 @@
+commit bc8f194c8c29e46e8ee4034f06e46988dfff38f7
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Wed Apr 30 12:00:39 2014 +0530
+
+    Initialize all of datahead structure in nscd (BZ #16791)
+    
+    The datahead structure has an unused padding field that remains
+    uninitialized.  Valgrind prints out a warning for it on querying a
+    netgroups entry.  This is harmless, but is a potential data leak since
+    it would result in writing out an uninitialized byte to the cache
+    file.  Besides, this happens only when there is a cache miss, so we're
+    not adding computation to any fast path.
+
+commit 1cdeb2372ddecac0dfe0c132a033e9590ffa07d2
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Wed Apr 30 11:57:09 2014 +0530
+
+    Consolidate code to initialize nscd dataset header
+    
+    This patch consolidates the code to initialize the header of a dataset
+    into a single set of functions (one for positive and another for
+    negative datasets) primarily to reduce repetition of code.  The
+    secondary reason is to simplify Patch 2/2 which fixes the problem of
+    an uninitialized byte in the header by initializing an unused field in
+    the structure and hence preventing a possible data leak into the cache
+    file.
+
+diff --git a/nscd/aicache.c b/nscd/aicache.c
+index 98d40a1..d7966bd 100644
+--- a/nscd/aicache.c
++++ b/nscd/aicache.c
+@@ -383,17 +383,12 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
+ 	  cp = family;
+ 	}
+ 
+-      /* Fill in the rest of the dataset.  */
+-      dataset->head.allocsize = total + req->key_len;
+-      dataset->head.recsize = total - offsetof (struct dataset, resp);
+-      dataset->head.notfound = false;
+-      dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
+-      dataset->head.usable = true;
+-
+-      /* Compute the timeout time.  */
+-      dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl;
+-      timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;
++      timeout = datahead_init_pos (&dataset->head, total + req->key_len,
++				   total - offsetof (struct dataset, resp),
++				   he == NULL ? 0 : dh->nreloads + 1,
++				   ttl == INT32_MAX ? db->postimeout : ttl);
+ 
++      /* Fill in the rest of the dataset.  */
+       dataset->resp.version = NSCD_VERSION;
+       dataset->resp.found = 1;
+       dataset->resp.naddrs = naddrs;
+@@ -528,15 +523,9 @@ next_nip:
+       else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ 					      + req->key_len), 1)) != NULL)
+ 	{
+-	  dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
+-	  dataset->head.recsize = total;
+-	  dataset->head.notfound = true;
+-	  dataset->head.nreloads = 0;
+-	  dataset->head.usable = true;
+-
+-	  /* Compute the timeout time.  */
+-	  timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
+-	  dataset->head.ttl = db->negtimeout;
++	  timeout = datahead_init_neg (&dataset->head,
++				       sizeof (struct dataset) + req->key_len,
++				       total, db->negtimeout);
+ 
+ 	  /* This is the reply.  */
+ 	  memcpy (&dataset->resp, &notfound, total);
+diff --git a/nscd/grpcache.c b/nscd/grpcache.c
+index b5a33eb..df59fa7 100644
+--- a/nscd/grpcache.c
++++ b/nscd/grpcache.c
+@@ -128,14 +128,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
+ 	    }
+ 	  else if ((dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1)) != NULL)
+ 	    {
+-	      dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
+-	      dataset->head.recsize = total;
+-	      dataset->head.notfound = true;
+-	      dataset->head.nreloads = 0;
+-	      dataset->head.usable = true;
+-
+-	      /* Compute the timeout time.  */
+-	      timeout = dataset->head.timeout = t + db->negtimeout;
++	      timeout = datahead_init_neg (&dataset->head,
++					   (sizeof (struct dataset)
++					    + req->key_len), total,
++					   db->negtimeout);
+ 
+ 	      /* This is the reply.  */
+ 	      memcpy (&dataset->resp, &notfound, total);
+@@ -232,14 +228,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
+ 	  dataset_temporary = true;
+ 	}
+ 
+-      dataset->head.allocsize = total + n;
+-      dataset->head.recsize = total - offsetof (struct dataset, resp);
+-      dataset->head.notfound = false;
+-      dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
+-      dataset->head.usable = true;
+-
+-      /* Compute the timeout time.  */
+-      timeout = dataset->head.timeout = t + db->postimeout;
++      timeout = datahead_init_pos (&dataset->head, total + n,
++				   total - offsetof (struct dataset, resp),
++				   he == NULL ? 0 : dh->nreloads + 1,
++				   db->postimeout);
+ 
+       dataset->resp.version = NSCD_VERSION;
+       dataset->resp.found = 1;
+diff --git a/nscd/hstcache.c b/nscd/hstcache.c
+index a79b67a..d4f1ad2 100644
+--- a/nscd/hstcache.c
++++ b/nscd/hstcache.c
+@@ -152,15 +152,11 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
+ 	  else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ 						  + req->key_len), 1)) != NULL)
+ 	    {
+-	      dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
+-	      dataset->head.recsize = total;
+-	      dataset->head.notfound = true;
+-	      dataset->head.nreloads = 0;
+-	      dataset->head.usable = true;
+-
+-	      /* Compute the timeout time.  */
+-	      dataset->head.ttl = ttl == INT32_MAX ? db->negtimeout : ttl;
+-	      timeout = dataset->head.timeout = t + dataset->head.ttl;
++	      timeout = datahead_init_neg (&dataset->head,
++					   (sizeof (struct dataset)
++					    + req->key_len), total,
++					   (ttl == INT32_MAX
++					    ? db->negtimeout : ttl));
+ 
+ 	      /* This is the reply.  */
+ 	      memcpy (&dataset->resp, resp, total);
+@@ -257,15 +253,10 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
+ 	  alloca_used = true;
+ 	}
+ 
+-      dataset->head.allocsize = total + req->key_len;
+-      dataset->head.recsize = total - offsetof (struct dataset, resp);
+-      dataset->head.notfound = false;
+-      dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
+-      dataset->head.usable = true;
+-
+-      /* Compute the timeout time.  */
+-      dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl;
+-      timeout = dataset->head.timeout = t + dataset->head.ttl;
++      timeout = datahead_init_pos (&dataset->head, total + req->key_len,
++				   total - offsetof (struct dataset, resp),
++				   he == NULL ? 0 : dh->nreloads + 1,
++				   ttl == INT32_MAX ? db->postimeout : ttl);
+ 
+       dataset->resp.version = NSCD_VERSION;
+       dataset->resp.found = 1;
+diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
+index 1bf9f0d..361319f 100644
+--- a/nscd/initgrcache.c
++++ b/nscd/initgrcache.c
+@@ -213,14 +213,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
+ 	  else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ 						  + req->key_len), 1)) != NULL)
+ 	    {
+-	      dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
+-	      dataset->head.recsize = total;
+-	      dataset->head.notfound = true;
+-	      dataset->head.nreloads = 0;
+-	      dataset->head.usable = true;
+-
+-	      /* Compute the timeout time.  */
+-	      timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
++	      timeout = datahead_init_neg (&dataset->head,
++					   (sizeof (struct dataset)
++					    + req->key_len), total,
++					   db->negtimeout);
+ 
+ 	      /* This is the reply.  */
+ 	      memcpy (&dataset->resp, &notfound, total);
+@@ -276,14 +272,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
+ 	  alloca_used = true;
+ 	}
+ 
+-      dataset->head.allocsize = total + req->key_len;
+-      dataset->head.recsize = total - offsetof (struct dataset, resp);
+-      dataset->head.notfound = false;
+-      dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
+-      dataset->head.usable = true;
+-
+-      /* Compute the timeout time.  */
+-      timeout = dataset->head.timeout = time (NULL) + db->postimeout;
++      timeout = datahead_init_pos (&dataset->head, total + req->key_len,
++				   total - offsetof (struct dataset, resp),
++				   he == NULL ? 0 : dh->nreloads + 1,
++				   db->postimeout);
+ 
+       dataset->resp.version = NSCD_VERSION;
+       dataset->resp.found = 1;
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 820d823..b3d40e9 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -90,15 +90,9 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
+   /* If we cannot permanently store the result, so be it.  */
+   if (dataset != NULL)
+     {
+-      dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
+-      dataset->head.recsize = total;
+-      dataset->head.notfound = true;
+-      dataset->head.nreloads = 0;
+-      dataset->head.usable = true;
+-
+-      /* Compute the timeout time.  */
+-      timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
+-      dataset->head.ttl = db->negtimeout;
++      timeout = datahead_init_neg (&dataset->head,
++				   sizeof (struct dataset) + req->key_len,
++				   total, db->negtimeout);
+ 
+       /* This is the reply.  */
+       memcpy (&dataset->resp, &notfound, total);
+@@ -359,13 +353,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 
+   /* Fill in the dataset.  */
+   dataset = (struct dataset *) buffer;
+-  dataset->head.allocsize = total + req->key_len;
+-  dataset->head.recsize = total - offsetof (struct dataset, resp);
+-  dataset->head.notfound = false;
+-  dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
+-  dataset->head.usable = true;
+-  dataset->head.ttl = db->postimeout;
+-  timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;
++  timeout = datahead_init_pos (&dataset->head, total + req->key_len,
++			       total - offsetof (struct dataset, resp),
++			       he == NULL ? 0 : dh->nreloads + 1,
++			       db->postimeout);
+ 
+   dataset->resp.version = NSCD_VERSION;
+   dataset->resp.found = 1;
+@@ -541,12 +532,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+       dataset = &dataset_mem;
+     }
+ 
+-  dataset->head.allocsize = sizeof (*dataset) + req->key_len;
+-  dataset->head.recsize = sizeof (innetgroup_response_header);
++  datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
++		     sizeof (innetgroup_response_header),
++		     he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
++  /* Set the notfound status and timeout based on the result from
++     getnetgrent.  */
+   dataset->head.notfound = result->head.notfound;
+-  dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
+-  dataset->head.usable = true;
+-  dataset->head.ttl = result->head.ttl;
+   dataset->head.timeout = timeout;
+ 
+   dataset->resp.version = NSCD_VERSION;
+diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
+index 98f77e7..ee16df6 100644
+--- a/nscd/nscd-client.h
++++ b/nscd/nscd-client.h
+@@ -236,6 +236,48 @@ struct datahead
+   } data[0];
+ };
+ 
++static inline time_t
++datahead_init_common (struct datahead *head, nscd_ssize_t allocsize,
++		      nscd_ssize_t recsize, uint32_t ttl)
++{
++  /* Initialize so that we don't write out junk in uninitialized data to the
++     cache.  */
++  memset (head, 0, sizeof (*head));
++
++  head->allocsize = allocsize;
++  head->recsize = recsize;
++  head->usable = true;
++
++  head->ttl = ttl;
++
++  /* Compute and return the timeout time.  */
++  return head->timeout = time (NULL) + ttl;
++}
++
++static inline time_t
++datahead_init_pos (struct datahead *head, nscd_ssize_t allocsize,
++		   nscd_ssize_t recsize, uint8_t nreloads, uint32_t ttl)
++{
++  time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
++
++  head->notfound = false;
++  head->nreloads = nreloads;
++
++  return ret;
++}
++
++static inline time_t
++datahead_init_neg (struct datahead *head, nscd_ssize_t allocsize,
++		   nscd_ssize_t recsize, uint32_t ttl)
++{
++  time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
++
++  /* We don't need to touch nreloads here since it is set to our desired value
++     (0) when we clear the structure.  */
++  head->notfound = true;
++
++  return ret;
++}
+ 
+ /* Structure for one hash table entry.  */
+ struct hashentry
+diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
+index fa355c3..41c245b 100644
+--- a/nscd/pwdcache.c
++++ b/nscd/pwdcache.c
+@@ -135,14 +135,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
+ 	  else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ 						  + req->key_len), 1)) != NULL)
+ 	    {
+-	      dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
+-	      dataset->head.recsize = total;
+-	      dataset->head.notfound = true;
+-	      dataset->head.nreloads = 0;
+-	      dataset->head.usable = true;
+-
+-	      /* Compute the timeout time.  */
+-	      timeout = dataset->head.timeout = t + db->negtimeout;
++	      timeout = datahead_init_neg (&dataset->head,
++					   (sizeof (struct dataset)
++					    + req->key_len), total,
++					   db->negtimeout);
+ 
+ 	      /* This is the reply.  */
+ 	      memcpy (&dataset->resp, &notfound, total);
+@@ -215,14 +211,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
+ 	  alloca_used = true;
+ 	}
+ 
+-      dataset->head.allocsize = total + n;
+-      dataset->head.recsize = total - offsetof (struct dataset, resp);
+-      dataset->head.notfound = false;
+-      dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
+-      dataset->head.usable = true;
+-
+-      /* Compute the timeout time.  */
+-      timeout = dataset->head.timeout = t + db->postimeout;
++      timeout = datahead_init_pos (&dataset->head, total + n,
++				   total - offsetof (struct dataset, resp),
++				   he == NULL ? 0 : dh->nreloads + 1,
++				   db->postimeout);
+ 
+       dataset->resp.version = NSCD_VERSION;
+       dataset->resp.found = 1;
+diff --git a/nscd/servicescache.c b/nscd/servicescache.c
+index 12ce9b2..95bdcfe 100644
+--- a/nscd/servicescache.c
++++ b/nscd/servicescache.c
+@@ -120,14 +120,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
+ 	  else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ 						  + req->key_len), 1)) != NULL)
+ 	    {
+-	      dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
+-	      dataset->head.recsize = total;
+-	      dataset->head.notfound = true;
+-	      dataset->head.nreloads = 0;
+-	      dataset->head.usable = true;
+-
+-	      /* Compute the timeout time.  */
+-	      timeout = dataset->head.timeout = t + db->negtimeout;
++	      timeout = datahead_init_neg (&dataset->head,
++					   (sizeof (struct dataset)
++					    + req->key_len), total,
++					   db->negtimeout);
+ 
+ 	      /* This is the reply.  */
+ 	      memcpy (&dataset->resp, &notfound, total);
+@@ -207,14 +203,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
+ 	  alloca_used = true;
+ 	}
+ 
+-      dataset->head.allocsize = total + req->key_len;
+-      dataset->head.recsize = total - offsetof (struct dataset, resp);
+-      dataset->head.notfound = false;
+-      dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
+-      dataset->head.usable = true;
+-
+-      /* Compute the timeout time.  */
+-      timeout = dataset->head.timeout = t + db->postimeout;
++      timeout = datahead_init_pos (&dataset->head, total + req->key_len,
++				   total - offsetof (struct dataset, resp),
++				   he == NULL ? 0 : dh->nreloads + 1,
++				   db->postimeout);
+ 
+       dataset->resp.version = NSCD_VERSION;
+       dataset->resp.found = 1;
diff --git a/SOURCES/glibc-rh1083647.patch b/SOURCES/glibc-rh1083647.patch
new file mode 100644
index 0000000..121127e
--- /dev/null
+++ b/SOURCES/glibc-rh1083647.patch
@@ -0,0 +1,26 @@
+commit c44496df2f090a56d3bf75df930592dac6bba46f
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Wed Mar 12 17:27:22 2014 +0530
+
+    Provide correct buffer length to netgroup queries in nscd (BZ #16695)
+    
+    The buffer to query netgroup entries is allocated sufficient space for
+    the netgroup entries and the key to be appended at the end, but it
+    sends in an incorrect available length to the NSS netgroup query
+    functions, resulting in overflow of the buffer in some special cases.
+    The fix here is to factor in the key length when sending the available
+    buffer and buffer length to the query functions.
+
+diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
+index 426d3c5..5ba1e1f 100644
+--- a/nscd/netgroupcache.c
++++ b/nscd/netgroupcache.c
+@@ -202,7 +202,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 		  {
+ 		    int e;
+ 		    status = getfct.f (&data, buffer + buffilled,
+-				       buflen - buffilled, &e);
++				       buflen - buffilled - req->key_len, &e);
+ 		    if (status == NSS_STATUS_RETURN
+ 			|| status == NSS_STATUS_NOTFOUND)
+ 		      /* This was either the last one for this group or the
diff --git a/SOURCES/glibc-rh1084089.patch b/SOURCES/glibc-rh1084089.patch
new file mode 100644
index 0000000..2411964
--- /dev/null
+++ b/SOURCES/glibc-rh1084089.patch
@@ -0,0 +1,65 @@
+diff -pruN a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
+--- a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c	2012-12-25 08:32:13.000000000 +0530
++++ b/nptl/sysdeps/unix/sysv/linux/lowlevellock.c	2014-09-05 21:50:56.982975803 +0530
+@@ -21,11 +21,13 @@
+ #include <sysdep.h>
+ #include <lowlevellock.h>
+ #include <sys/time.h>
++#include <stap-probe.h>
+ 
+ 
+ void
+ __lll_lock_wait_private (int *futex)
+ {
++  LIBC_PROBE (lll_lock_wait_private, 1, futex);
+   if (*futex == 2)
+     lll_futex_wait (futex, 2, LLL_PRIVATE);
+ 
+@@ -39,6 +42,7 @@ __lll_lock_wait_private (int *futex)
+ void
+ __lll_lock_wait (int *futex, int private)
+ {
++  LIBC_PROBE (lll_lock_wait, 2, futex, FUTEX_WAIT | private);
+   if (*futex == 2)
+     lll_futex_wait (futex, 2, private);
+ 
+diff -pruN a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+--- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h	2012-12-25 08:32:13.000000000 +0530
++++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h	2014-09-05 21:51:58.722483631 +0530
+@@ -19,6 +19,8 @@
+ #ifndef _LOWLEVELLOCK_H
+ #define _LOWLEVELLOCK_H	1
+ 
++#include <stap-probe.h>
++
+ #include <time.h>
+ #include <sys/param.h>
+ #include <bits/pthreadtypes.h>
+@@ -106,6 +108,7 @@
+     INTERNAL_SYSCALL_DECL (__err);					      \
+     long int __ret;							      \
+ 									      \
++    LIBC_PROBE (lll_futex_wake, 3, futexp, nr, private);		      \
+     __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+ 			      __lll_private_flag (FUTEX_WAKE, private),	      \
+ 			      (nr), 0);					      \
+diff -pruN a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
+--- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h	2012-12-25 08:32:13.000000000 +0530
++++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h	2014-09-05 21:51:58.722483631 +0530
+@@ -19,6 +19,8 @@
+ #ifndef _LOWLEVELLOCK_H
+ #define _LOWLEVELLOCK_H	1
+ 
++#include <stap-probe.h>
++
+ #include <time.h>
+ #include <sys/param.h>
+ #include <bits/pthreadtypes.h>
+@@ -122,6 +124,7 @@
+     register unsigned long int __r4 asm ("4") = (unsigned long int) (nr);     \
+     register unsigned long int __result asm ("2");			      \
+ 									      \
++    LIBC_PROBE (lll_futex_wake, 3, futex, nr, private);			      \
+     __asm __volatile ("svc %b1"						      \
+ 		      : "=d" (__result)					      \
+ 		      : "i" (SYS_futex), "0" (__r2), "d" (__r3), "d" (__r4)   \
diff --git a/SOURCES/glibc-rh1085290.patch b/SOURCES/glibc-rh1085290.patch
new file mode 100644
index 0000000..63e10b0
--- /dev/null
+++ b/SOURCES/glibc-rh1085290.patch
@@ -0,0 +1,60 @@
+commit dd3022d75e6fb8957843d6d84257a5d8457822d5
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Thu Mar 27 19:49:51 2014 +0530
+
+    Return NULL for wildcard values in getnetgrent from nscd (BZ #16759)
+    
+    getnetgrent is supposed to return NULL for values that are wildcards
+    in the (host, user, domain) triplet.  This works correctly with nscd
+    disabled, but with it enabled, it returns a blank ("") instead of a
+    NULL.  This is easily seen with the output of `getent netgroup foonet`
+    for a netgroup foonet defined as follows in /etc/netgroup:
+    
+        foonet (,foo,)
+    
+    The output with nscd disabled is:
+    
+        foonet ( ,foo,)
+    
+    while with nscd enabled, it is:
+    
+        foonet (,foo,)
+    
+    The extra space with nscd disabled is due to the fact that `getent
+    netgroup` adds it if the return value from getnetgrent is NULL for
+    either host or user.
+
+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)
+   __libc_lock_unlock (lock);
+ }
+ 
++static const char *
++get_nonempty_val (const char *in)
++{
++  if (*in == '\0')
++    return NULL;
++  return in;
++}
++
+ #ifdef USE_NSCD
+ static enum nss_status
+ nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
+@@ -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/SOURCES/glibc-rh1085313.patch b/SOURCES/glibc-rh1085313.patch
new file mode 100644
index 0000000..461d862
--- /dev/null
+++ b/SOURCES/glibc-rh1085313.patch
@@ -0,0 +1,34 @@
+commit 58b930ae216bfa98cd60212b954b07b9963d6d04
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Wed Sep 10 21:51:50 2014 +0530
+
+    Return failure in getnetgrent only when all netgroups have been searched (#17363)
+    
+    The netgroups lookup code fails when one of the groups in the search
+    tree is empty.  In such a case it only returns the leaves of the tree
+    after the blank netgroup.  This is because the line parser returns a
+    NOTFOUND status when the netgroup exists but is empty.  The
+    __getnetgrent_internal implementation needs to be fixed to try
+    remaining groups if the current group is entry.  This patch implements
+    this fix.  Tested on x86_64.
+    
+    	[BZ #17363]
+    	* inet/getnetgrent_r.c (__internal_getnetgrent_r): Try next
+    	group if the current group is empty.
+
+diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
+index f6d064d..e101537 100644
+--- a/inet/getnetgrent_r.c
++++ b/inet/getnetgrent_r.c
+@@ -297,7 +297,10 @@ __internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
+     {
+       status = DL_CALL_FCT (*fct, (datap, buffer, buflen, &errno));
+ 
+-      if (status == NSS_STATUS_RETURN)
++      if (status == NSS_STATUS_RETURN
++	  /* The service returned a NOTFOUND, but there are more groups that we
++	     need to resolve before we give up.  */
++	  || (status == NSS_STATUS_NOTFOUND && datap->needed_groups != NULL))
+ 	{
+ 	  /* This was the last one for this group.  Look at next group
+ 	     if available.  */
diff --git a/SOURCES/glibc-rh1098047.patch b/SOURCES/glibc-rh1098047.patch
new file mode 100644
index 0000000..5be5321
--- /dev/null
+++ b/SOURCES/glibc-rh1098047.patch
@@ -0,0 +1,247 @@
+commit 16b293a7a6f65d8ff348a603d19e8fd4372fa3a9
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Wed Apr 30 11:48:43 2014 +0530
+
+    Do not fail if one of the two responses to AF_UNSPEC fails (BZ #14308)
+    
+    [Fixes BZ #14308, #12994, #13651]
+    
+    AF_UNSPEC results in sending two queries in parallel, one for the A
+    record and the other for the AAAA record.  If one of these is a
+    referral, then the query fails, which is wrong.  It should return at
+    least the one successful response.
+    
+    The fix has two parts.  The first part makes the referral fall back to
+    the SERVFAIL path, which results in using the successful response.
+    There is a bug in that path however, due to which the second part is
+    necessary.  The bug here is that if the first response is a failure
+    and the second succeeds, __libc_res_nsearch does not detect that and
+    assumes a failure.  The case where the first response is a success and
+    the second fails, works correctly.
+    
+    This condition is produced by buggy routers, so here's a crude
+    interposable library that can simulate such a condition.  The library
+    overrides the recvfrom syscall and modifies the header of the packet
+    received to reproduce this scenario.  It has two key variables:
+    mod_packet and first_error.
+    
+    The mod_packet variable when set to 0, results in odd packets being
+    modified to be a referral.  When set to 1, even packets are modified
+    to be a referral.
+    
+    The first_error causes the first response to be a failure so that a
+    domain-appended search is performed to test the second part of the
+    __libc_nsearch fix.
+    
+    The driver for this fix is a simple getaddrinfo program that does an
+    AF_UNSPEC query.  I have omitted this since it should be easy to
+    implement.
+    
+    I have tested this on x86_64.
+    
+    The interceptor library source:
+    
+    /* Override recvfrom and modify the header of the first DNS response to make it
+       a referral and reproduce bz #845218.  We have to resort to this ugly hack
+       because we cannot make bind return the buggy response of a referral for the
+       AAAA record and an authoritative response for the A record.  */
+     #define _GNU_SOURCE
+     #include <sys/types.h>
+     #include <sys/socket.h>
+     #include <netinet/in.h>
+     #include <arpa/inet.h>
+     #include <stdio.h>
+     #include <stdbool.h>
+     #include <endian.h>
+     #include <dlfcn.h>
+     #include <stdlib.h>
+    
+    /* Lifted from resolv/arpa/nameser_compat.h.  */
+    typedef struct {
+        unsigned        id :16;         /*%< query identification number */
+     #if BYTE_ORDER == BIG_ENDIAN
+        /* fields in third byte */
+        unsigned        qr: 1;          /*%< response flag */
+        unsigned        opcode: 4;      /*%< purpose of message */
+        unsigned        aa: 1;          /*%< authoritive answer */
+        unsigned        tc: 1;          /*%< truncated message */
+        unsigned        rd: 1;          /*%< recursion desired */
+        /* fields
+         * in
+         * fourth
+         * byte
+         * */
+        unsigned        ra: 1;          /*%< recursion available */
+        unsigned        unused :1;      /*%< unused bits (MBZ as of 4.9.3a3) */
+        unsigned        ad: 1;          /*%< authentic data from named */
+        unsigned        cd: 1;          /*%< checking disabled by resolver */
+        unsigned        rcode :4;       /*%< response code */
+     #endif
+     #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+        /* fields
+         * in
+         * third
+         * byte
+         * */
+        unsigned        rd :1;          /*%< recursion desired */
+        unsigned        tc :1;          /*%< truncated message */
+        unsigned        aa :1;          /*%< authoritive answer */
+        unsigned        opcode :4;      /*%< purpose of message */
+        unsigned        qr :1;          /*%< response flag */
+        /* fields
+         * in
+         * fourth
+         * byte
+         * */
+        unsigned        rcode :4;       /*%< response code */
+        unsigned        cd: 1;          /*%< checking disabled by resolver */
+        unsigned        ad: 1;          /*%< authentic data from named */
+        unsigned        unused :1;      /*%< unused bits (MBZ as of 4.9.3a3) */
+        unsigned        ra :1;          /*%< recursion available */
+     #endif
+        /* remaining
+         * bytes
+         * */
+        unsigned        qdcount :16;    /*%< number of question entries */
+        unsigned        ancount :16;    /*%< number of answer entries */
+        unsigned        nscount :16;    /*%< number of authority entries */
+        unsigned        arcount :16;    /*%< number of resource entries */
+    } HEADER;
+    
+    static int done = 0;
+    
+    /* Packets to modify.  0 for the odd packets and 1 for even packets.  */
+    static const int mod_packet = 0;
+    
+    /* Set to true if the first request should result in an error, resulting in a
+       search query.  */
+    static bool first_error = true;
+    
+    static ssize_t (*real_recvfrom) (int sockfd, void *buf, size_t len, int flags,
+    			  struct sockaddr *src_addr, socklen_t *addrlen);
+    
+    void
+    __attribute__ ((constructor))
+    init (void)
+    {
+      real_recvfrom = dlsym (RTLD_NEXT, "recvfrom");
+    
+      if (real_recvfrom == NULL)
+        {
+          printf ("Failed to get reference to recvfrom: %s\n", dlerror ());
+          printf ("Cannot simulate test\n");
+          abort ();
+        }
+    }
+    
+    /* Modify the second packet that we receive to set the header in a manner as to
+       reproduce BZ #845218.  */
+    static void
+    mod_buf (HEADER *h, int port)
+    {
+      if (done % 2 == mod_packet || (first_error && done == 1))
+        {
+          printf ("(Modifying header)");
+    
+          if (first_error && done == 1)
+    	h->rcode = 3;
+          else
+    	h->rcode = 0;	/* NOERROR == 0.  */
+          h->ancount = 0;
+          h->aa = 0;
+          h->ra = 0;
+          h->arcount = 0;
+        }
+      done++;
+    }
+    
+    ssize_t
+    recvfrom (int sockfd, void *buf, size_t len, int flags,
+    	  struct sockaddr *src_addr, socklen_t *addrlen)
+    {
+      ssize_t ret = real_recvfrom (sockfd, buf, len, flags, src_addr, addrlen);
+      int port = htons (((struct sockaddr_in *) src_addr)->sin_port);
+      struct in_addr addr = ((struct sockaddr_in *) src_addr)->sin_addr;
+      const char *host = inet_ntoa (addr);
+      printf ("\n*** From %s:%d: ", host, port);
+    
+      mod_buf (buf, port);
+    
+      printf ("returned %zd\n", ret);
+      return ret;
+    }
+
+ ChangeLog          | 11 +++++++++++
+ NEWS               | 14 +++++++-------
+ resolv/res_query.c |  7 +++++--
+ resolv/res_send.c  |  2 +-
+ 4 files changed, 24 insertions(+), 10 deletions(-)
+
+commit e35c53e397e7abbd41fedacdedcfa5af7b5c2c52
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Tue Jul 8 16:40:24 2014 +0530
+
+    Check value at resplen2 if it is not NULL
+    
+    There was a typo in the previous patch due to which resplen2 was
+    checked for non-zero instead of the value at resplen2.  Fix that and
+    improve the condition by checking resplen2 for non-NULL (instead of
+    answerp2) and also adding the check in a third place.
+
+ ChangeLog          | 3 +++
+ resolv/res_query.c | 9 +++++----
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff -pruN a/resolv/res_query.c b/resolv/res_query.c
+--- a/resolv/res_query.c	2012-12-25 08:32:13.000000000 +0530
++++ b/resolv/res_query.c	2014-09-05 14:28:06.439191017 +0530
+@@ -378,7 +378,9 @@ __libc_res_nsearch(res_state statp,
+ 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
+ 					      answer, anslen, answerp,
+ 					      answerp2, nanswerp2, resplen2);
+-		if (ret > 0 || trailing_dot)
++		if (ret > 0 || trailing_dot
++		    /* If the second response is valid then we use that.  */
++		    || (ret == 0 && resplen2 != NULL && *resplen2 > 0))
+ 			return (ret);
+ 		saved_herrno = h_errno;
+ 		tried_as_is++;
+@@ -418,7 +420,8 @@ __libc_res_nsearch(res_state statp,
+ 						      answer, anslen, answerp,
+ 						      answerp2, nanswerp2,
+ 						      resplen2);
+-			if (ret > 0)
++			if (ret > 0 || (ret == 0 && resplen2 != NULL
++					&& *resplen2 > 0))
+ 				return (ret);
+ 
+ 			if (answerp && *answerp != answer) {
+@@ -487,7 +490,8 @@ __libc_res_nsearch(res_state statp,
+ 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
+ 					      answer, anslen, answerp,
+ 					      answerp2, nanswerp2, resplen2);
+-		if (ret > 0)
++		if (ret > 0 || (ret == 0 && resplen2 != NULL
++				&& *resplen2 > 0))
+ 			return (ret);
+ 	}
+ 
+diff -pruN a/resolv/res_send.c b/resolv/res_send.c
+--- a/resolv/res_send.c	2014-09-05 14:28:30.039337246 +0530
++++ b/resolv/res_send.c	2014-09-05 14:28:06.439191017 +0530
+@@ -1343,6 +1343,7 @@ send_dg(res_state statp,
+ 				(*thisresplenp > *thisanssizp)
+ 				? *thisanssizp : *thisresplenp);
+ 
++		next_ns:
+ 			if (recvresp1 || (buf2 != NULL && recvresp2)) {
+ 			  *resplen2 = 0;
+ 			  return resplen;
+@@ -1360,7 +1361,6 @@ send_dg(res_state statp,
+ 			    goto wait;
+ 			  }
+ 
+-		next_ns:
+ 			__res_iclose(statp, false);
+ 			/* don't retry if called from dig */
+ 			if (!statp->pfcode)
diff --git a/SOURCES/glibc-rh1103856.patch b/SOURCES/glibc-rh1103856.patch
new file mode 100644
index 0000000..8599cf0
--- /dev/null
+++ b/SOURCES/glibc-rh1103856.patch
@@ -0,0 +1,28 @@
+commit 4d653a59ffeae0f46f76a40230e2cfa9587b7e7e
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Fri May 30 22:43:52 2014 +0530
+
+    Add mmap usage in malloc_info output
+    
+    The current malloc_info xml output only has information about
+    allocations on the heap.  Display information about number of mappings
+    and total mmapped size to this to complete the picture.
+
+diff -pruN a/malloc/malloc.c b/malloc/malloc.c
+--- a/malloc/malloc.c	2014-06-02 07:35:22.573256155 +0530
++++ b/malloc/malloc.c	2014-06-02 07:34:58.856257177 +0530
+@@ -6553,12 +6553,14 @@ malloc_info (int options, FILE *fp)
+   fprintf (fp,
+ 	   "<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
+ 	   "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
++	   "<total type=\"mmap\" count=\"%d\" size=\"%zu\"/>\n"
+ 	   "<system type=\"current\" size=\"%zu\"/>\n"
+ 	   "<system type=\"max\" size=\"%zu\"/>\n"
+ 	   "<aspace type=\"total\" size=\"%zu\"/>\n"
+ 	   "<aspace type=\"mprotect\" size=\"%zu\"/>\n"
+ 	   "</malloc>\n",
+ 	   total_nfastblocks, total_fastavail, total_nblocks, total_avail,
++	   mp_.n_mmaps, mp_.mmapped_mem,
+ 	   total_system, total_max_system,
+ 	   total_aspace, total_aspace_mprotect);
+ 
diff --git a/SOURCES/glibc-rh1103874.patch b/SOURCES/glibc-rh1103874.patch
new file mode 100644
index 0000000..141470d
--- /dev/null
+++ b/SOURCES/glibc-rh1103874.patch
@@ -0,0 +1,152 @@
+diff -pruN a/nptl/sysdeps/pthread/unwind-forcedunwind.c b/nptl/sysdeps/pthread/unwind-forcedunwind.c
+--- a/nptl/sysdeps/pthread/unwind-forcedunwind.c	2010-05-04 16:57:23.000000000 +0530
++++ b/nptl/sysdeps/pthread/unwind-forcedunwind.c	2014-06-02 23:00:02.901013275 +0530
+@@ -45,8 +45,10 @@ pthread_cancel_init (void)
+ 
+   if (__builtin_expect (libgcc_s_handle != NULL, 1))
+     {
+-      /* Force gcc to reload all values.  */
+-      asm volatile ("" ::: "memory");
++      /* Order reads so as to prevent speculation of loads
++	 of libgcc_s_{resume,personality,forcedunwind,getcfa}
++	 to points prior to the write barrier.  */
++      atomic_read_barrier ();
+       return;
+     }
+ 
+@@ -72,9 +74,14 @@ pthread_cancel_init (void)
+   libgcc_s_forcedunwind = forcedunwind;
+   PTR_MANGLE (getcfa);
+   libgcc_s_getcfa = getcfa;
+-  /* Make sure libgcc_s_handle is written last.  Otherwise,
+-     pthread_cancel_init might return early even when the pointer the
+-     caller is interested in is not initialized yet.  */
++  /* At the point at which any thread writes the handle
++     to libgcc_s_handle, the initialization is complete.
++     The writing of libgcc_s_handle is atomic. All other
++     threads reading libgcc_s_handle do so atomically. Any
++     thread that does not execute this function must issue
++     a read barrier to ensure that all of the above has
++     actually completed and that the values of the
++     function pointers are correct.   */
+   atomic_write_barrier ();
+   libgcc_s_handle = handle;
+ }
+@@ -91,13 +98,19 @@ __unwind_freeres (void)
+     }
+ }
+ 
+-void
+-_Unwind_Resume (struct _Unwind_Exception *exc)
++static __always_inline void
++_maybe_pthread_cancel_init (void)
+ {
+   if (__builtin_expect (libgcc_s_handle == NULL, 0))
+     pthread_cancel_init ();
+   else
+     atomic_read_barrier ();
++}
++
++void
++_Unwind_Resume (struct _Unwind_Exception *exc)
++{
++  _maybe_pthread_cancel_init ();
+ 
+   void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume;
+   PTR_DEMANGLE (resume);
+@@ -108,10 +123,7 @@ __gcc_personality_v0 (int version, _Unwi
+ 		      struct _Unwind_Exception *ue_header,
+ 		      struct _Unwind_Context *context)
+ {
+-  if (__builtin_expect (libgcc_s_handle == NULL, 0))
+-    pthread_cancel_init ();
+-  else
+-    atomic_read_barrier ();
++  _maybe_pthread_cancel_init ();
+ 
+   _Unwind_Reason_Code (*personality)
+     (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+@@ -122,10 +136,7 @@ _Unwind_Reason_Code
+ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
+ 		      void *stop_argument)
+ {
+-  if (__builtin_expect (libgcc_s_handle == NULL, 0))
+-    pthread_cancel_init ();
+-  else
+-    atomic_read_barrier ();
++  _maybe_pthread_cancel_init ();
+ 
+   _Unwind_Reason_Code (*forcedunwind)
+     (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *)
+@@ -135,10 +148,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exc
+ _Unwind_Word
+ _Unwind_GetCFA (struct _Unwind_Context *context)
+ {
+-  if (__builtin_expect (libgcc_s_handle == NULL, 0))
+-    pthread_cancel_init ();
+-  else
+-    atomic_read_barrier ();
++  _maybe_pthread_cancel_init ();
+ 
+   _Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa;
+   PTR_DEMANGLE (getcfa);
+diff -pruN a/sysdeps/gnu/unwind-resume.c b/sysdeps/gnu/unwind-resume.c
+--- a/sysdeps/gnu/unwind-resume.c	2010-05-04 16:57:23.000000000 +0530
++++ b/sysdeps/gnu/unwind-resume.c	2014-06-02 23:02:26.812007078 +0530
+@@ -20,8 +20,11 @@
+ #include <dlfcn.h>
+ #include <stdio.h>
+ #include <unwind.h>
++#include <pthreadP.h>
++#include <sysdep.h>
+ #include <gnu/lib-names.h>
+ 
++static void *libgcc_s_handle;
+ static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
+ static _Unwind_Reason_Code (*libgcc_s_personality)
+   (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+@@ -42,13 +45,32 @@ init (void)
+ 
+   libgcc_s_resume = resume;
+   libgcc_s_personality = personality;
++  atomic_write_barrier ();
++  /* At the point at which any thread writes the handle
++     to libgcc_s_handle, the initialization is complete.
++     The writing of libgcc_s_handle is atomic. All other
++     threads reading libgcc_s_handle do so atomically. Any
++     thread that does not execute this function must issue
++     a read barrier to ensure that all of the above has
++     actually completed and that the values of the
++     function pointers are correct.   */
++  libgcc_s_handle = handle;
+ }
+ 
++static __always_inline void
++_maybe_init (void)
++{
++  if (__builtin_expect (libgcc_s_handle == NULL, 0))
++    init ();
++  else
++    atomic_read_barrier ();
++}
++
++
+ void
+ _Unwind_Resume (struct _Unwind_Exception *exc)
+ {
+-  if (__builtin_expect (libgcc_s_resume == NULL, 0))
+-    init ();
++  _maybe_init ();
+   libgcc_s_resume (exc);
+ }
+ 
+@@ -58,8 +80,7 @@ __gcc_personality_v0 (int version, _Unwi
+                       struct _Unwind_Exception *ue_header,
+                       struct _Unwind_Context *context)
+ {
+-  if (__builtin_expect (libgcc_s_personality == NULL, 0))
+-    init ();
++  _maybe_init ();
+   return libgcc_s_personality (version, actions, exception_class,
+ 			       ue_header, context);
+ }
diff --git a/SOURCES/glibc-rh1120490-int128.patch b/SOURCES/glibc-rh1120490-int128.patch
new file mode 100644
index 0000000..00fcc7b
--- /dev/null
+++ b/SOURCES/glibc-rh1120490-int128.patch
@@ -0,0 +1,60 @@
+Upstream patches to allow older compilers to use link.h:
+
+commit 30477995dc8a680283b4d6e02039bca09de83cf9
+Author: Marko Myllynen <myllynen@redhat.com>
+Date:   Fri May 30 10:50:21 2014 -0700
+
+    Replace __int128 with __int128_t
+    
+        * sysdeps/x86_64/link-defines.sym (BND_SIZE): Replace __int128
+        with __int128_t.
+
+commit 48332d822090e41253692053a00dfe224d3ebec0
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Fri Apr 25 09:33:41 2014 -0700
+
+    Replace __int128 with __int128_t in bits/link.h
+    
+    __int128 was added in GCC 4.6 and __int128_t was added before x86-64
+    was supported.  This patch replaces __int128 with __int128_t so that
+    the installed bits/link.h can be used with older GCC.
+    
+        * sysdeps/x86/bits/link.h (La_x86_64_regs): Replace __int128
+        with __int128_t.
+        (La_x86_64_retval): Likewise.
+
+diff -urN glibc-2.17-c758a686/sysdeps/x86/bits/link.h glibc-2.17-c758a686.mod/sysdeps/x86/bits/link.h
+--- glibc-2.17-c758a686/sysdeps/x86/bits/link.h	2014-11-05 13:39:09.888988366 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/x86/bits/link.h	2014-11-05 13:39:52.800863646 -0500
+@@ -94,7 +94,7 @@
+   La_x86_64_xmm lr_xmm[8];
+   La_x86_64_vector lr_vector[8];
+ #ifndef __ILP32__
+-  __int128 lr_bnd[4];
++  __int128_t lr_bnd[4];
+ #endif
+ } La_x86_64_regs;
+ 
+@@ -110,8 +110,8 @@
+   La_x86_64_vector lrv_vector0;
+   La_x86_64_vector lrv_vector1;
+ #ifndef __ILP32__
+-  __int128 lrv_bnd0;
+-  __int128 lrv_bnd1;
++  __int128_t lrv_bnd0;
++  __int128_t lrv_bnd1;
+ #endif
+ } La_x86_64_retval;
+ 
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym glibc-2.17-c758a686.mod/sysdeps/x86_64/link-defines.sym
+--- glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym	2014-11-05 13:39:09.889988363 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/x86_64/link-defines.sym	2014-11-05 13:39:52.800863646 -0500
+@@ -6,7 +6,7 @@
+ XMM_SIZE		sizeof (La_x86_64_xmm)
+ YMM_SIZE		sizeof (La_x86_64_ymm)
+ ZMM_SIZE		sizeof (La_x86_64_zmm)
+-BND_SIZE		sizeof (__int128)
++BND_SIZE		sizeof (__int128_t)
+ 
+ LR_SIZE			sizeof (struct La_x86_64_regs)
+ LR_RDX_OFFSET		offsetof (struct La_x86_64_regs, lr_rdx)
diff --git a/SOURCES/glibc-rh1120490.patch b/SOURCES/glibc-rh1120490.patch
new file mode 100644
index 0000000..0e911c8
--- /dev/null
+++ b/SOURCES/glibc-rh1120490.patch
@@ -0,0 +1,190 @@
+commit d0df3cfd9ffa32b85abae180127dc2a57db51f03
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Tue Sep 16 21:57:25 2014 +0530
+
+    Make __extern_always_inline usable on clang++ again
+    
+    The fix for BZ #17266 (884ddc5081278f488ef8cd49951f41cfdbb480ce)
+    removed changes that had gone into cdefs.h to make
+    __extern_always_inline usable with clang++.  This patch adds back
+    support for clang to detect if GNU inlining semantics are available,
+    this time without breaking the gcc use case.  The check put here is
+    based on the earlier patch and assertion[1] that checking if
+    __GNUC_STDC_INLINE__ or __GNUC_GNU_INLINE__ is defined is sufficient
+    to determine that clang++ suports GNU inlining semantics.
+    
+    Tested with a simple program that builds with __extern_always_inline
+    with the patch and fails compilation without it.
+    
+     #include <stdio.h>
+     #include <sys/cdefs.h>
+    
+    extern void foo_alias (void) __asm ("foo");
+    
+    __extern_always_inline void
+    foo (void)
+    {
+      puts ("hi oh world!");
+      return foo_alias ();
+    }
+    
+    void
+    foo_alias (void)
+    {
+      puts ("hell oh world");
+    }
+    
+    int
+    main ()
+    {
+      foo ();
+    }
+    
+    [1] https://sourceware.org/ml/libc-alpha/2012-12/msg00306.html
+    
+    	[BZ #17266]
+    	* misc/sys/cdefs.h: Define __extern_always_inline for clang
+    	4.2 and newer.
+
+commit 884ddc5081278f488ef8cd49951f41cfdbb480ce
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Tue Sep 16 14:08:48 2014 +0530
+
+    Revert to defining __extern_inline only for gcc-4.3+ (BZ #17266)
+    
+    The check for only __GNUC_STDC_INLINE__ and __GNUC_GNU_INLINE__ may
+    not be sufficient since those flags were added during initial support
+    for C99 inlining semantics.  There is also a problem with always
+    defining __extern_inline and __extern_always_inline, since it enables
+    inline wrapper functions even when GNU inlining semantics are not
+    guaranteed.  This, along with the possibility of such wrappers using
+    redirection (btowc for example) could result in compiler generating an
+    infinitely recusrive call to the function.
+    
+    In fact it was such a recursion that led to this code being written
+    the way it was; see:
+    
+    https://bugzilla.redhat.com/show_bug.cgi?id=186410
+    
+    The initial change was to fix bugs 14530 and 13741, but they can be
+    resolved by checking if __fortify_function and/or
+    __extern_always_inline are defined, as it has been done in this patch.
+    In addition, I have audited uses of __extern_always_inline to make
+    sure that none of the uses result in compilation errors.
+    
+    There is however a regression in this patch for llvm, since it reverts
+    the llvm expectation that __GNUC_STDC_INLINE__ or __GNUC_GNU_INLINE__
+    definition imply proper extern inline semantics.
+    
+    2014-09-16  Siddhesh Poyarekar  <siddhesh@redhat.com>
+    	    Jakub Jelinek  <jakub@redhat.com>
+    
+    	[BZ #17266]
+    	* libio/stdio.h: Check definition of __fortify_function
+    	instead of __extern_always_inline to include bits/stdio2.h.
+    	* math/bits/math-finite.h [__USE_XOPEN || __USE_ISOC99]: Also
+    	check if __extern_always_inline is defined.
+    	[__USE_MISC || __USE_XOPEN]: Likewise.
+    	[__USE_ISOC99] Likewise.
+    	* misc/sys/cdefs.h (__fortify_function): Define only if
+    	__extern_always_inline is defined.
+    	[!__cplusplus || __GNUC_PREREQ (4,3)]: Revert to defining
+    	__extern_always_inline and __extern_inline only for g++-4.3
+    	and newer or a compatible gcc.
+
+diff --git a/libio/stdio.h b/libio/stdio.h
+index d8c0bdb..1f4f837 100644
+--- a/libio/stdio.h
++++ b/libio/stdio.h
+@@ -932,7 +932,7 @@ extern void funlockfile (FILE *__stream) __THROW;
+ #ifdef __USE_EXTERN_INLINES
+ # include <bits/stdio.h>
+ #endif
+-#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
++#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
+ # include <bits/stdio2.h>
+ #endif
+ #ifdef __LDBL_COMPAT
+diff --git a/math/bits/math-finite.h b/math/bits/math-finite.h
+index aa755de..0656645 100644
+--- a/math/bits/math-finite.h
++++ b/math/bits/math-finite.h
+@@ -251,7 +251,8 @@ extern long double __REDIRECT_NTH (lgammal_r, (long double, int *),
+ # endif
+ #endif
+ 
+-#if defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99
++#if ((defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99) \
++     && defined __extern_always_inline)
+ /* lgamma.  */
+ __extern_always_inline double __NTH (lgamma (double __d))
+ {
+@@ -284,7 +285,8 @@ __extern_always_inline long double __NTH (lgammal (long double __d))
+ # endif
+ #endif
+ 
+-#if defined __USE_MISC || defined __USE_XOPEN
++#if ((defined __USE_MISC || defined __USE_XOPEN) \
++     && defined __extern_always_inline)
+ /* gamma.  */
+ __extern_always_inline double __NTH (gamma (double __d))
+ {
+@@ -422,7 +424,7 @@ extern long double __REDIRECT_NTH (sqrtl, (long double), __sqrtl_finite);
+ # endif
+ #endif
+ 
+-#ifdef __USE_ISOC99
++#if defined __USE_ISOC99 && defined __extern_always_inline
+ /* tgamma.  */
+ extern double __gamma_r_finite (double, int *);
+ __extern_always_inline double __NTH (tgamma (double __d))
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index 04db956..01e81ba 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -131,7 +131,6 @@
+ /* Fortify support.  */
+ #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
+ #define __bos0(ptr) __builtin_object_size (ptr, 0)
+-#define __fortify_function __extern_always_inline __attribute_artificial__
+ 
+ #if __GNUC_PREREQ (4,3)
+ # define __warndecl(name, msg) \
+@@ -319,8 +318,17 @@
+ #endif
+ 
+ /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+-   inline semantics, unless -fgnu89-inline is used.  */
+-#if (!defined __cplusplus || __GNUC_PREREQ (4,3)) && defined __GNUC__
++   inline semantics, unless -fgnu89-inline is used.  Using __GNUC_STDC_INLINE__
++   or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions
++   older than 4.3 may define these macros and still not guarantee GNU inlining
++   semantics.
++
++   clang++ identifies itself as gcc-4.2, but has support for GNU inlining
++   semantics, that can be checked fot by using the __GNUC_STDC_INLINE_ and
++   __GNUC_GNU_INLINE__ macro definitions.  */
++#if (!defined __cplusplus || __GNUC_PREREQ (4,3) \
++     || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \
++			       || defined __GNUC_GNU_INLINE__)))
+ # if defined __GNUC_STDC_INLINE__ || defined __cplusplus
+ #  define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
+ #  define __extern_always_inline \
+@@ -329,13 +337,10 @@
+ #  define __extern_inline extern __inline
+ #  define __extern_always_inline extern __always_inline
+ # endif
+-#elif defined __GNUC__ /* C++ and GCC <4.3.  */
+-# define __extern_inline extern __inline
+-# define __extern_always_inline \
+-  extern __always_inline
+-#else /* Not GCC.  */
+-# define __extern_inline  /* Ignore */
+-# define __extern_always_inline /* Ignore */
++#endif
++
++#ifdef __extern_always_inline
++# define __fortify_function __extern_always_inline __attribute_artificial__
+ #endif
+ 
+ /* GCC 4.3 and above allow passing all anonymous arguments of an
diff --git a/SOURCES/glibc-rh1125306.patch b/SOURCES/glibc-rh1125306.patch
new file mode 100644
index 0000000..4d07f4e
--- /dev/null
+++ b/SOURCES/glibc-rh1125306.patch
@@ -0,0 +1,20 @@
+commit a11892631d92f594c690d0d50a642b0d1aba58b8
+Author: Ondřej Bílka <neleai@seznam.cz>
+Date:   Wed May 7 14:08:57 2014 +0200
+
+    Fix typo in nscd/selinux.c
+
+diff --git a/nscd/selinux.c b/nscd/selinux.c
+index 9a8a5a8..eaed6dd 100644
+--- a/nscd/selinux.c
++++ b/nscd/selinux.c
+@@ -372,7 +372,7 @@ nscd_request_avc_has_perm (int fd, request_type req)
+   /* Get the security class for nscd.  If this fails we will likely be
+      unable to do anything unless avc_deny_unknown is 0.  */
+-  if ((sc_nscd = string_to_security_class ("nscd")) == 0
+-      && avc_deny_unknown == 1)
++  sc_nscd = string_to_security_class ("nscd");
++  if (sc_nscd == 0 && avc_deny_unknown == 1)
+     dbg_log (_("Error getting security class for nscd."));
+ 
+   /* Convert permission to AVC bits.  */
diff --git a/SOURCES/glibc-rh1132518-mpx.patch b/SOURCES/glibc-rh1132518-mpx.patch
new file mode 100644
index 0000000..b240ff1
--- /dev/null
+++ b/SOURCES/glibc-rh1132518-mpx.patch
@@ -0,0 +1,386 @@
+# MPX Support for glibc:
+#
+# Note: Renamed configure.ac changes to configure.in changes.
+#
+# commit ea8ba7cd14d0f479bae8365ae5c4ef177bdd0aad
+# Author: Igor Zamyatin <igor.zamyatin@intel.com>
+# Date:   Wed Apr 16 14:43:16 2014 -0700
+# 
+#     Save/restore bound registers for _dl_runtime_profile
+# 
+#     This patch saves and restores bound registers in x86-64 PLT for
+#     ld.so profile and LD_AUDIT:
+# 
+#         * sysdeps/x86_64/bits/link.h (La_x86_64_regs): Add lr_bnd.
+#         (La_x86_64_retval): Add lrv_bnd0 and lrv_bnd1.
+#         * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Save
+#         Intel MPX bound registers before _dl_profile_fixup.
+#         * sysdeps/x86_64/dl-trampoline.h: Restore Intel MPX bound
+#         registers after _dl_profile_fixup.  Save and restore bound
+#         registers bnd0/bnd1 when calling _dl_call_pltexit.
+#         * sysdeps/x86_64/link-defines.sym (BND_SIZE): New.
+#         (LR_BND_OFFSET): Likewise.
+#         (LRV_BND0_OFFSET): Likewise.
+#         (LRV_BND1_OFFSET): Likewise.
+# 
+# commit a4c75cfd56e536c2b18556e8a482d88dffa0fffc
+# Author: Igor Zamyatin <igor.zamyatin@intel.com>
+# Date:   Tue Apr 1 10:16:04 2014 -0700
+# 
+#     Save/restore bound registers in _dl_runtime_resolve
+# 
+#     This patch saves and restores bound registers in symbol lookup for x86-64:
+# 
+#     1. Branches without BND prefix clear bound registers.
+#     2. x86-64 pass bounds in bound registers as specified in MPX psABI
+#     extension on hjl/mpx/master branch at
+# 
+#     https://github.com/hjl-tools/x86-64-psABI
+#     https://groups.google.com/forum/#!topic/x86-64-abi/KFsB0XTgWYc
+# 
+#     Binutils has been updated to create an alternate PLT to add BND prefix
+#     when branching to ld.so.
+# 
+#         * config.h.in (HAVE_MPX_SUPPORT): New #undef.
+#         * sysdeps/x86_64/configure.ac: Set HAVE_MPX_SUPPORT.
+#         * sysdeps/x86_64/configure: Regenerated.
+#         * sysdeps/x86_64/dl-trampoline.S (REGISTER_SAVE_AREA): New
+#         macro.
+#         (REGISTER_SAVE_RAX): Likewise.
+#         (REGISTER_SAVE_RCX): Likewise.
+#         (REGISTER_SAVE_RDX): Likewise.
+#         (REGISTER_SAVE_RSI): Likewise.
+#         (REGISTER_SAVE_RDI): Likewise.
+#         (REGISTER_SAVE_R8): Likewise.
+#         (REGISTER_SAVE_R9): Likewise.
+#         (REGISTER_SAVE_BND0): Likewise.
+#         (REGISTER_SAVE_BND1): Likewise.
+#         (REGISTER_SAVE_BND2): Likewise.
+#         (_dl_runtime_resolve): Use them.  Save and restore Intel MPX
+#         bound registers when calling _dl_fixup.
+# 
+diff -urN glibc-2.17-c758a686/config.h.in glibc-2.17-c758a686.mod/config.h.in
+--- glibc-2.17-c758a686/config.h.in	2014-09-10 23:26:03.467045808 -0400
++++ glibc-2.17-c758a686.mod/config.h.in	2014-09-10 23:27:41.532851928 -0400
+@@ -107,6 +107,9 @@
+ /* Define if assembler supports AVX512.  */
+ #undef  HAVE_AVX512_ASM_SUPPORT
+ 
++/* Define if assembler supports Intel MPX.  */
++#undef  HAVE_MPX_SUPPORT
++
+ /* Define if gcc supports FMA4.  */
+ #undef	HAVE_FMA4_SUPPORT
+ 
+diff -urN glibc-2.17-c758a686/sysdeps/x86/bits/link.h glibc-2.17-c758a686.mod/sysdeps/x86/bits/link.h
+--- glibc-2.17-c758a686/sysdeps/x86/bits/link.h	2014-09-10 23:26:03.467045808 -0400
++++ glibc-2.17-c758a686.mod/sysdeps/x86/bits/link.h	2014-09-10 23:27:41.533851926 -0400
+@@ -93,6 +93,9 @@
+   uint64_t lr_rsp;
+   La_x86_64_xmm lr_xmm[8];
+   La_x86_64_vector lr_vector[8];
++#ifndef __ILP32__
++  __int128 lr_bnd[4];
++#endif
+ } La_x86_64_regs;
+ 
+ /* Return values for calls from PLT on x86-64.  */
+@@ -106,6 +109,10 @@
+   long double lrv_st1;
+   La_x86_64_vector lrv_vector0;
+   La_x86_64_vector lrv_vector1;
++#ifndef __ILP32__
++  __int128 lrv_bnd0;
++  __int128 lrv_bnd1;
++#endif
+ } La_x86_64_retval;
+ 
+ #define La_x32_regs La_x86_64_regs
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure glibc-2.17-c758a686.mod/sysdeps/x86_64/configure
+--- glibc-2.17-c758a686/sysdeps/x86_64/configure	2014-09-10 23:26:03.573045598 -0400
++++ glibc-2.17-c758a686.mod/sysdeps/x86_64/configure	2014-09-10 23:27:41.532851928 -0400
+@@ -212,6 +212,33 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_novzeroupper" >&5
+ $as_echo "$libc_cv_cc_novzeroupper" >&6; }
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Intel MPX support" >&5
++$as_echo_n "checking for Intel MPX support... " >&6; }
++if ${libc_cv_asm_mpx+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat > conftest.s <<\EOF
++        bndmov %bnd0,(%rsp)
++EOF
++if { ac_try='${CC-cc} -c $ASFLAGS conftest.s 1>&5'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then
++  libc_cv_asm_mpx=yes
++else
++  libc_cv_asm_mpx=no
++fi
++rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_mpx" >&5
++$as_echo "$libc_cv_asm_mpx" >&6; }
++if test $libc_cv_asm_mpx == yes; then
++  $as_echo "#define HAVE_MPX_SUPPORT 1" >>confdefs.h
++
++fi
++
+ $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+ 
+ # work around problem with autoconf and empty lines at the end of files
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure.in glibc-2.17-c758a686.mod/sysdeps/x86_64/configure.in
+--- glibc-2.17-c758a686/sysdeps/x86_64/configure.in	2014-09-10 23:26:03.468045806 -0400
++++ glibc-2.17-c758a686.mod/sysdeps/x86_64/configure.in	2014-09-10 23:27:41.532851928 -0400
+@@ -70,6 +70,21 @@
+ 		   [libc_cv_cc_novzeroupper=no])
+ ])
+ 
++dnl Check whether asm supports Intel MPX
++AC_CACHE_CHECK(for Intel MPX support, libc_cv_asm_mpx, [dnl
++cat > conftest.s <<\EOF
++        bndmov %bnd0,(%rsp)
++EOF
++if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
++  libc_cv_asm_mpx=yes
++else
++  libc_cv_asm_mpx=no
++fi
++rm -f conftest*])
++if test $libc_cv_asm_mpx == yes; then
++  AC_DEFINE(HAVE_MPX_SUPPORT)
++fi
++
+ dnl It is always possible to access static and hidden symbols in an
+ dnl position independent way.
+ AC_DEFINE(PI_STATIC_AND_HIDDEN)
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h glibc-2.17-c758a686.mod/sysdeps/x86_64/dl-trampoline.h
+--- glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h	2014-09-10 23:26:03.468045806 -0400
++++ glibc-2.17-c758a686.mod/sysdeps/x86_64/dl-trampoline.h	2014-09-10 23:27:41.535851922 -0400
+@@ -63,6 +63,20 @@
+ 	movaps (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp), %xmm6
+ 	movaps (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp), %xmm7
+ 
++#ifndef __ILP32__
++# ifdef HAVE_MPX_SUPPORT
++	bndmov 		    (LR_BND_OFFSET)(%rsp), %bnd0  # Restore bound
++	bndmov (LR_BND_OFFSET +   BND_SIZE)(%rsp), %bnd1  # registers.
++	bndmov (LR_BND_OFFSET + BND_SIZE*2)(%rsp), %bnd2
++	bndmov (LR_BND_OFFSET + BND_SIZE*3)(%rsp), %bnd3
++# else
++	.byte 0x66,0x0f,0x1a,0x84,0x24;.long (LR_BND_OFFSET)
++	.byte 0x66,0x0f,0x1a,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE)
++	.byte 0x66,0x0f,0x1a,0x94,0x24;.long (LR_BND_OFFSET + BND_SIZE*2)
++	.byte 0x66,0x0f,0x1a,0x9c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3)
++# endif
++#endif
++
+ #ifdef RESTORE_AVX
+ 	/* Check if any xmm0-xmm7 registers are changed by audit
+ 	   module.  */
+@@ -222,6 +236,16 @@
+ 	vmovdqa %xmm1, (LRV_SIZE + XMM_SIZE)(%rcx)
+ #endif
+ 
++#ifndef __ILP32__
++# ifdef HAVE_MPX_SUPPORT
++	bndmov %bnd0, LRV_BND0_OFFSET(%rcx)  # Preserve returned bounds.
++	bndmov %bnd1, LRV_BND1_OFFSET(%rcx)
++# else
++	.byte  0x66,0x0f,0x1b,0x81;.long (LRV_BND0_OFFSET)
++	.byte  0x66,0x0f,0x1b,0x89;.long (LRV_BND1_OFFSET)
++# endif
++#endif
++
+ 	fstpt LRV_ST0_OFFSET(%rcx)
+ 	fstpt LRV_ST1_OFFSET(%rcx)
+ 
+@@ -254,6 +278,16 @@
+ 1:
+ #endif
+ 
++#ifndef __ILP32__
++# ifdef HAVE_MPX_SUPPORT
++	bndmov LRV_BND0_OFFSET(%rcx), %bnd0  # Restore bound registers.
++	bndmov LRV_BND1_OFFSET(%rcx), %bnd1
++# else
++	.byte  0x66,0x0f,0x1a,0x81;.long (LRV_BND0_OFFSET)
++	.byte  0x66,0x0f,0x1a,0x89;.long (LRV_BND1_OFFSET)
++# endif
++#endif
++
+ 	fldt LRV_ST1_OFFSET(%rsp)
+ 	fldt LRV_ST0_OFFSET(%rsp)
+ 
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S glibc-2.17-c758a686.mod/sysdeps/x86_64/dl-trampoline.S
+--- glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S	2014-09-10 23:26:03.468045806 -0400
++++ glibc-2.17-c758a686.mod/sysdeps/x86_64/dl-trampoline.S	2014-09-10 23:27:41.534851924 -0400
+@@ -24,6 +24,30 @@
+ # error RTLD_SAVESPACE_SSE must be aligned to 32 bytes
+ #endif
+ 
++/* Area on stack to save and restore registers used for parameter
++   passing when calling _dl_fixup.  */
++#ifdef __ILP32__
++/* X32 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX.  */
++# define REGISTER_SAVE_AREA	(8 * 7)
++# define REGISTER_SAVE_RAX	0
++#else
++/* X86-64 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as BND0,
++   BND1, BND2, BND3.  */
++# define REGISTER_SAVE_AREA	(8 * 7 + 16 * 4)
++/* Align bound register save area to 16 bytes.  */
++# define REGISTER_SAVE_BND0	0
++# define REGISTER_SAVE_BND1	(REGISTER_SAVE_BND0 + 16)
++# define REGISTER_SAVE_BND2	(REGISTER_SAVE_BND1 + 16)
++# define REGISTER_SAVE_BND3	(REGISTER_SAVE_BND2 + 16)
++# define REGISTER_SAVE_RAX	(REGISTER_SAVE_BND3 + 16)
++#endif
++#define REGISTER_SAVE_RCX	(REGISTER_SAVE_RAX + 8)
++#define REGISTER_SAVE_RDX	(REGISTER_SAVE_RCX + 8)
++#define REGISTER_SAVE_RSI	(REGISTER_SAVE_RDX + 8)
++#define REGISTER_SAVE_RDI	(REGISTER_SAVE_RSI + 8)
++#define REGISTER_SAVE_R8	(REGISTER_SAVE_RDI + 8)
++#define REGISTER_SAVE_R9	(REGISTER_SAVE_R8 + 8)
++
+ 	.text
+ 	.globl _dl_runtime_resolve
+ 	.type _dl_runtime_resolve, @function
+@@ -31,28 +55,63 @@
+ 	cfi_startproc
+ _dl_runtime_resolve:
+ 	cfi_adjust_cfa_offset(16) # Incorporate PLT
+-	subq $56,%rsp
+-	cfi_adjust_cfa_offset(56)
+-	movq %rax,(%rsp)	# Preserve registers otherwise clobbered.
+-	movq %rcx, 8(%rsp)
+-	movq %rdx, 16(%rsp)
+-	movq %rsi, 24(%rsp)
+-	movq %rdi, 32(%rsp)
+-	movq %r8, 40(%rsp)
+-	movq %r9, 48(%rsp)
+-	movq 64(%rsp), %rsi	# Copy args pushed by PLT in register.
+-	movq 56(%rsp), %rdi	# %rdi: link_map, %rsi: reloc_index
++	subq $REGISTER_SAVE_AREA,%rsp
++	cfi_adjust_cfa_offset(REGISTER_SAVE_AREA)
++	# Preserve registers otherwise clobbered.
++	movq %rax, REGISTER_SAVE_RAX(%rsp)
++	movq %rcx, REGISTER_SAVE_RCX(%rsp)
++	movq %rdx, REGISTER_SAVE_RDX(%rsp)
++	movq %rsi, REGISTER_SAVE_RSI(%rsp)
++	movq %rdi, REGISTER_SAVE_RDI(%rsp)
++	movq %r8, REGISTER_SAVE_R8(%rsp)
++	movq %r9, REGISTER_SAVE_R9(%rsp)
++#ifndef __ILP32__
++	# We also have to preserve bound registers.  These are nops if
++	# Intel MPX isn't available or disabled.
++# ifdef HAVE_MPX_SUPPORT
++	bndmov %bnd0, REGISTER_SAVE_BND0(%rsp)
++	bndmov %bnd1, REGISTER_SAVE_BND1(%rsp)
++	bndmov %bnd2, REGISTER_SAVE_BND2(%rsp)
++	bndmov %bnd3, REGISTER_SAVE_BND3(%rsp)
++# else
++	.byte 0x66,0x0f,0x1b,0x44,0x24,REGISTER_SAVE_BND0
++	.byte 0x66,0x0f,0x1b,0x4c,0x24,REGISTER_SAVE_BND1
++	.byte 0x66,0x0f,0x1b,0x54,0x24,REGISTER_SAVE_BND2
++	.byte 0x66,0x0f,0x1b,0x5c,0x24,REGISTER_SAVE_BND3
++# endif
++#endif
++	# Copy args pushed by PLT in register.
++	# %rdi: link_map, %rsi: reloc_index
++	movq (REGISTER_SAVE_AREA + 8)(%rsp), %rsi
++	movq REGISTER_SAVE_AREA(%rsp), %rdi
+ 	call _dl_fixup		# Call resolver.
+ 	movq %rax, %r11		# Save return value
+-	movq 48(%rsp), %r9	# Get register content back.
+-	movq 40(%rsp), %r8
+-	movq 32(%rsp), %rdi
+-	movq 24(%rsp), %rsi
+-	movq 16(%rsp), %rdx
+-	movq 8(%rsp), %rcx
+-	movq (%rsp), %rax
+-	addq $72, %rsp		# Adjust stack(PLT did 2 pushes)
+-	cfi_adjust_cfa_offset(-72)
++#ifndef __ILP32__
++	# Restore bound registers.  These are nops if Intel MPX isn't
++	# avaiable or disabled.
++# ifdef HAVE_MPX_SUPPORT
++	bndmov REGISTER_SAVE_BND3(%rsp), %bnd3
++	bndmov REGISTER_SAVE_BND2(%rsp), %bnd2
++	bndmov REGISTER_SAVE_BND1(%rsp), %bnd1
++	bndmov REGISTER_SAVE_BND0(%rsp), %bnd0
++# else
++	.byte 0x66,0x0f,0x1a,0x5c,0x24,REGISTER_SAVE_BND3
++	.byte 0x66,0x0f,0x1a,0x54,0x24,REGISTER_SAVE_BND2
++	.byte 0x66,0x0f,0x1a,0x4c,0x24,REGISTER_SAVE_BND1
++	.byte 0x66,0x0f,0x1a,0x44,0x24,REGISTER_SAVE_BND0
++# endif
++#endif
++	# Get register content back.
++	movq REGISTER_SAVE_R9(%rsp), %r9
++	movq REGISTER_SAVE_R8(%rsp), %r8
++	movq REGISTER_SAVE_RDI(%rsp), %rdi
++	movq REGISTER_SAVE_RSI(%rsp), %rsi
++	movq REGISTER_SAVE_RDX(%rsp), %rdx
++	movq REGISTER_SAVE_RCX(%rsp), %rcx
++	movq REGISTER_SAVE_RAX(%rsp), %rax
++	# Adjust stack(PLT did 2 pushes)
++	addq $(REGISTER_SAVE_AREA + 16), %rsp
++	cfi_adjust_cfa_offset(-(REGISTER_SAVE_AREA + 16))
+ 	jmp *%r11		# Jump to function address.
+ 	cfi_endproc
+ 	.size _dl_runtime_resolve, .-_dl_runtime_resolve
+@@ -130,6 +189,20 @@
+ 	movaps %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp)
+ 	movaps %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp)
+ 
++# ifndef __ILP32__
++#  ifdef HAVE_MPX_SUPPORT
++	bndmov %bnd0, 		   (LR_BND_OFFSET)(%rsp)  # Preserve bound
++	bndmov %bnd1, (LR_BND_OFFSET +   BND_SIZE)(%rsp)  # registers. Nops if
++	bndmov %bnd2, (LR_BND_OFFSET + BND_SIZE*2)(%rsp)  # MPX not available
++	bndmov %bnd3, (LR_BND_OFFSET + BND_SIZE*3)(%rsp)  # or disabled.
++#  else
++	.byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET)
++	.byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE)
++	.byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET + BND_SIZE*2)
++	.byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3)
++#  endif
++# endif
++
+ # if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
+ 	.data
+ L(have_avx):
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym glibc-2.17-c758a686.mod/sysdeps/x86_64/link-defines.sym
+--- glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym	2014-09-10 23:26:03.468045806 -0400
++++ glibc-2.17-c758a686.mod/sysdeps/x86_64/link-defines.sym	2014-09-10 23:27:41.535851922 -0400
+@@ -6,6 +6,7 @@
+ XMM_SIZE		sizeof (La_x86_64_xmm)
+ YMM_SIZE		sizeof (La_x86_64_ymm)
+ ZMM_SIZE		sizeof (La_x86_64_zmm)
++BND_SIZE		sizeof (__int128)
+ 
+ LR_SIZE			sizeof (struct La_x86_64_regs)
+ LR_RDX_OFFSET		offsetof (struct La_x86_64_regs, lr_rdx)
+@@ -18,6 +19,9 @@
+ LR_RSP_OFFSET		offsetof (struct La_x86_64_regs, lr_rsp)
+ LR_XMM_OFFSET		offsetof (struct La_x86_64_regs, lr_xmm)
+ LR_VECTOR_OFFSET	offsetof (struct La_x86_64_regs, lr_vector)
++#ifndef __ILP32__
++LR_BND_OFFSET		offsetof (struct La_x86_64_regs, lr_bnd)
++#endif
+ 
+ LRV_SIZE		sizeof (struct La_x86_64_retval)
+ LRV_RAX_OFFSET		offsetof (struct La_x86_64_retval, lrv_rax)
+@@ -28,3 +32,7 @@
+ LRV_ST1_OFFSET		offsetof (struct La_x86_64_retval, lrv_st1)
+ LRV_VECTOR0_OFFSET	offsetof (struct La_x86_64_retval, lrv_vector0)
+ LRV_VECTOR1_OFFSET	offsetof (struct La_x86_64_retval, lrv_vector1)
++#ifndef __ILP32__
++LRV_BND0_OFFSET		offsetof (struct La_x86_64_retval, lrv_bnd0)
++LRV_BND1_OFFSET		offsetof (struct La_x86_64_retval, lrv_bnd1)
++#endif
diff --git a/SOURCES/glibc-rh1133811-1.patch b/SOURCES/glibc-rh1133811-1.patch
deleted file mode 100644
index 12b9949..0000000
--- a/SOURCES/glibc-rh1133811-1.patch
+++ /dev/null
@@ -1,199 +0,0 @@
-2014-08-21  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.
-
-diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
-index 1e25854..d71c029 100644
---- a/iconv/gconv_trans.c
-+++ b/iconv/gconv_trans.c
-@@ -238,181 +238,11 @@ __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;
-+  /* This function always fails.  Transliteration module loading is
-+     not implemented.  */
-+  return 1;
- }
--- 
-1.9.3
-
diff --git a/SOURCES/glibc-rh1133811-2.patch b/SOURCES/glibc-rh1133811-2.patch
deleted file mode 100644
index a82994f..0000000
--- a/SOURCES/glibc-rh1133811-2.patch
+++ /dev/null
@@ -1,631 +0,0 @@
-commit 585367266923156ac6fb789939a923641ba5aaf4
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Wed May 28 14:05:03 2014 +0200
-
-    manual: Update the locale documentation
-
-commit 4e8f95a0df7c2300b830ec12c0ae1e161bc8a8a3
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Mon May 12 15:24:12 2014 +0200
-
-    _nl_find_locale: Improve handling of crafted locale names [BZ #17137]
-    
-    Prevent directory traversal in locale-related environment variables
-    (CVE-2014-0475).
-
-commit d183645616b0533b3acee28f1a95570bffbdf50f
-Author: Florian Weimer <fweimer@redhat.com>
-Date:   Wed May 28 14:41:52 2014 +0200
-
-    setlocale: Use the heap for the copy of the locale argument
-    
-    This avoids alloca calls with potentially large arguments.
-
-diff -pruN glibc-2.18/locale/findlocale.c glibc-2.18.patched/locale/findlocale.c
---- glibc-2.18/locale/findlocale.c	2013-08-11 04:22:55.000000000 +0530
-+++ glibc-2.18.patched/locale/findlocale.c	2014-08-26 16:14:50.403253778 +0530
-@@ -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_
- 
- 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
- {
-   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
-   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 -pruN glibc-2.18/locale/setlocale.c glibc-2.18.patched/locale/setlocale.c
---- glibc-2.18/locale/setlocale.c	2013-08-11 04:22:55.000000000 +0530
-+++ glibc-2.18.patched/locale/setlocale.c	2014-08-26 16:14:50.401253764 +0530
-@@ -272,6 +272,8 @@ setlocale (int category, const char *loc
- 	 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 *loc
-       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 *loc
- 		{
- 		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 *loc
-       /* 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 -pruN glibc-2.18/localedata/Makefile glibc-2.18.patched/localedata/Makefile
---- glibc-2.18/localedata/Makefile	2014-08-26 16:15:22.656474571 +0530
-+++ glibc-2.18.patched/localedata/Makefile	2014-08-26 16:14:50.403253778 +0530
-@@ -77,7 +77,7 @@ locale_test_suite := tst_iswalnum tst_is
- 
- 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
- ifeq (yes,$(build-shared))
- ifneq (no,$(PERL))
- tests: $(objpfx)mtrace-tst-leaks
-diff -pruN glibc-2.18/localedata/tst-setlocale3.c glibc-2.18.patched/localedata/tst-setlocale3.c
---- glibc-2.18/localedata/tst-setlocale3.c	1970-01-01 05:30:00.000000000 +0530
-+++ glibc-2.18.patched/localedata/tst-setlocale3.c	2014-08-26 16:14:50.403253778 +0530
-@@ -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 -pruN glibc-2.18/manual/locale.texi glibc-2.18.patched/manual/locale.texi
---- glibc-2.18/manual/locale.texi	2013-08-11 04:22:55.000000000 +0530
-+++ glibc-2.18.patched/manual/locale.texi	2014-08-26 16:14:50.404253785 +0530
-@@ -29,6 +29,7 @@ will follow the conventions preferred by
- * Setting the Locale::          How a program specifies the locale
-                                  with library functions.
- * Standard Locales::            Locale names available on all systems.
-+* Locale Names::                Format of system-specific locale names.
- * Locale Information::          How to access the information for the locale.
- * Formatting Numbers::          A dedicated function to format numbers.
- * Yes-or-No Questions::         Check a Response against the locale.
-@@ -99,14 +100,16 @@ locale named @samp{espana-castellano} to
- most of Spain.
- 
- The set of locales supported depends on the operating system you are
--using, and so do their names.  We can't make any promises about what
--locales will exist, except for one standard locale called @samp{C} or
--@samp{POSIX}.  Later we will describe how to construct locales.
--@comment (@pxref{Building Locale Files}).
-+using, and so do their names, except that the standard locale called
-+@samp{C} or @samp{POSIX} always exist.  @xref{Locale Names}.
-+
-+In order to force the system to always use the default locale, the
-+user can set the @code{LC_ALL} environment variable to @samp{C}.
- 
- @cindex combining locales
--A user also has the option of specifying different locales for different
--purposes---in effect, choosing a mixture of multiple locales.
-+A user also has the option of specifying different locales for
-+different purposes---in effect, choosing a mixture of multiple
-+locales.  @xref{Locale Categories}.
- 
- For example, the user might specify the locale @samp{espana-castellano}
- for most purposes, but specify the locale @samp{usa-english} for
-@@ -120,7 +123,7 @@ which locales apply.  However, the user
- for a particular subset of those purposes.
- 
- @node Locale Categories, Setting the Locale, Choosing Locale, Locales
--@section Categories of Activities that Locales Affect
-+@section Locale Categories
- @cindex categories for locales
- @cindex locale categories
- 
-@@ -128,7 +131,11 @@ The purposes that locales serve are grou
- that a user or a program can choose the locale for each category
- independently.  Here is a table of categories; each name is both an
- environment variable that a user can set, and a macro name that you can
--use as an argument to @code{setlocale}.
-+use as the first argument to @code{setlocale}.
-+
-+The contents of the environment variable (or the string in the second
-+argument to @code{setlocale}) has to be a valid locale name.
-+@xref{Locale Names}.
- 
- @vtable @code
- @comment locale.h
-@@ -172,7 +179,7 @@ for affirmative and negative responses.
- @comment locale.h
- @comment ISO
- @item LC_ALL
--This is not an environment variable; it is only a macro that you can use
-+This is not a category; it is only a macro that you can use
- with @code{setlocale} to set a single locale for all purposes.  Setting
- this environment variable overwrites all selections by the other
- @code{LC_*} variables or @code{LANG}.
-@@ -225,13 +232,7 @@ The symbols in this section are defined
- @comment ISO
- @deftypefun {char *} setlocale (int @var{category}, const char *@var{locale})
- The function @code{setlocale} sets the current locale for category
--@var{category} to @var{locale}.  A list of all the locales the system
--provides can be created by running
--
--@pindex locale
--@smallexample
--  locale -a
--@end smallexample
-+@var{category} to @var{locale}.
- 
- If @var{category} is @code{LC_ALL}, this specifies the locale for all
- purposes.  The other possible values of @var{category} specify an
-@@ -256,10 +257,9 @@ is passed in as @var{locale} parameter.
- 
- When you read the current locale for category @code{LC_ALL}, the value
- encodes the entire combination of selected locales for all categories.
--In this case, the value is not just a single locale name.  In fact, we
--don't make any promises about what it looks like.  But if you specify
--the same ``locale name'' with @code{LC_ALL} in a subsequent call to
--@code{setlocale}, it restores the same combination of locale selections.
-+If you specify the same ``locale name'' with @code{LC_ALL} in a
-+subsequent call to @code{setlocale}, it restores the same combination
-+of locale selections.
- 
- To be sure you can use the returned string encoding the currently selected
- locale at a later time, you must make a copy of the string.  It is not
-@@ -275,20 +275,15 @@ for @var{category}.
- If a nonempty string is given for @var{locale}, then the locale of that
- name is used if possible.
- 
-+The effective locale name (either the second argument to
-+@code{setlocale}, or if the argument is an empty string, the name
-+obtained from the process environment) must be valid locale name.
-+@xref{Locale Names}.
-+
- If you specify an invalid locale name, @code{setlocale} returns a null
- pointer and leaves the current locale unchanged.
- @end deftypefun
- 
--The path used for finding locale data can be set using the
--@code{LOCPATH} environment variable. The default path for finding
--locale data is system specific.  It is computed from the value given
--as the prefix while configuring the C library.  This value normally is
--@file{/usr} or @file{/}.  For the former the complete path is:
--
--@smallexample
--/usr/lib/locale
--@end smallexample
--
- Here is an example showing how you might use @code{setlocale} to
- temporarily switch to a new locale.
- 
-@@ -328,7 +323,7 @@ locale categories, and future versions o
- portability, assume that any symbol beginning with @samp{LC_} might be
- defined in @file{locale.h}.
- 
--@node Standard Locales, Locale Information, Setting the Locale, Locales
-+@node Standard Locales, Locale Names, Setting the Locale, Locales
- @section Standard Locales
- 
- The only locale names you can count on finding on all operating systems
-@@ -362,7 +357,94 @@ with the environment, rather than trying
- locale explicitly by name.  Remember, different machines might have
- different sets of locales installed.
- 
--@node Locale Information, Formatting Numbers, Standard Locales, Locales
-+@node Locale Names, Locale Information, Standard Locales, Locales
-+@section Locale Names
-+
-+The following command prints a list of locales supported by the
-+system:
-+
-+@pindex locale
-+@smallexample
-+  locale -a
-+@end smallexample
-+
-+@strong{Portability Note:} With the notable exception of the standard
-+locale names @samp{C} and @samp{POSIX}, locale names are
-+system-specific.
-+
-+Most locale names follow XPG syntax and consist of up to four parts:
-+
-+@smallexample
-+@var{language}[_@var{territory}[.@var{codeset}]][@@@var{modifier}]
-+@end smallexample
-+
-+Beside the first part, all of them are allowed to be missing.  If the
-+full specified locale is not found, less specific ones are looked for.
-+The various parts will be stripped off, in the following order:
-+
-+@enumerate
-+@item
-+codeset
-+@item
-+normalized codeset
-+@item
-+territory
-+@item
-+modifier
-+@end enumerate
-+
-+For example, the locale name @samp{de_AT.iso885915@@euro} denotes a
-+German-language locale for use in Austria, using the ISO-8859-15
-+(Latin-9) character set, and with the Euro as the currency symbol.
-+
-+In addition to locale names which follow XPG syntax, systems may
-+provide aliases such as @samp{german}.  Both categories of names must
-+not contain the slash character @samp{/}.
-+
-+If the locale name starts with a slash @samp{/}, it is treated as a
-+path relative to the configured locale directories; see @code{LOCPATH}
-+below.  The specified path must not contain a component @samp{..}, or
-+the name is invalid, and @code{setlocale} will fail.
-+
-+@strong{Portability Note:} POSIX suggests that if a locale name starts
-+with a slash @samp{/}, it is resolved as an absolute path.  However,
-+@theglibc{} treats it as a relative path under the directories listed
-+in @code{LOCPATH} (or the default locale directory if @code{LOCPATH}
-+is unset).
-+
-+Locale names which are longer than an implementation-defined limit are
-+invalid and cause @code{setlocale} to fail.
-+
-+As a special case, locale names used with @code{LC_ALL} can combine
-+several locales, reflecting different locale settings for different
-+categories.  For example, you might want to use a U.S. locale with ISO
-+A4 paper format, so you set @code{LANG} to @samp{en_US.UTF-8}, and
-+@code{LC_PAPER} to @samp{de_DE.UTF-8}.  In this case, the
-+@code{LC_ALL}-style combined locale name is
-+
-+@smallexample
-+LC_CTYPE=en_US.UTF-8;LC_TIME=en_US.UTF-8;LC_PAPER=de_DE.UTF-8;@dots{}
-+@end smallexample
-+
-+followed by other category settings not shown here.
-+
-+@vindex LOCPATH
-+The path used for finding locale data can be set using the
-+@code{LOCPATH} environment variable.  This variable lists the
-+directories in which to search for locale definitions, separated by a
-+colon @samp{:}.
-+
-+The default path for finding locale data is system specific.  A typical
-+value for the @code{LOCPATH} default is:
-+
-+@smallexample
-+/usr/share/locale
-+@end smallexample
-+
-+The value of @code{LOCPATH} is ignored by privileged programs for
-+security reasons, and only the default directory is used.
-+
-+@node Locale Information, Formatting Numbers, Locale Names, Locales
- @section Accessing Locale Information
- 
- There are several ways to access locale information.  The simplest
diff --git a/SOURCES/glibc-rh1133811-3.patch b/SOURCES/glibc-rh1133811-3.patch
deleted file mode 100644
index 9ae2546..0000000
--- a/SOURCES/glibc-rh1133811-3.patch
+++ /dev/null
@@ -1,474 +0,0 @@
-commit 2bf1804182cc4bd671193587c8d5e3de45a9618e
-Author: Joseph Myers <joseph@codesourcery.com>
-Date:   Wed Jun 4 23:37:25 2014 +0000
-
-    Include LOCPATH in default test environment.
-    
-    Tests run using the default $(make-test-out) automatically get
-    GCONV_PATH and LC_ALL set, whether or not those environment variables
-    are actually needed for the individual test.  However, they do not get
-    LOCPATH set, meaning that a large number of tests have -ENV settings
-    just to set LOCPATH.
-    
-    This patch moves LOCPATH into the default environment used for all
-    tests, on the principle that like GCONV_PATH any settings needed to
-    use files associated with the newly built library, rather than any old
-    installed files, are appropriate to use by default.
-    
-    A further motivation is that various tests using .sh files also set
-    some combination of LC_ALL, GCONV_PATH and LOCPATH.  Preferably .sh
-    files should also use the default environment with any additions
-    required for the individual test.  Now, it was suggested in
-    <https://sourceware.org/ml/libc-alpha/2014-05/msg00715.html> that
-    various Makefile variables used in testing should be derived by
-    composing the -before-env and -after-env variables used when explicit
-    environment settings are required.  With such a change, it's also
-    natural for those variables to include the default settings (via some
-    intermediate makefile variable also used in make-test-out).
-    
-    Because some .sh files only set variables that correspond to the
-    default settings, or a subset thereof, and this applies to more of the
-    .sh files once LOCPATH is in the default settings, doing so reduces
-    the size of a revised version of
-    <https://sourceware.org/ml/libc-alpha/2014-05/msg00596.html>: scripts
-    only needing the (expanded) default settings will not need to receive
-    the separate -before-env and -after-env variables, only the single
-    variable they do at present.  So moving LOCPATH into the default
-    settings can reduce churn caused by subsequent patches.
-    
-    Tested x86_64 and x86.
-    
-    	* Rules (make-test-out): Include
-    	LOCPATH=$(common-objpfx)localedata in default environment.
-    	* debug/Makefile (tst-chk1-ENV): Remove variable.
-    	(tst-chk2-ENV): Likewise.
-    	(tst-chk3-ENV): Likewise.
-    	(tst-chk4-ENV): Likewise.
-    	(tst-chk5-ENV): Likewise.
-    	(tst-chk6-ENV): Likewise.
-    	(tst-lfschk1-ENV): Likewise.
-    	(tst-lfschk2-ENV): Likewise.
-    	(tst-lfschk3-ENV): Likewise.
-    	(tst-lfschk4-ENV): Likewise.
-    	(tst-lfschk5-ENV): Likewise.
-    	(tst-lfschk6-ENV): Likewise.
-    	* iconvdata/Makefile (bug-iconv6-ENV): Likewise.
-    	(tst-iconv7-ENV): Likewise.
-    	* intl/Makefile (LOCPATH-ENV): Likewise.
-    	(tst-codeset-ENV): Likewise.
-    	(tst-gettext3-ENV): Likewise.
-    	(tst-gettext5-ENV): Likewise.
-    	* libio/Makefile (tst-widetext-ENV): Don't set LOCPATH.
-    	(tst-fopenloc-ENV): Likewise.
-    	(tst-fgetws-ENV): Remove variable.
-    	(tst-ungetwc1-ENV): Likewise.
-    	(tst-ungetwc2-ENV): Likewise.
-    	(bug-ungetwc2-ENV): Likewise.
-    	(tst-swscanf-ENV): Likewise.
-    	(bug-ftell-ENV): Likewise.
-    	(tst-fgetwc-ENV): Likewise.
-    	(tst-fseek-ENV): Likewise.
-    	(tst-ftell-partial-wide-ENV): Likewise.
-    	(tst-ftell-active-handler-ENV): Likewise.
-    	(tst-ftell-append-ENV): Likewise.
-    	* posix/Makefile (tst-fnmatch-ENV): Likewise.
-    	(tst-regexloc-ENV): Likewise.
-    	(bug-regex1-ENV): Likewise.
-    	(tst-regex-ENV): Likewise.
-    	(tst-regex2-ENV): Likewise.
-    	(bug-regex5-ENV): Likewise.
-    	(bug-regex6-ENV): Likewise.
-    	(bug-regex17-ENV): Likewise.
-    	(bug-regex18-ENV): Likewise.
-    	(bug-regex19-ENV): Likewise.
-    	(bug-regex20-ENV): Likewise.
-    	(bug-regex22-ENV): Likewise.
-    	(bug-regex23-ENV): Likewise.
-    	(bug-regex25-ENV): Likewise.
-    	(bug-regex26-ENV): Likewise.
-    	(bug-regex30-ENV): Likewise.
-    	(bug-regex32-ENV): Likewise.
-    	(bug-regex33-ENV): Likewise.
-    	(bug-regex34-ENV): Likewise.
-    	(bug-regex35-ENV): Likewise.
-    	(tst-rxspencer-ENV): Likewise.
-    	(tst-rxspencer-no-utf8-ENV): Likewise.
-    	* stdio-common/Makefile (tst-sprintf-ENV): Likewise.
-    	(tst-sscanf-ENV): Likewise.
-    	(tst-swprintf-ENV): Likewise.
-    	(tst-swscanf-ENV): Likewise.
-    	(test-vfprintf-ENV): Likewise.
-    	(scanf13-ENV): Likewise.
-    	(bug14-ENV): Likewise.
-    	(tst-grouping-ENV): Likewise.
-    	* stdlib/Makefile (tst-strtod-ENV): Likewise.
-    	(tst-strtod3-ENV): Likewise.
-    	(tst-strtod4-ENV): Likewise.
-    	(tst-strtod5-ENV): Likewise.
-    	(testmb2-ENV): Likewise./
-    	* string/Makefile (tst-strxfrm-ENV): Likewise.
-    	(tst-strxfrm2-ENV): Likewise.
-    	(bug-strcoll1-ENV): Likewise.
-    	(test-strcasecmp-ENV): Likewise.
-    	(test-strncasecmp-ENV): Likewise.
-    	* time/Makefile (tst-strptime-ENV): Likewise.
-    	(tst-ftime_l-ENV): Likewise.
-    	* wcsmbs/Makefile (tst-btowc-ENV): Likewise.
-    	(tst-mbrtowc-ENV): Likewise.
-    	(tst-wcrtomb-ENV): Likewise.
-    	(tst-mbrtowc2-ENV): Likewise.
-    	(tst-c16c32-1-ENV): Likewise.
-    	(tst-mbsnrtowcs-ENV): Likewise.
-    
-    localedata/ChangeLog:
-    	* Makefile (TEST_MBWC_ENV): Remove variable.
-    	(tst_iswalnum-ENV): Likewise.
-    	(tst_iswalpha-ENV): Likewise.
-    	(tst_iswcntrl-ENV): Likewise.
-    	(tst_iswctype-ENV): Likewise.
-    	(tst_iswdigit-ENV): Likewise.
-    	(tst_iswgraph-ENV): Likewise.
-    	(tst_iswlower-ENV): Likewise.
-    	(tst_iswprint-ENV): Likewise.
-    	(tst_iswpunct-ENV): Likewise.
-    	(tst_iswspace-ENV): Likewise.
-    	(tst_iswupper-ENV): Likewise.
-    	(tst_iswxdigit-ENV): Likewise.
-    	(tst_mblen-ENV): Likewise.
-    	(tst_mbrlen-ENV): Likewise.
-    	(tst_mbrtowc-ENV): Likewise.
-    	(tst_mbsrtowcs-ENV): Likewise.
-    	(tst_mbstowcs-ENV): Likewise.
-    	(tst_mbtowc-ENV): Likewise.
-    	(tst_strcoll-ENV): Likewise.
-    	(tst_strfmon-ENV): Likewise.
-    	(tst_strxfrm-ENV): Likewise.
-    	(tst_swscanf-ENV): Likewise.
-    	(tst_towctrans-ENV): Likewise.
-    	(tst_towlower-ENV): Likewise.
-    	(tst_towupper-ENV): Likewise.
-    	(tst_wcrtomb-ENV): Likewise.
-    	(tst_wcscat-ENV): Likewise.
-    	(tst_wcschr-ENV): Likewise.
-    	(tst_wcscmp-ENV): Likewise.
-    	(tst_wcscoll-ENV): Likewise.
-    	(tst_wcscpy-ENV): Likewise.
-    	(tst_wcscspn-ENV): Likewise.
-    	(tst_wcslen-ENV): Likewise.
-    	(tst_wcsncat-ENV): Likewise.
-    	(tst_wcsncmp-ENV): Likewise.
-    	(tst_wcsncpy-ENV): Likewise.
-    	(tst_wcspbrk-ENV): Likewise.
-    	(tst_wcsrtombs-ENV): Likewise.
-    	(tst_wcsspn-ENV): Likewise.
-    	(tst_wcsstr-ENV): Likewise.
-    	(tst_wcstod-ENV): Likewise.
-    	(tst_wcstok-ENV): Likewise.
-    	(tst_wcstombs-ENV): Likewise.
-    	(tst_wcswidth-ENV): Likewise.
-    	(tst_wcsxfrm-ENV): Likewise.
-    	(tst_wctob-ENV): Likewise.
-    	(tst_wctomb-ENV): Likewise.
-    	(tst_wctrans-ENV): Likewise.
-    	(tst_wctype-ENV): Likewise.
-    	(tst_wcwidth-ENV): Likewise.
-    	(tst-digits-ENV): Likewise.
-    	(tst-mbswcs6-ENV): Likewise.
-    	(tst-xlocale1-ENV): Likewise.
-    	(tst-xlocale2-ENV): Likewise.
-    	(tst-strfmon1-ENV): Likewise.
-    	(tst-strptime-ENV): Likewise.
-    	(tst-setlocale-ENV): Don't set LOCPATH.
-    	(bug-iconv-trans-ENV): Remove variable.
-    	(tst-sscanf-ENV): Likewise.
-    	(tst-leaks-ENV): Don't set LOCPATH.
-    	(bug-setlocale1-ENV): Remove variable.
-    	(bug-setlocale1-static-ENV): Likewise.
-    	(tst-setlocale2-ENV): Likewise.
-
-diff --git a/Rules b/Rules
-index feb304d..9f1a445 100644
---- a/Rules
-+++ b/Rules
-@@ -191,7 +191,8 @@ ifneq "$(strip $(tests) $(xtests) $(test-srcs))" ""
- # from the test programs and whatever input files are present.
- 
- make-test-out = $(test-wrapper-env) \
--		GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
-+		GCONV_PATH=$(common-objpfx)iconvdata \
-+		LOCPATH=$(common-objpfx)localedata LC_ALL=C \
- 		$($*-ENV) $(host-built-program-cmd) $($*-ARGS)
- $(objpfx)%-bp.out: %.input $(objpfx)%-bp
- 	$(make-test-out) > $@ < $(word 1,$^)
-diff --git a/debug/Makefile b/debug/Makefile
-index b599a22..c284c51 100644
---- a/debug/Makefile
-+++ b/debug/Makefile
-@@ -109,18 +109,6 @@ CFLAGS-tst-lfschk3.c = -Wno-format
- CFLAGS-tst-lfschk4.cc = -Wno-format
- CFLAGS-tst-lfschk5.cc = -Wno-format
- CFLAGS-tst-lfschk6.cc = -Wno-format
--tst-chk1-ENV = LOCPATH=$(common-objpfx)localedata
--tst-chk2-ENV = LOCPATH=$(common-objpfx)localedata
--tst-chk3-ENV = LOCPATH=$(common-objpfx)localedata
--tst-chk4-ENV = LOCPATH=$(common-objpfx)localedata
--tst-chk5-ENV = LOCPATH=$(common-objpfx)localedata
--tst-chk6-ENV = LOCPATH=$(common-objpfx)localedata
--tst-lfschk1-ENV = LOCPATH=$(common-objpfx)localedata
--tst-lfschk2-ENV = LOCPATH=$(common-objpfx)localedata
--tst-lfschk3-ENV = LOCPATH=$(common-objpfx)localedata
--tst-lfschk4-ENV = LOCPATH=$(common-objpfx)localedata
--tst-lfschk5-ENV = LOCPATH=$(common-objpfx)localedata
--tst-lfschk6-ENV = LOCPATH=$(common-objpfx)localedata
- LDLIBS-tst-chk4 = -lstdc++
- LDLIBS-tst-chk5 = -lstdc++
- LDLIBS-tst-chk6 = -lstdc++
-diff --git a/iconvdata/Makefile b/iconvdata/Makefile
-index 074d330..d98b6bd 100644
---- a/iconvdata/Makefile
-+++ b/iconvdata/Makefile
-@@ -73,9 +73,6 @@ tests += bug-iconv3
- endif
- 
- test-srcs := tst-table-from tst-table-to
--
--bug-iconv6-ENV = LOCPATH=$(common-objpfx)localedata
--tst-iconv7-ENV = LOCPATH=$(common-objpfx)localedata
- endif
- 
- # No code here is in libc.so.
-diff --git a/intl/Makefile b/intl/Makefile
-index f11449d..10051f6 100644
---- a/intl/Makefile
-+++ b/intl/Makefile
-@@ -118,11 +118,6 @@ CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(objpfx)\"
- CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\"
- CFLAGS-tst-gettext6.c = -DOBJPFX=\"$(objpfx)\"
- 
--LOCPATH-ENV = LOCPATH=$(common-objpfx)localedata
--tst-codeset-ENV = $(LOCPATH-ENV)
--tst-gettext3-ENV = $(LOCPATH-ENV)
--tst-gettext5-ENV = $(LOCPATH-ENV)
--
- ifeq ($(have-thread-library),yes)
- ifeq (yes,$(build-shared))
- $(addprefix $(objpfx),$(multithread-test-srcs)): $(shared-thread-library)
-diff --git a/libio/Makefile b/libio/Makefile
-index b324ccc..4552360 100644
---- a/libio/Makefile
-+++ b/libio/Makefile
-@@ -148,17 +148,8 @@ CFLAGS-tst_putwc.c = -DOBJPFX=\"$(objpfx)\"
- 
- tst_wprintf2-ARGS = "Some Text"
- 
--tst-widetext-ENV = LOCPATH=$(common-objpfx)localedata LANGUAGE=C
--tst-fopenloc-ENV = LOCPATH=$(common-objpfx)localedata \
--		   MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
--tst-fgetws-ENV = LOCPATH=$(common-objpfx)localedata
--tst-ungetwc1-ENV = LOCPATH=$(common-objpfx)localedata
--tst-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata
--bug-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata
--tst-swscanf-ENV = LOCPATH=$(common-objpfx)localedata
--bug-ftell-ENV = LOCPATH=$(common-objpfx)localedata
--tst-fgetwc-ENV = LOCPATH=$(common-objpfx)localedata
--tst-fseek-ENV = LOCPATH=$(common-objpfx)localedata
-+tst-widetext-ENV = LANGUAGE=C
-+tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
- 
- generated = tst-fopenloc.mtrace tst-fopenloc.check
- 
-diff --git a/localedata/Makefile b/localedata/Makefile
-index d7ab445..20da00c 100644
---- a/localedata/Makefile
-+++ b/localedata/Makefile
-@@ -215,79 +215,13 @@
- 		     $(addprefix --prefix=,$(install_root)) $$locale; \
- 	echo ' done'; \
- 
--# The mbwc-tests need some environment setup to find the locale data files
--TEST_MBWC_ENV:= LOCPATH=$(common-objpfx)localedata
--tst_iswalnum-ENV = $(TEST_MBWC_ENV)
--tst_iswalpha-ENV = $(TEST_MBWC_ENV)
--tst_iswcntrl-ENV = $(TEST_MBWC_ENV)
--tst_iswctype-ENV = $(TEST_MBWC_ENV)
--tst_iswdigit-ENV = $(TEST_MBWC_ENV)
--tst_iswgraph-ENV = $(TEST_MBWC_ENV)
--tst_iswlower-ENV = $(TEST_MBWC_ENV)
--tst_iswprint-ENV = $(TEST_MBWC_ENV)
--tst_iswpunct-ENV = $(TEST_MBWC_ENV)
--tst_iswspace-ENV = $(TEST_MBWC_ENV)
--tst_iswupper-ENV = $(TEST_MBWC_ENV)
--tst_iswxdigit-ENV = $(TEST_MBWC_ENV)
--tst_mblen-ENV = $(TEST_MBWC_ENV)
--tst_mbrlen-ENV = $(TEST_MBWC_ENV)
--tst_mbrtowc-ENV = $(TEST_MBWC_ENV)
--tst_mbsrtowcs-ENV = $(TEST_MBWC_ENV)
--tst_mbstowcs-ENV = $(TEST_MBWC_ENV)
--tst_mbtowc-ENV = $(TEST_MBWC_ENV)
--tst_strcoll-ENV = $(TEST_MBWC_ENV)
--tst_strfmon-ENV = $(TEST_MBWC_ENV)
--tst_strxfrm-ENV = $(TEST_MBWC_ENV)
--tst_swscanf-ENV = $(TEST_MBWC_ENV)
--tst_towctrans-ENV = $(TEST_MBWC_ENV)
--tst_towlower-ENV = $(TEST_MBWC_ENV)
--tst_towupper-ENV = $(TEST_MBWC_ENV)
--tst_wcrtomb-ENV = $(TEST_MBWC_ENV)
--tst_wcscat-ENV = $(TEST_MBWC_ENV)
--tst_wcschr-ENV = $(TEST_MBWC_ENV)
--tst_wcscmp-ENV = $(TEST_MBWC_ENV)
--tst_wcscoll-ENV = $(TEST_MBWC_ENV)
--tst_wcscpy-ENV = $(TEST_MBWC_ENV)
--tst_wcscspn-ENV = $(TEST_MBWC_ENV)
--tst_wcslen-ENV = $(TEST_MBWC_ENV)
--tst_wcsncat-ENV = $(TEST_MBWC_ENV)
--tst_wcsncmp-ENV = $(TEST_MBWC_ENV)
--tst_wcsncpy-ENV = $(TEST_MBWC_ENV)
--tst_wcspbrk-ENV = $(TEST_MBWC_ENV)
--tst_wcsrtombs-ENV = $(TEST_MBWC_ENV)
--tst_wcsspn-ENV = $(TEST_MBWC_ENV)
--tst_wcsstr-ENV = $(TEST_MBWC_ENV)
--tst_wcstod-ENV = $(TEST_MBWC_ENV)
--tst_wcstok-ENV = $(TEST_MBWC_ENV)
--tst_wcstombs-ENV = $(TEST_MBWC_ENV)
--tst_wcswidth-ENV = $(TEST_MBWC_ENV)
--tst_wcsxfrm-ENV = $(TEST_MBWC_ENV)
--tst_wctob-ENV = $(TEST_MBWC_ENV)
--tst_wctomb-ENV = $(TEST_MBWC_ENV)
--tst_wctrans-ENV = $(TEST_MBWC_ENV)
--tst_wctype-ENV = $(TEST_MBWC_ENV)
--tst_wcwidth-ENV = $(TEST_MBWC_ENV)
--tst-digits-ENV = $(TEST_MBWC_ENV)
--tst-mbswcs6-ENV = $(TEST_MBWC_ENV)
--tst-xlocale1-ENV = $(TEST_MBWC_ENV)
--tst-xlocale2-ENV = $(TEST_MBWC_ENV)
--tst-strfmon1-ENV = $(TEST_MBWC_ENV)
--tst-strptime-ENV = $(TEST_MBWC_ENV)
-+tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP
- 
--tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-JP
--
--bug-iconv-trans-ENV = LOCPATH=$(common-objpfx)localedata
--
--tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata
--
--tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \
--		LOCPATH=$(common-objpfx)localedata
-+tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
- $(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out
- 	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@
- 
--bug-setlocale1-ENV = LOCPATH=$(common-objpfx)localedata
- bug-setlocale1-ARGS = $(common-objpfx)
--tst-setlocale2-ENV = LOCPATH=$(common-objpfx)localedata
- 
- $(objdir)/iconvdata/gconv-modules:
- 	$(MAKE) -C ../iconvdata subdir=iconvdata $@
-diff --git a/posix/Makefile b/posix/Makefile
-index 328c2c5..3d75971 100644
---- a/posix/Makefile
-+++ b/posix/Makefile
-@@ -203,27 +203,7 @@ tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir);
- tst-chmod-ARGS = $(objdir)
- tst-vfork3-ARGS = --test-dir=$(objpfx)
- 
--tst-fnmatch-ENV = LOCPATH=$(common-objpfx)localedata
--tst-regexloc-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex1-ENV = LOCPATH=$(common-objpfx)localedata
--tst-regex-ENV = LOCPATH=$(common-objpfx)localedata
--tst-regex2-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex5-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex6-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex17-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex18-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex19-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex20-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex22-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex23-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex25-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex26-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex30-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex32-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex33-ENV = LOCPATH=$(common-objpfx)localedata
--bug-regex34-ENV = LOCPATH=$(common-objpfx)localedata
- tst-rxspencer-ARGS = --utf8 rxspencer/tests
--tst-rxspencer-ENV = LOCPATH=$(common-objpfx)localedata
- tst-pcre-ARGS = PCRE.tests
- tst-boost-ARGS = BOOST.tests
- bug-glob1-ARGS = "$(objpfx)"
-diff --git a/stdio-common/Makefile b/stdio-common/Makefile
-index f179eab..5f8e534 100644
---- a/stdio-common/Makefile
-+++ b/stdio-common/Makefile
-@@ -118,13 +118,6 @@ CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \
- 
- # We know the test has a format string problem.
- CFLAGS-tst-sprintf.c = -Wno-format
--tst-sprintf-ENV = LOCPATH=$(common-objpfx)localedata
--tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata
--tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata
--test-vfprintf-ENV = LOCPATH=$(common-objpfx)localedata
--scanf13-ENV = LOCPATH=$(common-objpfx)localedata
--bug14-ENV = LOCPATH=$(common-objpfx)localedata
--tst-grouping-ENV = LOCPATH=$(common-objpfx)localedata
- 
- CPPFLAGS += $(libio-mtsafe)
- 
-diff --git a/stdlib/Makefile b/stdlib/Makefile
-index d7a562f..0fdf7cc 100644
---- a/stdlib/Makefile
-+++ b/stdlib/Makefile
-@@ -123,11 +123,6 @@ include ../Rules
- # Testdir has to be named stdlib and needs to be writable
- test-canon-ARGS = --test-dir=${common-objpfx}stdlib
- 
--tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata
--tst-strtod3-ENV = LOCPATH=$(common-objpfx)localedata
--tst-strtod4-ENV = LOCPATH=$(common-objpfx)localedata
--tst-strtod5-ENV = LOCPATH=$(common-objpfx)localedata
--testmb2-ENV = LOCPATH=$(common-objpfx)localedata
- bug-fmtmsg1-ENV = SEV_LEVEL=foo,11,newsev
- 
- # Run a test on the header files we use.
-diff --git a/string/Makefile b/string/Makefile
-index 5a76872..70b9c19 100644
---- a/string/Makefile
-+++ b/string/Makefile
-@@ -67,9 +67,6 @@ include ../Rules
- tester-ENV = LANGUAGE=C
- inl-tester-ENV = LANGUAGE=C
- noinl-tester-ENV = LANGUAGE=C
--tst-strxfrm-ENV = LOCPATH=$(common-objpfx)localedata
--tst-strxfrm2-ENV = LOCPATH=$(common-objpfx)localedata
--bug-strcoll1-ENV = LOCPATH=$(common-objpfx)localedata
- CFLAGS-inl-tester.c = -fno-builtin
- CFLAGS-noinl-tester.c = -fno-builtin
- CFLAGS-tst-strlen.c = -fno-builtin
-diff --git a/time/Makefile b/time/Makefile
-index b7f3dba..a07c041 100644
---- a/time/Makefile
-+++ b/time/Makefile
-@@ -55,7 +55,4 @@ CFLAGS-test_time.c = -Wno-format
- tst-getdate-ENV= DATEMSK=datemsk TZDIR=${common-objpfx}timezone/testdata
- test_time-ARGS= EST5EDT CST
- 
--tst-strptime-ENV = LOCPATH=${common-objpfx}localedata
--tst-ftime_l-ENV = LOCPATH=${common-objpfx}localedata
--
- bug-getdate1-ARGS = ${objpfx}bug-getdate1-fmt
-diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
-index 197ca7d..42843a6 100644
---- a/wcsmbs/Makefile
-+++ b/wcsmbs/Makefile
-@@ -80,10 +80,3 @@ CPPFLAGS += $(libio-mtsafe)
- 
- # We need to find the default version of strtold_l in stdlib.
- CPPFLAGS-wcstold_l.c = -I../stdlib
--
--tst-btowc-ENV = LOCPATH=$(common-objpfx)localedata
--tst-mbrtowc-ENV = LOCPATH=$(common-objpfx)localedata
--tst-wcrtomb-ENV = LOCPATH=$(common-objpfx)localedata
--tst-mbrtowc2-ENV = LOCPATH=$(common-objpfx)localedata
--tst-c16c32-1-ENV = LOCPATH=$(common-objpfx)localedata
--tst-mbsnrtowcs-ENV = LOCPATH=$(common-objpfx)localedata
---- glibc-2.17-c758a686/localedata/Makefile	2014-08-26 21:38:56.564751630 +0530
-+++ glibc-2.17-c758a686/localedata/Makefile.new	2014-08-26 21:40:16.596223207 +0530
diff --git a/SOURCES/glibc-rh1133812-1.patch b/SOURCES/glibc-rh1133812-1.patch
new file mode 100644
index 0000000..12b9949
--- /dev/null
+++ b/SOURCES/glibc-rh1133812-1.patch
@@ -0,0 +1,199 @@
+2014-08-21  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.
+
+diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
+index 1e25854..d71c029 100644
+--- a/iconv/gconv_trans.c
++++ b/iconv/gconv_trans.c
+@@ -238,181 +238,11 @@ __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;
++  /* This function always fails.  Transliteration module loading is
++     not implemented.  */
++  return 1;
+ }
+-- 
+1.9.3
+
diff --git a/SOURCES/glibc-rh1133812-2.patch b/SOURCES/glibc-rh1133812-2.patch
new file mode 100644
index 0000000..a82994f
--- /dev/null
+++ b/SOURCES/glibc-rh1133812-2.patch
@@ -0,0 +1,631 @@
+commit 585367266923156ac6fb789939a923641ba5aaf4
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed May 28 14:05:03 2014 +0200
+
+    manual: Update the locale documentation
+
+commit 4e8f95a0df7c2300b830ec12c0ae1e161bc8a8a3
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon May 12 15:24:12 2014 +0200
+
+    _nl_find_locale: Improve handling of crafted locale names [BZ #17137]
+    
+    Prevent directory traversal in locale-related environment variables
+    (CVE-2014-0475).
+
+commit d183645616b0533b3acee28f1a95570bffbdf50f
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed May 28 14:41:52 2014 +0200
+
+    setlocale: Use the heap for the copy of the locale argument
+    
+    This avoids alloca calls with potentially large arguments.
+
+diff -pruN glibc-2.18/locale/findlocale.c glibc-2.18.patched/locale/findlocale.c
+--- glibc-2.18/locale/findlocale.c	2013-08-11 04:22:55.000000000 +0530
++++ glibc-2.18.patched/locale/findlocale.c	2014-08-26 16:14:50.403253778 +0530
+@@ -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_
+ 
+ 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
+ {
+   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
+   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 -pruN glibc-2.18/locale/setlocale.c glibc-2.18.patched/locale/setlocale.c
+--- glibc-2.18/locale/setlocale.c	2013-08-11 04:22:55.000000000 +0530
++++ glibc-2.18.patched/locale/setlocale.c	2014-08-26 16:14:50.401253764 +0530
+@@ -272,6 +272,8 @@ setlocale (int category, const char *loc
+ 	 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 *loc
+       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 *loc
+ 		{
+ 		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 *loc
+       /* 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 -pruN glibc-2.18/localedata/Makefile glibc-2.18.patched/localedata/Makefile
+--- glibc-2.18/localedata/Makefile	2014-08-26 16:15:22.656474571 +0530
++++ glibc-2.18.patched/localedata/Makefile	2014-08-26 16:14:50.403253778 +0530
+@@ -77,7 +77,7 @@ locale_test_suite := tst_iswalnum tst_is
+ 
+ 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
+ ifeq (yes,$(build-shared))
+ ifneq (no,$(PERL))
+ tests: $(objpfx)mtrace-tst-leaks
+diff -pruN glibc-2.18/localedata/tst-setlocale3.c glibc-2.18.patched/localedata/tst-setlocale3.c
+--- glibc-2.18/localedata/tst-setlocale3.c	1970-01-01 05:30:00.000000000 +0530
++++ glibc-2.18.patched/localedata/tst-setlocale3.c	2014-08-26 16:14:50.403253778 +0530
+@@ -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 -pruN glibc-2.18/manual/locale.texi glibc-2.18.patched/manual/locale.texi
+--- glibc-2.18/manual/locale.texi	2013-08-11 04:22:55.000000000 +0530
++++ glibc-2.18.patched/manual/locale.texi	2014-08-26 16:14:50.404253785 +0530
+@@ -29,6 +29,7 @@ will follow the conventions preferred by
+ * Setting the Locale::          How a program specifies the locale
+                                  with library functions.
+ * Standard Locales::            Locale names available on all systems.
++* Locale Names::                Format of system-specific locale names.
+ * Locale Information::          How to access the information for the locale.
+ * Formatting Numbers::          A dedicated function to format numbers.
+ * Yes-or-No Questions::         Check a Response against the locale.
+@@ -99,14 +100,16 @@ locale named @samp{espana-castellano} to
+ most of Spain.
+ 
+ The set of locales supported depends on the operating system you are
+-using, and so do their names.  We can't make any promises about what
+-locales will exist, except for one standard locale called @samp{C} or
+-@samp{POSIX}.  Later we will describe how to construct locales.
+-@comment (@pxref{Building Locale Files}).
++using, and so do their names, except that the standard locale called
++@samp{C} or @samp{POSIX} always exist.  @xref{Locale Names}.
++
++In order to force the system to always use the default locale, the
++user can set the @code{LC_ALL} environment variable to @samp{C}.
+ 
+ @cindex combining locales
+-A user also has the option of specifying different locales for different
+-purposes---in effect, choosing a mixture of multiple locales.
++A user also has the option of specifying different locales for
++different purposes---in effect, choosing a mixture of multiple
++locales.  @xref{Locale Categories}.
+ 
+ For example, the user might specify the locale @samp{espana-castellano}
+ for most purposes, but specify the locale @samp{usa-english} for
+@@ -120,7 +123,7 @@ which locales apply.  However, the user
+ for a particular subset of those purposes.
+ 
+ @node Locale Categories, Setting the Locale, Choosing Locale, Locales
+-@section Categories of Activities that Locales Affect
++@section Locale Categories
+ @cindex categories for locales
+ @cindex locale categories
+ 
+@@ -128,7 +131,11 @@ The purposes that locales serve are grou
+ that a user or a program can choose the locale for each category
+ independently.  Here is a table of categories; each name is both an
+ environment variable that a user can set, and a macro name that you can
+-use as an argument to @code{setlocale}.
++use as the first argument to @code{setlocale}.
++
++The contents of the environment variable (or the string in the second
++argument to @code{setlocale}) has to be a valid locale name.
++@xref{Locale Names}.
+ 
+ @vtable @code
+ @comment locale.h
+@@ -172,7 +179,7 @@ for affirmative and negative responses.
+ @comment locale.h
+ @comment ISO
+ @item LC_ALL
+-This is not an environment variable; it is only a macro that you can use
++This is not a category; it is only a macro that you can use
+ with @code{setlocale} to set a single locale for all purposes.  Setting
+ this environment variable overwrites all selections by the other
+ @code{LC_*} variables or @code{LANG}.
+@@ -225,13 +232,7 @@ The symbols in this section are defined
+ @comment ISO
+ @deftypefun {char *} setlocale (int @var{category}, const char *@var{locale})
+ The function @code{setlocale} sets the current locale for category
+-@var{category} to @var{locale}.  A list of all the locales the system
+-provides can be created by running
+-
+-@pindex locale
+-@smallexample
+-  locale -a
+-@end smallexample
++@var{category} to @var{locale}.
+ 
+ If @var{category} is @code{LC_ALL}, this specifies the locale for all
+ purposes.  The other possible values of @var{category} specify an
+@@ -256,10 +257,9 @@ is passed in as @var{locale} parameter.
+ 
+ When you read the current locale for category @code{LC_ALL}, the value
+ encodes the entire combination of selected locales for all categories.
+-In this case, the value is not just a single locale name.  In fact, we
+-don't make any promises about what it looks like.  But if you specify
+-the same ``locale name'' with @code{LC_ALL} in a subsequent call to
+-@code{setlocale}, it restores the same combination of locale selections.
++If you specify the same ``locale name'' with @code{LC_ALL} in a
++subsequent call to @code{setlocale}, it restores the same combination
++of locale selections.
+ 
+ To be sure you can use the returned string encoding the currently selected
+ locale at a later time, you must make a copy of the string.  It is not
+@@ -275,20 +275,15 @@ for @var{category}.
+ If a nonempty string is given for @var{locale}, then the locale of that
+ name is used if possible.
+ 
++The effective locale name (either the second argument to
++@code{setlocale}, or if the argument is an empty string, the name
++obtained from the process environment) must be valid locale name.
++@xref{Locale Names}.
++
+ If you specify an invalid locale name, @code{setlocale} returns a null
+ pointer and leaves the current locale unchanged.
+ @end deftypefun
+ 
+-The path used for finding locale data can be set using the
+-@code{LOCPATH} environment variable. The default path for finding
+-locale data is system specific.  It is computed from the value given
+-as the prefix while configuring the C library.  This value normally is
+-@file{/usr} or @file{/}.  For the former the complete path is:
+-
+-@smallexample
+-/usr/lib/locale
+-@end smallexample
+-
+ Here is an example showing how you might use @code{setlocale} to
+ temporarily switch to a new locale.
+ 
+@@ -328,7 +323,7 @@ locale categories, and future versions o
+ portability, assume that any symbol beginning with @samp{LC_} might be
+ defined in @file{locale.h}.
+ 
+-@node Standard Locales, Locale Information, Setting the Locale, Locales
++@node Standard Locales, Locale Names, Setting the Locale, Locales
+ @section Standard Locales
+ 
+ The only locale names you can count on finding on all operating systems
+@@ -362,7 +357,94 @@ with the environment, rather than trying
+ locale explicitly by name.  Remember, different machines might have
+ different sets of locales installed.
+ 
+-@node Locale Information, Formatting Numbers, Standard Locales, Locales
++@node Locale Names, Locale Information, Standard Locales, Locales
++@section Locale Names
++
++The following command prints a list of locales supported by the
++system:
++
++@pindex locale
++@smallexample
++  locale -a
++@end smallexample
++
++@strong{Portability Note:} With the notable exception of the standard
++locale names @samp{C} and @samp{POSIX}, locale names are
++system-specific.
++
++Most locale names follow XPG syntax and consist of up to four parts:
++
++@smallexample
++@var{language}[_@var{territory}[.@var{codeset}]][@@@var{modifier}]
++@end smallexample
++
++Beside the first part, all of them are allowed to be missing.  If the
++full specified locale is not found, less specific ones are looked for.
++The various parts will be stripped off, in the following order:
++
++@enumerate
++@item
++codeset
++@item
++normalized codeset
++@item
++territory
++@item
++modifier
++@end enumerate
++
++For example, the locale name @samp{de_AT.iso885915@@euro} denotes a
++German-language locale for use in Austria, using the ISO-8859-15
++(Latin-9) character set, and with the Euro as the currency symbol.
++
++In addition to locale names which follow XPG syntax, systems may
++provide aliases such as @samp{german}.  Both categories of names must
++not contain the slash character @samp{/}.
++
++If the locale name starts with a slash @samp{/}, it is treated as a
++path relative to the configured locale directories; see @code{LOCPATH}
++below.  The specified path must not contain a component @samp{..}, or
++the name is invalid, and @code{setlocale} will fail.
++
++@strong{Portability Note:} POSIX suggests that if a locale name starts
++with a slash @samp{/}, it is resolved as an absolute path.  However,
++@theglibc{} treats it as a relative path under the directories listed
++in @code{LOCPATH} (or the default locale directory if @code{LOCPATH}
++is unset).
++
++Locale names which are longer than an implementation-defined limit are
++invalid and cause @code{setlocale} to fail.
++
++As a special case, locale names used with @code{LC_ALL} can combine
++several locales, reflecting different locale settings for different
++categories.  For example, you might want to use a U.S. locale with ISO
++A4 paper format, so you set @code{LANG} to @samp{en_US.UTF-8}, and
++@code{LC_PAPER} to @samp{de_DE.UTF-8}.  In this case, the
++@code{LC_ALL}-style combined locale name is
++
++@smallexample
++LC_CTYPE=en_US.UTF-8;LC_TIME=en_US.UTF-8;LC_PAPER=de_DE.UTF-8;@dots{}
++@end smallexample
++
++followed by other category settings not shown here.
++
++@vindex LOCPATH
++The path used for finding locale data can be set using the
++@code{LOCPATH} environment variable.  This variable lists the
++directories in which to search for locale definitions, separated by a
++colon @samp{:}.
++
++The default path for finding locale data is system specific.  A typical
++value for the @code{LOCPATH} default is:
++
++@smallexample
++/usr/share/locale
++@end smallexample
++
++The value of @code{LOCPATH} is ignored by privileged programs for
++security reasons, and only the default directory is used.
++
++@node Locale Information, Formatting Numbers, Locale Names, Locales
+ @section Accessing Locale Information
+ 
+ There are several ways to access locale information.  The simplest
diff --git a/SOURCES/glibc-rh1133812-3.patch b/SOURCES/glibc-rh1133812-3.patch
new file mode 100644
index 0000000..9ae2546
--- /dev/null
+++ b/SOURCES/glibc-rh1133812-3.patch
@@ -0,0 +1,474 @@
+commit 2bf1804182cc4bd671193587c8d5e3de45a9618e
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Wed Jun 4 23:37:25 2014 +0000
+
+    Include LOCPATH in default test environment.
+    
+    Tests run using the default $(make-test-out) automatically get
+    GCONV_PATH and LC_ALL set, whether or not those environment variables
+    are actually needed for the individual test.  However, they do not get
+    LOCPATH set, meaning that a large number of tests have -ENV settings
+    just to set LOCPATH.
+    
+    This patch moves LOCPATH into the default environment used for all
+    tests, on the principle that like GCONV_PATH any settings needed to
+    use files associated with the newly built library, rather than any old
+    installed files, are appropriate to use by default.
+    
+    A further motivation is that various tests using .sh files also set
+    some combination of LC_ALL, GCONV_PATH and LOCPATH.  Preferably .sh
+    files should also use the default environment with any additions
+    required for the individual test.  Now, it was suggested in
+    <https://sourceware.org/ml/libc-alpha/2014-05/msg00715.html> that
+    various Makefile variables used in testing should be derived by
+    composing the -before-env and -after-env variables used when explicit
+    environment settings are required.  With such a change, it's also
+    natural for those variables to include the default settings (via some
+    intermediate makefile variable also used in make-test-out).
+    
+    Because some .sh files only set variables that correspond to the
+    default settings, or a subset thereof, and this applies to more of the
+    .sh files once LOCPATH is in the default settings, doing so reduces
+    the size of a revised version of
+    <https://sourceware.org/ml/libc-alpha/2014-05/msg00596.html>: scripts
+    only needing the (expanded) default settings will not need to receive
+    the separate -before-env and -after-env variables, only the single
+    variable they do at present.  So moving LOCPATH into the default
+    settings can reduce churn caused by subsequent patches.
+    
+    Tested x86_64 and x86.
+    
+    	* Rules (make-test-out): Include
+    	LOCPATH=$(common-objpfx)localedata in default environment.
+    	* debug/Makefile (tst-chk1-ENV): Remove variable.
+    	(tst-chk2-ENV): Likewise.
+    	(tst-chk3-ENV): Likewise.
+    	(tst-chk4-ENV): Likewise.
+    	(tst-chk5-ENV): Likewise.
+    	(tst-chk6-ENV): Likewise.
+    	(tst-lfschk1-ENV): Likewise.
+    	(tst-lfschk2-ENV): Likewise.
+    	(tst-lfschk3-ENV): Likewise.
+    	(tst-lfschk4-ENV): Likewise.
+    	(tst-lfschk5-ENV): Likewise.
+    	(tst-lfschk6-ENV): Likewise.
+    	* iconvdata/Makefile (bug-iconv6-ENV): Likewise.
+    	(tst-iconv7-ENV): Likewise.
+    	* intl/Makefile (LOCPATH-ENV): Likewise.
+    	(tst-codeset-ENV): Likewise.
+    	(tst-gettext3-ENV): Likewise.
+    	(tst-gettext5-ENV): Likewise.
+    	* libio/Makefile (tst-widetext-ENV): Don't set LOCPATH.
+    	(tst-fopenloc-ENV): Likewise.
+    	(tst-fgetws-ENV): Remove variable.
+    	(tst-ungetwc1-ENV): Likewise.
+    	(tst-ungetwc2-ENV): Likewise.
+    	(bug-ungetwc2-ENV): Likewise.
+    	(tst-swscanf-ENV): Likewise.
+    	(bug-ftell-ENV): Likewise.
+    	(tst-fgetwc-ENV): Likewise.
+    	(tst-fseek-ENV): Likewise.
+    	(tst-ftell-partial-wide-ENV): Likewise.
+    	(tst-ftell-active-handler-ENV): Likewise.
+    	(tst-ftell-append-ENV): Likewise.
+    	* posix/Makefile (tst-fnmatch-ENV): Likewise.
+    	(tst-regexloc-ENV): Likewise.
+    	(bug-regex1-ENV): Likewise.
+    	(tst-regex-ENV): Likewise.
+    	(tst-regex2-ENV): Likewise.
+    	(bug-regex5-ENV): Likewise.
+    	(bug-regex6-ENV): Likewise.
+    	(bug-regex17-ENV): Likewise.
+    	(bug-regex18-ENV): Likewise.
+    	(bug-regex19-ENV): Likewise.
+    	(bug-regex20-ENV): Likewise.
+    	(bug-regex22-ENV): Likewise.
+    	(bug-regex23-ENV): Likewise.
+    	(bug-regex25-ENV): Likewise.
+    	(bug-regex26-ENV): Likewise.
+    	(bug-regex30-ENV): Likewise.
+    	(bug-regex32-ENV): Likewise.
+    	(bug-regex33-ENV): Likewise.
+    	(bug-regex34-ENV): Likewise.
+    	(bug-regex35-ENV): Likewise.
+    	(tst-rxspencer-ENV): Likewise.
+    	(tst-rxspencer-no-utf8-ENV): Likewise.
+    	* stdio-common/Makefile (tst-sprintf-ENV): Likewise.
+    	(tst-sscanf-ENV): Likewise.
+    	(tst-swprintf-ENV): Likewise.
+    	(tst-swscanf-ENV): Likewise.
+    	(test-vfprintf-ENV): Likewise.
+    	(scanf13-ENV): Likewise.
+    	(bug14-ENV): Likewise.
+    	(tst-grouping-ENV): Likewise.
+    	* stdlib/Makefile (tst-strtod-ENV): Likewise.
+    	(tst-strtod3-ENV): Likewise.
+    	(tst-strtod4-ENV): Likewise.
+    	(tst-strtod5-ENV): Likewise.
+    	(testmb2-ENV): Likewise./
+    	* string/Makefile (tst-strxfrm-ENV): Likewise.
+    	(tst-strxfrm2-ENV): Likewise.
+    	(bug-strcoll1-ENV): Likewise.
+    	(test-strcasecmp-ENV): Likewise.
+    	(test-strncasecmp-ENV): Likewise.
+    	* time/Makefile (tst-strptime-ENV): Likewise.
+    	(tst-ftime_l-ENV): Likewise.
+    	* wcsmbs/Makefile (tst-btowc-ENV): Likewise.
+    	(tst-mbrtowc-ENV): Likewise.
+    	(tst-wcrtomb-ENV): Likewise.
+    	(tst-mbrtowc2-ENV): Likewise.
+    	(tst-c16c32-1-ENV): Likewise.
+    	(tst-mbsnrtowcs-ENV): Likewise.
+    
+    localedata/ChangeLog:
+    	* Makefile (TEST_MBWC_ENV): Remove variable.
+    	(tst_iswalnum-ENV): Likewise.
+    	(tst_iswalpha-ENV): Likewise.
+    	(tst_iswcntrl-ENV): Likewise.
+    	(tst_iswctype-ENV): Likewise.
+    	(tst_iswdigit-ENV): Likewise.
+    	(tst_iswgraph-ENV): Likewise.
+    	(tst_iswlower-ENV): Likewise.
+    	(tst_iswprint-ENV): Likewise.
+    	(tst_iswpunct-ENV): Likewise.
+    	(tst_iswspace-ENV): Likewise.
+    	(tst_iswupper-ENV): Likewise.
+    	(tst_iswxdigit-ENV): Likewise.
+    	(tst_mblen-ENV): Likewise.
+    	(tst_mbrlen-ENV): Likewise.
+    	(tst_mbrtowc-ENV): Likewise.
+    	(tst_mbsrtowcs-ENV): Likewise.
+    	(tst_mbstowcs-ENV): Likewise.
+    	(tst_mbtowc-ENV): Likewise.
+    	(tst_strcoll-ENV): Likewise.
+    	(tst_strfmon-ENV): Likewise.
+    	(tst_strxfrm-ENV): Likewise.
+    	(tst_swscanf-ENV): Likewise.
+    	(tst_towctrans-ENV): Likewise.
+    	(tst_towlower-ENV): Likewise.
+    	(tst_towupper-ENV): Likewise.
+    	(tst_wcrtomb-ENV): Likewise.
+    	(tst_wcscat-ENV): Likewise.
+    	(tst_wcschr-ENV): Likewise.
+    	(tst_wcscmp-ENV): Likewise.
+    	(tst_wcscoll-ENV): Likewise.
+    	(tst_wcscpy-ENV): Likewise.
+    	(tst_wcscspn-ENV): Likewise.
+    	(tst_wcslen-ENV): Likewise.
+    	(tst_wcsncat-ENV): Likewise.
+    	(tst_wcsncmp-ENV): Likewise.
+    	(tst_wcsncpy-ENV): Likewise.
+    	(tst_wcspbrk-ENV): Likewise.
+    	(tst_wcsrtombs-ENV): Likewise.
+    	(tst_wcsspn-ENV): Likewise.
+    	(tst_wcsstr-ENV): Likewise.
+    	(tst_wcstod-ENV): Likewise.
+    	(tst_wcstok-ENV): Likewise.
+    	(tst_wcstombs-ENV): Likewise.
+    	(tst_wcswidth-ENV): Likewise.
+    	(tst_wcsxfrm-ENV): Likewise.
+    	(tst_wctob-ENV): Likewise.
+    	(tst_wctomb-ENV): Likewise.
+    	(tst_wctrans-ENV): Likewise.
+    	(tst_wctype-ENV): Likewise.
+    	(tst_wcwidth-ENV): Likewise.
+    	(tst-digits-ENV): Likewise.
+    	(tst-mbswcs6-ENV): Likewise.
+    	(tst-xlocale1-ENV): Likewise.
+    	(tst-xlocale2-ENV): Likewise.
+    	(tst-strfmon1-ENV): Likewise.
+    	(tst-strptime-ENV): Likewise.
+    	(tst-setlocale-ENV): Don't set LOCPATH.
+    	(bug-iconv-trans-ENV): Remove variable.
+    	(tst-sscanf-ENV): Likewise.
+    	(tst-leaks-ENV): Don't set LOCPATH.
+    	(bug-setlocale1-ENV): Remove variable.
+    	(bug-setlocale1-static-ENV): Likewise.
+    	(tst-setlocale2-ENV): Likewise.
+
+diff --git a/Rules b/Rules
+index feb304d..9f1a445 100644
+--- a/Rules
++++ b/Rules
+@@ -191,7 +191,8 @@ ifneq "$(strip $(tests) $(xtests) $(test-srcs))" ""
+ # from the test programs and whatever input files are present.
+ 
+ make-test-out = $(test-wrapper-env) \
+-		GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
++		GCONV_PATH=$(common-objpfx)iconvdata \
++		LOCPATH=$(common-objpfx)localedata LC_ALL=C \
+ 		$($*-ENV) $(host-built-program-cmd) $($*-ARGS)
+ $(objpfx)%-bp.out: %.input $(objpfx)%-bp
+ 	$(make-test-out) > $@ < $(word 1,$^)
+diff --git a/debug/Makefile b/debug/Makefile
+index b599a22..c284c51 100644
+--- a/debug/Makefile
++++ b/debug/Makefile
+@@ -109,18 +109,6 @@ CFLAGS-tst-lfschk3.c = -Wno-format
+ CFLAGS-tst-lfschk4.cc = -Wno-format
+ CFLAGS-tst-lfschk5.cc = -Wno-format
+ CFLAGS-tst-lfschk6.cc = -Wno-format
+-tst-chk1-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-chk2-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-chk3-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-chk4-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-chk5-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-chk6-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-lfschk1-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-lfschk2-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-lfschk3-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-lfschk4-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-lfschk5-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-lfschk6-ENV = LOCPATH=$(common-objpfx)localedata
+ LDLIBS-tst-chk4 = -lstdc++
+ LDLIBS-tst-chk5 = -lstdc++
+ LDLIBS-tst-chk6 = -lstdc++
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index 074d330..d98b6bd 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -73,9 +73,6 @@ tests += bug-iconv3
+ endif
+ 
+ test-srcs := tst-table-from tst-table-to
+-
+-bug-iconv6-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-iconv7-ENV = LOCPATH=$(common-objpfx)localedata
+ endif
+ 
+ # No code here is in libc.so.
+diff --git a/intl/Makefile b/intl/Makefile
+index f11449d..10051f6 100644
+--- a/intl/Makefile
++++ b/intl/Makefile
+@@ -118,11 +118,6 @@ CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(objpfx)\"
+ CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\"
+ CFLAGS-tst-gettext6.c = -DOBJPFX=\"$(objpfx)\"
+ 
+-LOCPATH-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-codeset-ENV = $(LOCPATH-ENV)
+-tst-gettext3-ENV = $(LOCPATH-ENV)
+-tst-gettext5-ENV = $(LOCPATH-ENV)
+-
+ ifeq ($(have-thread-library),yes)
+ ifeq (yes,$(build-shared))
+ $(addprefix $(objpfx),$(multithread-test-srcs)): $(shared-thread-library)
+diff --git a/libio/Makefile b/libio/Makefile
+index b324ccc..4552360 100644
+--- a/libio/Makefile
++++ b/libio/Makefile
+@@ -148,17 +148,8 @@ CFLAGS-tst_putwc.c = -DOBJPFX=\"$(objpfx)\"
+ 
+ tst_wprintf2-ARGS = "Some Text"
+ 
+-tst-widetext-ENV = LOCPATH=$(common-objpfx)localedata LANGUAGE=C
+-tst-fopenloc-ENV = LOCPATH=$(common-objpfx)localedata \
+-		   MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
+-tst-fgetws-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-ungetwc1-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-swscanf-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-ftell-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-fgetwc-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-fseek-ENV = LOCPATH=$(common-objpfx)localedata
++tst-widetext-ENV = LANGUAGE=C
++tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
+ 
+ generated = tst-fopenloc.mtrace tst-fopenloc.check
+ 
+diff --git a/localedata/Makefile b/localedata/Makefile
+index d7ab445..20da00c 100644
+--- a/localedata/Makefile
++++ b/localedata/Makefile
+@@ -215,79 +215,13 @@
+ 		     $(addprefix --prefix=,$(install_root)) $$locale; \
+ 	echo ' done'; \
+ 
+-# The mbwc-tests need some environment setup to find the locale data files
+-TEST_MBWC_ENV:= LOCPATH=$(common-objpfx)localedata
+-tst_iswalnum-ENV = $(TEST_MBWC_ENV)
+-tst_iswalpha-ENV = $(TEST_MBWC_ENV)
+-tst_iswcntrl-ENV = $(TEST_MBWC_ENV)
+-tst_iswctype-ENV = $(TEST_MBWC_ENV)
+-tst_iswdigit-ENV = $(TEST_MBWC_ENV)
+-tst_iswgraph-ENV = $(TEST_MBWC_ENV)
+-tst_iswlower-ENV = $(TEST_MBWC_ENV)
+-tst_iswprint-ENV = $(TEST_MBWC_ENV)
+-tst_iswpunct-ENV = $(TEST_MBWC_ENV)
+-tst_iswspace-ENV = $(TEST_MBWC_ENV)
+-tst_iswupper-ENV = $(TEST_MBWC_ENV)
+-tst_iswxdigit-ENV = $(TEST_MBWC_ENV)
+-tst_mblen-ENV = $(TEST_MBWC_ENV)
+-tst_mbrlen-ENV = $(TEST_MBWC_ENV)
+-tst_mbrtowc-ENV = $(TEST_MBWC_ENV)
+-tst_mbsrtowcs-ENV = $(TEST_MBWC_ENV)
+-tst_mbstowcs-ENV = $(TEST_MBWC_ENV)
+-tst_mbtowc-ENV = $(TEST_MBWC_ENV)
+-tst_strcoll-ENV = $(TEST_MBWC_ENV)
+-tst_strfmon-ENV = $(TEST_MBWC_ENV)
+-tst_strxfrm-ENV = $(TEST_MBWC_ENV)
+-tst_swscanf-ENV = $(TEST_MBWC_ENV)
+-tst_towctrans-ENV = $(TEST_MBWC_ENV)
+-tst_towlower-ENV = $(TEST_MBWC_ENV)
+-tst_towupper-ENV = $(TEST_MBWC_ENV)
+-tst_wcrtomb-ENV = $(TEST_MBWC_ENV)
+-tst_wcscat-ENV = $(TEST_MBWC_ENV)
+-tst_wcschr-ENV = $(TEST_MBWC_ENV)
+-tst_wcscmp-ENV = $(TEST_MBWC_ENV)
+-tst_wcscoll-ENV = $(TEST_MBWC_ENV)
+-tst_wcscpy-ENV = $(TEST_MBWC_ENV)
+-tst_wcscspn-ENV = $(TEST_MBWC_ENV)
+-tst_wcslen-ENV = $(TEST_MBWC_ENV)
+-tst_wcsncat-ENV = $(TEST_MBWC_ENV)
+-tst_wcsncmp-ENV = $(TEST_MBWC_ENV)
+-tst_wcsncpy-ENV = $(TEST_MBWC_ENV)
+-tst_wcspbrk-ENV = $(TEST_MBWC_ENV)
+-tst_wcsrtombs-ENV = $(TEST_MBWC_ENV)
+-tst_wcsspn-ENV = $(TEST_MBWC_ENV)
+-tst_wcsstr-ENV = $(TEST_MBWC_ENV)
+-tst_wcstod-ENV = $(TEST_MBWC_ENV)
+-tst_wcstok-ENV = $(TEST_MBWC_ENV)
+-tst_wcstombs-ENV = $(TEST_MBWC_ENV)
+-tst_wcswidth-ENV = $(TEST_MBWC_ENV)
+-tst_wcsxfrm-ENV = $(TEST_MBWC_ENV)
+-tst_wctob-ENV = $(TEST_MBWC_ENV)
+-tst_wctomb-ENV = $(TEST_MBWC_ENV)
+-tst_wctrans-ENV = $(TEST_MBWC_ENV)
+-tst_wctype-ENV = $(TEST_MBWC_ENV)
+-tst_wcwidth-ENV = $(TEST_MBWC_ENV)
+-tst-digits-ENV = $(TEST_MBWC_ENV)
+-tst-mbswcs6-ENV = $(TEST_MBWC_ENV)
+-tst-xlocale1-ENV = $(TEST_MBWC_ENV)
+-tst-xlocale2-ENV = $(TEST_MBWC_ENV)
+-tst-strfmon1-ENV = $(TEST_MBWC_ENV)
+-tst-strptime-ENV = $(TEST_MBWC_ENV)
++tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP
+ 
+-tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-JP
+-
+-bug-iconv-trans-ENV = LOCPATH=$(common-objpfx)localedata
+-
+-tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata
+-
+-tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \
+-		LOCPATH=$(common-objpfx)localedata
++tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
+ $(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out
+ 	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@
+ 
+-bug-setlocale1-ENV = LOCPATH=$(common-objpfx)localedata
+ bug-setlocale1-ARGS = $(common-objpfx)
+-tst-setlocale2-ENV = LOCPATH=$(common-objpfx)localedata
+ 
+ $(objdir)/iconvdata/gconv-modules:
+ 	$(MAKE) -C ../iconvdata subdir=iconvdata $@
+diff --git a/posix/Makefile b/posix/Makefile
+index 328c2c5..3d75971 100644
+--- a/posix/Makefile
++++ b/posix/Makefile
+@@ -203,27 +203,7 @@ tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir);
+ tst-chmod-ARGS = $(objdir)
+ tst-vfork3-ARGS = --test-dir=$(objpfx)
+ 
+-tst-fnmatch-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-regexloc-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex1-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-regex-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-regex2-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex5-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex6-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex17-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex18-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex19-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex20-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex22-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex23-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex25-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex26-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex30-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex32-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex33-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-regex34-ENV = LOCPATH=$(common-objpfx)localedata
+ tst-rxspencer-ARGS = --utf8 rxspencer/tests
+-tst-rxspencer-ENV = LOCPATH=$(common-objpfx)localedata
+ tst-pcre-ARGS = PCRE.tests
+ tst-boost-ARGS = BOOST.tests
+ bug-glob1-ARGS = "$(objpfx)"
+diff --git a/stdio-common/Makefile b/stdio-common/Makefile
+index f179eab..5f8e534 100644
+--- a/stdio-common/Makefile
++++ b/stdio-common/Makefile
+@@ -118,13 +118,6 @@ CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \
+ 
+ # We know the test has a format string problem.
+ CFLAGS-tst-sprintf.c = -Wno-format
+-tst-sprintf-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata
+-test-vfprintf-ENV = LOCPATH=$(common-objpfx)localedata
+-scanf13-ENV = LOCPATH=$(common-objpfx)localedata
+-bug14-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-grouping-ENV = LOCPATH=$(common-objpfx)localedata
+ 
+ CPPFLAGS += $(libio-mtsafe)
+ 
+diff --git a/stdlib/Makefile b/stdlib/Makefile
+index d7a562f..0fdf7cc 100644
+--- a/stdlib/Makefile
++++ b/stdlib/Makefile
+@@ -123,11 +123,6 @@ include ../Rules
+ # Testdir has to be named stdlib and needs to be writable
+ test-canon-ARGS = --test-dir=${common-objpfx}stdlib
+ 
+-tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-strtod3-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-strtod4-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-strtod5-ENV = LOCPATH=$(common-objpfx)localedata
+-testmb2-ENV = LOCPATH=$(common-objpfx)localedata
+ bug-fmtmsg1-ENV = SEV_LEVEL=foo,11,newsev
+ 
+ # Run a test on the header files we use.
+diff --git a/string/Makefile b/string/Makefile
+index 5a76872..70b9c19 100644
+--- a/string/Makefile
++++ b/string/Makefile
+@@ -67,9 +67,6 @@ include ../Rules
+ tester-ENV = LANGUAGE=C
+ inl-tester-ENV = LANGUAGE=C
+ noinl-tester-ENV = LANGUAGE=C
+-tst-strxfrm-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-strxfrm2-ENV = LOCPATH=$(common-objpfx)localedata
+-bug-strcoll1-ENV = LOCPATH=$(common-objpfx)localedata
+ CFLAGS-inl-tester.c = -fno-builtin
+ CFLAGS-noinl-tester.c = -fno-builtin
+ CFLAGS-tst-strlen.c = -fno-builtin
+diff --git a/time/Makefile b/time/Makefile
+index b7f3dba..a07c041 100644
+--- a/time/Makefile
++++ b/time/Makefile
+@@ -55,7 +55,4 @@ CFLAGS-test_time.c = -Wno-format
+ tst-getdate-ENV= DATEMSK=datemsk TZDIR=${common-objpfx}timezone/testdata
+ test_time-ARGS= EST5EDT CST
+ 
+-tst-strptime-ENV = LOCPATH=${common-objpfx}localedata
+-tst-ftime_l-ENV = LOCPATH=${common-objpfx}localedata
+-
+ bug-getdate1-ARGS = ${objpfx}bug-getdate1-fmt
+diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
+index 197ca7d..42843a6 100644
+--- a/wcsmbs/Makefile
++++ b/wcsmbs/Makefile
+@@ -80,10 +80,3 @@ CPPFLAGS += $(libio-mtsafe)
+ 
+ # We need to find the default version of strtold_l in stdlib.
+ CPPFLAGS-wcstold_l.c = -I../stdlib
+-
+-tst-btowc-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-mbrtowc-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-wcrtomb-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-mbrtowc2-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-c16c32-1-ENV = LOCPATH=$(common-objpfx)localedata
+-tst-mbsnrtowcs-ENV = LOCPATH=$(common-objpfx)localedata
+--- glibc-2.17-c758a686/localedata/Makefile	2014-08-26 21:38:56.564751630 +0530
++++ glibc-2.17-c758a686/localedata/Makefile.new	2014-08-26 21:40:16.596223207 +0530
diff --git a/SOURCES/glibc-rh1138520.patch b/SOURCES/glibc-rh1138520.patch
new file mode 100644
index 0000000..affbe96
--- /dev/null
+++ b/SOURCES/glibc-rh1138520.patch
@@ -0,0 +1,145 @@
+commit af37a8a3496327a6e5617a2c76f17aa1e8db835e
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Mon Jan 27 11:32:44 2014 +0530
+
+    Avoid undefined behaviour in netgroupcache
+    
+    Using a buffer after it has been reallocated is undefined behaviour,
+    so get offsets of the triplets in the old buffer before reallocating
+    it.
+
+commit 5d41dadf31bc8a2f9c34c40d52a442d3794e405c
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Fri Jan 24 13:51:15 2014 +0530
+
+    Adjust pointers to triplets in netgroup query data (BZ #16474)
+    
+    The _nss_*_getnetgrent_r query populates the netgroup results in the
+    allocated buffer and then sets the result triplet to point to strings
+    in the buffer.  This is a problem when the buffer is reallocated since
+    the pointers to the triplet strings are no longer valid.  The pointers
+    need to be adjusted so that they now point to strings in the
+    reallocated buffer.
+
+commit 980cb5180e1b71224a57ca52b995c959b7148c09
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Thu Jan 16 10:20:22 2014 +0530
+
+    Don't use alloca in addgetnetgrentX (BZ #16453)
+
+    addgetnetgrentX has a buffer which is grown as per the needs of the
+    requested size either by using alloca or by falling back to malloc if
+    the size is larger than 1K.  There are two problems with the alloca
+    bits: firstly, it doesn't really extend the buffer since it does not
+    use the return value of the extend_alloca macro, which is the location
+    of the reallocated buffer.  Due to this the buffer does not actually
+    extend itself and hence a subsequent write may overwrite stuff on the
+    stack.
+
+    The second problem is more subtle - the buffer growth on the stack is
+    discontinuous due to block scope local variables.  Combine that with
+    the fact that unlike realloc, extend_alloca does not copy over old
+    content and you have a situation where the buffer just has garbage in
+    the space where it should have had data.
+
+    This could have been fixed by adding code to copy over old data
+    whenever we call extend_alloca, but it seems unnecessarily
+    complicated.  This code is not exactly a performance hotspot (it's
+    called when there is a cache miss, so factors like network lookup or
+    file reads will dominate over memory allocation/reallocation), so this
+    premature optimization is unnecessary.
+    
+    Thanks Brad Hubbard <bhubbard@redhat.com> for his help with debugging
+    the problem.
+
+diff -pruN glibc-2.12-2-gc4ccff1/nscd/netgroupcache.c glibc-2.12-2-gc4ccff1.patched/nscd/netgroupcache.c
+--- glibc-2.12-2-gc4ccff1/nscd/netgroupcache.c	2014-04-09 12:13:58.618582111 +0530
++++ glibc-2.12-2-gc4ccff1.patched/nscd/netgroupcache.c	2014-04-09 12:07:21.486598665 +0530
+@@ -93,7 +93,6 @@ addgetnetgrentX (struct database_dyn *db
+   size_t buffilled = sizeof (*dataset);
+   char *buffer = NULL;
+   size_t nentries = 0;
+-  bool use_malloc = false;
+   size_t group_len = strlen (key) + 1;
+   union
+   {
+@@ -138,7 +137,7 @@ addgetnetgrentX (struct database_dyn *db
+     }
+ 
+   memset (&data, '\0', sizeof (data));
+-  buffer = alloca (buflen);
++  buffer = xmalloc (buflen);
+   first_needed.elem.next = &first_needed.elem;
+   memcpy (first_needed.elem.name, key, group_len);
+   data.needed_groups = &first_needed.elem;
+@@ -218,21 +217,24 @@ addgetnetgrentX (struct database_dyn *db
+ 
+ 				if (buflen - req->key_len - bufused < needed)
+ 				  {
+-				    size_t newsize = MAX (2 * buflen,
+-							  buflen + 2 * needed);
+-				    if (use_malloc || newsize > 1024 * 1024)
+-				      {
+-					buflen = newsize;
+-					char *newbuf = xrealloc (use_malloc
+-								 ? buffer
+-								 : NULL,
+-								 buflen);
+-
+-					buffer = newbuf;
+-					use_malloc = true;
+-				      }
+-				    else
+-				      extend_alloca (buffer, buflen, newsize);
++				    buflen += MAX (buflen, 2 * needed);
++				    /* Save offset in the old buffer.  We don't
++				       bother with the NULL check here since
++				       we'll do that later anyway.  */
++				    size_t nhostdiff = nhost - buffer;
++				    size_t nuserdiff = nuser - buffer;
++				    size_t ndomaindiff = ndomain - buffer;
++
++				    char *newbuf = xrealloc (buffer, buflen);
++				    /* Fix up the triplet pointers into the new
++				       buffer.  */
++				    nhost = (nhost ? newbuf + nhostdiff
++					     : NULL);
++				    nuser = (nuser ? newbuf + nuserdiff
++					     : NULL);
++				    ndomain = (ndomain ? newbuf + ndomaindiff
++					       : NULL);
++				    buffer = newbuf;
+ 				  }
+ 
+ 				nhost = memcpy (buffer + bufused,
+@@ -299,18 +301,8 @@ addgetnetgrentX (struct database_dyn *db
+ 		      }
+ 		    else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
+ 		      {
+-			size_t newsize = 2 * buflen;
+-			if (use_malloc || newsize > 1024 * 1024)
+-			  {
+-			    buflen = newsize;
+-			    char *newbuf = xrealloc (use_malloc
+-						     ? buffer : NULL, buflen);
+-
+-			    buffer = newbuf;
+-			    use_malloc = true;
+-			  }
+-			else
+-			  extend_alloca (buffer, buflen, newsize);
++			buflen *= 2;
++			buffer = xrealloc (buffer, buflen);
+ 		      }
+ 		  }
+ 
+@@ -446,8 +438,7 @@ addgetnetgrentX (struct database_dyn *db
+     }
+ 
+  out:
+-  if (use_malloc)
+-    free (buffer);
++  free (buffer);
+ 
+   *resultp = dataset;
+ 
diff --git a/SOURCES/glibc-rh1140272-avx512.patch b/SOURCES/glibc-rh1140272-avx512.patch
new file mode 100644
index 0000000..aa41415
--- /dev/null
+++ b/SOURCES/glibc-rh1140272-avx512.patch
@@ -0,0 +1,1430 @@
+#
+# AVX-512 support for glibc:
+#
+# Notes: Renamed configure.ac changes to configure.in.
+#
+# commit aa4de9cea5c07d43caeaca9722c2d417e9a2919c
+# Author: H.J. Lu <hjl.tools@gmail.com>
+# Date:   Fri Mar 14 08:51:25 2014 -0700
+# 
+#     Check AVX-512 assembler support first
+# 
+#     It checks AVX-512 assembler support first and sets libc_cv_cc_avx512 to
+#     $libc_cv_asm_avx512, instead of yes.  GCC won't support AVX-512 if
+#     assembler doesn't support it.
+# 
+#         * sysdeps/x86_64/configure.ac: Check AVX-512 assembler support
+#         first.  Disable AVX-512 GCC support if assembler doesn't support
+#         it.
+#         * sysdeps/x86_64/configure: Regenerated.
+# 
+# commit 2d63a517e4084ec80403cd9f278690fa8b676cc4
+# Author: Igor Zamyatin <igor.zamyatin@intel.com>
+# Date:   Thu Mar 13 11:10:22 2014 -0700
+# 
+#     Save and restore AVX-512 zmm registers to x86-64 ld.so
+#     
+#     AVX-512 ISA adds 512-bit zmm registers.  This patch updates
+#     _dl_runtime_profile to pass zmm registers to run-time audit. It also
+#     changes _dl_x86_64_save_sse and _dl_x86_64_restore_sse to upport zmm
+#     registers, which are called when only when RTLD_PREPARE_FOREIGN_CALL
+#     is used.  Its performance impact is minimum.
+#     
+#         * config.h.in (HAVE_AVX512_SUPPORT): New #undef.
+#         (HAVE_AVX512_ASM_SUPPORT): Likewise.
+#         * sysdeps/x86_64/bits/link.h (La_x86_64_zmm): New.
+#         (La_x86_64_vector): Add zmm.
+#         * sysdeps/x86_64/Makefile (tests): Add tst-audit10.
+#         (modules-names): Add tst-auditmod10a and tst-auditmod10b.
+#         ($(objpfx)tst-audit10): New target.
+#         ($(objpfx)tst-audit10.out): Likewise.
+#         (tst-audit10-ENV): New.
+#         (AVX512-CFLAGS): Likewise.
+#         (CFLAGS-tst-audit10.c): Likewise.
+#         (CFLAGS-tst-auditmod10a.c): Likewise.
+#         (CFLAGS-tst-auditmod10b.c): Likewise.
+#         * sysdeps/x86_64/configure.ac: Set config-cflags-avx512,
+#         HAVE_AVX512_SUPPORT and HAVE_AVX512_ASM_SUPPORT.
+#         * sysdeps/x86_64/configure: Regenerated.
+#         * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Add
+#         AVX-512 zmm register support.
+#         (_dl_x86_64_save_sse): Likewise.
+#         (_dl_x86_64_restore_sse): Likewise.
+#         * sysdeps/x86_64/dl-trampoline.h: Updated to support different
+#         size vector registers.
+#         * sysdeps/x86_64/link-defines.sym (YMM_SIZE): New.
+#         (ZMM_SIZE): Likewise. 
+#         * sysdeps/x86_64/tst-audit10.c: New file.
+#         * sysdeps/x86_64/tst-auditmod10a.c: Likewise.
+#         * sysdeps/x86_64/tst-auditmod10b.c: Likewise.
+# 
+# In addition adds:
+# https://sourceware.org/ml/libc-alpha/2014-09/msg00228.html
+# To extend zmm register checking.
+#
+diff -urN glibc-2.17-c758a686/config.h.in glibc-2.17-c758a686.mod-mpx/config.h.in
+--- glibc-2.17-c758a686/config.h.in	2014-09-10 23:11:14.605787816 -0400
++++ glibc-2.17-c758a686.mod-mpx/config.h.in	2014-09-10 23:16:36.331167056 -0400
+@@ -101,6 +101,12 @@
+ /* Define if gcc supports VEX encoding.  */
+ #undef	HAVE_SSE2AVX_SUPPORT
+ 
++/* Define if compiler supports AVX512.  */
++#undef  HAVE_AVX512_SUPPORT
++
++/* Define if assembler supports AVX512.  */
++#undef  HAVE_AVX512_ASM_SUPPORT
++
+ /* Define if gcc supports FMA4.  */
+ #undef	HAVE_FMA4_SUPPORT
+ 
+diff -urN glibc-2.17-c758a686/sysdeps/x86/bits/link.h glibc-2.17-c758a686.mod-mpx/sysdeps/x86/bits/link.h
+--- glibc-2.17-c758a686/sysdeps/x86/bits/link.h	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86/bits/link.h	2014-09-10 23:16:36.331167056 -0400
+@@ -66,6 +66,8 @@
+ typedef float La_x86_64_xmm __attribute__ ((__vector_size__ (16)));
+ typedef float La_x86_64_ymm
+     __attribute__ ((__vector_size__ (32), __aligned__ (16)));
++typedef double La_x86_64_zmm
++    __attribute__ ((__vector_size__ (64), __aligned__ (16)));
+ # else
+ typedef float La_x86_64_xmm __attribute__ ((__mode__ (__V4SF__)));
+ # endif
+@@ -74,6 +76,7 @@
+ {
+ # if __GNUC_PREREQ (4,0)
+   La_x86_64_ymm ymm[2];
++  La_x86_64_zmm zmm[1];
+ # endif
+   La_x86_64_xmm xmm[4];
+ } La_x86_64_vector __attribute__ ((__aligned__ (16)));
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/configure
+--- glibc-2.17-c758a686/sysdeps/x86_64/configure	2014-09-10 23:11:15.000787061 -0400
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/configure	2014-09-10 23:16:36.338167042 -0400
+@@ -91,6 +91,59 @@
+ 
+ fi
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX512 support in assembler" >&5
++$as_echo_n "checking for AVX512 support in assembler... " >&6; }
++if ${libc_cv_asm_avx512+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat > conftest.s <<\EOF
++        vmovdqu64 %zmm0, (%rsp)
++EOF
++if { ac_try='${CC-cc} -c $ASFLAGS conftest.s 1>&5'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then
++  libc_cv_asm_avx512=yes
++else
++  libc_cv_asm_avx512=no
++fi
++rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_avx512" >&5
++$as_echo "$libc_cv_asm_avx512" >&6; }
++if test $libc_cv_asm_avx512 == yes; then
++  $as_echo "#define HAVE_AVX512_ASM_SUPPORT 1" >>confdefs.h
++
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX512 support" >&5
++$as_echo_n "checking for AVX512 support... " >&6; }
++if ${libc_cv_cc_avx512+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if { ac_try='${CC-cc} -mavx512f -xc /dev/null -S -o /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then :
++  libc_cv_cc_avx512=$libc_cv_asm_avx512
++else
++  libc_cv_cc_avx512=no
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_avx512" >&5
++$as_echo "$libc_cv_cc_avx512" >&6; }
++if test $libc_cv_cc_avx512 = yes; then
++  $as_echo "#define HAVE_AVX512_SUPPORT 1" >>confdefs.h
++
++fi
++config_vars="$config_vars
++config-cflags-avx512 = $libc_cv_cc_avx512"
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX encoding of SSE instructions" >&5
+ $as_echo_n "checking for AVX encoding of SSE instructions... " >&6; }
+ if ${libc_cv_cc_sse2avx+:} false; then :
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure.in glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/configure.in
+--- glibc-2.17-c758a686/sysdeps/x86_64/configure.in	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/configure.in	2014-09-10 23:16:36.338167042 -0400
+@@ -21,6 +21,30 @@
+   AC_DEFINE(HAVE_AVX_SUPPORT)
+ fi
+ 
++dnl Check if asm supports AVX512.
++AC_CACHE_CHECK(for AVX512 support in assembler, libc_cv_asm_avx512, [dnl
++cat > conftest.s <<\EOF
++        vmovdqu64 %zmm0, (%rsp)
++EOF
++if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
++  libc_cv_asm_avx512=yes
++else
++  libc_cv_asm_avx512=no
++fi
++rm -f conftest*])
++if test $libc_cv_asm_avx512 == yes; then
++  AC_DEFINE(HAVE_AVX512_ASM_SUPPORT)
++fi
++
++dnl Check if -mavx512f works.
++AC_CACHE_CHECK(for AVX512 support, libc_cv_cc_avx512, [dnl
++LIBC_TRY_CC_OPTION([-mavx512f], [libc_cv_cc_avx512=$libc_cv_asm_avx512], [libc_cv_cc_avx512=no])
++])
++if test $libc_cv_cc_avx512 = yes; then
++  AC_DEFINE(HAVE_AVX512_SUPPORT)
++fi
++LIBC_CONFIG_VAR([config-cflags-avx512], [$libc_cv_cc_avx512])
++
+ dnl Check if -msse2avx works.
+ AC_CACHE_CHECK(for AVX encoding of SSE instructions, libc_cv_cc_sse2avx, [dnl
+ LIBC_TRY_CC_OPTION([-msse2avx],
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure.in.orig glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/configure.in.orig
+--- glibc-2.17-c758a686/sysdeps/x86_64/configure.in.orig	1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/configure.in.orig	2014-09-10 23:16:28.418182701 -0400
+@@ -0,0 +1,52 @@
++GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
++# Local configure fragment for sysdeps/x86_64.
++
++AC_CHECK_HEADER([cpuid.h], ,
++  [AC_MSG_ERROR([gcc must provide the <cpuid.h> header])],
++  [/* No default includes.  */])
++
++dnl Check if -msse4 works.
++AC_CACHE_CHECK(for SSE4 support, libc_cv_cc_sse4, [dnl
++LIBC_TRY_CC_OPTION([-msse4], [libc_cv_cc_sse4=yes], [libc_cv_cc_sse4=no])
++])
++if test $libc_cv_cc_sse4 = yes; then
++  AC_DEFINE(HAVE_SSE4_SUPPORT)
++fi
++
++dnl Check if -mavx works.
++AC_CACHE_CHECK(for AVX support, libc_cv_cc_avx, [dnl
++LIBC_TRY_CC_OPTION([-mavx], [libc_cv_cc_avx=yes], [libc_cv_cc_avx=no])
++])
++if test $libc_cv_cc_avx = yes; then
++  AC_DEFINE(HAVE_AVX_SUPPORT)
++fi
++
++dnl Check if -msse2avx works.
++AC_CACHE_CHECK(for AVX encoding of SSE instructions, libc_cv_cc_sse2avx, [dnl
++LIBC_TRY_CC_OPTION([-msse2avx],
++		   [libc_cv_cc_sse2avx=yes],
++		   [libc_cv_cc_sse2avx=no])
++])
++if test $libc_cv_cc_sse2avx = yes; then
++  AC_DEFINE(HAVE_SSE2AVX_SUPPORT)
++fi
++
++dnl Check if -mfma4 works.
++AC_CACHE_CHECK(for FMA4 support, libc_cv_cc_fma4, [dnl
++LIBC_TRY_CC_OPTION([-mfma4], [libc_cv_cc_fma4=yes], [libc_cv_cc_fma4=no])
++])
++if test $libc_cv_cc_fma4 = yes; then
++  AC_DEFINE(HAVE_FMA4_SUPPORT)
++fi
++
++dnl Check if -mno-vzeroupper works.
++AC_CACHE_CHECK(for -mno-vzeroupper support, libc_cv_cc_novzeroupper, [dnl
++LIBC_TRY_CC_OPTION([-mno-vzeroupper],
++		   [libc_cv_cc_novzeroupper=yes],
++		   [libc_cv_cc_novzeroupper=no])
++])
++
++dnl It is always possible to access static and hidden symbols in an
++dnl position independent way.
++AC_DEFINE(PI_STATIC_AND_HIDDEN)
++# work around problem with autoconf and empty lines at the end of files
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure.orig glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/configure.orig
+--- glibc-2.17-c758a686/sysdeps/x86_64/configure.orig	1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/configure.orig	2014-09-10 23:16:28.419182699 -0400
+@@ -0,0 +1,164 @@
++
++# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
++# -------------------------------------------------------
++# Tests whether HEADER exists and can be compiled using the include files in
++# INCLUDES, setting the cache variable VAR accordingly.
++ac_fn_c_check_header_compile ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
++$as_echo_n "checking for $2... " >&6; }
++if eval \${$3+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++$4
++#include <$2>
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  eval "$3=yes"
++else
++  eval "$3=no"
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++eval ac_res=\$$3
++	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++$as_echo "$ac_res" >&6; }
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++
++} # ac_fn_c_check_header_compile
++# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
++ # Local configure fragment for sysdeps/x86_64.
++
++
++ac_fn_c_check_header_compile "$LINENO" "cpuid.h" "ac_cv_header_cpuid_h" "/* No default includes.  */
++"
++if test "x$ac_cv_header_cpuid_h" = xyes; then :
++
++else
++  as_fn_error $? "gcc must provide the <cpuid.h> header" "$LINENO" 5
++fi
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSE4 support" >&5
++$as_echo_n "checking for SSE4 support... " >&6; }
++if ${libc_cv_cc_sse4+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if { ac_try='${CC-cc} -msse4 -xc /dev/null -S -o /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then :
++  libc_cv_cc_sse4=yes
++else
++  libc_cv_cc_sse4=no
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_sse4" >&5
++$as_echo "$libc_cv_cc_sse4" >&6; }
++if test $libc_cv_cc_sse4 = yes; then
++  $as_echo "#define HAVE_SSE4_SUPPORT 1" >>confdefs.h
++
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX support" >&5
++$as_echo_n "checking for AVX support... " >&6; }
++if ${libc_cv_cc_avx+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if { ac_try='${CC-cc} -mavx -xc /dev/null -S -o /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then :
++  libc_cv_cc_avx=yes
++else
++  libc_cv_cc_avx=no
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_avx" >&5
++$as_echo "$libc_cv_cc_avx" >&6; }
++if test $libc_cv_cc_avx = yes; then
++  $as_echo "#define HAVE_AVX_SUPPORT 1" >>confdefs.h
++
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX encoding of SSE instructions" >&5
++$as_echo_n "checking for AVX encoding of SSE instructions... " >&6; }
++if ${libc_cv_cc_sse2avx+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if { ac_try='${CC-cc} -msse2avx -xc /dev/null -S -o /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then :
++  libc_cv_cc_sse2avx=yes
++else
++  libc_cv_cc_sse2avx=no
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_sse2avx" >&5
++$as_echo "$libc_cv_cc_sse2avx" >&6; }
++if test $libc_cv_cc_sse2avx = yes; then
++  $as_echo "#define HAVE_SSE2AVX_SUPPORT 1" >>confdefs.h
++
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FMA4 support" >&5
++$as_echo_n "checking for FMA4 support... " >&6; }
++if ${libc_cv_cc_fma4+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if { ac_try='${CC-cc} -mfma4 -xc /dev/null -S -o /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then :
++  libc_cv_cc_fma4=yes
++else
++  libc_cv_cc_fma4=no
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_fma4" >&5
++$as_echo "$libc_cv_cc_fma4" >&6; }
++if test $libc_cv_cc_fma4 = yes; then
++  $as_echo "#define HAVE_FMA4_SUPPORT 1" >>confdefs.h
++
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -mno-vzeroupper support" >&5
++$as_echo_n "checking for -mno-vzeroupper support... " >&6; }
++if ${libc_cv_cc_novzeroupper+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if { ac_try='${CC-cc} -mno-vzeroupper -xc /dev/null -S -o /dev/null'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then :
++  libc_cv_cc_novzeroupper=yes
++else
++  libc_cv_cc_novzeroupper=no
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_novzeroupper" >&5
++$as_echo "$libc_cv_cc_novzeroupper" >&6; }
++
++$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
++
++# work around problem with autoconf and empty lines at the end of files
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/dl-trampoline.h
+--- glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/dl-trampoline.h	2014-09-10 23:16:36.334167050 -0400
+@@ -19,14 +19,14 @@
+ 
+ #ifdef RESTORE_AVX
+ 	/* This is to support AVX audit modules.  */
+-	vmovdqu %ymm0,		      (LR_VECTOR_OFFSET)(%rsp)
+-	vmovdqu %ymm1, (LR_VECTOR_OFFSET +   VECTOR_SIZE)(%rsp)
+-	vmovdqu %ymm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
+-	vmovdqu %ymm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
+-	vmovdqu %ymm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
+-	vmovdqu %ymm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
+-	vmovdqu %ymm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
+-	vmovdqu %ymm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
++	VMOV %VEC(0),		      (LR_VECTOR_OFFSET)(%rsp)
++	VMOV %VEC(1), (LR_VECTOR_OFFSET +   VECTOR_SIZE)(%rsp)
++	VMOV %VEC(2), (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
++	VMOV %VEC(3), (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
++	VMOV %VEC(4), (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
++	VMOV %VEC(5), (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
++	VMOV %VEC(6), (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
++	VMOV %VEC(7), (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
+ 
+ 	/* Save xmm0-xmm7 registers to detect if any of them are
+ 	   changed by audit module.  */
+@@ -72,7 +72,7 @@
+ 	je 2f
+ 	vmovdqa	%xmm0, (LR_VECTOR_OFFSET)(%rsp)
+ 	jmp 1f
+-2:	vmovdqu	(LR_VECTOR_OFFSET)(%rsp), %ymm0
++2:	VMOV (LR_VECTOR_OFFSET)(%rsp), %VEC(0)
+ 	vmovdqa	%xmm0, (LR_XMM_OFFSET)(%rsp)
+ 
+ 1:	vpcmpeqq (LR_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm8
+@@ -81,7 +81,7 @@
+ 	je 2f
+ 	vmovdqa	%xmm1, (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp)
+ 	jmp 1f
+-2:	vmovdqu	(LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %ymm1
++2:	VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %VEC(1)
+ 	vmovdqa	%xmm1, (LR_XMM_OFFSET + XMM_SIZE)(%rsp)
+ 
+ 1:	vpcmpeqq (LR_SIZE + XMM_SIZE*2)(%rsp), %xmm2, %xmm8
+@@ -90,7 +90,7 @@
+ 	je 2f
+ 	vmovdqa	%xmm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
+ 	jmp 1f
+-2:	vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %ymm2
++2:	VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %VEC(2)
+ 	vmovdqa	%xmm2, (LR_XMM_OFFSET + XMM_SIZE*2)(%rsp)
+ 
+ 1:	vpcmpeqq (LR_SIZE + XMM_SIZE*3)(%rsp), %xmm3, %xmm8
+@@ -99,7 +99,7 @@
+ 	je 2f
+ 	vmovdqa	%xmm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
+ 	jmp 1f
+-2:	vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %ymm3
++2:	VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %VEC(3)
+ 	vmovdqa	%xmm3, (LR_XMM_OFFSET + XMM_SIZE*3)(%rsp)
+ 
+ 1:	vpcmpeqq (LR_SIZE + XMM_SIZE*4)(%rsp), %xmm4, %xmm8
+@@ -108,7 +108,7 @@
+ 	je 2f
+ 	vmovdqa	%xmm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
+ 	jmp 1f
+-2:	vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %ymm4
++2:	VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %VEC(4)
+ 	vmovdqa	%xmm4, (LR_XMM_OFFSET + XMM_SIZE*4)(%rsp)
+ 
+ 1:	vpcmpeqq (LR_SIZE + XMM_SIZE*5)(%rsp), %xmm5, %xmm8
+@@ -117,7 +117,7 @@
+ 	je 2f
+ 	vmovdqa	%xmm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
+ 	jmp 1f
+-2:	vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %ymm5
++2:	VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %VEC(5)
+ 	vmovdqa	%xmm5, (LR_XMM_OFFSET + XMM_SIZE*5)(%rsp)
+ 
+ 1:	vpcmpeqq (LR_SIZE + XMM_SIZE*6)(%rsp), %xmm6, %xmm8
+@@ -126,7 +126,7 @@
+ 	je 2f
+ 	vmovdqa	%xmm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
+ 	jmp 1f
+-2:	vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %ymm6
++2:	VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %VEC(6)
+ 	vmovdqa	%xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp)
+ 
+ 1:	vpcmpeqq (LR_SIZE + XMM_SIZE*7)(%rsp), %xmm7, %xmm8
+@@ -135,7 +135,7 @@
+ 	je 2f
+ 	vmovdqa	%xmm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
+ 	jmp 1f
+-2:	vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %ymm7
++2:	VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %VEC(7)
+ 	vmovdqa	%xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp)
+ 
+ 1:
+@@ -213,8 +213,8 @@
+ 
+ #ifdef RESTORE_AVX
+ 	/* This is to support AVX audit modules.  */
+-	vmovdqu %ymm0, LRV_VECTOR0_OFFSET(%rcx)
+-	vmovdqu %ymm1, LRV_VECTOR1_OFFSET(%rcx)
++	VMOV %VEC(0), LRV_VECTOR0_OFFSET(%rcx)
++	VMOV %VEC(1), LRV_VECTOR1_OFFSET(%rcx)
+ 
+ 	/* Save xmm0/xmm1 registers to detect if they are changed
+ 	   by audit module.  */
+@@ -243,13 +243,13 @@
+ 	vpmovmskb %xmm2, %esi
+ 	cmpl $0xffff, %esi
+ 	jne 1f
+-	vmovdqu LRV_VECTOR0_OFFSET(%rsp), %ymm0
++	VMOV LRV_VECTOR0_OFFSET(%rsp), %VEC(0)
+ 
+ 1:	vpcmpeqq (LRV_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm2
+ 	vpmovmskb %xmm2, %esi
+ 	cmpl $0xffff, %esi
+ 	jne 1f
+-	vmovdqu LRV_VECTOR1_OFFSET(%rsp), %ymm1
++	VMOV LRV_VECTOR1_OFFSET(%rsp), %VEC(1)
+ 
+ 1:
+ #endif
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/dl-trampoline.S
+--- glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/dl-trampoline.S	2014-09-10 23:16:36.334167050 -0400
+@@ -96,7 +96,7 @@
+ 
+ 	/* Actively align the La_x86_64_regs structure.  */
+ 	andq $0xfffffffffffffff0, %rsp
+-# ifdef HAVE_AVX_SUPPORT
++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
+ 	/* sizeof(La_x86_64_regs).  Need extra space for 8 SSE registers
+ 	   to detect if any xmm0-xmm7 registers are changed by audit
+ 	   module.  */
+@@ -130,7 +130,7 @@
+ 	movaps %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp)
+ 	movaps %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp)
+ 
+-# ifdef HAVE_AVX_SUPPORT
++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
+ 	.data
+ L(have_avx):
+ 	.zero 4
+@@ -138,7 +138,7 @@
+ 	.previous
+ 
+ 	cmpl	$0, L(have_avx)(%rip)
+-	jne	1f
++	jne	L(defined)
+ 	movq	%rbx, %r11		# Save rbx
+ 	movl	$1, %eax
+ 	cpuid
+@@ -147,18 +147,54 @@
+ 	// AVX and XSAVE supported?
+ 	andl	$((1 << 28) | (1 << 27)), %ecx
+ 	cmpl	$((1 << 28) | (1 << 27)), %ecx
+-	jne	2f
++	jne	10f
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++	// AVX512 supported in processor?
++	movq	%rbx, %r11		# Save rbx
++	xorl	%ecx, %ecx
++	mov	$0x7, %eax
++	cpuid
++	andl	$(1 << 16), %ebx
++#  endif
+ 	xorl	%ecx, %ecx
+ 	// Get XFEATURE_ENABLED_MASK
+ 	xgetbv
+-	andl	$0x6, %eax
+-2:	subl	$0x5, %eax
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++	test	%ebx, %ebx
++	movq	%r11, %rbx		# Restore rbx
++	je	20f
++	// Verify that XCR0[7:5] = '111b' and
++	// XCR0[2:1] = '11b' which means
++	// that zmm state is enabled
++	andl	$0xe6, %eax
++	cmpl	$0xe6, %eax
++	jne	20f
++	movl	%eax, L(have_avx)(%rip)
++L(avx512):
++#   define RESTORE_AVX
++#   define VMOV    vmovdqu64
++#   define VEC(i)  zmm##i
++#   define MORE_CODE
++#   include "dl-trampoline.h"
++#   undef VMOV
++#   undef VEC
++#   undef RESTORE_AVX
++#  endif
++20:	andl	$0x6, %eax
++10:	subl	$0x5, %eax
+ 	movl	%eax, L(have_avx)(%rip)
+ 	cmpl	$0, %eax
+ 
+-1:	js	L(no_avx)
++L(defined):
++	js	L(no_avx)
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++	cmpl	$0xe6, L(have_avx)(%rip)
++	je	L(avx512)
++#  endif
+ 
+ #  define RESTORE_AVX
++#  define VMOV    vmovdqu
++#  define VEC(i)  ymm##i
+ #  define MORE_CODE
+ #  include "dl-trampoline.h"
+ 
+@@ -180,9 +216,9 @@
+ 	.align 16
+ 	cfi_startproc
+ _dl_x86_64_save_sse:
+-# ifdef HAVE_AVX_SUPPORT
++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
+ 	cmpl	$0, L(have_avx)(%rip)
+-	jne	1f
++	jne	L(defined_5)
+ 	movq	%rbx, %r11		# Save rbx
+ 	movl	$1, %eax
+ 	cpuid
+@@ -191,21 +227,43 @@
+ 	// AVX and XSAVE supported?
+ 	andl	$((1 << 28) | (1 << 27)), %ecx
+ 	cmpl	$((1 << 28) | (1 << 27)), %ecx
+-	jne	2f
++	jne	1f
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++	// AVX512 supported in a processor?
++	movq	%rbx, %r11              # Save rbx
++	xorl	%ecx,%ecx
++	mov	$0x7,%eax
++	cpuid
++	andl	$(1 << 16), %ebx
++#  endif
+ 	xorl	%ecx, %ecx
+ 	// Get XFEATURE_ENABLED_MASK
+ 	xgetbv
+-	andl	$0x6, %eax
+-	cmpl	$0x6, %eax
+-	// Nonzero if SSE and AVX state saving is enabled.
+-	sete	%al
+-2:	leal	-1(%eax,%eax), %eax
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++	test	%ebx, %ebx
++	movq	%r11, %rbx		# Restore rbx
++	je	2f
++	// Verify that XCR0[7:5] = '111b' and
++	// XCR0[2:1] = '11b' which means
++	// that zmm state is enabled
++	andl	$0xe6, %eax
++	movl	%eax, L(have_avx)(%rip)
++	cmpl	$0xe6, %eax
++	je	L(avx512_5)
++#  endif
++
++2:	andl	$0x6, %eax
++1:	subl	$0x5, %eax
+ 	movl	%eax, L(have_avx)(%rip)
+ 	cmpl	$0, %eax
+ 
+-1:	js	L(no_avx5)
++L(defined_5):
++	js	L(no_avx5)
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++	cmpl	$0xe6, L(have_avx)(%rip)
++	je	L(avx512_5)
++#  endif
+ 
+-#  define YMM_SIZE 32
+ 	vmovdqa %ymm0, %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE
+ 	vmovdqa %ymm1, %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE
+ 	vmovdqa %ymm2, %fs:RTLD_SAVESPACE_SSE+2*YMM_SIZE
+@@ -215,6 +273,18 @@
+ 	vmovdqa %ymm6, %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE
+ 	vmovdqa %ymm7, %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE
+ 	ret
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++L(avx512_5):
++	vmovdqu64 %zmm0, %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE
++	vmovdqu64 %zmm1, %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE
++	vmovdqu64 %zmm2, %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE
++	vmovdqu64 %zmm3, %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE
++	vmovdqu64 %zmm4, %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE
++	vmovdqu64 %zmm5, %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE
++	vmovdqu64 %zmm6, %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE
++	vmovdqu64 %zmm7, %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE
++	ret
++#  endif
+ L(no_avx5):
+ # endif
+ 	movdqa	%xmm0, %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE
+@@ -235,9 +305,13 @@
+ 	.align 16
+ 	cfi_startproc
+ _dl_x86_64_restore_sse:
+-# ifdef HAVE_AVX_SUPPORT
++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
+ 	cmpl	$0, L(have_avx)(%rip)
+ 	js	L(no_avx6)
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++	cmpl	$0xe6, L(have_avx)(%rip)
++	je	L(avx512_6)
++#  endif
+ 
+ 	vmovdqa %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE, %ymm0
+ 	vmovdqa %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE, %ymm1
+@@ -248,6 +322,18 @@
+ 	vmovdqa %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE, %ymm6
+ 	vmovdqa %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE, %ymm7
+ 	ret
++#  ifdef HAVE_AVX512_ASM_SUPPORT
++L(avx512_6):
++	vmovdqu64 %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE, %zmm0
++	vmovdqu64 %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE, %zmm1
++	vmovdqu64 %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE, %zmm2
++	vmovdqu64 %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE, %zmm3
++	vmovdqu64 %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE, %zmm4
++	vmovdqu64 %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE, %zmm5
++	vmovdqu64 %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE, %zmm6
++	vmovdqu64 %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE, %zmm7
++	ret
++#  endif
+ L(no_avx6):
+ # endif
+ 	movdqa	%fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE, %xmm0
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/link-defines.sym
+--- glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/link-defines.sym	2014-09-10 23:16:36.335167048 -0400
+@@ -4,6 +4,8 @@
+ --
+ VECTOR_SIZE		sizeof (La_x86_64_vector)
+ XMM_SIZE		sizeof (La_x86_64_xmm)
++YMM_SIZE		sizeof (La_x86_64_ymm)
++ZMM_SIZE		sizeof (La_x86_64_zmm)
+ 
+ LR_SIZE			sizeof (struct La_x86_64_regs)
+ LR_RDX_OFFSET		offsetof (struct La_x86_64_regs, lr_rdx)
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/Makefile glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/Makefile
+--- glibc-2.17-c758a686/sysdeps/x86_64/Makefile	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/Makefile	2014-09-10 23:22:04.269518711 -0400
+@@ -37,6 +37,20 @@
+ 
+ $(objpfx)tst-quad1pie: $(objpfx)tst-quadmod1pie.o
+ $(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o
++
++tests += tst-audit10
++modules-names += tst-auditmod10a tst-auditmod10b
++
++$(objpfx)tst-audit10: $(objpfx)tst-auditmod10a.so
++$(objpfx)tst-audit10.out: $(objpfx)tst-auditmod10b.so
++tst-audit10-ENV = LD_AUDIT=$(objpfx)tst-auditmod10b.so
++
++ifeq (yes,$(config-cflags-avx512))
++AVX512-CFLAGS = -mavx512f
++CFLAGS-tst-audit10.c += $(AVX512-CFLAGS)
++CFLAGS-tst-auditmod10a.c += $(AVX512-CFLAGS)
++CFLAGS-tst-auditmod10b.c += $(AVX512-CFLAGS)
++endif
+ endif
+ 
+ ifeq ($(subdir),csu)
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/Makefile.orig glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/Makefile.orig
+--- glibc-2.17-c758a686/sysdeps/x86_64/Makefile.orig	1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/Makefile.orig	2014-09-10 23:16:36.332167054 -0400
+@@ -0,0 +1,44 @@
++# The i387 `long double' is a distinct type we support.
++long-double-fcts = yes
++
++ifeq ($(subdir),csu)
++sysdep_routines += hp-timing
++elide-routines.os += hp-timing
++gen-as-const-headers += link-defines.sym
++endif
++
++ifeq ($(subdir),gmon)
++sysdep_routines += _mcount
++endif
++
++ifeq ($(subdir),malloc)
++tests += tst-mallocalign1
++endif
++
++ifeq ($(subdir),string)
++sysdep_routines += cacheinfo strcasecmp_l-nonascii strncase_l-nonascii
++gen-as-const-headers += locale-defines.sym
++endif
++
++ifeq ($(subdir),elf)
++sysdep-dl-routines += tlsdesc dl-tlsdesc
++sysdep_routines += tlsdesc dl-tlsdesc
++sysdep-rtld-routines += tlsdesc dl-tlsdesc
++
++tests += tst-quad1 tst-quad2
++modules-names += tst-quadmod1 tst-quadmod2
++
++$(objpfx)tst-quad1: $(objpfx)tst-quadmod1.so
++$(objpfx)tst-quad2: $(objpfx)tst-quadmod2.so
++
++quad-pie-test += tst-quad1pie tst-quad2pie
++tests += $(quad-pie-test)
++tests-pie += $(quad-pie-test)
++
++$(objpfx)tst-quad1pie: $(objpfx)tst-quadmod1pie.o
++$(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o
++endif
++
++ifeq ($(subdir),csu)
++gen-as-const-headers += tlsdesc.sym
++endif
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/tst-audit10.c glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/tst-audit10.c
+--- glibc-2.17-c758a686/sysdeps/x86_64/tst-audit10.c	1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/tst-audit10.c	2014-09-10 23:16:36.335167048 -0400
+@@ -0,0 +1,70 @@
++/* Copyright (C) 2012-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/>.  */
++
++/* Test case for x86-64 preserved registers in dynamic linker.  */
++
++#ifdef __AVX512F__
++#include <stdlib.h>
++#include <string.h>
++#include <cpuid.h>
++#include <immintrin.h>
++
++static int
++avx512_enabled (void)
++{
++  unsigned int eax, ebx, ecx, edx;
++
++  if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0
++      || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE))
++    return 0;
++
++  __cpuid_count (7, 0, eax, ebx, ecx, edx);
++  if (!(ebx & bit_AVX512F))
++    return 0;
++
++  asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
++
++  /* Verify that ZMM, YMM and XMM states are enabled.  */
++  return (eax & 0xe6) == 0xe6;
++}
++
++
++extern __m512i audit_test (__m512i, __m512i, __m512i, __m512i,
++			   __m512i, __m512i, __m512i, __m512i);
++int
++main (void)
++{
++  /* Run AVX512 test only if AVX512 is supported.  */
++  if (avx512_enabled ())
++    {
++      __m512i zmm = _mm512_setzero_si512 ();
++      __m512i ret = audit_test (zmm, zmm, zmm, zmm, zmm, zmm, zmm, zmm);
++
++      zmm = _mm512_set1_epi64 (0x12349876);
++
++      if (memcmp (&zmm, &ret, sizeof (ret)))
++	abort ();
++    }
++  return 0;
++}
++#else
++int
++main (void)
++{
++  return 0;
++}
++#endif
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10a.c glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/tst-auditmod10a.c
+--- glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10a.c	1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/tst-auditmod10a.c	2014-09-10 23:16:36.335167048 -0400
+@@ -0,0 +1,65 @@
++/* Copyright (C) 2012-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/>.  */
++
++/* Test case for x86-64 preserved registers in dynamic linker.  */
++
++#ifdef __AVX512F__
++#include <stdlib.h>
++#include <string.h>
++#include <immintrin.h>
++
++__m512i
++audit_test (__m512i x0, __m512i x1, __m512i x2, __m512i x3,
++	    __m512i x4, __m512i x5, __m512i x6, __m512i x7)
++{
++  __m512i zmm;
++
++  zmm = _mm512_set1_epi64 (1);
++  if (memcmp (&zmm, &x0, sizeof (zmm)))
++    abort ();
++
++  zmm = _mm512_set1_epi64 (2);
++  if (memcmp (&zmm, &x1, sizeof (zmm)))
++    abort ();
++
++  zmm = _mm512_set1_epi64 (3);
++  if (memcmp (&zmm, &x2, sizeof (zmm)))
++    abort ();
++
++  zmm = _mm512_set1_epi64 (4);
++  if (memcmp (&zmm, &x3, sizeof (zmm)))
++    abort ();
++
++  zmm = _mm512_set1_epi64 (5);
++  if (memcmp (&zmm, &x4, sizeof (zmm)))
++    abort ();
++
++  zmm = _mm512_set1_epi64 (6);
++  if (memcmp (&zmm, &x5, sizeof (zmm)))
++    abort ();
++
++  zmm = _mm512_set1_epi64 (7);
++  if (memcmp (&zmm, &x6, sizeof (zmm)))
++    abort ();
++
++  zmm = _mm512_set1_epi64 (8);
++  if (memcmp (&zmm, &x7, sizeof (zmm)))
++    abort ();
++
++  return _mm512_setzero_si512 ();
++}
++#endif
+diff -urN glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10b.c glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/tst-auditmod10b.c
+--- glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10b.c	1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.17-c758a686.mod-mpx/sysdeps/x86_64/tst-auditmod10b.c	2014-09-10 23:16:36.336167046 -0400
+@@ -0,0 +1,219 @@
++/* Copyright (C) 2012-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/>.  */
++
++/* Verify that changing AVX512 registers in audit library won't affect
++   function parameter passing/return.  */
++
++#include <dlfcn.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <bits/wordsize.h>
++#include <gnu/lib-names.h>
++
++unsigned int
++la_version (unsigned int v)
++{
++  setlinebuf (stdout);
++
++  printf ("version: %u\n", v);
++
++  char buf[20];
++  sprintf (buf, "%u", v);
++
++  return v;
++}
++
++void
++la_activity (uintptr_t *cookie, unsigned int flag)
++{
++  if (flag == LA_ACT_CONSISTENT)
++    printf ("activity: consistent\n");
++  else if (flag == LA_ACT_ADD)
++    printf ("activity: add\n");
++  else if (flag == LA_ACT_DELETE)
++    printf ("activity: delete\n");
++  else
++    printf ("activity: unknown activity %u\n", flag);
++}
++
++char *
++la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
++{
++  char buf[100];
++  const char *flagstr;
++  if (flag == LA_SER_ORIG)
++    flagstr = "LA_SET_ORIG";
++  else if (flag == LA_SER_LIBPATH)
++    flagstr = "LA_SER_LIBPATH";
++  else if (flag == LA_SER_RUNPATH)
++    flagstr = "LA_SER_RUNPATH";
++  else if (flag == LA_SER_CONFIG)
++    flagstr = "LA_SER_CONFIG";
++  else if (flag == LA_SER_DEFAULT)
++    flagstr = "LA_SER_DEFAULT";
++  else if (flag == LA_SER_SECURE)
++    flagstr = "LA_SER_SECURE";
++  else
++    {
++       sprintf (buf, "unknown flag %d", flag);
++       flagstr = buf;
++    }
++  printf ("objsearch: %s, %s\n", name, flagstr);
++
++  return (char *) name;
++}
++
++unsigned int
++la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie)
++{
++  printf ("objopen: %ld, %s\n", lmid, l->l_name);
++
++  return 3;
++}
++
++void
++la_preinit (uintptr_t *cookie)
++{
++  printf ("preinit\n");
++}
++
++unsigned int
++la_objclose  (uintptr_t *cookie)
++{
++  printf ("objclose\n");
++  return 0;
++}
++
++uintptr_t
++la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
++	      uintptr_t *defcook, unsigned int *flags, const char *symname)
++{
++  printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
++	  symname, (long int) sym->st_value, ndx, *flags);
++
++  return sym->st_value;
++}
++
++#include <tst-audit.h>
++
++#ifdef __AVX512F__
++#include <immintrin.h>
++#include <cpuid.h>
++
++static int
++check_avx512 (void)
++{
++  unsigned int eax, ebx, ecx, edx;
++
++  if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0
++      || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE))
++    return 0;
++
++  __cpuid_count (7, 0, eax, ebx, ecx, edx);
++  if (!(ebx & bit_AVX512F))
++    return 0;
++
++  asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
++
++  /* Verify that ZMM, YMM and XMM states are enabled.  */
++  return (eax & 0xe6) == 0xe6;
++}
++
++#else
++#include <emmintrin.h>
++#endif
++
++ElfW(Addr)
++pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
++	  uintptr_t *defcook, La_regs *regs, unsigned int *flags,
++	  const char *symname, long int *framesizep)
++{
++  printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
++	  symname, (long int) sym->st_value, ndx, *flags);
++
++#ifdef __AVX512F__
++  if (check_avx512 () && strcmp (symname, "audit_test") == 0)
++    {
++      __m512i zero = _mm512_setzero_si512 ();
++      if (memcmp (&regs->lr_vector[0], &zero, sizeof (zero))
++	  || memcmp (&regs->lr_vector[1], &zero, sizeof (zero))
++	  || memcmp (&regs->lr_vector[2], &zero, sizeof (zero))
++	  || memcmp (&regs->lr_vector[3], &zero, sizeof (zero))
++	  || memcmp (&regs->lr_vector[4], &zero, sizeof (zero))
++	  || memcmp (&regs->lr_vector[5], &zero, sizeof (zero))
++	  || memcmp (&regs->lr_vector[6], &zero, sizeof (zero))
++	  || memcmp (&regs->lr_vector[7], &zero, sizeof (zero)))
++	abort ();
++
++      for (int i = 0; i < 8; i++)
++	regs->lr_vector[i].zmm[0]
++	  = (La_x86_64_zmm) _mm512_set1_epi64 (i + 1);
++
++      __m512i zmm = _mm512_set1_epi64 (-1);
++      asm volatile ("vmovdqa64 %0, %%zmm0" : : "x" (zmm) : "xmm0" );
++      asm volatile ("vmovdqa64 %0, %%zmm1" : : "x" (zmm) : "xmm1" );
++      asm volatile ("vmovdqa64 %0, %%zmm2" : : "x" (zmm) : "xmm2" );
++      asm volatile ("vmovdqa64 %0, %%zmm3" : : "x" (zmm) : "xmm3" );
++      asm volatile ("vmovdqa64 %0, %%zmm4" : : "x" (zmm) : "xmm4" );
++      asm volatile ("vmovdqa64 %0, %%zmm5" : : "x" (zmm) : "xmm5" );
++      asm volatile ("vmovdqa64 %0, %%zmm6" : : "x" (zmm) : "xmm6" );
++      asm volatile ("vmovdqa64 %0, %%zmm7" : : "x" (zmm) : "xmm7" );
++
++      *framesizep = 1024;
++    }
++#endif
++
++  return sym->st_value;
++}
++
++unsigned int
++pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
++	 uintptr_t *defcook, const La_regs *inregs, La_retval *outregs,
++	 const char *symname)
++{
++  printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n",
++	  symname, (long int) sym->st_value, ndx,
++	  (ptrdiff_t) outregs->int_retval);
++
++#ifdef __AVX512F__
++  if (check_avx512 () && strcmp (symname, "audit_test") == 0)
++    {
++      __m512i zero = _mm512_setzero_si512 ();
++      if (memcmp (&outregs->lrv_vector0, &zero, sizeof (zero)))
++	abort ();
++
++      for (int i = 0; i < 8; i++)
++	{
++	  __m512i zmm = _mm512_set1_epi64 (i + 1);
++	  if (memcmp (&inregs->lr_vector[i], &zmm, sizeof (zmm)) != 0)
++	    abort ();
++	}
++
++      outregs->lrv_vector0.zmm[0]
++	= (La_x86_64_zmm) _mm512_set1_epi64 (0x12349876);
++
++      __m512i zmm = _mm512_set1_epi64 (-1);
++      asm volatile ("vmovdqa64 %0, %%zmm0" : : "x" (zmm) : "xmm0" );
++      asm volatile ("vmovdqa64 %0, %%zmm1" : : "x" (zmm) : "xmm1" );
++    }
++#endif
++
++  return 0;
++}
+diff -urN glibc-2.17-c758a686/sysdeps/x86/Makefile glibc-2.17-c758a686.mod/sysdeps/x86/Makefile
+--- glibc-2.17-c758a686/sysdeps/x86/Makefile	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/x86/Makefile	2014-09-11 16:06:03.121319867 -0400
+@@ -2,8 +2,8 @@
+ CFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\
+ 		   -mno-sse -mno-mmx)
+ 
+-tests: $(objpfx)tst-xmmymm.out
+-$(objpfx)tst-xmmymm.out: ../sysdeps/x86/tst-xmmymm.sh $(objpfx)ld.so
++tests: $(objpfx)tst-xmmymmzmm.out
++$(objpfx)tst-xmmymmzmm.out: ../sysdeps/x86/tst-xmmymmzmm.sh $(objpfx)ld.so
+ 	@echo "Checking ld.so for SSE register use.  This will take a few seconds..."
+ 	$(SHELL) $< $(objpfx) '$(NM)' '$(OBJDUMP)' '$(READELF)' > $@
+ endif
+diff -urN glibc-2.17-c758a686/sysdeps/x86/tst-xmmymm.sh glibc-2.17-c758a686.mod/sysdeps/x86/tst-xmmymm.sh
+--- glibc-2.17-c758a686/sysdeps/x86/tst-xmmymm.sh	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/x86/tst-xmmymm.sh	1969-12-31 19:00:00.000000000 -0500
+@@ -1,103 +0,0 @@
+-#! /bin/bash
+-# Make sure no code in ld.so uses xmm/ymm registers on x86-64.
+-# Copyright (C) 2009-2012 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/>.
+-
+-set -e
+-
+-objpfx="$1"
+-NM="$2"
+-OBJDUMP="$3"
+-READELF="$4"
+-
+-tmp=$(mktemp ${objpfx}tst-xmmymm.XXXXXX)
+-trap 'rm -f "$tmp"' 1 2 3 15
+-
+-# List of object files we have to test
+-rtldobjs=$($READELF -W -wi ${objpfx}dl-allobjs.os |
+-    awk '/^ </ { if ($5 == "(DW_TAG_compile_unit)") c=1; else c=0 } $2 == "DW_AT_name" { if (c == 1) print $NF }' |
+-    sed 's,\(.*/\|\)\([_[:alnum:]-]*[.]\).$,\2os,')
+-rtldobjs="$rtldobjs $(ar t ${objpfx}rtld-libc.a)"
+-
+-# OBJECT symbols can be ignored.
+-$READELF -sW ${objpfx}dl-allobjs.os ${objpfx}rtld-libc.a |
+-egrep " OBJECT  *GLOBAL " |
+-awk '{if ($7 != "ABS") print $8 }' |
+-sort -u > "$tmp"
+-declare -a objects
+-objects=($(cat "$tmp"))
+-
+-objs="dl-runtime.os"
+-tocheck="dl-runtime.os"
+-
+-while test -n "$objs"; do
+-  this="$objs"
+-  objs=""
+-
+-  for f in $this; do
+-    undef=$($NM -u "$objpfx"../*/"$f" | awk '{print $2}')
+-    if test -n "$undef"; then
+-      for s in $undef; do
+-	for obj in ${objects[*]} "_GLOBAL_OFFSET_TABLE_"; do
+-	  if test "$obj" = "$s"; then
+-	    continue 2
+-	  fi
+-	done
+-        for o in $rtldobjs; do
+-	  ro=$(echo "$objpfx"../*/"$o")
+-	  if $NM -g --defined-only "$ro" | egrep -qs " $s\$"; then
+-	    if ! (echo "$tocheck $objs" | fgrep -qs "$o"); then
+-	      echo "$o needed for $s"
+-	      objs="$objs $o"
+-	    fi
+-	    break;
+-	  fi
+-	done
+-      done
+-    fi
+-  done
+-  tocheck="$tocheck$objs"
+-done
+-
+-echo
+-echo
+-echo "object files needed: $tocheck"
+-
+-cp /dev/null "$tmp"
+-for f in $tocheck; do
+-  $OBJDUMP -d "$objpfx"../*/"$f" |
+-  awk 'BEGIN { last="" } /^[[:xdigit:]]* <[_[:alnum:]]*>:$/ { fct=substr($2, 2, length($2)-3) } /,%[xy]mm[[:digit:]]*$/ { if (last != fct) { print fct; last=fct} }' |
+-  while read fct; do
+-    if test "$fct" = "_dl_runtime_profile" -o "$fct" = "_dl_x86_64_restore_sse"; then
+-      continue;
+-    fi
+-    echo "function $fct in $f modifies xmm/ymm" >> "$tmp"
+-    result=1
+-  done
+-done
+-
+-if test -s "$tmp"; then
+-  echo
+-  echo
+-  cat "$tmp"
+-  result=1
+-else
+-  result=0
+-fi
+-
+-rm "$tmp"
+-exit $result
+diff -urN glibc-2.17-c758a686/sysdeps/x86/tst-xmmymmzmm.sh glibc-2.17-c758a686.mod/sysdeps/x86/tst-xmmymmzmm.sh
+--- glibc-2.17-c758a686/sysdeps/x86/tst-xmmymmzmm.sh	1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/x86/tst-xmmymmzmm.sh	2014-09-11 16:05:10.073426623 -0400
+@@ -0,0 +1,103 @@
++#! /bin/bash
++# Make sure no code in ld.so uses xmm/ymm/zmm registers on x86-64.
++# Copyright (C) 2009-2012 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/>.
++
++set -e
++
++objpfx="$1"
++NM="$2"
++OBJDUMP="$3"
++READELF="$4"
++
++tmp=$(mktemp ${objpfx}tst-xmmymmzmm.XXXXXX)
++trap 'rm -f "$tmp"' 1 2 3 15
++
++# List of object files we have to test
++rtldobjs=$($READELF -W -wi ${objpfx}dl-allobjs.os |
++    awk '/^ </ { if ($5 == "(DW_TAG_compile_unit)") c=1; else c=0 } $2 == "DW_AT_name" { if (c == 1) print $NF }' |
++    sed 's,\(.*/\|\)\([_[:alnum:]-]*[.]\).$,\2os,')
++rtldobjs="$rtldobjs $(ar t ${objpfx}rtld-libc.a)"
++
++# OBJECT symbols can be ignored.
++$READELF -sW ${objpfx}dl-allobjs.os ${objpfx}rtld-libc.a |
++egrep " OBJECT  *GLOBAL " |
++awk '{if ($7 != "ABS") print $8 }' |
++sort -u > "$tmp"
++declare -a objects
++objects=($(cat "$tmp"))
++
++objs="dl-runtime.os"
++tocheck="dl-runtime.os"
++
++while test -n "$objs"; do
++  this="$objs"
++  objs=""
++
++  for f in $this; do
++    undef=$($NM -u "$objpfx"../*/"$f" | awk '{print $2}')
++    if test -n "$undef"; then
++      for s in $undef; do
++	for obj in ${objects[*]} "_GLOBAL_OFFSET_TABLE_"; do
++	  if test "$obj" = "$s"; then
++	    continue 2
++	  fi
++	done
++        for o in $rtldobjs; do
++	  ro=$(echo "$objpfx"../*/"$o")
++	  if $NM -g --defined-only "$ro" | egrep -qs " $s\$"; then
++	    if ! (echo "$tocheck $objs" | fgrep -qs "$o"); then
++	      echo "$o needed for $s"
++	      objs="$objs $o"
++	    fi
++	    break;
++	  fi
++	done
++      done
++    fi
++  done
++  tocheck="$tocheck$objs"
++done
++
++echo
++echo
++echo "object files needed: $tocheck"
++
++cp /dev/null "$tmp"
++for f in $tocheck; do
++  $OBJDUMP -d "$objpfx"../*/"$f" |
++  awk 'BEGIN { last="" } /^[[:xdigit:]]* <[_[:alnum:]]*>:$/ { fct=substr($2, 2, length($2)-3) } /,%[xyz]mm[[:digit:]]*$/ { if (last != fct) { print fct; last=fct} }' |
++  while read fct; do
++    if test "$fct" = "_dl_runtime_profile" -o "$fct" = "_dl_x86_64_restore_sse"; then
++      continue;
++    fi
++    echo "function $fct in $f modifies xmm/ymm/zmm" >> "$tmp"
++    result=1
++  done
++done
++
++if test -s "$tmp"; then
++  echo
++  echo
++  cat "$tmp"
++  result=1
++else
++  result=0
++fi
++
++rm "$tmp"
++exit $result
diff --git a/SOURCES/glibc-rh1140474.patch b/SOURCES/glibc-rh1140474.patch
new file mode 100644
index 0000000..11815b4
--- /dev/null
+++ b/SOURCES/glibc-rh1140474.patch
@@ -0,0 +1,154 @@
+commit 41488498b6d9440ee66ab033808cce8323bba7ac
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Sep 3 19:45:43 2014 +0200
+
+    CVE-2014-6040: Crashes on invalid input in IBM gconv modules [BZ #17325]
+    
+    These changes are based on the fix for BZ #14134 in commit
+    6e230d11837f3ae7b375ea69d7905f0d18eb79e5.
+
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index 0a410a1..b6327d6 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -297,6 +297,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 0b5484f..cf80993 100644
+--- a/iconvdata/ibm1364.c
++++ b/iconvdata/ibm1364.c
+@@ -221,7 +221,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 f5dca59..aa69d65 100644
+--- a/iconvdata/ibm932.c
++++ b/iconvdata/ibm932.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 = __ibm932db_to_ucs4[ch + rp2->idx],		      \
+ 	    __builtin_expect (res, '\1') == 0 && ch !=0))		      \
+ 	  {								      \
+diff --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
+index f46dfb5..461fb5e 100644
+--- a/iconvdata/ibm933.c
++++ b/iconvdata/ibm933.c
+@@ -162,7 +162,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 a8e4e6c..132d816 100644
+--- a/iconvdata/ibm935.c
++++ b/iconvdata/ibm935.c
+@@ -162,7 +162,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 239be61..69b154d 100644
+--- a/iconvdata/ibm937.c
++++ b/iconvdata/ibm937.c
+@@ -162,7 +162,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 5d0db36..9936e2c 100644
+--- a/iconvdata/ibm939.c
++++ b/iconvdata/ibm939.c
+@@ -162,7 +162,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 be0c14f..c5d5742 100644
+--- a/iconvdata/ibm943.c
++++ b/iconvdata/ibm943.c
+@@ -75,11 +75,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 c98c929..5dfb69f 100755
+--- a/iconvdata/run-iconv-test.sh
++++ b/iconvdata/run-iconv-test.sh
+@@ -184,6 +184,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/SOURCES/glibc-rh1156331.patch b/SOURCES/glibc-rh1156331.patch
new file mode 100644
index 0000000..4ea2762
--- /dev/null
+++ b/SOURCES/glibc-rh1156331.patch
@@ -0,0 +1,202 @@
+commit e276f4f310a89a925dd59e583f7a1bef2114d9a7
+Author: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date:   Tue Nov 25 21:15:16 2014 +0530
+
+    ftell: seek to end only when there are unflushed bytes (BZ #17647)
+    
+    Currently we seek to end of file if there are unflushed writes or the
+    stream is in write mode, to get the current offset for writing in
+    append mode, which is the end of file.  The latter case (i.e. stream
+    is in write mode, but no unflushed writes) is unnecessary since it
+    will only happen when the stream has just been flushed, in which case
+    the recorded offset ought to be reliable.
+    
+    Removing that case lets ftell give the correct offset when it follows
+    an ftruncate.  The latter truncates the file, but does not change the
+    file position, due to which it is permissible to call ftell without an
+    intervening fseek call.
+    
+    Tested on x86_64 to verify that the added test case fails without the
+    patch and succeeds with it, and that there are no additional
+    regressions due to it.
+    
+    	[BZ #17647]
+    	* libio/fileops.c (do_ftell): Seek only when there are
+    	unflushed writes.
+    	* libio/wfileops.c (do_ftell_wide): Likewise.
+    	* libio/tst-ftell-active-handler.c (do_ftruncate_test): New
+    	test case.
+    	(do_one_test): Call it.
+
+diff --git a/libio/fileops.c b/libio/fileops.c
+index e0d7b76..1fc5719 100644
+--- a/libio/fileops.c
++++ b/libio/fileops.c
+@@ -943,15 +943,14 @@ do_ftell (_IO_FILE *fp)
+      yet.  */
+   if (fp->_IO_buf_base != NULL)
+     {
+-      bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
+-			  || _IO_in_put_mode (fp));
++      bool unflushed_writes = (fp->_IO_write_ptr > fp->_IO_write_base);
+ 
+       bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
+ 
+       /* When we have unflushed writes in append mode, seek to the end of the
+ 	 file and record that offset.  This is the only time we change the file
+ 	 stream state and it is safe since the file handle is active.  */
+-      if (was_writing && append_mode)
++      if (unflushed_writes && append_mode)
+ 	{
+ 	  result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
+ 	  if (result == _IO_pos_BAD)
+@@ -961,7 +960,7 @@ do_ftell (_IO_FILE *fp)
+ 	}
+ 
+       /* Adjust for unflushed data.  */
+-      if (!was_writing)
++      if (!unflushed_writes)
+ 	offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+       /* We don't trust _IO_read_end to represent the current file offset when
+ 	 writing in append mode because the value would have to be shifted to
+diff --git a/libio/tst-ftell-active-handler.c b/libio/tst-ftell-active-handler.c
+index e9dc7b3..9f23c55 100644
+--- a/libio/tst-ftell-active-handler.c
++++ b/libio/tst-ftell-active-handler.c
+@@ -88,6 +88,95 @@ static size_t file_len;
+ typedef int (*fputs_func_t) (const void *data, FILE *fp);
+ fputs_func_t fputs_func;
+ 
++/* This test verifies that the offset reported by ftell is correct after the
++   file is truncated using ftruncate.  ftruncate does not change the file
++   offset on truncation and hence, SEEK_CUR should continue to point to the
++   old offset and not be changed to the new offset.  */
++static int
++do_ftruncate_test (const char *filename)
++{
++  FILE *fp = NULL;
++  int fd;
++  int ret = 0;
++  struct test
++    {
++      const char *mode;
++      int fd_mode;
++    } test_modes[] = {
++	  {"r+", O_RDWR},
++	  {"w", O_WRONLY},
++	  {"w+", O_RDWR},
++	  {"a", O_WRONLY},
++	  {"a+", O_RDWR}
++    };
++
++  for (int j = 0; j < 2; j++)
++    {
++      for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++)
++	{
++	  int fileret;
++	  printf ("\tftruncate: %s (file, \"%s\"): ",
++		  j == 0 ? "fopen" : "fdopen",
++		  test_modes[i].mode);
++
++	  if (j == 0)
++	    fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode);
++	  else
++	    fileret = get_handles_fdopen (filename, fd, fp,
++					  test_modes[i].fd_mode,
++					  test_modes[i].mode);
++
++	  if (fileret != 0)
++	    return fileret;
++
++	  /* Write some data.  */
++	  size_t written = fputs_func (data, fp);
++
++	  if (written == EOF)
++	    {
++	      printf ("fputs[1] failed to write data\n");
++	      ret |= 1;
++	    }
++
++	  /* Record the offset.  */
++	  long offset = ftell (fp);
++
++	  /* Flush data to allow switching active handles.  */
++	  if (fflush (fp))
++	    {
++	      printf ("Flush failed: %m\n");
++	      ret |= 1;
++	    }
++
++	  /* Now truncate the file.  */
++	  if (ftruncate (fd, 0) != 0)
++	    {
++	      printf ("Failed to truncate file: %m\n");
++	      ret |= 1;
++	    }
++
++	  /* ftruncate does not change the offset, so there is no need to call
++	     anything to be able to switch active handles.  */
++	  long new_offset = ftell (fp);
++
++	  /* The offset should remain unchanged since ftruncate does not update
++	     it.  */
++	  if (offset != new_offset)
++	    {
++	      printf ("Incorrect offset.  Expected %zu, but got %ld\n",
++		      offset, new_offset);
++
++	      ret |= 1;
++	    }
++	  else
++	    printf ("offset = %ld\n", offset);
++
++	  fclose (fp);
++	}
++    }
++
++  return ret;
++}
+ /* Test that ftell output after a rewind is correct.  */
+ static int
+ do_rewind_test (const char *filename)
+@@ -481,6 +570,7 @@ do_one_test (const char *filename)
+   ret |= do_write_test (filename);
+   ret |= do_append_test (filename);
+   ret |= do_rewind_test (filename);
++  ret |= do_ftruncate_test (filename);
+ 
+   return ret;
+ }
+diff --git a/libio/wfileops.c b/libio/wfileops.c
+index 6a088b1..71281c1 100644
+--- a/libio/wfileops.c
++++ b/libio/wfileops.c
+@@ -626,16 +626,15 @@ do_ftell_wide (_IO_FILE *fp)
+       const wchar_t *wide_read_base;
+       const wchar_t *wide_read_ptr;
+       const wchar_t *wide_read_end;
+-      bool was_writing = ((fp->_wide_data->_IO_write_ptr
+-			   > fp->_wide_data->_IO_write_base)
+-			  || _IO_in_put_mode (fp));
++      bool unflushed_writes = (fp->_wide_data->_IO_write_ptr
++			       > fp->_wide_data->_IO_write_base);
+ 
+       bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
+ 
+       /* When we have unflushed writes in append mode, seek to the end of the
+ 	 file and record that offset.  This is the only time we change the file
+ 	 stream state and it is safe since the file handle is active.  */
+-      if (was_writing && append_mode)
++      if (unflushed_writes && append_mode)
+ 	{
+ 	  result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
+ 	  if (result == _IO_pos_BAD)
+@@ -674,7 +673,7 @@ do_ftell_wide (_IO_FILE *fp)
+       struct _IO_codecvt *cv = fp->_codecvt;
+       int clen = (*cv->__codecvt_do_encoding) (cv);
+ 
+-      if (!was_writing)
++      if (!unflushed_writes)
+ 	{
+ 	  if (clen > 0)
+ 	    {
diff --git a/SOURCES/glibc-rh1161666.patch b/SOURCES/glibc-rh1161666.patch
new file mode 100644
index 0000000..fff468d
--- /dev/null
+++ b/SOURCES/glibc-rh1161666.patch
@@ -0,0 +1,108 @@
+diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
+index c56185c..79f8ef9 100644
+--- a/sysdeps/s390/s390-32/dl-machine.h
++++ b/sysdeps/s390/s390-32/dl-machine.h
+@@ -166,18 +166,49 @@ _dl_start_user:\n\
+ 	# See if we were run as a command with the executable file\n\
+ 	# name as an extra leading argument.\n\
+ 	l     %r1,_dl_skip_args@GOT12(0,%r12)\n\
+-	l     %r1,0(%r1)          # load _dl_skip_args\n\
++	l     %r1,0(%r1)	# load _dl_skip_args\n\
++	ltr   %r1,%r1\n\
++	je    .L4		# Skip the arg adjustment if there were none.\n\
+ 	# Get the original argument count.\n\
+ 	l     %r0,96(%r15)\n\
+ 	# Subtract _dl_skip_args from it.\n\
+ 	sr    %r0,%r1\n\
+-	# Adjust the stack pointer to skip _dl_skip_args words.\n\
+-	sll   %r1,2\n\
+-	ar    %r15,%r1\n\
+-	# Set the back chain to zero again\n\
+-	xc    0(4,%r15),0(%r15)\n\
+ 	# Store back the modified argument count.\n\
+ 	st    %r0,96(%r15)\n\
++	# Copy argv and envp forward to account for skipped argv entries.\n\
++	# We skipped at least one argument or we would not get here.\n\
++	la    %r6,100(%r15)	# Destination pointer i.e. &argv[0]\n\
++	lr    %r5,%r6\n\
++	lr    %r0,%r1\n\
++	sll   %r0,2\n		# Number of skipped bytes.\n\
++	ar    %r5,%r0		# Source pointer = Dest + Skipped args.\n\
++	# argv copy loop:\n\
++.L1:	l     %r7,0(%r5)	# Load a word from the source.\n\
++	st    %r7,0(%r6)	# Store the word in the destination.\n\
++	ahi   %r5,4\n\
++	ahi   %r6,4\n\
++	ltr   %r7,%r7\n\
++	jne   .L1		# Stop after copying the NULL.\n\
++	# envp copy loop:\n\
++.L2:	l     %r7,0(%r5)	# Load a word from the source.\n\
++	st    %r7,0(%r6)	# Store the word in the destination.\n\
++	ahi   %r5,4\n\
++	ahi   %r6,4\n\
++	ltr   %r7,%r7\n\
++	jne   .L2		# Stop after copying the NULL.\n\
++	# Now we have to zero out the envp entries after NULL to allow\n\
++	# start.S to properly find auxv by skipping zeroes.\n\
++	# zero out loop:\n\
++	lhi   %r7,0\n\
++.L3:	st    %r7,0(%r6)	# Store zero.\n\
++	ahi   %r6,4		# Advance dest pointer.\n\
++	ahi   %r1,-1		# Subtract one from the word count.\n\
++	ltr   %r1,%r1\n\
++	jne    .L3		# Keep copying if the word count is non-zero.\n\
++	# Adjust _dl_argv\n\
++	la    %r6,100(%r15)\n\
++	l     %r1,_dl_argv@GOT12(0,%r12)\n\
++	st    %r6,0(%r1)\n\
+ 	# The special initializer gets called with the stack just\n\
+ 	# as the application's entry point will see it; it can\n\
+ 	# switch stacks if it moves these contents over.\n\
+@@ -185,7 +216,7 @@ _dl_start_user:\n\
+ 	# Call the function to run the initializers.\n\
+ 	# Load the parameters:\n\
+ 	# (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\
+-	l     %r2,_rtld_local@GOT(%r12)\n\
++.L4:	l     %r2,_rtld_local@GOT(%r12)\n\
+ 	l     %r2,0(%r2)\n\
+ 	l     %r3,96(%r15)\n\
+ 	la    %r4,100(%r15)\n\
+@@ -198,6 +229,9 @@ _dl_start_user:\n\
+ 	l     %r14,_dl_fini@GOT(%r12)\n\
+ 	# Free stack frame\n\
+ 	ahi   %r15,96\n\
++	# Reload argc and argv for the user's entry point.\n\
++	# l     %r2,0(%r15)\n\
++	# la    %r3,4(%r15)\n\
+ 	# Jump to the user's entry point (saved in %r8).\n\
+ 	br    %r8\n\
+ .Llit:\n\
+diff --git a/sysdeps/s390/s390-32/dl-sysdep.h b/sysdeps/s390/s390-32/dl-sysdep.h
+new file mode 100644
+index 0000000..b992778
+--- /dev/null
++++ b/sysdeps/s390/s390-32/dl-sysdep.h
+@@ -0,0 +1,23 @@
++/* System-specific settings for dynamic linker code.  S/390 version.
++   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_next <dl-sysdep.h>
++
++/* _dl_argv cannot be attribute_relro, because _dl_start_user
++   might write into it after _dl_start returns.  */
++#define DL_ARGV_NOT_RELRO 1
diff --git a/SOURCES/glibc-rh1162847-p1.patch b/SOURCES/glibc-rh1162847-p1.patch
new file mode 100644
index 0000000..d4c740a
--- /dev/null
+++ b/SOURCES/glibc-rh1162847-p1.patch
@@ -0,0 +1,104 @@
+#
+# commit f8e3e9f31bfd71641418897228fa1732170b69cc
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Thu Oct 3 13:51:52 2013 +0930
+# 
+#     Correct little-endian relocation of UADDR64,32,16.
+# 
+#         * sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela):
+#         Correct handling of unaligned relocs for little-endian.
+#         * sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela): Likewise.
+# 
+diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c glibc-2.17-c758a686.mod/sysdeps/powerpc/powerpc32/dl-machine.c
+--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/powerpc/powerpc32/dl-machine.c	2014-11-11 18:51:36.140570654 -0500
+@@ -423,6 +423,12 @@
+ 			Elf32_Addr const finaladdr,
+ 			int rinfo)
+ {
++  union unaligned
++    {
++      unsigned u2 __attribute__ ((mode (HI)));
++      unsigned u4 __attribute__ ((mode (SI)));
++    } __attribute__((__packed__));
++
+   switch (rinfo)
+     {
+     case R_PPC_NONE:
+@@ -439,10 +445,7 @@
+       return;
+ 
+     case R_PPC_UADDR32:
+-      ((char *) reloc_addr)[0] = finaladdr >> 24;
+-      ((char *) reloc_addr)[1] = finaladdr >> 16;
+-      ((char *) reloc_addr)[2] = finaladdr >> 8;
+-      ((char *) reloc_addr)[3] = finaladdr;
++      ((union unaligned *) reloc_addr)->u4 = finaladdr;
+       break;
+ 
+     case R_PPC_ADDR24:
+@@ -460,8 +463,7 @@
+     case R_PPC_UADDR16:
+       if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0))
+ 	_dl_reloc_overflow (map,  "R_PPC_UADDR16", reloc_addr, refsym);
+-      ((char *) reloc_addr)[0] = finaladdr >> 8;
+-      ((char *) reloc_addr)[1] = finaladdr;
++      ((union unaligned *) reloc_addr)->u2 = finaladdr;
+       break;
+ 
+     case R_PPC_ADDR16_LO:
+diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686.mod/sysdeps/powerpc/powerpc64/dl-machine.h
+--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h	2012-12-24 22:02:13.000000000 -0500
++++ glibc-2.17-c758a686.mod/sysdeps/powerpc/powerpc64/dl-machine.h	2014-11-11 18:51:36.141570651 -0500
+@@ -561,6 +561,12 @@
+   Elf64_Addr *const reloc_addr = reloc_addr_arg;
+   const int r_type = ELF64_R_TYPE (reloc->r_info);
+   const Elf64_Sym *const refsym = sym;
++  union unaligned
++    {
++      unsigned u2 __attribute__ ((mode (HI)));
++      unsigned u4 __attribute__ ((mode (SI)));
++      unsigned u8 __attribute__ ((mode (DI)));
++    } __attribute__((__packed__));
+ 
+   if (r_type == R_PPC64_RELATIVE)
+     {
+@@ -742,23 +748,11 @@
+       return;
+ 
+     case R_PPC64_UADDR64:
+-      /* We are big-endian.  */
+-      ((char *) reloc_addr_arg)[0] = (value >> 56) & 0xff;
+-      ((char *) reloc_addr_arg)[1] = (value >> 48) & 0xff;
+-      ((char *) reloc_addr_arg)[2] = (value >> 40) & 0xff;
+-      ((char *) reloc_addr_arg)[3] = (value >> 32) & 0xff;
+-      ((char *) reloc_addr_arg)[4] = (value >> 24) & 0xff;
+-      ((char *) reloc_addr_arg)[5] = (value >> 16) & 0xff;
+-      ((char *) reloc_addr_arg)[6] = (value >> 8) & 0xff;
+-      ((char *) reloc_addr_arg)[7] = (value >> 0) & 0xff;
++      ((union unaligned *) reloc_addr)->u8 = value;
+       return;
+ 
+     case R_PPC64_UADDR32:
+-      /* We are big-endian.  */
+-      ((char *) reloc_addr_arg)[0] = (value >> 24) & 0xff;
+-      ((char *) reloc_addr_arg)[1] = (value >> 16) & 0xff;
+-      ((char *) reloc_addr_arg)[2] = (value >> 8) & 0xff;
+-      ((char *) reloc_addr_arg)[3] = (value >> 0) & 0xff;
++      ((union unaligned *) reloc_addr)->u4 = value;
+       return;
+ 
+     case R_PPC64_ADDR32:
+@@ -782,10 +776,8 @@
+     case R_PPC64_UADDR16:
+       if (dont_expect ((value + 0x8000) >= 0x10000))
+ 	_dl_reloc_overflow (map, "R_PPC64_UADDR16", reloc_addr, refsym);
+-      /* We are big-endian.  */
+-      ((char *) reloc_addr_arg)[0] = (value >> 8) & 0xff;
+-      ((char *) reloc_addr_arg)[1] = (value >> 0) & 0xff;
+-      break;
++      ((union unaligned *) reloc_addr)->u2 = value;
++      return;
+ 
+     case R_PPC64_ADDR16_DS:
+       if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
diff --git a/SOURCES/glibc-rh1162847-p2.patch b/SOURCES/glibc-rh1162847-p2.patch
new file mode 100644
index 0000000..9192278
--- /dev/null
+++ b/SOURCES/glibc-rh1162847-p2.patch
@@ -0,0 +1,45 @@
+#
+# commit 4cb81307b3771672864fa3a7498bd39c13267a00
+# Author: Alan Modra <amodra@gmail.com>
+# Date:   Fri Oct 4 12:48:51 2013 +0930
+# 
+#     Use stdint.h types in union unaligned.
+# 
+#         * sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela):
+#         Use stdint types in rather than __attribute__((mode())).
+#         * sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela): Likewise.
+# 
+diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
+index f81899a..aba3618 100644
+--- a/sysdeps/powerpc/powerpc32/dl-machine.c
++++ b/sysdeps/powerpc/powerpc32/dl-machine.c
+@@ -418,8 +418,8 @@ __process_machine_rela (struct link_map *map,
+ {
+   union unaligned
+     {
+-      unsigned u2 __attribute__ ((mode (HI)));
+-      unsigned u4 __attribute__ ((mode (SI)));
++      uint16_t u2;
++      uint32_t u4;
+     } __attribute__((__packed__));
+ 
+   switch (rinfo)
+diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
+index b69a1ce..18cf157 100644
+--- a/sysdeps/powerpc/powerpc64/dl-machine.h
++++ b/sysdeps/powerpc/powerpc64/dl-machine.h
+@@ -563,10 +563,10 @@ elf_machine_rela (struct link_map *map,
+   const Elf64_Sym *const refsym = sym;
+   union unaligned
+     {
+-      unsigned u2 __attribute__ ((mode (HI)));
+-      unsigned u4 __attribute__ ((mode (SI)));
+-      unsigned u8 __attribute__ ((mode (DI)));
+-    } __attribute__((__packed__));
++      uint16_t u2;
++      uint32_t u4;
++      uint64_t u8;
++    } __attribute__ ((__packed__));
+ 
+   if (r_type == R_PPC64_RELATIVE)
+     {
diff --git a/SOURCES/glibc-rh1165192.patch b/SOURCES/glibc-rh1165192.patch
new file mode 100644
index 0000000..41e2591
--- /dev/null
+++ b/SOURCES/glibc-rh1165192.patch
@@ -0,0 +1,155 @@
+#
+# EMARGOED!!! -- EMBARGOED!!! -- EMBARGOED!!!
+# EMARGOED!!! -- EMBARGOED!!! -- EMBARGOED!!!
+# EMARGOED!!! -- EMBARGOED!!! -- EMBARGOED!!!
+# Release date is RHEL 7.1 RC.
+# CVE-2014-8121:
+# Unexpected closing of nss_files databases after lookups causes denial of service 
+# EMARGOED!!! -- EMBARGOED!!! -- EMBARGOED!!!
+# EMARGOED!!! -- EMBARGOED!!! -- EMBARGOED!!!
+# EMARGOED!!! -- EMBARGOED!!! -- EMBARGOED!!!
+#
+diff -up glibc-2.17-c758a686/nss/Makefile.rh1165192 glibc-2.17-c758a686/nss/Makefile
+--- glibc-2.17-c758a686/nss/Makefile.rh1165192	2015-01-14 21:22:57.558006945 +0100
++++ glibc-2.17-c758a686/nss/Makefile	2015-01-14 21:44:59.657777124 +0100
+@@ -38,7 +38,7 @@ install-bin             := getent makedb
+ makedb-modules = xmalloc hash-string
+ extra-objs		+= $(makedb-modules:=.o)
+ 
+-tests			= test-netdb tst-nss-test1
++tests			= test-netdb tst-nss-test1 tst-nss-getpwent
+ xtests			= bug-erange
+ 
+ include ../Makeconfig
+diff -up glibc-2.17-c758a686/nss/nss_files/files-XXX.c.rh1165192 glibc-2.17-c758a686/nss/nss_files/files-XXX.c
+--- glibc-2.17-c758a686/nss/nss_files/files-XXX.c.rh1165192	2015-01-14 21:22:14.630721754 +0100
++++ glibc-2.17-c758a686/nss/nss_files/files-XXX.c	2015-01-14 21:22:15.072725814 +0100
+@@ -135,7 +135,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stay
+ 
+   __libc_lock_lock (lock);
+ 
+-  status = internal_setent (stayopen);
++  status = internal_setent (1);
+ 
+   if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
+     {
+diff -up glibc-2.17-c758a686/nss/tst-nss-getpwent.c.rh1165192 glibc-2.17-c758a686/nss/tst-nss-getpwent.c
+--- glibc-2.17-c758a686/nss/tst-nss-getpwent.c.rh1165192	2015-01-14 21:23:50.003236107 +0100
++++ glibc-2.17-c758a686/nss/tst-nss-getpwent.c	2015-01-14 21:46:39.912194368 +0100
+@@ -0,0 +1,116 @@
++/* 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/SOURCES/glibc-rh1170187.patch b/SOURCES/glibc-rh1170187.patch
deleted file mode 100644
index 4ea2762..0000000
--- a/SOURCES/glibc-rh1170187.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-commit e276f4f310a89a925dd59e583f7a1bef2114d9a7
-Author: Siddhesh Poyarekar <siddhesh@redhat.com>
-Date:   Tue Nov 25 21:15:16 2014 +0530
-
-    ftell: seek to end only when there are unflushed bytes (BZ #17647)
-    
-    Currently we seek to end of file if there are unflushed writes or the
-    stream is in write mode, to get the current offset for writing in
-    append mode, which is the end of file.  The latter case (i.e. stream
-    is in write mode, but no unflushed writes) is unnecessary since it
-    will only happen when the stream has just been flushed, in which case
-    the recorded offset ought to be reliable.
-    
-    Removing that case lets ftell give the correct offset when it follows
-    an ftruncate.  The latter truncates the file, but does not change the
-    file position, due to which it is permissible to call ftell without an
-    intervening fseek call.
-    
-    Tested on x86_64 to verify that the added test case fails without the
-    patch and succeeds with it, and that there are no additional
-    regressions due to it.
-    
-    	[BZ #17647]
-    	* libio/fileops.c (do_ftell): Seek only when there are
-    	unflushed writes.
-    	* libio/wfileops.c (do_ftell_wide): Likewise.
-    	* libio/tst-ftell-active-handler.c (do_ftruncate_test): New
-    	test case.
-    	(do_one_test): Call it.
-
-diff --git a/libio/fileops.c b/libio/fileops.c
-index e0d7b76..1fc5719 100644
---- a/libio/fileops.c
-+++ b/libio/fileops.c
-@@ -943,15 +943,14 @@ do_ftell (_IO_FILE *fp)
-      yet.  */
-   if (fp->_IO_buf_base != NULL)
-     {
--      bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
--			  || _IO_in_put_mode (fp));
-+      bool unflushed_writes = (fp->_IO_write_ptr > fp->_IO_write_base);
- 
-       bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
- 
-       /* When we have unflushed writes in append mode, seek to the end of the
- 	 file and record that offset.  This is the only time we change the file
- 	 stream state and it is safe since the file handle is active.  */
--      if (was_writing && append_mode)
-+      if (unflushed_writes && append_mode)
- 	{
- 	  result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
- 	  if (result == _IO_pos_BAD)
-@@ -961,7 +960,7 @@ do_ftell (_IO_FILE *fp)
- 	}
- 
-       /* Adjust for unflushed data.  */
--      if (!was_writing)
-+      if (!unflushed_writes)
- 	offset -= fp->_IO_read_end - fp->_IO_read_ptr;
-       /* We don't trust _IO_read_end to represent the current file offset when
- 	 writing in append mode because the value would have to be shifted to
-diff --git a/libio/tst-ftell-active-handler.c b/libio/tst-ftell-active-handler.c
-index e9dc7b3..9f23c55 100644
---- a/libio/tst-ftell-active-handler.c
-+++ b/libio/tst-ftell-active-handler.c
-@@ -88,6 +88,95 @@ static size_t file_len;
- typedef int (*fputs_func_t) (const void *data, FILE *fp);
- fputs_func_t fputs_func;
- 
-+/* This test verifies that the offset reported by ftell is correct after the
-+   file is truncated using ftruncate.  ftruncate does not change the file
-+   offset on truncation and hence, SEEK_CUR should continue to point to the
-+   old offset and not be changed to the new offset.  */
-+static int
-+do_ftruncate_test (const char *filename)
-+{
-+  FILE *fp = NULL;
-+  int fd;
-+  int ret = 0;
-+  struct test
-+    {
-+      const char *mode;
-+      int fd_mode;
-+    } test_modes[] = {
-+	  {"r+", O_RDWR},
-+	  {"w", O_WRONLY},
-+	  {"w+", O_RDWR},
-+	  {"a", O_WRONLY},
-+	  {"a+", O_RDWR}
-+    };
-+
-+  for (int j = 0; j < 2; j++)
-+    {
-+      for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++)
-+	{
-+	  int fileret;
-+	  printf ("\tftruncate: %s (file, \"%s\"): ",
-+		  j == 0 ? "fopen" : "fdopen",
-+		  test_modes[i].mode);
-+
-+	  if (j == 0)
-+	    fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode);
-+	  else
-+	    fileret = get_handles_fdopen (filename, fd, fp,
-+					  test_modes[i].fd_mode,
-+					  test_modes[i].mode);
-+
-+	  if (fileret != 0)
-+	    return fileret;
-+
-+	  /* Write some data.  */
-+	  size_t written = fputs_func (data, fp);
-+
-+	  if (written == EOF)
-+	    {
-+	      printf ("fputs[1] failed to write data\n");
-+	      ret |= 1;
-+	    }
-+
-+	  /* Record the offset.  */
-+	  long offset = ftell (fp);
-+
-+	  /* Flush data to allow switching active handles.  */
-+	  if (fflush (fp))
-+	    {
-+	      printf ("Flush failed: %m\n");
-+	      ret |= 1;
-+	    }
-+
-+	  /* Now truncate the file.  */
-+	  if (ftruncate (fd, 0) != 0)
-+	    {
-+	      printf ("Failed to truncate file: %m\n");
-+	      ret |= 1;
-+	    }
-+
-+	  /* ftruncate does not change the offset, so there is no need to call
-+	     anything to be able to switch active handles.  */
-+	  long new_offset = ftell (fp);
-+
-+	  /* The offset should remain unchanged since ftruncate does not update
-+	     it.  */
-+	  if (offset != new_offset)
-+	    {
-+	      printf ("Incorrect offset.  Expected %zu, but got %ld\n",
-+		      offset, new_offset);
-+
-+	      ret |= 1;
-+	    }
-+	  else
-+	    printf ("offset = %ld\n", offset);
-+
-+	  fclose (fp);
-+	}
-+    }
-+
-+  return ret;
-+}
- /* Test that ftell output after a rewind is correct.  */
- static int
- do_rewind_test (const char *filename)
-@@ -481,6 +570,7 @@ do_one_test (const char *filename)
-   ret |= do_write_test (filename);
-   ret |= do_append_test (filename);
-   ret |= do_rewind_test (filename);
-+  ret |= do_ftruncate_test (filename);
- 
-   return ret;
- }
-diff --git a/libio/wfileops.c b/libio/wfileops.c
-index 6a088b1..71281c1 100644
---- a/libio/wfileops.c
-+++ b/libio/wfileops.c
-@@ -626,16 +626,15 @@ do_ftell_wide (_IO_FILE *fp)
-       const wchar_t *wide_read_base;
-       const wchar_t *wide_read_ptr;
-       const wchar_t *wide_read_end;
--      bool was_writing = ((fp->_wide_data->_IO_write_ptr
--			   > fp->_wide_data->_IO_write_base)
--			  || _IO_in_put_mode (fp));
-+      bool unflushed_writes = (fp->_wide_data->_IO_write_ptr
-+			       > fp->_wide_data->_IO_write_base);
- 
-       bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
- 
-       /* When we have unflushed writes in append mode, seek to the end of the
- 	 file and record that offset.  This is the only time we change the file
- 	 stream state and it is safe since the file handle is active.  */
--      if (was_writing && append_mode)
-+      if (unflushed_writes && append_mode)
- 	{
- 	  result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
- 	  if (result == _IO_pos_BAD)
-@@ -674,7 +673,7 @@ do_ftell_wide (_IO_FILE *fp)
-       struct _IO_codecvt *cv = fp->_codecvt;
-       int clen = (*cv->__codecvt_do_encoding) (cv);
- 
--      if (!was_writing)
-+      if (!unflushed_writes)
- 	{
- 	  if (clen > 0)
- 	    {
diff --git a/SOURCES/glibc-rh1183535.patch b/SOURCES/glibc-rh1183535.patch
deleted file mode 100644
index a2249c9..0000000
--- a/SOURCES/glibc-rh1183535.patch
+++ /dev/null
@@ -1,232 +0,0 @@
-commit d5dd6189d506068ed11c8bfa1e1e9bffde04decd
-Author: Andreas Schwab <schwab@suse.de>
-Date:   Mon Jan 21 17:41:28 2013 +0100
-
-    Fix parsing of numeric hosts in gethostbyname_r
-
-diff --git a/nss/Makefile b/nss/Makefile
-index 449a258..553eafa 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
-+tests			= test-netdb tst-nss-test1 test-digits-dots
- xtests			= bug-erange
- 
- include ../Makeconfig
-diff --git a/nss/digits_dots.c b/nss/digits_dots.c
-index 2b86295..e007ef4 100644
---- a/nss/digits_dots.c
-+++ b/nss/digits_dots.c
-@@ -46,7 +46,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
-     {
-       if (h_errnop)
- 	*h_errnop = NETDB_INTERNAL;
--      *result = NULL;
-+      if (buffer_size == NULL)
-+	*status = NSS_STATUS_TRYAGAIN;
-+      else
-+	*result = NULL;
-       return -1;
-     }
- 
-@@ -83,14 +86,16 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
- 	}
- 
-       size_needed = (sizeof (*host_addr)
--		     + sizeof (*h_addr_ptrs) + strlen (name) + 1);
-+		     + sizeof (*h_addr_ptrs)
-+		     + sizeof (*h_alias_ptr) + strlen (name) + 1);
- 
-       if (buffer_size == NULL)
-         {
- 	  if (buflen < size_needed)
- 	    {
-+	      *status = NSS_STATUS_TRYAGAIN;
- 	      if (h_errnop != NULL)
--		*h_errnop = TRY_AGAIN;
-+		*h_errnop = NETDB_INTERNAL;
- 	      __set_errno (ERANGE);
- 	      goto done;
- 	    }
-@@ -109,7 +114,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
- 	      *buffer_size = 0;
- 	      __set_errno (save);
- 	      if (h_errnop != NULL)
--		*h_errnop = TRY_AGAIN;
-+		*h_errnop = NETDB_INTERNAL;
- 	      *result = NULL;
- 	      goto done;
- 	    }
-@@ -149,7 +154,9 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
- 		  if (! ok)
- 		    {
- 		      *h_errnop = HOST_NOT_FOUND;
--		      if (buffer_size)
-+		      if (buffer_size == NULL)
-+			*status = NSS_STATUS_NOTFOUND;
-+		      else
- 			*result = NULL;
- 		      goto done;
- 		    }
-@@ -190,7 +197,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
- 		  if (buffer_size == NULL)
- 		    *status = NSS_STATUS_SUCCESS;
- 		  else
--		   *result = resbuf;
-+		    *result = resbuf;
- 		  goto done;
- 		}
- 
-@@ -201,15 +208,6 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
- 
-       if ((isxdigit (name[0]) && strchr (name, ':') != NULL) || name[0] == ':')
- 	{
--	  const char *cp;
--	  char *hostname;
--	  typedef unsigned char host_addr_t[16];
--	  host_addr_t *host_addr;
--	  typedef char *host_addr_list_t[2];
--	  host_addr_list_t *h_addr_ptrs;
--	  size_t size_needed;
--	  int addr_size;
--
- 	  switch (af)
- 	    {
- 	    default:
-@@ -225,7 +223,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
- 	      /* This is not possible.  We cannot represent an IPv6 address
- 		 in an `struct in_addr' variable.  */
- 	      *h_errnop = HOST_NOT_FOUND;
--	      *result = NULL;
-+	      if (buffer_size == NULL)
-+		*status = NSS_STATUS_NOTFOUND;
-+	      else
-+		*result = NULL;
- 	      goto done;
- 
- 	    case AF_INET6:
-@@ -233,42 +234,6 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
- 	      break;
- 	    }
- 
--	  size_needed = (sizeof (*host_addr)
--			 + sizeof (*h_addr_ptrs) + strlen (name) + 1);
--
--	  if (buffer_size == NULL && buflen < size_needed)
--	    {
--	      if (h_errnop != NULL)
--		*h_errnop = TRY_AGAIN;
--	      __set_errno (ERANGE);
--	      goto done;
--	    }
--	  else if (buffer_size != NULL && *buffer_size < size_needed)
--	    {
--	      char *new_buf;
--	      *buffer_size = size_needed;
--	      new_buf = realloc (*buffer, *buffer_size);
--
--	      if (new_buf == NULL)
--		{
--		  save = errno;
--		  free (*buffer);
--		  __set_errno (save);
--		  *buffer = NULL;
--		  *buffer_size = 0;
--		  *result = NULL;
--		  goto done;
--		}
--	      *buffer = new_buf;
--	    }
--
--	  memset (*buffer, '\0', size_needed);
--
--	  host_addr = (host_addr_t *) *buffer;
--	  h_addr_ptrs = (host_addr_list_t *)
--	    ((char *) host_addr + sizeof (*host_addr));
--	  hostname = (char *) h_addr_ptrs + sizeof (*h_addr_ptrs);
--
- 	  for (cp = name;; ++cp)
- 	    {
- 	      if (!*cp)
-@@ -281,7 +246,9 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
- 		  if (inet_pton (AF_INET6, name, host_addr) <= 0)
- 		    {
- 		      *h_errnop = HOST_NOT_FOUND;
--		      if (buffer_size)
-+		      if (buffer_size == NULL)
-+			*status = NSS_STATUS_NOTFOUND;
-+		      else
- 			*result = NULL;
- 		      goto done;
- 		    }
-diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
-index 1067744..44d00f4 100644
---- a/nss/getXXbyYY_r.c
-+++ b/nss/getXXbyYY_r.c
-@@ -179,6 +179,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
-     case -1:
-       return errno;
-     case 1:
-+#ifdef NEED_H_ERRNO
-+      any_service = true;
-+#endif
-       goto done;
-     }
- #endif
-@@ -288,7 +291,7 @@ done:
-     /* This happens when we weren't able to use a service for reasons other
-        than the module not being found.  In such a case, we'd want to tell the
-        caller that errno has the real reason for failure.  */
--      *h_errnop = NETDB_INTERNAL;
-+    *h_errnop = NETDB_INTERNAL;
-   else if (status != NSS_STATUS_SUCCESS && !any_service)
-     /* We were not able to use any service.  */
-     *h_errnop = NO_RECOVERY;
-diff --git a/nss/test-digits-dots.c b/nss/test-digits-dots.c
-new file mode 100644
-index 0000000..1efa344
---- /dev/null
-+++ b/nss/test-digits-dots.c
-@@ -0,0 +1,38 @@
-+/* 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/>.  */
-+
-+/* Testcase for BZ #15014 */
-+
-+#include <stdlib.h>
-+#include <netdb.h>
-+#include <errno.h>
-+
-+static int
-+do_test (void)
-+{
-+  char buf[32];
-+  struct hostent *result = NULL;
-+  struct hostent ret;
-+  int h_err = 0;
-+  int err;
-+
-+  err = gethostbyname_r ("1.2.3.4", &ret, buf, sizeof (buf), &result, &h_err);
-+  return err == ERANGE && h_err == NETDB_INTERNAL ? EXIT_SUCCESS : EXIT_FAILURE;
-+}
-+
-+#define TEST_FUNCTION do_test ()
-+#include "../test-skeleton.c"
diff --git a/SOURCES/glibc-rh1183545.patch b/SOURCES/glibc-rh1183545.patch
new file mode 100644
index 0000000..ad7a679
--- /dev/null
+++ b/SOURCES/glibc-rh1183545.patch
@@ -0,0 +1,233 @@
+commit d5dd6189d506068ed11c8bfa1e1e9bffde04decd
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Mon Jan 21 17:41:28 2013 +0100
+
+    Fix parsing of numeric hosts in gethostbyname_r
+
+diff --git a/nss/Makefile b/nss/Makefile
+index 449a258..553eafa 100644
+--- a/nss/Makefile
++++ b/nss/Makefile
+@@ -37,7 +37,8 @@ install-bin             := getent makedb
+ makedb-modules = xmalloc hash-string
+ extra-objs		+= $(makedb-modules:=.o)
+ 
+-tests			= test-netdb tst-nss-test1 tst-nss-getpwent
++tests			= test-netdb tst-nss-test1 tst-nss-getpwent \
++			 test-digits-dots
+ xtests			= bug-erange
+ 
+ include ../Makeconfig
+diff --git a/nss/digits_dots.c b/nss/digits_dots.c
+index 2b86295..e007ef4 100644
+--- a/nss/digits_dots.c
++++ b/nss/digits_dots.c
+@@ -46,7 +46,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+     {
+       if (h_errnop)
+ 	*h_errnop = NETDB_INTERNAL;
+-      *result = NULL;
++      if (buffer_size == NULL)
++	*status = NSS_STATUS_TRYAGAIN;
++      else
++	*result = NULL;
+       return -1;
+     }
+ 
+@@ -83,14 +86,16 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+ 	}
+ 
+       size_needed = (sizeof (*host_addr)
+-		     + sizeof (*h_addr_ptrs) + strlen (name) + 1);
++		     + sizeof (*h_addr_ptrs)
++		     + sizeof (*h_alias_ptr) + strlen (name) + 1);
+ 
+       if (buffer_size == NULL)
+         {
+ 	  if (buflen < size_needed)
+ 	    {
++	      *status = NSS_STATUS_TRYAGAIN;
+ 	      if (h_errnop != NULL)
+-		*h_errnop = TRY_AGAIN;
++		*h_errnop = NETDB_INTERNAL;
+ 	      __set_errno (ERANGE);
+ 	      goto done;
+ 	    }
+@@ -109,7 +114,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+ 	      *buffer_size = 0;
+ 	      __set_errno (save);
+ 	      if (h_errnop != NULL)
+-		*h_errnop = TRY_AGAIN;
++		*h_errnop = NETDB_INTERNAL;
+ 	      *result = NULL;
+ 	      goto done;
+ 	    }
+@@ -149,7 +154,9 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+ 		  if (! ok)
+ 		    {
+ 		      *h_errnop = HOST_NOT_FOUND;
+-		      if (buffer_size)
++		      if (buffer_size == NULL)
++			*status = NSS_STATUS_NOTFOUND;
++		      else
+ 			*result = NULL;
+ 		      goto done;
+ 		    }
+@@ -190,7 +197,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+ 		  if (buffer_size == NULL)
+ 		    *status = NSS_STATUS_SUCCESS;
+ 		  else
+-		   *result = resbuf;
++		    *result = resbuf;
+ 		  goto done;
+ 		}
+ 
+@@ -201,15 +208,6 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+ 
+       if ((isxdigit (name[0]) && strchr (name, ':') != NULL) || name[0] == ':')
+ 	{
+-	  const char *cp;
+-	  char *hostname;
+-	  typedef unsigned char host_addr_t[16];
+-	  host_addr_t *host_addr;
+-	  typedef char *host_addr_list_t[2];
+-	  host_addr_list_t *h_addr_ptrs;
+-	  size_t size_needed;
+-	  int addr_size;
+-
+ 	  switch (af)
+ 	    {
+ 	    default:
+@@ -225,7 +223,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+ 	      /* This is not possible.  We cannot represent an IPv6 address
+ 		 in an `struct in_addr' variable.  */
+ 	      *h_errnop = HOST_NOT_FOUND;
+-	      *result = NULL;
++	      if (buffer_size == NULL)
++		*status = NSS_STATUS_NOTFOUND;
++	      else
++		*result = NULL;
+ 	      goto done;
+ 
+ 	    case AF_INET6:
+@@ -233,42 +234,6 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+ 	      break;
+ 	    }
+ 
+-	  size_needed = (sizeof (*host_addr)
+-			 + sizeof (*h_addr_ptrs) + strlen (name) + 1);
+-
+-	  if (buffer_size == NULL && buflen < size_needed)
+-	    {
+-	      if (h_errnop != NULL)
+-		*h_errnop = TRY_AGAIN;
+-	      __set_errno (ERANGE);
+-	      goto done;
+-	    }
+-	  else if (buffer_size != NULL && *buffer_size < size_needed)
+-	    {
+-	      char *new_buf;
+-	      *buffer_size = size_needed;
+-	      new_buf = realloc (*buffer, *buffer_size);
+-
+-	      if (new_buf == NULL)
+-		{
+-		  save = errno;
+-		  free (*buffer);
+-		  __set_errno (save);
+-		  *buffer = NULL;
+-		  *buffer_size = 0;
+-		  *result = NULL;
+-		  goto done;
+-		}
+-	      *buffer = new_buf;
+-	    }
+-
+-	  memset (*buffer, '\0', size_needed);
+-
+-	  host_addr = (host_addr_t *) *buffer;
+-	  h_addr_ptrs = (host_addr_list_t *)
+-	    ((char *) host_addr + sizeof (*host_addr));
+-	  hostname = (char *) h_addr_ptrs + sizeof (*h_addr_ptrs);
+-
+ 	  for (cp = name;; ++cp)
+ 	    {
+ 	      if (!*cp)
+@@ -281,7 +246,9 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf,
+ 		  if (inet_pton (AF_INET6, name, host_addr) <= 0)
+ 		    {
+ 		      *h_errnop = HOST_NOT_FOUND;
+-		      if (buffer_size)
++		      if (buffer_size == NULL)
++			*status = NSS_STATUS_NOTFOUND;
++		      else
+ 			*result = NULL;
+ 		      goto done;
+ 		    }
+diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
+index 1067744..44d00f4 100644
+--- a/nss/getXXbyYY_r.c
++++ b/nss/getXXbyYY_r.c
+@@ -179,6 +179,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
+     case -1:
+       return errno;
+     case 1:
++#ifdef NEED_H_ERRNO
++      any_service = true;
++#endif
+       goto done;
+     }
+ #endif
+@@ -288,7 +291,7 @@ done:
+     /* This happens when we weren't able to use a service for reasons other
+        than the module not being found.  In such a case, we'd want to tell the
+        caller that errno has the real reason for failure.  */
+-      *h_errnop = NETDB_INTERNAL;
++    *h_errnop = NETDB_INTERNAL;
+   else if (status != NSS_STATUS_SUCCESS && !any_service)
+     /* We were not able to use any service.  */
+     *h_errnop = NO_RECOVERY;
+diff --git a/nss/test-digits-dots.c b/nss/test-digits-dots.c
+new file mode 100644
+index 0000000..1efa344
+--- /dev/null
++++ b/nss/test-digits-dots.c
+@@ -0,0 +1,38 @@
++/* 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/>.  */
++
++/* Testcase for BZ #15014 */
++
++#include <stdlib.h>
++#include <netdb.h>
++#include <errno.h>
++
++static int
++do_test (void)
++{
++  char buf[32];
++  struct hostent *result = NULL;
++  struct hostent ret;
++  int h_err = 0;
++  int err;
++
++  err = gethostbyname_r ("1.2.3.4", &ret, buf, sizeof (buf), &result, &h_err);
++  return err == ERANGE && h_err == NETDB_INTERNAL ? EXIT_SUCCESS : EXIT_FAILURE;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
diff --git a/SOURCES/glibc-rh731837-00.patch b/SOURCES/glibc-rh731837-00.patch
new file mode 100644
index 0000000..0283612
--- /dev/null
+++ b/SOURCES/glibc-rh731837-00.patch
@@ -0,0 +1,211 @@
+From 5315ec1fd24b4f2ae6e8fa624e14da15a8efdd84 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 04:42:49 -0500
+Subject: [PATCH] PowerPC: Adjust multiarch Implies for PowerPC64
+
+commit 5e6a4d4b9eb579c5ca606c0eed1f2f40e405a5f1
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:29:27 2013 -0500
+
+    PowerPC: Adjust multiarch Implies for PowerPC64
+
+    This patch adds Implies files on multiarch folder for POWER chips so
+    multirach is enabled when building with --with-cpu and powerN
+    option.
+
+The following file changed in the above commit is ignored as its part of already existing patch.
+sysdeps/powerpc/powerpc64/power5/Implies
+The following file changed in the above commit is ignored as this file is not present at 2.17 code.
+sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies
+---
+ sysdeps/powerpc/powerpc64/power4/fpu/Implies              | 1 +
+ sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies    | 1 +
+ sysdeps/powerpc/powerpc64/power4/multiarch/Implies        | 1 +
+ sysdeps/powerpc/powerpc64/power5+/fpu/Implies             | 1 +
+ sysdeps/powerpc/powerpc64/power5+/multiarch/Implies       | 1 +
+ sysdeps/powerpc/powerpc64/power5/fpu/Implies              | 1 +
+ sysdeps/powerpc/powerpc64/power5/multiarch/Implies        | 1 +
+ sysdeps/powerpc/powerpc64/power6/fpu/Implies              | 1 +
+ sysdeps/powerpc/powerpc64/power6/multiarch/Implies        | 1 +
+ sysdeps/powerpc/powerpc64/power7/fpu/Implies              | 1 +
+ sysdeps/powerpc/powerpc64/power7/multiarch/Implies        | 1 +
+ sysdeps/powerpc/powerpc64/power8/fpu/Implies              | 1 +
+ sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies    | 1 +
+ sysdeps/powerpc/powerpc64/power8/multiarch/Implies        | 1 +
+ sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies  | 2 --
+ sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies | 2 --
+ sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies  | 2 --
+ sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies  | 2 --
+ sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies | 2 --
+ sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies  | 2 --
+ 20 files changed, 14 insertions(+), 12 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power4/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power5+/fpu/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power5+/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power5/fpu/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power5/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power6/fpu/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power6/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power7/fpu/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power7/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power8/fpu/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power8/multiarch/Implies
+ delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies
+ delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies
+ delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies
+ delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies
+ delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies
+ delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies
+
+diff --git a/sysdeps/powerpc/powerpc64/power4/fpu/Implies b/sysdeps/powerpc/powerpc64/power4/fpu/Implies
+new file mode 100644
+index 0000000..c1f617b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power4/fpu/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/fpu
+diff --git a/sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies
+new file mode 100644
+index 0000000..8d6531a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/fpu/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power4/multiarch/Implies b/sysdeps/powerpc/powerpc64/power4/multiarch/Implies
+new file mode 100644
+index 0000000..30edcf7
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power4/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/Implies b/sysdeps/powerpc/powerpc64/power5+/fpu/Implies
+new file mode 100644
+index 0000000..f00c50f
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power5+/fpu/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power5/fpu
+diff --git a/sysdeps/powerpc/powerpc64/power5+/multiarch/Implies b/sysdeps/powerpc/powerpc64/power5+/multiarch/Implies
+new file mode 100644
+index 0000000..0851b19
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power5+/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power5/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power5/fpu/Implies b/sysdeps/powerpc/powerpc64/power5/fpu/Implies
+new file mode 100644
+index 0000000..558a5fb
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power5/fpu/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power4/fpu
+diff --git a/sysdeps/powerpc/powerpc64/power5/multiarch/Implies b/sysdeps/powerpc/powerpc64/power5/multiarch/Implies
+new file mode 100644
+index 0000000..9a3cbb0
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power5/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power4/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power6/fpu/Implies b/sysdeps/powerpc/powerpc64/power6/fpu/Implies
+new file mode 100644
+index 0000000..f09854e
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power6/fpu/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power5+/fpu
+diff --git a/sysdeps/powerpc/powerpc64/power6/multiarch/Implies b/sysdeps/powerpc/powerpc64/power6/multiarch/Implies
+new file mode 100644
+index 0000000..2ebe304
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power6/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power5+/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power7/fpu/Implies b/sysdeps/powerpc/powerpc64/power7/fpu/Implies
+new file mode 100644
+index 0000000..30fa176
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power7/fpu/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power6/fpu
+diff --git a/sysdeps/powerpc/powerpc64/power7/multiarch/Implies b/sysdeps/powerpc/powerpc64/power7/multiarch/Implies
+new file mode 100644
+index 0000000..bf5d617
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power7/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power6/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/Implies b/sysdeps/powerpc/powerpc64/power8/fpu/Implies
+new file mode 100644
+index 0000000..8447198
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power8/fpu/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power7/fpu
+diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies
+new file mode 100644
+index 0000000..7fd86fd
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power7/fpu/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power8/multiarch/Implies b/sysdeps/powerpc/powerpc64/power8/multiarch/Implies
+new file mode 100644
+index 0000000..1fc7b7c
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power8/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power7/multiarch
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies
+deleted file mode 100644
+index bedb20b..0000000
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies
++++ /dev/null
+@@ -1,2 +0,0 @@
+-powerpc/powerpc64/power4/fpu
+-powerpc/powerpc64/power4
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies
+deleted file mode 100644
+index 4c782d4..0000000
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies
++++ /dev/null
+@@ -1,2 +0,0 @@
+-powerpc/powerpc64/power5+/fpu
+-powerpc/powerpc64/power5+
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies
+deleted file mode 100644
+index a01a13a..0000000
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies
++++ /dev/null
+@@ -1,2 +0,0 @@
+-powerpc/powerpc64/power5/fpu
+-powerpc/powerpc64/power5
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies
+deleted file mode 100644
+index 9d68f39..0000000
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies
++++ /dev/null
+@@ -1,2 +0,0 @@
+-powerpc/powerpc64/power6/fpu
+-powerpc/powerpc64/power6
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies
+deleted file mode 100644
+index 9019778..0000000
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies
++++ /dev/null
+@@ -1,2 +0,0 @@
+-powerpc/powerpc64/power6x/fpu
+-powerpc/powerpc64/power6x
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies
+deleted file mode 100644
+index 9a5e3c7..0000000
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies
++++ /dev/null
+@@ -1,2 +0,0 @@
+-powerpc/powerpc64/power7/fpu
+-powerpc/powerpc64/power7
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-01.patch b/SOURCES/glibc-rh731837-01.patch
new file mode 100644
index 0000000..0d29a89
--- /dev/null
+++ b/SOURCES/glibc-rh731837-01.patch
@@ -0,0 +1,538 @@
+From 46450f90b70326319f8dc7f0e447e14f0cbd95e6 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:01:14 -0500
+Subject: [PATCH] PowerPC: multiarch memcpy for PowerPC64
+
+commit b5beafbceec80b5a33d3383dde88196afc966e67 Author:
+ Adhemerval Zanella <azanella@linux.vnet.ibm.com> Date:   Fri Dec 13 14:31:41
+ 2013 -0500
+
+    PowerPC: multiarch memcpy for PowerPC64
+
+Added sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h which was not part
+of original commit
+---
+ .../powerpc/powerpc32/power4/multiarch/init-arch.h | 52 +++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  4 ++
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  | 66 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/init-arch.h    | 18 ++++++
+ sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S    | 39 +++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S  | 39 +++++++++++++
+ .../powerpc/powerpc64/multiarch/memcpy-power4.S    | 39 +++++++++++++
+ .../powerpc/powerpc64/multiarch/memcpy-power6.S    | 39 +++++++++++++
+ .../powerpc/powerpc64/multiarch/memcpy-power7.S    | 39 +++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S | 41 ++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memcpy.c       | 55 ++++++++++++++++++
+ 11 files changed, 431 insertions(+)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/Makefile
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/init-arch.h
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy.c
+
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
+new file mode 100644
+index 0000000..51a34f2
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
+@@ -0,0 +1,52 @@
++/* This file is part of the GNU C Library.
++   Copyright (C) 2013-2014 Free Software Foundation, Inc.
++
++   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 <ldsodefs.h>
++
++/* The code checks if _rtld_global_ro was realocated before trying to access
++   the dl_hwcap field. The assembly is to make the compiler not optimize the
++   test (&_rtld_global_ro != NULL), which is always true in ISO C (but not
++   in that case since _rtld_global_ro might not been realocated yet).  */
++#if defined(SHARED) && !defined(IS_IN_rtld)
++# define __GLRO(value) \
++  ({ volatile void **__p = (volatile void**)(&_rtld_global_ro);	\
++    unsigned long int __ret;					\
++     asm ("# x in %0" : "+r" (__p));				\
++     __ret = (__p) ? GLRO(value) : 0;				\
++     __ret; })
++#else
++# define __GLRO(value)  GLRO(value)
++#endif
++
++/* dl_hwcap contains only the latest supported ISA, the macro checks which is
++   and fills the previous ones.  */
++#define INIT_ARCH() \
++  unsigned long int hwcap = __GLRO(dl_hwcap); 			\
++  if (hwcap & PPC_FEATURE_ARCH_2_06)				\
++    hwcap |= PPC_FEATURE_ARCH_2_05 |				\
++	     PPC_FEATURE_POWER5_PLUS |				\
++	     PPC_FEATURE_POWER5 |				\
++	     PPC_FEATURE_POWER4;				\
++  else if (hwcap & PPC_FEATURE_ARCH_2_05)			\
++    hwcap |= PPC_FEATURE_POWER5_PLUS |				\
++	     PPC_FEATURE_POWER5 |				\
++	     PPC_FEATURE_POWER4;				\
++  else if (hwcap & PPC_FEATURE_POWER5_PLUS)			\
++    hwcap |= PPC_FEATURE_POWER5 |				\
++	     PPC_FEATURE_POWER4;				\
++  else if (hwcap & PPC_FEATURE_POWER5)				\
++    hwcap |= PPC_FEATURE_POWER4;
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+new file mode 100644
+index 0000000..638c102
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -0,0 +1,4 @@
++ifeq ($(subdir),string)
++sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
++                  memcpy-power4 memcpy-ppc64
++endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+new file mode 100644
+index 0000000..5090af4
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -0,0 +1,66 @@
++/* Enumerate available IFUNC implementations of a function.  PowerPC64 version.
++   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 <assert.h>
++#include <string.h>
++#include <wchar.h>
++#include <ldsodefs.h>
++#include <ifunc-impl-list.h>
++
++/* Maximum number of IFUNC implementations.  */
++#define MAX_IFUNC      6
++
++size_t
++__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
++                       size_t max)
++{
++  assert (max >= MAX_IFUNC);
++
++  size_t i = 0;
++
++  unsigned long int hwcap = GLRO(dl_hwcap);
++  /* hwcap contains only the latest supported ISA, the code checks which is
++     and fills the previous supported ones.  */
++  if (hwcap & PPC_FEATURE_ARCH_2_06)
++    hwcap |= PPC_FEATURE_ARCH_2_05 | PPC_FEATURE_POWER5_PLUS |
++             PPC_FEATURE_POWER5 | PPC_FEATURE_POWER4;
++  else if (hwcap & PPC_FEATURE_ARCH_2_05)
++    hwcap |= PPC_FEATURE_POWER5_PLUS | PPC_FEATURE_POWER5 | PPC_FEATURE_POWER4;
++  else if (hwcap & PPC_FEATURE_POWER5_PLUS)
++    hwcap |= PPC_FEATURE_POWER5 | PPC_FEATURE_POWER4;
++  else if (hwcap & PPC_FEATURE_POWER5)
++    hwcap |= PPC_FEATURE_POWER4;
++
++#ifdef SHARED
++  /* Support sysdeps/powerpc/powerpc64/multiarch/memcpy.c.  */
++  IFUNC_IMPL (i, name, memcpy,
++             IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_HAS_VSX,
++                             __memcpy_power7)
++             IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_06,
++                             __memcpy_a2)
++             IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_05,
++                             __memcpy_power6)
++             IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_CELL_BE,
++                             __memcpy_cell)
++             IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_POWER4,
++                             __memcpy_power4)
++             IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc))
++#endif
++
++  return i;
++}
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/init-arch.h b/sysdeps/powerpc/powerpc64/multiarch/init-arch.h
+new file mode 100644
+index 0000000..b7d238c
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/init-arch.h
+@@ -0,0 +1,18 @@
++/* This file is part of the GNU C Library.
++   Copyright (C) 2013 Free Software Foundation, Inc.
++
++   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 <sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S
+new file mode 100644
+index 0000000..2d5bfa9
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S
+@@ -0,0 +1,39 @@
++/* Optimized memcpy implementation for PowerPC A2.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memcpy_a2)						\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memcpy_a2):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memcpy_a2,mask)				\
++  END_2(__memcpy_a2)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/a2/memcpy.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S
+new file mode 100644
+index 0000000..92c06be
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S
+@@ -0,0 +1,39 @@
++/* Optimized memcpy implementation for PowerPC/CELL.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memcpy_cell)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memcpy_cell):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memcpy_cell,mask)				\
++  END_2(__memcpy_cell)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/cell/memcpy.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S
+new file mode 100644
+index 0000000..eb01d67
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S
+@@ -0,0 +1,39 @@
++/* Optimized memcpy implementation for PowerPC64/POWER4.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memcpy_power4)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memcpy_power4):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memcpy_power4,mask)				\
++  END_2(__memcpy_power4)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power4/memcpy.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S
+new file mode 100644
+index 0000000..13b514d
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S
+@@ -0,0 +1,39 @@
++/* Optimized memcpy implementation for PowerPC/POWER6.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memcpy_power6)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memcpy_power6):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memcpy_power6,mask)				\
++  END_2(__memcpy_power6)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power6/memcpy.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S
+new file mode 100644
+index 0000000..2aea73d
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S
+@@ -0,0 +1,39 @@
++/* Optimized memcpy implementation for PowerPC/POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memcpy_power7)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memcpy_power7):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memcpy_power7,mask)				\
++  END_2(__memcpy_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power7/memcpy.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
+new file mode 100644
+index 0000000..b828915
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
+@@ -0,0 +1,41 @@
++/* Default memcpy implementation for PowerPC64.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#if defined SHARED && !defined NOT_IN_libc
++# undef EALIGN
++# define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memcpy_ppc)						\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memcpy_ppc):					\
++  cfi_startproc;
++
++# undef END_GEN_TB
++# define END_GEN_TB(name, mask)					\
++   cfi_endproc;							\
++   TRACEBACK_MASK(__memcpy_ppc,mask)				\
++   END_2(__memcpy_ppc)
++
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name)
++#endif
++
++#include <sysdeps/powerpc/powerpc64/memcpy.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy.c b/sysdeps/powerpc/powerpc64/multiarch/memcpy.c
+new file mode 100644
+index 0000000..305e963
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy.c
+@@ -0,0 +1,55 @@
++/* Multiple versions of memcpy. PowerPC64 version.
++   Copyright (C) 2013-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/>.  */
++
++/* Define multiple versions only for the definition in lib and for
++   DSO.  In static binaries we need memcpy before the initialization
++   happened.  */
++#if defined SHARED && !defined NOT_IN_libc
++/* Redefine memcpy so that the compiler won't complain about the type
++   mismatch with the IFUNC selector in strong_alias, below.  */
++# undef memcpy
++# define memcpy __redirect_memcpy
++# include <string.h>
++# include "init-arch.h"
++
++extern __typeof (__redirect_memcpy) __libc_memcpy;
++
++extern __typeof (__redirect_memcpy) __memcpy_ppc attribute_hidden;
++extern __typeof (__redirect_memcpy) __memcpy_power4 attribute_hidden;
++extern __typeof (__redirect_memcpy) __memcpy_cell attribute_hidden;
++extern __typeof (__redirect_memcpy) __memcpy_power6 attribute_hidden;
++extern __typeof (__redirect_memcpy) __memcpy_a2 attribute_hidden;
++extern __typeof (__redirect_memcpy) __memcpy_power7 attribute_hidden;
++
++libc_ifunc (__libc_memcpy,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __memcpy_power7 :
++	      (hwcap & PPC_FEATURE_ARCH_2_06)
++	      ? __memcpy_a2 :
++		(hwcap & PPC_FEATURE_ARCH_2_05)
++		? __memcpy_power6 :
++		  (hwcap & PPC_FEATURE_CELL_BE)
++		  ? __memcpy_cell :
++		    (hwcap & PPC_FEATURE_POWER4)
++		    ? __memcpy_power4
++            : __memcpy_ppc);
++
++#undef memcpy
++strong_alias (__libc_memcpy, memcpy);
++libc_hidden_ver (__libc_memcpy, memcpy);
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-02.patch b/SOURCES/glibc-rh731837-02.patch
new file mode 100644
index 0000000..af2929a
--- /dev/null
+++ b/SOURCES/glibc-rh731837-02.patch
@@ -0,0 +1,256 @@
+From 2d5b6d3bb4813306ba5aa9ba03a56fe686bc6d4c Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:05:19 -0500
+Subject: [PATCH] PowerPC: multirach memcmp for PowerPC64
+
+commit 07253fcf7b03535b26c81ee216d284ed7f1e250b
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:32:31 2013 -0500
+---
+ string/memcmp.c                                    |  6 +++-
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  3 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  8 +++++
+ .../powerpc/powerpc64/multiarch/memcmp-power4.S    | 41 ++++++++++++++++++++++
+ .../powerpc/powerpc64/multiarch/memcmp-power7.S    | 41 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c | 33 +++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memcmp.c       | 39 ++++++++++++++++++++
+ 7 files changed, 169 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcmp.c
+
+diff --git a/string/memcmp.c b/string/memcmp.c
+index a73cc19..4a3ef58 100644
+--- a/string/memcmp.c
++++ b/string/memcmp.c
+@@ -30,6 +30,10 @@
+ 
+ #undef memcmp
+ 
++#ifndef MEMCMP
++# define MEMCMP memcmp
++#endif
++
+ #ifdef _LIBC
+ 
+ # include <memcopy.h>
+@@ -308,7 +312,7 @@ memcmp_not_common_alignment (srcp1, srcp2, len)
+ }
+ 
+ int
+-memcmp (s1, s2, len)
++MEMCMP (s1, s2, len)
+      const __ptr_t s1;
+      const __ptr_t s2;
+      size_t len;
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 638c102..c0bc520 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -1,4 +1,5 @@
+ ifeq ($(subdir),string)
+ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+-                  memcpy-power4 memcpy-ppc64
++                  memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \
++                  memcmp-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 5090af4..295ebca 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -62,5 +62,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc))
+ #endif
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c.  */
++  IFUNC_IMPL (i, name, memcmp,
++             IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_HAS_VSX,
++                             __memcmp_power7)
++             IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_POWER4,
++                             __memcmp_power4)
++             IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S
+new file mode 100644
+index 0000000..12db42c
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S
+@@ -0,0 +1,41 @@
++/* Optimized memcmp implementation for PowerPC64/POWER4.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memcmp_power4)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memcmp_power4):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__memcmp_power4)					\
++  END_2(__memcmp_power4)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++#undef weak_alias
++#define weak_alias(name,alias)
++
++#include <sysdeps/powerpc/powerpc64/power4/memcmp.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S
+new file mode 100644
+index 0000000..4898a88
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S
+@@ -0,0 +1,41 @@
++/* Optimized memcmp implementation for PowerPC64/POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memcmp_power7)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memcmp_power7):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__memcmp_power7)					\
++  END_2(__memcmp_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++#undef weak_alias
++#define weak_alias(name,alias)
++
++#include <sysdeps/powerpc/powerpc64/power7/memcmp.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c
+new file mode 100644
+index 0000000..1a39d4a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c
+@@ -0,0 +1,33 @@
++/* Copyright (C) 2013-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 <string.h>
++
++#define MEMCMP __memcmp_ppc
++#undef weak_alias
++#define weak_alias(name, aliasname) \
++  extern __typeof (__memcmp_ppc) aliasname \
++    __attribute__ ((weak, alias ("__memcmp_ppc")));
++#if !defined(NOT_IN_libc) && defined(SHARED)
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name) \
++  __hidden_ver1(__memcmp_ppc, __GI_memcmp, __memcmp_ppc);
++#endif
++
++extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
++
++#include <string/memcmp.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
+new file mode 100644
+index 0000000..af90f0a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
+@@ -0,0 +1,39 @@
++/* Multiple versions of memcmp. PowerPC64 version.
++   Copyright (C) 2013-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/>.  */
++
++/* Define multiple versions only for definition in libc.  */
++#ifndef NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
++extern __typeof (memcmp) __memcmp_power4 attribute_hidden;
++extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (memcmp,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __memcmp_power7 :
++	      (hwcap & PPC_FEATURE_POWER4)
++		? __memcmp_power4
++            : __memcmp_ppc);
++#else
++#include <string/memcmp.c>
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-03.patch b/SOURCES/glibc-rh731837-03.patch
new file mode 100644
index 0000000..d51f8a1
--- /dev/null
+++ b/SOURCES/glibc-rh731837-03.patch
@@ -0,0 +1,579 @@
+From 3cd86ba149cd650c338332dddb63e16f95041daf Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:10:37 -0500
+Subject: [PATCH] PowerPC: multiarch memset/bzero for PowerPC64
+
+commit 8a29a3d00b5d8ce33fc291baecfd59d715190fd1
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:33:16 2013 -0500
+
+---
+ sysdeps/powerpc/powerpc64/memset.S                 |  2 +
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  3 +-
+ sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S | 26 ++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S | 26 ++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S | 26 ++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/bzero.c        | 40 ++++++++++++++++
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  | 20 ++++++++
+ .../powerpc/powerpc64/multiarch/memset-power4.S    | 40 ++++++++++++++++
+ .../powerpc/powerpc64/multiarch/memset-power6.S    | 40 ++++++++++++++++
+ .../powerpc/powerpc64/multiarch/memset-power7.S    | 40 ++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S | 55 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memset.c       | 50 ++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c  | 18 +++++++
+ sysdeps/powerpc/powerpc64/power4/memset.S          |  2 +
+ sysdeps/powerpc/powerpc64/power6/memset.S          |  2 +
+ sysdeps/powerpc/powerpc64/power7/memset.S          |  2 +
+ 16 files changed, 391 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/bzero.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-power4.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-power6.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c
+
+diff --git a/sysdeps/powerpc/powerpc64/memset.S b/sysdeps/powerpc/powerpc64/memset.S
+index d02af98..fd5d4e5 100644
+--- a/sysdeps/powerpc/powerpc64/memset.S
++++ b/sysdeps/powerpc/powerpc64/memset.S
+@@ -265,6 +265,7 @@ L(medium_28t):
+ END_GEN_TB (BP_SYM (memset),TB_TOCLESS)
+ libc_hidden_builtin_def (memset)
+ 
++#ifndef NO_BZERO_IMPL
+ /* Copied from bzero.S to prevent the linker from inserting a stub
+    between bzero and memset.  */
+ ENTRY (BP_SYM (__bzero))
+@@ -284,3 +285,4 @@ ENTRY (BP_SYM (__bzero))
+ END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS)
+ 
+ weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index c0bc520..424d2cd 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -1,5 +1,6 @@
+ ifeq ($(subdir),string)
+ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \
+-                  memcmp-ppc64
++                  memcmp-ppc64 memset-power7 memset-power6 memset-power4 \
++                  memset-ppc64 bzero-power4 bzero-power6 bzero-power7
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S b/sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S
+new file mode 100644
+index 0000000..72b75ac
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S
+@@ -0,0 +1,26 @@
++/* Optimized bzero implementation for PowerPC64/POWER4.
++   Copyright (C) 2013-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 <sysdep.h>
++
++ENTRY (__bzero_power4)
++	CALL_MCOUNT 3
++	mr	r5,r4
++	li	r4,0
++	b	__memset_power4
++END_GEN_TB (__bzero_power4,TB_TOCLESS)
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S b/sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S
+new file mode 100644
+index 0000000..d0917c5
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S
+@@ -0,0 +1,26 @@
++/* Optimized bzero implementation for PowerPC64/POWER6.
++   Copyright (C) 2013-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 <sysdep.h>
++
++ENTRY (__bzero_power6)
++	CALL_MCOUNT 3
++	mr	r5,r4
++	li	r4,0
++	b	__memset_power6
++END_GEN_TB (__bzero_power6,TB_TOCLESS)
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S b/sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S
+new file mode 100644
+index 0000000..0ec285a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S
+@@ -0,0 +1,26 @@
++/* Optimized bzero implementation for PowerPC64/POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++ENTRY (__bzero_power7)
++	CALL_MCOUNT 3
++	mr	r5,r4
++	li	r4,0
++	b	__memset_power7
++END_GEN_TB (__bzero_power7,TB_TOCLESS)
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/bzero.c b/sysdeps/powerpc/powerpc64/multiarch/bzero.c
+new file mode 100644
+index 0000000..ed83541
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/bzero.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of bzero. PowerPC64 version.
++   Copyright (C) 2013-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/>.  */
++
++/* Define multiple versions only for definition in libc.  */
++#ifndef NOT_IN_libc
++# include <string.h>
++# include <strings.h>
++# include "init-arch.h"
++
++extern __typeof (bzero) __bzero_ppc attribute_hidden;
++extern __typeof (bzero) __bzero_power4 attribute_hidden;
++extern __typeof (bzero) __bzero_power6 attribute_hidden;
++extern __typeof (bzero) __bzero_power7 attribute_hidden;
++
++libc_ifunc (__bzero,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __bzero_power7 :
++	      (hwcap & PPC_FEATURE_ARCH_2_05)
++		? __bzero_power6 :
++		  (hwcap & PPC_FEATURE_POWER4)
++		? __bzero_power4
++            : __bzero_ppc);
++
++weak_alias (__bzero, bzero)
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 295ebca..11e7063 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -60,6 +60,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_POWER4,
+                              __memcpy_power4)
+              IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc))
++
++  /* Support sysdeps/powerpc/powerpc64/multiarch/memset.c.  */
++  IFUNC_IMPL (i, name, memset,
++             IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX,
++                             __memset_power7)
++             IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05,
++                             __memset_power6)
++             IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_POWER4,
++                             __memset_power4)
++             IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ppc))
+ #endif
+ 
+   /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c.  */
+@@ -70,5 +80,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+                              __memcmp_power4)
+              IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/bzero.c.  */
++  IFUNC_IMPL (i, name, bzero,
++             IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_HAS_VSX,
++                             __bzero_power7)
++             IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_ARCH_2_05,
++                             __bzero_power6)
++             IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_POWER4,
++                             __bzero_power4)
++             IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S b/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S
+new file mode 100644
+index 0000000..9074b95
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S
+@@ -0,0 +1,40 @@
++/* Optimized memset implementation for PowerPC64/POWER4.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memset_power4)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memset_power4):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memset_power4,mask)				\
++  END_2(__memset_power4)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#define NO_BZERO_IMPL
++#include <sysdeps/powerpc/powerpc64/power4/memset.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S b/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S
+new file mode 100644
+index 0000000..70688b5
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S
+@@ -0,0 +1,40 @@
++/* Optimized memset implementation for PowerPC64/POWER6.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memset_power6)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memset_power6):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memset_power6,mask)				\
++  END_2(__memset_power6)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#define NO_BZERO_IMPL
++#include <sysdeps/powerpc/powerpc64/power6/memset.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S
+new file mode 100644
+index 0000000..ab226c5
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S
+@@ -0,0 +1,40 @@
++/* Optimized memset implementation for PowerPC64/POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memset_power7)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memset_power7):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memset_power7,mask)				\
++  END_2(__memset_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#define NO_BZERO_IMPL
++#include <sysdeps/powerpc/powerpc64/power7/memset.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
+new file mode 100644
+index 0000000..dc5549c
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
+@@ -0,0 +1,55 @@
++/* Default memset/bzero implementation for PowerPC64.
++   Copyright (C) 2013-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 <sysdep.h>
++
++/* Copied from bzero.S to prevent the linker from inserting a stub
++   between bzero and memset.  NOTE: this code should be positioned
++   before ENTRY/END_GEN_TB redefinition.  */
++ENTRY (__bzero_ppc)
++        CALL_MCOUNT 3
++        mr      r5,r4
++        li      r4,0
++        b       L(_memset)
++END_GEN_TB (__bzero_ppc,TB_TOCLESS)
++
++
++#if defined SHARED && !defined NOT_IN_libc
++# undef EALIGN
++# define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__memset_ppc)						\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__memset_ppc):					\
++  cfi_startproc;
++
++# undef END_GEN_TB
++# define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__memset_ppc,mask)				\
++  END_2(__memset_ppc)
++
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name)
++#endif
++
++/* Do not implement __bzero at powerpc64/memset.S.  */
++#define NO_BZERO_IMPL
++
++#include <sysdeps/powerpc/powerpc64/memset.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c
+new file mode 100644
+index 0000000..aa2ae70
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c
+@@ -0,0 +1,50 @@
++/* Multiple versions of memset.
++   Copyright (C) 2013-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/>.  */
++
++/* Define multiple versions only for definition in libc.  */
++#if defined SHARED && !defined NOT_IN_libc
++/* Redefine memset so that the compiler won't complain about the type
++   mismatch with the IFUNC selector in strong_alias, below.  */
++# undef memset
++# define memset __redirect_memset
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__redirect_memset) __libc_memset;
++
++extern __typeof (__redirect_memset) __memset_ppc attribute_hidden;
++extern __typeof (__redirect_memset) __memset_power4 attribute_hidden;
++extern __typeof (__redirect_memset) __memset_power6 attribute_hidden;
++extern __typeof (__redirect_memset) __memset_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (__libc_memset,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __memset_power7 :
++	      (hwcap & PPC_FEATURE_ARCH_2_05)
++		? __memset_power6 :
++		  (hwcap & PPC_FEATURE_POWER4)
++		? __memset_power4
++            : __memset_ppc);
++
++#undef memset
++strong_alias (__libc_memset, memset);
++libc_hidden_ver (__libc_memset, memset);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c b/sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c
+new file mode 100644
+index 0000000..8eac85b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c
+@@ -0,0 +1,18 @@
++/* Copyright (C) 2013-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 <sysdeps/powerpc/powerpc64/rtld-memset.c>
+diff --git a/sysdeps/powerpc/powerpc64/power4/memset.S b/sysdeps/powerpc/powerpc64/power4/memset.S
+index c86a68a..c077ae7 100644
+--- a/sysdeps/powerpc/powerpc64/power4/memset.S
++++ b/sysdeps/powerpc/powerpc64/power4/memset.S
+@@ -253,6 +253,7 @@ L(medium_28t):
+ END_GEN_TB (BP_SYM (memset),TB_TOCLESS)
+ libc_hidden_builtin_def (memset)
+ 
++#ifndef NO_BZERO_IMPL
+ /* Copied from bzero.S to prevent the linker from inserting a stub
+    between bzero and memset.  */
+ ENTRY (BP_SYM (__bzero))
+@@ -272,3 +273,4 @@ ENTRY (BP_SYM (__bzero))
+ END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS)
+ 
+ weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/power6/memset.S b/sysdeps/powerpc/powerpc64/power6/memset.S
+index 930ecce..967642a3 100644
+--- a/sysdeps/powerpc/powerpc64/power6/memset.S
++++ b/sysdeps/powerpc/powerpc64/power6/memset.S
+@@ -397,6 +397,7 @@ L(medium_28t):
+ END_GEN_TB (BP_SYM (memset),TB_TOCLESS)
+ libc_hidden_builtin_def (memset)
+ 
++#ifndef NO_BZERO_IMPL
+ /* Copied from bzero.S to prevent the linker from inserting a stub
+    between bzero and memset.  */
+ ENTRY (BP_SYM (__bzero))
+@@ -416,3 +417,4 @@ ENTRY (BP_SYM (__bzero))
+ END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS)
+ 
+ weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/power7/memset.S b/sysdeps/powerpc/powerpc64/power7/memset.S
+index 5970fbe..2716656 100644
+--- a/sysdeps/powerpc/powerpc64/power7/memset.S
++++ b/sysdeps/powerpc/powerpc64/power7/memset.S
+@@ -385,6 +385,7 @@ L(small):
+ END_GEN_TB (BP_SYM (memset),TB_TOCLESS)
+ libc_hidden_builtin_def (memset)
+ 
++#ifndef NO_BZERO_IMPL
+ /* Copied from bzero.S to prevent the linker from inserting a stub
+    between bzero and memset.  */
+ ENTRY (BP_SYM (__bzero))
+@@ -395,3 +396,4 @@ ENTRY (BP_SYM (__bzero))
+ END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS)
+ 
+ weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-04.patch b/SOURCES/glibc-rh731837-04.patch
new file mode 100644
index 0000000..1b6ef9a
--- /dev/null
+++ b/SOURCES/glibc-rh731837-04.patch
@@ -0,0 +1,233 @@
+From 09f1f5cc860480fd09383bca00eb71e0f71aae79 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:17:26 -0500
+Subject: [PATCH] PowerPC: multiarch mempcpy for PowerPC64
+
+commit f00be62b08c1440800898339f74fb4db20b19eef
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:34:06 2013 -0500
+
+Added sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c  and
+string/mempcpy.c apart from original commit.
+---
+ string/mempcpy.c                                   |  9 ++---
+ .../powerpc32/power4/multiarch/mempcpy-ppc32.c     | 32 +++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  3 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  8 +++++
+ .../powerpc/powerpc64/multiarch/mempcpy-power7.S   | 41 ++++++++++++++++++++++
+ .../powerpc/powerpc64/multiarch/mempcpy-ppc64.c    | 19 ++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/mempcpy.c      | 38 ++++++++++++++++++++
+ 7 files changed, 145 insertions(+), 5 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
+
+diff --git a/string/mempcpy.c b/string/mempcpy.c
+index 2a542e3..7509c24 100644
+--- a/string/mempcpy.c
++++ b/string/mempcpy.c
+@@ -26,11 +26,12 @@
+ #undef mempcpy
+ #undef __mempcpy
+ 
++#ifndef MEMPCPY
++# define MEMPCPY __mempcpy
++#endif
++
+ void *
+-__mempcpy (dstpp, srcpp, len)
+-     void *dstpp;
+-     const void *srcpp;
+-     size_t len;
++MEMPCPY (void *dstpp, const void *srcpp, size_t len)
+ {
+   unsigned long int dstp = (long int) dstpp;
+   unsigned long int srcp = (long int) srcpp;
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c
+new file mode 100644
+index 0000000..8dc77e9
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c
+@@ -0,0 +1,32 @@
++/* PowerPC32 default implementation of mempcpy.
++   Copyright (C) 2013-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/>.  */
++
++#define MEMPCPY  __mempcpy_ppc
++
++#undef libc_hidden_def
++#define libc_hidden_def(name)
++#undef weak_alias
++#define weak_alias(a, b)
++
++#if defined SHARED
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name)  \
++  __hidden_ver1 (__mempcpy_ppc, __GI_mempcpy, __mempcpy_ppc);
++#endif
++
++#include <string/mempcpy.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 424d2cd..22560e8 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -2,5 +2,6 @@ ifeq ($(subdir),string)
+ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \
+                   memcmp-ppc64 memset-power7 memset-power6 memset-power4 \
+-                  memset-ppc64 bzero-power4 bzero-power6 bzero-power7
++                  memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \
++                  mempcpy-power7 mempcpy-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 11e7063..c72c229 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -90,5 +90,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+                              __bzero_power4)
+              IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/mempcpy.c.  */
++  IFUNC_IMPL (i, name, mempcpy,
++             IFUNC_IMPL_ADD (array, i, mempcpy,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __mempcpy_power7)
++             IFUNC_IMPL_ADD (array, i, mempcpy, 1,
++                             __mempcpy_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S
+new file mode 100644
+index 0000000..6a79847
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S
+@@ -0,0 +1,41 @@
++/* Optimized mempcpy implementation for PowerPC/POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name, alignt, words)				\
++  .section ".text";						\
++  ENTRY_2(__mempcpy_power7)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__mempcpy_power7):					\
++  cfi_startproc;
++
++#undef END_GEN_TB
++#define END_GEN_TB(name, mask)					\
++  cfi_endproc;							\
++  TRACEBACK_MASK(__mempcpy_power7,mask)				\
++  END_2(__mempcpy_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++#undef weak_alias
++#define weak_alias(name, alias)
++
++#include <sysdeps/powerpc/powerpc64/power7/mempcpy.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c
+new file mode 100644
+index 0000000..78260bb
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c
+@@ -0,0 +1,19 @@
++/* PowerPC64 default implementation of mempcpy.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
+new file mode 100644
+index 0000000..38fbcc3
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
+@@ -0,0 +1,38 @@
++/* Multiple versions of mempcpy.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__mempcpy) __mempcpy_ppc attribute_hidden;
++extern __typeof (__mempcpy) __mempcpy_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (__mempcpy,
++	    (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __mempcpy_power7
++            : __mempcpy_ppc);
++
++weak_alias (__mempcpy, mempcpy)
++libc_hidden_def (mempcpy)
++#else
++# include <string/mempcpy.c>
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-05.patch b/SOURCES/glibc-rh731837-05.patch
new file mode 100644
index 0000000..9421fa9
--- /dev/null
+++ b/SOURCES/glibc-rh731837-05.patch
@@ -0,0 +1,232 @@
+From a8d62012e2b47e8f62fafe17ab1042b0415a06ea Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:20:37 -0500
+Subject: [PATCH] PowerPC: multiarch memchr for PowerPC64
+
+commit 870f867648fc62e230dad80cd34bd599f08e2193
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:35:28 2013 -0500
+
+Added string/memchr.c and
+sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c aart from
+original commit
+---
+ string/memchr.c                                    |  6 +++-
+ .../powerpc32/power4/multiarch/memchr-ppc32.c      | 34 ++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  2 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  8 +++++
+ .../powerpc/powerpc64/multiarch/memchr-power7.S    | 40 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c | 19 ++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memchr.c       | 38 ++++++++++++++++++++
+ 7 files changed, 145 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memchr.c
+
+diff --git a/string/memchr.c b/string/memchr.c
+index 22637cf..822c0a4 100644
+--- a/string/memchr.c
++++ b/string/memchr.c
+@@ -56,9 +56,13 @@
+ #undef memchr
+ #undef __memchr
+ 
++#ifndef MEMCHR
++# define MEMCHR __memchr
++#endif
++
+ /* Search no more than N bytes of S for C.  */
+ __ptr_t
+-__memchr (s, c_in, n)
++MEMCHR (s, c_in, n)
+      const __ptr_t s;
+      int c_in;
+      size_t n;
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
+new file mode 100644
+index 0000000..43c5652
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
+@@ -0,0 +1,34 @@
++/* PowerPC32 default implementation of memchr.
++   Copyright (C) 2013-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 <string.h>
++
++#define MEMCHR  __memchr_ppc
++
++#undef weak_alias
++#define weak_alias(a, b)
++
++#ifdef SHARED
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name)  \
++  __hidden_ver1 (__memchr_ppc, __GI_memchr, __memchr_ppc);
++#endif
++
++extern __typeof (memchr) __memchr_ppc attribute_hidden;
++
++#include <string/memchr.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 22560e8..b2815e7 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -3,5 +3,5 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \
+                   memcmp-ppc64 memset-power7 memset-power6 memset-power4 \
+                   memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \
+-                  mempcpy-power7 mempcpy-ppc64
++                  mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index c72c229..663e294 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -98,5 +98,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, mempcpy, 1,
+                              __mempcpy_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/memchr.c.  */
++  IFUNC_IMPL (i, name, memchr,
++             IFUNC_IMPL_ADD (array, i, memchr,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __memchr_power7)
++             IFUNC_IMPL_ADD (array, i, memchr, 1,
++                             __memchr_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S
+new file mode 100644
+index 0000000..b1b4ec7
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S
+@@ -0,0 +1,40 @@
++/* Optimized memchr implementation for PowerPC64/POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__memchr_power7)					\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__memchr_power7):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__memchr_power7)					\
++  END_2(__memchr_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++#undef weak_alias
++#define weak_alias(name,alias)
++
++#include <sysdeps/powerpc/powerpc64/power7/memchr.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c
+new file mode 100644
+index 0000000..9e2a711
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c
+@@ -0,0 +1,19 @@
++/* PowerPC64 default implementation of memchr.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr.c b/sysdeps/powerpc/powerpc64/multiarch/memchr.c
+new file mode 100644
+index 0000000..ca0f714
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memchr.c
+@@ -0,0 +1,38 @@
++/* Multiple versions of memchr.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__memchr) __memchr_ppc attribute_hidden;
++extern __typeof (__memchr) __memchr_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (__memchr,
++	    (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __memchr_power7
++            : __memchr_ppc);
++
++weak_alias (__memchr, memchr)
++libc_hidden_builtin_def (memchr)
++#else
++#include <string/memchr.c>
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-06.patch b/SOURCES/glibc-rh731837-06.patch
new file mode 100644
index 0000000..60f46fc
--- /dev/null
+++ b/SOURCES/glibc-rh731837-06.patch
@@ -0,0 +1,202 @@
+From 6a69f5d33526bf8dafd65f3b53719402ce09d566 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:31:40 -0500
+Subject: [PATCH] PowerPC: multiarch memrchr for PowerPC64
+
+commit 1fd005ad2f8ca30d44d5bfa036422b4ec281ea4a
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:37:26 2013 -0500
+
+Added sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c
+apart from original commit
+---
+ .../powerpc32/power4/multiarch/memrchr-ppc32.c     | 25 ++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  3 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  8 +++++
+ .../powerpc/powerpc64/multiarch/memrchr-power7.S   | 40 ++++++++++++++++++++++
+ .../powerpc/powerpc64/multiarch/memrchr-ppc64.c    | 19 ++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/memrchr.c      | 37 ++++++++++++++++++++
+ 6 files changed, 131 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memrchr-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memrchr.c
+
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c
+new file mode 100644
+index 0000000..c30e7d6
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c
+@@ -0,0 +1,25 @@
++/* PowerPC32 default implementation of memrchr.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# define MEMRCHR  __memrchr_ppc
++# include <string.h>
++extern void *__memrchr_ppc (const void *, int, size_t);
++#endif
++
++#include <string/memrchr.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index b2815e7..db765f2 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -3,5 +3,6 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \
+                   memcmp-ppc64 memset-power7 memset-power6 memset-power4 \
+                   memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \
+-                  mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64
++                  mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \
++                  memrchr-power7 memrchr-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 663e294..a0700dc 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -106,5 +106,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, memchr, 1,
+                              __memchr_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/memrchr.c.  */
++  IFUNC_IMPL (i, name, memrchr,
++             IFUNC_IMPL_ADD (array, i, memrchr,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __memrchr_power7)
++             IFUNC_IMPL_ADD (array, i, memrchr, 1,
++                             __memrchr_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S
+new file mode 100644
+index 0000000..42ee8e2
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S
+@@ -0,0 +1,40 @@
++/* Optimized memrchr implementation for PowerPC64/POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__memrchr_power7)					\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__memrchr_power7):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__memrchr_power7)					\
++  END_2(__memrchr_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++#undef weak_alias
++#define weak_alias(name,alias)
++
++#include <sysdeps/powerpc/powerpc64/power7/memrchr.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memrchr-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/memrchr-ppc64.c
+new file mode 100644
+index 0000000..c2ee4be
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memrchr-ppc64.c
+@@ -0,0 +1,19 @@
++/* PowerPC64 default implementation of memrchr.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memrchr.c b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c
+new file mode 100644
+index 0000000..610a957
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/memrchr.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of memrchr.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__memrchr) __memrchr_ppc attribute_hidden;
++extern __typeof (__memrchr) __memrchr_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (__memrchr,
++	    (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __memrchr_power7
++            : __memrchr_ppc);
++
++weak_alias (__memrchr, memrchr)
++#else
++#include <string/memrchr.c>
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-07.patch b/SOURCES/glibc-rh731837-07.patch
new file mode 100644
index 0000000..8775fb4
--- /dev/null
+++ b/SOURCES/glibc-rh731837-07.patch
@@ -0,0 +1,224 @@
+From c59b219a7fb36564572a864bd61a5cdc7e37f25b Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:35:32 -0500
+Subject: [PATCH] PowerPC: multiarch rawmemchr for PowerPC64
+
+commit 1fd005ad2f8ca30d44d5bfa036422b4ec281ea4a
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:37:26 2013 -0500
+
+Added sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c and
+string/rawmemchr.c apart from original commit.
+---
+ string/rawmemchr.c                                 |  5 ++-
+ .../powerpc32/power4/multiarch/rawmemchr-ppc32.c   | 32 +++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  3 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  8 +++++
+ .../powerpc/powerpc64/multiarch/rawmemchr-power7.S | 35 ++++++++++++++++++++
+ .../powerpc/powerpc64/multiarch/rawmemchr-ppc64.c  | 19 +++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c    | 37 ++++++++++++++++++++++
+ 7 files changed, 137 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rawmemchr-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
+
+diff --git a/string/rawmemchr.c b/string/rawmemchr.c
+index 90e8c7c..0e4f192 100644
+--- a/string/rawmemchr.c
++++ b/string/rawmemchr.c
+@@ -47,10 +47,13 @@
+ 
+ #undef memchr
+ 
++#ifndef RAWMEMCHR
++# define RAWMEMCHR __rawmemchr
++#endif
+ 
+ /* Find the first occurrence of C in S.  */
+ __ptr_t
+-__rawmemchr (s, c_in)
++RAWMEMCHR (s, c_in)
+      const __ptr_t s;
+      int c_in;
+ {
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c
+new file mode 100644
+index 0000000..2e8abaa
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c
+@@ -0,0 +1,32 @@
++/* PowerPC32 default implementation of rawmemchr.
++   Copyright (C) 2013-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 <string.h>
++
++#define RAWMEMCHR  __rawmemchr_ppc
++#undef weak_alias
++#define weak_alias(a, b)
++#ifdef SHARED
++# undef libc_hidden_def
++# define libc_hidden_def(name)  \
++  __hidden_ver1 (__rawmemchr_ppc, __GI___rawmemchr, __rawmemchr_ppc);
++#endif
++
++extern __typeof (rawmemchr) __rawmemchr_ppc attribute_hidden;
++
++#include <string/rawmemchr.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index db765f2..695112c 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -4,5 +4,6 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   memcmp-ppc64 memset-power7 memset-power6 memset-power4 \
+                   memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \
+                   mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \
+-                  memrchr-power7 memrchr-ppc64
++                  memrchr-power7 memrchr-ppc64 rawmemchr-power7 \
++                  rawmemchr-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index a0700dc..5b15c3f 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -114,5 +114,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, memrchr, 1,
+                              __memrchr_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c.  */
++  IFUNC_IMPL (i, name, rawmemchr,
++             IFUNC_IMPL_ADD (array, i, rawmemchr,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __rawmemchr_power7)
++             IFUNC_IMPL_ADD (array, i, rawmemchr, 1,
++                             __rawmemchr_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S
+new file mode 100644
+index 0000000..24ae3bf
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S
+@@ -0,0 +1,35 @@
++/* Optimized rawmemchr implementation for PowerPC64/POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__rawmemchr_power7)					\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__rawmemchr_power7):				\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__rawmemchr_power7)					\
++  END_2(__rawmemchr_power7)
++
++#include <sysdeps/powerpc/powerpc64/power7/rawmemchr.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-ppc64.c
+new file mode 100644
+index 0000000..0f2f202
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-ppc64.c
+@@ -0,0 +1,19 @@
++/* PowerPC64 default implementation of rawmemchr.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
+new file mode 100644
+index 0000000..3f53cd5
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of rawmemchr.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__rawmemchr) __rawmemchr_ppc attribute_hidden;
++extern __typeof (__rawmemchr) __rawmemchr_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (__rawmemchr,
++	    (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __rawmemchr_power7
++            : __rawmemchr_ppc);
++
++weak_alias (__rawmemchr, rawmemchr)
++#else
++#include <string/rawmemchr.c>
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-08.patch b/SOURCES/glibc-rh731837-08.patch
new file mode 100644
index 0000000..4b7e405
--- /dev/null
+++ b/SOURCES/glibc-rh731837-08.patch
@@ -0,0 +1,188 @@
+From b860ebda47c7964db0582d65ad949780c4c784c5 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:39:07 -0500
+Subject: [PATCH] PowerPC: multiarch strlen for PowerPC64
+
+commit a65f4904ab96de789d13f2c4f27c2d82959a546d
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:38:17 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  2 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  7 ++++
+ .../powerpc/powerpc64/multiarch/strlen-power7.S    | 38 ++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S | 40 +++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strlen.c       | 41 ++++++++++++++++++++++
+ 5 files changed, 127 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strlen.c
+
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 695112c..9da7be1 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -5,5 +5,5 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \
+                   mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \
+                   memrchr-power7 memrchr-ppc64 rawmemchr-power7 \
+-                  rawmemchr-ppc64
++                  rawmemchr-ppc64 strlen-power7 strlen-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 5b15c3f..bdc908b 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -70,6 +70,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_POWER4,
+                              __memset_power4)
+              IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ppc))
++
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strlen.c.  */
++  IFUNC_IMPL (i, name, strlen,
++             IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_HAS_VSX,
++                             __strlen_power7)
++             IFUNC_IMPL_ADD (array, i, strlen, 1,
++                             __strlen_ppc))
+ #endif
+ 
+   /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c.  */
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S
+new file mode 100644
+index 0000000..a38521d
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S
+@@ -0,0 +1,38 @@
++/* Optimized strlen implementation for POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__strlen_power7)					\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__strlen_power7):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strlen_power7)					\
++  END_2(__strlen_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power7/strlen.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
+new file mode 100644
+index 0000000..b463b3a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
+@@ -0,0 +1,40 @@
++/* Default strlen implementation for PowerPC64.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#if defined SHARED && !defined NOT_IN_libc
++# undef ENTRY
++# define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__strlen_ppc)						\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__strlen_ppc):					\
++  cfi_startproc;
++
++# undef END
++# define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strlen_ppc)					\
++  END_2(__strlen_ppc)
++
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name)
++#endif
++
++#include <sysdeps/powerpc/powerpc64/strlen.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen.c b/sysdeps/powerpc/powerpc64/multiarch/strlen.c
+new file mode 100644
+index 0000000..d2c26e9
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen.c
+@@ -0,0 +1,41 @@
++/* Multiple versions of strlen. PowerPC64 version.
++   Copyright (C) 2013-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/>.  */
++
++#if defined SHARED && !defined NOT_IN_libc
++/* Redefine strlen so that the compiler won't complain about the type
++   mismatch with the IFUNC selector in strong_alias, below.  */
++# undef strlen
++# define strlen __redirect_strlen
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__redirect_strlen) __libc_strlen;
++
++extern __typeof (__redirect_strlen) __strlen_ppc attribute_hidden;
++extern __typeof (__redirect_strlen) __strlen_power7 attribute_hidden;
++
++libc_ifunc (__libc_strlen,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __strlen_power7
++            : __strlen_ppc);
++
++#undef strlen
++strong_alias (__libc_strlen, strlen)
++libc_hidden_ver (__libc_strlen, strlen)
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-09.patch b/SOURCES/glibc-rh731837-09.patch
new file mode 100644
index 0000000..b1d8590
--- /dev/null
+++ b/SOURCES/glibc-rh731837-09.patch
@@ -0,0 +1,200 @@
+From dc5a73198455f4492a44dbc71fdadeb7551d5810 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:41:40 -0500
+Subject: [PATCH] PowerPC: multiarch strnlen for PowerPC64
+
+commit 62982bf9782f0f3ef4259fc03b1b557f1332b182
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:38:50 2013 -0500
+
+Added sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c
+apart from original commit.
+---
+ .../powerpc32/power4/multiarch/strnlen-ppc32.c     | 26 ++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  3 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  7 ++++
+ .../powerpc/powerpc64/multiarch/strnlen-power7.S   | 40 ++++++++++++++++++++++
+ .../powerpc/powerpc64/multiarch/strnlen-ppc64.c    | 18 ++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strnlen.c      | 36 +++++++++++++++++++
+ 6 files changed, 129 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strnlen-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strnlen.c
+
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c
+new file mode 100644
+index 0000000..676d837
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c
+@@ -0,0 +1,26 @@
++/* Default strnlen implementation for PowerPC32.
++   Copyright (C) 2013-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/>.  */
++
++#define STRNLEN  __strnlen_ppc
++#ifdef SHARED
++# undef libc_hidden_def
++# define libc_hidden_def(name)  \
++    __hidden_ver1 (__strnlen_ppc, __GI_strnlen, __strnlen_ppc);
++#endif
++
++#include <string/strnlen.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 9da7be1..3285fd7 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -5,5 +5,6 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \
+                   mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \
+                   memrchr-power7 memrchr-ppc64 rawmemchr-power7 \
+-                  rawmemchr-ppc64 strlen-power7 strlen-ppc64
++                  rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \
++                  strnlen-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index bdc908b..c9125b8 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -129,5 +129,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, rawmemchr, 1,
+                              __rawmemchr_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strnlen.c.  */
++  IFUNC_IMPL (i, name, strnlen,
++             IFUNC_IMPL_ADD (array, i, strnlen, hwcap & PPC_FEATURE_HAS_VSX,
++                             __strnlen_power7)
++             IFUNC_IMPL_ADD (array, i, strnlen, 1,
++                             __strnlen_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S
+new file mode 100644
+index 0000000..909aae8
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S
+@@ -0,0 +1,40 @@
++/* Optimized strnlen version for POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__strnlen_power7)					\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__strnlen_power7):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strnlen_power7)					\
++  END_2(__strnlen_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++#undef weak_alias
++#define weak_alias(name, alias)
++
++#include <sysdeps/powerpc/powerpc64/power7/strnlen.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen-ppc64.c
+new file mode 100644
+index 0000000..9d23994
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen-ppc64.c
+@@ -0,0 +1,18 @@
++/* Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
+new file mode 100644
+index 0000000..3926031
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
+@@ -0,0 +1,36 @@
++/* Multiple versions of strnlen.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__strnlen) __strnlen_ppc attribute_hidden;
++extern __typeof (__strnlen) __strnlen_power7 attribute_hidden;
++
++libc_ifunc (__strnlen,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __strnlen_power7
++            : __strnlen_ppc);
++weak_alias (__strnlen, strnlen)
++libc_hidden_def (strnlen)
++
++#else
++#include <string/strnlen.c>
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-10.patch b/SOURCES/glibc-rh731837-10.patch
new file mode 100644
index 0000000..a92b39c
--- /dev/null
+++ b/SOURCES/glibc-rh731837-10.patch
@@ -0,0 +1,248 @@
+From 4a6eeaf792815ff197f683e424d64cc3a9e16a66 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:47:00 -0500
+Subject: [PATCH] PowerPC: multiarch strcasecmp for PowerPC64
+
+commit 17de3ee3c109a13ecec60b8bc9514f33c5b42178
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:39:51 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  2 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  | 15 ++++++++
+ .../powerpc64/multiarch/strcasecmp-power7.S        | 41 +++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c   | 40 ++++++++++++++++++++
+ .../powerpc64/multiarch/strcasecmp_l-power7.S      | 43 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c | 40 ++++++++++++++++++++
+ 6 files changed, 180 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c
+
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 3285fd7..5e172da 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -6,5 +6,5 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \
+                   memrchr-power7 memrchr-ppc64 rawmemchr-power7 \
+                   rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \
+-                  strnlen-ppc64
++                  strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index c9125b8..ba78d97 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -136,5 +136,20 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, strnlen, 1,
+                              __strnlen_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c.  */
++  IFUNC_IMPL (i, name, strcasecmp,
++             IFUNC_IMPL_ADD (array, i, strcasecmp,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __strcasecmp_power7)
++             IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ppc))
++
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c.  */
++  IFUNC_IMPL (i, name, strcasecmp_l,
++             IFUNC_IMPL_ADD (array, i, strcasecmp_l,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __strcasecmp_l_power7)
++             IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
++                             __strcasecmp_l_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S
+new file mode 100644
+index 0000000..9714f88
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S
+@@ -0,0 +1,41 @@
++/* Optimized strcasecmp implementation foOWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__strcasecmp_power7)					\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__strcasecmp_power7):				\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strcasecmp_power7)				\
++  END_2(__strcasecmp_power7)
++
++#undef weak_alias
++#define weak_alias(name, alias)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power7/strcasecmp.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
+new file mode 100644
+index 0000000..7f02a25
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of strcasecmp.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# define strcasecmp __strcasecmp_ppc
++extern __typeof (__strcasecmp) __strcasecmp_ppc attribute_hidden;
++extern __typeof (__strcasecmp) __strcasecmp_power7 attribute_hidden;
++#endif
++
++#include <string/strcasecmp.c>
++#undef strcasecmp
++
++#ifndef NOT_IN_libc
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__strcasecmp) __libc_strcasecmp;
++libc_ifunc (__libc_strcasecmp,
++	    (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __strcasecmp_power7
++            : __strcasecmp_ppc);
++
++weak_alias (__libc_strcasecmp, strcasecmp)
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S
+new file mode 100644
+index 0000000..117e464
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S
+@@ -0,0 +1,43 @@
++/* Optimized strcasecmp_l implementation for POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__strcasecmp_l_power7)				\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__strcasecmp_l_power7):				\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strcasecmp_l_power7)				\
++  END_2(__strcasecmp_l_power7)
++
++#undef weak_alias
++#define weak_alias(name, alias)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#define USE_IN_EXTENDED_LOCALE_MODEL
++
++#include <sysdeps/powerpc/powerpc64/power7/strcasecmp.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c
+new file mode 100644
+index 0000000..a3374c3
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of strcasecmp_l.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# define strcasecmp_l __strcasecmp_l_ppc
++extern __typeof (__strcasecmp_l) __strcasecmp_l_ppc attribute_hidden;
++extern __typeof (__strcasecmp_l) __strcasecmp_l_power7 attribute_hidden;
++#endif
++
++#include <string/strcasecmp_l.c>
++#undef strcasecmp_l
++
++#ifndef NOT_IN_libc
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__strcasecmp_l) __libc_strcasecmp_l;
++libc_ifunc (__libc_strcasecmp_l,
++	    (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __strcasecmp_l_power7
++            : __strcasecmp_l_ppc);
++
++weak_alias (__libc_strcasecmp_l, strcasecmp_l)
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-11.patch b/SOURCES/glibc-rh731837-11.patch
new file mode 100644
index 0000000..6083f0c
--- /dev/null
+++ b/SOURCES/glibc-rh731837-11.patch
@@ -0,0 +1,220 @@
+From 0c36ea57312ce701930b879d49b3f64cead222d8 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:48:25 -0500
+Subject: [PATCH] PowerPC: multiarch strncasecmp for PowerPC64
+
+commit 1c92d9a0e0be6175915128157036cf138ef64af8
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:40:28 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  6 +++-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  | 15 ++++++++
+ .../powerpc/powerpc64/multiarch/strncase-power7.c  | 24 +++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strncase.c     | 41 +++++++++++++++++++++
+ .../powerpc64/multiarch/strncase_l-power7.c        | 25 +++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strncase_l.c   | 42 ++++++++++++++++++++++
+ 6 files changed, 152 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase_l-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase_l.c
+
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 5e172da..4dca756 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -6,5 +6,9 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \
+                   memrchr-power7 memrchr-ppc64 rawmemchr-power7 \
+                   rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \
+-                  strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7
++                  strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \
++                  strncase-power7 strncase_l-power7
++
++CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
++CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index ba78d97..4b8fb22 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -151,5 +151,20 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
+                              __strcasecmp_l_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strncase.c.  */
++  IFUNC_IMPL (i, name, strncasecmp,
++             IFUNC_IMPL_ADD (array, i, strncasecmp,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __strncasecmp_power7)
++             IFUNC_IMPL_ADD (array, i, strncasecmp, 1, __strncasecmp_ppc))
++
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strncase_l.c.  */
++  IFUNC_IMPL (i, name, strncasecmp_l,
++             IFUNC_IMPL_ADD (array, i, strncasecmp_l,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __strncasecmp_l_power7)
++             IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
++                             __strncasecmp_l_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase-power7.c b/sysdeps/powerpc/powerpc64/multiarch/strncase-power7.c
+new file mode 100644
+index 0000000..9c5dbab
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase-power7.c
+@@ -0,0 +1,24 @@
++/* Copyright (C) 2013-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 <string.h>
++
++#define __strncasecmp __strncasecmp_power7
++
++extern __typeof (strncasecmp) __strncasecmp_power7 attribute_hidden;
++
++#include <string/strncase.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase.c b/sysdeps/powerpc/powerpc64/multiarch/strncase.c
+new file mode 100644
+index 0000000..05eba7c
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase.c
+@@ -0,0 +1,41 @@
++/* Multiple versions of strncasecmp
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# define strncasecmp __strncasecmp_ppc
++extern __typeof (__strncasecmp) __strncasecmp_ppc attribute_hidden;
++extern __typeof (__strncasecmp) __strncasecmp_power7 attribute_hidden;
++#endif
++
++#include <string/strncase.c>
++#undef strncasecmp
++
++#ifndef NOT_IN_libc
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++extern __typeof (__strncasecmp) __libc_strncasecmp;
++libc_ifunc (__libc_strncasecmp,
++	     (hwcap & PPC_FEATURE_HAS_VSX)
++             ? __strncasecmp_power7
++             : __strncasecmp_ppc);
++weak_alias (__libc_strncasecmp, strncasecmp)
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase_l-power7.c b/sysdeps/powerpc/powerpc64/multiarch/strncase_l-power7.c
+new file mode 100644
+index 0000000..8c8cd8d
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase_l-power7.c
+@@ -0,0 +1,25 @@
++/* Copyright (C) 2013-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 <string.h>
++
++#define __strncasecmp_l __strncasecmp_l_power7
++#define USE_IN_EXTENDED_LOCALE_MODEL    1
++
++extern __typeof (strncasecmp_l) __strncasecmp_l_power7 attribute_hidden;
++
++#include <string/strncase.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c b/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c
+new file mode 100644
+index 0000000..4014269
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c
+@@ -0,0 +1,42 @@
++/* Multiple versions of strncasecmp_l
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# define strncasecmp_l __strncasecmp_l_ppc
++extern __typeof (__strncasecmp_l) __strncasecmp_l_ppc attribute_hidden;
++extern __typeof (__strncasecmp_l) __strncasecmp_l_power7 attribute_hidden;
++#endif
++
++#include <string/strncase_l.c>
++#undef strncasecmp_l
++
++#ifndef NOT_IN_libc
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++extern __typeof (__strncasecmp_l) __libc_strncasecmp_l;
++libc_ifunc (__libc_strncasecmp_l,
++	     (hwcap & PPC_FEATURE_HAS_VSX)
++             ? __strncasecmp_l_power7
++             : __strncasecmp_l_ppc);
++
++weak_alias (__libc_strncasecmp_l, strncasecmp_l)
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-12.patch b/SOURCES/glibc-rh731837-12.patch
new file mode 100644
index 0000000..15fa0cf
--- /dev/null
+++ b/SOURCES/glibc-rh731837-12.patch
@@ -0,0 +1,237 @@
+From fda2d6aca32ad6a4d546ab3a7dd708de78e18c3a Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:49:36 -0500
+Subject: [PATCH] PowerPC: multiarch strncmp for PowerPC64
+
+commit 24c2c3b99699b7cb7cc3c251d9bd504b2cde6a45
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:48:48 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  3 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  9 +++++
+ .../powerpc/powerpc64/multiarch/strncmp-power4.S   | 38 ++++++++++++++++++++
+ .../powerpc/powerpc64/multiarch/strncmp-power7.S   | 39 ++++++++++++++++++++
+ .../powerpc/powerpc64/multiarch/strncmp-ppc64.S    | 41 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strncmp.c      | 37 +++++++++++++++++++
+ 6 files changed, 166 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp.c
+
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 4dca756..22baf1c 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -7,7 +7,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   memrchr-power7 memrchr-ppc64 rawmemchr-power7 \
+                   rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \
+                   strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \
+-                  strncase-power7 strncase_l-power7
++                  strncase-power7 strncase_l-power7 strncmp-power7 \
++                  strncmp-power4 strncmp-ppc64
+ 
+ CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
+ CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 4b8fb22..67f75a5 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -77,6 +77,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+                              __strlen_power7)
+              IFUNC_IMPL_ADD (array, i, strlen, 1,
+                              __strlen_ppc))
++
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strncmp.c.  */
++  IFUNC_IMPL (i, name, strncmp,
++             IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_HAS_VSX,
++                             __strncmp_power7)
++             IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_POWER4,
++                             __strncmp_power4)
++             IFUNC_IMPL_ADD (array, i, strncmp, 1,
++                             __strncmp_ppc))
+ #endif
+ 
+   /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c.  */
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
+new file mode 100644
+index 0000000..62cebbc
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
+@@ -0,0 +1,38 @@
++/* Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name,alignt,words)				\
++  .section ".text";						\
++  ENTRY_2(__strncmp_power4)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__strncmp_power4):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strncmp_power4)					\
++  END_2(__strncmp_power4)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power4/strncmp.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
+new file mode 100644
+index 0000000..b0d607a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
+@@ -0,0 +1,39 @@
++/* Copyright (C) 2013-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 <sysdep.h>
++
++#undef EALIGN
++#define EALIGN(name,alignt,words)				\
++  .section ".text";						\
++  ENTRY_2(__strncmp_power7)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__strncmp_power7):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strncmp_power7)					\
++  END_2(__strncmp_power7)
++
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power7/strncmp.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
+new file mode 100644
+index 0000000..25b7f26
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
+@@ -0,0 +1,41 @@
++/* Copyright (C) 2013-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 <sysdep.h>
++
++#if defined SHARED && !defined NOT_IN_libc
++#undef EALIGN
++#define EALIGN(name,alignt,words)				\
++  .section ".text";						\
++  ENTRY_2(__strncmp_ppc)					\
++  .align ALIGNARG(alignt);					\
++  EALIGN_W_##words;						\
++  BODY_LABEL(__strncmp_ppc):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strncmp_ppc)					\
++  END_2(__strncmp_ppc)
++
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name)				\
++    .globl __GI_strncmp; __GI_strncmp = __strncmp_ppc
++#endif
++
++#include <sysdeps/powerpc/powerpc64/strncmp.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
+new file mode 100644
+index 0000000..9829d69
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of strncmp.
++   Copyright (C) 2013-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/>.  */
++
++/* Define multiple versions only for definition in libc.  */
++#if defined SHARED && !defined NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
++extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
++extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (strncmp,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __strncmp_power7 :
++	      (hwcap & PPC_FEATURE_POWER4)
++		? __strncmp_power4
++            : __strncmp_ppc);
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-13.patch b/SOURCES/glibc-rh731837-13.patch
new file mode 100644
index 0000000..f3a3c58
--- /dev/null
+++ b/SOURCES/glibc-rh731837-13.patch
@@ -0,0 +1,212 @@
+From 1a5121cbdc34d9f56bb1bbb3f3ce3a90ddc1ff6b Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:55:13 -0500
+Subject: [PATCH] PowerPC: multiarch strchr for PowerPC64
+
+commit 372dc060e0a25044ba5a797c71fb0ee53921fe47
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:49:54 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  2 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  8 +++++
+ sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S  | 18 ++++++++++
+ .../powerpc/powerpc64/multiarch/strchr-power7.S    | 38 ++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S | 41 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strchr.c       | 35 ++++++++++++++++++
+ 6 files changed, 141 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchr.c
+
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 22baf1c..f7c5853 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -8,7 +8,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \
+                   strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \
+                   strncase-power7 strncase_l-power7 strncmp-power7 \
+-                  strncmp-power4 strncmp-ppc64
++                  strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64
+ 
+ CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
+ CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 67f75a5..3b005ea 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -86,6 +86,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+                              __strncmp_power4)
+              IFUNC_IMPL_ADD (array, i, strncmp, 1,
+                              __strncmp_ppc))
++
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strchr.c.  */
++  IFUNC_IMPL (i, name, strchr,
++             IFUNC_IMPL_ADD (array, i, strchr,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __strchr_power7)
++             IFUNC_IMPL_ADD (array, i, strchr, 1,
++                             __strchr_ppc))
+ #endif
+ 
+   /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c.  */
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S b/sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S
+new file mode 100644
+index 0000000..5c62657
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S
+@@ -0,0 +1,18 @@
++/* Copyright (C) 2013-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 <sysdeps/powerpc/powerpc64/strchr.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S
+new file mode 100644
+index 0000000..0b2ca42
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S
+@@ -0,0 +1,38 @@
++/* Optimized strchr implementation for POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__strchr_power7)					\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__strchr_power7):					\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strchr_power7)					\
++  END_2(__strchr_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power7/strchr.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S
+new file mode 100644
+index 0000000..ded9284
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S
+@@ -0,0 +1,41 @@
++/* PowerPC64 default implementation of strchr.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#ifdef SHARED
++# undef ENTRY
++# define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__strchr_ppc)						\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__strchr_ppc):					\
++  cfi_startproc;
++
++# undef END
++# define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strchr_ppc)					\
++  END_2(__strchr_ppc)
++
++# undef libc_hidden_builtin_def
++# define libc_hidden_builtin_def(name)				\
++    .globl __GI_strchr; __GI_strchr = __strchr_ppc
++#endif
++
++#include <sysdeps/powerpc/powerpc64/strchr.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
+new file mode 100644
+index 0000000..74a9d54
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
+@@ -0,0 +1,35 @@
++/* Multiple versions of strchr.
++   Copyright (C) 2013-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/>.  */
++
++/* Define multiple versions only for definition in libc.  */
++#if defined SHARED && !defined NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (strchr) __strchr_ppc attribute_hidden;
++extern __typeof (strchr) __strchr_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (strchr,
++	    (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __strchr_power7
++            : __strchr_ppc);
++weak_alias (strchr, index)
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-14.patch b/SOURCES/glibc-rh731837-14.patch
new file mode 100644
index 0000000..569aba2
--- /dev/null
+++ b/SOURCES/glibc-rh731837-14.patch
@@ -0,0 +1,226 @@
+From 942cdf02caef0ea4fe257cf5898754b9b1897c4a Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 05:58:14 -0500
+Subject: [PATCH] PowerPC: multiarch strchrnul for PowerPC64
+
+commit 9ee2969b057862443b81789b56a61514edf34779
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:50:26 2013 -0500
+
+Added sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c and
+string/strchrnul.c apart from original commit.
+---
+ string/strchrnul.c                                 |  6 +++-
+ .../powerpc32/power4/multiarch/strchrnul-ppc32.c   | 28 ++++++++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  3 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  8 +++++
+ .../powerpc/powerpc64/multiarch/strchrnul-power7.S | 38 ++++++++++++++++++++++
+ .../powerpc/powerpc64/multiarch/strchrnul-ppc64.c  | 19 +++++++++++
+ sysdeps/powerpc/powerpc64/multiarch/strchrnul.c    | 37 +++++++++++++++++++++
+ 7 files changed, 137 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchrnul-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
+
+diff --git a/string/strchrnul.c b/string/strchrnul.c
+index 0db5e23..39540a3 100644
+--- a/string/strchrnul.c
++++ b/string/strchrnul.c
+@@ -27,9 +27,13 @@
+ #undef __strchrnul
+ #undef strchrnul
+ 
++#ifndef STRCHRNUL
++# define STRCHRNUL __strchrnul
++#endif
++
+ /* Find the first occurrence of C in S or the final NUL byte.  */
+ char *
+-__strchrnul (s, c_in)
++STRCHRNUL (s, c_in)
+      const char *s;
+      int c_in;
+ {
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c
+new file mode 100644
+index 0000000..950643a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c
+@@ -0,0 +1,28 @@
++/* PowerPC32 default implementation of strchrnul.
++   Copyright (C) 2013-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 <string.h>
++
++#define STRCHRNUL  __strchrnul_ppc
++
++#undef weak_alias
++#define weak_alias(a,b )
++
++extern __typeof (strchrnul) __strchrnul_ppc attribute_hidden;
++
++#include <string/strchrnul.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index f7c5853..15b86bd 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -8,7 +8,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \
+                   strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \
+                   strncase-power7 strncase_l-power7 strncmp-power7 \
+-                  strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64
++                  strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \
++                  strchrnul-power7 strchrnul-ppc64
+ 
+ CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
+ CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 3b005ea..9e3b89d 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -94,6 +94,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+                              __strchr_power7)
+              IFUNC_IMPL_ADD (array, i, strchr, 1,
+                              __strchr_ppc))
++
++  /* Support sysdeps/powerpc/powerpc64/multiarch/strchrnul.c.  */
++  IFUNC_IMPL (i, name, strchrnul,
++             IFUNC_IMPL_ADD (array, i, strchrnul,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __strchrnul_power7)
++             IFUNC_IMPL_ADD (array, i, strchrnul, 1,
++                             __strchrnul_ppc))
+ #endif
+ 
+   /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c.  */
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S
+new file mode 100644
+index 0000000..87d7c03
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S
+@@ -0,0 +1,38 @@
++/* Optimized strchrnul implementation for POWER7.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef ENTRY
++#define ENTRY(name)						\
++  .section ".text";						\
++  ENTRY_2(__strchrnul_power7)					\
++  .align ALIGNARG(2);						\
++  BODY_LABEL(__strchrnul_power7):				\
++  cfi_startproc;
++
++#undef END
++#define END(name)						\
++  cfi_endproc;							\
++  TRACEBACK(__strchrnul_power7)					\
++  END_2(__strchrnul_power7)
++
++#undef libc_hidden_builtin_def
++#define libc_hidden_builtin_def(name)
++
++#include <sysdeps/powerpc/powerpc64/power7/strchrnul.S>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchrnul-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strchrnul-ppc64.c
+new file mode 100644
+index 0000000..a76b335
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchrnul-ppc64.c
+@@ -0,0 +1,19 @@
++/* PowerPC64 default implementation of strchrnul.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
+new file mode 100644
+index 0000000..dab1cbf
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c
+@@ -0,0 +1,37 @@
++/* Multiple versions of strchrnul.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <string.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (__strchrnul) __strchrnul_ppc attribute_hidden;
++extern __typeof (__strchrnul) __strchrnul_power7 attribute_hidden;
++
++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
++   ifunc symbol properly.  */
++libc_ifunc (__strchrnul,
++	    (hwcap & PPC_FEATURE_HAS_VSX)
++            ? __strchrnul_power7
++            : __strchrnul_ppc);
++
++weak_alias (__strchrnul, strchrnul)
++#else
++#include <string/strchrnul.c>
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-15.patch b/SOURCES/glibc-rh731837-15.patch
new file mode 100644
index 0000000..f7c6eb8
--- /dev/null
+++ b/SOURCES/glibc-rh731837-15.patch
@@ -0,0 +1,399 @@
+From be1d5d1d239883daea876f39e804d87ca028fe2c Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 07:33:06 -0500
+Subject: [PATCH] PowerPC: multiarch wcschr for PowerPC64
+
+commit 16fd2ae37cce401aad580d3d6ffae825827231ae
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:51:36 2013 -0500
+
+Added the following files apart from original commit.
+sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c
+sysdeps/powerpc/powerpc64/power6/wcschr.c
+sysdeps/powerpc/power6/wcschr.c
+---
+ sysdeps/powerpc/power6/wcschr.c                    | 89 ++++++++++++++++++++++
+ .../powerpc32/power4/multiarch/wcschr-power6.c     | 26 +++++++
+ .../powerpc32/power4/multiarch/wcschr-power7.c     | 26 +++++++
+ .../powerpc32/power4/multiarch/wcschr-ppc32.c      | 31 ++++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  5 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  | 11 +++
+ .../powerpc/powerpc64/multiarch/wcschr-power6.c    | 19 +++++
+ .../powerpc/powerpc64/multiarch/wcschr-power7.c    | 19 +++++
+ sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c | 18 +++++
+ sysdeps/powerpc/powerpc64/multiarch/wcschr.c       | 38 +++++++++
+ sysdeps/powerpc/powerpc64/power6/wcschr.c          |  2 +-
+ 11 files changed, 282 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/power6/wcschr.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcschr-power6.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcschr-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcschr.c
+
+diff --git a/sysdeps/powerpc/power6/wcschr.c b/sysdeps/powerpc/power6/wcschr.c
+new file mode 100644
+index 0000000..7045677
+--- /dev/null
++++ b/sysdeps/powerpc/power6/wcschr.c
+@@ -0,0 +1,89 @@
++/* wcschr.c - Wide Character Search for POWER6+.
++   Copyright (C) 2012-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <wchar.h>
++
++#ifndef WCSCHR
++# define WCSCHR wcschr
++#endif
++
++/* Find the first occurrence of WC in WCS.  */
++wchar_t *
++WCSCHR (const wchar_t *wcs, const wchar_t wc)
++{
++  const wchar_t *wcs2 = wcs + 1;
++
++  if (*wcs == wc)
++    return (wchar_t *) wcs;
++  if (*wcs == L'\0')
++    return NULL;
++
++  do
++    {
++      wcs += 2;
++
++      if (*wcs2 == wc)
++        return (wchar_t *) wcs2;
++      if (*wcs2 == L'\0')
++        return NULL;
++       wcs2 += 2;
++
++      if (*wcs == wc)
++        return (wchar_t *) wcs;
++      if (*wcs == L'\0')
++        return NULL;
++      wcs += 2;
++
++      if (*wcs2 == wc)
++        return (wchar_t *) wcs2;
++      if (*wcs2 == L'\0')
++        return NULL;
++      wcs2 += 2;
++
++      if (*wcs == wc)
++        return (wchar_t *) wcs;
++      if (*wcs == L'\0')
++        return NULL;
++      wcs += 2;
++
++      if (*wcs2 == wc)
++        return (wchar_t *) wcs2;
++      if (*wcs2 == L'\0')
++        return NULL;
++      wcs2 += 2;
++
++      if (*wcs == wc)
++        return (wchar_t *) wcs;
++      if (*wcs == L'\0')
++        return NULL;
++      wcs += 2;
++
++      if (*wcs2 == wc)
++        return (wchar_t *) wcs2;
++      if (*wcs2 == L'\0')
++        return NULL;
++      wcs2 += 2;
++
++      if (*wcs == wc)
++        return (wchar_t *) wcs;
++    }
++  while (*wcs != L'\0');
++
++  return NULL;
++}
++libc_hidden_def (wcschr)
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c
+new file mode 100644
+index 0000000..7c648d8
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c
+@@ -0,0 +1,26 @@
++/* wcschr.c - Wide Character Search for powerpc32/power6.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <wchar.h>
++
++#define WCSCHR __wcschr_power6
++
++#undef libc_hidden_def
++#define libc_hidden_def(name)
++
++#include <sysdeps/powerpc/power6/wcschr.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c
+new file mode 100644
+index 0000000..e561ced
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c
+@@ -0,0 +1,26 @@
++/* wcschr.c - Wide Character Search for powerpc32/power7.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <wchar.h>
++
++#define WCSCHR __wcschr_power7
++
++#undef libc_hidden_def
++#define libc_hidden_def(name)
++
++#include <sysdeps/powerpc/power6/wcschr.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c
+new file mode 100644
+index 0000000..a42f70c
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c
+@@ -0,0 +1,31 @@
++/* Copyright (C) 2013-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 <wchar.h>
++
++#ifndef NOT_IN_libc
++# ifdef SHARED
++#   undef libc_hidden_def
++#   define libc_hidden_def(name)  \
++    __hidden_ver1 (__wcschr_ppc, __GI_wcschr, __wcschr_ppc);
++# endif
++# define WCSCHR  __wcschr_ppc
++#endif
++
++extern __typeof (wcschr) __wcschr_ppc;
++
++#include <wcsmbs/wcschr.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 15b86bd..ff3b8cf 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -9,8 +9,11 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \
+                   strncase-power7 strncase_l-power7 strncmp-power7 \
+                   strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \
+-                  strchrnul-power7 strchrnul-ppc64
++                  strchrnul-power7 strchrnul-ppc64 wcschr-power7 \
++                  wcschr-power6 wcschr-ppc64
+ 
+ CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
+ CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
++CFLAGS-wcschr-power7.c += -mcpu=power7
++CFLAGS-wcschr-power6.c += -mcpu=power6
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 9e3b89d..cc932c9 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -191,5 +191,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
+                              __strncasecmp_l_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/wcschr.c.  */
++  IFUNC_IMPL (i, name, wcschr,
++             IFUNC_IMPL_ADD (array, i, wcschr,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __wcschr_power7)
++             IFUNC_IMPL_ADD (array, i, wcschr,
++                             hwcap & PPC_FEATURE_ARCH_2_05,
++                             __wcschr_power6)
++             IFUNC_IMPL_ADD (array, i, wcschr, 1,
++                             __wcschr_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr-power6.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr-power6.c
+new file mode 100644
+index 0000000..21d965a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcschr-power6.c
+@@ -0,0 +1,19 @@
++/* wcschr.c - Wide Character Search for powerpc64/power6.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr-power7.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr-power7.c
+new file mode 100644
+index 0000000..3407219
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcschr-power7.c
+@@ -0,0 +1,19 @@
++/* wcschr.c - Wide Character Search for powerpc64/power7.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c
+new file mode 100644
+index 0000000..3f1f368
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c
+@@ -0,0 +1,18 @@
++/* Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
+new file mode 100644
+index 0000000..216d2bc
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
+@@ -0,0 +1,38 @@
++/* Multiple versions of wcschr
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <wchar.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (wcschr) __wcschr_ppc attribute_hidden;
++extern __typeof (wcschr) __wcschr_power6 attribute_hidden;
++extern __typeof (wcschr) __wcschr_power7 attribute_hidden;
++
++libc_ifunc (wcschr,
++	     (hwcap & PPC_FEATURE_HAS_VSX)
++             ? __wcschr_power7 :
++	       (hwcap & PPC_FEATURE_ARCH_2_05)
++	       ? __wcschr_power6
++             : __wcschr_ppc);
++#else
++#undef libc_hidden_def
++#define libc_hidden_def(a)
++#include <wcsmbs/wcschr.c>
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/power6/wcschr.c b/sysdeps/powerpc/powerpc64/power6/wcschr.c
+index 9136c02..ae04a13 100644
+--- a/sysdeps/powerpc/powerpc64/power6/wcschr.c
++++ b/sysdeps/powerpc/powerpc64/power6/wcschr.c
+@@ -1 +1 @@
+-#include "../../powerpc32/power6/wcschr.c"
++#include <sysdeps/powerpc/power6/wcschr.c>
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-16.patch b/SOURCES/glibc-rh731837-16.patch
new file mode 100644
index 0000000..74703de
--- /dev/null
+++ b/SOURCES/glibc-rh731837-16.patch
@@ -0,0 +1,402 @@
+From 62edac04130e7d91b0d4872376bdaa976065fd25 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 07:40:10 -0500
+Subject: [PATCH] PowerPC: multiarch wcsrchr for PowerPC64
+
+commit 7b714620a7146104aaf863ba1dbe386beedbcc0a
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:52:48 2013 -0500
+
+Added the following files apart from original commit.
+sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c
+sysdeps/powerpc/powerpc64/power6/wcsrchr.c
+wcsmbs/wcsrchr.c
+---
+ sysdeps/powerpc/power6/wcsrchr.c                   | 89 ++++++++++++++++++++++
+ .../powerpc32/power4/multiarch/wcsrchr-power6.c    | 20 +++++
+ .../powerpc32/power4/multiarch/wcsrchr-power7.c    | 20 +++++
+ .../powerpc32/power4/multiarch/wcsrchr-ppc32.c     | 26 +++++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |  5 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  | 11 +++
+ .../powerpc/powerpc64/multiarch/wcsrchr-power6.c   | 19 +++++
+ .../powerpc/powerpc64/multiarch/wcsrchr-power7.c   | 19 +++++
+ .../powerpc/powerpc64/multiarch/wcsrchr-ppc64.c    | 18 +++++
+ sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c      | 36 +++++++++
+ sysdeps/powerpc/powerpc64/power6/wcsrchr.c         |  2 +-
+ wcsmbs/wcsrchr.c                                   |  5 +-
+ 12 files changed, 267 insertions(+), 3 deletions(-)
+ create mode 100644 sysdeps/powerpc/power6/wcsrchr.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power6.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcsrchr-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c
+
+diff --git a/sysdeps/powerpc/power6/wcsrchr.c b/sysdeps/powerpc/power6/wcsrchr.c
+new file mode 100644
+index 0000000..278d98d
+--- /dev/null
++++ b/sysdeps/powerpc/power6/wcsrchr.c
+@@ -0,0 +1,89 @@
++/* wcsrchr.c - Wide Character Reverse Search for POWER6+.
++   Copyright (C) 2012-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <wchar.h>
++
++#ifndef WCSRCHR
++# define WCSRCHR wcsrchr
++#endif
++
++/* Find the last occurrence of WC in WCS.  */
++wchar_t *
++WCSRCHR (const wchar_t *wcs, const wchar_t wc)
++{
++  const wchar_t *wcs2 = wcs + 1;
++  const wchar_t *retval = NULL;
++
++  if (*wcs == wc)
++    retval = wcs;
++
++  if (*wcs == L'\0') return (wchar_t *) retval;
++
++  do
++    {
++    wcs+=2;
++
++    if (*wcs2 == wc)
++      retval = wcs2;
++    if (*wcs2 == L'\0')
++      return (wchar_t *) retval;
++    wcs2+=2;
++
++    if (*wcs == wc)
++      retval = wcs;
++    if (*wcs == L'\0')
++      return (wchar_t *) retval;
++    wcs+=2;
++
++    if (*wcs2 == wc)
++      retval = wcs2;
++    if (*wcs2 == L'\0')
++      return (wchar_t *) retval;
++    wcs2+=2;
++
++    if (*wcs == wc)
++      retval = wcs;
++    if (*wcs == L'\0')
++      return (wchar_t *) retval;
++    wcs+=2;
++
++    if (*wcs2 == wc)
++      retval = wcs2;
++    if (*wcs2 == L'\0')
++      return (wchar_t *) retval;
++    wcs2+=2;
++
++    if (*wcs == wc)
++      retval = wcs;
++    if (*wcs == L'\0')
++      return (wchar_t *) retval;
++    wcs+=2;
++
++    if (*wcs2 == wc)
++      retval = wcs2;
++    if (*wcs2 == L'\0')
++      return (wchar_t *) retval;
++    wcs2+=2;
++
++    if (*wcs == wc)
++      retval = wcs;
++    }
++  while (*wcs != L'\0');
++
++  return (wchar_t *) retval;
++}
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c
+new file mode 100644
+index 0000000..bd77eb3
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c
+@@ -0,0 +1,20 @@
++/* Copyright (C) 2013-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/>.  */
++
++#define WCSRCHR      __wcsrchr_power6
++
++#include <sysdeps/powerpc/power6/wcsrchr.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c
+new file mode 100644
+index 0000000..829a434
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c
+@@ -0,0 +1,20 @@
++/* Copyright (C) 2013-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/>.  */
++
++#define WCSRCHR      __wcsrchr_power7
++
++#include <sysdeps/powerpc/power6/wcsrchr.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c
+new file mode 100644
+index 0000000..9c7fe2d
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c
+@@ -0,0 +1,26 @@
++/* Copyright (C) 2013-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 <wchar.h>
++
++#ifndef NOT_IN_libc
++# define WCSRCHR  __wcsrchr_ppc
++#endif
++
++extern __typeof (wcsrchr) __wcsrchr_ppc;
++
++#include <wcsmbs/wcsrchr.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index ff3b8cf..b4504b7 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -10,10 +10,13 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   strncase-power7 strncase_l-power7 strncmp-power7 \
+                   strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \
+                   strchrnul-power7 strchrnul-ppc64 wcschr-power7 \
+-                  wcschr-power6 wcschr-ppc64
++                  wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \
++                  wcsrchr-ppc64
+ 
+ CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
+ CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
+ CFLAGS-wcschr-power7.c += -mcpu=power7
+ CFLAGS-wcschr-power6.c += -mcpu=power6
++CFLAGS-wcsrchr-power7.c += -mcpu=power7
++CFLAGS-wcsrchr-power6.c += -mcpu=power6
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index cc932c9..6c7422c 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -202,5 +202,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, wcschr, 1,
+                              __wcschr_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/wcschr.c.  */
++  IFUNC_IMPL (i, name, wcsrchr,
++             IFUNC_IMPL_ADD (array, i, wcsrchr,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __wcsrchr_power7)
++             IFUNC_IMPL_ADD (array, i, wcsrchr,
++                             hwcap & PPC_FEATURE_ARCH_2_05,
++                             __wcsrchr_power6)
++             IFUNC_IMPL_ADD (array, i, wcsrchr, 1,
++                             __wcsrchr_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power6.c b/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power6.c
+new file mode 100644
+index 0000000..da6f27b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power6.c
+@@ -0,0 +1,19 @@
++/* wcsrchr.c - Wide Character Search for powerpc64/power6.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power7.c b/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power7.c
+new file mode 100644
+index 0000000..60f07a8
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power7.c
+@@ -0,0 +1,19 @@
++/* wcsrchr.c - Wide Character Search for powerpc64/power7.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-ppc64.c
+new file mode 100644
+index 0000000..1fff510
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-ppc64.c
+@@ -0,0 +1,18 @@
++/* Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c b/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c
+new file mode 100644
+index 0000000..3d0ab42
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c
+@@ -0,0 +1,36 @@
++/* Multiple versions of wcsrchr.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <wchar.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (wcsrchr) __wcsrchr_ppc attribute_hidden;
++extern __typeof (wcsrchr) __wcsrchr_power6 attribute_hidden;
++extern __typeof (wcsrchr) __wcsrchr_power7 attribute_hidden;
++
++libc_ifunc (wcsrchr,
++	     (hwcap & PPC_FEATURE_HAS_VSX)
++             ? __wcsrchr_power7 :
++	       (hwcap & PPC_FEATURE_ARCH_2_05)
++	       ? __wcsrchr_power6
++             : __wcsrchr_ppc);
++#else
++#include <wcsmbs/wcsrchr.c>
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/power6/wcsrchr.c b/sysdeps/powerpc/powerpc64/power6/wcsrchr.c
+index 2327c05..b86472d 100644
+--- a/sysdeps/powerpc/powerpc64/power6/wcsrchr.c
++++ b/sysdeps/powerpc/powerpc64/power6/wcsrchr.c
+@@ -1 +1 @@
+-#include "../../powerpc32/power6/wcsrchr.c"
++#include <sysdeps/powerpc/power6/wcsrchr.c>
+diff --git a/wcsmbs/wcsrchr.c b/wcsmbs/wcsrchr.c
+index c1b5a59..27c94c5 100644
+--- a/wcsmbs/wcsrchr.c
++++ b/wcsmbs/wcsrchr.c
+@@ -18,10 +18,13 @@
+ 
+ #include <wchar.h>
+ 
++#ifndef WCSRCHR
++# define WCSRCHR wcsrchr
++#endif
+ 
+ /* Find the last occurrence of WC in WCS.  */
+ wchar_t *
+-wcsrchr (wcs, wc)
++WCSRCHR (wcs, wc)
+      register const wchar_t *wcs;
+      register const wchar_t wc;
+ {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-17.patch b/SOURCES/glibc-rh731837-17.patch
new file mode 100644
index 0000000..0672d30
--- /dev/null
+++ b/SOURCES/glibc-rh731837-17.patch
@@ -0,0 +1,424 @@
+From 21ee17d9e36c21d0c143287cc678a373893e94cc Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 07:45:17 -0500
+Subject: [PATCH] PowerPC: multiarch wcscpy for PowerPC64
+
+commit 92cacfce7d40cb331009fdcd79d83b075a1a8785
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:53:25 2013 -0500
+
+Added the following files apart from original commit.   .
+sysdeps/powerpc/power6/wcscpy.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c
+sysdeps/powerpc/powerpc64/power6/wcscpy.c
+wcsmbs/wcscpy.c
+---
+ sysdeps/powerpc/power6/wcscpy.c                    | 105 +++++++++++++++++++++
+ .../powerpc32/power4/multiarch/wcscpy-power6.c     |  22 +++++
+ .../powerpc32/power4/multiarch/wcscpy-power7.c     |  22 +++++
+ .../powerpc32/power4/multiarch/wcscpy-ppc32.c      |  26 +++++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |   4 +-
+ .../powerpc/powerpc64/multiarch/ifunc-impl-list.c  |  11 +++
+ .../powerpc/powerpc64/multiarch/wcscpy-power6.c    |  19 ++++
+ .../powerpc/powerpc64/multiarch/wcscpy-power7.c    |  19 ++++
+ sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c |  18 ++++
+ sysdeps/powerpc/powerpc64/multiarch/wcscpy.c       |  36 +++++++
+ sysdeps/powerpc/powerpc64/power6/wcscpy.c          |   2 +-
+ wcsmbs/wcscpy.c                                    |   5 +-
+ 12 files changed, 286 insertions(+), 3 deletions(-)
+ create mode 100644 sysdeps/powerpc/power6/wcscpy.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcscpy-power6.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcscpy-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcscpy.c
+
+diff --git a/sysdeps/powerpc/power6/wcscpy.c b/sysdeps/powerpc/power6/wcscpy.c
+new file mode 100644
+index 0000000..417ec72
+--- /dev/null
++++ b/sysdeps/powerpc/power6/wcscpy.c
+@@ -0,0 +1,105 @@
++/* wcscpy.c - Wide Character Copy for POWER6+.
++   Copyright (C) 2012-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <stddef.h>
++#include <wchar.h>
++
++#ifndef WCSCPY
++# define WCSCPY wcscpy
++#endif
++
++/* Copy SRC to DEST.  */
++wchar_t *
++WCSCPY (wchar_t *dest, const wchar_t *src)
++{
++  wint_t c,d;
++  wchar_t *wcp, *wcp2;
++
++  if (__alignof__ (wchar_t) >= sizeof (wchar_t))
++    {
++      const ptrdiff_t off = dest - src;
++
++      wcp = (wchar_t *) src;
++      wcp2 = wcp + 1 ;
++
++      do
++        {
++          d = *wcp;
++          wcp[off] = d;
++          if (d == L'\0')
++            return dest;
++          wcp += 2;
++
++          c = *wcp2;
++          wcp2[off] = c;
++          if (c == L'\0')
++            return dest;
++          wcp2 += 2;
++
++          d = *wcp;
++          wcp[off] = d;
++          if (d == L'\0')
++            return dest;
++          wcp += 2;
++
++          c = *wcp2;
++          wcp2[off] = c;
++          if (c == L'\0')
++            return dest;
++          wcp2 += 2;
++
++          d = *wcp;
++          wcp[off] = d;
++          if (d == L'\0')
++            return dest;
++          wcp += 2;
++
++          c = *wcp2;
++          wcp2[off] = c;
++          if (c == L'\0')
++            return dest;
++          wcp2 += 2;
++
++          d = *wcp;
++          wcp[off] = d;
++          if (d == L'\0')
++            return dest;
++          wcp += 2;
++
++          c = *wcp2;
++          wcp2[off] = c;
++          if (c == L'\0')
++            return dest;
++          wcp2 += 2;
++        }
++      while (c != L'\0');
++
++    }
++  else
++    {
++      wcp = dest;
++
++      do
++        {
++          c = *src++;
++          *wcp++ = c;
++        }
++      while (c != L'\0');
++    }
++  return dest;
++}
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c
+new file mode 100644
+index 0000000..6c86baa
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c
+@@ -0,0 +1,22 @@
++/* Copyright (C) 2013-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 <wchar.h>
++
++#define WCSCPY __wcscpy_power6
++
++#include <sysdeps/powerpc/power6/wcscpy.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c
+new file mode 100644
+index 0000000..dad0e70
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c
+@@ -0,0 +1,22 @@
++/* Copyright (C) 2013-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 <wchar.h>
++
++#define WCSCPY __wcscpy_power7
++
++#include <sysdeps/powerpc/power6/wcscpy.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c
+new file mode 100644
+index 0000000..c135835
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c
+@@ -0,0 +1,26 @@
++/* Copyright (C) 2013-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 <wchar.h>
++
++#ifndef NOT_IN_libc
++# define WCSCPY  __wcscpy_ppc
++#endif
++
++extern __typeof (wcscpy) __wcscpy_ppc;
++
++#include <wcsmbs/wcscpy.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index b4504b7..7113212 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -11,7 +11,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \
+                   strchrnul-power7 strchrnul-ppc64 wcschr-power7 \
+                   wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \
+-                  wcsrchr-ppc64
++                  wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64
+ 
+ CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
+ CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
+@@ -19,4 +19,6 @@ CFLAGS-wcschr-power7.c += -mcpu=power7
+ CFLAGS-wcschr-power6.c += -mcpu=power6
+ CFLAGS-wcsrchr-power7.c += -mcpu=power7
+ CFLAGS-wcsrchr-power6.c += -mcpu=power6
++CFLAGS-wcscpy-power7.c += -mcpu=power7
++CFLAGS-wcscpy-power6.c += -mcpu=power6
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+index 6c7422c..2d21ce1 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+@@ -213,5 +213,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+              IFUNC_IMPL_ADD (array, i, wcsrchr, 1,
+                              __wcsrchr_ppc))
+ 
++  /* Support sysdeps/powerpc/powerpc64/multiarch/wcscpy.c.  */
++  IFUNC_IMPL (i, name, wcscpy,
++             IFUNC_IMPL_ADD (array, i, wcscpy,
++                             hwcap & PPC_FEATURE_HAS_VSX,
++                             __wcscpy_power7)
++             IFUNC_IMPL_ADD (array, i, wcscpy,
++                             hwcap & PPC_FEATURE_ARCH_2_05,
++                             __wcscpy_power6)
++             IFUNC_IMPL_ADD (array, i, wcscpy, 1,
++                             __wcscpy_ppc))
++
+   return i;
+ }
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power6.c b/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power6.c
+new file mode 100644
+index 0000000..9f4bc41
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power6.c
+@@ -0,0 +1,19 @@
++/* wcscpy.c - Wide Character Search for powerpc64/power6.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power7.c b/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power7.c
+new file mode 100644
+index 0000000..0f37ad4
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power7.c
+@@ -0,0 +1,19 @@
++/* wcscpy.c - Wide Character Search for powerpc64/power7.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c
+new file mode 100644
+index 0000000..4559569
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c
+@@ -0,0 +1,18 @@
++/* Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c b/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c
+new file mode 100644
+index 0000000..5c0a6d3
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c
+@@ -0,0 +1,36 @@
++/* Multiple versions of wcscpy.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <wchar.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (wcscpy) __wcscpy_ppc attribute_hidden;
++extern __typeof (wcscpy) __wcscpy_power6 attribute_hidden;
++extern __typeof (wcscpy) __wcscpy_power7 attribute_hidden;
++
++libc_ifunc (wcscpy,
++	     (hwcap & PPC_FEATURE_HAS_VSX)
++             ? __wcscpy_power7 :
++	       (hwcap & PPC_FEATURE_ARCH_2_05)
++	       ? __wcscpy_power6
++             : __wcscpy_ppc);
++#else
++#include <wcsmbs/wcscpy.c>
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/power6/wcscpy.c b/sysdeps/powerpc/powerpc64/power6/wcscpy.c
+index 57b706a..722c8f9 100644
+--- a/sysdeps/powerpc/powerpc64/power6/wcscpy.c
++++ b/sysdeps/powerpc/powerpc64/power6/wcscpy.c
+@@ -1 +1 @@
+-#include "../../powerpc32/power6/wcscpy.c"
++#include <sysdeps/powerpc/power6/wcscpy.c>
+diff --git a/wcsmbs/wcscpy.c b/wcsmbs/wcscpy.c
+index 6dea24d..cec1249 100644
+--- a/wcsmbs/wcscpy.c
++++ b/wcsmbs/wcscpy.c
+@@ -19,10 +19,13 @@
+ #include <stddef.h>
+ #include <wchar.h>
+ 
++#ifndef WCSCPY
++# define WCSCPY wcscpy
++#endif
+ 
+ /* Copy SRC to DEST.  */
+ wchar_t *
+-wcscpy (dest, src)
++WCSCPY (dest, src)
+      wchar_t *dest;
+      const wchar_t *src;
+ {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-18.patch b/SOURCES/glibc-rh731837-18.patch
new file mode 100644
index 0000000..3259c95
--- /dev/null
+++ b/SOURCES/glibc-rh731837-18.patch
@@ -0,0 +1,1076 @@
+From 8d960764b1afa3b64c3c388665499935a38b194e Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 08:12:17 -0500
+Subject: [PATCH] PowerPC: multiarch wordcopy for PowerPC64
+
+commit e28bcd427b21b6c74021ca65736dd66474b09013
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:54:08 2013 -0500
+
+Added the following files apart from original commit.
+sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c
+sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c
+sysdeps/powerpc/power4/wordcopy.c
+sysdeps/powerpc/power6/wordcopy.c
+Removed the following files apart from original commit.
+sysdeps/powerpc/power4/wordcopy.c
+sysdeps/powerpc/powerpc64/power6/wordcopy.c
+---
+ string/wordcopy.c                                  |  38 ++--
+ sysdeps/powerpc/power4/wordcopy.c                  | 212 ++++++++++++++++++++
+ sysdeps/powerpc/power6/wordcopy.c                  | 221 +++++++++++++++++++++
+ .../powerpc32/power4/multiarch/wordcopy-power6.c   |  23 +++
+ .../powerpc32/power4/multiarch/wordcopy-power7.c   |  23 +++
+ .../powerpc32/power4/multiarch/wordcopy-ppc32.c    |  23 +++
+ sysdeps/powerpc/powerpc64/multiarch/Makefile       |   5 +-
+ .../powerpc/powerpc64/multiarch/wordcopy-power6.c  |  19 ++
+ .../powerpc/powerpc64/multiarch/wordcopy-power7.c  |  19 ++
+ .../powerpc/powerpc64/multiarch/wordcopy-ppc64.c   |  18 ++
+ sysdeps/powerpc/powerpc64/multiarch/wordcopy.c     |  86 ++++++++
+ sysdeps/powerpc/powerpc64/power4/wordcopy.c        |   1 -
+ sysdeps/powerpc/powerpc64/power6/wordcopy.c        | 217 --------------------
+ 13 files changed, 669 insertions(+), 236 deletions(-)
+ create mode 100644 sysdeps/powerpc/power4/wordcopy.c
+ create mode 100644 sysdeps/powerpc/power6/wordcopy.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wordcopy-power6.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wordcopy-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wordcopy-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wordcopy.c
+ delete mode 100644 sysdeps/powerpc/powerpc64/power4/wordcopy.c
+ delete mode 100644 sysdeps/powerpc/powerpc64/power6/wordcopy.c
+
+diff --git a/string/wordcopy.c b/string/wordcopy.c
+index b171f27..ff4cce4 100644
+--- a/string/wordcopy.c
++++ b/string/wordcopy.c
+@@ -1,5 +1,5 @@
+ /* _memcopy.c -- subroutines for memory copy functions.
+-   Copyright (C) 1991, 1996 Free Software Foundation, Inc.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Torbjorn Granlund (tege@sics.se).
+ 
+@@ -26,11 +26,12 @@
+    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+    Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
+ 
++#ifndef WORDCOPY_FWD_ALIGNED
++# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned
++#endif
++
+ void
+-_wordcopy_fwd_aligned (dstp, srcp, len)
+-     long int dstp;
+-     long int srcp;
+-     size_t len;
++WORDCOPY_FWD_ALIGNED (long int dstp, long int srcp, size_t len)
+ {
+   op_t a0, a1;
+ 
+@@ -134,11 +135,12 @@ _wordcopy_fwd_aligned (dstp, srcp, len)
+    DSTP should be aligned for memory operations on `op_t's, but SRCP must
+    *not* be aligned.  */
+ 
++#ifndef WORDCOPY_FWD_DEST_ALIGNED
++# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned
++#endif
++
+ void
+-_wordcopy_fwd_dest_aligned (dstp, srcp, len)
+-     long int dstp;
+-     long int srcp;
+-     size_t len;
++WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
+ {
+   op_t a0, a1, a2, a3;
+   int sh_1, sh_2;
+@@ -221,11 +223,12 @@ _wordcopy_fwd_dest_aligned (dstp, srcp, len)
+    (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
+    operations on `op_t's.  */
+ 
++#ifndef WORDCOPY_BWD_ALIGNED
++# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned
++#endif
++
+ void
+-_wordcopy_bwd_aligned (dstp, srcp, len)
+-     long int dstp;
+-     long int srcp;
+-     size_t len;
++WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len)
+ {
+   op_t a0, a1;
+ 
+@@ -329,11 +332,12 @@ _wordcopy_bwd_aligned (dstp, srcp, len)
+    words (not LEN bytes!).  DSTP should be aligned for memory
+    operations on `op_t', but SRCP must *not* be aligned.  */
+ 
++#ifndef WORDCOPY_BWD_DEST_ALIGNED
++# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned
++#endif
++
+ void
+-_wordcopy_bwd_dest_aligned (dstp, srcp, len)
+-     long int dstp;
+-     long int srcp;
+-     size_t len;
++WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
+ {
+   op_t a0, a1, a2, a3;
+   int sh_1, sh_2;
+diff --git a/sysdeps/powerpc/power4/wordcopy.c b/sysdeps/powerpc/power4/wordcopy.c
+new file mode 100644
+index 0000000..263b444
+--- /dev/null
++++ b/sysdeps/powerpc/power4/wordcopy.c
+@@ -0,0 +1,212 @@
++/* _memcopy.c -- subroutines for memory copy functions.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++   Contributed by Torbjorn Granlund (tege@sics.se).
++
++   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/>.  */
++
++/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
++
++#include <stddef.h>
++#include <memcopy.h>
++
++/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
++   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
++   Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
++
++#ifndef WORDCOPY_FWD_ALIGNED
++# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned
++#endif
++
++void
++WORDCOPY_FWD_ALIGNED (long int dstp, long int srcp, size_t len)
++{
++  op_t a0, a1;
++
++  if (len & 1)
++  {
++    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
++
++    if (len == 1)
++      return;
++    srcp += OPSIZ;
++    dstp += OPSIZ;
++    len -= 1;
++  }
++
++  do
++    {
++      a0 = ((op_t *) srcp)[0];
++      a1 = ((op_t *) srcp)[1];
++      ((op_t *) dstp)[0] = a0;
++      ((op_t *) dstp)[1] = a1;
++
++      srcp += 2 * OPSIZ;
++      dstp += 2 * OPSIZ;
++      len -= 2;
++    }
++  while (len != 0);
++}
++
++/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
++   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
++   DSTP should be aligned for memory operations on `op_t's, but SRCP must
++   *not* be aligned.  */
++
++#ifndef WORDCOPY_FWD_DEST_ALIGNED
++# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned
++#endif
++
++void
++WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
++{
++  op_t a0, a1, a2;
++  int sh_1, sh_2;
++
++  /* Calculate how to shift a word read at the memory operation
++     aligned srcp to make it aligned for copy.  */
++
++  sh_1 = 8 * (srcp % OPSIZ);
++  sh_2 = 8 * OPSIZ - sh_1;
++
++  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
++     it points in the middle of.  */
++  srcp &= -OPSIZ;
++  a0 = ((op_t *) srcp)[0];
++
++  if (len & 1)
++  {
++    a1 = ((op_t *) srcp)[1];
++    ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
++
++    if (len == 1)
++      return;
++
++    a0 = a1;
++    srcp += OPSIZ;
++    dstp += OPSIZ;
++    len -= 1;
++  }
++
++  do
++    {
++      a1 = ((op_t *) srcp)[1];
++      a2 = ((op_t *) srcp)[2];
++      ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
++      ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
++      a0 = a2;
++
++      srcp += 2 * OPSIZ;
++      dstp += 2 * OPSIZ;
++      len -= 2;
++    }
++  while (len != 0);
++}
++
++/* _wordcopy_bwd_aligned -- Copy block finishing right before
++   SRCP to block finishing right before DSTP with LEN `op_t' words
++   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
++   operations on `op_t's.  */
++
++#ifndef WORDCOPY_BWD_ALIGNED
++# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned
++#endif
++
++void
++WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len)
++{
++  op_t a0, a1;
++
++  if (len & 1)
++  {
++    srcp -= OPSIZ;
++    dstp -= OPSIZ;
++    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
++
++    if (len == 1)
++      return;
++    len -= 1;
++  }
++
++  do
++    {
++      srcp -= 2 * OPSIZ;
++      dstp -= 2 * OPSIZ;
++
++      a1 = ((op_t *) srcp)[1];
++      a0 = ((op_t *) srcp)[0];
++      ((op_t *) dstp)[1] = a1;
++      ((op_t *) dstp)[0] = a0;
++
++      len -= 2;
++    }
++  while (len != 0);
++}
++
++/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
++   before SRCP to block finishing right before DSTP with LEN `op_t'
++   words (not LEN bytes!).  DSTP should be aligned for memory
++   operations on `op_t', but SRCP must *not* be aligned.  */
++
++#ifndef WORDCOPY_BWD_DEST_ALIGNED
++# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned
++#endif
++
++void
++WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
++{
++  op_t a0, a1, a2;
++  int sh_1, sh_2;
++
++  /* Calculate how to shift a word read at the memory operation
++     aligned srcp to make it aligned for copy.  */
++
++  sh_1 = 8 * (srcp % OPSIZ);
++  sh_2 = 8 * OPSIZ - sh_1;
++
++  /* Make srcp aligned by rounding it down to the beginning of the op_t
++     it points in the middle of.  */
++  srcp &= -OPSIZ;
++  a2 = ((op_t *) srcp)[0];
++
++  if (len & 1)
++  {
++    srcp -= OPSIZ;
++    dstp -= OPSIZ;
++    a1 = ((op_t *) srcp)[0];
++    ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
++
++    if (len == 1)
++      return;
++
++    a2 = a1;
++    len -= 1;
++  }
++
++  do
++    {
++      srcp -= 2 * OPSIZ;
++      dstp -= 2 * OPSIZ;
++
++      a1 = ((op_t *) srcp)[1];
++      a0 = ((op_t *) srcp)[0];
++      ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
++      ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
++      a2 = a0;
++
++      len -= 2;
++    }
++  while (len != 0);
++}
+diff --git a/sysdeps/powerpc/power6/wordcopy.c b/sysdeps/powerpc/power6/wordcopy.c
+new file mode 100644
+index 0000000..c32e6dd
+--- /dev/null
++++ b/sysdeps/powerpc/power6/wordcopy.c
+@@ -0,0 +1,221 @@
++/* _memcopy.c -- subroutines for memory copy functions.
++   Copyright (C) 1991-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++   Contributed by Torbjorn Granlund (tege@sics.se).
++   Updated for POWER6 by Steven Munroe (sjmunroe@us.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/>.  */
++
++/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
++
++#include <stddef.h>
++#include <memcopy.h>
++
++/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
++   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
++   Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
++
++#ifndef WORDCOPY_FWD_ALIGNED
++# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned
++#endif
++
++void
++WORDCOPY_FWD_ALIGNED (long int dstp, long int srcp, size_t len)
++{
++  op_t a0, a1;
++
++  if (len & 1)
++  {
++    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
++
++    if (len == 1)
++      return;
++    srcp += OPSIZ;
++    dstp += OPSIZ;
++    len -= 1;
++  }
++
++  do
++    {
++      a0 = ((op_t *) srcp)[0];
++      a1 = ((op_t *) srcp)[1];
++      ((op_t *) dstp)[0] = a0;
++      ((op_t *) dstp)[1] = a1;
++
++      srcp += 2 * OPSIZ;
++      dstp += 2 * OPSIZ;
++      len -= 2;
++    }
++  while (len != 0);
++}
++
++/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
++   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
++   DSTP should be aligned for memory operations on `op_t's, but SRCP must
++   *not* be aligned.  */
++
++#define fwd_align_merge(align)                                         \
++  do                                                                   \
++    {                                                                  \
++      a1 = ((op_t *) srcp)[1];                                         \
++      a2 = ((op_t *) srcp)[2];                                         \
++      ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (__WORDSIZE-align*8)); \
++      ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (__WORDSIZE-align*8)); \
++      a0 = a2;                                                         \
++      srcp += 2 * OPSIZ;                                               \
++      dstp += 2 * OPSIZ;                                               \
++      len -= 2;                                                                \
++    }                                                                  \
++  while (len != 0)
++
++#ifndef WORDCOPY_FWD_DEST_ALIGNED
++# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned
++#endif
++
++void
++WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
++{
++  op_t a0, a1, a2;
++  int sh_1, sh_2;
++  int align;
++
++  /* Calculate how to shift a word read at the memory operation
++     aligned srcp to make it aligned for copy.  */
++
++  align = srcp % OPSIZ;
++  sh_1 = 8 * (srcp % OPSIZ);
++  sh_2 = 8 * OPSIZ - sh_1;
++
++  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
++     it points in the middle of.  */
++  srcp &= -OPSIZ;
++  a0 = ((op_t *) srcp)[0];
++
++  if (len & 1)
++  {
++    a1 = ((op_t *) srcp)[1];
++    ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
++
++    if (len == 1)
++      return;
++
++    a0 = a1;
++    srcp += OPSIZ;
++    dstp += OPSIZ;
++    len -= 1;
++  }
++
++  fwd_align_merge (align);
++
++}
++
++/* _wordcopy_bwd_aligned -- Copy block finishing right before
++   SRCP to block finishing right before DSTP with LEN `op_t' words
++   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
++   operations on `op_t's.  */
++
++#ifndef WORDCOPY_BWD_ALIGNED
++# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned
++#endif
++
++void
++WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len)
++{
++  op_t a0, a1;
++
++  if (len & 1)
++  {
++    srcp -= OPSIZ;
++    dstp -= OPSIZ;
++    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
++
++    if (len == 1)
++      return;
++    len -= 1;
++  }
++
++  do
++    {
++      srcp -= 2 * OPSIZ;
++      dstp -= 2 * OPSIZ;
++
++      a1 = ((op_t *) srcp)[1];
++      a0 = ((op_t *) srcp)[0];
++      ((op_t *) dstp)[1] = a1;
++      ((op_t *) dstp)[0] = a0;
++
++      len -= 2;
++    }
++  while (len != 0);
++}
++
++#define bwd_align_merge(align)                                         \
++  do                                                                   \
++    {                                                                  \
++      srcp -= 2 * OPSIZ;                                               \
++      dstp -= 2 * OPSIZ;                                               \
++      a1 = ((op_t *) srcp)[1];                                         \
++      a0 = ((op_t *) srcp)[0];                                         \
++      ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (__WORDSIZE-align*8)); \
++      ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (__WORDSIZE-align*8)); \
++      a2 = a0;                                                         \
++      len -= 2;                                                                \
++    }                                                                  \
++  while (len != 0)
++
++/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
++   before SRCP to block finishing right before DSTP with LEN `op_t'
++   words (not LEN bytes!).  DSTP should be aligned for memory
++   operations on `op_t', but SRCP must *not* be aligned.  */
++
++#ifndef WORDCOPY_BWD_DEST_ALIGNED
++# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned
++#endif
++
++void
++WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
++{
++  op_t a0, a1, a2;
++  int sh_1, sh_2;
++  int align;
++
++  /* Calculate how to shift a word read at the memory operation
++     aligned srcp to make it aligned for copy.  */
++
++  align = srcp % OPSIZ;
++  sh_1 = 8 * (srcp % OPSIZ);
++  sh_2 = 8 * OPSIZ - sh_1;
++
++  /* Make srcp aligned by rounding it down to the beginning of the op_t
++     it points in the middle of.  */
++  srcp &= -OPSIZ;
++  a2 = ((op_t *) srcp)[0];
++
++  if (len & 1)
++  {
++    srcp -= OPSIZ;
++    dstp -= OPSIZ;
++    a1 = ((op_t *) srcp)[0];
++    ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
++
++    if (len == 1)
++      return;
++
++    a2 = a1;
++    len -= 1;
++  }
++
++  bwd_align_merge (align);
++}
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c
+new file mode 100644
+index 0000000..c5c6eb7
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c
+@@ -0,0 +1,23 @@
++/* Copyright (C) 2013-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/>.  */
++
++#define WORDCOPY_FWD_ALIGNED      _wordcopy_fwd_aligned_power6
++#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_power6
++#define WORDCOPY_BWD_ALIGNED      _wordcopy_bwd_aligned_power6
++#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_power6
++
++#include <sysdeps/powerpc/power6/wordcopy.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c
+new file mode 100644
+index 0000000..841d1a2
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c
+@@ -0,0 +1,23 @@
++/* Copyright (C) 2013-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/>.  */
++
++#define WORDCOPY_FWD_ALIGNED      _wordcopy_fwd_aligned_power7
++#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_power7
++#define WORDCOPY_BWD_ALIGNED      _wordcopy_bwd_aligned_power7
++#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_power7
++
++#include <sysdeps/powerpc/power6/wordcopy.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c
+new file mode 100644
+index 0000000..ccd24ad
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c
+@@ -0,0 +1,23 @@
++/* Copyright (C) 2013-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/>.  */
++
++#define WORDCOPY_FWD_ALIGNED      _wordcopy_fwd_aligned_ppc
++#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_ppc
++#define WORDCOPY_BWD_ALIGNED      _wordcopy_bwd_aligned_ppc
++#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_ppc
++
++#include <sysdeps/powerpc/power4/wordcopy.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+index 7113212..8dceb09 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
+@@ -11,7 +11,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
+                   strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \
+                   strchrnul-power7 strchrnul-ppc64 wcschr-power7 \
+                   wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \
+-                  wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64
++                  wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64 \
++                  wordcopy-power7 wordcopy-power6 wordcopy-ppc64
+ 
+ CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
+ CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
+@@ -21,4 +22,6 @@ CFLAGS-wcsrchr-power7.c += -mcpu=power7
+ CFLAGS-wcsrchr-power6.c += -mcpu=power6
+ CFLAGS-wcscpy-power7.c += -mcpu=power7
+ CFLAGS-wcscpy-power6.c += -mcpu=power6
++CFLAGS-wordcopy-power7.c += -mcpu=power7
++CFLAGS-wordcopy-power6.c += -mcpu=power6
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power6.c b/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power6.c
+new file mode 100644
+index 0000000..2a65b52
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power6.c
+@@ -0,0 +1,19 @@
++/* wordcopy routines for powerpc64/power6.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power7.c b/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power7.c
+new file mode 100644
+index 0000000..e804f88
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power7.c
+@@ -0,0 +1,19 @@
++/* wordcopy routines for powerpc64/power7.
++   Copyright (C) 2013-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; see the file COPYING.LIB.  If
++   not, see <http://www.gnu.org/licenses/>.  */
++
++#include <sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wordcopy-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/wordcopy-ppc64.c
+new file mode 100644
+index 0000000..0584277
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wordcopy-ppc64.c
+@@ -0,0 +1,18 @@
++/* Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c>
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c b/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c
+new file mode 100644
+index 0000000..889be25
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c
+@@ -0,0 +1,86 @@
++/* Multiple versions of wordcopy functions.
++   Copyright (C) 2013-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/>.  */
++
++#ifndef NOT_IN_libc
++# include <stddef.h>
++# include <memcopy.h>
++# include <shlib-compat.h>
++# include "init-arch.h"
++
++extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_ppc
++attribute_hidden;
++extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power6
++attribute_hidden;
++extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power7
++attribute_hidden;
++
++libc_ifunc (_wordcopy_fwd_aligned,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? _wordcopy_fwd_aligned_power7 :
++	      (hwcap & PPC_FEATURE_ARCH_2_05)
++              ? _wordcopy_fwd_aligned_power6
++            : _wordcopy_fwd_aligned_ppc);
++
++
++extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_ppc
++attribute_hidden;
++extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power6
++attribute_hidden;
++extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power7
++attribute_hidden;
++
++libc_ifunc (_wordcopy_fwd_dest_aligned,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? _wordcopy_fwd_dest_aligned_power7 :
++	      (hwcap & PPC_FEATURE_ARCH_2_05)
++              ? _wordcopy_fwd_dest_aligned_power6
++            : _wordcopy_fwd_dest_aligned_ppc);
++
++
++extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_ppc
++attribute_hidden;
++extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power6
++attribute_hidden;
++extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power7
++attribute_hidden;
++
++libc_ifunc (_wordcopy_bwd_aligned,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? _wordcopy_bwd_aligned_power7 :
++	      (hwcap & PPC_FEATURE_ARCH_2_05)
++              ? _wordcopy_bwd_aligned_power6
++            : _wordcopy_bwd_aligned_ppc);
++
++
++extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_ppc
++attribute_hidden;
++extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power6
++attribute_hidden;
++extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power7
++attribute_hidden;
++
++libc_ifunc (_wordcopy_bwd_dest_aligned,
++            (hwcap & PPC_FEATURE_HAS_VSX)
++            ? _wordcopy_bwd_dest_aligned_power7 :
++	      (hwcap & PPC_FEATURE_ARCH_2_05)
++              ? _wordcopy_bwd_dest_aligned_power6
++            : _wordcopy_bwd_dest_aligned_ppc);
++
++#else
++#include <sysdeps/powerpc/power4/wordcopy.c>
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/power4/wordcopy.c b/sysdeps/powerpc/powerpc64/power4/wordcopy.c
+deleted file mode 100644
+index f427b48..0000000
+--- a/sysdeps/powerpc/powerpc64/power4/wordcopy.c
++++ /dev/null
+@@ -1 +0,0 @@
+-#include "../../powerpc32/power4/wordcopy.c"
+diff --git a/sysdeps/powerpc/powerpc64/power6/wordcopy.c b/sysdeps/powerpc/powerpc64/power6/wordcopy.c
+deleted file mode 100644
+index 4c72404..0000000
+--- a/sysdeps/powerpc/powerpc64/power6/wordcopy.c
++++ /dev/null
+@@ -1,217 +0,0 @@
+-/* _memcopy.c -- subroutines for memory copy functions.
+-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Torbjorn Granlund (tege@sics.se).
+-
+-   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/>.  */
+-
+-/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
+-
+-#include <stddef.h>
+-#include <memcopy.h>
+-
+-/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
+-   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+-   Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
+-
+-void
+-_wordcopy_fwd_aligned (dstp, srcp, len)
+-     long int dstp;
+-     long int srcp;
+-     size_t len;
+-{
+-  op_t a0, a1;
+-
+-  if (len & 1)
+-  {
+-    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
+-    
+-    if (len == 1)
+-      return;
+-    srcp += OPSIZ;
+-    dstp += OPSIZ;
+-    len -= 1;
+-  }
+-
+-  do
+-    {
+-      a0 = ((op_t *) srcp)[0];
+-      a1 = ((op_t *) srcp)[1];
+-      ((op_t *) dstp)[0] = a0;
+-      ((op_t *) dstp)[1] = a1;
+-
+-      srcp += 2 * OPSIZ;
+-      dstp += 2 * OPSIZ;
+-      len -= 2;
+-    }
+-  while (len != 0);
+-}
+-
+-#define fwd_align_merge(align)                                         \
+-  do                                                                   \
+-    {                                                                  \
+-      a1 = ((op_t *) srcp)[1];                                         \
+-      a2 = ((op_t *) srcp)[2];                                         \
+-      ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (64-align*8));      \
+-      ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (64-align*8));      \
+-      a0 = a2;                                                         \
+-      srcp += 2 * OPSIZ;                                               \
+-      dstp += 2 * OPSIZ;                                               \
+-      len -= 2;                                                                \
+-    }                                                                  \
+-  while (len != 0)
+-
+-
+-/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
+-   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+-   DSTP should be aligned for memory operations on `op_t's, but SRCP must
+-   *not* be aligned.  */
+-
+-void
+-_wordcopy_fwd_dest_aligned (dstp, srcp, len)
+-     long int dstp;
+-     long int srcp;
+-     size_t len;
+-{
+-  op_t a0, a1, a2;
+-  int sh_1, sh_2;
+-  int align;
+-
+-  /* Calculate how to shift a word read at the memory operation
+-     aligned srcp to make it aligned for copy.  */
+-
+-  align = srcp % OPSIZ;
+-  sh_1 = 8 * (srcp % OPSIZ);
+-  sh_2 = 8 * OPSIZ - sh_1;
+-
+-  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
+-     it points in the middle of.  */
+-  srcp &= -OPSIZ;
+-  a0 = ((op_t *) srcp)[0];
+-
+-  if (len & 1)
+-  {
+-    a1 = ((op_t *) srcp)[1];
+-    ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
+-    
+-    if (len == 1)
+-      return;
+-    
+-    a0 = a1;
+-    srcp += OPSIZ;
+-    dstp += OPSIZ;
+-    len -= 1;
+-  }
+-
+-  fwd_align_merge (align);
+-
+-}
+-
+-/* _wordcopy_bwd_aligned -- Copy block finishing right before
+-   SRCP to block finishing right before DSTP with LEN `op_t' words
+-   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
+-   operations on `op_t's.  */
+-
+-void
+-_wordcopy_bwd_aligned (dstp, srcp, len)
+-     long int dstp;
+-     long int srcp;
+-     size_t len;
+-{
+-  op_t a0, a1;
+-
+-  if (len & 1)
+-  {
+-    srcp -= OPSIZ;
+-    dstp -= OPSIZ;
+-    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
+-    
+-    if (len == 1)
+-      return;
+-    len -= 1;
+-  }
+-
+-  do
+-    {
+-      srcp -= 2 * OPSIZ;
+-      dstp -= 2 * OPSIZ;
+-
+-      a1 = ((op_t *) srcp)[1];
+-      a0 = ((op_t *) srcp)[0];
+-      ((op_t *) dstp)[1] = a1;
+-      ((op_t *) dstp)[0] = a0;
+-
+-      len -= 2;
+-    }
+-  while (len != 0);
+-}
+-
+-#define bwd_align_merge(align)                                         \
+-  do                                                                   \
+-    {                                                                  \
+-      srcp -= 2 * OPSIZ;                                               \
+-      dstp -= 2 * OPSIZ;                                               \
+-      a1 = ((op_t *) srcp)[1];                                         \
+-      a0 = ((op_t *) srcp)[0];                                         \
+-      ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (64-align*8));      \
+-      ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (64-align*8));      \
+-      a2 = a0;                                                         \
+-      len -= 2;                                                                \
+-    }                                                                  \
+-  while (len != 0)
+-
+-/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
+-   before SRCP to block finishing right before DSTP with LEN `op_t'
+-   words (not LEN bytes!).  DSTP should be aligned for memory
+-   operations on `op_t', but SRCP must *not* be aligned.  */
+-
+-void
+-_wordcopy_bwd_dest_aligned (dstp, srcp, len)
+-     long int dstp;
+-     long int srcp;
+-     size_t len;
+-{
+-  op_t a0, a1, a2;
+-  int sh_1, sh_2;
+-  int align;
+-
+-  /* Calculate how to shift a word read at the memory operation
+-     aligned srcp to make it aligned for copy.  */
+-
+-  align = srcp % OPSIZ;
+-  sh_1 = 8 * (srcp % OPSIZ);
+-  sh_2 = 8 * OPSIZ - sh_1;
+-
+-  /* Make srcp aligned by rounding it down to the beginning of the op_t
+-     it points in the middle of.  */
+-  srcp &= -OPSIZ;
+-  a2 = ((op_t *) srcp)[0];
+-
+-  if (len & 1)
+-  {
+-    srcp -= OPSIZ;
+-    dstp -= OPSIZ;
+-    a1 = ((op_t *) srcp)[0];
+-    ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
+-
+-    if (len == 1)
+-      return;
+-
+-    a2 = a1;
+-    len -= 1;
+-  }
+-
+-  bwd_align_merge (align);
+-}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-19.patch b/SOURCES/glibc-rh731837-19.patch
new file mode 100644
index 0000000..a20a73a
--- /dev/null
+++ b/SOURCES/glibc-rh731837-19.patch
@@ -0,0 +1,28 @@
+From a060ed545478f28bded88544e9361c49cf442427 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 08:19:53 -0500
+Subject: [PATCH] More fixes for unsafe compiler optimization
+
+commit 1775babf2be39c3e09eb8b855379d0aca867abeb
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Tue Apr 29 14:15:45 2014 -0500
+
+GCC 4.9 -ftree-loop-distribute-patterns now may transform loops in
+memcpy.  Add the alias to internal GLIBC symbol to avoid PLT creation.
+---
+ sysdeps/generic/symbol-hacks.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sysdeps/generic/symbol-hacks.h b/sysdeps/generic/symbol-hacks.h
+index 9eaf014..6bec24b 100644
+--- a/sysdeps/generic/symbol-hacks.h
++++ b/sysdeps/generic/symbol-hacks.h
+@@ -3,4 +3,5 @@
+ #if !defined __ASSEMBLER__ && !defined NOT_IN_libc && defined SHARED
+ asm ("memmove = __GI_memmove");
+ asm ("memset = __GI_memset");
++asm ("memcpy = __GI_memcpy");
+ #endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-20.patch b/SOURCES/glibc-rh731837-20.patch
new file mode 100644
index 0000000..0256027
--- /dev/null
+++ b/SOURCES/glibc-rh731837-20.patch
@@ -0,0 +1,75 @@
+From 18284d83fcce6440cd6610beff72e2ae475f835d Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 10:34:08 -0500
+Subject: [PATCH] PowerPC: fpu multiarch support for PowerPC64
+
+commit 69bbc63d883c2bc9938fc7b8a3b28794de0e26cc
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:58:02 2013 -0500
+
+    PowerPC: Adjust multiarch Implies for PowerPC64
+
+    This patch adds Implies files on multiarch folder for POWER chips so
+    multirach is enabled when building with --with-cpu and powerN
+    option.
+---
+ sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies | 1 +
+ sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies  | 1 +
+ sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies  | 1 +
+ sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies | 1 +
+ sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies  | 1 +
+ sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies   | 2 --
+ 6 files changed, 5 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies
+ create mode 100644 sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies
+ delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies
+
+diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies
+new file mode 100644
+index 0000000..c0e6784
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power5/fpu/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies
+new file mode 100644
+index 0000000..3740d05
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power4/fpu/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies
+new file mode 100644
+index 0000000..fca8a4e
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power5+/fpu/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies
+new file mode 100644
+index 0000000..410d289
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power6/fpu/multiarch
+diff --git a/sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies
+new file mode 100644
+index 0000000..410d289
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies
+@@ -0,0 +1 @@
++powerpc/powerpc64/power6/fpu/multiarch
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies
+deleted file mode 100644
+index 6243d2e..0000000
+--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies
++++ /dev/null
+@@ -1,2 +0,0 @@
+-# Override ldbl-opt with powerpc64 specific routines.
+-powerpc/powerpc64/fpu
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-21.patch b/SOURCES/glibc-rh731837-21.patch
new file mode 100644
index 0000000..283932d
--- /dev/null
+++ b/SOURCES/glibc-rh731837-21.patch
@@ -0,0 +1,203 @@
+From ae7cc530d644d05ef11fe9a846dd5e4b51966734 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 10:35:21 -0500
+Subject: [PATCH] PowerPC: Cleaning up uneeded sqrt routines
+
+commit c24517c9dd9e92b4fa81e192967c63e56c1726e2
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 14:56:09 2013 -0500
+
+    PowerPC: Cleaning up uneeded sqrt routines
+
+    For PPC64, all the wrappers at sysdeps are superfluous: they are
+    basically the same implementation from math/w_sqrt.c with the
+    '#ifdef _IEEE_LIBM'. And the power4 version just force the 'fsqrt'
+    instruction utilization with an inline assembly, which is already
+    handled by math_private.h __ieee754_sqrt implementation.
+
+File sysdeps/powerpc/fpu/w_sqrt.c (part oforiginal commit)
+is already deleted by some previous patch. Hence ignoring that.
+---
+ sysdeps/powerpc/fpu/w_sqrtf.c                  | 46 ---------------------
+ sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c  | 55 --------------------------
+ sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c | 53 -------------------------
+ 3 files changed, 154 deletions(-)
+ delete mode 100644 sysdeps/powerpc/fpu/w_sqrtf.c
+ delete mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c
+ delete mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c
+
+diff --git a/sysdeps/powerpc/fpu/w_sqrtf.c b/sysdeps/powerpc/fpu/w_sqrtf.c
+deleted file mode 100644
+index 39b5b20..0000000
+--- a/sysdeps/powerpc/fpu/w_sqrtf.c
++++ /dev/null
+@@ -1,46 +0,0 @@
+-/* Single-precision floating point square root wrapper.
+-   Copyright (C) 2004, 2012 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>
+-#include <fenv_libc.h>
+-
+-#include <sysdep.h>
+-#include <ldsodefs.h>
+-
+-float
+-__sqrtf (float x)		/* wrapper sqrtf */
+-{
+-#ifdef _IEEE_LIBM
+-  return __ieee754_sqrtf (x);
+-#else
+-  float z;
+-  z = __ieee754_sqrtf (x);
+-
+-  if (_LIB_VERSION == _IEEE_ || (x != x))
+-    return z;
+-
+-  if (x < (float) 0.0)
+-    /* sqrtf(negative) */
+-    return (float) __kernel_standard ((double) x, (double) x, 126);
+-  else
+-    return z;
+-#endif
+-}
+-
+-weak_alias (__sqrtf, sqrtf)
+diff --git a/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c b/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c
+deleted file mode 100644
+index 1bd6a67..0000000
+--- a/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/* Double-precision floating point square root wrapper.
+-   Copyright (C) 2004, 2007, 2012 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_ldbl_opt.h>
+-#include <math.h>
+-#include <math_private.h>
+-#include <fenv_libc.h>
+-
+-double
+-__sqrt (double x)		/* wrapper sqrt */
+-{
+-  double z;
+-/* Power4 (ISA V2.0) and above implement sqrt in hardware.  */
+-   __asm __volatile (
+-	"	fsqrt	%0,%1\n"
+-		: "=f" (z)
+-		: "f" (x));
+-#ifdef _IEEE_LIBM
+-  return z;
+-#else
+-  if (__builtin_expect (_LIB_VERSION == _IEEE_, 0))
+-    return z;
+-    
+-  if (__builtin_expect (x != x, 0))
+-    return z;
+-    
+-  if  (__builtin_expect (x < 0.0, 0))
+-    return __kernel_standard (x, x, 26);	/* sqrt(negative) */
+-  else
+-    return z;
+-#endif
+-}
+-
+-weak_alias (__sqrt, sqrt)
+-#ifdef NO_LONG_DOUBLE
+-  strong_alias (__sqrt, __sqrtl) weak_alias (__sqrt, sqrtl)
+-#endif
+-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+-compat_symbol (libm, __sqrt, sqrtl, GLIBC_2_0);
+-#endif
+diff --git a/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c b/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c
+deleted file mode 100644
+index 0e7e692..0000000
+--- a/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c
++++ /dev/null
+@@ -1,53 +0,0 @@
+-/* Single-precision floating point square root wrapper.
+-   Copyright (C) 2004, 2007, 2012 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>
+-#include <fenv_libc.h>
+-
+-#include <sysdep.h>
+-#include <ldsodefs.h>
+-
+-float
+-__sqrtf (float x)		/* wrapper sqrtf */
+-{
+-#ifdef _IEEE_LIBM
+-  return __ieee754_sqrtf (x);
+-#else
+-  float z;
+-/* Power4 (ISA V2.0) and above implement sqrtf in hardware.  */
+-   __asm __volatile (
+-	"	fsqrts	%0,%1\n"
+-		: "=f" (z)
+-		: "f" (x));
+-
+-  if (__builtin_expect (_LIB_VERSION == _IEEE_, 0))
+-    return z;
+-    
+-  if (__builtin_expect (x != x, 0))
+-    return z;
+-    
+-  if  (__builtin_expect (x < 0.0, 0))
+-    /* sqrtf(negative) */
+-    return (float) __kernel_standard ((double) x, (double) x, 126);
+-  else
+-    return z;
+-#endif
+-}
+-
+-weak_alias (__sqrtf, sqrtf)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-22.patch b/SOURCES/glibc-rh731837-22.patch
new file mode 100644
index 0000000..b6fbaed
--- /dev/null
+++ b/SOURCES/glibc-rh731837-22.patch
@@ -0,0 +1,45 @@
+From 1aa79fbb9921281a8aedfe3eea1f273406b5f24c Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 11:23:08 -0500
+Subject: [PATCH] Fix cproj handling of (finite, NaN) arguments (bug 15531).
+
+commit c980f2f4fe0f5d301f706017a1f7e4e942193ec0
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Tue Aug 20 19:41:15 2013 +0000
+
+    Fix cproj handling of (finite, NaN) arguments (bug 15531).
+
+	* math/s_cprojf.c (__cprojf): Only return an infinity if one part of
+	argument is infinite.
+
+This patch is added so as to compile isnan multiarch implementation
+successfully since __GI___isnanf is missing.This wll be fixed later in master.
+---
+ math/s_cprojf.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/math/s_cprojf.c b/math/s_cprojf.c
+index 6cbc93b..a0f0af9 100644
+--- a/math/s_cprojf.c
++++ b/math/s_cprojf.c
+@@ -1,5 +1,5 @@
+ /* Compute projection of complex float value to Riemann sphere.
+-   Copyright (C) 1997, 1999, 2010 Free Software Foundation, Inc.
++   Copyright (C) 1997-2014 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+ 
+@@ -24,9 +24,7 @@
+ __complex__ float
+ __cprojf (__complex__ float x)
+ {
+-  if (isnan (__real__ x) && isnan (__imag__ x))
+-    return x;
+-  else if (!isfinite (__real__ x) || !isfinite (__imag__ x))
++  if (__isinf_nsf (__real__ x) || __isinf_nsf (__imag__ x))
+     {
+       __complex__ float res;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-23.patch b/SOURCES/glibc-rh731837-23.patch
new file mode 100644
index 0000000..9727724
--- /dev/null
+++ b/SOURCES/glibc-rh731837-23.patch
@@ -0,0 +1,362 @@
+From 54c7fb4227e044758021e638082f69d2a48d2658 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 10:40:10 -0500
+Subject: [PATCH] PowerPC: multiarch isnan/isnanf for PowerPC64
+
+commit b2284ad7cf6d9c2fea4223d933fcc152c0fee7c1
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:01:10 2013 -0500
+
+Added sysdeps/powerpc/powerpc32/fpu/s_isnan.S apart from
+the original commit.
+---
+ sysdeps/powerpc/powerpc32/fpu/s_isnan.S            |  2 +
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  7 +++
+ .../powerpc64/fpu/multiarch/s_isnan-power5.S       | 33 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_isnan-power6.S       | 33 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_isnan-power6x.S      | 33 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_isnan-power7.S       | 33 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_isnan-ppc64.S        | 32 +++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c  | 53 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c | 40 ++++++++++++++++
+ 9 files changed, 266 insertions(+)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power5.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6x.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+
+diff --git a/sysdeps/powerpc/powerpc32/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/fpu/s_isnan.S
+index f1ea473..0157805 100644
+--- a/sysdeps/powerpc/powerpc32/fpu/s_isnan.S
++++ b/sysdeps/powerpc/powerpc32/fpu/s_isnan.S
+@@ -37,9 +37,11 @@ weak_alias (__isnan, isnan)
+ 
+ /* It turns out that the 'double' version will also always work for
+    single-precision.  */
++#ifndef __isnan
+ strong_alias (__isnan, __isnanf)
+ hidden_def (__isnanf)
+ weak_alias (__isnanf, isnanf)
++#endif
+ 
+ #ifdef NO_LONG_DOUBLE
+ strong_alias (__isnan, __isnanl)
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+new file mode 100644
+index 0000000..b57ddc9
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -0,0 +1,7 @@
++ifeq ($(subdir),math)
++sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
++                  s_isnan-power5 s_isnan-ppc64
++
++libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
++                       s_isnan-power5 s_isnan-ppc64
++endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power5.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power5.S
+new file mode 100644
+index 0000000..145e24b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power5.S
+@@ -0,0 +1,33 @@
++/* isnan().  PowerPC64/POWER5 version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef hidden_def
++#define hidden_def(name)
++#undef weak_alias
++#define weak_alias(name, alias)
++#undef strong_alias
++#define strong_alias(name, alias)
++#undef compat_symbol
++#define compat_symbol(lib, name, symbol, ver)
++
++#define __isnan __isnan_power5
++
++#include <sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6.S
+new file mode 100644
+index 0000000..4576eb3
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6.S
+@@ -0,0 +1,33 @@
++/* isnan().  PowerPC64/POWER6 version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef hidden_def
++#define hidden_def(name)
++#undef weak_alias
++#define weak_alias(name, alias)
++#undef strong_alias
++#define strong_alias(name, alias)
++#undef compat_symbol
++#define compat_symbol(lib, name, symbol, ver)
++
++#define __isnan __isnan_power6
++
++#include <sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6x.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6x.S
+new file mode 100644
+index 0000000..c2a45e3
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6x.S
+@@ -0,0 +1,33 @@
++/* isnan().  PowerPC64/POWER6X version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef hidden_def
++#define hidden_def(name)
++#undef weak_alias
++#define weak_alias(name, alias)
++#undef strong_alias
++#define strong_alias(name, alias)
++#undef compat_symbol
++#define compat_symbol(lib, name, symbol, ver)
++
++#define __isnan __isnan_power6x
++
++#include <sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power7.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power7.S
+new file mode 100644
+index 0000000..05b9fbc
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power7.S
+@@ -0,0 +1,33 @@
++/* isnan().  PowerPC64/POWER7 version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef hidden_def
++#define hidden_def(name)
++#undef weak_alias
++#define weak_alias(name, alias)
++#undef strong_alias
++#define strong_alias(name, alias)
++#undef compat_symbol
++#define compat_symbol(lib, name, symbol, ver)
++
++#define __isnan __isnan_power7
++
++#include <sysdeps/powerpc/powerpc64/power7/fpu/s_isnan.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S
+new file mode 100644
+index 0000000..cf01d64
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S
+@@ -0,0 +1,32 @@
++/* isnan().  PowerPC32 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++
++#define __isnan __isnan_ppc64
++#undef hidden_def
++#define hidden_def(name) \
++  .globl __GI___isnan ; .set __GI___isnan,__isnan_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_isnan.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+new file mode 100644
+index 0000000..0de833e
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+@@ -0,0 +1,53 @@
++/* Multiple versions of isnan.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__isnan) __isnan_ppc64 attribute_hidden;
++extern __typeof (__isnan) __isnan_power5 attribute_hidden;
++extern __typeof (__isnan) __isnan_power6 attribute_hidden;
++extern __typeof (__isnan) __isnan_power6x attribute_hidden;
++extern __typeof (__isnan) __isnan_power7 attribute_hidden;
++
++libc_ifunc (__isnan,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __isnan_power7 :
++	      (hwcap & PPC_FEATURE_POWER6_EXT)
++		? __isnan_power6x :
++		(hwcap & PPC_FEATURE_ARCH_2_05)
++		  ? __isnan_power6 :
++		  (hwcap & PPC_FEATURE_POWER5)
++		    ? __isnan_power5
++            : __isnan_ppc64);
++
++weak_alias (__isnan, isnan)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__isnan, __isnanl)
++weak_alias (__isnan, isnanl)
++#endif
++
++#ifndef IS_IN_libm
++# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
++compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
++compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
++# endif
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+new file mode 100644
+index 0000000..b237455
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of isnan.
++   Copyright (C) 2013-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 "init-arch.h"
++
++/* The double-precision implementation also works for the single one.  */
++extern __typeof (__isnanf) __isnan_ppc64 attribute_hidden;
++extern __typeof (__isnanf) __isnan_power5 attribute_hidden;
++extern __typeof (__isnanf) __isnan_power6 attribute_hidden;
++extern __typeof (__isnanf) __isnan_power6x attribute_hidden;
++extern __typeof (__isnanf) __isnan_power7 attribute_hidden;
++
++libc_ifunc (__isnanf,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __isnan_power7 :
++	      (hwcap & PPC_FEATURE_POWER6_EXT)
++		? __isnan_power6x :
++		(hwcap & PPC_FEATURE_ARCH_2_05)
++		  ? __isnan_power6 :
++		  (hwcap & PPC_FEATURE_POWER5)
++		    ? __isnan_power5
++            : __isnan_ppc64);
++
++weak_alias (__isnanf, isnanf)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-24.patch b/SOURCES/glibc-rh731837-24.patch
new file mode 100644
index 0000000..74ea0cd
--- /dev/null
+++ b/SOURCES/glibc-rh731837-24.patch
@@ -0,0 +1,220 @@
+From 925c1856c2c73401df1bed739f2f3e89b62bee89 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 10:45:21 -0500
+Subject: [PATCH] PowerPC: multiarch llround/lround for PowerPC64
+
+commit c3627f6e965834c7998184a55653ca016b1ff663
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:01:54 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  3 +-
+ .../powerpc64/fpu/multiarch/s_llround-power5+.S    | 32 ++++++++++++
+ .../powerpc64/fpu/multiarch/s_llround-power6x.S    | 32 ++++++++++++
+ .../powerpc64/fpu/multiarch/s_llround-ppc64.S      | 28 ++++++++++
+ .../powerpc/powerpc64/fpu/multiarch/s_llround.c    | 60 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c |  1 +
+ 6 files changed, 155 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power6x.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c
+
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index b57ddc9..a4636b0 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -3,5 +3,6 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                   s_isnan-power5 s_isnan-ppc64
+ 
+ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+-                       s_isnan-power5 s_isnan-ppc64
++                       s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
++                       s_llround-power5+ s_llround-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power5+.S
+new file mode 100644
+index 0000000..ba0b65c
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power5+.S
+@@ -0,0 +1,32 @@
++/* llround().  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(name, alias)
++#undef strong_alias
++#define strong_alias(name, alias)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __llround __llround_power5plus
++#define __lround __lround_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_llround.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power6x.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power6x.S
+new file mode 100644
+index 0000000..bd1c22a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power6x.S
+@@ -0,0 +1,32 @@
++/* llround().  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(name, alias)
++#undef strong_alias
++#define strong_alias(name, alias)
++#undef compat_symbol
++#define compat_symbol(lib, name, alias, ver)
++
++#define __llround __llround_power6x
++#define __lround __lround_power6x
++
++#include <sysdeps/powerpc/powerpc64/power6x/fpu/s_llround.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-ppc64.S
+new file mode 100644
+index 0000000..2316da2
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-ppc64.S
+@@ -0,0 +1,28 @@
++/* llround().  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __llround __llround_ppc64
++#define __lround __lround_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_llround.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c
+new file mode 100644
+index 0000000..a4d1bf3
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c
+@@ -0,0 +1,60 @@
++/* Multiple versions of llround.
++   Copyright (C) 2013-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/>.  */
++
++#define lround __hidden_lround
++#define __lround __hidden___lround
++
++#include <math.h>
++#include <math_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__llround) __llround_ppc64 attribute_hidden;
++extern __typeof (__llround) __llround_power5plus attribute_hidden;
++extern __typeof (__llround) __llround_power6x attribute_hidden;
++
++libc_ifunc (__llround,
++	    (hwcap & PPC_FEATURE_POWER6_EXT)
++	    ? __llround_power6x :
++	      (hwcap & PPC_FEATURE_POWER5_PLUS)
++	      ? __llround_power5plus
++            : __llround_ppc64);
++
++weak_alias (__llround, llround)
++
++#ifdef NO_LONG_DOUBLE
++weak_alias (__llround, llroundl)
++strong_alias (__llround, __llroundl)
++#endif
++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
++compat_symbol (libm, __llround, llroundl, GLIBC_2_1);
++compat_symbol (libm, llround, lroundl, GLIBC_2_1);
++#endif
++
++/* long has the same width as long long on PPC64.  */
++#undef lround
++#undef __lround
++strong_alias (__llround, __lround)
++weak_alias (__llround, lround)
++#ifdef NO_LONG_DOUBLE
++strong_alias (__llround, __llroundl)
++weak_alias (__llround, llroundl)
++#endif
++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
++compat_symbol (libm, __lround, lroundl, GLIBC_2_1);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c
+new file mode 100644
+index 0000000..0dab544
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c
+@@ -0,0 +1 @@
++/* __lround is in s_llround.c  */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-25.patch b/SOURCES/glibc-rh731837-25.patch
new file mode 100644
index 0000000..6787234
--- /dev/null
+++ b/SOURCES/glibc-rh731837-25.patch
@@ -0,0 +1,261 @@
+From 071e47e7ff9e64db97d887d8fc12a3aa9433685b Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 10:48:41 -0500
+Subject: [PATCH] PowerPC: multiarch ceil/ceilf for PowerPC64
+
+commit 96770f12b081984f872c84c2b8067e8ed574c25a
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:02:32 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  3 +-
+ .../powerpc64/fpu/multiarch/s_ceil-power5+.S       | 31 +++++++++++++++++
+ .../powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S | 31 +++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c   | 40 ++++++++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_ceilf-power5+.S      | 26 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_ceilf-ppc64.S        | 26 ++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c  | 32 +++++++++++++++++
+ 7 files changed, 188 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c
+
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index a4636b0..9eb69af 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -4,5 +4,6 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+ 
+ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
+-                       s_llround-power5+ s_llround-ppc64
++                       s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \
++                       s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S
+new file mode 100644
+index 0000000..cc1316f
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S
+@@ -0,0 +1,31 @@
++/* ceil function.  PowerPC64/power5+ version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __ceil __ceil_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S
+new file mode 100644
+index 0000000..52e5a56
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S
+@@ -0,0 +1,31 @@
++/* ceil function.  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __ceil __ceil_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_ceil.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c
+new file mode 100644
+index 0000000..f53df5b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of ceil.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__ceil) __ceil_ppc64 attribute_hidden;
++extern __typeof (__ceil) __ceil_power5plus attribute_hidden;
++
++libc_ifunc (__ceil,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __ceil_power5plus
++            : __ceil_ppc64);
++
++weak_alias (__ceil, ceil)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__ceil, __ceill)
++weak_alias (__ceil, ceill)
++#endif
++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
++compat_symbol (libm, __ceil, ceill, GLIBC_2_0);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S
+new file mode 100644
+index 0000000..21261e2
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S
+@@ -0,0 +1,26 @@
++/* ceilf function.  PowerPC64/power5+ version.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __ceilf __ceilf_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S
+new file mode 100644
+index 0000000..8cd869b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S
+@@ -0,0 +1,26 @@
++/* ceilf function.  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __ceilf __ceilf_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_ceilf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c
+new file mode 100644
+index 0000000..d951990
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of ceilf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__ceilf) __ceilf_ppc64 attribute_hidden;
++extern __typeof (__ceilf) __ceilf_power5plus attribute_hidden;
++
++libc_ifunc (__ceilf,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __ceilf_power5plus
++            : __ceilf_ppc64);
++
++weak_alias (__ceilf, ceilf)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-26.patch b/SOURCES/glibc-rh731837-26.patch
new file mode 100644
index 0000000..222b6a7
--- /dev/null
+++ b/SOURCES/glibc-rh731837-26.patch
@@ -0,0 +1,263 @@
+From 02a611b03a24e6b67e3f683d05ea374443c7523d Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 10:49:57 -0500
+Subject: [PATCH] PowerPC: multiarch floor/floorf for PowerPC64
+
+commit 357fd3b40a59df16191df23439411c1342cc1ba5
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:04:04 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  4 ++-
+ .../powerpc64/fpu/multiarch/s_floor-power5+.S      | 31 +++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_floor-ppc64.S        | 31 +++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c  | 40 ++++++++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_floorf-power5+.S     | 26 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_floorf-ppc64.S       | 27 +++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c | 32 +++++++++++++++++
+ 7 files changed, 190 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c
+
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 9eb69af..d3d230d 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -5,5 +5,7 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
+                        s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \
+-                       s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64
++                       s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \
++                       s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \
++                       s_floorf-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-power5+.S
+new file mode 100644
+index 0000000..a1550e9
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-power5+.S
+@@ -0,0 +1,31 @@
++/* floor function.  PowerPC64/power5+ version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __floor __floor_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_floor.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-ppc64.S
+new file mode 100644
+index 0000000..b5c232c
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-ppc64.S
+@@ -0,0 +1,31 @@
++/* floor function.  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __floor __floor_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_floor.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c
+new file mode 100644
+index 0000000..f43976a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of floor.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__floor) __floor_ppc64 attribute_hidden;
++extern __typeof (__floor) __floor_power5plus attribute_hidden;
++
++libc_ifunc (__floor,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __floor_power5plus
++            : __floor_ppc64);
++
++weak_alias (__floor, floor)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__floor, __floorl)
++weak_alias (__floor, floorl)
++#endif
++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
++compat_symbol (libm, __floor, floorl, GLIBC_2_0);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-power5+.S
+new file mode 100644
+index 0000000..d371708
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-power5+.S
+@@ -0,0 +1,26 @@
++/* floorf function.  PowerPC64/power5+ version.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __floorf __floorf_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_floorf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-ppc64.S
+new file mode 100644
+index 0000000..dc81dea
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-ppc64.S
+@@ -0,0 +1,27 @@
++/* floorf function.  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __floorf __floorf_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_floorf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c
+new file mode 100644
+index 0000000..08fc95e
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of floorf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__floorf) __floorf_ppc64 attribute_hidden;
++extern __typeof (__floorf) __floorf_power5plus attribute_hidden;
++
++libc_ifunc (__floorf,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __floorf_power5plus
++            : __floorf_ppc64);
++
++weak_alias (__floorf, floorf)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-27.patch b/SOURCES/glibc-rh731837-27.patch
new file mode 100644
index 0000000..7f10e1d
--- /dev/null
+++ b/SOURCES/glibc-rh731837-27.patch
@@ -0,0 +1,261 @@
+From defecce61df9fb5579cefdc26201d2be12b8c72a Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 11:20:40 -0500
+Subject: [PATCH] PowerPC: multiarch round/roundf for PowerPC64
+
+commit 59a3e194f75c4845b15caa1ae16b0264f9c7cf0c
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:06:01 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  3 +-
+ .../powerpc64/fpu/multiarch/s_round-power5+.S      | 31 +++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_round-ppc64.S        | 31 +++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c  | 40 ++++++++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_roundf-power5+.S     | 26 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_roundf-ppc64.S       | 26 ++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c | 32 +++++++++++++++++
+ 7 files changed, 188 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c
+
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index d3d230d..303cd0f 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -7,5 +7,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \
+                        s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \
+                        s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \
+-                       s_floorf-ppc64
++                       s_floorf-ppc64 s_round-power5+ s_round-ppc64 \
++                       s_roundf-power5+ s_roundf-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-power5+.S
+new file mode 100644
+index 0000000..c2afb4f
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-power5+.S
+@@ -0,0 +1,31 @@
++/* round function.  PowerPC64/power5+ version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __round __round_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_round.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-ppc64.S
+new file mode 100644
+index 0000000..76c96b6
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-ppc64.S
+@@ -0,0 +1,31 @@
++/* round function.  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __round __round_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_round.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c
+new file mode 100644
+index 0000000..5818411
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of round.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__round) __round_ppc64 attribute_hidden;
++extern __typeof (__round) __round_power5plus attribute_hidden;
++
++libc_ifunc (__round,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __round_power5plus
++            : __round_ppc64);
++
++weak_alias (__round, round)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__round, __roundl)
++weak_alias (__round, roundl)
++#endif
++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
++compat_symbol (libm, __round, roundl, GLIBC_2_0);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-power5+.S
+new file mode 100644
+index 0000000..8fbef39
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-power5+.S
+@@ -0,0 +1,26 @@
++/* roundf function.  PowerPC64/power5+ version.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __roundf __roundf_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_roundf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-ppc64.S
+new file mode 100644
+index 0000000..bc51fdd
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-ppc64.S
+@@ -0,0 +1,26 @@
++/* roundf function.  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __roundf __roundf_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_roundf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c
+new file mode 100644
+index 0000000..34c5bc7
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of roundf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__roundf) __roundf_ppc64 attribute_hidden;
++extern __typeof (__roundf) __roundf_power5plus attribute_hidden;
++
++libc_ifunc (__roundf,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __roundf_power5plus
++            : __roundf_ppc64);
++
++weak_alias (__roundf, roundf)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-28.patch b/SOURCES/glibc-rh731837-28.patch
new file mode 100644
index 0000000..362fb16
--- /dev/null
+++ b/SOURCES/glibc-rh731837-28.patch
@@ -0,0 +1,261 @@
+From 01c7534c4410d709181c835351d26409f4fae2b2 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 11:21:38 -0500
+Subject: [PATCH] PowerPC: multiarch trunc/truncf for PowerPC64
+
+commit 1cb341fd782817ad98a0470aa84b2ab197d7de00
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:30:57 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  3 +-
+ .../powerpc64/fpu/multiarch/s_trunc-power5+.S      | 31 +++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_trunc-ppc64.S        | 31 +++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c  | 40 ++++++++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_truncf-power5+.S     | 26 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_truncf-ppc64.S       | 26 ++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c | 32 +++++++++++++++++
+ 7 files changed, 188 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-power5+.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c
+
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 303cd0f..4cdb383 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -8,5 +8,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \
+                        s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \
+                        s_floorf-ppc64 s_round-power5+ s_round-ppc64 \
+-                       s_roundf-power5+ s_roundf-ppc64
++                       s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \
++                       s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-power5+.S
+new file mode 100644
+index 0000000..ed22bcb
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-power5+.S
+@@ -0,0 +1,31 @@
++/* trunc function.  PowerPC64/power5+ version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __trunc __trunc_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_trunc.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-ppc64.S
+new file mode 100644
+index 0000000..75b531a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-ppc64.S
+@@ -0,0 +1,31 @@
++/* trunc function.  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __trunc __trunc_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_trunc.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c
+new file mode 100644
+index 0000000..4dc22a6
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c
+@@ -0,0 +1,40 @@
++/* Multiple versions of trunc.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__trunc) __trunc_ppc64 attribute_hidden;
++extern __typeof (__trunc) __trunc_power5plus attribute_hidden;
++
++libc_ifunc (__trunc,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __trunc_power5plus
++            : __trunc_ppc64);
++
++weak_alias (__trunc, trunc)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__trunc, __truncl)
++weak_alias (__trunc, truncl)
++#endif
++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
++compat_symbol (libm, __trunc, truncl, GLIBC_2_0);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-power5+.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-power5+.S
+new file mode 100644
+index 0000000..44d858e
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-power5+.S
+@@ -0,0 +1,26 @@
++/* truncf function.  PowerPC64/power5+ version.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __truncf __truncf_power5plus
++
++#include <sysdeps/powerpc/powerpc64/power5+/fpu/s_truncf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-ppc64.S
+new file mode 100644
+index 0000000..236797d
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-ppc64.S
+@@ -0,0 +1,26 @@
++/* truncf function.  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __truncf __truncf_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_truncf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c
+new file mode 100644
+index 0000000..0eef89f
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of truncf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__truncf) __truncf_ppc64 attribute_hidden;
++extern __typeof (__truncf) __truncf_power5plus attribute_hidden;
++
++libc_ifunc (__truncf,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __truncf_power5plus
++            : __truncf_ppc64);
++
++weak_alias (__truncf, truncf)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-29.patch b/SOURCES/glibc-rh731837-29.patch
new file mode 100644
index 0000000..0daa911
--- /dev/null
+++ b/SOURCES/glibc-rh731837-29.patch
@@ -0,0 +1,219 @@
+From 7560c8b2254c082f754f1e8fd390d4b50146dcdd Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 11:30:28 -0500
+Subject: [PATCH] PowerPC: multiarch copysign/copysignf for PowerPC64
+
+commit 2568f3fa69bbf70d0bea457cb7cbbf3bee45bfe5
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:32:58 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  6 ++-
+ .../powerpc64/fpu/multiarch/s_copysign-power6.S    | 33 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_copysign-ppc64.S     | 35 +++++++++++++++
+ .../powerpc/powerpc64/fpu/multiarch/s_copysign.c   | 51 ++++++++++++++++++++++
+ .../powerpc/powerpc64/fpu/multiarch/s_copysignf.c  | 32 ++++++++++++++
+ 5 files changed, 155 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-power6.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysignf.c
+
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 4cdb383..3af4ac3 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -1,6 +1,7 @@
+ ifeq ($(subdir),math)
+ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+-                  s_isnan-power5 s_isnan-ppc64
++                  s_isnan-power5 s_isnan-ppc64 s_copysign-power6 \
++                  s_copysign-ppc64
+ 
+ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
+@@ -9,5 +10,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \
+                        s_floorf-ppc64 s_round-power5+ s_round-ppc64 \
+                        s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \
+-                       s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64
++                       s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 \
++                       s_copysign-power6 s_copysign-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-power6.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-power6.S
+new file mode 100644
+index 0000000..4fa34a6
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-power6.S
+@@ -0,0 +1,33 @@
++/* copysign().  PowerPC64 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a, b, c, d)
++#undef hidden_def
++#define hidden_def(name)
++
++#define __copysign __copysign_power6
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_copysign.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-ppc64.S
+new file mode 100644
+index 0000000..a5cdfc2
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-ppc64.S
+@@ -0,0 +1,35 @@
++/* copysign().  PowerPC64 default version.
++   Copyright (C) 2010-2014 Free Software Foundation, Inc.
++   Contributed by Luis Machado <luisgpm@br.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>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a, b, c, d)
++
++#define __copysign __copysign_ppc64
++#undef hidden_def
++#define hidden_def(name)				\
++  strong_alias (__copysign_ppc64, __GI___copysign)
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_copysign.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c
+new file mode 100644
+index 0000000..f3e6b3a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c
+@@ -0,0 +1,51 @@
++/* Multiple versions of copysign.
++   Copyright (C) 2013-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/>.  */
++
++/* Redefine copysign so that the compiler won't complain about the type
++   mismatch with the IFUNC selector in strong_alias below.  */
++#undef __copysign
++#define __copysign __redirect_copysign
++#include <math.h>
++#include <math_ldbl_opt.h>
++#undef __copysign
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__redirect_copysign) __copysign_ppc64 attribute_hidden;
++extern __typeof (__redirect_copysign) __copysign_power6 attribute_hidden;
++
++extern __typeof (__redirect_copysign) __libm_copysign;
++libc_ifunc (__libm_copysign,
++	    (hwcap & PPC_FEATURE_ARCH_2_05)
++	    ? __copysign_power6
++            : __copysign_ppc64);
++
++strong_alias (__libm_copysign, __copysign)
++weak_alias (__copysign, copysign)
++
++#ifdef NO_LONG_DOUBLE
++weak_alias (__copysign,copysignl)
++strong_alias(__copysign,__copysignl)
++#endif
++#ifdef IS_IN_libm
++# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
++compat_symbol (libm, __copysign, copysignl, GLIBC_2_0);
++# endif
++#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
++compat_symbol (libc, __copysign, copysignl, GLIBC_2_0);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysignf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysignf.c
+new file mode 100644
+index 0000000..55cc272
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysignf.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of copysignf.
++   Copyright (C) 2013-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 <shlib-compat.h>
++#include "init-arch.h"
++
++/* It's safe to use double-precision implementation for single-precision. */
++extern __typeof (__copysignf) __copysign_ppc64 attribute_hidden;
++extern __typeof (__copysignf) __copysign_power6 attribute_hidden;
++
++libc_ifunc (__copysignf,
++	    (hwcap & PPC_FEATURE_ARCH_2_05)
++	    ? __copysign_power6
++            : __copysign_ppc64);
++
++weak_alias (__copysignf, copysignf)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-30.patch b/SOURCES/glibc-rh731837-30.patch
new file mode 100644
index 0000000..8fbb4bd
--- /dev/null
+++ b/SOURCES/glibc-rh731837-30.patch
@@ -0,0 +1,179 @@
+From b303432f970be8b430f7155fd40adcffb65390ef Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 11:31:40 -0500
+Subject: [PATCH] PowerPC: multiarch llrint/lrint for PowerPC64
+
+commit 5ccd5fc893ca027703d2d9747092ee25729223d9
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:33:54 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  3 +-
+ .../powerpc64/fpu/multiarch/s_llrint-power6x.S     | 31 ++++++++++++
+ .../powerpc64/fpu/multiarch/s_llrint-ppc64.S       | 31 ++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c | 57 ++++++++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c  |  1 +
+ 5 files changed, 122 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power6x.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-ppc64.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c
+
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 3af4ac3..10d0ac9 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -11,5 +11,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_floorf-ppc64 s_round-power5+ s_round-ppc64 \
+                        s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \
+                        s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 \
+-                       s_copysign-power6 s_copysign-ppc64
++                       s_copysign-power6 s_copysign-ppc64 s_llrint-power6x \
++                       s_llrint-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power6x.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power6x.S
+new file mode 100644
+index 0000000..8cd39c6
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power6x.S
+@@ -0,0 +1,31 @@
++/* Round double to long int.  PowerPC64/POWER6X default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __llrint __llrint_power6x
++
++#include <sysdeps/powerpc/powerpc64/power6x/fpu/s_llrint.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-ppc64.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-ppc64.S
+new file mode 100644
+index 0000000..754d28f
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-ppc64.S
+@@ -0,0 +1,31 @@
++/* Round double to long int.  PowerPC32 default version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __llrint __llrint_ppc64
++
++#include <sysdeps/powerpc/powerpc64/fpu/s_llrint.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c
+new file mode 100644
+index 0000000..5818b53
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c
+@@ -0,0 +1,57 @@
++/* Multiple versions of llrint.
++   Copyright (C) 2013-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/>.  */
++
++/* Redefine lrint/__lrint so that the compiler won't complain about the type
++   mismatch with the IFUNC selector in strong_alias below.  */
++#define lrint __hidden_lrint
++#define __lrint __hidden___lrint
++
++#include <math.h>
++#include <math_ldbl_opt.h>
++#undef lrint
++#undef __lrint
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__llrint) __llrint_ppc64 attribute_hidden;
++extern __typeof (__llrint) __llrint_power6x attribute_hidden;
++
++libc_ifunc (__llrint,
++	    (hwcap & PPC_FEATURE_POWER6_EXT)
++	    ? __llrint_power6x
++            : __llrint_ppc64);
++
++weak_alias (__llrint, llrint)
++#ifdef NO_LONG_DOUBLE
++strong_alias (__llrint, __llrintl)
++weak_alias (__llrint, llrintl)
++#endif
++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
++compat_symbol (libm, __llrint, llrintl, GLIBC_2_1);
++#endif
++
++/* long has the same width as long long on PowerPC64.  */
++strong_alias (__llrint, __lrint)
++weak_alias (__lrint, lrint)
++#ifdef NO_LONG_DOUBLE
++strong_alias (__lrint, __lrintl)
++weak_alias (__lrint, lrintl)
++#endif
++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
++compat_symbol (libm, __lrint, lrintl, GLIBC_2_1);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c
+new file mode 100644
+index 0000000..d092862
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c
+@@ -0,0 +1 @@
++ /* __lrint is in s_llrint.c  */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-31.patch b/SOURCES/glibc-rh731837-31.patch
new file mode 100644
index 0000000..f408bec
--- /dev/null
+++ b/SOURCES/glibc-rh731837-31.patch
@@ -0,0 +1,308 @@
+From e7197c1f8c4c30734723059c97b6e7a8f58fb171 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 11:33:51 -0500
+Subject: [PATCH] PowerPC: multiarch finite/finitef for PowerPC64
+
+commit 1481d7066c4ce697ada1f33c8c7f97b46ef685e3
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:34:52 2013 -0500
+
+Modified the following files apart from the original commit.
+sysdeps/ieee754/dbl-64/s_finite.c
+sysdeps/ieee754/flt-32/s_finitef.c
+---
+ sysdeps/ieee754/dbl-64/s_finite.c                  | 13 ++++--
+ sysdeps/ieee754/flt-32/s_finitef.c                 |  7 ++-
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  6 ++-
+ .../powerpc64/fpu/multiarch/s_finite-power7.S      | 33 ++++++++++++++
+ .../powerpc64/fpu/multiarch/s_finite-ppc64.c       | 34 +++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c | 51 ++++++++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_finitef-ppc64.c      | 32 ++++++++++++++
+ .../powerpc/powerpc64/fpu/multiarch/s_finitef.c    | 32 ++++++++++++++
+ 8 files changed, 201 insertions(+), 7 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+
+diff --git a/sysdeps/ieee754/dbl-64/s_finite.c b/sysdeps/ieee754/dbl-64/s_finite.c
+index 47dad5d..49986bb 100644
+--- a/sysdeps/ieee754/dbl-64/s_finite.c
++++ b/sysdeps/ieee754/dbl-64/s_finite.c
+@@ -23,11 +23,16 @@ static char rcsid[] = "$NetBSD: s_finite.c,v 1.8 1995/05/10 20:47:17 jtc Exp $";
+ #include <math_private.h>
+ 
+ #undef __finite
+-int __finite(double x)
++
++#ifndef FINITE
++# define FINITE __finite
++#endif
++
++int FINITE(double x)
+ {
+-	int32_t hx;
+-	GET_HIGH_WORD(hx,x);
+-	return (int)((u_int32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
++  int32_t hx;
++  GET_HIGH_WORD (hx, x);
++  return (int) ((u_int32_t) ((hx & 0x7fffffff) - 0x7ff00000) >> 31);
+ }
+ hidden_def (__finite)
+ weak_alias (__finite, finite)
+diff --git a/sysdeps/ieee754/flt-32/s_finitef.c b/sysdeps/ieee754/flt-32/s_finitef.c
+index dfdf4ad..4ea270a 100644
+--- a/sysdeps/ieee754/flt-32/s_finitef.c
++++ b/sysdeps/ieee754/flt-32/s_finitef.c
+@@ -26,7 +26,12 @@ static char rcsid[] = "$NetBSD: s_finitef.c,v 1.4 1995/05/10 20:47:18 jtc Exp $"
+ #include <math_private.h>
+ 
+ #undef __finitef
+-int __finitef(float x)
++
++#ifndef FINITEF
++# define FINITEF __finitef
++#endif
++
++int FINITEF(float x)
+ {
+ 	int32_t ix;
+ 	GET_FLOAT_WORD(ix,x);
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 10d0ac9..1c23ddc 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -1,7 +1,8 @@
+ ifeq ($(subdir),math)
+ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                   s_isnan-power5 s_isnan-ppc64 s_copysign-power6 \
+-                  s_copysign-ppc64
++                  s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \
++                  s_finitef-ppc64
+ 
+ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
+@@ -12,5 +13,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \
+                        s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 \
+                        s_copysign-power6 s_copysign-ppc64 s_llrint-power6x \
+-                       s_llrint-ppc64
++                       s_llrint-ppc64 s_finite-power7 s_finite-ppc64 \
++                       s_finitef-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power7.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power7.S
+new file mode 100644
+index 0000000..ac2244b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power7.S
+@@ -0,0 +1,33 @@
++/* isnan().  PowerPC64/POWER7 version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef hidden_def
++#define hidden_def(name)
++#undef weak_alias
++#define weak_alias(name, alias)
++#undef strong_alias
++#define strong_alias(name, alias)
++#undef compat_symbol
++#define compat_symbol(lib, name, symbol, ver)
++
++#define __finite __finite_power7
++
++#include <sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-ppc64.c
+new file mode 100644
+index 0000000..1922e2b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-ppc64.c
+@@ -0,0 +1,34 @@
++/* finite().  PowerPC64 default version.
++   Copyright (C) 2013-2014 Free Software Foundation, Inc.
++   Contributed by Luis Machado <luisgpm@br.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 <math.h>
++
++#undef weak_alias
++#define weak_alias(a, b)
++#undef strong_alias
++#define strong_alias(a, b)
++
++#define FINITE __finite_ppc64
++#ifdef SHARED
++# undef hidden_def
++# define hidden_def(a) \
++   __hidden_ver1 (__finite_ppc64, __GI___finite, __finite_ppc64);
++#endif
++
++#include <sysdeps/ieee754/dbl-64/s_finite.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+new file mode 100644
+index 0000000..f79a93e
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+@@ -0,0 +1,51 @@
++/* Multiple versions of finite.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__finite) __finite_ppc64 attribute_hidden;
++extern __typeof (__finite) __finite_power7 attribute_hidden;
++
++libc_ifunc (__finite,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __finite_power7
++            : __finite_ppc64);
++
++weak_alias (__finite, finite)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__finite, __finitel)
++weak_alias (__finite, finitel)
++#endif
++
++#ifdef IS_IN_libm
++# if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0)
++compat_symbol (libm, finite, finitel, GLIBC_2_0);
++# endif
++# if LONG_DOUBLE_COMPAT (libm, GLIBC_2_1)
++compat_symbol (libm, __finite, __finitel, GLIBC_2_1);
++# endif
++#else
++# if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0)
++compat_symbol (libc, __finite, __finitel, GLIBC_2_0);
++compat_symbol (libc, finite, finitel, GLIBC_2_0);
++# endif
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef-ppc64.c
+new file mode 100644
+index 0000000..63dd003
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef-ppc64.c
+@@ -0,0 +1,32 @@
++/* finitef().  PowerPC64 default version.
++   Copyright (C) 2013-2014 Free Software Foundation, Inc.
++   Contributed by Luis Machado <luisgpm@br.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 <math.h>
++
++#undef weak_alias
++#define weak_alias(a, b)
++
++#define FINITEF __finitef_ppc64
++#ifdef SHARED
++# undef hidden_def
++# define hidden_def(a) \
++   __hidden_ver1 (__finitef_ppc64, __GI___finitef, __finitef_ppc64);
++#endif
++
++#include <sysdeps/ieee754/flt-32/s_finitef.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+new file mode 100644
+index 0000000..a7243b5
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of finitef.
++   Copyright (C) 2013-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 <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__finitef) __finitef_ppc64 attribute_hidden;
++/* The double-precision version also works for single-precision.  */
++extern __typeof (__finitef) __finite_power7 attribute_hidden;
++
++libc_ifunc (__finitef,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __finite_power7
++            : __finitef_ppc64);
++
++weak_alias (__finitef, finitef)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-32.patch b/SOURCES/glibc-rh731837-32.patch
new file mode 100644
index 0000000..9cd2ce0
--- /dev/null
+++ b/SOURCES/glibc-rh731837-32.patch
@@ -0,0 +1,251 @@
+From 9c2d0f05544d22786bff9324fbd24e6bed8839c4 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 11:36:27 -0500
+Subject: [PATCH] PowerPC: multiarch isinf/isinff for PowerPC64
+
+commit 8fdad1237900e10b3b263b18bf6ca4c092e2c609
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:35:44 2013 -0500
+---
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  6 ++-
+ .../powerpc64/fpu/multiarch/s_isinf-power7.S       | 33 ++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_isinf-ppc64.c        | 33 ++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c  | 44 ++++++++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_isinff-ppc64.c       | 31 +++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c | 33 ++++++++++++++++
+ 6 files changed, 178 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power7.S
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 1c23ddc..64dd85f 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -2,7 +2,8 @@ ifeq ($(subdir),math)
+ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                   s_isnan-power5 s_isnan-ppc64 s_copysign-power6 \
+                   s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \
+-                  s_finitef-ppc64
++                  s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \
++                  s_isinf-ppc64
+ 
+ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
+@@ -14,5 +15,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 \
+                        s_copysign-power6 s_copysign-ppc64 s_llrint-power6x \
+                        s_llrint-ppc64 s_finite-power7 s_finite-ppc64 \
+-                       s_finitef-ppc64
++                       s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \
++                       s_isinf-ppc64
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power7.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power7.S
+new file mode 100644
+index 0000000..80a682a
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power7.S
+@@ -0,0 +1,33 @@
++/* isinf().  PowerPC64/POWER7 version.
++   Copyright (C) 2013-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 <sysdep.h>
++#include <math_ldbl_opt.h>
++
++#undef hidden_def
++#define hidden_def(name)
++#undef weak_alias
++#define weak_alias(name, alias)
++#undef strong_alias
++#define strong_alias(name, alias)
++#undef compat_symbol
++#define compat_symbol(lib, name, alias, ver)
++
++#define __isinf __isinf_power7
++
++#include <sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-ppc64.c
+new file mode 100644
+index 0000000..28c5602
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-ppc64.c
+@@ -0,0 +1,33 @@
++/* isinf().  PowerPC64 default version.
++   Copyright (C) 2013-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>
++
++#undef weak_alias
++#define weak_alias(a, b)
++#undef strong_alias
++#define strong_alias(a, b)
++
++#define __isinf __isinf_ppc64
++#ifdef SHARED
++# undef hidden_def
++# define hidden_def(a) \
++   __hidden_ver1 (__isinf_ppc64, __GI___isinf, __isinf_ppc64);
++#endif
++
++#include <sysdeps/ieee754/dbl-64/s_isinf.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+new file mode 100644
+index 0000000..1ee230b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+@@ -0,0 +1,44 @@
++/* Multiple versions of isinf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
++extern __typeof (__isinf) __isinf_power7 attribute_hidden;
++
++libc_ifunc (__isinf,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __isinf_power7
++            : __isinf_ppc64);
++
++weak_alias (__isinf, isinf)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__isinf, __isinfl)
++weak_alias (__isinf, isinfl)
++#endif
++
++#ifndef IS_IN_libm
++# if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0)
++compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0);
++compat_symbol (libc, isinf, isinfl, GLIBC_2_0);
++# endif
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff-ppc64.c
+new file mode 100644
+index 0000000..c2559d7
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff-ppc64.c
+@@ -0,0 +1,31 @@
++/* isinff().  PowerPC64 default version.
++   Copyright (C) 2013-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>
++
++#undef weak_alias
++#define weak_alias(a, b)
++
++#define __isinff __isinff_ppc64
++#ifdef SHARED
++# undef hidden_def
++# define hidden_def(a) \
++   __hidden_ver1 (__isinff_ppc64, __GI___isinff, __isinff_ppc64);
++#endif
++
++#include <sysdeps/ieee754/flt-32/s_isinff.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+new file mode 100644
+index 0000000..1336feb
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+@@ -0,0 +1,33 @@
++/* Multiple versions of isinf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__isinff) __isinff_ppc64 attribute_hidden;
++/* The double-precision version also works for single-precision.  */
++extern __typeof (__isinff) __isinf_power7 attribute_hidden;
++
++libc_ifunc (__isinff,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __isinf_power7
++            : __isinff_ppc64);
++
++weak_alias (__isinff, isinff)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-33.patch b/SOURCES/glibc-rh731837-33.patch
new file mode 100644
index 0000000..169c5fd
--- /dev/null
+++ b/SOURCES/glibc-rh731837-33.patch
@@ -0,0 +1,698 @@
+From fa809e97912e4bb6faafa74c15a86588c05e89bc Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 12:04:31 -0500
+Subject: [PATCH] PowerPC: multiarch logb/logbl/logbf for PowerPC64
+
+commit 43e246d2a6a75710fbe3d3f3db23db3aeb8a9f93
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:36:33 2013 -0500
+
+Added the following file apart from the original commit.
+sysdeps/powerpc/power7/fpu/s_logb.c
+sysdeps/powerpc/power7/fpu/s_logbf.c
+sysdeps/powerpc/power7/fpu/s_logbl.c
+sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c
+sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c
+sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c
+
+---
+ sysdeps/ieee754/ldbl-128ibm/s_logbl.c              |  2 +
+ sysdeps/powerpc/power7/fpu/s_logb.c                | 78 ++++++++++++++++++++++
+ sysdeps/powerpc/power7/fpu/s_logbf.c               | 60 +++++++++++++++++
+ sysdeps/powerpc/power7/fpu/s_logbl.c               | 72 ++++++++++++++++++++
+ .../powerpc32/power4/fpu/multiarch/s_logb-power7.c | 31 +++++++++
+ .../power4/fpu/multiarch/s_logbf-power7.c          | 26 ++++++++
+ .../power4/fpu/multiarch/s_logbl-power7.c          | 21 ++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  8 ++-
+ .../powerpc64/fpu/multiarch/s_logb-power7.c        | 19 ++++++
+ .../powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c | 28 ++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c   | 41 ++++++++++++
+ .../powerpc64/fpu/multiarch/s_logbf-power7.c       | 19 ++++++
+ .../powerpc64/fpu/multiarch/s_logbf-ppc64.c        | 26 ++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c  | 32 +++++++++
+ .../powerpc64/fpu/multiarch/s_logbl-power7.c       | 19 ++++++
+ .../powerpc64/fpu/multiarch/s_logbl-ppc64.c        | 21 ++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c  | 32 +++++++++
+ 17 files changed, 534 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/power7/fpu/s_logb.c
+ create mode 100644 sysdeps/powerpc/power7/fpu/s_logbf.c
+ create mode 100644 sysdeps/powerpc/power7/fpu/s_logbl.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c
+
+diff --git a/sysdeps/ieee754/ldbl-128ibm/s_logbl.c b/sysdeps/ieee754/ldbl-128ibm/s_logbl.c
+index 6cbfcfa..28a50de 100644
+--- a/sysdeps/ieee754/ldbl-128ibm/s_logbl.c
++++ b/sysdeps/ieee754/ldbl-128ibm/s_logbl.c
+@@ -44,4 +44,6 @@ __logbl (long double x)
+   return (long double) (rhx - 1023);
+ }
+ 
++#ifndef __logbl
+ long_double_symbol (libm, __logbl, logbl);
++#endif
+diff --git a/sysdeps/powerpc/power7/fpu/s_logb.c b/sysdeps/powerpc/power7/fpu/s_logb.c
+new file mode 100644
+index 0000000..87176c3
+--- /dev/null
++++ b/sysdeps/powerpc/power7/fpu/s_logb.c
+@@ -0,0 +1,78 @@
++/* logb(). PowerPC/POWER7 version.
++   Copyright (C) 2012 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_ldbl_opt.h>
++
++/* This implementation avoids FP to INT conversions by using VSX
++   bitwise instructions over FP values.  */
++
++static const double two1div52 = 2.220446049250313e-16;	/* 1/2**52  */
++static const double two10m1   = -1023.0;		/* 2**10 -1  */
++
++/* FP mask to extract the exponent.  */
++static const union {
++  unsigned long long mask;
++  double d;
++} mask = { 0x7ff0000000000000ULL };
++
++double
++__logb (double x)
++{
++  double ret;
++
++  if (__builtin_expect (x == 0.0, 0))
++    /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF].  */
++    return -1.0 / __builtin_fabs (x);
++
++  /* ret = x & 0x7ff0000000000000;  */
++  asm (
++    "xxland %x0,%x1,%x2\n"
++    "fcfid  %0,%0"
++    : "=f" (ret)
++    : "f" (x), "f" (mask.d));
++  /* ret = (ret >> 52) - 1023.0;  */
++  ret = (ret * two1div52) + two10m1;
++  if (__builtin_expect (ret > -two10m1, 0))
++    /* Multiplication is used to set logb (+-INF) = INF.  */
++    return (x * x);
++  else if (__builtin_expect (ret == two10m1, 0))
++    {
++      /* POSIX specifies that denormal numbers are treated as
++         though they were normalized.  */
++      int32_t lx, ix;
++      int ma;
++
++      EXTRACT_WORDS (ix, lx, x);
++      if (ix == 0)
++	ma = __builtin_clz (lx) + 32;
++      else
++	ma = __builtin_clz (ix);
++      return (double) (-1023 - (ma - 12));
++    }
++  /* Test to avoid logb_downward (0.0) == -0.0.  */
++  return ret == -0.0 ? 0.0 : ret;
++}
++weak_alias (__logb, logb)
++#ifdef NO_LONG_DOUBLE
++strong_alias (__logb, __logbl)
++weak_alias (__logb, logbl)
++#endif
++
++#if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0)
++compat_symbol (libm, logb, logbl, GLIBC_2_0);
++#endif
+diff --git a/sysdeps/powerpc/power7/fpu/s_logbf.c b/sysdeps/powerpc/power7/fpu/s_logbf.c
+new file mode 100644
+index 0000000..aa8499a
+--- /dev/null
++++ b/sysdeps/powerpc/power7/fpu/s_logbf.c
+@@ -0,0 +1,60 @@
++/* logbf(). PowerPC/POWER7 version.
++   Copyright (C) 2012 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_private.h"
++
++/* This implementation avoids FP to INT conversions by using VSX
++   bitwise instructions over FP values.  */
++
++static const double two1div52 = 2.220446049250313e-16;	/* 1/2**52  */
++static const double two10m1   = -1023.0;		/* -2**10 + 1  */
++static const double two7m1    = -127.0;			/* -2**7 + 1  */
++
++/* FP mask to extract the exponent.  */
++static const union {
++  unsigned long long mask;
++  double d;
++} mask = { 0x7ff0000000000000ULL };
++
++float
++__logbf (float x)
++{
++  /* VSX operation are all done internally as double.  */
++  double ret;
++
++  if (__builtin_expect (x == 0.0, 0))
++    /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF].  */
++    return -1.0 / __builtin_fabsf (x);
++
++  /* ret = x & 0x7f800000;  */
++  asm (
++    "xxland %x0,%x1,%x2\n"
++    "fcfid  %0,%0"
++    : "=f"(ret)
++    : "f" (x), "f" (mask.d));
++  /* ret = (ret >> 52) - 1023.0, since ret is double.  */
++  ret = (ret * two1div52) + two10m1;
++  if (__builtin_expect (ret > -two7m1, 0))
++    /* Multiplication is used to set logb (+-INF) = INF.  */
++    return (x * x);
++  /* Since operations are done with double we don't need
++     additional tests for subnormal numbers.
++     The test is to avoid logb_downward (0.0) == -0.0.  */
++  return ret == -0.0 ? 0.0 : ret;
++}
++weak_alias (__logbf, logbf)
+diff --git a/sysdeps/powerpc/power7/fpu/s_logbl.c b/sysdeps/powerpc/power7/fpu/s_logbl.c
+new file mode 100644
+index 0000000..e1ec089
+--- /dev/null
++++ b/sysdeps/powerpc/power7/fpu/s_logbl.c
+@@ -0,0 +1,72 @@
++/* logbl(). PowerPC/POWER7 version.
++   Copyright (C) 2012 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>
++#include <math_ldbl_opt.h>
++
++/* This implementation avoids FP to INT conversions by using VSX
++   bitwise instructions over FP values.  */
++
++static const double two1div52 = 2.220446049250313e-16;	/* 1/2**52  */
++static const double two10m1   = -1023.0;		/* 2**10 -1  */
++
++/* FP mask to extract the exponent.  */
++static const union {
++  unsigned long long mask;
++  double d;
++} mask = { 0x7ff0000000000000ULL };
++
++long double
++__logbl (long double x)
++{
++  double xh, xl;
++  double ret;
++
++  if (__builtin_expect (x == 0.0L, 0))
++    /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF].  */
++    return -1.0L / __builtin_fabsl (x);
++
++  ldbl_unpack (x, &xh, &xl);
++  /* ret = x & 0x7ff0000000000000;  */
++  asm (
++    "xxland %x0,%x1,%x2\n"
++    "fcfid  %0,%0"
++    : "=f" (ret)
++    : "f" (xh), "f" (mask.d));
++  /* ret = (ret >> 52) - 1023.0;  */
++  ret = (ret * two1div52) + two10m1;
++  if (__builtin_expect (ret > -two10m1, 0))
++    /* Multiplication is used to set logb (+-INF) = INF.  */
++    return (xh * xh);
++  else if (__builtin_expect (ret == two10m1, 0))
++    {
++      /* POSIX specifies that denormal number is treated as
++         though it were normalized.  */
++      int64_t lx, hx;
++
++      GET_LDOUBLE_WORDS64 (hx, lx, x);
++      return (long double) (-1023 - (__builtin_clzll (hx) - 12));
++    }
++  /* Test to avoid logb_downward (0.0) == -0.0.  */
++  return ret == -0.0 ? 0.0 : ret;
++}
++
++#ifndef __logbl
++long_double_symbol (libm, __logbl, logbl);
++#endif
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c
+new file mode 100644
+index 0000000..3280566
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c
+@@ -0,0 +1,31 @@
++/* logb(). PowerPC32/POWER7 version.
++   Copyright (C) 2013-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_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a, b)
++#undef strong_alias
++#define strong_alias(a, b)
++#undef compat_symbol
++#define compat_symbol(lib, name, alias, ver)
++
++#define __logb __logb_power7
++
++#include <sysdeps/powerpc/power7/fpu/s_logb.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c
+new file mode 100644
+index 0000000..6531af0
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c
+@@ -0,0 +1,26 @@
++/* logbf(). PowerPC32/POWER7 version.
++   Copyright (C) 2013-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>
++
++#undef weak_alias
++#define weak_alias(a, b)
++
++#define __logbf __logbf_power7
++
++#include <sysdeps/powerpc/power7/fpu/s_logbf.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c
+new file mode 100644
+index 0000000..7c5ad47
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c
+@@ -0,0 +1,21 @@
++/* logbl(). PowerPC32/POWER7 version.
++   Copyright (C) 2013-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/>.  */
++
++#define __logbl __logbl_power7
++
++#include <sysdeps/powerpc/power7/fpu/s_logbl.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 64dd85f..87aabca 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -16,5 +16,11 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_copysign-power6 s_copysign-ppc64 s_llrint-power6x \
+                        s_llrint-ppc64 s_finite-power7 s_finite-ppc64 \
+                        s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \
+-                       s_isinf-ppc64
++                       s_isinf-ppc64 s_logb-power7 s_logbf-power7 \
++                       s_logbl-power7 s_logb-ppc64 s_logbf-ppc64 \
++                       s_logbl-ppc64
++
++CFLAGS-s_logbf-power7.c = -mcpu=power7
++CFLAGS-s_logbl-power7.c = -mcpu=power7
++CFLAGS-s_logb-power7.c = -mcpu=power7
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-power7.c
+new file mode 100644
+index 0000000..049f2c1
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-power7.c
+@@ -0,0 +1,19 @@
++/* logb().  PowerPC64/POWER7 version.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c
+new file mode 100644
+index 0000000..41d1d9b
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c
+@@ -0,0 +1,28 @@
++/* logb(). PowerPC32/POWER7 version.
++   Copyright (C) 2013-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>
++
++#undef weak_alias
++#define weak_alias(a, b)
++#undef strong_alias
++#define strong_alias(a, b)
++
++#define __logb __logb_ppc64
++
++#include <sysdeps/ieee754/dbl-64/s_logb.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c
+new file mode 100644
+index 0000000..e14efa7
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c
+@@ -0,0 +1,41 @@
++/* Multiple versions of logb.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__logb) __logb_ppc64 attribute_hidden;
++extern __typeof (__logb) __logb_power7 attribute_hidden;
++
++libc_ifunc (__logb,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __logb_power7
++            : __logb_ppc64);
++
++weak_alias (__logb, logb)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__logb, __logbl)
++weak_alias (__logb, logbl)
++#endif
++
++#if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0)
++compat_symbol (libm, logb, logbl, GLIBC_2_0);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-power7.c
+new file mode 100644
+index 0000000..5e4e4fc
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-power7.c
+@@ -0,0 +1,19 @@
++/* logb().  PowerPC64/POWER7 version.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-ppc64.c
+new file mode 100644
+index 0000000..08674a6
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-ppc64.c
+@@ -0,0 +1,26 @@
++/* logbf().  PowerPC64 default implementation.
++   Copyright (C) 2013-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>
++
++#undef weak_alias
++#define weak_alias(a, b)
++
++#define __logbf __logbf_ppc64
++
++#include <sysdeps/ieee754/flt-32/s_logbf.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c
+new file mode 100644
+index 0000000..01f9ecb
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of logbf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__logbf) __logbf_ppc64 attribute_hidden;
++extern __typeof (__logbf) __logbf_power7 attribute_hidden;
++
++libc_ifunc (__logbf,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __logbf_power7
++            : __logbf_ppc64);
++
++weak_alias (__logbf, logbf)
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-power7.c
+new file mode 100644
+index 0000000..258d502
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-power7.c
+@@ -0,0 +1,19 @@
++/* logb().  PowerPC64/POWER7 version.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-ppc64.c
+new file mode 100644
+index 0000000..47d4153
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-ppc64.c
+@@ -0,0 +1,21 @@
++/* logbl(). PowerPC64/POWER7 version.
++   Copyright (C) 2012-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/>.  */
++
++#define __logbl __logbl_ppc64
++
++#include <sysdeps/ieee754/ldbl-128ibm/s_logbl.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c
+new file mode 100644
+index 0000000..cb0b0c5
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of logbl.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__logbl) __logbl_ppc64 attribute_hidden;
++extern __typeof (__logbl) __logbl_power7 attribute_hidden;
++
++libc_ifunc (__logbl,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __logbl_power7
++            : __logbl_ppc64);
++
++long_double_symbol (libm, __logbl, logbl);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-33A.patch b/SOURCES/glibc-rh731837-33A.patch
new file mode 100644
index 0000000..5856b9f
--- /dev/null
+++ b/SOURCES/glibc-rh731837-33A.patch
@@ -0,0 +1,44 @@
+--- ./sysdeps/powerpc/power7/fpu/s_logbl.c	2014-09-10 20:52:01.813168232 -0400
++++ /home/carlos/src/glibc/./sysdeps/powerpc/power7/fpu/s_logbl.c	2014-01-02 13:16:41.441557403 -0500
+@@ -1,5 +1,5 @@
+ /* logbl(). PowerPC/POWER7 version.
+-   Copyright (C) 2012 Free Software Foundation, Inc.
++   Copyright (C) 2012-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
+@@ -35,14 +35,14 @@
+ long double
+ __logbl (long double x)
+ {
+-  double xh, xl;
++  double xh;
+   double ret;
+ 
+   if (__builtin_expect (x == 0.0L, 0))
+     /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF].  */
+     return -1.0L / __builtin_fabsl (x);
+ 
+-  ldbl_unpack (x, &xh, &xl);
++  xh = ldbl_high (x);
+   /* ret = x & 0x7ff0000000000000;  */
+   asm (
+     "xxland %x0,%x1,%x2\n"
+@@ -58,15 +58,14 @@
+     {
+       /* POSIX specifies that denormal number is treated as
+          though it were normalized.  */
+-      int64_t lx, hx;
++      int64_t hx;
+ 
+-      GET_LDOUBLE_WORDS64 (hx, lx, x);
++      EXTRACT_WORDS64 (hx, xh);
+       return (long double) (-1023 - (__builtin_clzll (hx) - 12));
+     }
+   /* Test to avoid logb_downward (0.0) == -0.0.  */
+   return ret == -0.0 ? 0.0 : ret;
+ }
+-
+ #ifndef __logbl
+ long_double_symbol (libm, __logbl, logbl);
+ #endif
diff --git a/SOURCES/glibc-rh731837-34.patch b/SOURCES/glibc-rh731837-34.patch
new file mode 100644
index 0000000..49a7aa4
--- /dev/null
+++ b/SOURCES/glibc-rh731837-34.patch
@@ -0,0 +1,336 @@
+From 9b608ba89342c722baadb89d221894ca270d4a02 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 12:09:18 -0500
+Subject: [PATCH] PowerPC: multiarch modf/modff for PowerPC64
+
+commit 83efded42445e9684173b09a6244109d058ed2bd
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:37:23 2013 -0500
+
+Added the following files apart from the original commit.
+sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c
+sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c
+---
+ .../power4/fpu/multiarch/s_modf-power5+.c          | 31 +++++++++++++++
+ .../power4/fpu/multiarch/s_modff-power5+.c         | 27 +++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  8 +++-
+ .../powerpc64/fpu/multiarch/s_modf-power5+.c       | 19 ++++++++++
+ .../powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c | 29 ++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c   | 44 ++++++++++++++++++++++
+ .../powerpc64/fpu/multiarch/s_modff-power5+.c      | 19 ++++++++++
+ .../powerpc64/fpu/multiarch/s_modff-ppc64.c        | 26 +++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c  | 30 +++++++++++++++
+ 9 files changed, 231 insertions(+), 2 deletions(-)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-power5+.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-power5+.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c
+
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c
+new file mode 100644
+index 0000000..d7ad0b7
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c
+@@ -0,0 +1,31 @@
++/* PowerPC/POWER5+ implementation for modf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++#undef compat_symbol
++#define compat_symbol(a,b,c,d)
++
++#define __modf __modf_power5plus
++
++#include <sysdeps/powerpc/power5+/fpu/s_modf.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c
+new file mode 100644
+index 0000000..4021b52
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c
+@@ -0,0 +1,27 @@
++/* PowerPC/POWER5+ implementation for modff.
++   Copyright (C) 2013-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_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __modff __modff_power5plus
++
++#include <sysdeps/powerpc/power5+/fpu/s_modff.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index 87aabca..e152bf5 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -3,7 +3,8 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                   s_isnan-power5 s_isnan-ppc64 s_copysign-power6 \
+                   s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \
+                   s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \
+-                  s_isinf-ppc64
++                  s_isinf-ppc64 s_modf-power5+ s_modf-ppc64 \
++                  s_modff-power5+ s_modff-ppc64
+ 
+ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
+@@ -18,9 +19,12 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \
+                        s_isinf-ppc64 s_logb-power7 s_logbf-power7 \
+                        s_logbl-power7 s_logb-ppc64 s_logbf-ppc64 \
+-                       s_logbl-ppc64
++                       s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \
++                       s_modff-power5+ s_modff-ppc64
+ 
+ CFLAGS-s_logbf-power7.c = -mcpu=power7
+ CFLAGS-s_logbl-power7.c = -mcpu=power7
+ CFLAGS-s_logb-power7.c = -mcpu=power7
++CFLAGS-s_modf-power5+.c = -mcpu=power5+
++CFLAGS-s_modff-power5+.c = -mcpu=power5+
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-power5+.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-power5+.c
+new file mode 100644
+index 0000000..bda9920
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-power5+.c
+@@ -0,0 +1,19 @@
++/* PowerPC/POWER5+ implementation for modf.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c
+new file mode 100644
+index 0000000..90e7599
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c
+@@ -0,0 +1,29 @@
++/* PowerPC64 default implementation for modf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++
++#undef weak_alias
++#define weak_alias(a,b)
++#undef strong_alias
++#define strong_alias(a,b)
++
++#define __modf __modf_ppc64
++
++#include <sysdeps/ieee754/dbl-64/s_modf.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c
+new file mode 100644
+index 0000000..f416fa9
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c
+@@ -0,0 +1,44 @@
++/* Multiple versions of modf.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__modf) __modf_ppc64 attribute_hidden;
++extern __typeof (__modf) __modf_power5plus attribute_hidden;
++
++libc_ifunc (__modf,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __modf_power5plus
++            : __modf_ppc64);
++
++weak_alias (__modf, modf)
++
++#ifdef NO_LONG_DOUBLE
++strong_alias (__modf, __modfl)
++weak_alias (__modf, modfl)
++#endif
++#ifdef IS_IN_libm
++# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
++compat_symbol (libm, __modf, modfl, GLIBC_2_0);
++# endif
++#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
++compat_symbol (libc, __modf, modfl, GLIBC_2_0);
++#endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-power5+.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-power5+.c
+new file mode 100644
+index 0000000..70a536d
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-power5+.c
+@@ -0,0 +1,19 @@
++/* PowerPC/POWER5+ implementation for modff.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-ppc64.c
+new file mode 100644
+index 0000000..89d8f63
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-ppc64.c
+@@ -0,0 +1,26 @@
++/* PowerPC64 default implementation for modff.
++   Copyright (C) 2013-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>
++
++#undef weak_alias
++#define weak_alias(a,b)
++
++#define __modff __modff_ppc64
++
++#include <sysdeps/ieee754/flt-32/s_modff.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c
+new file mode 100644
+index 0000000..137b7aa
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c
+@@ -0,0 +1,30 @@
++/* Multiple versions of modff.
++   Copyright (C) 2013-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 "init-arch.h"
++
++extern __typeof (__modff) __modff_ppc64 attribute_hidden;
++extern __typeof (__modff) __modff_power5plus attribute_hidden;
++
++libc_ifunc (__modff,
++	    (hwcap & PPC_FEATURE_POWER5_PLUS)
++	    ? __modff_power5plus
++            : __modff_ppc64);
++
++weak_alias (__modff, modff)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-35.patch b/SOURCES/glibc-rh731837-35.patch
new file mode 100644
index 0000000..f79df4a
--- /dev/null
+++ b/SOURCES/glibc-rh731837-35.patch
@@ -0,0 +1,309 @@
+From b5910d4c4976f9e1eb6c96d45dc2b7c04f5f3039 Mon Sep 17 00:00:00 2001
+From: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+Date: Wed, 30 Jul 2014 12:11:18 -0500
+Subject: [PATCH] PowerPC: multiarch hypot/hypotf for PowerPC64
+
+commit 42fcb46ce6dae3a9a55176b4c82e5f07a41ca536
+Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+Date:   Fri Dec 13 15:38:01 2013 -0500
+
+Added the following files apart from the original commit.
+sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c
+sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c
+---
+ .../power4/fpu/multiarch/e_hypot-power7.c          | 26 ++++++++++++++++++
+ .../power4/fpu/multiarch/e_hypotf-power7.c         | 26 ++++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |  5 +++-
+ .../powerpc64/fpu/multiarch/e_hypot-power7.c       | 19 +++++++++++++
+ .../powerpc64/fpu/multiarch/e_hypot-ppc64.c        | 26 ++++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c  | 32 ++++++++++++++++++++++
+ .../powerpc64/fpu/multiarch/e_hypotf-power7.c      | 19 +++++++++++++
+ .../powerpc64/fpu/multiarch/e_hypotf-ppc64.c       | 26 ++++++++++++++++++
+ sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c | 32 ++++++++++++++++++++++
+ 9 files changed, 210 insertions(+), 1 deletion(-)
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-power7.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-ppc64.c
+ create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c
+
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c
+new file mode 100644
+index 0000000..967b923
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c
+@@ -0,0 +1,26 @@
++/* __ieee_hypot() POWER7 version.
++   Copyright (C) 2013-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>
++
++#undef strong_alias
++#define strong_alias(a, b)
++
++#define __ieee754_hypot __ieee754_hypot_power7
++
++#include <sysdeps/powerpc/fpu/e_hypot.c>
+diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c
+new file mode 100644
+index 0000000..d1da9f2
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c
+@@ -0,0 +1,26 @@
++/* __ieee754_hypot POWER7 version.
++   Copyright (C) 2013-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>
++
++#undef strong_alias
++#define strong_alias(a, b)
++
++#define __ieee754_hypotf __ieee754_hypotf_power7
++
++#include <sysdeps/powerpc/fpu/e_hypotf.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+index e152bf5..1e04f21 100644
+--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+@@ -20,11 +20,14 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
+                        s_isinf-ppc64 s_logb-power7 s_logbf-power7 \
+                        s_logbl-power7 s_logb-ppc64 s_logbf-ppc64 \
+                        s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \
+-                       s_modff-power5+ s_modff-ppc64
++                       s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \
++                       e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7
+ 
+ CFLAGS-s_logbf-power7.c = -mcpu=power7
+ CFLAGS-s_logbl-power7.c = -mcpu=power7
+ CFLAGS-s_logb-power7.c = -mcpu=power7
+ CFLAGS-s_modf-power5+.c = -mcpu=power5+
+ CFLAGS-s_modff-power5+.c = -mcpu=power5+
++CFLAGS-e_hypot-power7.c = -mcpu=power7
++CFLAGS-e_hypotf-power7.c = -mcpu=power7
+ endif
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-power7.c
+new file mode 100644
+index 0000000..b153753
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-power7.c
+@@ -0,0 +1,19 @@
++/* __ieee_hypot() POWER7 version.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-ppc64.c
+new file mode 100644
+index 0000000..c418ae7
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-ppc64.c
+@@ -0,0 +1,26 @@
++/* __ieee_hypot() PowerPC64 version.
++   Copyright (C) 2013-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>
++
++#undef strong_alias
++#define strong_alias(a, b)
++
++#define __ieee754_hypot __ieee754_hypot_ppc64
++
++#include <sysdeps/powerpc/fpu/e_hypot.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c
+new file mode 100644
+index 0000000..941b293
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of ieee754_hypot.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__ieee754_hypot) __ieee754_hypot_ppc64 attribute_hidden;
++extern __typeof (__ieee754_hypot) __ieee754_hypot_power7 attribute_hidden;
++
++libc_ifunc (__ieee754_hypot,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __ieee754_hypot_power7
++            : __ieee754_hypot_ppc64);
++
++strong_alias (__ieee754_hypot, __hypot_finite)
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-power7.c
+new file mode 100644
+index 0000000..2d67ee9
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-power7.c
+@@ -0,0 +1,19 @@
++/* __ieee_hypotf() POWER7 version.
++   Copyright (C) 2013-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 <sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-ppc64.c
+new file mode 100644
+index 0000000..8335e19
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-ppc64.c
+@@ -0,0 +1,26 @@
++/* __ieee_hypot() PowerPC64 version.
++   Copyright (C) 2013-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>
++
++#undef strong_alias
++#define strong_alias(a, b)
++
++#define __ieee754_hypotf __ieee754_hypotf_ppc64
++
++#include <sysdeps/powerpc/fpu/e_hypotf.c>
+diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c
+new file mode 100644
+index 0000000..3c418d3
+--- /dev/null
++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c
+@@ -0,0 +1,32 @@
++/* Multiple versions of ieee754_hypot.
++   Copyright (C) 2013-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_ldbl_opt.h>
++#include <shlib-compat.h>
++#include "init-arch.h"
++
++extern __typeof (__ieee754_hypotf) __ieee754_hypotf_ppc64 attribute_hidden;
++extern __typeof (__ieee754_hypotf) __ieee754_hypotf_power7 attribute_hidden;
++
++libc_ifunc (__ieee754_hypotf,
++	    (hwcap & PPC_FEATURE_ARCH_2_06)
++	    ? __ieee754_hypotf_power7
++            : __ieee754_hypotf_ppc64);
++
++strong_alias (__ieee754_hypotf, __hypotf_finite)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/glibc-rh731837-36.patch b/SOURCES/glibc-rh731837-36.patch
new file mode 100644
index 0000000..e691145
--- /dev/null
+++ b/SOURCES/glibc-rh731837-36.patch
@@ -0,0 +1,382 @@
+#
+# Add all of the LOCALENTRY points for all of the functions.
+# This is required for LE to materialize the TOC.
+#
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S
+index b1b4ec7..4a8d459 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__memchr_power7)					\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__memchr_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memchr_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S
+index 12db42c..9903276 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memcmp_power4):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memcmp_power4)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S
+index 4898a88..ee31ca6 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memcmp_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memcmp_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S
+index 2d5bfa9..decbcff 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memcpy_a2):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memcpy_a2)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S
+index 92c06be..c3c2f7f 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memcpy_cell):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memcpy_cell)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S
+index eb01d67..02ba9b1 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memcpy_power4):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memcpy_power4)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S
+index 13b514d..58e8113 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memcpy_power6):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memcpy_power6)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S
+index 2aea73d..1170c50 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memcpy_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memcpy_power7)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
+index b828915..c630654 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
+@@ -26,7 +26,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memcpy_ppc):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memcpy_ppc)
+ 
+ # undef END_GEN_TB
+ # define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S
+index 6a79847..8d4b7a7 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__mempcpy_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__mempcpy_power7)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S
+index 42ee8e2..c363215 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__memrchr_power7)					\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__memrchr_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memrchr_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S b/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S
+index 9074b95..968dc24 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memset_power4):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memset_power4)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S b/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S
+index 70688b5..65519b9 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memset_power6):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memset_power6)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S b/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S
+index ab226c5..86765e7 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memset_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memset_power7)
+ 
+ #undef END_GEN_TB
+ #define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
+index dc5549c..3601a77 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
+@@ -37,7 +37,8 @@ END_GEN_TB (__bzero_ppc,TB_TOCLESS)
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__memset_ppc):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__memset_ppc)
+ 
+ # undef END_GEN_TB
+ # define END_GEN_TB(name, mask)					\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S
+index 24ae3bf..9f7533a 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__rawmemchr_power7)					\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__rawmemchr_power7):				\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__rawmemchr_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S
+index 9714f88..ad00f98 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__strcasecmp_power7)					\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__strcasecmp_power7):				\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strcasecmp_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S
+index 117e464..81ec696 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__strcasecmp_l_power7)				\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__strcasecmp_l_power7):				\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strcasecmp_l_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S
+index 0b2ca42..a3473a6 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__strchr_power7)					\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__strchr_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strchr_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S
+index ded9284..607668a 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S
+@@ -25,7 +25,8 @@
+   ENTRY_2(__strchr_ppc)						\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__strchr_ppc):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strchr_ppc)
+ 
+ # undef END
+ # define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S
+index 87d7c03..95ead0a 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__strchrnul_power7)					\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__strchrnul_power7):				\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strchrnul_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S
+index a38521d..c47c9d6 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__strlen_power7)					\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__strlen_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strlen_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
+index b463b3a..a195e9a 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
+@@ -25,7 +25,8 @@
+   ENTRY_2(__strlen_ppc)						\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__strlen_ppc):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strlen_ppc)
+ 
+ # undef END
+ # define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
+index 62cebbc..da32b0b 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S
+@@ -24,7 +24,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__strncmp_power4):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strncmp_power4)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
+index b0d607a..65ee0cd 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S
+@@ -24,7 +24,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__strncmp_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strncmp_power7)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
+index 25b7f26..14a2bec 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S
+@@ -25,7 +25,8 @@
+   .align ALIGNARG(alignt);					\
+   EALIGN_W_##words;						\
+   BODY_LABEL(__strncmp_ppc):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strncmp_ppc)
+ 
+ #undef END
+ #define END(name)						\
+diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S
+index 909aae8..057e5a8 100644
+--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S
++++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S
+@@ -24,7 +24,8 @@
+   ENTRY_2(__strnlen_power7)					\
+   .align ALIGNARG(2);						\
+   BODY_LABEL(__strnlen_power7):					\
+-  cfi_startproc;
++  cfi_startproc;						\
++  LOCALENTRY(__strnlen_power7)
+ 
+ #undef END
+ #define END(name)						\
diff --git a/SOURCES/glibc-rtkaio-inc-pthread.patch b/SOURCES/glibc-rtkaio-inc-pthread.patch
new file mode 100644
index 0000000..dbd9c19
--- /dev/null
+++ b/SOURCES/glibc-rtkaio-inc-pthread.patch
@@ -0,0 +1,22 @@
+diff -urN glibc-2.17-c758a686/rtkaio/tst-aiod2.c glibc-2.17-c758a686.mod/rtkaio/tst-aiod2.c
+--- glibc-2.17-c758a686/rtkaio/tst-aiod2.c	2011-10-19 07:04:41.000000000 -0400
++++ glibc-2.17-c758a686.mod/rtkaio/tst-aiod2.c	2014-08-19 18:32:10.174233598 -0400
+@@ -24,6 +24,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <errno.h>
++#include <pthread.h>
+ #include "tst-aiod.h"
+ 
+ 
+diff -urN glibc-2.17-c758a686/rtkaio/tst-aiod3.c glibc-2.17-c758a686.mod/rtkaio/tst-aiod3.c
+--- glibc-2.17-c758a686/rtkaio/tst-aiod3.c	2011-10-19 07:04:41.000000000 -0400
++++ glibc-2.17-c758a686.mod/rtkaio/tst-aiod3.c	2014-08-19 18:31:59.855273111 -0400
+@@ -23,6 +23,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <errno.h>
++#include <pthread.h>
+ #include "tst-aiod.h"
+ 
+ 
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index e913e49..747da11 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -1,6 +1,6 @@
 %define glibcsrcdir glibc-2.17-c758a686
 %define glibcversion 2.17
-%define glibcrelease 55%{?dist}.5
+%define glibcrelease 78%{?dist}
 ##############################################################################
 # If run_glibc_tests is zero then tests are not run for the build.
 # You must always set run_glibc_tests to one for production builds.
@@ -194,7 +194,24 @@ Patch0045: %{name}-rh731833-rtkaio-2.patch
 # Add -fstack-protector-strong support. 
 Patch0048: %{name}-rh1070806.patch
 
-Patch0061: %{name}-rh1133811-1.patch
+Patch0060: %{name}-aa64-commonpagesize-64k.patch
+
+Patch0061: %{name}-rh1133812-1.patch
+
+Patch0062: %{name}-cs-path.patch
+
+# Use __int128_t in link.h to support older compilers.
+Patch0063: %{name}-rh1120490-int128.patch
+
+# EMBARGOED!!! -- EMBARGOED!!! --- EMBARGOED!!!
+# EMBARGOED!!! -- EMBARGOED!!! --- EMBARGOED!!!
+# EMBARGOED!!! -- EMBARGOED!!! --- EMBARGOED!!!
+# CVE-2014-8121:
+Patch0064: glibc-rh1165192.patch
+# EMBARGOED!!! -- EMBARGOED!!! --- EMBARGOED!!!
+# EMBARGOED!!! -- EMBARGOED!!! --- EMBARGOED!!!
+# EMBARGOED!!! -- EMBARGOED!!! --- EMBARGOED!!!
+
 ##############################################################################
 #
 # Patches from upstream
@@ -316,14 +333,171 @@ Patch1062: %{name}-rh1063681.patch
 # Upstream BZ 16680
 Patch1063: %{name}-rh1074410.patch
 
-
-Patch1509: %{name}-rh1133811-2.patch
-Patch1510: %{name}-rh1133811-3.patch
-
-# Upstream CVE-2014-7817.
-Patch1511: %{name}-rh1170118-CVE-2014-7817.patch
-
-Patch1512: %{name}-rh1183535.patch
+# PPC64LE Patch Set:
+Patch1064: glibc-ppc64le-01.patch
+Patch1065: glibc-ppc64le-02.patch
+Patch1066: glibc-ppc64le-03.patch
+Patch1067: glibc-ppc64le-04.patch
+Patch1068: glibc-ppc64le-05.patch
+Patch1069: glibc-ppc64le-06.patch
+Patch1070: glibc-ppc64le-07.patch
+Patch1071: glibc-ppc64le-08.patch
+Patch1072: glibc-ppc64le-09.patch
+Patch1073: glibc-ppc64le-10.patch
+Patch1074: glibc-ppc64le-11.patch
+Patch1075: glibc-ppc64le-12.patch
+Patch1076: glibc-ppc64le-13.patch
+Patch1077: glibc-ppc64le-14.patch
+Patch1078: glibc-ppc64le-15.patch
+Patch1079: glibc-ppc64le-16.patch
+Patch1080: glibc-ppc64le-17.patch
+Patch1081: glibc-ppc64le-18.patch
+Patch1082: glibc-ppc64le-19.patch
+Patch1083: glibc-ppc64le-20.patch
+Patch1084: glibc-ppc64le-21.patch
+Patch1085: glibc-ppc64le-22.patch
+Patch1086: glibc-ppc64le-23.patch
+Patch1087: glibc-ppc64le-24.patch
+Patch1088: glibc-ppc64le-25.patch
+Patch1089: glibc-ppc64le-26.patch
+Patch1090: glibc-ppc64le-27.patch
+Patch1091: glibc-ppc64le-28.patch
+Patch1092: glibc-ppc64le-29.patch
+Patch1093: glibc-ppc64le-30.patch
+Patch1094: glibc-ppc64le-31.patch
+Patch1095: glibc-ppc64le-32.patch
+Patch1096: glibc-ppc64le-33.patch
+Patch1097: glibc-ppc64le-34.patch
+Patch1098: glibc-ppc64le-35.patch
+Patch1099: glibc-ppc64le-36.patch
+Patch1100: glibc-ppc64le-37.patch
+Patch1101: glibc-ppc64le-38.patch
+Patch1102: glibc-ppc64le-39.patch
+Patch1103: glibc-ppc64le-40.patch
+Patch1104: glibc-ppc64le-41.patch
+Patch1105: glibc-ppc64le-42.patch
+Patch1106: glibc-ppc64le-43.patch
+Patch1107: glibc-ppc64le-44.patch
+Patch1108: glibc-ppc64le-45.patch
+Patch1109: glibc-ppc64le-46.patch
+# End of PPC64LE patch set.
+# Leave room up to 1120 for ppc64le patches.
+
+# Split out ldbl_high into a distinct patch that is applied *before*
+# the ppc64le patches and the ppc64 IFUNC patches. We do this because
+# we want the IFUNC patches to be LE-safe and some code has to be
+# factored out and applied for both to use.
+Patch1110: glibc-powerpc-ldbl_high.patch
+
+# Backport fixes for power math ULP changes.
+Patch1121: glibc-power-libm-test-ulps.patch
+# Backport the write buffer size adjustment to match newer kernels.
+Patch1122: glibc-fix-test-write-buf-size.patch
+
+# Upstream BZ #14142
+# Required RHEL 7.1 BZ #1067754
+Patch1499: %{name}-rh1067755.patch
+
+# Acadia BZ #1070458
+Patch1500: %{name}-rh1070458.patch
+
+# Upstream BZ #15036
+# Acadia BZ #1070471
+Patch1501: %{name}-rh1070471.patch
+
+# Upstream BZ #16169
+# Acadia BZ #1078225
+Patch1502: %{name}-rh1078225.patch
+
+# Upstream BZ #16629 -- plus a bit extra
+Patch1503: %{name}-aa64-setcontext.patch
+
+Patch1504: glibc-aarch64-add-ptr_mangle-support.patch
+Patch1505: glibc-aarch64-fpu-optional-trapping-exceptions.patch
+Patch1506: glibc-aarch64-syscall-rewrite.patch
+Patch1508: glibc-aarch64-ifunc.patch
+
+Patch1509: %{name}-rh1133812-2.patch
+Patch1510: %{name}-rh1133812-3.patch
+
+Patch1511: %{name}-rh1083647.patch
+Patch1512: %{name}-rh1085290.patch
+Patch1513: %{name}-rh1083644.patch
+Patch1514: %{name}-rh1083646.patch
+
+Patch1515: %{name}-rh1103856.patch
+Patch1516: %{name}-rh1080766.patch
+Patch1517: %{name}-rh1103874.patch
+Patch1518: %{name}-rh1125306.patch
+Patch1519: %{name}-rh1098047.patch
+Patch1520: %{name}-rh1138520.patch
+Patch1521: %{name}-rh1085313.patch
+Patch1522: %{name}-rh1140474.patch
+
+# Backport multi-lib support in GLIBC for PowerPC using IFUNC
+Patch1530: %{name}-rh731837-00.patch
+Patch1531: %{name}-rh731837-01.patch
+Patch1532: %{name}-rh731837-02.patch
+Patch1533: %{name}-rh731837-03.patch
+Patch1534: %{name}-rh731837-04.patch
+Patch1535: %{name}-rh731837-05.patch
+Patch1536: %{name}-rh731837-06.patch
+Patch1537: %{name}-rh731837-07.patch
+Patch1538: %{name}-rh731837-08.patch
+Patch1539: %{name}-rh731837-09.patch
+Patch1540: %{name}-rh731837-10.patch
+Patch1541: %{name}-rh731837-11.patch
+Patch1542: %{name}-rh731837-12.patch
+Patch1543: %{name}-rh731837-13.patch
+Patch1544: %{name}-rh731837-14.patch
+Patch1545: %{name}-rh731837-15.patch
+Patch1546: %{name}-rh731837-16.patch
+Patch1547: %{name}-rh731837-17.patch
+Patch1548: %{name}-rh731837-18.patch
+Patch1549: %{name}-rh731837-19.patch
+Patch1550: %{name}-rh731837-20.patch
+Patch1551: %{name}-rh731837-21.patch
+Patch1552: %{name}-rh731837-22.patch
+Patch1553: %{name}-rh731837-23.patch
+Patch1554: %{name}-rh731837-24.patch
+Patch1555: %{name}-rh731837-25.patch
+Patch1556: %{name}-rh731837-26.patch
+Patch1557: %{name}-rh731837-27.patch
+Patch1558: %{name}-rh731837-28.patch
+Patch1559: %{name}-rh731837-29.patch
+Patch1560: %{name}-rh731837-30.patch
+Patch1561: %{name}-rh731837-31.patch
+Patch1562: %{name}-rh731837-32.patch
+Patch1563: %{name}-rh731837-33.patch
+Patch1564: %{name}-rh731837-34.patch
+Patch1565: %{name}-rh731837-35.patch
+Patch1566: %{name}-rh731837-33A.patch
+Patch1567: %{name}-rh731837-36.patch
+
+# Intel AVX-512 support.
+Patch1570: %{name}-rh1140272-avx512.patch
+# Intel MPX support.
+Patch1571: %{name}-rh1132518-mpx.patch
+# glibc manual update.
+Patch1572: %{name}-manual-update.patch
+
+Patch1573: %{name}-rh1120490.patch
+
+# Fix ppc64le relocation handling:
+Patch1574: %{name}-rh1162847-p1.patch
+Patch1575: %{name}-rh1162847-p2.patch
+
+# CVE-2014-7817
+Patch1576: %{name}-rh1170118-CVE-2014-7817.patch
+
+# Provide artificial OPDs for ppc64 VDSO functions.
+Patch1577: %{name}-rh1077389-p1.patch
+# BZ#16431
+Patch1578: %{name}-rh1077389-p2.patch
+# BZ#16037 - Allow GNU Make version 4.0 and up to be used. 
+Patch1579: %{name}-gmake.patch
+
+Patch1580: %{name}-rh1183545.patch
 
 ##############################################################################
 #
@@ -364,7 +538,21 @@ Patch2052: %{name}-rh1048123.patch
 # Upstream BZ 16680
 Patch2053: %{name}-rh1074410-2.patch
 
-Patch2065: %{name}-rh1170187.patch
+# Upstream BZ 15493.
+# Upstream as of 2013-03-20
+Patch2055: %{name}-rh1073667.patch
+
+Patch2060: %{name}-aarch64-rh1076760.patch
+Patch2061: %{name}-aarch64-dont-alloc-static-tls-for-TLS_DESC.patch
+
+# Include pthread.h in rtkaio/tst-aiod2.c and rtkaio/tst-aiod3.c.
+Patch2062: %{name}-rtkaio-inc-pthread.patch
+
+Patch2063: %{name}-rh1084089.patch
+
+Patch2064: %{name}-rh1161666.patch
+
+Patch2065: %{name}-rh1156331.patch
 
 ##############################################################################
 # End of glibc patches.
@@ -373,6 +561,7 @@ Patch2065: %{name}-rh1170187.patch
 ##############################################################################
 # Continued list of core "glibc" package information:
 ##############################################################################
+
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Obsoletes: glibc-profile < 2.4
 Obsoletes: nss_db
@@ -414,8 +603,12 @@ Conflicts: kernel < %{enablekernel}
 %define target %{_target_cpu}-redhat-linuxeabi
 %endif
 %ifarch %{power64}
+%ifarch ppc64le
+%define target ppc64le-redhat-linux
+%else
 %define target ppc64-redhat-linux
 %endif
+%endif
 
 %ifarch %{multiarcharches}
 # Need STT_IFUNC support
@@ -757,15 +950,163 @@ package or when debugging this package.
 %patch1045 -p1
 %patch2052 -p1
 %patch0048 -p1
+%patch0060 -p1
 %patch1062 -p1
 %patch1063 -p1
 %patch2053 -p1
+# Apply ldbl_high() patch for both ppc64le and ppc64.
+%patch1110 -p1
+# PPC64LE Patch set:
+# 1064 to 1108.
+%ifarch ppc64le
+%patch1064 -p1
+%patch1065 -p1
+%patch1066 -p1
+%patch1067 -p1
+%patch1068 -p1
+%patch1069 -p1
+%patch1070 -p1
+%patch1071 -p1
+%patch1072 -p1
+%patch1073 -p1
+%patch1074 -p1
+%patch1075 -p1
+%patch1076 -p1
+%patch1077 -p1
+%patch1078 -p1
+%patch1079 -p1
+%patch1080 -p1
+%patch1081 -p1
+%patch1082 -p1
+%patch1083 -p1
+%patch1084 -p1
+%patch1085 -p1
+%patch1086 -p1
+%patch1087 -p1
+%patch1088 -p1
+%patch1089 -p1
+%patch1090 -p1
+%patch1091 -p1
+%patch1092 -p1
+%patch1093 -p1
+%patch1094 -p1
+%patch1095 -p1
+%patch1096 -p1
+%patch1097 -p1
+%patch1098 -p1
+%patch1099 -p1
+%patch1100 -p1
+%patch1101 -p1
+%patch1102 -p1
+%patch1103 -p1
+%patch1104 -p1
+%patch1105 -p1
+%patch1106 -p1
+%patch1107 -p1
+%patch1108 -p1
+%patch1109 -p1
+%else
+# Some patches are different on !ppc64le, but only because the ppc64le patches
+# change things and require a slightly different patch. At present this is
+# becuase libm-test-ulps is shared between ppc64le and normal ppc64/ppc. This
+# means we have to keep two distinct patches to apply to either "branch."
+%patch1121 -p1
+%endif
+%patch1122 -p1
+%patch2055 -p1
+%patch1499 -p1
+%patch1500 -p1
+%patch1501 -p1
+%patch1502 -p1
+%patch1503 -p1
+%patch1504 -p1
+%patch1505 -p1
+%patch2060 -p1
+%patch2061 -p1
+%patch1506 -p1
+%patch1508 -p1
+%patch2062 -p1
 %patch0061 -p1
 %patch1509 -p1
 %patch1510 -p1
-%patch2065 -p1
 %patch1511 -p1
 %patch1512 -p1
+%patch1513 -p1
+%patch1514 -p1
+%patch1515 -p1
+%patch1516 -p1
+%patch1517 -p1
+%patch1518 -p1
+%patch1519 -p1
+%patch0062 -p1
+%patch2063 -p1
+%patch1520 -p1
+%patch1521 -p1
+%patch1522 -p1
+# Start of IBM IFUNC patch set.
+%patch1530 -p1
+%patch1531 -p1
+%patch1532 -p1
+%patch1533 -p1
+%patch1534 -p1
+%patch1535 -p1
+%patch1536 -p1
+%patch1537 -p1
+%patch1538 -p1
+%patch1539 -p1
+%patch1540 -p1
+%patch1541 -p1
+%patch1542 -p1
+%patch1543 -p1
+%patch1544 -p1
+%patch1545 -p1
+%patch1546 -p1
+%patch1547 -p1
+%patch1548 -p1
+%patch1549 -p1
+%patch1550 -p1
+%patch1551 -p1
+%patch1552 -p1
+%patch1553 -p1
+%patch1554 -p1
+%patch1555 -p1
+%patch1556 -p1
+%patch1557 -p1
+%patch1558 -p1
+%patch1559 -p1
+%patch1560 -p1
+%patch1561 -p1
+%patch1562 -p1
+%patch1563 -p1
+%patch1564 -p1
+%patch1565 -p1
+# Apply fixup patch for -33 in the series to make it LE safe.
+%patch1566 -p1
+%ifarch ppc64le
+# On ppc64le add LOCALENTRY() to all IFUNC functions to materialize the TOC.
+# Don't do this in general because LOCALENTRY() depends on ELFv2 patches which
+# we don't apply for ppc64.
+%patch1567 -p1
+%endif
+# End of IBM IFUNC patch set.
+%patch1570 -p1
+%patch1571 -p1
+%patch1572 -p1
+%patch1573 -p1
+%patch0063 -p1
+%patch2064 -p1
+%ifarch ppc64le
+# On ppc64le the relocation handling needs fixing.
+%patch1574 -p1
+%patch1575 -p1
+%endif
+%patch2065 -p1
+%patch1576 -p1
+%patch1577 -p1
+%patch1578 -p1
+%patch0064 -p1
+%patch1579 -p1
+%patch1580 -p1
 
 ##############################################################################
 # %%prep - Additional prep required...
@@ -910,8 +1251,10 @@ configure_CFLAGS="$build_CFLAGS -fno-asynchronous-unwind-tables"
 	--enable-systemtap \
 %endif
 %ifarch ppc %{power64}
+%ifnarch ppc64le
 	--with-cpu=power7 \
 %endif
+%endif
 	--disable-profile --enable-nss-crypt ||
 { cat config.log; false; }
 
@@ -986,6 +1329,16 @@ popd
 # Install glibc...
 ##############################################################################
 %install
+
+# Ensure the permissions of errlist.c do not change.  When the file is
+# regenerated the Makefile sets the permissions to 444. We set it to 644
+# to match what comes out of git. The tarball of the git archive won't have
+# correct permissions because git doesn't track all of the permissions
+# accurately (see git-cache-meta if you need that). We also set it to 644 to
+# match pre-existing rpms. We do this *after* the build because the build
+# might regenerate the file and set the permissions to 444.
+chmod 644 sysdeps/gnu/errlist.c
+
 # Reload compiler and build options that were used during %%build.
 GCC=`cat Gcc`
 
@@ -1403,7 +1756,7 @@ touch -r sunrpc/etc.rpc $RPM_BUILD_ROOT/etc/rpc
 # the one used at runtime.  This is really only needed during the ARM
 # transition from ld-linux.so.3 to ld-linux-armhf.so.3.
 pushd releng
-$GCC -Os -g -o build-locale-archive build-locale-archive.c \
+$GCC -Os -g -static -o build-locale-archive build-locale-archive.c \
   ../build-%{target}/locale/locarchive.o \
   ../build-%{target}/locale/md5.o \
   -DDATADIR=\"%{_datadir}\" -DPREFIX=\"%{_prefix}\" \
@@ -1821,23 +2174,112 @@ rm -f *.filelist*
 %endif
 
 %changelog
-* Mon Jan 19 2015 Carlos O'Donell <codonell@redhat.com> - 2.17-55.5
-- Rebuild and run regression testing.
+* Mon Jan 19 2015 Carlos O'Donell <carlos@redhat.com> - 2.17-78
+- Fix ppc64le builds (#1077389).
 
-* Mon Jan 19 2015 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-55.4
-- Fix parsing of numeric hosts in gethostbyname_r (CVE-2015-0235, #1183535).
+* Mon Jan 19 2015 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-77
+- Fix parsing of numeric hosts in gethostbyname_r (CVE-2015-0235, #1183545).
 
-* Fri Dec  5 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-55.3
-- Fix wordexp() to honour WRDE_NOCMD (CVE-2014-7817, #1170118)
+* Thu Jan 15 2015 Carlos O'Donell <carlos@redhat.com> - 2.17-76
+- Fix application crashes during calls to gettimeofday on ppc64
+  when kernel exports gettimeofday via VDSO (#1077389).
+- Prevent NSS-based file backend from entering infinite loop
+  when different APIs request the same service (CVE-2014-8121, #1182272).
 
-* Thu Dec  4 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-55.2
-- ftell: seek to end only when there are unflushed bytes (#1170187).
+* Mon Dec  8 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-75
+- Fix permission of debuginfo source files to allow multiarch
+  debuginfo packages to be installed and upgraded (#1170110).
 
-* Tue Aug 26 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-55.1
+* Fri Dec  5 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-74
+- Fix wordexp() to honour WRDE_NOCMD (CVE-2014-7817, #1170487).
+
+* Wed Dec  3 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-73
+- ftell: seek to end only when there are unflushed bytes (#1156331).
+
+* Wed Nov 12 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-72
+- [s390] Fix up _dl_argv after adjusting arguments in _dl_start_user (#1161666).
+
+* Tue Nov 11 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-71
+- Fix incorrect handling of relocations in 64-bit LE mode for Power
+  (#1162847).
+
+* Tue Nov 11 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-70
+- [s390] Retain stack alignment when skipping over loader argv (#1161666).
+
+* Wed Nov  5 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-69
+- Use __int128_t in link.h to support older compiler (#1120490).
+
+* Tue Sep 16 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-68
+- Revert to defining __extern_inline only for gcc-4.3+ (#1120490).
+
+* Mon Sep 15 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-67
+- Correct a defect in the generated math error table in the manual (#786638).
+
+* Fri Sep 12 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-66
+- Include preliminary thread, signal and cancellation safety documentation
+  in manual (#786638).
+
+* Thu Sep 11 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-65
+- PowerPC 32-bit and 64-bit optimized function support using STT_GNU_IFUNC
+  (#731837).
+- Support running Intel MPX-enabled applications (#1132518).
+- Support running Intel AVX-512-enabled applications (#1140272).
+
+* Thu Sep 11 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-64
+- Fix crashes on invalid input in IBM gconv modules (#1140474, CVE-2014-6040).
+
+* Wed Sep 10 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-63
+- Build build-locale-archive statically (#1070611).
+- Return failure in getnetgrent only when all netgroups have been searched
+  (#1085313).
+
+* Mon Sep  8 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-62
+- Don't use alloca in addgetnetgrentX (#1138520).
+- Adjust pointers to triplets in netgroup query data (#1138520).
+
+* Fri Sep  5 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-61
+- Set CS_PATH to just /use/bin (#1124453).
+- Add systemtap probe in lll_futex_wake for ppc and s390 (#1084089).
+
+* Fri Sep  5 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-60
+- Add mmap usage to malloc_info output (#1103856).
+- Fix nscd lookup for innetgr when netgroup has wildcards (#1080766).
+- Fix memory order when reading libgcc handle (#1103874).
+- Fix typo in nscd/selinux.c (#1125306).
+- Do not fail if one of the two responses to AF_UNSPEC fails (#1098047).
+
+* Thu Sep  4 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-59
+- Provide correct buffer length to netgroup queries in nscd (#1083647).
+- Return NULL for wildcard values in getnetgrent from nscd (#1085290).
+- Avoid overlapping addresses to stpcpy calls in nscd (#1083644).
+- Initialize all of datahead structure in nscd (#1083646).
+
+* Tue Aug 26 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-58
 - Remove gconv transliteration loadable modules support (CVE-2014-5119,
-  #1133811).
+  #1133812).
 - _nl_find_locale: Improve handling of crafted locale names (CVE-2014-0475,
-  #1133811).
+  #1133812).
+
+* Tue Aug 19 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-57
+- Merge 64-bit ARM (AArch64) support (#1027179).
+- Fix build failure for rtkaio/tst-aiod2.c and rtkaio/tst-aiod3.c.
+
+* Sun Aug  3 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-56
+- Merge LE 64-bit POWER support (#1125513).
+
+* Fri Jul 25 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-55.4
+- Fix tst-cancel4, tst-cancelx4, tst-cancel5, and tst-cancelx5 for all targets.
+- Fix tst-ildoubl, and tst-ldouble for POWER.
+- Allow LE 64-bit POWER to build with VSX if enabled (#1124048).
+
+* Mon Jun  2 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-55.3
+- Fix ppc64le ABI issue with pthread_atfork being present in libpthread.so.0.
+
+* Fri May 30 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-55.2
+- Add ABI baseline for 64-bit POWER LE.
+
+* Fri May 30 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-55.1
+- Add 64-bit POWER LE support.
 
 * Wed Mar 19 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-55
 - Fix up test case for previous ftell bug (#1074410).
@@ -1850,6 +2292,12 @@ rm -f *.filelist*
 - Change offset in fdopen only if setting O_APPEND (#1074410).
 - Fix up return codes for tests in tst-ftell-active-handler (#1074410).
 
+* Thu Mar  6 2014 Richard Henderson <rth@redhat.com> - 2.17-52.2
+- Fix argument clobber (#1073667).
+
+* Thu Mar  6 2014 Carlos O'Donell <carlos@redhat.com> - 2.17-52.1
+- Fix nscd failure on AArch64 involving errno access (#1067755).
+
 * Tue Mar  4 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.17-52
 - Fix ftell behavior when the stream handle is not active (#1063681).