@@ -410,17 +410,54 @@ - (NSArray *)loadMethodsAtAddress:(uint64_t)address extendedMethodTypesCursor:(C
410410
411411 struct cd_objc2_list_header listHeader;
412412
413- // See getEntsize() from http://www.opensource.apple.com/source/objc4/objc4-532.2/runtime/objc-runtime-new.h
414- listHeader.entsize = [cursor readInt32 ] & ~(uint32_t )3 ;
415- listHeader.count = [cursor readInt32 ];
416- NSParameterAssert (listHeader.entsize == 3 * [self .machOFile ptrSize ]);
417-
413+ // See https://opensource.apple.com/source/objc4/objc4-787.1/runtime/objc-runtime-new.h
414+ uint32_t mask = 0xFFFF0003 ;
415+ uint32_t value = [cursor readInt32 ];
416+ listHeader.entsize = value & ~mask;
417+ uint32_t flags = value & mask;
418+ int smallMethods = (flags & 0x80000000 ) != 0 ;
419+ /*
420+ Tests show no leftovers were present. Consistent with comments indicating smallMethodListFlag is currently the only flag.
421+ int leftOvers = flags & ~0x80000000;
422+ if (leftOvers != 0) {
423+ NSLog(@"Leftovers was non-zero: 0x%08x (0x%08x)", leftOvers, value);
424+ }
425+ */
426+ listHeader.count = [cursor readInt32 ];
427+ // NSLog(@"Info: %u == %lu?: listHeader.entsize=%u self.machOFile ptrSize=%lu (%d 0x%x)", listHeader.entsize, (3 * [self.machOFile ptrSize]), listHeader.entsize, [self.machOFile ptrSize], listHeader.entsize, listHeader.entsize);
428+ if (smallMethods) {
429+ NSParameterAssert (listHeader.entsize == (3 * sizeof (uint32_t )));
430+ } else {
431+ NSParameterAssert (listHeader.entsize == 3 * [self .machOFile ptrSize ]);
432+ }
418433 for (uint32_t index = 0 ; index < listHeader.count ; index++) {
419434 struct cd_objc2_method objc2Method;
420435
421- objc2Method.name = [cursor readPtr ];
422- objc2Method.types = [cursor readPtr ];
423- objc2Method.imp = [cursor readPtr ];
436+ if (smallMethods) {
437+ // NSLog(@"NEW METHOD!!");
438+ uint64_t offset1 = [cursor offset ];
439+ int value1 = [cursor readInt32 ];
440+ objc2Method.name = (uint64_t )(((int64_t )offset1) + value1);
441+
442+ uint64_t offset2 = [cursor offset ];
443+ int value2 = [cursor readInt32 ];
444+ objc2Method.types = (uint64_t )(((int64_t )offset2) + value2);
445+
446+ uint64_t offset3 = [cursor offset ];
447+ int value3 = [cursor readInt32 ];
448+ objc2Method.imp = (uint64_t )(((int64_t )offset3) + value3);
449+
450+ // NSLog(@"values12f: 0x%016llx 0x%016llx 0x%016llx", objc2Method.name, objc2Method.types, objc2Method.imp);
451+ // NSLog(@"values12: 0x%08x 0x%08x 0x%08x", value1, value2, value3);
452+ } else {
453+ uint64_t value1 = [cursor readPtr ];
454+ uint64_t value2 = [cursor readPtr ];
455+ uint64_t value3 = [cursor readPtr ];
456+ // NSLog(@"values24: 0x%016llx 0x%016llx 0x%016llx", value1, value2, value3);
457+ objc2Method.name = value1;
458+ objc2Method.types = value2;
459+ objc2Method.imp = value3;
460+ }
424461 NSString *name = [self .machOFile stringAtAddress: objc2Method.name];
425462 NSString *types = [self .machOFile stringAtAddress: objc2Method.types];
426463
@@ -448,12 +485,13 @@ - (NSArray *)loadIvarsAtAddress:(uint64_t)address;
448485 if (address != 0 ) {
449486 CDMachOFileDataCursor *cursor = [[CDMachOFileDataCursor alloc ] initWithFile: self .machOFile address: address];
450487 NSParameterAssert ([cursor offset ] != 0 );
451- // NSLog(@"ivar list data offset: %lu", [cursor offset]);
488+ // NSLog(@"ivar list data offset: %lu", [cursor offset]);
452489
453490 struct cd_objc2_list_header listHeader;
454491
455492 listHeader.entsize = [cursor readInt32 ];
456493 listHeader.count = [cursor readInt32 ];
494+ // NSLog(@"Info: %u == %lu?: listHeader.entsize=%u self.machOFile ptrSize=%lu", listHeader.entsize, (3 * [self.machOFile ptrSize] + 2 * sizeof(uint32_t)), listHeader.entsize, [self.machOFile ptrSize]);
457495 NSParameterAssert (listHeader.entsize == 3 * [self .machOFile ptrSize ] + 2 * sizeof (uint32_t ));
458496
459497 for (uint32_t index = 0 ; index < listHeader.count ; index++) {
0 commit comments