summary refs log tree commit diff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2015-01-16 13:27:03 +0100
committerLudovic Courtès <ludo@gnu.org>2015-01-16 13:27:03 +0100
commit57b7e1a62d2269bfd9d37f88bae92c829222f8fc (patch)
tree5e6395e08025eb80de2040d77ac6febb558d2a72 /gnu/packages/patches
parent72b703cdcaec260733a4e30800cef5eab3f071a6 (diff)
parentb01a0ba86e93012044f42c41ba5cbc7d7936c356 (diff)
downloadguix-57b7e1a62d2269bfd9d37f88bae92c829222f8fc.tar.gz
Merge branch 'core-updates'
Conflicts:
	gnu/packages/bootstrap.scm
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r--gnu/packages/patches/curl-gss-api-fix.patch38
-rw-r--r--gnu/packages/patches/file-CVE-2014-3587.patch16
-rw-r--r--gnu/packages/patches/gcc-fix-pr61801.patch25
-rw-r--r--gnu/packages/patches/gd-mips64-deplibs-fix.patch17
-rw-r--r--gnu/packages/patches/glibc-CVE-2012-3406.patch282
-rw-r--r--gnu/packages/patches/glibc-CVE-2014-7817.patch171
-rw-r--r--gnu/packages/patches/glibc-mips-dangling-vfork-ref.patch45
-rw-r--r--gnu/packages/patches/gmp-arm-asm-nothumb.patch21
-rw-r--r--gnu/packages/patches/guile-arm-fixes.patch203
-rw-r--r--gnu/packages/patches/libtool-2.4-skip-tests.patch24
-rw-r--r--gnu/packages/patches/libtool-skip-tests-for-mips.patch12
-rw-r--r--gnu/packages/patches/libtool-skip-tests.patch82
-rw-r--r--gnu/packages/patches/m4-readlink-EINVAL.patch18
-rw-r--r--gnu/packages/patches/patchelf-page-size.patch33
-rw-r--r--gnu/packages/patches/patchelf-rework-for-arm.patch473
-rw-r--r--gnu/packages/patches/sqlite-large-page-size-fix.patch180
16 files changed, 1300 insertions, 340 deletions
diff --git a/gnu/packages/patches/curl-gss-api-fix.patch b/gnu/packages/patches/curl-gss-api-fix.patch
new file mode 100644
index 0000000000..ea838ae8c7
--- /dev/null
+++ b/gnu/packages/patches/curl-gss-api-fix.patch
@@ -0,0 +1,38 @@
+Copied from upstream:
+https://github.com/bagder/curl/commit/5c0e66d63214e0306197c5a3f162441e074f3401.patch
+
+From 5c0e66d63214e0306197c5a3f162441e074f3401 Mon Sep 17 00:00:00 2001
+From: Steve Holme <steve_holme@hotmail.com>
+Date: Thu, 8 Jan 2015 19:23:53 +0000
+Subject: [PATCH] sasl_gssapi: Fixed build on NetBSD with built-in GSS-API
+
+Bug: http://curl.haxx.se/bug/view.cgi?id=1469
+Reported-by: Thomas Klausner
+---
+ lib/curl_sasl_gssapi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/curl_sasl_gssapi.c b/lib/curl_sasl_gssapi.c
+index 6dda0e9..a50646a 100644
+--- a/lib/curl_sasl_gssapi.c
++++ b/lib/curl_sasl_gssapi.c
+@@ -6,6 +6,7 @@
+  *                             \___|\___/|_| \_\_____|
+  *
+  * Copyright (C) 2014, Steve Holme, <steve_holme@hotmail.com>.
++ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+  *
+  * This software is licensed as described in the file COPYING, which
+  * you should have received as part of this distribution. The terms
+@@ -126,7 +127,7 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
+ 
+     /* Import the SPN */
+     gss_major_status = gss_import_name(&gss_minor_status, &spn_token,
+-                                       gss_nt_service_name, &krb5->spn);
++                                       GSS_C_NT_HOSTBASED_SERVICE, &krb5->spn);
+     if(GSS_ERROR(gss_major_status)) {
+       Curl_gss_log_error(data, gss_minor_status, "gss_import_name() failed: ");
+ 
+-- 
+2.2.1
+
diff --git a/gnu/packages/patches/file-CVE-2014-3587.patch b/gnu/packages/patches/file-CVE-2014-3587.patch
deleted file mode 100644
index cf88bf5f3e..0000000000
--- a/gnu/packages/patches/file-CVE-2014-3587.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Fixes CVE-2014-3587.  Copied from upstream commit
-0641e56be1af003aa02c7c6b0184466540637233.
-
---- file-5.19/src/cdf.c.orig	2014-06-09 09:04:37.000000000 -0400
-+++ file-5.19/src/cdf.c	2014-08-26 11:55:23.887118898 -0400
-@@ -824,6 +824,10 @@
- 		q = (const uint8_t *)(const void *)
- 		    ((const char *)(const void *)p + ofs
- 		    - 2 * sizeof(uint32_t));
-+		if (q < p) {
-+			DPRINTF(("Wrapped around %p < %p\n", q, p));
-+			goto out;
-+		}
- 		if (q > e) {
- 			DPRINTF(("Ran of the end %p > %p\n", q, e));
- 			goto out;
diff --git a/gnu/packages/patches/gcc-fix-pr61801.patch b/gnu/packages/patches/gcc-fix-pr61801.patch
deleted file mode 100644
index e9cd92aa1c..0000000000
--- a/gnu/packages/patches/gcc-fix-pr61801.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-GCC bug fix for <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61801>.
-Initially discussed at
- <http://lists.gnu.org/archive/html/guix-devel/2014-09/msg00283.html>.
-Patch from <https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=212740>.
-
-2014-07-17  Richard Biener  <rguenther@suse.de>
-
-        PR rtl-optimization/61801
-
-        * sched-deps.c (sched_analyze_2): For ASM_OPERANDS and
-        ASM_INPUT don't set reg_pending_barrier if it appears in a
-        debug-insn.
-
---- gcc-4_8-branch/gcc/sched-deps.c	2014/07/17 07:48:49	212739
-+++ gcc-4_8-branch/gcc/sched-deps.c	2014/07/17 07:49:44	212740
-@@ -2744,7 +2744,8 @@
- 	   Consider for instance a volatile asm that changes the fpu rounding
- 	   mode.  An insn should not be moved across this even if it only uses
- 	   pseudo-regs because it might give an incorrectly rounded result.  */
--	if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
-+	if ((code != ASM_OPERANDS || MEM_VOLATILE_P (x))
-+	    && !DEBUG_INSN_P (insn))
- 	  reg_pending_barrier = TRUE_BARRIER;
- 
- 	/* For all ASM_OPERANDS, we must traverse the vector of input operands.
diff --git a/gnu/packages/patches/gd-mips64-deplibs-fix.patch b/gnu/packages/patches/gd-mips64-deplibs-fix.patch
deleted file mode 100644
index 6231310cdb..0000000000
--- a/gnu/packages/patches/gd-mips64-deplibs-fix.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Patch configure script to choose pass_all deplibs check method for
-linux-gnu* systems on mips64.  This is a temporary hack until libgd
-bootstraps their build system with a newer libtool.
-
-Patch by Mark H Weaver <mhw@netris.org>.
-
---- libgd-gd/src/configure.orig	2006-04-05 11:56:57.000000000 -0400
-+++ libgd-gd/src/configure	2013-11-02 17:56:19.123995838 -0400
-@@ -4457,7 +4457,7 @@
- # This must be Linux ELF.
- linux-gnu*)
-   case $host_cpu in
--  alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64* | s390* | x86_64*)
-+  alpha* | hppa* | i*86 | mips | mipsel | mips64 | mips64el | powerpc* | sparc* | ia64* | s390* | x86_64*)
-     lt_cv_deplibs_check_method=pass_all ;;
-   *)
-     # glibc up to 2.1.1 does not perform some relocations on ARM
diff --git a/gnu/packages/patches/glibc-CVE-2012-3406.patch b/gnu/packages/patches/glibc-CVE-2012-3406.patch
new file mode 100644
index 0000000000..9147a2aeee
--- /dev/null
+++ b/gnu/packages/patches/glibc-CVE-2012-3406.patch
@@ -0,0 +1,282 @@
+Fix CVE-2012-3406: Stack overflow in vfprintf [BZ #16617]
+
+Note: Here the ChangeLog and NEWS updates are removed from Jeff's
+      patch, since they depend on other earlier commits.
+
+From: Jeff Law <law@redhat.com>
+Date: Mon, 15 Dec 2014 09:09:32 +0000 (+0100)
+Subject: CVE-2012-3406: Stack overflow in vfprintf [BZ #16617]
+X-Git-Url: https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff_plain;h=a3a1f4163c4d0f9a36056c8640661a88674ae8a2
+
+CVE-2012-3406: Stack overflow in vfprintf [BZ #16617]
+
+A larger number of format specifiers coudld cause a stack overflow,
+potentially allowing to bypass _FORTIFY_SOURCE format string
+protection.
+
+(cherry picked from commit a5357b7ce2a2982c5778435704bcdb55ce3667a0)
+(cherry picked from commit ae61fc7b33d9d99d2763c16de8275227dc9748ba)
+
+Conflicts:
+	NEWS
+---
+
+diff --git a/stdio-common/Makefile b/stdio-common/Makefile
+index 5f8e534..e5e45b6 100644
+--- a/stdio-common/Makefile
++++ b/stdio-common/Makefile
+@@ -57,7 +57,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
+ 	 bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
+ 	 scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
+ 	 bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
+-	 bug25 tst-printf-round bug26
++	 bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26
+ 
+ test-srcs = tst-unbputc tst-printf
+ 
+diff --git a/stdio-common/bug23-2.c b/stdio-common/bug23-2.c
+new file mode 100644
+index 0000000..9e0cfe6
+--- /dev/null
++++ b/stdio-common/bug23-2.c
+@@ -0,0 +1,70 @@
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++
++static const char expected[] = "\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
++
++static int
++do_test (void)
++{
++  char *buf = malloc (strlen (expected) + 1);
++  snprintf (buf, strlen (expected) + 1,
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n",
++	    "a", "b", "c", "d", 5);
++  return strcmp (buf, expected) != 0;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff --git a/stdio-common/bug23-3.c b/stdio-common/bug23-3.c
+new file mode 100644
+index 0000000..57c8cef
+--- /dev/null
++++ b/stdio-common/bug23-3.c
+@@ -0,0 +1,50 @@
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++
++int
++do_test (void)
++{
++  size_t instances = 16384;
++#define X0 "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++  const char *item = "\na\nabbcd55";
++#define X3 X0 X0 X0 X0 X0 X0 X0 X0
++#define X6 X3 X3 X3 X3 X3 X3 X3 X3
++#define X9 X6 X6 X6 X6 X6 X6 X6 X6
++#define X12 X9 X9 X9 X9 X9 X9 X9 X9
++#define X14 X12 X12 X12 X12
++#define TRAILER "%%%%%%%%%%%%%%%%%%%%%%%%%%"
++#define TRAILER2 TRAILER TRAILER
++  size_t length = instances * strlen (item) + strlen (TRAILER) + 1;
++
++  char *buf = malloc (length + 1);
++  snprintf (buf, length + 1,
++	    X14 TRAILER2 "\n",
++	    "a", "b", "c", "d", 5);
++
++  const char *p = buf;
++  size_t i;
++  for (i = 0; i < instances; ++i)
++    {
++      const char *expected;
++      for (expected = item; *expected; ++expected)
++	{
++	  if (*p != *expected)
++	    {
++	      printf ("mismatch at offset %zu (%zu): expected %d, got %d\n",
++		      (size_t) (p - buf), i, *expected & 0xFF, *p & 0xFF);
++	      return 1;
++	    }
++	  ++p;
++	}
++    }
++  if (strcmp (p, TRAILER "\n") != 0)
++    {
++      printf ("mismatch at trailer: [%s]\n", p);
++      return 1;
++    }
++  free (buf);
++  return 0;
++}
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff --git a/stdio-common/bug23-4.c b/stdio-common/bug23-4.c
+new file mode 100644
+index 0000000..a478564
+--- /dev/null
++++ b/stdio-common/bug23-4.c
+@@ -0,0 +1,31 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/resource.h>
++
++#define LIMIT 1000000
++
++int
++main (void)
++{
++  struct rlimit lim;
++  getrlimit (RLIMIT_STACK, &lim);
++  lim.rlim_cur = 1048576;
++  setrlimit (RLIMIT_STACK, &lim);
++  char *fmtstr = malloc (4 * LIMIT + 1);
++  if (fmtstr == NULL)
++    abort ();
++  char *output = malloc (LIMIT + 1);
++  if (output == NULL)
++    abort ();
++  for (size_t i = 0; i < LIMIT; i++)
++    memcpy (fmtstr + 4 * i, "%1$d", 4);
++  fmtstr[4 * LIMIT] = '\0';
++  int ret = snprintf (output, LIMIT + 1, fmtstr, 0);
++  if (ret != LIMIT)
++    abort ();
++  for (size_t i = 0; i < LIMIT; i++)
++    if (output[i] != '0')
++      abort ();
++  return 0;
++}
+diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
+index c4ff833..429a3d1 100644
+--- a/stdio-common/vfprintf.c
++++ b/stdio-common/vfprintf.c
+@@ -263,6 +263,12 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
+   /* For the argument descriptions, which may be allocated on the heap.  */
+   void *args_malloced = NULL;
+ 
++  /* For positional argument handling.  */
++  struct printf_spec *specs;
++
++  /* Track if we malloced the SPECS array and thus must free it.  */
++  bool specs_malloced = false;
++
+   /* This table maps a character into a number representing a
+      class.  In each step there is a destination label for each
+      class.  */
+@@ -1679,8 +1685,8 @@ do_positional:
+     size_t nspecs = 0;
+     /* A more or less arbitrary start value.  */
+     size_t nspecs_size = 32 * sizeof (struct printf_spec);
+-    struct printf_spec *specs = alloca (nspecs_size);
+ 
++    specs = alloca (nspecs_size);
+     /* The number of arguments the format string requests.  This will
+        determine the size of the array needed to store the argument
+        attributes.  */
+@@ -1721,11 +1727,39 @@ do_positional:
+ 	if (nspecs * sizeof (*specs) >= nspecs_size)
+ 	  {
+ 	    /* Extend the array of format specifiers.  */
++	    if (nspecs_size * 2 < nspecs_size)
++	      {
++		__set_errno (ENOMEM);
++		done = -1;
++		goto all_done;
++	      }
+ 	    struct printf_spec *old = specs;
+-	    specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
++	    if (__libc_use_alloca (2 * nspecs_size))
++	      specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
++	    else
++	      {
++		nspecs_size *= 2;
++		specs = malloc (nspecs_size);
++		if (specs == NULL)
++		  {
++		    __set_errno (ENOMEM);
++		    specs = old;
++		    done = -1;
++		    goto all_done;
++		  }
++	      }
+ 
+ 	    /* Copy the old array's elements to the new space.  */
+ 	    memmove (specs, old, nspecs * sizeof (*specs));
++
++	    /* If we had previously malloc'd space for SPECS, then
++	       release it after the copy is complete.  */
++	    if (specs_malloced)
++	      free (old);
++
++	    /* Now set SPECS_MALLOCED if needed.  */
++	    if (!__libc_use_alloca (nspecs_size))
++	      specs_malloced = true;
+ 	  }
+ 
+ 	/* Parse the format specifier.  */
+@@ -2046,6 +2080,8 @@ do_positional:
+   }
+ 
+ all_done:
++  if (specs_malloced)
++    free (specs);
+   if (__glibc_unlikely (args_malloced != NULL))
+     free (args_malloced);
+   if (__glibc_unlikely (workstart != NULL))
diff --git a/gnu/packages/patches/glibc-CVE-2014-7817.patch b/gnu/packages/patches/glibc-CVE-2014-7817.patch
new file mode 100644
index 0000000000..14c885523c
--- /dev/null
+++ b/gnu/packages/patches/glibc-CVE-2014-7817.patch
@@ -0,0 +1,171 @@
+Fix CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
+
+Note: Here the ChangeLog and NEWS updates are removed from Carlos's
+      patch, since they depend on other earlier commits.
+
+From: Carlos O'Donell <carlos@redhat.com>
+Date: Wed, 19 Nov 2014 16:44:12 +0000 (-0500)
+Subject: CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
+X-Git-Url: https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff_plain;h=33ceaf6187b31ea15284ac65131749e1cb68d2ae
+
+CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
+
+The function wordexp() fails to properly handle the WRDE_NOCMD
+flag when processing arithmetic inputs in the form of "$((... ``))"
+where "..." can be anything valid. The backticks in the arithmetic
+epxression are evaluated by in a shell even if WRDE_NOCMD forbade
+command substitution. This allows an attacker to attempt to pass
+dangerous commands via constructs of the above form, and bypass
+the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD
+in exec_comm(), the only place that can execute a shell. All other
+checks for WRDE_NOCMD are superfluous and removed.
+
+We expand the testsuite and add 3 new regression tests of roughly
+the same form but with a couple of nested levels.
+
+On top of the 3 new tests we add fork validation to the WRDE_NOCMD
+testing. If any forks are detected during the execution of a wordexp()
+call with WRDE_NOCMD, the test is marked as failed. This is slightly
+heuristic since vfork might be used in the future, but it provides a
+higher level of assurance that no shells were executed as part of
+command substitution with WRDE_NOCMD in effect. In addition it doesn't
+require libpthread or libdl, instead we use the public implementation
+namespace function __register_atfork (already part of the public ABI
+for libpthread).
+
+Tested on x86_64 with no regressions.
+
+(cherry picked from commit a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c)
+---
+
+diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
+index 4957006..bdd65e4 100644
+--- a/posix/wordexp-test.c
++++ b/posix/wordexp-test.c
+@@ -27,6 +27,25 @@
+ 
+ #define IFS " \n\t"
+ 
++extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
++extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
++
++static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
++{
++  return __register_atfork (prepare, parent, child,
++			    &__dso_handle == NULL ? NULL : __dso_handle);
++}
++
++/* Number of forks seen.  */
++static int registered_forks;
++
++/* For each fork increment the fork count.  */
++static void
++register_fork (void)
++{
++  registered_forks++;
++}
++
+ struct test_case_struct
+ {
+   int retval;
+@@ -206,6 +225,12 @@ struct test_case_struct
+     { WRDE_SYNTAX, NULL, "$((2+))", 0, 0, { NULL, }, IFS },
+     { WRDE_SYNTAX, NULL, "`", 0, 0, { NULL, }, IFS },
+     { WRDE_SYNTAX, NULL, "$((010+4+))", 0, 0, { NULL }, IFS },
++    /* Test for CVE-2014-7817. We test 3 combinations of command
++       substitution inside an arithmetic expression to make sure that
++       no commands are executed and error is returned.  */
++    { WRDE_CMDSUB, NULL, "$((`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
++    { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
++    { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS },
+ 
+     { -1, NULL, NULL, 0, 0, { NULL, }, IFS },
+   };
+@@ -258,6 +283,15 @@ main (int argc, char *argv[])
+ 	  return -1;
+     }
+ 
++  /* If we are not allowed to do command substitution, we install
++     fork handlers to verify that no forks happened.  No forks should
++     happen at all if command substitution is disabled.  */
++  if (__app_register_atfork (register_fork, NULL, NULL) != 0)
++    {
++      printf ("Failed to register fork handler.\n");
++      return -1;
++    }
++
+   for (test = 0; test_case[test].retval != -1; test++)
+     if (testit (&test_case[test]))
+       ++fail;
+@@ -367,6 +401,9 @@ testit (struct test_case_struct *tc)
+ 
+   printf ("Test %d (%s): ", ++tests, tc->words);
+ 
++  if (tc->flags & WRDE_NOCMD)
++    registered_forks = 0;
++
+   if (tc->flags & WRDE_APPEND)
+     {
+       /* initial wordexp() call, to be appended to */
+@@ -378,6 +415,13 @@ testit (struct test_case_struct *tc)
+     }
+   retval = wordexp (tc->words, &we, tc->flags);
+ 
++  if ((tc->flags & WRDE_NOCMD)
++      && (registered_forks > 0))
++    {
++	  printf ("FAILED fork called for WRDE_NOCMD\n");
++	  return 1;
++    }
++
+   if (tc->flags & WRDE_DOOFFS)
+       start_offs = sav_we.we_offs;
+ 
+diff --git a/posix/wordexp.c b/posix/wordexp.c
+index b6b65dd..26f3a26 100644
+--- a/posix/wordexp.c
++++ b/posix/wordexp.c
+@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
+   pid_t pid;
+   int noexec = 0;
+ 
++  /* Do nothing if command substitution should not succeed.  */
++  if (flags & WRDE_NOCMD)
++    return WRDE_CMDSUB;
++
+   /* Don't fork() unless necessary */
+   if (!comm || !*comm)
+     return 0;
+@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word_length, size_t *max_length,
+ 	    }
+ 	}
+ 
+-      if (flags & WRDE_NOCMD)
+-	return WRDE_CMDSUB;
+-
+       (*offset) += 2;
+       return parse_comm (word, word_length, max_length, words, offset, flags,
+ 			 quoted? NULL : pwordexp, ifs, ifs_white);
+@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_length, size_t *max_length,
+ 	  break;
+ 
+ 	case '`':
+-	  if (flags & WRDE_NOCMD)
+-	    return WRDE_CMDSUB;
+-
+ 	  ++(*offset);
+ 	  error = parse_backtick (word, word_length, max_length, words,
+ 				  offset, flags, NULL, NULL, NULL);
+@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags)
+ 	break;
+ 
+       case '`':
+-	if (flags & WRDE_NOCMD)
+-	  {
+-	    error = WRDE_CMDSUB;
+-	    goto do_error;
+-	  }
+-
+ 	++words_offset;
+ 	error = parse_backtick (&word, &word_length, &max_length, words,
+ 				&words_offset, flags, pwordexp, ifs,
diff --git a/gnu/packages/patches/glibc-mips-dangling-vfork-ref.patch b/gnu/packages/patches/glibc-mips-dangling-vfork-ref.patch
new file mode 100644
index 0000000000..852b6de669
--- /dev/null
+++ b/gnu/packages/patches/glibc-mips-dangling-vfork-ref.patch
@@ -0,0 +1,45 @@
+Avoid a dangling `vfork@GLIBC_2.0' reference on MIPS.
+
+Note: Here the ChangeLog and NEWS updates are removed from Maciej's
+      patch, since they depend on other earlier commits.
+
+From: Maciej W. Rozycki <macro@codesourcery.com>
+Date: Wed, 22 Oct 2014 14:20:37 +0000 (+0100)
+Subject: MIPS: Avoid a dangling `vfork@GLIBC_2.0' reference
+X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=c14e752fc73d34c75d4f84f37fea8e0b1734cf98
+
+MIPS: Avoid a dangling `vfork@GLIBC_2.0' reference
+
+This satisfies a symbol reference created with:
+
+	.symver	__libc_vfork, vfork@GLIBC_2.0
+
+where `__libc_vfork' has not been defined or referenced.  In this case
+the `vfork@GLIBC_2.0' reference is supposed to be discarded, however a
+bug present in GAS since forever causes an undefined symbol table entry
+to be created.  This in turn triggers a problem in the linker that can
+manifest itself by link errors such as:
+
+ld: libpthread.so: invalid string offset 2765592330 >= 5154 for section `.dynstr'
+
+The GAS and linker bugs need to be resolved, but we can avoid them too
+by providing a `__libc_vfork' definition just like our other platforms.
+
+	[BZ #17485]
+	* sysdeps/unix/sysv/linux/mips/vfork.S (__libc_vfork): Define.
+
+(cherry picked from commit b5af9297d51a43f96c5be1bafab032184690dd6f)
+
+Conflicts:
+	NEWS
+---
+
+diff --git a/sysdeps/unix/sysv/linux/mips/vfork.S b/sysdeps/unix/sysv/linux/mips/vfork.S
+index 80c362d..2c1a747 100644
+--- a/sysdeps/unix/sysv/linux/mips/vfork.S
++++ b/sysdeps/unix/sysv/linux/mips/vfork.S
+@@ -108,3 +108,4 @@ L(error):
+ 
+ libc_hidden_def(__vfork)
+ weak_alias (__vfork, vfork)
++strong_alias (__vfork, __libc_vfork)
diff --git a/gnu/packages/patches/gmp-arm-asm-nothumb.patch b/gnu/packages/patches/gmp-arm-asm-nothumb.patch
new file mode 100644
index 0000000000..666cf58cf6
--- /dev/null
+++ b/gnu/packages/patches/gmp-arm-asm-nothumb.patch
@@ -0,0 +1,21 @@
+
+# HG changeset patch
+# User Torbjorn Granlund <tege@gmplib.org>
+# Date 1396602422 -7200
+# Node ID 676e2d0f0e4dd301a7066079d2c9326c25c34a40
+# Parent  0194a75b56b21a9196626430af86c5bd9110c42d
+Conditionalise ARM asm on !__thumb__.
+
+diff -r 0194a75b56b2 -r 676e2d0f0e4d mpn/generic/div_qr_1n_pi1.c
+--- a/mpn/generic/div_qr_1n_pi1.c	Thu Apr 03 23:58:51 2014 +0200
++++ b/mpn/generic/div_qr_1n_pi1.c	Fri Apr 04 11:07:02 2014 +0200
+@@ -130,7 +130,7 @@
+ 	     "%2" ((UDItype)(a0)), "r" ((UDItype)(b0)) __CLOBBER_CC)
+ #endif
+ 
+-#if defined (__arm__) && W_TYPE_SIZE == 32
++#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32
+ #define add_mssaaaa(m, sh, sl, ah, al, bh, bl)				\
+   __asm__ (  "adds	%2, %5, %6\n\t"					\
+ 	     "adcs	%1, %3, %4\n\t"					\
+
diff --git a/gnu/packages/patches/guile-arm-fixes.patch b/gnu/packages/patches/guile-arm-fixes.patch
new file mode 100644
index 0000000000..62bcf0fa7b
--- /dev/null
+++ b/gnu/packages/patches/guile-arm-fixes.patch
@@ -0,0 +1,203 @@
+Apply fixes for ARM to Guile.
+
+From df8c52e93dfa3965e4714275f4b8cea2c8e0170b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
+Date: Fri, 4 Jul 2014 15:35:06 +0200
+Subject: [PATCH] Recognize arm-* target triplets.
+
+Reported by Sylvain Beucler <beuc@beuc.net>.
+
+* module/system/base/target.scm (cpu-endianness): Add case where CPU is
+  "arm".
+* test-suite/tests/asm-to-bytecode.test ("cross-compilation")["arm-unknown-linux-androideabi"]:
+  New test.
+---
+ module/system/base/target.scm         | 4 +++-
+ test-suite/tests/asm-to-bytecode.test | 5 ++++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/module/system/base/target.scm b/module/system/base/target.scm
+index c74ae67..cefa951 100644
+--- a/module/system/base/target.scm
++++ b/module/system/base/target.scm
+@@ -1,6 +1,6 @@
+ ;;; Compilation targets
+ 
+-;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
++;; Copyright (C) 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+ 
+ ;; This library is free software; you can redistribute it and/or
+ ;; modify it under the terms of the GNU Lesser General Public
+@@ -72,6 +72,8 @@
+              (endianness big))
+             ((string-match "^arm.*el" cpu)
+              (endianness little))
++            ((string=? "arm" cpu)                ;ARMs are LE by default
++             (endianness little))
+             (else
+              (error "unknown CPU endianness" cpu)))))
+ 
+diff --git a/test-suite/tests/asm-to-bytecode.test b/test-suite/tests/asm-to-bytecode.test
+index 6d2f20e..62ea0ed 100644
+--- a/test-suite/tests/asm-to-bytecode.test
++++ b/test-suite/tests/asm-to-bytecode.test
+@@ -1,6 +1,6 @@
+ ;;;; Assembly to bytecode compilation -*- mode: scheme; coding: utf-8; -*-
+ ;;;;
+-;;;; 	Copyright (C) 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
++;;;; 	Copyright (C) 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+ ;;;;
+ ;;;; This library is free software; you can redistribute it and/or
+ ;;;; modify it under the terms of the GNU Lesser General Public
+@@ -205,6 +205,9 @@
+   (test-target "x86_64-unknown-linux-gnux32"      ; x32 ABI (Debian tuplet)
+                (endianness little) 4)
+ 
++  (test-target "arm-unknown-linux-androideabi"
++               (endianness little) 4)
++
+   (pass-if-exception "unknown target"
+     exception:miscellaneous-error
+     (call-with-values (lambda ()
+-- 
+2.1.2
+
+From ffd3e55cfd12a3559621e3130d613d319243512d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
+Date: Fri, 4 Jul 2014 17:26:41 +0200
+Subject: [PATCH] Recognize more ARM targets.
+
+Suggested by Dale P. Smith.
+
+* module/system/base/target.scm (cpu-endianness): Add cases for
+  "arm.*eb", "^aarch64.*be", and "aarch64".  Change "arm" case to
+  "arm.*".
+  (triplet-pointer-size): Allow underscore as in 'aarch64_be'.
+* test-suite/tests/asm-to-bytecode.test ("cross-compilation")["armeb-unknown-linux-gnu",
+  "aarch64-linux-gnu", "aarch64_be-linux-gnu"]: New tests.
+---
+ module/system/base/target.scm         | 10 ++++++++--
+ test-suite/tests/asm-to-bytecode.test |  6 ++++++
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/module/system/base/target.scm b/module/system/base/target.scm
+index cefa951..31e3fea 100644
+--- a/module/system/base/target.scm
++++ b/module/system/base/target.scm
+@@ -72,7 +72,13 @@
+              (endianness big))
+             ((string-match "^arm.*el" cpu)
+              (endianness little))
+-            ((string=? "arm" cpu)                ;ARMs are LE by default
++            ((string-match "^arm.*eb" cpu)
++             (endianness big))
++            ((string-prefix? "arm" cpu)          ;ARMs are LE by default
++             (endianness little))
++            ((string-match "^aarch64.*be" cpu)
++             (endianness big))
++            ((string=? "aarch64" cpu)
+              (endianness little))
+             (else
+              (error "unknown CPU endianness" cpu)))))
+@@ -97,7 +103,7 @@
+           ((string-match "^x86_64-.*-gnux32" triplet) 4)  ; x32
+ 
+           ((string-match "64$" cpu) 8)
+-          ((string-match "64[lbe][lbe]$" cpu) 8)
++          ((string-match "64_?[lbe][lbe]$" cpu) 8)
+           ((member cpu '("sparc" "powerpc" "mips" "mipsel")) 4)
+           ((string-match "^arm.*" cpu) 4)
+           (else (error "unknown CPU word size" cpu)))))
+diff --git a/test-suite/tests/asm-to-bytecode.test b/test-suite/tests/asm-to-bytecode.test
+index 62ea0ed..8aeba84 100644
+--- a/test-suite/tests/asm-to-bytecode.test
++++ b/test-suite/tests/asm-to-bytecode.test
+@@ -207,6 +207,12 @@
+ 
+   (test-target "arm-unknown-linux-androideabi"
+                (endianness little) 4)
++  (test-target "armeb-unknown-linux-gnu"
++               (endianness big) 4)
++  (test-target "aarch64-linux-gnu"
++               (endianness little) 8)
++  (test-target "aarch64_be-linux-gnu"
++               (endianness big) 8)
+ 
+   (pass-if-exception "unknown target"
+     exception:miscellaneous-error
+-- 
+2.1.2
+
+From a85c78ea1393985fdb6e6678dea19135c553d341 Mon Sep 17 00:00:00 2001
+From: Mark H Weaver <mhw@netris.org>
+Date: Fri, 19 Sep 2014 21:18:09 -0400
+Subject: [PATCH] VM: ASM_MUL for ARM: Add earlyclobber constraint to the SMULL
+ outputs.
+
+Reported by Rob Browning <rlb@defaultvalue.org>.
+
+* libguile/vm-i-scheme.c (ASM_MUL)[ARM]: Add earlyclobber (&) constraint
+  to the SMULL output registers.
+---
+ libguile/vm-i-scheme.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/libguile/vm-i-scheme.c b/libguile/vm-i-scheme.c
+index 587aa95..162efab 100644
+--- a/libguile/vm-i-scheme.c
++++ b/libguile/vm-i-scheme.c
+@@ -1,5 +1,4 @@
+-/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013,
+- *   2014 Free Software Foundation, Inc.
++/* Copyright (C) 2001, 2009-2014 Free Software Foundation, Inc.
+  * 
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public License
+@@ -363,7 +362,7 @@ VM_DEFINE_FUNCTION (149, ge, "ge?", 2)
+       {									\
+ 	scm_t_signed_bits rlo, rhi;					\
+ 	asm ("smull %0, %1, %2, %3\n"					\
+-	     : "=r" (rlo), "=r" (rhi)					\
++	     : "=&r" (rlo), "=&r" (rhi)					\
+ 	     : "r" (SCM_UNPACK (x) - scm_tc2_int),			\
+ 	       "r" (SCM_I_INUM (y)));					\
+ 	if (SCM_LIKELY (SCM_SRS (rlo, 31) == rhi))			\
+-- 
+2.1.2
+
+From bed025bd2569b1c033f24d7d9e660e39ebf65cac Mon Sep 17 00:00:00 2001
+From: Mark H Weaver <mhw@netris.org>
+Date: Sat, 20 Sep 2014 03:59:51 -0400
+Subject: [PATCH] VM: Allow the C compiler to choose FP_REG on ARM.
+
+Reported by Rob Browning <rlb@defaultvalue.org>.
+
+* libguile/vm-engine.h (IP_REG)[__arm__]: Remove explicit register
+  choice ("r7") for FP_REG, which was reported to cause compilation
+  failures on ARM.
+---
+ libguile/vm-engine.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libguile/vm-engine.h b/libguile/vm-engine.h
+index 46d4cff..e618be7 100644
+--- a/libguile/vm-engine.h
++++ b/libguile/vm-engine.h
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 2001, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
++/* Copyright (C) 2001, 2009-2012, 2014 Free Software Foundation, Inc.
+  * 
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public License
+@@ -81,7 +81,7 @@
+ #ifdef __arm__
+ #define IP_REG asm("r9")
+ #define SP_REG asm("r8")
+-#define FP_REG asm("r7")
++#define FP_REG
+ #endif
+ #endif
+ 
+-- 
+2.1.2
+
diff --git a/gnu/packages/patches/libtool-2.4-skip-tests.patch b/gnu/packages/patches/libtool-2.4-skip-tests.patch
deleted file mode 100644
index 95747dfef0..0000000000
--- a/gnu/packages/patches/libtool-2.4-skip-tests.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-Because our GCC 'lib' spec automatically adds '-rpath' for each '-L'
-and a couple more '-rpath, there are two test failures:
-one in demo.test, and one in destdir.at.  Disable these.
-
---- libtool-2.4.4/tests/testsuite	2014-11-29 17:43:11.000000000 +0100
-+++ libtool-2.4.4/tests/testsuite	2015-01-03 23:00:09.367775122 +0100
-@@ -9185,7 +9185,7 @@ read at_status <"$at_status_file"
- #AT_START_33
- at_fn_group_banner 33 'demo.at:548' \
-   "hardcoding library path" "                        " 3
--at_xfail=no
-+at_xfail=yes
-       test no = "$ACLOCAL" && at_xfail=yes
-       test no = "$AUTOHEADER" && at_xfail=yes
-       test no = "$AUTOMAKE" && at_xfail=yes
-@@ -27052,7 +27052,7 @@ read at_status <"$at_status_file"
- #AT_START_97
- at_fn_group_banner 97 'destdir.at:75' \
-   "DESTDIR with in-package deplibs" "                " 7
--at_xfail=no
-+at_xfail=yes
-       eval `$LIBTOOL --config | $GREP '^fast_install='`
-            case $fast_install in no) :;; *) false;; esac && at_xfail=yes
- (
diff --git a/gnu/packages/patches/libtool-skip-tests-for-mips.patch b/gnu/packages/patches/libtool-skip-tests-for-mips.patch
deleted file mode 100644
index 36587d23c2..0000000000
--- a/gnu/packages/patches/libtool-skip-tests-for-mips.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-TEMPORARY HACK: Disable a test that fails on MIPS.
-
---- libtool/Makefile.in.orig	2011-10-17 06:18:55.000000000 -0400
-+++ libtool/Makefile.in	2013-10-12 20:41:50.669067382 -0400
-@@ -890,7 +890,6 @@
- 	tests/demo-pic-make.test \
- 	tests/demo-pic-exec.test \
- 	tests/demo-nopic.test \
--	tests/demo-nopic-make.test \
- 	tests/demo-nopic-exec.test \
- 	tests/cdemo-shared.test \
- 	tests/cdemo-shared-make.test \
diff --git a/gnu/packages/patches/libtool-skip-tests.patch b/gnu/packages/patches/libtool-skip-tests.patch
index 6e12615d51..6082c3f1f1 100644
--- a/gnu/packages/patches/libtool-skip-tests.patch
+++ b/gnu/packages/patches/libtool-skip-tests.patch
@@ -1,37 +1,55 @@
-Because our GCC `lib' spec automatically adds `-rpath' for each `-L'
-and a couple more `-rpath, there are two test failures:
-demo-hardcode.test, and destdir.at.  Disable these.
+Because our GCC 'lib' spec automatically adds '-rpath' for each '-L'
+and a couple more '-rpath, there are two test failures:
+one in demo.test, and one in destdir.at.  Disable these.
 
---- libtool-2.4.2/Makefile.in	2011-10-17 12:18:55.000000000 +0200
-+++ libtool-2.4.2/Makefile.in	2012-09-13 23:50:37.000000000 +0200
-@@ -909,7 +908,7 @@ COMMON_TESTS = \
- # but they depend on the other tests being run beforehand.
- INTERACTIVE_TESTS = tests/demo-shared.test tests/demo-shared-make.test \
- 	tests/demo-shared-exec.test tests/demo-shared-inst.test \
--	tests/demo-hardcode.test tests/demo-relink.test \
-+	tests/demo-relink.test \
- 	tests/demo-noinst-link.test tests/demo-shared-unst.test \
- 	tests/depdemo-shared.test tests/depdemo-shared-make.test \
- 	tests/depdemo-shared-exec.test tests/depdemo-shared-inst.test \
-@@ -2580,8 +2579,7 @@ tests/cdemo-static-make.log:	tests/cdemo
- 
- tests/demo-shared-unst.log:	tests/demo-noinst-link.log
- tests/demo-noinst-link.log:	tests/demo-relink.log
--tests/demo-relink.log:		tests/demo-hardcode.log
--tests/demo-hardcode.log:	tests/demo-shared-inst.log
-+tests/demo-relink.log:		tests/demo-shared-inst.log
- tests/demo-shared-inst.log:	tests/demo-shared-exec.log
- tests/demo-shared-exec.log:	tests/demo-shared-make.log
- tests/demo-shared-make.log:	tests/demo-shared.log
+Also skip the nopic test on ARM and MIPS systems.
 
---- libtool-2.4.2/tests/testsuite	2011-10-17 12:19:52.000000000 +0200
-+++ libtool-2.4.2/tests/testsuite	2012-09-14 00:28:45.000000000 +0200
-@@ -14443,6 +14443,6 @@ read at_status <"$at_status_file"
- #AT_START_69
- at_fn_group_banner 69 'destdir.at:75' \
-   "DESTDIR with in-package deplibs" "                " 4
+--- libtool-2.4.4/tests/demo.at.orig	2014-11-19 07:28:51.000000000 -0500
++++ libtool-2.4.4/tests/demo.at	2015-01-07 17:30:46.482247718 -0500
+@@ -510,7 +510,7 @@
+ AT_SETUP([force non-PIC objects])
+ 
+ AT_CHECK([case $host in
+-hppa*|x86_64*|s390*)
++hppa*|x86_64*|s390*|arm*|mips*)
+   # These hosts cannot use non-PIC shared libs
+   exit 77 ;;
+ *-solaris*|*-sunos*)
+--- libtool-2.4.4/tests/testsuite.orig	2014-11-29 11:43:11.000000000 -0500
++++ libtool-2.4.4/tests/testsuite	2015-01-07 17:24:51.424672582 -0500
+@@ -8633,7 +8633,7 @@
+ 
+ { set +x
+ $as_echo "$at_srcdir/demo.at:535: case \$host in
+-hppa*|x86_64*|s390*)
++hppa*|x86_64*|s390*|arm*|mips*)
+   # These hosts cannot use non-PIC shared libs
+   exit 77 ;;
+ *-solaris*|*-sunos*)
+@@ -8658,7 +8658,7 @@
+ "
+ at_fn_check_prepare_notrace 'a `...` command substitution' "demo.at:535"
+ ( $at_check_trace; case $host in
+-hppa*|x86_64*|s390*)
++hppa*|x86_64*|s390*|arm*|mips*)
+   # These hosts cannot use non-PIC shared libs
+   exit 77 ;;
+ *-solaris*|*-sunos*)
+@@ -9185,7 +9185,7 @@ read at_status <"$at_status_file"
+ #AT_START_33
+ at_fn_group_banner 33 'demo.at:548' \
+   "hardcoding library path" "                        " 3
 -at_xfail=no
 +at_xfail=yes
