diff options
Diffstat (limited to 'source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp')
-rw-r--r-- | source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp | 711 |
1 files changed, 345 insertions, 366 deletions
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index 805fca7a31b9..13bd245a33b4 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -1,4 +1,5 @@ -//===-- AppleObjCRuntimeV1.cpp --------------------------------------*- C++ -*-===// +//===-- AppleObjCRuntimeV1.cpp --------------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -8,8 +9,8 @@ //===----------------------------------------------------------------------===// #include "AppleObjCRuntimeV1.h" -#include "AppleObjCTrampolineHandler.h" #include "AppleObjCDeclVendor.h" +#include "AppleObjCTrampolineHandler.h" #include "clang/AST/Type.h" @@ -36,425 +37,403 @@ using namespace lldb; using namespace lldb_private; -AppleObjCRuntimeV1::AppleObjCRuntimeV1(Process *process) : - AppleObjCRuntime (process), - m_hash_signature (), - m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS) -{ -} +AppleObjCRuntimeV1::AppleObjCRuntimeV1(Process *process) + : AppleObjCRuntime(process), m_hash_signature(), + m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS) {} -// for V1 runtime we just try to return a class name as that is the minimum level of support +// for V1 runtime we just try to return a class name as that is the minimum +// level of support // required for the data formatters to work -bool -AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value, - lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, - Address &address, - Value::ValueType &value_type) -{ - class_type_or_name.Clear(); - value_type = Value::ValueType::eValueTypeScalar; - if (CouldHaveDynamicValue(in_value)) - { - auto class_descriptor(GetClassDescriptor(in_value)); - if (class_descriptor && class_descriptor->IsValid() && class_descriptor->GetClassName()) - { - const addr_t object_ptr = in_value.GetPointerValue(); - address.SetRawAddress(object_ptr); - class_type_or_name.SetName(class_descriptor->GetClassName()); - } +bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress( + ValueObject &in_value, lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, Address &address, + Value::ValueType &value_type) { + class_type_or_name.Clear(); + value_type = Value::ValueType::eValueTypeScalar; + if (CouldHaveDynamicValue(in_value)) { + auto class_descriptor(GetClassDescriptor(in_value)); + if (class_descriptor && class_descriptor->IsValid() && + class_descriptor->GetClassName()) { + const addr_t object_ptr = in_value.GetPointerValue(); + address.SetRawAddress(object_ptr); + class_type_or_name.SetName(class_descriptor->GetClassName()); } - return class_type_or_name.IsEmpty() == false; + } + return class_type_or_name.IsEmpty() == false; } //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ lldb_private::LanguageRuntime * -AppleObjCRuntimeV1::CreateInstance (Process *process, lldb::LanguageType language) -{ - // FIXME: This should be a MacOS or iOS process, and we need to look for the OBJC section to make - // sure we aren't using the V1 runtime. - if (language == eLanguageTypeObjC) - { - ModuleSP objc_module_sp; - - if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == ObjCRuntimeVersions::eAppleObjC_V1) - return new AppleObjCRuntimeV1 (process); - else - return NULL; - } +AppleObjCRuntimeV1::CreateInstance(Process *process, + lldb::LanguageType language) { + // FIXME: This should be a MacOS or iOS process, and we need to look for the + // OBJC section to make + // sure we aren't using the V1 runtime. + if (language == eLanguageTypeObjC) { + ModuleSP objc_module_sp; + + if (AppleObjCRuntime::GetObjCVersion(process, objc_module_sp) == + ObjCRuntimeVersions::eAppleObjC_V1) + return new AppleObjCRuntimeV1(process); else - return NULL; + return NULL; + } else + return NULL; } - -void -AppleObjCRuntimeV1::Initialize() -{ - PluginManager::RegisterPlugin (GetPluginNameStatic(), - "Apple Objective C Language Runtime - Version 1", - CreateInstance); +void AppleObjCRuntimeV1::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "Apple Objective C Language Runtime - Version 1", + CreateInstance); } -void -AppleObjCRuntimeV1::Terminate() -{ - PluginManager::UnregisterPlugin (CreateInstance); +void AppleObjCRuntimeV1::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString -AppleObjCRuntimeV1::GetPluginNameStatic() -{ - static ConstString g_name("apple-objc-v1"); - return g_name; +lldb_private::ConstString AppleObjCRuntimeV1::GetPluginNameStatic() { + static ConstString g_name("apple-objc-v1"); + return g_name; } //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ -ConstString -AppleObjCRuntimeV1::GetPluginName() -{ - return GetPluginNameStatic(); +ConstString AppleObjCRuntimeV1::GetPluginName() { + return GetPluginNameStatic(); } -uint32_t -AppleObjCRuntimeV1::GetPluginVersion() -{ - return 1; -} +uint32_t AppleObjCRuntimeV1::GetPluginVersion() { return 1; } BreakpointResolverSP -AppleObjCRuntimeV1::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp) -{ - BreakpointResolverSP resolver_sp; - - if (throw_bp) - resolver_sp.reset (new BreakpointResolverName (bkpt, - "objc_exception_throw", - eFunctionNameTypeBase, - eLanguageTypeUnknown, - Breakpoint::Exact, - 0, - eLazyBoolNo)); - // FIXME: don't do catch yet. - return resolver_sp; +AppleObjCRuntimeV1::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, + bool throw_bp) { + BreakpointResolverSP resolver_sp; + + if (throw_bp) + resolver_sp.reset(new BreakpointResolverName( + bkpt, "objc_exception_throw", eFunctionNameTypeBase, + eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo)); + // FIXME: don't do catch yet. + return resolver_sp; } struct BufStruct { - char contents[2048]; + char contents[2048]; }; -UtilityFunction * -AppleObjCRuntimeV1::CreateObjectChecker(const char *name) -{ - std::unique_ptr<BufStruct> buf(new BufStruct); - - assert(snprintf(&buf->contents[0], sizeof(buf->contents), - "struct __objc_class \n" - "{ \n" - " struct __objc_class *isa; \n" - " struct __objc_class *super_class; \n" - " const char *name; \n" - " // rest of struct elided because unused \n" - "}; \n" - " \n" - "struct __objc_object \n" - "{ \n" - " struct __objc_class *isa; \n" - "}; \n" - " \n" - "extern \"C\" void \n" - "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) \n" - "{ \n" - " struct __objc_object *obj = (struct __objc_object*)$__lldb_arg_obj; \n" - " (int)strlen(obj->isa->name); \n" - "} \n", - name) < (int)sizeof(buf->contents)); - - Error error; - return GetTargetRef().GetUtilityFunctionForLanguage(buf->contents, eLanguageTypeObjC, name, error); +UtilityFunction *AppleObjCRuntimeV1::CreateObjectChecker(const char *name) { + std::unique_ptr<BufStruct> buf(new BufStruct); + + assert(snprintf(&buf->contents[0], sizeof(buf->contents), + "struct __objc_class " + " \n" + "{ " + " \n" + " struct __objc_class *isa; " + " \n" + " struct __objc_class *super_class; " + " \n" + " const char *name; " + " \n" + " // rest of struct elided because unused " + " \n" + "}; " + " \n" + " " + " \n" + "struct __objc_object " + " \n" + "{ " + " \n" + " struct __objc_class *isa; " + " \n" + "}; " + " \n" + " " + " \n" + "extern \"C\" void " + " \n" + "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) " + " \n" + "{ " + " \n" + " struct __objc_object *obj = (struct " + "__objc_object*)$__lldb_arg_obj; \n" + " if ($__lldb_arg_obj == (void *)0) " + " \n" + " return; // nil is ok " + " (int)strlen(obj->isa->name); " + " \n" + "} " + " \n", + name) < (int)sizeof(buf->contents)); + + Error error; + return GetTargetRef().GetUtilityFunctionForLanguage( + buf->contents, eLanguageTypeObjC, name, error); } -AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ValueObject &isa_pointer) -{ - Initialize (isa_pointer.GetValueAsUnsigned(0), - isa_pointer.GetProcessSP()); +AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1( + ValueObject &isa_pointer) { + Initialize(isa_pointer.GetValueAsUnsigned(0), isa_pointer.GetProcessSP()); } -AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ObjCISA isa, lldb::ProcessSP process_sp) -{ - Initialize (isa, process_sp); +AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1( + ObjCISA isa, lldb::ProcessSP process_sp) { + Initialize(isa, process_sp); } -void -AppleObjCRuntimeV1::ClassDescriptorV1::Initialize (ObjCISA isa, lldb::ProcessSP process_sp) -{ - if (!isa || !process_sp) - { - m_valid = false; - return; - } - - m_valid = true; - - Error error; - - m_isa = process_sp->ReadPointerFromMemory(isa, error); - - if (error.Fail()) - { - m_valid = false; - return; - } - - uint32_t ptr_size = process_sp->GetAddressByteSize(); - - if (!IsPointerValid(m_isa,ptr_size)) - { - m_valid = false; - return; - } +void AppleObjCRuntimeV1::ClassDescriptorV1::Initialize( + ObjCISA isa, lldb::ProcessSP process_sp) { + if (!isa || !process_sp) { + m_valid = false; + return; + } - m_parent_isa = process_sp->ReadPointerFromMemory(m_isa + ptr_size,error); - - if (error.Fail()) - { - m_valid = false; - return; - } - - if (!IsPointerValid(m_parent_isa,ptr_size,true)) - { - m_valid = false; - return; - } - - lldb::addr_t name_ptr = process_sp->ReadPointerFromMemory(m_isa + 2 * ptr_size,error); - - if (error.Fail()) - { - m_valid = false; - return; - } - - lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); - - size_t count = process_sp->ReadCStringFromMemory(name_ptr, (char*)buffer_sp->GetBytes(), 1024, error); - - if (error.Fail()) - { - m_valid = false; - return; - } - - if (count) - m_name = ConstString((char*)buffer_sp->GetBytes()); - else - m_name = ConstString(); - - m_instance_size = process_sp->ReadUnsignedIntegerFromMemory(m_isa + 5 * ptr_size, ptr_size, 0, error); - - if (error.Fail()) - { - m_valid = false; - return; - } - - m_process_wp = lldb::ProcessWP(process_sp); + m_valid = true; + + Error error; + + m_isa = process_sp->ReadPointerFromMemory(isa, error); + + if (error.Fail()) { + m_valid = false; + return; + } + + uint32_t ptr_size = process_sp->GetAddressByteSize(); + + if (!IsPointerValid(m_isa, ptr_size)) { + m_valid = false; + return; + } + + m_parent_isa = process_sp->ReadPointerFromMemory(m_isa + ptr_size, error); + + if (error.Fail()) { + m_valid = false; + return; + } + + if (!IsPointerValid(m_parent_isa, ptr_size, true)) { + m_valid = false; + return; + } + + lldb::addr_t name_ptr = + process_sp->ReadPointerFromMemory(m_isa + 2 * ptr_size, error); + + if (error.Fail()) { + m_valid = false; + return; + } + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); + + size_t count = process_sp->ReadCStringFromMemory( + name_ptr, (char *)buffer_sp->GetBytes(), 1024, error); + + if (error.Fail()) { + m_valid = false; + return; + } + + if (count) + m_name = ConstString((char *)buffer_sp->GetBytes()); + else + m_name = ConstString(); + + m_instance_size = process_sp->ReadUnsignedIntegerFromMemory( + m_isa + 5 * ptr_size, ptr_size, 0, error); + + if (error.Fail()) { + m_valid = false; + return; + } + + m_process_wp = lldb::ProcessWP(process_sp); } AppleObjCRuntime::ClassDescriptorSP -AppleObjCRuntimeV1::ClassDescriptorV1::GetSuperclass () -{ - if (!m_valid) - return AppleObjCRuntime::ClassDescriptorSP(); - ProcessSP process_sp = m_process_wp.lock(); - if (!process_sp) - return AppleObjCRuntime::ClassDescriptorSP(); - return ObjCLanguageRuntime::ClassDescriptorSP(new AppleObjCRuntimeV1::ClassDescriptorV1(m_parent_isa,process_sp)); +AppleObjCRuntimeV1::ClassDescriptorV1::GetSuperclass() { + if (!m_valid) + return AppleObjCRuntime::ClassDescriptorSP(); + ProcessSP process_sp = m_process_wp.lock(); + if (!process_sp) + return AppleObjCRuntime::ClassDescriptorSP(); + return ObjCLanguageRuntime::ClassDescriptorSP( + new AppleObjCRuntimeV1::ClassDescriptorV1(m_parent_isa, process_sp)); } AppleObjCRuntime::ClassDescriptorSP -AppleObjCRuntimeV1::ClassDescriptorV1::GetMetaclass () const -{ - return ClassDescriptorSP(); +AppleObjCRuntimeV1::ClassDescriptorV1::GetMetaclass() const { + return ClassDescriptorSP(); } -bool -AppleObjCRuntimeV1::ClassDescriptorV1::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 -{ - return false; +bool AppleObjCRuntimeV1::ClassDescriptorV1::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 { + return false; } -lldb::addr_t -AppleObjCRuntimeV1::GetISAHashTablePointer () -{ - if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS) - { - ModuleSP objc_module_sp(GetObjCModule()); - - if (!objc_module_sp) - return LLDB_INVALID_ADDRESS; - - static ConstString g_objc_debug_class_hash("_objc_debug_class_hash"); - - const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_objc_debug_class_hash, lldb::eSymbolTypeData); - if (symbol && symbol->ValueIsAddress()) - { - Process *process = GetProcess(); - if (process) - { - - lldb::addr_t objc_debug_class_hash_addr = symbol->GetAddressRef().GetLoadAddress(&process->GetTarget()); - - if (objc_debug_class_hash_addr != LLDB_INVALID_ADDRESS) - { - Error error; - lldb::addr_t objc_debug_class_hash_ptr = process->ReadPointerFromMemory(objc_debug_class_hash_addr, error); - if (objc_debug_class_hash_ptr != 0 && - objc_debug_class_hash_ptr != LLDB_INVALID_ADDRESS) - { - m_isa_hash_table_ptr = objc_debug_class_hash_ptr; - } - } - } +lldb::addr_t AppleObjCRuntimeV1::GetISAHashTablePointer() { + if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS) { + ModuleSP objc_module_sp(GetObjCModule()); + + if (!objc_module_sp) + return LLDB_INVALID_ADDRESS; + + static ConstString g_objc_debug_class_hash("_objc_debug_class_hash"); + + const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType( + g_objc_debug_class_hash, lldb::eSymbolTypeData); + if (symbol && symbol->ValueIsAddress()) { + Process *process = GetProcess(); + if (process) { + + lldb::addr_t objc_debug_class_hash_addr = + symbol->GetAddressRef().GetLoadAddress(&process->GetTarget()); + + if (objc_debug_class_hash_addr != LLDB_INVALID_ADDRESS) { + Error error; + lldb::addr_t objc_debug_class_hash_ptr = + process->ReadPointerFromMemory(objc_debug_class_hash_addr, error); + if (objc_debug_class_hash_ptr != 0 && + objc_debug_class_hash_ptr != LLDB_INVALID_ADDRESS) { + m_isa_hash_table_ptr = objc_debug_class_hash_ptr; + } } + } } - return m_isa_hash_table_ptr; + } + return m_isa_hash_table_ptr; } -void -AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() -{ - // TODO: implement HashTableSignature... - Process *process = GetProcess(); - - if (process) - { - // Update the process stop ID that indicates the last time we updated the - // map, whether it was successful or not. - m_isa_to_descriptor_stop_id = process->GetStopID(); - - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - - ProcessSP process_sp = process->shared_from_this(); - - ModuleSP objc_module_sp(GetObjCModule()); - - if (!objc_module_sp) - return; - - uint32_t isa_count = 0; - - lldb::addr_t hash_table_ptr = GetISAHashTablePointer (); - if (hash_table_ptr != LLDB_INVALID_ADDRESS) - { - // Read the NXHashTable struct: - // - // typedef struct { - // const NXHashTablePrototype *prototype; - // unsigned count; - // unsigned nbBuckets; - // void *buckets; - // const void *info; - // } NXHashTable; - - Error error; - DataBufferHeap buffer(1024, 0); - if (process->ReadMemory(hash_table_ptr, buffer.GetBytes(), 20, error) == 20) - { - const uint32_t addr_size = m_process->GetAddressByteSize(); - const ByteOrder byte_order = m_process->GetByteOrder(); - DataExtractor data (buffer.GetBytes(), buffer.GetByteSize(), byte_order, addr_size); - lldb::offset_t offset = addr_size; // Skip prototype - const uint32_t count = data.GetU32(&offset); - const uint32_t num_buckets = data.GetU32(&offset); - const addr_t buckets_ptr = data.GetPointer(&offset); - if (m_hash_signature.NeedsUpdate (count, num_buckets, buckets_ptr)) - { - m_hash_signature.UpdateSignature (count, num_buckets, buckets_ptr); - - const uint32_t data_size = num_buckets * 2 * sizeof(uint32_t); - buffer.SetByteSize(data_size); - - if (process->ReadMemory(buckets_ptr, buffer.GetBytes(), data_size, error) == data_size) - { - data.SetData(buffer.GetBytes(), buffer.GetByteSize(), byte_order); - offset = 0; - for (uint32_t bucket_idx = 0; bucket_idx < num_buckets; ++bucket_idx) - { - const uint32_t bucket_isa_count = data.GetU32 (&offset); - const lldb::addr_t bucket_data = data.GetU32 (&offset); - - - if (bucket_isa_count == 0) - continue; - - isa_count += bucket_isa_count; - - ObjCISA isa; - if (bucket_isa_count == 1) - { - // When we only have one entry in the bucket, the bucket data is the "isa" - isa = bucket_data; - if (isa) - { - if (!ISAIsCached(isa)) - { - ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp)); - - if (log && log->GetVerbose()) - log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa); - - AddClass (isa, descriptor_sp); - } - } - } - else - { - // When we have more than one entry in the bucket, the bucket data is a pointer - // to an array of "isa" values - addr_t isa_addr = bucket_data; - for (uint32_t isa_idx = 0; isa_idx < bucket_isa_count; ++isa_idx, isa_addr += addr_size) - { - isa = m_process->ReadPointerFromMemory(isa_addr, error); - - if (isa && isa != LLDB_INVALID_ADDRESS) - { - if (!ISAIsCached(isa)) - { - ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp)); - - if (log && log->GetVerbose()) - log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa); - - AddClass (isa, descriptor_sp); - } - } - } - } - } +void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() { + // TODO: implement HashTableSignature... + Process *process = GetProcess(); + + if (process) { + // Update the process stop ID that indicates the last time we updated the + // map, whether it was successful or not. + m_isa_to_descriptor_stop_id = process->GetStopID(); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + + ProcessSP process_sp = process->shared_from_this(); + + ModuleSP objc_module_sp(GetObjCModule()); + + if (!objc_module_sp) + return; + + uint32_t isa_count = 0; + + lldb::addr_t hash_table_ptr = GetISAHashTablePointer(); + if (hash_table_ptr != LLDB_INVALID_ADDRESS) { + // Read the NXHashTable struct: + // + // typedef struct { + // const NXHashTablePrototype *prototype; + // unsigned count; + // unsigned nbBuckets; + // void *buckets; + // const void *info; + // } NXHashTable; + + Error error; + DataBufferHeap buffer(1024, 0); + if (process->ReadMemory(hash_table_ptr, buffer.GetBytes(), 20, error) == + 20) { + const uint32_t addr_size = m_process->GetAddressByteSize(); + const ByteOrder byte_order = m_process->GetByteOrder(); + DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(), byte_order, + addr_size); + lldb::offset_t offset = addr_size; // Skip prototype + const uint32_t count = data.GetU32(&offset); + const uint32_t num_buckets = data.GetU32(&offset); + const addr_t buckets_ptr = data.GetPointer(&offset); + if (m_hash_signature.NeedsUpdate(count, num_buckets, buckets_ptr)) { + m_hash_signature.UpdateSignature(count, num_buckets, buckets_ptr); + + const uint32_t data_size = num_buckets * 2 * sizeof(uint32_t); + buffer.SetByteSize(data_size); + + if (process->ReadMemory(buckets_ptr, buffer.GetBytes(), data_size, + error) == data_size) { + data.SetData(buffer.GetBytes(), buffer.GetByteSize(), byte_order); + offset = 0; + for (uint32_t bucket_idx = 0; bucket_idx < num_buckets; + ++bucket_idx) { + const uint32_t bucket_isa_count = data.GetU32(&offset); + const lldb::addr_t bucket_data = data.GetU32(&offset); + + if (bucket_isa_count == 0) + continue; + + isa_count += bucket_isa_count; + + ObjCISA isa; + if (bucket_isa_count == 1) { + // When we only have one entry in the bucket, the bucket data is + // the "isa" + isa = bucket_data; + if (isa) { + if (!ISAIsCached(isa)) { + ClassDescriptorSP descriptor_sp( + new ClassDescriptorV1(isa, process_sp)); + + if (log && log->GetVerbose()) + log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 + " from _objc_debug_class_hash to " + "isa->descriptor cache", + isa); + + AddClass(isa, descriptor_sp); + } + } + } else { + // When we have more than one entry in the bucket, the bucket + // data is a pointer + // to an array of "isa" values + addr_t isa_addr = bucket_data; + for (uint32_t isa_idx = 0; isa_idx < bucket_isa_count; + ++isa_idx, isa_addr += addr_size) { + isa = m_process->ReadPointerFromMemory(isa_addr, error); + + if (isa && isa != LLDB_INVALID_ADDRESS) { + if (!ISAIsCached(isa)) { + ClassDescriptorSP descriptor_sp( + new ClassDescriptorV1(isa, process_sp)); + + if (log && log->GetVerbose()) + log->Printf( + "AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 + " from _objc_debug_class_hash to isa->descriptor " + "cache", + isa); + + AddClass(isa, descriptor_sp); } + } } + } } - } - } - else - { - m_isa_to_descriptor_stop_id = UINT32_MAX; + } + } + } } + } else { + m_isa_to_descriptor_stop_id = UINT32_MAX; + } } -DeclVendor * -AppleObjCRuntimeV1::GetDeclVendor() -{ - if (!m_decl_vendor_ap.get()) - m_decl_vendor_ap.reset(new AppleObjCDeclVendor(*this)); - - return m_decl_vendor_ap.get(); +DeclVendor *AppleObjCRuntimeV1::GetDeclVendor() { + return nullptr; } |