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"
12 #include "lldb/Target/Thread.h"
13 #include "lldb/Utility/DataBufferHeap.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "lldb/Utility/RegisterValue.h"
16 #include "lldb/Utility/Scalar.h"
17 #include "lldb/Utility/StreamString.h"
18 #include "lldb/Utility/StringExtractorGDBRemote.h"
21 using namespace lldb_private;
23 //----------------------------------------------------------------------
24 // RegisterContextMacOSXFrameBackchain constructor
25 //----------------------------------------------------------------------
26 RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
27 Thread &thread, uint32_t concrete_frame_idx,
28 const UnwindMacOSXFrameBackchain::Cursor &cursor)
29 : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
30 m_cursor_is_valid(true) {}
32 //----------------------------------------------------------------------
34 //----------------------------------------------------------------------
35 RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}
37 void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
38 m_cursor_is_valid = false;
41 size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
42 return m_thread.GetRegisterContext()->GetRegisterCount();
46 RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
47 return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
50 size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
51 return m_thread.GetRegisterContext()->GetRegisterSetCount();
55 RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
56 return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
59 bool RegisterContextMacOSXFrameBackchain::ReadRegister(
60 const RegisterInfo *reg_info, RegisterValue &value) {
61 if (!m_cursor_is_valid)
64 uint64_t reg_value = LLDB_INVALID_ADDRESS;
66 switch (reg_info->kinds[eRegisterKindGeneric]) {
67 case LLDB_REGNUM_GENERIC_PC:
68 if (m_cursor.pc == LLDB_INVALID_ADDRESS)
70 reg_value = m_cursor.pc;
73 case LLDB_REGNUM_GENERIC_FP:
74 if (m_cursor.fp == LLDB_INVALID_ADDRESS)
76 reg_value = m_cursor.fp;
83 switch (reg_info->encoding) {
84 case eEncodingInvalid:
90 value.SetUInt(reg_value, reg_info->byte_size);
93 case eEncodingIEEE754:
94 switch (reg_info->byte_size) {
96 if (sizeof(float) == sizeof(uint32_t)) {
97 value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
99 } else if (sizeof(float) == sizeof(uint64_t)) {
100 value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
106 if (sizeof(double) == sizeof(uint32_t)) {
107 value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
109 } else if (sizeof(double) == sizeof(uint64_t)) {
110 value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
115 // TOOD: need a better way to detect when "long double" types are
116 // the same bytes size as "double"
117 #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && \
118 !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) && \
119 !defined(__ANDROID__)
120 case sizeof(long double):
121 if (sizeof(long double) == sizeof(uint32_t)) {
122 value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
124 } else if (sizeof(long double) == sizeof(uint64_t)) {
125 value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
136 bool RegisterContextMacOSXFrameBackchain::WriteRegister(
137 const RegisterInfo *reg_info, const RegisterValue &value) {
138 // Not supported yet. We could easily add support for this by remembering the
139 // address of each entry (it would need to be part of the cursor)
143 bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
144 lldb::DataBufferSP &data_sp) {
145 // libunwind frames can't handle this it doesn't always have all register
146 // values. This call should only be called on frame zero anyway so there
147 // shouldn't be any problem
151 bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
152 const lldb::DataBufferSP &data_sp) {
153 // Since this class doesn't respond to "ReadAllRegisterValues()", it must not
154 // have been the one that saved all the register values. So we just let the
155 // thread's register context (the register context for frame zero) do the
157 return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
161 RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
162 lldb::RegisterKind kind, uint32_t num) {
163 return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(