diff options
-rw-r--r-- | src/cmd/go/testdata/script/version_gc_sections.txt | 24 | ||||
-rw-r--r-- | src/cmd/link/internal/ld/data.go | 13 |
2 files changed, 36 insertions, 1 deletions
diff --git a/src/cmd/go/testdata/script/version_gc_sections.txt b/src/cmd/go/testdata/script/version_gc_sections.txt new file mode 100644 index 0000000000..6dabd96162 --- /dev/null +++ b/src/cmd/go/testdata/script/version_gc_sections.txt @@ -0,0 +1,24 @@ +# This test checks that external linking with --gc-sections does not strip version information. + +[short] skip +[!cgo] skip +[aix] skip # no --gc-sections +[darwin] skip # no --gc-sections + +go build -ldflags='-linkmode=external -extldflags=-Wl,--gc-sections' +go version hello$GOEXE +! stdout 'not a Go executable' +! stderr 'not a Go executable' + +-- go.mod -- +module hello +-- hello.go -- +package main + +/* +*/ +import "C" + +func main() { + println("hello") +} diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index cb2afeaa9a..e1a211a16e 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -1601,6 +1601,9 @@ func (ctxt *Link) dodata(symGroupType []sym.SymKind) { func (state *dodataState) allocateDataSectionForSym(seg *sym.Segment, s loader.Sym, rwx int) *sym.Section { ldr := state.ctxt.loader sname := ldr.SymName(s) + if sname == "go.buildinfo" { // clumsy hack for Go 1.19 builders + sname = ".go.buildinfo" + } sect := addsection(ldr, state.ctxt.Arch, seg, sname, rwx) sect.Align = symalign(ldr, s) state.datsize = Rnd(state.datsize, int64(sect.Align)) @@ -2177,7 +2180,7 @@ func (ctxt *Link) buildinfo() { // Write the buildinfo symbol, which go version looks for. // The code reading this data is in package debug/buildinfo. ldr := ctxt.loader - s := ldr.CreateSymForUpdate(".go.buildinfo", 0) + s := ldr.CreateSymForUpdate("go.buildinfo", 0) s.SetType(sym.SBUILDINFO) s.SetAlign(16) // The \xff is invalid UTF-8, meant to make it less likely @@ -2199,6 +2202,14 @@ func (ctxt *Link) buildinfo() { } s.SetData(data) s.SetSize(int64(len(data))) + + // Add reference to go:buildinfo from the rodata section, + // so that external linking with -Wl,--gc-sections does not + // delete the build info. + sr := ldr.CreateSymForUpdate("go.buildinfo.ref", 0) + sr.SetType(sym.SRODATA) + sr.SetAlign(int32(ctxt.Arch.PtrSize)) + sr.AddAddr(ctxt.Arch, s.Sym()) } // appendString appends s to data, prefixed by its varint-encoded length. |