diff options
| author | Richard Musiol <mail@richard-musiol.de> | 2019-03-24 18:21:11 +0100 |
|---|---|---|
| committer | Richard Musiol <neelance@gmail.com> | 2019-03-25 07:54:44 +0000 |
| commit | fb9b818bbd2273579ea09f71017ee42bbc91a3b3 (patch) | |
| tree | 5c15e4c78a235b999afcae98e901f62b181512ac | |
| parent | 56e1614c47cca7dc76b435f485fe86fe088d5127 (diff) | |
| download | go-fb9b818bbd2273579ea09f71017ee42bbc91a3b3.tar.xz | |
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: Cherry Zhang <cherryyz@google.com>
| -rw-r--r-- | src/cmd/link/internal/wasm/asm.go | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/src/cmd/link/internal/wasm/asm.go b/src/cmd/link/internal/wasm/asm.go index 2665659fe0..abb4409188 100644 --- a/src/cmd/link/internal/wasm/asm.go +++ b/src/cmd/link/internal/wasm/asm.go @@ -427,8 +427,11 @@ func writeDataSec(ctxt *ld.Link) { // overhead of adding a new segment (same as wasm-opt's memory-packing optimization uses). 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 - for _, sec := range sections { + for secIndex, sec := range sections { data := ld.DatblkBytes(ctxt, int64(sec.Vaddr), int64(sec.Length)) offset := int32(sec.Vaddr) @@ -441,21 +444,26 @@ func writeDataSec(ctxt *ld.Link) { for len(data) > 0 { dataLen := int32(len(data)) var segmentEnd, zeroEnd int32 - for { - // look for beginning of zeroes - for segmentEnd < dataLen && data[segmentEnd] != 0 { - segmentEnd++ - } - // look for end of zeroes - zeroEnd = segmentEnd - for zeroEnd < dataLen && data[zeroEnd] == 0 { - zeroEnd++ - } - // emit segment if omitting zeroes reduces the output size - if zeroEnd-segmentEnd >= segmentOverhead || zeroEnd == dataLen { - break + if len(segments)+(len(sections)-secIndex) == maxNumSegments { + segmentEnd = dataLen + zeroEnd = dataLen + } else { + for { + // look for beginning of zeroes + for segmentEnd < dataLen && data[segmentEnd] != 0 { + segmentEnd++ + } + // look for end of zeroes + zeroEnd = segmentEnd + for zeroEnd < dataLen && data[zeroEnd] == 0 { + 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{ |
