summaryrefslogtreecommitdiff
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)
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++){