Skip to content

Commit

Permalink
macho: clean up error reporting for fat libs
Browse files Browse the repository at this point in the history
  • Loading branch information
kubkon committed Aug 5, 2023
1 parent 7242e85 commit dfc4a05
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 24 deletions.
23 changes: 21 additions & 2 deletions src/MachO.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -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;

Expand All @@ -766,6 +784,7 @@ pub fn parseDylib(
dependent_libs,
path,
contents,
self,
) catch |err| switch (err) {
error.NotDylib => {
try file.seekTo(0);
Expand Down
10 changes: 9 additions & 1 deletion src/MachO/Dylib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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}", .{
Expand Down
28 changes: 7 additions & 21 deletions src/MachO/fat.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}

0 comments on commit dfc4a05

Please sign in to comment.