Subject: bug#30820: Chunked store references in compiled code break grafting (again)

From: [email-masked] (Ludovic Courtès)
Date: Wed, 14 Mar 2018 18:24:48 +0100

There are two issues.  First the gcc-strmov-store-file-names.patch
stopped working.  When we introduced it, we were at 5.3.0 and 6.2.0 (see
<https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/gcc.scm?id=8033772363b287ca529461e575ceb4a69d7af942>).

Today, with 5.5.0 and 6.3.0 it seems to have no effect (I use ‘ltrace’
here, which shows the getenv("NIX_STORE") call, which confirms that the
‘store_reference_p’ function in that patch gets called):

--8<---------------cut here---------------start------------->8---
$ cat strmov.c
#define _GNU_SOURCE
#include <string.h>
static const char str[] = "MEMpCPY /gnu/store/THIS IS A LONG STRING, A VERY, VERY, VERY LOOOOONG STRING";

extern char *p, *q;

#ifndef MEMCPY
# define MEMCPY memcpy
#endif

void foo (char *x, char *y)
{
  /* MEMCPY (x, str, sizeof str); */
  MEMCPY (y, "this is a literal /gnu/store string", 35);
}
$ guix environment --no-grafts --pure --ad-hoc -C ltrace gcc-toolchain@5 -- ltrace -f -e getenv gcc -O2 -c strmov.c 
[pid 2] gcc->getenv("COLUMNS")                                                                                 = nil
[pid 2] gcc->getenv("TERM")                                                                                    = nil
[pid 2] gcc->getenv("GCC_EXEC_PREFIX")                                                                         = nil
[pid 2] gcc->getenv("PATH")                                                                                    = "/gnu/store/c312mxd0ykdh3zi3zj13m"...
[pid 2] gcc->getenv("PATH")                                                                                    = "/gnu/store/c312mxd0ykdh3zi3zj13m"...
[pid 2] gcc->getenv("COMPILER_PATH")                                                                           = nil
[pid 2] gcc->getenv("LIBRARY_PATH")                                                                            = "/gnu/store/c312mxd0ykdh3zi3zj13m"...
[pid 2] gcc->getenv("LPATH")                                                                                   = nil
[pid 2] gcc->getenv("GCC_COMPARE_DEBUG")                                                                       = nil
[pid 2] gcc->getenv("GCC_ROOT")                                                                                = nil
[pid 2] gcc->getenv("BINUTILS_ROOT")                                                                           = nil
[pid 2] gcc->getenv("TMPDIR")                                                                                  = "/tmp"
[pid 2] gcc->getenv("TMP")                                                                                     = "/tmp"
[pid 2] gcc->getenv("TEMP")                                                                                    = "/tmp"
[pid 3] --- Called exec() ---
[pid 3] gcc->getenv("COLUMNS")                                                                                 = nil
[pid 3] gcc->getenv("TERM")                                                                                    = nil
[pid 3] gcc->getenv("DEPENDENCIES_OUTPUT")                                                                     = nil
[pid 3] gcc->getenv("SUNPRO_DEPENDENCIES")                                                                     = nil
[pid 3] gcc->getenv("CPATH")                                                                                   = nil
[pid 3] gcc->getenv("C_INCLUDE_PATH")                                                                          = "/gnu/store/c312mxd0ykdh3zi3zj13m"...
[pid 3] gcc->getenv("GCC_EXEC_PREFIX")                                                                         = nil
[pid 3] gcc->getenv("PWD")                                                                                     = nil
[pid 3] gcc->getenv("NIX_STORE")                                                                               = nil
[pid 3] +++ exited (status 0) +++
[pid 2] --- SIGCHLD (Child exited) ---
[pid 4] --- Called exec() ---
[pid 4] +++ exited (status 0) +++
[pid 2] --- SIGCHLD (Child exited) ---
[pid 2] +++ exited (status 0) +++
$ objdump -S strmov.o | grep movabs
   0:	48 b8 74 68 69 73 20 	movabs $0x2073692073696874,%rax
  11:	48 b8 61 20 6c 69 74 	movabs $0x61726574696c2061,%rax
  1f:	48 b8 6c 20 2f 67 6e 	movabs $0x732f756e672f206c,%rax
  2d:	48 b8 74 6f 72 65 20 	movabs $0x7274732065726f74,%rax
