authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-28 16:19:42+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-29 11:40:20+02:00
log1820aed786a2bb61a6526873e7a8ddf47d45e9fd
tree3abf13999c01f19669632c0eef3a83ff595d5e8c
parent68dc1a3e3fc8ab739cb34ed536c71a02727b3825

macho: convert log.err when CPU arch is mismatched into actual errors


2 files changed, 118 insertions(+), 99 deletions(-)

src/link/MachO.zig+76-88
...@@ -396,11 +396,17 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -396,11 +396,17 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
396 self.dylibs_map.clearRetainingCapacity();396 self.dylibs_map.clearRetainingCapacity();
397 self.referenced_dylibs.clearRetainingCapacity();397 self.referenced_dylibs.clearRetainingCapacity();
398398
399 const cpu_arch = self.base.options.target.cpu.arch;
399 var dependent_libs = std.fifo.LinearFifo(struct {400 var dependent_libs = std.fifo.LinearFifo(struct {
400 id: Dylib.Id,401 id: Dylib.Id,
401 parent: u16,402 parent: u16,
402 }, .Dynamic).init(arena);403 }, .Dynamic).init(arena);
403404
405 var parse_error_ctx: union {
406 none: void,
407 detected_arch: std.Target.Cpu.Arch,
408 } = .{ .none = {} };
409
404 for (libs.keys(), libs.values()) |path, lib| {410 for (libs.keys(), libs.values()) |path, lib| {
405 const in_file = try std.fs.cwd().openFile(path, .{});411 const in_file = try std.fs.cwd().openFile(path, .{});
406 defer in_file.close();412 defer in_file.close();
...@@ -411,15 +417,28 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -411,15 +417,28 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
411 lib,417 lib,
412 false,418 false,
413 &dependent_libs,419 &dependent_libs,
414 &self.base.options,420 &parse_error_ctx,
415 ) catch |err| {421 ) catch |err| switch (err) {
416 // TODO convert to error422 error.UnknownFileType => try self.reportParseError(path, "unknown file type", .{}),
417 log.err("{s}: parsing library failed with err {s}", .{ path, @errorName(err) });423 error.MissingArchFatLib => try self.reportParseError(
418 continue;424 path,
425 "missing architecture in universal file, expected '{s}'",
426 .{@tagName(cpu_arch)},
427 ),
428 error.InvalidArch => try self.reportParseError(
429 path,
430 "invalid architecture '{s}', expected '{s}'",
431 .{ @tagName(parse_error_ctx.detected_arch), @tagName(cpu_arch) },
432 ),
433 else => |e| try self.reportParseError(
434 path,
435 "parsing library failed with error '{s}'",
436 .{@errorName(e)},
437 ),
419 };438 };
420 }439 }
421440
422 self.parseDependentLibs(&dependent_libs, &self.base.options) catch |err| {441 self.parseDependentLibs(&dependent_libs, &parse_error_ctx) catch |err| {
423 // TODO convert to error442 // TODO convert to error
424 log.err("parsing dependent libraries failed with err {s}", .{@errorName(err)});443 log.err("parsing dependent libraries failed with err {s}", .{@errorName(err)});
425 };444 };
...@@ -710,19 +729,19 @@ pub fn parsePositional(...@@ -710,19 +729,19 @@ pub fn parsePositional(
710 path: []const u8,729 path: []const u8,
711 must_link: bool,730 must_link: bool,
712 dependent_libs: anytype,731 dependent_libs: anytype,
713 link_options: *const link.Options,732 error_ctx: anytype,
714) !void {733) !void {
715 const tracy = trace(@src());734 const tracy = trace(@src());
716 defer tracy.end();735 defer tracy.end();
717736
718 if (Object.isObject(file)) {737 if (Object.isObject(file)) {
719 try self.parseObject(file, path, link_options);738 try self.parseObject(file, path, error_ctx);
720 } else {739 } else {
721 try self.parseLibrary(file, path, .{740 try self.parseLibrary(file, path, .{
722 .path = null,741 .path = null,
723 .needed = false,742 .needed = false,
724 .weak = false,743 .weak = false,
725 }, must_link, dependent_libs, link_options);744 }, must_link, dependent_libs, error_ctx);
726 }745 }
727}746}
728747
...@@ -730,7 +749,7 @@ fn parseObject(...@@ -730,7 +749,7 @@ fn parseObject(
730 self: *MachO,749 self: *MachO,
731 file: std.fs.File,750 file: std.fs.File,
732 path: []const u8,751 path: []const u8,
733 link_options: *const link.Options,752 error_ctx: anytype,
734) !void {753) !void {
735 const tracy = trace(@src());754 const tracy = trace(@src());
736 defer tracy.end();755 defer tracy.end();
...@@ -758,15 +777,11 @@ fn parseObject(...@@ -758,15 +777,11 @@ fn parseObject(
758 macho.CPU_TYPE_X86_64 => .x86_64,777 macho.CPU_TYPE_X86_64 => .x86_64,
759 else => unreachable,778 else => unreachable,
760 };779 };
761 const self_cpu_arch = link_options.target.cpu.arch;780 const self_cpu_arch = self.base.options.target.cpu.arch;
762781
763 if (self_cpu_arch != cpu_arch) {782 if (self_cpu_arch != cpu_arch) {
764 // TODO convert into an error783 error_ctx.* = .{ .detected_arch = cpu_arch };
765 log.err("{s}: invalid architecture '{s}', expected '{s}'", .{784 return error.InvalidArch;
766 path,
767 @tagName(cpu_arch),
768 @tagName(self_cpu_arch),
769 });
770 }785 }
771}786}
772787
...@@ -777,70 +792,50 @@ pub fn parseLibrary(...@@ -777,70 +792,50 @@ pub fn parseLibrary(
777 lib: link.SystemLib,792 lib: link.SystemLib,
778 must_link: bool,793 must_link: bool,
779 dependent_libs: anytype,794 dependent_libs: anytype,
780 link_options: *const link.Options,795 error_ctx: anytype,
781) !void {796) !void {
782 const tracy = trace(@src());797 const tracy = trace(@src());
783 defer tracy.end();798 defer tracy.end();
784799
785 const cpu_arch = link_options.target.cpu.arch;800 const cpu_arch = self.base.options.target.cpu.arch;
786801
787 if (fat.isFatLibrary(file)) {802 if (fat.isFatLibrary(file)) {
788 const offset = self.parseFatLibrary(file, path, cpu_arch) catch |err| switch (err) {803 const offset = try self.parseFatLibrary(file, cpu_arch);
789 error.MissingArch => return,
790 else => |e| return e,
791 };
792 try file.seekTo(offset);804 try file.seekTo(offset);
793805
794 if (Archive.isArchive(file, offset)) {806 if (Archive.isArchive(file, offset)) {
795 try self.parseArchive(path, offset, must_link, cpu_arch);807 try self.parseArchive(path, offset, must_link, cpu_arch, error_ctx);
796 } else if (Dylib.isDylib(file, offset)) {808 } else if (Dylib.isDylib(file, offset)) {
797 try self.parseDylib(file, path, offset, dependent_libs, link_options, .{809 try self.parseDylib(file, path, offset, dependent_libs, .{
798 .needed = lib.needed,810 .needed = lib.needed,
799 .weak = lib.weak,811 .weak = lib.weak,
800 });812 }, error_ctx);
801 } else {813 } else return error.UnknownFileType;
802 // TODO convert into an error
803 log.err("{s}: unknown file type", .{path});
804 return;
805 }
806 } else if (Archive.isArchive(file, 0)) {814 } else if (Archive.isArchive(file, 0)) {
807 try self.parseArchive(path, 0, must_link, cpu_arch);815 try self.parseArchive(path, 0, must_link, cpu_arch, error_ctx);
808 } else if (Dylib.isDylib(file, 0)) {816 } else if (Dylib.isDylib(file, 0)) {
809 try self.parseDylib(file, path, 0, dependent_libs, link_options, .{817 try self.parseDylib(file, path, 0, dependent_libs, .{
810 .needed = lib.needed,818 .needed = lib.needed,
811 .weak = lib.weak,819 .weak = lib.weak,
812 });820 }, error_ctx);
813 } else {821 } else {
814 self.parseLibStub(file, path, dependent_libs, link_options, .{822 self.parseLibStub(file, path, dependent_libs, .{
815 .needed = lib.needed,823 .needed = lib.needed,
816 .weak = lib.weak,824 .weak = lib.weak,
817 }) catch |err| switch (err) {825 }) catch |err| switch (err) {
818 error.NotLibStub, error.UnexpectedToken => {826 error.NotLibStub, error.UnexpectedToken => return error.UnknownFileType,
819 // TODO convert into an error
820 log.err("{s}: unknown file type", .{path});
821 return;
822 },
823 else => |e| return e,827 else => |e| return e,
824 };828 };
825 }829 }
826}830}
827831
828pub fn parseFatLibrary(832pub fn parseFatLibrary(self: *MachO, file: std.fs.File, cpu_arch: std.Target.Cpu.Arch) !u64 {
829 self: *MachO,
830 file: std.fs.File,
831 path: []const u8,
832 cpu_arch: std.Target.Cpu.Arch,
833) !u64 {
834 _ = self;833 _ = self;
835 var buffer: [2]fat.Arch = undefined;834 var buffer: [2]fat.Arch = undefined;
836 const fat_archs = try fat.parseArchs(file, &buffer);835 const fat_archs = try fat.parseArchs(file, &buffer);
837 const offset = for (fat_archs) |arch| {836 const offset = for (fat_archs) |arch| {
838 if (arch.tag == cpu_arch) break arch.offset;837 if (arch.tag == cpu_arch) break arch.offset;
839 } else {838 } else return error.MissingArchFatLib;
840 // TODO convert into an error
841 log.err("{s}: missing arch in universal file: expected {s}", .{ path, @tagName(cpu_arch) });
842 return error.MissingArch;
843 };
844 return offset;839 return offset;
845}840}
846841
...@@ -850,13 +845,13 @@ fn parseArchive(...@@ -850,13 +845,13 @@ fn parseArchive(
850 fat_offset: u64,845 fat_offset: u64,
851 must_link: bool,846 must_link: bool,
852 cpu_arch: std.Target.Cpu.Arch,847 cpu_arch: std.Target.Cpu.Arch,
848 error_ctx: anytype,
853) !void {849) !void {
854 const gpa = self.base.allocator;850 const gpa = self.base.allocator;
855851
856 // We take ownership of the file so that we can store it for the duration of symbol resolution.852 // We take ownership of the file so that we can store it for the duration of symbol resolution.
857 // TODO we shouldn't need to do that and could pre-parse the archive like we do for zld/ELF?853 // TODO we shouldn't need to do that and could pre-parse the archive like we do for zld/ELF?
858 const file = try std.fs.cwd().openFile(path, .{});854 const file = try std.fs.cwd().openFile(path, .{});
859 errdefer file.close();
860 try file.seekTo(fat_offset);855 try file.seekTo(fat_offset);
861856
862 var archive = Archive{857 var archive = Archive{
...@@ -882,13 +877,8 @@ fn parseArchive(...@@ -882,13 +877,8 @@ fn parseArchive(
882 else => unreachable,877 else => unreachable,
883 };878 };
884 if (cpu_arch != parsed_cpu_arch) {879 if (cpu_arch != parsed_cpu_arch) {
885 // TODO convert into an error880 error_ctx.* = .{ .detected_arch = parsed_cpu_arch };
886 log.err("{s}: invalid architecture in archive '{s}', expected '{s}'", .{881 return error.InvalidArch;
887 path,
888 @tagName(parsed_cpu_arch),
889 @tagName(cpu_arch),
890 });
891 return error.MissingArch;
892 }882 }
893 }883 }
894884
...@@ -923,11 +913,11 @@ fn parseDylib(...@@ -923,11 +913,11 @@ fn parseDylib(
923 path: []const u8,913 path: []const u8,
924 offset: u64,914 offset: u64,
925 dependent_libs: anytype,915 dependent_libs: anytype,
926 link_options: *const link.Options,
927 dylib_options: DylibOpts,916 dylib_options: DylibOpts,
917 error_ctx: anytype,
928) !void {918) !void {
929 const gpa = self.base.allocator;919 const gpa = self.base.allocator;
930 const self_cpu_arch = link_options.target.cpu.arch;920 const self_cpu_arch = self.base.options.target.cpu.arch;
931921
932 const file_stat = try file.stat();922 const file_stat = try file.stat();
933 const file_size = math.cast(usize, file_stat.size - offset) orelse return error.Overflow;923 const file_size = math.cast(usize, file_stat.size - offset) orelse return error.Overflow;
...@@ -952,18 +942,13 @@ fn parseDylib(...@@ -952,18 +942,13 @@ fn parseDylib(
952 else => unreachable,942 else => unreachable,
953 };943 };
954 if (self_cpu_arch != cpu_arch) {944 if (self_cpu_arch != cpu_arch) {
955 // TODO convert into an error945 error_ctx.* = .{ .detected_arch = cpu_arch };
956 log.err("{s}: invalid architecture '{s}', expected '{s}'", .{946 return error.InvalidArch;
957 path,
958 @tagName(cpu_arch),
959 @tagName(self_cpu_arch),
960 });
961 return error.MissingArch;
962 }947 }
963948
964 // TODO verify platform949 // TODO verify platform
965950
966 self.addDylib(dylib, link_options, .{951 self.addDylib(dylib, .{
967 .needed = dylib_options.needed,952 .needed = dylib_options.needed,
968 .weak = dylib_options.weak,953 .weak = dylib_options.weak,
969 }) catch |err| switch (err) {954 }) catch |err| switch (err) {
...@@ -977,7 +962,6 @@ fn parseLibStub(...@@ -977,7 +962,6 @@ fn parseLibStub(
977 file: std.fs.File,962 file: std.fs.File,
978 path: []const u8,963 path: []const u8,
979 dependent_libs: anytype,964 dependent_libs: anytype,
980 link_options: *const link.Options,
981 dylib_options: DylibOpts,965 dylib_options: DylibOpts,
982) !void {966) !void {
983 const gpa = self.base.allocator;967 const gpa = self.base.allocator;
...@@ -993,14 +977,14 @@ fn parseLibStub(...@@ -993,14 +977,14 @@ fn parseLibStub(
993977
994 try dylib.parseFromStub(978 try dylib.parseFromStub(
995 gpa,979 gpa,
996 link_options.target,980 self.base.options.target,
997 lib_stub,981 lib_stub,
998 @intCast(self.dylibs.items.len), // TODO defer it till later982 @intCast(self.dylibs.items.len), // TODO defer it till later
999 dependent_libs,983 dependent_libs,
1000 path,984 path,
1001 );985 );
1002986
1003 self.addDylib(dylib, link_options, .{987 self.addDylib(dylib, .{
1004 .needed = dylib_options.needed,988 .needed = dylib_options.needed,
1005 .weak = dylib_options.weak,989 .weak = dylib_options.weak,
1006 }) catch |err| switch (err) {990 }) catch |err| switch (err) {
...@@ -1009,12 +993,7 @@ fn parseLibStub(...@@ -1009,12 +993,7 @@ fn parseLibStub(
1009 };993 };
1010}994}
1011995
1012fn addDylib(996fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts) !void {
1013 self: *MachO,
1014 dylib: Dylib,
1015 link_options: *const link.Options,
1016 dylib_options: DylibOpts,
1017) !void {
1018 if (dylib_options.id) |id| {997 if (dylib_options.id) |id| {
1019 if (dylib.id.?.current_version < id.compatibility_version) {998 if (dylib.id.?.current_version < id.compatibility_version) {
1020 // TODO convert into an error999 // TODO convert into an error
...@@ -1034,7 +1013,7 @@ fn addDylib(...@@ -1034,7 +1013,7 @@ fn addDylib(
1034 try self.dylibs.append(gpa, dylib);1013 try self.dylibs.append(gpa, dylib);
10351014
1036 const should_link_dylib_even_if_unreachable = blk: {1015 const should_link_dylib_even_if_unreachable = blk: {
1037 if (link_options.dead_strip_dylibs and !dylib_options.needed) break :blk false;1016 if (self.base.options.dead_strip_dylibs and !dylib_options.needed) break :blk false;
1038 break :blk !(dylib_options.dependent or self.referenced_dylibs.contains(gop.value_ptr.*));1017 break :blk !(dylib_options.dependent or self.referenced_dylibs.contains(gop.value_ptr.*));
1039 };1018 };
10401019
...@@ -1043,7 +1022,7 @@ fn addDylib(...@@ -1043,7 +1022,7 @@ fn addDylib(
1043 }1022 }
1044}1023}
10451024
1046pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype, link_options: *const link.Options) !void {1025pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype, error_ctx: anytype) !void {
1047 const tracy = trace(@src());1026 const tracy = trace(@src());
1048 defer tracy.end();1027 defer tracy.end();
10491028
...@@ -1075,7 +1054,7 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype, link_options: *...@@ -1075,7 +1054,7 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype, link_options: *
10751054
1076 for (&[_][]const u8{ extension, ".tbd" }) |ext| {1055 for (&[_][]const u8{ extension, ".tbd" }) |ext| {
1077 const with_ext = try std.fmt.allocPrint(arena, "{s}{s}", .{ without_ext, ext });1056 const with_ext = try std.fmt.allocPrint(arena, "{s}{s}", .{ without_ext, ext });
1078 const full_path = if (link_options.sysroot) |root|1057 const full_path = if (self.base.options.sysroot) |root|
1079 try fs.path.join(arena, &.{ root, with_ext })1058 try fs.path.join(arena, &.{ root, with_ext })
1080 else1059 else
1081 with_ext;1060 with_ext;
...@@ -1089,21 +1068,18 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype, link_options: *...@@ -1089,21 +1068,18 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype, link_options: *
1089 log.debug("trying dependency at fully resolved path {s}", .{full_path});1068 log.debug("trying dependency at fully resolved path {s}", .{full_path});
10901069
1091 const offset: u64 = if (fat.isFatLibrary(file)) blk: {1070 const offset: u64 = if (fat.isFatLibrary(file)) blk: {
1092 const offset = self.parseFatLibrary(file, full_path, link_options.target.cpu.arch) catch |err| switch (err) {1071 const offset = try self.parseFatLibrary(file, self.base.options.target.cpu.arch);
1093 error.MissingArch => break,
1094 else => |e| return e,
1095 };
1096 try file.seekTo(offset);1072 try file.seekTo(offset);
1097 break :blk offset;1073 break :blk offset;
1098 } else 0;1074 } else 0;
10991075
1100 if (Dylib.isDylib(file, offset)) {1076 if (Dylib.isDylib(file, offset)) {
1101 try self.parseDylib(file, full_path, offset, dependent_libs, link_options, .{1077 try self.parseDylib(file, full_path, offset, dependent_libs, .{
1102 .dependent = true,1078 .dependent = true,
1103 .weak = weak,1079 .weak = weak,
1104 });1080 }, error_ctx);
1105 } else {1081 } else {
1106 self.parseLibStub(file, full_path, dependent_libs, link_options, .{1082 self.parseLibStub(file, full_path, dependent_libs, .{
1107 .dependent = true,1083 .dependent = true,
1108 .weak = weak,1084 .weak = weak,
1109 }) catch |err| switch (err) {1085 }) catch |err| switch (err) {
...@@ -4836,6 +4812,18 @@ pub fn getSectionPrecedence(header: macho.section_64) u8 {...@@ -4836,6 +4812,18 @@ pub fn getSectionPrecedence(header: macho.section_64) u8 {
4836 return (@as(u8, @intCast(segment_precedence)) << 4) + section_precedence;4812 return (@as(u8, @intCast(segment_precedence)) << 4) + section_precedence;
4837}4813}
48384814
4815pub fn reportParseError(self: *MachO, path: []const u8, comptime format: []const u8, args: anytype) !void {
4816 const gpa = self.base.allocator;
4817 try self.misc_errors.ensureUnusedCapacity(gpa, 1);
4818 var notes = try gpa.alloc(File.ErrorMsg, 1);
4819 errdefer gpa.free(notes);
4820 notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{path}) };
4821 self.misc_errors.appendAssumeCapacity(.{
4822 .msg = try std.fmt.allocPrint(gpa, format, args),
4823 .notes = notes,
4824 });
4825}
4826
4839pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void {4827pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void {
4840 const gpa = self.base.allocator;4828 const gpa = self.base.allocator;
4841 const count = self.unresolved.count();4829 const count = self.unresolved.count();
src/link/MachO/zld.zig+42-11
...@@ -345,6 +345,11 @@ pub fn linkWithZld(...@@ -345,6 +345,11 @@ pub fn linkWithZld(
345 parent: u16,345 parent: u16,
346 }, .Dynamic).init(arena);346 }, .Dynamic).init(arena);
347347
348 var parse_error_ctx: union {
349 none: void,
350 detected_arch: std.Target.Cpu.Arch,
351 } = .{ .none = {} };
352
348 for (positionals.items) |obj| {353 for (positionals.items) |obj| {
349 const in_file = try std.fs.cwd().openFile(obj.path, .{});354 const in_file = try std.fs.cwd().openFile(obj.path, .{});
350 defer in_file.close();355 defer in_file.close();
...@@ -354,11 +359,24 @@ pub fn linkWithZld(...@@ -354,11 +359,24 @@ pub fn linkWithZld(
354 obj.path,359 obj.path,
355 obj.must_link,360 obj.must_link,
356 &dependent_libs,361 &dependent_libs,
357 options,362 &parse_error_ctx,
358 ) catch |err| {363 ) catch |err| switch (err) {
359 // TODO convert to error364 error.UnknownFileType => try macho_file.reportParseError(obj.path, "unknown file type", .{}),
360 log.err("{s}: parsing positional failed with err {s}", .{ obj.path, @errorName(err) });365 error.MissingArchFatLib => try macho_file.reportParseError(
361 continue;366 obj.path,
367 "missing architecture in universal file, expected '{s}'",
368 .{@tagName(cpu_arch)},
369 ),
370 error.InvalidArch => try macho_file.reportParseError(
371 obj.path,
372 "invalid architecture '{s}', expected '{s}'",
373 .{ @tagName(parse_error_ctx.detected_arch), @tagName(cpu_arch) },
374 ),
375 else => |e| try macho_file.reportParseError(
376 obj.path,
377 "parsing positional argument failed with error '{s}'",
378 .{@errorName(e)},
379 ),
362 };380 };
363 }381 }
364382
...@@ -372,15 +390,28 @@ pub fn linkWithZld(...@@ -372,15 +390,28 @@ pub fn linkWithZld(
372 lib,390 lib,
373 false,391 false,
374 &dependent_libs,392 &dependent_libs,
375 options,393 &parse_error_ctx,
376 ) catch |err| {394 ) catch |err| switch (err) {
377 // TODO convert to error395 error.UnknownFileType => try macho_file.reportParseError(path, "unknown file type", .{}),
378 log.err("{s}: parsing library failed with err {s}", .{ path, @errorName(err) });396 error.MissingArchFatLib => try macho_file.reportParseError(
379 continue;397 path,
398 "missing architecture in universal file, expected '{s}'",
399 .{@tagName(cpu_arch)},
400 ),
401 error.InvalidArch => try macho_file.reportParseError(
402 path,
403 "invalid architecture '{s}', expected '{s}'",
404 .{ @tagName(parse_error_ctx.detected_arch), @tagName(cpu_arch) },
405 ),
406 else => |e| try macho_file.reportParseError(
407 path,
408 "parsing library failed with error '{s}'",
409 .{@errorName(e)},
410 ),
380 };411 };
381 }412 }
382413
383 macho_file.parseDependentLibs(&dependent_libs, options) catch |err| {414 macho_file.parseDependentLibs(&dependent_libs, &parse_error_ctx) catch |err| {
384 // TODO convert to error415 // TODO convert to error
385 log.err("parsing dependent libraries failed with err {s}", .{@errorName(err)});416 log.err("parsing dependent libraries failed with err {s}", .{@errorName(err)});
386 };417 };