NativeProcessLinux: Remove some register context boilerplate

Summary:
This patch follows the spirit of D63594, and removes some null checks
for things which should be operating invariants. Specifically
{Read,Write}[GF]PR now no longer check whether the supplied buffers are
null, because they never are. After this, the Do*** versions of these
function no longer serve any purpose and are inlined into their callers.

Other cleanups are possible here too, but I am taking this one step at a
time because this involves a lot of architecture-specific code, which I
don't have the hardware to test on (I did do a build-test though).

Reviewers: mgorny, jankratochvil, omjavaid, alexandreyy, uweigand

Subscribers: nemanjai, javed.absar, kbarton, lldb-commits

Differential Revision: https://reviews.llvm.org/D66744

llvm-svn: 370653
This commit is contained in:
Pavel Labath 2019-09-02 12:50:18 +00:00
parent fe2ee4c46a
commit 3f3673ead9
10 changed files with 114 additions and 202 deletions

View File

@ -95,39 +95,25 @@ NativeRegisterContextLinux::WriteRegisterRaw(uint32_t reg_index,
}
Status NativeRegisterContextLinux::ReadGPR() {
void *buf = GetGPRBuffer();
if (!buf)
return Status("GPR buffer is NULL");
size_t buf_size = GetGPRSize();
return DoReadGPR(buf, buf_size);
return NativeProcessLinux::PtraceWrapper(
PTRACE_GETREGS, m_thread.GetID(), nullptr, GetGPRBuffer(), GetGPRSize());
}
Status NativeRegisterContextLinux::WriteGPR() {
void *buf = GetGPRBuffer();
if (!buf)
return Status("GPR buffer is NULL");
size_t buf_size = GetGPRSize();
return DoWriteGPR(buf, buf_size);
return NativeProcessLinux::PtraceWrapper(
PTRACE_SETREGS, m_thread.GetID(), nullptr, GetGPRBuffer(), GetGPRSize());
}
Status NativeRegisterContextLinux::ReadFPR() {
void *buf = GetFPRBuffer();
if (!buf)
return Status("FPR buffer is NULL");
size_t buf_size = GetFPRSize();
return DoReadFPR(buf, buf_size);
return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
nullptr, GetFPRBuffer(),
GetFPRSize());
}
Status NativeRegisterContextLinux::WriteFPR() {
void *buf = GetFPRBuffer();
if (!buf)
return Status("FPR buffer is NULL");
size_t buf_size = GetFPRSize();
return DoWriteFPR(buf, buf_size);
return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
nullptr, GetFPRBuffer(),
GetFPRSize());
}
Status NativeRegisterContextLinux::ReadRegisterSet(void *buf, size_t buf_size,
@ -173,23 +159,3 @@ Status NativeRegisterContextLinux::DoWriteRegisterValue(
return NativeProcessLinux::PtraceWrapper(
PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
}
Status NativeRegisterContextLinux::DoReadGPR(void *buf, size_t buf_size) {
return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
nullptr, buf, buf_size);
}
Status NativeRegisterContextLinux::DoWriteGPR(void *buf, size_t buf_size) {
return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
nullptr, buf, buf_size);
}
Status NativeRegisterContextLinux::DoReadFPR(void *buf, size_t buf_size) {
return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
nullptr, buf, buf_size);
}
Status NativeRegisterContextLinux::DoWriteFPR(void *buf, size_t buf_size) {
return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
nullptr, buf, buf_size);
}

View File

@ -50,15 +50,15 @@ protected:
virtual Status WriteFPR();
virtual void *GetGPRBuffer() { return nullptr; }
virtual void *GetGPRBuffer() = 0;
virtual size_t GetGPRSize() {
return GetRegisterInfoInterface().GetGPRSize();
}
virtual void *GetFPRBuffer() { return nullptr; }
virtual void *GetFPRBuffer() = 0;
virtual size_t GetFPRSize() { return 0; }
virtual size_t GetFPRSize() = 0;
// The Do*** functions are executed on the privileged thread and can perform
// ptrace
@ -68,14 +68,6 @@ protected:
virtual Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
const RegisterValue &value);
virtual Status DoReadGPR(void *buf, size_t buf_size);
virtual Status DoWriteGPR(void *buf, size_t buf_size);
virtual Status DoReadFPR(void *buf, size_t buf_size);
virtual Status DoWriteFPR(void *buf, size_t buf_size);
};
} // namespace process_linux

View File

@ -867,7 +867,7 @@ Status NativeRegisterContextLinux_arm::DoReadRegisterValue(
if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
return Status("Register isn't fit into the size of the GPR area");
Status error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
Status error = ReadGPR();
if (error.Fail())
return error;
@ -886,7 +886,7 @@ Status NativeRegisterContextLinux_arm::DoWriteRegisterValue(
if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
return Status("Register isn't fit into the size of the GPR area");
Status error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
Status error = ReadGPR();
if (error.Fail())
return error;
@ -904,56 +904,58 @@ Status NativeRegisterContextLinux_arm::DoWriteRegisterValue(
}
m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
return WriteGPR();
}
Status NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size) {
Status NativeRegisterContextLinux_arm::ReadGPR() {
#ifdef __arm__
return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
return NativeRegisterContextLinux::ReadGPR();
#else // __aarch64__
struct iovec ioVec;
ioVec.iov_base = buf;
ioVec.iov_len = buf_size;
ioVec.iov_base = GetGPRBuffer();
ioVec.iov_len = GetGPRSize();
return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
return ReadRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS);
#endif // __arm__
}
Status NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size) {
Status NativeRegisterContextLinux_arm::WriteGPR() {
#ifdef __arm__
return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
return NativeRegisterContextLinux::WriteGPR();
#else // __aarch64__
struct iovec ioVec;
ioVec.iov_base = buf;
ioVec.iov_len = buf_size;
ioVec.iov_base = GetGPRBuffer();
ioVec.iov_len = GetGPRSize();
return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
return WriteRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS);
#endif // __arm__
}
Status NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size) {
Status NativeRegisterContextLinux_arm::ReadFPR() {
#ifdef __arm__
return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS, m_thread.GetID(),
nullptr, buf, buf_size);
nullptr, GetFPRBuffer(),
GetFPRSize());
#else // __aarch64__
struct iovec ioVec;
ioVec.iov_base = buf;
ioVec.iov_len = buf_size;
ioVec.iov_base = GetFPRBuffer();
ioVec.iov_len = GetFPRSize();
return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
return ReadRegisterSet(&ioVec, GetFPRSize(), NT_ARM_VFP);
#endif // __arm__
}
Status NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size) {
Status NativeRegisterContextLinux_arm::WriteFPR() {
#ifdef __arm__
return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS, m_thread.GetID(),
nullptr, buf, buf_size);
nullptr, GetFPRBuffer(),
GetFPRSize());
#else // __aarch64__
struct iovec ioVec;
ioVec.iov_base = buf;
ioVec.iov_len = buf_size;
ioVec.iov_base = GetFPRBuffer();
ioVec.iov_len = GetFPRSize();
return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
return WriteRegisterSet(&ioVec, GetFPRSize(), NT_ARM_VFP);
#endif // __arm__
}

View File

@ -83,13 +83,13 @@ protected:
Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
const RegisterValue &value) override;
Status DoReadGPR(void *buf, size_t buf_size) override;
Status ReadGPR() override;
Status DoWriteGPR(void *buf, size_t buf_size) override;
Status WriteGPR() override;
Status DoReadFPR(void *buf, size_t buf_size) override;
Status ReadFPR() override;
Status DoWriteFPR(void *buf, size_t buf_size) override;
Status WriteFPR() override;
void *GetGPRBuffer() override { return &m_gpr_arm; }

View File

