RegisterContextMacOSXFrameBackchain.cpp revision 263363
11539Srgrimes//===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===//
21539Srgrimes//
31539Srgrimes//                     The LLVM Compiler Infrastructure
41539Srgrimes//
51539Srgrimes// This file is distributed under the University of Illinois Open Source
61539Srgrimes// License. See LICENSE.TXT for details.
71539Srgrimes//
81539Srgrimes//===----------------------------------------------------------------------===//
91539Srgrimes
101539Srgrimes#include "RegisterContextMacOSXFrameBackchain.h"
111539Srgrimes
121539Srgrimes// C Includes
13203964Simp// C++ Includes
141539Srgrimes// Other libraries and framework includes
151539Srgrimes#include "lldb/Core/DataBufferHeap.h"
161539Srgrimes#include "lldb/Core/DataExtractor.h"
171539Srgrimes#include "lldb/Core/RegisterValue.h"
181539Srgrimes#include "lldb/Core/Scalar.h"
191539Srgrimes#include "lldb/Core/StreamString.h"
201539Srgrimes#include "lldb/Target/Thread.h"
211539Srgrimes// Project includes
221539Srgrimes#include "Utility/StringExtractorGDBRemote.h"
231539Srgrimes
241539Srgrimesusing namespace lldb;
251539Srgrimesusing namespace lldb_private;
261539Srgrimes
271539Srgrimes//----------------------------------------------------------------------
281539Srgrimes// RegisterContextMacOSXFrameBackchain constructor
291539Srgrimes//----------------------------------------------------------------------
3093032SimpRegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain
311539Srgrimes(
321539Srgrimes    Thread &thread,
331539Srgrimes    uint32_t concrete_frame_idx,
341539Srgrimes    const UnwindMacOSXFrameBackchain::Cursor &cursor
351539Srgrimes) :
361539Srgrimes    RegisterContext (thread, concrete_frame_idx),
371539Srgrimes    m_cursor (cursor),
381539Srgrimes    m_cursor_is_valid (true)
391539Srgrimes{
40267236Snwhitehorn}
411539Srgrimes
4222734Sdavidn//----------------------------------------------------------------------
431539Srgrimes// Destructor
4421189Sdavidn//----------------------------------------------------------------------
4524923SbdeRegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain()
4624891Sdavidn{
4724891Sdavidn}
481539Srgrimes
491539Srgrimesvoid
501539SrgrimesRegisterContextMacOSXFrameBackchain::InvalidateAllRegisters ()
511539Srgrimes{
521539Srgrimes    m_cursor_is_valid = false;
531539Srgrimes}
541539Srgrimes
5524891Sdavidnsize_t
5624891SdavidnRegisterContextMacOSXFrameBackchain::GetRegisterCount ()
571539Srgrimes{
581539Srgrimes    return m_thread.GetRegisterContext()->GetRegisterCount();
591539Srgrimes}
6021189Sdavidn
611539Srgrimesconst RegisterInfo *
621539SrgrimesRegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (size_t reg)
631539Srgrimes{
641539Srgrimes    return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
651539Srgrimes}
6693032Simp
6793032Simpsize_t
6893032SimpRegisterContextMacOSXFrameBackchain::GetRegisterSetCount ()
6993032Simp{
7093032Simp    return m_thread.GetRegisterContext()->GetRegisterSetCount();
7193032Simp}
721539Srgrimes
731539Srgrimes
741539Srgrimes
75const RegisterSet *
76RegisterContextMacOSXFrameBackchain::GetRegisterSet (size_t reg_set)
77{
78    return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
79}
80
81
82
83bool
84RegisterContextMacOSXFrameBackchain::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(_MSC_VER) && !defined(__mips__)
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
172bool
173RegisterContextMacOSXFrameBackchain::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
181bool
182RegisterContextMacOSXFrameBackchain::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
190bool
191RegisterContextMacOSXFrameBackchain::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
201uint32_t
202RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
203{
204    return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
205}
206
207