Skip to content

Commit

Permalink
llvm: Fix compiler-rt missing sanitizers when using useLLVM
Browse files Browse the repository at this point in the history
(cherry picked from commit 344902e)
  • Loading branch information
s1341 authored and github-actions[bot] committed Jul 29, 2024
1 parent fc2fc81 commit b9bd166
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 69 deletions.
88 changes: 65 additions & 23 deletions pkgs/development/compilers/llvm/12/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
, preLibcCrossHeaders
, substitute, substituteAll, fetchFromGitHub, fetchpatch, fetchurl
, overrideCC, wrapCCWith, wrapBintoolsWith
, libxcrypt
, buildLlvmTools # tools, but from the previous stage, for cross
, targetLlvmLibraries # libraries, but from the next stage, for cross
, targetLlvm
Expand Down Expand Up @@ -49,6 +50,10 @@ let
ln -s "${cc.lib}/lib/clang/${metadata.release_version}/include" "$rsrc"
echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
'';
mkExtraBuildCommandsBasicRt = cc: mkExtraBuildCommands0 cc + ''
ln -s "${targetLlvmLibraries.compiler-rt-no-libc.out}/lib" "$rsrc/lib"
ln -s "${targetLlvmLibraries.compiler-rt-no-libc.out}/share" "$rsrc/share"
'';
mkExtraBuildCommands = cc: mkExtraBuildCommands0 cc + ''
ln -s "${targetLlvmLibraries.compiler-rt.out}/lib" "$rsrc/lib"
ln -s "${targetLlvmLibraries.compiler-rt.out}/share" "$rsrc/share"
Expand Down Expand Up @@ -245,34 +250,50 @@ let
'' + mkExtraBuildCommands cc;
};

clangNoLibcxx = wrapCCWith rec {
clangWithLibcAndBasicRtAndLibcxx = wrapCCWith rec {
cc = tools.clang-unwrapped;
libcxx = targetLlvmLibraries.libcxx;
bintools = bintools';
extraPackages = [
targetLlvmLibraries.compiler-rt-no-libc
] ++ lib.optionals (!stdenv.targetPlatform.isWasm) [
targetLlvmLibraries.libunwind
];
extraBuildCommands = ''
echo "-rtlib=compiler-rt" >> $out/nix-support/cc-cflags
echo "-Wno-unused-command-line-argument" >> $out/nix-support/cc-cflags
echo "-B${targetLlvmLibraries.compiler-rt-no-libc}/lib" >> $out/nix-support/cc-cflags
'' + mkExtraBuildCommandsBasicRt cc;
};

clangWithLibcAndBasicRt = wrapCCWith rec {
cc = tools.clang-unwrapped;
libcxx = null;
bintools = bintools';
extraPackages = [
targetLlvmLibraries.compiler-rt
targetLlvmLibraries.compiler-rt-no-libc
];
extraBuildCommands = ''
echo "-rtlib=compiler-rt" >> $out/nix-support/cc-cflags
echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
echo "-B${targetLlvmLibraries.compiler-rt-no-libc}/lib" >> $out/nix-support/cc-cflags
echo "-nostdlib++" >> $out/nix-support/cc-cflags
'' + mkExtraBuildCommands cc;
'' + mkExtraBuildCommandsBasicRt cc;
};

clangNoLibc = wrapCCWith rec {
clangNoLibcWithBasicRt = wrapCCWith rec {
cc = tools.clang-unwrapped;
libcxx = null;
bintools = bintoolsNoLibc';
extraPackages = [
targetLlvmLibraries.compiler-rt
targetLlvmLibraries.compiler-rt-no-libc
];
extraBuildCommands = ''
echo "-rtlib=compiler-rt" >> $out/nix-support/cc-cflags
echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags
'' + mkExtraBuildCommands cc;
echo "-B${targetLlvmLibraries.compiler-rt-no-libc}/lib" >> $out/nix-support/cc-cflags
'' + mkExtraBuildCommandsBasicRt cc;
};

clangNoCompilerRt = wrapCCWith rec {
clangNoLibcNoRt = wrapCCWith rec {
cc = tools.clang-unwrapped;
libcxx = null;
bintools = bintoolsNoLibc';
Expand All @@ -282,6 +303,8 @@ let
'' + mkExtraBuildCommands0 cc;
};

# This is an "oddly ordered" bootstrap just for Darwin. Probably
# don't want it otherwise.
clangNoCompilerRtWithLibc = wrapCCWith rec {
cc = tools.clang-unwrapped;
libcxx = null;
Expand All @@ -290,13 +313,23 @@ let
extraBuildCommands = mkExtraBuildCommands0 cc;
};

# Aliases
clangNoCompilerRt = tools.clangNoLibcNoRt;
clangNoLibc = tools.clangNoLibcWithBasicRt;
clangNoLibcxx = tools.clangWithLibcAndBasicRt;
});

libraries = lib.makeExtensible (libraries: let
callPackage = newScope (libraries // buildLlvmTools // args // metadata);
in {

compiler-rt-libc = callPackage ../common/compiler-rt {
compiler-rt-libc = callPackage ../common/compiler-rt (let
stdenv =
if args.stdenv.hostPlatform.useLLVM or false then
overrideCC args.stdenv buildLlvmTools.clangWithLibcAndBasicRtAndLibcxx
else
args.stdenv;
in {
src = fetch "compiler-rt" "1950rg294izdwkaasi7yjrmadc9mzdd5paf0q63jjcq2m3rdbj5l";
patches = [
../common/compiler-rt/7-12-codesign.patch # Revert compiler-rt commit that makes codesign mandatory
Expand All @@ -312,10 +345,12 @@ let
../common/compiler-rt/armv6-sync-ops-no-thumb.patch
../common/compiler-rt/armv6-no-ldrexd-strexd.patch
];
stdenv = if stdenv.hostPlatform.useLLVM or false
then overrideCC stdenv buildLlvmTools.clangNoCompilerRtWithLibc
else stdenv;
};
inherit stdenv;
} // lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) {
libxcrypt = (libxcrypt.override { inherit stdenv; }).overrideAttrs (old: {
configureFlags = old.configureFlags ++ [ "--disable-symvers" ];
});
});

compiler-rt-no-libc = callPackage ../common/compiler-rt {
src = fetch "compiler-rt" "1950rg294izdwkaasi7yjrmadc9mzdd5paf0q63jjcq2m3rdbj5l";
Expand All @@ -333,15 +368,22 @@ let
../common/compiler-rt/armv6-sync-ops-no-thumb.patch
../common/compiler-rt/armv6-no-ldrexd-strexd.patch
];
stdenv = if stdenv.hostPlatform.useLLVM or false
then overrideCC stdenv buildLlvmTools.clangNoCompilerRt
else stdenv;
stdenv =
if stdenv.hostPlatform.isDarwin && stdenv.hostPlatform == stdenv.buildPlatform then
stdenv
else
# TODO: make this branch unconditional next rebuild
overrideCC stdenv buildLlvmTools.clangNoLibcNoRt;
};

# N.B. condition is safe because without useLLVM both are the same.
compiler-rt = if stdenv.hostPlatform.isAndroid
then libraries.compiler-rt-libc
else libraries.compiler-rt-no-libc;
compiler-rt =
# Building the with-libc compiler-rt and WASM doesn't yet work,
# because wasilibc doesn't provide some expected things. See
# compiler-rt's file for further details.
if stdenv.hostPlatform.libc == null || stdenv.hostPlatform.isWasm then
libraries.compiler-rt-no-libc
else
libraries.compiler-rt-libc;

stdenv = overrideCC stdenv buildLlvmTools.clang;

Expand Down Expand Up @@ -376,15 +418,15 @@ let
];
})
];
stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
stdenv = overrideCC stdenv buildLlvmTools.clangWithLibcAndBasicRt;
};

