Commit 7556948e authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle Committed by Ian Lance Taylor

cmd/internal/ld: put the list of packages built into a shared library into an ELF note

Change-Id: I611f7dec2109dc7e2f090ced0a1dca3d4b577134
Reviewed-on: https://go-review.googlesource.com/9520Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
parent ccaaf1f1
......@@ -1039,11 +1039,13 @@ func elfwriteinterp() int {
return int(sh.size)
}
func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int, alloc bool) int {
n := 3*4 + uint64(sz) + resoff%4
sh.type_ = SHT_NOTE
sh.flags = SHF_ALLOC
if alloc {
sh.flags = SHF_ALLOC
}
sh.addralign = 4
sh.addr = startva + resoff - n
sh.off = resoff - n
......@@ -1077,7 +1079,7 @@ var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
return elfnote(sh, startva, resoff, n)
return elfnote(sh, startva, resoff, n, true)
}
func elfwritenetbsdsig() int {
......@@ -1109,7 +1111,7 @@ var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
return elfnote(sh, startva, resoff, n)
return elfnote(sh, startva, resoff, n, true)
}
func elfwriteopenbsdsig() int {
......@@ -1180,7 +1182,7 @@ var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
return elfnote(sh, startva, resoff, n)
return elfnote(sh, startva, resoff, n, true)
}
func elfwritebuildinfo() int {
......@@ -1197,6 +1199,32 @@ func elfwritebuildinfo() int {
return int(sh.size)
}
// Go package list note
const (
ELF_NOTE_GOPKGLIST_TAG = 1
)
var ELF_NOTE_GO_NAME = []byte("GO\x00\x00")
func elfgopkgnote(sh *ElfShdr, startva uint64, resoff uint64) int {
n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(pkglistfornote)), 4))
return elfnote(sh, startva, resoff, n, false)
}
func elfwritegopkgnote() int {
sh := elfwritenotehdr(".note.go.pkg-list", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(pkglistfornote)), ELF_NOTE_GOPKGLIST_TAG)
if sh == nil {
return 0
}
Cwrite(ELF_NOTE_GO_NAME)
Cwrite(pkglistfornote)
var zero = make([]byte, 4)
Cwrite(zero[:int(Rnd(int64(len(pkglistfornote)), 4)-int64(len(pkglistfornote)))])
return int(sh.size)
}
var elfverneed int
type Elfaux struct {
......@@ -1604,6 +1632,9 @@ func doelf() {
if len(buildinfo) > 0 {
Addstring(shstrtab, ".note.gnu.build-id")
}
if Buildmode == BuildmodeShared {
Addstring(shstrtab, ".note.go.pkg-list")
}
Addstring(shstrtab, ".elfdata")
Addstring(shstrtab, ".rodata")
Addstring(shstrtab, ".typelink")
......@@ -1888,6 +1919,11 @@ func Asmbelf(symo int64) {
eh.phoff = 0
eh.phentsize = 0
if Buildmode == BuildmodeShared {
sh := elfshname(".note.go.pkg-list")
resoff -= int64(elfgopkgnote(sh, uint64(startva), uint64(resoff)))
}
goto elfobj
}
......@@ -2296,6 +2332,9 @@ elfobj:
a += int64(elfwritebuildinfo())
}
}
if Buildmode == BuildmodeShared {
a += int64(elfwritegopkgnote())
}
if a > ELFRESERVE {
Diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE)
......
......@@ -516,6 +516,15 @@ func loadlib() {
if Ctxt.Library[i].Shlib != "" {
ldshlibsyms(Ctxt.Library[i].Shlib)
} else {
// Because the linker always looks for runtime/cgo when
// -buildmode=shared is passed, the go tool never passes
// runtime/cgo on the command line. But runtime/cgo needs
// to end up in the package list if it is being built into
// the shared libarary.
if Buildmode == BuildmodeShared {
pkglistfornote = append(pkglistfornote, "runtime/cgo"...)
pkglistfornote = append(pkglistfornote, '\n')
}
objfile(Ctxt.Library[i].File, Ctxt.Library[i].Pkg)
}
}
......
......@@ -38,6 +38,8 @@ import (
"strings"
)
var pkglistfornote []byte
// Reading object files.
func Ldmain() {
......@@ -196,6 +198,8 @@ func Ldmain() {
} else {
pkgpath, file = parts[0], parts[1]
}
pkglistfornote = append(pkglistfornote, pkgpath...)
pkglistfornote = append(pkglistfornote, '\n')
addlibpath(Ctxt, "command line", "command line", file, pkgpath, "")
}
} else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment