aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Musiol <mail@richard-musiol.de>2019-03-24 18:21:11 +0100
committerRichard Musiol <neelance@gmail.com>2019-03-25 07:54:44 +0000
commitfb9b818bbd2273579ea09f71017ee42bbc91a3b3 (patch)
tree5c15e4c78a235b999afcae98e901f62b181512ac
parent56e1614c47cca7dc76b435f485fe86fe088d5127 (diff)
downloadgo-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.go38
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{