[dev.link] cmd/link: remove *Link from relocsym

This is the last step requried before relocsym can go parallel.

Change-Id: Id1c1c530c2b9277917208c3767eeb29e02c17a9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/220841
Run-TryBot: Jeremy Faller <jeremy@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Jeremy Faller 2020-02-24 21:07:26 -05:00
parent 4ab7ab54b0
commit 7d8aef689d
4 changed files with 32 additions and 21 deletions

View file

@ -100,7 +100,7 @@ func trampoline(ctxt *Link, s *sym.Symbol) {
if Symaddr(r.Sym) == 0 && (r.Sym.Type != sym.SDYNIMPORT && r.Sym.Type != sym.SUNDEFEXT) { if Symaddr(r.Sym) == 0 && (r.Sym.Type != sym.SDYNIMPORT && r.Sym.Type != sym.SUNDEFEXT) {
if r.Sym.File != s.File { if r.Sym.File != s.File {
if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) { if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) {
ctxt.errorUnresolved(ctxt.Syms.ROLookup, s, r) ctxt.errorUnresolved(s, r)
} }
// runtime and its dependent packages may call to each other. // runtime and its dependent packages may call to each other.
// they are fine, as they will be laid down together. // they are fine, as they will be laid down together.
@ -127,7 +127,7 @@ func trampoline(ctxt *Link, s *sym.Symbol) {
// //
// This is a performance-critical function for the linker; be careful // This is a performance-critical function for the linker; be careful
// to avoid introducing unnecessary allocations in the main loop. // to avoid introducing unnecessary allocations in the main loop.
func relocsym(ctxt *Link, target *Target, s *sym.Symbol) { func relocsym(target *Target, err *ErrorReporter, lookup LookupFn, syms *ArchSyms, s *sym.Symbol) {
if len(s.R) == 0 { if len(s.R) == 0 {
return return
} }
@ -167,7 +167,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
continue continue
} }
} else { } else {
ctxt.errorUnresolved(ctxt.Syms.ROLookup, s, r) err.errorUnresolved(s, r)
continue continue
} }
} }
@ -222,7 +222,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
case 8: case 8:
o = int64(target.Arch.ByteOrder.Uint64(s.P[off:])) o = int64(target.Arch.ByteOrder.Uint64(s.P[off:]))
} }
if offset, ok := thearch.Archreloc(target, &ctxt.ArchSyms, r, s, o); ok { if offset, ok := thearch.Archreloc(target, syms, r, s, o); ok {
o = offset o = offset
} else { } else {
Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(target.Arch, r.Type)) Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(target.Arch, r.Type))
@ -231,7 +231,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
if target.IsExternal() && target.IsElf() { if target.IsExternal() && target.IsElf() {
r.Done = false r.Done = false
if r.Sym == nil { if r.Sym == nil {
r.Sym = ctxt.Tlsg r.Sym = syms.Tlsg
} }
r.Xsym = r.Sym r.Xsym = r.Sym
r.Xadd = r.Add r.Xadd = r.Add
@ -252,7 +252,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
// to take up 8 bytes. // to take up 8 bytes.
o = 8 + r.Sym.Value o = 8 + r.Sym.Value
} else if target.IsElf() || target.IsPlan9() || target.IsDarwin() { } else if target.IsElf() || target.IsPlan9() || target.IsDarwin() {
o = int64(ctxt.Tlsoffset) + r.Add o = int64(syms.Tlsoffset) + r.Add
} else if target.IsWindows() { } else if target.IsWindows() {
o = r.Add o = r.Add
} else { } else {
@ -262,7 +262,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
if target.IsExternal() && target.IsElf() { if target.IsExternal() && target.IsElf() {
r.Done = false r.Done = false
if r.Sym == nil { if r.Sym == nil {
r.Sym = ctxt.Tlsg r.Sym = syms.Tlsg
} }
r.Xsym = r.Sym r.Xsym = r.Sym
r.Xadd = r.Add r.Xadd = r.Add
@ -279,8 +279,8 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
log.Fatalf("internal linking of TLS IE not supported on %v", target.Arch.Family) log.Fatalf("internal linking of TLS IE not supported on %v", target.Arch.Family)
} }
thearch.TLSIEtoLE(s, int(off), int(r.Siz)) thearch.TLSIEtoLE(s, int(off), int(r.Siz))
o = int64(ctxt.Tlsoffset) o = int64(syms.Tlsoffset)
// TODO: o += r.Add when ctxt.Arch.Family != sys.AMD64? // TODO: o += r.Add when !target.IsAmd64()?
// Why do we treat r.Add differently on AMD64? // Why do we treat r.Add differently on AMD64?
// Is the external linker using Xadd at all? // Is the external linker using Xadd at all?
} else { } else {
@ -376,7 +376,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
r.Type = objabi.R_ADDR r.Type = objabi.R_ADDR
} }
r.Xsym = ctxt.Syms.ROLookup(r.Sym.Sect.Name, 0) r.Xsym = lookup(r.Sym.Sect.Name, 0)
r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
o = r.Xadd o = r.Xadd
@ -520,7 +520,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
if target.IsPPC64() || target.IsS390X() { if target.IsPPC64() || target.IsS390X() {
r.InitExt() r.InitExt()
if r.Variant != sym.RV_NONE { if r.Variant != sym.RV_NONE {
o = thearch.Archrelocvariant(target, &ctxt.ArchSyms, r, s, o) o = thearch.Archrelocvariant(target, syms, r, s, o)
} }
} }
@ -571,14 +571,18 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
} }
func (ctxt *Link) reloc() { func (ctxt *Link) reloc() {
target := &ctxt.Target
reporter := &ctxt.ErrorReporter
lookup := ctxt.Syms.ROLookup
syms := &ctxt.ArchSyms
for _, s := range ctxt.Textp { for _, s := range ctxt.Textp {
relocsym(ctxt, &ctxt.Target, s) relocsym(target, reporter, lookup, syms, s)
} }
for _, s := range datap { for _, s := range datap {
relocsym(ctxt, &ctxt.Target, s) relocsym(target, reporter, lookup, syms, s)
} }
for _, s := range dwarfp { for _, s := range dwarfp {
relocsym(ctxt, &ctxt.Target, s) relocsym(target, reporter, lookup, syms, s)
} }
} }
@ -2453,6 +2457,10 @@ func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte {
if err != nil { if err != nil {
log.Fatalf("NewWriterLevel failed: %s", err) log.Fatalf("NewWriterLevel failed: %s", err)
} }
target := &ctxt.Target
reporter := &ctxt.ErrorReporter
lookup := ctxt.Syms.ROLookup
archSyms := &ctxt.ArchSyms
for _, s := range syms { for _, s := range syms {
// s.P may be read-only. Apply relocations in a // s.P may be read-only. Apply relocations in a
// temporary buffer, and immediately write it out. // temporary buffer, and immediately write it out.
@ -2463,7 +2471,7 @@ func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte {
s.P = relocbuf s.P = relocbuf
s.Attr.Set(sym.AttrReadOnly, false) s.Attr.Set(sym.AttrReadOnly, false)
} }
relocsym(ctxt, &ctxt.Target, s) relocsym(target, reporter, lookup, archSyms, s)
if _, err := z.Write(s.P); err != nil { if _, err := z.Write(s.P); err != nil {
log.Fatalf("compression failed: %s", err) log.Fatalf("compression failed: %s", err)
} }

View file

@ -14,17 +14,18 @@ type unresolvedSymKey struct {
to *sym.Symbol // Unresolved symbol referenced by "from" to *sym.Symbol // Unresolved symbol referenced by "from"
} }
type lookupFn func(name string, version int) *sym.Symbol
// ErrorReporter is used to make error reporting thread safe. // ErrorReporter is used to make error reporting thread safe.
type ErrorReporter struct { type ErrorReporter struct {
unresOnce sync.Once unresOnce sync.Once
unresSyms map[unresolvedSymKey]bool unresSyms map[unresolvedSymKey]bool
unresMutex sync.Mutex unresMutex sync.Mutex
lookup lookupFn
} }
type roLookup func(name string, v int) *sym.Symbol
// errorUnresolved prints unresolved symbol error for r.Sym that is referenced from s. // errorUnresolved prints unresolved symbol error for r.Sym that is referenced from s.
func (reporter *ErrorReporter) errorUnresolved(lookup roLookup, s *sym.Symbol, r *sym.Reloc) { func (reporter *ErrorReporter) errorUnresolved(s *sym.Symbol, r *sym.Reloc) {
reporter.unresOnce.Do(func() { reporter.unresSyms = make(map[unresolvedSymKey]bool) }) reporter.unresOnce.Do(func() { reporter.unresSyms = make(map[unresolvedSymKey]bool) })
k := unresolvedSymKey{from: s, to: r.Sym} k := unresolvedSymKey{from: s, to: r.Sym}
@ -43,7 +44,7 @@ func (reporter *ErrorReporter) errorUnresolved(lookup roLookup, s *sym.Symbol, r
if v == -1 { if v == -1 {
continue continue
} }
if rs := lookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx { if rs := reporter.lookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx {
haveABI = abi haveABI = abi
} }
} }

View file

@ -105,6 +105,9 @@ type ArchSyms struct {
GOT *sym.Symbol GOT *sym.Symbol
PLT *sym.Symbol PLT *sym.Symbol
GOTPLT *sym.Symbol GOTPLT *sym.Symbol
Tlsg *sym.Symbol
Tlsoffset int
} }
// setArchSyms sets up the ArchSyms structure, and must be called before // setArchSyms sets up the ArchSyms structure, and must be called before
@ -2651,6 +2654,7 @@ func (ctxt *Link) loadlibfull() {
// Pull the symbols out. // Pull the symbols out.
ctxt.loader.ExtractSymbols(ctxt.Syms, ctxt.Reachparent) ctxt.loader.ExtractSymbols(ctxt.Syms, ctxt.Reachparent)
ctxt.lookup = ctxt.Syms.ROLookup
// When we generated dwarf DIE objects, we created them // When we generated dwarf DIE objects, we created them
// with embedded loader.Sym refs as opposed to sym.Symbol refs. // with embedded loader.Sym refs as opposed to sym.Symbol refs.

View file

@ -64,13 +64,11 @@ type Link struct {
compressDWARF bool compressDWARF bool
Tlsg *sym.Symbol
Tlsg2 loader.Sym Tlsg2 loader.Sym
Libdir []string Libdir []string
Library []*sym.Library Library []*sym.Library
LibraryByPkg map[string]*sym.Library LibraryByPkg map[string]*sym.Library
Shlibs []Shlib Shlibs []Shlib
Tlsoffset int
Textp []*sym.Symbol Textp []*sym.Symbol
Textp2 []loader.Sym Textp2 []loader.Sym
Filesyms []*sym.Symbol Filesyms []*sym.Symbol