]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: use more compact representation for external relocations
authorCherry Zhang <cherryyz@google.com>
Thu, 30 Apr 2020 02:00:28 +0000 (22:00 -0400)
committerCherry Zhang <cherryyz@google.com>
Thu, 30 Apr 2020 21:30:02 +0000 (21:30 +0000)
Currently, for external relocations, the ExtReloc structure
contains all the fields of the relocation. In fact, many of the
fields are the same with the original relocation. So, instead, we
can just use an index to reference the original relocation and
not expand the fields.

There is one place where we modify relocation type: changing
R_DWARFSECTREF to R_ADDR. Get away with it by changing
downstreams.

It also makes it easier to retrieve the reloc variant.

This reduces some allocation. Linking cmd/compile with external
linking,

name           old alloc/op   new alloc/op   delta
Reloc_GC         34.1MB ± 0%    22.7MB ± 0%  -33.30%  (p=0.000 n=5+4)

Change-Id: Id08a89ed2aee705296886d3b95014b806a0d55cf
Reviewed-on: https://go-review.googlesource.com/c/go/+/231217
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/arm/asm.go
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/loader/loader.go
src/cmd/link/internal/mips/asm.go
src/cmd/link/internal/mips64/asm.go
src/cmd/link/internal/ppc64/asm.go
src/cmd/link/internal/s390x/asm.go
src/cmd/link/internal/x86/asm.go

