Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions pkgs/development/compilers/llvm/20/clang/macro_file_mangling.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
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` and `clang` 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
This patch to `clang` is a copy of the corresponding `gcc` patch so the same
approach was kept.

This patch 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_CLANG_DONT_MANGLE_PREFIX_MAP`
environment variable. It should not normally be needed.

The ability to go back to the original store path is relied on by
nixseparatedebuginfod, for example.
--- clang/lib/Basic/LangOptions.cpp
+++ clang/lib/Basic/LangOptions.cpp
@@ -12,6 +12,8 @@

#include "clang/Basic/LangOptions.h"
#include "llvm/Support/Path.h"
+#include <cctype>
+#include <cstdlib>

using namespace clang;

@@ -76,6 +78,21 @@ void LangOptions::remapPathPrefix(SmallVectorImpl<char> &Path) const {
for (const auto &Entry : MacroPrefixMap)
if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second))
break;
+ if (std::getenv("NIX_CLANG_DONT_MANGLE_PREFIX_MAP") == nullptr) {
+ char* nix_store = getenv("NIX_STORE");
+ if (nix_store == nullptr) {
+ return;
+ }
+ size_t nix_store_len = strlen(nix_store);
+ if (Path.size() <= nix_store_len + 1 + 32) {
+ return;
+ }
+ if (std::equal(Path.begin(), Path.begin() + nix_store_len, nix_store)) {
+ for (auto c = Path.begin() + nix_store_len + 1; c < Path.begin() + nix_store_len + 1 + 32; c++) {
+ *c = std::toupper(*c);
+ }
+ }
+ }
}

std::string LangOptions::getOpenCLVersionString() const {
1 change: 1 addition & 0 deletions pkgs/development/compilers/llvm/common/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ stdenv.mkDerivation (
patches =
[
(getVersionFile "clang/purity.patch")
(getVersionFile "clang/macro_file_mangling.patch")
# Remove extraneous ".a" suffix from baremetal clang_rt.builtins when compiling for baremetal.
# https://reviews.llvm.org/D51899
(getVersionFile "clang/gnu-install-dirs.patch")
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/compilers/llvm/common/patches.nix
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
path = ../12;
}
];
"clang/macro_file_mangling.patch" = [
{
after = "19";
path = ../20;
}
];
"clang/aarch64-tblgen.patch" = [
{
after = "17";
Expand Down
Loading