diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 0dfee5ef4736..6f3aa685e651 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -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, ®s, 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, ®set, &ioVec, sizeof regs, m_error); } } +#elif defined (__mips__) + elf_gregset_t regs; + PTRACE(PTRACE_GETREGS, m_tid, NULL, ®s, sizeof regs, m_error); + if (m_error.Success()) + { + ::memcpy((void *)(((unsigned char *)(®s)) + m_offset), m_value.GetBytes(), 8); + PTRACE(PTRACE_SETREGS, m_tid, NULL, ®s, sizeof regs, m_error); + } #else void* buf; Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp index 0e4da3705ac2..43986fcd53e9 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp @@ -123,20 +123,109 @@ NativeRegisterContextLinux_mips64::GetRegisterSet (uint32_t set_index) const return nullptr; } -Error +lldb_private::Error +NativeRegisterContextLinux_mips64::ReadRegisterRaw (uint32_t reg_index, RegisterValue ®_value) +{ + Error error; + + const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index); + if (!reg_info) + { + error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index); + return error; + } + + NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); + if (!process_sp) + { + error.SetErrorString ("NativeProcessProtocol is NULL"); + return error; + } + + NativeProcessLinux *const process_p = reinterpret_cast (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 ®_value) { Error error; - error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::ReadRegister 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; } -Error -NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) +lldb_private::Error +NativeRegisterContextLinux_mips64::WriteRegister(const uint32_t reg, + const RegisterValue &value) { Error error; - error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::WriteRegister not implemented"); - return 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 (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 ®_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 : ""); + + return WriteRegister(reg_index, reg_value); } Error diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h index a8014061b40f..07e8f20668cf 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h @@ -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 ®_value); }; } // namespace process_linux