Skip to content

Commit 6080be0

Browse files
author
Alex B
committed
[lld-macho] Address Feedback #1
1 parent c99ad35 commit 6080be0

File tree

1 file changed

+53
-79
lines changed

1 file changed

+53
-79
lines changed

llvm/tools/llvm-objdump/MachODump.cpp

Lines changed: 53 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3519,12 +3519,6 @@ static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
35193519
return nullptr;
35203520
}
35213521

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-
35283522
static const char *get_pointer_32(uint32_t Address, uint32_t &offset,
35293523
uint32_t &left, SectionRef &S,
35303524
DisassembleInfo *info,
@@ -3667,8 +3661,8 @@ struct class_ro32_t {
36673661
#define RO_ROOT (1 << 1)
36683662
#define RO_HAS_CXX_STRUCTORS (1 << 2)
36693663

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)
36723666
#define ML_ENTSIZE_MASK 0xFFFF
36733667

36743668
struct method_list64_t {
@@ -3683,12 +3677,6 @@ struct method_list32_t {
36833677
/* struct method32_t first; These structures follow inline */
36843678
};
36853679

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-
36923680
struct method64_t {
36933681
uint64_t name; /* SEL (64-bit pointer) */
36943682
uint64_t types; /* const char * (64-bit pointer) */
@@ -3701,10 +3689,10 @@ struct method32_t {
37013689
uint32_t imp; /* IMP (32-bit pointer) */
37023690
};
37033691

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) */
37083696
};
37093697

37103698
struct protocol_list64_t {
@@ -3996,11 +3984,6 @@ inline void swapStruct(struct method_list32_t &ml) {
39963984
sys::swapByteOrder(ml.count);
39973985
}
39983986

3999-
inline void swapStruct(struct method_list_delta_t &ml) {
4000-
sys::swapByteOrder(ml.entsize);
4001-
sys::swapByteOrder(ml.count);
4002-
}
4003-
40043987
inline void swapStruct(struct method64_t &m) {
40053988
sys::swapByteOrder(m.name);
40063989
sys::swapByteOrder(m.types);
@@ -4013,7 +3996,7 @@ inline void swapStruct(struct method32_t &m) {
40133996
sys::swapByteOrder(m.imp);
40143997
}
40153998

4016-
inline void swapStruct(struct method_delta_t &m) {
3999+
inline void swapStruct(struct method_relative_t &m) {
40174000
sys::swapByteOrder(m.name);
40184001
sys::swapByteOrder(m.types);
40194002
sys::swapByteOrder(m.imp);
@@ -4473,74 +4456,63 @@ static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
44734456
print_layout_map(layout_map, left);
44744457
}
44754458

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;
44824465
const char *r, *name;
44834466
uint32_t offset, xoffset, left, i;
44844467
SectionRef S, xS;
44854468

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");
44994471

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";
45034475

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)) {
45124480
memcpy(&m, r, left);
45134481
outs() << indent << " (method_t extends past the end of the section)\n";
45144482
} else
4515-
memcpy(&m, r, sizeof(struct method_delta_t));
4483+
memcpy(&m, r, sizeof(struct method_relative_t));
45164484
if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
45174485
swapStruct(m);
45184486

45194487
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);
45214489
uint64_t absNameRefVA = relNameRefVA + m.name;
45224490
outs() << " (" << format("0x%" PRIx32, absNameRefVA) << ")";
45234491

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
45254493
// __objc_selrefs entry, so a pointer, not the actual name
45264494
const char *nameRefPtr =
4527-
get_pointer_32(absNameRefVA, xoffset, left, xS, info);
4495+
get_pointer_64(absNameRefVA, xoffset, left, xS, info);
45284496
if (nameRefPtr) {
45294497
uint32_t pointerSize = pointerBits / CHAR_BIT;
45304498
if (left < pointerSize)
45314499
outs() << indent << " (nameRefPtr extends past the end of the section)";
45324500
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+
}
45364508
if (name != nullptr)
45374509
outs() << format(" %.*s", left, name);
45384510
}
45394511
}
45404512
outs() << "\n";
45414513

45424514
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);
45444516
uint64_t absTypesVA = relTypesVA + m.types;
45454517
outs() << " (" << format("0x%" PRIx32, absTypesVA) << ")";
45464518
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,
45494521
outs() << "\n";
45504522

45514523
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);
45534525
uint64_t absImpVA = relImpVA + m.imp;
45544526
outs() << " (" << format("0x%" PRIx32, absImpVA) << ")";
45554527
name = GuessSymbolName(absImpVA, info->AddrMap);
45564528
if (name != nullptr)
45574529
outs() << " " << name;
45584530
outs() << "\n";
45594531

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);
45624534
}
4563-
4564-
return true;
45654535
}
45664536

45674537
static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
45684538
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-
45744539
struct method_list64_t ml;
45754540
struct method64_t m;
45764541
const char *r;
@@ -4590,10 +4555,17 @@ static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
45904555
memcpy(&ml, r, sizeof(struct method_list64_t));
45914556
if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
45924557
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+
45934566
outs() << indent << "\t\t entsize " << ml.entsize << "\n";
45944567
outs() << indent << "\t\t count " << ml.count << "\n";
45954568

4596-
p += sizeof(struct method_list64_t);
45974569
offset += sizeof(struct method_list64_t);
45984570
for (i = 0; i < ml.count; i++) {
45994571
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,
46644636

46654637
static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
46664638
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-
46724639
struct method_list32_t ml;
46734640
struct method32_t m;
46744641
const char *r, *name;
@@ -4686,10 +4653,17 @@ static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
46864653
memcpy(&ml, r, sizeof(struct method_list32_t));
46874654
if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
46884655
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+
46894664
outs() << indent << "\t\t entsize " << ml.entsize << "\n";
46904665
outs() << indent << "\t\t count " << ml.count << "\n";
46914666

4692-
p += sizeof(struct method_list32_t);
46934667
offset += sizeof(struct method_list32_t);
46944668
for (i = 0; i < ml.count; i++) {
46954669
r = get_pointer_32(p, offset, left, S, info);

0 commit comments

Comments
 (0)