From 0cbc4983adcdbbd85ccb38b2dfbfe5985367b1b2 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Thu, 6 Feb 2025 19:04:01 -0800 Subject: =?UTF-8?q?[lldb]=20Make=20ValueObjectDynamicValue::UpdateValue()?= =?UTF-8?q?=20point=20to=20=20a=20host=20b=E2=80=A6=20(#125143)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …uffer 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 --- .../source/ValueObject/ValueObjectDynamicValue.cpp | 43 +++++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'lldb/source/ValueObject/ValueObjectDynamicValue.cpp') diff --git a/lldb/source/ValueObject/ValueObjectDynamicValue.cpp b/lldb/source/ValueObject/ValueObjectDynamicValue.cpp index 588c644bbfd0..dddb0f0700b3 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 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); } } @@ -239,11 +240,29 @@ 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, and the dynamic type fits in the local buffer + // that was found, point to thar buffer. Later on this function will copy + // the buffer over. + if (value_type == Value::ValueType::HostAddress && !local_buffer.empty()) { + auto *exe_scope = exe_ctx.GetBestExecutionContextScope(); + // If we found a host address but it doesn't fit in the buffer, there's + // nothing we can do. + if (local_buffer.size() < + m_dynamic_type_info.GetCompilerType().GetByteSize(exe_scope)) { + SetValueIsValid(false); + return false; + } + + 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 + // 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 +277,11 @@ bool ValueObjectDynamicValue::UpdateValue() { LLDB_LOGF(log, "[%s %p] has a new dynamic type %s", GetName().GetCString(), static_cast(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()); -- cgit v1.2.3