~ruther/guix-local

8033772363b287ca529461e575ceb4a69d7af942 — Ludovic Courtès 9 years ago c169d91
gnu: gcc@5, gcc@6: Work around use of 'movabs' for /gnu/store strings.

Partly addresses <http://bugs.gnu.org/24703>.
Reported by Mark H Weaver <mhw@netris.org>.

* gnu/packages/patches/gcc-strmov-store-file-names.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/gcc.scm (gcc-5)[sources](patches): Add it.
(gcc-6)[sources](patches): Add it.
3 files changed, 71 insertions(+), 2 deletions(-)

M gnu/local.mk
M gnu/packages/gcc.scm
A gnu/packages/patches/gcc-strmov-store-file-names.patch
M gnu/local.mk => gnu/local.mk +1 -0
@@ 543,6 543,7 @@ dist_patch_DATA =						\
  %D%/packages/patches/gcc-arm-link-spec-fix.patch		\
  %D%/packages/patches/gcc-cross-environment-variables.patch	\
  %D%/packages/patches/gcc-libvtv-runpath.patch			\
  %D%/packages/patches/gcc-strmov-store-file-names.patch	\
  %D%/packages/patches/gcc-5.0-libvtv-runpath.patch		\
  %D%/packages/patches/gcc-6-arm-none-eabi-multilib.patch	\
  %D%/packages/patches/gcc-6-cross-environment-variables.patch	\

M gnu/packages/gcc.scm => gnu/packages/gcc.scm +4 -2
@@ 354,7 354,8 @@ Go.  It also includes runtime support libraries for these languages.")
              (sha256
               (base32
                "1ny4smkp5bzs3cp8ss7pl6lk8yss0d9m4av1mvdp72r1x695akxq"))
              (patches (search-patches "gcc-5.0-libvtv-runpath.patch"))))))
              (patches (search-patches "gcc-strmov-store-file-names.patch"
                                       "gcc-5.0-libvtv-runpath.patch"))))))

(define-public gcc-6
  (package


@@ 367,7 368,8 @@ Go.  It also includes runtime support libraries for these languages.")
              (sha256
               (base32
                "1idpf43988v1a6i8lw9ak1r7igcfg1bm5kn011iydlr2qygmhi4r"))
              (patches (search-patches "gcc-5.0-libvtv-runpath.patch"))))))
              (patches (search-patches "gcc-strmov-store-file-names.patch"
                                       "gcc-5.0-libvtv-runpath.patch"))))))

;; Note: When changing the default gcc version, update
;;       the gcc-toolchain-* definitions accordingly.

A gnu/packages/patches/gcc-strmov-store-file-names.patch => gnu/packages/patches/gcc-strmov-store-file-names.patch +66 -0
@@ 0,0 1,66 @@
Make sure that statements such as:

  strcpy (dst, "/gnu/store/…");

do not result in chunked /gnu/store strings that are undetectable by
Guix's GC and its grafting code.  See <http://bugs.gnu.org/24703>.

--- gcc-5.3.0/gcc/builtins.c	2016-10-18 10:50:46.080616285 +0200
+++ gcc-5.3.0/gcc/builtins.c	2016-11-09 15:26:43.693042737 +0100
@@ -3192,6 +3192,42 @@ determine_block_size (tree len, rtx len_
 			  GET_MODE_MASK (GET_MODE (len_rtx)));
 }
 
+/* Return true if STR contains the string "/gnu/store".  */
+
+static bool
+store_reference_p (tree str)
+{
+  if (TREE_CODE (str) == ADDR_EXPR)
+    str = TREE_OPERAND (str, 0);
+
+  if (TREE_CODE (str) != STRING_CST)
+    return false;
+
+  int len;
+  const char *store;
+
+  store = getenv ("NIX_STORE") ? getenv ("NIX_STORE") : "/gnu/store";
+  len = strlen (store);
+
+  /* Size of the hash part of store file names, including leading slash and
+     trailing hyphen.  */
+  const int hash_len = 34;
+
+  if (TREE_STRING_LENGTH (str) < len + hash_len)
+    return false;
+
+  /* We cannot use 'strstr' because 'TREE_STRING_POINTER' returns a string
+     that is not necessarily NUL-terminated.  */
+
+  for (int i = 0; i < TREE_STRING_LENGTH (str) - (len + hash_len); i++)
+    {
+      if (strncmp (TREE_STRING_POINTER (str) + i, store, len) == 0)
+	return true;
+    }
+
+  return false;
+}
+
 /* Helper function to do the actual work for expand_builtin_memcpy.  */
 
 static rtx
@@ -3207,6 +3243,13 @@ expand_builtin_memcpy_args (tree dest, t
   unsigned HOST_WIDE_INT max_size;
   unsigned HOST_WIDE_INT probable_max_size;
 
+  /* Do not emit block moves, which translate to the 'movabs' instruction on
+     x86_64, when SRC refers to store items.  That way, store references
+     remain visible to the Guix GC and grafting code.  See
+     <http://bugs.gnu.org/24703>.  */
+  if (store_reference_p (src))
+    return NULL_RTX;
+
   /* If DEST is not a pointer type, call the normal function.  */
   if (dest_align == 0)
     return NULL_RTX;