mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: convert asmb pass to new style
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>
This commit is contained in:
parent
0722a49b37
commit
1adae7fe76
4 changed files with 77 additions and 45 deletions
|
|
@ -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) {
|
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.
|
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
|
// 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
|
// blocks, waiting on the writes to complete. Note that we use the sem parameter
|
||||||
// to limit the number of concurrent writes taking place.
|
// 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 {
|
for i, s := range syms {
|
||||||
if s.Value >= addr && !s.Attr.SubSymbol() {
|
if ldr.SymValue(s) >= addr && !ldr.AttrSubSymbol(s) {
|
||||||
syms = syms[i:]
|
syms = syms[i:]
|
||||||
break
|
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.
|
// Find the last symbol we'd write.
|
||||||
idx := -1
|
idx := -1
|
||||||
for i, s := range syms {
|
for i, s := range syms {
|
||||||
if s.Attr.SubSymbol() {
|
if ldr.AttrSubSymbol(s) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the next symbol's size would put us out of bounds on the total length,
|
// If the next symbol's size would put us out of bounds on the total length,
|
||||||
// stop looking.
|
// stop looking.
|
||||||
if s.Value+s.Size > lastAddr {
|
end := ldr.SymValue(s) + ldr.SymSize(s)
|
||||||
|
if end > lastAddr {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -754,7 +755,7 @@ func writeBlocks(out *OutBuf, sem chan int, syms []*sym.Symbol, addr, size int64
|
||||||
idx = i
|
idx = i
|
||||||
|
|
||||||
// If we cross over the max size, we've got enough symbols.
|
// If we cross over the max size, we've got enough symbols.
|
||||||
if s.Value+s.Size > addr+max {
|
if end > addr+max {
|
||||||
break
|
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
|
// Skip over sub symbols so we won't split a containter symbol
|
||||||
// into two blocks.
|
// into two blocks.
|
||||||
next := syms[idx+1]
|
next := syms[idx+1]
|
||||||
for next.Attr.SubSymbol() {
|
for ldr.AttrSubSymbol(next) {
|
||||||
idx++
|
idx++
|
||||||
next = syms[idx+1]
|
next = syms[idx+1]
|
||||||
}
|
}
|
||||||
length = next.Value - addr
|
length = ldr.SymValue(next) - addr
|
||||||
}
|
}
|
||||||
if length == 0 || length > lastAddr-addr {
|
if length == 0 || length > lastAddr-addr {
|
||||||
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 {
|
if o, err := out.View(uint64(out.Offset() + written)); err == nil {
|
||||||
sem <- 1
|
sem <- 1
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(o *OutBuf, syms []*sym.Symbol, addr, size int64, pad []byte) {
|
go func(o *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
|
||||||
writeBlock(o, syms, addr, size, pad)
|
writeBlock(o, ldr, syms, addr, size, pad)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
<-sem
|
<-sem
|
||||||
}(o, syms, addr, length, pad)
|
}(o, ldr, syms, addr, length, pad)
|
||||||
} else { // output not mmaped, don't parallelize.
|
} 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.
|
// Prepare for the next loop.
|
||||||
|
|
@ -808,9 +809,9 @@ func writeBlocks(out *OutBuf, sem chan int, syms []*sym.Symbol, addr, size int64
|
||||||
wg.Wait()
|
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 {
|
for i, s := range syms {
|
||||||
if s.Value >= addr && !s.Attr.SubSymbol() {
|
if ldr.SymValue(s) >= addr && !ldr.AttrSubSymbol(s) {
|
||||||
syms = syms[i:]
|
syms = syms[i:]
|
||||||
break
|
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.
|
// so dwarfcompress will fix this up later if necessary.
|
||||||
eaddr := addr + size
|
eaddr := addr + size
|
||||||
for _, s := range syms {
|
for _, s := range syms {
|
||||||
if s.Attr.SubSymbol() {
|
if ldr.AttrSubSymbol(s) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if s.Value >= eaddr {
|
val := ldr.SymValue(s)
|
||||||
|
if val >= eaddr {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if s.Value < addr {
|
if val < addr {
|
||||||
Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, s.Value, s.Type)
|
ldr.Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, val, ldr.SymType(s))
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
if addr < s.Value {
|
if addr < val {
|
||||||
out.WriteStringPad("", int(s.Value-addr), pad)
|
out.WriteStringPad("", int(val-addr), pad)
|
||||||
addr = s.Value
|
addr = val
|
||||||
}
|
}
|
||||||
out.WriteSym(s)
|
out.WriteSym(ldr, s)
|
||||||
addr += int64(len(s.P))
|
addr += int64(len(ldr.Data(s)))
|
||||||
if addr < s.Value+s.Size {
|
siz := ldr.SymSize(s)
|
||||||
out.WriteStringPad("", int(s.Value+s.Size-addr), pad)
|
if addr < val+siz {
|
||||||
addr = s.Value + s.Size
|
out.WriteStringPad("", int(val+siz-addr), pad)
|
||||||
|
addr = val + siz
|
||||||
}
|
}
|
||||||
if addr != s.Value+s.Size {
|
if addr != val+siz {
|
||||||
Errorf(s, "phase error: addr=%#x value+size=%#x", addr, s.Value+s.Size)
|
ldr.Errorf(s, "phase error: addr=%#x value+size=%#x", addr, val+siz)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
if s.Value+s.Size >= eaddr {
|
if val+siz >= eaddr {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -885,7 +888,7 @@ func DatblkBytes(ctxt *Link, addr int64, size int64) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeDatblkToOutBuf(ctxt *Link, out *OutBuf, addr int64, size int64) {
|
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) {
|
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
|
// section, but this would run the risk of undoing any file offset
|
||||||
// adjustments made during layout.
|
// adjustments made during layout.
|
||||||
n := 0
|
n := 0
|
||||||
for i := range dwarfp {
|
for i := range dwarfp2 {
|
||||||
n += len(dwarfp[i].syms)
|
n += len(dwarfp2[i].syms)
|
||||||
}
|
}
|
||||||
syms := make([]*sym.Symbol, 0, n)
|
syms := make([]loader.Sym, 0, n)
|
||||||
for i := range dwarfp {
|
for i := range dwarfp2 {
|
||||||
syms = append(syms, dwarfp[i].syms...)
|
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
|
var zeros [512]byte
|
||||||
|
|
|
||||||
|
|
@ -306,8 +306,6 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||||
dwarfcompress(ctxt)
|
dwarfcompress(ctxt)
|
||||||
bench.Start("layout")
|
bench.Start("layout")
|
||||||
filesize := ctxt.layout(order)
|
filesize := ctxt.layout(order)
|
||||||
bench.Start("loadlibfull")
|
|
||||||
ctxt.loadlibfull(symGroupType) // XXX do it here for now
|
|
||||||
|
|
||||||
// Write out the output file.
|
// Write out the output file.
|
||||||
// It is split into two parts (Asmb and Asmb2). The first
|
// 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
|
// Asmb will redirect symbols to the output file mmap, and relocations
|
||||||
// will be applied directly there.
|
// will be applied directly there.
|
||||||
bench.Start("Asmb")
|
bench.Start("Asmb")
|
||||||
|
ctxt.loader.InitOutData()
|
||||||
thearch.Asmb(ctxt, ctxt.loader)
|
thearch.Asmb(ctxt, ctxt.loader)
|
||||||
|
bench.Start("loadlibfull")
|
||||||
|
ctxt.loadlibfull(symGroupType) // XXX do it here for now
|
||||||
bench.Start("reloc")
|
bench.Start("reloc")
|
||||||
ctxt.reloc()
|
ctxt.reloc()
|
||||||
bench.Start("Asmb2")
|
bench.Start("Asmb2")
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ package ld
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/loader"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"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
|
// to point to the output buffer that we just wrote, so we can apply further
|
||||||
// edit to the symbol content.
|
// edit to the symbol content.
|
||||||
// If the output file is not Mmap'd, just writes the content.
|
// If the output file is not Mmap'd, just writes the content.
|
||||||
func (out *OutBuf) WriteSym(s *sym.Symbol) {
|
func (out *OutBuf) WriteSym(ldr *loader.Loader, s loader.Sym) {
|
||||||
n := int64(len(s.P))
|
P := ldr.Data(s)
|
||||||
|
n := int64(len(P))
|
||||||
pos, buf := out.writeLoc(n)
|
pos, buf := out.writeLoc(n)
|
||||||
copy(buf[pos:], s.P)
|
copy(buf[pos:], P)
|
||||||
out.off += n
|
out.off += n
|
||||||
s.P = buf[pos : pos+n]
|
ldr.SetOutData(s, buf[pos:pos+n])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,8 @@ type Loader struct {
|
||||||
sects []*sym.Section // sections
|
sects []*sym.Section // sections
|
||||||
symSects []uint16 // symbol's section, index to sects array
|
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.*
|
itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
|
||||||
|
|
||||||
objByPkg map[string]*oReader // map package path to its Go object reader
|
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)
|
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.
|
// SymAlign returns the alignment for a symbol.
|
||||||
func (l *Loader) SymAlign(i Sym) int32 {
|
func (l *Loader) SymAlign(i Sym) int32 {
|
||||||
// If an alignment has been recorded, return that.
|
// If an alignment has been recorded, return that.
|
||||||
|
|
@ -2592,8 +2620,7 @@ func loadObjFull(l *Loader, r *oReader) {
|
||||||
size := osym.Siz()
|
size := osym.Siz()
|
||||||
|
|
||||||
// Symbol data
|
// Symbol data
|
||||||
s.P = r.Data(i)
|
s.P = l.OutData(gi)
|
||||||
s.Attr.Set(sym.AttrReadOnly, r.ReadOnly())
|
|
||||||
|
|
||||||
// Relocs
|
// Relocs
|
||||||
relocs := l.relocs(r, i)
|
relocs := l.relocs(r, i)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue