at master 3.8 kB view raw
1From e160a8cd4a704f4b7724df02b62394f677cc4198 Mon Sep 17 00:00:00 2001 2From: Sergei Trofimovich <siarheit@google.com> 3Date: Fri, 22 Sep 2023 22:41:49 +0100 4Subject: [PATCH] gcc/file-prefix-map.cc: always mangle __FILE__ into invalid 5 store path 6 7Without the change `__FILE__` used in static inline functions in headers 8embed paths to header files into executable images. For local headers 9it's not a problem, but for headers in `/nix/store` this causes `-dev` 10inputs to be retained in runtime closure. 11 12Typical examples are `nix` -> `nlohmann_json` and `pipewire` -> 13`lttng-ust.dev`. 14 15For this reason we want to remove the occurrences of hashes in the 16expansion of `__FILE__`. `nuke-references` does it by replacing hashes 17by `eeeeee...`. It is handy to be able to invert the transformation to 18go back to the original store path. The chosen solution is to make the 19hash uppercase: 20- it does not trigger runtime references (except for all digit hashes, 21 which are unlikely enough) 22- it visually looks like a bogus store path 23- it is easy to find the original store path if required 24 25Ideally we would like to use `-fmacro-prefix-map=` feature of `gcc` as: 26 27 -fmacro-prefix-map=/nix/store/$hash1-nlohmann-json-ver=/nix/store/$HASH1-nlohmann-json-ver 28 -fmacro-prefix-map=/nix/... 29 30In practice it quickly exhausts argument length limit due to `gcc` 31deficiency: https://gcc.gnu.org/PR111527 32 33Until it's fixed let's hardcode header mangling if $NIX_STORE variable 34is present in the environment. 35 36Tested as: 37 38 $ printf "# 0 \"/nix/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-pppppp-vvvvvvv\" \nconst char * f(void) { return __FILE__; }" | NIX_STORE=/nix/store ./gcc/xgcc -Bgcc -x c - -S -o - 39 ... 40 .string "/nix/store/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-pppppp-vvvvvvv" 41 ... 42 43Mangled successfully. 44 45To reverse the effect of the mangle use new `NIX_GCC_DONT_MANGLE_PREFIX_MAP` 46environment variable. It should not normally be needed. 47--- a/gcc/file-prefix-map.cc 48+++ b/gcc/file-prefix-map.cc 49@@ -74,7 +74,7 @@ add_prefix_map (file_prefix_map *&maps, const char *arg, const char *opt) 50 remapping was performed. */ 51 52 static const char * 53-remap_filename (file_prefix_map *maps, const char *filename) 54+remap_filename (file_prefix_map *maps, const char *filename, bool mangle_nix_store = false) 55 { 56 file_prefix_map *map; 57 char *s; 58@@ -102,6 +102,30 @@ remap_filename (file_prefix_map *maps, const char *filename) 59 break; 60 if (!map) 61 { 62+ if (mangle_nix_store && getenv("NIX_GCC_DONT_MANGLE_PREFIX_MAP") == NULL) 63+ { 64+ /* Remap all fo $NIX_STORE/.{32} paths to uppercase 65+ * 66+ * That way we avoid argument parameters explosion 67+ * and still avoid embedding headers into runtime closure: 68+ * https://gcc.gnu.org/PR111527 69+ */ 70+ char * nix_store = getenv("NIX_STORE"); 71+ size_t nix_store_len = nix_store ? strlen(nix_store) : 0; 72+ const char * name = realname ? realname : filename; 73+ size_t name_len = strlen(name); 74+ if (nix_store && name_len >= nix_store_len + 1 + 32 && memcmp(name, nix_store, nix_store_len) == 0) 75+ { 76+ s = (char *) ggc_alloc_atomic (name_len + 1); 77+ memcpy(s, name, name_len + 1); 78+ for (size_t i = nix_store_len + 1; i < nix_store_len + 1 + 32; i++) { 79+ s[i] = TOUPPER(s[i]); 80+ } 81+ if (realname != filename) 82+ free (const_cast <char *> (realname)); 83+ return s; 84+ } 85+ } 86 if (realname != filename) 87 free (const_cast <char *> (realname)); 88 return filename; 89@@ -163,7 +187,7 @@ add_profile_prefix_map (const char *arg) 90 const char * 91 remap_macro_filename (const char *filename) 92 { 93- return remap_filename (macro_prefix_maps, filename); 94+ return remap_filename (macro_prefix_maps, filename, true); 95 } 96 97 /* Remap using -fdebug-prefix-map. Return the GC-allocated new name