$ guix environment --no-grafts --pure --ad-hoc -C ltrace gcc-toolchain@6 -- ltrace -f -e getenv gcc -O2 -c strmov.c 
[pid 2] gcc->getenv("COLUMNS")                                                                                 = nil
[pid 2] gcc->getenv("TERM")                                                                                    = nil
[pid 2] gcc->getenv("GCC_EXEC_PREFIX")                                                                         = nil
[pid 2] gcc->getenv("PATH")                                                                                    = "/gnu/store/5141337yvhhjj5fhdx660"...
[pid 2] gcc->getenv("PATH")                                                                                    = "/gnu/store/5141337yvhhjj5fhdx660"...
[pid 2] gcc->getenv("COMPILER_PATH")                                                                           = nil
[pid 2] gcc->getenv("LIBRARY_PATH")                                                                            = "/gnu/store/5141337yvhhjj5fhdx660"...
[pid 2] gcc->getenv("LPATH")                                                                                   = nil
[pid 2] gcc->getenv("GCC_COMPARE_DEBUG")                                                                       = nil
[pid 2] gcc->getenv("GCC_ROOT")                                                                                = nil
[pid 2] gcc->getenv("BINUTILS_ROOT")                                                                           = nil
[pid 2] gcc->getenv("TMPDIR")                                                                                  = "/tmp"
[pid 2] gcc->getenv("TMP")                                                                                     = "/tmp"
[pid 2] gcc->getenv("TEMP")                                                                                    = "/tmp"
[pid 3] --- Called exec() ---
[pid 3] gcc->getenv("COLUMNS")                                                                                 = nil
[pid 3] gcc->getenv("TERM")                                                                                    = nil
[pid 3] gcc->getenv("DEPENDENCIES_OUTPUT")                                                                     = nil
[pid 3] gcc->getenv("SUNPRO_DEPENDENCIES")                                                                     = nil
[pid 3] gcc->getenv("CPATH")                                                                                   = nil
[pid 3] gcc->getenv("C_INCLUDE_PATH")                                                                          = "/gnu/store/5141337yvhhjj5fhdx660"...
[pid 3] gcc->getenv("GCC_EXEC_PREFIX")                                                                         = nil
[pid 3] gcc->getenv("PWD")                                                                                     = nil
[pid 3] gcc->getenv("NIX_STORE")                                                                               = nil
[pid 3] +++ exited (status 0) +++
[pid 2] --- SIGCHLD (Child exited) ---
[pid 4] --- Called exec() ---
[pid 4] +++ exited (status 0) +++
[pid 2] --- SIGCHLD (Child exited) ---
[pid 2] +++ exited (status 0) +++
$ objdump -S strmov.o | grep movabs
   0:	48 b8 74 68 69 73 20 	movabs $0x2073692073696874,%rax
  11:	48 b8 61 20 6c 69 74 	movabs $0x61726574696c2061,%rax
  1f:	48 b8 6c 20 2f 67 6e 	movabs $0x732f756e672f206c,%rax
  2d:	48 b8 74 6f 72 65 20 	movabs $0x7274732065726f74,%rax
--8<---------------cut here---------------end--------------->8---

On GCC 7.3.0, it works as intended:

