Skip to content

Commit 28184f5

Browse files
authored
Merge pull request #9989 from augusto2112/cp-02-10
Support dynamic value object pointing to host address
2 parents 41229f3 + 93d7ce0 commit 28184f5

27 files changed

+440
-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: 59 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,40 @@ 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+
// Check if the dynamic type fits in the value object's buffer.
2461+
auto in_value_buffer = in_value.GetLocalBuffer();
2462+
2463+
// If we can't find the local buffer we can't safely know if the
2464+
// dynamic type fits in it.
2465+
if (in_value_buffer.empty())
2466+
return false;
2467+
// If the dynamic type doesn't in the buffer we can't use it either.
2468+
if (in_value_buffer.size() < bound_type.GetByteSize(exe_scope))
2469+
return false;
2470+
2471+
value_type = Value::GetValueTypeFromAddressType(address_type);
2472+
local_buffer = in_value_buffer;
2473+
return true;
2474+
}
24502475
if (*size && (!val_address || val_address == LLDB_INVALID_ADDRESS))
24512476
return false;
24522477

@@ -2458,7 +2483,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Value(
24582483
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
24592484
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
24602485
TypeAndOrName &class_type_or_name, Address &address,
2461-
Value::ValueType &value_type) {
2486+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
24622487
Status error;
24632488
CompilerType child_type = in_value.GetCompilerType();
24642489
class_type_or_name.SetCompilerType(child_type);
@@ -2490,7 +2515,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
24902515
return false;
24912516

24922517
return GetDynamicTypeAndAddress(*valobj_sp, use_dynamic, class_type_or_name,
2493-
address, value_type);
2518+
address, value_type, local_buffer);
24942519
} else {
24952520
// This is most likely a statically known type.
24962521
address.SetLoadAddress(box_value, &GetProcess().GetTarget());
@@ -2516,7 +2541,8 @@ void SwiftLanguageRuntime::DumpTyperef(CompilerType type,
25162541

25172542
Value::ValueType SwiftLanguageRuntime::GetValueType(
25182543
ValueObject &in_value, CompilerType dynamic_type,
2519-
Value::ValueType static_value_type, bool is_indirect_enum_case) {
2544+
Value::ValueType static_value_type, bool is_indirect_enum_case,
2545+
llvm::ArrayRef<uint8_t> &local_buffer) {
25202546
CompilerType static_type = in_value.GetCompilerType();
25212547
Flags static_type_flags(static_type.GetTypeInfo());
25222548
Flags dynamic_type_flags(dynamic_type.GetTypeInfo());
@@ -2570,6 +2596,12 @@ Value::ValueType SwiftLanguageRuntime::GetValueType(
25702596
// If the data is not inlined, we have a pointer.
25712597
return Value::ValueType::LoadAddress;
25722598
}
2599+
// If we found a host address and the dynamic type fits in there, and
2600+
// this is not a pointer from an existential container, then this points to
2601+
// the local buffer.
2602+
if (static_value_type == Value::ValueType::HostAddress &&
2603+
!local_buffer.empty())
2604+
return static_value_type;
25732605

25742606
if (static_type_flags.AllSet(eTypeIsSwift | eTypeIsGenericTypeParam)) {
25752607
// if I am handling a non-pointer Swift type obtained from an archetype,
@@ -2677,7 +2709,7 @@ std::optional<SwiftNominalType> GetSwiftClass(ValueObject &valobj,
26772709
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_ClangType(
26782710
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
26792711
TypeAndOrName &class_type_or_name, Address &address,
2680-
Value::ValueType &value_type) {
2712+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
26812713
AppleObjCRuntime *objc_runtime =
26822714
SwiftLanguageRuntime::GetObjCRuntime(GetProcess());
26832715
if (!objc_runtime)
@@ -2690,8 +2722,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_ClangType(
26902722
// resolution first, and then map the dynamic Objective-C type back
26912723
// into Swift.
26922724
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))
2725+
if (!objc_runtime->GetDynamicTypeAndAddress(in_value, use_dynamic,
2726+
dyn_class_type_or_name, address,
2727+
value_type, local_buffer))
26952728
return false;
26962729

26972730
StringRef dyn_name = dyn_class_type_or_name.GetName().GetStringRef();
@@ -2797,7 +2830,7 @@ static bool CouldHaveDynamicValue(ValueObject &in_value) {
27972830
bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
27982831
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
27992832
TypeAndOrName &class_type_or_name, Address &address,
2800-
Value::ValueType &value_type) {
2833+
Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
28012834
class_type_or_name.Clear();
28022835
if (use_dynamic == lldb::eNoDynamicValues)
28032836
return false;
@@ -2806,8 +2839,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28062839

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

28122846
if (!CouldHaveDynamicValue(in_value))
28132847
return false;
@@ -2823,7 +2857,8 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28232857
// Type kinds with instance metadata don't need generic type resolution.
28242858
if (is_indirect_enum_case)
28252859
success = GetDynamicTypeAndAddress_IndirectEnumCase(
2826-
in_value, use_dynamic, class_type_or_name, address, static_value_type);
2860+
in_value, use_dynamic, class_type_or_name, address, static_value_type,
2861+
local_buffer);
28272862
else if (type_info.AnySet(eTypeIsPack))
28282863
success = GetDynamicTypeAndAddress_Pack(in_value, val_type, use_dynamic,
28292864
class_type_or_name, address,
@@ -2832,7 +2867,7 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28322867
type_info.AllSet(eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue))
28332868
success = GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic,
28342869
class_type_or_name, address,
2835-
static_value_type);
2870+
static_value_type, local_buffer);
28362871
else if (type_info.AllSet(eTypeIsMetatype | eTypeIsProtocol))
28372872
success = GetDynamicTypeAndAddress_ExistentialMetatype(
28382873
in_value, val_type, use_dynamic, class_type_or_name, address);
@@ -2856,16 +2891,16 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28562891

28572892
Flags subst_type_info(bound_type.GetTypeInfo());
28582893
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);
2894+
success = GetDynamicTypeAndAddress_Class(
2895+
in_value, bound_type, use_dynamic, class_type_or_name, address,
2896+
static_value_type, local_buffer);
28622897
} else if (subst_type_info.AnySet(eTypeIsProtocol)) {
28632898
success = GetDynamicTypeAndAddress_Existential(
28642899
in_value, bound_type, use_dynamic, class_type_or_name, address);
28652900
} else {
2866-
success = GetDynamicTypeAndAddress_Value(in_value, bound_type,
2867-
use_dynamic, class_type_or_name,
2868-
address, static_value_type);
2901+
success = GetDynamicTypeAndAddress_Value(
2902+
in_value, bound_type, use_dynamic, class_type_or_name, address,
2903+
static_value_type, local_buffer);
28692904
}
28702905
}
28712906

