summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authorJohn Ericson <Ericson2314@yahoo.com>2017-09-03 10:37:27 -0400
committerGitHub <noreply@github.com>2017-09-03 10:37:27 -0400
commit0a944b345e89ca0096974d168f49e1c6830c3fc2 (patch)
tree63079e9098b44fd8a48748daab614ebd67253fce /pkgs/build-support
parent61733ed6ccde3427016720f2e0cd191d3d95152c (diff)
parent44cc709e29a67c8c6d361157c05916fee235ec7a (diff)
downloadnixlib-0a944b345e89ca0096974d168f49e1c6830c3fc2.tar
nixlib-0a944b345e89ca0096974d168f49e1c6830c3fc2.tar.gz
nixlib-0a944b345e89ca0096974d168f49e1c6830c3fc2.tar.bz2
nixlib-0a944b345e89ca0096974d168f49e1c6830c3fc2.tar.lz
nixlib-0a944b345e89ca0096974d168f49e1c6830c3fc2.tar.xz
nixlib-0a944b345e89ca0096974d168f49e1c6830c3fc2.tar.zst
nixlib-0a944b345e89ca0096974d168f49e1c6830c3fc2.zip
Merge pull request #28557 from obsidiansystems/binutils-wrapper
Binutils-wrapper: Init by refactoring out of cc-wrapper
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/binutils-wrapper/add-flags.sh40
-rw-r--r--pkgs/build-support/binutils-wrapper/add-hardening.sh53
-rw-r--r--pkgs/build-support/binutils-wrapper/default.nix288
-rw-r--r--[-rwxr-xr-x]pkgs/build-support/binutils-wrapper/ld-solaris-wrapper.sh (renamed from pkgs/build-support/cc-wrapper/ld-solaris-wrapper.sh)0
-rw-r--r--pkgs/build-support/binutils-wrapper/ld-wrapper.sh (renamed from pkgs/build-support/cc-wrapper/ld-wrapper.sh)21
-rw-r--r--pkgs/build-support/binutils-wrapper/setup-hook.sh63
-rw-r--r--pkgs/build-support/cc-wrapper/add-flags.sh39
-rw-r--r--pkgs/build-support/cc-wrapper/add-hardening.sh10
-rw-r--r--pkgs/build-support/cc-wrapper/cc-wrapper.sh14
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix131
-rw-r--r--pkgs/build-support/cc-wrapper/gnat-wrapper.sh4
-rw-r--r--pkgs/build-support/cc-wrapper/macos-sierra-reexport-hack.bash106
-rw-r--r--pkgs/build-support/cc-wrapper/setup-hook.sh23
-rw-r--r--pkgs/build-support/cc-wrapper/utils.sh32
14 files changed, 533 insertions, 291 deletions
diff --git a/pkgs/build-support/binutils-wrapper/add-flags.sh b/pkgs/build-support/binutils-wrapper/add-flags.sh
new file mode 100644
index 000000000000..a69e2313af3b
--- /dev/null
+++ b/pkgs/build-support/binutils-wrapper/add-flags.sh
@@ -0,0 +1,40 @@
+# See cc-wrapper for comments.
+var_templates_list=(
+    NIX+IGNORE_LD_THROUGH_GCC
+    NIX+LDFLAGS
+    NIX+LDFLAGS_BEFORE
+    NIX+LDFLAGS_AFTER
+    NIX+LDFLAGS_HARDEN
+)
+var_templates_bool=(
+    NIX+SET_BUILD_ID
+    NIX+DONT_SET_RPATH
+)
+
+declare -a role_infixes=()
+if [ "${NIX_BINUTILS_WRAPPER_@infixSalt@_TARGET_BUILD:-}" ]; then
+    role_infixes+=(_BUILD_)
+fi
+if [ "${NIX_BINUTILS_WRAPPER_@infixSalt@_TARGET_HOST:-}" ]; then
+    role_infixes+=(_)
+fi
+if [ "${NIX_BINUTILS_WRAPPER_@infixSalt@_TARGET_TARGET:-}" ]; then
+    role_infixes+=(_TARGET_)
+fi
+
+for var in "${var_templates_list[@]}"; do
+    mangleVarList "$var" "${role_infixes[@]}"
+done
+for var in "${var_templates_bool[@]}"; do
+    mangleVarBool "$var" "${role_infixes[@]}"
+done
+
+if [ -e @out@/nix-support/libc-ldflags ]; then
+    NIX_@infixSalt@_LDFLAGS+=" $(< @out@/nix-support/libc-ldflags)"
+fi
+
+if [ -e @out@/nix-support/libc-ldflags-before ]; then
+    NIX_@infixSalt@_LDFLAGS_BEFORE="$(< @out@/nix-support/libc-ldflags-before) $NIX_@infixSalt@_LDFLAGS_BEFORE"
+fi
+
+export NIX_BINUTILS_WRAPPER_@infixSalt@_FLAGS_SET=1
diff --git a/pkgs/build-support/binutils-wrapper/add-hardening.sh b/pkgs/build-support/binutils-wrapper/add-hardening.sh
new file mode 100644
index 000000000000..6dabc2007bc9
--- /dev/null
+++ b/pkgs/build-support/binutils-wrapper/add-hardening.sh
@@ -0,0 +1,53 @@
+hardeningFlags=(relro bindnow)
+# Intentionally word-split in case 'hardeningEnable' is defined in
+# Nix. Also, our bootstrap tools version of bash is old enough that
+# undefined arrays trip `set -u`.
+if [[ -v hardeningEnable[@] ]]; then
+  hardeningFlags+=(${hardeningEnable[@]})
+fi
+hardeningLDFlags=()
+
+declare -A hardeningDisableMap
+
+# Intentionally word-split in case 'hardeningDisable' is defined in Nix.
+for flag in ${hardeningDisable[@]:-IGNORED_KEY} @hardening_unsupported_flags@
+do
+  hardeningDisableMap[$flag]=1
+done
+
+if [[ -n "${NIX_DEBUG:-}" ]]; then
+  printf 'HARDENING: disabled flags:' >&2
+  (( "${#hardeningDisableMap[@]}" )) && printf ' %q' "${!hardeningDisableMap[@]}" >&2
+  echo >&2
+fi
+
+if [[ -z "${hardeningDisableMap[all]:-}" ]]; then
+  if [[ -n "${NIX_DEBUG:-}" ]]; then
+    echo 'HARDENING: Is active (not completely disabled with "all" flag)' >&2;
+  fi
+  for flag in "${hardeningFlags[@]}"
+  do
+    if [[ -z "${hardeningDisableMap[$flag]:-}" ]]; then
+      case $flag in
+        pie)
+          if [[ ! ("$*" =~ " -shared " || "$*" =~ " -static ") ]]; then
+            if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling LDFlags -pie >&2; fi
+            hardeningLDFlags+=('-pie')
+          fi
+          ;;
+        relro)
+          if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling relro >&2; fi
+          hardeningLDFlags+=('-z' 'relro')
+          ;;
+        bindnow)
+          if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling bindnow >&2; fi
+          hardeningLDFlags+=('-z' 'now')
+          ;;
+        *)
+          # Ignore unsupported. Checked in Nix that at least *some*
+          # tool supports each flag.
+          ;;
+      esac
+    fi
+  done
+fi
diff --git a/pkgs/build-support/binutils-wrapper/default.nix b/pkgs/build-support/binutils-wrapper/default.nix
new file mode 100644
index 000000000000..7e255cdb2eb1
--- /dev/null
+++ b/pkgs/build-support/binutils-wrapper/default.nix
@@ -0,0 +1,288 @@
+# The Nixpkgs CC is not directly usable, since it doesn't know where
+# the C library and standard header files are. Therefore the compiler
+# produced by that package cannot be installed directly in a user
+# environment and used from the command line. So we use a wrapper
+# script that sets up the right environment variables so that the
+# compiler and the linker just "work".
+
+{ name ? "", stdenv, nativeTools, noLibc ? false, nativeLibc, nativePrefix ? ""
+, binutils ? null, libc ? null
+, coreutils ? null, shell ? stdenv.shell, gnugrep ? null
+, extraPackages ? [], extraBuildCommands ? ""
+, buildPackages ? {}
+, useMacosReexportHack ? false
+}:
+
+with stdenv.lib;
+
+assert nativeTools -> nativePrefix != "";
+assert !nativeTools ->
+  binutils != null && coreutils != null && gnugrep != null;
+assert !(nativeLibc && noLibc);
+assert (noLibc || nativeLibc) == (libc == null);
+
+let
+  inherit (stdenv) hostPlatform targetPlatform;
+
+  # Prefix for binaries. Customarily ends with a dash separator.
+  #
+  # TODO(@Ericson2314) Make unconditional, or optional but always true by
+  # default.
+  prefix = stdenv.lib.optionalString (targetPlatform != hostPlatform)
+                                     (targetPlatform.config + "-");
+
+  binutilsVersion = (builtins.parseDrvName binutils.name).version;
+  binutilsName = (builtins.parseDrvName binutils.name).name;
+
+  libc_bin = if libc == null then null else getBin libc;
+  libc_dev = if libc == null then null else getDev libc;
+  libc_lib = if libc == null then null else getLib libc;
+  binutils_bin = if nativeTools then "" else getBin binutils;
+  # The wrapper scripts use 'cat' and 'grep', so we may need coreutils.
+  coreutils_bin = if nativeTools then "" else getBin coreutils;
+
+  dashlessTarget = stdenv.lib.replaceStrings ["-"] ["_"] targetPlatform.config;
+
+  # See description in cc-wrapper.
+  infixSalt = dashlessTarget;
+
+  # The dynamic linker has different names on different platforms. This is a
+  # shell glob that ought to match it.
+  dynamicLinker =
+    /**/ if libc == null then null
+    else if targetPlatform.system == "i686-linux"     then "${libc_lib}/lib/ld-linux.so.2"
+    else if targetPlatform.system == "x86_64-linux"   then "${libc_lib}/lib/ld-linux-x86-64.so.2"
+    # ARM with a wildcard, which can be "" or "-armhf".
+    else if targetPlatform.isArm                      then "${libc_lib}/lib/ld-linux*.so.3"
+    else if targetPlatform.system == "aarch64-linux"  then "${libc_lib}/lib/ld-linux-aarch64.so.1"
+    else if targetPlatform.system == "powerpc-linux"  then "${libc_lib}/lib/ld.so.1"
+    else if targetPlatform.system == "mips64el-linux" then "${libc_lib}/lib/ld.so.1"
+    else if targetPlatform.system == "x86_64-darwin"  then "/usr/lib/dyld"
+    else if stdenv.lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1"
+    else null;
+
+  expand-response-params =
+    if buildPackages.stdenv.cc or null != null && buildPackages.stdenv.cc != "/dev/null"
+    then import ../expand-response-params { inherit (buildPackages) stdenv; }
+    else "";
+
+in
+
+stdenv.mkDerivation {
+  name = prefix
+    + (if name != "" then name else "${binutilsName}-wrapper")
+    + (stdenv.lib.optionalString (binutils != null && binutilsVersion != "") "-${binutilsVersion}");
+
+  preferLocalBuild = true;
+
+  inherit binutils_bin shell libc_bin libc_dev libc_lib coreutils_bin;
+  gnugrep_bin = if nativeTools then "" else gnugrep;
+
+  binPrefix = prefix;
+  inherit infixSalt;
+
+  outputs = [ "out" "man" ];
+
+  passthru = {
+    inherit binutils libc nativeTools nativeLibc nativePrefix prefix;
+
+    emacsBufferSetup = pkgs: ''
+      ; We should handle propagation here too
+      (mapc
+        (lambda (arg)
+          (when (file-directory-p (concat arg "/lib"))
+            (setenv "NIX_${infixSalt}_LDFLAGS" (concat (getenv "NIX_${infixSalt}_LDFLAGS") " -L" arg "/lib")))
+          (when (file-directory-p (concat arg "/lib64"))
+            (setenv "NIX_${infixSalt}_LDFLAGS" (concat (getenv "NIX_${infixSalt}_LDFLAGS") " -L" arg "/lib64"))))
+        '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
+    '';
+  };
+
+  dontBuild = true;
+  dontConfigure = true;
+
+  unpackPhase = ''
+    src=$PWD
+  '';
+
+  installPhase =
+    ''
+      set -u
+
+      mkdir -p $out/bin $out/nix-support $man/nix-support
+
+      wrap() {
+        local dst="$1"
+        local wrapper="$2"
+        export prog="$3"
+        set +u
+        substituteAll "$wrapper" "$out/bin/$dst"
+        set -u
+        chmod +x "$out/bin/$dst"
+      }
+    ''
+
+    + (if nativeTools then ''
+      echo ${nativePrefix} > $out/nix-support/orig-binutils
+
+      ldPath="${nativePrefix}/bin"
+    '' else ''
+      echo $binutils_bin > $out/nix-support/orig-binutils
+
+      ldPath="${binutils_bin}/bin"
+    ''
+
+    + optionalString (targetPlatform.isSunOS && nativePrefix != "") ''
+      # Solaris needs an additional ld wrapper.
+      ldPath="${nativePrefix}/bin"
+      exec="$ldPath/${prefix}ld"
+      wrap ld-solaris ${./ld-solaris-wrapper.sh}
+    '')
+
+    + ''
+      # Create a symlink to as (the assembler).
+      if [ -e $ldPath/${prefix}as ]; then
+        ln -s $ldPath/${prefix}as $out/bin/${prefix}as
+      fi
+
+    '' + (if !useMacosReexportHack then ''
+      wrap ${prefix}ld ${./ld-wrapper.sh} ''${ld:-$ldPath/${prefix}ld}
+    '' else ''
+      ldInner="${prefix}ld-reexport-delegate"
+      wrap "$ldInner" ${./macos-sierra-reexport-hack.bash} ''${ld:-$ldPath/${prefix}ld}
+      wrap "${prefix}ld" ${./ld-wrapper.sh} "$out/bin/$ldInner"
+      unset ldInner
+    '') + ''
+
+      if [ -e ${binutils_bin}/bin/${prefix}ld.gold ]; then
+        wrap ${prefix}ld.gold ${./ld-wrapper.sh} ${binutils_bin}/bin/${prefix}ld.gold
+      fi
+
+      if [ -e ${binutils_bin}/bin/ld.bfd ]; then
+        wrap ${prefix}ld.bfd ${./ld-wrapper.sh} ${binutils_bin}/bin/${prefix}ld.bfd
+      fi
+
+      set +u
+    '';
+
+  propagatedBuildInputs = extraPackages;
+
+  setupHook = ./setup-hook.sh;
+
+  postFixup =
+    ''
+      set -u
+    ''
+
+    + optionalString (libc != null) (''
+      ##
+      ## General libc support
+      ##
+
+      echo "-L${libc_lib}/lib" > $out/nix-support/libc-ldflags
+
+      echo "${libc_lib}" > $out/nix-support/orig-libc
+      echo "${libc_dev}" > $out/nix-support/orig-libc-dev
+
+      ##
+      ## Dynamic linker support
+      ##
+
+      if [[ -z ''${dynamicLinker+x} ]]; then
+        echo "Don't know the name of the dynamic linker for platform '${targetPlatform.config}', so guessing instead." >&2
+        local dynamicLinker="${libc_lib}/lib/ld*.so.?"
+      fi
+
+      # Expand globs to fill array of options
+      dynamicLinker=($dynamicLinker)
+
+      case ''${#dynamicLinker[@]} in
+        0) echo "No dynamic linker found for platform '${targetPlatform.config}'." >&2;;
+        1) echo "Using dynamic linker: '$dynamicLinker'" >&2;;
+        *) echo "Multiple dynamic linkers found for platform '${targetPlatform.config}'." >&2;;
+      esac
+
+      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
+
+        local ldflagsBefore=(-dynamic-linker "$dynamicLinker")
+    '') + ''
+      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).
+      printWords "''${ldflagsBefore[@]}" > $out/nix-support/libc-ldflags-before
+    '')
+
+    + optionalString (!nativeTools) ''
+
+      ##
+      ## User env support
+      ##
+
+      # Propagate the underling unwrapped binutils so that if you
+      # install the wrapper, you get tools like objdump, the manpages,
+      # etc. as well (same for any binaries of libc).
+      printWords ${binutils_bin} ${if libc == null then "" else libc_bin} > $out/nix-support/propagated-user-env-packages
+    ''
+
+    + ''
+
+      ##
+      ## Hardening support
+      ##
+
+      # some linkers on some platforms don't support specific -z flags
+      export hardening_unsupported_flags=""
+      if [[ "$($ldPath/${prefix}ld -z now 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
+        hardening_unsupported_flags+=" bindnow"
+      fi
+      if [[ "$($ldPath/${prefix}ld -z relro 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
+        hardening_unsupported_flags+=" relro"
+      fi
+    ''
+
+    + optionalString hostPlatform.isCygwin ''
+      hardening_unsupported_flags+=" pic"
+    ''
+
+    + ''
+      set +u
+      substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh
+      substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh
+      substituteAll ${../cc-wrapper/utils.sh} $out/nix-support/utils.sh
+
+      ##
+      ## Extra custom steps
+      ##
+
+    ''
+    + extraBuildCommands;
+
+  inherit dynamicLinker expand-response-params;
+
+  # for substitution in utils.sh
+  expandResponseParams = "${expand-response-params}/bin/expand-response-params";
+
+  crossAttrs = {
+    shell = shell.crossDrv + shell.crossDrv.shellPath;
+  };
+
+  meta =
+    let binutils_ = if binutils != null then binutils else {}; in
+    (if binutils_ ? meta then removeAttrs binutils.meta ["priority"] else {}) //
+    { description =
+        stdenv.lib.attrByPath ["meta" "description"] "System binary utilities" binutils_
+        + " (wrapper script)";
+  } // optionalAttrs useMacosReexportHack {
+    platforms = stdenv.lib.platforms.darwin;
+  };
+}
diff --git a/pkgs/build-support/cc-wrapper/ld-solaris-wrapper.sh b/pkgs/build-support/binutils-wrapper/ld-solaris-wrapper.sh
index 72c999ff8bc8..72c999ff8bc8 100755..100644
--- a/pkgs/build-support/cc-wrapper/ld-solaris-wrapper.sh
+++ b/pkgs/build-support/binutils-wrapper/ld-solaris-wrapper.sh
diff --git a/pkgs/build-support/cc-wrapper/ld-wrapper.sh b/pkgs/build-support/binutils-wrapper/ld-wrapper.sh
index a9cc1e3f9e6f..dd30c4d55ef7 100644
--- a/pkgs/build-support/cc-wrapper/ld-wrapper.sh
+++ b/pkgs/build-support/binutils-wrapper/ld-wrapper.sh
@@ -10,12 +10,12 @@ if [ -n "@coreutils_bin@" ]; then
     PATH="@coreutils_bin@/bin"
 fi
 
-if [ -z "${NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET:-}" ]; then
+source @out@/nix-support/utils.sh
+
+if [ -z "${NIX_BINUTILS_WRAPPER_@infixSalt@_FLAGS_SET:-}" ]; then
     source @out@/nix-support/add-flags.sh
 fi
 
-source @out@/nix-support/utils.sh
-
 
 # Optionally filter out paths not refering to the store.
 expandResponseParams "$@"
@@ -63,6 +63,21 @@ fi
 
 extraAfter+=($NIX_@infixSalt@_LDFLAGS_AFTER)
 
+# Choose 32-bit dynamic linker if needed
+if [ -e @out@/nix-support/dynamic-linker-m32 ]; then
+    prev=
+    for p in ${params+"${params[@]}"}; do
+        if [[ "$prev" = "-m" && "$p" = "elf_i386" ]]; then
+           extraAfter+=(
+               '-dynamic-linker'
+               "$(< @out@/nix-support/dynamic-linker-m32)"
+           )
+           break
+        fi
+        prev="$p"
+    done
+fi
+
 declare -a libDirs
 declare -A libs
 relocatable=
diff --git a/pkgs/build-support/binutils-wrapper/setup-hook.sh b/pkgs/build-support/binutils-wrapper/setup-hook.sh
new file mode 100644
index 000000000000..3395ddd33919
--- /dev/null
+++ b/pkgs/build-support/binutils-wrapper/setup-hook.sh
@@ -0,0 +1,63 @@
+# Binutils Wrapper hygiene
+#
+# See comments in cc-wrapper's setup hook. This works exactly the same way.
+
+binutilsWrapper_addLDVars () {
+    case $depOffset in
+        -1) local role='BUILD_' ;;
+        0)  local role='' ;;
+        1)  local role='TARGET_' ;;
+        *)  echo "binutils-wrapper: Error: Cannot be used with $depOffset-offset deps, " >2;
+            return 1 ;;
+    esac
+
+    if [[ -d "$1/lib64" && ! -L "$1/lib64" ]]; then
+        export NIX_${role}LDFLAGS+=" -L$1/lib64"
+    fi
+
+    if [[ -d "$1/lib" ]]; then
+        export NIX_${role}LDFLAGS+=" -L$1/lib"
+    fi
+}
+
+if [ -n "${crossConfig:-}" ]; then
+    export NIX_BINUTILS_WRAPPER_@infixSalt@_TARGET_BUILD=1
+    role="BUILD_"
+else
+    export NIX_BINUTILS_WRAPPER_@infixSalt@_TARGET_HOST=1
+    role=""
+fi
+
+envHooks+=(binutilsWrapper_addLDVars)
+
+# shellcheck disable=SC2157
+if [ -n "@binutils_bin@" ]; then
+    addToSearchPath _PATH @binutils_bin@/bin
+fi
+
+# shellcheck disable=SC2157
+if [ -n "@libc_bin@" ]; then
+    addToSearchPath _PATH @libc_bin@/bin
+fi
+
+# shellcheck disable=SC2157
+if [ -n "@coreutils_bin@" ]; then
+    addToSearchPath _PATH @coreutils_bin@/bin
+fi
+
+# Export tool environment variables so various build systems use the right ones.
+
+export NIX_${role}BINUTILS=@out@
+
+for CMD in \
+    ar as nm objcopy ranlib strip strings size ld windres
+do
+    if
+        PATH=$_PATH type -p "@binPrefix@$CMD" > /dev/null
+    then
+        export "${role}$(echo "$CMD" | tr "[:lower:]" "[:upper:]")=@binPrefix@${CMD}";
+    fi
+done
+
+# No local scope in sourced file
+unset role
diff --git a/pkgs/build-support/cc-wrapper/add-flags.sh b/pkgs/build-support/cc-wrapper/add-flags.sh
index 39633fce69a8..fb6e38302a5d 100644
--- a/pkgs/build-support/cc-wrapper/add-flags.sh
+++ b/pkgs/build-support/cc-wrapper/add-flags.sh
@@ -4,19 +4,14 @@
 # that case, it is cheaper/better to not repeat this step and let the forked
 # wrapped binary just inherit the work of the forker's wrapper script.
 
-var_templates=(
+var_templates_list=(
     NIX+CFLAGS_COMPILE
     NIX+CFLAGS_LINK
     NIX+CXXSTDLIB_COMPILE
     NIX+CXXSTDLIB_LINK
     NIX+GNATFLAGS_COMPILE
-    NIX+IGNORE_LD_THROUGH_GCC
-    NIX+LDFLAGS
-    NIX+LDFLAGS_BEFORE
-    NIX+LDFLAGS_AFTER
-
-    NIX+SET_BUILD_ID
-    NIX+DONT_SET_RPATH
+)
+var_templates_bool=(
     NIX+ENFORCE_NO_NATIVE
 )
 
@@ -35,17 +30,11 @@ fi
 
 # We need to mangle names for hygiene, but also take parameters/overrides
 # from the environment.
-for var in "${var_templates[@]}"; do
-    outputVar="${var/+/_@infixSalt@_}"
-    export ${outputVar}+=''
-    # For each role we serve, we accumulate the input parameters into our own
-    # cc-wrapper-derivation-specific environment variables.
-    for infix in "${role_infixes[@]}"; do
-        inputVar="${var/+/${infix}}"
-        if [ -v "$inputVar" ]; then
-            export ${outputVar}+="${!outputVar:+ }${!inputVar}"
-        fi
-    done
+for var in "${var_templates_list[@]}"; do
+    mangleVarList "$var" "${role_infixes[@]}"
+done
+for var in "${var_templates_bool[@]}"; do
+    mangleVarBool "$var" "${role_infixes[@]}"
 done
 
 # `-B@out@/bin' forces cc to use ld-wrapper.sh when calling ld.
@@ -66,17 +55,13 @@ if [ -e @out@/nix-support/gnat-cflags ]; then
     NIX_@infixSalt@_GNATFLAGS_COMPILE="$(< @out@/nix-support/gnat-cflags) $NIX_@infixSalt@_GNATFLAGS_COMPILE"
 fi
 
-if [ -e @out@/nix-support/libc-ldflags ]; then
-    NIX_@infixSalt@_LDFLAGS+=" $(< @out@/nix-support/libc-ldflags)"
-fi
-
 if [ -e @out@/nix-support/cc-ldflags ]; then
+    # We don't import this above, but just tack this on know. binutils-wrapper's
+    # add-flags will not clobber it.
+    #
+    # TODO(@Ericson2314): Consider `NIX_@infixSalt@_CFLAGS_LINK` instead
     NIX_@infixSalt@_LDFLAGS+=" $(< @out@/nix-support/cc-ldflags)"
 fi
 
-if [ -e @out@/nix-support/libc-ldflags-before ]; then
-    NIX_@infixSalt@_LDFLAGS_BEFORE="$(< @out@/nix-support/libc-ldflags-before) $NIX_@infixSalt@_LDFLAGS_BEFORE"
-fi
-
 # That way forked processes will not extend these environment variables again.
 export NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET=1
diff --git a/pkgs/build-support/cc-wrapper/add-hardening.sh b/pkgs/build-support/cc-wrapper/add-hardening.sh
index 34358e04194a..3983e866ee1f 100644
--- a/pkgs/build-support/cc-wrapper/add-hardening.sh
+++ b/pkgs/build-support/cc-wrapper/add-hardening.sh
@@ -6,7 +6,6 @@ if [[ -v hardeningEnable[@] ]]; then
   hardeningFlags+=(${hardeningEnable[@]})
 fi
 hardeningCFlags=()
-hardeningLDFlags=()
 
 declare -A hardeningDisableMap
 
@@ -44,7 +43,6 @@ if [[ -z "${hardeningDisableMap[all]:-}" ]]; then
           if [[ ! ("$*" =~ " -shared " || "$*" =~ " -static ") ]]; then
             if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling LDFlags -pie >&2; fi
             hardeningCFlags+=('-pie')
-            hardeningLDFlags+=('-pie')
           fi
           ;;
         pic)
