1
0
mirror of https://github.com/golang/go synced 2024-11-18 12:04:57 -07:00

[dev.link] cmd/link: write data sections to heap in Asmb on Wasm

Make Wasm more like other architectures, writing data sections to
heap in Asmb instead of Asmb2. Then we can remove the
copy-on-write logic in applying relocations.

Change-Id: I26d5315ea9fba032fe4bdb9b5c7fe483611c4373
Reviewed-on: https://go-review.googlesource.com/c/go/+/230465
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:
Cherry Zhang 2020-04-28 09:53:29 -04:00
parent 3e8975172f
commit dd34841de7
13 changed files with 39 additions and 35 deletions

View File

@ -684,7 +684,7 @@ func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
}
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}

View File

@ -682,7 +682,7 @@ func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
}
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}

View File

@ -830,7 +830,7 @@ func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
}
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}

View File

@ -58,15 +58,6 @@ func relocsym2(target *Target, ldr *loader.Loader, err *ErrorReporter, syms *Arc
if len(s.R) == 0 {
return
}
if target.IsWasm() && s.Attr.ReadOnly() {
// The symbol's content is backed by read-only memory.
// Copy it to writable memory to apply relocations.
// Only need to do this on Wasm. On other platforms we
// apply relocations to the output buffer, which is
// always writeable.
s.P = append([]byte(nil), s.P...)
// No need to unset AttrReadOnly because it will not be used.
}
for ri := int32(0); ri < int32(len(s.R)); ri++ {
r := &s.R[ri]
if r.Done {

View File

@ -265,7 +265,7 @@ type Arch struct {
// file. Typically, Asmb writes most of the content (sections and
// segments), for which we have computed the size and offset. Asmb2
// writes the rest.
Asmb func(*Link)
Asmb func(*Link, *loader.Loader)
Asmb2 func(*Link)
Elfreloc1 func(*Link, *sym.Reloc, int64) bool

View File

@ -325,7 +325,7 @@ 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")
thearch.Asmb(ctxt)
thearch.Asmb(ctxt, ctxt.loader)
bench.Start("reloc")
ctxt.reloc()
bench.Start("Asmb2")

View File

@ -164,7 +164,7 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
return -1
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}

View File

@ -170,7 +170,7 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
return -1
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}

View File

@ -1082,7 +1082,7 @@ func ensureglinkresolver2(ctxt *ld.Link, ldr *loader.Loader) *loader.SymbolBuild
return glink
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}

View File

@ -98,7 +98,7 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
return -1
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}

View File

@ -485,7 +485,7 @@ func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
}
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}

View File

@ -92,7 +92,30 @@ func assignAddress(ldr *loader.Loader, sect *sym.Section, n int, s loader.Sym, v
return sect, n, va
}
func asmb(ctxt *ld.Link) {} // dummy
type wasmDataSect struct {
sect *sym.Section
data []byte
}
var dataSects []wasmDataSect
func asmb(ctxt *ld.Link, ldr *loader.Loader) {
sections := []*sym.Section{
ldr.SymSect(ldr.Lookup("runtime.rodata", 0)),
ldr.SymSect(ldr.Lookup("runtime.typelink", 0)),
ldr.SymSect(ldr.Lookup("runtime.itablink", 0)),
ldr.SymSect(ldr.Lookup("runtime.symtab", 0)),
ldr.SymSect(ldr.Lookup("runtime.pclntab", 0)),
ldr.SymSect(ldr.Lookup("runtime.noptrdata", 0)),
ldr.SymSect(ldr.Lookup("runtime.data", 0)),
}
dataSects = make([]wasmDataSect, len(sections))
for i, sect := range sections {
data := ld.DatblkBytes(ctxt, int64(sect.Vaddr), int64(sect.Length))
dataSects[i] = wasmDataSect{sect, data}
}
}
// asmb writes the final WebAssembly module binary.
// Spec: https://webassembly.github.io/spec/core/binary/modules.html
@ -396,16 +419,6 @@ func writeCodeSec(ctxt *ld.Link, fns []*wasmFunc) {
func writeDataSec(ctxt *ld.Link) {
sizeOffset := writeSecHeader(ctxt, sectionData)
sections := []*sym.Section{
ctxt.Syms.Lookup("runtime.rodata", 0).Sect,
ctxt.Syms.Lookup("runtime.typelink", 0).Sect,
ctxt.Syms.Lookup("runtime.itablink", 0).Sect,
ctxt.Syms.Lookup("runtime.symtab", 0).Sect,
ctxt.Syms.Lookup("runtime.pclntab", 0).Sect,
ctxt.Syms.Lookup("runtime.noptrdata", 0).Sect,
ctxt.Syms.Lookup("runtime.data", 0).Sect,
}
type dataSegment struct {
offset int32
data []byte
@ -420,9 +433,9 @@ func writeDataSec(ctxt *ld.Link) {
const maxNumSegments = 100000
var segments []*dataSegment
for secIndex, sec := range sections {
data := ld.DatblkBytes(ctxt, int64(sec.Vaddr), int64(sec.Length))
offset := int32(sec.Vaddr)
for secIndex, ds := range dataSects {
data := ds.data
offset := int32(ds.sect.Vaddr)
// skip leading zeroes
for len(data) > 0 && data[0] == 0 {
@ -433,7 +446,7 @@ func writeDataSec(ctxt *ld.Link) {
for len(data) > 0 {
dataLen := int32(len(data))
var segmentEnd, zeroEnd int32
if len(segments)+(len(sections)-secIndex) == maxNumSegments {
if len(segments)+(len(dataSects)-secIndex) == maxNumSegments {
segmentEnd = dataLen
zeroEnd = dataLen
} else {

View File

@ -564,7 +564,7 @@ func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
}
}
func asmb(ctxt *ld.Link) {
func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF {
ld.Asmbelfsetup()
}