libunwind = callPackage ../common/libunwind {
src = fetch "libunwind" "192ww6n81lj2mb9pj4043z79jp3cf58a9c2qrxjwm5c3a64n1shb";
patches = [
./libunwind/gnu-install-dirs.patch
];
stdenv = overrideCC stdenv buildLlvmTools.clangNoLibcxx;
stdenv = overrideCC stdenv buildLlvmTools.clangWithLibcAndBasicRt;
};

openmp = callPackage ../common/openmp {
Expand Down
39 changes: 28 additions & 11 deletions pkgs/development/compilers/llvm/common/compiler-rt/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
, python3
, xcbuild
, libllvm
, libcxx
, linuxHeaders
, libxcrypt

Expand All @@ -33,6 +34,9 @@ let
useLLVM = stdenv.hostPlatform.useLLVM or false;
bareMetal = stdenv.hostPlatform.parsed.kernel.name == "none";
haveLibc = stdenv.cc.libc != null;
# TODO: Make this account for GCC having libstdcxx, which will help
# use clean up the `cmakeFlags` rats nest below.
haveLibcxx = stdenv.cc.libcxx != null;
isDarwinStatic = stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isStatic && lib.versionAtLeast release_version "16";
inherit (stdenv.hostPlatform) isMusl isAarch64;

Expand All @@ -46,7 +50,7 @@ let
cp -r ${monorepoSrc}/${baseName} "$out"
'' else src;

preConfigure = lib.optionalString (useLLVM && !haveLibc) ''
preConfigure = lib.optionalString (!haveLibc) ''
cmakeFlagsArray+=(-DCMAKE_C_FLAGS="-nodefaultlibs -ffreestanding")
'';
in
Expand Down Expand Up @@ -82,23 +86,32 @@ stdenv.mkDerivation ({
"-DCMAKE_ASM_COMPILER_TARGET=${stdenv.hostPlatform.config}"
] ++ lib.optionals (haveLibc && stdenv.hostPlatform.libc == "glibc") [
"-DSANITIZER_COMMON_CFLAGS=-I${libxcrypt}/include"
] ++ lib.optionals ((useLLVM || bareMetal || isMusl || isAarch64) && (lib.versions.major release_version == "13")) [
] ++ lib.optionals (useLLVM && haveLibc && stdenv.cc.libcxx == libcxx) [
"-DSANITIZER_CXX_ABI=libcxxabi"
"-DSANITIZER_CXX_ABI_LIBNAME=libcxxabi"
"-DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON"
] ++ lib.optionals ((!haveLibc || bareMetal || isMusl || isAarch64) && (lib.versions.major release_version == "13")) [
"-DCOMPILER_RT_BUILD_LIBFUZZER=OFF"
] ++ lib.optionals (useLLVM || bareMetal || isMusl || isDarwinStatic) [
] ++ lib.optionals (useLLVM && haveLibc) [
"-DCOMPILER_RT_BUILD_SANITIZERS=ON"
] ++ lib.optionals (!haveLibc || bareMetal || isMusl || isDarwinStatic) [
"-DCOMPILER_RT_BUILD_SANITIZERS=OFF"
] ++ lib.optionals ((useLLVM && !haveLibcxx) || !haveLibc || bareMetal || isMusl || isDarwinStatic) [
"-DCOMPILER_RT_BUILD_XRAY=OFF"
"-DCOMPILER_RT_BUILD_LIBFUZZER=OFF"
"-DCOMPILER_RT_BUILD_MEMPROF=OFF"
"-DCOMPILER_RT_BUILD_ORC=OFF" # may be possible to build with musl if necessary
] ++ lib.optionals (useLLVM || bareMetal) [
] ++ lib.optionals (useLLVM && haveLibc) [
"-DCOMPILER_RT_BUILD_PROFILE=ON"
] ++ lib.optionals (!haveLibc || bareMetal) [
"-DCOMPILER_RT_BUILD_PROFILE=OFF"
] ++ lib.optionals ((useLLVM && !haveLibc) || bareMetal || isDarwinStatic) [
] ++ lib.optionals (!haveLibc || bareMetal || isDarwinStatic) [
"-DCMAKE_CXX_COMPILER_WORKS=ON"
] ++ lib.optionals ((useLLVM && !haveLibc) || bareMetal) [
] ++ lib.optionals (!haveLibc || bareMetal) [
"-DCMAKE_C_COMPILER_WORKS=ON"
"-DCOMPILER_RT_BAREMETAL_BUILD=ON"
"-DCMAKE_SIZEOF_VOID_P=${toString (stdenv.hostPlatform.parsed.cpu.bits / 8)}"
] ++ lib.optionals (useLLVM && !haveLibc) [
] ++ lib.optionals (!haveLibc) [
"-DCMAKE_C_FLAGS=-nodefaultlibs"
] ++ lib.optionals (useLLVM) [
"-DCOMPILER_RT_BUILD_BUILTINS=ON"
Expand Down Expand Up @@ -133,7 +146,7 @@ stdenv.mkDerivation ({
'' + lib.optionalString stdenv.isDarwin ''
substituteInPlace cmake/config-ix.cmake \
--replace 'set(COMPILER_RT_HAS_TSAN TRUE)' 'set(COMPILER_RT_HAS_TSAN FALSE)'
'' + lib.optionalString (useLLVM && !haveLibc) ((lib.optionalString (lib.versionAtLeast release_version "18") ''
'' + lib.optionalString (!haveLibc) ((lib.optionalString (lib.versionAtLeast release_version "18") ''
substituteInPlace lib/builtins/aarch64/sme-libc-routines.c \
--replace "<stdlib.h>" "<stddef.h>"
'') + ''
Expand Down Expand Up @@ -179,8 +192,12 @@ stdenv.mkDerivation ({
# "All of the code in the compiler-rt project is dual licensed under the MIT
# license and the UIUC License (a BSD-like license)":
license = with lib.licenses; [ mit ncsa ];
# compiler-rt requires a Clang stdenv on 32-bit RISC-V:
# https://reviews.llvm.org/D43106#1019077
broken = stdenv.hostPlatform.isRiscV32 && !stdenv.cc.isClang;
broken =
# compiler-rt requires a Clang stdenv on 32-bit RISC-V:
# https://reviews.llvm.org/D43106#1019077
(stdenv.hostPlatform.isRiscV32 && !stdenv.cc.isClang)
# emutls wants `<pthread.h>` which isn't avaiable (without exeprimental WASM threads proposal).
# `enable_execute_stack.c` Also doesn't sound like something WASM would support.
|| (stdenv.hostPlatform.isWasm && haveLibc);
};
} // (if lib.versionOlder release_version "16" then { inherit preConfigure; } else {}))
Loading

0 comments on commit b9bd166

Please sign in to comment.