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,
44address_size: AddressSize,
55const_pool: link.ConstPool,
66
7units: std.array_hash_map.Auto(*Module, Unit),
7units: []Unit,
88/// Indices are `link.ConstPool.Index`.
99consts: std.ArrayList(Const),
1010globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),
......@@ -23,6 +23,7 @@ debug_str_offsets: StrOffsets,
2323pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };
2424
2525pub const Unit = struct {
26 alive: bool,
2627 dirs: std.array_hash_map.Auto(Unit.Index, void),
2728 files: std.array_hash_map.Auto(Zcu.File.Index, void),
2829 frame_ni: MappedFile.Node.Index.Optional,
......@@ -40,11 +41,11 @@ pub const Unit = struct {
4041 _,
4142
4243 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)];
4445 }
4546
4647 pub fn get(ui: Unit.Index, dwarf: *Dwarf) *Unit {
47 return &dwarf.units.values()[@backingInt(ui)];
48 return &dwarf.units[@backingInt(ui)];
4849 }
4950 };
5051
......@@ -221,7 +222,11 @@ pub const Str = struct {
221222 };
222223};
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
226231pub const StrOffsets = struct {
227232 ni: MappedFile.Node.Index.Optional,
......@@ -630,8 +635,7 @@ pub const WipNav = struct {
630635 const zcu = debug.pt.zcu;
631636 const ip = &zcu.intern_pool;
632637 const func = zcu.funcInfo(debug.wip_nav.func);
633 const src_inst = ip.getNav(func.owner_nav).srcInst(ip);
634 const inst_info = src_inst.resolveFull(ip).?;
638 const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?;
635639 const decl = zcu.fileByIndex(inst_info.file).zir.?.getDeclaration(inst_info.inst);
636640 const nav = ip.getNav(func.owner_nav);
637641 const diw = &debug.info_writer.interface;
......@@ -1087,7 +1091,7 @@ pub const WipNav = struct {
10871091
10881092 fn strpFmt(debug: *Debug, comptime fmt: []const u8, args: anytype) link.EmitError!void {
10891093 const gpa = debug.pt.zcu.gpa;
1090 const str = try std.fmt.allocPrint(gpa, fmt, args);
1094 const str = try gpa.print(fmt, args);
10911095 defer gpa.free(str);
10921096 try debug.strp(str);
10931097 }
......@@ -1341,7 +1345,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
13411345 .endian = target.cpu.arch.endian(),
13421346 .const_pool = .empty,
13431347
1344 .units = .empty,
1348 .units = &.{},
13451349 .consts = .empty,
13461350 .globals = .empty,
13471351 .funcs = .empty,
......@@ -1414,8 +1418,8 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
14141418pub fn deinit(dwarf: *Dwarf) void {
14151419 const gpa = dwarf.lf.comp.gpa;
14161420 dwarf.const_pool.deinit(gpa);
1417 for (dwarf.units.values()) |*unit| unit.deinit(gpa);
1418 dwarf.units.deinit(gpa);
1421 for (dwarf.units) |*unit| unit.deinit(gpa);
1422 gpa.free(dwarf.units);
14191423 dwarf.consts.deinit(gpa);
14201424 dwarf.globals.deinit(gpa);
14211425 dwarf.funcs.deinit(gpa);
......@@ -1425,38 +1429,47 @@ pub fn deinit(dwarf: *Dwarf) void {
14251429 dwarf.* = undefined;
14261430}
14271431
1428pub fn updateUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {
1429 try dwarf.units.ensureTotalCapacity(zcu.gpa, zcu.module_roots.count() - dwarf.units.count());
1430 for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, root| if (root.unwrap()) |root_zfi| {
1431 if (!zcu.alive_files.contains(root_zfi)) continue;
1432pub fn initUnits(dwarf: *Dwarf, gpa: std.mem.Allocator, units_len: usize) std.mem.Allocator.Error!void {
1433 assert(dwarf.units.len == 0);
1434 dwarf.units = try gpa.alloc(Unit, units_len);
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
14321460 assert(zcu.fileByIndex(root_zfi).mod != null);
1433 const unit_gop = dwarf.units.getOrPutAssumeCapacity(mod);
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(
1461 const root_di, const root_fi = try unit.getFile(
14501462 zcu.gpa,
1451 @fromBackingInt(@intCast(unit_gop.index)),
1463 @fromBackingInt(@intCast(ui)),
14521464 root_zfi,
14531465 );
14541466 assert(root_di == .root and root_fi == .root);
1455 };
1467 }
1468 return units_changed;
14561469}
14571470
14581471pub 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).?));
14601473}
14611474
14621475pub fn getConst(dwarf: *Dwarf, pt: Zcu.PerThread, val: Value) link.Error!link.ConstPool.Index {
......@@ -1678,10 +1691,10 @@ pub fn genDebugInfoHeader(
16781691 mod: *Module,
16791692 unit: *Unit,
16801693 dih_nw: *MappedFile.Node.Writer,
1681 debug_rnglists_offsets_table_offset: usize,
16821694) link.EmitError!void {
16831695 const comp = zcu.comp;
16841696 const dihw = &dih_nw.interface;
1697 if (!unit.alive) return dwarf.genUnitPadding(dihw);
16851698 try dwarf.genUnitLength(dihw);
16861699 try dihw.writeInt(u16, 5, dwarf.endian);
16871700 try dihw.writeByte(DW.UT.compile);
......@@ -1704,7 +1717,7 @@ pub fn genDebugInfoHeader(
17041717 try dwarf.sectionOffset(
17051718 dih_nw,
17061719 unit.debug_rnglists_ni.unwrap().?,
1707 debug_rnglists_offsets_table_offset,
1720 Rnglists.offsetsTableOffset(dwarf),
17081721 );
17091722 try dihw.writeUleb128(0);
17101723 const module_offset = dihw.end;
......@@ -1715,31 +1728,27 @@ pub fn genDebugInfoHeader(
17151728 zcu.builtin_modules.get(mod.getBuiltinOptions(comp.config).hash()).?,
17161729 zcu.root_mod,
17171730 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);
17191732 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);
17211734 for ([2]AbbrevCode{ .pad_1, .pad_n }) |pad| _ = try dwarf.refAbbrevCode(pad);
17221735 try dwarf.genDebugInfoPadding(dihw, dihw.unusedCapacityLen());
17231736}
17241737
17251738fn genModuleDependency(
17261739 dwarf: *Dwarf,
1727 zcu: *Zcu,
17281740 nw: *MappedFile.Node.Writer,
17291741 name: []const u8,
17301742 dep: *Module,
17311743 module_offset: usize,
17321744) 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;
17341747 const diw = &nw.interface;
17351748 try diw.writeUleb128(try dwarf.refAbbrevCode(.module_dependency));
17361749 try diw.writeAll(name);
17371750 try diw.writeByte(0);
1738 try dwarf.sectionOffset(
1739 nw,
1740 dwarf.getUnit(dep).get(dwarf).debug_info_header_ni.unwrap().?,
1741 module_offset,
1742 );
1751 try dwarf.sectionOffset(nw, dep_unit.debug_info_header_ni.unwrap().?, module_offset);
17431752}
17441753
17451754pub fn genDebugInfoPadding(dwarf: *Dwarf, diw: *Writer, size: u64) Writer.Error!void {
......@@ -1899,21 +1908,20 @@ pub fn genDebugRnglistsHeader(
18991908 dwarf: *Dwarf,
19001909 unit: *Unit,
19011910 drh_nw: *MappedFile.Node.Writer,
1902) Writer.Error!usize {
1911) Writer.Error!void {
19031912 const drhw = &drh_nw.interface;
19041913 try dwarf.genUnitLength(drhw);
19051914 try drhw.writeInt(u16, 5, dwarf.endian);
19061915 try drhw.writeByte(@backingInt(dwarf.address_size));
19071916 try drhw.writeByte(0);
19081917 try drhw.writeInt(u32, 1, dwarf.endian);
1909 const offsets_table_offset = drhw.end;
1918 assert(drhw.end == Rnglists.offsetsTableOffset(dwarf));
19101919 switch (dwarf.format) {
19111920 .@"32" => try drhw.writeInt(u32, 4, dwarf.endian),
19121921 .@"64" => try drhw.writeInt(u64, 8, dwarf.endian),
19131922 }
19141923 unit.debug_rnglists_end = drhw.end;
19151924 try drhw.writeByte(DW.RLE.end_of_list);
1916 return offsets_table_offset;
19171925}
19181926
19191927pub fn genDebugRnglists(
......@@ -2097,16 +2105,18 @@ pub fn updateConst(dwarf: *Dwarf, cpi: link.ConstPool.Index, val: InternPool.Ind
20972105
20982106pub fn updateConstIncomplete(
20992107 dwarf: *Dwarf,
2108 pt: Zcu.PerThread,
21002109 di_nw: *MappedFile.Node.Writer,
21012110 val: InternPool.Index,
21022111) link.Error!void {
2103 dwarf.updateConstIncompleteInner(di_nw, val) catch |err| switch (err) {
2112 dwarf.updateConstIncompleteInner(pt, di_nw, val) catch |err| switch (err) {
21042113 else => |e| return e,
21052114 error.WriteFailed => return dwarf.reportWriteError(di_nw),
21062115 };
21072116}
21082117fn updateConstIncompleteInner(
21092118 dwarf: *Dwarf,
2119 pt: Zcu.PerThread,
21102120 di_nw: *MappedFile.Node.Writer,
21112121 val: InternPool.Index,
21122122) link.EmitError!void {
......@@ -2114,23 +2124,87 @@ fn updateConstIncompleteInner(
21142124 const zcu = comp.zcu.?;
21152125 const ip = &zcu.intern_pool;
21162126 const diw = &di_nw.interface;
2117 emit: switch (ip.indexToKey(val)) {
2118 .struct_type => {
2119 const loaded_struct = ip.loadStructType(val);
2120 if (loaded_struct.zir_index.resolveFull(ip)) |src_inst| switch (src_inst.inst) {
2121 .main_struct_inst => {
2122 const ui = dwarf.getUnit(comp.zcu.?.fileByIndex(src_inst.file).mod.?);
2123 _, const fi = try ui.get(dwarf).getFile(comp.gpa, ui, src_inst.file);
2124 try diw.writeUleb128(try dwarf.refAbbrevCode(.empty_file));
2125 try diw.writeUleb128(@backingInt(fi));
2126 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_struct.name.toSlice(ip));
2127 break :emit;
2127 done: {
2128 const zir_index, const name, const maybe_name_nav = container: switch (ip.indexToKey(val)) {
2129 .struct_type => {
2130 const loaded_struct = ip.loadStructType(val);
2131 if (loaded_struct.zir_index.resolveFull(ip)) |src_inst| switch (src_inst.inst) {
2132 .main_struct_inst => {
2133 const ui = dwarf.getUnit(comp.zcu.?.fileByIndex(src_inst.file).mod.?);
2134 _, const fi = try ui.get(dwarf).getFile(comp.gpa, ui, src_inst.file);
2135 try diw.writeUleb128(try dwarf.refAbbrevCode(.empty_file));
2136 try diw.writeUleb128(@backingInt(fi));
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));
21282176 },
2129 else => return,
2130 };
2131 return;
2132 },
2133 else => return,
2177 else => |ty| {
2178 const ty_cpi = try dwarf.getConst(pt, Value.fromInterned(ty));
2179 try diw.writeUleb128(try dwarf.refAbbrevCode(.undefined_comptime_value));
2180 try dwarf.sectionOffset(
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));
21342208 }
21352209 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());
21362210}
src/link/Elf2.zig+145-131
......@@ -212,37 +212,11 @@ changed_symtab_index: std.array_hash_map.Auto(String(.strtab), void),
212212textrel_count: u32,
213213
214214dwarf: Dwarf,
215dwarf_shared: std.enums.EnumArray(Dwarf.SharedSection, struct {
216 first_target_reloc: NodeReloc.Index,
217}),
218dwarf_units: std.ArrayList(struct {
219 frame_cie_first_target_reloc: NodeReloc.Index,
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}),
215dwarf_shared: std.enums.EnumArray(Dwarf.SharedSection, dwarf_relocs.Shared),
216dwarf_units: []dwarf_relocs.Unit,
217dwarf_consts: std.array_hash_map.Auto(link.ConstPool.Index, dwarf_relocs.Const),
218dwarf_globals: std.ArrayList(dwarf_relocs.Global),
219dwarf_funcs: std.ArrayList(dwarf_relocs.Func),
246220
247221overflowed_reloc_count: u32,
248222misaligned_reloc_count: u32,
......@@ -878,6 +852,40 @@ const Section = struct {
878852 };
879853};
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
881889pub const MachineRelocType = union {
882890 AARCH64: std.elf.R_AARCH64,
883891 LARCH: std.elf.R_LARCH,
......@@ -1859,10 +1867,10 @@ const NodeReloc = struct {
18591867 const first_target_reloc = switch (elf.getNode(reloc.target)) {
18601868 else => unreachable,
18611869 .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,
1863 .unit_debug_info_header => |ui| &elf.dwarf_units.items[@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,
1865 .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc,
1870 .unit_frame_cie => |ui| &elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc,
1871 .unit_debug_info_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_target_reloc,
1872 .unit_debug_line_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_line_header_first_target_reloc,
1873 .unit_debug_rnglists => |ui| &elf.dwarf_units[@backingInt(ui)].debug_rnglists_first_target_reloc,
18661874 .const_debug_info => |cpi| &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_target_reloc,
18671875 .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc,
18681876 .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc,
......@@ -3829,7 +3837,7 @@ fn create(
38293837 .dwarf_shared = comptime .initFill(.{
38303838 .first_target_reloc = .none,
38313839 }),
3832 .dwarf_units = .empty,
3840 .dwarf_units = &.{},
38333841 .dwarf_consts = .empty,
38343842 .dwarf_globals = .empty,
38353843 .dwarf_funcs = .empty,
......@@ -3883,8 +3891,8 @@ pub fn deinit(elf: *Elf) void {
38833891 elf.changed_symtab_index.deinit(gpa);
38843892
38853893 elf.dwarf.deinit();
3886 for (elf.dwarf_units.items) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa);
3887 elf.dwarf_units.deinit(gpa);
3894 for (elf.dwarf_units) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa);
3895 gpa.free(elf.dwarf_units);
38883896 elf.dwarf_consts.deinit(gpa);
38893897 elf.dwarf_globals.deinit(gpa);
38903898 elf.dwarf_funcs.deinit(gpa);
......@@ -4286,8 +4294,8 @@ fn initHeaders(
42864294 }
42874295
42884296 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 initially
4290 .alignment = addr_align.max(node_block_align),
4297 .size = 1 * entsize.sh, // as above, only the null shdr initially
4298 .alignment = addr_align,
42914299 .moved = true,
42924300 .resized = true,
42934301 }), .shdr);
......@@ -5357,10 +5365,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
53575365 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_got_reloc,
53585366 },
53595367 .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,
53615369 },
53625370 .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,
53645372 },
53655373 .unit_debug_rnglists => unreachable, // unsupported
53665374 .const_debug_info => |cpi| .{
......@@ -5744,13 +5752,12 @@ const ShdrPtr = union(std.elf.CLASS) {
57445752 @"64": *std.elf.Elf64.Shdr,
57455753};
57465754fn 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);
57485756 switch (elf.identClass()) {
57495757 .NONE, _ => unreachable,
57505758 inline else => |class| {
5751 const shdrs_len = elf.shdrs.items.len + 1; // +1 for SHN_UNDEF
57525759 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)],
57545761 ));
57555762 const shdr_ptr = &shdr_slice[@backingInt(shndx)];
57565763 return @unionInit(ShdrPtr, @tagName(class), shdr_ptr);
......@@ -7196,104 +7203,110 @@ pub fn zcuFilesReady(elf: *Elf, zcu: *Zcu) link.Error!void {
71967203}
71977204fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
71987205 const gpa = zcu.gpa;
7199
7200 try elf.dwarf.updateUnits(zcu);
7201 const old_units_len = elf.dwarf_units.items.len;
7202 const new_units_len = elf.dwarf.units.count();
7203 try elf.dwarf_units.appendNTimes(gpa, .{
7204 .frame_cie_first_target_reloc = .none,
7205 .debug_info_header_first_target_reloc = .none,
7206 .debug_info_header_first_node_reloc = .none,
7207 .debug_line_header_first_target_reloc = .none,
7208 .debug_line_header_first_node_reloc = .none,
7209 .debug_rnglists_first_target_reloc = .none,
7210 .debug_rnglists_symbol_relocs = .empty,
7211 }, new_units_len - old_units_len);
7212 try elf.nodes.ensureUnusedCapacity(gpa, 5 * (new_units_len - old_units_len));
7213
7214 for (old_units_len.., elf.dwarf.units.values()[old_units_len..]) |unit_index, *unit| {
7206 const units_len = zcu.module_roots.count();
7207 if (elf.dwarf_units.len == 0) {
7208 @branchHint(.unlikely);
7209 try elf.dwarf.initUnits(gpa, units_len);
7210 elf.dwarf_units = try gpa.alloc(dwarf_relocs.Unit, zcu.module_roots.count());
7211 @memset(elf.dwarf_units, .{
7212 .frame_cie_first_target_reloc = .none,
7213 .debug_info_header_first_target_reloc = .none,
7214 .debug_info_header_first_node_reloc = .none,
7215 .debug_line_header_first_target_reloc = .none,
7216 .debug_line_header_first_node_reloc = .none,
7217 .debug_rnglists_first_target_reloc = .none,
7218 .debug_rnglists_symbol_relocs = .empty,
7219 });
7220 }
7221 if (!try elf.dwarf.updateUnits(zcu)) return;
7222 try elf.nodes.ensureUnusedCapacity(gpa, 5 * units_len);
7223 for (0..units_len) |unit_index| {
72157224 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));
7225 const unit = ui.get(&elf.dwarf);
7226 if (!unit.alive) continue;
72167227 switch (elf.shndx.debug_info) {
72177228 .UNDEF => {},
72187229 else => |debug_info_shndx| {
7219 const debug_info_ni = elf.addNodeAssumeCapacity(
7220 try debug_info_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7221 .alignment = elf.mf.flags.block_size,
7222 .enable_next_moved = true,
7223 }),
7224 .{ .unit_debug_info = ui },
7225 );
7226 unit.debug_info_ni = .wrap(debug_info_ni);
7230 const debug_info_ni = unit.debug_info_ni.unwrap() orelse debug_info_ni: {
7231 const debug_info_ni = elf.addNodeAssumeCapacity(
7232 try debug_info_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7233 .alignment = elf.mf.flags.block_size,
7234 .enable_next_moved = true,
7235 }),
7236 .{ .unit_debug_info = ui },
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(
7229 try debug_info_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
7242 if (unit.debug_info_header_ni == .none) unit.debug_info_header_ni = .wrap(
7243 elf.addNodeAssumeCapacity(try debug_info_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
72307244 .next_moved = true,
72317245 .enable_next_moved = true,
7232 }),
7233 .{ .unit_debug_info_header = ui },
7234 ));
7246 }), .{ .unit_debug_info_header = ui }),
7247 );
72357248 },
72367249 }
72377250 switch (elf.shndx.debug_line) {
72387251 .UNDEF => {},
72397252 else => |debug_line_shndx| {
7240 const debug_line_ni = elf.addNodeAssumeCapacity(
7241 try debug_line_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7242 .alignment = elf.mf.flags.block_size,
7243 .enable_next_moved = true,
7244 }),
7245 .{ .unit_debug_line = ui },
7246 );
7247 unit.debug_line_ni = .wrap(debug_line_ni);
7253 const debug_line_ni = unit.debug_line_ni.unwrap() orelse debug_line_ni: {
7254 const debug_line_ni = elf.addNodeAssumeCapacity(
7255 try debug_line_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7256 .alignment = elf.mf.flags.block_size,
7257 .enable_next_moved = true,
7258 }),
7259 .{ .unit_debug_line = ui },
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(
7250 try debug_line_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
7265 if (unit.debug_line_header_ni == .none) unit.debug_line_header_ni = .wrap(
7266 elf.addNodeAssumeCapacity(try debug_line_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
72517267 // Idle tasks are going to try to keep this up to date before we are able to
72527268 // write out the full header, so just reserve space for them to do so.
72537269 .size = elf.dwarf.unitLengthSize(),
72547270 .enable_next_moved = true,
7255 }),
7256 .{ .unit_debug_line_header = ui },
7257 ));
7271 }), .{ .unit_debug_line_header = ui }),
7272 );
72587273 },
72597274 }
72607275 switch (elf.shndx.debug_rnglists) {
72617276 .UNDEF => {},
7262 else => |debug_rnglists_shndx| unit.debug_rnglists_ni = .wrap(elf.addNodeAssumeCapacity(
7263 try debug_rnglists_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7264 .next_moved = true,
7265 .enable_next_moved = true,
7266 }),
7267 .{ .unit_debug_rnglists = ui },
7268 )),
7277 else => |debug_rnglists_shndx| {
7278 const debug_rnglists_ni = unit.debug_rnglists_ni.unwrap() orelse debug_rnglists_ni: {
7279 const debug_rnglists_ni = elf.addNodeAssumeCapacity(
7280 try debug_rnglists_shndx.get(elf).ni.addFloatingChild(gpa, &elf.mf, .{
7281 .next_moved = true,
7282 .enable_next_moved = true,
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 },
72697298 }
72707299 }
7271
7272 for (
7273 elf.dwarf.units.keys()[old_units_len..],
7274 elf.dwarf.units.values()[old_units_len..],
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
7300 for (0..units_len) |unit_index| {
7301 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));
7302 const unit = ui.get(&elf.dwarf);
7303 if (unit.debug_info_header_ni == .none) continue;
72857304 var dih_nw: MappedFile.Node.Writer = undefined;
72867305 const debug_info_header_ni = unit.debug_info_header_ni.unwrap().?;
72877306 debug_info_header_ni.writer(gpa, &elf.mf, &dih_nw);
72887307 defer dih_nw.deinit();
72897308 elf.resetNodeRelocs(debug_info_header_ni);
7290 elf.dwarf.genDebugInfoHeader(
7291 zcu,
7292 mod,
7293 unit,
7294 &dih_nw,
7295 debug_rnglists_offsets_table_offset,
7296 ) catch |err| switch (err) {
7309 elf.dwarf.genDebugInfoHeader(zcu, ui.mod(&elf.dwarf), unit, &dih_nw) catch |err| switch (err) {
72977310 else => |e| return e,
72987311 error.WriteFailed => return dih_nw.err.?,
72997312 };
......@@ -7302,8 +7315,9 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
73027315
73037316fn flushFiles(elf: *Elf) Error!void {
73047317 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| {
73067319 if (!unit.cleanDebugLineHeaderChanged()) continue;
7320 assert(unit.alive);
73077321 const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?;
73087322 try debug_line_header_ni.parent(&elf.mf).unwrap().?.nextMoved(gpa, &elf.mf);
73097323 try debug_line_header_ni.moved(gpa, &elf.mf);
......@@ -8122,10 +8136,10 @@ fn addNodeRelocAssumeCapacity(
81228136 const first_target_reloc = switch (elf.getNode(target)) {
81238137 else => unreachable,
81248138 .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,
8126 .unit_debug_info_header => |ui| &elf.dwarf_units.items[@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,
8128 .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc,
8139 .unit_frame_cie => |ui| &elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc,
8140 .unit_debug_info_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_target_reloc,
8141 .unit_debug_line_header => |ui| &elf.dwarf_units[@backingInt(ui)].debug_line_header_first_target_reloc,
8142 .unit_debug_rnglists => |ui| &elf.dwarf_units[@backingInt(ui)].debug_rnglists_first_target_reloc,
81298143 .const_debug_info => |cpi| &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_target_reloc,
81308144 .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc,
81318145 .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc,
......@@ -8621,7 +8635,7 @@ fn updateConstInner(
86218635
86228636pub fn updateConstIncomplete(
86238637 elf: *Elf,
8624 _: Zcu.PerThread,
8638 pt: Zcu.PerThread,
86258639 cpi: link.ConstPool.Index,
86268640 val: InternPool.Index,
86278641) link.Error!void {
......@@ -8629,7 +8643,7 @@ pub fn updateConstIncomplete(
86298643 var di_nw: MappedFile.Node.Writer = undefined;
86308644 debug_info_ni.writer(elf.base.comp.gpa, &elf.mf, &di_nw);
86318645 defer di_nw.deinit();
8632 try elf.dwarf.updateConstIncomplete(&di_nw, val);
8646 try elf.dwarf.updateConstIncomplete(pt, &di_nw, val);
86338647}
86348648
86358649pub fn updateFunc(
......@@ -8717,7 +8731,7 @@ fn updateFuncInner(
87178731 unit.frame_ni = .wrap(frame_ni);
87188732 break :frame_ni frame_ni;
87198733 };
8720 _ = unit.cie_ni.unwrap() orelse {
8734 if (unit.cie_ni == .none) {
87218735 const cie_ni = elf.addNodeAssumeCapacity(
87228736 try frame_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
87238737 .alignment = frame_align,
......@@ -8736,19 +8750,19 @@ fn updateFuncInner(
87368750 }, wip_nav.frame_format) catch |err| switch (err) {
87378751 error.WriteFailed => return cie_nw.err.?,
87388752 };
8739 };
8753 }
87408754 const dwarf_func = dwarf_fi.get(dwarf);
87418755 const fde_ni = if (dwarf_func.fde_ni.unwrap()) |fde_ni| fde_ni: {
87428756 try fde_ni.moved(gpa, &elf.mf);
87438757 try fde_ni.nextMoved(gpa, &elf.mf);
87448758 break :fde_ni fde_ni;
87458759 } 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, .{
87478761 .alignment = frame_align,
87488762 .moved = true,
87498763 .next_moved = true,
87508764 .enable_next_moved = true,
8751 });
8765 }), .{ .func_frame_fde = dwarf_fi });
87528766 dwarf_func.fde_ni = .wrap(fde_ni);
87538767 break :fde_ni fde_ni;
87548768 };
......@@ -8868,7 +8882,7 @@ fn updateFuncInner(
88688882 else => |e| return e,
88698883 error.WriteFailed => return dr_nw.err.?,
88708884 };
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)]
88728886 .debug_rnglists_symbol_relocs;
88738887 try symbol_relocs.ensureUnusedCapacity(gpa, elf.symbol_relocs.items.len -
88748888 first_symbol_reloc);
......@@ -9629,7 +9643,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
96299643 .unit_padding, .unit_frame, .unit_debug_info, .unit_debug_line => {},
96309644 .unit_frame_cie => |ui| {
96319645 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;
96339647 while (target_ri != .none) {
96349648 const target_reloc = target_ri.get(elf);
96359649 assert(target_reloc.target == ni);
......@@ -9638,7 +9652,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
96389652 }
96399653 },
96409654 .unit_debug_info_header => |ui| {
9641 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];
9655 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
96429656 const target_section_offset = elf.computeNodeSectionOffset(ni);
96439657 var target_ri = dwarf_unit.debug_info_header_first_target_reloc;
96449658 while (target_ri != .none) {
......@@ -9652,7 +9666,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
96529666 });
96539667 },
96549668 .unit_debug_line_header => |ui| {
9655 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];
9669 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
96569670 const target_section_offset = elf.computeNodeSectionOffset(ni);
96579671 var target_ri = dwarf_unit.debug_line_header_first_target_reloc;
96589672 while (target_ri != .none) {
......@@ -9666,7 +9680,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
96669680 });
96679681 },
96689682 .unit_debug_rnglists => |ui| {
9669 const dwarf_unit = &elf.dwarf_units.items[@backingInt(ui)];
9683 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
96709684 const target_section_offset = elf.computeNodeSectionOffset(ni);
96719685 var target_ri = dwarf_unit.debug_rnglists_first_target_reloc;
96729686 while (target_ri != .none) {