index e1daaec2c73459cdbce683c88edc357b65d5779a..e2c33b80010a065b11cf1d5897712f46087627f0 100644 (file)
@@ -400,7 +400,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        switch r.Type {
        default:
                return false
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                if r.Siz == 4 {
                        ctxt.Out.Write64(uint64(elf.R_X86_64_32) | uint64(elfsym)<<32)
                } else if r.Siz == 8 {
index c95de0de2f153b24c71911f99961a4ac9d2463e4..a2024bcedec76df36714994162039b950759a61f 100644 (file)
@@ -256,7 +256,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        switch r.Type {
        default:
                return false
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                if r.Siz == 4 {
                        ctxt.Out.Write32(uint32(elf.R_ARM_ABS32) | uint32(elfsym)<<8)
                } else {
index 2d12fc2f5956c1640401a680980bceba61d25c20..dc3e45d6c07e89aa7135fcafd679248717bf90f2 100644 (file)
@@ -332,7 +332,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        switch r.Type {
        default:
                return false
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                switch r.Siz {
                case 4:
                        ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS32) | uint64(elfsym)<<32)
index af1b335db7b8a6bf471cfcd0afdedcc04873eaed..102fcabe47827679e0ac29ba78f7ab47847eac2d 100644 (file)
@@ -224,11 +224,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                var rr loader.ExtReloc
                needExtReloc := false // will set to true below in case it is needed
                if target.IsExternal() {
-                       rr.Sym = rs
-                       rr.Type = rt
-                       rr.Off = off
-                       rr.Siz = uint8(siz)
-                       rr.Add = r.Add()
+                       rr.Idx = ri
                }
 
                // TODO(mundaym): remove this special case - see issue 14218.
@@ -282,14 +278,14 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                case objabi.R_TLS_LE:
                        if target.IsExternal() && target.IsElf() {
                                needExtReloc = true
-                               if rr.Sym == 0 {
-                                       rr.Sym = syms.Tlsg2
+                               rr.Xsym = rs
+                               if rr.Xsym == 0 {
+                                       rr.Xsym = syms.Tlsg2
                                }
-                               rr.Xsym = rr.Sym
-                               rr.Xadd = rr.Add
+                               rr.Xadd = r.Add()
                                o = 0
                                if !target.IsAMD64() {
-                                       o = rr.Add
+                                       o = r.Add()
                                }
                                break
                        }
@@ -313,14 +309,14 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                case objabi.R_TLS_IE:
                        if target.IsExternal() && target.IsElf() {
                                needExtReloc = true
-                               if rr.Sym == 0 {
-                                       rr.Sym = syms.Tlsg2
+                               rr.Xsym = rs
+                               if rr.Xsym == 0 {
+                                       rr.Xsym = syms.Tlsg2
                                }
-                               rr.Xsym = rr.Sym
-                               rr.Xadd = rr.Add
+                               rr.Xadd = r.Add()
                                o = 0
                                if !target.IsAMD64() {
-                                       o = rr.Add
+                                       o = r.Add()
                                }
                                break
                        }
@@ -342,7 +338,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                // set up addend for eventual relocation via outer symbol.
                                rs := rs
                                rs, off := foldSubSymbolOffset(ldr, rs)
-                               rr.Xadd = rr.Add + off
+                               rr.Xadd = r.Add() + off
                                rst := ldr.SymType(rs)
                                if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
                                        st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs))
@@ -361,7 +357,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                } else if target.IsWindows() {
                                        // nothing to do
                                } else if target.IsAIX() {
-                                       o = ldr.SymValue(rr.Sym) + rr.Add
+                                       o = ldr.SymValue(rs) + r.Add()
                                } else {
                                        st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
                                }
@@ -413,17 +409,8 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                        needExtReloc = false
                                }
 
-                               // PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL
-                               // for R_DWARFSECREF relocations, while R_ADDR is replaced with
-                               // IMAGE_REL_I386_DIR32, IMAGE_REL_AMD64_ADDR64 and IMAGE_REL_AMD64_ADDR32.
-                               // Do not replace R_DWARFSECREF with R_ADDR for windows -
-                               // let PE code emit correct relocations.
-                               if !target.IsWindows() {
-                                       rr.Type = objabi.R_ADDR
-                               }
-
-                               rr.Xsym = loader.Sym(ldr.SymSect(rr.Sym).Sym2)
-                               rr.Xadd = rr.Add + ldr.SymValue(rr.Sym) - int64(ldr.SymSect(rr.Sym).Vaddr)
+                               rr.Xsym = loader.Sym(ldr.SymSect(rs).Sym2)
+                               rr.Xadd = r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr)
 
                                o = rr.Xadd
                                if target.IsElf() && target.IsAMD64() {
@@ -455,12 +442,12 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                case objabi.R_GOTPCREL:
                        if target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 && rst != sym.SCONST {
                                needExtReloc = true
-                               rr.Xadd = rr.Add
-                               rr.Xadd -= int64(rr.Siz) // relative to address after the relocated chunk
-                               rr.Xsym = rr.Sym
+                               rr.Xadd = r.Add()
+                               rr.Xadd -= int64(siz) // relative to address after the relocated chunk
+                               rr.Xsym = rs
 
                                o = rr.Xadd
-                               o += int64(rr.Siz)
+                               o += int64(siz)
                                break
                        }
                        fallthrough
@@ -470,9 +457,9 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                needExtReloc = true
                                rr.Xadd = 0
                                if target.IsElf() {
-                                       rr.Xadd -= int64(rr.Siz)
+                                       rr.Xadd -= int64(siz)
                                }
-                               rr.Xsym = rr.Sym
+                               rr.Xsym = rs
                                o = 0
                                break
                        }
@@ -482,8 +469,8 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                // set up addend for eventual relocation via outer symbol.
                                rs := rs
                                rs, off := foldSubSymbolOffset(ldr, rs)
-                               rr.Xadd = rr.Add + off
-                               rr.Xadd -= int64(rr.Siz) // relative to address after the relocated chunk
+                               rr.Xadd = r.Add() + off
+                               rr.Xadd -= int64(siz) // relative to address after the relocated chunk
                                rst := ldr.SymType(rs)
                                if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && ldr.SymSect(rs) == nil {
                                        st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs))
@@ -496,25 +483,25 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                                o = 0
                                        }
                                } else if target.IsDarwin() {
-                                       if rr.Type == objabi.R_CALL {
+                                       if rt == objabi.R_CALL {
                                                if target.IsExternal() && rst == sym.SDYNIMPORT {
                                                        if target.IsAMD64() {
                                                                // AMD64 dynamic relocations are relative to the end of the relocation.
-                                                               o += int64(rr.Siz)
+                                                               o += int64(siz)
                                                        }
                                                } else {
                                                        if rst != sym.SHOSTOBJ {
                                                                o += int64(uint64(ldr.SymValue(rs)) - ldr.SymSect(rs).Vaddr)
                                                        }
-                                                       o -= int64(rr.Off) // relative to section offset, not symbol
+                                                       o -= int64(off) // relative to section offset, not symbol
                                                }
                                        } else {
-                                               o += int64(rr.Siz)
+                                               o += int64(siz)
                                        }
                                } else if target.IsWindows() && target.IsAMD64() { // only amd64 needs PCREL
                                        // PE/COFF's PC32 relocation uses the address after the relocated
                                        // bytes as the base. Compensate by skewing the addend.
-                                       o += int64(rr.Siz)
+                                       o += int64(siz)
                                } else {
                                        st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
                                }
@@ -539,8 +526,8 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                st.err.Errorf(s, "find XCOFF R_REF with internal linking")
                        }
                        needExtReloc = true
