Skip to content

Commit 010726b

Browse files
committed
Factor our TargetReflectionContext into a separate file (NFC)
1 parent b28a169 commit 010726b

File tree

4 files changed

+217
-194
lines changed

4 files changed

+217
-194
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_lldb_library(lldbPluginSwiftLanguageRuntime PLUGIN
22
LLDBMemoryReader.cpp
3+
ReflectionContext.cpp
34
SwiftLanguageRuntime.cpp
45
SwiftLanguageRuntimeDynamicTypeResolution.cpp
56
SwiftLanguageRuntimeNames.cpp
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
//===-- ReflectionContext.cpp --------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "SwiftLanguageRuntimeImpl.h"
14+
#include "lldb/Utility/LLDBLog.h"
15+
#include "lldb/Utility/Log.h"
16+
17+
using namespace lldb;
18+
using namespace lldb_private;
19+
20+
namespace {
21+
22+
/// An implementation of the generic ReflectionContextInterface that
23+
/// is templatized on target pointer width and specialized to either
24+
/// 32-bit or 64-bit pointers, with and without ObjC interoperability.
25+
template <typename ReflectionContext>
26+
class TargetReflectionContext
27+
: public SwiftLanguageRuntimeImpl::ReflectionContextInterface {
28+
ReflectionContext m_reflection_ctx;
29+
30+
public:
31+
TargetReflectionContext(
32+
std::shared_ptr<swift::reflection::MemoryReader> reader,
33+
SwiftMetadataCache *swift_metadata_cache)
34+
: m_reflection_ctx(reader, swift_metadata_cache) {}
35+
36+
llvm::Optional<uint32_t> addImage(
37+
llvm::function_ref<std::pair<swift::remote::RemoteRef<void>, uint64_t>(
38+
swift::ReflectionSectionKind)>
39+
find_section,
40+
llvm::SmallVector<llvm::StringRef, 1> likely_module_names) override {
41+
return m_reflection_ctx.addImage(find_section, likely_module_names);
42+
}
43+
44+
llvm::Optional<uint32_t>
45+
addImage(swift::remote::RemoteAddress image_start,
46+
llvm::SmallVector<llvm::StringRef, 1> likely_module_names) override {
47+
return m_reflection_ctx.addImage(image_start, likely_module_names);
48+
}
49+
50+
llvm::Optional<uint32_t> readELF(
51+
swift::remote::RemoteAddress ImageStart,
52+
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
53+
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) override {
54+
return m_reflection_ctx.readELF(ImageStart, FileBuffer,
55+
likely_module_names);
56+
}
57+
58+
const swift::reflection::TypeInfo *
59+
getTypeInfo(const swift::reflection::TypeRef *type_ref,
60+
swift::remote::TypeInfoProvider *provider) override {
61+
if (!type_ref)
62+
return nullptr;
63+
64+
Log *log(GetLog(LLDBLog::Types));
65+
if (log && log->GetVerbose()) {
66+
std::stringstream ss;
67+
type_ref->dump(ss);
68+
LLDB_LOGF(log,
69+
"[TargetReflectionContext::getTypeInfo] Getting "
70+
"type info for typeref:\n%s",
71+
ss.str().c_str());
72+
}
73+
74+
auto type_info = m_reflection_ctx.getTypeInfo(type_ref, provider);
75+
if (log && !type_info) {
76+
std::stringstream ss;
77+
type_ref->dump(ss);
78+
LLDB_LOGF(log,
79+
"[TargetReflectionContext::getTypeInfo] Could not get "
80+
"type info for typeref:\n%s",
81+
ss.str().c_str());
82+
}
83+
84+
if (type_info && log && log->GetVerbose()) {
85+
std::stringstream ss;
86+
type_info->dump(ss);
87+
log->Printf("[TargetReflectionContext::getTypeInfo] Found "
88+
"type info:\n%s",
89+
ss.str().c_str());
90+
}
91+
return type_info;
92+
}
93+
94+
swift::reflection::MemoryReader &getReader() override {
95+
return m_reflection_ctx.getReader();
96+
}
97+
98+
bool ForEachSuperClassType(
99+
swift::remote::TypeInfoProvider *tip, lldb::addr_t pointer,
100+
std::function<bool(SwiftLanguageRuntimeImpl::SuperClassType)> fn)
101+
override {
102+
// Guard against faulty self-referential metadata.
103+
unsigned limit = 256;
104+
auto md_ptr = m_reflection_ctx.readMetadataFromInstance(pointer);
105+
if (!md_ptr)
106+
return false;
107+
108+
// Class object.
109+
while (md_ptr && *md_ptr && --limit) {
110+
// Reading metadata is potentially expensive since (in a remote
111+
// debugging scenario it may even incur network traffic) so we
112+
// just return closures that the caller can use to query details
113+
// if they need them.'
114+
auto metadata = *md_ptr;
115+
if (fn({[=]() -> const swift::reflection::RecordTypeInfo * {
116+
auto *ti = m_reflection_ctx.getMetadataTypeInfo(metadata, tip);
117+
return llvm::dyn_cast_or_null<
118+
swift::reflection::RecordTypeInfo>(ti);
119+
},
120+
[=]() -> const swift::reflection::TypeRef * {
121+
return m_reflection_ctx.readTypeFromMetadata(metadata);
122+
}}))
123+
return true;
124+
125+
// Continue with the base class.
126+
md_ptr = m_reflection_ctx.readSuperClassFromClassMetadata(metadata);
127+
}
128+
return false;
129+
}
130+
131+
llvm::Optional<std::pair<const swift::reflection::TypeRef *,
132+
swift::reflection::RemoteAddress>>
133+
projectExistentialAndUnwrapClass(
134+
swift::reflection::RemoteAddress existential_address,
135+
const swift::reflection::TypeRef &existential_tr) override {
136+
return m_reflection_ctx.projectExistentialAndUnwrapClass(
137+
existential_address, existential_tr);
138+
}
139+
140+
const swift::reflection::TypeRef *
141+
readTypeFromMetadata(lldb::addr_t metadata_address,
142+
bool skip_artificial_subclasses) override {
143+
return m_reflection_ctx.readTypeFromMetadata(metadata_address,
144+
skip_artificial_subclasses);
145+
}
146+
147+
const swift::reflection::TypeRef *
148+
readTypeFromInstance(lldb::addr_t instance_address,
149+
bool skip_artificial_subclasses) override {
150+
auto metadata_address =
151+
m_reflection_ctx.readMetadataFromInstance(instance_address);
152+
if (!metadata_address) {
153+
LLDB_LOGF(GetLog(LLDBLog::Types),
154+
"could not read heap metadata for object at %llu\n",
155+
instance_address);
156+
return nullptr;
157+
}
158+
159+
return m_reflection_ctx.readTypeFromMetadata(*metadata_address,
160+
skip_artificial_subclasses);
161+
}
162+
163+
swift::reflection::TypeRefBuilder &getBuilder() override {
164+
return m_reflection_ctx.getBuilder();
165+
}
166+
167+
llvm::Optional<bool> isValueInlinedInExistentialContainer(
168+
swift::remote::RemoteAddress existential_address) override {
169+
return m_reflection_ctx.isValueInlinedInExistentialContainer(
170+
existential_address);
171+
}
172+
173+
swift::remote::RemoteAbsolutePointer
174+
stripSignedPointer(swift::remote::RemoteAbsolutePointer pointer) override {
175+
return m_reflection_ctx.stripSignedPointer(pointer);
176+
}
177+
};
178+
179+
} // namespace
180+
181+
namespace lldb_private {
182+
std::unique_ptr<SwiftLanguageRuntimeImpl::ReflectionContextInterface>
183+
SwiftLanguageRuntimeImpl::ReflectionContextInterface::CreateReflectionContext(
184+
uint8_t ptr_size, std::shared_ptr<swift::remote::MemoryReader> reader,
185+
bool ObjCInterop, SwiftMetadataCache *swift_metadata_cache) {
186+
using ReflectionContext32ObjCInterop =
187+
TargetReflectionContext<swift::reflection::ReflectionContext<
188+
swift::External<swift::WithObjCInterop<swift::RuntimeTarget<4>>>>>;
189+
using ReflectionContext32NoObjCInterop =
190+
TargetReflectionContext<swift::reflection::ReflectionContext<
191+
swift::External<swift::NoObjCInterop<swift::RuntimeTarget<4>>>>>;
192+
using ReflectionContext64ObjCInterop =
193+
TargetReflectionContext<swift::reflection::ReflectionContext<
194+
swift::External<swift::WithObjCInterop<swift::RuntimeTarget<8>>>>>;
195+
using ReflectionContext64NoObjCInterop =
196+
TargetReflectionContext<swift::reflection::ReflectionContext<
197+
swift::External<swift::NoObjCInterop<swift::RuntimeTarget<8>>>>>;
198+
if (ptr_size == 4) {
199+
if (ObjCInterop)
200+
return std::make_unique<ReflectionContext32ObjCInterop>(
201+
reader, swift_metadata_cache);
202+
return std::make_unique<ReflectionContext32NoObjCInterop>(
203+
reader, swift_metadata_cache);
204+
}
205+
if (ptr_size == 8) {
206+
if (ObjCInterop)
207+
return std::make_unique<ReflectionContext64ObjCInterop>(
208+
reader, swift_metadata_cache);
209+
return std::make_unique<ReflectionContext64NoObjCInterop>(
210+
reader, swift_metadata_cache);
211+
}
212+
return {};
213+
}
214+
} // namespace lldb_private

0 commit comments

Comments
 (0)