| ... | @@ -59,7 +59,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -59,7 +59,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 59 | const gpa = comp.gpa; | 59 | const gpa = comp.gpa; |
| 60 | const import_memory = comp.config.import_memory; | 60 | const import_memory = comp.config.import_memory; |
| 61 | const export_memory = comp.config.export_memory; | 61 | const export_memory = comp.config.export_memory; |
| 62 | const target = comp.root_mod.resolved_target.result; | 62 | const target = &comp.root_mod.resolved_target.result; |
| 63 | const is_obj = comp.config.output_mode == .Obj; | 63 | const is_obj = comp.config.output_mode == .Obj; |
| 64 | const allow_undefined = is_obj or wasm.import_symbols; | 64 | const allow_undefined = is_obj or wasm.import_symbols; |
| 65 | const zcu = wasm.base.comp.zcu.?; | 65 | const zcu = wasm.base.comp.zcu.?; |
| ... | @@ -523,7 +523,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -523,7 +523,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 523 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); | 523 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); |
| 524 | try binary_bytes.appendSlice(gpa, name); | 524 | try binary_bytes.appendSlice(gpa, name); |
| 525 | try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.function)); | 525 | try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.function)); |
| 526 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.function_imports.entries.len + @intFromEnum(exp.function_index)))); | 526 | try leb.writeUleb128(binary_writer, @intFromEnum(exp.function_index)); |
| 527 | } | 527 | } |
| 528 | exports_len += wasm.function_exports.items.len; | 528 | exports_len += wasm.function_exports.items.len; |
| 529 | | 529 | |
| ... | @@ -543,7 +543,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -543,7 +543,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 543 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); | 543 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); |
| 544 | try binary_bytes.appendSlice(gpa, name); | 544 | try binary_bytes.appendSlice(gpa, name); |
| 545 | try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.global)); | 545 | try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.global)); |
| 546 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.global_imports.entries.len + @intFromEnum(exp.global_index)))); | 546 | try leb.writeUleb128(binary_writer, @intFromEnum(exp.global_index)); |
| 547 | } | 547 | } |
| 548 | exports_len += wasm.global_exports.items.len; | 548 | exports_len += wasm.global_exports.items.len; |
| 549 | | 549 | |
| ... | @@ -555,38 +555,39 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -555,38 +555,39 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 555 | } | 555 | } |
| 556 | } | 556 | } |
| 557 | | 557 | |
| 558 | if (Wasm.FunctionIndex.fromResolution(wasm.entry_resolution)) |entry_index| { | 558 | if (Wasm.FunctionIndex.fromResolution(wasm, wasm.entry_resolution)) |entry_index| { |
| 559 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 559 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 560 | replaceVecSectionHeader(binary_bytes, header_offset, .start, @intFromEnum(entry_index)); | 560 | replaceVecSectionHeader(binary_bytes, header_offset, .start, @intFromEnum(entry_index)); |
| 561 | } | 561 | } |
| 562 | | 562 | |
| 563 | // element section (function table) | 563 | // element section (function table) |
| 564 | if (wasm.function_table.count() > 0) { | 564 | if (f.indirect_function_table.count() > 0) { |
| 565 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 565 | @panic("TODO"); |
| | 566 | //const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 566 | | 567 | |
| 567 | const table_loc = wasm.globals.get(wasm.preloaded_strings.__indirect_function_table).?; | 568 | //const table_loc = wasm.globals.get(wasm.preloaded_strings.__indirect_function_table).?; |
| 568 | const table_sym = wasm.finalSymbolByLoc(table_loc); | 569 | //const table_sym = wasm.finalSymbolByLoc(table_loc); |
| 569 | | 570 | |
| 570 | const flags: u32 = if (table_sym.index == 0) 0x0 else 0x02; // passive with implicit 0-index table or set table index manually | 571 | //const flags: u32 = if (table_sym.index == 0) 0x0 else 0x02; // passive with implicit 0-index table or set table index manually |
| 571 | try leb.writeUleb128(binary_writer, flags); | 572 | //try leb.writeUleb128(binary_writer, flags); |
| 572 | if (flags == 0x02) { | 573 | //if (flags == 0x02) { |
| 573 | try leb.writeUleb128(binary_writer, table_sym.index); | 574 | // try leb.writeUleb128(binary_writer, table_sym.index); |
| 574 | } | 575 | //} |
| 575 | try emitInit(binary_writer, .{ .i32_const = 1 }); // We start at index 1, so unresolved function pointers are invalid | 576 | //try emitInit(binary_writer, .{ .i32_const = 1 }); // We start at index 1, so unresolved function pointers are invalid |
| 576 | if (flags == 0x02) { | 577 | //if (flags == 0x02) { |
| 577 | try leb.writeUleb128(binary_writer, @as(u8, 0)); // represents funcref | 578 | // try leb.writeUleb128(binary_writer, @as(u8, 0)); // represents funcref |
| 578 | } | 579 | //} |
| 579 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.function_table.count()))); | 580 | //try leb.writeUleb128(binary_writer, @as(u32, @intCast(f.indirect_function_table.count()))); |
| 580 | var symbol_it = wasm.function_table.keyIterator(); | 581 | //var symbol_it = f.indirect_function_table.keyIterator(); |
| 581 | while (symbol_it.next()) |symbol_loc_ptr| { | 582 | //while (symbol_it.next()) |symbol_loc_ptr| { |
| 582 | const sym = wasm.finalSymbolByLoc(symbol_loc_ptr.*); | 583 | // const sym = wasm.finalSymbolByLoc(symbol_loc_ptr.*); |
| 583 | assert(sym.flags.alive); | 584 | // assert(sym.flags.alive); |
| 584 | assert(sym.index < wasm.functions.count() + wasm.imported_functions_count); | 585 | // assert(sym.index < wasm.functions.count() + wasm.imported_functions_count); |
| 585 | try leb.writeUleb128(binary_writer, sym.index); | 586 | // try leb.writeUleb128(binary_writer, sym.index); |
| 586 | } | 587 | //} |
| 587 | | 588 | |
| 588 | replaceVecSectionHeader(binary_bytes, header_offset, .element, 1); | 589 | //replaceVecSectionHeader(binary_bytes, header_offset, .element, 1); |
| 589 | section_index += 1; | 590 | //section_index += 1; |
| 590 | } | 591 | } |
| 591 | | 592 | |
| 592 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. | 593 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. |
| ... | @@ -600,7 +601,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -600,7 +601,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 600 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 601 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 601 | const start_offset = binary_bytes.items.len - 5; // minus 5 so start offset is 5 to include entry count | 602 | const start_offset = binary_bytes.items.len - 5; // minus 5 so start offset is 5 to include entry count |
| 602 | | 603 | |
| 603 | for (wasm.functions.keys()) |resolution| switch (resolution.unpack()) { | 604 | for (wasm.functions.keys()) |resolution| switch (resolution.unpack(wasm)) { |
| 604 | .unresolved => unreachable, | 605 | .unresolved => unreachable, |
| 605 | .__wasm_apply_global_tls_relocs => @panic("TODO lower __wasm_apply_global_tls_relocs"), | 606 | .__wasm_apply_global_tls_relocs => @panic("TODO lower __wasm_apply_global_tls_relocs"), |
| 606 | .__wasm_call_ctors => @panic("TODO lower __wasm_call_ctors"), | 607 | .__wasm_call_ctors => @panic("TODO lower __wasm_call_ctors"), |
| ... | @@ -614,10 +615,19 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -614,10 +615,19 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 614 | //try leb.writeUleb128(binary_writer, atom.code.len); | 615 | //try leb.writeUleb128(binary_writer, atom.code.len); |
| 615 | //try binary_bytes.appendSlice(gpa, atom.code.slice(wasm)); | 616 | //try binary_bytes.appendSlice(gpa, atom.code.slice(wasm)); |
| 616 | }, | 617 | }, |
| 617 | .nav => |i| { | 618 | .nav_exe => |i| { |
| | 619 | assert(!is_obj); |
| | 620 | _ = i; |
| | 621 | _ = start_offset; |
| | 622 | @panic("TODO lower nav exe code and apply relocations"); |
| | 623 | //try leb.writeUleb128(binary_writer, atom.code.len); |
| | 624 | //try binary_bytes.appendSlice(gpa, atom.code.slice(wasm)); |
| | 625 | }, |
| | 626 | .nav_obj => |i| { |
| | 627 | assert(is_obj); |
| 618 | _ = i; | 628 | _ = i; |
| 619 | _ = start_offset; | 629 | _ = start_offset; |
| 620 | @panic("TODO lower nav code and apply relocations"); | 630 | @panic("TODO lower nav obj code and apply relocations"); |
| 621 | //try leb.writeUleb128(binary_writer, atom.code.len); | 631 | //try leb.writeUleb128(binary_writer, atom.code.len); |
| 622 | //try binary_bytes.appendSlice(gpa, atom.code.slice(wasm)); | 632 | //try binary_bytes.appendSlice(gpa, atom.code.slice(wasm)); |
| 623 | }, | 633 | }, |
| ... | @@ -636,7 +646,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -636,7 +646,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 636 | var offset: u32 = undefined; | 646 | var offset: u32 = undefined; |
| 637 | for (segment_indexes, segment_offsets) |segment_index, segment_offset| { | 647 | for (segment_indexes, segment_offsets) |segment_index, segment_offset| { |
| 638 | const segment = segment_index.ptr(wasm); | 648 | const segment = segment_index.ptr(wasm); |
| 639 | if (segment.size == 0) continue; | 649 | const segment_payload = segment.payload.slice(wasm); |
| | 650 | if (segment_payload.len == 0) continue; |
| 640 | if (!import_memory and isBss(wasm, segment.name)) { | 651 | if (!import_memory and isBss(wasm, segment.name)) { |
| 641 | // It counted for virtual memory but it does not go into the binary. | 652 | // It counted for virtual memory but it does not go into the binary. |
| 642 | continue; | 653 | continue; |
| ... | @@ -657,8 +668,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -657,8 +668,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 657 | | 668 | |
| 658 | try binary_bytes.appendNTimes(gpa, 0, segment_offset - offset); | 669 | try binary_bytes.appendNTimes(gpa, 0, segment_offset - offset); |
| 659 | offset = segment_offset; | 670 | offset = segment_offset; |
| 660 | try binary_bytes.appendSlice(gpa, segment.payload.slice(wasm)); | 671 | try binary_bytes.appendSlice(gpa, segment_payload); |
| 661 | offset += segment.payload.len; | 672 | offset += @intCast(segment_payload.len); |
| 662 | if (true) @panic("TODO apply data segment relocations"); | 673 | if (true) @panic("TODO apply data segment relocations"); |
| 663 | } | 674 | } |
| 664 | assert(group_index == f.data_segment_groups.items.len); | 675 | assert(group_index == f.data_segment_groups.items.len); |
| ... | @@ -680,7 +691,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -680,7 +691,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 680 | // try wasm.emitDataRelocations(binary_bytes, data_index, symbol_table); | 691 | // try wasm.emitDataRelocations(binary_bytes, data_index, symbol_table); |
| 681 | //} | 692 | //} |
| 682 | } else if (comp.config.debug_format != .strip) { | 693 | } else if (comp.config.debug_format != .strip) { |
| 683 | try wasm.emitNameSection(binary_bytes, arena); | 694 | try emitNameSection(wasm, binary_bytes, arena); |
| 684 | } | 695 | } |
| 685 | | 696 | |
| 686 | if (comp.config.debug_format != .strip) { | 697 | if (comp.config.debug_format != .strip) { |
| ... | @@ -699,14 +710,14 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -699,14 +710,14 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 699 | std.fmt.fmtSliceHexLower(id[8..10]), | 710 | std.fmt.fmtSliceHexLower(id[8..10]), |
| 700 | std.fmt.fmtSliceHexLower(id[10..]), | 711 | std.fmt.fmtSliceHexLower(id[10..]), |
| 701 | }); | 712 | }); |
| 702 | try emitBuildIdSection(binary_bytes, &uuid); | 713 | try emitBuildIdSection(gpa, binary_bytes, &uuid); |
| 703 | }, | 714 | }, |
| 704 | .hexstring => |hs| { | 715 | .hexstring => |hs| { |
| 705 | var buffer: [32 * 2]u8 = undefined; | 716 | var buffer: [32 * 2]u8 = undefined; |
| 706 | const str = std.fmt.bufPrint(&buffer, "{s}", .{ | 717 | const str = std.fmt.bufPrint(&buffer, "{s}", .{ |
| 707 | std.fmt.fmtSliceHexLower(hs.toSlice()), | 718 | std.fmt.fmtSliceHexLower(hs.toSlice()), |
| 708 | }) catch unreachable; | 719 | }) catch unreachable; |
| 709 | try emitBuildIdSection(binary_bytes, str); | 720 | try emitBuildIdSection(gpa, binary_bytes, str); |
| 710 | }, | 721 | }, |
| 711 | else => |mode| { | 722 | else => |mode| { |
| 712 | var err = try diags.addErrorWithNotes(0); | 723 | var err = try diags.addErrorWithNotes(0); |
| ... | @@ -717,9 +728,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -717,9 +728,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 717 | var debug_bytes = std.ArrayList(u8).init(gpa); | 728 | var debug_bytes = std.ArrayList(u8).init(gpa); |
| 718 | defer debug_bytes.deinit(); | 729 | defer debug_bytes.deinit(); |
| 719 | | 730 | |
| 720 | try emitProducerSection(binary_bytes); | 731 | try emitProducerSection(gpa, binary_bytes); |
| 721 | if (!target.cpu.features.isEmpty()) | 732 | try emitFeaturesSection(gpa, binary_bytes, target); |
| 722 | try emitFeaturesSection(binary_bytes, target.cpu.features); | | |
| 723 | } | 733 | } |
| 724 | | 734 | |
| 725 | // Finally, write the entire binary into the file. | 735 | // Finally, write the entire binary into the file. |
| ... | @@ -729,6 +739,10 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { | ... | @@ -729,6 +739,10 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 729 | } | 739 | } |
| 730 | | 740 | |
| 731 | fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), arena: Allocator) !void { | 741 | fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), arena: Allocator) !void { |
| | 742 | if (true) { |
| | 743 | std.log.warn("TODO emit name section", .{}); |
| | 744 | return; |
| | 745 | } |
| 732 | const comp = wasm.base.comp; | 746 | const comp = wasm.base.comp; |
| 733 | const gpa = comp.gpa; | 747 | const gpa = comp.gpa; |
| 734 | const import_memory = comp.config.import_memory; | 748 | const import_memory = comp.config.import_memory; |
| ... | @@ -796,31 +810,15 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), arena | ... | @@ -796,31 +810,15 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), arena |
| 796 | // Data segments are already ordered. | 810 | // Data segments are already ordered. |
| 797 | | 811 | |
| 798 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 812 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 799 | const writer = binary_bytes.writer(); | 813 | defer writeCustomSectionHeader(binary_bytes, header_offset); |
| | 814 | |
| | 815 | const writer = binary_bytes.writer(gpa); |
| 800 | try leb.writeUleb128(writer, @as(u32, @intCast("name".len))); | 816 | try leb.writeUleb128(writer, @as(u32, @intCast("name".len))); |
| 801 | try writer.writeAll("name"); | 817 | try writer.writeAll("name"); |
| 802 | | 818 | |
| 803 | try emitNameSubsection(wasm, binary_bytes, .function, funcs.keys(), funcs.values()); | 819 | try emitNameSubsection(wasm, binary_bytes, .function, funcs.keys(), funcs.values()); |
| 804 | try emitNameSubsection(wasm, binary_bytes, .global, globals.items(.index), globals.items(.name)); | 820 | try emitNameSubsection(wasm, binary_bytes, .global, globals.items(.index), globals.items(.name)); |
| 805 | try emitNameSubsection(wasm, binary_bytes, .data_segment, segments.items(.index), segments.items(.name)); | 821 | try emitNameSubsection(wasm, binary_bytes, .data_segment, segments.items(.index), segments.items(.name)); |
| 806 | | | |
| 807 | try writeCustomSectionHeader( | | |
| 808 | binary_bytes.items, | | |
| 809 | header_offset, | | |
| 810 | @as(u32, @intCast(binary_bytes.items.len - header_offset - 6)), | | |
| 811 | ); | | |
| 812 | } | | |
| 813 | | | |
| 814 | fn writeCustomSectionHeader(buffer: []u8, offset: u32, size: u32) !void { | | |
| 815 | var buf: [1 + 5]u8 = undefined; | | |
| 816 | buf[0] = 0; // 0 = 'custom' section | | |
| 817 | leb.writeUnsignedFixed(5, buf[1..6], size); | | |
| 818 | buffer[offset..][0..buf.len].* = buf; | | |
| 819 | } | | |
| 820 | | | |
| 821 | fn reserveCustomSectionHeader(gpa: Allocator, bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!u32 { | | |
| 822 | try bytes.appendNTimes(gpa, 0, section_header_size); | | |
| 823 | return @intCast(bytes.items.len - section_header_size); | | |
| 824 | } | 822 | } |
| 825 | | 823 | |
| 826 | fn emitNameSubsection( | 824 | fn emitNameSubsection( |
| ... | @@ -856,35 +854,40 @@ fn emitNameSubsection( | ... | @@ -856,35 +854,40 @@ fn emitNameSubsection( |
| 856 | fn emitFeaturesSection( | 854 | fn emitFeaturesSection( |
| 857 | gpa: Allocator, | 855 | gpa: Allocator, |
| 858 | binary_bytes: *std.ArrayListUnmanaged(u8), | 856 | binary_bytes: *std.ArrayListUnmanaged(u8), |
| 859 | features: []const Wasm.Feature, | 857 | target: *const std.Target, |
| 860 | ) !void { | 858 | ) Allocator.Error!void { |
| | 859 | const feature_count = target.cpu.features.count(); |
| | 860 | if (feature_count == 0) return; |
| | 861 | |
| 861 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 862 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| | 863 | defer writeCustomSectionHeader(binary_bytes, header_offset); |
| 862 | | 864 | |
| 863 | const writer = binary_bytes.writer(); | 865 | const writer = binary_bytes.writer(gpa); |
| 864 | const target_features = "target_features"; | 866 | const target_features = "target_features"; |
| 865 | try leb.writeUleb128(writer, @as(u32, @intCast(target_features.len))); | 867 | try leb.writeUleb128(writer, @as(u32, @intCast(target_features.len))); |
| 866 | try writer.writeAll(target_features); | 868 | try writer.writeAll(target_features); |
| 867 | | 869 | |
| 868 | try leb.writeUleb128(writer, @as(u32, @intCast(features.len))); | 870 | try leb.writeUleb128(writer, @as(u32, @intCast(feature_count))); |
| 869 | for (features) |feature| { | 871 | |
| 870 | assert(feature.prefix != .invalid); | 872 | var safety_count = feature_count; |
| 871 | try leb.writeUleb128(writer, @tagName(feature.prefix)[0]); | 873 | for (target.cpu.arch.allFeaturesList(), 0..) |*feature, i| { |
| 872 | const name = @tagName(feature.tag); | 874 | if (!std.Target.wasm.featureSetHas(target.cpu.features, @enumFromInt(i))) continue; |
| 873 | try leb.writeUleb128(writer, @as(u32, name.len)); | 875 | safety_count -= 1; |
| | 876 | |
| | 877 | try leb.writeUleb128(writer, @as(u32, '+')); |
| | 878 | // Depends on llvm_name for the hyphenated version that matches wasm tooling conventions. |
| | 879 | const name = feature.llvm_name.?; |
| | 880 | try leb.writeUleb128(writer, @as(u32, @intCast(name.len))); |
| 874 | try writer.writeAll(name); | 881 | try writer.writeAll(name); |
| 875 | } | 882 | } |
| 876 | | 883 | assert(safety_count == 0); |
| 877 | try writeCustomSectionHeader( | | |
| 878 | binary_bytes.items, | | |
| 879 | header_offset, | | |
| 880 | @as(u32, @intCast(binary_bytes.items.len - header_offset - 6)), | | |
| 881 | ); | | |
| 882 | } | 884 | } |
| 883 | | 885 | |
| 884 | fn emitBuildIdSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8), build_id: []const u8) !void { | 886 | fn emitBuildIdSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8), build_id: []const u8) !void { |
| 885 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 887 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| | 888 | defer writeCustomSectionHeader(binary_bytes, header_offset); |
| 886 | | 889 | |
| 887 | const writer = binary_bytes.writer(); | 890 | const writer = binary_bytes.writer(gpa); |
| 888 | const hdr_build_id = "build_id"; | 891 | const hdr_build_id = "build_id"; |
| 889 | try leb.writeUleb128(writer, @as(u32, @intCast(hdr_build_id.len))); | 892 | try leb.writeUleb128(writer, @as(u32, @intCast(hdr_build_id.len))); |
| 890 | try writer.writeAll(hdr_build_id); | 893 | try writer.writeAll(hdr_build_id); |
| ... | @@ -892,18 +895,13 @@ fn emitBuildIdSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8), | ... | @@ -892,18 +895,13 @@ fn emitBuildIdSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8), |
| 892 | try leb.writeUleb128(writer, @as(u32, 1)); | 895 | try leb.writeUleb128(writer, @as(u32, 1)); |
| 893 | try leb.writeUleb128(writer, @as(u32, @intCast(build_id.len))); | 896 | try leb.writeUleb128(writer, @as(u32, @intCast(build_id.len))); |
| 894 | try writer.writeAll(build_id); | 897 | try writer.writeAll(build_id); |
| 895 | | | |
| 896 | try writeCustomSectionHeader( | | |
| 897 | binary_bytes.items, | | |
| 898 | header_offset, | | |
| 899 | @as(u32, @intCast(binary_bytes.items.len - header_offset - 6)), | | |
| 900 | ); | | |
| 901 | } | 898 | } |
| 902 | | 899 | |
| 903 | fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8)) !void { | 900 | fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8)) !void { |
| 904 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 901 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| | 902 | defer writeCustomSectionHeader(binary_bytes, header_offset); |
| 905 | | 903 | |
| 906 | const writer = binary_bytes.writer(); | 904 | const writer = binary_bytes.writer(gpa); |
| 907 | const producers = "producers"; | 905 | const producers = "producers"; |
| 908 | try leb.writeUleb128(writer, @as(u32, @intCast(producers.len))); | 906 | try leb.writeUleb128(writer, @as(u32, @intCast(producers.len))); |
| 909 | try writer.writeAll(producers); | 907 | try writer.writeAll(producers); |
| ... | @@ -947,12 +945,6 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) | ... | @@ -947,12 +945,6 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 947 | try writer.writeAll(build_options.version); | 945 | try writer.writeAll(build_options.version); |
| 948 | } | 946 | } |
| 949 | } | 947 | } |
| 950 | | | |
| 951 | try writeCustomSectionHeader( | | |
| 952 | binary_bytes.items, | | |
| 953 | header_offset, | | |
| 954 | @as(u32, @intCast(binary_bytes.items.len - header_offset - 6)), | | |
| 955 | ); | | |
| 956 | } | 948 | } |
| 957 | | 949 | |
| 958 | ///// For each relocatable section, emits a custom "relocation.<section_name>" section | 950 | ///// For each relocatable section, emits a custom "relocation.<section_name>" section |
| ... | @@ -965,7 +957,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) | ... | @@ -965,7 +957,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 965 | // const comp = wasm.base.comp; | 957 | // const comp = wasm.base.comp; |
| 966 | // const gpa = comp.gpa; | 958 | // const gpa = comp.gpa; |
| 967 | // const code_index = wasm.code_section_index.unwrap() orelse return; | 959 | // const code_index = wasm.code_section_index.unwrap() orelse return; |
| 968 | // const writer = binary_bytes.writer(); | 960 | // const writer = binary_bytes.writer(gpa); |
| 969 | // const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 961 | // const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 970 | // | 962 | // |
| 971 | // // write custom section information | 963 | // // write custom section information |
| ... | @@ -1001,8 +993,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) | ... | @@ -1001,8 +993,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 1001 | // var buf: [5]u8 = undefined; | 993 | // var buf: [5]u8 = undefined; |
| 1002 | // leb.writeUnsignedFixed(5, &buf, count); | 994 | // leb.writeUnsignedFixed(5, &buf, count); |
| 1003 | // try binary_bytes.insertSlice(reloc_start, &buf); | 995 | // try binary_bytes.insertSlice(reloc_start, &buf); |
| 1004 | // const size: u32 = @intCast(binary_bytes.items.len - header_offset - 6); | 996 | // writeCustomSectionHeader(binary_bytes, header_offset); |
| 1005 | // try writeCustomSectionHeader(binary_bytes.items, header_offset, size); | | |
| 1006 | //} | 997 | //} |
| 1007 | | 998 | |
| 1008 | //fn emitDataRelocations( | 999 | //fn emitDataRelocations( |
| ... | @@ -1013,7 +1004,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) | ... | @@ -1013,7 +1004,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 1013 | //) !void { | 1004 | //) !void { |
| 1014 | // const comp = wasm.base.comp; | 1005 | // const comp = wasm.base.comp; |
| 1015 | // const gpa = comp.gpa; | 1006 | // const gpa = comp.gpa; |
| 1016 | // const writer = binary_bytes.writer(); | 1007 | // const writer = binary_bytes.writer(gpa); |
| 1017 | // const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 1008 | // const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 1018 | // | 1009 | // |
| 1019 | // // write custom section information | 1010 | // // write custom section information |
| ... | @@ -1052,8 +1043,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) | ... | @@ -1052,8 +1043,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 1052 | // var buf: [5]u8 = undefined; | 1043 | // var buf: [5]u8 = undefined; |
| 1053 | // leb.writeUnsignedFixed(5, &buf, count); | 1044 | // leb.writeUnsignedFixed(5, &buf, count); |
| 1054 | // try binary_bytes.insertSlice(reloc_start, &buf); | 1045 | // try binary_bytes.insertSlice(reloc_start, &buf); |
| 1055 | // const size = @as(u32, @intCast(binary_bytes.items.len - header_offset - 6)); | 1046 | // writeCustomSectionHeader(binary_bytes, header_offset); |
| 1056 | // try writeCustomSectionHeader(binary_bytes.items, header_offset, size); | | |
| 1057 | //} | 1047 | //} |
| 1058 | | 1048 | |
| 1059 | fn isBss(wasm: *Wasm, optional_name: Wasm.OptionalString) bool { | 1049 | fn isBss(wasm: *Wasm, optional_name: Wasm.OptionalString) bool { |
| ... | @@ -1104,6 +1094,21 @@ fn replaceVecSectionHeader( | ... | @@ -1104,6 +1094,21 @@ fn replaceVecSectionHeader( |
| 1104 | bytes.replaceRangeAssumeCapacity(offset, section_header_reserve_size, fbw.getWritten()); | 1094 | bytes.replaceRangeAssumeCapacity(offset, section_header_reserve_size, fbw.getWritten()); |
| 1105 | } | 1095 | } |
| 1106 | | 1096 | |
| | 1097 | fn reserveCustomSectionHeader(gpa: Allocator, bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!u32 { |
| | 1098 | try bytes.appendNTimes(gpa, 0, section_header_size); |
| | 1099 | return @intCast(bytes.items.len - section_header_size); |
| | 1100 | } |
| | 1101 | |
| | 1102 | fn writeCustomSectionHeader(bytes: *std.ArrayListUnmanaged(u8), offset: u32) void { |
| | 1103 | const size: u32 = @intCast(bytes.items.len - offset - section_header_size); |
| | 1104 | var buf: [section_header_size]u8 = undefined; |
| | 1105 | var fbw = std.io.fixedBufferStream(&buf); |
| | 1106 | const w = fbw.writer(); |
| | 1107 | w.writeByte(0) catch unreachable; // 0 = 'custom' section |
| | 1108 | leb.writeUleb128(w, size) catch unreachable; |
| | 1109 | bytes.replaceRangeAssumeCapacity(offset, section_header_size, fbw.getWritten()); |
| | 1110 | } |
| | 1111 | |
| 1107 | fn emitLimits( | 1112 | fn emitLimits( |
| 1108 | gpa: Allocator, | 1113 | gpa: Allocator, |
| 1109 | binary_bytes: *std.ArrayListUnmanaged(u8), | 1114 | binary_bytes: *std.ArrayListUnmanaged(u8), |
| ... | @@ -1171,7 +1176,7 @@ pub fn emitExpr(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), ex | ... | @@ -1171,7 +1176,7 @@ pub fn emitExpr(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), ex |
| 1171 | //) !void { | 1176 | //) !void { |
| 1172 | // const gpa = wasm.base.comp.gpa; | 1177 | // const gpa = wasm.base.comp.gpa; |
| 1173 | // const offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 1178 | // const offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 1174 | // const writer = binary_bytes.writer(); | 1179 | // const writer = binary_bytes.writer(gpa); |
| 1175 | // // emit "linking" custom section name | 1180 | // // emit "linking" custom section name |
| 1176 | // const section_name = "linking"; | 1181 | // const section_name = "linking"; |
| 1177 | // try leb.writeUleb128(writer, section_name.len); | 1182 | // try leb.writeUleb128(writer, section_name.len); |
| ... | @@ -1186,11 +1191,12 @@ pub fn emitExpr(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), ex | ... | @@ -1186,11 +1191,12 @@ pub fn emitExpr(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), ex |
| 1186 | // try wasm.emitSegmentInfo(binary_bytes); | 1191 | // try wasm.emitSegmentInfo(binary_bytes); |
| 1187 | // | 1192 | // |
| 1188 | // const size: u32 = @intCast(binary_bytes.items.len - offset - 6); | 1193 | // const size: u32 = @intCast(binary_bytes.items.len - offset - 6); |
| 1189 | // try writeCustomSectionHeader(binary_bytes.items, offset, size); | 1194 | // writeCustomSectionHeader(binary_bytes, offset, size); |
| 1190 | //} | 1195 | //} |
| 1191 | | 1196 | |
| 1192 | fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void { | 1197 | fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void { |
| 1193 | const writer = binary_bytes.writer(); | 1198 | const gpa = wasm.base.comp.gpa; |
| | 1199 | const writer = binary_bytes.writer(gpa); |
| 1194 | try leb.writeUleb128(writer, @intFromEnum(Wasm.SubsectionType.segment_info)); | 1200 | try leb.writeUleb128(writer, @intFromEnum(Wasm.SubsectionType.segment_info)); |
| 1195 | const segment_offset = binary_bytes.items.len; | 1201 | const segment_offset = binary_bytes.items.len; |
| 1196 | | 1202 | |
| ... | @@ -1370,7 +1376,7 @@ fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void { | ... | @@ -1370,7 +1376,7 @@ fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void { |
| 1370 | // .TABLE_INDEX_I64, | 1376 | // .TABLE_INDEX_I64, |
| 1371 | // .TABLE_INDEX_SLEB, | 1377 | // .TABLE_INDEX_SLEB, |
| 1372 | // .TABLE_INDEX_SLEB64, | 1378 | // .TABLE_INDEX_SLEB64, |
| 1373 | // => wasm.function_table.get(.{ .file = atom.file, .index = @enumFromInt(relocation.index) }) orelse 0, | 1379 | // => wasm.indirect_function_table.get(.{ .file = atom.file, .index = @enumFromInt(relocation.index) }) orelse 0, |
| 1374 | // | 1380 | // |
| 1375 | // .TYPE_INDEX_LEB => unreachable, // handled above | 1381 | // .TYPE_INDEX_LEB => unreachable, // handled above |
| 1376 | // .GLOBAL_INDEX_I32, .GLOBAL_INDEX_LEB => if (symbol.flags.undefined) | 1382 | // .GLOBAL_INDEX_I32, .GLOBAL_INDEX_LEB => if (symbol.flags.undefined) |