aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/go/note.go32
-rw-r--r--src/cmd/go/note_test.go3
-rw-r--r--src/cmd/link/internal/ld/elf.go4
3 files changed, 26 insertions, 13 deletions
diff --git a/src/cmd/go/note.go b/src/cmd/go/note.go
index f8d6588b73..c7346a5731 100644
--- a/src/cmd/go/note.go
+++ b/src/cmd/go/note.go
@@ -70,11 +70,11 @@ func readELFNote(filename, name string, typ int32) ([]byte, error) {
var elfGoNote = []byte("Go\x00\x00")
-// readELFGoBuildID the Go build ID string from an ELF binary.
-// The Go build ID is stored in a note described by an ELF PT_NOTE prog header.
-// The caller has already opened filename, to get f, and read the first 4 kB out, in data.
+// The Go build ID is stored in a note described by an ELF PT_NOTE prog
+// header. The caller has already opened filename, to get f, and read
+// at least 4 kB out, in data.
func readELFGoBuildID(filename string, f *os.File, data []byte) (buildid string, err error) {
- // Assume the note content is in the first 4 kB, already read.
+ // Assume the note content is in the data, already read.
// Rewrite the ELF header to set shnum to 0, so that we can pass
// the data to elf.NewFile and it will decode the Prog list but not
// try to read the section headers and the string table from disk.
@@ -96,11 +96,31 @@ func readELFGoBuildID(filename string, f *os.File, data []byte) (buildid string,
return "", &os.PathError{Path: filename, Op: "parse", Err: err}
}
for _, p := range ef.Progs {
- if p.Type != elf.PT_NOTE || p.Off >= uint64(len(data)) || p.Off+p.Filesz >= uint64(len(data)) || p.Filesz < 16 {
+ if p.Type != elf.PT_NOTE || p.Filesz < 16 {
continue
}
- note := data[p.Off : p.Off+p.Filesz]
+ var note []byte
+ if p.Off+p.Filesz < uint64(len(data)) {
+ note = data[p.Off : p.Off+p.Filesz]
+ } else {
+ // For some linkers, such as the Solaris linker,
+ // the buildid may not be found in data (which
+ // likely contains the first 16kB of the file)
+ // or even the first few megabytes of the file
+ // due to differences in note segment placement;
+ // in that case, extract the note data manually.
+ _, err = f.Seek(int64(p.Off), 0)
+ if err != nil {
+ return "", err
+ }
+
+ note = make([]byte, p.Filesz)
+ _, err = io.ReadFull(f, note)
+ if err != nil {
+ return "", err
+ }
+ }
nameSize := ef.ByteOrder.Uint32(note)
valSize := ef.ByteOrder.Uint32(note[4:])
tag := ef.ByteOrder.Uint32(note[8:])
diff --git a/src/cmd/go/note_test.go b/src/cmd/go/note_test.go
index a5ecab17ed..39b79c5cfd 100644
--- a/src/cmd/go/note_test.go
+++ b/src/cmd/go/note_test.go
@@ -50,9 +50,6 @@ func testNoteReading(t *testing.T) {
// no external linking
t.Logf("no external linking - skipping linkmode=external test")
- case "solaris":
- t.Logf("skipping - golang.org/issue/12178")
-
default:
tg.run("build", "-ldflags", "-buildid="+buildID+" -linkmode=external", "-o", tg.path("hello.exe"), tg.path("hello.go"))
id, err := main.ReadBuildIDFromBinary(tg.path("hello.exe"))
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index c9a5c99c34..9dedb0eabe 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -1739,10 +1739,6 @@ func doelf() {
Addstring(shstrtab, ".note.go.pkg-list")
Addstring(shstrtab, ".note.go.deps")
}
-
- if buildid != "" {
- Addstring(shstrtab, ".note.go.buildid")
- }
}
hasinitarr := Linkshared