authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-29 20:33:54+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-29 20:33:54+01:00
log3e939e61538706f37abb76a97af0ee77c15b24fc
tree115e68db5a398834f7bf3034275ad5e54a27da04
parentf93a36c091a151ed02602d2f330f7206eb9f95a3
parent78740e55406ebf82371f385bbbf54f224949b8cb
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #18722 from ziglang/macho-debug-info

macho: reinstate DWARF in self-hosted x86_64-macho

9 files changed, 278 insertions(+), 283 deletions(-)

src/link/Dwarf.zig-1
......@@ -1468,7 +1468,6 @@ pub fn commitDeclState(
14681468 .target = reloc.target,
14691469 .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off,
14701470 .addend = 0,
1471 .prev_vaddr = 0,
14721471 });
14731472 },
14741473 .elf => {}, // TODO
src/link/MachO.zig+45-37
......@@ -256,32 +256,39 @@ pub fn createEmpty(
256256 .program_code_size_hint = options.program_code_size_hint,
257257 });
258258
259 // TODO init dwarf
260
261 // if (comp.config.debug_format != .strip) {
262 // // Create dSYM bundle.
263 // log.debug("creating {s}.dSYM bundle", .{emit.sub_path});
264
265 // const d_sym_path = try std.fmt.allocPrint(
266 // arena,
267 // "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF",
268 // .{emit.sub_path},
269 // );
270
271 // var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{});
272 // defer d_sym_bundle.close();
273
274 // const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{
275 // .truncate = false,
276 // .read = true,
277 // });
278
279 // self.d_sym = .{
280 // .allocator = gpa,
281 // .dwarf = link.File.Dwarf.init(&self.base, .dwarf32),
282 // .file = d_sym_file,
283 // };
284 // }
259 switch (comp.config.debug_format) {
260 .strip => {},
261 .dwarf => if (!self.base.isRelocatable()) {
262 // Create dSYM bundle.
263 log.debug("creating {s}.dSYM bundle", .{emit.sub_path});
264
265 const sep = fs.path.sep_str;
266 const d_sym_path = try std.fmt.allocPrint(
267 arena,
268 "{s}.dSYM" ++ sep ++ "Contents" ++ sep ++ "Resources" ++ sep ++ "DWARF",
269 .{emit.sub_path},
270 );
271
272 var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{});
273 defer d_sym_bundle.close();
274
275 const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{
276 .truncate = false,
277 .read = true,
278 });
279
280 self.d_sym = .{
281 .allocator = gpa,
282 .dwarf = link.File.Dwarf.init(&self.base, .dwarf32),
283 .file = d_sym_file,
284 };
285 try self.d_sym.?.initMetadata(self);
286 } else {
287 try self.reportUnexpectedError("TODO: implement generating and emitting __DWARF in .o file", .{});
288 return error.Unexpected;
289 },
290 .code_view => unreachable,
291 }
285292 }
286293 }
287294
......@@ -692,6 +699,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
692699 const ncmds, const sizeofcmds, const uuid_cmd_offset = try self.writeLoadCommands();
693700 try self.writeHeader(ncmds, sizeofcmds);
694701 try self.writeUuid(uuid_cmd_offset, self.requiresCodeSig());
702 if (self.getDebugSymbols()) |dsym| try dsym.flushModule(self);
695703
696704 if (codesig) |*csig| {
697705 try self.writeCodeSignature(csig); // code signing always comes last
......@@ -731,9 +739,6 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
731739 try argv.append("-r");
732740 }
733741
734 try argv.append("-o");
735 try argv.append(full_out_path);
736
737742 if (self.base.isRelocatable()) {
738743 for (comp.objects) |obj| {
739744 try argv.append(obj.path);
......@@ -2047,7 +2052,11 @@ pub fn sortSections(self: *MachO) !void {
20472052 for (&[_]*?u8{
20482053 &self.data_sect_index,
20492054 &self.got_sect_index,
2055 &self.zig_text_sect_index,
20502056 &self.zig_got_sect_index,
2057 &self.zig_const_sect_index,
2058 &self.zig_data_sect_index,
2059 &self.zig_bss_sect_index,
20512060 &self.stubs_sect_index,
20522061 &self.stubs_helper_sect_index,
20532062 &self.la_symbol_ptr_sect_index,
......@@ -2901,16 +2910,16 @@ pub fn writeSymtab(self: *MachO, off: u32) !u32 {
29012910 try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1);
29022911
29032912 if (self.getZigObject()) |zo| {
2904 zo.writeSymtab(self);
2913 zo.writeSymtab(self, self);
29052914 }
29062915 for (self.objects.items) |index| {
2907 try self.getFile(index).?.writeSymtab(self);
2916 try self.getFile(index).?.writeSymtab(self, self);
29082917 }
29092918 for (self.dylibs.items) |index| {
2910 try self.getFile(index).?.writeSymtab(self);
2919 try self.getFile(index).?.writeSymtab(self, self);
29112920 }
29122921 if (self.getInternalObject()) |internal| {
2913 internal.writeSymtab(self);
2922 internal.writeSymtab(self, self);
29142923 }
29152924
29162925 assert(self.strtab.items.len == cmd.strsize);
......@@ -3176,7 +3185,7 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex)
31763185
31773186pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void {
31783187 if (self.llvm_object) |_| return;
3179 return self.getZigObject().?.updateDeclLineNumber(module, decl_index);
3188 return self.getZigObject().?.updateDeclLineNumber(self, module, decl_index);
31803189}
31813190
31823191pub fn updateExports(
......@@ -3909,9 +3918,8 @@ fn reportDuplicates(self: *MachO, dupes: anytype) error{ HasDuplicates, OutOfMem
39093918}
39103919
39113920pub fn getDebugSymbols(self: *MachO) ?*DebugSymbols {
3912 if (self.d_sym) |*ds| {
3913 return ds;
3914 } else return null;
3921 if (self.d_sym) |*ds| return ds;
3922 return null;
39153923}
39163924
39173925pub fn ptraceAttach(self: *MachO, pid: std.os.pid_t) !void {
src/link/MachO/DebugSymbols.zig+117-153
......@@ -3,6 +3,7 @@ dwarf: Dwarf,
33file: fs.File,
44
55symtab_cmd: macho.symtab_command = .{},
6uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 },
67
78segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{},
89sections: std.ArrayListUnmanaged(macho.section_64) = .{},
......@@ -22,9 +23,12 @@ debug_aranges_section_dirty: bool = false,
2223debug_info_header_dirty: bool = false,
2324debug_line_header_dirty: bool = false,
2425
25strtab: StringTable = .{},
2626relocs: std.ArrayListUnmanaged(Reloc) = .{},
2727
28/// Output synthetic sections
29symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{},
30strtab: std.ArrayListUnmanaged(u8) = .{},
31
2832pub const Reloc = struct {
2933 type: enum {
3034 direct_load,
......@@ -33,18 +37,17 @@ pub const Reloc = struct {
3337 target: u32,
3438 offset: u64,
3539 addend: u32,
36 prev_vaddr: u64,
3740};
3841
39/// You must call this function *after* `MachO.populateMissingMetadata()`
42/// You must call this function *after* `ZigObject.initMetadata()`
4043/// has been called to get a viable debug symbols output.
41pub fn populateMissingMetadata(self: *DebugSymbols, macho_file: *MachO) !void {
42 const target = macho_file.base.comp.root_mod.resolved_target.result;
44pub fn initMetadata(self: *DebugSymbols, macho_file: *MachO) !void {
45 try self.strtab.append(self.allocator, 0);
4346
4447 if (self.dwarf_segment_cmd_index == null) {
4548 self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len));
4649
47 const page_size = MachO.getPageSize(target.cpu.arch);
50 const page_size = macho_file.getPageSize();
4851 const off = @as(u64, @intCast(page_size));
4952 const ideal_size: u16 = 200 + 128 + 160 + 250;
5053 const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), page_size);
......@@ -203,35 +206,24 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
203206 // and it corresponds to the Zig source code.
204207 const zcu = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
205208
209 try self.dwarf.flushModule(zcu);
210
206211 for (self.relocs.items) |*reloc| {
207 const sym = switch (reloc.type) {
208 .direct_load => macho_file.getSymbol(.{ .sym_index = reloc.target }),
209 .got_load => blk: {
210 const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?;
211 const got_entry = macho_file.got_table.entries.items[got_index];
212 break :blk macho_file.getSymbol(got_entry);
213 },
214 };
215 if (sym.n_value == reloc.prev_vaddr) continue;
216
217 const sym_name = switch (reloc.type) {
218 .direct_load => macho_file.getSymbolName(.{ .sym_index = reloc.target }),
219 .got_load => blk: {
220 const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?;
221 const got_entry = macho_file.got_table.entries.items[got_index];
222 break :blk macho_file.getSymbolName(got_entry);
223 },
212 const sym = macho_file.getSymbol(reloc.target);
213 const sym_name = sym.getName(macho_file);
214 const addr = switch (reloc.type) {
215 .direct_load => sym.getAddress(.{}, macho_file),
216 .got_load => sym.getGotAddress(macho_file),
224217 };
225218 const sect = &self.sections.items[self.debug_info_section_index.?];
226219 const file_offset = sect.offset + reloc.offset;
227220 log.debug("resolving relocation: {d}@{x} ('{s}') at offset {x}", .{
228221 reloc.target,
229 sym.n_value,
222 addr,
230223 sym_name,
231224 file_offset,
232225 });
233 try self.file.pwriteAll(mem.asBytes(&sym.n_value), file_offset);
234 reloc.prev_vaddr = sym.n_value;
226 try self.file.pwriteAll(mem.asBytes(&addr), file_offset);
235227 }
236228
237229 if (self.debug_abbrev_section_dirty) {
......@@ -242,7 +234,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
242234 if (self.debug_info_header_dirty) {
243235 // Currently only one compilation unit is supported, so the address range is simply
244236 // identical to the main program header virtual address and memory size.
245 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];
237 const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?];
246238 const low_pc = text_section.addr;
247239 const high_pc = text_section.addr + text_section.size;
248240 try self.dwarf.writeDbgInfoHeader(zcu, low_pc, high_pc);
......@@ -252,7 +244,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
252244 if (self.debug_aranges_section_dirty) {
253245 // Currently only one compilation unit is supported, so the address range is simply
254246 // identical to the main program header virtual address and memory size.
255 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];
247 const text_section = macho_file.sections.items(.header)[macho_file.zig_text_sect_index.?];
256248 try self.dwarf.writeDbgAranges(text_section.addr, text_section.size);
257249 self.debug_aranges_section_dirty = false;
258250 }
......@@ -276,17 +268,8 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
276268 try self.writeLinkeditSegmentData(macho_file);
277269
278270 // Write load commands
279 var lc_buffer = std.ArrayList(u8).init(self.allocator);
280 defer lc_buffer.deinit();
281 const lc_writer = lc_buffer.writer();
282
283 try self.writeSegmentHeaders(macho_file, lc_writer);
284 try lc_writer.writeStruct(self.symtab_cmd);
285 try lc_writer.writeStruct(macho_file.uuid_cmd);
286
287 const ncmds = load_commands.calcNumOfLCs(lc_buffer.items);
288 try self.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64));
289 try self.writeHeader(macho_file, ncmds, @as(u32, @intCast(lc_buffer.items.len)));
271 const ncmds, const sizeofcmds = try self.writeLoadCommands(macho_file);
272 try self.writeHeader(macho_file, ncmds, sizeofcmds);
290273
291274 assert(!self.debug_abbrev_section_dirty);
292275 assert(!self.debug_aranges_section_dirty);
......@@ -299,8 +282,9 @@ pub fn deinit(self: *DebugSymbols) void {
299282 self.segments.deinit(gpa);
300283 self.sections.deinit(gpa);
301284 self.dwarf.deinit();
302 self.strtab.deinit(gpa);
303285 self.relocs.deinit(gpa);
286 self.symtab.deinit(gpa);
287 self.strtab.deinit(gpa);
304288}
305289
306290pub fn swapRemoveRelocs(self: *DebugSymbols, target: u32) void {
......@@ -324,7 +308,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
324308 // however at the cost of having LINKEDIT preceed DWARF in dSYM binary which we
325309 // do not want as we want to be able to incrementally move DWARF sections in the
326310 // file as we please.
327 const last_seg = macho_file.getLinkeditSegmentPtr();
311 const last_seg = macho_file.getLinkeditSegment();
328312 break :blk last_seg.vmaddr + last_seg.vmsize;
329313 };
330314 const dwarf_segment = self.getDwarfSegmentPtr();
......@@ -334,8 +318,7 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
334318 file_size = @max(file_size, header.offset + header.size);
335319 }
336320
337 const target = macho_file.base.comp.root_mod.resolved_target.result;
338 const page_size = MachO.getPageSize(target.cpu.arch);
321 const page_size = macho_file.getPageSize();
339322 const aligned_size = mem.alignForward(u64, file_size, page_size);
340323 dwarf_segment.vmaddr = base_vmaddr;
341324 dwarf_segment.filesize = aligned_size;
......@@ -355,54 +338,70 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
355338 log.debug("found __LINKEDIT segment free space at 0x{x}", .{linkedit.fileoff});
356339}
357340
358fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype) !void {
359 // Write segment/section headers from the binary file first.
360 const end = macho_file.linkedit_segment_cmd_index.?;
361 for (macho_file.segments.items[0..end], 0..) |seg, i| {
362 const indexes = macho_file.getSectionIndexes(@as(u8, @intCast(i)));
363 var out_seg = seg;
364 out_seg.fileoff = 0;
365 out_seg.filesize = 0;
366 out_seg.cmdsize = @sizeOf(macho.segment_command_64);
367 out_seg.nsects = 0;
368
369 // Update section headers count; any section with size of 0 is excluded
370 // since it doesn't have any data in the final binary file.
371 for (macho_file.sections.items(.header)[indexes.start..indexes.end]) |header| {
372 if (header.size == 0) continue;
373 out_seg.cmdsize += @sizeOf(macho.section_64);
374 out_seg.nsects += 1;
375 }
341fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, usize } {
342 const gpa = self.allocator;
343 const needed_size = load_commands.calcLoadCommandsSizeDsym(macho_file, self);
344 const buffer = try gpa.alloc(u8, needed_size);
345 defer gpa.free(buffer);
346
347 var stream = std.io.fixedBufferStream(buffer);
348 var cwriter = std.io.countingWriter(stream.writer());
349 const writer = cwriter.writer();
376350
377 if (out_seg.nsects == 0 and
378 (mem.eql(u8, out_seg.segName(), "__DATA_CONST") or
379 mem.eql(u8, out_seg.segName(), "__DATA"))) continue;
351 var ncmds: usize = 0;
380352
381 try writer.writeStruct(out_seg);
382 for (macho_file.sections.items(.header)[indexes.start..indexes.end]) |header| {
383 if (header.size == 0) continue;
384 var out_header = header;
385 out_header.offset = 0;
386 try writer.writeStruct(out_header);
353 // UUID comes first presumably to speed up lookup by the consumer like lldb.
354 @memcpy(&self.uuid_cmd.uuid, &macho_file.uuid_cmd.uuid);
355 try writer.writeStruct(self.uuid_cmd);
356 ncmds += 1;
357
358 // Segment and section load commands
359 {
360 // Write segment/section headers from the binary file first.
361 const slice = macho_file.sections.slice();
362 var sect_id: usize = 0;
363 for (macho_file.segments.items, 0..) |seg, seg_id| {
364 if (seg_id == macho_file.linkedit_seg_index.?) break;
365 var out_seg = seg;
366 out_seg.fileoff = 0;
367 out_seg.filesize = 0;
368 try writer.writeStruct(out_seg);
369 for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| {
370 var out_header = header;
371 out_header.offset = 0;
372 try writer.writeStruct(out_header);
373 }
374 sect_id += seg.nsects;
387375 }
388 }
389 // Next, commit DSYM's __LINKEDIT and __DWARF segments headers.
390 for (self.segments.items, 0..) |seg, i| {
391 const indexes = self.getSectionIndexes(@as(u8, @intCast(i)));
392 try writer.writeStruct(seg);
393 for (self.sections.items[indexes.start..indexes.end]) |header| {
394 try writer.writeStruct(header);
376 ncmds += macho_file.segments.items.len - 1;
377
378 // Next, commit DSYM's __LINKEDIT and __DWARF segments headers.
379 sect_id = 0;
380 for (self.segments.items) |seg| {
381 try writer.writeStruct(seg);
382 for (self.sections.items[sect_id..][0..seg.nsects]) |header| {
383 try writer.writeStruct(header);
384 }
385 sect_id += seg.nsects;
395386 }
387 ncmds += self.segments.items.len;
396388 }
397}
398389
399fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void {
400 const target = macho_file.base.comp.root_mod.resolved_target.result;
390 try writer.writeStruct(self.symtab_cmd);
391 ncmds += 1;
392
393 assert(cwriter.bytes_written == needed_size);
401394
395 try self.file.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
396
397 return .{ ncmds, buffer.len };
398}
399
400fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void {
402401 var header: macho.mach_header_64 = .{};
403402 header.filetype = macho.MH_DSYM;
404403
405 switch (target.cpu.arch) {
404 switch (macho_file.getTarget().cpu.arch) {
406405 .aarch64 => {
407406 header.cputype = macho.CPU_TYPE_ARM64;
408407 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
......@@ -414,8 +413,8 @@ fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds:
414413 else => return error.UnsupportedCpuArchitecture,
415414 }
416415
417 header.ncmds = ncmds;
418 header.sizeofcmds = sizeofcmds;
416 header.ncmds = @intCast(ncmds);
417 header.sizeofcmds = @intCast(sizeofcmds);
419418
420419 log.debug("writing Mach-O header {}", .{header});
421420
......@@ -437,91 +436,56 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void {
437436 const tracy = trace(@src());
438437 defer tracy.end();
439438
440 try self.writeSymtab(macho_file);
441 try self.writeStrtab();
442
443 const target = macho_file.base.comp.root_mod.resolved_target.result;
444 const page_size = MachO.getPageSize(target.cpu.arch);
439 const page_size = macho_file.getPageSize();
445440 const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];
441
442 var off = math.cast(u32, seg.fileoff) orelse return error.Overflow;
443 off = try self.writeSymtab(off, macho_file);
444 off = mem.alignForward(u32, off, @alignOf(u64));
445 off = try self.writeStrtab(off);
446 seg.filesize = off - seg.fileoff;
447
446448 const aligned_size = mem.alignForward(u64, seg.filesize, page_size);
447449 seg.vmsize = aligned_size;
448450}
449451
450fn writeSymtab(self: *DebugSymbols, macho_file: *MachO) !void {
452pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 {
451453 const tracy = trace(@src());
452454 defer tracy.end();
453
454455 const gpa = self.allocator;
456 const cmd = &self.symtab_cmd;
457 cmd.nsyms = macho_file.symtab_cmd.nsyms;
458 cmd.strsize = macho_file.symtab_cmd.strsize;
459 cmd.symoff = off;
455460
456 var locals = std.ArrayList(macho.nlist_64).init(gpa);
457 defer locals.deinit();
458
459 for (macho_file.locals.items, 0..) |sym, sym_id| {
460 if (sym.n_strx == 0) continue; // no name, skip
461 const sym_loc = MachO.SymbolWithLoc{ .sym_index = @as(u32, @intCast(sym_id)) };
462 if (macho_file.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip
463 if (macho_file.getGlobal(macho_file.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip
464 var out_sym = sym;
465 out_sym.n_strx = try self.strtab.insert(gpa, macho_file.getSymbolName(sym_loc));
466 try locals.append(out_sym);
467 }
461 try self.symtab.resize(gpa, cmd.nsyms);
462 try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1);
468463
469 var exports = std.ArrayList(macho.nlist_64).init(gpa);
470 defer exports.deinit();
471
472 for (macho_file.globals.items) |global| {
473 const sym = macho_file.getSymbol(global);
474 if (sym.undf()) continue; // import, skip
475 var out_sym = sym;
476 out_sym.n_strx = try self.strtab.insert(gpa, macho_file.getSymbolName(global));
477 try exports.append(out_sym);
464 if (macho_file.getZigObject()) |zo| {
465 zo.writeSymtab(macho_file, self);
466 }
467 for (macho_file.objects.items) |index| {
468 try macho_file.getFile(index).?.writeSymtab(macho_file, self);
469 }
470 for (macho_file.dylibs.items) |index| {
471 try macho_file.getFile(index).?.writeSymtab(macho_file, self);
472 }
473 if (macho_file.getInternalObject()) |internal| {
474 internal.writeSymtab(macho_file, self);
478475 }
479476
480 const nlocals = locals.items.len;
481 const nexports = exports.items.len;
482 const nsyms = nlocals + nexports;
483
484 const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];
485 const offset = mem.alignForward(u64, seg.fileoff, @alignOf(macho.nlist_64));
486 const needed_size = nsyms * @sizeOf(macho.nlist_64);
487 seg.filesize = offset + needed_size - seg.fileoff;
488
489 self.symtab_cmd.symoff = @as(u32, @intCast(offset));
490 self.symtab_cmd.nsyms = @as(u32, @intCast(nsyms));
491
492 const locals_off = @as(u32, @intCast(offset));
493 const locals_size = nlocals * @sizeOf(macho.nlist_64);
494 const exports_off = locals_off + locals_size;
495 const exports_size = nexports * @sizeOf(macho.nlist_64);
477 assert(self.strtab.items.len == cmd.strsize);
496478
497 log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off });
498 try self.file.pwriteAll(mem.sliceAsBytes(locals.items), locals_off);
479 try self.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);
499480
500 log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off });
501 try self.file.pwriteAll(mem.sliceAsBytes(exports.items), exports_off);
481 return off + cmd.nsyms * @sizeOf(macho.nlist_64);
502482}
503483
504fn writeStrtab(self: *DebugSymbols) !void {
505 const tracy = trace(@src());
506 defer tracy.end();
507
508 const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];
509 const symtab_size = @as(u32, @intCast(self.symtab_cmd.nsyms * @sizeOf(macho.nlist_64)));
510 const offset = mem.alignForward(u64, self.symtab_cmd.symoff + symtab_size, @alignOf(u64));
511 const needed_size = mem.alignForward(u64, self.strtab.buffer.items.len, @alignOf(u64));
512
513 seg.filesize = offset + needed_size - seg.fileoff;
514 self.symtab_cmd.stroff = @as(u32, @intCast(offset));
515 self.symtab_cmd.strsize = @as(u32, @intCast(needed_size));
516
517 log.debug("writing string table from 0x{x} to 0x{x}", .{ offset, offset + needed_size });
518
519 try self.file.pwriteAll(self.strtab.buffer.items, offset);
520
521 if (self.strtab.buffer.items.len < needed_size) {
522 // Ensure we are always padded to the actual length of the file.
523 try self.file.pwriteAll(&[_]u8{0}, offset + needed_size);
524 }
484pub fn writeStrtab(self: *DebugSymbols, off: u32) !u32 {
485 const cmd = &self.symtab_cmd;
486 cmd.stroff = off;
487 try self.file.pwriteAll(self.strtab.items, cmd.stroff);
488 return off + cmd.strsize;
525489}
526490
527491pub fn getSectionIndexes(self: *DebugSymbols, segment_index: u8) struct { start: u8, end: u8 } {
......@@ -561,7 +525,7 @@ const assert = std.debug.assert;
561525const fs = std.fs;
562526const link = @import("../../link.zig");
563527const load_commands = @import("load_commands.zig");
564const log = std.log.scoped(.dsym);
528const log = std.log.scoped(.link_dsym);
565529const macho = std.macho;
566530const makeStaticString = MachO.makeStaticString;
567531const math = std.math;
src/link/MachO/Dylib.zig+5-5
......@@ -576,7 +576,7 @@ pub fn calcSymtabSize(self: *Dylib, macho_file: *MachO) !void {
576576 }
577577}
578578
579pub fn writeSymtab(self: Dylib, macho_file: *MachO) void {
579pub fn writeSymtab(self: Dylib, macho_file: *MachO, ctx: anytype) void {
580580 const tracy = trace(@src());
581581 defer tracy.end();
582582
......@@ -585,10 +585,10 @@ pub fn writeSymtab(self: Dylib, macho_file: *MachO) void {
585585 const file = global.getFile(macho_file) orelse continue;
586586 if (file.getIndex() != self.index) continue;
587587 const idx = global.getOutputSymtabIndex(macho_file) orelse continue;
588 const n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
589 macho_file.strtab.appendSliceAssumeCapacity(global.getName(macho_file));
590 macho_file.strtab.appendAssumeCapacity(0);
591 const out_sym = &macho_file.symtab.items[idx];
588 const n_strx = @as(u32, @intCast(ctx.strtab.items.len));
589 ctx.strtab.appendSliceAssumeCapacity(global.getName(macho_file));
590 ctx.strtab.appendAssumeCapacity(0);
591 const out_sym = &ctx.symtab.items[idx];
592592 out_sym.n_strx = n_strx;
593593 global.setOutputSym(macho_file, out_sym);
594594 }
src/link/MachO/InternalObject.zig+5-5
......@@ -139,15 +139,15 @@ pub fn calcSymtabSize(self: *InternalObject, macho_file: *MachO) !void {
139139 }
140140}
141141
142pub fn writeSymtab(self: InternalObject, macho_file: *MachO) void {
142pub fn writeSymtab(self: InternalObject, macho_file: *MachO, ctx: anytype) void {
143143 for (self.symbols.items) |sym_index| {
144144 const sym = macho_file.getSymbol(sym_index);
145145 if (sym.getFile(macho_file)) |file| if (file.getIndex() != self.index) continue;
146146 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
147 const n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
148 macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file));
149 macho_file.strtab.appendAssumeCapacity(0);
150 const out_sym = &macho_file.symtab.items[idx];
147 const n_strx = @as(u32, @intCast(ctx.strtab.items.len));
148 ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file));
149 ctx.strtab.appendAssumeCapacity(0);
150 const out_sym = &ctx.symtab.items[idx];
151151 out_sym.n_strx = n_strx;
152152 sym.setOutputSym(macho_file, out_sym);
153153 }
src/link/MachO/Object.zig+51-51
......@@ -1320,7 +1320,7 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void {
13201320 }
13211321}
13221322
1323pub fn writeSymtab(self: Object, macho_file: *MachO) error{Overflow}!void {
1323pub fn writeSymtab(self: Object, macho_file: *MachO, ctx: anytype) error{Overflow}!void {
13241324 const tracy = trace(@src());
13251325 defer tracy.end();
13261326
......@@ -1329,19 +1329,19 @@ pub fn writeSymtab(self: Object, macho_file: *MachO) error{Overflow}!void {
13291329 const file = sym.getFile(macho_file) orelse continue;
13301330 if (file.getIndex() != self.index) continue;
13311331 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
1332 const n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
1333 macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file));
1334 macho_file.strtab.appendAssumeCapacity(0);
1335 const out_sym = &macho_file.symtab.items[idx];
1332 const n_strx = @as(u32, @intCast(ctx.strtab.items.len));
1333 ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file));
1334 ctx.strtab.appendAssumeCapacity(0);
1335 const out_sym = &ctx.symtab.items[idx];
13361336 out_sym.n_strx = n_strx;
13371337 sym.setOutputSym(macho_file, out_sym);
13381338 }
13391339
13401340 if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo())
1341 try self.writeStabs(macho_file);
1341 try self.writeStabs(macho_file, ctx);
13421342}
13431343
1344pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void {
1344pub fn writeStabs(self: *const Object, macho_file: *MachO, ctx: anytype) error{Overflow}!void {
13451345 const writeFuncStab = struct {
13461346 inline fn writeFuncStab(
13471347 n_strx: u32,
......@@ -1349,30 +1349,30 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
13491349 n_value: u64,
13501350 size: u64,
13511351 index: u32,
1352 ctx: *MachO,
1352 context: anytype,
13531353 ) void {
1354 ctx.symtab.items[index] = .{
1354 context.symtab.items[index] = .{
13551355 .n_strx = 0,
13561356 .n_type = macho.N_BNSYM,
13571357 .n_sect = n_sect,
13581358 .n_desc = 0,
13591359 .n_value = n_value,
13601360 };
1361 ctx.symtab.items[index + 1] = .{
1361 context.symtab.items[index + 1] = .{
13621362 .n_strx = n_strx,
13631363 .n_type = macho.N_FUN,
13641364 .n_sect = n_sect,
13651365 .n_desc = 0,
13661366 .n_value = n_value,
13671367 };
1368 ctx.symtab.items[index + 2] = .{
1368 context.symtab.items[index + 2] = .{
13691369 .n_strx = 0,
13701370 .n_type = macho.N_FUN,
13711371 .n_sect = 0,
13721372 .n_desc = 0,
13731373 .n_value = size,
13741374 };
1375 ctx.symtab.items[index + 3] = .{
1375 context.symtab.items[index + 3] = .{
13761376 .n_strx = 0,
13771377 .n_type = macho.N_ENSYM,
13781378 .n_sect = n_sect,
......@@ -1392,10 +1392,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
13921392
13931393 // Open scope
13941394 // N_SO comp_dir
1395 var n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
1396 macho_file.strtab.appendSliceAssumeCapacity(comp_dir);
1397 macho_file.strtab.appendAssumeCapacity(0);
1398 macho_file.symtab.items[index] = .{
1395 var n_strx = @as(u32, @intCast(ctx.strtab.items.len));
1396 ctx.strtab.appendSliceAssumeCapacity(comp_dir);
1397 ctx.strtab.appendAssumeCapacity(0);
1398 ctx.symtab.items[index] = .{
13991399 .n_strx = n_strx,
14001400 .n_type = macho.N_SO,
14011401 .n_sect = 0,
......@@ -1404,10 +1404,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
14041404 };
14051405 index += 1;
14061406 // N_SO tu_name
1407 n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
1408 macho_file.strtab.appendSliceAssumeCapacity(tu_name);
1409 macho_file.strtab.appendAssumeCapacity(0);
1410 macho_file.symtab.items[index] = .{
1407 n_strx = @as(u32, @intCast(ctx.strtab.items.len));
1408 ctx.strtab.appendSliceAssumeCapacity(tu_name);
1409 ctx.strtab.appendAssumeCapacity(0);
1410 ctx.symtab.items[index] = .{
14111411 .n_strx = n_strx,
14121412 .n_type = macho.N_SO,
14131413 .n_sect = 0,
......@@ -1416,18 +1416,18 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
14161416 };
14171417 index += 1;
14181418 // N_OSO path
1419 n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
1419 n_strx = @as(u32, @intCast(ctx.strtab.items.len));
14201420 if (self.archive) |ar| {
1421 macho_file.strtab.appendSliceAssumeCapacity(ar.path);
1422 macho_file.strtab.appendAssumeCapacity('(');
1423 macho_file.strtab.appendSliceAssumeCapacity(self.path);
1424 macho_file.strtab.appendAssumeCapacity(')');
1425 macho_file.strtab.appendAssumeCapacity(0);
1421 ctx.strtab.appendSliceAssumeCapacity(ar.path);
1422 ctx.strtab.appendAssumeCapacity('(');
1423 ctx.strtab.appendSliceAssumeCapacity(self.path);
1424 ctx.strtab.appendAssumeCapacity(')');
1425 ctx.strtab.appendAssumeCapacity(0);
14261426 } else {
1427 macho_file.strtab.appendSliceAssumeCapacity(self.path);
1428 macho_file.strtab.appendAssumeCapacity(0);
1427 ctx.strtab.appendSliceAssumeCapacity(self.path);
1428 ctx.strtab.appendAssumeCapacity(0);
14291429 }
1430 macho_file.symtab.items[index] = .{
1430 ctx.symtab.items[index] = .{
14311431 .n_strx = n_strx,
14321432 .n_type = macho.N_OSO,
14331433 .n_sect = 0,
......@@ -1448,17 +1448,17 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
14481448 const sect = macho_file.sections.items(.header)[sym.out_n_sect];
14491449 const sym_n_strx = n_strx: {
14501450 const symtab_index = sym.getOutputSymtabIndex(macho_file).?;
1451 const osym = macho_file.symtab.items[symtab_index];
1451 const osym = ctx.symtab.items[symtab_index];
14521452 break :n_strx osym.n_strx;
14531453 };
14541454 const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.out_n_sect + 1) else 0;
14551455 const sym_n_value = sym.getAddress(.{}, macho_file);
14561456 const sym_size = sym.getSize(macho_file);
14571457 if (sect.isCode()) {
1458 writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, macho_file);
1458 writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx);
14591459 index += 4;
14601460 } else if (sym.visibility == .global) {
1461 macho_file.symtab.items[index] = .{
1461 ctx.symtab.items[index] = .{
14621462 .n_strx = sym_n_strx,
14631463 .n_type = macho.N_GSYM,
14641464 .n_sect = sym_n_sect,
......@@ -1467,7 +1467,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
14671467 };
14681468 index += 1;
14691469 } else {
1470 macho_file.symtab.items[index] = .{
1470 ctx.symtab.items[index] = .{
14711471 .n_strx = sym_n_strx,
14721472 .n_type = macho.N_STSYM,
14731473 .n_sect = sym_n_sect,
......@@ -1480,7 +1480,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
14801480
14811481 // Close scope
14821482 // N_SO
1483 macho_file.symtab.items[index] = .{
1483 ctx.symtab.items[index] = .{
14841484 .n_strx = 0,
14851485 .n_type = macho.N_SO,
14861486 .n_sect = 0,
......@@ -1493,10 +1493,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
14931493 for (self.stab_files.items) |sf| {
14941494 // Open scope
14951495 // N_SO comp_dir
1496 var n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
1497 macho_file.strtab.appendSliceAssumeCapacity(sf.getCompDir(self));
1498 macho_file.strtab.appendAssumeCapacity(0);
1499 macho_file.symtab.items[index] = .{
1496 var n_strx = @as(u32, @intCast(ctx.strtab.items.len));
1497 ctx.strtab.appendSliceAssumeCapacity(sf.getCompDir(self));
1498 ctx.strtab.appendAssumeCapacity(0);
1499 ctx.symtab.items[index] = .{
15001500 .n_strx = n_strx,
15011501 .n_type = macho.N_SO,
15021502 .n_sect = 0,
......@@ -1505,10 +1505,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
15051505 };
15061506 index += 1;
15071507 // N_SO tu_name
1508 n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
1509 macho_file.strtab.appendSliceAssumeCapacity(sf.getTuName(self));
1510 macho_file.strtab.appendAssumeCapacity(0);
1511 macho_file.symtab.items[index] = .{
1508 n_strx = @as(u32, @intCast(ctx.strtab.items.len));
1509 ctx.strtab.appendSliceAssumeCapacity(sf.getTuName(self));
1510 ctx.strtab.appendAssumeCapacity(0);
1511 ctx.symtab.items[index] = .{
15121512 .n_strx = n_strx,
15131513 .n_type = macho.N_SO,
15141514 .n_sect = 0,
......@@ -1517,10 +1517,10 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
15171517 };
15181518 index += 1;
15191519 // N_OSO path
1520 n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
1521 macho_file.strtab.appendSliceAssumeCapacity(sf.getOsoPath(self));
1522 macho_file.strtab.appendAssumeCapacity(0);
1523 macho_file.symtab.items[index] = .{
1520 n_strx = @as(u32, @intCast(ctx.strtab.items.len));
1521 ctx.strtab.appendSliceAssumeCapacity(sf.getOsoPath(self));
1522 ctx.strtab.appendAssumeCapacity(0);
1523 ctx.symtab.items[index] = .{
15241524 .n_strx = n_strx,
15251525 .n_type = macho.N_OSO,
15261526 .n_sect = 0,
......@@ -1536,7 +1536,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
15361536 if (!sym.flags.output_symtab) continue;
15371537 const sym_n_strx = n_strx: {
15381538 const symtab_index = sym.getOutputSymtabIndex(macho_file).?;
1539 const osym = macho_file.symtab.items[symtab_index];
1539 const osym = ctx.symtab.items[symtab_index];
15401540 break :n_strx osym.n_strx;
15411541 };
15421542 const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.out_n_sect + 1) else 0;
......@@ -1544,11 +1544,11 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
15441544 const sym_size = sym.getSize(macho_file);
15451545 switch (stab.tag) {
15461546 .func => {
1547 writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, macho_file);
1547 writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx);
15481548 index += 4;
15491549 },
15501550 .global => {
1551 macho_file.symtab.items[index] = .{
1551 ctx.symtab.items[index] = .{
15521552 .n_strx = sym_n_strx,
15531553 .n_type = macho.N_GSYM,
15541554 .n_sect = sym_n_sect,
......@@ -1558,7 +1558,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
15581558 index += 1;
15591559 },
15601560 .static => {
1561 macho_file.symtab.items[index] = .{
1561 ctx.symtab.items[index] = .{
15621562 .n_strx = sym_n_strx,
15631563 .n_type = macho.N_STSYM,
15641564 .n_sect = sym_n_sect,
......@@ -1572,7 +1572,7 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void
15721572
15731573 // Close scope
15741574 // N_SO
1575 macho_file.symtab.items[index] = .{
1575 ctx.symtab.items[index] = .{
15761576 .n_strx = 0,
15771577 .n_type = macho.N_SO,
15781578 .n_sect = 0,
src/link/MachO/ZigObject.zig+31-29
......@@ -310,7 +310,7 @@ pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void {
310310 }
311311}
312312
313pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void {
313pub fn writeSymtab(self: ZigObject, macho_file: *MachO, ctx: anytype) void {
314314 const tracy = trace(@src());
315315 defer tracy.end();
316316
......@@ -319,10 +319,10 @@ pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void {
319319 const file = sym.getFile(macho_file) orelse continue;
320320 if (file.getIndex() != self.index) continue;
321321 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
322 const n_strx = @as(u32, @intCast(macho_file.strtab.items.len));
323 macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file));
324 macho_file.strtab.appendAssumeCapacity(0);
325 const out_sym = &macho_file.symtab.items[idx];
322 const n_strx = @as(u32, @intCast(ctx.strtab.items.len));
323 ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file));
324 ctx.strtab.appendAssumeCapacity(0);
325 const out_sym = &ctx.symtab.items[idx];
326326 out_sym.n_strx = n_strx;
327327 sym.setOutputSym(macho_file, out_sym);
328328 }
......@@ -531,7 +531,7 @@ pub fn updateFunc(
531531 var code_buffer = std.ArrayList(u8).init(gpa);
532532 defer code_buffer.deinit();
533533
534 var decl_state: ?Dwarf.DeclState = null; // TODO: Dwarf
534 var decl_state: ?Dwarf.DeclState = if (macho_file.getDebugSymbols()) |d_sym| try d_sym.dwarf.initDeclState(mod, decl_index) else null;
535535 defer if (decl_state) |*ds| ds.deinit();
536536
537537 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
......@@ -557,16 +557,16 @@ pub fn updateFunc(
557557 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);
558558 try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code);
559559
560 // if (decl_state) |*ds| {
561 // const sym = elf_file.symbol(sym_index);
562 // try self.dwarf.?.commitDeclState(
563 // mod,
564 // decl_index,
565 // sym.value,
566 // sym.atom(elf_file).?.size,
567 // ds,
568 // );
569 // }
560 if (decl_state) |*ds| {
561 const sym = macho_file.getSymbol(sym_index);
562 try macho_file.getDebugSymbols().?.dwarf.commitDeclState(
563 mod,
564 decl_index,
565 sym.getAddress(.{}, macho_file),
566 sym.getAtom(macho_file).?.size,
567 ds,
568 );
569 }
570570
571571 // Since we updated the vaddr and the size, each corresponding export
572572 // symbol also needs to be updated.
......@@ -606,7 +606,7 @@ pub fn updateDecl(
606606 var code_buffer = std.ArrayList(u8).init(gpa);
607607 defer code_buffer.deinit();
608608
609 var decl_state: ?Dwarf.DeclState = null; // TODO: Dwarf
609 var decl_state: ?Dwarf.DeclState = if (macho_file.getDebugSymbols()) |d_sym| try d_sym.dwarf.initDeclState(mod, decl_index) else null;
610610 defer if (decl_state) |*ds| ds.deinit();
611611
612612 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
......@@ -638,15 +638,16 @@ pub fn updateDecl(
638638 try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code);
639639 }
640640
641 // if (decl_state) |*ds| {
642 // try self.d_sym.?.dwarf.commitDeclState(
643 // mod,
644 // decl_index,
645 // addr,
646 // self.getAtom(atom_index).size,
647 // ds,
648 // );
649 // }
641 if (decl_state) |*ds| {
642 const sym = macho_file.getSymbol(sym_index);
643 try macho_file.getDebugSymbols().?.dwarf.commitDeclState(
644 mod,
645 decl_index,
646 sym.getAddress(.{}, macho_file),
647 sym.getAtom(macho_file).?.size,
648 ds,
649 );
650 }
650651
651652 // Since we updated the vaddr and the size, each corresponding export symbol also
652653 // needs to be updated.
......@@ -1220,13 +1221,14 @@ fn updateLazySymbol(
12201221/// Must be called only after a successful call to `updateDecl`.
12211222pub fn updateDeclLineNumber(
12221223 self: *ZigObject,
1224 macho_file: *MachO,
12231225 mod: *Module,
12241226 decl_index: InternPool.DeclIndex,
12251227) !void {
12261228 _ = self;
1227 _ = mod;
1228 _ = decl_index;
1229 // TODO: Dwarf
1229 if (macho_file.getDebugSymbols()) |d_sym| {
1230 try d_sym.dwarf.updateDeclLineNumber(mod, decl_index);
1231 }
12301232}
12311233
12321234pub fn deleteDeclExport(
src/link/MachO/file.zig+2-2
......@@ -90,9 +90,9 @@ pub const File = union(enum) {
9090 };
9191 }
9292
93 pub fn writeSymtab(file: File, macho_file: *MachO) !void {
93 pub fn writeSymtab(file: File, macho_file: *MachO, ctx: anytype) !void {
9494 return switch (file) {
95 inline else => |x| x.writeSymtab(macho_file),
95 inline else => |x| x.writeSymtab(macho_file, ctx),
9696 };
9797 }
9898
src/link/MachO/load_commands.zig+22
......@@ -5,6 +5,7 @@ const macho = std.macho;
55const mem = std.mem;
66
77const Allocator = mem.Allocator;
8const DebugSymbols = @import("DebugSymbols.zig");
89const Dylib = @import("Dylib.zig");
910const MachO = @import("../MachO.zig");
1011
......@@ -97,6 +98,27 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) u32 {
9798 return @as(u32, @intCast(sizeofcmds));
9899}
99100
101pub fn calcLoadCommandsSizeDsym(macho_file: *MachO, dsym: *const DebugSymbols) u32 {
102 var sizeofcmds: u64 = 0;
103
104 // LC_SEGMENT_64
105 sizeofcmds += @sizeOf(macho.segment_command_64) * (macho_file.segments.items.len - 1);
106 for (macho_file.segments.items) |seg| {
107 sizeofcmds += seg.nsects * @sizeOf(macho.section_64);
108 }
109 sizeofcmds += @sizeOf(macho.segment_command_64) * dsym.segments.items.len;
110 for (dsym.segments.items) |seg| {
111 sizeofcmds += seg.nsects * @sizeOf(macho.section_64);
112 }
113
114 // LC_SYMTAB
115 sizeofcmds += @sizeOf(macho.symtab_command);
116 // LC_UUID
117 sizeofcmds += @sizeOf(macho.uuid_command);
118
119 return @as(u32, @intCast(sizeofcmds));
120}
121
100122pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 {
101123 var sizeofcmds: u64 = 0;
102124