mirror of
https://github.com/golang/go
synced 2024-11-18 11:55:01 -07:00
[dev.link] cmd/link: convert asmb2 pass to new style on Wasm
And no longer do loadlibfull there. Change-Id: I3dd41d25f5f7db4ef1d112559299e322acb32641 Reviewed-on: https://go-review.googlesource.com/c/go/+/232987 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
6d7c2459ad
commit
744641ef37
@ -722,7 +722,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
machlink := int64(0)
|
||||
if ctxt.HeadType == objabi.Hdarwin {
|
||||
machlink = ld.Domacholink(ctxt)
|
||||
|
@ -696,7 +696,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
/* output symbol table */
|
||||
ld.Symsize = 0
|
||||
|
||||
|
@ -825,7 +825,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
machlink := uint32(0)
|
||||
if ctxt.HeadType == objabi.Hdarwin {
|
||||
machlink = uint32(ld.Domacholink(ctxt))
|
||||
|
@ -266,7 +266,7 @@ type Arch struct {
|
||||
// segments), for which we have computed the size and offset. Asmb2
|
||||
// writes the rest.
|
||||
Asmb func(*Link, *loader.Loader)
|
||||
Asmb2 func(*Link)
|
||||
Asmb2 func(*Link, *loader.Loader)
|
||||
|
||||
Elfreloc1 func(*Link, *sym.Reloc, int64) bool
|
||||
Elfreloc2 func(*Link, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
|
||||
|
@ -320,19 +320,18 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||
thearch.Asmb(ctxt, ctxt.loader)
|
||||
bench.Start("reloc")
|
||||
ctxt.reloc()
|
||||
newasmb2 := ctxt.IsDarwin() || ctxt.IsWindows()
|
||||
newasmb2 := ctxt.IsDarwin() || ctxt.IsWindows() || ctxt.IsWasm()
|
||||
if !newasmb2 {
|
||||
bench.Start("loadlibfull")
|
||||
// We don't need relocations at this point.
|
||||
// Wasm is an exception, where it applies text relocations in Asmb2.
|
||||
needReloc := ctxt.IsWasm()
|
||||
needReloc := false
|
||||
// On AMD64 ELF, we directly use the loader's ExtRelocs, so we don't
|
||||
// need conversion. Otherwise we do.
|
||||
needExtReloc := ctxt.IsExternal() && !(ctxt.IsAMD64() && ctxt.IsELF)
|
||||
ctxt.loadlibfull(symGroupType, needReloc, needExtReloc) // XXX do it here for now
|
||||
}
|
||||
bench.Start("Asmb2")
|
||||
thearch.Asmb2(ctxt)
|
||||
thearch.Asmb2(ctxt, ctxt.loader)
|
||||
|
||||
bench.Start("Munmap")
|
||||
ctxt.Out.Close() // Close handles Munmapping if necessary.
|
||||
|
@ -184,7 +184,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
/* output symbol table */
|
||||
ld.Symsize = 0
|
||||
|
||||
|
@ -193,7 +193,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
/* output symbol table */
|
||||
ld.Symsize = 0
|
||||
|
||||
|
@ -1106,7 +1106,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
/* output symbol table */
|
||||
ld.Symsize = 0
|
||||
|
||||
|
@ -129,7 +129,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
ld.Symsize = 0
|
||||
ld.Lcsize = 0
|
||||
symo := uint32(0)
|
||||
|
@ -503,7 +503,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
/* output symbol table */
|
||||
ld.Symsize = 0
|
||||
|
||||
|
@ -119,7 +119,7 @@ func asmb(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
|
||||
// asmb writes the final WebAssembly module binary.
|
||||
// Spec: https://webassembly.github.io/spec/core/binary/modules.html
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
types := []*wasmFuncType{
|
||||
// For normal Go functions, the single parameter is PC_B,
|
||||
// the return value is
|
||||
@ -135,13 +135,15 @@ func asmb2(ctxt *ld.Link) {
|
||||
Type: lookupType(&wasmFuncType{Params: []byte{I32}}, &types),
|
||||
},
|
||||
}
|
||||
hostImportMap := make(map[*sym.Symbol]int64)
|
||||
for _, fn := range ctxt.Textp {
|
||||
for _, r := range fn.R {
|
||||
if r.Type == objabi.R_WASMIMPORT {
|
||||
hostImportMap[r.Sym] = int64(len(hostImports))
|
||||
hostImportMap := make(map[loader.Sym]int64)
|
||||
for _, fn := range ctxt.Textp2 {
|
||||
relocs := ldr.Relocs(fn)
|
||||
for ri := 0; ri < relocs.Count(); ri++ {
|
||||
r := relocs.At2(ri)
|
||||
if r.Type() == objabi.R_WASMIMPORT {
|
||||
hostImportMap[r.Sym()] = int64(len(hostImports))
|
||||
hostImports = append(hostImports, &wasmFunc{
|
||||
Name: r.Sym.Name,
|
||||
Name: ldr.SymName(r.Sym()),
|
||||
Type: lookupType(&wasmFuncType{Params: []byte{I32}}, &types),
|
||||
})
|
||||
}
|
||||
@ -150,41 +152,45 @@ func asmb2(ctxt *ld.Link) {
|
||||
|
||||
// collect functions with WebAssembly body
|
||||
var buildid []byte
|
||||
fns := make([]*wasmFunc, len(ctxt.Textp))
|
||||
for i, fn := range ctxt.Textp {
|
||||
fns := make([]*wasmFunc, len(ctxt.Textp2))
|
||||
for i, fn := range ctxt.Textp2 {
|
||||
wfn := new(bytes.Buffer)
|
||||
if fn.Name == "go.buildid" {
|
||||
if ldr.SymName(fn) == "go.buildid" {
|
||||
writeUleb128(wfn, 0) // number of sets of locals
|
||||
writeI32Const(wfn, 0)
|
||||
wfn.WriteByte(0x0b) // end
|
||||
buildid = fn.P
|
||||
buildid = ldr.Data(fn)
|
||||
} else {
|
||||
// Relocations have variable length, handle them here.
|
||||
relocs := ldr.Relocs(fn)
|
||||
P := ldr.Data(fn)
|
||||
off := int32(0)
|
||||
for _, r := range fn.R {
|
||||
wfn.Write(fn.P[off:r.Off])
|
||||
off = r.Off
|
||||
switch r.Type {
|
||||
for ri := 0; ri < relocs.Count(); ri++ {
|
||||
r := relocs.At2(ri)
|
||||
wfn.Write(P[off:r.Off()])
|
||||
off = r.Off()
|
||||
rs := ldr.ResolveABIAlias(r.Sym())
|
||||
switch r.Type() {
|
||||
case objabi.R_ADDR:
|
||||
writeSleb128(wfn, r.Sym.Value+r.Add)
|
||||
writeSleb128(wfn, ldr.SymValue(rs)+r.Add())
|
||||
case objabi.R_CALL:
|
||||
writeSleb128(wfn, int64(len(hostImports))+r.Sym.Value>>16-funcValueOffset)
|
||||
writeSleb128(wfn, int64(len(hostImports))+ldr.SymValue(rs)>>16-funcValueOffset)
|
||||
case objabi.R_WASMIMPORT:
|
||||
writeSleb128(wfn, hostImportMap[r.Sym])
|
||||
writeSleb128(wfn, hostImportMap[rs])
|
||||
default:
|
||||
ld.Errorf(fn, "bad reloc type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
|
||||
ldr.Errorf(fn, "bad reloc type %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
wfn.Write(fn.P[off:])
|
||||
wfn.Write(P[off:])
|
||||
}
|
||||
|
||||
typ := uint32(0)
|
||||
if sig, ok := wasmFuncTypes[fn.Name]; ok {
|
||||
if sig, ok := wasmFuncTypes[ldr.SymName(fn)]; ok {
|
||||
typ = lookupType(sig, &types)
|
||||
}
|
||||
|
||||
name := nameRegexp.ReplaceAllString(fn.Name, "_")
|
||||
name := nameRegexp.ReplaceAllString(ldr.SymName(fn), "_")
|
||||
fns[i] = &wasmFunc{Name: name, Type: typ, Code: wfn.Bytes()}
|
||||
}
|
||||
|
||||
@ -200,9 +206,9 @@ func asmb2(ctxt *ld.Link) {
|
||||
writeImportSec(ctxt, hostImports)
|
||||
writeFunctionSec(ctxt, fns)
|
||||
writeTableSec(ctxt, fns)
|
||||
writeMemorySec(ctxt)
|
||||
writeMemorySec(ctxt, ldr)
|
||||
writeGlobalSec(ctxt)
|
||||
writeExportSec(ctxt, len(hostImports))
|
||||
writeExportSec(ctxt, ldr, len(hostImports))
|
||||
writeElementSec(ctxt, uint64(len(hostImports)), uint64(len(fns)))
|
||||
writeCodeSec(ctxt, fns)
|
||||
writeDataSec(ctxt)
|
||||
@ -311,10 +317,10 @@ func writeTableSec(ctxt *ld.Link, fns []*wasmFunc) {
|
||||
|
||||
// writeMemorySec writes the section that declares linear memories. Currently one linear memory is being used.
|
||||
// Linear memory always starts at address zero. More memory can be requested with the GrowMemory instruction.
|
||||
func writeMemorySec(ctxt *ld.Link) {
|
||||
func writeMemorySec(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
sizeOffset := writeSecHeader(ctxt, sectionMemory)
|
||||
|
||||
dataSection := ctxt.Syms.Lookup("runtime.data", 0).Sect
|
||||
dataSection := ldr.SymSect(ldr.Lookup("runtime.data", 0))
|
||||
dataEnd := dataSection.Vaddr + dataSection.Length
|
||||
var initialSize = dataEnd + 16<<20 // 16MB, enough for runtime init without growing
|
||||
|
||||
@ -362,13 +368,14 @@ func writeGlobalSec(ctxt *ld.Link) {
|
||||
// writeExportSec writes the section that declares exports.
|
||||
// Exports can be accessed by the WebAssembly host, usually JavaScript.
|
||||
// The wasm_export_* functions and the linear memory get exported.
|
||||
func writeExportSec(ctxt *ld.Link, lenHostImports int) {
|
||||
func writeExportSec(ctxt *ld.Link, ldr *loader.Loader, lenHostImports int) {
|
||||
sizeOffset := writeSecHeader(ctxt, sectionExport)
|
||||
|
||||
writeUleb128(ctxt.Out, 4) // number of exports
|
||||
|
||||
for _, name := range []string{"run", "resume", "getsp"} {
|
||||
idx := uint32(lenHostImports) + uint32(ctxt.Syms.ROLookup("wasm_export_"+name, 0).Value>>16) - funcValueOffset
|
||||
s := ldr.Lookup("wasm_export_"+name, 0)
|
||||
idx := uint32(lenHostImports) + uint32(ldr.SymValue(s)>>16) - funcValueOffset
|
||||
writeName(ctxt.Out, name) // inst.exports.run/resume/getsp in wasm_exec.js
|
||||
ctxt.Out.WriteByte(0x00) // func export
|
||||
writeUleb128(ctxt.Out, uint64(idx)) // funcidx
|
||||
|
@ -587,7 +587,7 @@ func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func asmb2(ctxt *ld.Link) {
|
||||
func asmb2(ctxt *ld.Link, _ *loader.Loader) {
|
||||
machlink := uint32(0)
|
||||
if ctxt.HeadType == objabi.Hdarwin {
|
||||
machlink = uint32(ld.Domacholink(ctxt))
|
||||
|
Loading…
Reference in New Issue
Block a user