mirror of
https://github.com/burrowers/garble.git
synced 2025-12-24 12:58:05 +08:00
rebuild cmd/link with the correct toolchain under GOTOOLCHAIN=auto
When we build the patched cmd/link binary for use by garble, we perform this build in a temporary directory so that the Go module from the user does not get in the way. When the user module made us upgrade the toolchain per GOTOOLCHAIN, leaving that module's directory stops upgrading the toolchain, so we patch a newer toolchain and build it with an older toolchain. This is largely harmless, but it makes the newer toolchain think it is actually an older toolchain, which leads to those pesky "linker object header mismatch" version errors. Updates #934.
This commit is contained in:
committed by
Paul Scheduikat
parent
6f7af3b785
commit
7f80dfb59d
@@ -27,9 +27,6 @@ const (
|
||||
MagicValueEnv = "GARBLE_LINK_MAGIC"
|
||||
TinyEnv = "GARBLE_LINK_TINY"
|
||||
EntryOffKeyEnv = "GARBLE_LINK_ENTRYOFF_KEY"
|
||||
|
||||
versionExt = ".version"
|
||||
baseSrcSubdir = "src"
|
||||
)
|
||||
|
||||
//go:embed patches/*/*.patch
|
||||
@@ -163,6 +160,8 @@ func getCurrentVersion(goVersion, patchesVer string) string {
|
||||
return goVersion + " " + patchesVer + "\n"
|
||||
}
|
||||
|
||||
const versionExt = ".version"
|
||||
|
||||
func checkVersion(linkerPath, goVersion, patchesVer string) (bool, error) {
|
||||
versionPath := linkerPath + versionExt
|
||||
version, err := os.ReadFile(versionPath)
|
||||
@@ -181,7 +180,7 @@ func writeVersion(linkerPath, goVersion, patchesVer string) error {
|
||||
return os.WriteFile(versionPath, []byte(getCurrentVersion(goVersion, patchesVer)), 0o777)
|
||||
}
|
||||
|
||||
func buildLinker(workingDir string, overlay map[string]string, outputLinkPath string) error {
|
||||
func buildLinker(goRoot, workingDir string, overlay map[string]string, outputLinkPath string) error {
|
||||
file, err := json.Marshal(&struct{ Replace map[string]string }{overlay})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -191,7 +190,8 @@ func buildLinker(workingDir string, overlay map[string]string, outputLinkPath st
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command("go", "build", "-overlay", overlayPath, "-o", outputLinkPath, "cmd/link")
|
||||
goCmd := filepath.Join(goRoot, "bin", "go")
|
||||
cmd := exec.Command(goCmd, "build", "-overlay", overlayPath, "-o", outputLinkPath, "cmd/link")
|
||||
// Ignore any build settings from the environment or GOENV.
|
||||
// We want to build cmd/link like the rest of the toolchain,
|
||||
// regardless of what build options are set for the current build.
|
||||
@@ -250,14 +250,14 @@ func PatchLinker(goRoot, goVersion, cacheDir, tempDir string) (string, func(), e
|
||||
return outputLinkPath, unlock, nil
|
||||
}
|
||||
|
||||
srcDir := filepath.Join(goRoot, baseSrcSubdir)
|
||||
srcDir := filepath.Join(goRoot, "src")
|
||||
workingDir := filepath.Join(tempDir, "linker-src")
|
||||
|
||||
overlay, err := applyPatches(srcDir, workingDir, modFiles, patches)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := buildLinker(workingDir, overlay, outputLinkPath); err != nil {
|
||||
if err := buildLinker(goRoot, workingDir, overlay, outputLinkPath); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := writeVersion(outputLinkPath, goVersion, patchesVer); err != nil {
|
||||
|
||||
2
testdata/script/gotoolchain.txtar
vendored
2
testdata/script/gotoolchain.txtar
vendored
@@ -21,7 +21,7 @@ stderr 'hello from go1\.24\.1'
|
||||
|
||||
# TODO: fix this.
|
||||
! exec garble run .
|
||||
stderr 'linked object header mismatch'
|
||||
stderr 'gcMarkTermination: relocation target .* not defined'
|
||||
|
||||
-- mod/go.mod --
|
||||
module test
|
||||
|
||||
Reference in New Issue
Block a user