]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: write data sections to heap in Asmb on Wasm
authorCherry Zhang <cherryyz@google.com>
Tue, 28 Apr 2020 13:53:29 +0000 (09:53 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 28 Apr 2020 18:36:45 +0000 (18:36 +0000)
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>
13 files changed:
src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/arm/asm.go
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/ld/data2.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/mips/asm.go
src/cmd/link/internal/mips64/asm.go
src/cmd/link/internal/ppc64/asm.go
src/cmd/link/internal/riscv64/asm.go
src/cmd/link/internal/s390x/asm.go
src/cmd/link/internal/wasm/asm.go
src/cmd/link/internal/x86/asm.go

index e2a66daf4f782e4352780032a4907cbe3ef824b5..95831d6dd0c773d5bad2d98025c99a5a30aaf9ea 100644 (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()
        }
index e1edc9e45da66c761c35b132b1cf30371cea1bc4..7665cc59f04cf3ea1ef8f21589cde3e104205a9e 100644 (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()
        }
index a0f06b6aa67aaebae214d4b5a19381ead36fdf1d..fbcbc9c8c34d127b4893171615dfffa31de8e1d4 100644 (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()
        }
index 79badd5fdd19aa4d11e2ff0e43cece24d2000a01..2aba40c231e547bb578467d415f1d07169d081f5 100644 (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 {
index 7264f9383e89cc2575e695366b310391ee5a2a4b..57b9e8cb24c1317a4459542fd8fdabbfdae9b43a 100644 (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
index 6c5a18c3595676032e10791c268e271256a49c05..48fea57cc9544f32b71637ef235308c00286bef2 100644 (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")
index 21a57ccbb0d182345685c87985c74272813bc123..928167870442abee54ee3c41cac8e066bd7f0540 100644 (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()
        }
index 0a2a3c11f3eff41195fac9ef1b7c339957964853..615851b564a6a80952c9cad1761b91a8999e470e 100644 (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()
        }
index be124acaf86b7565e1a323b55b7e8ec8da8fca4c..6b6e1294d30862b635c9ecaf140e0f9c8f614bbf 100644 (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()
        }
index 51cc5980c89a75a76a93fb4aab1251a2252fa685..5183de8d6b73d6914c562bcc745bc9ee98de2f7e 100644 (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()
        }
index 59c49b4537698686bfea0b83879495c46c340a83..ac634f99e396a6349cbccda3d56701dd36fdc2b7 100644 (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()
        }
index 7f8742d00823648701324e5eb06bb437db53c099..1eb3291db6667bd15a3129181383abba8726d938 100644 (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 {
index 03c73671b8804e92ece2ceeea213db19475590fc..069d2bc31ce05fefa66206efb986c1e098c85f84 100644 (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()
        }