authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-23 18:18:54-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:36-08:00
log1a4c5837fedcad57f6c81301672e6246e0f0a8c1
tree97b7b1b10d130d96cb93d7b28c88ad00971e0e1d
parent4b9dc2922ff0c5d873971f6f6f25db709df21cc0

wasm linker: fix crashes when parsing compiler_rt


10 files changed, 514 insertions(+), 369 deletions(-)

src/link.zig+3-6
......@@ -97,15 +97,12 @@ pub const Diags = struct {
9797 err_msg.msg = try std.fmt.allocPrint(gpa, format, args);
9898 }
9999
100 pub fn addNote(
101 err: *ErrorWithNotes,
102 comptime format: []const u8,
103 args: anytype,
104 ) error{OutOfMemory}!void {
100 pub fn addNote(err: *ErrorWithNotes, comptime format: []const u8, args: anytype) void {
105101 const gpa = err.diags.gpa;
102 const msg = std.fmt.allocPrint(gpa, format, args) catch return err.diags.setAllocFailure();
106103 const err_msg = &err.diags.msgs.items[err.index];
107104 assert(err.note_slot < err_msg.notes.len);
108 err_msg.notes[err.note_slot] = .{ .msg = try std.fmt.allocPrint(gpa, format, args) };
105 err_msg.notes[err.note_slot] = .{ .msg = msg };
109106 err.note_slot += 1;
110107 }
111108 };
src/link/Elf.zig+7-7
......@@ -3394,7 +3394,7 @@ fn allocatePhdrTable(self: *Elf) error{OutOfMemory}!void {
33943394 // TODO verify `getMaxNumberOfPhdrs()` is accurate and convert this into no-op
33953395 var err = try diags.addErrorWithNotes(1);
33963396 try err.addMsg("fatal linker error: not enough space reserved for EHDR and PHDR table", .{});
3397 try err.addNote("required 0x{x}, available 0x{x}", .{ needed_size, available_space });
3397 err.addNote("required 0x{x}, available 0x{x}", .{ needed_size, available_space });
33983398 }
33993399
34003400 phdr_table_load.p_filesz = needed_size + ehsize;
......@@ -4545,12 +4545,12 @@ fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {
45454545 for (refs.items[0..nrefs]) |ref| {
45464546 const atom_ptr = self.atom(ref).?;
45474547 const file_ptr = atom_ptr.file(self).?;
4548 try err.addNote("referenced by {s}:{s}", .{ file_ptr.fmtPath(), atom_ptr.name(self) });
4548 err.addNote("referenced by {s}:{s}", .{ file_ptr.fmtPath(), atom_ptr.name(self) });
45494549 }
45504550
45514551 if (refs.items.len > max_notes) {
45524552 const remaining = refs.items.len - max_notes;
4553 try err.addNote("referenced {d} more times", .{remaining});
4553 err.addNote("referenced {d} more times", .{remaining});
45544554 }
45554555 }
45564556}
......@@ -4567,17 +4567,17 @@ fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemor
45674567
45684568 var err = try diags.addErrorWithNotes(nnotes + 1);
45694569 try err.addMsg("duplicate symbol definition: {s}", .{sym.name(self)});
4570 try err.addNote("defined by {}", .{sym.file(self).?.fmtPath()});
4570 err.addNote("defined by {}", .{sym.file(self).?.fmtPath()});
45714571
45724572 var inote: usize = 0;
45734573 while (inote < @min(notes.items.len, max_notes)) : (inote += 1) {
45744574 const file_ptr = self.file(notes.items[inote]).?;
4575 try err.addNote("defined by {}", .{file_ptr.fmtPath()});
4575 err.addNote("defined by {}", .{file_ptr.fmtPath()});
45764576 }
45774577
45784578 if (notes.items.len > max_notes) {
45794579 const remaining = notes.items.len - max_notes;
4580 try err.addNote("defined {d} more times", .{remaining});
4580 err.addNote("defined {d} more times", .{remaining});
45814581 }
45824582 }
45834583
......@@ -4601,7 +4601,7 @@ pub fn addFileError(
46014601 const diags = &self.base.comp.link_diags;
46024602 var err = try diags.addErrorWithNotes(1);
46034603 try err.addMsg(format, args);
4604 try err.addNote("while parsing {}", .{self.file(file_index).?.fmtPath()});
4604 err.addNote("while parsing {}", .{self.file(file_index).?.fmtPath()});
46054605}
46064606
46074607pub fn failFile(
src/link/Elf/Atom.zig+12-12
......@@ -523,7 +523,7 @@ fn reportUnhandledRelocError(self: Atom, rel: elf.Elf64_Rela, elf_file: *Elf) Re
523523 relocation.fmtRelocType(rel.r_type(), elf_file.getTarget().cpu.arch),
524524 rel.r_offset,
525525 });
526 try err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
526 err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
527527 return error.RelocFailure;
528528}
529529
......@@ -539,7 +539,7 @@ fn reportTextRelocError(
539539 rel.r_offset,
540540 symbol.name(elf_file),
541541 });
542 try err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
542 err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
543543 return error.RelocFailure;
544544}
545545
......@@ -555,8 +555,8 @@ fn reportPicError(
555555 rel.r_offset,
556556 symbol.name(elf_file),
557557 });
558 try err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
559 try err.addNote("recompile with -fPIC", .{});
558 err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
559 err.addNote("recompile with -fPIC", .{});
560560 return error.RelocFailure;
561561}
562562
......@@ -572,8 +572,8 @@ fn reportNoPicError(
572572 rel.r_offset,
573573 symbol.name(elf_file),
574574 });
575 try err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
576 try err.addNote("recompile with -fno-PIC", .{});
575 err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
576 err.addNote("recompile with -fno-PIC", .{});
577577 return error.RelocFailure;
578578}
579579
......@@ -1187,7 +1187,7 @@ const x86_64 = struct {
11871187 x86_64.relaxGotPcTlsDesc(code[r_offset - 3 ..]) catch {
11881188 var err = try diags.addErrorWithNotes(1);
11891189 try err.addMsg("could not relax {s}", .{@tagName(r_type)});
1190 try err.addNote("in {}:{s} at offset 0x{x}", .{
1190 err.addNote("in {}:{s} at offset 0x{x}", .{
11911191 atom.file(elf_file).?.fmtPath(),
11921192 atom.name(elf_file),
11931193 rel.r_offset,
......@@ -1332,7 +1332,7 @@ const x86_64 = struct {
13321332 relocation.fmtRelocType(rels[0].r_type(), .x86_64),
13331333 relocation.fmtRelocType(rels[1].r_type(), .x86_64),
13341334 });
1335 try err.addNote("in {}:{s} at offset 0x{x}", .{
1335 err.addNote("in {}:{s} at offset 0x{x}", .{
13361336 self.file(elf_file).?.fmtPath(),
13371337 self.name(elf_file),
13381338 rels[0].r_offset,
......@@ -1388,7 +1388,7 @@ const x86_64 = struct {
13881388 relocation.fmtRelocType(rels[0].r_type(), .x86_64),
13891389 relocation.fmtRelocType(rels[1].r_type(), .x86_64),
13901390 });
1391 try err.addNote("in {}:{s} at offset 0x{x}", .{
1391 err.addNote("in {}:{s} at offset 0x{x}", .{
13921392 self.file(elf_file).?.fmtPath(),
13931393 self.name(elf_file),
13941394 rels[0].r_offset,
......@@ -1485,7 +1485,7 @@ const x86_64 = struct {
14851485 relocation.fmtRelocType(rels[0].r_type(), .x86_64),
14861486 relocation.fmtRelocType(rels[1].r_type(), .x86_64),
14871487 });
1488 try err.addNote("in {}:{s} at offset 0x{x}", .{
1488 err.addNote("in {}:{s} at offset 0x{x}", .{
14891489 self.file(elf_file).?.fmtPath(),
14901490 self.name(elf_file),
14911491 rels[0].r_offset,
......@@ -1672,7 +1672,7 @@ const aarch64 = struct {
16721672 // TODO: relax
16731673 var err = try diags.addErrorWithNotes(1);
16741674 try err.addMsg("TODO: relax ADR_GOT_PAGE", .{});
1675 try err.addNote("in {}:{s} at offset 0x{x}", .{
1675 err.addNote("in {}:{s} at offset 0x{x}", .{
16761676 atom.file(elf_file).?.fmtPath(),
16771677 atom.name(elf_file),
16781678 r_offset,
......@@ -1959,7 +1959,7 @@ const riscv = struct {
19591959 // TODO: implement searching forward
19601960 var err = try diags.addErrorWithNotes(1);
19611961 try err.addMsg("TODO: find HI20 paired reloc scanning forward", .{});
1962 try err.addNote("in {}:{s} at offset 0x{x}", .{
1962 err.addNote("in {}:{s} at offset 0x{x}", .{
19631963 atom.file(elf_file).?.fmtPath(),
19641964 atom.name(elf_file),
19651965 rel.r_offset,
src/link/Elf/Object.zig+5-5
......@@ -797,7 +797,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void {
797797 if (!isNull(data[end .. end + sh_entsize])) {
798798 var err = try diags.addErrorWithNotes(1);
799799 try err.addMsg("string not null terminated", .{});
800 try err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
800 err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
801801 return error.LinkFailure;
802802 }
803803 end += sh_entsize;
......@@ -812,7 +812,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void {
812812 if (shdr.sh_size % sh_entsize != 0) {
813813 var err = try diags.addErrorWithNotes(1);
814814 try err.addMsg("size not a multiple of sh_entsize", .{});
815 try err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
815 err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
816816 return error.LinkFailure;
817817 }
818818
......@@ -889,8 +889,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{
889889 const res = imsec.findSubsection(@intCast(esym.st_value)) orelse {
890890 var err = try diags.addErrorWithNotes(2);
891891 try err.addMsg("invalid symbol value: {x}", .{esym.st_value});
892 try err.addNote("for symbol {s}", .{sym.name(elf_file)});
893 try err.addNote("in {}", .{self.fmtPath()});
892 err.addNote("for symbol {s}", .{sym.name(elf_file)});
893 err.addNote("in {}", .{self.fmtPath()});
894894 return error.LinkFailure;
895895 };
896896
......@@ -915,7 +915,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{
915915 const res = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse {
916916 var err = try diags.addErrorWithNotes(1);
917917 try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset});
918 try err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
918 err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
919919 return error.LinkFailure;
920920 };
921921
src/link/Elf/eh_frame.zig+1-1
......@@ -611,7 +611,7 @@ fn reportInvalidReloc(rec: anytype, elf_file: *Elf, rel: elf.Elf64_Rela) !void {
611611 relocation.fmtRelocType(rel.r_type(), elf_file.getTarget().cpu.arch),
612612 rel.r_offset,
613613 });
614 try err.addNote("in {}:.eh_frame", .{elf_file.file(rec.file_index).?.fmtPath()});
614 err.addNote("in {}:.eh_frame", .{elf_file.file(rec.file_index).?.fmtPath()});
615615 return error.RelocFailure;
616616}
617617
src/link/MachO.zig+16-16
......@@ -1572,21 +1572,21 @@ fn reportUndefs(self: *MachO) !void {
15721572 try err.addMsg("undefined symbol: {s}", .{undef_sym.getName(self)});
15731573
15741574 switch (notes) {
1575 .force_undefined => try err.addNote("referenced with linker flag -u", .{}),
1576 .entry => try err.addNote("referenced with linker flag -e", .{}),
1577 .dyld_stub_binder, .objc_msgsend => try err.addNote("referenced implicitly", .{}),
1575 .force_undefined => err.addNote("referenced with linker flag -u", .{}),
1576 .entry => err.addNote("referenced with linker flag -e", .{}),
1577 .dyld_stub_binder, .objc_msgsend => err.addNote("referenced implicitly", .{}),
15781578 .refs => |refs| {
15791579 var inote: usize = 0;
15801580 while (inote < @min(refs.items.len, max_notes)) : (inote += 1) {
15811581 const ref = refs.items[inote];
15821582 const file = self.getFile(ref.file).?;
15831583 const atom = ref.getAtom(self).?;
1584 try err.addNote("referenced by {}:{s}", .{ file.fmtPath(), atom.getName(self) });
1584 err.addNote("referenced by {}:{s}", .{ file.fmtPath(), atom.getName(self) });
15851585 }
15861586
15871587 if (refs.items.len > max_notes) {
15881588 const remaining = refs.items.len - max_notes;
1589 try err.addNote("referenced {d} more times", .{remaining});
1589 err.addNote("referenced {d} more times", .{remaining});
15901590 }
15911591 },
15921592 }
......@@ -3473,8 +3473,8 @@ fn growSectionNonRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !vo
34733473 seg_id,
34743474 seg.segName(),
34753475 });
3476 try err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{});
3477 try err.addNote("as a workaround, try increasing pre-allocated virtual memory of each segment", .{});
3476 err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{});
3477 err.addNote("as a workaround, try increasing pre-allocated virtual memory of each segment", .{});
34783478 }
34793479
34803480 seg.vmsize = needed_size;
......@@ -3776,7 +3776,7 @@ pub fn reportParseError2(
37763776 const diags = &self.base.comp.link_diags;
37773777 var err = try diags.addErrorWithNotes(1);
37783778 try err.addMsg(format, args);
3779 try err.addNote("while parsing {}", .{self.getFile(file_index).?.fmtPath()});
3779 err.addNote("while parsing {}", .{self.getFile(file_index).?.fmtPath()});
37803780}
37813781
37823782fn reportMissingDependencyError(
......@@ -3790,10 +3790,10 @@ fn reportMissingDependencyError(
37903790 const diags = &self.base.comp.link_diags;
37913791 var err = try diags.addErrorWithNotes(2 + checked_paths.len);
37923792 try err.addMsg(format, args);
3793 try err.addNote("while resolving {s}", .{path});
3794 try err.addNote("a dependency of {}", .{self.getFile(parent).?.fmtPath()});
3793 err.addNote("while resolving {s}", .{path});
3794 err.addNote("a dependency of {}", .{self.getFile(parent).?.fmtPath()});
37953795 for (checked_paths) |p| {
3796 try err.addNote("tried {s}", .{p});
3796 err.addNote("tried {s}", .{p});
37973797 }
37983798}
37993799
......@@ -3807,8 +3807,8 @@ fn reportDependencyError(
38073807 const diags = &self.base.comp.link_diags;
38083808 var err = try diags.addErrorWithNotes(2);
38093809 try err.addMsg(format, args);
3810 try err.addNote("while parsing {s}", .{path});
3811 try err.addNote("a dependency of {}", .{self.getFile(parent).?.fmtPath()});
3810 err.addNote("while parsing {s}", .{path});
3811 err.addNote("a dependency of {}", .{self.getFile(parent).?.fmtPath()});
38123812}
38133813
38143814fn reportDuplicates(self: *MachO) error{ HasDuplicates, OutOfMemory }!void {
......@@ -3838,17 +3838,17 @@ fn reportDuplicates(self: *MachO) error{ HasDuplicates, OutOfMemory }!void {
38383838
38393839 var err = try diags.addErrorWithNotes(nnotes + 1);
38403840 try err.addMsg("duplicate symbol definition: {s}", .{sym.getName(self)});
3841 try err.addNote("defined by {}", .{sym.getFile(self).?.fmtPath()});
3841 err.addNote("defined by {}", .{sym.getFile(self).?.fmtPath()});
38423842
38433843 var inote: usize = 0;
38443844 while (inote < @min(notes.items.len, max_notes)) : (inote += 1) {
38453845 const file = self.getFile(notes.items[inote]).?;
3846 try err.addNote("defined by {}", .{file.fmtPath()});
3846 err.addNote("defined by {}", .{file.fmtPath()});
38473847 }
38483848
38493849 if (notes.items.len > max_notes) {
38503850 const remaining = notes.items.len - max_notes;
3851 try err.addNote("defined {d} more times", .{remaining});
3851 err.addNote("defined {d} more times", .{remaining});
38523852 }
38533853 }
38543854 return error.HasDuplicates;
src/link/MachO/Atom.zig+2-2
......@@ -909,8 +909,8 @@ const x86_64 = struct {
909909 rel.offset,
910910 rel.fmtPretty(.x86_64),
911911 });
912 try err.addNote("expected .mov instruction but found .{s}", .{@tagName(x)});
913 try err.addNote("while parsing {}", .{self.getFile(macho_file).fmtPath()});
912 err.addNote("expected .mov instruction but found .{s}", .{@tagName(x)});
913 err.addNote("while parsing {}", .{self.getFile(macho_file).fmtPath()});
914914 return error.RelaxFailUnexpectedInstruction;
915915 },
916916 }
src/link/Wasm.zig+351-229
......@@ -109,7 +109,7 @@ object_tables: std.ArrayListUnmanaged(Table) = .empty,
109109/// All memory imports for all objects.
110110object_memory_imports: std.ArrayListUnmanaged(MemoryImport) = .empty,
111111/// All parsed memory sections for all objects.
112object_memories: std.ArrayListUnmanaged(std.wasm.Memory) = .empty,
112object_memories: std.ArrayListUnmanaged(ObjectMemory) = .empty,
113113
114114/// All relocations from all objects concatenated. `relocs_start` marks the end
115115/// point of object relocations and start point of Zcu relocations.
......@@ -119,8 +119,13 @@ object_relocations: std.MultiArrayList(ObjectRelocation) = .empty,
119119/// by the (synthetic) __wasm_call_ctors function.
120120object_init_funcs: std.ArrayListUnmanaged(InitFunc) = .empty,
121121
122/// Non-synthetic section that can essentially be mem-cpy'd into place after performing relocations.
123object_data_segments: std.ArrayListUnmanaged(DataSegment) = .empty,
122/// The data section of an object has many segments. Each segment corresponds
123/// logically to an object file's .data section, or .rodata section. In
124/// the case of `-fdata-sections` there will be one segment per data symbol.
125object_data_segments: std.ArrayListUnmanaged(ObjectDataSegment) = .empty,
126/// Each segment has many data symbols. These correspond logically to global
127/// constants.
128object_datas: std.ArrayListUnmanaged(ObjectData) = .empty,
124129/// Non-synthetic section that can essentially be mem-cpy'd into place after performing relocations.
125130object_custom_segments: std.AutoArrayHashMapUnmanaged(ObjectSectionIndex, CustomSegment) = .empty,
126131
......@@ -457,6 +462,21 @@ pub const SourceLocation = enum(u32) {
457462 .source_location_index => @panic("TODO"),
458463 }
459464 }
465
466 pub fn addNote(
467 sl: SourceLocation,
468 wasm: *Wasm,
469 err: *link.Diags.ErrorWithNotes,
470 comptime f: []const u8,
471 args: anytype,
472 ) void {
473 switch (sl.unpack(wasm)) {
474 .none => err.addNote(f, args),
475 .zig_object_nofile => err.addNote("zig compilation unit: " ++ f, args),
476 .object_index => |i| err.addNote("{}: " ++ f, .{i.ptr(wasm).path} ++ args),
477 .source_location_index => @panic("TODO"),
478 }
479 }
460480};
461481
462482/// The lower bits of this ABI-match the flags here:
......@@ -687,13 +707,13 @@ pub const UavsExeIndex = enum(u32) {
687707
688708/// Used when emitting a relocatable object.
689709pub const ZcuDataObj = extern struct {
690 code: DataSegment.Payload,
710 code: DataPayload,
691711 relocs: OutReloc.Slice,
692712};
693713
694714/// Used when not emitting a relocatable object.
695715pub const ZcuDataExe = extern struct {
696 code: DataSegment.Payload,
716 code: DataPayload,
697717 /// Tracks how many references there are for the purposes of sorting data segments.
698718 count: u32,
699719};
......@@ -917,6 +937,10 @@ pub const FunctionImport = extern struct {
917937 return pack(wasm, .{ .zcu_func = @enumFromInt(wasm.zcu_funcs.getIndex(ip_index).?) });
918938 }
919939
940 pub fn fromObjectFunction(wasm: *const Wasm, object_function: ObjectFunctionIndex) Resolution {
941 return pack(wasm, .{ .object_function = object_function });
942 }
943
920944 pub fn isNavOrUnresolved(r: Resolution, wasm: *const Wasm) bool {
921945 return switch (r.unpack(wasm)) {
922946 .unresolved, .zcu_func => true,
......@@ -988,7 +1012,7 @@ pub const Function = extern struct {
9881012 section_index: ObjectSectionIndex,
9891013 source_location: SourceLocation,
9901014
991 pub const Code = DataSegment.Payload;
1015 pub const Code = DataPayload;
9921016};
9931017
9941018pub const GlobalImport = extern struct {
......@@ -1283,12 +1307,30 @@ pub const ObjectGlobalIndex = enum(u32) {
12831307 }
12841308};
12851309
1286/// Index into `Wasm.object_memories`.
1287pub const ObjectMemoryIndex = enum(u32) {
1288 _,
1310pub const ObjectMemory = extern struct {
1311 flags: SymbolFlags,
1312 name: OptionalString,
1313 limits_min: u32,
1314 limits_max: u32,
12891315
1290 pub fn ptr(index: ObjectMemoryIndex, wasm: *const Wasm) *std.wasm.Memory {
1291 return &wasm.object_memories.items[@intFromEnum(index)];
1316 /// Index into `Wasm.object_memories`.
1317 pub const Index = enum(u32) {
1318 _,
1319
1320 pub fn ptr(index: Index, wasm: *const Wasm) *ObjectMemory {
1321 return &wasm.object_memories.items[@intFromEnum(index)];
1322 }
1323 };
1324
1325 pub fn limits(om: *const ObjectMemory) std.wasm.Limits {
1326 return .{
1327 .flags = .{
1328 .has_max = om.limits_has_max,
1329 .is_shared = om.limits_is_shared,
1330 },
1331 .min = om.limits_min,
1332 .max = om.limits_max,
1333 };
12921334 }
12931335};
12941336
......@@ -1318,14 +1360,74 @@ pub const OptionalObjectFunctionIndex = enum(u32) {
13181360 }
13191361};
13201362
1321pub const DataSegment = extern struct {
1363pub const ObjectDataSegment = extern struct {
1364 /// `none` if segment info custom subsection is missing.
1365 name: OptionalString,
1366 flags: SymbolFlags,
1367 payload: DataPayload,
1368
1369 /// Index into `Wasm.object_data_segments`.
1370 pub const Index = enum(u32) {
1371 _,
1372
1373 pub fn ptr(i: Index, wasm: *const Wasm) *ObjectDataSegment {
1374 return &wasm.object_data_segments.items[@intFromEnum(i)];
1375 }
1376 };
1377};
1378
1379/// A local or exported global const from an object file.
1380pub const ObjectData = extern struct {
1381 segment: ObjectDataSegment.Index,
1382 /// Index into the object segment payload. Must be <= the segment's size.
1383 offset: u32,
1384 /// May be zero. `offset + size` must be <= the segment's size.
1385 size: u32,
13221386 /// `none` if no symbol describes it.
13231387 name: OptionalString,
13241388 flags: SymbolFlags,
1325 payload: Payload,
1326 /// From the data segment start to the first byte of payload.
1327 segment_offset: u32,
1328 section_index: ObjectSectionIndex,
1389
1390 /// Index into `Wasm.object_datas`.
1391 pub const Index = enum(u32) {
1392 _,
1393
1394 pub fn ptr(i: Index, wasm: *const Wasm) *ObjectData {
1395 return &wasm.object_datas.items[@intFromEnum(i)];
1396 }
1397 };
1398};
1399
1400pub const DataPayload = extern struct {
1401 off: Off,
1402 /// The size in bytes of the data representing the segment within the section.
1403 len: u32,
1404
1405 pub const Off = enum(u32) {
1406 /// The payload is all zeroes (bss section).
1407 none = std.math.maxInt(u32),
1408 /// Points into string_bytes. No corresponding string_table entry.
1409 _,
1410
1411 pub fn unwrap(off: Off) ?u32 {
1412 return if (off == .none) null else @intFromEnum(off);
1413 }
1414 };
1415
1416 pub fn slice(p: DataPayload, wasm: *const Wasm) []const u8 {
1417 return wasm.string_bytes.items[p.off.unwrap().?..][0..p.len];
1418 }
1419};
1420
1421/// A reference to a local or exported global const.
1422pub const DataId = enum(u32) {
1423 __zig_error_names,
1424 __zig_error_name_table,
1425 /// First, an `ObjectDataSegment.Index`.
1426 /// Next, index into `uavs_obj` or `uavs_exe` depending on whether emitting an object.
1427 /// Next, index into `navs_obj` or `navs_exe` depending on whether emitting an object.
1428 _,
1429
1430 const first_object = @intFromEnum(DataId.__zig_error_name_table) + 1;
13291431
13301432 pub const Category = enum {
13311433 /// Thread-local variables.
......@@ -1337,221 +1439,180 @@ pub const DataSegment = extern struct {
13371439 zero,
13381440 };
13391441
1340 pub const Payload = extern struct {
1341 off: Off,
1342 /// The size in bytes of the data representing the segment within the section.
1343 len: u32,
1344
1345 pub const Off = enum(u32) {
1346 /// The payload is all zeroes (bss section).
1347 none = std.math.maxInt(u32),
1348 /// Points into string_bytes. No corresponding string_table entry.
1349 _,
1350
1351 pub fn unwrap(off: Off) ?u32 {
1352 return if (off == .none) null else @intFromEnum(off);
1353 }
1354 };
1355
1356 pub fn slice(p: DataSegment.Payload, wasm: *const Wasm) []const u8 {
1357 return wasm.string_bytes.items[p.off.unwrap().?..][0..p.len];
1358 }
1359 };
1360
1361 pub const Id = enum(u32) {
1442 pub const Unpacked = union(enum) {
13621443 __zig_error_names,
13631444 __zig_error_name_table,
1364 /// First, an `ObjectDataSegmentIndex`.
1365 /// Next, index into `uavs_obj` or `uavs_exe` depending on whether emitting an object.
1366 /// Next, index into `navs_obj` or `navs_exe` depending on whether emitting an object.
1367 _,
1368
1369 const first_object = @intFromEnum(Id.__zig_error_name_table) + 1;
1445 object: ObjectDataSegment.Index,
1446 uav_exe: UavsExeIndex,
1447 uav_obj: UavsObjIndex,
1448 nav_exe: NavsExeIndex,
1449 nav_obj: NavsObjIndex,
1450 };
13701451
1371 pub const Unpacked = union(enum) {
1372 __zig_error_names,
1373 __zig_error_name_table,
1374 object: ObjectDataSegmentIndex,
1375 uav_exe: UavsExeIndex,
1376 uav_obj: UavsObjIndex,
1377 nav_exe: NavsExeIndex,
1378 nav_obj: NavsObjIndex,
1452 pub fn pack(wasm: *const Wasm, unpacked: Unpacked) DataId {
1453 return switch (unpacked) {
1454 .__zig_error_names => .__zig_error_names,
1455 .__zig_error_name_table => .__zig_error_name_table,
1456 .object => |i| @enumFromInt(first_object + @intFromEnum(i)),
1457 inline .uav_exe, .uav_obj => |i| @enumFromInt(first_object + wasm.object_data_segments.items.len + @intFromEnum(i)),
1458 .nav_exe => |i| @enumFromInt(first_object + wasm.object_data_segments.items.len + wasm.uavs_exe.entries.len + @intFromEnum(i)),
1459 .nav_obj => |i| @enumFromInt(first_object + wasm.object_data_segments.items.len + wasm.uavs_obj.entries.len + @intFromEnum(i)),
13791460 };
1461 }
13801462
1381 pub fn pack(wasm: *const Wasm, unpacked: Unpacked) Id {
1382 return switch (unpacked) {
1383 .__zig_error_names => .__zig_error_names,
1384 .__zig_error_name_table => .__zig_error_name_table,
1385 .object => |i| @enumFromInt(first_object + @intFromEnum(i)),
1386 inline .uav_exe, .uav_obj => |i| @enumFromInt(first_object + wasm.object_data_segments.items.len + @intFromEnum(i)),
1387 .nav_exe => |i| @enumFromInt(first_object + wasm.object_data_segments.items.len + wasm.uavs_exe.entries.len + @intFromEnum(i)),
1388 .nav_obj => |i| @enumFromInt(first_object + wasm.object_data_segments.items.len + wasm.uavs_obj.entries.len + @intFromEnum(i)),
1389 };
1390 }
1391
1392 pub fn unpack(id: Id, wasm: *const Wasm) Unpacked {
1393 return switch (id) {
1394 .__zig_error_names => .__zig_error_names,
1395 .__zig_error_name_table => .__zig_error_name_table,
1396 _ => {
1397 const object_index = @intFromEnum(id) - first_object;
1398
1399 const uav_index = if (object_index < wasm.object_data_segments.items.len)
1400 return .{ .object = @enumFromInt(object_index) }
1463 pub fn unpack(id: DataId, wasm: *const Wasm) Unpacked {
1464 return switch (id) {
1465 .__zig_error_names => .__zig_error_names,
1466 .__zig_error_name_table => .__zig_error_name_table,
1467 _ => {
1468 const object_index = @intFromEnum(id) - first_object;
1469
1470 const uav_index = if (object_index < wasm.object_data_segments.items.len)
1471 return .{ .object = @enumFromInt(object_index) }
1472 else
1473 object_index - wasm.object_data_segments.items.len;
1474
1475 const comp = wasm.base.comp;
1476 const is_obj = comp.config.output_mode == .Obj;
1477 if (is_obj) {
1478 const nav_index = if (uav_index < wasm.uavs_obj.entries.len)
1479 return .{ .uav_obj = @enumFromInt(uav_index) }
14011480 else
1402 object_index - wasm.object_data_segments.items.len;
1403
1404 const comp = wasm.base.comp;
1405 const is_obj = comp.config.output_mode == .Obj;
1406 if (is_obj) {
1407 const nav_index = if (uav_index < wasm.uavs_obj.entries.len)
1408 return .{ .uav_obj = @enumFromInt(uav_index) }
1409 else
1410 uav_index - wasm.uavs_obj.entries.len;
1411
1412 return .{ .nav_obj = @enumFromInt(nav_index) };
1413 } else {
1414 const nav_index = if (uav_index < wasm.uavs_exe.entries.len)
1415 return .{ .uav_exe = @enumFromInt(uav_index) }
1416 else
1417 uav_index - wasm.uavs_exe.entries.len;
1418
1419 return .{ .nav_exe = @enumFromInt(nav_index) };
1420 }
1421 },
1422 };
1423 }
1481 uav_index - wasm.uavs_obj.entries.len;
14241482
1425 pub fn category(id: Id, wasm: *const Wasm) Category {
1426 return switch (unpack(id, wasm)) {
1427 .__zig_error_names, .__zig_error_name_table => .data,
1428 .object => |i| {
1429 const ptr = i.ptr(wasm);
1430 if (ptr.flags.tls) return .tls;
1431 if (wasm.isBss(ptr.name)) return .zero;
1432 return .data;
1433 },
1434 inline .uav_exe, .uav_obj => |i| if (i.value(wasm).code.off == .none) .zero else .data,
1435 inline .nav_exe, .nav_obj => |i| {
1436 const zcu = wasm.base.comp.zcu.?;
1437 const ip = &zcu.intern_pool;
1438 const nav = ip.getNav(i.key(wasm).*);
1439 if (nav.isThreadLocal(ip)) return .tls;
1440 const code = i.value(wasm).code;
1441 return if (code.off == .none) .zero else .data;
1442 },
1443 };
1444 }
1483 return .{ .nav_obj = @enumFromInt(nav_index) };
1484 } else {
1485 const nav_index = if (uav_index < wasm.uavs_exe.entries.len)
1486 return .{ .uav_exe = @enumFromInt(uav_index) }
1487 else
1488 uav_index - wasm.uavs_exe.entries.len;
14451489
1446 pub fn isTls(id: Id, wasm: *const Wasm) bool {
1447 return switch (unpack(id, wasm)) {
1448 .__zig_error_names, .__zig_error_name_table => false,
1449 .object => |i| i.ptr(wasm).flags.tls,
1450 .uav_exe, .uav_obj => false,
1451 inline .nav_exe, .nav_obj => |i| {
1452 const zcu = wasm.base.comp.zcu.?;
1453 const ip = &zcu.intern_pool;
1454 const nav = ip.getNav(i.key(wasm).*);
1455 return nav.isThreadLocal(ip);
1456 },
1457 };
1458 }
1490 return .{ .nav_exe = @enumFromInt(nav_index) };
1491 }
1492 },
1493 };
1494 }
14591495
1460 pub fn isBss(id: Id, wasm: *const Wasm) bool {
1461 return id.category(wasm) == .zero;
1462 }
1496 pub fn category(id: DataId, wasm: *const Wasm) Category {
1497 return switch (unpack(id, wasm)) {
1498 .__zig_error_names, .__zig_error_name_table => .data,
1499 .object => |i| {
1500 const ptr = i.ptr(wasm);
1501 if (ptr.flags.tls) return .tls;
1502 if (wasm.isBss(ptr.name)) return .zero;
1503 return .data;
1504 },
1505 inline .uav_exe, .uav_obj => |i| if (i.value(wasm).code.off == .none) .zero else .data,
1506 inline .nav_exe, .nav_obj => |i| {
1507 const zcu = wasm.base.comp.zcu.?;
1508 const ip = &zcu.intern_pool;
1509 const nav = ip.getNav(i.key(wasm).*);
1510 if (nav.isThreadLocal(ip)) return .tls;
1511 const code = i.value(wasm).code;
1512 return if (code.off == .none) .zero else .data;
1513 },
1514 };
1515 }
14631516
1464 pub fn name(id: Id, wasm: *const Wasm) []const u8 {
1465 return switch (unpack(id, wasm)) {
1466 .__zig_error_names, .__zig_error_name_table, .uav_exe, .uav_obj => ".data",
1467 .object => |i| i.ptr(wasm).name.unwrap().?.slice(wasm),
1468 inline .nav_exe, .nav_obj => |i| {
1469 const zcu = wasm.base.comp.zcu.?;
1470 const ip = &zcu.intern_pool;
1471 const nav = ip.getNav(i.key(wasm).*);
1472 return nav.status.resolved.@"linksection".toSlice(ip) orelse ".data";
1473 },
1474 };
1475 }
1517 pub fn isTls(id: DataId, wasm: *const Wasm) bool {
1518 return switch (unpack(id, wasm)) {
1519 .__zig_error_names, .__zig_error_name_table => false,
1520 .object => |i| i.ptr(wasm).flags.tls,
1521 .uav_exe, .uav_obj => false,
1522 inline .nav_exe, .nav_obj => |i| {
1523 const zcu = wasm.base.comp.zcu.?;
1524 const ip = &zcu.intern_pool;
1525 const nav = ip.getNav(i.key(wasm).*);
1526 return nav.isThreadLocal(ip);
1527 },
1528 };
1529 }
14761530
1477 pub fn alignment(id: Id, wasm: *const Wasm) Alignment {
1478 return switch (unpack(id, wasm)) {
1479 .__zig_error_names => .@"1",
1480 .__zig_error_name_table => wasm.pointerAlignment(),
1481 .object => |i| i.ptr(wasm).flags.alignment,
1482 inline .uav_exe, .uav_obj => |i| {
1483 const zcu = wasm.base.comp.zcu.?;
1484 const ip = &zcu.intern_pool;
1485 const ip_index = i.key(wasm).*;
1486 const ty: ZcuType = .fromInterned(ip.typeOf(ip_index));
1487 const result = ty.abiAlignment(zcu);
1488 assert(result != .none);
1489 return result;
1490 },
1491 inline .nav_exe, .nav_obj => |i| {
1492 const zcu = wasm.base.comp.zcu.?;
1493 const ip = &zcu.intern_pool;
1494 const nav = ip.getNav(i.key(wasm).*);
1495 const explicit = nav.status.resolved.alignment;
1496 if (explicit != .none) return explicit;
1497 const ty: ZcuType = .fromInterned(nav.typeOf(ip));
1498 const result = ty.abiAlignment(zcu);
1499 assert(result != .none);
1500 return result;
1501 },
1502 };
1503 }
1531 pub fn isBss(id: DataId, wasm: *const Wasm) bool {
1532 return id.category(wasm) == .zero;
1533 }
15041534
1505 pub fn refCount(id: Id, wasm: *const Wasm) u32 {
1506 return switch (unpack(id, wasm)) {
1507 .__zig_error_names => @intCast(wasm.error_name_offs.items.len),
1508 .__zig_error_name_table => wasm.error_name_table_ref_count,
1509 .object, .uav_obj, .nav_obj => 0,
1510 inline .uav_exe, .nav_exe => |i| i.value(wasm).count,
1511 };
1512 }
1535 pub fn name(id: DataId, wasm: *const Wasm) []const u8 {
1536 return switch (unpack(id, wasm)) {
1537 .__zig_error_names, .__zig_error_name_table, .uav_exe, .uav_obj => ".data",
1538 .object => |i| i.ptr(wasm).name.unwrap().?.slice(wasm),
1539 inline .nav_exe, .nav_obj => |i| {
1540 const zcu = wasm.base.comp.zcu.?;
1541 const ip = &zcu.intern_pool;
1542 const nav = ip.getNav(i.key(wasm).*);
1543 return nav.status.resolved.@"linksection".toSlice(ip) orelse ".data";
1544 },
1545 };
1546 }
15131547
1514 pub fn isPassive(id: Id, wasm: *const Wasm) bool {
1515 const comp = wasm.base.comp;
1516 if (comp.config.import_memory and !id.isBss(wasm)) return true;
1517 return switch (unpack(id, wasm)) {
1518 .__zig_error_names, .__zig_error_name_table => false,
1519 .object => |i| i.ptr(wasm).flags.is_passive,
1520 .uav_exe, .uav_obj, .nav_exe, .nav_obj => false,
1521 };
1522 }
1548 pub fn alignment(id: DataId, wasm: *const Wasm) Alignment {
1549 return switch (unpack(id, wasm)) {
1550 .__zig_error_names => .@"1",
1551 .__zig_error_name_table => wasm.pointerAlignment(),
1552 .object => |i| i.ptr(wasm).flags.alignment,
1553 inline .uav_exe, .uav_obj => |i| {
1554 const zcu = wasm.base.comp.zcu.?;
1555 const ip = &zcu.intern_pool;
1556 const ip_index = i.key(wasm).*;
1557 const ty: ZcuType = .fromInterned(ip.typeOf(ip_index));
1558 const result = ty.abiAlignment(zcu);
1559 assert(result != .none);
1560 return result;
1561 },
1562 inline .nav_exe, .nav_obj => |i| {
1563 const zcu = wasm.base.comp.zcu.?;
1564 const ip = &zcu.intern_pool;
1565 const nav = ip.getNav(i.key(wasm).*);
1566 const explicit = nav.status.resolved.alignment;
1567 if (explicit != .none) return explicit;
1568 const ty: ZcuType = .fromInterned(nav.typeOf(ip));
1569 const result = ty.abiAlignment(zcu);
1570 assert(result != .none);
1571 return result;
1572 },
1573 };
1574 }
15231575
1524 pub fn isEmpty(id: Id, wasm: *const Wasm) bool {
1525 return switch (unpack(id, wasm)) {
1526 .__zig_error_names, .__zig_error_name_table => false,
1527 .object => |i| i.ptr(wasm).payload.off == .none,
1528 inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code.off == .none,
1529 };
1530 }
1576 pub fn refCount(id: DataId, wasm: *const Wasm) u32 {
1577 return switch (unpack(id, wasm)) {
1578 .__zig_error_names => @intCast(wasm.error_name_offs.items.len),
1579 .__zig_error_name_table => wasm.error_name_table_ref_count,
1580 .object, .uav_obj, .nav_obj => 0,
1581 inline .uav_exe, .nav_exe => |i| i.value(wasm).count,
1582 };
1583 }
15311584
1532 pub fn size(id: Id, wasm: *const Wasm) u32 {
1533 return switch (unpack(id, wasm)) {
1534 .__zig_error_names => @intCast(wasm.error_name_bytes.items.len),
1535 .__zig_error_name_table => {
1536 const comp = wasm.base.comp;
1537 const zcu = comp.zcu.?;
1538 const errors_len = wasm.error_name_offs.items.len;
1539 const elem_size = ZcuType.slice_const_u8_sentinel_0.abiSize(zcu);
1540 return @intCast(errors_len * elem_size);
1541 },
1542 .object => |i| i.ptr(wasm).payload.len,
1543 inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code.len,
1544 };
1545 }
1546 };
1547};
1585 pub fn isPassive(id: DataId, wasm: *const Wasm) bool {
1586 const comp = wasm.base.comp;
1587 if (comp.config.import_memory and !id.isBss(wasm)) return true;
1588 return switch (unpack(id, wasm)) {
1589 .__zig_error_names, .__zig_error_name_table => false,
1590 .object => |i| i.ptr(wasm).flags.is_passive,
1591 .uav_exe, .uav_obj, .nav_exe, .nav_obj => false,
1592 };
1593 }
15481594
1549/// Index into `Wasm.object_data_segments`.
1550pub const ObjectDataSegmentIndex = enum(u32) {
1551 _,
1595 pub fn isEmpty(id: DataId, wasm: *const Wasm) bool {
1596 return switch (unpack(id, wasm)) {
1597 .__zig_error_names, .__zig_error_name_table => false,
1598 .object => |i| i.ptr(wasm).payload.off == .none,
1599 inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code.off == .none,
1600 };
1601 }
15521602
1553 pub fn ptr(i: ObjectDataSegmentIndex, wasm: *const Wasm) *DataSegment {
1554 return &wasm.object_data_segments.items[@intFromEnum(i)];
1603 pub fn size(id: DataId, wasm: *const Wasm) u32 {
1604 return switch (unpack(id, wasm)) {
1605 .__zig_error_names => @intCast(wasm.error_name_bytes.items.len),
1606 .__zig_error_name_table => {
1607 const comp = wasm.base.comp;
1608 const zcu = comp.zcu.?;
1609 const errors_len = wasm.error_name_offs.items.len;
1610 const elem_size = ZcuType.slice_const_u8_sentinel_0.abiSize(zcu);
1611 return @intCast(errors_len * elem_size);
1612 },
1613 .object => |i| i.ptr(wasm).payload.len,
1614 inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code.len,
1615 };
15551616 }
15561617};
15571618
......@@ -1565,7 +1626,7 @@ pub const CustomSegment = extern struct {
15651626 flags: SymbolFlags,
15661627 section_name: String,
15671628
1568 pub const Payload = DataSegment.Payload;
1629 pub const Payload = DataPayload;
15691630};
15701631
15711632/// An index into string_bytes where a wasm expression is found.
......@@ -1591,9 +1652,13 @@ pub const FunctionType = extern struct {
15911652 pub const Index = enum(u32) {
15921653 _,
15931654
1594 pub fn ptr(i: FunctionType.Index, wasm: *const Wasm) *FunctionType {
1655 pub fn ptr(i: Index, wasm: *const Wasm) *FunctionType {
15951656 return &wasm.func_types.keys()[@intFromEnum(i)];
15961657 }
1658
1659 pub fn fmt(i: Index, wasm: *const Wasm) Formatter {
1660 return i.ptr(wasm).fmt(wasm);
1661 }
15971662 };
15981663
15991664 pub const format = @compileError("can't format without *Wasm reference");
......@@ -1601,6 +1666,46 @@ pub const FunctionType = extern struct {
16011666 pub fn eql(a: FunctionType, b: FunctionType) bool {
16021667 return a.params == b.params and a.returns == b.returns;
16031668 }
1669
1670 pub fn fmt(ft: FunctionType, wasm: *const Wasm) Formatter {
1671 return .{ .wasm = wasm, .ft = ft };
1672 }
1673
1674 const Formatter = struct {
1675 wasm: *const Wasm,
1676 ft: FunctionType,
1677
1678 pub fn format(
1679 self: Formatter,
1680 comptime format_string: []const u8,
1681 options: std.fmt.FormatOptions,
1682 writer: anytype,
1683 ) !void {
1684 if (format_string.len != 0) std.fmt.invalidFmtError(format_string, self);
1685 _ = options;
1686 const params = self.ft.params.slice(self.wasm);
1687 const returns = self.ft.returns.slice(self.wasm);
1688
1689 try writer.writeByte('(');
1690 for (params, 0..) |param, i| {
1691 try writer.print("{s}", .{@tagName(param)});
1692 if (i + 1 != params.len) {
1693 try writer.writeAll(", ");
1694 }
1695 }
1696 try writer.writeAll(") -> ");
1697 if (returns.len == 0) {
1698 try writer.writeAll("nil");
1699 } else {
1700 for (returns, 0..) |return_ty, i| {
1701 try writer.print("{s}", .{@tagName(return_ty)});
1702 if (i + 1 != returns.len) {
1703 try writer.writeAll(", ");
1704 }
1705 }
1706 }
1707 }
1708 };
16041709};
16051710
16061711/// Represents a function entry, holding the index to its type
......@@ -1955,7 +2060,7 @@ pub const ObjectRelocation = struct {
19552060 symbol_name: String,
19562061 type_index: FunctionType.Index,
19572062 section: ObjectSectionIndex,
1958 data_segment: ObjectDataSegmentIndex,
2063 data: ObjectData.Index,
19592064 function: Wasm.ObjectFunctionIndex,
19602065 };
19612066
......@@ -2096,6 +2201,8 @@ pub const Feature = packed struct(u8) {
20962201 /// Type of the feature, must be unique in the sequence of features.
20972202 tag: Tag,
20982203
2204 pub const sentinel: Feature = @bitCast(@as(u8, 0));
2205
20992206 /// Stored identically to `String`. The bytes are reinterpreted as `Feature`
21002207 /// elements. Elements must be sorted before string-interning.
21012208 pub const Set = enum(u32) {
......@@ -2104,6 +2211,14 @@ pub const Feature = packed struct(u8) {
21042211 pub fn fromString(s: String) Set {
21052212 return @enumFromInt(@intFromEnum(s));
21062213 }
2214
2215 pub fn string(s: Set) String {
2216 return @enumFromInt(@intFromEnum(s));
2217 }
2218
2219 pub fn slice(s: Set, wasm: *const Wasm) [:sentinel]const Feature {
2220 return @ptrCast(string(s).slice(wasm));
2221 }
21072222 };
21082223
21092224 /// Unlike `std.Target.wasm.Feature` this also contains linker-features such as shared-mem.
......@@ -2129,6 +2244,13 @@ pub const Feature = packed struct(u8) {
21292244 return @enumFromInt(@intFromEnum(feature));
21302245 }
21312246
2247 pub fn toCpuFeature(tag: Tag) ?std.Target.wasm.Feature {
2248 return if (@intFromEnum(tag) < @typeInfo(std.Target.wasm.Feature).@"enum".fields.len)
2249 @enumFromInt(@intFromEnum(tag))
2250 else
2251 null;
2252 }
2253
21322254 pub const format = @compileError("use @tagName instead");
21332255 };
21342256
......@@ -2136,15 +2258,14 @@ pub const Feature = packed struct(u8) {
21362258 pub const Prefix = enum(u2) {
21372259 /// Reserved so that a 0-byte Feature is invalid and therefore can be a sentinel.
21382260 invalid,
2139 /// '0x2b': Object uses this feature, and the link fails if feature is
2140 /// not in the allowed set.
2261 /// Object uses this feature, and the link fails if feature is not in
2262 /// the allowed set.
21412263 @"+",
2142 /// '0x2d': Object does not use this feature, and the link fails if
2143 /// this feature is in the allowed set.
2264 /// Object does not use this feature, and the link fails if this
2265 /// feature is in the allowed set.
21442266 @"-",
2145 /// '0x3d': Object uses this feature, and the link fails if this
2146 /// feature is not in the allowed set, or if any object does not use
2147 /// this feature.
2267 /// Object uses this feature, and the link fails if this feature is not
2268 /// in the allowed set, or if any object does not use this feature.
21482269 @"=",
21492270 };
21502271
......@@ -2390,6 +2511,7 @@ pub fn deinit(wasm: *Wasm) void {
23902511 wasm.object_memories.deinit(gpa);
23912512 wasm.object_relocations.deinit(gpa);
23922513 wasm.object_data_segments.deinit(gpa);
2514 wasm.object_datas.deinit(gpa);
23932515 wasm.object_custom_segments.deinit(gpa);
23942516 wasm.object_init_funcs.deinit(gpa);
23952517 wasm.object_comdats.deinit(gpa);
......@@ -3412,7 +3534,7 @@ pub fn addExpr(wasm: *Wasm, bytes: []const u8) Allocator.Error!Expr {
34123534 return @enumFromInt(wasm.string_bytes.items.len - bytes.len);
34133535}
34143536
3415pub fn addRelocatableDataPayload(wasm: *Wasm, bytes: []const u8) Allocator.Error!DataSegment.Payload {
3537pub fn addRelocatableDataPayload(wasm: *Wasm, bytes: []const u8) Allocator.Error!DataPayload {
34163538 const gpa = wasm.base.comp.gpa;
34173539 try wasm.string_bytes.appendSlice(gpa, bytes);
34183540 return .{
......@@ -3546,7 +3668,7 @@ pub fn uavAddr(wasm: *Wasm, uav_index: UavsExeIndex) u32 {
35463668 assert(wasm.flush_buffer.memory_layout_finished);
35473669 const comp = wasm.base.comp;
35483670 assert(comp.config.output_mode != .Obj);
3549 const ds_id: DataSegment.Id = .pack(wasm, .{ .uav_exe = uav_index });
3671 const ds_id: DataId = .pack(wasm, .{ .uav_exe = uav_index });
35503672 return wasm.flush_buffer.data_segments.get(ds_id).?;
35513673}
35523674
......@@ -3557,7 +3679,7 @@ pub fn navAddr(wasm: *Wasm, nav_index: InternPool.Nav.Index) u32 {
35573679 assert(comp.config.output_mode != .Obj);
35583680 const navs_exe_index: NavsExeIndex = @enumFromInt(wasm.navs_exe.getIndex(nav_index).?);
35593681 log.debug("navAddr {s} {}", .{ navs_exe_index.name(wasm), nav_index });
3560 const ds_id: DataSegment.Id = .pack(wasm, .{ .nav_exe = navs_exe_index });
3682 const ds_id: DataId = .pack(wasm, .{ .nav_exe = navs_exe_index });
35613683 return wasm.flush_buffer.data_segments.get(ds_id).?;
35623684}
35633685
......@@ -3646,14 +3768,14 @@ fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Zcu
36463768 const relocs_len: u32 = @intCast(wasm.out_relocs.len - relocs_start);
36473769 wasm.string_bytes_lock.unlock();
36483770
3649 const naive_code: DataSegment.Payload = .{
3771 const naive_code: DataPayload = .{
36503772 .off = @enumFromInt(code_start),
36513773 .len = code_len,
36523774 };
36533775
36543776 // Only nonzero init values need to take up space in the output.
36553777 const all_zeroes = std.mem.allEqual(u8, naive_code.slice(wasm), 0);
3656 const code: DataSegment.Payload = if (!all_zeroes) naive_code else c: {
3778 const code: DataPayload = if (!all_zeroes) naive_code else c: {
36573779 wasm.string_bytes.shrinkRetainingCapacity(code_start);
36583780 // Indicate empty by making off and len the same value, however, still
36593781 // transmit the data size by using the size as that value.
src/link/Wasm/Flush.zig+12-12
......@@ -22,7 +22,7 @@ const assert = std.debug.assert;
2222/// Ordered list of data segments that will appear in the final binary.
2323/// When sorted, to-be-merged segments will be made adjacent.
2424/// Values are virtual address.
25data_segments: std.AutoArrayHashMapUnmanaged(Wasm.DataSegment.Id, u32) = .empty,
25data_segments: std.AutoArrayHashMapUnmanaged(Wasm.DataId, u32) = .empty,
2626/// Each time a `data_segment` offset equals zero it indicates a new group, and
2727/// the next element in this array will contain the total merged segment size.
2828/// Value is the virtual memory address of the end of the segment.
......@@ -120,7 +120,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
120120 if (wasm.entry_resolution == .unresolved) {
121121 var err = try diags.addErrorWithNotes(1);
122122 try err.addMsg("entry symbol '{s}' missing", .{name.slice(wasm)});
123 try err.addNote("'-fno-entry' suppresses this error", .{});
123 err.addNote("'-fno-entry' suppresses this error", .{});
124124 }
125125 }
126126 }
......@@ -176,10 +176,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
176176 }), @as(u32, undefined));
177177 for (wasm.object_data_segments.items, 0..) |*ds, i| {
178178 if (!ds.flags.alive) continue;
179 const data_segment_index: Wasm.ObjectDataSegmentIndex = @enumFromInt(i);
179 const obj_seg_index: Wasm.ObjectDataSegment.Index = @enumFromInt(i);
180180 any_passive_inits = any_passive_inits or ds.flags.is_passive or (import_memory and !wasm.isBss(ds.name));
181181 _ = f.data_segments.putAssumeCapacityNoClobber(.pack(wasm, .{
182 .object = data_segment_index,
182 .object = obj_seg_index,
183183 }), @as(u32, undefined));
184184 }
185185 if (wasm.error_name_table_ref_count > 0) {
......@@ -229,7 +229,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
229229 // For the purposes of sorting, they are implicitly all named ".data".
230230 const Sort = struct {
231231 wasm: *const Wasm,
232 segments: []const Wasm.DataSegment.Id,
232 segments: []const Wasm.DataId,
233233 pub fn lessThan(ctx: @This(), lhs: usize, rhs: usize) bool {
234234 const lhs_segment = ctx.segments[lhs];
235235 const rhs_segment = ctx.segments[rhs];
......@@ -312,7 +312,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
312312 const data_vaddr: u32 = @intCast(memory_ptr);
313313 {
314314 var seen_tls: enum { before, during, after } = .before;
315 var category: Wasm.DataSegment.Category = undefined;
315 var category: Wasm.DataId.Category = undefined;
316316 for (segment_ids, segment_vaddrs, 0..) |segment_id, *segment_vaddr, i| {
317317 const alignment = segment_id.alignment(wasm);
318318 category = segment_id.category(wasm);
......@@ -707,7 +707,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
707707
708708 if (!is_obj) {
709709 for (wasm.uav_fixups.items) |uav_fixup| {
710 const ds_id: Wasm.DataSegment.Id = .pack(wasm, .{ .uav_exe = uav_fixup.uavs_exe_index });
710 const ds_id: Wasm.DataId = .pack(wasm, .{ .uav_exe = uav_fixup.uavs_exe_index });
711711 const vaddr = f.data_segments.get(ds_id).?;
712712 if (!is64) {
713713 mem.writeInt(u32, wasm.string_bytes.items[uav_fixup.offset..][0..4], vaddr, .little);
......@@ -716,7 +716,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
716716 }
717717 }
718718 for (wasm.nav_fixups.items) |nav_fixup| {
719 const ds_id: Wasm.DataSegment.Id = .pack(wasm, .{ .nav_exe = nav_fixup.navs_exe_index });
719 const ds_id: Wasm.DataId = .pack(wasm, .{ .nav_exe = nav_fixup.navs_exe_index });
720720 const vaddr = f.data_segments.get(ds_id).?;
721721 if (!is64) {
722722 mem.writeInt(u32, wasm.string_bytes.items[nav_fixup.offset..][0..4], vaddr, .little);
......@@ -862,7 +862,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
862862
863863fn emitNameSection(
864864 wasm: *Wasm,
865 data_segments: *const std.AutoArrayHashMapUnmanaged(Wasm.DataSegment.Id, u32),
865 data_segments: *const std.AutoArrayHashMapUnmanaged(Wasm.DataId, u32),
866866 binary_bytes: *std.ArrayListUnmanaged(u8),
867867) !void {
868868 const f = &wasm.flush_buffer;
......@@ -1137,9 +1137,9 @@ fn splitSegmentName(name: []const u8) struct { []const u8, []const u8 } {
11371137
11381138fn wantSegmentMerge(
11391139 wasm: *const Wasm,
1140 a_id: Wasm.DataSegment.Id,
1141 b_id: Wasm.DataSegment.Id,
1142 b_category: Wasm.DataSegment.Category,
1140 a_id: Wasm.DataId,
1141 b_id: Wasm.DataId,
1142 b_category: Wasm.DataId.Category,
11431143) bool {
11441144 const a_category = a_id.category(wasm);
11451145 if (a_category != b_category) return false;
src/link/Wasm/Object.zig+105-79
......@@ -102,11 +102,7 @@ pub const Symbol = struct {
102102 const Pointee = union(enum) {
103103 function: Wasm.ObjectFunctionIndex,
104104 function_import: ScratchSpace.FuncImportIndex,
105 data: struct {
106 segment_index: Wasm.ObjectDataSegmentIndex,
107 segment_offset: u32,
108 size: u32,
109 },
105 data: Wasm.ObjectData.Index,
110106 data_import: void,
111107 global: Wasm.ObjectGlobalIndex,
112108 global_import: Wasm.GlobalImport.Index,
......@@ -131,7 +127,7 @@ pub const ScratchSpace = struct {
131127 const Pointee = union(std.wasm.ExternalKind) {
132128 function: Wasm.ObjectFunctionIndex,
133129 table: Wasm.ObjectTableIndex,
134 memory: Wasm.ObjectMemoryIndex,
130 memory: Wasm.ObjectMemory.Index,
135131 global: Wasm.ObjectGlobalIndex,
136132 };
137133 };
......@@ -184,8 +180,9 @@ pub fn parse(
184180 must_link: bool,
185181 gc_sections: bool,
186182) anyerror!Object {
187 const gpa = wasm.base.comp.gpa;
188 const diags = &wasm.base.comp.link_diags;
183 const comp = wasm.base.comp;
184 const gpa = comp.gpa;
185 const diags = &comp.link_diags;
189186
190187 var pos: usize = 0;
191188
......@@ -334,12 +331,16 @@ pub fn parse(
334331 const segment_index, pos = readLeb(u32, bytes, pos);
335332 const segment_offset, pos = readLeb(u32, bytes, pos);
336333 const size, pos = readLeb(u32, bytes, pos);
337
338 symbol.pointee = .{ .data = .{
339 .segment_index = @enumFromInt(data_segment_start + segment_index),
340 .segment_offset = segment_offset,
334 try wasm.object_datas.append(gpa, .{
335 .segment = @enumFromInt(data_segment_start + segment_index),
336 .offset = segment_offset,
341337 .size = size,
342 } };
338 .name = symbol.name,
339 .flags = symbol.flags,
340 });
341 symbol.pointee = .{
342 .data = @enumFromInt(wasm.object_datas.items.len - 1),
343 };
343344 }
344345 },
345346 .section => {
......@@ -405,7 +406,6 @@ pub fn parse(
405406 return error.UnrecognizedSymbolType;
406407 },
407408 }
408 log.debug("found symbol: {}", .{symbol});
409409 }
410410 },
411411 }
......@@ -450,22 +450,10 @@ pub fn parse(
450450 .MEMORY_ADDR_TLS_SLEB64,
451451 => {
452452 const addend: i32, pos = readLeb(i32, bytes, pos);
453 const sym_section = ss.symbol_table.items[index].pointee.data;
454 if (sym_section.segment_offset != 0) {
455 return diags.failParse(path, "data symbol {d} has nonzero offset {d}", .{
456 index, sym_section.segment_offset,
457 });
458 }
459 const seg_size = sym_section.segment_index.ptr(wasm).payload.len;
460 if (sym_section.size != seg_size) {
461 return diags.failParse(path, "data symbol {d} has size {d}, inequal to corresponding data segment {d} size {d}", .{
462 index, sym_section.size, @intFromEnum(sym_section.segment_index), seg_size,
463 });
464 }
465453 wasm.object_relocations.appendAssumeCapacity(.{
466454 .tag = tag,
467455 .offset = offset,
468 .pointee = .{ .data_segment = sym_section.segment_index },
456 .pointee = .{ .data = ss.symbol_table.items[index].pointee.data },
469457 .addend = addend,
470458 });
471459 },
......@@ -651,7 +639,15 @@ pub fn parse(
651639 const memories_len, pos = readLeb(u32, bytes, pos);
652640 for (try wasm.object_memories.addManyAsSlice(gpa, memories_len)) |*memory| {
653641 const limits, pos = readLimits(bytes, pos);
654 memory.* = .{ .limits = limits };
642 memory.* = .{
643 .name = .none,
644 .flags = .{
645 .limits_has_max = limits.flags.has_max,
646 .limits_is_shared = limits.flags.is_shared,
647 },
648 .limits_min = limits.min,
649 .limits_max = limits.max,
650 };
655651 }
656652 },
657653 .global => {
......@@ -722,7 +718,6 @@ pub fn parse(
722718 }
723719 },
724720 .data => {
725 const start = pos;
726721 const count, pos = readLeb(u32, bytes, pos);
727722 for (try wasm.object_data_segments.addManyAsSlice(gpa, count)) |*elem| {
728723 const flags, pos = readEnum(DataSegmentFlags, bytes, pos);
......@@ -733,13 +728,10 @@ pub fn parse(
733728 //const expr, pos = if (flags != .passive) try readInit(wasm, bytes, pos) else .{ .none, pos };
734729 if (flags != .passive) pos = try skipInit(bytes, pos);
735730 const data_len, pos = readLeb(u32, bytes, pos);
736 const segment_offset: u32 = @intCast(pos - start);
737731 const payload = try wasm.addRelocatableDataPayload(bytes[pos..][0..data_len]);
738732 pos += data_len;
739733 elem.* = .{
740734 .payload = payload,
741 .segment_offset = segment_offset,
742 .section_index = section_index,
743735 .name = .none, // Populated from symbol table
744736 .flags = .{}, // Populated from symbol table and segment_info
745737 };
......@@ -751,20 +743,56 @@ pub fn parse(
751743 }
752744 if (!saw_linking_section) return error.MissingLinkingSection;
753745
746 const target_features = comp.root_mod.resolved_target.result.cpu.features;
747
754748 if (has_tls) {
755 const cpu_features = wasm.base.comp.root_mod.resolved_target.result.cpu.features;
756 if (!std.Target.wasm.featureSetHas(cpu_features, .atomics))
749 if (!std.Target.wasm.featureSetHas(target_features, .atomics))
757750 return diags.failParse(path, "object has TLS segment but target CPU feature atomics is disabled", .{});
758 if (!std.Target.wasm.featureSetHas(cpu_features, .bulk_memory))
751 if (!std.Target.wasm.featureSetHas(target_features, .bulk_memory))
759752 return diags.failParse(path, "object has TLS segment but target CPU feature bulk_memory is disabled", .{});
760753 }
761754
762755 const features = opt_features orelse return error.MissingFeatures;
763 if (true) @panic("iterate features, match against target features");
756 for (features.slice(wasm)) |feat| {
757 log.debug("feature: {s}{s}", .{ @tagName(feat.prefix), @tagName(feat.tag) });
758 switch (feat.prefix) {
759 .invalid => unreachable,
760 .@"-" => switch (feat.tag) {
761 .@"shared-mem" => if (comp.config.shared_memory) {
762 return diags.failParse(path, "object forbids shared-mem but compilation enables it", .{});
763 },
764 else => {
765 const f = feat.tag.toCpuFeature().?;
766 if (std.Target.wasm.featureSetHas(target_features, f)) {
767 return diags.failParse(
768 path,
769 "object forbids {s} but specified target features include {s}",
770 .{ @tagName(feat.tag), @tagName(f) },
771 );
772 }
773 },
774 },
775 .@"+", .@"=" => switch (feat.tag) {
776 .@"shared-mem" => if (!comp.config.shared_memory) {
777 return diags.failParse(path, "object requires shared-mem but compilation disables it", .{});
778 },
779 else => {
780 const f = feat.tag.toCpuFeature().?;
781 if (!std.Target.wasm.featureSetHas(target_features, f)) {
782 return diags.failParse(
783 path,
784 "object requires {s} but specified target features exclude {s}",
785 .{ @tagName(feat.tag), @tagName(f) },
786 );
787 }
788 },
789 },
790 }
791 }
764792
765793 // Apply function type information.
766 for (ss.func_types.items, wasm.object_functions.items[functions_start..]) |func_type, *func| {
767 func.type_index = func_type;
794 for (ss.func_type_indexes.items, wasm.object_functions.items[functions_start..]) |func_type, *func| {
795 func.type_index = func_type.ptr(ss).*;
768796 }
769797
770798 // Apply symbol table information.
......@@ -782,15 +810,21 @@ pub fn parse(
782810 if (gop.value_ptr.type != fn_ty_index) {
783811 var err = try diags.addErrorWithNotes(2);
784812 try err.addMsg("symbol '{s}' mismatching function signatures", .{name.slice(wasm)});
785 try err.addSrcNote(gop.value_ptr.source_location, "imported as {} here", .{gop.value_ptr.type.fmt(wasm)});
786 try err.addSrcNote(source_location, "imported as {} here", .{fn_ty_index.fmt(wasm)});
813 gop.value_ptr.source_location.addNote(wasm, &err, "imported as {} here", .{
814 gop.value_ptr.type.fmt(wasm),
815 });
816 source_location.addNote(wasm, &err, "imported as {} here", .{fn_ty_index.fmt(wasm)});
787817 continue;
788818 }
789 if (gop.value_ptr.module_name != ptr.module_name) {
819 if (gop.value_ptr.module_name != ptr.module_name.toOptional()) {
790820 var err = try diags.addErrorWithNotes(2);
791821 try err.addMsg("symbol '{s}' mismatching module names", .{name.slice(wasm)});
792 try err.addSrcNote(gop.value_ptr.source_location, "module '{s}' here", .{gop.value_ptr.module_name.slice(wasm)});
793 try err.addSrcNote(source_location, "module '{s}' here", .{ptr.module_name.slice(wasm)});
822 if (gop.value_ptr.module_name.slice(wasm)) |module_name| {
823 gop.value_ptr.source_location.addNote(wasm, &err, "module '{s}' here", .{module_name});
824 } else {
825 gop.value_ptr.source_location.addNote(wasm, &err, "no module here", .{});
826 }
827 source_location.addNote(wasm, &err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
794828 continue;
795829 }
796830 if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;
......@@ -799,7 +833,7 @@ pub fn parse(
799833 } else {
800834 gop.value_ptr.* = .{
801835 .flags = symbol.flags,
802 .module_name = ptr.module_name,
836 .module_name = ptr.module_name.toOptional(),
803837 .source_location = source_location,
804838 .resolution = .unresolved,
805839 .type = fn_ty_index,
......@@ -808,7 +842,7 @@ pub fn parse(
808842 },
809843 .function => |index| {
810844 assert(!symbol.flags.undefined);
811 const ptr = index.ptr();
845 const ptr = index.ptr(wasm);
812846 ptr.name = symbol.name;
813847 ptr.flags = symbol.flags;
814848 if (symbol.flags.binding == .local) continue; // No participation in symbol resolution.
......@@ -818,35 +852,46 @@ pub fn parse(
818852 if (gop.value_ptr.type != ptr.type_index) {
819853 var err = try diags.addErrorWithNotes(2);
820854 try err.addMsg("function signature mismatch: {s}", .{name.slice(wasm)});
821 try err.addSrcNote(gop.value_ptr.source_location, "exported as {} here", .{ptr.type_index.fmt(wasm)});
822 const word = if (gop.value_ptr.resolution == .none) "imported" else "exported";
823 try err.addSrcNote(source_location, "{s} as {} here", .{ word, gop.value_ptr.type.fmt(wasm) });
855 gop.value_ptr.source_location.addNote(wasm, &err, "exported as {} here", .{
856 ptr.type_index.fmt(wasm),
857 });
858 const word = if (gop.value_ptr.resolution == .unresolved) "imported" else "exported";
859 source_location.addNote(wasm, &err, "{s} as {} here", .{ word, gop.value_ptr.type.fmt(wasm) });
824860 continue;
825861 }
826 if (gop.value_ptr.resolution == .none or gop.value_ptr.flags.binding == .weak) {
862 if (gop.value_ptr.resolution == .unresolved or gop.value_ptr.flags.binding == .weak) {
827863 // Intentional: if they're both weak, take the last one.
828864 gop.value_ptr.source_location = source_location;
829865 gop.value_ptr.module_name = host_name;
830 gop.value_ptr.resolution = .fromObjectFunction(index);
866 gop.value_ptr.resolution = .fromObjectFunction(wasm, index);
831867 continue;
832868 }
833869 var err = try diags.addErrorWithNotes(2);
834870 try err.addMsg("symbol collision: {s}", .{name.slice(wasm)});
835 try err.addSrcNote(gop.value_ptr.source_location, "exported as {} here", .{ptr.type_index.fmt(wasm)});
836 try err.addSrcNote(source_location, "exported as {} here", .{gop.value_ptr.type.fmt(wasm)});
871 gop.value_ptr.source_location.addNote(wasm, &err, "exported as {} here", .{ptr.type_index.fmt(wasm)});
872 source_location.addNote(wasm, &err, "exported as {} here", .{gop.value_ptr.type.fmt(wasm)});
837873 continue;
838874 } else {
839875 gop.value_ptr.* = .{
840876 .flags = symbol.flags,
841877 .module_name = host_name,
842878 .source_location = source_location,
843 .resolution = .fromObjectFunction(index),
879 .resolution = .fromObjectFunction(wasm, index),
844880 .type = ptr.type_index,
845881 };
846882 }
847883 },
848884
849 inline .global, .global_import, .table, .table_import => |i| {
885 inline .global_import, .table_import => |i| {
886 const ptr = i.value(wasm);
887 assert(i.key(wasm).toOptional() == symbol.name); // TODO
888 ptr.flags = symbol.flags;
889 if (symbol.flags.undefined and symbol.flags.binding == .local) {
890 const name = i.key(wasm).slice(wasm);
891 diags.addParseError(path, "local symbol '{s}' references import", .{name});
892 }
893 },
894 inline .global, .table => |i| {
850895 const ptr = i.ptr(wasm);
851896 ptr.name = symbol.name;
852897 ptr.flags = symbol.flags;
......@@ -857,10 +902,11 @@ pub fn parse(
857902 },
858903 .section => |i| {
859904 // Name is provided by the section directly; symbol table does not have it.
860 const ptr = i.ptr(wasm);
861 ptr.flags = symbol.flags;
905 //const ptr = i.ptr(wasm);
906 //ptr.flags = symbol.flags;
907 _ = i;
862908 if (symbol.flags.undefined and symbol.flags.binding == .local) {
863 const name = ptr.name.slice(wasm);
909 const name = symbol.name.slice(wasm).?;
864910 diags.addParseError(path, "local symbol '{s}' references import", .{name});
865911 }
866912 },
......@@ -868,15 +914,7 @@ pub fn parse(
868914 const name = symbol.name.unwrap().?;
869915 log.warn("TODO data import '{s}'", .{name.slice(wasm)});
870916 },
871 .data => |data| {
872 const ptr = data.ptr(wasm);
873 const is_passive = ptr.flags.is_passive;
874 ptr.name = symbol.name;
875 ptr.flags = symbol.flags;
876 ptr.flags.is_passive = is_passive;
877 ptr.offset = data.segment_offset;
878 ptr.size = data.size;
879 },
917 .data => continue, // `wasm.object_datas` has already been populated.
880918 };
881919
882920 // Apply export section info. This is done after the symbol table above so
......@@ -957,18 +995,6 @@ pub fn parse(
957995 .off = functions_start,
958996 .len = @intCast(wasm.object_functions.items.len - functions_start),
959997 },
960 .globals = .{
961 .off = globals_start,
962 .len = @intCast(wasm.object_globals.items.len - globals_start),
963 },
964 .tables = .{
965 .off = tables_start,
966 .len = @intCast(wasm.object_tables.items.len - tables_start),
967 },
968 .memories = .{
969 .off = memories_start,
970 .len = @intCast(wasm.object_memories.items.len - memories_start),
971 },
972998 .function_imports = .{
973999 .off = function_imports_start,
9741000 .len = @intCast(wasm.object_function_imports.entries.len - function_imports_start),
......@@ -979,7 +1005,7 @@ pub fn parse(
9791005 },
9801006 .table_imports = .{
9811007 .off = table_imports_start,
982 .len = @intCast(wasm.object_table_imports.items.len - table_imports_start),
1008 .len = @intCast(wasm.object_table_imports.entries.len - table_imports_start),
9831009 },
9841010 .init_funcs = .{
9851011 .off = init_funcs_start,