Skip to content

Commit 7351df5

Browse files
committed
[lldb] Make GetDynamicTypeAndAddress() use host address if available
If GetDynamicTypeAndAddress_Value cannot get back to the inferior address, but does have a host address and buffer that fits the dynamic type, return that. (cherry picked from commit 829f2bc)
1 parent 5067ac6 commit 7351df5

File tree

6 files changed

+102
-47
lines changed

6 files changed

+102
-47
lines changed

lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,13 +1114,14 @@ SwiftLanguage::GetHardcodedSynthetics() {
11141114
TypeAndOrName type_or_name;
11151115
Address address;
11161116
Value::ValueType value_type;
1117+
llvm::ArrayRef<uint8_t> local_buffer;
11171118
// Try to find the dynamic type of the Swift type.
11181119
// TODO: find a way to get the dyamic value type from the
11191120
// command.
11201121
if (swift_runtime->GetDynamicTypeAndAddress(
11211122
*casted_to_swift.get(),
11221123
lldb::DynamicValueType::eDynamicCanRunTarget, type_or_name,
1123-
address, value_type)) {
1124+
address, value_type, local_buffer)) {
11241125
if (type_or_name.HasCompilerType()) {
11251126
swift_type = type_or_name.GetCompilerType();
11261127
// Cast it to the more specific type.
@@ -1268,8 +1269,9 @@ SwiftLanguage::GetPossibleFormattersMatches(
12681269
TypeAndOrName type_and_or_name;
12691270
Address address;
12701271
Value::ValueType value_type;
1272+
llvm::ArrayRef<uint8_t> local_buffer;
12711273
if (!runtime->GetDynamicTypeAndAddress(valobj, use_dynamic, type_and_or_name,
1272-
address, value_type))
1274+
address, value_type, local_buffer))
12731275
return result;
12741276
if (ConstString name = type_and_or_name.GetName())
12751277
result.push_back(

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ class SwiftLanguageRuntime : public LanguageRuntime {
242242
bool GetDynamicTypeAndAddress(ValueObject &in_value,
243243
lldb::DynamicValueType use_dynamic,
244244
TypeAndOrName &class_type_or_name,
245-
Address &address,
246-
Value::ValueType &value_type) override;
245+
Address &address, Value::ValueType &value_type,
246+
llvm::ArrayRef<uint8_t> &local_buffer) override;
247247

248248
CompilerType BindGenericTypeParameters(
249249
CompilerType unbound_type,
@@ -569,7 +569,8 @@ class SwiftLanguageRuntime : public LanguageRuntime {
569569
lldb::DynamicValueType use_dynamic,
570570
TypeAndOrName &class_type_or_name,
571571
Address &address,
572-
Value::ValueType &value_type);
572+
Value::ValueType &value_type,
573+
llvm::ArrayRef<uint8_t> &local_buffer);
573574
#ifndef NDEBUG
574575
ConstString GetDynamicTypeName_ClassRemoteAST(ValueObject &in_value,
575576
lldb::addr_t instance_ptr);
@@ -596,18 +597,18 @@ class SwiftLanguageRuntime : public LanguageRuntime {
596597
lldb::DynamicValueType use_dynamic,
597598
TypeAndOrName &class_type_or_name,
598599
Address &address,
599-
Value::ValueType &value_type);
600+
Value::ValueType &value_type,
601+
llvm::ArrayRef<uint8_t> &local_buffer);
600602

601603
bool GetDynamicTypeAndAddress_IndirectEnumCase(
602604
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
603605
TypeAndOrName &class_type_or_name, Address &address,
604-
Value::ValueType &value_type);
606+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer);
605607

606-
bool GetDynamicTypeAndAddress_ClangType(ValueObject &in_value,
607-
lldb::DynamicValueType use_dynamic,
608-
TypeAndOrName &class_type_or_name,
609-
Address &address,
610-
Value::ValueType &value_type);
608+
bool GetDynamicTypeAndAddress_ClangType(
609+
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
610+
TypeAndOrName &class_type_or_name, Address &address,
611+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer);
611612

