summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--patches/binutils-2.24/0001-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch36
-rw-r--r--patches/binutils-2.24/series4
-rw-r--r--patches/glibc-2.18/0001-ARM-Fix-clone-code-when-built-for-Thumb.patch35
-rw-r--r--patches/glibc-2.18/0002-Fix-PI-mutex-check-in-pthread_cond_broadcast-and-pth.patch51
-rw-r--r--patches/glibc-2.18/0003-ARM-Fix-memcpy-computed-jump-calculations-for-ARM_AL.patch70
-rw-r--r--patches/glibc-2.18/0004-Accept-make-versions-4.0-and-greater.patch35
-rw-r--r--patches/glibc-2.18/0005-Simplify-strcoll-implementation.patch795
-rw-r--r--patches/glibc-2.18/0006-Fall-back-to-non-cached-sequence-traversal-and-compa.patch384
-rw-r--r--patches/glibc-2.18/0007-Check-for-integer-overflow-in-cache-size-computation.patch121
-rw-r--r--patches/glibc-2.18/0008-BZ-15754-CVE-2013-4788.patch199
-rw-r--r--patches/glibc-2.18/0009-CVE-2013-4237-BZ-14699-Buffer-overflow-in-readdir_r.patch171
-rw-r--r--patches/glibc-2.18/0010-malloc-Check-for-integer-overflow-in-pvalloc.patch37
-rw-r--r--patches/glibc-2.18/0011-malloc-Check-for-integer-overflow-in-valloc.patch37
-rw-r--r--patches/glibc-2.18/0012-malloc-Check-for-integer-overflow-in-memalign.patch37
-rw-r--r--patches/glibc-2.18/0013-Fix-stack-overflow-due-to-large-AF_INET6-requests.patch51
-rw-r--r--patches/glibc-2.18/0100-add-install-lib-all-target.patch35
-rw-r--r--patches/glibc-2.18/0101-don-t-regen-docs-if-perl-is-not-found.patch35
-rw-r--r--patches/glibc-2.18/0200-Fix-localedef-segfault-when-run-under-exec-shield-Pa.patch67
-rw-r--r--patches/glibc-2.18/0300-resolv-dynamic.patch47
-rw-r--r--patches/glibc-2.18/0400-optimized-string-functions-for-NEON-from-Linaro.patch699
-rw-r--r--patches/glibc-2.18/0401-add-libc_hidden_builtin_def-for-all-cortex-functions.patch64
-rw-r--r--patches/glibc-2.18/series27
-rw-r--r--patches/m4-1.4.18/0001-fflush-adjust-to-glibc-2.28-libio.h-removal.patch159
-rw-r--r--patches/m4-1.4.18/series4
-rw-r--r--ptxconfigs/powerpc-603e-linux-gnu-gcc-5.4.0-glibc-2.18-binutils-2.24-kernel-2.6.29.6-sanitized.ptxconfig142
-rw-r--r--rules/host-m4.make46
-rwxr-xr-xscripts/make_deb.sh6
27 files changed, 3391 insertions, 3 deletions
diff --git a/patches/binutils-2.24/0001-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch b/patches/binutils-2.24/0001-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch
new file mode 100644
index 0000000..ac35c20
--- /dev/null
+++ b/patches/binutils-2.24/0001-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch
@@ -0,0 +1,36 @@
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Tue, 1 Nov 2011 16:45:55 +0100
+Subject: [PATCH] Only generate an RPATH entry if LD_RUN_PATH is not empty, for
+ cases where -rpath isn't specified.
+
+This is http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=151024
+
+This patch is still used in debian binutils 2.24-1
+
+Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
+---
+ ld/emultempl/elf32.em | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
+index 3128255..27a2a96 100644
+--- a/ld/emultempl/elf32.em
++++ b/ld/emultempl/elf32.em
+@@ -1278,6 +1278,8 @@ fragment <<EOF
+ && command_line.rpath == NULL)
+ {
+ lib_path = (const char *) getenv ("LD_RUN_PATH");
++ if ((lib_path) && (strlen (lib_path) == 0))
++ lib_path = NULL;
+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
+ force))
+ break;
+@@ -1505,6 +1507,8 @@ gld${EMULATION_NAME}_before_allocation (void)
+ rpath = command_line.rpath;
+ if (rpath == NULL)
+ rpath = (const char *) getenv ("LD_RUN_PATH");
++ if ((rpath) && (strlen (rpath) == 0))
++ rpath = NULL;
+
+ for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
diff --git a/patches/binutils-2.24/series b/patches/binutils-2.24/series
new file mode 100644
index 0000000..59e5333
--- /dev/null
+++ b/patches/binutils-2.24/series
@@ -0,0 +1,4 @@
+# generated by git-ptx-patches
+#tag:base --start-number 1
+0001-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch
+# 2bc8f5caabd1d41386e8713e7cb558dc - git-ptx-patches magic
diff --git a/patches/glibc-2.18/0001-ARM-Fix-clone-code-when-built-for-Thumb.patch b/patches/glibc-2.18/0001-ARM-Fix-clone-code-when-built-for-Thumb.patch
new file mode 100644
index 0000000..78bf5f9
--- /dev/null
+++ b/patches/glibc-2.18/0001-ARM-Fix-clone-code-when-built-for-Thumb.patch
@@ -0,0 +1,35 @@
+From: Will Newton <will.newton@linaro.org>
+Date: Thu, 29 Aug 2013 20:10:26 +0100
+Subject: [PATCH] ARM: Fix clone code when built for Thumb.
+
+The mov lr, pc instruction will lose the Thumb bit from the return address
+so use blx lr instead.
+
+ports/ChangeLog.arm:
+
+2013-08-30 Will Newton <will.newton@linaro.org>
+
+ [BZ #15909]
+ * sysdeps/unix/sysv/linux/arm/clone.S (__clone): Use blx
+ instead of mov lr, pc.
+
+(cherry picked from commit 6b06ac56cdfc9293908724e51e827534e97819aa)
+---
+ ports/sysdeps/unix/sysv/linux/arm/clone.S | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ports/sysdeps/unix/sysv/linux/arm/clone.S b/ports/sysdeps/unix/sysv/linux/arm/clone.S
+index ce9c2a5..6e74fa7 100644
+--- a/ports/sysdeps/unix/sysv/linux/arm/clone.S
++++ b/ports/sysdeps/unix/sysv/linux/arm/clone.S
+@@ -93,8 +93,8 @@ PSEUDO_END (__clone)
+ mov lr, pc
+ bx ip
+ #else
+- mov lr, pc
+- ldr pc, [sp], #8
++ ldr lr, [sp], #8
++ blx lr
+ #endif
+
+ @ and we are done, passing the return value through r0
diff --git a/patches/glibc-2.18/0002-Fix-PI-mutex-check-in-pthread_cond_broadcast-and-pth.patch b/patches/glibc-2.18/0002-Fix-PI-mutex-check-in-pthread_cond_broadcast-and-pth.patch
new file mode 100644
index 0000000..a255632
--- /dev/null
+++ b/patches/glibc-2.18/0002-Fix-PI-mutex-check-in-pthread_cond_broadcast-and-pth.patch
@@ -0,0 +1,51 @@
+From: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date: Thu, 3 Oct 2013 08:26:21 +0530
+Subject: [PATCH] Fix PI mutex check in pthread_cond_broadcast and
+ pthread_cond_signal
+
+Fixes BZ #15996.
+
+The check had a typo - it checked for PTHREAD_MUTEX_ROBUST_NP instead
+of PTHREAD_MUTEX_ROBUST_NORMAL_NP. It has now been replaced by the
+already existing convenience macro USE_REQUEUE_PI.
+---
+ nptl/pthread_cond_broadcast.c | 5 +----
+ nptl/pthread_cond_signal.c | 7 +------
+ 2 files changed, 2 insertions(+), 10 deletions(-)
+
+diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
+index 0702ec0..7ba9efa 100644
+--- a/nptl/pthread_cond_broadcast.c
++++ b/nptl/pthread_cond_broadcast.c
+@@ -63,10 +63,7 @@ __pthread_cond_broadcast (cond)
+
+ #if (defined lll_futex_cmp_requeue_pi \
+ && defined __ASSUME_REQUEUE_PI)
+- int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
+- pi_flag &= mut->__data.__kind;
+-
+- if (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP)
++ if (USE_REQUEUE_PI (mut))
+ {
+ if (lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, INT_MAX,
+ &mut->__data.__lock, futex_val,
+diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
+index 102d0b3..ffc35dc 100644
+--- a/nptl/pthread_cond_signal.c
++++ b/nptl/pthread_cond_signal.c
+@@ -49,14 +49,9 @@ __pthread_cond_signal (cond)
+
+ #if (defined lll_futex_cmp_requeue_pi \
+ && defined __ASSUME_REQUEUE_PI)
+- int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
+ pthread_mutex_t *mut = cond->__data.__mutex;
+
+- /* Do not use requeue for pshared condvars. */
+- if (mut != (void *) ~0l)
+- pi_flag &= mut->__data.__kind;
+-
+- if (__builtin_expect (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP, 0)
++ if (USE_REQUEUE_PI (mut)
+ /* This can only really fail with a ENOSYS, since nobody can modify
+ futex while we have the cond_lock. */
+ && lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, 0,
diff --git a/patches/glibc-2.18/0003-ARM-Fix-memcpy-computed-jump-calculations-for-ARM_AL.patch b/patches/glibc-2.18/0003-ARM-Fix-memcpy-computed-jump-calculations-for-ARM_AL.patch
new file mode 100644
index 0000000..e02a24d
--- /dev/null
+++ b/patches/glibc-2.18/0003-ARM-Fix-memcpy-computed-jump-calculations-for-ARM_AL.patch
@@ -0,0 +1,70 @@
+From: Roland McGrath <roland@hack.frob.com>
+Date: Fri, 22 Nov 2013 11:39:20 -0800
+Subject: [PATCH] ARM: Fix memcpy computed-jump calculations for ARM_ALWAYS_BX
+ case.
+
+---
+ ports/sysdeps/arm/arm-features.h | 8 --------
+ ports/sysdeps/arm/armv7/multiarch/memcpy_impl.S | 21 +++++++++++----------
+ 2 files changed, 11 insertions(+), 18 deletions(-)
+
+diff --git a/ports/sysdeps/arm/arm-features.h b/ports/sysdeps/arm/arm-features.h
+index 1d4b0f1..336b690 100644
+--- a/ports/sysdeps/arm/arm-features.h
++++ b/ports/sysdeps/arm/arm-features.h
+@@ -53,14 +53,6 @@
+ # define ARM_BX_ALIGN_LOG2 2
+ #endif
+
+-/* The number of instructions that 'bx' expands to. A more-specific
+- arm-features.h that defines 'bx' as a macro should define this to the
+- number instructions it expands to. This is used only in a context
+- where the 'bx' expansion won't cross an ARM_BX_ALIGN_LOG2 boundary. */
+-#ifndef ARM_BX_NINSNS
+-# define ARM_BX_NINSNS 1
+-#endif
+-
+ /* An OS-specific arm-features.h file may define ARM_NO_INDEX_REGISTER to
+ indicate that the two-register addressing modes must never be used. */
+
+diff --git a/ports/sysdeps/arm/armv7/multiarch/memcpy_impl.S b/ports/sysdeps/arm/armv7/multiarch/memcpy_impl.S
+index 3decad6..5ed076e 100644
+--- a/ports/sysdeps/arm/armv7/multiarch/memcpy_impl.S
++++ b/ports/sysdeps/arm/armv7/multiarch/memcpy_impl.S
+@@ -128,25 +128,26 @@
+ .purgem dispatch_step
+ .endm
+ #else
+-# if ARM_BX_ALIGN_LOG2 < 4
++# if ARM_BX_ALIGN_LOG2 < 3
+ # error case not handled
+ # endif
+ .macro dispatch_helper steps, log2_bytes_per_step
+- .p2align ARM_BX_ALIGN_LOG2
+ /* TMP1 gets (max_bytes - bytes_to_copy), where max_bytes is
+ (STEPS << LOG2_BYTES_PER_STEP).
+- So this is (steps_to_skip << LOG2_BYTES_PER_STEP). */
+- rsb tmp1, tmp1, #(\steps << \log2_bytes_per_step)
+- /* Pad so that the add;bx pair immediately precedes an alignment
+- boundary. Hence, TMP1=0 will run all the steps. */
+- .rept (1 << (ARM_BX_ALIGN_LOG2 - 2)) - (2 + ARM_BX_NINSNS)
+- nop
+- .endr
++ So this is (steps_to_skip << LOG2_BYTES_PER_STEP).
++ Then it needs further adjustment to compensate for the
++ distance between the PC value taken below (0f + PC_OFS)
++ and the first step's instructions (1f). */
++ rsb tmp1, tmp1, #((\steps << \log2_bytes_per_step) \
++ + ((1f - PC_OFS - 0f) \
++ >> (ARM_BX_ALIGN_LOG2 - \log2_bytes_per_step)))
+ /* Shifting down LOG2_BYTES_PER_STEP gives us the number of
+ steps to skip, then shifting up ARM_BX_ALIGN_LOG2 gives us
+ the (byte) distance to add to the PC. */
+- add tmp1, pc, tmp1, lsl #(ARM_BX_ALIGN_LOG2 - \log2_bytes_per_step)
++0: add tmp1, pc, tmp1, lsl #(ARM_BX_ALIGN_LOG2 - \log2_bytes_per_step)
+ bx tmp1
++ .p2align ARM_BX_ALIGN_LOG2
++1:
+ .endm
+
+ .macro dispatch_7_dword
diff --git a/patches/glibc-2.18/0004-Accept-make-versions-4.0-and-greater.patch b/patches/glibc-2.18/0004-Accept-make-versions-4.0-and-greater.patch
new file mode 100644
index 0000000..3206a74
--- /dev/null
+++ b/patches/glibc-2.18/0004-Accept-make-versions-4.0-and-greater.patch
@@ -0,0 +1,35 @@
+From: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
+Date: Thu, 31 Oct 2013 12:37:50 +1000
+Subject: [PATCH] Accept make versions 4.0 and greater
+
+---
+ configure | 2 +-
+ configure.in | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure b/configure
+index 1ee4c42..804fd7e 100755
+--- a/configure
++++ b/configure
+@@ -4772,7 +4772,7 @@ $as_echo_n "checking version of $MAKE... " >&6; }
+ 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 --git a/configure.in b/configure.in
+index 769e8ef..2364142 100644
+--- a/configure.in
++++ b/configure.in
+@@ -989,7 +989,7 @@ AC_CHECK_PROG_VER(CC, ${ac_tool_prefix}gcc ${ac_tool_prefix}cc, -v,
+ critic_missing="$critic_missing gcc")
+ AC_CHECK_PROG_VER(MAKE, gnumake gmake make, --version,
+ [GNU Make[^0-9]*\([0-9][0-9.]*\)],
+- [3.79* | 3.[89]*], critic_missing="$critic_missing make")
++ [3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*], critic_missing="$critic_missing make")
+
+ AC_CHECK_PROG_VER(MSGFMT, gnumsgfmt gmsgfmt msgfmt, --version,
+ [GNU gettext.* \([0-9]*\.[0-9.]*\)],
diff --git a/patches/glibc-2.18/0005-Simplify-strcoll-implementation.patch b/patches/glibc-2.18/0005-Simplify-strcoll-implementation.patch
new file mode 100644
index 0000000..e715b38
--- /dev/null
+++ b/patches/glibc-2.18/0005-Simplify-strcoll-implementation.patch
@@ -0,0 +1,795 @@
+From: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date: Tue, 20 Aug 2013 08:40:05 +0530
+Subject: [PATCH] Simplify strcoll implementation
+
+Break up strcoll into simpler functions so that the logic is easier to
+follow and maintain.
+---
+ string/strcoll_l.c | 701 ++++++++++++++++++++++-------------------------------
+ 1 file changed, 295 insertions(+), 406 deletions(-)
+
+diff --git a/string/strcoll_l.c b/string/strcoll_l.c
+index ecda08f..50ed84d 100644
+--- a/string/strcoll_l.c
++++ b/string/strcoll_l.c
+@@ -41,11 +41,244 @@
+
+ #include "../locale/localeinfo.h"
+
++/* Track status while looking for sequences in a string. */
++typedef struct
++{
++ int len; /* Length of the current sequence. */
++ int val; /* Position of the sequence relative to the
++ previous non-ignored sequence. */
++ size_t idxnow; /* Current index in sequences. */
++ size_t idxmax; /* Maximum index in sequences. */
++ size_t idxcnt; /* Current count of indices. */
++ size_t backw; /* Current Backward sequence index. */
++ size_t backw_stop; /* Index where the backward sequences stop. */
++ const USTRING_TYPE *us; /* The string. */
++ int32_t *idxarr; /* Array to cache weight indices. */
++ unsigned char *rulearr; /* Array to cache rules. */
++} coll_seq;
++
++/* Get next sequence. The weight indices are cached, so we don't need to
++ traverse the string. */
++static void
++get_next_seq_cached (coll_seq *seq, int nrules, int pass,
++ const unsigned char *rulesets,
++ const USTRING_TYPE *weights)
++{
++ int val = seq->val = 0;
++ int len = seq->len;
++ size_t backw_stop = seq->backw_stop;
++ size_t backw = seq->backw;
++ size_t idxcnt = seq->idxcnt;
++ size_t idxmax = seq->idxmax;
++ size_t idxnow = seq->idxnow;
++ unsigned char *rulearr = seq->rulearr;
++ int32_t *idxarr = seq->idxarr;
++
++ while (len == 0)
++ {
++ ++val;
++ if (backw_stop != ~0ul)
++ {
++ /* There is something pushed. */
++ if (backw == backw_stop)
++ {
++ /* The last pushed character was handled. Continue
++ with forward characters. */
++ if (idxcnt < idxmax)
++ {
++ idxnow = idxcnt;
++ backw_stop = ~0ul;
++ }
++ else
++ {
++ /* Nothing any more. The backward sequence
++ ended with the last sequence in the string. */
++ idxnow = ~0ul;
++ break;
++ }
++ }
++ else
++ idxnow = --backw;
++ }
++ else
++ {
++ backw_stop = idxcnt;
++
++ while (idxcnt < idxmax)
++ {
++ if ((rulesets[rulearr[idxcnt] * nrules + pass]
++ & sort_backward) == 0)
++ /* No more backward characters to push. */
++ break;
++ ++idxcnt;
++ }
++
++ if (backw_stop == idxcnt)
++ {
++ /* No sequence at all or just one. */
++ if (idxcnt == idxmax)
++ /* Note that LEN is still zero. */
++ break;
++
++ backw_stop = ~0ul;
++ idxnow = idxcnt++;
++ }
++ else
++ /* We pushed backward sequences. */
++ idxnow = backw = idxcnt - 1;
++ }
++ len = weights[idxarr[idxnow]++];
++ }
++
++ /* Update the structure. */
++ seq->val = val;
++ seq->len = len;
++ seq->backw_stop = backw_stop;
++ seq->backw = backw;
++ seq->idxcnt = idxcnt;
++ seq->idxnow = idxnow;
++}
++
++/* Get next sequence. Traverse the string as required. */
++static void
++get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
++ const USTRING_TYPE *weights, const int32_t *table,
++ const USTRING_TYPE *extra, const int32_t *indirect)
++{
++#include WEIGHT_H
++ int val = seq->val = 0;
++ int len = seq->len;
++ size_t backw_stop = seq->backw_stop;
++ size_t backw = seq->backw;
++ size_t idxcnt = seq->idxcnt;
++ size_t idxmax = seq->idxmax;
++ size_t idxnow = seq->idxnow;
++ unsigned char *rulearr = seq->rulearr;
++ int32_t *idxarr = seq->idxarr;
++ const USTRING_TYPE *us = seq->us;
++
++ while (len == 0)
++ {
++ ++val;
++ if (backw_stop != ~0ul)
++ {
++ /* The is something pushed. */
++ if (backw == backw_stop)
++ {
++ /* The last pushed character was handled. Continue
++ with forward characters. */
++ if (idxcnt < idxmax)
++ {
++ idxnow = idxcnt;
++ backw_stop = ~0ul;
++ }
++ else
++ /* Nothing any more. The backward sequence ended with
++ the last sequence in the string. Note that LEN
++ is still zero. */
++ break;
++ }
++ else
++ idxnow = --backw;
++ }
++ else
++ {
++ backw_stop = idxmax;
++
++ while (*us != L('\0'))
++ {
++ int32_t tmp = findidx (&us, -1);
++ rulearr[idxmax] = tmp >> 24;
++ idxarr[idxmax] = tmp & 0xffffff;
++ idxcnt = idxmax++;
++
++ if ((rulesets[rulearr[idxcnt] * nrules]
++ & sort_backward) == 0)
++ /* No more backward characters to push. */
++ break;
++ ++idxcnt;
++ }
++
++ if (backw_stop >= idxcnt)
++ {
++ /* No sequence at all or just one. */
++ if (idxcnt == idxmax || backw_stop > idxcnt)
++ /* Note that LEN is still zero. */
++ break;
++
++ backw_stop = ~0ul;
++ idxnow = idxcnt;
++ }
++ else
++ /* We pushed backward sequences. */
++ idxnow = backw = idxcnt - 1;
++ }
++ len = weights[idxarr[idxnow]++];
++ }
++
++ /* Update the structure. */
++ seq->val = val;
++ seq->len = len;
++ seq->backw_stop = backw_stop;
++ seq->backw = backw;
++ seq->idxcnt = idxcnt;
++ seq->idxmax = idxmax;
++ seq->idxnow = idxnow;
++ seq->us = us;
++}
++
++/* Compare two sequences. */
++static int
++do_compare (coll_seq *seq1, coll_seq *seq2, int position,
++ const USTRING_TYPE *weights)
++{
++ int seq1len = seq1->len;
++ int seq2len = seq2->len;
++ int val1 = seq1->val;
++ int val2 = seq2->val;
++ int32_t *idx1arr = seq1->idxarr;
++ int32_t *idx2arr = seq2->idxarr;
++ int idx1now = seq1->idxnow;
++ int idx2now = seq2->idxnow;
++ int result = 0;
++
++ /* Test for position if necessary. */
++ if (position && val1 != val2)
++ {
++ result = val1 - val2;
++ goto out;
++ }
++
++ /* Compare the two sequences. */
++ do
++ {
++ if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
++ {
++ /* The sequences differ. */
++ result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]];
++ goto out;
++ }
++
++ /* Increment the offsets. */
++ ++idx1arr[idx1now];
++ ++idx2arr[idx2now];
++
++ --seq1len;
++ --seq2len;
++ }
++ while (seq1len > 0 && seq2len > 0);
++
++ if (position && seq1len != seq2len)
++ result = seq1len - seq2len;
++
++out:
++ seq1->len = seq1len;
++ seq2->len = seq2len;
++ return result;
++}
++
+ int
+-STRCOLL (s1, s2, l)
+- const STRING_TYPE *s1;
+- const STRING_TYPE *s2;
+- __locale_t l;
++STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ {
+ struct __locale_data *current = l->__locales[LC_COLLATE];
+ uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
+@@ -56,34 +289,6 @@ STRCOLL (s1, s2, l)
+ const USTRING_TYPE *weights;
+ const USTRING_TYPE *extra;
+ const int32_t *indirect;
+- uint_fast32_t pass;
+- int result = 0;
+- const USTRING_TYPE *us1;
+- const USTRING_TYPE *us2;
+- size_t s1len;
+- size_t s2len;
+- int32_t *idx1arr;
+- int32_t *idx2arr;
+- unsigned char *rule1arr;
+- unsigned char *rule2arr;
+- size_t idx1max;
+- size_t idx2max;
+- size_t idx1cnt;
+- size_t idx2cnt;
+- size_t idx1now;
+- size_t idx2now;
+- size_t backw1_stop;
+- size_t backw2_stop;
+- size_t backw1;
+- size_t backw2;
+- int val1;
+- int val2;
+- int position;
+- int seq1len;
+- int seq2len;
+- int use_malloc;
+-
+-#include WEIGHT_H
+
+ if (nrules == 0)
+ return STRCMP (s1, s2);
+@@ -98,7 +303,6 @@ STRCOLL (s1, s2, l)
+ current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
+ indirect = (const int32_t *)
+ current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
+- use_malloc = 0;
+
+ assert (((uintptr_t) table) % __alignof__ (table[0]) == 0);
+ assert (((uintptr_t) weights) % __alignof__ (weights[0]) == 0);
+@@ -106,18 +310,13 @@ STRCOLL (s1, s2, l)
+ assert (((uintptr_t) indirect) % __alignof__ (indirect[0]) == 0);
+
+ /* We need this a few times. */
+- s1len = STRLEN (s1);
+- s2len = STRLEN (s2);
++ size_t s1len = STRLEN (s1);
++ size_t s2len = STRLEN (s2);
+
+ /* Catch empty strings. */
+- if (__builtin_expect (s1len == 0, 0) || __builtin_expect (s2len == 0, 0))
++ if (__glibc_unlikely (s1len == 0) || __glibc_unlikely (s2len == 0))
+ return (s1len != 0) - (s2len != 0);
+
+- /* We need the elements of the strings as unsigned values since they
+- are used as indeces. */
+- us1 = (const USTRING_TYPE *) s1;
+- us2 = (const USTRING_TYPE *) s2;
+-
+ /* Perform the first pass over the string and while doing this find
+ and store the weights for each character. Since we want this to
+ be as fast as possible we are using `alloca' to store the temporary
+@@ -127,411 +326,101 @@ STRCOLL (s1, s2, l)
+
+ Please note that the localedef programs makes sure that `position'
+ is not used at the first level. */
++
++ coll_seq seq1, seq2;
++ bool use_malloc = false;
++ int result = 0;
++
++ memset (&seq1, 0, sizeof (seq1));
++ seq2 = seq1;
++
++ /* We need the elements of the strings as unsigned values since they
++ are used as indices. */
++ seq1.us = (const USTRING_TYPE *) s1;
++ seq2.us = (const USTRING_TYPE *) s2;
++
+ if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
+ {
+- idx1arr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1));
+- idx2arr = &idx1arr[s1len];
+- rule1arr = (unsigned char *) &idx2arr[s2len];
+- rule2arr = &rule1arr[s1len];
++ seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1));
++ seq2.idxarr = &seq1.idxarr[s1len];
++ seq1.rulearr = (unsigned char *) &seq2.idxarr[s2len];
++ seq2.rulearr = &seq1.rulearr[s1len];
+
+- if (idx1arr == NULL)
++ if (seq1.idxarr == NULL)
+ /* No memory. Well, go with the stack then.
+
+ XXX Once this implementation is stable we will handle this
+- differently. Instead of precomputing the indeces we will
++ differently. Instead of precomputing the indices we will
+ do this in time. This means, though, that this happens for
+ every pass again. */
+ goto try_stack;
+- use_malloc = 1;
++ use_malloc = true;
+ }
+ else
+ {
+ try_stack:
+- idx1arr = (int32_t *) alloca (s1len * sizeof (int32_t));
+- idx2arr = (int32_t *) alloca (s2len * sizeof (int32_t));
+- rule1arr = (unsigned char *) alloca (s1len);
+- rule2arr = (unsigned char *) alloca (s2len);
++ seq1.idxarr = (int32_t *) alloca (s1len * sizeof (int32_t));
++ seq2.idxarr = (int32_t *) alloca (s2len * sizeof (int32_t));
++ seq1.rulearr = (unsigned char *) alloca (s1len);
++ seq2.rulearr = (unsigned char *) alloca (s2len);
+ }
+
+- idx1cnt = 0;
+- idx2cnt = 0;
+- idx1max = 0;
+- idx2max = 0;
+- idx1now = 0;
+- idx2now = 0;
+- backw1_stop = ~0ul;
+- backw2_stop = ~0ul;
+- backw1 = ~0ul;
+- backw2 = ~0ul;
+- seq1len = 0;
+- seq2len = 0;
+- position = rulesets[0] & sort_position;
+- while (1)
+- {
+- val1 = 0;
+- val2 = 0;
+-
+- /* Get the next non-IGNOREd element for string `s1'. */
+- if (seq1len == 0)
+- do
+- {
+- ++val1;
+-
+- if (backw1_stop != ~0ul)
+- {
+- /* The is something pushed. */
+- if (backw1 == backw1_stop)
+- {
+- /* The last pushed character was handled. Continue
+- with forward characters. */
+- if (idx1cnt < idx1max)
+- {
+- idx1now = idx1cnt;
+- backw1_stop = ~0ul;
+- }
+- else
+- /* Nothing anymore. The backward sequence ended with
+- the last sequence in the string. Note that seq1len
+- is still zero. */
+- break;
+- }
+- else
+- idx1now = --backw1;
+- }
+- else
+- {
+- backw1_stop = idx1max;
+-
+- while (*us1 != L('\0'))
+- {
+- int32_t tmp = findidx (&us1, -1);
+- rule1arr[idx1max] = tmp >> 24;
+- idx1arr[idx1max] = tmp & 0xffffff;
+- idx1cnt = idx1max++;
+-
+- if ((rulesets[rule1arr[idx1cnt] * nrules]
+- & sort_backward) == 0)
+- /* No more backward characters to push. */
+- break;
+- ++idx1cnt;
+- }
+-
+- if (backw1_stop >= idx1cnt)
+- {
+- /* No sequence at all or just one. */
+- if (idx1cnt == idx1max || backw1_stop > idx1cnt)
+- /* Note that seq1len is still zero. */
+- break;
+-
+- backw1_stop = ~0ul;
+- idx1now = idx1cnt;
+- }
+- else
+- /* We pushed backward sequences. */
+- idx1now = backw1 = idx1cnt - 1;
+- }
+- }
+- while ((seq1len = weights[idx1arr[idx1now]++]) == 0);
+-
+- /* And the same for string `s2'. */
+- if (seq2len == 0)
+- do
+- {
+- ++val2;
+-
+- if (backw2_stop != ~0ul)
+- {
+- /* The is something pushed. */
+- if (backw2 == backw2_stop)
+- {
+- /* The last pushed character was handled. Continue
+- with forward characters. */
+- if (idx2cnt < idx2max)
+- {
+- idx2now = idx2cnt;
+- backw2_stop = ~0ul;
+- }
+- else
+- /* Nothing anymore. The backward sequence ended with
+- the last sequence in the string. Note that seq2len
+- is still zero. */
+- break;
+- }
+- else
+- idx2now = --backw2;
+- }
+- else
+- {
+- backw2_stop = idx2max;
+-
+- while (*us2 != L('\0'))
+- {
+- int32_t tmp = findidx (&us2, -1);
+- rule2arr[idx2max] = tmp >> 24;
+- idx2arr[idx2max] = tmp & 0xffffff;
+- idx2cnt = idx2max++;
+-
+- if ((rulesets[rule2arr[idx2cnt] * nrules]
+- & sort_backward) == 0)
+- /* No more backward characters to push. */
+- break;
+- ++idx2cnt;
+- }
+-
+- if (backw2_stop >= idx2cnt)
+- {
+- /* No sequence at all or just one. */
+- if (idx2cnt == idx2max || backw2_stop > idx2cnt)
+- /* Note that seq1len is still zero. */
+- break;
+-
+- backw2_stop = ~0ul;
+- idx2now = idx2cnt;
+- }
+- else
+- /* We pushed backward sequences. */
+- idx2now = backw2 = idx2cnt - 1;
+- }
+- }
+- while ((seq2len = weights[idx2arr[idx2now]++]) == 0);
+-
+- /* See whether any or both strings are empty. */
+- if (seq1len == 0 || seq2len == 0)
+- {
+- if (seq1len == seq2len)
+- /* Both ended. So far so good, both strings are equal at the
+- first level. */
+- break;
+-
+- /* This means one string is shorter than the other. Find out
+- which one and return an appropriate value. */
+- result = seq1len == 0 ? -1 : 1;
+- goto free_and_return;
+- }
+-
+- /* Test for position if necessary. */
+- if (position && val1 != val2)
+- {
+- result = val1 - val2;
+- goto free_and_return;
+- }
+-
+- /* Compare the two sequences. */
+- do
+- {
+- if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
+- {
+- /* The sequences differ. */
+- result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]];
+- goto free_and_return;
+- }
+-
+- /* Increment the offsets. */
+- ++idx1arr[idx1now];
+- ++idx2arr[idx2now];
++ seq1.rulearr[0] = 0;
+
+- --seq1len;
+- --seq2len;
+- }
+- while (seq1len > 0 && seq2len > 0);
+-
+- if (position && seq1len != seq2len)
+- {
+- result = seq1len - seq2len;
+- goto free_and_return;
+- }
+- }
+-
+- /* Now the remaining passes over the weights. We now use the
+- indeces we found before. */
+- for (pass = 1; pass < nrules; ++pass)
++ /* Cache values in the first pass and if needed, use them in subsequent
++ passes. */
++ for (int pass = 0; pass < nrules; ++pass)
+ {
++ seq1.idxcnt = 0;
++ seq1.backw_stop = ~0ul;
++ seq1.backw = ~0ul;
++ seq2.idxcnt = 0;
++ seq2.backw_stop = ~0ul;
++ seq2.backw = ~0ul;
++
+ /* We assume that if a rule has defined `position' in one section
+ this is true for all of them. */
+- idx1cnt = 0;
+- idx2cnt = 0;
+- backw1_stop = ~0ul;
+- backw2_stop = ~0ul;
+- backw1 = ~0ul;
+- backw2 = ~0ul;
+- position = rulesets[rule1arr[0] * nrules + pass] & sort_position;
++ int position = rulesets[seq1.rulearr[0] * nrules + pass] & sort_position;
+
+ while (1)
+ {
+- val1 = 0;
+- val2 = 0;
+-
+- /* Get the next non-IGNOREd element for string `s1'. */
+- if (seq1len == 0)
+- do
+- {
+- ++val1;
+-
+- if (backw1_stop != ~0ul)
+- {
+- /* The is something pushed. */
+- if (backw1 == backw1_stop)
+- {
+- /* The last pushed character was handled. Continue
+- with forward characters. */
+- if (idx1cnt < idx1max)
+- {
+- idx1now = idx1cnt;
+- backw1_stop = ~0ul;
+- }
+- else
+- {
+- /* Nothing anymore. The backward sequence
+- ended with the last sequence in the string. */
+- idx1now = ~0ul;
+- break;
+- }
+- }
+- else
+- idx1now = --backw1;
+- }
+- else
+- {
+- backw1_stop = idx1cnt;
+-
+- while (idx1cnt < idx1max)
+- {
+- if ((rulesets[rule1arr[idx1cnt] * nrules + pass]
+- & sort_backward) == 0)
+- /* No more backward characters to push. */
+- break;
+- ++idx1cnt;
+- }
+-
+- if (backw1_stop == idx1cnt)
+- {
+- /* No sequence at all or just one. */
+- if (idx1cnt == idx1max)
+- /* Note that seq1len is still zero. */
+- break;
+-
+- backw1_stop = ~0ul;
+- idx1now = idx1cnt++;
+- }
+- else
+- /* We pushed backward sequences. */
+- idx1now = backw1 = idx1cnt - 1;
+- }
+- }
+- while ((seq1len = weights[idx1arr[idx1now]++]) == 0);
+-
+- /* And the same for string `s2'. */
+- if (seq2len == 0)
+- do
+- {
+- ++val2;
+-
+- if (backw2_stop != ~0ul)
+- {
+- /* The is something pushed. */
+- if (backw2 == backw2_stop)
+- {
+- /* The last pushed character was handled. Continue
+- with forward characters. */
+- if (idx2cnt < idx2max)
+- {
+- idx2now = idx2cnt;
+- backw2_stop = ~0ul;
+- }
+- else
+- {
+- /* Nothing anymore. The backward sequence
+- ended with the last sequence in the string. */
+- idx2now = ~0ul;
+- break;
+- }
+- }
+- else
+- idx2now = --backw2;
+- }
+- else
+- {
+- backw2_stop = idx2cnt;
+-
+- while (idx2cnt < idx2max)
+- {
+- if ((rulesets[rule2arr[idx2cnt] * nrules + pass]
+- & sort_backward) == 0)
+- /* No more backward characters to push. */
+- break;
+- ++idx2cnt;
+- }
+-
+- if (backw2_stop == idx2cnt)
+- {
+- /* No sequence at all or just one. */
+- if (idx2cnt == idx2max)
+- /* Note that seq2len is still zero. */
+- break;
+-
+- backw2_stop = ~0ul;
+- idx2now = idx2cnt++;
+- }
+- else
+- /* We pushed backward sequences. */
+- idx2now = backw2 = idx2cnt - 1;
+- }
+- }
+- while ((seq2len = weights[idx2arr[idx2now]++]) == 0);
++ if (pass == 0)
++ {
++ get_next_seq (&seq1, nrules, rulesets, weights, table, extra,
++ indirect);
++ get_next_seq (&seq2, nrules, rulesets, weights, table, extra,
++ indirect);
++ }
++ else
++ {
++ get_next_seq_cached (&seq1, nrules, pass, rulesets, weights);
++ get_next_seq_cached (&seq2, nrules, pass, rulesets, weights);
++ }
+
+ /* See whether any or both strings are empty. */
+- if (seq1len == 0 || seq2len == 0)
++ if (seq1.len == 0 || seq2.len == 0)
+ {
+- if (seq1len == seq2len)
++ if (seq1.len == seq2.len)
+ /* Both ended. So far so good, both strings are equal
+ at this level. */
+ break;
+
+ /* This means one string is shorter than the other. Find out
+ which one and return an appropriate value. */
+- result = seq1len == 0 ? -1 : 1;
++ result = seq1.len == 0 ? -1 : 1;
+ goto free_and_return;
+ }
+
+- /* Test for position if necessary. */
+- if (position && val1 != val2)
+- {
+- result = val1 - val2;
+- goto free_and_return;
+- }
+-
+- /* Compare the two sequences. */
+- do
+- {
+- if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]])
+- {
+- /* The sequences differ. */
+- result = (weights[idx1arr[idx1now]]
+- - weights[idx2arr[idx2now]]);
+- goto free_and_return;
+- }
+-
+- /* Increment the offsets. */
+- ++idx1arr[idx1now];
+- ++idx2arr[idx2now];
+-
+- --seq1len;
+- --seq2len;
+- }
+- while (seq1len > 0 && seq2len > 0);
+-
+- if (position && seq1len != seq2len)
+- {
+- result = seq1len - seq2len;
+- goto free_and_return;
+- }
++ result = do_compare (&seq1, &seq2, position, weights);
++ if (result != 0)
++ goto free_and_return;
+ }
+ }
+
+ /* Free the memory if needed. */
+ free_and_return:
+ if (use_malloc)
+- free (idx1arr);
++ free (seq1.idxarr);
+
+ return result;
+ }
diff --git a/patches/glibc-2.18/0006-Fall-back-to-non-cached-sequence-traversal-and-compa.patch b/patches/glibc-2.18/0006-Fall-back-to-non-cached-sequence-traversal-and-compa.patch
new file mode 100644
index 0000000..b7f1c22
--- /dev/null
+++ b/patches/glibc-2.18/0006-Fall-back-to-non-cached-sequence-traversal-and-compa.patch
@@ -0,0 +1,384 @@
+From: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date: Mon, 23 Sep 2013 11:20:02 +0530
+Subject: [PATCH] Fall back to non-cached sequence traversal and comparison on
+ malloc fail
+
+strcoll currently falls back to alloca if malloc fails, resulting in a
+possible stack overflow. This patch implements sequence traversal and
+comparison without caching indices and rules.
+
+Fixes CVE-2012-4424.
+---
+ string/strcoll_l.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 234 insertions(+), 31 deletions(-)
+
+diff --git a/string/strcoll_l.c b/string/strcoll_l.c
+index 50ed84d..eb042ff 100644
+--- a/string/strcoll_l.c
++++ b/string/strcoll_l.c
+@@ -45,7 +45,7 @@
+ typedef struct
+ {
+ int len; /* Length of the current sequence. */
+- int val; /* Position of the sequence relative to the
++ size_t val; /* Position of the sequence relative to the
+ previous non-ignored sequence. */
+ size_t idxnow; /* Current index in sequences. */
+ size_t idxmax; /* Maximum index in sequences. */
+@@ -55,6 +55,12 @@ typedef struct
+ const USTRING_TYPE *us; /* The string. */
+ int32_t *idxarr; /* Array to cache weight indices. */
+ unsigned char *rulearr; /* Array to cache rules. */
++ unsigned char rule; /* Saved rule for the first sequence. */
++ int32_t idx; /* Index to weight of the current sequence. */
++ int32_t save_idx; /* Save looked up index of a forward
++ sequence after the last backward
++ sequence. */
++ const USTRING_TYPE *back_us; /* Beginning of the backward sequence. */
+ } coll_seq;
+
+ /* Get next sequence. The weight indices are cached, so we don't need to
+@@ -64,7 +70,7 @@ get_next_seq_cached (coll_seq *seq, int nrules, int pass,
+ const unsigned char *rulesets,
+ const USTRING_TYPE *weights)
+ {
+- int val = seq->val = 0;
++ size_t val = seq->val = 0;
+ int len = seq->len;
+ size_t backw_stop = seq->backw_stop;
+ size_t backw = seq->backw;
+@@ -146,7 +152,7 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
+ const USTRING_TYPE *extra, const int32_t *indirect)
+ {
+ #include WEIGHT_H
+- int val = seq->val = 0;
++ size_t val = seq->val = 0;
+ int len = seq->len;
+ size_t backw_stop = seq->backw_stop;
+ size_t backw = seq->backw;
+@@ -162,7 +168,7 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
+ ++val;
+ if (backw_stop != ~0ul)
+ {
+- /* The is something pushed. */
++ /* There is something pushed. */
+ if (backw == backw_stop)
+ {
+ /* The last pushed character was handled. Continue
+@@ -227,15 +233,199 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
+ seq->us = us;
+ }
+
+-/* Compare two sequences. */
++/* Get next sequence. Traverse the string as required. This function does not
++ set or use any index or rule cache. */
++static void
++get_next_seq_nocache (coll_seq *seq, int nrules, const unsigned char *rulesets,
++ const USTRING_TYPE *weights, const int32_t *table,
++ const USTRING_TYPE *extra, const int32_t *indirect,
++ int pass)
++{
++#include WEIGHT_H
++ size_t val = seq->val = 0;
++ int len = seq->len;
++ size_t backw_stop = seq->backw_stop;
++ size_t backw = seq->backw;
++ size_t idxcnt = seq->idxcnt;
++ size_t idxmax = seq->idxmax;
++ int32_t idx = seq->idx;
++ const USTRING_TYPE *us = seq->us;
++
++ while (len == 0)
++ {
++ ++val;
++ if (backw_stop != ~0ul)
++ {
++ /* There is something pushed. */
++ if (backw == backw_stop)
++ {
++ /* The last pushed character was handled. Continue
++ with forward characters. */
++ if (idxcnt < idxmax)
++ {
++ idx = seq->save_idx;
++ backw_stop = ~0ul;
++ }
++ else
++ {
++ /* Nothing anymore. The backward sequence ended with
++ the last sequence in the string. Note that len is
++ still zero. */
++ idx = 0;
++ break;
++ }
++ }
++ else
++ {
++ /* XXX Traverse BACKW sequences from the beginning of
++ BACKW_STOP to get the next sequence. Is ther a quicker way
++ to do this? */
++ size_t i = backw_stop;
++ us = seq->back_us;
++ while (i < backw)
++ {
++ int32_t tmp = findidx (&us, -1);
++ idx = tmp & 0xffffff;
++ i++;
++ }
++ --backw;
++ us = seq->us;
++ }
++ }
++ else
++ {
++ backw_stop = idxmax;
++ int32_t prev_idx = idx;
++
++ while (*us != L('\0'))
++ {
++ int32_t tmp = findidx (&us, -1);
++ unsigned char rule = tmp >> 24;
++ prev_idx = idx;
++ idx = tmp & 0xffffff;
++ idxcnt = idxmax++;
++
++ /* Save the rule for the first sequence. */
++ if (__glibc_unlikely (idxcnt == 0))
++ seq->rule = rule;
++
++ if ((rulesets[rule * nrules + pass]
++ & sort_backward) == 0)
++ /* No more backward characters to push. */
++ break;
++ ++idxcnt;
++ }
++
++ if (backw_stop >= idxcnt)
++ {
++ /* No sequence at all or just one. */
++ if (idxcnt == idxmax || backw_stop > idxcnt)
++ /* Note that len is still zero. */
++ break;
++
++ backw_stop = ~0ul;
++ }
++ else
++ {
++ /* We pushed backward sequences. If the stream ended with the
++ backward sequence, then we process the last sequence we
++ found. Otherwise we process the sequence before the last
++ one since the last one was a forward sequence. */
++ seq->back_us = seq->us;
++ seq->us = us;
++ backw = idxcnt;
++ if (idxmax > idxcnt)
++ {
++ backw--;
++ seq->save_idx = idx;
++ idx = prev_idx;
++ }
++ if (backw > backw_stop)
++ backw--;
++ }
++ }
++
++ len = weights[idx++];
++ /* Skip over indices of previous levels. */
++ for (int i = 0; i < pass; i++)
++ {
++ idx += len;
++ len = weights[idx];
++ idx++;
++ }
++ }
++
++ /* Update the structure. */
++ seq->val = val;
++ seq->len = len;
++ seq->backw_stop = backw_stop;
++ seq->backw = backw;
++ seq->idxcnt = idxcnt;
++ seq->idxmax = idxmax;
++ seq->us = us;
++ seq->idx = idx;
++}
++
++/* Compare two sequences. This version does not use the index and rules
++ cache. */
++static int
++do_compare_nocache (coll_seq *seq1, coll_seq *seq2, int position,
++ const USTRING_TYPE *weights)
++{
++ int seq1len = seq1->len;
++ int seq2len = seq2->len;
++ size_t val1 = seq1->val;
++ size_t val2 = seq2->val;
++ int idx1 = seq1->idx;
++ int idx2 = seq2->idx;
++ int result = 0;
++
++ /* Test for position if necessary. */
++ if (position && val1 != val2)
++ {
++ result = val1 > val2 ? 1 : -1;
++ goto out;
++ }
++
++ /* Compare the two sequences. */
++ do
++ {
++ if (weights[idx1] != weights[idx2])
++ {
++ /* The sequences differ. */
++ result = weights[idx1] - weights[idx2];
++ goto out;
++ }
++
++ /* Increment the offsets. */
++ ++idx1;
++ ++idx2;
++
++ --seq1len;
++ --seq2len;
++ }
++ while (seq1len > 0 && seq2len > 0);
++
++ if (position && seq1len != seq2len)
++ result = seq1len - seq2len;
++
++out:
++ seq1->len = seq1len;
++ seq2->len = seq2len;
++ seq1->idx = idx1;
++ seq2->idx = idx2;
++ return result;
++}
++
++/* Compare two sequences using the index cache. */
+ static int
+ do_compare (coll_seq *seq1, coll_seq *seq2, int position,
+ const USTRING_TYPE *weights)
+ {
+ int seq1len = seq1->len;
+ int seq2len = seq2->len;
+- int val1 = seq1->val;
+- int val2 = seq2->val;
++ size_t val1 = seq1->val;
++ size_t val2 = seq2->val;
+ int32_t *idx1arr = seq1->idxarr;
+ int32_t *idx2arr = seq2->idxarr;
+ int idx1now = seq1->idxnow;
+@@ -245,7 +435,7 @@ do_compare (coll_seq *seq1, coll_seq *seq2, int position,
+ /* Test for position if necessary. */
+ if (position && val1 != val2)
+ {
+- result = val1 - val2;
++ result = val1 > val2 ? 1 : -1;
+ goto out;
+ }
+
+@@ -334,57 +524,62 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ memset (&seq1, 0, sizeof (seq1));
+ seq2 = seq1;
+
+- /* We need the elements of the strings as unsigned values since they
+- are used as indices. */
+- seq1.us = (const USTRING_TYPE *) s1;
+- seq2.us = (const USTRING_TYPE *) s2;
+-
+ if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
+ {
+ seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1));
+- seq2.idxarr = &seq1.idxarr[s1len];
+- seq1.rulearr = (unsigned char *) &seq2.idxarr[s2len];
+- seq2.rulearr = &seq1.rulearr[s1len];
+-
+- if (seq1.idxarr == NULL)
+- /* No memory. Well, go with the stack then.
+-
+- XXX Once this implementation is stable we will handle this
+- differently. Instead of precomputing the indices we will
+- do this in time. This means, though, that this happens for
+- every pass again. */
+- goto try_stack;
+- use_malloc = true;
++
++ /* If we failed to allocate memory, we leave everything as NULL so that
++ we use the nocache version of traversal and comparison functions. */
++ if (seq1.idxarr != NULL)
++ {
++ seq2.idxarr = &seq1.idxarr[s1len];
++ seq1.rulearr = (unsigned char *) &seq2.idxarr[s2len];
++ seq2.rulearr = &seq1.rulearr[s1len];
++ use_malloc = true;
++ }
+ }
+ else
+ {
+- try_stack:
+ seq1.idxarr = (int32_t *) alloca (s1len * sizeof (int32_t));
+ seq2.idxarr = (int32_t *) alloca (s2len * sizeof (int32_t));
+ seq1.rulearr = (unsigned char *) alloca (s1len);
+ seq2.rulearr = (unsigned char *) alloca (s2len);
+ }
+
+- seq1.rulearr[0] = 0;
++ int rule = 0;
+
+ /* Cache values in the first pass and if needed, use them in subsequent
+ passes. */
+ for (int pass = 0; pass < nrules; ++pass)
+ {
+ seq1.idxcnt = 0;
++ seq1.idx = 0;
++ seq2.idx = 0;
+ seq1.backw_stop = ~0ul;
+ seq1.backw = ~0ul;
+ seq2.idxcnt = 0;
+ seq2.backw_stop = ~0ul;
+ seq2.backw = ~0ul;
+
++ /* We need the elements of the strings as unsigned values since they
++ are used as indices. */
++ seq1.us = (const USTRING_TYPE *) s1;
++ seq2.us = (const USTRING_TYPE *) s2;
++
+ /* We assume that if a rule has defined `position' in one section
+ this is true for all of them. */
+- int position = rulesets[seq1.rulearr[0] * nrules + pass] & sort_position;
++ int position = rulesets[rule * nrules + pass] & sort_position;
+
+ while (1)
+ {
+- if (pass == 0)
++ if (__glibc_unlikely (seq1.idxarr == NULL))
++ {
++ get_next_seq_nocache (&seq1, nrules, rulesets, weights, table,
++ extra, indirect, pass);
++ get_next_seq_nocache (&seq2, nrules, rulesets, weights, table,
++ extra, indirect, pass);
++ }
++ else if (pass == 0)
+ {
+ get_next_seq (&seq1, nrules, rulesets, weights, table, extra,
+ indirect);
+@@ -411,10 +606,18 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ goto free_and_return;
+ }
+
+- result = do_compare (&seq1, &seq2, position, weights);
++ if (__glibc_unlikely (seq1.idxarr == NULL))
++ result = do_compare_nocache (&seq1, &seq2, position, weights);
++ else
++ result = do_compare (&seq1, &seq2, position, weights);
+ if (result != 0)
+ goto free_and_return;
+ }
++
++ if (__glibc_likely (seq1.rulearr != NULL))
++ rule = seq1.rulearr[0];
++ else
++ rule = seq1.rule;
+ }
+
+ /* Free the memory if needed. */
diff --git a/patches/glibc-2.18/0007-Check-for-integer-overflow-in-cache-size-computation.patch b/patches/glibc-2.18/0007-Check-for-integer-overflow-in-cache-size-computation.patch
new file mode 100644
index 0000000..549e3e2
--- /dev/null
+++ b/patches/glibc-2.18/0007-Check-for-integer-overflow-in-cache-size-computation.patch
@@ -0,0 +1,121 @@
+From: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date: Mon, 23 Sep 2013 11:24:30 +0530
+Subject: [PATCH] Check for integer overflow in cache size computation in
+ strcoll
+
+strcoll is implemented using a cache for indices and weights of
+collation sequences in the strings so that subsequent passes do not
+have to search through collation data again. For very large string
+inputs, the cache size computation could overflow. In such a case,
+use the fallback function that does not cache indices and weights of
+collation sequences.
+
+Fixes CVE-2012-4412.
+---
+ string/Makefile | 2 ++
+ string/strcoll_l.c | 10 ++++++-
+ string/tst-strcoll-overflow.c | 61 +++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 72 insertions(+), 1 deletion(-)
+ create mode 100644 string/tst-strcoll-overflow.c
+
+diff --git a/string/Makefile b/string/Makefile
+index 0237edd..59c658f 100644
+--- a/string/Makefile
++++ b/string/Makefile
+@@ -57,6 +57,8 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \
+ tests-ifunc := $(strop-tests:%=test-%-ifunc)
+ tests += $(tests-ifunc)
+
++xtests = tst-strcoll-overflow
++
+ include ../Rules
+
+ tester-ENV = LANGUAGE=C
+diff --git a/string/strcoll_l.c b/string/strcoll_l.c
+index eb042ff..4ee101a 100644
+--- a/string/strcoll_l.c
++++ b/string/strcoll_l.c
+@@ -524,7 +524,15 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ memset (&seq1, 0, sizeof (seq1));
+ seq2 = seq1;
+
+- if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
++ size_t size_max = SIZE_MAX / (sizeof (int32_t) + 1);
++
++ if (MIN (s1len, s2len) > size_max
++ || MAX (s1len, s2len) > size_max - MIN (s1len, s2len))
++ {
++ /* If the strings are long enough to cause overflow in the size request,
++ then skip the allocation and proceed with the non-cached routines. */
++ }
++ else if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
+ {
+ seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1));
+
+diff --git a/string/tst-strcoll-overflow.c b/string/tst-strcoll-overflow.c
+new file mode 100644
+index 0000000..bb665ac
+--- /dev/null
++++ b/string/tst-strcoll-overflow.c
+@@ -0,0 +1,61 @@
++/* Copyright (C) 2013 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <http://www.gnu.org/licenses/>. */
++
++#include <locale.h>
++#include <stdio.h>
++#include <stdint.h>
++#include <stdlib.h>
++#include <string.h>
++
++/* Verify that strcoll does not crash for large strings for which it cannot
++ cache weight lookup results. The size is large enough to cause integer
++ overflows on 32-bit as well as buffer overflows on 64-bit. The test should
++ work reasonably reliably when overcommit is disabled, but it obviously
++ depends on how much memory the system has. There's a limitation to this
++ test in that it does not run to completion. Actually collating such a
++ large string can take days and we can't have xcheck running that long. For
++ that reason, we run the test for about 5 minutes and then assume that
++ everything is fine if there are no crashes. */
++#define SIZE 0x40000000ul
++
++int
++do_test (void)
++{
++ if (setlocale (LC_COLLATE, "en_GB.UTF-8") == NULL)
++ {
++ puts ("setlocale failed, cannot test for overflow");
++ return 0;
++ }
++
++ char *p = malloc (SIZE);
++
++ if (p == NULL)
++ {
++ puts ("could not allocate memory");
++ return 1;
++ }
++
++ memset (p, 'x', SIZE - 1);
++ p[SIZE - 1] = 0;
++ printf ("%d\n", strcoll (p, p));
++ return 0;
++}
++
++#define TIMEOUT 300
++#define EXPECTED_SIGNAL SIGALRM
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
diff --git a/patches/glibc-2.18/0008-BZ-15754-CVE-2013-4788.patch b/patches/glibc-2.18/0008-BZ-15754-CVE-2013-4788.patch
new file mode 100644
index 0000000..d027f7e
--- /dev/null
+++ b/patches/glibc-2.18/0008-BZ-15754-CVE-2013-4788.patch
@@ -0,0 +1,199 @@
+From: Carlos O'Donell <carlos@redhat.com>
+Date: Mon, 23 Sep 2013 00:52:09 -0400
+Subject: [PATCH] BZ #15754: CVE-2013-4788
+
+The pointer guard used for pointer mangling was not initialized for
+static applications resulting in the security feature being disabled.
+The pointer guard is now correctly initialized to a random value for
+static applications. Existing static applications need to be
+recompiled to take advantage of the fix.
+
+The test tst-ptrguard1-static and tst-ptrguard1 add regression
+coverage to ensure the pointer guards are sufficiently random
+and initialized to a default value.
+---
+ ports/sysdeps/ia64/stackguard-macros.h | 3 +++
+ ports/sysdeps/tile/stackguard-macros.h | 6 ++++++
+ sysdeps/generic/stackguard-macros.h | 3 +++
+ sysdeps/i386/stackguard-macros.h | 8 ++++++++
+ sysdeps/powerpc/powerpc32/stackguard-macros.h | 10 ++++++++++
+ sysdeps/powerpc/powerpc64/stackguard-macros.h | 10 ++++++++++
+ sysdeps/s390/s390-32/stackguard-macros.h | 11 +++++++++++
+ sysdeps/s390/s390-64/stackguard-macros.h | 14 ++++++++++++++
+ sysdeps/sparc/sparc32/stackguard-macros.h | 3 +++
+ sysdeps/sparc/sparc64/stackguard-macros.h | 3 +++
+ sysdeps/x86_64/stackguard-macros.h | 5 +++++
+ 11 files changed, 76 insertions(+)
+
+diff --git a/ports/sysdeps/ia64/stackguard-macros.h b/ports/sysdeps/ia64/stackguard-macros.h
+index dc683c2..3907293 100644
+--- a/ports/sysdeps/ia64/stackguard-macros.h
++++ b/ports/sysdeps/ia64/stackguard-macros.h
+@@ -2,3 +2,6 @@
+
+ #define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("adds %0 = -8, r13;; ld8 %0 = [%0]" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++ ({ uintptr_t x; asm ("adds %0 = -16, r13;; ld8 %0 = [%0]" : "=r" (x)); x; })
+diff --git a/ports/sysdeps/tile/stackguard-macros.h b/ports/sysdeps/tile/stackguard-macros.h
+index 589ea2b..f2e041b 100644
+--- a/ports/sysdeps/tile/stackguard-macros.h
++++ b/ports/sysdeps/tile/stackguard-macros.h
+@@ -4,11 +4,17 @@
+ # if __WORDSIZE == 64
+ # define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("addi %0, tp, -16; ld %0, %0" : "=r" (x)); x; })
++# define POINTER_CHK_GUARD \
++ ({ uintptr_t x; asm ("addi %0, tp, -24; ld %0, %0" : "=r" (x)); x; })
+ # else
+ # define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("addi %0, tp, -8; ld4s %0, %0" : "=r" (x)); x; })
++# define POINTER_CHK_GUARD \
++ ({ uintptr_t x; asm ("addi %0, tp, -12; ld4s %0, %0" : "=r" (x)); x; })
+ # endif
+ #else
+ # define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("addi %0, tp, -8; lw %0, %0" : "=r" (x)); x; })
++# define POINTER_CHK_GUARD \
++ ({ uintptr_t x; asm ("addi %0, tp, -12; lw %0, %0" : "=r" (x)); x; })
+ #endif
+diff --git a/sysdeps/generic/stackguard-macros.h b/sysdeps/generic/stackguard-macros.h
+index ababf65..4fa3d96 100644
+--- a/sysdeps/generic/stackguard-macros.h
++++ b/sysdeps/generic/stackguard-macros.h
+@@ -2,3 +2,6 @@
+
+ extern uintptr_t __stack_chk_guard;
+ #define STACK_CHK_GUARD __stack_chk_guard
++
++extern uintptr_t __pointer_chk_guard_local;
++#define POINTER_CHK_GUARD __pointer_chk_guard_local
+diff --git a/sysdeps/i386/stackguard-macros.h b/sysdeps/i386/stackguard-macros.h
+index 8c31e19..0397629 100644
+--- a/sysdeps/i386/stackguard-macros.h
++++ b/sysdeps/i386/stackguard-macros.h
+@@ -2,3 +2,11 @@
+
+ #define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("movl %%gs:0x14, %0" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++ ({ \
++ uintptr_t x; \
++ asm ("movl %%gs:%c1, %0" : "=r" (x) \
++ : "i" (offsetof (tcbhead_t, pointer_guard))); \
++ x; \
++ })
+diff --git a/sysdeps/powerpc/powerpc32/stackguard-macros.h b/sysdeps/powerpc/powerpc32/stackguard-macros.h
+index 839f6a4..b3d0af8 100644
+--- a/sysdeps/powerpc/powerpc32/stackguard-macros.h
++++ b/sysdeps/powerpc/powerpc32/stackguard-macros.h
+@@ -2,3 +2,13 @@
+
+ #define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("lwz %0,-28680(2)" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++ ({ \
++ uintptr_t x; \
++ asm ("lwz %0,%1(2)" \
++ : "=r" (x) \
++ : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \
++ ); \
++ x; \
++ })
+diff --git a/sysdeps/powerpc/powerpc64/stackguard-macros.h b/sysdeps/powerpc/powerpc64/stackguard-macros.h
+index 9da879c..4620f96 100644
+--- a/sysdeps/powerpc/powerpc64/stackguard-macros.h
++++ b/sysdeps/powerpc/powerpc64/stackguard-macros.h
+@@ -2,3 +2,13 @@
+
+ #define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("ld %0,-28688(13)" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++ ({ \
++ uintptr_t x; \
++ asm ("ld %0,%1(2)" \
++ : "=r" (x) \
++ : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \
++ ); \
++ x; \
++ })
+diff --git a/sysdeps/s390/s390-32/stackguard-macros.h b/sysdeps/s390/s390-32/stackguard-macros.h
+index b74c579..449e8d4 100644
+--- a/sysdeps/s390/s390-32/stackguard-macros.h
++++ b/sysdeps/s390/s390-32/stackguard-macros.h
+@@ -2,3 +2,14 @@
+
+ #define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("ear %0,%%a0; l %0,0x14(%0)" : "=a" (x)); x; })
++
++/* On s390/s390x there is no unique pointer guard, instead we use the
++ same value as the stack guard. */
++#define POINTER_CHK_GUARD \
++ ({ \
++ uintptr_t x; \
++ asm ("ear %0,%%a0; l %0,%1(%0)" \
++ : "=a" (x) \
++ : "i" (offsetof (tcbhead_t, stack_guard))); \
++ x; \
++ })
+diff --git a/sysdeps/s390/s390-64/stackguard-macros.h b/sysdeps/s390/s390-64/stackguard-macros.h
+index 0cebb5f..c8270fb 100644
+--- a/sysdeps/s390/s390-64/stackguard-macros.h
++++ b/sysdeps/s390/s390-64/stackguard-macros.h
+@@ -2,3 +2,17 @@
+
+ #define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; })
++
++/* On s390/s390x there is no unique pointer guard, instead we use the
++ same value as the stack guard. */
++#define POINTER_CHK_GUARD \
++ ({ \
++ uintptr_t x; \
++ asm ("ear %0,%%a0;" \
++ "sllg %0,%0,32;" \
++ "ear %0,%%a1;" \
++ "lg %0,%1(%0)" \
++ : "=a" (x) \
++ : "i" (offsetof (tcbhead_t, stack_guard))); \
++ x; \
++ })
+diff --git a/sysdeps/sparc/sparc32/stackguard-macros.h b/sysdeps/sparc/sparc32/stackguard-macros.h
+index c0b02b0..1eef0f1 100644
+--- a/sysdeps/sparc/sparc32/stackguard-macros.h
++++ b/sysdeps/sparc/sparc32/stackguard-macros.h
+@@ -2,3 +2,6 @@
+
+ #define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("ld [%%g7+0x14], %0" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++ ({ uintptr_t x; asm ("ld [%%g7+0x18], %0" : "=r" (x)); x; })
+diff --git a/sysdeps/sparc/sparc64/stackguard-macros.h b/sysdeps/sparc/sparc64/stackguard-macros.h
+index 80f0635..cc0c12c 100644
+--- a/sysdeps/sparc/sparc64/stackguard-macros.h
++++ b/sysdeps/sparc/sparc64/stackguard-macros.h
+@@ -2,3 +2,6 @@
+
+ #define STACK_CHK_GUARD \
+ ({ uintptr_t x; asm ("ldx [%%g7+0x28], %0" : "=r" (x)); x; })
++
++#define POINTER_CHK_GUARD \
++ ({ uintptr_t x; asm ("ldx [%%g7+0x30], %0" : "=r" (x)); x; })
+diff --git a/sysdeps/x86_64/stackguard-macros.h b/sysdeps/x86_64/stackguard-macros.h
+index d7fedb3..1948800 100644
+--- a/sysdeps/x86_64/stackguard-macros.h
++++ b/sysdeps/x86_64/stackguard-macros.h
+@@ -4,3 +4,8 @@
+ ({ uintptr_t x; \
+ asm ("mov %%fs:%c1, %0" : "=r" (x) \
+ : "i" (offsetof (tcbhead_t, stack_guard))); x; })
++
++#define POINTER_CHK_GUARD \
++ ({ uintptr_t x; \
++ asm ("mov %%fs:%c1, %0" : "=r" (x) \
++ : "i" (offsetof (tcbhead_t, pointer_guard))); x; })
diff --git a/patches/glibc-2.18/0009-CVE-2013-4237-BZ-14699-Buffer-overflow-in-readdir_r.patch b/patches/glibc-2.18/0009-CVE-2013-4237-BZ-14699-Buffer-overflow-in-readdir_r.patch
new file mode 100644
index 0000000..526775b
--- /dev/null
+++ b/patches/glibc-2.18/0009-CVE-2013-4237-BZ-14699-Buffer-overflow-in-readdir_r.patch
@@ -0,0 +1,171 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 16 Aug 2013 09:38:52 +0200
+Subject: [PATCH] CVE-2013-4237, BZ #14699: Buffer overflow in readdir_r
+
+ * sysdeps/posix/dirstream.h (struct __dirstream): Add errcode
+ member.
+ * sysdeps/posix/opendir.c (__alloc_dir): Initialize errcode
+ member.
+ * sysdeps/posix/rewinddir.c (rewinddir): Reset errcode member.
+ * sysdeps/posix/readdir_r.c (__READDIR_R): Enforce NAME_MAX limit.
+ Return delayed error code. Remove GETDENTS_64BIT_ALIGNED
+ conditional.
+ * sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c: Do not define
+ GETDENTS_64BIT_ALIGNED.
+ * sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise.
+ * manual/filesys.texi (Reading/Closing Directory): Document
+ ENAMETOOLONG return value of readdir_r. Recommend readdir more
+ strongly.
+ * manual/conf.texi (Limits for Files): Add portability note to
+ NAME_MAX, PATH_MAX.
+ (Pathconf): Add portability note for _PC_NAME_MAX, _PC_PATH_MAX.
+---
+ sysdeps/posix/dirstream.h | 2 ++
+ sysdeps/posix/opendir.c | 1 +
+ sysdeps/posix/readdir_r.c | 42 ++++++++++++++++++-------
+ sysdeps/posix/rewinddir.c | 1 +
+ sysdeps/unix/sysv/linux/i386/readdir64_r.c | 1 -
+ sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c | 1 -
+ 6 files changed, 34 insertions(+), 14 deletions(-)
+
+diff --git a/sysdeps/posix/dirstream.h b/sysdeps/posix/dirstream.h
+index a7a074d..8e8570d 100644
+--- a/sysdeps/posix/dirstream.h
++++ b/sysdeps/posix/dirstream.h
+@@ -39,6 +39,8 @@ struct __dirstream
+
+ off_t filepos; /* Position of next entry to read. */
+
++ int errcode; /* Delayed error code. */
++
+ /* Directory block. */
+ char data[0] __attribute__ ((aligned (__alignof__ (void*))));
+ };
+diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c
+index ddfc3a7..fc05b0f 100644
+--- a/sysdeps/posix/opendir.c
++++ b/sysdeps/posix/opendir.c
+@@ -231,6 +231,7 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp)
+ dirp->size = 0;
+ dirp->offset = 0;
+ dirp->filepos = 0;
++ dirp->errcode = 0;
+
+ return dirp;
+ }
+diff --git a/sysdeps/posix/readdir_r.c b/sysdeps/posix/readdir_r.c
+index b5a8e2e..8ed5c3f 100644
+--- a/sysdeps/posix/readdir_r.c
++++ b/sysdeps/posix/readdir_r.c
+@@ -40,6 +40,7 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
+ DIRENT_TYPE *dp;
+ size_t reclen;
+ const int saved_errno = errno;
++ int ret;
+
+ __libc_lock_lock (dirp->lock);
+
+@@ -70,10 +71,10 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
+ bytes = 0;
+ __set_errno (saved_errno);
+ }
++ if (bytes < 0)
++ dirp->errcode = errno;
+
+ dp = NULL;
+- /* Reclen != 0 signals that an error occurred. */
+- reclen = bytes != 0;
+ break;
+ }
+ dirp->size = (size_t) bytes;
+@@ -106,29 +107,46 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
+ dirp->filepos += reclen;
+ #endif
+
+- /* Skip deleted files. */
++#ifdef NAME_MAX
++ if (reclen > offsetof (DIRENT_TYPE, d_name) + NAME_MAX + 1)
++ {
++ /* The record is very long. It could still fit into the
++ caller-supplied buffer if we can skip padding at the
++ end. */
++ size_t namelen = _D_EXACT_NAMLEN (dp);
++ if (namelen <= NAME_MAX)
++ reclen = offsetof (DIRENT_TYPE, d_name) + namelen + 1;
++ else
++ {
++ /* The name is too long. Ignore this file. */
++ dirp->errcode = ENAMETOOLONG;
++ dp->d_ino = 0;
++ continue;
++ }
++ }
++#endif
++
++ /* Skip deleted and ignored files. */
+ }
+ while (dp->d_ino == 0);
+
+ if (dp != NULL)
+ {
+-#ifdef GETDENTS_64BIT_ALIGNED
+- /* The d_reclen value might include padding which is not part of
+- the DIRENT_TYPE data structure. */
+- reclen = MIN (reclen,
+- offsetof (DIRENT_TYPE, d_name) + sizeof (dp->d_name));
+-#endif
+ *result = memcpy (entry, dp, reclen);
+-#ifdef GETDENTS_64BIT_ALIGNED
++#ifdef _DIRENT_HAVE_D_RECLEN
+ entry->d_reclen = reclen;
+ #endif
++ ret = 0;
+ }
+ else
+- *result = NULL;
++ {
++ *result = NULL;
++ ret = dirp->errcode;
++ }
+
+ __libc_lock_unlock (dirp->lock);
+
+- return dp != NULL ? 0 : reclen ? errno : 0;
++ return ret;
+ }
+
+ #ifdef __READDIR_R_ALIAS
+diff --git a/sysdeps/posix/rewinddir.c b/sysdeps/posix/rewinddir.c
+index 2935a8e..d4991ad 100644
+--- a/sysdeps/posix/rewinddir.c
++++ b/sysdeps/posix/rewinddir.c
+@@ -33,6 +33,7 @@ rewinddir (dirp)
+ dirp->filepos = 0;
+ dirp->offset = 0;
+ dirp->size = 0;
++ dirp->errcode = 0;
+ #ifndef NOT_IN_libc
+ __libc_lock_unlock (dirp->lock);
+ #endif
+diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
+index 8ebbcfd..a7d114e 100644
+--- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c
++++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
+@@ -18,7 +18,6 @@
+ #define __READDIR_R __readdir64_r
+ #define __GETDENTS __getdents64
+ #define DIRENT_TYPE struct dirent64
+-#define GETDENTS_64BIT_ALIGNED 1
+
+ #include <sysdeps/posix/readdir_r.c>
+
+diff --git a/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c b/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c
+index 5ed8e95..290f2c8 100644
+--- a/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c
++++ b/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c
+@@ -1,5 +1,4 @@
+ #define readdir64_r __no_readdir64_r_decl
+-#define GETDENTS_64BIT_ALIGNED 1
+ #include <sysdeps/posix/readdir_r.c>
+ #undef readdir64_r
+ weak_alias (__readdir_r, readdir64_r)
diff --git a/patches/glibc-2.18/0010-malloc-Check-for-integer-overflow-in-pvalloc.patch b/patches/glibc-2.18/0010-malloc-Check-for-integer-overflow-in-pvalloc.patch
new file mode 100644
index 0000000..9331ceb
--- /dev/null
+++ b/patches/glibc-2.18/0010-malloc-Check-for-integer-overflow-in-pvalloc.patch
@@ -0,0 +1,37 @@
+From: Will Newton <will.newton@linaro.org>
+Date: Mon, 12 Aug 2013 15:08:02 +0100
+Subject: [PATCH] malloc: Check for integer overflow in pvalloc.
+
+A large bytes parameter to pvalloc could cause an integer overflow
+and corrupt allocator internals. Check the overflow does not occur
+before continuing with the allocation.
+
+ChangeLog:
+
+2013-09-11 Will Newton <will.newton@linaro.org>
+
+ [BZ #15855]
+ * malloc/malloc.c (__libc_pvalloc): Check the value of bytes
+ does not overflow.
+---
+ malloc/malloc.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index be472b2..bcc08c4 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -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;
++ }
++
+ void *(*hook) (size_t, size_t, const void *) =
+ force_reg (__memalign_hook);
+ if (__builtin_expect (hook != NULL, 0))
diff --git a/patches/glibc-2.18/0011-malloc-Check-for-integer-overflow-in-valloc.patch b/patches/glibc-2.18/0011-malloc-Check-for-integer-overflow-in-valloc.patch
new file mode 100644
index 0000000..1a29ffb
--- /dev/null
+++ b/patches/glibc-2.18/0011-malloc-Check-for-integer-overflow-in-valloc.patch
@@ -0,0 +1,37 @@
+From: Will Newton <will.newton@linaro.org>
+Date: Fri, 16 Aug 2013 11:59:37 +0100
+Subject: [PATCH] malloc: Check for integer overflow in valloc.
+
+A large bytes parameter to valloc could cause an integer overflow
+and corrupt allocator internals. Check the overflow does not occur
+before continuing with the allocation.
+
+ChangeLog:
+
+2013-09-11 Will Newton <will.newton@linaro.org>
+
+ [BZ #15856]
+ * malloc/malloc.c (__libc_valloc): Check the value of bytes
+ does not overflow.
+---
+ malloc/malloc.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index bcc08c4..31e2dfa 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -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;
++ }
++
+ void *(*hook) (size_t, size_t, const void *) =
+ force_reg (__memalign_hook);
+ if (__builtin_expect (hook != NULL, 0))
diff --git a/patches/glibc-2.18/0012-malloc-Check-for-integer-overflow-in-memalign.patch b/patches/glibc-2.18/0012-malloc-Check-for-integer-overflow-in-memalign.patch
new file mode 100644
index 0000000..8bc5718
--- /dev/null
+++ b/patches/glibc-2.18/0012-malloc-Check-for-integer-overflow-in-memalign.patch
@@ -0,0 +1,37 @@
+From: Will Newton <will.newton@linaro.org>
+Date: Fri, 16 Aug 2013 12:54:29 +0100
+Subject: [PATCH] malloc: Check for integer overflow in memalign.
+
+A large bytes parameter to memalign could cause an integer overflow
+and corrupt allocator internals. Check the overflow does not occur
+before continuing with the allocation.
+
+ChangeLog:
+
+2013-09-11 Will Newton <will.newton@linaro.org>
+
+ [BZ #15857]
+ * malloc/malloc.c (__libc_memalign): Check the value of bytes
+ does not overflow.
+---
+ malloc/malloc.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 31e2dfa..ebbe86d 100644
+--- a/malloc/malloc.c
++++ b/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;
diff --git a/patches/glibc-2.18/0013-Fix-stack-overflow-due-to-large-AF_INET6-requests.patch b/patches/glibc-2.18/0013-Fix-stack-overflow-due-to-large-AF_INET6-requests.patch
new file mode 100644
index 0000000..c59df8c
--- /dev/null
+++ b/patches/glibc-2.18/0013-Fix-stack-overflow-due-to-large-AF_INET6-requests.patch
@@ -0,0 +1,51 @@
+From: Siddhesh Poyarekar <siddhesh@redhat.com>
+Date: Fri, 25 Oct 2013 10:22:12 +0530
+Subject: [PATCH] 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.
+---
+ sysdeps/posix/getaddrinfo.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index 7bb3ded..2e97255 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/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; \
diff --git a/patches/glibc-2.18/0100-add-install-lib-all-target.patch b/patches/glibc-2.18/0100-add-install-lib-all-target.patch
new file mode 100644
index 0000000..078aba9
--- /dev/null
+++ b/patches/glibc-2.18/0100-add-install-lib-all-target.patch
@@ -0,0 +1,35 @@
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Tue, 1 Nov 2011 19:22:27 +0100
+Subject: [PATCH] add install-lib-all target
+
+From http://svn.exactcode.de/t2/trunk/package/base/glibc32/make-install-lib-all.patch
+
+Rule to install all needed libraries, not just the ones installed by install-lib,
+yet not install programs.
+Needed because we can't use the main install target, as we can't build programs before
+we have the final gcc installed; linking fails because libeh.a is not present,
+and glibc insists on linking programs with that library.
+
+Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
+---
+ Makerules | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/Makerules b/Makerules
+index 03eafb0..5d7effd 100644
+--- a/Makerules
++++ b/Makerules
+@@ -801,6 +801,13 @@ endef
+ installed-libcs := $(foreach o,$(filter-out .os,$(object-suffixes-for-libc)),\
+ $(inst_libdir)/$(patsubst %,$(libtype$o),\
+ $(libprefix)$(libc-name)))
++
++install-lib-all: $(inst_slibdir)/libc.so$(libc.so-version) \
++ $(inst_slibdir)/libc-$(version).so \
++ $(inst_libdir)/libc.so \
++ $(inst_libdir)/libc.a \
++ install-lib
++
+ install: $(installed-libcs)
+ $(installed-libcs): $(inst_libdir)/lib$(libprefix)%: lib $(+force)
+ $(make-target-directory)
diff --git a/patches/glibc-2.18/0101-don-t-regen-docs-if-perl-is-not-found.patch b/patches/glibc-2.18/0101-don-t-regen-docs-if-perl-is-not-found.patch
new file mode 100644
index 0000000..f89304d
--- /dev/null
+++ b/patches/glibc-2.18/0101-don-t-regen-docs-if-perl-is-not-found.patch
@@ -0,0 +1,35 @@
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Wed, 2 Nov 2011 00:14:37 +0100
+Subject: [PATCH] don't regen docs if perl is not found
+
+If we're using a cvs snapshot which updates the source files, and
+perl isn't installed yet, then we can't regen the docs. Not a big
+deal, so just whine a little and continue on our merry way.
+
+This patch was taken from gentoo.
+http://bugs.gentoo.org/60132
+
+Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
+---
+ manual/Makefile | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/manual/Makefile b/manual/Makefile
+index 44c0fd4..54217e0 100644
+--- a/manual/Makefile
++++ b/manual/Makefile
+@@ -107,9 +107,14 @@ $(objpfx)dir-add.texi: xtract-typefun.awk $(texis-path)
+ $(objpfx)libm-err.texi: $(objpfx)stamp-libm-err
+ $(objpfx)stamp-libm-err: libm-err-tab.pl $(wildcard $(foreach dir,$(sysdirs),\
+ $(dir)/libm-test-ulps))
++ifneq ($(PERL),no)
+ pwd=`pwd`; \
+ $(PERL) $< $$pwd/.. > $(objpfx)libm-err-tmp
+ $(move-if-change) $(objpfx)libm-err-tmp $(objpfx)libm-err.texi
++else
++ echo "Unable to rebuild math docs, no perl installed"
++ touch libm-err.texi
++endif
+ touch $@
+
+ # Package version and bug reporting URL.
diff --git a/patches/glibc-2.18/0200-Fix-localedef-segfault-when-run-under-exec-shield-Pa.patch b/patches/glibc-2.18/0200-Fix-localedef-segfault-when-run-under-exec-shield-Pa.patch
new file mode 100644
index 0000000..02c87ef
--- /dev/null
+++ b/patches/glibc-2.18/0200-Fix-localedef-segfault-when-run-under-exec-shield-Pa.patch
@@ -0,0 +1,67 @@
+From: Jakub Jelinek <jakub@redhat.com>
+Date: Tue, 1 Nov 2011 18:58:26 +0100
+Subject: [PATCH] Fix localedef segfault when run under exec-shield, PaX or
+ similar
+
+# DP: Description: Fix localedef segfault when run under exec-shield,
+# PaX or similar. (#231438, #198099)
+# DP: Dpatch Author: James Troup <james@nocrew.org>
+# DP: Patch Author: (probably) Jakub Jelinek <jakub@redhat.com>
+# DP: Upstream status: Unknown
+# DP: Status Details: Unknown
+# DP: Date: 2004-03-16
+
+Taken from Debian.
+
+Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
+---
+ locale/programs/3level.h | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/locale/programs/3level.h b/locale/programs/3level.h
+index 9b8b1b9..93b643c 100644
+--- a/locale/programs/3level.h
++++ b/locale/programs/3level.h
+@@ -204,6 +204,42 @@ CONCAT(TABLE,_iterate) (struct TABLE *t,
+ }
+ }
+ }
++
++/* GCC ATM seems to do a poor job with pointers to nested functions passed
++ to inlined functions. Help it a little bit with this hack. */
++#define wchead_table_iterate(tp, fn) \
++do \
++ { \
++ struct wchead_table *t = (tp); \
++ uint32_t index1; \
++ for (index1 = 0; index1 < t->level1_size; index1++) \
++ { \
++ uint32_t lookup1 = t->level1[index1]; \
++ if (lookup1 != ((uint32_t) ~0)) \
++ { \
++ uint32_t lookup1_shifted = lookup1 << t->q; \
++ uint32_t index2; \
++ for (index2 = 0; index2 < (1 << t->q); index2++) \
++ { \
++ uint32_t lookup2 = t->level2[index2 + lookup1_shifted]; \
++ if (lookup2 != ((uint32_t) ~0)) \
++ { \
++ uint32_t lookup2_shifted = lookup2 << t->p; \
++ uint32_t index3; \
++ for (index3 = 0; index3 < (1 << t->p); index3++) \
++ { \
++ struct element_t *lookup3 \
++ = t->level3[index3 + lookup2_shifted]; \
++ if (lookup3 != NULL) \
++ fn ((((index1 << t->q) + index2) << t->p) + index3, \
++ lookup3); \
++ } \
++ } \
++ } \
++ } \
++ } \
++ } while (0)
++
+ #endif
+
+ #ifndef NO_FINALIZE
diff --git a/patches/glibc-2.18/0300-resolv-dynamic.patch b/patches/glibc-2.18/0300-resolv-dynamic.patch
new file mode 100644
index 0000000..efe056e
--- /dev/null
+++ b/patches/glibc-2.18/0300-resolv-dynamic.patch
@@ -0,0 +1,47 @@
+From: unknown author <unknown.author@example.com>
+Date: Tue, 1 Nov 2011 18:58:26 +0100
+Subject: [PATCH] resolv dynamic
+
+ripped from SuSE
+
+if /etc/resolv.conf is updated, then make sure applications
+already running get the updated information.
+
+http://bugs.gentoo.org/177416
+---
+ resolv/res_libc.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/resolv/res_libc.c b/resolv/res_libc.c
+index 48d3200..a443345 100644
+--- a/resolv/res_libc.c
++++ b/resolv/res_libc.c
+@@ -22,6 +22,7 @@
+ #include <arpa/nameser.h>
+ #include <resolv.h>
+ #include <bits/libc-lock.h>
++#include <sys/stat.h>
+
+
+ /* The following bit is copied from res_data.c (where it is #ifdef'ed
+@@ -95,6 +96,20 @@ int
+ __res_maybe_init (res_state resp, int preinit)
+ {
+ if (resp->options & RES_INIT) {
++ static time_t last_mtime, last_check;
++ time_t now;
++ struct stat statbuf;
++
++ time (&now);
++ if (now != last_check) {
++ last_check = now;
++ if (stat (_PATH_RESCONF, &statbuf) == 0 && last_mtime != statbuf.st_mtime) {
++ last_mtime = statbuf.st_mtime;
++ atomicinclock (lock);
++ atomicinc (__res_initstamp);
++ atomicincunlock (lock);
++ }
++ }
+ if (__res_initstamp != resp->_u._ext.initstamp) {
+ if (resp->nscount > 0)
+ __res_iclose (resp, true);
diff --git a/patches/glibc-2.18/0400-optimized-string-functions-for-NEON-from-Linaro.patch b/patches/glibc-2.18/0400-optimized-string-functions-for-NEON-from-Linaro.patch
new file mode 100644
index 0000000..4795949
--- /dev/null
+++ b/patches/glibc-2.18/0400-optimized-string-functions-for-NEON-from-Linaro.patch
@@ -0,0 +1,699 @@
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Thu, 15 Sep 2011 16:50:56 +0200
+Subject: [PATCH] optimized string functions for NEON from Linaro
+
+Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
+---
+ cortex-strings/sysdeps/arm/armv7/memchr.S | 155 ++++++++++++++++++++++++++++++
+ cortex-strings/sysdeps/arm/armv7/memcpy.S | 152 +++++++++++++++++++++++++++++
+ cortex-strings/sysdeps/arm/armv7/memset.S | 118 +++++++++++++++++++++++
+ cortex-strings/sysdeps/arm/armv7/strchr.S | 76 +++++++++++++++
+ cortex-strings/sysdeps/arm/armv7/strlen.S | 150 +++++++++++++++++++++++++++++
+ 5 files changed, 651 insertions(+)
+ create mode 100644 cortex-strings/sysdeps/arm/armv7/memchr.S
+ create mode 100644 cortex-strings/sysdeps/arm/armv7/memcpy.S
+ create mode 100644 cortex-strings/sysdeps/arm/armv7/memset.S
+ create mode 100644 cortex-strings/sysdeps/arm/armv7/strchr.S
+ create mode 100644 cortex-strings/sysdeps/arm/armv7/strlen.S
+
+diff --git a/cortex-strings/sysdeps/arm/armv7/memchr.S b/cortex-strings/sysdeps/arm/armv7/memchr.S
+new file mode 100644
+index 0000000..92a2d9f
+--- /dev/null
++++ b/cortex-strings/sysdeps/arm/armv7/memchr.S
+@@ -0,0 +1,155 @@
++/* Copyright (c) 2010-2011, Linaro Limited
++ All rights reserved.
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions
++ are met:
++
++ * Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++
++ * Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++
++ * Neither the name of Linaro Limited nor the names of its
++ contributors may be used to endorse or promote products derived
++ from this software without specific prior written permission.
++
++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/*
++ Written by Dave Gilbert <david.gilbert@linaro.org>
++
++ This memchr routine is optimised on a Cortex-A9 and should work on
++ all ARMv7 processors. It has a fast past for short sizes, and has
++ an optimised path for large data sets; the worst case is finding the
++ match early in a large data set.
++
++ */
++
++@ 2011-02-07 david.gilbert@linaro.org
++@ Extracted from local git a5b438d861
++@ 2011-07-14 david.gilbert@linaro.org
++@ Import endianness fix from local git ea786f1b
++@ 2011-12-07 david.gilbert@linaro.org
++@ Removed unneeded cbz from align loop
++
++ .syntax unified
++ .arch armv7-a
++
++@ this lets us check a flag in a 00/ff byte easily in either endianness
++#ifdef __ARMEB__
++#define CHARTSTMASK(c) 1<<(31-(c*8))
++#else
++#define CHARTSTMASK(c) 1<<(c*8)
++#endif
++ .text
++ .thumb
++
++@ ---------------------------------------------------------------------------
++ .thumb_func
++ .align 2
++ .p2align 4,,15
++ .global memchr
++ .type memchr,%function
++memchr:
++ @ r0 = start of memory to scan
++ @ r1 = character to look for
++ @ r2 = length
++ @ returns r0 = pointer to character or NULL if not found
++ and r1,r1,#0xff @ Don't think we can trust the caller to actually pass a char
++
++ cmp r2,#16 @ If it's short don't bother with anything clever
++ blt 20f
++
++ tst r0, #7 @ If it's already aligned skip the next bit
++ beq 10f
++
++ @ Work up to an aligned point
++5:
++ ldrb r3, [r0],#1
++ subs r2, r2, #1
++ cmp r3, r1
++ beq 50f @ If it matches exit found
++ tst r0, #7
++ bne 5b @ If not aligned yet then do next byte
++
++10:
++ @ At this point, we are aligned, we know we have at least 8 bytes to work with
++ push {r4,r5,r6,r7}
++ orr r1, r1, r1, lsl #8 @ expand the match word across to all bytes
++ orr r1, r1, r1, lsl #16
++ bic r4, r2, #7 @ Number of double words to work with
++ mvns r7, #0 @ all F's
++ movs r3, #0
++
++15:
++ ldmia r0!,{r5,r6}
++ subs r4, r4, #8
++ eor r5,r5, r1 @ Get it so that r5,r6 have 00's where the bytes match the target
++ eor r6,r6, r1
++ uadd8 r5, r5, r7 @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
++ sel r5, r3, r7 @ bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
++ uadd8 r6, r6, r7 @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
++ sel r6, r5, r7 @ chained....bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
++ cbnz r6, 60f
++ bne 15b @ (Flags from the subs above) If not run out of bytes then go around again
++
++ pop {r4,r5,r6,r7}
++ and r1,r1,#0xff @ Get r1 back to a single character from the expansion above
++ and r2,r2,#7 @ Leave the count remaining as the number after the double words have been done
++
++20:
++ cbz r2, 40f @ 0 length or hit the end already then not found
++
++21: @ Post aligned section, or just a short call
++ ldrb r3,[r0],#1
++ subs r2,r2,#1
++ eor r3,r3,r1 @ r3 = 0 if match - doesn't break flags from sub
++ cbz r3, 50f
++ bne 21b @ on r2 flags
++
++40:
++ movs r0,#0 @ not found
++ bx lr
++
++50:
++ subs r0,r0,#1 @ found
++ bx lr
++
++60: @ We're here because the fast path found a hit - now we have to track down exactly which word it was
++ @ r0 points to the start of the double word after the one that was tested
++ @ r5 has the 00/ff pattern for the first word, r6 has the chained value
++ cmp r5, #0
++ itte eq
++ moveq r5, r6 @ the end is in the 2nd word
++ subeq r0,r0,#3 @ Points to 2nd byte of 2nd word
++ subne r0,r0,#7 @ or 2nd byte of 1st word
++
++ @ r0 currently points to the 3rd byte of the word containing the hit
++ tst r5, # CHARTSTMASK(0) @ 1st character
++ bne 61f
++ adds r0,r0,#1
++ tst r5, # CHARTSTMASK(1) @ 2nd character
++ ittt eq
++ addeq r0,r0,#1
++ tsteq r5, # (3<<15) @ 2nd & 3rd character
++ @ If not the 3rd must be the last one
++ addeq r0,r0,#1
++
++61:
++ pop {r4,r5,r6,r7}
++ subs r0,r0,#1
++ bx lr
+diff --git a/cortex-strings/sysdeps/arm/armv7/memcpy.S b/cortex-strings/sysdeps/arm/armv7/memcpy.S
+new file mode 100644
+index 0000000..3be24ca
+--- /dev/null
++++ b/cortex-strings/sysdeps/arm/armv7/memcpy.S
+@@ -0,0 +1,152 @@
++/* Copyright (c) 2010-2011, Linaro Limited
++ All rights reserved.
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions
++ are met:
++
++ * Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++
++ * Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++
++ * Neither the name of Linaro Limited nor the names of its
++ contributors may be used to endorse or promote products derived
++ from this software without specific prior written permission.
++
++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++ Written by Dave Gilbert <david.gilbert@linaro.org>
++
++ This memcpy routine is optimised on a Cortex-A9 and should work on
++ all ARMv7 processors with NEON. */
++
++@ 2011-09-01 david.gilbert@linaro.org
++@ Extracted from local git 2f11b436
++
++ .syntax unified
++ .arch armv7-a
++
++@ this lets us check a flag in a 00/ff byte easily in either endianness
++#ifdef __ARMEB__
++#define CHARTSTMASK(c) 1<<(31-(c*8))
++#else
++#define CHARTSTMASK(c) 1<<(c*8)
++#endif
++ .text
++ .thumb
++
++@ ---------------------------------------------------------------------------
++ .thumb_func
++ .align 2
++ .p2align 4,,15
++ .global memcpy
++ .type memcpy,%function
++memcpy:
++ @ r0 = dest
++ @ r1 = source
++ @ r2 = count
++ @ returns dest in r0
++ @ Overlaps of source/dest not allowed according to spec
++ @ Note this routine relies on v7 misaligned loads/stores
++ pld [r1]
++ mov r12, r0 @ stash original r0
++ cmp r2,#32
++ blt 10f @ take the small copy case separately
++
++ @ test for either source or destination being misaligned
++ @ (We only rely on word align)
++ tst r0,#3
++ it eq
++ tsteq r1,#3
++ bne 30f @ misaligned case
++
++4:
++ @ at this point we are word (or better) aligned and have at least
++ @ 32 bytes to play with
++
++ @ If it's a huge copy, try Neon
++ cmp r2, #128*1024
++ bge 35f @ Sharing general non-aligned case here, aligned could be faster
++
++ push {r3,r4,r5,r6,r7,r8,r10,r11}
++5:
++ ldmia r1!,{r3,r4,r5,r6,r7,r8,r10,r11}
++ sub r2,r2,#32
++ pld [r1,#96]
++ cmp r2,#32
++ stmia r0!,{r3,r4,r5,r6,r7,r8,r10,r11}
++ bge 5b
++
++ pop {r3,r4,r5,r6,r7,r8,r10,r11}
++ @ We are now down to less than 32 bytes
++ cbz r2,15f @ quick exit for the case where we copied a multiple of 32
++
++10: @ small copies (not necessarily aligned - note might be slightly more than 32bytes)
++ cmp r2,#4
++ blt 12f
++11:
++ sub r2,r2,#4
++ cmp r2,#4
++ ldr r3, [r1],#4
++ str r3, [r0],#4
++ bge 11b
++12:
++ tst r2,#2
++ itt ne
++ ldrhne r3, [r1],#2
++ strhne r3, [r0],#2
++
++ tst r2,#1
++ itt ne
++ ldrbne r3, [r1],#1
++ strbne r3, [r0],#1
++
++15: @ exit
++ mov r0,r12 @ restore r0
++ bx lr
++
++ .align 2
++ .p2align 4,,15
++30: @ non-aligned - at least 32 bytes to play with
++ @ Test for co-misalignment
++ eor r3, r0, r1
++ tst r3,#3
++ beq 50f
++
++ @ Use Neon for misaligned
++35:
++ vld1.8 {d0,d1,d2,d3}, [r1]!
++ sub r2,r2,#32
++ cmp r2,#32
++ pld [r1,#96]
++ vst1.8 {d0,d1,d2,d3}, [r0]!
++ bge 35b
++ b 10b @ TODO: Probably a bad idea to switch to ARM at this point
++
++ .align 2
++ .p2align 4,,15
++50: @ Co-misaligned
++ @ At this point we've got at least 32 bytes
++51:
++ ldrb r3,[r1],#1
++ sub r2,r2,#1
++ strb r3,[r0],#1
++ tst r0,#7
++ bne 51b
++
++ cmp r2,#32
++ blt 10b
++ b 4b
+diff --git a/cortex-strings/sysdeps/arm/armv7/memset.S b/cortex-strings/sysdeps/arm/armv7/memset.S
+new file mode 100644
+index 0000000..921cb75
+--- /dev/null
++++ b/cortex-strings/sysdeps/arm/armv7/memset.S
+@@ -0,0 +1,118 @@
++/* Copyright (c) 2010-2011, Linaro Limited
++ All rights reserved.
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions
++ are met:
++
++ * Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++
++ * Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++
++ * Neither the name of Linaro Limited nor the names of its
++ contributors may be used to endorse or promote products derived
++ from this software without specific prior written permission.
++
++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++ Written by Dave Gilbert <david.gilbert@linaro.org>
++
++ This memset routine is optimised on a Cortex-A9 and should work on
++ all ARMv7 processors. */
++
++ .syntax unified
++ .arch armv7-a
++
++@ 2011-08-30 david.gilbert@linaro.org
++@ Extracted from local git 2f11b436
++
++@ this lets us check a flag in a 00/ff byte easily in either endianness
++#ifdef __ARMEB__
++#define CHARTSTMASK(c) 1<<(31-(c*8))
++#else
++#define CHARTSTMASK(c) 1<<(c*8)
++#endif
++ .text
++ .thumb
++
++@ ---------------------------------------------------------------------------
++ .thumb_func
++ .align 2
++ .p2align 4,,15
++ .global memset
++ .type memset,%function
++memset:
++ @ r0 = address
++ @ r1 = character
++ @ r2 = count
++ @ returns original address in r0
++
++ mov r3, r0 @ Leave r0 alone
++ cbz r2, 10f @ Exit if 0 length
++
++ tst r0, #7
++ beq 2f @ Already aligned
++
++ @ Ok, so we're misaligned here
++1:
++ strb r1, [r3], #1
++ subs r2,r2,#1
++ tst r3, #7
++ cbz r2, 10f @ Exit if we hit the end
++ bne 1b @ go round again if still misaligned
++
++2:
++ @ OK, so we're aligned
++ push {r4,r5,r6,r7}
++ bics r4, r2, #15 @ if less than 16 bytes then need to finish it off
++ beq 5f
++
++3:
++ @ POSIX says that ch is cast to an unsigned char. A uxtb is one
++ @ byte and takes two cycles, where an AND is four bytes but one
++ @ cycle.
++ and r1, #0xFF
++ orr r1, r1, r1, lsl#8 @ Same character into all bytes
++ orr r1, r1, r1, lsl#16
++ mov r5,r1
++ mov r6,r1
++ mov r7,r1
++
++4:
++ subs r4,r4,#16
++ stmia r3!,{r1,r5,r6,r7}
++ bne 4b
++ and r2,r2,#15
++
++ @ At this point we're still aligned and we have upto align-1 bytes left to right
++ @ we can avoid some of the byte-at-a time now by testing for some big chunks
++ tst r2,#8
++ itt ne
++ subne r2,r2,#8
++ stmiane r3!,{r1,r5}
++
++5:
++ pop {r4,r5,r6,r7}
++ cbz r2, 10f
++
++ @ Got to do any last < alignment bytes
++6:
++ subs r2,r2,#1
++ strb r1,[r3],#1
++ bne 6b
++
++10:
++ bx lr @ goodbye
+diff --git a/cortex-strings/sysdeps/arm/armv7/strchr.S b/cortex-strings/sysdeps/arm/armv7/strchr.S
+new file mode 100644
+index 0000000..8875dbf
+--- /dev/null
++++ b/cortex-strings/sysdeps/arm/armv7/strchr.S
+@@ -0,0 +1,76 @@
++/* Copyright (c) 2010-2011, Linaro Limited
++ All rights reserved.
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions
++ are met:
++
++ * Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++
++ * Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++
++ * Neither the name of Linaro Limited nor the names of its
++ contributors may be used to endorse or promote products derived
++ from this software without specific prior written permission.
++
++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++ Written by Dave Gilbert <david.gilbert@linaro.org>
++
++ A very simple strchr routine, from benchmarks on A9 it's a bit faster than
++ the current version in eglibc (2.12.1-0ubuntu14 package)
++ I don't think doing a word at a time version is worth it since a lot
++ of strchr cases are very short anyway */
++
++@ 2011-02-07 david.gilbert@linaro.org
++@ Extracted from local git a5b438d861
++
++ .syntax unified
++ .arch armv7-a
++
++ .text
++ .thumb
++
++@ ---------------------------------------------------------------------------
++
++ .thumb_func
++ .align 2
++ .p2align 4,,15
++ .global strchr
++ .type strchr,%function
++strchr:
++ @ r0 = start of string
++ @ r1 = character to match
++ @ returns NULL for no match, or a pointer to the match
++ and r1,r1, #255
++
++1:
++ ldrb r2,[r0],#1
++ cmp r2,r1
++ cbz r2,10f
++ bne 1b
++
++ @ We're here if it matched
++5:
++ subs r0,r0,#1
++ bx lr
++
++10:
++ @ We're here if we ran off the end
++ cmp r1, #0 @ Corner case - you're allowed to search for the nil and get a pointer to it
++ beq 5b @ A bit messy, if it's common we should branch at the start to a special loop
++ mov r0,#0
++ bx lr
+diff --git a/cortex-strings/sysdeps/arm/armv7/strlen.S b/cortex-strings/sysdeps/arm/armv7/strlen.S
+new file mode 100644
+index 0000000..8efa235
+--- /dev/null
++++ b/cortex-strings/sysdeps/arm/armv7/strlen.S
+@@ -0,0 +1,150 @@
++/* Copyright (c) 2010-2011,2013 Linaro Limited
++ All rights reserved.
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions
++ are met:
++
++ * Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++
++ * Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++
++ * Neither the name of Linaro Limited nor the names of its
++ contributors may be used to endorse or promote products derived
++ from this software without specific prior written permission.
++
++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/*
++ Assumes:
++ ARMv6T2, AArch32
++
++ */
++
++ .macro def_fn f p2align=0
++ .text
++ .p2align \p2align
++ .global \f
++ .type \f, %function
++\f:
++ .endm
++
++#ifdef __ARMEB__
++#define S2LO lsl
++#define S2HI lsr
++#else
++#define S2LO lsr
++#define S2HI lsl
++#endif
++
++ /* This code requires Thumb. */
++ .thumb
++ .syntax unified
++
++/* Parameters and result. */
++#define srcin r0
++#define result r0
++
++/* Internal variables. */
++#define src r1
++#define data1a r2
++#define data1b r3
++#define const_m1 r12
++#define const_0 r4
++#define tmp1 r4 /* Overlaps const_0 */
++#define tmp2 r5
++
++def_fn strlen p2align=6
++ pld [srcin, #0]
++ strd r4, r5, [sp, #-8]!
++ bic src, srcin, #7
++ mvn const_m1, #0
++ ands tmp1, srcin, #7 /* (8 - bytes) to alignment. */
++ pld [src, #32]
++ bne.w .Lmisaligned8
++ mov const_0, #0
++ mov result, #-8
++.Lloop_aligned:
++ /* Bytes 0-7. */
++ ldrd data1a, data1b, [src]
++ pld [src, #64]
++ add result, result, #8
++.Lstart_realigned:
++ uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */
++ sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */
++ uadd8 data1b, data1b, const_m1
++ sel data1b, data1a, const_m1 /* Only used if d1a == 0. */
++ cbnz data1b, .Lnull_found
++
++ /* Bytes 8-15. */
++ ldrd data1a, data1b, [src, #8]
++ uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */
++ add result, result, #8
++ sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */
++ uadd8 data1b, data1b, const_m1
++ sel data1b, data1a, const_m1 /* Only used if d1a == 0. */
++ cbnz data1b, .Lnull_found
++
++ /* Bytes 16-23. */
++ ldrd data1a, data1b, [src, #16]
++ uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */
++ add result, result, #8
++ sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */
++ uadd8 data1b, data1b, const_m1
++ sel data1b, data1a, const_m1 /* Only used if d1a == 0. */
++ cbnz data1b, .Lnull_found
++
++ /* Bytes 24-31. */
++ ldrd data1a, data1b, [src, #24]
++ add src, src, #32
++ uadd8 data1a, data1a, const_m1 /* Saturating GE<0:3> set. */
++ add result, result, #8
++ sel data1a, const_0, const_m1 /* Select based on GE<0:3>. */
++ uadd8 data1b, data1b, const_m1
++ sel data1b, data1a, const_m1 /* Only used if d1a == 0. */
++ cmp data1b, #0
++ beq .Lloop_aligned
++
++.Lnull_found:
++ cmp data1a, #0
++ itt eq
++ addeq result, result, #4
++ moveq data1a, data1b
++#ifndef __ARMEB__
++ rev data1a, data1a
++#endif
++ clz data1a, data1a
++ ldrd r4, r5, [sp], #8
++ add result, result, data1a, lsr #3 /* Bits -> Bytes. */
++ bx lr
++
++.Lmisaligned8:
++ ldrd data1a, data1b, [src]
++ and tmp2, tmp1, #3
++ rsb result, tmp1, #0
++ lsl tmp2, tmp2, #3 /* Bytes -> bits. */
++ tst tmp1, #4
++ pld [src, #64]
++ S2HI tmp2, const_m1, tmp2
++ orn data1a, data1a, tmp2
++ itt ne
++ ornne data1b, data1b, tmp2
++ movne data1a, const_m1
++ mov const_0, #0
++ b .Lstart_realigned
++ .size strlen, . - strlen
++
diff --git a/patches/glibc-2.18/0401-add-libc_hidden_builtin_def-for-all-cortex-functions.patch b/patches/glibc-2.18/0401-add-libc_hidden_builtin_def-for-all-cortex-functions.patch
new file mode 100644
index 0000000..363ee0d
--- /dev/null
+++ b/patches/glibc-2.18/0401-add-libc_hidden_builtin_def-for-all-cortex-functions.patch
@@ -0,0 +1,64 @@
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Thu, 15 Sep 2011 23:30:25 +0200
+Subject: [PATCH] add libc_hidden_builtin_def for all cortex functions
+
+Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
+---
+ cortex-strings/sysdeps/arm/armv7/memchr.S | 3 +++
+ cortex-strings/sysdeps/arm/armv7/memcpy.S | 2 ++
+ cortex-strings/sysdeps/arm/armv7/memset.S | 2 ++
+ cortex-strings/sysdeps/arm/armv7/strchr.S | 3 +++
+ cortex-strings/sysdeps/arm/armv7/strlen.S | 1 +
+ 5 files changed, 11 insertions(+)
+
+diff --git a/cortex-strings/sysdeps/arm/armv7/memchr.S b/cortex-strings/sysdeps/arm/armv7/memchr.S
+index 92a2d9f..6e41953 100644
+--- a/cortex-strings/sysdeps/arm/armv7/memchr.S
++++ b/cortex-strings/sysdeps/arm/armv7/memchr.S
+@@ -153,3 +153,6 @@ memchr:
+ pop {r4,r5,r6,r7}
+ subs r0,r0,#1
+ bx lr
++
++strong_alias (memchr, __memchr)
++libc_hidden_builtin_def (memchr)
+diff --git a/cortex-strings/sysdeps/arm/armv7/memcpy.S b/cortex-strings/sysdeps/arm/armv7/memcpy.S
+index 3be24ca..c274207 100644
+--- a/cortex-strings/sysdeps/arm/armv7/memcpy.S
++++ b/cortex-strings/sysdeps/arm/armv7/memcpy.S
+@@ -150,3 +150,5 @@ memcpy:
+ cmp r2,#32
+ blt 10b
+ b 4b
++
++libc_hidden_builtin_def (memcpy)
+diff --git a/cortex-strings/sysdeps/arm/armv7/memset.S b/cortex-strings/sysdeps/arm/armv7/memset.S
+index 921cb75..d4c12a4 100644
+--- a/cortex-strings/sysdeps/arm/armv7/memset.S
++++ b/cortex-strings/sysdeps/arm/armv7/memset.S
+@@ -116,3 +116,5 @@ memset:
+
+ 10:
+ bx lr @ goodbye
++
++libc_hidden_builtin_def (memset)
+diff --git a/cortex-strings/sysdeps/arm/armv7/strchr.S b/cortex-strings/sysdeps/arm/armv7/strchr.S
+index 8875dbf..05c832f 100644
+--- a/cortex-strings/sysdeps/arm/armv7/strchr.S
++++ b/cortex-strings/sysdeps/arm/armv7/strchr.S
+@@ -74,3 +74,6 @@ strchr:
+ beq 5b @ A bit messy, if it's common we should branch at the start to a special loop
+ mov r0,#0
+ bx lr
++
++weak_alias (strchr, index)
++libc_hidden_builtin_def (strchr)
+diff --git a/cortex-strings/sysdeps/arm/armv7/strlen.S b/cortex-strings/sysdeps/arm/armv7/strlen.S
+index 8efa235..1445d8e 100644
+--- a/cortex-strings/sysdeps/arm/armv7/strlen.S
++++ b/cortex-strings/sysdeps/arm/armv7/strlen.S
+@@ -148,3 +148,4 @@ def_fn strlen p2align=6
+ b .Lstart_realigned
+ .size strlen, . - strlen
+
++libc_hidden_builtin_def (strlen)
diff --git a/patches/glibc-2.18/series b/patches/glibc-2.18/series
new file mode 100644
index 0000000..ba8f90c
--- /dev/null
+++ b/patches/glibc-2.18/series
@@ -0,0 +1,27 @@
+# generated by git-ptx-patches
+#tag:base --start-number 1
+#tag:upstream --start-number 1
+0001-ARM-Fix-clone-code-when-built-for-Thumb.patch
+0002-Fix-PI-mutex-check-in-pthread_cond_broadcast-and-pth.patch
+0003-ARM-Fix-memcpy-computed-jump-calculations-for-ARM_AL.patch
+0004-Accept-make-versions-4.0-and-greater.patch
+0005-Simplify-strcoll-implementation.patch
+0006-Fall-back-to-non-cached-sequence-traversal-and-compa.patch
+0007-Check-for-integer-overflow-in-cache-size-computation.patch
+0008-BZ-15754-CVE-2013-4788.patch
+0009-CVE-2013-4237-BZ-14699-Buffer-overflow-in-readdir_r.patch
+0010-malloc-Check-for-integer-overflow-in-pvalloc.patch
+0011-malloc-Check-for-integer-overflow-in-valloc.patch
+0012-malloc-Check-for-integer-overflow-in-memalign.patch
+0013-Fix-stack-overflow-due-to-large-AF_INET6-requests.patch
+#tag:build-system --start-number 100
+0100-add-install-lib-all-target.patch
+0101-don-t-regen-docs-if-perl-is-not-found.patch
+#tag:debian --start-number 200
+0200-Fix-localedef-segfault-when-run-under-exec-shield-Pa.patch
+#tag:gentoo --start-number 300
+0300-resolv-dynamic.patch
+#tag:linaro --start-number 400
+0400-optimized-string-functions-for-NEON-from-Linaro.patch
+0401-add-libc_hidden_builtin_def-for-all-cortex-functions.patch
+# c7c37d04f6d7c2fc5e7140d9570db200 - git-ptx-patches magic
diff --git a/patches/m4-1.4.18/0001-fflush-adjust-to-glibc-2.28-libio.h-removal.patch b/patches/m4-1.4.18/0001-fflush-adjust-to-glibc-2.28-libio.h-removal.patch
new file mode 100644
index 0000000..00b99fd
--- /dev/null
+++ b/patches/m4-1.4.18/0001-fflush-adjust-to-glibc-2.28-libio.h-removal.patch
@@ -0,0 +1,159 @@
+From: Paul Eggert <eggert@cs.ucla.edu>
+Date: Thu, 8 Mar 2018 16:42:45 2018 -0800
+Subject: [PATCH] fflush: adjust to glibc 2.28 libio.h removal
+
+Problem reported by Daniel P. Berrangé in:
+https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html
+* lib/fbufmode.c (fbufmode):
+* lib/fflush.c (clear_ungetc_buffer_preserving_position)
+(disable_seek_optimization, rpl_fflush):
+* lib/fpending.c (__fpending):
+* lib/fpurge.c (fpurge):
+* lib/freadable.c (freadable):
+* lib/freadahead.c (freadahead):
+* lib/freading.c (freading):
+* lib/freadptr.c (freadptr):
+* lib/freadseek.c (freadptrinc):
+* lib/fseeko.c (fseeko):
+* lib/fseterr.c (fseterr):
+* lib/fwritable.c (fwritable):
+* lib/fwriting.c (fwriting):
+Check _IO_EOF_SEEN instead of _IO_ftrylockfile.
+* lib/stdio-impl.h (_IO_IN_BACKUP) [_IO_EOF_SEEN]:
+Define if not already defined.
+
+manual backport of of4af4a4a71827c0bc5e0ec67af23edef4f15cee8e
+
+Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
+---
+ lib/fflush.c | 6 +++---
+ lib/fpending.c | 2 +-
+ lib/fpurge.c | 2 +-
+ lib/freadahead.c | 2 +-
+ lib/freading.c | 2 +-
+ lib/fseeko.c | 4 ++--
+ lib/stdio-impl.h | 6 ++++++
+ 7 files changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/lib/fflush.c b/lib/fflush.c
+index ef2a7f1237ee..787790d09031 100644
+--- a/lib/fflush.c
++++ b/lib/fflush.c
+@@ -33,7 +33,7 @@
+ #undef fflush
+
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+
+ /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */
+ static void
+@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp)
+
+ #endif
+
+-#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
++#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
+
+ # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT
+ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
+@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream)
+ if (stream == NULL || ! freading (stream))
+ return fflush (stream);
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+
+ clear_ungetc_buffer_preserving_position (stream);
+
+diff --git a/lib/fpending.c b/lib/fpending.c
+index ce93604e518f..9fe7ffb2f615 100644
+--- a/lib/fpending.c
++++ b/lib/fpending.c
+@@ -32,7 +32,7 @@ __fpending (FILE *fp)
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ return fp->_IO_write_ptr - fp->_IO_write_base;
+ #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
+ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
+diff --git a/lib/fpurge.c b/lib/fpurge.c
+index 53ee68c37efc..7cba3a37bef2 100644
+--- a/lib/fpurge.c
++++ b/lib/fpurge.c
+@@ -62,7 +62,7 @@ fpurge (FILE *fp)
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ fp->_IO_read_end = fp->_IO_read_ptr;
+ fp->_IO_write_ptr = fp->_IO_write_base;
+ /* Avoid memory leak when there is an active ungetc buffer. */
+diff --git a/lib/freadahead.c b/lib/freadahead.c
+index cfc969b4cffd..5e43e13af727 100644
+--- a/lib/freadahead.c
++++ b/lib/freadahead.c
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ if (fp->_IO_write_ptr > fp->_IO_write_base)
+ return 0;
+ return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff --git a/lib/freading.c b/lib/freading.c
+index 05cb0b80999d..f1da5b958b5e 100644
+--- a/lib/freading.c
++++ b/lib/freading.c
+@@ -31,7 +31,7 @@ freading (FILE *fp)
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ return ((fp->_flags & _IO_NO_WRITES) != 0
+ || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
+ && fp->_IO_read_base != NULL));
+diff --git a/lib/fseeko.c b/lib/fseeko.c
+index 0c01c4fd08c1..0601619d80a2 100644
+--- a/lib/fseeko.c
++++ b/lib/fseeko.c
+@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int whence)
+ #endif
+
+ /* These tests are based on fpurge.c. */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ if (fp->_IO_read_end == fp->_IO_read_ptr
+ && fp->_IO_write_ptr == fp->_IO_write_base
+ && fp->_IO_save_base == NULL)
+@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int whence)
+ return -1;
+ }
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ fp->_flags &= ~_IO_EOF_SEEN;
+ fp->_offset = pos;
+ #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
+diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h
+index 766d6936590f..75fe3ade4237 100644
+--- a/lib/stdio-impl.h
++++ b/lib/stdio-impl.h
+@@ -18,6 +18,12 @@
+ the same implementation of stdio extension API, except that some fields
+ have different naming conventions, or their access requires some casts. */
+
++/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this
++ problem by defining it ourselves. FIXME: Do not rely on glibc
++ internals. */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+
+ /* BSD stdio derived implementations. */
+
diff --git a/patches/m4-1.4.18/series b/patches/m4-1.4.18/series
new file mode 100644
index 0000000..c9993f0
--- /dev/null
+++ b/patches/m4-1.4.18/series
@@ -0,0 +1,4 @@
+# generated by git-ptx-patches
+#tag:base --start-number 1
+0001-fflush-adjust-to-glibc-2.28-libio.h-removal.patch
+# b03bed9248af170f04892265a5918d5b - git-ptx-patches magic
diff --git a/ptxconfigs/powerpc-603e-linux-gnu-gcc-5.4.0-glibc-2.18-binutils-2.24-kernel-2.6.29.6-sanitized.ptxconfig b/ptxconfigs/powerpc-603e-linux-gnu-gcc-5.4.0-glibc-2.18-binutils-2.24-kernel-2.6.29.6-sanitized.ptxconfig
new file mode 100644
index 0000000..9f4f36b
--- /dev/null
+++ b/ptxconfigs/powerpc-603e-linux-gnu-gcc-5.4.0-glibc-2.18-binutils-2.24-kernel-2.6.29.6-sanitized.ptxconfig
@@ -0,0 +1,142 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# PTXdist 2016.06.1
+#
+PTXCONF__ptxconfig_MAGIC__=y
+PTXCONF_BUILD_TOOLCHAIN=y
+PTXCONF_NO_PLATFORM=y
+PTXCONF_PROJECT="OSELAS.Toolchain-2016.06.1"
+
+#
+# ----------------------------------
+#
+# PTXCONF_ARCH_ARM is not set
+# PTXCONF_ARCH_ARM64 is not set
+# PTXCONF_ARCH_M68K is not set
+# PTXCONF_ARCH_MIPS is not set
+PTXCONF_ARCH_POWERPC=y
+# PTXCONF_ARCH_I386 is not set
+# PTXCONF_ARCH_X86_64 is not set
+# PTXCONF_ARCH_AVR is not set
+# PTXCONF_ARCH_AVR32 is not set
+PTXCONF_ARCH="powerpc"
+PTXCONF_GNU_TARGET="powerpc-603e-linux-gnu"
+PTXCONF_SIZEOF_LONG_DOUBLE="8"
+
+#
+# ----------------------------------
+#
+PTXCONF_LIBC_HEADERS=y
+PTXCONF_LIBC_FIRST=y
+PTXCONF_LIBC=y
+PTXCONF_LIBC_GLIBC=y
+# PTXCONF_LIBC_UCLIBC is not set
+# PTXCONF_LIBC_NEWLIB is not set
+# PTXCONF_LIBC_MINGW is not set
+# PTXCONF_LIBC_AVR is not set
+PTXCONF_GLIBC_HEADERS=y
+PTXCONF_GLIBC_CRT=y
+PTXCONF_GLIBC_FIRST=y
+PTXCONF_GLIBC=y
+PTXCONF_GLIBC_VERSION="2.18"
+PTXCONF_GLIBC_MD5="e67f791383077c5f6a6e91fabc7579a5"
+PTXCONF_GLIBC_LICENSE="GPL-2.0+ AND LGPL-2.1+"
+PTXCONF_GLIBC_LICENSE_FILES="file://COPYING;md5=393a5ca445f6965873eca0259a17f833 file://COPYING.LIB;md5=bbb461211a33b134d42ed5ee802b37ff file://LICENSES;md5=e9a558e243b36d3209f380deb394b213"
+PTXCONF_GLIBC_TIMESTAMP=""
+PTXCONF_GLIBC_SERIES=""
+PTXCONF_GLIBC_ENABLE_KERNEL="2.6.29"
+PTXCONF_GLIBC_CONFIG_EXTRA=""
+PTXCONF_GLIBC_CONFIG_EXTRA_CROSS="--enable-obsolete-rpc --enable-stackguard-randomization --enable-lock-elision"
+PTXCONF_GLIBC_HEADERS_FAKE_CROSS=""
+PTXCONF_GLIBC_TLS=y
+PTXCONF_GLIBC_EXTRA_ADDONS="ports nptl"
+PTXCONF_CROSS_BINUTILS=y
+PTXCONF_CROSS_BINUTILS_VERSION="2.24"
+PTXCONF_CROSS_BINUTILS_MD5="e0f71a7b2ddab0f8612336ac81d9636b"
+PTXCONF_CROSS_BINUTILS_LICENSE="GPL-2.0+ AND LGPL-2.0+ GPL-3.0+ AND LGPL-3.0+"
+PTXCONF_CROSS_BINUTILS_LICENSE_FILES="file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 file://COPYING.LIB;md5=9f604d8a4f8e74f4f5140845a21b6674 file://COPYING3;md5=d32239bcb673463ab874e80d47fae504 file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6"
+# PTXCONF_CROSS_ELF2FLT is not set
+PTXCONF_KERNEL_HEADERS=y
+PTXCONF_KERNEL_HEADERS_VERSION="2.6.29.6"
+PTXCONF_KERNEL_HEADERS_MD5="07374d09c9783b482994977567cf1f5f"
+PTXCONF_KERNEL_HEADERS_SANITIZED=y
+PTXCONF_CROSS_GCC=y
+PTXCONF_CROSS_GCC_VERSION="5.4.0"
+PTXCONF_CROSS_GCC_MD5="4c626ac2a83ef30dfb9260e6f59c2b30"
+PTXCONF_CROSS_GCC_DL_VERSION="${PTXCONF_CROSS_GCC_VERSION}"
+PTXCONF_CROSS_GCC_PKGVERSION="${PTXCONF_PROJECT}"
+PTXCONF_CROSS_GCC_43=y
+PTXCONF_CROSS_GCC_45=y
+PTXCONF_CROSS_GCC_48=y
+PTXCONF_CROSS_GCC_50=y
+PTXCONF_CROSS_GCC_SERIES=""
+PTXCONF_CROSS_GCC_CONFIG_EXTRA="--with-cpu=603e --disable-altivec"
+PTXCONF_CROSS_GCC_LICENSE="GPL-2.0+ WITH Classpath-exception-2.0 AND LGPL-2.1+ AND GPL-3.0+ AND GPL-3.0+ WITH GCC-exception-3.1 AND LGPL-3.0+"
+PTXCONF_CROSS_GCC_LICENSE_FILES="file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1 file://COPYING.RUNTIME;md5=fe60d87048567d4fe8c8a0ed2448bcc8 file://COPYING3;md5=d32239bcb673463ab874e80d47fae504 file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6"
+PTXCONF_CROSS_GCC_GCCLIBS_LICENSE="GPL-3.0 WITH GCC-exception-3.1"
+PTXCONF_CROSS_GCC_GCCLIBS_LICENSES="COPYING3 COPYING.RUNTIME"
+
+#
+# Additional supported languages:
+#
+PTXCONF_CROSS_GCC_LANG_C=y
+PTXCONF_CROSS_GCC_LANG_CXX=y
+# PTXCONF_CROSS_GCC_LANG_FORTRAN is not set
+# PTXCONF_CROSS_GCC_LANG_JAVA is not set
+PTXCONF_CROSS_GCC_ENABLE_CXA_ATEXIT=y
+PTXCONF_CROSS_GCC_CONFIG_CXA_ATEXIT="--enable-__cxa_atexit"
+PTXCONF_CROSS_GCC_DISABLE_SJLJ_EXCEPTIONS=y
+PTXCONF_CROSS_GCC_CONFIG_SJLJ_EXCEPTIONS="--disable-sjlj-exceptions"
+PTXCONF_CROSS_GCC_DISABLE_LIBSSP=y
+PTXCONF_CROSS_GCC_CONFIG_LIBSSP="--disable-libssp"
+PTXCONF_CROSS_GCC_ENABLE_SHARED=y
+PTXCONF_CROSS_GCC_CONFIG_SHARED="--enable-shared"
+PTXCONF_CROSS_GCC_THREADS_POSIX=y
+PTXCONF_CROSS_GCC_THREADS="posix"
+PTXCONF_CROSS_GCC_FIRST=y
+PTXCONF_CROSS_GDB=y
+PTXCONF_CROSS_GDB_VERSION="7.11"
+PTXCONF_CROSS_GDB_MD5="b5c784685e1cde65ba135feea86b6d75"
+PTXCONF_CROSS_GDB_LICENSE="GPL-2.0+ AND LGPL-2.0+ GPL-3.0+ AND LGPL-3.0+"
+PTXCONF_CROSS_GDB_LICENSE_FILES="file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 file://COPYING.LIB;md5=9f604d8a4f8e74f4f5140845a21b6674 file://COPYING3;md5=d32239bcb673463ab874e80d47fae504 file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6"
+PTXCONF_CROSS_TOOLCHAIN=y
+PTXCONF_HOST_FAKE_MAKEINFO=y
+PTXCONF_HOST_EXPAT=y
+PTXCONF_HOST_GMP=y
+PTXCONF_HOST_ISL=y
+PTXCONF_HOST_MPC=y
+PTXCONF_HOST_MPFR=y
+PTXCONF_HOST_XZ=y
+PTXCONF_HOST_ZLIB=y
+PTXCONF_HOST_LIBELF=y
+PTXCONF_HOST_AUTOTOOLS_AUTOCONF=y
+PTXCONF_HOST_CHRPATH=y
+PTXCONF_HOST_M4=y
+PTXCONF_HOST_SYSTEM_PERL=y
+
+#
+# ----------------------------------
+#
+PTXCONF_TOOLCHAIN_ENABLE_SYSROOT=y
+PTXCONF_TOOLCHAIN_CONFIG_SYSROOT="--with-build-sysroot=${SYSROOT} --with-sysroot=${PTXCONF_PREFIX_TARGET}"
+PTXCONF_TOOLCHAIN_DISABLE_MULTILIB=y
+PTXCONF_TOOLCHAIN_CONFIG_MULTILIB="--disable-multilib"
+
+#
+# misc
+#
+PTXCONF_DESTDIR="${PTX_AUTOBUILD_DESTDIR}"
+PTXCONF_PREFIX="/opt"
+PTXCONF_PREFIX_KERNEL="-sanitized"
+PTXCONF_PREFIX_TCID="gcc-${PTXCONF_CROSS_GCC_VERSION}${PTXCONF_PREFIX_JAVA}-glibc-${PTXCONF_GLIBC_VERSION}-binutils-${PTXCONF_CROSS_BINUTILS_VERSION}-kernel-${PTXCONF_KERNEL_HEADERS_VERSION}${PTXCONF_PREFIX_KERNEL}"
+PTXCONF_SYSROOT_HOST="${PTXDIST_PLATFORMDIR}/sysroot-host"
+PTXCONF_PREFIX_CROSS="${PTXCONF_PREFIX}/${PTXCONF_PROJECT}/${PTXCONF_GNU_TARGET}/${PTXCONF_PREFIX_TCID}"
+PTXCONF_SYSROOT_CROSS="${PTXCONF_DESTDIR}${PTXCONF_PREFIX_CROSS}"
+PTXCONF_PREFIX_TARGET="${PTXCONF_PREFIX_CROSS}/sysroot-${PTXCONF_GNU_TARGET}"
+PTXCONF_SYSROOT_TARGET="${PTXCONF_DESTDIR}${PTXCONF_PREFIX_TARGET}"
+PTXCONF_PLATFORM="${PTXCONF_GNU_TARGET}-${PTXCONF_PREFIX_TCID}"
+PTXCONF_COMPILER_PREFIX="${PTXCONF_GNU_TARGET}-"
+# PTXCONF_TOOLCHAIN_DEBUG is not set
+PTXCONF_IMAGE_TOOLCHAIN_TGZ=y
+PTXCONF_IMAGE_TOOLCHAIN_DEB=y
+PTXCONF_CONFIGFILE_VERSION="2016.06.1"
diff --git a/rules/host-m4.make b/rules/host-m4.make
new file mode 100644
index 0000000..9264fe5
--- /dev/null
+++ b/rules/host-m4.make
@@ -0,0 +1,46 @@
+# -*-makefile-*-
+#
+# Copyright (C) 2014 by Juergen Beisert <jbe@pengutronix.de>
+#
+# For further information about the PTXdist project and license conditions
+# see the README file.
+#
+
+#
+# We provide this package
+#
+HOST_PACKAGES-$(PTXCONF_HOST_M4) += host-m4
+
+#
+# Paths and names
+#
+HOST_M4_VERSION := 1.4.18
+HOST_M4_MD5 := 730bb15d96fffe47e148d1e09235af82
+HOST_M4 := m4-$(HOST_M4_VERSION)
+HOST_M4_SUFFIX := tar.xz
+HOST_M4_URL := http://ftp.gnu.org/gnu/m4/$(HOST_M4).$(HOST_M4_SUFFIX)
+HOST_M4_SOURCE := $(SRCDIR)/$(HOST_M4).$(HOST_M4_SUFFIX)
+HOST_M4_DIR := $(HOST_BUILDDIR)/$(HOST_M4)
+HOST_M4_LICENSE := GPL-3.0-only
+
+# ----------------------------------------------------------------------------
+# Prepare
+# ----------------------------------------------------------------------------
+
+#
+# autoconf
+#
+HOST_M4_CONF_TOOL := autoconf
+HOST_M4_CONF_OPT := \
+ $(HOST_AUTOCONF) \
+ --enable-threads=posix \
+ --disable-gcc-warnings \
+ --enable-assert \
+ --disable-rpath \
+ --disable-c++ \
+ --disable-changeword \
+ --without-included-regex \
+ --with-syscmd-shell=/bin/sh \
+ --without-dmalloc
+
+# vim: syntax=make
diff --git a/scripts/make_deb.sh b/scripts/make_deb.sh
index 2601b54..f749d37 100755
--- a/scripts/make_deb.sh
+++ b/scripts/make_deb.sh
@@ -17,11 +17,11 @@ main() {
local ifs_orig="${IFS}"
IFS="_"
- set -- ${deb}
+ set -- ${deb##*/}
IFS="${ifs_orig}"
- local package="${1##*/}"
- local inst="${1%${package}}"
+ local package="${1}"
+ local inst="${deb%${package}}"
local version="${2}"
local arch="${3%%.deb}"