Browse Source

glibc package update

Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>
master
basebuilder_pel7ppc64bebuilder0 6 years ago
parent
commit
956dd03e97
  1. 11
      SOURCES/glibc-aa64-commonpagesize-64k.patch
  2. 220
      SOURCES/glibc-aa64-setcontext.patch
  3. 233
      SOURCES/glibc-aarch64-add-ptr_mangle-support.patch
  4. 122
      SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch
  5. 216
      SOURCES/glibc-aarch64-ifunc.patch
  6. 20
      SOURCES/glibc-aarch64-rh1076760.patch
  7. 539
      SOURCES/glibc-aarch64-syscall-rewrite.patch
  8. 21
      SOURCES/glibc-arm-hardfloat-3.patch
  9. 6
      SOURCES/glibc-cs-path.patch
  10. 83
      SOURCES/glibc-fedora-__libc_multiple_libcs.patch
  11. 98
      SOURCES/glibc-fedora-elf-ORIGIN.patch
  12. 30
      SOURCES/glibc-fedora-elf-init-hidden_undef.patch
  13. 15
      SOURCES/glibc-fedora-elf-rh737223.patch
  14. 124
      SOURCES/glibc-fedora-gai-canonical.patch
  15. 35
      SOURCES/glibc-fedora-getrlimit-PLT.patch
  16. 18
      SOURCES/glibc-fedora-i386-tls-direct-seg-refs.patch
  17. 36
      SOURCES/glibc-fedora-include-bits-ldbl.patch
  18. 38
      SOURCES/glibc-fedora-ldd.patch
  19. 48
      SOURCES/glibc-fedora-linux-tcsetattr.patch
  20. 38
      SOURCES/glibc-fedora-localedata-rh61908.patch
  21. 11
      SOURCES/glibc-fedora-localedef.patch
  22. 51
      SOURCES/glibc-fedora-locarchive.patch
  23. 20
      SOURCES/glibc-fedora-manual-dircategory.patch
  24. 21
      SOURCES/glibc-fedora-nis-rh188246.patch
  25. 25
      SOURCES/glibc-fedora-nptl-linklibc.patch
  26. 12
      SOURCES/glibc-fedora-nscd.patch
  27. 23
      SOURCES/glibc-fedora-ppc-unwind.patch
  28. 155
      SOURCES/glibc-fedora-regcomp-sw11561.patch
  29. 28
      SOURCES/glibc-fedora-streams-rh436349.patch
  30. 52
      SOURCES/glibc-fedora-uname-getrlimit.patch
  31. 54
      SOURCES/glibc-fix-test-write-buf-size.patch
  32. 37
      SOURCES/glibc-gmake.patch
  33. 19408
      SOURCES/glibc-manual-update.patch
  34. 744
      SOURCES/glibc-ol7-strstr-sse4.patch
  35. 13
      SOURCES/glibc-powerpc-ldbl_high.patch
  36. 83
      SOURCES/glibc-ppc64le-01.patch
  37. 3197
      SOURCES/glibc-ppc64le-02.patch
  38. 1617
      SOURCES/glibc-ppc64le-03.patch
  39. 676
      SOURCES/glibc-ppc64le-04.patch
  40. 486
      SOURCES/glibc-ppc64le-05.patch
  41. 652
      SOURCES/glibc-ppc64le-06.patch
  42. 651
      SOURCES/glibc-ppc64le-07.patch
  43. 1235
      SOURCES/glibc-ppc64le-08.patch
  44. 567
      SOURCES/glibc-ppc64le-09.patch
  45. 91
      SOURCES/glibc-ppc64le-10.patch
  46. 113
      SOURCES/glibc-ppc64le-11.patch
  47. 74
      SOURCES/glibc-ppc64le-12.patch
  48. 283
      SOURCES/glibc-ppc64le-13.patch
  49. 120
      SOURCES/glibc-ppc64le-14.patch
  50. 119
      SOURCES/glibc-ppc64le-15.patch
  51. 163
      SOURCES/glibc-ppc64le-16.patch
  52. 312
      SOURCES/glibc-ppc64le-17.patch
  53. 81
      SOURCES/glibc-ppc64le-18.patch
  54. 110
      SOURCES/glibc-ppc64le-19.patch
  55. 41
      SOURCES/glibc-ppc64le-20.patch
  56. 294
      SOURCES/glibc-ppc64le-21.patch
  57. 228
      SOURCES/glibc-ppc64le-22.patch
  58. 102
      SOURCES/glibc-ppc64le-23.patch
  59. 55
      SOURCES/glibc-ppc64le-24.patch
  60. 411
      SOURCES/glibc-ppc64le-25.patch
  61. 379
      SOURCES/glibc-ppc64le-26.patch
  62. 861
      SOURCES/glibc-ppc64le-27.patch
  63. 167
      SOURCES/glibc-ppc64le-28.patch
  64. 642
      SOURCES/glibc-ppc64le-29.patch
  65. 7383
      SOURCES/glibc-ppc64le-30.patch
  66. 2943
      SOURCES/glibc-ppc64le-31.patch
  67. 272
      SOURCES/glibc-ppc64le-32.patch
  68. 1255
      SOURCES/glibc-ppc64le-33.patch
  69. 68
      SOURCES/glibc-ppc64le-34.patch
  70. 106
      SOURCES/glibc-ppc64le-35.patch
  71. 105
      SOURCES/glibc-ppc64le-36.patch
  72. 31
      SOURCES/glibc-ppc64le-37.patch
  73. 262
      SOURCES/glibc-ppc64le-38.patch
  74. 508
      SOURCES/glibc-ppc64le-39.patch
  75. 159
      SOURCES/glibc-ppc64le-40.patch
  76. 764
      SOURCES/glibc-ppc64le-41.patch
  77. 404
      SOURCES/glibc-ppc64le-42.patch
  78. 248
      SOURCES/glibc-ppc64le-43.patch
  79. 26
      SOURCES/glibc-ppc64le-44.patch
  80. 33
      SOURCES/glibc-ppc64le-45.patch
  81. 22
      SOURCES/glibc-ppc64le-46.patch
  82. 32
      SOURCES/glibc-rh1000923.patch
  83. 46
      SOURCES/glibc-rh1008298.patch
  84. 128
      SOURCES/glibc-rh1020637.patch
  85. 50
      SOURCES/glibc-rh1025612.patch
  86. 143
      SOURCES/glibc-rh1025934.patch
  87. 58
      SOURCES/glibc-rh1027101.patch
  88. 280
      SOURCES/glibc-rh1027348-1.patch
  89. 229
      SOURCES/glibc-rh1027348-2.patch
  90. 144
      SOURCES/glibc-rh1027348-3.patch
  91. 105
      SOURCES/glibc-rh1027348-4.patch
  92. 3917
      SOURCES/glibc-rh1027348.patch
  93. 96
      SOURCES/glibc-rh1028652.patch
  94. 390
      SOURCES/glibc-rh1032435.patch
  95. 102
      SOURCES/glibc-rh1039496.patch
  96. 135
      SOURCES/glibc-rh1039970.patch
  97. 23
      SOURCES/glibc-rh1046199.patch
  98. 555
      SOURCES/glibc-rh1047983.patch
  99. 29
      SOURCES/glibc-rh1048036.patch
  100. 515
      SOURCES/glibc-rh1048123.patch
  101. Some files were not shown because too many files have changed in this diff Show More

11
SOURCES/glibc-aa64-commonpagesize-64k.patch

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
--- glibc-2.17-c758a686/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

220
SOURCES/glibc-aa64-setcontext.patch

@ -0,0 +1,220 @@ @@ -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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S
index aff2e32..70b2e32 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S
index a98f67f..f45a655 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
index 1afff78..ab3930c 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
+++ glibc-2.17-c758a686/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)

233
SOURCES/glibc-aarch64-add-ptr_mangle-support.patch

@ -0,0 +1,233 @@ @@ -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 glibc-2.17-c758a686/ports/sysdeps/aarch64/__longjmp.S glibc-2.17-c758a686/ports/sysdeps/aarch64/__longjmp.S
index 250f2af..2d38bbf 100644
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/__longjmp.S
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-offsets.h glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-offsets.h
index 84c2ccc..bcf2afa 100644
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-offsets.h
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-unwind.h glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-unwind.h
index 22c6c2b..39a5dc2 100644
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-unwind.h
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S
index cb94e01..5822abd 100644
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/aarch64/sysdep.h glibc-2.17-c758a686/ports/sysdeps/aarch64/sysdep.h
index 0dd597a..7169ba7 100644
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/sysdep.h
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index f3f0ada..5ccf1da 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ glibc-2.17-c758a686/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.

diff --git glibc-2.17-c758a686/elf/Makefile glibc-2.17-c758a686/elf/Makefile
index cb8da93..27d249b 100644
--- glibc-2.17-c758a686/elf/Makefile
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h
index 4fa3d96..b4a6b23 100644
--- glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h
+++ glibc-2.17-c758a686/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

122
SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch

@ -0,0 +1,122 @@ @@ -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.

--- glibc-2.17-c758a686/ports/sysdeps/aarch64/fpu/feenablxcpt.c
+++ glibc-2.17-c758a686/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;
}
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/fpu/fesetenv.c
+++ glibc-2.17-c758a686/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)

--- glibc-2.17-c758a686/math/test-fenv.c
+++ glibc-2.17-c758a686/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);

216
SOURCES/glibc-aarch64-ifunc.patch

@ -0,0 +1,216 @@ @@ -0,0 +1,216 @@
diff --git glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h
index 8686fd5..2b10581 100644
--- glibc-2.17-c758a686/elf/elf.h
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h
index 32dee0f..9a48dc2 100644
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h
index b1878a7..1db5a5b 100644
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h
+++ glibc-2.17-c758a686/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);
}

20
SOURCES/glibc-aarch64-rh1076760.patch

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
--- glibc-2.17-c758a686/ports/sysdeps/aarch64/nptl/tls.h
+++ glibc-2.17-c758a686/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. */

539
SOURCES/glibc-aarch64-syscall-rewrite.patch

@ -0,0 +1,539 @@ @@ -0,0 +1,539 @@
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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
index 8be1464..d5c31f3 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
index f01fb84..be6c026 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
index 84af95d..dfca9a7 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
index e0e5cc0..a3b9284 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
index 574fdf1..fac6416 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index 713bf7d..9961c03 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ glibc-2.17-c758a686/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 glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
index f2dc49b..3fb68b9 100644
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
+++ glibc-2.17-c758a686/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

21
SOURCES/glibc-arm-hardfloat-3.patch

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
(Not needed anymore.)

diff -Nru glibc-2.17-c758a686/elf/dl-load.c glibc-2.17-c758a686/elf/dl-load.c
--- glibc-2.17-c758a686/elf/dl-load.c 2012-06-06 13:07:41.727524312 -0600
+++ glibc-2.17-c758a686/elf/dl-load.c 2012-06-06 13:11:19.308681002 -0600
@@ -2093,10 +2093,14 @@ _dl_map_object (struct link_map *loader,
soname = ((const char *) D_PTR (l, l_info[DT_STRTAB])
+ l->l_info[DT_SONAME]->d_un.d_val);
if (strcmp (name, soname) != 0)
- continue;
+#ifdef __arm__
+ if (strcmp (name, "ld-linux.so.3")
+ || strcmp (soname, "ld-linux-armhf.so.3"))
+#endif
+ continue;

/* We have a match on a new name -- cache it. */
- add_name_to_object (l, soname);
+ add_name_to_object (l, name);
l->l_soname_added = 1;
}

6
SOURCES/glibc-cs-path.patch

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
diff -pruN glibc-2.17-c758a686/sysdeps/unix/confstr.h glibc-2.17-c758a686/sysdeps/unix/confstr.h
--- glibc-2.17-c758a686/sysdeps/unix/confstr.h 2012-12-25 08:32:13.000000000 +0530
+++ glibc-2.17-c758a686/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"

83
SOURCES/glibc-fedora-__libc_multiple_libcs.patch

@ -0,0 +1,83 @@ @@ -0,0 +1,83 @@
From 16552c01a66633c9e412984d9d92616bd4e5303c Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@redhat.com>
Date: Fri, 11 Jun 2010 11:04:11 +0200
Subject: [PATCH] Properly set __libc_multiple_libcs

* elf/rtld.c (_dl_starting_up): Always define.
(dl_main): Always set _dl_starting_up.
* elf/dl-support.c (_dl_starting_up): Always define.
* elf/dl-init.c (_dl_init): Always clear _dl_starting_up.

---
ChangeLog | 7 +++++++
elf/dl-init.c | 4 ----
elf/dl-support.c | 2 --
elf/rtld.c | 4 ----
4 files changed, 7 insertions(+), 10 deletions(-)

--- glibc-2.17-c758a686/elf/dl-init.c
+++ glibc-2.17-c758a686/elf/dl-init.c
@@ -23,11 +23,9 @@
/* Type of the initializer. */
typedef void (*init_t) (int, char **, char **);

-#ifndef HAVE_INLINED_SYSCALLS
/* Flag, nonzero during startup phase. */
extern int _dl_starting_up;
extern int _dl_starting_up_internal attribute_hidden;
-#endif


static void
@@ -132,9 +130,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
while (i-- > 0)
call_init (main_map->l_initfini[i], argc, argv, env);

-#ifndef HAVE_INLINED_SYSCALLS
/* Finished starting up. */
INTUSE(_dl_starting_up) = 0;
-#endif
}
INTDEF (_dl_init)
--- glibc-2.17-c758a686/elf/dl-support.c
+++ glibc-2.17-c758a686/elf/dl-support.c
@@ -81,10 +81,8 @@ unsigned long long _dl_load_adds;
create a fake scope containing nothing. */
struct r_scope_elem _dl_initial_searchlist;

-#ifndef HAVE_INLINED_SYSCALLS
/* Nonzero during startup. */
int _dl_starting_up = 1;
-#endif

/* Random data provided by the kernel. */
void *_dl_random;
--- glibc-2.17-c758a686/elf/rtld.c
+++ glibc-2.17-c758a686/elf/rtld.c
@@ -106,7 +106,6 @@ static struct audit_list
struct audit_list *next;
} *audit_list;

-#ifndef HAVE_INLINED_SYSCALLS
/* Set nonzero during loading and initialization of executable and
libraries, cleared before the executable's entry point runs. This
must not be initialized to nonzero, because the unused dynamic
@@ -116,7 +115,6 @@ static struct audit_list
never be called. */
int _dl_starting_up = 0;
INTVARDEF(_dl_starting_up)
-#endif

