admin管理员组文章数量:1435859
I am attempting to write a function which takes as input a Nix derivation (any derivation which can build with clang), and as output, returns a modified version of the derivation that builds with compiler flags of my choosing, namely -fsanitize=
flags.
I have written something that works in many cases, but it often fails because the linker is unable to find the clang runtime shared library symbols. It seems to be only looking at gcc sanitizer symbols, which are similar but not the same as the clang ones.
I think this should be possible, as it's only a matter of compiling a previously-working derivation with different compiler flags, but I cannot figure out how to resolve the linker issue. My approach works when using gcc asan, but I need to use clang, because it has sanitizers not present in gcc (for example, the fuzzer sanitizer).
An example of something that works with my function is the relatively simple libtasn1 library. An example of something that does not work is openssl.
openssl can be compiled with a clangStdenv
derivation. I think the issue is not clang, but rather ld
not being aware of the symbols in things like libclang_rt.asan-x86_64.so
from the LLVM resource directory.
I imagine this would be easier if I were using lld
, but that doesn't seem to be properly supported on NixOS.
Please note that I am not asking how to build openssl with sanitizers. I am asking how to build an arbitrary derivation with them, and using openssl as an example.
Also please note that I am not asking for a way to configure the underlying build system called by the derivation. I would like the approach to be build-system-agnostic, which should be possible since Nix only presents a wrapped version of the compiler binary during the build process, which it can inject flags into irrespective of whether or not they are understood by the underlying build system. Nix is able to accomplish similar things regarding its hardening settings by changing the configuration used for the wrapped compiler binaries.
The errors that I get look like this:
/nix/store/3r87a2wq1w4l66wnsm7rqvy608mx23h6-binutils-2.40/bin/ld: /build/openssl-3.0.11/test/p_test.c:181: undefined reference to `__asan_report_store4'
/nix/store/3r87a2wq1w4l66wnsm7rqvy608mx23h6-binutils-2.40/bin/ld: /build/openssl-3.0.11/test/p_test.c:83: undefined reference to `__asan_report_load8'
/nix/store/3r87a2wq1w4l66wnsm7rqvy608mx23h6-binutils-2.40/bin/ld: test/p_test-dso-p_test.o: in function `p_teardown':
/build/openssl-3.0.11/test/p_test.c:311: undefined reference to `__sancov_lowest_stack'
/nix/store/3r87a2wq1w4l66wnsm7rqvy608mx23h6-binutils-2.40/bin/ld: /build/openssl-3.0.11/test/p_test.c:317: undefined reference to `__asan_report_load8'
/nix/store/3r87a2wq1w4l66wnsm7rqvy608mx23h6-binutils-2.40/bin/ld: /build/openssl-3.0.11/test/p_test.c:318: undefined reference to `__asan_report_load8'
/nix/store/3r87a2wq1w4l66wnsm7rqvy608mx23h6-binutils-2.40/bin/ld: test/p_test-dso-p_test.o: in function `sancov.module_ctor_8bit_counters':
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)
This is the file I am using:
# test with
# nix-build -E 'with import <nixpkgs> {}; callPackage ./test_instrument_derivation.nix {}'
{ nixpkgs ? import <nixpkgs> {} }: let
# tried adding overlay here to replace stdenv with clangStdenv
# but it often got stuck compiling huge amounts of stuff and breaking
# before even getting to the package I want to build
pkgs = import <nixpkgs> {};
# make a clangStdenv derivation out of another derivation and
# add some extra configuration. use clang because not all of the functionality of the clang
# sanitizers is present in gcc, for example, -fsanitize=fuzzer
instrumentLibraryDerivation = orig : (pkgs.clangStdenv.mkDerivation orig.drvAttrs).overrideAttrs (oldAttrs: {
preBuild = ''
${oldAttrs.preBuild}
# setting the clang sanitizer compile flags
# doing this after the configure stage because the sanitizers often
# confuse configure scripts when they try to autodetect compiler features
# sigaltstack=0 seems to be required on nixos or else asan/ubsan binaries don't work
# suppress asan detections that might trigger if binaries are run during the build/test phases
export ASAN_OPTIONS=use_sigaltstack=0,detect_leaks=0
export UBSAN_OPTIONS=use_sigaltstack=false
# these are sufficient to compile a simple hello world binary with the right instrumentation
export NIX_CFLAGS_COMPILE=" $NIX_CFLAGS_COMPILE -fsanitize=fuzzer-no-link,address"
# tried things like:
# -fuse-ld=lld
# export LD=lld
# -lasan
# -Wl,-lasan
# -L$(clang -print-file-name="libclang_rt.asan-x86_64.so")
# -Wl,$(clang -print-file-name="libclang_rt.asan-x86_64.so")
'';
# trying to avoid including anything with GCC here
depsBuildBuild = [ pkgs.buildPackages.clangStdenv pkgs.buildPackages.clangStdenv ];
nativeBuildInputs = (oldAttrs.nativeBuildInputs or []) ++ [
# trying to make the clang runtime libraries available
# not working :(
pkgs.llvmPackages.clang
pkgs.llvmPackagespiler-rt
];
# ASAN sometimes changes the behavior of unit tests and breaks them, so skip check
doCheck = false;
outputs = [ "out" ];
}
);
in
# despite working with simpler derivations, this instrument derivation function causes linker errors
# in things like openSSL. this seems to be because it uses bintools ld to link, which is not aware of
# the clang runtime libraries. this is sometimes easier to see with -fsanitize=fuzzer-no-link, because
# that doesn't exist in gcc. sometimes it can find asan symbols, but they're incompatible since they're
# for GCC asan instead of clang asan.
instrumentLibraryDerivation pkgs.openssl
# this works fine with simple things like libtasn1
#
# instrumentLibraryDerivation pkgs.libtasn1
#
# $ nm result/lib/libtasn1.so | grep sancov
#
# 0000000000034010 d __sancov_gen_cov_switch_values
# 0000000000034530 d __sancov_gen_cov_switch_values
# 00000000000346e0 d __sancov_gen_cov_switch_values
# 0000000000034880 d __sancov_gen_cov_switch_values
# 0000000000034b00 d __sancov_gen_cov_switch_values
#
# ...
#
本文标签: linker errorsHow to compile preexisting nix derivation with Clang sanitizersStack Overflow
版权声明:本文标题:linker errors - How to compile preexisting nix derivation with Clang sanitizers - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745670668a2669547.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论