]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: on ELF, generate GNU build ID by default
authorCherry Mui <cherryyz@google.com>
Tue, 8 Oct 2024 21:59:29 +0000 (17:59 -0400)
committerCherry Mui <cherryyz@google.com>
Mon, 21 Oct 2024 17:57:00 +0000 (17:57 +0000)
On ELF, default to "-B gobuildid", so it generates GNU build ID
based on Go buildid by default.

Updates #41004.
Fixes #63934.
Fixes #68652.

Change-Id: I5619dfaa4eeb6575c52922ae1de3430b46e31db6
Reviewed-on: https://go-review.googlesource.com/c/go/+/618601
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Than McIntosh <thanm@golang.org>
src/cmd/link/elf_test.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/main.go

index 527b97d23b5955d2bc96bc706d146866c74535bf..e68f94e7de32be10db249169a15eb77c50118daf 100644 (file)
@@ -7,7 +7,6 @@
 package main
 
 import (
-       "bytes"
        "cmd/internal/buildid"
        "cmd/internal/hash"
        "cmd/link/internal/ld"
@@ -203,36 +202,51 @@ func TestMinusRSymsWithSameName(t *testing.T) {
        }
 }
 
-func TestGNUBuildIDDerivedFromGoBuildID(t *testing.T) {
+func TestGNUBuildID(t *testing.T) {
        testenv.MustHaveGoBuild(t)
 
        t.Parallel()
 
-       goFile := filepath.Join(t.TempDir(), "notes.go")
+       tmpdir := t.TempDir()
+       goFile := filepath.Join(tmpdir, "notes.go")
        if err := os.WriteFile(goFile, []byte(goSource), 0444); err != nil {
                t.Fatal(err)
        }
-       outFile := filepath.Join(t.TempDir(), "notes.exe")
-       goTool := testenv.GoToolPath(t)
 
-       cmd := testenv.Command(t, goTool, "build", "-o", outFile, "-ldflags", "-buildid 0x1234 -B gobuildid", goFile)
-       cmd.Dir = t.TempDir()
+       // Use a specific Go buildid for testing.
+       const gobuildid = "testbuildid"
+       h := hash.Sum32([]byte(gobuildid))
+       gobuildidHash := string(h[:20])
 
-       out, err := cmd.CombinedOutput()
-       if err != nil {
-               t.Logf("%s", out)
-               t.Fatal(err)
+       tests := []struct{ name, ldflags, expect string }{
+               {"default", "", gobuildidHash},
+               {"gobuildid", "-B=gobuildid", gobuildidHash},
+               {"specific", "-B=0x0123456789abcdef", "\x01\x23\x45\x67\x89\xab\xcd\xef"},
+               {"none", "-B=none", ""},
        }
-
-       expectedGoBuildID := hash.Sum32([]byte("0x1234"))
-
-       gnuBuildID, err := buildid.ReadELFNote(outFile, string(ld.ELF_NOTE_BUILDINFO_NAME), ld.ELF_NOTE_BUILDINFO_TAG)
-       if err != nil || gnuBuildID == nil {
-               t.Fatalf("can't read GNU build ID")
+       if testenv.HasCGO() {
+               for _, test := range tests {
+                       t1 := test
+                       t1.name += "_external"
+                       t1.ldflags += " -linkmode=external"
+                       tests = append(tests, t1)
+               }
        }
-
-       if !bytes.Equal(gnuBuildID, expectedGoBuildID[:20]) {
-               t.Fatalf("build id not matching")
+       for _, test := range tests {
+               t.Run(test.name, func(t *testing.T) {
+                       exe := filepath.Join(tmpdir, test.name)
+                       cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-buildid="+gobuildid+" "+test.ldflags, "-o", exe, goFile)
+                       if out, err := cmd.CombinedOutput(); err != nil {
+                               t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
+                       }
+                       gnuBuildID, err := buildid.ReadELFNote(exe, string(ld.ELF_NOTE_BUILDINFO_NAME), ld.ELF_NOTE_BUILDINFO_TAG)
+                       if err != nil {
+                               t.Fatalf("can't read GNU build ID")
+                       }
+                       if string(gnuBuildID) != test.expect {
+                               t.Errorf("build id mismatch: got %x, want %x", gnuBuildID, test.expect)
+                       }
+               })
        }
 }
 
index cbae6dda172ebad2a0818275e8647a67b37546a3..02bea8e443fb3ea329ce99b4cf4eb12e66c23d27 100644 (file)
@@ -1701,8 +1701,12 @@ func (ctxt *Link) hostlink() {
                argv = append(argv, "-fuse-ld="+altLinker)
        }
 
-       if ctxt.IsELF && len(buildinfo) > 0 {
-               argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
+       if ctxt.IsELF {
+               if len(buildinfo) > 0 {
+                       argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
+               } else if *flagHostBuildid == "none" {
+                       argv = append(argv, "-Wl,--build-id=none")
+               }
        }
 
        // On Windows, given -o foo, GCC will append ".exe" to produce
index 532d6dc80ea891912182e9bb0a97d92a56c11956..17a05414e49d9906d11531f10fc6f71b1f53b056 100644 (file)
@@ -294,7 +294,7 @@ func Main(arch *sys.Arch, theArch Arch) {
                *flagBuildid = "go-openbsd"
        }
 
-       if *flagHostBuildid == "" && *flagBuildid != "" && ctxt.IsDarwin() {
+       if *flagHostBuildid == "" && *flagBuildid != "" {
                *flagHostBuildid = "gobuildid"
        }
        addbuildinfo(ctxt)