[Lldb-commits] [lldb] [lldb] Add constant value mode for RegisterLocation in UnwindPlans (PR #100624)
Felipe de Azevedo Piovezan via lldb-commits
lldb-commits at lists.llvm.org
Tue Jul 30 08:09:32 PDT 2024
https://github.com/felipepiovezan updated https://github.com/llvm/llvm-project/pull/100624
>From 223075d6f036537a7edec10b370f6d922135cb79 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Tue, 23 Jul 2024 13:30:40 -0700
Subject: [PATCH 1/2] [lldb] Add constant value mode for RegisterLocation in
UnwindPlans
This is useful for language runtimes that compute register values by inspecting
the state of the currently running process. Currently, there are no mechanisms
enabling these runtimes to set register values to arbitrary values.
The alternative considered would involve creating a dwarf expression that
produces an arbitrary integer (e.g. using OP_constu). However, the current data
structure for Rows is such that they do not own any memory associated with dwarf
expressions, which implies any such expression would need to have static storage
and therefore could not contain a runtime value.
Adding a new rule for constants leads to a simpler implementation. It's also
worth noting that this does not make the "Location" union any bigger, since it
already contains a pointer+size pair.
---
lldb/include/lldb/Symbol/UnwindPlan.h | 17 ++++++++++++++++-
lldb/source/Symbol/UnwindPlan.cpp | 17 +++++++++++++++++
lldb/source/Target/RegisterContextUnwind.cpp | 9 +++++++++
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h
index ebb0ec421da72..a9e8406608ff3 100644
--- a/lldb/include/lldb/Symbol/UnwindPlan.h
+++ b/lldb/include/lldb/Symbol/UnwindPlan.h
@@ -68,7 +68,8 @@ class UnwindPlan {
isAFAPlusOffset, // reg = AFA + offset
inOtherRegister, // reg = other reg
atDWARFExpression, // reg = deref(eval(dwarf_expr))
- isDWARFExpression // reg = eval(dwarf_expr)
+ isDWARFExpression, // reg = eval(dwarf_expr)
+ isConstant // reg = constant
};
RegisterLocation() : m_location() {}
@@ -105,6 +106,15 @@ class UnwindPlan {
bool IsDWARFExpression() const { return m_type == isDWARFExpression; }
+ bool IsConstant() const { return m_type == isConstant; }
+
+ void SetIsConstant(uint64_t value) {
+ m_type = isConstant;
+ m_location.constant_value = value;
+ }
+
+ uint64_t GetConstant() const { return m_location.constant_value; }
+
void SetAtCFAPlusOffset(int32_t offset) {
m_type = atCFAPlusOffset;
m_location.offset = offset;
@@ -192,6 +202,8 @@ class UnwindPlan {
const uint8_t *opcodes;
uint16_t length;
} expr;
+ // For m_type == isConstant
+ uint64_t constant_value;
} m_location;
};
@@ -358,6 +370,9 @@ class UnwindPlan {
bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace);
+ bool SetRegisterLocationToIsConstant(uint32_t reg_num, uint64_t constant,
+ bool can_replace);
+
// When this UnspecifiedRegistersAreUndefined mode is
// set, any register that is not specified by this Row will
// be described as Undefined.
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index e258a4e3d82f2..fcd3154a01d82 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -46,6 +46,8 @@ operator==(const UnwindPlan::Row::RegisterLocation &rhs) const {
return !memcmp(m_location.expr.opcodes, rhs.m_location.expr.opcodes,
m_location.expr.length);
break;
+ case isConstant:
+ return m_location.constant_value == rhs.m_location.constant_value;
}
}
return false;
@@ -153,6 +155,9 @@ void UnwindPlan::Row::RegisterLocation::Dump(Stream &s,
if (m_type == atDWARFExpression)
s.PutChar(']');
} break;
+ case isConstant:
+ s.Printf("=%x", m_location.offset);
+ break;
}
}
@@ -351,6 +356,18 @@ bool UnwindPlan::Row::SetRegisterLocationToSame(uint32_t reg_num,
return true;
}
+bool UnwindPlan::Row::SetRegisterLocationToIsConstant(uint32_t reg_num,
+ uint64_t constant,
+ bool can_replace) {
+ if (!can_replace &&
+ m_register_locations.find(reg_num) != m_register_locations.end())
+ return false;
+ RegisterLocation reg_loc;
+ reg_loc.SetIsConstant(constant);
+ m_register_locations[reg_num] = reg_loc;
+ return true;
+}
+
bool UnwindPlan::Row::operator==(const UnwindPlan::Row &rhs) const {
return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value &&
m_afa_value == rhs.m_afa_value &&
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index 95e8abd763d53..f74f1dc0e1b80 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -1694,6 +1694,15 @@ RegisterContextUnwind::SavedLocationForRegister(
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
+ if (unwindplan_regloc.IsConstant()) {
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
+ regloc.location.inferred_value = unwindplan_regloc.GetConstant();
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) via constant value",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+
UnwindLogMsg("no save location for %s (%d) in this stack frame",
regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
>From 4aa1086282c5587708969bb0d2f9a7c2f650d9c6 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Tue, 30 Jul 2024 08:09:10 -0700
Subject: [PATCH 2/2] fixup! [lldb] Add constant value mode for
RegisterLocation in UnwindPlans
---
lldb/source/Symbol/UnwindPlan.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index fcd3154a01d82..e2dbd81a82c84 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -156,7 +156,7 @@ void UnwindPlan::Row::RegisterLocation::Dump(Stream &s,
s.PutChar(']');
} break;
case isConstant:
- s.Printf("=%x", m_location.offset);
+ s.Printf("=0x%" PRIx64, m_location.constant_value);
break;
}
}
More information about the lldb-commits
mailing list