@@ -59,14 +57,6 @@ if [[ -z "${hardeningDisableMap[all]:-}" ]]; then
           if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling format >&2; fi
           hardeningCFlags+=('-Wformat' '-Wformat-security' '-Werror=format-security')
           ;;
-        relro)
-          if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling relro >&2; fi
-          hardeningLDFlags+=('-z' 'relro')
-          ;;
-        bindnow)
-          if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling bindnow >&2; fi
-          hardeningLDFlags+=('-z' 'now')
-          ;;
         *)
           # Ignore unsupported. Checked in Nix that at least *some*
           # tool supports each flag.
diff --git a/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/pkgs/build-support/cc-wrapper/cc-wrapper.sh
index aacaf196f313..524e53098476 100644
--- a/pkgs/build-support/cc-wrapper/cc-wrapper.sh
+++ b/pkgs/build-support/cc-wrapper/cc-wrapper.sh
@@ -11,12 +11,18 @@ if [[ -n "@coreutils_bin@" && -n "@gnugrep_bin@" ]]; then
     PATH="@coreutils_bin@/bin:@gnugrep_bin@/bin"
 fi
 
+source @out@/nix-support/utils.sh
+
+# Flirting with a layer violation here.
+if [ -z "${NIX_BINUTILS_WRAPPER_@infixSalt@_FLAGS_SET:-}" ]; then
+    source @binutils@/nix-support/add-flags.sh
+fi
+
+# Put this one second so libc ldflags take priority.
 if [ -z "${NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET:-}" ]; then
     source @out@/nix-support/add-flags.sh
 fi
 
