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 "CDSymbol.h" |
| 7 |
| 8 #import <mach-o/nlist.h> |
| 9 #import <mach-o/loader.h> |
| 10 #import "CDMachOFile.h" |
| 11 #import "CDLCDylib.h" |
| 12 #import "CDLCSegment.h" |
| 13 #import "CDSection.h" |
| 14 |
| 15 NSString *const ObjCClassSymbolPrefix = @"_OBJC_CLASS_$_"; |
| 16 |
| 17 @implementation CDSymbol |
| 18 |
| 19 - (id)initWithName:(NSString *)aName machOFile:(CDMachOFile *)aMachOFile nlist32
:(struct nlist)nlist32; |
| 20 { |
| 21 if ([super init] == nil) |
| 22 return nil; |
| 23 |
| 24 is32Bit = YES; |
| 25 name = [aName retain]; |
| 26 nonretained_machOFile = aMachOFile; |
| 27 nlist.n_un.n_strx = 0; // We don't use it. |
| 28 nlist.n_type = nlist32.n_type; |
| 29 nlist.n_sect = nlist32.n_sect; |
| 30 nlist.n_desc = nlist32.n_desc; |
| 31 nlist.n_value = nlist32.n_value; |
| 32 |
| 33 return self; |
| 34 } |
| 35 |
| 36 - (id)initWithName:(NSString *)aName machOFile:(CDMachOFile *)aMachOFile nlist64
:(struct nlist_64)nlist64; |
| 37 { |
| 38 if ([super init] == nil) |
| 39 return nil; |
| 40 |
| 41 is32Bit = NO; |
| 42 name = [aName retain]; |
| 43 nonretained_machOFile = aMachOFile; |
| 44 nlist.n_un.n_strx = 0; // We don't use it. |
| 45 nlist.n_type = nlist64.n_type; |
| 46 nlist.n_sect = nlist64.n_sect; |
| 47 nlist.n_desc = nlist64.n_desc; |
| 48 nlist.n_value = nlist64.n_value; |
| 49 |
| 50 return self; |
| 51 } |
| 52 |
| 53 - (void)dealloc; |
| 54 { |
| 55 [name release]; |
| 56 |
| 57 [super dealloc]; |
| 58 } |
| 59 |
| 60 - (uint64_t)value; |
| 61 { |
| 62 return nlist.n_value; |
| 63 } |
| 64 |
| 65 - (NSString *)name; |
| 66 { |
| 67 return name; |
| 68 } |
| 69 |
| 70 - (CDSection *)section |
| 71 { |
| 72 // We might be tempted to do [[nonretained_machOFile segmentContainingAddres
s:nlist.n_value] sectionContainingAddress:nlist.n_value] |
| 73 // but this does not work for __mh_dylib_header for example (n_value == 0, b
ut it is in the __TEXT,__text section) |
| 74 NSMutableArray *sections = [NSMutableArray array]; |
| 75 for (CDLCSegment *segment in [nonretained_machOFile segments]) { |
| 76 for (CDSection *section in [segment sections]) |
| 77 [sections addObject:section]; |
| 78 } |
| 79 |
| 80 // n_sect is 1-indexed (NO_SECT == 0) |
| 81 NSUInteger sectionIndex = nlist.n_sect - 1; |
| 82 if (sectionIndex < [sections count]) |
| 83 return [sections objectAtIndex:sectionIndex]; |
| 84 else |
| 85 return nil; |
| 86 } |
| 87 |
| 88 - (CDLCDylib *)dylibLoadCommand; |
| 89 { |
| 90 NSUInteger libraryOrdinal = GET_LIBRARY_ORDINAL(nlist.n_desc); |
| 91 NSArray *dylibLoadCommands = [nonretained_machOFile dylibLoadCommands]; |
| 92 |
| 93 if (libraryOrdinal < [dylibLoadCommands count]) |
| 94 return [dylibLoadCommands objectAtIndex:libraryOrdinal]; |
| 95 else |
| 96 return nil; |
| 97 } |
| 98 |
| 99 - (BOOL)isExternal; |
| 100 { |
| 101 return (nlist.n_type & N_EXT) == N_EXT; |
| 102 } |
| 103 |
| 104 - (BOOL)isPrivateExternal; |
| 105 { |
| 106 return (nlist.n_type & N_PEXT) == N_PEXT; |
| 107 } |
| 108 |
| 109 - (NSUInteger)stab; |
| 110 { |
| 111 return nlist.n_type & N_STAB; |
| 112 } |
| 113 |
| 114 - (NSUInteger)type; |
| 115 { |
| 116 return nlist.n_type & N_TYPE; |
| 117 } |
| 118 |
| 119 - (BOOL)isUndefined; |
| 120 { |
| 121 return [self type] == N_UNDF; |
| 122 } |
| 123 |
| 124 - (BOOL)isAbsolte; |
| 125 { |
| 126 return [self type] == N_ABS; |
| 127 } |
| 128 |
| 129 - (BOOL)isInSection; |
| 130 { |
| 131 return [self type] == N_SECT; |
| 132 } |
| 133 |
| 134 - (BOOL)isPrebound; |
| 135 { |
| 136 return [self type] == N_PBUD; |
| 137 } |
| 138 |
| 139 - (BOOL)isIndirect; |
| 140 { |
| 141 return [self type] == N_INDR; |
| 142 } |
| 143 |
| 144 - (BOOL)isCommon; |
| 145 { |
| 146 return [self isUndefined] && [self isExternal] && nlist.n_value != 0; |
| 147 } |
| 148 |
| 149 - (BOOL)isInTextSection; |
| 150 { |
| 151 CDSection *section = [self section]; |
| 152 return [[section segmentName] isEqualToString:@"__TEXT"] && [[section sectio
nName] isEqualToString:@"__text"]; |
| 153 } |
| 154 |
| 155 - (BOOL)isInDataSection; |
| 156 { |
| 157 CDSection *section = [self section]; |
| 158 return [[section segmentName] isEqualToString:@"__DATA"] && [[section sectio
nName] isEqualToString:@"__data"]; |
| 159 } |
| 160 |
| 161 - (BOOL)isInBssSection; |
| 162 { |
| 163 CDSection *section = [self section]; |
| 164 return [[section segmentName] isEqualToString:@"__DATA"] && [[section sectio
nName] isEqualToString:@"__bss"]; |
| 165 } |
| 166 |
| 167 - (NSUInteger)referenceType; |
| 168 { |
| 169 return (nlist.n_desc & REFERENCE_TYPE); |
| 170 } |
| 171 |
| 172 - (NSString *)referenceTypeName |
| 173 { |
| 174 switch ([self referenceType]) { |
| 175 case REFERENCE_FLAG_UNDEFINED_NON_LAZY: return @"undefined non lazy"; |
| 176 case REFERENCE_FLAG_UNDEFINED_LAZY: return @"undefined lazy"; |
| 177 case REFERENCE_FLAG_DEFINED: return @"defined"; |
| 178 case REFERENCE_FLAG_PRIVATE_DEFINED: return @"private defined"; |
| 179 case REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY: return @"private undefined
non lazy"; |
| 180 case REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY: return @"private undefined laz
y"; |
| 181 } |
| 182 return nil; |
| 183 } |
| 184 |
| 185 - (NSComparisonResult)compare:(CDSymbol *)aSymbol; |
| 186 { |
| 187 if ([aSymbol value] > [self value]) |
| 188 return NSOrderedAscending; |
| 189 else if ([aSymbol value] < [self value]) |
| 190 return NSOrderedDescending; |
| 191 else |
| 192 return NSOrderedSame; |
| 193 } |
| 194 |
| 195 - (NSComparisonResult)nameCompare:(CDSymbol *)aSymbol; |
| 196 { |
| 197 return [[self name] compare:[aSymbol name]]; |
| 198 } |
| 199 |
| 200 - (NSString *)shortTypeDescription; |
| 201 { |
| 202 NSString *c = nil; |
| 203 |
| 204 if ([self stab]) |
| 205 c = @"-"; |
| 206 else if ([self isCommon]) |
| 207 c = @"c"; |
| 208 else if ([self isUndefined] || [self isPrebound]) |
| 209 c = @"u"; |
| 210 else if ([self isAbsolte]) |
| 211 c = @"a"; |
| 212 else if ([self isInSection]) { |
| 213 if ([self isInTextSection]) |
| 214 c = @"t"; |
| 215 else if ([self isInDataSection]) |
| 216 c = @"d"; |
| 217 else if ([self isInBssSection]) |
| 218 c = @"b"; |
| 219 else |
| 220 c = @"s"; |
| 221 } |
| 222 else if ([self isIndirect]) |
| 223 c = @"i"; |
| 224 else |
| 225 c = @"?"; |
| 226 |
| 227 return [self isExternal] ? [c uppercaseString] : c; |
| 228 } |
| 229 |
| 230 - (NSString *)longTypeDescription; |
| 231 { |
| 232 NSString *c = nil; |
| 233 |
| 234 if ([self isCommon]) |
| 235 c = @"common"; |
| 236 else if ([self isUndefined]) |
| 237 c = @"undefined"; |
| 238 else if ([self isPrebound]) |
| 239 c = @"prebound"; |
| 240 else if ([self isAbsolte]) |
| 241 c = @"absolute"; |
| 242 else if ([self isInSection]) { |
| 243 CDSection *section = [self section]; |
| 244 if (section) |
| 245 c = [NSString stringWithFormat:@"%@,%@", [section segmentName], [sec
tion sectionName]]; |
| 246 else |
| 247 c = @"?,?"; |
| 248 } |
| 249 else if ([self isIndirect]) |
| 250 c = @"indirect"; |
| 251 else |
| 252 c = @"?"; |
| 253 |
| 254 return c; |
| 255 } |
| 256 |
| 257 - (NSString *)description; |
| 258 { |
| 259 NSString *valueFormat = [NSString stringWithFormat:@"%%0%ullx", is32Bit ? 8
: 16]; |
| 260 NSString *valuePad = is32Bit ? @" " : @" "; |
| 261 NSString *valueString = [self isUndefined] ? valuePad : [NSString stringWith
Format:valueFormat, [self value]]; |
| 262 NSString *dylibName = [[[[[self dylibLoadCommand] path] lastPathComponent] c
omponentsSeparatedByString:@"."] objectAtIndex:0]; |
| 263 NSString *fromString = [self isUndefined] ? [NSString stringWithFormat:@" (f
rom %@)", dylibName] : @""; |
| 264 return [NSString stringWithFormat:@"%@ %@ %@", valueString, [self shortTypeD
escription], name]; |
| 265 return [NSString stringWithFormat:@"%@ (%@) %@ %@%@", valueString, [self lon
gTypeDescription], [self isExternal] ? @"external" : @"non-external", name, from
String]; |
| 266 return [NSString stringWithFormat:[valueFormat stringByAppendingString:@" %0
2x %02x %04x - %@"], |
| 267 nlist.n_value, nlist.n_type, nlist.n_sect, nlist.n_desc, name]; |
| 268 } |
| 269 |
| 270 @end |
OLD | NEW |