authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-26 14:20:08+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-27 20:53:06+02:00
log1a80315836f77e38eee3e4c0a646b82febbc3604
tree74ea13fa37e13af5e4ade0f18d9f3ee7231bae3a
parentb4815b31310a36e3c1fabd83d010b44b693c9782

dwarf: rename DebugInfoAtom into Atom; free all allocated memory


3 files changed, 39 insertions(+), 30 deletions(-)

src/link/Dwarf.zig+37-28
...@@ -31,10 +31,11 @@ dbg_line_fn_free_list: std.AutoHashMapUnmanaged(*SrcFn, void) = .{},...@@ -31,10 +31,11 @@ dbg_line_fn_free_list: std.AutoHashMapUnmanaged(*SrcFn, void) = .{},
31dbg_line_fn_first: ?*SrcFn = null,31dbg_line_fn_first: ?*SrcFn = null,
32dbg_line_fn_last: ?*SrcFn = null,32dbg_line_fn_last: ?*SrcFn = null,
3333
34/// A list of `TextBlock` whose corresponding .debug_info tags have surplus capacity. /// This is the same concept as `text_block_free_list`; see those doc comments.34/// A list of `Atom`s whose corresponding .debug_info tags have surplus capacity.
35dbg_info_decl_free_list: std.AutoHashMapUnmanaged(*DebugInfoAtom, void) = .{},35/// This is the same concept as `text_block_free_list`; see those doc comments.
36dbg_info_decl_first: ?*DebugInfoAtom = null,36atom_free_list: std.AutoHashMapUnmanaged(*Atom, void) = .{},
37dbg_info_decl_last: ?*DebugInfoAtom = null,37atom_first: ?*Atom = null,
38atom_last: ?*Atom = null,
3839
39abbrev_table_offset: ?u64 = null,40abbrev_table_offset: ?u64 = null,
4041
...@@ -43,11 +44,16 @@ strtab: std.ArrayListUnmanaged(u8) = .{},...@@ -43,11 +44,16 @@ strtab: std.ArrayListUnmanaged(u8) = .{},
4344
44deferred_error_sets_relocs: std.ArrayListUnmanaged(u32) = .{},45deferred_error_sets_relocs: std.ArrayListUnmanaged(u32) = .{},
4546
46pub const DebugInfoAtom = struct {47/// List of atoms that are owned directly by the DWARF module.
48/// TODO convert links in DebugInfoAtom into indices and make
49/// sure every atom is owned by this module.
50managed_atoms: std.ArrayListUnmanaged(*Atom) = .{},
51
52pub const Atom = struct {
47 /// Previous/next linked list pointers.53 /// Previous/next linked list pointers.
48 /// This is the linked list node for this Decl's corresponding .debug_info tag.54 /// This is the linked list node for this Decl's corresponding .debug_info tag.
49 prev: ?*DebugInfoAtom,55 prev: ?*Atom,
50 next: ?*DebugInfoAtom,56 next: ?*Atom,
51 /// Offset into .debug_info pointing to the tag for this Decl.57 /// Offset into .debug_info pointing to the tag for this Decl.
52 off: u32,58 off: u32,
53 /// Size of the .debug_info tag for this Decl, not including padding.59 /// Size of the .debug_info tag for this Decl, not including padding.
...@@ -119,9 +125,14 @@ pub fn init(allocator: Allocator, tag: File.Tag, target: std.Target) Dwarf {...@@ -119,9 +125,14 @@ pub fn init(allocator: Allocator, tag: File.Tag, target: std.Target) Dwarf {
119pub fn deinit(self: *Dwarf) void {125pub fn deinit(self: *Dwarf) void {
120 const gpa = self.allocator;126 const gpa = self.allocator;
121 self.dbg_line_fn_free_list.deinit(gpa);127 self.dbg_line_fn_free_list.deinit(gpa);
122 self.dbg_info_decl_free_list.deinit(gpa);128 self.atom_free_list.deinit(gpa);
123 self.strtab.deinit(gpa);129 self.strtab.deinit(gpa);
124 self.deferred_error_sets_relocs.deinit(gpa);130 self.deferred_error_sets_relocs.deinit(gpa);
131
132 for (self.managed_atoms.items) |atom| {
133 gpa.destroy(atom);
134 }
135 self.managed_atoms.deinit(gpa);
125}136}
126137
127pub const DeclDebugBuffers = struct {138pub const DeclDebugBuffers = struct {
...@@ -568,10 +579,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void...@@ -568,10 +579,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void
568 var dbg_info_buffer = std.ArrayList(u8).init(arena);579 var dbg_info_buffer = std.ArrayList(u8).init(arena);
569 try self.addDbgInfoErrorSet(arena, module, ty, &dbg_info_buffer);580 try self.addDbgInfoErrorSet(arena, module, ty, &dbg_info_buffer);
570581
571 // TODO seems like we need to store DebugInfoAtoms in Dwarf object582 const atom = try gpa.create(Atom);
572 // In other words, I have turned Dwarf into a linker...
573 // FIXME memory leak!!!
574 const atom = try gpa.create(DebugInfoAtom);
575 errdefer gpa.destroy(atom);583 errdefer gpa.destroy(atom);
576 atom.* = .{584 atom.* = .{
577 .prev = null,585 .prev = null,
...@@ -579,6 +587,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void...@@ -579,6 +587,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void
579 .off = 0,587 .off = 0,
580 .len = 0,588 .len = 0,
581 };589 };
590 try self.managed_atoms.append(gpa, atom);
582 try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));591 try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));
583 try self.writeDeclDebugInfo(file, atom, dbg_info_buffer.items);592 try self.writeDeclDebugInfo(file, atom, dbg_info_buffer.items);
584593
...@@ -620,7 +629,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void...@@ -620,7 +629,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void
620 }629 }
621}630}
622631
623fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom, len: u32) !void {632fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u32) !void {
624 const tracy = trace(@src());633 const tracy = trace(@src());
625 defer tracy.end();634 defer tracy.end();
626635
...@@ -630,14 +639,14 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom...@@ -630,14 +639,14 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom
630 const gpa = self.allocator;639 const gpa = self.allocator;
631640
632 atom.len = len;641 atom.len = len;
633 if (self.dbg_info_decl_last) |last| blk: {642 if (self.atom_last) |last| blk: {
634 if (atom == last) break :blk;643 if (atom == last) break :blk;
635 if (atom.next) |next| {644 if (atom.next) |next| {
636 // Update existing Decl - non-last item.645 // Update existing Decl - non-last item.
637 if (atom.off + atom.len + min_nop_size > next.off) {646 if (atom.off + atom.len + min_nop_size > next.off) {
638 // It grew too big, so we move it to a new location.647 // It grew too big, so we move it to a new location.
639 if (atom.prev) |prev| {648 if (atom.prev) |prev| {
640 self.dbg_info_decl_free_list.put(gpa, prev, {}) catch {};649 self.atom_free_list.put(gpa, prev, {}) catch {};
641 prev.next = atom.next;650 prev.next = atom.next;
642 }651 }
643 next.prev = atom.prev;652 next.prev = atom.prev;
...@@ -663,7 +672,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom...@@ -663,7 +672,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom
663 // TODO Look at the free list before appending at the end.672 // TODO Look at the free list before appending at the end.
664 atom.prev = last;673 atom.prev = last;
665 last.next = atom;674 last.next = atom;
666 self.dbg_info_decl_last = atom;675 self.atom_last = atom;
667676
668 atom.off = last.off + padToIdeal(last.len);677 atom.off = last.off + padToIdeal(last.len);
669 }678 }
...@@ -672,20 +681,20 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom...@@ -672,20 +681,20 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom
672 // TODO Look at the free list before appending at the end.681 // TODO Look at the free list before appending at the end.
673 atom.prev = last;682 atom.prev = last;
674 last.next = atom;683 last.next = atom;
675 self.dbg_info_decl_last = atom;684 self.atom_last = atom;
676685
677 atom.off = last.off + padToIdeal(last.len);686 atom.off = last.off + padToIdeal(last.len);
678 }687 }
679 } else {688 } else {
680 // This is the first Decl of the .debug_info689 // This is the first Decl of the .debug_info
681 self.dbg_info_decl_first = atom;690 self.atom_first = atom;
682 self.dbg_info_decl_last = atom;691 self.atom_last = atom;
683692
684 atom.off = @intCast(u32, padToIdeal(self.dbgInfoHeaderBytes()));693 atom.off = @intCast(u32, padToIdeal(self.dbgInfoHeaderBytes()));
685 }694 }
686}695}
687696
688fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *DebugInfoAtom, dbg_info_buf: []const u8) !void {697fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []const u8) !void {
689 const tracy = trace(@src());698 const tracy = trace(@src());
690 defer tracy.end();699 defer tracy.end();
691700
...@@ -694,7 +703,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *DebugInfoAtom, dbg_info_...@@ -694,7 +703,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *DebugInfoAtom, dbg_info_
694 // probably need to edit that logic too.703 // probably need to edit that logic too.
695 const gpa = self.allocator;704 const gpa = self.allocator;
696705
697 const last_decl = self.dbg_info_decl_last.?;706 const last_decl = self.atom_last.?;
698 // +1 for a trailing zero to end the children of the decl tag.707 // +1 for a trailing zero to end the children of the decl tag.
699 const needed_size = last_decl.off + last_decl.len + 1;708 const needed_size = last_decl.off + last_decl.len + 1;
700 const prev_padding_size: u32 = if (atom.prev) |prev| atom.off - (prev.off + prev.len) else 0;709 const prev_padding_size: u32 = if (atom.prev) |prev| atom.off - (prev.off + prev.len) else 0;
...@@ -819,13 +828,13 @@ pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl)...@@ -819,13 +828,13 @@ pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl)
819 }828 }
820}829}
821830
822pub fn freeAtom(self: *Dwarf, atom: *DebugInfoAtom) void {831pub fn freeAtom(self: *Dwarf, atom: *Atom) void {
823 if (self.dbg_info_decl_first == atom) {832 if (self.atom_first == atom) {
824 self.dbg_info_decl_first = atom.next;833 self.atom_first = atom.next;
825 }834 }
826 if (self.dbg_info_decl_last == atom) {835 if (self.atom_last == atom) {
827 // TODO shrink the .debug_info section size here836 // TODO shrink the .debug_info section size here
828 self.dbg_info_decl_last = atom.prev;837 self.atom_last = atom.prev;
829 }838 }
830839
831 if (atom.prev) |prev| {840 if (atom.prev) |prev| {
...@@ -1964,12 +1973,12 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {...@@ -1964,12 +1973,12 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
1964}1973}
19651974
1966fn getDebugInfoOff(self: Dwarf) ?u32 {1975fn getDebugInfoOff(self: Dwarf) ?u32 {
1967 const first = self.dbg_info_decl_first orelse return null;1976 const first = self.atom_first orelse return null;
1968 return first.off;1977 return first.off;
1969}1978}
19701979
1971fn getDebugInfoEnd(self: Dwarf) ?u32 {1980fn getDebugInfoEnd(self: Dwarf) ?u32 {
1972 const last = self.dbg_info_decl_last orelse return null;1981 const last = self.atom_last orelse return null;
1973 return last.off + last.len;1982 return last.off + last.len;
1974}1983}
19751984
src/link/Elf.zig+1-1
...@@ -207,7 +207,7 @@ pub const TextBlock = struct {...@@ -207,7 +207,7 @@ pub const TextBlock = struct {
207 prev: ?*TextBlock,207 prev: ?*TextBlock,
208 next: ?*TextBlock,208 next: ?*TextBlock,
209209
210 dbg_info_atom: Dwarf.DebugInfoAtom,210 dbg_info_atom: Dwarf.Atom,
211211
212 pub const empty = TextBlock{212 pub const empty = TextBlock{
213 .local_sym_index = 0,213 .local_sym_index = 0,
src/link/MachO/Atom.zig+1-1
...@@ -72,7 +72,7 @@ stab: ?Stab = null,...@@ -72,7 +72,7 @@ stab: ?Stab = null,
72next: ?*Atom,72next: ?*Atom,
73prev: ?*Atom,73prev: ?*Atom,
7474
75dbg_info_atom: Dwarf.DebugInfoAtom,75dbg_info_atom: Dwarf.Atom,
7676
77dirty: bool = true,77dirty: bool = true,
7878