-source @out@/nix-support/utils.sh
-
 
 # Parse command line options and set several variables.
 # For instance, figure out if linker flags should be passed.
@@ -57,10 +63,6 @@ while (( "$n" < "$nParams" )); do
         cppInclude=0
     elif [ "${p:0:1}" != - ]; then
         nonFlagArgs=1
-    elif [ "$p" = -m32 ]; then
-        if [ -e @out@/nix-support/dynamic-linker-m32 ]; then
-            NIX_@infixSalt@_LDFLAGS+=" -dynamic-linker $(< @out@/nix-support/dynamic-linker-m32)"
-        fi
     fi
     n+=1
 done
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index 0114170b8ebc..30520290086c 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -6,23 +6,20 @@
 # compiler and the linker just "work".
 
 { name ? "", stdenv, nativeTools, noLibc ? false, nativeLibc, nativePrefix ? ""
-, cc ? null, libc ? null, binutils ? null, coreutils ? null, shell ? stdenv.shell
+, cc ? null, libc ? null, binutils, coreutils ? null, shell ? stdenv.shell
 , zlib ? null, extraPackages ? [], extraBuildCommands ? ""
 , isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null
 , buildPackages ? {}
-, useMacosReexportHack ? false
 }:
 
 with stdenv.lib;
 
 assert nativeTools -> nativePrefix != "";
 assert !nativeTools ->
