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 <anoro...@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 <anoro...@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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits