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:
parent
3e8975172f
commit
dd34841de7
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user