cmd/release: sanity check relocations before release
Updates golang/go#31293
Change-Id: I001e1f1518c302a9e8c49716d44860603fd5c28b
Reviewed-on: https://go-review.googlesource.com/c/build/+/171317
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/cmd/release/release.go b/cmd/release/release.go
index 0cf1e20..a6fae05 100644
--- a/cmd/release/release.go
+++ b/cmd/release/release.go
@@ -401,6 +401,10 @@
return fmt.Errorf("Build failed: %v\nOutput:\n%v", remoteErr, out)
}
+ if err := b.checkRelocations(client); err != nil {
+ return err
+ }
+
goCmd := path.Join(goDir, "bin/go")
if b.OS == "windows" {
goCmd += ".exe"
@@ -701,6 +705,32 @@
return nil
}
+// checkRelocations runs readelf on pkg/linux_amd64/runtime/cgo.a and makes sure
+// we don't see R_X86_64_REX_GOTPCRELX. See issue 31293.
+func (b *Build) checkRelocations(client *buildlet.Client) error {
+ if b.OS != "linux" || b.Arch != "amd64" {
+ return nil
+ }
+ var out bytes.Buffer
+ file := fmt.Sprintf("go/pkg/linux_%s/runtime/cgo.a", b.Arch)
+ remoteErr, err := client.Exec("readelf", buildlet.ExecOpts{
+ Output: &out,
+ Args: []string{"-r", "--wide", file},
+ SystemLevel: true, // look for readelf in system's PATH
+ })
+ if err != nil {
+ return fmt.Errorf("failed to run readelf: %v", err)
+ }
+ got := out.String()
+ if strings.Contains(got, "R_X86_64_REX_GOTPCRELX") {
+ return fmt.Errorf("%s contained a R_X86_64_REX_GOTPCRELX relocation", file)
+ }
+ if !strings.Contains(got, "R_X86_64_GOTPCREL") {
+ return fmt.Errorf("%s did not contain a R_X86_64_GOTPCREL relocation; remoteErr=%v, %s", file, remoteErr, got)
+ }
+ return nil
+}
+
// verifyGzipSingleStream verifies that the named gzip file is not
// a multi-stream file. See golang.org/issue/19052
func verifyGzipSingleStream(name string) error {