• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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__)
153         case sizeof (long double):
154             if (sizeof (long double) == sizeof(uint32_t))
155             {
156                 value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
157                 return true;
158             }
159             else if (sizeof (long double) == sizeof(uint64_t))
160             {
161                 value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
162                 return true;
163             }
164             break;
165 #endif
166         }
167         break;
168     }
169     return false;
170 }
171 
172 bool
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & value)173 RegisterContextMacOSXFrameBackchain::WriteRegister (const RegisterInfo *reg_info,
174                                                     const RegisterValue &value)
175 {
176     // Not supported yet. We could easily add support for this by remembering
177     // the address of each entry (it would need to be part of the cursor)
178     return false;
179 }
180 
181 bool
ReadAllRegisterValues(lldb::DataBufferSP & data_sp)182 RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
183 {
184     // libunwind frames can't handle this it doesn't always have all register
185     // values. This call should only be called on frame zero anyway so there
186     // shouldn't be any problem
187     return false;
188 }
189 
190 bool
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)191 RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
192 {
193     // Since this class doesn't respond to "ReadAllRegisterValues()", it must
194     // not have been the one that saved all the register values. So we just let
195     // the thread's register context (the register context for frame zero) do
196     // the writing.
197     return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
198 }
199 
200 
201 uint32_t
ConvertRegisterKindToRegisterNumber(uint32_t kind,uint32_t num)202 RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
203 {
204     return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
205 }
206 
207