]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: convert asmb pass to new style
authorCherry Zhang <cherryyz@google.com>
Sat, 25 Apr 2020 21:50:48 +0000 (17:50 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 28 Apr 2020 19:32:45 +0000 (19:32 +0000)
Change-Id: I8675f56a7f7f18653754eb87b95f5a7aec31ad74
Reviewed-on: https://go-review.googlesource.com/c/go/+/229860
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/ld/data.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/ld/outbuf.go
src/cmd/link/internal/loader/loader.go

index 1fd048e10dc5c9dfc1014fecc542298cd68de9ca..d44d590623e633dffd94faf69340f26f8ac84640 100644 (file)
@@ -716,7 +716,7 @@ func Codeblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
 }
 
 func CodeblkPad(ctxt *Link, out *OutBuf, addr int64, size int64, pad []byte) {
-       writeBlocks(out, ctxt.outSem, ctxt.Textp, addr, size, pad)
+       writeBlocks(out, ctxt.outSem, ctxt.loader, ctxt.Textp2, addr, size, pad)
 }
 
 const blockSize = 1 << 20 // 1MB chunks written at a time.
@@ -726,9 +726,9 @@ const blockSize = 1 << 20 // 1MB chunks written at a time.
 // as many goroutines as necessary to accomplish this task. This call then
 // blocks, waiting on the writes to complete. Note that we use the sem parameter
 // to limit the number of concurrent writes taking place.
