0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-14 14:10:33 +03:00

gcc: prevent runtime references via __FILE__ but in a reversible manner

the mangling done by mangle-NIX_STORE-in-__FILE__.patch also applies to
source paths embedded in debug symbols. When putting a breakpoint in a
template instanciation from another lib, the path that gdb looks for is
therefore mangled (/nix/store/eeeeeee;...-the-lib-dev/include/foo.h)
This severely degrades the debugging experience. To alleviate that, it's
possible to make the mangling reversible: a debuginfod server can then
reverse the mangling. I plan to implement that in nixseparatedebuginfod.
The reversible mangling that was chosen in making the hash of the store
path uppercase.
This commit is contained in:
Guillaume Girol 2024-01-07 12:00:00 +00:00
parent bd645e8668
commit 9cb3614007
2 changed files with 40 additions and 17 deletions

View file

@ -12,9 +12,20 @@ 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...` but those paths are also used for debug symbols. It is
handy to be able to invert the transformation to go back to the original
store path for debuginfod servers. 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/eeee.eee-nlohmann-json-ver
-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`
@ -25,9 +36,9 @@ is present in the environment.
Tested as:
$ printf "# 0 \"/nix/store/01234567890123456789012345678901-pppppp-vvvvvvv\" \nconst char * f(void) { return __FILE__; }" | NIX_STORE=/nix/store ./gcc/xgcc -Bgcc -x c - -S -o -
$ 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/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-pppppp-vvvvvvv"
.string "/nix/store/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-pppppp-vvvvvvv"
...
Mangled successfully.
@ -43,7 +54,7 @@ Mangled successfully.
/* Perform user-specified mapping of filename prefixes. Return the
GC-allocated new name corresponding to FILENAME or FILENAME if no
remapping was performed. */
@@ -76,7 +79,30 @@ remap_filename (file_prefix_map *maps, const char *filename)
@@ -76,7 +79,31 @@ remap_filename (file_prefix_map *maps, const char *filename)
if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0)
break;
if (!map)
@ -51,8 +62,7 @@ Mangled successfully.
+ {
+ if (maps == macro_prefix_maps)
+ {
+ /* Remap all fo $NIX_STORE/.{32} paths to
+ * equivalent $NIX_STORE/e{32}.
+ /* Remap the 32 characters after $NIX_STORE/ to uppercase
+ *
+ * That way we avoid argument parameters explosion
+ * and still avoid embedding headers into runtime closure:
@ -66,7 +76,9 @@ Mangled successfully.
+ {
+ s = (char *) ggc_alloc_atomic (name_len + 1);
+ memcpy(s, name, name_len + 1);
+ memset(s + nix_store_len + 1, 'e', 32);
+ for (int i = nix_store_len + 1; i < nix_store_len + 1 + 32; i++) {
+ s[i] = TOUPPER(s[i]);
+ }
+ return s;
+ }
+ }
@ -75,7 +87,7 @@ Mangled successfully.
name = filename + map->old_len;
name_len = strlen (name) + 1;
@@ -90,7 +116,6 @@ remap_filename (file_prefix_map *maps, const char *filename)
@@ -90,7 +117,6 @@ remap_filename (file_prefix_map *maps, const char *filename)
ignore it in DW_AT_producer (dwarf2out.cc). */
/* Linked lists of file_prefix_map structures. */

View file

@ -12,9 +12,20 @@ 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...` but those paths are also used for debug symbols. It is
handy to be able to invert the transformation to go back to the original
store path for debuginfod servers. 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/eeee.eee-nlohmann-json-ver
-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`
@ -25,9 +36,9 @@ is present in the environment.
Tested as:
$ printf "# 0 \"/nix/store/01234567890123456789012345678901-pppppp-vvvvvvv\" \nconst char * f(void) { return __FILE__; }" | NIX_STORE=/nix/store ./gcc/xgcc -Bgcc -x c - -S -o -
$ 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/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-pppppp-vvvvvvv"
.string "/nix/store/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-pppppp-vvvvvvv"
...
Mangled successfully.
@ -43,14 +54,13 @@ Mangled successfully.
/* Perform user-specified mapping of filename prefixes. Return the
GC-allocated new name corresponding to FILENAME or FILENAME if no
remapping was performed. */
@@ -102,6 +105,29 @@ remap_filename (file_prefix_map *maps, const char *filename)
@@ -102,6 +105,30 @@ remap_filename (file_prefix_map *maps, const char *filename)
break;
if (!map)
{
+ if (maps == macro_prefix_maps)
+ {
+ /* Remap all fo $NIX_STORE/.{32} paths to
+ * equivalent $NIX_STORE/e{32}.
+ /* Remap all fo $NIX_STORE/.{32} paths to uppercase
+ *
+ * That way we avoid argument parameters explosion
+ * and still avoid embedding headers into runtime closure:
@ -64,7 +74,9 @@ Mangled successfully.
+ {
+ s = (char *) ggc_alloc_atomic (name_len + 1);
+ memcpy(s, name, name_len + 1);
+ memset(s + nix_store_len + 1, 'e', 32);
+ for (int 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;
@ -73,7 +85,7 @@ Mangled successfully.
if (realname != filename)
free (const_cast <char *> (realname));
return filename;
@@ -124,7 +150,6 @@ remap_filename (file_prefix_map *maps, const char *filename)
@@ -124,7 +151,6 @@ remap_filename (file_prefix_map *maps, const char *filename)
ignore it in DW_AT_producer (gen_command_line_string in opts.cc). */
/* Linked lists of file_prefix_map structures. */
@ -81,4 +93,3 @@ Mangled successfully.
static file_prefix_map *debug_prefix_maps; /* -fdebug-prefix-map */
static file_prefix_map *profile_prefix_maps; /* -fprofile-prefix-map */