blob: 6cfad1eb0dd473aff6bb0c1b10ab2fa6714fd02c [file] [log] [blame]
//===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "RegisterContextMacOSXFrameBackchain.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Target/Thread.h"
// Project includes
#include "Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
// RegisterContextMacOSXFrameBackchain constructor
//----------------------------------------------------------------------
RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain
(
Thread &thread,
uint32_t concrete_frame_idx,
const UnwindMacOSXFrameBackchain::Cursor &cursor
) :
RegisterContext (thread, concrete_frame_idx),
m_cursor (cursor),
m_cursor_is_valid (true)
{
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain()
{
}
void
RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters ()
{
m_cursor_is_valid = false;
}
size_t
RegisterContextMacOSXFrameBackchain::GetRegisterCount ()
{
return m_thread.GetRegisterContext()->GetRegisterCount();
}
const RegisterInfo *
RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (uint32_t reg)
{
return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}
size_t
RegisterContextMacOSXFrameBackchain::GetRegisterSetCount ()
{
return m_thread.GetRegisterContext()->GetRegisterSetCount();
}
const RegisterSet *
RegisterContextMacOSXFrameBackchain::GetRegisterSet (uint32_t reg_set)
{
return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
}
bool
RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info,
RegisterValue &value)
{
if (!m_cursor_is_valid)
return false;
uint64_t reg_value = LLDB_INVALID_ADDRESS;
switch (reg_info->kinds[eRegisterKindGeneric])
{
case LLDB_REGNUM_GENERIC_PC:
if (m_cursor.pc == LLDB_INVALID_ADDRESS)
return false;
reg_value = m_cursor.pc;
break;
case LLDB_REGNUM_GENERIC_FP:
if (m_cursor.fp == LLDB_INVALID_ADDRESS)
return false;
reg_value = m_cursor.fp;
break;
default:
return false;
}
switch (reg_info->encoding)
{
case eEncodingInvalid:
case eEncodingVector:
break;
case eEncodingUint:
case eEncodingSint:
value.SetUInt(reg_value, reg_info->byte_size);
return true;
case eEncodingIEEE754:
switch (reg_info->byte_size)
{
case sizeof (float):
if (sizeof (float) == sizeof(uint32_t))
{
value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
return true;
}
else if (sizeof (float) == sizeof(uint64_t))
{
value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
return true;
}
break;
case sizeof (double):
if (sizeof (double) == sizeof(uint32_t))
{
value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
return true;
}
else if (sizeof (double) == sizeof(uint64_t))
{
value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
return true;
}
break;
// TOOD: need a better way to detect when "long double" types are
// the same bytes size as "double"
#if !defined(__arm__)
case sizeof (long double):
if (sizeof (long double) == sizeof(uint32_t))
{
value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
return true;
}
else if (sizeof (long double) == sizeof(uint64_t))
{
value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
return true;
}
break;
#endif
}
break;
}
return false;
}
bool
RegisterContextMacOSXFrameBackchain::WriteRegister (const RegisterInfo *reg_info,
const RegisterValue &value)
{
// Not supported yet. We could easily add support for this by remembering
// the address of each entry (it would need to be part of the cursor)
return false;
}
bool
RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
{
// libunwind frames can't handle this it doesn't always have all register
// values. This call should only be called on frame zero anyway so there
// shouldn't be any problem
return false;
}
bool
RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
{
// Since this class doesn't respond to "ReadAllRegisterValues()", it must
// not have been the one that saved all the register values. So we just let
// the thread's register context (the register context for frame zero) do
// the writing.
return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
}
uint32_t
RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
{
return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
}