authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-04 13:05:42+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-04 16:58:45+01:00
logaa8b26cf25c0d0e5e50d51f993147be8773a9c1e
tree95fa03ffc9fca856de5ea716691350f6463455c5
parentd67de87baa9ebc45f51e3a83fed761e03367f904

dsym: refactor API - do not store ptr to MachO


3 files changed, 85 insertions(+), 72 deletions(-)

src/link/Dwarf.zig+1-1
...@@ -1318,7 +1318,7 @@ pub fn commitDeclState(...@@ -1318,7 +1318,7 @@ pub fn commitDeclState(
1318 .macho => {1318 .macho => {
1319 const macho_file = file.cast(File.MachO).?;1319 const macho_file = file.cast(File.MachO).?;
1320 const d_sym = &macho_file.d_sym.?;1320 const d_sym = &macho_file.d_sym.?;
1321 try d_sym.relocs.append(d_sym.base.base.allocator, .{1321 try d_sym.relocs.append(d_sym.allocator, .{
1322 .type = switch (reloc.type) {1322 .type = switch (reloc.type) {
1323 .direct_load => .direct_load,1323 .direct_load => .direct_load,
1324 .got_load => .got_load,1324 .got_load => .got_load,
src/link/MachO.zig+5-4
...@@ -347,9 +347,10 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {...@@ -347,9 +347,10 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
347 });347 });
348348
349 self.d_sym = .{349 self.d_sym = .{
350 .base = self,350 .allocator = allocator,
351 .dwarf = link.File.Dwarf.init(allocator, .macho, options.target),351 .dwarf = link.File.Dwarf.init(allocator, .macho, options.target),
352 .file = d_sym_file,352 .file = d_sym_file,
353 .page_size = self.page_size,
353 };354 };
354 }355 }
355356
...@@ -366,7 +367,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {...@@ -366,7 +367,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
366 try self.populateMissingMetadata();367 try self.populateMissingMetadata();
367368
368 if (self.d_sym) |*d_sym| {369 if (self.d_sym) |*d_sym| {
369 try d_sym.populateMissingMetadata(allocator);370 try d_sym.populateMissingMetadata();
370 }371 }
371372
372 return self;373 return self;
...@@ -629,7 +630,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -629,7 +630,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
629630
630 if (self.d_sym) |*d_sym| {631 if (self.d_sym) |*d_sym| {
631 // Flush debug symbols bundle.632 // Flush debug symbols bundle.
632 try d_sym.flushModule(self.base.allocator, self.base.options);633 try d_sym.flushModule(self);
633 }634 }
634635
635 // if (build_options.enable_link_snapshots) {636 // if (build_options.enable_link_snapshots) {
...@@ -1900,7 +1901,7 @@ pub fn deinit(self: *MachO) void {...@@ -1900,7 +1901,7 @@ pub fn deinit(self: *MachO) void {
1900 }1901 }
19011902
1902 if (self.d_sym) |*d_sym| {1903 if (self.d_sym) |*d_sym| {
1903 d_sym.deinit(gpa);1904 d_sym.deinit();
1904 }1905 }
19051906
1906 self.got_entries.deinit(gpa);1907 self.got_entries.deinit(gpa);
src/link/MachO/DebugSymbols.zig+79-67
...@@ -20,9 +20,10 @@ const Module = @import("../../Module.zig");...@@ -20,9 +20,10 @@ const Module = @import("../../Module.zig");
20const StringTable = @import("../strtab.zig").StringTable;20const StringTable = @import("../strtab.zig").StringTable;
21const Type = @import("../../type.zig").Type;21const Type = @import("../../type.zig").Type;
2222
23base: *MachO,23allocator: Allocator,
24dwarf: Dwarf,24dwarf: Dwarf,
25file: fs.File,25file: fs.File,
26page_size: u16,
2627
27segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{},28segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{},
28sections: std.ArrayListUnmanaged(macho.section_64) = .{},29sections: std.ArrayListUnmanaged(macho.section_64) = .{},
...@@ -59,21 +60,17 @@ pub const Reloc = struct {...@@ -59,21 +60,17 @@ pub const Reloc = struct {
5960
60/// You must call this function *after* `MachO.populateMissingMetadata()`61/// You must call this function *after* `MachO.populateMissingMetadata()`
61/// has been called to get a viable debug symbols output.62/// has been called to get a viable debug symbols output.
62pub fn populateMissingMetadata(self: *DebugSymbols, gpa: Allocator) !void {63pub fn populateMissingMetadata(self: *DebugSymbols) !void {
63 if (self.dwarf_segment_cmd_index == null) {64 if (self.dwarf_segment_cmd_index == null) {
64 self.dwarf_segment_cmd_index = @intCast(u8, self.segments.items.len);65 self.dwarf_segment_cmd_index = @intCast(u8, self.segments.items.len);
6566
66 const off = @intCast(u64, self.base.page_size);67 const off = @intCast(u64, self.page_size);
67 const ideal_size: u16 = 200 + 128 + 160 + 250;68 const ideal_size: u16 = 200 + 128 + 160 + 250;
68 const needed_size = mem.alignForwardGeneric(69 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
69 u64,
70 padToIdeal(ideal_size),
71 self.base.page_size,
72 );
7370
74 log.debug("found __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });71 log.debug("found __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });
7572
76 try self.segments.append(gpa, .{73 try self.segments.append(self.allocator, .{
77 .segname = makeStaticString("__DWARF"),74 .segname = makeStaticString("__DWARF"),
78 .vmsize = needed_size,75 .vmsize = needed_size,
79 .fileoff = off,76 .fileoff = off,
...@@ -114,7 +111,7 @@ pub fn populateMissingMetadata(self: *DebugSymbols, gpa: Allocator) !void {...@@ -114,7 +111,7 @@ pub fn populateMissingMetadata(self: *DebugSymbols, gpa: Allocator) !void {
114111
115 if (self.linkedit_segment_cmd_index == null) {112 if (self.linkedit_segment_cmd_index == null) {
116 self.linkedit_segment_cmd_index = @intCast(u8, self.segments.items.len);113 self.linkedit_segment_cmd_index = @intCast(u8, self.segments.items.len);
117 try self.segments.append(gpa, .{114 try self.segments.append(self.allocator, .{
118 .segname = makeStaticString("__LINKEDIT"),115 .segname = makeStaticString("__LINKEDIT"),
119 .maxprot = macho.PROT.READ,116 .maxprot = macho.PROT.READ,
120 .initprot = macho.PROT.READ,117 .initprot = macho.PROT.READ,
...@@ -124,8 +121,6 @@ pub fn populateMissingMetadata(self: *DebugSymbols, gpa: Allocator) !void {...@@ -124,8 +121,6 @@ pub fn populateMissingMetadata(self: *DebugSymbols, gpa: Allocator) !void {
124}121}
125122
126fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignment: u16) !u8 {123fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignment: u16) !u8 {
127 const gpa = self.base.base.allocator;
128
129 const segment = self.getDwarfSegmentPtr();124 const segment = self.getDwarfSegmentPtr();
130 var sect = macho.section_64{125 var sect = macho.section_64{
131 .sectname = makeStaticString(sectname),126 .sectname = makeStaticString(sectname),
...@@ -147,7 +142,7 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme...@@ -147,7 +142,7 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme
147 sect.offset = @intCast(u32, off);142 sect.offset = @intCast(u32, off);
148143
149 const index = @intCast(u8, self.sections.items.len);144 const index = @intCast(u8, self.sections.items.len);
150 try self.sections.append(gpa, sect);145 try self.sections.append(self.allocator, sect);
151 segment.cmdsize += @sizeOf(macho.section_64);146 segment.cmdsize += @sizeOf(macho.section_64);
152 segment.nsects += 1;147 segment.nsects += 1;
153148
...@@ -175,34 +170,35 @@ pub fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64)...@@ -175,34 +170,35 @@ pub fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64)
175 return offset;170 return offset;
176}171}
177172
178pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Options) !void {173pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
179 // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the174 // TODO This linker code currently assumes there is only 1 compilation unit
180 // Zig source code.175 // and it corresponds to the Zig source code.
176 const options = macho_file.base.options;
181 const module = options.module orelse return error.LinkingWithoutZigSourceUnimplemented;177 const module = options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
182178
183 for (self.relocs.items) |*reloc| {179 for (self.relocs.items) |*reloc| {
184 const sym = switch (reloc.type) {180 const sym = switch (reloc.type) {
185 .direct_load => self.base.getSymbol(.{ .sym_index = reloc.target, .file = null }),181 .direct_load => macho_file.getSymbol(.{ .sym_index = reloc.target, .file = null }),
186 .got_load => blk: {182 .got_load => blk: {
187 const got_index = self.base.got_entries_table.get(.{183 const got_index = macho_file.got_entries_table.get(.{
188 .sym_index = reloc.target,184 .sym_index = reloc.target,
189 .file = null,185 .file = null,
190 }).?;186 }).?;
191 const got_entry = self.base.got_entries.items[got_index];187 const got_entry = macho_file.got_entries.items[got_index];
192 break :blk got_entry.getSymbol(self.base);188 break :blk got_entry.getSymbol(macho_file);
193 },189 },
194 };190 };
195 if (sym.n_value == reloc.prev_vaddr) continue;191 if (sym.n_value == reloc.prev_vaddr) continue;
196192
197 const sym_name = switch (reloc.type) {193 const sym_name = switch (reloc.type) {
198 .direct_load => self.base.getSymbolName(.{ .sym_index = reloc.target, .file = null }),194 .direct_load => macho_file.getSymbolName(.{ .sym_index = reloc.target, .file = null }),
199 .got_load => blk: {195 .got_load => blk: {
200 const got_index = self.base.got_entries_table.get(.{196 const got_index = macho_file.got_entries_table.get(.{
201 .sym_index = reloc.target,197 .sym_index = reloc.target,
202 .file = null,198 .file = null,
203 }).?;199 }).?;
204 const got_entry = self.base.got_entries.items[got_index];200 const got_entry = macho_file.got_entries.items[got_index];
205 break :blk got_entry.getName(self.base);201 break :blk got_entry.getName(macho_file);
206 },202 },
207 };203 };
208 const sect = &self.sections.items[self.debug_info_section_index.?];204 const sect = &self.sections.items[self.debug_info_section_index.?];
...@@ -218,30 +214,30 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti...@@ -218,30 +214,30 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti
218 }214 }
219215
220 if (self.debug_abbrev_section_dirty) {216 if (self.debug_abbrev_section_dirty) {
221 try self.dwarf.writeDbgAbbrev(&self.base.base);217 try self.dwarf.writeDbgAbbrev(&macho_file.base);
222 self.debug_abbrev_section_dirty = false;218 self.debug_abbrev_section_dirty = false;
223 }219 }
224220
225 if (self.debug_info_header_dirty) {221 if (self.debug_info_header_dirty) {
226 // Currently only one compilation unit is supported, so the address range is simply222 // Currently only one compilation unit is supported, so the address range is simply
227 // identical to the main program header virtual address and memory size.223 // identical to the main program header virtual address and memory size.
228 const text_section = self.base.sections.items(.header)[self.base.text_section_index.?];224 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];
229 const low_pc = text_section.addr;225 const low_pc = text_section.addr;
230 const high_pc = text_section.addr + text_section.size;226 const high_pc = text_section.addr + text_section.size;
231 try self.dwarf.writeDbgInfoHeader(&self.base.base, module, low_pc, high_pc);227 try self.dwarf.writeDbgInfoHeader(&macho_file.base, module, low_pc, high_pc);
232 self.debug_info_header_dirty = false;228 self.debug_info_header_dirty = false;
233 }229 }
234230
235 if (self.debug_aranges_section_dirty) {231 if (self.debug_aranges_section_dirty) {
236 // Currently only one compilation unit is supported, so the address range is simply232 // Currently only one compilation unit is supported, so the address range is simply
237 // identical to the main program header virtual address and memory size.233 // identical to the main program header virtual address and memory size.
238 const text_section = self.base.sections.items(.header)[self.base.text_section_index.?];234 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];
239 try self.dwarf.writeDbgAranges(&self.base.base, text_section.addr, text_section.size);235 try self.dwarf.writeDbgAranges(&macho_file.base, text_section.addr, text_section.size);
240 self.debug_aranges_section_dirty = false;236 self.debug_aranges_section_dirty = false;
241 }237 }
242238
243 if (self.debug_line_header_dirty) {239 if (self.debug_line_header_dirty) {
244 try self.dwarf.writeDbgLineHeader(&self.base.base, module);240 try self.dwarf.writeDbgLineHeader(&macho_file.base, module);
245 self.debug_line_header_dirty = false;241 self.debug_line_header_dirty = false;
246 }242 }
247243
...@@ -270,40 +266,45 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti...@@ -270,40 +266,45 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti
270 }266 }
271 }267 }
272268
273 var lc_buffer = std.ArrayList(u8).init(allocator);269 var lc_buffer = std.ArrayList(u8).init(self.allocator);
274 defer lc_buffer.deinit();270 defer lc_buffer.deinit();
275 const lc_writer = lc_buffer.writer();271 const lc_writer = lc_buffer.writer();
276 var ncmds: u32 = 0;272 var ncmds: u32 = 0;
277273
278 self.finalizeDwarfSegment();274 self.finalizeDwarfSegment(macho_file);
279 try self.writeLinkeditSegmentData(&ncmds, lc_writer);275 try self.writeLinkeditSegmentData(macho_file, &ncmds, lc_writer);
280276
281 {277 {
282 try lc_writer.writeStruct(self.base.uuid);278 try lc_writer.writeStruct(macho_file.uuid);
283 ncmds += 1;279 ncmds += 1;
284 }280 }
285281
286 var headers_buf = std.ArrayList(u8).init(allocator);282 var headers_buf = std.ArrayList(u8).init(self.allocator);
287 defer headers_buf.deinit();283 defer headers_buf.deinit();
288 try self.writeSegmentHeaders(&ncmds, headers_buf.writer());284 try self.writeSegmentHeaders(macho_file, &ncmds, headers_buf.writer());
289285
290 try self.file.pwriteAll(headers_buf.items, @sizeOf(macho.mach_header_64));286 try self.file.pwriteAll(headers_buf.items, @sizeOf(macho.mach_header_64));
291 try self.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64) + headers_buf.items.len);287 try self.file.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64) + headers_buf.items.len);
292288
293 try self.writeHeader(ncmds, @intCast(u32, lc_buffer.items.len + headers_buf.items.len));289 try self.writeHeader(
290 macho_file,
291 ncmds,
292 @intCast(u32, lc_buffer.items.len + headers_buf.items.len),
293 );
294294
295 assert(!self.debug_abbrev_section_dirty);295 assert(!self.debug_abbrev_section_dirty);
296 assert(!self.debug_aranges_section_dirty);296 assert(!self.debug_aranges_section_dirty);
297 assert(!self.debug_string_table_dirty);297 assert(!self.debug_string_table_dirty);
298}298}
299299
300pub fn deinit(self: *DebugSymbols, allocator: Allocator) void {300pub fn deinit(self: *DebugSymbols) void {
301 const gpa = self.allocator;
301 self.file.close();302 self.file.close();
302 self.segments.deinit(allocator);303 self.segments.deinit(gpa);
303 self.sections.deinit(allocator);304 self.sections.deinit(gpa);
304 self.dwarf.deinit();305 self.dwarf.deinit();
305 self.strtab.deinit(allocator);306 self.strtab.deinit(gpa);
306 self.relocs.deinit(allocator);307 self.relocs.deinit(gpa);
307}308}
308309
309pub fn swapRemoveRelocs(self: *DebugSymbols, target: u32) void {310pub fn swapRemoveRelocs(self: *DebugSymbols, target: u32) void {
...@@ -319,16 +320,22 @@ pub fn swapRemoveRelocs(self: *DebugSymbols, target: u32) void {...@@ -319,16 +320,22 @@ pub fn swapRemoveRelocs(self: *DebugSymbols, target: u32) void {
319 }320 }
320}321}
321322
322fn finalizeDwarfSegment(self: *DebugSymbols) void {323fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
323 const base_vmaddr = blk: {324 const base_vmaddr = blk: {
324 const last_seg = self.base.getLinkeditSegmentPtr();325 // Note that we purposely take the last VM address of the MachO binary including
326 // the binary's LINKEDIT segment. This is in contrast to how dsymutil does it
327 // which overwrites the the address space taken by the original MachO binary,
328 // however at the cost of having LINKEDIT preceed DWARF in dSYM binary which we
329 // do not want as we want to be able to incrementally move DWARF sections in the
330 // file as we please.
331 const last_seg = macho_file.getLinkeditSegmentPtr();
325 break :blk last_seg.vmaddr + last_seg.vmsize;332 break :blk last_seg.vmaddr + last_seg.vmsize;
326 };333 };
327 const dwarf_segment = self.getDwarfSegmentPtr();334 const dwarf_segment = self.getDwarfSegmentPtr();
328 const aligned_size = mem.alignForwardGeneric(335 const aligned_size = mem.alignForwardGeneric(
329 u64,336 u64,
330 dwarf_segment.filesize,337 dwarf_segment.filesize,
331 self.base.page_size,338 self.page_size,
332 );339 );
333 dwarf_segment.vmaddr = base_vmaddr;340 dwarf_segment.vmaddr = base_vmaddr;
334 dwarf_segment.filesize = aligned_size;341 dwarf_segment.filesize = aligned_size;
...@@ -338,21 +345,21 @@ fn finalizeDwarfSegment(self: *DebugSymbols) void {...@@ -338,21 +345,21 @@ fn finalizeDwarfSegment(self: *DebugSymbols) void {
338 linkedit.vmaddr = mem.alignForwardGeneric(345 linkedit.vmaddr = mem.alignForwardGeneric(
339 u64,346 u64,
340 dwarf_segment.vmaddr + aligned_size,347 dwarf_segment.vmaddr + aligned_size,
341 self.base.page_size,348 self.page_size,
342 );349 );
343 linkedit.fileoff = mem.alignForwardGeneric(350 linkedit.fileoff = mem.alignForwardGeneric(
344 u64,351 u64,
345 dwarf_segment.fileoff + aligned_size,352 dwarf_segment.fileoff + aligned_size,
346 self.base.page_size,353 self.page_size,
347 );354 );
348 log.debug("found __LINKEDIT segment free space at 0x{x}", .{linkedit.fileoff});355 log.debug("found __LINKEDIT segment free space at 0x{x}", .{linkedit.fileoff});
349}356}
350357
351fn writeSegmentHeaders(self: *DebugSymbols, ncmds: *u32, writer: anytype) !void {358fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, ncmds: *u32, writer: anytype) !void {
352 // Write segment/section headers from the binary file first.359 // Write segment/section headers from the binary file first.
353 const end = self.base.linkedit_segment_cmd_index.?;360 const end = macho_file.linkedit_segment_cmd_index.?;
354 for (self.base.segments.items[0..end]) |seg, i| {361 for (macho_file.segments.items[0..end]) |seg, i| {
355 const indexes = self.base.getSectionIndexes(@intCast(u8, i));362 const indexes = macho_file.getSectionIndexes(@intCast(u8, i));
356 var out_seg = seg;363 var out_seg = seg;
357 out_seg.fileoff = 0;364 out_seg.fileoff = 0;
358 out_seg.filesize = 0;365 out_seg.filesize = 0;
...@@ -361,7 +368,7 @@ fn writeSegmentHeaders(self: *DebugSymbols, ncmds: *u32, writer: anytype) !void...@@ -361,7 +368,7 @@ fn writeSegmentHeaders(self: *DebugSymbols, ncmds: *u32, writer: anytype) !void
361368
362 // Update section headers count; any section with size of 0 is excluded369 // Update section headers count; any section with size of 0 is excluded
363 // since it doesn't have any data in the final binary file.370 // since it doesn't have any data in the final binary file.
364 for (self.base.sections.items(.header)[indexes.start..indexes.end]) |header| {371 for (macho_file.sections.items(.header)[indexes.start..indexes.end]) |header| {
365 if (header.size == 0) continue;372 if (header.size == 0) continue;
366 out_seg.cmdsize += @sizeOf(macho.section_64);373 out_seg.cmdsize += @sizeOf(macho.section_64);
367 out_seg.nsects += 1;374 out_seg.nsects += 1;
...@@ -372,7 +379,7 @@ fn writeSegmentHeaders(self: *DebugSymbols, ncmds: *u32, writer: anytype) !void...@@ -372,7 +379,7 @@ fn writeSegmentHeaders(self: *DebugSymbols, ncmds: *u32, writer: anytype) !void
372 mem.eql(u8, out_seg.segName(), "__DATA"))) continue;379 mem.eql(u8, out_seg.segName(), "__DATA"))) continue;
373380
374 try writer.writeStruct(out_seg);381 try writer.writeStruct(out_seg);
375 for (self.base.sections.items(.header)[indexes.start..indexes.end]) |header| {382 for (macho_file.sections.items(.header)[indexes.start..indexes.end]) |header| {
376 if (header.size == 0) continue;383 if (header.size == 0) continue;
377 var out_header = header;384 var out_header = header;
378 out_header.offset = 0;385 out_header.offset = 0;
...@@ -392,11 +399,11 @@ fn writeSegmentHeaders(self: *DebugSymbols, ncmds: *u32, writer: anytype) !void...@@ -392,11 +399,11 @@ fn writeSegmentHeaders(self: *DebugSymbols, ncmds: *u32, writer: anytype) !void
392 }399 }
393}400}
394401
395fn writeHeader(self: *DebugSymbols, ncmds: u32, sizeofcmds: u32) !void {402fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void {
396 var header: macho.mach_header_64 = .{};403 var header: macho.mach_header_64 = .{};
397 header.filetype = macho.MH_DSYM;404 header.filetype = macho.MH_DSYM;
398405
399 switch (self.base.base.options.target.cpu.arch) {406 switch (macho_file.base.options.target.cpu.arch) {
400 .aarch64 => {407 .aarch64 => {
401 header.cputype = macho.CPU_TYPE_ARM64;408 header.cputype = macho.CPU_TYPE_ARM64;
402 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;409 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
...@@ -427,7 +434,12 @@ pub fn allocatedSize(self: *DebugSymbols, start: u64) u64 {...@@ -427,7 +434,12 @@ pub fn allocatedSize(self: *DebugSymbols, start: u64) u64 {
427 return min_pos - start;434 return min_pos - start;
428}435}
429436
430fn writeLinkeditSegmentData(self: *DebugSymbols, ncmds: *u32, lc_writer: anytype) !void {437fn writeLinkeditSegmentData(
438 self: *DebugSymbols,
439 macho_file: *MachO,
440 ncmds: *u32,
441 lc_writer: anytype,
442) !void {
431 const tracy = trace(@src());443 const tracy = trace(@src());
432 defer tracy.end();444 defer tracy.end();
433445
...@@ -438,43 +450,43 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, ncmds: *u32, lc_writer: anytype...@@ -438,43 +450,43 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, ncmds: *u32, lc_writer: anytype
438 .stroff = 0,450 .stroff = 0,
439 .strsize = 0,451 .strsize = 0,
440 };452 };
441 try self.writeSymtab(&symtab_cmd);453 try self.writeSymtab(macho_file, &symtab_cmd);
442 try self.writeStrtab(&symtab_cmd);454 try self.writeStrtab(&symtab_cmd);
443 try lc_writer.writeStruct(symtab_cmd);455 try lc_writer.writeStruct(symtab_cmd);
444 ncmds.* += 1;456 ncmds.* += 1;
445457
446 const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];458 const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];
447 const aligned_size = mem.alignForwardGeneric(u64, seg.filesize, self.base.page_size);459 const aligned_size = mem.alignForwardGeneric(u64, seg.filesize, self.page_size);
448 seg.vmsize = aligned_size;460 seg.vmsize = aligned_size;
449}461}
450462
451fn writeSymtab(self: *DebugSymbols, lc: *macho.symtab_command) !void {463fn writeSymtab(self: *DebugSymbols, macho_file: *MachO, lc: *macho.symtab_command) !void {
452 const tracy = trace(@src());464 const tracy = trace(@src());
453 defer tracy.end();465 defer tracy.end();
454466
455 const gpa = self.base.base.allocator;467 const gpa = self.allocator;
456468
457 var locals = std.ArrayList(macho.nlist_64).init(gpa);469 var locals = std.ArrayList(macho.nlist_64).init(gpa);
458 defer locals.deinit();470 defer locals.deinit();
459471
460 for (self.base.locals.items) |sym, sym_id| {472 for (macho_file.locals.items) |sym, sym_id| {
461 if (sym.n_strx == 0) continue; // no name, skip473 if (sym.n_strx == 0) continue; // no name, skip
462 const sym_loc = MachO.SymbolWithLoc{ .sym_index = @intCast(u32, sym_id), .file = null };474 const sym_loc = MachO.SymbolWithLoc{ .sym_index = @intCast(u32, sym_id), .file = null };
463 if (self.base.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip475 if (macho_file.symbolIsTemp(sym_loc)) continue; // local temp symbol, skip
464 if (self.base.getGlobal(self.base.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip476 if (macho_file.getGlobal(macho_file.getSymbolName(sym_loc)) != null) continue; // global symbol is either an export or import, skip
465 var out_sym = sym;477 var out_sym = sym;
466 out_sym.n_strx = try self.strtab.insert(gpa, self.base.getSymbolName(sym_loc));478 out_sym.n_strx = try self.strtab.insert(gpa, macho_file.getSymbolName(sym_loc));
467 try locals.append(out_sym);479 try locals.append(out_sym);
468 }480 }
469481
470 var exports = std.ArrayList(macho.nlist_64).init(gpa);482 var exports = std.ArrayList(macho.nlist_64).init(gpa);
471 defer exports.deinit();483 defer exports.deinit();
472484
473 for (self.base.globals.items) |global| {485 for (macho_file.globals.items) |global| {
474 const sym = self.base.getSymbol(global);486 const sym = macho_file.getSymbol(global);
475 if (sym.undf()) continue; // import, skip487 if (sym.undf()) continue; // import, skip
476 var out_sym = sym;488 var out_sym = sym;
477 out_sym.n_strx = try self.strtab.insert(gpa, self.base.getSymbolName(global));489 out_sym.n_strx = try self.strtab.insert(gpa, macho_file.getSymbolName(global));
478 try exports.append(out_sym);490 try exports.append(out_sym);
479 }491 }
480492