blob: bc896704b88000bcb25ebbbda9a52318b1e92765 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
pub fn isFatLibrary(file: std.fs.File) bool {
const reader = file.reader();
const hdr = reader.readStructBig(macho.fat_header) catch return false;
defer file.seekTo(0) catch {};
return hdr.magic == macho.FAT_MAGIC;
}
pub const Arch = struct {
tag: std.Target.Cpu.Arch,
offset: u64,
};
/// Caller owns the memory.
pub fn parseArchs(gpa: Allocator, file: std.fs.File) ![]const Arch {
const reader = file.reader();
const fat_header = try reader.readStructBig(macho.fat_header);
assert(fat_header.magic == macho.FAT_MAGIC);
var archs = try std.ArrayList(Arch).initCapacity(gpa, fat_header.nfat_arch);
defer archs.deinit();
var fat_arch_index: u32 = 0;
while (fat_arch_index < fat_header.nfat_arch) : (fat_arch_index += 1) {
const fat_arch = try reader.readStructBig(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 arch: std.Target.Cpu.Arch = switch (fat_arch.cputype) {
macho.CPU_TYPE_ARM64 => if (fat_arch.cpusubtype == macho.CPU_SUBTYPE_ARM_ALL) .aarch64 else continue,
macho.CPU_TYPE_X86_64 => if (fat_arch.cpusubtype == macho.CPU_SUBTYPE_X86_64_ALL) .x86_64 else continue,
else => continue,
};
archs.appendAssumeCapacity(.{ .tag = arch, .offset = fat_arch.offset });
}
return archs.toOwnedSlice();
}
const std = @import("std");
const assert = std.debug.assert;
const log = std.log.scoped(.archive);
const macho = std.macho;
const mem = std.mem;
const Allocator = mem.Allocator;
|