mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-18 15:56:50 +01:00
bintools-wrapper: skip dynamic linker for static binaries
Currently we set dynamic-linker unconditionally. This breaks however some static binaries i.e. rust binaries linked against musl. There is no reason we should set an elf interpreter for static binaries hence this is skipped if `-static` or `-static-pie` is either passed to our cc or ld wrapper.
This commit is contained in:
parent
c2842e5ad4
commit
ccfd26ef14
5 changed files with 40 additions and 12 deletions
|
@ -3,6 +3,7 @@ var_templates_list=(
|
|||
NIX_IGNORE_LD_THROUGH_GCC
|
||||
NIX_LDFLAGS
|
||||
NIX_LDFLAGS_BEFORE
|
||||
NIX_DYNAMIC_LINKER
|
||||
NIX_LDFLAGS_AFTER
|
||||
NIX_LDFLAGS_HARDEN
|
||||
NIX_HARDENING_ENABLE
|
||||
|
@ -25,6 +26,10 @@ if [ -e @out@/nix-support/libc-ldflags ]; then
|
|||
NIX_LDFLAGS_@suffixSalt@+=" $(< @out@/nix-support/libc-ldflags)"
|
||||
fi
|
||||
|
||||
if [ -z "$NIX_DYNAMIC_LINKER_@suffixSalt@" ] && [ -e @out@/nix-support/dynamic-linker ]; then
|
||||
NIX_DYNAMIC_LINKER_@suffixSalt@="$(< @out@/nix-support/dynamic-linker)"
|
||||
fi
|
||||
|
||||
if [ -e @out@/nix-support/libc-ldflags-before ]; then
|
||||
NIX_LDFLAGS_BEFORE_@suffixSalt@="$(< @out@/nix-support/libc-ldflags-before) $NIX_LDFLAGS_BEFORE_@suffixSalt@"
|
||||
fi
|
||||
|
|
|
@ -243,13 +243,7 @@ stdenv.mkDerivation {
|
|||
if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then
|
||||
echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32
|
||||
fi
|
||||
''
|
||||
# The dynamic linker is passed in `ldflagsBefore' to allow
|
||||
# explicit overrides of the dynamic linker by callers to ld
|
||||
# (the *last* value counts, so ours should come first).
|
||||
+ ''
|
||||
echo -dynamic-linker "$dynamicLinker" >> $out/nix-support/libc-ldflags-before
|
||||
'') + ''
|
||||
'') + ''
|
||||
fi
|
||||
'')
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then
|
|||
source @out@/nix-support/add-flags.sh
|
||||
fi
|
||||
|
||||
setDynamicLinker=1
|
||||
|
||||
# Optionally filter out paths not refering to the store.
|
||||
expandResponseParams "$@"
|
||||
|
@ -47,6 +48,11 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}"
|
|||
# Our ld is not built with sysroot support (Can we fix that?)
|
||||
:
|
||||
else
|
||||
if [[ "$p" = -static || "$p" = -static-pie ]]; then
|
||||
# Using a dynamic linker for static binaries can lead to crashes.
|
||||
# This was observed for rust binaries.
|
||||
setDynamicLinker=0
|
||||
fi
|
||||
rest+=("$p")
|
||||
fi
|
||||
n+=1
|
||||
|
@ -63,6 +69,11 @@ extraBefore=(${hardeningLDFlags[@]+"${hardeningLDFlags[@]}"})
|
|||
if [ -z "${NIX_LDFLAGS_SET_@suffixSalt@:-}" ]; then
|
||||
extraAfter+=($NIX_LDFLAGS_@suffixSalt@)
|
||||
extraBefore+=($NIX_LDFLAGS_BEFORE_@suffixSalt@)
|
||||
# By adding dynamic linker to extraBefore we allow the users set their
|
||||
# own dynamic linker as NIX_LD_FLAGS will override earlier set flags
|
||||
if [ "$setDynamicLinker" = 1 ]; then
|
||||
extraBefore+=("-dynamic-linker" "$NIX_DYNAMIC_LINKER_@suffixSalt@")
|
||||
fi
|
||||
fi
|
||||
|
||||
extraAfter+=($NIX_LDFLAGS_AFTER_@suffixSalt@)
|
||||
|
@ -134,7 +145,7 @@ then
|
|||
done
|
||||
fi
|
||||
|
||||
if [ -e "@out@/nix-support/dynamic-linker-m32" ] && (( "$link32" )); then
|
||||
if [[ "$link32" = "0" && "$setDynamicLinker" = 1 && -e "@out@/nix-support/dynamic-linker-m32" ]]; then
|
||||
# We have an alternate 32-bit linker and we're producing a 32-bit ELF, let's
|
||||
# use it.
|
||||
extraAfter+=(
|
||||
|
|
|
@ -28,6 +28,7 @@ cc1=0
|
|||
[[ "@prog@" = *++ ]] && isCpp=1 || isCpp=0
|
||||
cppInclude=1
|
||||
cInclude=1
|
||||
setDynamicLinker=1
|
||||
|
||||
expandResponseParams "$@"
|
||||
declare -i n=0
|
||||
|
@ -58,6 +59,8 @@ while (( "$n" < "$nParams" )); do
|
|||
cppInclude=0
|
||||
elif [ "$p" = -nostdinc++ ]; then
|
||||
cppInclude=0
|
||||
elif [[ "$p" = -static || "$p" = -static-pie ]]; then
|
||||
setDynamicLinker=0
|
||||
elif [[ "$p" != -?* ]]; then
|
||||
# A dash alone signifies standard input; it is not a flag
|
||||
nonFlagArgs=1
|
||||
|
@ -152,6 +155,9 @@ if [ "$dontLink" != 1 ]; then
|
|||
for i in $NIX_LDFLAGS_BEFORE_@suffixSalt@; do
|
||||
extraBefore+=("-Wl,$i")
|
||||
done
|
||||
if [ "$setDynamicLinker" = 1 ]; then
|
||||
extraBefore+=("-Wl,-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@")
|
||||
fi
|
||||
for i in $NIX_LDFLAGS_@suffixSalt@; do
|
||||
if [ "${i:0:3}" = -L/ ]; then
|
||||
extraAfter+=("$i")
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
{ stdenv }:
|
||||
{ stdenv, glibc }:
|
||||
with stdenv.lib;
|
||||
let
|
||||
# Sanitizers are not supported on Darwin.
|
||||
# Sanitizer headers aren't available in older libc++ stdenvs due to a bug
|
||||
sanitizersWorking =
|
||||
(stdenv.cc.isClang && versionAtLeast (getVersion stdenv.cc.name) "5.0.0")
|
||||
|| (stdenv.cc.isGNU && stdenv.isLinux);
|
||||
sanitizersWorking = !stdenv.hostPlatform.isMusl && (
|
||||
(stdenv.cc.isClang && versionAtLeast (getVersion stdenv.cc.name) "5.0.0")
|
||||
|| (stdenv.cc.isGNU && stdenv.isLinux)
|
||||
);
|
||||
staticLibc = optionalString (stdenv.hostPlatform.libc == "glibc") "-L ${glibc.static}/lib";
|
||||
in stdenv.mkDerivation {
|
||||
name = "cc-wrapper-test";
|
||||
|
||||
|
@ -28,6 +30,16 @@ in stdenv.mkDerivation {
|
|||
./core-foundation-check
|
||||
''}
|
||||
|
||||
printf "checking whether compiler builds valid static C binaries... " >&2
|
||||
$CC ${staticLibc} -static -o cc-static ${./cc-main.c}
|
||||
./cc-static
|
||||
# our glibc does not have pie enabled yet.
|
||||
${optionalString (stdenv.hostPlatform.isMusl && stdenv.cc.isGNU) ''
|
||||
printf "checking whether compiler builds valid static pie C binaries... " >&2
|
||||
$CC ${staticLibc} -static-pie -o cc-static-pie ${./cc-main.c}
|
||||
./cc-static-pie
|
||||
''}
|
||||
|
||||
printf "checking whether compiler uses NIX_CFLAGS_COMPILE... " >&2
|
||||
mkdir -p foo/include
|
||||
cp ${./foo.c} foo/include/foo.h
|
||||
|
|
Loading…
Reference in a new issue