@ -915,50 +915,32 @@ Status NativeRegisterContextLinux_arm64::DoWriteRegisterValue(
return error;
}
Status NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size) {
int regset = NT_PRSTATUS;
Status NativeRegisterContextLinux_arm64::ReadGPR() {
struct iovec ioVec;
Status error;
ioVec.iov_base = buf;
ioVec.iov_len = buf_size;
return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
&regset, &ioVec, buf_size);
ioVec.iov_base = GetGPRBuffer();
ioVec.iov_len = GetGPRSize();
return ReadRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS);
}
Status NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf,
size_t buf_size) {
int regset = NT_PRSTATUS;
Status NativeRegisterContextLinux_arm64::WriteGPR() {
struct iovec ioVec;
Status error;
ioVec.iov_base = buf;
ioVec.iov_len = buf_size;
return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
&regset, &ioVec, buf_size);
ioVec.iov_base = GetGPRBuffer();
ioVec.iov_len = GetGPRSize();
return WriteRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS);
}
Status NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size) {
int regset = NT_FPREGSET;
Status NativeRegisterContextLinux_arm64::ReadFPR() {
struct iovec ioVec;
Status error;
ioVec.iov_base = buf;
ioVec.iov_len = buf_size;
return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
&regset, &ioVec, buf_size);
ioVec.iov_base = GetFPRBuffer();
ioVec.iov_len = GetFPRSize();
return ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
}
Status NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf,
size_t buf_size) {
int regset = NT_FPREGSET;
Status NativeRegisterContextLinux_arm64::WriteFPR() {
struct iovec ioVec;
Status error;
ioVec.iov_base = buf;
ioVec.iov_len = buf_size;
return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
&regset, &ioVec, buf_size);
ioVec.iov_base = GetFPRBuffer();
ioVec.iov_len = GetFPRSize();
return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
}
uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(

View File

@ -83,13 +83,13 @@ protected:
Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
const RegisterValue &value) override;
Status DoReadGPR(void *buf, size_t buf_size) override;
Status ReadGPR() override;
Status DoWriteGPR(void *buf, size_t buf_size) override;
Status WriteGPR() override;
Status DoReadFPR(void *buf, size_t buf_size) override;
Status ReadFPR() override;
Status DoWriteFPR(void *buf, size_t buf_size) override;
Status WriteFPR() override;
void *GetGPRBuffer() override { return &m_gpr_arm64; }

View File

