authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-13 17:31:13-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 12:59:38-04:00
log507af69474b2a3de7d48abe001b25f1bcacd571d
tree34ae525d291a16cefc961e0173bceb48d7241b69
parent3dd202df0101e9ac9380a1aa5a813555241e8c3d

Elf2: handle updates that change the set of referenced modules


2 files changed, 284 insertions(+), 196 deletions(-)

src/link/Dwarf2.zig+139-65
...@@ -4,7 +4,7 @@ endian: std.lang.Endian,...@@ -4,7 +4,7 @@ endian: std.lang.Endian,
4address_size: AddressSize,4address_size: AddressSize,
5const_pool: link.ConstPool,5const_pool: link.ConstPool,
66
7units: std.array_hash_map.Auto(*Module, Unit),7units: []Unit,
8/// Indices are `link.ConstPool.Index`.8/// Indices are `link.ConstPool.Index`.
9consts: std.ArrayList(Const),9consts: std.ArrayList(Const),
10globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),10globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),
...@@ -23,6 +23,7 @@ debug_str_offsets: StrOffsets,...@@ -23,6 +23,7 @@ debug_str_offsets: StrOffsets,
23pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };23pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };
2424
25pub const Unit = struct {25pub const Unit = struct {
26 alive: bool,
26 dirs: std.array_hash_map.Auto(Unit.Index, void),27 dirs: std.array_hash_map.Auto(Unit.Index, void),
27 files: std.array_hash_map.Auto(Zcu.File.Index, void),28 files: std.array_hash_map.Auto(Zcu.File.Index, void),
28 frame_ni: MappedFile.Node.Index.Optional,29 frame_ni: MappedFile.Node.Index.Optional,
...@@ -40,11 +41,11 @@ pub const Unit = struct {...@@ -40,11 +41,11 @@ pub const Unit = struct {
40 _,41 _,
4142
42 pub fn mod(ui: Unit.Index, dwarf: *Dwarf) *Module {43 pub fn mod(ui: Unit.Index, dwarf: *Dwarf) *Module {
43 return dwarf.units.keys()[@backingInt(ui)];44 return dwarf.lf.comp.zcu.?.module_roots.keys()[@backingInt(ui)];
44 }45 }
4546
46 pub fn get(ui: Unit.Index, dwarf: *Dwarf) *Unit {47 pub fn get(ui: Unit.Index, dwarf: *Dwarf) *Unit {
47 return &dwarf.units.values()[@backingInt(ui)];48 return &dwarf.units[@backingInt(ui)];
48 }49 }
49 };50 };
5051
...@@ -221,7 +222,11 @@ pub const Str = struct {...@@ -221,7 +222,11 @@ pub const Str = struct {
221 };222 };
222};223};
223224
224pub const Rnglists = struct {};225pub const Rnglists = struct {
226 fn offsetsTableOffset(dwarf: *Dwarf) usize {
227 return dwarf.unitLengthSize() + 2 + 1 + 1 + 4;
228 }
229};
225230
226pub const StrOffsets = struct {231pub const StrOffsets = struct {
227 ni: MappedFile.Node.Index.Optional,232 ni: MappedFile.Node.Index.Optional,
...@@ -630,8 +635,7 @@ pub const WipNav = struct {...@@ -630,8 +635,7 @@ pub const WipNav = struct {
630 const zcu = debug.pt.zcu;635 const zcu = debug.pt.zcu;
631 const ip = &zcu.intern_pool;636 const ip = &zcu.intern_pool;
632 const func = zcu.funcInfo(debug.wip_nav.func);637 const func = zcu.funcInfo(debug.wip_nav.func);
633 const src_inst = ip.getNav(func.owner_nav).srcInst(ip);638 const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?;
634 const inst_info = src_inst.resolveFull(ip).?;
635 const decl = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst);639 const decl = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst);
636 const nav = ip.getNav(func.owner_nav);640 const nav = ip.getNav(func.owner_nav);
637 const diw = &debug.info_writer.interface;641 const diw = &debug.info_writer.interface;
...@@ -1087,7 +1091,7 @@ pub const WipNav = struct {...@@ -1087,7 +1091,7 @@ pub const WipNav = struct {
10871091
1088 fn strpFmt(debug: *Debug, comptime fmt: []const u8, args: anytype) link.EmitError!void {1092 fn strpFmt(debug: *Debug, comptime fmt: []const u8, args: anytype) link.EmitError!void {
1089 const gpa = debug.pt.zcu.gpa;1093 const gpa = debug.pt.zcu.gpa;
1090 const str = try std.fmt.allocPrint(gpa, fmt, args);1094 const str = try gpa.print(fmt, args);
1091 defer gpa.free(str);1095 defer gpa.free(str);
1092 try debug.strp(str);1096 try debug.strp(str);
1093 }1097 }
...@@ -1341,7 +1345,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {...@@ -1341,7 +1345,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
1341 .endian = target.cpu.arch.endian(),1345 .endian = target.cpu.arch.endian(),
1342 .const_pool = .empty,1346 .const_pool = .empty,
13431347
1344 .units = .empty,1348 .units = &.{},
1345 .consts = .empty,1349 .consts = .empty,
1346 .globals = .empty,1350 .globals = .empty,
1347 .funcs = .empty,1351 .funcs = .empty,
...@@ -1414,8 +1418,8 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {...@@ -1414,8 +1418,8 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
1414pub fn deinit(dwarf: *Dwarf) void {1418pub fn deinit(dwarf: *Dwarf) void {
1415 const gpa = dwarf.lf.comp.gpa;1419 const gpa = dwarf.lf.comp.gpa;
1416 dwarf.const_pool.deinit(gpa);1420 dwarf.const_pool.deinit(gpa);
1417 for (dwarf.units.values()) |*unit| unit.deinit(gpa);1421 for (dwarf.units) |*unit| unit.deinit(gpa);
1418 dwarf.units.deinit(gpa);1422 gpa.free(dwarf.units);
1419 dwarf.consts.deinit(gpa);1423 dwarf.consts.deinit(gpa);
1420 dwarf.globals.deinit(gpa);1424 dwarf.globals.deinit(gpa);
1421 dwarf.funcs.deinit(gpa);1425 dwarf.funcs.deinit(gpa);
...@@ -1425,38 +1429,47 @@ pub fn deinit(dwarf: *Dwarf) void {...@@ -1425,38 +1429,47 @@ pub fn deinit(dwarf: *Dwarf) void {
1425 dwarf.* = undefined;1429 dwarf.* = undefined;
1426}1430}
14271431
1428pub fn updateUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {1432pub fn initUnits(dwarf: *Dwarf, gpa: std.mem.Allocator, units_len: usize) std.mem.Allocator.Error!void {
1429 try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count() - dwarf.units.count());1433 assert(dwarf.units.len == 0);
1430 for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, root| if (root.unwrap()) |root_zfi| {1434 dwarf.units = try gpa.alloc(Unit, units_len);
1431 if (!zcu.alive_files.contains(root_zfi)) continue;1435 @memset(dwarf.units, .{
1436 .alive = false,
1437 .dirs = .empty,
1438 .files = .empty,
1439 .frame_ni = .none,
1440 .cie_ni = .none,
1441 .debug_info_ni = .none,
1442 .debug_info_header_ni = .none,
1443 .debug_line_ni = .none,
1444 .debug_line_header_ni = .none,
1445 .debug_line_header_changed = false,
1446 .debug_rnglists_ni = .none,
1447 .debug_rnglists_offsets_table_offset = undefined,
1448 .debug_rnglists_end = undefined,
1449 });
1450}
1451pub fn updateUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!bool {
1452 var units_changed = false;
1453 for (zcu.module_roots.values(), dwarf.units, 0..) |root, *unit, ui| {
1454 const root_zfi = root.unwrap() orelse continue; // non-zig
1455 const alive = zcu.alive_files.contains(root_zfi);
1456 if (unit.alive == alive) continue; // unchanged
1457 unit.alive = alive;
1458 units_changed = true;
1459 if (!alive) continue; // unreferenced
1432 assert(zcu.fileByIndex(root_zfi).mod != null);1460 assert(zcu.fileByIndex(root_zfi).mod != null);
1433 const unit_gop = dwarf.units.getOrPutAssumeCapacity(mod);1461 const root_di, const root_fi = try unit.getFile(
1434 if (unit_gop.found_existing) continue;
1435 unit_gop.value_ptr.* = .{
1436 .dirs = .empty,
1437 .files = .empty,
1438 .frame_ni = .none,
1439 .cie_ni = .none,
1440 .debug_info_ni = .none,
1441 .debug_info_header_ni = .none,
1442 .debug_line_ni = .none,
1443 .debug_line_header_ni = .none,
1444 .debug_line_header_changed = true,
1445 .debug_rnglists_ni = .none,
1446 .debug_rnglists_offsets_table_offset = undefined,
1447 .debug_rnglists_end = undefined,
1448 };
1449 const root_di, const root_fi = try unit_gop.value_ptr.getFile(
1450 zcu.gpa,1462 zcu.gpa,
1451 @fromBackingInt(@intCast(unit_gop.index)),1463 @fromBackingInt(@intCast(ui)),
1452 root_zfi,1464 root_zfi,
1453 );1465 );
1454 assert(root_di == .root and root_fi == .root);1466 assert(root_di == .root and root_fi == .root);
1455 };1467 }
1468 return units_changed;
1456}1469}
14571470
1458pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {1471pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {
1459 return @fromBackingInt(@intCast(dwarf.units.getIndex(mod).?));1472 return @fromBackingInt(@intCast(dwarf.lf.comp.zcu.?.module_roots.getIndex(mod).?));
1460}1473}
14611474
1462pub fn getConst(dwarf: *Dwarf, pt: Zcu.PerThread, val: Value) link.Error!link.ConstPool.Index {1475pub fn getConst(dwarf: *Dwarf, pt: Zcu.PerThread, val: Value) link.Error!link.ConstPool.Index {
...@@ -1678,10 +1691,10 @@ pub fn genDebugInfoHeader(...@@ -1678,10 +1691,10 @@ pub fn genDebugInfoHeader(
1678 mod: *Module,1691 mod: *Module,
1679 unit: *Unit,1692 unit: *Unit,
1680 dih_nw: *MappedFile.Node.Writer,1693 dih_nw: *MappedFile.Node.Writer,
1681 debug_rnglists_offsets_table_offset: usize,
1682) link.EmitError!void {1694) link.EmitError!void {
1683 const comp = zcu.comp;1695 const comp = zcu.comp;
1684 const dihw = &dih_nw.interface;1696 const dihw = &dih_nw.interface;
1697 if (!unit.alive) return dwarf.genUnitPadding(dihw);
1685 try dwarf.genUnitLength(dihw);1698 try dwarf.genUnitLength(dihw);
1686 try dihw.writeInt(u16, 5, dwarf.endian);1699 try dihw.writeInt(u16, 5, dwarf.endian);
1687 try dihw.writeByte(DW.UT.compile);1700 try dihw.writeByte(DW.UT.compile);
...@@ -1704,7 +1717,7 @@ pub fn genDebugInfoHeader(...@@ -1704,7 +1717,7 @@ pub fn genDebugInfoHeader(
1704 try dwarf.sectionOffset(1717 try dwarf.sectionOffset(
1705 dih_nw,1718 dih_nw,
1706 unit.debug_rnglists_ni.unwrap().?,1719 unit.debug_rnglists_ni.unwrap().?,
1707 debug_rnglists_offsets_table_offset,1720 Rnglists.offsetsTableOffset(dwarf),
1708 );1721 );
1709 try dihw.writeUleb128(0);1722 try dihw.writeUleb128(0);
1710 const module_offset = dihw.end;1723 const module_offset = dihw.end;
...@@ -1715,31 +1728,27 @@ pub fn genDebugInfoHeader(...@@ -1715,31 +1728,27 @@ pub fn genDebugInfoHeader(
1715 zcu.builtin_modules.get(mod.getBuiltinOptions(comp.config).hash()).?,1728 zcu.builtin_modules.get(mod.getBuiltinOptions(comp.config).hash()).?,
1716 zcu.root_mod,1729 zcu.root_mod,
1717 zcu.std_mod,1730 zcu.std_mod,
1718 }) |name, dep| try dwarf.genModuleDependency(zcu, dih_nw, name, dep, module_offset);1731 }) |name, dep| try dwarf.genModuleDependency(dih_nw, name, dep, module_offset);
1719 for (mod.deps.keys(), mod.deps.values()) |name, dep|1732 for (mod.deps.keys(), mod.deps.values()) |name, dep|
1720 try dwarf.genModuleDependency(zcu, dih_nw, name, dep, module_offset);1733 try dwarf.genModuleDependency(dih_nw, name, dep, module_offset);
1721 for ([2]AbbrevCode{ .pad_1, .pad_n }) |pad| _ = try dwarf.refAbbrevCode(pad);1734 for ([2]AbbrevCode{ .pad_1, .pad_n }) |pad| _ = try dwarf.refAbbrevCode(pad);
1722 try dwarf.genDebugInfoPadding(dihw, dihw.unusedCapacityLen());1735 try dwarf.genDebugInfoPadding(dihw, dihw.unusedCapacityLen());
1723}1736}
17241737
1725fn genModuleDependency(1738fn genModuleDependency(
1726 dwarf: *Dwarf,1739 dwarf: *Dwarf,
1727 zcu: *Zcu,
1728 nw: *MappedFile.Node.Writer,1740 nw: *MappedFile.Node.Writer,
1729 name: []const u8,1741 name: []const u8,
1730 dep: *Module,1742 dep: *Module,
1731 module_offset: usize,1743 module_offset: usize,
1732) link.EmitError!void {1744) link.EmitError!void {
1733 if (!zcu.alive_files.contains(zcu.module_roots.get(dep).?.unwrap() orelse return)) return;1745 const dep_unit = dwarf.getUnit(dep).get(dwarf);
1746 if (!dep_unit.alive) return;
1734 const diw = &nw.interface;1747 const diw = &nw.interface;
1735 try diw.writeUleb128(try dwarf.refAbbrevCode(.module_dependency));1748 try diw.writeUleb128(try dwarf.refAbbrevCode(.module_dependency));
1736 try diw.writeAll(name);1749 try diw.writeAll(name);
1737 try diw.writeByte(0);1750 try diw.writeByte(0);
1738 try dwarf.sectionOffset(1751 try dwarf.sectionOffset(nw, dep_unit.debug_info_header_ni.unwrap().?, module_offset);
1739 nw,
1740 dwarf.getUnit(dep).get(dwarf).debug_info_header_ni.unwrap().?,
1741 module_offset,
1742 );
1743}1752}
17441753
1745pub fn genDebugInfoPadding(dwarf: *Dwarf, diw: *Writer, size: u64) Writer.Error!void {1754pub fn genDebugInfoPadding(dwarf: *Dwarf, diw: *Writer, size: u64) Writer.Error!void {
...@@ -1899,21 +1908,20 @@ pub fn genDebugRnglistsHeader(...@@ -1899,21 +1908,20 @@ pub fn genDebugRnglistsHeader(
1899 dwarf: *Dwarf,1908 dwarf: *Dwarf,
1900 unit: *Unit,1909 unit: *Unit,
1901 drh_nw: *MappedFile.Node.Writer,1910 drh_nw: *MappedFile.Node.Writer,
1902) Writer.Error!usize {1911) Writer.Error!void {
1903 const drhw = &drh_nw.interface;1912 const drhw = &drh_nw.interface;
1904 try dwarf.genUnitLength(drhw);1913 try dwarf.genUnitLength(drhw);
1905 try drhw.writeInt(u16, 5, dwarf.endian);1914 try drhw.writeInt(u16, 5, dwarf.endian);
1906 try drhw.writeByte(@backingInt(dwarf.address_size));1915 try drhw.writeByte(@backingInt(dwarf.address_size));
1907 try drhw.writeByte(0);1916 try drhw.writeByte(0);
1908 try drhw.writeInt(u32, 1, dwarf.endian);1917 try drhw.writeInt(u32, 1, dwarf.endian);
1909 const offsets_table_offset = drhw.end;1918 assert(drhw.end == Rnglists.offsetsTableOffset(dwarf));
1910 switch (dwarf.format) {1919 switch (dwarf.format) {
1911 .@"32" => try drhw.writeInt(u32, 4, dwarf.endian),1920 .@"32" => try drhw.writeInt(u32, 4, dwarf.endian),
1912 .@"64" => try drhw.writeInt(u64, 8, dwarf.endian),1921 .@"64" => try drhw.writeInt(u64, 8, dwarf.endian),
1913 }1922 }
1914 unit.debug_rnglists_end = drhw.end;1923 unit.debug_rnglists_end = drhw.end;
1915 try drhw.writeByte(DW.RLE.end_of_list);1924 try drhw.writeByte(DW.RLE.end_of_list);
1916 return offsets_table_offset;
1917}1925}
19181926
1919pub fn genDebugRnglists(1927pub fn genDebugRnglists(
...@@ -2097,16 +2105,18 @@ pub fn updateConst(dwarf: *Dwarf, cpi: link.ConstPool.Index, val: InternPool.Ind...@@ -2097,16 +2105,18 @@ pub fn updateConst(dwarf: *Dwarf, cpi: link.ConstPool.Index, val: InternPool.Ind
20972105
2098pub fn updateConstIncomplete(2106pub fn updateConstIncomplete(
2099 dwarf: *Dwarf,2107 dwarf: *Dwarf,
2108 pt: Zcu.PerThread,
2100 di_nw: *MappedFile.Node.Writer,2109 di_nw: *MappedFile.Node.Writer,
2101 val: InternPool.Index,2110 val: InternPool.Index,
2102) link.Error!void {2111) link.Error!void {
2103 dwarf.updateConstIncompleteInner(di_nw, val) catch |err| switch (err) {2112 dwarf.updateConstIncompleteInner(pt, di_nw, val) catch |err| switch (err) {
2104 else => |e| return e,2113 else => |e| return e,
2105 error.WriteFailed => return dwarf.reportWriteError(di_nw),2114 error.WriteFailed => return dwarf.reportWriteError(di_nw),
2106 };2115 };
2107}2116}
2108fn updateConstIncompleteInner(2117fn updateConstIncompleteInner(
2109 dwarf: *Dwarf,2118 dwarf: *Dwarf,
2119 pt: Zcu.PerThread,
2110 di_nw: *MappedFile.Node.Writer,2120 di_nw: *MappedFile.Node.Writer,
2111 val: InternPool.Index,2121 val: InternPool.Index,
2112) link.EmitError!void {2122) link.EmitError!void {
...@@ -2114,23 +2124,87 @@ fn updateConstIncompleteInner(...@@ -2114,23 +2124,87 @@ fn updateConstIncompleteInner(
2114 const zcu = comp.zcu.?;2124 const zcu = comp.zcu.?;
2115 const ip = &zcu.intern_pool;2125 const ip = &zcu.intern_pool;
2116 const diw = &di_nw.interface;2126 const diw = &di_nw.interface;
2117 emit: switch (ip.indexToKey(val)) {2127 done: {
2118 .struct_type => {2128 const zir_index, const name, const maybe_name_nav = container: switch (ip.indexToKey(val)) {
2119 const loaded_struct = ip.loadStructType(val);2129 .struct_type => {
2120 if (loaded_struct.zir_index.resolveFull(ip)) |src_inst| switch (src_inst.inst) {2130 const loaded_struct = ip.loadStructType(val);
2121 .main_struct_inst => {2131 if (loaded_struct.zir_index.resolveFull(ip)) |src_inst| switch (src_inst.inst) {
2122 const ui = dwarf.getUnit(comp.zcu.?.fileByIndex(src_inst.file).mod.?);2132 .main_struct_inst => {
2123 _, const fi = try ui.get(dwarf).getFile(comp.gpa, ui, src_inst.file);2133 const ui = dwarf.getUnit(comp.zcu.?.fileByIndex(src_inst.file).mod.?);
2124 try diw.writeUleb128(try dwarf.refAbbrevCode(.empty_file));2134 _, const fi = try ui.get(dwarf).getFile(comp.gpa, ui, src_inst.file);
2125 try diw.writeUleb128(@backingInt(fi));2135 try diw.writeUleb128(try dwarf.refAbbrevCode(.empty_file));
2126 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_struct.name.toSlice(ip));2136 try diw.writeUleb128(@backingInt(fi));
2127 break :emit;2137 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_struct.name.toSlice(ip));
2138 break :done;
2139 },
2140 else => {},
2141 };
2142 break :container .{
2143 loaded_struct.zir_index,
2144 loaded_struct.name,
2145 loaded_struct.name_nav,
2146 };
2147 },
2148 .union_type => {
2149 const loaded_union = ip.loadUnionType(val);
2150 break :container .{ loaded_union.zir_index, loaded_union.name, loaded_union.name_nav };
2151 },
2152 .enum_type => {
2153 const loaded_enum = ip.loadEnumType(val);
2154 if (loaded_enum.zir_index.unwrap()) |zir_index|
2155 break :container .{ zir_index, loaded_enum.name, loaded_enum.name_nav };
2156 try diw.writeUleb128(try dwarf.refAbbrevCode(.generated_empty_struct_type));
2157 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_enum.name.toSlice(ip));
2158 try diw.writeByte(@intFromBool(true));
2159 break :done;
2160 },
2161 .opaque_type => {
2162 const loaded_opaque = ip.loadOpaqueType(val);
2163 break :container .{
2164 loaded_opaque.zir_index,
2165 loaded_opaque.name,
2166 loaded_opaque.name_nav,
2167 };
2168 },
2169 else => |val_key| break :done switch (val_key.typeOf()) {
2170 .type_type => {
2171 const name = try comp.gpa.print("{f}", .{Type.fromInterned(val).fmt(pt)});
2172 defer comp.gpa.free(name);
2173 try diw.writeUleb128(try dwarf.refAbbrevCode(.generated_empty_struct_type));
2174 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2175 try diw.writeByte(@intFromBool(true));
2128 },2176 },
2129 else => return,2177 else => |ty| {
2130 };2178 const ty_cpi = try dwarf.getConst(pt, Value.fromInterned(ty));
2131 return;2179 try diw.writeUleb128(try dwarf.refAbbrevCode(.undefined_comptime_value));
2132 },2180 try dwarf.sectionOffset(
2133 else => return,2181 di_nw,
2182 Const.get(ty_cpi, dwarf).debug_info_ni.unwrap().?,
2183 0,
2184 );
2185 },
2186 },
2187 };
2188 if (maybe_name_nav.unwrap()) |name_nav| {
2189 const src_inst = ip.getNav(name_nav).srcInst(ip).resolveFull(ip).?;
2190 const decl = zcu.fileByIndex(src_inst.file).zir.?.getDeclaration(src_inst.inst);
2191 const parent_cpi = try dwarf.getConst(pt, .fromInterned(zcu.fileRootType(src_inst.file)));
2192 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func_generic));
2193 try dwarf.sectionOffset(di_nw, Const.get(parent_cpi, dwarf).debug_info_ni.unwrap().?, 0);
2194 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2195 try diw.writeUleb128(decl.src_column + 1);
2196 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2197 try dwarf.strp(&dwarf.debug_str, di_nw, name.toSlice(ip));
2198 try diw.writeUleb128(@backingInt(AbbrevCode.null));
2199 } else {
2200 const zfi = zir_index.resolveFile(ip);
2201 const ui = dwarf.getUnit(zcu.fileByIndex(zfi).mod.?);
2202 _, const fi = try ui.get(dwarf).getFile(comp.gpa, ui, zfi);
2203 try diw.writeUleb128(try dwarf.refAbbrevCode(.empty_struct_type));
2204 try diw.writeUleb128(@backingInt(fi));
2205 try dwarf.strp(&dwarf.debug_str, di_nw, name.toSlice(ip));
2206 }
2207 try diw.writeByte(@intFromBool(true));
2134 }2208 }
2135 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());2209 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());
2136}2210}
src/link/Elf2.zig+145-131
...@@ -212,37 +212,11 @@ changed_symtab_index: std.array_hash_map.Auto(String(.strtab), void),...@@ -212,37 +212,11 @@ changed_symtab_index: std.array_hash_map.Auto(String(.strtab), void),
212textrel_count: u32,212textrel_count: u32,
213213
214dwarf: Dwarf,214dwarf: Dwarf,
215dwarf_shared: std.enums.EnumArray(Dwarf.SharedSection, struct {215dwarf_shared: std.enums.EnumArray(Dwarf.SharedSection, dwarf_relocs.Shared),
216 first_target_reloc: NodeReloc.Index,216dwarf_units: []dwarf_relocs.Unit,
217}),217dwarf_consts: std.array_hash_map.Auto(link.ConstPool.Index, dwarf_relocs.Const),
218dwarf_units: std.ArrayList(struct {218dwarf_globals: std.ArrayList(dwarf_relocs.Global),
219 frame_cie_first_target_reloc: NodeReloc.Index,219dwarf_funcs: std.ArrayList(dwarf_relocs.Func),
220 debug_info_header_first_target_reloc: NodeReloc.Index,
221 debug_info_header_first_node_reloc: NodeReloc.Index,
222 debug_line_header_first_target_reloc: NodeReloc.Index,
223 debug_line_header_first_node_reloc: NodeReloc.Index,
224 debug_rnglists_first_target_reloc: NodeReloc.Index,
225 debug_rnglists_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void),
226}),
227dwarf_consts: std.array_hash_map.Auto(link.ConstPool.Index, struct {
228 debug_info_first_target_reloc: NodeReloc.Index,
229 debug_info_first_symbol_reloc: SymbolReloc.Index,
230 debug_info_first_node_reloc: NodeReloc.Index,
231}),
232dwarf_globals: std.ArrayList(struct {
233 debug_info_first_target_reloc: NodeReloc.Index,
234 debug_info_first_symbol_reloc: SymbolReloc.Index,
235 debug_info_first_node_reloc: NodeReloc.Index,
236}),
237dwarf_funcs: std.ArrayList(struct {
238 frame_fde_first_symbol_reloc: SymbolReloc.Index,
239 frame_fde_first_node_reloc: NodeReloc.Index,
240 debug_info_first_target_reloc: NodeReloc.Index,
241 debug_info_first_symbol_reloc: SymbolReloc.Index,
242 debug_info_first_node_reloc: NodeReloc.Index,
243 debug_line_first_symbol_reloc: SymbolReloc.Index,
244 debug_line_first_node_reloc: NodeReloc.Index,
245}),
246220
247overflowed_reloc_count: u32,221overflowed_reloc_count: u32,
248misaligned_reloc_count: u32,222misaligned_reloc_count: u32,
...@@ -878,6 +852,40 @@ const Section = struct {...@@ -878,6 +852,40 @@ const Section = struct {
878 };852 };
879};853};
880854
855const dwarf_relocs = struct {
856 const Shared = struct {
857 first_target_reloc: NodeReloc.Index,
858 };
859 const Unit = struct {
860 frame_cie_first_target_reloc: NodeReloc.Index,
861 debug_info_header_first_target_reloc: NodeReloc.Index,
862 debug_info_header_first_node_reloc: NodeReloc.Index,
863 debug_line_header_first_target_reloc: NodeReloc.Index,
864 debug_line_header_first_node_reloc: NodeReloc.Index,
865 debug_rnglists_first_target_reloc: NodeReloc.Index,
866 debug_rnglists_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void),
867 };
868 const Const = struct {
869 debug_info_first_target_reloc: NodeReloc.Index,
870 debug_info_first_symbol_reloc: SymbolReloc.Index,
871 debug_info_first_node_reloc: NodeReloc.Index,
872 };
873 const Global = struct {
874 debug_info_first_target_reloc: NodeReloc.Index,
875 debug_info_first_symbol_reloc: SymbolReloc.Index,
876 debug_info_first_node_reloc: NodeReloc.Index,
877 };
878 const Func = struct {
879 frame_fde_first_symbol_reloc: SymbolReloc.Index,
880 frame_fde_first_node_reloc: NodeReloc.Index,
881 debug_info_first_target_reloc: NodeReloc.Index,
882 debug_info_first_symbol_reloc: SymbolReloc.Index,
883 debug_info_first_node_reloc: NodeReloc.Index,
884 debug_line_first_symbol_reloc: SymbolReloc.Index,
885 debug_line_first_node_reloc: NodeReloc.Index,
886 };
887};
888
881pub const MachineRelocType = union {889pub const MachineRelocType = union {
882 AARCH64: std.elf.R_AARCH64,890 AARCH64: std.elf.R_AARCH64,
883 LARCH: std.elf.R_LARCH,891 LARCH: std.elf.R_LARCH,
...@@ -1859,10 +1867,10 @@ const NodeReloc = struct {...@@ -1859,10 +1867,10 @@ const NodeReloc = struct {
1859 const first_target_reloc = switch (elf.getNode(reloc.target)) {1867 const first_target_reloc = switch (elf.getNode(reloc.target)) {
1860 else => unreachable,1868 else => unreachable,
1861 .debug_shared => |ss| &elf.dwarf_shared.getPtr(ss).first_target_reloc,1869 .debug_shared => |ss| &elf.dwarf_shared.getPtr(ss).first_target_reloc,
1862 .unit_frame_cie => |ui| &elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc,1870 .unit_frame_cie => |ui| &elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc,
1863 .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc,1871 .unit_debug_info_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_target_reloc,
1864 .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc,1872 .unit_debug_line_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_line_header_first_target_reloc,
1865 .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc,1873 .unit_debug_rnglists => |ui| &elf.dwarf_units[@backingInt(ui)].debug_rnglists_first_target_reloc,
1866 .const_debug_info => |cpi| &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_target_reloc,1874 .const_debug_info => |cpi| &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_target_reloc,
1867 .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc,1875 .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc,
1868 .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc,1876 .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc,
...@@ -3829,7 +3837,7 @@ fn create(...@@ -3829,7 +3837,7 @@ fn create(
3829 .dwarf_shared = comptime .initFill(.{3837 .dwarf_shared = comptime .initFill(.{
3830 .first_target_reloc = .none,3838 .first_target_reloc = .none,
3831 }),3839 }),
3832 .dwarf_units = .empty,3840 .dwarf_units = &.{},
3833 .dwarf_consts = .empty,3841 .dwarf_consts = .empty,
3834 .dwarf_globals = .empty,3842 .dwarf_globals = .empty,
3835 .dwarf_funcs = .empty,3843 .dwarf_funcs = .empty,
...@@ -3883,8 +3891,8 @@ pub fn deinit(elf: *Elf) void {...@@ -3883,8 +3891,8 @@ pub fn deinit(elf: *Elf) void {
3883 elf.changed_symtab_index.deinit(gpa);3891 elf.changed_symtab_index.deinit(gpa);
38843892
3885 elf.dwarf.deinit();3893 elf.dwarf.deinit();
3886 for (elf.dwarf_units.items) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa);3894 for (elf.dwarf_units) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa);
3887 elf.dwarf_units.deinit(gpa);3895 gpa.free(elf.dwarf_units);
3888 elf.dwarf_consts.deinit(gpa);3896 elf.dwarf_consts.deinit(gpa);
3889 elf.dwarf_globals.deinit(gpa);3897 elf.dwarf_globals.deinit(gpa);
3890 elf.dwarf_funcs.deinit(gpa);3898 elf.dwarf_funcs.deinit(gpa);
...@@ -4286,8 +4294,8 @@ fn initHeaders(...@@ -4286,8 +4294,8 @@ fn initHeaders(
4286 }4294 }
42874295
4288 elf.ni.shdr = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{4296 elf.ni.shdr = elf.addNodeAssumeCapacity(try elf.ni.elf.addFloatingChild(gpa, &elf.mf, .{
4289 .size = node_block_align.forward(1 * entsize.sh), // as above, only the SHN_UNDEF initially4297 .size = 1 * entsize.sh, // as above, only the null shdr initially
4290 .alignment = addr_align.max(node_block_align),4298 .alignment = addr_align,
4291 .moved = true,4299 .moved = true,
4292 .resized = true,4300 .resized = true,
4293 }), .shdr);4301 }), .shdr);
...@@ -5357,10 +5365,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5357,10 +5365,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5357 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_got_reloc,5365 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_got_reloc,
5358 },5366 },
5359 .unit_debug_info_header => |ui| .{5367 .unit_debug_info_header => |ui| .{
5360 .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_node_reloc,5368 .first_node_reloc = &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_node_reloc,
5361 },5369 },
5362 .unit_debug_line_header => |ui| .{5370 .unit_debug_line_header => |ui| .{
5363 .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_node_reloc,5371 .first_node_reloc = &elf.dwarf_units[@backingInt(ui)].debug_line_header_first_node_reloc,
5364 },5372 },
5365 .unit_debug_rnglists => unreachable, // unsupported5373 .unit_debug_rnglists => unreachable, // unsupported
5366 .const_debug_info => |cpi| .{5374 .const_debug_info => |cpi| .{
...@@ -5744,13 +5752,12 @@ const ShdrPtr = union(std.elf.CLASS) {...@@ -5744,13 +5752,12 @@ const ShdrPtr = union(std.elf.CLASS) {
5744 @"64": *std.elf.Elf64.Shdr,5752 @"64": *std.elf.Elf64.Shdr,
5745};5753};
5746fn shdrPtr(elf: *Elf, shndx: Section.Index) ShdrPtr {5754fn shdrPtr(elf: *Elf, shndx: Section.Index) ShdrPtr {
5747 const raw_slice = elf.ni.shdr.slice(&elf.mf);5755 const slice = elf.ni.shdr.slice(&elf.mf);
5748 switch (elf.identClass()) {5756 switch (elf.identClass()) {
5749 .NONE, _ => unreachable,5757 .NONE, _ => unreachable,
5750 inline else => |class| {5758 inline else => |class| {
5751 const shdrs_len = elf.shdrs.items.len + 1; // +1 for SHN_UNDEF
5752 const shdr_slice: []class.ElfN().Shdr = @ptrCast(@alignCast(5759 const shdr_slice: []class.ElfN().Shdr = @ptrCast(@alignCast(
5753 raw_slice[0 .. shdrs_len * @sizeOf(class.ElfN().Shdr)],5760 slice[0 .. @sizeOf(class.ElfN().Shdr) * (1 + elf.shdrs.items.len)],
5754 ));5761 ));
5755 const shdr_ptr = &shdr_slice[@backingInt(shndx)];5762 const shdr_ptr = &shdr_slice[@backingInt(shndx)];
5756 return @unionInit(ShdrPtr, @tagName(class), shdr_ptr);5763 return @unionInit(ShdrPtr, @tagName(class), shdr_ptr);
...@@ -7196,104 +7203,110 @@ pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void {...@@ -7196,104 +7203,110 @@ pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void {
7196}7203}
7197fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {7204fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7198 const gpa = zcu.gpa;7205 const gpa = zcu.gpa;
71997206 const units_len = zcu.module_roots.count();
7200 try elf.dwarf.updateUnits(zcu);7207 if (elf.dwarf_units.len == 0) {
7201 const old_units_len = elf.dwarf_units.items.len;7208 @branchHint(.unlikely);
7202 const new_units_len = elf.dwarf.units.count();7209 try elf.dwarf.initUnits(gpa, units_len);
7203 try elf.dwarf_units.appendNTimes(gpa, .{7210 elf.dwarf_units = try gpa.alloc(dwarf_relocs.Unit, zcu.module_roots.count());
7204 .frame_cie_first_target_reloc = .none,7211 @memset(elf.dwarf_units, .{
7205 .debug_info_header_first_target_reloc = .none,7212 .frame_cie_first_target_reloc = .none,
7206 .debug_info_header_first_node_reloc = .none,7213 .debug_info_header_first_target_reloc = .none,
7207 .debug_line_header_first_target_reloc = .none,7214 .debug_info_header_first_node_reloc = .none,
7208 .debug_line_header_first_node_reloc = .none,7215 .debug_line_header_first_target_reloc = .none,
7209 .debug_rnglists_first_target_reloc = .none,7216 .debug_line_header_first_node_reloc = .none,
7210 .debug_rnglists_symbol_relocs = .empty,7217 .debug_rnglists_first_target_reloc = .none,
7211 }, new_units_len - old_units_len);7218 .debug_rnglists_symbol_relocs = .empty,
7212 try elf.nodes.ensureUnusedCapacity(gpa, 5 * (new_units_len - old_units_len));7219 });
72137220 }
7214 for (old_units_len.., elf.dwarf.units.values()[old_units_len..]) |unit_index, *unit| {7221 if (!try elf.dwarf.updateUnits(zcu)) return;
7222 try elf.nodes.ensureUnusedCapacity(gpa, 5 * units_len);
7223 for (0..units_len) |unit_index| {
7215 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));7224 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));
7225 const unit = ui.get(&elf.dwarf);
7226 if (!unit.alive) continue;
7216 switch (elf.shndx.debug_info) {7227 switch (elf.shndx.debug_info) {
7217 .UNDEF => {},7228 .UNDEF => {},
7218 else => |debug_info_shndx| {7229 else => |debug_info_shndx| {
7219 const debug_info_ni = elf.addNodeAssumeCapacity(7230 const debug_info_ni = unit.debug_info_ni.unwrap() orelse debug_info_ni: {
7220 try debug_info_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{7231 const debug_info_ni = elf.addNodeAssumeCapacity(
7221 .alignment = elf.mf.flags.block_size,7232 try debug_info_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7222 .enable_next_moved = true,7233 .alignment = elf.mf.flags.block_size,
7223 }),7234 .enable_next_moved = true,
7224 .{ .unit_debug_info = ui },7235 }),
7225 );7236 .{ .unit_debug_info = ui },
7226 unit.debug_info_ni = .wrap(debug_info_ni);7237 );
7238 unit.debug_info_ni = .wrap(debug_info_ni);
7239 break :debug_info_ni debug_info_ni;
7240 };
72277241
7228 unit.debug_info_header_ni = .wrap(elf.addNodeAssumeCapacity(7242 if (unit.debug_info_header_ni == .none) unit.debug_info_header_ni = .wrap(
7229 try debug_info_ni.addOnlyHeaderChild(gpa, &elf.mf, .{7243 elf.addNodeAssumeCapacity(try debug_info_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
7230 .next_moved = true,7244 .next_moved = true,
7231 .enable_next_moved = true,7245 .enable_next_moved = true,
7232 }),7246 }), .{ .unit_debug_info_header = ui }),
7233 .{ .unit_debug_info_header = ui },7247 );
7234 ));
7235 },7248 },
7236 }7249 }
7237 switch (elf.shndx.debug_line) {7250 switch (elf.shndx.debug_line) {
7238 .UNDEF => {},7251 .UNDEF => {},
7239 else => |debug_line_shndx| {7252 else => |debug_line_shndx| {
7240 const debug_line_ni = elf.addNodeAssumeCapacity(7253 const debug_line_ni = unit.debug_line_ni.unwrap() orelse debug_line_ni: {
7241 try debug_line_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{7254 const debug_line_ni = elf.addNodeAssumeCapacity(
7242 .alignment = elf.mf.flags.block_size,7255 try debug_line_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7243 .enable_next_moved = true,7256 .alignment = elf.mf.flags.block_size,
7244 }),7257 .enable_next_moved = true,
7245 .{ .unit_debug_line = ui },7258 }),
7246 );7259 .{ .unit_debug_line = ui },
7247 unit.debug_line_ni = .wrap(debug_line_ni);7260 );
7261 unit.debug_line_ni = .wrap(debug_line_ni);
7262 break :debug_line_ni debug_line_ni;
7263 };
72487264
7249 unit.debug_line_header_ni = .wrap(elf.addNodeAssumeCapacity(7265 if (unit.debug_line_header_ni == .none) unit.debug_line_header_ni = .wrap(
7250 try debug_line_ni.addOnlyHeaderChild(gpa, &elf.mf, .{7266 elf.addNodeAssumeCapacity(try debug_line_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
7251 // Idle tasks are going to try to keep this up to date before we are able to7267 // Idle tasks are going to try to keep this up to date before we are able to
7252 // write out the full header, so just reserve space for them to do so.7268 // write out the full header, so just reserve space for them to do so.
7253 .size = elf.dwarf.unitLengthSize(),7269 .size = elf.dwarf.unitLengthSize(),
7254 .enable_next_moved = true,7270 .enable_next_moved = true,
7255 }),7271 }), .{ .unit_debug_line_header = ui }),
7256 .{ .unit_debug_line_header = ui },7272 );
7257 ));
7258 },7273 },
7259 }7274 }
7260 switch (elf.shndx.debug_rnglists) {7275 switch (elf.shndx.debug_rnglists) {
7261 .UNDEF => {},7276 .UNDEF => {},
7262 else => |debug_rnglists_shndx| unit.debug_rnglists_ni = .wrap(elf.addNodeAssumeCapacity(7277 else => |debug_rnglists_shndx| {
7263 try debug_rnglists_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{7278 const debug_rnglists_ni = unit.debug_rnglists_ni.unwrap() orelse debug_rnglists_ni: {
7264 .next_moved = true,7279 const debug_rnglists_ni = elf.addNodeAssumeCapacity(
7265 .enable_next_moved = true,7280 try debug_rnglists_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7266 }),7281 .next_moved = true,
7267 .{ .unit_debug_rnglists = ui },7282 .enable_next_moved = true,
7268 )),7283 }),
7284 .{ .unit_debug_rnglists = ui },
7285 );
7286 unit.debug_rnglists_ni = .wrap(debug_rnglists_ni);
7287 break :debug_rnglists_ni debug_rnglists_ni;
7288 };
7289
7290 var drh_nw: MappedFile.Node.Writer = undefined;
7291 debug_rnglists_ni.writer(gpa, &elf.mf, &drh_nw);
7292 defer drh_nw.deinit();
7293 elf.dwarf.genDebugRnglistsHeader(unit, &drh_nw) catch |err| switch (err) {
7294 else => |e| return e,
7295 error.WriteFailed => return drh_nw.err.?,
7296 };
7297 },
7269 }7298 }
7270 }7299 }
72717300 for (0..units_len) |unit_index| {
7272 for (7301 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));
7273 elf.dwarf.units.keys()[old_units_len..],7302 const unit = ui.get(&elf.dwarf);
7274 elf.dwarf.units.values()[old_units_len..],7303 if (unit.debug_info_header_ni == .none) continue;
7275 ) |mod, *unit| {
7276 var drh_nw: MappedFile.Node.Writer = undefined;
7277 unit.debug_rnglists_ni.unwrap().?.writer(gpa, &elf.mf, &drh_nw);
7278 defer drh_nw.deinit();
7279 const debug_rnglists_offsets_table_offset =
7280 elf.dwarf.genDebugRnglistsHeader(unit, &drh_nw) catch |err| switch (err) {
7281 else => |e| return e,
7282 error.WriteFailed => return drh_nw.err.?,
7283 };
7284
7285 var dih_nw: MappedFile.Node.Writer = undefined;7304 var dih_nw: MappedFile.Node.Writer = undefined;
7286 const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?;7305 const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?;
7287 debug_info_header_ni.writer(gpa, &elf.mf, &dih_nw);7306 debug_info_header_ni.writer(gpa, &elf.mf, &dih_nw);
7288 defer dih_nw.deinit();7307 defer dih_nw.deinit();
7289 elf.resetNodeRelocs(debug_info_header_ni);7308 elf.resetNodeRelocs(debug_info_header_ni);
7290 elf.dwarf.genDebugInfoHeader(7309 elf.dwarf.genDebugInfoHeader(zcu, ui.mod(&elf.dwarf), unit, &dih_nw) catch |err| switch (err) {
7291 zcu,
7292 mod,
7293 unit,
7294 &dih_nw,
7295 debug_rnglists_offsets_table_offset,
7296 ) catch |err| switch (err) {
7297 else => |e| return e,7310 else => |e| return e,
7298 error.WriteFailed => return dih_nw.err.?,7311 error.WriteFailed => return dih_nw.err.?,
7299 };7312 };
...@@ -7302,8 +7315,9 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {...@@ -7302,8 +7315,9 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
73027315
7303fn flushFiles(elf: *Elf) Error!void {7316fn flushFiles(elf: *Elf) Error!void {
7304 const gpa = elf.base.comp.gpa;7317 const gpa = elf.base.comp.gpa;
7305 if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units.values()) |*unit| {7318 if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units) |*unit| {
7306 if (!unit.cleanDebugLineHeaderChanged()) continue;7319 if (!unit.cleanDebugLineHeaderChanged()) continue;
7320 assert(unit.alive);
7307 const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?;7321 const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?;
7308 try debug_line_header_ni.parent(&elf.mf).unwrap().?.nextMoved(gpa, &elf.mf);7322 try debug_line_header_ni.parent(&elf.mf).unwrap().?.nextMoved(gpa, &elf.mf);
7309 try debug_line_header_ni.moved(gpa, &elf.mf);7323 try debug_line_header_ni.moved(gpa, &elf.mf);
...@@ -8122,10 +8136,10 @@ fn addNodeRelocAssumeCapacity(...@@ -8122,10 +8136,10 @@ fn addNodeRelocAssumeCapacity(
8122 const first_target_reloc = switch (elf.getNode(target)) {8136 const first_target_reloc = switch (elf.getNode(target)) {
8123 else => unreachable,8137 else => unreachable,
8124 .debug_shared => |ss| &elf.dwarf_shared.getPtr(ss).first_target_reloc,8138 .debug_shared => |ss| &elf.dwarf_shared.getPtr(ss).first_target_reloc,
8125 .unit_frame_cie => |ui| &elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc,8139 .unit_frame_cie => |ui| &elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc,
8126 .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc,8140 .unit_debug_info_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_target_reloc,
8127 .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc,8141 .unit_debug_line_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_line_header_first_target_reloc,
8128 .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc,8142 .unit_debug_rnglists => |ui| &elf.dwarf_units[@backingInt(ui)].debug_rnglists_first_target_reloc,
8129 .const_debug_info => |cpi| &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_target_reloc,8143 .const_debug_info => |cpi| &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_target_reloc,
8130 .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc,8144 .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc,
8131 .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc,8145 .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc,
...@@ -8621,7 +8635,7 @@ fn updateConstInner(...@@ -8621,7 +8635,7 @@ fn updateConstInner(
86218635
8622pub fn updateConstIncomplete(8636pub fn updateConstIncomplete(
8623 elf: *Elf,8637 elf: *Elf,
8624 _: Zcu.PerThread,8638 pt: Zcu.PerThread,
8625 cpi: link.ConstPool.Index,8639 cpi: link.ConstPool.Index,
8626 val: InternPool.Index,8640 val: InternPool.Index,
8627) link.Error!void {8641) link.Error!void {
...@@ -8629,7 +8643,7 @@ pub fn updateConstIncomplete(...@@ -8629,7 +8643,7 @@ pub fn updateConstIncomplete(
8629 var di_nw: MappedFile.Node.Writer = undefined;8643 var di_nw: MappedFile.Node.Writer = undefined;
8630 debug_info_ni.writer(elf.base.comp.gpa, &elf.mf, &di_nw);8644 debug_info_ni.writer(elf.base.comp.gpa, &elf.mf, &di_nw);
8631 defer di_nw.deinit();8645 defer di_nw.deinit();
8632 try elf.dwarf.updateConstIncomplete(&di_nw, val);8646 try elf.dwarf.updateConstIncomplete(pt, &di_nw, val);
8633}8647}
86348648
8635pub fn updateFunc(8649pub fn updateFunc(
...@@ -8717,7 +8731,7 @@ fn updateFuncInner(...@@ -8717,7 +8731,7 @@ fn updateFuncInner(
8717 unit.frame_ni = .wrap(frame_ni);8731 unit.frame_ni = .wrap(frame_ni);
8718 break :frame_ni frame_ni;8732 break :frame_ni frame_ni;
8719 };8733 };
8720 _ = unit.cie_ni.unwrap() orelse {8734 if (unit.cie_ni == .none) {
8721 const cie_ni = elf.addNodeAssumeCapacity(8735 const cie_ni = elf.addNodeAssumeCapacity(
8722 try frame_ni.addOnlyHeaderChild(gpa, &elf.mf, .{8736 try frame_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
8723 .alignment = frame_align,8737 .alignment = frame_align,
...@@ -8736,19 +8750,19 @@ fn updateFuncInner(...@@ -8736,19 +8750,19 @@ fn updateFuncInner(
8736 }, wip_nav.frame_format) catch |err| switch (err) {8750 }, wip_nav.frame_format) catch |err| switch (err) {
8737 error.WriteFailed => return cie_nw.err.?,8751 error.WriteFailed => return cie_nw.err.?,
8738 };8752 };
8739 };8753 }
8740 const dwarf_func = dwarf_fi.get(dwarf);8754 const dwarf_func = dwarf_fi.get(dwarf);
8741 const fde_ni = if (dwarf_func.fde_ni.unwrap()) |fde_ni| fde_ni: {8755 const fde_ni = if (dwarf_func.fde_ni.unwrap()) |fde_ni| fde_ni: {
8742 try fde_ni.moved(gpa, &elf.mf);8756 try fde_ni.moved(gpa, &elf.mf);
8743 try fde_ni.nextMoved(gpa, &elf.mf);8757 try fde_ni.nextMoved(gpa, &elf.mf);
8744 break :fde_ni fde_ni;8758 break :fde_ni fde_ni;
8745 } else fde_ni: {8759 } else fde_ni: {
8746 const fde_ni = try frame_ni.addFloatingChild(gpa, &elf.mf, .{8760 const fde_ni = elf.addNodeAssumeCapacity(try frame_ni.addFloatingChild(gpa, &elf.mf, .{
8747 .alignment = frame_align,8761 .alignment = frame_align,
8748 .moved = true,8762 .moved = true,
8749 .next_moved = true,8763 .next_moved = true,
8750 .enable_next_moved = true,8764 .enable_next_moved = true,
8751 });8765 }), .{ .func_frame_fde = dwarf_fi });
8752 dwarf_func.fde_ni = .wrap(fde_ni);8766 dwarf_func.fde_ni = .wrap(fde_ni);
8753 break :fde_ni fde_ni;8767 break :fde_ni fde_ni;
8754 };8768 };
...@@ -8868,7 +8882,7 @@ fn updateFuncInner(...@@ -8868,7 +8882,7 @@ fn updateFuncInner(
8868 else => |e| return e,8882 else => |e| return e,
8869 error.WriteFailed => return dr_nw.err.?,8883 error.WriteFailed => return dr_nw.err.?,
8870 };8884 };
8871 const symbol_relocs = &elf.dwarf_units.items[@backingInt(debug.wip_nav.unit)]8885 const symbol_relocs = &elf.dwarf_units[@backingInt(debug.wip_nav.unit)]
8872 .debug_rnglists_symbol_relocs;8886 .debug_rnglists_symbol_relocs;
8873 try symbol_relocs.ensureUnusedCapacity(gpa, elf.symbol_relocs.items.len -8887 try symbol_relocs.ensureUnusedCapacity(gpa, elf.symbol_relocs.items.len -
8874 first_symbol_reloc);8888 first_symbol_reloc);
...@@ -9629,7 +9643,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9629,7 +9643,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9629 .unit_padding, .unit_frame, .unit_debug_info, .unit_debug_line => {},9643 .unit_padding, .unit_frame, .unit_debug_info, .unit_debug_line => {},
9630 .unit_frame_cie => |ui| {9644 .unit_frame_cie => |ui| {
9631 const target_section_offset = elf.computeNodeSectionOffset(ni);9645 const target_section_offset = elf.computeNodeSectionOffset(ni);
9632 var target_ri = elf.dwarf_units.items[@backingInt(ui)].frame_cie_first_target_reloc;9646 var target_ri = elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc;
9633 while (target_ri != .none) {9647 while (target_ri != .none) {
9634 const target_reloc = target_ri.get(elf);9648 const target_reloc = target_ri.get(elf);
9635 assert(target_reloc.target == ni);9649 assert(target_reloc.target == ni);
...@@ -9638,7 +9652,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9638,7 +9652,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9638 }9652 }
9639 },9653 },
9640 .unit_debug_info_header => |ui| {9654 .unit_debug_info_header => |ui| {
9641 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];9655 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
9642 const target_section_offset = elf.computeNodeSectionOffset(ni);9656 const target_section_offset = elf.computeNodeSectionOffset(ni);
9643 var target_ri = dwarf_unit.debug_info_header_first_target_reloc;9657 var target_ri = dwarf_unit.debug_info_header_first_target_reloc;
9644 while (target_ri != .none) {9658 while (target_ri != .none) {
...@@ -9652,7 +9666,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9652,7 +9666,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9652 });9666 });
9653 },9667 },
9654 .unit_debug_line_header => |ui| {9668 .unit_debug_line_header => |ui| {
9655 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];9669 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
9656 const target_section_offset = elf.computeNodeSectionOffset(ni);9670 const target_section_offset = elf.computeNodeSectionOffset(ni);
9657 var target_ri = dwarf_unit.debug_line_header_first_target_reloc;9671 var target_ri = dwarf_unit.debug_line_header_first_target_reloc;
9658 while (target_ri != .none) {9672 while (target_ri != .none) {
...@@ -9666,7 +9680,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9666,7 +9680,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9666 });9680 });
9667 },9681 },
9668 .unit_debug_rnglists => |ui| {9682 .unit_debug_rnglists => |ui| {
9669 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];9683 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
9670 const target_section_offset = elf.computeNodeSectionOffset(ni);9684 const target_section_offset = elf.computeNodeSectionOffset(ni);
9671 var target_ri = dwarf_unit.debug_rnglists_first_target_reloc;9685 var target_ri = dwarf_unit.debug_rnglists_first_target_reloc;
9672 while (target_ri != .none) {9686 while (target_ri != .none) {