1 //===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "RegisterContextMacOSXFrameBackchain.h"
14 // Other libraries and framework includes
15 #include "lldb/Core/RegisterValue.h"
16 #include "lldb/Core/Scalar.h"
17 #include "lldb/Target/Thread.h"
18 #include "lldb/Utility/DataBufferHeap.h"
19 #include "lldb/Utility/DataExtractor.h"
20 #include "lldb/Utility/StreamString.h"
22 #include "lldb/Utility/StringExtractorGDBRemote.h"
25 using namespace lldb_private;
27 //----------------------------------------------------------------------
28 // RegisterContextMacOSXFrameBackchain constructor
29 //----------------------------------------------------------------------
30 RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
31 Thread &thread, uint32_t concrete_frame_idx,
32 const UnwindMacOSXFrameBackchain::Cursor &cursor)
33 : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
34 m_cursor_is_valid(true) {}
36 //----------------------------------------------------------------------
38 //----------------------------------------------------------------------
39 RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}
41 void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
42 m_cursor_is_valid = false;
45 size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
46 return m_thread.GetRegisterContext()->GetRegisterCount();
50 RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
51 return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
54 size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
55 return m_thread.GetRegisterContext()->GetRegisterSetCount();
59 RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
60 return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
63 bool RegisterContextMacOSXFrameBackchain::ReadRegister(
64 const RegisterInfo *reg_info, RegisterValue &value) {
65 if (!m_cursor_is_valid)
68 uint64_t reg_value = LLDB_INVALID_ADDRESS;
70 switch (reg_info->kinds[eRegisterKindGeneric]) {
71 case LLDB_REGNUM_GENERIC_PC:
72 if (m_cursor.pc == LLDB_INVALID_ADDRESS)
74 reg_value = m_cursor.pc;
77 case LLDB_REGNUM_GENERIC_FP:
78 if (m_cursor.fp == LLDB_INVALID_ADDRESS)
80 reg_value = m_cursor.fp;
87 switch (reg_info->encoding) {
88 case eEncodingInvalid:
94 value.SetUInt(reg_value, reg_info->byte_size);
97 case eEncodingIEEE754:
98 switch (reg_info->byte_size) {
100 if (sizeof(float) == sizeof(uint32_t)) {
101 value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
103 } else if (sizeof(float) == sizeof(uint64_t)) {
104 value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
110 if (sizeof(double) == sizeof(uint32_t)) {
111 value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
113 } else if (sizeof(double) == sizeof(uint64_t)) {
114 value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
119 // TOOD: need a better way to detect when "long double" types are
120 // the same bytes size as "double"
121 #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && \
122 !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) && \
123 !defined(__ANDROID__)
124 case sizeof(long double):
125 if (sizeof(long double) == sizeof(uint32_t)) {
126 value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
128 } else if (sizeof(long double) == sizeof(uint64_t)) {
129 value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
140 bool RegisterContextMacOSXFrameBackchain::WriteRegister(
141 const RegisterInfo *reg_info, const RegisterValue &value) {
142 // Not supported yet. We could easily add support for this by remembering the
143 // address of each entry (it would need to be part of the cursor)
147 bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
148 lldb::DataBufferSP &data_sp) {
149 // libunwind frames can't handle this it doesn't always have all register
150 // values. This call should only be called on frame zero anyway so there
151 // shouldn't be any problem
155 bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
156 const lldb::DataBufferSP &data_sp) {
157 // Since this class doesn't respond to "ReadAllRegisterValues()", it must not
158 // have been the one that saved all the register values. So we just let the
159 // thread's register context (the register context for frame zero) do the
161 return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
165 RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
166 lldb::RegisterKind kind, uint32_t num) {
167 return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(