forked from OSchip/llvm-project
Fix arm lldb-server on aarch64 device
* Use PTRACE_GETVFPREGS/PTRACE_SETVFPREGS to access the floating point registers instead of the old PTRACE_GETFPREGS/PTRACE_SETFPREGS. The new call is available since armv5. * Work around a kernel issue in PTRACE_POKEUSER with reading out the full register set, modifying the neccessary value and then writing it back. llvm-svn: 251111
This commit is contained in:
parent
422b3ff120
commit
ce26b7a6ee
|
@ -20,6 +20,10 @@
|
|||
|
||||
#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))
|
||||
|
||||
#ifndef PTRACE_GETVFPREGS
|
||||
#define PTRACE_GETVFPREGS 27
|
||||
#define PTRACE_SETVFPREGS 28
|
||||
#endif
|
||||
#ifndef PTRACE_GETHBPREGS
|
||||
#define PTRACE_GETHBPREGS 29
|
||||
#define PTRACE_SETHBPREGS 30
|
||||
|
@ -853,4 +857,45 @@ NativeRegisterContextLinux_arm::CalculateFprOffset(const RegisterInfo* reg_info)
|
|||
return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
|
||||
}
|
||||
|
||||
Error
|
||||
NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset,
|
||||
const char* reg_name,
|
||||
const RegisterValue &value)
|
||||
{
|
||||
// PTRACE_POKEUSER don't work in the aarch64 liux kernel used on android devices (always return
|
||||
// "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR register set, modify
|
||||
// the requested register and write it back. This approach is about 4 times slower but the
|
||||
// performance overhead is negligible in comparision to processing time in lldb-server.
|
||||
assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
|
||||
if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
|
||||
return Error("Register isn't fit into the size of the GPR area");
|
||||
|
||||
Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
|
||||
if (error.Fail())
|
||||
return error;
|
||||
|
||||
m_gpr_arm[offset / sizeof(uint32_t)] = value.GetAsUInt32();
|
||||
return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
|
||||
}
|
||||
|
||||
Error
|
||||
NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size)
|
||||
{
|
||||
return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS,
|
||||
m_thread.GetID(),
|
||||
nullptr,
|
||||
buf,
|
||||
buf_size);
|
||||
}
|
||||
|
||||
Error
|
||||
NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size)
|
||||
{
|
||||
return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS,
|
||||
m_thread.GetID(),
|
||||
nullptr,
|
||||
buf,
|
||||
buf_size);
|
||||
}
|
||||
|
||||
#endif // defined(__arm__)
|
||||
|
|
|
@ -90,6 +90,17 @@ namespace process_linux {
|
|||
};
|
||||
|
||||
protected:
|
||||
Error
|
||||
DoWriteRegisterValue(uint32_t offset,
|
||||
const char* reg_name,
|
||||
const RegisterValue &value) override;
|
||||
|
||||
Error
|
||||
DoReadFPR(void *buf, size_t buf_size) override;
|
||||
|
||||
Error
|
||||
DoWriteFPR(void *buf, size_t buf_size) override;
|
||||
|
||||
void*
|
||||
GetGPRBuffer() override { return &m_gpr_arm; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue