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:
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 {
|
if ctxt.IsELF {
|
||||||
ld.Asmbelfsetup()
|
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 {
|
if ctxt.IsELF {
|
||||||
ld.Asmbelfsetup()
|
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 {
|
if ctxt.IsELF {
|
||||||
ld.Asmbelfsetup()
|
ld.Asmbelfsetup()
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user