-       eval `$LIBTOOL --config | grep '^fast_install='`
+       test no = "$ACLOCAL" && at_xfail=yes
+       test no = "$AUTOHEADER" && at_xfail=yes
+       test no = "$AUTOMAKE" && at_xfail=yes
+@@ -27052,7 +27052,7 @@ read at_status <"$at_status_file"
+ #AT_START_97
+ at_fn_group_banner 97 'destdir.at:75' \
+   "DESTDIR with in-package deplibs" "                " 7
+-at_xfail=no
++at_xfail=yes
+       eval `$LIBTOOL --config | $GREP '^fast_install='`
             case $fast_install in no) :;; *) false;; esac && at_xfail=yes
-
+ (
diff --git a/gnu/packages/patches/m4-readlink-EINVAL.patch b/gnu/packages/patches/m4-readlink-EINVAL.patch
deleted file mode 100644
index dd371584a7..0000000000
--- a/gnu/packages/patches/m4-readlink-EINVAL.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-Newer Linux kernels would return EINVAL instead of ENOENT.
-The patch below, taken from Gnulib, allows the test to pass when
-these Linux versions are in use:
-https://lists.gnu.org/archive/html/bug-gnulib/2011-03/msg00308.html .
-
-diff --git a/tests/test-readlink.h b/tests/test-readlink.h
-index 08d5662..7247fc4 100644
---- a/tests/test-readlink.h
-+++ b/tests/test-readlink.h
-@@ -38,7 +38,7 @@ test_readlink (ssize_t (*func) (char const *, char *, size_t), bool print)
-   ASSERT (errno == ENOENT);
-   errno = 0;
-   ASSERT (func ("", buf, sizeof buf) == -1);
--  ASSERT (errno == ENOENT);
-+  ASSERT (errno == ENOENT || errno == EINVAL);
-   errno = 0;
-   ASSERT (func (".", buf, sizeof buf) == -1);
-   ASSERT (errno == EINVAL);
diff --git a/gnu/packages/patches/patchelf-page-size.patch b/gnu/packages/patches/patchelf-page-size.patch
index 2528b604e5..1c14047512 100644
--- a/gnu/packages/patches/patchelf-page-size.patch
+++ b/gnu/packages/patches/patchelf-page-size.patch
@@ -28,42 +28,43 @@ Patch by Mark H Weaver <mhw@netris.org>.
  #endif
  
  
---- patchelf/tests/no-rpath.sh.orig	1969-12-31 19:00:01.000000000 -0500
-+++ patchelf/tests/no-rpath.sh	2014-02-16 20:44:12.036376953 -0500
-@@ -1,22 +1,22 @@
+--- patchelf/tests/no-rpath.sh.orig	2014-01-14 08:17:47.000000000 -0500
++++ patchelf/tests/no-rpath.sh	2015-01-06 18:31:53.418172797 -0500
+@@ -1,23 +1,23 @@
  #! /bin/sh -e
+ SCRATCH=scratch/$(basename $0 .sh)
  
--rm -rf scratch
--mkdir -p scratch
+-rm -rf ${SCRATCH}
+-mkdir -p ${SCRATCH}
 +if [ "$(uname -m)" = i686 -a "$(uname -s)" = Linux ]; then
-+    rm -rf scratch
-+    mkdir -p scratch
++    rm -rf ${SCRATCH}
++    mkdir -p ${SCRATCH}
  
--cp no-rpath scratch/
-+    cp no-rpath scratch/
+-cp ${srcdir}/no-rpath ${SCRATCH}/
++    cp ${srcdir}/no-rpath ${SCRATCH}/
  
--oldRPath=$(../src/patchelf --print-rpath scratch/no-rpath)
+-oldRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath)
 -if test -n "$oldRPath"; then exit 1; fi
 -../src/patchelf \
 -  --set-interpreter "$(../src/patchelf --print-interpreter ../src/patchelf)" \
--  --set-rpath /foo:/bar:/xxxxxxxxxxxxxxx scratch/no-rpath
-+    oldRPath=$(../src/patchelf --print-rpath scratch/no-rpath)
+-  --set-rpath /foo:/bar:/xxxxxxxxxxxxxxx ${SCRATCH}/no-rpath
++    oldRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath)
 +    if test -n "$oldRPath"; then exit 1; fi
 +    ../src/patchelf \
 +      --set-interpreter "$(../src/patchelf --print-interpreter ../src/patchelf)" \
-+      --set-rpath /foo:/bar:/xxxxxxxxxxxxxxx scratch/no-rpath
++      --set-rpath /foo:/bar:/xxxxxxxxxxxxxxx ${SCRATCH}/no-rpath
  
--newRPath=$(../src/patchelf --print-rpath scratch/no-rpath)
+-newRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath)
 -if ! echo "$newRPath" | grep -q '/foo:/bar'; then
 -    echo "incomplete RPATH"
 -    exit 1
 -fi
-+    newRPath=$(../src/patchelf --print-rpath scratch/no-rpath)
++    newRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath)
 +    if ! echo "$newRPath" | grep -q '/foo:/bar'; then
 +        echo "incomplete RPATH"
 +        exit 1
 +    fi
  
 -if [ "$(uname -m)" = i686 -a "$(uname -s)" = Linux ]; then
