[LLDB][MIPS] Read/Write register for MIPS64

Patch by Sagar Thakur

Reviewers: clayborg, tberghammer.

Subscribers: jaydeep, bhushan, mohit.bhakkad, llvm-commits.

Differential Revision: http://reviews.llvm.org/D8695

llvm-svn: 233685
This commit is contained in:
Mohit K. Bhakkad 2015-03-31 12:01:27 +00:00
parent 7aed6890fd
commit 09ba1a323e
3 changed files with 122 additions and 6 deletions

View File

@ -657,6 +657,17 @@ namespace
m_error.SetErrorString("failed to get architecture");
}
}
#elif defined (__mips__)
elf_gregset_t regs;
PTRACE(PTRACE_GETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
if (m_error.Success())
{
lldb_private::ArchSpec arch;
if (monitor->GetArchitecture(arch))
m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder());
else
m_error.SetErrorString("failed to get architecture");
}
#else
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
@ -733,6 +744,14 @@ namespace
PTRACE(PTRACE_SETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
}
}
#elif defined (__mips__)
elf_gregset_t regs;
PTRACE(PTRACE_GETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
if (m_error.Success())
{
::memcpy((void *)(((unsigned char *)(&regs)) + m_offset), m_value.GetBytes(), 8);
PTRACE(PTRACE_SETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
}
#else
void* buf;
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));

View File

@ -123,22 +123,111 @@ NativeRegisterContextLinux_mips64::GetRegisterSet (uint32_t set_index) const
return nullptr;
}
Error
NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
lldb_private::Error
NativeRegisterContextLinux_mips64::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::ReadRegister not implemented");
const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
if (!reg_info)
{
error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
return error;
}
Error
NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
if (!process_sp)
{
error.SetErrorString ("NativeProcessProtocol is NULL");
return error;
}
NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
return process_p->ReadRegisterValue(m_thread.GetID(),
reg_info->byte_offset,
reg_info->name,
reg_info->byte_size,
reg_value);
}
lldb_private::Error
NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
{
Error error;
error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::WriteRegister not implemented");
if (!reg_info)
{
error.SetErrorString ("reg_info NULL");
return error;
}
const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
if (reg == LLDB_INVALID_REGNUM)
{
// This is likely an internal register for lldb use only and should not be directly queried.
error.SetErrorStringWithFormat ("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
return error;
}
error = ReadRegisterRaw(reg, reg_value);
if (error.Success ())
{
// If our return byte size was greater than the return value reg size, then
// use the type specified by reg_info rather than the uint64_t default
if (reg_value.GetByteSize() > reg_info->byte_size)
reg_value.SetType(reg_info);
}
return error;
}
lldb_private::Error
NativeRegisterContextLinux_mips64::WriteRegister(const uint32_t reg,
const RegisterValue &value)
{
Error error;
uint32_t reg_to_write = reg;
RegisterValue value_to_write = value;
NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
if (!process_sp)
{
error.SetErrorString ("NativeProcessProtocol is NULL");
return error;
}
const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
if (!register_to_write_info_p)
{
error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
return error;
}
NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
return process_p->WriteRegisterValue(m_thread.GetID(),
register_to_write_info_p->byte_offset,
register_to_write_info_p->name,
value_to_write);
}
lldb_private::Error
NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
{
assert (reg_info && "reg_info is null");
const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
if (reg_index == LLDB_INVALID_REGNUM)
return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
return WriteRegister(reg_index, reg_value);
}
Error
NativeRegisterContextLinux_mips64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
{

View File

@ -117,6 +117,14 @@ namespace process_linux {
uint32_t
NumSupportedHardwareWatchpoints () override;
private:
lldb_private::Error
WriteRegister(const uint32_t reg, const RegisterValue &value);
lldb_private::Error
ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value);
};
} // namespace process_linux