authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-12 10:46:56+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:39+01:00
log10a5536a7c9f9545c292f8e863a7cecd89e9ee54
tree5b8e398a33144ecae930d7f05162d20b118e90f3
parentc2a0a882842d8cc9d0ad29781fe1e13c1a5880cd

macho: re-instate build-obj codepath


4 files changed, 81 insertions(+), 56 deletions(-)

src/link/MachO.zig+6-14
...@@ -369,7 +369,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -369,7 +369,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
369 if (comp.verbose_link) try self.dumpArgv(comp);369 if (comp.verbose_link) try self.dumpArgv(comp);
370370
371 if (self.base.isStaticLib()) return self.flushStaticLib(comp, module_obj_path);371 if (self.base.isStaticLib()) return self.flushStaticLib(comp, module_obj_path);
372 if (self.base.isObject()) return self.flushObject(comp, module_obj_path);372 if (self.base.isObject()) return relocatable.flush(self, comp, module_obj_path);
373373
374 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);374 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
375 defer positionals.deinit();375 defer positionals.deinit();
...@@ -483,7 +483,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -483,7 +483,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
483 self.getFile(index).?.dylib.umbrella = index;483 self.getFile(index).?.dylib.umbrella = index;
484 }484 }
485485
486 // try self.parseDependentDylibs();486 // TODO: try self.parseDependentDylibs();
487487
488 for (self.dylibs.items) |index| {488 for (self.dylibs.items) |index| {
489 const dylib = self.getFile(index).?.dylib;489 const dylib = self.getFile(index).?.dylib;
...@@ -783,16 +783,6 @@ fn flushStaticLib(self: *MachO, comp: *Compilation, module_obj_path: ?[]const u8...@@ -783,16 +783,6 @@ fn flushStaticLib(self: *MachO, comp: *Compilation, module_obj_path: ?[]const u8
783 return error.FlushFailure;783 return error.FlushFailure;
784}784}
785785
786fn flushObject(self: *MachO, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
787 _ = comp;
788 _ = module_obj_path;
789
790 var err = try self.addErrorWithNotes(0);
791 try err.addMsg(self, "TODO implement flushObject", .{});
792
793 return error.FlushFailure;
794}
795
796pub fn resolveLibSystem(786pub fn resolveLibSystem(
797 self: *MachO,787 self: *MachO,
798 arena: Allocator,788 arena: Allocator,
...@@ -890,7 +880,7 @@ const ParseError = error{...@@ -890,7 +880,7 @@ const ParseError = error{
890 UnknownFileType,880 UnknownFileType,
891} || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError || tapi.TapiError;881} || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError || tapi.TapiError;
892882
893fn parsePositional(self: *MachO, path: []const u8, must_link: bool) ParseError!void {883pub fn parsePositional(self: *MachO, path: []const u8, must_link: bool) ParseError!void {
894 const tracy = trace(@src());884 const tracy = trace(@src());
895 defer tracy.end();885 defer tracy.end();
896 if (try Object.isObject(path)) {886 if (try Object.isObject(path)) {
...@@ -1083,6 +1073,7 @@ fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!File.Index...@@ -1083,6 +1073,7 @@ fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!File.Index
1083// return false;1073// return false;
1084// }1074// }
10851075
1076// TODO:
1086// fn parseDependentDylibs(1077// fn parseDependentDylibs(
1087// self: *MachO1078// self: *MachO
1088// ) !void {1079// ) !void {
...@@ -1212,7 +1203,7 @@ fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!File.Index...@@ -1212,7 +1203,7 @@ fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!File.Index
1212// }1203// }
1213// }1204// }
12141205
1215fn addUndefinedGlobals(self: *MachO) !void {1206pub fn addUndefinedGlobals(self: *MachO) !void {
1216 const gpa = self.base.comp.gpa;1207 const gpa = self.base.comp.gpa;
12171208
1218 try self.undefined_symbols.ensureUnusedCapacity(gpa, self.base.comp.force_undefined_symbols.keys().len);1209 try self.undefined_symbols.ensureUnusedCapacity(gpa, self.base.comp.force_undefined_symbols.keys().len);
...@@ -4033,6 +4024,7 @@ const fat = @import("MachO/fat.zig");...@@ -4033,6 +4024,7 @@ const fat = @import("MachO/fat.zig");
4033const link = @import("../link.zig");4024const link = @import("../link.zig");
4034const llvm_backend = @import("../codegen/llvm.zig");4025const llvm_backend = @import("../codegen/llvm.zig");
4035const load_commands = @import("MachO/load_commands.zig");4026const load_commands = @import("MachO/load_commands.zig");
4027const relocatable = @import("MachO/relocatable.zig");
4036const tapi = @import("tapi.zig");4028const tapi = @import("tapi.zig");
4037const target_util = @import("../target.zig");4029const target_util = @import("../target.zig");
4038const thunks = @import("MachO/thunks.zig");4030const thunks = @import("MachO/thunks.zig");
src/link/MachO/Atom.zig+2-2
...@@ -682,7 +682,7 @@ const x86_64 = struct {...@@ -682,7 +682,7 @@ const x86_64 = struct {
682};682};
683683
684pub fn calcNumRelocs(self: Atom, macho_file: *MachO) u32 {684pub fn calcNumRelocs(self: Atom, macho_file: *MachO) u32 {
685 switch (macho_file.options.cpu_arch.?) {685 switch (macho_file.getTarget().cpu.arch) {
686 .aarch64 => {686 .aarch64 => {
687 var nreloc: u32 = 0;687 var nreloc: u32 = 0;
688 for (self.getRelocs(macho_file)) |rel| {688 for (self.getRelocs(macho_file)) |rel| {
...@@ -705,7 +705,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: *std.Arra...@@ -705,7 +705,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: *std.Arra
705 const tracy = trace(@src());705 const tracy = trace(@src());
706 defer tracy.end();706 defer tracy.end();
707707
708 const cpu_arch = macho_file.options.cpu_arch.?;708 const cpu_arch = macho_file.getTarget().cpu.arch;
709 const relocs = self.getRelocs(macho_file);709 const relocs = self.getRelocs(macho_file);
710 const sect = macho_file.sections.items(.header)[self.out_n_sect];710 const sect = macho_file.sections.items(.header)[self.out_n_sect];
711 var stream = std.io.fixedBufferStream(code);711 var stream = std.io.fixedBufferStream(code);
src/link/MachO/load_commands.zig+6-9
...@@ -98,7 +98,6 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) u32 {...@@ -98,7 +98,6 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) u32 {
98}98}
9999
100pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 {100pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 {
101 const options = &macho_file.options;
102 var sizeofcmds: u64 = 0;101 var sizeofcmds: u64 = 0;
103102
104 // LC_SEGMENT_64103 // LC_SEGMENT_64
...@@ -116,14 +115,12 @@ pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 {...@@ -116,14 +115,12 @@ pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 {
116 // LC_DYSYMTAB115 // LC_DYSYMTAB
117 sizeofcmds += @sizeOf(macho.dysymtab_command);116 sizeofcmds += @sizeOf(macho.dysymtab_command);
118117
119 if (options.platform) |platform| {118 if (macho_file.platform.isBuildVersionCompatible()) {
120 if (platform.isBuildVersionCompatible()) {119 // LC_BUILD_VERSION
121 // LC_BUILD_VERSION120 sizeofcmds += @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version);
122 sizeofcmds += @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version);121 } else {
123 } else {122 // LC_VERSION_MIN_*
124 // LC_VERSION_MIN_*123 sizeofcmds += @sizeOf(macho.version_min_command);
125 sizeofcmds += @sizeOf(macho.version_min_command);
126 }
127 }124 }
128125
129 return @as(u32, @intCast(sizeofcmds));126 return @as(u32, @intCast(sizeofcmds));
src/link/MachO/relocatable.zig+67-31
...@@ -1,4 +1,37 @@...@@ -1,4 +1,37 @@
1pub fn flush(macho_file: *MachO) !void {1pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
2 const gpa = macho_file.base.comp.gpa;
3
4 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
5 defer positionals.deinit();
6 try positionals.ensureUnusedCapacity(comp.objects.len);
7 positionals.appendSliceAssumeCapacity(comp.objects);
8
9 for (comp.c_object_table.keys()) |key| {
10 try positionals.append(.{ .path = key.status.success.object_path });
11 }
12
13 if (module_obj_path) |path| try positionals.append(.{ .path = path });
14
15 for (positionals.items) |obj| {
16 macho_file.parsePositional(obj.path, obj.must_link) catch |err| switch (err) {
17 error.MalformedObject,
18 error.MalformedArchive,
19 error.InvalidCpuArch,
20 error.InvalidTarget,
21 => continue, // already reported
22 error.UnknownFileType => try macho_file.reportParseError(obj.path, "unknown file type for an object file", .{}),
23 else => |e| try macho_file.reportParseError(
24 obj.path,
25 "unexpected error: parsing input file failed with error {s}",
26 .{@errorName(e)},
27 ),
28 };
29 }
30
31 if (comp.link_errors.items.len > 0) return error.FlushFailure;
32
33 try macho_file.addUndefinedGlobals();
34 try macho_file.resolveSymbols();
2 markExports(macho_file);35 markExports(macho_file);
3 claimUnresolved(macho_file);36 claimUnresolved(macho_file);
4 try initOutputSections(macho_file);37 try initOutputSections(macho_file);
...@@ -9,7 +42,7 @@ pub fn flush(macho_file: *MachO) !void {...@@ -9,7 +42,7 @@ pub fn flush(macho_file: *MachO) !void {
9 {42 {
10 // For relocatable, we only ever need a single segment so create it now.43 // For relocatable, we only ever need a single segment so create it now.
11 const prot: macho.vm_prot_t = macho.PROT.READ | macho.PROT.WRITE | macho.PROT.EXEC;44 const prot: macho.vm_prot_t = macho.PROT.READ | macho.PROT.WRITE | macho.PROT.EXEC;
12 try macho_file.segments.append(macho_file.base.allocator, .{45 try macho_file.segments.append(gpa, .{
13 .cmdsize = @sizeOf(macho.segment_command_64),46 .cmdsize = @sizeOf(macho.segment_command_64),
14 .segname = MachO.makeStaticString(""),47 .segname = MachO.makeStaticString(""),
15 .maxprot = prot,48 .maxprot = prot,
...@@ -128,17 +161,20 @@ fn initOutputSections(macho_file: *MachO) !void {...@@ -128,17 +161,20 @@ fn initOutputSections(macho_file: *MachO) !void {
128}161}
129162
130fn calcSectionSizes(macho_file: *MachO) !void {163fn calcSectionSizes(macho_file: *MachO) !void {
164 const tracy = trace(@src());
165 defer tracy.end();
166
131 const slice = macho_file.sections.slice();167 const slice = macho_file.sections.slice();
132 for (slice.items(.header), slice.items(.atoms)) |*header, atoms| {168 for (slice.items(.header), slice.items(.atoms)) |*header, atoms| {
133 if (atoms.items.len == 0) continue;169 if (atoms.items.len == 0) continue;
134 for (atoms.items) |atom_index| {170 for (atoms.items) |atom_index| {
135 const atom = macho_file.getAtom(atom_index).?;171 const atom = macho_file.getAtom(atom_index).?;
136 const atom_alignment = try math.powi(u32, 2, atom.alignment);172 const atom_alignment = atom.alignment.toByteUnits(1);
137 const offset = mem.alignForward(u64, header.size, atom_alignment);173 const offset = mem.alignForward(u64, header.size, atom_alignment);
138 const padding = offset - header.size;174 const padding = offset - header.size;
139 atom.value = offset;175 atom.value = offset;
140 header.size += padding + atom.size;176 header.size += padding + atom.size;
141 header.@"align" = @max(header.@"align", atom.alignment);177 header.@"align" = @max(header.@"align", atom.alignment.toLog2Units());
142 header.nreloc += atom.calcNumRelocs(macho_file);178 header.nreloc += atom.calcNumRelocs(macho_file);
143 }179 }
144 }180 }
...@@ -218,8 +254,8 @@ fn writeAtoms(macho_file: *MachO) !void {...@@ -218,8 +254,8 @@ fn writeAtoms(macho_file: *MachO) !void {
218 const tracy = trace(@src());254 const tracy = trace(@src());
219 defer tracy.end();255 defer tracy.end();
220256
221 const gpa = macho_file.base.allocator;257 const gpa = macho_file.base.comp.gpa;
222 const cpu_arch = macho_file.options.cpu_arch.?;258 const cpu_arch = macho_file.getTarget().cpu.arch;
223 const slice = macho_file.sections.slice();259 const slice = macho_file.sections.slice();
224260
225 for (slice.items(.header), slice.items(.atoms)) |header, atoms| {261 for (slice.items(.header), slice.items(.atoms)) |header, atoms| {
...@@ -247,14 +283,14 @@ fn writeAtoms(macho_file: *MachO) !void {...@@ -247,14 +283,14 @@ fn writeAtoms(macho_file: *MachO) !void {
247 mem.sort(macho.relocation_info, relocs.items, {}, sortReloc);283 mem.sort(macho.relocation_info, relocs.items, {}, sortReloc);
248284
249 // TODO scattered writes?285 // TODO scattered writes?
250 try macho_file.base.file.pwriteAll(code, header.offset);286 try macho_file.base.file.?.pwriteAll(code, header.offset);
251 try macho_file.base.file.pwriteAll(mem.sliceAsBytes(relocs.items), header.reloff);287 try macho_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), header.reloff);
252 }288 }
253}289}
254290
255fn writeCompactUnwind(macho_file: *MachO) !void {291fn writeCompactUnwind(macho_file: *MachO) !void {
256 const sect_index = macho_file.unwind_info_sect_index orelse return;292 const sect_index = macho_file.unwind_info_sect_index orelse return;
257 const gpa = macho_file.base.allocator;293 const gpa = macho_file.base.comp.gpa;
258 const header = macho_file.sections.items(.header)[sect_index];294 const header = macho_file.sections.items(.header)[sect_index];
259295
260 const nrecs = @divExact(header.size, @sizeOf(macho.compact_unwind_entry));296 const nrecs = @divExact(header.size, @sizeOf(macho.compact_unwind_entry));
...@@ -301,7 +337,7 @@ fn writeCompactUnwind(macho_file: *MachO) !void {...@@ -301,7 +337,7 @@ fn writeCompactUnwind(macho_file: *MachO) !void {
301 const atom = rec.getAtom(macho_file);337 const atom = rec.getAtom(macho_file);
302 const addr = rec.getAtomAddress(macho_file);338 const addr = rec.getAtomAddress(macho_file);
303 out.rangeStart = addr;339 out.rangeStart = addr;
304 var reloc = addReloc(offset, macho_file.options.cpu_arch.?);340 var reloc = addReloc(offset, macho_file.getTarget().cpu.arch);
305 reloc.r_symbolnum = atom.out_n_sect + 1;341 reloc.r_symbolnum = atom.out_n_sect + 1;
306 relocs.appendAssumeCapacity(reloc);342 relocs.appendAssumeCapacity(reloc);
307 }343 }
...@@ -309,7 +345,7 @@ fn writeCompactUnwind(macho_file: *MachO) !void {...@@ -309,7 +345,7 @@ fn writeCompactUnwind(macho_file: *MachO) !void {
309 // Personality function345 // Personality function
310 if (rec.getPersonality(macho_file)) |sym| {346 if (rec.getPersonality(macho_file)) |sym| {
311 const r_symbolnum = math.cast(u24, sym.getOutputSymtabIndex(macho_file).?) orelse return error.Overflow;347 const r_symbolnum = math.cast(u24, sym.getOutputSymtabIndex(macho_file).?) orelse return error.Overflow;
312 var reloc = addReloc(offset + 16, macho_file.options.cpu_arch.?);348 var reloc = addReloc(offset + 16, macho_file.getTarget().cpu.arch);
313 reloc.r_symbolnum = r_symbolnum;349 reloc.r_symbolnum = r_symbolnum;
314 reloc.r_extern = 1;350 reloc.r_extern = 1;
315 relocs.appendAssumeCapacity(reloc);351 relocs.appendAssumeCapacity(reloc);
...@@ -319,7 +355,7 @@ fn writeCompactUnwind(macho_file: *MachO) !void {...@@ -319,7 +355,7 @@ fn writeCompactUnwind(macho_file: *MachO) !void {
319 if (rec.getLsdaAtom(macho_file)) |atom| {355 if (rec.getLsdaAtom(macho_file)) |atom| {
320 const addr = rec.getLsdaAddress(macho_file);356 const addr = rec.getLsdaAddress(macho_file);
321 out.lsda = addr;357 out.lsda = addr;
322 var reloc = addReloc(offset + 24, macho_file.options.cpu_arch.?);358 var reloc = addReloc(offset + 24, macho_file.getTarget().cpu.arch);
323 reloc.r_symbolnum = atom.out_n_sect + 1;359 reloc.r_symbolnum = atom.out_n_sect + 1;
324 relocs.appendAssumeCapacity(reloc);360 relocs.appendAssumeCapacity(reloc);
325 }361 }
...@@ -335,13 +371,13 @@ fn writeCompactUnwind(macho_file: *MachO) !void {...@@ -335,13 +371,13 @@ fn writeCompactUnwind(macho_file: *MachO) !void {
335 mem.sort(macho.relocation_info, relocs.items, {}, sortReloc);371 mem.sort(macho.relocation_info, relocs.items, {}, sortReloc);
336372
337 // TODO scattered writes?373 // TODO scattered writes?
338 try macho_file.base.file.pwriteAll(mem.sliceAsBytes(entries.items), header.offset);374 try macho_file.base.file.?.pwriteAll(mem.sliceAsBytes(entries.items), header.offset);
339 try macho_file.base.file.pwriteAll(mem.sliceAsBytes(relocs.items), header.reloff);375 try macho_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), header.reloff);
340}376}
341377
342fn writeEhFrame(macho_file: *MachO) !void {378fn writeEhFrame(macho_file: *MachO) !void {
343 const sect_index = macho_file.eh_frame_sect_index orelse return;379 const sect_index = macho_file.eh_frame_sect_index orelse return;
344 const gpa = macho_file.base.allocator;380 const gpa = macho_file.base.comp.gpa;
345 const header = macho_file.sections.items(.header)[sect_index];381 const header = macho_file.sections.items(.header)[sect_index];
346382
347 const code = try gpa.alloc(u8, header.size);383 const code = try gpa.alloc(u8, header.size);
...@@ -356,12 +392,12 @@ fn writeEhFrame(macho_file: *MachO) !void {...@@ -356,12 +392,12 @@ fn writeEhFrame(macho_file: *MachO) !void {
356 mem.sort(macho.relocation_info, relocs.items, {}, sortReloc);392 mem.sort(macho.relocation_info, relocs.items, {}, sortReloc);
357393
358 // TODO scattered writes?394 // TODO scattered writes?
359 try macho_file.base.file.pwriteAll(code, header.offset);395 try macho_file.base.file.?.pwriteAll(code, header.offset);
360 try macho_file.base.file.pwriteAll(mem.sliceAsBytes(relocs.items), header.reloff);396 try macho_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), header.reloff);
361}397}
362398
363fn writeLoadCommands(macho_file: *MachO) !struct { usize, usize } {399fn writeLoadCommands(macho_file: *MachO) !struct { usize, usize } {
364 const gpa = macho_file.base.allocator;400 const gpa = macho_file.base.comp.gpa;
365 const needed_size = load_commands.calcLoadCommandsSizeObject(macho_file);401 const needed_size = load_commands.calcLoadCommandsSizeObject(macho_file);
366 const buffer = try gpa.alloc(u8, needed_size);402 const buffer = try gpa.alloc(u8, needed_size);
367 defer gpa.free(buffer);403 defer gpa.free(buffer);
...@@ -390,19 +426,17 @@ fn writeLoadCommands(macho_file: *MachO) !struct { usize, usize } {...@@ -390,19 +426,17 @@ fn writeLoadCommands(macho_file: *MachO) !struct { usize, usize } {
390 try writer.writeStruct(macho_file.dysymtab_cmd);426 try writer.writeStruct(macho_file.dysymtab_cmd);
391 ncmds += 1;427 ncmds += 1;
392428
393 if (macho_file.options.platform) |platform| {429 if (macho_file.platform.isBuildVersionCompatible()) {
394 if (platform.isBuildVersionCompatible()) {430 try load_commands.writeBuildVersionLC(macho_file.platform, macho_file.sdk_version, writer);
395 try load_commands.writeBuildVersionLC(platform, macho_file.options.sdk_version, writer);431 ncmds += 1;
396 ncmds += 1;432 } else {
397 } else {433 try load_commands.writeVersionMinLC(macho_file.platform, macho_file.sdk_version, writer);
398 try load_commands.writeVersionMinLC(platform, macho_file.options.sdk_version, writer);434 ncmds += 1;
399 ncmds += 1;
400 }
401 }435 }
402436
403 assert(cwriter.bytes_written == needed_size);437 assert(cwriter.bytes_written == needed_size);
404438
405 try macho_file.base.file.pwriteAll(buffer, @sizeOf(macho.mach_header_64));439 try macho_file.base.file.?.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
406440
407 return .{ ncmds, buffer.len };441 return .{ ncmds, buffer.len };
408}442}
...@@ -419,7 +453,7 @@ fn writeHeader(macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void {...@@ -419,7 +453,7 @@ fn writeHeader(macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void {
419 header.flags |= macho.MH_SUBSECTIONS_VIA_SYMBOLS;453 header.flags |= macho.MH_SUBSECTIONS_VIA_SYMBOLS;
420 }454 }
421455
422 switch (macho_file.options.cpu_arch.?) {456 switch (macho_file.getTarget().cpu.arch) {
423 .aarch64 => {457 .aarch64 => {
424 header.cputype = macho.CPU_TYPE_ARM64;458 header.cputype = macho.CPU_TYPE_ARM64;
425 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;459 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
...@@ -434,19 +468,21 @@ fn writeHeader(macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void {...@@ -434,19 +468,21 @@ fn writeHeader(macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void {
434 header.ncmds = @intCast(ncmds);468 header.ncmds = @intCast(ncmds);
435 header.sizeofcmds = @intCast(sizeofcmds);469 header.sizeofcmds = @intCast(sizeofcmds);
436470
437 try macho_file.base.file.pwriteAll(mem.asBytes(&header), 0);471 try macho_file.base.file.?.pwriteAll(mem.asBytes(&header), 0);
438}472}
439473
440const assert = std.debug.assert;474const assert = std.debug.assert;
441const eh_frame = @import("eh_frame.zig");475const eh_frame = @import("eh_frame.zig");
476const link = @import("../../link.zig");
442const load_commands = @import("load_commands.zig");477const load_commands = @import("load_commands.zig");
443const macho = std.macho;478const macho = std.macho;
444const math = std.math;479const math = std.math;
445const mem = std.mem;480const mem = std.mem;
446const state_log = std.log.scoped(.state);481const state_log = std.log.scoped(.link_state);
447const std = @import("std");482const std = @import("std");
448const trace = @import("../tracy.zig").trace;483const trace = @import("../../tracy.zig").trace;
449484
450const Atom = @import("Atom.zig");485const Atom = @import("Atom.zig");
486const Compilation = @import("../../Compilation.zig");
451const MachO = @import("../MachO.zig");487const MachO = @import("../MachO.zig");
452const Symbol = @import("Symbol.zig");488const Symbol = @import("Symbol.zig");