aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp')
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp64
1 files changed, 45 insertions, 19 deletions
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 859b693477a9..bdd5c29db848 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -1,5 +1,4 @@
-//===-- AppleObjCClassDescriptorV2.cpp -----------------------------*- C++
-//-*-===//
+//===-- AppleObjCClassDescriptorV2.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -17,7 +16,7 @@ using namespace lldb_private;
bool ClassDescriptorV2::Read_objc_class(
Process *process, std::unique_ptr<objc_class_t> &objc_class) const {
- objc_class.reset(new objc_class_t);
+ objc_class = std::make_unique<objc_class_t>();
bool ret = objc_class->Read(process, m_objc_class_ptr);
@@ -198,14 +197,14 @@ bool ClassDescriptorV2::Read_class_row(
return false;
if (class_row_t_flags & RW_REALIZED) {
- class_rw.reset(new class_rw_t);
+ class_rw = std::make_unique<class_rw_t>();
if (!class_rw->Read(process, objc_class.m_data_ptr)) {
class_rw.reset();
return false;
}
- class_ro.reset(new class_ro_t);
+ class_ro = std::make_unique<class_ro_t>();
if (!class_ro->Read(process, class_rw->m_ro_ptr)) {
class_rw.reset();
@@ -213,7 +212,7 @@ bool ClassDescriptorV2::Read_class_row(
return false;
}
} else {
- class_ro.reset(new class_ro_t);
+ class_ro = std::make_unique<class_ro_t>();
if (!class_ro->Read(process, objc_class.m_data_ptr)) {
class_ro.reset();
@@ -242,15 +241,20 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process,
lldb::offset_t cursor = 0;
- m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
+ uint32_t entsize = extractor.GetU32_unchecked(&cursor);
+ m_is_small = (entsize & 0x80000000) != 0;
+ m_has_direct_selector = (entsize & 0x40000000) != 0;
+ m_entsize = entsize & 0xfffc;
m_count = extractor.GetU32_unchecked(&cursor);
m_first_ptr = addr + cursor;
return true;
}
-bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) {
- size_t size = GetSize(process);
+bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
+ bool is_small, bool has_direct_sel) {
+ size_t ptr_size = process->GetAddressByteSize();
+ size_t size = GetSize(process, is_small);
DataBufferHeap buffer(size, '\0');
Status error;
@@ -261,13 +265,30 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) {
}
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
- process->GetAddressByteSize());
-
+ ptr_size);
lldb::offset_t cursor = 0;
- m_name_ptr = extractor.GetAddress_unchecked(&cursor);
- m_types_ptr = extractor.GetAddress_unchecked(&cursor);
- m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
+ if (is_small) {
+ uint32_t nameref_offset = extractor.GetU32_unchecked(&cursor);
+ uint32_t types_offset = extractor.GetU32_unchecked(&cursor);
+ uint32_t imp_offset = extractor.GetU32_unchecked(&cursor);
+
+ m_name_ptr = addr + nameref_offset;
+
+ if (!has_direct_sel) {
+ // The SEL offset points to a SELRef. We need to dereference twice.
+ m_name_ptr = process->ReadUnsignedIntegerFromMemory(m_name_ptr, ptr_size,
+ 0, error);
+ if (!error.Success())
+ return false;
+ }
+ m_types_ptr = addr + 4 + types_offset;
+ m_imp_ptr = addr + 8 + imp_offset;
+ } else {
+ m_name_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_types_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
+ }
process->ReadCStringFromMemory(m_name_ptr, m_name, error);
if (error.Fail()) {
@@ -358,19 +379,24 @@ bool ClassDescriptorV2::Describe(
if (instance_method_func) {
std::unique_ptr<method_list_t> base_method_list;
- base_method_list.reset(new method_list_t);
+ base_method_list = std::make_unique<method_list_t>();
if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
return false;
- if (base_method_list->m_entsize != method_t::GetSize(process))
+ bool is_small = base_method_list->m_is_small;
+ bool has_direct_selector = base_method_list->m_has_direct_selector;
+
+ if (base_method_list->m_entsize != method_t::GetSize(process, is_small))
return false;
std::unique_ptr<method_t> method;
- method.reset(new method_t);
+ method = std::make_unique<method_t>();
for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) {
- method->Read(process, base_method_list->m_first_ptr +
- (i * base_method_list->m_entsize));
+ method->Read(process,
+ base_method_list->m_first_ptr +
+ (i * base_method_list->m_entsize),
+ is_small, has_direct_selector);
if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
break;