Skip to content

Conversation

@JDevlieghere
Copy link
Member

Support the types and name field in the relative method list to be relative to a buffer in the shared cache, not relative to the field in the method list itself.

A new magic bit, 0x20000000, is attached to method lists where the types are encoded in this way. This is covered by the existing tests when running against a shared cache that uses this encoding.

rdar://147545351

Support the types and name field in the relative method list to be
relative to a buffer in the shared cache, not relative to the field in
the method list itself.

A new magic bit, 0x20000000, is attached to method lists where the types
are encoded in this way. This is covered by the existing tests when
running against a shared cache that uses this encoding.

rdar://147545351
@llvmbot
Copy link
Member

llvmbot commented Oct 16, 2025

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

Support the types and name field in the relative method list to be relative to a buffer in the shared cache, not relative to the field in the method list itself.

A new magic bit, 0x20000000, is attached to method lists where the types are encoded in this way. This is covered by the existing tests when running against a shared cache that uses this encoding.

rdar://147545351


Full diff: https://github.com/llvm/llvm-project/pull/163663.diff

2 Files Affected:

  • (modified) lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp (+17-10)
  • (modified) lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h (+5-4)
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 6d8f41aef1ffc..460c503b25c73 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -260,6 +260,7 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process,
   uint32_t entsize = extractor.GetU32_unchecked(&cursor);
   m_is_small = (entsize & 0x80000000) != 0;
   m_has_direct_selector = (entsize & 0x40000000) != 0;
+  m_has_relative_types = (entsize & 0x20000000) != 0;
   m_entsize = entsize & 0xfffc;
   m_count = extractor.GetU32_unchecked(&cursor);
   m_first_ptr = addr + cursor;
@@ -269,8 +270,9 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process,
 
 llvm::SmallVector<ClassDescriptorV2::method_t, 0>
 ClassDescriptorV2::ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses,
-                               lldb::addr_t relative_selector_base_addr,
-                               bool is_small, bool has_direct_sel) const {
+                               lldb::addr_t relative_string_base_addr,
+                               bool is_small, bool has_direct_sel,
+                               bool has_relative_types) const {
   lldb_private::Process *process = m_runtime.GetProcess();
   if (!process)
     return {};
@@ -297,8 +299,8 @@ ClassDescriptorV2::ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses,
                             process->GetByteOrder(),
                             process->GetAddressByteSize());
     methods.push_back(method_t());
-    methods.back().Read(extractor, process, addr, relative_selector_base_addr,
-                        is_small, has_direct_sel);
+    methods.back().Read(extractor, process, addr, relative_string_base_addr,
+                        is_small, has_direct_sel, has_relative_types);
   }
 
   return methods;
@@ -306,8 +308,9 @@ ClassDescriptorV2::ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses,
 
 bool ClassDescriptorV2::method_t::Read(DataExtractor &extractor,
                                        Process *process, lldb::addr_t addr,
-                                       lldb::addr_t relative_selector_base_addr,
-                                       bool is_small, bool has_direct_sel) {
+                                       lldb::addr_t relative_string_base_addr,
+                                       bool is_small, bool has_direct_sel,
+                                       bool has_relative_types) {
   lldb::offset_t cursor = 0;
 
   if (is_small) {
@@ -323,10 +326,13 @@ bool ClassDescriptorV2::method_t::Read(DataExtractor &extractor,
       m_name_ptr = process->ReadPointerFromMemory(m_name_ptr, error);
       if (error.Fail())
         return false;
-    } else if (relative_selector_base_addr != LLDB_INVALID_ADDRESS) {
-      m_name_ptr = relative_selector_base_addr + nameref_offset;
+    } else if (relative_string_base_addr != LLDB_INVALID_ADDRESS) {
+      m_name_ptr = relative_string_base_addr + nameref_offset;
     }
-    m_types_ptr = addr + 4 + types_offset;
+    if (has_relative_types)
+      m_types_ptr = relative_string_base_addr + types_offset;
+    else
+      m_types_ptr = addr + 4 + types_offset;
     m_imp_ptr = addr + 8 + imp_offset;
   } else {
     m_name_ptr = extractor.GetAddress_unchecked(&cursor);
@@ -481,7 +487,8 @@ bool ClassDescriptorV2::ProcessMethodList(
 
   llvm::SmallVector<method_t, 0> methods =
       ReadMethods(addresses, m_runtime.GetRelativeSelectorBaseAddr(),
-                  method_list.m_is_small, method_list.m_has_direct_selector);
+                  method_list.m_is_small, method_list.m_has_direct_selector,
+                  method_list.m_has_relative_types);
 
   for (const auto &method : methods)
     if (instance_method_func(method.m_name.c_str(), method.m_types.c_str()))
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 78b33113b59da..0fff9af438367 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -143,6 +143,7 @@ class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor {
     uint16_t m_entsize;
     bool m_is_small;
     bool m_has_direct_selector;
+    bool m_has_relative_types;
     uint32_t m_count;
     lldb::addr_t m_first_ptr;
 
@@ -173,14 +174,14 @@ class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor {
     }
 
     bool Read(DataExtractor &extractor, Process *process, lldb::addr_t addr,
-              lldb::addr_t relative_selector_base_addr, bool is_small,
-              bool has_direct_sel);
+              lldb::addr_t relative_string_base_addr, bool is_small,
+              bool has_direct_sel, bool has_relative_types);
   };
 
   llvm::SmallVector<method_t, 0>
   ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses,
-              lldb::addr_t relative_selector_base_addr, bool is_small,
-              bool has_direct_sel) const;
+              lldb::addr_t relative_string_base_addr, bool is_small,
+              bool has_direct_sel, bool has_relative_types) const;
 
   struct ivar_list_t {
     uint32_t m_entsize;

Copy link
Contributor

@cooperp cooperp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@JDevlieghere JDevlieghere merged commit d0d001d into llvm:main Oct 16, 2025
12 checks passed
@JDevlieghere JDevlieghere deleted the rdar147545351 branch October 16, 2025 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants