├── CDUnitTests-Info.plist
├── CHANGELOG.md
├── Info.plist
├── MachObjC-Prefix.pch
├── README.md
├── Source
├── CDBalanceFormatter.h
├── CDBalanceFormatter.m
├── CDClassDump.h
├── CDClassDump.m
├── CDClassDumpVisitor.h
├── CDClassDumpVisitor.m
├── CDClassFrameworkVisitor.h
├── CDClassFrameworkVisitor.m
├── CDDataCursor.h
├── CDDataCursor.m
├── CDExtensions.h
├── CDFatArch.h
├── CDFatArch.m
├── CDFatFile.h
├── CDFatFile.m
├── CDFile.h
├── CDFile.m
├── CDFindMethodVisitor.h
├── CDFindMethodVisitor.m
├── CDLCBuildVersion.h
├── CDLCBuildVersion.m
├── CDLCDataInCode.h
├── CDLCDataInCode.m
├── CDLCDyldInfo.h
├── CDLCDyldInfo.m
├── CDLCDylib.h
├── CDLCDylib.m
├── CDLCDylinker.h
├── CDLCDylinker.m
├── CDLCDynamicSymbolTable.h
├── CDLCDynamicSymbolTable.m
├── CDLCEncryptionInfo.h
├── CDLCEncryptionInfo.m
├── CDLCFunctionStarts.h
├── CDLCFunctionStarts.m
├── CDLCLinkeditData.h
├── CDLCLinkeditData.m
├── CDLCMain.h
├── CDLCMain.m
├── CDLCPrebindChecksum.h
├── CDLCPrebindChecksum.m
├── CDLCPreboundDylib.h
├── CDLCPreboundDylib.m
├── CDLCRoutines32.h
├── CDLCRoutines32.m
├── CDLCRoutines64.h
├── CDLCRoutines64.m
├── CDLCRunPath.h
├── CDLCRunPath.m
├── CDLCSegment.h
├── CDLCSegment.m
├── CDLCSourceVersion.h
├── CDLCSourceVersion.m
├── CDLCSubClient.h
├── CDLCSubClient.m
├── CDLCSubFramework.h
├── CDLCSubFramework.m
├── CDLCSubLibrary.h
├── CDLCSubLibrary.m
├── CDLCSubUmbrella.h
├── CDLCSubUmbrella.m
├── CDLCSymbolTable.h
├── CDLCSymbolTable.m
├── CDLCTwoLevelHints.h
├── CDLCTwoLevelHints.m
├── CDLCUUID.h
├── CDLCUUID.m
├── CDLCUnixThread.h
├── CDLCUnixThread.m
├── CDLCUnknown.h
├── CDLCUnknown.m
├── CDLCVersionMinimum.h
├── CDLCVersionMinimum.m
├── CDLoadCommand.h
├── CDLoadCommand.m
├── CDMachOFile.h
├── CDMachOFile.m
├── CDMachOFileDataCursor.h
├── CDMachOFileDataCursor.m
├── CDMethodType.h
├── CDMethodType.m
├── CDMultiFileVisitor.h
├── CDMultiFileVisitor.m
├── CDOCCategory.h
├── CDOCCategory.m
├── CDOCClass.h
├── CDOCClass.m
├── CDOCClassReference.h
├── CDOCClassReference.m
├── CDOCInstanceVariable.h
├── CDOCInstanceVariable.m
├── CDOCMethod.h
├── CDOCMethod.m
├── CDOCModule.h
├── CDOCModule.m
├── CDOCProperty.h
├── CDOCProperty.m
├── CDOCProtocol.h
├── CDOCProtocol.m
├── CDOCSymtab.h
├── CDOCSymtab.m
├── CDObjectiveC1Processor.h
├── CDObjectiveC1Processor.m
├── CDObjectiveC2Processor.h
├── CDObjectiveC2Processor.m
├── CDObjectiveCProcessor.h
├── CDObjectiveCProcessor.m
├── CDProtocolUniquer.h
├── CDProtocolUniquer.m
├── CDRelocationInfo.h
├── CDRelocationInfo.m
├── CDSearchPathState.h
├── CDSearchPathState.m
├── CDSection.h
├── CDSection.m
├── CDStructureInfo.h
├── CDStructureInfo.m
├── CDStructureTable.h
├── CDStructureTable.m
├── CDSymbol.h
├── CDSymbol.m
├── CDTextClassDumpVisitor.h
├── CDTextClassDumpVisitor.m
├── CDTopoSortNode.h
├── CDTopoSortNode.m
├── CDTopologicalSortProtocol.h
├── CDType.h
├── CDType.m
├── CDTypeController.h
├── CDTypeController.m
├── CDTypeFormatter.h
├── CDTypeFormatter.m
├── CDTypeLexer.h
├── CDTypeLexer.m
├── CDTypeName.h
├── CDTypeName.m
├── CDTypeParser.h
├── CDTypeParser.m
├── CDVisitor.h
├── CDVisitor.m
├── CDVisitorPropertyState.h
├── CDVisitorPropertyState.m
├── NSArray-CDExtensions.h
├── NSArray-CDExtensions.m
├── NSData-CDExtensions.h
├── NSData-CDExtensions.m
├── NSError-CDExtensions.h
├── NSError-CDExtensions.m
├── NSScanner-CDExtensions.h
├── NSScanner-CDExtensions.m
├── NSString-CDExtensions.h
├── NSString-CDExtensions.m
├── ULEB128.h
├── ULEB128.m
└── cd_objc2.h
├── Tests
├── doTests.py
└── showdiff
├── ThirdParty
├── blowfish.c
└── blowfish.h
├── UnitTests.old
├── AllTests.h
├── AllTests.m
├── CDPathUnitTest.h
├── CDPathUnitTest.m
├── CDStructHandlingUnitTest.h
├── CDStructHandlingUnitTest.m
├── CDTypeFormatterUnitTest.h
├── CDTypeFormatterUnitTest.m
├── CDTypeLexerUnitTest.h
├── CDTypeLexerUnitTest.m
├── CDTypeParserUnitTest.h
├── CDTypeParserUnitTest.m
├── method-001.txt
├── otest-all
├── shud01-in.txt
├── shud01-out.txt
├── shud02-in.txt
├── shud02-out.txt
├── shud04-in.txt
├── shud04-out.txt
├── shud05-in.txt
├── shud05-out.txt
├── shud06-in.txt
├── shud06-out.txt
├── shud07-in.txt
├── shud07-out.txt
├── shud08-in.txt
├── shud08-out.txt
├── shud09-in.txt
├── shud09-out.txt
├── shud10-in.txt
├── shud10-out.txt
├── shud11-in.txt
├── shud11-out.txt
├── shud13-in.txt
├── shud13-out.txt
├── shud14-in.txt
├── shud14-out.txt
├── shud15-in.txt
├── shud15-out.txt
├── shud16-in.txt
├── shud16-out.txt
├── var-001.txt
├── var-002.txt
├── var-003.txt
├── var-004.txt
└── var-005.txt
├── UnitTests
├── TestBlockSignature.m
├── TestCDArchFromName.m
├── TestCDArchUses64BitABI.m
├── TestCDNameForCPUType.m
├── TestFatFile_Intel32_64.m
├── TestFatFile_Intel32_64_lib64.m
├── TestFatFile_Intel64_32.m
├── TestFatFile_armv7_v7s.m
├── TestThinFile_Intel64.m
├── TestThinFile_Intel64_lib64.m
├── UnitTests-Info.plist
├── UnitTests-Prefix.pch
└── en.lproj
│ └── InfoPlist.strings
├── class-dump-Prefix.pch
├── class-dump.m
├── class-dump.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── nygard.xcuserdatad
│ │ └── WorkspaceSettings.xcsettings
└── xcuserdata
│ └── nygard.xcuserdatad
│ └── xcschemes
│ ├── MachObjC.xcscheme
│ ├── all.xcscheme
│ ├── class-dump.xcscheme
│ ├── deprotect.xcscheme
│ ├── formatType.xcscheme
│ └── xcschememanagement.plist
├── deprotect-Prefix.pch
├── deprotect.m
├── formatType-Prefix.pch
├── formatType.m
└── keys.txt
/CDUnitTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.stevenygard.CDUnitTests
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleSignature
16 | ????
17 | CFBundleVersion
18 | 1.0
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleIdentifier
8 | com.stevenygard.class-dump
9 | CFBundleInfoDictionaryVersion
10 | 6.0
11 | CFBundleName
12 | class-dump
13 |
14 |
15 |
--------------------------------------------------------------------------------
/MachObjC-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'libMachObjC' target in the 'class-dump' project.
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import "CDExtensions.h"
8 | #define __cmd __PRETTY_FUNCTION__
9 | #endif
10 |
--------------------------------------------------------------------------------
/Source/CDBalanceFormatter.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface CDBalanceFormatter : NSObject
7 |
8 | - (id)initWithString:(NSString *)str;
9 |
10 | - (void)parse:(NSString *)open index:(NSUInteger)openIndex level:(NSUInteger)level;
11 |
12 | - (NSString *)format;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Source/CDBalanceFormatter.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDBalanceFormatter.h"
7 |
8 | static BOOL debug = NO;
9 |
10 | @implementation CDBalanceFormatter
11 | {
12 | NSScanner *_scanner;
13 | NSCharacterSet *_openCloseSet;
14 |
15 | NSMutableString *_result;
16 | }
17 |
18 | - (id)initWithString:(NSString *)str;
19 | {
20 | if ((self = [super init])) {
21 | _scanner = [[NSScanner alloc] initWithString:str];
22 | _openCloseSet = [NSCharacterSet characterSetWithCharactersInString:@"{}<>()"];
23 |
24 | _result = [[NSMutableString alloc] init];
25 | }
26 |
27 | return self;
28 | }
29 |
30 | #pragma mark -
31 |
32 | - (void)parse:(NSString *)open index:(NSUInteger)openIndex level:(NSUInteger)level;
33 | {
34 | NSString *opens[] = { @"{", @"<", @"(", nil};
35 | NSString *closes[] = { @"}", @">", @")", nil};
36 | BOOL foundOpen = NO;
37 | BOOL foundClose = NO;
38 |
39 | while ([_scanner isAtEnd] == NO) {
40 | NSString *pre;
41 |
42 | if ([_scanner scanUpToCharactersFromSet:_openCloseSet intoString:&pre]) {
43 | if (debug) NSLog(@"pre = '%@'", pre);
44 | [_result appendFormat:@"%@%@\n", [NSString spacesIndentedToLevel:level], pre];
45 | }
46 | if (debug) NSLog(@"remaining: '%@'", [[_scanner string] substringFromIndex:[_scanner scanLocation]]);
47 |
48 | foundOpen = foundClose = NO;
49 | for (NSUInteger index = 0; index < 3; index++) {
50 | if (debug) NSLog(@"Checking open %lu: '%@'", index, opens[index]);
51 | if ([_scanner scanString:opens[index] intoString:NULL]) {
52 | if (debug) NSLog(@"Start %@", opens[index]);
53 | [_result appendSpacesIndentedToLevel:level];
54 | [_result appendString:opens[index]];
55 | [_result appendString:@"\n"];
56 |
57 | [self parse:opens[index] index:[_scanner scanLocation] - 1 level:level + 1];
58 |
59 | [_result appendSpacesIndentedToLevel:level];
60 | [_result appendString:closes[index]];
61 | [_result appendString:@"\n"];
62 | foundOpen = YES;
63 | break;
64 | }
65 |
66 | if (debug) NSLog(@"Checking close %lu: '%@'", index, closes[index]);
67 | if ([_scanner scanString:closes[index] intoString:NULL]) {
68 | if ([open isEqualToString:opens[index]]) {
69 | if (debug) NSLog(@"End %@", closes[index]);
70 | } else {
71 | NSLog(@"ERROR: Unmatched end %@", closes[index]);
72 | }
73 | foundClose = YES;
74 | break;
75 | }
76 | }
77 |
78 | if (foundOpen == NO && foundClose == NO) {
79 | if (debug) NSLog(@"Unknown @ %lu: %@", [_scanner scanLocation], [[_scanner string] substringFromIndex:[_scanner scanLocation]]);
80 | break;
81 | }
82 |
83 | if (foundClose)
84 | break;
85 | }
86 | }
87 |
88 | - (NSString *)format;
89 | {
90 | [self parse:nil index:0 level:0];
91 |
92 | if (debug) NSLog(@"result:\n%@", _result);
93 |
94 | return [NSString stringWithString:_result];
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/Source/CDClassDump.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDFile.h" // For CDArch
7 |
8 | #define CLASS_DUMP_BASE_VERSION "3.5 (64 bit)"
9 |
10 | #ifdef DEBUG
11 | #define CLASS_DUMP_VERSION CLASS_DUMP_BASE_VERSION " (Debug version compiled " __DATE__ " " __TIME__ ")"
12 | #else
13 | #define CLASS_DUMP_VERSION CLASS_DUMP_BASE_VERSION
14 | #endif
15 |
16 | @class CDFile;
17 | @class CDTypeController;
18 | @class CDVisitor;
19 | @class CDSearchPathState;
20 |
21 | @interface CDClassDump : NSObject
22 |
23 | @property (readonly) CDSearchPathState *searchPathState;
24 |
25 | @property (assign) BOOL shouldProcessRecursively;
26 | @property (assign) BOOL shouldSortClasses;
27 | @property (assign) BOOL shouldSortClassesByInheritance;
28 | @property (assign) BOOL shouldSortMethods;
29 | @property (assign) BOOL shouldShowIvarOffsets;
30 | @property (assign) BOOL shouldShowMethodAddresses;
31 | @property (assign) BOOL shouldShowHeader;
32 |
33 | @property (strong) NSRegularExpression *regularExpression;
34 | - (BOOL)shouldShowName:(NSString *)name;
35 |
36 | @property (strong) NSString *sdkRoot;
37 |
38 | @property (readonly) NSArray *machOFiles;
39 | @property (readonly) NSArray *objcProcessors;
40 |
41 | @property (assign) CDArch targetArch;
42 |
43 | @property (nonatomic, readonly) BOOL containsObjectiveCData;
44 | @property (nonatomic, readonly) BOOL hasEncryptedFiles;
45 | @property (nonatomic, readonly) BOOL hasObjectiveCRuntimeInfo;
46 |
47 | @property (readonly) CDTypeController *typeController;
48 |
49 | - (BOOL)loadFile:(CDFile *)file error:(NSError **)error;
50 | - (void)processObjectiveCData;
51 |
52 | - (void)recursivelyVisit:(CDVisitor *)visitor;
53 |
54 | - (void)appendHeaderToString:(NSMutableString *)resultString;
55 |
56 | - (void)registerTypes;
57 |
58 | - (void)showHeader;
59 | - (void)showLoadCommands;
60 |
61 | @end
62 |
63 | extern NSString *CDErrorDomain_ClassDump;
64 | extern NSString *CDErrorKey_Exception;
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Source/CDClassDumpVisitor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDTextClassDumpVisitor.h"
7 |
8 | @interface CDClassDumpVisitor : CDTextClassDumpVisitor
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDClassFrameworkVisitor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDVisitor.h"
7 |
8 | // This builds up a dictionary mapping class names to a framework names.
9 | // It is only used by CDMultiFileVisitor to generate individual imports when creating separate header files.
10 |
11 | // Some protocols appear in multiple frameworks. This just records the last framework that contained a reference, which
12 | // produces incorrect results. For example, -r AppKit.framework, and Foundation.framework is processed before several
13 | // others, including Symbolication.
14 |
15 | // If we follow framework dependancies, the earliest reference to NSCopying is CoreFoundation, but NSCopying is really
16 | // defined in Foundation.
17 |
18 | // But it turns out that we can just use forward references for protocols.
19 |
20 | @interface CDClassFrameworkVisitor : CDVisitor
21 |
22 | // NSString (class name) -> NSString (framework name)
23 | @property (nonatomic, readonly) NSDictionary *frameworkNamesByClassName;
24 |
25 | // NSString (protocol name) -> NSString (framework name)
26 | @property (nonatomic, readonly) NSDictionary *frameworkNamesByProtocolName;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/Source/CDClassFrameworkVisitor.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDClassFrameworkVisitor.h"
7 |
8 | #import "CDMachOFile.h"
9 | #import "CDOCClass.h"
10 | #import "CDObjectiveCProcessor.h"
11 | #import "CDSymbol.h"
12 | #import "CDLCDylib.h"
13 | #import "CDOCCategory.h"
14 | #import "CDOCClassReference.h"
15 |
16 | @interface CDClassFrameworkVisitor ()
17 | @property (strong) NSString *frameworkName;
18 | @end
19 |
20 | #pragma mark -
21 |
22 | @implementation CDClassFrameworkVisitor
23 | {
24 | NSMutableDictionary *_frameworkNamesByClassName;
25 | NSMutableDictionary *_frameworkNamesByProtocolName;
26 | NSString *_frameworkName;
27 | }
28 |
29 | - (id)init;
30 | {
31 | if ((self = [super init])) {
32 | _frameworkNamesByClassName = [[NSMutableDictionary alloc] init];
33 | _frameworkNamesByProtocolName = [[NSMutableDictionary alloc] init];
34 | }
35 |
36 | return self;
37 | }
38 |
39 | #pragma mark -
40 |
41 | - (void)willVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
42 | {
43 | self.frameworkName = processor.machOFile.importBaseName;
44 | }
45 |
46 | - (void)willVisitClass:(CDOCClass *)aClass;
47 | {
48 | [self addClassName:aClass.name referencedInFramework:self.frameworkName];
49 |
50 | // We only need to add superclasses for external classes - classes defined in this binary will be visited on their own
51 | CDOCClassReference *superClassRef = [aClass superClassRef];
52 | if ([superClassRef isExternalClass] && superClassRef.classSymbol != nil) {
53 | [self addClassForExternalSymbol:superClassRef.classSymbol];
54 | }
55 | }
56 |
57 | - (void)willVisitProtocol:(CDOCProtocol *)protocol;
58 | {
59 | // TODO: (2012-02-28) Figure out what frameworks use each protocol, and try to pick the correct one. More difficult because, for example, NSCopying is found in many frameworks, and picking the last one isn't good enough. Perhaps a topological sort of the dependancies would be better.
60 | [self addProtocolName:protocol.name referencedInFramework:self.frameworkName];
61 | }
62 |
63 | - (void)willVisitCategory:(CDOCCategory *)category;
64 | {
65 | CDOCClassReference *classRef = [category classRef];
66 | if ([classRef isExternalClass] && classRef.classSymbol != nil) {
67 | [self addClassForExternalSymbol:classRef.classSymbol];
68 | }
69 | }
70 |
71 | #pragma mark -
72 |
73 | - (void)addClassForExternalSymbol:(CDSymbol *)symbol;
74 | {
75 | NSString *frameworkName = CDImportNameForPath([[symbol dylibLoadCommand] path]);
76 | NSString *className = [CDSymbol classNameFromSymbolName:[symbol name]];
77 | [self addClassName:className referencedInFramework:frameworkName];
78 | }
79 |
80 | - (void)addClassName:(NSString *)name referencedInFramework:(NSString *)frameworkName;
81 | {
82 | if (name != nil && frameworkName != nil)
83 | _frameworkNamesByClassName[name] = frameworkName;
84 | }
85 |
86 | - (void)addProtocolName:(NSString *)name referencedInFramework:(NSString *)frameworkName;
87 | {
88 | if (name != nil && frameworkName != nil)
89 | _frameworkNamesByProtocolName[name] = frameworkName;
90 | }
91 |
92 | - (NSDictionary *)frameworkNamesByClassName;
93 | {
94 | return [_frameworkNamesByClassName copy];
95 | }
96 |
97 | - (NSDictionary *)frameworkNamesByProtocolName;
98 | {
99 | return [_frameworkNamesByProtocolName copy];
100 | }
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/Source/CDDataCursor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface CDDataCursor : NSObject
7 |
8 | - (id)initWithData:(NSData *)data;
9 |
10 | @property (readonly) NSData *data;
11 | - (const void *)bytes;
12 |
13 | @property (nonatomic, assign) NSUInteger offset;
14 |
15 | - (void)advanceByLength:(NSUInteger)length;
16 | - (NSUInteger)remaining;
17 |
18 | - (uint8_t)readByte;
19 |
20 | - (uint16_t)readLittleInt16;
21 | - (uint32_t)readLittleInt32;
22 | - (uint64_t)readLittleInt64;
23 |
24 | - (uint16_t)readBigInt16;
25 | - (uint32_t)readBigInt32;
26 | - (uint64_t)readBigInt64;
27 |
28 | - (float)readLittleFloat32;
29 | - (float)readBigFloat32;
30 |
31 | - (double)readLittleFloat64;
32 | //- (double)readBigFloat64;
33 |
34 | - (void)appendBytesOfLength:(NSUInteger)length intoData:(NSMutableData *)data;
35 | - (void)readBytesOfLength:(NSUInteger)length intoBuffer:(void *)buf;
36 | - (BOOL)isAtEnd;
37 |
38 | - (NSString *)readCString;
39 | - (NSString *)readStringOfLength:(NSUInteger)length encoding:(NSStringEncoding)encoding;
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Source/CDExtensions.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDTopoSortNode.h"
7 | #import "NSArray-CDExtensions.h"
8 | #import "NSData-CDExtensions.h"
9 | #import "NSData-CDExtensions.h"
10 | #import "NSError-CDExtensions.h"
11 | #import "NSScanner-CDExtensions.h"
12 | #import "NSString-CDExtensions.h"
13 |
--------------------------------------------------------------------------------
/Source/CDFatArch.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDFile.h" // For CDArch
7 |
8 | @class CDDataCursor;
9 | @class CDFatFile, CDMachOFile;
10 |
11 | @interface CDFatArch : NSObject
12 |
13 | - (id)initWithMachOFile:(CDMachOFile *)machOFile;
14 | - (id)initWithDataCursor:(CDDataCursor *)cursor;
15 |
16 | @property (assign) cpu_type_t cputype;
17 | @property (assign) cpu_subtype_t cpusubtype;
18 | @property (assign) uint32_t offset;
19 | @property (assign) uint32_t size;
20 | @property (assign) uint32_t align;
21 |
22 | @property (nonatomic, readonly) cpu_type_t maskedCPUType;
23 | @property (nonatomic, readonly) cpu_subtype_t maskedCPUSubtype;
24 | @property (nonatomic, readonly) BOOL uses64BitABI;
25 | @property (nonatomic, readonly) BOOL uses64BitLibraries;
26 |
27 | @property (weak) CDFatFile *fatFile;
28 |
29 | @property (nonatomic, readonly) CDArch arch;
30 | @property (nonatomic, readonly) NSString *archName;
31 |
32 | @property (nonatomic, readonly) CDMachOFile *machOFile;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/Source/CDFatArch.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDFatArch.h"
7 |
8 | #include
9 | #import "CDDataCursor.h"
10 | #import "CDFatFile.h"
11 | #import "CDMachOFile.h"
12 |
13 | @implementation CDFatArch
14 | {
15 | __weak CDFatFile *_fatFile;
16 |
17 | // This is essentially struct fat_arch, but this way our property accessors can be synthesized.
18 | cpu_type_t _cputype;
19 | cpu_subtype_t _cpusubtype;
20 | uint32_t _offset;
21 | uint32_t _size;
22 | uint32_t _align;
23 |
24 | CDMachOFile *_machOFile; // Lazily create this.
25 | }
26 |
27 | - (id)initWithMachOFile:(CDMachOFile *)machOFile;
28 | {
29 | if ((self = [super init])) {
30 | _machOFile = machOFile;
31 | NSParameterAssert([machOFile.data length] < 0x100000000);
32 |
33 | _cputype = _machOFile.cputype;
34 | _cpusubtype = _machOFile.cpusubtype;
35 | _offset = 0; // Would be filled in when this is written to disk
36 | _size = (uint32_t)[_machOFile.data length];
37 | _align = 12; // 2**12 = 4096 (0x1000)
38 | }
39 |
40 | return self;
41 | }
42 |
43 | - (id)initWithDataCursor:(CDDataCursor *)cursor;
44 | {
45 | if ((self = [super init])) {
46 | _cputype = [cursor readBigInt32];
47 | _cpusubtype = [cursor readBigInt32];
48 | _offset = [cursor readBigInt32];
49 | _size = [cursor readBigInt32];
50 | _align = [cursor readBigInt32];
51 |
52 | //NSLog(@"self: %@", self);
53 | }
54 |
55 | return self;
56 | }
57 |
58 | #pragma mark - Debugging
59 |
60 | - (NSString *)description;
61 | {
62 | return [NSString stringWithFormat:@"64 bit ABI? %d, cputype: 0x%08x, cpusubtype: 0x%08x, offset: 0x%08x (%8u), size: 0x%08x (%8u), align: 2^%u (%x), arch name: %@",
63 | self.uses64BitABI, self.cputype, self.cpusubtype, self.offset, self.offset, self.size, self.size,
64 | self.align, 1 << self.align, self.archName];
65 | }
66 |
67 | #pragma mark -
68 |
69 | - (cpu_type_t)maskedCPUType;
70 | {
71 | return self.cputype & ~CPU_ARCH_MASK;
72 | }
73 |
74 | - (cpu_subtype_t)maskedCPUSubtype;
75 | {
76 | return self.cpusubtype & ~CPU_SUBTYPE_MASK;
77 | }
78 |
79 | - (BOOL)uses64BitABI;
80 | {
81 | return CDArchUses64BitABI(self.arch);
82 | }
83 |
84 | - (BOOL)uses64BitLibraries;
85 | {
86 | return CDArchUses64BitLibraries(self.arch);
87 | }
88 |
89 | - (CDArch)arch;
90 | {
91 | CDArch arch = { self.cputype, self.cpusubtype };
92 |
93 | return arch;
94 | }
95 |
96 | // Must not return nil.
97 | - (NSString *)archName;
98 | {
99 | return CDNameForCPUType(self.cputype, self.cpusubtype);
100 | }
101 |
102 | - (CDMachOFile *)machOFile;
103 | {
104 | if (_machOFile == nil) {
105 | NSData *data = [NSData dataWithBytesNoCopy:((uint8_t *)[self.fatFile.data bytes] + self.offset) length:self.size freeWhenDone:NO];
106 | _machOFile = [[CDMachOFile alloc] initWithData:data filename:self.fatFile.filename searchPathState:self.fatFile.searchPathState];
107 | }
108 |
109 | return _machOFile;
110 | }
111 |
112 | @end
113 |
--------------------------------------------------------------------------------
/Source/CDFatFile.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDFile.h"
7 |
8 | @class CDFatArch;
9 |
10 | @interface CDFatFile : CDFile
11 |
12 | @property (readonly) NSMutableArray *arches;
13 | @property (nonatomic, readonly) NSArray *archNames;
14 |
15 | - (void)addArchitecture:(CDFatArch *)fatArch;
16 | - (BOOL)containsArchitecture:(CDArch)arch;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Source/CDFile.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #include // For cpu_type_t, cpu_subtype_t
7 |
8 | typedef struct {
9 | cpu_type_t cputype;
10 | cpu_subtype_t cpusubtype;
11 | } CDArch;
12 |
13 | @class CDMachOFile, CDSearchPathState;
14 |
15 | NSString *CDImportNameForPath(NSString *path);
16 | NSString *CDNameForCPUType(cpu_type_t cputype, cpu_subtype_t cpusubtype);
17 | CDArch CDArchFromName(NSString *name);
18 | BOOL CDArchUses64BitABI(CDArch arch);
19 | BOOL CDArchUses64BitLibraries(CDArch arch);
20 |
21 | @interface CDFile : NSObject
22 |
23 | // Returns CDFatFile or CDMachOFile
24 | + (id)fileWithContentsOfFile:(NSString *)filename searchPathState:(CDSearchPathState *)searchPathState;
25 |
26 | - (id)initWithData:(NSData *)data filename:(NSString *)filename searchPathState:(CDSearchPathState *)searchPathState;
27 |
28 | @property (readonly) NSString *filename;
29 | @property (readonly) NSData *data;
30 | @property (readonly) CDSearchPathState *searchPathState;
31 |
32 | - (BOOL)bestMatchForLocalArch:(CDArch *)oArchPtr;
33 | - (BOOL)bestMatchForArch:(CDArch *)ioArchPtr;
34 | - (CDMachOFile *)machOFileWithArch:(CDArch)arch;
35 |
36 | @property (nonatomic, readonly) NSString *architectureNameDescription;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/Source/CDFindMethodVisitor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDVisitor.h"
7 |
8 | // This limits the output to methods matching the search string. Some context is included, so that you can see which class, category, or protocol
9 | // contains the method.
10 |
11 | @interface CDFindMethodVisitor : CDVisitor
12 |
13 | @property (strong) NSString *searchString;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Source/CDLCBuildVersion.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCBuildVersion : CDLoadCommand
9 |
10 | @property (nonatomic, readonly) NSString *buildVersionString;
11 | @property (nonatomic, readonly) NSArray *toolStrings;
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCDataInCode.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCLinkeditData.h"
7 |
8 | @interface CDLCDataInCode : CDLCLinkeditData
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDLCDataInCode.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCDataInCode.h"
7 |
8 | #import "CDMachOFile.h"
9 |
10 | @implementation CDLCDataInCode
11 | {
12 | }
13 |
14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
15 | {
16 | if ((self = [super initWithDataCursor:cursor])) {
17 | }
18 |
19 | return self;
20 | }
21 |
22 | #pragma mark -
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Source/CDLCDyldInfo.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCDyldInfo : CDLoadCommand
9 |
10 | - (NSString *)symbolNameForAddress:(NSUInteger)address;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCDylib.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCDylib : CDLoadCommand
9 |
10 | @property (readonly) NSString *path;
11 | @property (nonatomic, readonly) uint32_t timestamp;
12 | @property (nonatomic, readonly) uint32_t currentVersion;
13 | @property (nonatomic, readonly) uint32_t compatibilityVersion;
14 |
15 | @property (nonatomic, readonly) NSString *formattedCurrentVersion;
16 | @property (nonatomic, readonly) NSString *formattedCompatibilityVersion;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Source/CDLCDylib.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCDylib.h"
7 |
8 | #import "CDFatFile.h"
9 | #import "CDMachOFile.h"
10 |
11 | static NSString *CDDylibVersionString(uint32_t version)
12 | {
13 | return [NSString stringWithFormat:@"%d.%d.%d", version >> 16, (version >> 8) & 0xff, version & 0xff];
14 | }
15 |
16 | @implementation CDLCDylib
17 | {
18 | struct dylib_command _dylibCommand;
19 | NSString *_path;
20 | }
21 |
22 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
23 | {
24 | if ((self = [super initWithDataCursor:cursor])) {
25 | _dylibCommand.cmd = [cursor readInt32];
26 | _dylibCommand.cmdsize = [cursor readInt32];
27 |
28 | _dylibCommand.dylib.name.offset = [cursor readInt32];
29 | _dylibCommand.dylib.timestamp = [cursor readInt32];
30 | _dylibCommand.dylib.current_version = [cursor readInt32];
31 | _dylibCommand.dylib.compatibility_version = [cursor readInt32];
32 |
33 | NSUInteger length = _dylibCommand.cmdsize - sizeof(_dylibCommand);
34 | //NSLog(@"expected length: %u", length);
35 |
36 | _path = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding];
37 | //NSLog(@"path: %@", path);
38 | }
39 |
40 | return self;
41 | }
42 |
43 | #pragma mark -
44 |
45 | - (uint32_t)cmd;
46 | {
47 | return _dylibCommand.cmd;
48 | }
49 |
50 | - (uint32_t)cmdsize;
51 | {
52 | return _dylibCommand.cmdsize;
53 | }
54 |
55 | - (uint32_t)timestamp;
56 | {
57 | return _dylibCommand.dylib.timestamp;
58 | }
59 |
60 | - (uint32_t)currentVersion;
61 | {
62 | return _dylibCommand.dylib.current_version;
63 | }
64 |
65 | - (uint32_t)compatibilityVersion;
66 | {
67 | return _dylibCommand.dylib.compatibility_version;
68 | }
69 |
70 | - (NSString *)formattedCurrentVersion;
71 | {
72 | return CDDylibVersionString(self.currentVersion);
73 | }
74 |
75 | - (NSString *)formattedCompatibilityVersion;
76 | {
77 | return CDDylibVersionString(self.compatibilityVersion);
78 | }
79 |
80 | #if 0
81 | - (NSString *)extraDescription;
82 | {
83 | return [NSString stringWithFormat:@"%@ (compatibility version %@, current version %@, timestamp %d [%@])",
84 | self.path, CDDylibVersionString(self.compatibilityVersion), CDDylibVersionString(self.currentVersion),
85 | self.timestamp, [NSDate dateWithTimeIntervalSince1970:self.timestamp]];
86 | }
87 | #endif
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/Source/CDLCDylinker.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCDylinker : CDLoadCommand
9 |
10 | @property (readonly) NSString *name;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCDylinker.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCDylinker.h"
7 |
8 | @implementation CDLCDylinker
9 | {
10 | struct dylinker_command _dylinkerCommand;
11 | NSString *_name;
12 | }
13 |
14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
15 | {
16 | if ((self = [super initWithDataCursor:cursor])) {
17 | _dylinkerCommand.cmd = [cursor readInt32];
18 | _dylinkerCommand.cmdsize = [cursor readInt32];
19 |
20 | _dylinkerCommand.name.offset = [cursor readInt32];
21 |
22 | NSUInteger length = _dylinkerCommand.cmdsize - sizeof(_dylinkerCommand);
23 | //NSLog(@"expected length: %u", length);
24 |
25 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding];
26 | //NSLog(@"name: %@", name);
27 | }
28 |
29 | return self;
30 | }
31 |
32 | #pragma mark -
33 |
34 | - (uint32_t)cmd;
35 | {
36 | return _dylinkerCommand.cmd;
37 | }
38 |
39 | - (uint32_t)cmdsize;
40 | {
41 | return _dylinkerCommand.cmdsize;
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/Source/CDLCDynamicSymbolTable.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @class CDRelocationInfo;
9 |
10 | @interface CDLCDynamicSymbolTable : CDLoadCommand
11 |
12 | - (void)loadSymbols;
13 |
14 | - (CDRelocationInfo *)relocationEntryWithOffset:(NSUInteger)offset;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Source/CDLCEncryptionInfo.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCEncryptionInfo : CDLoadCommand
9 |
10 | @property (nonatomic, readonly) uint32_t cryptoff;
11 | @property (nonatomic, readonly) uint32_t cryptsize;
12 | @property (nonatomic, readonly) uint32_t cryptid;
13 |
14 | @property (nonatomic, readonly) BOOL isEncrypted;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Source/CDLCEncryptionInfo.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCEncryptionInfo.h"
7 |
8 | // This is used on iOS.
9 |
10 | @implementation CDLCEncryptionInfo
11 | {
12 | struct encryption_info_command_64 _encryptionInfoCommand;
13 | }
14 |
15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
16 | {
17 | if ((self = [super initWithDataCursor:cursor])) {
18 | _encryptionInfoCommand.cmd = [cursor readInt32];
19 | _encryptionInfoCommand.cmdsize = [cursor readInt32];
20 |
21 | _encryptionInfoCommand.cryptoff = [cursor readInt32];
22 | _encryptionInfoCommand.cryptsize = [cursor readInt32];
23 | _encryptionInfoCommand.cryptid = [cursor readInt32];
24 | if (_encryptionInfoCommand.cmd == LC_ENCRYPTION_INFO_64) {
25 | _encryptionInfoCommand.pad = [cursor readInt32];
26 | }
27 | }
28 |
29 | return self;
30 | }
31 |
32 | #pragma mark -
33 |
34 | - (uint32_t)cmd;
35 | {
36 | return _encryptionInfoCommand.cmd;
37 | }
38 |
39 | - (uint32_t)cmdsize;
40 | {
41 | return _encryptionInfoCommand.cmdsize;
42 | }
43 |
44 | - (uint32_t)cryptoff;
45 | {
46 | return _encryptionInfoCommand.cryptoff;
47 | }
48 |
49 | - (uint32_t)cryptsize;
50 | {
51 | return _encryptionInfoCommand.cryptsize;
52 | }
53 |
54 | - (uint32_t)cryptid;
55 | {
56 | return _encryptionInfoCommand.cryptid;
57 | }
58 |
59 | - (BOOL)isEncrypted;
60 | {
61 | return _encryptionInfoCommand.cryptid != 0;
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/Source/CDLCFunctionStarts.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCLinkeditData.h"
7 |
8 | @interface CDLCFunctionStarts : CDLCLinkeditData
9 |
10 | @property (nonatomic, readonly) NSArray *functionStarts;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCFunctionStarts.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCFunctionStarts.h"
7 |
8 | #import "ULEB128.h"
9 |
10 | @implementation CDLCFunctionStarts
11 | {
12 | NSArray *_functionStarts;
13 | }
14 |
15 | #pragma mark -
16 |
17 | - (NSArray *)functionStarts;
18 | {
19 | if (_functionStarts == nil) {
20 | NSData *functionStartsData = [self linkeditData];
21 | const uint8_t *start = (uint8_t *)[functionStartsData bytes];
22 | const uint8_t *end = start + [functionStartsData length];
23 | uint64_t startAddress;
24 | uint64_t previousAddress = 0;
25 | NSMutableArray *functionStarts = [[NSMutableArray alloc] init];
26 | while ((startAddress = read_uleb128(&start, end))) {
27 | [functionStarts addObject:@(startAddress + previousAddress)];
28 | previousAddress += startAddress;
29 | }
30 | _functionStarts = [functionStarts copy];
31 | }
32 | return _functionStarts;
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/Source/CDLCLinkeditData.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCLinkeditData : CDLoadCommand
9 |
10 | @property (nonatomic, readonly) NSData *linkeditData;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCLinkeditData.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCLinkeditData.h"
7 |
8 | #import "CDMachOFile.h"
9 |
10 | @implementation CDLCLinkeditData
11 | {
12 | struct linkedit_data_command _linkeditDataCommand;
13 | NSData *_linkeditData;
14 | }
15 |
16 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
17 | {
18 | if ((self = [super initWithDataCursor:cursor])) {
19 | _linkeditDataCommand.cmd = [cursor readInt32];
20 | _linkeditDataCommand.cmdsize = [cursor readInt32];
21 |
22 | _linkeditDataCommand.dataoff = [cursor readInt32];
23 | _linkeditDataCommand.datasize = [cursor readInt32];
24 | }
25 |
26 | return self;
27 | }
28 |
29 | #pragma mark -
30 |
31 | - (uint32_t)cmd;
32 | {
33 | return _linkeditDataCommand.cmd;
34 | }
35 |
36 | - (uint32_t)cmdsize;
37 | {
38 | return _linkeditDataCommand.cmdsize;
39 | }
40 |
41 | - (NSData *)linkeditData;
42 | {
43 | if (_linkeditData == NULL) {
44 | _linkeditData = [[NSData alloc] initWithBytes:[self.machOFile bytesAtOffset:_linkeditDataCommand.dataoff] length:_linkeditDataCommand.datasize];
45 | }
46 |
47 | return _linkeditData;
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Source/CDLCMain.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCMain : CDLoadCommand
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDLCMain.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCMain.h"
7 |
8 | @implementation CDLCMain
9 | {
10 | struct entry_point_command _entryPointCommand;
11 | }
12 |
13 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
14 | {
15 | if ((self = [super initWithDataCursor:cursor])) {
16 | _entryPointCommand.cmd = [cursor readInt32];
17 | _entryPointCommand.cmdsize = [cursor readInt32];
18 | _entryPointCommand.entryoff = [cursor readInt64];
19 | _entryPointCommand.stacksize = [cursor readInt64];
20 | }
21 |
22 | return self;
23 | }
24 |
25 | #pragma mark -
26 |
27 | - (uint32_t)cmd;
28 | {
29 | return _entryPointCommand.cmd;
30 | }
31 |
32 | - (uint32_t)cmdsize;
33 | {
34 | return _entryPointCommand.cmdsize;
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/Source/CDLCPrebindChecksum.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCPrebindChecksum : CDLoadCommand
9 |
10 | @property (nonatomic, readonly) uint32_t cksum;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCPrebindChecksum.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCPrebindChecksum.h"
7 |
8 | @implementation CDLCPrebindChecksum
9 | {
10 | struct prebind_cksum_command _prebindChecksumCommand;
11 | }
12 |
13 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
14 | {
15 | if ((self = [super initWithDataCursor:cursor])) {
16 | _prebindChecksumCommand.cmd = [cursor readInt32];
17 | _prebindChecksumCommand.cmdsize = [cursor readInt32];
18 | _prebindChecksumCommand.cksum = [cursor readInt32];
19 | }
20 |
21 | return self;
22 | }
23 |
24 | #pragma mark -
25 |
26 | - (uint32_t)cmd;
27 | {
28 | return _prebindChecksumCommand.cmd;
29 | }
30 |
31 | - (uint32_t)cmdsize;
32 | {
33 | return _prebindChecksumCommand.cmdsize;
34 | }
35 |
36 | - (uint32_t)cksum;
37 | {
38 | return _prebindChecksumCommand.cksum;
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Source/CDLCPreboundDylib.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCPreboundDylib : CDLoadCommand
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDLCPreboundDylib.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCPreboundDylib.h"
7 |
8 | #import "CDFatFile.h"
9 | #import "CDMachOFile.h"
10 |
11 | @implementation CDLCPreboundDylib
12 | {
13 | struct prebound_dylib_command _preboundDylibCommand;
14 | }
15 |
16 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
17 | {
18 | if ((self = [super initWithDataCursor:cursor])) {
19 | //NSLog(@"current offset: %u", [cursor offset]);
20 | _preboundDylibCommand.cmd = [cursor readInt32];
21 | _preboundDylibCommand.cmdsize = [cursor readInt32];
22 | //NSLog(@"cmdsize: %u", preboundDylibCommand.cmdsize);
23 |
24 | _preboundDylibCommand.name.offset = [cursor readInt32];
25 | _preboundDylibCommand.nmodules = [cursor readInt32];
26 | _preboundDylibCommand.linked_modules.offset = [cursor readInt32];
27 |
28 | if (_preboundDylibCommand.cmdsize > 20) {
29 | // Don't need this info right now.
30 | [cursor advanceByLength:_preboundDylibCommand.cmdsize - 20];
31 | }
32 | }
33 |
34 | return self;
35 | }
36 |
37 | #pragma mark -
38 |
39 | - (uint32_t)cmd;
40 | {
41 | return _preboundDylibCommand.cmd;
42 | }
43 |
44 | - (uint32_t)cmdsize;
45 | {
46 | return _preboundDylibCommand.cmdsize;
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/Source/CDLCRoutines32.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCRoutines32 : CDLoadCommand
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDLCRoutines32.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCRoutines32.h"
7 |
8 | @implementation CDLCRoutines32
9 | {
10 | struct routines_command _routinesCommand;
11 | }
12 |
13 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
14 | {
15 | if ((self = [super initWithDataCursor:cursor])) {
16 | _routinesCommand.cmd = [cursor readInt32];
17 | _routinesCommand.cmdsize = [cursor readInt32];
18 |
19 | _routinesCommand.init_address = [cursor readInt32];
20 | _routinesCommand.init_module = [cursor readInt32];
21 | _routinesCommand.reserved1 = [cursor readInt32];
22 | _routinesCommand.reserved2 = [cursor readInt32];
23 | _routinesCommand.reserved3 = [cursor readInt32];
24 | _routinesCommand.reserved4 = [cursor readInt32];
25 | _routinesCommand.reserved5 = [cursor readInt32];
26 | _routinesCommand.reserved6 = [cursor readInt32];
27 | }
28 |
29 | return self;
30 | }
31 |
32 | #pragma mark -
33 |
34 | - (uint32_t)cmd;
35 | {
36 | return _routinesCommand.cmd;
37 | }
38 |
39 | - (uint32_t)cmdsize;
40 | {
41 | return _routinesCommand.cmdsize;
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/Source/CDLCRoutines64.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCRoutines64 : CDLoadCommand
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDLCRoutines64.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCRoutines64.h"
7 |
8 | @implementation CDLCRoutines64
9 | {
10 | struct routines_command_64 _routinesCommand;
11 | }
12 |
13 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
14 | {
15 | if ((self = [super initWithDataCursor:cursor])) {
16 | _routinesCommand.cmd = [cursor readInt32];
17 | _routinesCommand.cmdsize = [cursor readInt32];
18 |
19 | _routinesCommand.init_address = [cursor readInt64];
20 | _routinesCommand.init_module = [cursor readInt64];
21 | _routinesCommand.reserved1 = [cursor readInt64];
22 | _routinesCommand.reserved2 = [cursor readInt64];
23 | _routinesCommand.reserved3 = [cursor readInt64];
24 | _routinesCommand.reserved4 = [cursor readInt64];
25 | _routinesCommand.reserved5 = [cursor readInt64];
26 | _routinesCommand.reserved6 = [cursor readInt64];
27 | }
28 |
29 | return self;
30 | }
31 |
32 | #pragma mark -
33 |
34 | - (uint32_t)cmd;
35 | {
36 | return _routinesCommand.cmd;
37 | }
38 |
39 | - (uint32_t)cmdsize;
40 | {
41 | return _routinesCommand.cmdsize;
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/Source/CDLCRunPath.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCRunPath : CDLoadCommand
9 |
10 | @property (readonly) NSString *path;
11 | @property (nonatomic, readonly) NSString *resolvedRunPath;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Source/CDLCRunPath.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCRunPath.h"
7 |
8 | #import "CDMachOFile.h"
9 | #import "CDSearchPathState.h"
10 |
11 | @implementation CDLCRunPath
12 | {
13 | struct rpath_command _rpathCommand;
14 | NSString *_path;
15 | }
16 |
17 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
18 | {
19 | if ((self = [super initWithDataCursor:cursor])) {
20 | _rpathCommand.cmd = [cursor readInt32];
21 | _rpathCommand.cmdsize = [cursor readInt32];
22 |
23 | _rpathCommand.path.offset = [cursor readInt32];
24 |
25 | NSUInteger length = _rpathCommand.cmdsize - sizeof(_rpathCommand);
26 | //NSLog(@"expected length: %u", length);
27 |
28 | _path = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding];
29 | //NSLog(@"path: %@", _path);
30 | }
31 |
32 | return self;
33 | }
34 |
35 | #pragma mark -
36 |
37 | - (uint32_t)cmd;
38 | {
39 | return _rpathCommand.cmd;
40 | }
41 |
42 | - (uint32_t)cmdsize;
43 | {
44 | return _rpathCommand.cmdsize;
45 | }
46 |
47 | - (NSString *)resolvedRunPath;
48 | {
49 | NSString *loaderPathPrefix = @"@loader_path";
50 | NSString *executablePathPrefix = @"@executable_path";
51 |
52 | if ([self.path hasPrefix:loaderPathPrefix]) {
53 | NSString *loaderPath = [self.machOFile.filename stringByDeletingLastPathComponent];
54 | NSString *str = [[self.path stringByReplacingOccurrencesOfString:loaderPathPrefix withString:loaderPath] stringByStandardizingPath];
55 |
56 | return str;
57 | }
58 |
59 | if ([self.path hasPrefix:executablePathPrefix]) {
60 | NSString *str = @"";
61 | NSString *executablePath = self.machOFile.searchPathState.executablePath;
62 | if (executablePath)
63 | str = [[self.path stringByReplacingOccurrencesOfString:executablePathPrefix withString:executablePath] stringByStandardizingPath];
64 |
65 | return str;
66 | }
67 |
68 | return self.path;
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/Source/CDLCSegment.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @class CDSection;
9 |
10 | #define CDSegmentProtectedMagic_None 0
11 | #define CDSegmentProtectedMagic_AES 0xc2286295
12 | #define CDSegmentProtectedMagic_Blowfish 0x2e69cf40
13 |
14 | typedef enum : NSUInteger {
15 | CDSegmentEncryptionType_None = 0,
16 | CDSegmentEncryptionType_AES = 1, // 10.5 and earlier (AES)
17 | CDSegmentEncryptionType_Blowfish = 2, // 10.6 (Blowfish)
18 | CDSegmentEncryptionType_Unknown
19 | } CDSegmentEncryptionType;
20 |
21 | extern NSString *CDSegmentEncryptionTypeName(CDSegmentEncryptionType type);
22 |
23 | @interface CDLCSegment : CDLoadCommand
24 |
25 | @property (strong) NSString *name;
26 | @property (strong) NSArray *sections;
27 |
28 | @property (nonatomic, readonly) NSUInteger vmaddr;
29 | @property (nonatomic, readonly) NSUInteger fileoff;
30 | @property (nonatomic, readonly) NSUInteger filesize;
31 | @property (nonatomic, readonly) vm_prot_t initprot;
32 | @property (nonatomic, readonly) uint32_t flags;
33 | @property (nonatomic, readonly) BOOL isProtected;
34 |
35 | @property (nonatomic, readonly) CDSegmentEncryptionType encryptionType;
36 | @property (nonatomic, readonly) BOOL canDecrypt;
37 |
38 | - (NSString *)flagDescription;
39 |
40 | - (BOOL)containsAddress:(NSUInteger)address;
41 | - (CDSection *)sectionContainingAddress:(NSUInteger)address;
42 | - (CDSection *)sectionWithName:(NSString *)name;
43 | - (NSUInteger)fileOffsetForAddress:(NSUInteger)address;
44 | - (NSUInteger)segmentOffsetForAddress:(NSUInteger)address;
45 |
46 | - (void)writeSectionData;
47 |
48 | - (NSData *)decryptedData;
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Source/CDLCSourceVersion.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCSourceVersion : CDLoadCommand
9 |
10 | @property (nonatomic, readonly) NSString *sourceVersionString;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCSourceVersion.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCSourceVersion.h"
7 |
8 | #import "CDMachOFile.h"
9 |
10 | @implementation CDLCSourceVersion
11 | {
12 | struct source_version_command _sourceVersionCommand;
13 | }
14 |
15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
16 | {
17 | if ((self = [super initWithDataCursor:cursor])) {
18 | _sourceVersionCommand.cmd = [cursor readInt32];
19 | _sourceVersionCommand.cmdsize = [cursor readInt32];
20 | _sourceVersionCommand.version = [cursor readInt64];
21 | }
22 |
23 | return self;
24 | }
25 |
26 | #pragma mark -
27 |
28 | - (uint32_t)cmd;
29 | {
30 | return _sourceVersionCommand.cmd;
31 | }
32 |
33 | - (uint32_t)cmdsize;
34 | {
35 | return _sourceVersionCommand.cmdsize;
36 | }
37 |
38 | - (NSString *)sourceVersionString;
39 | {
40 | // A.B.C.D.E packed as a24.b10.c10.d10.e10
41 | uint32_t a = _sourceVersionCommand.version >> 40;
42 | uint32_t b = (_sourceVersionCommand.version >> 30) & 0x3ff;
43 | uint32_t c = (_sourceVersionCommand.version >> 20) & 0x3ff;
44 | uint32_t d = (_sourceVersionCommand.version >> 10) & 0x3ff;
45 | uint32_t e = _sourceVersionCommand.version & 0x3ff;
46 |
47 | return [NSString stringWithFormat:@"%u.%u.%u.%u.%u", a, b, c, d, e];
48 | }
49 |
50 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose;
51 | {
52 | [super appendToString:resultString verbose:isVerbose];
53 |
54 | [resultString appendFormat:@" Source version: %@\n", self.sourceVersionString];
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/Source/CDLCSubClient.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCSubClient : CDLoadCommand
9 |
10 | @property (readonly) NSString *name;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCSubClient.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCSubClient.h"
7 |
8 | @implementation CDLCSubClient
9 | {
10 | struct sub_client_command _command;
11 | NSString *_name;
12 | }
13 |
14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
15 | {
16 | if ((self = [super initWithDataCursor:cursor])) {
17 | _command.cmd = [cursor readInt32];
18 | _command.cmdsize = [cursor readInt32];
19 |
20 | uint32_t strOffset = [cursor readInt32];
21 | NSParameterAssert(strOffset == 12);
22 |
23 | NSUInteger length = _command.cmdsize - sizeof(_command);
24 | //NSLog(@"expected length: %u", length);
25 |
26 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding];
27 | //NSLog(@"name: %@", _name);
28 | }
29 |
30 | return self;
31 | }
32 |
33 | #pragma mark -
34 |
35 | - (uint32_t)cmd;
36 | {
37 | return _command.cmd;
38 | }
39 |
40 | - (uint32_t)cmdsize;
41 | {
42 | return _command.cmdsize;
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Source/CDLCSubFramework.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCSubFramework : CDLoadCommand
9 |
10 | @property (readonly) NSString *name;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCSubFramework.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCSubFramework.h"
7 |
8 | @implementation CDLCSubFramework
9 | {
10 | struct sub_framework_command _command;
11 | NSString *_name;
12 | }
13 |
14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
15 | {
16 | if ((self = [super initWithDataCursor:cursor])) {
17 | _command.cmd = [cursor readInt32];
18 | _command.cmdsize = [cursor readInt32];
19 |
20 | uint32_t strOffset = [cursor readInt32];
21 | NSParameterAssert(strOffset == 12);
22 |
23 | NSUInteger length = _command.cmdsize - sizeof(_command);
24 | //NSLog(@"expected length: %u", length);
25 |
26 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding];
27 | //NSLog(@"name: %@", _name);
28 | }
29 |
30 | return self;
31 | }
32 |
33 | #pragma mark -
34 |
35 | - (uint32_t)cmd;
36 | {
37 | return _command.cmd;
38 | }
39 |
40 | - (uint32_t)cmdsize;
41 | {
42 | return _command.cmdsize;
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Source/CDLCSubLibrary.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCSubLibrary : CDLoadCommand
9 |
10 | @property (readonly) NSString *name;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCSubLibrary.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCSubLibrary.h"
7 |
8 | @implementation CDLCSubLibrary
9 | {
10 | struct sub_library_command _command;
11 | NSString *_name;
12 | }
13 |
14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
15 | {
16 | if ((self = [super initWithDataCursor:cursor])) {
17 | _command.cmd = [cursor readInt32];
18 | _command.cmdsize = [cursor readInt32];
19 |
20 | NSUInteger length = _command.cmdsize - sizeof(_command);
21 | //NSLog(@"expected length: %u", length);
22 |
23 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding];
24 | //NSLog(@"name: %@", _name);
25 | }
26 |
27 | return self;
28 | }
29 |
30 | #pragma mark -
31 |
32 | - (uint32_t)cmd;
33 | {
34 | return _command.cmd;
35 | }
36 |
37 | - (uint32_t)cmdsize;
38 | {
39 | return _command.cmdsize;
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/Source/CDLCSubUmbrella.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCSubUmbrella : CDLoadCommand
9 |
10 | @property (readonly) NSString *name;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCSubUmbrella.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCSubUmbrella.h"
7 |
8 | @implementation CDLCSubUmbrella
9 | {
10 | struct sub_umbrella_command _command;
11 | NSString *_name;
12 | }
13 |
14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
15 | {
16 | if ((self = [super initWithDataCursor:cursor])) {
17 | _command.cmd = [cursor readInt32];
18 | _command.cmdsize = [cursor readInt32];
19 |
20 | NSUInteger length = _command.cmdsize - sizeof(_command);
21 | //NSLog(@"expected length: %u", length);
22 |
23 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding];
24 | //NSLog(@"name: %@", _name);
25 | }
26 |
27 | return self;
28 | }
29 |
30 | #pragma mark -
31 |
32 | - (uint32_t)cmd;
33 | {
34 | return _command.cmd;
35 | }
36 |
37 | - (uint32_t)cmdsize;
38 | {
39 | return _command.cmdsize;
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/Source/CDLCSymbolTable.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @class CDSymbol;
9 |
10 | @interface CDLCSymbolTable : CDLoadCommand
11 |
12 | - (void)loadSymbols;
13 |
14 | @property (nonatomic, readonly) uint32_t symoff;
15 | @property (nonatomic, readonly) uint32_t nsyms;
16 | @property (nonatomic, readonly) uint32_t stroff;
17 | @property (nonatomic, readonly) uint32_t strsize;
18 |
19 | @property (nonatomic, readonly) NSUInteger baseAddress;
20 | @property (nonatomic, readonly) NSArray *symbols;
21 |
22 | - (CDSymbol *)symbolForClassName:(NSString *)className;
23 | - (CDSymbol *)symbolForExternalClassName:(NSString *)className;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Source/CDLCTwoLevelHints.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCTwoLevelHints : CDLoadCommand
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDLCTwoLevelHints.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCTwoLevelHints.h"
7 |
8 | #import "CDMachOFile.h"
9 |
10 | @implementation CDLCTwoLevelHints
11 | {
12 | struct twolevel_hints_command _hintsCommand;
13 | }
14 |
15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
16 | {
17 | if ((self = [super initWithDataCursor:cursor])) {
18 | _hintsCommand.cmd = [cursor readInt32];
19 | _hintsCommand.cmdsize = [cursor readInt32];
20 | _hintsCommand.offset = [cursor readInt32];
21 | _hintsCommand.nhints = [cursor readInt32];
22 | }
23 |
24 | return self;
25 | }
26 |
27 | #pragma mark -
28 |
29 | - (uint32_t)cmd;
30 | {
31 | return _hintsCommand.cmd;
32 | }
33 |
34 | - (uint32_t)cmdsize;
35 | {
36 | return _hintsCommand.cmdsize;
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Source/CDLCUUID.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCUUID : CDLoadCommand
9 |
10 | @property (nonatomic, readonly) NSUUID *UUID;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/CDLCUUID.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCUUID.h"
7 |
8 | #import "CDMachOFile.h"
9 |
10 | @implementation CDLCUUID
11 | {
12 | struct uuid_command _uuidCommand;
13 |
14 | NSUUID *_UUID;
15 | }
16 |
17 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
18 | {
19 | if ((self = [super initWithDataCursor:cursor])) {
20 | _uuidCommand.cmd = [cursor readInt32];
21 | _uuidCommand.cmdsize = [cursor readInt32];
22 | for (NSUInteger index = 0; index < sizeof(_uuidCommand.uuid); index++) {
23 | _uuidCommand.uuid[index] = [cursor readByte];
24 | }
25 | _UUID = [[NSUUID alloc] initWithUUIDBytes:_uuidCommand.uuid];
26 | }
27 |
28 | return self;
29 | }
30 |
31 | #pragma mark -
32 |
33 | - (uint32_t)cmd;
34 | {
35 | return _uuidCommand.cmd;
36 | }
37 |
38 | - (uint32_t)cmdsize;
39 | {
40 | return _uuidCommand.cmdsize;
41 | }
42 |
43 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose;
44 | {
45 | [super appendToString:resultString verbose:isVerbose];
46 |
47 | [resultString appendString:@" uuid "];
48 | [resultString appendString:[self.UUID UUIDString]];
49 | [resultString appendString:@"\n"];
50 | }
51 |
52 | - (NSString *)extraDescription;
53 | {
54 | return [self.UUID UUIDString];
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/Source/CDLCUnixThread.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCUnixThread : CDLoadCommand
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDLCUnixThread.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCUnixThread.h"
7 |
8 | // For now, this is all I need. There is no data in here sensitive to its position in the file.
9 |
10 | @implementation CDLCUnixThread
11 | {
12 | struct load_command _loadCommand;
13 |
14 | NSData *_commandData;
15 | }
16 |
17 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
18 | {
19 | if ((self = [super initWithDataCursor:cursor])) {
20 | _loadCommand.cmd = [cursor readInt32];
21 | _loadCommand.cmdsize = [cursor readInt32];
22 |
23 | if (_loadCommand.cmdsize > 8) {
24 | NSMutableData *commandData = [[NSMutableData alloc] init];
25 | [cursor appendBytesOfLength:_loadCommand.cmdsize - 8 intoData:commandData];
26 | _commandData = [commandData copy];
27 | } else {
28 | _commandData = nil;
29 | }
30 | }
31 |
32 | return self;
33 | }
34 |
35 | #pragma mark -
36 |
37 | - (uint32_t)cmd;
38 | {
39 | return _loadCommand.cmd;
40 | }
41 |
42 | - (uint32_t)cmdsize;
43 | {
44 | return _loadCommand.cmdsize;
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/Source/CDLCUnknown.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCUnknown : CDLoadCommand
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDLCUnknown.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCUnknown.h"
7 |
8 | static BOOL debug = NO;
9 |
10 | @implementation CDLCUnknown
11 | {
12 | struct load_command _loadCommand;
13 |
14 | NSData *_commandData;
15 | }
16 |
17 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
18 | {
19 | if ((self = [super initWithDataCursor:cursor])) {
20 | if (debug) NSLog(@"offset: %lu", [cursor offset]);
21 | _loadCommand.cmd = [cursor readInt32];
22 | _loadCommand.cmdsize = [cursor readInt32];
23 | if (debug) NSLog(@"cmdsize: %u", _loadCommand.cmdsize);
24 |
25 | if (_loadCommand.cmdsize > 8) {
26 | NSMutableData *commandData = [[NSMutableData alloc] init];
27 | [cursor appendBytesOfLength:_loadCommand.cmdsize - 8 intoData:commandData];
28 | _commandData = [commandData copy];
29 | } else {
30 | _commandData = nil;
31 | }
32 | }
33 |
34 | return self;
35 | }
36 |
37 | #pragma mark -
38 |
39 | - (uint32_t)cmd;
40 | {
41 | return _loadCommand.cmd;
42 | }
43 |
44 | - (uint32_t)cmdsize;
45 | {
46 | return _loadCommand.cmdsize;
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/Source/CDLCVersionMinimum.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLoadCommand.h"
7 |
8 | @interface CDLCVersionMinimum : CDLoadCommand
9 |
10 | @property (nonatomic, readonly) NSString *minimumVersionString;
11 | @property (nonatomic, readonly) NSString *SDKVersionString;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Source/CDLCVersionMinimum.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDLCVersionMinimum.h"
7 |
8 | #import "CDMachOFile.h"
9 |
10 | @implementation CDLCVersionMinimum
11 | {
12 | struct version_min_command _versionMinCommand;
13 | }
14 |
15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
16 | {
17 | if ((self = [super initWithDataCursor:cursor])) {
18 | _versionMinCommand.cmd = [cursor readInt32];
19 | _versionMinCommand.cmdsize = [cursor readInt32];
20 | _versionMinCommand.version = [cursor readInt32];
21 | _versionMinCommand.sdk = [cursor readInt32];
22 | }
23 |
24 | return self;
25 | }
26 |
27 | #pragma mark -
28 |
29 | - (uint32_t)cmd;
30 | {
31 | return _versionMinCommand.cmd;
32 | }
33 |
34 | - (uint32_t)cmdsize;
35 | {
36 | return _versionMinCommand.cmdsize;
37 | }
38 |
39 | - (NSString *)minimumVersionString;
40 | {
41 | uint32_t x = (_versionMinCommand.version >> 16);
42 | uint32_t y = (_versionMinCommand.version >> 8) & 0xff;
43 | uint32_t z = _versionMinCommand.version & 0xff;
44 |
45 | return [NSString stringWithFormat:@"%u.%u.%u", x, y, z];
46 | }
47 |
48 | - (NSString *)SDKVersionString;
49 | {
50 | uint32_t x = (_versionMinCommand.sdk >> 16);
51 | uint32_t y = (_versionMinCommand.sdk >> 8) & 0xff;
52 | uint32_t z = _versionMinCommand.sdk & 0xff;
53 |
54 | return [NSString stringWithFormat:@"%u.%u.%u", x, y, z];
55 | }
56 |
57 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose;
58 | {
59 | [super appendToString:resultString verbose:isVerbose];
60 |
61 | [resultString appendFormat:@" Minimum version: %@\n", self.minimumVersionString];
62 | [resultString appendFormat:@" SDK version: %@\n", self.SDKVersionString];
63 | }
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/Source/CDLoadCommand.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | // Importing these here saves us from importing them in the implementation of every load command.
7 | #include
8 | #import "CDMachOFileDataCursor.h"
9 |
10 | @class CDMachOFile;
11 |
12 | @interface CDLoadCommand : NSObject
13 |
14 | + (id)loadCommandWithDataCursor:(CDMachOFileDataCursor *)cursor;
15 |
16 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
17 |
18 | - (NSString *)extraDescription;
19 |
20 | @property (weak, readonly) CDMachOFile *machOFile;
21 | @property (readonly) NSUInteger commandOffset;
22 |
23 | @property (nonatomic, readonly) uint32_t cmd;
24 | @property (nonatomic, readonly) uint32_t cmdsize;
25 | @property (nonatomic, readonly) BOOL mustUnderstandToExecute;
26 |
27 | @property (nonatomic, readonly) NSString *commandName;
28 |
29 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose;
30 |
31 | - (void)machOFileDidReadLoadCommands:(CDMachOFile *)machOFile;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Source/CDMachOFile.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDFile.h"
7 |
8 | #include // For cpu_type_t, cpu_subtype_t
9 | #include
10 |
11 | typedef enum : NSUInteger {
12 | CDByteOrder_LittleEndian = 0,
13 | CDByteOrder_BigEndian = 1,
14 | } CDByteOrder;
15 |
16 | @class CDLCSegment;
17 | @class CDLCBuildVersion, CDLCDyldInfo, CDLCDylib, CDMachOFile, CDLCSymbolTable, CDLCDynamicSymbolTable, CDLCVersionMinimum, CDLCSourceVersion;
18 |
19 | @interface CDMachOFile : CDFile
20 |
21 | @property (readonly) CDByteOrder byteOrder;
22 |
23 | @property (readonly) uint32_t magic;
24 | @property (assign) cpu_type_t cputype;
25 | @property (assign) cpu_subtype_t cpusubtype;
26 | @property (readonly) uint32_t filetype;
27 | @property (readonly) uint32_t flags;
28 |
29 | @property (nonatomic, readonly) cpu_type_t maskedCPUType;
30 | @property (nonatomic, readonly) cpu_subtype_t maskedCPUSubtype;
31 |
32 | @property (readonly) NSArray *loadCommands;
33 | @property (readonly) NSArray *dylibLoadCommands;
34 | @property (readonly) NSArray *segments;
35 | @property (readonly) NSArray *runPaths;
36 | @property (readonly) NSArray *runPathCommands;
37 | @property (readonly) NSArray *dyldEnvironment;
38 | @property (readonly) NSArray *reExportedDylibs;
39 |
40 | @property (strong) CDLCSymbolTable *symbolTable;
41 | @property (strong) CDLCDynamicSymbolTable *dynamicSymbolTable;
42 | @property (strong) CDLCDyldInfo *dyldInfo;
43 | @property (strong) CDLCDylib *dylibIdentifier;
44 | @property (strong) CDLCVersionMinimum *minVersionMacOSX;
45 | @property (strong) CDLCVersionMinimum *minVersionIOS;
46 | @property (strong) CDLCSourceVersion *sourceVersion;
47 | @property (strong) CDLCBuildVersion *buildVersion;
48 |
49 | @property (readonly) BOOL uses64BitABI;
50 | - (NSUInteger)ptrSize;
51 |
52 | - (NSString *)filetypeDescription;
53 | - (NSString *)flagDescription;
54 |
55 | - (CDLCSegment *)dataConstSegment;
56 | - (CDLCSegment *)segmentWithName:(NSString *)segmentName;
57 | - (CDLCSegment *)segmentContainingAddress:(NSUInteger)address;
58 | - (NSString *)stringAtAddress:(NSUInteger)address;
59 |
60 | - (NSUInteger)dataOffsetForAddress:(NSUInteger)address;
61 |
62 | - (const void *)bytes;
63 | - (const void *)bytesAtOffset:(NSUInteger)offset;
64 |
65 | @property (nonatomic, readonly) NSString *importBaseName;
66 |
67 | @property (nonatomic, readonly) BOOL isEncrypted;
68 | @property (nonatomic, readonly) BOOL hasProtectedSegments;
69 | @property (nonatomic, readonly) BOOL canDecryptAllSegments;
70 |
71 | - (NSString *)loadCommandString:(BOOL)isVerbose;
72 | - (NSString *)headerString:(BOOL)isVerbose;
73 |
74 | @property (nonatomic, readonly) NSUUID *UUID;
75 | @property (nonatomic, readonly) NSString *archName;
76 |
77 | - (Class)processorClass;
78 | - (void)logInfoForAddress:(NSUInteger)address;
79 |
80 | - (NSString *)externalClassNameForAddress:(NSUInteger)address;
81 | - (BOOL)hasRelocationEntryForAddress:(NSUInteger)address;
82 |
83 | // Checks compressed dyld info on 10.6 or later.
84 | - (BOOL)hasRelocationEntryForAddress2:(NSUInteger)address;
85 | - (NSString *)externalClassNameForAddress2:(NSUInteger)address;
86 |
87 | - (CDLCDylib *)dylibLoadCommandForLibraryOrdinal:(NSUInteger)ordinal;
88 |
89 | @property (nonatomic, readonly) BOOL hasObjectiveC1Data;
90 | @property (nonatomic, readonly) BOOL hasObjectiveC2Data;
91 | @property (nonatomic, readonly) Class processorClass;
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/Source/CDMachOFileDataCursor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDDataCursor.h"
7 |
8 | @class CDMachOFile, CDSection;
9 |
10 | @interface CDMachOFileDataCursor : CDDataCursor
11 |
12 | - (id)initWithFile:(CDMachOFile *)machOFile;
13 | - (id)initWithFile:(CDMachOFile *)machOFile offset:(NSUInteger)offset;
14 | - (id)initWithFile:(CDMachOFile *)machOFile address:(NSUInteger)address;
15 |
16 | - (id)initWithSection:(CDSection *)section;
17 |
18 | @property (nonatomic, weak, readonly) CDMachOFile *machOFile;
19 |
20 | - (void)setAddress:(NSUInteger)address;
21 |
22 | // Read using the current byteOrder
23 | - (uint16_t)readInt16;
24 | - (uint32_t)readInt32;
25 | - (uint64_t)readInt64;
26 |
27 | - (uint32_t)peekInt32;
28 |
29 | // Read using the current byteOrder and ptrSize (from the machOFile)
30 | - (uint64_t)readPtr;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/Source/CDMachOFileDataCursor.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDMachOFileDataCursor.h"
7 |
8 | #import "CDMachOFile.h"
9 | #import "CDLCSegment.h"
10 | #import "CDSection.h"
11 |
12 | @implementation CDMachOFileDataCursor
13 | {
14 | __weak CDMachOFile *_machOFile;
15 | NSUInteger _ptrSize;
16 | CDByteOrder _byteOrder;
17 | }
18 |
19 | - (id)initWithFile:(CDMachOFile *)machOFile;
20 | {
21 | return [self initWithFile:machOFile offset:0];
22 | }
23 |
24 | - (id)initWithFile:(CDMachOFile *)machOFile offset:(NSUInteger)offset;
25 | {
26 | if ((self = [super initWithData:machOFile.data])) {
27 | self.machOFile = machOFile;
28 | [self setOffset:offset];
29 | }
30 |
31 | return self;
32 | }
33 |
34 | - (id)initWithFile:(CDMachOFile *)machOFile address:(NSUInteger)address;
35 | {
36 | if ((self = [super initWithData:machOFile.data])) {
37 | self.machOFile = machOFile;
38 | [self setAddress:address];
39 | }
40 |
41 | return self;
42 | }
43 |
44 | - (id)initWithSection:(CDSection *)section;
45 | {
46 | if ((self = [super initWithData:[section data]])) {
47 | self.machOFile = section.segment.machOFile;
48 | }
49 |
50 | return self;
51 | }
52 |
53 | #pragma mark -
54 |
55 | - (void)setMachOFile:(CDMachOFile *)machOFile;
56 | {
57 | _machOFile = machOFile;
58 | _ptrSize = machOFile.ptrSize;
59 | _byteOrder = machOFile.byteOrder;
60 | }
61 |
62 | - (void)setAddress:(NSUInteger)address;
63 | {
64 | NSUInteger dataOffset = [_machOFile dataOffsetForAddress:address];
65 | [self setOffset:dataOffset];
66 | }
67 |
68 | #pragma mark - Read using the current byteOrder
69 |
70 | - (uint16_t)readInt16;
71 | {
72 | if (_byteOrder == CDByteOrder_LittleEndian)
73 | return [self readLittleInt16];
74 |
75 | return [self readBigInt16];
76 | }
77 |
78 | - (uint32_t)readInt32;
79 | {
80 | if (_byteOrder == CDByteOrder_LittleEndian)
81 | return [self readLittleInt32];
82 |
83 | return [self readBigInt32];
84 | }
85 |
86 | - (uint64_t)readInt64;
87 | {
88 | if (_byteOrder == CDByteOrder_LittleEndian)
89 | return [self readLittleInt64];
90 |
91 | return [self readBigInt64];
92 | }
93 |
94 | - (uint32_t)peekInt32;
95 | {
96 | NSUInteger savedOffset = self.offset;
97 | uint32_t val = [self readInt32];
98 | self.offset = savedOffset;
99 |
100 | return val;
101 | }
102 |
103 | - (uint64_t)readPtr;
104 | {
105 | switch (_ptrSize) {
106 | case sizeof(uint32_t): return [self readInt32];
107 | case sizeof(uint64_t): return [self readInt64];
108 | }
109 | [NSException raise:NSInternalInconsistencyException format:@"The ptrSize must be either 4 (32-bit) or 8 (64-bit)"];
110 | return 0;
111 | }
112 |
113 | @end
114 |
--------------------------------------------------------------------------------
/Source/CDMethodType.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDType;
7 |
8 | @interface CDMethodType : NSObject
9 |
10 | - (id)initWithType:(CDType *)type offset:(NSString *)offset;
11 |
12 | @property (readonly) CDType *type;
13 | @property (readonly) NSString *offset;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Source/CDMethodType.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDMethodType.h"
7 |
8 | #import "CDType.h"
9 |
10 | @implementation CDMethodType
11 | {
12 | CDType *_type;
13 | NSString *_offset;
14 | }
15 |
16 | - (id)initWithType:(CDType *)type offset:(NSString *)offset;
17 | {
18 | if ((self = [super init])) {
19 | _type = type;
20 | _offset = offset;
21 | }
22 |
23 | return self;
24 | }
25 |
26 | #pragma mark - Debugging
27 |
28 | - (NSString *)description;
29 | {
30 | return [NSString stringWithFormat:@"[%@] type: %@, offset: %@", NSStringFromClass([self class]), self.type, self.offset];
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Source/CDMultiFileVisitor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDTextClassDumpVisitor.h"
7 |
8 | #import "CDTypeController.h" // For CDTypeControllerDelegate protocol
9 |
10 | // This generates separate files for each class. Files are created in the 'outputPath' directory.
11 |
12 | @interface CDMultiFileVisitor : CDTextClassDumpVisitor
13 |
14 | @property (strong) NSString *outputPath;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Source/CDOCCategory.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCProtocol.h"
7 |
8 | @class CDOCClassReference;
9 |
10 | @interface CDOCCategory : CDOCProtocol
11 |
12 | @property (strong) CDOCClassReference *classRef;
13 | @property (strong, readonly) NSString *className;
14 |
15 | - (NSString *)methodSearchContext;
16 | - (void)recursivelyVisit:(CDVisitor *)visitor;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Source/CDOCCategory.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCCategory.h"
7 |
8 | #import "CDClassDump.h"
9 | #import "CDOCMethod.h"
10 | #import "CDVisitor.h"
11 | #import "CDVisitorPropertyState.h"
12 | #import "CDOCClass.h"
13 | #import "CDOCClassReference.h"
14 |
15 | @implementation CDOCCategory
16 |
17 | #pragma mark - Superclass overrides
18 |
19 | - (NSString *)sortableName;
20 | {
21 | return [NSString stringWithFormat:@"%@ (%@)", self.className, self.name];
22 | }
23 |
24 | #pragma mark -
25 |
26 | - (NSString *)className
27 | {
28 | return [_classRef className];
29 | }
30 |
31 | - (NSString *)methodSearchContext;
32 | {
33 | NSMutableString *resultString = [NSMutableString string];
34 |
35 | [resultString appendFormat:@"@interface %@ (%@)", self.className, self.name];
36 |
37 | if ([self.protocols count] > 0)
38 | [resultString appendFormat:@" <%@>", self.protocolsString];
39 |
40 | return resultString;
41 | }
42 |
43 | - (void)recursivelyVisit:(CDVisitor *)visitor;
44 | {
45 | if ([visitor.classDump shouldShowName:self.name]) {
46 | CDVisitorPropertyState *propertyState = [[CDVisitorPropertyState alloc] initWithProperties:self.properties];
47 |
48 | [visitor willVisitCategory:self];
49 |
50 | //[aVisitor willVisitPropertiesOfCategory:self];
51 | //[self visitProperties:aVisitor];
52 | //[aVisitor didVisitPropertiesOfCategory:self];
53 |
54 | [self visitMethods:visitor propertyState:propertyState];
55 | // This can happen when... the accessors are implemented on the main class. Odd case, but we should still emit the remaining properties.
56 | // Should mostly be dynamic properties
57 | [visitor visitRemainingProperties:propertyState];
58 | [visitor didVisitCategory:self];
59 | }
60 | }
61 |
62 | #pragma mark - CDTopologicalSort protocol
63 |
64 | - (NSString *)identifier;
65 | {
66 | return self.sortableName;
67 | }
68 |
69 | - (NSArray *)dependancies;
70 | {
71 | if (self.className == nil)
72 | return @[];
73 |
74 | return @[self.className];
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/Source/CDOCClass.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCProtocol.h"
7 |
8 | #import "CDTopologicalSortProtocol.h"
9 |
10 | @class CDOCClassReference;
11 |
12 | @interface CDOCClass : CDOCProtocol
13 |
14 | @property (strong) CDOCClassReference *superClassRef;
15 | @property (copy, readonly) NSString *superClassName;
16 | @property (strong) NSArray *instanceVariables;
17 | @property (assign) BOOL isExported;
18 | @property (assign) BOOL isSwiftClass;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Source/CDOCClass.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCClass.h"
7 |
8 | #import "CDClassDump.h"
9 | #import "CDOCInstanceVariable.h"
10 | #import "CDOCMethod.h"
11 | #import "CDType.h"
12 | #import "CDTypeController.h"
13 | #import "CDTypeParser.h"
14 | #import "CDVisitor.h"
15 | #import "CDVisitorPropertyState.h"
16 | #import "CDOCClassReference.h"
17 |
18 | @implementation CDOCClass
19 | {
20 | NSArray *_instanceVariables;
21 |
22 | BOOL _isExported;
23 | }
24 |
25 | - (id)init;
26 | {
27 | if ((self = [super init])) {
28 | _isExported = YES;
29 | }
30 |
31 | return self;
32 | }
33 |
34 | #pragma mark - Debugging
35 |
36 | - (NSString *)description;
37 | {
38 | return [NSString stringWithFormat:@"%@, exported: %@", [super description], self.isExported ? @"YES" : @"NO"];
39 | }
40 |
41 | #pragma mark -
42 |
43 | - (NSString *)superClassName;
44 | {
45 | return [_superClassRef className];
46 | }
47 |
48 | - (void)registerTypesWithObject:(CDTypeController *)typeController phase:(NSUInteger)phase;
49 | {
50 | [super registerTypesWithObject:typeController phase:phase];
51 |
52 | for (CDOCInstanceVariable *instanceVariable in self.instanceVariables) {
53 | [instanceVariable.type phase:phase registerTypesWithObject:typeController usedInMethod:NO];
54 | }
55 | }
56 |
57 | - (NSString *)methodSearchContext;
58 | {
59 | NSMutableString *resultString = [NSMutableString string];
60 |
61 | [resultString appendFormat:@"@interface %@", self.name];
62 | if (self.superClassName != nil)
63 | [resultString appendFormat:@" : %@", self.superClassName];
64 |
65 | if ([self.protocols count] > 0)
66 | [resultString appendFormat:@" <%@>", self.protocolsString];
67 |
68 | return resultString;
69 | }
70 |
71 | - (void)recursivelyVisit:(CDVisitor *)visitor;
72 | {
73 | if ([visitor.classDump shouldShowName:self.name]) {
74 | CDVisitorPropertyState *propertyState = [[CDVisitorPropertyState alloc] initWithProperties:self.properties];
75 |
76 | [visitor willVisitClass:self];
77 |
78 | [visitor willVisitIvarsOfClass:self];
79 | for (CDOCInstanceVariable *instanceVariable in self.instanceVariables)
80 | [visitor visitIvar:instanceVariable];
81 | [visitor didVisitIvarsOfClass:self];
82 |
83 | //[visitor willVisitPropertiesOfClass:self];
84 | //[self visitProperties:visitor];
85 | //[visitor didVisitPropertiesOfClass:self];
86 |
87 | [self visitMethods:visitor propertyState:propertyState];
88 | // Should mostly be dynamic properties
89 | [visitor visitRemainingProperties:propertyState];
90 | [visitor didVisitClass:self];
91 | }
92 | }
93 |
94 | #pragma mark - CDTopologicalSort protocol
95 |
96 | - (NSString *)identifier;
97 | {
98 | return self.name;
99 | }
100 |
101 | - (NSArray *)dependancies;
102 | {
103 | if (self.superClassName == nil)
104 | return @[];
105 |
106 | return @[self.superClassName];
107 | }
108 |
109 | @end
110 |
--------------------------------------------------------------------------------
/Source/CDOCClassReference.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | @class CDOCClass, CDSymbol;
9 |
10 | /*!
11 | * CDOCClassReference acts as a proxy object to a class that may be external. It can thus be repesented
12 | * as one of: a \c CDOCClass object (for internal classes), a \c CDSymbol object (for external classes),
13 | * or an \c NSString of the class name (for ObjC1 compatibility). The class name can then be inferred from
14 | * any of these representations.
15 | */
16 | @interface CDOCClassReference : NSObject
17 |
18 | @property (strong) CDOCClass *classObject;
19 | @property (strong) CDSymbol *classSymbol;
20 | @property (nonatomic, copy) NSString *className; // inferred from classObject / classSymbol if not set directly
21 | @property (nonatomic, readonly, getter = isExternalClass) BOOL externalClass;
22 |
23 | - (instancetype)initWithClassObject:(CDOCClass *)classObject;
24 | - (instancetype)initWithClassSymbol:(CDSymbol *)symbol;
25 | - (instancetype)initWithClassName:(NSString *)className;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/Source/CDOCClassReference.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCClassReference.h"
7 | #import "CDOCClass.h"
8 | #import "CDSymbol.h"
9 |
10 | @implementation CDOCClassReference
11 |
12 | - (instancetype)initWithClassSymbol:(CDSymbol *)symbol;
13 | {
14 | if ((self = [super init])) {
15 | _classSymbol = symbol;
16 | }
17 |
18 | return self;
19 | }
20 |
21 | - (instancetype)initWithClassObject:(CDOCClass *)classObject;
22 | {
23 | if ((self = [super init])) {
24 | _classObject = classObject;
25 | }
26 |
27 | return self;
28 | }
29 |
30 | - (instancetype)initWithClassName:(NSString *)className;
31 | {
32 | if ((self = [super init])) {
33 | _className = [className copy];
34 | }
35 |
36 | return self;
37 | }
38 |
39 | - (NSString *)className;
40 | {
41 | if (_className != nil)
42 | return _className;
43 | else if (_classObject != nil)
44 | return [_classObject name];
45 | else if (_classSymbol != nil)
46 | return [CDSymbol classNameFromSymbolName:[_classSymbol name]];
47 | else
48 | return nil;
49 | }
50 |
51 | - (BOOL)isExternalClass;
52 | {
53 | return (!_classObject && (!_classSymbol || [_classSymbol isExternal]));
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/Source/CDOCInstanceVariable.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDType, CDTypeController;
7 |
8 | @interface CDOCInstanceVariable : NSObject
9 |
10 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString offset:(NSUInteger)offset;
11 |
12 | @property (readonly) NSString *name;
13 | @property (readonly) NSString *typeString;
14 | @property (readonly) NSUInteger offset;
15 |
16 | // Lazily parses the typeString. Returns nil and sets the parseError if parsing failed. Does not try to parse again in the event of an error.
17 | @property (nonatomic, readonly) CDType *type;
18 |
19 | // This is set after the typeString has been parsed if there was an error. Doesn't trigger parsing.
20 | @property (readonly) NSError *parseError;
21 |
22 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Source/CDOCInstanceVariable.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCInstanceVariable.h"
7 |
8 | #import "CDClassDump.h"
9 | #import "CDTypeFormatter.h"
10 | #import "CDTypeParser.h"
11 | #import "CDTypeController.h"
12 | #import "CDType.h"
13 |
14 | @interface CDOCInstanceVariable ()
15 | @property (assign) BOOL hasParsedType;
16 | @end
17 |
18 | #pragma mark -
19 |
20 | @implementation CDOCInstanceVariable
21 | {
22 | NSString *_name;
23 | NSString *_typeString;
24 | NSUInteger _offset;
25 |
26 | BOOL _hasParsedType;
27 | CDType *_type;
28 | NSError *_parseError;
29 | }
30 |
31 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString offset:(NSUInteger)offset;
32 | {
33 | if ((self = [super init])) {
34 | _name = name;
35 | _typeString = typeString;
36 | _offset = offset;
37 |
38 | _hasParsedType = NO;
39 | _type = nil;
40 | _parseError = nil;
41 | }
42 |
43 | return self;
44 | }
45 |
46 | #pragma mark - Debugging
47 |
48 | - (NSString *)description;
49 | {
50 | return [NSString stringWithFormat:@"[%@] name: %@, typeString: '%@', offset: %lu",
51 | NSStringFromClass([self class]), self.name, self.typeString, self.offset];
52 | }
53 |
54 | #pragma mark -
55 |
56 | - (CDType *)type;
57 | {
58 | if (self.hasParsedType == NO && self.parseError == nil) {
59 | CDTypeParser *parser = [[CDTypeParser alloc] initWithString:self.typeString];
60 | NSError *error;
61 | _type = [parser parseType:&error];
62 | if (_type == nil) {
63 | NSLog(@"Warning: Parsing instance variable type failed, %@", self.name);
64 | _parseError = error;
65 | } else {
66 | self.hasParsedType = YES;
67 | }
68 | }
69 |
70 | return _type;
71 | }
72 |
73 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController;
74 | {
75 | CDType *type = [self type]; // Parses it, if necessary;
76 | if (self.parseError != nil) {
77 | if ([self.typeString length] > 0) {
78 | [resultString appendFormat:@" // Error: parsing type: '%@', name: %@", self.typeString, self.name];
79 | } else {
80 | [resultString appendFormat:@" // Error: Empty type, name: %@", self.name];
81 | }
82 | } else {
83 | NSString *formattedString = [[typeController ivarTypeFormatter] formatVariable:self.name type:type];
84 | NSParameterAssert(formattedString != nil);
85 | [resultString appendString:formattedString];
86 | [resultString appendString:@";"];
87 | if ([typeController shouldShowIvarOffsets]) {
88 | [resultString appendFormat:@"\t// %ld = 0x%lx", self.offset, self.offset];
89 | }
90 | }
91 | }
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/Source/CDOCMethod.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDTypeController;
7 |
8 | @interface CDOCMethod : NSObject
9 |
10 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString;
11 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString address:(NSUInteger)address;
12 |
13 | @property (readonly) NSString *name;
14 | @property (readonly) NSString *typeString;
15 | @property (assign) NSUInteger address;
16 |
17 | - (NSArray *)parsedMethodTypes;
18 |
19 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController;
20 |
21 | - (NSComparisonResult)ascendingCompareByName:(CDOCMethod *)other;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Source/CDOCMethod.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCMethod.h"
7 |
8 | #import "CDClassDump.h"
9 | #import "CDTypeFormatter.h"
10 | #import "CDTypeParser.h"
11 | #import "CDTypeController.h"
12 |
13 | @implementation CDOCMethod
14 | {
15 | NSString *_name;
16 | NSString *_typeString;
17 | NSUInteger _address;
18 |
19 | BOOL _hasParsedType;
20 | NSArray *_parsedMethodTypes;
21 | }
22 |
23 | - (id)init;
24 | {
25 | [NSException raise:@"RejectUnusedImplementation" format:@"-initWithName:typeString:imp: is the designated initializer"];
26 | return nil;
27 | }
28 |
29 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString;
30 | {
31 | return [self initWithName:name typeString:typeString address:0];
32 | }
33 |
34 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString address:(NSUInteger)address;
35 | {
36 | if ((self = [super init])) {
37 | _name = name;
38 | _typeString = typeString;
39 | _address = address;
40 |
41 | _hasParsedType = NO;
42 | _parsedMethodTypes = nil;
43 | }
44 |
45 | return self;
46 | }
47 |
48 | #pragma mark - NSCopying
49 |
50 | - (id)copyWithZone:(NSZone *)zone;
51 | {
52 | return [[CDOCMethod alloc] initWithName:self.name typeString:self.typeString address:self.address];
53 | }
54 |
55 | #pragma mark - Debugging
56 |
57 | - (NSString *)description;
58 | {
59 | return [NSString stringWithFormat:@"[%@] name: %@, typeString: %@, address: 0x%016lx",
60 | NSStringFromClass([self class]), self.name, self.typeString, self.address];
61 | }
62 |
63 | #pragma mark -
64 |
65 | - (NSArray *)parsedMethodTypes;
66 | {
67 | if (_hasParsedType == NO) {
68 | NSError *error = nil;
69 |
70 | CDTypeParser *parser = [[CDTypeParser alloc] initWithString:self.typeString];
71 | _parsedMethodTypes = [parser parseMethodType:&error];
72 | if (_parsedMethodTypes == nil)
73 | NSLog(@"Warning: Parsing method types failed, %@", self.name);
74 | _hasParsedType = YES;
75 | }
76 |
77 | return _parsedMethodTypes;
78 | }
79 |
80 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController;
81 | {
82 | NSString *formattedString = [typeController.methodTypeFormatter formatMethodName:self.name typeString:self.typeString];
83 | if (formattedString != nil) {
84 | [resultString appendString:formattedString];
85 | [resultString appendString:@";"];
86 | if (typeController.shouldShowMethodAddresses && self.address != 0) {
87 | if (typeController.targetArchUses64BitABI)
88 | [resultString appendFormat:@"\t// IMP=0x%016lx", self.address];
89 | else
90 | [resultString appendFormat:@"\t// IMP=0x%08lx", self.address];
91 | }
92 | } else
93 | [resultString appendFormat:@" // Error parsing type: %@, name: %@", self.typeString, self.name];
94 | }
95 |
96 | #pragma mark - Sorting
97 |
98 | - (NSComparisonResult)ascendingCompareByName:(CDOCMethod *)other;
99 | {
100 | return [self.name compare:other.name];
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------
/Source/CDOCModule.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDOCSymtab;
7 |
8 | @interface CDOCModule : NSObject
9 |
10 | @property (assign) uint32_t version;
11 | @property (strong) NSString *name;
12 | @property (strong) CDOCSymtab *symtab;
13 |
14 | - (NSString *)formattedString;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Source/CDOCModule.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCModule.h"
7 |
8 | #import "CDObjectiveC1Processor.h"
9 | #import "CDOCSymtab.h"
10 |
11 | @implementation CDOCModule
12 | {
13 | uint32_t _version;
14 | NSString *_name;
15 | CDOCSymtab *_symtab;
16 | }
17 |
18 | - (id)init;
19 | {
20 | if ((self = [super init])) {
21 | _version = 0;
22 | _name = nil;
23 | _symtab = nil;
24 | }
25 |
26 | return self;
27 | }
28 |
29 | #pragma mark - Debugging
30 |
31 | - (NSString *)description;
32 | {
33 | return [NSString stringWithFormat:@"[%@] name: %@, version: %u, symtab: %@", NSStringFromClass([self class]), self.name, self.version, self.symtab];
34 | }
35 |
36 | #pragma mark -
37 |
38 | - (NSString *)formattedString;
39 | {
40 | return [NSString stringWithFormat:@"//\n// %@\n//\n", self.name];
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Source/CDOCProperty.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDType;
7 |
8 | @interface CDOCProperty : NSObject
9 |
10 | - (id)initWithName:(NSString *)name attributes:(NSString *)attributes;
11 |
12 | @property (readonly) NSString *name;
13 | @property (readonly) NSString *attributeString;
14 | @property (readonly) CDType *type;
15 | @property (readonly) NSArray *attributes;
16 |
17 | @property (strong) NSString *attributeStringAfterType;
18 |
19 | @property (nonatomic, readonly) NSString *defaultGetter;
20 | @property (nonatomic, readonly) NSString *defaultSetter;
21 |
22 | @property (strong) NSString *customGetter;
23 | @property (strong) NSString *customSetter;
24 |
25 | @property (nonatomic, readonly) NSString *getter;
26 | @property (nonatomic, readonly) NSString *setter;
27 |
28 | @property (readonly) BOOL isReadOnly;
29 | @property (readonly) BOOL isDynamic;
30 |
31 | - (NSComparisonResult)ascendingCompareByName:(CDOCProperty *)other;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Source/CDOCProtocol.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDTypeController;
7 | @class CDVisitor, CDVisitorPropertyState;
8 | @class CDOCMethod, CDOCProperty;
9 |
10 | @interface CDOCProtocol : NSObject
11 |
12 | @property (strong) NSString *name;
13 |
14 | @property (readonly) NSArray *protocols;
15 | - (void)addProtocol:(CDOCProtocol *)protocol;
16 | - (void)removeProtocol:(CDOCProtocol *)protocol;
17 | @property (nonatomic, readonly) NSArray *protocolNames;
18 | @property (nonatomic, readonly) NSString *protocolsString;
19 |
20 | @property (nonatomic, readonly) NSArray *classMethods; // TODO: NSArray vs. NSMutableArray
21 | - (void)addClassMethod:(CDOCMethod *)method;
22 |
23 | @property (nonatomic, readonly) NSArray *instanceMethods;
24 | - (void)addInstanceMethod:(CDOCMethod *)method;
25 |
26 | @property (nonatomic, readonly) NSArray *optionalClassMethods;
27 | - (void)addOptionalClassMethod:(CDOCMethod *)method;
28 |
29 | @property (nonatomic, readonly) NSArray *optionalInstanceMethods;
30 | - (void)addOptionalInstanceMethod:(CDOCMethod *)method;
31 |
32 | @property (nonatomic, readonly) NSArray *properties;
33 | - (void)addProperty:(CDOCProperty *)property;
34 |
35 | @property (nonatomic, readonly) BOOL hasMethods;
36 |
37 | - (void)registerTypesWithObject:(CDTypeController *)typeController phase:(NSUInteger)phase;
38 | - (void)registerTypesFromMethods:(NSArray *)methods withObject:(CDTypeController *)typeController phase:(NSUInteger)phase;
39 |
40 | - (NSComparisonResult)ascendingCompareByName:(CDOCProtocol *)other;
41 |
42 | - (NSString *)methodSearchContext;
43 | - (void)recursivelyVisit:(CDVisitor *)visitor;
44 |
45 | - (void)visitMethods:(CDVisitor *)visitor propertyState:(CDVisitorPropertyState *)propertyState;
46 |
47 | - (void)mergeMethodsFromProtocol:(CDOCProtocol *)other;
48 | - (void)mergePropertiesFromProtocol:(CDOCProtocol *)other;
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Source/CDOCSymtab.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDOCCategory, CDOCClass;
7 |
8 | @interface CDOCSymtab : NSObject
9 |
10 | @property (readonly) NSMutableArray *classes;
11 | - (void)addClass:(CDOCClass *)aClass;
12 |
13 | @property (readonly) NSMutableArray *categories;
14 | - (void)addCategory:(CDOCCategory *)category;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Source/CDOCSymtab.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDOCSymtab.h"
7 |
8 | #import "CDOCCategory.h"
9 | #import "CDOCClass.h"
10 |
11 | @implementation CDOCSymtab
12 | {
13 | NSMutableArray *_classes;
14 | NSMutableArray *_categories;
15 | }
16 |
17 | - (id)init;
18 | {
19 | if ((self = [super init])) {
20 | _classes = [[NSMutableArray alloc] init];
21 | _categories = [[NSMutableArray alloc] init];
22 | }
23 |
24 | return self;
25 | }
26 |
27 | #pragma mark - Debugging
28 |
29 | - (NSString *)description;
30 | {
31 | return [NSString stringWithFormat:@"[%@] classes: %@, categories: %@", NSStringFromClass([self class]), self.classes, self.categories];
32 | }
33 |
34 | #pragma mark -
35 |
36 | - (void)addClass:(CDOCClass *)aClass;
37 | {
38 | [self.classes addObject:aClass];
39 | }
40 |
41 | - (void)addCategory:(CDOCCategory *)category;
42 | {
43 | [self.categories addObject:category];
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Source/CDObjectiveC1Processor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDObjectiveCProcessor.h"
7 |
8 | @interface CDObjectiveC1Processor : CDObjectiveCProcessor
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDObjectiveC2Processor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDObjectiveCProcessor.h"
7 |
8 | @interface CDObjectiveC2Processor : CDObjectiveCProcessor
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDObjectiveCProcessor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDMachOFile, CDSection, CDTypeController;
7 | @class CDVisitor;
8 | @class CDOCClass, CDOCCategory;
9 | @class CDProtocolUniquer;
10 |
11 | @interface CDObjectiveCProcessor : NSObject
12 |
13 | - (id)initWithMachOFile:(CDMachOFile *)machOFile;
14 |
15 | @property (readonly) CDMachOFile *machOFile;
16 | @property (nonatomic, readonly) BOOL hasObjectiveCData;
17 |
18 | @property (nonatomic, readonly) CDSection *objcImageInfoSection;
19 | @property (nonatomic, readonly) NSString *garbageCollectionStatus;
20 |
21 | - (void)addClass:(CDOCClass *)aClass withAddress:(uint64_t)address;
22 | - (CDOCClass *)classWithAddress:(uint64_t)address;
23 |
24 | - (void)addClassesFromArray:(NSArray *)array;
25 | - (void)addCategoriesFromArray:(NSArray *)array;
26 |
27 | - (void)addCategory:(CDOCCategory *)category;
28 |
29 | - (void)process;
30 | - (void)loadProtocols;
31 | - (void)loadClasses;
32 | - (void)loadCategories;
33 |
34 | - (void)registerTypesWithObject:(CDTypeController *)typeController phase:(NSUInteger)phase;
35 | - (void)recursivelyVisit:(CDVisitor *)visitor;
36 |
37 | - (NSArray *)protocolAddressListAtAddress:(uint64_t)address;
38 |
39 | @property (readonly) CDProtocolUniquer *protocolUniquer;
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Source/CDProtocolUniquer.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDOCProtocol;
7 |
8 | @interface CDProtocolUniquer : NSObject
9 |
10 | // Gather
11 | - (CDOCProtocol *)protocolWithAddress:(uint64_t)address;
12 | - (void)setProtocol:(CDOCProtocol *)protocol withAddress:(uint64_t)address;
13 |
14 | // Process
15 | - (void)createUniquedProtocols;
16 |
17 | // Results
18 | - (NSArray *)uniqueProtocolsAtAddresses:(NSArray *)addresses;
19 | - (NSArray *)uniqueProtocolsSortedByName;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Source/CDRelocationInfo.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #include
7 |
8 | typedef enum : NSUInteger {
9 | CDRelocationInfoSize_8Bit = 0,
10 | CDRelocationInfoSize_16Bit = 1,
11 | CDRelocationInfoSize_32Bit = 2,
12 | CDRelocationInfoSize_64Bit = 3,
13 | } CDRelocationSize;
14 |
15 | @interface CDRelocationInfo : NSObject
16 |
17 | - (id)initWithInfo:(struct relocation_info)info;
18 |
19 | @property (nonatomic, readonly) NSUInteger offset;
20 | @property (nonatomic, readonly) CDRelocationSize size;
21 | @property (nonatomic, readonly) uint32_t symbolnum;
22 | @property (nonatomic, readonly) BOOL isExtern;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Source/CDRelocationInfo.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDRelocationInfo.h"
7 |
8 | @implementation CDRelocationInfo
9 | {
10 | struct relocation_info _rinfo;
11 | }
12 |
13 | - (id)initWithInfo:(struct relocation_info)info;
14 | {
15 | if ((self = [super init])) {
16 | _rinfo = info;
17 | }
18 |
19 | return self;
20 | }
21 |
22 | #pragma mark - Debugging
23 |
24 | - (NSString *)description;
25 | {
26 | return [NSString stringWithFormat:@"<%@:%p> addr/off: %08x, sym #: %5u, pcrel? %u, len: %u, extern? %u, type: %x",
27 | NSStringFromClass([self class]), self,
28 | _rinfo.r_address, _rinfo.r_symbolnum, _rinfo.r_pcrel, _rinfo.r_length, _rinfo.r_extern, _rinfo.r_type];
29 | }
30 |
31 | #pragma mark -
32 |
33 | - (NSUInteger)offset;
34 | {
35 | return _rinfo.r_address;
36 | }
37 |
38 | - (CDRelocationSize)size;
39 | {
40 | return _rinfo.r_length;
41 | }
42 |
43 | - (uint32_t)symbolnum;
44 | {
45 | return _rinfo.r_symbolnum;
46 | }
47 |
48 | - (BOOL)isExtern;
49 | {
50 | return _rinfo.r_extern == 1;
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/Source/CDSearchPathState.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface CDSearchPathState : NSObject
7 |
8 | @property (nonatomic, strong) NSString *executablePath;
9 |
10 | - (void)pushSearchPaths:(NSArray *)searchPaths;
11 | - (void)popSearchPaths;
12 |
13 | - (NSArray *)searchPaths;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Source/CDSearchPathState.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDSearchPathState.h"
7 |
8 | @interface CDSearchPathState ()
9 | @property (readonly) NSMutableArray *searchPathStack;
10 | @end
11 |
12 | #pragma mark -
13 |
14 | @implementation CDSearchPathState
15 | {
16 | NSString *_executablePath;
17 | NSMutableArray *_searchPathStack;
18 | }
19 |
20 | - (id)init;
21 | {
22 | if ((self = [super init])) {
23 | _executablePath = nil;
24 | _searchPathStack = [[NSMutableArray alloc] init];
25 | }
26 |
27 | return self;
28 | }
29 |
30 | #pragma mark -
31 |
32 | - (void)pushSearchPaths:(NSArray *)searchPaths;
33 | {
34 | [self.searchPathStack addObject:searchPaths];
35 | }
36 |
37 | - (void)popSearchPaths;
38 | {
39 | if ([self.searchPathStack count] > 0) {
40 | [self.searchPathStack removeLastObject];
41 | } else {
42 | NSLog(@"Warning: Unbalanced popSearchPaths");
43 | }
44 | }
45 |
46 | - (NSArray *)searchPaths;
47 | {
48 | NSMutableArray *result = [NSMutableArray array];
49 | for (NSArray *group in self.searchPathStack) {
50 | [result addObjectsFromArray:group];
51 | }
52 |
53 | return [result copy];
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/Source/CDSection.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDMachOFileDataCursor;
7 | @class CDLCSegment;
8 |
9 | @interface CDSection : NSObject
10 |
11 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor segment:(CDLCSegment *)segment;
12 |
13 | @property (weak, readonly) CDLCSegment *segment;
14 |
15 | @property (nonatomic, readonly) NSData *data;
16 |
17 | @property (nonatomic, readonly) NSString *segmentName;
18 | @property (nonatomic, readonly) NSString *sectionName;
19 |
20 | @property (nonatomic, readonly) NSUInteger addr;
21 | @property (nonatomic, readonly) NSUInteger size;
22 |
23 | - (BOOL)containsAddress:(NSUInteger)address;
24 | - (NSUInteger)fileOffsetForAddress:(NSUInteger)address;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/Source/CDSection.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDSection.h"
7 |
8 | #include
9 | #import "CDMachOFile.h"
10 | #import "CDMachOFileDataCursor.h"
11 | #import "CDLCSegment.h"
12 |
13 | @implementation CDSection
14 | {
15 | struct section_64 _section; // 64-bit, also holding 32-bit
16 | }
17 |
18 | @synthesize data = _data;
19 |
20 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor segment:(CDLCSegment *)segment;
21 | {
22 | if ((self = [super init])) {
23 | _segment = segment;
24 |
25 | _sectionName = [cursor readStringOfLength:16 encoding:NSASCIIStringEncoding];
26 | size_t sectionNameLength = [_sectionName lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
27 | memcpy(_section.sectname, [_sectionName UTF8String], MIN(sectionNameLength, sizeof(_section.sectname)));
28 | size_t segmentNameLength = [_sectionName lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
29 | _segmentName = [cursor readStringOfLength:16 encoding:NSASCIIStringEncoding];
30 | memcpy(_section.segname, [_segmentName UTF8String], MIN(segmentNameLength, sizeof(_section.segname)));
31 | _section.addr = [cursor readPtr];
32 | _section.size = [cursor readPtr];
33 | _section.offset = [cursor readInt32];
34 | uint32_t dyldOffset = (uint32_t)(_section.addr - segment.vmaddr + segment.fileoff);
35 | if (_section.offset > 0 && _section.offset != dyldOffset) {
36 | fprintf(stderr, "Warning: Invalid section offset 0x%08x replaced with 0x%08x in %s,%s\n", _section.offset, dyldOffset, [_segmentName UTF8String], [_sectionName UTF8String]);
37 | _section.offset = dyldOffset;
38 | }
39 | _section.align = [cursor readInt32];
40 | _section.reloff = [cursor readInt32];
41 | _section.nreloc = [cursor readInt32];
42 | _section.flags = [cursor readInt32];
43 | _section.reserved1 = [cursor readInt32];
44 | _section.reserved2 = [cursor readInt32];
45 | if (cursor.machOFile.uses64BitABI) {
46 | _section.reserved3 = [cursor readInt32];
47 | }
48 | }
49 |
50 | return self;
51 | }
52 |
53 | #pragma mark -
54 |
55 | - (NSData *)data;
56 | {
57 | if (!_data) {
58 | _data = [[NSData alloc] initWithBytes:(uint8_t *)[self.segment.machOFile.data bytes] + _section.offset length:_section.size];
59 | }
60 | return _data;
61 | }
62 |
63 | - (NSUInteger)addr;
64 | {
65 | return _section.addr;
66 | }
67 |
68 | - (NSUInteger)size;
69 | {
70 | return _section.size;
71 | }
72 |
73 | - (BOOL)containsAddress:(NSUInteger)address;
74 | {
75 | return (address >= _section.addr) && (address < _section.addr + _section.size);
76 | }
77 |
78 | - (NSUInteger)fileOffsetForAddress:(NSUInteger)address;
79 | {
80 | NSParameterAssert([self containsAddress:address]);
81 | return _section.offset + address - _section.addr;
82 | }
83 |
84 | #pragma mark - Debugging
85 |
86 | - (NSString *)description;
87 | {
88 | int padding = (int)self.segment.machOFile.ptrSize * 2;
89 | return [NSString stringWithFormat:@"<%@:%p> '%@,%-16s' addr: %0*llx, size: %0*llx",
90 | NSStringFromClass([self class]), self,
91 | self.segmentName, [self.sectionName UTF8String],
92 | padding, _section.addr, padding, _section.size];
93 | }
94 |
95 | @end
96 |
--------------------------------------------------------------------------------
/Source/CDStructureInfo.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDType;
7 |
8 | @interface CDStructureInfo : NSObject
9 |
10 | - (id)initWithType:(CDType *)type;
11 |
12 | - (NSString *)shortDescription;
13 |
14 | @property (readonly) CDType *type;
15 |
16 | @property (assign) NSUInteger referenceCount;
17 | - (void)addReferenceCount:(NSUInteger)count;
18 |
19 | @property (assign) BOOL isUsedInMethod;
20 | @property (strong) NSString *typedefName;
21 |
22 | - (void)generateTypedefName:(NSString *)baseName;
23 |
24 | @property (nonatomic, readonly) NSString *name;
25 |
26 | - (NSComparisonResult)ascendingCompareByStructureDepth:(CDStructureInfo *)other;
27 | - (NSComparisonResult)descendingCompareByStructureDepth:(CDStructureInfo *)other;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Source/CDStructureTable.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDType, CDTypeController, CDTypeFormatter;
7 |
8 | @interface CDStructureTable : NSObject
9 |
10 | @property (strong) NSString *identifier;
11 | @property (strong) NSString *anonymousBaseName;
12 | @property (assign) BOOL shouldDebug;
13 |
14 | @property (weak) CDTypeController *typeController;
15 |
16 | // Phase 0
17 | - (void)phase0RegisterStructure:(CDType *)structure usedInMethod:(BOOL)isUsedInMethod;
18 | - (void)finishPhase0;
19 |
20 | // Phase 1
21 | - (void)runPhase1;
22 | - (void)phase1RegisterStructure:(CDType *)structure;
23 | - (void)finishPhase1;
24 | @property (nonatomic, readonly) NSUInteger phase1_maxDepth;
25 |
26 | // Phase 2
27 | - (void)runPhase2AtDepth:(NSUInteger)depth;
28 | - (CDType *)phase2ReplacementForType:(CDType *)type;
29 |
30 | - (void)finishPhase2;
31 |
32 | // Phase 3
33 | - (void)phase2ReplacementOnPhase0;
34 |
35 | - (void)buildPhase3Exceptions;
36 | - (void)runPhase3;
37 | - (void)phase3RegisterStructure:(CDType *)structure
38 | count:(NSUInteger)referenceCount
39 | usedInMethod:(BOOL)isUsedInMethod;
40 | - (void)finishPhase3;
41 | - (CDType *)phase3ReplacementForType:(CDType *)type;
42 |
43 | // Other
44 |
45 | // Called by CDTypeController prior to calling the next two methods.
46 | - (void)generateTypedefNames;
47 | - (void)generateMemberNames;
48 |
49 | // Called by CDTypeController
50 | - (void)appendNamedStructuresToString:(NSMutableString *)resultString
51 | formatter:(CDTypeFormatter *)typeFormatter
52 | markName:(NSString *)markName;
53 |
54 | // Called by CDTypeController
55 | - (void)appendTypedefsToString:(NSMutableString *)resultString
56 | formatter:(CDTypeFormatter *)typeFormatter
57 | markName:(NSString *)markName;
58 |
59 | - (BOOL)shouldExpandType:(CDType *)type;
60 | - (NSString *)typedefNameForType:(CDType *)type;
61 |
62 | // Debugging
63 | - (void)debugName:(NSString *)name;
64 | - (void)debugAnon:(NSString *)str;
65 | - (void)logPhase0Info;
66 | - (void)logPhase2Info;
67 | - (void)logPhase3Info;
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/Source/CDSymbol.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #include
7 |
8 | extern NSString *const ObjCClassSymbolPrefix;
9 |
10 | @class CDMachOFile, CDSection, CDLCDylib;
11 |
12 | @interface CDSymbol : NSObject
13 |
14 | - (id)initWithName:(NSString *)name machOFile:(CDMachOFile *)machOFile nlist32:(struct nlist)nlist32;
15 | - (id)initWithName:(NSString *)name machOFile:(CDMachOFile *)machOFile nlist64:(struct nlist_64)nlist64;
16 |
17 | @property (nonatomic, readonly) uint64_t value;
18 | @property (readonly) NSString *name;
19 | @property (nonatomic, readonly) CDSection *section;
20 | @property (nonatomic, readonly) CDLCDylib *dylibLoadCommand;
21 |
22 | @property (nonatomic, readonly) BOOL isExternal;
23 | @property (nonatomic, readonly) BOOL isPrivateExternal;
24 | @property (nonatomic, readonly) NSUInteger stab;
25 | @property (nonatomic, readonly) NSUInteger type;
26 | @property (nonatomic, readonly) BOOL isDefined;
27 | @property (nonatomic, readonly) BOOL isAbsolute;
28 | @property (nonatomic, readonly) BOOL isInSection;
29 | @property (nonatomic, readonly) BOOL isPrebound;
30 | @property (nonatomic, readonly) BOOL isIndirect;
31 | @property (nonatomic, readonly) BOOL isCommon;
32 | @property (nonatomic, readonly) BOOL isInTextSection;
33 | @property (nonatomic, readonly) BOOL isInDataSection;
34 | @property (nonatomic, readonly) BOOL isInBssSection;
35 | @property (nonatomic, readonly) NSUInteger referenceType;
36 | @property (nonatomic, readonly) NSString *referenceTypeName;
37 | @property (nonatomic, readonly) NSString *shortTypeDescription;
38 | @property (nonatomic, readonly) NSString *longTypeDescription;
39 |
40 | - (NSComparisonResult)compare:(CDSymbol *)other;
41 | - (NSComparisonResult)compareByName:(CDSymbol *)other;
42 |
43 | + (NSString *)classNameFromSymbolName:(NSString *)symbolName;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Source/CDTextClassDumpVisitor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDVisitor.h"
7 |
8 | // Has a mutable string for storing output, and method to write it to standard out.
9 | // symbol references are for... ?
10 |
11 | @interface CDTextClassDumpVisitor : CDVisitor
12 |
13 | @property (readonly) NSMutableString *resultString;
14 |
15 | - (void)writeResultToStandardOutput;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Source/CDTopoSortNode.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDTopologicalSortProtocol.h"
7 |
8 | typedef enum : NSUInteger {
9 | CDNodeColor_White = 0,
10 | CDNodeColor_Gray = 1,
11 | CDNodeColor_Black = 2,
12 | } CDNodeColor;
13 |
14 | @interface CDTopoSortNode : NSObject
15 |
16 | - (id)initWithObject:(id )object;
17 |
18 | @property (nonatomic, readonly) NSString *identifier;
19 | @property (readonly) id sortableObject;
20 |
21 | - (NSArray *)dependancies;
22 | - (void)addDependancy:(NSString *)identifier;
23 | - (void)removeDependancy:(NSString *)identifier;
24 | - (void)addDependanciesFromArray:(NSArray *)identifiers;
25 | @property (nonatomic, readonly) NSString *dependancyDescription;
26 |
27 | @property (assign) CDNodeColor color;
28 |
29 | - (NSComparisonResult)ascendingCompareByIdentifier:(CDTopoSortNode *)other;
30 | - (void)topologicallySortNodes:(NSDictionary *)nodesByIdentifier intoArray:(NSMutableArray *)sortedArray;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/Source/CDTopoSortNode.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDTopoSortNode.h"
7 |
8 | @implementation CDTopoSortNode
9 | {
10 | id _sortableObject;
11 |
12 | NSMutableSet *_dependancies;
13 | CDNodeColor _color;
14 | }
15 |
16 | - (id)initWithObject:(id )object;
17 | {
18 | if ((self = [super init])) {
19 | _sortableObject = object;
20 | _dependancies = [[NSMutableSet alloc] init];
21 | _color = CDNodeColor_White;
22 |
23 | [self addDependanciesFromArray:[_sortableObject dependancies]];
24 | }
25 |
26 | return self;
27 | }
28 |
29 | #pragma mark - Debugging
30 |
31 | - (NSString *)description;
32 | {
33 | return [NSString stringWithFormat:@"%@ (%lu) depends on %@", self.identifier, self.color, self.dependancyDescription];
34 | }
35 |
36 | #pragma mark -
37 |
38 | - (NSString *)identifier;
39 | {
40 | return self.sortableObject.identifier;
41 | }
42 |
43 | - (NSArray *)dependancies;
44 | {
45 | return [_dependancies allObjects];
46 | }
47 |
48 | - (void)addDependancy:(NSString *)identifier;
49 | {
50 | [_dependancies addObject:identifier];
51 | }
52 |
53 | - (void)removeDependancy:(NSString *)identifier;
54 | {
55 | [_dependancies removeObject:identifier];
56 | }
57 |
58 | - (void)addDependanciesFromArray:(NSArray *)identifiers;
59 | {
60 | [_dependancies addObjectsFromArray:identifiers];
61 | }
62 |
63 | - (NSString *)dependancyDescription;
64 | {
65 | return [[_dependancies allObjects] componentsJoinedByString:@", "];
66 | }
67 |
68 | #pragma mark - Sorting
69 |
70 | - (NSComparisonResult)ascendingCompareByIdentifier:(CDTopoSortNode *)other;
71 | {
72 | return [self.identifier compare:other.identifier];
73 | }
74 |
75 | - (void)topologicallySortNodes:(NSDictionary *)nodesByIdentifier intoArray:(NSMutableArray *)sortedArray;
76 | {
77 | NSArray *dependantIdentifiers = [self dependancies];
78 |
79 | for (NSString *identifier in dependantIdentifiers) {
80 | CDTopoSortNode *node = nodesByIdentifier[identifier];
81 | if (node.color == CDNodeColor_White) {
82 | node.color = CDNodeColor_Gray;
83 | [node topologicallySortNodes:nodesByIdentifier intoArray:sortedArray];
84 | } else if (node.color == CDNodeColor_Gray) {
85 | NSLog(@"Warning: Possible circular reference? %@ -> %@", self.identifier, node.identifier);
86 | }
87 | }
88 |
89 | [sortedArray addObject:[self sortableObject]];
90 | self.color = CDNodeColor_Black;
91 | }
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/Source/CDTopologicalSortProtocol.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | // A rather clunky way to avoid warnings in CDTopoSortNode.m regarding -retain not implemented by protocols
7 | @protocol CDTopologicalSort
8 | @property (nonatomic, readonly) NSString *identifier;
9 | @property (nonatomic, readonly) NSArray *dependancies;
10 | @end
11 |
--------------------------------------------------------------------------------
/Source/CDType.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDTypeController, CDTypeFormatter, CDTypeName;
7 |
8 | @interface CDType : NSObject
9 |
10 | - (id)initSimpleType:(int)type;
11 | - (id)initIDType:(CDTypeName *)name;
12 | - (id)initIDType:(CDTypeName *)name withProtocols:(NSArray *)protocols;
13 | - (id)initIDTypeWithProtocols:(NSArray *)protocols;
14 | - (id)initStructType:(CDTypeName *)name members:(NSArray *)members;
15 | - (id)initUnionType:(CDTypeName *)name members:(NSArray *)members;
16 | - (id)initBitfieldType:(NSString *)bitfieldSize;
17 | - (id)initArrayType:(CDType *)type count:(NSString *)count;
18 | - (id)initPointerType:(CDType *)type;
19 | - (id)initFunctionPointerType;
20 | - (id)initBlockTypeWithTypes:(NSArray *)types;
21 | - (id)initModifier:(int)modifier type:(CDType *)type;
22 |
23 | @property (strong) NSString *variableName;
24 |
25 | @property (nonatomic, readonly) int primitiveType;
26 | @property (nonatomic, readonly) BOOL isIDType;
27 | @property (nonatomic, readonly) BOOL isNamedObject;
28 | @property (nonatomic, readonly) BOOL isTemplateType;
29 |
30 | @property (nonatomic, readonly) CDType *subtype;
31 | @property (nonatomic, readonly) CDTypeName *typeName;
32 |
33 | @property (nonatomic, readonly) NSArray *members;
34 | @property (nonatomic, readonly) NSArray *types;
35 |
36 | @property (nonatomic, readonly) int typeIgnoringModifiers;
37 | @property (nonatomic, readonly) NSUInteger structureDepth;
38 |
39 | - (NSString *)formattedString:(NSString *)previousName formatter:(CDTypeFormatter *)typeFormatter level:(NSUInteger)level;
40 |
41 | @property (nonatomic, readonly) NSString *typeString;
42 | @property (nonatomic, readonly) NSString *bareTypeString;
43 | @property (nonatomic, readonly) NSString *reallyBareTypeString;
44 | @property (nonatomic, readonly) NSString *keyTypeString;
45 |
46 |
47 | - (BOOL)canMergeWithType:(CDType *)otherType;
48 | - (void)mergeWithType:(CDType *)otherType;
49 |
50 | @property (nonatomic, readonly) NSArray *memberVariableNames;
51 | - (void)generateMemberNames;
52 |
53 | // Phase 0
54 | - (void)phase:(NSUInteger)phase registerTypesWithObject:(CDTypeController *)typeController usedInMethod:(BOOL)isUsedInMethod;
55 | - (void)phase0RecursivelyFixStructureNames:(BOOL)flag;
56 |
57 | // Phase 1
58 | - (void)phase1RegisterStructuresWithObject:(CDTypeController *)typeController;
59 |
60 | // Phase 2
61 | - (void)phase2MergeWithTypeController:(CDTypeController *)typeController debug:(BOOL)phase2Debug;
62 |
63 | // Phase 3
64 | - (void)phase3RegisterMembersWithTypeController:(CDTypeController *)typeController;
65 | - (void)phase3MergeWithTypeController:(CDTypeController *)typeController;
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/Source/CDTypeController.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @protocol CDTypeControllerDelegate;
7 |
8 | @class CDClassDump, CDType, CDTypeFormatter;
9 |
10 | @interface CDTypeController : NSObject
11 |
12 | - (id)initWithClassDump:(CDClassDump *)classDump;
13 |
14 | @property (weak) id delegate;
15 |
16 | @property (readonly) CDTypeFormatter *ivarTypeFormatter;
17 | @property (readonly) CDTypeFormatter *methodTypeFormatter;
18 | @property (readonly) CDTypeFormatter *propertyTypeFormatter;
19 | @property (readonly) CDTypeFormatter *structDeclarationTypeFormatter;
20 |
21 | @property (nonatomic, readonly) BOOL shouldShowIvarOffsets;
22 | @property (nonatomic, readonly) BOOL shouldShowMethodAddresses;
23 | @property (nonatomic, readonly) BOOL targetArchUses64BitABI;
24 |
25 | @property (nonatomic, assign) BOOL hasUnknownFunctionPointers;
26 | @property (nonatomic, assign) BOOL hasUnknownBlocks;
27 |
28 | - (CDType *)typeFormatter:(CDTypeFormatter *)typeFormatter replacementForType:(CDType *)type;
29 | - (NSString *)typeFormatter:(CDTypeFormatter *)typeFormatter typedefNameForStructure:(CDType *)structureType level:(NSUInteger)level;
30 | - (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceClassName:(NSString *)name;
31 | - (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceProtocolNames:(NSArray *)names;
32 |
33 | - (void)appendStructuresToString:(NSMutableString *)resultString;
34 |
35 | // Phase 0 - initiated from -[CDClassDump registerTypes]
36 | - (void)phase0RegisterStructure:(CDType *)structure usedInMethod:(BOOL)isUsedInMethod;
37 |
38 | // Run phase 1+
39 | - (void)workSomeMagic;
40 |
41 | // Phase 1
42 | - (void)phase1RegisterStructure:(CDType *)structure;
43 |
44 | - (void)endPhase:(NSUInteger)phase;
45 |
46 | - (CDType *)phase2ReplacementForType:(CDType *)type;
47 |
48 | - (void)phase3RegisterStructure:(CDType *)structure;
49 | - (CDType *)phase3ReplacementForType:(CDType *)type;
50 |
51 | - (BOOL)shouldShowName:(NSString *)name;
52 | - (BOOL)shouldExpandType:(CDType *)type;
53 | - (NSString *)typedefNameForType:(CDType *)type;
54 |
55 | @end
56 |
57 | #pragma mark -
58 |
59 | @protocol CDTypeControllerDelegate
60 | @optional
61 | - (void)typeController:(CDTypeController *)typeController didReferenceClassName:(NSString *)name;
62 | - (void)typeController:(CDTypeController *)typeController didReferenceProtocolNames:(NSArray *)names;
63 | @end
64 |
--------------------------------------------------------------------------------
/Source/CDTypeFormatter.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDType, CDTypeController;
7 |
8 | @interface CDTypeFormatter : NSObject
9 |
10 | @property (weak) CDTypeController *typeController;
11 |
12 | @property (assign) NSUInteger baseLevel;
13 | @property (assign) BOOL shouldExpand;
14 | @property (assign) BOOL shouldAutoExpand;
15 | @property (assign) BOOL shouldShowLexing;
16 |
17 | - (NSString *)formatVariable:(NSString *)name type:(CDType *)type;
18 | - (NSString *)formatMethodName:(NSString *)name typeString:(NSString *)typeString;
19 |
20 | - (NSString *)typedefNameForStructure:(CDType *)structureType level:(NSUInteger)level;
21 |
22 | - (void)formattingDidReferenceClassName:(NSString *)name;
23 | - (void)formattingDidReferenceProtocolNames:(NSArray *)names;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Source/CDTypeLexer.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #define TK_EOS 0
7 | #define TK_NUMBER 257
8 | #define TK_IDENTIFIER 258
9 | #define T_NAMED_OBJECT 259
10 | #define TK_QUOTED_STRING 260
11 | #define TK_TEMPLATE_TYPE TK_IDENTIFIER
12 | #define T_FUNCTION_POINTER_TYPE 1001
13 | #define T_BLOCK_TYPE 1002
14 |
15 | typedef enum : NSUInteger {
16 | CDTypeLexerState_Normal = 0,
17 | CDTypeLexerState_Identifier = 1,
18 | CDTypeLexerState_TemplateTypes = 2,
19 | } CDTypeLexerState;
20 |
21 | @interface CDTypeLexer : NSObject
22 |
23 | - (id)initWithString:(NSString *)string;
24 |
25 | @property (readonly) NSScanner *scanner;
26 | @property (nonatomic, assign) CDTypeLexerState state;
27 | @property (assign) BOOL shouldShowLexing;
28 |
29 | @property (nonatomic, readonly) NSString *string;
30 | - (int)scanNextToken;
31 |
32 | @property (strong) NSString *lexText;
33 |
34 | @property (nonatomic, readonly) unichar peekChar;
35 | @property (nonatomic, readonly) NSString *remainingString;
36 | @property (nonatomic, readonly) NSString *peekIdentifier;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/Source/CDTypeName.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface CDTypeName : NSObject
7 |
8 | @property (strong) NSString *name;
9 | @property (readonly) NSMutableArray *templateTypes;
10 | @property (strong) NSString *suffix;
11 | @property (nonatomic, readonly) BOOL isTemplateType;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Source/CDTypeName.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDTypeName.h"
7 |
8 | @implementation CDTypeName
9 | {
10 | NSString *_name;
11 | NSMutableArray *_templateTypes;
12 | NSString *_suffix;
13 | }
14 |
15 | - (id)init;
16 | {
17 | if ((self = [super init])) {
18 | _name = nil;
19 | _templateTypes = [[NSMutableArray alloc] init];
20 | _suffix = nil;
21 | }
22 |
23 | return self;
24 | }
25 |
26 | #pragma mark - NSCopying
27 |
28 | - (id)copyWithZone:(NSZone *)zone;
29 | {
30 | CDTypeName *copy = [[CDTypeName alloc] init];
31 | copy.name = self.name;
32 | copy.suffix = self.suffix;
33 |
34 | for (CDTypeName *subtype in self.templateTypes) {
35 | CDTypeName *subcopy = [subtype copy];
36 | [copy.templateTypes addObject:subcopy];
37 | }
38 |
39 | return copy;
40 | }
41 |
42 | #pragma mark -
43 |
44 | - (BOOL)isEqual:(id)otherObject;
45 | {
46 | if ([otherObject isKindOfClass:[self class]] == NO)
47 | return NO;
48 |
49 | return [[self description] isEqual:[otherObject description]];
50 | }
51 |
52 | #pragma mark - Debugging
53 |
54 | - (NSString *)description;
55 | {
56 | if ([self.templateTypes count] == 0) {
57 | return self.name ? self.name : @"";
58 | }
59 |
60 | if (self.suffix != nil)
61 | return [NSString stringWithFormat:@"%@<%@>%@", self.name, [self.templateTypes componentsJoinedByString:@", "], self.suffix];
62 |
63 | return [NSString stringWithFormat:@"%@<%@>", self.name, [self.templateTypes componentsJoinedByString:@", "]];
64 | }
65 |
66 | #pragma mark -
67 |
68 | - (BOOL)isTemplateType;
69 | {
70 | return [self.templateTypes count] > 0;
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/Source/CDTypeParser.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDType, CDTypeLexer;
7 |
8 | extern NSString *CDExceptionName_SyntaxError;
9 | extern NSString *CDErrorDomain_TypeParser;
10 |
11 | extern NSString *CDErrorKey_Type;
12 | extern NSString *CDErrorKey_RemainingString;
13 | extern NSString *CDErrorKey_MethodOrVariable;
14 | extern NSString *CDErrorKey_LocalizedLongDescription;
15 |
16 | #define CDTypeParserCode_Default 0
17 | #define CDTypeParserCode_SyntaxError 1
18 |
19 | @interface CDTypeParser : NSObject
20 |
21 | - (id)initWithString:(NSString *)string;
22 |
23 | @property (readonly) CDTypeLexer *lexer;
24 |
25 | - (NSArray *)parseMethodType:(NSError **)error;
26 | - (CDType *)parseType:(NSError **)error;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/Source/CDVisitor.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDClassDump, CDObjectiveCProcessor, CDOCProtocol, CDOCMethod, CDOCInstanceVariable, CDOCClass, CDOCCategory, CDOCProperty;
7 | @class CDVisitorPropertyState;
8 |
9 | @interface CDVisitor : NSObject
10 |
11 | @property (strong) CDClassDump *classDump;
12 |
13 | - (void)willBeginVisiting;
14 | - (void)didEndVisiting;
15 |
16 | - (void)willVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
17 | - (void)visitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
18 | - (void)didVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
19 |
20 | - (void)willVisitProtocol:(CDOCProtocol *)protocol;
21 | - (void)didVisitProtocol:(CDOCProtocol *)protocol;
22 |
23 | - (void)willVisitPropertiesOfProtocol:(CDOCProtocol *)protocol;
24 | - (void)didVisitPropertiesOfProtocol:(CDOCProtocol *)protocol;
25 |
26 | - (void)willVisitOptionalMethods;
27 | - (void)didVisitOptionalMethods;
28 |
29 | - (void)willVisitClass:(CDOCClass *)aClass;
30 | - (void)didVisitClass:(CDOCClass *)aClass;
31 |
32 | - (void)willVisitIvarsOfClass:(CDOCClass *)aClass;
33 | - (void)didVisitIvarsOfClass:(CDOCClass *)aClass;
34 |
35 | - (void)willVisitPropertiesOfClass:(CDOCClass *)aClass;
36 | - (void)didVisitPropertiesOfClass:(CDOCClass *)aClass;
37 |
38 | - (void)willVisitCategory:(CDOCCategory *)category;
39 | - (void)didVisitCategory:(CDOCCategory *)category;
40 |
41 | - (void)willVisitPropertiesOfCategory:(CDOCCategory *)category;
42 | - (void)didVisitPropertiesOfCategory:(CDOCCategory *)category;
43 |
44 | - (void)visitClassMethod:(CDOCMethod *)method;
45 | - (void)visitInstanceMethod:(CDOCMethod *)method propertyState:(CDVisitorPropertyState *)propertyState;
46 | - (void)visitIvar:(CDOCInstanceVariable *)ivar;
47 | - (void)visitProperty:(CDOCProperty *)property;
48 |
49 | - (void)visitRemainingProperties:(CDVisitorPropertyState *)propertyState;
50 |
51 | @property (assign) BOOL shouldShowStructureSection;
52 | @property (assign) BOOL shouldShowProtocolSection;
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/Source/CDVisitor.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDVisitor.h"
7 |
8 | #import "CDClassDump.h"
9 |
10 | @implementation CDVisitor
11 | {
12 | CDClassDump *_classDump;
13 | BOOL _shouldShowStructureSection;
14 | BOOL _shouldShowProtocolSection;
15 | }
16 |
17 | - (id)init;
18 | {
19 | if ((self = [super init])) {
20 | _shouldShowStructureSection = YES;
21 | _shouldShowProtocolSection = YES;
22 | }
23 |
24 | return self;
25 | }
26 |
27 | #pragma mark -
28 |
29 | - (void)willBeginVisiting;
30 | {
31 | }
32 |
33 | - (void)didEndVisiting;
34 | {
35 | }
36 |
37 | // Called before visiting.
38 | - (void)willVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
39 | {
40 | }
41 |
42 | // This gets called before visiting the children, but only if it has children it will visit.
43 | - (void)visitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
44 | {
45 | }
46 |
47 | - (void)willVisitPropertiesOfProtocol:(CDOCProtocol *)protocol;
48 | {
49 | }
50 |
51 | - (void)didVisitPropertiesOfProtocol:(CDOCProtocol *)protocol;
52 | {
53 | }
54 |
55 | - (void)willVisitOptionalMethods;
56 | {
57 | }
58 |
59 | - (void)didVisitOptionalMethods;
60 | {
61 | }
62 |
63 | // Called after visiting.
64 | - (void)didVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
65 | {
66 | }
67 |
68 | - (void)willVisitProtocol:(CDOCProtocol *)protocol;
69 | {
70 | }
71 |
72 | - (void)didVisitProtocol:(CDOCProtocol *)protocol;
73 | {
74 | }
75 |
76 | - (void)willVisitClass:(CDOCClass *)aClass;
77 | {
78 | }
79 |
80 | - (void)didVisitClass:(CDOCClass *)aClass;
81 | {
82 | }
83 |
84 | - (void)willVisitIvarsOfClass:(CDOCClass *)aClass;
85 | {
86 | }
87 |
88 | - (void)didVisitIvarsOfClass:(CDOCClass *)aClass;
89 | {
90 | }
91 |
92 | - (void)willVisitPropertiesOfClass:(CDOCClass *)aClass;
93 | {
94 | }
95 |
96 | - (void)didVisitPropertiesOfClass:(CDOCClass *)aClass;
97 | {
98 | }
99 |
100 | - (void)willVisitCategory:(CDOCCategory *)category;
101 | {
102 | }
103 |
104 | - (void)didVisitCategory:(CDOCCategory *)category;
105 | {
106 | }
107 |
108 | - (void)willVisitPropertiesOfCategory:(CDOCCategory *)category;
109 | {
110 | }
111 |
112 | - (void)didVisitPropertiesOfCategory:(CDOCCategory *)category;
113 | {
114 | }
115 |
116 | - (void)visitClassMethod:(CDOCMethod *)method;
117 | {
118 | }
119 |
120 | - (void)visitInstanceMethod:(CDOCMethod *)method propertyState:(CDVisitorPropertyState *)propertyState;
121 | {
122 | }
123 |
124 | - (void)visitIvar:(CDOCInstanceVariable *)ivar;
125 | {
126 | }
127 |
128 | - (void)visitProperty:(CDOCProperty *)property;
129 | {
130 | }
131 |
132 | - (void)visitRemainingProperties:(CDVisitorPropertyState *)propertyState;
133 | {
134 | }
135 |
136 | @end
137 |
--------------------------------------------------------------------------------
/Source/CDVisitorPropertyState.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @class CDOCProperty;
7 |
8 | @interface CDVisitorPropertyState : NSObject
9 |
10 | - (id)initWithProperties:(NSArray *)properties;
11 |
12 | - (CDOCProperty *)propertyForAccessor:(NSString *)str;
13 |
14 | - (BOOL)hasUsedProperty:(CDOCProperty *)property;
15 | - (void)useProperty:(CDOCProperty *)property;
16 |
17 | @property (nonatomic, readonly) NSArray *remainingProperties;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Source/CDVisitorPropertyState.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "CDVisitorPropertyState.h"
7 |
8 | #import "CDOCProperty.h"
9 |
10 | @interface CDVisitorPropertyState ()
11 | @end
12 |
13 | #pragma mark -
14 |
15 | @implementation CDVisitorPropertyState
16 | {
17 | NSMutableDictionary *_propertiesByAccessor; // NSString (accessor) -> CDOCProperty
18 | NSMutableDictionary *_propertiesByName; // NSString (property name) -> CDOCProperty
19 | }
20 |
21 | - (id)initWithProperties:(NSArray *)properties;
22 | {
23 | if ((self = [super init])) {
24 | _propertiesByAccessor = [[NSMutableDictionary alloc] init];
25 | _propertiesByName = [[NSMutableDictionary alloc] init];
26 |
27 | for (CDOCProperty *property in properties) {
28 | //NSLog(@"property: %@, getter: %@, setter: %@", [property name], [property getter], [property setter]);
29 | _propertiesByName[property.name] = property;
30 | _propertiesByAccessor[property.getter] = property;
31 | if (property.isReadOnly == NO)
32 | _propertiesByAccessor[property.setter] = property;
33 | }
34 | }
35 |
36 | return self;
37 | }
38 |
39 | #pragma mark - Debugging
40 |
41 | - (void)log;
42 | {
43 | NSLog(@"propertiesByAccessor: %@", _propertiesByAccessor);
44 | NSLog(@"propertiesByName: %@", _propertiesByName);
45 | }
46 |
47 | #pragma mark -
48 |
49 | - (CDOCProperty *)propertyForAccessor:(NSString *)str;
50 | {
51 | return _propertiesByAccessor[str];
52 | }
53 |
54 | - (BOOL)hasUsedProperty:(CDOCProperty *)property;
55 | {
56 | return _propertiesByName[property.name] == nil;
57 | }
58 |
59 | - (void)useProperty:(CDOCProperty *)property;
60 | {
61 | [_propertiesByName removeObjectForKey:property.name];
62 | }
63 |
64 | - (NSArray *)remainingProperties;
65 | {
66 | return [[_propertiesByName allValues] sortedArrayUsingSelector:@selector(ascendingCompareByName:)];
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/Source/NSArray-CDExtensions.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface NSArray (CDExtensions)
7 |
8 | - (NSArray *)reversedArray;
9 |
10 | @end
11 |
12 | @interface NSArray (CDTopoSort)
13 |
14 | - (NSArray *)topologicallySortedArray;
15 |
16 | @end
17 |
18 | @interface NSMutableArray (CDTopoSort)
19 |
20 | - (void)sortTopologically;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/Source/NSArray-CDExtensions.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "NSArray-CDExtensions.h"
7 |
8 | @implementation NSArray (CDExtensions)
9 |
10 | - (NSArray *)reversedArray;
11 | {
12 | return [[self reverseObjectEnumerator] allObjects];
13 | }
14 |
15 | @end
16 |
17 | #pragma mark -
18 |
19 | @implementation NSArray (CDTopoSort)
20 |
21 | - (NSArray *)topologicallySortedArray;
22 | {
23 | NSMutableDictionary *nodesByName = [[NSMutableDictionary alloc] init];
24 |
25 | for (id object in self) {
26 | CDTopoSortNode *node = [[CDTopoSortNode alloc] initWithObject:object];
27 | [node addDependanciesFromArray:[object dependancies]];
28 |
29 | if (nodesByName[node.identifier] != nil)
30 | NSLog(@"Warning: Duplicate identifier (%@) in %s", node.identifier, __cmd);
31 | nodesByName[node.identifier] = node;
32 | }
33 |
34 | NSMutableArray *sortedArray = [NSMutableArray array];
35 |
36 | NSArray *allNodes = [[nodesByName allValues] sortedArrayUsingSelector:@selector(ascendingCompareByIdentifier:)];
37 | for (CDTopoSortNode *node in allNodes) {
38 | if (node.color == CDNodeColor_White)
39 | [node topologicallySortNodes:nodesByName intoArray:sortedArray];
40 | }
41 |
42 |
43 | return sortedArray;
44 | }
45 |
46 | @end
47 |
48 | #pragma mark -
49 |
50 | @implementation NSMutableArray (CDTopoSort)
51 |
52 | - (void)sortTopologically;
53 | {
54 | NSArray *sortedArray = [self topologicallySortedArray];
55 | assert([self count] == [sortedArray count]);
56 |
57 | [self removeAllObjects];
58 | [self addObjectsFromArray:sortedArray];
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/Source/NSData-CDExtensions.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface NSData (CDExtensions)
7 |
8 | - (NSString *)hexString;
9 | - (NSData *)SHA1Digest;
10 |
11 | @end
12 |
--------------------------------------------------------------------------------
/Source/NSData-CDExtensions.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "NSData-CDExtensions.h"
7 |
8 | #import
9 |
10 | @implementation NSData (CDExtensions)
11 |
12 | - (NSString *)hexString;
13 | {
14 | NSMutableString *str = [NSMutableString string];
15 | const uint8_t *ptr = [self bytes];
16 | for (NSUInteger index = 0; index < [self length]; index++) {
17 | [str appendFormat:@"%02x", *ptr++];
18 | }
19 |
20 | return str;
21 | }
22 |
23 | - (NSData *)SHA1Digest;
24 | {
25 | NSParameterAssert([self length] <= UINT32_MAX);
26 |
27 | unsigned char digest[CC_SHA1_DIGEST_LENGTH];
28 | CC_SHA1([self bytes], (CC_LONG)[self length], digest);
29 |
30 | return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Source/NSError-CDExtensions.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface NSError (CDExtensions)
7 |
8 | @end
9 |
10 | extern NSString *NSErrorDomain_ClassDump;
11 |
--------------------------------------------------------------------------------
/Source/NSError-CDExtensions.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "NSError-CDExtensions.h"
7 |
8 | NSString *NSErrorDomain_ClassDump = @"com.stevenygard.MachObjC.ErrorDomain";
9 |
10 | @implementation NSError (CDExtensions)
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Source/NSScanner-CDExtensions.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface NSScanner (CDExtensions)
7 |
8 | + (NSCharacterSet *)cdOtherCharacterSet;
9 | + (NSCharacterSet *)cdIdentifierStartCharacterSet;
10 | + (NSCharacterSet *)cdIdentifierCharacterSet;
11 | + (NSCharacterSet *)cdTemplateTypeCharacterSet;
12 |
13 | - (NSString *)peekCharacter;
14 | - (unichar)peekChar;
15 | - (BOOL)scanCharacter:(unichar *)value;
16 | - (BOOL)scanCharacterFromSet:(NSCharacterSet *)set intoString:(NSString **)value;
17 | - (BOOL)my_scanCharactersFromSet:(NSCharacterSet *)set intoString:(NSString **)value;
18 |
19 | - (BOOL)scanIdentifierIntoString:(NSString **)stringPointer;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Source/NSString-CDExtensions.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | @interface NSString (CDExtensions)
7 |
8 | + (NSString *)stringWithFileSystemRepresentation:(const char *)str;
9 | + (NSString *)spacesIndentedToLevel:(NSUInteger)level;
10 | + (NSString *)spacesIndentedToLevel:(NSUInteger)level spacesPerLevel:(NSUInteger)spacesPerLevel;
11 | + (NSString *)stringWithUnichar:(unichar)character;
12 |
13 | - (BOOL)isFirstLetterUppercase;
14 |
15 | - (void)print;
16 |
17 | - (NSString *)executablePathForFilename;
18 |
19 | - (NSString *)SHA1DigestString;
20 |
21 | - (BOOL)hasUnderscoreCapitalPrefix;
22 | - (NSString *)capitalizeFirstCharacter;
23 |
24 | @end
25 |
26 | @interface NSMutableString (CDExtensions)
27 |
28 | - (void)appendSpacesIndentedToLevel:(NSUInteger)level;
29 | - (void)appendSpacesIndentedToLevel:(NSUInteger)level spacesPerLevel:(NSUInteger)spacesPerLevel;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/Source/ULEB128.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | // http://en.wikipedia.org/wiki/LEB128
7 | // http://web.mit.edu/rhel-doc/3/rhel-as-en-3/uleb128.html
8 | // uleb128 stands for "unsigned little endian base 128."
9 | // This is a compact, variable length representation of numbers used by the DWARF symbolic debugging format.
10 |
11 | // Top bit of byte is set until last byte.
12 | // Other 7 bits are the "slice".
13 | // Basically, it represents the low order bits 7 at a time, and can stop when the rest of the bits would be zero.
14 | // This needs to modify ptr.
15 |
16 | // For example, uleb with these bytes: e8 d7 15
17 | // 0xe8 = 1110 1000
18 | // 0xd7 = 1101 0111
19 | // 0x15 = 0001 0101
20 |
21 | // .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... ....
22 | // 0xe8 1 1101000 .... .... .... .... .... .... .... .... .... .... .... .... .... .... .110 1000
23 | // 0xd7 1 1010111 .... .... .... .... .... .... .... .... .... .... .... .... ..10 1011 1110 1000
24 | // 0x15 0 0010101 .... .... .... .... .... .... .... .... .... .... .... .... ..10 1011 1110 1000
25 | // 0x15 0 0010101 .... .... .... .... .... .... .... .... .... .... ...0 0101 0110 1011 1110 1000
26 | // Result is: 0x056be8
27 | // So... 24 bits to encode 64 bits
28 |
29 | uint64_t read_uleb128(const uint8_t **ptrptr, const uint8_t *end);
30 |
31 | int64_t read_sleb128(const uint8_t **ptrptr, const uint8_t *end);
32 |
--------------------------------------------------------------------------------
/Source/ULEB128.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import "ULEB128.h"
7 |
8 | uint64_t read_uleb128(const uint8_t **ptrptr, const uint8_t *end)
9 | {
10 | const uint8_t *ptr = *ptrptr;
11 | uint64_t result = 0;
12 | int bit = 0;
13 |
14 | //NSLog(@"read_uleb128()");
15 | do {
16 | NSCAssert(ptr != end, @"Malformed uleb128", nil);
17 |
18 | //NSLog(@"byte: %02x", *ptr);
19 | uint64_t slice = *ptr & 0x7f;
20 |
21 | if (bit >= 64 || slice << bit >> bit != slice) {
22 | NSLog(@"uleb128 too big");
23 | exit(88);
24 | } else {
25 | result |= (slice << bit);
26 | bit += 7;
27 | }
28 | }
29 | while ((*ptr++ & 0x80) != 0);
30 |
31 | #if 0
32 | static NSUInteger maxlen = 0;
33 | if (maxlen < ptr - *ptrptr) {
34 | const uint8_t *ptr2 = *ptrptr;
35 |
36 | NSMutableArray *byteStrs = [NSMutableArray array];
37 | do {
38 | [byteStrs addObject:[NSString stringWithFormat:@"%02x", *ptr2]];
39 | } while (++ptr2 < ptr);
40 | //NSLog(@"max uleb length now: %u (%@)", ptr - *ptrptr, [byteStrs componentsJoinedByString:@" "]);
41 | //NSLog(@"sizeof(uint64_t): %u, sizeof(uintptr_t): %u", sizeof(uint64_t), sizeof(uintptr_t));
42 | maxlen = ptr - *ptrptr;
43 | }
44 | #endif
45 |
46 | *ptrptr = ptr;
47 | return result;
48 | }
49 |
50 | int64_t read_sleb128(const uint8_t **ptrptr, const uint8_t *end)
51 | {
52 | const uint8_t *ptr = *ptrptr;
53 |
54 | int64_t result = 0;
55 | int bit = 0;
56 | uint8_t byte;
57 |
58 | //NSLog(@"read_sleb128()");
59 | do {
60 | NSCAssert(ptr != end, @"Malformed sleb128", nil);
61 |
62 | byte = *ptr++;
63 | //NSLog(@"%02x", byte);
64 | result |= ((byte & 0x7f) << bit);
65 | bit += 7;
66 | } while ((byte & 0x80) != 0);
67 |
68 | //NSLog(@"result before sign extend: %ld", result);
69 | // sign extend negative numbers
70 | // This essentially clears out from -1 the low order bits we've already set, and combines that with our bits.
71 | if ( (byte & 0x40) != 0 )
72 | result |= (-1LL) << bit;
73 |
74 | //NSLog(@"result after sign extend: %ld", result);
75 |
76 | //NSLog(@"ptr before: %p, after: %p", *ptrptr, ptr);
77 | *ptrptr = ptr;
78 | return result;
79 | }
80 |
--------------------------------------------------------------------------------
/Source/cd_objc2.h:
--------------------------------------------------------------------------------
1 | struct cd_objc2_list_header {
2 | uint32_t entsize;
3 | uint32_t count;
4 | };
5 |
6 | struct cd_objc2_image_info {
7 | uint32_t version;
8 | uint32_t flags;
9 | };
10 |
11 |
12 | //
13 | // 64-bit, also holding 32-bit
14 | //
15 |
16 | struct cd_objc2_class {
17 | uint64_t isa;
18 | uint64_t superclass;
19 | uint64_t cache;
20 | uint64_t vtable;
21 | uint64_t data; // points to class_ro_t
22 | uint64_t reserved1;
23 | uint64_t reserved2;
24 | uint64_t reserved3;
25 | };
26 |
27 | struct cd_objc2_class_ro_t {
28 | uint32_t flags;
29 | uint32_t instanceStart;
30 | uint32_t instanceSize;
31 | uint32_t reserved; // *** this field does not exist in the 32-bit version ***
32 | uint64_t ivarLayout;
33 | uint64_t name;
34 | uint64_t baseMethods;
35 | uint64_t baseProtocols;
36 | uint64_t ivars;
37 | uint64_t weakIvarLayout;
38 | uint64_t baseProperties;
39 | };
40 |
41 | struct cd_objc2_method {
42 | uint64_t name;
43 | uint64_t types;
44 | uint64_t imp;
45 | };
46 |
47 | struct cd_objc2_ivar {
48 | uint64_t offset;
49 | uint64_t name;
50 | uint64_t type;
51 | uint32_t alignment;
52 | uint32_t size;
53 | };
54 |
55 | struct cd_objc2_property {
56 | uint64_t name;
57 | uint64_t attributes;
58 | };
59 |
60 | struct cd_objc2_protocol {
61 | uint64_t isa;
62 | uint64_t name;
63 | uint64_t protocols;
64 | uint64_t instanceMethods;
65 | uint64_t classMethods;
66 | uint64_t optionalInstanceMethods;
67 | uint64_t optionalClassMethods;
68 | uint64_t instanceProperties; // So far, always 0
69 | uint32_t size; // sizeof(cd_objc2_protocol)
70 | uint32_t flags;
71 | uint64_t extendedMethodTypes;
72 | };
73 |
74 | struct cd_objc2_category {
75 | uint64_t name;
76 | uint64_t class;
77 | uint64_t instanceMethods;
78 | uint64_t classMethods;
79 | uint64_t protocols;
80 | uint64_t instanceProperties;
81 | uint64_t v7;
82 | uint64_t v8;
83 | };
84 |
--------------------------------------------------------------------------------
/Tests/showdiff:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 |
3 | pushd /tmp/cdt/new
4 | foreach i (*.txt)
5 | echo -e "\\033[32m"
6 | echo $i
7 | echo -e "\\033[0m"
8 | diff ../old/$i $i | colordiff.pl
9 | echo
10 | echo
11 | echo
12 |
13 | end
14 |
--------------------------------------------------------------------------------
/ThirdParty/blowfish.h:
--------------------------------------------------------------------------------
1 | /*
2 | blowfish.h: Header file for blowfish.c
3 |
4 | Copyright (C) 1997 by Paul Kocher
5 |
6 | This library is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU Lesser General Public
8 | License as published by the Free Software Foundation; either
9 | version 2.1 of the License, or (at your option) any later version.
10 | This library is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public
15 | License along with this library; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 |
19 | See blowfish.c for more information about this file.
20 | */
21 |
22 | #include
23 |
24 | typedef struct {
25 | uint32_t P[16 + 2];
26 | uint32_t S[4][256];
27 | } BLOWFISH_CTX;
28 |
29 | void Blowfish_Init(BLOWFISH_CTX *ctx, uint8_t *key, int32_t keyLen);
30 | void Blowfish_Encrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr);
31 | void Blowfish_Decrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr);
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/UnitTests.old/AllTests.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
3 | #import
4 |
5 | @interface AllTests : SenTestCase
6 | {
7 | }
8 |
9 | + (id)defaultTestSuite;
10 |
11 | @end
12 |
--------------------------------------------------------------------------------
/UnitTests.old/CDPathUnitTest.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | @class CDClassDump;
9 |
10 | @interface CDPathUnitTest : SenTestCase
11 | {
12 | CDClassDump *classDump;
13 | }
14 |
15 | - (void)setUp;
16 | - (void)tearDown;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/UnitTests.old/CDPathUnitTest.m:
--------------------------------------------------------------------------------
1 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
2 | // Copyright (C) 1997-2019 Steve Nygard.
3 |
4 | #import "CDPathUnitTest.h"
5 |
6 | #import
7 | #import "CDClassDump.h"
8 |
9 | @implementation CDPathUnitTest
10 |
11 | - (void)setUp;
12 | {
13 | classDump = [[CDClassDump alloc] init];
14 | }
15 |
16 | - (void)tearDown;
17 | {
18 | [classDump release];
19 | classDump = nil;
20 | }
21 |
22 | - (void)testPrivateSyncFramework;
23 | {
24 | NSString *path = @"/System/Library/PrivateFrameworks/SyndicationUI.framework";
25 | NSBundle *bundle;
26 |
27 | bundle = [NSBundle bundleWithPath:path];
28 | STAssertNotNil(bundle, @"%@ doesn't seem to exist, we can remove this test now.", path);
29 | if (bundle != nil) {
30 | STAssertNil([bundle executablePath], @"This fails on 10.5. It's fixed if you see this! Executable path for %@", path);
31 | //STAssertNotNil([bundle executablePath], @"This fails on 10.5. Executable path for %@", path);
32 | }
33 | }
34 |
35 | - (void)testBundlePathWithoutTrailingSlash;
36 | {
37 | BOOL result;
38 |
39 | result = [classDump processFilename:@"/System/Library/Frameworks/AppKit.framework"];
40 | STAssertEquals(YES, result, @"Couldn't process AppKit.framework");
41 | STAssertEqualObjects(@"/System/Library/Frameworks/AppKit.framework/Versions/C", [classDump executablePath], @"");
42 | }
43 |
44 | - (void)testBundlePathWithTrailingSlash;
45 | {
46 | BOOL result;
47 |
48 | result = [classDump processFilename:@"/System/Library/Frameworks/AppKit.framework/"];
49 | STAssertEquals(YES, result, @"Couldn't process AppKit.framework");
50 | STAssertEqualObjects(@"/System/Library/Frameworks/AppKit.framework/Versions/C", [classDump executablePath], @"");
51 | }
52 |
53 | - (void)testExecutableSymlinkPath;
54 | {
55 | BOOL result;
56 |
57 | result = [classDump processFilename:@"/System/Library/Frameworks/AppKit.framework/AppKit"];
58 | STAssertEquals(YES, result, @"Couldn't process AppKit.framework");
59 | STAssertEqualObjects(@"/System/Library/Frameworks/AppKit.framework/Versions/C", [classDump executablePath], @"");
60 | }
61 |
62 | - (void)testExecutableFullPath;
63 | {
64 | BOOL result;
65 |
66 | result = [classDump processFilename:@"/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"];
67 | STAssertEquals(YES, result, @"Couldn't process AppKit.framework");
68 | STAssertEqualObjects(@"/System/Library/Frameworks/AppKit.framework/Versions/C", [classDump executablePath], @"");
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/UnitTests.old/CDStructHandlingUnitTest.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | @class CDClassDump;
9 |
10 | @interface CDStructHandlingUnitTest : SenTestCase
11 | {
12 | CDClassDump *classDump;
13 | }
14 |
15 | - (void)dealloc;
16 |
17 | - (void)setUp;
18 | - (void)tearDown;
19 |
20 | - (void)testVariableName:(NSString *)aVariableName type:(NSString *)aType expectedResult:(NSString *)expectedResult;
21 | - (void)registerStructsFromType:(NSString *)aTypeString phase:(int)phase;
22 |
23 | - (void)testFilename:(NSString *)testFilename;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/UnitTests.old/CDTypeFormatterUnitTest.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | @class CDTypeFormatter;
9 |
10 | @interface CDTypeFormatterUnitTest : SenTestCase
11 | {
12 | CDTypeFormatter *typeFormatter;
13 | }
14 |
15 | - (void)dealloc;
16 |
17 | - (void)setUp;
18 | - (void)tearDown;
19 |
20 | - (void)testVariableName:(NSString *)aVariableName type:(NSString *)aType expectedResult:(NSString *)expectedResult;
21 | - (void)parseAndEncodeType:(NSString *)originalType;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/UnitTests.old/CDTypeLexerUnitTest.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | @class CDTypeLexer;
9 |
10 | @interface CDTypeLexerUnitTest : SenTestCase
11 | {
12 | CDTypeLexer *lexer;
13 | }
14 |
15 | - (void)setUp;
16 | - (void)tearDown;
17 |
18 | - (void)_setupLexerForString:(NSString *)str;
19 | - (void)_cleanupLexer;
20 | - (void)_showScannedTokens;
21 | - (void)showScannedTokensForString:(NSString *)str;
22 |
23 | - (void)testLexingString:(NSString *)str expectedResults:(struct tokenValuePair *)expectedResults;
24 |
25 | - (void)testSimpleTokens;
26 | - (void)testQuotedStringToken;
27 | - (void)testEmptyQuotedStringToken;
28 | - (void)testUnterminatedQuotedString;
29 | - (void)testIdentifierToken;
30 | - (void)testTemplateTokens;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/UnitTests.old/CDTypeParserUnitTest.h:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | @interface CDTypeParserUnitTest : SenTestCase
9 | {
10 | }
11 |
12 | - (void)setUp;
13 | - (void)tearDown;
14 |
15 | - (void)testType:(NSString *)aType showLexing:(BOOL)shouldShowLexing;
16 | - (void)testMethodType:(NSString *)aMethodType showLexing:(BOOL)shouldShowLexing;
17 |
18 | - (void)testLoneConstType;
19 | - (void)testObjectQuotedStringTypes;
20 |
21 | - (void)testMissingFieldNames;
22 | - (void)testLowercaseClassName;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/UnitTests.old/method-001.txt:
--------------------------------------------------------------------------------
1 | // This comes from Safari 4.0.2 on Mac OS 10.5
2 | // The problem here was with the trailing * after the template type name.
3 |
4 | initWithBookmarkGroup:
5 | @12@0:4^{BookmarkGroup=B{SString={RetainPtr=^{__CFString}}}{SString={RetainPtr=^{__CFString}}}B{HashMap, 0ul>*,Safari::SCFObjectSubclassHash,WTF::HashTraits,WTF::HashTraits, 0ul>*> >={HashTable, 0ul>*>,WTF::PairFirstExtractor, 0ul>*> >,Safari::SCFObjectSubclassHash,WTF::PairHashTraits, WTF::HashTraits, 0ul>*> >,WTF::HashTraits >=^{pair, 0ul>*>}iiii}}{HashMap,Safari::SCFObjectSubclassHash,WTF::HashTraits,WTF::HashTraits > >={HashTable >,WTF::PairFirstExtractor > >,Safari::SCFObjectSubclassHash,WTF::PairHashTraits, WTF::HashTraits > >,WTF::HashTraits >=^{pair >}iiii}}BB{RetainPtr=@}{RetainPtr=@}}8
6 |
--------------------------------------------------------------------------------
/UnitTests.old/otest-all:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ "${OTEST_TEST_CLASS}" = "" ]; then
4 | OTEST_TEST_CLASS="AllTests"
5 | fi
6 |
7 | ${DEVELOPER_DIR}/Tools/otest -SenTest ${OTEST_TEST_CLASS} $*
8 |
--------------------------------------------------------------------------------
/UnitTests.old/shud01-in.txt:
--------------------------------------------------------------------------------
1 | // This tests a simple structure without field names.
2 | {_NSRange=II} foo
3 |
--------------------------------------------------------------------------------
/UnitTests.old/shud01-out.txt:
--------------------------------------------------------------------------------
1 | struct _NSRange {
2 | unsigned int;
3 | unsigned int;
4 | };
5 |
6 | struct _NSRange foo;
7 |
--------------------------------------------------------------------------------
/UnitTests.old/shud02-in.txt:
--------------------------------------------------------------------------------
1 | // This tests recognizing that two structures, one with field names and the other without, are really the same.
2 | {_NSRange=II} foo
3 | {_NSRange="location"I"length"I} bar
4 |
--------------------------------------------------------------------------------
/UnitTests.old/shud02-out.txt:
--------------------------------------------------------------------------------
1 | struct _NSRange {
2 | unsigned int location;
3 | unsigned int length;
4 | };
5 |
6 | struct _NSRange foo;
7 | struct _NSRange bar;
8 |
--------------------------------------------------------------------------------
/UnitTests.old/shud04-in.txt:
--------------------------------------------------------------------------------
1 | // This tests a common structure that contains two other structures.
2 | // Note: It looks like struct _NSSize is shown after _NSRect, but it should really be before it.
3 | {_NSRect={_NSPoint=ff}{_NSSize=ff}}
4 |
--------------------------------------------------------------------------------
/UnitTests.old/shud04-out.txt:
--------------------------------------------------------------------------------
1 | struct _NSPoint {
2 | float;
3 | float;
4 | };
5 |
6 | struct _NSRect {
7 | struct _NSPoint;
8 | struct _NSSize;
9 | };
10 |
11 | struct _NSSize {
12 | float;
13 | float;
14 | };
15 |
16 | struct _NSRect var;
17 |
--------------------------------------------------------------------------------
/UnitTests.old/shud05-in.txt:
--------------------------------------------------------------------------------
1 | {one="field1"i"field2"c"field3"{?=ff}}
2 |
--------------------------------------------------------------------------------
/UnitTests.old/shud05-out.txt:
--------------------------------------------------------------------------------
1 | struct one {
2 | int field1;
3 | char field2;
4 | struct {
5 | float;
6 | float;
7 | } field3;
8 | };
9 |
10 | struct one var;
11 |
--------------------------------------------------------------------------------
/UnitTests.old/shud06-in.txt:
--------------------------------------------------------------------------------
1 | {one="field1"i"field2"c"field3"{?=ff}}
2 | {one="field1"i"field2"c"field3"{?="x"f"y"f}}
3 |
--------------------------------------------------------------------------------
/UnitTests.old/shud06-out.txt:
--------------------------------------------------------------------------------
1 | struct one {
2 | int field1;
3 | char field2;
4 | struct {
5 | float x;
6 | float y;
7 | } field3;
8 | };
9 |
10 | struct one var;
11 | struct one var;
12 |
--------------------------------------------------------------------------------
/UnitTests.old/shud07-in.txt:
--------------------------------------------------------------------------------
1 | {one="field1"i"field2"c"field3"{?="x"f"y"f}}
2 | {one="field1"i"field2"c"field3"{?="x"f"y"f}}
3 |
--------------------------------------------------------------------------------
/UnitTests.old/shud07-out.txt:
--------------------------------------------------------------------------------
1 | struct one {
2 | int field1;
3 | char field2;
4 | struct {
5 | float x;
6 | float y;
7 | } field3;
8 | };
9 |
10 | struct one var;
11 | struct one var;
12 |
--------------------------------------------------------------------------------
/UnitTests.old/shud08-in.txt:
--------------------------------------------------------------------------------
1 | {one="field1"i"field2"c"field3"{?="x"f"y"f}}
2 | {one="field1"i"field2"c"field3"{?="x"f"y"f}}
3 | {?="x"f"y"f}
4 |
--------------------------------------------------------------------------------
/UnitTests.old/shud08-out.txt:
--------------------------------------------------------------------------------
1 | struct one {
2 | int field1;
3 | char field2;
4 | CDAnonymousStruct1 field3;
5 | };
6 |
7 | typedef struct {
8 | float x;
9 | float y;
10 | } CDAnonymousStruct1;
11 |
12 | struct one var;
13 | struct one var;
14 | CDAnonymousStruct1 var;
15 |
--------------------------------------------------------------------------------
/UnitTests.old/shud09-in.txt:
--------------------------------------------------------------------------------
1 | // Test a structure that contains one of many common types. The first type has member names, the second doesn't, but they're the same.
2 | {?="type"i"value"(?="charValue"c"shortValue"s"longValue"l"longlongValue"q"floatValue"f"doubleValue"d"boolValue"B"selectorValue":"objectValue"@"pointerValue"^v"structLocation"^v"cStringLocation"*)}
3 | {?=i(?=cslqfdB:@^v^v*)}
4 |
--------------------------------------------------------------------------------
/UnitTests.old/shud09-out.txt:
--------------------------------------------------------------------------------
1 | typedef struct {
2 | int type;
3 | union {
4 | char charValue;
5 | short shortValue;
6 | long longValue;
7 | long long longlongValue;
8 | float floatValue;
9 | double doubleValue;
10 | _Bool boolValue;
11 | SEL selectorValue;
12 | id objectValue;
13 | void *pointerValue;
14 | void *structLocation;
15 | char *cStringLocation;
16 | } value;
17 | } CDAnonymousStruct1;
18 |
19 | CDAnonymousStruct1 var;
20 | CDAnonymousStruct1 var;
21 |
--------------------------------------------------------------------------------
/UnitTests.old/shud10-in.txt:
--------------------------------------------------------------------------------
1 | {?="field1"i"field2"i}
2 | {?=ii}
3 |
--------------------------------------------------------------------------------
/UnitTests.old/shud10-out.txt:
--------------------------------------------------------------------------------
1 | typedef struct {
2 | int field1;
3 | int field2;
4 | } CDAnonymousStruct1;
5 |
6 | CDAnonymousStruct1 var;
7 | CDAnonymousStruct1 var;
8 |
--------------------------------------------------------------------------------
/UnitTests.old/shud11-in.txt:
--------------------------------------------------------------------------------
1 | {?="field1"i"field2"i}
2 | {?=ii}
3 | {?="bar1"i"bar2"i}
4 |
--------------------------------------------------------------------------------
/UnitTests.old/shud11-out.txt:
--------------------------------------------------------------------------------
1 | struct {
2 | int field1;
3 | int field2;
4 | } var;
5 | struct {
6 | int;
7 | int;
8 | } var;
9 | struct {
10 | int bar1;
11 | int bar2;
12 | } var;
13 |
--------------------------------------------------------------------------------
/UnitTests.old/shud13-in.txt:
--------------------------------------------------------------------------------
1 | {NSBrowserAuxiliary="_field1"@"NSMutableArray""_field2"@"_NSBrowserScrollView""_field3"@"NSClipView""_field4"@"_NSBrowserColumnScrollHelper""_field5"i"_field6"i"_field7"@"NSMatrix""_field8"@"NSEvent""_field9"f"_field10"@"NSMutableArray""_field11"i"_field12"i"_field13"@"NSString""_field14"{__BrFlags2="delegateShouldSizeColumnToWidth"b1"delegateSizeToFitWidtOfColumn"b1"shouldAnimateColumnScrolling"b1"tilingDisabled"b1"setPathOptimizationOn"b1"readingSavedColumns"b1"recomputeExistingColumnPositions"b1"waitingToSendDoubleActionAtEndOfScroll"b1"waitingToSendSingleActionAtEndOfScroll"b1"waitingToSendConfigChangeNotificationAtEndOfScroll"b1"compatContinuousScrollingCapable"b1"compatContinuousScrollingCapableSet"b1"forceSynchronizedScrollingAnimation"b1"useCustomBorderType"b1"customBorderType"b3"animateColumnScrollingForAnyEvent"b1"reserved"b14}}
2 |
--------------------------------------------------------------------------------
/UnitTests.old/shud13-out.txt:
--------------------------------------------------------------------------------
1 | struct NSBrowserAuxiliary {
2 | NSMutableArray *_field1;
3 | _NSBrowserScrollView *_field2;
4 | NSClipView *_field3;
5 | _NSBrowserColumnScrollHelper *_field4;
6 | int _field5;
7 | int _field6;
8 | NSMatrix *_field7;
9 | NSEvent *_field8;
10 | float _field9;
11 | NSMutableArray *_field10;
12 | int _field11;
13 | int _field12;
14 | NSString *_field13;
15 | struct __BrFlags2 _field14;
16 | };
17 |
18 | struct __BrFlags2 {
19 | unsigned int delegateShouldSizeColumnToWidth:1;
20 | unsigned int delegateSizeToFitWidtOfColumn:1;
21 | unsigned int shouldAnimateColumnScrolling:1;
22 | unsigned int tilingDisabled:1;
23 | unsigned int setPathOptimizationOn:1;
24 | unsigned int readingSavedColumns:1;
25 | unsigned int recomputeExistingColumnPositions:1;
26 | unsigned int waitingToSendDoubleActionAtEndOfScroll:1;
27 | unsigned int waitingToSendSingleActionAtEndOfScroll:1;
28 | unsigned int waitingToSendConfigChangeNotificationAtEndOfScroll:1;
29 | unsigned int compatContinuousScrollingCapable:1;
30 | unsigned int compatContinuousScrollingCapableSet:1;
31 | unsigned int forceSynchronizedScrollingAnimation:1;
32 | unsigned int useCustomBorderType:1;
33 | unsigned int customBorderType:3;
34 | unsigned int animateColumnScrollingForAnyEvent:1;
35 | unsigned int reserved:14;
36 | };
37 |
38 | struct NSBrowserAuxiliary var;
39 |
--------------------------------------------------------------------------------
/UnitTests.old/shud14-in.txt:
--------------------------------------------------------------------------------
1 | // This is a type from iPhoto 5 that caused problems.
2 | ^{IPAlbumList=^^?{vector >={?={?=^@^@^@}}}{_opaque_pthread_mutex_t=l[40c]}}
3 |
--------------------------------------------------------------------------------
/UnitTests.old/shud14-out.txt:
--------------------------------------------------------------------------------
1 | struct IPAlbumList {
2 | void **;
3 | struct vector>;
4 | struct _opaque_pthread_mutex_t;
5 | };
6 |
7 | struct _opaque_pthread_mutex_t {
8 | long;
9 | char [40];
10 | };
11 |
12 | struct vector> {
13 | struct {
14 | struct {
15 | id *;
16 | id *;
17 | id *;
18 | };
19 | };
20 | };
21 |
22 | struct IPAlbumList *var;
23 |
--------------------------------------------------------------------------------
/UnitTests.old/shud15-in.txt:
--------------------------------------------------------------------------------
1 | {my_struct1="field1"@"NSObject"}
2 | {my_struct2="field1"@"NSObject""field2"@}
3 | {my_struct3="field1"@"field2"@}
4 | {my_struct4=@"NSObject"}
5 | {my_struct5=@"NSObject"@"NSObject"}
6 |
--------------------------------------------------------------------------------
/UnitTests.old/shud15-out.txt:
--------------------------------------------------------------------------------
1 | struct my_struct1 {
2 | NSObject *field1;
3 | };
4 |
5 | struct my_struct2 {
6 | NSObject *field1;
7 | id field2;
8 | };
9 |
10 | struct my_struct3 {
11 | id field1;
12 | id field2;
13 | };
14 |
15 | struct my_struct4 {
16 | NSObject *;
17 | };
18 |
19 | struct my_struct5 {
20 | NSObject *;
21 | NSObject *;
22 | };
23 |
24 | struct my_struct1 var;
25 | struct my_struct2 var;
26 | struct my_struct3 var;
27 | struct my_struct4 var;
28 | struct my_struct5 var;
29 |
--------------------------------------------------------------------------------
/UnitTests.old/shud16-in.txt:
--------------------------------------------------------------------------------
1 | // TextMate 1.5.4 has structures like... "storage""stack"{etc} -- two quoted strings next to each other.
2 | // It looks like this is a problem with the name rather than a problem with missing types -- when I compared
3 | // it to a case that didn't have names the types matched up perfectly.
4 | {my_struct1="storage""stack"i}
5 |
--------------------------------------------------------------------------------
/UnitTests.old/shud16-out.txt:
--------------------------------------------------------------------------------
1 | struct my_struct1 {
2 | int storage__stack;
3 | };
4 |
5 | struct my_struct1 var;
6 |
--------------------------------------------------------------------------------
/UnitTests.old/var-001.txt:
--------------------------------------------------------------------------------
1 | // Test a pointer to no type in a structure.
2 | // This is an excerpt from the _topSitesViewController ivar of BrowserWebView in Safari 4.0 on Mac OS X 10.5.
3 |
4 | var1
5 | {?="__pfn"^"__delta"i}
6 |
7 | // Similar to the case above, but what happens if it occurs as the last member of the structure?
8 |
9 | var2
10 | {?="__pfn"^}
11 |
12 | // Combination of the first two cases. Order reversed from first case.
13 |
14 | var3
15 | {?="__delta"i"__pfn"^}
16 |
17 | // Same as the three tests above, but for unions.
18 |
19 | var4
20 | (?="__pfn"^"__delta"i)
21 |
22 | var5
23 | (?="__pfn"^)
24 |
25 | var6
26 | (?="__delta"i"__pfn"^)
27 |
28 |
--------------------------------------------------------------------------------
/UnitTests.old/var-002.txt:
--------------------------------------------------------------------------------
1 | // This is an excerpt from the _topSitesViewController ivar of BrowserWebView in Safari 4.0 on Mac OS X 10.5.
2 |
3 | var1
4 | {STimer="_vptr$STimerBase"^^?"m_ID"I"m_isRepeating"B"m_object"^{TopSitesViewController}"m_function"{?="__pfn"^"__delta"i}}
5 |
--------------------------------------------------------------------------------
/UnitTests.old/var-003.txt:
--------------------------------------------------------------------------------
1 | // This is the full definition of the _topSitesViewController ivar of BrowserWebView in Safari 4.0 on Mac OS X 10.5.
2 |
3 | _topSitesViewController
4 | ^{TopSitesViewController=^^?@"BrowserWebView"i^{TopSitesViewLayer}BII{SNotifier="_vptr$SNotificationObserver"^^?"m_notifiedObject"^{TopSitesViewController}"m_notifications"{HashMap,std::mem_fun1_t,WTF::PairHash,WTF::HashTraits >,WTF::HashTraits > >="m_impl"{HashTable,std::pair, std::mem_fun1_t >,WTF::PairFirstExtractor, std::mem_fun1_t > >,WTF::PairHash,WTF::PairHashTraits >, WTF::HashTraits > >,WTF::HashTraits > >="m_table"^{pair,std::mem_fun1_t >}"m_tableSize"i"m_tableSizeMask"i"m_keyCount"i"m_deletedCount"i}}}{STimer="_vptr$STimerBase"^^?"m_ID"I"m_isRepeating"B"m_object"^{TopSitesViewController}"m_function"{?="__pfn"^"__delta"i}}BBB{STimer="_vptr$STimerBase"^^?"m_ID"I"m_isRepeating"B"m_object"^{TopSitesViewController}"m_function"{?="__pfn"^"__delta"i}}{RefPtr="m_ptr"^{TopSite}}BB{STimer="_vptr$STimerBase"^^?"m_ID"I"m_isRepeating"B"m_object"^{TopSitesViewController}"m_function"{?="__pfn"^"__delta"i}}d{SString="m_cfObject"{RetainPtr="m_ptr"^{__CFString}}}BII{RetainPtr="m_ptr"^{CGImage}}}
5 |
--------------------------------------------------------------------------------
/UnitTests.old/var-004.txt:
--------------------------------------------------------------------------------
1 | var 1
2 | {RetainPtr=^{__CFString}}
3 |
4 | var
5 | {My::List}
6 |
7 | var
8 | {My::List}
9 |
10 | var
11 | {My::List}
12 |
13 | var
14 | {My::List*,int>}
15 |
16 | // If it's still in the template mode, it adds any identifier after the > to the suffix;
17 |
18 | var
19 | {My::List*bob,int>}
20 |
21 | // And this should fail:
22 | var
23 | {My::List*}
24 |
25 | // Should this work or not?
26 | var
27 | {^My::List}
28 |
29 |
--------------------------------------------------------------------------------
/UnitTests.old/var-005.txt:
--------------------------------------------------------------------------------
1 | // From Safari 4.0.2 on Mac OS X 10.5:
2 |
3 | var
4 | {pair, 0ul>*>}
5 |
--------------------------------------------------------------------------------
/UnitTests/TestBlockSignature.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDType.h"
9 | #import "CDTypeName.h"
10 |
11 | @interface CDType (UnitTests)
12 | - (NSString *)blockSignatureString;
13 | @end
14 |
15 | @interface TestBlockSignature : XCTestCase
16 | @end
17 |
18 | @implementation TestBlockSignature
19 |
20 | - (void)testZeroArguments;
21 | {
22 | NSMutableArray *types = [NSMutableArray new];
23 | [types addObject:[[CDType alloc] initSimpleType:'v']];
24 | [types addObject:[[CDType alloc] initBlockTypeWithTypes:nil]];
25 | CDType *blockType = [[CDType alloc] initBlockTypeWithTypes:types];
26 | NSString *blockSignatureString = [blockType blockSignatureString];
27 | XCTAssertEqualObjects(blockSignatureString, @"void (^)(void)", @"");
28 | }
29 |
30 | - (void)testOneArgument;
31 | {
32 | NSMutableArray *types = [NSMutableArray new];
33 | [types addObject:[[CDType alloc] initSimpleType:'v']];
34 | [types addObject:[[CDType alloc] initBlockTypeWithTypes:nil]];
35 | CDTypeName *typeName = [CDTypeName new];
36 | typeName.name = @"NSData";
37 | [types addObject:[[CDType alloc] initIDType:typeName]];
38 | CDType *blockType = [[CDType alloc] initBlockTypeWithTypes:types];
39 | NSString *blockSignatureString = [blockType blockSignatureString];
40 | XCTAssertEqualObjects(blockSignatureString, @"void (^)(NSData *)", @"");
41 | }
42 |
43 | - (void)testTwoArguments;
44 | {
45 | NSMutableArray *types = [NSMutableArray new];
46 | [types addObject:[[CDType alloc] initSimpleType:'v']];
47 | [types addObject:[[CDType alloc] initBlockTypeWithTypes:nil]];
48 | [types addObject:[[CDType alloc] initIDType:nil]];
49 | CDTypeName *typeName = [CDTypeName new];
50 | typeName.name = @"NSError";
51 | [types addObject:[[CDType alloc] initIDType:typeName]];
52 | CDType *blockType = [[CDType alloc] initBlockTypeWithTypes:types];
53 | NSString *blockSignatureString = [blockType blockSignatureString];
54 | XCTAssertEqualObjects(blockSignatureString, @"void (^)(id, NSError *)", @"");
55 | }
56 |
57 | - (void)testBlockArgument;
58 | {
59 | NSMutableArray *types = [NSMutableArray new];
60 | [types addObject:[[CDType alloc] initSimpleType:'v']];
61 | [types addObject:[[CDType alloc] initBlockTypeWithTypes:nil]];
62 | [types addObject:[[CDType alloc] initBlockTypeWithTypes:[types copy]]];
63 | CDType *blockType = [[CDType alloc] initBlockTypeWithTypes:types];
64 | NSString *blockSignatureString = [blockType blockSignatureString];
65 | XCTAssertEqualObjects(blockSignatureString, @"void (^)(void (^)(void))", @"");
66 | }
67 |
68 | - (void)testBOOLArgument;
69 | {
70 | NSMutableArray *types = [NSMutableArray new];
71 | [types addObject:[[CDType alloc] initSimpleType:'v']];
72 | [types addObject:[[CDType alloc] initBlockTypeWithTypes:nil]];
73 | [types addObject:[[CDType alloc] initSimpleType:'c']];
74 | CDType *blockType = [[CDType alloc] initBlockTypeWithTypes:types];
75 | NSString *blockSignatureString = [blockType blockSignatureString];
76 | XCTAssertEqualObjects(blockSignatureString, @"void (^)(BOOL)", @"");
77 | }
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/UnitTests/TestCDArchFromName.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFile.h"
9 |
10 | @interface TestCDArchFromName : XCTestCase
11 | @end
12 |
13 | @implementation TestCDArchFromName
14 |
15 | - (void)setUp;
16 | {
17 | [super setUp];
18 |
19 | // Set-up code here.
20 | }
21 |
22 | - (void)tearDown;
23 | {
24 | // Tear-down code here.
25 |
26 | [super tearDown];
27 | }
28 |
29 | #pragma mark - ARM
30 |
31 | - (void)test_armv6;
32 | {
33 | CDArch arch = CDArchFromName(@"armv6");
34 | XCTAssertEqual(arch.cputype, CPU_TYPE_ARM, @"The cputype for 'armv6' should be ARM");
35 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_ARM_V6, @"The cpusubtype for 'armv6' should be ARM_V6");
36 | }
37 |
38 | - (void)test_armv7;
39 | {
40 | CDArch arch = CDArchFromName(@"armv7");
41 | XCTAssertEqual(arch.cputype, CPU_TYPE_ARM, @"The cputype for 'armv7' should be ARM");
42 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_ARM_V7, @"The cpusubtype for 'armv7' should be ARM_V7");
43 | }
44 |
45 | - (void)test_armv7s;
46 | {
47 | CDArch arch = CDArchFromName(@"armv7s");
48 | XCTAssertEqual(arch.cputype, CPU_TYPE_ARM, @"The cputype for 'armv7s' should be ARM");
49 | XCTAssertEqual(arch.cpusubtype, 11, @"The cpusubtype for 'armv7s' should be 11");
50 | }
51 |
52 | - (void)test_arm64;
53 | {
54 | CDArch arch = CDArchFromName(@"arm64");
55 | XCTAssertEqual(arch.cputype, CPU_TYPE_ARM | CPU_ARCH_ABI64, @"The cputype for 'arm64' should be ARM with 64-bit mask");
56 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_ARM_ALL, @"The cpusubtype for 'arm64' should be CPU_SUBTYPE_ARM_ALL");
57 | }
58 |
59 | #pragma mark - Intel x86
60 |
61 | - (void)test_i386;
62 | {
63 | CDArch arch = CDArchFromName(@"i386");
64 | XCTAssertEqual(arch.cputype, CPU_TYPE_X86, @"The cputype for 'i386' should be X86");
65 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_386, @"The cpusubtype for 'i386' should be 386");
66 | }
67 |
68 | - (void)test_x86_64;
69 | {
70 | CDArch arch = CDArchFromName(@"x86_64");
71 | XCTAssertEqual(arch.cputype, CPU_TYPE_X86_64, @"The cputype for 'x86_64' should be X86_64");
72 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_386, @"The cpusubtype for 'x86_64' should be 386");
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/UnitTests/TestCDArchUses64BitABI.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFile.h"
9 |
10 | @interface TestCDArchUses64BitABI : XCTestCase
11 | @end
12 |
13 | @implementation TestCDArchUses64BitABI
14 |
15 | - (void)setUp;
16 | {
17 | [super setUp];
18 |
19 | // Set-up code here.
20 | }
21 |
22 | - (void)tearDown;
23 | {
24 | // Tear-down code here.
25 |
26 | [super tearDown];
27 | }
28 |
29 | #pragma mark - Intel x86
30 |
31 | - (void)test_i386;
32 | {
33 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
34 | XCTAssertFalse(CDArchUses64BitABI(arch), @"i386 does not use 64 bit ABI");
35 | }
36 |
37 | - (void)test_x86_64;
38 | {
39 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
40 | XCTAssertTrue(CDArchUses64BitABI(arch), @"x86_64 uses 64 bit ABI");
41 | }
42 |
43 | - (void)test_x86_64_lib64;
44 | {
45 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64 };
46 | XCTAssertTrue(CDArchUses64BitABI(arch), @"x86_64 (with LIB64 capability bit) uses 64 bit ABI");
47 | }
48 |
49 | - (void)test_x86_64_plusOtherCapablity
50 | {
51 | CDArch arch = { CPU_TYPE_X86_64 | 0x40000000, CPU_SUBTYPE_386 };
52 | XCTAssertTrue(CDArchUses64BitABI(arch), @"x86_64 (with other capability bit) uses 64 bit ABI");
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/UnitTests/TestCDNameForCPUType.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFile.h"
9 |
10 | @interface TestCDNameForCPUType : XCTestCase
11 | @end
12 |
13 | @implementation TestCDNameForCPUType
14 |
15 | - (void)setUp;
16 | {
17 | [super setUp];
18 |
19 | // Set-up code here.
20 | }
21 |
22 | - (void)tearDown;
23 | {
24 | // Tear-down code here.
25 |
26 | [super tearDown];
27 | }
28 |
29 | #pragma mark - ARM
30 |
31 | - (void)test_armv6;
32 | {
33 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6), @"armv6", @"The name for ARM subtype CPU_SUBTYPE_ARM_V6 should be 'armv6'");
34 | }
35 |
36 | - (void)test_armv7;
37 | {
38 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7), @"armv7", @"The name for ARM subtype CPU_SUBTYPE_ARM_V7 should be 'armv7'");
39 | }
40 |
41 | - (void)test_armv7s;
42 | {
43 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_ARM, 11), @"armv7s", @"The name for ARM subtype 11 should be 'armv7s'");
44 | }
45 |
46 | - (void)test_arm64;
47 | {
48 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_ARM | CPU_ARCH_ABI64, CPU_SUBTYPE_ARM_ALL), @"arm64", @"The name for ARM 64-bit subtype CPU_SUBTYPE_ARM_ALL should be 'arm64'");
49 | }
50 |
51 | #pragma mark - Intel x86
52 |
53 | - (void)test_i386;
54 | {
55 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_X86, CPU_SUBTYPE_386), @"i386", @"The name for X86 subtype CPU_SUBTYPE_386 should be 'i386'");
56 | }
57 |
58 | - (void)test_x86_64;
59 | {
60 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_X86_64, CPU_SUBTYPE_386), @"x86_64", @"The name for X86_64 subtype CPU_SUBTYPE_386 should be 'x86_64'");
61 | }
62 |
63 | - (void)test_x86_64_lib64;
64 | {
65 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_X86_64, CPU_SUBTYPE_386|CPU_SUBTYPE_LIB64), @"x86_64", @"The name for X86_64 subtype CPU_SUBTYPE_386 with capability bits should be 'x86_64'");
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/UnitTests/TestFatFile_Intel32_64.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFatArch.h"
9 | #import "CDFatFile.h"
10 | #import "CDMachOFile.h"
11 |
12 | @interface TestFatFile_Intel32_64 : XCTestCase
13 | @end
14 |
15 | @implementation TestFatFile_Intel32_64
16 | {
17 | CDFatFile *_fatFile;
18 | CDFatArch *_arch_i386;
19 | CDFatArch *_arch_x86_64;
20 | CDMachOFile *_macho_i386;
21 | CDMachOFile *_macho_x86_64;
22 | }
23 |
24 | - (void)setUp;
25 | {
26 | [super setUp];
27 |
28 | // Set-up code here.
29 | _fatFile = [[CDFatFile alloc] init];
30 |
31 | _macho_i386 = [[CDMachOFile alloc] init];
32 | _macho_i386.cputype = CPU_TYPE_X86;
33 | _macho_i386.cpusubtype = CPU_SUBTYPE_386;
34 |
35 | _arch_i386 = [[CDFatArch alloc] initWithMachOFile:_macho_i386];
36 | [_fatFile addArchitecture:_arch_i386];
37 |
38 | _macho_x86_64 = [[CDMachOFile alloc] init];
39 | _macho_x86_64.cputype = CPU_TYPE_X86_64;
40 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386;
41 |
42 | _arch_x86_64 = [[CDFatArch alloc] initWithMachOFile:_macho_x86_64];
43 | [_fatFile addArchitecture:_arch_x86_64];
44 | }
45 |
46 | - (void)tearDown;
47 | {
48 | // Tear-down code here.
49 | _fatFile = nil;
50 | _arch_i386 = nil;
51 | _arch_x86_64 = nil;
52 | _macho_i386 = nil;
53 | _macho_x86_64 = nil;
54 |
55 | [super tearDown];
56 | }
57 |
58 | #pragma mark -
59 |
60 | - (void)test_bestMatchIntel64;
61 | {
62 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
63 |
64 | BOOL result = [_fatFile bestMatchForArch:&arch];
65 | XCTAssertTrue(result, @"Didn't find a best match for x86_64");
66 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64");
67 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386");
68 | }
69 |
70 | #if 0
71 | // We don't build 32-bit any more, so this test case shouldn't come up.
72 | - (void)test_bestMatchIntel32;
73 | {
74 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
75 |
76 | BOOL result = [_intel_32_64 bestMatchForArch:&arch];
77 | XCTAssertTrue(result, @"Didn't find a best match for i386");
78 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86, @"Best match cputype should be CPU_TYPE_X86");
79 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386");
80 | }
81 | #endif
82 |
83 | - (void)test_machOFileWithArch_x86_64;
84 | {
85 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
86 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch];
87 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL);
88 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file");
89 | }
90 |
91 | - (void)test_machOFileWithArch_i386;
92 | {
93 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
94 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch];
95 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil");
96 | XCTAssertEqual(machOFile, _macho_i386, @"Didn't find correct Mach-O file");
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/UnitTests/TestFatFile_Intel32_64_lib64.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFatArch.h"
9 | #import "CDFatFile.h"
10 | #import "CDMachOFile.h"
11 |
12 | @interface TestFatFile_Intel32_64_lib64 : XCTestCase
13 | @end
14 |
15 | @implementation TestFatFile_Intel32_64_lib64
16 | {
17 | CDFatFile *_fatFile;
18 | CDFatArch *_arch_i386;
19 | CDFatArch *_arch_x86_64;
20 | CDMachOFile *_macho_i386;
21 | CDMachOFile *_macho_x86_64;
22 | }
23 |
24 | - (void)setUp;
25 | {
26 | [super setUp];
27 |
28 | // Set-up code here.
29 | _fatFile = [[CDFatFile alloc] init];
30 |
31 | _macho_i386 = [[CDMachOFile alloc] init];
32 | _macho_i386.cputype = CPU_TYPE_X86;
33 | _macho_i386.cpusubtype = CPU_SUBTYPE_386;
34 |
35 | _arch_i386 = [[CDFatArch alloc] initWithMachOFile:_macho_i386];
36 | [_fatFile addArchitecture:_arch_i386];
37 |
38 | _macho_x86_64 = [[CDMachOFile alloc] init];
39 | _macho_x86_64.cputype = CPU_TYPE_X86_64;
40 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64;
41 |
42 | _arch_x86_64 = [[CDFatArch alloc] initWithMachOFile:_macho_x86_64];
43 | [_fatFile addArchitecture:_arch_x86_64];
44 | }
45 |
46 | - (void)tearDown;
47 | {
48 | // Tear-down code here.
49 | _fatFile = nil;
50 | _arch_i386 = nil;
51 | _arch_x86_64 = nil;
52 | _macho_i386 = nil;
53 | _macho_x86_64 = nil;
54 |
55 | [super tearDown];
56 | }
57 |
58 | #pragma mark -
59 |
60 | - (void)test_bestMatchIntel64;
61 | {
62 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
63 |
64 | BOOL result = [_fatFile bestMatchForArch:&arch];
65 | XCTAssertTrue(result, @"Didn't find a best match for x86_64");
66 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64");
67 | XCTAssertTrue(arch.cpusubtype == (cpu_subtype_t)(CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64), @"Best match cpusubtype should be CPU_SUBTYPE_386");
68 | }
69 |
70 | #if 0
71 | // We don't build 32-bit any more, so this test case shouldn't come up.
72 | - (void)test_bestMatchIntel32;
73 | {
74 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
75 |
76 | BOOL result = [_intel_32_64 bestMatchForArch:&arch];
77 | XCTAssertTrue(result, @"Didn't find a best match for i386");
78 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86, @"Best match cputype should be CPU_TYPE_X86");
79 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386");
80 | }
81 | #endif
82 |
83 | - (void)test_machOFileWithArch_x86_64;
84 | {
85 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
86 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch];
87 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL);
88 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file");
89 | }
90 |
91 | - (void)test_machOFileWithArch_i386;
92 | {
93 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
94 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch];
95 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil");
96 | XCTAssertEqual(machOFile, _macho_i386, @"Didn't find correct Mach-O file");
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/UnitTests/TestFatFile_Intel64_32.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFatArch.h"
9 | #import "CDFatFile.h"
10 | #import "CDMachOFile.h"
11 |
12 | @interface TestFatFile_Intel64_32 : XCTestCase
13 | @end
14 |
15 | @implementation TestFatFile_Intel64_32
16 | {
17 | CDFatFile *_fatFile;
18 | CDFatArch *_arch_i386;
19 | CDFatArch *_arch_x86_64;
20 | CDMachOFile *_macho_i386;
21 | CDMachOFile *_macho_x86_64;
22 | }
23 |
24 | - (void)setUp;
25 | {
26 | [super setUp];
27 |
28 | // Set-up code here.
29 | _fatFile = [[CDFatFile alloc] init];
30 |
31 | _macho_x86_64 = [[CDMachOFile alloc] init];
32 | _macho_x86_64.cputype = CPU_TYPE_X86_64;
33 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386;
34 |
35 | _arch_x86_64 = [[CDFatArch alloc] initWithMachOFile:_macho_x86_64];
36 | [_fatFile addArchitecture:_arch_x86_64];
37 |
38 | _macho_i386 = [[CDMachOFile alloc] init];
39 | _macho_i386.cputype = CPU_TYPE_X86;
40 | _macho_i386.cpusubtype = CPU_SUBTYPE_386;
41 |
42 | _arch_i386 = [[CDFatArch alloc] initWithMachOFile:_macho_i386];
43 | [_fatFile addArchitecture:_arch_i386];
44 | }
45 |
46 | - (void)tearDown;
47 | {
48 | // Tear-down code here.
49 | _fatFile = nil;
50 | _arch_i386 = nil;
51 | _arch_x86_64 = nil;
52 | _macho_i386 = nil;
53 | _macho_x86_64 = nil;
54 |
55 | [super tearDown];
56 | }
57 |
58 | #pragma mark -
59 |
60 | - (void)test_bestMatchIntel64;
61 | {
62 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
63 |
64 | BOOL result = [_fatFile bestMatchForArch:&arch];
65 | XCTAssertTrue(result, @"Didn't find a best match for x86_64");
66 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64");
67 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386");
68 | }
69 |
70 | #if 0
71 | // We don't build 32-bit any more, so this test case shouldn't come up.
72 | - (void)test_bestMatchIntel32;
73 | {
74 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
75 |
76 | BOOL result = [_intel_64_32 bestMatchForArch:&arch];
77 | XCTAssertTrue(result, @"Didn't find a best match for i386");
78 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86, @"Best match cputype should be CPU_TYPE_X86");
79 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386");
80 | }
81 | #endif
82 |
83 | - (void)test_machOFileWithArch_x86_64;
84 | {
85 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
86 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch];
87 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL);
88 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file", NULL);
89 | }
90 |
91 | - (void)test_machOFileWithArch_i386;
92 | {
93 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
94 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch];
95 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL);
96 | XCTAssertEqual(machOFile, _macho_i386, @"Didn't find correct Mach-O file");
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/UnitTests/TestFatFile_armv7_v7s.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFatArch.h"
9 | #import "CDFatFile.h"
10 | #import "CDMachOFile.h"
11 |
12 | @interface TestFatFile_armv7_v7s : XCTestCase
13 | @end
14 |
15 | @implementation TestFatFile_armv7_v7s
16 | {
17 | CDFatFile *_fatFile;
18 | CDFatArch *_arch_v7;
19 | CDFatArch *_arch_v7s;
20 | CDMachOFile *_macho_v7;
21 | CDMachOFile *_macho_v7s;
22 | }
23 |
24 | - (void)setUp;
25 | {
26 | [super setUp];
27 |
28 | // Set-up code here.
29 | _fatFile = [[CDFatFile alloc] init];
30 |
31 | _macho_v7 = [[CDMachOFile alloc] init];
32 | _macho_v7.cputype = CPU_TYPE_ARM;
33 | _macho_v7.cpusubtype = CPU_SUBTYPE_ARM_V7;
34 |
35 | _arch_v7 = [[CDFatArch alloc] initWithMachOFile:_macho_v7];
36 | [_fatFile addArchitecture:_arch_v7];
37 |
38 | _macho_v7s = [[CDMachOFile alloc] init];
39 | _macho_v7s.cputype = CPU_TYPE_ARM;
40 | _macho_v7s.cpusubtype = 11;
41 |
42 | _arch_v7s = [[CDFatArch alloc] initWithMachOFile:_macho_v7s];
43 | [_fatFile addArchitecture:_arch_v7s];
44 | }
45 |
46 | - (void)tearDown;
47 | {
48 | // Tear-down code here.
49 | _fatFile = nil;
50 | _arch_v7 = nil;
51 | _arch_v7s = nil;
52 | _macho_v7 = nil;
53 | _macho_v7s = nil;
54 |
55 | [super tearDown];
56 | }
57 |
58 | #pragma mark -
59 |
60 | - (void)test_machOFileWithArch_armv7;
61 | {
62 | CDArch arch = { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 };
63 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch];
64 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL);
65 | XCTAssertEqual(machOFile, _macho_v7, @"Didn't find correct Mach-O file");
66 | }
67 |
68 | - (void)test_machOFileWithArch_armv7s;
69 | {
70 | CDArch arch = { CPU_TYPE_ARM, 11 };
71 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch];
72 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil");
73 | XCTAssertEqual(machOFile, _macho_v7s, @"Didn't find correct Mach-O file");
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/UnitTests/TestThinFile_Intel64.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFatArch.h"
9 | #import "CDFatFile.h"
10 | #import "CDMachOFile.h"
11 |
12 | @interface TestThinFile_Intel64 : XCTestCase
13 | @end
14 |
15 | @implementation TestThinFile_Intel64
16 | {
17 | CDMachOFile *_macho_x86_64;
18 | }
19 |
20 | - (void)setUp;
21 | {
22 | [super setUp];
23 |
24 | // Set-up code here.
25 | _macho_x86_64 = [[CDMachOFile alloc] init];
26 | _macho_x86_64.cputype = CPU_TYPE_X86_64;
27 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386;
28 | }
29 |
30 | - (void)tearDown;
31 | {
32 | // Tear-down code here.
33 | _macho_x86_64 = nil;
34 |
35 | [super tearDown];
36 | }
37 |
38 | #pragma mark -
39 |
40 | - (void)test_bestMatchIntel64;
41 | {
42 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
43 |
44 | BOOL result = [_macho_x86_64 bestMatchForArch:&arch];
45 | XCTAssertTrue(result, @"Didn't find a best match for x86_64");
46 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64");
47 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386");
48 | }
49 |
50 | - (void)test_machOFileWithArch_x86_64;
51 | {
52 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
53 | CDMachOFile *machOFile = [_macho_x86_64 machOFileWithArch:arch];
54 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL);
55 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file", NULL);
56 | }
57 |
58 | - (void)test_machOFileWithArch_i386;
59 | {
60 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
61 | CDMachOFile *machOFile = [_macho_x86_64 machOFileWithArch:arch];
62 | XCTAssertNil(machOFile, @"The Mach-O file should be nil", NULL);
63 | }
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/UnitTests/TestThinFile_Intel64_lib64.m:
--------------------------------------------------------------------------------
1 | // -*- mode: ObjC -*-
2 |
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.
5 |
6 | #import
7 |
8 | #import "CDFatArch.h"
9 | #import "CDFatFile.h"
10 | #import "CDMachOFile.h"
11 |
12 | @interface TestThinFile_Intel64_lib64 : XCTestCase
13 | @end
14 |
15 | @implementation TestThinFile_Intel64_lib64
16 | {
17 | CDMachOFile *_macho_x86_64;
18 | }
19 |
20 | - (void)setUp;
21 | {
22 | [super setUp];
23 |
24 | // Set-up code here.
25 | _macho_x86_64 = [[CDMachOFile alloc] init];
26 | _macho_x86_64.cputype = CPU_TYPE_X86_64;
27 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64; // For example, /Applications/Utilities/Grab.app on 10.8
28 | }
29 |
30 | - (void)tearDown;
31 | {
32 | // Tear-down code here.
33 | _macho_x86_64 = nil;
34 |
35 | [super tearDown];
36 | }
37 |
38 | #pragma mark -
39 |
40 | - (void)test_bestMatchIntel64;
41 | {
42 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
43 |
44 | BOOL result = [_macho_x86_64 bestMatchForArch:&arch];
45 | XCTAssertTrue(result, @"Didn't find a best match for x86_64");
46 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64");
47 | XCTAssertTrue(arch.cpusubtype == (cpu_subtype_t)(CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64), @"Best match cpusubtype should be CPU_SUBTYPE_386");
48 | }
49 |
50 | - (void)test_machOFileWithArch_x86_64;
51 | {
52 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 };
53 | CDMachOFile *machOFile = [_macho_x86_64 machOFileWithArch:arch];
54 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL);
55 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file", NULL);
56 | }
57 |
58 | - (void)test_machOFileWithArch_i386;
59 | {
60 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 };
61 | CDMachOFile *machOFile = [_macho_x86_64 machOFileWithArch:arch];
62 | XCTAssertNil(machOFile, @"The Mach-O file should be nil", NULL);
63 | }
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/UnitTests/UnitTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/UnitTests/UnitTests-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #ifdef __OBJC__
8 | #import
9 | #endif
10 |
--------------------------------------------------------------------------------
/UnitTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/class-dump-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'class-dump' target in the 'class-dump' project.
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import "CDExtensions.h"
8 | #define __cmd __PRETTY_FUNCTION__
9 | #endif
10 |
--------------------------------------------------------------------------------
/class-dump.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/class-dump.xcodeproj/project.xcworkspace/xcuserdata/nygard.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceUserSettings_BuildLocationStyle
6 | 0
7 | IDEWorkspaceUserSettings_BuildSubfolderNameStyle
8 | 0
9 | IDEWorkspaceUserSettings_DerivedDataLocationStyle
10 | 0
11 | IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
12 |
13 | IDEWorkspaceUserSettings_IssueFilterStyle
14 | 0
15 | IDEWorkspaceUserSettings_LiveSourceIssuesEnabled
16 |
17 | IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges
18 |
19 | IDEWorkspaceUserSettings_SnapshotLocationStyle
20 | 0
21 |
22 |
23 |
--------------------------------------------------------------------------------
/class-dump.xcodeproj/xcuserdata/nygard.xcuserdatad/xcschemes/MachObjC.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
57 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
77 |
78 |
80 |
81 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/class-dump.xcodeproj/xcuserdata/nygard.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MachObjC.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | all.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 | class-dump.xcscheme
18 |
19 | orderHint
20 | 2
21 |
22 | deprotect.xcscheme
23 |
24 | orderHint
25 | 3
26 |
27 | formatType.xcscheme
28 |
29 | orderHint
30 | 4
31 |
32 |
33 | SuppressBuildableAutocreation
34 |
35 | 011E483D1604DF3700722F8D
36 |
37 | primary
38 |
39 |
40 | 012FF1890CDB886C00F31E61
41 |
42 | primary
43 |
44 |
45 | 013182B00CDF6EE400EC5A2C
46 |
47 | primary
48 |
49 |
50 | 013D1EFA13A5A0F100BF0A67
51 |
52 | primary
53 |
54 |
55 | 013D1F1013A5AE5A00BF0A67
56 |
57 | primary
58 |
59 |
60 | 013E8CE814EA0285002BDB6D
61 |
62 | primary
63 |
64 |
65 | 013E8CEE14EA04E0002BDB6D
66 |
67 | primary
68 |
69 |
70 | 01549F710903BF88002FA8F1
71 |
72 | primary
73 |
74 |
75 | 0165B8B01827137D00CC647F
76 |
77 | primary
78 |
79 |
80 | 01A9A4BC0FF19B2F00475772
81 |
82 | primary
83 |
84 |
85 | 01A9A4C40FF19BAE00475772
86 |
87 | primary
88 |
89 |
90 | 01B02CFE13A5B0DC0047BC53
91 |
92 | primary
93 |
94 |
95 | 01B02D2E13A5B5D50047BC53
96 |
97 | primary
98 |
99 |
100 | 01EB825E13A590D9003EDE60
101 |
102 | primary
103 |
104 |
105 | 01F5238E1001D19A0006B272
106 |
107 | primary
108 |
109 |
110 | 01F524FF1001F3E60006B272
111 |
112 | primary
113 |
114 |
115 | 8DD76F960486AA7600D96B5E
116 |
117 | primary
118 |
119 |
120 | DAF6959411E62A4F009AF361
121 |
122 | primary
123 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/deprotect-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'deprotect' target in the 'deprotect' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import "CDExtensions.h"
8 | #endif
9 |
--------------------------------------------------------------------------------
/formatType-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'formatType' target in the 'formatType' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import "CDExtensions.h"
8 | #endif
9 |
--------------------------------------------------------------------------------
/keys.txt:
--------------------------------------------------------------------------------
1 | APPNAME=class-dump
2 | SHORT_DESCRIPTION=a utility for examining the Objective-C segment of Mach-O files
3 | OWNER=Steve Nygard
4 | COPYRIGHT=Copyright (C) 1997-2019 Steve Nygard.
5 |
--------------------------------------------------------------------------------