authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-01 12:58:19-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 12:59:38-04:00
logdd01fe96d36a7cf898f04a55b820174d76588a32
tree7d6e9b5bb22df174c00b883a4d5570c13cd8f53c
parent3939c4f5b56a6f3440d98e1c5f6dbf4a1e6ccdce

Dwarf2: track function resolution for deterministic ies debug info

Avoid calling `funcIesResolvedUnordered` before the frontend is guaranteed to have set it.

2 files changed, 24 insertions(+), 5 deletions(-)

src/link/Dwarf2.zig+18-5
......@@ -120,10 +120,13 @@ pub const Global = struct {
120120};
121121
122122pub const Func = struct {
123 state: State,
123124 fde_ni: MappedFile.Node.Index.Optional,
124125 debug_info_ni: MappedFile.Node.Index.Optional,
125126 debug_line_ni: MappedFile.Node.Index.Optional,
126127
128 pub const State = enum { unresolved, resolved };
129
127130 pub const Index = enum(u32) {
128131 _,
129132
......@@ -1419,6 +1422,7 @@ pub fn getFunc(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Func.Index {
14191422 const gpa = comp.gpa;
14201423 const func_gop = try dwarf.funcs.getOrPut(gpa, nav);
14211424 if (!func_gop.found_existing) func_gop.value_ptr.* = .{
1425 .state = .unresolved,
14221426 .fde_ni = .none,
14231427 .debug_info_ni = .none,
14241428 .debug_line_ni = .none,
......@@ -1975,7 +1979,10 @@ pub fn updateComptimeNav(
19751979 .func => |func| if (func.owner_nav == nav_index and func.generic_owner == .none) {
19761980 const fi = try dwarf.getFunc(func.owner_nav);
19771981 const f = fi.get(dwarf);
1978 if (f.fde_ni != .none or f.debug_line_ni != .none) return;
1982 switch (f.state) {
1983 .unresolved => {},
1984 .resolved => return,
1985 }
19791986 const elf = dwarf.lf.cast(.elf2).?;
19801987 const debug_info_ni = f.debug_info_ni.unwrap().?;
19811988 var di_nw: MappedFile.Node.Writer = undefined;
......@@ -2837,7 +2844,14 @@ fn updateConstInner(
28372844 defer zcu.gpa.free(name);
28382845 try diw.writeUleb128(try dwarf.refAbbrevCode(.inferred_error_set_type));
28392846 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2840 try dwarf.refType(pt, di_nw, switch (ip.funcIesResolvedUnordered(func)) {
2847 try dwarf.refType(pt, di_nw, switch (ies: {
2848 const fi = dwarf.getFuncIfExists(ip.indexToKey(func).func.owner_nav) orelse
2849 break :ies .none;
2850 break :ies switch (fi.get(dwarf).state) {
2851 .unresolved => .none,
2852 .resolved => ip.funcIesResolvedUnordered(func),
2853 };
2854 }) {
28412855 .none => .anyerror,
28422856 else => |ies| .fromInterned(ies),
28432857 });
......@@ -3563,10 +3577,9 @@ fn exprLoc(dwarf: *Dwarf, nw: *MappedFile.Node.Writer, loc: Loc) link.EmitError!
35633577
35643578fn strp(dwarf: *Dwarf, s: *Str, nw: *MappedFile.Node.Writer, str: []const u8) link.EmitError!void {
35653579 const comp = dwarf.lf.comp;
3566 const mf = &dwarf.lf.cast(.elf2).?.mf;
3567 try dwarf.secOffset(nw, s.ni.unwrap().?, s.get(comp.gpa, mf, str) catch |err| switch (err) {
3580 try dwarf.secOffset(nw, s.ni.unwrap().?, s.get(comp.gpa, nw.mf, str) catch |err| switch (err) {
35683581 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
3569 mf.io_err.?,
3582 nw.mf.io_err.?,
35703583 }),
35713584 else => |e| return e,
35723585 });
src/link/Elf2.zig+6
......@@ -8926,6 +8926,7 @@ fn updateFuncInner(
89268926 debug.pt = pt;
89278927 debug.any_children = false;
89288928 debug.blocks = .empty;
8929 dwarf_func.state = .resolved;
89298930
89308931 const debug_info_ni = dwarf_func.debug_info_ni.unwrap().?;
89318932 try dwarf.decls.put(zcu.comp.gpa, src_inst, .{
......@@ -9020,6 +9021,11 @@ fn updateFuncInner(
90209021 );
90219022 }
90229023 debug.wip_nav.finishDebugFrameFde(func_length);
9024 if (func.analysisUnordered(ip).inferred_error_set) {
9025 const ies = ip.getIfExists(.{ .inferred_error_set_type = func_index }).?;
9026 if (elf.dwarf.const_pool.getIfExists(ies)) |cpi|
9027 try elf.updateConstInner(pt, cpi, ies);
9028 }
90239029 },
90249030 .none => {},
90259031 }