/* This is the structure which defines all variables global to ld.so
(except those which cannot be added for some reason). */
@@ -929,10 +927,8 @@ dl_main (const ElfW(Phdr) *phdr,
/* Process the environment variable which control the behaviour. */
process_envvars (&mode);

-#ifndef HAVE_INLINED_SYSCALLS
/* Set up a flag which tells we are just starting. */
INTUSE(_dl_starting_up) = 1;
-#endif

if (*user_entry == (ElfW(Addr)) ENTRY_POINT)
{

98
SOURCES/glibc-fedora-elf-ORIGIN.patch

@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
From 207e77fd3f0a94acdf0557608dd4f10ce0e0f22f Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@redhat.com>
Date: Mon, 9 May 2011 10:55:58 +0200
Subject: [PATCH] Never leave $ORIGIN unexpanded

* elf/dl-load.c (is_dst): Remove parameter secure, all callers
changed. Move check for valid use of $ORIGIN ...
(_dl_dst_substitute): ... here. Reset check_for_trusted when a
path element is skipped.

---
ChangeLog | 7 +++++++
elf/dl-load.c | 34 ++++++++++++++++------------------
2 files changed, 23 insertions(+), 18 deletions(-)

diff --git glibc-2.17-c758a686/elf/dl-load.c glibc-2.17-c758a686/elf/dl-load.c
index 18a83d2..6e16a9a 100644
--- glibc-2.17-c758a686/elf/dl-load.c
+++ glibc-2.17-c758a686/elf/dl-load.c
@@ -249,8 +249,7 @@ is_trusted_path_normalize (const char *path, size_t len)


static size_t
-is_dst (const char *start, const char *name, const char *str,
- int is_path, int secure)
+is_dst (const char *start, const char *name, const char *str, int is_path)
{
size_t len;
bool is_curly = false;
@@ -279,12 +278,6 @@ is_dst (const char *start, const char *name, const char *str,
&& (!is_path || name[len] != ':'))
return 0;

- if (__builtin_expect (secure, 0)
- && ((name[len] != '\0' && name[len] != '/'
- && (!is_path || name[len] != ':'))
- || (name != start + 1 && (!is_path || name[-2] != ':'))))
- return 0;
-
return len;
}

@@ -299,13 +292,10 @@ _dl_dst_count (const char *name, int is_path)
{
size_t len;

- /* $ORIGIN is not expanded for SUID/GUID programs (except if it
- is $ORIGIN alone) and it must always appear first in path. */
++name;
- if ((len = is_dst (start, name, "ORIGIN", is_path,
- INTUSE(__libc_enable_secure))) != 0
- || (len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0
- || (len = is_dst (start, name, "LIB", is_path, 0)) != 0)
+ if ((len = is_dst (start, name, "ORIGIN", is_path)) != 0
+ || (len = is_dst (start, name, "PLATFORM", is_path)) != 0
+ || (len = is_dst (start, name, "LIB", is_path)) != 0)
++cnt;

name = strchr (name + len, '$');
@@ -338,9 +328,16 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
size_t len;

++name;
- if ((len = is_dst (start, name, "ORIGIN", is_path,
- INTUSE(__libc_enable_secure))) != 0)
+ if ((len = is_dst (start, name, "ORIGIN", is_path)) != 0)
{
+ /* For SUID/GUID programs $ORIGIN must always appear
+ first in a path element. */
+ if (__builtin_expect (INTUSE(__libc_enable_secure), 0)
+ && ((name[len] != '\0' && name[len] != '/'
+ && (!is_path || name[len] != ':'))
+ || (name != start + 1 && (!is_path || name[-2] != ':'))))
+ repl = (const char *) -1;
+ else
#ifndef SHARED
if (l == NULL)
repl = _dl_get_origin ();
@@ -351,9 +348,9 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
check_for_trusted = (INTUSE(__libc_enable_secure)
&& l->l_type == lt_executable);
}
- else if ((len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0)
+ else if ((len = is_dst (start, name, "PLATFORM", is_path)) != 0)
repl = GLRO(dl_platform);
- else if ((len = is_dst (start, name, "LIB", is_path, 0)) != 0)
+ else if ((len = is_dst (start, name, "LIB", is_path)) != 0)
repl = DL_DST_LIB;

if (repl != NULL && repl != (const char *) -1)
@@ -373,6 +370,7 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
element, but keep an empty element at the end. */
if (wp == result && is_path && *name == ':' && name[1] != '\0')
++name;
+ check_for_trusted = false;
}
else
/* No DST we recognize. */

30
SOURCES/glibc-fedora-elf-init-hidden_undef.patch

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
* Fri May 29 2003 Jakub Jelinek <jakub@redhat.com> 2.3.2-44
- make __init_array_start etc. symbols in elf-init.oS hidden undefined

diff -Nru glibc-2.17-c758a686/csu/elf-init.c glibc-2.17-c758a686/csu/elf-init.c
--- glibc-2.17-c758a686/csu/elf-init.c 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/csu/elf-init.c 2012-06-07 12:15:21.570319597 -0600
@@ -63,6 +63,23 @@ extern void (*__init_array_end []) (int,
extern void (*__fini_array_start []) (void) attribute_hidden;
extern void (*__fini_array_end []) (void) attribute_hidden;

+#if defined HAVE_VISIBILITY_ATTRIBUTE \
+ && (defined SHARED || defined LIBC_NONSHARED)
+# define hidden_undef_2(x) #x
+# define hidden_undef_1(x) hidden_undef_2 (x)
+# define hidden_undef(x) \
+ __asm (hidden_undef_1 (ASM_GLOBAL_DIRECTIVE) " " #x); \
+ __asm (".hidden " #x);
+#else
+# define hidden_undef(x)
+#endif
+
+hidden_undef (__preinit_array_start)
+hidden_undef (__preinit_array_end)
+hidden_undef (__init_array_start)
+hidden_undef (__init_array_end)
+hidden_undef (__fini_array_start)
+hidden_undef (__fini_array_end)

/* These function symbols are provided for the .init/.fini section entry
points automagically by the linker. */

15
SOURCES/glibc-fedora-elf-rh737223.patch

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
Binary filesglibc-2.17-c758a686/elf/.rtld.c.rej.swp andglibc-2.17-c758a686/elf/.rtld.c.rej.swp differ
diff -Nru glibc-2.17-c758a686/elf/setup-vdso.h glibc-2.17-c758a686/elf/setup-vdso.h
--- glibc-2.17-c758a686/elf/setup-vdso.h 2012-10-10 21:34:38.000000000 -0600
+++ glibc-2.17-c758a686/elf/setup-vdso.h 2012-10-11 09:43:14.152958832 -0600
@@ -93,7 +93,9 @@ setup_vdso (struct link_map *main_map __
char *copy = malloc (len);
if (copy == NULL)
_dl_fatal_printf ("out of memory\n");
- l->l_libname->name = l->l_name = memcpy (copy, dsoname, len);
+ l->l_libname->name = memcpy (copy, dsoname, len);
+ if (GLRO(dl_debug_mask))
+ l->l_name = copy;
}

/* Add the vDSO to the object list. */

124
SOURCES/glibc-fedora-gai-canonical.patch

@ -0,0 +1,124 @@ @@ -0,0 +1,124 @@
Upstream commit, fixing [BZ #15218]:

commit b957ced8890a4438c8efe2c15e5abf4e327f25cf
Author: Andreas Schwab <schwab@suse.de>
Date: Tue Oct 15 10:21:13 2013 +0200

Don't use gethostbyaddr to determine canonical name


--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c
+++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c
@@ -565,8 +565,8 @@ gaih_inet (const char *name, const struct gaih_service *service,

/* If we do not have to look for IPv6 addresses, use
the simple, old functions, which do not support
- IPv6 scope ids. */
- if (req->ai_family == AF_INET)
+ IPv6 scope ids, nor retrieving the canonical name. */
+ if (req->ai_family == AF_INET && (req->ai_flags & AI_CANONNAME) == 0)
{
/* Allocate additional room for struct host_data. */
size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*)
@@ -1107,70 +1107,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
/* Only the first entry gets the canonical name. */
if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
{
- char *tmpbuf2 = NULL;
- bool malloc_tmpbuf2 = false;
-
if (canon == NULL)
- {
- struct hostent *h = NULL;
- int herrno;
- struct hostent th;
- /* Add room for struct host_data. */
- size_t tmpbuf2len = (512 + (MAX_NR_ALIASES+MAX_NR_ADDRS+1)
- * sizeof(char*) + 16 * sizeof(char));
-
- do
- {
- if (__libc_use_alloca (alloca_used + 2 * tmpbuf2len))
- tmpbuf2 = extend_alloca_account (tmpbuf2, tmpbuf2len,
- tmpbuf2len * 2,
- alloca_used);
- else
- {
- char *newp = realloc (malloc_tmpbuf2 ? tmpbuf2 : NULL,
- 2 * tmpbuf2len);
- if (newp == NULL)
- {
- if (malloc_tmpbuf2)
- free (tmpbuf2);
- result = -EAI_MEMORY;
- goto free_and_return;
- }
-
- tmpbuf2 = newp;
- tmpbuf2len = 2 * tmpbuf2len;
- malloc_tmpbuf2 = true;
- }
-
- rc = __gethostbyaddr_r (at2->addr,
- ((at2->family == AF_INET6)
- ? sizeof (struct in6_addr)
- : sizeof (struct in_addr)),
- at2->family, &th, tmpbuf2,
- tmpbuf2len, &h, &herrno);
- }
- while (rc == ERANGE && herrno == NETDB_INTERNAL);
-
- if (rc != 0 && herrno == NETDB_INTERNAL)
- {
- if (malloc_tmpbuf2)
- free (tmpbuf2);
-
- __set_h_errno (herrno);
- result = -EAI_SYSTEM;
- goto free_and_return;
- }
-
- if (h != NULL)
- canon = h->h_name;
- else
- {
- assert (orig_name != NULL);
- /* If the canonical name cannot be determined, use
- the passed in string. */
- canon = orig_name;
- }
- }
+ /* If the canonical name cannot be determined, use
+ the passed in string. */
+ canon = orig_name;

#ifdef HAVE_LIBIDN
if (req->ai_flags & AI_CANONIDN)
@@ -1185,9 +1125,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
if (rc != IDNA_SUCCESS)
{
- if (malloc_tmpbuf2)
- free (tmpbuf2);
-
if (rc == IDNA_MALLOC_ERROR)
result = -EAI_MEMORY;
else if (rc == IDNA_DLOPEN_ERROR)
@@ -1217,17 +1154,11 @@ gaih_inet (const char *name, const struct gaih_service *service,
canon = strdup (canon);
if (canon == NULL)
{
- if (malloc_tmpbuf2)
- free (tmpbuf2);
-
result = -EAI_MEMORY;
goto free_and_return;
}
}
}
-
- if (malloc_tmpbuf2)
- free (tmpbuf2);
}

family = at2->family;

35
SOURCES/glibc-fedora-getrlimit-PLT.patch

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
Related upstream commit:

commit c5c2b7c3fd823fc5c4a52506292a90eba60b0c62
Author: Joseph Myers <joseph@codesourcery.com>
Date: Sat Dec 6 23:40:48 2014 +0000

Fix pthreads getrlimit, gettimeofday namespace (bug 17682).

--- glibc-2.17-c758a686/include/sys/resource.h
+++ glibc-2.17-c758a686/include/sys/resource.h
@@ -14,5 +14,6 @@ extern int __getrusage (enum __rusage_who __who, struct rusage *__usage)

extern int __setrlimit (enum __rlimit_resource __resource,
const struct rlimit *__rlimits);
+libc_hidden_proto (__getrlimit)
#endif
#endif
--- glibc-2.17-c758a686/resource/getrlimit.c
+++ glibc-2.17-c758a686/resource/getrlimit.c
@@ -27,6 +27,7 @@ __getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits)
__set_errno (ENOSYS);
return -1;
}
+libc_hidden_def (__getrlimit)
weak_alias (__getrlimit, getrlimit)

stub_warning (getrlimit)
--- glibc-2.17-c758a686/sysdeps/mach/hurd/getrlimit.c
+++ glibc-2.17-c758a686/sysdeps/mach/hurd/getrlimit.c
@@ -43,4 +43,5 @@ __getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits)

return 0;
}
+libc_hidden_def (__getrlimit)
weak_alias (__getrlimit, getrlimit)

18
SOURCES/glibc-fedora-i386-tls-direct-seg-refs.patch

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
diff -Nru glibc-2.17-c758a686/sysdeps/i386/Makefile glibc-2.17-c758a686/sysdeps/i386/Makefile
--- glibc-2.17-c758a686/sysdeps/i386/Makefile 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/sysdeps/i386/Makefile 2012-06-07 12:15:21.826318641 -0600
@@ -62,6 +64,14 @@ endif

ifneq (,$(filter -mno-tls-direct-seg-refs,$(CFLAGS)))
defines += -DNO_TLS_DIRECT_SEG_REFS
+else
+# .a libraries are not performance critical and so we
+# build them without direct TLS segment references
+# always.
+CPPFLAGS-.o += -DNO_TLS_DIRECT_SEG_REFS
+CFLAGS-.o += -mno-tls-direct-seg-refs
+CPPFLAGS-.oS += -DNO_TLS_DIRECT_SEG_REFS
+CFLAGS-.oS += -mno-tls-direct-seg-refs
endif

ifeq ($(subdir),elf)

36
SOURCES/glibc-fedora-include-bits-ldbl.patch

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
Only needed for glibc builds with -mlong-double-64:

https://sourceware.org/ml/libc-alpha/2017-08/msg01139.html

This means the patch is no longer needed.

From 5eb4509a6651d19c7a28c4506d6aa582c9ee095a Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 1 Feb 2006 09:30:43 +0000
Subject: [PATCH] 128-bit long double fixes

* include/bits/stdlib-ldbl.h: New file.
* include/bits/wchar-ldbl.h: New file.

---
ChangeLog | 5 +++++
include/bits/stdlib-ldbl.h | 1 +
include/bits/wchar-ldbl.h | 1 +
3 files changed, 7 insertions(+), 0 deletions(-)
create mode 100644 include/bits/stdlib-ldbl.h
create mode 100644 include/bits/wchar-ldbl.h

diff --git glibc-2.17-c758a686/include/bits/stdlib-ldbl.h glibc-2.17-c758a686/include/bits/stdlib-ldbl.h
new file mode 100644
index 0000000..6250949
--- /dev/null
+++ glibc-2.17-c758a686/include/bits/stdlib-ldbl.h
@@ -0,0 +1 @@
+#include <stdlib/bits/stdlib-ldbl.h>
diff --git glibc-2.17-c758a686/include/bits/wchar-ldbl.h glibc-2.17-c758a686/include/bits/wchar-ldbl.h
new file mode 100644
index 0000000..29baa2f
--- /dev/null
+++ glibc-2.17-c758a686/include/bits/wchar-ldbl.h
@@ -0,0 +1 @@
+#include <wcsmbs/bits/wchar-ldbl.h>

38
SOURCES/glibc-fedora-ldd.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
Upstream commit:

commit eedca9772e99c72ab4c3c34e43cc764250aa3e3c (HEAD -> master)
Author: Andreas Schwab <schwab@suse.de>
Date: Wed Aug 16 15:59:55 2017 +0200

ldd: never run file directly

--- glibc-2.17-c758a686/elf/ldd.bash.in
+++ glibc-2.17-c758a686/elf/ldd.bash.in
@@ -166,18 +166,6 @@ warning: you do not have execution permission for" "\`$file'" >&2
fi
done
case $ret in
- 0)
- # If the program exits with exit code 5, it means the process has been
- # invoked with __libc_enable_secure. Fall back to running it through
- # the dynamic linker.
- try_trace "$file"
- rc=$?
- if [ $rc = 5 ]; then
- try_trace "$RTLD" "$file"
- rc=$?
- fi
- [ $rc = 0 ] || result=1
- ;;
1)
# This can be a non-ELF binary or no binary at all.
nonelf "$file" || {
@@ -185,7 +173,7 @@ warning: you do not have execution permission for" "\`$file'" >&2
result=1
}
;;
- 2)
+ 0|2)
try_trace "$RTLD" "$file" || result=1
;;
*)

48
SOURCES/glibc-fedora-linux-tcsetattr.patch

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c 2012-06-07 12:15:21.831318623 -0600
@@ -48,6 +48,7 @@ tcsetattr (fd, optional_actions, termios
{
struct __kernel_termios k_termios;
unsigned long int cmd;
+ int retval;

switch (optional_actions)
{
@@ -79,6 +80,35 @@ tcsetattr (fd, optional_actions, termios
memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
__KERNEL_NCCS * sizeof (cc_t));

- return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
+ retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
+
+ if (retval == 0 && cmd == TCSETS)
+ {
+ /* The Linux kernel has a bug which silently ignore the invalid
+ c_cflag on pty. We have to check it here. */
+ int save = errno;
+ retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
+ if (retval)
+ {
+ /* We cannot verify if the setting is ok. We don't return
+ an error (?). */
+ __set_errno (save);
+ retval = 0;
+ }
+ else if ((termios_p->c_cflag & (PARENB | CREAD))
+ != (k_termios.c_cflag & (PARENB | CREAD))
+ || ((termios_p->c_cflag & CSIZE)
+ && ((termios_p->c_cflag & CSIZE)
+ != (k_termios.c_cflag & CSIZE))))
+ {
+ /* It looks like the Linux kernel silently changed the
+ PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
+ error. */
+ __set_errno (EINVAL);
+ retval = -1;
+ }
+ }
+
+ return retval;
}
libc_hidden_def (tcsetattr)

38
SOURCES/glibc-fedora-localedata-rh61908.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
* Tue Mar 26 2002 Jakub Jelinek <jakub@redhat.com> 2.2.5-28
- add a couple of .ISO-8859-15 locales (#61908)

diff -Nru glibc-2.17-c758a686/localedata/SUPPORTED glibc-2.17-c758a686/localedata/SUPPORTED
--- glibc-2.17-c758a686/localedata/SUPPORTED 2012-11-25 12:59:31.000000000 -0700
+++ glibc-2.17-c758a686/localedata/SUPPORTED 2012-11-26 12:58:43.298223018 -0700
@@ -89,6 +89,7 @@ cy_GB.UTF-8/UTF-8 \
cy_GB/ISO-8859-14 \
da_DK.UTF-8/UTF-8 \
da_DK/ISO-8859-1 \
+da_DK.ISO-8859-15/ISO-8859-15 \
de_AT.UTF-8/UTF-8 \
de_AT/ISO-8859-1 \
de_AT@euro/ISO-8859-15 \
@@ -121,6 +122,7 @@ en_DK.UTF-8/UTF-8 \
en_DK/ISO-8859-1 \
en_GB.UTF-8/UTF-8 \
en_GB/ISO-8859-1 \
+en_GB.ISO-8859-15/ISO-8859-15 \
en_HK.UTF-8/UTF-8 \
en_HK/ISO-8859-1 \
en_IE.UTF-8/UTF-8 \
@@ -136,6 +138,7 @@ en_SG.UTF-8/UTF-8 \
en_SG/ISO-8859-1 \
en_US.UTF-8/UTF-8 \
en_US/ISO-8859-1 \
+en_US.ISO-8859-15/ISO-8859-15 \
en_ZA.UTF-8/UTF-8 \
en_ZA/ISO-8859-1 \
en_ZM/UTF-8 \
@@ -385,6 +388,7 @@ sv_FI/ISO-8859-1 \
sv_FI@euro/ISO-8859-15 \
sv_SE.UTF-8/UTF-8 \
sv_SE/ISO-8859-1 \
+sv_SE.ISO-8859-15/ISO-8859-15 \
sw_KE/UTF-8 \
sw_TZ/UTF-8 \
szl_PL/UTF-8 \

11
SOURCES/glibc-fedora-localedef.patch

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
diff -Nru glibc-2.17-c758a686/localedata/Makefile glibc-2.17-c758a686/localedata/Makefile
--- glibc-2.17-c758a686/localedata/Makefile 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/localedata/Makefile 2012-06-07 12:15:21.776318827 -0600
@@ -211,6 +211,7 @@ $(INSTALL-SUPPORTED-LOCALES): install-lo
echo -n '...'; \
input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \
$(LOCALEDEF) --alias-file=../intl/locale.alias \
+ --no-archive \
-i locales/$$input -c -f charmaps/$$charset \
$(addprefix --prefix=,$(install_root)) $$locale; \
echo ' done'; \

51
SOURCES/glibc-fedora-locarchive.patch

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
This is a part of commit glibc-2.3.3-1492-ga891c7b,
needed for fedora/build-locale-archive.c only.

diff -Nru glibc-2.17-c758a686/ChangeLog.17 glibc-2.17-c758a686/ChangeLog.17
--- glibc-2.17-c758a686/ChangeLog.17 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/ChangeLog.17 2012-06-07 12:15:21.564319619 -0600
@@ -11818,6 +11829,10 @@ d2009-10-30 Ulrich Drepper <drepper@re
[BZ #4368]
* stdlib/stdlib.h: Remove obsolete part of comment for realpath.

+2007-04-16 Jakub Jelinek <jakub@redhat.com>
+
+ * locale/programs/locarchive.c (add_alias, insert_name): Remove static.
+
2007-04-16 Ulrich Drepper <drepper@redhat.com>

[BZ #4364]
diff -Nru glibc-2.17-c758a686/locale/programs/locarchive.c glibc-2.17-c758a686/locale/programs/locarchive.c
--- glibc-2.17-c758a686/locale/programs/locarchive.c 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/locale/programs/locarchive.c 2012-06-07 12:15:21.585319540 -0600
@@ -252,9 +252,9 @@ oldlocrecentcmp (const void *a, const vo
/* forward decls for below */
static uint32_t add_locale (struct locarhandle *ah, const char *name,
locale_data_t data, bool replace);
-static void add_alias (struct locarhandle *ah, const char *alias,
- bool replace, const char *oldname,
- uint32_t *locrec_offset_p);
+void add_alias (struct locarhandle *ah, const char *alias,
+ bool replace, const char *oldname,
+ uint32_t *locrec_offset_p);


static bool
@@ -635,7 +635,7 @@ close_archive (struct locarhandle *ah)
#include "../../intl/explodename.c"
#include "../../intl/l10nflist.c"

-static struct namehashent *
+struct namehashent *
insert_name (struct locarhandle *ah,
const char *name, size_t name_len, bool replace)
{
@@ -693,7 +693,7 @@ insert_name (struct locarhandle *ah,
return &namehashtab[idx];
}

-static void
+void
add_alias (struct locarhandle *ah, const char *alias, bool replace,
const char *oldname, uint32_t *locrec_offset_p)
{

20
SOURCES/glibc-fedora-manual-dircategory.patch

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
From 4820b9175535e13df79ce816106016040014916e Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Fri, 3 Nov 2006 16:31:21 +0000
Subject: [PATCH] Change @dircategory.

---
manual/libc.texinfo | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

--- glibc-2.17-c758a686/manual/libc.texinfo
+++ glibc-2.17-c758a686/manual/libc.texinfo
@@ -7,7 +7,7 @@
@include macros.texi

@comment Tell install-info what to do.
-@dircategory Software libraries
+@dircategory Libraries
@direntry
* Libc: (libc). C library.
@end direntry

21
SOURCES/glibc-fedora-nis-rh188246.patch

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
From baba5d9461d4e8a581ac26fe4412ad783ffc73e7 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Mon, 1 May 2006 08:02:53 +0000
Subject: [PATCH] Enable SETENT_BATCH_READ nis/nss option by default

* Mon May 1 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-4
- SETENT_BATCH_READ /etc/default/nss option for speeding up
some usages of NIS+ (#188246)

diff --git glibc-2.17-c758a686/nis/nss glibc-2.17-c758a686/nis/nss
--- glibc-2.17-c758a686/nis/nss
+++ glibc-2.17-c758a686/nis/nss
@@ -25,7 +25,7 @@
# memory with every getXXent() call. Otherwise each getXXent() call
# might result into a network communication with the server to get
# the next entry.
-#SETENT_BATCH_READ=TRUE
+SETENT_BATCH_READ=TRUE
#
# ADJUNCT_AS_SHADOW
# If set to TRUE, the passwd routines in the NIS NSS module will not

25
SOURCES/glibc-fedora-nptl-linklibc.patch

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
diff -Nru glibc-2.17-c758a686/nptl/Makefile glibc-2.17-c758a686/nptl/Makefile
--- glibc-2.17-c758a686/nptl/Makefile 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/nptl/Makefile 2012-06-07 12:15:21.816318678 -0600
@@ -529,15 +529,19 @@ $(addprefix $(objpfx), \
$(tests) $(xtests) $(test-srcs))): $(objpfx)libpthread.so \
$(objpfx)libpthread_nonshared.a
$(objpfx)tst-unload: $(common-objpfx)dlfcn/libdl.so
-# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
+# $(objpfx)linklibc.so is used instead of $(common-objpfx)libc.so,
# since otherwise libpthread.so comes before libc.so when linking.
$(addprefix $(objpfx), $(tests-reverse)): \
- $(objpfx)../libc.so $(objpfx)libpthread.so \
+ $(objpfx)linklibc.so $(objpfx)libpthread.so \
$(objpfx)libpthread_nonshared.a
$(objpfx)../libc.so: $(common-objpfx)libc.so ;
$(addprefix $(objpfx),$(tests-static) $(xtests-static)): $(objpfx)libpthread.a

$(objpfx)tst-atfork2.out: $(objpfx)tst-atfork2mod.so
+
+$(objpfx)linklibc.so: $(common-objpfx)libc.so
+ ln -s ../libc.so $@
+generated += libclink.so
else
$(addprefix $(objpfx),$(tests) $(test-srcs)): $(objpfx)libpthread.a
endif

12
SOURCES/glibc-fedora-nscd.patch

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
diff -Nru glibc-2.17-c758a686/nscd/nscd.conf glibc-2.17-c758a686/nscd/nscd.conf
--- glibc-2.17-c758a686/nscd/nscd.conf 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/nscd/nscd.conf 2012-06-07 12:15:21.818318670 -0600
@@ -33,7 +33,7 @@
# logfile /var/log/nscd.log
# threads 4
# max-threads 32
-# server-user nobody
+ server-user nscd
# stat-user somebody
debug-level 0
# reload-count 5

23
SOURCES/glibc-fedora-ppc-unwind.patch

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
(This patch is no longer needed because we currently build all of
glibc with -fno-asynchronous-unwind-tables.)

glibc-2.3.3-1478-g37582bc

* Thu Nov 30 2006 Jakub Jelinek <jakub@redhat.com> 2.5.90-9
- on ppc64 build __libc_start_main without unwind info,
as it breaks MD_FROB_UPDATE_CONTEXT (#217729, #217775; in the
future that could be fixable just by providing .cfi_undefined r2
in __libc_start_main instead)

diff -Nru glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile 2012-06-07 12:15:21.828318633 -0600
@@ -35,6 +35,8 @@ CFLAGS-rtld-memmove.os = $(no-special-re
CFLAGS-rtld-memchr.os = $(no-special-regs)
CFLAGS-rtld-strnlen.os = $(no-special-regs)

+CFLAGS-libc-start.c += -fno-asynchronous-unwind-tables
+
ifeq ($(subdir),csu)
sysdep_routines += hp-timing
elide-routines.os += hp-timing

155
SOURCES/glibc-fedora-regcomp-sw11561.patch

@ -0,0 +1,155 @@ @@ -0,0 +1,155 @@
Upstream commit:

commit 7e2f0d2d77e4bc273fe00f99d970605d8e38d4d6
Author: Andreas Schwab <schwab@suse.de>
Date: Mon Feb 4 10:16:33 2013 +0100

Fix handling of collating symbols in regexps

From c1b97d6d896b1f22fdf5d28471ef7859ec840a57 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@redhat.com>
Date: Wed, 1 Sep 2010 17:26:15 +0200
Subject: [PATCH] Fix handling of collating symbols in regexps

[BZ #11561]
* posix/regcomp.c (parse_bracket_exp): When looking up collating
elements compare against the byte sequence of it, not its name.

---
ChangeLog | 4 +++
posix/regcomp.c | 72 ++++++++++++++++++++----------------------------------
2 files changed, 31 insertions(+), 45 deletions(-)

--- glibc-2.17-c758a686/posix/regcomp.c
+++ glibc-2.17-c758a686/posix/regcomp.c
@@ -2772,40 +2772,29 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,

/* Local function for parse_bracket_exp used in _LIBC environement.
Seek the collating symbol entry correspondings to NAME.
- Return the index of the symbol in the SYMB_TABLE. */
+ Return the index of the symbol in the SYMB_TABLE,
+ or -1 if not found. */

auto inline int32_t
__attribute ((always_inline))
- seek_collating_symbol_entry (name, name_len)
- const unsigned char *name;
- size_t name_len;
+ seek_collating_symbol_entry (const unsigned char *name, size_t name_len)
{
- int32_t hash = elem_hash ((const char *) name, name_len);
- int32_t elem = hash % table_size;
- if (symb_table[2 * elem] != 0)
- {
- int32_t second = hash % (table_size - 2) + 1;
-
- do
- {
- /* First compare the hashing value. */
- if (symb_table[2 * elem] == hash
- /* Compare the length of the name. */
- && name_len == extra[symb_table[2 * elem + 1]]
- /* Compare the name. */
- && memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
- name_len) == 0)
- {
- /* Yep, this is the entry. */
- break;
- }
+ int32_t elem;

- /* Next entry. */
- elem += second;
- }
- while (symb_table[2 * elem] != 0);
- }
- return elem;
+ for (elem = 0; elem < table_size; elem++)
+ if (symb_table[2 * elem] != 0)
+ {
+ int32_t idx = symb_table[2 * elem + 1];
+ /* Skip the name of collating element name. */
+ idx += 1 + extra[idx];
+ if (/* Compare the length of the name. */
+ name_len == extra[idx]
+ /* Compare the name. */
+ && memcmp (name, &extra[idx + 1], name_len) == 0)
+ /* Yep, this is the entry. */
+ return elem;
+ }
+ return -1;
}

/* Local function for parse_bracket_exp used in _LIBC environment.
@@ -2814,8 +2803,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,

auto inline unsigned int
__attribute ((always_inline))
- lookup_collation_sequence_value (br_elem)
- bracket_elem_t *br_elem;
+ lookup_collation_sequence_value (bracket_elem_t *br_elem)
{
if (br_elem->type == SB_CHAR)
{
@@ -2843,7 +2831,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
int32_t elem, idx;
elem = seek_collating_symbol_entry (br_elem->opr.name,
sym_name_len);
- if (symb_table[2 * elem] != 0)
+ if (elem != -1)
{
/* We found the entry. */
idx = symb_table[2 * elem + 1];
@@ -2861,7 +2849,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
/* Return the collation sequence value. */
return *(unsigned int *) (extra + idx);
}
- else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
+ else if (sym_name_len == 1)
{
/* No valid character. Match it as a single byte
character. */
@@ -2883,11 +2871,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,

auto inline reg_errcode_t
__attribute ((always_inline))
- build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
- re_charset_t *mbcset;
- int *range_alloc;
- bitset_t sbcset;
- bracket_elem_t *start_elem, *end_elem;
+ build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
+ bracket_elem_t *start_elem, bracket_elem_t *end_elem)
{
unsigned int ch;
uint32_t start_collseq;
@@ -2966,25 +2951,22 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,

auto inline reg_errcode_t
__attribute ((always_inline))
- build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
- re_charset_t *mbcset;
- int *coll_sym_alloc;
- bitset_t sbcset;
- const unsigned char *name;
+ build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
+ int *coll_sym_alloc, const unsigned char *name)
{
int32_t elem, idx;
size_t name_len = strlen ((const char *) name);
if (nrules != 0)
{
elem = seek_collating_symbol_entry (name, name_len);
- if (symb_table[2 * elem] != 0)
+ if (elem != -1)
{
/* We found the entry. */
idx = symb_table[2 * elem + 1];
/* Skip the name of collating element name. */
idx += 1 + extra[idx];
}
- else if (symb_table[2 * elem] == 0 && name_len == 1)
+ else if (name_len == 1)
{
/* No valid character, treat it as a normal
character. */

28
SOURCES/glibc-fedora-streams-rh436349.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
This is part of commit glibc-2.3.3-1564-gd0b6ac6

* Fri Mar 14 2008 Jakub Jelinek <jakub@redhat.com> 2.7.90-11
- remove <stropts.h>, define _XOPEN_STREAMS -1 (#436349)

diff -Nru glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-07 12:15:21.817318674 -0600
@@ -188,4 +188,7 @@
/* Typed memory objects are not available. */
#define _POSIX_TYPED_MEMORY_OBJECTS -1

+/* Streams are not available. */
+#define _XOPEN_STREAMS -1
+
#endif /* bits/posix_opt.h */
diff -Nru glibc-2.17-c758a686/streams/Makefile glibc-2.17-c758a686/streams/Makefile
--- glibc-2.17-c758a686/streams/Makefile 2012-06-05 07:42:49.000000000 -0600
+++ glibc-2.17-c758a686/streams/Makefile 2012-06-07 12:15:21.824318649 -0600
@@ -20,7 +20,7 @@
#
subdir := streams

-headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
+#headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach

include ../Rules

52
SOURCES/glibc-fedora-uname-getrlimit.patch

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
Related upstream commit:

commit c5c2b7c3fd823fc5c4a52506292a90eba60b0c62
Author: Joseph Myers <joseph@codesourcery.com>
Date: Sat Dec 6 23:40:48 2014 +0000

Fix pthreads getrlimit, gettimeofday namespace (bug 17682).

The uname call is again present in Fedora because UTS namespaces can
be used nowadays to change the uname result.

--- glibc-2.17-c758a686/nptl/Version
+++ glibc-2.17-c758a686/nptl/Versions
@@ -30,6 +30,7 @@ libc {
__libc_alloca_cutoff;
# Internal libc interface to libpthread
__libc_dl_error_tsd;
+ __getrlimit;
}
}

--- glibc-2.17-c758a686/nptl/nptl-init.c
+++ glibc-2.17-c758a686/nptl/nptl-init.c
@@ -414,7 +414,7 @@ __pthread_initialize_minimal_internal (void)
/* Determine the default allowed stack size. This is the size used
in case the user does not specify one. */
struct rlimit limit;
- if (getrlimit (RLIMIT_STACK, &limit) != 0
+ if (__getrlimit (RLIMIT_STACK, &limit) != 0
|| limit.rlim_cur == RLIM_INFINITY)
/* The system limit is not usable. Use an architecture-specific
default. */
--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/Versions
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/Versions
@@ -0,0 +1,6 @@
+libc {
+ GLIBC_PRIVATE {
+ # Internal libc interface to libpthread
+ __uname;
+ }
+}
--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/smp.h
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/smp.h
@@ -36,7 +36,7 @@ is_smp_system (void)
char *cp;

/* Try reading the number using `sysctl' first. */
- if (uname (&u.uts) == 0)
+ if (__uname (&u.uts) == 0)
cp = u.uts.version;
else
{

54
SOURCES/glibc-fix-test-write-buf-size.patch

@ -0,0 +1,54 @@ @@ -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/nptl/tst-cancel4.c glibc-2.17-c758a686/nptl/tst-cancel4.c
--- glibc-2.17-c758a686/nptl/tst-cancel4.c 2014-07-25 22:07:09.130021164 -0400
+++ glibc-2.17-c758a686/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;

37
SOURCES/glibc-gmake.patch

@ -0,0 +1,37 @@ @@ -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/configure
--- glibc-2.17-c758a686/configure 2015-01-15 16:32:14.983435268 -0500
+++ glibc-2.17-c758a686/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/configure.in
--- glibc-2.17-c758a686/configure.in 2015-01-15 16:32:14.781441511 -0500
+++ glibc-2.17-c758a686/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.]*\)],

19408
SOURCES/glibc-manual-update.patch

File diff suppressed because it is too large Load Diff

744
SOURCES/glibc-ol7-strstr-sse4.patch

@ -0,0 +1,744 @@ @@ -0,0 +1,744 @@
This patch file contains a backport of the following upstream commits,
which prevent segmentation faults due to unaligned accesses by sse4.2
instructions.

commit 584b18eb4df61ccd447db2dfe8c8a7901f8c8598
Author: Ondej Blka <neleai@seznam.cz>
Date: Sat Dec 14 19:33:56 2

Add strstr with unaligned loads. Fixes bug 12100.

A sse42 version of strstr used pcmpistr instruction which is quite
ineffective. A faster way is look for pairs of characters which is uses
sse2, is faster than pcmpistr and for real strings a pairs we look for
are relatively rare.

For linear time complexity we use buy or rent technique which switches
to two-way algorithm when superlinear behaviour is detected.

commit 1818483b15d22016b0eae41d37ee91cc87b37510
Author: Andreas Schwab <schwab@suse.de>
Date: Wed Dec 18 11:53:27

Remove use of SSE4.2 functions for strstr on i686

The SSE4.2 have been removed from x86_64 by commit 584b18eb. This patch
fixes the build on i686, which attempts to use the removed files.

diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/ifunc-impl-list.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/ifunc-impl-list.c
--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/ifunc-impl-list.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/ifunc-impl-list.c 2014-07-01 05:38:25.138749032 -0400
@@ -141,12 +141,6 @@
IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
__strcasecmp_l_ia32))

- /* Support sysdeps/i386/i686/multiarch/strcasestr.c. */
- IFUNC_IMPL (i, name, strcasestr,
- IFUNC_IMPL_ADD (array, i, strcasestr, HAS_SSE4_2,
- __strcasestr_sse42)
- IFUNC_IMPL_ADD (array, i, strcasestr, 1, __strcasestr_ia32))
-
/* Support sysdeps/i386/i686/multiarch/strcat.S. */
IFUNC_IMPL (i, name, strcat,
IFUNC_IMPL_ADD (array, i, strcat, HAS_SSSE3, __strcat_ssse3)
@@ -234,11 +228,6 @@
IFUNC_IMPL_ADD (array, i, strspn, HAS_SSE4_2, __strspn_sse42)
IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_ia32))

