From 1b9e78d8e538c023281d597960ec15ca9e2211ad Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 14 Aug 2026 19:27:16 -0400 Subject: [PATCH] Elf2: fix incremental test failure caused by empty lazy symbols --- src/codegen/loongarch/Mir.zig | 2 +- src/codegen/x86_64/Emit.zig | 2 +- src/link/Coff.zig | 72 ++++------ src/link/Dwarf2.zig | 98 +++++++------- src/link/Elf2.zig | 243 +++++++++++++++++++++------------- 5 files changed, 228 insertions(+), 189 deletions(-) diff --git a/src/codegen/loongarch/Mir.zig b/src/codegen/loongarch/Mir.zig index a0b90b0f730ac350723c3420f292ba5e128b9aae..f81843ff4e24ce3c395cd250844e1bed9bb368cb 100644 --- a/src/codegen/loongarch/Mir.zig +++ b/src/codegen/loongarch/Mir.zig @@ -115,7 +115,7 @@ pub fn emit( @fromBackingInt(ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err| return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})) else if (lf.cast(.elf2)) |elf| - elf.lazySymbol(pt, lazy_reloc.symbol) catch |err| + elf.lazySymbol(lazy_reloc.symbol) catch |err| return zcu.codegenFail(func.owner_nav, "emit lazy symbol: {t}", .{err}) else return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}), diff --git a/src/codegen/x86_64/Emit.zig b/src/codegen/x86_64/Emit.zig index f0961b6970a631a2e224b5f7cf71e4f52717cc75..7196aca6ef02eee3b07bcdf58d84822ee550877d 100644 --- a/src/codegen/x86_64/Emit.zig +++ b/src/codegen/x86_64/Emit.zig @@ -138,7 +138,7 @@ pub fn emitMir(emit: *Emit) Error!void { return emit.fail("{s} creating lazy symbol", .{@errorName(err)}), )) else if (emit.bin_file.cast(.elf2)) |elf| - try elf.lazySymbol(emit.pt, lazy_sym) + try elf.lazySymbol(lazy_sym) else if (emit.bin_file.cast(.macho)) |macho_file| @fromBackingInt(@intCast(macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err| return emit.fail("{s} creating lazy symbol", .{@errorName(err)}))) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 7d04b80e8d2a39b47a54b4a6dd15c4d71cbf0997..a1dd8d799bd8eebb99a4a006e83fab2d508ac8b9 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -5504,27 +5504,7 @@ pub fn updateContainerType( while (lazy_it.next()) |lazy| if (lazy.value.map.getIndex(ty)) |lmi| { if (lazy.value.pending_index <= lmi) continue; // This type has changed on this incremental update, so update the lazy code/data. - const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = @intCast(lmi) }; - const kind = switch (lmr.kind) { - .code => "code", - .const_data => "data", - }; - var name: [std.Progress.Node.max_name_len]u8 = undefined; - const sub_prog_node = coff.synth_prog_node.start( - std.mem.print(&name, "lazy {s} for {f}", .{ - kind, - Type.fromInterned(ty).fmt(pt), - }) catch &name, - 0, - ); - defer sub_prog_node.end(); - coff.genLazy(pt, lmr) catch |err| switch (err) { - else => |e| return e, - error.MappedFileIo => return coff.base.comp.link_diags.fail( - "linker failed to lower lazy {s}: {t}", - .{ kind, coff.mf.io_err.? }, - ), - }; + try coff.genLazy(pt, .{ .kind = lazy.key, .index = @intCast(lmi) }); }; } @@ -5647,7 +5627,7 @@ fn updateFuncInner( } pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void { - coff.genLazy(pt, .{ + coff.genLazyInner(pt, .{ .kind = .const_data, .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), }) catch |err| switch (err) { @@ -6163,29 +6143,9 @@ fn genPending(coff: *Coff, pt: Zcu.PerThread) Error!void { }; } var lazy_it = coff.lazy.iterator(); - while (lazy_it.next()) |lazy| if (lazy.value.pending_index < lazy.value.map.count()) { - const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = lazy.value.pending_index }; + while (lazy_it.next()) |lazy| while (lazy.value.pending_index < lazy.value.map.count()) { + try coff.genLazy(pt, .{ .kind = lazy.key, .index = lazy.value.pending_index }); lazy.value.pending_index += 1; - const kind = switch (lmr.kind) { - .code => "code", - .const_data => "data", - }; - var name: [std.Progress.Node.max_name_len]u8 = undefined; - const sub_prog_node = coff.synth_prog_node.start( - std.mem.print(&name, "lazy {s} for {f}", .{ - kind, - Type.fromInterned(lmr.lazySymbol(coff).ty).fmt(pt), - }) catch &name, - 0, - ); - defer sub_prog_node.end(); - coff.genLazy(pt, lmr) catch |err| switch (err) { - else => |e| return e, - error.MappedFileIo => return comp.link_diags.fail( - "linker failed to lower lazy {s}: {t}", - .{ kind, coff.mf.io_err.? }, - ), - }; }; } @@ -6810,6 +6770,30 @@ fn flushSpecialSymbol(coff: *Coff, pending: SpecialSymbol) !SpecialSymbol { } fn genLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { + const lazy = lmr.lazySymbol(coff); + if (lazy.ty == .anyerror_type) return; + const kind = switch (lmr.kind) { + .code => "code", + .const_data => "data", + }; + var name: [std.Progress.Node.max_name_len]u8 = undefined; + const sub_prog_node = coff.synth_prog_node.start( + std.mem.print(&name, "lazy {s} for {f}", .{ + kind, + Type.fromInterned(lazy.ty).fmt(pt), + }) catch &name, + 0, + ); + defer sub_prog_node.end(); + coff.genLazyInner(pt, lmr) catch |err| switch (err) { + else => |e| return e, + error.MappedFileIo => return coff.base.comp.link_diags.fail( + "linker failed to lower lazy {s}: {t}", + .{ kind, coff.mf.io_err.? }, + ), + }; +} +fn genLazyInner(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { const zcu = pt.zcu; const gpa = zcu.gpa; diff --git a/src/link/Dwarf2.zig b/src/link/Dwarf2.zig index 05071d246b2783e2e482d7619f0011029ecb602a..a4c34374d7831d051e6756adcbe4d4c86304105b 100644 --- a/src/link/Dwarf2.zig +++ b/src/link/Dwarf2.zig @@ -1487,28 +1487,29 @@ pub fn getGlobal(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Global.Ind .debug_info_ni = .none, }; const gi: Global.Index = @fromBackingInt(@intCast(global_gop.index)); - if (global_gop.value_ptr.debug_info_ni == .none) { - const elf = dwarf.lf.cast(.elf2).?; - try elf.nodes.ensureUnusedCapacity(gpa, 1); - try elf.dwarf_globals.ensureUnusedCapacity(gpa, 1); - const unit = dwarf.getUnit(comp.zcu.?.navFileScope(nav).mod.?).get(dwarf); - global_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity( - unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{ - .enable_next_moved = true, - }) catch |err| switch (err) { - else => |e| return e, - error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{ - elf.mf.io_err.?, - }), - }, - .{ .global_debug_info = gi }, - )); - elf.dwarf_globals.addOneAssumeCapacity().* = .{ - .debug_info_first_target_reloc = .none, - .debug_info_first_node_reloc = .none, - .debug_info_first_symbol_reloc = .none, - }; - } + if (global_gop.value_ptr.debug_info_ni != .none) return gi; + const mod = comp.zcu.?.navFileScope(nav).mod.?; + assert(!mod.strip); + const elf = dwarf.lf.cast(.elf2).?; + try elf.nodes.ensureUnusedCapacity(gpa, 1); + try elf.dwarf_globals.ensureUnusedCapacity(gpa, 1); + const unit = dwarf.getUnit(mod).get(dwarf); + global_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity( + unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{ + .enable_next_moved = true, + }) catch |err| switch (err) { + else => |e| return e, + error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{ + elf.mf.io_err.?, + }), + }, + .{ .global_debug_info = gi }, + )); + elf.dwarf_globals.addOneAssumeCapacity().* = .{ + .debug_info_first_target_reloc = .none, + .debug_info_first_node_reloc = .none, + .debug_info_first_symbol_reloc = .none, + }; return gi; } pub 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 { .debug_line_ni = .none, }; const fi: Func.Index = @fromBackingInt(@intCast(func_gop.index)); - if (func_gop.value_ptr.debug_info_ni == .none) { - const elf = dwarf.lf.cast(.elf2).?; - try elf.nodes.ensureUnusedCapacity(gpa, 1); - try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1); - const unit = dwarf.getUnit(comp.zcu.?.navFileScope(nav).mod.?).get(dwarf); - func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity( - unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{ - .enable_next_moved = true, - }) catch |err| switch (err) { - else => |e| return e, - error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{ - elf.mf.io_err.?, - }), - }, - .{ .func_debug_info = fi }, - )); - elf.dwarf_funcs.addOneAssumeCapacity().* = .{ - .frame_fde_first_symbol_reloc = .none, - .frame_fde_first_node_reloc = .none, - .debug_info_first_target_reloc = .none, - .debug_info_first_symbol_reloc = .none, - .debug_info_first_node_reloc = .none, - .debug_line_first_symbol_reloc = .none, - .debug_line_first_node_reloc = .none, - }; - } + if (func_gop.value_ptr.debug_info_ni != .none) return fi; + const mod = comp.zcu.?.navFileScope(nav).mod.?; + const elf = dwarf.lf.cast(.elf2).?; + try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1); + try elf.nodes.ensureUnusedCapacity(gpa, 1); + elf.dwarf_funcs.addOneAssumeCapacity().* = .{ + .frame_fde_first_symbol_reloc = .none, + .frame_fde_first_node_reloc = .none, + .debug_info_first_target_reloc = .none, + .debug_info_first_symbol_reloc = .none, + .debug_info_first_node_reloc = .none, + .debug_line_first_symbol_reloc = .none, + .debug_line_first_node_reloc = .none, + }; + if (mod.strip) return fi; + const unit = dwarf.getUnit(mod).get(dwarf); + func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity( + unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{ + .enable_next_moved = true, + }) catch |err| switch (err) { + else => |e| return e, + error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{ + elf.mf.io_err.?, + }), + }, + .{ .func_debug_info = fi }, + )); return fi; } pub fn getFuncIfExists(dwarf: *Dwarf, nav: InternPool.Nav.Index) ?Func.Index { diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 183560e4f64d41cfacfb574facf630a9366770d2..89a8cd47611c9ad895a98b5fceb6492d44f0bfbd 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -185,13 +185,16 @@ uavs: std.array_hash_map.Auto(InternPool.Index, struct { first_symbol_reloc: SymbolReloc.Index, // No `first_got_reloc` field because a UAV never contains GOT relocations. }), -lazy: std.EnumArray(link.File.LazySymbol.Kind, std.array_hash_map.Auto(link.ConstPool.Index, struct { - lsi: Symbol.LocalIndex, - /// The start index of the contiguous sequence of symbol relocations in this lazy code/data. - first_symbol_reloc: SymbolReloc.Index, - /// The start index of the contiguous sequence of GOT relocations in this lazy code/data. - first_got_reloc: GotReloc.Index, -})), +lazy: std.EnumArray(link.File.LazySymbol.Kind, struct { + map: std.array_hash_map.Auto(InternPool.Index, struct { + lsi: Symbol.LocalIndex, + /// The start index of the contiguous sequence of symbol relocations in this lazy code/data. + first_symbol_reloc: SymbolReloc.Index, + /// The start index of the contiguous sequence of GOT relocations in this lazy code/data. + first_got_reloc: GotReloc.Index, + }), + pending_index: u32, +}), pending_uavs: std.ArrayList(Node.UavMapIndex), symbol_relocs: std.ArrayList(SymbolReloc), node_relocs: std.ArrayList(NodeReloc), @@ -391,23 +394,20 @@ const Node = union(enum) { } fn firstSymbolReloc(lmi: @This(), elf: *const Elf) SymbolReloc.Index { - return elf.lazy.getPtrConst(kind).values()[@backingInt(lmi)].first_symbol_reloc; + return elf.lazy.getPtrConst(kind).map.values()[@backingInt(lmi)].first_symbol_reloc; } fn firstGotReloc(lmi: @This(), elf: *const Elf) GotReloc.Index { - return elf.lazy.getPtrConst(kind).values()[@backingInt(lmi)].first_got_reloc; + return elf.lazy.getPtrConst(kind).map.values()[@backingInt(lmi)].first_got_reloc; } }; } pub fn lazySymbol(lmr: LazyMapRef, elf: *const Elf) link.File.LazySymbol { - return .{ - .kind = lmr.kind, - .ty = elf.lazy.getPtrConst(lmr.kind).keys()[lmr.index].val(&elf.dwarf.const_pool), - }; + return .{ .kind = lmr.kind, .ty = elf.lazy.getPtrConst(lmr.kind).map.keys()[lmr.index] }; } pub fn symbol(lmr: LazyMapRef, elf: *const Elf) Symbol.LocalIndex { - return elf.lazy.getPtrConst(lmr.kind).values()[lmr.index].lsi; + return elf.lazy.getPtrConst(lmr.kind).map.values()[lmr.index].lsi; } }; @@ -3340,26 +3340,20 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { const s: Symbol.Id = .local(lsi); return s.toTypeErased(); } -pub fn lazySymbol( - elf: *Elf, - pt: Zcu.PerThread, - lazy: link.File.LazySymbol, -) link.Error!link.File.SymbolId { - const diags = &elf.base.comp.link_diags; - return elf.lazySymbolInner(pt, lazy) catch |err| switch (err) { +pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) link.Error!link.File.SymbolId { + return elf.lazySymbolInner(lazy) catch |err| switch (err) { else => |e| return e, - error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), + error.MappedFileIo => return elf.base.comp.link_diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), }; } -fn lazySymbolInner(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol) Error!link.File.SymbolId { +fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId { const gpa = elf.base.comp.gpa; try elf.ensureUnusedSymbolCapacity(1, .all_local); try elf.nodes.ensureUnusedCapacity(gpa, 1); - try elf.lazy.getPtr(lazy.kind).ensureUnusedCapacity(gpa, 1); + try elf.lazy.getPtr(lazy.kind).map.ensureUnusedCapacity(gpa, 1); - const cpi = try elf.dwarf.const_pool.get(pt, .{ .elf2 = elf }, lazy.ty); - const gop = elf.lazy.getPtr(lazy.kind).getOrPutAssumeCapacity(cpi); + const gop = elf.lazy.getPtr(lazy.kind).map.getOrPutAssumeCapacity(lazy.ty); if (!gop.found_existing) { const shndx: Section.Index, const sym_type: std.elf.STT = switch (lazy.kind) { .code => .{ .text, .FUNC }, @@ -3819,7 +3813,10 @@ fn create( .one_shot_fixups = .empty, .navs = .empty, .uavs = .empty, - .lazy = comptime .initFill(.empty), + .lazy = comptime .initFill(.{ + .map = .empty, + .pending_index = 0, + }), .pending_uavs = .empty, .symbol_relocs = .empty, .node_relocs = .empty, @@ -3881,7 +3878,7 @@ pub fn deinit(elf: *Elf) void { elf.one_shot_fixups.deinit(gpa); elf.navs.deinit(gpa); elf.uavs.deinit(gpa); - for (&elf.lazy.values) |*lazy| lazy.deinit(gpa); + for (&elf.lazy.values) |*lazy| lazy.map.deinit(gpa); elf.pending_uavs.deinit(gpa); elf.symbol_relocs.deinit(gpa); elf.node_relocs.deinit(gpa); @@ -5361,8 +5358,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { .first_symbol_reloc = &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc, }, inline .lazy_code, .lazy_const_data => |lmi| .{ - .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_symbol_reloc, - .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_got_reloc, + .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_symbol_reloc, + .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_got_reloc, }, .unit_debug_info_header => |ui| .{ .first_node_reloc = &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_node_reloc, @@ -7137,24 +7134,38 @@ fn prelinkInner(elf: *Elf) Error!void { }; elf.input_pending_index += 1; - try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5); + try elf.nodes.ensureUnusedCapacity(gpa, 5 + 4); - elf.dwarf.debug_abbrev.ni = .wrap(elf.addNodeAssumeCapacity( - try elf.shndx.debug_abbrev.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), - .{ .debug_shared = .debug_abbrev }, - )); - elf.dwarf.debug_line_str.ni = .wrap(elf.addNodeAssumeCapacity( - try elf.shndx.debug_line_str.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), - .{ .debug_shared = .debug_line_str }, - )); - elf.dwarf.debug_str.ni = .wrap(elf.addNodeAssumeCapacity( - try elf.shndx.debug_str.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), - .{ .debug_shared = .debug_str }, - )); - elf.dwarf.debug_str_offsets.ni = .wrap(elf.addNodeAssumeCapacity( - try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), - .{ .debug_shared = .debug_str_offsets }, - )); + switch (elf.shndx.debug_abbrev) { + .UNDEF => {}, + else => |debug_abbrev_shndx| elf.dwarf.debug_abbrev.ni = .wrap(elf.addNodeAssumeCapacity( + try debug_abbrev_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), + .{ .debug_shared = .debug_abbrev }, + )), + } + switch (elf.shndx.debug_line_str) { + .UNDEF => {}, + else => |debug_line_str_shndx| elf.dwarf.debug_line_str.ni = + .wrap(elf.addNodeAssumeCapacity( + try debug_line_str_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), + .{ .debug_shared = .debug_line_str }, + )), + } + switch (elf.shndx.debug_str) { + .UNDEF => {}, + else => |debug_str_shndx| elf.dwarf.debug_str.ni = .wrap(elf.addNodeAssumeCapacity( + try debug_str_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), + .{ .debug_shared = .debug_str }, + )), + } + switch (elf.shndx.debug_str_offsets) { + .UNDEF => {}, + else => |debug_str_offsets_shndx| elf.dwarf.debug_str_offsets.ni = + .wrap(elf.addNodeAssumeCapacity( + try debug_str_offsets_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{}), + .{ .debug_shared = .debug_str_offsets }, + )), + } for ([5]Section.Index{ elf.shndx.eh_frame, @@ -8541,8 +8552,11 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) const nav = ip.getNav(nav_index); if (ip.indexToKey(nav.resolved.?.value) == .@"extern") return; - if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) - return elf.dwarf.updateComptimeNav(pt, nav_index); + if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) { + if (elf.ehdrMachine() != .X86_64) return; + const mod = zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?; + return if (!mod.strip) elf.dwarf.updateComptimeNav(pt, nav_index); + } const nmi = try elf.navMapIndex(zcu, nav_index); const ni = nmi.symbol(elf).index().ptr(elf).node.unwrap().?; @@ -8581,7 +8595,32 @@ pub fn updateContainerType( ty: InternPool.Index, success: bool, ) link.Error!void { - try elf.dwarf.const_pool.updateContainerType(pt, .{ .elf2 = elf }, ty, success); + elf.updateContainerTypeInner(pt, ty, success) catch |err| switch (err) { + else => |e| return e, + error.MappedFileIo => return elf.base.comp.link_diags.fail( + "failed to write output file: {t}", + .{elf.mf.io_err.?}, + ), + }; +} +pub fn updateContainerTypeInner( + elf: *Elf, + pt: Zcu.PerThread, + ty: InternPool.Index, + success: bool, +) Error!void { + switch (elf.base.comp.config.debug_format) { + .strip => {}, + .dwarf => try elf.dwarf.const_pool.updateContainerType(pt, .{ .elf2 = elf }, ty, success), + .code_view => unreachable, + } + if (!success) return; + var lazy_it = elf.lazy.iterator(); + while (lazy_it.next()) |lazy| if (lazy.value.map.getIndex(ty)) |lmi| { + if (lazy.value.pending_index <= lmi) continue; + // This type has changed on this incremental update, so update the lazy code/data. + try elf.genLazy(pt, .{ .kind = lazy.key, .index = @intCast(lmi) }); + }; } pub fn addConst( @@ -8590,47 +8629,24 @@ pub fn addConst( index: link.ConstPool.Index, val: InternPool.Index, ) link.Error!void { - try elf.dwarf.addConst(index, val); + switch (elf.base.comp.config.debug_format) { + .strip => {}, + .dwarf => try elf.dwarf.addConst(index, val), + .code_view => unreachable, + } } pub fn updateConst( elf: *Elf, - pt: Zcu.PerThread, + _: Zcu.PerThread, cpi: link.ConstPool.Index, val: InternPool.Index, ) link.Error!void { - if (val == .anyerror_type) return; - try elf.updateConstInner(pt, cpi, val); -} -fn updateConstInner( - elf: *Elf, - pt: Zcu.PerThread, - cpi: link.ConstPool.Index, - val: InternPool.Index, -) link.Error!void { - var lazy_it = elf.lazy.iterator(); - while (lazy_it.next()) |lazy| if (lazy.value.getIndex(cpi)) |li| { - const lazy_ty: Type = .fromInterned(val); - var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined; - const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(pt.zcu)) { - .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf, - .error_set => switch (lazy.key) { - .code => std.mem.print(&prog_name_buf, "@errorCast({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf, - .const_data => "@errorName(anyerror)", - }, - else => unreachable, - }; - const prog_node = elf.base.comp.link_prog_node.start(prog_name, 0); - defer prog_node.end(); - elf.genLazy(pt, .{ .kind = lazy.key, .index = @intCast(li) }) catch |err| switch (err) { - else => |e| return e, - error.MappedFileIo => return elf.base.comp.link_diags.fail( - "failed to write output file: {t}", - .{elf.mf.io_err.?}, - ), - }; - }; - elf.dwarf.updateConst(cpi, val); + switch (elf.base.comp.config.debug_format) { + .strip => {}, + .dwarf => elf.dwarf.updateConst(cpi, val), + .code_view => unreachable, + } } pub fn updateConstIncomplete( @@ -8639,11 +8655,17 @@ pub fn updateConstIncomplete( cpi: link.ConstPool.Index, val: InternPool.Index, ) link.Error!void { - const debug_info_ni = Dwarf.Const.get(cpi, &elf.dwarf).debug_info_ni.unwrap().?; - var di_nw: MappedFile.Node.Writer = undefined; - debug_info_ni.writer(elf.base.comp.gpa, &elf.mf, &di_nw); - defer di_nw.deinit(); - try elf.dwarf.updateConstIncomplete(pt, &di_nw, val); + switch (elf.base.comp.config.debug_format) { + .strip => {}, + .dwarf => { + const debug_info_ni = Dwarf.Const.get(cpi, &elf.dwarf).debug_info_ni.unwrap().?; + var di_nw: MappedFile.Node.Writer = undefined; + debug_info_ni.writer(elf.base.comp.gpa, &elf.mf, &di_nw); + defer di_nw.deinit(); + try elf.dwarf.updateConstIncomplete(pt, &di_nw, val); + }, + .code_view => unreachable, + } } pub fn updateFunc( @@ -8930,11 +8952,16 @@ pub fn lostTracking( } pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void { - try elf.updateConstInner( - pt, - elf.dwarf.const_pool.getIfExists(.anyerror_type) orelse return, - .anyerror_type, - ); + elf.genLazyInner(pt, .{ + .kind = .const_data, + .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), + }) catch |err| switch (err) { + else => |e| return e, + error.MappedFileIo => return elf.base.comp.link_diags.fail( + "failed to write output file: {t}", + .{elf.mf.io_err.?}, + ), + }; } pub fn flush( @@ -9266,7 +9293,16 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void { defer prog_node.end(); try elf.genUav(pt, umi); } - try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf }); + var lazy_it = elf.lazy.iterator(); + while (lazy_it.next()) |lazy| while (lazy.value.pending_index < lazy.value.map.count()) { + try elf.genLazy(pt, .{ .kind = lazy.key, .index = lazy.value.pending_index }); + lazy.value.pending_index += 1; + }; + switch (elf.base.comp.config.debug_format) { + .strip => {}, + .dwarf => try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf }), + .code_view => unreachable, + } } fn genUav( @@ -9302,6 +9338,23 @@ fn genUav( } fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void { + const lazy = lmr.lazySymbol(elf); + if (lazy.ty == .anyerror_type) return; + const lazy_ty: Type = .fromInterned(lazy.ty); + var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined; + const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(pt.zcu)) { + .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf, + .error_set => switch (lmr.kind) { + .code => std.mem.print(&prog_name_buf, "@errorCast({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf, + .const_data => "@errorName(anyerror)", + }, + else => unreachable, + }; + const prog_node = elf.base.comp.link_prog_node.start(prog_name, 0); + defer prog_node.end(); + try elf.genLazyInner(pt, lmr); +} +fn genLazyInner(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void { const zcu = pt.zcu; const gpa = zcu.gpa; -- 2.54.0