Skip to content

Commit 1161f74

Browse files
author
Mike Richter
committed
Support small methods and selector indirection
1 parent 2c82b4f commit 1161f74

File tree

5 files changed

+35
-10
lines changed

5 files changed

+35
-10
lines changed

Source/CDMachOFile.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,13 @@ - (NSString *)stringAtAddress:(NSUInteger)address;
350350
if (offset == 0)
351351
return nil;
352352

353+
// Support small methods referencing selector names in __objc_selrefs.
354+
CDSection *section = [segment sectionContainingAddress:address];
355+
if ([[section sectionName] isEqualToString:@"__objc_selrefs"]) {
356+
const void * reference = [self.data bytes] + offset;
357+
offset = ([self ptrSize] == 8) ? *((uint64_t *)reference) : *((uint32_t *)reference);
358+
}
359+
353360
ptr = (uint8_t *)[self.data bytes] + offset;
354361

355362
return [[NSString alloc] initWithBytes:ptr length:strlen(ptr) encoding:NSASCIIStringEncoding];

Source/CDMachOFileDataCursor.h

Lines changed: 1 addition & 0 deletions
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

Lines changed: 11 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -398,17 +398,19 @@ - (NSArray *)loadMethodsAtAddress:(uint64_t)address extendedMethodTypesCursor:(C
398398

399399
struct cd_objc2_list_header listHeader;
400400

401-
// See getEntsize() from http://www.opensource.apple.com/source/objc4/objc4-532.2/runtime/objc-runtime-new.h
402-
listHeader.entsize = [cursor readInt32] & ~(uint32_t)3;
403-
listHeader.count = [cursor readInt32];
404-
NSParameterAssert(listHeader.entsize == 3 * [self.machOFile ptrSize]);
405-
401+
// See https://opensource.apple.com/source/objc4/objc4-787.1/runtime/objc-runtime-new.h
402+
uint32_t value = [cursor readInt32];
403+
listHeader.entsize = value & ~METHOD_LIST_T_ENTSIZE_MASK;
404+
bool small = (value & METHOD_LIST_T_SMALL_METHOD_FLAG) != 0;
405+
listHeader.count = [cursor readInt32];
406+
NSParameterAssert(listHeader.entsize == 3 * (small ? sizeof(int32_t) : [self.machOFile ptrSize]));
407+
406408
for (uint32_t index = 0; index < listHeader.count; index++) {
407409
struct cd_objc2_method objc2Method;
408-
409-
objc2Method.name = [cursor readPtr];
410-
objc2Method.types = [cursor readPtr];
411-
objc2Method.imp = [cursor readPtr];
410+
411+
objc2Method.name = [cursor readPtr:small];
412+
objc2Method.types = [cursor readPtr:small];
413+
objc2Method.imp = [cursor readPtr:small];
412414
NSString *name = [self.machOFile stringAtAddress:objc2Method.name];
413415
NSString *types = [self.machOFile stringAtAddress:objc2Method.types];
414416

@@ -417,7 +419,7 @@ - (NSArray *)loadMethodsAtAddress:(uint64_t)address extendedMethodTypesCursor:(C
417419
types = [self.machOFile stringAtAddress:extendedMethodTypes];
418420
}
419421

420-
//NSLog(@"%3u: %016lx %016lx %016lx", index, objc2Method.name, objc2Method.types, objc2Method.imp);
422+
//NSLog(@"%3u: %016llx %016llx %016llx", index, objc2Method.name, objc2Method.types, objc2Method.imp);
421423
//NSLog(@"name: %@", name);
422424
//NSLog(@"types: %@", types);
423425

0 commit comments

Comments
 (0)