- /* Support sysdeps/i386/i686/multiarch/strstr-c.c. */
- IFUNC_IMPL (i, name, strstr,
- IFUNC_IMPL_ADD (array, i, strstr, HAS_SSE4_2, __strstr_sse42)
- IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_ia32))
-
/* Support sysdeps/i386/i686/multiarch/wcschr.S. */
IFUNC_IMPL (i, name, wcschr,
IFUNC_IMPL_ADD (array, i, wcschr, HAS_SSE2, __wcschr_sse2)
diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/Makefile glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/Makefile
--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/Makefile 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/Makefile 2014-07-01 05:37:15.985617738 -0400
@@ -11,7 +11,7 @@
memmove-ssse3-rep bcopy-ssse3 bcopy-ssse3-rep \
memset-sse2-rep bzero-sse2-rep strcmp-ssse3 \
strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
- memcmp-ssse3 memcmp-sse4 strcasestr-nonascii varshift \
+ memcmp-ssse3 memcmp-sse4 varshift \
strlen-sse2 strlen-sse2-bsf strncpy-c strcpy-ssse3 \
strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 strcpy-sse2 \
strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \
@@ -25,14 +25,11 @@
strncase_l-c strncase-c strncase_l-ssse3 \
strcasecmp_l-sse4 strncase_l-sse4
ifeq (yes,$(config-cflags-sse4))
-sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c
+sysdep_routines += strcspn-c strpbrk-c strspn-c
CFLAGS-varshift.c += -msse4
CFLAGS-strcspn-c.c += -msse4
CFLAGS-strpbrk-c.c += -msse4
CFLAGS-strspn-c.c += -msse4
-CFLAGS-strstr.c += -msse4
-CFLAGS-strcasestr.c += -msse4
-CFLAGS-strcasestr-nonascii.c += -msse4
endif
endif

diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasestr.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strcasestr.c
--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasestr.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strcasestr.c 1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include <sysdeps/x86_64/multiarch/strcasestr.c>
diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c
--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-#include <nmmintrin.h>
-#include <sysdeps/x86_64/multiarch/strcasestr-nonascii.c>
diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strstr.c
--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strstr.c 1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include <sysdeps/x86_64/multiarch/strstr.c>
diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr-c.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strstr-c.c
--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr-c.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strstr-c.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-/* Multiple versions of strstr
- All versions must be listed in ifunc-impl-list.c. */
-
-#define STRSTR __strstr_ia32
-#if defined SHARED && defined DO_VERSIONING && !defined NO_HIDDEN
-#undef libc_hidden_builtin_def
-#define libc_hidden_builtin_def(name) \
- __hidden_ver1 (__strstr_ia32, __GI_strstr, __strstr_ia32);
-#endif
-
-/* Redefine strstr so that the compiler won't complain about the type
- mismatch with the IFUNC selector in strong_alias, below. */
-#undef strstr
-#define strstr __redirect_strstr
-
-#include "string/strstr.c"
-
-#include "init-arch.h"
-
-extern __typeof (__redirect_strstr) __strstr_sse42 attribute_hidden;
-extern __typeof (__redirect_strstr) __strstr_ia32 attribute_hidden;
-
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
- ifunc symbol properly. */
-extern __typeof (__redirect_strstr) __libc_strstr;
-libc_ifunc (__libc_strstr,
- HAS_SSE4_2 && !use_unaligned_strstr () ?
- __strstr_sse42 : __strstr_ia32)
-
-#undef strstr
-strong_alias (__libc_strstr, strstr)
diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/ifunc-impl-list.c
--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/ifunc-impl-list.c 2014-06-30 10:58:16.637073138 -0400
@@ -115,8 +115,6 @@

/* Support sysdeps/x86_64/multiarch/strcasestr.c. */
IFUNC_IMPL (i, name, strcasestr,
- IFUNC_IMPL_ADD (array, i, strcasestr, HAS_SSE4_2,
- __strcasestr_sse42)
IFUNC_IMPL_ADD (array, i, strcasestr, 1, __strcasestr_sse2))

/* Support sysdeps/x86_64/multiarch/strcat.S. */
@@ -210,9 +210,7 @@

/* Support sysdeps/x86_64/multiarch/strstr-c.c. */
IFUNC_IMPL (i, name, strstr,
- IFUNC_IMPL_ADD (array, i, strstr, use_unaligned_strstr (),
- __strstr_sse2_unaligned)
- IFUNC_IMPL_ADD (array, i, strstr, HAS_SSE4_2, __strstr_sse42)
+ IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_sse2_unaligned)
IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_sse2))

/* Support sysdeps/x86_64/multiarch/wcscpy.S. */
diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/Makefile
--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/Makefile 2014-06-30 10:55:08.343714449 -0400
@@ -9,7 +9,7 @@
sysdep_routines += strncat-c stpncpy-c strncpy-c strcmp-ssse3 strncmp-ssse3 \
strend-sse4 memcmp-sse4 memcpy-ssse3 mempcpy-ssse3 \
memmove-ssse3 memcpy-ssse3-back mempcpy-ssse3-back \
- memmove-ssse3-back strcasestr-nonascii strcasecmp_l-ssse3 \
+ memmove-ssse3-back strcasecmp_l-ssse3 \
strncase_l-ssse3 strlen-sse4 strlen-sse2-no-bsf memset-x86-64 \
strcpy-ssse3 strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 \
strcpy-sse2-unaligned strncpy-sse2-unaligned \
@@ -17,14 +17,11 @@
strnlen-sse2-no-bsf strrchr-sse2-no-bsf strchr-sse2-no-bsf \
memcmp-ssse3 strstr-sse2-unaligned
ifeq (yes,$(config-cflags-sse4))
-sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c varshift
+sysdep_routines += strcspn-c strpbrk-c strspn-c varshift
CFLAGS-varshift.c += -msse4
CFLAGS-strcspn-c.c += -msse4
CFLAGS-strpbrk-c.c += -msse4
CFLAGS-strspn-c.c += -msse4
-CFLAGS-strstr.c += -msse4
-CFLAGS-strcasestr.c += -msse4
-CFLAGS-strcasestr-nonascii.c += -msse4
endif
endif

diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr.c
--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr.c 2014-06-30 11:01:34.394453519 -0400
@@ -1,7 +1,13 @@
-extern char *__strcasestr_sse42_nonascii (const unsigned char *s1,
- const unsigned char *s2)
- attribute_hidden;
+/* Multiple versions of strcasestr
+ All versions must be listed in ifunc-impl-list.c. */

-#define USE_AS_STRCASESTR
-#define STRSTR_SSE42 __strcasestr_sse42
-#include "strstr.c"
+#include "init-arch.h"
+
+#define STRCASESTR __strcasestr_sse2
+
+#include "string/strcasestr.c"
+
+extern __typeof (__strcasestr_sse2) __strcasestr_sse2 attribute_hidden;
+
+libc_ifunc (__strcasestr,
+ __strcasestr_sse2);
diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-c.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr-c.c
--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-c.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr-c.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-/* Multiple versions of strcasestr
- All versions must be listed in ifunc-impl-list.c. */
-
-#include "init-arch.h"
-
-#define STRCASESTR __strcasestr_sse2
-
-#include "string/strcasestr.c"
-
-extern char *__strcasestr_sse42 (const char *, const char *) attribute_hidden;
-extern __typeof (__strcasestr_sse2) __strcasestr_sse2 attribute_hidden;
-
-#if 1
-libc_ifunc (__strcasestr,
- HAS_SSE4_2 && !use_unaligned_strstr () ? __strcasestr_sse42 :
- __strcasestr_sse2);
-#else
-libc_ifunc (__strcasestr,
- 0 ? __strcasestr_sse42 : __strcasestr_sse2);
-#endif
diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-nonascii.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr-nonascii.c
--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-nonascii.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr-nonascii.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/* strstr with SSE4.2 intrinsics
- Copyright (C) 2010 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 <ctype.h>
-#include <xmmintrin.h>
-
-
-/* Similar to __m128i_strloadu. Convert to lower case for none-POSIX/C
- locale. */
-static inline __m128i
-__m128i_strloadu_tolower (const unsigned char *p)
-{
- union
- {
- char b[16];
- __m128i x;
- } u;
-
- for (int i = 0; i < 16; ++i)
- if (p[i] == 0)
- {
- u.b[i] = 0;
- break;
- }
- else
- u.b[i] = tolower (p[i]);
-
- return u.x;
-}
-
-
-#define STRCASESTR_NONASCII
-#define USE_AS_STRCASESTR
-#define STRSTR_SSE42 __strcasestr_sse42_nonascii
-#include "strstr.c"
diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strstr.c
--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strstr.c 2014-06-30 11:26:55.025294484 -0400
@@ -1,6 +1,6 @@
-/* strstr with SSE4.2 intrinsics
- Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
- Contributed by Intel Corporation.
+/* Multiple versions of strstr.
+ All versions must be listed in ifunc-impl-list.c.
+ 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
@@ -17,368 +17,32 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */

-#include <nmmintrin.h>
-#include "varshift.h"
-
-#ifndef STRSTR_SSE42
-# define STRSTR_SSE42 __strstr_sse42
-#endif
-
-#ifdef USE_AS_STRCASESTR
-# include <ctype.h>
-# include <locale/localeinfo.h>
-
-# define LOADBYTE(C) tolower (C)
-# define CMPBYTE(C1, C2) (tolower (C1) == tolower (C2))
-#else
-# define LOADBYTE(C) (C)
-# define CMPBYTE(C1, C2) ((C1) == (C2))
+/* Redefine strstr so that the compiler won't complain about the type
+ mismatch with the IFUNC selector in strong_alias, below. */
+#undef strstr
+#define strstr __redirect_strstr
+#include <string.h>
+#undef strstr
+
+#define STRSTR __strstr_sse2
+#ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1 (__strstr_sse2, __GI_strstr, __strstr_sse2);
#endif

-/* We use 0xe ordered-compare:
- _SIDD_SBYTE_OPS
- | _SIDD_CMP_EQUAL_ORDER
- | _SIDD_LEAST_SIGNIFICANT
- on pcmpistri to do the scanning and string comparsion requirements of
- sub-string match. In the scanning phase, we process Cflag and ECX
- index to locate the first fragment match; once the first fragment
- match position has been identified, we do comparison of subsequent
- string fragments until we can conclude false or true match; whe
- n concluding a false match, we may need to repeat scanning process
- from next relevant offset in the target string.
-
- In the scanning phase we have 4 cases:
- case ECX CFlag ZFlag SFlag
- 1 16 0 0 0
- 2a 16 0 0 1
- 2b 16 0 1 0
- 2c 16 0 1 1
-
- 1. No ordered-comparison match, both 16B fragments are valid, so
- continue to next fragment.
- 2. No ordered-comparison match, there is EOS in either fragment,
- 2a. Zflg = 0, Sflg = 1, we continue
- 2b. Zflg = 1, Sflg = 0, we conclude no match and return.
- 2c. Zflg = 1, sflg = 1, lenth determine match or no match
-
- In the string comparison phase, the 1st fragment match is fixed up
- to produce ECX = 0. Subsequent fragment compare of nonzero index
- and no match conclude a false match.
-
- case ECX CFlag ZFlag SFlag
- 3 X 1 0 0/1
- 4a 0 1 0 0
- 4b 0 1 0 1
- 4c 0 < X 1 0 0/1
- 5 16 0 1 0
-
- 3. An initial ordered-comparison fragment match, we fix up to do
- subsequent string comparison
- 4a. Continuation of fragment comparison of a string compare.
- 4b. EOS reached in the reference string, we conclude true match and
- return
- 4c. String compare failed if index is nonzero, we need to go back to
- scanning
- 5. failed string compare, go back to scanning
- */
-
-/* Simple replacement of movdqu to address 4KB boundary cross issue.
- If EOS occurs within less than 16B before 4KB boundary, we don't
- cross to next page. */
-
-static inline __m128i
-__m128i_strloadu (const unsigned char * p, __m128i zero)
-{
- if (__builtin_expect ((int) ((size_t) p & 0xfff) > 0xff0, 0))
- {
- size_t offset = ((size_t) p & (16 - 1));
- __m128i a = _mm_load_si128 ((__m128i *) (p - offset));
- int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (a, zero));
- if ((bmsk >> offset) != 0)
- return __m128i_shift_right (a, offset);
- }
- return _mm_loadu_si128 ((__m128i *) p);
-}
-
-#if defined USE_AS_STRCASESTR && !defined STRCASESTR_NONASCII
-
-/* Similar to __m128i_strloadu. Convert to lower case for POSIX/C
- locale and other which have single-byte letters only in the ASCII
- range. */
-static inline __m128i
-__m128i_strloadu_tolower (const unsigned char *p, __m128i zero, __m128i uclow,
- __m128i uchigh, __m128i lcqword)
-{
- __m128i frag = __m128i_strloadu (p, zero);
-
- /* Compare if 'Z' > bytes. Inverted way to get a mask for byte <= 'Z'. */
- __m128i r2 = _mm_cmpgt_epi8 (uchigh, frag);
- /* Compare if bytes are > 'A' - 1. */
- __m128i r1 = _mm_cmpgt_epi8 (frag, uclow);
- /* Mask byte == ff if byte(r2) <= 'Z' and byte(r1) > 'A' - 1. */
- __m128i mask = _mm_and_si128 (r2, r1);
- /* Apply lowercase bit 6 mask for above mask bytes == ff. */
- return _mm_or_si128 (frag, _mm_and_si128 (mask, lcqword));
-}
+#include "string/strstr.c"

-#endif
+extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_strstr) __strstr_sse2 attribute_hidden;

-/* Calculate Knuth-Morris-Pratt string searching algorithm (or KMP
- algorithm) overlap for a fully populated 16B vector.
- Input parameter: 1st 16Byte loaded from the reference string of a
- strstr function.
- We don't use KMP algorithm if reference string is less than 16B. */
-static int
-__inline__ __attribute__ ((__always_inline__,))
-KMP16Bovrlap (__m128i s2)
-{
- __m128i b = _mm_unpacklo_epi8 (s2, s2);
- __m128i a = _mm_unpacklo_epi8 (b, b);
- a = _mm_shuffle_epi32 (a, 0);
- b = _mm_srli_si128 (s2, sizeof (char));
- int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (b, a));
-
- /* _BitScanForward(&k1, bmsk); */
- int k1;
- __asm ("bsfl %[bmsk], %[k1]" : [k1] "=r" (k1) : [bmsk] "r" (bmsk));
- if (!bmsk)
- return 16;
- else if (bmsk == 0x7fff)
- return 1;
- else if (!k1)
- {
- /* There are al least two distinct chars in s2. If byte 0 and 1 are
- idential and the distinct value lies farther down, we can deduce
- the next byte offset to restart full compare is least no earlier
- than byte 3. */
- return 3;
- }
- else
- {
- /* Byte 1 is not degenerated to byte 0. */
- return k1 + 1;
- }
-}
-
-char *
-__attribute__ ((section (".text.sse4.2")))
-STRSTR_SSE42 (const unsigned char *s1, const unsigned char *s2)
-{
-#define p1 s1
- const unsigned char *p2 = s2;
-
-#ifndef STRCASESTR_NONASCII
- if (__builtin_expect (p2[0] == '\0', 0))
- return (char *) p1;
-
- if (__builtin_expect (p1[0] == '\0', 0))
- return NULL;
-
- /* Check if p1 length is 1 byte long. */
- if (__builtin_expect (p1[1] == '\0', 0))
- return p2[1] == '\0' && CMPBYTE (p1[0], p2[0]) ? (char *) p1 : NULL;
-#endif
+#include "init-arch.h"

-#ifdef USE_AS_STRCASESTR
-# ifndef STRCASESTR_NONASCII
- if (__builtin_expect (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_NONASCII_CASE)
- != 0, 0))
- return __strcasestr_sse42_nonascii (s1, s2);
-
- const __m128i uclow = _mm_set1_epi8 (0x40);
- const __m128i uchigh = _mm_set1_epi8 (0x5b);
- const __m128i lcqword = _mm_set1_epi8 (0x20);
- const __m128i zero = _mm_setzero_si128 ();
-# define strloadu(p) __m128i_strloadu_tolower (p, zero, uclow, uchigh, lcqword)
-# else
-# define strloadu __m128i_strloadu_tolower
-# define zero _mm_setzero_si128 ()
-# endif
-#else
-# define strloadu(p) __m128i_strloadu (p, zero)
- const __m128i zero = _mm_setzero_si128 ();
-#endif
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+extern __typeof (__redirect_strstr) __libc_strstr;
+libc_ifunc (__libc_strstr, HAS_FAST_UNALIGNED_LOAD ? __strstr_sse2_unaligned : __strstr_sse2)

- /* p1 > 1 byte long. Load up to 16 bytes of fragment. */
- __m128i frag1 = strloadu (p1);

- __m128i frag2;
- if (p2[1] != '\0')
- /* p2 is > 1 byte long. */
- frag2 = strloadu (p2);
- else
- frag2 = _mm_insert_epi8 (zero, LOADBYTE (p2[0]), 0);
-
- /* Unsigned bytes, equal order, does frag2 has null? */
- int cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c);
- int cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c);
- int cmp = _mm_cmpistri (frag2, frag1, 0x0c);
- int cmp_s = _mm_cmpistrs (frag2, frag1, 0x0c);
- if (cmp_s & cmp_c)
- {
- int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (frag2, zero));
- int len;
- __asm ("bsfl %[bmsk], %[len]"
- : [len] "=r" (len) : [bmsk] "r" (bmsk));
- p1 += cmp;
- if ((len + cmp) <= 16)
- return (char *) p1;
-
- /* Load up to 16 bytes of fragment. */
- frag1 = strloadu (p1);
- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c);
- cmp_s = _mm_cmpistrs (frag2, frag1, 0x0c);
- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c);
- cmp = _mm_cmpistri (frag2, frag1, 0x0c);
- if ((len + cmp) <= 16)
- return (char *) p1 + cmp;
- }
-
- if (cmp_s)
- {
- /* Adjust addr for 16B alginment in ensuing loop. */
- while (!cmp_z)
- {
- p1 += cmp;
- /* Load up to 16 bytes of fragment. */
- frag1 = strloadu (p1);
- cmp = _mm_cmpistri (frag2, frag1, 0x0c);
- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c);
- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c);
- /* Because s2 < 16 bytes and we adjusted p1 by non-zero cmp
- once already, this time cmp will be zero and we can exit. */
- if ((!cmp) & cmp_c)
- break;
- }
-
- if (!cmp_c)
- return NULL;
-
- /* Since s2 is less than 16 bytes, com_c is definitive
- determination of full match. */
- return (char *) p1 + cmp;
- }
-
- /* General case, s2 is at least 16 bytes or more.
- First, the common case of false-match at first byte of p2. */
- const unsigned char *pt = NULL;
- int kmp_fwd = 0;
-re_trace:
- while (!cmp_c)
- {
- /* frag1 has null. */
- if (cmp_z)
- return NULL;
-
- /* frag 1 has no null, advance 16 bytes. */
- p1 += 16;
- /* Load up to 16 bytes of fragment. */
- frag1 = strloadu (p1);
- /* Unsigned bytes, equal order, is there a partial match? */
- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c);
- cmp = _mm_cmpistri (frag2, frag1, 0x0c);
- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c);
- }
-
- /* Next, handle initial positive match as first byte of p2. We have
- a partial fragment match, make full determination until we reached
- end of s2. */
- if (!cmp)
- {
- if (cmp_z)
- return (char *) p1;
-
- pt = p1;
- p1 += 16;
- p2 += 16;
- /* Load up to 16 bytes of fragment. */
- frag2 = strloadu (p2);
- }
- else
- {
- /* Adjust 16B alignment. */
- p1 += cmp;
- pt = p1;
- }
-
- /* Load up to 16 bytes of fragment. */
- frag1 = strloadu (p1);
-
- /* Unsigned bytes, equal order, does frag2 has null? */
- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c);
- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c);
- cmp = _mm_cmpistri (frag2, frag1, 0x0c);
- cmp_s = _mm_cmpistrs (frag2, frag1, 0x0c);
- while (!(cmp | cmp_z | cmp_s))
- {
- p1 += 16;
- p2 += 16;
- /* Load up to 16 bytes of fragment. */
- frag2 = strloadu (p2);
- /* Load up to 16 bytes of fragment. */
- frag1 = strloadu (p1);
- /* Unsigned bytes, equal order, does frag2 has null? */
- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c);
- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c);
- cmp = _mm_cmpistri (frag2, frag1, 0x0c);
- cmp_s = _mm_cmpistrs (frag2, frag1, 0x0c);
- }
-
- /* Full determination yielded a false result, retrace s1 to next
- starting position.
- Zflg 1 0 1 0/1
- Sflg 0 1 1 0/1
- cmp na 0 0 >0
- action done done continue continue if s2 < s1
- false match retrace s1 else false
- */
-
- if (cmp_s & !cmp)
- return (char *) pt;
- if (cmp_z)
- {
- if (!cmp_s)
- return NULL;
-
- /* Handle both zero and sign flag set and s1 is shorter in
- length. */
- int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (zero, frag2));
- int bmsk1 = _mm_movemask_epi8 (_mm_cmpeq_epi8 (zero, frag1));
- int len;
- int len1;
- __asm ("bsfl %[bmsk], %[len]"
- : [len] "=r" (len) : [bmsk] "r" (bmsk));
- __asm ("bsfl %[bmsk1], %[len1]"
- : [len1] "=r" (len1) : [bmsk1] "r" (bmsk1));
- if (len >= len1)
- return NULL;
- }
- else if (!cmp)
- return (char *) pt;
-
- /* Otherwise, we have to retrace and continue. Default of multiple
- paths that need to retrace from next byte in s1. */
- p2 = s2;
- frag2 = strloadu (p2);
-
- if (!kmp_fwd)
- kmp_fwd = KMP16Bovrlap (frag2);
-
- /* KMP algorithm predicted overlap needs to be corrected for
- partial fragment compare. */
- p1 = pt + (kmp_fwd > cmp ? cmp : kmp_fwd);
-
- /* Since s2 is at least 16 bytes long, we're certain there is no
- match. */
- if (p1[0] == '\0')
- return NULL;
-
- /* Load up to 16 bytes of fragment. */
- frag1 = strloadu (p1);
-
- /* Unsigned bytes, equal order, is there a partial match? */
- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c);
- cmp = _mm_cmpistri (frag2, frag1, 0x0c);
- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c);
- goto re_trace;
-}
+#undef strstr
+strong_alias (__libc_strstr, strstr)
diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strstr-c.c
--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strstr-c.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/* Multiple versions of strstr.
- All versions must be listed in ifunc-impl-list.c.
- 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/>. */
-
-/* Redefine strstr so that the compiler won't complain about the type
- mismatch with the IFUNC selector in strong_alias, below. */
-#undef strstr
-#define strstr __redirect_strstr
-#include <string.h>
-#undef strstr
-
-#define STRSTR __strstr_sse2
-#ifdef SHARED
-# undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name) \
- __hidden_ver1 (__strstr_sse2, __GI_strstr, __strstr_sse2);
-#endif
-
-#include "string/strstr.c"
-
-extern __typeof (__redirect_strstr) __strstr_sse42 attribute_hidden;
-extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden;
-extern __typeof (__redirect_strstr) __strstr_sse2 attribute_hidden;
-
-#include "init-arch.h"
-
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
- ifunc symbol properly. */
-extern __typeof (__redirect_strstr) __libc_strstr;
-libc_ifunc (__libc_strstr, HAS_SSE4_2 ? (use_unaligned_strstr () ?
- __strstr_sse2_unaligned :
- __strstr_sse42) : __strstr_sse2)
-
-#undef strstr
-strong_alias (__libc_strstr, strstr)

13
SOURCES/glibc-powerpc-ldbl_high.patch

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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

83
SOURCES/glibc-ppc64le-01.patch

@ -0,0 +1,83 @@ @@ -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/Makerules glibc-2.17-c758a686/Makerules
--- glibc-2.17-c758a686/Makerules 2014-06-02 15:29:42.000000000 +0000
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/Makefile glibc-2.17-c758a686/sysdeps/powerpc/Makefile
--- glibc-2.17-c758a686/sysdeps/powerpc/Makefile 2014-06-02 15:29:42.000000000 +0000
+++ glibc-2.17-c758a686/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

3197
SOURCES/glibc-ppc64le-02.patch

File diff suppressed because it is too large Load Diff

1617
SOURCES/glibc-ppc64le-03.patch

File diff suppressed because it is too large Load Diff

676
SOURCES/glibc-ppc64le-04.patch

@ -0,0 +1,676 @@ @@ -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/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_expl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_expl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_expl.c 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/ieee754.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/strtold_l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/strtold_l.c 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c 2014-05-26 21:08:01.000000000 -0500
+++ glibc-2.17-c758a686/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
{

486
SOURCES/glibc-ppc64le-05.patch

@ -0,0 +1,486 @@ @@ -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/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c 2014-05-27 19:13:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c 2014-05-27 19:13:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 19:13:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c 2014-05-27 19:13:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-27 19:13:56.000000000 -0500
+++ glibc-2.17-c758a686/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) \

652
SOURCES/glibc-ppc64le-06.patch

@ -0,0 +1,652 @@ @@ -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/math/test-misc.c glibc-2.17-c758a686/math/test-misc.c
--- glibc-2.17-c758a686/math/test-misc.c 2014-05-27 19:53:22.000000000 -0500
+++ glibc-2.17-c758a686/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/ports/sysdeps/ia64/fpu/printf_fphex.c glibc-2.17-c758a686/ports/sysdeps/ia64/fpu/printf_fphex.c
--- glibc-2.17-c758a686/ports/sysdeps/ia64/fpu/printf_fphex.c 2014-05-27 19:53:21.000000000 -0500
+++ glibc-2.17-c758a686/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/stdio-common/printf_fp.c glibc-2.17-c758a686/stdio-common/printf_fp.c
--- glibc-2.17-c758a686/stdio-common/printf_fp.c 2014-05-27 19:53:22.000000000 -0500
+++ glibc-2.17-c758a686/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/stdio-common/printf_fphex.c glibc-2.17-c758a686/stdio-common/printf_fphex.c
--- glibc-2.17-c758a686/stdio-common/printf_fphex.c 2014-05-27 19:53:22.000000000 -0500
+++ glibc-2.17-c758a686/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/stdio-common/printf_size.c glibc-2.17-c758a686/stdio-common/printf_size.c
--- glibc-2.17-c758a686/stdio-common/printf_size.c 2014-05-27 19:53:22.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128/printf_fphex.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128/printf_fphex.c 2014-05-27 19:53:20.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-27 19:53:20.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-96/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-96/printf_fphex.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-96/printf_fphex.c 2014-05-27 19:53:20.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/x86_64/fpu/printf_fphex.c glibc-2.17-c758a686/sysdeps/x86_64/fpu/printf_fphex.c
--- glibc-2.17-c758a686/sysdeps/x86_64/fpu/printf_fphex.c 2014-05-27 19:53:20.000000000 -0500
+++ glibc-2.17-c758a686/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) \
{ \

651
SOURCES/glibc-ppc64le-07.patch

@ -0,0 +1,651 @@ @@ -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/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_acosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acosl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acosl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_asinl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_asinl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_asinl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_coshl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_coshl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_coshl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_log2l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log2l.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log2l.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/k_cosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_cosl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_cosl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/k_sinl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sinl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sinl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_atanl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_atanl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_atanl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_cosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_cosl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_cosl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_finitel.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_finitel.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_finitel.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_logbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_sinl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sinl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sinl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_tanl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c 2014-05-27 19:58:07.000000000 -0500
+++ glibc-2.17-c758a686/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. */

1235
SOURCES/glibc-ppc64le-08.patch

File diff suppressed because it is too large Load Diff

567
SOURCES/glibc-ppc64le-09.patch

@ -0,0 +1,567 @@ @@ -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/math/libm-test.inc glibc-2.17-c758a686/math/libm-test.inc
--- glibc-2.17-c758a686/math/libm-test.inc 2014-05-27 20:02:29.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c 2014-05-27 20:02:27.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c 2014-05-27 20:02:27.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c 2014-05-27 20:02:27.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/s_erfl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c 2014-05-27 20:02:27.000000000 -0500
+++ glibc-2.17-c758a686/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;

91
SOURCES/glibc-ppc64le-10.patch

@ -0,0 +1,91 @@ @@ -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/sysdeps/ieee754/ldbl-128ibm/ieee754.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h 2014-05-27 22:10:43.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 22:10:43.000000000 -0500
+++ glibc-2.17-c758a686/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

113
SOURCES/glibc-ppc64le-11.patch

@ -0,0 +1,113 @@ @@ -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/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c
--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c 2014-05-27 22:20:12.000000000 -0500
+++ glibc-2.17-c758a686/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)

74
SOURCES/glibc-ppc64le-12.patch

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
# 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/sysdeps/powerpc/fpu/bits/mathinline.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/bits/mathinline.h
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/bits/mathinline.h 2014-05-27 22:28:12.000000000 -0500
+++ glibc-2.17-c758a686/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

283
SOURCES/glibc-ppc64le-13.patch

@ -0,0 +1,283 @@ @@ -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/sysdeps/powerpc/fpu/e_sqrt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrt.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrt.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/e_sqrtf.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrtf.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrtf.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/fclrexcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fclrexcpt.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fclrexcpt.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/fedisblxcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fedisblxcpt.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fedisblxcpt.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/feenablxcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/feenablxcpt.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/feenablxcpt.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/fegetexcept.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fegetexcept.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fegetexcept.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/feholdexcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/feholdexcpt.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/feholdexcpt.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/fenv_libc.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/fenv_libc.h
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fenv_libc.h 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/fesetenv.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fesetenv.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fesetenv.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/feupdateenv.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/feupdateenv.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/feupdateenv.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/fgetexcptflg.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fgetexcptflg.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fgetexcptflg.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/fraiseexcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fraiseexcpt.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fraiseexcpt.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/fsetexcptflg.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fsetexcptflg.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fsetexcptflg.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/ftestexcept.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/ftestexcept.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/ftestexcept.c 2014-05-27 22:31:42.000000000 -0500
+++ glibc-2.17-c758a686/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)

120
SOURCES/glibc-ppc64le-14.patch

@ -0,0 +1,120 @@ @@ -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/sysdeps/powerpc/fpu/s_float_bitwise.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_float_bitwise.h
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_float_bitwise.h 2014-05-27 22:37:18.000000000 -0500
+++ glibc-2.17-c758a686/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

119
SOURCES/glibc-ppc64le-15.patch

@ -0,0 +1,119 @@ @@ -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/sysdeps/powerpc/fpu/s_llround.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2014-05-27 22:38:55.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/s_llroundf.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c 2014-05-27 22:38:55.000000000 -0500
+++ glibc-2.17-c758a686/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)

163
SOURCES/glibc-ppc64le-16.patch

@ -0,0 +1,163 @@ @@ -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/sysdeps/powerpc/fpu/fpu_control.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h 2014-05-27 22:40:18.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c 2014-05-27 22:40:18.000000000 -0500
+++ glibc-2.17-c758a686/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)
{

312
SOURCES/glibc-ppc64le-17.patch

@ -0,0 +1,312 @@ @@ -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/sysdeps/powerpc/powerpc32/fpu/s_copysign.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysign.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysign.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/fpu/s_lrint.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lrint.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/fpu/s_lround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lround.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lround.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h
--- glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h 2014-05-27 22:45:44.000000000 -0500
+++ glibc-2.17-c758a686/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

81
SOURCES/glibc-ppc64le-18.patch

@ -0,0 +1,81 @@ @@ -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/sysdeps/powerpc/powerpc32/fpu/s_roundf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_roundf.S 2014-05-27 22:50:13.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S 2014-05-27 22:50:13.000000000 -0500
+++ glibc-2.17-c758a686/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

110
SOURCES/glibc-ppc64le-19.patch

@ -0,0 +1,110 @@ @@ -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/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S 2014-05-27 22:52:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/fpu/s_floorf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_floorf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_floorf.S 2014-05-27 22:52:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S 2014-05-27 22:52:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/fpu/s_rintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S 2014-05-27 22:52:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/fpu/s_roundf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_roundf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_roundf.S 2014-05-27 22:52:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/fpu/s_truncf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_truncf.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_truncf.S 2014-05-27 22:52:12.000000000 -0500
+++ glibc-2.17-c758a686/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])

41
SOURCES/glibc-ppc64le-20.patch

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
# 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/sysdeps/powerpc/powerpc32/power4/hp-timing.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h 2014-05-27 22:53:37.000000000 -0500
+++ glibc-2.17-c758a686/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)

294
SOURCES/glibc-ppc64le-21.patch

@ -0,0 +1,294 @@ @@ -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/sysdeps/powerpc/jmpbuf-offsets.h glibc-2.17-c758a686/sysdeps/powerpc/jmpbuf-offsets.h
--- glibc-2.17-c758a686/sysdeps/powerpc/jmpbuf-offsets.h 2014-05-27 22:55:23.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S 2014-05-27 22:55:23.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S 2014-05-27 22:55:23.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/__longjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S 2014-05-27 22:55:23.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-27 22:55:23.000000000 -0500
+++ glibc-2.17-c758a686/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):

228
SOURCES/glibc-ppc64le-22.patch

@ -0,0 +1,228 @@ @@ -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/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c
--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c 2014-05-27 23:22:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/longjmp.c glibc-2.17-c758a686/sysdeps/powerpc/longjmp.c
--- glibc-2.17-c758a686/sysdeps/powerpc/longjmp.c 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/novmx-longjmp.c glibc-2.17-c758a686/sysdeps/powerpc/novmx-longjmp.c
--- glibc-2.17-c758a686/sysdeps/powerpc/novmx-longjmp.c 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/bsd-_setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-_setjmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-_setjmp.S 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/bsd-setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-setjmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-setjmp.S 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/fpu/__longjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp.S 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/fpu/setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp.S 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/mcount.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/mcount.c
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/mcount.c 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp.S 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp.S 2014-05-27 23:22:10.000000000 -0500
+++ glibc-2.17-c758a686/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

102
SOURCES/glibc-ppc64le-23.patch

@ -0,0 +1,102 @@ @@ -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/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S 2014-05-27 23:25:35.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S 2014-05-27 23:25:35.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S 2014-05-27 23:25:35.000000000 -0500
+++ glibc-2.17-c758a686/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)

55
SOURCES/glibc-ppc64le-24.patch

@ -0,0 +1,55 @@ @@ -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/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S 2014-05-28 12:25:49.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-28 12:25:49.000000000 -0500
+++ glibc-2.17-c758a686/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

411
SOURCES/glibc-ppc64le-25.patch

@ -0,0 +1,411 @@ @@ -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/sysdeps/powerpc/powerpc32/power7/strlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strlen.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strlen.S 2014-05-28 12:28:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/strlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strlen.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strlen.S 2014-05-28 12:28:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power7/strlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strlen.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strlen.S 2014-05-28 12:28:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/strlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strlen.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strlen.S 2014-05-28 12:28:44.000000000 -0500
+++ glibc-2.17-c758a686/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)

379
SOURCES/glibc-ppc64le-26.patch

@ -0,0 +1,379 @@ @@ -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/sysdeps/powerpc/powerpc32/power7/strnlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strnlen.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strnlen.S 2014-05-28 12:40:17.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power7/strnlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strnlen.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strnlen.S 2014-05-28 12:40:17.000000000 -0500
+++ glibc-2.17-c758a686/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)

861
SOURCES/glibc-ppc64le-27.patch

@ -0,0 +1,861 @@ @@ -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/sysdeps/powerpc/powerpc32/power4/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/strncmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/strncmp.S 2014-05-28 13:26:59.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power7/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strncmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strncmp.S 2014-05-28 13:26:59.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/strcmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcmp.S 2014-05-28 13:26:59.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strncmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strncmp.S 2014-05-28 13:26:59.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power4/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/strncmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/strncmp.S 2014-05-28 13:26:59.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power7/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strncmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strncmp.S 2014-05-28 13:26:59.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/strcmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcmp.S 2014-05-28 13:26:59.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strncmp.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strncmp.S 2014-05-28 13:26:59.000000000 -0500
+++ glibc-2.17-c758a686/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

167
SOURCES/glibc-ppc64le-28.patch

@ -0,0 +1,167 @@ @@ -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/sysdeps/powerpc/powerpc32/stpcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stpcpy.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stpcpy.S 2014-05-28 13:40:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/strcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcpy.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcpy.S 2014-05-28 13:40:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/stpcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stpcpy.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stpcpy.S 2014-05-28 13:40:01.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/strcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcpy.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcpy.S 2014-05-28 13:40:01.000000000 -0500
+++ glibc-2.17-c758a686/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

642
SOURCES/glibc-ppc64le-29.patch

@ -0,0 +1,642 @@ @@ -0,0 +1,642 @@
# 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.
#
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchr.S
===================================================================
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchr.S.orig
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchr.S
@@ -37,8 +37,8 @@ ENTRY (BP_SYM(strchr))
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 @@ ENTRY (BP_SYM(strchr))

/* 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 @@ ENTRY (BP_SYM(strchr))

/* 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 @@ L(loop):
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 @@ L(null_match):
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 @@ L(loop_null):
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
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchrnul.S
===================================================================
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchrnul.S.orig
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchrnul.S
@@ -29,8 +29,8 @@ ENTRY (BP_SYM(__strchrnul))
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 @@ ENTRY (BP_SYM(__strchrnul))

/* 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 @@ ENTRY (BP_SYM(__strchrnul))

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 @@ L(loop):
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 @@ L(loop):
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 @@ L(loop):
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
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strchr.S
===================================================================
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strchr.S.orig
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strchr.S
@@ -44,6 +44,8 @@ ENTRY (BP_SYM (strchr))
#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 @@ ENTRY (BP_SYM (strchr))
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 @@ L(missed):
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)
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchr.S
===================================================================
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchr.S.orig
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchr.S
@@ -37,8 +37,8 @@ ENTRY (BP_SYM(strchr))
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 @@ ENTRY (BP_SYM(strchr))

/* 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 @@ L(loop):
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 @@ L(null_match):

/* 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 @@ L(loop_null):
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
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchrnul.S
===================================================================
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchrnul.S.orig
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchrnul.S
@@ -29,8 +29,8 @@ ENTRY (BP_SYM(__strchrnul))
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 @@ ENTRY (BP_SYM(__strchrnul))

/* 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 @@ L(loop):
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 @@ L(loop):
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
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strchr.S
===================================================================
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strchr.S.orig
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strchr.S
@@ -50,14 +50,16 @@ ENTRY (BP_SYM (strchr))
#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 @@ ENTRY (BP_SYM (strchr))
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 @@ L(missed):
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)

7383
SOURCES/glibc-ppc64le-30.patch

File diff suppressed because it is too large Load Diff

2943
SOURCES/glibc-ppc64le-31.patch

File diff suppressed because it is too large Load Diff

272
SOURCES/glibc-ppc64le-32.patch

@ -0,0 +1,272 @@ @@ -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/sysdeps/powerpc/powerpc32/power4/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memset.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memset.S 2014-05-29 13:07:41.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power6/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S 2014-05-29 13:07:41.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc32/power7/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memset.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memset.S 2014-05-29 13:07:41.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S 2014-05-29 13:07:41.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power4/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S 2014-05-29 13:07:41.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power6/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S 2014-05-29 13:07:41.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/power7/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S 2014-05-29 13:07:41.000000000 -0500
+++ glibc-2.17-c758a686/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. */

1255
SOURCES/glibc-ppc64le-33.patch

File diff suppressed because it is too large Load Diff

68
SOURCES/glibc-ppc64le-34.patch

@ -0,0 +1,68 @@ @@ -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/configure glibc-2.17-c758a686/configure
--- glibc-2.17-c758a686/configure 2014-05-26 19:52:31.000000000 -0500
+++ glibc-2.17-c758a686/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/configure.in glibc-2.17-c758a686/configure.in
--- glibc-2.17-c758a686/configure.in 2014-05-26 19:52:30.000000000 -0500
+++ glibc-2.17-c758a686/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/nptl/shlib-versions glibc-2.17-c758a686/nptl/shlib-versions
--- glibc-2.17-c758a686/nptl/shlib-versions 2014-05-26 19:52:31.000000000 -0500
+++ glibc-2.17-c758a686/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/shlib-versions glibc-2.17-c758a686/shlib-versions
--- glibc-2.17-c758a686/shlib-versions 2014-05-26 19:52:31.000000000 -0500
+++ glibc-2.17-c758a686/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

106
SOURCES/glibc-ppc64le-35.patch

@ -0,0 +1,106 @@ @@ -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/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-29 13:16:16.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S 2014-05-29 13:16:16.000000000 -0500
+++ glibc-2.17-c758a686/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

105
SOURCES/glibc-ppc64le-36.patch

@ -0,0 +1,105 @@ @@ -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/elf/elf.h glibc-2.17-c758a686/elf/elf.h
--- glibc-2.17-c758a686/elf/elf.h 2014-05-29 13:17:35.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:17:34.000000000 -0500
+++ glibc-2.17-c758a686/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;

31
SOURCES/glibc-ppc64le-37.patch

@ -0,0 +1,31 @@ @@ -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/nptl/sysdeps/powerpc/tls.h glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h
--- glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h 2014-05-29 13:19:25.000000000 -0500
+++ glibc-2.17-c758a686/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;

262
SOURCES/glibc-ppc64le-38.patch

@ -0,0 +1,262 @@ @@ -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/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 13:56:35.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:56:35.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 13:56:35.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 13:56:35.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S 2014-05-29 13:56:35.000000000 -0500
+++ glibc-2.17-c758a686/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)

508
SOURCES/glibc-ppc64le-39.patch

@ -0,0 +1,508 @@ @@ -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/elf/elf.h glibc-2.17-c758a686/elf/elf.h
--- glibc-2.17-c758a686/elf/elf.h 2014-05-29 13:58:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 13:58:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-irel.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h 2014-05-29 13:58:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:58:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-29 13:58:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 13:58:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h 2014-05-29 13:58:24.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-29 13:58:24.000000000 -0500
+++ glibc-2.17-c758a686/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

159
SOURCES/glibc-ppc64le-40.patch

@ -0,0 +1,159 @@ @@ -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/elf/elf.h glibc-2.17-c758a686/elf/elf.h
--- glibc-2.17-c758a686/elf/elf.h 2014-05-29 14:08:44.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 14:08:40.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:08:40.000000000 -0500
+++ glibc-2.17-c758a686/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)

764
SOURCES/glibc-ppc64le-41.patch

@ -0,0 +1,764 @@ @@ -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/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h 2014-05-29 14:10:00.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/__longjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/crtn.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crtn.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crtn.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/ppc-mcount.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/ppc-mcount.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/ppc-mcount.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym 2014-05-29 14:09:56.000000000 -0500
+++ glibc-2.17-c758a686/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)

404
SOURCES/glibc-ppc64le-42.patch

@ -0,0 +1,404 @@ @@ -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/sysdeps/powerpc/bits/link.h glibc-2.17-c758a686/sysdeps/powerpc/bits/link.h
--- glibc-2.17-c758a686/sysdeps/powerpc/bits/link.h 2014-05-29 14:11:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/ldsodefs.h glibc-2.17-c758a686/sysdeps/powerpc/ldsodefs.h
--- glibc-2.17-c758a686/sysdeps/powerpc/ldsodefs.h 2014-05-29 14:11:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 14:11:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:11:12.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/powerpc/powerpc64/tst-audit.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/tst-audit.h
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/tst-audit.h 2014-05-29 14:11:12.000000000 -0500
+++ glibc-2.17-c758a686/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

248
SOURCES/glibc-ppc64le-43.patch

@ -0,0 +1,248 @@ @@ -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/sysdeps/unix/sysv/linux/powerpc/Makefile glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile 2014-05-29 14:12:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/ldconfig.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldconfig.h
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldconfig.h 2014-05-29 14:12:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile 2014-05-29 14:12:25.000000000 -0500
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure 1969-12-31 18:00:00.000000000 -0600
+++ glibc-2.17-c758a686/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/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac
--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac 1969-12-31 18:00:00.000000000 -0600
+++ glibc-2.17-c758a686/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

26
SOURCES/glibc-ppc64le-44.patch

@ -0,0 +1,26 @@ @@ -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/sysdeps/powerpc/powerpc64/fpu/s_copysign.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysign.S 2014-05-29 14:13:47.000000000 -0500
+++ glibc-2.17-c758a686/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

33
SOURCES/glibc-ppc64le-45.patch

@ -0,0 +1,33 @@ @@ -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/Versions.def glibc-2.17-c758a686/Versions.def
--- glibc-2.17-c758a686/Versions.def 2014-06-02 21:13:12.000000000 +0000
+++ glibc-2.17-c758a686/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 {

22
SOURCES/glibc-ppc64le-46.patch

@ -0,0 +1,22 @@ @@ -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/sysdeps/powerpc/fpu/libm-test-ulps glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps 2014-07-25 22:07:06.280020855 -0400
+++ glibc-2.17-c758a686/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

32
SOURCES/glibc-rh1000923.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
commit 595aba70a4c676f7efaf6a012f54cd22aa189c5b
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Mon Aug 26 15:42:29 2013 +0530

Initialize res_hconf in nscd

Fixes BZ #15890.

diff -pruN glibc-2.17-c758a686/nscd/aicache.c glibc-2.17-c758a686/nscd/aicache.c
--- glibc-2.17-c758a686/nscd/aicache.c 2013-08-11 04:22:55.000000000 +0530
+++ glibc-2.17-c758a686/nscd/aicache.c 2013-08-26 11:10:25.843470413 +0530
@@ -25,6 +25,7 @@
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <resolv/res_hconf.h>

#include "dbg_log.h"
#include "nscd.h"
@@ -100,8 +101,11 @@ addhstaiX (struct database_dyn *db, int
no_more = __nss_database_lookup ("hosts", NULL,
"dns [!UNAVAIL=return] files", &nip);

+ /* Initialize configurations. */
+ if (__builtin_expect (!_res_hconf.initialized, 0))
+ _res_hconf_init ();
if (__res_maybe_init (&_res, 0) == -1)
- no_more = 1;
+ no_more = 1;

/* If we are looking for both IPv4 and IPv6 address we don't want
the lookup functions to automatically promote IPv4 addresses to

46
SOURCES/glibc-rh1008298.patch

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
diff --git glibc-2.17-c758a686/malloc/malloc.c glibc-2.17-c758a686/malloc/malloc.c
index 3148c5f..f7718a9 100644
--- glibc-2.17-c758a686/malloc/malloc.c
+++ glibc-2.17-c758a686/malloc/malloc.c
@@ -3015,6 +3015,13 @@ __libc_memalign(size_t alignment, size_t bytes)
/* Otherwise, ensure that it is at least a minimum chunk size */
if (alignment < MINSIZE) alignment = MINSIZE;

+ /* Check for overflow. */
+ if (bytes > SIZE_MAX - alignment - MINSIZE)
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
arena_get(ar_ptr, bytes + alignment + MINSIZE);
if(!ar_ptr)
return 0;
@@ -3046,6 +3046,13 @@ __libc_valloc(size_t bytes)

size_t pagesz = GLRO(dl_pagesize);

+ /* Check for overflow. */
+ if (bytes > SIZE_MAX - pagesz - MINSIZE)
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
__malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t,
const __malloc_ptr_t)) =
force_reg (__memalign_hook);
@@ -3082,6 +3082,13 @@ __libc_pvalloc(size_t bytes)
size_t page_mask = GLRO(dl_pagesize) - 1;
size_t rounded_bytes = (bytes + page_mask) & ~(page_mask);

+ /* Check for overflow. */
+ if (bytes > SIZE_MAX - 2*pagesz - MINSIZE)
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
__malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t,
const __malloc_ptr_t)) =
force_reg (__memalign_hook);

128
SOURCES/glibc-rh1020637.patch

@ -0,0 +1,128 @@ @@ -0,0 +1,128 @@
commit acd98a8ed1460497e788c701eb92616f1df9b446
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Fri Nov 29 09:57:04 2013 +0100

[BZ #16214] S/390: Fix TLS GOT pointer setup.

diff --git glibc-2.17-c758a686/sysdeps/s390/Versions glibc-2.17-c758a686/sysdeps/s390/Versions
index e18617c..baf9842 100644
--- glibc-2.17-c758a686/sysdeps/s390/Versions
+++ glibc-2.17-c758a686/sysdeps/s390/Versions
@@ -3,4 +3,8 @@ ld {
# runtime interface to TLS
__tls_get_offset;
}
+ GLIBC_PRIVATE {
+ # Exported by ld used by libc.
+ __tls_get_addr_internal;
+ }
}
diff --git glibc-2.17-c758a686/sysdeps/s390/dl-tls.h glibc-2.17-c758a686/sysdeps/s390/dl-tls.h
index 68a5af4..52192a2 100644
--- glibc-2.17-c758a686/sysdeps/s390/dl-tls.h
+++ glibc-2.17-c758a686/sysdeps/s390/dl-tls.h
@@ -26,11 +26,26 @@ typedef struct


#ifdef SHARED
-/* This is the prototype for the GNU version. */
-extern void *__tls_get_addr (tls_index *ti) attribute_hidden;
+
extern unsigned long __tls_get_offset (unsigned long got_offset);

