From 4d77d156cb73d42e01117530eb1612b93b81a281 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Tue, 15 Aug 2017 21:23:14 +0000 Subject: Update NSArray/NSDictionary/NSSet formatters to handle new macOS 10.13 - High Sierra - internal layouts. Patch by Sean Callanan. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@310959 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/Language/ObjC/NSArray.cpp | 612 +++++++++++--------------- source/Plugins/Language/ObjC/NSDictionary.cpp | 317 ++++++++----- source/Plugins/Language/ObjC/NSSet.cpp | 84 +++- 3 files changed, 546 insertions(+), 467 deletions(-) (limited to 'source/Plugins/Language/ObjC') diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp index 27cb9558c..228a626be 100644 --- a/source/Plugins/Language/ObjC/NSArray.cpp +++ b/source/Plugins/Language/ObjC/NSArray.cpp @@ -48,11 +48,11 @@ NSArray_Additionals::GetAdditionalSynthetics() { return g_map; } -class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +class NSArrayMSyntheticFrontEndBase : public SyntheticChildrenFrontEnd { public: - NSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp); - ~NSArrayMSyntheticFrontEnd() override = default; + ~NSArrayMSyntheticFrontEndBase() override = default; size_t CalculateNumChildren() override; @@ -78,11 +78,12 @@ protected: CompilerType m_id_type; }; -class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd { +template +class GenericNSArrayMSyntheticFrontEnd : public NSArrayMSyntheticFrontEndBase { public: - NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp); + GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); - ~NSArrayMSyntheticFrontEnd_109() override; + ~GenericNSArrayMSyntheticFrontEnd() override; bool Update() override; @@ -96,6 +97,11 @@ protected: uint64_t GetSize() override; private: + D32 *m_data_32; + D64 *m_data_64; +}; + +namespace Foundation109 { struct DataDescriptor_32 { uint32_t _used; uint32_t _priv1 : 2; @@ -105,7 +111,7 @@ private: uint32_t _priv3; uint32_t _data; }; - + struct DataDescriptor_64 { uint64_t _used; uint64_t _priv1 : 2; @@ -115,29 +121,12 @@ private: uint32_t _priv3; uint64_t _data; }; - - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; + + using NSArrayMSyntheticFrontEnd = + GenericNSArrayMSyntheticFrontEnd; }; - -class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd { -public: - NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp); - - ~NSArrayMSyntheticFrontEnd_1010() override; - - bool Update() override; - -protected: - lldb::addr_t GetDataAddress() override; - - uint64_t GetUsedCount() override; - - uint64_t GetOffset() override; - - uint64_t GetSize() override; - -private: + +namespace Foundation1010 { struct DataDescriptor_32 { uint32_t _used; uint32_t _offset; @@ -146,7 +135,7 @@ private: uint32_t _priv2; uint32_t _data; }; - + struct DataDescriptor_64 { uint64_t _used; uint64_t _offset; @@ -155,52 +144,86 @@ private: uint32_t _priv2; uint64_t _data; }; - - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; + + using NSArrayMSyntheticFrontEnd = + GenericNSArrayMSyntheticFrontEnd; }; - -class NSArrayMSyntheticFrontEnd_1400 : public NSArrayMSyntheticFrontEnd { -public: - NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp); - - ~NSArrayMSyntheticFrontEnd_1400() override; - - bool Update() override; - -protected: - lldb::addr_t GetDataAddress() override; - - uint64_t GetUsedCount() override; - - uint64_t GetOffset() override; - - uint64_t GetSize() override; - -private: + +namespace Foundation1428 { struct DataDescriptor_32 { - uint32_t used; - uint32_t offset; - uint32_t size; - uint32_t list; + uint32_t _used; + uint32_t _offset; + uint32_t _size; + uint32_t _data; }; - + struct DataDescriptor_64 { - uint64_t used; - uint64_t offset; - uint64_t size; - uint64_t list; + uint64_t _used; + uint64_t _offset; + uint64_t _size; + uint64_t _data; + }; + + using NSArrayMSyntheticFrontEnd = + GenericNSArrayMSyntheticFrontEnd; +}; + +namespace Foundation1437 { + template + struct DataDescriptor { + PtrType _cow; + // __deque + PtrType _data; + uint32_t _offset; + uint32_t _size; + union { + PtrType _mutations; + struct { + uint32_t _muts; + uint32_t _used; + }; + }; }; + + using NSArrayMSyntheticFrontEnd = + GenericNSArrayMSyntheticFrontEnd< + DataDescriptor, DataDescriptor>; + + template + uint64_t + __NSArrayMSize_Impl(lldb_private::Process &process, + lldb::addr_t valobj_addr, Status &error) { + const lldb::addr_t start_of_descriptor = + valobj_addr + process.GetAddressByteSize(); + DD descriptor = DD(); + process.ReadMemory(start_of_descriptor, &descriptor, + sizeof(descriptor), error); + if (error.Fail()) { + return 0; + } + return descriptor._used; + } + + uint64_t + __NSArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, + Status &error) { + if (process.GetAddressByteSize() == 4) { + return __NSArrayMSize_Impl>(process, valobj_addr, + error); + } else { + return __NSArrayMSize_Impl>(process, valobj_addr, + error); + } + } - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; }; -class NSArrayISyntheticFrontEnd_1300 : public SyntheticChildrenFrontEnd { +template +class GenericNSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: - NSArrayISyntheticFrontEnd_1300(lldb::ValueObjectSP valobj_sp); + GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); - ~NSArrayISyntheticFrontEnd_1300() override = default; + ~GenericNSArrayISyntheticFrontEnd() override; size_t CalculateNumChildren() override; @@ -215,48 +238,57 @@ public: private: ExecutionContextRef m_exe_ctx_ref; uint8_t m_ptr_size; - uint64_t m_items; - lldb::addr_t m_data_ptr; + + D32 *m_data_32; + D64 *m_data_64; CompilerType m_id_type; }; + +namespace Foundation1300 { + struct IDD32 { + uint32_t used; + uint32_t list; + }; + + struct IDD64 { + uint64_t used; + uint64_t list; + }; + + using NSArrayISyntheticFrontEnd = + GenericNSArrayISyntheticFrontEnd; +}; -class NSArrayISyntheticFrontEnd_1400 : public SyntheticChildrenFrontEnd { -public: - NSArrayISyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp); - - ~NSArrayISyntheticFrontEnd_1400() override; - - size_t CalculateNumChildren() override; - - lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; - - bool Update() override; - - bool MightHaveChildren() override; - - size_t GetIndexOfChildWithName(const ConstString &name) override; - -private: - ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - - struct DataDescriptor_32 { - uint32_t used; - uint32_t offset; - uint32_t size; - uint32_t list; - }; - - struct DataDescriptor_64 { - uint64_t used; - uint64_t offset; - uint64_t size; - uint64_t list; - }; +namespace Foundation1430 { + using NSArrayISyntheticFrontEnd = + Foundation1428::NSArrayMSyntheticFrontEnd; +}; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; - CompilerType m_id_type; +namespace Foundation1436 { + struct IDD32 { + uint32_t used; + uint32_t list; // in Inline cases, this is the first element + }; + + struct IDD64 { + uint64_t used; + uint64_t list; // in Inline cases, this is the first element + }; + + using NSArrayI_TransferSyntheticFrontEnd = + GenericNSArrayISyntheticFrontEnd; + + using NSArrayISyntheticFrontEnd = + GenericNSArrayISyntheticFrontEnd; + + using NSFrozenArrayMSyntheticFrontEnd = + Foundation1437::NSArrayMSyntheticFrontEnd; + + uint64_t + __NSFrozenArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, + Status &error) { + return Foundation1437::__NSArrayMSize(process, valobj_addr, error); + } }; class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd { @@ -329,6 +361,8 @@ bool lldb_private::formatters::NSArraySummaryProvider( static const ConstString g_NSArrayI("__NSArrayI"); static const ConstString g_NSArrayM("__NSArrayM"); + static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer"); + static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM"); static const ConstString g_NSArray0("__NSArray0"); static const ConstString g_NSArray1("__NSSingleObjectArrayI"); static const ConstString g_NSArrayCF("__NSCFArray"); @@ -345,11 +379,28 @@ bool lldb_private::formatters::NSArraySummaryProvider( if (error.Fail()) return false; } else if (class_name == g_NSArrayM) { + AppleObjCRuntime *apple_runtime = + llvm::dyn_cast_or_null(runtime); + Status error; + if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) { + value = Foundation1437::__NSArrayMSize(*process_sp, valobj_addr, error); + } else { + value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, + ptr_size, 0, error); + } + if (error.Fail()) + return false; + } else if (class_name == g_NSArrayI_Transfer) { Status error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; + } else if (class_name == g_NSFrozenArrayM) { + Status error; + value = Foundation1436::__NSFrozenArrayMSize(*process_sp, valobj_addr, error); + if (error.Fail()) + return false; } else if (class_name == g_NSArrayMLegacy) { Status error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, @@ -395,7 +446,7 @@ bool lldb_private::formatters::NSArraySummaryProvider( return true; } -lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd( +lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontEndBase( lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), m_id_type() { @@ -411,28 +462,20 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd( } } -lldb_private::formatters::NSArrayMSyntheticFrontEnd_109:: - NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp) - : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr), - m_data_64(nullptr) {} - -lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010:: - NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp) - : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr), - m_data_64(nullptr) {} - -lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400:: - NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp) - : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr), +template +lldb_private::formatters:: + GenericNSArrayMSyntheticFrontEnd:: + GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : NSArrayMSyntheticFrontEndBase(valobj_sp), m_data_32(nullptr), m_data_64(nullptr) {} size_t -lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren() { +lldb_private::formatters::NSArrayMSyntheticFrontEndBase::CalculateNumChildren() { return GetUsedCount(); } lldb::ValueObjectSP -lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex( +lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetChildAtIndex( size_t idx) { if (idx >= CalculateNumChildren()) return lldb::ValueObjectSP(); @@ -448,38 +491,10 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex( m_exe_ctx_ref, m_id_type); } -bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update() { - ValueObjectSP valobj_sp = m_backend.GetSP(); - m_ptr_size = 0; - delete m_data_32; - m_data_32 = nullptr; - delete m_data_64; - m_data_64 = nullptr; - if (!valobj_sp) - return false; - m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); - Status error; - error.Clear(); - lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); - if (!process_sp) - return false; - m_ptr_size = process_sp->GetAddressByteSize(); - uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; - if (m_ptr_size == 4) { - m_data_32 = new DataDescriptor_32(); - process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32), - error); - } else { - m_data_64 = new DataDescriptor_64(); - process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64), - error); - } - if (error.Fail()) - return false; - return false; -} - -bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update() { +template +bool +lldb_private::formatters:: + GenericNSArrayMSyntheticFrontEnd::Update() { ValueObjectSP valobj_sp = m_backend.GetSP(); m_ptr_size = 0; delete m_data_32; @@ -497,12 +512,12 @@ bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update() { m_ptr_size = process_sp->GetAddressByteSize(); uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; if (m_ptr_size == 4) { - m_data_32 = new DataDescriptor_32(); - process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32), + m_data_32 = new D32(); + process_sp->ReadMemory(data_location, m_data_32, sizeof(D32), error); } else { - m_data_64 = new DataDescriptor_64(); - process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64), + m_data_64 = new D64(); + process_sp->ReadMemory(data_location, m_data_64, sizeof(D64), error); } if (error.Fail()) @@ -510,43 +525,13 @@ bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update() { return false; } -bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::Update() { - ValueObjectSP valobj_sp = m_backend.GetSP(); - m_ptr_size = 0; - delete m_data_32; - m_data_32 = nullptr; - delete m_data_64; - m_data_64 = nullptr; - if (!valobj_sp) - return false; - m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); - Status error; - error.Clear(); - lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); - if (!process_sp) - return false; - m_ptr_size = process_sp->GetAddressByteSize(); - uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; - if (m_ptr_size == 4) { - m_data_32 = new DataDescriptor_32(); - process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32), - error); - } else { - m_data_64 = new DataDescriptor_64(); - process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64), - error); - } - if (error.Fail()) - return false; - return false; -} - -bool lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren() { +bool +lldb_private::formatters::NSArrayMSyntheticFrontEndBase::MightHaveChildren() { return true; } size_t -lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName( +lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetIndexOfChildWithName( const ConstString &name) { const char *item_name = name.GetCString(); uint32_t idx = ExtractIndexFromString(item_name); @@ -555,187 +540,59 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName( return idx; } -lldb_private::formatters::NSArrayMSyntheticFrontEnd_109:: - ~NSArrayMSyntheticFrontEnd_109() { +template +lldb_private::formatters:: + GenericNSArrayMSyntheticFrontEnd:: + ~GenericNSArrayMSyntheticFrontEnd() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; m_data_64 = nullptr; } +template lldb::addr_t -lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress() { +lldb_private::formatters:: + GenericNSArrayMSyntheticFrontEnd:: + GenericNSArrayMSyntheticFrontEnd::GetDataAddress() { if (!m_data_32 && !m_data_64) return LLDB_INVALID_ADDRESS; return m_data_32 ? m_data_32->_data : m_data_64->_data; } +template uint64_t -lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetUsedCount() { +lldb_private::formatters:: + GenericNSArrayMSyntheticFrontEnd:: + GenericNSArrayMSyntheticFrontEnd::GetUsedCount() { if (!m_data_32 && !m_data_64) return 0; return m_data_32 ? m_data_32->_used : m_data_64->_used; } -uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetOffset() { - if (!m_data_32 && !m_data_64) - return 0; - return m_data_32 ? m_data_32->_offset : m_data_64->_offset; -} - -uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize() { - if (!m_data_32 && !m_data_64) - return 0; - return m_data_32 ? m_data_32->_size : m_data_64->_size; -} - -lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010:: - ~NSArrayMSyntheticFrontEnd_1010() { - delete m_data_32; - m_data_32 = nullptr; - delete m_data_64; - m_data_64 = nullptr; -} - -lldb::addr_t -lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetDataAddress() { - if (!m_data_32 && !m_data_64) - return LLDB_INVALID_ADDRESS; - return m_data_32 ? m_data_32->_data : m_data_64->_data; -} - +template uint64_t -lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetUsedCount() { - if (!m_data_32 && !m_data_64) - return 0; - return m_data_32 ? m_data_32->_used : m_data_64->_used; -} - -uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetOffset() { +lldb_private::formatters:: + GenericNSArrayMSyntheticFrontEnd:: + GenericNSArrayMSyntheticFrontEnd::GetOffset() { if (!m_data_32 && !m_data_64) return 0; return m_data_32 ? m_data_32->_offset : m_data_64->_offset; } -uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize() { - if (!m_data_32 && !m_data_64) - return 0; - return m_data_32 ? m_data_32->_size : m_data_64->_size; -} - -lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400:: - ~NSArrayMSyntheticFrontEnd_1400() { - delete m_data_32; - m_data_32 = nullptr; - delete m_data_64; - m_data_64 = nullptr; -} - -lldb::addr_t -lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetDataAddress() { - if (!m_data_32 && !m_data_64) - return LLDB_INVALID_ADDRESS; - return m_data_32 ? m_data_32->list : m_data_64->list; -} - +template uint64_t -lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetUsedCount() { +lldb_private::formatters:: + GenericNSArrayMSyntheticFrontEnd:: + GenericNSArrayMSyntheticFrontEnd::GetSize() { if (!m_data_32 && !m_data_64) return 0; - return m_data_32 ? m_data_32->used : m_data_64->used; -} - -uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetOffset() { - if (!m_data_32 && !m_data_64) - return 0; - return m_data_32 ? m_data_32->offset : m_data_64->offset; -} - -uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetSize() { - if (!m_data_32 && !m_data_64) - return 0; - return m_data_32 ? m_data_32->size : m_data_64->size; -} - - -lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::NSArrayISyntheticFrontEnd_1300( - lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), - m_items(0), m_data_ptr(0) { - if (valobj_sp) { - CompilerType type = valobj_sp->GetCompilerType(); - if (type) { - ClangASTContext *ast = valobj_sp->GetExecutionContextRef() - .GetTargetSP() - ->GetScratchClangASTContext(); - if (ast) - m_id_type = CompilerType(ast->getASTContext(), - ast->getASTContext()->ObjCBuiltinIdTy); - } - } -} - -size_t -lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetIndexOfChildWithName( - const ConstString &name) { - const char *item_name = name.GetCString(); - uint32_t idx = ExtractIndexFromString(item_name); - if (idx < UINT32_MAX && idx >= CalculateNumChildren()) - return UINT32_MAX; - return idx; -} - -size_t -lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::CalculateNumChildren() { - return m_items; -} - -bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::Update() { - m_ptr_size = 0; - m_items = 0; - m_data_ptr = 0; - ValueObjectSP valobj_sp = m_backend.GetSP(); - if (!valobj_sp) - return false; - m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); - Status error; - error.Clear(); - lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); - if (!process_sp) - return false; - m_ptr_size = process_sp->GetAddressByteSize(); - uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; - m_items = process_sp->ReadPointerFromMemory(data_location, error); - if (error.Fail()) - return false; - m_data_ptr = data_location + m_ptr_size; - return false; -} - -bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::MightHaveChildren() { - return true; -} - -lldb::ValueObjectSP -lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetChildAtIndex( - size_t idx) { - if (idx >= CalculateNumChildren()) - return lldb::ValueObjectSP(); - lldb::addr_t object_at_idx = m_data_ptr; - object_at_idx += (idx * m_ptr_size); - ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); - if (!process_sp) - return lldb::ValueObjectSP(); - Status error; - if (error.Fail()) - return lldb::ValueObjectSP(); - StreamString idx_name; - idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); - return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx, - m_exe_ctx_ref, m_id_type); + return m_data_32 ? m_data_32->_size : m_data_64->_size; } -lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::NSArrayISyntheticFrontEnd_1400( +template +lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: + GenericNSArrayISyntheticFrontEnd( lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), m_data_32(nullptr), m_data_64(nullptr) { @@ -752,16 +609,19 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::NSArrayISyntheticFront } } -lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::~NSArrayISyntheticFrontEnd_1400() { +template +lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: + ~GenericNSArrayISyntheticFrontEnd() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; m_data_64 = nullptr; } +template size_t -lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetIndexOfChildWithName( - const ConstString &name) { +lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: + GetIndexOfChildWithName(const ConstString &name) { const char *item_name = name.GetCString(); uint32_t idx = ExtractIndexFromString(item_name); if (idx < UINT32_MAX && idx >= CalculateNumChildren()) @@ -769,12 +629,17 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetIndexOfChildWithNam return idx; } +template size_t -lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::CalculateNumChildren() { +lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: + CalculateNumChildren() { return m_data_32 ? m_data_32->used : m_data_64->used; } -bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() { +template +bool +lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: + Update() { ValueObjectSP valobj_sp = m_backend.GetSP(); m_ptr_size = 0; delete m_data_32; @@ -792,12 +657,12 @@ bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() { m_ptr_size = process_sp->GetAddressByteSize(); uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; if (m_ptr_size == 4) { - m_data_32 = new DataDescriptor_32(); - process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32), + m_data_32 = new D32(); + process_sp->ReadMemory(data_location, m_data_32, sizeof(D32), error); } else { - m_data_64 = new DataDescriptor_64(); - process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64), + m_data_64 = new D64(); + process_sp->ReadMemory(data_location, m_data_64, sizeof(D64), error); } if (error.Fail()) @@ -805,17 +670,29 @@ bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() { return false; } -bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::MightHaveChildren() { +template +bool +lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: + MightHaveChildren() { return true; } +template lldb::ValueObjectSP -lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetChildAtIndex( - size_t idx) { +lldb_private::formatters::GenericNSArrayISyntheticFrontEnd:: + GetChildAtIndex(size_t idx) { if (idx >= CalculateNumChildren()) return lldb::ValueObjectSP(); - lldb::addr_t object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list; + lldb::addr_t object_at_idx; + if (Inline) { + object_at_idx = m_backend.GetSP()->GetValueAsUnsigned(0) + m_ptr_size; + object_at_idx += m_ptr_size == 4 ? sizeof(D32) : sizeof(D64); // skip the data header + object_at_idx -= m_ptr_size; // we treat the last entry in the data header as the first pointer + } else { + object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list; + } object_at_idx += (idx * m_ptr_size); + ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); if (!process_sp) return lldb::ValueObjectSP(); @@ -933,6 +810,8 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator( ConstString class_name(descriptor->GetClassName()); static const ConstString g_NSArrayI("__NSArrayI"); + static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer"); + static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM"); static const ConstString g_NSArrayM("__NSArrayM"); static const ConstString g_NSArray0("__NSArray0"); static const ConstString g_NSArray1("__NSSingleObjectArrayI"); @@ -943,21 +822,30 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator( return nullptr; if (class_name == g_NSArrayI) { - if (runtime->GetFoundationVersion() >= 1400) - return (new NSArrayISyntheticFrontEnd_1400(valobj_sp)); - else - return (new NSArrayISyntheticFrontEnd_1300(valobj_sp)); + if (runtime->GetFoundationVersion() >= 1436) + return (new Foundation1436::NSArrayISyntheticFrontEnd(valobj_sp)); + if (runtime->GetFoundationVersion() >= 1430) + return (new Foundation1430::NSArrayISyntheticFrontEnd(valobj_sp)); + else + return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp)); + } else if (class_name == g_NSArrayI_Transfer) { + return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp)); + } else if (class_name == g_NSArray0) { + } else if (class_name == g_NSFrozenArrayM) { + return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp)); } else if (class_name == g_NSArray0) { return (new NSArray0SyntheticFrontEnd(valobj_sp)); } else if (class_name == g_NSArray1) { return (new NSArray1SyntheticFrontEnd(valobj_sp)); } else if (class_name == g_NSArrayM) { - if (runtime->GetFoundationVersion() >= 1400) - return (new NSArrayMSyntheticFrontEnd_1400(valobj_sp)); + if (runtime->GetFoundationVersion() >= 1437) + return (new Foundation1437::NSArrayMSyntheticFrontEnd(valobj_sp)); + if (runtime->GetFoundationVersion() >= 1428) + return (new Foundation1428::NSArrayMSyntheticFrontEnd(valobj_sp)); if (runtime->GetFoundationVersion() >= 1100) - return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp)); + return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp)); else - return (new NSArrayMSyntheticFrontEnd_109(valobj_sp)); + return (new Foundation109::NSArrayMSyntheticFrontEnd(valobj_sp)); } else { auto &map(NSArray_Additionals::GetAdditionalSynthetics()); auto iter = map.find(class_name), end = map.end(); diff --git a/source/Plugins/Language/ObjC/NSDictionary.cpp b/source/Plugins/Language/ObjC/NSDictionary.cpp index 50febbe39..4c98580d2 100644 --- a/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -165,11 +165,12 @@ private: ValueObjectSP m_pair; }; -class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +template +class GenericNSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: - NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); - ~NSDictionaryMSyntheticFrontEnd() override; + ~GenericNSDictionaryMSyntheticFrontEnd() override; size_t CalculateNumChildren() override; @@ -182,20 +183,6 @@ public: size_t GetIndexOfChildWithName(const ConstString &name) override; private: - struct DataDescriptor_32 { - uint32_t used : 26; - uint32_t kvo : 1; - uint32_t size; - uint32_t buffer; - }; - - struct DataDescriptor_64 { - uint64_t used : 58; - uint32_t kvo : 1; - uint64_t size; - uint64_t buffer; - }; - struct DictionaryItemDescriptor { lldb::addr_t key_ptr; lldb::addr_t val_ptr; @@ -205,60 +192,168 @@ private: ExecutionContextRef m_exe_ctx_ref; uint8_t m_ptr_size; lldb::ByteOrder m_order; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; + D32 *m_data_32; + D64 *m_data_64; CompilerType m_pair_type; std::vector m_children; }; - -class NSDictionaryMLegacySyntheticFrontEnd : public SyntheticChildrenFrontEnd { -public: - NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); - - ~NSDictionaryMLegacySyntheticFrontEnd() override; - - size_t CalculateNumChildren() override; - - lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; - - bool Update() override; - - bool MightHaveChildren() override; - - size_t GetIndexOfChildWithName(const ConstString &name) override; - -private: + +namespace Foundation1100 { + class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd { + public: + NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + ~NSDictionaryMSyntheticFrontEnd() override; + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(const ConstString &name) override; + + private: + struct DataDescriptor_32 { + uint32_t _used : 26; + uint32_t _kvo : 1; + uint32_t _size; + uint32_t _mutations; + uint32_t _objs_addr; + uint32_t _keys_addr; + }; + + struct DataDescriptor_64 { + uint64_t _used : 58; + uint32_t _kvo : 1; + uint64_t _size; + uint64_t _mutations; + uint64_t _objs_addr; + uint64_t _keys_addr; + }; + + struct DictionaryItemDescriptor { + lldb::addr_t key_ptr; + lldb::addr_t val_ptr; + lldb::ValueObjectSP valobj_sp; + }; + + ExecutionContextRef m_exe_ctx_ref; + uint8_t m_ptr_size; + lldb::ByteOrder m_order; + DataDescriptor_32 *m_data_32; + DataDescriptor_64 *m_data_64; + CompilerType m_pair_type; + std::vector m_children; + }; +}; + +namespace Foundation1428 { struct DataDescriptor_32 { uint32_t _used : 26; uint32_t _kvo : 1; uint32_t _size; - uint32_t _mutations; - uint32_t _objs_addr; - uint32_t _keys_addr; + uint32_t _buffer; + uint64_t GetSize() { return _size; } }; - + struct DataDescriptor_64 { uint64_t _used : 58; uint32_t _kvo : 1; uint64_t _size; - uint64_t _mutations; - uint64_t _objs_addr; - uint64_t _keys_addr; + uint64_t _buffer; + uint64_t GetSize() { return _size; } }; - - struct DictionaryItemDescriptor { - lldb::addr_t key_ptr; - lldb::addr_t val_ptr; - lldb::ValueObjectSP valobj_sp; + + + + using NSDictionaryMSyntheticFrontEnd = + GenericNSDictionaryMSyntheticFrontEnd; +}; + +namespace Foundation1437 { + static const uint64_t NSDictionaryCapacities[] = { + 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723, + 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607, + 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119, + 6221311, 10066421, 16287743, 26354171, 42641881, 68996069, + 111638519, 180634607, 292272623, 472907251 + }; + + static const size_t NSDictionaryNumSizeBuckets = sizeof(NSDictionaryCapacities) / sizeof(uint64_t); + + struct DataDescriptor_32 { + uint32_t _buffer; + union { + struct { + uint32_t _mutations; + }; + struct { + uint32_t _muts; + uint32_t _used:25; + uint32_t _kvo:1; + uint32_t _szidx:6; + }; + }; + + uint64_t GetSize() { + return (_szidx) >= NSDictionaryNumSizeBuckets ? + 0 : NSDictionaryCapacities[_szidx]; + } }; + + struct DataDescriptor_64 { + uint64_t _buffer; + union { + struct { + uint64_t _mutations; + }; + struct { + uint32_t _muts; + uint32_t _used:25; + uint32_t _kvo:1; + uint32_t _szidx:6; + }; + }; + + uint64_t GetSize() { + return (_szidx) >= NSDictionaryNumSizeBuckets ? + 0 : NSDictionaryCapacities[_szidx]; + } + }; + + using NSDictionaryMSyntheticFrontEnd = + GenericNSDictionaryMSyntheticFrontEnd; + + template + uint64_t + __NSDictionaryMSize_Impl(lldb_private::Process &process, + lldb::addr_t valobj_addr, Status &error) { + const lldb::addr_t start_of_descriptor = + valobj_addr + process.GetAddressByteSize(); + DD descriptor = DD(); + process.ReadMemory(start_of_descriptor, &descriptor, sizeof(descriptor), + error); + if (error.Fail()) { + return 0; + } + return descriptor._used; + } + + uint64_t + __NSDictionaryMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, + Status &error) { + if (process.GetAddressByteSize() == 4) { + return __NSDictionaryMSize_Impl(process, valobj_addr, + error); + } else { + return __NSDictionaryMSize_Impl(process, valobj_addr, + error); + } + } - ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - lldb::ByteOrder m_order; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; - CompilerType m_pair_type; - std::vector m_children; }; } // namespace formatters } // namespace lldb_private @@ -313,12 +408,19 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) { + AppleObjCRuntime *apple_runtime = + llvm::dyn_cast_or_null(runtime); Status error; - value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, - ptr_size, 0, error); + if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) { + value = Foundation1437::__NSDictionaryMSize(*process_sp, valobj_addr, + error); + } else { + value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, + ptr_size, 0, error); + value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); + } if (error.Fail()) return false; - value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } else if (class_name == g_Dictionary1) { value = 1; } @@ -396,13 +498,15 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( if (class_name == g_DictionaryI) { return (new NSDictionaryISyntheticFrontEnd(valobj_sp)); } else if (class_name == g_DictionaryM) { - if (runtime->GetFoundationVersion() > 1400) { - return (new NSDictionaryMSyntheticFrontEnd(valobj_sp)); + if (runtime->GetFoundationVersion() >= 1437) { + return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp)); + } else if (runtime->GetFoundationVersion() >= 1428) { + return (new Foundation1428::NSDictionaryMSyntheticFrontEnd(valobj_sp)); } else { - return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp)); + return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp)); } } else if (class_name == g_DictionaryMLegacy) { - return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp)); + return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp)); } else if (class_name == g_Dictionary1) { return (new NSDictionary1SyntheticFrontEnd(valobj_sp)); } else { @@ -641,22 +745,25 @@ lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex( return m_pair; } -lldb_private::formatters::NSDictionaryMSyntheticFrontEnd:: - NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +template +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: + GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr), m_pair_type() {} -lldb_private::formatters::NSDictionaryMSyntheticFrontEnd:: - ~NSDictionaryMSyntheticFrontEnd() { +template +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: + ~GenericNSDictionaryMSyntheticFrontEnd() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; m_data_64 = nullptr; } -size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd:: - GetIndexOfChildWithName(const ConstString &name) { +template +size_t +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: GetIndexOfChildWithName(const ConstString &name) { const char *item_name = name.GetCString(); uint32_t idx = ExtractIndexFromString(item_name); if (idx < UINT32_MAX && idx >= CalculateNumChildren()) @@ -664,14 +771,18 @@ size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd:: return idx; } -size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd:: - CalculateNumChildren() { +template +size_t +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd::CalculateNumChildren() { if (!m_data_32 && !m_data_64) return 0; - return (m_data_32 ? m_data_32->used : m_data_64->used); + return (m_data_32 ? m_data_32->_used : m_data_64->_used); } -bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() { +template +bool +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: + Update() { m_children.clear(); ValueObjectSP valobj_sp = m_backend.GetSP(); m_ptr_size = 0; @@ -691,12 +802,12 @@ bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() { m_order = process_sp->GetByteOrder(); uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; if (m_ptr_size == 4) { - m_data_32 = new DataDescriptor_32(); - process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32), + m_data_32 = new D32(); + process_sp->ReadMemory(data_location, m_data_32, sizeof(D32), error); } else { - m_data_64 = new DataDescriptor_64(); - process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64), + m_data_64 = new D64(); + process_sp->ReadMemory(data_location, m_data_64, sizeof(D64), error); } if (error.Fail()) @@ -704,24 +815,28 @@ bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() { return false; } -bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd:: +template +bool +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: MightHaveChildren() { return true; } +template lldb::ValueObjectSP -lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex( +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd:: + GetChildAtIndex( size_t idx) { lldb::addr_t m_keys_ptr; lldb::addr_t m_values_ptr; if (m_data_32) { - uint32_t size = m_data_32->size; - m_keys_ptr = m_data_32->buffer; - m_values_ptr = m_data_32->buffer + (m_ptr_size * size); + uint32_t size = m_data_32->GetSize(); + m_keys_ptr = m_data_32->_buffer; + m_values_ptr = m_data_32->_buffer + (m_ptr_size * size); } else { - uint32_t size = m_data_64->size; - m_keys_ptr = m_data_64->buffer; - m_values_ptr = m_data_64->buffer + (m_ptr_size * size); + uint32_t size = m_data_64->GetSize(); + m_keys_ptr = m_data_64->_buffer; + m_values_ptr = m_data_64->_buffer + (m_ptr_size * size); } uint32_t num_children = CalculateNumChildren(); @@ -800,22 +915,24 @@ lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex( } -lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd:: - NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +lldb_private::formatters::Foundation1100:: + NSDictionaryMSyntheticFrontEnd:: + NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr), m_pair_type() {} -lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd:: - ~NSDictionaryMLegacySyntheticFrontEnd() { +lldb_private::formatters::Foundation1100:: + NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; m_data_64 = nullptr; } -size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd:: - GetIndexOfChildWithName(const ConstString &name) { +size_t +lldb_private::formatters::Foundation1100:: + NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name) { const char *item_name = name.GetCString(); uint32_t idx = ExtractIndexFromString(item_name); if (idx < UINT32_MAX && idx >= CalculateNumChildren()) @@ -823,14 +940,17 @@ size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd:: return idx; } -size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd:: - CalculateNumChildren() { +size_t +lldb_private::formatters::Foundation1100:: + NSDictionaryMSyntheticFrontEnd::CalculateNumChildren() { if (!m_data_32 && !m_data_64) return 0; return (m_data_32 ? m_data_32->_used : m_data_64->_used); } -bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::Update() { +bool +lldb_private::formatters::Foundation1100:: + NSDictionaryMSyntheticFrontEnd::Update() { m_children.clear(); ValueObjectSP valobj_sp = m_backend.GetSP(); m_ptr_size = 0; @@ -863,14 +983,15 @@ bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::Update() { return false; } -bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd:: - MightHaveChildren() { +bool +lldb_private::formatters::Foundation1100:: + NSDictionaryMSyntheticFrontEnd::MightHaveChildren() { return true; } lldb::ValueObjectSP -lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::GetChildAtIndex( - size_t idx) { +lldb_private::formatters::Foundation1100:: + NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(size_t idx) { lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr); lldb::addr_t m_values_ptr = diff --git a/source/Plugins/Language/ObjC/NSSet.cpp b/source/Plugins/Language/ObjC/NSSet.cpp index 2f3398775..fa2483ecc 100644 --- a/source/Plugins/Language/ObjC/NSSet.cpp +++ b/source/Plugins/Language/ObjC/NSSet.cpp @@ -135,7 +135,7 @@ namespace Foundation1300 { GenericNSSetMSyntheticFrontEnd; } -namespace Foundation1400 { +namespace Foundation1428 { struct DataDescriptor_32 { uint32_t _used : 26; uint32_t _size; @@ -154,6 +154,64 @@ namespace Foundation1400 { GenericNSSetMSyntheticFrontEnd; } +namespace Foundation1437 { + struct DataDescriptor_32 { + uint32_t _cow; + // __table storage + uint32_t _objs_addr; + union { + uint32_t _mutations; + struct { + uint32_t _muts; + uint32_t _used : 26; + uint32_t _szidx : 6; + }; + }; + }; + + struct DataDescriptor_64 { + uint64_t _cow; + // __Table storage + uint64_t _objs_addr; + union { + uint64_t _mutations; + struct { + uint32_t _muts; + uint32_t _used : 26; + uint32_t _szidx : 6; + }; + }; + }; + + using NSSetMSyntheticFrontEnd = + GenericNSSetMSyntheticFrontEnd; + + template + uint64_t + __NSSetMSize_Impl(lldb_private::Process &process, lldb::addr_t valobj_addr, + Status &error) { + const lldb::addr_t start_of_descriptor = + valobj_addr + process.GetAddressByteSize(); + DD descriptor = DD(); + process.ReadMemory(start_of_descriptor, &descriptor, sizeof(descriptor), + error); + if (error.Fail()) { + return 0; + } + return descriptor._used; + } + + uint64_t + __NSSetMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, + Status &error) { + if (process.GetAddressByteSize() == 4) { + return __NSSetMSize_Impl(process, valobj_addr, error); + } else { + return __NSSetMSize_Impl(process, valobj_addr, error); + } + } +} + class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); @@ -219,12 +277,18 @@ bool lldb_private::formatters::NSSetSummaryProvider( return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } else if (!strcmp(class_name, "__NSSetM")) { + AppleObjCRuntime *apple_runtime = + llvm::dyn_cast_or_null(runtime); Status error; - value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, - ptr_size, 0, error); + if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) { + value = Foundation1437::__NSSetMSize(*process_sp, valobj_addr, error); + } else { + value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, + ptr_size, 0, error); + value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); + } if (error.Fail()) return false; - value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } /*else if (!strcmp(class_name,"__NSCFSet")) { @@ -312,10 +376,16 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator( } else if (!strcmp(class_name, "__NSSetM")) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null(runtime); - if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1400) - return (new Foundation1400::NSSetMSyntheticFrontEnd(valobj_sp)); - else + if (apple_runtime) { + if (apple_runtime->GetFoundationVersion() >= 1437) + return (new Foundation1437::NSSetMSyntheticFrontEnd(valobj_sp)); + else if (apple_runtime->GetFoundationVersion() >= 1428) + return (new Foundation1428::NSSetMSyntheticFrontEnd(valobj_sp)); + else + return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp)); + } else { return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp)); + } } else { auto &map(NSSet_Additionals::GetAdditionalSynthetics()); auto iter = map.find(class_name_cs), end = map.end(); -- cgit v1.2.3