diff options
author | Cherry Zhang <cherryyz@google.com> | 2020-04-30 16:28:49 -0400 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2020-05-01 13:53:45 +0000 |
commit | 83db26ac4aae372e470c07fbe2cac37d6b540aa8 (patch) | |
tree | fb0599a8d98a68de255d1cf524ebff969d23adba /src/cmd/link/internal/loader/loader.go | |
parent | f875f8fe76160699432cdab8a23cfd292462c2b3 (diff) | |
download | go-83db26ac4aae372e470c07fbe2cac37d6b540aa8.tar.gz go-83db26ac4aae372e470c07fbe2cac37d6b540aa8.zip |
[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 <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/cmd/link/internal/loader/loader.go')
-rw-r--r-- | src/cmd/link/internal/loader/loader.go | 47 |
1 files changed, 39 insertions, 8 deletions
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() |