nitesh.jain updated this revision to Diff 71505.
nitesh.jain added a comment.
Updated diff as per suggestion.
https://reviews.llvm.org/D24603
Files:
source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
===================================================================
--- source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
@@ -76,11 +76,16 @@
static bool IsMSAAvailable();
protected:
- Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value) override;
+ Error Read_SR_Config(uint32_t offset, const char *reg_name, uint32_t size,
+ RegisterValue &value);
- Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value) override;
+ uint32_t GetPtraceOffset(uint32_t reg_index,
+ const RegisterInfo *const reg_info);
+
+ Error ReadRegisterRaw(uint32_t reg_index, RegisterValue &value) override;
+
+ Error WriteRegisterRaw(uint32_t reg_index,
+ const RegisterValue &value) override;
Error DoReadWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
===================================================================
--- source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -28,9 +28,16 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-enumerations.h"
+
#define NT_MIPS_MSA 0x600
#define CONFIG5_FRE (1 << 8)
#define SR_FR (1 << 26)
+#define FPR_BASE 32
+#define PC 64
+#define CAUSE 65
+#define BADVADDR 66
+#define MMHI 67
+#define MMLO 68
#define NUM_REGISTERS 32
#include <asm/ptrace.h>
@@ -466,21 +473,23 @@
}
if (IsFPR(reg_index) || IsMSA(reg_index)) {
- uint8_t *dst;
- uint64_t *src;
+ uint8_t *dst = nullptr;
+ uint64_t *src = nullptr;
+ uint8_t byte_size = reg_info->byte_size;
// Initialise the FP and MSA buffers by reading all co-processor 1 registers
ReadCP1();
if (IsFPR(reg_index)) {
assert(reg_info->byte_offset < sizeof(UserArea));
dst = (uint8_t *)&m_fpr + reg_info->byte_offset - (sizeof(m_gpr));
+ byte_size = IsFR0() ? 4 : 8;
} else {
assert(reg_info->byte_offset < sizeof(UserArea));
dst = (uint8_t *)&m_msa + reg_info->byte_offset -
(sizeof(m_gpr) + sizeof(m_fpr));
}
- switch (reg_info->byte_size) {
+ switch (byte_size) {
case 4:
*(uint32_t *)dst = reg_value.GetAsUInt32();
break;
@@ -611,11 +620,12 @@
Error NativeRegisterContextLinux_mips64::ReadCP1() {
Error error;
- uint8_t *src, *dst;
+ uint8_t *src = nullptr;
+ uint8_t *dst = nullptr;
lldb::ByteOrder byte_order = GetByteOrder();
- uint32_t IsBigEndian = (byte_order == lldb::eByteOrderBig);
+ bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
if (IsMSAAvailable()) {
error = NativeRegisterContextLinux::ReadRegisterSet(
@@ -637,11 +647,18 @@
// TODO: Add support for FRE
if (IsFR0()) {
- src = (uint8_t *)&m_fpr + 4 + (IsBigEndian * 4);
- dst = (uint8_t *)&m_fpr + 8 + (IsBigEndian * 4);
+ src = (uint8_t *)&m_fpr + (!IsBigEndian) * 4;
+ dst = (uint8_t *)&m_fpr + 8;
for (int i = 0; i < (NUM_REGISTERS / 2); i++) {
// copy odd single from top of neighbouring even double
+ // In case of little endian, 32 bit LSB store even FP register
+ // and 32 bit MSB store odd FP register
+ // vice-versa for big-endian
*(uint32_t *)dst = *(uint32_t *)src;
+
+ if (IsBigEndian)
+ // Copy 32 bit MSB to 32 bit LSB
+ *(uint32_t *)src = *(uint32_t *)(src + 4);
src = src + 16;
dst = dst + 16;
}
@@ -653,18 +670,23 @@
Error NativeRegisterContextLinux_mips64::WriteCP1() {
Error error;
- uint8_t *src, *dst;
+ uint8_t *src = nullptr;
+ uint8_t *dst = nullptr;
lldb::ByteOrder byte_order = GetByteOrder();
- uint32_t IsBigEndian = (byte_order == lldb::eByteOrderBig);
+ bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
// TODO: Add support for FRE
if (IsFR0()) {
- src = (uint8_t *)&m_fpr + 8 + (IsBigEndian * 4);
- dst = (uint8_t *)&m_fpr + 4 + (IsBigEndian * 4);
+ dst = (uint8_t *)&m_fpr + (!IsBigEndian) * 4;
+ src = dst + 8 - (!IsBigEndian) * 4;
for (int i = 0; i < (NUM_REGISTERS / 2); i++) {
// copy odd single to top of neighbouring even double
+ if (IsBigEndian)
+ // Copy 32 bit LSB to 32 bit MSB
+ *(uint32_t *)(dst + 4) = *(uint32_t *)dst;
+
*(uint32_t *)dst = *(uint32_t *)src;
src = src + 16;
dst = dst + 16;
@@ -1132,50 +1154,90 @@
}
return num_valid;
}
-Error NativeRegisterContextLinux_mips64::DoReadRegisterValue(
- uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value) {
- GPR_linux_mips regs;
- ::memset(®s, 0, sizeof(GPR_linux_mips));
- // Clear all bits in RegisterValue before writing actual value read from
- // ptrace to avoid garbage value in 32-bit MSB
- value.SetBytes((void *)(((unsigned char *)®s) + offset), 8,
- GetByteOrder());
- Error error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGS, m_thread.GetID(), NULL, ®s, sizeof regs);
- if (error.Success()) {
- lldb_private::ArchSpec arch;
- if (m_thread.GetProcess()->GetArchitecture(arch)) {
- void *target_address = ((uint8_t *)®s) + offset +
- 4 * (arch.GetMachine() == llvm::Triple::mips);
- uint32_t target_size;
- if ((::strcmp(reg_name, "sr") == 0) ||
- (::strcmp(reg_name, "cause") == 0) ||
- (::strcmp(reg_name, "config5") == 0))
- target_size = 4;
- else
- target_size =
- arch.GetFlags() & lldb_private::ArchSpec::eMIPSABI_O32 ? 4 : 8;
- value.SetBytes(target_address, target_size, arch.GetByteOrder());
- } else
- error.SetErrorString("failed to get architecture");
+uint32_t NativeRegisterContextLinux_mips64::GetPtraceOffset(
+ uint32_t reg_index, const RegisterInfo *const reg_info) {
+ // In case of MIPS, the PTRACE_PEEKUSER/PTRACE_POKEUSER
+ // take register number has an offset
+ // Apart from GPR registers , the offset for other registers are
+ // FPR_BASE 32
+ // PC 64
+ // CAUSE 65
+ // BADVADDR 66
+ // MMHI 67
+ // MMLO 68
+
+ static_assert(dwarf_zero_mips == dwarf_zero_mips64 &&
+ dwarf_pc_mips == dwarf_pc_mips64,
+ "MIPS and MIPS64 dwarf no. mismatch");
+
+ if (reg_index < dwarf_sr_mips)
+ return reg_index;
+
+ switch (reg_info->kinds[lldb::eRegisterKindDWARF]) {
+ case dwarf_pc_mips:
+ return PC;
+ case dwarf_sr_mips:
+ case dwarf_config5_mips:
+ case dwarf_config5_mips64:
+ return reg_info->byte_offset;
+ case dwarf_cause_mips:
+ return CAUSE;
+ case dwarf_bad_mips:
+ return BADVADDR;
+ case dwarf_hi_mips:
+ return MMHI;
+ case dwarf_lo_mips:
+ return MMLO;
+ default:
+ assert(false && "Invalid Register Kinds");
}
- return error;
+ return 0;
+}
+
+Error NativeRegisterContextLinux_mips64::ReadRegisterRaw(uint32_t reg_index,
+ RegisterValue &value) {
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+
+ if (!reg_info)
+ return Error("register %" PRIu32 " not found", reg_index);
+
+ uint32_t offset = GetPtraceOffset(reg_index, reg_info);
+
+ if ((reg_index == dwarf_sr_mips) || (strcmp(reg_info->name, "config5") == 0))
+ return Read_SR_Config(offset, reg_info->name, reg_info->byte_size, value);
+
+ return DoReadRegisterValue(offset, reg_info->name, reg_info->byte_size,
+ value);
}
-Error NativeRegisterContextLinux_mips64::DoWriteRegisterValue(
- uint32_t offset, const char *reg_name, const RegisterValue &value) {
+Error NativeRegisterContextLinux_mips64::WriteRegisterRaw(
+ uint32_t reg_index, const RegisterValue &value) {
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+
+ if (!reg_info)
+ return Error("register %" PRIu32 " not found", reg_index);
+
+ assert(!reg_info->invalidate_regs);
+ uint32_t offset = GetPtraceOffset(reg_index, reg_info);
+ return DoWriteRegisterValue(offset, reg_info->name, value);
+}
+
+Error NativeRegisterContextLinux_mips64::Read_SR_Config(uint32_t offset,
+ const char *reg_name,
+ uint32_t size,
+ RegisterValue &value) {
GPR_linux_mips regs;
+ ::memset(®s, 0, sizeof(GPR_linux_mips));
+
Error error = NativeProcessLinux::PtraceWrapper(
PTRACE_GETREGS, m_thread.GetID(), NULL, ®s, sizeof regs);
if (error.Success()) {
lldb_private::ArchSpec arch;
if (m_thread.GetProcess()->GetArchitecture(arch)) {
- ::memcpy((void *)(((unsigned char *)(®s)) + offset), value.GetBytes(),
- arch.GetFlags() & lldb_private::ArchSpec::eMIPSABI_O32 ? 4 : 8);
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_SETREGS, m_thread.GetID(), NULL, ®s, sizeof regs);
+ void *target_address = ((uint8_t *)®s) + offset +
+ 4 * (arch.GetMachine() == llvm::Triple::mips);
+ value.SetUInt(*(uint32_t *)target_address, size);
} else
error.SetErrorString("failed to get architecture");
}
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits