1 //===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "RegisterContextMacOSXFrameBackchain.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 #include "lldb/Core/DataBufferHeap.h"
16 #include "lldb/Core/DataExtractor.h"
17 #include "lldb/Core/RegisterValue.h"
18 #include "lldb/Core/Scalar.h"
19 #include "lldb/Core/StreamString.h"
20 #include "lldb/Target/Thread.h"
21 // Project includes
22 #include "Utility/StringExtractorGDBRemote.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 //----------------------------------------------------------------------
28 // RegisterContextMacOSXFrameBackchain constructor
29 //----------------------------------------------------------------------
RegisterContextMacOSXFrameBackchain(Thread & thread,uint32_t concrete_frame_idx,const UnwindMacOSXFrameBackchain::Cursor & cursor)30 RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain
31 (
32 Thread &thread,
33 uint32_t concrete_frame_idx,
34 const UnwindMacOSXFrameBackchain::Cursor &cursor
35 ) :
36 RegisterContext (thread, concrete_frame_idx),
37 m_cursor (cursor),
38 m_cursor_is_valid (true)
39 {
40 }
41
42 //----------------------------------------------------------------------
43 // Destructor
44 //----------------------------------------------------------------------
~RegisterContextMacOSXFrameBackchain()45 RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain()
46 {
47 }
48
49 void
InvalidateAllRegisters()50 RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters ()
51 {
52 m_cursor_is_valid = false;
53 }
54
55 size_t
GetRegisterCount()56 RegisterContextMacOSXFrameBackchain::GetRegisterCount ()
57 {
58 return m_thread.GetRegisterContext()->GetRegisterCount();
59 }
60
61 const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)62 RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (size_t reg)
63 {
64 return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
65 }
66
67 size_t
GetRegisterSetCount()68 RegisterContextMacOSXFrameBackchain::GetRegisterSetCount ()
69 {
70 return m_thread.GetRegisterContext()->GetRegisterSetCount();
71 }
72
73
74
75 const RegisterSet *
GetRegisterSet(size_t reg_set)76 RegisterContextMacOSXFrameBackchain::GetRegisterSet (size_t reg_set)
77 {
78 return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
79 }
80
81
82
83 bool
ReadRegister(const RegisterInfo * reg_info,RegisterValue & value)84 RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info,
85 RegisterValue &value)
86 {
87 if (!m_cursor_is_valid)
88 return false;
89
90 uint64_t reg_value = LLDB_INVALID_ADDRESS;
91
92 switch (reg_info->kinds[eRegisterKindGeneric])
93 {
94 case LLDB_REGNUM_GENERIC_PC:
95 if (m_cursor.pc == LLDB_INVALID_ADDRESS)
96 return false;
97 reg_value = m_cursor.pc;
98 break;
99
100 case LLDB_REGNUM_GENERIC_FP:
101 if (m_cursor.fp == LLDB_INVALID_ADDRESS)
102 return false;
103 reg_value = m_cursor.fp;
104 break;
105
106 default:
107 return false;
108 }
109
110 switch (reg_info->encoding)
111 {
112 case eEncodingInvalid:
113 case eEncodingVector:
114 break;
115
116 case eEncodingUint:
117 case eEncodingSint:
118 value.SetUInt(reg_value, reg_info->byte_size);
119 return true;
120
121 case eEncodingIEEE754:
122 switch (reg_info->byte_size)
123 {
124 case sizeof (float):
125 if (sizeof (float) == sizeof(uint32_t))
126 {
127 value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
128 return true;
129 }
130 else if (sizeof (float) == sizeof(uint64_t))
131 {
132 value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
133 return true;
134 }
135 break;
136
137 case sizeof (double):
138 if (sizeof (double) == sizeof(uint32_t))
139 {
140 value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
141 return true;
142 }
143 else if (sizeof (double) == sizeof(uint64_t))
144 {
145 value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
146 return true;
147 }
148 break;
149
150 // TOOD: need a better way to detect when "long double" types are
151 // the same bytes size as "double"
152 #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && \
153 !defined(__mips__) && !defined(__powerpc__) && !defined(__ANDROID_NDK__)
154 case sizeof (long double):
155 if (sizeof (long double) == sizeof(uint32_t))
156 {
157 value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
158 return true;
159 }
160 else if (sizeof (long double) == sizeof(uint64_t))
161 {
162 value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
163 return true;
164 }
165 break;
166 #endif
167 }
168 break;
169 }
170 return false;
171 }
172
173 bool
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & value)174 RegisterContextMacOSXFrameBackchain::WriteRegister (const RegisterInfo *reg_info,
175 const RegisterValue &value)
176 {
177 // Not supported yet. We could easily add support for this by remembering
178 // the address of each entry (it would need to be part of the cursor)
179 return false;
180 }
181
182 bool
ReadAllRegisterValues(lldb::DataBufferSP & data_sp)183 RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
184 {
185 // libunwind frames can't handle this it doesn't always have all register
186 // values. This call should only be called on frame zero anyway so there
187 // shouldn't be any problem
188 return false;
189 }
190
191 bool
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)192 RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
193 {
194 // Since this class doesn't respond to "ReadAllRegisterValues()", it must
195 // not have been the one that saved all the register values. So we just let
196 // the thread's register context (the register context for frame zero) do
197 // the writing.
198 return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
199 }
200
201
202 uint32_t
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t num)203 RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
204 {
205 return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
206 }
207
208