Skip to content

Commit 65ad075

Browse files
committed
Merge pull request nygard#103 from neuralmer/neuralmer/support-small-methods
2 parents 0074e9d + 1161f74 commit 65ad075

5 files changed

+36
-10
lines changed

Source/CDMachOFile.m

+8
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ - (NSString *)stringAtAddress:(NSUInteger)address;
353353
NSLog(@"Warning: Meet Swift object at %s",__cmd);
354354
return @"Swift";
355355
}
356+
357+
// Support small methods referencing selector names in __objc_selrefs.
358+
CDSection *section = [segment sectionContainingAddress:address];
359+
if ([[section sectionName] isEqualToString:@"__objc_selrefs"]) {
360+
const void * reference = [self.data bytes] + offset;
361+
offset = ([self ptrSize] == 8) ? *((uint64_t *)reference) : *((uint32_t *)reference);
362+
}
363+
356364
ptr = (uint8_t *)[self.data bytes] + offset;
357365

358366
return [[NSString alloc] initWithBytes:ptr length:strlen(ptr) encoding:NSUTF8StringEncoding];

Source/CDMachOFileDataCursor.h

+1
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@
2828

2929
// Read using the current byteOrder and ptrSize (from the machOFile)
3030
- (uint64_t)readPtr;
31+
- (uint64_t)readPtr:(bool)small;
3132

3233
@end

Source/CDMachOFileDataCursor.m

+11
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,15 @@ - (uint64_t)readPtr;
110110
return 0;
111111
}
112112

113+
- (uint64_t)readPtr:(bool)small;
114+
{
115+
// "small" pointers are signed 32-bit values
116+
if (small) {
117+
// The pointers are relative to the location in the image, so get the offset before reading the offset:
118+
return [self offset] + [self readInt32];
119+
} else {
120+
return [self readPtr];
121+
}
122+
}
123+
113124
@end

Source/CDObjectiveC2Processor.h

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
#import "CDObjectiveCProcessor.h"
77

8+
#define METHOD_LIST_T_RESERVED_BITS 0x7FFF0003
9+
#define METHOD_LIST_T_SMALL_METHOD_FLAG 0x80000000
10+
#define METHOD_LIST_T_ENTSIZE_MASK (METHOD_LIST_T_RESERVED_BITS|METHOD_LIST_T_SMALL_METHOD_FLAG)
11+
812
@interface CDObjectiveC2Processor : CDObjectiveCProcessor
913

1014
@end

Source/CDObjectiveC2Processor.m

+12-10
Original file line numberDiff line numberDiff line change
@@ -405,17 +405,19 @@ - (NSArray *)loadMethodsAtAddress:(uint64_t)address extendedMethodTypesCursor:(C
405405

406406
struct cd_objc2_list_header listHeader;
407407

408-
// See getEntsize() from http://www.opensource.apple.com/source/objc4/objc4-532.2/runtime/objc-runtime-new.h
409-
listHeader.entsize = [cursor readInt32] & ~(uint32_t)3;
410-
listHeader.count = [cursor readInt32];
411-
NSParameterAssert(listHeader.entsize == 3 * [self.machOFile ptrSize]);
412-
408+
// See https://opensource.apple.com/source/objc4/objc4-787.1/runtime/objc-runtime-new.h
409+
uint32_t value = [cursor readInt32];
410+
listHeader.entsize = value & ~METHOD_LIST_T_ENTSIZE_MASK;
411+
bool small = (value & METHOD_LIST_T_SMALL_METHOD_FLAG) != 0;
412+
listHeader.count = [cursor readInt32];
413+
NSParameterAssert(listHeader.entsize == 3 * (small ? sizeof(int32_t) : [self.machOFile ptrSize]));
414+
413415
for (uint32_t index = 0; index < listHeader.count; index++) {
414416
struct cd_objc2_method objc2Method;
415-
416-
objc2Method.name = [cursor readPtr];
417-
objc2Method.types = [cursor readPtr];
418-
objc2Method.imp = [cursor readPtr];
417+
418+
objc2Method.name = [cursor readPtr:small];
419+
objc2Method.types = [cursor readPtr:small];
420+
objc2Method.imp = [cursor readPtr:small];
419421
NSString *name = [self.machOFile stringAtAddress:objc2Method.name];
420422
NSString *types = [self.machOFile stringAtAddress:objc2Method.types];
421423

@@ -424,7 +426,7 @@ - (NSArray *)loadMethodsAtAddress:(uint64_t)address extendedMethodTypesCursor:(C
424426
types = [self.machOFile stringAtAddress:extendedMethodTypes];
425427
}
426428

427-
//NSLog(@"%3u: %016lx %016lx %016lx", index, objc2Method.name, objc2Method.types, objc2Method.imp);
429+
//NSLog(@"%3u: %016llx %016llx %016llx", index, objc2Method.name, objc2Method.types, objc2Method.imp);
428430
//NSLog(@"name: %@", name);
429431
//NSLog(@"types: %@", types);
430432

0 commit comments

Comments
 (0)