@@ -3519,12 +3519,6 @@ static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
3519
3519
return nullptr ;
3520
3520
}
3521
3521
3522
- static const char *get_value_32 (uint32_t Address, uint32_t &offset,
3523
- uint32_t &left, SectionRef &S,
3524
- DisassembleInfo *info, bool objc_only = false ) {
3525
- return get_pointer_64 (Address, offset, left, S, info, objc_only);
3526
- }
3527
-
3528
3522
static const char *get_pointer_32 (uint32_t Address, uint32_t &offset,
3529
3523
uint32_t &left, SectionRef &S,
3530
3524
DisassembleInfo *info,
@@ -3667,8 +3661,8 @@ struct class_ro32_t {
3667
3661
#define RO_ROOT (1 << 1 )
3668
3662
#define RO_HAS_CXX_STRUCTORS (1 << 2 )
3669
3663
3670
- /* Values for method_list{64,32,_delta }_t->entsize */
3671
- #define ML_HAS_DELTAS (1 << 31 )
3664
+ /* Values for method_list{64,32}_t->entsize */
3665
+ #define ML_HAS_RELATIVE_PTRS (1 << 31 )
3672
3666
#define ML_ENTSIZE_MASK 0xFFFF
3673
3667
3674
3668
struct method_list64_t {
@@ -3683,12 +3677,6 @@ struct method_list32_t {
3683
3677
/* struct method32_t first; These structures follow inline */
3684
3678
};
3685
3679
3686
- struct method_list_delta_t {
3687
- uint32_t entsize;
3688
- uint32_t count;
3689
- /* struct method_delta_t first; These structures follow inline */
3690
- };
3691
-
3692
3680
struct method64_t {
3693
3681
uint64_t name; /* SEL (64-bit pointer) */
3694
3682
uint64_t types; /* const char * (64-bit pointer) */
@@ -3701,10 +3689,10 @@ struct method32_t {
3701
3689
uint32_t imp; /* IMP (32-bit pointer) */
3702
3690
};
3703
3691
3704
- struct method_delta_t {
3705
- int32_t name; /* SEL (32-bit delta ) */
3706
- int32_t types; /* const char * (32-bit delta ) */
3707
- int32_t imp; /* IMP (32-bit delta ) */
3692
+ struct method_relative_t {
3693
+ int32_t name; /* SEL (32-bit relative ) */
3694
+ int32_t types; /* const char * (32-bit relative ) */
3695
+ int32_t imp; /* IMP (32-bit relative ) */
3708
3696
};
3709
3697
3710
3698
struct protocol_list64_t {
@@ -3996,11 +3984,6 @@ inline void swapStruct(struct method_list32_t &ml) {
3996
3984
sys::swapByteOrder (ml.count );
3997
3985
}
3998
3986
3999
- inline void swapStruct (struct method_list_delta_t &ml) {
4000
- sys::swapByteOrder (ml.entsize );
4001
- sys::swapByteOrder (ml.count );
4002
- }
4003
-
4004
3987
inline void swapStruct (struct method64_t &m) {
4005
3988
sys::swapByteOrder (m.name );
4006
3989
sys::swapByteOrder (m.types );
@@ -4013,7 +3996,7 @@ inline void swapStruct(struct method32_t &m) {
4013
3996
sys::swapByteOrder (m.imp );
4014
3997
}
4015
3998
4016
- inline void swapStruct (struct method_delta_t &m) {
3999
+ inline void swapStruct (struct method_relative_t &m) {
4017
4000
sys::swapByteOrder (m.name );
4018
4001
sys::swapByteOrder (m.types );
4019
4002
sys::swapByteOrder (m.imp );
@@ -4473,74 +4456,63 @@ static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
4473
4456
print_layout_map (layout_map, left);
4474
4457
}
4475
4458
4476
- // Return true if this is a delta method list, false otherwise
4477
- static bool print_method_list_delta_t ( uint64_t p, struct DisassembleInfo *info ,
4478
- const char *indent ,
4479
- uint32_t pointerBits) {
4480
- struct method_list_delta_t ml;
4481
- struct method_delta_t m;
4459
+ static void print_relative_method_list ( uint32_t structSizeAndFlags,
4460
+ uint32_t structCount, uint64_t p ,
4461
+ struct DisassembleInfo *info ,
4462
+ const char *indent,
4463
+ uint32_t pointerBits) {
4464
+ struct method_relative_t m;
4482
4465
const char *r, *name;
4483
4466
uint32_t offset, xoffset, left, i;
4484
4467
SectionRef S, xS;
4485
4468
4486
- r = get_pointer_32 (p, offset, left, S, info);
4487
- if (r == nullptr )
4488
- return false ;
4489
- memset (&ml, ' \0 ' , sizeof (struct method_list_delta_t ));
4490
- if (left < sizeof (struct method_list_delta_t )) {
4491
- memcpy (&ml, r, left);
4492
- outs () << " (method_delta_t extends past the end of the section)\n " ;
4493
- } else
4494
- memcpy (&ml, r, sizeof (struct method_list_delta_t ));
4495
- if (info->O ->isLittleEndian () != sys::IsLittleEndianHost)
4496
- swapStruct (ml);
4497
- if ((ml.entsize & ML_HAS_DELTAS) == 0 )
4498
- return false ;
4469
+ assert (((structSizeAndFlags & ML_HAS_RELATIVE_PTRS) != 0 ) &&
4470
+ " expected structSizeAndFlags to have ML_HAS_RELATIVE_PTRS flag" );
4499
4471
4500
- outs () << indent << " \t\t entsize " << (ml. entsize & ML_ENTSIZE_MASK)
4501
- << " (relative) \n " ;
4502
- outs () << indent << " \t\t count " << ml. count << " \n " ;
4472
+ outs () << indent << " \t\t entsize "
4473
+ << (structSizeAndFlags & ML_ENTSIZE_MASK) << " (relative) \n " ;
4474
+ outs () << indent << " \t\t count " << structCount << " \n " ;
4503
4475
4504
- p += sizeof (struct method_list_delta_t );
4505
- offset += sizeof (struct method_delta_t );
4506
- for (i = 0 ; i < ml.count ; i++) {
4507
- r = get_value_32 (p, offset, left, S, info);
4508
- if (r == nullptr )
4509
- return true ;
4510
- memset (&m, ' \0 ' , sizeof (struct method_delta_t ));
4511
- if (left < sizeof (struct method_delta_t )) {
4476
+ for (i = 0 ; i < structCount; i++) {
4477
+ r = get_pointer_64 (p, offset, left, S, info);
4478
+ memset (&m, ' \0 ' , sizeof (struct method_relative_t ));
4479
+ if (left < sizeof (struct method_relative_t )) {
4512
4480
memcpy (&m, r, left);
4513
4481
outs () << indent << " (method_t extends past the end of the section)\n " ;
4514
4482
} else
4515
- memcpy (&m, r, sizeof (struct method_delta_t ));
4483
+ memcpy (&m, r, sizeof (struct method_relative_t ));
4516
4484
if (info->O ->isLittleEndian () != sys::IsLittleEndianHost)
4517
4485
swapStruct (m);
4518
4486
4519
4487
outs () << indent << " \t\t name " << format (" 0x%" PRIx32, m.name );
4520
- uint64_t relNameRefVA = p + offsetof (struct method_delta_t , name);
4488
+ uint64_t relNameRefVA = p + offsetof (struct method_relative_t , name);
4521
4489
uint64_t absNameRefVA = relNameRefVA + m.name ;
4522
4490
outs () << " (" << format (" 0x%" PRIx32, absNameRefVA) << " )" ;
4523
4491
4524
- // since this is a delta list, absNameRefVA is the address of the
4492
+ // since this is a relative list, absNameRefVA is the address of the
4525
4493
// __objc_selrefs entry, so a pointer, not the actual name
4526
4494
const char *nameRefPtr =
4527
- get_pointer_32 (absNameRefVA, xoffset, left, xS, info);
4495
+ get_pointer_64 (absNameRefVA, xoffset, left, xS, info);
4528
4496
if (nameRefPtr) {
4529
4497
uint32_t pointerSize = pointerBits / CHAR_BIT;
4530
4498
if (left < pointerSize)
4531
4499
outs () << indent << " (nameRefPtr extends past the end of the section)" ;
4532
4500
else {
4533
- uint64_t nameVA = 0 ;
4534
- memcpy (&nameVA, nameRefPtr, pointerSize);
4535
- name = get_pointer_32 (nameVA, xoffset, left, xS, info);
4501
+ if (pointerSize == 64 ) {
4502
+ name = get_pointer_64 (*reinterpret_cast <const uint64_t *>(nameRefPtr),
4503
+ xoffset, left, xS, info);
4504
+ } else {
4505
+ name = get_pointer_32 (*reinterpret_cast <const uint32_t *>(nameRefPtr),
4506
+ xoffset, left, xS, info);
4507
+ }
4536
4508
if (name != nullptr )
4537
4509
outs () << format (" %.*s" , left, name);
4538
4510
}
4539
4511
}
4540
4512
outs () << " \n " ;
4541
4513
4542
4514
outs () << indent << " \t\t types " << format (" 0x%" PRIx32, m.types );
4543
- uint64_t relTypesVA = p + offsetof (struct method_delta_t , types);
4515
+ uint64_t relTypesVA = p + offsetof (struct method_relative_t , types);
4544
4516
uint64_t absTypesVA = relTypesVA + m.types ;
4545
4517
outs () << " (" << format (" 0x%" PRIx32, absTypesVA) << " )" ;
4546
4518
name = get_pointer_32 (absTypesVA, xoffset, left, xS, info);
@@ -4549,28 +4521,21 @@ static bool print_method_list_delta_t(uint64_t p, struct DisassembleInfo *info,
4549
4521
outs () << " \n " ;
4550
4522
4551
4523
outs () << indent << " \t\t imp " << format (" 0x%" PRIx32, m.imp );
4552
- uint64_t relImpVA = p + offsetof (struct method_delta_t , imp);
4524
+ uint64_t relImpVA = p + offsetof (struct method_relative_t , imp);
4553
4525
uint64_t absImpVA = relImpVA + m.imp ;
4554
4526
outs () << " (" << format (" 0x%" PRIx32, absImpVA) << " )" ;
4555
4527
name = GuessSymbolName (absImpVA, info->AddrMap );
4556
4528
if (name != nullptr )
4557
4529
outs () << " " << name;
4558
4530
outs () << " \n " ;
4559
4531
4560
- p += sizeof (struct method_delta_t );
4561
- offset += sizeof (struct method_delta_t );
4532
+ p += sizeof (struct method_relative_t );
4533
+ offset += sizeof (struct method_relative_t );
4562
4534
}
4563
-
4564
- return true ;
4565
4535
}
4566
4536
4567
4537
static void print_method_list64_t (uint64_t p, struct DisassembleInfo *info,
4568
4538
const char *indent) {
4569
- // Attempt to parse the method list as a delta list. If successful, return
4570
- // early since the parsing is complete.
4571
- if (print_method_list_delta_t (p, info, indent, /* pointerBits=*/ 64 ))
4572
- return ;
4573
-
4574
4539
struct method_list64_t ml;
4575
4540
struct method64_t m;
4576
4541
const char *r;
@@ -4590,10 +4555,17 @@ static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
4590
4555
memcpy (&ml, r, sizeof (struct method_list64_t ));
4591
4556
if (info->O ->isLittleEndian () != sys::IsLittleEndianHost)
4592
4557
swapStruct (ml);
4558
+ p += sizeof (struct method_list64_t );
4559
+
4560
+ if ((ml.entsize & ML_HAS_RELATIVE_PTRS) != 0 ) {
4561
+ print_relative_method_list (ml.entsize , ml.count , p, info, indent,
4562
+ /* pointerBits=*/ 32 );
4563
+ return ;
4564
+ }
4565
+
4593
4566
outs () << indent << " \t\t entsize " << ml.entsize << " \n " ;
4594
4567
outs () << indent << " \t\t count " << ml.count << " \n " ;
4595
4568
4596
- p += sizeof (struct method_list64_t );
4597
4569
offset += sizeof (struct method_list64_t );
4598
4570
for (i = 0 ; i < ml.count ; i++) {
4599
4571
r = get_pointer_64 (p, offset, left, S, info);
@@ -4664,11 +4636,6 @@ static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
4664
4636
4665
4637
static void print_method_list32_t (uint64_t p, struct DisassembleInfo *info,
4666
4638
const char *indent) {
4667
- // Attempt to parse the method list as a delta list. If successful, return
4668
- // early since the parsing is complete.
4669
- if (print_method_list_delta_t (p, info, indent, /* pointerBits=*/ 32 ))
4670
- return ;
4671
-
4672
4639
struct method_list32_t ml;
4673
4640
struct method32_t m;
4674
4641
const char *r, *name;
@@ -4686,10 +4653,17 @@ static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
4686
4653
memcpy (&ml, r, sizeof (struct method_list32_t ));
4687
4654
if (info->O ->isLittleEndian () != sys::IsLittleEndianHost)
4688
4655
swapStruct (ml);
4656
+ p += sizeof (struct method_list32_t );
4657
+
4658
+ if ((ml.entsize & ML_HAS_RELATIVE_PTRS) != 0 ) {
4659
+ print_relative_method_list (ml.entsize , ml.count , p, info, indent,
4660
+ /* pointerBits=*/ 32 );
4661
+ return ;
4662
+ }
4663
+
4689
4664
outs () << indent << " \t\t entsize " << ml.entsize << " \n " ;
4690
4665
outs () << indent << " \t\t count " << ml.count << " \n " ;
4691
4666
4692
- p += sizeof (struct method_list32_t );
4693
4667
offset += sizeof (struct method_list32_t );
4694
4668
for (i = 0 ; i < ml.count ; i++) {
4695
4669
r = get_pointer_32 (p, offset, left, S, info);
0 commit comments