diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h index e1567c7357d0b..48c9bef76857c 100644 --- a/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/lldb/include/lldb/Symbol/UnwindPlan.h @@ -215,6 +215,7 @@ class UnwindPlan { isRegisterDereferenced, // FA = [reg] isDWARFExpression, // FA = eval(dwarf_expr) isRaSearch, // FA = SP + offset + ??? + isConstant, // FA = constant }; FAValue() : m_value() {} @@ -259,6 +260,15 @@ class UnwindPlan { m_value.expr.length = len; } + bool IsConstant() const { return m_type == isConstant; } + + void SetIsConstant(uint64_t constant) { + m_type = isConstant; + m_value.constant = constant; + } + + uint64_t GetConstant() const { return m_value.constant; } + uint32_t GetRegisterNumber() const { if (m_type == isRegisterDereferenced || m_type == isRegisterPlusOffset) return m_value.reg.reg_num; @@ -329,6 +339,8 @@ class UnwindPlan { } expr; // For m_type == isRaSearch int32_t ra_search_offset; + // For m_type = isConstant + uint64_t constant; } m_value; }; // class FAValue diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp index a06e7cfd7f544..25e3676761436 100644 --- a/lldb/source/Symbol/UnwindPlan.cpp +++ b/lldb/source/Symbol/UnwindPlan.cpp @@ -187,6 +187,8 @@ operator==(const UnwindPlan::Row::FAValue &rhs) const { return !memcmp(m_value.expr.opcodes, rhs.m_value.expr.opcodes, m_value.expr.length); break; + case isConstant: + return m_value.constant == rhs.m_value.constant; } } return false; @@ -214,6 +216,8 @@ void UnwindPlan::Row::FAValue::Dump(Stream &s, const UnwindPlan *unwind_plan, case isRaSearch: s.Printf("RaSearch@SP%+d", m_value.ra_search_offset); break; + case isConstant: + s.Printf("0x%" PRIx64, m_value.constant); } } diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp index b683ea7237de0..9a4a8db84a9fa 100644 --- a/lldb/source/Target/RegisterContextUnwind.cpp +++ b/lldb/source/Target/RegisterContextUnwind.cpp @@ -2088,6 +2088,12 @@ bool RegisterContextUnwind::ReadFrameAddress( UnwindLogMsg("No suitable CFA found"); break; } + case UnwindPlan::Row::FAValue::isConstant: { + address = fa.GetConstant(); + address = m_thread.GetProcess()->FixDataAddress(address); + UnwindLogMsg("CFA value set by constant is 0x%" PRIx64, address); + return true; + } default: return false; }