authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-12 14:42:47-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 12:59:38-04:00
log8530e997ea6673ebdeb2c90d6d2eb2d777a99fcb
treeb412bc2a28b5a0d64194fcc4fb9be75b55d01170
parentb9b1174d069fcf201df79cb2fbaecdfc1fc74206

Elf2: try deleting lost nodes which contain stale info


6 files changed, 638 insertions(+), 513 deletions(-)

src/Zcu/PerThread.zig+2-1
......@@ -861,6 +861,7 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void {
861861 log.debug("tracking failed for %{d}", .{old_inst});
862862 tracked_inst.inst = .lost;
863863 try zcu.markDependeeOutdated(.not_marked_po, .{ .src_hash = tracked_inst_index });
864 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .lost_tracking = tracked_inst_index });
864865 continue;
865866 };
866867 tracked_inst.inst = InternPool.TrackedInst.MaybeLost.ZirIndex.wrap(new_inst);
......@@ -981,7 +982,7 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void {
981982/// Ensures that `zcu.fileRootType` on this `file_index` is populated (not `.none`). This implies
982983/// that the file's namespace is scanned, discovering declarations.
983984///
984/// Typical Zig compilations begin by claling this function on the root source file of the standard
985/// Typical Zig compilations begin by calling this function on the root source file of the standard
985986/// library, `lib/std/std.zig`. The resulting namespace scan discovers a `comptime` declaration in
986987/// that file, which is queued for analysis, and everything goes from there.
987988pub fn ensureFilePopulated(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Allocator.Error || Io.Cancelable)!void {
src/link.zig+29-3
......@@ -878,12 +878,11 @@ pub const File = struct {
878878 const inst = file.zir.?.instructions.get(@backingInt(ti.inst));
879879 assert(inst.tag == .declaration);
880880 }
881
882881 switch (base.tag) {
883882 .lld => unreachable,
884 .spirv => {},
885883 .plan9 => unreachable,
886 .elf2, .coff2 => {},
884 .spirv => {},
885 .coff2 => {},
887886 inline else => |tag| {
888887 dev.check(tag.devFeature());
889888 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id);
......@@ -891,6 +890,19 @@ pub const File = struct {
891890 }
892891 }
893892
893 fn lostTracking(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) Error!void {
894 assert(base.comp.zcu.?.llvm_object == null);
895 switch (base.tag) {
896 .lld => unreachable,
897 .plan9 => unreachable,
898 else => {},
899 inline .elf2 => |tag| {
900 dev.check(tag.devFeature());
901 return @as(*tag.Type(), @fieldParentPtr("base", base)).lostTracking(pt, ti_id);
902 },
903 }
904 }
905
894906 pub fn releaseLock(base: *File) void {
895907 const comp = base.comp;
896908 const io = comp.io;
......@@ -1441,6 +1453,7 @@ pub const ZcuTask = union(enum) {
14411453 success: bool,
14421454 },
14431455 debug_update_line_number: InternPool.TrackedInst.Index,
1456 lost_tracking: InternPool.TrackedInst.Index,
14441457};
14451458
14461459pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
......@@ -1713,6 +1726,19 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
17131726 }
17141727 break :nav null;
17151728 },
1729 .lost_tracking => |ti| nav: {
1730 const nav_prog_node = comp.link_prog_node.start("Lost tracking", 0);
1731 defer nav_prog_node.end();
1732 if (pt.zcu.llvm_object == null) {
1733 if (comp.bin_file) |lf| {
1734 lf.lostTracking(pt, ti) catch |err| switch (err) {
1735 error.OutOfMemory => diags.setAllocFailure(),
1736 else => |e| log.err("lost tracking failed: {s}", .{@errorName(e)}),
1737 };
1738 }
1739 }
1740 break :nav null;
1741 },
17161742 };
17171743
17181744 if (timer.finish(io)) |ns_link| report_time: {
src/link/Coff.zig+71-70
......@@ -536,7 +536,7 @@ pub const Member = struct {
536536 const new_size = Alignment.@"4".forward(old_size + name.len + 1);
537537 assert(new_size < comptime try std.math.powi(u64, 10, max_name_len - 1));
538538
539 try Node.known.longnames_member.resizeLeaf(&coff.mf, gpa, new_size);
539 try Node.known.longnames_member.resizeLeaf(gpa, &coff.mf, new_size);
540540 const name_table_slice = Node.known.longnames_member.slice(&coff.mf);
541541 const name_slice = name_table_slice[@intCast(old_size)..][0 .. name.len + 1];
542542 @memcpy(name_slice[0..name.len], name);
......@@ -1840,13 +1840,13 @@ fn initHeaders(
18401840 coff.nodes.appendAssumeCapacity(.file);
18411841
18421842 const header_ni = Node.known.header;
1843 assert(header_ni == try Node.known.file.addOnlyHeaderChild(&coff.mf, gpa, .{
1843 assert(header_ni == try Node.known.file.addOnlyHeaderChild(gpa, &coff.mf, .{
18441844 .alignment = coff.mf.flags.block_size,
18451845 }));
18461846 coff.nodes.appendAssumeCapacity(.header);
18471847
18481848 const coff_parent_ni: MappedFile.Node.Index = if (is_archive) parent: {
1849 assert(try Node.known.file.addHeaderChildAfter(&coff.mf, gpa, .wrap(header_ni), .{
1849 assert(try Node.known.file.addHeaderChildAfter(gpa, &coff.mf, .wrap(header_ni), .{
18501850 .size = std.coff.archive_signature.len,
18511851 .alignment = .@"4",
18521852 }) == Node.known.signature);
......@@ -1879,7 +1879,7 @@ fn initHeaders(
18791879 const zcu_member = zcu_mi.get(coff);
18801880 try zcu_member.initHeader(coff, zcu.main_mod.fully_qualified_name, timestamp);
18811881
1882 assert(try zcu_member.content_ni.addOnlyHeaderChild(&coff.mf, gpa, .{
1882 assert(try zcu_member.content_ni.addOnlyHeaderChild(gpa, &coff.mf, .{
18831883 .size = @sizeOf(std.coff.Header),
18841884 .alignment = .@"4",
18851885 }) == Node.known.coff_header);
......@@ -1894,13 +1894,13 @@ fn initHeaders(
18941894 // no other members then the last linker member (longnames) needs to expand
18951895 // to fill the padding at the end of the file.
18961896 while (coff.nodes.len < Node.known_count) {
1897 _ = try Node.known.header.addHeaderChildAfter(&coff.mf, gpa, .none, .{});
1897 _ = try Node.known.header.addHeaderChildAfter(gpa, &coff.mf, .none, .{});
18981898 coff.nodes.appendAssumeCapacity(.placeholder);
18991899 }
19001900
19011901 return;
19021902 } else parent: {
1903 assert(try header_ni.addOnlyHeaderChild(&coff.mf, gpa, .{
1903 assert(try header_ni.addOnlyHeaderChild(gpa, &coff.mf, .{
19041904 .size = if (is_image) msdos_stub.len + std.coff.pe_signature.len else 0,
19051905 .alignment = .@"4",
19061906 }) == Node.known.signature);
......@@ -1913,12 +1913,12 @@ fn initHeaders(
19131913
19141914 // TODO: Not ideal to have this many placeholder nodes - use two distinct `Node.known` types?
19151915 while (true) {
1916 const placeholder_ni = try Node.known.file.addHeaderChildAfter(&coff.mf, gpa, .none, .{});
1916 const placeholder_ni = try Node.known.file.addHeaderChildAfter(gpa, &coff.mf, .none, .{});
19171917 coff.nodes.appendAssumeCapacity(.placeholder);
19181918 if (placeholder_ni == Node.known.zcu_member) break;
19191919 }
19201920
1921 assert(try header_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(Node.known.signature), .{
1921 assert(try header_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(Node.known.signature), .{
19221922 .size = @sizeOf(std.coff.Header),
19231923 .alignment = .@"4",
19241924 }) == Node.known.coff_header);
......@@ -1949,7 +1949,7 @@ fn initHeaders(
19491949 }
19501950
19511951 const optional_header_ni = Node.known.optional_header;
1952 assert(optional_header_ni == try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(Node.known.coff_header), .{
1952 assert(optional_header_ni == try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(Node.known.coff_header), .{
19531953 .size = optional_header_size,
19541954 .alignment = .@"4",
19551955 }));
......@@ -2060,7 +2060,7 @@ fn initHeaders(
20602060 }
20612061
20622062 const data_directories_ni = Node.known.data_directories;
2063 assert(data_directories_ni == try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(optional_header_ni), .{
2063 assert(data_directories_ni == try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(optional_header_ni), .{
20642064 .size = data_directories_size,
20652065 .alignment = .@"4",
20662066 }));
......@@ -2075,7 +2075,7 @@ fn initHeaders(
20752075 }
20762076
20772077 const section_table_ni = Node.known.section_table;
2078 assert(section_table_ni == try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(data_directories_ni), .{
2078 assert(section_table_ni == try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(data_directories_ni), .{
20792079 .alignment = .@"4",
20802080 }));
20812081 coff.nodes.appendAssumeCapacity(.section_table);
......@@ -2084,13 +2084,13 @@ fn initHeaders(
20842084
20852085 if (!is_image) {
20862086 // TODO: These two nodes could be inside one movable node?
2087 coff.symbol_table.ni = try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(section_table_ni), .{
2087 coff.symbol_table.ni = try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(section_table_ni), .{
20882088 .alignment = .@"2",
20892089 .moved = true,
20902090 });
20912091 coff.nodes.appendAssumeCapacity(.symbol_table);
20922092
2093 coff.symbol_table.strings_ni = try coff_parent_ni.addHeaderChildAfter(&coff.mf, gpa, .wrap(coff.symbol_table.ni), .{
2093 coff.symbol_table.strings_ni = try coff_parent_ni.addHeaderChildAfter(gpa, &coff.mf, .wrap(coff.symbol_table.ni), .{
20942094 .size = @sizeOf(u32),
20952095 .resized = true,
20962096 });
......@@ -2143,7 +2143,7 @@ fn initHeaders(
21432143 coff.mf.flags.block_size,
21442144 .{ .read = true, .initialized = true },
21452145 )).symbol(coff).node(coff);
2146 coff.import_table.ni = try import_table_parent_ni.addFloatingChild(&coff.mf, gpa, .{
2146 coff.import_table.ni = try import_table_parent_ni.addFloatingChild(gpa, &coff.mf, .{
21472147 .alignment = .@"4",
21482148 });
21492149 coff.nodes.appendAssumeCapacity(.import_directory_table);
......@@ -2154,7 +2154,7 @@ fn initHeaders(
21542154 .{ .read = true, .initialized = true },
21552155 )).symbol(coff).node(coff);
21562156
2157 coff.export_table.export_directory_table_ni = try coff.export_table.ni.addHeaderChildAfter(&coff.mf, gpa, coff.export_table.ni.last(&coff.mf), .{
2157 coff.export_table.export_directory_table_ni = try coff.export_table.ni.addHeaderChildAfter(gpa, &coff.mf, coff.export_table.ni.last(&coff.mf), .{
21582158 .size = @sizeOf(std.coff.ExportDirectoryTable) + file_name.len + 1,
21592159 .moved = true,
21602160 });
......@@ -2165,7 +2165,7 @@ fn initHeaders(
21652165 @memcpy(table_slice[name_index..][0..file_name.len], file_name[0..file_name.len]);
21662166 @memset(table_slice[name_index + file_name.len ..], 0);
21672167
2168 const export_address_table_ni = try coff.export_table.ni.addFloatingChild(&coff.mf, gpa, .{
2168 const export_address_table_ni = try coff.export_table.ni.addFloatingChild(gpa, &coff.mf, .{
21692169 .alignment = .of(std.coff.ExportAddressTableEntry),
21702170 .moved = true,
21712171 });
......@@ -2181,19 +2181,19 @@ fn initHeaders(
21812181 export_address_table_sym.section_number =
21822182 coff.getNode(coff.export_table.ni).pseudo_section.symbol(coff).get(coff).section_number;
21832183
2184 coff.export_table.name_pointer_table_ni = try coff.export_table.ni.addFloatingChild(&coff.mf, gpa, .{
2184 coff.export_table.name_pointer_table_ni = try coff.export_table.ni.addFloatingChild(gpa, &coff.mf, .{
21852185 .alignment = .of(std.coff.ExportNamePointerTableEntry),
21862186 .moved = true,
21872187 });
21882188 coff.nodes.appendAssumeCapacity(.export_name_pointer_table);
21892189
2190 coff.export_table.ordinal_table_ni = try coff.export_table.ni.addFloatingChild(&coff.mf, gpa, .{
2190 coff.export_table.ordinal_table_ni = try coff.export_table.ni.addFloatingChild(gpa, &coff.mf, .{
21912191 .alignment = .of(std.coff.ExportOrdinalTableEntry),
21922192 .moved = true,
21932193 });
21942194 coff.nodes.appendAssumeCapacity(.export_ordinal_table);
21952195
2196 coff.export_table.name_table_ni = try coff.export_table.ni.addFloatingChild(&coff.mf, gpa, .{
2196 coff.export_table.name_table_ni = try coff.export_table.ni.addFloatingChild(gpa, &coff.mf, .{
21972197 .alignment = .of(u8),
21982198 .moved = true,
21992199 });
......@@ -2286,7 +2286,7 @@ pub fn initBuiltins(coff: *Coff) !void {
22862286 const list_len_si = try coff.globalSymbol(.{ .name = list.global, .type = .data });
22872287 const list_len_sym = list_len_si.get(coff);
22882288 list_len_sym.setExtra(.{ .size = addr_info.size });
2289 list_len_sym.ni = .wrap(try start_sym.ni.unwrap().?.addHeaderChildAfter(&coff.mf, gpa, .none, .{
2289 list_len_sym.ni = .wrap(try start_sym.ni.unwrap().?.addHeaderChildAfter(gpa, &coff.mf, .none, .{
22902290 .size = addr_info.size,
22912291 }));
22922292 coff.nodes.appendAssumeCapacity(.{ .builtin = list_len_si });
......@@ -2307,7 +2307,7 @@ pub fn initBuiltins(coff: *Coff) !void {
23072307 const list_end_si = coff.addSymbolAssumeCapacity();
23082308 const list_end_sym = list_end_si.get(coff);
23092309 list_end_sym.setExtra(.{ .size = addr_info.size });
2310 list_end_sym.ni = .wrap(try end_sym.ni.unwrap().?.addHeaderChildAfter(&coff.mf, gpa, .none, .{
2310 list_end_sym.ni = .wrap(try end_sym.ni.unwrap().?.addHeaderChildAfter(gpa, &coff.mf, .none, .{
23112311 .size = addr_info.size,
23122312 }));
23132313 coff.nodes.appendAssumeCapacity(.{ .builtin = list_end_si });
......@@ -2723,7 +2723,7 @@ fn getOrPutSymbolName(coff: *Coff, name: []const u8, opt_string: ?String) !Symbo
27232723 const string_index = coff.symbol_table.strings_ni.location(&coff.mf).resolve(&coff.mf)[1];
27242724 string_gop.value_ptr.* = @fromBackingInt(@intCast(string_index));
27252725
2726 try coff.symbol_table.strings_ni.resizeLeaf(&coff.mf, gpa, string_index + name.len + 1);
2726 try coff.symbol_table.strings_ni.resizeLeaf(gpa, &coff.mf, string_index + name.len + 1);
27272727 const slice = coff.symbol_table.strings_ni.slice(&coff.mf);
27282728 @memcpy(slice[@intCast(string_index)..][0..name.len], name);
27292729 slice[@intCast(string_index + name.len)] = 0;
......@@ -2948,7 +2948,7 @@ fn addMemberAssumeCapacity(coff: *Coff, kind: std.coff.ArchiveMemberHeader.Kind,
29482948 const comp = coff.base.comp;
29492949 const gpa = comp.gpa;
29502950
2951 const header_ni = try Node.known.file.addHeaderChildAfter(&coff.mf, gpa, Node.known.file.last(&coff.mf), .{
2951 const header_ni = try Node.known.file.addHeaderChildAfter(gpa, &coff.mf, Node.known.file.last(&coff.mf), .{
29522952 .size = @sizeOf(std.coff.ArchiveMemberHeader),
29532953 .alignment = .@"2",
29542954 .moved = true,
......@@ -2960,7 +2960,7 @@ fn addMemberAssumeCapacity(coff: *Coff, kind: std.coff.ArchiveMemberHeader.Kind,
29602960 .first_linker, .second_linker, .longnames, .coff => .@"4",
29612961 else => .@"2",
29622962 };
2963 const content_ni = try Node.known.file.addHeaderChildAfter(&coff.mf, gpa, .wrap(header_ni), .{
2963 const content_ni = try Node.known.file.addHeaderChildAfter(gpa, &coff.mf, .wrap(header_ni), .{
29642964 .alignment = content_align,
29652965 .size = content_align.forward(size),
29662966 .resized = size > 0,
......@@ -2989,7 +2989,7 @@ fn addMemberAssumeCapacity(coff: *Coff, kind: std.coff.ArchiveMemberHeader.Kind,
29892989 const old_size = Node.known.second_linker_member.location(&coff.mf).resolve(&coff.mf)[1];
29902990 const old_header_size = new_num_members * @sizeOf(u32);
29912991 const trailing_size: usize = @intCast(old_size - old_header_size);
2992 try Node.known.second_linker_member.resizeLeaf(&coff.mf, gpa, old_size + @sizeOf(u32));
2992 try Node.known.second_linker_member.resizeLeaf(gpa, &coff.mf, old_size + @sizeOf(u32));
29932993
29942994 const slice = Node.known.second_linker_member.slice(&coff.mf);
29952995 @memmove(
......@@ -3060,7 +3060,7 @@ fn ensureMemberSymbol(coff: *Coff, mi: Member.Index, name: String) !void {
30603060 {
30613061 const old_header_size: usize = @intCast(@sizeOf(u32) + @backingInt(mfli) * @sizeOf(u32));
30623062 const new_header_size: usize = @intCast(old_header_size + @sizeOf(u32));
3063 try Node.known.first_linker_member.resizeLeaf(&coff.mf, gpa, Alignment.@"4".forward(new_header_size + new_string_table_size));
3063 try Node.known.first_linker_member.resizeLeaf(gpa, &coff.mf, Alignment.@"4".forward(new_header_size + new_string_table_size));
30643064
30653065 const slice = Node.known.first_linker_member.slice(&coff.mf);
30663066 @memmove(slice[new_header_size..][0..coff.lib_string_len], slice[old_header_size..][0..coff.lib_string_len]);
......@@ -3074,7 +3074,7 @@ fn ensureMemberSymbol(coff: *Coff, mi: Member.Index, name: String) !void {
30743074 const num_members = coff.targetLoad(coff.secondLinkerMemberNumMembersPtr());
30753075 const old_header_size = 2 * @sizeOf(u32) + num_members * @sizeOf(u32) + @backingInt(mfli) * @sizeOf(u16);
30763076 const new_header_size = old_header_size + @sizeOf(u16);
3077 try Node.known.second_linker_member.resizeLeaf(&coff.mf, gpa, Alignment.@"4".forward(new_header_size + new_string_table_size));
3077 try Node.known.second_linker_member.resizeLeaf(gpa, &coff.mf, Alignment.@"4".forward(new_header_size + new_string_table_size));
30783078
30793079 const old_needs_sort = coff.pending_members.get(Member.Index.second) != null;
30803080 const needs_sort = old_needs_sort or (if (coff.lib_string_table.items.len > 0)
......@@ -3181,7 +3181,7 @@ fn flushSymbolTableEntry(coff: *Coff, index: u32) !void {
31813181 const new_num_symbols = old_num_symbols + 1 + num_aux_symbols;
31823182 coff.targetStore(&coff.headerPtr().number_of_symbols, new_num_symbols);
31833183
3184 try coff.symbol_table.ni.resizeLeaf(&coff.mf, gpa, new_num_symbols * std.coff.Symbol.sizeOf());
3184 try coff.symbol_table.ni.resizeLeaf(gpa, &coff.mf, new_num_symbols * std.coff.Symbol.sizeOf());
31853185
31863186 sti.* = .wrap(old_num_symbols);
31873187 si.flushSymbolTableIndex(coff);
......@@ -3317,7 +3317,7 @@ fn flushInputSection(coff: *Coff, isi: Node.InputSection.Index) !void {
33173317 try fr.seekTo(file_loc.offset);
33183318 var nw: MappedFile.Node.Writer = undefined;
33193319 const si = isi.symbol(coff);
3320 si.node(coff).writer(&coff.mf, gpa, &nw);
3320 si.node(coff).writer(gpa, &coff.mf, &nw);
33213321 defer nw.deinit();
33223322 log.debug("flushInputSection({f}{f}, {s}, {d}, n{d})", .{
33233323 path,
......@@ -3345,12 +3345,12 @@ fn addSection(coff: *Coff, name: String, flags: std.coff.SectionHeader.Flags) !S
33453345 const section_table_len = section_index + 1;
33463346 coff.targetStore(&coff_header.number_of_sections, section_table_len);
33473347 try Node.known.section_table.resizeLeaf(
3348 &coff.mf,
33493348 gpa,
3349 &coff.mf,
33503350 @sizeOf(std.coff.SectionHeader) * section_table_len,
33513351 );
33523352
3353 const ni = try coff.sectionParent().addFloatingChild(&coff.mf, gpa, .{
3353 const ni = try coff.sectionParent().addFloatingChild(gpa, &coff.mf, .{
33543354 .alignment = coff.mf.flags.block_size,
33553355 .moved = true,
33563356 .bubbles_moved = false,
......@@ -3486,7 +3486,7 @@ fn pseudoSectionMapIndex(
34863486
34873487 try coff.nodes.ensureUnusedCapacity(gpa, 1);
34883488 try coff.symbols.ensureUnusedCapacity(gpa, 1);
3489 const ni = try parent.node(coff).addFloatingChild(&coff.mf, gpa, .{ .alignment = alignment });
3489 const ni = try parent.node(coff).addFloatingChild(gpa, &coff.mf, .{ .alignment = alignment });
34903490 const si = coff.addSymbolAssumeCapacity();
34913491 pseudo_section_gop.value_ptr.* = si;
34923492 const sym = si.get(coff);
......@@ -3560,7 +3560,7 @@ fn objectSectionMapIndex(
35603560 }
35613561 }
35623562 }
3563 const ni = try parent_ni.addHeaderChildAfter(&coff.mf, gpa, prev_oni, .{
3563 const ni = try parent_ni.addHeaderChildAfter(gpa, &coff.mf, prev_oni, .{
35643564 .alignment = alignment,
35653565 });
35663566 const si = coff.addSymbolAssumeCapacity();
......@@ -3579,13 +3579,13 @@ fn objectSectionMapIndex(
35793579 const parent_alignment = parent_ni.alignment(&coff.mf);
35803580 if (alignment.compare(.gt, parent_alignment)) {
35813581 log.debug("realignParent({s}, {d}) {d}->{d}", .{ name.toSlice(coff), parent_ni, parent_alignment, alignment });
3582 try parent_ni.realign(&coff.mf, gpa, alignment);
3582 try parent_ni.realign(gpa, &coff.mf, alignment);
35833583 }
35843584
35853585 const old_alignment = sym.ni.unwrap().?.alignment(&coff.mf);
35863586 if (alignment.compare(.gt, old_alignment)) {
35873587 log.debug("realignObject({s}) {d}->{d}", .{ name.toSlice(coff), old_alignment, alignment });
3588 try sym.ni.unwrap().?.realign(&coff.mf, gpa, alignment);
3588 try sym.ni.unwrap().?.realign(gpa, &coff.mf, alignment);
35893589 }
35903590
35913591 try coff.verifyParentSectionAttributes(
......@@ -3742,9 +3742,9 @@ fn addRelocAssumeCapacity(
37423742 coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations);
37433743
37443744 if (section.relocation_table_ni.unwrap()) |relocation_table_ni| {
3745 try relocation_table_ni.resizeLeaf(&coff.mf, gpa, new_size);
3745 try relocation_table_ni.resizeLeaf(gpa, &coff.mf, new_size);
37463746 } else {
3747 section.relocation_table_ni = .wrap(try coff.sectionParent().addFloatingChild(&coff.mf, gpa, .{
3747 section.relocation_table_ni = .wrap(try coff.sectionParent().addFloatingChild(gpa, &coff.mf, .{
37483748 .size = new_size,
37493749 .alignment = .@"2",
37503750 .moved = true,
......@@ -4094,7 +4094,7 @@ fn loadObject(
40944094 {
40954095 // TODO: This should be deferred to an idle task (but resize it here!)
40964096 var nw: MappedFile.Node.Writer = undefined;
4097 member.content_ni.writer(&coff.mf, gpa, &nw);
4097 member.content_ni.writer(gpa, &coff.mf, &nw);
40984098 defer nw.deinit();
40994099
41004100 try fr.seekTo(fl.offset);
......@@ -4653,7 +4653,7 @@ fn loadObject(
46534653 if (section.parent_si == .null) continue;
46544654
46554655 const alignment: Alignment = .fromByteUnits(section.header.flags.ALIGN.toByteUnits() orelse 1);
4656 const ni = try section.parent_si.node(coff).addFloatingChild(&coff.mf, gpa, .{
4656 const ni = try section.parent_si.node(coff).addFloatingChild(gpa, &coff.mf, .{
46574657 .size = alignment.forward(section.header.size_of_raw_data),
46584658 .alignment = alignment,
46594659 .moved = true,
......@@ -5447,7 +5447,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
54475447 const sec_si = try coff.navSection(zcu, nav.resolved.?);
54485448 try coff.nodes.ensureUnusedCapacity(gpa, 1);
54495449 if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1);
5450 const ni = try sec_si.node(coff).addFloatingChild(&coff.mf, gpa, .{
5450 const ni = try sec_si.node(coff).addFloatingChild(gpa, &coff.mf, .{
54515451 .alignment = .fromIp(zcu.navAlignment(nav_index)),
54525452 .moved = true,
54535453 });
......@@ -5469,7 +5469,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
54695469
54705470 {
54715471 var nw: MappedFile.Node.Writer = undefined;
5472 ni.writer(&coff.mf, gpa, &nw);
5472 ni.writer(gpa, &coff.mf, &nw);
54735473 defer nw.deinit();
54745474 codegen.generateSymbol(
54755475 &coff.base,
......@@ -5486,7 +5486,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
54865486 }
54875487
54885488 if (nav.resolved.?.@"linksection".unwrap()) |_| {
5489 try ni.resizeLeaf(&coff.mf, gpa, si.get(coff).extra.size);
5489 try ni.resizeLeaf(gpa, &coff.mf, si.get(coff).extra.size);
54905490 }
54915491
54925492 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.
......@@ -5596,7 +5596,7 @@ fn updateFuncInner(
55965596 if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1);
55975597 const mod = zcu.navFileScope(func.owner_nav).mod.?;
55985598 const target = &mod.resolved_target.result;
5599 const ni = try sec_si.node(coff).addFloatingChild(&coff.mf, gpa, .{
5599 const ni = try sec_si.node(coff).addFloatingChild(gpa, &coff.mf, .{
56005600 .alignment = switch (nav.resolved.?.@"align") {
56015601 .none => switch (mod.optimize_mode) {
56025602 .debug,
......@@ -5625,7 +5625,7 @@ fn updateFuncInner(
56255625 };
56265626
56275627 var nw: MappedFile.Node.Writer = undefined;
5628 ni.writer(&coff.mf, gpa, &nw);
5628 ni.writer(gpa, &coff.mf, &nw);
56295629 defer nw.deinit();
56305630 codegen.emitFunction(
56315631 &coff.base,
......@@ -5904,8 +5904,8 @@ pub fn flush(
59045904
59055905 const number_of_symbols = coff.targetLoad(&coff.headerPtr().number_of_symbols);
59065906 coff.symbol_table.ni.resizeLeaf(
5907 &coff.mf,
59085907 comp.gpa,
5908 &coff.mf,
59095909 number_of_symbols * std.coff.Symbol.sizeOf(),
59105910 ) catch |err| switch (err) {
59115911 else => |e| return e,
......@@ -6072,17 +6072,18 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
60726072 };
60736073 break :task;
60746074 }
6075 while (coff.mf.updates.pop()) |ni| {
6075 while (coff.mf.updates.pop()) |ni| : (coff.mf.update_prog_node.completeOne()) {
6076 if (ni.pendingDelete(&coff.mf)) continue;
60766077 const clean_moved = ni.cleanMoved(&coff.mf);
60776078 const clean_resized = ni.cleanResized(&coff.mf);
6078 if (clean_moved or clean_resized) {
6079 const sub_prog_node =
6080 coff.idleProgNode(tid, coff.mf.update_prog_node, coff.getNode(ni));
6081 defer sub_prog_node.end();
6082 if (clean_moved) try coff.flushMoved(ni);
6083 if (clean_resized) try coff.flushResized(ni);
6084 break :task;
6085 } else coff.mf.update_prog_node.completeOne();
6079 const clean_next_moved = ni.cleanNextMoved(&coff.mf);
6080 if (!clean_moved and !clean_resized and !clean_next_moved) continue;
6081 const sub_prog_node =
6082 coff.idleProgNode(tid, coff.mf.update_prog_node, coff.getNode(ni));
6083 defer sub_prog_node.end();
6084 if (clean_moved) try coff.flushMoved(ni);
6085 if (clean_resized) try coff.flushResized(ni);
6086 break :task;
60866087 }
60876088 while (coff.pending_members.pop()) |pending_mi| {
60886089 const sub_prog_node = coff.idleProgNode(
......@@ -6210,7 +6211,7 @@ fn genUav(
62106211 try coff.nodes.ensureUnusedCapacity(gpa, 1);
62116212 if (!isImage(coff)) try coff.symbol_table.symbols.ensureUnusedCapacity(gpa, 1);
62126213 const sym = si.get(coff);
6213 const ni = try sec_si.node(coff).addFloatingChild(&coff.mf, gpa, .{
6214 const ni = try sec_si.node(coff).addFloatingChild(gpa, &coff.mf, .{
62146215 .alignment = .fromIp(uav_align),
62156216 .moved = true,
62166217 });
......@@ -6239,7 +6240,7 @@ fn genUav(
62396240 };
62406241
62416242 var nw: MappedFile.Node.Writer = undefined;
6242 ni.writer(&coff.mf, gpa, &nw);
6243 ni.writer(gpa, &coff.mf, &nw);
62436244 defer nw.deinit();
62446245 codegen.generateSymbol(
62456246 &coff.base,
......@@ -6503,19 +6504,19 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {
65036504 if (!gop.found_existing) {
65046505 errdefer _ = coff.import_table.entries.pop();
65056506 try coff.import_table.ni.resizeLeaf(
6506 &coff.mf,
65076507 gpa,
6508 &coff.mf,
65086509 @sizeOf(std.coff.ImportDirectoryEntry) * (gop.index + 2),
65096510 );
65106511 const import_hint_name_table_len =
65116512 import_hint_name_align.forward(lib_name.len + ".dll".len + 1);
65126513 const idata_section_ni = coff.import_table.ni.parent(&coff.mf).unwrap().?;
6513 const import_lookup_table_ni = try idata_section_ni.addFloatingChild(&coff.mf, gpa, .{
6514 const import_lookup_table_ni = try idata_section_ni.addFloatingChild(gpa, &coff.mf, .{
65146515 .size = addr_info.size * 2,
65156516 .alignment = addr_info.alignment,
65166517 .moved = true,
65176518 });
6518 const import_address_table_ni = try idata_section_ni.addFloatingChild(&coff.mf, gpa, .{
6519 const import_address_table_ni = try idata_section_ni.addFloatingChild(gpa, &coff.mf, .{
65196520 .size = addr_info.size * 2,
65206521 .alignment = addr_info.alignment,
65216522 .moved = true,
......@@ -6529,7 +6530,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {
65296530 import_address_table_sym.section_number =
65306531 coff.getNode(idata_section_ni).object_section.symbol(coff).get(coff).section_number;
65316532 }
6532 const import_hint_name_table_ni = try idata_section_ni.addFloatingChild(&coff.mf, gpa, .{
6533 const import_hint_name_table_ni = try idata_section_ni.addFloatingChild(gpa, &coff.mf, .{
65336534 .size = import_hint_name_table_len,
65346535 .alignment = import_hint_name_align,
65356536 .moved = true,
......@@ -6585,9 +6586,9 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {
65856586 gop.value_ptr.len = import_symbol_index + 1;
65866587 const new_symbol_table_size = addr_info.size * (import_symbol_index + 2);
65876588
6588 try gop.value_ptr.import_lookup_table_ni.resizeLeaf(&coff.mf, gpa, new_symbol_table_size);
6589 try gop.value_ptr.import_lookup_table_ni.resizeLeaf(gpa, &coff.mf, new_symbol_table_size);
65896590 const import_address_table_ni = gop.value_ptr.import_address_table_si.node(coff);
6590 try import_address_table_ni.resizeLeaf(&coff.mf, gpa, new_symbol_table_size);
6591 try import_address_table_ni.resizeLeaf(gpa, &coff.mf, new_symbol_table_size);
65916592
65926593 const opt_imp_name = import.name.toSlice(coff);
65936594 const opt_import_hint_name_index = if (opt_imp_name) |imp_name| blk: {
......@@ -6595,7 +6596,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {
65956596 gop.value_ptr.hint_name_len = @intCast(
65966597 import_hint_name_align.forward(import_hint_name_index + 2 + imp_name.len + 1),
65976598 );
6598 try gop.value_ptr.import_hint_name_table_ni.resizeLeaf(&coff.mf, gpa, gop.value_ptr.hint_name_len);
6599 try gop.value_ptr.import_hint_name_table_ni.resizeLeaf(gpa, &coff.mf, gop.value_ptr.hint_name_len);
65996600 break :blk import_hint_name_index;
66006601 } else null;
66016602
......@@ -6670,7 +6671,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {
66706671 else => |tag| @panic(@tagName(tag)),
66716672 .AMD64 => {
66726673 const init = [_]u8{ 0xff, 0x25, 0x00, 0x00, 0x00, 0x00 };
6673 const ni = try parent_sym.ni.unwrap().?.addFloatingChild(&coff.mf, gpa, .{
6674 const ni = try parent_sym.ni.unwrap().?.addFloatingChild(gpa, &coff.mf, .{
66746675 .alignment = alignment,
66756676 .size = alignment.forward(init.len),
66766677 });
......@@ -6823,7 +6824,7 @@ fn genLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
68236824 .code => .text,
68246825 .const_data => .rdata,
68256826 };
6826 const ni = try sec_si.node(coff).addFloatingChild(&coff.mf, gpa, .{ .moved = true });
6827 const ni = try sec_si.node(coff).addFloatingChild(gpa, &coff.mf, .{ .moved = true });
68276828 coff.nodes.appendAssumeCapacity(switch (lazy.kind) {
68286829 .code => .{ .lazy_code = @fromBackingInt(@intCast(lmr.index)) },
68296830 .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(lmr.index)) },
......@@ -6843,7 +6844,7 @@ fn genLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
68436844
68446845 var required_alignment: InternPool.Alignment = .none;
68456846 var nw: MappedFile.Node.Writer = undefined;
6846 ni.writer(&coff.mf, gpa, &nw);
6847 ni.writer(gpa, &coff.mf, &nw);
68476848 defer nw.deinit();
68486849 codegen.generateLazySymbol(
68496850 &coff.base,
......@@ -7479,7 +7480,7 @@ fn updateExportInner(
74797480 if (new_name_table_size > std.math.maxInt(@FieldType(ExportTable.Entry, "name_index")))
74807481 return coff.base.comp.link_diags.fail("exports name table limit reached", .{});
74817482
7482 try coff.export_table.name_table_ni.resizeLeaf(&coff.mf, gpa, new_name_table_size);
7483 try coff.export_table.name_table_ni.resizeLeaf(gpa, &coff.mf, new_name_table_size);
74837484
74847485 const name_table_slice = coff.export_table.name_table_ni.slice(&coff.mf);
74857486 @memcpy(name_table_slice[name_index..][0 .. name.len + 1], name[0 .. name.len + 1]);
......@@ -7503,20 +7504,20 @@ fn updateExportInner(
75037504 // TODO: These should all be resized ahead of time to fit all exports
75047505 // after https://github.com/ziglang/zig/issues/23616
75057506 try coff.export_table.export_address_table_si.node(coff).resizeLeaf(
7506 &coff.mf,
75077507 gpa,
7508 &coff.mf,
75087509 export_count * @sizeOf(std.coff.ExportAddressTableEntry),
75097510 );
75107511
75117512 try coff.export_table.name_pointer_table_ni.resizeLeaf(
7512 &coff.mf,
75137513 gpa,
7514 &coff.mf,
75147515 export_count * @sizeOf(std.coff.ExportNamePointerTableEntry),
75157516 );
75167517
75177518 try coff.export_table.ordinal_table_ni.resizeLeaf(
7518 &coff.mf,
75197519 gpa,
7520 &coff.mf,
75207521 export_count * @sizeOf(std.coff.ExportOrdinalTableEntry),
75217522 );
75227523
src/link/Dwarf2.zig+73-43
......@@ -8,7 +8,7 @@ units: std.array_hash_map.Auto(*Module, Unit),
88/// Indices are `link.ConstPool.Index`.
99values: std.ArrayList(Value),
1010globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),
11funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func),
11funcs: std.array_hash_map.Auto(InternPool.TrackedInst.Index, Func),
1212
1313debug_abbrev: Abbrev,
1414frame: Frame,
......@@ -123,6 +123,7 @@ pub const Global = struct {
123123};
124124
125125pub const Func = struct {
126 owner_nav: InternPool.Nav.Index,
126127 fde_ni: MappedFile.Node.Index.Optional,
127128 debug_info_ni: MappedFile.Node.Index.Optional,
128129 debug_line_ni: MappedFile.Node.Index.Optional,
......@@ -130,7 +131,7 @@ pub const Func = struct {
130131 pub const Index = enum(u32) {
131132 _,
132133
133 pub fn nav(fi: Func.Index, dwarf: *Dwarf) InternPool.Nav.Index {
134 pub fn srcInst(fi: Func.Index, dwarf: *Dwarf) InternPool.TrackedInst.Index {
134135 return dwarf.funcs.keys()[@backingInt(fi)];
135136 }
136137
......@@ -195,7 +196,7 @@ pub const Str = struct {
195196 );
196197 if (!gop.found_existing) {
197198 gop.key_ptr.* = s.offset;
198 try ni.ensureMinimumSize(mf, gpa, s.offset + str.len + 1);
199 try ni.ensureMinimumSize(gpa, mf, s.offset + str.len + 1);
199200 const slice_mut = ni.slice(mf);
200201 @memcpy(slice_mut[s.offset..][0..str.len], str);
201202 s.offset += str.len;
......@@ -635,9 +636,15 @@ pub const WipNav = struct {
635636 const dwarf = debug.wip_nav.dwarf;
636637 const zcu = debug.pt.zcu;
637638 const ip = &zcu.intern_pool;
638 const nav = ip.getNav(zcu.funcInfo(debug.wip_nav.func).owner_nav);
639 const func = zcu.funcInfo(debug.wip_nav.func);
640 const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?;
641 const decl = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst);
642 const nav = ip.getNav(func.owner_nav);
639643 const diw = &debug.info_writer.interface;
640644 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func));
645 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
646 try diw.writeUleb128(decl.src_column + 1);
647 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
641648 try debug.strp(nav.name.toSlice(ip));
642649 try debug.strp(nav.fqn.toSlice(ip));
643650 try dwarf.symbolAddress(&debug.info_writer, debug.wip_nav.func_si, 0);
......@@ -657,9 +664,8 @@ pub const WipNav = struct {
657664 const zcu = debug.pt.zcu;
658665 const ip = &zcu.intern_pool;
659666 const func = zcu.funcInfo(debug.wip_nav.func);
660 const zfi = zcu.navFileScopeIndex(func.owner_nav);
661 const zf = zcu.fileByIndex(zfi);
662667 const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?;
668 const zf = zcu.fileByIndex(inst_info.file);
663669 const decl = zf.zir.?.getDeclaration(inst_info.inst);
664670 const dlw = &debug.line_writer.interface;
665671 try dlw.writeByte(DW.LNS.extended_op);
......@@ -678,7 +684,7 @@ pub const WipNav = struct {
678684 try dwarf.symbolAddress(&debug.line_writer, debug.wip_nav.func_si, 0);
679685
680686 const unit = dwarf.getUnit(zf.mod.?);
681 _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, zfi);
687 _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, inst_info.file);
682688 try dlw.writeByte(DW.LNS.set_file);
683689 try dlw.writeUleb128(@backingInt(fi));
684690
......@@ -928,7 +934,7 @@ pub const WipNav = struct {
928934 }
929935 fn leaveBlockInner(debug: *Debug, code_off: usize) link.EmitError!void {
930936 const dwarf = debug.wip_nav.dwarf;
931 const block_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.block));
937 const block_bytes = comptime uleb128Size(@backingInt(AbbrevCode.block));
932938 const block = debug.blocks.pop().?;
933939 if (debug.any_children)
934940 try debug.info_writer.interface.writeUleb128(@backingInt(AbbrevCode.null))
......@@ -1000,7 +1006,7 @@ pub const WipNav = struct {
10001006 code_off: usize,
10011007 ) link.EmitError!void {
10021008 const dwarf = debug.wip_nav.dwarf;
1003 const inlined_func_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.inlined_func));
1009 const inlined_func_bytes = comptime uleb128Size(@backingInt(AbbrevCode.inlined_func));
10041010 const block = debug.blocks.pop().?;
10051011 const diw = &debug.info_writer.interface;
10061012 if (debug.any_children)
......@@ -1029,14 +1035,14 @@ pub const WipNav = struct {
10291035 }
10301036 fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) link.EmitError!void {
10311037 const zcu = debug.pt.zcu;
1038 const ip = &zcu.intern_pool;
10321039 const dwarf = debug.wip_nav.dwarf;
10331040 if (debug.wip_nav.func == func) return;
10341041
1035 const new_func_info = zcu.funcInfo(func);
1036
1042 const new_owner_nav = zcu.funcInfo(func).owner_nav;
10371043 const dlw = &debug.line_writer.interface;
10381044 if (zcu.comp.config.incremental) {
1039 const new_func = try dwarf.getFunc(new_func_info.owner_nav);
1045 const new_func = try dwarf.getFunc(new_owner_nav);
10401046 try dlw.writeByte(DW.LNS.extended_op);
10411047 try dlw.writeUleb128(1 + dwarf.sectionOffsetSize());
10421048 try dlw.writeByte(DW.LNE.ZIG_set_decl);
......@@ -1048,19 +1054,22 @@ pub const WipNav = struct {
10481054 return;
10491055 }
10501056
1051 const old_func_info = zcu.funcInfo(debug.wip_nav.func);
1052 const old_zfi = zcu.navFileScopeIndex(old_func_info.owner_nav);
1053 const new_zfi = zcu.navFileScopeIndex(new_func_info.owner_nav);
1054 if (old_zfi != new_zfi) {
1055 const new_ui = dwarf.getUnit(zcu.fileByIndex(new_zfi).mod.?);
1056 _, const new_fi = try debug.wip_nav.unit.get(dwarf).getFile(zcu.gpa, new_ui, new_zfi);
1057 const old_owner_nav = zcu.funcInfo(debug.wip_nav.func).owner_nav;
1058 const old_inst_info = ip.getNav(old_owner_nav).srcInst(ip).resolveFull(ip).?;
1059 const old_file = zcu.fileByIndex(old_inst_info.file);
1060 const new_inst_info = ip.getNav(new_owner_nav).srcInst(ip).resolveFull(ip).?;
1061 const new_file = zcu.fileByIndex(new_inst_info.file);
1062 if (old_inst_info.file != new_inst_info.file) {
1063 const new_ui = dwarf.getUnit(new_file.mod.?);
1064 _, const new_fi =
1065 try debug.wip_nav.unit.get(dwarf).getFile(zcu.gpa, new_ui, new_inst_info.file);
10571066
10581067 try dlw.writeByte(DW.LNS.set_file);
10591068 try dlw.writeUleb128(@backingInt(new_fi));
10601069 }
10611070
1062 const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav);
1063 const new_src_line: i33 = zcu.navSrcLine(new_func_info.owner_nav);
1071 const old_src_line: i33 = old_file.zir.?.getDeclaration(old_inst_info.inst).src_line;
1072 const new_src_line: i33 = new_file.zir.?.getDeclaration(new_inst_info.inst).src_line;
10641073 if (new_src_line != old_src_line) {
10651074 try dlw.writeByte(DW.LNS.advance_line);
10661075 try dlw.writeSleb128(new_src_line - old_src_line);
......@@ -1435,10 +1444,12 @@ pub fn deinit(dwarf: *Dwarf) void {
14351444}
14361445
14371446pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {
1438 try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count());
1447 try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count() - dwarf.units.count());
14391448 for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, root| if (root.unwrap()) |root_zfi| {
1449 if (!zcu.alive_files.contains(root_zfi)) continue;
1450 assert(zcu.fileByIndex(root_zfi).mod != null);
14401451 const unit_gop = dwarf.units.getOrPutAssumeCapacity(mod);
1441 assert(!unit_gop.found_existing);
1452 if (unit_gop.found_existing) continue;
14421453 unit_gop.value_ptr.* = .{
14431454 .dirs = .empty,
14441455 .files = .empty,
......@@ -1468,8 +1479,12 @@ pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {
14681479pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.Index {
14691480 const comp = dwarf.lf.comp;
14701481 const gpa = comp.gpa;
1471 const func_gop = try dwarf.funcs.getOrPut(gpa, owner_nav);
1482 const zcu = comp.zcu.?;
1483 const ip = &zcu.intern_pool;
1484 const src_inst = ip.getNav(owner_nav).srcInst(ip);
1485 const func_gop = try dwarf.funcs.getOrPut(gpa, src_inst);
14721486 if (!func_gop.found_existing) func_gop.value_ptr.* = .{
1487 .owner_nav = owner_nav,
14731488 .fde_ni = .none,
14741489 .debug_info_ni = .none,
14751490 .debug_line_ni = .none,
......@@ -1479,17 +1494,18 @@ pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.I
14791494 const elf = dwarf.lf.cast(.elf2).?;
14801495 try elf.nodes.ensureUnusedCapacity(gpa, 1);
14811496 try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1);
1482 const unit = dwarf.getUnit(comp.zcu.?.navFileScope(owner_nav).mod.?).get(dwarf);
1483 func_gop.value_ptr.debug_info_ni =
1484 .wrap(unit.debug_info_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{
1497 const unit = dwarf.getUnit(zcu.fileByIndex(src_inst.resolveFile(ip)).mod.?).get(dwarf);
1498 func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(
1499 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
14851500 .enable_next_moved = true,
14861501 }) catch |err| switch (err) {
14871502 else => |e| return e,
14881503 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
14891504 elf.mf.io_err.?,
14901505 }),
1491 });
1492 elf.nodes.appendAssumeCapacity(.{ .func_debug_info = fi });
1506 },
1507 .{ .func_debug_info = fi },
1508 ));
14931509 elf.dwarf_funcs.addOneAssumeCapacity().* = .{
14941510 .frame_fde_first_symbol_reloc = .none,
14951511 .frame_fde_first_node_reloc = .none,
......@@ -1503,7 +1519,9 @@ pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.I
15031519 return fi;
15041520}
15051521pub fn getFuncIfExists(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) ?Func.Index {
1506 return @fromBackingInt(@intCast(dwarf.funcs.getIndex(owner_nav) orelse return null));
1522 const ip = &dwarf.lf.comp.zcu.?.intern_pool;
1523 return @fromBackingInt(@intCast(dwarf.funcs.getIndex(ip.getNav(owner_nav).srcInst(ip)) orelse
1524 return null));
15071525}
15081526
15091527pub fn unitLengthSize(dwarf: *Dwarf) usize {
......@@ -1797,20 +1815,20 @@ pub fn genDebugLineHeader(
17971815 try dlhw.writeUleb128(DW.FORM.line_strp);
17981816 try dlhw.writeUleb128(unit.files.count());
17991817 for (unit.files.keys()) |zfi| {
1800 const zcu_file = zcu.fileByIndex(zfi);
1801 try dwarf.strp(&dwarf.debug_line_str, dlh_nw, zcu_file.sub_file_path);
1818 const zf = zcu.fileByIndex(zfi);
1819 try dwarf.strp(&dwarf.debug_line_str, dlh_nw, zf.sub_file_path);
18021820 switch (directory_index_form) {
18031821 else => unreachable,
18041822 .data1 => try dlhw.writeByte(0),
18051823 .data2 => try dlhw.writeInt(u16, 0, dwarf.endian),
18061824 .udata => try dlhw.writeUleb128(0),
18071825 }
1808 try dlhw.writeInt(i64, @truncate(zcu_file.stat.mtime.nanoseconds), dwarf.endian);
1809 try dlhw.writeInt(u64, zcu_file.stat.size, dwarf.endian);
1826 try dlhw.writeInt(i64, @truncate(zf.stat.mtime.nanoseconds), dwarf.endian);
1827 try dlhw.writeInt(u64, zf.stat.size, dwarf.endian);
18101828 try dwarf.strp(
18111829 &dwarf.debug_line_str,
18121830 dlh_nw,
1813 if (zcu_file.is_builtin) zcu_file.source.? else "",
1831 if (zf.is_builtin) zf.source.? else "",
18141832 );
18151833 }
18161834 switch (dwarf.format) {
......@@ -1892,6 +1910,18 @@ pub fn genDebugRnglists(
18921910 try drw.writeByte(DW.RLE.end_of_list);
18931911}
18941912
1913pub fn updateLineNumber(
1914 dwarf: *Dwarf,
1915 zcu: *Zcu,
1916 src_inst: InternPool.TrackedInst.Index,
1917 debug_info: []u8,
1918) void {
1919 const inst_info = src_inst.resolveFull(&zcu.intern_pool).?;
1920 assert(inst_info.inst != .main_struct_inst);
1921 const src_line = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst).src_line;
1922 std.mem.writeInt(u32, debug_info[AbbrevCode.decl_bytes..][0..4], src_line + 1, dwarf.endian);
1923}
1924
18951925fn refAbbrevCodeIfExists(
18961926 dwarf: *Dwarf,
18971927 abbrev_code: AbbrevCode,
......@@ -1911,7 +1941,7 @@ fn refAbbrevCode(
19111941 const elf = dwarf.lf.cast(.elf2).?;
19121942 const comp = elf.base.comp;
19131943 var nw: MappedFile.Node.Writer = undefined;
1914 dwarf.debug_abbrev.ni.unwrap().?.writer(&elf.mf, comp.gpa, &nw);
1944 dwarf.debug_abbrev.ni.unwrap().?.writer(comp.gpa, &elf.mf, &nw);
19151945 defer nw.deinit();
19161946 const abbrev = AbbrevCode.abbrevs.get(abbrev_code);
19171947 const daw = &nw.interface;
......@@ -2133,11 +2163,11 @@ pub const AbbrevCode = enum {
21332163 comptime_value_elem_runtime_bits,
21342164 comptime_value_elem_comptime_state,
21352165
2136 const decl_bytes = uleb128Bytes(@backingInt(AbbrevCode.decl_instance_extern_func));
2166 const decl_bytes = uleb128Size(@backingInt(AbbrevCode.decl_instance_extern_func));
21372167 comptime {
2138 assert(uleb128Bytes(@backingInt(AbbrevCode.pad_1)) == 1);
2139 assert(uleb128Bytes(@backingInt(AbbrevCode.pad_n)) == 1);
2140 assert(uleb128Bytes(@backingInt(AbbrevCode.decl_alias)) == decl_bytes);
2168 assert(uleb128Size(@backingInt(AbbrevCode.pad_1)) == 1);
2169 assert(uleb128Size(@backingInt(AbbrevCode.pad_n)) == 1);
2170 assert(uleb128Size(@backingInt(AbbrevCode.decl_alias)) == decl_bytes);
21412171 }
21422172
21432173 const Attr = struct {
......@@ -2145,7 +2175,7 @@ pub const AbbrevCode = enum {
21452175 DeclValEnum(DW.FORM),
21462176 };
21472177 const decl_abbrev_common_attrs = &[_]Attr{
2148 .{ .ZIG_parent, .ref_addr },
2178 //.{ .ZIG_parent, .ref_addr },
21492179 .{ .decl_line, .data4 },
21502180 .{ .decl_column, .udata },
21512181 .{ .accessibility, .data1 },
......@@ -2292,7 +2322,7 @@ pub const AbbrevCode = enum {
22922322 .decl_func = .{
22932323 .tag = .subprogram,
22942324 .children = true,
2295 .attrs = decl_abbrev_common_attrs[4..] ++ .{
2325 .attrs = decl_abbrev_common_attrs ++ .{
22962326 .{ .linkage_name, .strp },
22972327 //.{ .type, .ref_addr },
22982328 .{ .low_pc, .addr },
......@@ -3197,14 +3227,14 @@ pub const AbbrevCode = enum {
31973227 });
31983228};
31993229
3200pub fn uleb128Bytes(value: anytype) u32 {
3230pub fn uleb128Size(value: anytype) u32 {
32013231 var buf: [64]u8 = undefined;
32023232 var dw: Writer.Discarding = .init(&buf);
32033233 dw.writer.writeUleb128(value) catch unreachable;
32043234 return @intCast(dw.fullCount());
32053235}
32063236
3207pub fn sleb128Bytes(value: anytype) u32 {
3237pub fn sleb128Size(value: anytype) u32 {
32083238 var buf: [64]u8 = undefined;
32093239 var dw: Writer.Discarding = .init(&buf);
32103240 dw.writer.writeSleb128(value) catch unreachable;
src/link/Elf2.zig+394-340
......@@ -253,6 +253,8 @@ input_prog_node: std.Progress.Node,
253253const Error = link.Error || error{MappedFileIo};
254254
255255const Node = union(enum) {
256 deleted,
257
256258 /// Only used when emitting a static library.
257259 ///
258260 /// Contains a header node which is an `.archive_header`.
......@@ -642,7 +644,7 @@ const Section = struct {
642644 }
643645 const ni = shndx.get(elf).ni;
644646 if (min_align.compare(.gt, ni.alignment(&elf.mf))) {
645 try ni.realign(&elf.mf, elf.base.comp.gpa, min_align);
647 try ni.realign(elf.base.comp.gpa, &elf.mf, min_align);
646648 }
647649 switch (elf.getNode(ni.parent(&elf.mf).unwrap().?)) {
648650 .elf => {},
......@@ -675,7 +677,7 @@ const Section = struct {
675677 break :need_size cur_size + need_additional * ent_size;
676678 },
677679 };
678 try node.ensureMinimumSize(&elf.mf, elf.base.comp.gpa, need_size);
680 try node.ensureMinimumSize(elf.base.comp.gpa, &elf.mf, need_size);
679681 }
680682
681683 /// Asserts that `rela_shndx` is a `SHT_RELA` section and deletes the `ElfN.Rela` entry at
......@@ -2094,7 +2096,7 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe
20942096 const need_node_size: u64 = switch (elf.shdrPtr(.symtab)) {
20952097 inline else => |shdr, class| elf.targetLoad(&shdr.size) + len * @sizeOf(class.ElfN().Sym),
20962098 };
2097 try Section.Index.symtab.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_node_size);
2099 try Section.Index.symtab.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_node_size);
20982100 }
20992101
21002102 switch (kind) {
......@@ -2117,7 +2119,7 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe
21172119 const dynsym_cur_len: u32 = @intCast(@divExact(dynsym_cur_size, dynsym_ent_size));
21182120
21192121 const dynsym_need_size: u64 = (dynsym_cur_len + len) * dynsym_ent_size;
2120 try elf.shndx.dynsym.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, dynsym_need_size);
2122 try elf.shndx.dynsym.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, dynsym_need_size);
21212123
21222124 try elf.ensureDynsymHashCapacity(dynsym_cur_len + len);
21232125
......@@ -2150,7 +2152,7 @@ fn ensureDynsymHashCapacity(elf: *Elf, max_dynsym_count: u32) Error!void {
21502152 // We don't need to add any buckets, but we still need to make sure the section is large
21512153 // enough to fit `max_dynsym_count` chains.
21522154 const need_size = @sizeOf(info.Header()) + (nbucket + max_dynsym_count) * 4;
2153 try elf.shndx.hash.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size);
2155 try elf.shndx.hash.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size);
21542156 return;
21552157 }
21562158 // We need more buckets, so we'll have to rebuild the hash table.
......@@ -2162,7 +2164,7 @@ fn ensureDynsymHashCapacity(elf: *Elf, max_dynsym_count: u32) Error!void {
21622164
21632165 {
21642166 const need_size = @sizeOf(info.Header()) + (new_nbucket + max_dynsym_count) * 4;
2165 try elf.shndx.hash.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size);
2167 try elf.shndx.hash.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size);
21662168 }
21672169
21682170 elf.mf.nodes_lock.lock();
......@@ -2306,19 +2308,19 @@ fn ensureUnusedPltCapacity(elf: *Elf, len: u32) Error!void {
23062308 // Ensure the `.plt` section's node is big enough:
23072309 {
23082310 const need_size: usize = plt.entry_size * (1 + need_plt_count);
2309 try elf.shndx.plt.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size);
2311 try elf.shndx.plt.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size);
23102312 }
23112313
23122314 // If there is a `.got.plt` section, ensure its node is big enough
23132315 if (plt.got_plt) |got_plt| {
23142316 const need_size: usize = elf.targetPtrSize() * (got_plt.header_entries + need_plt_count);
2315 try elf.shndx.got_plt.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size);
2317 try elf.shndx.got_plt.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size);
23162318 }
23172319
23182320 // If there is a `.plt.sec` section, ensure its node is big enough
23192321 if (plt.plt_sec) |plt_sec| {
23202322 const need_size: usize = plt_sec.entry_size * need_plt_count;
2321 try elf.shndx.plt_sec.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_size);
2323 try elf.shndx.plt_sec.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_size);
23222324 }
23232325}
23242326/// Given an index into the PLT, returns whether that PLT entry is dead, meaning it may be reused at
......@@ -3244,6 +3246,7 @@ fn classifySymbolValue(elf: *Elf, sym: Symbol.Id) enum {
32443246
32453247pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
32463248 const lsi: Symbol.LocalIndex = switch (elf.getNode(Node.fromAtom(atom))) {
3249 .deleted,
32473250 .archive,
32483251 .archive_header,
32493252 .archive_input_member,
......@@ -3305,7 +3308,13 @@ fn lazySymbolInner(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol) Err
33053308 .code => .{ .text, .FUNC },
33063309 .const_data => .{ .rodata, .OBJECT },
33073310 };
3308 const node = try shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{});
3311 const node = elf.addNodeAssumeCapacity(
3312 try shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
3313 switch (lazy.kind) {
3314 .code => .{ .lazy_code = @fromBackingInt(@intCast(gop.index)) },
3315 .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(gop.index)) },
3316 },
3317 );
33093318 var name_buf: [std.fmt.count("__lazy_const_data_{d}", .{std.math.maxInt(u32)})]u8 = undefined;
33103319 const name = std.mem.print(&name_buf, "__lazy_{t}_{d}", .{ lazy.kind, gop.index }) catch
33113320 unreachable;
......@@ -3321,10 +3330,6 @@ fn lazySymbolInner(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol) Err
33213330 .first_symbol_reloc = .none,
33223331 .first_got_reloc = .none,
33233332 };
3324 elf.nodes.appendAssumeCapacity(switch (lazy.kind) {
3325 .code => .{ .lazy_code = @fromBackingInt(@intCast(gop.index)) },
3326 .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(gop.index)) },
3327 });
33283333 elf.base.comp.link_prog_node.increaseEstimatedTotalItems(1);
33293334 }
33303335 const s: Symbol.Id = .local(gop.value_ptr.lsi);
......@@ -3583,7 +3588,7 @@ const StringTable = struct {
35833588 break :size .{ old_size, new_size };
35843589 },
35853590 };
3586 try ni.ensureMinimumSize(&elf.mf, gpa, new_size);
3591 try ni.ensureMinimumSize(gpa, &elf.mf, new_size);
35873592 const slice = ni.slice(&elf.mf)[old_size..];
35883593 @memcpy(slice[0..key.len], key);
35893594 slice[key.len] = 0;
......@@ -4014,21 +4019,21 @@ fn initHeaders(
40144019 try elf.symtab.ensureTotalCapacity(gpa, 1);
40154020
40164021 if (is_archive) {
4017 elf.nodes.appendAssumeCapacity(.archive);
4018
4019 const archive_ni: MappedFile.Node.Index = .root;
4020
4021 const archive_header_ni = try archive_ni.addOnlyHeaderChild(&elf.mf, gpa, .{
4022 // We intentionally do not set `.alignment = .@"2"` here, because the string table data
4023 // in this node does not need to have an aligned length. (This node's offset is aligned
4024 // regardless by virtue of it being a header.)
4025 .size = std.elf.ARMAG.len + @sizeOf(std.elf.ar_hdr),
4026 // The archive header uses 'next_moved' events to resize the "//" member, so that it
4027 // absorbs all padding between `archive_header_ni` and the actual object file members.
4028 .enable_next_moved = true,
4029 .next_moved = true,
4030 });
4031 elf.nodes.appendAssumeCapacity(.archive_header);
4022 const archive_ni = elf.addNodeAssumeCapacity(.root, .archive);
4023
4024 const archive_header_ni = elf.addNodeAssumeCapacity(
4025 try archive_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
4026 // We intentionally do not set `.alignment = .@"2"` here, because the string table data
4027 // in this node does not need to have an aligned length. (This node's offset is aligned
4028 // regardless by virtue of it being a header.)
4029 .size = std.elf.ARMAG.len + @sizeOf(std.elf.ar_hdr),
4030 // The archive header uses 'next_moved' events to resize the "//" member, so that it
4031 // absorbs all padding between `archive_header_ni` and the actual object file members.
4032 .enable_next_moved = true,
4033 .next_moved = true,
4034 }),
4035 .archive_header,
4036 );
40324037 const archive_header_slice = archive_header_ni.slice(&elf.mf);
40334038 @memcpy(archive_header_slice[0..std.elf.ARMAG.len], std.elf.ARMAG);
40344039 const strtab_ar_hdr: *std.elf.ar_hdr = @ptrCast(archive_header_slice[std.elf.ARMAG.len..]);
......@@ -4042,18 +4047,19 @@ fn initHeaders(
40424047 .ar_fmag = std.elf.ARFMAG.*,
40434048 };
40444049
4045 elf.ni.elf = try archive_ni.addOnlyFooterChild(&elf.mf, gpa, .{
4050 elf.ni.elf = elf.addNodeAssumeCapacity(try archive_ni.addOnlyFooterChild(gpa, &elf.mf, .{
40464051 .alignment = node_block_align.max(.@"2"),
40474052 .bubbles_moved = false,
40484053 .resized = true, // ensure that this node's `ar_hdr.ar_size` is updated at least once
4049 });
4050 elf.nodes.appendAssumeCapacity(.elf);
4054 }), .elf);
40514055
4052 const elf_ar_hdr_ni = try archive_ni.addFooterChildBefore(&elf.mf, gpa, .wrap(elf.ni.elf), .{
4053 .alignment = .@"2",
4054 .size = @sizeOf(std.elf.ar_hdr),
4055 });
4056 elf.nodes.appendAssumeCapacity(.archive_elf_member_header);
4056 const elf_ar_hdr_ni = elf.addNodeAssumeCapacity(
4057 try archive_ni.addFooterChildBefore(gpa, &elf.mf, .wrap(elf.ni.elf), .{
4058 .alignment = .@"2",
4059 .size = @sizeOf(std.elf.ar_hdr),
4060 }),
4061 .archive_elf_member_header,
4062 );
40574063
40584064 // Must be populated before we call `populateArchiveMemberName` below.
40594065 elf.archive = .{
......@@ -4079,10 +4085,7 @@ fn initHeaders(
40794085 defer gpa.free(zcu_member_name);
40804086 // After this call returns, `elf_ar_hdr` is invalidated.
40814087 try elf.populateArchiveMemberName(elf_ar_hdr, zcu_member_name);
4082 } else {
4083 elf.ni.elf = .root;
4084 elf.nodes.appendAssumeCapacity(.elf);
4085 }
4088 } else elf.ni.elf = elf.addNodeAssumeCapacity(.root, .elf);
40864089
40874090 const entsize: struct { ph: u32, sh: u32 } = switch (class) {
40884091 .NONE, _ => unreachable,
......@@ -4098,69 +4101,65 @@ fn initHeaders(
40984101 if (@"type" != .REL) {
40994102 // This node will contain the ehdr, which must be at the start of the ELF file, so this
41004103 // node must itself be a header of the `.elf` node.
4101 elf.ni.rodata = try elf.ni.elf.addOnlyHeaderChild(&elf.mf, gpa, .{
4104 elf.ni.rodata = elf.addNodeAssumeCapacity(try elf.ni.elf.addOnlyHeaderChild(gpa, &elf.mf, .{
41024105 // Must be at least `addr_align` for `elf.ni.phdr` to be placed inside this node
41034106 .alignment = node_block_align.max(addr_align),
41044107 .moved = true,
41054108 .bubbles_moved = false,
4106 });
4107 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.rodata });
4109 }), .{ .segment = phndx.rodata });
41084110 elf.phdrs.items[phndx.rodata] = .wrap(elf.ni.rodata);
41094111
4110 elf.ni.phdr = try elf.ni.rodata.addFloatingChild(&elf.mf, gpa, .{
4112 elf.ni.phdr = elf.addNodeAssumeCapacity(try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{
41114113 .size = @as(u64, phnum) * entsize.ph,
41124114 .alignment = addr_align, // keep in sync with `elf.ni.rodata` alignment above
41134115 .moved = true,
41144116 .resized = true,
41154117 .bubbles_moved = false,
4116 });
4117 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.phdr });
4118 }), .{ .segment = phndx.phdr });
41184119 elf.phdrs.items[phndx.phdr] = .wrap(elf.ni.phdr);
41194120
4120 elf.ni.text = try elf.ni.elf.addFloatingChild(&elf.mf, gpa, .{
4121 elf.ni.text = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{
41214122 .alignment = node_block_align,
41224123 .moved = true,
41234124 .bubbles_moved = false,
4124 });
4125 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.text });
4125 }), .{ .segment = phndx.text });
41264126 elf.phdrs.items[phndx.text] = .wrap(elf.ni.text);
41274127
4128 elf.ni.data = try elf.ni.elf.addFloatingChild(&elf.mf, gpa, .{
4128 elf.ni.data = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{
41294129 // Must be at least `addr_align` for `elf.ni.data_rel_ro` to be placed inside this node
41304130 .alignment = node_block_align.max(addr_align),
41314131 .moved = true,
41324132 .bubbles_moved = false,
4133 });
4134 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.data });
4133 }), .{ .segment = phndx.data });
41354134 elf.phdrs.items[phndx.data] = .wrap(elf.ni.data);
41364135
4137 if (plt.got_plt == null) {
4138 const plt_ni = try elf.ni.elf.addFloatingChild(&elf.mf, gpa, .{
4136 if (plt.got_plt == null) elf.phdrs.items[phndx.plt] = .wrap(elf.addNodeAssumeCapacity(
4137 try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{
41394138 .alignment = node_block_align,
41404139 .moved = true,
41414140 .bubbles_moved = false,
4142 });
4143 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.plt });
4144 elf.phdrs.items[phndx.plt] = .wrap(plt_ni);
4145 }
4141 }),
4142 .{ .segment = phndx.plt },
4143 ));
41464144
4147 elf.ni.data_rel_ro = try elf.ni.data.addFloatingChild(&elf.mf, gpa, .{
4145 elf.ni.data_rel_ro = elf.addNodeAssumeCapacity(try elf.ni.data.addFloatingChild(gpa, &elf.mf, .{
41484146 // Must be at least `addr_align` for the `PT_DYNAMIC` node to be placed inside this one
41494147 // later (if `have_dynamic_section`). Keep in sync with `elf.ni.data` alignment above.
41504148 .alignment = node_block_align.max(addr_align),
41514149 .moved = true,
41524150 .bubbles_moved = false,
4153 });
4154 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.relro });
4151 }), .{ .segment = phndx.relro });
41554152 elf.phdrs.items[phndx.relro] = .wrap(elf.ni.data_rel_ro);
41564153
41574154 if (comp.config.any_non_single_threaded) {
4158 elf.ni.tls = .wrap(try elf.ni.rodata.addFloatingChild(&elf.mf, gpa, .{
4159 .alignment = node_block_align,
4160 .moved = true,
4161 .bubbles_moved = false,
4162 }));
4163 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.tls });
4155 elf.ni.tls = .wrap(elf.addNodeAssumeCapacity(
4156 try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{
4157 .alignment = node_block_align,
4158 .moved = true,
4159 .bubbles_moved = false,
4160 }),
4161 .{ .segment = phndx.tls },
4162 ));
41644163 elf.phdrs.items[phndx.tls] = elf.ni.tls;
41654164 }
41664165
......@@ -4184,11 +4183,10 @@ fn initHeaders(
41844183 .REL => elf.ni.elf,
41854184 .DYN, .EXEC => elf.ni.rodata,
41864185 };
4187 elf.ni.ehdr = try parent_ni.addOnlyHeaderChild(&elf.mf, gpa, .{
4186 elf.ni.ehdr = elf.addNodeAssumeCapacity(try parent_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
41884187 .size = @sizeOf(ElfN.Ehdr),
41894188 .alignment = addr_align,
4190 });
4191 elf.nodes.appendAssumeCapacity(.ehdr);
4189 }), .ehdr);
41924190
41934191 const ehdr: *ElfN.Ehdr = @ptrCast(@alignCast(elf.ni.ehdr.slice(&elf.mf)));
41944192 ehdr.ident = .{
......@@ -4238,13 +4236,12 @@ fn initHeaders(
42384236 },
42394237 }
42404238
4241 elf.ni.shdr = try elf.ni.elf.addFloatingChild(&elf.mf, gpa, .{
4239 elf.ni.shdr = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{
42424240 .size = node_block_align.forward(1 * entsize.sh), // as above, only the SHN_UNDEF initially
42434241 .alignment = addr_align.max(node_block_align),
42444242 .moved = true,
42454243 .resized = true,
4246 });
4247 elf.nodes.appendAssumeCapacity(.shdr);
4244 }), .shdr);
42484245
42494246 switch (class) {
42504247 .NONE, _ => unreachable,
......@@ -4298,18 +4295,16 @@ fn initHeaders(
42984295 .@"align" = @intCast(elf.ni.phdr.alignment(&elf.mf).toByteUnits()),
42994296 };
43004297
4301 if (maybe_interp) |_| {
4302 phdr[phndx.interp] = .{
4303 .type = .INTERP,
4304 .offset = 0,
4305 .vaddr = 0,
4306 .paddr = 0,
4307 .filesz = 0,
4308 .memsz = 0,
4309 .flags = .{ .R = true },
4310 .@"align" = 1,
4311 };
4312 }
4298 if (maybe_interp) |_| phdr[phndx.interp] = .{
4299 .type = .INTERP,
4300 .offset = 0,
4301 .vaddr = 0,
4302 .paddr = 0,
4303 .filesz = 0,
4304 .memsz = 0,
4305 .flags = .{ .R = true },
4306 .@"align" = 1,
4307 };
43134308
43144309 phdr[phndx.rodata] = .{
43154310 .type = .NULL,
......@@ -4567,13 +4562,15 @@ fn initHeaders(
45674562 .node_align = node_block_align,
45684563 });
45694564 if (maybe_interp) |interp| {
4570 const interp_ni = try elf.ni.rodata.addFloatingChild(&elf.mf, gpa, .{
4571 .size = interp.len + 1,
4572 .moved = true,
4573 .resized = true,
4574 .bubbles_moved = false,
4575 });
4576 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.interp });
4565 const interp_ni = elf.addNodeAssumeCapacity(
4566 try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{
4567 .size = interp.len + 1,
4568 .moved = true,
4569 .resized = true,
4570 .bubbles_moved = false,
4571 }),
4572 .{ .segment = phndx.interp },
4573 );
45774574 elf.phdrs.items[phndx.interp] = .wrap(interp_ni);
45784575
45794576 const sec_interp_shndx = try elf.addSection(interp_ni, .{
......@@ -4588,12 +4585,14 @@ fn initHeaders(
45884585 }
45894586 if (have_dynamic) {
45904587 assert(elf.ni.data_rel_ro.alignment(&elf.mf).compare(.gte, addr_align));
4591 const dynamic_ni = try elf.ni.data_rel_ro.addFloatingChild(&elf.mf, gpa, .{
4592 .alignment = addr_align,
4593 .moved = true,
4594 .bubbles_moved = false,
4595 });
4596 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.dynamic });
4588 const dynamic_ni = elf.addNodeAssumeCapacity(
4589 try elf.ni.data_rel_ro.addFloatingChild(gpa, &elf.mf, .{
4590 .alignment = addr_align,
4591 .moved = true,
4592 .bubbles_moved = false,
4593 }),
4594 .{ .segment = phndx.dynamic },
4595 );
45974596 elf.phdrs.items[phndx.dynamic] = .wrap(dynamic_ni);
45984597
45994598 const dynstr_shndx = try elf.addSection(elf.ni.rodata, .{
......@@ -4778,13 +4777,15 @@ fn initHeaders(
47784777 }
47794778 }
47804779 if (have_eh_frame) {
4781 elf.ni.gnu_eh_frame = .wrap(try elf.ni.rodata.addFloatingChild(&elf.mf, gpa, .{
4782 .size = @sizeOf(Dwarf.EhFrameHdr),
4783 .alignment = .@"4",
4784 .moved = true,
4785 .bubbles_moved = false,
4786 }));
4787 elf.nodes.appendAssumeCapacity(.{ .segment = phndx.gnu_eh_frame });
4780 elf.ni.gnu_eh_frame = .wrap(elf.addNodeAssumeCapacity(
4781 try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{
4782 .size = @sizeOf(Dwarf.EhFrameHdr),
4783 .alignment = .@"4",
4784 .moved = true,
4785 .bubbles_moved = false,
4786 }),
4787 .{ .segment = phndx.gnu_eh_frame },
4788 ));
47884789 elf.phdrs.items[phndx.gnu_eh_frame] = elf.ni.gnu_eh_frame;
47894790
47904791 elf.shndx.eh_frame_hdr = try elf.addSection(elf.ni.gnu_eh_frame.unwrap().?, .{
......@@ -5106,6 +5107,7 @@ fn getNode(elf: *const Elf, ni: MappedFile.Node.Index) Node {
51065107/// Asserts that `ni` is a section, input section, copied global, NAV, UAV, or lazy code/data.
51075108fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {
51085109 return switch (elf.getNode(ni)) {
5110 .deleted,
51095111 .archive,
51105112 .archive_header,
51115113 .archive_input_member,
......@@ -5142,6 +5144,7 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {
51425144}
51435145fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
51445146 return switch (elf.getNode(ni)) {
5147 .deleted,
51455148 .archive,
51465149 .archive_header,
51475150 .archive_input_member,
......@@ -5179,7 +5182,12 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
51795182fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
51805183 const parent_ni = ni.parent(&elf.mf).unwrap().?;
51815184 const parent_vaddr = parent_vaddr: switch (elf.getNode(parent_ni)) {
5182 .archive, .archive_header, .archive_input_member, .archive_elf_member_header => unreachable,
5185 .deleted,
5186 .archive,
5187 .archive_header,
5188 .archive_input_member,
5189 .archive_elf_member_header,
5190 => unreachable,
51835191 .elf => return 0,
51845192 .ehdr, .shdr => unreachable,
51855193 .segment => |phndx| switch (elf.phdrSlice()) {
......@@ -5229,6 +5237,7 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
52295237 skip_node_relocs: MappedFile.Node.Index.Optional = .none,
52305238 first_got_reloc: ?*GotReloc.Index = null,
52315239 } = switch (elf.getNode(ni)) {
5240 .deleted,
52325241 .archive,
52335242 .archive_header,
52345243 .archive_input_member,
......@@ -5284,8 +5293,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
52845293 },
52855294 .func_debug_info => |fi| .{
52865295 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc,
5287 .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav|
5288 nav.lsi.index().ptr(elf).node
5296 .skip_symbol_relocs = if (elf.navs.getPtr(fi.get(&elf.dwarf).owner_nav)) |owner_nav|
5297 owner_nav.lsi.index().ptr(elf).node
52895298 else
52905299 .none,
52915300 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc,
......@@ -5875,9 +5884,9 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node
58755884 },
58765885 };
58775886 try shndx.ensureAligned(elf, alignment);
5878 const node = try shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
5887 const node = elf.addNodeAssumeCapacity(try shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
58795888 .alignment = alignment,
5880 });
5889 }), .{ .nav = nmi });
58815890 nav_gop.value_ptr.* = .{
58825891 .lsi = elf.addLocalSymbolAssumeCapacity(.{
58835892 .node = .wrap(node),
......@@ -5890,7 +5899,6 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node
58905899 .first_symbol_reloc = .none,
58915900 .first_got_reloc = .none,
58925901 };
5893 elf.nodes.appendAssumeCapacity(.{ .nav = nmi });
58945902 }
58955903 return nmi;
58965904}
......@@ -5919,10 +5927,10 @@ fn uavMapIndex(
59195927 if (!uav_gop.found_existing) {
59205928 const shndx: Section.Index = .data_rel_ro; // TODO: it would be better to use `.rodata` if the UAV value doesn't have relocs
59215929 try shndx.ensureAligned(elf, resolved_align);
5922 const node = try shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
5930 const node = elf.addNodeAssumeCapacity(try shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
59235931 .moved = true, // see assert at end of `genUav`
59245932 .alignment = resolved_align,
5925 });
5933 }), .{ .uav = umi });
59265934 var name_buf: [std.fmt.count("__anon_{d}", .{std.math.maxInt(u32)})]u8 = undefined;
59275935 const name = std.mem.print(&name_buf, "__anon_{d}", .{umi}) catch unreachable;
59285936 uav_gop.value_ptr.* = .{
......@@ -5936,7 +5944,6 @@ fn uavMapIndex(
59365944 }),
59375945 .first_symbol_reloc = .none,
59385946 };
5939 elf.nodes.appendAssumeCapacity(.{ .uav = umi });
59405947 elf.const_prog_node.increaseEstimatedTotalItems(1);
59415948 elf.pending_uavs.appendAssumeCapacity(umi);
59425949 } else {
......@@ -5944,7 +5951,7 @@ fn uavMapIndex(
59445951 const shndx = elf.getNode(node.parent(&elf.mf).unwrap().?).section;
59455952 try shndx.ensureAligned(elf, resolved_align);
59465953 if (resolved_align.order(node.alignment(&elf.mf)).compare(.gt)) {
5947 try node.realign(&elf.mf, gpa, resolved_align);
5954 try node.realign(gpa, &elf.mf, resolved_align);
59485955 }
59495956 }
59505957 return umi;
......@@ -6173,11 +6180,13 @@ fn loadObject(
61736180 };
61746181
61756182 try elf.nodes.ensureUnusedCapacity(gpa, 1);
6176 const new_member_ni = try archive.ni.addFooterChildBefore(&elf.mf, gpa, first_member_oni, .{
6177 .size = Alignment.@"2".forward(@sizeOf(std.elf.ar_hdr) + fl.size),
6178 .alignment = .@"2",
6179 });
6180 elf.nodes.appendAssumeCapacity(.{ .archive_input_member = input_index });
6183 const new_member_ni = elf.addNodeAssumeCapacity(
6184 try archive.ni.addFooterChildBefore(gpa, &elf.mf, first_member_oni, .{
6185 .size = Alignment.@"2".forward(@sizeOf(std.elf.ar_hdr) + fl.size),
6186 .alignment = .@"2",
6187 }),
6188 .{ .archive_input_member = input_index },
6189 );
61816190 input.extra = .{ .node = new_member_ni };
61826191 elf.input_prog_node.increaseEstimatedTotalItems(1);
61836192
......@@ -6391,22 +6400,20 @@ fn loadObject(
63916400 .alignment = need_align,
63926401 .moved = true, // see assert at end of `flushInputSection`
63936402 };
6394 const ni = if (opts.node_fixed) ni: {
6395 const shndx_ni = opts.shndx.get(elf).ni;
6396 const after_oni: MappedFile.Node.Index.Optional = after: {
6397 const last_ni = shndx_ni.last(&elf.mf).unwrap() orelse break :after .none;
6398 break :after switch (last_ni.position(&elf.mf)) {
6399 .header => .wrap(last_ni),
6400 .footer, .floating => .none,
6403 const ni = elf.addNodeAssumeCapacity(
6404 if (opts.node_fixed) ni: {
6405 const shndx_ni = opts.shndx.get(elf).ni;
6406 const after_oni: MappedFile.Node.Index.Optional = after: {
6407 const last_ni = shndx_ni.last(&elf.mf).unwrap() orelse break :after .none;
6408 break :after switch (last_ni.position(&elf.mf)) {
6409 .header => .wrap(last_ni),
6410 .footer, .floating => .none,
6411 };
64016412 };
6402 };
6403 break :ni try shndx_ni.addHeaderChildAfter(&elf.mf, gpa, after_oni, add_node_opts);
6404 } else ni: {
6405 break :ni try opts.shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, add_node_opts);
6406 };
6407 elf.nodes.appendAssumeCapacity(.{
6408 .input_section = @fromBackingInt(@intCast(elf.input_sections.items.len)),
6409 });
6413 break :ni try shndx_ni.addHeaderChildAfter(gpa, &elf.mf, after_oni, add_node_opts);
6414 } else try opts.shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, add_node_opts),
6415 .{ .input_section = @fromBackingInt(@intCast(elf.input_sections.items.len)) },
6416 );
64106417 section.isi = @fromBackingInt(@intCast(elf.input_sections.items.len));
64116418 elf.input_sections.addOneAssumeCapacity().* = .{
64126419 .input = input_index,
......@@ -6659,7 +6666,7 @@ fn populateArchiveMemberName(elf: *Elf, member_ar_hdr: *std.elf.ar_hdr, member_n
66596666 // We set the size of the archive header node exactly, because we want padding bytes to go into
66606667 // the root `.archive` node. That way, those bytes could still be used to grow the string table
66616668 // if necessary, but they could also be used for new archive members.
6662 try archive_header_ni.resizeLeaf(&elf.mf, gpa, old_archive_header_size + member_name.len + 2);
6669 try archive_header_ni.resizeLeaf(gpa, &elf.mf, old_archive_header_size + member_name.len + 2);
66636670
66646671 const dest_slice = archive_header_ni.slice(&elf.mf)[@intCast(old_archive_header_size)..];
66656672 @memcpy(dest_slice[0 .. dest_slice.len - 2], member_name);
......@@ -6811,8 +6818,12 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadPars
68116818 // We have a copy relocation for this global, but the amount of space we
68126819 // reserved for it could be too small or underaligned!
68136820 try Section.Index.data.ensureAligned(elf, gop.value_ptr.alignment);
6814 try copied_global.node.resizeLeaf(&elf.mf, gpa, gop.value_ptr.alignment.forward(gop.value_ptr.size));
6815 try copied_global.node.realign(&elf.mf, gpa, gop.value_ptr.alignment);
6821 try copied_global.node.resizeLeaf(
6822 gpa,
6823 &elf.mf,
6824 gop.value_ptr.alignment.forward(gop.value_ptr.size),
6825 );
6826 try copied_global.node.realign(gpa, &elf.mf, gop.value_ptr.alignment);
68166827 const global_ptr = elf.globalByName(name).?;
68176828 switch (elf.symPtr(global_ptr.symtab_index)) {
68186829 inline else => |sym_ptr| elf.targetStore(&sym_ptr.size, @intCast(gop.value_ptr.size)),
......@@ -7034,49 +7045,25 @@ fn prelinkInner(elf: *Elf) Error!void {
70347045 .extra = .{ .file_symbol = zcu_file_symbol },
70357046 };
70367047 elf.input_pending_index += 1;
7037 }
7038}
7039
7040pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void {
7041 elf.zcuFilesReadyInner(zcu) catch |err| switch (err) {
7042 else => |e| return e,
7043 error.MappedFileIo => return elf.base.comp.link_diags.fail(
7044 "failed to write output file: {t}",
7045 .{elf.mf.io_err.?},
7046 ),
7047 };
7048}
7049fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7050 const gpa = zcu.gpa;
70517048
7052 if (elf.dwarf.units.count() == 0) {
7053 try elf.dwarf.initUnits(zcu);
7054 try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5 + 5 * elf.dwarf.units.count());
7055 try elf.dwarf_units.appendNTimes(gpa, .{
7056 .frame_cie_first_target_reloc = .none,
7057 .debug_info_header_first_target_reloc = .none,
7058 .debug_info_header_first_node_reloc = .none,
7059 .debug_line_header_first_target_reloc = .none,
7060 .debug_line_header_first_node_reloc = .none,
7061 .debug_rnglists_first_target_reloc = .none,
7062 .debug_rnglists_symbol_relocs = .empty,
7063 }, elf.dwarf.units.count());
7064
7065 elf.dwarf.debug_abbrev.ni =
7066 .wrap(try elf.shndx.debug_abbrev.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{}));
7067 elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_abbrev });
7068
7069 elf.dwarf.debug_line_str.ni =
7070 .wrap(try elf.shndx.debug_line_str.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{}));
7071 elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_line_str });
7072
7073 elf.dwarf.debug_str.ni =
7074 .wrap(try elf.shndx.debug_str.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{}));
7075 elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_str });
7076
7077 elf.dwarf.debug_str_offsets.ni =
7078 .wrap(try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{}));
7079 elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_str_offsets });
7049 try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5);
7050
7051 elf.dwarf.debug_abbrev.ni = .wrap(elf.addNodeAssumeCapacity(
7052 try elf.shndx.debug_abbrev.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7053 .{ .debug_shared = .debug_abbrev },
7054 ));
7055 elf.dwarf.debug_line_str.ni = .wrap(elf.addNodeAssumeCapacity(
7056 try elf.shndx.debug_line_str.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7057 .{ .debug_shared = .debug_line_str },
7058 ));
7059 elf.dwarf.debug_str.ni = .wrap(elf.addNodeAssumeCapacity(
7060 try elf.shndx.debug_str.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7061 .{ .debug_shared = .debug_str },
7062 ));
7063 elf.dwarf.debug_str_offsets.ni = .wrap(elf.addNodeAssumeCapacity(
7064 try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7065 .{ .debug_shared = .debug_str_offsets },
7066 ));
70807067
70817068 for ([5]Section.Index{
70827069 elf.shndx.eh_frame,
......@@ -7089,18 +7076,20 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
70897076 const debug_ni = debug_shndx.get(elf).ni;
70907077 _ = debug_ni.last(&elf.mf).unwrap() orelse continue;
70917078 const frame_format = debug_shndx.debugFrameFormat(elf);
7092 const unit_padding_ni = try debug_ni.addFloatingChild(&elf.mf, gpa, .{
7093 .alignment = if (frame_format) |_| switch (elf.identClass()) {
7094 .NONE, _ => unreachable,
7095 .@"32" => .@"4",
7096 .@"64" => .@"8",
7097 } else .@"1",
7098 .next_moved = true,
7099 .enable_next_moved = true,
7100 });
7101 elf.nodes.appendAssumeCapacity(.unit_padding);
7079 const unit_padding_ni = elf.addNodeAssumeCapacity(
7080 try debug_ni.addFloatingChild(gpa, &elf.mf, .{
7081 .alignment = if (frame_format) |_| switch (elf.identClass()) {
7082 .NONE, _ => unreachable,
7083 .@"32" => .@"4",
7084 .@"64" => .@"8",
7085 } else .@"1",
7086 .next_moved = true,
7087 .enable_next_moved = true,
7088 }),
7089 .unit_padding,
7090 );
71027091 var debug_nw: MappedFile.Node.Writer = undefined;
7103 unit_padding_ni.writer(&elf.mf, gpa, &debug_nw);
7092 unit_padding_ni.writer(gpa, &elf.mf, &debug_nw);
71047093 defer debug_nw.deinit();
71057094 (if (frame_format) |format|
71067095 elf.dwarf.genDebugFrameCie(&debug_nw.interface, null, format)
......@@ -7109,88 +7098,121 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
71097098 error.WriteFailed => return debug_nw.err.?,
71107099 };
71117100 }
7101 }
7102}
71127103
7113 for (0.., elf.dwarf.units.values()) |unit_index, *unit| {
7114 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));
7115 switch (elf.shndx.debug_info) {
7116 .UNDEF => {},
7117 else => |debug_info_shndx| {
7118 const debug_info_ni =
7119 try debug_info_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
7120 .alignment = elf.mf.flags.block_size,
7121 .enable_next_moved = true,
7122 });
7123 unit.debug_info_ni = .wrap(debug_info_ni);
7124 elf.nodes.appendAssumeCapacity(.{ .unit_debug_info = ui });
7125
7126 unit.debug_info_header_ni =
7127 .wrap(try debug_info_ni.addOnlyHeaderChild(&elf.mf, gpa, .{
7128 .next_moved = true,
7129 .enable_next_moved = true,
7130 }));
7131 elf.nodes.appendAssumeCapacity(.{ .unit_debug_info_header = ui });
7132 },
7133 }
7134 switch (elf.shndx.debug_line) {
7135 .UNDEF => {},
7136 else => |debug_line_shndx| {
7137 const debug_line_ni =
7138 try debug_line_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
7139 .alignment = elf.mf.flags.block_size,
7140 .enable_next_moved = true,
7141 });
7142 unit.debug_line_ni = .wrap(debug_line_ni);
7143 elf.nodes.appendAssumeCapacity(.{ .unit_debug_line = ui });
7144
7145 unit.debug_line_header_ni =
7146 .wrap(try debug_line_ni.addOnlyHeaderChild(&elf.mf, gpa, .{
7147 // Idle tasks are going to try to keep this up to date before we are able to
7148 // write out the full header, so just reserve space for them to do so.
7149 .size = elf.dwarf.unitLengthSize(),
7150 .enable_next_moved = true,
7151 }));
7152 elf.nodes.appendAssumeCapacity(.{ .unit_debug_line_header = ui });
7153 },
7154 }
7155 switch (elf.shndx.debug_rnglists) {
7156 .UNDEF => {},
7157 else => |debug_rnglists_shndx| {
7158 unit.debug_rnglists_ni =
7159 .wrap(try debug_rnglists_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
7160 .next_moved = true,
7161 .enable_next_moved = true,
7162 }));
7163 elf.nodes.appendAssumeCapacity(.{ .unit_debug_rnglists = ui });
7164 },
7165 }
7104pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void {
7105 elf.zcuFilesReadyInner(zcu) catch |err| switch (err) {
7106 else => |e| return e,
7107 error.MappedFileIo => return elf.base.comp.link_diags.fail(
7108 "failed to write output file: {t}",
7109 .{elf.mf.io_err.?},
7110 ),
7111 };
7112}
7113fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7114 const gpa = zcu.gpa;
7115
7116 try elf.dwarf.initUnits(zcu);
7117 const old_units_len = elf.dwarf_units.items.len;
7118 const new_units_len = elf.dwarf.units.count();
7119 try elf.dwarf_units.appendNTimes(gpa, .{
7120 .frame_cie_first_target_reloc = .none,
7121 .debug_info_header_first_target_reloc = .none,
7122 .debug_info_header_first_node_reloc = .none,
7123 .debug_line_header_first_target_reloc = .none,
7124 .debug_line_header_first_node_reloc = .none,
7125 .debug_rnglists_first_target_reloc = .none,
7126 .debug_rnglists_symbol_relocs = .empty,
7127 }, new_units_len - old_units_len);
7128 try elf.nodes.ensureUnusedCapacity(gpa, 5 * (new_units_len - old_units_len));
7129
7130 for (old_units_len.., elf.dwarf.units.values()[old_units_len..]) |unit_index, *unit| {
7131 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));
7132 switch (elf.shndx.debug_info) {
7133 .UNDEF => {},
7134 else => |debug_info_shndx| {
7135 const debug_info_ni = elf.addNodeAssumeCapacity(
7136 try debug_info_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7137 .alignment = elf.mf.flags.block_size,
7138 .enable_next_moved = true,
7139 }),
7140 .{ .unit_debug_info = ui },
7141 );
7142 unit.debug_info_ni = .wrap(debug_info_ni);
7143
7144 unit.debug_info_header_ni = .wrap(elf.addNodeAssumeCapacity(
7145 try debug_info_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
7146 .next_moved = true,
7147 .enable_next_moved = true,
7148 }),
7149 .{ .unit_debug_info_header = ui },
7150 ));
7151 },
71667152 }
7153 switch (elf.shndx.debug_line) {
7154 .UNDEF => {},
7155 else => |debug_line_shndx| {
7156 const debug_line_ni = elf.addNodeAssumeCapacity(
7157 try debug_line_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7158 .alignment = elf.mf.flags.block_size,
7159 .enable_next_moved = true,
7160 }),
7161 .{ .unit_debug_line = ui },
7162 );
7163 unit.debug_line_ni = .wrap(debug_line_ni);
71677164
7168 for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| {
7169 var drh_nw: MappedFile.Node.Writer = undefined;
7170 unit.debug_rnglists_ni.unwrap().?.writer(&elf.mf, gpa, &drh_nw);
7171 defer drh_nw.deinit();
7172 const debug_rnglists_offsets_table_offset =
7173 elf.dwarf.genDebugRnglistsHeader(unit, &drh_nw) catch |err| switch (err) {
7174 else => |e| return e,
7175 error.WriteFailed => return drh_nw.err.?,
7176 };
7165 unit.debug_line_header_ni = .wrap(elf.addNodeAssumeCapacity(
7166 try debug_line_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
7167 // Idle tasks are going to try to keep this up to date before we are able to
7168 // write out the full header, so just reserve space for them to do so.
7169 .size = elf.dwarf.unitLengthSize(),
7170 .enable_next_moved = true,
7171 }),
7172 .{ .unit_debug_line_header = ui },
7173 ));
7174 },
7175 }
7176 switch (elf.shndx.debug_rnglists) {
7177 .UNDEF => {},
7178 else => |debug_rnglists_shndx| unit.debug_rnglists_ni = .wrap(elf.addNodeAssumeCapacity(
7179 try debug_rnglists_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7180 .next_moved = true,
7181 .enable_next_moved = true,
7182 }),
7183 .{ .unit_debug_rnglists = ui },
7184 )),
7185 }
7186 }
71777187
7178 var dih_nw: MappedFile.Node.Writer = undefined;
7179 const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?;
7180 debug_info_header_ni.writer(&elf.mf, gpa, &dih_nw);
7181 defer dih_nw.deinit();
7182 elf.resetNodeRelocs(debug_info_header_ni);
7183 elf.dwarf.genDebugInfoHeader(
7184 mod,
7185 unit,
7186 &dih_nw,
7187 debug_rnglists_offsets_table_offset,
7188 zcu,
7189 ) catch |err| switch (err) {
7188 for (
7189 elf.dwarf.units.keys()[old_units_len..],
7190 elf.dwarf.units.values()[old_units_len..],
7191 ) |mod, *unit| {
7192 var drh_nw: MappedFile.Node.Writer = undefined;
7193 unit.debug_rnglists_ni.unwrap().?.writer(gpa, &elf.mf, &drh_nw);
7194 defer drh_nw.deinit();
7195 const debug_rnglists_offsets_table_offset =
7196 elf.dwarf.genDebugRnglistsHeader(unit, &drh_nw) catch |err| switch (err) {
71907197 else => |e| return e,
7191 error.WriteFailed => return dih_nw.err.?,
7198 error.WriteFailed => return drh_nw.err.?,
71927199 };
7193 }
7200
7201 var dih_nw: MappedFile.Node.Writer = undefined;
7202 const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?;
7203 debug_info_header_ni.writer(gpa, &elf.mf, &dih_nw);
7204 defer dih_nw.deinit();
7205 elf.resetNodeRelocs(debug_info_header_ni);
7206 elf.dwarf.genDebugInfoHeader(
7207 mod,
7208 unit,
7209 &dih_nw,
7210 debug_rnglists_offsets_table_offset,
7211 zcu,
7212 ) catch |err| switch (err) {
7213 else => |e| return e,
7214 error.WriteFailed => return dih_nw.err.?,
7215 };
71947216 }
71957217}
71967218
......@@ -7203,7 +7225,7 @@ fn flushFiles(elf: *Elf) Error!void {
72037225 try debug_line_header_ni.moved(gpa, &elf.mf);
72047226 try debug_line_header_ni.nextMoved(gpa, &elf.mf);
72057227 var dlh_nw: MappedFile.Node.Writer = undefined;
7206 debug_line_header_ni.writer(&elf.mf, gpa, &dlh_nw);
7228 debug_line_header_ni.writer(gpa, &elf.mf, &dlh_nw);
72077229 defer dlh_nw.deinit();
72087230 elf.resetNodeRelocs(debug_line_header_ni);
72097231 elf.dwarf.genDebugLineHeader(mod, unit, &dlh_nw, elf.base.comp.zcu.?) catch |err| switch (err) {
......@@ -7235,7 +7257,7 @@ fn prepareDynamic(elf: *Elf) Error!void {
72357257
72367258 const dynamic_size = dynamic_len * 2 * elf.targetPtrSize();
72377259
7238 try elf.shndx.dynamic.get(elf).ni.resizeLeaf(&elf.mf, comp.gpa, dynamic_size);
7260 try elf.shndx.dynamic.get(elf).ni.resizeLeaf(comp.gpa, &elf.mf, dynamic_size);
72397261 switch (elf.shdrPtr(elf.shndx.dynamic)) {
72407262 inline else => |shdr| elf.targetStore(&shdr.size, @intCast(dynamic_size)),
72417263 }
......@@ -7405,17 +7427,20 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
74057427 break :shndx .{ @fromBackingInt(shndx), @as(u64, elf.targetLoad(&ehdr.shentsize)) * @as(u64, shnum) };
74067428 },
74077429 };
7408 try elf.ni.shdr.ensureMinimumSize(&elf.mf, gpa, new_shdr_size);
7430 try elf.ni.shdr.ensureMinimumSize(gpa, &elf.mf, new_shdr_size);
74097431 const parent_ni = switch (elf.ehdrType()) {
74107432 .REL => elf.ni.elf,
74117433 .EXEC, .DYN => segment_ni,
74127434 };
74137435 assert(opts.addralign.check(opts.size));
7414 const ni = try parent_ni.addFloatingChild(&elf.mf, gpa, .{
7436 const ni = elf.addNodeAssumeCapacity(try parent_ni.addFloatingChild(gpa, &elf.mf, .{
74157437 .size = opts.node_align.forward(opts.size),
74167438 .alignment = opts.addralign.max(opts.node_align),
74177439 .resized = opts.size > 0,
74187440 .bubbles_moved = opts.flags.ALLOC,
7441 }), switch (opts.manual_size) {
7442 false => .{ .section = shndx },
7443 true => .{ .section_manual_size = shndx },
74197444 });
74207445 const addr = elf.computeNodeVAddr(ni);
74217446 const lsi: Symbol.LocalIndex = if (opts.flags.ALLOC) elf.addLocalSymbolAssumeCapacity(.{
......@@ -7431,10 +7456,6 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
74317456 .RELA => .{ .free_head = .none },
74327457 else => .{ .shndx = .UNDEF },
74337458 } });
7434 elf.nodes.appendAssumeCapacity(switch (opts.manual_size) {
7435 false => .{ .section = shndx },
7436 true => .{ .section_manual_size = shndx },
7437 });
74387459 switch (elf.shdrPtr(shndx)) {
74397460 inline else => |shdr, class| {
74407461 shdr.* = .{
......@@ -7505,7 +7526,7 @@ fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize)
75057526 .NONE, _ => unreachable,
75067527 inline else => |ct_class| (elf.got.count() + new_got_entries) * @sizeOf(ct_class.ElfN().Addr),
75077528 };
7508 try elf.shndx.got.get(elf).ni.ensureMinimumSize(&elf.mf, gpa, need_got_size);
7529 try elf.shndx.got.get(elf).ni.ensureMinimumSize(gpa, &elf.mf, need_got_size);
75097530
75107531 if (elf.shndx.dynamic != .UNDEF) {
75117532 try elf.shndx.rela_dyn.relaEnsureAdditionalCapacity(elf, new_got_entries);
......@@ -8100,6 +8121,7 @@ fn addGotRelocAssumeCapacity(
81008121) void {
81018122 assert(elf.ehdrType() != .REL);
81028123 switch (elf.getNode(node)) {
8124 .deleted,
81038125 .archive,
81048126 .archive_header,
81058127 .archive_input_member,
......@@ -8361,14 +8383,13 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) Error!bool {
83618383 try Section.Index.data.ensureAligned(elf, dso_global.alignment);
83628384
83638385 try elf.nodes.ensureUnusedCapacity(gpa, 1);
8364 const node = try Section.Index.data.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
8386 const node = try Section.Index.data.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
83658387 .size = dso_global.alignment.forward(dso_global.size),
83668388 .alignment = dso_global.alignment,
83678389 });
83688390 errdefer comptime unreachable;
83698391
83708392 const vaddr = elf.computeNodeVAddr(node);
8371 elf.nodes.appendAssumeCapacity(.{ .copied_global = global_name });
83728393 const rela_index = elf.shndx.rela_dyn.relaAddOneAssumeCapacity(elf, .{
83738394 .type = .copy(elf),
83748395 .offset = vaddr,
......@@ -8423,7 +8444,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
84238444
84248445 {
84258446 var nw: MappedFile.Node.Writer = undefined;
8426 ni.writer(&elf.mf, gpa, &nw);
8447 ni.writer(gpa, &elf.mf, &nw);
84278448 defer nw.deinit();
84288449 elf.resetNodeRelocs(ni);
84298450 codegen.generateSymbol(
......@@ -8549,16 +8570,16 @@ fn updateFuncInner(
85498570
85508571 {
85518572 var nw: MappedFile.Node.Writer = undefined;
8552 ni.writer(&elf.mf, gpa, &nw);
8573 ni.writer(gpa, &elf.mf, &nw);
85538574 defer nw.deinit();
85548575 var debug_output_buf: Dwarf.WipNav.Debug = undefined;
85558576 const debug_output: link.File.DebugInfoOutput, const dwarf_func = debug_output: {
85568577 if (elf.ehdrMachine() != .X86_64) break :debug_output .{ .none, undefined };
85578578 const dwarf = &elf.dwarf;
8558 const mod = zcu.navFileScope(func.owner_nav).mod.?;
8579 const mod = zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?;
85598580 if (mod.strip and mod.unwind_tables == .none) break :debug_output .{ .none, undefined };
85608581
8561 try elf.nodes.ensureUnusedCapacity(gpa, 5);
8582 try elf.nodes.ensureUnusedCapacity(gpa, 4);
85628583 const dwarf_fi = try dwarf.getFunc(func.owner_nav);
85638584
85648585 const wip_nav = &debug_output_buf.wip_nav;
......@@ -8586,27 +8607,28 @@ fn updateFuncInner(
85868607 .@"64" => .@"8",
85878608 };
85888609 const frame_ni = unit.frame_ni.unwrap() orelse frame_ni: {
8589 const frame_ni = try switch (wip_nav.frame_format) {
8610 const frame_ni = elf.addNodeAssumeCapacity(try switch (wip_nav.frame_format) {
85908611 .debug_frame => elf.shndx.debug_frame,
85918612 .eh_frame => elf.shndx.eh_frame,
8592 }.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
8613 }.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
85938614 .alignment = frame_align.max(elf.mf.flags.block_size),
85948615 .enable_next_moved = true,
8595 });
8616 }), .{ .unit_frame = wip_nav.unit });
85968617 unit.frame_ni = .wrap(frame_ni);
8597 elf.nodes.appendAssumeCapacity(.{ .unit_frame = wip_nav.unit });
85988618 break :frame_ni frame_ni;
85998619 };
86008620 _ = unit.cie_ni.unwrap() orelse {
8601 const cie_ni = try frame_ni.addOnlyHeaderChild(&elf.mf, gpa, .{
8602 .alignment = frame_align,
8603 .next_moved = true,
8604 .enable_next_moved = true,
8605 });
8621 const cie_ni = elf.addNodeAssumeCapacity(
8622 try frame_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
8623 .alignment = frame_align,
8624 .next_moved = true,
8625 .enable_next_moved = true,
8626 }),
8627 .{ .unit_frame_cie = wip_nav.unit },
8628 );
86068629 unit.cie_ni = .wrap(cie_ni);
8607 elf.nodes.appendAssumeCapacity(.{ .unit_frame_cie = wip_nav.unit });
86088630 var cie_nw: MappedFile.Node.Writer = undefined;
8609 cie_ni.writer(&elf.mf, gpa, &cie_nw);
8631 cie_ni.writer(gpa, &elf.mf, &cie_nw);
86108632 defer cie_nw.deinit();
86118633 dwarf.genDebugFrameCie(&cie_nw.interface, switch (elf.ehdrMachine()) {
86128634 else => unreachable,
......@@ -8621,7 +8643,7 @@ fn updateFuncInner(
86218643 try fde_ni.nextMoved(gpa, &elf.mf);
86228644 break :fde_ni fde_ni;
86238645 } else fde_ni: {
8624 const fde_ni = try frame_ni.addFloatingChild(&elf.mf, gpa, .{
8646 const fde_ni = try frame_ni.addFloatingChild(gpa, &elf.mf, .{
86258647 .alignment = frame_align,
86268648 .moved = true,
86278649 .next_moved = true,
......@@ -8630,7 +8652,7 @@ fn updateFuncInner(
86308652 dwarf_func.fde_ni = .wrap(fde_ni);
86318653 break :fde_ni fde_ni;
86328654 };
8633 fde_ni.writer(&elf.mf, gpa, &wip_nav.fde_writer);
8655 fde_ni.writer(gpa, &elf.mf, &wip_nav.fde_writer);
86348656
86358657 if (mod.strip) break :debug_output .{ .{ .eh_frame = wip_nav }, dwarf_func };
86368658
......@@ -8642,20 +8664,21 @@ fn updateFuncInner(
86428664 const debug_info_ni = dwarf_func.debug_info_ni.unwrap().?;
86438665 try debug_info_ni.moved(gpa, &elf.mf);
86448666 try debug_info_ni.nextMoved(gpa, &elf.mf);
8645 debug_info_ni.writer(&elf.mf, gpa, &debug.info_writer);
8667 debug_info_ni.writer(gpa, &elf.mf, &debug.info_writer);
86468668
86478669 const debug_line_ni = dwarf_func.debug_line_ni.unwrap() orelse debug_line_ni: {
8648 const debug_line_ni =
8649 try unit.debug_line_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{
8670 const debug_line_ni = elf.addNodeAssumeCapacity(
8671 try unit.debug_line_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
86508672 .moved = true,
86518673 .next_moved = true,
86528674 .enable_next_moved = true,
8653 });
8675 }),
8676 .{ .func_debug_line = dwarf_fi },
8677 );
86548678 dwarf_func.debug_line_ni = .wrap(debug_line_ni);
8655 elf.nodes.appendAssumeCapacity(.{ .func_debug_line = dwarf_fi });
86568679 break :debug_line_ni debug_line_ni;
86578680 };
8658 debug_line_ni.writer(&elf.mf, gpa, &debug.line_writer);
8681 debug_line_ni.writer(gpa, &elf.mf, &debug.line_writer);
86598682
86608683 break :debug_output .{ .{ .dwarf2 = debug }, dwarf_func };
86618684 };
......@@ -8705,13 +8728,13 @@ fn updateFuncInner(
87058728 .debug_frame => elf.shndx.debug_frame,
87068729 .eh_frame => elf.shndx.eh_frame,
87078730 }.get(elf).ni;
8708 try frame_ni.trimStart(&elf.mf, gpa);
8731 try frame_ni.trimStart(gpa, &elf.mf);
87098732 switch (wip_nav.frame_format) {
87108733 .debug_frame => {},
87118734 .eh_frame => {
87128735 const last_offset, const last_size =
87138736 frame_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf);
8714 try frame_ni.ensureMinimumSize(&elf.mf, gpa, last_offset + last_size + 4);
8737 try frame_ni.ensureMinimumSize(gpa, &elf.mf, last_offset + last_size + 4);
87158738 },
87168739 }
87178740 },
......@@ -8721,18 +8744,18 @@ fn updateFuncInner(
87218744 elf.shndx.debug_info,
87228745 elf.shndx.debug_line,
87238746 elf.shndx.debug_rnglists,
8724 }) |debug_shndx| try debug_shndx.get(elf).ni.trimStart(&elf.mf, gpa);
8747 }) |debug_shndx| try debug_shndx.get(elf).ni.trimStart(gpa, &elf.mf);
87258748 const unit = debug.wip_nav.unit.get(debug.wip_nav.dwarf);
87268749 {
87278750 const debug_info_ni = unit.debug_info_ni.unwrap().?;
87288751 const last_offset, const last_size =
87298752 debug_info_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf);
8730 try debug_info_ni.ensureMinimumSize(&elf.mf, gpa, last_offset + last_size +
8731 comptime Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) * 2);
8753 try debug_info_ni.ensureMinimumSize(gpa, &elf.mf, last_offset + last_size +
8754 comptime Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) * 2);
87328755 }
87338756 {
87348757 var dr_nw: MappedFile.Node.Writer = undefined;
8735 unit.debug_rnglists_ni.unwrap().?.writer(&elf.mf, gpa, &dr_nw);
8758 unit.debug_rnglists_ni.unwrap().?.writer(gpa, &elf.mf, &dr_nw);
87368759 defer dr_nw.deinit();
87378760 const first_symbol_reloc = elf.symbol_relocs.items.len;
87388761 debug.wip_nav.dwarf.genDebugRnglists(
......@@ -8764,6 +8787,25 @@ fn updateFuncInner(
87648787 try elf.genPending(pt);
87658788}
87668789
8790pub fn updateLineNumber(elf: *Elf, pt: Zcu.PerThread, src_inst: InternPool.TrackedInst.Index) void {
8791 const func = elf.dwarf.funcs.getPtr(src_inst) orelse return;
8792 elf.dwarf.updateLineNumber(pt.zcu, src_inst, func.debug_info_ni.unwrap().?.slice(&elf.mf));
8793}
8794
8795pub fn lostTracking(
8796 elf: *Elf,
8797 _: Zcu.PerThread,
8798 src_inst: InternPool.TrackedInst.Index,
8799) std.mem.Allocator.Error!void {
8800 const func = elf.dwarf.funcs.getPtr(src_inst) orelse return;
8801 elf.resetNodeRelocs(func.fde_ni.unwrap().?);
8802 elf.resetNodeRelocs(func.debug_info_ni.unwrap().?);
8803 elf.resetNodeRelocs(func.debug_line_ni.unwrap().?);
8804 try elf.deleteNode(&func.fde_ni);
8805 try elf.deleteNode(&func.debug_info_ni);
8806 try elf.deleteNode(&func.debug_line_ni);
8807}
8808
87678809pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
87688810 try elf.updateConstInner(
87698811 pt,
......@@ -8996,18 +9038,18 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {
89969038
89979039 break :task;
89989040 }
8999 while (elf.mf.updates.pop()) |ni| {
9041 while (elf.mf.updates.pop()) |ni| : (elf.mf.update_prog_node.completeOne()) {
9042 if (ni.pendingDelete(&elf.mf)) continue;
90009043 const clean_moved = ni.cleanMoved(&elf.mf);
90019044 const clean_resized = ni.cleanResized(&elf.mf);
90029045 const clean_next_moved = ni.cleanNextMoved(&elf.mf);
9003 if (clean_moved or clean_resized or clean_next_moved) {
9004 const sub_prog_node = elf.idleProgNode(tid, elf.mf.update_prog_node, elf.getNode(ni));
9005 defer sub_prog_node.end();
9006 if (clean_moved) try elf.flushMoved(ni);
9007 if (clean_resized) try elf.flushResized(ni);
9008 if (clean_next_moved) try elf.flushNextMoved(ni);
9009 break :task;
9010 } else elf.mf.update_prog_node.completeOne();
9046 if (!clean_moved and !clean_resized and !clean_next_moved) continue;
9047 const sub_prog_node = elf.idleProgNode(tid, elf.mf.update_prog_node, elf.getNode(ni));
9048 defer sub_prog_node.end();
9049 if (clean_moved) try elf.flushMoved(ni);
9050 if (clean_resized) try elf.flushResized(ni);
9051 if (clean_next_moved) try elf.flushNextMoved(ni);
9052 break :task;
90119053 }
90129054 }
90139055 if (elf.input_sections.items.len > elf.input_section_pending_index) return true;
......@@ -9085,7 +9127,7 @@ fn idleProgNode(
90859127 .func_debug_info => "debug",
90869128 .func_debug_line => "line",
90879129 },
9088 ip.getNav(fi.nav(&elf.dwarf)).fqn.fmt(ip),
9130 ip.getNav(fi.get(&elf.dwarf).owner_nav).fqn.fmt(ip),
90899131 }) catch &name;
90909132 },
90919133 }, 0);
......@@ -9109,14 +9151,13 @@ fn genUav(
91099151 pt: Zcu.PerThread,
91109152 umi: Node.UavMapIndex,
91119153) Error!void {
9112 const comp = elf.base.comp;
9113 const gpa = comp.gpa;
9154 const gpa = elf.base.comp.gpa;
91149155
91159156 const uav_val = umi.uavValue(elf);
91169157 const ni = umi.symbol(elf).index().ptr(elf).node.unwrap().?;
91179158
91189159 var nw: MappedFile.Node.Writer = undefined;
9119 ni.writer(&elf.mf, gpa, &nw);
9160 ni.writer(gpa, &elf.mf, &nw);
91209161 defer nw.deinit();
91219162 elf.resetNodeRelocs(ni);
91229163 codegen.generateSymbol(
......@@ -9150,7 +9191,7 @@ fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void {
91509191
91519192 var required_alignment: InternPool.Alignment = .none;
91529193 var nw: MappedFile.Node.Writer = undefined;
9153 ni.writer(&elf.mf, gpa, &nw);
9194 ni.writer(gpa, &elf.mf, &nw);
91549195 defer nw.deinit();
91559196 elf.resetNodeRelocs(ni);
91569197 codegen.generateLazySymbol(
......@@ -9241,7 +9282,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {
92419282 }),
92429283 };
92439284 var nw: MappedFile.Node.Writer = undefined;
9244 isi.node(elf).writer(&elf.mf, gpa, &nw);
9285 isi.node(elf).writer(gpa, &elf.mf, &nw);
92459286 defer nw.deinit();
92469287 const n_bytes = nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) catch |err| switch (err) {
92479288 error.ReadFailed => return diags.fail("failed to read input section '{s}' from \"{f}{f}\": {t}", .{
......@@ -9296,17 +9337,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
92969337 defer trace.end();
92979338
92989339 switch (elf.getNode(ni)) {
9299 .archive => unreachable,
9300 .archive_header => unreachable,
9301
9302 .archive_input_member,
9303 .archive_elf_member_header,
9304 .elf,
9305 => {
9340 .deleted => unreachable,
9341 .archive, .archive_header => unreachable,
9342 .archive_input_member, .archive_elf_member_header, .elf => {
93069343 assert(elf.archive != null);
93079344 return;
93089345 },
9309
93109346 .ehdr, .shdr => elf.flushElfOffset(ni),
93119347 .segment => |phndx| {
93129348 elf.flushElfOffset(ni);
......@@ -9570,7 +9606,8 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
95709606 },
95719607 .func_frame_fde => |fi| {
95729608 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
9573 const mod = elf.base.comp.zcu.?.navFileScope(fi.nav(&elf.dwarf)).mod.?;
9609 const zcu = elf.base.comp.zcu.?;
9610 const mod = zcu.fileByIndex(fi.srcInst(&elf.dwarf).resolveFile(&zcu.intern_pool)).mod.?;
95749611 switch (mod.unwind_tables) {
95759612 .none => {},
95769613 .sync, .async => {
......@@ -9594,8 +9631,8 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
95949631 }
95959632 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
95969633 .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc,
9597 .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav|
9598 nav.lsi.index().ptr(elf).node
9634 .skip_symbol_relocs = if (elf.navs.getPtr(fi.get(&elf.dwarf).owner_nav)) |owner_nav|
9635 owner_nav.lsi.index().ptr(elf).node
95999636 else
96009637 .none,
96019638 .first_node_reloc = dwarf_func.debug_info_first_node_reloc,
......@@ -9770,6 +9807,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
97709807
97719808 _, const size = ni.location(&elf.mf).resolve(&elf.mf);
97729809 switch (elf.getNode(ni)) {
9810 .deleted => unreachable,
97739811 .archive, .archive_header => {},
97749812 .archive_input_member => unreachable,
97759813 .archive_elf_member_header => unreachable,
......@@ -9869,6 +9907,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
98699907 defer trace.end();
98709908
98719909 switch (elf.getNode(ni)) {
9910 .deleted,
98729911 .archive,
98739912 .archive_input_member,
98749913 .archive_elf_member_header,
......@@ -10002,7 +10041,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
1000210041 switch (tag) {
1000310042 else => unreachable,
1000410043 .unit_debug_info_header, .value_debug_info, .global_debug_info, .func_debug_info => {
10005 comptime assert(Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) == 1);
10044 comptime assert(Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) == 1);
1000610045 @memset(fw.unusedCapacitySlice(), @backingInt(Dwarf.AbbrevCode.null));
1000710046 },
1000810047 .unit_debug_line_header, .func_debug_line => Dwarf.genDebugLinePadding(&fw, fw.unusedCapacityLen()) catch
......@@ -10591,10 +10630,10 @@ pub fn printNode(
1059110630 .func_frame_fde, .func_debug_info, .func_debug_line => |fi| {
1059210631 const zcu = elf.base.comp.zcu.?;
1059310632 const ip = &zcu.intern_pool;
10594 const nav = ip.getNav(fi.nav(&elf.dwarf));
10633 const owner_nav = ip.getNav(fi.get(&elf.dwarf).owner_nav);
1059510634 try w.print("({f}, {f})", .{
10596 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
10597 nav.fqn.fmt(ip),
10635 Type.fromInterned(owner_nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
10636 owner_nav.fqn.fmt(ip),
1059810637 });
1059910638 },
1060010639 }
......@@ -10655,7 +10694,7 @@ fn ensureSegmentAligned(elf: *Elf, start_phndx: u32, min_align: Alignment) Error
1065510694 // Align the actual node
1065610695 const seg_ni = elf.phdrs.items[phndx].unwrap().?;
1065710696 if (min_align.compare(.gt, seg_ni.alignment(&elf.mf))) {
10658 try seg_ni.realign(&elf.mf, gpa, min_align);
10697 try seg_ni.realign(gpa, &elf.mf, min_align);
1065910698 }
1066010699 // Update the phdr `@"align"` field if necessary
1066110700 switch (elf.phdrSlice()) {
......@@ -10686,6 +10725,21 @@ fn ensureSegmentAligned(elf: *Elf, start_phndx: u32, min_align: Alignment) Error
1068610725 }
1068710726}
1068810727
10728pub fn addNodeAssumeCapacity(elf: *Elf, ni: MappedFile.Node.Index, node: Node) MappedFile.Node.Index {
10729 if (elf.nodes.len - @backingInt(ni) > 0) {
10730 assert(elf.getNode(ni) == .deleted);
10731 elf.nodes.set(@backingInt(ni), node);
10732 } else elf.nodes.appendAssumeCapacity(node);
10733 return ni;
10734}
10735
10736fn deleteNode(elf: *Elf, node: *MappedFile.Node.Index.Optional) std.mem.Allocator.Error!void {
10737 const ni = node.unwrap().?;
10738 try ni.delete(elf.base.comp.gpa, &elf.mf);
10739 elf.nodes.set(@backingInt(ni), .deleted);
10740 node.* = .none;
10741}
10742
1068910743/// If `sym` has a PLT entry, returns the address of that entry (specifically, the address which a
1069010744/// branch to the PLT should target). If `sym` does not have a PLT entry, returns `null`.
1069110745fn pltEntryTargetAddr(elf: *Elf, sym: Symbol.Id) ?u64 {
src/link/MappedFile.zig+69-56
......@@ -362,7 +362,7 @@ pub const Node = extern struct {
362362 }
363363
364364 /// Adds a floating child node to `parent_ni`. Returns the index of the new child.
365 pub fn addFloatingChild(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, opts: AddOptions) Error!Node.Index {
365 pub fn addFloatingChild(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, opts: AddOptions) Error!Node.Index {
366366 return mf.addNode(gpa, .{
367367 .add_options = opts,
368368 .position = .floating,
......@@ -373,11 +373,11 @@ pub const Node = extern struct {
373373 /// Adds a header child node to `parent_ni`. Returns the index of the new child.
374374 ///
375375 /// Asserts that `parent_ni` has no existing header children.
376 pub fn addOnlyHeaderChild(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, opts: AddOptions) Error!Node.Index {
376 pub fn addOnlyHeaderChild(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, opts: AddOptions) Error!Node.Index {
377377 if (parent_ni.first(mf).unwrap()) |first_ni| {
378378 assert(first_ni.position(mf) != .header); // `parent_ni` already has a header child
379379 }
380 return parent_ni.addHeaderChildAfter(mf, gpa, .none, opts);
380 return parent_ni.addHeaderChildAfter(gpa, mf, .none, opts);
381381 }
382382 /// Adds a header child node to `parent_ni`. Returns the index of the new child.
383383 ///
......@@ -386,7 +386,7 @@ pub const Node = extern struct {
386386 ///
387387 /// Otherwise, asserts that `prev_oni` is a header node and a child of `parent_ni`, and
388388 /// places the new child node immediately after `prev_oni`.
389 pub fn addHeaderChildAfter(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, prev_oni: Node.Index.Optional, opts: AddOptions) Error!Node.Index {
389 pub fn addHeaderChildAfter(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, prev_oni: Node.Index.Optional, opts: AddOptions) Error!Node.Index {
390390 return mf.addNode(gpa, .{
391391 .add_options = opts,
392392 .position = .header,
......@@ -397,11 +397,11 @@ pub const Node = extern struct {
397397 /// Adds a footer child node to `parent_ni`. Returns the index of the new child.
398398 ///
399399 /// Asserts that `parent_ni` has no existing footer children.
400 pub fn addOnlyFooterChild(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, opts: AddOptions) Error!Node.Index {
400 pub fn addOnlyFooterChild(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, opts: AddOptions) Error!Node.Index {
401401 if (parent_ni.last(mf).unwrap()) |last_ni| {
402402 assert(last_ni.position(mf) != .footer); // `parent_ni` already has a footer child
403403 }
404 return parent_ni.addFooterChildBefore(mf, gpa, .none, opts);
404 return parent_ni.addFooterChildBefore(gpa, mf, .none, opts);
405405 }
406406 /// Adds a footer child node to `parent_ni`. Returns the index of the new child.
407407 ///
......@@ -410,7 +410,7 @@ pub const Node = extern struct {
410410 ///
411411 /// Otherwise, asserts that `next_oni` is a footer node and a child of `parent_ni`, and
412412 /// places the new child node immediately before `next_oni`.
413 pub fn addFooterChildBefore(parent_ni: Node.Index, mf: *MappedFile, gpa: Allocator, next_oni: Node.Index.Optional, opts: AddOptions) Error!Node.Index {
413 pub fn addFooterChildBefore(parent_ni: Node.Index, gpa: Allocator, mf: *MappedFile, next_oni: Node.Index.Optional, opts: AddOptions) Error!Node.Index {
414414 const prev_oni: Node.Index.Optional = prev: {
415415 const next_ni = next_oni.unwrap() orelse {
416416 break :prev parent_ni.last(mf);
......@@ -473,8 +473,8 @@ pub const Node = extern struct {
473473 fn setNext(
474474 ni: Node.Index,
475475 gpa: Allocator,
476 next_ni: Node.Index.Optional,
477476 mf: *MappedFile,
477 next_ni: Node.Index.Optional,
478478 ) Allocator.Error!void {
479479 const next_ptr = &ni.get(mf).next;
480480 if (next_ptr.* == next_ni) return;
......@@ -571,7 +571,7 @@ pub const Node = extern struct {
571571 return ni.get(mf).flags.alignment;
572572 }
573573
574 fn setLocation(ni: Node.Index, mf: *MappedFile, gpa: Allocator, offset: u64, size: u64) Allocator.Error!void {
574 fn setLocation(ni: Node.Index, gpa: Allocator, mf: *MappedFile, offset: u64, size: u64) Allocator.Error!void {
575575 try mf.large.ensureUnusedCapacity(gpa, 2);
576576 try mf.updates.ensureUnusedCapacity(gpa, 2);
577577 const node = ni.get(mf);
......@@ -646,19 +646,37 @@ pub const Node = extern struct {
646646 return mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)];
647647 }
648648
649 pub fn trimStart(ni: Node.Index, mf: *MappedFile, gpa: Allocator) Allocator.Error!void {
649 pub fn delete(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void {
650 const node = ni.get(mf);
651 assert(node.first == .none and node.last == .none); // has children
652 mf.removeNodesFromChildList(gpa, ni, ni);
653 const updated = node.flags.moved or node.flags.resized or node.flags.next_moved;
654 node.* = undefined;
655 node.next = ni.toOptional();
656 if (!updated) assert(ni.pendingDelete(mf));
657 }
658
659 pub fn pendingDelete(ni: Node.Index, mf: *MappedFile) bool {
660 const node = ni.get(mf);
661 if (node.next != ni.toOptional()) return false;
662 node.next = mf.free_ni;
663 mf.free_ni = ni.toOptional();
664 return true;
665 }
666
667 pub fn trimStart(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void {
650668 mf.nodes_lock.assertUnlocked();
651669 const node = ni.get(mf);
652670 const first_ni = node.first.unwrap() orelse return;
653671 const shift, _ = first_ni.location(mf).resolve(mf);
654672 if (shift == 0) return;
655673 const offset, const size = node.location().resolve(mf);
656 try ni.setLocation(mf, gpa, offset + shift, size - shift);
674 try ni.setLocation(gpa, mf, offset + shift, size - shift);
657675 var child_oni = node.first;
658676 while (child_oni.unwrap()) |child_ni| {
659677 const child_node = child_ni.get(mf);
660678 const child_offset, const child_size = child_node.location().resolve(mf);
661 try child_ni.setLocation(mf, gpa, child_offset - shift, child_size);
679 try child_ni.setLocation(gpa, mf, child_offset - shift, child_size);
662680 child_oni = child_node.next;
663681 }
664682 }
......@@ -666,7 +684,7 @@ pub const Node = extern struct {
666684 /// Ensures that the size of `ni` is at least `min_size`. Valid for any node.
667685 ///
668686 /// Applies `growth_factor` if necessary (so the caller should *not* apply `growth_factor`).
669 pub fn ensureMinimumSize(ni: Node.Index, mf: *MappedFile, gpa: Allocator, min_size: u64) Error!void {
687 pub fn ensureMinimumSize(ni: Node.Index, gpa: Allocator, mf: *MappedFile, min_size: u64) Error!void {
670688 _, const current_size = ni.location(mf).resolve(mf);
671689 if (current_size >= min_size) return;
672690 const new_size = ni.alignment(mf).forward(min_size +| min_size / growth_factor);
......@@ -682,7 +700,7 @@ pub const Node = extern struct {
682700 /// Asserts that `ni` is a leaf node, i.e. has no children.
683701 ///
684702 /// Asserts that `size` is aligned to `ni.alignment(mf)`.
685 pub fn resizeLeaf(ni: Node.Index, mf: *MappedFile, gpa: Allocator, size: u64) Error!void {
703 pub fn resizeLeaf(ni: Node.Index, gpa: Allocator, mf: *MappedFile, size: u64) Error!void {
686704 assert(ni.first(mf) == .none);
687705 // The alignment of `size` is asserted by `shrinkLeafNode` and `growNode`.
688706 _, const old_size = ni.location(mf).resolve(mf);
......@@ -702,17 +720,12 @@ pub const Node = extern struct {
702720 /// If the node's current offset or size is not sufficiently aligned, it will be moved
703721 /// and/or resized to match the new alignment. The node's size may be increased by any
704722 /// amount, as if `ensureMinimumSize` were used.
705 pub fn realign(
706 ni: Node.Index,
707 mf: *MappedFile,
708 gpa: Allocator,
709 new_alignment: Alignment,
710 ) Error!void {
723 pub fn realign(ni: Node.Index, gpa: Allocator, mf: *MappedFile, new_alignment: Alignment) Error!void {
711724 try mf.realignNode(gpa, ni, new_alignment);
712725 mf.updateWriters();
713726 }
714727
715 pub fn writer(ni: Node.Index, mf: *MappedFile, gpa: Allocator, w: *Writer) void {
728 pub fn writer(ni: Node.Index, gpa: Allocator, mf: *MappedFile, w: *Writer) void {
716729 w.* = .{
717730 .gpa = gpa,
718731 .mf = mf,
......@@ -842,7 +855,7 @@ pub const Node = extern struct {
842855 ) Io.Writer.Error!void {
843856 _ = preserve;
844857 const w: *Writer = @fieldParentPtr("interface", interface);
845 w.ni.ensureMinimumSize(w.mf, w.gpa, interface.end + unused_capacity) catch |err| {
858 w.ni.ensureMinimumSize(w.gpa, w.mf, interface.end + unused_capacity) catch |err| {
846859 w.err = err;
847860 return error.WriteFailed;
848861 };
......@@ -1014,7 +1027,7 @@ fn shrinkLeafNode(
10141027 },
10151028 };
10161029 try mf.ensureTotalCapacityPrecise(@intCast(new_size));
1017 try ni.setLocation(mf, gpa, old_offset, new_size);
1030 try ni.setLocation(gpa, mf, old_offset, new_size);
10181031 return;
10191032 };
10201033
......@@ -1022,7 +1035,7 @@ fn shrinkLeafNode(
10221035 .header => {
10231036 const shift = old_size - new_size;
10241037
1025 try ni.setLocation(mf, gpa, old_offset, new_size);
1038 try ni.setLocation(gpa, mf, old_offset, new_size);
10261039
10271040 // We need to shift backwards all header nodes following us.
10281041 const next_header_ni = ni.next(mf).unwrap() orelse return;
......@@ -1031,7 +1044,7 @@ fn shrinkLeafNode(
10311044 var header_ni = next_header_ni;
10321045 while (true) {
10331046 const old_header_off, const old_header_size = header_ni.location(mf).resolve(mf);
1034 try header_ni.setLocation(mf, gpa, old_header_off - shift, old_header_size);
1047 try header_ni.setLocation(gpa, mf, old_header_off - shift, old_header_size);
10351048
10361049 const next_ni = header_ni.next(mf).unwrap() orelse break;
10371050 if (next_ni.position(mf) != .header) break;
......@@ -1056,13 +1069,13 @@ fn shrinkLeafNode(
10561069 );
10571070 },
10581071 .floating => {
1059 try ni.setLocation(mf, gpa, old_offset, new_size);
1072 try ni.setLocation(gpa, mf, old_offset, new_size);
10601073 },
10611074 .footer => {
10621075 const shift = old_size - new_size;
10631076
10641077 const new_offset = old_offset + shift;
1065 try ni.setLocation(mf, gpa, new_offset, new_size);
1078 try ni.setLocation(gpa, mf, new_offset, new_size);
10661079
10671080 const prev_footers_size = prev_footers_size: {
10681081 // We need to shift forwards all footer nodes preceding us.
......@@ -1076,7 +1089,7 @@ fn shrinkLeafNode(
10761089 var footer_ni = prev_footer_ni;
10771090 while (true) {
10781091 const old_footer_off, const old_footer_size = footer_ni.location(mf).resolve(mf);
1079 try footer_ni.setLocation(mf, gpa, old_footer_off + shift, old_footer_size);
1092 try footer_ni.setLocation(gpa, mf, old_footer_off + shift, old_footer_size);
10801093
10811094 const prev_ni = footer_ni.prev(mf).unwrap() orelse break;
10821095 if (prev_ni.position(mf) != .footer) break;
......@@ -1159,7 +1172,7 @@ fn growNode(
11591172 },
11601173 };
11611174 try mf.ensureTotalCapacityPrecise(@intCast(new_size));
1162 try ni.setLocation(mf, gpa, old_offset, new_size);
1175 try ni.setLocation(gpa, mf, old_offset, new_size);
11631176 if (grow_options.move_footers) {
11641177 // We need to move any footers to be at the *new* end of the file.
11651178 if (ni.firstFooter(mf).unwrap()) |first_footer_ni| {
......@@ -1174,7 +1187,7 @@ fn growNode(
11741187 var cur_ni = first_footer_ni;
11751188 while (true) {
11761189 const old_footer_offset, const footer_size = cur_ni.location(mf).resolve(mf);
1177 try cur_ni.setLocation(mf, gpa, old_footer_offset + (new_size - old_size), footer_size);
1190 try cur_ni.setLocation(gpa, mf, old_footer_offset + (new_size - old_size), footer_size);
11781191 cur_ni = cur_ni.next(mf).unwrap() orelse break;
11791192 }
11801193 }
......@@ -1233,8 +1246,8 @@ fn growNode(
12331246 while (true) {
12341247 const old_sub_footer_offset, const sub_footer_size = cur_ni.location(mf).resolve(mf);
12351248 try cur_ni.setLocation(
1236 mf,
12371249 gpa,
1250 mf,
12381251 old_sub_footer_offset + (new_size - old_size),
12391252 sub_footer_size,
12401253 );
......@@ -1249,8 +1262,8 @@ fn growNode(
12491262 assert(moved_header_ni.position(mf) == .header);
12501263 const moved_header_offset, const moved_header_size = moved_header_ni.location(mf).resolve(mf);
12511264 try moved_header_ni.setLocation(
1252 mf,
12531265 gpa,
1266 mf,
12541267 moved_header_offset - old_size + new_size,
12551268 moved_header_size,
12561269 );
......@@ -1259,7 +1272,7 @@ fn growNode(
12591272 }
12601273
12611274 // Finally, update our own size:
1262 try ni.setLocation(mf, gpa, old_offset, new_size);
1275 try ni.setLocation(gpa, mf, old_offset, new_size);
12631276 return;
12641277 },
12651278 .floating => {
......@@ -1387,8 +1400,8 @@ fn growNode(
13871400
13881401 // Update our own offset and size:
13891402 try ni.setLocation(
1390 mf,
13911403 gpa,
1404 mf,
13921405 node.location().resolve(mf)[0] - shift,
13931406 new_size,
13941407 );
......@@ -1399,7 +1412,7 @@ fn growNode(
13991412 var footer_oni = first_sub_footer_oni;
14001413 while (footer_oni.unwrap()) |footer_ni| : (footer_oni = footer_ni.next(mf)) {
14011414 const old_footer_offset, const footer_size = footer_ni.location(mf).resolve(mf);
1402 try footer_ni.setLocation(mf, gpa, old_footer_offset + shift, footer_size);
1415 try footer_ni.setLocation(gpa, mf, old_footer_offset + shift, footer_size);
14031416 }
14041417 }
14051418
......@@ -1414,7 +1427,7 @@ fn growNode(
14141427 while (footer_ni != ni) : (footer_ni = footer_ni.next(mf).unwrap().?) {
14151428 moved_has_content = moved_has_content or footer_ni.get(mf).flags.has_content;
14161429 const old_footer_offset, const footer_size = footer_ni.location(mf).resolve(mf);
1417 try footer_ni.setLocation(mf, gpa, old_footer_offset - shift, footer_size);
1430 try footer_ni.setLocation(gpa, mf, old_footer_offset - shift, footer_size);
14181431 }
14191432 }
14201433
......@@ -1466,8 +1479,8 @@ fn growNode(
14661479 }
14671480
14681481 try ni.setLocation(
1469 mf,
14701482 gpa,
1483 mf,
14711484 node.location().resolve(mf)[0],
14721485 actual_new_size,
14731486 );
......@@ -1483,7 +1496,7 @@ fn growNode(
14831496 assert(footer_ni.position(mf) == .footer);
14841497 moved_has_content = moved_has_content or footer_ni.get(mf).flags.has_content;
14851498 const footer_old_offset: u64, const footer_size: u64 = footer_ni.location(mf).resolve(mf);
1486 try footer_ni.setLocation(mf, gpa, footer_old_offset + shift, footer_size);
1499 try footer_ni.setLocation(gpa, mf, footer_old_offset + shift, footer_size);
14871500 }
14881501 }
14891502
......@@ -1494,7 +1507,7 @@ fn growNode(
14941507 assert(footer_ni.position(mf) == .footer);
14951508 moved_has_content = moved_has_content or footer_ni.get(mf).flags.has_content;
14961509 const footer_old_offset: u64, const footer_size: u64 = footer_ni.location(mf).resolve(mf);
1497 try footer_ni.setLocation(mf, gpa, footer_old_offset + shift, footer_size);
1510 try footer_ni.setLocation(gpa, mf, footer_old_offset + shift, footer_size);
14981511 }
14991512 }
15001513
......@@ -1566,7 +1579,7 @@ fn growFloatingNodeWithAlignment(
15661579 break :grow_in_place; // the parent is not big enough
15671580 }
15681581 // Great, we can grow this node without changing its offset or moving any siblings.
1569 try ni.setLocation(mf, gpa, old_offset, new_size);
1582 try ni.setLocation(gpa, mf, old_offset, new_size);
15701583 if (grow_options.move_footers) {
15711584 // If we have any footers, we need to move them to the end of our new size, and update
15721585 // their offsets accordingly.
......@@ -1576,7 +1589,7 @@ fn growFloatingNodeWithAlignment(
15761589 while (true) {
15771590 footers_have_content = footers_have_content or cur_ni.get(mf).flags.has_content;
15781591 const old_footer_offset, const footer_size = cur_ni.location(mf).resolve(mf);
1579 try cur_ni.setLocation(mf, gpa, old_footer_offset + (new_size - old_size), footer_size);
1592 try cur_ni.setLocation(gpa, mf, old_footer_offset + (new_size - old_size), footer_size);
15801593 cur_ni = cur_ni.next(mf).unwrap() orelse break;
15811594 }
15821595 if (footers_have_content) {
......@@ -1713,7 +1726,7 @@ fn growFloatingNodeWithAlignment(
17131726 footers_have_content = footers_have_content or cur_ni.get(mf).flags.has_content;
17141727 const old_footer_offset, const footer_size = cur_ni.location(mf).resolve(mf);
17151728 // Our footers' offsets must change to be at the end of our new size.
1716 try cur_ni.setLocation(mf, gpa, old_footer_offset + (new_size - old_size), footer_size);
1729 try cur_ni.setLocation(gpa, mf, old_footer_offset + (new_size - old_size), footer_size);
17171730 cur_ni = cur_ni.next(mf).unwrap() orelse break;
17181731 }
17191732
......@@ -1740,7 +1753,7 @@ fn growFloatingNodeWithAlignment(
17401753 assert(!footers_have_content);
17411754 }
17421755
1743 try ni.setLocation(mf, gpa, new_loc.offset, new_size);
1756 try ni.setLocation(gpa, mf, new_loc.offset, new_size);
17441757
17451758 if (new_loc.prev != ni.toOptional()) {
17461759 // We're potentially in a different place in `parent_ni`'s child list, so remove and re-add ourselves.
......@@ -1940,11 +1953,11 @@ fn growNodeViaInsertRange(
19401953 if (cur_ni == .root) {
19411954 try mf.ensureTotalCapacityPrecise(@intCast(this_old_size + range_size));
19421955 }
1943 try cur_ni.setLocation(mf, gpa, this_offset, this_old_size + range_size);
1956 try cur_ni.setLocation(gpa, mf, this_offset, this_old_size + range_size);
19441957
19451958 while (cur_ni.next(mf).unwrap()) |next_ni| {
19461959 const next_old_offset, const next_size = next_ni.location(mf).resolve(mf);
1947 try next_ni.setLocation(mf, gpa, next_old_offset + range_size, next_size);
1960 try next_ni.setLocation(gpa, mf, next_old_offset + range_size, next_size);
19481961 cur_ni = next_ni;
19491962 }
19501963
......@@ -1957,7 +1970,7 @@ fn growNodeViaInsertRange(
19571970 var footer_ni = first_footer_ni;
19581971 while (true) {
19591972 const old_footer_offset, const footer_size = footer_ni.location(mf).resolve(mf);
1960 try footer_ni.setLocation(mf, gpa, old_footer_offset + range_size, footer_size);
1973 try footer_ni.setLocation(gpa, mf, old_footer_offset + range_size, footer_size);
19611974 footer_ni = footer_ni.next(mf).unwrap() orelse break;
19621975 }
19631976 }
......@@ -2125,7 +2138,7 @@ fn ensureAdditionalHeaderCapacity(
21252138 const old_offset, const old_size = cur_ni.location(mf).resolve(mf);
21262139 const new_offset = old_offset - moving_offset + dest_offset;
21272140 assert(cur_ni.alignment(mf).check(new_offset));
2128 try cur_ni.setLocation(mf, gpa, new_offset, old_size);
2141 try cur_ni.setLocation(gpa, mf, new_offset, old_size);
21292142 if (cur_ni == last_moving_ni) break;
21302143 cur_ni = cur_ni.next(mf).unwrap().?;
21312144 }
......@@ -2168,7 +2181,7 @@ fn removeNodesFromChildList(
21682181
21692182 if (prev_oni.unwrap()) |prev_ni| {
21702183 assert(prev_ni.next(mf).unwrap().? == first_remove_ni);
2171 try prev_ni.setNext(gpa, next_oni, mf);
2184 try prev_ni.setNext(gpa, mf, next_oni);
21722185 } else {
21732186 assert(parent_ni.first(mf).unwrap().? == first_remove_ni);
21742187 parent_ni.get(mf).first = next_oni;
......@@ -2207,11 +2220,11 @@ fn addNodesToChildListBefore(
22072220 };
22082221
22092222 first_add_ni.get(mf).prev = prev_oni;
2210 try last_add_ni.setNext(gpa, next_oni, mf);
2223 try last_add_ni.setNext(gpa, mf, next_oni);
22112224
22122225 if (prev_oni.unwrap()) |prev_ni| {
22132226 assert(prev_ni.next(mf) == next_oni);
2214 try prev_ni.setNext(gpa, .wrap(first_add_ni), mf);
2227 try prev_ni.setNext(gpa, mf, .wrap(first_add_ni));
22152228 } else {
22162229 assert(parent_ni.first(mf) == next_oni);
22172230 parent_ni.get(mf).first = .wrap(first_add_ni);
......@@ -2652,7 +2665,7 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void {
26522665 for (1..n) |_| cur_ni = cur_ni.next(&mf).unwrap().?;
26532666 break :prev_oni .wrap(cur_ni);
26542667 };
2655 const new_ni = try parent_ni.addHeaderChildAfter(&mf, gpa, prev_oni, .{
2668 const new_ni = try parent_ni.addHeaderChildAfter(gpa, &mf, prev_oni, .{
26562669 .size = size,
26572670 .alignment = alignment,
26582671 });
......@@ -2660,7 +2673,7 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void {
26602673 break :new_ni new_ni;
26612674 },
26622675
2663 .floating => try parent_ni.addFloatingChild(&mf, gpa, .{
2676 .floating => try parent_ni.addFloatingChild(gpa, &mf, .{
26642677 .size = size,
26652678 .alignment = alignment,
26662679 }),
......@@ -2674,7 +2687,7 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void {
26742687 for (1..n) |_| cur_ni = cur_ni.prev(&mf).unwrap().?;
26752688 break :next_oni .wrap(cur_ni);
26762689 };
2677 const new_ni = try parent_ni.addFooterChildBefore(&mf, gpa, next_oni, .{
2690 const new_ni = try parent_ni.addFooterChildBefore(gpa, &mf, next_oni, .{
26782691 .size = size,
26792692 .alignment = alignment,
26802693 });
......@@ -2708,13 +2721,13 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void {
27082721 if (ni.first(&mf) == .none and smith.value(bool)) {
27092722 // Since this is a leaf node, we can use `resizeLeaf`.
27102723 const new_size = alignment.forward(smith.valueWeighted(u64, initial_size_weights));
2711 try ni.resizeLeaf(&mf, gpa, new_size);
2724 try ni.resizeLeaf(gpa, &mf, new_size);
27122725 if (new_size == 0) {
27132726 node_info.initialized = false;
27142727 }
27152728 } else {
27162729 const min_size = alignment.forward(smith.valueWeighted(u64, initial_size_weights));
2717 try ni.ensureMinimumSize(&mf, gpa, min_size);
2730 try ni.ensureMinimumSize(gpa, &mf, min_size);
27182731 }
27192732
27202733 if (ni.first(&mf) == .none) {
......@@ -2740,7 +2753,7 @@ fn fuzzOneNodeOperations(_: void, smith: *std.testing.Smith) anyerror!void {
27402753 const new_alignment = smith.valueWeighted(Alignment, alignment_weights);
27412754 if (new_alignment.compare(.gt, ni.alignment(&mf))) {
27422755 _, const old_size = ni.location(&mf).resolve(&mf);
2743 try ni.realign(&mf, gpa, new_alignment);
2756 try ni.realign(gpa, &mf, new_alignment);
27442757 if (ni.first(&mf) == .none and nodes.get(ni).?.initialized) {
27452758 const slice = ni.slice(&mf);
27462759 @memmove(slice[slice.len - 4 ..][0..4], slice[old_size - 4 ..][0..4]);