Commit fb9b818b authored by Richard Musiol's avatar Richard Musiol Committed by Richard Musiol

cmd/link/internal/wasm: do not generate more than 100000 data segments

Some WebAssembly runtimes (e.g. Node.js) fail to load a wasm binary if
it has more than 100000 data segments. Do not skip zero regions any more
if the limit was reached.

Change-Id: I14c4c2aba142d1d2b887bce6d03b8c1c1746c5ec
Reviewed-on: https://go-review.googlesource.com/c/go/+/168884
Run-TryBot: Richard Musiol <neelance@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent 56e1614c
...@@ -427,8 +427,11 @@ func writeDataSec(ctxt *ld.Link) { ...@@ -427,8 +427,11 @@ func writeDataSec(ctxt *ld.Link) {
// overhead of adding a new segment (same as wasm-opt's memory-packing optimization uses). // overhead of adding a new segment (same as wasm-opt's memory-packing optimization uses).
const segmentOverhead = 8 const segmentOverhead = 8
// Generate at most this many segments. A higher number of segments gets rejected by some WebAssembly runtimes.
const maxNumSegments = 100000
var segments []*dataSegment var segments []*dataSegment
for _, sec := range sections { for secIndex, sec := range sections {
data := ld.DatblkBytes(ctxt, int64(sec.Vaddr), int64(sec.Length)) data := ld.DatblkBytes(ctxt, int64(sec.Vaddr), int64(sec.Length))
offset := int32(sec.Vaddr) offset := int32(sec.Vaddr)
...@@ -441,21 +444,26 @@ func writeDataSec(ctxt *ld.Link) { ...@@ -441,21 +444,26 @@ 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
for { if len(segments)+(len(sections)-secIndex) == maxNumSegments {
// look for beginning of zeroes segmentEnd = dataLen
for segmentEnd < dataLen && data[segmentEnd] != 0 { zeroEnd = dataLen
segmentEnd++ } else {
} for {
// look for end of zeroes // look for beginning of zeroes
zeroEnd = segmentEnd for segmentEnd < dataLen && data[segmentEnd] != 0 {
for zeroEnd < dataLen && data[zeroEnd] == 0 { segmentEnd++
zeroEnd++ }
} // look for end of zeroes
// emit segment if omitting zeroes reduces the output size zeroEnd = segmentEnd
if zeroEnd-segmentEnd >= segmentOverhead || zeroEnd == dataLen { for zeroEnd < dataLen && data[zeroEnd] == 0 {
break zeroEnd++
}
// emit segment if omitting zeroes reduces the output size
if zeroEnd-segmentEnd >= segmentOverhead || zeroEnd == dataLen {
break
}
segmentEnd = zeroEnd
} }
segmentEnd = zeroEnd
} }
segments = append(segments, &dataSegment{ segments = append(segments, &dataSegment{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment