authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-02 10:29:39-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 11:00:54-04:00
logabbec23e9cfb6549a2260fd447086dfd2935a350
treef11add52df2d829d9c2d4ed8052f40c1048732fc
parent6f746eef85c143ec559039bb4a70d15a05bcd2b5

Dwarf2: implement enough debug info to get line info working


3 files changed, 738 insertions(+), 338 deletions(-)

src/link.zig+11-11
...@@ -805,20 +805,20 @@ pub const File = struct {...@@ -805,20 +805,20 @@ pub const File = struct {
805 /// * `updateLineNumber`805 /// * `updateLineNumber`
806 ///806 ///
807 /// Asserts that the ZCU is not using the LLVM backend.807 /// Asserts that the ZCU is not using the LLVM backend.
808 fn zcuFilesReady(base: *File) Error!void {808 fn zcuFilesReady(base: *File, zcu: *Zcu) Error!void {
809 assert(base.comp.zcu.?.llvm_object == null);809 assert(zcu.llvm_object == null);
810 switch (base.tag) {810 switch (base.tag) {
811 else => {},811 else => {},
812 inline .elf2 => |tag| {812 inline .elf2 => |tag| {
813 dev.check(tag.devFeature());813 dev.check(tag.devFeature());
814 return @as(*tag.Type(), @fieldParentPtr("base", base)).zcuFilesReady();814 return @as(*tag.Type(), @fieldParentPtr("base", base)).zcuFilesReady(zcu);
815 },815 },
816 }816 }
817 }817 }
818818
819 /// Asserts that the ZCU is not using the LLVM backend.819 /// Asserts that the ZCU is not using the LLVM backend.
820 fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void {820 fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void {
821 assert(base.comp.zcu.?.llvm_object == null);821 assert(pt.zcu.llvm_object == null);
822 const nav = pt.zcu.intern_pool.getNav(nav_index);822 const nav = pt.zcu.intern_pool.getNav(nav_index);
823 assert(nav.resolved.?.value != .none);823 assert(nav.resolved.?.value != .none);
824824
...@@ -834,7 +834,7 @@ pub const File = struct {...@@ -834,7 +834,7 @@ pub const File = struct {
834834
835 /// Never called when LLVM is codegenning the ZCU.835 /// Never called when LLVM is codegenning the ZCU.
836 fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Error!void {836 fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Error!void {
837 assert(base.comp.zcu.?.llvm_object == null);837 assert(pt.zcu.llvm_object == null);
838 switch (base.tag) {838 switch (base.tag) {
839 .lld => unreachable,839 .lld => unreachable,
840 else => {},840 else => {},
...@@ -856,7 +856,7 @@ pub const File = struct {...@@ -856,7 +856,7 @@ pub const File = struct {
856 /// take ownership of an embedded slice and replace it with `&.{}` in `mir`.856 /// take ownership of an embedded slice and replace it with `&.{}` in `mir`.
857 mir: *codegen.AnyMir,857 mir: *codegen.AnyMir,
858 ) Error!void {858 ) Error!void {
859 assert(base.comp.zcu.?.llvm_object == null);859 assert(pt.zcu.llvm_object == null);
860 switch (base.tag) {860 switch (base.tag) {
861 .lld => unreachable,861 .lld => unreachable,
862 .plan9 => unreachable,862 .plan9 => unreachable,
...@@ -871,7 +871,7 @@ pub const File = struct {...@@ -871,7 +871,7 @@ pub const File = struct {
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) Error!void {
874 assert(base.comp.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 const file = pt.zcu.fileByIndex(ti.file);877 const file = pt.zcu.fileByIndex(ti.file);
...@@ -996,7 +996,7 @@ pub const File = struct {...@@ -996,7 +996,7 @@ pub const File = struct {
996 pt: Zcu.PerThread,996 pt: Zcu.PerThread,
997 export_indices: []const Zcu.Export.Index,997 export_indices: []const Zcu.Export.Index,
998 ) Error!void {998 ) Error!void {
999 assert(base.comp.zcu.?.llvm_object == null);999 assert(pt.zcu.llvm_object == null);
10001000
1001 crash_report.LinkerOp.start(base, pt.tid);1001 crash_report.LinkerOp.start(base, pt.tid);
1002 defer crash_report.LinkerOp.stop(base, pt.tid);1002 defer crash_report.LinkerOp.stop(base, pt.tid);
...@@ -1031,7 +1031,7 @@ pub const File = struct {...@@ -1031,7 +1031,7 @@ pub const File = struct {
1031 /// the block/atom.1031 /// the block/atom.
1032 /// Never called when LLVM is codegenning the ZCU.1032 /// Never called when LLVM is codegenning the ZCU.
1033 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) Error!u64 {1033 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) Error!u64 {
1034 assert(base.comp.zcu.?.llvm_object == null);1034 assert(pt.zcu.llvm_object == null);
10351035
1036 switch (base.tag) {1036 switch (base.tag) {
1037 .lld => unreachable,1037 .lld => unreachable,
...@@ -1054,7 +1054,7 @@ pub const File = struct {...@@ -1054,7 +1054,7 @@ pub const File = struct {
1054 decl_val: InternPool.Index,1054 decl_val: InternPool.Index,
1055 decl_align: InternPool.Alignment,1055 decl_align: InternPool.Alignment,
1056 ) Error!SymbolId {1056 ) Error!SymbolId {
1057 assert(base.comp.zcu.?.llvm_object == null);1057 assert(pt.zcu.llvm_object == null);
10581058
1059 switch (base.tag) {1059 switch (base.tag) {
1060 .lld => unreachable,1060 .lld => unreachable,
...@@ -1635,7 +1635,7 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void...@@ -1635,7 +1635,7 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
1635 .files_ready => {1635 .files_ready => {
1636 if (zcu.llvm_object != null) return;1636 if (zcu.llvm_object != null) return;
1637 const lf = comp.bin_file orelse return;1637 const lf = comp.bin_file orelse return;
1638 lf.zcuFilesReady() catch |err| switch (err) {1638 lf.zcuFilesReady(zcu) catch |err| switch (err) {
1639 error.Canceled => io.recancel(),1639 error.Canceled => io.recancel(),
1640 error.AlreadyReported => return,1640 error.AlreadyReported => return,
1641 error.OutOfMemory => return diags.setAllocFailure(),1641 error.OutOfMemory => return diags.setAllocFailure(),
src/link/Dwarf2.zig+366-113
...@@ -12,23 +12,28 @@ values: std.ArrayList(struct {...@@ -12,23 +12,28 @@ values: std.ArrayList(struct {
12globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),12globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),
13funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func),13funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func),
1414
15debug_abbrev: DebugAbbrev,15debug_abbrev: Abbrev,
16frame: Frame,16frame: Frame,
17debug_info: DebugInfo,17debug_info: Info,
18debug_line: DebugLine,18debug_line: Line,
19debug_line_str: String,19debug_line_str: Str,
20debug_str: String,20debug_rnglists: Rnglists,
21debug_str_offsets: StringOffsets,21debug_str: Str,
22debug_str_offsets: StrOffsets,
2223
23pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };24pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };
2425
25pub const Unit = struct {26pub const Unit = struct {
27 files: std.array_hash_map.Auto(Zcu.File.Index, void),
28 files_changed: bool,
26 frame_ni: MappedFile.Node.Index.Optional,29 frame_ni: MappedFile.Node.Index.Optional,
27 cie_ni: MappedFile.Node.Index.Optional,30 cie_ni: MappedFile.Node.Index.Optional,
28 debug_info_ni: MappedFile.Node.Index.Optional,31 debug_info_ni: MappedFile.Node.Index.Optional,
29 debug_info_header_ni: MappedFile.Node.Index.Optional,32 debug_info_header_ni: MappedFile.Node.Index.Optional,
30 debug_line_ni: MappedFile.Node.Index.Optional,33 debug_line_ni: MappedFile.Node.Index.Optional,
31 debug_line_header_ni: MappedFile.Node.Index.Optional,34 debug_line_header_ni: MappedFile.Node.Index.Optional,
35 debug_rnglists_ni: MappedFile.Node.Index.Optional,
36 debug_rnglists_offset: usize,
3237
33 pub const Index = enum(u32) {38 pub const Index = enum(u32) {
34 _,39 _,
...@@ -41,6 +46,30 @@ pub const Unit = struct {...@@ -41,6 +46,30 @@ pub const Unit = struct {
41 return &dwarf.units.values()[@backingInt(ui)];46 return &dwarf.units.values()[@backingInt(ui)];
42 }47 }
43 };48 };
49
50 pub const FileIndex = enum(u32) {
51 root = 0,
52 _,
53
54 fn get(fi: FileIndex, unit: *Unit) Zcu.File.Index {
55 return unit.files.keys()[@backingInt(fi)];
56 }
57 };
58
59 fn getFile(
60 unit: *Unit,
61 gpa: std.mem.Allocator,
62 zfi: Zcu.File.Index,
63 ) std.mem.Allocator.Error!FileIndex {
64 const file_gop = try unit.files.getOrPut(gpa, zfi);
65 if (!file_gop.found_existing) unit.files_changed = true;
66 return @fromBackingInt(@intCast(file_gop.index));
67 }
68
69 pub fn cleanFilesChanged(unit: *Unit) bool {
70 defer unit.files_changed = false;
71 return unit.files_changed;
72 }
44};73};
4574
46pub const Global = struct {75pub const Global = struct {
...@@ -90,15 +119,15 @@ pub const Frame = struct {...@@ -90,15 +119,15 @@ pub const Frame = struct {
90 pub const Format = std.debug.Dwarf.Unwind.Section;119 pub const Format = std.debug.Dwarf.Unwind.Section;
91};120};
92121
93pub const DebugAbbrev = struct {122pub const Abbrev = struct {
94 ni: MappedFile.Node.Index.Optional,123 ni: MappedFile.Node.Index.Optional,
95 offset: usize,124 offset: usize,
96 set: std.enums.EnumSet(AbbrevCode),125 set: std.enums.EnumSet(AbbrevCode),
97};126};
98127
99pub const DebugInfo = struct {};128pub const Info = struct {};
100129
101pub const DebugLine = struct {130pub const Line = struct {
102 header: Header,131 header: Header,
103132
104 pub const Header = struct {133 pub const Header = struct {
...@@ -111,35 +140,51 @@ pub const DebugLine = struct {...@@ -111,35 +140,51 @@ pub const DebugLine = struct {
111 };140 };
112};141};
113142
114pub const String = struct {143pub const Str = struct {
115 ni: MappedFile.Node.Index.Optional,144 ni: MappedFile.Node.Index.Optional,
116 offset: usize,145 offset: usize,
117 map: std.AutoHashMapUnmanaged(usize, void),146 map: std.HashMapUnmanaged(usize, void, Context, std.hash_map.default_max_load_percentage),
118147
119 fn get(148 fn get(
120 s: *String,149 s: *Str,
121 gpa: std.mem.Allocator,150 gpa: std.mem.Allocator,
122 mf: *MappedFile,151 mf: *MappedFile,
123 string: []const u8,152 str: []const u8,
124 ) MappedFile.Error!usize {153 ) MappedFile.Error!usize {
125 const ni = s.ni.unwrap().?;154 const ni = s.ni.unwrap().?;
126 const gop = try s.map.getOrPutAdapted(gpa, string, Adapter{ .slice = ni.sliceConst(mf) });155 const slice = ni.sliceConst(mf);
156 const gop = try s.map.getOrPutContextAdapted(
157 gpa,
158 str,
159 Adapter{ .slice = slice },
160 .{ .slice = slice },
161 );
127 if (!gop.found_existing) {162 if (!gop.found_existing) {
128 gop.key_ptr.* = s.offset;163 gop.key_ptr.* = s.offset;
129 try ni.ensureMinimumSize(mf, gpa, s.offset + string.len + 1);164 try ni.ensureMinimumSize(mf, gpa, s.offset + str.len + 1);
130 const slice_mut = ni.slice(mf);165 const slice_mut = ni.slice(mf);
131 @memcpy(slice_mut[s.offset..][0..string.len], string);166 @memcpy(slice_mut[s.offset..][0..str.len], str);
132 s.offset += string.len;167 s.offset += str.len;
133 slice_mut[s.offset] = 0;168 slice_mut[s.offset] = 0;
134 s.offset += 1;169 s.offset += 1;
135 }170 }
136 return gop.key_ptr.*;171 return gop.key_ptr.*;
137 }172 }
138173
174 const Context = struct {
175 slice: []const u8,
176 pub fn hash(context: Context, offset: usize) u64 {
177 return std.hash.Wyhash.hash(0, std.mem.sliceTo(context.slice[offset..], 0));
178 }
179 pub fn eql(_: Context, lhs_offset: usize, rhs_offset: usize) bool {
180 return lhs_offset == rhs_offset;
181 }
182 };
183
139 const Adapter = struct {184 const Adapter = struct {
140 slice: []const u8,185 slice: []const u8,
141 pub fn hash(_: Adapter, key: []const u8) u32 {186 pub fn hash(_: Adapter, key: []const u8) u64 {
142 return @truncate(std.hash.Wyhash.hash(0, key));187 return std.hash.Wyhash.hash(0, key);
143 }188 }
144 pub fn eql(adapter: Adapter, key: []const u8, rhs_offset: usize) bool {189 pub fn eql(adapter: Adapter, key: []const u8, rhs_offset: usize) bool {
145 return std.mem.startsWith(u8, adapter.slice[rhs_offset..], key) and190 return std.mem.startsWith(u8, adapter.slice[rhs_offset..], key) and
...@@ -148,7 +193,9 @@ pub const String = struct {...@@ -148,7 +193,9 @@ pub const String = struct {
148 };193 };
149};194};
150195
151pub const StringOffsets = struct {196pub const Rnglists = struct {};
197
198pub const StrOffsets = struct {
152 ni: MappedFile.Node.Index.Optional,199 ni: MappedFile.Node.Index.Optional,
153 offset: usize,200 offset: usize,
154};201};
...@@ -527,6 +574,7 @@ pub const WipNav = struct {...@@ -527,6 +574,7 @@ pub const WipNav = struct {
527 high_pc: u32,574 high_pc: u32,
528 }),575 }),
529 info_writer: MappedFile.Node.Writer,576 info_writer: MappedFile.Node.Writer,
577 info_func_length_offset: usize,
530 line_writer: MappedFile.Node.Writer,578 line_writer: MappedFile.Node.Writer,
531579
532 pub fn deinit(debug: *Debug) void {580 pub fn deinit(debug: *Debug) void {
...@@ -538,13 +586,22 @@ pub const WipNav = struct {...@@ -538,13 +586,22 @@ pub const WipNav = struct {
538 debug.* = undefined;586 debug.* = undefined;
539 }587 }
540588
541 pub fn startDebugInfo(debug: *Debug) link.Error!void {589 pub fn genDebugFrame(debug: *Debug, loc: u32, cfa: Cfa) link.Error!void {
542 debug.startDebugInfoInner() catch |err| switch (err) {590 return debug.wip_nav.genDebugFrame(loc, cfa);
591 }
592
593 pub fn startFunc(debug: *Debug) link.Error!void {
594 assert(debug.wip_nav.func != null);
595 debug.startDebugInfo() catch |err| switch (err) {
543 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),596 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
544 else => |e| return e,597 else => |e| return e,
545 };598 };
599 debug.startDebugLine() catch |err| switch (err) {
600 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
601 else => |e| return e,
602 };
546 }603 }
547 fn startDebugInfoInner(debug: *Debug) link.EmitError!void {604 fn startDebugInfo(debug: *Debug) link.EmitError!void {
548 const dwarf = debug.wip_nav.dwarf;605 const dwarf = debug.wip_nav.dwarf;
549 const ip = &debug.pt.zcu.intern_pool;606 const ip = &debug.pt.zcu.intern_pool;
550 const nav = ip.getNav(debug.wip_nav.func.?.nav(dwarf));607 const nav = ip.getNav(debug.wip_nav.func.?.nav(dwarf));
...@@ -552,29 +609,80 @@ pub const WipNav = struct {...@@ -552,29 +609,80 @@ pub const WipNav = struct {
552 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func));609 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func));
553 try debug.strp(nav.name.toSlice(ip));610 try debug.strp(nav.name.toSlice(ip));
554 try debug.strp(nav.fqn.toSlice(ip));611 try debug.strp(nav.fqn.toSlice(ip));
612 try dwarf.symbolAddress(&debug.info_writer, debug.wip_nav.func_si, 0);
613 debug.info_func_length_offset = diw.end;
614 try diw.writeInt(u32, undefined, dwarf.endian);
555 }615 }
616 fn startDebugLine(debug: *Debug) link.EmitError!void {
617 const dwarf = debug.wip_nav.dwarf;
618 const zcu = debug.pt.zcu;
619 const ip = &zcu.intern_pool;
620 const nav = debug.wip_nav.func.?.nav(dwarf);
621 const func = zcu.funcInfo(zcu.navValue(nav).toIntern());
622 const zfi = zcu.navFileScopeIndex(nav);
623 const zf = zcu.fileByIndex(zfi);
624 const inst_info = ip.getNav(nav).srcInst(ip).resolveFull(ip).?;
625 const decl = zf.zir.?.getDeclaration(inst_info.inst);
626 const mod = zf.mod.?;
627 const dlw = &debug.line_writer.interface;
628 try dlw.writeByte(DW.LNS.extended_op);
629 if (zcu.comp.config.incremental) {
630 try dlw.writeUleb128(1 + @as(u7, switch (dwarf.format) {
631 .@"32" => 4,
632 .@"64" => 8,
633 }));
634 try dlw.writeByte(DW.LNE.ZIG_set_decl);
635 try dwarf.sectionOffset(&debug.line_writer, debug.info_writer.ni, 0);
556636
557 pub fn genDebugFrame(debug: *Debug, loc: u32, cfa: Cfa) link.Error!void {637 try dlw.writeByte(DW.LNS.set_column);
558 return debug.wip_nav.genDebugFrame(loc, cfa);638 try dlw.writeUleb128(func.lbrace_column + 1);
639
640 try debug.advancePcAndLine(func.lbrace_line, 0);
641 } else {
642 try dlw.writeUleb128(1 + @backingInt(dwarf.address_size));
643 try dlw.writeByte(DW.LNE.set_address);
644 try dwarf.symbolAddress(&debug.line_writer, debug.wip_nav.func_si, 0);
645
646 const fi = try dwarf.getUnit(mod).get(dwarf).getFile(zcu.gpa, zfi);
647 try dlw.writeByte(DW.LNS.set_file);
648 try dlw.writeUleb128(@backingInt(fi));
649
650 try dlw.writeByte(DW.LNS.set_column);
651 try dlw.writeUleb128(func.lbrace_column + 1);
652
653 try debug.advancePcAndLine(@intCast(decl.src_line + func.lbrace_line), 0);
654 }
559 }655 }
560656
561 pub fn finishFunc(debug: *Debug) link.Error!void {657 pub fn finishFunc(debug: *Debug, func_length: u64) link.Error!void {
562 assert(debug.wip_nav.func != null);658 assert(debug.wip_nav.func != null);
563 debug.finishDebugInfo() catch |err| switch (err) {659 debug.finishDebugInfo(func_length) catch |err| switch (err) {
564 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),660 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
565 else => |e| return e,661 else => |e| return e,
566 };662 };
567 const dlw = &debug.line_writer.interface;663 debug.finishDebugLine() catch |err| switch (err) {
568 dlw.rebase(dlw.end, comptime 1 + uleb128Bytes(1) + 1) catch |err| switch (err) {
569 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),664 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
665 else => |e| return e,
570 };666 };
571 }667 }
572668 fn finishDebugInfo(debug: *Debug, func_length: u64) link.EmitError!void {
573 fn finishDebugInfo(debug: *Debug) link.EmitError!void {
574 const diw = &debug.info_writer.interface;669 const diw = &debug.info_writer.interface;
670 std.mem.writeInt(
671 u32,
672 diw.buffered()[debug.info_func_length_offset..][0..4],
673 @intCast(func_length),
674 debug.wip_nav.dwarf.endian,
675 );
575 try diw.writeUleb128(@backingInt(AbbrevCode.null));676 try diw.writeUleb128(@backingInt(AbbrevCode.null));
576 try debug.wip_nav.dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());677 try debug.wip_nav.dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());
577 }678 }
679 fn finishDebugLine(debug: *Debug) link.EmitError!void {
680 const dlw = &debug.line_writer.interface;
681 try dlw.writeByte(DW.LNS.extended_op);
682 try dlw.writeUleb128(1);
683 try dlw.writeByte(DW.LNE.end_sequence);
684 try genDebugLinePadding(dlw, dlw.unusedCapacityLen());
685 }
578686
579 pub const LocalVarTag = enum { arg, local_var };687 pub const LocalVarTag = enum { arg, local_var };
580 pub fn genLocalVarDebugInfo(688 pub fn genLocalVarDebugInfo(
...@@ -666,7 +774,6 @@ pub const WipNav = struct {...@@ -666,7 +774,6 @@ pub const WipNav = struct {
666 }774 }
667775
668 pub fn advancePcAndLine(debug: *Debug, delta_line: i33, delta_pc: u64) link.Error!void {776 pub fn advancePcAndLine(debug: *Debug, delta_line: i33, delta_pc: u64) link.Error!void {
669 if (true) return;
670 return debug.advancePcAndLineInner(delta_line, delta_pc) catch |err| switch (err) {777 return debug.advancePcAndLineInner(delta_line, delta_pc) catch |err| switch (err) {
671 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),778 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
672 };779 };
...@@ -707,7 +814,6 @@ pub const WipNav = struct {...@@ -707,7 +814,6 @@ pub const WipNav = struct {
707 }814 }
708815
709 pub fn setColumn(debug: *Debug, column: u32) link.Error!void {816 pub fn setColumn(debug: *Debug, column: u32) link.Error!void {
710 if (true) return;
711 return debug.setColumnInner(column) catch |err| switch (err) {817 return debug.setColumnInner(column) catch |err| switch (err) {
712 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),818 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
713 };819 };
...@@ -719,7 +825,6 @@ pub const WipNav = struct {...@@ -719,7 +825,6 @@ pub const WipNav = struct {
719 }825 }
720826
721 pub fn negateStmt(debug: *Debug) link.Error!void {827 pub fn negateStmt(debug: *Debug) link.Error!void {
722 if (true) return;
723 return debug.negateStmtInner() catch |err| switch (err) {828 return debug.negateStmtInner() catch |err| switch (err) {
724 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),829 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
725 };830 };
...@@ -729,7 +834,6 @@ pub const WipNav = struct {...@@ -729,7 +834,6 @@ pub const WipNav = struct {
729 }834 }
730835
731 pub fn setPrologueEnd(debug: *Debug) link.Error!void {836 pub fn setPrologueEnd(debug: *Debug) link.Error!void {
732 if (true) return;
733 return debug.setPrologueEndInner() catch |err| switch (err) {837 return debug.setPrologueEndInner() catch |err| switch (err) {
734 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),838 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
735 };839 };
...@@ -739,7 +843,6 @@ pub const WipNav = struct {...@@ -739,7 +843,6 @@ pub const WipNav = struct {
739 }843 }
740844
741 pub fn setEpilogueBegin(debug: *Debug) link.Error!void {845 pub fn setEpilogueBegin(debug: *Debug) link.Error!void {
742 if (true) return;
743 return debug.setEpilogueBeginInner() catch |err| switch (err) {846 return debug.setEpilogueBeginInner() catch |err| switch (err) {
744 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),847 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
745 };848 };
...@@ -749,13 +852,13 @@ pub const WipNav = struct {...@@ -749,13 +852,13 @@ pub const WipNav = struct {
749 }852 }
750853
751 pub fn enterBlock(debug: *Debug, code_off: u64) link.Error!void {854 pub fn enterBlock(debug: *Debug, code_off: u64) link.Error!void {
752 if (true) return;
753 return debug.enterBlockInner(code_off) catch |err| switch (err) {855 return debug.enterBlockInner(code_off) catch |err| switch (err) {
754 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),856 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
755 else => |e| e,857 else => |e| e,
756 };858 };
757 }859 }
758 fn enterBlockInner(debug: *Debug, code_off: u64) link.EmitError!void {860 fn enterBlockInner(debug: *Debug, code_off: u64) link.EmitError!void {
861 if (true) return;
759 const dwarf = debug.wip_nav.dwarf;862 const dwarf = debug.wip_nav.dwarf;
760 const diw = &debug.info_writer.interface;863 const diw = &debug.info_writer.interface;
761 const block = try debug.blocks.addOne(dwarf.lf.comp.gpa);864 const block = try debug.blocks.addOne(dwarf.lf.comp.gpa);
...@@ -943,15 +1046,6 @@ pub const WipNav = struct {...@@ -943,15 +1046,6 @@ pub const WipNav = struct {
943 );1046 );
944 }1047 }
9451048
946 fn infoExternalReloc(debug: *Debug, reloc: struct {
947 source_off: u32 = 0,
948 target_si: link.File.SymbolId,
949 target_off: u64 = 0,
950 }) std.mem.Allocator.Error!void {
951 if (true) @panic("TODO");
952 try debug.wip_nav.externalReloc(&debug.wip_nav.dwarf.debug_frame.section, reloc);
953 }
954
955 fn infoSectionOffset(1049 fn infoSectionOffset(
956 debug: *Debug,1050 debug: *Debug,
957 target_ni: MappedFile.Node.Index,1051 target_ni: MappedFile.Node.Index,
...@@ -996,18 +1090,8 @@ pub const WipNav = struct {...@@ -996,18 +1090,8 @@ pub const WipNav = struct {
996 try loc.write(adapter);1090 try loc.write(adapter);
997 }1091 }
9981092
999 fn infoAddrSym(1093 fn infoAddrSym(debug: *Debug, si: link.File.SymbolId, addend: usize) link.EmitError!void {
1000 debug: *Debug,1094 try debug.wip_nav.dwarf.symbolAddress(&debug.info_writer, si, addend);
1001 si: link.File.SymbolId,
1002 sym_off: u64,
1003 ) link.EmitError!void {
1004 const diw = &debug.info_writer.interface;
1005 try debug.infoExternalReloc(.{
1006 .source_off = @bitCast(@as(u64, diw.end)),
1007 .target_si = si,
1008 .target_off = sym_off,
1009 });
1010 try diw.splatByteAll(0, @backingInt(debug.wip_nav.dwarf.address_size));
1011 }1095 }
10121096
1013 fn refNav(debug: *Debug, nav_index: InternPool.Nav.Index) link.EmitError!void {1097 fn refNav(debug: *Debug, nav_index: InternPool.Nav.Index) link.EmitError!void {
...@@ -1037,7 +1121,7 @@ pub const WipNav = struct {...@@ -1037,7 +1121,7 @@ pub const WipNav = struct {
1037 const size = ty.abiSize(debug.pt.zcu);1121 const size = ty.abiSize(debug.pt.zcu);
1038 try diw.writeUleb128(size);1122 try diw.writeUleb128(size);
1039 if (size == 0) return;1123 if (size == 0) return;
1040 const old_end = diw.end;1124 const offset = diw.end;
1041 try codegen.generateSymbol(1125 try codegen.generateSymbol(
1042 debug.wip_nav.dwarf.lf,1126 debug.wip_nav.dwarf.lf,
1043 debug.pt,1127 debug.pt,
...@@ -1045,12 +1129,12 @@ pub const WipNav = struct {...@@ -1045,12 +1129,12 @@ pub const WipNav = struct {
1045 diw,1129 diw,
1046 .{ .debug_output = .{ .dwarf2 = debug } },1130 .{ .debug_output = .{ .dwarf2 = debug } },
1047 );1131 );
1048 if (old_end + size != diw.end) {1132 if (offset + size != diw.end) {
1049 std.debug.print("{f} [{}]: {} != {}\n", .{1133 std.debug.print("{f} [{}]: {} != {}\n", .{
1050 ty.fmt(debug.pt),1134 ty.fmt(debug.pt),
1051 ty.toIntern(),1135 ty.toIntern(),
1052 size,1136 size,
1053 diw.end - old_end,1137 diw.end - offset,
1054 });1138 });
1055 unreachable;1139 unreachable;
1056 }1140 }
...@@ -1210,7 +1294,8 @@ pub const WipNav = struct {...@@ -1210,7 +1294,8 @@ pub const WipNav = struct {
1210 offset,1294 offset,
1211 si,1295 si,
1212 @bitCast(sym_off),1296 @bitCast(sym_off),
1213 switch (dwarf.format) {1297 switch (dwarf.address_size) {
1298 else => unreachable,
1214 .@"32" => .abs32(elf),1299 .@"32" => .abs32(elf),
1215 .@"64" => .abs64(elf),1300 .@"64" => .abs64(elf),
1216 },1301 },
...@@ -1240,6 +1325,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {...@@ -1240,6 +1325,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
1240 },1325 },
1241 .endian = target.cpu.arch.endian(),1326 .endian = target.cpu.arch.endian(),
1242 .const_pool = .empty,1327 .const_pool = .empty,
1328
1243 .units = .empty,1329 .units = .empty,
1244 .values = .empty,1330 .values = .empty,
1245 .globals = .empty,1331 .globals = .empty,
...@@ -1296,6 +1382,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {...@@ -1296,6 +1382,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
1296 .offset = 0,1382 .offset = 0,
1297 .map = .empty,1383 .map = .empty,
1298 },1384 },
1385 .debug_rnglists = .{},
1299 .debug_str = .{1386 .debug_str = .{
1300 .ni = .none,1387 .ni = .none,
1301 .offset = 0,1388 .offset = 0,
...@@ -1311,29 +1398,41 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {...@@ -1311,29 +1398,41 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
1311pub fn deinit(dwarf: *Dwarf) void {1398pub fn deinit(dwarf: *Dwarf) void {
1312 const gpa = dwarf.lf.comp.gpa;1399 const gpa = dwarf.lf.comp.gpa;
1313 dwarf.const_pool.deinit(gpa);1400 dwarf.const_pool.deinit(gpa);
1401 for (dwarf.units.values()) |*unit| unit.files.deinit(gpa);
1314 dwarf.units.deinit(gpa);1402 dwarf.units.deinit(gpa);
1315 dwarf.values.deinit(gpa);1403 dwarf.values.deinit(gpa);
1316 dwarf.globals.deinit(gpa);1404 dwarf.globals.deinit(gpa);
1317 dwarf.funcs.deinit(gpa);1405 dwarf.funcs.deinit(gpa);
1406 dwarf.debug_line_str.map.deinit(gpa);
1318 dwarf.debug_str.map.deinit(gpa);1407 dwarf.debug_str.map.deinit(gpa);
1319 dwarf.* = undefined;1408 dwarf.* = undefined;
1320}1409}
13211410
1322pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {1411pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {
1323 try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count());1412 try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count());
1324 for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, root| switch (root) {1413 for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, root| if (root.unwrap()) |root_zfi| {
1325 .none => {},1414 const unit_gop = dwarf.units.getOrPutAssumeCapacity(mod);
1326 else => dwarf.units.putAssumeCapacityNoClobber(mod, .{1415 assert(!unit_gop.found_existing);
1416 unit_gop.value_ptr.* = .{
1417 .files = .empty,
1418 .files_changed = true,
1327 .frame_ni = .none,1419 .frame_ni = .none,
1328 .cie_ni = .none,1420 .cie_ni = .none,
1329 .debug_info_ni = .none,1421 .debug_info_ni = .none,
1330 .debug_info_header_ni = .none,1422 .debug_info_header_ni = .none,
1331 .debug_line_ni = .none,1423 .debug_line_ni = .none,
1332 .debug_line_header_ni = .none,1424 .debug_line_header_ni = .none,
1333 }),1425 .debug_rnglists_ni = .none,
1426 .debug_rnglists_offset = undefined,
1427 };
1428 assert(try unit_gop.value_ptr.getFile(zcu.gpa, root_zfi) == .root);
1334 };1429 };
1335}1430}
13361431
1432pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {
1433 return @fromBackingInt(@intCast(dwarf.units.getIndex(mod).?));
1434}
1435
1337fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) link.Error!MappedFile.Node.Index {1436fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) link.Error!MappedFile.Node.Index {
1338 if (true) @panic("TODO");1437 if (true) @panic("TODO");
1339 const zcu = dwarf.linkFile().comp.zcu.?;1438 const zcu = dwarf.linkFile().comp.zcu.?;
...@@ -1347,10 +1446,6 @@ fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) link.Error!MappedF...@@ -1347,10 +1446,6 @@ fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) link.Error!MappedF
1347 return .{ unit, entry };1446 return .{ unit, entry };
1348}1447}
13491448
1350pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {
1351 return @fromBackingInt(@intCast(dwarf.units.getIndex(mod).?));
1352}
1353
1354pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) std.mem.Allocator.Error!Func.Index {1449pub fn getFunc(dwarf: *Dwarf, owner_nav: InternPool.Nav.Index) std.mem.Allocator.Error!Func.Index {
1355 const func_gop = try dwarf.funcs.getOrPut(dwarf.lf.comp.gpa, owner_nav);1450 const func_gop = try dwarf.funcs.getOrPut(dwarf.lf.comp.gpa, owner_nav);
1356 if (!func_gop.found_existing) func_gop.value_ptr.* = .{1451 if (!func_gop.found_existing) func_gop.value_ptr.* = .{
...@@ -1485,44 +1580,52 @@ pub fn updateEhFrameFde(dwarf: *Dwarf, fde: []u8, fde_offset: u64) void {...@@ -1485,44 +1580,52 @@ pub fn updateEhFrameFde(dwarf: *Dwarf, fde: []u8, fde_offset: u64) void {
14851580
1486pub fn genDebugInfoHeader(1581pub fn genDebugInfoHeader(
1487 dwarf: *Dwarf,1582 dwarf: *Dwarf,
1488 nw: *MappedFile.Node.Writer,1583 mod: *Module,
1489 unit: Unit.Index,1584 unit: *Unit,
1585 dih_nw: *MappedFile.Node.Writer,
1586 debug_rnglists_offsets_table_offset: usize,
1490 zcu: *Zcu,1587 zcu: *Zcu,
1491) link.EmitError!void {1588) link.EmitError!void {
1492 const comp = zcu.comp;1589 const comp = zcu.comp;
1493 const mod = unit.mod(dwarf);1590 const dihw = &dih_nw.interface;
1494 const diw = &nw.interface;1591 try dwarf.genUnitLength(dihw);
1495 try dwarf.genUnitLength(diw);1592 try dihw.writeInt(u16, 5, dwarf.endian);
1496 try diw.writeInt(u16, 5, dwarf.endian);1593 try dihw.writeByte(DW.UT.compile);
1497 try diw.writeByte(DW.UT.compile);1594 try dihw.writeByte(@backingInt(dwarf.address_size));
1498 try diw.writeByte(@backingInt(dwarf.address_size));1595 try dwarf.sectionOffset(dih_nw, dwarf.debug_abbrev.ni.unwrap().?, 0);
1499 try dwarf.sectionOffset(nw, dwarf.debug_abbrev.ni.unwrap().?, 0);1596 const compile_unit_offset = dihw.end;
1500 const compile_unit_offset = diw.end;1597 try dihw.writeUleb128(try dwarf.refAbbrevCode(.compile_unit));
1501 try diw.writeUleb128(try dwarf.refAbbrevCode(.compile_unit));1598 try dihw.writeByte(DW.LANG.Zig);
1502 try dwarf.strp(&dwarf.debug_str, nw, "zig " ++ @import("build_options").version);1599 try dwarf.strp(&dwarf.debug_str, dih_nw, "zig " ++ @import("build_options").version);
1503 try diw.writeByte(DW.LANG.Zig);
1504 const root_dir_path = try mod.root.toAbsolute(&comp.dirs, comp.gpa);1600 const root_dir_path = try mod.root.toAbsolute(&comp.dirs, comp.gpa);
1505 defer comp.gpa.free(root_dir_path);1601 defer comp.gpa.free(root_dir_path);
1506 try dwarf.strp(&dwarf.debug_line_str, nw, root_dir_path);1602 try dwarf.strp(&dwarf.debug_line_str, dih_nw, root_dir_path);
1507 try dwarf.strp(&dwarf.debug_line_str, nw, mod.root_src_path);1603 try dwarf.strp(&dwarf.debug_line_str, dih_nw, mod.root_src_path);
1508 try dwarf.sectionOffset(1604 try dwarf.sectionOffset(
1509 nw,1605 dih_nw,
1510 dwarf.getUnit(comp.root_mod).get(dwarf).debug_info_header_ni.unwrap().?,1606 dwarf.getUnit(comp.root_mod).get(dwarf).debug_info_header_ni.unwrap().?,
1511 compile_unit_offset,1607 compile_unit_offset,
1512 );1608 );
1513 try dwarf.sectionOffset(nw, unit.get(dwarf).debug_line_header_ni.unwrap().?, 0);1609 try dwarf.sectionOffset(dih_nw, unit.debug_line_header_ni.unwrap().?, 0);
1514 const module_offset = diw.end;1610 try dwarf.sectionOffset(
1515 try diw.writeUleb128(try dwarf.refAbbrevCode(.module));1611 dih_nw,
1516 try dwarf.strp(&dwarf.debug_str, nw, mod.fully_qualified_name);1612 unit.debug_rnglists_ni.unwrap().?,
1613 debug_rnglists_offsets_table_offset,
1614 );
1615 try dihw.writeUleb128(0);
1616 const module_offset = dihw.end;
1617 try dihw.writeUleb128(try dwarf.refAbbrevCode(.module));
1618 try dwarf.strp(&dwarf.debug_str, dih_nw, mod.fully_qualified_name);
1619 try dihw.writeUleb128(0);
1517 for ([_][]const u8{ "builtin", "root", "std" }, [_]*Module{1620 for ([_][]const u8{ "builtin", "root", "std" }, [_]*Module{
1518 zcu.builtin_modules.get(mod.getBuiltinOptions(comp.config).hash()).?,1621 zcu.builtin_modules.get(mod.getBuiltinOptions(comp.config).hash()).?,
1519 zcu.root_mod,1622 zcu.root_mod,
1520 zcu.std_mod,1623 zcu.std_mod,
1521 }) |name, dep| try dwarf.genModuleDependency(nw, name, dep, module_offset);1624 }) |name, dep| try dwarf.genModuleDependency(dih_nw, name, dep, module_offset);
1522 for (mod.deps.keys(), mod.deps.values()) |name, dep|1625 for (mod.deps.keys(), mod.deps.values()) |name, dep|
1523 try dwarf.genModuleDependency(nw, name, dep, module_offset);1626 try dwarf.genModuleDependency(dih_nw, name, dep, module_offset);
1524 for ([2]AbbrevCode{ .pad_1, .pad_n }) |pad| _ = try dwarf.refAbbrevCode(pad);1627 for ([2]AbbrevCode{ .pad_1, .pad_n }) |pad| _ = try dwarf.refAbbrevCode(pad);
1525 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());1628 try dwarf.genDebugInfoPadding(dihw, dihw.unusedCapacityLen());
1526}1629}
15271630
1528fn genModuleDependency(1631fn genModuleDependency(
...@@ -1566,15 +1669,116 @@ pub fn genDebugInfoPadding(dwarf: *Dwarf, diw: *Writer, size: u64) Writer.Error!...@@ -1566,15 +1669,116 @@ pub fn genDebugInfoPadding(dwarf: *Dwarf, diw: *Writer, size: u64) Writer.Error!
1566 }1669 }
1567}1670}
15681671
1569pub fn genDebugLineHeader(dwarf: *Dwarf, dlw: *Writer) Writer.Error!void {1672pub fn genDebugLineHeader(
1570 try dwarf.genUnitLength(dlw);1673 dwarf: *Dwarf,
1571 @memset(dlw.unusedCapacitySlice(), 0xaa);1674 mod: *Module,
1675 unit: *Unit,
1676 dlh_nw: *MappedFile.Node.Writer,
1677 zcu: *Zcu,
1678) link.EmitError!void {
1679 const comp = zcu.comp;
1680 const dlhw = &dlh_nw.interface;
1681 try dwarf.genUnitLength(dlhw);
1682 try dlhw.writeInt(u16, 5, dwarf.endian);
1683 try dlhw.writeByte(@backingInt(dwarf.address_size));
1684 try dlhw.writeByte(0);
1685 const header_length_offset = dlhw.end;
1686 switch (dwarf.format) {
1687 .@"32" => try dlhw.writeInt(u32, undefined, dwarf.endian),
1688 .@"64" => try dlhw.writeInt(u64, undefined, dwarf.endian),
1689 }
1690 const header_start = dlhw.end;
1691 const StandardOpcode = DeclValEnum(DW.LNS);
1692 try dlhw.writeAll(&.{
1693 dwarf.debug_line.header.minimum_instruction_length,
1694 dwarf.debug_line.header.maximum_operations_per_instruction,
1695 @intFromBool(dwarf.debug_line.header.default_is_stmt),
1696 @bitCast(dwarf.debug_line.header.line_base),
1697 dwarf.debug_line.header.line_range,
1698 dwarf.debug_line.header.opcode_base,
1699 });
1700 try dlhw.writeAll(std.enums.EnumArray(StandardOpcode, u8).init(.{
1701 .extended_op = undefined,
1702 .copy = 0,
1703 .advance_pc = 1,
1704 .advance_line = 1,
1705 .set_file = 1,
1706 .set_column = 1,
1707 .negate_stmt = 0,
1708 .set_basic_block = 0,
1709 .const_add_pc = 0,
1710 .fixed_advance_pc = 1,
1711 .set_prologue_end = 0,
1712 .set_epilogue_begin = 0,
1713 .set_isa = 1,
1714 }).values[1..dwarf.debug_line.header.opcode_base]);
1715 try dlhw.writeByte(1);
1716 try dlhw.writeUleb128(DW.LNCT.path);
1717 try dlhw.writeUleb128(DW.FORM.line_strp);
1718 const dir_count = 1;
1719 const directory_index_form: DeclValEnum(DW.FORM) = if (dir_count <= 1 << 8)
1720 .data1
1721 else if (dir_count <= 1 << 16)
1722 .data2
1723 else
1724 .udata;
1725 try dlhw.writeUleb128(dir_count);
1726 {
1727 const root_dir_path = try mod.root.toAbsolute(&zcu.comp.dirs, comp.gpa);
1728 defer comp.gpa.free(root_dir_path);
1729 try dwarf.strp(&dwarf.debug_line_str, dlh_nw, root_dir_path);
1730 }
1731 try dlhw.writeByte(5);
1732 try dlhw.writeUleb128(DW.LNCT.path);
1733 try dlhw.writeUleb128(DW.FORM.line_strp);
1734 try dlhw.writeUleb128(DW.LNCT.directory_index);
1735 try dlhw.writeUleb128(@backingInt(directory_index_form));
1736 try dlhw.writeUleb128(DW.LNCT.timestamp);
1737 try dlhw.writeUleb128(DW.FORM.data8);
1738 try dlhw.writeUleb128(DW.LNCT.size);
1739 try dlhw.writeUleb128(DW.FORM.data8);
1740 try dlhw.writeUleb128(DW.LNCT.LLVM_source);
1741 try dlhw.writeUleb128(DW.FORM.line_strp);
1742 try dlhw.writeUleb128(unit.files.count());
1743 for (unit.files.keys()) |zfi| {
1744 const zcu_file = zcu.fileByIndex(zfi);
1745 try dwarf.strp(&dwarf.debug_line_str, dlh_nw, zcu_file.sub_file_path);
1746 switch (directory_index_form) {
1747 else => unreachable,
1748 .data1 => try dlhw.writeByte(0),
1749 .data2 => try dlhw.writeInt(u16, 0, dwarf.endian),
1750 .udata => try dlhw.writeUleb128(0),
1751 }
1752 try dlhw.writeInt(i64, @truncate(zcu_file.stat.mtime.nanoseconds), dwarf.endian);
1753 try dlhw.writeInt(u64, zcu_file.stat.size, dwarf.endian);
1754 try dwarf.strp(
1755 &dwarf.debug_line_str,
1756 dlh_nw,
1757 if (zcu_file.is_builtin) zcu_file.source.? else "",
1758 );
1759 }
1760 switch (dwarf.format) {
1761 .@"32" => std.mem.writeInt(
1762 u32,
1763 dlhw.buffer[header_length_offset..][0..4],
1764 @intCast(dlhw.end - header_start),
1765 dwarf.endian,
1766 ),
1767 .@"64" => std.mem.writeInt(
1768 u64,
1769 dlhw.buffer[header_length_offset..][0..8],
1770 dlhw.end - header_start,
1771 dwarf.endian,
1772 ),
1773 }
1774 try genDebugLinePadding(dlhw, dlhw.unusedCapacityLen());
1572}1775}
15731776
1574pub fn genDebugLinePadding(dlw: *Writer, size: u64) Writer.Error!void {1777pub fn genDebugLinePadding(dlw: *Writer, size: u64) Writer.Error!void {
1575 switch (size) {1778 switch (size) {
1576 0 => {},1779 0 => {},
1577 1 => try dlw.writeByte(DW.LNS.const_add_pc),1780 1 => try dlw.writeByte(DW.LNS.const_add_pc),
1781 2 => try dlw.writeAll(&.{ DW.LNS.negate_stmt, DW.LNS.negate_stmt }),
1578 else => {1782 else => {
1579 const extended_op_offset = dlw.end;1783 const extended_op_offset = dlw.end;
1580 try dlw.writeByte(DW.LNS.extended_op);1784 try dlw.writeByte(DW.LNS.extended_op);
...@@ -1590,10 +1794,48 @@ pub fn genDebugLinePadding(dlw: *Writer, size: u64) Writer.Error!void {...@@ -1590,10 +1794,48 @@ pub fn genDebugLinePadding(dlw: *Writer, size: u64) Writer.Error!void {
1590 },1794 },
1591 .gt => op_len_size += 1,1795 .gt => op_len_size += 1,
1592 };1796 };
1797 try dlw.writeByte(DW.LNE.padding);
1593 },1798 },
1594 }1799 }
1595}1800}
15961801
1802pub fn genDebugRnglistsHeader(
1803 dwarf: *Dwarf,
1804 unit: *Unit,
1805 drh_nw: *MappedFile.Node.Writer,
1806) Writer.Error!usize {
1807 const drhw = &drh_nw.interface;
1808 try dwarf.genUnitLength(drhw);
1809 try drhw.writeInt(u16, 5, dwarf.endian);
1810 try drhw.writeByte(@backingInt(dwarf.address_size));
1811 try drhw.writeByte(0);
1812 try drhw.writeInt(u32, 1, dwarf.endian);
1813 const offsets_table_offset = drhw.end;
1814 switch (dwarf.format) {
1815 .@"32" => try drhw.writeInt(u32, 4, dwarf.endian),
1816 .@"64" => try drhw.writeInt(u64, 8, dwarf.endian),
1817 }
1818 unit.debug_rnglists_offset = drhw.end;
1819 try drhw.writeByte(DW.RLE.end_of_list);
1820 return offsets_table_offset;
1821}
1822
1823pub fn genDebugRnglists(
1824 dwarf: *Dwarf,
1825 unit: *Unit,
1826 dr_nw: *MappedFile.Node.Writer,
1827 func_si: link.File.SymbolId,
1828 func_length: u64,
1829) link.EmitError!void {
1830 const drw = &dr_nw.interface;
1831 drw.end = unit.debug_rnglists_offset;
1832 try drw.writeByte(DW.RLE.start_length);
1833 try dwarf.symbolAddress(dr_nw, func_si, 0);
1834 try drw.writeUleb128(func_length);
1835 unit.debug_rnglists_offset = drw.end;
1836 try drw.writeByte(DW.RLE.end_of_list);
1837}
1838
1597fn refAbbrevCodeIfExists(1839fn refAbbrevCodeIfExists(
1598 dwarf: *Dwarf,1840 dwarf: *Dwarf,
1599 abbrev_code: AbbrevCode,1841 abbrev_code: AbbrevCode,
...@@ -1638,19 +1880,30 @@ fn sectionOffset(...@@ -1638,19 +1880,30 @@ fn sectionOffset(
1638 .@"32" => try nw.interface.writeInt(u32, 0, dwarf.endian),1880 .@"32" => try nw.interface.writeInt(u32, 0, dwarf.endian),
1639 .@"64" => try nw.interface.writeInt(u64, 0, dwarf.endian),1881 .@"64" => try nw.interface.writeInt(u64, 0, dwarf.endian),
1640 }1882 }
1641 try dwarf.lf.cast(.elf2).?.addNodeReloc(1883 const elf = dwarf.lf.cast(.elf2).?;
1642 nw.ni,1884 try elf.addNodeReloc(nw.ni, offset, target_ni, @bitCast(@as(u64, addend)), switch (dwarf.format) {
1643 offset,1885 .@"32" => .abs32,
1644 target_ni,1886 .@"64" => .abs64,
1645 @bitCast(@as(u64, addend)),1887 });
1646 switch (dwarf.format) {
1647 .@"32" => .abs32,
1648 .@"64" => .abs64,
1649 },
1650 );
1651}1888}
16521889
1653fn strp(dwarf: *Dwarf, s: *String, nw: *MappedFile.Node.Writer, str: []const u8) link.EmitError!void {1890fn symbolAddress(
1891 dwarf: *Dwarf,
1892 nw: *MappedFile.Node.Writer,
1893 target_si: link.File.SymbolId,
1894 addend: usize,
1895) link.EmitError!void {
1896 const offset = nw.interface.end;
1897 switch (dwarf.address_size) {
1898 else => unreachable,
1899 .@"32" => try nw.interface.writeInt(u32, 0, dwarf.endian),
1900 .@"64" => try nw.interface.writeInt(u64, 0, dwarf.endian),
1901 }
1902 const elf = dwarf.lf.cast(.elf2).?;
1903 try elf.addReloc(@bitCast(nw.ni), offset, target_si, @bitCast(@as(u64, addend)), .absAddr(elf));
1904}
1905
1906fn strp(dwarf: *Dwarf, s: *Str, nw: *MappedFile.Node.Writer, str: []const u8) link.EmitError!void {
1654 const comp = dwarf.lf.comp;1907 const comp = dwarf.lf.comp;
1655 const mf = &dwarf.lf.cast(.elf2).?.mf;1908 const mf = &dwarf.lf.cast(.elf2).?.mf;
1656 try dwarf.sectionOffset(nw, s.ni.unwrap().?, s.get(comp.gpa, mf, str) catch |err| switch (err) {1909 try dwarf.sectionOffset(nw, s.ni.unwrap().?, s.get(comp.gpa, mf, str) catch |err| switch (err) {
...@@ -1979,8 +2232,8 @@ pub const AbbrevCode = enum {...@@ -1979,8 +2232,8 @@ pub const AbbrevCode = enum {
1979 .attrs = decl_abbrev_common_attrs[4..] ++ .{2232 .attrs = decl_abbrev_common_attrs[4..] ++ .{
1980 .{ .linkage_name, .strp },2233 .{ .linkage_name, .strp },
1981 //.{ .type, .ref_addr },2234 //.{ .type, .ref_addr },
1982 //.{ .low_pc, .addr },2235 .{ .low_pc, .addr },
1983 //.{ .high_pc, .data4 },2236 .{ .high_pc, .data4 },
1984 //.{ .alignment, .udata },2237 //.{ .alignment, .udata },
1985 //.{ .external, .flag },2238 //.{ .external, .flag },
1986 //.{ .noreturn, .flag },2239 //.{ .noreturn, .flag },
...@@ -2200,14 +2453,14 @@ pub const AbbrevCode = enum {...@@ -2200,14 +2453,14 @@ pub const AbbrevCode = enum {
2200 .tag = .compile_unit,2453 .tag = .compile_unit,
2201 .children = true,2454 .children = true,
2202 .attrs = &.{2455 .attrs = &.{
2203 .{ .producer, .strp },
2204 .{ .language, .data1 },2456 .{ .language, .data1 },
2457 .{ .producer, .strp },
2205 .{ .comp_dir, .line_strp },2458 .{ .comp_dir, .line_strp },
2206 .{ .name, .line_strp },2459 .{ .name, .line_strp },
2207 .{ .base_types, .ref_addr },2460 .{ .base_types, .ref_addr },
2208 .{ .stmt_list, .sec_offset },2461 .{ .stmt_list, .sec_offset },
2209 //.{ .rnglists_base, .sec_offset },2462 .{ .rnglists_base, .sec_offset },
2210 //.{ .ranges, .rnglistx },2463 .{ .ranges, .rnglistx },
2211 .{ .use_UTF8, .flag_present },2464 .{ .use_UTF8, .flag_present },
2212 },2465 },
2213 },2466 },
...@@ -2216,7 +2469,7 @@ pub const AbbrevCode = enum {...@@ -2216,7 +2469,7 @@ pub const AbbrevCode = enum {
2216 .children = true,2469 .children = true,
2217 .attrs = &.{2470 .attrs = &.{
2218 .{ .name, .strp },2471 .{ .name, .strp },
2219 //.{ .ranges, .rnglistx },2472 .{ .ranges, .rnglistx },
2220 },2473 },
2221 },2474 },
2222 .module_dependency = .{2475 .module_dependency = .{
src/link/Elf2.zig+361-214
...@@ -49,6 +49,7 @@ shndx: struct {...@@ -49,6 +49,7 @@ shndx: struct {
49 debug_info: Section.Index,49 debug_info: Section.Index,
50 debug_line: Section.Index,50 debug_line: Section.Index,
51 debug_line_str: Section.Index,51 debug_line_str: Section.Index,
52 debug_rnglists: Section.Index,
52 debug_str: Section.Index,53 debug_str: Section.Index,
53 debug_str_offsets: Section.Index,54 debug_str_offsets: Section.Index,
54 // These sections are created only as needed, and are initially `.UNDEF`.55 // These sections are created only as needed, and are initially `.UNDEF`.
...@@ -212,6 +213,8 @@ dwarf_units: std.ArrayList(struct {...@@ -212,6 +213,8 @@ dwarf_units: std.ArrayList(struct {
212 debug_info_header_first_node_reloc: NodeReloc.Index,213 debug_info_header_first_node_reloc: NodeReloc.Index,
213 debug_line_header_first_target_reloc: NodeReloc.Index,214 debug_line_header_first_target_reloc: NodeReloc.Index,
214 debug_line_header_first_node_reloc: NodeReloc.Index,215 debug_line_header_first_node_reloc: NodeReloc.Index,
216 debug_rnglists_first_target_reloc: NodeReloc.Index,
217 debug_rnglists_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void),
215}),218}),
216dwarf_values: std.ArrayList(struct {219dwarf_values: std.ArrayList(struct {
217 debug_info_first_target_reloc: NodeReloc.Index,220 debug_info_first_target_reloc: NodeReloc.Index,
...@@ -304,6 +307,7 @@ const Node = union(enum) {...@@ -304,6 +307,7 @@ const Node = union(enum) {
304 unit_debug_info_header: Dwarf.Unit.Index,307 unit_debug_info_header: Dwarf.Unit.Index,
305 unit_debug_line: Dwarf.Unit.Index,308 unit_debug_line: Dwarf.Unit.Index,
306 unit_debug_line_header: Dwarf.Unit.Index,309 unit_debug_line_header: Dwarf.Unit.Index,
310 unit_debug_rnglists: Dwarf.Unit.Index,
307311
308 value_debug_info: link.ConstPool.Index,312 value_debug_info: link.ConstPool.Index,
309 global_debug_info: Dwarf.Global.Index,313 global_debug_info: Dwarf.Global.Index,
...@@ -1808,9 +1812,14 @@ const NodeReloc = struct {...@@ -1808,9 +1812,14 @@ const NodeReloc = struct {
1808 .none => {1812 .none => {
1809 const first_target_reloc = switch (elf.getNode(reloc.target)) {1813 const first_target_reloc = switch (elf.getNode(reloc.target)) {
1810 else => unreachable,1814 else => unreachable,
1815 .debug_shared => |ss| &elf.dwarf_shared.getPtr(ss).first_target_reloc,
1811 .unit_frame_cie => |ui| &elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc,1816 .unit_frame_cie => |ui| &elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc,
1812 .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc,1817 .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc,
1813 .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc,1818 .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc,
1819 .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc,
1820 .value_debug_info => |vi| &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_target_reloc,
1821 .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc,
1822 .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc,
1814 };1823 };
1815 first_target_reloc.* = reloc.next;1824 first_target_reloc.* = reloc.next;
1816 },1825 },
...@@ -3258,6 +3267,7 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {...@@ -3258,6 +3267,7 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
3258 .unit_debug_info_header,3267 .unit_debug_info_header,
3259 .unit_debug_line,3268 .unit_debug_line,
3260 .unit_debug_line_header,3269 .unit_debug_line_header,
3270 .unit_debug_rnglists,
3261 .value_debug_info,3271 .value_debug_info,
3262 .global_debug_info,3272 .global_debug_info,
3263 .func_frame_fde,3273 .func_frame_fde,
...@@ -3276,8 +3286,8 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {...@@ -3276,8 +3286,8 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
3276pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) link.Error!link.File.SymbolId {3286pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) link.Error!link.File.SymbolId {
3277 const diags = &elf.base.comp.link_diags;3287 const diags = &elf.base.comp.link_diags;
3278 return elf.lazySymbolInner(lazy) catch |err| switch (err) {3288 return elf.lazySymbolInner(lazy) catch |err| switch (err) {
3279 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3280 else => |e| return e,3289 else => |e| return e,
3290 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3281 };3291 };
3282}3292}
3283fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId {3293fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId {
...@@ -3331,8 +3341,8 @@ pub const ExternSymbolOpts = struct {...@@ -3331,8 +3341,8 @@ pub const ExternSymbolOpts = struct {
3331pub fn externSymbol(elf: *Elf, opts: ExternSymbolOpts) link.Error!link.File.SymbolId {3341pub fn externSymbol(elf: *Elf, opts: ExternSymbolOpts) link.Error!link.File.SymbolId {
3332 const diags = &elf.base.comp.link_diags;3342 const diags = &elf.base.comp.link_diags;
3333 return (elf.externSymbolInner(opts) catch |err| switch (err) {3343 return (elf.externSymbolInner(opts) catch |err| switch (err) {
3334 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3335 else => |e| return e,3344 else => |e| return e,
3345 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3336 }).toTypeErased();3346 }).toTypeErased();
3337}3347}
3338fn externSymbolInner(elf: *Elf, opts: ExternSymbolOpts) Error!Symbol.Id {3348fn externSymbolInner(elf: *Elf, opts: ExternSymbolOpts) Error!Symbol.Id {
...@@ -3372,15 +3382,15 @@ pub fn addReloc(...@@ -3372,15 +3382,15 @@ pub fn addReloc(
3372 const node: MappedFile.Node.Index = Node.fromAtom(atom);3382 const node: MappedFile.Node.Index = Node.fromAtom(atom);
3373 const diags = &elf.base.comp.link_diags;3383 const diags = &elf.base.comp.link_diags;
3374 elf.ensureUnusedRelocCapacity(node, 1) catch |err| switch (err) {3384 elf.ensureUnusedRelocCapacity(node, 1) catch |err| switch (err) {
3375 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3376 else => |e| return e,3385 else => |e| return e,
3386 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3377 };3387 };
3378 elf.addRelocAssumeCapacity(node, offset, .fromTypeErased(target), addend, @"type") catch |err| switch (err) {3388 elf.addRelocAssumeCapacity(node, offset, .fromTypeErased(target), addend, @"type") catch |err| switch (err) {
3389 else => |e| return e,
3379 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),3390 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3380 error.UnknownRelocation => unreachable, // codegen bug3391 error.UnknownRelocation => unreachable, // codegen bug
3381 error.NonStaticRelocation => unreachable, // codegen bug3392 error.NonStaticRelocation => unreachable, // codegen bug
3382 error.UnimplementedRelocation => unreachable, // codegen bug (asking Elf2 for a relocation it does not support)3393 error.UnimplementedRelocation => unreachable, // codegen bug (asking Elf2 for a relocation it does not support)
3383 else => |e| return e,
3384 };3394 };
3385}3395}
3386pub fn addNodeReloc(3396pub fn addNodeReloc(
...@@ -3393,12 +3403,12 @@ pub fn addNodeReloc(...@@ -3393,12 +3403,12 @@ pub fn addNodeReloc(
3393) link.Error!void {3403) link.Error!void {
3394 const diags = &elf.base.comp.link_diags;3404 const diags = &elf.base.comp.link_diags;
3395 elf.ensureUnusedRelocCapacity(node, 1) catch |err| switch (err) {3405 elf.ensureUnusedRelocCapacity(node, 1) catch |err| switch (err) {
3396 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3397 else => |e| return e,3406 else => |e| return e,
3407 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3398 };3408 };
3399 elf.addNodeRelocAssumeCapacity(node, offset, target, addend, @"type") catch |err| switch (err) {3409 elf.addNodeRelocAssumeCapacity(node, offset, target, addend, @"type") catch |err| switch (err) {
3400 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3401 else => |e| return e,3410 else => |e| return e,
3411 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3402 };3412 };
3403}3413}
3404pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.File.SymbolId {3414pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.File.SymbolId {
...@@ -3416,8 +3426,8 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.Fil...@@ -3416,8 +3426,8 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.Fil
3416 });3426 });
3417 }3427 }
3418 const nmi = elf.navMapIndex(zcu, nav_index) catch |err| switch (err) {3428 const nmi = elf.navMapIndex(zcu, nav_index) catch |err| switch (err) {
3419 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3420 else => |e| return e,3429 else => |e| return e,
3430 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3421 };3431 };
3422 const s: Symbol.Id = .local(nmi.symbol(elf));3432 const s: Symbol.Id = .local(nmi.symbol(elf));
3423 return s.toTypeErased();3433 return s.toTypeErased();
...@@ -3429,8 +3439,8 @@ pub fn uavSymbol(...@@ -3429,8 +3439,8 @@ pub fn uavSymbol(
3429) link.Error!link.File.SymbolId {3439) link.Error!link.File.SymbolId {
3430 const diags = &elf.base.comp.link_diags;3440 const diags = &elf.base.comp.link_diags;
3431 const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) {3441 const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) {
3432 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3433 else => |e| return e,3442 else => |e| return e,
3443 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3434 };3444 };
3435 const s: Symbol.Id = .local(umi.symbol(elf));3445 const s: Symbol.Id = .local(umi.symbol(elf));
3436 return s.toTypeErased();3446 return s.toTypeErased();
...@@ -3470,8 +3480,8 @@ pub fn lowerUav(...@@ -3470,8 +3480,8 @@ pub fn lowerUav(
3470 _ = pt;3480 _ = pt;
3471 const diags = &elf.base.comp.link_diags;3481 const diags = &elf.base.comp.link_diags;
3472 const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) {3482 const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) {
3473 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3474 else => |e| return e,3483 else => |e| return e,
3484 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3475 };3485 };
3476 const s: Symbol.Id = .local(umi.symbol(elf));3486 const s: Symbol.Id = .local(umi.symbol(elf));
3477 return s.toTypeErased();3487 return s.toTypeErased();
...@@ -3705,6 +3715,7 @@ fn create(...@@ -3705,6 +3715,7 @@ fn create(
3705 .debug_info = .UNDEF,3715 .debug_info = .UNDEF,
3706 .debug_line = .UNDEF,3716 .debug_line = .UNDEF,
3707 .debug_line_str = .UNDEF,3717 .debug_line_str = .UNDEF,
3718 .debug_rnglists = .UNDEF,
3708 .debug_str = .UNDEF,3719 .debug_str = .UNDEF,
3709 .debug_str_offsets = .UNDEF,3720 .debug_str_offsets = .UNDEF,
3710 .init_array = .UNDEF,3721 .init_array = .UNDEF,
...@@ -3819,6 +3830,7 @@ pub fn deinit(elf: *Elf) void {...@@ -3819,6 +3830,7 @@ pub fn deinit(elf: *Elf) void {
3819 elf.changed_symtab_index.deinit(gpa);3830 elf.changed_symtab_index.deinit(gpa);
38203831
3821 elf.dwarf.deinit();3832 elf.dwarf.deinit();
3833 for (elf.dwarf_units.items) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa);
3822 elf.dwarf_units.deinit(gpa);3834 elf.dwarf_units.deinit(gpa);
3823 elf.dwarf_values.deinit(gpa);3835 elf.dwarf_values.deinit(gpa);
3824 elf.dwarf_globals.deinit(gpa);3836 elf.dwarf_globals.deinit(gpa);
...@@ -3900,6 +3912,7 @@ fn initHeaders(...@@ -3900,6 +3912,7 @@ fn initHeaders(
3900 shnum += 1; // .debug_info3912 shnum += 1; // .debug_info
3901 shnum += 1; // .debug_line3913 shnum += 1; // .debug_line
3902 shnum += 1; // .debug_line_str3914 shnum += 1; // .debug_line_str
3915 shnum += 1; // .debug_rnglists
3903 shnum += 1; // .debug_str3916 shnum += 1; // .debug_str
3904 shnum += 1; // .debug_str_offsets3917 shnum += 1; // .debug_str_offsets
3905 },3918 },
...@@ -4744,22 +4757,22 @@ fn initHeaders(...@@ -4744,22 +4757,22 @@ fn initHeaders(
4744 elf.plt_first_symbol_reloc = @fromBackingInt(@intCast(elf.symbol_relocs.items.len));4757 elf.plt_first_symbol_reloc = @fromBackingInt(@intCast(elf.symbol_relocs.items.len));
4745 try elf.ensureUnusedRelocCapacity(plt_ni, 3);4758 try elf.ensureUnusedRelocCapacity(plt_ni, 3);
4746 elf.addRelocAssumeCapacity(plt_ni, 0, got_plt_sym, 0, .{ .LARCH = .PCALA_HI20 }) catch |err| switch (err) {4759 elf.addRelocAssumeCapacity(plt_ni, 0, got_plt_sym, 0, .{ .LARCH = .PCALA_HI20 }) catch |err| switch (err) {
4760 else => |e| return e,
4747 error.UnknownRelocation => unreachable,4761 error.UnknownRelocation => unreachable,
4748 error.NonStaticRelocation => unreachable,4762 error.NonStaticRelocation => unreachable,
4749 error.UnimplementedRelocation => unreachable,4763 error.UnimplementedRelocation => unreachable,
4750 else => |e| return e,
4751 };4764 };
4752 elf.addRelocAssumeCapacity(plt_ni, 8, got_plt_sym, 0, .{ .LARCH = .PCALA_LO12 }) catch |err| switch (err) {4765 elf.addRelocAssumeCapacity(plt_ni, 8, got_plt_sym, 0, .{ .LARCH = .PCALA_LO12 }) catch |err| switch (err) {
4766 else => |e| return e,
4753 error.UnknownRelocation => unreachable,4767 error.UnknownRelocation => unreachable,
4754 error.NonStaticRelocation => unreachable,4768 error.NonStaticRelocation => unreachable,
4755 error.UnimplementedRelocation => unreachable,4769 error.UnimplementedRelocation => unreachable,
4756 else => |e| return e,
4757 };4770 };
4758 elf.addRelocAssumeCapacity(plt_ni, 16, got_plt_sym, 0, .{ .LARCH = .PCALA_LO12 }) catch |err| switch (err) {4771 elf.addRelocAssumeCapacity(plt_ni, 16, got_plt_sym, 0, .{ .LARCH = .PCALA_LO12 }) catch |err| switch (err) {
4772 else => |e| return e,
4759 error.UnknownRelocation => unreachable,4773 error.UnknownRelocation => unreachable,
4760 error.NonStaticRelocation => unreachable,4774 error.NonStaticRelocation => unreachable,
4761 error.UnimplementedRelocation => unreachable,4775 error.UnimplementedRelocation => unreachable,
4762 else => |e| return e,
4763 };4776 };
4764 },4777 },
4765 .SPARCV9 => {},4778 .SPARCV9 => {},
...@@ -5008,6 +5021,10 @@ fn initHeaders(...@@ -5008,6 +5021,10 @@ fn initHeaders(
5008 .name = ".debug_line_str",5021 .name = ".debug_line_str",
5009 .flags = .{ .MERGE = true, .STRINGS = true },5022 .flags = .{ .MERGE = true, .STRINGS = true },
5010 });5023 });
5024 elf.shndx.debug_rnglists = try elf.addSection(elf.ni.elf, .{
5025 .name = ".debug_rnglists",
5026 .node_align = elf.mf.flags.block_size,
5027 });
5011 elf.shndx.debug_str = try elf.addSection(elf.ni.elf, .{5028 elf.shndx.debug_str = try elf.addSection(elf.ni.elf, .{
5012 .name = ".debug_str",5029 .name = ".debug_str",
5013 .flags = .{ .MERGE = true, .STRINGS = true },5030 .flags = .{ .MERGE = true, .STRINGS = true },
...@@ -5118,6 +5135,7 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {...@@ -5118,6 +5135,7 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {
5118 .unit_frame,5135 .unit_frame,
5119 .unit_debug_info,5136 .unit_debug_info,
5120 .unit_debug_line,5137 .unit_debug_line,
5138 .unit_debug_rnglists,
5121 => elf.getNode(ni.parent(&elf.mf).unwrap().?).section,5139 => elf.getNode(ni.parent(&elf.mf).unwrap().?).section,
5122 .unit_frame_cie,5140 .unit_frame_cie,
5123 .unit_debug_info_header,5141 .unit_debug_info_header,
...@@ -5157,6 +5175,7 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5157,6 +5175,7 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5157 .unit_debug_info_header,5175 .unit_debug_info_header,
5158 .unit_debug_line,5176 .unit_debug_line,
5159 .unit_debug_line_header,5177 .unit_debug_line_header,
5178 .unit_debug_rnglists,
5160 .value_debug_info,5179 .value_debug_info,
5161 .global_debug_info,5180 .global_debug_info,
5162 .func_frame_fde,5181 .func_frame_fde,
...@@ -5190,6 +5209,7 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5190,6 +5209,7 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5190 .unit_frame_cie,5209 .unit_frame_cie,
5191 .unit_debug_info_header,5210 .unit_debug_info_header,
5192 .unit_debug_line_header,5211 .unit_debug_line_header,
5212 .unit_debug_rnglists,
5193 .value_debug_info,5213 .value_debug_info,
5194 .global_debug_info,5214 .global_debug_info,
5195 .func_frame_fde,5215 .func_frame_fde,
...@@ -5210,7 +5230,12 @@ fn getNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5210,7 +5230,12 @@ fn getNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5210/// Asserts that `ni` must be a node which supports relocations (see `Elf.Node`). Does not support5230/// Asserts that `ni` must be a node which supports relocations (see `Elf.Node`). Does not support
5211/// the special-case sections '.plt', '.dynamic', and '.eh_frame_hdr'.5231/// the special-case sections '.plt', '.dynamic', and '.eh_frame_hdr'.
5212fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {5232fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5213 const symbol_relocs: ?*SymbolReloc.Index, const node_relocs: ?*NodeReloc.Index, const got_relocs: ?*GotReloc.Index = switch (elf.getNode(ni)) {5233 const opts: struct {
5234 ignore_node: MappedFile.Node.Index.Optional = .none,
5235 first_symbol_reloc: ?*SymbolReloc.Index = null,
5236 first_node_reloc: ?*NodeReloc.Index = null,
5237 first_got_reloc: ?*GotReloc.Index = null,
5238 } = switch (elf.getNode(ni)) {
5214 .archive,5239 .archive,
5215 .archive_header,5240 .archive_header,
5216 .archive_input_member,5241 .archive_input_member,
...@@ -5231,65 +5256,55 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5231,65 +5256,55 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5231 .section_manual_size,5256 .section_manual_size,
5232 => unreachable, // cannot contain relocs (.plt, .dynamic, and .eh_frame_hdr unsupported)5257 => unreachable, // cannot contain relocs (.plt, .dynamic, and .eh_frame_hdr unsupported)
5233 .input_section => |isi| .{5258 .input_section => |isi| .{
5234 &elf.input_sections.items[@backingInt(isi)].first_symbol_reloc,5259 .first_symbol_reloc = &elf.input_sections.items[@backingInt(isi)].first_symbol_reloc,
5235 null,5260 .first_got_reloc = &elf.input_sections.items[@backingInt(isi)].first_got_reloc,
5236 &elf.input_sections.items[@backingInt(isi)].first_got_reloc,
5237 },5261 },
5238 .nav => |nmi| .{5262 .nav => |nmi| .{
5239 &elf.navs.values()[@backingInt(nmi)].first_symbol_reloc,5263 .first_symbol_reloc = &elf.navs.values()[@backingInt(nmi)].first_symbol_reloc,
5240 null,5264 .first_got_reloc = &elf.navs.values()[@backingInt(nmi)].first_got_reloc,
5241 &elf.navs.values()[@backingInt(nmi)].first_got_reloc,
5242 },5265 },
5243 .uav => |umi| .{5266 .uav => |umi| .{
5244 &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc,5267 .first_symbol_reloc = &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc,
5245 null,
5246 null,
5247 },5268 },
5248 inline .lazy_code, .lazy_const_data => |lmi| .{5269 inline .lazy_code, .lazy_const_data => |lmi| .{
5249 &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_symbol_reloc,5270 .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_symbol_reloc,
5250 null,5271 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_got_reloc,
5251 &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_got_reloc,
5252 },5272 },
5253 .unit_debug_info_header => |ui| .{5273 .unit_debug_info_header => |ui| .{
5254 null,5274 .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_node_reloc,
5255 &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_node_reloc,
5256 null,
5257 },5275 },
5258 .unit_debug_line_header => |ui| .{5276 .unit_debug_line_header => |ui| .{
5259 null,5277 .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_node_reloc,
5260 &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_node_reloc,
5261 null,
5262 },5278 },
5279 .unit_debug_rnglists => unreachable, // unsupported
5263 .value_debug_info => |vi| .{5280 .value_debug_info => |vi| .{
5264 &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_symbol_reloc,5281 .first_symbol_reloc = &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_symbol_reloc,
5265 &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_node_reloc,5282 .first_node_reloc = &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_node_reloc,
5266 null,
5267 },5283 },
5268 .global_debug_info => |gi| .{5284 .global_debug_info => |gi| .{
5269 &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_symbol_reloc,5285 .first_symbol_reloc = &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_symbol_reloc,
5270 &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_node_reloc,5286 .first_node_reloc = &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_node_reloc,
5271 null,
5272 },5287 },
5273 .func_frame_fde => |fi| .{5288 .func_frame_fde => |fi| .{
5274 &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_symbol_reloc,5289 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_symbol_reloc,
5275 &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_node_reloc,5290 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].frame_fde_first_node_reloc,
5276 null,
5277 },5291 },
5278 .func_debug_info => |fi| .{5292 .func_debug_info => |fi| .{
5279 &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc,5293 .ignore_node = fi.get(&elf.dwarf).debug_line_ni,
5280 &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc,5294 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_symbol_reloc,
5281 null,5295 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_node_reloc,
5282 },5296 },
5283 .func_debug_line => |fi| .{5297 .func_debug_line => |fi| .{
5284 &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_symbol_reloc,5298 .ignore_node = fi.get(&elf.dwarf).debug_info_ni,
5285 &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_node_reloc,5299 .first_symbol_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_symbol_reloc,
5286 null,5300 .first_node_reloc = &elf.dwarf_funcs.items[@backingInt(fi)].debug_line_first_node_reloc,
5287 },5301 },
5288 };5302 };
52895303
5290 if (symbol_relocs) |ptr| {5304 if (opts.first_symbol_reloc) |ptr| {
5291 if (ptr.* != .none) {5305 if (ptr.* != .none) {
5292 for (elf.symbol_relocs.items[@backingInt(ptr.*)..], @backingInt(ptr.*)..) |*reloc, index| {5306 for (elf.symbol_relocs.items[@backingInt(ptr.*)..], @backingInt(ptr.*)..) |*reloc, index| {
5307 if (reloc.node.toOptional() == opts.ignore_node) continue;
5293 if (reloc.node != ni) break;5308 if (reloc.node != ni) break;
5294 reloc.delete(elf, @fromBackingInt(@intCast(index)));5309 reloc.delete(elf, @fromBackingInt(@intCast(index)));
5295 }5310 }
...@@ -5297,9 +5312,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5297,9 +5312,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5297 ptr.* = @fromBackingInt(@intCast(elf.symbol_relocs.items.len));5312 ptr.* = @fromBackingInt(@intCast(elf.symbol_relocs.items.len));
5298 }5313 }
52995314
5300 if (node_relocs) |ptr| {5315 if (opts.first_node_reloc) |ptr| {
5301 if (ptr.* != .none) {5316 if (ptr.* != .none) {
5302 for (elf.node_relocs.items[@backingInt(ptr.*)..]) |*reloc| {5317 for (elf.node_relocs.items[@backingInt(ptr.*)..]) |*reloc| {
5318 if (reloc.node.toOptional() == opts.ignore_node) continue;
5303 if (reloc.node != ni) break;5319 if (reloc.node != ni) break;
5304 reloc.delete(elf);5320 reloc.delete(elf);
5305 }5321 }
...@@ -5307,9 +5323,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5307,9 +5323,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5307 ptr.* = @fromBackingInt(@intCast(elf.node_relocs.items.len));5323 ptr.* = @fromBackingInt(@intCast(elf.node_relocs.items.len));
5308 }5324 }
53095325
5310 if (got_relocs) |ptr| {5326 if (opts.first_got_reloc) |ptr| {
5311 if (ptr.* != .none) {5327 if (ptr.* != .none) {
5312 for (elf.got_relocs.items[@backingInt(ptr.*)..]) |*reloc| {5328 for (elf.got_relocs.items[@backingInt(ptr.*)..]) |*reloc| {
5329 if (reloc.node == opts.ignore_node) continue;
5313 if (reloc.node != ni.toOptional()) break;5330 if (reloc.node != ni.toOptional()) break;
5314 reloc.delete(elf);5331 reloc.delete(elf);
5315 }5332 }
...@@ -5324,12 +5341,16 @@ fn flushMovedNodeRelocs(...@@ -5324,12 +5341,16 @@ fn flushMovedNodeRelocs(
5324 elf: *Elf,5341 elf: *Elf,
5325 node: MappedFile.Node.Index,5342 node: MappedFile.Node.Index,
5326 node_vaddr: u64,5343 node_vaddr: u64,
5327 first_symbol_reloc: SymbolReloc.Index,5344 opts: struct {
5328 first_node_reloc: NodeReloc.Index,5345 ignore_node: MappedFile.Node.Index.Optional = .none,
5329 first_got_reloc: GotReloc.Index,5346 first_symbol_reloc: SymbolReloc.Index = .none,
5347 first_node_reloc: NodeReloc.Index = .none,
5348 first_got_reloc: GotReloc.Index = .none,
5349 },
5330) void {5350) void {
5331 if (first_symbol_reloc != .none) {5351 if (opts.first_symbol_reloc != .none) {
5332 for (elf.symbol_relocs.items[@backingInt(first_symbol_reloc)..]) |*reloc| {5352 for (elf.symbol_relocs.items[@backingInt(opts.first_symbol_reloc)..]) |*reloc| {
5353 if (reloc.node.toOptional() == opts.ignore_node) continue;
5333 if (reloc.node != node) break;5354 if (reloc.node != node) break;
5334 if (reloc.rela_index.unwrap()) |rela_index| {5355 if (reloc.rela_index.unwrap()) |rela_index| {
5335 // The node has moved, so the offset of the relocation within the section might have5356 // The node has moved, so the offset of the relocation within the section might have
...@@ -5345,8 +5366,9 @@ fn flushMovedNodeRelocs(...@@ -5345,8 +5366,9 @@ fn flushMovedNodeRelocs(
5345 }5366 }
5346 }5367 }
53475368
5348 if (first_node_reloc != .none) {5369 if (opts.first_node_reloc != .none) {
5349 for (elf.node_relocs.items[@backingInt(first_node_reloc)..]) |*reloc| {5370 for (elf.node_relocs.items[@backingInt(opts.first_node_reloc)..]) |*reloc| {
5371 if (reloc.node.toOptional() == opts.ignore_node) continue;
5350 if (reloc.node != node) break;5372 if (reloc.node != node) break;
5351 if (reloc.rela_index.unwrap()) |rela_index| {5373 if (reloc.rela_index.unwrap()) |rela_index| {
5352 assert(elf.ehdrType() == .REL);5374 assert(elf.ehdrType() == .REL);
...@@ -5360,8 +5382,9 @@ fn flushMovedNodeRelocs(...@@ -5360,8 +5382,9 @@ fn flushMovedNodeRelocs(
5360 }5382 }
5361 }5383 }
53625384
5363 if (first_got_reloc != .none) {5385 if (opts.first_got_reloc != .none) {
5364 for (elf.got_relocs.items[@backingInt(first_got_reloc)..]) |*reloc| {5386 for (elf.got_relocs.items[@backingInt(opts.first_got_reloc)..]) |*reloc| {
5387 if (reloc.node == opts.ignore_node) continue;
5365 if (reloc.node != node.toOptional()) break;5388 if (reloc.node != node.toOptional()) break;
5366 reloc.apply(elf);5389 reloc.apply(elf);
5367 }5390 }
...@@ -5814,6 +5837,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node...@@ -5814,6 +5837,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node
5814 })) |shndx| {5837 })) |shndx| {
5815 break :section shndx;5838 break :section shndx;
5816 } else |err| switch (err) {5839 } else |err| switch (err) {
5840 else => |e| return e,
5817 error.StripSection,5841 error.StripSection,
5818 error.TlsSectionUnavailable,5842 error.TlsSectionUnavailable,
5819 error.UnsupportedSectionFlags,5843 error.UnsupportedSectionFlags,
...@@ -5821,7 +5845,6 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node...@@ -5821,7 +5845,6 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node
5821 error.SectionFlagsConflict,5845 error.SectionFlagsConflict,
5822 => {}, // fall back to default behavior below5846 => {}, // fall back to default behavior below
58235847
5824 else => |e| return e,
5825 }5848 }
5826 }5849 }
5827 if (elf.base.comp.config.any_non_single_threaded and nav.resolved.?.@"threadlocal") {5850 if (elf.base.comp.config.any_non_single_threaded and nav.resolved.?.@"threadlocal") {
...@@ -6074,8 +6097,8 @@ fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (Load...@@ -6074,8 +6097,8 @@ fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (Load
6074 strtab.clearRetainingCapacity();6097 strtab.clearRetainingCapacity();
6075 try strtab.ensureTotalCapacityPrecise(size);6098 try strtab.ensureTotalCapacityPrecise(size);
6076 r.streamExact(&strtab.writer, size) catch |err| switch (err) {6099 r.streamExact(&strtab.writer, size) catch |err| switch (err) {
6077 error.WriteFailed => return error.OutOfMemory,
6078 else => |e| return e,6100 else => |e| return e,
6101 error.WriteFailed => return error.OutOfMemory,
6079 };6102 };
6080 continue;6103 continue;
6081 }6104 }
...@@ -6106,8 +6129,8 @@ fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (Load...@@ -6106,8 +6129,8 @@ fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (Load
6106 }6129 }
6107 try fr.seekTo(std.mem.alignForward(u64, offset + size, 2));6130 try fr.seekTo(std.mem.alignForward(u64, offset + size, 2));
6108 } else |err| switch (err) {6131 } else |err| switch (err) {
6109 error.EndOfStream => if (!fr.atEnd()) return error.EndOfStream,
6110 else => |e| return e,6132 else => |e| return e,
6133 error.EndOfStream => if (!fr.atEnd()) return error.EndOfStream,
6111 }6134 }
6112}6135}
6113fn fmtMemberString(member: ?[]const u8) std.fmt.Alt(?[]const u8, memberStringEscape) {6136fn fmtMemberString(member: ?[]const u8) std.fmt.Alt(?[]const u8, memberStringEscape) {
...@@ -6273,6 +6296,7 @@ fn loadObject(...@@ -6273,6 +6296,7 @@ fn loadObject(
6273 .flags = section.shdr.flags.shf,6296 .flags = section.shdr.flags.shf,
6274 .entsize = section.shdr.entsize,6297 .entsize = section.shdr.entsize,
6275 }) catch |err| switch (err) {6298 }) catch |err| switch (err) {
6299 else => |e| return e,
6276 error.StripSection => continue,6300 error.StripSection => continue,
6277 error.TlsSectionUnavailable => return diags.failParse(6301 error.TlsSectionUnavailable => return diags.failParse(
6278 path,6302 path,
...@@ -6303,7 +6327,6 @@ fn loadObject(...@@ -6303,7 +6327,6 @@ fn loadObject(
6303 "flags of section '{s}' conflict with other inputs",6327 "flags of section '{s}' conflict with other inputs",
6304 .{name},6328 .{name},
6305 ),6329 ),
6306 else => |e| return e,
6307 };6330 };
6308 if (section.shdr.flags.shf.COMPRESSED) {6331 if (section.shdr.flags.shf.COMPRESSED) {
6309 // SHF_COMPRESSED is only allowed on non-alloc sections.6332 // SHF_COMPRESSED is only allowed on non-alloc sections.
...@@ -6585,6 +6608,7 @@ fn loadObject(...@@ -6585,6 +6608,7 @@ fn loadObject(
6585 rel.addend,6608 rel.addend,
6586 rt,6609 rt,
6587 ) catch |err| switch (err) {6610 ) catch |err| switch (err) {
6611 else => |e| return e,
6588 error.UnknownRelocation => diags.addParseError(6612 error.UnknownRelocation => diags.addParseError(
6589 path,6613 path,
6590 "unknown relocation type '{f}'",6614 "unknown relocation type '{f}'",
...@@ -6600,7 +6624,6 @@ fn loadObject(...@@ -6600,7 +6624,6 @@ fn loadObject(
6600 "TODO(Elf2): unimplemented relocation type '{f}'",6624 "TODO(Elf2): unimplemented relocation type '{f}'",
6601 .{rt.fmt(elf)},6625 .{rt.fmt(elf)},
6602 ),6626 ),
6603 else => |e| return e,
6604 };6627 };
6605 }6628 }
6606 },6629 },
...@@ -6997,7 +7020,7 @@ pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) link.Error!void {...@@ -6997,7 +7020,7 @@ pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) link.Error!void {
6997fn prelinkInner(elf: *Elf) Error!void {7020fn prelinkInner(elf: *Elf) Error!void {
6998 const comp = elf.base.comp;7021 const comp = elf.base.comp;
6999 const gpa = comp.gpa;7022 const gpa = comp.gpa;
7000 if (comp.zcu) |zcu| self_hosted_codegen: {7023 if (comp.zcu) |_| self_hosted_codegen: {
7001 if (comp.config.use_llvm) break :self_hosted_codegen;7024 if (comp.config.use_llvm) break :self_hosted_codegen;
70027025
7003 // We're using self-hosted codegen---add an input representing the Zig "object".7026 // We're using self-hosted codegen---add an input representing the Zig "object".
...@@ -7019,15 +7042,32 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7019,15 +7042,32 @@ fn prelinkInner(elf: *Elf) Error!void {
7019 .extra = .{ .file_symbol = zcu_file_symbol },7042 .extra = .{ .file_symbol = zcu_file_symbol },
7020 };7043 };
7021 elf.input_pending_index += 1;7044 elf.input_pending_index += 1;
7045 }
7046}
7047
7048pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void {
7049 elf.zcuFilesReadyInner(zcu) catch |err| switch (err) {
7050 else => |e| return e,
7051 error.MappedFileIo => return elf.base.comp.link_diags.fail(
7052 "failed to write output file: {t}",
7053 .{elf.mf.io_err.?},
7054 ),
7055 };
7056}
7057fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7058 const gpa = zcu.gpa;
70227059
7060 if (elf.dwarf.units.count() == 0) {
7023 try elf.dwarf.initUnits(zcu);7061 try elf.dwarf.initUnits(zcu);
7024 try elf.nodes.ensureUnusedCapacity(gpa, 4 + 4 + (4 + 4) * elf.dwarf.units.count());7062 try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5 + 5 * elf.dwarf.units.count());
7025 try elf.dwarf_units.appendNTimes(gpa, .{7063 try elf.dwarf_units.appendNTimes(gpa, .{
7026 .frame_cie_first_target_reloc = .none,7064 .frame_cie_first_target_reloc = .none,
7027 .debug_info_header_first_target_reloc = .none,7065 .debug_info_header_first_target_reloc = .none,
7028 .debug_info_header_first_node_reloc = .none,7066 .debug_info_header_first_node_reloc = .none,
7029 .debug_line_header_first_target_reloc = .none,7067 .debug_line_header_first_target_reloc = .none,
7030 .debug_line_header_first_node_reloc = .none,7068 .debug_line_header_first_node_reloc = .none,
7069 .debug_rnglists_first_target_reloc = .none,
7070 .debug_rnglists_symbol_relocs = .empty,
7031 }, elf.dwarf.units.count());7071 }, elf.dwarf.units.count());
70327072
7033 elf.dwarf.debug_abbrev.ni =7073 elf.dwarf.debug_abbrev.ni =
...@@ -7046,11 +7086,12 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7046,11 +7086,12 @@ fn prelinkInner(elf: *Elf) Error!void {
7046 .wrap(try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{}));7086 .wrap(try elf.shndx.debug_str_offsets.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{}));
7047 elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_str_offsets });7087 elf.nodes.appendAssumeCapacity(.{ .debug_shared = .debug_str_offsets });
70487088
7049 for ([4]Section.Index{7089 for ([5]Section.Index{
7050 elf.shndx.eh_frame,7090 elf.shndx.eh_frame,
7051 elf.shndx.debug_frame,7091 elf.shndx.debug_frame,
7052 elf.shndx.debug_info,7092 elf.shndx.debug_info,
7053 elf.shndx.debug_line,7093 elf.shndx.debug_line,
7094 elf.shndx.debug_rnglists,
7054 }) |debug_shndx| {7095 }) |debug_shndx| {
7055 if (debug_shndx == .UNDEF) continue;7096 if (debug_shndx == .UNDEF) continue;
7056 const debug_ni = debug_shndx.get(elf).ni;7097 const debug_ni = debug_shndx.get(elf).ni;
...@@ -7085,7 +7126,6 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7085,7 +7126,6 @@ fn prelinkInner(elf: *Elf) Error!void {
7085 const debug_info_ni =7126 const debug_info_ni =
7086 try debug_info_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{7127 try debug_info_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
7087 .alignment = elf.mf.flags.block_size,7128 .alignment = elf.mf.flags.block_size,
7088 .next_moved = true,
7089 .enable_next_moved = true,7129 .enable_next_moved = true,
7090 });7130 });
7091 unit.debug_info_ni = .wrap(debug_info_ni);7131 unit.debug_info_ni = .wrap(debug_info_ni);
...@@ -7105,7 +7145,6 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7105,7 +7145,6 @@ fn prelinkInner(elf: *Elf) Error!void {
7105 const debug_line_ni =7145 const debug_line_ni =
7106 try debug_line_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{7146 try debug_line_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
7107 .alignment = elf.mf.flags.block_size,7147 .alignment = elf.mf.flags.block_size,
7108 .next_moved = true,
7109 .enable_next_moved = true,7148 .enable_next_moved = true,
7110 });7149 });
7111 unit.debug_line_ni = .wrap(debug_line_ni);7150 unit.debug_line_ni = .wrap(debug_line_ni);
...@@ -7113,43 +7152,72 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7113,43 +7152,72 @@ fn prelinkInner(elf: *Elf) Error!void {
71137152
7114 unit.debug_line_header_ni =7153 unit.debug_line_header_ni =
7115 .wrap(try debug_line_ni.addOnlyHeaderChild(&elf.mf, gpa, .{7154 .wrap(try debug_line_ni.addOnlyHeaderChild(&elf.mf, gpa, .{
7116 .next_moved = true,7155 // Idle tasks are going to try to keep this up to date before we are able to
7156 // write out the full header, so just reserve space for them to do so.
7157 .size = elf.dwarf.unitLengthSize(),
7117 .enable_next_moved = true,7158 .enable_next_moved = true,
7118 }));7159 }));
7119 elf.nodes.appendAssumeCapacity(.{ .unit_debug_line_header = ui });7160 elf.nodes.appendAssumeCapacity(.{ .unit_debug_line_header = ui });
7120 },7161 },
7121 }7162 }
7163 switch (elf.shndx.debug_rnglists) {
7164 .UNDEF => {},
7165 else => |debug_rnglists_shndx| {
7166 unit.debug_rnglists_ni =
7167 .wrap(try debug_rnglists_shndx.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
7168 .next_moved = true,
7169 .enable_next_moved = true,
7170 }));
7171 elf.nodes.appendAssumeCapacity(.{ .unit_debug_rnglists = ui });
7172 },
7173 }
7122 }7174 }
71237175
7124 for (0.., elf.dwarf.units.values()) |unit_index, *unit| {7176 for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| {
7125 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));7177 var drh_nw: MappedFile.Node.Writer = undefined;
7126 if (elf.shndx.debug_info != .UNDEF) {7178 unit.debug_rnglists_ni.unwrap().?.writer(&elf.mf, gpa, &drh_nw);
7127 var header_nw: MappedFile.Node.Writer = undefined;7179 defer drh_nw.deinit();
7128 const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?;7180 const debug_rnglists_offsets_table_offset =
7129 debug_info_header_ni.writer(&elf.mf, gpa, &header_nw);7181 elf.dwarf.genDebugRnglistsHeader(unit, &drh_nw) catch |err| switch (err) {
7130 defer header_nw.deinit();
7131 elf.resetNodeRelocs(debug_info_header_ni);
7132 elf.dwarf.genDebugInfoHeader(&header_nw, ui, zcu) catch |err| switch (err) {
7133 error.WriteFailed => return header_nw.err.?,
7134 else => |e| return e,7182 else => |e| return e,
7183 error.WriteFailed => return drh_nw.err.?,
7135 };7184 };
7136 }7185
7137 if (elf.shndx.debug_line != .UNDEF) {7186 var dih_nw: MappedFile.Node.Writer = undefined;
7138 var header_nw: MappedFile.Node.Writer = undefined;7187 const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?;
7139 const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?;7188 debug_info_header_ni.writer(&elf.mf, gpa, &dih_nw);
7140 debug_line_header_ni.writer(&elf.mf, gpa, &header_nw);7189 defer dih_nw.deinit();
7141 defer header_nw.deinit();7190 elf.resetNodeRelocs(debug_info_header_ni);
7142 elf.resetNodeRelocs(debug_line_header_ni);7191 elf.dwarf.genDebugInfoHeader(
7143 elf.dwarf.genDebugLineHeader(&header_nw.interface) catch |err| switch (err) {7192 mod,
7144 error.WriteFailed => return header_nw.err.?,7193 unit,
7145 };7194 &dih_nw,
7146 }7195 debug_rnglists_offsets_table_offset,
7196 zcu,
7197 ) catch |err| switch (err) {
7198 else => |e| return e,
7199 error.WriteFailed => return dih_nw.err.?,
7200 };
7147 }7201 }
7148 }7202 }
7149}7203}
71507204
7151pub fn zcuFilesReady(elf: *Elf) link.Error!void {7205fn flushFiles(elf: *Elf) Error!void {
7152 _ = elf; // TODO jacobly7206 const gpa = elf.base.comp.gpa;
7207 if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| {
7208 if (!unit.cleanFilesChanged()) continue;
7209 const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?;
7210 try debug_line_header_ni.moved(gpa, &elf.mf);
7211 try debug_line_header_ni.nextMoved(gpa, &elf.mf);
7212 var dlh_nw: MappedFile.Node.Writer = undefined;
7213 debug_line_header_ni.writer(&elf.mf, gpa, &dlh_nw);
7214 defer dlh_nw.deinit();
7215 elf.resetNodeRelocs(debug_line_header_ni);
7216 elf.dwarf.genDebugLineHeader(mod, unit, &dlh_nw, elf.base.comp.zcu.?) catch |err| switch (err) {
7217 else => |e| return e,
7218 error.WriteFailed => return dlh_nw.err.?,
7219 };
7220 };
7153}7221}
71547222
7155fn prepareDynamic(elf: *Elf) Error!void {7223fn prepareDynamic(elf: *Elf) Error!void {
...@@ -7952,6 +8020,10 @@ fn addNodeRelocAssumeCapacity(...@@ -7952,6 +8020,10 @@ fn addNodeRelocAssumeCapacity(
7952 .unit_frame_cie => |ui| &elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc,8020 .unit_frame_cie => |ui| &elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc,
7953 .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc,8021 .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc,
7954 .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc,8022 .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc,
8023 .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc,
8024 .value_debug_info => |vi| &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_target_reloc,
8025 .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc,
8026 .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc,
7955 };8027 };
7956 const next = first_target_reloc.*;8028 const next = first_target_reloc.*;
7957 const ri: NodeReloc.Index = @fromBackingInt(@intCast(elf.node_relocs.items.len));8029 const ri: NodeReloc.Index = @fromBackingInt(@intCast(elf.node_relocs.items.len));
...@@ -8052,6 +8124,7 @@ fn addGotRelocAssumeCapacity(...@@ -8052,6 +8124,7 @@ fn addGotRelocAssumeCapacity(
8052 .unit_debug_info_header,8124 .unit_debug_info_header,
8053 .unit_debug_line,8125 .unit_debug_line,
8054 .unit_debug_line_header,8126 .unit_debug_line_header,
8127 .unit_debug_rnglists,
8055 .value_debug_info,8128 .value_debug_info,
8056 .global_debug_info,8129 .global_debug_info,
8057 .func_frame_fde,8130 .func_frame_fde,
...@@ -8331,10 +8404,12 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) Error!bool {...@@ -8331,10 +8404,12 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) Error!bool {
8331}8404}
83328405
8333pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void {8406pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void {
8334 const diags = &elf.base.comp.link_diags;
8335 elf.updateNavInner(pt, nav_index) catch |err| switch (err) {8407 elf.updateNavInner(pt, nav_index) catch |err| switch (err) {
8336 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
8337 else => |e| return e,8408 else => |e| return e,
8409 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8410 "failed to write output file: {t}",
8411 .{elf.mf.io_err.?},
8412 ),
8338 };8413 };
8339}8414}
8340fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void {8415fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void {
...@@ -8365,8 +8440,8 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)...@@ -8365,8 +8440,8 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
8365 &nw.interface,8440 &nw.interface,
8366 .{ .atom_index = Node.toAtom(ni) },8441 .{ .atom_index = Node.toAtom(ni) },
8367 ) catch |err| switch (err) {8442 ) catch |err| switch (err) {
8368 error.WriteFailed => return nw.err.?,
8369 else => |e| return e,8443 else => |e| return e,
8444 error.WriteFailed => return nw.err.?,
8370 };8445 };
8371 switch (elf.symPtr(nmi.symbol(elf).index())) {8446 switch (elf.symPtr(nmi.symbol(elf).index())) {
8372 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),8447 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),
...@@ -8383,10 +8458,12 @@ pub fn updateFunc(...@@ -8383,10 +8458,12 @@ pub fn updateFunc(
8383 func_index: InternPool.Index,8458 func_index: InternPool.Index,
8384 mir: *const codegen.AnyMir,8459 mir: *const codegen.AnyMir,
8385) link.Error!void {8460) link.Error!void {
8386 const diags = &elf.base.comp.link_diags;
8387 elf.updateFuncInner(pt, func_index, mir) catch |err| switch (err) {8461 elf.updateFuncInner(pt, func_index, mir) catch |err| switch (err) {
8388 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
8389 else => |e| return e,8462 else => |e| return e,
8463 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8464 "failed to write output file: {t}",
8465 .{elf.mf.io_err.?},
8466 ),
8390 };8467 };
8391}8468}
8392fn updateFuncInner(8469fn updateFuncInner(
...@@ -8403,7 +8480,8 @@ fn updateFuncInner(...@@ -8403,7 +8480,8 @@ fn updateFuncInner(
84038480
8404 const nmi = try elf.navMapIndex(zcu, func.owner_nav);8481 const nmi = try elf.navMapIndex(zcu, func.owner_nav);
8405 log.debug("updateFunc({f}) = {d}", .{ nav.fqn.fmt(ip), nmi.symbol(elf) });8482 log.debug("updateFunc({f}) = {d}", .{ nav.fqn.fmt(ip), nmi.symbol(elf) });
8406 const ni = nmi.symbol(elf).index().ptr(elf).node.unwrap().?;8483 const lsi = nmi.symbol(elf);
8484 const ni = lsi.index().ptr(elf).node.unwrap().?;
84078485
8408 // Ensure the NAV is marked as moved so that once we're done, `flushMoved` will eventually be8486 // Ensure the NAV is marked as moved so that once we're done, `flushMoved` will eventually be
8409 // called to apply the NAV's new relocations.8487 // called to apply the NAV's new relocations.
...@@ -8421,7 +8499,7 @@ fn updateFuncInner(...@@ -8421,7 +8499,7 @@ fn updateFuncInner(
8421 if (mod.strip and mod.unwind_tables == .none) break :debug_output .{ .none, undefined };8499 if (mod.strip and mod.unwind_tables == .none) break :debug_output .{ .none, undefined };
84228500
8423 try elf.nodes.ensureUnusedCapacity(gpa, 5);8501 try elf.nodes.ensureUnusedCapacity(gpa, 5);
8424 const dwarf_func_index = try dwarf.getFunc(func.owner_nav);8502 const dwarf_fi = try dwarf.getFunc(func.owner_nav);
8425 try elf.dwarf_funcs.appendNTimes(gpa, .{8503 try elf.dwarf_funcs.appendNTimes(gpa, .{
8426 .frame_fde_first_symbol_reloc = .none,8504 .frame_fde_first_symbol_reloc = .none,
8427 .frame_fde_first_node_reloc = .none,8505 .frame_fde_first_node_reloc = .none,
...@@ -8430,14 +8508,14 @@ fn updateFuncInner(...@@ -8430,14 +8508,14 @@ fn updateFuncInner(
8430 .debug_info_first_node_reloc = .none,8508 .debug_info_first_node_reloc = .none,
8431 .debug_line_first_symbol_reloc = .none,8509 .debug_line_first_symbol_reloc = .none,
8432 .debug_line_first_node_reloc = .none,8510 .debug_line_first_node_reloc = .none,
8433 }, @backingInt(dwarf_func_index) + 1 -| elf.dwarf_funcs.items.len);8511 }, @backingInt(dwarf_fi) + 1 -| elf.dwarf_funcs.items.len);
84348512
8435 const wip_nav = &debug_output_buf.wip_nav;8513 const wip_nav = &debug_output_buf.wip_nav;
8436 wip_nav.* = .{8514 wip_nav.* = .{
8437 .dwarf = dwarf,8515 .dwarf = dwarf,
8438 .unit = dwarf.getUnit(mod),8516 .unit = dwarf.getUnit(mod),
8439 .func = dwarf_func_index,8517 .func = dwarf_fi,
8440 .func_si = Symbol.Id.local(nmi.symbol(elf)).toTypeErased(),8518 .func_si = Symbol.Id.local(lsi).toTypeErased(),
8441 .cfi = .{8519 .cfi = .{
8442 .loc = 0,8520 .loc = 0,
8443 .cfa = dwarf.frame.header.initial_instructions[0].def_cfa,8521 .cfa = dwarf.frame.header.initial_instructions[0].def_cfa,
...@@ -8462,7 +8540,6 @@ fn updateFuncInner(...@@ -8462,7 +8540,6 @@ fn updateFuncInner(
8462 .eh_frame => elf.shndx.eh_frame,8540 .eh_frame => elf.shndx.eh_frame,
8463 }.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{8541 }.get(elf).ni.addFloatingChild(&elf.mf, gpa, .{
8464 .alignment = frame_align.max(elf.mf.flags.block_size),8542 .alignment = frame_align.max(elf.mf.flags.block_size),
8465 .next_moved = true,
8466 .enable_next_moved = true,8543 .enable_next_moved = true,
8467 });8544 });
8468 unit.frame_ni = .wrap(frame_ni);8545 unit.frame_ni = .wrap(frame_ni);
...@@ -8487,7 +8564,7 @@ fn updateFuncInner(...@@ -8487,7 +8564,7 @@ fn updateFuncInner(
8487 error.WriteFailed => return cie_nw.err.?,8564 error.WriteFailed => return cie_nw.err.?,
8488 };8565 };
8489 };8566 };
8490 const dwarf_func = dwarf_func_index.get(dwarf);8567 const dwarf_func = dwarf_fi.get(dwarf);
8491 const fde_ni = if (dwarf_func.fde_ni.unwrap()) |fde_ni| fde_ni: {8568 const fde_ni = if (dwarf_func.fde_ni.unwrap()) |fde_ni| fde_ni: {
8492 try fde_ni.moved(gpa, &elf.mf);8569 try fde_ni.moved(gpa, &elf.mf);
8493 try fde_ni.nextMoved(gpa, &elf.mf);8570 try fde_ni.nextMoved(gpa, &elf.mf);
...@@ -8510,24 +8587,34 @@ fn updateFuncInner(...@@ -8510,24 +8587,34 @@ fn updateFuncInner(
8510 debug.pt = pt;8587 debug.pt = pt;
8511 debug.any_children = false;8588 debug.any_children = false;
8512 debug.blocks = .empty;8589 debug.blocks = .empty;
8513 const debug_info_ni = dwarf_func.debug_info_ni.unwrap() orelse debug_info_ni: {8590 const debug_info_ni = if (dwarf_func.debug_info_ni.unwrap()) |debug_info_ni| debug_info_ni: {
8591 try debug_info_ni.moved(gpa, &elf.mf);
8592 try debug_info_ni.nextMoved(gpa, &elf.mf);
8593 break :debug_info_ni debug_info_ni;
8594 } else debug_info_ni: {
8514 const debug_info_ni =8595 const debug_info_ni =
8515 try unit.debug_info_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{8596 try unit.debug_info_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{
8597 .moved = true,
8516 .next_moved = true,8598 .next_moved = true,
8517 .enable_next_moved = true,8599 .enable_next_moved = true,
8518 });8600 });
8519 dwarf_func.debug_info_ni = .wrap(debug_info_ni);8601 dwarf_func.debug_info_ni = .wrap(debug_info_ni);
8520 elf.nodes.appendAssumeCapacity(.{ .func_debug_info = dwarf_func_index });8602 elf.nodes.appendAssumeCapacity(.{ .func_debug_info = dwarf_fi });
8521 break :debug_info_ni debug_info_ni;8603 break :debug_info_ni debug_info_ni;
8522 };8604 };
8523 debug_info_ni.writer(&elf.mf, gpa, &debug.info_writer);8605 debug_info_ni.writer(&elf.mf, gpa, &debug.info_writer);
8524 const debug_line_ni = dwarf_func.debug_line_ni.unwrap() orelse debug_line_ni: {8606 const debug_line_ni = if (dwarf_func.debug_line_ni.unwrap()) |debug_line_ni| debug_line_ni: {
8607 try debug_line_ni.moved(gpa, &elf.mf);
8608 try debug_line_ni.nextMoved(gpa, &elf.mf);
8609 break :debug_line_ni debug_line_ni;
8610 } else debug_line_ni: {
8525 const debug_line_ni =8611 const debug_line_ni =
8526 try unit.debug_line_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{8612 try unit.debug_line_ni.unwrap().?.addFloatingChild(&elf.mf, gpa, .{
8613 .moved = true,
8527 .next_moved = true,8614 .next_moved = true,
8528 .enable_next_moved = true,8615 .enable_next_moved = true,
8529 });8616 });
8530 elf.nodes.appendAssumeCapacity(.{ .func_debug_line = dwarf_func_index });8617 elf.nodes.appendAssumeCapacity(.{ .func_debug_line = dwarf_fi });
8531 break :debug_line_ni debug_line_ni;8618 break :debug_line_ni debug_line_ni;
8532 };8619 };
8533 debug_line_ni.writer(&elf.mf, gpa, &debug.line_writer);8620 debug_line_ni.writer(&elf.mf, gpa, &debug.line_writer);
...@@ -8549,7 +8636,8 @@ fn updateFuncInner(...@@ -8549,7 +8636,8 @@ fn updateFuncInner(
8549 elf.resetNodeRelocs(dwarf_func.fde_ni.unwrap().?);8636 elf.resetNodeRelocs(dwarf_func.fde_ni.unwrap().?);
8550 try debug.wip_nav.genDebugFrameHeader();8637 try debug.wip_nav.genDebugFrameHeader();
8551 elf.resetNodeRelocs(dwarf_func.debug_info_ni.unwrap().?);8638 elf.resetNodeRelocs(dwarf_func.debug_info_ni.unwrap().?);
8552 try debug.startDebugInfo();8639 elf.resetNodeRelocs(dwarf_func.debug_line_ni.unwrap().?);
8640 try debug.startFunc();
8553 },8641 },
8554 .none => {},8642 .none => {},
8555 }8643 }
...@@ -8563,10 +8651,8 @@ fn updateFuncInner(...@@ -8563,10 +8651,8 @@ fn updateFuncInner(
8563 &nw.interface,8651 &nw.interface,
8564 debug_output,8652 debug_output,
8565 ) catch |err| switch (err) {8653 ) catch |err| switch (err) {
8566 error.WriteFailed => {
8567 if (nw.err) |e| return e;
8568 },
8569 else => |e| return e,8654 else => |e| return e,
8655 error.WriteFailed => if (nw.err) |e| return e,
8570 };8656 };
8571 const func_length = nw.interface.end;8657 const func_length = nw.interface.end;
8572 switch (elf.symPtr(nmi.symbol(elf).index())) {8658 switch (elf.symPtr(nmi.symbol(elf).index())) {
...@@ -8591,19 +8677,44 @@ fn updateFuncInner(...@@ -8591,19 +8677,44 @@ fn updateFuncInner(
8591 }8677 }
8592 },8678 },
8593 .dwarf2 => |debug| {8679 .dwarf2 => |debug| {
8594 try debug.finishFunc();8680 try debug.finishFunc(func_length);
8595 for ([2]Section.Index{8681 for ([3]Section.Index{
8596 elf.shndx.debug_info,8682 elf.shndx.debug_info,
8597 elf.shndx.debug_line,8683 elf.shndx.debug_line,
8684 elf.shndx.debug_rnglists,
8598 }) |debug_shndx| try debug_shndx.get(elf).ni.trimStart(&elf.mf, gpa);8685 }) |debug_shndx| try debug_shndx.get(elf).ni.trimStart(&elf.mf, gpa);
8686 const unit = debug.wip_nav.unit.get(debug.wip_nav.dwarf);
8599 {8687 {
8600 const debug_info_ni =8688 const debug_info_ni = unit.debug_info_ni.unwrap().?;
8601 debug.wip_nav.unit.get(debug.wip_nav.dwarf).debug_info_ni.unwrap().?;
8602 const last_offset, const last_size =8689 const last_offset, const last_size =
8603 debug_info_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf);8690 debug_info_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf);
8604 try debug_info_ni.ensureMinimumSize(&elf.mf, gpa, last_offset + last_size +8691 try debug_info_ni.ensureMinimumSize(&elf.mf, gpa, last_offset + last_size +
8605 comptime Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) * 2);8692 comptime Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) * 2);
8606 }8693 }
8694 {
8695 var dr_nw: MappedFile.Node.Writer = undefined;
8696 unit.debug_rnglists_ni.unwrap().?.writer(&elf.mf, gpa, &dr_nw);
8697 defer dr_nw.deinit();
8698 const first_symbol_reloc = elf.symbol_relocs.items.len;
8699 debug.wip_nav.dwarf.genDebugRnglists(
8700 unit,
8701 &dr_nw,
8702 debug.wip_nav.func_si,
8703 func_length,
8704 ) catch |err| switch (err) {
8705 else => |e| return e,
8706 error.WriteFailed => return dr_nw.err.?,
8707 };
8708 const symbol_relocs = &elf.dwarf_units.items[@backingInt(debug.wip_nav.unit)]
8709 .debug_rnglists_symbol_relocs;
8710 try symbol_relocs.ensureUnusedCapacity(gpa, elf.symbol_relocs.items.len -
8711 first_symbol_reloc);
8712 for (first_symbol_reloc..elf.symbol_relocs.items.len) |symbol_ri|
8713 symbol_relocs.putAssumeCapacityNoClobber(
8714 @fromBackingInt(@intCast(symbol_ri)),
8715 {},
8716 );
8717 }
8607 continue :debug_output .{ .eh_frame = &debug.wip_nav };8718 continue :debug_output .{ .eh_frame = &debug.wip_nav };
8608 },8719 },
8609 .none => {},8720 .none => {},
...@@ -8615,13 +8726,15 @@ fn updateFuncInner(...@@ -8615,13 +8726,15 @@ fn updateFuncInner(
8615}8726}
86168727
8617pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {8728pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
8618 const diags = &elf.base.comp.link_diags;
8619 elf.genLazy(pt, .{8729 elf.genLazy(pt, .{
8620 .kind = .const_data,8730 .kind = .const_data,
8621 .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),8731 .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
8622 }) catch |err| switch (err) {8732 }) catch |err| switch (err) {
8623 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
8624 else => |e| return e,8733 else => |e| return e,
8734 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8735 "failed to write output file: {t}",
8736 .{elf.mf.io_err.?},
8737 ),
8625 };8738 };
8626}8739}
86278740
...@@ -8632,8 +8745,11 @@ pub fn flush(...@@ -8632,8 +8745,11 @@ pub fn flush(
8632 prog_node: std.Progress.Node,8745 prog_node: std.Progress.Node,
8633) link.Error!void {8746) link.Error!void {
8634 elf.flushInner(arena, tid, prog_node) catch |err| switch (err) {8747 elf.flushInner(arena, tid, prog_node) catch |err| switch (err) {
8635 error.MappedFileIo => return elf.base.comp.link_diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
8636 else => |e| return e,8748 else => |e| return e,
8749 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8750 "failed to write output file: {t}",
8751 .{elf.mf.io_err.?},
8752 ),
8637 };8753 };
8638}8754}
8639fn flushInner(8755fn flushInner(
...@@ -8649,6 +8765,8 @@ fn flushInner(...@@ -8649,6 +8765,8 @@ fn flushInner(
8649 const sub_prog_node = prog_node.start("ELF Flush", 0);8765 const sub_prog_node = prog_node.start("ELF Flush", 0);
8650 defer sub_prog_node.end();8766 defer sub_prog_node.end();
86518767
8768 try elf.flushFiles();
8769
8652 if (comp.config.output_mode == .Exe) {8770 if (comp.config.output_mode == .Exe) {
8653 var any_undef = false;8771 var any_undef = false;
8654 for (elf.globals.strong_undef.keys()) |name| {8772 for (elf.globals.strong_undef.keys()) |name| {
...@@ -8714,7 +8832,7 @@ fn flushInner(...@@ -8714,7 +8832,7 @@ fn flushInner(
87148832
8715 if (elf.options.enable_link_snapshots)8833 if (elf.options.enable_link_snapshots)
8716 elf.dumpStderr(tid) catch |err|8834 elf.dumpStderr(tid) catch |err|
8717 return comp.link_diags.fail("dumping link snapshot failed: {t}", .{err});8835 return diags.fail("dumping link snapshot failed: {t}", .{err});
8718}8836}
87198837
8720pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {8838pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {
...@@ -8737,8 +8855,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {...@@ -8737,8 +8855,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {
8737 const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(ii.node(elf)));8855 const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(ii.node(elf)));
8738 defer sub_prog_node.end();8856 defer sub_prog_node.end();
8739 elf.flushInput(ii) catch |err| switch (err) {8857 elf.flushInput(ii) catch |err| switch (err) {
8740 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
8741 else => |e| return e,8858 else => |e| return e,
8859 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
8742 };8860 };
8743 break :task;8861 break :task;
8744 }8862 }
...@@ -8748,8 +8866,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {...@@ -8748,8 +8866,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {
8748 const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf)));8866 const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf)));
8749 defer sub_prog_node.end();8867 defer sub_prog_node.end();
8750 elf.flushInputSection(isi) catch |err| switch (err) {8868 elf.flushInputSection(isi) catch |err| switch (err) {
8751 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
8752 else => |e| return e,8869 else => |e| return e,
8870 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
8753 };8871 };
8754 break :task;8872 break :task;
8755 }8873 }
...@@ -8907,11 +9025,12 @@ fn idleProgNode(...@@ -8907,11 +9025,12 @@ fn idleProgNode(
8907 .unit_debug_info_header,9025 .unit_debug_info_header,
8908 .unit_debug_line,9026 .unit_debug_line,
8909 .unit_debug_line_header,9027 .unit_debug_line_header,
9028 .unit_debug_rnglists,
8910 => |ui, tag| std.mem.print(&name, "{s} info for {s}", .{9029 => |ui, tag| std.mem.print(&name, "{s} info for {s}", .{
8911 switch (tag) {9030 switch (tag) {
8912 else => unreachable,9031 else => unreachable,
8913 .unit_frame, .unit_frame_cie => "unwind",9032 .unit_frame, .unit_frame_cie => "unwind",
8914 .unit_debug_info, .unit_debug_info_header => "debug",9033 .unit_debug_info, .unit_debug_info_header, .unit_debug_rnglists => "debug",
8915 .unit_debug_line, .unit_debug_line_header => "line",9034 .unit_debug_line, .unit_debug_line_header => "line",
8916 },9035 },
8917 ui.mod(&elf.dwarf).fully_qualified_name,9036 ui.mod(&elf.dwarf).fully_qualified_name,
...@@ -8996,8 +9115,8 @@ fn genUav(...@@ -8996,8 +9115,8 @@ fn genUav(
8996 &nw.interface,9115 &nw.interface,
8997 .{ .atom_index = Node.toAtom(ni) },9116 .{ .atom_index = Node.toAtom(ni) },
8998 ) catch |err| switch (err) {9117 ) catch |err| switch (err) {
8999 error.WriteFailed => return nw.err.?,
9000 else => |e| return e,9118 else => |e| return e,
9119 error.WriteFailed => return nw.err.?,
9001 };9120 };
9002 switch (elf.symPtr(umi.symbol(elf).index())) {9121 switch (elf.symPtr(umi.symbol(elf).index())) {
9003 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),9122 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),
...@@ -9032,8 +9151,8 @@ fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void {...@@ -9032,8 +9151,8 @@ fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void {
9032 .none,9151 .none,
9033 .{ .atom_index = Node.toAtom(ni) },9152 .{ .atom_index = Node.toAtom(ni) },
9034 ) catch |err| switch (err) {9153 ) catch |err| switch (err) {
9035 error.WriteFailed => return nw.err.?,
9036 else => |e| return e,9154 else => |e| return e,
9155 error.WriteFailed => return nw.err.?,
9037 };9156 };
9038 switch (elf.symPtr(lmr.symbol(elf).index())) {9157 switch (elf.symPtr(lmr.symbol(elf).index())) {
9039 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),9158 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),
...@@ -9241,14 +9360,18 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9241,14 +9360,18 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9241 reloc.apply(elf);9360 reloc.apply(elf);
9242 }9361 }
9243 } else if (shndx == elf.shndx.plt) {9362 } else if (shndx == elf.shndx.plt) {
9244 elf.flushMovedNodeRelocs(ni, addr, elf.plt_first_symbol_reloc, .none, .none);9363 elf.flushMovedNodeRelocs(ni, addr, .{
9364 .first_symbol_reloc = elf.plt_first_symbol_reloc,
9365 });
9245 elf.flushMovedPltSection(.plt, old_addr, addr);9366 elf.flushMovedPltSection(.plt, old_addr, addr);
9246 } else if (shndx == elf.shndx.got_plt) {9367 } else if (shndx == elf.shndx.got_plt) {
9247 elf.flushMovedPltSection(.got_plt, old_addr, addr);9368 elf.flushMovedPltSection(.got_plt, old_addr, addr);
9248 } else if (shndx == elf.shndx.plt_sec) {9369 } else if (shndx == elf.shndx.plt_sec) {
9249 elf.flushMovedPltSection(.plt_sec, old_addr, addr);9370 elf.flushMovedPltSection(.plt_sec, old_addr, addr);
9250 } else if (shndx == elf.shndx.eh_frame_hdr) {9371 } else if (shndx == elf.shndx.eh_frame_hdr) {
9251 elf.flushMovedNodeRelocs(ni, addr, elf.eh_frame_hdr_first_symbol_reloc, .none, .none);9372 elf.flushMovedNodeRelocs(ni, addr, .{
9373 .first_symbol_reloc = elf.eh_frame_hdr_first_symbol_reloc,
9374 });
9252 }9375 }
9253 },9376 },
9254 .input_section => |isi| {9377 .input_section => |isi| {
...@@ -9295,13 +9418,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9295,13 +9418,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9295 }9418 }
9296 }9419 }
92979420
9298 elf.flushMovedNodeRelocs(9421 elf.flushMovedNodeRelocs(ni, new_section_addr, .{
9299 ni,9422 .first_symbol_reloc = isi.ptrConst(elf).first_symbol_reloc,
9300 new_section_addr,9423 .first_got_reloc = isi.ptrConst(elf).first_got_reloc,
9301 isi.ptrConst(elf).first_symbol_reloc,9424 });
9302 .none,
9303 isi.ptrConst(elf).first_got_reloc,
9304 );
9305 },9425 },
9306 .copied_global => |global_name| {9426 .copied_global => |global_name| {
9307 const copied_global = elf.copied_globals.getPtr(global_name) orelse {9427 const copied_global = elf.copied_globals.getPtr(global_name) orelse {
...@@ -9327,13 +9447,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9327,13 +9447,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9327 name = elf.globalByName(name).?.next_in_node;9447 name = elf.globalByName(name).?.next_in_node;
9328 }9448 }
9329 }9449 }
9330 elf.flushMovedNodeRelocs(9450 elf.flushMovedNodeRelocs(ni, new_addr, .{
9331 ni,9451 .first_symbol_reloc = mi.firstSymbolReloc(elf),
9332 new_addr,9452 .first_got_reloc = mi.firstGotReloc(elf),
9333 mi.firstSymbolReloc(elf),9453 });
9334 .none,
9335 mi.firstGotReloc(elf),
9336 );
9337 },9454 },
9338 .debug_shared => |ss| {9455 .debug_shared => |ss| {
9339 var target_ri = elf.dwarf_shared.getPtr(ss).first_target_reloc;9456 var target_ri = elf.dwarf_shared.getPtr(ss).first_target_reloc;
...@@ -9364,13 +9481,9 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9364,13 +9481,9 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9364 target_reloc.apply(elf);9481 target_reloc.apply(elf);
9365 target_ri = target_reloc.next;9482 target_ri = target_reloc.next;
9366 }9483 }
9367 elf.flushMovedNodeRelocs(9484 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9368 ni,9485 .first_node_reloc = dwarf_unit.debug_info_header_first_node_reloc,
9369 elf.computeNodeVAddr(ni),9486 });
9370 .none,
9371 dwarf_unit.debug_info_header_first_node_reloc,
9372 .none,
9373 );
9374 },9487 },
9375 .unit_debug_line_header => |ui| {9488 .unit_debug_line_header => |ui| {
9376 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];9489 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];
...@@ -9381,13 +9494,32 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9381,13 +9494,32 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9381 target_reloc.apply(elf);9494 target_reloc.apply(elf);
9382 target_ri = target_reloc.next;9495 target_ri = target_reloc.next;
9383 }9496 }
9384 elf.flushMovedNodeRelocs(9497 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9385 ni,9498 .first_node_reloc = dwarf_unit.debug_line_header_first_node_reloc,
9386 elf.computeNodeVAddr(ni),9499 });
9387 .none,9500 },
9388 dwarf_unit.debug_line_header_first_node_reloc,9501 .unit_debug_rnglists => |ui| {
9389 .none,9502 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];
9390 );9503 var target_ri = dwarf_unit.debug_rnglists_first_target_reloc;
9504 while (target_ri != .none) {
9505 const target_reloc = target_ri.get(elf);
9506 assert(target_reloc.target == ni);
9507 target_reloc.apply(elf);
9508 target_ri = target_reloc.next;
9509 }
9510 const node_vaddr = elf.computeNodeVAddr(ni);
9511 for (dwarf_unit.debug_rnglists_symbol_relocs.keys()) |symbol_ri| {
9512 const symbol_reloc = symbol_ri.get(elf);
9513 assert(symbol_reloc.node == ni);
9514 if (symbol_reloc.rela_index.unwrap()) |rela_index| {
9515 // The node has moved, so the offset of the relocation within the section might have
9516 // changed, so update the `offset` field of the `ElfN.Rela` entry.
9517 symbol_reloc.relaSection(elf).relaSetOffset(elf, rela_index, node_vaddr + symbol_reloc.offset);
9518 }
9519 if (elf.ehdrType() != .REL) {
9520 symbol_reloc.apply(elf);
9521 }
9522 }
9391 },9523 },
9392 .value_debug_info => |vi| {9524 .value_debug_info => |vi| {
9393 const dwarf_value = &elf.dwarf_values.items[@backingInt(vi)];9525 const dwarf_value = &elf.dwarf_values.items[@backingInt(vi)];
...@@ -9398,13 +9530,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9398,13 +9530,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9398 target_reloc.apply(elf);9530 target_reloc.apply(elf);
9399 target_ri = target_reloc.next;9531 target_ri = target_reloc.next;
9400 }9532 }
9401 elf.flushMovedNodeRelocs(9533 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9402 ni,9534 .first_symbol_reloc = dwarf_value.debug_info_first_symbol_reloc,
9403 elf.computeNodeVAddr(ni),9535 .first_node_reloc = dwarf_value.debug_info_first_node_reloc,
9404 dwarf_value.debug_info_first_symbol_reloc,9536 });
9405 dwarf_value.debug_info_first_node_reloc,
9406 .none,
9407 );
9408 },9537 },
9409 .global_debug_info => |vi| {9538 .global_debug_info => |vi| {
9410 const dwarf_global = &elf.dwarf_globals.items[@backingInt(vi)];9539 const dwarf_global = &elf.dwarf_globals.items[@backingInt(vi)];
...@@ -9415,13 +9544,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9415,13 +9544,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9415 target_reloc.apply(elf);9544 target_reloc.apply(elf);
9416 target_ri = target_reloc.next;9545 target_ri = target_reloc.next;
9417 }9546 }
9418 elf.flushMovedNodeRelocs(9547 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9419 ni,9548 .first_symbol_reloc = dwarf_global.debug_info_first_symbol_reloc,
9420 elf.computeNodeVAddr(ni),9549 .first_node_reloc = dwarf_global.debug_info_first_node_reloc,
9421 dwarf_global.debug_info_first_symbol_reloc,9550 });
9422 dwarf_global.debug_info_first_node_reloc,
9423 .none,
9424 );
9425 },9551 },
9426 .func_frame_fde => |fi| {9552 .func_frame_fde => |fi| {
9427 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];9553 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
...@@ -9433,13 +9559,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9433,13 +9559,10 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9433 elf.dwarf.updateEhFrameFde(ni.slice(&elf.mf), offset);9559 elf.dwarf.updateEhFrameFde(ni.slice(&elf.mf), offset);
9434 },9560 },
9435 }9561 }
9436 elf.flushMovedNodeRelocs(9562 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9437 ni,9563 .first_symbol_reloc = dwarf_func.frame_fde_first_symbol_reloc,
9438 elf.computeNodeVAddr(ni),9564 .first_node_reloc = dwarf_func.frame_fde_first_node_reloc,
9439 dwarf_func.frame_fde_first_symbol_reloc,9565 });
9440 dwarf_func.frame_fde_first_node_reloc,
9441 .none,
9442 );
9443 },9566 },
9444 .func_debug_info => |fi| {9567 .func_debug_info => |fi| {
9445 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];9568 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
...@@ -9450,23 +9573,19 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9450,23 +9573,19 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9450 target_reloc.apply(elf);9573 target_reloc.apply(elf);
9451 target_ri = target_reloc.next;9574 target_ri = target_reloc.next;
9452 }9575 }
9453 elf.flushMovedNodeRelocs(9576 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9454 ni,9577 .ignore_node = fi.get(&elf.dwarf).debug_line_ni,
9455 elf.computeNodeVAddr(ni),9578 .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc,
9456 dwarf_func.debug_info_first_symbol_reloc,9579 .first_node_reloc = dwarf_func.debug_info_first_node_reloc,
9457 dwarf_func.debug_info_first_node_reloc,9580 });
9458 .none,
9459 );
9460 },9581 },
9461 .func_debug_line => |fi| {9582 .func_debug_line => |fi| {
9462 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];9583 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
9463 elf.flushMovedNodeRelocs(9584 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{
9464 ni,9585 .ignore_node = fi.get(&elf.dwarf).debug_info_ni,
9465 elf.computeNodeVAddr(ni),9586 .first_symbol_reloc = dwarf_func.debug_line_first_symbol_reloc,
9466 dwarf_func.debug_line_first_symbol_reloc,9587 .first_node_reloc = dwarf_func.debug_line_first_node_reloc,
9467 dwarf_func.debug_line_first_node_reloc,9588 });
9468 .none,
9469 );
9470 },9589 },
9471 }9590 }
9472 try ni.childrenMoved(elf.base.comp.gpa, &elf.mf);9591 try ni.childrenMoved(elf.base.comp.gpa, &elf.mf);
...@@ -9712,6 +9831,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo...@@ -9712,6 +9831,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
9712 .unit_debug_info_header,9831 .unit_debug_info_header,
9713 .unit_debug_line,9832 .unit_debug_line,
9714 .unit_debug_line_header,9833 .unit_debug_line_header,
9834 .unit_debug_rnglists,
9715 .value_debug_info,9835 .value_debug_info,
9716 .global_debug_info,9836 .global_debug_info,
9717 .func_frame_fde,9837 .func_frame_fde,
...@@ -9774,6 +9894,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -9774,6 +9894,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
9774 .unit_frame_cie,9894 .unit_frame_cie,
9775 .unit_debug_info_header,9895 .unit_debug_info_header,
9776 .unit_debug_line_header,9896 .unit_debug_line_header,
9897 .unit_debug_rnglists,
9777 .value_debug_info,9898 .value_debug_info,
9778 .global_debug_info,9899 .global_debug_info,
9779 .func_frame_fde,9900 .func_frame_fde,
...@@ -9788,15 +9909,15 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -9788,15 +9909,15 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
9788 break :slice parent_slice[@intCast(offset)..@intCast(next_offset)];9909 break :slice parent_slice[@intCast(offset)..@intCast(next_offset)];
9789 } else slice: switch (tag) {9910 } else slice: switch (tag) {
9790 else => unreachable,9911 else => unreachable,
9791 .unit_padding => {9912 .unit_padding, .unit_debug_rnglists => {
9792 const frame_slice = parent_ni.slicePadding(&elf.mf);9913 const parent_slice = parent_ni.slicePadding(&elf.mf);
9793 switch (elf.getNode(parent_ni).section.debugFrameFormat(elf) orelse .debug_frame) {9914 switch (elf.getNode(parent_ni).section.debugFrameFormat(elf) orelse .debug_frame) {
9794 .eh_frame => {9915 .eh_frame => {
9795 const end = frame_slice.len - 4;9916 const end = parent_slice.len - 4;
9796 std.mem.writeInt(u32, frame_slice[end..][0..4], 0, elf.dwarf.endian);9917 std.mem.writeInt(u32, parent_slice[end..][0..4], 0, elf.dwarf.endian);
9797 break :slice frame_slice[@intCast(offset)..end];9918 break :slice parent_slice[@intCast(offset)..end];
9798 },9919 },
9799 .debug_frame => break :slice frame_slice[@intCast(offset)..],9920 .debug_frame => break :slice parent_slice[@intCast(offset)..],
9800 }9921 }
9801 },9922 },
9802 .unit_frame_cie, .func_frame_fde => {9923 .unit_frame_cie, .func_frame_fde => {
...@@ -9840,36 +9961,64 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -9840,36 +9961,64 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
9840 break :debug_end @intCast(parent_next_offset);9961 break :debug_end @intCast(parent_next_offset);
9841 } else debug_slice.len]);9962 } else debug_slice.len]);
9842 fw.end = @intCast(offset + size);9963 fw.end = @intCast(offset + size);
9843 for (0..2) |_| fw.writeUleb128(@backingInt(Dwarf.AbbrevCode.null)) catch9964 switch (tag) {
9844 unreachable; // ensured by `updateFunc`9965 else => unreachable,
9845 elf.dwarf.updateUnitLength(fw.buffer, fw.end);9966 .unit_debug_info_header,
9967 .value_debug_info,
9968 .global_debug_info,
9969 .func_debug_info,
9970 => for (0..2) |_| fw.writeUleb128(@backingInt(Dwarf.AbbrevCode.null)) catch unreachable,
9971 .unit_debug_line_header, .func_debug_line => {},
9972 }
9973 const unit_padding_offset = fw.end;
9846 const unit_padding = fw.unusedCapacitySlice();9974 const unit_padding = fw.unusedCapacitySlice();
9847 elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) {9975 elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) {
9848 error.WriteFailed => {9976 error.WriteFailed => {
9849 comptime assert(Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) == 1);9977 fw.end = unit_padding_offset;
9850 @memset(fw.buffer, @backingInt(Dwarf.AbbrevCode.null));9978 elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len);
9979 switch (tag) {
9980 else => unreachable,
9981 .unit_debug_info_header, .value_debug_info, .global_debug_info, .func_debug_info => {
9982 comptime assert(Dwarf.uleb128Bytes(@backingInt(Dwarf.AbbrevCode.null)) == 1);
9983 @memset(fw.unusedCapacitySlice(), @backingInt(Dwarf.AbbrevCode.null));
9984 },
9985 .unit_debug_line_header, .func_debug_line => Dwarf.genDebugLinePadding(&fw, fw.unusedCapacityLen()) catch
9986 unreachable,
9987 }
9988 return;
9851 },9989 },
9852 };9990 };
9991 elf.dwarf.updateUnitLength(fw.buffer, unit_padding_offset);
9853 elf.dwarf.updateUnitLength(unit_padding, unit_padding.len);9992 elf.dwarf.updateUnitLength(unit_padding, unit_padding.len);
9854 return;9993 return;
9855 },9994 },
9856 };9995 };
9996 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);
9857 switch (tag) {9997 switch (tag) {
9858 else => unreachable,9998 else => unreachable,
9859 .unit_padding => elf.dwarf.updateUnitLength(slice, slice.len),9999 .unit_padding => elf.dwarf.updateUnitLength(slice, slice.len),
9860 .unit_frame_cie, .func_frame_fde => {10000 .unit_frame_cie, .func_frame_fde => {
9861 elf.dwarf.updateUnitLength(slice, slice.len);10001 elf.dwarf.updateUnitLength(slice, slice.len);
9862 @memset(slice[@intCast(size)..], std.dwarf.CFA.nop);10002 @memset(fw.buffer, std.dwarf.CFA.nop);
9863 },10003 },
9864 .unit_debug_info_header,10004 .unit_debug_info_header,
9865 .unit_debug_line_header,
9866 .value_debug_info,10005 .value_debug_info,
9867 .global_debug_info,10006 .global_debug_info,
9868 .func_debug_info,10007 .func_debug_info,
10008 => elf.dwarf.genDebugInfoPadding(&fw, fw.buffer.len) catch unreachable,
10009 .unit_debug_line_header,
9869 .func_debug_line,10010 .func_debug_line,
9870 => {10011 => Dwarf.genDebugLinePadding(&fw, fw.buffer.len) catch unreachable,
9871 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);10012 .unit_debug_rnglists => {
9872 elf.dwarf.genDebugInfoPadding(&fw, fw.unusedCapacityLen()) catch unreachable;10013 elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) {
10014 error.WriteFailed => {
10015 elf.dwarf.updateUnitLength(slice, slice.len);
10016 @memset(fw.buffer, std.dwarf.RLE.end_of_list);
10017 return;
10018 },
10019 };
10020 elf.dwarf.updateUnitLength(slice, size);
10021 elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len);
9873 },10022 },
9874 }10023 }
9875 },10024 },
...@@ -10229,11 +10378,10 @@ pub fn updateExports(...@@ -10229,11 +10378,10 @@ pub fn updateExports(
10229 pt: Zcu.PerThread,10378 pt: Zcu.PerThread,
10230 export_indices: []const Zcu.Export.Index,10379 export_indices: []const Zcu.Export.Index,
10231) link.Error!void {10380) link.Error!void {
10232 const diags = &elf.base.comp.link_diags;
10233 for (export_indices) |export_index| {10381 for (export_indices) |export_index| {
10234 elf.updateExportInner(pt, export_index) catch |err| switch (err) {10382 elf.updateExportInner(pt, export_index) catch |err| switch (err) {
10235 else => |e| return e,10383 else => |e| return e,
10236 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),10384 error.MappedFileIo => return elf.base.comp.link_diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
10237 };10385 };
10238 }10386 }
10239}10387}
...@@ -10377,7 +10525,7 @@ pub fn printNode(...@@ -10377,7 +10525,7 @@ pub fn printNode(
10377 const ip = &zcu.intern_pool;10525 const ip = &zcu.intern_pool;
10378 const nav = ip.getNav(nmi.navIndex(elf));10526 const nav = ip.getNav(nmi.navIndex(elf));
10379 try w.print("({f}, {f})", .{10527 try w.print("({f}, {f})", .{
10380 Type.fromInterned(ip.typeOf(nav.resolved.?.value)).fmt(.{ .zcu = zcu, .tid = tid }),10528 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
10381 nav.fqn.fmt(ip),10529 nav.fqn.fmt(ip),
10382 });10530 });
10383 },10531 },
...@@ -10402,9 +10550,8 @@ pub fn printNode(...@@ -10402,9 +10550,8 @@ pub fn printNode(
10402 .unit_debug_info_header,10550 .unit_debug_info_header,
10403 .unit_debug_line,10551 .unit_debug_line,
10404 .unit_debug_line_header,10552 .unit_debug_line_header,
10405 => |ui| try w.print("({s})", .{10553 .unit_debug_rnglists,
10406 ui.mod(&elf.dwarf).fully_qualified_name,10554 => |ui| try w.print("({s})", .{ui.mod(&elf.dwarf).fully_qualified_name}),
10407 }),
10408 .value_debug_info => |cpi| try w.print("({f})", .{10555 .value_debug_info => |cpi| try w.print("({f})", .{
10409 Value.fromInterned(cpi.val(&elf.dwarf.const_pool))10556 Value.fromInterned(cpi.val(&elf.dwarf.const_pool))
10410 .fmtValue(.{ .zcu = elf.base.comp.zcu.?, .tid = tid }),10557 .fmtValue(.{ .zcu = elf.base.comp.zcu.?, .tid = tid }),
...@@ -10414,7 +10561,7 @@ pub fn printNode(...@@ -10414,7 +10561,7 @@ pub fn printNode(
10414 const ip = &zcu.intern_pool;10561 const ip = &zcu.intern_pool;
10415 const nav = ip.getNav(gi.nav(&elf.dwarf));10562 const nav = ip.getNav(gi.nav(&elf.dwarf));
10416 try w.print("({f}, {f})", .{10563 try w.print("({f}, {f})", .{
10417 Type.fromInterned(ip.typeOf(nav.resolved.?.value)).fmt(.{ .zcu = zcu, .tid = tid }),10564 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
10418 nav.fqn.fmt(ip),10565 nav.fqn.fmt(ip),
10419 });10566 });
10420 },10567 },
...@@ -10423,7 +10570,7 @@ pub fn printNode(...@@ -10423,7 +10570,7 @@ pub fn printNode(
10423 const ip = &zcu.intern_pool;10570 const ip = &zcu.intern_pool;
10424 const nav = ip.getNav(fi.nav(&elf.dwarf));10571 const nav = ip.getNav(fi.nav(&elf.dwarf));
10425 try w.print("({f}, {f})", .{10572 try w.print("({f}, {f})", .{
10426 Type.fromInterned(ip.typeOf(nav.resolved.?.value)).fmt(.{ .zcu = zcu, .tid = tid }),10573 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
10427 nav.fqn.fmt(ip),10574 nav.fqn.fmt(ip),
10428 });10575 });
10429 },10576 },