@@ -2875,8 +2910,9 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
28752910
if (static_value_type == Value::ValueType::Invalid)
28762911
static_value_type = in_value.GetValue().GetValueType();
28772912

2878-
value_type = GetValueType(in_value, class_type_or_name.GetCompilerType(),
2879-
static_value_type, is_indirect_enum_case);
2913+
value_type =
2914+
GetValueType(in_value, class_type_or_name.GetCompilerType(),
2915+
static_value_type, is_indirect_enum_case, local_buffer);
28802916
}
28812917
return success;
28822918
}

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 &&
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
SWIFT_SOURCES := main.swift
2+
3+
all: libPublic.dylib a.out
4+
5+
include Makefile.rules
6+
LD_EXTRAS = -lPublic -L$(BUILDDIR)
7+
SWIFTFLAGS_EXTRAS = -I$(BUILDDIR)
8+
9+
libPublic.dylib: Public.swift
10+
"$(MAKE)" MAKE_DSYM=YES CC=$(CC) SWIFTC=$(SWIFTC) \
11+
ARCH=$(ARCH) DSYMUTIL=$(DSYMUTIL) \
12+
BASENAME=Public \
13+
SWIFTFLAGS_EXTRAS="-I$(BUILDDIR) -enable-library-evolution -enable-testing" \
14+
VPATH=$(SRCDIR) -I $(SRCDIR) \
15+
DYLIB_ONLY:=YES DYLIB_NAME=Public \
16+
DYLIB_SWIFT_SOURCES:=Public.swift \
17+
-f $(MAKEFILE_RULES)
18+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class SomeClass {
2+
let value = 42
3+
}
4+
5+
class ClassWithProperty {
6+
private var v = SomeClass()
7+
8+
func f() {
9+
print("break here")
10+
}
11+
}
12+
13+
public func entry() {
14+
ClassWithProperty().f()
15+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
6+
7+
class TestSwiftEnableTesting(TestBase):
8+
9+
@skipUnlessDarwin
10+
@swiftTest
11+
def test(self):
12+
"""Test that expression evaluation generates a direct member access to a private property in a module compiled with -enable-library-evolution and -enable-testing"""
13+
14+
self.build()
15+
target, process, _, _ = lldbutil.run_to_source_breakpoint(
16+
self, "break here", lldb.SBFileSpec("Public.swift"), extra_images=["Public"]
17+
)
18+
19+
self.expect("expression v", substrs=["Public.SomeClass", "value = 42"])
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Public
2+
3+
entry()

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)