authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-08 12:15:46+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-08 12:15:46+01:00
logce207caa24dc3a283288beb7ee5fd4a07c2c8691
tree2bb9c32250c547a4a8ca33c9e99a5b310e80f90b
parent37033a96ac2e33a56eb2e153462d1a730b426029

macho: in relocatable mode, macho emit __DWARF directly


3 files changed, 312 insertions(+), 106 deletions(-)

src/link/Dwarf.zig+194-82
......@@ -1282,10 +1282,17 @@ pub fn commitDeclState(
12821282 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
12831283 },
12841284 .macho => {
1285 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
1286 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);
1287 const file_pos = debug_line_sect.offset + src_fn.off;
1288 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);
1285 const macho_file = self.bin_file.cast(File.MachO).?;
1286 if (macho_file.base.isRelocatable()) {
1287 const debug_line_sect = &macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
1288 const file_pos = debug_line_sect.offset + src_fn.off;
1289 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
1290 } else {
1291 const d_sym = macho_file.getDebugSymbols().?;
1292 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);
1293 const file_pos = debug_line_sect.offset + src_fn.off;
1294 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);
1295 }
12891296 },
12901297 .wasm => {
12911298 const wasm_file = self.bin_file.cast(File.Wasm).?;
......@@ -1352,18 +1359,32 @@ pub fn commitDeclState(
13521359
13531360 .macho => {
13541361 const macho_file = self.bin_file.cast(File.MachO).?;
1355 const d_sym = macho_file.getDebugSymbols().?;
1356 const sect_index = d_sym.debug_line_section_index.?;
1357 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1358 const sect = d_sym.getSection(sect_index);
1359 const file_pos = sect.offset + src_fn.off;
1360 try pwriteDbgLineNops(
1361 d_sym.file,
1362 file_pos,
1363 prev_padding_size,
1364 dbg_line_buffer.items,
1365 next_padding_size,
1366 );
1362 if (macho_file.base.isRelocatable()) {
1363 const sect_index = macho_file.debug_line_sect_index.?;
1364 try macho_file.growSection(sect_index, needed_size);
1365 const sect = macho_file.sections.items(.header)[sect_index];
1366 const file_pos = sect.offset + src_fn.off;
1367 try pwriteDbgLineNops(
1368 macho_file.base.file.?,
1369 file_pos,
1370 prev_padding_size,
1371 dbg_line_buffer.items,
1372 next_padding_size,
1373 );
1374 } else {
1375 const d_sym = macho_file.getDebugSymbols().?;
1376 const sect_index = d_sym.debug_line_section_index.?;
1377 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1378 const sect = d_sym.getSection(sect_index);
1379 const file_pos = sect.offset + src_fn.off;
1380 try pwriteDbgLineNops(
1381 d_sym.file,
1382 file_pos,
1383 prev_padding_size,
1384 dbg_line_buffer.items,
1385 next_padding_size,
1386 );
1387 }
13671388 },
13681389
13691390 .wasm => {
......@@ -1460,16 +1481,21 @@ pub fn commitDeclState(
14601481 while (decl_state.exprloc_relocs.popOrNull()) |reloc| {
14611482 switch (self.bin_file.tag) {
14621483 .macho => {
1463 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
1464 try d_sym.relocs.append(d_sym.allocator, .{
1465 .type = switch (reloc.type) {
1466 .direct_load => .direct_load,
1467 .got_load => .got_load,
1468 },
1469 .target = reloc.target,
1470 .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off,
1471 .addend = 0,
1472 });
1484 const macho_file = self.bin_file.cast(File.MachO).?;
1485 if (macho_file.base.isRelocatable()) {
1486 // TODO
1487 } else {
1488 const d_sym = macho_file.getDebugSymbols().?;
1489 try d_sym.relocs.append(d_sym.allocator, .{
1490 .type = switch (reloc.type) {
1491 .direct_load => .direct_load,
1492 .got_load => .got_load,
1493 },
1494 .target = reloc.target,
1495 .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off,
1496 .addend = 0,
1497 });
1498 }
14731499 },
14741500 .elf => {}, // TODO
14751501 else => unreachable,
......@@ -1512,10 +1538,17 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
15121538 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
15131539 },
15141540 .macho => {
1515 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
1516 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
1517 const file_pos = debug_info_sect.offset + atom.off;
1518 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);
1541 const macho_file = self.bin_file.cast(File.MachO).?;
1542 if (macho_file.base.isRelocatable()) {
1543 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
1544 const file_pos = debug_info_sect.offset + atom.off;
1545 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
1546 } else {
1547 const d_sym = macho_file.getDebugSymbols().?;
1548 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
1549 const file_pos = debug_info_sect.offset + atom.off;
1550 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);
1551 }
15191552 },
15201553 .wasm => {
15211554 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
15991632
16001633 .macho => {
16011634 const macho_file = self.bin_file.cast(File.MachO).?;
1602 const d_sym = macho_file.getDebugSymbols().?;
1603 const sect_index = d_sym.debug_info_section_index.?;
1604 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1605 const sect = d_sym.getSection(sect_index);
1606 const file_pos = sect.offset + atom.off;
1607 try pwriteDbgInfoNops(
1608 d_sym.file,
1609 file_pos,
1610 prev_padding_size,
1611 dbg_info_buf,
1612 next_padding_size,
1613 trailing_zero,
1614 );
1635 if (macho_file.base.isRelocatable()) {
1636 const sect_index = macho_file.debug_info_sect_index.?;
1637 try macho_file.growSection(sect_index, needed_size);
1638 const sect = macho_file.sections.items(.header)[sect_index];
1639 const file_pos = sect.offset + atom.off;
1640 try pwriteDbgInfoNops(
1641 macho_file.base.file.?,
1642 file_pos,
1643 prev_padding_size,
1644 dbg_info_buf,
1645 next_padding_size,
1646 trailing_zero,
1647 );
1648 } else {
1649 const d_sym = macho_file.getDebugSymbols().?;
1650 const sect_index = d_sym.debug_info_section_index.?;
1651 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1652 const sect = d_sym.getSection(sect_index);
1653 const file_pos = sect.offset + atom.off;
1654 try pwriteDbgInfoNops(
1655 d_sym.file,
1656 file_pos,
1657 prev_padding_size,
1658 dbg_info_buf,
1659 next_padding_size,
1660 trailing_zero,
1661 );
1662 }
16151663 },
16161664
16171665 .wasm => {
......@@ -1672,10 +1720,17 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: InternPool.D
16721720 try elf_file.base.file.?.pwriteAll(&data, file_pos);
16731721 },
16741722 .macho => {
1675 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
1676 const sect = d_sym.getSection(d_sym.debug_line_section_index.?);
1677 const file_pos = sect.offset + atom.off + self.getRelocDbgLineOff();
1678 try d_sym.file.pwriteAll(&data, file_pos);
1723 const macho_file = self.bin_file.cast(File.MachO).?;
1724 if (macho_file.base.isRelocatable()) {
1725 const sect = macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
1726 const file_pos = sect.offset + atom.off + self.getRelocDbgLineOff();
1727 try macho_file.base.file.?.pwriteAll(&data, file_pos);
1728 } else {
1729 const d_sym = macho_file.getDebugSymbols().?;
1730 const sect = d_sym.getSection(d_sym.debug_line_section_index.?);
1731 const file_pos = sect.offset + atom.off + self.getRelocDbgLineOff();
1732 try d_sym.file.pwriteAll(&data, file_pos);
1733 }
16791734 },
16801735 .wasm => {
16811736 const wasm_file = self.bin_file.cast(File.Wasm).?;
......@@ -1880,12 +1935,20 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {
18801935 },
18811936 .macho => {
18821937 const macho_file = self.bin_file.cast(File.MachO).?;
1883 const d_sym = macho_file.getDebugSymbols().?;
1884 const sect_index = d_sym.debug_abbrev_section_index.?;
1885 try d_sym.growSection(sect_index, needed_size, false, macho_file);
1886 const sect = d_sym.getSection(sect_index);
1887 const file_pos = sect.offset + abbrev_offset;
1888 try d_sym.file.pwriteAll(&abbrev_buf, file_pos);
1938 if (macho_file.base.isRelocatable()) {
1939 const sect_index = macho_file.debug_abbrev_sect_index.?;
1940 try macho_file.growSection(sect_index, needed_size);
1941 const sect = macho_file.sections.items(.header)[sect_index];
1942 const file_pos = sect.offset + abbrev_offset;
1943 try macho_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1944 } else {
1945 const d_sym = macho_file.getDebugSymbols().?;
1946 const sect_index = d_sym.debug_abbrev_section_index.?;
1947 try d_sym.growSection(sect_index, needed_size, false, macho_file);
1948 const sect = d_sym.getSection(sect_index);
1949 const file_pos = sect.offset + abbrev_offset;
1950 try d_sym.file.pwriteAll(&abbrev_buf, file_pos);
1951 }
18891952 },
18901953 .wasm => {
18911954 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)
19702033 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
19712034 },
19722035 .macho => {
1973 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
1974 const debug_info_sect = d_sym.getSection(d_sym.debug_info_section_index.?);
1975 const file_pos = debug_info_sect.offset;
1976 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);
2036 const macho_file = self.bin_file.cast(File.MachO).?;
2037 if (macho_file.base.isRelocatable()) {
2038 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
2039 const file_pos = debug_info_sect.offset;
2040 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
2041 } else {
2042 const d_sym = macho_file.getDebugSymbols().?;
2043 const debug_info_sect = d_sym.getSection(d_sym.debug_info_section_index.?);
2044 const file_pos = debug_info_sect.offset;
2045 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);
2046 }
19772047 },
19782048 .wasm => {
19792049 const wasm_file = self.bin_file.cast(File.Wasm).?;
......@@ -2296,12 +2366,20 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
22962366 },
22972367 .macho => {
22982368 const macho_file = self.bin_file.cast(File.MachO).?;
2299 const d_sym = macho_file.getDebugSymbols().?;
2300 const sect_index = d_sym.debug_aranges_section_index.?;
2301 try d_sym.growSection(sect_index, needed_size, false, macho_file);
2302 const sect = d_sym.getSection(sect_index);
2303 const file_pos = sect.offset;
2304 try d_sym.file.pwriteAll(di_buf.items, file_pos);
2369 if (macho_file.base.isRelocatable()) {
2370 const sect_index = macho_file.debug_aranges_sect_index.?;
2371 try macho_file.growSection(sect_index, needed_size);
2372 const sect = macho_file.sections.items(.header)[sect_index];
2373 const file_pos = sect.offset;
2374 try macho_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2375 } else {
2376 const d_sym = macho_file.getDebugSymbols().?;
2377 const sect_index = d_sym.debug_aranges_section_index.?;
2378 try d_sym.growSection(sect_index, needed_size, false, macho_file);
2379 const sect = d_sym.getSection(sect_index);
2380 const file_pos = sect.offset;
2381 try d_sym.file.pwriteAll(di_buf.items, file_pos);
2382 }
23052383 },
23062384 .wasm => {
23072385 const wasm_file = self.bin_file.cast(File.Wasm).?;
......@@ -2437,16 +2515,28 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
24372515 },
24382516 .macho => {
24392517 const macho_file = self.bin_file.cast(File.MachO).?;
2440 const d_sym = macho_file.getDebugSymbols().?;
2441 const sect_index = d_sym.debug_line_section_index.?;
2442 const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta);
2443 try d_sym.growSection(sect_index, needed_size, true, macho_file);
2444 const file_pos = d_sym.getSection(sect_index).offset + first_fn.off;
2518 if (macho_file.base.isRelocatable()) {
2519 const sect_index = macho_file.debug_line_sect_index.?;
2520 const needed_size: u32 = @intCast(macho_file.sections.items(.header)[sect_index].size + delta);
2521 try macho_file.growSection(sect_index, needed_size);
2522 const file_pos = macho_file.sections.items(.header)[sect_index].offset + first_fn.off;
24452523
2446 const amt = try d_sym.file.preadAll(buffer, file_pos);
2447 if (amt != buffer.len) return error.InputOutput;
2524 const amt = try macho_file.base.file.?.preadAll(buffer, file_pos);
2525 if (amt != buffer.len) return error.InputOutput;
2526
2527 try macho_file.base.file.?.pwriteAll(buffer, file_pos + delta);
2528 } else {
2529 const d_sym = macho_file.getDebugSymbols().?;
2530 const sect_index = d_sym.debug_line_section_index.?;
2531 const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta);
2532 try d_sym.growSection(sect_index, needed_size, true, macho_file);
2533 const file_pos = d_sym.getSection(sect_index).offset + first_fn.off;
2534
2535 const amt = try d_sym.file.preadAll(buffer, file_pos);
2536 if (amt != buffer.len) return error.InputOutput;
24482537
2449 try d_sym.file.pwriteAll(buffer, file_pos + delta);
2538 try d_sym.file.pwriteAll(buffer, file_pos + delta);
2539 }
24502540 },
24512541 .wasm => {
24522542 const wasm_file = self.bin_file.cast(File.Wasm).?;
......@@ -2492,10 +2582,17 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
24922582 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
24932583 },
24942584 .macho => {
2495 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
2496 const debug_line_sect = d_sym.getSection(d_sym.debug_line_section_index.?);
2497 const file_pos = debug_line_sect.offset;
2498 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);
2585 const macho_file = self.bin_file.cast(File.MachO).?;
2586 if (macho_file.base.isRelocatable()) {
2587 const debug_line_sect = macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
2588 const file_pos = debug_line_sect.offset;
2589 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
2590 } else {
2591 const d_sym = macho_file.getDebugSymbols().?;
2592 const debug_line_sect = d_sym.getSection(d_sym.debug_line_section_index.?);
2593 const file_pos = debug_line_sect.offset;
2594 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);
2595 }
24992596 },
25002597 .wasm => {
25012598 const wasm_file = self.bin_file.cast(File.Wasm).?;
......@@ -2613,9 +2710,15 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
26132710 break :pos debug_info_sect.sh_offset;
26142711 },
26152712 .macho => pos: {
2616 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
2617 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
2618 break :pos debug_info_sect.offset;
2713 const macho_file = self.bin_file.cast(File.MachO).?;
2714 if (macho_file.base.isRelocatable()) {
2715 const debug_info_sect = &macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
2716 break :pos debug_info_sect.offset;
2717 } else {
2718 const d_sym = macho_file.getDebugSymbols().?;
2719 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
2720 break :pos debug_info_sect.offset;
2721 }
26192722 },
26202723 // for wasm, the offset is always 0 as we write to memory first
26212724 .wasm => 0,
......@@ -2633,8 +2736,13 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
26332736 try elf_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
26342737 },
26352738 .macho => {
2636 const d_sym = self.bin_file.cast(File.MachO).?.getDebugSymbols().?;
2637 try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2739 const macho_file = self.bin_file.cast(File.MachO).?;
2740 if (macho_file.base.isRelocatable()) {
2741 try macho_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2742 } else {
2743 const d_sym = macho_file.getDebugSymbols().?;
2744 try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2745 }
26382746 },
26392747 .wasm => {
26402748 const wasm_file = self.bin_file.cast(File.Wasm).?;
......@@ -2659,8 +2767,12 @@ fn addDIFile(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclIndex) !u28
26592767 },
26602768 .macho => {
26612769 const macho_file = self.bin_file.cast(File.MachO).?;
2662 const d_sym = macho_file.getDebugSymbols().?;
2663 d_sym.markDirty(d_sym.debug_line_section_index.?, macho_file);
2770 if (macho_file.base.isRelocatable()) {
2771 macho_file.markDirty(macho_file.debug_line_sect_index.?);
2772 } else {
2773 const d_sym = macho_file.getDebugSymbols().?;
2774 d_sym.markDirty(d_sym.debug_line_section_index.?, macho_file);
2775 }
26642776 },
26652777 .wasm => {},
26662778 else => unreachable,
src/link/MachO.zig+111-23
......@@ -103,6 +103,14 @@ zig_const_sect_index: ?u8 = null,
103103zig_data_sect_index: ?u8 = null,
104104zig_bss_sect_index: ?u8 = null,
105105
106/// Tracked DWARF section headers that apply only when we emit relocatable.
107/// For executable and loadable images, DWARF is tracked directly by dSYM bundle object.
108debug_info_sect_index: ?u8 = null,
109debug_abbrev_sect_index: ?u8 = null,
110debug_str_sect_index: ?u8 = null,
111debug_aranges_sect_index: ?u8 = null,
112debug_line_sect_index: ?u8 = null,
113
106114has_tlv: bool = false,
107115binds_to_weak: bool = false,
108116weak_defines: bool = false,
......@@ -259,32 +267,11 @@ pub fn createEmpty(
259267 try zo.init(self);
260268
261269 try self.initMetadata(.{
270 .emit = emit,
271 .zo = zo,
262272 .symbol_count_hint = options.symbol_count_hint,
263273 .program_code_size_hint = options.program_code_size_hint,
264274 });
265
266 if (zo.dwarf != null and !self.base.isRelocatable()) {
267 // Create dSYM bundle.
268 log.debug("creating {s}.dSYM bundle", .{emit.sub_path});
269
270 const sep = fs.path.sep_str;
271 const d_sym_path = try std.fmt.allocPrint(
272 arena,
273 "{s}.dSYM" ++ sep ++ "Contents" ++ sep ++ "Resources" ++ sep ++ "DWARF",
274 .{emit.sub_path},
275 );
276
277 var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{});
278 defer d_sym_bundle.close();
279
280 const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{
281 .truncate = false,
282 .read = true,
283 });
284
285 self.d_sym = .{ .allocator = gpa, .file = d_sym_file };
286 try self.d_sym.?.initMetadata(self);
287 }
288275 }
289276 }
290277
......@@ -2007,6 +1994,11 @@ pub fn sortSections(self: *MachO) !void {
20071994 &self.eh_frame_sect_index,
20081995 &self.unwind_info_sect_index,
20091996 &self.objc_stubs_sect_index,
1997 &self.debug_info_sect_index,
1998 &self.debug_str_sect_index,
1999 &self.debug_line_sect_index,
2000 &self.debug_abbrev_sect_index,
2001 &self.debug_info_sect_index,
20102002 }) |maybe_index| {
20112003 if (maybe_index.*) |*index| {
20122004 index.* = backlinks[index.*];
......@@ -3317,6 +3309,8 @@ fn copyRangeAllZeroOut(self: *MachO, old_offset: u64, new_offset: u64, size: u64
33173309}
33183310
33193311const InitMetadataOptions = struct {
3312 emit: Compilation.Emit,
3313 zo: *ZigObject,
33203314 symbol_count_hint: u64,
33213315 program_code_size_hint: u64,
33223316};
......@@ -3385,6 +3379,31 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void {
33853379 .prot = macho.PROT.READ | macho.PROT.WRITE,
33863380 });
33873381 }
3382
3383 if (options.zo.dwarf) |_| {
3384 // Create dSYM bundle.
3385 log.debug("creating {s}.dSYM bundle", .{options.emit.sub_path});
3386
3387 const gpa = self.base.comp.gpa;
3388 const sep = fs.path.sep_str;
3389 const d_sym_path = try std.fmt.allocPrint(
3390 gpa,
3391 "{s}.dSYM" ++ sep ++ "Contents" ++ sep ++ "Resources" ++ sep ++ "DWARF",
3392 .{options.emit.sub_path},
3393 );
3394 defer gpa.free(d_sym_path);
3395
3396 var d_sym_bundle = try options.emit.directory.handle.makeOpenPath(d_sym_path, .{});
3397 defer d_sym_bundle.close();
3398
3399 const d_sym_file = try d_sym_bundle.createFile(options.emit.sub_path, .{
3400 .truncate = false,
3401 .read = true,
3402 });
3403
3404 self.d_sym = .{ .allocator = gpa, .file = d_sym_file };
3405 try self.d_sym.?.initMetadata(self);
3406 }
33883407 }
33893408
33903409 const appendSect = struct {
......@@ -3462,6 +3481,44 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void {
34623481 appendSect(self, self.zig_bss_sect_index.?, self.zig_bss_seg_index.?);
34633482 }
34643483 }
3484
3485 if (self.base.isRelocatable()) {
3486 {
3487 self.debug_str_sect_index = try self.addSection("__DWARF", "__debug_str", .{
3488 .flags = macho.S_ATTR_DEBUG,
3489 });
3490 try allocSect(self, self.debug_str_sect_index.?, 200);
3491 }
3492
3493 {
3494 self.debug_info_sect_index = try self.addSection("__DWARF", "__debug_info", .{
3495 .flags = macho.S_ATTR_DEBUG,
3496 });
3497 try allocSect(self, self.debug_info_sect_index.?, 200);
3498 }
3499
3500 {
3501 self.debug_abbrev_sect_index = try self.addSection("__DWARF", "__debug_abbrev", .{
3502 .flags = macho.S_ATTR_DEBUG,
3503 });
3504 try allocSect(self, self.debug_abbrev_sect_index.?, 128);
3505 }
3506
3507 {
3508 self.debug_aranges_sect_index = try self.addSection("__DWARF", "__debug_aranges", .{
3509 .alignment = 4,
3510 .flags = macho.S_ATTR_DEBUG,
3511 });
3512 try allocSect(self, self.debug_aranges_sect_index.?, 160);
3513 }
3514
3515 {
3516 self.debug_line_sect_index = try self.addSection("__DWARF", "__debug_line", .{
3517 .flags = macho.S_ATTR_DEBUG,
3518 });
3519 try allocSect(self, self.debug_line_sect_index.?, 250);
3520 }
3521 }
34653522}
34663523
34673524pub 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
35493606 sect.size = needed_size;
35503607}
35513608
3609pub fn markDirty(self: *MachO, sect_index: u8) void {
3610 if (self.getZigObject()) |zo| {
3611 if (self.debug_info_sect_index.? == sect_index) {
3612 zo.debug_info_header_dirty = true;
3613 } else if (self.debug_line_sect_index.? == sect_index) {
3614 zo.debug_line_header_dirty = true;
3615 } else if (self.debug_abbrev_sect_index.? == sect_index) {
3616 zo.debug_abbrev_dirty = true;
3617 } else if (self.debug_str_sect_index.? == sect_index) {
3618 zo.debug_strtab_dirty = true;
3619 } else if (self.debug_aranges_sect_index.? == sect_index) {
3620 zo.debug_aranges_dirty = true;
3621 }
3622 }
3623}
3624
35523625pub fn getTarget(self: MachO) std.Target {
35533626 return self.base.comp.root_mod.resolved_target.result;
35543627}
......@@ -3624,6 +3697,21 @@ pub fn isZigSection(self: MachO, sect_id: u8) bool {
36243697 return false;
36253698}
36263699
3700pub fn isDebugSection(self: MachO, sect_id: u8) bool {
3701 inline for (&[_]?u8{
3702 self.debug_info_sect_index,
3703 self.debug_abbrev_sect_index,
3704 self.debug_str_sect_index,
3705 self.debug_aranges_sect_index,
3706 self.debug_line_sect_index,
3707 }) |maybe_index| {
3708 if (maybe_index) |index| {
3709 if (index == sect_id) return true;
3710 }
3711 }
3712 return false;
3713}
3714
36273715pub fn addSegment(self: *MachO, name: []const u8, opts: struct {
36283716 vmaddr: u64 = 0,
36293717 vmsize: u64 = 0,
src/link/MachO/ZigObject.zig+7-1
......@@ -471,7 +471,13 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO) !void {
471471 self.debug_strtab_dirty = false;
472472 }
473473 } else {
474 // TODO: relocatable
474 const sect_index = macho_file.debug_str_sect_index.?;
475 if (self.debug_strtab_dirty or dw.strtab.buffer.items.len != macho_file.sections.items(.header)[sect_index].size) {
476 const needed_size = @as(u32, @intCast(dw.strtab.buffer.items.len));
477 try macho_file.growSection(sect_index, needed_size);
478 try macho_file.base.file.?.pwriteAll(dw.strtab.buffer.items, macho_file.sections.items(.header)[sect_index].offset);
479 self.debug_strtab_dirty = false;
480 }
475481 }
476482 }
477483