From 84e7e048167566487e2fe0f61aa178c6ef531998 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 18 Jun 2026 15:15:53 +0100 Subject: [PATCH] Handle relocation groups --- core/rexcode/wasm/module/print_wat.odin | 65 +++++++++++++++++++------ 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/core/rexcode/wasm/module/print_wat.odin b/core/rexcode/wasm/module/print_wat.odin index 4c066819e..18832045e 100644 --- a/core/rexcode/wasm/module/print_wat.odin +++ b/core/rexcode/wasm/module/print_wat.odin @@ -115,16 +115,25 @@ sbprint_wat :: proc(sb: ^strings.Builder, m: Module, opts := DEFAULT_WAT_OPTIONS wat_write_imports(sb, m, unit) + relocs_group, _ := parse_relocations(m, context.temp_allocator) + func_relocs: []wasm.Relocation + for rg in relocs_group { + if rg.target_section == .FUNCTION { + func_relocs = rg.relocs + break + } + } + for f in m.functions { if f.imported { continue } - wat_write_function(sb, m, f, unit) + wat_write_function(sb, m, func_relocs, f, unit) } wat_write_tables (sb, m, unit) wat_write_memories(sb, m, unit) - wat_write_globals (sb, m, unit) + wat_write_globals (sb, m, relocs_group, unit) for e in m.exports { fmt.sbprintf(sb, "%s(export %q (%s %d))\n", unit, e.name, external_kind_name(e.kind), e.index) @@ -134,8 +143,8 @@ sbprint_wat :: proc(sb: ^strings.Builder, m: Module, opts := DEFAULT_WAT_OPTIONS fmt.sbprintf(sb, "%s(start %d)\n", unit, m.start) } - wat_write_elements(sb, m, unit) - wat_write_data (sb, m, unit) + wat_write_elements(sb, m, relocs_group, unit) + wat_write_data (sb, m, relocs_group, unit) } wat_write_functype :: proc(sb: ^strings.Builder, t: Func_Type) { @@ -234,7 +243,7 @@ wat_write_imports :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Pars return nil } -wat_write_function :: proc(sb: ^strings.Builder, m: Module, f: Function, unit: string) { +wat_write_function :: proc(sb: ^strings.Builder, m: Module, func_relocs: []wasm.Relocation, f: Function, unit: string) { strings.write_string(sb, unit) strings.write_string(sb, "(func") defer strings.write_string(sb, ")\n") @@ -271,19 +280,19 @@ wat_write_function :: proc(sb: ^strings.Builder, m: Module, f: Function, unit: s if f.body_size != 0 { body := m.data[f.body_offset:][:f.body_size] - wat_write_body(sb, m, body, unit, level0=2) + wat_write_body(sb, m, func_relocs, body, unit, level0=2) } strings.write_string(sb, unit) } -wat_write_body :: proc(sb: ^strings.Builder, m: Module, body: []u8, unit: string, level0: int) { +wat_write_body :: proc(sb: ^strings.Builder, m: Module, func_relocs: []wasm.Relocation, body: []u8, unit: string, level0: int) { context.allocator = context.temp_allocator // scratch trees live in temp insts: [dynamic]wasm.Instruction info: [dynamic]wasm.Instruction_Info errs: [dynamic]wasm.Error - wasm.decode(body, nil, &insts, &info, &errs, context.temp_allocator) + wasm.decode(body, func_relocs, &insts, &info, &errs, context.temp_allocator) i := 0 stmts, _ := wat_fold_region(insts[:], m, &i) @@ -517,12 +526,20 @@ wat_write_memories :: proc(sb: ^strings.Builder, m: Module, unit: string) { } } -wat_write_globals :: proc(sb: ^strings.Builder, m: Module, unit: string) { +wat_write_globals :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Reloc_Group, unit: string) { idx := count_import_kind(m, .GLOBAL) for sec in m.sections { if sec.id != .GLOBAL { continue } + relocs: []wasm.Relocation + for rg in relocs_group { + if rg.target_section == sec.id { + relocs = rg.relocs + break + } + } + r := reader(m.data, sec.offset) count := rd_u32(&r) or_break for _ in 0.. Parse_Error { +wat_write_elements :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Reloc_Group, unit: string) -> Parse_Error { elem_idx := 0 for sec in m.sections { if sec.id != .ELEMENT { continue } + relocs: []wasm.Relocation + for rg in relocs_group { + if rg.target_section == sec.id { + relocs = rg.relocs + break + } + } + r := reader(m.data, sec.offset) count := rd_u32(&r) or_break for _ in 0.. Par fmt.sbprintf(sb, "%s(elem (;%d;) ", unit, elem_idx) defer strings.write_string(sb, ")\n") - wat_write_const_expr(sb, m, m.data, &r.off, unit, context.temp_allocator) + wat_write_const_expr(sb, m, relocs, m.data, &r.off, unit, context.temp_allocator) strings.write_string(sb, " func") n := rd_u32(&r) or_break for _ in 0.. Par return nil } -wat_write_data :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Parse_Error { +wat_write_data :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Reloc_Group, unit: string) -> Parse_Error { data_idx := 0 for sec in m.sections { if sec.id != .DATA { @@ -595,12 +620,20 @@ wat_write_data :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Parse_E memidx, _ = rd_u32(&r) fallthrough case 0: + relocs: []wasm.Relocation + for rg in relocs_group { + if rg.target_section == sec.id { + relocs = rg.relocs + break + } + } + // expr + bytes if memidx != 0 { fmt.sbprintf(sb, " (memory %d)", memidx) } strings.write_byte(sb, ' ') - wat_write_const_expr(sb, m, m.data, &r.off, unit, context.temp_allocator) + wat_write_const_expr(sb, m, relocs, m.data, &r.off, unit, context.temp_allocator) case 1: // bytes case: @@ -620,7 +653,7 @@ wat_write_data :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Parse_E } // Decode and fold a constant expression at `off^` (advancing past its `end`). -wat_write_const_expr :: proc(sb: ^strings.Builder, m: Module, data: []u8, off: ^u32, unit: string, allocator: runtime.Allocator) { +wat_write_const_expr :: proc(sb: ^strings.Builder, m: Module, relocs: []wasm.Relocation, data: []u8, off: ^u32, unit: string, allocator: runtime.Allocator) { context.allocator = context.temp_allocator exprs: [dynamic]wasm.Instruction @@ -628,7 +661,7 @@ wat_write_const_expr :: proc(sb: ^strings.Builder, m: Module, data: []u8, off: ^ defer delete(exprs) for off^ < u32(len(data)) { - inst, _, next := wasm.decode_one(data, nil, off^, allocator) or_break + inst, _, next := wasm.decode_one(data, relocs, off^, allocator) or_break off^ = next if inst.mnemonic == .END { break