]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / Process / Utility / RegisterContextMacOSXFrameBackchain.cpp
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
9 #include "RegisterContextMacOSXFrameBackchain.h"
10
11 #include "lldb/Target/Thread.h"
12 #include "lldb/Utility/DataBufferHeap.h"
13 #include "lldb/Utility/DataExtractor.h"
14 #include "lldb/Utility/RegisterValue.h"
15 #include "lldb/Utility/Scalar.h"
16 #include "lldb/Utility/StreamString.h"
17 #include "lldb/Utility/StringExtractorGDBRemote.h"
18
19 using namespace lldb;
20 using namespace lldb_private;
21
22 // RegisterContextMacOSXFrameBackchain constructor
23 RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
24     Thread &thread, uint32_t concrete_frame_idx,
25     const UnwindMacOSXFrameBackchain::Cursor &cursor)
26     : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
27       m_cursor_is_valid(true) {}
28
29 // Destructor
30 RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}
31
32 void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
33   m_cursor_is_valid = false;
34 }
35
36 size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
37   return m_thread.GetRegisterContext()->GetRegisterCount();
38 }
39
40 const RegisterInfo *
41 RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
42   return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
43 }
44
45 size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
46   return m_thread.GetRegisterContext()->GetRegisterSetCount();
47 }
48
49 const RegisterSet *
50 RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
51   return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
52 }
53
54 bool RegisterContextMacOSXFrameBackchain::ReadRegister(
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]) {
62   case LLDB_REGNUM_GENERIC_PC:
63     if (m_cursor.pc == LLDB_INVALID_ADDRESS)
64       return false;
65     reg_value = m_cursor.pc;
66     break;
67
68   case LLDB_REGNUM_GENERIC_FP:
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
131 bool RegisterContextMacOSXFrameBackchain::WriteRegister(
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
138 bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
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
146 bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
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
156 RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
157     lldb::RegisterKind kind, uint32_t num) {
158   return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
159       kind, num);
160 }