98 lines
3.7 KiB
Diff
98 lines
3.7 KiB
Diff
From e160a8cd4a704f4b7724df02b62394f677cc4198 Mon Sep 17 00:00:00 2001
|
|
From: Sergei Trofimovich <siarheit@google.com>
|
|
Date: Fri, 22 Sep 2023 22:41:49 +0100
|
|
Subject: [PATCH] gcc/file-prefix-map.cc: always mangle __FILE__ into invalid
|
|
store path
|
|
|
|
Without the change `__FILE__` used in static inline functions in headers
|
|
embed paths to header files into executable images. For local headers
|
|
it's not a problem, but for headers in `/nix/store` this causes `-dev`
|
|
inputs to be retained in runtime closure.
|
|
|
|
Typical examples are `nix` -> `nlohmann_json` and `pipewire` ->
|
|
`lttng-ust.dev`.
|
|
|
|
For this reason we want to remove the occurrences of hashes in the
|
|
expansion of `__FILE__`. `nuke-references` does it by replacing hashes
|
|
by `eeeeee...`. It is handy to be able to invert the transformation to
|
|
go back to the original store path. The chosen solution is to make the
|
|
hash uppercase:
|
|
- it does not trigger runtime references (except for all digit hashes,
|
|
which are unlikely enough)
|
|
- it visually looks like a bogus store path
|
|
- it is easy to find the original store path if required
|
|
|
|
Ideally we would like to use `-fmacro-prefix-map=` feature of `gcc` as:
|
|
|
|
-fmacro-prefix-map=/nix/store/$hash1-nlohmann-json-ver=/nix/store/$HASH1-nlohmann-json-ver
|
|
-fmacro-prefix-map=/nix/...
|
|
|
|
In practice it quickly exhausts argument length limit due to `gcc`
|
|
deficiency: https://gcc.gnu.org/PR111527
|
|
|
|
Until it's fixed let's hardcode header mangling if $NIX_STORE variable
|
|
is present in the environment.
|
|
|
|
Tested as:
|
|
|
|
$ printf "# 0 \"/nix/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-pppppp-vvvvvvv\" \nconst char * f(void) { return __FILE__; }" | NIX_STORE=/nix/store ./gcc/xgcc -Bgcc -x c - -S -o -
|
|
...
|
|
.string "/nix/store/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-pppppp-vvvvvvv"
|
|
...
|
|
|
|
Mangled successfully.
|
|
|
|
To reverse the effect of the mangle use new `NIX_GCC_DONT_MANGLE_PREFIX_MAP`
|
|
environment variable. It should not normally be needed.
|
|
--- a/gcc/file-prefix-map.cc
|
|
+++ b/gcc/file-prefix-map.cc
|
|
@@ -74,7 +74,7 @@ add_prefix_map (file_prefix_map *&maps, const char *arg, const char *opt)
|
|
remapping was performed. */
|
|
|
|
static const char *
|
|
-remap_filename (file_prefix_map *maps, const char *filename)
|
|
+remap_filename (file_prefix_map *maps, const char *filename, bool mangle_nix_store = false)
|
|
{
|
|
file_prefix_map *map;
|
|
char *s;
|
|
@@ -102,6 +102,30 @@ remap_filename (file_prefix_map *maps, const char *filename)
|
|
break;
|
|
if (!map)
|
|
{
|
|
+ if (mangle_nix_store && getenv("NIX_GCC_DONT_MANGLE_PREFIX_MAP") == NULL)
|
|
+ {
|
|
+ /* Remap all fo $NIX_STORE/.{32} paths to uppercase
|
|
+ *
|
|
+ * That way we avoid argument parameters explosion
|
|
+ * and still avoid embedding headers into runtime closure:
|
|
+ * https://gcc.gnu.org/PR111527
|
|
+ */
|
|
+ char * nix_store = getenv("NIX_STORE");
|
|
+ size_t nix_store_len = nix_store ? strlen(nix_store) : 0;
|
|
+ const char * name = realname ? realname : filename;
|
|
+ size_t name_len = strlen(name);
|
|
+ if (nix_store && name_len >= nix_store_len + 1 + 32 && memcmp(name, nix_store, nix_store_len) == 0)
|
|
+ {
|
|
+ s = (char *) ggc_alloc_atomic (name_len + 1);
|
|
+ memcpy(s, name, name_len + 1);
|
|
+ for (size_t i = nix_store_len + 1; i < nix_store_len + 1 + 32; i++) {
|
|
+ s[i] = TOUPPER(s[i]);
|
|
+ }
|
|
+ if (realname != filename)
|
|
+ free (const_cast <char *> (realname));
|
|
+ return s;
|
|
+ }
|
|
+ }
|
|
if (realname != filename)
|
|
free (const_cast <char *> (realname));
|
|
return filename;
|
|
@@ -163,7 +187,7 @@ add_profile_prefix_map (const char *arg)
|
|
const char *
|
|
remap_macro_filename (const char *filename)
|
|
{
|
|
- return remap_filename (macro_prefix_maps, filename);
|
|
+ return remap_filename (macro_prefix_maps, filename, true);
|
|
}
|
|
|
|
/* Remap using -fdebug-prefix-map. Return the GC-allocated new name
|