-     cd scratch && ./no-rpath
+     cd ${SCRATCH} && ./no-rpath
  fi
diff --git a/gnu/packages/patches/patchelf-rework-for-arm.patch b/gnu/packages/patches/patchelf-rework-for-arm.patch
new file mode 100644
index 0000000000..6f4eb8f72b
--- /dev/null
+++ b/gnu/packages/patches/patchelf-rework-for-arm.patch
@@ -0,0 +1,473 @@
+Rework the growing algorithm in patchelf to support ARM systems.
+See <https://github.com/NixOS/patchelf/issues/8>.
+This patch copied from:
+<https://github.com/sriemer/patchelf/commit/0a96239cea6b97b9a0fff80da576e58ca2dfb2a2>
+
+From 0a96239cea6b97b9a0fff80da576e58ca2dfb2a2 Mon Sep 17 00:00:00 2001
+From: Sebastian Parschauer <s.parschauer@gmx.de>
+Date: Sat, 28 Jun 2014 01:24:57 +0200
+Subject: [PATCH] Rework the growing algorithm
+
+On ARM systems there is no space in virtual memory for another LOAD
+area in front of the code LOAD area. So insert data to its end
+instead. At this location there should be enough space in virtual
+memory due to alignment. We can extend it until the end of the
+alignment but the file shift may be greater as it must be aligned
+to the page size. Do the same for the data LOAD area.
+---
+ src/patchelf.cc | 357 ++++++++++++++++++++++----------------------------------
+ 1 file changed, 142 insertions(+), 215 deletions(-)
+
+diff --git a/src/patchelf.cc b/src/patchelf.cc
+index dcbfd38..4fce9e6 100644
+--- a/src/patchelf.cc
++++ b/src/patchelf.cc
+@@ -116,7 +116,11 @@ private:
+ 
+     void sortShdrs();
+ 
+-    void shiftFile(unsigned int extraPages, Elf_Addr startPage);
++    void shiftFileSingle(size_t fileShift, Elf_Off insertOff);
++
++    void shiftFile(size_t neededCode, size_t neededData,
++                   Elf_Off codeOff[], Elf_Off dataOff[],
++                   Elf_Addr *codePage, Elf_Addr *dataPage);
+ 
+     string getSectionName(const Elf_Shdr & shdr);
+ 
+@@ -130,13 +134,11 @@ private:
+         unsigned int size);
+ 
+     void writeReplacedSections(Elf_Off & curOff,
+-        Elf_Addr startAddr, Elf_Off startOffset);
++        Elf_Addr startAddr, Elf_Off startOffset, bool isData);
+ 
+     void rewriteHeaders(Elf_Addr phdrAddress);
+ 
+-    void rewriteSectionsLibrary();
+-
+-    void rewriteSectionsExecutable();
++    void rewriteSectionsBinary();
+ 
+ public:
+ 
+@@ -391,46 +393,119 @@ static unsigned int roundUp(unsigned int n, unsigned int m)
+ 
+ 
+ template<ElfFileParams>
+-void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, Elf_Addr startPage)
++void ElfFile<ElfFileParamNames>::shiftFileSingle(size_t fileShift,
++        Elf_Off insertOff)
+ {
+-    /* Move the entire contents of the file `extraPages' pages
+-       further. */
+     unsigned int oldSize = fileSize;
+-    unsigned int shift = extraPages * pageSize;
+-    growFile(fileSize + extraPages * pageSize);
+-    memmove(contents + extraPages * pageSize, contents, oldSize);
+-    memset(contents + sizeof(Elf_Ehdr), 0, shift - sizeof(Elf_Ehdr));
++
++    /* Grow at the end */
++    growFile(fileSize + fileShift);
++
++    /* move the data from the insertion point
++       to the end and zero inserted space */
++    memmove(contents + insertOff + fileShift,
++            contents + insertOff, oldSize - insertOff);
++    memset(contents + insertOff, 0, fileShift);
+ 
+     /* Adjust the ELF header. */
+     wri(hdr->e_phoff, sizeof(Elf_Ehdr));
+-    wri(hdr->e_shoff, rdi(hdr->e_shoff) + shift);
++    if (rdi(hdr->e_shoff) >= insertOff)
++        wri(hdr->e_shoff, rdi(hdr->e_shoff) + fileShift);
+ 
+     /* Update the offsets in the section headers. */
+-    for (int i = 1; i < rdi(hdr->e_shnum); ++i)
+-        wri(shdrs[i].sh_offset, rdi(shdrs[i].sh_offset) + shift);
++    for (int i = 1; i < rdi(hdr->e_shnum); ++i) {
++        if (rdi(shdrs[i].sh_offset) >= insertOff)
++            wri(shdrs[i].sh_offset, rdi(shdrs[i].sh_offset) + fileShift);
++    }
+ 
+     /* Update the offsets in the program headers. */
+     for (int i = 0; i < rdi(hdr->e_phnum); ++i) {
+-        wri(phdrs[i].p_offset, rdi(phdrs[i].p_offset) + shift);
+-        if (rdi(phdrs[i].p_align) != 0 &&
+-            (rdi(phdrs[i].p_vaddr) - rdi(phdrs[i].p_offset)) % rdi(phdrs[i].p_align) != 0) {
+-            debug("changing alignment of program header %d from %d to %d\n", i,
+-                rdi(phdrs[i].p_align), pageSize);
+-            wri(phdrs[i].p_align, pageSize);
++        if (rdi(phdrs[i].p_offset) >= insertOff)
++            wri(phdrs[i].p_offset, rdi(phdrs[i].p_offset) + fileShift);
++        /* Check for ELF load command alignment issue the same
++           way as glibc/elf/dl-load.c does. This gives us the
++           chance to run an interpreter explicitly. */
++        if (rdi(phdrs[i].p_type) == PT_LOAD && ((rdi(phdrs[i].p_vaddr) -
++          rdi(phdrs[i].p_offset)) & (rdi(phdrs[i].p_align) - 1)) != 0) {
++             debug("changing alignment of program header %d from %d to %d\n",
++                   i, rdi(phdrs[i].p_align), pageSize);
++             wri(phdrs[i].p_align, pageSize);
+         }
+     }
++}
++
++template<ElfFileParams>
++void ElfFile<ElfFileParamNames>::shiftFile(size_t neededCode,
++        size_t neededData, Elf_Off codeOff[], Elf_Off dataOff[],
++        Elf_Addr *codePage, Elf_Addr *dataPage)
++{
++    /* Move some contents of the file further. The binary has one LOAD area
++     * for code and one for data. There is virtual memory space between
++     * these which we can use due to alignment.
++     */
++    unsigned int memShift = neededCode;
++    unsigned int fileShift = roundUp(neededCode, pageSize);
++    unsigned int maxMemShift = 0;
++
++    if (neededCode > 0) {
++        /* find the LOAD program header for code and extend it */
++        for (int i = 0; i < rdi(hdr->e_phnum); ++i) {
++            if (rdi(phdrs[i].p_type) == PT_LOAD &&
++              rdi(phdrs[i].p_flags) & PF_X) {
++                codeOff[1] = rdi(phdrs[i].p_filesz);
++                codeOff[0] = codeOff[1] + rdi(phdrs[i].p_offset);
++                maxMemShift = rdi(phdrs[i].p_memsz) % rdi(phdrs[i].p_align);
++                if (maxMemShift == 0)
++                    continue;
++                maxMemShift = rdi(phdrs[i].p_align) - maxMemShift;
++                if (maxMemShift == 0 || memShift > maxMemShift)
++                    continue;
++                *codePage = rdi(phdrs[i].p_vaddr);
++                wri(phdrs[i].p_filesz, rdi(phdrs[i].p_filesz) + memShift);
++                wri(phdrs[i].p_memsz, rdi(phdrs[i].p_memsz) + memShift);
++                break;
++            }
++        }
++        debug("codeOff: %#lx, memShift: %d, maxMemShift: %d, fileShift: %d\n",
++              codeOff[1], memShift, maxMemShift, fileShift);
++        if (codeOff[1] == 0 || maxMemShift == 0)
++            goto out;
++
++        shiftFileSingle(fileShift, codeOff[0]);
++    }
++
++    /* +++ Do the same for the data LOAD area  +++ */
++    memShift = neededData;
++    fileShift = roundUp(neededData, pageSize);
++    maxMemShift = 0;
++    if (neededData > 0) {
++        /* find the LOAD program header for data and extend it */
++        for (int i = 0; i < rdi(hdr->e_phnum); ++i) {
++            if (rdi(phdrs[i].p_type) == PT_LOAD &&
++              rdi(phdrs[i].p_flags) & PF_W) {
++                dataOff[1] = rdi(phdrs[i].p_filesz);
++                dataOff[0] = dataOff[1] + rdi(phdrs[i].p_offset);
++                maxMemShift = rdi(phdrs[i].p_memsz) % rdi(phdrs[i].p_align);
++                if (maxMemShift == 0)
++                    continue;
++                maxMemShift = rdi(phdrs[i].p_align) - maxMemShift;
++                if (maxMemShift == 0 || memShift > maxMemShift)
++                    continue;
++                *dataPage = rdi(phdrs[i].p_vaddr);
++                wri(phdrs[i].p_filesz, rdi(phdrs[i].p_filesz) + memShift);
++                wri(phdrs[i].p_memsz, rdi(phdrs[i].p_memsz) + memShift);
++                break;
++            }
++        }
++        debug("dataOff: %#lx, memShift: %d, maxMemShift: %d, fileShift: %d\n",
++              dataOff[1], memShift, maxMemShift, fileShift);
++        if (dataOff[1] == 0 || maxMemShift == 0)
++            goto out;
+ 
+-    /* Add a segment that maps the new program/section headers and
+-       PT_INTERP segment into memory.  Otherwise glibc will choke. */
+-    phdrs.resize(rdi(hdr->e_phnum) + 1);
+-    wri(hdr->e_phnum, rdi(hdr->e_phnum) + 1);
+-    Elf_Phdr & phdr = phdrs[rdi(hdr->e_phnum) - 1];
+-    wri(phdr.p_type, PT_LOAD);
+-    wri(phdr.p_offset, 0);
+-    wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage));
+-    wri(phdr.p_filesz, wri(phdr.p_memsz, shift));
+-    wri(phdr.p_flags, PF_R | PF_W);
+-    wri(phdr.p_align, pageSize);
++        shiftFileSingle(fileShift, dataOff[0]);
++    }
++out:
++    return;
+ }
+ 
+ 
+@@ -491,7 +566,7 @@ string & ElfFile<ElfFileParamNames>::replaceSection(const SectionName & sectionN
+ 
+ template<ElfFileParams>
+ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
+-    Elf_Addr startAddr, Elf_Off startOffset)
++    Elf_Addr startAddr, Elf_Off startOffset, bool isData = false)
+ {
+     /* Overwrite the old section contents with 'X's.  Do this
+        *before* writing the new section contents (below) to prevent
+@@ -501,6 +576,9 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
+     {
+         string sectionName = i->first;
+         Elf_Shdr & shdr = findSection(sectionName);
++        if ((!isData && rdi(shdr.sh_flags) & SHF_WRITE) ||
++         (isData && ~(rdi(shdr.sh_flags)) & SHF_WRITE))
++            continue;
+         memset(contents + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size));
+     }
+ 
+@@ -509,6 +587,9 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
+     {
+         string sectionName = i->first;
+         Elf_Shdr & shdr = findSection(sectionName);
++        if ((!isData && rdi(shdr.sh_flags) & SHF_WRITE) ||
++         (isData && ~(rdi(shdr.sh_flags)) & SHF_WRITE))
++            continue;
+         debug("rewriting section `%s' from offset 0x%x (size %d) to offset 0x%x (size %d)\n",
+             sectionName.c_str(), rdi(shdr.sh_offset), rdi(shdr.sh_size), curOff, i->second.size());
+ 
+@@ -546,201 +627,47 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
+         curOff += roundUp(i->second.size(), sectionAlignment);
+     }
+ 
+-    replacedSections.clear();
++    if (isData)
++        replacedSections.clear();
+ }
+ 
+ 
+ template<ElfFileParams>
+-void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
++void ElfFile<ElfFileParamNames>::rewriteSectionsBinary()
+ {
+-    /* For dynamic libraries, we just place the replacement sections
+-       at the end of the file.  They're mapped into memory by a
+-       PT_LOAD segment located directly after the last virtual address
+-       page of other segments. */
+-    Elf_Addr startPage = 0;
+-    for (unsigned int i = 0; i < phdrs.size(); ++i) {
+-        Elf_Addr thisPage = roundUp(rdi(phdrs[i].p_vaddr) + rdi(phdrs[i].p_memsz), pageSize);
+-        if (thisPage > startPage) startPage = thisPage;
+-    }
+-
+-    debug("last page is 0x%llx\n", (unsigned long long) startPage);
++    Elf_Off codeOff[2] = {0}, dataOff[2] = {0};
++    Elf_Addr codePage = 0, dataPage = 0;
++    size_t neededCode = 0, neededData = 0, oldCode = 0, oldData = 0;
++    Elf_Shdr shdr = findSection(".text");
++    Elf_Addr firstPage = rdi(shdr.sh_addr) - rdi(shdr.sh_offset);
+ 
++    debug("first page is 0x%llx\n", (unsigned long long) firstPage);
+ 
+-    /* Compute the total space needed for the replaced sections and
+-       the program headers. */
+-    off_t neededSpace = (phdrs.size() + 1) * sizeof(Elf_Phdr);
++    /* Compute the total space needed for the replaced sections */
+     for (ReplacedSections::iterator i = replacedSections.begin();
+-         i != replacedSections.end(); ++i)
+-        neededSpace += roundUp(i->second.size(), sectionAlignment);
+-    debug("needed space is %d\n", neededSpace);
+-
+-
+-    size_t startOffset = roundUp(fileSize, pageSize);
+-
+-    growFile(startOffset + neededSpace);
+-
+-
+-    /* Even though this file is of type ET_DYN, it could actually be
+-       an executable.  For instance, Gold produces executables marked
+-       ET_DYN.  In that case we can still hit the kernel bug that
+-       necessitated rewriteSectionsExecutable().  However, such
+-       executables also tend to start at virtual address 0, so
+-       rewriteSectionsExecutable() won't work because it doesn't have
+-       any virtual address space to grow downwards into.  As a
+-       workaround, make sure that the virtual address of our new
+-       PT_LOAD segment relative to the first PT_LOAD segment is equal
+-       to its offset; otherwise we hit the kernel bug.  This may
+-       require creating a hole in the executable.  The bigger the size
+-       of the uninitialised data segment, the bigger the hole. */
+-    if (isExecutable) {
+-        if (startOffset >= startPage) {
+-            debug("shifting new PT_LOAD segment by %d bytes to work around a Linux kernel bug\n", startOffset - startPage);
+-        } else {
+-            size_t hole = startPage - startOffset;
+-            /* Print a warning, because the hole could be very big. */
+-            fprintf(stderr, "warning: working around a Linux kernel bug by creating a hole of %zu bytes in ‘%s’\n", hole, fileName.c_str());
+-            assert(hole % pageSize == 0);
+-            /* !!! We could create an actual hole in the file here,
+-               but it's probably not worth the effort. */
+-            growFile(fileSize + hole);
+-            startOffset += hole;
+-        }
+-        startPage = startOffset;
+-    }
+-
+-
+-    /* Add a segment that maps the replaced sections and program
+-       headers into memory. */
+-    phdrs.resize(rdi(hdr->e_phnum) + 1);
+-    wri(hdr->e_phnum, rdi(hdr->e_phnum) + 1);
+-    Elf_Phdr & phdr = phdrs[rdi(hdr->e_phnum) - 1];
+-    wri(phdr.p_type, PT_LOAD);
+-    wri(phdr.p_offset, startOffset);
+-    wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage));
+-    wri(phdr.p_filesz, wri(phdr.p_memsz, neededSpace));
+-    wri(phdr.p_flags, PF_R | PF_W);
+-    wri(phdr.p_align, pageSize);
+-
+-
+-    /* Write out the replaced sections. */
+-    Elf_Off curOff = startOffset + phdrs.size() * sizeof(Elf_Phdr);
+-    writeReplacedSections(curOff, startPage, startOffset);
+-    assert((off_t) curOff == startOffset + neededSpace);
+-
+-
+-    /* Move the program header to the start of the new area. */
+-    wri(hdr->e_phoff, startOffset);
+-
+-    rewriteHeaders(startPage);
+-}
+-
+-
+-template<ElfFileParams>
+-void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
+-{
+-    /* Sort the sections by offset, otherwise we won't correctly find
+-       all the sections before the last replaced section. */
+-    sortShdrs();
+-
+-
+-    /* What is the index of the last replaced section? */
+-    unsigned int lastReplaced = 0;
+-    for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) {
+-        string sectionName = getSectionName(shdrs[i]);
+-        if (replacedSections.find(sectionName) != replacedSections.end()) {
+-            debug("using replaced section `%s'\n", sectionName.c_str());
+-            lastReplaced = i;
+-        }
+-    }
+-
+-    assert(lastReplaced != 0);
+-
+-    debug("last replaced is %d\n", lastReplaced);
+-
+-    /* Try to replace all sections before that, as far as possible.
+-       Stop when we reach an irreplacable section (such as one of type
+-       SHT_PROGBITS).  These cannot be moved in virtual address space
+-       since that would invalidate absolute references to them. */
+-    assert(lastReplaced + 1 < shdrs.size()); /* !!! I'm lazy. */
+-    size_t startOffset = rdi(shdrs[lastReplaced + 1].sh_offset);
+-    Elf_Addr startAddr = rdi(shdrs[lastReplaced + 1].sh_addr);
+-    string prevSection;
+-    for (unsigned int i = 1; i <= lastReplaced; ++i) {
+-        Elf_Shdr & shdr(shdrs[i]);
+-        string sectionName = getSectionName(shdr);
+-        debug("looking at section `%s'\n", sectionName.c_str());
+-        /* !!! Why do we stop after a .dynstr section? I can't
+-           remember! */
+-        if ((rdi(shdr.sh_type) == SHT_PROGBITS && sectionName != ".interp")
+-            || prevSection == ".dynstr")
+-        {
+-            startOffset = rdi(shdr.sh_offset);
+-            startAddr = rdi(shdr.sh_addr);
+-            lastReplaced = i - 1;
+-            break;
++         i != replacedSections.end(); ++i) {
++        shdr = findSection(i->first);
++        if (rdi(shdr.sh_flags) & SHF_WRITE) {
++            oldData += rdi(shdr.sh_size);
++            neededData += roundUp(i->second.size(), sectionAlignment);
+         } else {
+-            if (replacedSections.find(sectionName) == replacedSections.end()) {
+-                debug("replacing section `%s' which is in the way\n", sectionName.c_str());
+-                replaceSection(sectionName, rdi(shdr.sh_size));
+-            }
++            oldCode += rdi(shdr.sh_size);
++            neededCode += roundUp(i->second.size(), sectionAlignment);
+         }
+-        prevSection = sectionName;
+     }
+ 
+-    debug("first reserved offset/addr is 0x%x/0x%llx\n",
+-        startOffset, (unsigned long long) startAddr);
+-
+-    assert(startAddr % pageSize == startOffset % pageSize);
+-    Elf_Addr firstPage = startAddr - startOffset;
+-    debug("first page is 0x%llx\n", (unsigned long long) firstPage);
+-
+-    /* Right now we assume that the section headers are somewhere near
+-       the end, which appears to be the case most of the time.
+-       Therefore they're not accidentally overwritten by the replaced
+-       sections. !!!  Fix this. */
+-    assert((off_t) rdi(hdr->e_shoff) >= startOffset);
+-
+-
+-    /* Compute the total space needed for the replaced sections, the
+-       ELF header, and the program headers. */
+-    size_t neededSpace = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr);
+-    for (ReplacedSections::iterator i = replacedSections.begin();
+-         i != replacedSections.end(); ++i)
+-        neededSpace += roundUp(i->second.size(), sectionAlignment);
+-
+-    debug("needed space is %d\n", neededSpace);
+-
+-    /* If we need more space at the start of the file, then grow the
+-       file by the minimum number of pages and adjust internal
+-       offsets. */
+-    if (neededSpace > startOffset) {
+-
+-        /* We also need an additional program header, so adjust for that. */
+-        neededSpace += sizeof(Elf_Phdr);
+-        debug("needed space is %d\n", neededSpace);
+-
+-        unsigned int neededPages = roundUp(neededSpace - startOffset, pageSize) / pageSize;
+-        debug("needed pages is %d\n", neededPages);
+-        if (neededPages * pageSize > firstPage)
+-            error("virtual address space underrun!");
+-
+-        firstPage -= neededPages * pageSize;
+-        startOffset += neededPages * pageSize;
+-
+-        shiftFile(neededPages, firstPage);
+-    }
+-
+-
+-    /* Clear out the free space. */
+-    Elf_Off curOff = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr);
+-    debug("clearing first %d bytes\n", startOffset - curOff);
+-    memset(contents + curOff, 0, startOffset - curOff);
++    debug("needed space is C: %d, D: %d\n", neededCode, neededData);
+ 
++    /* If we need more space within the file, then grow the
++       file and adjust internal offsets. */
++    shiftFile(neededCode, neededData, codeOff, dataOff, &codePage,
++              &dataPage);
++    assert(codeOff[0] > 0);
+ 
+     /* Write out the replaced sections. */
+-    writeReplacedSections(curOff, firstPage, 0);
+-    assert((off_t) curOff == neededSpace);
+-
++    debug("codePage: %#lx, dataPage: %#lx\n", codePage, dataPage);
++    writeReplacedSections(codeOff[0], codePage + codeOff[1], codeOff[0]);
++    writeReplacedSections(dataOff[0], dataPage + dataOff[1], dataOff[0], true);
+ 
+     rewriteHeaders(firstPage + rdi(hdr->e_phoff));
+ }
+@@ -758,10 +685,10 @@ void ElfFile<ElfFileParamNames>::rewriteSections()
+ 
+     if (rdi(hdr->e_type) == ET_DYN) {
+         debug("this is a dynamic library\n");
+-        rewriteSectionsLibrary();
++        rewriteSectionsBinary();
+     } else if (rdi(hdr->e_type) == ET_EXEC) {
+         debug("this is an executable\n");
+-        rewriteSectionsExecutable();
++        rewriteSectionsBinary();
+     } else error("unknown ELF type");
+ }
+ 
+-- 
+2.1.2
+
diff --git a/gnu/packages/patches/sqlite-large-page-size-fix.patch b/gnu/packages/patches/sqlite-large-page-size-fix.patch
deleted file mode 100644
index c561fa20a2..0000000000
--- a/gnu/packages/patches/sqlite-large-page-size-fix.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-Add an experimental fix to avoid attempting to mmap memory from an
-offset that is not a multiple of the system page size on systems with
-page sizes larger than 32KB.
-
-Patch by Dan Kennedy <danielk1977@gmail.com>.
-
---- sqlite-autoconf/sqlite3.c.orig	2014-03-22 23:44:47.055908203 -0400
-+++ sqlite-autoconf/sqlite3.c	2014-03-22 23:44:06.716552734 -0400
-@@ -24010,6 +24010,7 @@
- 
- /* Forward reference */
- static int openDirectory(const char*, int*);
-+static int unixGetpagesize(void);
- 
- /*
- ** Many system calls are accessed through pointer-to-functions so that
-@@ -24133,6 +24134,9 @@
- #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
- #endif
- 
-+  { "getpagesize",  (sqlite3_syscall_ptr)unixGetpagesize, 0 },
-+#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
-+
- }; /* End of the overrideable system calls */
- 
- /*
-@@ -27792,6 +27796,36 @@
-   return rc;        
- }
- 
-+/*
-+** Return the system page size.
-+**
-+** This function should not be called directly by other code in this file. 
-+** Instead, it should be called via macro osGetpagesize().
-+*/
-+static int unixGetpagesize(void){
-+#if defined(_BSD_SOURCE)
-+  return getpagesize();
-+#else
-+  return (int)sysconf(_SC_PAGESIZE);
-+#endif
-+}
-+
-+/*
-+** Return the minimum number of 32KB shm regions that should be mapped at
-+** a time, assuming that each mapping must be an integer multiple of the
-+** current system page-size.
-+**
-+** Usually, this is 1. The exception seems to be systems that are configured
-+** to use 64KB pages - in this case each mapping must cover at least two
-+** shm regions.
-+*/
-+static int unixShmRegionPerMap(void){
-+  int shmsz = 32*1024;            /* SHM region size */
-+  int pgsz = osGetpagesize();   /* System page size */
-+  assert( ((pgsz-1)&pgsz)==0 );   /* Page size must be a power of 2 */
-+  if( pgsz<shmsz ) return 1;
-+  return pgsz/shmsz;
-+}
- 
- /*
- ** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
-@@ -27803,10 +27837,11 @@
-   unixShmNode *p = pFd->pInode->pShmNode;
-   assert( unixMutexHeld() );
-   if( p && p->nRef==0 ){
-+    int nShmPerMap = unixShmRegionPerMap();
-     int i;
-     assert( p->pInode==pFd->pInode );
-     sqlite3_mutex_free(p->mutex);
--    for(i=0; i<p->nRegion; i++){
-+    for(i=0; i<p->nRegion; i+=nShmPerMap){
-       if( p->h>=0 ){
-         osMunmap(p->apRegion[i], p->szRegion);
-       }else{
-@@ -28013,6 +28048,8 @@
-   unixShm *p;
-   unixShmNode *pShmNode;
-   int rc = SQLITE_OK;
-+  int nShmPerMap = unixShmRegionPerMap();
-+  int nReqRegion;
- 
-   /* If the shared-memory file has not yet been opened, open it now. */
-   if( pDbFd->pShm==0 ){
-@@ -28028,9 +28065,12 @@
-   assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
-   assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
- 
--  if( pShmNode->nRegion<=iRegion ){
-+  /* Minimum number of regions required to be mapped. */
-+  nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
-+
-+  if( pShmNode->nRegion<nReqRegion ){
-     char **apNew;                      /* New apRegion[] array */
--    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
-+    int nByte = nReqRegion*szRegion;   /* Minimum required file size */
-     struct stat sStat;                 /* Used by fstat() */
- 
-     pShmNode->szRegion = szRegion;
-@@ -28079,17 +28119,19 @@
- 
-     /* Map the requested memory region into this processes address space. */
-     apNew = (char **)sqlite3_realloc(
--        pShmNode->apRegion, (iRegion+1)*sizeof(char *)
-+        pShmNode->apRegion, nReqRegion*sizeof(char *)
-     );
-     if( !apNew ){
-       rc = SQLITE_IOERR_NOMEM;
-       goto shmpage_out;
-     }
-     pShmNode->apRegion = apNew;
--    while(pShmNode->nRegion<=iRegion){
-+    while( pShmNode->nRegion<nReqRegion ){
-+      int nMap = szRegion*nShmPerMap;
-+      int i;
-       void *pMem;
-       if( pShmNode->h>=0 ){
--        pMem = osMmap(0, szRegion,
-+        pMem = osMmap(0, nMap,
-             pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
-             MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
-         );
-@@ -28105,8 +28147,11 @@
-         }
-         memset(pMem, 0, szRegion);
-       }
--      pShmNode->apRegion[pShmNode->nRegion] = pMem;
--      pShmNode->nRegion++;
-+
-+      for(i=0; i<nShmPerMap; i++){
-+        pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
-+      }
-+      pShmNode->nRegion += nShmPerMap;
-     }
-   }
- 
-@@ -28321,19 +28366,6 @@
- }
- 
- /*
--** Return the system page size.
--*/
--static int unixGetPagesize(void){
--#if HAVE_MREMAP
--  return 512;
--#elif defined(_BSD_SOURCE)
--  return getpagesize();
--#else
--  return (int)sysconf(_SC_PAGESIZE);
--#endif
--}
--
--/*
- ** Attempt to set the size of the memory mapping maintained by file 
- ** descriptor pFd to nNew bytes. Any existing mapping is discarded.
- **
-@@ -28369,8 +28401,12 @@
-   if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
- 
-   if( pOrig ){
--    const int szSyspage = unixGetPagesize();
-+#if HAVE_MREMAP
-+    i64 nReuse = pFd->mmapSize;
-+#else
-+    const int szSyspage = osGetpagesize();
-     i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
-+#endif
-     u8 *pReq = &pOrig[nReuse];
- 
-     /* Unmap any pages of the existing mapping that cannot be reused. */
-@@ -31116,7 +31152,7 @@
- 
-   /* Double-check that the aSyscall[] array has been constructed
-   ** correctly.  See ticket [bb3a86e890c8e96ab] */
--  assert( ArraySize(aSyscall)==24 );
-+  assert( ArraySize(aSyscall)==25 );
- 
-   /* Register all VFSes defined in the aVfs[] array */
-   for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){