Skip to content

Commit 2ae06c9

Browse files
LiedtkeV8-internal LUCI CQ
authored andcommitted
[wasm] Don't emit empty module sections
Change-Id: I99bc88a3cefdd5d4cbaf645b10e1cdcd66138a52 Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/9123977 Commit-Queue: Manos Koukoutos <manoskouk@google.com> Reviewed-by: Manos Koukoutos <manoskouk@google.com> Auto-Submit: Matthias Liedtke <mliedtke@google.com>
1 parent 7e5724c commit 2ae06c9

File tree

2 files changed

+67
-23
lines changed

2 files changed

+67
-23
lines changed

Sources/Fuzzilli/Lifting/WasmLifter.swift

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -622,10 +622,6 @@ public class WasmLifter {
622622
}
623623

624624
private func buildTypeSection() throws {
625-
self.bytecode += [WasmSection.type.rawValue]
626-
627-
var temp = Data()
628-
629625
// Collect all signatures of imported functions, suspendable objects or tags.
630626
// See importAnalysis for more details.
631627
for signature in self.exports.compactMap({ $0.getImport()?.signature }) {
@@ -638,7 +634,12 @@ public class WasmLifter {
638634
}
639635

640636
let typeCount = self.signatures.count + typeGroups.count
641-
temp += Leb128.unsignedEncode(typeCount)
637+
if typeCount == 0 {
638+
return
639+
}
640+
641+
self.bytecode += [WasmSection.type.rawValue]
642+
var temp = Leb128.unsignedEncode(typeCount)
642643

643644
// TODO(mliedtke): Integrate this with the whole signature mechanism as
644645
// these signatures could contain wasm-gc types.
@@ -791,11 +792,16 @@ public class WasmLifter {
791792
}
792793

793794
private func buildFunctionSection() throws {
795+
let functionCount = self.exports.count { $0.isFunction }
796+
if functionCount == 0 {
797+
return
798+
}
799+
794800
self.bytecode += [WasmSection.function.rawValue]
795801

796802
// The number of functions we have, as this is a vector of type idxs.
797803
// TODO(cffsmith): functions can share type indices. This could be an optimization later on.
798-
var temp = Leb128.unsignedEncode(self.exports.count { $0.isFunction })
804+
var temp = Leb128.unsignedEncode(functionCount)
799805

800806
for case let .function(functionInfo) in self.exports {
801807
temp.append(Leb128.unsignedEncode(try getSignatureIndex(functionInfo!.signature)))
@@ -814,9 +820,14 @@ public class WasmLifter {
814820
}
815821

816822
private func buildTableSection() throws {
823+
let tableCount = self.exports.count { $0.isTable }
824+
if tableCount == 0 {
825+
return
826+
}
827+
817828
self.bytecode += [WasmSection.table.rawValue]
818829

819-
var temp = Leb128.unsignedEncode(self.exports.count { $0.isTable })
830+
var temp = Leb128.unsignedEncode(tableCount)
820831

821832
for case let .table(instruction) in self.exports {
822833
let op = instruction!.op as! WasmDefineTable
@@ -922,9 +933,13 @@ public class WasmLifter {
922933
}
923934

924935
private func buildCodeSection(_ instructions: Code) throws {
936+
let functionCount = self.exports.count { $0.isFunction }
937+
if functionCount == 0 {
938+
return
939+
}
940+
925941
// Build the contents of the section
926-
var temp = Data()
927-
temp += Leb128.unsignedEncode(self.exports.count { $0.isFunction })
942+
var temp = Leb128.unsignedEncode(functionCount)
928943

929944
var functionBranchHints = [Data]()
930945

@@ -1006,6 +1021,10 @@ public class WasmLifter {
10061021
}
10071022

10081023
private func buildDataSection() throws {
1024+
if self.dataSegments.isEmpty {
1025+
return
1026+
}
1027+
10091028
self.bytecode += [WasmSection.data.rawValue]
10101029

10111030
var temp = Data()
@@ -1030,11 +1049,12 @@ public class WasmLifter {
10301049
}
10311050

10321051
private func buildDataCountSection() throws {
1033-
self.bytecode += [WasmSection.datacount.rawValue]
1034-
1035-
var temp = Data()
1036-
temp += Leb128.unsignedEncode(self.dataSegments.count)
1052+
if self.dataSegments.isEmpty {
1053+
return
1054+
}
10371055

1056+
self.bytecode += [WasmSection.datacount.rawValue]
1057+
let temp = Leb128.unsignedEncode(self.dataSegments.count)
10381058
self.bytecode.append(Leb128.unsignedEncode(temp.count))
10391059
self.bytecode.append(temp)
10401060

@@ -1047,11 +1067,13 @@ public class WasmLifter {
10471067
}
10481068

10491069
private func buildGlobalSection() throws {
1050-
self.bytecode += [WasmSection.global.rawValue]
1051-
1052-
var temp = Data()
1070+
let globalCount = self.exports.count { $0.isGlobal }
1071+
if globalCount == 0 {
1072+
return
1073+
}
10531074

1054-
temp += Leb128.unsignedEncode(self.exports.count { $0.isGlobal })
1075+
self.bytecode += [WasmSection.global.rawValue]
1076+
var temp = Leb128.unsignedEncode(globalCount)
10551077

10561078
// TODO: in the future this should maybe be a context that allows instructions? Such that we can fuzz this expression as well?
10571079
for case let .global(instruction) in self.exports {
@@ -1102,13 +1124,13 @@ public class WasmLifter {
11021124
}
11031125

11041126
private func buildMemorySection() {
1105-
self.bytecode += [WasmSection.memory.rawValue]
1106-
1107-
var temp = Data()
1127+
let memoryCount = self.exports.count { $0.isMemory }
1128+
if memoryCount == 0 {
1129+
return
1130+
}
11081131

1109-
// The amount of memories we have, per standard this can currently only be one, either defined or imported
1110-
// https://webassembly.github.io/spec/core/syntax/modules.html#memories
1111-
temp += Leb128.unsignedEncode(self.exports.count { $0.isMemory })
1132+
self.bytecode += [WasmSection.memory.rawValue]
1133+
var temp = Leb128.unsignedEncode(memoryCount)
11121134

11131135
for case let .memory(instruction) in self.exports {
11141136
let type = typer.type(of: instruction!.output)
@@ -1164,6 +1186,10 @@ public class WasmLifter {
11641186

11651187
// Export all imports and defined things by default.
11661188
private func buildExportedSection() throws {
1189+
if self.exports.isEmpty {
1190+
return
1191+
}
1192+
11671193
self.bytecode += [WasmSection.export.rawValue]
11681194

11691195
var temp = Data()

Tests/FuzzilliTests/LifterTest.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3897,4 +3897,22 @@ class LifterTests: XCTestCase {
38973897

38983898
XCTAssertEqual(actual, expected)
38993899
}
3900+
3901+
func testEmptyWasmModule() {
3902+
let fuzzer = makeMockFuzzer()
3903+
let b = fuzzer.makeBuilder()
3904+
b.buildWasmModule {_ in}
3905+
let program = b.finalize()
3906+
let actual = fuzzer.lifter.lift(program)
3907+
3908+
// An empty Wasm module should only contain the needed prefix but no empty sections.
3909+
let expected = """
3910+
const v0 = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([
3911+
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00,
3912+
])));
3913+
3914+
"""
3915+
3916+
XCTAssertEqual(actual, expected)
3917+
}
39003918
}

0 commit comments

Comments
 (0)