authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-22 11:47:30+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-22 12:06:02+02:00
log96fa29b90f16ea12a4fea944636f5c5de73160fc
tree9388aa40d136c7d90f27da061d796cc79c326234
parent7e5a2673ac8b76dbd8cbcfadb829083238182666

macho: write sections in parallel in -r mode


2 files changed, 64 insertions(+), 16 deletions(-)

src/link/MachO/file.zig+7
......@@ -302,6 +302,13 @@ pub const File = union(enum) {
302302 };
303303 }
304304
305 pub fn writeAtomsRelocatable(file: File, macho_file: *MachO) !void {
306 return switch (file) {
307 .dylib, .internal => unreachable,
308 inline else => |x| x.writeAtomsRelocatable(macho_file),
309 };
310 }
311
305312 pub fn calcSymtabSize(file: File, macho_file: *MachO) void {
306313 return switch (file) {
307314 inline else => |x| x.calcSymtabSize(macho_file),
src/link/MachO/relocatable.zig+57-16
......@@ -605,33 +605,74 @@ fn writeSections(macho_file: *MachO) !void {
605605 try macho_file.strtab.resize(gpa, cmd.strsize);
606606 macho_file.strtab.items[0] = 0;
607607
608 for (macho_file.objects.items) |index| {
609 try macho_file.getFile(index).?.object.writeAtomsRelocatable(macho_file);
610 macho_file.getFile(index).?.writeSymtab(macho_file, macho_file);
608 const tp = macho_file.base.comp.thread_pool;
609 var wg: WaitGroup = .{};
610 {
611 wg.reset();
612 defer wg.wait();
613
614 for (macho_file.objects.items) |index| {
615 tp.spawnWg(&wg, writeAtomsWorker, .{ macho_file, macho_file.getFile(index).? });
616 tp.spawnWg(&wg, File.writeSymtab, .{ macho_file.getFile(index).?, macho_file, macho_file });
617 }
618
619 if (macho_file.getZigObject()) |zo| {
620 tp.spawnWg(&wg, writeAtomsWorker, .{ macho_file, zo.asFile() });
621 tp.spawnWg(&wg, File.writeSymtab, .{ zo.asFile(), macho_file, macho_file });
622 }
623
624 if (macho_file.eh_frame_sect_index) |_| {
625 tp.spawnWg(&wg, writeEhFrameWorker, .{macho_file});
626 }
627
628 if (macho_file.unwind_info_sect_index) |_| {
629 for (macho_file.objects.items) |index| {
630 tp.spawnWg(&wg, writeCompactUnwindWorker, .{ macho_file, macho_file.getFile(index).?.object });
631 }
632 }
611633 }
612634
635 if (macho_file.has_errors.swap(false, .seq_cst)) return error.FlushFailure;
636
613637 if (macho_file.getZigObject()) |zo| {
614638 try zo.writeRelocs(macho_file);
615 try zo.writeAtomsRelocatable(macho_file);
616 zo.writeSymtab(macho_file, macho_file);
617 }
618
619 if (macho_file.eh_frame_sect_index) |_| {
620 try writeEhFrame(macho_file);
621639 }
640}
622641
623 if (macho_file.unwind_info_sect_index) |_| {
624 for (macho_file.objects.items) |index| {
625 try macho_file.getFile(index).?.object.writeCompactUnwindRelocatable(macho_file);
626 }
627 }
642fn writeAtomsWorker(macho_file: *MachO, file: File) void {
643 const tracy = trace(@src());
644 defer tracy.end();
645 file.writeAtomsRelocatable(macho_file) catch |err| {
646 macho_file.reportParseError2(file.getIndex(), "failed to write atoms: {s}", .{
647 @errorName(err),
648 }) catch {};
649 _ = macho_file.has_errors.swap(true, .seq_cst);
650 };
628651}
629652
630fn writeEhFrame(macho_file: *MachO) !void {
653fn writeEhFrameWorker(macho_file: *MachO) void {
654 const tracy = trace(@src());
655 defer tracy.end();
631656 const sect_index = macho_file.eh_frame_sect_index.?;
632657 const buffer = macho_file.sections.items(.out)[sect_index];
633658 const relocs = macho_file.sections.items(.relocs)[sect_index];
634 try eh_frame.writeRelocs(macho_file, buffer.items, relocs.items);
659 eh_frame.writeRelocs(macho_file, buffer.items, relocs.items) catch |err| {
660 macho_file.reportUnexpectedError("failed to write '__LD,__eh_frame' section: {s}", .{
661 @errorName(err),
662 }) catch {};
663 _ = macho_file.has_errors.swap(true, .seq_cst);
664 };
665}
666
667fn writeCompactUnwindWorker(macho_file: *MachO, object: *Object) void {
668 const tracy = trace(@src());
669 defer tracy.end();
670 object.writeCompactUnwindRelocatable(macho_file) catch |err| {
671 macho_file.reportUnexpectedError("failed to write '__LD,__eh_frame' section: {s}", .{
672 @errorName(err),
673 }) catch {};
674 _ = macho_file.has_errors.swap(true, .seq_cst);
675 };
635676}
636677
637678fn writeSectionsToFile(macho_file: *MachO) !void {