authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-12 18:12:19-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 12:59:38-04:00
logfd9f45c358837b0091b795fad1c75f4efc8f4fc4
tree3b1851b1e8bb944839467fff775848224c61d6b3
parent8530e997ea6673ebdeb2c90d6d2eb2d777a99fcb

Elf2: rework lost handling


13 files changed, 451 insertions(+), 318 deletions(-)

lib/std/dwarf/TAG.zig+1
...@@ -120,3 +120,4 @@ pub const PGI_interface_block = 0xA020;...@@ -120,3 +120,4 @@ pub const PGI_interface_block = 0xA020;
120// ZIG extensions.120// ZIG extensions.
121pub const ZIG_padding = 0xfdb1;121pub const ZIG_padding = 0xfdb1;
122pub const ZIG_comptime_value = 0xfdb2;122pub const ZIG_comptime_value = 0xfdb2;
123pub const ZIG_lost_declaration = 0xfdb3;
src/Zcu/PerThread.zig+4-1
...@@ -877,7 +877,10 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void {...@@ -877,7 +877,10 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void {
877 const new_line = new_zir.getDeclaration(new_inst).src_line;877 const new_line = new_zir.getDeclaration(new_inst).src_line;
878 if (old_line != new_line) {878 if (old_line != new_line) {
879 comp.link_prog_node.increaseEstimatedTotalItems(1);879 comp.link_prog_node.increaseEstimatedTotalItems(1);
880 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .debug_update_line_number = tracked_inst_index });880 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .debug_update_line_number = .{
881 .inst = tracked_inst_index,
882 .line = new_line,
883 } });
881 }884 }
882 },885 },
883 else => {},886 else => {},
src/link.zig+9-5
...@@ -870,10 +870,11 @@ pub const File = struct {...@@ -870,10 +870,11 @@ pub const File = struct {
870 /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because870 /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because
871 /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`.871 /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`.
872 /// Never called when LLVM is codegenning the ZCU.872 /// Never called when LLVM is codegenning the ZCU.
873 fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) Error!void {873 fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index, line: u32) Error!void {
874 assert(pt.zcu.llvm_object == null);874 assert(pt.zcu.llvm_object == null);
875 {875 {
876 const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?;876 const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?;
877 assert(ti.inst != .main_struct_inst);
877 const file = pt.zcu.fileByIndex(ti.file);878 const file = pt.zcu.fileByIndex(ti.file);
878 const inst = file.zir.?.instructions.get(@backingInt(ti.inst));879 const inst = file.zir.?.instructions.get(@backingInt(ti.inst));
879 assert(inst.tag == .declaration);880 assert(inst.tag == .declaration);
...@@ -885,7 +886,7 @@ pub const File = struct {...@@ -885,7 +886,7 @@ pub const File = struct {
885 .coff2 => {},886 .coff2 => {},
886 inline else => |tag| {887 inline else => |tag| {
887 dev.check(tag.devFeature());888 dev.check(tag.devFeature());
888 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id);889 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id, line);
889 },890 },
890 }891 }
891 }892 }
...@@ -1452,7 +1453,10 @@ pub const ZcuTask = union(enum) {...@@ -1452,7 +1453,10 @@ pub const ZcuTask = union(enum) {
1452 ty: InternPool.Index,1453 ty: InternPool.Index,
1453 success: bool,1454 success: bool,
1454 },1455 },
1455 debug_update_line_number: InternPool.TrackedInst.Index,1456 debug_update_line_number: struct {
1457 inst: InternPool.TrackedInst.Index,
1458 line: u32,
1459 },
1456 lost_tracking: InternPool.TrackedInst.Index,1460 lost_tracking: InternPool.TrackedInst.Index,
1457};1461};
14581462
...@@ -1713,12 +1717,12 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void...@@ -1713,12 +1717,12 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
1713 };1717 };
1714 break :nav null;1718 break :nav null;
1715 },1719 },
1716 .debug_update_line_number => |ti| nav: {1720 .debug_update_line_number => |line_update| nav: {
1717 const nav_prog_node = comp.link_prog_node.start("Update line number", 0);1721 const nav_prog_node = comp.link_prog_node.start("Update line number", 0);
1718 defer nav_prog_node.end();1722 defer nav_prog_node.end();
1719 if (pt.zcu.llvm_object == null) {1723 if (pt.zcu.llvm_object == null) {
1720 if (comp.bin_file) |lf| {1724 if (comp.bin_file) |lf| {
1721 lf.updateLineNumber(pt, ti) catch |err| switch (err) {1725 lf.updateLineNumber(pt, line_update.inst, line_update.line) catch |err| switch (err) {
1722 error.OutOfMemory => diags.setAllocFailure(),1726 error.OutOfMemory => diags.setAllocFailure(),
1723 else => |e| log.err("update line number failed: {s}", .{@errorName(e)}),1727 else => |e| log.err("update line number failed: {s}", .{@errorName(e)}),
1724 };1728 };
src/link/C.zig+2-1
...@@ -721,12 +721,13 @@ fn updateUav(...@@ -721,12 +721,13 @@ fn updateUav(
721 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);721 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);
722}722}
723723
724pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) error{}!void {724pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index, line: u32) error{}!void {
725 // The C backend does not currently emit "#line" directives. Even if it did, it would not be725 // The C backend does not currently emit "#line" directives. Even if it did, it would not be
726 // capable of updating those line numbers without re-generating the entire declaration.726 // capable of updating those line numbers without re-generating the entire declaration.
727 _ = c;727 _ = c;
728 _ = pt;728 _ = pt;
729 _ = ti_id;729 _ = ti_id;
730 _ = line;
730}731}
731732
732pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.Error!void {733pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.Error!void {
src/link/Dwarf.zig+51-59
...@@ -2202,7 +2202,7 @@ pub const WipNav = struct {...@@ -2202,7 +2202,7 @@ pub const WipNav = struct {
2202 wip_nav: *WipNav,2202 wip_nav: *WipNav,
2203 abbrev_code: struct {2203 abbrev_code: struct {
2204 decl: AbbrevCode,2204 decl: AbbrevCode,
2205 generic_decl: AbbrevCode,2205 decl_abstract: AbbrevCode,
2206 decl_instance: AbbrevCode,2206 decl_instance: AbbrevCode,
2207 },2207 },
2208 nav: *const InternPool.Nav,2208 nav: *const InternPool.Nav,
...@@ -2216,11 +2216,11 @@ pub const WipNav = struct {...@@ -2216,11 +2216,11 @@ pub const WipNav = struct {
22162216
2217 const orig_entry = wip_nav.entry;2217 const orig_entry = wip_nav.entry;
2218 defer wip_nav.entry = orig_entry;2218 defer wip_nav.entry = orig_entry;
2219 const parent_type, const is_generic_decl = if (nav.analysis) |analysis| parent_info: {2219 const parent_type, const is_abstract = if (nav.analysis) |analysis| parent_info: {
2220 const parent_type: Type = .fromInterned(zcu.namespacePtr(analysis.namespace).owner_type);2220 const parent_type: Type = .fromInterned(zcu.namespacePtr(analysis.namespace).owner_type);
2221 const decl_gop = try dwarf.decls.getOrPut(dwarf.gpa, analysis.zir_index);2221 const decl_gop = try dwarf.decls.getOrPut(dwarf.gpa, analysis.zir_index);
2222 errdefer _ = if (!decl_gop.found_existing) dwarf.decls.pop();2222 errdefer _ = if (!decl_gop.found_existing) dwarf.decls.pop();
2223 const was_generic_decl = decl_gop.found_existing and2223 const was_abstract = decl_gop.found_existing and
2224 switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, decl_gop.value_ptr.*)) {2224 switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, decl_gop.value_ptr.*)) {
2225 .null,2225 .null,
2226 .decl_alias,2226 .decl_alias,
...@@ -2242,9 +2242,9 @@ pub const WipNav = struct {...@@ -2242,9 +2242,9 @@ pub const WipNav = struct {
2242 .decl_extern_nullary_func,2242 .decl_extern_nullary_func,
2243 .decl_extern_func,2243 .decl_extern_func,
2244 => false,2244 => false,
2245 .generic_decl_var,2245 .decl_abstract_var,
2246 .generic_decl_const,2246 .decl_abstract_const,
2247 .generic_decl_func,2247 .decl_abstract_func,
2248 => true,2248 => true,
22492249
2250 // This comes from a decl which was previously generated as an incomplete value2250 // This comes from a decl which was previously generated as an incomplete value
...@@ -2255,11 +2255,11 @@ pub const WipNav = struct {...@@ -2255,11 +2255,11 @@ pub const WipNav = struct {
2255 else => |t| std.debug.panic("bad decl abbrev code: {t}", .{t}),2255 else => |t| std.debug.panic("bad decl abbrev code: {t}", .{t}),
2256 };2256 };
2257 if (parent_type.getCaptures(zcu).len == 0) {2257 if (parent_type.getCaptures(zcu).len == 0) {
2258 if (was_generic_decl) try dwarf.freeCommonEntry(wip_nav.unit, decl_gop.value_ptr.*);2258 if (was_abstract) try dwarf.freeCommonEntry(wip_nav.unit, decl_gop.value_ptr.*);
2259 decl_gop.value_ptr.* = orig_entry;2259 decl_gop.value_ptr.* = orig_entry;
2260 break :parent_info .{ parent_type, false };2260 break :parent_info .{ parent_type, false };
2261 } else {2261 } else {
2262 if (was_generic_decl)2262 if (was_abstract)
2263 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(decl_gop.value_ptr.*).clear()2263 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(decl_gop.value_ptr.*).clear()
2264 else2264 else
2265 decl_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2265 decl_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
...@@ -2268,8 +2268,8 @@ pub const WipNav = struct {...@@ -2268,8 +2268,8 @@ pub const WipNav = struct {
2268 }2268 }
2269 } else .{ null, false };2269 } else .{ null, false };
22702270
2271 try wip_nav.abbrevCode(if (is_generic_decl) abbrev_code.generic_decl else abbrev_code.decl);2271 try wip_nav.abbrevCode(if (is_abstract) abbrev_code.decl_abstract else abbrev_code.decl);
2272 try wip_nav.refType((if (is_generic_decl) null else parent_type) orelse2272 try wip_nav.refType((if (is_abstract) null else parent_type) orelse
2273 .fromInterned(zcu.fileRootType(file)));2273 .fromInterned(zcu.fileRootType(file)));
2274 assert(diw.end == DebugInfo.declEntryLineOff(dwarf));2274 assert(diw.end == DebugInfo.declEntryLineOff(dwarf));
2275 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);2275 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
...@@ -2277,14 +2277,14 @@ pub const WipNav = struct {...@@ -2277,14 +2277,14 @@ pub const WipNav = struct {
2277 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);2277 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2278 try wip_nav.strp(nav.name.toSlice(ip));2278 try wip_nav.strp(nav.name.toSlice(ip));
22792279
2280 if (!is_generic_decl) return;2280 if (!is_abstract) return;
2281 const generic_decl_entry = wip_nav.entry;2281 const abstract_entry = wip_nav.entry;
2282 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, generic_decl_entry, dwarf, wip_nav.debug_info.written());2282 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, abstract_entry, dwarf, wip_nav.debug_info.written());
2283 wip_nav.debug_info.clearRetainingCapacity();2283 wip_nav.debug_info.clearRetainingCapacity();
2284 wip_nav.entry = orig_entry;2284 wip_nav.entry = orig_entry;
2285 try wip_nav.abbrevCode(abbrev_code.decl_instance);2285 try wip_nav.abbrevCode(abbrev_code.decl_instance);
2286 try wip_nav.refType(parent_type.?);2286 try wip_nav.refType(parent_type.?);
2287 try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, generic_decl_entry, 0);2287 try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, abstract_entry, 0);
2288 }2288 }
2289};2289};
22902290
...@@ -2680,11 +2680,11 @@ fn initWipNavInner(...@@ -2680,11 +2680,11 @@ fn initWipNavInner(
2680 const diw = &wip_nav.debug_info.writer;2680 const diw = &wip_nav.debug_info.writer;
2681 try wip_nav.declCommon(if (func_type.param_types.len > 0 or func_type.is_var_args) .{2681 try wip_nav.declCommon(if (func_type.param_types.len > 0 or func_type.is_var_args) .{
2682 .decl = .decl_extern_func,2682 .decl = .decl_extern_func,
2683 .generic_decl = .generic_decl_func,2683 .decl_abstract = .decl_abstract_func,
2684 .decl_instance = .decl_instance_extern_func,2684 .decl_instance = .decl_instance_extern_func,
2685 } else .{2685 } else .{
2686 .decl = .decl_extern_nullary_func,2686 .decl = .decl_extern_nullary_func,
2687 .generic_decl = .generic_decl_func,2687 .decl_abstract = .decl_abstract_func,
2688 .decl_instance = .decl_instance_extern_nullary_func,2688 .decl_instance = .decl_instance_extern_nullary_func,
2689 }, &nav, inst_info.file, &decl);2689 }, &nav, inst_info.file, &decl);
2690 try wip_nav.strp(@"extern".name.toSlice(ip));2690 try wip_nav.strp(@"extern".name.toSlice(ip));
...@@ -2705,7 +2705,7 @@ fn initWipNavInner(...@@ -2705,7 +2705,7 @@ fn initWipNavInner(
2705 .func => |func| if (func.owner_nav != nav_index) {2705 .func => |func| if (func.owner_nav != nav_index) {
2706 try wip_nav.declCommon(.{2706 try wip_nav.declCommon(.{
2707 .decl = .decl_alias,2707 .decl = .decl_alias,
2708 .generic_decl = .generic_decl_const,2708 .decl_abstract = .decl_abstract_const,
2709 .decl_instance = .decl_instance_alias,2709 .decl_instance = .decl_instance_alias,
2710 }, &nav, inst_info.file, &decl);2710 }, &nav, inst_info.file, &decl);
2711 try wip_nav.refNav(func.owner_nav);2711 try wip_nav.refNav(func.owner_nav);
...@@ -2758,7 +2758,7 @@ fn initWipNavInner(...@@ -2758,7 +2758,7 @@ fn initWipNavInner(
2758 const diw = &wip_nav.debug_info.writer;2758 const diw = &wip_nav.debug_info.writer;
2759 try wip_nav.declCommon(.{2759 try wip_nav.declCommon(.{
2760 .decl = .decl_func,2760 .decl = .decl_func,
2761 .generic_decl = .generic_decl_func,2761 .decl_abstract = .decl_abstract_func,
2762 .decl_instance = .decl_instance_func,2762 .decl_instance = .decl_instance_func,
2763 }, &nav, inst_info.file, &decl);2763 }, &nav, inst_info.file, &decl);
2764 try wip_nav.strp(switch (decl.linkage) {2764 try wip_nav.strp(switch (decl.linkage) {
...@@ -2817,10 +2817,10 @@ fn initWipNavInner(...@@ -2817,10 +2817,10 @@ fn initWipNavInner(
2817 const diw = &wip_nav.debug_info.writer;2817 const diw = &wip_nav.debug_info.writer;
2818 try wip_nav.declCommon(.{2818 try wip_nav.declCommon(.{
2819 .decl = .decl_var,2819 .decl = .decl_var,
2820 .generic_decl = switch (decl.kind) {2820 .decl_abstract = switch (decl.kind) {
2821 .unnamed_test, .@"test", .decltest, .@"comptime" => unreachable,2821 .unnamed_test, .@"test", .decltest, .@"comptime" => unreachable,
2822 .@"const" => .generic_decl_const,2822 .@"const" => .decl_abstract_const,
2823 .@"var" => .generic_decl_var,2823 .@"var" => .decl_abstract_var,
2824 },2824 },
2825 .decl_instance = .decl_instance_var,2825 .decl_instance = .decl_instance_var,
2826 }, &nav, inst_info.file, &decl);2826 }, &nav, inst_info.file, &decl);
...@@ -3181,7 +3181,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3181,7 +3181,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3181 .alias => {3181 .alias => {
3182 try wip_nav.declCommon(.{3182 try wip_nav.declCommon(.{
3183 .decl = .decl_alias,3183 .decl = .decl_alias,
3184 .generic_decl = .generic_decl_const,3184 .decl_abstract = .decl_abstract_const,
3185 .decl_instance = .decl_instance_alias,3185 .decl_instance = .decl_instance_alias,
3186 }, &nav, inst_info.file, &decl);3186 }, &nav, inst_info.file, &decl);
3187 try wip_nav.refType(nav_val.toType());3187 try wip_nav.refType(nav_val.toType());
...@@ -3189,7 +3189,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3189,7 +3189,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3189 .@"var" => {3189 .@"var" => {
3190 try wip_nav.declCommon(.{3190 try wip_nav.declCommon(.{
3191 .decl = .decl_var,3191 .decl = .decl_var,
3192 .generic_decl = .generic_decl_var,3192 .decl_abstract = .decl_abstract_var,
3193 .decl_instance = .decl_instance_var,3193 .decl_instance = .decl_instance_var,
3194 }, &nav, inst_info.file, &decl);3194 }, &nav, inst_info.file, &decl);
3195 try wip_nav.strp(switch (decl.linkage) {3195 try wip_nav.strp(switch (decl.linkage) {
...@@ -3209,19 +3209,19 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3209,19 +3209,19 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3209 const has_comptime_state = nav_ty.comptimeOnly(zcu);3209 const has_comptime_state = nav_ty.comptimeOnly(zcu);
3210 try wip_nav.declCommon(if (has_runtime_bits and has_comptime_state) .{3210 try wip_nav.declCommon(if (has_runtime_bits and has_comptime_state) .{
3211 .decl = .decl_const_runtime_bits_comptime_state,3211 .decl = .decl_const_runtime_bits_comptime_state,
3212 .generic_decl = .generic_decl_const,3212 .decl_abstract = .decl_abstract_const,
3213 .decl_instance = .decl_instance_const_runtime_bits_comptime_state,3213 .decl_instance = .decl_instance_const_runtime_bits_comptime_state,
3214 } else if (has_comptime_state) .{3214 } else if (has_comptime_state) .{
3215 .decl = .decl_const_comptime_state,3215 .decl = .decl_const_comptime_state,
3216 .generic_decl = .generic_decl_const,3216 .decl_abstract = .decl_abstract_const,
3217 .decl_instance = .decl_instance_const_comptime_state,3217 .decl_instance = .decl_instance_const_comptime_state,
3218 } else if (has_runtime_bits) .{3218 } else if (has_runtime_bits) .{
3219 .decl = .decl_const_runtime_bits,3219 .decl = .decl_const_runtime_bits,
3220 .generic_decl = .generic_decl_const,3220 .decl_abstract = .decl_abstract_const,
3221 .decl_instance = .decl_instance_const_runtime_bits,3221 .decl_instance = .decl_instance_const_runtime_bits,
3222 } else .{3222 } else .{
3223 .decl = .decl_const,3223 .decl = .decl_const,
3224 .generic_decl = .generic_decl_const,3224 .decl_abstract = .decl_abstract_const,
3225 .decl_instance = .decl_instance_const,3225 .decl_instance = .decl_instance_const,
3226 }, &nav, inst_info.file, &decl);3226 }, &nav, inst_info.file, &decl);
3227 try wip_nav.strp(switch (decl.linkage) {3227 try wip_nav.strp(switch (decl.linkage) {
...@@ -3245,11 +3245,11 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3245,11 +3245,11 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3245 } else true;3245 } else true;
3246 try wip_nav.declCommon(if (is_nullary) .{3246 try wip_nav.declCommon(if (is_nullary) .{
3247 .decl = .decl_nullary_func_generic,3247 .decl = .decl_nullary_func_generic,
3248 .generic_decl = .generic_decl_func,3248 .decl_abstract = .decl_abstract_func,
3249 .decl_instance = .decl_instance_nullary_func_generic,3249 .decl_instance = .decl_instance_nullary_func_generic,
3250 } else .{3250 } else .{
3251 .decl = .decl_func_generic,3251 .decl = .decl_func_generic,
3252 .generic_decl = .generic_decl_func,3252 .decl_abstract = .decl_abstract_func,
3253 .decl_instance = .decl_instance_func_generic,3253 .decl_instance = .decl_instance_func_generic,
3254 }, &nav, inst_info.file, &decl);3254 }, &nav, inst_info.file, &decl);
3255 try wip_nav.refType(.fromInterned(func_type.return_type));3255 try wip_nav.refType(.fromInterned(func_type.return_type));
...@@ -3267,7 +3267,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -3267,7 +3267,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
3267 .func_alias => |owner_nav| {3267 .func_alias => |owner_nav| {
3268 try wip_nav.declCommon(.{3268 try wip_nav.declCommon(.{
3269 .decl = .decl_alias,3269 .decl = .decl_alias,
3270 .generic_decl = .generic_decl_const,3270 .decl_abstract = .decl_abstract_const,
3271 .decl_instance = .decl_instance_alias,3271 .decl_instance = .decl_instance_alias,
3272 }, &nav, inst_info.file, &decl);3272 }, &nav, inst_info.file, &decl);
3273 try wip_nav.refNav(owner_nav);3273 try wip_nav.refNav(owner_nav);
...@@ -3463,7 +3463,7 @@ fn emitIncompleteContainerType(...@@ -3463,7 +3463,7 @@ fn emitIncompleteContainerType(
3463 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);3463 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3464 try wip_nav.declCommon(.{3464 try wip_nav.declCommon(.{
3465 .decl = .decl_namespace_struct,3465 .decl = .decl_namespace_struct,
3466 .generic_decl = .generic_decl_const,3466 .decl_abstract = .decl_abstract_const,
3467 .decl_instance = .decl_instance_namespace_struct,3467 .decl_instance = .decl_instance_namespace_struct,
3468 }, &nav, file, &decl);3468 }, &nav, file, &decl);
3469 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));3469 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));
...@@ -3881,11 +3881,11 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -3881,11 +3881,11 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
3881 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);3881 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3882 try wip_nav.declCommon(if (loaded_struct.field_types.len == 0) .{3882 try wip_nav.declCommon(if (loaded_struct.field_types.len == 0) .{
3883 .decl = .decl_namespace_struct,3883 .decl = .decl_namespace_struct,
3884 .generic_decl = .generic_decl_const,3884 .decl_abstract = .decl_abstract_const,
3885 .decl_instance = .decl_instance_namespace_struct,3885 .decl_instance = .decl_instance_namespace_struct,
3886 } else .{3886 } else .{
3887 .decl = .decl_struct,3887 .decl = .decl_struct,
3888 .generic_decl = .generic_decl_const,3888 .decl_abstract = .decl_abstract_const,
3889 .decl_instance = .decl_instance_struct,3889 .decl_instance = .decl_instance_struct,
3890 }, &nav, file, &decl);3890 }, &nav, file, &decl);
3891 } else {3891 } else {
...@@ -3960,7 +3960,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -3960,7 +3960,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
3960 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);3960 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3961 try wip_nav.declCommon(.{3961 try wip_nav.declCommon(.{
3962 .decl = .decl_packed_struct,3962 .decl = .decl_packed_struct,
3963 .generic_decl = .generic_decl_const,3963 .decl_abstract = .decl_abstract_const,
3964 .decl_instance = .decl_instance_packed_struct,3964 .decl_instance = .decl_instance_packed_struct,
3965 }, &nav, file, &decl);3965 }, &nav, file, &decl);
3966 break :t true;3966 break :t true;
...@@ -3997,7 +3997,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -3997,7 +3997,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
3997 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);3997 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3998 try wip_nav.declCommon(.{3998 try wip_nav.declCommon(.{
3999 .decl = .decl_union,3999 .decl = .decl_union,
4000 .generic_decl = .generic_decl_const,4000 .decl_abstract = .decl_abstract_const,
4001 .decl_instance = .decl_instance_union,4001 .decl_instance = .decl_instance_union,
4002 }, &nav, file, &decl);4002 }, &nav, file, &decl);
4003 break :t true;4003 break :t true;
...@@ -4059,7 +4059,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -4059,7 +4059,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
4059 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);4059 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
4060 try wip_nav.declCommon(.{4060 try wip_nav.declCommon(.{
4061 .decl = .decl_packed_union,4061 .decl = .decl_packed_union,
4062 .generic_decl = .generic_decl_const,4062 .decl_abstract = .decl_abstract_const,
4063 .decl_instance = .decl_instance_packed_union,4063 .decl_instance = .decl_instance_packed_union,
4064 }, &nav, file, &decl);4064 }, &nav, file, &decl);
4065 break :t true;4065 break :t true;
...@@ -4092,11 +4092,11 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -4092,11 +4092,11 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
4092 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);4092 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
4093 try wip_nav.declCommon(if (loaded_enum.field_names.len > 0) .{4093 try wip_nav.declCommon(if (loaded_enum.field_names.len > 0) .{
4094 .decl = .decl_enum,4094 .decl = .decl_enum,
4095 .generic_decl = .generic_decl_const,4095 .decl_abstract = .decl_abstract_const,
4096 .decl_instance = .decl_instance_enum,4096 .decl_instance = .decl_instance_enum,
4097 } else .{4097 } else .{
4098 .decl = .decl_empty_enum,4098 .decl = .decl_empty_enum,
4099 .generic_decl = .generic_decl_const,4099 .decl_abstract = .decl_abstract_const,
4100 .decl_instance = .decl_instance_empty_enum,4100 .decl_instance = .decl_instance_empty_enum,
4101 }, &nav, file, &decl);4101 }, &nav, file, &decl);
4102 } else {4102 } else {
...@@ -4134,7 +4134,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -4134,7 +4134,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
4134 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);4134 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
4135 try wip_nav.declCommon(.{4135 try wip_nav.declCommon(.{
4136 .decl = .decl_namespace_struct,4136 .decl = .decl_namespace_struct,
4137 .generic_decl = .generic_decl_const,4137 .decl_abstract = .decl_abstract_const,
4138 .decl_instance = .decl_instance_namespace_struct,4138 .decl_instance = .decl_instance_namespace_struct,
4139 }, &nav, file, &decl);4139 }, &nav, file, &decl);
4140 } else {4140 } else {
...@@ -4645,7 +4645,7 @@ fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { unpacked, opv_null, err...@@ -4645,7 +4645,7 @@ fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { unpacked, opv_null, err
4645 };4645 };
4646}4646}
46474647
4648pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedInst.Index) UpdateError!void {4648pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedInst.Index, line: u32) UpdateError!void {
4649 const comp = dwarf.bin_file.comp;4649 const comp = dwarf.bin_file.comp;
4650 const io = comp.io;4650 const io = comp.io;
4651 const ip = &zcu.intern_pool;4651 const ip = &zcu.intern_pool;
...@@ -4653,17 +4653,9 @@ pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedI...@@ -4653,17 +4653,9 @@ pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedI
4653 const inst_info = zir_index.resolveFull(ip).?;4653 const inst_info = zir_index.resolveFull(ip).?;
4654 assert(inst_info.inst != .main_struct_inst);4654 assert(inst_info.inst != .main_struct_inst);
4655 const file = zcu.fileByIndex(inst_info.file);4655 const file = zcu.fileByIndex(inst_info.file);
4656 const decl = file.zir.?.getDeclaration(inst_info.inst);
4657 log.debug("updateLineNumber({s}:{d}:{d} %{d} = {s})", .{
4658 file.sub_file_path,
4659 decl.src_line + 1,
4660 decl.src_column + 1,
4661 @backingInt(inst_info.inst),
4662 file.zir.?.nullTerminatedString(decl.name),
4663 });
46644656
4665 var line_buf: [4]u8 = undefined;4657 var line_buf: [4]u8 = undefined;
4666 std.mem.writeInt(u32, &line_buf, decl.src_line + 1, dwarf.endian);4658 std.mem.writeInt(u32, &line_buf, line + 1, dwarf.endian);
46674659
4668 const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod.?) orelse return);4660 const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod.?) orelse return);
4669 const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return);4661 const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return);
...@@ -5144,9 +5136,9 @@ const AbbrevCode = enum {...@@ -5144,9 +5136,9 @@ const AbbrevCode = enum {
5144 decl_func_generic,5136 decl_func_generic,
5145 decl_extern_nullary_func,5137 decl_extern_nullary_func,
5146 decl_extern_func,5138 decl_extern_func,
5147 generic_decl_var,5139 decl_abstract_var,
5148 generic_decl_const,5140 decl_abstract_const,
5149 generic_decl_func,5141 decl_abstract_func,
5150 decl_instance_alias,5142 decl_instance_alias,
5151 decl_instance_empty_enum,5143 decl_instance_empty_enum,
5152 decl_instance_enum,5144 decl_instance_enum,
...@@ -5270,7 +5262,7 @@ const AbbrevCode = enum {...@@ -5270,7 +5262,7 @@ const AbbrevCode = enum {
5270 .{ .accessibility, .data1 },5262 .{ .accessibility, .data1 },
5271 .{ .name, .strp },5263 .{ .name, .strp },
5272 };5264 };
5273 const generic_decl_abbrev_common_attrs = decl_abbrev_common_attrs ++ &[_]Attr{5265 const decl_abstract_abbrev_common_attrs = decl_abbrev_common_attrs ++ &[_]Attr{
5274 .{ .declaration, .flag_present },5266 .{ .declaration, .flag_present },
5275 };5267 };
5276 const decl_instance_abbrev_common_attrs = &[_]Attr{5268 const decl_instance_abbrev_common_attrs = &[_]Attr{
...@@ -5455,17 +5447,17 @@ const AbbrevCode = enum {...@@ -5455,17 +5447,17 @@ const AbbrevCode = enum {
5455 .{ .noreturn, .flag },5447 .{ .noreturn, .flag },
5456 },5448 },
5457 },5449 },
5458 .generic_decl_var = .{5450 .decl_abstract_var = .{
5459 .tag = .variable,5451 .tag = .variable,
5460 .attrs = generic_decl_abbrev_common_attrs,5452 .attrs = decl_abstract_abbrev_common_attrs,
5461 },5453 },
5462 .generic_decl_const = .{5454 .decl_abstract_const = .{
5463 .tag = .constant,5455 .tag = .constant,
5464 .attrs = generic_decl_abbrev_common_attrs,5456 .attrs = decl_abstract_abbrev_common_attrs,
5465 },5457 },
5466 .generic_decl_func = .{5458 .decl_abstract_func = .{
5467 .tag = .subprogram,5459 .tag = .subprogram,
5468 .attrs = generic_decl_abbrev_common_attrs,5460 .attrs = decl_abstract_abbrev_common_attrs,
5469 },5461 },
5470 .decl_instance_alias = .{5462 .decl_instance_alias = .{
5471 .tag = .imported_declaration,5463 .tag = .imported_declaration,
src/link/Dwarf2.zig+182-130
...@@ -8,7 +8,8 @@ units: std.array_hash_map.Auto(*Module, Unit),...@@ -8,7 +8,8 @@ units: std.array_hash_map.Auto(*Module, Unit),
8/// Indices are `link.ConstPool.Index`.8/// Indices are `link.ConstPool.Index`.
9values: std.ArrayList(Value),9values: std.ArrayList(Value),
10globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),10globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),
11funcs: std.array_hash_map.Auto(InternPool.TrackedInst.Index, Func),11funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func),
12decls: std.array_hash_map.Auto(InternPool.TrackedInst.Index, MappedFile.Node.Index),
1213
13debug_abbrev: Abbrev,14debug_abbrev: Abbrev,
14frame: Frame,15frame: Frame,
...@@ -32,7 +33,8 @@ pub const Unit = struct {...@@ -32,7 +33,8 @@ pub const Unit = struct {
32 debug_line_header_ni: MappedFile.Node.Index.Optional,33 debug_line_header_ni: MappedFile.Node.Index.Optional,
33 debug_line_header_changed: bool,34 debug_line_header_changed: bool,
34 debug_rnglists_ni: MappedFile.Node.Index.Optional,35 debug_rnglists_ni: MappedFile.Node.Index.Optional,
35 debug_rnglists_offset: usize,36 debug_rnglists_offsets_table_offset: usize,
37 debug_rnglists_end: usize,
3638
37 pub const Index = enum(u32) {39 pub const Index = enum(u32) {
38 _,40 _,
...@@ -123,7 +125,6 @@ pub const Global = struct {...@@ -123,7 +125,6 @@ pub const Global = struct {
123};125};
124126
125pub const Func = struct {127pub const Func = struct {
126 owner_nav: InternPool.Nav.Index,
127 fde_ni: MappedFile.Node.Index.Optional,128 fde_ni: MappedFile.Node.Index.Optional,
128 debug_info_ni: MappedFile.Node.Index.Optional,129 debug_info_ni: MappedFile.Node.Index.Optional,
129 debug_line_ni: MappedFile.Node.Index.Optional,130 debug_line_ni: MappedFile.Node.Index.Optional,
...@@ -131,7 +132,7 @@ pub const Func = struct {...@@ -131,7 +132,7 @@ pub const Func = struct {
131 pub const Index = enum(u32) {132 pub const Index = enum(u32) {
132 _,133 _,
133134
134 pub fn srcInst(fi: Func.Index, dwarf: *Dwarf) InternPool.TrackedInst.Index {135 pub fn nav(fi: Func.Index, dwarf: *Dwarf) InternPool.Nav.Index {
135 return dwarf.funcs.keys()[@backingInt(fi)];136 return dwarf.funcs.keys()[@backingInt(fi)];
136 }137 }
137138
...@@ -156,7 +157,7 @@ pub const Frame = struct {...@@ -156,7 +157,7 @@ pub const Frame = struct {
156157
157pub const Abbrev = struct {158pub const Abbrev = struct {
158 ni: MappedFile.Node.Index.Optional,159 ni: MappedFile.Node.Index.Optional,
159 offset: usize,160 end: usize,
160 set: std.enums.EnumSet(AbbrevCode),161 set: std.enums.EnumSet(AbbrevCode),
161};162};
162163
...@@ -628,7 +629,7 @@ pub const WipNav = struct {...@@ -628,7 +629,7 @@ pub const WipNav = struct {
628 pub fn startDebugInfo(debug: *Debug) link.Error!void {629 pub fn startDebugInfo(debug: *Debug) link.Error!void {
629 assert(debug.wip_nav.func != .none);630 assert(debug.wip_nav.func != .none);
630 debug.startDebugInfoInner() catch |err| switch (err) {631 debug.startDebugInfoInner() catch |err| switch (err) {
631 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),632 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
632 else => |e| return e,633 else => |e| return e,
633 };634 };
634 }635 }
...@@ -637,7 +638,8 @@ pub const WipNav = struct {...@@ -637,7 +638,8 @@ pub const WipNav = struct {
637 const zcu = debug.pt.zcu;638 const zcu = debug.pt.zcu;
638 const ip = &zcu.intern_pool;639 const ip = &zcu.intern_pool;
639 const func = zcu.funcInfo(debug.wip_nav.func);640 const func = zcu.funcInfo(debug.wip_nav.func);
640 const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?;641 const src_inst = ip.getNav(func.owner_nav).srcInst(ip);
642 const inst_info = src_inst.resolveFull(ip).?;
641 const decl = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst);643 const decl = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst);
642 const nav = ip.getNav(func.owner_nav);644 const nav = ip.getNav(func.owner_nav);
643 const diw = &debug.info_writer.interface;645 const diw = &debug.info_writer.interface;
...@@ -655,7 +657,7 @@ pub const WipNav = struct {...@@ -655,7 +657,7 @@ pub const WipNav = struct {
655 pub fn startDebugLine(debug: *Debug) link.Error!void {657 pub fn startDebugLine(debug: *Debug) link.Error!void {
656 assert(debug.wip_nav.func != .none);658 assert(debug.wip_nav.func != .none);
657 debug.startDebugLineInner() catch |err| switch (err) {659 debug.startDebugLineInner() catch |err| switch (err) {
658 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),660 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
659 else => |e| return e,661 else => |e| return e,
660 };662 };
661 }663 }
...@@ -698,24 +700,25 @@ pub const WipNav = struct {...@@ -698,24 +700,25 @@ pub const WipNav = struct {
698 pub fn finishFunc(debug: *Debug, func_length: u64) link.Error!void {700 pub fn finishFunc(debug: *Debug, func_length: u64) link.Error!void {
699 assert(debug.wip_nav.func != .none);701 assert(debug.wip_nav.func != .none);
700 debug.finishDebugInfo(func_length) catch |err| switch (err) {702 debug.finishDebugInfo(func_length) catch |err| switch (err) {
701 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),703 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
702 else => |e| return e,704 else => |e| return e,
703 };705 };
704 debug.finishDebugLine() catch |err| switch (err) {706 debug.finishDebugLine() catch |err| switch (err) {
705 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),707 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
706 else => |e| return e,708 else => |e| return e,
707 };709 };
708 }710 }
709 fn finishDebugInfo(debug: *Debug, func_length: u64) link.EmitError!void {711 fn finishDebugInfo(debug: *Debug, func_length: u64) link.EmitError!void {
712 const dwarf = debug.wip_nav.dwarf;
710 const diw = &debug.info_writer.interface;713 const diw = &debug.info_writer.interface;
711 std.mem.writeInt(714 std.mem.writeInt(
712 u32,715 u32,
713 diw.buffered()[debug.info_func_length_offset..][0..4],716 diw.buffered()[debug.info_func_length_offset..][0..4],
714 @intCast(func_length),717 @intCast(func_length),
715 debug.wip_nav.dwarf.endian,718 dwarf.endian,
716 );719 );
717 try diw.writeUleb128(@backingInt(AbbrevCode.null));720 try diw.writeUleb128(@backingInt(AbbrevCode.null));
718 try debug.wip_nav.dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());721 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());
719 }722 }
720 fn finishDebugLine(debug: *Debug) link.EmitError!void {723 fn finishDebugLine(debug: *Debug) link.EmitError!void {
721 const dlw = &debug.line_writer.interface;724 const dlw = &debug.line_writer.interface;
...@@ -731,7 +734,7 @@ pub const WipNav = struct {...@@ -731,7 +734,7 @@ pub const WipNav = struct {
731 loc: Loc,734 loc: Loc,
732 ) link.Error!void {735 ) link.Error!void {
733 return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) {736 return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) {
734 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),737 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
735 else => |e| e,738 else => |e| e,
736 };739 };
737 }740 }
...@@ -761,7 +764,7 @@ pub const WipNav = struct {...@@ -761,7 +764,7 @@ pub const WipNav = struct {
761 val: ZigValue,764 val: ZigValue,
762 ) link.Error!void {765 ) link.Error!void {
763 return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) {766 return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) {
764 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),767 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
765 else => |e| e,768 else => |e| e,
766 };769 };
767 }770 }
...@@ -798,7 +801,7 @@ pub const WipNav = struct {...@@ -798,7 +801,7 @@ pub const WipNav = struct {
798801
799 pub fn genVarArgsDebugInfo(debug: *Debug) link.Error!void {802 pub fn genVarArgsDebugInfo(debug: *Debug) link.Error!void {
800 return debug.genVarArgsDebugInfoInner() catch |err| switch (err) {803 return debug.genVarArgsDebugInfoInner() catch |err| switch (err) {
801 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),804 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
802 else => |e| e,805 else => |e| e,
803 };806 };
804 }807 }
...@@ -815,7 +818,7 @@ pub const WipNav = struct {...@@ -815,7 +818,7 @@ pub const WipNav = struct {
815 end: bool,818 end: bool,
816 ) link.Error!void {819 ) link.Error!void {
817 return debug.advanceLineAndPcInner(delta_line, delta_pc, end) catch |err| switch (err) {820 return debug.advanceLineAndPcInner(delta_line, delta_pc, end) catch |err| switch (err) {
818 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),821 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
819 };822 };
820 }823 }
821 fn advanceLineAndPcInner(824 fn advanceLineAndPcInner(
...@@ -870,7 +873,7 @@ pub const WipNav = struct {...@@ -870,7 +873,7 @@ pub const WipNav = struct {
870873
871 pub fn setColumn(debug: *Debug, column: u32) link.Error!void {874 pub fn setColumn(debug: *Debug, column: u32) link.Error!void {
872 return debug.setColumnInner(column) catch |err| switch (err) {875 return debug.setColumnInner(column) catch |err| switch (err) {
873 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),876 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
874 };877 };
875 }878 }
876 fn setColumnInner(debug: *Debug, column: u32) Writer.Error!void {879 fn setColumnInner(debug: *Debug, column: u32) Writer.Error!void {
...@@ -881,7 +884,7 @@ pub const WipNav = struct {...@@ -881,7 +884,7 @@ pub const WipNav = struct {
881884
882 pub fn negateStmt(debug: *Debug) link.Error!void {885 pub fn negateStmt(debug: *Debug) link.Error!void {
883 return debug.negateStmtInner() catch |err| switch (err) {886 return debug.negateStmtInner() catch |err| switch (err) {
884 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),887 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
885 };888 };
886 }889 }
887 fn negateStmtInner(debug: *Debug) Writer.Error!void {890 fn negateStmtInner(debug: *Debug) Writer.Error!void {
...@@ -890,7 +893,7 @@ pub const WipNav = struct {...@@ -890,7 +893,7 @@ pub const WipNav = struct {
890893
891 pub fn setPrologueEnd(debug: *Debug) link.Error!void {894 pub fn setPrologueEnd(debug: *Debug) link.Error!void {
892 return debug.setPrologueEndInner() catch |err| switch (err) {895 return debug.setPrologueEndInner() catch |err| switch (err) {
893 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),896 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
894 };897 };
895 }898 }
896 fn setPrologueEndInner(debug: *Debug) Writer.Error!void {899 fn setPrologueEndInner(debug: *Debug) Writer.Error!void {
...@@ -899,7 +902,7 @@ pub const WipNav = struct {...@@ -899,7 +902,7 @@ pub const WipNav = struct {
899902
900 pub fn setEpilogueBegin(debug: *Debug) link.Error!void {903 pub fn setEpilogueBegin(debug: *Debug) link.Error!void {
901 return debug.setEpilogueBeginInner() catch |err| switch (err) {904 return debug.setEpilogueBeginInner() catch |err| switch (err) {
902 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),905 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
903 };906 };
904 }907 }
905 fn setEpilogueBeginInner(debug: *Debug) Writer.Error!void {908 fn setEpilogueBeginInner(debug: *Debug) Writer.Error!void {
...@@ -908,7 +911,7 @@ pub const WipNav = struct {...@@ -908,7 +911,7 @@ pub const WipNav = struct {
908911
909 pub fn enterBlock(debug: *Debug, code_off: usize) link.Error!void {912 pub fn enterBlock(debug: *Debug, code_off: usize) link.Error!void {
910 return debug.enterBlockInner(code_off) catch |err| switch (err) {913 return debug.enterBlockInner(code_off) catch |err| switch (err) {
911 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),914 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
912 else => |e| e,915 else => |e| e,
913 };916 };
914 }917 }
...@@ -928,7 +931,7 @@ pub const WipNav = struct {...@@ -928,7 +931,7 @@ pub const WipNav = struct {
928931
929 pub fn leaveBlock(debug: *Debug, code_off: usize) link.Error!void {932 pub fn leaveBlock(debug: *Debug, code_off: usize) link.Error!void {
930 return debug.leaveBlockInner(code_off) catch |err| switch (err) {933 return debug.leaveBlockInner(code_off) catch |err| switch (err) {
931 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),934 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
932 else => |e| e,935 else => |e| e,
933 };936 };
934 }937 }
...@@ -961,7 +964,7 @@ pub const WipNav = struct {...@@ -961,7 +964,7 @@ pub const WipNav = struct {
961 column: u32,964 column: u32,
962 ) link.Error!void {965 ) link.Error!void {
963 return debug.enterInlineFuncInner(func, code_off, line, column) catch |err| switch (err) {966 return debug.enterInlineFuncInner(func, code_off, line, column) catch |err| switch (err) {
964 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),967 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
965 else => |e| e,968 else => |e| e,
966 };969 };
967 }970 }
...@@ -996,7 +999,7 @@ pub const WipNav = struct {...@@ -996,7 +999,7 @@ pub const WipNav = struct {
996999
997 pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: usize) link.Error!void {1000 pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: usize) link.Error!void {
998 return debug.leaveInlineFuncInner(func, code_off) catch |err| switch (err) {1001 return debug.leaveInlineFuncInner(func, code_off) catch |err| switch (err) {
999 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),1002 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
1000 else => |e| e,1003 else => |e| e,
1001 };1004 };
1002 }1005 }
...@@ -1029,7 +1032,7 @@ pub const WipNav = struct {...@@ -1029,7 +1032,7 @@ pub const WipNav = struct {
10291032
1030 pub fn setInlineFunc(debug: *Debug, func: InternPool.Index) link.Error!void {1033 pub fn setInlineFunc(debug: *Debug, func: InternPool.Index) link.Error!void {
1031 return debug.setInlineFuncInner(func) catch |err| switch (err) {1034 return debug.setInlineFuncInner(func) catch |err| switch (err) {
1032 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),1035 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
1033 else => |e| e,1036 else => |e| e,
1034 };1037 };
1035 }1038 }
...@@ -1187,7 +1190,7 @@ pub const WipNav = struct {...@@ -1187,7 +1190,7 @@ pub const WipNav = struct {
11871190
1188 pub fn genDebugFrameHeader(wip_nav: *WipNav) link.Error!void {1191 pub fn genDebugFrameHeader(wip_nav: *WipNav) link.Error!void {
1189 wip_nav.genDebugFrameHeaderInner() catch |err| switch (err) {1192 wip_nav.genDebugFrameHeaderInner() catch |err| switch (err) {
1190 error.WriteFailed => return wip_nav.reportWriteError(&wip_nav.fde_writer),1193 error.WriteFailed => return wip_nav.dwarf.reportWriteError(&wip_nav.fde_writer),
1191 else => |e| return e,1194 else => |e| return e,
1192 };1195 };
1193 }1196 }
...@@ -1230,7 +1233,7 @@ pub const WipNav = struct {...@@ -1230,7 +1233,7 @@ pub const WipNav = struct {
12301233
1231 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.Error!void {1234 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.Error!void {
1232 return wip_nav.genDebugFrameInner(loc, cfa) catch |err| switch (err) {1235 return wip_nav.genDebugFrameInner(loc, cfa) catch |err| switch (err) {
1233 error.WriteFailed => return wip_nav.reportWriteError(&wip_nav.fde_writer),1236 error.WriteFailed => return wip_nav.dwarf.reportWriteError(&wip_nav.fde_writer),
1234 else => |e| return e,1237 else => |e| return e,
1235 };1238 };
1236 }1239 }
...@@ -1336,16 +1339,6 @@ pub const WipNav = struct {...@@ -1336,16 +1339,6 @@ pub const WipNav = struct {
1336 },1339 },
1337 );1340 );
1338 }1341 }
1339
1340 fn reportWriteError(wip_nav: *WipNav, mfnw: *const MappedFile.Node.Writer) link.Error {
1341 switch (mfnw.err.?) {
1342 else => |e| return e,
1343 error.MappedFileIo => return wip_nav.dwarf.lf.comp.link_diags.fail(
1344 "failed to write output file: {t}",
1345 .{mfnw.mf.io_err.?},
1346 ),
1347 }
1348 }
1349};1342};
13501343
1351pub fn init(lf: *link.File, format: DW.Format) Dwarf {1344pub fn init(lf: *link.File, format: DW.Format) Dwarf {
...@@ -1365,10 +1358,11 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {...@@ -1365,10 +1358,11 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
1365 .values = .empty,1358 .values = .empty,
1366 .globals = .empty,1359 .globals = .empty,
1367 .funcs = .empty,1360 .funcs = .empty,
1361 .decls = .empty,
13681362
1369 .debug_abbrev = .{1363 .debug_abbrev = .{
1370 .ni = .none,1364 .ni = .none,
1371 .offset = 0,1365 .end = 0,
1372 .set = .empty,1366 .set = .empty,
1373 },1367 },
1374 .frame = .{1368 .frame = .{
...@@ -1443,7 +1437,7 @@ pub fn deinit(dwarf: *Dwarf) void {...@@ -1443,7 +1437,7 @@ pub fn deinit(dwarf: *Dwarf) void {
1443 dwarf.* = undefined;1437 dwarf.* = undefined;
1444}1438}
14451439
1446pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {1440pub fn updateUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {
1447 try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count() - dwarf.units.count());1441 try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count() - dwarf.units.count());
1448 for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, root| if (root.unwrap()) |root_zfi| {1442 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;1443 if (!zcu.alive_files.contains(root_zfi)) continue;
...@@ -1461,7 +1455,8 @@ pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {...@@ -1461,7 +1455,8 @@ pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {
1461 .debug_line_header_ni = .none,1455 .debug_line_header_ni = .none,
1462 .debug_line_header_changed = true,1456 .debug_line_header_changed = true,
1463 .debug_rnglists_ni = .none,1457 .debug_rnglists_ni = .none,
1464 .debug_rnglists_offset = undefined,1458 .debug_rnglists_offsets_table_offset = undefined,
1459 .debug_rnglists_end = undefined,
1465 };1460 };
1466 const root_di, const root_fi = try unit_gop.value_ptr.getFile(1461 const root_di, const root_fi = try unit_gop.value_ptr.getFile(
1467 zcu.gpa,1462 zcu.gpa,
...@@ -1476,15 +1471,48 @@ pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {...@@ -1476,15 +1471,48 @@ pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {
1476 return @fromBackingInt(@intCast(dwarf.units.getIndex(mod).?));1471 return @fromBackingInt(@intCast(dwarf.units.getIndex(mod).?));
1477}1472}
14781473
1479pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.Index {1474pub fn getGlobal(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Global.Index {
1480 const comp = dwarf.lf.comp;1475 const comp = dwarf.lf.comp;
1481 const gpa = comp.gpa;1476 const gpa = comp.gpa;
1482 const zcu = comp.zcu.?;1477 const global_gop = try dwarf.globals.getOrPut(gpa, nav);
1483 const ip = &zcu.intern_pool;1478 if (!global_gop.found_existing) global_gop.value_ptr.* = .{
1484 const src_inst = ip.getNav(owner_nav).srcInst(ip);1479 .debug_info_ni = .none,
1485 const func_gop = try dwarf.funcs.getOrPut(gpa, src_inst);1480 };
1481 const gi: Global.Index = @fromBackingInt(@intCast(global_gop.index));
1482 if (global_gop.value_ptr.debug_info_ni == .none) {
1483 const elf = dwarf.lf.cast(.elf2).?;
1484 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1485 try elf.dwarf_globals.ensureUnusedCapacity(gpa, 1);
1486 const unit = dwarf.getUnit(comp.zcu.?.zcu.navFileScope(nav).mod.?).get(dwarf);
1487 assert(unit.debug_info_ni != .none);
1488 global_gop.value_ptr.debug_info_ni = elf.addNodeAssumeCapacity(
1489 elf.mf.addLastChildNode(gpa, unit.debug_info_ni, .{
1490 .enable_next_moved = true,
1491 }) catch |err| switch (err) {
1492 else => |e| return e,
1493 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1494 elf.mf.io_err.?,
1495 }),
1496 },
1497 .{ .global_debug_info = gi },
1498 );
1499 elf.dwarf_globals.addOneAssumeCapacity().* = .{
1500 .debug_info_first_target_reloc = .none,
1501 .debug_info_first_node_reloc = .none,
1502 .debug_info_first_symbol_reloc = .none,
1503 };
1504 }
1505 return gi;
1506}
1507pub fn getGlobalIfExists(dwarf: *Dwarf, nav: InternPool.Nav.Index) ?Global.Index {
1508 return @fromBackingInt(@intCast(dwarf.globals.getIndex(nav) orelse return null));
1509}
1510
1511pub fn getFunc(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Func.Index {
1512 const comp = dwarf.lf.comp;
1513 const gpa = comp.gpa;
1514 const func_gop = try dwarf.funcs.getOrPut(gpa, nav);
1486 if (!func_gop.found_existing) func_gop.value_ptr.* = .{1515 if (!func_gop.found_existing) func_gop.value_ptr.* = .{
1487 .owner_nav = owner_nav,
1488 .fde_ni = .none,1516 .fde_ni = .none,
1489 .debug_info_ni = .none,1517 .debug_info_ni = .none,
1490 .debug_line_ni = .none,1518 .debug_line_ni = .none,
...@@ -1494,7 +1522,7 @@ pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.I...@@ -1494,7 +1522,7 @@ pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.I
1494 const elf = dwarf.lf.cast(.elf2).?;1522 const elf = dwarf.lf.cast(.elf2).?;
1495 try elf.nodes.ensureUnusedCapacity(gpa, 1);1523 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1496 try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1);1524 try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1);
1497 const unit = dwarf.getUnit(zcu.fileByIndex(src_inst.resolveFile(ip)).mod.?).get(dwarf);1525 const unit = dwarf.getUnit(comp.zcu.?.navFileScope(nav).mod.?).get(dwarf);
1498 func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(1526 func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(
1499 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{1527 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
1500 .enable_next_moved = true,1528 .enable_next_moved = true,
...@@ -1518,10 +1546,8 @@ pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.I...@@ -1518,10 +1546,8 @@ pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.I
1518 }1546 }
1519 return fi;1547 return fi;
1520}1548}
1521pub fn getFuncIfExists(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) ?Func.Index {1549pub fn getFuncIfExists(dwarf: *Dwarf, nav: InternPool.Nav.Index) ?Func.Index {
1522 const ip = &dwarf.lf.comp.zcu.?.intern_pool;1550 return @fromBackingInt(@intCast(dwarf.funcs.getIndex(nav) orelse return null));
1523 return @fromBackingInt(@intCast(dwarf.funcs.getIndex(ip.getNav(owner_nav).srcInst(ip)) orelse
1524 return null));
1525}1551}
15261552
1527pub fn unitLengthSize(dwarf: *Dwarf) usize {1553pub fn unitLengthSize(dwarf: *Dwarf) usize {
...@@ -1654,11 +1680,11 @@ pub fn updateEhFrameFde(dwarf: *Dwarf, fde: []u8, fde_offset: u64) void {...@@ -1654,11 +1680,11 @@ pub fn updateEhFrameFde(dwarf: *Dwarf, fde: []u8, fde_offset: u64) void {
16541680
1655pub fn genDebugInfoHeader(1681pub fn genDebugInfoHeader(
1656 dwarf: *Dwarf,1682 dwarf: *Dwarf,
1683 zcu: *Zcu,
1657 mod: *Module,1684 mod: *Module,
1658 unit: *Unit,1685 unit: *Unit,
1659 dih_nw: *MappedFile.Node.Writer,1686 dih_nw: *MappedFile.Node.Writer,
1660 debug_rnglists_offsets_table_offset: usize,1687 debug_rnglists_offsets_table_offset: usize,
1661 zcu: *Zcu,
1662) link.EmitError!void {1688) link.EmitError!void {
1663 const comp = zcu.comp;1689 const comp = zcu.comp;
1664 const dihw = &dih_nw.interface;1690 const dihw = &dih_nw.interface;
...@@ -1695,20 +1721,22 @@ pub fn genDebugInfoHeader(...@@ -1695,20 +1721,22 @@ pub fn genDebugInfoHeader(
1695 zcu.builtin_modules.get(mod.getBuiltinOptions(comp.config).hash()).?,1721 zcu.builtin_modules.get(mod.getBuiltinOptions(comp.config).hash()).?,
1696 zcu.root_mod,1722 zcu.root_mod,
1697 zcu.std_mod,1723 zcu.std_mod,
1698 }) |name, dep| try dwarf.genModuleDependency(dih_nw, name, dep, module_offset);1724 }) |name, dep| try dwarf.genModuleDependency(zcu, dih_nw, name, dep, module_offset);
1699 for (mod.deps.keys(), mod.deps.values()) |name, dep|1725 for (mod.deps.keys(), mod.deps.values()) |name, dep|
1700 try dwarf.genModuleDependency(dih_nw, name, dep, module_offset);1726 try dwarf.genModuleDependency(zcu, dih_nw, name, dep, module_offset);
1701 for ([2]AbbrevCode{ .pad_1, .pad_n }) |pad| _ = try dwarf.refAbbrevCode(pad);1727 for ([2]AbbrevCode{ .pad_1, .pad_n }) |pad| _ = try dwarf.refAbbrevCode(pad);
1702 try dwarf.genDebugInfoPadding(dihw, dihw.unusedCapacityLen());1728 try dwarf.genDebugInfoPadding(dihw, dihw.unusedCapacityLen());
1703}1729}
17041730
1705fn genModuleDependency(1731fn genModuleDependency(
1706 dwarf: *Dwarf,1732 dwarf: *Dwarf,
1733 zcu: *Zcu,
1707 nw: *MappedFile.Node.Writer,1734 nw: *MappedFile.Node.Writer,
1708 name: []const u8,1735 name: []const u8,
1709 dep: *Module,1736 dep: *Module,
1710 module_offset: usize,1737 module_offset: usize,
1711) link.EmitError!void {1738) link.EmitError!void {
1739 if (!zcu.alive_files.contains(zcu.module_roots.get(dep).?.unwrap() orelse return)) return;
1712 const diw = &nw.interface;1740 const diw = &nw.interface;
1713 try diw.writeUleb128(try dwarf.refAbbrevCode(.module_dependency));1741 try diw.writeUleb128(try dwarf.refAbbrevCode(.module_dependency));
1714 try diw.writeAll(name);1742 try diw.writeAll(name);
...@@ -1889,7 +1917,7 @@ pub fn genDebugRnglistsHeader(...@@ -1889,7 +1917,7 @@ pub fn genDebugRnglistsHeader(
1889 .@"32" => try drhw.writeInt(u32, 4, dwarf.endian),1917 .@"32" => try drhw.writeInt(u32, 4, dwarf.endian),
1890 .@"64" => try drhw.writeInt(u64, 8, dwarf.endian),1918 .@"64" => try drhw.writeInt(u64, 8, dwarf.endian),
1891 }1919 }
1892 unit.debug_rnglists_offset = drhw.end;1920 unit.debug_rnglists_end = drhw.end;
1893 try drhw.writeByte(DW.RLE.end_of_list);1921 try drhw.writeByte(DW.RLE.end_of_list);
1894 return offsets_table_offset;1922 return offsets_table_offset;
1895}1923}
...@@ -1902,24 +1930,22 @@ pub fn genDebugRnglists(...@@ -1902,24 +1930,22 @@ pub fn genDebugRnglists(
1902 func_length: u64,1930 func_length: u64,
1903) link.EmitError!void {1931) link.EmitError!void {
1904 const drw = &dr_nw.interface;1932 const drw = &dr_nw.interface;
1905 drw.end = unit.debug_rnglists_offset;1933 drw.end = unit.debug_rnglists_end;
1906 try drw.writeByte(DW.RLE.start_length);1934 try drw.writeByte(DW.RLE.start_length);
1907 try dwarf.symbolAddress(dr_nw, func_si, 0);1935 try dwarf.symbolAddress(dr_nw, func_si, 0);
1908 try drw.writeUleb128(func_length);1936 try drw.writeUleb128(func_length);
1909 unit.debug_rnglists_offset = drw.end;1937 unit.debug_rnglists_end = drw.end;
1910 try drw.writeByte(DW.RLE.end_of_list);1938 try drw.writeByte(DW.RLE.end_of_list);
1911}1939}
19121940
1913pub fn updateLineNumber(1941pub fn updateLineNumber(
1914 dwarf: *Dwarf,1942 dwarf: *Dwarf,
1915 zcu: *Zcu,1943 mf: *MappedFile,
1916 src_inst: InternPool.TrackedInst.Index,1944 inst: InternPool.TrackedInst.Index,
1917 debug_info: []u8,1945 line: u32,
1918) void {1946) void {
1919 const inst_info = src_inst.resolveFull(&zcu.intern_pool).?;1947 const decl_ni = dwarf.decls.get(inst) orelse return;
1920 assert(inst_info.inst != .main_struct_inst);1948 std.mem.writeInt(u32, decl_ni.slice(mf)[AbbrevCode.decl_bytes..][0..4], line + 1, dwarf.endian);
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}1949}
19241950
1925fn refAbbrevCodeIfExists(1951fn refAbbrevCodeIfExists(
...@@ -1930,36 +1956,45 @@ fn refAbbrevCodeIfExists(...@@ -1930,36 +1956,45 @@ fn refAbbrevCodeIfExists(
1930 return if (dwarf.debug_abbrev.set.contains(abbrev_code)) @backingInt(abbrev_code) else null;1956 return if (dwarf.debug_abbrev.set.contains(abbrev_code)) @backingInt(abbrev_code) else null;
1931}1957}
19321958
1933fn refAbbrevCode(1959pub fn refAbbrevCode(
1934 dwarf: *Dwarf,1960 dwarf: *Dwarf,
1935 abbrev_code: AbbrevCode,1961 abbrev_code: AbbrevCode,
1936) link.EmitError!@typeInfo(AbbrevCode).@"enum".tag_type {1962) link.Error!@typeInfo(AbbrevCode).@"enum".tag_type {
1937 if (dwarf.refAbbrevCodeIfExists(abbrev_code)) |backing_int| {1963 if (dwarf.refAbbrevCodeIfExists(abbrev_code)) |backing_int| {
1938 @branchHint(.likely);1964 @branchHint(.likely);
1939 return backing_int;1965 return backing_int;
1940 }1966 }
1941 const elf = dwarf.lf.cast(.elf2).?;1967 var da_nw: MappedFile.Node.Writer = undefined;
1942 const comp = elf.base.comp;1968 dwarf.debug_abbrev.ni.unwrap().?.writer(dwarf.lf.comp.gpa, &dwarf.lf.cast(.elf2).?.mf, &da_nw);
1943 var nw: MappedFile.Node.Writer = undefined;1969 defer da_nw.deinit();
1944 dwarf.debug_abbrev.ni.unwrap().?.writer(comp.gpa, &elf.mf, &nw);1970 dwarf.genDebugAbbrev(&da_nw, abbrev_code) catch |err| switch (err) {
1945 defer nw.deinit();1971 else => |e| return e,
1972 error.WriteFailed => return dwarf.reportWriteError(&da_nw),
1973 };
1974 dwarf.debug_abbrev.set.insert(abbrev_code);
1975 return dwarf.refAbbrevCodeIfExists(abbrev_code).?;
1976}
1977
1978fn genDebugAbbrev(
1979 dwarf: *Dwarf,
1980 da_nw: *MappedFile.Node.Writer,
1981 abbrev_code: AbbrevCode,
1982) link.EmitError!void {
1946 const abbrev = AbbrevCode.abbrevs.get(abbrev_code);1983 const abbrev = AbbrevCode.abbrevs.get(abbrev_code);
1947 const daw = &nw.interface;1984 const daw = &da_nw.interface;
1948 daw.end = dwarf.debug_abbrev.offset;1985 daw.end = dwarf.debug_abbrev.end;
1949 try daw.writeUleb128(@backingInt(abbrev_code));1986 try daw.writeUleb128(@backingInt(abbrev_code));
1950 try daw.writeUleb128(@backingInt(abbrev.tag));1987 try daw.writeUleb128(@backingInt(abbrev.tag));
1951 try daw.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);1988 try daw.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
1952 for (abbrev.attrs) |*attr| {1989 for (abbrev.attrs) |*attr| {
1953 try daw.writeUleb128(@backingInt(switch (attr[0]) {1990 try daw.writeUleb128(@backingInt(switch (attr[0]) {
1954 else => |at| at,1991 else => |at| at,
1955 .ZIG_call_line_relative => |at| if (comp.config.incremental) at else .call_line,1992 .ZIG_call_line_relative => |at| if (dwarf.lf.comp.config.incremental) at else .call_line,
1956 }));1993 }));
1957 try daw.writeUleb128(@backingInt(attr[1]));1994 try daw.writeUleb128(@backingInt(attr[1]));
1958 }1995 }
1959 for (0..2) |_| try daw.writeUleb128(0);1996 for (0..2) |_| try daw.writeUleb128(0);
1960 dwarf.debug_abbrev.offset = daw.end;1997 dwarf.debug_abbrev.end = daw.end;
1961 dwarf.debug_abbrev.set.insert(abbrev_code);
1962 return dwarf.refAbbrevCodeIfExists(abbrev_code).?;
1963}1998}
19641999
1965fn sectionOffset(2000fn sectionOffset(
...@@ -2007,6 +2042,16 @@ fn strp(dwarf: *Dwarf, s: *Str, nw: *MappedFile.Node.Writer, str: []const u8) li...@@ -2007,6 +2042,16 @@ fn strp(dwarf: *Dwarf, s: *Str, nw: *MappedFile.Node.Writer, str: []const u8) li
2007 });2042 });
2008}2043}
20092044
2045fn reportWriteError(dwarf: *Dwarf, nw: *const MappedFile.Node.Writer) link.Error {
2046 switch (nw.err.?) {
2047 else => |e| return e,
2048 error.MappedFileIo => return dwarf.lf.comp.link_diags.fail(
2049 "failed to write output file: {t}",
2050 .{nw.mf.io_err.?},
2051 ),
2052 }
2053}
2054
2010fn DeclValEnum(comptime T: type) type {2055fn DeclValEnum(comptime T: type) type {
2011 const decl_names = @typeInfo(T).@"struct".decl_names;2056 const decl_names = @typeInfo(T).@"struct".decl_names;
2012 @setEvalBranchQuota(10 * decl_names.len);2057 @setEvalBranchQuota(10 * decl_names.len);
...@@ -2034,7 +2079,8 @@ pub const AbbrevCode = enum {...@@ -2034,7 +2079,8 @@ pub const AbbrevCode = enum {
2034 // padding codes must be one byte uleb128 values to function2079 // padding codes must be one byte uleb128 values to function
2035 pad_1,2080 pad_1,
2036 pad_n,2081 pad_n,
2037 // decl, generic decl, and instance codes are assumed to all have the same uleb128 length2082 // decl, specification, and instance codes are assumed to all have the same uleb128 size
2083 decl_lost,
2038 decl_alias,2084 decl_alias,
2039 decl_empty_enum,2085 decl_empty_enum,
2040 decl_enum,2086 decl_enum,
...@@ -2054,9 +2100,9 @@ pub const AbbrevCode = enum {...@@ -2054,9 +2100,9 @@ pub const AbbrevCode = enum {
2054 decl_func_generic,2100 decl_func_generic,
2055 decl_extern_nullary_func,2101 decl_extern_nullary_func,
2056 decl_extern_func,2102 decl_extern_func,
2057 generic_decl_var,2103 decl_specification_struct,
2058 generic_decl_const,2104 decl_specification_union,
2059 generic_decl_func,2105 decl_specification_func,
2060 decl_instance_alias,2106 decl_instance_alias,
2061 decl_instance_empty_enum,2107 decl_instance_empty_enum,
2062 decl_instance_enum,2108 decl_instance_enum,
...@@ -2174,20 +2220,23 @@ pub const AbbrevCode = enum {...@@ -2174,20 +2220,23 @@ pub const AbbrevCode = enum {
2174 DeclValEnum(DW.AT),2220 DeclValEnum(DW.AT),
2175 DeclValEnum(DW.FORM),2221 DeclValEnum(DW.FORM),
2176 };2222 };
2177 const decl_abbrev_common_attrs = &[_]Attr{2223 const decl_attrs = &[_]Attr{
2178 //.{ .ZIG_parent, .ref_addr },2224 //.{ .ZIG_parent, .ref_addr },
2179 .{ .decl_line, .data4 },2225 .{ .decl_line, .data4 },
2180 .{ .decl_column, .udata },2226 .{ .decl_column, .udata },
2181 .{ .accessibility, .data1 },2227 .{ .accessibility, .data1 },
2182 .{ .name, .strp },2228 .{ .name, .strp },
2183 };2229 };
2184 const generic_decl_abbrev_common_attrs = decl_abbrev_common_attrs ++ &[_]Attr{2230
2231 const decl_specification_attrs = decl_attrs ++ &[_]Attr{
2185 .{ .declaration, .flag_present },2232 .{ .declaration, .flag_present },
2186 };2233 };
2187 const decl_instance_abbrev_common_attrs = &[_]Attr{2234
2188 .{ .ZIG_parent, .ref_addr },2235 const decl_instance_attrs = &[_]Attr{
2189 .{ .abstract_origin, .ref_addr },2236 //.{ .ZIG_parent, .ref_addr },
2237 .{ .specification, .ref_addr },
2190 };2238 };
2239
2191 const abbrevs = std.EnumArray(AbbrevCode, struct {2240 const abbrevs = std.EnumArray(AbbrevCode, struct {
2192 tag: DeclValEnum(DW.TAG),2241 tag: DeclValEnum(DW.TAG),
2193 children: bool = false,2242 children: bool = false,
...@@ -2202,35 +2251,38 @@ pub const AbbrevCode = enum {...@@ -2202,35 +2251,38 @@ pub const AbbrevCode = enum {
2202 .{ .ZIG_padding, .block },2251 .{ .ZIG_padding, .block },
2203 },2252 },
2204 },2253 },
2254 .decl_lost = .{
2255 .tag = .ZIG_lost_declaration,
2256 },
2205 .decl_alias = .{2257 .decl_alias = .{
2206 .tag = .imported_declaration,2258 .tag = .imported_declaration,
2207 .attrs = decl_abbrev_common_attrs ++ .{2259 .attrs = decl_attrs ++ .{
2208 .{ .import, .ref_addr },2260 .{ .import, .ref_addr },
2209 },2261 },
2210 },2262 },
2211 .decl_empty_enum = .{2263 .decl_empty_enum = .{
2212 .tag = .enumeration_type,2264 .tag = .enumeration_type,
2213 .attrs = decl_abbrev_common_attrs ++ .{2265 .attrs = decl_attrs ++ .{
2214 .{ .type, .ref_addr },2266 .{ .type, .ref_addr },
2215 },2267 },
2216 },2268 },
2217 .decl_enum = .{2269 .decl_enum = .{
2218 .tag = .enumeration_type,2270 .tag = .enumeration_type,
2219 .children = true,2271 .children = true,
2220 .attrs = decl_abbrev_common_attrs ++ .{2272 .attrs = decl_attrs ++ .{
2221 .{ .type, .ref_addr },2273 .{ .type, .ref_addr },
2222 },2274 },
2223 },2275 },
2224 .decl_namespace_struct = .{2276 .decl_namespace_struct = .{
2225 .tag = .structure_type,2277 .tag = .structure_type,
2226 .attrs = decl_abbrev_common_attrs ++ .{2278 .attrs = decl_attrs ++ .{
2227 .{ .declaration, .flag },2279 .{ .declaration, .flag },
2228 },2280 },
2229 },2281 },
2230 .decl_struct = .{2282 .decl_struct = .{
2231 .tag = .structure_type,2283 .tag = .structure_type,
2232 .children = true,2284 .children = true,
2233 .attrs = decl_abbrev_common_attrs ++ .{2285 .attrs = decl_attrs ++ .{
2234 .{ .byte_size, .udata },2286 .{ .byte_size, .udata },
2235 .{ .alignment, .udata },2287 .{ .alignment, .udata },
2236 },2288 },
...@@ -2238,14 +2290,14 @@ pub const AbbrevCode = enum {...@@ -2238,14 +2290,14 @@ pub const AbbrevCode = enum {
2238 .decl_packed_struct = .{2290 .decl_packed_struct = .{
2239 .tag = .structure_type,2291 .tag = .structure_type,
2240 .children = true,2292 .children = true,
2241 .attrs = decl_abbrev_common_attrs ++ .{2293 .attrs = decl_attrs ++ .{
2242 .{ .type, .ref_addr },2294 .{ .type, .ref_addr },
2243 },2295 },
2244 },2296 },
2245 .decl_union = .{2297 .decl_union = .{
2246 .tag = .union_type,2298 .tag = .union_type,
2247 .children = true,2299 .children = true,
2248 .attrs = decl_abbrev_common_attrs ++ .{2300 .attrs = decl_attrs ++ .{
2249 .{ .byte_size, .udata },2301 .{ .byte_size, .udata },
2250 .{ .alignment, .udata },2302 .{ .alignment, .udata },
2251 },2303 },
...@@ -2253,13 +2305,13 @@ pub const AbbrevCode = enum {...@@ -2253,13 +2305,13 @@ pub const AbbrevCode = enum {
2253 .decl_packed_union = .{2305 .decl_packed_union = .{
2254 .tag = .union_type,2306 .tag = .union_type,
2255 .children = true,2307 .children = true,
2256 .attrs = decl_abbrev_common_attrs ++ .{2308 .attrs = decl_attrs ++ .{
2257 .{ .type, .ref_addr },2309 .{ .type, .ref_addr },
2258 },2310 },
2259 },2311 },
2260 .decl_var = .{2312 .decl_var = .{
2261 .tag = .variable,2313 .tag = .variable,
2262 .attrs = decl_abbrev_common_attrs ++ .{2314 .attrs = decl_attrs ++ .{
2263 .{ .linkage_name, .strp },2315 .{ .linkage_name, .strp },
2264 .{ .type, .ref_addr },2316 .{ .type, .ref_addr },
2265 .{ .location, .exprloc },2317 .{ .location, .exprloc },
...@@ -2269,7 +2321,7 @@ pub const AbbrevCode = enum {...@@ -2269,7 +2321,7 @@ pub const AbbrevCode = enum {
2269 },2321 },
2270 .decl_const = .{2322 .decl_const = .{
2271 .tag = .constant,2323 .tag = .constant,
2272 .attrs = decl_abbrev_common_attrs ++ .{2324 .attrs = decl_attrs ++ .{
2273 .{ .linkage_name, .strp },2325 .{ .linkage_name, .strp },
2274 .{ .type, .ref_addr },2326 .{ .type, .ref_addr },
2275 .{ .alignment, .udata },2327 .{ .alignment, .udata },
...@@ -2278,7 +2330,7 @@ pub const AbbrevCode = enum {...@@ -2278,7 +2330,7 @@ pub const AbbrevCode = enum {
2278 },2330 },
2279 .decl_const_runtime_bits = .{2331 .decl_const_runtime_bits = .{
2280 .tag = .constant,2332 .tag = .constant,
2281 .attrs = decl_abbrev_common_attrs ++ .{2333 .attrs = decl_attrs ++ .{
2282 .{ .linkage_name, .strp },2334 .{ .linkage_name, .strp },
2283 .{ .type, .ref_addr },2335 .{ .type, .ref_addr },
2284 .{ .alignment, .udata },2336 .{ .alignment, .udata },
...@@ -2288,7 +2340,7 @@ pub const AbbrevCode = enum {...@@ -2288,7 +2340,7 @@ pub const AbbrevCode = enum {
2288 },2340 },
2289 .decl_const_comptime_state = .{2341 .decl_const_comptime_state = .{
2290 .tag = .constant,2342 .tag = .constant,
2291 .attrs = decl_abbrev_common_attrs ++ .{2343 .attrs = decl_attrs ++ .{
2292 .{ .linkage_name, .strp },2344 .{ .linkage_name, .strp },
2293 .{ .type, .ref_addr },2345 .{ .type, .ref_addr },
2294 .{ .alignment, .udata },2346 .{ .alignment, .udata },
...@@ -2298,7 +2350,7 @@ pub const AbbrevCode = enum {...@@ -2298,7 +2350,7 @@ pub const AbbrevCode = enum {
2298 },2350 },
2299 .decl_const_runtime_bits_comptime_state = .{2351 .decl_const_runtime_bits_comptime_state = .{
2300 .tag = .constant,2352 .tag = .constant,
2301 .attrs = decl_abbrev_common_attrs ++ .{2353 .attrs = decl_attrs ++ .{
2302 .{ .linkage_name, .strp },2354 .{ .linkage_name, .strp },
2303 .{ .type, .ref_addr },2355 .{ .type, .ref_addr },
2304 .{ .alignment, .udata },2356 .{ .alignment, .udata },
...@@ -2309,7 +2361,7 @@ pub const AbbrevCode = enum {...@@ -2309,7 +2361,7 @@ pub const AbbrevCode = enum {
2309 },2361 },
2310 .decl_nullary_func = .{2362 .decl_nullary_func = .{
2311 .tag = .subprogram,2363 .tag = .subprogram,
2312 .attrs = decl_abbrev_common_attrs ++ .{2364 .attrs = decl_attrs ++ .{
2313 .{ .linkage_name, .strp },2365 .{ .linkage_name, .strp },
2314 .{ .type, .ref_addr },2366 .{ .type, .ref_addr },
2315 .{ .low_pc, .addr },2367 .{ .low_pc, .addr },
...@@ -2322,7 +2374,7 @@ pub const AbbrevCode = enum {...@@ -2322,7 +2374,7 @@ pub const AbbrevCode = enum {
2322 .decl_func = .{2374 .decl_func = .{
2323 .tag = .subprogram,2375 .tag = .subprogram,
2324 .children = true,2376 .children = true,
2325 .attrs = decl_abbrev_common_attrs ++ .{2377 .attrs = decl_attrs ++ .{
2326 .{ .linkage_name, .strp },2378 .{ .linkage_name, .strp },
2327 //.{ .type, .ref_addr },2379 //.{ .type, .ref_addr },
2328 .{ .low_pc, .addr },2380 .{ .low_pc, .addr },
...@@ -2334,20 +2386,20 @@ pub const AbbrevCode = enum {...@@ -2334,20 +2386,20 @@ pub const AbbrevCode = enum {
2334 },2386 },
2335 .decl_nullary_func_generic = .{2387 .decl_nullary_func_generic = .{
2336 .tag = .subprogram,2388 .tag = .subprogram,
2337 .attrs = decl_abbrev_common_attrs ++ .{2389 .attrs = decl_attrs ++ .{
2338 .{ .type, .ref_addr },2390 .{ .type, .ref_addr },
2339 },2391 },
2340 },2392 },
2341 .decl_func_generic = .{2393 .decl_func_generic = .{
2342 .tag = .subprogram,2394 .tag = .subprogram,
2343 .children = true,2395 .children = true,
2344 .attrs = decl_abbrev_common_attrs ++ .{2396 .attrs = decl_attrs ++ .{
2345 .{ .type, .ref_addr },2397 .{ .type, .ref_addr },
2346 },2398 },
2347 },2399 },
2348 .decl_extern_nullary_func = .{2400 .decl_extern_nullary_func = .{
2349 .tag = .subprogram,2401 .tag = .subprogram,
2350 .attrs = decl_abbrev_common_attrs ++ .{2402 .attrs = decl_attrs ++ .{
2351 .{ .linkage_name, .strp },2403 .{ .linkage_name, .strp },
2352 .{ .type, .ref_addr },2404 .{ .type, .ref_addr },
2353 .{ .low_pc, .addr },2405 .{ .low_pc, .addr },
...@@ -2358,7 +2410,7 @@ pub const AbbrevCode = enum {...@@ -2358,7 +2410,7 @@ pub const AbbrevCode = enum {
2358 .decl_extern_func = .{2410 .decl_extern_func = .{
2359 .tag = .subprogram,2411 .tag = .subprogram,
2360 .children = true,2412 .children = true,
2361 .attrs = decl_abbrev_common_attrs ++ .{2413 .attrs = decl_attrs ++ .{
2362 .{ .linkage_name, .strp },2414 .{ .linkage_name, .strp },
2363 .{ .type, .ref_addr },2415 .{ .type, .ref_addr },
2364 .{ .low_pc, .addr },2416 .{ .low_pc, .addr },
...@@ -2366,47 +2418,47 @@ pub const AbbrevCode = enum {...@@ -2366,47 +2418,47 @@ pub const AbbrevCode = enum {
2366 .{ .noreturn, .flag },2418 .{ .noreturn, .flag },
2367 },2419 },
2368 },2420 },
2369 .generic_decl_var = .{2421 .decl_specification_struct = .{
2370 .tag = .variable,2422 .tag = .variable,
2371 .attrs = generic_decl_abbrev_common_attrs,2423 .attrs = decl_specification_attrs,
2372 },2424 },
2373 .generic_decl_const = .{2425 .decl_specification_union = .{
2374 .tag = .constant,2426 .tag = .constant,
2375 .attrs = generic_decl_abbrev_common_attrs,2427 .attrs = decl_specification_attrs,
2376 },2428 },
2377 .generic_decl_func = .{2429 .decl_specification_func = .{
2378 .tag = .subprogram,2430 .tag = .subprogram,
2379 .attrs = generic_decl_abbrev_common_attrs,2431 .attrs = decl_specification_attrs,
2380 },2432 },
2381 .decl_instance_alias = .{2433 .decl_instance_alias = .{
2382 .tag = .imported_declaration,2434 .tag = .imported_declaration,
2383 .attrs = decl_instance_abbrev_common_attrs ++ .{2435 .attrs = decl_instance_attrs ++ .{
2384 .{ .import, .ref_addr },2436 .{ .import, .ref_addr },
2385 },2437 },
2386 },2438 },
2387 .decl_instance_empty_enum = .{2439 .decl_instance_empty_enum = .{
2388 .tag = .enumeration_type,2440 .tag = .enumeration_type,
2389 .attrs = decl_instance_abbrev_common_attrs ++ .{2441 .attrs = decl_instance_attrs ++ .{
2390 .{ .type, .ref_addr },2442 .{ .type, .ref_addr },
2391 },2443 },
2392 },2444 },
2393 .decl_instance_enum = .{2445 .decl_instance_enum = .{
2394 .tag = .enumeration_type,2446 .tag = .enumeration_type,
2395 .children = true,2447 .children = true,
2396 .attrs = decl_instance_abbrev_common_attrs ++ .{2448 .attrs = decl_instance_attrs ++ .{
2397 .{ .type, .ref_addr },2449 .{ .type, .ref_addr },
2398 },2450 },
2399 },2451 },
2400 .decl_instance_namespace_struct = .{2452 .decl_instance_namespace_struct = .{
2401 .tag = .structure_type,2453 .tag = .structure_type,
2402 .attrs = decl_instance_abbrev_common_attrs ++ .{2454 .attrs = decl_instance_attrs ++ .{
2403 .{ .declaration, .flag },2455 .{ .declaration, .flag },
2404 },2456 },
2405 },2457 },
2406 .decl_instance_struct = .{2458 .decl_instance_struct = .{
2407 .tag = .structure_type,2459 .tag = .structure_type,
2408 .children = true,2460 .children = true,
2409 .attrs = decl_instance_abbrev_common_attrs ++ .{2461 .attrs = decl_instance_attrs ++ .{
2410 .{ .byte_size, .udata },2462 .{ .byte_size, .udata },
2411 .{ .alignment, .udata },2463 .{ .alignment, .udata },
2412 },2464 },
...@@ -2414,14 +2466,14 @@ pub const AbbrevCode = enum {...@@ -2414,14 +2466,14 @@ pub const AbbrevCode = enum {
2414 .decl_instance_packed_struct = .{2466 .decl_instance_packed_struct = .{
2415 .tag = .structure_type,2467 .tag = .structure_type,
2416 .children = true,2468 .children = true,
2417 .attrs = decl_instance_abbrev_common_attrs ++ .{2469 .attrs = decl_instance_attrs ++ .{
2418 .{ .type, .ref_addr },2470 .{ .type, .ref_addr },
2419 },2471 },
2420 },2472 },
2421 .decl_instance_union = .{2473 .decl_instance_union = .{
2422 .tag = .union_type,2474 .tag = .union_type,
2423 .children = true,2475 .children = true,
2424 .attrs = decl_instance_abbrev_common_attrs ++ .{2476 .attrs = decl_instance_attrs ++ .{
2425 .{ .byte_size, .udata },2477 .{ .byte_size, .udata },
2426 .{ .alignment, .udata },2478 .{ .alignment, .udata },
2427 },2479 },
...@@ -2429,13 +2481,13 @@ pub const AbbrevCode = enum {...@@ -2429,13 +2481,13 @@ pub const AbbrevCode = enum {
2429 .decl_instance_packed_union = .{2481 .decl_instance_packed_union = .{
2430 .tag = .union_type,2482 .tag = .union_type,
2431 .children = true,2483 .children = true,
2432 .attrs = decl_instance_abbrev_common_attrs ++ .{2484 .attrs = decl_instance_attrs ++ .{
2433 .{ .type, .ref_addr },2485 .{ .type, .ref_addr },
2434 },2486 },
2435 },2487 },
2436 .decl_instance_var = .{2488 .decl_instance_var = .{
2437 .tag = .variable,2489 .tag = .variable,
2438 .attrs = decl_instance_abbrev_common_attrs ++ .{2490 .attrs = decl_instance_attrs ++ .{
2439 .{ .linkage_name, .strp },2491 .{ .linkage_name, .strp },
2440 .{ .type, .ref_addr },2492 .{ .type, .ref_addr },
2441 .{ .location, .exprloc },2493 .{ .location, .exprloc },
...@@ -2445,7 +2497,7 @@ pub const AbbrevCode = enum {...@@ -2445,7 +2497,7 @@ pub const AbbrevCode = enum {
2445 },2497 },
2446 .decl_instance_const = .{2498 .decl_instance_const = .{
2447 .tag = .constant,2499 .tag = .constant,
2448 .attrs = decl_instance_abbrev_common_attrs ++ .{2500 .attrs = decl_instance_attrs ++ .{
2449 .{ .linkage_name, .strp },2501 .{ .linkage_name, .strp },
2450 .{ .type, .ref_addr },2502 .{ .type, .ref_addr },
2451 .{ .alignment, .udata },2503 .{ .alignment, .udata },
...@@ -2454,7 +2506,7 @@ pub const AbbrevCode = enum {...@@ -2454,7 +2506,7 @@ pub const AbbrevCode = enum {
2454 },2506 },
2455 .decl_instance_const_runtime_bits = .{2507 .decl_instance_const_runtime_bits = .{
2456 .tag = .constant,2508 .tag = .constant,
2457 .attrs = decl_instance_abbrev_common_attrs ++ .{2509 .attrs = decl_instance_attrs ++ .{
2458 .{ .linkage_name, .strp },2510 .{ .linkage_name, .strp },
2459 .{ .type, .ref_addr },2511 .{ .type, .ref_addr },
2460 .{ .alignment, .udata },2512 .{ .alignment, .udata },
...@@ -2464,7 +2516,7 @@ pub const AbbrevCode = enum {...@@ -2464,7 +2516,7 @@ pub const AbbrevCode = enum {
2464 },2516 },
2465 .decl_instance_const_comptime_state = .{2517 .decl_instance_const_comptime_state = .{
2466 .tag = .constant,2518 .tag = .constant,
2467 .attrs = decl_instance_abbrev_common_attrs ++ .{2519 .attrs = decl_instance_attrs ++ .{
2468 .{ .linkage_name, .strp },2520 .{ .linkage_name, .strp },
2469 .{ .type, .ref_addr },2521 .{ .type, .ref_addr },
2470 .{ .alignment, .udata },2522 .{ .alignment, .udata },
...@@ -2474,7 +2526,7 @@ pub const AbbrevCode = enum {...@@ -2474,7 +2526,7 @@ pub const AbbrevCode = enum {
2474 },2526 },
2475 .decl_instance_const_runtime_bits_comptime_state = .{2527 .decl_instance_const_runtime_bits_comptime_state = .{
2476 .tag = .constant,2528 .tag = .constant,
2477 .attrs = decl_instance_abbrev_common_attrs ++ .{2529 .attrs = decl_instance_attrs ++ .{
2478 .{ .linkage_name, .strp },2530 .{ .linkage_name, .strp },
2479 .{ .type, .ref_addr },2531 .{ .type, .ref_addr },
2480 .{ .alignment, .udata },2532 .{ .alignment, .udata },
...@@ -2485,7 +2537,7 @@ pub const AbbrevCode = enum {...@@ -2485,7 +2537,7 @@ pub const AbbrevCode = enum {
2485 },2537 },
2486 .decl_instance_nullary_func = .{2538 .decl_instance_nullary_func = .{
2487 .tag = .subprogram,2539 .tag = .subprogram,
2488 .attrs = decl_instance_abbrev_common_attrs ++ .{2540 .attrs = decl_instance_attrs ++ .{
2489 .{ .linkage_name, .strp },2541 .{ .linkage_name, .strp },
2490 .{ .type, .ref_addr },2542 .{ .type, .ref_addr },
2491 .{ .low_pc, .addr },2543 .{ .low_pc, .addr },
...@@ -2498,7 +2550,7 @@ pub const AbbrevCode = enum {...@@ -2498,7 +2550,7 @@ pub const AbbrevCode = enum {
2498 .decl_instance_func = .{2550 .decl_instance_func = .{
2499 .tag = .subprogram,2551 .tag = .subprogram,
2500 .children = true,2552 .children = true,
2501 .attrs = decl_instance_abbrev_common_attrs ++ .{2553 .attrs = decl_instance_attrs ++ .{
2502 .{ .linkage_name, .strp },2554 .{ .linkage_name, .strp },
2503 .{ .type, .ref_addr },2555 .{ .type, .ref_addr },
2504 .{ .low_pc, .addr },2556 .{ .low_pc, .addr },
...@@ -2510,20 +2562,20 @@ pub const AbbrevCode = enum {...@@ -2510,20 +2562,20 @@ pub const AbbrevCode = enum {
2510 },2562 },
2511 .decl_instance_nullary_func_generic = .{2563 .decl_instance_nullary_func_generic = .{
2512 .tag = .subprogram,2564 .tag = .subprogram,
2513 .attrs = decl_instance_abbrev_common_attrs ++ .{2565 .attrs = decl_instance_attrs ++ .{
2514 .{ .type, .ref_addr },2566 .{ .type, .ref_addr },
2515 },2567 },
2516 },2568 },
2517 .decl_instance_func_generic = .{2569 .decl_instance_func_generic = .{
2518 .tag = .subprogram,2570 .tag = .subprogram,
2519 .children = true,2571 .children = true,
2520 .attrs = decl_instance_abbrev_common_attrs ++ .{2572 .attrs = decl_instance_attrs ++ .{
2521 .{ .type, .ref_addr },2573 .{ .type, .ref_addr },
2522 },2574 },
2523 },2575 },
2524 .decl_instance_extern_nullary_func = .{2576 .decl_instance_extern_nullary_func = .{
2525 .tag = .subprogram,2577 .tag = .subprogram,
2526 .attrs = decl_instance_abbrev_common_attrs ++ .{2578 .attrs = decl_instance_attrs ++ .{
2527 .{ .linkage_name, .strp },2579 .{ .linkage_name, .strp },
2528 .{ .type, .ref_addr },2580 .{ .type, .ref_addr },
2529 .{ .low_pc, .addr },2581 .{ .low_pc, .addr },
...@@ -2534,7 +2586,7 @@ pub const AbbrevCode = enum {...@@ -2534,7 +2586,7 @@ pub const AbbrevCode = enum {
2534 .decl_instance_extern_func = .{2586 .decl_instance_extern_func = .{
2535 .tag = .subprogram,2587 .tag = .subprogram,
2536 .children = true,2588 .children = true,
2537 .attrs = decl_instance_abbrev_common_attrs ++ .{2589 .attrs = decl_instance_attrs ++ .{
2538 .{ .linkage_name, .strp },2590 .{ .linkage_name, .strp },
2539 .{ .type, .ref_addr },2591 .{ .type, .ref_addr },
2540 .{ .low_pc, .addr },2592 .{ .low_pc, .addr },
src/link/Elf.zig+2-2
...@@ -1688,8 +1688,8 @@ pub fn updateExports(...@@ -1688,8 +1688,8 @@ pub fn updateExports(
1688 return self.zigObjectPtr().?.updateExports(self, pt, export_indices);1688 return self.zigObjectPtr().?.updateExports(self, pt, export_indices);
1689}1689}
16901690
1691pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {1691pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, inst: InternPool.TrackedInst.Index, line: u32) link.Error!void {
1692 return self.zigObjectPtr().?.updateLineNumber(pt, ti_id);1692 return self.zigObjectPtr().?.updateLineNumber(pt, inst, line);
1693}1693}
16941694
1695fn checkDuplicates(self: *Elf) !void {1695fn checkDuplicates(self: *Elf) !void {
src/link/Elf/ZigObject.zig+2-2
...@@ -1946,11 +1946,11 @@ pub fn updateExports(...@@ -1946,11 +1946,11 @@ pub fn updateExports(
1946 }1946 }
1947}1947}
19481948
1949pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {1949pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index, line: u32) link.Error!void {
1950 if (self.dwarf) |*dwarf| {1950 if (self.dwarf) |*dwarf| {
1951 const comp = dwarf.bin_file.comp;1951 const comp = dwarf.bin_file.comp;
1952 const diags = &comp.link_diags;1952 const diags = &comp.link_diags;
1953 dwarf.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) {1953 dwarf.updateLineNumber(pt.zcu, ti_id, line) catch |err| switch (err) {
1954 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,1954 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
1955 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),1955 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),
1956 };1956 };
src/link/Elf2.zig+189-110
...@@ -501,7 +501,7 @@ const Section = struct {...@@ -501,7 +501,7 @@ const Section = struct {
501 ni: MappedFile.Node.Index,501 ni: MappedFile.Node.Index,
502 /// A symbol which is exactly at the start of this section.502 /// A symbol which is exactly at the start of this section.
503 ///503 ///
504 /// If the section does not have flag `std.elf.SHF.ALLOC`, this is `.null`.504 /// When not emitting a relocatable, or for special section types, this is `.null`.
505 lsi: Symbol.LocalIndex,505 lsi: Symbol.LocalIndex,
506 rela: union {506 rela: union {
507 /// This field is active if and only if this section is *not* a `SHT_RELA` section.507 /// This field is active if and only if this section is *not* a `SHT_RELA` section.
...@@ -848,10 +848,10 @@ const Section = struct {...@@ -848,10 +848,10 @@ const Section = struct {
848 }848 }
849 }849 }
850850
851 /// Asserts that `rela_shndx` is a `SHT_RELA` section, and asserts that `index` refers to an851 /// Asserts that `rela_shndx` is a `SHT_RELA` section and updates the `addend` field of the
852 /// `R_*_RELATIVE` relocation inside of it; then, updates that relocation's addend (which is852 /// `ElfN.Rela` entry at the given index. Asserts that `index` is not in the free-list (i.e.
853 /// an address in this DSO without the runtime load offset applied) to the given value.853 /// it is not deleted).
854 fn relaSetRelativeOffset(rela_shndx: Index, elf: *Elf, index: RelaIndex, new_addend: u64) void {854 fn relaSetAddend(rela_shndx: Index, elf: *Elf, index: RelaIndex, new_addend: u64) void {
855 switch (elf.shdrPtr(rela_shndx)) {855 switch (elf.shdrPtr(rela_shndx)) {
856 inline else => |shdr, class| {856 inline else => |shdr, class| {
857 assert(elf.targetLoad(&shdr.type) == .RELA);857 assert(elf.targetLoad(&shdr.type) == .RELA);
...@@ -1603,6 +1603,20 @@ const SymbolReloc = struct {...@@ -1603,6 +1603,20 @@ const SymbolReloc = struct {
1603 }1603 }
1604 };1604 };
16051605
1606 fn flushMovedNode(reloc: *SymbolReloc, elf: *Elf, node_vaddr: u64) void {
1607 if (reloc.rela_index.unwrap()) |rela_index| {
1608 // The node has moved, so the offset of the relocation within the section might have
1609 // changed, so update the `offset` field of the `ElfN.Rela` entry.
1610 reloc.relaSection(elf).relaSetOffset(elf, rela_index, node_vaddr + reloc.offset);
1611 }
1612 // This is not just the inverse of the above condition, because if `reloc` is relative
1613 // to the base of this DSO, then `rela_index` is an `R_*_RELATIVE` relocation, but we
1614 // still need to call `SymbolReloc.apply` to update that relocation's addend.
1615 if (elf.ehdrType() != .REL) {
1616 reloc.apply(elf);
1617 }
1618 }
1619
1606 fn apply(reloc: *SymbolReloc, elf: *Elf) void {1620 fn apply(reloc: *SymbolReloc, elf: *Elf) void {
1607 assert(elf.ehdrType() != .REL);1621 assert(elf.ehdrType() != .REL);
1608 if (reloc.node.hasMoved(&elf.mf) or reloc.target.hasMoved(elf)) {1622 if (reloc.node.hasMoved(&elf.mf) or reloc.target.hasMoved(elf)) {
...@@ -1688,7 +1702,7 @@ const SymbolReloc = struct {...@@ -1688,7 +1702,7 @@ const SymbolReloc = struct {
1688 }1702 }
1689 assert(reloc.type.action.simple.cast == .unsigned);1703 assert(reloc.type.action.simple.cast == .unsigned);
1690 assert(reloc.type.action.simple.shift == .@"0");1704 assert(reloc.type.action.simple.shift == .@"0");
1691 elf.shndx.rela_dyn.relaSetRelativeOffset(elf, rela_index, target_val);1705 elf.shndx.rela_dyn.relaSetAddend(elf, rela_index, target_val);
1692 return;1706 return;
1693 },1707 },
1694 };1708 };
...@@ -1767,30 +1781,58 @@ const NodeReloc = struct {...@@ -1767,30 +1781,58 @@ const NodeReloc = struct {
1767 }1781 }
1768 };1782 };
17691783
1770 fn apply(reloc: *NodeReloc, elf: *Elf) void {1784 fn flushMovedNode(reloc: *NodeReloc, elf: *Elf, node_vaddr: u64) void {
1771 assert(elf.ehdrType() != .REL);1785 if (reloc.rela_index.unwrap()) |rela_index| {
1772 if (reloc.node.hasMoved(&elf.mf) or reloc.target.hasMoved(&elf.mf)) {1786 assert(elf.ehdrType() == .REL);
1773 // There's no point applying the relocation now, because it will be re-applied by1787 // The node has moved, so the offset of the relocation within the section might have
1774 // `flushMoved` at some point anyway.1788 // changed, so update the `offset` field of the `ElfN.Rela` entry.
1775 return;1789 elf.getNodeShndx(reloc.node).get(elf).rela.shndx.relaSetOffset(elf, rela_index, node_vaddr + reloc.offset);
1790 } else {
1791 assert(elf.ehdrType() != .REL);
1792 reloc.apply(elf);
1776 }1793 }
1777 switch (reloc.result) {1794 }
1778 .ok => {},1795
1779 .overflowed => elf.overflowed_reloc_count -= 1,1796 fn flushMovedTarget(reloc: *NodeReloc, elf: *Elf, target_section_offset: u64) void {
1780 .misaligned => elf.misaligned_reloc_count -= 1,1797 if (reloc.rela_index.unwrap()) |rela_index| {
1798 assert(elf.ehdrType() == .REL);
1799 // The target has moved, so the `addend` field of the `ElfN.Rela` entry needs to be updated.
1800 elf.getNodeShndx(reloc.node).get(elf).rela.shndx.relaSetAddend(elf, rela_index, target_section_offset +% @as(u64, @bitCast(reloc.addend)));
1801 } else {
1802 assert(elf.ehdrType() != .REL);
1803 reloc.apply(elf);
1781 }1804 }
1782 if (reloc.applyInner(elf)) {1805 }
1783 @branchHint(.likely);1806
1784 reloc.result = .ok;1807 fn apply(reloc: *NodeReloc, elf: *Elf) void {
1785 } else |err| switch (err) {1808 if (reloc.rela_index.unwrap()) |rela_index| {
1786 error.RelocationOverflow => {1809 assert(elf.ehdrType() == .REL);
1787 reloc.result = .overflowed;1810 _ = rela_index;
1788 elf.overflowed_reloc_count += 1;1811 } else {
1789 },1812 assert(elf.ehdrType() != .REL);
1790 error.RelocationMisaligned => {1813 if (reloc.node.hasMoved(&elf.mf) or reloc.target.hasMoved(&elf.mf)) {
1791 reloc.result = .misaligned;1814 // There's no point applying the relocation now, because it will be re-applied by
1792 elf.misaligned_reloc_count += 1;1815 // `flushMoved` at some point anyway.
1793 },1816 return;
1817 }
1818 switch (reloc.result) {
1819 .ok => {},
1820 .overflowed => elf.overflowed_reloc_count -= 1,
1821 .misaligned => elf.misaligned_reloc_count -= 1,
1822 }
1823 if (reloc.applyInner(elf)) {
1824 @branchHint(.likely);
1825 reloc.result = .ok;
1826 } else |err| switch (err) {
1827 error.RelocationOverflow => {
1828 reloc.result = .overflowed;
1829 elf.overflowed_reloc_count += 1;
1830 },
1831 error.RelocationMisaligned => {
1832 reloc.result = .misaligned;
1833 elf.misaligned_reloc_count += 1;
1834 },
1835 }
1794 }1836 }
1795 }1837 }
1796 fn applyInner(reloc: *const NodeReloc, elf: *Elf) error{ RelocationOverflow, RelocationMisaligned }!void {1838 fn applyInner(reloc: *const NodeReloc, elf: *Elf) error{ RelocationOverflow, RelocationMisaligned }!void {
...@@ -5220,7 +5262,42 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5220,7 +5262,42 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5220 const offset, _ = ni.location(&elf.mf).resolve(&elf.mf);5262 const offset, _ = ni.location(&elf.mf).resolve(&elf.mf);
5221 return parent_vaddr + offset;5263 return parent_vaddr + offset;
5222}5264}
5223fn getNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {5265fn computeNodeSectionOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5266 const parent_ni = ni.parent(&elf.mf).unwrap().?;
5267 const parent_section_offset = parent_section_offset: switch (elf.getNode(parent_ni)) {
5268 .deleted,
5269 .archive,
5270 .archive_header,
5271 .archive_input_member,
5272 .archive_elf_member_header,
5273 .elf,
5274 .ehdr,
5275 .shdr,
5276 .segment,
5277 => unreachable,
5278 .section, .section_manual_size => 0,
5279 .input_section, .copied_global => unreachable,
5280 .nav, .uav, .lazy_code, .lazy_const_data => unreachable,
5281 .debug_shared, .unit_padding => unreachable,
5282 .unit_frame, .unit_debug_info, .unit_debug_line => {
5283 const parent_section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
5284 break :parent_section_offset parent_section_offset;
5285 },
5286 .unit_frame_cie,
5287 .unit_debug_info_header,
5288 .unit_debug_line_header,
5289 .unit_debug_rnglists,
5290 .value_debug_info,
5291 .global_debug_info,
5292 .func_frame_fde,
5293 .func_debug_info,
5294 .func_debug_line,
5295 => unreachable,
5296 };
5297 const offset, _ = ni.location(&elf.mf).resolve(&elf.mf);
5298 return parent_section_offset + offset;
5299}
5300fn computeNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5224 return ni.fileLocation(&elf.mf, false).offset - elf.ni.elf.fileLocation(&elf.mf, false).offset;5301 return ni.fileLocation(&elf.mf, false).offset - elf.ni.elf.fileLocation(&elf.mf, false).offset;
5225}5302}
52265303
...@@ -5293,8 +5370,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5293,8 +5370,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5293 },5370 },
5294 .func_debug_info => |fi| .{5371 .func_debug_info => |fi| .{
5295 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc,5372 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc,
5296 .skip_symbol_relocs = if (elf.navs.getPtr(fi.get(&elf.dwarf).owner_nav)) |owner_nav|5373 .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav|
5297 owner_nav.lsi.index().ptr(elf).node5374 nav.lsi.index().ptr(elf).node
5298 else5375 else
5299 .none,5376 .none,
5300 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc,5377 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc,
...@@ -5358,17 +5435,7 @@ fn flushMovedNodeRelocs(...@@ -5358,17 +5435,7 @@ fn flushMovedNodeRelocs(
5358 for (elf.symbol_relocs.items[@backingInt(opts.first_symbol_reloc)..]) |*reloc| {5435 for (elf.symbol_relocs.items[@backingInt(opts.first_symbol_reloc)..]) |*reloc| {
5359 if (reloc.node.toOptional() == opts.skip_symbol_relocs) continue;5436 if (reloc.node.toOptional() == opts.skip_symbol_relocs) continue;
5360 if (reloc.node != node) break;5437 if (reloc.node != node) break;
5361 if (reloc.rela_index.unwrap()) |rela_index| {5438 reloc.flushMovedNode(elf, node_vaddr);
5362 // The node has moved, so the offset of the relocation within the section might have
5363 // changed, so update the `offset` field of the `ElfN.Rela` entry.
5364 reloc.relaSection(elf).relaSetOffset(elf, rela_index, node_vaddr + reloc.offset);
5365 }
5366 // This is not just the inverse of the above condition, because if `reloc` is relative
5367 // to the base of this DSO, then `rela_index` is an `R_*_RELATIVE` relocation, but we
5368 // still need to call `SymbolReloc.apply` to update that relocation's addend.
5369 if (elf.ehdrType() != .REL) {
5370 reloc.apply(elf);
5371 }
5372 }5439 }
5373 }5440 }
53745441
...@@ -5376,15 +5443,7 @@ fn flushMovedNodeRelocs(...@@ -5376,15 +5443,7 @@ fn flushMovedNodeRelocs(
5376 for (elf.node_relocs.items[@backingInt(opts.first_node_reloc)..]) |*reloc| {5443 for (elf.node_relocs.items[@backingInt(opts.first_node_reloc)..]) |*reloc| {
5377 if (reloc.node.toOptional() == opts.skip_node_relocs) continue;5444 if (reloc.node.toOptional() == opts.skip_node_relocs) continue;
5378 if (reloc.node != node) break;5445 if (reloc.node != node) break;
5379 if (reloc.rela_index.unwrap()) |rela_index| {5446 reloc.flushMovedNode(elf, node_vaddr);
5380 assert(elf.ehdrType() == .REL);
5381 // The node has moved, so the offset of the relocation within the section might have
5382 // changed, so update the `offset` field of the `ElfN.Rela` entry.
5383 elf.getNodeShndx(reloc.node).get(elf).rela.shndx.relaSetOffset(elf, rela_index, node_vaddr + reloc.offset);
5384 } else {
5385 assert(elf.ehdrType() != .REL);
5386 reloc.apply(elf);
5387 }
5388 }5447 }
5389 }5448 }
53905449
...@@ -7113,7 +7172,7 @@ pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void {...@@ -7113,7 +7172,7 @@ pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void {
7113fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {7172fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7114 const gpa = zcu.gpa;7173 const gpa = zcu.gpa;
71157174
7116 try elf.dwarf.initUnits(zcu);7175 try elf.dwarf.updateUnits(zcu);
7117 const old_units_len = elf.dwarf_units.items.len;7176 const old_units_len = elf.dwarf_units.items.len;
7118 const new_units_len = elf.dwarf.units.count();7177 const new_units_len = elf.dwarf.units.count();
7119 try elf.dwarf_units.appendNTimes(gpa, .{7178 try elf.dwarf_units.appendNTimes(gpa, .{
...@@ -7204,11 +7263,11 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {...@@ -7204,11 +7263,11 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7204 defer dih_nw.deinit();7263 defer dih_nw.deinit();
7205 elf.resetNodeRelocs(debug_info_header_ni);7264 elf.resetNodeRelocs(debug_info_header_ni);
7206 elf.dwarf.genDebugInfoHeader(7265 elf.dwarf.genDebugInfoHeader(
7266 zcu,
7207 mod,7267 mod,
7208 unit,7268 unit,
7209 &dih_nw,7269 &dih_nw,
7210 debug_rnglists_offsets_table_offset,7270 debug_rnglists_offsets_table_offset,
7211 zcu,
7212 ) catch |err| switch (err) {7271 ) catch |err| switch (err) {
7213 else => |e| return e,7272 else => |e| return e,
7214 error.WriteFailed => return dih_nw.err.?,7273 error.WriteFailed => return dih_nw.err.?,
...@@ -7397,7 +7456,11 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {...@@ -7397,7 +7456,11 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
7397 const gpa = elf.base.comp.gpa;7456 const gpa = elf.base.comp.gpa;
7398 try elf.nodes.ensureUnusedCapacity(gpa, 1);7457 try elf.nodes.ensureUnusedCapacity(gpa, 1);
7399 try elf.shdrs.ensureUnusedCapacity(gpa, 1);7458 try elf.shdrs.ensureUnusedCapacity(gpa, 1);
7400 if (opts.flags.ALLOC) try elf.ensureUnusedSymbolCapacity(1, .all_local);7459 const want_symbol = opts.flags.ALLOC or switch (opts.type) {
7460 .NULL, .PROGBITS, .NOBITS, .X86_64_UNWIND => elf.ehdrType() == .REL,
7461 else => false,
7462 };
7463 if (want_symbol) try elf.ensureUnusedSymbolCapacity(1, .all_local);
74017464
7402 const shstrtab_entry = try elf.string(.shstrtab, opts.name);7465 const shstrtab_entry = try elf.string(.shstrtab, opts.name);
7403 const shndx: Section.Index, const new_shdr_size = shndx: switch (elf.ehdrPtr()) {7466 const shndx: Section.Index, const new_shdr_size = shndx: switch (elf.ehdrPtr()) {
...@@ -7443,19 +7506,22 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {...@@ -7443,19 +7506,22 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
7443 true => .{ .section_manual_size = shndx },7506 true => .{ .section_manual_size = shndx },
7444 });7507 });
7445 const addr = elf.computeNodeVAddr(ni);7508 const addr = elf.computeNodeVAddr(ni);
7446 const lsi: Symbol.LocalIndex = if (opts.flags.ALLOC) elf.addLocalSymbolAssumeCapacity(.{7509 elf.shdrs.appendAssumeCapacity(.{
7447 .node = .wrap(ni),7510 .lsi = if (want_symbol) elf.addLocalSymbolAssumeCapacity(.{
7448 .name = .empty,7511 .node = ni.toOptional(),
7449 .value = addr,7512 .name = .empty,
7450 .size = 0,7513 .value = addr,
7451 .type = .SECTION,7514 .size = 0,
7452 .shndx = shndx,7515 .type = .SECTION,
7453 }) else .null;7516 .shndx = shndx,
7454 elf.shdrs.appendAssumeCapacity(.{ .lsi = lsi, .ni = ni, .rela = switch (opts.type) {7517 }) else .null,
7455 .REL => unreachable,7518 .ni = ni,
7456 .RELA => .{ .free_head = .none },7519 .rela = switch (opts.type) {
7457 else => .{ .shndx = .UNDEF },7520 .REL => unreachable,
7458 } });7521 .RELA => .{ .free_head = .none },
7522 else => .{ .shndx = .UNDEF },
7523 },
7524 });
7459 switch (elf.shdrPtr(shndx)) {7525 switch (elf.shdrPtr(shndx)) {
7460 inline else => |shdr, class| {7526 inline else => |shdr, class| {
7461 shdr.* = .{7527 shdr.* = .{
...@@ -7463,7 +7529,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {...@@ -7463,7 +7529,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
7463 .type = opts.type,7529 .type = opts.type,
7464 .flags = .{ .shf = opts.flags },7530 .flags = .{ .shf = opts.flags },
7465 .addr = @intCast(addr),7531 .addr = @intCast(addr),
7466 .offset = @intCast(elf.getNodeElfOffset(ni)),7532 .offset = @intCast(elf.computeNodeElfOffset(ni)),
7467 .size = @intCast(opts.size),7533 .size = @intCast(opts.size),
7468 .link = opts.link,7534 .link = opts.link,
7469 .info = opts.info,7535 .info = opts.info,
...@@ -8068,7 +8134,7 @@ fn addNodeRelocAssumeCapacity(...@@ -8068,7 +8134,7 @@ fn addNodeRelocAssumeCapacity(
8068 .abs32 => .UA32,8134 .abs32 => .UA32,
8069 .abs64 => .UA64,8135 .abs64 => .UA64,
8070 } },8136 } },
8071 .X86_64 => .{ .SPARC = switch (@"type") {8137 .X86_64 => .{ .X86_64 = switch (@"type") {
8072 .abs32 => .@"32",8138 .abs32 => .@"32",
8073 .abs64 => .@"64",8139 .abs64 => .@"64",
8074 } },8140 } },
...@@ -8078,8 +8144,11 @@ fn addNodeRelocAssumeCapacity(...@@ -8078,8 +8144,11 @@ fn addNodeRelocAssumeCapacity(
8078 // the section offset now, but there's no point, because `flushMovedNodeRelocs` will8144 // the section offset now, but there's no point, because `flushMovedNodeRelocs` will
8079 // eventually do it for us anyway, so just init to 0.8145 // eventually do it for us anyway, so just init to 0.
8080 .offset = 0,8146 .offset = 0,
8081 .raw_sym_index = @backingInt(shndx.get(elf).lsi.index()),8147 .raw_sym_index = @backingInt(switch (shndx.get(elf).lsi) {
8082 .addend = addend,8148 .null => unreachable,
8149 else => |lsi| lsi.index(),
8150 }),
8151 .addend = 0,
8083 });8152 });
8084 elf.node_relocs.appendAssumeCapacity(.{8153 elf.node_relocs.appendAssumeCapacity(.{
8085 .node = node,8154 .node = node,
...@@ -8576,7 +8645,8 @@ fn updateFuncInner(...@@ -8576,7 +8645,8 @@ fn updateFuncInner(
8576 const debug_output: link.File.DebugInfoOutput, const dwarf_func = debug_output: {8645 const debug_output: link.File.DebugInfoOutput, const dwarf_func = debug_output: {
8577 if (elf.ehdrMachine() != .X86_64) break :debug_output .{ .none, undefined };8646 if (elf.ehdrMachine() != .X86_64) break :debug_output .{ .none, undefined };
8578 const dwarf = &elf.dwarf;8647 const dwarf = &elf.dwarf;
8579 const mod = zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?;8648 const src_inst = nav.srcInst(ip);
8649 const mod = zcu.fileByIndex(src_inst.resolveFile(ip)).mod.?;
8580 if (mod.strip and mod.unwind_tables == .none) break :debug_output .{ .none, undefined };8650 if (mod.strip and mod.unwind_tables == .none) break :debug_output .{ .none, undefined };
85818651
8582 try elf.nodes.ensureUnusedCapacity(gpa, 4);8652 try elf.nodes.ensureUnusedCapacity(gpa, 4);
...@@ -8662,6 +8732,7 @@ fn updateFuncInner(...@@ -8662,6 +8732,7 @@ fn updateFuncInner(
8662 debug.blocks = .empty;8732 debug.blocks = .empty;
86638733
8664 const debug_info_ni = dwarf_func.debug_info_ni.unwrap().?;8734 const debug_info_ni = dwarf_func.debug_info_ni.unwrap().?;
8735 try dwarf.decls.put(zcu.comp.gpa, src_inst, debug_info_ni);
8665 try debug_info_ni.moved(gpa, &elf.mf);8736 try debug_info_ni.moved(gpa, &elf.mf);
8666 try debug_info_ni.nextMoved(gpa, &elf.mf);8737 try debug_info_ni.nextMoved(gpa, &elf.mf);
8667 debug_info_ni.writer(gpa, &elf.mf, &debug.info_writer);8738 debug_info_ni.writer(gpa, &elf.mf, &debug.info_writer);
...@@ -8787,23 +8858,31 @@ fn updateFuncInner(...@@ -8787,23 +8858,31 @@ fn updateFuncInner(
8787 try elf.genPending(pt);8858 try elf.genPending(pt);
8788}8859}
87898860
8790pub fn updateLineNumber(elf: *Elf, pt: Zcu.PerThread, src_inst: InternPool.TrackedInst.Index) void {8861pub fn updateLineNumber(
8791 const func = elf.dwarf.funcs.getPtr(src_inst) orelse return;8862 elf: *Elf,
8792 elf.dwarf.updateLineNumber(pt.zcu, src_inst, func.debug_info_ni.unwrap().?.slice(&elf.mf));8863 _: Zcu.PerThread,
8864 inst: InternPool.TrackedInst.Index,
8865 line: u32,
8866) void {
8867 elf.dwarf.updateLineNumber(&elf.mf, inst, line);
8793}8868}
87948869
8795pub fn lostTracking(8870pub fn lostTracking(
8796 elf: *Elf,8871 elf: *Elf,
8797 _: Zcu.PerThread,8872 _: Zcu.PerThread,
8798 src_inst: InternPool.TrackedInst.Index,8873 inst: InternPool.TrackedInst.Index,
8799) std.mem.Allocator.Error!void {8874) link.Error!void {
8800 const func = elf.dwarf.funcs.getPtr(src_inst) orelse return;8875 const decl_ni = elf.dwarf.decls.get(inst) orelse return;
8801 elf.resetNodeRelocs(func.fde_ni.unwrap().?);8876 const comp = elf.base.comp;
8802 elf.resetNodeRelocs(func.debug_info_ni.unwrap().?);8877 var diw: std.Io.Writer = .fixed(decl_ni.slice(&elf.mf));
8803 elf.resetNodeRelocs(func.debug_line_ni.unwrap().?);8878 elf.resetNodeRelocs(decl_ni);
8804 try elf.deleteNode(&func.fde_ni);8879 diw.writeUleb128(try elf.dwarf.refAbbrevCode(.decl_lost)) catch unreachable;
8805 try elf.deleteNode(&func.debug_info_ni);8880 decl_ni.resizeLeaf(comp.gpa, &elf.mf, diw.end) catch |err| switch (err) {
8806 try elf.deleteNode(&func.debug_line_ni);8881 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
8882 elf.mf.io_err.?,
8883 }),
8884 else => |e| return e,
8885 };
8807}8886}
88088887
8809pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {8888pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
...@@ -9127,7 +9206,7 @@ fn idleProgNode(...@@ -9127,7 +9206,7 @@ fn idleProgNode(
9127 .func_debug_info => "debug",9206 .func_debug_info => "debug",
9128 .func_debug_line => "line",9207 .func_debug_line => "line",
9129 },9208 },
9130 ip.getNav(fi.get(&elf.dwarf).owner_nav).fqn.fmt(ip),9209 ip.getNav(fi.nav(&elf.dwarf)).fqn.fmt(ip),
9131 }) catch &name;9210 }) catch &name;
9132 },9211 },
9133 }, 0);9212 }, 0);
...@@ -9304,7 +9383,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {...@@ -9304,7 +9383,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {
9304}9383}
93059384
9306fn flushElfOffset(elf: *Elf, ni: MappedFile.Node.Index) void {9385fn flushElfOffset(elf: *Elf, ni: MappedFile.Node.Index) void {
9307 const elf_offset = elf.getNodeElfOffset(ni);9386 const elf_offset = elf.computeNodeElfOffset(ni);
9308 switch (elf.getNode(ni)) {9387 switch (elf.getNode(ni)) {
9309 else => unreachable,9388 else => unreachable,
9310 .ehdr => assert(elf_offset == 0),9389 .ehdr => assert(elf_offset == 0),
...@@ -9508,32 +9587,34 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9508,32 +9587,34 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9508 });9587 });
9509 },9588 },
9510 .debug_shared => |ss| {9589 .debug_shared => |ss| {
9590 const target_section_offset = elf.computeNodeSectionOffset(ni);
9511 var target_ri = elf.dwarf_shared.getPtr(ss).first_target_reloc;9591 var target_ri = elf.dwarf_shared.getPtr(ss).first_target_reloc;
9512 while (target_ri != .none) {9592 while (target_ri != .none) {
9513 const target_reloc = target_ri.get(elf);9593 const target_reloc = target_ri.get(elf);
9514 assert(target_reloc.target == ni);9594 assert(target_reloc.target == ni);
9515 target_reloc.apply(elf);9595 target_reloc.flushMovedTarget(elf, target_section_offset);
9516 target_ri = target_reloc.next;9596 target_ri = target_reloc.next;
9517 }9597 }
9518 },9598 },
9519 .unit_padding, .unit_frame, .unit_debug_info, .unit_debug_line => {},9599 .unit_padding, .unit_frame, .unit_debug_info, .unit_debug_line => {},
9520 .unit_frame_cie => |ui| {9600 .unit_frame_cie => |ui| {
9521 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];9601 const target_section_offset = elf.computeNodeSectionOffset(ni);
9522 var target_ri = dwarf_unit.frame_cie_first_target_reloc;9602 var target_ri = elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc;
9523 while (target_ri != .none) {9603 while (target_ri != .none) {
9524 const target_reloc = target_ri.get(elf);9604 const target_reloc = target_ri.get(elf);
9525 assert(target_reloc.target == ni);9605 assert(target_reloc.target == ni);
9526 target_reloc.apply(elf);9606 target_reloc.flushMovedTarget(elf, target_section_offset);
9527 target_ri = target_reloc.next;9607 target_ri = target_reloc.next;
9528 }9608 }
9529 },9609 },
9530 .unit_debug_info_header => |ui| {9610 .unit_debug_info_header => |ui| {
9531 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];9611 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];
9612 const target_section_offset = elf.computeNodeSectionOffset(ni);
9532 var target_ri = dwarf_unit.debug_info_header_first_target_reloc;9613 var target_ri = dwarf_unit.debug_info_header_first_target_reloc;
9533 while (target_ri != .none) {9614 while (target_ri != .none) {
9534 const target_reloc = target_ri.get(elf);9615 const target_reloc = target_ri.get(elf);
9535 assert(target_reloc.target == ni);9616 assert(target_reloc.target == ni);
9536 target_reloc.apply(elf);9617 target_reloc.flushMovedTarget(elf, target_section_offset);
9537 target_ri = target_reloc.next;9618 target_ri = target_reloc.next;
9538 }9619 }
9539 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{9620 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
...@@ -9542,11 +9623,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9542,11 +9623,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9542 },9623 },
9543 .unit_debug_line_header => |ui| {9624 .unit_debug_line_header => |ui| {
9544 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];9625 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];
9626 const target_section_offset = elf.computeNodeSectionOffset(ni);
9545 var target_ri = dwarf_unit.debug_line_header_first_target_reloc;9627 var target_ri = dwarf_unit.debug_line_header_first_target_reloc;
9546 while (target_ri != .none) {9628 while (target_ri != .none) {
9547 const target_reloc = target_ri.get(elf);9629 const target_reloc = target_ri.get(elf);
9548 assert(target_reloc.target == ni);9630 assert(target_reloc.target == ni);
9549 target_reloc.apply(elf);9631 target_reloc.flushMovedTarget(elf, target_section_offset);
9550 target_ri = target_reloc.next;9632 target_ri = target_reloc.next;
9551 }9633 }
9552 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{9634 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
...@@ -9555,34 +9637,29 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9555,34 +9637,29 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9555 },9637 },
9556 .unit_debug_rnglists => |ui| {9638 .unit_debug_rnglists => |ui| {
9557 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];9639 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];
9640 const target_section_offset = elf.computeNodeSectionOffset(ni);
9558 var target_ri = dwarf_unit.debug_rnglists_first_target_reloc;9641 var target_ri = dwarf_unit.debug_rnglists_first_target_reloc;
9559 while (target_ri != .none) {9642 while (target_ri != .none) {
9560 const target_reloc = target_ri.get(elf);9643 const target_reloc = target_ri.get(elf);
9561 assert(target_reloc.target == ni);9644 assert(target_reloc.target == ni);
9562 target_reloc.apply(elf);9645 target_reloc.flushMovedTarget(elf, target_section_offset);
9563 target_ri = target_reloc.next;9646 target_ri = target_reloc.next;
9564 }9647 }
9565 const node_vaddr = elf.computeNodeVAddr(ni);9648 const node_vaddr = elf.computeNodeVAddr(ni);
9566 for (dwarf_unit.debug_rnglists_symbol_relocs.keys()) |symbol_ri| {9649 for (dwarf_unit.debug_rnglists_symbol_relocs.keys()) |symbol_ri| {
9567 const symbol_reloc = symbol_ri.get(elf);9650 const symbol_reloc = symbol_ri.get(elf);
9568 assert(symbol_reloc.node == ni);9651 assert(symbol_reloc.node == ni);
9569 if (symbol_reloc.rela_index.unwrap()) |rela_index| {9652 symbol_reloc.flushMovedNode(elf, node_vaddr);
9570 // The node has moved, so the offset of the relocation within the section might have
9571 // changed, so update the `offset` field of the `ElfN.Rela` entry.
9572 symbol_reloc.relaSection(elf).relaSetOffset(elf, rela_index, node_vaddr + symbol_reloc.offset);
9573 }
9574 if (elf.ehdrType() != .REL) {
9575 symbol_reloc.apply(elf);
9576 }
9577 }9653 }
9578 },9654 },
9579 .value_debug_info => |vi| {9655 .value_debug_info => |vi| {
9580 const dwarf_value = &elf.dwarf_values.items[@backingInt(vi)];9656 const dwarf_value = &elf.dwarf_values.items[@backingInt(vi)];
9657 const target_section_offset = elf.computeNodeSectionOffset(ni);
9581 var target_ri = dwarf_value.debug_info_first_target_reloc;9658 var target_ri = dwarf_value.debug_info_first_target_reloc;
9582 while (target_ri != .none) {9659 while (target_ri != .none) {
9583 const target_reloc = target_ri.get(elf);9660 const target_reloc = target_ri.get(elf);
9584 assert(target_reloc.target == ni);9661 assert(target_reloc.target == ni);
9585 target_reloc.apply(elf);9662 target_reloc.flushMovedTarget(elf, target_section_offset);
9586 target_ri = target_reloc.next;9663 target_ri = target_reloc.next;
9587 }9664 }
9588 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{9665 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
...@@ -9592,11 +9669,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9592,11 +9669,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9592 },9669 },
9593 .global_debug_info => |vi| {9670 .global_debug_info => |vi| {
9594 const dwarf_global = &elf.dwarf_globals.items[@backingInt(vi)];9671 const dwarf_global = &elf.dwarf_globals.items[@backingInt(vi)];
9672 const target_section_offset = elf.computeNodeSectionOffset(ni);
9595 var target_ri = dwarf_global.debug_info_first_target_reloc;9673 var target_ri = dwarf_global.debug_info_first_target_reloc;
9596 while (target_ri != .none) {9674 while (target_ri != .none) {
9597 const target_reloc = target_ri.get(elf);9675 const target_reloc = target_ri.get(elf);
9598 assert(target_reloc.target == ni);9676 assert(target_reloc.target == ni);
9599 target_reloc.apply(elf);9677 target_reloc.flushMovedTarget(elf, target_section_offset);
9600 target_ri = target_reloc.next;9678 target_ri = target_reloc.next;
9601 }9679 }
9602 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{9680 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
...@@ -9607,7 +9685,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9607,7 +9685,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9607 .func_frame_fde => |fi| {9685 .func_frame_fde => |fi| {
9608 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];9686 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
9609 const zcu = elf.base.comp.zcu.?;9687 const zcu = elf.base.comp.zcu.?;
9610 const mod = zcu.fileByIndex(fi.srcInst(&elf.dwarf).resolveFile(&zcu.intern_pool)).mod.?;9688 const mod = zcu.navFileScope(fi.nav(&elf.dwarf)).mod.?;
9611 switch (mod.unwind_tables) {9689 switch (mod.unwind_tables) {
9612 .none => {},9690 .none => {},
9613 .sync, .async => {9691 .sync, .async => {
...@@ -9622,17 +9700,18 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9622,17 +9700,18 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9622 },9700 },
9623 .func_debug_info => |fi| {9701 .func_debug_info => |fi| {
9624 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];9702 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
9703 const target_section_offset = elf.computeNodeSectionOffset(ni);
9625 var target_ri = dwarf_func.debug_info_first_target_reloc;9704 var target_ri = dwarf_func.debug_info_first_target_reloc;
9626 while (target_ri != .none) {9705 while (target_ri != .none) {
9627 const target_reloc = target_ri.get(elf);9706 const target_reloc = target_ri.get(elf);
9628 assert(target_reloc.target == ni);9707 assert(target_reloc.target == ni);
9629 target_reloc.apply(elf);9708 target_reloc.flushMovedTarget(elf, target_section_offset);
9630 target_ri = target_reloc.next;9709 target_ri = target_reloc.next;
9631 }9710 }
9632 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{9711 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9633 .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc,9712 .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc,
9634 .skip_symbol_relocs = if (elf.navs.getPtr(fi.get(&elf.dwarf).owner_nav)) |owner_nav|9713 .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav|
9635 owner_nav.lsi.index().ptr(elf).node9714 nav.lsi.index().ptr(elf).node
9636 else9715 else
9637 .none,9716 .none,
9638 .first_node_reloc = dwarf_func.debug_info_first_node_reloc,9717 .first_node_reloc = dwarf_func.debug_info_first_node_reloc,
...@@ -10630,10 +10709,10 @@ pub fn printNode(...@@ -10630,10 +10709,10 @@ pub fn printNode(
10630 .func_frame_fde, .func_debug_info, .func_debug_line => |fi| {10709 .func_frame_fde, .func_debug_info, .func_debug_line => |fi| {
10631 const zcu = elf.base.comp.zcu.?;10710 const zcu = elf.base.comp.zcu.?;
10632 const ip = &zcu.intern_pool;10711 const ip = &zcu.intern_pool;
10633 const owner_nav = ip.getNav(fi.get(&elf.dwarf).owner_nav);10712 const nav = ip.getNav(fi.nav(&elf.dwarf));
10634 try w.print("({f}, {f})", .{10713 try w.print("({f}, {f})", .{
10635 Type.fromInterned(owner_nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),10714 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
10636 owner_nav.fqn.fmt(ip),10715 nav.fqn.fmt(ip),
10637 });10716 });
10638 },10717 },
10639 }10718 }
src/link/MachO.zig+2-2
...@@ -3095,8 +3095,8 @@ pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) lin...@@ -3095,8 +3095,8 @@ pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) lin
3095 return self.getZigObject().?.updateNav(self, pt, nav);3095 return self.getZigObject().?.updateNav(self, pt, nav);
3096}3096}
30973097
3098pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {3098pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, inst: InternPool.TrackedInst.Index, line: u32) link.Error!void {
3099 return self.getZigObject().?.updateLineNumber(pt, ti_id);3099 return self.getZigObject().?.updateLineNumber(pt, inst, line);
3100}3100}
31013101
3102pub fn updateExports(3102pub fn updateExports(
src/link/MachO/ZigObject.zig+2-2
...@@ -1412,11 +1412,11 @@ fn updateLazySymbol(...@@ -1412,11 +1412,11 @@ fn updateLazySymbol(
1412 try macho_file.pwriteAll(code, file_offset);1412 try macho_file.pwriteAll(code, file_offset);
1413}1413}
14141414
1415pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {1415pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index, line: u32) link.Error!void {
1416 if (self.dwarf) |*dwarf| {1416 if (self.dwarf) |*dwarf| {
1417 const comp = dwarf.bin_file.comp;1417 const comp = dwarf.bin_file.comp;
1418 const diags = &comp.link_diags;1418 const diags = &comp.link_diags;
1419 dwarf.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) {1419 dwarf.updateLineNumber(pt.zcu, ti_id, line) catch |err| switch (err) {
1420 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,1420 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
1421 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),1421 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),
1422 };1422 };
src/link/Spork8.zig+3-2
...@@ -168,10 +168,11 @@ pub fn updateNav(spork8: *Spork8, pt: Zcu.PerThread, nav_index: InternPool.Nav.I...@@ -168,10 +168,11 @@ pub fn updateNav(spork8: *Spork8, pt: Zcu.PerThread, nav_index: InternPool.Nav.I
168 log.debug("updateNav {f}", .{nav.fqn.fmt(ip)});168 log.debug("updateNav {f}", .{nav.fqn.fmt(ip)});
169}169}
170170
171pub fn updateLineNumber(spork8: *Spork8, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {171pub fn updateLineNumber(spork8: *Spork8, pt: Zcu.PerThread, inst: InternPool.TrackedInst.Index, line: u32) !void {
172 _ = spork8;172 _ = spork8;
173 _ = pt;173 _ = pt;
174 _ = ti_id;174 _ = inst;
175 _ = line;
175}176}
176177
177pub fn deleteExport(178pub fn deleteExport(
src/link/Wasm.zig+2-2
...@@ -3728,11 +3728,11 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index...@@ -3728,11 +3728,11 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
3728 }3728 }
3729}3729}
37303730
3731pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {3731pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index, line: u32) link.Error!void {
3732 const comp = wasm.base.comp;3732 const comp = wasm.base.comp;
3733 const diags = &comp.link_diags;3733 const diags = &comp.link_diags;
3734 if (wasm.dwarf) |*dw| {3734 if (wasm.dwarf) |*dw| {
3735 dw.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) {3735 dw.updateLineNumber(pt.zcu, ti_id, line) catch |err| switch (err) {
3736 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,3736 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
3737 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),3737 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),
3738 };3738 };