Skip to content

Commit 829f2bc

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.
1 parent 2012b54 commit 829f2bc

File tree

6 files changed

+103
-48
lines changed

6 files changed

+103
-48
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.
@@ -1248,8 +1249,9 @@ SwiftLanguage::GetPossibleFormattersMatches(
12481249
TypeAndOrName type_and_or_name;
12491250
Address address;
12501251
Value::ValueType value_type;
1252+
llvm::ArrayRef<uint8_t> local_buffer;
12511253
if (!runtime->GetDynamicTypeAndAddress(valobj, use_dynamic, type_and_or_name,
1252-
address, value_type))
1254+
address, value_type, local_buffer))
12531255
return result;
12541256
if (ConstString name = type_and_or_name.GetName())
12551257
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 {
@@ -2430,17 +2432,41 @@ bool SwiftLanguageRuntime::GetAbstractTypeName(StreamString &name,
24302432
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Value(
24312433
ValueObject &in_value, CompilerType &bound_type,
24322434
lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name,
2433-
Address &address, Value::ValueType &value_type) {
2435+
Address &address, Value::ValueType &value_type,
2436+
llvm::ArrayRef<uint8_t> &local_buffer) {
2437+
auto static_type = in_value.GetCompilerType();
24342438
value_type = Value::ValueType::Invalid;
24352439
class_type_or_name.SetCompilerType(bound_type);
24362440

24372441
ExecutionContext exe_ctx = in_value.GetExecutionContextRef().Lock(true);
2442+
ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
2443+
if (!exe_scope)
2444+
return false;
24382445
std::optional<uint64_t> size =
24392446
bound_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
24402447
if (!size)
24412448
return false;
24422449
AddressType address_type;
24432450
lldb::addr_t val_address = in_value.GetAddressOf(true, &address_type);
2451+
// If we couldn't find a load address, but the value object has a local
2452+
// buffer, use that.
2453+
if (val_address == LLDB_INVALID_ADDRESS && address_type == eAddressTypeHost) {
2454+
// Get the start and size of the local buffer.
2455+
auto start = in_value.GetValue().GetScalar().ULongLong();
2456+
auto local_buffer_size = in_value.GetLocalBufferSize();
2457+
2458+
// If we can't find the size of the local buffer we can't safely know if the
2459+
// dynamic type fits in it.
2460+
if (local_buffer_size == LLDB_INVALID_ADDRESS)
2461+
return false;
2462+
// If the dynamic type doesn't in the buffer we can't use it either.
2463+
if (local_buffer_size < bound_type.GetByteSize(exe_scope))
2464+
return false;
2465+
2466+
value_type = Value::GetValueTypeFromAddressType(address_type);
2467+
local_buffer = {(uint8_t *)start, local_buffer_size};
2468+
return true;
2469+
}
24442470
if (*size && (!val_address || val_address == LLDB_INVALID_ADDRESS))
24452471
return false;
24462472

@@ -2452,7 +2478,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Value(
24522478
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
24532479
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
24542480
TypeAndOrName &class_type_or_name, Address &address,
2455-
Value::ValueType &value_type) {
2481+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
24562482
Status error;
24572483
CompilerType child_type = in_value.GetCompilerType();
24582484
class_type_or_name.SetCompilerType(child_type);
@@ -2484,7 +2510,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
24842510
return false;
24852511

24862512
return GetDynamicTypeAndAddress(*valobj_sp, use_dynamic, class_type_or_name,
2487-
address, value_type);
2513+
address, value_type, local_buffer);
24882514
} else {
24892515
// This is most likely a statically known type.
24902516
address.SetLoadAddress(box_value, &GetProcess().GetTarget());
@@ -2510,7 +2536,8 @@ void SwiftLanguageRuntime::DumpTyperef(CompilerType type,
25102536

25112537
Value::ValueType SwiftLanguageRuntime::GetValueType(
25122538
ValueObject &in_value, CompilerType dynamic_type,
2513-
Value::ValueType static_value_type, bool is_indirect_enum_case) {
2539+
Value::ValueType static_value_type, bool is_indirect_enum_case,
2540+
llvm::ArrayRef<uint8_t> &local_buffer) {
25142541
CompilerType static_type = in_value.GetCompilerType();
25152542
Flags static_type_flags(static_type.GetTypeInfo());
25162543
Flags dynamic_type_flags(dynamic_type.GetTypeInfo());
@@ -2564,6 +2591,12 @@ Value::ValueType SwiftLanguageRuntime::GetValueType(
25642591
// If the data is not inlined, we have a pointer.
25652592
return Value::ValueType::LoadAddress;
25662593
}
2594+
// If we found a host address and the dynamic type fits in there, and
2595+
// this is not a pointer from an existential container, then this points to
2596+
// the local buffer.
2597+
if (static_value_type == Value::ValueType::HostAddress &&
2598+
!local_buffer.empty())
2599+
return static_value_type;
25672600

25682601
if (static_type_flags.AllSet(eTypeIsSwift | eTypeIsGenericTypeParam)) {
25692602
// if I am handling a non-pointer Swift type obtained from an archetype,
@@ -2671,7 +2704,7 @@ std::optional<SwiftNominalType> GetSwiftClass(ValueObject &valobj,
26712704
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_ClangType(
26722705
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
26732706
TypeAndOrName &class_type_or_name, Address &address,
2674-
Value::ValueType &value_type) {
2707+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
26752708
AppleObjCRuntime *objc_runtime =
26762709
SwiftLanguageRuntime::GetObjCRuntime(GetProcess());
26772710
if (!objc_runtime)
@@ -2684,8 +2717,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_ClangType(
26842717
// resolution first, and then map the dynamic Objective-C type back
26852718
// into Swift.
26862719
TypeAndOrName dyn_class_type_or_name = class_type_or_name;
2687-
if (!objc_runtime->GetDynamicTypeAndAddress(
2688-
in_value, use_dynamic, dyn_class_type_or_name, address, value_type))
2720+
if (!objc_runtime->GetDynamicTypeAndAddress(in_value, use_dynamic,
2721+
dyn_class_type_or_name, address,
2722+
value_type, local_buffer))
26892723
return false;
26902724

26912725
StringRef dyn_name = dyn_class_type_or_name.GetName().GetStringRef();
@@ -2791,7 +2825,7 @@ static bool CouldHaveDynamicValue(ValueObject &in_value) {
27912825
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
27922826
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
27932827
TypeAndOrName &class_type_or_name, Address &address,
2794-
Value::ValueType &value_type) {
2828+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
27952829
class_type_or_name.Clear();
27962830
if (use_dynamic == lldb::eNoDynamicValues)
27972831
return false;
@@ -2800,8 +2834,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28002834

28012835
// Try to import a Clang type into Swift.
28022836
if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC)
2803-
return GetDynamicTypeAndAddress_ClangType(
2804-
in_value, use_dynamic, class_type_or_name, address, value_type);
2837+
return GetDynamicTypeAndAddress_ClangType(in_value, use_dynamic,
2838+
class_type_or_name, address,
2839+
value_type, local_buffer);
28052840

28062841
if (!CouldHaveDynamicValue(in_value))
28072842
return false;
@@ -2817,7 +2852,8 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28172852
// Type kinds with instance metadata don't need generic type resolution.
28182853
if (is_indirect_enum_case)
28192854
success = GetDynamicTypeAndAddress_IndirectEnumCase(
2820-
in_value, use_dynamic, class_type_or_name, address, static_value_type);
2855+
in_value, use_dynamic, class_type_or_name, address, static_value_type,
2856+
local_buffer);
28212857
else if (type_info.AnySet(eTypeIsPack))
28222858
success = GetDynamicTypeAndAddress_Pack(in_value, val_type, use_dynamic,
28232859
class_type_or_name, address,
@@ -2826,7 +2862,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28262862
type_info.AllSet(eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue))
28272863
success = GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic,
28282864
class_type_or_name, address,
2829-
static_value_type);
2865+
static_value_type, local_buffer);
28302866
else if (type_info.AllSet(eTypeIsMetatype | eTypeIsProtocol))
28312867
success = GetDynamicTypeAndAddress_ExistentialMetatype(
28322868
in_value, val_type, use_dynamic, class_type_or_name, address);
@@ -2850,16 +2886,16 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28502886

28512887
Flags subst_type_info(bound_type.GetTypeInfo());
28522888
if (subst_type_info.AnySet(eTypeIsClass)) {
2853-
success = GetDynamicTypeAndAddress_Class(in_value, bound_type,
2854-
use_dynamic, class_type_or_name,
2855-
address, static_value_type);
2889+
success = GetDynamicTypeAndAddress_Class(
2890+
in_value, bound_type, use_dynamic, class_type_or_name, address,
2891+
static_value_type, local_buffer);
28562892
} else if (subst_type_info.AnySet(eTypeIsProtocol)) {
28572893
success = GetDynamicTypeAndAddress_Existential(
28582894
in_value, bound_type, use_dynamic, class_type_or_name, address);
28592895
} else {
2860-
success = GetDynamicTypeAndAddress_Value(in_value, bound_type,
2861-
use_dynamic, class_type_or_name,
2862-
address, static_value_type);
2896+
success = GetDynamicTypeAndAddress_Value(
2897+
in_value, bound_type, use_dynamic, class_type_or_name, address,
2898+
static_value_type, local_buffer);
28632899
}
28642900
}
28652901

@@ -2869,8 +2905,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28692905
if (static_value_type == Value::ValueType::Invalid)
28702906
static_value_type = in_value.GetValue().GetValueType();
28712907

2872-
value_type = GetValueType(in_value, class_type_or_name.GetCompilerType(),
2873-
static_value_type, is_indirect_enum_case);
2908+
value_type =
2909+
GetValueType(in_value, class_type_or_name.GetCompilerType(),
2910+
static_value_type, is_indirect_enum_case, local_buffer);
28742911
}
28752912
return success;
28762913
}

lldb/source/ValueObject/ValueObjectDynamicValue.cpp

Lines changed: 2 additions & 2 deletions
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 &&
@@ -193,7 +193,7 @@ bool ValueObjectDynamicValue::UpdateValue() {
193193
// Fallback to the runtime for `known_type`.
194194
found_dynamic_type = runtime->GetDynamicTypeAndAddress(
195195
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
196-
value_type);
196+
value_type, local_buffer);
197197
} else if (!found_dynamic_type) {
198198
runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
199199
if (runtime)

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)