blob: 68a207c9ec9610ed443bb6e13681bf9f80f61cce [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/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 lldb::RegisterInfo *
RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (uint32_t reg)
{
return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}
size_t
RegisterContextMacOSXFrameBackchain::GetRegisterSetCount ()
{
return m_thread.GetRegisterContext()->GetRegisterSetCount();
}
const lldb::RegisterSet *
RegisterContextMacOSXFrameBackchain::GetRegisterSet (uint32_t reg_set)
{
return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
}
bool
RegisterContextMacOSXFrameBackchain::ReadRegisterValue (uint32_t reg, Scalar &value)
{
if (!m_cursor_is_valid)
return false;
uint64_t reg_value = LLDB_INVALID_ADDRESS;
const RegisterInfo *reg_info = m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (reg);
if (reg_info == NULL)
return false;
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.pc;
break;
default:
return false;
}
switch (reg_info->encoding)
{
case eEncodingUint:
switch (reg_info->byte_size)
{
case 1:
case 2:
case 4:
value = (uint32_t)reg_value;
return true;
case 8:
value = (uint64_t)reg_value;
return true;
}
break;
case eEncodingSint:
switch (reg_info->byte_size)
{
case 1:
case 2:
case 4:
value = (int32_t)reg_value;
return true;
case 8:
value = (int64_t)reg_value;
return true;
}
break;
case eEncodingIEEE754:
switch (reg_info->byte_size)
{
case sizeof (float):
if (sizeof (float) == sizeof(uint32_t))
{
value = (uint32_t)reg_value;
return true;
}
else if (sizeof (float) == sizeof(uint64_t))
{
value = (uint64_t)reg_value;
return true;
}
break;
case sizeof (double):
if (sizeof (double) == sizeof(uint32_t))
{
value = (uint32_t)reg_value;
return true;
}
else if (sizeof (double) == sizeof(uint64_t))
{
value = (uint64_t)reg_value;
return true;
}
break;
case sizeof (long double):
if (sizeof (long double) == sizeof(uint32_t))
{
value = (uint32_t)reg_value;
return true;
}
else if (sizeof (long double) == sizeof(uint64_t))
{
value = (uint64_t)reg_value;
return true;
}
break;
}
break;
}
return false;
}
bool
RegisterContextMacOSXFrameBackchain::ReadRegisterBytes (uint32_t reg, DataExtractor &data)
{
Scalar reg_value;
if (ReadRegisterValue (reg, reg_value))
{
if (reg_value.GetData(data))
{
// "reg_value" is local and now "data" points to the data within
// "reg_value", so we must make a copy that will live within "data"
DataBufferSP data_sp (new DataBufferHeap (data.GetDataStart(), data.GetByteSize()));
data.SetData (data_sp, 0, data.GetByteSize());
return true;
}
}
return false;
}
bool
RegisterContextMacOSXFrameBackchain::WriteRegisterValue (uint32_t reg, const Scalar &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::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset)
{
// 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);
}