authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-07 19:37:01-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-07 19:53:17-04:00
loga059c9a5e57164338bf4b99728905882b0d6323c
treef88220844871861ef457de9ca3ed8aaf17a87089
parent5637ede041a9b8b0a050343be5392f97994f6777

Dwarf2: use indexed addresses

This saves another ~70MB.

3 files changed, 229 insertions(+), 59 deletions(-)

src/codegen/x86_64/Emit.zig+18-13
...@@ -552,9 +552,9 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -552,9 +552,9 @@ pub fn emitMir(emit: *Emit) Error!void {
552 .pseudo_dbg_var_m,552 .pseudo_dbg_var_m,
553 => switch (emit.debug_output) {553 => switch (emit.debug_output) {
554 inline .dwarf, .dwarf2 => |dwarf, tag| {554 inline .dwarf, .dwarf2 => |dwarf, tag| {
555 const DwarfLoc = switch (tag) {555 const DwarfLoc, const addr_loc = switch (tag) {
556 .dwarf => link.File.Dwarf.Loc,556 .dwarf => .{ link.File.Dwarf.Loc, "addr_reloc" },
557 .dwarf2 => link.File.Dwarf2.Loc,557 .dwarf2 => .{ link.File.Dwarf2.Loc, "addrx_sym" },
558 .eh_frame, .none => comptime unreachable,558 .eh_frame, .none => comptime unreachable,
559 };559 };
560 var loc_buf: [2]DwarfLoc = undefined;560 var loc_buf: [2]DwarfLoc = undefined;
...@@ -597,16 +597,21 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -597,16 +597,21 @@ pub fn emitMir(emit: *Emit) Error!void {
597 .none => .{ .constu = 0 },597 .none => .{ .constu = 0 },
598 .reg => |reg| .{ .breg = reg.dwarfNum() },598 .reg => |reg| .{ .breg = reg.dwarfNum() },
599 .frame, .table, .rip_inst => unreachable,599 .frame, .table, .rip_inst => unreachable,
600 .nav => |nav| .{ .addr_reloc = try codegen.genNavRef(600 .nav => |nav| @unionInit(
601 emit.bin_file,601 DwarfLoc,
602 emit.pt,602 addr_loc,
603 nav,603 try codegen.genNavRef(emit.bin_file, emit.pt, nav),
604 ) },604 ),
605 .uav => |uav| .{ .addr_reloc = try emit.bin_file.lowerUav(605 .uav => |uav| @unionInit(
606 emit.pt,606 DwarfLoc,
607 uav.val,607 addr_loc,
608 Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu),608 try emit.bin_file.lowerUav(
609 ) },609 emit.pt,
610 uav.val,
611 Type.fromInterned(uav.orig_ty)
612 .ptrAlignment(emit.pt.zcu),
613 ),
614 ),
610 .lazy_sym, .extern_func => unreachable,615 .lazy_sym, .extern_func => unreachable,
611 };616 };
612 break :base &loc_buf[0];617 break :base &loc_buf[0];
src/link/Dwarf2.zig+108-28
...@@ -13,6 +13,7 @@ decls: std.array_hash_map.Auto(InternPool.TrackedInst.Index, Decl),...@@ -13,6 +13,7 @@ decls: std.array_hash_map.Auto(InternPool.TrackedInst.Index, Decl),
13pending_decl: struct { di: Decl.Index, instance: Decl.Instance },13pending_decl: struct { di: Decl.Index, instance: Decl.Instance },
1414
15debug_abbrev: Abbrev,15debug_abbrev: Abbrev,
16debug_addr: Addr,
16frame: Frame,17frame: Frame,
17debug_info: Info,18debug_info: Info,
18debug_line: Line,19debug_line: Line,
...@@ -182,6 +183,29 @@ pub const Abbrev = struct {...@@ -182,6 +183,29 @@ pub const Abbrev = struct {
182 set: std.enums.EnumSet(AbbrevCode),183 set: std.enums.EnumSet(AbbrevCode),
183};184};
184185
186pub const Addr = struct {
187 ni: link.MappedFile.Node.Index.Optional,
188 pending_index: usize,
189 map: std.array_hash_map.Auto(link.File.SymbolId, void),
190
191 fn get(a: *Addr, gpa: std.mem.Allocator, si: link.File.SymbolId) std.mem.Allocator.Error!usize {
192 const gop = try a.map.getOrPut(gpa, si);
193 return gop.index;
194 }
195
196 fn tableOffset(dwarf: *Dwarf) usize {
197 return dwarf.unitLengthSize() + 2 + 1 + 1;
198 }
199
200 pub fn size(a: *Addr, dwarf: *Dwarf) usize {
201 return tableOffset(dwarf) + @backingInt(dwarf.address_size) * a.pending_index;
202 }
203
204 pub fn anyPending(a: *Addr) bool {
205 return a.map.count() - a.pending_index > 0;
206 }
207};
208
185pub const Info = struct {};209pub const Info = struct {};
186210
187pub const Line = struct {211pub const Line = struct {
...@@ -274,12 +298,14 @@ pub const StrOffsets = struct {...@@ -274,12 +298,14 @@ pub const StrOffsets = struct {
274 ) link.Error!usize {298 ) link.Error!usize {
275 const comp = dwarf.lf.comp;299 const comp = dwarf.lf.comp;
276 try so.map.ensureUnusedCapacity(comp.gpa, 1);300 try so.map.ensureUnusedCapacity(comp.gpa, 1);
277 return so.map.getOrPutAssumeCapacity(s.get(comp.gpa, mf, str) catch |err| switch (err) {301 const offset = s.get(comp.gpa, mf, str) catch |err| switch (err) {
278 else => |e| return e,302 else => |e| return e,
279 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{303 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
280 mf.io_err.?,304 mf.io_err.?,
281 }),305 }),
282 }).index;306 };
307 const gop = so.map.getOrPutAssumeCapacity(offset);
308 return gop.index;
283 }309 }
284310
285 fn tableOffset(dwarf: *Dwarf) usize {311 fn tableOffset(dwarf: *Dwarf) usize {
...@@ -289,13 +315,20 @@ pub const StrOffsets = struct {...@@ -289,13 +315,20 @@ pub const StrOffsets = struct {
289 pub fn size(so: *StrOffsets, dwarf: *Dwarf) usize {315 pub fn size(so: *StrOffsets, dwarf: *Dwarf) usize {
290 return tableOffset(dwarf) + dwarf.secOffsetSize() * so.pending_index;316 return tableOffset(dwarf) + dwarf.secOffsetSize() * so.pending_index;
291 }317 }
318
319 pub fn anyPending(so: *StrOffsets) bool {
320 return so.map.count() - so.pending_index > 0;
321 }
292};322};
293323
294pub const SharedSection = enum { debug_abbrev, debug_line_str, debug_str };324pub const SharedSection = enum { debug_abbrev, debug_line_str, debug_str };
295325
296pub const Loc = union(enum) {326pub const Loc = union(enum) {
297 empty,327 empty,
298 addr_reloc: link.File.SymbolId,328 addr_sym: struct {
329 si: link.File.SymbolId,
330 offset: usize = 0,
331 },
299 deref: *const Loc,332 deref: *const Loc,
300 constu: u64,333 constu: u64,
301 consts: i64,334 consts: i64,
...@@ -314,6 +347,8 @@ pub const Loc = union(enum) {...@@ -314,6 +347,8 @@ pub const Loc = union(enum) {
314 node: link.MappedFile.Node.Index,347 node: link.MappedFile.Node.Index,
315 offset: i65 = 0,348 offset: i65 = 0,
316 },349 },
350 addrx_sym: link.File.SymbolId,
351 constx_sym: link.File.SymbolId,
317 wasm_ext: union(enum) {352 wasm_ext: union(enum) {
318 local: u32,353 local: u32,
319 global: u32,354 global: u32,
...@@ -356,11 +391,11 @@ pub const Loc = union(enum) {...@@ -356,11 +391,11 @@ pub const Loc = union(enum) {
356 };391 };
357 switch (loc) {392 switch (loc) {
358 .empty => {},393 .empty => {},
359 .addr_reloc => |si| {394 .addr_sym => |sym| {
360 try w.writeByte(DW.OP.addr);395 try w.writeByte(DW.OP.addr);
361 switch (writer) {396 switch (writer) {
362 .io => try dwarf.addrPlaceholder(w),397 .io => try dwarf.addrPlaceholder(w),
363 .mf => |nw| try dwarf.addrSym(nw, si, 0),398 .mf => |nw| try dwarf.addrSym(nw, sym.si, sym.offset),
364 }399 }
365 },400 },
366 .deref => |addr| {401 .deref => |addr| {
...@@ -479,6 +514,14 @@ pub const Loc = union(enum) {...@@ -479,6 +514,14 @@ pub const Loc = union(enum) {
479 }514 }
480 try w.writeSleb128(implicit_pointer.offset);515 try w.writeSleb128(implicit_pointer.offset);
481 },516 },
517 .addrx_sym => |si| {
518 try w.writeByte(DW.OP.addrx);
519 try dwarf.addrxSym(w, si);
520 },
521 .constx_sym => |si| {
522 try w.writeByte(DW.OP.constx);
523 try dwarf.addrxSym(w, si);
524 },
482 .wasm_ext => |wasm_ext| {525 .wasm_ext => |wasm_ext| {
483 try w.writeByte(DW.OP.WASM_location);526 try w.writeByte(DW.OP.WASM_location);
484 switch (wasm_ext) {527 switch (wasm_ext) {
...@@ -731,14 +774,16 @@ pub const WipFunc = struct {...@@ -731,14 +774,16 @@ pub const WipFunc = struct {
731 .@"extern", .@"export" => nav.name,774 .@"extern", .@"export" => nav.name,
732 }.toSlice(ip));775 }.toSlice(ip));
733 try dwarf.refType(pt, di_nw, .fromInterned(func_type.return_type));776 try dwarf.refType(pt, di_nw, .fromInterned(func_type.return_type));
734 try dwarf.addrSym(di_nw, debug.wip_func.func_si, 0);777 try dwarf.addrxSym(di_w, debug.wip_func.func_si);
735 debug.info_func_length_offset = di_w.end;778 debug.info_func_length_offset = di_w.end;
736 try di_w.writeInt(u32, undefined, dwarf.endian);779 try di_w.writeInt(u32, undefined, dwarf.endian);
737 try di_w.writeUleb128(780 try di_w.writeUleb128(
738 target_info.minFunctionAlignment(target).max(nav.resolved.?.@"align").toByteUnits().?,781 target_info.minFunctionAlignment(target).max(nav.resolved.?.@"align").toByteUnits().?,
739 );782 );
740 try di_w.writeByte(@intFromBool(decl.linkage != .normal));783 try di_w.writeAll(&.{
741 try di_w.writeByte(@intFromBool(Type.fromInterned(func_type.return_type).isNoReturn(zcu)));784 @intFromBool(decl.linkage != .normal),
785 @intFromBool(Type.fromInterned(func_type.return_type).isNoReturn(zcu)),
786 });
742 }787 }
743788
744 pub fn startDebugLine(debug: *Debug) link.Error!void {789 pub fn startDebugLine(debug: *Debug) link.Error!void {
...@@ -1284,6 +1329,11 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {...@@ -1284,6 +1329,11 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
1284 .end = 0,1329 .end = 0,
1285 .set = .empty,1330 .set = .empty,
1286 },1331 },
1332 .debug_addr = .{
1333 .ni = .none,
1334 .pending_index = 0,
1335 .map = .empty,
1336 },
1287 .frame = .{1337 .frame = .{
1288 .header = if (target.cpu.arch == .x86_64 and target.ofmt == .elf) header: {1338 .header = if (target.cpu.arch == .x86_64 and target.ofmt == .elf) header: {
1289 dev.checkAny(&.{ .llvm_backend, .x86_64_backend });1339 dev.checkAny(&.{ .llvm_backend, .x86_64_backend });
...@@ -1353,6 +1403,7 @@ pub fn deinit(dwarf: *Dwarf) void {...@@ -1353,6 +1403,7 @@ pub fn deinit(dwarf: *Dwarf) void {
1353 dwarf.globals.deinit(gpa);1403 dwarf.globals.deinit(gpa);
1354 dwarf.funcs.deinit(gpa);1404 dwarf.funcs.deinit(gpa);
1355 dwarf.decls.deinit(gpa);1405 dwarf.decls.deinit(gpa);
1406 dwarf.debug_addr.map.deinit(gpa);
1356 dwarf.debug_line_str.map.deinit(gpa);1407 dwarf.debug_line_str.map.deinit(gpa);
1357 dwarf.debug_str.map.deinit(gpa);1408 dwarf.debug_str.map.deinit(gpa);
1358 dwarf.debug_str_offsets.map.deinit(gpa);1409 dwarf.debug_str_offsets.map.deinit(gpa);
...@@ -1620,6 +1671,24 @@ pub fn genUnitPadding(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void...@@ -1620,6 +1671,24 @@ pub fn genUnitPadding(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void
1620 try w.writeInt(u16, 0, dwarf.endian);1671 try w.writeInt(u16, 0, dwarf.endian);
1621}1672}
16221673
1674pub fn genDebugAddrHeader(dwarf: *Dwarf, dah_w: *std.Io.Writer) std.Io.Writer.Error!void {
1675 try dwarf.genUnitLength(dah_w);
1676 try dah_w.writeInt(u16, 5, dwarf.endian);
1677 try dah_w.writeAll(&.{ @backingInt(dwarf.address_size), 0 });
1678 assert(dah_w.end == Addr.tableOffset(dwarf));
1679}
1680
1681pub fn genPendingDebugAddr(dwarf: *Dwarf, da_nw: *link.MappedFile.Node.Writer) link.Error!void {
1682 da_nw.interface.end = dwarf.debug_addr.size(dwarf);
1683 for (dwarf.debug_addr.map.keys()[dwarf.debug_addr.pending_index..]) |si| {
1684 dwarf.addrSym(da_nw, si, 0) catch |err| switch (err) {
1685 else => |e| return e,
1686 error.WriteFailed => return dwarf.reportWriteError(da_nw),
1687 };
1688 dwarf.debug_addr.pending_index += 1;
1689 }
1690}
1691
1623pub const EhFrameHdr = extern struct {1692pub const EhFrameHdr = extern struct {
1624 version: u8,1693 version: u8,
1625 eh_frame_ptr_enc: std.dwarf.EH.PE,1694 eh_frame_ptr_enc: std.dwarf.EH.PE,
...@@ -1675,11 +1744,7 @@ pub fn genDebugFrameCie(...@@ -1675,11 +1744,7 @@ pub fn genDebugFrameCie(
1675 const Register = @import("../codegen/x86_64/bits.zig").Register;1744 const Register = @import("../codegen/x86_64/bits.zig").Register;
1676 switch (format) {1745 switch (format) {
1677 .eh_frame => try df_w.writeAll("zR\x00"),1746 .eh_frame => try df_w.writeAll("zR\x00"),
1678 .debug_frame => {1747 .debug_frame => try df_w.writeAll("\x00" ++ .{ @backingInt(dwarf.address_size), 0 }),
1679 try df_w.writeAll("\x00");
1680 try df_w.writeByte(@backingInt(dwarf.address_size));
1681 try df_w.writeByte(0);
1682 },
1683 }1748 }
1684 try df_w.writeUleb128(dwarf.frame.header.code_alignment_factor);1749 try df_w.writeUleb128(dwarf.frame.header.code_alignment_factor);
1685 try df_w.writeSleb128(dwarf.frame.header.data_alignment_factor);1750 try df_w.writeSleb128(dwarf.frame.header.data_alignment_factor);
...@@ -1726,8 +1791,7 @@ pub fn genDebugInfoHeader(...@@ -1726,8 +1791,7 @@ pub fn genDebugInfoHeader(
1726 if (!unit.alive) return dwarf.genUnitPadding(dih_w);1791 if (!unit.alive) return dwarf.genUnitPadding(dih_w);
1727 try dwarf.genUnitLength(dih_w);1792 try dwarf.genUnitLength(dih_w);
1728 try dih_w.writeInt(u16, 5, dwarf.endian);1793 try dih_w.writeInt(u16, 5, dwarf.endian);
1729 try dih_w.writeByte(DW.UT.compile);1794 try dih_w.writeAll(&.{ DW.UT.compile, @backingInt(dwarf.address_size) });
1730 try dih_w.writeByte(@backingInt(dwarf.address_size));
1731 try dwarf.secOffset(dih_nw, dwarf.debug_abbrev.ni.unwrap().?, 0);1795 try dwarf.secOffset(dih_nw, dwarf.debug_abbrev.ni.unwrap().?, 0);
1732 const compile_unit_offset = dih_w.end;1796 const compile_unit_offset = dih_w.end;
1733 try dwarf.abbrevCode(dih_nw, .compile_unit);1797 try dwarf.abbrevCode(dih_nw, .compile_unit);
...@@ -1738,6 +1802,7 @@ pub fn genDebugInfoHeader(...@@ -1738,6 +1802,7 @@ pub fn genDebugInfoHeader(
1738 compile_unit_offset,1802 compile_unit_offset,
1739 );1803 );
1740 try dwarf.secOffset(dih_nw, unit.debug_line_header_ni.unwrap().?, 0);1804 try dwarf.secOffset(dih_nw, unit.debug_line_header_ni.unwrap().?, 0);
1805 try dwarf.secOffset(dih_nw, dwarf.debug_addr.ni.unwrap().?, Addr.tableOffset(dwarf));
1741 try dwarf.secOffset(dih_nw, unit.debug_rnglists_ni.unwrap().?, Rnglists.tableOffset(dwarf));1806 try dwarf.secOffset(dih_nw, unit.debug_rnglists_ni.unwrap().?, Rnglists.tableOffset(dwarf));
1742 try dwarf.secOffset(dih_nw, dwarf.debug_str_offsets.ni.unwrap().?, StrOffsets.tableOffset(dwarf));1807 try dwarf.secOffset(dih_nw, dwarf.debug_str_offsets.ni.unwrap().?, StrOffsets.tableOffset(dwarf));
1743 try dwarf.strx1(dih_nw, "zig " ++ @import("build_options").version);1808 try dwarf.strx1(dih_nw, "zig " ++ @import("build_options").version);
...@@ -1818,8 +1883,7 @@ pub fn genDebugLineHeader(...@@ -1818,8 +1883,7 @@ pub fn genDebugLineHeader(
1818 const dlh_w = &dlh_nw.interface;1883 const dlh_w = &dlh_nw.interface;
1819 try dwarf.genUnitLength(dlh_w);1884 try dwarf.genUnitLength(dlh_w);
1820 try dlh_w.writeInt(u16, 5, dwarf.endian);1885 try dlh_w.writeInt(u16, 5, dwarf.endian);
1821 try dlh_w.writeByte(@backingInt(dwarf.address_size));1886 try dlh_w.writeAll(&.{ @backingInt(dwarf.address_size), 0 });
1822 try dlh_w.writeByte(0);
1823 const header_length_offset = dlh_w.end;1887 const header_length_offset = dlh_w.end;
1824 switch (dwarf.format) {1888 switch (dwarf.format) {
1825 .@"32" => try dlh_w.writeInt(u32, undefined, dwarf.endian),1889 .@"32" => try dlh_w.writeInt(u32, undefined, dwarf.endian),
...@@ -1950,8 +2014,7 @@ pub fn genDebugRnglistsHeader(...@@ -1950,8 +2014,7 @@ pub fn genDebugRnglistsHeader(
1950 const drh_w = &drh_nw.interface;2014 const drh_w = &drh_nw.interface;
1951 try dwarf.genUnitLength(drh_w);2015 try dwarf.genUnitLength(drh_w);
1952 try drh_w.writeInt(u16, 5, dwarf.endian);2016 try drh_w.writeInt(u16, 5, dwarf.endian);
1953 try drh_w.writeByte(@backingInt(dwarf.address_size));2017 try drh_w.writeAll(&.{ @backingInt(dwarf.address_size), 0 });
1954 try drh_w.writeByte(0);
1955 try drh_w.writeInt(u32, 1, dwarf.endian);2018 try drh_w.writeInt(u32, 1, dwarf.endian);
1956 assert(drh_w.end == Rnglists.tableOffset(dwarf));2019 assert(drh_w.end == Rnglists.tableOffset(dwarf));
1957 switch (dwarf.format) {2020 switch (dwarf.format) {
...@@ -1971,8 +2034,8 @@ pub fn genDebugRnglistsRange(...@@ -1971,8 +2034,8 @@ pub fn genDebugRnglistsRange(
1971) link.EmitError!void {2034) link.EmitError!void {
1972 const dr_w = &dr_nw.interface;2035 const dr_w = &dr_nw.interface;
1973 dr_w.end = unit.debug_rnglists_end;2036 dr_w.end = unit.debug_rnglists_end;
1974 try dr_w.writeByte(DW.RLE.start_length);2037 try dr_w.writeByte(DW.RLE.startx_length);
1975 try dwarf.addrSym(dr_nw, func_si, 0);2038 try dwarf.addrxSym(dr_w, func_si);
1976 try dr_w.writeUleb128(func_length);2039 try dr_w.writeUleb128(func_length);
1977 unit.debug_rnglists_end = dr_w.end;2040 unit.debug_rnglists_end = dr_w.end;
1978 try dr_w.writeByte(DW.RLE.end_of_list);2041 try dr_w.writeByte(DW.RLE.end_of_list);
...@@ -1986,9 +2049,10 @@ pub fn genDebugStrOffsetsHeader(dwarf: *Dwarf, dsoh_w: *std.Io.Writer) std.Io.Wr...@@ -1986,9 +2049,10 @@ pub fn genDebugStrOffsetsHeader(dwarf: *Dwarf, dsoh_w: *std.Io.Writer) std.Io.Wr
1986}2049}
19872050
1988pub fn genPendingDebugStrOffsets(dwarf: *Dwarf, dso_nw: *link.MappedFile.Node.Writer) link.Error!void {2051pub fn genPendingDebugStrOffsets(dwarf: *Dwarf, dso_nw: *link.MappedFile.Node.Writer) link.Error!void {
2052 const debug_str_ni = dwarf.debug_str.ni.unwrap().?;
1989 dso_nw.interface.end = dwarf.debug_str_offsets.size(dwarf);2053 dso_nw.interface.end = dwarf.debug_str_offsets.size(dwarf);
1990 for (dwarf.debug_str_offsets.map.keys()[dwarf.debug_str_offsets.pending_index..]) |offset| {2054 for (dwarf.debug_str_offsets.map.keys()[dwarf.debug_str_offsets.pending_index..]) |offset| {
1991 dwarf.secOffset(dso_nw, dwarf.debug_str.ni.unwrap().?, offset) catch |err| switch (err) {2055 dwarf.secOffset(dso_nw, debug_str_ni, offset) catch |err| switch (err) {
1992 else => |e| return e,2056 else => |e| return e,
1993 error.WriteFailed => return dwarf.reportWriteError(dso_nw),2057 error.WriteFailed => return dwarf.reportWriteError(dso_nw),
1994 };2058 };
...@@ -2081,7 +2145,7 @@ fn updateExternInner(...@@ -2081,7 +2145,7 @@ fn updateExternInner(
2081 if (func_type.is_var_args) try dwarf.abbrevCode(di_nw, .is_var_args);2145 if (func_type.is_var_args) try dwarf.abbrevCode(di_nw, .is_var_args);
2082 if (!is_empty) try di_w.writeUleb128(@backingInt(AbbrevCode.null));2146 if (!is_empty) try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2083 } else {2147 } else {
2084 const addr: Loc = .{ .addr_reloc = si };2148 const addr: Loc = .{ .addr_sym = .{ .si = si } };
2085 const loc: Loc = if (nav_threadlocal) switch (arch) {2149 const loc: Loc = if (nav_threadlocal) switch (arch) {
2086 .x86_64 => .{ .form_tls_address = &addr },2150 .x86_64 => .{ .form_tls_address = &addr },
2087 else => unreachable,2151 else => unreachable,
...@@ -2169,7 +2233,7 @@ fn updateGlobalInner(...@@ -2169,7 +2233,7 @@ fn updateGlobalInner(
2169 .@"extern" => unreachable,2233 .@"extern" => unreachable,
2170 .@"export" => nav.name,2234 .@"export" => nav.name,
2171 }.toSlice(ip));2235 }.toSlice(ip));
2172 const addr: Loc = .{ .addr_reloc = si };2236 const addr: Loc = .{ .addr_sym = .{ .si = si } };
2173 const loc: Loc = if (nav_threadlocal) switch (arch) {2237 const loc: Loc = if (nav_threadlocal) switch (arch) {
2174 .x86_64 => .{ .form_tls_address = &addr },2238 .x86_64 => .{ .form_tls_address = &addr },
2175 else => unreachable,2239 else => unreachable,
...@@ -4403,6 +4467,21 @@ fn addrSym(...@@ -4403,6 +4467,21 @@ fn addrSym(
4403 .absAddr(elf),4467 .absAddr(elf),
4404 ) else unreachable;4468 ) else unreachable;
4405}4469}
4470fn addrxSym(dwarf: *Dwarf, w: *std.Io.Writer, si: link.File.SymbolId) link.EmitError!void {
4471 try w.writeUleb128(try dwarf.debug_addr.get(dwarf.lf.comp.gpa, si));
4472}
4473fn addrx1Sym(dwarf: *Dwarf, w: *std.Io.Writer, si: link.File.SymbolId) link.EmitError!void {
4474 try w.writeByte(@intCast(try dwarf.debug_addr.get(dwarf.lf.comp.gpa, si)));
4475}
4476fn addrx2Sym(dwarf: *Dwarf, w: *std.Io.Writer, si: link.File.SymbolId) link.EmitError!void {
4477 try w.writeInt(u16, @intCast(try dwarf.debug_addr.get(dwarf.lf.comp.gpa, si)), dwarf.endian);
4478}
4479fn addrx3Sym(dwarf: *Dwarf, w: *std.Io.Writer, si: link.File.SymbolId) link.EmitError!void {
4480 try w.writeInt(u24, @intCast(try dwarf.debug_addr.get(dwarf.lf.comp.gpa, si)), dwarf.endian);
4481}
4482fn addrx4Sym(dwarf: *Dwarf, w: *std.Io.Writer, si: link.File.SymbolId) link.EmitError!void {
4483 try w.writeInt(u32, @intCast(try dwarf.debug_addr.get(dwarf.lf.comp.gpa, si)), dwarf.endian);
4484}
44064485
4407fn blockConst(4486fn blockConst(
4408 dwarf: *Dwarf,4487 dwarf: *Dwarf,
...@@ -5072,7 +5151,7 @@ pub const AbbrevCode = enum {...@@ -5072,7 +5151,7 @@ pub const AbbrevCode = enum {
5072 .attrs = decl_attrs ++ .{5151 .attrs = decl_attrs ++ .{
5073 .{ .linkage_name, .strx },5152 .{ .linkage_name, .strx },
5074 .{ .type, .ref_addr },5153 .{ .type, .ref_addr },
5075 .{ .low_pc, .addr },5154 .{ .low_pc, .addrx },
5076 .{ .high_pc, .data4 },5155 .{ .high_pc, .data4 },
5077 .{ .alignment, .udata },5156 .{ .alignment, .udata },
5078 .{ .external, .flag },5157 .{ .external, .flag },
...@@ -5085,7 +5164,7 @@ pub const AbbrevCode = enum {...@@ -5085,7 +5164,7 @@ pub const AbbrevCode = enum {
5085 .attrs = decl_attrs ++ .{5164 .attrs = decl_attrs ++ .{
5086 .{ .linkage_name, .strx },5165 .{ .linkage_name, .strx },
5087 .{ .type, .ref_addr },5166 .{ .type, .ref_addr },
5088 .{ .low_pc, .addr },5167 .{ .low_pc, .addrx },
5089 .{ .high_pc, .data4 },5168 .{ .high_pc, .data4 },
5090 .{ .alignment, .udata },5169 .{ .alignment, .udata },
5091 .{ .external, .flag },5170 .{ .external, .flag },
...@@ -5353,7 +5432,7 @@ pub const AbbrevCode = enum {...@@ -5353,7 +5432,7 @@ pub const AbbrevCode = enum {
5353 .attrs = decl_instance_attrs ++ .{5432 .attrs = decl_instance_attrs ++ .{
5354 .{ .linkage_name, .strx },5433 .{ .linkage_name, .strx },
5355 .{ .type, .ref_addr },5434 .{ .type, .ref_addr },
5356 .{ .low_pc, .addr },5435 .{ .low_pc, .addrx },
5357 .{ .high_pc, .data4 },5436 .{ .high_pc, .data4 },
5358 .{ .alignment, .udata },5437 .{ .alignment, .udata },
5359 .{ .external, .flag },5438 .{ .external, .flag },
...@@ -5366,7 +5445,7 @@ pub const AbbrevCode = enum {...@@ -5366,7 +5445,7 @@ pub const AbbrevCode = enum {
5366 .attrs = decl_instance_attrs ++ .{5445 .attrs = decl_instance_attrs ++ .{
5367 .{ .linkage_name, .strx },5446 .{ .linkage_name, .strx },
5368 .{ .type, .ref_addr },5447 .{ .type, .ref_addr },
5369 .{ .low_pc, .addr },5448 .{ .low_pc, .addrx },
5370 .{ .high_pc, .data4 },5449 .{ .high_pc, .data4 },
5371 .{ .alignment, .udata },5450 .{ .alignment, .udata },
5372 .{ .external, .flag },5451 .{ .external, .flag },
...@@ -6020,6 +6099,7 @@ pub const AbbrevCode = enum {...@@ -6020,6 +6099,7 @@ pub const AbbrevCode = enum {
6020 .{ .language, .data1 },6099 .{ .language, .data1 },
6021 .{ .base_types, .ref_addr },6100 .{ .base_types, .ref_addr },
6022 .{ .stmt_list, .sec_offset },6101 .{ .stmt_list, .sec_offset },
6102 .{ .addr_base, .sec_offset },
6023 .{ .rnglists_base, .sec_offset },6103 .{ .rnglists_base, .sec_offset },
6024 .{ .str_offsets_base, .sec_offset },6104 .{ .str_offsets_base, .sec_offset },
6025 .{ .producer, .strx1 },6105 .{ .producer, .strx1 },
src/link/Elf2.zig+103-18
...@@ -53,6 +53,7 @@ shndx: struct {...@@ -53,6 +53,7 @@ shndx: struct {
53 rela_dyn: Section.Index,53 rela_dyn: Section.Index,
54 rela_plt: Section.Index,54 rela_plt: Section.Index,
55 debug_abbrev: Section.Index,55 debug_abbrev: Section.Index,
56 debug_addr: Section.Index,
56 eh_frame_hdr: Section.Index,57 eh_frame_hdr: Section.Index,
57 eh_frame: Section.Index,58 eh_frame: Section.Index,
58 debug_frame: Section.Index,59 debug_frame: Section.Index,
...@@ -215,6 +216,7 @@ textrel_count: u32,...@@ -215,6 +216,7 @@ textrel_count: u32,
215216
216dwarf: Dwarf,217dwarf: Dwarf,
217dwarf_shared: std.enums.EnumArray(Dwarf.SharedSection, dwarf_relocs.Shared),218dwarf_shared: std.enums.EnumArray(Dwarf.SharedSection, dwarf_relocs.Shared),
219dwarf_addr: dwarf_relocs.Addr,
218dwarf_str_offsets: dwarf_relocs.StrOffsets,220dwarf_str_offsets: dwarf_relocs.StrOffsets,
219dwarf_units: []dwarf_relocs.Unit,221dwarf_units: []dwarf_relocs.Unit,
220dwarf_consts: std.array_hash_map.Auto(link.ConstPool.Index, dwarf_relocs.Const),222dwarf_consts: std.array_hash_map.Auto(link.ConstPool.Index, dwarf_relocs.Const),
...@@ -287,6 +289,7 @@ const Node = union(enum) {...@@ -287,6 +289,7 @@ const Node = union(enum) {
287 lazy_const_data: LazyMapRef.Index(.const_data),289 lazy_const_data: LazyMapRef.Index(.const_data),
288290
289 debug_shared: Dwarf.SharedSection,291 debug_shared: Dwarf.SharedSection,
292 debug_addr,
290 eh_frame_footer,293 eh_frame_footer,
291 debug_str_offsets,294 debug_str_offsets,
292 unit_padding,295 unit_padding,
...@@ -882,6 +885,10 @@ const dwarf_relocs = struct {...@@ -882,6 +885,10 @@ const dwarf_relocs = struct {
882 const Shared = struct {885 const Shared = struct {
883 first_target_reloc: NodeReloc.Index,886 first_target_reloc: NodeReloc.Index,
884 };887 };
888 const Addr = struct {
889 first_target_reloc: NodeReloc.Index,
890 symbol_relocs: std.ArrayList(SymbolReloc.Index),
891 };
885 const StrOffsets = struct {892 const StrOffsets = struct {
886 first_target_reloc: NodeReloc.Index,893 first_target_reloc: NodeReloc.Index,
887 node_relocs: std.ArrayList(NodeReloc.Index),894 node_relocs: std.ArrayList(NodeReloc.Index),
...@@ -3352,6 +3359,7 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {...@@ -3352,6 +3359,7 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
3352 .input_section,3359 .input_section,
3353 .copied_global,3360 .copied_global,
3354 .debug_shared,3361 .debug_shared,
3362 .debug_addr,
3355 .eh_frame_footer,3363 .eh_frame_footer,
3356 .debug_str_offsets,3364 .debug_str_offsets,
3357 .unit_padding,3365 .unit_padding,
...@@ -3807,6 +3815,7 @@ fn create(...@@ -3807,6 +3815,7 @@ fn create(
3807 .rela_dyn = .UNDEF,3815 .rela_dyn = .UNDEF,
3808 .rela_plt = .UNDEF,3816 .rela_plt = .UNDEF,
3809 .debug_abbrev = .UNDEF,3817 .debug_abbrev = .UNDEF,
3818 .debug_addr = .UNDEF,
3810 .eh_frame_hdr = .UNDEF,3819 .eh_frame_hdr = .UNDEF,
3811 .eh_frame = .UNDEF,3820 .eh_frame = .UNDEF,
3812 .debug_frame = .UNDEF,3821 .debug_frame = .UNDEF,
...@@ -3873,6 +3882,10 @@ fn create(...@@ -3873,6 +3882,10 @@ fn create(
3873 .dwarf_shared = comptime .initFill(.{3882 .dwarf_shared = comptime .initFill(.{
3874 .first_target_reloc = .none,3883 .first_target_reloc = .none,
3875 }),3884 }),
3885 .dwarf_addr = .{
3886 .first_target_reloc = .none,
3887 .symbol_relocs = .empty,
3888 },
3876 .dwarf_str_offsets = .{3889 .dwarf_str_offsets = .{
3877 .first_target_reloc = .none,3890 .first_target_reloc = .none,
3878 .node_relocs = .empty,3891 .node_relocs = .empty,
...@@ -3932,6 +3945,7 @@ pub fn deinit(elf: *Elf) void {...@@ -3932,6 +3945,7 @@ pub fn deinit(elf: *Elf) void {
3932 elf.changed_symtab_index.deinit(gpa);3945 elf.changed_symtab_index.deinit(gpa);
39333946
3934 elf.dwarf.deinit();3947 elf.dwarf.deinit();
3948 elf.dwarf_addr.symbol_relocs.deinit(gpa);
3935 elf.dwarf_str_offsets.node_relocs.deinit(gpa);3949 elf.dwarf_str_offsets.node_relocs.deinit(gpa);
3936 for (elf.dwarf_units) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa);3950 for (elf.dwarf_units) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa);
3937 gpa.free(elf.dwarf_units);3951 gpa.free(elf.dwarf_units);
...@@ -4012,6 +4026,7 @@ fn initHeaders(...@@ -4012,6 +4026,7 @@ fn initHeaders(
4012 .strip => {},4026 .strip => {},
4013 .dwarf => {4027 .dwarf => {
4014 shnum += 1; // .debug_abbrev4028 shnum += 1; // .debug_abbrev
4029 shnum += 1; // .debug_addr
4015 shnum += @intFromBool(have_debug_frame); // .debug_frame4030 shnum += @intFromBool(have_debug_frame); // .debug_frame
4016 shnum += 1; // .debug_info4031 shnum += 1; // .debug_info
4017 shnum += 1; // .debug_line4032 shnum += 1; // .debug_line
...@@ -5116,6 +5131,11 @@ fn initHeaders(...@@ -5116,6 +5131,11 @@ fn initHeaders(
5116 .strip => {},5131 .strip => {},
5117 .dwarf => {5132 .dwarf => {
5118 elf.shndx.debug_abbrev = try elf.addSection(elf.ni.elf, .{ .name = ".debug_abbrev" });5133 elf.shndx.debug_abbrev = try elf.addSection(elf.ni.elf, .{ .name = ".debug_abbrev" });
5134 elf.shndx.debug_addr = try elf.addSection(elf.ni.elf, .{
5135 .name = ".debug_addr",
5136 .addralign = addr_align,
5137 .node_align = elf.mf.flags.block_size,
5138 });
5119 if (have_debug_frame) elf.shndx.debug_frame = try elf.addSection(elf.ni.elf, .{5139 if (have_debug_frame) elf.shndx.debug_frame = try elf.addSection(elf.ni.elf, .{
5120 .name = ".debug_frame",5140 .name = ".debug_frame",
5121 .addralign = addr_align,5141 .addralign = addr_align,
...@@ -5144,7 +5164,10 @@ fn initHeaders(...@@ -5144,7 +5164,10 @@ fn initHeaders(
5144 });5164 });
5145 elf.shndx.debug_str_offsets = try elf.addSection(elf.ni.elf, .{5165 elf.shndx.debug_str_offsets = try elf.addSection(elf.ni.elf, .{
5146 .name = ".debug_str_offsets",5166 .name = ".debug_str_offsets",
5147 .addralign = addr_align,5167 .addralign = switch (elf.dwarf.format) {
5168 .@"32" => .@"4",
5169 .@"64" => .@"8",
5170 },
5148 .node_align = elf.mf.flags.block_size,5171 .node_align = elf.mf.flags.block_size,
5149 });5172 });
5150 },5173 },
...@@ -5240,6 +5263,7 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {...@@ -5240,6 +5263,7 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {
5240 .lazy_code,5263 .lazy_code,
5241 .lazy_const_data,5264 .lazy_const_data,
5242 .debug_shared,5265 .debug_shared,
5266 .debug_addr,
5243 .eh_frame_footer,5267 .eh_frame_footer,
5244 .debug_str_offsets,5268 .debug_str_offsets,
5245 .unit_padding,5269 .unit_padding,
...@@ -5288,6 +5312,7 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5288,6 +5312,7 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5288 .lazy_const_data,5312 .lazy_const_data,
5289 => |i| Symbol.Id.local(i.symbol(elf)).value(elf),5313 => |i| Symbol.Id.local(i.symbol(elf)).value(elf),
5290 .debug_shared,5314 .debug_shared,
5315 .debug_addr,
5291 .eh_frame_footer,5316 .eh_frame_footer,
5292 .debug_str_offsets,5317 .debug_str_offsets,
5293 .unit_padding,5318 .unit_padding,
...@@ -5329,7 +5354,7 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5329,7 +5354,7 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5329 .lazy_code,5354 .lazy_code,
5330 .lazy_const_data,5355 .lazy_const_data,
5331 => |i| Symbol.Id.local(i.symbol(elf)).value(elf),5356 => |i| Symbol.Id.local(i.symbol(elf)).value(elf),
5332 .debug_shared, .eh_frame_footer, .debug_str_offsets, .unit_padding => unreachable,5357 .debug_shared, .debug_addr, .eh_frame_footer, .debug_str_offsets, .unit_padding => unreachable,
5333 .unit_frame, .unit_debug_info, .unit_debug_line => {5358 .unit_frame, .unit_debug_info, .unit_debug_line => {
5334 const section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);5359 const section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
5335 break :parent_vaddr elf.getNodeShndx(parent_ni).vaddr(elf) + section_offset;5360 break :parent_vaddr elf.getNodeShndx(parent_ni).vaddr(elf) + section_offset;
...@@ -5366,7 +5391,7 @@ fn computeNodeSectionOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5366,7 +5391,7 @@ fn computeNodeSectionOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5366 .section, .section_manual_size => 0,5391 .section, .section_manual_size => 0,
5367 .input_section, .copied_global => unreachable,5392 .input_section, .copied_global => unreachable,
5368 .nav, .uav, .lazy_code, .lazy_const_data => unreachable,5393 .nav, .uav, .lazy_code, .lazy_const_data => unreachable,
5369 .debug_shared, .eh_frame_footer, .debug_str_offsets, .unit_padding => unreachable,5394 .debug_shared, .debug_addr, .eh_frame_footer, .debug_str_offsets, .unit_padding => unreachable,
5370 .unit_frame, .unit_debug_info, .unit_debug_line => {5395 .unit_frame, .unit_debug_info, .unit_debug_line => {
5371 const parent_section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);5396 const parent_section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
5372 break :parent_section_offset parent_section_offset;5397 break :parent_section_offset parent_section_offset;
...@@ -5415,6 +5440,7 @@ pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5415,6 +5440,7 @@ pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5415 .segment,5440 .segment,
5416 .copied_global,5441 .copied_global,
5417 .debug_shared,5442 .debug_shared,
5443 .debug_addr,
5418 .eh_frame_footer,5444 .eh_frame_footer,
5419 .debug_str_offsets,5445 .debug_str_offsets,
5420 .unit_padding,5446 .unit_padding,
...@@ -7215,8 +7241,14 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7215,8 +7241,14 @@ fn prelinkInner(elf: *Elf) Error!void {
7215 };7241 };
7216 elf.input_pending_index += 1;7242 elf.input_pending_index += 1;
72177243
7218 try elf.nodes.ensureUnusedCapacity(gpa, 6 + 4);7244 const addr_align: Alignment = switch (elf.identClass()) {
7219 for ([6]Section.Index{7245 .NONE, _ => unreachable,
7246 .@"32" => .@"4",
7247 .@"64" => .@"8",
7248 };
7249 try elf.nodes.ensureUnusedCapacity(gpa, 7 + 5);
7250 for ([7]Section.Index{
7251 elf.shndx.debug_addr,
7220 elf.shndx.eh_frame,7252 elf.shndx.eh_frame,
7221 elf.shndx.debug_frame,7253 elf.shndx.debug_frame,
7222 elf.shndx.debug_info,7254 elf.shndx.debug_info,
...@@ -7238,11 +7270,7 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7238,11 +7270,7 @@ fn prelinkInner(elf: *Elf) Error!void {
7238 };7270 };
7239 break :last_header_oni last_header_oni;7271 break :last_header_oni last_header_oni;
7240 }, .{7272 }, .{
7241 .alignment = if (frame_format) |_| switch (elf.identClass()) {7273 .alignment = if (frame_format) |_| addr_align else .@"1",
7242 .NONE, _ => unreachable,
7243 .@"32" => .@"4",
7244 .@"64" => .@"8",
7245 } else .@"1",
7246 .next_moved = true,7274 .next_moved = true,
7247 .enable_next_moved = true,7275 .enable_next_moved = true,
7248 }),7276 }),
...@@ -7258,6 +7286,28 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7258,6 +7286,28 @@ fn prelinkInner(elf: *Elf) Error!void {
7258 error.WriteFailed => return debug_nw.err.?,7286 error.WriteFailed => return debug_nw.err.?,
7259 };7287 };
7260 }7288 }
7289 switch (elf.shndx.debug_addr) {
7290 .UNDEF => {},
7291 else => |debug_addr_shndx| {
7292 const debug_addr_ni = elf.addNodeAssumeCapacity(
7293 try debug_addr_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7294 .alignment = addr_align,
7295 .next_moved = true,
7296 .enable_next_moved = true,
7297 }),
7298 .debug_addr,
7299 );
7300 elf.dwarf.debug_addr.ni = .wrap(debug_addr_ni);
7301
7302 var dah_nw: link.MappedFile.Node.Writer = undefined;
7303 debug_addr_ni.writer(gpa, &elf.mf, &dah_nw);
7304 defer dah_nw.deinit();
7305 elf.dwarf.genDebugAddrHeader(&dah_nw.interface) catch |err| switch (err) {
7306 else => |e| return e,
7307 error.WriteFailed => return dah_nw.err.?,
7308 };
7309 },
7310 }
7261 switch (elf.shndx.debug_abbrev) {7311 switch (elf.shndx.debug_abbrev) {
7262 .UNDEF => {},7312 .UNDEF => {},
7263 else => |debug_abbrev_shndx| elf.dwarf.debug_abbrev.ni = .wrap(elf.addNodeAssumeCapacity(7313 else => |debug_abbrev_shndx| elf.dwarf.debug_abbrev.ni = .wrap(elf.addNodeAssumeCapacity(
...@@ -7430,7 +7480,7 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {...@@ -7430,7 +7480,7 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7430 error.WriteFailed => return dih_nw.err.?,7480 error.WriteFailed => return dih_nw.err.?,
7431 };7481 };
7432 }7482 }
7433 try elf.genPendingDebugStrings(gpa);7483 try elf.genPendingDebug(gpa);
7434}7484}
74357485
7436fn flushFiles(elf: *Elf) Error!void {7486fn flushFiles(elf: *Elf) Error!void {
...@@ -8255,6 +8305,7 @@ fn addNodeRelocAssumeCapacity(...@@ -8255,6 +8305,7 @@ fn addNodeRelocAssumeCapacity(
8255 const first_target_reloc = switch (elf.getNode(target)) {8305 const first_target_reloc = switch (elf.getNode(target)) {
8256 else => unreachable,8306 else => unreachable,
8257 .debug_shared => |ss| &elf.dwarf_shared.getPtr(ss).first_target_reloc,8307 .debug_shared => |ss| &elf.dwarf_shared.getPtr(ss).first_target_reloc,
8308 .debug_addr => &elf.dwarf_addr.first_target_reloc,
8258 .debug_str_offsets => &elf.dwarf_str_offsets.first_target_reloc,8309 .debug_str_offsets => &elf.dwarf_str_offsets.first_target_reloc,
8259 .unit_frame_cie => |ui| &elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc,8310 .unit_frame_cie => |ui| &elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc,
8260 .unit_debug_info_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_target_reloc,8311 .unit_debug_info_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_target_reloc,
...@@ -8361,6 +8412,7 @@ fn addGotRelocAssumeCapacity(...@@ -8361,6 +8412,7 @@ fn addGotRelocAssumeCapacity(
8361 .segment,8412 .segment,
8362 .copied_global,8413 .copied_global,
8363 .debug_shared,8414 .debug_shared,
8415 .debug_addr,
8364 .eh_frame_footer,8416 .eh_frame_footer,
8365 .debug_str_offsets,8417 .debug_str_offsets,
8366 .unit_padding,8418 .unit_padding,
...@@ -9211,7 +9263,8 @@ fn flushInner(...@@ -9211,7 +9263,8 @@ fn flushInner(
9211 assert(elf.input_section_pending_index == elf.input_sections.items.len);9263 assert(elf.input_section_pending_index == elf.input_sections.items.len);
9212 assert(elf.pending_uavs.items.len == 0);9264 assert(elf.pending_uavs.items.len == 0);
9213 assert(elf.dwarf.const_pool.pending.items.len == 0);9265 assert(elf.dwarf.const_pool.pending.items.len == 0);
9214 assert(elf.dwarf.debug_str_offsets.pending_index == elf.dwarf.debug_str_offsets.map.count());9266 assert(!elf.dwarf.debug_addr.anyPending());
9267 assert(!elf.dwarf.debug_str_offsets.anyPending());
92159268
9216 // We've done the final `idle` loop, so everything is at its final place in the file. We have a9269 // We've done the final `idle` loop, so everything is at its final place in the file. We have a
9217 // few more things to check and write now that addresses and offsets are finalized.9270 // few more things to check and write now that addresses and offsets are finalized.
...@@ -9536,9 +9589,22 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) link.Error!void {...@@ -9536,9 +9589,22 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
9536 },9589 },
9537 .code_view => unreachable,9590 .code_view => unreachable,
9538 }9591 }
9539 try elf.genPendingDebugStrings(gpa);9592 try elf.genPendingDebug(gpa);
9540}9593}
9541fn genPendingDebugStrings(elf: *Elf, gpa: std.mem.Allocator) link.Error!void {9594fn genPendingDebug(elf: *Elf, gpa: std.mem.Allocator) link.Error!void {
9595 while (elf.dwarf.debug_addr.map.count() - elf.dwarf.debug_addr.pending_index > 0) {
9596 const debug_addr_ni = elf.dwarf.debug_addr.ni.unwrap().?;
9597 try debug_addr_ni.moved(gpa, &elf.mf);
9598 var da_nw: link.MappedFile.Node.Writer = undefined;
9599 debug_addr_ni.writer(gpa, &elf.mf, &da_nw);
9600 defer da_nw.deinit();
9601 const first_symbol_ri = elf.symbol_relocs.items.len;
9602 try elf.dwarf.genPendingDebugAddr(&da_nw);
9603 const symbol_relocs = &elf.dwarf_addr.symbol_relocs;
9604 try symbol_relocs.ensureUnusedCapacity(gpa, elf.symbol_relocs.items.len - first_symbol_ri);
9605 for (first_symbol_ri..elf.symbol_relocs.items.len) |symbol_ri|
9606 symbol_relocs.appendAssumeCapacity(@fromBackingInt(@intCast(symbol_ri)));
9607 }
9542 while (elf.dwarf.debug_str_offsets.map.count() - elf.dwarf.debug_str_offsets.pending_index > 0) {9608 while (elf.dwarf.debug_str_offsets.map.count() - elf.dwarf.debug_str_offsets.pending_index > 0) {
9543 const debug_str_offsets_ni = elf.dwarf.debug_str_offsets.ni.unwrap().?;9609 const debug_str_offsets_ni = elf.dwarf.debug_str_offsets.ni.unwrap().?;
9544 try debug_str_offsets_ni.moved(gpa, &elf.mf);9610 try debug_str_offsets_ni.moved(gpa, &elf.mf);
...@@ -9958,6 +10024,22 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9958,6 +10024,22 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9958 .unit_debug_info,10024 .unit_debug_info,
9959 .unit_debug_line,10025 .unit_debug_line,
9960 => {},10026 => {},
10027 .debug_addr => {
10028 const target_section_offset = elf.computeNodeSectionOffset(ni);
10029 var target_ri = elf.dwarf_addr.first_target_reloc;
10030 while (target_ri != .none) {
10031 const target_reloc = target_ri.get(elf);
10032 assert(target_reloc.target == ni);
10033 target_reloc.flushMovedTarget(elf, target_section_offset);
10034 target_ri = target_reloc.next;
10035 }
10036 const node_vaddr = elf.computeNodeVAddr(ni);
10037 for (elf.dwarf_addr.symbol_relocs.items) |symbol_ri| {
10038 const symbol_reloc = symbol_ri.get(elf);
10039 assert(symbol_reloc.node.unwrap().? == ni);
10040 symbol_reloc.flushMovedNode(elf, node_vaddr);
10041 }
10042 },
9961 .debug_str_offsets => {10043 .debug_str_offsets => {
9962 const target_section_offset = elf.computeNodeSectionOffset(ni);10044 const target_section_offset = elf.computeNodeSectionOffset(ni);
9963 var target_ri = elf.dwarf_str_offsets.first_target_reloc;10045 var target_ri = elf.dwarf_str_offsets.first_target_reloc;
...@@ -10356,6 +10438,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo...@@ -10356,6 +10438,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
10356 .lazy_code,10438 .lazy_code,
10357 .lazy_const_data,10439 .lazy_const_data,
10358 .debug_shared,10440 .debug_shared,
10441 .debug_addr,
10359 .eh_frame_footer,10442 .eh_frame_footer,
10360 .debug_str_offsets,10443 .debug_str_offsets,
10361 .unit_padding,10444 .unit_padding,
...@@ -10430,6 +10513,7 @@ fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo...@@ -10430,6 +10513,7 @@ fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
10430 error.NoSpaceLeft => archive.strtab_member_too_big = true,10513 error.NoSpaceLeft => archive.strtab_member_too_big = true,
10431 }10514 }
10432 },10515 },
10516 .debug_addr,
10433 .debug_str_offsets,10517 .debug_str_offsets,
10434 .unit_padding,10518 .unit_padding,
10435 .unit_frame_cie,10519 .unit_frame_cie,
...@@ -10447,6 +10531,7 @@ fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo...@@ -10447,6 +10531,7 @@ fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
10447 const offset, const size = ni.location(&elf.mf).resolve(&elf.mf);10531 const offset, const size = ni.location(&elf.mf).resolve(&elf.mf);
10448 break :location .{ offset, switch (node) {10532 break :location .{ offset, switch (node) {
10449 else => unreachable,10533 else => unreachable,
10534 .debug_addr => elf.dwarf.debug_addr.size(&elf.dwarf),
10450 .debug_str_offsets => elf.dwarf.debug_str_offsets.size(&elf.dwarf),10535 .debug_str_offsets => elf.dwarf.debug_str_offsets.size(&elf.dwarf),
10451 .unit_padding,10536 .unit_padding,
10452 .unit_frame_cie,10537 .unit_frame_cie,
...@@ -10475,7 +10560,7 @@ fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo...@@ -10475,7 +10560,7 @@ fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
10475 };10560 };
10476 switch (node) {10561 switch (node) {
10477 else => unreachable,10562 else => unreachable,
10478 .debug_str_offsets, .unit_padding, .unit_debug_rnglists => {10563 .debug_addr, .debug_str_offsets, .unit_padding, .unit_debug_rnglists => {
10479 const parent_slice = parent_ni.slicePadding(&elf.mf);10564 const parent_slice = parent_ni.slicePadding(&elf.mf);
10480 const frame_shndx = elf.getNodeShndx(parent_ni);10565 const frame_shndx = elf.getNodeShndx(parent_ni);
10481 const frame_format = frame_shndx.debugFrameFormat(elf) orelse10566 const frame_format = frame_shndx.debugFrameFormat(elf) orelse
...@@ -10600,13 +10685,13 @@ fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo...@@ -10600,13 +10685,13 @@ fn flushPadding(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
10600 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);10685 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);
10601 switch (node) {10686 switch (node) {
10602 else => unreachable,10687 else => unreachable,
10603 .debug_str_offsets, .unit_debug_rnglists => {10688 .debug_addr, .debug_str_offsets, .unit_debug_rnglists => {
10604 elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) {10689 elf.dwarf.genUnitPadding(&fw) catch |err| switch (err) {
10605 error.WriteFailed => {10690 error.WriteFailed => {
10606 elf.dwarf.updateUnitLength(slice, slice.len);10691 elf.dwarf.updateUnitLength(slice, slice.len);
10607 @memset(fw.buffer, switch (node) {10692 @memset(fw.buffer, switch (node) {
10608 else => unreachable,10693 else => unreachable,
10609 .debug_str_offsets => std.math.maxInt(u8),10694 .debug_addr, .debug_str_offsets => std.math.maxInt(u8),
10610 .unit_debug_rnglists => std.dwarf.RLE.end_of_list,10695 .unit_debug_rnglists => std.dwarf.RLE.end_of_list,
10611 });10696 });
10612 return;10697 return;