From 05e221796a7c60f26c4c7bc996f12e1392c83d97 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 8 Dec 2022 10:19:52 +0100 Subject: [PATCH] dwarf+d_sym: move logic for growing section to d_sym --- src/link/Dwarf.zig | 41 +++++++++--------------------- src/link/MachO/DebugSymbols.zig | 44 +++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 1a3c1f93f3..4972a1a5f0 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -1106,7 +1106,7 @@ pub fn commitDeclState( .macho => { const macho_file = self.bin_file.cast(File.MachO).?; const d_sym = &macho_file.d_sym.?; - const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?]; + const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?); const file_pos = debug_line_sect.offset + src_fn.off; try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len); }, @@ -1187,7 +1187,7 @@ pub fn commitDeclState( .macho => { const macho_file = self.bin_file.cast(File.MachO).?; const d_sym = &macho_file.d_sym.?; - const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?]; + const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?); if (needed_size != debug_line_sect.size) { if (needed_size > d_sym.allocatedSize(debug_line_sect.offset)) { const new_offset = d_sym.findFreeSpace(needed_size, 1); @@ -1381,7 +1381,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom: *Atom, len: u32) !void { .macho => { const macho_file = self.bin_file.cast(File.MachO).?; const d_sym = &macho_file.d_sym.?; - const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?]; + const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?); const file_pos = debug_info_sect.offset + atom.off; try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false); }, @@ -1477,29 +1477,10 @@ fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void .macho => { const macho_file = self.bin_file.cast(File.MachO).?; const d_sym = &macho_file.d_sym.?; - const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?]; - if (needed_size != debug_info_sect.size) { - if (needed_size > d_sym.allocatedSize(debug_info_sect.offset)) { - const new_offset = d_sym.findFreeSpace(needed_size, 1); - const existing_size = last_decl.off; - std.log.scoped(.dsym).debug("moving __debug_info section: {} bytes from 0x{x} to 0x{x}", .{ - existing_size, - debug_info_sect.offset, - new_offset, - }); - const amt = try d_sym.file.copyRangeAll( - debug_info_sect.offset, - d_sym.file, - new_offset, - existing_size, - ); - if (amt != existing_size) return error.InputOutput; - debug_info_sect.offset = @intCast(u32, new_offset); - } - debug_info_sect.size = needed_size; - d_sym.debug_info_header_dirty = true; - } - const file_pos = debug_info_sect.offset + atom.off; + const sect_index = d_sym.debug_info_section_index.?; + try d_sym.growSection(sect_index, needed_size); + const sect = d_sym.getSection(sect_index); + const file_pos = sect.offset + atom.off; try pwriteDbgInfoNops( d_sym.file, file_pos, @@ -1916,7 +1897,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u .macho => { const macho_file = self.bin_file.cast(File.MachO).?; const d_sym = &macho_file.d_sym.?; - const debug_info_sect = d_sym.sections.items[d_sym.debug_info_section_index.?]; + const debug_info_sect = d_sym.getSection(d_sym.debug_info_section_index.?); const file_pos = debug_info_sect.offset; try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false); }, @@ -2406,7 +2387,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void { const macho_file = self.bin_file.cast(File.MachO).?; const d_sym = &macho_file.d_sym.?; - const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?]; + const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?); const needed_size = debug_line_sect.size + delta; if (needed_size > d_sym.allocatedSize(debug_line_sect.offset)) { @@ -2463,7 +2444,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void { .macho => { const macho_file = self.bin_file.cast(File.MachO).?; const d_sym = &macho_file.d_sym.?; - const debug_line_sect = d_sym.sections.items[d_sym.debug_line_section_index.?]; + const debug_line_sect = d_sym.getSection(d_sym.debug_line_section_index.?); const file_pos = debug_line_sect.offset; try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt); }, @@ -2606,7 +2587,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { .macho => { const macho_file = self.bin_file.cast(File.MachO).?; const d_sym = &macho_file.d_sym.?; - const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?]; + const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?); break :blk debug_info_sect.offset; }, // for wasm, the offset is always 0 as we write to memory first diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig index e198f474c8..d67311b62e 100644 --- a/src/link/MachO/DebugSymbols.zig +++ b/src/link/MachO/DebugSymbols.zig @@ -148,6 +148,40 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme return index; } +pub fn growSection(self: *DebugSymbols, sect_index: u8, needed_size: u32) !void { + const sect = self.getSectionPtr(sect_index); + + if (needed_size > self.allocatedSize(sect.offset)) { + const new_offset = self.findFreeSpace(needed_size, 1); + + log.debug("moving {s} section: {} bytes from 0x{x} to 0x{x}", .{ + sect.sectName(), + sect.size, + sect.offset, + new_offset, + }); + + const amt = try self.file.copyRangeAll( + sect.offset, + self.file, + new_offset, + sect.size, + ); + if (amt != sect.size) return error.InputOutput; + sect.offset = @intCast(u32, new_offset); + } + sect.size = needed_size; + self.markDirty(sect_index); +} + +pub fn markDirty(self: *DebugSymbols, sect_index: u8) void { + if (self.debug_info_section_index.? == sect_index) { + self.debug_info_header_dirty = true; + } else if (self.debug_line_section_index.? == sect_index) { + self.debug_line_header_dirty = true; + } +} + fn detectAllocCollision(self: *DebugSymbols, start: u64, size: u64) ?u64 { const end = start + padToIdeal(size); for (self.sections.items) |section| { @@ -556,3 +590,13 @@ fn getLinkeditSegmentPtr(self: *DebugSymbols) *macho.segment_command_64 { const index = self.linkedit_segment_cmd_index.?; return &self.segments.items[index]; } + +pub fn getSectionPtr(self: *DebugSymbols, sect: u8) *macho.section_64 { + assert(sect < self.sections.items.len); + return &self.sections.items[sect]; +} + +pub fn getSection(self: DebugSymbols, sect: u8) macho.section_64 { + assert(sect < self.sections.items.len); + return self.sections.items[sect]; +}