summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorJörg Thalheim <joerg@thalheim.io>2020-12-25 21:52:42 +0100
committerJörg Thalheim <joerg@thalheim.io>2020-12-27 16:42:11 +0100
commit61bbbcd1af1c3b5a365423f2ecc722a627ff353f (patch)
treed5bd5d7b10f26bad5c5ee4507361a911f94c8be7 /pkgs
parent7659201d58cd85b215e561068a2c96bf760c002b (diff)
downloadnixpkgs-61bbbcd1af1c3b5a365423f2ecc722a627ff353f.tar
nixpkgs-61bbbcd1af1c3b5a365423f2ecc722a627ff353f.tar.gz
nixpkgs-61bbbcd1af1c3b5a365423f2ecc722a627ff353f.tar.bz2
nixpkgs-61bbbcd1af1c3b5a365423f2ecc722a627ff353f.tar.lz
nixpkgs-61bbbcd1af1c3b5a365423f2ecc722a627ff353f.tar.xz
nixpkgs-61bbbcd1af1c3b5a365423f2ecc722a627ff353f.tar.zst
nixpkgs-61bbbcd1af1c3b5a365423f2ecc722a627ff353f.zip
bintools-wrapper: skip dynamic linker for static binaries
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/build-support/bintools-wrapper/add-flags.sh5
-rw-r--r--pkgs/build-support/bintools-wrapper/default.nix21
-rw-r--r--pkgs/build-support/bintools-wrapper/ld-wrapper.sh13
-rw-r--r--pkgs/build-support/cc-wrapper/cc-wrapper.sh6
-rw-r--r--pkgs/development/compilers/gcc/builder.sh5
-rw-r--r--pkgs/test/cc-wrapper/default.nix23
6 files changed, 54 insertions, 19 deletions
diff --git a/pkgs/build-support/bintools-wrapper/add-flags.sh b/pkgs/build-support/bintools-wrapper/add-flags.sh
index e99beb38158..3b94daba65d 100644
--- a/pkgs/build-support/bintools-wrapper/add-flags.sh
+++ b/pkgs/build-support/bintools-wrapper/add-flags.sh
@@ -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/ld-set-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
diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix
index 6da0e58436d..bd3ebdf800e 100644
--- a/pkgs/build-support/bintools-wrapper/default.nix
+++ b/pkgs/build-support/bintools-wrapper/default.nix
@@ -237,19 +237,14 @@ stdenv.mkDerivation {
       if [ -n "''${dynamicLinker-}" ]; then
         echo $dynamicLinker > $out/nix-support/dynamic-linker
 
-    '' + (if targetPlatform.isDarwin then ''
-        printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook
-      '' else ''
-        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
-    '') + ''
+        ${if targetPlatform.isDarwin then ''
+          printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook
+        '' else ''
+          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
+          touch $out/nix-support/ld-set-dynamic-linker
+        ''}
       fi
     '')
 
diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
index 81b5a90edd5..9d02f99851a 100644
--- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
+++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
@@ -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 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; 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" = "1" && "$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+=(
diff --git a/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/pkgs/build-support/cc-wrapper/cc-wrapper.sh
index 7e734f57773..1450218aff2 100644
--- a/pkgs/build-support/cc-wrapper/cc-wrapper.sh
+++ b/pkgs/build-support/cc-wrapper/cc-wrapper.sh
@@ -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 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; 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")
diff --git a/pkgs/development/compilers/gcc/builder.sh b/pkgs/development/compilers/gcc/builder.sh
index e1c4768413f..7d104b96624 100644
--- a/pkgs/development/compilers/gcc/builder.sh
+++ b/pkgs/development/compilers/gcc/builder.sh
@@ -37,6 +37,9 @@ if test "$noSysDirs" = "1"; then
             # Figure out what extra flags when linking to pass to the gcc
             # compilers being generated to make sure that they use our libc.
             extraLDFlags=($(< "${!curBintools}/nix-support/libc-ldflags") $(< "${!curBintools}/nix-support/libc-ldflags-before" || true))
+            if [ -e ${!curBintools}/nix-support/ld-set-dynamic-linker ]; then
+                extraLDFlags=-dynamic-linker=$(< ${!curBintools}/nix-support/dynamic-linker)
+            fi
 
             # The path to the Libc binaries such as `crti.o'.
             libc_libdir="$(< "${!curBintools}/nix-support/orig-libc")/lib"
@@ -252,7 +255,7 @@ postInstall() {
 
     if [[ targetConfig == *"linux"* ]]; then
         # For some reason, when building for linux on darwin, the libs retain
-	# RPATH to $out.
+        # RPATH to $out.
         for i in "$lib"/"$targetConfig"/lib/{libtsan,libasan,libubsan}.so.*.*.*; do
             PREV_RPATH=`patchelf --print-rpath "$i"`
             NEW_RPATH=`echo "$PREV_RPATH" | sed "s,:${out}[^:]*,,g"`
diff --git a/pkgs/test/cc-wrapper/default.nix b/pkgs/test/cc-wrapper/default.nix
index c0c89d63fff..fae3448c44c 100644
--- a/pkgs/test/cc-wrapper/default.nix
+++ b/pkgs/test/cc-wrapper/default.nix
@@ -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,19 @@ in stdenv.mkDerivation {
       ./core-foundation-check
     ''}
 
+
+    ${optionalString (!stdenv.isDarwin) ''
+      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