mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-02-03 13:12:54 +01: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:
parent
cc0c170f53
commit
0314ff8522
2 changed files with 45 additions and 2 deletions
|
@ -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,
|
||||
|
|
|
@ -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 = ®s;
|
||||
loc.iov_len = sizeof(regs);
|
||||
|
||||
r = (char *)®s + _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)
|
||||
|
|
Loading…
Reference in a new issue