3 // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
4 // Copyright (C) 1997-2019 Steve Nygard.
8 #include <mach-o/arch.h>
9 #include <mach-o/fat.h>
11 #import "CDDataCursor.h"
13 #import "CDMachOFile.h"
15 @implementation CDFatFile
17 NSMutableArray *_arches;
22 if ((self = [super init])) {
23 _arches = [[NSMutableArray alloc] init];
29 - (id)initWithData:(NSData *)data filename:(NSString *)filename searchPathState:(CDSearchPathState *)searchPathState;
31 if ((self = [super initWithData:data filename:filename searchPathState:searchPathState])) {
32 CDDataCursor *cursor = [[CDDataCursor alloc] initWithData:data];
34 struct fat_header header;
35 header.magic = [cursor readBigInt32];
37 //NSLog(@"(testing fat) magic: 0x%x", header.magic);
38 if (header.magic != FAT_MAGIC) {
42 _arches = [[NSMutableArray alloc] init];
44 header.nfat_arch = [cursor readBigInt32];
45 //NSLog(@"nfat_arch: %u", header.nfat_arch);
46 for (NSUInteger index = 0; index < header.nfat_arch; index++) {
47 CDFatArch *arch = [[CDFatArch alloc] initWithDataCursor:cursor];
49 [_arches addObject:arch];
56 #pragma mark - Debugging
58 - (NSString *)description;
60 return [NSString stringWithFormat:@"<%@:%p> %lu arches", NSStringFromClass([self class]), self, [self.arches count]];
66 // Case 1: no arch specified
67 // - check main file for these, then lock down on that arch:
68 // - local arch, 64 bit
69 // - local arch, 32 bit
73 // Case 2: you specified a specific arch (i386, x86_64, ppc, ppc7400, ppc64, etc.)
76 // In either case, we can ignore the cpu subtype
78 // Returns YES on success, NO on failure.
79 - (BOOL)bestMatchForArch:(CDArch *)ioArchPtr;
81 cpu_type_t targetType = ioArchPtr->cputype & ~CPU_ARCH_MASK;
83 // Target architecture, 64 bit
84 for (CDFatArch *fatArch in self.arches) {
85 if (fatArch.maskedCPUType == targetType && fatArch.uses64BitABI) {
86 if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch;
91 // Target architecture, 32 bit
92 for (CDFatArch *fatArch in self.arches) {
93 if (fatArch.maskedCPUType == targetType && fatArch.uses64BitABI == NO) {
94 if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch;
99 // Any architecture, 64 bit
100 for (CDFatArch *fatArch in self.arches) {
101 if (fatArch.uses64BitABI) {
102 if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch;
107 // Any architecture, 32 bit
108 for (CDFatArch *fatArch in self.arches) {
109 if (fatArch.uses64BitABI == NO) {
110 if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch;
116 if ([self.arches count] > 0) {
117 if (ioArchPtr != NULL) *ioArchPtr = [self.arches[0] arch];
124 - (CDFatArch *)fatArchWithArch:(CDArch)cdarch;
126 for (CDFatArch *arch in self.arches) {
127 if (arch.cputype == cdarch.cputype && arch.maskedCPUSubtype == (cdarch.cpusubtype & ~CPU_SUBTYPE_MASK))
134 - (CDMachOFile *)machOFileWithArch:(CDArch)cdarch;
136 return [[self fatArchWithArch:cdarch] machOFile];
139 - (NSArray *)archNames;
141 NSMutableArray *archNames = [NSMutableArray array];
142 for (CDFatArch *arch in self.arches)
143 [archNames addObject:arch.archName];
148 - (NSString *)architectureNameDescription;
150 return [self.archNames componentsJoinedByString:@", "];
155 - (void)addArchitecture:(CDFatArch *)fatArch;
157 fatArch.fatFile = self;
158 [self.arches addObject:fatArch];
161 - (BOOL)containsArchitecture:(CDArch)arch;
163 return [self fatArchWithArch:arch] != nil;