# ifdef IS_IN_rtld
+
+# include <shlib-compat.h>
+
+extern void *__tls_get_addr (tls_index *ti) attribute_hidden;
+/* Make a temporary alias of __tls_get_addr to remove the hidden
+ attribute. Then export __tls_get_addr as __tls_get_addr_internal
+ for use from libc. We do not want to export __tls_get_addr, but we
+ do need to use it from libc when looking up the address of a TLS
+ variable. We don't use __tls_get_offset because it requires r12 to
+ be setup and that might not always be true. Either way it's more
+ optimal to use __tls_get_addr directly (that's what
+ __tls_get_offset does anyways). */
+strong_alias (__tls_get_addr, __tls_get_addr_internal_tmp);
+versioned_symbol (ld, __tls_get_addr_internal_tmp,
+ __tls_get_addr_internal, GLIBC_PRIVATE);
+
/* The special thing about the s390 TLS ABI is that we do not have the
standard __tls_get_addr function but the __tls_get_offset function
which differs in two important aspects:
@@ -63,15 +78,21 @@ __tls_get_offset:\n\
1: .long __tls_get_addr - 0b\n\
");
# endif
-# endif
+# else /* IS_IN_rtld */
+extern void *__tls_get_addr_internal (tls_index *ti);
+# endif /* !IS_IN_rtld */

# define GET_ADDR_OFFSET \
(ti->ti_offset - (unsigned long) __builtin_thread_pointer ())

-# define __TLS_GET_ADDR(__ti) \
- ({ extern char _GLOBAL_OFFSET_TABLE_[] attribute_hidden; \
- (void *) __tls_get_offset ((char *) (__ti) - _GLOBAL_OFFSET_TABLE_) \
- + (unsigned long) __builtin_thread_pointer (); })
+/* Use the privately exported __tls_get_addr_internal instead of
+ __tls_get_offset in order to avoid the __tls_get_offset special
+ linkage requiring the GOT pointer to be set up in r12. The
+ compiler will take care of setting up r12 only if itself issued the
+ __tls_get_offset call. */
+# define __TLS_GET_ADDR(__ti) \
+ ({ (void *) __tls_get_addr_internal ((char *) (__ti)) \
+ + (unsigned long) __builtin_thread_pointer (); })

#endif

diff --git glibc-2.17-c758a686/sysdeps/s390/s390-32/tls-macros.h glibc-2.17-c758a686/sysdeps/s390/s390-32/tls-macros.h
index 8a0ad58..a592d81 100644
--- glibc-2.17-c758a686/sysdeps/s390/s390-32/tls-macros.h
+++ glibc-2.17-c758a686/sysdeps/s390/s390-32/tls-macros.h
@@ -8,12 +8,15 @@

#ifdef PIC
# define TLS_IE(x) \
- ({ unsigned long __offset; \
+ ({ unsigned long __offset, __got; \
asm ("bras %0,1f\n" \
- "0:\t.long " #x "@gotntpoff\n" \
- "1:\tl %0,0(%0)\n\t" \
- "l %0,0(%0,%%r12):tls_load:" #x \
- : "=&a" (__offset) : : "cc" ); \
+ "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \
+ ".long " #x "@gotntpoff\n" \
+ "1:\tl %1,0(%0)\n\t" \
+ "la %1,0(%1,%0)\n\t" \
+ "l %0,4(%0)\n\t" \
+ "l %0,0(%0,%1):tls_load:" #x "\n" \
+ : "=&a" (__offset), "=&a" (__got) : : "cc" ); \
(int *) (__builtin_thread_pointer() + __offset); })
#else
# define TLS_IE(x) \
diff --git glibc-2.17-c758a686/sysdeps/s390/s390-64/tls-macros.h glibc-2.17-c758a686/sysdeps/s390/s390-64/tls-macros.h
index be8aa6c..3c59436 100644
--- glibc-2.17-c758a686/sysdeps/s390/s390-64/tls-macros.h
+++ glibc-2.17-c758a686/sysdeps/s390/s390-64/tls-macros.h
@@ -8,12 +8,13 @@

#ifdef PIC
# define TLS_IE(x) \
- ({ unsigned long __offset; \
- asm ("bras %0,1f\n" \
- "0:\t.quad " #x "@gotntpoff\n" \
- "1:\tlg %0,0(%0)\n\t" \
- "lg %0,0(%0,%%r12):tls_load:" #x \
- : "=&a" (__offset) : : "cc" ); \
+ ({ unsigned long __offset, __got; \
+ asm ("bras %0,0f\n\t" \
+ ".quad " #x "@gotntpoff\n" \
+ "0:\tlarl %1,_GLOBAL_OFFSET_TABLE_\n\t" \
+ "lg %0,0(%0)\n\t" \
+ "lg %0,0(%0,%1):tls_load:" #x "\n" \
+ : "=&a" (__offset), "=&a" (__got) : : "cc" ); \
(int *) (__builtin_thread_pointer() + __offset); })
#else
# define TLS_IE(x) \

50
SOURCES/glibc-rh1025612.patch

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
commit 7cbcdb3699584db8913ca90f705d6337633ee10f
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Fri Oct 25 10:22:12 2013 +0530

Fix stack overflow due to large AF_INET6 requests

Resolves #16072 (CVE-2013-4458).

This patch fixes another stack overflow in getaddrinfo when it is
called with AF_INET6. The AF_UNSPEC case was fixed as CVE-2013-1914,
but the AF_INET6 case went undetected back then.

diff --git glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c
index e6ce4cf..8ff74b4 100644
--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c
+++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c
@@ -197,7 +197,22 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
&rc, &herrno, NULL, &localcanon)); \
if (rc != ERANGE || herrno != NETDB_INTERNAL) \
break; \
- tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
+ if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \
+ tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \
+ alloca_used); \
+ else \
+ { \
+ char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \
+ 2 * tmpbuflen); \
+ if (newp == NULL) \
+ { \
+ result = -EAI_MEMORY; \
+ goto free_and_return; \
+ } \
+ tmpbuf = newp; \
+ malloc_tmpbuf = true; \
+ tmpbuflen = 2 * tmpbuflen; \
+ } \
} \
if (status == NSS_STATUS_SUCCESS && rc == 0) \
h = &th; \
@@ -209,7 +224,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
{ \
__set_h_errno (herrno); \
_res.options |= old_res_options & RES_USE_INET6; \
- return -EAI_SYSTEM; \
+ result = -EAI_SYSTEM; \
+ goto free_and_return; \
} \
if (herrno == TRY_AGAIN) \
no_data = EAI_AGAIN; \

143
SOURCES/glibc-rh1025934.patch

@ -0,0 +1,143 @@ @@ -0,0 +1,143 @@
Mostly equivalent upstream commit:

commit 0699f766b10c86912b75f35bef697106b70c1cf6
Author: Carlos O'Donell <carlos@redhat.com>
Date: Thu Apr 10 18:31:53 2014 -0400

nscd: Make SELinux checks dynamic.

diff --git glibc-2.17-c758a686/nscd/selinux.c glibc-2.17-c758a686/nscd/selinux.c
index 0866c44..ba55b04 100644
--- glibc-2.17-c758a686/nscd/selinux.c
+++ glibc-2.17-c758a686/nscd/selinux.c
@@ -44,35 +44,31 @@
/* Global variable to tell if the kernel has SELinux support. */
int selinux_enabled;

-/* Define mappings of access vector permissions to request types. */
-static const access_vector_t perms[LASTREQ] =
+/* Define mappings of request type to AVC permission name. */
+static const char *perms[LASTREQ] =
{
- [GETPWBYNAME] = NSCD__GETPWD,
- [GETPWBYUID] = NSCD__GETPWD,
- [GETGRBYNAME] = NSCD__GETGRP,
- [GETGRBYGID] = NSCD__GETGRP,
- [GETHOSTBYNAME] = NSCD__GETHOST,
- [GETHOSTBYNAMEv6] = NSCD__GETHOST,
- [GETHOSTBYADDR] = NSCD__GETHOST,
- [GETHOSTBYADDRv6] = NSCD__GETHOST,
- [GETSTAT] = NSCD__GETSTAT,
- [SHUTDOWN] = NSCD__ADMIN,
- [INVALIDATE] = NSCD__ADMIN,
- [GETFDPW] = NSCD__SHMEMPWD,
- [GETFDGR] = NSCD__SHMEMGRP,
- [GETFDHST] = NSCD__SHMEMHOST,
- [GETAI] = NSCD__GETHOST,
- [INITGROUPS] = NSCD__GETGRP,
-#ifdef NSCD__GETSERV
- [GETSERVBYNAME] = NSCD__GETSERV,
- [GETSERVBYPORT] = NSCD__GETSERV,
- [GETFDSERV] = NSCD__SHMEMSERV,
-#endif
-#ifdef NSCD__GETNETGRP
- [GETNETGRENT] = NSCD__GETNETGRP,
- [INNETGR] = NSCD__GETNETGRP,
- [GETFDNETGR] = NSCD__SHMEMNETGRP,
-#endif
+ [GETPWBYNAME] = "getpwd",
+ [GETPWBYUID] = "getpwd",
+ [GETGRBYNAME] = "getgrp",
+ [GETGRBYGID] = "getgrp",
+ [GETHOSTBYNAME] = "gethost",
+ [GETHOSTBYNAMEv6] = "gethost",
+ [GETHOSTBYADDR] = "gethost",
+ [GETHOSTBYADDRv6] = "gethost",
+ [SHUTDOWN] = "admin",
+ [GETSTAT] = "getstat",
+ [INVALIDATE] = "admin",
+ [GETFDPW] = "shmempwd",
+ [GETFDGR] = "shmemgrp",
+ [GETFDHST] = "shmemhost",
+ [GETAI] = "gethost",
+ [INITGROUPS] = "getgrp",
+ [GETSERVBYNAME] = "getserv",
+ [GETSERVBYPORT] = "getserv",
+ [GETFDSERV] = "shmemserv",
+ [GETNETGRENT] = "getnetgrp",
+ [INNETGR] = "getnetgrp",
+ [GETFDNETGR] = "shmemnetgrp",
};

/* Store an entry ref to speed AVC decisions. */
@@ -344,7 +340,18 @@ nscd_avc_init (void)


/* Check the permission from the caller (via getpeercon) to nscd.
- Returns 0 if access is allowed, 1 if denied, and -1 on error. */
+ Returns 0 if access is allowed, 1 if denied, and -1 on error.
+
+ Implementation note:
+ The SELinux policy, enablement, and permission bits are all dynamic
+ and the caching done by glibc is not entirely correct. This nscd
+ support should be rewritten to use selinux_check_permission.
+ A rewrite is risky though and requires some refactoring fist.
+ Instead we use symbolic mappings instead of compile time
+ constants (which selinux upstream says are going away), and use
+ security_deny_unknown to determine what to do if selinux-policy
+ doesn't have a definition for the the permission or object class
+ we are looking up. */
int
nscd_request_avc_has_perm (int fd, request_type req)
{
@@ -354,6 +361,33 @@ nscd_request_avc_has_perm (int fd, request_type req)
security_id_t ssid = NULL;
security_id_t tsid = NULL;
int rc = -1;
+ security_class_t sc_nscd = 0;
+ access_vector_t perm = 0;
+ int avc_deny_unknown = 0;
+
+ /* Check if SELinux denys or allows unknown object classes
+ and permissions. It is 0 if they are allowed, 1 if they
+ are not allowed and -1 on error. */
+ if ((avc_deny_unknown = security_deny_unknown ()) == -1)
+ dbg_log (_("Error querying policy for undefined object classes "
+ "or permissions."));
+
+ /* 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)
+ dbg_log (_("Error getting security class for nscd."));
+
+ /* Convert permission to AVC bits. */
+ perm = string_to_av_perm (sc_nscd, perms[req]);
+ if (perm == 0 && avc_deny_unknown == 1)
+ dbg_log (_("Error translating permission name "
+ "\"%s\" to access vector bit."), perms[req]);
+
+ /* If the nscd security class was not found or perms were not
+ found and AVC does not deny unknown values then allow it. */
+ if ((sc_nscd == 0 || perm == 0) && avc_deny_unknown == 0)
+ return 0;

if (getpeercon (fd, &scon) < 0)
{
@@ -372,15 +406,7 @@ nscd_request_avc_has_perm (int fd, request_type req)
goto out;
}

-#ifndef NSCD__GETSERV
- if (perms[req] == 0)
- {
- dbg_log (_("compile-time support for database policy missing"));
- goto out;
- }
-#endif
-
- rc = avc_has_perm (ssid, tsid, SECCLASS_NSCD, perms[req], &aeref, NULL) < 0;
+ rc = avc_has_perm (ssid, tsid, sc_nscd, perm, &aeref, NULL) < 0;

out:
if (scon)

58
SOURCES/glibc-rh1027101.patch

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
commit 362b47fe09ca9a928d444c7e2f7992f7f61bfc3e
Author: Maxim Kuvyrkov <maxim@kugelworks.com>
Date: Tue Dec 24 09:44:50 2013 +1300

Fix race in free() of fastbin chunk: BZ #15073

Perform sanity check only if we have_lock. Due to lockless nature of fastbins
we need to be careful derefencing pointers to fastbin entries (chunksize(old)
in this case) in multithreaded environments.

The fix is to add have_lock to the if-condition checks. The rest of the patch
only makes code more readable.

* malloc/malloc.c (_int_free): Perform sanity check only if we
have_lock.

Index: b/malloc/malloc.c
===================================================================
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3909,25 +3909,29 @@ _int_free(mstate av, mchunkptr p, int ha
unsigned int idx = fastbin_index(size);
fb = &fastbin (av, idx);

- mchunkptr fd;
- mchunkptr old = *fb;
+ /* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */
+ mchunkptr old = *fb, old2;
unsigned int old_idx = ~0u;
do
{
- /* Another simple check: make sure the top of the bin is not the
- record we are going to add (i.e., double free). */
+ /* Check that the top of the bin is not the record we are going to add
+ (i.e., double free). */
if (__builtin_expect (old == p, 0))
{
errstr = "double free or corruption (fasttop)";
goto errout;
}
- if (old != NULL)
+ /* Check that size of fastbin chunk at the top is the same as
+ size of the chunk that we are adding. We can dereference OLD
+ only if we have the lock, otherwise it might have already been
+ deallocated. See use of OLD_IDX below for the actual check. */
+ if (have_lock && old != NULL)
old_idx = fastbin_index(chunksize(old));
- p->fd = fd = old;
+ p->fd = old2 = old;
}
- while ((old = catomic_compare_and_exchange_val_rel (fb, p, fd)) != fd);
+ while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2);

- if (fd != NULL && __builtin_expect (old_idx != idx, 0))
+ if (have_lock && old != NULL && __builtin_expect (old_idx != idx, 0))
{
errstr = "invalid fastbin entry (free)";
goto errout;

280
SOURCES/glibc-rh1027348-1.patch

@ -0,0 +1,280 @@ @@ -0,0 +1,280 @@
Backporting the C11 atomic support will allow future algorithms
to be more easily backported to RHEL7. This is initially backported
to support the new semaphore algorithm which is now in RHEL7
(rhbz#1027348).

commit 1ea339b69725cb2f30b5a84cb7ca96111c9a637b
Author: Torvald Riegel <triegel@redhat.com>
Date: Sat Oct 18 01:02:59 2014 +0200

Add arch-specific configuration for C11 atomics support.

This sets __HAVE_64B_ATOMICS if provided. It also sets
USE_ATOMIC_COMPILER_BUILTINS to true if the existing atomic ops use the
__atomic* builtins (aarch64, mips partially) or if this has been
tested (x86_64); otherwise, this is set to false so that C11 atomics will
be based on the existing atomic operations.

Index: glibc-2.17-c758a686/ports/sysdeps/aarch64/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/ports/sysdeps/aarch64/bits/atomic.h
+++ glibc-2.17-c758a686/ports/sysdeps/aarch64/bits/atomic.h
@@ -36,6 +36,8 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 1
+#define USE_ATOMIC_COMPILER_BUILTINS 1

/* Compare and exchange.
For all "bool" routines, we return FALSE if exchange succesful. */
Index: glibc-2.17-c758a686/ports/sysdeps/alpha/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/ports/sysdeps/alpha/bits/atomic.h
+++ glibc-2.17-c758a686/ports/sysdeps/alpha/bits/atomic.h
@@ -42,6 +42,9 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 1
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+

#ifdef UP
# define __MB /* nothing */
Index: glibc-2.17-c758a686/ports/sysdeps/arm/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/ports/sysdeps/arm/bits/atomic.h
+++ glibc-2.17-c758a686/ports/sysdeps/arm/bits/atomic.h
@@ -33,6 +33,9 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 0
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+
void __arm_link_error (void);

/* Use the atomic builtins provided by GCC in case the backend provides
Index: glibc-2.17-c758a686/sysdeps/i386/i486/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/sysdeps/i386/i486/bits/atomic.h
+++ glibc-2.17-c758a686/sysdeps/i386/i486/bits/atomic.h
@@ -54,6 +54,9 @@ typedef uintmax_t uatomic_max_t;
# endif
#endif

+#define __HAVE_64B_ATOMICS 0
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+

#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
__sync_val_compare_and_swap (mem, oldval, newval)
Index: glibc-2.17-c758a686/ports/sysdeps/ia64/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/ports/sysdeps/ia64/bits/atomic.h
+++ glibc-2.17-c758a686/ports/sysdeps/ia64/bits/atomic.h
@@ -43,6 +43,9 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 1
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+

#define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
(abort (), 0)
Index: glibc-2.17-c758a686/ports/sysdeps/m68k/coldfire/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/ports/sysdeps/m68k/coldfire/bits/atomic.h
+++ glibc-2.17-c758a686/ports/sysdeps/m68k/coldfire/bits/atomic.h
@@ -49,6 +49,10 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+/* If we have just non-atomic operations, we can as well make them wide. */
+#define __HAVE_64B_ATOMICS 1
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+
/* The only basic operation needed is compare and exchange. */
#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
({ __typeof (mem) __gmemp = (mem); \
Index: glibc-2.17-c758a686/ports/sysdeps/m68k/m680x0/m68020/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/ports/sysdeps/m68k/m680x0/m68020/bits/atomic.h
+++ glibc-2.17-c758a686/ports/sysdeps/m68k/m680x0/m68020/bits/atomic.h
@@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 1
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+
#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
({ __typeof (*(mem)) __ret; \
__asm __volatile ("cas%.b %0,%2,%1" \
Index: glibc-2.17-c758a686/ports/sysdeps/mips/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/ports/sysdeps/mips/bits/atomic.h
+++ glibc-2.17-c758a686/ports/sysdeps/mips/bits/atomic.h
@@ -43,6 +43,12 @@ typedef uintmax_t uatomic_max_t;
#define MIPS_PUSH_MIPS2
#endif

+#if _MIPS_SIM == _ABIO32
+#define __HAVE_64B_ATOMICS 0
+#else
+#define __HAVE_64B_ATOMICS 1
+#endif
+
/* See the comments in <sys/asm.h> about the use of the sync instruction. */
#ifndef MIPS_SYNC
# define MIPS_SYNC sync
@@ -82,6 +88,8 @@ typedef uintmax_t uatomic_max_t;
/* The __atomic_* builtins are available in GCC 4.7 and later, but MIPS
support for their efficient implementation was added only in GCC 4.8. */

+#define USE_ATOMIC_COMPILER_BUILTINS 1
+
/* Compare and exchange.
For all "bool" routines, we return FALSE if exchange succesful. */

@@ -204,6 +212,8 @@ typedef uintmax_t uatomic_max_t;
/* This implementation using inline assembly will be removed once glibc
requires GCC 4.8 or later to build. */

+#define USE_ATOMIC_COMPILER_BUILTINS 0
+
/* Compare and exchange. For all of the "xxx" routines, we expect a
"__prev" and a "__cmp" variable to be provided by the enclosing scope,
in which values are returned. */
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/bits/atomic.h
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bits/atomic.h
@@ -33,6 +33,9 @@
# define MUTEX_HINT_REL
#endif

+#define __HAVE_64B_ATOMICS 0
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+
/*
* The 32-bit exchange_bool is different on powerpc64 because the subf
* does signed 64-bit arthmatic while the lwarx is 32-bit unsigned
Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/bits/atomic.h
+++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/bits/atomic.h
@@ -33,6 +33,9 @@
# define MUTEX_HINT_REL
#endif

+#define __HAVE_64B_ATOMICS 1
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+
/* The 32-bit exchange_bool is different on powerpc64 because the subf
does signed 64-bit arthmatic while the lwarx is 32-bit unsigned
(a load word and zero (high 32) form) load.
Index: glibc-2.17-c758a686/sysdeps/s390/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/sysdeps/s390/bits/atomic.h
+++ glibc-2.17-c758a686/sysdeps/s390/bits/atomic.h
@@ -43,6 +43,8 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define USE_ATOMIC_COMPILER_BUILTINS 0
+

#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
(abort (), (__typeof (*mem)) 0)
@@ -59,6 +61,7 @@ typedef uintmax_t uatomic_max_t;
__archold; })

#ifdef __s390x__
+# define __HAVE_64B_ATOMICS 1
# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ __typeof (mem) __archmem = (mem); \
__typeof (*mem) __archold = (oldval); \
@@ -67,6 +70,7 @@ typedef uintmax_t uatomic_max_t;
: "d" ((long) (newval)), "m" (*__archmem) : "cc", "memory" ); \
__archold; })
#else
+# define __HAVE_64B_ATOMICS 0
/* For 31 bit we do not really need 64-bit compare-and-exchange. We can
implement them by use of the csd instruction. The straightforward
implementation causes warnings so we skip the definition for now. */
Index: glibc-2.17-c758a686/sysdeps/sparc/sparc32/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc32/bits/atomic.h
+++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/bits/atomic.h
@@ -47,6 +47,9 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 0
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+

/* We have no compare and swap, just test and set.
The following implementation contends on 64 global locks
Index: glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
+++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
@@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 0
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+

#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
(abort (), (__typeof (*mem)) 0)
Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/bits/atomic.h
+++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/bits/atomic.h
@@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 1
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+

#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
(abort (), (__typeof (*mem)) 0)
Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
@@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t;
typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t;

+#define __HAVE_64B_ATOMICS 0
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+
/* prev = *addr;
if (prev == old)
*addr = new;
Index: glibc-2.17-c758a686/sysdeps/x86_64/bits/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/sysdeps/x86_64/bits/atomic.h
+++ glibc-2.17-c758a686/sysdeps/x86_64/bits/atomic.h
@@ -55,6 +55,12 @@ typedef uintmax_t uatomic_max_t;
# endif
#endif

+#define __HAVE_64B_ATOMICS 1
+#if __GNUC_PREREQ (4, 7)
+#define USE_ATOMIC_COMPILER_BUILTINS 1
+#else
+#define USE_ATOMIC_COMPILER_BUILTINS 0
+#endif

#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
__sync_val_compare_and_swap (mem, oldval, newval)

229
SOURCES/glibc-rh1027348-2.patch

@ -0,0 +1,229 @@ @@ -0,0 +1,229 @@
commit ff8714269c9312d9164456279a56b6f6c47e2771
Author: Torvald Riegel <triegel@redhat.com>
Date: Sun Sep 14 20:04:54 2014 +0200

Add atomic operations similar to those provided by C11.

Index: glibc-2.17-c758a686/include/atomic.h
===================================================================
--- glibc-2.17-c758a686.orig/include/atomic.h
+++ glibc-2.17-c758a686/include/atomic.h
@@ -542,6 +542,218 @@
({ __typeof (x) __x; __asm ("" : "=r" (__x) : "0" (x)); __x; })
#endif

+/* This is equal to 1 iff the architecture supports 64b atomic operations. */
+#ifndef __HAVE_64B_ATOMICS
+#error Unable to determine if 64-bit atomics are present.
+#endif
+
+/* The following functions are a subset of the atomic operations provided by
+ C11. Usually, a function named atomic_OP_MO(args) is equivalent to C11's
+ atomic_OP_explicit(args, memory_order_MO); exceptions noted below. */
+
+/* Each arch can request to use compiler built-ins for C11 atomics. If it
+ does, all atomics will be based on these. */
+#if USE_ATOMIC_COMPILER_BUILTINS
+
+/* We require 32b atomic operations; some archs also support 64b atomic
+ operations. */
+void __atomic_link_error (void);
+# if __HAVE_64B_ATOMICS == 1
+# define __atomic_check_size(mem) \
+ if ((sizeof (*mem) != 4) && (sizeof (*mem) != 8)) \
+ __atomic_link_error ();
+# else
+# define __atomic_check_size(mem) \
+ if (sizeof (*mem) != 4) \
+ __atomic_link_error ();
+# endif
+
+# define atomic_thread_fence_acquire() \
+ __atomic_thread_fence (__ATOMIC_ACQUIRE)
+# define atomic_thread_fence_release() \
+ __atomic_thread_fence (__ATOMIC_RELEASE)
+# define atomic_thread_fence_seq_cst() \
+ __atomic_thread_fence (__ATOMIC_SEQ_CST)
+
+# define atomic_load_relaxed(mem) \
+ ({ __atomic_check_size((mem)); __atomic_load_n ((mem), __ATOMIC_RELAXED); })
+# define atomic_load_acquire(mem) \
+ ({ __atomic_check_size((mem)); __atomic_load_n ((mem), __ATOMIC_ACQUIRE); })
+
+# define atomic_store_relaxed(mem, val) \
+ do { \
+ __atomic_check_size((mem)); \
+ __atomic_store_n ((mem), (val), __ATOMIC_RELAXED); \
+ } while (0)
+# define atomic_store_release(mem, val) \
+ do { \
+ __atomic_check_size((mem)); \
+ __atomic_store_n ((mem), (val), __ATOMIC_RELEASE); \
+ } while (0)
+
+/* On failure, this CAS has memory_order_relaxed semantics. */
+# define atomic_compare_exchange_weak_relaxed(mem, expected, desired) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_compare_exchange_n ((mem), (expected), (desired), 1, \
+ __ATOMIC_RELAXED, __ATOMIC_RELAXED); })
+# define atomic_compare_exchange_weak_acquire(mem, expected, desired) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_compare_exchange_n ((mem), (expected), (desired), 1, \
+ __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); })
+# define atomic_compare_exchange_weak_release(mem, expected, desired) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_compare_exchange_n ((mem), (expected), (desired), 1, \
+ __ATOMIC_RELEASE, __ATOMIC_RELAXED); })
+
+# define atomic_exchange_acquire(mem, desired) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_exchange_n ((mem), (desired), __ATOMIC_ACQUIRE); })
+# define atomic_exchange_release(mem, desired) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_exchange_n ((mem), (desired), __ATOMIC_RELEASE); })
+
+# define atomic_fetch_add_relaxed(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_add ((mem), (operand), __ATOMIC_RELAXED); })
+# define atomic_fetch_add_acquire(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQUIRE); })
+# define atomic_fetch_add_release(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_add ((mem), (operand), __ATOMIC_RELEASE); })
+# define atomic_fetch_add_acq_rel(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQ_REL); })
+
+# define atomic_fetch_and_acquire(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_and ((mem), (operand), __ATOMIC_ACQUIRE); })
+
+# define atomic_fetch_or_relaxed(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_or ((mem), (operand), __ATOMIC_RELAXED); })
+# define atomic_fetch_or_acquire(mem, operand) \
+ ({ __atomic_check_size((mem)); \
+ __atomic_fetch_or ((mem), (operand), __ATOMIC_ACQUIRE); })
+
+#else /* !USE_ATOMIC_COMPILER_BUILTINS */
+
+/* By default, we assume that read, write, and full barriers are equivalent
+ to acquire, release, and seq_cst barriers. Archs for which this does not
+ hold have to provide custom definitions of the fences. */
+# ifndef atomic_thread_fence_acquire
+# define atomic_thread_fence_acquire() atomic_read_barrier ()
+# endif
+# ifndef atomic_thread_fence_release
+# define atomic_thread_fence_release() atomic_write_barrier ()
+# endif
+# ifndef atomic_thread_fence_seq_cst
+# define atomic_thread_fence_seq_cst() atomic_full_barrier ()
+# endif
+
+# ifndef atomic_load_relaxed
+# define atomic_load_relaxed(mem) \
+ ({ __typeof (*(mem)) __atg100_val; \
+ __asm ("" : "=r" (__atg100_val) : "0" (*(mem))); \
+ __atg100_val; })
+# endif
+# ifndef atomic_load_acquire
+# define atomic_load_acquire(mem) \
+ ({ __typeof (*(mem)) __atg101_val = atomic_load_relaxed (mem); \
+ atomic_thread_fence_acquire (); \
+ __atg101_val; })
+# endif
+
+# ifndef atomic_store_relaxed
+/* XXX Use inline asm here? */
+# define atomic_store_relaxed(mem, val) do { *(mem) = (val); } while (0)
+# endif
+# ifndef atomic_store_release
+# define atomic_store_release(mem, val) \
+ do { \
+ atomic_thread_fence_release (); \
+ atomic_store_relaxed ((mem), (val)); \
+ } while (0)
+# endif
+
+/* On failure, this CAS has memory_order_relaxed semantics. */
+/* XXX This potentially has one branch more than necessary, but archs
+ currently do not define a CAS that returns both the previous value and
+ the success flag. */
+# ifndef atomic_compare_exchange_weak_acquire
+# define atomic_compare_exchange_weak_acquire(mem, expected, desired) \
+ ({ typeof (*(expected)) __atg102_expected = *(expected); \
+ *(expected) = \
+ atomic_compare_and_exchange_val_acq ((mem), (desired), *(expected)); \
+ *(expected) == __atg102_expected; })
+# endif
+# ifndef atomic_compare_exchange_weak_relaxed
+/* XXX Fall back to CAS with acquire MO because archs do not define a weaker
+ CAS. */
+# define atomic_compare_exchange_weak_relaxed(mem, expected, desired) \
+ atomic_compare_exchange_weak_acquire ((mem), (expected), (desired))
+# endif
+# ifndef atomic_compare_exchange_weak_release
+# define atomic_compare_exchange_weak_release(mem, expected, desired) \
+ ({ typeof (*(expected)) __atg103_expected = *(expected); \
+ *(expected) = \
+ atomic_compare_and_exchange_val_rel ((mem), (desired), *(expected)); \
+ *(expected) == __atg103_expected; })
+# endif
+
+# ifndef atomic_exchange_acquire
+# define atomic_exchange_acquire(mem, val) \
+ atomic_exchange_acq ((mem), (val))
+# endif
+# ifndef atomic_exchange_release
+# define atomic_exchange_release(mem, val) \
+ atomic_exchange_rel ((mem), (val))
+# endif
+
+# ifndef atomic_fetch_add_acquire
+# define atomic_fetch_add_acquire(mem, operand) \
+ atomic_exchange_and_add_acq ((mem), (operand))
+# endif
+# ifndef atomic_fetch_add_relaxed
+/* XXX Fall back to acquire MO because the MO semantics of
+ atomic_exchange_and_add are not documented; the generic version falls back
+ to atomic_exchange_and_add_acq if atomic_exchange_and_add is not defined,
+ and vice versa. */
+# define atomic_fetch_add_relaxed(mem, operand) \
+ atomic_fetch_add_acquire ((mem), (operand))
+# endif
+# ifndef atomic_fetch_add_release
+# define atomic_fetch_add_release(mem, operand) \
+ atomic_exchange_and_add_rel ((mem), (operand))
+# endif
+# ifndef atomic_fetch_add_acq_rel
+# define atomic_fetch_add_acq_rel(mem, operand) \
+ ({ atomic_thread_fence_release (); \
+ atomic_exchange_and_add_acq ((mem), (operand)); })
+# endif
+
+/* XXX The default for atomic_and_val has acquire semantics, but this is not
+ documented. */
+# ifndef atomic_fetch_and_acquire
+# define atomic_fetch_and_acquire(mem, operand) \
+ atomic_and_val ((mem), (operand))
+# endif
+
+/* XXX The default for atomic_or_val has acquire semantics, but this is not
+ documented. */
+# ifndef atomic_fetch_or_acquire
+# define atomic_fetch_or_acquire(mem, operand) \
+ atomic_or_val ((mem), (operand))
+# endif
+/* XXX Fall back to acquire MO because archs do not define a weaker
+ atomic_or_val. */
+# ifndef atomic_fetch_or_relaxed
+# define atomic_fetch_or_relaxed(mem, operand) \
+ atomic_fetch_or_acquire ((mem), (operand))
+# endif
+
+#endif /* !USE_ATOMIC_COMPILER_BUILTINS */
+