-                       rr.Xsym = rr.Sym
-                       rr.Xadd = rr.Add
+                       rr.Xsym = rs
+                       rr.Xadd = r.Add()
 
                        // This isn't a real relocation so it must not update
                        // its offset value.
index a7b65e3580e478f0d362262efb8fd47b5fc40cd7..749995bf8e89c39b372aeb2281681c88e30baa7c 100644 (file)
@@ -51,11 +51,7 @@ type Reloc struct {
 
 // ExtReloc contains the payload for an external relocation.
 type ExtReloc struct {
-       Off  int32            // offset to rewrite
-       Siz  uint8            // number of bytes to rewrite: 0, 1, 2, or 4
-       Type objabi.RelocType // the relocation type
-       Sym  Sym              // global index of symbol the reloc addresses
-       Add  int64            // addend
+       Idx  int // index of the original relocation
        Xsym Sym
        Xadd int64
 }
@@ -2763,25 +2759,30 @@ func (l *Loader) convertExtRelocs(dst *sym.Symbol, src Sym) {
        if int(src) >= len(l.extRelocs) {
                return
        }
-       relocs := l.extRelocs[src]
-       if len(relocs) == 0 {
+       extRelocs := l.extRelocs[src]
+       if len(extRelocs) == 0 {
                return
        }
        if len(dst.R) != 0 {
                panic("bad")
        }
-       dst.R = make([]sym.Reloc, len(relocs))
+       dst.R = make([]sym.Reloc, len(extRelocs))
+       relocs := l.Relocs(src)
        for i := range dst.R {
-               sr := &relocs[i]
+               er := &extRelocs[i]
+               sr := relocs.At2(er.Idx)
                r := &dst.R[i]
                r.InitExt()
-               r.Off = sr.Off
-               r.Siz = sr.Siz
-               r.Type = sr.Type
-               r.Sym = l.Syms[sr.Sym]
-               r.Add = sr.Add
-               r.Xsym = l.Syms[sr.Xsym]
-               r.Xadd = sr.Xadd
+               r.Off = sr.Off()
+               r.Siz = sr.Siz()
+               r.Type = sr.Type()
+               r.Sym = l.Syms[l.ResolveABIAlias(sr.Sym())]
+               r.Add = sr.Add()
+               r.Xsym = l.Syms[er.Xsym]
+               r.Xadd = er.Xadd
+               if rv := l.RelocVariant(src, er.Idx); rv != 0 {
+                       r.Variant = rv
+               }
        }
 }
 
index 53032a7e335fd244120621a28a979f963ce21a90..a366e80ea3ed2c0262d79c45ee2e493c4baf8661 100644 (file)
@@ -58,7 +58,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        switch r.Type {
        default:
                return false
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                if r.Siz != 4 {
                        return false
                }
index 33f8b3350908db1b4c617fa6f64dcc1ad4912c3c..e69db2980995b8c251f33fb4dea02a27faad6e22 100644 (file)
@@ -69,7 +69,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        switch r.Type {
        default:
                return false
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                switch r.Siz {
                case 4:
                        ctxt.Out.Write8(uint8(elf.R_MIPS_32))
index 7a5dc565e68f242dce0fefb20b49e77c3cd2af37..4dc50eab79aeb4124ab3348ff4c6b9f31394e450 100644 (file)
@@ -457,7 +457,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        switch r.Type {
        default:
                return false
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                switch r.Siz {
                case 4:
                        ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR32) | uint64(elfsym)<<32)
index 4def25868aabe4f9ee3f5dca62d7c8f1b3e8af5a..bec7705be5804700879fc96af2d10b96df423202 100644 (file)
@@ -246,7 +246,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
                case 4:
                        ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32)
                }
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                switch r.Siz {
                default:
                        return false
index df704a444d152c2d75bae6134724a7cac67927f9..21ea5780cbb475c1a69fd1eff373c62cd1c4494e 100644 (file)
@@ -347,7 +347,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        switch r.Type {
        default:
                return false
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                if r.Siz == 4 {
                        ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8)
                } else {