diff options
Diffstat (limited to 'lldb/source/Plugins/Language/ObjC/NSDictionary.cpp')
-rw-r--r-- | lldb/source/Plugins/Language/ObjC/NSDictionary.cpp | 317 |
1 files changed, 219 insertions, 98 deletions
diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp index 50febbe3975..4c98580d210 100644 --- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -165,11 +165,12 @@ private: ValueObjectSP m_pair; }; -class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +template <typename D32, typename D64> +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<DictionaryItemDescriptor> 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<DictionaryItemDescriptor> 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<DataDescriptor_32, DataDescriptor_64>; +}; + +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<DataDescriptor_32, DataDescriptor_64>; + + template <typename DD> + 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<DataDescriptor_32>(process, valobj_addr, + error); + } else { + return __NSDictionaryMSize_Impl<DataDescriptor_64>(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<DictionaryItemDescriptor> 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<AppleObjCRuntime>(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 <typename D32, typename D64> +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: + 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 <typename D32, typename D64> +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: + ~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 <typename D32, typename D64> +size_t +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: 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 <typename D32, typename D64> +size_t +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::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 <typename D32, typename D64> +bool +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: + 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 <typename D32, typename D64> +bool +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: MightHaveChildren() { return true; } +template <typename D32, typename D64> lldb::ValueObjectSP -lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex( +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: + 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 = |