-func writeBlocks(out *OutBuf, sem chan int, syms []*sym.Symbol, addr, size int64, pad []byte) {
+func writeBlocks(out *OutBuf, sem chan int, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
        for i, s := range syms {
-               if s.Value >= addr && !s.Attr.SubSymbol() {
+               if ldr.SymValue(s) >= addr && !ldr.AttrSubSymbol(s) {
                        syms = syms[i:]
                        break
                }
@@ -740,13 +740,14 @@ func writeBlocks(out *OutBuf, sem chan int, syms []*sym.Symbol, addr, size int64
                // Find the last symbol we'd write.
                idx := -1
                for i, s := range syms {
-                       if s.Attr.SubSymbol() {
+                       if ldr.AttrSubSymbol(s) {
                                continue
                        }
 
                        // If the next symbol's size would put us out of bounds on the total length,
                        // stop looking.
-                       if s.Value+s.Size > lastAddr {
+                       end := ldr.SymValue(s) + ldr.SymSize(s)
+                       if end > lastAddr {
                                break
                        }
 
@@ -754,7 +755,7 @@ func writeBlocks(out *OutBuf, sem chan int, syms []*sym.Symbol, addr, size int64
                        idx = i
 
                        // If we cross over the max size, we've got enough symbols.
-                       if s.Value+s.Size > addr+max {
+                       if end > addr+max {
                                break
                        }
                }
@@ -775,11 +776,11 @@ func writeBlocks(out *OutBuf, sem chan int, syms []*sym.Symbol, addr, size int64
                        // Skip over sub symbols so we won't split a containter symbol
                        // into two blocks.
                        next := syms[idx+1]
-                       for next.Attr.SubSymbol() {
+                       for ldr.AttrSubSymbol(next) {
                                idx++
                                next = syms[idx+1]
                        }
-                       length = next.Value - addr
+                       length = ldr.SymValue(next) - addr
                }
                if length == 0 || length > lastAddr-addr {
                        length = lastAddr - addr
@@ -789,13 +790,13 @@ func writeBlocks(out *OutBuf, sem chan int, syms []*sym.Symbol, addr, size int64
                if o, err := out.View(uint64(out.Offset() + written)); err == nil {
                        sem <- 1
                        wg.Add(1)
-                       go func(o *OutBuf, syms []*sym.Symbol, addr, size int64, pad []byte) {
-                               writeBlock(o, syms, addr, size, pad)
+                       go func(o *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
+                               writeBlock(o, ldr, syms, addr, size, pad)
                                wg.Done()
                                <-sem
-                       }(o, syms, addr, length, pad)
+                       }(o, ldr, syms, addr, length, pad)
                } else { // output not mmaped, don't parallelize.
-                       writeBlock(out, syms, addr, length, pad)
+                       writeBlock(out, ldr, syms, addr, length, pad)
                }
 
                // Prepare for the next loop.
@@ -808,9 +809,9 @@ func writeBlocks(out *OutBuf, sem chan int, syms []*sym.Symbol, addr, size int64
        wg.Wait()
 }
 
-func writeBlock(out *OutBuf, syms []*sym.Symbol, addr, size int64, pad []byte) {
+func writeBlock(out *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
        for i, s := range syms {
-               if s.Value >= addr && !s.Attr.SubSymbol() {
+               if ldr.SymValue(s) >= addr && !ldr.AttrSubSymbol(s) {
                        syms = syms[i:]
                        break
                }
@@ -822,31 +823,33 @@ func writeBlock(out *OutBuf, syms []*sym.Symbol, addr, size int64, pad []byte) {
        // so dwarfcompress will fix this up later if necessary.
        eaddr := addr + size
        for _, s := range syms {
-               if s.Attr.SubSymbol() {
+               if ldr.AttrSubSymbol(s) {
                        continue
                }
-               if s.Value >= eaddr {
+               val := ldr.SymValue(s)
+               if val >= eaddr {
                        break
                }
-               if s.Value < addr {
-                       Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, s.Value, s.Type)
+               if val < addr {
+                       ldr.Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, val, ldr.SymType(s))
                        errorexit()
                }
-               if addr < s.Value {
-                       out.WriteStringPad("", int(s.Value-addr), pad)
-                       addr = s.Value
+               if addr < val {
+                       out.WriteStringPad("", int(val-addr), pad)
+                       addr = val
                }
-               out.WriteSym(s)
-               addr += int64(len(s.P))
-               if addr < s.Value+s.Size {
-                       out.WriteStringPad("", int(s.Value+s.Size-addr), pad)
-                       addr = s.Value + s.Size
+               out.WriteSym(ldr, s)
+               addr += int64(len(ldr.Data(s)))
+               siz := ldr.SymSize(s)
+               if addr < val+siz {
+                       out.WriteStringPad("", int(val+siz-addr), pad)
+                       addr = val + siz
                }
-               if addr != s.Value+s.Size {
-                       Errorf(s, "phase error: addr=%#x value+size=%#x", addr, s.Value+s.Size)
+               if addr != val+siz {
+                       ldr.Errorf(s, "phase error: addr=%#x value+size=%#x", addr, val+siz)
                        errorexit()
                }
-               if s.Value+s.Size >= eaddr {
+               if val+siz >= eaddr {
                        break
                }
        }
@@ -885,7 +888,7 @@ func DatblkBytes(ctxt *Link, addr int64, size int64) []byte {
 }
 
 func writeDatblkToOutBuf(ctxt *Link, out *OutBuf, addr int64, size int64) {
-       writeBlocks(out, ctxt.outSem, ctxt.datap, addr, size, zeros[:])
+       writeBlocks(out, ctxt.outSem, ctxt.loader, ctxt.datap2, addr, size, zeros[:])
 }
 
 func Dwarfblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
@@ -896,14 +899,14 @@ func Dwarfblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
        // section, but this would run the risk of undoing any file offset
        // adjustments made during layout.
        n := 0
-       for i := range dwarfp {
-               n += len(dwarfp[i].syms)
+       for i := range dwarfp2 {
+               n += len(dwarfp2[i].syms)
        }
-       syms := make([]*sym.Symbol, 0, n)
-       for i := range dwarfp {
-               syms = append(syms, dwarfp[i].syms...)
+       syms := make([]loader.Sym, 0, n)
+       for i := range dwarfp2 {
+               syms = append(syms, dwarfp2[i].syms...)
        }
-       writeBlocks(out, ctxt.outSem, syms, addr, size, zeros[:])
+       writeBlocks(out, ctxt.outSem, ctxt.loader, syms, addr, size, zeros[:])
 }
 
 var zeros [512]byte
index 48fea57cc9544f32b71637ef235308c00286bef2..a4526230c926a42a3d755a44339435374f90bef9 100644 (file)
@@ -306,8 +306,6 @@ func Main(arch *sys.Arch, theArch Arch) {
        dwarfcompress(ctxt)
        bench.Start("layout")
        filesize := ctxt.layout(order)
-       bench.Start("loadlibfull")
-       ctxt.loadlibfull(symGroupType) // XXX do it here for now
 
        // Write out the output file.
        // It is split into two parts (Asmb and Asmb2). The first
@@ -325,7 +323,10 @@ func Main(arch *sys.Arch, theArch Arch) {
        // Asmb will redirect symbols to the output file mmap, and relocations
        // will be applied directly there.
        bench.Start("Asmb")
+       ctxt.loader.InitOutData()
        thearch.Asmb(ctxt, ctxt.loader)
+       bench.Start("loadlibfull")
+       ctxt.loadlibfull(symGroupType) // XXX do it here for now
        bench.Start("reloc")
        ctxt.reloc()
        bench.Start("Asmb2")
index 40e02cb7cf91e313c132a0f2ff7ef0177c6c799b..4ce211172cb007af76366c4d016c5c057b12874e 100644 (file)
@@ -6,7 +6,7 @@ package ld
 
 import (
        "cmd/internal/sys"
-       "cmd/link/internal/sym"
+       "cmd/link/internal/loader"
        "encoding/binary"
        "errors"
        "log"
@@ -285,10 +285,11 @@ func (out *OutBuf) WriteStringPad(s string, n int, pad []byte) {
 // to point to the output buffer that we just wrote, so we can apply further
 // edit to the symbol content.
 // If the output file is not Mmap'd, just writes the content.
-func (out *OutBuf) WriteSym(s *sym.Symbol) {
-       n := int64(len(s.P))
+func (out *OutBuf) WriteSym(ldr *loader.Loader, s loader.Sym) {
+       P := ldr.Data(s)
+       n := int64(len(P))
        pos, buf := out.writeLoc(n)
-       copy(buf[pos:], s.P)
+       copy(buf[pos:], P)
        out.off += n
-       s.P = buf[pos : pos+n]
+       ldr.SetOutData(s, buf[pos:pos+n])
 }
index fb792ac059a628d921bb61b084be890905970e72..775a2cb522ee553b320b6b5a23a5088dbdfe48ee 100644 (file)
@@ -216,6 +216,8 @@ type Loader struct {
        sects    []*sym.Section // sections
        symSects []uint16       // symbol's section, index to sects array
 
+       outdata [][]byte // symbol's data in the output buffer
+
        itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
 
        objByPkg map[string]*oReader // map package path to its Go object reader
@@ -1080,6 +1082,32 @@ func (l *Loader) Data(i Sym) []byte {
        return r.Data(li)
 }
 
+// Returns the data of the i-th symbol in the output buffer.
+func (l *Loader) OutData(i Sym) []byte {
+       if int(i) < len(l.outdata) && l.outdata[i] != nil {
+               return l.outdata[i]
+       }
+       return l.Data(i)
+}
+
+// SetOutData sets the position of the data of the i-th symbol in the output buffer.
+// i is global index.
+func (l *Loader) SetOutData(i Sym, data []byte) {
+       if l.IsExternal(i) {
+               pp := l.getPayload(i)
+               if pp != nil {
+                       pp.data = data
+                       return
+               }
+       }
+       l.outdata[i] = data
+}
+
+// InitOutData initializes the slice used to store symbol output data.
+func (l *Loader) InitOutData() {
+       l.outdata = make([][]byte, l.extStart)
+}
+
 // SymAlign returns the alignment for a symbol.
 func (l *Loader) SymAlign(i Sym) int32 {
        // If an alignment has been recorded, return that.
@@ -2592,8 +2620,7 @@ func loadObjFull(l *Loader, r *oReader) {
                size := osym.Siz()
 
                // Symbol data
-               s.P = r.Data(i)
-               s.Attr.Set(sym.AttrReadOnly, r.ReadOnly())
+               s.P = l.OutData(gi)
 
                // Relocs
                relocs := l.relocs(r, i)