mirror of https://github.com/golang/go.git
cmd/link: merge note sections into one segment
The ld from binutils merges note sections into one PT_NOTE segment. We should do that for consistency with binutils. Change-Id: I45703525c720972d49c36c4f10ac47d1628b5698 Reviewed-on: https://go-review.googlesource.com/c/go/+/265957 Trust: Meng Zhuo <mzh@golangcn.org> Trust: Emmanuel Odeke <emmanuel@orijtech.com> Run-TryBot: Meng Zhuo <mzh@golangcn.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
78af02e8b5
commit
1ea4d3b911
|
|
@ -201,6 +201,61 @@ func TestMinusRSymsWithSameName(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMergeNoteSections(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
expected := 1
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "linux", "freebsd", "dragonfly":
|
||||
case "openbsd", "netbsd":
|
||||
// These OSes require independent segment
|
||||
expected = 2
|
||||
default:
|
||||
t.Skip("We should only test on elf output.")
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
goFile := filepath.Join(t.TempDir(), "notes.go")
|
||||
if err := ioutil.WriteFile(goFile, []byte(goSource), 0444); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
outFile := filepath.Join(t.TempDir(), "notes.exe")
|
||||
goTool := testenv.GoToolPath(t)
|
||||
// sha1sum of "gopher"
|
||||
id := "0xf4e8cd51ce8bae2996dc3b74639cdeaa1f7fee5f"
|
||||
cmd := exec.Command(goTool, "build", "-o", outFile, "-ldflags",
|
||||
"-B "+id, goFile)
|
||||
cmd.Dir = t.TempDir()
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ef, err := elf.Open(outFile)
|
||||
if err != nil {
|
||||
t.Fatalf("open elf file failed:%v", err)
|
||||
}
|
||||
defer ef.Close()
|
||||
sec := ef.Section(".note.gnu.build-id")
|
||||
if sec == nil {
|
||||
t.Fatalf("can't find gnu build id")
|
||||
}
|
||||
|
||||
sec = ef.Section(".note.go.buildid")
|
||||
if sec == nil {
|
||||
t.Fatalf("can't find go build id")
|
||||
}
|
||||
cnt := 0
|
||||
for _, ph := range ef.Progs {
|
||||
if ph.Type == elf.PT_NOTE {
|
||||
cnt += 1
|
||||
}
|
||||
}
|
||||
if cnt != expected {
|
||||
t.Fatalf("want %d PT_NOTE segment, got %d", expected, cnt)
|
||||
}
|
||||
}
|
||||
|
||||
const pieSourceTemplate = `
|
||||
package main
|
||||
|
||||
|
|
|
|||
|
|
@ -1682,13 +1682,18 @@ func asmbElf(ctxt *Link) {
|
|||
|
||||
var pph *ElfPhdr
|
||||
var pnote *ElfPhdr
|
||||
getpnote := func() *ElfPhdr {
|
||||
if pnote == nil {
|
||||
pnote = newElfPhdr()
|
||||
pnote.Type = elf.PT_NOTE
|
||||
pnote.Flags = elf.PF_R
|
||||
}
|
||||
return pnote
|
||||
}
|
||||
if *flagRace && ctxt.IsNetbsd() {
|
||||
sh := elfshname(".note.netbsd.pax")
|
||||
resoff -= int64(elfnetbsdpax(sh, uint64(startva), uint64(resoff)))
|
||||
pnote = newElfPhdr()
|
||||
pnote.Type = elf.PT_NOTE
|
||||
pnote.Flags = elf.PF_R
|
||||
phsh(pnote, sh)
|
||||
phsh(getpnote(), sh)
|
||||
}
|
||||
if ctxt.LinkMode == LinkExternal {
|
||||
/* skip program headers */
|
||||
|
|
@ -1787,7 +1792,6 @@ func asmbElf(ctxt *Link) {
|
|||
phsh(ph, sh)
|
||||
}
|
||||
|
||||
pnote = nil
|
||||
if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd {
|
||||
var sh *ElfShdr
|
||||
switch ctxt.HeadType {
|
||||
|
|
@ -1799,34 +1803,23 @@ func asmbElf(ctxt *Link) {
|
|||
sh = elfshname(".note.openbsd.ident")
|
||||
resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
|
||||
}
|
||||
|
||||
pnote = newElfPhdr()
|
||||
pnote.Type = elf.PT_NOTE
|
||||
pnote.Flags = elf.PF_R
|
||||
phsh(pnote, sh)
|
||||
// netbsd and openbsd require ident in an independent segment.
|
||||
pnotei := newElfPhdr()
|
||||
pnotei.Type = elf.PT_NOTE
|
||||
pnotei.Flags = elf.PF_R
|
||||
phsh(pnotei, sh)
|
||||
}
|
||||
|
||||
if len(buildinfo) > 0 {
|
||||
sh := elfshname(".note.gnu.build-id")
|
||||
resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
|
||||
|
||||
if pnote == nil {
|
||||
pnote = newElfPhdr()
|
||||
pnote.Type = elf.PT_NOTE
|
||||
pnote.Flags = elf.PF_R
|
||||
}
|
||||
|
||||
phsh(pnote, sh)
|
||||
phsh(getpnote(), sh)
|
||||
}
|
||||
|
||||
if *flagBuildid != "" {
|
||||
sh := elfshname(".note.go.buildid")
|
||||
resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
|
||||
|
||||
pnote := newElfPhdr()
|
||||
pnote.Type = elf.PT_NOTE
|
||||
pnote.Flags = elf.PF_R
|
||||
phsh(pnote, sh)
|
||||
phsh(getpnote(), sh)
|
||||
}
|
||||
|
||||
// Additions to the reserved area must be above this line.
|
||||
|
|
|
|||
Loading…
Reference in New Issue