diff --git a/src/MachO.zig b/src/MachO.zig index e5e36676..437fc0a4 100644 --- a/src/MachO.zig +++ b/src/MachO.zig @@ -678,7 +678,16 @@ fn parseArchive(self: *MachO, path: []const u8, force_load: bool) !bool { const name = try gpa.dupe(u8, path); const cpu_arch = self.options.target.cpu_arch.?; const reader = file.reader(); - const fat_offset = try fat.getLibraryOffset(reader, cpu_arch); + const fat_offset = fat.getLibraryOffset(reader, cpu_arch) catch |err| switch (err) { + error.MissingArch => { + self.base.fatal( + "{s}: could not find matching cpu architecture in fat library: expected {s}", + .{ name, @tagName(cpu_arch) }, + ); + return true; + }, + else => |e| return e, + }; try reader.context.seekTo(fat_offset); var archive = Archive{ @@ -749,7 +758,16 @@ pub fn parseDylib( var file_size = math.cast(usize, file_stat.size) orelse return error.Overflow; const reader = file.reader(); - const lib_offset = try fat.getLibraryOffset(reader, cpu_arch); + const lib_offset = fat.getLibraryOffset(reader, cpu_arch) catch |err| switch (err) { + error.MissingArch => { + self.base.fatal( + "{s}: could not find matching cpu architecture in fat library: expected {s}", + .{ path, @tagName(cpu_arch) }, + ); + return true; + }, + else => |e| return e, + }; try file.seekTo(lib_offset); file_size -= lib_offset; @@ -766,6 +784,7 @@ pub fn parseDylib( dependent_libs, path, contents, + self, ) catch |err| switch (err) { error.NotDylib => { try file.seekTo(0); diff --git a/src/MachO/Dylib.zig b/src/MachO/Dylib.zig index 588a58f6..0728b3ac 100644 --- a/src/MachO/Dylib.zig +++ b/src/MachO/Dylib.zig @@ -134,6 +134,7 @@ pub fn parseFromBinary( dependent_libs: anytype, name: []const u8, data: []align(@alignOf(u64)) const u8, + macho_file: *MachO, ) !void { var stream = std.io.fixedBufferStream(data); const reader = stream.reader(); @@ -150,7 +151,14 @@ pub fn parseFromBinary( return error.NotDylib; } - const this_arch: std.Target.Cpu.Arch = try fat.decodeArch(header.cputype, true); + const this_arch: std.Target.Cpu.Arch = switch (header.cputype) { + macho.CPU_TYPE_ARM64 => .aarch64, + macho.CPU_TYPE_X86_64 => .x86_64, + else => |value| { + macho_file.base.fatal("unsupported cpu architecture 0x{x}", .{value}); + return; + }, + }; if (this_arch != cpu_arch) { log.err("mismatched cpu architecture: expected {s}, found {s}", .{ diff --git a/src/MachO/fat.zig b/src/MachO/fat.zig index b7d85141..c1bbe793 100644 --- a/src/MachO/fat.zig +++ b/src/MachO/fat.zig @@ -5,19 +5,7 @@ const macho = std.macho; const mem = std.mem; const native_endian = builtin.target.cpu.arch.endian(); -pub fn decodeArch(cputype: macho.cpu_type_t, comptime logError: bool) !std.Target.Cpu.Arch { - const cpu_arch: std.Target.Cpu.Arch = switch (cputype) { - macho.CPU_TYPE_ARM64 => .aarch64, - macho.CPU_TYPE_X86_64 => .x86_64, - else => { - if (logError) { - log.err("unsupported cpu architecture 0x{x}", .{cputype}); - } - return error.UnsupportedCpuArchitecture; - }, - }; - return cpu_arch; -} +const MachO = @import("../MachO.zig"); fn readFatStruct(reader: anytype, comptime T: type) !T { // Fat structures (fat_header & fat_arch) are always written and read to/from @@ -38,18 +26,16 @@ pub fn getLibraryOffset(reader: anytype, cpu_arch: std.Target.Cpu.Arch) !u64 { const fat_arch = try readFatStruct(reader, macho.fat_arch); // If we come across an architecture that we do not know how to handle, that's // fine because we can keep looking for one that might match. - const lib_arch = decodeArch(fat_arch.cputype, false) catch |err| switch (err) { - error.UnsupportedCpuArchitecture => continue, - else => |e| return e, + const lib_arch: std.Target.Cpu.Arch = switch (fat_arch.cputype) { + macho.CPU_TYPE_ARM64 => .aarch64, + macho.CPU_TYPE_X86_64 => .x86_64, + else => continue, }; if (lib_arch == cpu_arch) { // We have found a matching architecture! return fat_arch.offset; } - } else { - log.err("Could not find matching cpu architecture in fat library: expected {s}", .{ - @tagName(cpu_arch), - }); - return error.MismatchedCpuArchitecture; } + + return error.MissingArch; }