#ifndef atomic_delay
# define atomic_delay() do { /* nothing */ } while (0)

144
SOURCES/glibc-rh1027348-3.patch

@ -0,0 +1,144 @@ @@ -0,0 +1,144 @@
commit 88ed594f5d431d855256edbe7e886c8cf4b575dc
Author: Roland McGrath <roland@hack.frob.com>
Date: Tue May 19 15:04:41 2015 -0700

BZ#18434: Fix sem_post EOVERFLOW check for [!__HAVE_64B_ATOMICS].

Index: glibc-2.17-c758a686/nptl/Makefile
===================================================================
--- glibc-2.17-c758a686.orig/nptl/Makefile
+++ glibc-2.17-c758a686/nptl/Makefile
@@ -224,6 +224,7 @@ tests = tst-typesizes \
tst-key1 tst-key2 tst-key3 tst-key4 \
tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 tst-sem13 tst-sem14 \
+ tst-sem15 \
tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
tst-align tst-align2 tst-align3 \
tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
Index: glibc-2.17-c758a686/nptl/tst-sem15.c
===================================================================
--- /dev/null
+++ glibc-2.17-c758a686/nptl/tst-sem15.c
@@ -0,0 +1,99 @@
+/* Test for SEM_VALUE_MAX overflow detection: BZ #18434.
+ 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 <errno.h>
+#include <limits.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static int
+do_test (void)
+{
+ sem_t s;
+
+ if (sem_init (&s, 0, SEM_VALUE_MAX))
+ {
+ printf ("sem_init: %m\n");
+ return 1;
+ }
+
+ int result = 0;
+
+ int value = 0xdeadbeef;
+ if (sem_getvalue (&s, &value))
+ {
+ printf ("sem_getvalue: %m\n");
+ result = 1;
+ }
+ else
+ {
+ printf ("sem_getvalue after init: %d\n", value);
+ if (value != SEM_VALUE_MAX)
+ {
+ printf ("\tshould be %d\n", SEM_VALUE_MAX);
+ result = 1;
+ }
+ }
+
+ errno = 0;
+ if (sem_post(&s) == 0)
+ {
+ puts ("sem_post at SEM_VALUE_MAX succeeded!");
+ result = 1;
+ }
+ else
+ {
+ printf ("sem_post at SEM_VALUE_MAX: %m (%d)\n", errno);
+ if (errno != EOVERFLOW)
+ {
+ printf ("\tshould be %s (EOVERFLOW = %d)\n",
+ strerror (EOVERFLOW), EOVERFLOW);
+ result = 1;
+ }
+ }
+
+ value = 0xbad1d00d;
+ if (sem_getvalue (&s, &value))
+ {
+ printf ("sem_getvalue: %m\n");
+ result = 1;
+ }
+ else
+ {
+ printf ("sem_getvalue after post: %d\n", value);
+ if (value != SEM_VALUE_MAX)
+ {
+ printf ("\tshould be %d\n", SEM_VALUE_MAX);
+ result = 1;
+ }
+ }
+
+ if (sem_destroy (&s))
+ {
+ printf ("sem_destroy: %m\n");
+ result = 1;
+ }
+
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_post.c
===================================================================
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_post.c
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_post.c
@@ -83,14 +83,14 @@ __new_sem_post (sem_t *sem)
unsigned int v = atomic_load_relaxed (&isem->value);
do
{
- if ((v << SEM_VALUE_SHIFT) == SEM_VALUE_MAX)
+ if ((v >> SEM_VALUE_SHIFT) == SEM_VALUE_MAX)
{
__set_errno (EOVERFLOW);
return -1;
}
}
- while (!atomic_compare_exchange_weak_release (&isem->value,
- &v, v + (1 << SEM_VALUE_SHIFT)));
+ while (!atomic_compare_exchange_weak_release
+ (&isem->value, &v, v + (1 << SEM_VALUE_SHIFT)));

/* If there is any potentially blocked waiter, wake one of them. */
if ((v & SEM_NWAITERS_MASK) != 0)

105
SOURCES/glibc-rh1027348-4.patch

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
commit c2f5813ae0a68f6c6d69e66dac2da6e46b9df034
Author: Joseph Myers <joseph@codesourcery.com>
Date: Wed Mar 18 17:05:38 2015 +0000

Make sem_timedwait use FUTEX_CLOCK_REALTIME (bug 18138).

sem_timedwait converts absolute timeouts to relative to pass them to
the futex syscall. (Before the recent reimplementation, on x86_64 it
used FUTEX_CLOCK_REALTIME, but not on other architectures.)

Correctly implementing POSIX requirements, however, requires use of
FUTEX_CLOCK_REALTIME; passing a relative timeout to the kernel does
not conform to POSIX. The POSIX specification for sem_timedwait says
"The timeout shall be based on the CLOCK_REALTIME clock.". The POSIX
specification for clock_settime says "If the value of the
CLOCK_REALTIME clock is set via clock_settime(), the new value of the
clock shall be used to determine the time of expiration for absolute
time services based upon the CLOCK_REALTIME clock. This applies to the
time at which armed absolute timers expire. If the absolute time
requested at the invocation of such a time service is before the new
value of the clock, the time service shall expire immediately as if
the clock had reached the requested time normally.". If a relative
timeout is passed to the kernel, it is interpreted according to the
CLOCK_MONOTONIC clock, and so fails to meet that POSIX requirement in
the event of clock changes.

This patch makes sem_timedwait use lll_futex_timed_wait_bitset with
FUTEX_CLOCK_REALTIME when possible, as done in some other places in
NPTL. FUTEX_CLOCK_REALTIME is always available for supported Linux
kernel versions; unavailability of lll_futex_timed_wait_bitset is only
an issue for hppa (an issue noted in
<https://sourceware.org/glibc/wiki/PortStatus>, and fixed by the
unreviewed
<https://sourceware.org/ml/libc-alpha/2014-12/msg00655.html> that
removes the hppa lowlevellock.h completely).

In the FUTEX_CLOCK_REALTIME case, the glibc code still needs to check
for negative tv_sec and handle that as timeout, because the Linux
kernel returns EINVAL not ETIMEDOUT for that case, so resulting in
failures of nptl/tst-abstime and nptl/tst-sem13 in the absence of that
check. If we're trying to distinguish between Linux-specific and
generic-futex NPTL code, I suppose having this in an nptl/ file isn't
ideal, but there doesn't seem to be any better place at present.

It's not possible to add a testcase for this issue to the testsuite
because of the requirement to change the system clock as part of a
test (this is a case where testing would require some form of
container, with root in that container, and one whose CLOCK_REALTIME
is isolated from that of the host; I'm not sure what forms of
containers, short of a full virtual machine, provide that clock
isolation).

Tested for x86_64. Also tested for powerpc with the testcase included
in the bug.

[BZ #18138]
* nptl/sem_waitcommon.c: Include <kernel-features.h>.
(futex_abstimed_wait)
[__ASSUME_FUTEX_CLOCK_REALTIME && lll_futex_timed_wait_bitset]:
Use lll_futex_timed_wait_bitset with FUTEX_CLOCK_REALTIME instead
of lll_futex_timed_wait.

Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c
===================================================================
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c
@@ -17,6 +17,7 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */

+#include <kernel-features.h>
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
@@ -45,6 +46,13 @@ futex_abstimed_wait (unsigned int* futex
}
else
{
+#if (defined __ASSUME_FUTEX_CLOCK_REALTIME \
+ && defined lll_futex_timed_wait_bitset)
+ /* The Linux kernel returns EINVAL for this, but in userspace
+ such a value is valid. */
+ if (abstime->tv_sec < 0)
+ return ETIMEDOUT;
+#else
struct timeval tv;
struct timespec rt;
int sec, nsec;
@@ -68,9 +76,16 @@ futex_abstimed_wait (unsigned int* futex
/* Do wait. */
rt.tv_sec = sec;
rt.tv_nsec = nsec;
+#endif
if (cancel)
oldtype = __pthread_enable_asynccancel ();
+#if (defined __ASSUME_FUTEX_CLOCK_REALTIME \
+ && defined lll_futex_timed_wait_bitset)
+ err = lll_futex_timed_wait_bitset (futex, expected, abstime,
+ FUTEX_CLOCK_REALTIME, private);
+#else
err = lll_futex_timed_wait (futex, expected, &rt, private);
+#endif
if (cancel)
__pthread_disable_asynccancel (oldtype);
}

3917
SOURCES/glibc-rh1027348.patch

File diff suppressed because it is too large Load Diff

96
SOURCES/glibc-rh1028652.patch

@ -0,0 +1,96 @@ @@ -0,0 +1,96 @@
#
# 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 glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h
new file mode 100644
index 0000000..33be9e8
--- /dev/null
+++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h
@@ -0,0 +1,54 @@
+/* sigstack, sigaltstack definitions.
+ Copyright (C) 1998-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/>. */
+
+#ifndef _SIGNAL_H
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+
+/* Structure describing a signal stack (obsolete). */
+struct sigstack
+ {
+ void *ss_sp; /* Signal stack pointer. */
+ int ss_onstack; /* Nonzero if executing on this stack. */
+ };
+
+
+/* Possible values for `ss_flags.'. */
+enum
+{
+ SS_ONSTACK = 1,
+#define SS_ONSTACK SS_ONSTACK
+ SS_DISABLE
+#define SS_DISABLE SS_DISABLE
+};
+
+/* Minimum stack size for a signal handler. */
+#define MINSIGSTKSZ 4096
+
+/* System default stack size. */
+#define SIGSTKSZ 16384
+
+
+/* Alternate, preferred interface. */
+typedef struct sigaltstack
+ {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+ } stack_t;

390
SOURCES/glibc-rh1032435.patch

@ -0,0 +1,390 @@ @@ -0,0 +1,390 @@
commit 977f4b31b7ca4a4e498c397f3fd70510694bbd86
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Oct 30 16:13:37 2013 +0530

Fix reads for sizes larger than INT_MAX in AF_INET lookup

Currently for AF_INET lookups from the hosts file, buffer sizes larger
than INT_MAX silently overflow and may result in access beyond bounds
of a buffer. This happens when the number of results in an AF_INET
lookup in /etc/hosts are very large.

There are two aspects to the problem. One problem is that the size
computed from the buffer size is stored into an int, which results in
overflow for large sizes. Additionally, even if this size was
expanded, the function used to read content into the buffer (fgets)
accepts only int sizes. As a result, the fix is to have a function
wrap around fgets that calls it multiple times with int sizes if
necessary.

(The previous commit fixes upstream bug 16071.)

commit ac60763eac3d43b7234dd21286ad3ec3f17957fc
Author: Andreas Schwab <schwab@suse.de>
Date: Mon Jun 23 10:24:45 2014 +0200

Don't ignore too long lines in nss_files (BZ #17079)

commit e07aabba73ea62e7dfa0512507c92efb851fbdbe
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Sep 22 13:20:18 2015 +0200

Add test case for bug 18287

commit 90fa42a1d7b78de0d75f7e3af362275b2abe807f
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Sep 22 13:40:17 2015 +0200

Test in commit e07aabba73ea62e7dfa0512507c92efb851fbdbe is for bug 17079

diff -u b/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
--- b/nss/nss_files/files-XXX.c
+++ b/nss/nss_files/files-XXX.c
@@ -179,8 +179,53 @@
return NSS_STATUS_SUCCESS;
}
-/* Parsing the database file into `struct STRUCTURE' data structures. */

