authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-10 19:31:14-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:36-08:00
log7b255235d60cb2891ec628506f4d5e8ca811a865
tree5184e5f869d1cc51b218df74c1b18f0ce7f85dae
parente44bafe5fff4a80bb4d69fa88f0242ffecf2a252

wasm linker: fix off-by-one in function table indexes


2 files changed, 11 insertions(+), 7 deletions(-)

src/arch/wasm/Emit.zig+1-1
...@@ -81,7 +81,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -81,7 +81,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
81 if (is_obj) {81 if (is_obj) {
82 @panic("TODO");82 @panic("TODO");
83 } else {83 } else {
84 leb.writeUleb128(code.fixedWriter(), @intFromEnum(datas[inst].indirect_function_table_index)) catch unreachable;84 leb.writeUleb128(code.fixedWriter(), 1 + @intFromEnum(datas[inst].indirect_function_table_index)) catch unreachable;
85 }85 }
86 inst += 1;86 inst += 1;
87 continue :loop tags[inst];87 continue :loop tags[inst];
src/link/Wasm/Flush.zig+10-6
...@@ -59,6 +59,10 @@ const IndirectFunctionTableIndex = enum(u32) {...@@ -59,6 +59,10 @@ const IndirectFunctionTableIndex = enum(u32) {
59 // These are the same since those are added to the table first.59 // These are the same since those are added to the table first.
60 return @enumFromInt(@intFromEnum(i));60 return @enumFromInt(@intFromEnum(i));
61 }61 }
62
63 fn toAbi(i: IndirectFunctionTableIndex) u32 {
64 return @intFromEnum(i) + 1;
65 }
62};66};
6367
64const DataSegmentGroup = struct {68const DataSegmentGroup = struct {
...@@ -777,9 +781,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -777,9 +781,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
777 for (wasm.func_table_fixups.items) |fixup| {781 for (wasm.func_table_fixups.items) |fixup| {
778 const table_index: IndirectFunctionTableIndex = .fromZcuIndirectFunctionSetIndex(fixup.table_index);782 const table_index: IndirectFunctionTableIndex = .fromZcuIndirectFunctionSetIndex(fixup.table_index);
779 if (!is64) {783 if (!is64) {
780 mem.writeInt(u32, wasm.string_bytes.items[fixup.offset..][0..4], @intFromEnum(table_index), .little);784 mem.writeInt(u32, wasm.string_bytes.items[fixup.offset..][0..4], table_index.toAbi(), .little);
781 } else {785 } else {
782 mem.writeInt(u64, wasm.string_bytes.items[fixup.offset..][0..8], @intFromEnum(table_index), .little);786 mem.writeInt(u64, wasm.string_bytes.items[fixup.offset..][0..8], table_index.toAbi(), .little);
783 }787 }
784 }788 }
785 }789 }
...@@ -1582,19 +1586,19 @@ fn applyRelocs(code: []u8, code_offset: u32, relocs: Wasm.ObjectRelocation.Itera...@@ -1582,19 +1586,19 @@ fn applyRelocs(code: []u8, code_offset: u32, relocs: Wasm.ObjectRelocation.Itera
1582}1586}
15831587
1584fn reloc_u32_table_index(code: []u8, i: IndirectFunctionTableIndex) void {1588fn reloc_u32_table_index(code: []u8, i: IndirectFunctionTableIndex) void {
1585 mem.writeInt(u32, code[0..4], @intFromEnum(i), .little);1589 mem.writeInt(u32, code[0..4], i.toAbi(), .little);
1586}1590}
15871591
1588fn reloc_u64_table_index(code: []u8, i: IndirectFunctionTableIndex) void {1592fn reloc_u64_table_index(code: []u8, i: IndirectFunctionTableIndex) void {
1589 mem.writeInt(u64, code[0..8], @intFromEnum(i), .little);1593 mem.writeInt(u64, code[0..8], i.toAbi(), .little);
1590}1594}
15911595
1592fn reloc_sleb_table_index(code: []u8, i: IndirectFunctionTableIndex) void {1596fn reloc_sleb_table_index(code: []u8, i: IndirectFunctionTableIndex) void {
1593 leb.writeSignedFixed(5, code[0..5], @intFromEnum(i));1597 leb.writeSignedFixed(5, code[0..5], i.toAbi());
1594}1598}
15951599
1596fn reloc_sleb64_table_index(code: []u8, i: IndirectFunctionTableIndex) void {1600fn reloc_sleb64_table_index(code: []u8, i: IndirectFunctionTableIndex) void {
1597 leb.writeSignedFixed(11, code[0..11], @intFromEnum(i));1601 leb.writeSignedFixed(11, code[0..11], i.toAbi());
1598}1602}
15991603
1600fn reloc_u32_function(code: []u8, function: Wasm.OutputFunctionIndex) void {1604fn reloc_u32_function(code: []u8, function: Wasm.OutputFunctionIndex) void {