Created
October 29, 2022 11:32
-
-
Save rrbutani/92021b86f1cbfd178d2f580bed440aec to your computer and use it in GitHub Desktop.
nixpkgs darwin stdenv `LC_UUID`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
inputs = { | |
nixpkgs.url = github:NixOS/nixpkgs?ref=60b1608ad793c763ffbeabddc95dba7b4ed9cbc8; # nixos-unstable as of this writing | |
flu.url = github:numtide/flake-utils; | |
}; | |
outputs = { nixpkgs, flu, self }: | |
with flu.lib; eachSystem [ "aarch64-darwin" "x86_64-darwin" ] (system: let | |
# The `nixpkgs` bintools wrapper passes `-no_uuid` to `ld` when targeting | |
# macOS which causes `ld` to omit `LC_UUID`. | |
# | |
# Some tools (crash reporters, debuggers) use this metadata to associate | |
# binaries with debug info; other tools (like Xcode Instruments) will | |
# actually refuse to load symbols (dSYM files) if this UUID is not | |
# present. | |
# | |
# `nixpkgs`'s first started to pass `-no_uuid` on macOS here: | |
# - https://github.com/NixOS/nixpkgs/commit/a826b49c97bcc9d8365b5d18aeec8087116d195d | |
# - PR: https://github.com/NixOS/nixpkgs/pull/77632 | |
# - context: | |
# https://github.com/NixOS/nixpkgs/issues/21629#issuecomment-398266212 | |
# | |
# Since then this flag has migrated from the macOS stdenv to the bintools | |
# wrapper: | |
# https://github.com/NixOS/nixpkgs/blob/19f597b8cc2dd2ab41ae77a4ad607876007a7da8/pkgs/build-support/bintools-wrapper/default.nix#L311-L316 | |
# | |
# The commit linked above claims that the the `LC_UUID` UUID is | |
# "semi-random" however: | |
# - LLD appears to use a hash of the output file's contents: | |
# https://github.com/llvm/llvm-project/blob/efae1a7cf06bd71f7ec6e8dc9e5c2b085150a451/lld/MachO/Writer.cpp#L504-L509 | |
# - as per [this message](https://groups.google.com/a/chromium.org/g/security-dev/c/xAL44GDnaVI) | |
# and the source code it references, `ld64` from `cctools` appears to | |
# hash specific parts of the output | |
# So, in an attempt to find out whether we can safely drop `-no_uuid` from | |
# the `nixpkgs` bintools wrapper, the below conjures a stdenv with this | |
# change applied and then checks the resulting UUIDs of some binaries in | |
# some packages. | |
# | |
# Run `nix flake check` on your x86_64 or apple silicon mac to see if the | |
# UUIDs your machine produces match mine. | |
# The proper thing to do here would be to use an overlay but we don't want | |
# to suffer through a full rebuild of everything... | |
np = nixpkgs.legacyPackages.${system}; | |
stdenv = let | |
bintools = np.stdenv.cc.bintools.overrideDerivation (attrs: { | |
# We're looking to undo this bit: | |
# https://github.com/NixOS/nixpkgs/blob/19f597b8cc2dd2ab41ae77a4ad607876007a7da8/pkgs/build-support/bintools-wrapper/default.nix#L311-L316 | |
postFixup = attrs.postFixup + '' | |
sed -i 's/-no_uuid//g' $out/nix-support/libc-ldflags-before | |
''; | |
}); | |
cc = np.stdenv.cc.override { inherit bintools; }; | |
in np.stdenv.override { inherit cc; allowedRequisites = null; }; | |
# If you do want to suffer through a rebuild.. | |
npAlt = import nixpkgs { | |
inherit system; | |
overlays = [(f: p: { | |
bintools = p.bintools.overrideDerivation (attrs: { | |
postFixup = attrs.postFixup + '' | |
sed -i 's/-no_uuid//g' $out/nix-support/libc-ldflags-before | |
''; | |
}); | |
})]; | |
config.replaceStdenv = { pkgs }: pkgs.stdenv.override { | |
cc = pkgs.stdenv.cc.override { | |
bintools = pkgs.stdenv.cc.bintools.overrideDerivation (attrs: { | |
postFixup = attrs.postFixup + '' | |
sed -i 's/-no_uuid//g' $out/nix-support/libc-ldflags-before | |
''; | |
}); | |
}; | |
}; | |
}; | |
checkUuidMatches = { package, uuids, mainProgram ? null }: let | |
pkg = if mainProgram != null then package // { meta = { inherit mainProgram; }; } else package; | |
isArm = np.targetPlatform.isAarch64; | |
expected = uuids.${if isArm then "arm" else "x86"}; | |
in np.runCommand | |
"check-uuid-${pkg.pname or pkg.name}" | |
{ nativeBuildInputs = [ np.llvmPackages.bintools-unwrapped ]; } | |
'' | |
set -e | |
bin="${np.lib.getExe pkg}" | |
echo "checking '$bin'" | |
expected="${expected}" | |
got=$( | |
llvm-dwarfdump --uuid "$bin" | | |
grep "${if isArm then "arm64" else "x86_64"}" | | |
cut -d' ' -f2 | | |
head -1 | |
) | |
if [[ $expected != $got ]]; then | |
echo "expected UUID: '$expected'" | |
echo "got UUID: '$got'" | |
exit 2 | |
fi | |
echo $got > $out | |
''; | |
uuidPair = arm: x86: { inherit arm x86; }; | |
packageUuids = { | |
hello = { | |
package = np.hello.override { inherit stdenv; }; | |
uuids = uuidPair "FD76B509-06B2-3E8E-A3F8-A73AB271FEA2" ""; | |
}; | |
fortune = { | |
package = np.fortune.override { inherit stdenv; }; | |
# uuids = uuidPair "30507B82-1901-34E7-8443-942D32EDAB0C" ""; | |
uuids = uuidPair "DF23713F-5604-36DB-82DA-4965E74AE8CC" ""; | |
}; | |
bat = { | |
# package = np.bat.override { inherit stdenv rustPlatform; }; | |
package = npAlt.bat; | |
mainProgram = ".bat-wrapped"; | |
uuids = uuidPair "" ""; | |
}; | |
bash = { | |
# package = np.bash.override { inherit stdenv; binutils = stdenv.cc.bintools; }; | |
package = npAlt.bash; | |
uuids = uuidPair "" ""; | |
}; | |
}; | |
in rec { | |
packages = builtins.mapAttrs (_: { package, ... }: package) packageUuids; | |
checks = builtins.mapAttrs (_: checkUuidMatches) packageUuids; | |
}); | |
# Unfortunately, testing the above shows that (when using `ld` from | |
# cctools) the UUID is not stable (change the fixup addendum a bit and | |
# rebuild the fortune check -- seems to change as the build directory | |
# changes). | |
# | |
# See: https://bugs.chromium.org/p/chromium/issues/detail?id=1068970 | |
# LLD allegedly does not have this issue (a quick read of the relevant | |
# source in LLD corroborates this). | |
# | |
# However the darwin stdenv does not use LLD (though, it could now that | |
# mach-o support is there in LLD in LLVM14+). | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment