diff -r c36e3195e3e9 -r 9c955076ffe3 components/golang/patches/0056-release-branch.go1.5-cmd-go-fix-Go-buildid-reading-o.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/golang/patches/0056-release-branch.go1.5-cmd-go-fix-Go-buildid-reading-o.patch Thu Jan 21 09:20:59 2016 -0800 @@ -0,0 +1,134 @@ +From 61e1caee5b3a79f8986248541839eb15d311a3a9 Mon Sep 17 00:00:00 2001 +From: Shawn Walker-Salas +Date: Wed, 26 Aug 2015 15:24:41 -0700 +Subject: [PATCH 56/63] [release-branch.go1.5] cmd/go: fix Go buildid reading + on Solaris +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +TestNoteReading fails on Solaris with linkmode=external due to some +assumptions made about how ELF .note sections are written by some +linkers. + +On current versions of Solaris and older derivatives, SHF_ALLOC is +intentionally ignored for .note sections unless the .note section is +assigned to the text segment via a mapfile. Also, if .note sections +are assigned to the text segment, no PT_NOTE program header will be +created thwarting Go's attempts at attempting to quickly find the +.note. + +Furthermore, Go assumes that the relevant note segment will be placed +early in the file while the Solaris linker currently places the note +segment last in the file, additionally thwarting Go's optimisation +attempts that read only the first 16KB of the file to find the +buildid. + +The fix is to detect when the note section is outside of the first +16KB of the file and then fallback to additionally reading that +section of the file. This way, in future versions of Solaris when +this linking behaviour is changed, the fast path will always succeed +and we'll only be slower if it fails; likewise, any other linker that +does this will also just work. + +Fixes #12178 + +Change-Id: I61c1dc3f744ae3ad63938386d2ace8a432c0efe1 +Reviewed-on: https://go-review.googlesource.com/14210 +Run-TryBot: Aram Hăvărneanu +Reviewed-by: Aram Hăvărneanu +Reviewed-on: https://go-review.googlesource.com/17142 +Run-TryBot: Russ Cox +Reviewed-by: Russ Cox +--- + src/cmd/go/note.go | 32 ++++++++++++++++++++++++++------ + src/cmd/go/note_test.go | 3 --- + src/cmd/link/internal/ld/elf.go | 4 ---- + 3 files changed, 26 insertions(+), 13 deletions(-) + +diff --git a/src/cmd/go/note.go b/src/cmd/go/note.go +index f8d6588..c7346a5 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 a5ecab1..39b79c5 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 c9a5c99..9dedb0e 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 +-- +2.6.1 +