properly patch the linker when GOROOT is a symlink

Some Go version managers like github.com/voidint/g use GOROOT symlinks,
which silently broke the way we patch the linker via go build -overlay.

Reproduced the original crash via the following testscript:

    env GARBLE_CACHE=${WORK}/garble-cache
    symlink goroot -> /usr/lib/go
    env GOROOT=${WORK}/goroot
    exec garble run main.go

    -- main.go --
    package main

    import "fmt"

    func main() {
        fmt.Println("hello world")
    }

We don't commit this testscript given how it's an expensive test
and for a relatively rare edge case whose fix is now well documented.
Moreover, as GOTOOLCHAIN is now available, I expect version managers
for Go to fade away with time.

While here, remove a debugging 'exec cat' from a testscript.

Fixes #915.
pull/949/head
Daniel Martí 6 months ago committed by Paul Scheduikat
parent 62050d8e16
commit 9cf2a6a77f

@ -2325,6 +2325,16 @@ To install Go, see: https://go.dev/doc/install
if err := json.Unmarshal(out, &sharedCache.GoEnv); err != nil { if err := json.Unmarshal(out, &sharedCache.GoEnv); err != nil {
return fmt.Errorf(`cannot unmarshal from "go env -json": %w`, err) return fmt.Errorf(`cannot unmarshal from "go env -json": %w`, err)
} }
// Some Go version managers switch between Go versions via a GOROOT which symlinks
// to one of the available versions. Given that later we build a patched linker
// from GOROOT/src via `go build -overlay`, we need to resolve any symlinks.
// Note that this edge case has no tests as it's relatively rare.
sharedCache.GoEnv.GOROOT, err = filepath.EvalSymlinks(sharedCache.GoEnv.GOROOT)
if err != nil {
return err
}
sharedCache.GoCmd = filepath.Join(sharedCache.GoEnv.GOROOT, "bin", "go") sharedCache.GoCmd = filepath.Join(sharedCache.GoEnv.GOROOT, "bin", "go")
sharedCache.GOGARBLE = cmp.Or(os.Getenv("GOGARBLE"), "*") // we default to obfuscating everything sharedCache.GOGARBLE = cmp.Or(os.Getenv("GOGARBLE"), "*") // we default to obfuscating everything
return nil return nil

@ -4,7 +4,6 @@
# setting up a `go` directive with its Go version. # setting up a `go` directive with its Go version.
cd mod cd mod
go mod init test go mod init test
exec cat go.mod
cd .. cd ..
go env GOVERSION go env GOVERSION
setenvfile GOVERSION_UPGRADE stdout setenvfile GOVERSION_UPGRADE stdout

Loading…
Cancel
Save