-  cc != null && binutils != null && coreutils != null && gnugrep != null;
+  cc != null && coreutils != null && gnugrep != null;
 assert !(nativeLibc && noLibc);
 assert (noLibc || nativeLibc) == (libc == null);
 
-assert stdenv.targetPlatform != stdenv.hostPlatform -> runCommand != null;
-
 # For ghdl (the vhdl language provider to gcc) we need zlib in the wrapper.
 assert cc.langVhdl or false -> zlib != null;
 
@@ -43,7 +40,6 @@ let
   libc_dev = if libc == null then null else getDev libc;
   libc_lib = if libc == null then null else getLib libc;
   cc_solib = getLib cc;
-  binutils_bin = if nativeTools then "" else getBin binutils;
   # The wrapper scripts use 'cat' and 'grep', so we may need coreutils.
   coreutils_bin = if nativeTools then "" else getBin coreutils;
 
@@ -59,21 +55,6 @@ let
   # unstable implementation detail, however.
   infixSalt = dashlessTarget;
 
-  # The dynamic linker has different names on different platforms. This is a
-  # shell glob that ought to match it.
-  dynamicLinker =
-    /**/ if libc == null then null
-    else if targetPlatform.system == "i686-linux"     then "${libc_lib}/lib/ld-linux.so.2"
-    else if targetPlatform.system == "x86_64-linux"   then "${libc_lib}/lib/ld-linux-x86-64.so.2"
-    # ARM with a wildcard, which can be "" or "-armhf".
-    else if targetPlatform.isArm                      then "${libc_lib}/lib/ld-linux*.so.3"
-    else if targetPlatform.system == "aarch64-linux"  then "${libc_lib}/lib/ld-linux-aarch64.so.1"
-    else if targetPlatform.system == "powerpc-linux"  then "${libc_lib}/lib/ld.so.1"
-    else if targetPlatform.system == "mips64el-linux" then "${libc_lib}/lib/ld.so.1"
-    else if targetPlatform.system == "x86_64-darwin"  then "/usr/lib/dyld"
-    else if stdenv.lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1"
-    else null;
-
   expand-response-params =
     if buildPackages.stdenv.cc or null != null && buildPackages.stdenv.cc != "/dev/null"
     then import ../expand-response-params { inherit (buildPackages) stdenv; }
@@ -88,7 +69,7 @@ stdenv.mkDerivation {
 
   preferLocalBuild = true;
 
-  inherit cc shell libc_bin libc_dev libc_lib binutils_bin coreutils_bin;
+  inherit cc shell libc_bin libc_dev libc_lib binutils coreutils_bin;
   gnugrep_bin = if nativeTools then "" else gnugrep;
 
   binPrefix = prefix;
@@ -102,13 +83,11 @@ stdenv.mkDerivation {
 
     emacsBufferSetup = pkgs: ''
       ; We should handle propagation here too
-      (mapc (lambda (arg)
-        (when (file-directory-p (concat arg "/include"))
-          (setenv "NIX_${infixSalt}_CFLAGS_COMPILE" (concat (getenv "NIX_${infixSalt}_CFLAGS_COMPILE") " -isystem " arg "/include")))
-        (when (file-directory-p (concat arg "/lib"))
-          (setenv "NIX_${infixSalt}_LDFLAGS" (concat (getenv "NIX_${infixSalt}_LDFLAGS") " -L" arg "/lib")))
-        (when (file-directory-p (concat arg "/lib64"))
-          (setenv "NIX_${infixSalt}_LDFLAGS" (concat (getenv "NIX_${infixSalt}_LDFLAGS") " -L" arg "/lib64")))) '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
+      (mapc
+        (lambda (arg)
+          (when (file-directory-p (concat arg "/include"))
+            (setenv "NIX_${infixSalt}_CFLAGS_COMPILE" (concat (getenv "NIX_${infixSalt}_CFLAGS_COMPILE") " -isystem " arg "/include"))))
+        '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
     '';
   };
 
@@ -138,45 +117,18 @@ stdenv.mkDerivation {
       echo ${if targetPlatform.isDarwin then cc else nativePrefix} > $out/nix-support/orig-cc
 
       ccPath="${if targetPlatform.isDarwin then cc else nativePrefix}/bin"
-      ldPath="${nativePrefix}/bin"
     '' else ''
       echo $cc > $out/nix-support/orig-cc
 
       ccPath="${cc}/bin"
-      ldPath="${binutils_bin}/bin"
-    ''
-
-    + optionalString (targetPlatform.isSunOS && nativePrefix != "") ''
-      # Solaris needs an additional ld wrapper.
-      ldPath="${nativePrefix}/bin"
-      exec="$ldPath/${prefix}ld"
-      wrap ld-solaris ${./ld-solaris-wrapper.sh}
     '')
 
     + ''
-      # Create a symlink to as (the assembler).  This is useful when a
-      # cc-wrapper is installed in a user environment, as it ensures that
-      # the right assembler is called.
-      if [ -e $ldPath/${prefix}as ]; then
-        ln -s $ldPath/${prefix}as $out/bin/${prefix}as
-      fi
-
-    '' + (if !useMacosReexportHack then ''
-      wrap ${prefix}ld ${./ld-wrapper.sh} ''${ld:-$ldPath/${prefix}ld}
-    '' else ''
-      ldInner="${prefix}ld-reexport-delegate"
-      wrap "$ldInner" ${./macos-sierra-reexport-hack.bash} ''${ld:-$ldPath/${prefix}ld}
-      wrap "${prefix}ld" ${./ld-wrapper.sh} "$out/bin/$ldInner"
-      unset ldInner
-    '') + ''
-
-      if [ -e ${binutils_bin}/bin/${prefix}ld.gold ]; then
-        wrap ${prefix}ld.gold ${./ld-wrapper.sh} ${binutils_bin}/bin/${prefix}ld.gold
-      fi
-
-      if [ -e ${binutils_bin}/bin/ld.bfd ]; then
-        wrap ${prefix}ld.bfd ${./ld-wrapper.sh} ${binutils_bin}/bin/${prefix}ld.bfd
-      fi
+      # Create symlinks to everything in the binutils wrapper.
+      for bbin in $binutils/bin/*; do
+        mkdir -p "$out/bin"
+        ln -s "$bbin" "$out/bin/$(basename $bbin)"
+      done
 
       # We export environment variables pointing to the wrapped nonstandard
       # cmds, lest some lousy configure script use those to guess compiler
@@ -236,7 +188,7 @@ stdenv.mkDerivation {
       ln -s $ccPath/${prefix}ghdl $out/bin/${prefix}ghdl
     '';
 
-  propagatedBuildInputs = extraPackages;
+  propagatedBuildInputs = [ binutils ] ++ extraPackages;
 
   setupHook = ./setup-hook.sh;
 
@@ -245,7 +197,7 @@ stdenv.mkDerivation {
       set -u
     ''
 
-    + optionalString (libc != null) (''
+    + optionalString (libc != null) ''
       ##
       ## General libc support
       ##
@@ -263,48 +215,9 @@ stdenv.mkDerivation {
       # another -idirafter is necessary to add that directory again.
       echo "-B${libc_lib}/lib/ -idirafter ${libc_dev}/include -idirafter ${cc}/lib/gcc/*/*/include-fixed" > $out/nix-support/libc-cflags
 
-      echo "-L${libc_lib}/lib" > $out/nix-support/libc-ldflags
-
       echo "${libc_lib}" > $out/nix-support/orig-libc
       echo "${libc_dev}" > $out/nix-support/orig-libc-dev
-
-      ##
-      ## Dynamic linker support
-      ##
-
-      if [[ -z ''${dynamicLinker+x} ]]; then
-        echo "Don't know the name of the dynamic linker for platform '${targetPlatform.config}', so guessing instead." >&2
-        local dynamicLinker="${libc_lib}/lib/ld*.so.?"
-      fi
-
-      # Expand globs to fill array of options
-      dynamicLinker=($dynamicLinker)
-
-      case ''${#dynamicLinker[@]} in
-        0) echo "No dynamic linker found for platform '${targetPlatform.config}'." >&2;;
-        1) echo "Using dynamic linker: '$dynamicLinker'" >&2;;
-        *) echo "Multiple dynamic linkers found for platform '${targetPlatform.config}'." >&2;;
-      esac
-
-      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
-
-        local ldflagsBefore=(-dynamic-linker "$dynamicLinker")
-    '') + ''
-      fi
-
-      # The dynamic linker is passed in `ldflagsBefore' to allow
-      # explicit overrides of the dynamic linker by callers to gcc/ld
-      # (the *last* value counts, so ours should come first).
-      printWords "''${ldflagsBefore[@]}" > $out/nix-support/libc-ldflags-before
-    '')
+    ''
 
     + optionalString (!nativeTools) ''
 
