From a9a1217112aa8f5e01fe2f3e5f203ac880dbd566 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Thu, 25 Jun 2020 22:22:59 -0400 Subject: [PATCH] [dev.link] cmd/link: handle runtime.text/etext symbols more consistently Currently, on most platforms, the start/end symbols runtime.text and runtime.etext are defined in symtab pass and assigned values in address pass. In some cases (darwin+dynlink or AIX+external), however, they are defined and assigned values in textaddress pass (because they need non-zero sizes). Then their values get overwritten in address pass. This is bad. The linker expects their values to be consistent. In particular, in CL 239281, findfunctab is split to two parts. The two parts need to have a consistent view of the start/end symbols. If its value changes in between, bad things can happen. This CL fixes it by always defining runtime.text/etext symbols in the textaddress pass. Fix darwin and AIX builds. Change-Id: Ifdc1bcb69d99be1b7e5b4fd31d473650c03e3b9d Reviewed-on: https://go-review.googlesource.com/c/go/+/240065 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: Jeremy Faller --- src/cmd/link/internal/ld/data.go | 26 +++++++++----------------- src/cmd/link/internal/ld/lib.go | 3 ++- src/cmd/link/internal/ld/symtab.go | 2 -- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 5234a2406a..be1af4bcae 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -2084,8 +2084,9 @@ func (ctxt *Link) textaddress() { sect.Align = int32(Funcalign) ldr := ctxt.loader - text := ldr.LookupOrCreateSym("runtime.text", 0) - ldr.SetAttrReachable(text, true) + + text := ctxt.xdefine("runtime.text", sym.STEXT, 0) + etext := ctxt.xdefine("runtime.etext", sym.STEXT, 0) ldr.SetSymSect(text, sect) if ctxt.IsAIX() && ctxt.IsExternal() { // Setting runtime.text has a real symbol prevents ld to @@ -2097,9 +2098,7 @@ func (ctxt *Link) textaddress() { } if (ctxt.DynlinkingGo() && ctxt.IsDarwin()) || (ctxt.IsAIX() && ctxt.IsExternal()) { - etext := ldr.LookupOrCreateSym("runtime.etext", 0) ldr.SetSymSect(etext, sect) - ctxt.Textp = append(ctxt.Textp, etext, 0) copy(ctxt.Textp[1:], ctxt.Textp) ctxt.Textp[0] = text @@ -2126,9 +2125,13 @@ func (ctxt *Link) textaddress() { } sect.Length = va - sect.Vaddr - etext := ldr.LookupOrCreateSym("runtime.etext", 0) - ldr.SetAttrReachable(etext, true) ldr.SetSymSect(etext, sect) + if ldr.SymValue(etext) == 0 { + // Set the address of the start/end symbols, if not already + // (i.e. not darwin+dynlink or AIX+external, see above). + ldr.SetSymValue(etext, int64(va)) + ldr.SetSymValue(text, *FlagTextAddr) + } // merge tramps into Textp, keeping Textp in address order if ntramps != 0 { @@ -2351,20 +2354,12 @@ func (ctxt *Link) address() []*sym.Segment { ldr := ctxt.loader var ( - text = Segtext.Sections[0] rodata = ldr.SymSect(ldr.LookupOrCreateSym("runtime.rodata", 0)) itablink = ldr.SymSect(ldr.LookupOrCreateSym("runtime.itablink", 0)) symtab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.symtab", 0)) pclntab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0)) types = ldr.SymSect(ldr.LookupOrCreateSym("runtime.types", 0)) ) - lasttext := text - // Could be multiple .text sections - for _, sect := range Segtext.Sections { - if sect.Name == ".text" { - lasttext = sect - } - } for _, s := range ctxt.datap { if sect := ldr.SymSect(s); sect != nil { @@ -2399,9 +2394,6 @@ func (ctxt *Link) address() []*sym.Segment { ldr.SetSymValue(s, int64(sect.Vaddr+16)) } - ctxt.xdefine("runtime.text", sym.STEXT, int64(text.Vaddr)) - ctxt.xdefine("runtime.etext", sym.STEXT, int64(lasttext.Vaddr+lasttext.Length)) - // If there are multiple text sections, create runtime.text.n for // their section Vaddr, using n for index n := 1 diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index ed59e6af27..fbf72f6715 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -2376,13 +2376,14 @@ const ( DeletedAutoSym = 'x' ) -func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) { +func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) loader.Sym { ldr := ctxt.loader s := ldr.CreateSymForUpdate(p, 0) s.SetType(t) s.SetValue(v) s.SetSpecial(true) s.SetLocal(true) + return s.Sym() } func datoff(ldr *loader.Loader, s loader.Sym, addr int64) int64 { diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index 1c70a94e1a..a2aabbb108 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -409,8 +409,6 @@ func (ctxt *Link) symtab() []sym.SymKind { // Define these so that they'll get put into the symbol table. // data.c:/^address will provide the actual values. - ctxt.xdefine("runtime.text", sym.STEXT, 0) - ctxt.xdefine("runtime.etext", sym.STEXT, 0) ctxt.xdefine("runtime.itablink", sym.SRODATA, 0) ctxt.xdefine("runtime.eitablink", sym.SRODATA, 0) ctxt.xdefine("runtime.rodata", sym.SRODATA, 0) -- 2.48.1