authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-02-01 15:03:55+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-02-01 15:03:55+01:00
log5de2aae63cd75322e58204a6be8df49754e4851a
treec8e61e82649f412b6a7c4b5bb422f9855df61665
parentd98fc53b8fbe479f828114b0276d5290146cc2a3

link: decouple DI atoms from linker atoms, and manage them in Dwarf linker


19 files changed, 663 insertions(+), 665 deletions(-)

src/Compilation.zig+1-1
......@@ -3299,7 +3299,7 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
32993299 const gpa = comp.gpa;
33003300 const module = comp.bin_file.options.module.?;
33013301 const decl = module.declPtr(decl_index);
3302 comp.bin_file.updateDeclLineNumber(module, decl) catch |err| {
3302 comp.bin_file.updateDeclLineNumber(module, decl_index) catch |err| {
33033303 try module.failed_decls.ensureUnusedCapacity(gpa, 1);
33043304 module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
33053305 gpa,
src/Module.zig+6-6
......@@ -5186,12 +5186,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
51865186 .coff => {
51875187 // TODO Implement for COFF
51885188 },
5189 .elf => if (decl.fn_link.elf.len != 0) {
5189 .elf => {
51905190 // TODO Look into detecting when this would be unnecessary by storing enough state
51915191 // in `Decl` to notice that the line number did not change.
51925192 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
51935193 },
5194 .macho => if (decl.fn_link.macho.len != 0) {
5194 .macho => {
51955195 // TODO Look into detecting when this would be unnecessary by storing enough state
51965196 // in `Decl` to notice that the line number did not change.
51975197 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
......@@ -5285,8 +5285,8 @@ pub fn clearDecl(
52855285 };
52865286 decl.fn_link = switch (mod.comp.bin_file.tag) {
52875287 .coff => .{ .coff = {} },
5288 .elf => .{ .elf = link.File.Dwarf.SrcFn.empty },
5289 .macho => .{ .macho = link.File.Dwarf.SrcFn.empty },
5288 .elf => .{ .elf = {} },
5289 .macho => .{ .macho = {} },
52905290 .plan9 => .{ .plan9 = {} },
52915291 .c => .{ .c = {} },
52925292 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },
......@@ -5705,8 +5705,8 @@ pub fn allocateNewDecl(
57055705 },
57065706 .fn_link = switch (mod.comp.bin_file.tag) {
57075707 .coff => .{ .coff = {} },
5708 .elf => .{ .elf = link.File.Dwarf.SrcFn.empty },
5709 .macho => .{ .macho = link.File.Dwarf.SrcFn.empty },
5708 .elf => .{ .elf = {} },
5709 .macho => .{ .macho = {} },
57105710 .plan9 => .{ .plan9 = {} },
57115711 .c => .{ .c = {} },
57125712 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },
src/arch/aarch64/CodeGen.zig+2-15
......@@ -203,13 +203,7 @@ const DbgInfoReloc = struct {
203203 else => unreachable, // not a possible argument
204204
205205 };
206 try dw.genArgDbgInfo(
207 reloc.name,
208 reloc.ty,
209 function.bin_file.tag,
210 function.mod_fn.owner_decl,
211 loc,
212 );
206 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, loc);
213207 },
214208 .plan9 => {},
215209 .none => {},
......@@ -255,14 +249,7 @@ const DbgInfoReloc = struct {
255249 break :blk .nop;
256250 },
257251 };
258 try dw.genVarDbgInfo(
259 reloc.name,
260 reloc.ty,
261 function.bin_file.tag,
262 function.mod_fn.owner_decl,
263 is_ptr,
264 loc,
265 );
252 try dw.genVarDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, is_ptr, loc);
266253 },
267254 .plan9 => {},
268255 .none => {},
src/arch/arm/CodeGen.zig+2-15
......@@ -282,13 +282,7 @@ const DbgInfoReloc = struct {
282282 else => unreachable, // not a possible argument
283283 };
284284
285 try dw.genArgDbgInfo(
286 reloc.name,
287 reloc.ty,
288 function.bin_file.tag,
289 function.mod_fn.owner_decl,
290 loc,
291 );
285 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, loc);
292286 },
293287 .plan9 => {},
294288 .none => {},
......@@ -331,14 +325,7 @@ const DbgInfoReloc = struct {
331325 break :blk .nop;
332326 },
333327 };
334 try dw.genVarDbgInfo(
335 reloc.name,
336 reloc.ty,
337 function.bin_file.tag,
338 function.mod_fn.owner_decl,
339 is_ptr,
340 loc,
341 );
328 try dw.genVarDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, is_ptr, loc);
342329 },
343330 .plan9 => {},
344331 .none => {},
src/arch/riscv64/CodeGen.zig+3-7
......@@ -1615,13 +1615,9 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
16151615
16161616 switch (self.debug_output) {
16171617 .dwarf => |dw| switch (mcv) {
1618 .register => |reg| try dw.genArgDbgInfo(
1619 name,
1620 ty,
1621 self.bin_file.tag,
1622 self.mod_fn.owner_decl,
1623 .{ .register = reg.dwarfLocOp() },
1624 ),
1618 .register => |reg| try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, .{
1619 .register = reg.dwarfLocOp(),
1620 }),
16251621 .stack_offset => {},
16261622 else => {},
16271623 },
src/arch/sparc64/CodeGen.zig+3-7
......@@ -3412,13 +3412,9 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
34123412
34133413 switch (self.debug_output) {
34143414 .dwarf => |dw| switch (mcv) {
3415 .register => |reg| try dw.genArgDbgInfo(
3416 name,
3417 ty,
3418 self.bin_file.tag,
3419 self.mod_fn.owner_decl,
3420 .{ .register = reg.dwarfLocOp() },
3421 ),
3415 .register => |reg| try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, .{
3416 .register = reg.dwarfLocOp(),
3417 }),
34223418 else => {},
34233419 },
34243420 else => {},
src/arch/wasm/CodeGen.zig+2-2
......@@ -2475,7 +2475,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24752475 .dwarf => |dwarf| {
24762476 const src_index = func.air.instructions.items(.data)[inst].arg.src_index;
24772477 const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, src_index);
2478 try dwarf.genArgDbgInfo(name, arg_ty, .wasm, func.mod_fn.owner_decl, .{
2478 try dwarf.genArgDbgInfo(name, arg_ty, func.mod_fn.owner_decl, .{
24792479 .wasm_local = arg.local.value,
24802480 });
24812481 },
......@@ -5539,7 +5539,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
55395539 break :blk .nop;
55405540 },
55415541 };
5542 try func.debug_output.dwarf.genVarDbgInfo(name, ty, .wasm, func.mod_fn.owner_decl, is_ptr, loc);
5542 try func.debug_output.dwarf.genVarDbgInfo(name, ty, func.mod_fn.owner_decl, is_ptr, loc);
55435543
55445544 func.finishAir(inst, .none, &.{});
55455545}
src/arch/x86_64/CodeGen.zig+2-2
......@@ -3836,7 +3836,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
38363836 },
38373837 else => unreachable, // not a valid function parameter
38383838 };
3839 try dw.genArgDbgInfo(name, ty, self.bin_file.tag, self.mod_fn.owner_decl, loc);
3839 try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, loc);
38403840 },
38413841 .plan9 => {},
38423842 .none => {},
......@@ -3876,7 +3876,7 @@ fn genVarDbgInfo(
38763876 break :blk .nop;
38773877 },
38783878 };
3879 try dw.genVarDbgInfo(name, ty, self.bin_file.tag, self.mod_fn.owner_decl, is_ptr, loc);
3879 try dw.genVarDbgInfo(name, ty, self.mod_fn.owner_decl, is_ptr, loc);
38803880 },
38813881 .plan9 => {},
38823882 .none => {},
src/link.zig+12-11
......@@ -273,9 +273,9 @@ pub const File = struct {
273273 };
274274
275275 pub const LinkFn = union {
276 elf: Dwarf.SrcFn,
277 coff: Coff.SrcFn,
278 macho: Dwarf.SrcFn,
276 elf: void,
277 coff: void,
278 macho: void,
279279 plan9: void,
280280 c: void,
281281 wasm: Wasm.FnData,
......@@ -580,22 +580,23 @@ pub const File = struct {
580580 }
581581 }
582582
583 pub fn updateDeclLineNumber(base: *File, module: *Module, decl: *Module.Decl) UpdateDeclError!void {
583 pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
584 const decl = module.declPtr(decl_index);
584585 log.debug("updateDeclLineNumber {*} ({s}), line={}", .{
585586 decl, decl.name, decl.src_line + 1,
586587 });
587588 assert(decl.has_tv);
588589 if (build_options.only_c) {
589590 assert(base.tag == .c);
590 return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl);
591 return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl_index);
591592 }
592593 switch (base.tag) {
593 .coff => return @fieldParentPtr(Coff, "base", base).updateDeclLineNumber(module, decl),
594 .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl),
595 .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl),
596 .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl),
597 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclLineNumber(module, decl),
598 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclLineNumber(module, decl),
594 .coff => return @fieldParentPtr(Coff, "base", base).updateDeclLineNumber(module, decl_index),
595 .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl_index),
596 .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl_index),
597 .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl_index),
598 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclLineNumber(module, decl_index),
599 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclLineNumber(module, decl_index),
599600 .spirv, .nvptx => {},
600601 }
601602 }
src/link/C.zig+2-2
......@@ -219,12 +219,12 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
219219 code.shrinkAndFree(module.gpa, code.items.len);
220220}
221221
222pub fn updateDeclLineNumber(self: *C, module: *Module, decl: *Module.Decl) !void {
222pub fn updateDeclLineNumber(self: *C, module: *Module, decl_index: Module.Decl.Index) !void {
223223 // The C backend does not have the ability to fix line numbers without re-generating
224224 // the entire Decl.
225225 _ = self;
226226 _ = module;
227 _ = decl;
227 _ = decl_index;
228228}
229229
230230pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
src/link/Coff.zig+2-3
......@@ -195,7 +195,6 @@ pub const PtrWidth = enum {
195195 };
196196 }
197197};
198pub const SrcFn = void;
199198
200199pub const SymbolWithLoc = struct {
201200 // Index into the respective symbol table.
......@@ -1545,10 +1544,10 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 {
15451544 return global_index;
15461545}
15471546
1548pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !void {
1547pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !void {
15491548 _ = self;
15501549 _ = module;
1551 _ = decl;
1550 _ = decl_index;
15521551 log.debug("TODO implement updateDeclLineNumber", .{});
15531552}
15541553
src/link/Dwarf.zig+292-224
......@@ -27,17 +27,21 @@ bin_file: *File,
2727ptr_width: PtrWidth,
2828target: std.Target,
2929
30/// A list of `File.LinkFn` whose Line Number Programs have surplus capacity.
31/// This is the same concept as `text_block_free_list`; see those doc comments.
32dbg_line_fn_free_list: std.AutoHashMapUnmanaged(*SrcFn, void) = .{},
33dbg_line_fn_first: ?*SrcFn = null,
34dbg_line_fn_last: ?*SrcFn = null,
30/// A list of `Atom`s whose Line Number Programs have surplus capacity.
31/// This is the same concept as `Section.free_list` in Elf; see those doc comments.
32src_fn_free_list: std.AutoHashMapUnmanaged(Atom.Index, void) = .{},
33src_fn_first_index: ?Atom.Index = null,
34src_fn_last_index: ?Atom.Index = null,
35src_fns: std.ArrayListUnmanaged(Atom) = .{},
36src_fn_decls: AtomTable = .{},
3537
3638/// A list of `Atom`s whose corresponding .debug_info tags have surplus capacity.
3739/// This is the same concept as `text_block_free_list`; see those doc comments.
38atom_free_list: std.AutoHashMapUnmanaged(*Atom, void) = .{},
39atom_first: ?*Atom = null,
40atom_last: ?*Atom = null,
40di_atom_free_list: std.AutoHashMapUnmanaged(Atom.Index, void) = .{},
41di_atom_first_index: ?Atom.Index = null,
42di_atom_last_index: ?Atom.Index = null,
43di_atoms: std.ArrayListUnmanaged(Atom) = .{},
44di_atom_decls: AtomTable = .{},
4145
4246abbrev_table_offset: ?u64 = null,
4347
......@@ -51,22 +55,23 @@ strtab: StringTable(.strtab) = .{},
5155/// * []file_names
5256di_files: std.AutoArrayHashMapUnmanaged(*const Module.File, void) = .{},
5357
54/// List of atoms that are owned directly by the DWARF module.
55/// TODO convert links in DebugInfoAtom into indices and make
56/// sure every atom is owned by this module.
57managed_atoms: std.ArrayListUnmanaged(*Atom) = .{},
58
5958global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},
6059
61pub const Atom = struct {
62 /// Previous/next linked list pointers.
63 /// This is the linked list node for this Decl's corresponding .debug_info tag.
64 prev: ?*Atom,
65 next: ?*Atom,
66 /// Offset into .debug_info pointing to the tag for this Decl.
60const AtomTable = std.AutoHashMapUnmanaged(Module.Decl.Index, Atom.Index);
61
62const Atom = struct {
63 /// Offset into .debug_info pointing to the tag for this Decl, or
64 /// offset from the beginning of the Debug Line Program header that contains this function.
6765 off: u32,
68 /// Size of the .debug_info tag for this Decl, not including padding.
66 /// Size of the .debug_info tag for this Decl, not including padding, or
67 /// size of the line number program component belonging to this function, not
68 /// including padding.
6969 len: u32,
70
71 prev_index: ?Index,
72 next_index: ?Index,
73
74 pub const Index = u32;
7075};
7176
7277/// Represents state of the analysed Decl.
......@@ -76,6 +81,7 @@ pub const Atom = struct {
7681pub const DeclState = struct {
7782 gpa: Allocator,
7883 mod: *Module,
84 di_atom_decls: *const AtomTable,
7985 dbg_line: std.ArrayList(u8),
8086 dbg_info: std.ArrayList(u8),
8187 abbrev_type_arena: std.heap.ArenaAllocator,
......@@ -89,10 +95,11 @@ pub const DeclState = struct {
8995 abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},
9096 exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation) = .{},
9197
92 fn init(gpa: Allocator, mod: *Module) DeclState {
98 fn init(gpa: Allocator, mod: *Module, di_atom_decls: *const AtomTable) DeclState {
9399 return .{
94100 .gpa = gpa,
95101 .mod = mod,
102 .di_atom_decls = di_atom_decls,
96103 .dbg_line = std.ArrayList(u8).init(gpa),
97104 .dbg_info = std.ArrayList(u8).init(gpa),
98105 .abbrev_type_arena = std.heap.ArenaAllocator.init(gpa),
......@@ -120,11 +127,11 @@ pub const DeclState = struct {
120127
121128 /// Adds local type relocation of the form: @offset => @this + addend
122129 /// @this signifies the offset within the .debug_abbrev section of the containing atom.
123 fn addTypeRelocLocal(self: *DeclState, atom: *const Atom, offset: u32, addend: u32) !void {
130 fn addTypeRelocLocal(self: *DeclState, atom_index: Atom.Index, offset: u32, addend: u32) !void {
124131 log.debug("{x}: @this + {x}", .{ offset, addend });
125132 try self.abbrev_relocs.append(self.gpa, .{
126133 .target = null,
127 .atom = atom,
134 .atom_index = atom_index,
128135 .offset = offset,
129136 .addend = addend,
130137 });
......@@ -133,13 +140,13 @@ pub const DeclState = struct {
133140 /// Adds global type relocation of the form: @offset => @symbol + 0
134141 /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section
135142 /// which we use as our target of the relocation.
136 fn addTypeRelocGlobal(self: *DeclState, atom: *const Atom, ty: Type, offset: u32) !void {
143 fn addTypeRelocGlobal(self: *DeclState, atom_index: Atom.Index, ty: Type, offset: u32) !void {
137144 const resolv = self.abbrev_resolver.getContext(ty, .{
138145 .mod = self.mod,
139146 }) orelse blk: {
140147 const sym_index = @intCast(u32, self.abbrev_table.items.len);
141148 try self.abbrev_table.append(self.gpa, .{
142 .atom = atom,
149 .atom_index = atom_index,
143150 .type = ty,
144151 .offset = undefined,
145152 });
......@@ -154,7 +161,7 @@ pub const DeclState = struct {
154161 log.debug("{x}: %{d} + 0", .{ offset, resolv });
155162 try self.abbrev_relocs.append(self.gpa, .{
156163 .target = resolv,
157 .atom = atom,
164 .atom_index = atom_index,
158165 .offset = offset,
159166 .addend = 0,
160167 });
......@@ -163,7 +170,7 @@ pub const DeclState = struct {
163170 fn addDbgInfoType(
164171 self: *DeclState,
165172 module: *Module,
166 atom: *Atom,
173 atom_index: Atom.Index,
167174 ty: Type,
168175 ) error{OutOfMemory}!void {
169176 const arena = self.abbrev_type_arena.allocator();
......@@ -228,7 +235,7 @@ pub const DeclState = struct {
228235 // DW.AT.type, DW.FORM.ref4
229236 var index = dbg_info_buffer.items.len;
230237 try dbg_info_buffer.resize(index + 4);
231 try self.addTypeRelocGlobal(atom, Type.bool, @intCast(u32, index));
238 try self.addTypeRelocGlobal(atom_index, Type.bool, @intCast(u32, index));
232239 // DW.AT.data_member_location, DW.FORM.sdata
233240 try dbg_info_buffer.ensureUnusedCapacity(6);
234241 dbg_info_buffer.appendAssumeCapacity(0);
......@@ -240,7 +247,7 @@ pub const DeclState = struct {
240247 // DW.AT.type, DW.FORM.ref4
241248 index = dbg_info_buffer.items.len;
242249 try dbg_info_buffer.resize(index + 4);
243 try self.addTypeRelocGlobal(atom, payload_ty, @intCast(u32, index));
250 try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index));
244251 // DW.AT.data_member_location, DW.FORM.sdata
245252 const offset = abi_size - payload_ty.abiSize(target);
246253 try leb128.writeULEB128(dbg_info_buffer.writer(), offset);
......@@ -271,7 +278,7 @@ pub const DeclState = struct {
271278 try dbg_info_buffer.resize(index + 4);
272279 var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);
273280 const ptr_ty = ty.slicePtrFieldType(buf);
274 try self.addTypeRelocGlobal(atom, ptr_ty, @intCast(u32, index));
281 try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index));
275282 // DW.AT.data_member_location, DW.FORM.sdata
276283 try dbg_info_buffer.ensureUnusedCapacity(6);
277284 dbg_info_buffer.appendAssumeCapacity(0);
......@@ -283,7 +290,7 @@ pub const DeclState = struct {
283290 // DW.AT.type, DW.FORM.ref4
284291 index = dbg_info_buffer.items.len;
285292 try dbg_info_buffer.resize(index + 4);
286 try self.addTypeRelocGlobal(atom, Type.usize, @intCast(u32, index));
293 try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(u32, index));
287294 // DW.AT.data_member_location, DW.FORM.sdata
288295 try dbg_info_buffer.ensureUnusedCapacity(2);
289296 dbg_info_buffer.appendAssumeCapacity(ptr_bytes);
......@@ -295,7 +302,7 @@ pub const DeclState = struct {
295302 // DW.AT.type, DW.FORM.ref4
296303 const index = dbg_info_buffer.items.len;
297304 try dbg_info_buffer.resize(index + 4);
298 try self.addTypeRelocGlobal(atom, ty.childType(), @intCast(u32, index));
305 try self.addTypeRelocGlobal(atom_index, ty.childType(), @intCast(u32, index));
299306 }
300307 },
301308 .Array => {
......@@ -306,13 +313,13 @@ pub const DeclState = struct {
306313 // DW.AT.type, DW.FORM.ref4
307314 var index = dbg_info_buffer.items.len;
308315 try dbg_info_buffer.resize(index + 4);
309 try self.addTypeRelocGlobal(atom, ty.childType(), @intCast(u32, index));
316 try self.addTypeRelocGlobal(atom_index, ty.childType(), @intCast(u32, index));
310317 // DW.AT.subrange_type
311318 try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_dim));
312319 // DW.AT.type, DW.FORM.ref4
313320 index = dbg_info_buffer.items.len;
314321 try dbg_info_buffer.resize(index + 4);
315 try self.addTypeRelocGlobal(atom, Type.usize, @intCast(u32, index));
322 try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(u32, index));
316323 // DW.AT.count, DW.FORM.udata
317324 const len = ty.arrayLenIncludingSentinel();
318325 try leb128.writeULEB128(dbg_info_buffer.writer(), len);
......@@ -340,7 +347,7 @@ pub const DeclState = struct {
340347 // DW.AT.type, DW.FORM.ref4
341348 var index = dbg_info_buffer.items.len;
342349 try dbg_info_buffer.resize(index + 4);
343 try self.addTypeRelocGlobal(atom, field, @intCast(u32, index));
350 try self.addTypeRelocGlobal(atom_index, field, @intCast(u32, index));
344351 // DW.AT.data_member_location, DW.FORM.sdata
345352 const field_off = ty.structFieldOffset(field_index, target);
346353 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
......@@ -372,7 +379,7 @@ pub const DeclState = struct {
372379 // DW.AT.type, DW.FORM.ref4
373380 var index = dbg_info_buffer.items.len;
374381 try dbg_info_buffer.resize(index + 4);
375 try self.addTypeRelocGlobal(atom, field.ty, @intCast(u32, index));
382 try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index));
376383 // DW.AT.data_member_location, DW.FORM.sdata
377384 const field_off = ty.structFieldOffset(field_index, target);
378385 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
......@@ -455,7 +462,7 @@ pub const DeclState = struct {
455462 // DW.AT.type, DW.FORM.ref4
456463 const inner_union_index = dbg_info_buffer.items.len;
457464 try dbg_info_buffer.resize(inner_union_index + 4);
458 try self.addTypeRelocLocal(atom, @intCast(u32, inner_union_index), 5);
465 try self.addTypeRelocLocal(atom_index, @intCast(u32, inner_union_index), 5);
459466 // DW.AT.data_member_location, DW.FORM.sdata
460467 try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset);
461468 }
......@@ -482,7 +489,7 @@ pub const DeclState = struct {
482489 // DW.AT.type, DW.FORM.ref4
483490 const index = dbg_info_buffer.items.len;
484491 try dbg_info_buffer.resize(index + 4);
485 try self.addTypeRelocGlobal(atom, field.ty, @intCast(u32, index));
492 try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index));
486493 // DW.AT.data_member_location, DW.FORM.sdata
487494 try dbg_info_buffer.append(0);
488495 }
......@@ -499,7 +506,7 @@ pub const DeclState = struct {
499506 // DW.AT.type, DW.FORM.ref4
500507 const index = dbg_info_buffer.items.len;
501508 try dbg_info_buffer.resize(index + 4);
502 try self.addTypeRelocGlobal(atom, union_obj.tag_ty, @intCast(u32, index));
509 try self.addTypeRelocGlobal(atom_index, union_obj.tag_ty, @intCast(u32, index));
503510 // DW.AT.data_member_location, DW.FORM.sdata
504511 try leb128.writeULEB128(dbg_info_buffer.writer(), tag_offset);
505512
......@@ -542,7 +549,7 @@ pub const DeclState = struct {
542549 // DW.AT.type, DW.FORM.ref4
543550 var index = dbg_info_buffer.items.len;
544551 try dbg_info_buffer.resize(index + 4);
545 try self.addTypeRelocGlobal(atom, payload_ty, @intCast(u32, index));
552 try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index));
546553 // DW.AT.data_member_location, DW.FORM.sdata
547554 try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off);
548555
......@@ -555,7 +562,7 @@ pub const DeclState = struct {
555562 // DW.AT.type, DW.FORM.ref4
556563 index = dbg_info_buffer.items.len;
557564 try dbg_info_buffer.resize(index + 4);
558 try self.addTypeRelocGlobal(atom, error_ty, @intCast(u32, index));
565 try self.addTypeRelocGlobal(atom_index, error_ty, @intCast(u32, index));
559566 // DW.AT.data_member_location, DW.FORM.sdata
560567 try leb128.writeULEB128(dbg_info_buffer.writer(), error_off);
561568
......@@ -588,12 +595,11 @@ pub const DeclState = struct {
588595 self: *DeclState,
589596 name: [:0]const u8,
590597 ty: Type,
591 tag: File.Tag,
592598 owner_decl: Module.Decl.Index,
593599 loc: DbgInfoLoc,
594600 ) error{OutOfMemory}!void {
595601 const dbg_info = &self.dbg_info;
596 const atom = getDbgInfoAtom(tag, self.mod, owner_decl);
602 const atom_index = self.di_atom_decls.get(owner_decl).?;
597603 const name_with_null = name.ptr[0 .. name.len + 1];
598604
599605 switch (loc) {
......@@ -638,7 +644,7 @@ pub const DeclState = struct {
638644 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
639645 const index = dbg_info.items.len;
640646 try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4
641 try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4
647 try self.addTypeRelocGlobal(atom_index, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4
642648 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
643649 }
644650
......@@ -646,13 +652,12 @@ pub const DeclState = struct {
646652 self: *DeclState,
647653 name: [:0]const u8,
648654 ty: Type,
649 tag: File.Tag,
650655 owner_decl: Module.Decl.Index,
651656 is_ptr: bool,
652657 loc: DbgInfoLoc,
653658 ) error{OutOfMemory}!void {
654659 const dbg_info = &self.dbg_info;
655 const atom = getDbgInfoAtom(tag, self.mod, owner_decl);
660 const atom_index = self.di_atom_decls.get(owner_decl).?;
656661 const name_with_null = name.ptr[0 .. name.len + 1];
657662 try dbg_info.append(@enumToInt(AbbrevKind.variable));
658663 const target = self.mod.getTarget();
......@@ -782,7 +787,7 @@ pub const DeclState = struct {
782787 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
783788 const index = dbg_info.items.len;
784789 try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4
785 try self.addTypeRelocGlobal(atom, child_ty, @intCast(u32, index));
790 try self.addTypeRelocGlobal(atom_index, child_ty, @intCast(u32, index));
786791 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
787792 }
788793
......@@ -815,7 +820,7 @@ pub const DeclState = struct {
815820};
816821
817822pub const AbbrevEntry = struct {
818 atom: *const Atom,
823 atom_index: Atom.Index,
819824 type: Type,
820825 offset: u32,
821826};
......@@ -824,7 +829,7 @@ pub const AbbrevRelocation = struct {
824829 /// If target is null, we deal with a local relocation that is based on simple offset + addend
825830 /// only.
826831 target: ?u32,
827 atom: *const Atom,
832 atom_index: Atom.Index,
828833 offset: u32,
829834 addend: u32,
830835};
......@@ -841,26 +846,6 @@ pub const ExprlocRelocation = struct {
841846 offset: u32,
842847};
843848
844pub const SrcFn = struct {
845 /// Offset from the beginning of the Debug Line Program header that contains this function.
846 off: u32,
847 /// Size of the line number program component belonging to this function, not
848 /// including padding.
849 len: u32,
850
851 /// Points to the previous and next neighbors, based on the offset from .debug_line.
852 /// This can be used to find, for example, the capacity of this `SrcFn`.
853 prev: ?*SrcFn,
854 next: ?*SrcFn,
855
856 pub const empty: SrcFn = .{
857 .off = 0,
858 .len = 0,
859 .prev = null,
860 .next = null,
861 };
862};
863
864849pub const PtrWidth = enum { p32, p64 };
865850
866851pub const AbbrevKind = enum(u8) {
......@@ -910,16 +895,18 @@ pub fn init(allocator: Allocator, bin_file: *File, target: std.Target) Dwarf {
910895
911896pub fn deinit(self: *Dwarf) void {
912897 const gpa = self.allocator;
913 self.dbg_line_fn_free_list.deinit(gpa);
914 self.atom_free_list.deinit(gpa);
898
899 self.src_fn_free_list.deinit(gpa);
900 self.src_fns.deinit(gpa);
901 self.src_fn_decls.deinit(gpa);
902
903 self.di_atom_free_list.deinit(gpa);
904 self.di_atoms.deinit(gpa);
905 self.di_atom_decls.deinit(gpa);
906
915907 self.strtab.deinit(gpa);
916908 self.di_files.deinit(gpa);
917909 self.global_abbrev_relocs.deinit(gpa);
918
919 for (self.managed_atoms.items) |atom| {
920 gpa.destroy(atom);
921 }
922 self.managed_atoms.deinit(gpa);
923910}
924911
925912/// Initializes Decl's state and its matching output buffers.
......@@ -935,15 +922,19 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
935922 log.debug("initDeclState {s}{*}", .{ decl_name, decl });
936923
937924 const gpa = self.allocator;
938 var decl_state = DeclState.init(gpa, mod);
925 var decl_state = DeclState.init(gpa, mod, &self.di_atom_decls);
939926 errdefer decl_state.deinit();
940927 const dbg_line_buffer = &decl_state.dbg_line;
941928 const dbg_info_buffer = &decl_state.dbg_info;
942929
930 const di_atom_index = try self.getOrCreateAtomForDecl(.di_atom, decl_index);
931
943932 assert(decl.has_tv);
944933
945934 switch (decl.ty.zigTypeTag()) {
946935 .Fn => {
936 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);
937
947938 // For functions we need to add a prologue to the debug line program.
948939 try dbg_line_buffer.ensureTotalCapacity(26);
949940
......@@ -1003,8 +994,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
1003994 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4
1004995 //
1005996 if (fn_ret_has_bits) {
1006 const atom = getDbgInfoAtom(self.bin_file.tag, mod, decl_index);
1007 try decl_state.addTypeRelocGlobal(atom, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len));
997 try decl_state.addTypeRelocGlobal(di_atom_index, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len));
1008998 dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4
1009999 }
10101000
......@@ -1076,26 +1066,23 @@ pub fn commitDeclState(
10761066 // This logic is nearly identical to the logic below in `updateDeclDebugInfo` for
10771067 // `TextBlock` and the .debug_info. If you are editing this logic, you
10781068 // probably need to edit that logic too.
1079 const src_fn = switch (self.bin_file.tag) {
1080 .elf => &decl.fn_link.elf,
1081 .macho => &decl.fn_link.macho,
1082 .wasm => &decl.fn_link.wasm.src_fn,
1083 else => unreachable, // TODO
1084 };
1069 const src_fn_index = self.src_fn_decls.get(decl_index).?;
1070 const src_fn = self.getAtomPtr(.src_fn, src_fn_index);
10851071 src_fn.len = @intCast(u32, dbg_line_buffer.items.len);
10861072
1087 if (self.dbg_line_fn_last) |last| blk: {
1088 if (src_fn == last) break :blk;
1089 if (src_fn.next) |next| {
1073 if (self.src_fn_last_index) |last_index| blk: {
1074 if (src_fn_index == last_index) break :blk;
1075 if (src_fn.next_index) |next_index| {
1076 const next = self.getAtomPtr(.src_fn, next_index);
10901077 // Update existing function - non-last item.
10911078 if (src_fn.off + src_fn.len + min_nop_size > next.off) {
10921079 // It grew too big, so we move it to a new location.
1093 if (src_fn.prev) |prev| {
1094 self.dbg_line_fn_free_list.put(gpa, prev, {}) catch {};
1095 prev.next = src_fn.next;
1080 if (src_fn.prev_index) |prev_index| {
1081 self.src_fn_free_list.put(gpa, prev_index, {}) catch {};
1082 self.getAtomPtr(.src_fn, prev_index).next_index = src_fn.next_index;
10961083 }
1097 next.prev = src_fn.prev;
1098 src_fn.next = null;
1084 next.prev_index = src_fn.prev_index;
1085 src_fn.next_index = null;
10991086 // Populate where it used to be with NOPs.
11001087 switch (self.bin_file.tag) {
11011088 .elf => {
......@@ -1118,33 +1105,42 @@ pub fn commitDeclState(
11181105 else => unreachable,
11191106 }
11201107 // TODO Look at the free list before appending at the end.
1121 src_fn.prev = last;
1122 last.next = src_fn;
1123 self.dbg_line_fn_last = src_fn;
1108 src_fn.prev_index = last_index;
1109 const last = self.getAtomPtr(.src_fn, last_index);
1110 last.next_index = src_fn_index;
1111 self.src_fn_last_index = src_fn_index;
11241112
11251113 src_fn.off = last.off + padToIdeal(last.len);
11261114 }
1127 } else if (src_fn.prev == null) {
1115 } else if (src_fn.prev_index == null) {
11281116 // Append new function.
11291117 // TODO Look at the free list before appending at the end.
1130 src_fn.prev = last;
1131 last.next = src_fn;
1132 self.dbg_line_fn_last = src_fn;
1118 src_fn.prev_index = last_index;
1119 const last = self.getAtomPtr(.src_fn, last_index);
1120 last.next_index = src_fn_index;
1121 self.src_fn_last_index = src_fn_index;
11331122
11341123 src_fn.off = last.off + padToIdeal(last.len);
11351124 }
11361125 } else {
11371126 // This is the first function of the Line Number Program.
1138 self.dbg_line_fn_first = src_fn;
1139 self.dbg_line_fn_last = src_fn;
1127 self.src_fn_first_index = src_fn_index;
1128 self.src_fn_last_index = src_fn_index;
11401129
11411130 src_fn.off = padToIdeal(self.dbgLineNeededHeaderBytes(&[0][]u8{}, &[0][]u8{}));
11421131 }
11431132
1144 const last_src_fn = self.dbg_line_fn_last.?;
1133 const last_src_fn_index = self.src_fn_last_index.?;
1134 const last_src_fn = self.getAtom(.src_fn, last_src_fn_index);
11451135 const needed_size = last_src_fn.off + last_src_fn.len;
1146 const prev_padding_size: u32 = if (src_fn.prev) |prev| src_fn.off - (prev.off + prev.len) else 0;
1147 const next_padding_size: u32 = if (src_fn.next) |next| next.off - (src_fn.off + src_fn.len) else 0;
1136 const prev_padding_size: u32 = if (src_fn.prev_index) |prev_index| blk: {
1137 const prev = self.getAtom(.src_fn, prev_index);
1138 break :blk src_fn.off - (prev.off + prev.len);
1139 } else 0;
1140 const next_padding_size: u32 = if (src_fn.next_index) |next_index| blk: {
1141 const next = self.getAtom(.src_fn, next_index);
1142 break :blk next.off - (src_fn.off + src_fn.len);
1143 } else 0;
11481144
11491145 // We only have support for one compilation unit so far, so the offsets are directly
11501146 // from the .debug_line section.
......@@ -1213,7 +1209,7 @@ pub fn commitDeclState(
12131209 if (dbg_info_buffer.items.len == 0)
12141210 return;
12151211
1216 const atom = getDbgInfoAtom(self.bin_file.tag, module, decl_index);
1212 const di_atom_index = self.di_atom_decls.get(decl_index).?;
12171213 if (decl_state.abbrev_table.items.len > 0) {
12181214 // Now we emit the .debug_info types of the Decl. These will count towards the size of
12191215 // the buffer, so we have to do it before computing the offset, and we can't perform the actual
......@@ -1235,12 +1231,12 @@ pub fn commitDeclState(
12351231 if (deferred) continue;
12361232
12371233 symbol.offset = @intCast(u32, dbg_info_buffer.items.len);
1238 try decl_state.addDbgInfoType(module, atom, ty);
1234 try decl_state.addDbgInfoType(module, di_atom_index, ty);
12391235 }
12401236 }
12411237
12421238 log.debug("updateDeclDebugInfoAllocation for '{s}'", .{decl.name});
1243 try self.updateDeclDebugInfoAllocation(atom, @intCast(u32, dbg_info_buffer.items.len));
1239 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(u32, dbg_info_buffer.items.len));
12441240
12451241 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
12461242 if (reloc.target) |target| {
......@@ -1261,11 +1257,12 @@ pub fn commitDeclState(
12611257 try self.global_abbrev_relocs.append(gpa, .{
12621258 .target = null,
12631259 .offset = reloc.offset,
1264 .atom = reloc.atom,
1260 .atom_index = reloc.atom_index,
12651261 .addend = reloc.addend,
12661262 });
12671263 } else {
1268 const value = symbol.atom.off + symbol.offset + reloc.addend;
1264 const atom = self.getAtom(.di_atom, symbol.atom_index);
1265 const value = atom.off + symbol.offset + reloc.addend;
12691266 log.debug("{x}: [() => {x}] (%{d}, '{}')", .{ reloc.offset, value, target, ty.fmtDebug() });
12701267 mem.writeInt(
12711268 u32,
......@@ -1275,10 +1272,11 @@ pub fn commitDeclState(
12751272 );
12761273 }
12771274 } else {
1275 const atom = self.getAtom(.di_atom, reloc.atom_index);
12781276 mem.writeInt(
12791277 u32,
12801278 dbg_info_buffer.items[reloc.offset..][0..@sizeOf(u32)],
1281 reloc.atom.off + reloc.offset + reloc.addend,
1279 atom.off + reloc.offset + reloc.addend,
12821280 target_endian,
12831281 );
12841282 }
......@@ -1294,7 +1292,7 @@ pub fn commitDeclState(
12941292 .got_load => .got_load,
12951293 },
12961294 .target = reloc.target,
1297 .offset = reloc.offset + atom.off,
1295 .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off,
12981296 .addend = 0,
12991297 .prev_vaddr = 0,
13001298 });
......@@ -1304,10 +1302,10 @@ pub fn commitDeclState(
13041302 }
13051303
13061304 log.debug("writeDeclDebugInfo for '{s}", .{decl.name});
1307 try self.writeDeclDebugInfo(atom, dbg_info_buffer.items);
1305 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);
13081306}
13091307
1310fn updateDeclDebugInfoAllocation(self: *Dwarf, atom: *Atom, len: u32) !void {
1308fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) !void {
13111309 const tracy = trace(@src());
13121310 defer tracy.end();
13131311
......@@ -1316,19 +1314,21 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom: *Atom, len: u32) !void {
13161314 // probably need to edit that logic too.
13171315 const gpa = self.allocator;
13181316
1317 const atom = self.getAtomPtr(.di_atom, atom_index);
13191318 atom.len = len;
1320 if (self.atom_last) |last| blk: {
1321 if (atom == last) break :blk;
1322 if (atom.next) |next| {
1319 if (self.di_atom_last_index) |last_index| blk: {
1320 if (atom_index == last_index) break :blk;
1321 if (atom.next_index) |next_index| {
1322 const next = self.getAtomPtr(.di_atom, next_index);
13231323 // Update existing Decl - non-last item.
13241324 if (atom.off + atom.len + min_nop_size > next.off) {
13251325 // It grew too big, so we move it to a new location.
1326 if (atom.prev) |prev| {
1327 self.atom_free_list.put(gpa, prev, {}) catch {};
1328 prev.next = atom.next;
1326 if (atom.prev_index) |prev_index| {
1327 self.di_atom_free_list.put(gpa, prev_index, {}) catch {};
1328 self.getAtomPtr(.di_atom, prev_index).next_index = atom.next_index;
13291329 }
1330 next.prev = atom.prev;
1331 atom.next = null;
1330 next.prev_index = atom.prev_index;
1331 atom.next_index = null;
13321332 // Populate where it used to be with NOPs.
13331333 switch (self.bin_file.tag) {
13341334 .elf => {
......@@ -1351,31 +1351,33 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom: *Atom, len: u32) !void {
13511351 else => unreachable,
13521352 }
13531353 // TODO Look at the free list before appending at the end.
1354 atom.prev = last;
1355 last.next = atom;
1356 self.atom_last = atom;
1354 atom.prev_index = last_index;
1355 const last = self.getAtomPtr(.di_atom, last_index);
1356 last.next_index = atom_index;
1357 self.di_atom_last_index = atom_index;
13571358
13581359 atom.off = last.off + padToIdeal(last.len);
13591360 }
1360 } else if (atom.prev == null) {
1361 } else if (atom.prev_index == null) {
13611362 // Append new Decl.
13621363 // TODO Look at the free list before appending at the end.
1363 atom.prev = last;
1364 last.next = atom;
1365 self.atom_last = atom;
1364 atom.prev_index = last_index;
1365 const last = self.getAtomPtr(.di_atom, last_index);
1366 last.next_index = atom_index;
1367 self.di_atom_last_index = atom_index;
13661368
13671369 atom.off = last.off + padToIdeal(last.len);
13681370 }
13691371 } else {
13701372 // This is the first Decl of the .debug_info
1371 self.atom_first = atom;
1372 self.atom_last = atom;
1373 self.di_atom_first_index = atom_index;
1374 self.di_atom_last_index = atom_index;
13731375
13741376 atom.off = @intCast(u32, padToIdeal(self.dbgInfoHeaderBytes()));
13751377 }
13761378}
13771379
1378fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void {
1380fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []const u8) !void {
13791381 const tracy = trace(@src());
13801382 defer tracy.end();
13811383
......@@ -1384,14 +1386,22 @@ fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void
13841386 // probably need to edit that logic too.
13851387 const gpa = self.allocator;
13861388
1387 const last_decl = self.atom_last.?;
1389 const atom = self.getAtom(.di_atom, atom_index);
1390 const last_decl_index = self.di_atom_last_index.?;
1391 const last_decl = self.getAtom(.di_atom, last_decl_index);
13881392 // +1 for a trailing zero to end the children of the decl tag.
13891393 const needed_size = last_decl.off + last_decl.len + 1;
1390 const prev_padding_size: u32 = if (atom.prev) |prev| atom.off - (prev.off + prev.len) else 0;
1391 const next_padding_size: u32 = if (atom.next) |next| next.off - (atom.off + atom.len) else 0;
1394 const prev_padding_size: u32 = if (atom.prev_index) |prev_index| blk: {
1395 const prev = self.getAtom(.di_atom, prev_index);
1396 break :blk atom.off - (prev.off + prev.len);
1397 } else 0;
1398 const next_padding_size: u32 = if (atom.next_index) |next_index| blk: {
1399 const next = self.getAtom(.di_atom, next_index);
1400 break :blk next.off - (atom.off + atom.len);
1401 } else 0;
13921402
13931403 // To end the children of the decl tag.
1394 const trailing_zero = atom.next == null;
1404 const trailing_zero = atom.next_index == null;
13951405
13961406 // We only have support for one compilation unit so far, so the offsets are directly
13971407 // from the .debug_info section.
......@@ -1459,10 +1469,15 @@ fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void
14591469 }
14601470}
14611471
1462pub fn updateDeclLineNumber(self: *Dwarf, decl: *const Module.Decl) !void {
1472pub fn updateDeclLineNumber(self: *Dwarf, module: *Module, decl_index: Module.Decl.Index) !void {
14631473 const tracy = trace(@src());
14641474 defer tracy.end();
14651475
1476 const atom_index = try self.getOrCreateAtomForDecl(.src_fn, decl_index);
1477 const atom = self.getAtom(.src_fn, atom_index);
1478 if (atom.len == 0) return;
1479
1480 const decl = module.declPtr(decl_index);
14661481 const func = decl.val.castTag(.function).?.data;
14671482 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
14681483 decl.src_line,
......@@ -1477,78 +1492,80 @@ pub fn updateDeclLineNumber(self: *Dwarf, decl: *const Module.Decl) !void {
14771492 .elf => {
14781493 const elf_file = self.bin_file.cast(File.Elf).?;
14791494 const shdr = elf_file.sections.items(.shdr)[elf_file.debug_line_section_index.?];
1480 const file_pos = shdr.sh_offset + decl.fn_link.elf.off + self.getRelocDbgLineOff();
1495 const file_pos = shdr.sh_offset + atom.off + self.getRelocDbgLineOff();
14811496 try elf_file.base.file.?.pwriteAll(&data, file_pos);
14821497 },
14831498 .macho => {
14841499 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
14851500 const sect = d_sym.getSection(d_sym.debug_line_section_index.?);
1486 const file_pos = sect.offset + decl.fn_link.macho.off + self.getRelocDbgLineOff();
1501 const file_pos = sect.offset + atom.off + self.getRelocDbgLineOff();
14871502 try d_sym.file.pwriteAll(&data, file_pos);
14881503 },
14891504 .wasm => {
14901505 const wasm_file = self.bin_file.cast(File.Wasm).?;
1491 const offset = decl.fn_link.wasm.src_fn.off + self.getRelocDbgLineOff();
1492 const atom = wasm_file.debug_line_atom.?;
1493 mem.copy(u8, atom.code.items[offset..], &data);
1506 const offset = atom.off + self.getRelocDbgLineOff();
1507 const atom_ = wasm_file.debug_line_atom.?;
1508 mem.copy(u8, atom_.code.items[offset..], &data);
14941509 },
14951510 else => unreachable,
14961511 }
14971512}
14981513
1499pub fn freeAtom(self: *Dwarf, atom: *Atom) void {
1500 if (self.atom_first == atom) {
1501 self.atom_first = atom.next;
1502 }
1503 if (self.atom_last == atom) {
1504 // TODO shrink the .debug_info section size here
1505 self.atom_last = atom.prev;
1506 }
1507
1508 if (atom.prev) |prev| {
1509 prev.next = atom.next;
1514pub fn freeDecl(self: *Dwarf, decl_index: Module.Decl.Index) void {
1515 const gpa = self.allocator;
15101516
1511 // TODO the free list logic like we do for text blocks above
1512 } else {
1513 atom.prev = null;
1517 // Free SrcFn atom
1518 if (self.src_fn_decls.fetchRemove(decl_index)) |kv| {
1519 const src_fn_index = kv.value;
1520 const src_fn = self.getAtom(.src_fn, src_fn_index);
1521 _ = self.src_fn_free_list.remove(src_fn_index);
1522
1523 if (src_fn.prev_index) |prev_index| {
1524 self.src_fn_free_list.put(gpa, prev_index, {}) catch {};
1525 const prev = self.getAtomPtr(.src_fn, prev_index);
1526 prev.next_index = src_fn.next_index;
1527 if (src_fn.next_index) |next_index| {
1528 self.getAtomPtr(.src_fn, next_index).prev_index = prev_index;
1529 } else {
1530 self.src_fn_last_index = prev_index;
1531 }
1532 } else if (src_fn.next_index) |next_index| {
1533 self.src_fn_first_index = next_index;
1534 self.getAtomPtr(.src_fn, next_index).prev_index = null;
1535 }
1536 if (self.src_fn_first_index == src_fn_index) {
1537 self.src_fn_first_index = src_fn.next_index;
1538 }
1539 if (self.src_fn_last_index == src_fn_index) {
1540 self.src_fn_last_index = src_fn.prev_index;
1541 }
15141542 }
15151543
1516 if (atom.next) |next| {
1517 next.prev = atom.prev;
1518 } else {
1519 atom.next = null;
1520 }
1521}
1544 // Free DI atom
1545 if (self.di_atom_decls.fetchRemove(decl_index)) |kv| {
1546 const di_atom_index = kv.value;
1547 const di_atom = self.getAtomPtr(.di_atom, di_atom_index);
15221548
1523pub fn freeDecl(self: *Dwarf, decl: *Module.Decl) void {
1524 // TODO make this logic match freeTextBlock. Maybe abstract the logic out since the same thing
1525 // is desired for both.
1526 const gpa = self.allocator;
1527 const fn_link = switch (self.bin_file.tag) {
1528 .elf => &decl.fn_link.elf,
1529 .macho => &decl.fn_link.macho,
1530 .wasm => &decl.fn_link.wasm.src_fn,
1531 else => unreachable,
1532 };
1533 _ = self.dbg_line_fn_free_list.remove(fn_link);
1549 if (self.di_atom_first_index == di_atom_index) {
1550 self.di_atom_first_index = di_atom.next_index;
1551 }
1552 if (self.di_atom_last_index == di_atom_index) {
1553 // TODO shrink the .debug_info section size here
1554 self.di_atom_last_index = di_atom.prev_index;
1555 }
15341556
1535 if (fn_link.prev) |prev| {
1536 self.dbg_line_fn_free_list.put(gpa, prev, {}) catch {};
1537 prev.next = fn_link.next;
1538 if (fn_link.next) |next| {
1539 next.prev = prev;
1557 if (di_atom.prev_index) |prev_index| {
1558 self.getAtomPtr(.di_atom, prev_index).next_index = di_atom.next_index;
1559 // TODO the free list logic like we do for SrcFn above
15401560 } else {
1541 self.dbg_line_fn_last = prev;
1561 di_atom.prev_index = null;
1562 }
1563
1564 if (di_atom.next_index) |next_index| {
1565 self.getAtomPtr(.di_atom, next_index).prev_index = di_atom.prev_index;
1566 } else {
1567 di_atom.next_index = null;
15421568 }
1543 } else if (fn_link.next) |next| {
1544 self.dbg_line_fn_first = next;
1545 next.prev = null;
1546 }
1547 if (self.dbg_line_fn_first == fn_link) {
1548 self.dbg_line_fn_first = fn_link.next;
1549 }
1550 if (self.dbg_line_fn_last == fn_link) {
1551 self.dbg_line_fn_last = fn_link.prev;
15521569 }
15531570}
15541571
......@@ -2276,10 +2293,14 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
22762293 const needed_with_padding = padToIdeal(needed_bytes);
22772294 const delta = needed_with_padding - dbg_line_prg_off;
22782295
2279 var src_fn = self.dbg_line_fn_first.?;
2280 const last_fn = self.dbg_line_fn_last.?;
2296 const first_fn_index = self.src_fn_first_index.?;
2297 const first_fn = self.getAtom(.src_fn, first_fn_index);
2298 const last_fn_index = self.src_fn_last_index.?;
2299 const last_fn = self.getAtom(.src_fn, last_fn_index);
2300
2301 var src_fn_index = first_fn_index;
22812302
2282 var buffer = try gpa.alloc(u8, last_fn.off + last_fn.len - src_fn.off);
2303 var buffer = try gpa.alloc(u8, last_fn.off + last_fn.len - first_fn.off);
22832304 defer gpa.free(buffer);
22842305
22852306 switch (self.bin_file.tag) {
......@@ -2288,7 +2309,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
22882309 const shdr_index = elf_file.debug_line_section_index.?;
22892310 const needed_size = elf_file.sections.items(.shdr)[shdr_index].sh_size + delta;
22902311 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
2291 const file_pos = elf_file.sections.items(.shdr)[shdr_index].sh_offset + src_fn.off;
2312 const file_pos = elf_file.sections.items(.shdr)[shdr_index].sh_offset + first_fn.off;
22922313
22932314 const amt = try elf_file.base.file.?.preadAll(buffer, file_pos);
22942315 if (amt != buffer.len) return error.InputOutput;
......@@ -2300,7 +2321,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
23002321 const sect_index = d_sym.debug_line_section_index.?;
23012322 const needed_size = @intCast(u32, d_sym.getSection(sect_index).size + delta);
23022323 try d_sym.growSection(sect_index, needed_size, true);
2303 const file_pos = d_sym.getSection(sect_index).offset + src_fn.off;
2324 const file_pos = d_sym.getSection(sect_index).offset + first_fn.off;
23042325
23052326 const amt = try d_sym.file.preadAll(buffer, file_pos);
23062327 if (amt != buffer.len) return error.InputOutput;
......@@ -2310,18 +2331,19 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
23102331 .wasm => {
23112332 const wasm_file = self.bin_file.cast(File.Wasm).?;
23122333 const debug_line = &wasm_file.debug_line_atom.?.code;
2313 mem.copy(u8, buffer, debug_line.items[src_fn.off..]);
2334 mem.copy(u8, buffer, debug_line.items[first_fn.off..]);
23142335 try debug_line.resize(self.allocator, debug_line.items.len + delta);
2315 mem.copy(u8, debug_line.items[src_fn.off + delta ..], buffer);
2336 mem.copy(u8, debug_line.items[first_fn.off + delta ..], buffer);
23162337 },
23172338 else => unreachable,
23182339 }
23192340
23202341 while (true) {
2342 const src_fn = self.getAtomPtr(.src_fn, src_fn_index);
23212343 src_fn.off += delta;
23222344
2323 if (src_fn.next) |next| {
2324 src_fn = next;
2345 if (src_fn.next_index) |next_index| {
2346 src_fn_index = next_index;
23252347 } else break;
23262348 }
23272349 }
......@@ -2367,22 +2389,26 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
23672389}
23682390
23692391fn getDebugInfoOff(self: Dwarf) ?u32 {
2370 const first = self.atom_first orelse return null;
2392 const first_index = self.di_atom_first_index orelse return null;
2393 const first = self.getAtom(.di_atom, first_index);
23712394 return first.off;
23722395}
23732396
23742397fn getDebugInfoEnd(self: Dwarf) ?u32 {
2375 const last = self.atom_last orelse return null;
2398 const last_index = self.di_atom_last_index orelse return null;
2399 const last = self.getAtom(.di_atom, last_index);
23762400 return last.off + last.len;
23772401}
23782402
23792403fn getDebugLineProgramOff(self: Dwarf) ?u32 {
2380 const first = self.dbg_line_fn_first orelse return null;
2404 const first_index = self.src_fn_first_index orelse return null;
2405 const first = self.getAtom(.src_fn, first_index);
23812406 return first.off;
23822407}
23832408
23842409fn getDebugLineProgramEnd(self: Dwarf) ?u32 {
2385 const last = self.dbg_line_fn_last orelse return null;
2410 const last_index = self.src_fn_last_index orelse return null;
2411 const last = self.getAtom(.src_fn, last_index);
23862412 return last.off + last.len;
23872413}
23882414
......@@ -2457,23 +2483,14 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
24572483 }
24582484 error_set.names = names;
24592485
2460 const atom = try gpa.create(Atom);
2461 errdefer gpa.destroy(atom);
2462 atom.* = .{
2463 .prev = null,
2464 .next = null,
2465 .off = 0,
2466 .len = 0,
2467 };
2468
24692486 var dbg_info_buffer = std.ArrayList(u8).init(arena);
24702487 try addDbgInfoErrorSet(arena, module, error_ty, self.target, &dbg_info_buffer);
24712488
2472 try self.managed_atoms.append(gpa, atom);
2489 const di_atom_index = try self.createAtom(.di_atom);
24732490 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});
2474 try self.updateDeclDebugInfoAllocation(atom, @intCast(u32, dbg_info_buffer.items.len));
2491 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(u32, dbg_info_buffer.items.len));
24752492 log.debug("writeDeclDebugInfo in flushModule", .{});
2476 try self.writeDeclDebugInfo(atom, dbg_info_buffer.items);
2493 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);
24772494
24782495 const file_pos = blk: {
24792496 switch (self.bin_file.tag) {
......@@ -2494,22 +2511,23 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
24942511 };
24952512
24962513 var buf: [@sizeOf(u32)]u8 = undefined;
2497 mem.writeInt(u32, &buf, atom.off, self.target.cpu.arch.endian());
2514 mem.writeInt(u32, &buf, self.getAtom(.di_atom, di_atom_index).off, self.target.cpu.arch.endian());
24982515
24992516 while (self.global_abbrev_relocs.popOrNull()) |reloc| {
2517 const atom = self.getAtom(.di_atom, reloc.atom_index);
25002518 switch (self.bin_file.tag) {
25012519 .elf => {
25022520 const elf_file = self.bin_file.cast(File.Elf).?;
2503 try elf_file.base.file.?.pwriteAll(&buf, file_pos + reloc.atom.off + reloc.offset);
2521 try elf_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
25042522 },
25052523 .macho => {
25062524 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
2507 try d_sym.file.pwriteAll(&buf, file_pos + reloc.atom.off + reloc.offset);
2525 try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
25082526 },
25092527 .wasm => {
25102528 const wasm_file = self.bin_file.cast(File.Wasm).?;
25112529 const debug_info = wasm_file.debug_info_atom.?.code;
2512 mem.copy(u8, debug_info.items[reloc.atom.off + reloc.offset ..], &buf);
2530 mem.copy(u8, debug_info.items[atom.off + reloc.offset ..], &buf);
25132531 },
25142532 else => unreachable,
25152533 }
......@@ -2627,12 +2645,62 @@ fn addDbgInfoErrorSet(
26272645 try dbg_info_buffer.append(0);
26282646}
26292647
2630fn getDbgInfoAtom(tag: File.Tag, mod: *Module, decl_index: Module.Decl.Index) *Atom {
2631 const decl = mod.declPtr(decl_index);
2632 return switch (tag) {
2633 .elf => unreachable,
2634 .macho => unreachable,
2635 .wasm => &decl.link.wasm.dbg_info_atom,
2636 else => unreachable,
2648const Kind = enum { src_fn, di_atom };
2649
2650fn createAtom(self: *Dwarf, comptime kind: Kind) !Atom.Index {
2651 const index = blk: {
2652 switch (kind) {
2653 .src_fn => {
2654 const index = @intCast(Atom.Index, self.src_fns.items.len);
2655 _ = try self.src_fns.addOne(self.allocator);
2656 break :blk index;
2657 },
2658 .di_atom => {
2659 const index = @intCast(Atom.Index, self.di_atoms.items.len);
2660 _ = try self.di_atoms.addOne(self.allocator);
2661 break :blk index;
2662 },
2663 }
2664 };
2665 const atom = self.getAtomPtr(kind, index);
2666 atom.* = .{
2667 .off = 0,
2668 .len = 0,
2669 .prev_index = null,
2670 .next_index = null,
2671 };
2672 return index;
2673}
2674
2675fn getOrCreateAtomForDecl(self: *Dwarf, comptime kind: Kind, decl_index: Module.Decl.Index) !Atom.Index {
2676 switch (kind) {
2677 .src_fn => {
2678 const gop = try self.src_fn_decls.getOrPut(self.allocator, decl_index);
2679 if (!gop.found_existing) {
2680 gop.value_ptr.* = try self.createAtom(kind);
2681 }
2682 return gop.value_ptr.*;
2683 },
2684 .di_atom => {
2685 const gop = try self.di_atom_decls.getOrPut(self.allocator, decl_index);
2686 if (!gop.found_existing) {
2687 gop.value_ptr.* = try self.createAtom(kind);
2688 }
2689 return gop.value_ptr.*;
2690 },
2691 }
2692}
2693
2694fn getAtom(self: *const Dwarf, comptime kind: Kind, index: Atom.Index) Atom {
2695 return switch (kind) {
2696 .src_fn => self.src_fns.items[index],
2697 .di_atom => self.di_atoms.items[index],
2698 };
2699}
2700
2701fn getAtomPtr(self: *Dwarf, comptime kind: Kind, index: Atom.Index) *Atom {
2702 return switch (kind) {
2703 .src_fn => &self.src_fns.items[index],
2704 .di_atom => &self.di_atoms.items[index],
26372705 };
26382706}
src/link/Elf.zig+267-275
......@@ -344,9 +344,9 @@ pub fn deinit(self: *Elf) void {
344344 self.relocs.deinit(gpa);
345345 }
346346
347 // if (self.dwarf) |*dw| {
348 // dw.deinit();
349 // }
347 if (self.dwarf) |*dw| {
348 dw.deinit();
349 }
350350}
351351
352352pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: File.RelocInfo) !u64 {
......@@ -685,146 +685,146 @@ pub fn populateMissingMetadata(self: *Elf) !void {
685685 try self.writeSymbol(0);
686686 }
687687
688 // if (self.dwarf) |*dw| {
689 // if (self.debug_str_section_index == null) {
690 // self.debug_str_section_index = @intCast(u16, self.sections.slice().len);
691 // assert(dw.strtab.buffer.items.len == 0);
692 // try dw.strtab.buffer.append(gpa, 0);
693 // try self.sections.append(gpa, .{
694 // .shdr = .{
695 // .sh_name = try self.shstrtab.insert(gpa, ".debug_str"),
696 // .sh_type = elf.SHT_PROGBITS,
697 // .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS,
698 // .sh_addr = 0,
699 // .sh_offset = 0,
700 // .sh_size = 0,
701 // .sh_link = 0,
702 // .sh_info = 0,
703 // .sh_addralign = 1,
704 // .sh_entsize = 1,
705 // },
706 // .phdr_index = undefined,
707 // });
708 // self.debug_strtab_dirty = true;
709 // self.shdr_table_dirty = true;
710 // }
711
712 // if (self.debug_info_section_index == null) {
713 // self.debug_info_section_index = @intCast(u16, self.sections.slice().len);
714
715 // const file_size_hint = 200;
716 // const p_align = 1;
717 // const off = self.findFreeSpace(file_size_hint, p_align);
718 // log.debug("found .debug_info free space 0x{x} to 0x{x}", .{
719 // off,
720 // off + file_size_hint,
721 // });
722 // try self.sections.append(gpa, .{
723 // .shdr = .{
724 // .sh_name = try self.shstrtab.insert(gpa, ".debug_info"),
725 // .sh_type = elf.SHT_PROGBITS,
726 // .sh_flags = 0,
727 // .sh_addr = 0,
728 // .sh_offset = off,
729 // .sh_size = file_size_hint,
730 // .sh_link = 0,
731 // .sh_info = 0,
732 // .sh_addralign = p_align,
733 // .sh_entsize = 0,
734 // },
735 // .phdr_index = undefined,
736 // });
737 // self.shdr_table_dirty = true;
738 // self.debug_info_header_dirty = true;
739 // }
740
741 // if (self.debug_abbrev_section_index == null) {
742 // self.debug_abbrev_section_index = @intCast(u16, self.sections.slice().len);
743
744 // const file_size_hint = 128;
745 // const p_align = 1;
746 // const off = self.findFreeSpace(file_size_hint, p_align);
747 // log.debug("found .debug_abbrev free space 0x{x} to 0x{x}", .{
748 // off,
749 // off + file_size_hint,
750 // });
751 // try self.sections.append(gpa, .{
752 // .shdr = .{
753 // .sh_name = try self.shstrtab.insert(gpa, ".debug_abbrev"),
754 // .sh_type = elf.SHT_PROGBITS,
755 // .sh_flags = 0,
756 // .sh_addr = 0,
757 // .sh_offset = off,
758 // .sh_size = file_size_hint,
759 // .sh_link = 0,
760 // .sh_info = 0,
761 // .sh_addralign = p_align,
762 // .sh_entsize = 0,
763 // },
764 // .phdr_index = undefined,
765 // });
766 // self.shdr_table_dirty = true;
767 // self.debug_abbrev_section_dirty = true;
768 // }
769
770 // if (self.debug_aranges_section_index == null) {
771 // self.debug_aranges_section_index = @intCast(u16, self.sections.slice().len);
772
773 // const file_size_hint = 160;
774 // const p_align = 16;
775 // const off = self.findFreeSpace(file_size_hint, p_align);
776 // log.debug("found .debug_aranges free space 0x{x} to 0x{x}", .{
777 // off,
778 // off + file_size_hint,
779 // });
780 // try self.sections.append(gpa, .{
781 // .shdr = .{
782 // .sh_name = try self.shstrtab.insert(gpa, ".debug_aranges"),
783 // .sh_type = elf.SHT_PROGBITS,
784 // .sh_flags = 0,
785 // .sh_addr = 0,
786 // .sh_offset = off,
787 // .sh_size = file_size_hint,
788 // .sh_link = 0,
789 // .sh_info = 0,
790 // .sh_addralign = p_align,
791 // .sh_entsize = 0,
792 // },
793 // .phdr_index = undefined,
794 // });
795 // self.shdr_table_dirty = true;
796 // self.debug_aranges_section_dirty = true;
797 // }
798
799 // if (self.debug_line_section_index == null) {
800 // self.debug_line_section_index = @intCast(u16, self.sections.slice().len);
801
802 // const file_size_hint = 250;
803 // const p_align = 1;
804 // const off = self.findFreeSpace(file_size_hint, p_align);
805 // log.debug("found .debug_line free space 0x{x} to 0x{x}", .{
806 // off,
807 // off + file_size_hint,
808 // });
809 // try self.sections.append(gpa, .{
810 // .shdr = .{
811 // .sh_name = try self.shstrtab.insert(gpa, ".debug_line"),
812 // .sh_type = elf.SHT_PROGBITS,
813 // .sh_flags = 0,
814 // .sh_addr = 0,
815 // .sh_offset = off,
816 // .sh_size = file_size_hint,
817 // .sh_link = 0,
818 // .sh_info = 0,
819 // .sh_addralign = p_align,
820 // .sh_entsize = 0,
821 // },
822 // .phdr_index = undefined,
823 // });
824 // self.shdr_table_dirty = true;
825 // self.debug_line_header_dirty = true;
826 // }
827 // }
688 if (self.dwarf) |*dw| {
689 if (self.debug_str_section_index == null) {
690 self.debug_str_section_index = @intCast(u16, self.sections.slice().len);
691 assert(dw.strtab.buffer.items.len == 0);
692 try dw.strtab.buffer.append(gpa, 0);
693 try self.sections.append(gpa, .{
694 .shdr = .{
695 .sh_name = try self.shstrtab.insert(gpa, ".debug_str"),
696 .sh_type = elf.SHT_PROGBITS,
697 .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS,
698 .sh_addr = 0,
699 .sh_offset = 0,
700 .sh_size = 0,
701 .sh_link = 0,
702 .sh_info = 0,
703 .sh_addralign = 1,
704 .sh_entsize = 1,
705 },
706 .phdr_index = undefined,
707 });
708 self.debug_strtab_dirty = true;
709 self.shdr_table_dirty = true;
710 }
711
712 if (self.debug_info_section_index == null) {
713 self.debug_info_section_index = @intCast(u16, self.sections.slice().len);
714
715 const file_size_hint = 200;
716 const p_align = 1;
717 const off = self.findFreeSpace(file_size_hint, p_align);
718 log.debug("found .debug_info free space 0x{x} to 0x{x}", .{
719 off,
720 off + file_size_hint,
721 });
722 try self.sections.append(gpa, .{
723 .shdr = .{
724 .sh_name = try self.shstrtab.insert(gpa, ".debug_info"),
725 .sh_type = elf.SHT_PROGBITS,
726 .sh_flags = 0,
727 .sh_addr = 0,
728 .sh_offset = off,
729 .sh_size = file_size_hint,
730 .sh_link = 0,
731 .sh_info = 0,
732 .sh_addralign = p_align,
733 .sh_entsize = 0,
734 },
735 .phdr_index = undefined,
736 });
737 self.shdr_table_dirty = true;
738 self.debug_info_header_dirty = true;
739 }
740
741 if (self.debug_abbrev_section_index == null) {
742 self.debug_abbrev_section_index = @intCast(u16, self.sections.slice().len);
743
744 const file_size_hint = 128;
745 const p_align = 1;
746 const off = self.findFreeSpace(file_size_hint, p_align);
747 log.debug("found .debug_abbrev free space 0x{x} to 0x{x}", .{
748 off,
749 off + file_size_hint,
750 });
751 try self.sections.append(gpa, .{
752 .shdr = .{
753 .sh_name = try self.shstrtab.insert(gpa, ".debug_abbrev"),
754 .sh_type = elf.SHT_PROGBITS,
755 .sh_flags = 0,
756 .sh_addr = 0,
757 .sh_offset = off,
758 .sh_size = file_size_hint,
759 .sh_link = 0,
760 .sh_info = 0,
761 .sh_addralign = p_align,
762 .sh_entsize = 0,
763 },
764 .phdr_index = undefined,
765 });
766 self.shdr_table_dirty = true;
767 self.debug_abbrev_section_dirty = true;
768 }
769
770 if (self.debug_aranges_section_index == null) {
771 self.debug_aranges_section_index = @intCast(u16, self.sections.slice().len);
772
773 const file_size_hint = 160;
774 const p_align = 16;
775 const off = self.findFreeSpace(file_size_hint, p_align);
776 log.debug("found .debug_aranges free space 0x{x} to 0x{x}", .{
777 off,
778 off + file_size_hint,
779 });
780 try self.sections.append(gpa, .{
781 .shdr = .{
782 .sh_name = try self.shstrtab.insert(gpa, ".debug_aranges"),
783 .sh_type = elf.SHT_PROGBITS,
784 .sh_flags = 0,
785 .sh_addr = 0,
786 .sh_offset = off,
787 .sh_size = file_size_hint,
788 .sh_link = 0,
789 .sh_info = 0,
790 .sh_addralign = p_align,
791 .sh_entsize = 0,
792 },
793 .phdr_index = undefined,
794 });
795 self.shdr_table_dirty = true;
796 self.debug_aranges_section_dirty = true;
797 }
798
799 if (self.debug_line_section_index == null) {
800 self.debug_line_section_index = @intCast(u16, self.sections.slice().len);
801
802 const file_size_hint = 250;
803 const p_align = 1;
804 const off = self.findFreeSpace(file_size_hint, p_align);
805 log.debug("found .debug_line free space 0x{x} to 0x{x}", .{
806 off,
807 off + file_size_hint,
808 });
809 try self.sections.append(gpa, .{
810 .shdr = .{
811 .sh_name = try self.shstrtab.insert(gpa, ".debug_line"),
812 .sh_type = elf.SHT_PROGBITS,
813 .sh_flags = 0,
814 .sh_addr = 0,
815 .sh_offset = off,
816 .sh_size = file_size_hint,
817 .sh_link = 0,
818 .sh_info = 0,
819 .sh_addralign = p_align,
820 .sh_entsize = 0,
821 },
822 .phdr_index = undefined,
823 });
824 self.shdr_table_dirty = true;
825 self.debug_line_header_dirty = true;
826 }
827 }
828828
829829 const shsize: u64 = switch (self.ptr_width) {
830830 .p32 => @sizeOf(elf.Elf32_Shdr),
......@@ -956,26 +956,25 @@ pub fn growNonAllocSection(
956956}
957957
958958pub fn markDirty(self: *Elf, shdr_index: u16, phdr_index: ?u16) void {
959 _ = shdr_index;
960959 self.shdr_table_dirty = true; // TODO look into only writing one section
961960
962961 if (phdr_index) |_| {
963962 self.phdr_table_dirty = true; // TODO look into making only the one program header dirty
964963 }
965964
966 // if (self.dwarf) |_| {
967 // if (self.debug_info_section_index.? == shdr_index) {
968 // self.debug_info_header_dirty = true;
969 // } else if (self.debug_line_section_index.? == shdr_index) {
970 // self.debug_line_header_dirty = true;
971 // } else if (self.debug_abbrev_section_index.? == shdr_index) {
972 // self.debug_abbrev_section_dirty = true;
973 // } else if (self.debug_str_section_index.? == shdr_index) {
974 // self.debug_strtab_dirty = true;
975 // } else if (self.debug_aranges_section_index.? == shdr_index) {
976 // self.debug_aranges_section_dirty = true;
977 // }
978 // }
965 if (self.dwarf) |_| {
966 if (self.debug_info_section_index.? == shdr_index) {
967 self.debug_info_header_dirty = true;
968 } else if (self.debug_line_section_index.? == shdr_index) {
969 self.debug_line_header_dirty = true;
970 } else if (self.debug_abbrev_section_index.? == shdr_index) {
971 self.debug_abbrev_section_dirty = true;
972 } else if (self.debug_str_section_index.? == shdr_index) {
973 self.debug_strtab_dirty = true;
974 } else if (self.debug_aranges_section_index.? == shdr_index) {
975 self.debug_aranges_section_dirty = true;
976 }
977 }
979978}
980979
981980pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
......@@ -1015,14 +1014,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10151014 // TODO This linker code currently assumes there is only 1 compilation unit and it
10161015 // corresponds to the Zig source code.
10171016 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
1018 _ = module;
10191017
10201018 const target_endian = self.base.options.target.cpu.arch.endian();
10211019 const foreign_endian = target_endian != builtin.cpu.arch.endian();
10221020
1023 // if (self.dwarf) |*dw| {
1024 // try dw.flushModule(module);
1025 // }
1021 if (self.dwarf) |*dw| {
1022 try dw.flushModule(module);
1023 }
10261024
10271025 {
10281026 var it = self.relocs.iterator();
......@@ -1068,43 +1066,43 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10681066 self.logSymtab();
10691067 }
10701068
1071 // if (self.dwarf) |*dw| {
1072 // if (self.debug_abbrev_section_dirty) {
1073 // try dw.writeDbgAbbrev();
1074 // if (!self.shdr_table_dirty) {
1075 // // Then it won't get written with the others and we need to do it.
1076 // try self.writeSectHeader(self.debug_abbrev_section_index.?);
1077 // }
1078 // self.debug_abbrev_section_dirty = false;
1079 // }
1080
1081 // if (self.debug_info_header_dirty) {
1082 // // Currently only one compilation unit is supported, so the address range is simply
1083 // // identical to the main program header virtual address and memory size.
1084 // const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?];
1085 // const low_pc = text_phdr.p_vaddr;
1086 // const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;
1087 // try dw.writeDbgInfoHeader(module, low_pc, high_pc);
1088 // self.debug_info_header_dirty = false;
1089 // }
1090
1091 // if (self.debug_aranges_section_dirty) {
1092 // // Currently only one compilation unit is supported, so the address range is simply
1093 // // identical to the main program header virtual address and memory size.
1094 // const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?];
1095 // try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz);
1096 // if (!self.shdr_table_dirty) {
1097 // // Then it won't get written with the others and we need to do it.
1098 // try self.writeSectHeader(self.debug_aranges_section_index.?);
1099 // }
1100 // self.debug_aranges_section_dirty = false;
1101 // }
1102
1103 // if (self.debug_line_header_dirty) {
1104 // try dw.writeDbgLineHeader();
1105 // self.debug_line_header_dirty = false;
1106 // }
1107 // }
1069 if (self.dwarf) |*dw| {
1070 if (self.debug_abbrev_section_dirty) {
1071 try dw.writeDbgAbbrev();
1072 if (!self.shdr_table_dirty) {
1073 // Then it won't get written with the others and we need to do it.
1074 try self.writeSectHeader(self.debug_abbrev_section_index.?);
1075 }
1076 self.debug_abbrev_section_dirty = false;
1077 }
1078
1079 if (self.debug_info_header_dirty) {
1080 // Currently only one compilation unit is supported, so the address range is simply
1081 // identical to the main program header virtual address and memory size.
1082 const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?];
1083 const low_pc = text_phdr.p_vaddr;
1084 const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;
1085 try dw.writeDbgInfoHeader(module, low_pc, high_pc);
1086 self.debug_info_header_dirty = false;
1087 }
1088
1089 if (self.debug_aranges_section_dirty) {
1090 // Currently only one compilation unit is supported, so the address range is simply
1091 // identical to the main program header virtual address and memory size.
1092 const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?];
1093 try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz);
1094 if (!self.shdr_table_dirty) {
1095 // Then it won't get written with the others and we need to do it.
1096 try self.writeSectHeader(self.debug_aranges_section_index.?);
1097 }
1098 self.debug_aranges_section_dirty = false;
1099 }
1100
1101 if (self.debug_line_header_dirty) {
1102 try dw.writeDbgLineHeader();
1103 self.debug_line_header_dirty = false;
1104 }
1105 }
11081106
11091107 if (self.phdr_table_dirty) {
11101108 const phsize: u64 = switch (self.ptr_width) {
......@@ -1162,15 +1160,15 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11621160 }
11631161 }
11641162
1165 // if (self.dwarf) |dwarf| {
1166 // const shdr_index = self.debug_str_section_index.?;
1167 // if (self.debug_strtab_dirty or dwarf.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) {
1168 // try self.growNonAllocSection(shdr_index, dwarf.strtab.buffer.items.len, 1, false);
1169 // const debug_strtab_sect = self.sections.items(.shdr)[shdr_index];
1170 // try self.base.file.?.pwriteAll(dwarf.strtab.buffer.items, debug_strtab_sect.sh_offset);
1171 // self.debug_strtab_dirty = false;
1172 // }
1173 // }
1163 if (self.dwarf) |dwarf| {
1164 const shdr_index = self.debug_str_section_index.?;
1165 if (self.debug_strtab_dirty or dwarf.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) {
1166 try self.growNonAllocSection(shdr_index, dwarf.strtab.buffer.items.len, 1, false);
1167 const debug_strtab_sect = self.sections.items(.shdr)[shdr_index];
1168 try self.base.file.?.pwriteAll(dwarf.strtab.buffer.items, debug_strtab_sect.sh_offset);
1169 self.debug_strtab_dirty = false;
1170 }
1171 }
11741172
11751173 if (self.shdr_table_dirty) {
11761174 const shsize: u64 = switch (self.ptr_width) {
......@@ -2100,10 +2098,6 @@ fn freeAtom(self: *Elf, atom_index: Atom.Index) void {
21002098 self.getAtomPtr(atom_index).local_sym_index = 0;
21012099
21022100 self.offset_table_free_list.append(self.base.allocator, atom.offset_table_index) catch {};
2103
2104 // if (self.dwarf) |*dw| {
2105 // dw.freeAtom(&atom.dbg_info_atom);
2106 // }
21072101}
21082102
21092103fn shrinkAtom(self: *Elf, atom_index: Atom.Index, new_block_size: u64) void {
......@@ -2133,7 +2127,6 @@ pub fn createAtom(self: *Elf) !Atom.Index {
21332127 .offset_table_index = offset_table_index,
21342128 .prev_index = null,
21352129 .next_index = null,
2136 .dbg_info_atom = undefined,
21372130 };
21382131 log.debug("creating ATOM(%{d}) at index {d}", .{ local_sym_index, atom_index });
21392132 return atom_index;
......@@ -2219,16 +2212,16 @@ fn allocateAtom(self: *Elf, atom_index: Atom.Index, new_block_size: u64, alignme
22192212 try self.growAllocSection(sym.st_shndx, needed_size);
22202213 maybe_last_atom_index.* = atom_index;
22212214
2222 // if (self.dwarf) |_| {
2223 // // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address
2224 // // range of the compilation unit. When we expand the text section, this range changes,
2225 // // so the DW_TAG.compile_unit tag of the .debug_info section becomes dirty.
2226 // self.debug_info_header_dirty = true;
2227 // // This becomes dirty for the same reason. We could potentially make this more
2228 // // fine-grained with the addition of support for more compilation units. It is planned to
2229 // // model each package as a different compilation unit.
2230 // self.debug_aranges_section_dirty = true;
2231 // }
2215 if (self.dwarf) |_| {
2216 // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address
2217 // range of the compilation unit. When we expand the text section, this range changes,
2218 // so the DW_TAG.compile_unit tag of the .debug_info section becomes dirty.
2219 self.debug_info_header_dirty = true;
2220 // This becomes dirty for the same reason. We could potentially make this more
2221 // fine-grained with the addition of support for more compilation units. It is planned to
2222 // model each package as a different compilation unit.
2223 self.debug_aranges_section_dirty = true;
2224 }
22322225 }
22332226 shdr.sh_addralign = math.max(shdr.sh_addralign, alignment);
22342227
......@@ -2333,9 +2326,9 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
23332326 kv.value.exports.deinit(self.base.allocator);
23342327 }
23352328
2336 // if (self.dwarf) |*dw| {
2337 // dw.freeDecl(decl);
2338 // }
2329 if (self.dwarf) |*dw| {
2330 dw.freeDecl(decl_index);
2331 }
23392332}
23402333
23412334pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index {
......@@ -2471,15 +2464,15 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
24712464 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
24722465 defer code_buffer.deinit();
24732466
2474 // var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(module, decl_index) else null;
2475 // defer if (decl_state) |*ds| ds.deinit();
2467 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(module, decl_index) else null;
2468 defer if (decl_state) |*ds| ds.deinit();
24762469
2477 // const res = if (decl_state) |*ds|
2478 // try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
2479 // .dwarf = ds,
2480 // })
2481 // else
2482 const res = try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none);
2470 const res = if (decl_state) |*ds|
2471 try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
2472 .dwarf = ds,
2473 })
2474 else
2475 try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none);
24832476
24842477 const code = switch (res) {
24852478 .ok => code_buffer.items,
......@@ -2490,16 +2483,15 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
24902483 },
24912484 };
24922485 const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_FUNC);
2493 _ = local_sym;
2494 // if (decl_state) |*ds| {
2495 // try self.dwarf.?.commitDeclState(
2496 // module,
2497 // decl_index,
2498 // local_sym.st_value,
2499 // local_sym.st_size,
2500 // ds,
2501 // );
2502 // }
2486 if (decl_state) |*ds| {
2487 try self.dwarf.?.commitDeclState(
2488 module,
2489 decl_index,
2490 local_sym.st_value,
2491 local_sym.st_size,
2492 ds,
2493 );
2494 }
25032495
25042496 // Since we updated the vaddr and the size, each corresponding export
25052497 // symbol also needs to be updated.
......@@ -2536,27 +2528,27 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v
25362528 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
25372529 defer code_buffer.deinit();
25382530
2539 // var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(module, decl_index) else null;
2540 // defer if (decl_state) |*ds| ds.deinit();
2531 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(module, decl_index) else null;
2532 defer if (decl_state) |*ds| ds.deinit();
25412533
25422534 // TODO implement .debug_info for global variables
25432535 const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
2544 // const res = if (decl_state) |*ds|
2545 // try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2546 // .ty = decl.ty,
2547 // .val = decl_val,
2548 // }, &code_buffer, .{
2549 // .dwarf = ds,
2550 // }, .{
2551 // .parent_atom_index = atom.getSymbolIndex().?,
2552 // })
2553 // else
2554 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2555 .ty = decl.ty,
2556 .val = decl_val,
2557 }, &code_buffer, .none, .{
2558 .parent_atom_index = atom.getSymbolIndex().?,
2559 });
2536 const res = if (decl_state) |*ds|
2537 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2538 .ty = decl.ty,
2539 .val = decl_val,
2540 }, &code_buffer, .{
2541 .dwarf = ds,
2542 }, .{
2543 .parent_atom_index = atom.getSymbolIndex().?,
2544 })
2545 else
2546 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2547 .ty = decl.ty,
2548 .val = decl_val,
2549 }, &code_buffer, .none, .{
2550 .parent_atom_index = atom.getSymbolIndex().?,
2551 });
25602552
25612553 const code = switch (res) {
25622554 .ok => code_buffer.items,
......@@ -2568,16 +2560,15 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v
25682560 };
25692561
25702562 const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_OBJECT);
2571 _ = local_sym;
2572 // if (decl_state) |*ds| {
2573 // try self.dwarf.?.commitDeclState(
2574 // module,
2575 // decl_index,
2576 // local_sym.st_value,
2577 // local_sym.st_size,
2578 // ds,
2579 // );
2580 // }
2563 if (decl_state) |*ds| {
2564 try self.dwarf.?.commitDeclState(
2565 module,
2566 decl_index,
2567 local_sym.st_value,
2568 local_sym.st_size,
2569 ds,
2570 );
2571 }
25812572
25822573 // Since we updated the vaddr and the size, each corresponding export
25832574 // symbol also needs to be updated.
......@@ -2737,19 +2728,20 @@ pub fn updateDeclExports(
27372728}
27382729
27392730/// Must be called only after a successful call to `updateDecl`.
2740pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl: *const Module.Decl) !void {
2731pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.Index) !void {
27412732 const tracy = trace(@src());
27422733 defer tracy.end();
27432734
2735 const decl = mod.declPtr(decl_index);
27442736 const decl_name = try decl.getFullyQualifiedName(mod);
27452737 defer self.base.allocator.free(decl_name);
27462738
27472739 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
27482740
27492741 if (self.llvm_object) |_| return;
2750 // if (self.dwarf) |*dw| {
2751 // try dw.updateDeclLineNumber(decl);
2752 // }
2742 if (self.dwarf) |*dw| {
2743 try dw.updateDeclLineNumber(mod, decl_index);
2744 }
27532745}
27542746
27552747pub fn deleteDeclExport(self: *Elf, decl_index: Module.Decl.Index, name: []const u8) void {
src/link/Elf/Atom.zig-3
......@@ -4,7 +4,6 @@ const std = @import("std");
44const assert = std.debug.assert;
55const elf = std.elf;
66
7const Dwarf = @import("../Dwarf.zig");
87const Elf = @import("../Elf.zig");
98
109/// Each decl always gets a local symbol with the fully qualified name.
......@@ -23,8 +22,6 @@ offset_table_index: u32,
2322prev_index: ?Index,
2423next_index: ?Index,
2524
26dbg_info_atom: Dwarf.Atom,
27
2825pub const Index = u32;
2926
3027pub const Reloc = struct {
src/link/MachO.zig+59-71
......@@ -472,9 +472,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
472472
473473 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
474474
475 // if (self.d_sym) |*d_sym| {
476 // try d_sym.dwarf.flushModule(module);
477 // }
475 if (self.d_sym) |*d_sym| {
476 try d_sym.dwarf.flushModule(module);
477 }
478478
479479 var libs = std.StringArrayHashMap(link.SystemLib).init(arena);
480480 try resolveLibSystem(
......@@ -664,10 +664,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
664664 try self.writeCodeSignature(comp, csig); // code signing always comes last
665665 }
666666
667 // if (self.d_sym) |*d_sym| {
668 // // Flush debug symbols bundle.
669 // try d_sym.flushModule(self);
670 // }
667 if (self.d_sym) |*d_sym| {
668 // Flush debug symbols bundle.
669 try d_sym.flushModule(self);
670 }
671671
672672 // if (build_options.enable_link_snapshots) {
673673 // if (self.base.options.enable_link_snapshots)
......@@ -1089,7 +1089,6 @@ pub fn createAtom(self: *MachO) !Atom.Index {
10891089 .alignment = 0,
10901090 .prev_index = null,
10911091 .next_index = null,
1092 .dbg_info_atom = undefined,
10931092 };
10941093 log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, atom_index });
10951094 return atom_index;
......@@ -1724,9 +1723,9 @@ pub fn deinit(self: *MachO) void {
17241723 if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa);
17251724 }
17261725
1727 // if (self.d_sym) |*d_sym| {
1728 // d_sym.deinit();
1729 // }
1726 if (self.d_sym) |*d_sym| {
1727 d_sym.deinit();
1728 }
17301729
17311730 self.got_entries.deinit(gpa);
17321731 self.got_entries_free_list.deinit(gpa);
......@@ -1804,9 +1803,8 @@ pub fn deinit(self: *MachO) void {
18041803}
18051804
18061805fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
1807 log.debug("freeAtom {d}", .{atom_index});
1808
18091806 const gpa = self.base.allocator;
1807 log.debug("freeAtom {d}", .{atom_index});
18101808
18111809 // Remove any relocs and base relocs associated with this Atom
18121810 Atom.freeRelocations(self, atom_index);
......@@ -1876,9 +1874,9 @@ fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
18761874 };
18771875 _ = self.got_entries_table.remove(got_target);
18781876
1879 // if (self.d_sym) |*d_sym| {
1880 // d_sym.swapRemoveRelocs(sym_index);
1881 // }
1877 if (self.d_sym) |*d_sym| {
1878 d_sym.swapRemoveRelocs(sym_index);
1879 }
18821880
18831881 log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index });
18841882 }
......@@ -1887,10 +1885,6 @@ fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
18871885 _ = self.atom_by_index_table.remove(sym_index);
18881886 log.debug(" adding local symbol index {d} to free list", .{sym_index});
18891887 self.getAtomPtr(atom_index).sym_index = 0;
1890
1891 // if (self.d_sym) |*d_sym| {
1892 // d_sym.dwarf.freeAtom(&atom.dbg_info_atom);
1893 // }
18941888}
18951889
18961890fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void {
......@@ -2020,23 +2014,22 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
20202014 Atom.freeRelocations(self, atom_index);
20212015
20222016 const atom = self.getAtom(atom_index);
2023 _ = atom;
20242017
20252018 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
20262019 defer code_buffer.deinit();
20272020
2028 // var decl_state = if (self.d_sym) |*d_sym|
2029 // try d_sym.dwarf.initDeclState(module, decl_index)
2030 // else
2031 // null;
2032 // defer if (decl_state) |*ds| ds.deinit();
2021 var decl_state = if (self.d_sym) |*d_sym|
2022 try d_sym.dwarf.initDeclState(module, decl_index)
2023 else
2024 null;
2025 defer if (decl_state) |*ds| ds.deinit();
20332026
2034 // const res = if (decl_state) |*ds|
2035 // try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
2036 // .dwarf = ds,
2037 // })
2038 // else
2039 const res = try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none);
2027 const res = if (decl_state) |*ds|
2028 try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
2029 .dwarf = ds,
2030 })
2031 else
2032 try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none);
20402033
20412034 const code = switch (res) {
20422035 .ok => code_buffer.items,
......@@ -2048,11 +2041,10 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
20482041 };
20492042
20502043 const addr = try self.updateDeclCode(decl_index, code);
2051 _ = addr;
20522044
2053 // if (decl_state) |*ds| {
2054 // try self.d_sym.?.dwarf.commitDeclState(module, decl_index, addr, atom.size, ds);
2055 // }
2045 if (decl_state) |*ds| {
2046 try self.d_sym.?.dwarf.commitDeclState(module, decl_index, addr, atom.size, ds);
2047 }
20562048
20572049 // Since we updated the vaddr and the size, each corresponding export symbol also
20582050 // needs to be updated.
......@@ -2154,29 +2146,29 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
21542146 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
21552147 defer code_buffer.deinit();
21562148
2157 // var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym|
2158 // try d_sym.dwarf.initDeclState(module, decl_index)
2159 // else
2160 // null;
2161 // defer if (decl_state) |*ds| ds.deinit();
2149 var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym|
2150 try d_sym.dwarf.initDeclState(module, decl_index)
2151 else
2152 null;
2153 defer if (decl_state) |*ds| ds.deinit();
21622154
21632155 const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
2164 // const res = if (decl_state) |*ds|
2165 // try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2166 // .ty = decl.ty,
2167 // .val = decl_val,
2168 // }, &code_buffer, .{
2169 // .dwarf = ds,
2170 // }, .{
2171 // .parent_atom_index = atom.getSymbolIndex().?,
2172 // })
2173 // else
2174 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2175 .ty = decl.ty,
2176 .val = decl_val,
2177 }, &code_buffer, .none, .{
2178 .parent_atom_index = atom.getSymbolIndex().?,
2179 });
2156 const res = if (decl_state) |*ds|
2157 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2158 .ty = decl.ty,
2159 .val = decl_val,
2160 }, &code_buffer, .{
2161 .dwarf = ds,
2162 }, .{
2163 .parent_atom_index = atom.getSymbolIndex().?,
2164 })
2165 else
2166 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2167 .ty = decl.ty,
2168 .val = decl_val,
2169 }, &code_buffer, .none, .{
2170 .parent_atom_index = atom.getSymbolIndex().?,
2171 });
21802172
21812173 const code = switch (res) {
21822174 .ok => code_buffer.items,
......@@ -2187,11 +2179,10 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
21872179 },
21882180 };
21892181 const addr = try self.updateDeclCode(decl_index, code);
2190 _ = addr;
21912182
2192 // if (decl_state) |*ds| {
2193 // try self.d_sym.?.dwarf.commitDeclState(module, decl_index, addr, atom.size, ds);
2194 // }
2183 if (decl_state) |*ds| {
2184 try self.d_sym.?.dwarf.commitDeclState(module, decl_index, addr, atom.size, ds);
2185 }
21952186
21962187 // Since we updated the vaddr and the size, each corresponding export symbol also
21972188 // needs to be updated.
......@@ -2432,13 +2423,10 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8)
24322423 return atom.getSymbol(self).n_value;
24332424}
24342425
2435pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void {
2436 _ = decl;
2437 _ = self;
2438 _ = module;
2439 // if (self.d_sym) |*d_sym| {
2440 // try d_sym.dwarf.updateDeclLineNumber(decl);
2441 // }
2426pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {
2427 if (self.d_sym) |*d_sym| {
2428 try d_sym.dwarf.updateDeclLineNumber(module, decl_index);
2429 }
24422430}
24432431
24442432pub fn updateDeclExports(
......@@ -2611,9 +2599,9 @@ pub fn freeDecl(self: *MachO, decl_index: Module.Decl.Index) void {
26112599 kv.value.exports.deinit(self.base.allocator);
26122600 }
26132601
2614 // if (self.d_sym) |*d_sym| {
2615 // d_sym.dwarf.freeDecl(decl);
2616 // }
2602 if (self.d_sym) |*d_sym| {
2603 d_sym.dwarf.freeDecl(decl_index);
2604 }
26172605}
26182606
26192607pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: File.RelocInfo) !u64 {
src/link/MachO/Atom.zig-3
......@@ -13,7 +13,6 @@ const trace = @import("../../tracy.zig").trace;
1313
1414const Allocator = mem.Allocator;
1515const Arch = std.Target.Cpu.Arch;
16const Dwarf = @import("../Dwarf.zig");
1716const MachO = @import("../MachO.zig");
1817const Relocation = @import("Relocation.zig");
1918const SymbolWithLoc = MachO.SymbolWithLoc;
......@@ -43,8 +42,6 @@ alignment: u32,
4342next_index: ?Index,
4443prev_index: ?Index,
4544
46dbg_info_atom: Dwarf.Atom,
47
4845pub const Index = u32;
4946
5047pub const Binding = struct {
src/link/Plan9.zig+2-2
......@@ -1018,10 +1018,10 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
10181018}
10191019
10201020/// Must be called only after a successful call to `updateDecl`.
1021pub fn updateDeclLineNumber(self: *Plan9, mod: *Module, decl: *const Module.Decl) !void {
1021pub fn updateDeclLineNumber(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !void {
10221022 _ = self;
10231023 _ = mod;
1024 _ = decl;
1024 _ = decl_index;
10251025}
10261026
10271027pub fn getDeclVAddr(
src/link/Wasm.zig+6-11
......@@ -183,13 +183,9 @@ pub const Segment = struct {
183183pub const FnData = struct {
184184 /// Reference to the wasm type that represents this function.
185185 type_index: u32,
186 /// Contains debug information related to this function.
187 /// For Wasm, the offset is relative to the code-section.
188 src_fn: Dwarf.SrcFn,
189186
190187 pub const empty: FnData = .{
191188 .type_index = undefined,
192 .src_fn = Dwarf.SrcFn.empty,
193189 };
194190};
195191
......@@ -1122,17 +1118,18 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi
11221118 return wasm.finishUpdateDecl(decl, code);
11231119}
11241120
1125pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl: *const Module.Decl) !void {
1121pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !void {
11261122 if (wasm.llvm_object) |_| return;
11271123 if (wasm.dwarf) |*dw| {
11281124 const tracy = trace(@src());
11291125 defer tracy.end();
11301126
1127 const decl = mod.declPtr(decl_index);
11311128 const decl_name = try decl.getFullyQualifiedName(mod);
11321129 defer wasm.base.allocator.free(decl_name);
11331130
11341131 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
1135 try dw.updateDeclLineNumber(decl);
1132 try dw.updateDeclLineNumber(mod, decl_index);
11361133 }
11371134}
11381135
......@@ -1460,10 +1457,9 @@ pub fn freeDecl(wasm: *Wasm, decl_index: Module.Decl.Index) void {
14601457 _ = wasm.resolved_symbols.swapRemove(atom.symbolLoc());
14611458 _ = wasm.symbol_atom.remove(atom.symbolLoc());
14621459
1463 if (wasm.dwarf) |*dwarf| {
1464 dwarf.freeDecl(decl);
1465 dwarf.freeAtom(&atom.dbg_info_atom);
1466 }
1460 // if (wasm.dwarf) |*dwarf| {
1461 // dwarf.freeDecl(decl_index);
1462 // }
14671463
14681464 atom.deinit(wasm.base.allocator);
14691465}
......@@ -1882,7 +1878,6 @@ fn initializeCallCtorsFunction(wasm: *Wasm) !void {
18821878 .next = null,
18831879 .prev = null,
18841880 .code = function_body.moveToUnmanaged(),
1885 .dbg_info_atom = undefined,
18861881 };
18871882 try wasm.managed_atoms.append(wasm.base.allocator, atom);
18881883 try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom);
src/link/Wasm/Atom.zig-5
......@@ -4,7 +4,6 @@ const std = @import("std");
44const types = @import("types.zig");
55const Wasm = @import("../Wasm.zig");
66const Symbol = @import("Symbol.zig");
7const Dwarf = @import("../Dwarf.zig");
87
98const leb = std.leb;
109const log = std.log.scoped(.link);
......@@ -39,9 +38,6 @@ prev: ?*Atom,
3938/// When the parent atom is being freed, it will also do so for all local atoms.
4039locals: std.ArrayListUnmanaged(Atom) = .{},
4140
42/// Represents the debug Atom that holds all debug information of this Atom.
43dbg_info_atom: Dwarf.Atom,
44
4541/// Represents a default empty wasm `Atom`
4642pub const empty: Atom = .{
4743 .alignment = 0,
......@@ -51,7 +47,6 @@ pub const empty: Atom = .{
5147 .prev = null,
5248 .size = 0,
5349 .sym_index = 0,
54 .dbg_info_atom = undefined,
5550};
5651
5752/// Frees all resources owned by this `Atom`.