diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-02-08 12:15:46 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-02-08 12:15:46 +0100 |
| commit | ce207caa24dc3a283288beb7ee5fd4a07c2c8691 (patch) | |
| tree | 2bb9c32250c547a4a8ca33c9e99a5b310e80f90b | |
| parent | 37033a96ac2e33a56eb2e153462d1a730b426029 (diff) | |
| download | zig-ce207caa24dc3a283288beb7ee5fd4a07c2c8691.tar.gz zig-ce207caa24dc3a283288beb7ee5fd4a07c2c8691.zip | |
macho: in relocatable mode, macho emit __DWARF directly
| -rw-r--r-- | src/link/Dwarf.zig | 276 | ||||
| -rw-r--r-- | src/link/MachO.zig | 134 | ||||
| -rw-r--r-- | src/link/MachO/ZigObject.zig | 8 |
3 files changed, 312 insertions, 106 deletions
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index a38853b7a1..a5dd57a406 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -1282,10 +1282,17 @@ pub fn commitDeclState( try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len); }, .macho => { - const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; - 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); + const macho_file = self.bin_file.cast(File.MachO).?; + if (macho_file.base.isRelocatable()) { + const debug_line_sect = &macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?]; + const file_pos = debug_line_sect.offset + src_fn.off; + try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len); + } else { + const d_sym = macho_file.getDebugSymbols().?; + 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); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -1352,18 +1359,32 @@ pub fn commitDeclState( .macho => { const macho_file = self.bin_file.cast(File.MachO).?; - const d_sym = macho_file.getDebugSymbols().?; - const sect_index = d_sym.debug_line_section_index.?; - try d_sym.growSection(sect_index, needed_size, true, macho_file); - const sect = d_sym.getSection(sect_index); - const file_pos = sect.offset + src_fn.off; - try pwriteDbgLineNops( - d_sym.file, - file_pos, - prev_padding_size, - dbg_line_buffer.items, - next_padding_size, - ); + if (macho_file.base.isRelocatable()) { + const sect_index = macho_file.debug_line_sect_index.?; + try macho_file.growSection(sect_index, needed_size); + const sect = macho_file.sections.items(.header)[sect_index]; + const file_pos = sect.offset + src_fn.off; + try pwriteDbgLineNops( + macho_file.base.file.?, + file_pos, + prev_padding_size, + dbg_line_buffer.items, + next_padding_size, + ); + } else { + const d_sym = macho_file.getDebugSymbols().?; + const sect_index = d_sym.debug_line_section_index.?; + try d_sym.growSection(sect_index, needed_size, true, macho_file); + const sect = d_sym.getSection(sect_index); + const file_pos = sect.offset + src_fn.off; + try pwriteDbgLineNops( + d_sym.file, + file_pos, + prev_padding_size, + dbg_line_buffer.items, + next_padding_size, + ); + } }, .wasm => { @@ -1460,16 +1481,21 @@ pub fn commitDeclState( while (decl_state.exprloc_relocs.popOrNull()) |reloc| { switch (self.bin_file.tag) { .macho => { - const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; - try d_sym.relocs.append(d_sym.allocator, .{ - .type = switch (reloc.type) { - .direct_load => .direct_load, - .got_load => .got_load, - }, - .target = reloc.target, - .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off, - .addend = 0, - }); + const macho_file = self.bin_file.cast(File.MachO).?; + if (macho_file.base.isRelocatable()) { + // TODO + } else { + const d_sym = macho_file.getDebugSymbols().?; + try d_sym.relocs.append(d_sym.allocator, .{ + .type = switch (reloc.type) { + .direct_load => .direct_load, + .got_load => .got_load, + }, + .target = reloc.target, + .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off, + .addend = 0, + }); + } }, .elf => {}, // TODO else => unreachable, @@ -1512,10 +1538,17 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false); }, .macho => { - const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; - 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); + const macho_file = self.bin_file.cast(File.MachO).?; + if (macho_file.base.isRelocatable()) { + const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?]; + const file_pos = debug_info_sect.offset + atom.off; + try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false); + } else { + const d_sym = macho_file.getDebugSymbols().?; + 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); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -1599,19 +1632,34 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons .macho => { const macho_file = self.bin_file.cast(File.MachO).?; - const d_sym = macho_file.getDebugSymbols().?; - const sect_index = d_sym.debug_info_section_index.?; - try d_sym.growSection(sect_index, needed_size, true, macho_file); - const sect = d_sym.getSection(sect_index); - const file_pos = sect.offset + atom.off; - try pwriteDbgInfoNops( - d_sym.file, - file_pos, - prev_padding_size, - dbg_info_buf, - next_padding_size, - trailing_zero, - ); + if (macho_file.base.isRelocatable()) { + const sect_index = macho_file.debug_info_sect_index.?; + try macho_file.growSection(sect_index, needed_size); + const sect = macho_file.sections.items(.header)[sect_index]; + const file_pos = sect.offset + atom.off; + try pwriteDbgInfoNops( + macho_file.base.file.?, + file_pos, + prev_padding_size, + dbg_info_buf, + next_padding_size, + trailing_zero, + ); + } else { + const d_sym = macho_file.getDebugSymbols().?; + const sect_index = d_sym.debug_info_section_index.?; + try d_sym.growSection(sect_index, needed_size, true, macho_file); + const sect = d_sym.getSection(sect_index); + const file_pos = sect.offset + atom.off; + try pwriteDbgInfoNops( + d_sym.file, + file_pos, + prev_padding_size, + dbg_info_buf, + next_padding_size, + trailing_zero, + ); + } }, .wasm => { @@ -1672,10 +1720,17 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.D try elf_file.base.file.?.pwriteAll(&data, file_pos); }, .macho => { - const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; - const sect = d_sym.getSection(d_sym.debug_line_section_index.?); - const file_pos = sect.offset + atom.off + self.getRelocDbgLineOff(); - try d_sym.file.pwriteAll(&data, file_pos); + const macho_file = self.bin_file.cast(File.MachO).?; + if (macho_file.base.isRelocatable()) { + const sect = macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?]; + const file_pos = sect.offset + atom.off + self.getRelocDbgLineOff(); + try macho_file.base.file.?.pwriteAll(&data, file_pos); + } else { + const d_sym = macho_file.getDebugSymbols().?; + const sect = d_sym.getSection(d_sym.debug_line_section_index.?); + const file_pos = sect.offset + atom.off + self.getRelocDbgLineOff(); + try d_sym.file.pwriteAll(&data, file_pos); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -1880,12 +1935,20 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { }, .macho => { const macho_file = self.bin_file.cast(File.MachO).?; - const d_sym = macho_file.getDebugSymbols().?; - const sect_index = d_sym.debug_abbrev_section_index.?; - try d_sym.growSection(sect_index, needed_size, false, macho_file); - const sect = d_sym.getSection(sect_index); - const file_pos = sect.offset + abbrev_offset; - try d_sym.file.pwriteAll(&abbrev_buf, file_pos); + if (macho_file.base.isRelocatable()) { + const sect_index = macho_file.debug_abbrev_sect_index.?; + try macho_file.growSection(sect_index, needed_size); + const sect = macho_file.sections.items(.header)[sect_index]; + const file_pos = sect.offset + abbrev_offset; + try macho_file.base.file.?.pwriteAll(&abbrev_buf, file_pos); + } else { + const d_sym = macho_file.getDebugSymbols().?; + const sect_index = d_sym.debug_abbrev_section_index.?; + try d_sym.growSection(sect_index, needed_size, false, macho_file); + const sect = d_sym.getSection(sect_index); + const file_pos = sect.offset + abbrev_offset; + try d_sym.file.pwriteAll(&abbrev_buf, file_pos); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -1970,10 +2033,17 @@ pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64) try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false); }, .macho => { - const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; - 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); + const macho_file = self.bin_file.cast(File.MachO).?; + if (macho_file.base.isRelocatable()) { + const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?]; + const file_pos = debug_info_sect.offset; + try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false); + } else { + const d_sym = macho_file.getDebugSymbols().?; + 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); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -2296,12 +2366,20 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void { }, .macho => { const macho_file = self.bin_file.cast(File.MachO).?; - const d_sym = macho_file.getDebugSymbols().?; - const sect_index = d_sym.debug_aranges_section_index.?; - try d_sym.growSection(sect_index, needed_size, false, macho_file); - const sect = d_sym.getSection(sect_index); - const file_pos = sect.offset; - try d_sym.file.pwriteAll(di_buf.items, file_pos); + if (macho_file.base.isRelocatable()) { + const sect_index = macho_file.debug_aranges_sect_index.?; + try macho_file.growSection(sect_index, needed_size); + const sect = macho_file.sections.items(.header)[sect_index]; + const file_pos = sect.offset; + try macho_file.base.file.?.pwriteAll(di_buf.items, file_pos); + } else { + const d_sym = macho_file.getDebugSymbols().?; + const sect_index = d_sym.debug_aranges_section_index.?; + try d_sym.growSection(sect_index, needed_size, false, macho_file); + const sect = d_sym.getSection(sect_index); + const file_pos = sect.offset; + try d_sym.file.pwriteAll(di_buf.items, file_pos); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -2437,16 +2515,28 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { }, .macho => { const macho_file = self.bin_file.cast(File.MachO).?; - const d_sym = macho_file.getDebugSymbols().?; - const sect_index = d_sym.debug_line_section_index.?; - const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta); - try d_sym.growSection(sect_index, needed_size, true, macho_file); - const file_pos = d_sym.getSection(sect_index).offset + first_fn.off; + if (macho_file.base.isRelocatable()) { + const sect_index = macho_file.debug_line_sect_index.?; + const needed_size: u32 = @intCast(macho_file.sections.items(.header)[sect_index].size + delta); + try macho_file.growSection(sect_index, needed_size); + const file_pos = macho_file.sections.items(.header)[sect_index].offset + first_fn.off; - const amt = try d_sym.file.preadAll(buffer, file_pos); - if (amt != buffer.len) return error.InputOutput; + const amt = try macho_file.base.file.?.preadAll(buffer, file_pos); + if (amt != buffer.len) return error.InputOutput; + + try macho_file.base.file.?.pwriteAll(buffer, file_pos + delta); + } else { + const d_sym = macho_file.getDebugSymbols().?; + const sect_index = d_sym.debug_line_section_index.?; + const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta); + try d_sym.growSection(sect_index, needed_size, true, macho_file); + const file_pos = d_sym.getSection(sect_index).offset + first_fn.off; + + const amt = try d_sym.file.preadAll(buffer, file_pos); + if (amt != buffer.len) return error.InputOutput; - try d_sym.file.pwriteAll(buffer, file_pos + delta); + try d_sym.file.pwriteAll(buffer, file_pos + delta); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -2492,10 +2582,17 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void { try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt); }, .macho => { - const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; - 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); + const macho_file = self.bin_file.cast(File.MachO).?; + if (macho_file.base.isRelocatable()) { + const debug_line_sect = macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?]; + const file_pos = debug_line_sect.offset; + try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt); + } else { + const d_sym = macho_file.getDebugSymbols().?; + 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); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -2613,9 +2710,15 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { break :pos debug_info_sect.sh_offset; }, .macho => pos: { - const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; - const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?); - break :pos debug_info_sect.offset; + const macho_file = self.bin_file.cast(File.MachO).?; + if (macho_file.base.isRelocatable()) { + const debug_info_sect = &macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?]; + break :pos debug_info_sect.offset; + } else { + const d_sym = macho_file.getDebugSymbols().?; + const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?); + break :pos debug_info_sect.offset; + } }, // for wasm, the offset is always 0 as we write to memory first .wasm => 0, @@ -2633,8 +2736,13 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void { try elf_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset); }, .macho => { - const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?; - try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset); + const macho_file = self.bin_file.cast(File.MachO).?; + if (macho_file.base.isRelocatable()) { + try macho_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset); + } else { + const d_sym = macho_file.getDebugSymbols().?; + try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset); + } }, .wasm => { const wasm_file = self.bin_file.cast(File.Wasm).?; @@ -2659,8 +2767,12 @@ fn addDIFile(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclIndex) !u28 }, .macho => { const macho_file = self.bin_file.cast(File.MachO).?; - const d_sym = macho_file.getDebugSymbols().?; - d_sym.markDirty(d_sym.debug_line_section_index.?, macho_file); + if (macho_file.base.isRelocatable()) { + macho_file.markDirty(macho_file.debug_line_sect_index.?); + } else { + const d_sym = macho_file.getDebugSymbols().?; + d_sym.markDirty(d_sym.debug_line_section_index.?, macho_file); + } }, .wasm => {}, else => unreachable, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 00b456eb12..aac0536816 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -103,6 +103,14 @@ zig_const_sect_index: ?u8 = null, zig_data_sect_index: ?u8 = null, zig_bss_sect_index: ?u8 = null, +/// Tracked DWARF section headers that apply only when we emit relocatable. +/// For executable and loadable images, DWARF is tracked directly by dSYM bundle object. +debug_info_sect_index: ?u8 = null, +debug_abbrev_sect_index: ?u8 = null, +debug_str_sect_index: ?u8 = null, +debug_aranges_sect_index: ?u8 = null, +debug_line_sect_index: ?u8 = null, + has_tlv: bool = false, binds_to_weak: bool = false, weak_defines: bool = false, @@ -259,32 +267,11 @@ pub fn createEmpty( try zo.init(self); try self.initMetadata(.{ + .emit = emit, + .zo = zo, .symbol_count_hint = options.symbol_count_hint, .program_code_size_hint = options.program_code_size_hint, }); - - if (zo.dwarf != null and !self.base.isRelocatable()) { - // Create dSYM bundle. - log.debug("creating {s}.dSYM bundle", .{emit.sub_path}); - - const sep = fs.path.sep_str; - const d_sym_path = try std.fmt.allocPrint( - arena, - "{s}.dSYM" ++ sep ++ "Contents" ++ sep ++ "Resources" ++ sep ++ "DWARF", - .{emit.sub_path}, - ); - - var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{}); - defer d_sym_bundle.close(); - - const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{ - .truncate = false, - .read = true, - }); - - self.d_sym = .{ .allocator = gpa, .file = d_sym_file }; - try self.d_sym.?.initMetadata(self); - } } } @@ -2007,6 +1994,11 @@ pub fn sortSections(self: *MachO) !void { &self.eh_frame_sect_index, &self.unwind_info_sect_index, &self.objc_stubs_sect_index, + &self.debug_info_sect_index, + &self.debug_str_sect_index, + &self.debug_line_sect_index, + &self.debug_abbrev_sect_index, + &self.debug_info_sect_index, }) |maybe_index| { if (maybe_index.*) |*index| { index.* = backlinks[index.*]; @@ -3317,6 +3309,8 @@ fn copyRangeAllZeroOut(self: *MachO, old_offset: u64, new_offset: u64, size: u64 } const InitMetadataOptions = struct { + emit: Compilation.Emit, + zo: *ZigObject, symbol_count_hint: u64, program_code_size_hint: u64, }; @@ -3385,6 +3379,31 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { .prot = macho.PROT.READ | macho.PROT.WRITE, }); } + + if (options.zo.dwarf) |_| { + // Create dSYM bundle. + log.debug("creating {s}.dSYM bundle", .{options.emit.sub_path}); + + const gpa = self.base.comp.gpa; + const sep = fs.path.sep_str; + const d_sym_path = try std.fmt.allocPrint( + gpa, + "{s}.dSYM" ++ sep ++ "Contents" ++ sep ++ "Resources" ++ sep ++ "DWARF", + .{options.emit.sub_path}, + ); + defer gpa.free(d_sym_path); + + var d_sym_bundle = try options.emit.directory.handle.makeOpenPath(d_sym_path, .{}); + defer d_sym_bundle.close(); + + const d_sym_file = try d_sym_bundle.createFile(options.emit.sub_path, .{ + .truncate = false, + .read = true, + }); + + self.d_sym = .{ .allocator = gpa, .file = d_sym_file }; + try self.d_sym.?.initMetadata(self); + } } const appendSect = struct { @@ -3462,6 +3481,44 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { appendSect(self, self.zig_bss_sect_index.?, self.zig_bss_seg_index.?); } } + + if (self.base.isRelocatable()) { + { + self.debug_str_sect_index = try self.addSection("__DWARF", "__debug_str", .{ + .flags = macho.S_ATTR_DEBUG, + }); + try allocSect(self, self.debug_str_sect_index.?, 200); + } + + { + self.debug_info_sect_index = try self.addSection("__DWARF", "__debug_info", .{ + .flags = macho.S_ATTR_DEBUG, + }); + try allocSect(self, self.debug_info_sect_index.?, 200); + } + + { + self.debug_abbrev_sect_index = try self.addSection("__DWARF", "__debug_abbrev", .{ + .flags = macho.S_ATTR_DEBUG, + }); + try allocSect(self, self.debug_abbrev_sect_index.?, 128); + } + + { + self.debug_aranges_sect_index = try self.addSection("__DWARF", "__debug_aranges", .{ + .alignment = 4, + .flags = macho.S_ATTR_DEBUG, + }); + try allocSect(self, self.debug_aranges_sect_index.?, 160); + } + + { + self.debug_line_sect_index = try self.addSection("__DWARF", "__debug_line", .{ + .flags = macho.S_ATTR_DEBUG, + }); + try allocSect(self, self.debug_line_sect_index.?, 250); + } + } } pub fn growSection(self: *MachO, sect_index: u8, needed_size: u64) !void { @@ -3549,6 +3606,22 @@ fn growSectionRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !void sect.size = needed_size; } +pub fn markDirty(self: *MachO, sect_index: u8) void { + if (self.getZigObject()) |zo| { + if (self.debug_info_sect_index.? == sect_index) { + zo.debug_info_header_dirty = true; + } else if (self.debug_line_sect_index.? == sect_index) { + zo.debug_line_header_dirty = true; + } else if (self.debug_abbrev_sect_index.? == sect_index) { + zo.debug_abbrev_dirty = true; + } else if (self.debug_str_sect_index.? == sect_index) { + zo.debug_strtab_dirty = true; + } else if (self.debug_aranges_sect_index.? == sect_index) { + zo.debug_aranges_dirty = true; + } + } +} + pub fn getTarget(self: MachO) std.Target { return self.base.comp.root_mod.resolved_target.result; } @@ -3624,6 +3697,21 @@ pub fn isZigSection(self: MachO, sect_id: u8) bool { return false; } +pub fn isDebugSection(self: MachO, sect_id: u8) bool { + inline for (&[_]?u8{ + self.debug_info_sect_index, + self.debug_abbrev_sect_index, + self.debug_str_sect_index, + self.debug_aranges_sect_index, + self.debug_line_sect_index, + }) |maybe_index| { + if (maybe_index) |index| { + if (index == sect_id) return true; + } + } + return false; +} + pub fn addSegment(self: *MachO, name: []const u8, opts: struct { vmaddr: u64 = 0, vmsize: u64 = 0, diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index abaa4fe6f7..061f268892 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -471,7 +471,13 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void { self.debug_strtab_dirty = false; } } else { - // TODO: relocatable + const sect_index = macho_file.debug_str_sect_index.?; + if (self.debug_strtab_dirty or dw.strtab.buffer.items.len != macho_file.sections.items(.header)[sect_index].size) { + const needed_size = @as(u32, @intCast(dw.strtab.buffer.items.len)); + try macho_file.growSection(sect_index, needed_size); + try macho_file.base.file.?.pwriteAll(dw.strtab.buffer.items, macho_file.sections.items(.header)[sect_index].offset); + self.debug_strtab_dirty = false; + } } } |
