OLD | NEW |
(Empty) | |
| 1 // -*- mode: ObjC -*- |
| 2 |
| 3 // This file is part of class-dump, a utility for examining the Objective-C seg
ment of Mach-O files. |
| 4 // Copyright (C) 1997-1998, 2000-2001, 2004-2010 Steve Nygard. |
| 5 |
| 6 #import "CDLoadCommand.h" |
| 7 |
| 8 #import "CDLCDyldInfo.h" |
| 9 #import "CDLCDylib.h" |
| 10 #import "CDLCDylinker.h" |
| 11 #import "CDLCDynamicSymbolTable.h" |
| 12 #import "CDLCEncryptionInfo.h" |
| 13 #import "CDLCLinkeditData.h" |
| 14 #import "CDLCPrebindChecksum.h" |
| 15 #import "CDLCPreboundDylib.h" |
| 16 #import "CDLCRoutines32.h" |
| 17 #import "CDLCRoutines64.h" |
| 18 #import "CDLCRunPath.h" |
| 19 #import "CDLCSegment32.h" |
| 20 #import "CDLCSegment64.h" |
| 21 #import "CDLCSubClient.h" |
| 22 #import "CDLCSubFramework.h" |
| 23 #import "CDLCSubLibrary.h" |
| 24 #import "CDLCSubUmbrella.h" |
| 25 #import "CDLCSymbolTable.h" |
| 26 #import "CDLCTwoLevelHints.h" |
| 27 #import "CDLCUnixThread.h" |
| 28 #import "CDLCUUID.h" |
| 29 #import "CDLCUnknown.h" |
| 30 #import "CDMachOFile.h" |
| 31 |
| 32 @implementation CDLoadCommand |
| 33 |
| 34 //+ (id)loadCommandWithPointer:(const void *)ptr machOFile:(CDMachOFile *)aMachO
File; |
| 35 + (id)loadCommandWithDataCursor:(CDDataCursor *)cursor machOFile:(CDMachOFile *)
aMachOFile; |
| 36 { |
| 37 Class targetClass = [CDLCUnknown class]; |
| 38 unsigned int val; |
| 39 |
| 40 val = [cursor peekInt32]; |
| 41 |
| 42 switch (val) { |
| 43 case LC_SEGMENT: targetClass = [CDLCSegment32 class]; break; |
| 44 case LC_SYMTAB: targetClass = [CDLCSymbolTable class]; break
; |
| 45 //case LC_SYMSEG: // obsolete |
| 46 //case LC_THREAD: // not used? |
| 47 case LC_UNIXTHREAD: targetClass = [CDLCUnixThread class]; break; |
| 48 //case LC_LOADFVMLIB: // not used? |
| 49 //case LC_IDFVMLIB: // not used? |
| 50 //case LC_IDENT: // not used? |
| 51 //case LC_FVMFILE: // not used? |
| 52 //case LC_PREPAGE: // not used |
| 53 case LC_DYSYMTAB: targetClass = [CDLCDynamicSymbolTable class]
; break; |
| 54 case LC_LOAD_DYLIB: targetClass = [CDLCDylib class]; break; |
| 55 case LC_ID_DYLIB: targetClass = [CDLCDylib class]; break; |
| 56 case LC_LOAD_DYLINKER: targetClass = [CDLCDylinker class]; break; |
| 57 case LC_ID_DYLINKER: targetClass = [CDLCDylinker class]; break; |
| 58 case LC_PREBOUND_DYLIB: targetClass = [CDLCPreboundDylib class]; bre
ak; |
| 59 case LC_ROUTINES: targetClass = [CDLCRoutines32 class]; break; |
| 60 case LC_SUB_FRAMEWORK: targetClass = [CDLCSubFramework class]; brea
k; |
| 61 //case LC_SUB_UMBRELLA: targetClass = [CDLCSubUmbrella class]; break
; |
| 62 case LC_SUB_CLIENT: targetClass = [CDLCSubClient class]; break; |
| 63 //case LC_SUB_LIBRARY: targetClass = [CDLCSubLibrary class]; break; |
| 64 case LC_TWOLEVEL_HINTS: targetClass = [CDLCTwoLevelHints class]; bre
ak; |
| 65 case LC_PREBIND_CKSUM: targetClass = [CDLCPrebindChecksum class]; b
reak; |
| 66 case LC_LOAD_WEAK_DYLIB: targetClass = [CDLCDylib class]; break; |
| 67 case LC_SEGMENT_64: targetClass = [CDLCSegment64 class]; break; |
| 68 case LC_ROUTINES_64: targetClass = [CDLCRoutines64 class]; break; |
| 69 case LC_UUID: targetClass = [CDLCUUID class]; break; |
| 70 case LC_RPATH: targetClass = [CDLCRunPath class]; break; |
| 71 case LC_CODE_SIGNATURE: targetClass = [CDLCLinkeditData class]; brea
k; |
| 72 case LC_SEGMENT_SPLIT_INFO: targetClass = [CDLCLinkeditData class]; brea
k; |
| 73 case LC_REEXPORT_DYLIB: targetClass = [CDLCDylib class]; break; |
| 74 //case LC_LAZY_LOAD_DYLIB: targetClass = [CDLCDylib class]; break; |
| 75 case LC_ENCRYPTION_INFO: targetClass = [CDLCEncryptionInfo class]; br
eak; |
| 76 case LC_DYLD_INFO: targetClass = [CDLCDyldInfo class]; break; |
| 77 case LC_DYLD_INFO_ONLY: targetClass = [CDLCDyldInfo class]; break; |
| 78 |
| 79 default: |
| 80 NSLog(@"Unknown load command: 0x%08x", val); |
| 81 }; |
| 82 |
| 83 //NSLog(@"targetClass: %@", NSStringFromClass(targetClass)); |
| 84 |
| 85 return [[[targetClass alloc] initWithDataCursor:cursor machOFile:aMachOFile]
autorelease]; |
| 86 } |
| 87 |
| 88 - (id)initWithDataCursor:(CDDataCursor *)cursor machOFile:(CDMachOFile *)aMachOF
ile; |
| 89 { |
| 90 if ([super init] == nil) |
| 91 return nil; |
| 92 |
| 93 nonretained_machOFile = aMachOFile; |
| 94 commandOffset = [cursor offset]; |
| 95 |
| 96 return self; |
| 97 } |
| 98 |
| 99 - (CDMachOFile *)machOFile; |
| 100 { |
| 101 return nonretained_machOFile; |
| 102 } |
| 103 |
| 104 - (NSUInteger)commandOffset; |
| 105 { |
| 106 return commandOffset; |
| 107 } |
| 108 |
| 109 - (uint32_t)cmd; |
| 110 { |
| 111 // Implement in subclasses |
| 112 [NSException raise:NSGenericException format:@"Must implement method in subc
lasses."]; |
| 113 return 0; |
| 114 } |
| 115 |
| 116 - (uint32_t)cmdsize; |
| 117 { |
| 118 // Implement in subclasses |
| 119 [NSException raise:NSGenericException format:@"Must implement method in subc
lasses."]; |
| 120 return 0; |
| 121 } |
| 122 |
| 123 - (NSString *)commandName; |
| 124 { |
| 125 switch ([self cmd]) { |
| 126 case LC_SEGMENT: return @"LC_SEGMENT"; |
| 127 case LC_SYMTAB: return @"LC_SYMTAB"; |
| 128 case LC_SYMSEG: return @"LC_SYMSEG"; |
| 129 case LC_THREAD: return @"LC_THREAD"; |
| 130 case LC_UNIXTHREAD: return @"LC_UNIXTHREAD"; |
| 131 case LC_LOADFVMLIB: return @"LC_LOADFVMLIB"; |
| 132 case LC_IDFVMLIB: return @"LC_IDFVMLIB"; |
| 133 case LC_IDENT: return @"LC_IDENT"; |
| 134 case LC_FVMFILE: return @"LC_FVMFILE"; |
| 135 case LC_PREPAGE: return @"LC_PREPAGE"; |
| 136 case LC_DYSYMTAB: return @"LC_DYSYMTAB"; |
| 137 case LC_LOAD_DYLIB: return @"LC_LOAD_DYLIB"; |
| 138 case LC_ID_DYLIB: return @"LC_ID_DYLIB"; |
| 139 case LC_LOAD_DYLINKER: return @"LC_LOAD_DYLINKER"; |
| 140 case LC_ID_DYLINKER: return @"LC_ID_DYLINKER"; |
| 141 case LC_PREBOUND_DYLIB: return @"LC_PREBOUND_DYLIB"; |
| 142 case LC_ROUTINES: return @"LC_ROUTINES"; |
| 143 case LC_SUB_FRAMEWORK: return @"LC_SUB_FRAMEWORK"; |
| 144 case LC_SUB_UMBRELLA: return @"LC_SUB_UMBRELLA"; |
| 145 case LC_SUB_CLIENT: return @"LC_SUB_CLIENT"; |
| 146 case LC_SUB_LIBRARY: return @"LC_SUB_LIBRARY"; |
| 147 case LC_TWOLEVEL_HINTS: return @"LC_TWOLEVEL_HINTS"; |
| 148 case LC_PREBIND_CKSUM: return @"LC_PREBIND_CKSUM"; |
| 149 |
| 150 case LC_LOAD_WEAK_DYLIB: return @"LC_LOAD_WEAK_DYLIB"; |
| 151 case LC_SEGMENT_64: return @"LC_SEGMENT_64"; |
| 152 case LC_ROUTINES_64: return @"LC_ROUTINES_64"; |
| 153 case LC_UUID: return @"LC_UUID"; |
| 154 case LC_RPATH: return @"LC_RPATH"; |
| 155 case LC_CODE_SIGNATURE: return @"LC_CODE_SIGNATURE"; |
| 156 case LC_SEGMENT_SPLIT_INFO: return @"LC_SEGMENT_SPLIT_INFO"; |
| 157 case LC_REEXPORT_DYLIB: return @"LC_REEXPORT_DYLIB"; |
| 158 case LC_LAZY_LOAD_DYLIB: return @"LC_LAZY_LOAD_DYLIB"; |
| 159 case LC_ENCRYPTION_INFO: return @"LC_ENCRYPTION_INFO"; |
| 160 case LC_DYLD_INFO: return @"LC_DYLD_INFO"; |
| 161 case LC_DYLD_INFO_ONLY: return @"LC_DYLD_INFO_ONLY"; |
| 162 default: |
| 163 break; |
| 164 } |
| 165 |
| 166 return [NSString stringWithFormat:@"0x%08x", [self cmd]]; |
| 167 } |
| 168 |
| 169 - (NSString *)description; |
| 170 { |
| 171 return [NSString stringWithFormat:@"<%@:%p> cmd: 0x%08x (%@), cmdsize: %d //
%@", |
| 172 NSStringFromClass([self class]), self, |
| 173 [self cmd], [self commandName], [self cmdsize], [self extra
Description]]; |
| 174 } |
| 175 |
| 176 - (NSString *)extraDescription; |
| 177 { |
| 178 return @""; |
| 179 } |
| 180 |
| 181 - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose; |
| 182 { |
| 183 [resultString appendFormat:@" cmd %@", [self commandName]]; |
| 184 if ([self mustUnderstandToExecute]) |
| 185 [resultString appendFormat:@" (must understand to execute)"]; |
| 186 [resultString appendFormat:@"\n"]; |
| 187 [resultString appendFormat:@" cmdsize %u\n", [self cmdsize]]; |
| 188 } |
| 189 |
| 190 - (BOOL)mustUnderstandToExecute; |
| 191 { |
| 192 return ([self cmd] & LC_REQ_DYLD) != 0; |
| 193 } |
| 194 |
| 195 @end |
OLD | NEW |