]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: batch allocations when converting external relocations
authorCherry Zhang <cherryyz@google.com>
Thu, 30 Apr 2020 20:28:49 +0000 (16:28 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 1 May 2020 13:53:45 +0000 (13:53 +0000)
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>
src/cmd/link/internal/loader/loader.go
src/cmd/link/internal/sym/reloc.go

index 60c38cc1d459cf293f8281a58ebc0724d1e3747a..e1d5c864ab913a0a69f6cd51d80f73917570dec7 100644 (file)
@@ -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()
index 4809db8c800506224bb3dccaa8bc3db345adb753..f589447be86641d29f73d4799c8fa4b3c2202793 100644 (file)
@@ -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)
        }
 }