authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-11 10:50:03-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 11:00:56-04:00
logb9b1174d069fcf201df79cb2fbaecdfc1fc74206
tree7bad94fb34cf0c32679cea7a913d6e65e48f1fc3
parent2a122576c3042c30f9a78492252cbbc4c0424a40

Dwarf2: implement line info for inline calls


3 files changed, 250 insertions(+), 231 deletions(-)

lib/std/dwarf/AT.zig+1
...@@ -225,6 +225,7 @@ pub const ZIG_padding = 0x2cce;...@@ -225,6 +225,7 @@ pub const ZIG_padding = 0x2cce;
225pub const ZIG_relative_decl = 0x2cd0;225pub const ZIG_relative_decl = 0x2cd0;
226pub const ZIG_decl_line_relative = 0x2cd1;226pub const ZIG_decl_line_relative = 0x2cd1;
227pub const ZIG_comptime_value = 0x2cd2;227pub const ZIG_comptime_value = 0x2cd2;
228pub const ZIG_call_line_relative = 0x2cd3;
228pub const ZIG_sentinel = 0x2ce2;229pub const ZIG_sentinel = 0x2ce2;
229230
230// UPC extension.231// UPC extension.
src/link/Dwarf2.zig+188-168
...@@ -6,9 +6,7 @@ const_pool: link.ConstPool,...@@ -6,9 +6,7 @@ const_pool: link.ConstPool,
66
7units: std.array_hash_map.Auto(*Module, Unit),7units: std.array_hash_map.Auto(*Module, Unit),
8/// Indices are `link.ConstPool.Index`.8/// Indices are `link.ConstPool.Index`.
9values: std.ArrayList(struct {9values: std.ArrayList(Value),
10 debug_info_ni: MappedFile.Node.Index,
11}),
12globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),10globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),
13funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func),11funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func),
1412
...@@ -92,6 +90,22 @@ pub const Unit = struct {...@@ -92,6 +90,22 @@ pub const Unit = struct {
92 }90 }
93};91};
9492
93pub const Value = struct {
94 debug_info_ni: MappedFile.Node.Index,
95
96 pub const Index = enum(u32) {
97 _,
98
99 pub fn cpi(vi: Value.Index, dwarf: *Dwarf) link.ConstPool.Index {
100 return dwarf.values[@backingInt(vi)];
101 }
102
103 pub fn get(vi: Value.Index, dwarf: *Dwarf) *Global {
104 return &dwarf.values[@backingInt(vi)];
105 }
106 };
107};
108
95pub const Global = struct {109pub const Global = struct {
96 debug_info_ni: MappedFile.Node.Index.Optional,110 debug_info_ni: MappedFile.Node.Index.Optional,
97111
...@@ -574,7 +588,7 @@ pub const Cfa = union(enum) {...@@ -574,7 +588,7 @@ pub const Cfa = union(enum) {
574pub const WipNav = struct {588pub const WipNav = struct {
575 dwarf: *Dwarf,589 dwarf: *Dwarf,
576 unit: Unit.Index,590 unit: Unit.Index,
577 func: ?Func.Index,591 func: InternPool.Index,
578 func_si: link.File.SymbolId,592 func_si: link.File.SymbolId,
579 cfi: struct {593 cfi: struct {
580 loc: u32,594 loc: u32,
...@@ -590,7 +604,7 @@ pub const WipNav = struct {...@@ -590,7 +604,7 @@ pub const WipNav = struct {
590 any_children: bool,604 any_children: bool,
591 blocks: std.ArrayList(struct {605 blocks: std.ArrayList(struct {
592 abbrev_code: u32,606 abbrev_code: u32,
593 low_pc_off: u64,607 low_pc_off: usize,
594 high_pc: u32,608 high_pc: u32,
595 }),609 }),
596 info_writer: MappedFile.Node.Writer,610 info_writer: MappedFile.Node.Writer,
...@@ -610,21 +624,18 @@ pub const WipNav = struct {...@@ -610,21 +624,18 @@ pub const WipNav = struct {
610 return debug.wip_nav.genDebugFrame(loc, cfa);624 return debug.wip_nav.genDebugFrame(loc, cfa);
611 }625 }
612626
613 pub fn startFunc(debug: *Debug) link.Error!void {627 pub fn startDebugInfo(debug: *Debug) link.Error!void {
614 assert(debug.wip_nav.func != null);628 assert(debug.wip_nav.func != .none);
615 debug.startDebugInfo() catch |err| switch (err) {629 debug.startDebugInfoInner() catch |err| switch (err) {
616 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),630 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
617 else => |e| return e,631 else => |e| return e,
618 };632 };
619 debug.startDebugLine() catch |err| switch (err) {
620 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
621 else => |e| return e,
622 };
623 }633 }
624 fn startDebugInfo(debug: *Debug) link.EmitError!void {634 fn startDebugInfoInner(debug: *Debug) link.EmitError!void {
625 const dwarf = debug.wip_nav.dwarf;635 const dwarf = debug.wip_nav.dwarf;
626 const ip = &debug.pt.zcu.intern_pool;636 const zcu = debug.pt.zcu;
627 const nav = ip.getNav(debug.wip_nav.func.?.nav(dwarf));637 const ip = &zcu.intern_pool;
638 const nav = ip.getNav(zcu.funcInfo(debug.wip_nav.func).owner_nav);
628 const diw = &debug.info_writer.interface;639 const diw = &debug.info_writer.interface;
629 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func));640 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func));
630 try debug.strp(nav.name.toSlice(ip));641 try debug.strp(nav.name.toSlice(ip));
...@@ -633,23 +644,27 @@ pub const WipNav = struct {...@@ -633,23 +644,27 @@ pub const WipNav = struct {
633 debug.info_func_length_offset = diw.end;644 debug.info_func_length_offset = diw.end;
634 try diw.writeInt(u32, undefined, dwarf.endian);645 try diw.writeInt(u32, undefined, dwarf.endian);
635 }646 }
636 fn startDebugLine(debug: *Debug) link.EmitError!void {647
648 pub fn startDebugLine(debug: *Debug) link.Error!void {
649 assert(debug.wip_nav.func != .none);
650 debug.startDebugLineInner() catch |err| switch (err) {
651 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
652 else => |e| return e,
653 };
654 }
655 fn startDebugLineInner(debug: *Debug) link.EmitError!void {
637 const dwarf = debug.wip_nav.dwarf;656 const dwarf = debug.wip_nav.dwarf;
638 const zcu = debug.pt.zcu;657 const zcu = debug.pt.zcu;
639 const ip = &zcu.intern_pool;658 const ip = &zcu.intern_pool;
640 const nav = debug.wip_nav.func.?.nav(dwarf);659 const func = zcu.funcInfo(debug.wip_nav.func);
641 const func = zcu.funcInfo(zcu.navValue(nav).toIntern());660 const zfi = zcu.navFileScopeIndex(func.owner_nav);
642 const zfi = zcu.navFileScopeIndex(nav);
643 const zf = zcu.fileByIndex(zfi);661 const zf = zcu.fileByIndex(zfi);
644 const inst_info = ip.getNav(nav).srcInst(ip).resolveFull(ip).?;662 const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?;
645 const decl = zf.zir.?.getDeclaration(inst_info.inst);663 const decl = zf.zir.?.getDeclaration(inst_info.inst);
646 const dlw = &debug.line_writer.interface;664 const dlw = &debug.line_writer.interface;
647 try dlw.writeByte(DW.LNS.extended_op);665 try dlw.writeByte(DW.LNS.extended_op);
648 if (zcu.comp.config.incremental) {666 if (zcu.comp.config.incremental) {
649 try dlw.writeUleb128(1 + @as(u7, switch (dwarf.format) {667 try dlw.writeUleb128(1 + dwarf.sectionOffsetSize());
650 .@"32" => 4,
651 .@"64" => 8,
652 }));
653 try dlw.writeByte(DW.LNE.ZIG_set_decl);668 try dlw.writeByte(DW.LNE.ZIG_set_decl);
654 try dwarf.sectionOffset(&debug.line_writer, debug.info_writer.ni, 0);669 try dwarf.sectionOffset(&debug.line_writer, debug.info_writer.ni, 0);
655670
...@@ -675,7 +690,7 @@ pub const WipNav = struct {...@@ -675,7 +690,7 @@ pub const WipNav = struct {
675 }690 }
676691
677 pub fn finishFunc(debug: *Debug, func_length: u64) link.Error!void {692 pub fn finishFunc(debug: *Debug, func_length: u64) link.Error!void {
678 assert(debug.wip_nav.func != null);693 assert(debug.wip_nav.func != .none);
679 debug.finishDebugInfo(func_length) catch |err| switch (err) {694 debug.finishDebugInfo(func_length) catch |err| switch (err) {
680 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),695 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
681 else => |e| return e,696 else => |e| return e,
...@@ -706,10 +721,9 @@ pub const WipNav = struct {...@@ -706,10 +721,9 @@ pub const WipNav = struct {
706 debug: *Debug,721 debug: *Debug,
707 tag: LocalVarTag,722 tag: LocalVarTag,
708 opt_name: ?[]const u8,723 opt_name: ?[]const u8,
709 ty: Type,724 ty: ZigType,
710 loc: Loc,725 loc: Loc,
711 ) link.Error!void {726 ) link.Error!void {
712 if (true) return;
713 return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) {727 return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) {
714 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),728 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
715 else => |e| e,729 else => |e| e,
...@@ -719,16 +733,16 @@ pub const WipNav = struct {...@@ -719,16 +733,16 @@ pub const WipNav = struct {
719 debug: *Debug,733 debug: *Debug,
720 tag: LocalVarTag,734 tag: LocalVarTag,
721 opt_name: ?[]const u8,735 opt_name: ?[]const u8,
722 ty: Type,736 ty: ZigType,
723 loc: Loc,737 loc: Loc,
724 ) link.EmitError!void {738 ) link.EmitError!void {
725 assert(debug.wip_nav.func != null);739 assert(debug.wip_nav.func != .none);
726 try debug.abbrevCode(switch (tag) {740 try debug.abbrevCode(switch (tag) {
727 .arg => if (opt_name) |_| .arg else .unnamed_arg,741 .arg => if (opt_name) |_| .arg else .unnamed_arg,
728 .local_var => if (opt_name) |_| .local_var else unreachable,742 .local_var => if (opt_name) |_| .local_var else unreachable,
729 });743 });
730 if (opt_name) |name| try debug.strp(name);744 if (opt_name) |name| try debug.strp(name);
731 try debug.refType(ty);745 if (false) try debug.refType(ty);
732 try debug.infoExprLoc(loc);746 try debug.infoExprLoc(loc);
733 debug.any_children = true;747 debug.any_children = true;
734 }748 }
...@@ -738,9 +752,8 @@ pub const WipNav = struct {...@@ -738,9 +752,8 @@ pub const WipNav = struct {
738 debug: *Debug,752 debug: *Debug,
739 tag: LocalConstTag,753 tag: LocalConstTag,
740 opt_name: ?[]const u8,754 opt_name: ?[]const u8,
741 val: Value,755 val: ZigValue,
742 ) link.Error!void {756 ) link.Error!void {
743 if (true) return;
744 return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) {757 return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) {
745 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),758 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
746 else => |e| e,759 else => |e| e,
...@@ -750,9 +763,9 @@ pub const WipNav = struct {...@@ -750,9 +763,9 @@ pub const WipNav = struct {
750 debug: *Debug,763 debug: *Debug,
751 tag: LocalConstTag,764 tag: LocalConstTag,
752 opt_name: ?[]const u8,765 opt_name: ?[]const u8,
753 val: Value,766 val: ZigValue,
754 ) link.EmitError!void {767 ) link.EmitError!void {
755 assert(debug.wip_nav.func != null);768 assert(debug.wip_nav.func != .none);
756 const zcu = debug.pt.zcu;769 const zcu = debug.pt.zcu;
757 const ty = val.typeOf(zcu);770 const ty = val.typeOf(zcu);
758 const has_runtime_bits = ty.hasRuntimeBits(zcu);771 const has_runtime_bits = ty.hasRuntimeBits(zcu);
...@@ -771,21 +784,20 @@ pub const WipNav = struct {...@@ -771,21 +784,20 @@ pub const WipNav = struct {
771 .local_const => if (opt_name) |_| .local_const else unreachable,784 .local_const => if (opt_name) |_| .local_const else unreachable,
772 });785 });
773 if (opt_name) |name| try debug.strp(name);786 if (opt_name) |name| try debug.strp(name);
774 try debug.refType(ty);787 if (false) try debug.refType(ty);
775 if (has_runtime_bits) try debug.blockValue(val);788 if (has_runtime_bits) try debug.blockValue(val);
776 if (has_comptime_state) try debug.refValue(val);789 if (false and has_comptime_state) try debug.refValue(val);
777 debug.any_children = true;790 debug.any_children = true;
778 }791 }
779792
780 pub fn genVarArgsDebugInfo(debug: *Debug) link.Error!void {793 pub fn genVarArgsDebugInfo(debug: *Debug) link.Error!void {
781 if (true) return;
782 return debug.genVarArgsDebugInfoInner() catch |err| switch (err) {794 return debug.genVarArgsDebugInfoInner() catch |err| switch (err) {
783 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),795 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
784 else => |e| e,796 else => |e| e,
785 };797 };
786 }798 }
787 fn genVarArgsDebugInfoInner(debug: *Debug) link.EmitError!void {799 fn genVarArgsDebugInfoInner(debug: *Debug) link.EmitError!void {
788 assert(debug.wip_nav.func != null);800 assert(debug.wip_nav.func != .none);
789 try debug.abbrevCode(.is_var_args);801 try debug.abbrevCode(.is_var_args);
790 debug.any_children = true;802 debug.any_children = true;
791 }803 }
...@@ -888,14 +900,13 @@ pub const WipNav = struct {...@@ -888,14 +900,13 @@ pub const WipNav = struct {
888 try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin);900 try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin);
889 }901 }
890902
891 pub fn enterBlock(debug: *Debug, code_off: u64) link.Error!void {903 pub fn enterBlock(debug: *Debug, code_off: usize) link.Error!void {
892 return debug.enterBlockInner(code_off) catch |err| switch (err) {904 return debug.enterBlockInner(code_off) catch |err| switch (err) {
893 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),905 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
894 else => |e| e,906 else => |e| e,
895 };907 };
896 }908 }
897 fn enterBlockInner(debug: *Debug, code_off: u64) link.EmitError!void {909 fn enterBlockInner(debug: *Debug, code_off: usize) link.EmitError!void {
898 if (true) return;
899 const dwarf = debug.wip_nav.dwarf;910 const dwarf = debug.wip_nav.dwarf;
900 const diw = &debug.info_writer.interface;911 const diw = &debug.info_writer.interface;
901 const block = try debug.blocks.addOne(dwarf.lf.comp.gpa);912 const block = try debug.blocks.addOne(dwarf.lf.comp.gpa);
...@@ -909,14 +920,13 @@ pub const WipNav = struct {...@@ -909,14 +920,13 @@ pub const WipNav = struct {
909 debug.any_children = false;920 debug.any_children = false;
910 }921 }
911922
912 pub fn leaveBlock(debug: *Debug, code_off: u64) link.Error!void {923 pub fn leaveBlock(debug: *Debug, code_off: usize) link.Error!void {
913 if (true) return;
914 return debug.leaveBlockInner(code_off) catch |err| switch (err) {924 return debug.leaveBlockInner(code_off) catch |err| switch (err) {
915 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),925 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
916 else => |e| e,926 else => |e| e,
917 };927 };
918 }928 }
919 fn leaveBlockInner(debug: *Debug, code_off: u64) link.EmitError!void {929 fn leaveBlockInner(debug: *Debug, code_off: usize) link.EmitError!void {
920 const dwarf = debug.wip_nav.dwarf;930 const dwarf = debug.wip_nav.dwarf;
921 const block_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.block));931 const block_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.block));
922 const block = debug.blocks.pop().?;932 const block = debug.blocks.pop().?;
...@@ -940,11 +950,10 @@ pub const WipNav = struct {...@@ -940,11 +950,10 @@ pub const WipNav = struct {
940 pub fn enterInlineFunc(950 pub fn enterInlineFunc(
941 debug: *Debug,951 debug: *Debug,
942 func: InternPool.Index,952 func: InternPool.Index,
943 code_off: u64,953 code_off: usize,
944 line: u32,954 line: u32,
945 column: u32,955 column: u32,
946 ) link.Error!void {956 ) link.Error!void {
947 if (true) return;
948 return debug.enterInlineFuncInner(func, code_off, line, column) catch |err| switch (err) {957 return debug.enterInlineFuncInner(func, code_off, line, column) catch |err| switch (err) {
949 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),958 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
950 else => |e| e,959 else => |e| e,
...@@ -953,7 +962,7 @@ pub const WipNav = struct {...@@ -953,7 +962,7 @@ pub const WipNav = struct {
953 fn enterInlineFuncInner(962 fn enterInlineFuncInner(
954 debug: *Debug,963 debug: *Debug,
955 func: InternPool.Index,964 func: InternPool.Index,
956 code_off: u64,965 code_off: usize,
957 line: u32,966 line: u32,
958 column: u32,967 column: u32,
959 ) link.EmitError!void {968 ) link.EmitError!void {
...@@ -964,8 +973,12 @@ pub const WipNav = struct {...@@ -964,8 +973,12 @@ pub const WipNav = struct {
964973
965 block.abbrev_code = @intCast(diw.end);974 block.abbrev_code = @intCast(diw.end);
966 try debug.abbrevCode(.inlined_func);975 try debug.abbrevCode(.inlined_func);
967 try debug.refNav(zcu.funcInfo(func).owner_nav);976 try debug.refFunc(func);
968 try diw.writeUleb128(zcu.navSrcLine(debug.wip_nav.func.?.nav(dwarf)) + line + 1);977 try diw.writeUleb128((if (zcu.comp.config.incremental)
978 0
979 else
980 zcu.navSrcLine(zcu.funcInfo(debug.wip_nav.func).owner_nav) + 1) + line);
981 try diw.writeUleb128(line);
969 try diw.writeUleb128(column + 1);982 try diw.writeUleb128(column + 1);
970 block.low_pc_off = code_off;983 block.low_pc_off = code_off;
971 try debug.infoAddrSym(debug.wip_nav.func_si, code_off);984 try debug.infoAddrSym(debug.wip_nav.func_si, code_off);
...@@ -975,8 +988,7 @@ pub const WipNav = struct {...@@ -975,8 +988,7 @@ pub const WipNav = struct {
975 debug.any_children = false;988 debug.any_children = false;
976 }989 }
977990
978 pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: u64) link.Error!void {991 pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: usize) link.Error!void {
979 if (true) return;
980 return debug.leaveInlineFuncInner(func, code_off) catch |err| switch (err) {992 return debug.leaveInlineFuncInner(func, code_off) catch |err| switch (err) {
981 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),993 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
982 else => |e| e,994 else => |e| e,
...@@ -985,7 +997,7 @@ pub const WipNav = struct {...@@ -985,7 +997,7 @@ pub const WipNav = struct {
985 fn leaveInlineFuncInner(997 fn leaveInlineFuncInner(
986 debug: *Debug,998 debug: *Debug,
987 func: InternPool.Index,999 func: InternPool.Index,
988 code_off: u64,1000 code_off: usize,
989 ) link.EmitError!void {1001 ) link.EmitError!void {
990 const dwarf = debug.wip_nav.dwarf;1002 const dwarf = debug.wip_nav.dwarf;
991 const inlined_func_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.inlined_func));1003 const inlined_func_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.inlined_func));
...@@ -1016,55 +1028,35 @@ pub const WipNav = struct {...@@ -1016,55 +1028,35 @@ pub const WipNav = struct {
1016 };1028 };
1017 }1029 }
1018 fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) link.EmitError!void {1030 fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) link.EmitError!void {
1019 const wip_nav = &debug.wip_nav;
1020 const zcu = debug.pt.zcu;1031 const zcu = debug.pt.zcu;
1021 const dwarf = wip_nav.dwarf;1032 const dwarf = debug.wip_nav.dwarf;
10221033 if (debug.wip_nav.func == func) return;
1023 const func_index = try dwarf.getFunc(zcu.funcInfo(func).owner_nav);
1024 if (wip_nav.func == func_index) return;
10251034
1026 if (true) @panic("TODO");
1027 const new_func_info = zcu.funcInfo(func);1035 const new_func_info = zcu.funcInfo(func);
1028 const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav);
1029 const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod.?);
10301036
1031 const dlw = &debug.line_writer.interface;1037 const dlw = &debug.line_writer.interface;
1032 if (zcu.comp.config.incremental) {1038 if (zcu.comp.config.incremental) {
1033 const new_func_gop = try dwarf.funcs.getOrPut(zcu.gpa, new_func_info.owner_nav);1039 const new_func = try dwarf.getFunc(new_func_info.owner_nav);
1034 errdefer _ = if (!new_func_gop.found_existing) dwarf.funcs.pop();
1035 if (!new_func_gop.found_existing) new_func_gop.value_ptr.* = .{
1036 .frame_node = .none,
1037 .debug_info_node = .none,
1038 .debug_line_node = .none,
1039 };
1040
1041 const section_offset_size: u4 = switch (dwarf.format) {
1042 .@"32" => 4,
1043 .@"64" => 8,
1044 };
1045
1046 try dlw.writeByte(DW.LNS.extended_op);1040 try dlw.writeByte(DW.LNS.extended_op);
1047 try dlw.writeUleb128(1 + section_offset_size);1041 try dlw.writeUleb128(1 + dwarf.sectionOffsetSize());
1048 try dlw.writeByte(DW.LNE.ZIG_set_decl);1042 try dlw.writeByte(DW.LNE.ZIG_set_decl);
1049 try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_section_relocs.append(zcu.gpa, .{1043 try dwarf.sectionOffset(
1050 .source_off = @bitCast(@as(u64, dlw.end)),1044 &debug.line_writer,
1051 .target_sec = .debug_info,1045 new_func.get(dwarf).debug_info_ni.unwrap().?,
1052 .target_unit = new_unit,1046 0,
1053 .target_entry = new_func_gop.value_ptr.toOptional(),1047 );
1054 });
1055 try dlw.splatByteAll(0, section_offset_size);
1056 return;1048 return;
1057 }1049 }
10581050
1059 const old_func_info = zcu.funcInfo(wip_nav.func);1051 const old_func_info = zcu.funcInfo(debug.wip_nav.func);
1060 const old_file = zcu.navFileScopeIndex(old_func_info.owner_nav);1052 const old_zfi = zcu.navFileScopeIndex(old_func_info.owner_nav);
1061 if (old_file != new_file) {1053 const new_zfi = zcu.navFileScopeIndex(new_func_info.owner_nav);
1062 const mod_info = dwarf.getModInfo(wip_nav.unit);1054 if (old_zfi != new_zfi) {
1063 try mod_info.dirs.put(zcu.gpa, new_unit, {});1055 const new_ui = dwarf.getUnit(zcu.fileByIndex(new_zfi).mod.?);
1064 const file_gop = try mod_info.files.getOrPut(zcu.gpa, new_file);1056 _, const new_fi = try debug.wip_nav.unit.get(dwarf).getFile(zcu.gpa, new_ui, new_zfi);
10651057
1066 try dlw.writeByte(DW.LNS.set_file);1058 try dlw.writeByte(DW.LNS.set_file);
1067 try dlw.writeUleb128(file_gop.index);1059 try dlw.writeUleb128(@backingInt(new_fi));
1068 }1060 }
10691061
1070 const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav);1062 const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav);
...@@ -1074,7 +1066,7 @@ pub const WipNav = struct {...@@ -1074,7 +1066,7 @@ pub const WipNav = struct {
1074 try dlw.writeSleb128(new_src_line - old_src_line);1066 try dlw.writeSleb128(new_src_line - old_src_line);
1075 }1067 }
10761068
1077 wip_nav.func = func;1069 debug.wip_nav.func = func;
1078 }1070 }
10791071
1080 fn abbrevCode(debug: *Debug, abbrev_code: AbbrevCode) link.EmitError!void {1072 fn abbrevCode(debug: *Debug, abbrev_code: AbbrevCode) link.EmitError!void {
...@@ -1083,14 +1075,6 @@ pub const WipNav = struct {...@@ -1083,14 +1075,6 @@ pub const WipNav = struct {
1083 );1075 );
1084 }1076 }
10851077
1086 fn infoSectionOffset(
1087 debug: *Debug,
1088 target_ni: MappedFile.Node.Index,
1089 addend: i64,
1090 ) link.EmitError!void {
1091 try debug.wip_nav.dwarf.sectionOffset(&debug.info_writer, target_ni, addend);
1092 }
1093
1094 fn strp(debug: *Debug, str: []const u8) link.EmitError!void {1078 fn strp(debug: *Debug, str: []const u8) link.EmitError!void {
1095 const dwarf = debug.wip_nav.dwarf;1079 const dwarf = debug.wip_nav.dwarf;
1096 try dwarf.strp(&dwarf.debug_str, &debug.info_writer, str);1080 try dwarf.strp(&dwarf.debug_str, &debug.info_writer, str);
...@@ -1119,8 +1103,8 @@ pub const WipNav = struct {...@@ -1119,8 +1103,8 @@ pub const WipNav = struct {
1119 fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void {1103 fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void {
1120 try ctx.debug.infoAddrSym(si, 0);1104 try ctx.debug.infoAddrSym(si, 0);
1121 }1105 }
1122 fn infoEntry(ctx: @This(), node: MappedFile.Node.Index) link.EmitError!void {1106 fn infoEntry(ctx: @This(), ni: MappedFile.Node.Index) link.EmitError!void {
1123 try ctx.debug.infoSectionOffset(node, 0);1107 try ctx.debug.wip_nav.dwarf.sectionOffset(&ctx.debug.info_writer, ni, 0);
1124 }1108 }
1125 } = .{ .debug = debug };1109 } = .{ .debug = debug };
1126 try adapter.writer().writeUleb128(counter.dw.fullCount());1110 try adapter.writer().writeUleb128(counter.dw.fullCount());
...@@ -1131,28 +1115,37 @@ pub const WipNav = struct {...@@ -1131,28 +1115,37 @@ pub const WipNav = struct {
1131 try debug.wip_nav.dwarf.symbolAddress(&debug.info_writer, si, addend);1115 try debug.wip_nav.dwarf.symbolAddress(&debug.info_writer, si, addend);
1132 }1116 }
11331117
1134 fn refNav(debug: *Debug, nav_index: InternPool.Nav.Index) link.EmitError!void {1118 fn refFunc(debug: *Debug, func: InternPool.Index) link.EmitError!void {
1135 try debug.infoSectionOffset(try debug.wip_nav.dwarf.getNavNode(nav_index), 0);1119 const dwarf = debug.wip_nav.dwarf;
1120 const fi = try dwarf.getFunc(debug.pt.zcu.funcInfo(func).owner_nav);
1121 try debug.wip_nav.dwarf.sectionOffset(
1122 &debug.info_writer,
1123 fi.get(dwarf).debug_info_ni.unwrap().?,
1124 0,
1125 );
1136 }1126 }
11371127
1138 fn refType(debug: *Debug, ty: Type) link.EmitError!void {1128 fn refType(debug: *Debug, ty: ZigType) link.EmitError!void {
1139 return debug.refValue(ty.toValue());1129 return debug.refValue(ty.toValue());
1140 }1130 }
11411131
1142 fn refValue(debug: *Debug, value: Value) link.EmitError!void {1132 fn refValue(debug: *Debug, value: ZigValue) link.EmitError!void {
1143 try debug.infoSectionOffset(.debug_info, try debug.getValueNode(value), 0);1133 try debug.wip_nav.dwarf.sectionOffset(&debug.info_writer, try debug.getValueNode(value), 0);
1144 }1134 }
11451135
1146 fn getValueNode(debug: *Debug, value: Value) link.Error!MappedFile.Node.Index {1136 fn getValueNode(debug: *Debug, value: ZigValue) link.Error!MappedFile.Node.Index {
1147 if (value.typeOf(debug.zcu).toIntern() != .type_type) {1137 const zcu = debug.pt.zcu;
1148 assert(value.typeOf(debug.zcu).comptimeOnly(debug.zcu));1138 if (value.typeOf(zcu).toIntern() != .type_type) {
1139 assert(value.typeOf(zcu).comptimeOnly(zcu));
1149 }1140 }
1150 const dwarf = debug.wip_nav.dwarf;1141 const dwarf = debug.wip_nav.dwarf;
1151 const index = try dwarf.const_pool.get(debug.pt, .{ .dwarf = dwarf }, value.toIntern());1142 const index = try dwarf.const_pool.get(debug.pt, .{
1152 return dwarf.values.items[@backingInt(index)];1143 .elf2 = dwarf.lf.cast(.elf2).?,
1144 }, value.toIntern());
1145 return dwarf.values.items[@backingInt(index)].debug_info_ni;
1153 }1146 }
11541147
1155 fn blockValue(debug: *Debug, val: Value) link.EmitError!void {1148 fn blockValue(debug: *Debug, val: ZigValue) link.EmitError!void {
1156 const ty = val.typeOf(debug.pt.zcu);1149 const ty = val.typeOf(debug.pt.zcu);
1157 const diw = &debug.info_writer.interface;1150 const diw = &debug.info_writer.interface;
1158 const size = ty.abiSize(debug.pt.zcu);1151 const size = ty.abiSize(debug.pt.zcu);
...@@ -1190,7 +1183,7 @@ pub const WipNav = struct {...@@ -1190,7 +1183,7 @@ pub const WipNav = struct {
1190 };1183 };
1191 }1184 }
1192 fn genDebugFrameHeaderInner(wip_nav: *WipNav) link.EmitError!void {1185 fn genDebugFrameHeaderInner(wip_nav: *WipNav) link.EmitError!void {
1193 assert(wip_nav.func != null);1186 assert(wip_nav.func != .none);
1194 const dwarf = wip_nav.dwarf;1187 const dwarf = wip_nav.dwarf;
1195 const dfw = &wip_nav.fde_writer.interface;1188 const dfw = &wip_nav.fde_writer.interface;
1196 try dwarf.genUnitLength(dfw);1189 try dwarf.genUnitLength(dfw);
...@@ -1214,7 +1207,11 @@ pub const WipNav = struct {...@@ -1214,7 +1207,11 @@ pub const WipNav = struct {
1214 try dfw.writeUleb128(0);1207 try dfw.writeUleb128(0);
1215 },1208 },
1216 .debug_frame => {1209 .debug_frame => {
1217 try wip_nav.frameSectionOffset(wip_nav.unit.get(dwarf).cie_ni.unwrap().?, 0);1210 try dwarf.sectionOffset(
1211 &wip_nav.fde_writer,
1212 wip_nav.unit.get(dwarf).cie_ni.unwrap().?,
1213 0,
1214 );
1218 try wip_nav.frameAddrSym(wip_nav.func_si, 0);1215 try wip_nav.frameAddrSym(wip_nav.func_si, 0);
1219 wip_nav.frame_func_length = .{ .offset = dfw.end, .size = dwarf.address_size };1216 wip_nav.frame_func_length = .{ .offset = dfw.end, .size = dwarf.address_size };
1220 try dfw.splatByteAll(undefined, @backingInt(dwarf.address_size));1217 try dfw.splatByteAll(undefined, @backingInt(dwarf.address_size));
...@@ -1229,7 +1226,7 @@ pub const WipNav = struct {...@@ -1229,7 +1226,7 @@ pub const WipNav = struct {
1229 };1226 };
1230 }1227 }
1231 fn genDebugFrameInner(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.EmitError!void {1228 fn genDebugFrameInner(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.EmitError!void {
1232 assert(wip_nav.func != null);1229 assert(wip_nav.func != .none);
1233 const loc_cfa: Cfa = .{ .advance_loc = loc };1230 const loc_cfa: Cfa = .{ .advance_loc = loc };
1234 try loc_cfa.write(wip_nav);1231 try loc_cfa.write(wip_nav);
1235 try cfa.write(wip_nav);1232 try cfa.write(wip_nav);
...@@ -1284,14 +1281,6 @@ pub const WipNav = struct {...@@ -1284,14 +1281,6 @@ pub const WipNav = struct {
1284 }1281 }
1285 };1282 };
12861283
1287 fn frameSectionOffset(
1288 wip_nav: *WipNav,
1289 target_ni: MappedFile.Node.Index,
1290 addend: usize,
1291 ) link.EmitError!void {
1292 try wip_nav.dwarf.sectionOffset(&wip_nav.fde_writer, target_ni, addend);
1293 }
1294
1295 fn frameExprLoc(wip_nav: *WipNav, loc: Loc) link.EmitError!void {1284 fn frameExprLoc(wip_nav: *WipNav, loc: Loc) link.EmitError!void {
1296 var buf: [64]u8 = undefined;1285 var buf: [64]u8 = undefined;
1297 var counter: ExprLocCounter = .init(wip_nav.dwarf, &buf);1286 var counter: ExprLocCounter = .init(wip_nav.dwarf, &buf);
...@@ -1308,8 +1297,8 @@ pub const WipNav = struct {...@@ -1308,8 +1297,8 @@ pub const WipNav = struct {
1308 fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void {1297 fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void {
1309 try ctx.wip_nav.frameAddrSym(si, 0);1298 try ctx.wip_nav.frameAddrSym(si, 0);
1310 }1299 }
1311 fn infoEntry(ctx: @This(), node: MappedFile.Node.Index) link.EmitError!void {1300 fn infoEntry(ctx: @This(), ni: MappedFile.Node.Index) link.EmitError!void {
1312 try ctx.wip_nav.frameSectionOffset(node, 0);1301 try ctx.wip_nav.dwarf.sectionOffset(&ctx.wip_nav.fde_writer, ni, 0);
1313 }1302 }
1314 } = .{ .wip_nav = wip_nav };1303 } = .{ .wip_nav = wip_nav };
1315 try adapter.writer().writeUleb128(counter.dw.fullCount());1304 try adapter.writer().writeUleb128(counter.dw.fullCount());
...@@ -1476,33 +1465,57 @@ pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {...@@ -1476,33 +1465,57 @@ pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {
1476 return @fromBackingInt(@intCast(dwarf.units.getIndex(mod).?));1465 return @fromBackingInt(@intCast(dwarf.units.getIndex(mod).?));
1477}1466}
14781467
1479fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) link.Error!MappedFile.Node.Index {1468pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) link.Error!Func.Index {
1480 if (true) @panic("TODO");1469 const comp = dwarf.lf.comp;
1481 const zcu = dwarf.linkFile().comp.zcu.?;1470 const gpa = comp.gpa;
1482 const ip = &zcu.intern_pool;1471 const func_gop = try dwarf.funcs.getOrPut(gpa, owner_nav);
1483 const nav = ip.getNav(nav_index);
1484 const unit = try dwarf.getUnit(zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?);
1485 const gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
1486 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
1487 const entry = try dwarf.addCommonEntry(unit);
1488 gop.value_ptr.* = entry;
1489 return .{ unit, entry };
1490}
1491
1492pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) std.mem.Allocator.Error!Func.Index {
1493 const func_gop = try dwarf.funcs.getOrPut(dwarf.lf.comp.gpa, owner_nav);
1494 if (!func_gop.found_existing) func_gop.value_ptr.* = .{1472 if (!func_gop.found_existing) func_gop.value_ptr.* = .{
1495 .fde_ni = .none,1473 .fde_ni = .none,
1496 .debug_info_ni = .none,1474 .debug_info_ni = .none,
1497 .debug_line_ni = .none,1475 .debug_line_ni = .none,
1498 };1476 };
1499 return @fromBackingInt(@intCast(func_gop.index));1477 const fi: Func.Index = @fromBackingInt(@intCast(func_gop.index));
1478 if (func_gop.value_ptr.debug_info_ni == .none) {
1479 const elf = dwarf.lf.cast(.elf2).?;
1480 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1481 try elf.dwarf_funcs.ensureUnusedCapacity(gpa, 1);
1482 const unit = dwarf.getUnit(comp.zcu.?.navFileScope(owner_nav).mod.?).get(dwarf);
1483 func_gop.value_ptr.debug_info_ni =
1484 .wrap(unit.debug_info_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{
1485 .enable_next_moved = true,
1486 }) catch |err| switch (err) {
1487 else => |e| return e,
1488 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1489 elf.mf.io_err.?,
1490 }),
1491 });
1492 elf.nodes.appendAssumeCapacity(.{ .func_debug_info = fi });
1493 elf.dwarf_funcs.addOneAssumeCapacity().* = .{
1494 .frame_fde_first_symbol_reloc = .none,
1495 .frame_fde_first_node_reloc = .none,
1496 .debug_info_first_target_reloc = .none,
1497 .debug_info_first_symbol_reloc = .none,
1498 .debug_info_first_node_reloc = .none,
1499 .debug_line_first_symbol_reloc = .none,
1500 .debug_line_first_node_reloc = .none,
1501 };
1502 }
1503 return fi;
1504}
1505pub fn getFuncIfExists(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) ?Func.Index {
1506 return @fromBackingInt(@intCast(dwarf.funcs.getIndex(owner_nav) orelse return null));
1500}1507}
15011508
1502pub fn unitLengthSize(dwarf: *Dwarf) usize {1509pub fn unitLengthSize(dwarf: *Dwarf) usize {
1503 return switch (dwarf.format) {1510 return switch (dwarf.format) {
1504 .@"32" => 4,1511 .@"32" => 4,
1505 .@"64" => 12,1512 .@"64" => 4 + 8,
1513 };
1514}
1515pub fn sectionOffsetSize(dwarf: *Dwarf) usize {
1516 return switch (dwarf.format) {
1517 .@"32" => 4,
1518 .@"64" => 8,
1506 };1519 };
1507}1520}
1508pub fn genUnitLength(dwarf: *Dwarf, w: *Writer) Writer.Error!void {1521pub fn genUnitLength(dwarf: *Dwarf, w: *Writer) Writer.Error!void {
...@@ -1896,8 +1909,9 @@ fn refAbbrevCode(...@@ -1896,8 +1909,9 @@ fn refAbbrevCode(
1896 return backing_int;1909 return backing_int;
1897 }1910 }
1898 const elf = dwarf.lf.cast(.elf2).?;1911 const elf = dwarf.lf.cast(.elf2).?;
1912 const comp = elf.base.comp;
1899 var nw: MappedFile.Node.Writer = undefined;1913 var nw: MappedFile.Node.Writer = undefined;
1900 dwarf.debug_abbrev.ni.unwrap().?.writer(&elf.mf, elf.base.comp.gpa, &nw);1914 dwarf.debug_abbrev.ni.unwrap().?.writer(&elf.mf, comp.gpa, &nw);
1901 defer nw.deinit();1915 defer nw.deinit();
1902 const abbrev = AbbrevCode.abbrevs.get(abbrev_code);1916 const abbrev = AbbrevCode.abbrevs.get(abbrev_code);
1903 const daw = &nw.interface;1917 const daw = &nw.interface;
...@@ -1905,7 +1919,13 @@ fn refAbbrevCode(...@@ -1905,7 +1919,13 @@ fn refAbbrevCode(
1905 try daw.writeUleb128(@backingInt(abbrev_code));1919 try daw.writeUleb128(@backingInt(abbrev_code));
1906 try daw.writeUleb128(@backingInt(abbrev.tag));1920 try daw.writeUleb128(@backingInt(abbrev.tag));
1907 try daw.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);1921 try daw.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
1908 for (abbrev.attrs) |*attr| inline for (attr) |info| try daw.writeUleb128(@backingInt(info));1922 for (abbrev.attrs) |*attr| {
1923 try daw.writeUleb128(@backingInt(switch (attr[0]) {
1924 else => |at| at,
1925 .ZIG_call_line_relative => |at| if (comp.config.incremental) at else .call_line,
1926 }));
1927 try daw.writeUleb128(@backingInt(attr[1]));
1928 }
1909 for (0..2) |_| try daw.writeUleb128(0);1929 for (0..2) |_| try daw.writeUleb128(0);
1910 dwarf.debug_abbrev.offset = daw.end;1930 dwarf.debug_abbrev.offset = daw.end;
1911 dwarf.debug_abbrev.set.insert(abbrev_code);1931 dwarf.debug_abbrev.set.insert(abbrev_code);
...@@ -2958,7 +2978,7 @@ pub const AbbrevCode = enum {...@@ -2958,7 +2978,7 @@ pub const AbbrevCode = enum {
2958 .tag = .inlined_subroutine,2978 .tag = .inlined_subroutine,
2959 .attrs = &.{2979 .attrs = &.{
2960 .{ .abstract_origin, .ref_addr },2980 .{ .abstract_origin, .ref_addr },
2961 .{ .call_line, .udata },2981 .{ .ZIG_call_line_relative, .udata },
2962 .{ .call_column, .udata },2982 .{ .call_column, .udata },
2963 .{ .low_pc, .addr },2983 .{ .low_pc, .addr },
2964 .{ .high_pc, .data4 },2984 .{ .high_pc, .data4 },
...@@ -2969,7 +2989,7 @@ pub const AbbrevCode = enum {...@@ -2969,7 +2989,7 @@ pub const AbbrevCode = enum {
2969 .children = true,2989 .children = true,
2970 .attrs = &.{2990 .attrs = &.{
2971 .{ .abstract_origin, .ref_addr },2991 .{ .abstract_origin, .ref_addr },
2972 .{ .call_line, .udata },2992 .{ .ZIG_call_line_relative, .udata },
2973 .{ .call_column, .udata },2993 .{ .call_column, .udata },
2974 .{ .low_pc, .addr },2994 .{ .low_pc, .addr },
2975 .{ .high_pc, .data4 },2995 .{ .high_pc, .data4 },
...@@ -2979,14 +2999,14 @@ pub const AbbrevCode = enum {...@@ -2979,14 +2999,14 @@ pub const AbbrevCode = enum {
2979 .tag = .formal_parameter,2999 .tag = .formal_parameter,
2980 .attrs = &.{3000 .attrs = &.{
2981 .{ .name, .strp },3001 .{ .name, .strp },
2982 .{ .type, .ref_addr },3002 //.{ .type, .ref_addr },
2983 .{ .location, .exprloc },3003 .{ .location, .exprloc },
2984 },3004 },
2985 },3005 },
2986 .unnamed_arg = .{3006 .unnamed_arg = .{
2987 .tag = .formal_parameter,3007 .tag = .formal_parameter,
2988 .attrs = &.{3008 .attrs = &.{
2989 .{ .type, .ref_addr },3009 //.{ .type, .ref_addr },
2990 .{ .location, .exprloc },3010 .{ .location, .exprloc },
2991 },3011 },
2992 },3012 },
...@@ -2995,14 +3015,14 @@ pub const AbbrevCode = enum {...@@ -2995,14 +3015,14 @@ pub const AbbrevCode = enum {
2995 .attrs = &.{3015 .attrs = &.{
2996 .{ .const_expr, .flag_present },3016 .{ .const_expr, .flag_present },
2997 .{ .name, .strp },3017 .{ .name, .strp },
2998 .{ .type, .ref_addr },3018 //.{ .type, .ref_addr },
2999 },3019 },
3000 },3020 },
3001 .unnamed_comptime_arg = .{3021 .unnamed_comptime_arg = .{
3002 .tag = .formal_parameter,3022 .tag = .formal_parameter,
3003 .attrs = &.{3023 .attrs = &.{
3004 .{ .const_expr, .flag_present },3024 .{ .const_expr, .flag_present },
3005 .{ .type, .ref_addr },3025 //.{ .type, .ref_addr },
3006 },3026 },
3007 },3027 },
3008 .comptime_arg_runtime_bits = .{3028 .comptime_arg_runtime_bits = .{
...@@ -3010,7 +3030,7 @@ pub const AbbrevCode = enum {...@@ -3010,7 +3030,7 @@ pub const AbbrevCode = enum {
3010 .attrs = &.{3030 .attrs = &.{
3011 .{ .const_expr, .flag_present },3031 .{ .const_expr, .flag_present },
3012 .{ .name, .strp },3032 .{ .name, .strp },
3013 .{ .type, .ref_addr },3033 //.{ .type, .ref_addr },
3014 .{ .const_value, .block },3034 .{ .const_value, .block },
3015 },3035 },
3016 },3036 },
...@@ -3018,7 +3038,7 @@ pub const AbbrevCode = enum {...@@ -3018,7 +3038,7 @@ pub const AbbrevCode = enum {
3018 .tag = .formal_parameter,3038 .tag = .formal_parameter,
3019 .attrs = &.{3039 .attrs = &.{
3020 .{ .const_expr, .flag_present },3040 .{ .const_expr, .flag_present },
3021 .{ .type, .ref_addr },3041 //.{ .type, .ref_addr },
3022 .{ .const_value, .block },3042 .{ .const_value, .block },
3023 },3043 },
3024 },3044 },
...@@ -3027,16 +3047,16 @@ pub const AbbrevCode = enum {...@@ -3027,16 +3047,16 @@ pub const AbbrevCode = enum {
3027 .attrs = &.{3047 .attrs = &.{
3028 .{ .const_expr, .flag_present },3048 .{ .const_expr, .flag_present },
3029 .{ .name, .strp },3049 .{ .name, .strp },
3030 .{ .type, .ref_addr },3050 //.{ .type, .ref_addr },
3031 .{ .ZIG_comptime_value, .ref_addr },3051 //.{ .ZIG_comptime_value, .ref_addr },
3032 },3052 },
3033 },3053 },
3034 .unnamed_comptime_arg_comptime_state = .{3054 .unnamed_comptime_arg_comptime_state = .{
3035 .tag = .formal_parameter,3055 .tag = .formal_parameter,
3036 .attrs = &.{3056 .attrs = &.{
3037 .{ .const_expr, .flag_present },3057 .{ .const_expr, .flag_present },
3038 .{ .type, .ref_addr },3058 //.{ .type, .ref_addr },
3039 .{ .ZIG_comptime_value, .ref_addr },3059 //.{ .ZIG_comptime_value, .ref_addr },
3040 },3060 },
3041 },3061 },
3042 .comptime_arg_runtime_bits_comptime_state = .{3062 .comptime_arg_runtime_bits_comptime_state = .{
...@@ -3044,31 +3064,31 @@ pub const AbbrevCode = enum {...@@ -3044,31 +3064,31 @@ pub const AbbrevCode = enum {
3044 .attrs = &.{3064 .attrs = &.{
3045 .{ .const_expr, .flag_present },3065 .{ .const_expr, .flag_present },
3046 .{ .name, .strp },3066 .{ .name, .strp },
3047 .{ .type, .ref_addr },3067 //.{ .type, .ref_addr },
3048 .{ .const_value, .block },3068 .{ .const_value, .block },
3049 .{ .ZIG_comptime_value, .ref_addr },3069 //.{ .ZIG_comptime_value, .ref_addr },
3050 },3070 },
3051 },3071 },
3052 .unnamed_comptime_arg_runtime_bits_comptime_state = .{3072 .unnamed_comptime_arg_runtime_bits_comptime_state = .{
3053 .tag = .formal_parameter,3073 .tag = .formal_parameter,
3054 .attrs = &.{3074 .attrs = &.{
3055 .{ .const_expr, .flag_present },3075 .{ .const_expr, .flag_present },
3056 .{ .type, .ref_addr },3076 //.{ .type, .ref_addr },
3057 .{ .const_value, .block },3077 .{ .const_value, .block },
3058 .{ .ZIG_comptime_value, .ref_addr },3078 //.{ .ZIG_comptime_value, .ref_addr },
3059 },3079 },
3060 },3080 },
3061 .extern_param = .{3081 .extern_param = .{
3062 .tag = .formal_parameter,3082 .tag = .formal_parameter,
3063 .attrs = &.{3083 .attrs = &.{
3064 .{ .type, .ref_addr },3084 //.{ .type, .ref_addr },
3065 },3085 },
3066 },3086 },
3067 .local_var = .{3087 .local_var = .{
3068 .tag = .variable,3088 .tag = .variable,
3069 .attrs = &.{3089 .attrs = &.{
3070 .{ .name, .strp },3090 .{ .name, .strp },
3071 .{ .type, .ref_addr },3091 //.{ .type, .ref_addr },
3072 .{ .location, .exprloc },3092 .{ .location, .exprloc },
3073 },3093 },
3074 },3094 },
...@@ -3076,14 +3096,14 @@ pub const AbbrevCode = enum {...@@ -3076,14 +3096,14 @@ pub const AbbrevCode = enum {
3076 .tag = .constant,3096 .tag = .constant,
3077 .attrs = &.{3097 .attrs = &.{
3078 .{ .name, .strp },3098 .{ .name, .strp },
3079 .{ .type, .ref_addr },3099 //.{ .type, .ref_addr },
3080 },3100 },
3081 },3101 },
3082 .local_const_runtime_bits = .{3102 .local_const_runtime_bits = .{
3083 .tag = .constant,3103 .tag = .constant,
3084 .attrs = &.{3104 .attrs = &.{
3085 .{ .name, .strp },3105 .{ .name, .strp },
3086 .{ .type, .ref_addr },3106 //.{ .type, .ref_addr },
3087 .{ .const_value, .block },3107 .{ .const_value, .block },
3088 },3108 },
3089 },3109 },
...@@ -3091,17 +3111,17 @@ pub const AbbrevCode = enum {...@@ -3091,17 +3111,17 @@ pub const AbbrevCode = enum {
3091 .tag = .constant,3111 .tag = .constant,
3092 .attrs = &.{3112 .attrs = &.{
3093 .{ .name, .strp },3113 .{ .name, .strp },
3094 .{ .type, .ref_addr },3114 //.{ .type, .ref_addr },
3095 .{ .ZIG_comptime_value, .ref_addr },3115 //.{ .ZIG_comptime_value, .ref_addr },
3096 },3116 },
3097 },3117 },
3098 .local_const_runtime_bits_comptime_state = .{3118 .local_const_runtime_bits_comptime_state = .{
3099 .tag = .constant,3119 .tag = .constant,
3100 .attrs = &.{3120 .attrs = &.{
3101 .{ .name, .strp },3121 .{ .name, .strp },
3102 .{ .type, .ref_addr },3122 //.{ .type, .ref_addr },
3103 .{ .const_value, .block },3123 .{ .const_value, .block },
3104 .{ .ZIG_comptime_value, .ref_addr },3124 //.{ .ZIG_comptime_value, .ref_addr },
3105 },3125 },
3106 },3126 },
3107 .undefined_comptime_value = .{3127 .undefined_comptime_value = .{
...@@ -3202,7 +3222,7 @@ const link = @import("../link.zig");...@@ -3202,7 +3222,7 @@ const link = @import("../link.zig");
3202const MappedFile = @import("MappedFile.zig");3222const MappedFile = @import("MappedFile.zig");
3203const Module = @import("../Module.zig");3223const Module = @import("../Module.zig");
3204const std = @import("std");3224const std = @import("std");
3205const Type = @import("../Type.zig");3225const ZigType = @import("../Type.zig");
3206const Value = @import("../Value.zig");3226const ZigValue = @import("../Value.zig");
3207const Writer = std.Io.Writer;3227const Writer = std.Io.Writer;
3208const Zcu = @import("../Zcu.zig");3228const Zcu = @import("../Zcu.zig");
src/link/Elf2.zig+61-63
...@@ -22,7 +22,18 @@ const Alignment = MappedFile.Alignment;...@@ -22,7 +22,18 @@ const Alignment = MappedFile.Alignment;
22base: link.File,22base: link.File,
23options: link.File.OpenOptions,23options: link.File.OpenOptions,
24mf: MappedFile,24mf: MappedFile,
25ni: Node.Known,25ni: struct {
26 elf: MappedFile.Node.Index,
27 ehdr: MappedFile.Node.Index,
28 shdr: MappedFile.Node.Index,
29 rodata: MappedFile.Node.Index,
30 phdr: MappedFile.Node.Index,
31 text: MappedFile.Node.Index,
32 data: MappedFile.Node.Index,
33 data_rel_ro: MappedFile.Node.Index,
34 tls: MappedFile.Node.Index.Optional,
35 gnu_eh_frame: MappedFile.Node.Index.Optional,
36},
26archive: ?Archive,37archive: ?Archive,
27nodes: std.MultiArrayList(Node),38nodes: std.MultiArrayList(Node),
28/// Does not contain an item for `SHN_UNDEF`.39/// Does not contain an item for `SHN_UNDEF`.
...@@ -346,7 +357,7 @@ const Node = union(enum) {...@@ -346,7 +357,7 @@ const Node = union(enum) {
346 pub const NavMapIndex = enum(u32) {357 pub const NavMapIndex = enum(u32) {
347 _,358 _,
348359
349 pub fn navIndex(nmi: NavMapIndex, elf: *const Elf) InternPool.Nav.Index {360 pub fn nav(nmi: NavMapIndex, elf: *const Elf) InternPool.Nav.Index {
350 return elf.navs.keys()[@backingInt(nmi)];361 return elf.navs.keys()[@backingInt(nmi)];
351 }362 }
352363
...@@ -424,19 +435,6 @@ const Node = union(enum) {...@@ -424,19 +435,6 @@ const Node = union(enum) {
424 }435 }
425 };436 };
426437
427 pub const Known = struct {
428 elf: MappedFile.Node.Index,
429 ehdr: MappedFile.Node.Index,
430 shdr: MappedFile.Node.Index,
431 rodata: MappedFile.Node.Index,
432 phdr: MappedFile.Node.Index,
433 text: MappedFile.Node.Index,
434 data: MappedFile.Node.Index,
435 data_rel_ro: MappedFile.Node.Index,
436 tls: MappedFile.Node.Index.Optional,
437 gnu_eh_frame: MappedFile.Node.Index.Optional,
438 };
439
440 comptime {438 comptime {
441 if (!std.debug.runtime_safety) std.debug.assert(@sizeOf(Node) == 8);439 if (!std.debug.runtime_safety) std.debug.assert(@sizeOf(Node) == 8);
442 }440 }
...@@ -3464,7 +3462,11 @@ pub fn getUavVAddr(...@@ -3464,7 +3462,11 @@ pub fn getUavVAddr(
3464}3462}
3465pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.SymbolId) link.Error!u64 {3463pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.SymbolId) link.Error!u64 {
3466 try elf.addReloc(3464 try elf.addReloc(
3467 reloc_info.parent.atom_index,3465 switch (reloc_info.parent) {
3466 .none => unreachable,
3467 .atom_index => |atom_id| atom_id,
3468 .debug_output => |debug_output| Node.toAtom(debug_output.dwarf2.info_writer.ni),
3469 },
3468 reloc_info.offset,3470 reloc_info.offset,
3469 target,3471 target,
3470 reloc_info.addend,3472 reloc_info.addend,
...@@ -5221,9 +5223,10 @@ fn getNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5221,9 +5223,10 @@ fn getNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5221/// the special-case sections '.plt', '.dynamic', and '.eh_frame_hdr'.5223/// the special-case sections '.plt', '.dynamic', and '.eh_frame_hdr'.
5222fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {5224fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5223 const opts: struct {5225 const opts: struct {
5224 ignore_node: MappedFile.Node.Index.Optional = .none,
5225 first_symbol_reloc: ?*SymbolReloc.Index = null,5226 first_symbol_reloc: ?*SymbolReloc.Index = null,
5227 skip_symbol_relocs: MappedFile.Node.Index.Optional = .none,
5226 first_node_reloc: ?*NodeReloc.Index = null,5228 first_node_reloc: ?*NodeReloc.Index = null,
5229 skip_node_relocs: MappedFile.Node.Index.Optional = .none,
5227 first_got_reloc: ?*GotReloc.Index = null,5230 first_got_reloc: ?*GotReloc.Index = null,
5228 } = switch (elf.getNode(ni)) {5231 } = switch (elf.getNode(ni)) {
5229 .archive,5232 .archive,
...@@ -5280,21 +5283,25 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5280,21 +5283,25 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5280 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_node_reloc,5283 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_node_reloc,
5281 },5284 },
5282 .func_debug_info => |fi| .{5285 .func_debug_info => |fi| .{
5283 .ignore_node = fi.get(&elf.dwarf).debug_line_ni,
5284 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc,5286 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc,
5287 .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav|
5288 nav.lsi.index().ptr(elf).node
5289 else
5290 .none,
5285 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc,5291 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc,
5292 .skip_node_relocs = fi.get(&elf.dwarf).debug_line_ni,
5286 },5293 },
5287 .func_debug_line => |fi| .{5294 .func_debug_line => |fi| .{
5288 .ignore_node = fi.get(&elf.dwarf).debug_info_ni,
5289 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_symbol_reloc,5295 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_symbol_reloc,
5290 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_node_reloc,5296 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_node_reloc,
5297 .skip_node_relocs = fi.get(&elf.dwarf).debug_info_ni,
5291 },5298 },
5292 };5299 };
52935300
5294 if (opts.first_symbol_reloc) |ptr| {5301 if (opts.first_symbol_reloc) |ptr| {
5295 if (ptr.* != .none) {5302 if (ptr.* != .none) {
5296 for (elf.symbol_relocs.items[@backingInt(ptr.*)..], @backingInt(ptr.*)..) |*reloc, index| {5303 for (elf.symbol_relocs.items[@backingInt(ptr.*)..], @backingInt(ptr.*)..) |*reloc, index| {
5297 if (reloc.node.toOptional() == opts.ignore_node) continue;5304 if (reloc.node.toOptional() == opts.skip_symbol_relocs) continue;
5298 if (reloc.node != ni) break;5305 if (reloc.node != ni) break;
5299 reloc.delete(elf, @fromBackingInt(@intCast(index)));5306 reloc.delete(elf, @fromBackingInt(@intCast(index)));
5300 }5307 }
...@@ -5305,7 +5312,7 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5305,7 +5312,7 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5305 if (opts.first_node_reloc) |ptr| {5312 if (opts.first_node_reloc) |ptr| {
5306 if (ptr.* != .none) {5313 if (ptr.* != .none) {
5307 for (elf.node_relocs.items[@backingInt(ptr.*)..]) |*reloc| {5314 for (elf.node_relocs.items[@backingInt(ptr.*)..]) |*reloc| {
5308 if (reloc.node.toOptional() == opts.ignore_node) continue;5315 if (reloc.node.toOptional() == opts.skip_node_relocs) continue;
5309 if (reloc.node != ni) break;5316 if (reloc.node != ni) break;
5310 reloc.delete(elf);5317 reloc.delete(elf);
5311 }5318 }
...@@ -5316,7 +5323,6 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5316,7 +5323,6 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5316 if (opts.first_got_reloc) |ptr| {5323 if (opts.first_got_reloc) |ptr| {
5317 if (ptr.* != .none) {5324 if (ptr.* != .none) {
5318 for (elf.got_relocs.items[@backingInt(ptr.*)..]) |*reloc| {5325 for (elf.got_relocs.items[@backingInt(ptr.*)..]) |*reloc| {
5319 if (reloc.node == opts.ignore_node) continue;
5320 if (reloc.node != ni.toOptional()) break;5326 if (reloc.node != ni.toOptional()) break;
5321 reloc.delete(elf);5327 reloc.delete(elf);
5322 }5328 }
...@@ -5332,15 +5338,16 @@ fn flushMovedNodeRelocs(...@@ -5332,15 +5338,16 @@ fn flushMovedNodeRelocs(
5332 node: MappedFile.Node.Index,5338 node: MappedFile.Node.Index,
5333 node_vaddr: u64,5339 node_vaddr: u64,
5334 opts: struct {5340 opts: struct {
5335 ignore_node: MappedFile.Node.Index.Optional = .none,
5336 first_symbol_reloc: SymbolReloc.Index = .none,5341 first_symbol_reloc: SymbolReloc.Index = .none,
5342 skip_symbol_relocs: MappedFile.Node.Index.Optional = .none,
5337 first_node_reloc: NodeReloc.Index = .none,5343 first_node_reloc: NodeReloc.Index = .none,
5344 skip_node_relocs: MappedFile.Node.Index.Optional = .none,
5338 first_got_reloc: GotReloc.Index = .none,5345 first_got_reloc: GotReloc.Index = .none,
5339 },5346 },
5340) void {5347) void {
5341 if (opts.first_symbol_reloc != .none) {5348 if (opts.first_symbol_reloc != .none) {
5342 for (elf.symbol_relocs.items[@backingInt(opts.first_symbol_reloc)..]) |*reloc| {5349 for (elf.symbol_relocs.items[@backingInt(opts.first_symbol_reloc)..]) |*reloc| {
5343 if (reloc.node.toOptional() == opts.ignore_node) continue;5350 if (reloc.node.toOptional() == opts.skip_symbol_relocs) continue;
5344 if (reloc.node != node) break;5351 if (reloc.node != node) break;
5345 if (reloc.rela_index.unwrap()) |rela_index| {5352 if (reloc.rela_index.unwrap()) |rela_index| {
5346 // The node has moved, so the offset of the relocation within the section might have5353 // The node has moved, so the offset of the relocation within the section might have
...@@ -5358,7 +5365,7 @@ fn flushMovedNodeRelocs(...@@ -5358,7 +5365,7 @@ fn flushMovedNodeRelocs(
53585365
5359 if (opts.first_node_reloc != .none) {5366 if (opts.first_node_reloc != .none) {
5360 for (elf.node_relocs.items[@backingInt(opts.first_node_reloc)..]) |*reloc| {5367 for (elf.node_relocs.items[@backingInt(opts.first_node_reloc)..]) |*reloc| {
5361 if (reloc.node.toOptional() == opts.ignore_node) continue;5368 if (reloc.node.toOptional() == opts.skip_node_relocs) continue;
5362 if (reloc.node != node) break;5369 if (reloc.node != node) break;
5363 if (reloc.rela_index.unwrap()) |rela_index| {5370 if (reloc.rela_index.unwrap()) |rela_index| {
5364 assert(elf.ehdrType() == .REL);5371 assert(elf.ehdrType() == .REL);
...@@ -5374,7 +5381,6 @@ fn flushMovedNodeRelocs(...@@ -5374,7 +5381,6 @@ fn flushMovedNodeRelocs(
53745381
5375 if (opts.first_got_reloc != .none) {5382 if (opts.first_got_reloc != .none) {
5376 for (elf.got_relocs.items[@backingInt(opts.first_got_reloc)..]) |*reloc| {5383 for (elf.got_relocs.items[@backingInt(opts.first_got_reloc)..]) |*reloc| {
5377 if (reloc.node == opts.ignore_node) continue;
5378 if (reloc.node != node.toOptional()) break;5384 if (reloc.node != node.toOptional()) break;
5379 reloc.apply(elf);5385 reloc.apply(elf);
5380 }5386 }
...@@ -7193,6 +7199,7 @@ fn flushFiles(elf: *Elf) Error!void {...@@ -7193,6 +7199,7 @@ fn flushFiles(elf: *Elf) Error!void {
7193 if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| {7199 if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| {
7194 if (!unit.cleanDebugLineHeaderChanged()) continue;7200 if (!unit.cleanDebugLineHeaderChanged()) continue;
7195 const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?;7201 const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?;
7202 try debug_line_header_ni.parent(&elf.mf).unwrap().?.nextMoved(gpa, &elf.mf);
7196 try debug_line_header_ni.moved(gpa, &elf.mf);7203 try debug_line_header_ni.moved(gpa, &elf.mf);
7197 try debug_line_header_ni.nextMoved(gpa, &elf.mf);7204 try debug_line_header_ni.nextMoved(gpa, &elf.mf);
7198 var dlh_nw: MappedFile.Node.Writer = undefined;7205 var dlh_nw: MappedFile.Node.Writer = undefined;
...@@ -8553,21 +8560,12 @@ fn updateFuncInner(...@@ -8553,21 +8560,12 @@ fn updateFuncInner(
85538560
8554 try elf.nodes.ensureUnusedCapacity(gpa, 5);8561 try elf.nodes.ensureUnusedCapacity(gpa, 5);
8555 const dwarf_fi = try dwarf.getFunc(func.owner_nav);8562 const dwarf_fi = try dwarf.getFunc(func.owner_nav);
8556 try elf.dwarf_funcs.appendNTimes(gpa, .{
8557 .frame_fde_first_symbol_reloc = .none,
8558 .frame_fde_first_node_reloc = .none,
8559 .debug_info_first_target_reloc = .none,
8560 .debug_info_first_symbol_reloc = .none,
8561 .debug_info_first_node_reloc = .none,
8562 .debug_line_first_symbol_reloc = .none,
8563 .debug_line_first_node_reloc = .none,
8564 }, @backingInt(dwarf_fi) + 1 -| elf.dwarf_funcs.items.len);
85658563
8566 const wip_nav = &debug_output_buf.wip_nav;8564 const wip_nav = &debug_output_buf.wip_nav;
8567 wip_nav.* = .{8565 wip_nav.* = .{
8568 .dwarf = dwarf,8566 .dwarf = dwarf,
8569 .unit = dwarf.getUnit(mod),8567 .unit = dwarf.getUnit(mod),
8570 .func = dwarf_fi,8568 .func = func_index,
8571 .func_si = Symbol.Id.local(lsi).toTypeErased(),8569 .func_si = Symbol.Id.local(lsi).toTypeErased(),
8572 .cfi = .{8570 .cfi = .{
8573 .loc = 0,8571 .loc = 0,
...@@ -8640,33 +8638,20 @@ fn updateFuncInner(...@@ -8640,33 +8638,20 @@ fn updateFuncInner(
8640 debug.pt = pt;8638 debug.pt = pt;
8641 debug.any_children = false;8639 debug.any_children = false;
8642 debug.blocks = .empty;8640 debug.blocks = .empty;
8643 const debug_info_ni = if (dwarf_func.debug_info_ni.unwrap()) |debug_info_ni| debug_info_ni: {8641
8644 try debug_info_ni.moved(gpa, &elf.mf);8642 const debug_info_ni = dwarf_func.debug_info_ni.unwrap().?;
8645 try debug_info_ni.nextMoved(gpa, &elf.mf);8643 try debug_info_ni.moved(gpa, &elf.mf);
8646 break :debug_info_ni debug_info_ni;8644 try debug_info_ni.nextMoved(gpa, &elf.mf);
8647 } else debug_info_ni: {
8648 const debug_info_ni =
8649 try unit.debug_info_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{
8650 .moved = true,
8651 .next_moved = true,
8652 .enable_next_moved = true,
8653 });
8654 dwarf_func.debug_info_ni = .wrap(debug_info_ni);
8655 elf.nodes.appendAssumeCapacity(.{ .func_debug_info = dwarf_fi });
8656 break :debug_info_ni debug_info_ni;
8657 };
8658 debug_info_ni.writer(&elf.mf, gpa, &debug.info_writer);8645 debug_info_ni.writer(&elf.mf, gpa, &debug.info_writer);
8659 const debug_line_ni = if (dwarf_func.debug_line_ni.unwrap()) |debug_line_ni| debug_line_ni: {8646
8660 try debug_line_ni.moved(gpa, &elf.mf);8647 const debug_line_ni = dwarf_func.debug_line_ni.unwrap() orelse debug_line_ni: {
8661 try debug_line_ni.nextMoved(gpa, &elf.mf);
8662 break :debug_line_ni debug_line_ni;
8663 } else debug_line_ni: {
8664 const debug_line_ni =8648 const debug_line_ni =
8665 try unit.debug_line_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{8649 try unit.debug_line_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{
8666 .moved = true,8650 .moved = true,
8667 .next_moved = true,8651 .next_moved = true,
8668 .enable_next_moved = true,8652 .enable_next_moved = true,
8669 });8653 });
8654 dwarf_func.debug_line_ni = .wrap(debug_line_ni);
8670 elf.nodes.appendAssumeCapacity(.{ .func_debug_line = dwarf_fi });8655 elf.nodes.appendAssumeCapacity(.{ .func_debug_line = dwarf_fi });
8671 break :debug_line_ni debug_line_ni;8656 break :debug_line_ni debug_line_ni;
8672 };8657 };
...@@ -8688,9 +8673,10 @@ fn updateFuncInner(...@@ -8688,9 +8673,10 @@ fn updateFuncInner(
8688 .dwarf2 => |debug| {8673 .dwarf2 => |debug| {
8689 elf.resetNodeRelocs(dwarf_func.fde_ni.unwrap().?);8674 elf.resetNodeRelocs(dwarf_func.fde_ni.unwrap().?);
8690 try debug.wip_nav.genDebugFrameHeader();8675 try debug.wip_nav.genDebugFrameHeader();
8691 elf.resetNodeRelocs(dwarf_func.debug_info_ni.unwrap().?);
8692 elf.resetNodeRelocs(dwarf_func.debug_line_ni.unwrap().?);8676 elf.resetNodeRelocs(dwarf_func.debug_line_ni.unwrap().?);
8693 try debug.startFunc();8677 try debug.startDebugLine();
8678 elf.resetNodeRelocs(dwarf_func.debug_info_ni.unwrap().?);
8679 try debug.startDebugInfo();
8694 },8680 },
8695 .none => {},8681 .none => {},
8696 }8682 }
...@@ -9055,7 +9041,7 @@ fn idleProgNode(...@@ -9055,7 +9041,7 @@ fn idleProgNode(
9055 },9041 },
9056 .nav => |nmi| {9042 .nav => |nmi| {
9057 const ip = &elf.base.comp.zcu.?.intern_pool;9043 const ip = &elf.base.comp.zcu.?.intern_pool;
9058 break :name ip.getNav(nmi.navIndex(elf)).fqn.toSlice(ip);9044 break :name ip.getNav(nmi.nav(elf)).fqn.toSlice(ip);
9059 },9045 },
9060 .uav => |umi| std.mem.print(&name, "{f}", .{9046 .uav => |umi| std.mem.print(&name, "{f}", .{
9061 Value.fromInterned(umi.uavValue(elf)).fmtValue(.{ .zcu = elf.base.comp.zcu.?, .tid = tid }),9047 Value.fromInterned(umi.uavValue(elf)).fmtValue(.{ .zcu = elf.base.comp.zcu.?, .tid = tid }),
...@@ -9461,7 +9447,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9461,7 +9447,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
94619447
9462 Symbol.Id.global(global_name).flushMoved(elf, new_addr);9448 Symbol.Id.global(global_name).flushMoved(elf, new_addr);
9463 },9449 },
9464 inline .nav, .uav, .lazy_code, .lazy_const_data => |mi| {9450 inline .nav, .uav, .lazy_code, .lazy_const_data => |mi, tag| {
9465 const new_addr = elf.computeNodeVAddr(ni);9451 const new_addr = elf.computeNodeVAddr(ni);
9466 Symbol.Id.local(mi.symbol(elf)).flushMoved(elf, new_addr);9452 Symbol.Id.local(mi.symbol(elf)).flushMoved(elf, new_addr);
9467 if (elf.node_global_symbols.get(ni)) |first_name| {9453 if (elf.node_global_symbols.get(ni)) |first_name| {
...@@ -9474,6 +9460,14 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9474,6 +9460,14 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9474 }9460 }
9475 elf.flushMovedNodeRelocs(ni, new_addr, .{9461 elf.flushMovedNodeRelocs(ni, new_addr, .{
9476 .first_symbol_reloc = mi.firstSymbolReloc(elf),9462 .first_symbol_reloc = mi.firstSymbolReloc(elf),
9463 .skip_symbol_relocs = switch (tag) {
9464 else => comptime unreachable,
9465 .nav => if (elf.dwarf.getFuncIfExists(mi.nav(elf))) |dwarf_fi|
9466 dwarf_fi.get(&elf.dwarf).debug_info_ni
9467 else
9468 .none,
9469 .uav, .lazy_code, .lazy_const_data => .none,
9470 },
9477 .first_got_reloc = mi.firstGotReloc(elf),9471 .first_got_reloc = mi.firstGotReloc(elf),
9478 });9472 });
9479 },9473 },
...@@ -9599,17 +9593,21 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9599,17 +9593,21 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9599 target_ri = target_reloc.next;9593 target_ri = target_reloc.next;
9600 }9594 }
9601 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{9595 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9602 .ignore_node = fi.get(&elf.dwarf).debug_line_ni,
9603 .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc,9596 .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc,
9597 .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav|
9598 nav.lsi.index().ptr(elf).node
9599 else
9600 .none,
9604 .first_node_reloc = dwarf_func.debug_info_first_node_reloc,9601 .first_node_reloc = dwarf_func.debug_info_first_node_reloc,
9602 .skip_node_relocs = fi.get(&elf.dwarf).debug_line_ni,
9605 });9603 });
9606 },9604 },
9607 .func_debug_line => |fi| {9605 .func_debug_line => |fi| {
9608 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];9606 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
9609 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{9607 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9610 .ignore_node = fi.get(&elf.dwarf).debug_info_ni,
9611 .first_symbol_reloc = dwarf_func.debug_line_first_symbol_reloc,9608 .first_symbol_reloc = dwarf_func.debug_line_first_symbol_reloc,
9612 .first_node_reloc = dwarf_func.debug_line_first_node_reloc,9609 .first_node_reloc = dwarf_func.debug_line_first_node_reloc,
9610 .skip_node_relocs = fi.get(&elf.dwarf).debug_info_ni,
9613 });9611 });
9614 },9612 },
9615 }9613 }
...@@ -10548,7 +10546,7 @@ pub fn printNode(...@@ -10548,7 +10546,7 @@ pub fn printNode(
10548 .nav => |nmi| {10546 .nav => |nmi| {
10549 const zcu = elf.base.comp.zcu.?;10547 const zcu = elf.base.comp.zcu.?;
10550 const ip = &zcu.intern_pool;10548 const ip = &zcu.intern_pool;
10551 const nav = ip.getNav(nmi.navIndex(elf));10549 const nav = ip.getNav(nmi.nav(elf));
10552 try w.print("({f}, {f})", .{10550 try w.print("({f}, {f})", .{
10553 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),10551 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
10554 nav.fqn.fmt(ip),10552 nav.fqn.fmt(ip),