--8<---------------cut here---------------start------------->8---
$ guix environment --no-grafts --pure --ad-hoc -C ltrace gcc-toolchain@7 -- ltrace -f -e getenv gcc -O2 -c strmov.c 
[pid 2] gcc->getenv("COLUMNS")                                                                                 = nil
[pid 2] gcc->getenv("TERM")                                                                                    = nil
[pid 2] gcc->getenv("GCC_EXEC_PREFIX")                                                                         = nil
[pid 2] gcc->getenv("PATH")                                                                                    = "/gnu/store/zahi3qjfnfq5z0bsxkggq"...
[pid 2] gcc->getenv("PATH")                                                                                    = "/gnu/store/zahi3qjfnfq5z0bsxkggq"...
[pid 2] gcc->getenv("COMPILER_PATH")                                                                           = nil
[pid 2] gcc->getenv("LIBRARY_PATH")                                                                            = "/gnu/store/zahi3qjfnfq5z0bsxkggq"...
[pid 2] gcc->getenv("LPATH")                                                                                   = nil
[pid 2] gcc->getenv("GCC_COMPARE_DEBUG")                                                                       = nil
[pid 2] gcc->getenv("GCC_ROOT")                                                                                = nil
[pid 2] gcc->getenv("BINUTILS_ROOT")                                                                           = nil
[pid 2] gcc->getenv("TMPDIR")                                                                                  = "/tmp"
[pid 2] gcc->getenv("TMP")                                                                                     = "/tmp"
[pid 2] gcc->getenv("TEMP")                                                                                    = "/tmp"
[pid 3] --- Called exec() ---
[pid 3] gcc->getenv("COLUMNS")                                                                                 = nil
[pid 3] gcc->getenv("TERM")                                                                                    = nil
[pid 3] gcc->getenv("DEPENDENCIES_OUTPUT")                                                                     = nil
[pid 3] gcc->getenv("SUNPRO_DEPENDENCIES")                                                                     = nil
[pid 3] gcc->getenv("CPATH")                                                                                   = nil
[pid 3] gcc->getenv("C_INCLUDE_PATH")                                                                          = "/gnu/store/zahi3qjfnfq5z0bsxkggq"...
[pid 3] gcc->getenv("GCC_EXEC_PREFIX")                                                                         = nil
[pid 3] gcc->getenv("PWD")                                                                                     = nil
[pid 3] gcc->getenv("NIX_STORE")                                                                               = nil
[pid 3] +++ exited (status 0) +++
[pid 2] --- SIGCHLD (Child exited) ---
[pid 4] --- Called exec() ---
[pid 4] +++ exited (status 0) +++
[pid 2] --- SIGCHLD (Child exited) ---
[pid 2] +++ exited (status 0) +++
$ objdump -S strmov.o | grep movabs
$ guix environment --no-grafts --pure --ad-hoc -C ltrace gcc-toolchain@6 -- /bin/sh -c 'export NIX_STORE=/foo ; ltrace -f -e getenv   gcc -O2 -c strmov.c '
[pid 3] gcc->getenv("COLUMNS")                                                                                 = nil
[pid 3] gcc->getenv("TERM")                                                                                    = nil
[pid 3] gcc->getenv("GCC_EXEC_PREFIX")                                                                         = nil
[pid 3] gcc->getenv("PATH")                                                                                    = "/gnu/store/5141337yvhhjj5fhdx660"...
[pid 3] gcc->getenv("PATH")                                                                                    = "/gnu/store/5141337yvhhjj5fhdx660"...
[pid 3] gcc->getenv("COMPILER_PATH")                                                                           = nil
[pid 3] gcc->getenv("LIBRARY_PATH")                                                                            = "/gnu/store/5141337yvhhjj5fhdx660"...
[pid 3] gcc->getenv("LPATH")                                                                                   = nil
[pid 3] gcc->getenv("GCC_COMPARE_DEBUG")                                                                       = nil
[pid 3] gcc->getenv("GCC_ROOT")                                                                                = nil
[pid 3] gcc->getenv("BINUTILS_ROOT")                                                                           = nil
[pid 3] gcc->getenv("TMPDIR")                                                                                  = "/tmp"
[pid 3] gcc->getenv("TMP")                                                                                     = "/tmp"
[pid 3] gcc->getenv("TEMP")                                                                                    = "/tmp"
[pid 4] --- Called exec() ---
[pid 4] gcc->getenv("COLUMNS")                                                                                 = nil
[pid 4] gcc->getenv("TERM")                                                                                    = nil
[pid 4] gcc->getenv("DEPENDENCIES_OUTPUT")                                                                     = nil
[pid 4] gcc->getenv("SUNPRO_DEPENDENCIES")                                                                     = nil
[pid 4] gcc->getenv("CPATH")                                                                                   = nil
[pid 4] gcc->getenv("C_INCLUDE_PATH")                                                                          = "/gnu/store/5141337yvhhjj5fhdx660"...
[pid 4] gcc->getenv("GCC_EXEC_PREFIX")                                                                         = nil
[pid 4] gcc->getenv("PWD")                                                                                     = "/home/ludo/src/guix"
[pid 4] gcc->getenv("NIX_STORE")                                                                               = "/foo"
[pid 4] gcc->getenv("NIX_STORE")                                                                               = "/foo"
[pid 4] +++ exited (status 0) +++
[pid 3] --- SIGCHLD (Child exited) ---
[pid 5] --- Called exec() ---
[pid 5] +++ exited (status 0) +++
[pid 3] --- SIGCHLD (Child exited) ---
[pid 3] +++ exited (status 0) +++
$ objdump -S strmov.o | grep movabs
   0:	48 b8 74 68 69 73 20 	movabs $0x2073692073696874,%rax
  11:	48 b8 61 20 6c 69 74 	movabs $0x61726574696c2061,%rax
  1f:	48 b8 6c 20 2f 67 6e 	movabs $0x732f756e672f206c,%rax
  2d:	48 b8 74 6f 72 65 20 	movabs $0x7274732065726f74,%rax
--8<---------------cut here---------------end--------------->8---

The second issue is that the patch only ever worked with literal
strings.  It does not “see” strings in constant arrays like the ‘str’
array in the example above.

The gconv-module file name mentioned in the first message in this bug
report is an example of a string assigned to a static array, in
iconv/gconv_conf.c:

  /* This is the default path where we look for module lists.  */
  static const char default_gconv_path[] = GCONV_PATH;

Ludo’.