Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions pkgs/build-support/bintools-wrapper/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
{ name ? ""
, lib
, stdenvNoCC
, stdenv ? stdenvNoCC
, bintools ? null, libc ? null, coreutils ? null, shell ? stdenvNoCC.shell, gnugrep ? null
, netbsd ? null, netbsdCross ? null
, sharedLibraryLoader ?
Expand Down Expand Up @@ -42,7 +43,6 @@ assert !(nativeLibc && noLibc);
assert (noLibc || nativeLibc) == (libc == null);

let
stdenv = stdenvNoCC;
inherit (stdenv) hostPlatform targetPlatform;

# Prefix for binaries. Customarily ends with a dash separator.
Expand Down Expand Up @@ -94,6 +94,15 @@ let
then import ../expand-response-params { inherit (buildPackages) stdenv; }
else "";

# We can install the link only if our compiler's host and target
# match GNU binutils' host and target.
gcc_lto_plugin_is_compatible =
(bintools.isGNU or false)
&& stdenv.cc != null
&& stdenv.cc.stdenv.hostPlatform == stdenv.hostPlatform
&& stdenv.cc.stdenv.targetPlatform == stdenv.targetPlatform;
gcc_lto_plugin_path = "${stdenv.cc.cc}/libexec/gcc/${stdenv.targetPlatform.config}/${stdenv.cc.cc.version or "UNKNOWN"}/liblto_plugin.so";

in

stdenv.mkDerivation {
Expand Down Expand Up @@ -137,6 +146,8 @@ stdenv.mkDerivation {

installPhase =
''
runHook preInstall

mkdir -p $out/bin $out/nix-support

wrap() {
Expand Down Expand Up @@ -167,7 +178,7 @@ stdenv.mkDerivation {

# Create symlinks for rest of the binaries.
+ ''
for binary in objdump objcopy size strings as ar nm gprof dwp c++filt addr2line ranlib readelf elfedit; do
for binary in objdump objcopy size strings as nm gprof dwp c++filt addr2line ranlib readelf elfedit; do
if [ -e $ldPath/${targetPrefix}''${binary} ]; then
ln -s $ldPath/${targetPrefix}''${binary} $out/bin/${targetPrefix}''${binary}
fi
Expand All @@ -187,6 +198,8 @@ stdenv.mkDerivation {
[[ -e "$underlying" ]] || continue
wrap ${targetPrefix}$variant ${./ld-wrapper.sh} $underlying
done

runHook postInstall
'';

strictDeps = true;
Expand All @@ -199,6 +212,25 @@ stdenv.mkDerivation {
./setup-hook.sh
];

# Install linker plugin to make 'ar', 'ld' and friends auto-load
# linker plugin to handle LTO bytecode without explicit --plugin
# parameter.
#
# We can install the link only if our compiler's host and target
# match GNU binutils' host and target.
gnu_binutils_inject_plugin = lib.optionalString gcc_lto_plugin_is_compatible ''
if [ -d ${placeholder "out"}/lib/bfd-plugins ]; then
export BFD_PLUGINS_DIR="${placeholder "out"}/lib/bfd-plugins"
fi
'';

postInstall = lib.optionalString gcc_lto_plugin_is_compatible ''
if [ -e ${gcc_lto_plugin_path} ]; then
mkdir -p $out/lib/bfd-plugins
ln -s ${gcc_lto_plugin_path} $out/lib/bfd-plugins/
fi
'';

postFixup =
##
## General libc support
Expand All @@ -209,6 +241,7 @@ stdenv.mkDerivation {

echo "${libc_lib}" > $out/nix-support/orig-libc
echo "${libc_dev}" > $out/nix-support/orig-libc-dev

''

##
Expand Down Expand Up @@ -306,6 +339,9 @@ stdenv.mkDerivation {
+ optionalString (bintools.isGNU or false) ''
wrap ${targetPrefix}strip ${./gnu-binutils-strip-wrapper.sh} \
"${bintools_bin}/bin/${targetPrefix}strip"
# TODO: also wrap: size, rescoff, nm, dlltool, coffdump, addr2line, ranlib, maybe others?
wrap ${targetPrefix}ar ${./gnu-binutils-ar-wrapper.sh} \
"${bintools_bin}/bin/${targetPrefix}ar"
''

###
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#! @shell@
# shellcheck shell=bash

@gnu_binutils_inject_plugin@
exec @prog@ "$@"
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#! @shell@
# shellcheck shell=bash

@gnu_binutils_inject_plugin@
exec @prog@ --enable-deterministic-archives "$@"
1 change: 1 addition & 0 deletions pkgs/build-support/bintools-wrapper/ld-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ if (( "${NIX_DEBUG:-0}" >= 1 )); then
fi

PATH="$path_backup"
@gnu_binutils_inject_plugin@
# Old bash workaround, see above.
@prog@ \
${extraBefore+"${extraBefore[@]}"} \
Expand Down
24 changes: 24 additions & 0 deletions pkgs/development/tools/misc/binutils/BFD_PLUGINS_DIR.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -490,9 +490,18 @@ build_plugin_list (bfd *abfd)
/* The intent was to search ${libdir}/bfd-plugins for plugins, but
unfortunately the original implementation wasn't precisely that
when configuring binutils using --libdir. Search in the proper
- path first, then the old one for backwards compatibility. */
- static const char *path[]
- = { LIBDIR "/bfd-plugins", BINDIR "/../lib/bfd-plugins" };
+ path first, then the old one for backwards compatibility.
+
+ On top of that user is allowed to extend default search path with
+ BFD_PLUGINS_DIR environment variable. It's useful for cases when
+ modifying system directories is not feasible.
+ */
+ const char *path[] =
+ {
+ getenv ("BFD_PLUGINS_DIR"),
+ LIBDIR "/bfd-plugins",
+ BINDIR "/../lib/bfd-plugins",
+ };
struct stat last_st;
unsigned int i;

3 changes: 3 additions & 0 deletions pkgs/development/tools/misc/binutils/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ stdenv.mkDerivation {
# https://sourceware.org/PR29450
# Remove once 2.40 releases.
./gas-dwarf-zero-PR29451.patch

# Add an extra path to look up gcc LTO plugin. Used by binutils wrapper.
./BFD_PLUGINS_DIR.patch
]
++ lib.optional targetPlatform.isiOS ./support-ios.patch
# This patch was suggested by Nick Clifton to fix
Expand Down