| ... | ... | @@ -59,7 +59,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 59 | 59 | const gpa = comp.gpa; |
| 60 | 60 | const import_memory = comp.config.import_memory; |
| 61 | 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 | 63 | const is_obj = comp.config.output_mode == .Obj; |
| 64 | 64 | const allow_undefined = is_obj or wasm.import_symbols; |
| 65 | 65 | const zcu = wasm.base.comp.zcu.?; |
| ... | ... | @@ -523,7 +523,7 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 523 | 523 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); |
| 524 | 524 | try binary_bytes.appendSlice(gpa, name); |
| 525 | 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 | 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 | 543 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len))); |
| 544 | 544 | try binary_bytes.appendSlice(gpa, name); |
| 545 | 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 | 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 | 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 | 559 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 560 | 560 | replaceVecSectionHeader(binary_bytes, header_offset, .start, @intFromEnum(entry_index)); |
| 561 | 561 | } |
| 562 | 562 | |
| 563 | 563 | // element section (function table) |
| 564 | | if (wasm.function_table.count() > 0) { |
| 565 | | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 564 | if (f.indirect_function_table.count() > 0) { |
| 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_sym = wasm.finalSymbolByLoc(table_loc); |
| 568 | //const table_loc = wasm.globals.get(wasm.preloaded_strings.__indirect_function_table).?; |
| 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 | | try leb.writeUleb128(binary_writer, flags); |
| 572 | | if (flags == 0x02) { |
| 573 | | try leb.writeUleb128(binary_writer, table_sym.index); |
| 574 | | } |
| 575 | | try emitInit(binary_writer, .{ .i32_const = 1 }); // We start at index 1, so unresolved function pointers are invalid |
| 576 | | if (flags == 0x02) { |
| 577 | | try leb.writeUleb128(binary_writer, @as(u8, 0)); // represents funcref |
| 578 | | } |
| 579 | | try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.function_table.count()))); |
| 580 | | var symbol_it = wasm.function_table.keyIterator(); |
| 581 | | while (symbol_it.next()) |symbol_loc_ptr| { |
| 582 | | const sym = wasm.finalSymbolByLoc(symbol_loc_ptr.*); |
| 583 | | assert(sym.flags.alive); |
| 584 | | assert(sym.index < wasm.functions.count() + wasm.imported_functions_count); |
| 585 | | try leb.writeUleb128(binary_writer, sym.index); |
| 586 | | } |
| 571 | //const flags: u32 = if (table_sym.index == 0) 0x0 else 0x02; // passive with implicit 0-index table or set table index manually |
| 572 | //try leb.writeUleb128(binary_writer, flags); |
| 573 | //if (flags == 0x02) { |
| 574 | // try leb.writeUleb128(binary_writer, table_sym.index); |
| 575 | //} |
| 576 | //try emitInit(binary_writer, .{ .i32_const = 1 }); // We start at index 1, so unresolved function pointers are invalid |
| 577 | //if (flags == 0x02) { |
| 578 | // try leb.writeUleb128(binary_writer, @as(u8, 0)); // represents funcref |
| 579 | //} |
| 580 | //try leb.writeUleb128(binary_writer, @as(u32, @intCast(f.indirect_function_table.count()))); |
| 581 | //var symbol_it = f.indirect_function_table.keyIterator(); |
| 582 | //while (symbol_it.next()) |symbol_loc_ptr| { |
| 583 | // const sym = wasm.finalSymbolByLoc(symbol_loc_ptr.*); |
| 584 | // assert(sym.flags.alive); |
| 585 | // assert(sym.index < wasm.functions.count() + wasm.imported_functions_count); |
| 586 | // try leb.writeUleb128(binary_writer, sym.index); |
| 587 | //} |
| 587 | 588 | |
| 588 | | replaceVecSectionHeader(binary_bytes, header_offset, .element, 1); |
| 589 | | section_index += 1; |
| 589 | //replaceVecSectionHeader(binary_bytes, header_offset, .element, 1); |
| 590 | //section_index += 1; |
| 590 | 591 | } |
| 591 | 592 | |
| 592 | 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 | 601 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 601 | 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 | 605 | .unresolved => unreachable, |
| 605 | 606 | .__wasm_apply_global_tls_relocs => @panic("TODO lower __wasm_apply_global_tls_relocs"), |
| 606 | 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 | 615 | //try leb.writeUleb128(binary_writer, atom.code.len); |
| 615 | 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 | 628 | _ = i; |
| 619 | 629 | _ = start_offset; |
| 620 | | @panic("TODO lower nav code and apply relocations"); |
| 630 | @panic("TODO lower nav obj code and apply relocations"); |
| 621 | 631 | //try leb.writeUleb128(binary_writer, atom.code.len); |
| 622 | 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 | 646 | var offset: u32 = undefined; |
| 637 | 647 | for (segment_indexes, segment_offsets) |segment_index, segment_offset| { |
| 638 | 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 | 651 | if (!import_memory and isBss(wasm, segment.name)) { |
| 641 | 652 | // It counted for virtual memory but it does not go into the binary. |
| 642 | 653 | continue; |
| ... | ... | @@ -657,8 +668,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 657 | 668 | |
| 658 | 669 | try binary_bytes.appendNTimes(gpa, 0, segment_offset - offset); |
| 659 | 670 | offset = segment_offset; |
| 660 | | try binary_bytes.appendSlice(gpa, segment.payload.slice(wasm)); |
| 661 | | offset += segment.payload.len; |
| 671 | try binary_bytes.appendSlice(gpa, segment_payload); |
| 672 | offset += @intCast(segment_payload.len); |
| 662 | 673 | if (true) @panic("TODO apply data segment relocations"); |
| 663 | 674 | } |
| 664 | 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 | 691 | // try wasm.emitDataRelocations(binary_bytes, data_index, symbol_table); |
| 681 | 692 | //} |
| 682 | 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 | 697 | if (comp.config.debug_format != .strip) { |
| ... | ... | @@ -699,14 +710,14 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 699 | 710 | std.fmt.fmtSliceHexLower(id[8..10]), |
| 700 | 711 | std.fmt.fmtSliceHexLower(id[10..]), |
| 701 | 712 | }); |
| 702 | | try emitBuildIdSection(binary_bytes, &uuid); |
| 713 | try emitBuildIdSection(gpa, binary_bytes, &uuid); |
| 703 | 714 | }, |
| 704 | 715 | .hexstring => |hs| { |
| 705 | 716 | var buffer: [32 * 2]u8 = undefined; |
| 706 | 717 | const str = std.fmt.bufPrint(&buffer, "{s}", .{ |
| 707 | 718 | std.fmt.fmtSliceHexLower(hs.toSlice()), |
| 708 | 719 | }) catch unreachable; |
| 709 | | try emitBuildIdSection(binary_bytes, str); |
| 720 | try emitBuildIdSection(gpa, binary_bytes, str); |
| 710 | 721 | }, |
| 711 | 722 | else => |mode| { |
| 712 | 723 | var err = try diags.addErrorWithNotes(0); |
| ... | ... | @@ -717,9 +728,8 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 717 | 728 | var debug_bytes = std.ArrayList(u8).init(gpa); |
| 718 | 729 | defer debug_bytes.deinit(); |
| 719 | 730 | |
| 720 | | try emitProducerSection(binary_bytes); |
| 721 | | if (!target.cpu.features.isEmpty()) |
| 722 | | try emitFeaturesSection(binary_bytes, target.cpu.features); |
| 731 | try emitProducerSection(gpa, binary_bytes); |
| 732 | try emitFeaturesSection(gpa, binary_bytes, target); |
| 723 | 733 | } |
| 724 | 734 | |
| 725 | 735 | // Finally, write the entire binary into the file. |
| ... | ... | @@ -729,6 +739,10 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) !void { |
| 729 | 739 | } |
| 730 | 740 | |
| 731 | 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 | 746 | const comp = wasm.base.comp; |
| 733 | 747 | const gpa = comp.gpa; |
| 734 | 748 | const import_memory = comp.config.import_memory; |
| ... | ... | @@ -796,31 +810,15 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), arena |
| 796 | 810 | // Data segments are already ordered. |
| 797 | 811 | |
| 798 | 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 | 816 | try leb.writeUleb128(writer, @as(u32, @intCast("name".len))); |
| 801 | 817 | try writer.writeAll("name"); |
| 802 | 818 | |
| 803 | 819 | try emitNameSubsection(wasm, binary_bytes, .function, funcs.keys(), funcs.values()); |
| 804 | 820 | try emitNameSubsection(wasm, binary_bytes, .global, globals.items(.index), globals.items(.name)); |
| 805 | 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 | 824 | fn emitNameSubsection( |
| ... | ... | @@ -856,35 +854,40 @@ fn emitNameSubsection( |
| 856 | 854 | fn emitFeaturesSection( |
| 857 | 855 | gpa: Allocator, |
| 858 | 856 | binary_bytes: *std.ArrayListUnmanaged(u8), |
| 859 | | features: []const Wasm.Feature, |
| 860 | | ) !void { |
| 857 | target: *const std.Target, |
| 858 | ) Allocator.Error!void { |
| 859 | const feature_count = target.cpu.features.count(); |
| 860 | if (feature_count == 0) return; |
| 861 | |
| 861 | 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 | 866 | const target_features = "target_features"; |
| 865 | 867 | try leb.writeUleb128(writer, @as(u32, @intCast(target_features.len))); |
| 866 | 868 | try writer.writeAll(target_features); |
| 867 | 869 | |
| 868 | | try leb.writeUleb128(writer, @as(u32, @intCast(features.len))); |
| 869 | | for (features) |feature| { |
| 870 | | assert(feature.prefix != .invalid); |
| 871 | | try leb.writeUleb128(writer, @tagName(feature.prefix)[0]); |
| 872 | | const name = @tagName(feature.tag); |
| 873 | | try leb.writeUleb128(writer, @as(u32, name.len)); |
| 870 | try leb.writeUleb128(writer, @as(u32, @intCast(feature_count))); |
| 871 | |
| 872 | var safety_count = feature_count; |
| 873 | for (target.cpu.arch.allFeaturesList(), 0..) |*feature, i| { |
| 874 | if (!std.Target.wasm.featureSetHas(target.cpu.features, @enumFromInt(i))) continue; |
| 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 | 881 | try writer.writeAll(name); |
| 875 | 882 | } |
| 876 | | |
| 877 | | try writeCustomSectionHeader( |
| 878 | | binary_bytes.items, |
| 879 | | header_offset, |
| 880 | | @as(u32, @intCast(binary_bytes.items.len - header_offset - 6)), |
| 881 | | ); |
| 883 | assert(safety_count == 0); |
| 882 | 884 | } |
| 883 | 885 | |
| 884 | 886 | fn emitBuildIdSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8), build_id: []const u8) !void { |
| 885 | 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 | 891 | const hdr_build_id = "build_id"; |
| 889 | 892 | try leb.writeUleb128(writer, @as(u32, @intCast(hdr_build_id.len))); |
| 890 | 893 | try writer.writeAll(hdr_build_id); |
| ... | ... | @@ -892,18 +895,13 @@ fn emitBuildIdSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8), |
| 892 | 895 | try leb.writeUleb128(writer, @as(u32, 1)); |
| 893 | 896 | try leb.writeUleb128(writer, @as(u32, @intCast(build_id.len))); |
| 894 | 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 | 900 | fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8)) !void { |
| 904 | 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 | 905 | const producers = "producers"; |
| 908 | 906 | try leb.writeUleb128(writer, @as(u32, @intCast(producers.len))); |
| 909 | 907 | try writer.writeAll(producers); |
| ... | ... | @@ -947,12 +945,6 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 947 | 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 | 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 | 957 | // const comp = wasm.base.comp; |
| 966 | 958 | // const gpa = comp.gpa; |
| 967 | 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 | 961 | // const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 970 | 962 | // |
| 971 | 963 | // // write custom section information |
| ... | ... | @@ -1001,8 +993,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 1001 | 993 | // var buf: [5]u8 = undefined; |
| 1002 | 994 | // leb.writeUnsignedFixed(5, &buf, count); |
| 1003 | 995 | // try binary_bytes.insertSlice(reloc_start, &buf); |
| 1004 | | // const size: u32 = @intCast(binary_bytes.items.len - header_offset - 6); |
| 1005 | | // try writeCustomSectionHeader(binary_bytes.items, header_offset, size); |
| 996 | // writeCustomSectionHeader(binary_bytes, header_offset); |
| 1006 | 997 | //} |
| 1007 | 998 | |
| 1008 | 999 | //fn emitDataRelocations( |
| ... | ... | @@ -1013,7 +1004,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 1013 | 1004 | //) !void { |
| 1014 | 1005 | // const comp = wasm.base.comp; |
| 1015 | 1006 | // const gpa = comp.gpa; |
| 1016 | | // const writer = binary_bytes.writer(); |
| 1007 | // const writer = binary_bytes.writer(gpa); |
| 1017 | 1008 | // const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 1018 | 1009 | // |
| 1019 | 1010 | // // write custom section information |
| ... | ... | @@ -1052,8 +1043,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 1052 | 1043 | // var buf: [5]u8 = undefined; |
| 1053 | 1044 | // leb.writeUnsignedFixed(5, &buf, count); |
| 1054 | 1045 | // try binary_bytes.insertSlice(reloc_start, &buf); |
| 1055 | | // const size = @as(u32, @intCast(binary_bytes.items.len - header_offset - 6)); |
| 1056 | | // try writeCustomSectionHeader(binary_bytes.items, header_offset, size); |
| 1046 | // writeCustomSectionHeader(binary_bytes, header_offset); |
| 1057 | 1047 | //} |
| 1058 | 1048 | |
| 1059 | 1049 | fn isBss(wasm: *Wasm, optional_name: Wasm.OptionalString) bool { |
| ... | ... | @@ -1104,6 +1094,21 @@ fn replaceVecSectionHeader( |
| 1104 | 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 | 1112 | fn emitLimits( |
| 1108 | 1113 | gpa: Allocator, |
| 1109 | 1114 | binary_bytes: *std.ArrayListUnmanaged(u8), |
| ... | ... | @@ -1171,7 +1176,7 @@ pub fn emitExpr(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), ex |
| 1171 | 1176 | //) !void { |
| 1172 | 1177 | // const gpa = wasm.base.comp.gpa; |
| 1173 | 1178 | // const offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 1174 | | // const writer = binary_bytes.writer(); |
| 1179 | // const writer = binary_bytes.writer(gpa); |
| 1175 | 1180 | // // emit "linking" custom section name |
| 1176 | 1181 | // const section_name = "linking"; |
| 1177 | 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 | 1191 | // try wasm.emitSegmentInfo(binary_bytes); |
| 1187 | 1192 | // |
| 1188 | 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 | 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 | 1200 | try leb.writeUleb128(writer, @intFromEnum(Wasm.SubsectionType.segment_info)); |
| 1195 | 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 | 1376 | // .TABLE_INDEX_I64, |
| 1371 | 1377 | // .TABLE_INDEX_SLEB, |
| 1372 | 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 | 1381 | // .TYPE_INDEX_LEB => unreachable, // handled above |
| 1376 | 1382 | // .GLOBAL_INDEX_I32, .GLOBAL_INDEX_LEB => if (symbol.flags.undefined) |