Add placeholder for types that start with A, for _Atomic() types.
[class-dump.git] / Source / CDFatFile.m
blob5b806ebb915454ebebfb5373c2415f9f9c599c03
1 // -*- mode: ObjC -*-
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.
6 #import "CDFatFile.h"
8 #include <mach-o/arch.h>
9 #include <mach-o/fat.h>
11 #import "CDDataCursor.h"
12 #import "CDFatArch.h"
13 #import "CDMachOFile.h"
15 @implementation CDFatFile
17     NSMutableArray *_arches;
20 - (id)init;
22     if ((self = [super init])) {
23         _arches = [[NSMutableArray alloc] init];
24     }
25     
26     return self;
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];
36         
37         //NSLog(@"(testing fat) magic: 0x%x", header.magic);
38         if (header.magic != FAT_MAGIC) {
39             return nil;
40         }
41         
42         _arches = [[NSMutableArray alloc] init];
43         
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];
48             arch.fatFile = self;
49             [_arches addObject:arch];
50         }
51     }
53     return self;
56 #pragma mark - Debugging
58 - (NSString *)description;
60     return [NSString stringWithFormat:@"<%@:%p> %lu arches", NSStringFromClass([self class]), self, [self.arches count]];
63 #pragma mark -
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
70 //    - any arch, 64 bit
71 //    - any arch, 32 bit
73 // Case 2: you specified a specific arch (i386, x86_64, ppc, ppc7400, ppc64, etc.)
74 //  - only that arch
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;
87             return YES;
88         }
89     }
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;
95             return YES;
96         }
97     }
99     // Any architecture, 64 bit
100     for (CDFatArch *fatArch in self.arches) {
101         if (fatArch.uses64BitABI) {
102             if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch;
103             return YES;
104         }
105     }
107     // Any architecture, 32 bit
108     for (CDFatArch *fatArch in self.arches) {
109         if (fatArch.uses64BitABI == NO) {
110             if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch;
111             return YES;
112         }
113     }
115     // Any architecture
116     if ([self.arches count] > 0) {
117         if (ioArchPtr != NULL) *ioArchPtr = [self.arches[0] arch];
118         return YES;
119     }
121     return NO;
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))
128             return arch;
129     }
131     return nil;
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];
145     return archNames;
148 - (NSString *)architectureNameDescription;
150     return [self.archNames componentsJoinedByString:@", "];
153 #pragma mark -
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;
166 @end