@@ -345,7 +258,6 @@ stdenv.mkDerivation {
       # Propagate the wrapped cc so that if you install the wrapper,
       # you get tools like gcov, the manpages, etc. as well (including
       # for binutils and Glibc).
-      printWords ${cc} ${binutils_bin} ${if libc == null then "" else libc_bin} > $out/nix-support/propagated-user-env-packages
       printWords ${cc.man or ""}  > $man/nix-support/propagated-user-env-packages
     ''
 
@@ -355,14 +267,7 @@ stdenv.mkDerivation {
       ## Hardening support
       ##
 
-      # some linkers on some platforms don't support specific -z flags
       export hardening_unsupported_flags=""
-      if [[ "$($ldPath/${prefix}ld -z now 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
-        hardening_unsupported_flags+=" bindnow"
-      fi
-      if [[ "$($ldPath/${prefix}ld -z relro 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
-        hardening_unsupported_flags+=" relro"
-      fi
     ''
 
     + optionalString hostPlatform.isCygwin ''
@@ -381,7 +286,7 @@ stdenv.mkDerivation {
     ''
     + extraBuildCommands;
 
-  inherit dynamicLinker expand-response-params;
+  inherit expand-response-params;
 
   # for substitution in utils.sh
   expandResponseParams = "${expand-response-params}/bin/expand-response-params";
@@ -396,7 +301,5 @@ stdenv.mkDerivation {
     { description =
         stdenv.lib.attrByPath ["meta" "description"] "System C compiler" cc_
         + " (wrapper script)";
-  } // optionalAttrs useMacosReexportHack {
-    platforms = stdenv.lib.platforms.darwin;
   };
 }
diff --git a/pkgs/build-support/cc-wrapper/gnat-wrapper.sh b/pkgs/build-support/cc-wrapper/gnat-wrapper.sh
index f0c922a3d5b4..63e5d99d5017 100644
--- a/pkgs/build-support/cc-wrapper/gnat-wrapper.sh
+++ b/pkgs/build-support/cc-wrapper/gnat-wrapper.sh
@@ -13,12 +13,12 @@ if [ -n "@coreutils_bin@" ]; then
     PATH="@coreutils_bin@/bin"
 fi
 
+source @out@/nix-support/utils.sh
+
 if [ -z "${NIX_@infixSalt@_GNAT_WRAPPER_FLAGS_SET:-}" ]; then
     source @out@/nix-support/add-flags.sh
 fi
 
-source @out@/nix-support/utils.sh
-
 
 # Figure out if linker flags should be passed.  GCC prints annoying
 # warnings when they are not needed.
diff --git a/pkgs/build-support/cc-wrapper/macos-sierra-reexport-hack.bash b/pkgs/build-support/cc-wrapper/macos-sierra-reexport-hack.bash
deleted file mode 100644
index b7aa7ea5c092..000000000000
--- a/pkgs/build-support/cc-wrapper/macos-sierra-reexport-hack.bash
+++ /dev/null
@@ -1,106 +0,0 @@
-#! @shell@
-
-set -eu -o pipefail
-
-path_backup="$PATH"
-if [ -n "@coreutils_bin@" ]; then
-  PATH="@coreutils_bin@/bin"
-fi
-
-declare -r recurThreshold=300
-
-declare overflowCount=0
-for ((n=0; n < $#; ++n)); do
-    case "${!n}" in
-        -l*) let overflowCount+=1 ;;
-        -reexport-l*) let overflowCount+=1 ;;
-        *) ;;
-    esac
-done
-
-declare -a allArgs=()
-
-if (( "$overflowCount" <= "$recurThreshold" )); then
-    allArgs=("$@")
-else
-    declare -a childrenLookup=() childrenLink=()
-
-    while (( $# )); do
-        case "$1" in
-            -L/*)
-                childrenLookup+=("$1")
-                allArgs+=("$1")
-                ;;
-            -L)
-                echo "cctools LD does not support '-L foo' or '-l foo'" >&2
-                exit 1
-                ;;
-            -l)
-                echo "cctools LD does not support '-L foo' or '-l foo'" >&2
-                exit 1
-                ;;
-            -lazy_library | -lazy_framework | -lto_library)
-                # We aren't linking any "azy_library", "to_library", etc.
-                allArgs+=("$1")
-                ;;
-            -lazy-l | -weak-l)    allArgs+=("$1") ;;
-                # We can't so easily prevent header issues from these.
-            -lSystem)             allArgs+=("$1") ;;
-                # Special case as indirection seems like a bad idea for something
-                # so fundamental. Can be removed for simplicity.
-            -l?* | -reexport-l?*) childrenLink+=("$1") ;;
-            *)                    allArgs+=("$1") ;;
-        esac
-
-        shift
-    done
-
-    declare n=0
-    while (( $n < "${#childrenLink[@]}" )); do
-        if [[ "${childrenLink[n]}" = -l* ]]; then
-            childrenLink[n]="-reexport${childrenLink[n]}"
-        fi
-        let ++n
-    done
-    unset n
-
-    declare -r outputNameLibless=$(basename $( \
-        if [[ -z "${outputName:+isUndefined}" ]]; then
-            echo unnamed
-        elif [[ "${outputName:0:3}" = lib ]]; then
-            echo "${outputName:3}"
-        else
-            echo "${outputName}"
-        fi))
-    declare -ra children=("$outputNameLibless-reexport-delegate-0" \
-                          "$outputNameLibless-reexport-delegate-1")
-
-    mkdir -p "$out/lib"
-
-    PATH="$PATH:@out@/bin"
-
-    symbolBloatObject=$outputNameLibless-symbol-hack.o
-    if [[ ! -e $symbolBloatObject ]]; then
-        printf '.private_extern _______child_hack_foo\nchild_hack_foo:\n' \
-            | @binPrefix@as -- -o $symbolBloatObject
-    fi
-
-    # first half of libs
-    @binPrefix@ld -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64 -dylib \
-      -o "$out/lib/lib${children[0]}.dylib" \
-      -install_name "$out/lib/lib${children[0]}.dylib" \
-      "${childrenLookup[@]}" "$symbolBloatObject" \
-      "${childrenLink[@]:0:$((${#childrenLink[@]} / 2 ))}"
-
-    # second half of libs
-    @binPrefix@ld -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64 -dylib \
-      -o "$out/lib/lib${children[1]}.dylib" \
-      -install_name "$out/lib/lib${children[1]}.dylib" \
-      "${childrenLookup[@]}" "$symbolBloatObject" \
-      "${childrenLink[@]:$((${#childrenLink[@]} / 2 ))}"
-
-    allArgs+=("-L$out/lib" "-l${children[0]}" "-l${children[1]}")
-fi
-
-PATH="$path_backup"
-exec @prog@ "${allArgs[@]}"
diff --git a/pkgs/build-support/cc-wrapper/setup-hook.sh b/pkgs/build-support/cc-wrapper/setup-hook.sh
index e43c1609edb1..9273f50c6670 100644
--- a/pkgs/build-support/cc-wrapper/setup-hook.sh
+++ b/pkgs/build-support/cc-wrapper/setup-hook.sh
@@ -74,14 +74,6 @@ ccWrapper_addCVars () {
         export NIX_${role}CFLAGS_COMPILE+=" ${ccIncludeFlag:--isystem} $1/include"
     fi
 
-    if [[ -d "$1/lib64" && ! -L "$1/lib64" ]]; then
-        export NIX_${role}LDFLAGS+=" -L$1/lib64"
-    fi
-
-    if [[ -d "$1/lib" ]]; then
-        export NIX_${role}LDFLAGS+=" -L$1/lib"
-    fi
-
     if [[ -d "$1/Library/Frameworks" ]]; then
         export NIX_${role}CFLAGS_COMPILE+=" -F$1/Library/Frameworks"
     fi
@@ -117,11 +109,6 @@ if [ -n "@cc@" ]; then
 fi
 
 # shellcheck disable=SC2157
-if [ -n "@binutils_bin@" ]; then
-    addToSearchPath _PATH @binutils_bin@/bin
-fi
-
-# shellcheck disable=SC2157
 if [ -n "@libc_bin@" ]; then
     addToSearchPath _PATH @libc_bin@/bin
 fi
@@ -138,15 +125,5 @@ export NIX_${role}CC=@out@
 export ${role}CC=@named_cc@
 export ${role}CXX=@named_cxx@
 
-for CMD in \
-    ar as nm objcopy ranlib strip strings size ld windres
-do
-    if
-        PATH=$_PATH type -p "@binPrefix@$CMD" > /dev/null
-    then
-        export "${role}$(echo "$CMD" | tr "[:lower:]" "[:upper:]")=@binPrefix@${CMD}";
-    fi
-done
-
 # No local scope in sourced file
 unset role
diff --git a/pkgs/build-support/cc-wrapper/utils.sh b/pkgs/build-support/cc-wrapper/utils.sh
index c84a094e26b0..a9ab2b23f24d 100644
--- a/pkgs/build-support/cc-wrapper/utils.sh
+++ b/pkgs/build-support/cc-wrapper/utils.sh
@@ -1,3 +1,35 @@
+mangleVarList() {
+    local var="$1"
+    shift
+    local -a role_infixes=("$@")
+
+    local outputVar="${var/+/_@infixSalt@_}"
+    declare -gx ${outputVar}+=''
+    # For each role we serve, we accumulate the input parameters into our own
+    # cc-wrapper-derivation-specific environment variables.
+    for infix in "${role_infixes[@]}"; do
+        local inputVar="${var/+/${infix}}"
+        if [ -v "$inputVar" ]; then
+            export ${outputVar}+="${!outputVar:+ }${!inputVar}"
+        fi
+    done
+}
+
+mangleVarBool() {
+    local var="$1"
+    shift
+    local -a role_infixes=("$@")
+
+    local outputVar="${var/+/_@infixSalt@_}"
+    declare -gxi ${outputVar}+=''
+    for infix in "${role_infixes[@]}"; do
+        local inputVar="${var/+/${infix}}"
+        if [ -v "$inputVar" ]; then
+            let "${outputVar} |= ${!inputVar}"
+        fi
+    done
+}
+
 skip () {
     if [ -n "${NIX_DEBUG:-}" ]; then
         echo "skipping impure path $1" >&2