From 7b3a342260ecb20350acc42eb7593f8ffc9bec26 Mon Sep 17 00:00:00 2001 From: Luna Nova Date: Wed, 8 Oct 2025 09:38:44 -0700 Subject: [PATCH] go: restrict default pie patch to known good GOARCH Blanket application of the patch was insufficiently pessimistic. The original plan from discussion in matrix was that BuildModeSupported("gc", "pie", goos, goarch) should let us know if default pie would work, however it seems that in some cases BuildModeSupported can return true but pie will fail anyway. Let's make an allowlist of GOARCH values so we aren't breaking any value that has not been tested. Co-authored-by: Philip Taron --- pkgs/development/compilers/go/1.24.nix | 26 ++++++++++++++++++++++++++ pkgs/development/compilers/go/1.25.nix | 26 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/pkgs/development/compilers/go/1.24.nix b/pkgs/development/compilers/go/1.24.nix index 8ee9c0f16725..de002ec70b09 100644 --- a/pkgs/development/compilers/go/1.24.nix +++ b/pkgs/development/compilers/go/1.24.nix @@ -24,6 +24,30 @@ let targetCC = pkgsBuildTarget.targetPackages.stdenv.cc; isCross = stdenv.buildPlatform != stdenv.targetPlatform; + + # In order for buildmode=pie to work either Go's internal linker must know how + # to produce position-independent executables or Go must be using an external linker. + # + # go-default-pie.patch tries to enable position-independent codegen (PIE) only when the platform + # reports support (via BuildModeSupported(..., "pie", ...)). + # + # That probe is not fully reliable: for example, `pkgsi686Linux.go` can fail during bootstrap + # with message 'default PIE binary requires external (cgo) linking, but cgo is not enabled' + # despite CGO being enabled. (we set `CGO_ENABLED=1`). + # + # To avoid such breakage, limit this patch to a small set of explicitly tested platforms + # rather than relying on the general BuildModeSupported("pie") check. + supportsDefaultPie = + let + hasPie = { + "amd64" = true; + "arm64" = true; + "ppc64le" = true; + "riscv64" = true; + }; + in + hasPie.${stdenv.hostPlatform.go.GOARCH} or false + && hasPie.${stdenv.targetPlatform.go.GOARCH} or false; in stdenv.mkDerivation (finalAttrs: { pname = "go"; @@ -65,6 +89,8 @@ stdenv.mkDerivation (finalAttrs: { ./remove-tools-1.11.patch ./go_no_vendor_checks-1.23.patch ./go-env-go_ldso.patch + ] + ++ lib.optionals supportsDefaultPie [ (replaceVars ./go-default-pie.patch { inherit (stdenv.targetPlatform.go) GOARCH; }) diff --git a/pkgs/development/compilers/go/1.25.nix b/pkgs/development/compilers/go/1.25.nix index d61039eba543..db50761a4bbc 100644 --- a/pkgs/development/compilers/go/1.25.nix +++ b/pkgs/development/compilers/go/1.25.nix @@ -30,6 +30,30 @@ let targetCC = pkgsBuildTarget.targetPackages.stdenv.cc; isCross = stdenv.buildPlatform != stdenv.targetPlatform; + + # go-default-pie.patch tries to enable position-independent codegen (PIE) only when the platform + # reports support (via BuildModeSupported(..., "pie", ...)). + # + # In order for buildmode=pie to work either Go's internal linker must know how + # to produce position-independent executables or Go must be using an external linker. + # + # That probe is not fully reliable: for example, `pkgsi686Linux.go` can fail during bootstrap + # with message 'default PIE binary requires external (cgo) linking, but cgo is not enabled' + # despite CGO being enabled. (we set `CGO_ENABLED=1`). + # + # To avoid such breakage, limit this patch to a small set of explicitly tested platforms + # rather than relying on the general BuildModeSupported("pie") check. + supportsDefaultPie = + let + hasPie = { + "amd64" = true; + "arm64" = true; + "ppc64le" = true; + "riscv64" = true; + }; + in + hasPie.${stdenv.hostPlatform.go.GOARCH} or false + && hasPie.${stdenv.targetPlatform.go.GOARCH} or false; in stdenv.mkDerivation (finalAttrs: { pname = "go"; @@ -75,6 +99,8 @@ stdenv.mkDerivation (finalAttrs: { ./remove-tools-1.11.patch ./go_no_vendor_checks-1.23.patch ./go-env-go_ldso.patch + ] + ++ lib.optionals supportsDefaultPie [ (replaceVars ./go-default-pie.patch { inherit (stdenv.targetPlatform.go) GOARCH; })