@ -445,34 +445,6 @@ bool NativeRegisterContextLinux_ppc64le::IsFPR(unsigned reg) const {
return (k_first_fpr_ppc64le <= reg && reg <= k_last_fpr_ppc64le);
}
Status NativeRegisterContextLinux_ppc64le::DoReadGPR(
void *buf, size_t buf_size) {
int regset = NT_PRSTATUS;
return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
&regset, buf, buf_size);
}
Status NativeRegisterContextLinux_ppc64le::DoWriteGPR(
void *buf, size_t buf_size) {
int regset = NT_PRSTATUS;
return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
&regset, buf, buf_size);
}
Status NativeRegisterContextLinux_ppc64le::DoReadFPR(void *buf,
size_t buf_size) {
int regset = NT_FPREGSET;
return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
&regset, buf, buf_size);
}
Status NativeRegisterContextLinux_ppc64le::DoWriteFPR(void *buf,
size_t buf_size) {
int regset = NT_FPREGSET;
return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
&regset, buf, buf_size);
}
uint32_t NativeRegisterContextLinux_ppc64le::CalculateFprOffset(
const RegisterInfo *reg_info) const {
return reg_info->byte_offset -

View File

@ -68,14 +68,6 @@ public:
bool WatchpointIsEnabled(uint32_t wp_index);
protected:
Status DoReadGPR(void *buf, size_t buf_size) override;
Status DoWriteGPR(void *buf, size_t buf_size) override;
Status DoReadFPR(void *buf, size_t buf_size) override;
Status DoWriteFPR(void *buf, size_t buf_size) override;
bool IsVMX(unsigned reg);
bool IsVSX(unsigned reg);

View File

@ -18,7 +18,6 @@
#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
#include <asm/ptrace.h>
#include <linux/uio.h>
#include <sys/ptrace.h>
@ -196,13 +195,12 @@ NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info,
reg_info->name);
if (IsGPR(reg)) {
s390_regs regs;
Status error = DoReadGPR(&regs, sizeof(regs));
Status error = ReadGPR();
if (error.Fail())
return error;
uint8_t *src = (uint8_t *)&regs + reg_info->byte_offset;
assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
uint8_t *src = (uint8_t *)&m_regs + reg_info->byte_offset;
assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(m_regs));
switch (reg_info->byte_size) {
case 4:
reg_value.SetUInt32(*(uint32_t *)src);
@ -218,14 +216,13 @@ NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info,
}
if (IsFPR(reg)) {
s390_fp_regs fp_regs;
Status error = DoReadFPR(&fp_regs, sizeof(fp_regs));
Status error = ReadFPR();
if (error.Fail())
return error;
// byte_offset is just the offset within FPR, not the whole user area.
uint8_t *src = (uint8_t *)&fp_regs + reg_info->byte_offset;
assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
uint8_t *src = (uint8_t *)&m_fp_regs + reg_info->byte_offset;
assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(m_fp_regs));
switch (reg_info->byte_size) {
case 4:
reg_value.SetUInt32(*(uint32_t *)src);
@ -275,13 +272,12 @@ Status NativeRegisterContextLinux_s390x::WriteRegister(
reg_info->name);
if (IsGPR(reg)) {
s390_regs regs;
Status error = DoReadGPR(&regs, sizeof(regs));
Status error = ReadGPR();
if (error.Fail())
return error;
uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
uint8_t *dst = (uint8_t *)&m_regs + reg_info->byte_offset;
assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(m_regs));
switch (reg_info->byte_size) {
case 4:
*(uint32_t *)dst = reg_value.GetAsUInt32();
@ -293,18 +289,17 @@ Status NativeRegisterContextLinux_s390x::WriteRegister(
assert(false && "Unhandled data size.");
return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
}
return DoWriteGPR(&regs, sizeof(regs));
return WriteGPR();
}
if (IsFPR(reg)) {
s390_fp_regs fp_regs;
Status error = DoReadFPR(&fp_regs, sizeof(fp_regs));
Status error = ReadFPR();
if (error.Fail())
return error;
// byte_offset is just the offset within fp_regs, not the whole user area.
uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
uint8_t *dst = (uint8_t *)&m_fp_regs + reg_info->byte_offset;
assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(m_fp_regs));
switch (reg_info->byte_size) {
case 4:
*(uint32_t *)dst = reg_value.GetAsUInt32();
@ -316,7 +311,7 @@ Status NativeRegisterContextLinux_s390x::WriteRegister(
assert(false && "Unhandled data size.");
return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
}
return DoWriteFPR(&fp_regs, sizeof(fp_regs));
return WriteFPR();
}
if (reg == lldb_last_break_s390x) {
@ -337,15 +332,17 @@ Status NativeRegisterContextLinux_s390x::ReadAllRegisterValues(
data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
uint8_t *dst = data_sp->GetBytes();
error = DoReadGPR(dst, sizeof(s390_regs));
dst += sizeof(s390_regs);
error = ReadGPR();
if (error.Fail())
return error;
memcpy(dst, GetGPRBuffer(), GetGPRSize());
dst += GetGPRSize();
error = DoReadFPR(dst, sizeof(s390_fp_regs));
dst += sizeof(s390_fp_regs);
error = ReadFPR();
if (error.Fail())
return error;
memcpy(dst, GetFPRBuffer(), GetFPRSize());
dst += GetFPRSize();
// Ignore errors if the regset is unsupported (happens on older kernels).
DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
@ -380,7 +377,7 @@ Status NativeRegisterContextLinux_s390x::WriteAllRegisterValues(
return error;
}
uint8_t *src = data_sp->GetBytes();
const uint8_t *src = data_sp->GetBytes();
if (src == nullptr) {
error.SetErrorStringWithFormat("NativeRegisterContextLinux_s390x::%s "
"DataBuffer::GetBytes() returned a null "
@ -389,13 +386,15 @@ Status NativeRegisterContextLinux_s390x::WriteAllRegisterValues(
return error;
}
error = DoWriteGPR(src, sizeof(s390_regs));
src += sizeof(s390_regs);
memcpy(GetGPRBuffer(), src, GetGPRSize());
src += GetGPRSize();
error = WriteGPR();
if (error.Fail())
return error;
error = DoWriteFPR(src, sizeof(s390_fp_regs));
src += sizeof(s390_fp_regs);
memcpy(GetFPRBuffer(), src, GetFPRSize());
src += GetFPRSize();
error = WriteFPR();
if (error.Fail())
return error;
@ -441,26 +440,24 @@ Status NativeRegisterContextLinux_s390x::PokeUserArea(uint32_t offset,
m_thread.GetID(), &parea);
}
Status NativeRegisterContextLinux_s390x::DoReadGPR(void *buf, size_t buf_size) {
assert(buf_size == sizeof(s390_regs));
return PeekUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
Status NativeRegisterContextLinux_s390x::ReadGPR() {
return PeekUserArea(offsetof(user_regs_struct, psw), GetGPRBuffer(),
GetGPRSize());
}
Status NativeRegisterContextLinux_s390x::DoWriteGPR(void *buf,
size_t buf_size) {
assert(buf_size == sizeof(s390_regs));
return PokeUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
Status NativeRegisterContextLinux_s390x::WriteGPR() {
return PokeUserArea(offsetof(user_regs_struct, psw), GetGPRBuffer(),
GetGPRSize());
}
Status NativeRegisterContextLinux_s390x::DoReadFPR(void *buf, size_t buf_size) {
assert(buf_size == sizeof(s390_fp_regs));
return PeekUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
Status NativeRegisterContextLinux_s390x::ReadFPR() {
return PeekUserArea(offsetof(user_regs_struct, fp_regs), GetGPRBuffer(),
GetGPRSize());
}
Status NativeRegisterContextLinux_s390x::DoWriteFPR(void *buf,
size_t buf_size) {
assert(buf_size == sizeof(s390_fp_regs));
return PokeUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
Status NativeRegisterContextLinux_s390x::WriteFPR() {
return PokeUserArea(offsetof(user_regs_struct, fp_regs), GetGPRBuffer(),
GetGPRSize());
}
Status NativeRegisterContextLinux_s390x::DoReadRegisterSet(uint32_t regset,

View File

@ -14,6 +14,7 @@
#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
#include "Plugins/Process/Utility/RegisterContext_s390x.h"
#include "Plugins/Process/Utility/lldb-s390x-register-enums.h"
#include <asm/ptrace.h>
namespace lldb_private {
namespace process_linux {
@ -66,13 +67,18 @@ protected:
Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
const RegisterValue &value) override;
Status DoReadGPR(void *buf, size_t buf_size) override;
Status ReadGPR() override;
Status DoWriteGPR(void *buf, size_t buf_size) override;
Status WriteGPR() override;
Status DoReadFPR(void *buf, size_t buf_size) override;
Status ReadFPR() override;
Status DoWriteFPR(void *buf, size_t buf_size) override;
Status WriteFPR() override;
void *GetGPRBuffer() override { return &m_regs; }
size_t GetGPRSize() override { return sizeof(m_regs); }
void *GetFPRBuffer() override { return &m_fp_regs; }
size_t GetFPRSize() override { return sizeof(m_fp_regs); }
private:
// Info about register ranges.
@ -90,6 +96,9 @@ private:
RegInfo m_reg_info;
lldb::addr_t m_watchpoint_addr;
s390_regs m_regs;
s390_fp_regs m_fp_regs;
// Private member methods.
bool IsRegisterSetAvailable(uint32_t set_index) const;