diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index 19d7165882c25..d4fdb4c5cf739 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -412,7 +412,7 @@ static bool HasReflectionInfo(ObjectFile *obj_file) { return hasReflectionSection; } -SwiftLanguageRuntimeImpl::ReflectionContextInterface * +SwiftLanguageRuntimeImpl::NativeReflectionContext * SwiftLanguageRuntimeImpl::GetReflectionContext() { if (!m_initialized_reflection_ctx) SetupReflection(); @@ -438,21 +438,7 @@ void SwiftLanguageRuntimeImpl::SetupReflection() { if (m_initialized_reflection_ctx) return; - auto &target = m_process.GetTarget(); - if (auto exe_module = target.GetExecutableModule()) { - auto &triple = exe_module->GetArchitecture().GetTriple(); - if (triple.isArch64Bit()) - m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext64( - this->GetMemoryReader()); - else if (triple.isArch32Bit()) - m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext32( - this->GetMemoryReader()); - else { - LLDB_LOGF(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), - "Could not initialize reflection context for \"%s\"", - triple.str().c_str()); - } - } + m_reflection_ctx.reset(new NativeReflectionContext(this->GetMemoryReader())); m_initialized_reflection_ctx = true; // Add all defered modules to reflection context that were added to diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index fd26155589228..12f56a94df70d 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -250,142 +250,6 @@ lldb::addr_t SwiftLanguageRuntime::MaybeMaskNonTrivialReferencePointer( return addr; } -namespace { - -/// An implementation of the generic ReflectionContextInterface that -/// is templatized on target pointer width and specialized to either -/// 32-bit or 64-bit pointers. -template -class TargetReflectionContext - : public SwiftLanguageRuntimeImpl::ReflectionContextInterface { - using ReflectionContext = swift::reflection::ReflectionContext< - swift::External>>; - ReflectionContext m_reflection_ctx; - -public: - TargetReflectionContext( - std::shared_ptr reader) - : m_reflection_ctx(reader) {} - - bool addImage( - llvm::function_ref, uint64_t>( - swift::ReflectionSectionKind)> - find_section) override { - return m_reflection_ctx.addImage(find_section); - } - - bool addImage(swift::remote::RemoteAddress image_start) override { - return m_reflection_ctx.addImage(image_start); - } - - bool readELF(swift::remote::RemoteAddress ImageStart, - llvm::Optional FileBuffer) override { - return m_reflection_ctx.readELF(ImageStart, FileBuffer); - } - - const swift::reflection::TypeInfo * - getTypeInfo(const swift::reflection::TypeRef *type_ref, - swift::remote::TypeInfoProvider *provider) override { - return m_reflection_ctx.getTypeInfo(type_ref, provider); - } - - swift::reflection::MemoryReader &getReader() override { - return m_reflection_ctx.getReader(); - } - - bool ForEachSuperClassType( - LLDBTypeInfoProvider *tip, lldb::addr_t pointer, - std::function fn) - override { - auto md_ptr = m_reflection_ctx.readMetadataFromInstance(pointer); - if (!md_ptr) - return false; - - // Class object. - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), - "found RecordTypeInfo for instance"); - while (md_ptr && *md_ptr) { - // Reading metadata is potentially expensive since (in a remote - // debugging scenario it may even incur network traffic) so we - // just return closures that the caller can use to query details - // if they need them.' - auto metadata = *md_ptr; - if (fn({[=]() -> const swift::reflection::RecordTypeInfo * { - auto *ti = m_reflection_ctx.getMetadataTypeInfo(metadata, tip); - return llvm::dyn_cast_or_null< - swift::reflection::RecordTypeInfo>(ti); - }, - [=]() -> const swift::reflection::TypeRef * { - return m_reflection_ctx.readTypeFromMetadata(metadata); - }})) - return true; - - // Continue with the base class. - md_ptr = m_reflection_ctx.readSuperClassFromClassMetadata(metadata); - } - return false; - } - - llvm::Optional> - projectExistentialAndUnwrapClass( - swift::reflection::RemoteAddress existential_address, - const swift::reflection::TypeRef &existential_tr) override { - return m_reflection_ctx.projectExistentialAndUnwrapClass( - existential_address, existential_tr); - } - - const swift::reflection::TypeRef * - readTypeFromMetadata(lldb::addr_t metadata_address, - bool skip_artificial_subclasses) override { - return m_reflection_ctx.readTypeFromMetadata(metadata_address, - skip_artificial_subclasses); - } - - const swift::reflection::TypeRef * - readTypeFromInstance(lldb::addr_t instance_address, - bool skip_artificial_subclasses) override { - auto metadata_address = - m_reflection_ctx.readMetadataFromInstance(instance_address); - if (!metadata_address) { - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), - "could not read heap metadata for object at %llu\n", - instance_address); - return nullptr; - } - - return m_reflection_ctx.readTypeFromMetadata(*metadata_address, - skip_artificial_subclasses); - } - - swift::reflection::TypeRefBuilder &getBuilder() override { - return m_reflection_ctx.getBuilder(); - } - - llvm::Optional isValueInlinedInExistentialContainer( - swift::remote::RemoteAddress existential_address) override { - return m_reflection_ctx.isValueInlinedInExistentialContainer( - existential_address); - } -}; - -} // namespace - -std::unique_ptr -SwiftLanguageRuntimeImpl::ReflectionContextInterface::CreateReflectionContext32( - std::shared_ptr reader) { - return std::make_unique>(reader); -} - -std::unique_ptr -SwiftLanguageRuntimeImpl::ReflectionContextInterface::CreateReflectionContext64( - std::shared_ptr reader) { - return std::make_unique>(reader); -} - -SwiftLanguageRuntimeImpl::ReflectionContextInterface:: - ~ReflectionContextInterface() {} - const CompilerType &SwiftLanguageRuntimeImpl::GetBoxMetadataType() { if (m_box_metadata_type.IsValid()) return m_box_metadata_type; @@ -770,8 +634,6 @@ class ASTVerifier : public swift::ASTWalker { } }; -} // namespace - class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider { SwiftLanguageRuntimeImpl &m_runtime; TypeSystemSwift &m_typesystem; @@ -850,8 +712,7 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider { if (is_bitfield_ptr) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); if (log) - log->Printf("[LLDBTypeInfoProvider] bitfield support is not yet " - "implemented"); + log->Printf("[LLDBTypeInfoProvider] bitfield support is not yet implemented"); continue; } swift::reflection::FieldInfo field_info = { @@ -864,6 +725,8 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider { } }; +} // namespace + llvm::Optional SwiftLanguageRuntimeImpl::lookupClangTypeInfo(CompilerType clang_type) { std::lock_guard locker(m_clang_type_info_mutex); @@ -1711,9 +1574,35 @@ bool SwiftLanguageRuntimeImpl::ForEachSuperClassType( if (!ts) return false; - LLDBTypeInfoProvider tip(*this, *ts); lldb::addr_t pointer = instance.GetPointerValue(); - return reflection_ctx->ForEachSuperClassType(&tip, pointer, fn); + auto md_ptr = reflection_ctx->readMetadataFromInstance(pointer); + if (!md_ptr) + return false; + + // Class object. + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), + "found RecordTypeInfo for instance"); + while (md_ptr && *md_ptr) { + // Reading metadata is potentially expensive since (in a remote + // debugging scenario it may even incur network traffic) so we + // just return closures that the caller can use to query details + // if they need them. + auto metadata = *md_ptr; + if (fn({[=]() -> const swift::reflection::RecordTypeInfo * { + LLDBTypeInfoProvider tip(*this, *ts); + auto *ti = reflection_ctx->getMetadataTypeInfo(metadata, &tip); + return llvm::dyn_cast_or_null( + ti); + }, + [=]() -> const swift::reflection::TypeRef * { + return reflection_ctx->readTypeFromMetadata(metadata); + }})) + return true; + + // Continue with the base class. + md_ptr = reflection_ctx->readSuperClassFromClassMetadata(metadata); + } + return false; } bool SwiftLanguageRuntime::IsSelf(Variable &variable) { @@ -1784,8 +1673,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address) { AddressType address_type; - lldb::addr_t instance_ptr = in_value.GetPointerValue(&address_type); - if (instance_ptr == LLDB_INVALID_ADDRESS || instance_ptr == 0) + lldb::addr_t class_metadata_ptr = in_value.GetPointerValue(&address_type); + if (class_metadata_ptr == LLDB_INVALID_ADDRESS || class_metadata_ptr == 0) return false; CompilerType static_type = in_value.GetCompilerType(); @@ -1793,7 +1682,7 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( llvm::dyn_cast_or_null(static_type.GetTypeSystem()); if (!tss) return false; - address.SetRawAddress(instance_ptr); + address.SetRawAddress(class_metadata_ptr); auto &ts = tss->GetTypeSystemSwiftTypeRef(); // Ask the Objective-C runtime about Objective-C types. if (tss->IsImportedType(static_type.GetOpaqueQualType(), nullptr)) @@ -1823,7 +1712,19 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( } Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); auto *reflection_ctx = GetReflectionContext(); - const auto *typeref = reflection_ctx->readTypeFromInstance(instance_ptr); + swift::remote::RemoteAddress instance_address(class_metadata_ptr); + auto metadata_address = + reflection_ctx->readMetadataFromInstance(class_metadata_ptr); + if (!metadata_address) { + if (log) + log->Printf("could not read heap metadata for object at %llu\n", + class_metadata_ptr); + return false; + } + + const auto *typeref = + reflection_ctx->readTypeFromMetadata(*metadata_address, + /*skipArtificial=*/false); if (!typeref) return false; swift::Demangle::Demangler dem; @@ -1832,8 +1733,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( #ifndef NDEBUG auto &remote_ast = GetRemoteASTContext(scratch_ctx); - auto remote_ast_metadata_address = remote_ast.getHeapMetadataForObject( - swift::remote::RemoteAddress(instance_ptr)); + auto remote_ast_metadata_address = + remote_ast.getHeapMetadataForObject(instance_address); if (remote_ast_metadata_address) { auto instance_type = remote_ast.getTypeForRemoteTypeMetadata( remote_ast_metadata_address.getValue(), @@ -1847,8 +1748,9 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( << "\n"; } else { if (log) { - log->Printf("could not get type metadata: %s\n", - instance_type.getFailure().render().c_str()); + log->Printf( + "could not get type metadata from address %" PRIu64 " : %s\n", + *metadata_address, instance_type.getFailure().render().c_str()); } } } diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h index 711c36941495b..7474ab2516600 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h @@ -15,7 +15,6 @@ #include "SwiftLanguageRuntime.h" #include "swift/Reflection/TypeLowering.h" -#include "llvm/Support/Memory.h" namespace swift { namespace reflection { @@ -25,7 +24,6 @@ class TypeRef; namespace lldb_private { class Process; -class LLDBTypeInfoProvider; /// A full LLDB language runtime backed by the Swift runtime library /// in the process. @@ -179,6 +177,15 @@ class SwiftLanguageRuntimeImpl { bool IsABIStable(); +protected: + using NativeReflectionContext = swift::reflection::ReflectionContext< + swift::External>>; + + /// Use the reflection context to build a TypeRef object. + const swift::reflection::TypeRef * + GetTypeRef(CompilerType type, TypeSystemSwiftTypeRef *module_holder, + SwiftASTContext *swift_ast_context); + /// Returned by \ref ForEachSuperClassType. Not every user of \p /// ForEachSuperClassType needs all of these. By returning this /// object we call into the runtime only when needed. @@ -187,62 +194,6 @@ class SwiftLanguageRuntimeImpl { std::function get_record_type_info; std::function get_typeref; }; - - /// An abstract interface to swift::reflection::ReflectionContext - /// objects of varying pointer sizes. This class encapsulates all - /// traffic to ReflectionContext and abstracts the detail that - /// ReflectionContext is a template that needs to be specialized for - /// a specific pointer width. - class ReflectionContextInterface { - public: - /// Return a 32-bit reflection context. - static std::unique_ptr - CreateReflectionContext32( - std::shared_ptr reader); - - /// Return a 64-bit reflection context. - static std::unique_ptr - CreateReflectionContext64( - std::shared_ptr reader); - - virtual ~ReflectionContextInterface(); - - virtual bool addImage( - llvm::function_ref, uint64_t>( - swift::ReflectionSectionKind)> - find_section); - virtual bool addImage(swift::remote::RemoteAddress image_start) = 0; - virtual bool readELF(swift::remote::RemoteAddress ImageStart, - llvm::Optional FileBuffer) = 0; - virtual const swift::reflection::TypeInfo * - getTypeInfo(const swift::reflection::TypeRef *type_ref, - swift::remote::TypeInfoProvider *provider) = 0; - virtual swift::remote::MemoryReader &getReader() = 0; - virtual bool - ForEachSuperClassType(LLDBTypeInfoProvider *tip, lldb::addr_t pointer, - std::function fn) = 0; - virtual llvm::Optional> - projectExistentialAndUnwrapClass( - swift::remote::RemoteAddress existential_addess, - const swift::reflection::TypeRef &existential_tr) = 0; - virtual const swift::reflection::TypeRef * - readTypeFromMetadata(lldb::addr_t metadata_address, - bool skip_artificial_subclasses = false) = 0; - virtual const swift::reflection::TypeRef * - readTypeFromInstance(lldb::addr_t instance_address, - bool skip_artificial_subclasses = false) = 0; - virtual swift::reflection::TypeRefBuilder &getBuilder() = 0; - virtual llvm::Optional isValueInlinedInExistentialContainer( - swift::remote::RemoteAddress existential_address) = 0; - }; - -protected: - /// Use the reflection context to build a TypeRef object. - const swift::reflection::TypeRef * - GetTypeRef(CompilerType type, TypeSystemSwiftTypeRef *module_holder, - SwiftASTContext *swift_ast_context); - /// If \p instance points to a Swift object, retrieve its /// RecordTypeInfo and pass it to the callback \p fn. Repeat the /// process with all superclasses. If \p fn returns \p true, early @@ -350,7 +301,7 @@ class SwiftLanguageRuntimeImpl { llvm::Optional GetDynamicExclusivityFlagAddr(); /// Lazily initialize the reflection context. Return \p nullptr on failure. - ReflectionContextInterface *GetReflectionContext(); + NativeReflectionContext *GetReflectionContext(); /// Lazily initialize and return \p m_SwiftNativeNSErrorISA. llvm::Optional GetSwiftNativeNSErrorISA(); @@ -370,7 +321,7 @@ class SwiftLanguageRuntimeImpl { /// Reflection context. /// \{ - std::unique_ptr m_reflection_ctx; + std::unique_ptr m_reflection_ctx; /// Record modules added through ModulesDidLoad, which are to be /// added to the reflection context once it's being initialized.