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