From: Cherry Zhang Date: Thu, 30 Apr 2020 20:28:49 +0000 (-0400) Subject: [dev.link] cmd/link: batch allocations when converting external relocations X-Git-Tag: go1.15beta1~259^2^2~2 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=83db26ac4aae372e470c07fbe2cac37d6b540aa8;p=gostls13.git [dev.link] cmd/link: batch allocations when converting external relocations Change-Id: Iad81cb159e46f694a03d58892ca7dfde3ee3095a Reviewed-on: https://go-review.googlesource.com/c/go/+/231219 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: Jeremy Faller Reviewed-by: Than McIntosh --- diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 60c38cc1d4..e1d5c864ab 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -284,7 +284,8 @@ type Loader struct { // the symbol that triggered the marking of symbol K as live. Reachparent []Sym - relocBatch []sym.Reloc // for bulk allocation of relocations + relocBatch []sym.Reloc // for bulk allocation of relocations + relocExtBatch []sym.RelocExt // for bulk allocation of relocations flags uint32 @@ -2037,9 +2038,16 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc bool) { l.growSyms(l.NSym()) l.growSects(l.NSym()) + if needReloc && len(l.extRelocs) != 0 { + // If needReloc is true, we are going to convert the loader's + // "internal" relocations to sym.Relocs. In this case, external + // relocations shouldn't be used. + panic("phase error") + } + nr := 0 // total number of sym.Reloc's we'll need for _, o := range l.objs[1:] { - nr += loadObjSyms(l, syms, o.r) + nr += loadObjSyms(l, syms, o.r, needReloc) } // Make a first pass through the external symbols, making @@ -2052,7 +2060,12 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc bool) { continue } pp := l.getPayload(i) - nr += len(pp.relocs) + if needReloc { + nr += len(pp.relocs) + } + if int(i) < len(l.extRelocs) { + nr += len(l.extRelocs[i]) + } // create and install the sym.Symbol here so that l.Syms will // be fully populated when we do relocation processing and // outer/sub processing below. Note that once we do this, @@ -2064,8 +2077,11 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc bool) { } // allocate a single large slab of relocations for all live symbols - if needReloc { + if nr != 0 { l.relocBatch = make([]sym.Reloc, nr) + if len(l.extRelocs) != 0 { + l.relocExtBatch = make([]sym.RelocExt, nr) + } } // convert payload-based external symbols into sym.Symbol-based @@ -2101,6 +2117,11 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc bool) { loadObjFull(l, o.r, needReloc) } + // Sanity check: we should have consumed all batched allocations. + if len(l.relocBatch) != 0 || len(l.relocExtBatch) != 0 { + panic("batch allocation mismatch") + } + // Note: resolution of ABI aliases is now also handled in // loader.convertRelocations, so once the host object loaders move // completely to loader.Sym, we can remove the code below. @@ -2417,7 +2438,7 @@ func topLevelSym(sname string, skind sym.SymKind) bool { // loadObjSyms creates sym.Symbol objects for the live Syms in the // object corresponding to object reader "r". Return value is the // number of sym.Reloc entries required for all the new symbols. -func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) int { +func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader, needReloc bool) int { nr := 0 for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ { gi := r.syms[i] @@ -2447,7 +2468,12 @@ func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) int { } l.addNewSym(gi, name, ver, r.unit, t) - nr += r.NReloc(i) + if needReloc { + nr += r.NReloc(i) + } + if int(gi) < len(l.extRelocs) { + nr += len(l.extRelocs[gi]) + } } return nr } @@ -2764,13 +2790,18 @@ func (l *Loader) convertExtRelocs(dst *sym.Symbol, src Sym) { if len(dst.R) != 0 { panic("bad") } - dst.R = make([]sym.Reloc, len(extRelocs)) + + n := len(extRelocs) + batch := l.relocBatch + dst.R = batch[:n:n] + l.relocBatch = batch[n:] relocs := l.Relocs(src) for i := range dst.R { er := &extRelocs[i] sr := relocs.At2(er.Idx) r := &dst.R[i] - r.InitExt() + r.RelocExt = &l.relocExtBatch[0] + l.relocExtBatch = l.relocExtBatch[1:] r.Off = sr.Off() r.Siz = sr.Siz() r.Type = sr.Type() diff --git a/src/cmd/link/internal/sym/reloc.go b/src/cmd/link/internal/sym/reloc.go index 4809db8c80..f589447be8 100644 --- a/src/cmd/link/internal/sym/reloc.go +++ b/src/cmd/link/internal/sym/reloc.go @@ -28,20 +28,20 @@ type Reloc struct { Type objabi.RelocType // the relocation type Add int64 // addend Sym *Symbol // symbol the relocation addresses - *relocExt // extra fields (see below), may be nil, call InitExt before use + *RelocExt // extra fields (see below), may be nil, call InitExt before use } // relocExt contains extra fields in Reloc that are used only in // certain cases. -type relocExt struct { +type RelocExt struct { Xadd int64 // addend passed to external linker Xsym *Symbol // symbol passed to external linker Variant RelocVariant // variation on Type, currently used only on PPC64 and S390X } func (r *Reloc) InitExt() { - if r.relocExt == nil { - r.relocExt = new(relocExt) + if r.RelocExt == nil { + r.RelocExt = new(RelocExt) } }