Commit 05e221796a

Jakub Konka <kubkon@jakubkonka.com>
2022-12-08 10:19:52
dwarf+d_sym: move logic for growing section to d_sym
1 parent 4c38ba7
Changed files (2)
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];
+}
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