authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-14 19:27:16-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 12:59:38-04:00
log1b9e78d8e538c023281d597960ec15ca9e2211ad
tree5fa8e1eb3fe2f4effd9f102015f78c5a73d6969f
parentf7a6d64ffb77db10d8f61effe0e7f6d1bc6d84cd

Elf2: fix incremental test failure caused by empty lazy symbols


5 files changed, 228 insertions(+), 189 deletions(-)

src/codegen/loongarch/Mir.zig+1-1
......@@ -115,7 +115,7 @@ pub fn emit(
115115 @fromBackingInt(ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err|
116116 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)}))
117117 else if (lf.cast(.elf2)) |elf|
118 elf.lazySymbol(pt, lazy_reloc.symbol) catch |err|
118 elf.lazySymbol(lazy_reloc.symbol) catch |err|
119119 return zcu.codegenFail(func.owner_nav, "emit lazy symbol: {t}", .{err})
120120 else
121121 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
src/codegen/x86_64/Emit.zig+1-1
......@@ -138,7 +138,7 @@ pub fn emitMir(emit: *Emit) Error!void {
138138 return emit.fail("{s} creating lazy symbol", .{@errorName(err)}),
139139 ))
140140 else if (emit.bin_file.cast(.elf2)) |elf|
141 try elf.lazySymbol(emit.pt, lazy_sym)
141 try elf.lazySymbol(lazy_sym)
142142 else if (emit.bin_file.cast(.macho)) |macho_file|
143143 @fromBackingInt(@intCast(macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
144144 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})))
src/link/Coff.zig+28-44
......@@ -5504,27 +5504,7 @@ pub fn updateContainerType(
55045504 while (lazy_it.next()) |lazy| if (lazy.value.map.getIndex(ty)) |lmi| {
55055505 if (lazy.value.pending_index <= lmi) continue;
55065506 // This type has changed on this incremental update, so update the lazy code/data.
5507 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = @intCast(lmi) };
5508 const kind = switch (lmr.kind) {
5509 .code => "code",
5510 .const_data => "data",
5511 };
5512 var name: [std.Progress.Node.max_name_len]u8 = undefined;
5513 const sub_prog_node = coff.synth_prog_node.start(
5514 std.mem.print(&name, "lazy {s} for {f}", .{
5515 kind,
5516 Type.fromInterned(ty).fmt(pt),
5517 }) catch &name,
5518 0,
5519 );
5520 defer sub_prog_node.end();
5521 coff.genLazy(pt, lmr) catch |err| switch (err) {
5522 else => |e| return e,
5523 error.MappedFileIo => return coff.base.comp.link_diags.fail(
5524 "linker failed to lower lazy {s}: {t}",
5525 .{ kind, coff.mf.io_err.? },
5526 ),
5527 };
5507 try coff.genLazy(pt, .{ .kind = lazy.key, .index = @intCast(lmi) });
55285508 };
55295509}
55305510
......@@ -5647,7 +5627,7 @@ fn updateFuncInner(
56475627}
56485628
56495629pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void {
5650 coff.genLazy(pt, .{
5630 coff.genLazyInner(pt, .{
56515631 .kind = .const_data,
56525632 .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
56535633 }) catch |err| switch (err) {
......@@ -6163,29 +6143,9 @@ fn genPending(coff: *Coff, pt: Zcu.PerThread) Error!void {
61636143 };
61646144 }
61656145 var lazy_it = coff.lazy.iterator();
6166 while (lazy_it.next()) |lazy| if (lazy.value.pending_index < lazy.value.map.count()) {
6167 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = lazy.value.pending_index };
6146 while (lazy_it.next()) |lazy| while (lazy.value.pending_index < lazy.value.map.count()) {
6147 try coff.genLazy(pt, .{ .kind = lazy.key, .index = lazy.value.pending_index });
61686148 lazy.value.pending_index += 1;
6169 const kind = switch (lmr.kind) {
6170 .code => "code",
6171 .const_data => "data",
6172 };
6173 var name: [std.Progress.Node.max_name_len]u8 = undefined;
6174 const sub_prog_node = coff.synth_prog_node.start(
6175 std.mem.print(&name, "lazy {s} for {f}", .{
6176 kind,
6177 Type.fromInterned(lmr.lazySymbol(coff).ty).fmt(pt),
6178 }) catch &name,
6179 0,
6180 );
6181 defer sub_prog_node.end();
6182 coff.genLazy(pt, lmr) catch |err| switch (err) {
6183 else => |e| return e,
6184 error.MappedFileIo => return comp.link_diags.fail(
6185 "linker failed to lower lazy {s}: {t}",
6186 .{ kind, coff.mf.io_err.? },
6187 ),
6188 };
61896149 };
61906150}
61916151
......@@ -6810,6 +6770,30 @@ fn flushSpecialSymbol(coff: *Coff, pending: SpecialSymbol) !SpecialSymbol {
68106770}
68116771
68126772fn genLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
6773 const lazy = lmr.lazySymbol(coff);
6774 if (lazy.ty == .anyerror_type) return;
6775 const kind = switch (lmr.kind) {
6776 .code => "code",
6777 .const_data => "data",
6778 };
6779 var name: [std.Progress.Node.max_name_len]u8 = undefined;
6780 const sub_prog_node = coff.synth_prog_node.start(
6781 std.mem.print(&name, "lazy {s} for {f}", .{
6782 kind,
6783 Type.fromInterned(lazy.ty).fmt(pt),
6784 }) catch &name,
6785 0,
6786 );
6787 defer sub_prog_node.end();
6788 coff.genLazyInner(pt, lmr) catch |err| switch (err) {
6789 else => |e| return e,
6790 error.MappedFileIo => return coff.base.comp.link_diags.fail(
6791 "linker failed to lower lazy {s}: {t}",
6792 .{ kind, coff.mf.io_err.? },
6793 ),
6794 };
6795}
6796fn genLazyInner(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
68136797 const zcu = pt.zcu;
68146798 const gpa = zcu.gpa;
68156799
src/link/Dwarf2.zig+50-48
......@@ -1487,28 +1487,29 @@ pub fn getGlobal(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Global.Ind
14871487 .debug_info_ni = .none,
14881488 };
14891489 const gi: Global.Index = @fromBackingInt(@intCast(global_gop.index));
1490 if (global_gop.value_ptr.debug_info_ni == .none) {
1491 const elf = dwarf.lf.cast(.elf2).?;
1492 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1493 try elf.dwarf_globals.ensureUnusedCapacity(gpa, 1);
1494 const unit = dwarf.getUnit(comp.zcu.?.navFileScope(nav).mod.?).get(dwarf);
1495 global_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(
1496 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
1497 .enable_next_moved = true,
1498 }) catch |err| switch (err) {
1499 else => |e| return e,
1500 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1501 elf.mf.io_err.?,
1502 }),
1503 },
1504 .{ .global_debug_info = gi },
1505 ));
1506 elf.dwarf_globals.addOneAssumeCapacity().* = .{
1507 .debug_info_first_target_reloc = .none,
1508 .debug_info_first_node_reloc = .none,
1509 .debug_info_first_symbol_reloc = .none,
1510 };
1511 }
1490 if (global_gop.value_ptr.debug_info_ni != .none) return gi;
1491 const mod = comp.zcu.?.navFileScope(nav).mod.?;
1492 assert(!mod.strip);
1493 const elf = dwarf.lf.cast(.elf2).?;
1494 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1495 try elf.dwarf_globals.ensureUnusedCapacity(gpa, 1);
1496 const unit = dwarf.getUnit(mod).get(dwarf);
1497 global_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(
1498 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
1499 .enable_next_moved = true,
1500 }) catch |err| switch (err) {
1501 else => |e| return e,
1502 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1503 elf.mf.io_err.?,
1504 }),
1505 },
1506 .{ .global_debug_info = gi },
1507 ));
1508 elf.dwarf_globals.addOneAssumeCapacity().* = .{
1509 .debug_info_first_target_reloc = .none,
1510 .debug_info_first_node_reloc = .none,
1511 .debug_info_first_symbol_reloc = .none,
1512 };
15121513 return gi;
15131514}
15141515pub fn getGlobalIfExists(dwarf: *Dwarf, nav: InternPool.Nav.Index) ?Global.Index {
......@@ -1525,32 +1526,33 @@ pub fn getFunc(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Func.Index {
15251526 .debug_line_ni = .none,
15261527 };
15271528 const fi: Func.Index = @fromBackingInt(@intCast(func_gop.index));
1528 if (func_gop.value_ptr.debug_info_ni == .none) {
1529 const elf = dwarf.lf.cast(.elf2).?;
1530 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1531 try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1);
1532 const unit = dwarf.getUnit(comp.zcu.?.navFileScope(nav).mod.?).get(dwarf);
1533 func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(
1534 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
1535 .enable_next_moved = true,
1536 }) catch |err| switch (err) {
1537 else => |e| return e,
1538 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1539 elf.mf.io_err.?,
1540 }),
1541 },
1542 .{ .func_debug_info = fi },
1543 ));
1544 elf.dwarf_funcs.addOneAssumeCapacity().* = .{
1545 .frame_fde_first_symbol_reloc = .none,
1546 .frame_fde_first_node_reloc = .none,
1547 .debug_info_first_target_reloc = .none,
1548 .debug_info_first_symbol_reloc = .none,
1549 .debug_info_first_node_reloc = .none,
1550 .debug_line_first_symbol_reloc = .none,
1551 .debug_line_first_node_reloc = .none,
1552 };
1553 }
1529 if (func_gop.value_ptr.debug_info_ni != .none) return fi;
1530 const mod = comp.zcu.?.navFileScope(nav).mod.?;
1531 const elf = dwarf.lf.cast(.elf2).?;
1532 try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1);
1533 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1534 elf.dwarf_funcs.addOneAssumeCapacity().* = .{
1535 .frame_fde_first_symbol_reloc = .none,
1536 .frame_fde_first_node_reloc = .none,
1537 .debug_info_first_target_reloc = .none,
1538 .debug_info_first_symbol_reloc = .none,
1539 .debug_info_first_node_reloc = .none,
1540 .debug_line_first_symbol_reloc = .none,
1541 .debug_line_first_node_reloc = .none,
1542 };
1543 if (mod.strip) return fi;
1544 const unit = dwarf.getUnit(mod).get(dwarf);
1545 func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(
1546 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
1547 .enable_next_moved = true,
1548 }) catch |err| switch (err) {
1549 else => |e| return e,
1550 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1551 elf.mf.io_err.?,
1552 }),
1553 },
1554 .{ .func_debug_info = fi },
1555 ));
15541556 return fi;
15551557}
15561558pub fn getFuncIfExists(dwarf: *Dwarf, nav: InternPool.Nav.Index) ?Func.Index {
src/link/Elf2.zig+148-95
......@@ -185,13 +185,16 @@ uavs: std.array_hash_map.Auto(InternPool.Index, struct {
185185 first_symbol_reloc: SymbolReloc.Index,
186186 // No `first_got_reloc` field because a UAV never contains GOT relocations.
187187}),
188lazy: std.EnumArray(link.File.LazySymbol.Kind, std.array_hash_map.Auto(link.ConstPool.Index, struct {
189 lsi: Symbol.LocalIndex,
190 /// The start index of the contiguous sequence of symbol relocations in this lazy code/data.
191 first_symbol_reloc: SymbolReloc.Index,
192 /// The start index of the contiguous sequence of GOT relocations in this lazy code/data.
193 first_got_reloc: GotReloc.Index,
194})),
188lazy: std.EnumArray(link.File.LazySymbol.Kind, struct {
189 map: std.array_hash_map.Auto(InternPool.Index, struct {
190 lsi: Symbol.LocalIndex,
191 /// The start index of the contiguous sequence of symbol relocations in this lazy code/data.
192 first_symbol_reloc: SymbolReloc.Index,
193 /// The start index of the contiguous sequence of GOT relocations in this lazy code/data.
194 first_got_reloc: GotReloc.Index,
195 }),
196 pending_index: u32,
197}),
195198pending_uavs: std.ArrayList(Node.UavMapIndex),
196199symbol_relocs: std.ArrayList(SymbolReloc),
197200node_relocs: std.ArrayList(NodeReloc),
......@@ -391,23 +394,20 @@ const Node = union(enum) {
391394 }
392395
393396 fn firstSymbolReloc(lmi: @This(), elf: *const Elf) SymbolReloc.Index {
394 return elf.lazy.getPtrConst(kind).values()[@backingInt(lmi)].first_symbol_reloc;
397 return elf.lazy.getPtrConst(kind).map.values()[@backingInt(lmi)].first_symbol_reloc;
395398 }
396399 fn firstGotReloc(lmi: @This(), elf: *const Elf) GotReloc.Index {
397 return elf.lazy.getPtrConst(kind).values()[@backingInt(lmi)].first_got_reloc;
400 return elf.lazy.getPtrConst(kind).map.values()[@backingInt(lmi)].first_got_reloc;
398401 }
399402 };
400403 }
401404
402405 pub fn lazySymbol(lmr: LazyMapRef, elf: *const Elf) link.File.LazySymbol {
403 return .{
404 .kind = lmr.kind,
405 .ty = elf.lazy.getPtrConst(lmr.kind).keys()[lmr.index].val(&elf.dwarf.const_pool),
406 };
406 return .{ .kind = lmr.kind, .ty = elf.lazy.getPtrConst(lmr.kind).map.keys()[lmr.index] };
407407 }
408408
409409 pub fn symbol(lmr: LazyMapRef, elf: *const Elf) Symbol.LocalIndex {
410 return elf.lazy.getPtrConst(lmr.kind).values()[lmr.index].lsi;
410 return elf.lazy.getPtrConst(lmr.kind).map.values()[lmr.index].lsi;
411411 }
412412 };
413413
......@@ -3340,26 +3340,20 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
33403340 const s: Symbol.Id = .local(lsi);
33413341 return s.toTypeErased();
33423342}
3343pub fn lazySymbol(
3344 elf: *Elf,
3345 pt: Zcu.PerThread,
3346 lazy: link.File.LazySymbol,
3347) link.Error!link.File.SymbolId {
3348 const diags = &elf.base.comp.link_diags;
3349 return elf.lazySymbolInner(pt, lazy) catch |err| switch (err) {
3343pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) link.Error!link.File.SymbolId {
3344 return elf.lazySymbolInner(lazy) catch |err| switch (err) {
33503345 else => |e| return e,
3351 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3346 error.MappedFileIo => return elf.base.comp.link_diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
33523347 };
33533348}
3354fn lazySymbolInner(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol) Error!link.File.SymbolId {
3349fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId {
33553350 const gpa = elf.base.comp.gpa;
33563351
33573352 try elf.ensureUnusedSymbolCapacity(1, .all_local);
33583353 try elf.nodes.ensureUnusedCapacity(gpa, 1);
3359 try elf.lazy.getPtr(lazy.kind).ensureUnusedCapacity(gpa, 1);
3354 try elf.lazy.getPtr(lazy.kind).map.ensureUnusedCapacity(gpa, 1);
33603355
3361 const cpi = try elf.dwarf.const_pool.get(pt, .{ .elf2 = elf }, lazy.ty);
3362 const gop = elf.lazy.getPtr(lazy.kind).getOrPutAssumeCapacity(cpi);
3356 const gop = elf.lazy.getPtr(lazy.kind).map.getOrPutAssumeCapacity(lazy.ty);
33633357 if (!gop.found_existing) {
33643358 const shndx: Section.Index, const sym_type: std.elf.STT = switch (lazy.kind) {
33653359 .code => .{ .text, .FUNC },
......@@ -3819,7 +3813,10 @@ fn create(
38193813 .one_shot_fixups = .empty,
38203814 .navs = .empty,
38213815 .uavs = .empty,
3822 .lazy = comptime .initFill(.empty),
3816 .lazy = comptime .initFill(.{
3817 .map = .empty,
3818 .pending_index = 0,
3819 }),
38233820 .pending_uavs = .empty,
38243821 .symbol_relocs = .empty,
38253822 .node_relocs = .empty,
......@@ -3881,7 +3878,7 @@ pub fn deinit(elf: *Elf) void {
38813878 elf.one_shot_fixups.deinit(gpa);
38823879 elf.navs.deinit(gpa);
38833880 elf.uavs.deinit(gpa);
3884 for (&elf.lazy.values) |*lazy| lazy.deinit(gpa);
3881 for (&elf.lazy.values) |*lazy| lazy.map.deinit(gpa);
38853882 elf.pending_uavs.deinit(gpa);
38863883 elf.symbol_relocs.deinit(gpa);
38873884 elf.node_relocs.deinit(gpa);
......@@ -5361,8 +5358,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
53615358 .first_symbol_reloc = &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc,
53625359 },
53635360 inline .lazy_code, .lazy_const_data => |lmi| .{
5364 .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_symbol_reloc,
5365 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_got_reloc,
5361 .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_symbol_reloc,
5362 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_got_reloc,
53665363 },
53675364 .unit_debug_info_header => |ui| .{
53685365 .first_node_reloc = &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_node_reloc,
......@@ -7137,24 +7134,38 @@ fn prelinkInner(elf: *Elf) Error!void {
71377134 };
71387135 elf.input_pending_index += 1;
71397136
7140 try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5);
7137 try elf.nodes.ensureUnusedCapacity(gpa, 5 + 4);
71417138
7142 elf.dwarf.debug_abbrev.ni = .wrap(elf.addNodeAssumeCapacity(
7143 try elf.shndx.debug_abbrev.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7144 .{ .debug_shared = .debug_abbrev },
7145 ));
7146 elf.dwarf.debug_line_str.ni = .wrap(elf.addNodeAssumeCapacity(
7147 try elf.shndx.debug_line_str.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7148 .{ .debug_shared = .debug_line_str },
7149 ));
7150 elf.dwarf.debug_str.ni = .wrap(elf.addNodeAssumeCapacity(
7151 try elf.shndx.debug_str.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7152 .{ .debug_shared = .debug_str },
7153 ));
7154 elf.dwarf.debug_str_offsets.ni = .wrap(elf.addNodeAssumeCapacity(
7155 try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7156 .{ .debug_shared = .debug_str_offsets },
7157 ));
7139 switch (elf.shndx.debug_abbrev) {
7140 .UNDEF => {},
7141 else => |debug_abbrev_shndx| elf.dwarf.debug_abbrev.ni = .wrap(elf.addNodeAssumeCapacity(
7142 try debug_abbrev_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7143 .{ .debug_shared = .debug_abbrev },
7144 )),
7145 }
7146 switch (elf.shndx.debug_line_str) {
7147 .UNDEF => {},
7148 else => |debug_line_str_shndx| elf.dwarf.debug_line_str.ni =
7149 .wrap(elf.addNodeAssumeCapacity(
7150 try debug_line_str_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7151 .{ .debug_shared = .debug_line_str },
7152 )),
7153 }
7154 switch (elf.shndx.debug_str) {
7155 .UNDEF => {},
7156 else => |debug_str_shndx| elf.dwarf.debug_str.ni = .wrap(elf.addNodeAssumeCapacity(
7157 try debug_str_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7158 .{ .debug_shared = .debug_str },
7159 )),
7160 }
7161 switch (elf.shndx.debug_str_offsets) {
7162 .UNDEF => {},
7163 else => |debug_str_offsets_shndx| elf.dwarf.debug_str_offsets.ni =
7164 .wrap(elf.addNodeAssumeCapacity(
7165 try debug_str_offsets_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}),
7166 .{ .debug_shared = .debug_str_offsets },
7167 )),
7168 }
71587169
71597170 for ([5]Section.Index{
71607171 elf.shndx.eh_frame,
......@@ -8541,8 +8552,11 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
85418552
85428553 const nav = ip.getNav(nav_index);
85438554 if (ip.indexToKey(nav.resolved.?.value) == .@"extern") return;
8544 if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu))
8545 return elf.dwarf.updateComptimeNav(pt, nav_index);
8555 if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) {
8556 if (elf.ehdrMachine() != .X86_64) return;
8557 const mod = zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?;
8558 return if (!mod.strip) elf.dwarf.updateComptimeNav(pt, nav_index);
8559 }
85468560
85478561 const nmi = try elf.navMapIndex(zcu, nav_index);
85488562 const ni = nmi.symbol(elf).index().ptr(elf).node.unwrap().?;
......@@ -8581,7 +8595,32 @@ pub fn updateContainerType(
85818595 ty: InternPool.Index,
85828596 success: bool,
85838597) link.Error!void {
8584 try elf.dwarf.const_pool.updateContainerType(pt, .{ .elf2 = elf }, ty, success);
8598 elf.updateContainerTypeInner(pt, ty, success) catch |err| switch (err) {
8599 else => |e| return e,
8600 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8601 "failed to write output file: {t}",
8602 .{elf.mf.io_err.?},
8603 ),
8604 };
8605}
8606pub fn updateContainerTypeInner(
8607 elf: *Elf,
8608 pt: Zcu.PerThread,
8609 ty: InternPool.Index,
8610 success: bool,
8611) Error!void {
8612 switch (elf.base.comp.config.debug_format) {
8613 .strip => {},
8614 .dwarf => try elf.dwarf.const_pool.updateContainerType(pt, .{ .elf2 = elf }, ty, success),
8615 .code_view => unreachable,
8616 }
8617 if (!success) return;
8618 var lazy_it = elf.lazy.iterator();
8619 while (lazy_it.next()) |lazy| if (lazy.value.map.getIndex(ty)) |lmi| {
8620 if (lazy.value.pending_index <= lmi) continue;
8621 // This type has changed on this incremental update, so update the lazy code/data.
8622 try elf.genLazy(pt, .{ .kind = lazy.key, .index = @intCast(lmi) });
8623 };
85858624}
85868625
85878626pub fn addConst(
......@@ -8590,47 +8629,24 @@ pub fn addConst(
85908629 index: link.ConstPool.Index,
85918630 val: InternPool.Index,
85928631) link.Error!void {
8593 try elf.dwarf.addConst(index, val);
8632 switch (elf.base.comp.config.debug_format) {
8633 .strip => {},
8634 .dwarf => try elf.dwarf.addConst(index, val),
8635 .code_view => unreachable,
8636 }
85948637}
85958638
85968639pub fn updateConst(
85978640 elf: *Elf,
8598 pt: Zcu.PerThread,
8599 cpi: link.ConstPool.Index,
8600 val: InternPool.Index,
8601) link.Error!void {
8602 if (val == .anyerror_type) return;
8603 try elf.updateConstInner(pt, cpi, val);
8604}
8605fn updateConstInner(
8606 elf: *Elf,
8607 pt: Zcu.PerThread,
8641 _: Zcu.PerThread,
86088642 cpi: link.ConstPool.Index,
86098643 val: InternPool.Index,
86108644) link.Error!void {
8611 var lazy_it = elf.lazy.iterator();
8612 while (lazy_it.next()) |lazy| if (lazy.value.getIndex(cpi)) |li| {
8613 const lazy_ty: Type = .fromInterned(val);
8614 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;
8615 const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(pt.zcu)) {
8616 .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
8617 .error_set => switch (lazy.key) {
8618 .code => std.mem.print(&prog_name_buf, "@errorCast({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
8619 .const_data => "@errorName(anyerror)",
8620 },
8621 else => unreachable,
8622 };
8623 const prog_node = elf.base.comp.link_prog_node.start(prog_name, 0);
8624 defer prog_node.end();
8625 elf.genLazy(pt, .{ .kind = lazy.key, .index = @intCast(li) }) catch |err| switch (err) {
8626 else => |e| return e,
8627 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8628 "failed to write output file: {t}",
8629 .{elf.mf.io_err.?},
8630 ),
8631 };
8632 };
8633 elf.dwarf.updateConst(cpi, val);
8645 switch (elf.base.comp.config.debug_format) {
8646 .strip => {},
8647 .dwarf => elf.dwarf.updateConst(cpi, val),
8648 .code_view => unreachable,
8649 }
86348650}
86358651
86368652pub fn updateConstIncomplete(
......@@ -8639,11 +8655,17 @@ pub fn updateConstIncomplete(
86398655 cpi: link.ConstPool.Index,
86408656 val: InternPool.Index,
86418657) link.Error!void {
8642 const debug_info_ni = Dwarf.Const.get(cpi, &elf.dwarf).debug_info_ni.unwrap().?;
8643 var di_nw: MappedFile.Node.Writer = undefined;
8644 debug_info_ni.writer(elf.base.comp.gpa, &elf.mf, &di_nw);
8645 defer di_nw.deinit();
8646 try elf.dwarf.updateConstIncomplete(pt, &di_nw, val);
8658 switch (elf.base.comp.config.debug_format) {
8659 .strip => {},
8660 .dwarf => {
8661 const debug_info_ni = Dwarf.Const.get(cpi, &elf.dwarf).debug_info_ni.unwrap().?;
8662 var di_nw: MappedFile.Node.Writer = undefined;
8663 debug_info_ni.writer(elf.base.comp.gpa, &elf.mf, &di_nw);
8664 defer di_nw.deinit();
8665 try elf.dwarf.updateConstIncomplete(pt, &di_nw, val);
8666 },
8667 .code_view => unreachable,
8668 }
86478669}
86488670
86498671pub fn updateFunc(
......@@ -8930,11 +8952,16 @@ pub fn lostTracking(
89308952}
89318953
89328954pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
8933 try elf.updateConstInner(
8934 pt,
8935 elf.dwarf.const_pool.getIfExists(.anyerror_type) orelse return,
8936 .anyerror_type,
8937 );
8955 elf.genLazyInner(pt, .{
8956 .kind = .const_data,
8957 .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
8958 }) catch |err| switch (err) {
8959 else => |e| return e,
8960 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8961 "failed to write output file: {t}",
8962 .{elf.mf.io_err.?},
8963 ),
8964 };
89388965}
89398966
89408967pub fn flush(
......@@ -9266,7 +9293,16 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void {
92669293 defer prog_node.end();
92679294 try elf.genUav(pt, umi);
92689295 }
9269 try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf });
9296 var lazy_it = elf.lazy.iterator();
9297 while (lazy_it.next()) |lazy| while (lazy.value.pending_index < lazy.value.map.count()) {
9298 try elf.genLazy(pt, .{ .kind = lazy.key, .index = lazy.value.pending_index });
9299 lazy.value.pending_index += 1;
9300 };
9301 switch (elf.base.comp.config.debug_format) {
9302 .strip => {},
9303 .dwarf => try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf }),
9304 .code_view => unreachable,
9305 }
92709306}
92719307
92729308fn genUav(
......@@ -9302,6 +9338,23 @@ fn genUav(
93029338}
93039339
93049340fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void {
9341 const lazy = lmr.lazySymbol(elf);
9342 if (lazy.ty == .anyerror_type) return;
9343 const lazy_ty: Type = .fromInterned(lazy.ty);
9344 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;
9345 const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(pt.zcu)) {
9346 .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
9347 .error_set => switch (lmr.kind) {
9348 .code => std.mem.print(&prog_name_buf, "@errorCast({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
9349 .const_data => "@errorName(anyerror)",
9350 },
9351 else => unreachable,
9352 };
9353 const prog_node = elf.base.comp.link_prog_node.start(prog_name, 0);
9354 defer prog_node.end();
9355 try elf.genLazyInner(pt, lmr);
9356}
9357fn genLazyInner(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void {
93059358 const zcu = pt.zcu;
93069359 const gpa = zcu.gpa;
93079360