[llvm] [llvm-objdump][macho] Add support for ObjC relative method lists (PR #84250)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 13 16:17:46 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);
+      }
----------------
alx32 wrote:

Updated to this, but using `reinterpret_cast`, as to match file style.

https://github.com/llvm/llvm-project/pull/84250


More information about the llvm-commits mailing list