[llvm] [llvm-objdump][macho] Add support for ObjC relative method lists (PR #84250)
Daniel RodrÃguez Troitiño via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 13 13:00:10 PDT 2024
================
@@ -4440,8 +4473,104 @@ static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
print_layout_map(layout_map, left);
}
+// Return true if this is a delta method list, false otherwise
+static bool print_method_list_delta_t(uint64_t p, struct DisassembleInfo *info,
+ const char *indent,
+ uint32_t pointerBits) {
+ struct method_list_delta_t ml;
+ struct method_delta_t m;
+ const char *r, *name;
+ uint32_t offset, xoffset, left, i;
+ SectionRef S, xS;
+
+ r = get_pointer_32(p, offset, left, S, info);
+ if (r == nullptr)
+ return false;
+ memset(&ml, '\0', sizeof(struct method_list_delta_t));
+ if (left < sizeof(struct method_list_delta_t)) {
+ memcpy(&ml, r, left);
+ outs() << " (method_delta_t extends past the end of the section)\n";
+ } else
+ memcpy(&ml, r, sizeof(struct method_list_delta_t));
+ if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
+ swapStruct(ml);
+ if ((ml.entsize & ML_HAS_DELTAS) == 0)
+ return false;
+
+ outs() << indent << "\t\t entsize " << (ml.entsize & ML_ENTSIZE_MASK)
+ << " (relative) \n";
+ outs() << indent << "\t\t count " << ml.count << "\n";
+
+ p += sizeof(struct method_list_delta_t);
+ offset += sizeof(struct method_delta_t);
+ for (i = 0; i < ml.count; i++) {
+ r = get_value_32(p, offset, left, S, info);
+ if (r == nullptr)
+ return true;
+ memset(&m, '\0', sizeof(struct method_delta_t));
+ if (left < sizeof(struct method_delta_t)) {
+ memcpy(&m, r, left);
+ outs() << indent << " (method_t extends past the end of the section)\n";
+ } else
+ memcpy(&m, r, sizeof(struct method_delta_t));
+ if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
+ swapStruct(m);
+
+ outs() << indent << "\t\t name " << format("0x%" PRIx32, m.name);
+ uint64_t relNameRefVA = p + offsetof(struct method_delta_t, name);
+ uint64_t absNameRefVA = relNameRefVA + m.name;
+ outs() << " (" << format("0x%" PRIx32, absNameRefVA) << ")";
+
+ // since this is a delta list, absNameRefVA is the address of the
+ // __objc_selrefs entry, so a pointer, not the actual name
+ const char *nameRefPtr =
+ get_pointer_32(absNameRefVA, xoffset, left, xS, info);
+ if (nameRefPtr) {
+ uint32_t pointerSize = pointerBits / CHAR_BIT;
+ if (left < pointerSize)
+ outs() << indent << " (nameRefPtr extends past the end of the section)";
+ else {
+ uint64_t nameVA = 0;
+ memcpy(&nameVA, nameRefPtr, pointerSize);
+ name = get_pointer_32(nameVA, xoffset, left, xS, info);
+ if (name != nullptr)
+ outs() << format(" %.*s", left, name);
+ }
----------------
drodriguez wrote:
Sorry the usage of `(uint64_t *)nameRefPtr` was not correct. I think I was missing the `*` at the start: `*(uint64_t *)nameRefPtr` should be equivalent of doing the `memcpy` of those bytes from `nameRefPtr`, without the confusion of doing a `memcpy`: https://godbolt.org/z/P84h3ejTb
https://github.com/llvm/llvm-project/pull/84250
More information about the llvm-commits
mailing list