LLDB  mainline
RegisterContextMacOSXFrameBackchain.cpp
Go to the documentation of this file.
1 //===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "lldb/Target/Thread.h"
15 #include "lldb/Utility/Scalar.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 // RegisterContextMacOSXFrameBackchain constructor
24  Thread &thread, uint32_t concrete_frame_idx,
26  : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
27  m_cursor_is_valid(true) {}
28 
29 // Destructor
31 
33  m_cursor_is_valid = false;
34 }
35 
37  return m_thread.GetRegisterContext()->GetRegisterCount();
38 }
39 
40 const RegisterInfo *
42  return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
43 }
44 
46  return m_thread.GetRegisterContext()->GetRegisterSetCount();
47 }
48 
49 const RegisterSet *
51  return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
52 }
53 
55  const RegisterInfo *reg_info, RegisterValue &value) {
56  if (!m_cursor_is_valid)
57  return false;
58 
59  uint64_t reg_value = LLDB_INVALID_ADDRESS;
60 
61  switch (reg_info->kinds[eRegisterKindGeneric]) {
63  if (m_cursor.pc == LLDB_INVALID_ADDRESS)
64  return false;
65  reg_value = m_cursor.pc;
66  break;
67 
69  if (m_cursor.fp == LLDB_INVALID_ADDRESS)
70  return false;
71  reg_value = m_cursor.fp;
72  break;
73 
74  default:
75  return false;
76  }
77 
78  switch (reg_info->encoding) {
79  case eEncodingInvalid:
80  case eEncodingVector:
81  break;
82 
83  case eEncodingUint:
84  case eEncodingSint:
85  value.SetUInt(reg_value, reg_info->byte_size);
86  return true;
87 
88  case eEncodingIEEE754:
89  switch (reg_info->byte_size) {
90  case sizeof(float):
91  if (sizeof(float) == sizeof(uint32_t)) {
92  value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
93  return true;
94  } else if (sizeof(float) == sizeof(uint64_t)) {
95  value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
96  return true;
97  }
98  break;
99 
100  case sizeof(double):
101  if (sizeof(double) == sizeof(uint32_t)) {
102  value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
103  return true;
104  } else if (sizeof(double) == sizeof(uint64_t)) {
105  value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
106  return true;
107  }
108  break;
109 
110 // TOOD: need a better way to detect when "long double" types are
111 // the same bytes size as "double"
112 #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && \
113  !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) && \
114  !defined(__ANDROID__)
115  case sizeof(long double):
116  if (sizeof(long double) == sizeof(uint32_t)) {
117  value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
118  return true;
119  } else if (sizeof(long double) == sizeof(uint64_t)) {
120  value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
121  return true;
122  }
123  break;
124 #endif
125  }
126  break;
127  }
128  return false;
129 }
130 
132  const RegisterInfo *reg_info, const RegisterValue &value) {
133  // Not supported yet. We could easily add support for this by remembering the
134  // address of each entry (it would need to be part of the cursor)
135  return false;
136 }
137 
139  lldb::DataBufferSP &data_sp) {
140  // libunwind frames can't handle this it doesn't always have all register
141  // values. This call should only be called on frame zero anyway so there
142  // shouldn't be any problem
143  return false;
144 }
145 
147  const lldb::DataBufferSP &data_sp) {
148  // Since this class doesn't respond to "ReadAllRegisterValues()", it must not
149  // have been the one that saved all the register values. So we just let the
150  // thread's register context (the register context for frame zero) do the
151  // writing.
152  return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
153 }
154 
155 uint32_t
157  lldb::RegisterKind kind, uint32_t num) {
158  return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
159  kind, num);
160 }
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
const lldb_private::RegisterSet * GetRegisterSet(size_t reg_set) override
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
bool SetUInt(uint64_t uint, uint32_t byte_size)
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
virtual lldb::RegisterContextSP GetRegisterContext()=0
bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override
Definition: SBAddress.h:15
RegisterContextMacOSXFrameBackchain(lldb_private::Thread &thread, uint32_t concrete_frame_idx, const UnwindMacOSXFrameBackchain::Cursor &cursor)
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.