summaryrefslogtreecommitdiff
path: root/lldb/source/ValueObject/ValueObjectDynamicValue.cpp
diff options
context:
space:
mode:
authorAugusto Noronha <anoronha@apple.com>2025-02-06 19:04:01 -0800
committerGitHub <noreply@github.com>2025-02-06 19:04:01 -0800
commit0cbc4983adcdbbd85ccb38b2dfbfe5985367b1b2 (patch)
tree2e38570729c780142c6f6811f9d7ebbc7e36df54 /lldb/source/ValueObject/ValueObjectDynamicValue.cpp
parent6f508492d13944edd0e7e70a3cc34eb29caeb8e9 (diff)
[lldb] Make ValueObjectDynamicValue::UpdateValue() point to a host b… (#125143)
…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
Diffstat (limited to 'lldb/source/ValueObject/ValueObjectDynamicValue.cpp')
-rw-r--r--lldb/source/ValueObject/ValueObjectDynamicValue.cpp43
1 files changed, 33 insertions, 10 deletions
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<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);
}
}
@@ -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<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());