612613
/// Dynamic type resolution tends to want to generate scalar data -
613614
/// but there are caveats Per original comment here "Our address is
@@ -618,7 +619,8 @@ class SwiftLanguageRuntime : public LanguageRuntime {
618619
Value::ValueType GetValueType(ValueObject &in_value,
619620
CompilerType dynamic_type,
620621
Value::ValueType static_value_type,
621-
bool is_indirect_enum_case);
622+
bool is_indirect_enum_case,
623+
llvm::ArrayRef<uint8_t> &local_buffer);
622624

623625
lldb::UnwindPlanSP
624626
GetRuntimeUnwindPlan(lldb::ProcessSP process_sp,

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,7 +1847,8 @@ static bool IsPrivateNSClass(NodePointer node) {
18471847
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class(
18481848
ValueObject &in_value, CompilerType class_type,
18491849
lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name,
1850-
Address &address, Value::ValueType &value_type) {
1850+
Address &address, Value::ValueType &value_type,
1851+
llvm::ArrayRef<uint8_t> &local_buffer) {
18511852
AddressType address_type;
18521853
lldb::addr_t instance_ptr = in_value.GetPointerValue(&address_type);
18531854
value_type = Value::GetValueTypeFromAddressType(address_type);
@@ -1873,8 +1874,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class(
18731874
if (auto *objc_runtime =
18741875
SwiftLanguageRuntime::GetObjCRuntime(GetProcess())) {
18751876
Value::ValueType value_type;
1876-
if (objc_runtime->GetDynamicTypeAndAddress(
1877-
in_value, use_dynamic, class_type_or_name, address, value_type)) {
1877+
if (objc_runtime->GetDynamicTypeAndAddress(in_value, use_dynamic,
1878+
class_type_or_name, address,
1879+
value_type, local_buffer)) {
18781880
bool found = false;
18791881
// Return the most specific class which we can get the typeref.
18801882
ForEachSuperClassType(in_value, [&](SuperClassType sc) -> bool {
@@ -2436,17 +2438,41 @@ bool SwiftLanguageRuntime::GetAbstractTypeName(StreamString &name,
24362438
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Value(
24372439
ValueObject &in_value, CompilerType &bound_type,
24382440
lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name,
2439-
Address &address, Value::ValueType &value_type) {
2441+
Address &address, Value::ValueType &value_type,
2442+
llvm::ArrayRef<uint8_t> &local_buffer) {
2443+
auto static_type = in_value.GetCompilerType();
24402444
value_type = Value::ValueType::Invalid;
24412445
class_type_or_name.SetCompilerType(bound_type);
24422446

24432447
ExecutionContext exe_ctx = in_value.GetExecutionContextRef().Lock(true);
2448+
ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
2449+
if (!exe_scope)
2450+
return false;
24442451
std::optional<uint64_t> size =
24452452
bound_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
24462453
if (!size)
24472454
return false;
24482455
AddressType address_type;
24492456
lldb::addr_t val_address = in_value.GetAddressOf(true, &address_type);
2457+
// If we couldn't find a load address, but the value object has a local
2458+
// buffer, use that.
2459+
if (val_address == LLDB_INVALID_ADDRESS && address_type == eAddressTypeHost) {
2460+
// Get the start and size of the local buffer.
2461+
auto start = in_value.GetValue().GetScalar().ULongLong();
2462+
auto local_buffer_size = in_value.GetLocalBufferSize();
2463+
2464+
// If we can't find the size of the local buffer we can't safely know if the
2465+
// dynamic type fits in it.
2466+
if (local_buffer_size == LLDB_INVALID_ADDRESS)
2467+
return false;
2468+
// If the dynamic type doesn't in the buffer we can't use it either.
2469+
if (local_buffer_size < bound_type.GetByteSize(exe_scope))
2470+
return false;
2471+
2472+
value_type = Value::GetValueTypeFromAddressType(address_type);
2473+
local_buffer = {(uint8_t *)start, local_buffer_size};
2474+
return true;
2475+
}
24502476
if (*size && (!val_address || val_address == LLDB_INVALID_ADDRESS))
24512477
return false;
24522478

@@ -2458,7 +2484,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Value(
24582484
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
24592485
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
24602486
TypeAndOrName &class_type_or_name, Address &address,
2461-
Value::ValueType &value_type) {
2487+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
24622488
Status error;
24632489
CompilerType child_type = in_value.GetCompilerType();
24642490
class_type_or_name.SetCompilerType(child_type);
@@ -2490,7 +2516,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
24902516
return false;
24912517

24922518
return GetDynamicTypeAndAddress(*valobj_sp, use_dynamic, class_type_or_name,
2493-
address, value_type);
2519+
address, value_type, local_buffer);
24942520
} else {
24952521
// This is most likely a statically known type.
24962522
address.SetLoadAddress(box_value, &GetProcess().GetTarget());
@@ -2516,7 +2542,8 @@ void SwiftLanguageRuntime::DumpTyperef(CompilerType type,
25162542

25172543
Value::ValueType SwiftLanguageRuntime::GetValueType(
25182544
ValueObject &in_value, CompilerType dynamic_type,
2519-
Value::ValueType static_value_type, bool is_indirect_enum_case) {
2545+
Value::ValueType static_value_type, bool is_indirect_enum_case,
2546+
llvm::ArrayRef<uint8_t> &local_buffer) {
25202547
CompilerType static_type = in_value.GetCompilerType();
25212548
Flags static_type_flags(static_type.GetTypeInfo());
25222549
Flags dynamic_type_flags(dynamic_type.GetTypeInfo());
@@ -2570,6 +2597,12 @@ Value::ValueType SwiftLanguageRuntime::GetValueType(
25702597
// If the data is not inlined, we have a pointer.
25712598
return Value::ValueType::LoadAddress;
25722599
}
2600+
// If we found a host address and the dynamic type fits in there, and
2601+
// this is not a pointer from an existential container, then this points to
2602+
// the local buffer.
2603+
if (static_value_type == Value::ValueType::HostAddress &&
2604+
!local_buffer.empty())
2605+
return static_value_type;
25732606

25742607
if (static_type_flags.AllSet(eTypeIsSwift | eTypeIsGenericTypeParam)) {
25752608
// if I am handling a non-pointer Swift type obtained from an archetype,
@@ -2677,7 +2710,7 @@ std::optional<SwiftNominalType> GetSwiftClass(ValueObject &valobj,
26772710
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_ClangType(
26782711
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
26792712
TypeAndOrName &class_type_or_name, Address &address,
2680-
Value::ValueType &value_type) {
2713+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
26812714
AppleObjCRuntime *objc_runtime =
26822715
SwiftLanguageRuntime::GetObjCRuntime(GetProcess());
26832716
if (!objc_runtime)
@@ -2690,8 +2723,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_ClangType(
26902723
// resolution first, and then map the dynamic Objective-C type back
26912724
// into Swift.
26922725
TypeAndOrName dyn_class_type_or_name = class_type_or_name;
2693-
if (!objc_runtime->GetDynamicTypeAndAddress(
2694-
in_value, use_dynamic, dyn_class_type_or_name, address, value_type))
2726+
if (!objc_runtime->GetDynamicTypeAndAddress(in_value, use_dynamic,
2727+
dyn_class_type_or_name, address,
2728+
value_type, local_buffer))
26952729
return false;
26962730

26972731
StringRef dyn_name = dyn_class_type_or_name.GetName().GetStringRef();
@@ -2797,7 +2831,7 @@ static bool CouldHaveDynamicValue(ValueObject &in_value) {
27972831
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
27982832
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
27992833
TypeAndOrName &class_type_or_name, Address &address,
2800-
Value::ValueType &value_type) {
2834+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
28012835
class_type_or_name.Clear();
28022836
if (use_dynamic == lldb::eNoDynamicValues)
28032837
return false;
@@ -2806,8 +2840,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28062840

28072841
// Try to import a Clang type into Swift.
28082842
if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC)
2809-
return GetDynamicTypeAndAddress_ClangType(
2810-
in_value, use_dynamic, class_type_or_name, address, value_type);
2843+
return GetDynamicTypeAndAddress_ClangType(in_value, use_dynamic,
2844+
class_type_or_name, address,
2845+
value_type, local_buffer);
28112846

28122847
if (!CouldHaveDynamicValue(in_value))
28132848
return false;
@@ -2823,7 +2858,8 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28232858
// Type kinds with instance metadata don't need generic type resolution.
28242859
if (is_indirect_enum_case)
28252860
success = GetDynamicTypeAndAddress_IndirectEnumCase(
2826-
in_value, use_dynamic, class_type_or_name, address, static_value_type);
2861+
in_value, use_dynamic, class_type_or_name, address, static_value_type,
2862+
local_buffer);
28272863
else if (type_info.AnySet(eTypeIsPack))
28282864
success = GetDynamicTypeAndAddress_Pack(in_value, val_type, use_dynamic,
28292865
class_type_or_name, address,
@@ -2832,7 +2868,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28322868
type_info.AllSet(eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue))
28332869
success = GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic,
28342870
class_type_or_name, address,
2835-
static_value_type);
2871+
static_value_type, local_buffer);
28362872
else if (type_info.AllSet(eTypeIsMetatype | eTypeIsProtocol))
28372873
success = GetDynamicTypeAndAddress_ExistentialMetatype(
28382874
in_value, val_type, use_dynamic, class_type_or_name, address);
@@ -2856,16 +2892,16 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28562892

28572893
Flags subst_type_info(bound_type.GetTypeInfo());
28582894
if (subst_type_info.AnySet(eTypeIsClass)) {
2859-
success = GetDynamicTypeAndAddress_Class(in_value, bound_type,
2860-
use_dynamic, class_type_or_name,
2861-
address, static_value_type);
2895+
success = GetDynamicTypeAndAddress_Class(
2896+
in_value, bound_type, use_dynamic, class_type_or_name, address,
2897+
static_value_type, local_buffer);
28622898
} else if (subst_type_info.AnySet(eTypeIsProtocol)) {
28632899
success = GetDynamicTypeAndAddress_Existential(
28642900
in_value, bound_type, use_dynamic, class_type_or_name, address);
28652901
} else {
2866-
success = GetDynamicTypeAndAddress_Value(in_value, bound_type,
2867-
use_dynamic, class_type_or_name,
2868-
address, static_value_type);
2902+
success = GetDynamicTypeAndAddress_Value(
2903+
in_value, bound_type, use_dynamic, class_type_or_name, address,
2904+
static_value_type, local_buffer);
28692905
}
28702906
}
28712907

@@ -2875,8 +2911,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28752911
if (static_value_type == Value::ValueType::Invalid)
28762912
static_value_type = in_value.GetValue().GetValueType();
28772913

2878-
value_type = GetValueType(in_value, class_type_or_name.GetCompilerType(),
2879-
static_value_type, is_indirect_enum_case);
2914+
value_type =
2915+
GetValueType(in_value, class_type_or_name.GetCompilerType(),
2916+
static_value_type, is_indirect_enum_case, local_buffer);
28802917
}
28812918
return success;
28822919
}

lldb/source/ValueObject/ValueObjectDynamicValue.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ bool ValueObjectDynamicValue::UpdateValue() {
172172
if (runtime)
173173
found_dynamic_type = runtime->GetDynamicTypeAndAddress(
174174
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
175-
value_type);
175+
value_type, local_buffer);
176176
}
177177
#endif // LLDB_ENABLE_SWIFT
178178
if (!found_dynamic_type &&

lldb/test/API/lang/swift/private_discriminator/TestSwiftPrivateDiscriminator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def test(self):
2727
self.expect("expr --bind-generic-types true -- self", error=True, substrs=["Hint"])
2828
# This should work because expression evaluation automatically falls back
2929
# to not binding generic parameters.
30-
self.expect("expression self", substrs=['Generic', '<T>', 'n', '23'])
30+
self.expect("expression self", substrs=['Generic', '<Builder.Private>', 'n', '23'])
3131

3232
process.Continue()
3333
# This should work.

0 commit comments

Comments
 (0)