1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
//===-- ReflectionContextInterface.h ----------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_SwiftReflectionContextInterface_h_
#define liblldb_SwiftReflectionContextInterface_h_
#include <mutex>
#include "lldb/lldb-types.h"
#include "swift/ABI/ObjectFile.h"
#include "swift/Remote/RemoteAddress.h"
#include "swift/RemoteInspection/TypeRef.h"
#include <optional>
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Memory.h"
#include "LockGuarded.h"
namespace swift {
namespace Demangle {
class Demangler;
} // namespace Demangle
namespace reflection {
struct DescriptorFinder;
class RecordTypeInfo;
class TypeInfo;
} // namespace reflection
namespace remote {
class MemoryReader;
struct TypeInfoProvider;
} // namespace remote
} // namespace swift
namespace lldb_private {
struct SwiftMetadataCache;
/// 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.
/// Using function objects to avoid instantiating ReflectionContext in this
/// header.
struct SuperClassType {
std::function<const swift::reflection::RecordTypeInfo *()>
get_record_type_info;
std::function<const swift::reflection::TypeRef *()> 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 reflection context.
static std::unique_ptr<ReflectionContextInterface> CreateReflectionContext(
uint8_t pointer_size, std::shared_ptr<swift::remote::MemoryReader> reader,
bool objc_interop, SwiftMetadataCache *swift_metadata_cache);
virtual ~ReflectionContextInterface() = default;
virtual std::optional<uint32_t> AddImage(
llvm::function_ref<std::pair<swift::remote::RemoteRef<void>, uint64_t>(
swift::ReflectionSectionKind)>
find_section,
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
virtual std::optional<uint32_t>
AddImage(swift::remote::RemoteAddress image_start,
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
virtual std::optional<uint32_t>
ReadELF(swift::remote::RemoteAddress ImageStart,
std::optional<llvm::sys::MemoryBlock> FileBuffer,
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
virtual const swift::reflection::TypeRef *GetTypeRefOrNull(
llvm::StringRef mangled_type_name,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual const swift::reflection::TypeRef *GetTypeRefOrNull(
swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual const swift::reflection::TypeInfo *GetClassInstanceTypeInfo(
const swift::reflection::TypeRef *type_ref,
swift::remote::TypeInfoProvider *provider,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual const swift::reflection::TypeInfo *
GetTypeInfo(const swift::reflection::TypeRef *type_ref,
swift::remote::TypeInfoProvider *provider,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual const swift::reflection::TypeInfo *GetTypeInfoFromInstance(
lldb::addr_t instance, swift::remote::TypeInfoProvider *provider,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual swift::remote::MemoryReader &GetReader() = 0;
virtual const swift::reflection::TypeRef *LookupSuperclass(
const swift::reflection::TypeRef *tr,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual bool
ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
swift::reflection::DescriptorFinder *descriptor_finder,
lldb::addr_t pointer,
std::function<bool(SuperClassType)> fn) = 0;
/// Traverses the superclass hierarchy using the typeref, as opposed to the
/// other version of the function that uses the instance's pointer. This
/// version is useful when reflection metadata has been stripped from the
/// binary (for example, when debugging embedded Swift programs).
virtual bool
ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
swift::reflection::DescriptorFinder *descriptor_finder,
const swift::reflection::TypeRef *tr,
std::function<bool(SuperClassType)> fn) = 0;
virtual std::optional<std::pair<const swift::reflection::TypeRef *,
swift::remote::RemoteAddress>>
ProjectExistentialAndUnwrapClass(
swift::remote::RemoteAddress existential_addess,
const swift::reflection::TypeRef &existential_tr,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual std::optional<int32_t> ProjectEnumValue(
swift::remote::RemoteAddress enum_addr,
const swift::reflection::TypeRef *enum_type_ref,
swift::remote::TypeInfoProvider *provider,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual const swift::reflection::TypeRef *ReadTypeFromMetadata(
lldb::addr_t metadata_address,
swift::reflection::DescriptorFinder *descriptor_finder,
bool skip_artificial_subclasses = false) = 0;
virtual const swift::reflection::TypeRef *ReadTypeFromInstance(
lldb::addr_t instance_address,
swift::reflection::DescriptorFinder *descriptor_finder,
bool skip_artificial_subclasses = false) = 0;
virtual std::optional<bool> IsValueInlinedInExistentialContainer(
swift::remote::RemoteAddress existential_address) = 0;
virtual const swift::reflection::TypeRef *ApplySubstitutions(
const swift::reflection::TypeRef *type_ref,
swift::reflection::GenericArgumentMap substitutions,
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
virtual swift::remote::RemoteAbsolutePointer
StripSignedPointer(swift::remote::RemoteAbsolutePointer pointer) = 0;
};
using ThreadSafeReflectionContext = LockGuarded<ReflectionContextInterface>;
} // namespace lldb_private
#endif
|