[Lldb-commits] [lldb] [lldb] Make ValueObjectDynamicValue::UpdateValue() point to a host b… (PR #125143)
Augusto Noronha via lldb-commits
lldb-commits at lists.llvm.org
Mon Feb 3 11:24:14 PST 2025
https://github.com/augusto2112 updated https://github.com/llvm/llvm-project/pull/125143
>From 0c22a94214e97146b2592b77ac96255bdee47b0f Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Thu, 30 Jan 2025 16:33:09 -0800
Subject: [PATCH 1/2] [lldb] Make ValueObjectDynamicValue::UpdateValue() point
to a host buffer
ValueObjectDynamicValue::UpdateValue() assumes that the dynamic type
found by GetDynamicTypeAndAddress() would return an address in the
inferior. This commit makes it so it can deal with being passed a
host address instead.
This is needed downstream by the Swift fork.
rdar://143357274
---
lldb/include/lldb/Target/LanguageRuntime.h | 4 +++-
.../ValueObject/ValueObjectDynamicValue.cpp | 24 ++++++++++++++-----
2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 4a0214b04e235e..08db8a17a67e69 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -105,7 +105,9 @@ class LanguageRuntime : public Runtime, public PluginInterface {
"language doesn't support getting vtable information");
}
- // this call should return true if it could set the name and/or the type
+ // This call should return true if it could set the name and/or the type.
+ // address can be either a legitimate address on the inferior, or an address
+ // in lldb, if value_type == HostAddress.
virtual bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
diff --git a/lldb/source/ValueObject/ValueObjectDynamicValue.cpp b/lldb/source/ValueObject/ValueObjectDynamicValue.cpp
index 588c644bbfd07b..10a5a9d0b76919 100644
--- a/lldb/source/ValueObject/ValueObjectDynamicValue.cpp
+++ b/lldb/source/ValueObject/ValueObjectDynamicValue.cpp
@@ -239,11 +239,19 @@ bool ValueObjectDynamicValue::UpdateValue() {
if (m_address.IsValid())
SetValueDidChange(true);
- // We've moved, so we should be fine...
- m_address = dynamic_address;
- lldb::TargetSP target_sp(GetTargetSP());
- lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
- m_value.GetScalar() = load_address;
+ // If we found a host address, point to the buffer in host memory.
+ // Later on this function will copy the buffer over.
+ if (value_type == Value::ValueType::HostAddress) {
+ m_value.GetScalar() = dynamic_address.GetOffset();
+ m_address = LLDB_INVALID_ADDRESS;
+ } else {
+ // Otherwise we have a legitimate address on the target. Point to the load
+ // address.
+ m_address = dynamic_address;
+ lldb::TargetSP target_sp(GetTargetSP());
+ lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
+ m_value.GetScalar() = load_address;
+ }
}
if (runtime)
@@ -258,7 +266,11 @@ bool ValueObjectDynamicValue::UpdateValue() {
LLDB_LOGF(log, "[%s %p] has a new dynamic type %s", GetName().GetCString(),
static_cast<void *>(this), GetTypeName().GetCString());
- if (m_address.IsValid() && m_dynamic_type_info) {
+ // m_address could be invalid but we could still have a local buffer
+ // containing the dynamic value.
+ if ((m_address.IsValid() ||
+ m_value.GetValueType() == Value::ValueType::HostAddress) &&
+ m_dynamic_type_info) {
// The variable value is in the Scalar value inside the m_value. We can
// point our m_data right to it.
m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
>From 64eb2c0365daf780a0e372c0fcbd9e4023c6a518 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Mon, 3 Feb 2025 11:23:41 -0800
Subject: [PATCH 2/2] Added a new local_buffer parameter to
GetDynamicTypeAndAddress
---
lldb/include/lldb/Target/LanguageRuntime.h | 16 ++++++++--------
lldb/include/lldb/ValueObject/ValueObject.h | 12 ++++++++++++
.../ItaniumABI/ItaniumABILanguageRuntime.cpp | 2 +-
.../ItaniumABI/ItaniumABILanguageRuntime.h | 4 ++--
.../ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp | 2 +-
.../ObjC/AppleObjCRuntime/AppleObjCRuntime.h | 4 ++--
.../ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp | 2 +-
.../ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h | 4 ++--
.../ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 2 +-
.../ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h | 4 ++--
.../GNUstepObjCRuntime/GNUstepObjCRuntime.cpp | 2 +-
.../ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h | 4 ++--
lldb/source/ValueObject/ValueObject.cpp | 16 ++++++++++++++++
.../ValueObject/ValueObjectDynamicValue.cpp | 13 +++++++------
14 files changed, 58 insertions(+), 29 deletions(-)
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 08db8a17a67e69..da7b4801be6691 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -105,14 +105,14 @@ class LanguageRuntime : public Runtime, public PluginInterface {
"language doesn't support getting vtable information");
}
- // This call should return true if it could set the name and/or the type.
- // address can be either a legitimate address on the inferior, or an address
- // in lldb, if value_type == HostAddress.
- virtual bool GetDynamicTypeAndAddress(ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) = 0;
+ /// This call should return true if it could set the name and/or the type
+ /// Sets address to the address of the dynamic type if value_type is set to
+ /// a file or load address. Sets local_buffer to a buffer containing the data
+ /// of the dynamic type if value_type is set to a host address.
+ virtual bool GetDynamicTypeAndAddress(
+ ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) = 0;
// This call should return a CompilerType given a generic type name and an
// ExecutionContextScope in which one can actually fetch any specialization
diff --git a/lldb/include/lldb/ValueObject/ValueObject.h b/lldb/include/lldb/ValueObject/ValueObject.h
index 4f77384bb8f136..c8d5c2723106d6 100644
--- a/lldb/include/lldb/ValueObject/ValueObject.h
+++ b/lldb/include/lldb/ValueObject/ValueObject.h
@@ -865,6 +865,18 @@ class ValueObject {
virtual void SetLanguageFlags(uint64_t flags) { m_language_flags = flags; }
+ /// Returns the size of the local buffer if it's available.
+ /// \return
+ /// The size of the local buffer if this value object's value points to a
+ /// host address, and if that size can be determined. Otherwise, returns
+ /// LLDB_INVALID_ADDRESS.
+ ///
+ /// TODO: Because a ValueObject's Value can point to any arbitrary memory
+ /// location, it is possible that the size of the local buffer can't be
+ /// determined at all. See the comment in Value::m_value for a more thorough
+ /// explanation of why that is.
+ uint64_t GetLocalBufferSize();
+
protected:
typedef ClusterManager<ValueObject> ValueObjectManager;
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 66cdab1307ce9b..8faf7135217acf 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -289,7 +289,7 @@ llvm::Expected<LanguageRuntime::VTableInfo>
bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &dynamic_address,
- Value::ValueType &value_type) {
+ Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
// For Itanium, if the type has a vtable pointer in the object, it will be at
// offset 0 in the object. That will point to the "address point" within the
// vtable (not the beginning of the vtable.) We can then look up the symbol
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index 0f7e73cfee0754..7abf2f8547cd50 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -54,8 +54,8 @@ class ItaniumABILanguageRuntime : public lldb_private::CPPLanguageRuntime {
bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
+ Address &address, Value::ValueType &value_type,
+ llvm::ArrayRef<uint8_t> &local_buffer) override;
TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
ValueObject &static_value) override;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index ceee19c136d253..ad60290382c02d 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -276,7 +276,7 @@ bool AppleObjCRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
bool AppleObjCRuntime::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &address,
- Value::ValueType &value_type) {
+ Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
return false;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
index da58d44db19a89..425a608d65c2cf 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
@@ -54,8 +54,8 @@ class AppleObjCRuntime : public lldb_private::ObjCLanguageRuntime {
bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
+ Address &address, Value::ValueType &value_type,
+ llvm::ArrayRef<uint8_t> &local_buffer) override;
TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
ValueObject &static_value) override;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 93168c23f3547b..db1317d70d060c 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -48,7 +48,7 @@ AppleObjCRuntimeV1::AppleObjCRuntimeV1(Process *process)
bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &address,
- Value::ValueType &value_type) {
+ Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
class_type_or_name.Clear();
value_type = Value::ValueType::Scalar;
if (CouldHaveDynamicValue(in_value)) {
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index 46d8e89c906e32..c51ac24e690b80 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -100,8 +100,8 @@ class AppleObjCRuntimeV1 : public AppleObjCRuntime {
bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
+ Address &address, Value::ValueType &value_type,
+ llvm::ArrayRef<uint8_t> &local_buffer) override;
llvm::Expected<std::unique_ptr<UtilityFunction>>
CreateObjectChecker(std::string, ExecutionContext &exe_ctx) override;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index c43871b08191db..a57099f3df4543 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -770,7 +770,7 @@ AppleObjCRuntimeV2::GetPreferredLanguageRuntime(ValueObject &in_value) {
bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &address,
- Value::ValueType &value_type) {
+ Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
// We should never get here with a null process...
assert(m_process != nullptr);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 2422539b13f13d..79840f9be79b3a 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -53,8 +53,8 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime {
bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
+ Address &address, Value::ValueType &value_type,
+ llvm::ArrayRef<uint8_t> &local_buffer) override;
llvm::Expected<std::unique_ptr<UtilityFunction>>
CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp
index d6ffb03ab55e2c..a4b3e26474a550 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp
@@ -127,7 +127,7 @@ bool GNUstepObjCRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
bool GNUstepObjCRuntime::GetDynamicTypeAndAddress(
ValueObject &in_value, DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &address,
- Value::ValueType &value_type) {
+ Value::ValueType &value_type, llvm::ArrayRef<uint8_t> &local_buffer) {
return false;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h
index de24466ebb003c..94a5c9e1261a82 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h
@@ -67,8 +67,8 @@ class GNUstepObjCRuntime : public lldb_private::ObjCLanguageRuntime {
bool GetDynamicTypeAndAddress(ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
+ Address &address, Value::ValueType &value_type,
+ llvm::ArrayRef<uint8_t> &local_buffer) override;
TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
ValueObject &static_value) override;
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index 2864af107b925f..551d882a48d40f 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -849,6 +849,22 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) {
return true;
}
+uint64_t ValueObject::GetLocalBufferSize() {
+ if (m_value.GetValueType() != Value::ValueType::HostAddress)
+ return LLDB_INVALID_ADDRESS;
+ auto start = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (start == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+ // Does our pointer point to this value object's m_data buffer?
+ if ((uint64_t)m_data.GetDataStart() == start)
+ return m_data.GetByteSize();
+ // Does our pointer point to the value's buffer?
+ if ((uint64_t)m_value.GetBuffer().GetBytes() == start)
+ return m_value.GetBuffer().GetByteSize();
+ // Our pointer points to something else. We can't know what the size is.
+ return LLDB_INVALID_ADDRESS;
+}
+
static bool CopyStringDataToBufferSP(const StreamString &source,
lldb::WritableDataBufferSP &destination) {
llvm::StringRef src = source.GetString();
diff --git a/lldb/source/ValueObject/ValueObjectDynamicValue.cpp b/lldb/source/ValueObject/ValueObjectDynamicValue.cpp
index 10a5a9d0b76919..6d6e589b534067 100644
--- a/lldb/source/ValueObject/ValueObjectDynamicValue.cpp
+++ b/lldb/source/ValueObject/ValueObjectDynamicValue.cpp
@@ -145,6 +145,7 @@ bool ValueObjectDynamicValue::UpdateValue() {
Address dynamic_address;
bool found_dynamic_type = false;
Value::ValueType value_type;
+ llvm::ArrayRef<uint8_t> local_buffer;
LanguageRuntime *runtime = nullptr;
@@ -157,7 +158,7 @@ bool ValueObjectDynamicValue::UpdateValue() {
// Try the preferred runtime first.
found_dynamic_type = preferred_runtime->GetDynamicTypeAndAddress(
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
- value_type);
+ value_type, local_buffer);
if (found_dynamic_type)
// Set the operative `runtime` for later use in this function.
runtime = preferred_runtime;
@@ -166,20 +167,20 @@ bool ValueObjectDynamicValue::UpdateValue() {
// Fallback to the runtime for `known_type`.
found_dynamic_type = runtime->GetDynamicTypeAndAddress(
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
- value_type);
+ value_type, local_buffer);
} else {
runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
if (runtime)
found_dynamic_type = runtime->GetDynamicTypeAndAddress(
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
- value_type);
+ value_type, local_buffer);
if (!found_dynamic_type) {
runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
if (runtime)
found_dynamic_type = runtime->GetDynamicTypeAndAddress(
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
- value_type);
+ value_type, local_buffer);
}
}
@@ -241,8 +242,8 @@ bool ValueObjectDynamicValue::UpdateValue() {
// If we found a host address, point to the buffer in host memory.
// Later on this function will copy the buffer over.
- if (value_type == Value::ValueType::HostAddress) {
- m_value.GetScalar() = dynamic_address.GetOffset();
+ if (value_type == Value::ValueType::HostAddress && !local_buffer.empty()) {
+ m_value.GetScalar() = (uint64_t)local_buffer.data();
m_address = LLDB_INVALID_ADDRESS;
} else {
// Otherwise we have a legitimate address on the target. Point to the load
More information about the lldb-commits
mailing list