diff options
Diffstat (limited to 'source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h')
-rw-r--r-- | source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h | 665 |
1 files changed, 294 insertions, 371 deletions
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h index f5fc8bc0644b..787423b54766 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h @@ -16,397 +16,320 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" -#include "lldb/Target/ObjCLanguageRuntime.h" #include "AppleObjCRuntimeV2.h" +#include "lldb/Target/ObjCLanguageRuntime.h" +#include "lldb/lldb-private.h" namespace lldb_private { -class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor -{ +class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor { public: - friend class lldb_private::AppleObjCRuntimeV2; - - ~ClassDescriptorV2() override = default; - - ConstString - GetClassName() override; - - ObjCLanguageRuntime::ClassDescriptorSP - GetSuperclass() override; - - ObjCLanguageRuntime::ClassDescriptorSP - GetMetaclass() const override; - - bool - IsValid() override - { - return true; // any Objective-C v2 runtime class descriptor we vend is valid - } - - // a custom descriptor is used for tagged pointers - bool - GetTaggedPointerInfo(uint64_t* info_bits = nullptr, - uint64_t* value_bits = nullptr, - uint64_t* payload = nullptr) override - { - return false; - } - - uint64_t - GetInstanceSize() override; - - ObjCLanguageRuntime::ObjCISA - GetISA() override - { - return m_objc_class_ptr; - } - - bool - Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func, - std::function <bool (const char *, const char *)> const &instance_method_func, - std::function <bool (const char *, const char *)> const &class_method_func, - std::function <bool (const char *, const char *, - lldb::addr_t, uint64_t)> const &ivar_func) const override; - - size_t - GetNumIVars() override - { - GetIVarInformation(); - return m_ivars_storage.size(); - } - - iVarDescriptor - GetIVarAtIndex(size_t idx) override - { - if (idx >= GetNumIVars()) - return iVarDescriptor(); - return m_ivars_storage[idx]; - } - + friend class lldb_private::AppleObjCRuntimeV2; + + ~ClassDescriptorV2() override = default; + + ConstString GetClassName() override; + + ObjCLanguageRuntime::ClassDescriptorSP GetSuperclass() override; + + ObjCLanguageRuntime::ClassDescriptorSP GetMetaclass() const override; + + bool IsValid() override { + return true; // any Objective-C v2 runtime class descriptor we vend is valid + } + + // a custom descriptor is used for tagged pointers + bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr, + uint64_t *value_bits = nullptr, + uint64_t *payload = nullptr) override { + return false; + } + + uint64_t GetInstanceSize() override; + + ObjCLanguageRuntime::ObjCISA GetISA() override { return m_objc_class_ptr; } + + bool Describe( + std::function<void(ObjCLanguageRuntime::ObjCISA)> const &superclass_func, + std::function<bool(const char *, const char *)> const + &instance_method_func, + std::function<bool(const char *, const char *)> const &class_method_func, + std::function<bool(const char *, const char *, lldb::addr_t, + uint64_t)> const &ivar_func) const override; + + size_t GetNumIVars() override { + GetIVarInformation(); + return m_ivars_storage.size(); + } + + iVarDescriptor GetIVarAtIndex(size_t idx) override { + if (idx >= GetNumIVars()) + return iVarDescriptor(); + return m_ivars_storage[idx]; + } + protected: - void - GetIVarInformation (); - + void GetIVarInformation(); + private: - static const uint32_t RW_REALIZED = (1 << 31); - - struct objc_class_t { - ObjCLanguageRuntime::ObjCISA m_isa; // The class's metaclass. - ObjCLanguageRuntime::ObjCISA m_superclass; - lldb::addr_t m_cache_ptr; - lldb::addr_t m_vtable_ptr; - lldb::addr_t m_data_ptr; - uint8_t m_flags; - - objc_class_t () : - m_isa (0), - m_superclass (0), - m_cache_ptr (0), - m_vtable_ptr (0), - m_data_ptr (0), - m_flags (0) - { - } - - void - Clear() - { - m_isa = 0; - m_superclass = 0; - m_cache_ptr = 0; - m_vtable_ptr = 0; - m_data_ptr = 0; - m_flags = 0; - } - - bool - Read(Process *process, lldb::addr_t addr); - }; - - struct class_ro_t { - uint32_t m_flags; - uint32_t m_instanceStart; - uint32_t m_instanceSize; - uint32_t m_reserved; - - lldb::addr_t m_ivarLayout_ptr; - lldb::addr_t m_name_ptr; - lldb::addr_t m_baseMethods_ptr; - lldb::addr_t m_baseProtocols_ptr; - lldb::addr_t m_ivars_ptr; - - lldb::addr_t m_weakIvarLayout_ptr; - lldb::addr_t m_baseProperties_ptr; - - std::string m_name; - - bool - Read(Process *process, lldb::addr_t addr); - }; - - struct class_rw_t { - uint32_t m_flags; - uint32_t m_version; - - lldb::addr_t m_ro_ptr; - union { - lldb::addr_t m_method_list_ptr; - lldb::addr_t m_method_lists_ptr; - }; - lldb::addr_t m_properties_ptr; - lldb::addr_t m_protocols_ptr; - - ObjCLanguageRuntime::ObjCISA m_firstSubclass; - ObjCLanguageRuntime::ObjCISA m_nextSiblingClass; - - bool - Read(Process *process, lldb::addr_t addr); - }; - - struct method_list_t - { - uint32_t m_entsize; - uint32_t m_count; - lldb::addr_t m_first_ptr; - - bool - Read(Process *process, lldb::addr_t addr); - }; - - struct method_t - { - lldb::addr_t m_name_ptr; - lldb::addr_t m_types_ptr; - lldb::addr_t m_imp_ptr; - - std::string m_name; - std::string m_types; - - static size_t GetSize(Process *process) - { - size_t ptr_size = process->GetAddressByteSize(); - - return ptr_size // SEL name; - + ptr_size // const char *types; - + ptr_size; // IMP imp; - } - - bool - Read(Process *process, lldb::addr_t addr); - }; - - struct ivar_list_t - { - uint32_t m_entsize; - uint32_t m_count; - lldb::addr_t m_first_ptr; - - bool Read(Process *process, lldb::addr_t addr); - }; - - struct ivar_t - { - lldb::addr_t m_offset_ptr; - lldb::addr_t m_name_ptr; - lldb::addr_t m_type_ptr; - uint32_t m_alignment; - uint32_t m_size; - - std::string m_name; - std::string m_type; - - static size_t GetSize(Process *process) - { - size_t ptr_size = process->GetAddressByteSize(); - - return ptr_size // uintptr_t *offset; - + ptr_size // const char *name; - + ptr_size // const char *type; - + sizeof(uint32_t) // uint32_t alignment; - + sizeof(uint32_t); // uint32_t size; - } - - bool - Read(Process *process, lldb::addr_t addr); - }; - - class iVarsStorage - { - public: - iVarsStorage (); - - size_t - size (); - - iVarDescriptor& - operator[] (size_t idx); - - void - fill (AppleObjCRuntimeV2& runtime, ClassDescriptorV2& descriptor); - - private: - bool m_filled; - std::vector<iVarDescriptor> m_ivars; - std::recursive_mutex m_mutex; + static const uint32_t RW_REALIZED = (1 << 31); + + struct objc_class_t { + ObjCLanguageRuntime::ObjCISA m_isa; // The class's metaclass. + ObjCLanguageRuntime::ObjCISA m_superclass; + lldb::addr_t m_cache_ptr; + lldb::addr_t m_vtable_ptr; + lldb::addr_t m_data_ptr; + uint8_t m_flags; + + objc_class_t() + : m_isa(0), m_superclass(0), m_cache_ptr(0), m_vtable_ptr(0), + m_data_ptr(0), m_flags(0) {} + + void Clear() { + m_isa = 0; + m_superclass = 0; + m_cache_ptr = 0; + m_vtable_ptr = 0; + m_data_ptr = 0; + m_flags = 0; + } + + bool Read(Process *process, lldb::addr_t addr); + }; + + struct class_ro_t { + uint32_t m_flags; + uint32_t m_instanceStart; + uint32_t m_instanceSize; + uint32_t m_reserved; + + lldb::addr_t m_ivarLayout_ptr; + lldb::addr_t m_name_ptr; + lldb::addr_t m_baseMethods_ptr; + lldb::addr_t m_baseProtocols_ptr; + lldb::addr_t m_ivars_ptr; + + lldb::addr_t m_weakIvarLayout_ptr; + lldb::addr_t m_baseProperties_ptr; + + std::string m_name; + + bool Read(Process *process, lldb::addr_t addr); + }; + + struct class_rw_t { + uint32_t m_flags; + uint32_t m_version; + + lldb::addr_t m_ro_ptr; + union { + lldb::addr_t m_method_list_ptr; + lldb::addr_t m_method_lists_ptr; }; - - // The constructor should only be invoked by the runtime as it builds its caches - // or populates them. A ClassDescriptorV2 should only ever exist in a cache. - ClassDescriptorV2(AppleObjCRuntimeV2 &runtime, ObjCLanguageRuntime::ObjCISA isa, const char *name) : - m_runtime (runtime), - m_objc_class_ptr (isa), - m_name (name), - m_ivars_storage() - { + lldb::addr_t m_properties_ptr; + lldb::addr_t m_protocols_ptr; + + ObjCLanguageRuntime::ObjCISA m_firstSubclass; + ObjCLanguageRuntime::ObjCISA m_nextSiblingClass; + + bool Read(Process *process, lldb::addr_t addr); + }; + + struct method_list_t { + uint32_t m_entsize; + uint32_t m_count; + lldb::addr_t m_first_ptr; + + bool Read(Process *process, lldb::addr_t addr); + }; + + struct method_t { + lldb::addr_t m_name_ptr; + lldb::addr_t m_types_ptr; + lldb::addr_t m_imp_ptr; + + std::string m_name; + std::string m_types; + + static size_t GetSize(Process *process) { + size_t ptr_size = process->GetAddressByteSize(); + + return ptr_size // SEL name; + + ptr_size // const char *types; + + ptr_size; // IMP imp; + } + + bool Read(Process *process, lldb::addr_t addr); + }; + + struct ivar_list_t { + uint32_t m_entsize; + uint32_t m_count; + lldb::addr_t m_first_ptr; + + bool Read(Process *process, lldb::addr_t addr); + }; + + struct ivar_t { + lldb::addr_t m_offset_ptr; + lldb::addr_t m_name_ptr; + lldb::addr_t m_type_ptr; + uint32_t m_alignment; + uint32_t m_size; + + std::string m_name; + std::string m_type; + + static size_t GetSize(Process *process) { + size_t ptr_size = process->GetAddressByteSize(); + + return ptr_size // uintptr_t *offset; + + ptr_size // const char *name; + + ptr_size // const char *type; + + sizeof(uint32_t) // uint32_t alignment; + + sizeof(uint32_t); // uint32_t size; } - - bool - Read_objc_class (Process* process, std::unique_ptr<objc_class_t> &objc_class) const; - - bool - Read_class_row (Process* process, const objc_class_t &objc_class, std::unique_ptr<class_ro_t> &class_ro, std::unique_ptr<class_rw_t> &class_rw) const; - - AppleObjCRuntimeV2 &m_runtime; // The runtime, so we can read information lazily. - lldb::addr_t m_objc_class_ptr; // The address of the objc_class_t. (I.e., objects of this class type have this as their ISA) - ConstString m_name; // May be NULL - iVarsStorage m_ivars_storage; + + bool Read(Process *process, lldb::addr_t addr); + }; + + class iVarsStorage { + public: + iVarsStorage(); + + size_t size(); + + iVarDescriptor &operator[](size_t idx); + + void fill(AppleObjCRuntimeV2 &runtime, ClassDescriptorV2 &descriptor); + + private: + bool m_filled; + std::vector<iVarDescriptor> m_ivars; + std::recursive_mutex m_mutex; + }; + + // The constructor should only be invoked by the runtime as it builds its + // caches + // or populates them. A ClassDescriptorV2 should only ever exist in a cache. + ClassDescriptorV2(AppleObjCRuntimeV2 &runtime, + ObjCLanguageRuntime::ObjCISA isa, const char *name) + : m_runtime(runtime), m_objc_class_ptr(isa), m_name(name), + m_ivars_storage() {} + + bool Read_objc_class(Process *process, + std::unique_ptr<objc_class_t> &objc_class) const; + + bool Read_class_row(Process *process, const objc_class_t &objc_class, + std::unique_ptr<class_ro_t> &class_ro, + std::unique_ptr<class_rw_t> &class_rw) const; + + AppleObjCRuntimeV2 + &m_runtime; // The runtime, so we can read information lazily. + lldb::addr_t m_objc_class_ptr; // The address of the objc_class_t. (I.e., + // objects of this class type have this as + // their ISA) + ConstString m_name; // May be NULL + iVarsStorage m_ivars_storage; }; // tagged pointer descriptor -class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor -{ +class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor { public: - ClassDescriptorV2Tagged (ConstString class_name, - uint64_t payload) - { - m_name = class_name; - if (!m_name) - { - m_valid = false; - return; - } - m_valid = true; - m_payload = payload; - m_info_bits = (m_payload & 0xF0ULL) >> 4; - m_value_bits = (m_payload & ~0x0000000000000000FFULL) >> 8; + ClassDescriptorV2Tagged(ConstString class_name, uint64_t payload) { + m_name = class_name; + if (!m_name) { + m_valid = false; + return; } - - ClassDescriptorV2Tagged (ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp, - uint64_t payload) - { - if (!actual_class_sp) - { - m_valid = false; - return; - } - m_name = actual_class_sp->GetClassName(); - if (!m_name) - { - m_valid = false; - return; - } - m_valid = true; - m_payload = payload; - m_info_bits = (m_payload & 0x0FULL); - m_value_bits = (m_payload & ~0x0FULL) >> 4; - } - - ~ClassDescriptorV2Tagged() override = default; + m_valid = true; + m_payload = payload; + m_info_bits = (m_payload & 0xF0ULL) >> 4; + m_value_bits = (m_payload & ~0x0000000000000000FFULL) >> 8; + } - ConstString - GetClassName() override - { - return m_name; - } - - ObjCLanguageRuntime::ClassDescriptorSP - GetSuperclass() override - { - // tagged pointers can represent a class that has a superclass, but since that information is not - // stored in the object itself, we would have to query the runtime to discover the hierarchy - // for the time being, we skip this step in the interest of static discovery - return ObjCLanguageRuntime::ClassDescriptorSP(); + ClassDescriptorV2Tagged( + ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp, + uint64_t payload) { + if (!actual_class_sp) { + m_valid = false; + return; } - - ObjCLanguageRuntime::ClassDescriptorSP - GetMetaclass() const override - { - return ObjCLanguageRuntime::ClassDescriptorSP(); - } - - bool - IsValid() override - { - return m_valid; - } - - bool - IsKVO() override - { - return false; // tagged pointers are not KVO'ed - } - - bool - IsCFType() override - { - return false; // tagged pointers are not CF objects - } - - bool - GetTaggedPointerInfo(uint64_t* info_bits = nullptr, - uint64_t* value_bits = nullptr, - uint64_t* payload = nullptr) override - { - if (info_bits) - *info_bits = GetInfoBits(); - if (value_bits) - *value_bits = GetValueBits(); - if (payload) - *payload = GetPayload(); - return true; - } - - uint64_t - GetInstanceSize() override - { - return (IsValid() ? m_pointer_size : 0); - } - - ObjCLanguageRuntime::ObjCISA - GetISA() override - { - return 0; // tagged pointers have no ISA - } - - // these calls are not part of any formal tagged pointers specification - virtual uint64_t - GetValueBits () - { - return (IsValid() ? m_value_bits : 0); - } - - virtual uint64_t - GetInfoBits () - { - return (IsValid() ? m_info_bits : 0); - } - - virtual uint64_t - GetPayload () - { - return (IsValid() ? m_payload : 0); + m_name = actual_class_sp->GetClassName(); + if (!m_name) { + m_valid = false; + return; } + m_valid = true; + m_payload = payload; + m_info_bits = (m_payload & 0x0FULL); + m_value_bits = (m_payload & ~0x0FULL) >> 4; + } + + ~ClassDescriptorV2Tagged() override = default; + + ConstString GetClassName() override { return m_name; } + + ObjCLanguageRuntime::ClassDescriptorSP GetSuperclass() override { + // tagged pointers can represent a class that has a superclass, but since + // that information is not + // stored in the object itself, we would have to query the runtime to + // discover the hierarchy + // for the time being, we skip this step in the interest of static discovery + return ObjCLanguageRuntime::ClassDescriptorSP(); + } + + ObjCLanguageRuntime::ClassDescriptorSP GetMetaclass() const override { + return ObjCLanguageRuntime::ClassDescriptorSP(); + } + + bool IsValid() override { return m_valid; } + + bool IsKVO() override { + return false; // tagged pointers are not KVO'ed + } + + bool IsCFType() override { + return false; // tagged pointers are not CF objects + } + + bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr, + uint64_t *value_bits = nullptr, + uint64_t *payload = nullptr) override { + if (info_bits) + *info_bits = GetInfoBits(); + if (value_bits) + *value_bits = GetValueBits(); + if (payload) + *payload = GetPayload(); + return true; + } + + uint64_t GetInstanceSize() override { + return (IsValid() ? m_pointer_size : 0); + } + + ObjCLanguageRuntime::ObjCISA GetISA() override { + return 0; // tagged pointers have no ISA + } + + // these calls are not part of any formal tagged pointers specification + virtual uint64_t GetValueBits() { return (IsValid() ? m_value_bits : 0); } + + virtual uint64_t GetInfoBits() { return (IsValid() ? m_info_bits : 0); } + + virtual uint64_t GetPayload() { return (IsValid() ? m_payload : 0); } private: - ConstString m_name; - uint8_t m_pointer_size; - bool m_valid; - uint64_t m_info_bits; - uint64_t m_value_bits; - uint64_t m_payload; + ConstString m_name; + uint8_t m_pointer_size; + bool m_valid; + uint64_t m_info_bits; + uint64_t m_value_bits; + uint64_t m_payload; }; - + } // namespace lldb_private #endif // liblldb_AppleObjCClassDescriptorV2_h_ |