+typedef enum
+{
+ gcr_ok = 0,
+ gcr_error = -1,
+ gcr_overflow = -2
+} get_contents_ret;
+
+/* Hack around the fact that fgets only accepts int sizes. */
+static get_contents_ret
+get_contents (char *linebuf, size_t len, FILE *stream)
+{
+ size_t remaining_len = len;
+ char *curbuf = linebuf;
+
+ do
+ {
+ int curlen = ((remaining_len > (size_t) INT_MAX) ? INT_MAX
+ : remaining_len);
+
+ /* Terminate the line so that we can test for overflow. */
+ ((unsigned char *) curbuf)[curlen - 1] = 0xff;
+
+ char *p = fgets_unlocked (curbuf, curlen, stream);
+
+ /* EOF or read error. */
+ if (p == NULL)
+ return gcr_error;
+
+ /* Done reading in the line. */
+ if (((unsigned char *) curbuf)[curlen - 1] == 0xff)
+ return gcr_ok;
+
+ /* Drop the terminating '\0'. */
+ remaining_len -= curlen - 1;
+ curbuf += curlen - 1;
+ }
+ /* fgets copies one less than the input length. Our last iteration is of
+ REMAINING_LEN and once that is done, REMAINING_LEN is decremented by
+ REMAINING_LEN - 1, leaving the result as 1. */
+ while (remaining_len > 1);
+
+ /* This means that the current buffer was not large enough. */
+ return gcr_overflow;
+}
+
+/* Parsing the database file into `struct STRUCTURE' data structures. */
static enum nss_status
internal_getent (struct STRUCTURE *result,
char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO
@@ -188,7 +233,7 @@
{
char *p;
struct parser_data *data = (void *) buffer;
- int linebuflen = buffer + buflen - data->linebuffer;
+ size_t linebuflen = buffer + buflen - data->linebuffer;
int parse_result;

if (buflen < sizeof *data + 2)
@@ -200,17 +245,16 @@

do
{
- /* Terminate the line so that we can test for overflow. */
- ((unsigned char *) data->linebuffer)[linebuflen - 1] = '\xff';
+ get_contents_ret r = get_contents (data->linebuffer, linebuflen, stream);

- p = fgets_unlocked (data->linebuffer, linebuflen, stream);
- if (p == NULL)
+ if (r == gcr_error)
{
/* End of file or read error. */
H_ERRNO_SET (HOST_NOT_FOUND);
return NSS_STATUS_NOTFOUND;
}
- else if (((unsigned char *) data->linebuffer)[linebuflen - 1] != 0xff)
+
+ if (r == gcr_overflow)
{
/* The line is too long. Give the user the opportunity to
enlarge the buffer. */
@@ -219,7 +263,8 @@
return NSS_STATUS_TRYAGAIN;
}

- /* Skip leading blanks. */
+ /* Everything OK. Now skip leading blanks. */
+ p = data->linebuffer;
while (isspace (*p))
++p;
}

diff a/nss/bug17079.c b/nss/bug17079.c
--- /dev/null
+++ b/nss/bug17079.c
@@ -0,0 +1,236 @@
+/* Test for bug 17079: heap overflow in NSS with small buffers.
+ 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 <errno.h>
+#include <pwd.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Check if two passwd structs contain the same data. */
+static bool
+equal (const struct passwd *a, const struct passwd *b)
+{
+ return strcmp (a->pw_name, b->pw_name) == 0
+ && strcmp (a->pw_passwd, b->pw_passwd) == 0
+ && a->pw_uid == b->pw_uid
+ && a->pw_gid == b->pw_gid
+ && strcmp (a->pw_gecos, b->pw_gecos) == 0
+ && strcmp (a->pw_dir, b->pw_dir) == 0
+ && strcmp (a->pw_shell, b->pw_shell) == 0;
+}
+
+enum { MAX_TEST_ITEMS = 10 };
+static struct passwd test_items[MAX_TEST_ITEMS];
+static int test_count;
+
+/* Initialize test_items and test_count above, with data from the
+ passwd database. */
+static bool
+init_test_items (void)
+{
+ setpwent ();
+ do
+ {
+ struct passwd *pwd = getpwent ();
+ if (pwd == NULL)
+ break;
+ struct passwd *target = test_items + test_count;
+ target->pw_name = strdup (pwd->pw_name);
+ target->pw_passwd = strdup (pwd->pw_passwd);
+ target->pw_uid = pwd->pw_uid;
+ target->pw_gid = pwd->pw_gid;
+ target->pw_gecos = strdup (pwd->pw_gecos);
+ target->pw_dir = strdup (pwd->pw_dir);
+ target->pw_shell = strdup (pwd->pw_shell);
+ }
+ while (++test_count < MAX_TEST_ITEMS);
+ endpwent ();
+
+ /* Filter out those test items which cannot be looked up by name or
+ UID. */
+ bool found = false;
+ for (int i = 0; i < test_count; ++i)
+ {
+ struct passwd *pwd1 = getpwnam (test_items[i].pw_name);
+ struct passwd *pwd2 = getpwuid (test_items[i].pw_uid);
+ if (pwd1 == NULL || !equal (pwd1, test_items + i)
+ || pwd2 == NULL || !equal (pwd2, test_items + i))
+ test_items[i].pw_name = NULL;
+ else
+ found = true;
+ }
+
+ if (!found)
+ puts ("error: no accounts found which can be looked up by name and UID.");
+ return found;
+}
+
+/* Set to true if an error is encountered. */
+static bool errors;
+
+/* Return true if the padding has not been tampered with. */
+static bool
+check_padding (char *buffer, size_t size, char pad)
+{
+ char *end = buffer + size;
+ while (buffer < end)
+ {
+ if (*buffer != pad)
+ return false;
+ ++buffer;
+ }
+ return true;
+}
+
+/* Test one buffer size and padding combination. */
+static void
+test_one (const struct passwd *item, size_t buffer_size,
+ char pad, size_t padding_size)
+{
+ char *buffer = malloc (buffer_size + padding_size);
+ if (buffer == NULL)
+ {
+ puts ("error: malloc failure");
+ errors = true;
+ return;
+ }
+
+ struct passwd pwd;
+ struct passwd *result;
+ int ret;
+
+ /* Test getpwname_r. */
+ memset (buffer, pad, buffer_size + padding_size);
+ pwd = (struct passwd) {};
+ ret = getpwnam_r (item->pw_name, &pwd, buffer, buffer_size, &result);
+ if (!check_padding (buffer + buffer_size, padding_size, pad))
+ {
+ printf ("error: padding change: "
+ "name \"%s\", buffer size %zu, padding size %zu, pad 0x%02x\n",
+ item->pw_name, buffer_size, padding_size, (unsigned char) pad);
+ errors = true;
+ }
+ if (ret == 0)
+ {
+ if (result == NULL)
+ {
+ printf ("error: no data: name \"%s\", buffer size %zu\n",
+ item->pw_name, buffer_size);
+ errors = true;
+ }
+ else if (!equal (item, result))
+ {
+ printf ("error: lookup mismatch: name \"%s\", buffer size %zu\n",
+ item->pw_name, buffer_size);
+ errors = true;
+ }
+ }
+ else if (ret != ERANGE)
+ {
+ errno = ret;
+ printf ("error: lookup failure for name \"%s\": %m (%d)\n",
+ item->pw_name, ret);
+ errors = true;
+ }
+
+ /* Test getpwuid_r. */
+ memset (buffer, pad, buffer_size + padding_size);
+ pwd = (struct passwd) {};
+ ret = getpwuid_r (item->pw_uid, &pwd, buffer, buffer_size, &result);
+ if (!check_padding (buffer + buffer_size, padding_size, pad))
+ {
+ printf ("error: padding change: "
+ "UID %ld, buffer size %zu, padding size %zu, pad 0x%02x\n",
+ (long) item->pw_uid, buffer_size, padding_size,
+ (unsigned char) pad);
+ errors = true;
+ }
+ if (ret == 0)
+ {
+ if (result == NULL)
+ {
+ printf ("error: no data: UID %ld, buffer size %zu\n",
+ (long) item->pw_uid, buffer_size);
+ errors = true;
+ }
+ else if (!equal (item, result))
+ {
+ printf ("error: lookup mismatch: UID %ld, buffer size %zu\n",
+ (long) item->pw_uid, buffer_size);
+ errors = true;
+ }
+ }
+ else if (ret != ERANGE)
+ {
+ errno = ret;
+ printf ("error: lookup failure for UID \"%ld\": %m (%d)\n",
+ (long) item->pw_uid, ret);
+ errors = true;
+ }
+
+ free (buffer);
+}
+
+/* Test one buffer size with different paddings. */
+static void
+test_buffer_size (size_t buffer_size)
+{
+ for (int i = 0; i < test_count; ++i)
+ for (size_t padding_size = 0; padding_size < 3; ++padding_size)
+ {
+ test_one (test_items + i, buffer_size, '\0', padding_size);
+ if (padding_size > 0)
+ {
+ test_one (test_items + i, buffer_size, ':', padding_size);
+ test_one (test_items + i, buffer_size, '\n', padding_size);
+ test_one (test_items + i, buffer_size, '\xff', padding_size);
+ test_one (test_items + i, buffer_size, '@', padding_size);
+ }
+ }
+}
+
+int
+do_test (void)
+{
+ if (!init_test_items ())
+ return 1;
+ printf ("info: %d test items\n", test_count);
+
+ for (size_t buffer_size = 0; buffer_size <= 65; ++buffer_size)
+ test_buffer_size (buffer_size);
+ for (size_t buffer_size = 64 + 4; buffer_size < 256; buffer_size += 4)
+ test_buffer_size (buffer_size);
+ test_buffer_size (255);
+ test_buffer_size (257);
+ for (size_t buffer_size = 256; buffer_size < 512; buffer_size += 8)
+ test_buffer_size (buffer_size);
+ test_buffer_size (511);
+ test_buffer_size (513);
+ test_buffer_size (1024);
+ test_buffer_size (2048);
+
+ if (errors)
+ return 1;
+ else
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff a/nss/Makefile b/nss/Makefile
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -39,6 +39,6 @@
extra-objs += $(makedb-modules:=.o)

-tests = test-netdb tst-nss-test1
+tests = test-netdb tst-nss-test1 bug17079
xtests = bug-erange

include ../Makeconfig

102
SOURCES/glibc-rh1039496.patch

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
diff -urNglibc-2.17-c758a686/libio/tst-widetext.inputglibc-2.17-c758a686/libio/tst-widetext.input
--- glibc-2.17-c758a686/libio/tst-widetext.input 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686/libio/tst-widetext.input 2013-12-11 09:48:30.760084849 -0500
@@ -126,7 +126,7 @@
઀◌àª<EFBFBD>◌ંઃ઄અઆઇઈઉઊઋઌàª<EFBFBD>઎àª<EFBFBD>àª<EFBFBD>ઑ઒ઓઔકખગઘઙચછજàª<EFBFBD>ઞટઠડઢણતથદધન઩પફબભમયર઱લળ઴વશષસહ઺઻◌઼ઽાિ
ી◌à«<EFBFBD>◌ૂ◌ૃ◌ૄ◌ૅ૆◌ે◌ૈૉ૊ોૌ◌à«<EFBFBD>à«Žà«<EFBFBD>à«<EFBFBD>૑૒૓૔૕૖૗૘૙૚૛૜à«<EFBFBD>૞૟ૠૡૢૣ૤૥૦૧૨૩૪૫૬૭૮૯૰૱૲૳૴૵૶૷૸ૹૺૻૼ૽૾૿

-Oriya (U+0B00-U+0B7F):
+Odia (U+0B00-U+0B7F):

଀◌à¬<EFBFBD>ଂଃ଄ଅଆଇଈଉଊଋଌà¬<EFBFBD>଎à¬<EFBFBD>à¬<EFBFBD>଑଒ଓଔକଖଗଘଙଚଛଜà¬<EFBFBD>ଞଟଠଡଢଣତଥଦଧନ଩ପଫବଭମଯର଱ଲଳ଴ଵଶଷସହ଺଻◌଼ଽା◌ି
ୀ◌à­<EFBFBD>◌ୂ◌ୃୄ୅୆େୈ୉୊ୋୌ◌à­<EFBFBD>à­Žà­<EFBFBD>à­<EFBFBD>୑୒୓୔୕◌ୖୗ୘୙୚୛ଡ଼à­<EFBFBD>୞ୟୠୡୢୣ୤୥୦୧୨୩୪୫୬୭୮୯୰ୱ୲୳୴୵୶୷୸୹୺୻୼୽୾୿
diff -urNglibc-2.17-c758a686/locale/iso-639.defglibc-2.17-c758a686/locale/iso-639.def
--- glibc-2.17-c758a686/locale/iso-639.def 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686/locale/iso-639.def 2013-12-11 09:58:58.414959856 -0500
@@ -181,7 +181,7 @@
DEFINE_LANGUAGE_CODE ("Greek, Modern (1453-)", el, ell, gre)
DEFINE_LANGUAGE_CODE ("Guarani", gn, grn, grn)
DEFINE_LANGUAGE_CODE ("Gujarati", gu, guj, guj)
-DEFINE_LANGUAGE_CODE3 ("Gwich´in", gwi, gwi)
+DEFINE_LANGUAGE_CODE3 ("Gwich´in", gwi, gwi)
DEFINE_LANGUAGE_CODE3 ("Haida", hai, hai)
DEFINE_LANGUAGE_CODE ("Haitian; Haitian Creole", ht, hat, hat)
DEFINE_LANGUAGE_CODE ("Hausa", ha, hau, hau)
@@ -337,7 +337,7 @@
DEFINE_LANGUAGE_CODE3 ("North American Indian", nai, nai)
DEFINE_LANGUAGE_CODE ("Northern Sami", se, sme, sme)
DEFINE_LANGUAGE_CODE3 ("Northern Sotho; Pedi; Sepedi", nso, nso)
-DEFINE_LANGUAGE_CODE ("Norwegian Bokmål", nb, nob, nob)
+DEFINE_LANGUAGE_CODE ("Norwegian Bokmål", nb, nob, nob)
DEFINE_LANGUAGE_CODE ("Norwegian Nynorsk", nn, nno, nno)
DEFINE_LANGUAGE_CODE ("Norwegian", no, nor, nor)
DEFINE_LANGUAGE_CODE3 ("Nubian languages", nub, nub)
@@ -345,9 +345,9 @@
DEFINE_LANGUAGE_CODE3 ("Nyankole", nyn, nyn)
DEFINE_LANGUAGE_CODE3 ("Nyoro", nyo, nyo)
DEFINE_LANGUAGE_CODE3 ("Nzima", nzi, nzi)
-DEFINE_LANGUAGE_CODE ("Occitan (post 1500); Provençal", oc, oci, oci)
+DEFINE_LANGUAGE_CODE ("Occitan (post 1500); Provençal", oc, oci, oci)
DEFINE_LANGUAGE_CODE ("Ojibwa", oj, oji, oji)
-DEFINE_LANGUAGE_CODE ("Oriya", or, ori, ori)
+DEFINE_LANGUAGE_CODE ("Odia", or, ori, ori)
DEFINE_LANGUAGE_CODE ("Oromo", om, orm, orm)
DEFINE_LANGUAGE_CODE3 ("Osage", osa, osa)
DEFINE_LANGUAGE_CODE ("Ossetian; Ossetic", os, oss, oss)
@@ -368,7 +368,7 @@
DEFINE_LANGUAGE_CODE ("Polish", pl, pol, pol)
DEFINE_LANGUAGE_CODE ("Portuguese", pt, por, por)
DEFINE_LANGUAGE_CODE3 ("Prakrit languages", pra, pra)
-DEFINE_LANGUAGE_CODE3 ("Provençal, Old (to 1500)", pro, pro)
+DEFINE_LANGUAGE_CODE3 ("Provençal, Old (to 1500)", pro, pro)
DEFINE_LANGUAGE_CODE ("Pushto", ps, pus, pus)
DEFINE_LANGUAGE_CODE ("Quechua", qu, que, que)
DEFINE_LANGUAGE_CODE ("Raeto-Romance", rm, roh, roh)
@@ -476,7 +476,7 @@
DEFINE_LANGUAGE_CODE3 ("Vai", vai, vai)
DEFINE_LANGUAGE_CODE ("Venda", ve, ven, ven)
DEFINE_LANGUAGE_CODE ("Vietnamese", vi, vie, vie)
-DEFINE_LANGUAGE_CODE ("Volapük", vo, vol, vol)
+DEFINE_LANGUAGE_CODE ("Volapük", vo, vol, vol)
DEFINE_LANGUAGE_CODE3 ("Votic", vot, vot)
DEFINE_LANGUAGE_CODE3 ("Wakashan languages", wak, wak)
DEFINE_LANGUAGE_CODE3 ("Walser", wae, wae)
diff -urNglibc-2.17-c758a686/localedata/locales/or_INglibc-2.17-c758a686/localedata/locales/or_IN
--- glibc-2.17-c758a686/localedata/locales/or_IN 2012-12-24 22:02:13.000000000 -0500
+++ glibc-2.17-c758a686/localedata/locales/or_IN 2013-12-11 09:52:26.932931534 -0500
@@ -1,19 +1,19 @@
comment_char %
escape_char /

-% Oriya locale for India.
+% Odia locale for India.
% Contributed by Masahide Washizawa <washi at jp ibm com>

%%%%%%%%%%%%%
LC_IDENTIFICATION
-title "Oriya language locale for India"
+title "Odia language locale for India"
source "IBM AP Linux Technology Center, Yamato Software Laboratory"
address "1623-14, Shimotsuruma, Yamato-shi, Kanagawa-ken, 242-8502, Japan"
contact ""
email "bug-glibc@gnu.org"
tel ""
fax ""
-language "Oriya"
+language "Odia"
territory "India"
revision "1.0"
date "2006-05-25"
@@ -35,10 +35,10 @@
LC_CTYPE
copy "i18n"

-% Oriya uses the alternate digits U+0B66..U+0B6F
+% Odia uses the alternate digits U+0B66..U+0B6F
outdigit <U0B66>..<U0B6F>

-% This is used in the scanf family of functions to read Oriya numbers
+% This is used in the scanf family of functions to read Odia numbers
% using "%Id" and such.
map to_inpunct; /
(<U0030>,<U0B66>); /

135
SOURCES/glibc-rh1039970.patch

@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
commit 9a3c6a6ff602c88d7155139a7d7d0000b7b7e946
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Jan 2 10:05:27 2014 +0530

Fix return code from getent netgroup when the netgroup is not found (bz #16366)

diff -pruN glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c
--- glibc-2.17-c758a686/nscd/netgroupcache.c 2013-12-03 20:41:12.000000000 -0500
+++ glibc-2.17-c758a686/nscd/netgroupcache.c 2013-12-19 08:36:52.253000000 -0500
@@ -65,6 +65,55 @@ struct dataset
char strdata[0];
};

+/* Sends a notfound message and prepares a notfound dataset to write to the
+ cache. Returns true if there was enough memory to allocate the dataset and
+ returns the dataset in DATASETP, total bytes to write in TOTALP and the
+ timeout in TIMEOUTP. KEY_COPY is set to point to the copy of the key in the
+ dataset. */
+static bool
+do_notfound (struct database_dyn *db, int fd, request_header *req,
+ const char *key, struct dataset **datasetp, ssize_t *totalp,
+ time_t *timeoutp, char **key_copy)
+{
+ struct dataset *dataset;
+ ssize_t total;
+ time_t timeout;
+ bool cacheable = false;
+
+ total = sizeof (notfound);
+ timeout = time (NULL) + db->negtimeout;
+
+ if (fd != -1)
+ TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
+
+ dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
+ /* 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;
+
+ /* This is the reply. */
+ memcpy (&dataset->resp, &notfound, total);
+
+ /* Copy the key data. */
+ memcpy (dataset->strdata, key, req->key_len);
+ *key_copy = dataset->strdata;
+
+ cacheable = true;
+ }
+ *timeoutp = timeout;
+ *totalp = total;
+ *datasetp = dataset;
+ return cacheable;
+}

static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
@@ -84,6 +133,7 @@ addgetnetgrentX (struct database_dyn *db
struct dataset *dataset;
bool cacheable = false;
ssize_t total;
+ bool found = false;

char *key_copy = NULL;
struct __netgrent data;
@@ -103,35 +153,8 @@ addgetnetgrentX (struct database_dyn *db
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
{
/* No such service. */
- total = sizeof (notfound);
- timeout = time (NULL) + db->negtimeout;
-
- if (fd != -1)
- TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
-
- dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
- /* 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;
-
- /* This is the reply. */
- memcpy (&dataset->resp, &notfound, total);
-
- /* Copy the key data. */
- memcpy (dataset->strdata, key, req->key_len);
-
- cacheable = true;
- }
-
+ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+ &key_copy);
goto writeout;
}

@@ -167,6 +190,7 @@ addgetnetgrentX (struct database_dyn *db

if (status == NSS_STATUS_SUCCESS)
{
+ found = true;
union
{
enum nss_status (*f) (struct __netgrent *, char *, size_t,
@@ -325,6 +349,15 @@ addgetnetgrentX (struct database_dyn *db
}
}

+ /* No results. Return a failure and write out a notfound record in the
+ cache. */
+ if (!found)
+ {
+ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+ &key_copy);
+ goto writeout;
+ }
+
total = buffilled;

/* Fill in the dataset. */

23
SOURCES/glibc-rh1046199.patch

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
commit d41242129ba693cdbc8db85b846fcaccf9f0b7c4
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Jan 2 10:03:12 2014 +0530

Fix infinite loop in nscd when netgroup is empty (bz #16365)

diff -pruN glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c
--- glibc-2.17-c758a686/nscd/netgroupcache.c 2013-12-20 04:38:40.432000000 -0500
+++ glibc-2.17-c758a686/nscd/netgroupcache.c 2013-12-20 04:37:29.945000000 -0500
@@ -204,9 +204,10 @@ addgetnetgrentX (struct database_dyn *db
int e;
status = getfct.f (&data, buffer + buffilled,
buflen - buffilled, &e);
- if (status == NSS_STATUS_RETURN)
- /* This was the last one for this group. Look
- at next group if available. */
+ if (status == NSS_STATUS_RETURN
+ || status == NSS_STATUS_NOTFOUND)
+ /* This was either the last one for this group or the
+ group was empty. Look at next group if available. */
break;
if (status == NSS_STATUS_SUCCESS)
{

555
SOURCES/glibc-rh1047983.patch

@ -0,0 +1,555 @@ @@ -0,0 +1,555 @@
commit 5a4c6d53f50b264d60cf6453576ca2810c7890b7
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Nov 28 17:18:12 2013 +0530

Get canonical name in getaddrinfo from hosts file for AF_INET (fixes 16077)

AF_INET lookup in hosts file uses _nss_files_gethostbyname2_r, which
is not capable of returning a canonical name if it has found one.
This change adds _nss_files_gethostbyname3_r, which wraps around
_nss_files_gethostbyname2_r and then returns result.h_name as the
canonical name.

diff --git glibc-2.17-c758a686/nss/Versions glibc-2.17-c758a686/nss/Versions
index d13d570..f8ababc 100644
--- glibc-2.17-c758a686/nss/Versions
+++ glibc-2.17-c758a686/nss/Versions
@@ -40,6 +40,7 @@ libnss_files {
_nss_files_endhostent;
_nss_files_gethostbyaddr_r;
_nss_files_gethostbyname2_r;
+ _nss_files_gethostbyname3_r;
_nss_files_gethostbyname4_r;
_nss_files_gethostbyname_r;
_nss_files_gethostent_r;
diff --git glibc-2.17-c758a686/nss/nss_files/files-hosts.c glibc-2.17-c758a686/nss/nss_files/files-hosts.c
index 6db2535..957c9aa 100644
--- glibc-2.17-c758a686/nss/nss_files/files-hosts.c
+++ glibc-2.17-c758a686/nss/nss_files/files-hosts.c
@@ -97,262 +97,12 @@ LINE_PARSER
STRING_FIELD (result->h_name, isspace, 1);
})

-
-
-#define HOST_DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...) \
-enum nss_status \
-_nss_files_get##name##_r (proto, \
- struct STRUCTURE *result, char *buffer, \
- size_t buflen, int *errnop H_ERRNO_PROTO) \
-{ \
- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data); \
- buffer += pad; \
- buflen = buflen > pad ? buflen - pad : 0; \
- \
- __libc_lock_lock (lock); \
- \
- /* Reset file pointer to beginning or open file. */ \
- enum nss_status status = internal_setent (keep_stream); \
- \
- if (status == NSS_STATUS_SUCCESS) \
- { \
- /* Tell getent function that we have repositioned the file pointer. */ \
- last_use = getby; \
- \
- while ((status = internal_getent (result, buffer, buflen, errnop \
- H_ERRNO_ARG EXTRA_ARGS_VALUE)) \
- == NSS_STATUS_SUCCESS) \
- { break_if_match } \
- \
- if (status == NSS_STATUS_SUCCESS \
- && _res_hconf.flags & HCONF_FLAG_MULTI) \
- { \
- /* We have to get all host entries from the file. */ \
- size_t tmp_buflen = MIN (buflen, 4096); \
- char tmp_buffer_stack[tmp_buflen] \
- __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));\
- char *tmp_buffer = tmp_buffer_stack; \
- struct hostent tmp_result_buf; \
- int naddrs = 1; \
- int naliases = 0; \
- char *bufferend; \
- bool tmp_buffer_malloced = false; \
- \
- while (result->h_aliases[naliases] != NULL) \
- ++naliases; \
- \
- bufferend = (char *) &result->h_aliases[naliases + 1]; \
- \
- again: \
- while ((status = internal_getent (&tmp_result_buf, tmp_buffer, \
- tmp_buflen, errnop H_ERRNO_ARG \
- EXTRA_ARGS_VALUE)) \
- == NSS_STATUS_SUCCESS) \
- { \
- int matches = 1; \
- struct hostent *old_result = result; \
- result = &tmp_result_buf; \
- /* The following piece is a bit clumsy but we want to use the \
- `break_if_match' value. The optimizer should do its \
- job. */ \
- do \
- { \
- break_if_match \
- result = old_result; \
- } \
- while ((matches = 0)); \
- \
- if (matches) \
- { \
- /* We could be very clever and try to recycle a few bytes \
- in the buffer instead of generating new arrays. But \
- we are not doing this here since it's more work than \
- it's worth. Simply let the user provide a bit bigger \
- buffer. */ \
- char **new_h_addr_list; \
- char **new_h_aliases; \
- int newaliases = 0; \
- size_t newstrlen = 0; \
- int cnt; \
- \
- /* Count the new aliases and the length of the strings. */ \
- while (tmp_result_buf.h_aliases[newaliases] != NULL) \
- { \
- char *cp = tmp_result_buf.h_aliases[newaliases]; \
- ++newaliases; \
- newstrlen += strlen (cp) + 1; \
- } \
- /* If the real name is different add it also to the \
- aliases. This means that there is a duplication \
- in the alias list but this is really the user's \
- problem. */ \
- if (strcmp (old_result->h_name, \
- tmp_result_buf.h_name) != 0) \
- { \
- ++newaliases; \
- newstrlen += strlen (tmp_result_buf.h_name) + 1; \
- } \
- \
- /* Make sure bufferend is aligned. */ \
- assert ((bufferend - (char *) 0) % sizeof (char *) == 0); \
- \
- /* Now we can check whether the buffer is large enough. \
- 16 is the maximal size of the IP address. */ \
- if (bufferend + 16 + (naddrs + 2) * sizeof (char *) \
- + roundup (newstrlen, sizeof (char *)) \
- + (naliases + newaliases + 1) * sizeof (char *) \
- >= buffer + buflen) \
- { \
- *errnop = ERANGE; \
- *herrnop = NETDB_INTERNAL; \
- status = NSS_STATUS_TRYAGAIN; \
- goto out; \
- } \
- \
- new_h_addr_list = \
- (char **) (bufferend \
- + roundup (newstrlen, sizeof (char *)) \
- + 16); \
- new_h_aliases = \
- (char **) ((char *) new_h_addr_list \
- + (naddrs + 2) * sizeof (char *)); \
- \
- /* Copy the old data in the new arrays. */ \
- for (cnt = 0; cnt < naddrs; ++cnt) \
- new_h_addr_list[cnt] = old_result->h_addr_list[cnt]; \
- \
- for (cnt = 0; cnt < naliases; ++cnt) \
- new_h_aliases[cnt] = old_result->h_aliases[cnt]; \
- \
- /* Store the new strings. */ \
- cnt = 0; \
- while (tmp_result_buf.h_aliases[cnt] != NULL) \
- { \
- new_h_aliases[naliases++] = bufferend; \
- bufferend = (__stpcpy (bufferend, \
- tmp_result_buf.h_aliases[cnt]) \
- + 1); \
- ++cnt; \
- } \
- \
- if (cnt < newaliases) \
- { \
- new_h_aliases[naliases++] = bufferend; \
- bufferend = __stpcpy (bufferend, \
- tmp_result_buf.h_name) + 1; \
- } \
- \
- /* Final NULL pointer. */ \
- new_h_aliases[naliases] = NULL; \
- \
- /* Round up the buffer end address. */ \
- bufferend += (sizeof (char *) \
- - ((bufferend - (char *) 0) \
- % sizeof (char *))) % sizeof (char *); \
- \
- /* Now the new address. */ \
- new_h_addr_list[naddrs++] = \
- memcpy (bufferend, tmp_result_buf.h_addr, \
- tmp_result_buf.h_length); \
- \
- /* Also here a final NULL pointer. */ \
- new_h_addr_list[naddrs] = NULL; \
- \
- /* Store the new array pointers. */ \
- old_result->h_aliases = new_h_aliases; \
- old_result->h_addr_list = new_h_addr_list; \
- \
- /* Compute the new buffer end. */ \
- bufferend = (char *) &new_h_aliases[naliases + 1]; \
- assert (bufferend <= buffer + buflen); \
- \
- result = old_result; \
- } \
- } \
- \
- if (status == NSS_STATUS_TRYAGAIN) \
- { \
- size_t newsize = 2 * tmp_buflen; \
- if (tmp_buffer_malloced) \
- { \
- char *newp = realloc (tmp_buffer, newsize); \
- if (newp != NULL) \
- { \
- assert ((((uintptr_t) newp) \
- & (__alignof__ (struct hostent_data) - 1)) \
- == 0); \
- tmp_buffer = newp; \
- tmp_buflen = newsize; \
- goto again; \
- } \
- } \
- else if (!__libc_use_alloca (buflen + newsize)) \
- { \
- tmp_buffer = malloc (newsize); \
- if (tmp_buffer != NULL) \
- { \
- assert ((((uintptr_t) tmp_buffer) \
- & (__alignof__ (struct hostent_data) - 1)) \
- == 0); \
- tmp_buffer_malloced = true; \
- tmp_buflen = newsize; \
- goto again; \
- } \
- } \
- else \
- { \
- tmp_buffer \
- = extend_alloca (tmp_buffer, tmp_buflen, \
- newsize \
- + __alignof__ (struct hostent_data)); \
- tmp_buffer = (char *) (((uintptr_t) tmp_buffer \
- + __alignof__ (struct hostent_data) \
- - 1) \
- & ~(__alignof__ (struct hostent_data)\
- - 1)); \
- goto again; \
- } \
- } \
- else \
- status = NSS_STATUS_SUCCESS; \
- out: \
- if (tmp_buffer_malloced) \
- free (tmp_buffer); \
- } \
- \
- \
- if (! keep_stream) \
- internal_endent (); \
- } \
- \
- __libc_lock_unlock (lock); \
- \
- return status; \
-}
-
-
#define EXTRA_ARGS_VALUE \
, ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET), \
((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
#include "files-XXX.c"
-HOST_DB_LOOKUP (hostbyname, ,,
- {
- LOOKUP_NAME_CASE (h_name, h_aliases)
- }, const char *name)
#undef EXTRA_ARGS_VALUE

-
-/* XXX Is using _res to determine whether we want to convert IPv4 addresses
- to IPv6 addresses really the right thing to do? */
-#define EXTRA_ARGS_VALUE \
- , af, ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
-HOST_DB_LOOKUP (hostbyname2, ,,
- {
- LOOKUP_NAME_CASE (h_name, h_aliases)
- }, const char *name, int af)
-#undef EXTRA_ARGS_VALUE
-
-
/* We only need to consider IPv4 mapped addresses if the input to the
gethostbyaddr() function is an IPv6 address. */
#define EXTRA_ARGS_VALUE \
@@ -365,6 +115,263 @@ DB_LOOKUP (hostbyaddr, ,,,
}, const void *addr, socklen_t len, int af)
#undef EXTRA_ARGS_VALUE

+enum nss_status
+_nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result,
+ char *buffer, size_t buflen, int *errnop,
+ int *herrnop, int32_t *ttlp, char **canonp)
+{
+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data);
+ buffer += pad;
+ buflen = buflen > pad ? buflen - pad : 0;
+
+ __libc_lock_lock (lock);
+
+ /* Reset file pointer to beginning or open file. */
+ enum nss_status status = internal_setent (keep_stream);
+
+ if (status == NSS_STATUS_SUCCESS)
+ {
+ /* XXX Is using _res to determine whether we want to convert IPv4
+ addresses to IPv6 addresses really the right thing to do? */
+ int flags = ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0);
+
+ /* Tell getent function that we have repositioned the file pointer. */
+ last_use = getby;
+
+ while ((status = internal_getent (result, buffer, buflen, errnop,
+ herrnop, af, flags))
+ == NSS_STATUS_SUCCESS)
+ {
+ LOOKUP_NAME_CASE (h_name, h_aliases)
+ }
+
+ if (status == NSS_STATUS_SUCCESS
+ && _res_hconf.flags & HCONF_FLAG_MULTI)
+ {
+ /* We have to get all host entries from the file. */
+ size_t tmp_buflen = MIN (buflen, 4096);
+ char tmp_buffer_stack[tmp_buflen]
+ __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));
+ char *tmp_buffer = tmp_buffer_stack;
+ struct hostent tmp_result_buf;
+ int naddrs = 1;
+ int naliases = 0;
+ char *bufferend;
+ bool tmp_buffer_malloced = false;
+
+ while (result->h_aliases[naliases] != NULL)
+ ++naliases;
+
+ bufferend = (char *) &result->h_aliases[naliases + 1];
+
+ again:
+ while ((status = internal_getent (&tmp_result_buf, tmp_buffer,
+ tmp_buflen, errnop, herrnop, af,
+ flags))
+ == NSS_STATUS_SUCCESS)
+ {
+ int matches = 1;
+ struct hostent *old_result = result;
+ result = &tmp_result_buf;
+ /* The following piece is a bit clumsy but we want to use the
+ `LOOKUP_NAME_CASE' value. The optimizer should do its
+ job. */
+ do
+ {
+ LOOKUP_NAME_CASE (h_name, h_aliases)
+ result = old_result;
+ }
+ while ((matches = 0));
+
+ if (matches)
+ {
+ /* We could be very clever and try to recycle a few bytes
+ in the buffer instead of generating new arrays. But
+ we are not doing this here since it's more work than
+ it's worth. Simply let the user provide a bit bigger
+ buffer. */
+ char **new_h_addr_list;
+ char **new_h_aliases;
+ int newaliases = 0;
+ size_t newstrlen = 0;
+ int cnt;
+
+ /* Count the new aliases and the length of the strings. */
+ while (tmp_result_buf.h_aliases[newaliases] != NULL)
+ {
+ char *cp = tmp_result_buf.h_aliases[newaliases];
+ ++newaliases;
+ newstrlen += strlen (cp) + 1;
+ }
+ /* If the real name is different add it also to the
+ aliases. This means that there is a duplication
+ in the alias list but this is really the user's
+ problem. */
+ if (strcmp (old_result->h_name,
+ tmp_result_buf.h_name) != 0)
+ {
+ ++newaliases;
+ newstrlen += strlen (tmp_result_buf.h_name) + 1;
+ }
+
+ /* Make sure bufferend is aligned. */
+ assert ((bufferend - (char *) 0) % sizeof (char *) == 0);
+
+ /* Now we can check whether the buffer is large enough.
+ 16 is the maximal size of the IP address. */
+ if (bufferend + 16 + (naddrs + 2) * sizeof (char *)
+ + roundup (newstrlen, sizeof (char *))
+ + (naliases + newaliases + 1) * sizeof (char *)
+ >= buffer + buflen)
+ {
+ *errnop = ERANGE;
+ *herrnop = NETDB_INTERNAL;
+ status = NSS_STATUS_TRYAGAIN;
+ goto out;
+ }
+
+ new_h_addr_list =
+ (char **) (bufferend
+ + roundup (newstrlen, sizeof (char *))
+ + 16);
+ new_h_aliases =
+ (char **) ((char *) new_h_addr_list
+ + (naddrs + 2) * sizeof (char *));
+
+ /* Copy the old data in the new arrays. */
+ for (cnt = 0; cnt < naddrs; ++cnt)
+ new_h_addr_list[cnt] = old_result->h_addr_list[cnt];
+
+ for (cnt = 0; cnt < naliases; ++cnt)
+ new_h_aliases[cnt] = old_result->h_aliases[cnt];
+
+ /* Store the new strings. */
+ cnt = 0;
+ while (tmp_result_buf.h_aliases[cnt] != NULL)
+ {
+ new_h_aliases[naliases++] = bufferend;
+ bufferend = (__stpcpy (bufferend,
+ tmp_result_buf.h_aliases[cnt])
+ + 1);
+ ++cnt;
+ }
+
+ if (cnt < newaliases)
+ {
+ new_h_aliases[naliases++] = bufferend;
+ bufferend = __stpcpy (bufferend,
+ tmp_result_buf.h_name) + 1;
+ }
+
+ /* Final NULL pointer. */
+ new_h_aliases[naliases] = NULL;
+
+ /* Round up the buffer end address. */
+ bufferend += (sizeof (char *)
+ - ((bufferend - (char *) 0)
+ % sizeof (char *))) % sizeof (char *);
+
+ /* Now the new address. */
+ new_h_addr_list[naddrs++] =
+ memcpy (bufferend, tmp_result_buf.h_addr,
+ tmp_result_buf.h_length);
+
+ /* Also here a final NULL pointer. */
+ new_h_addr_list[naddrs] = NULL;
+
+ /* Store the new array pointers. */
+ old_result->h_aliases = new_h_aliases;
+ old_result->h_addr_list = new_h_addr_list;
+
+ /* Compute the new buffer end. */
+ bufferend = (char *) &new_h_aliases[naliases + 1];
+ assert (bufferend <= buffer + buflen);
+
+ result = old_result;
+ }
+ }
+
+ if (status == NSS_STATUS_TRYAGAIN)
+ {
+ size_t newsize = 2 * tmp_buflen;
+ if (tmp_buffer_malloced)
+ {
+ char *newp = realloc (tmp_buffer, newsize);
+ if (newp != NULL)
+ {
+ assert ((((uintptr_t) newp)
+ & (__alignof__ (struct hostent_data) - 1))
+ == 0);
+ tmp_buffer = newp;
+ tmp_buflen = newsize;
+ goto again;
+ }
+ }
+ else if (!__libc_use_alloca (buflen + newsize))
+ {
+ tmp_buffer = malloc (newsize);
+ if (tmp_buffer != NULL)
+ {
+ assert ((((uintptr_t) tmp_buffer)
+ & (__alignof__ (struct hostent_data) - 1))
+ == 0);
+ tmp_buffer_malloced = true;
+ tmp_buflen = newsize;
+ goto again;
+ }
+ }
+ else
+ {
+ tmp_buffer
+ = extend_alloca (tmp_buffer, tmp_buflen,
+ newsize
+ + __alignof__ (struct hostent_data));
+ tmp_buffer = (char *) (((uintptr_t) tmp_buffer
+ + __alignof__ (struct hostent_data)
+ - 1)
+ & ~(__alignof__ (struct hostent_data)
+ - 1));
+ goto again;
+ }
+ }
+ else
+ status = NSS_STATUS_SUCCESS;
+ out:
+ if (tmp_buffer_malloced)
+ free (tmp_buffer);
+ }
+
+ if (! keep_stream)
+ internal_endent ();
+ }
+
+ if (canonp && status == NSS_STATUS_SUCCESS)
+ *canonp = result->h_name;
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_files_gethostbyname_r (const char *name, struct hostent *result,
+ char *buffer, size_t buflen, int *errnop,
+ int *herrnop)
+{
+ int af = ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET);
+
+ return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen,
+ errnop, herrnop, NULL, NULL);
+}
+
+enum nss_status
+_nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result,
+ char *buffer, size_t buflen, int *errnop,
+ int *herrnop)
+{
+ return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen,
+ errnop, herrnop, NULL, NULL);
+}

enum nss_status
_nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,

29
SOURCES/glibc-rh1048036.patch

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
diff --git glibc-2.17-c758a686/libio/wfileops.c glibc-2.17-c758a686/libio/wfileops.c
index 87d3cdc..877fc1f 100644
--- glibc-2.17-c758a686/libio/wfileops.c
+++ glibc-2.17-c758a686/libio/wfileops.c
@@ -715,7 +715,7 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
- fp->_wide_data->_IO_write_base) / clen;
else
{
- enum __codecvt_result status;
+ enum __codecvt_result status = __codecvt_ok;
delta = (fp->_wide_data->_IO_write_ptr
- fp->_wide_data->_IO_write_base);
const wchar_t *write_base = fp->_wide_data->_IO_write_base;
@@ -728,9 +728,12 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
flush buffers for every ftell. */
do
{
- /* Ugh, no point trying to avoid the flush. Just do it
- and go back to how it was with the read mode. */
- if (delta > 0 && new_write_ptr == fp->_IO_buf_end)
+ /* There is not enough space in the buffer to do the entire
+ conversion, so there is no point trying to avoid the
+ buffer flush. Just do it and go back to how it was with
+ the read mode. */
+ if (status == __codecvt_partial
+ || (delta > 0 && new_write_ptr == fp->_IO_buf_end))
{
if (_IO_switch_to_wget_mode (fp))
return WEOF;

515
SOURCES/glibc-rh1048123.patch

@ -0,0 +1,515 @@ @@ -0,0 +1,515 @@
commit 0582f6b3d6fab2128ee43a06250571922ee7c1e3
Author: Andreas Schwab <schwab@suse.de>
Date: Sun Dec 23 09:45:07 2012 +0100

nscd: don't fork twice

commit 532a60357ef4c5852cc1bf836cfd9d6f093ef204
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Mon Mar 3 22:51:39 2014 +0530

nscd: Improved support for tracking startup failure in nscd service (BZ #16639)

Currently, the nscd parent process parses commandline options and
configuration, forks on startup and immediately exits with a success.
If the child process encounters some error after this, it goes
undetected and any services started up after it may have to repeatedly
check to make sure that the nscd service did actually start up and is
serving requests.

To make this process more reliable, I have added a pipe between the
parent and child process, through which the child process sends a
notification to the parent informing it of its status. The parent
waits for this status and once it receives it, exits with the
corresponding exit code. So if the child service sends a success
status (0), the parent exits with a success status. Similarly for
error conditions, the child sends the non-zero status code, which the
parent passes on as the exit code.

This, along with setting the nscd service type to forking in its
systemd configuration file, allows systemd to be certain that the nscd
service is ready and is accepting connections.


diff --git glibc-2.17-c758a686/nscd/connections.c glibc-2.17-c758a686/nscd/connections.c
index f463f45..180ae77 100644
--- glibc-2.17-c758a686/nscd/connections.c
+++ glibc-2.17-c758a686/nscd/connections.c
@@ -649,8 +649,8 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
close (fd);
}
else if (errno == EACCES)
- error (EXIT_FAILURE, 0, _("cannot access '%s'"),
- dbs[cnt].db_filename);
+ do_exit (EXIT_FAILURE, 0, _("cannot access '%s'"),
+ dbs[cnt].db_filename);
}

if (dbs[cnt].head == NULL)
@@ -699,8 +699,7 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
{
dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
dbnames[cnt], dbs[cnt].db_filename);
- // XXX Correct way to terminate?
- exit (1);
+ do_exit (1, 0, NULL);
}

if (dbs[cnt].persistent)
@@ -867,7 +866,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
if (sock < 0)
{
dbg_log (_("cannot open socket: %s"), strerror (errno));
- exit (errno == EACCES ? 4 : 1);
+ do_exit (errno == EACCES ? 4 : 1, 0, NULL);
}
/* Bind a name to the socket. */
struct sockaddr_un sock_addr;
@@ -876,7 +875,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
{
dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
- exit (errno == EACCES ? 4 : 1);
+ do_exit (errno == EACCES ? 4 : 1, 0, NULL);
}

#ifndef __ASSUME_SOCK_CLOEXEC
@@ -888,7 +887,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
{
dbg_log (_("cannot change socket to nonblocking mode: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}

/* The descriptor needs to be closed on exec. */
@@ -896,7 +895,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
{
dbg_log (_("cannot set socket to close on exec: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}
}
#endif
@@ -909,7 +908,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
{
dbg_log (_("cannot enable socket to accept connections: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}

#ifdef HAVE_NETLINK
@@ -953,7 +952,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
dbg_log (_("\
cannot change socket to nonblocking mode: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}

/* The descriptor needs to be closed on exec. */
@@ -962,7 +961,7 @@ cannot change socket to nonblocking mode: %s"),
{
dbg_log (_("cannot set socket to close on exec: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}
}
# endif
@@ -2392,7 +2391,7 @@ start_threads (void)
if (pthread_cond_init (&dbs[i].prune_cond, &condattr) != 0)
{
dbg_log (_("could not initialize conditional variable"));
- exit (1);
+ do_exit (1, 0, NULL);
}

pthread_t th;
@@ -2400,7 +2399,7 @@ start_threads (void)
&& pthread_create (&th, &attr, nscd_run_prune, (void *) i) != 0)
{
dbg_log (_("could not start clean-up thread; terminating"));
- exit (1);
+ do_exit (1, 0, NULL);
}
}

@@ -2414,13 +2413,17 @@ start_threads (void)
if (i == 0)
{
dbg_log (_("could not start any worker thread; terminating"));
- exit (1);
+ do_exit (1, 0, NULL);
}

break;
}
}

+ /* Now it is safe to let the parent know that we're doing fine and it can
+ exit. */
+ notify_parent (0);
+
/* Determine how much room for descriptors we should initially
allocate. This might need to change later if we cap the number
with MAXCONN. */
@@ -2465,8 +2468,8 @@ begin_drop_privileges (void)
if (pwd == NULL)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- error (EXIT_FAILURE, 0, _("Failed to run nscd as user '%s'"),
- server_user);
+ do_exit (EXIT_FAILURE, 0,
+ _("Failed to run nscd as user '%s'"), server_user);
}

server_uid = pwd->pw_uid;
@@ -2483,7 +2486,8 @@ begin_drop_privileges (void)
{
/* This really must never happen. */
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- error (EXIT_FAILURE, errno, _("initial getgrouplist failed"));
+ do_exit (EXIT_FAILURE, errno,
+ _("initial getgrouplist failed"));
}

server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t));
@@ -2492,7 +2496,7 @@ begin_drop_privileges (void)
== -1)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- error (EXIT_FAILURE, errno, _("getgrouplist failed"));
+ do_exit (EXIT_FAILURE, errno, _("getgrouplist failed"));
}
}

@@ -2510,7 +2514,7 @@ finish_drop_privileges (void)
if (setgroups (server_ngroups, server_groups) == -1)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- error (EXIT_FAILURE, errno, _("setgroups failed"));
+ do_exit (EXIT_FAILURE, errno, _("setgroups failed"));
}

int res;
@@ -2521,8 +2525,7 @@ finish_drop_privileges (void)
if (res == -1)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- perror ("setgid");
- exit (4);
+ do_exit (4, errno, "setgid");
}

if (paranoia)
@@ -2532,8 +2535,7 @@ finish_drop_privileges (void)
if (res == -1)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- perror ("setuid");
- exit (4);
+ do_exit (4, errno, "setuid");
}

#if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
diff --git glibc-2.17-c758a686/nscd/nscd.c glibc-2.17-c758a686/nscd/nscd.c
index 63d9d83..5680378 100644
--- glibc-2.17-c758a686/nscd/nscd.c
+++ glibc-2.17-c758a686/nscd/nscd.c
@@ -39,6 +39,8 @@
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/un.h>
+#include <sys/wait.h>
+#include <stdarg.h>

#include "dbg_log.h"
#include "nscd.h"
@@ -101,6 +103,7 @@ gid_t old_gid;

static int check_pid (const char *file);
static int write_pid (const char *file);
+static int monitor_child (int fd);

/* Name and version of program. */
static void print_version (FILE *stream, struct argp_state *state);
@@ -142,6 +145,7 @@ static struct argp argp =

/* True if only statistics are requested. */
static bool get_stats;
+static int parent_fd = -1;

int
main (int argc, char **argv)
@@ -196,11 +200,27 @@ main (int argc, char **argv)
/* Behave like a daemon. */
if (run_mode == RUN_DAEMONIZE)
{
+ int fd[2];
+
+ if (pipe (fd) != 0)
+ error (EXIT_FAILURE, errno,
+ _("cannot create a pipe to talk to the child"));
+
pid = fork ();
if (pid == -1)
error (EXIT_FAILURE, errno, _("cannot fork"));
if (pid != 0)
- exit (0);
+ {
+ /* The parent only reads from the child. */
+ close (fd[1]);
+ exit (monitor_child (fd[0]));
+ }
+ else
+ {
+ /* The child only writes to the parent. */
+ close (fd[0]);
+ parent_fd = fd[1];
+ }
}

int nullfd = open (_PATH_DEVNULL, O_RDWR);
@@ -242,7 +262,8 @@ main (int argc, char **argv)
char *endp;
long int fdn = strtol (dirent->d_name, &endp, 10);

- if (*endp == '\0' && fdn != dfdn && fdn >= min_close_fd)
+ if (*endp == '\0' && fdn != dfdn && fdn >= min_close_fd
+ && fdn != parent_fd)
close ((int) fdn);
}

@@ -250,22 +271,14 @@ main (int argc, char **argv)
}
else
for (i = min_close_fd; i < getdtablesize (); i++)
- close (i);
+ if (i != parent_fd)
+ close (i);

- if (run_mode == RUN_DAEMONIZE)
- {
- pid = fork ();
- if (pid == -1)
- error (EXIT_FAILURE, errno, _("cannot fork"));
- if (pid != 0)
- exit (0);
- }
-
setsid ();

if (chdir ("/") != 0)
- error (EXIT_FAILURE, errno,
- _("cannot change current working directory to \"/\""));
+ do_exit (EXIT_FAILURE, errno,
+ _("cannot change current working directory to \"/\""));

openlog ("nscd", LOG_CONS | LOG_ODELAY, LOG_DAEMON);

@@ -592,3 +614,79 @@ write_pid (const char *file)

return result;
}
+
+static int
+monitor_child (int fd)
+{
+ int child_ret = 0;
+ int ret = read (fd, &child_ret, sizeof (child_ret));
+
+ /* The child terminated with an error, either via exit or some other abnormal
+ method, like a segfault. */
+ if (ret <= 0 || child_ret != 0)
+ {
+ int err = wait (&child_ret);
+
+ if (err < 0)
+ {
+ fprintf (stderr, _("wait failed"));
+ return 1;
+ }
+
+ fprintf (stderr, _("child exited with status %d"),
+ WEXITSTATUS (child_ret));
+ if (WIFSIGNALED (child_ret))
+ fprintf (stderr, _(", terminated by signal %d.\n"),
+ WTERMSIG (child_ret));
+ else
+ fprintf (stderr, ".\n");
+ }
+
+ /* We have the child status, so exit with that code. */
+ close (fd);
+
+ return child_ret;
+}
+
+void
+do_exit (int child_ret, int errnum, const char *format, ...)
+{
+ if (parent_fd != -1)
+ {
+ int ret = write (parent_fd, &child_ret, sizeof (child_ret));
+ assert (ret == sizeof (child_ret));
+ close (parent_fd);
+ }
+
+ if (format != NULL)
+ {
+ /* Emulate error() since we don't have a va_list variant for it. */
+ va_list argp;
+
+ fflush (stdout);
+
+ fprintf (stderr, "%s: ", program_invocation_name);
+
+ va_start (argp, format);
+ vfprintf (stderr, format, argp);
+ va_end (argp);
+
+ fprintf (stderr, ": %s\n", strerror (errnum));
+ fflush (stderr);
+ }
+
+ /* Finally, exit. */
+ exit (child_ret);
+}
+
+void
+notify_parent (int child_ret)
+{
+ if (parent_fd == -1)
+ return;
+
+ int ret = write (parent_fd, &child_ret, sizeof (child_ret));
+ assert (ret == sizeof (child_ret));
+ close (parent_fd);
+ parent_fd = -1;
+}
diff --git glibc-2.17-c758a686/nscd/nscd.h glibc-2.17-c758a686/nscd/nscd.h
index 972f462..529b3f5 100644
--- glibc-2.17-c758a686/nscd/nscd.h
+++ glibc-2.17-c758a686/nscd/nscd.h
@@ -205,6 +205,8 @@ extern gid_t old_gid;
/* nscd.c */
extern void termination_handler (int signum) __attribute__ ((__noreturn__));
extern int nscd_open_socket (void);
+void notify_parent (int child_ret);
+void do_exit (int child_ret, int errnum, const char *format, ...);

/* connections.c */
extern void nscd_init (void);
diff --git glibc-2.17-c758a686/nscd/selinux.c glibc-2.17-c758a686/nscd/selinux.c
index e477254..46b0ea9 100644
--- glibc-2.17-c758a686/nscd/selinux.c
+++ glibc-2.17-c758a686/nscd/selinux.c
@@ -179,7 +179,7 @@ preserve_capabilities (void)
if (prctl (PR_SET_KEEPCAPS, 1) == -1)
{
dbg_log (_("Failed to set keep-capabilities"));
- error (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
+ do_exit (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
/* NOTREACHED */
}

@@ -194,7 +194,7 @@ preserve_capabilities (void)
cap_free (tmp_caps);

dbg_log (_("Failed to initialize drop of capabilities"));
- error (EXIT_FAILURE, 0, _("cap_init failed"));
+ do_exit (EXIT_FAILURE, 0, _("cap_init failed"));
}

/* There is no reason why these should not work. */
@@ -216,7 +216,7 @@ preserve_capabilities (void)
{
cap_free (new_caps);
dbg_log (_("Failed to drop capabilities"));
- error (EXIT_FAILURE, 0, _("cap_set_proc failed"));
+ do_exit (EXIT_FAILURE, 0, _("cap_set_proc failed"));
}

return new_caps;
@@ -233,7 +233,7 @@ install_real_capabilities (cap_t new_caps)
{
cap_free (new_caps);
dbg_log (_("Failed to drop capabilities"));
- error (EXIT_FAILURE, 0, _("cap_set_proc failed"));
+ do_exit (EXIT_FAILURE, 0, _("cap_set_proc failed"));
/* NOTREACHED */
}

@@ -242,7 +242,7 @@ install_real_capabilities (cap_t new_caps)
if (prctl (PR_SET_KEEPCAPS, 0) == -1)
{
dbg_log (_("Failed to unset keep-capabilities"));
- error (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
+ do_exit (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
/* NOTREACHED */
}
}
@@ -258,7 +258,7 @@ nscd_selinux_enabled (int *selinux_enabled)
if (*selinux_enabled < 0)
{
dbg_log (_("Failed to determine if kernel supports SELinux"));
- exit (EXIT_FAILURE);
+ do_exit (EXIT_FAILURE, 0, NULL);
}
}

@@ -272,7 +272,7 @@ avc_create_thread (void (*run) (void))
rc =
pthread_create (&avc_notify_thread, NULL, (void *(*) (void *)) run, NULL);
if (rc != 0)
- error (EXIT_FAILURE, rc, _("Failed to start AVC thread"));
+ do_exit (EXIT_FAILURE, rc, _("Failed to start AVC thread"));

return &avc_notify_thread;
}
@@ -294,7 +294,7 @@ avc_alloc_lock (void)

avc_mutex = malloc (sizeof (pthread_mutex_t));
if (avc_mutex == NULL)
- error (EXIT_FAILURE, errno, _("Failed to create AVC lock"));
+ do_exit (EXIT_FAILURE, errno, _("Failed to create AVC lock"));
pthread_mutex_init (avc_mutex, NULL);

return avc_mutex;
@@ -334,7 +334,7 @@ nscd_avc_init (void)
avc_entry_ref_init (&aeref);

if (avc_init ("avc", NULL, &log_cb, &thread_cb, &lock_cb) < 0)
- error (EXIT_FAILURE, errno, _("Failed to start AVC"));
+ do_exit (EXIT_FAILURE, errno, _("Failed to start AVC"));
else
dbg_log (_("Access Vector Cache (AVC) started"));
#ifdef HAVE_LIBAUDIT
--- glibc-2.17-c758a686/releng/nscd.service 2012-11-06 03:03:19.000000000 +0530
+++ glibc-2.17-c758a686/releng/nscd.service 2014-02-28 16:59:51.096630222 +0530
@@ -1,10 +1,13 @@
+# systemd service file for nscd
+
[Unit]
Description=Name Service Cache Daemon
After=syslog.target

[Service]
+Type=forking
EnvironmentFile=-/etc/sysconfig/nscd
-ExecStart=/usr/sbin/nscd --foreground $NSCD_OPTIONS
+ExecStart=/usr/sbin/nscd $NSCD_OPTIONS
ExecStop=/usr/sbin/nscd --shutdown
ExecReload=/usr/sbin/nscd -i passwd
ExecReload=/usr/sbin/nscd -i group
@@ -12,6 +14,7 @@
ExecReload=/usr/sbin/nscd -i services
ExecReload=/usr/sbin/nscd -i netgroup
Restart=always
+PIDFile=/run/nscd/nscd.pid

[Install]
WantedBy=multi-user.target

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save