1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-06-30 13:11:44 +02:00

aarch64: Use PTRACE_GETREGSET if available

In remote ptrace mode, we currently use PTRACE_PEEKUSER to read the registers.

PTRACE_PEEKUSER only works on x86 or arm 32 bit compatibility mode on linux. On aarch64 system,
it always return -EIO. https://github.com/torvalds/linux/blob/master/kernel/ptrace.c#L885-L1102

PTRACE_GETREGSET is the newer and more supported way of reading registers. Use that if it's available.
This commit is contained in:
Stephen Chen 2017-08-07 09:32:27 -07:00 committed by Dave Watson
parent cc0c170f53
commit 0314ff8522
2 changed files with 45 additions and 2 deletions

View file

@ -56,7 +56,7 @@ AC_CHECK_TYPES([struct elf_prstatus, struct prstatus], [], [],
#endif
])
AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA,
AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA, PTRACE_SETREGSET,
PTRACE_TRACEME, PTRACE_CONT, PTRACE_SINGLESTEP,
PTRACE_SYSCALL, PT_IO, PT_GETREGS,
PT_GETFPREGS, PT_CONTINUE, PT_TRACE_ME,

View file

@ -34,7 +34,50 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
# include "tdep-ia64/rse.h"
#endif
#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE
#if HAVE_DECL_PTRACE_SETREGSET
#include <sys/uio.h>
int
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
int write, void *arg)
{
struct UPT_info *ui = arg;
pid_t pid = ui->pid;
gregset_t regs;
char *r;
struct iovec loc;
#if UNW_DEBUG
Debug(16, "using getregset: reg: %s [%u], val: %lx, write: %u\n",
unw_regname(reg), (unsigned) reg, (long) val, write);
if (write)
Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val);
#endif
if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset))
{
errno = EINVAL;
goto badreg;
}
loc.iov_base = &regs;
loc.iov_len = sizeof(regs);
r = (char *)&regs + _UPT_reg_offset[reg];
if (ptrace (PTRACE_GETREGSET, pid, NT_PRSTATUS, &loc) == -1)
goto badreg;
if (write) {
memcpy(r, val, sizeof(unw_word_t));
if (ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &loc) == -1)
goto badreg;
} else
memcpy(val, r, sizeof(unw_word_t));
return 0;
badreg:
Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno));
return -UNW_EBADREG;
}
#elif HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE
int
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
int write, void *arg)