1 Make sure that statements such as:
3 strcpy (dst, "/gnu/store/…");
7 static const char str[] = "/gnu/store/…";
11 do not result in chunked /gnu/store strings that are undetectable by
12 Guix's GC and its grafting code. See <https://bugs.gnu.org/24703>
13 and <https://bugs.gnu.org/30395>.
15 --- gcc-5.3.0/gcc/builtins.c 2016-10-18 10:50:46.080616285 +0200
16 +++ gcc-5.3.0/gcc/builtins.c 2016-11-09 15:26:43.693042737 +0100
17 @@ -3012,6 +3012,58 @@ determine_block_size (tree len, rtx len_rtx,
18 GET_MODE_MASK (GET_MODE (len_rtx)));
21 +extern void debug_tree (tree);
23 +/* Return true if STR contains the string "/gnu/store". */
26 +store_reference_p (tree str)
28 + if (getenv ("GUIX_GCC_DEBUG") != NULL)
31 + if (TREE_CODE (str) == ADDR_EXPR)
32 + str = TREE_OPERAND (str, 0);
34 + if (TREE_CODE (str) == VAR_DECL
35 + && TREE_STATIC (str)
36 + && TREE_READONLY (str))
38 + /* STR may be a 'static const' variable whose initial value
39 + is a string constant. See <https://bugs.gnu.org/30395>. */
40 + str = DECL_INITIAL (str);
41 + if (str == NULL_TREE)
45 + if (TREE_CODE (str) != STRING_CST)
51 + store = getenv ("NIX_STORE") ? getenv ("NIX_STORE") : "/gnu/store";
52 + len = strlen (store);
54 + /* Size of the hash part of store file names, including leading slash and
56 + const int hash_len = 34;
58 + if (TREE_STRING_LENGTH (str) < len + hash_len)
61 + /* We cannot use 'strstr' because 'TREE_STRING_POINTER' returns a string
62 + that is not necessarily NUL-terminated. */
64 + for (int i = 0; i < TREE_STRING_LENGTH (str) - (len + hash_len); i++)
66 + if (strncmp (TREE_STRING_POINTER (str) + i, store, len) == 0)
73 /* Try to verify that the sizes and lengths of the arguments to a string
74 manipulation function given by EXP are within valid bounds and that
75 the operation does not lead to buffer overflow or read past the end.
76 @@ -3605,6 +3657,13 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len,
77 unsigned HOST_WIDE_INT max_size;
78 unsigned HOST_WIDE_INT probable_max_size;
80 + /* Do not emit block moves, which translate to the 'movabs' instruction on
81 + x86_64, when SRC refers to store items. That way, store references
82 + remain visible to the Guix GC and grafting code. See
83 + <https://bugs.gnu.org/24703>. */
84 + if (store_reference_p (src))
87 /* If DEST is not a pointer type, call the normal function. */
90 --- gcc-5.5.0/gcc/gimple-fold.c 2018-03-20 11:36:16.709442004 +0100
91 +++ gcc-5.5.0/gcc/gimple-fold.c 2018-03-20 11:46:43.838487065 +0100
92 @@ -635,6 +635,8 @@ var_decl_component_p (tree var)
93 return SSA_VAR_P (inner);
96 +extern bool store_reference_p (tree);
98 /* If the SIZE argument representing the size of an object is in a range
99 of values of which exactly one is valid (and that is zero), return
100 true, otherwise false. */
101 @@ -742,6 +744,9 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
102 off0 = build_int_cst (build_pointer_type_for_mode (char_type_node,
105 + if (store_reference_p (src))
108 /* If we can perform the copy efficiently with first doing all loads
109 and then all stores inline it that way. Currently efficiently
110 means that we can load all the memory into a single integer