1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:34:39 -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 { if ctxt.IsELF {
ld.Asmbelfsetup() 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 { if ctxt.IsELF {
ld.Asmbelfsetup() 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 { if ctxt.IsELF {
ld.Asmbelfsetup() ld.Asmbelfsetup()
} }

View File

@ -58,15 +58,6 @@ func relocsym2(target *Target, ldr *loader.Loader, err *ErrorReporter, syms *Arc
if len(s.R) == 0 { if len(s.R) == 0 {
return 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++ { for ri := int32(0); ri < int32(len(s.R)); ri++ {
r := &s.R[ri] r := &s.R[ri]
if r.Done { if r.Done {

View File

@ -265,7 +265,7 @@ type Arch struct {
// file. Typically, Asmb writes most of the content (sections and // file. Typically, Asmb writes most of the content (sections and
// segments), for which we have computed the size and offset. Asmb2 // segments), for which we have computed the size and offset. Asmb2
// writes the rest. // writes the rest.
Asmb func(*Link) Asmb func(*Link, *loader.Loader)
Asmb2 func(*Link) Asmb2 func(*Link)
Elfreloc1 func(*Link, *sym.Reloc, int64) bool 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 // 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")
thearch.Asmb(ctxt) thearch.Asmb(ctxt, ctxt.loader)
bench.Start("reloc") bench.Start("reloc")
ctxt.reloc() ctxt.reloc()
bench.Start("Asmb2") bench.Start("Asmb2")

View File

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

View File

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

View File

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

View File

@ -98,7 +98,7 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
return -1 return -1
} }
func asmb(ctxt *ld.Link) { func asmb(ctxt *ld.Link, _ *loader.Loader) {
if ctxt.IsELF { if ctxt.IsELF {
ld.Asmbelfsetup() 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 { if ctxt.IsELF {
ld.Asmbelfsetup() 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 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. // asmb writes the final WebAssembly module binary.
// Spec: https://webassembly.github.io/spec/core/binary/modules.html // 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) { func writeDataSec(ctxt *ld.Link) {
sizeOffset := writeSecHeader(ctxt, sectionData) 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 { type dataSegment struct {
offset int32 offset int32
data []byte data []byte
@ -420,9 +433,9 @@ func writeDataSec(ctxt *ld.Link) {
const maxNumSegments = 100000 const maxNumSegments = 100000
var segments []*dataSegment var segments []*dataSegment
for secIndex, sec := range sections { for secIndex, ds := range dataSects {
data := ld.DatblkBytes(ctxt, int64(sec.Vaddr), int64(sec.Length)) data := ds.data
offset := int32(sec.Vaddr) offset := int32(ds.sect.Vaddr)
// skip leading zeroes // skip leading zeroes
for len(data) > 0 && data[0] == 0 { for len(data) > 0 && data[0] == 0 {
@ -433,7 +446,7 @@ func writeDataSec(ctxt *ld.Link) {
for len(data) > 0 { for len(data) > 0 {
dataLen := int32(len(data)) dataLen := int32(len(data))
var segmentEnd, zeroEnd int32 var segmentEnd, zeroEnd int32
if len(segments)+(len(sections)-secIndex) == maxNumSegments { if len(segments)+(len(dataSects)-secIndex) == maxNumSegments {
segmentEnd = dataLen segmentEnd = dataLen
zeroEnd = dataLen zeroEnd = dataLen
} else { } 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 { if ctxt.IsELF {
ld.Asmbelfsetup() ld.Asmbelfsetup()
} }