mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-07-04 14:35:34 +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:
parent
cc0c170f53
commit
0314ff8522
|
@ -56,7 +56,7 @@ AC_CHECK_TYPES([struct elf_prstatus, struct prstatus], [], [],
|
||||||
#endif
|
#endif
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA,
|
AC_CHECK_DECLS([PTRACE_POKEUSER, PTRACE_POKEDATA, PTRACE_SETREGSET,
|
||||||
PTRACE_TRACEME, PTRACE_CONT, PTRACE_SINGLESTEP,
|
PTRACE_TRACEME, PTRACE_CONT, PTRACE_SINGLESTEP,
|
||||||
PTRACE_SYSCALL, PT_IO, PT_GETREGS,
|
PTRACE_SYSCALL, PT_IO, PT_GETREGS,
|
||||||
PT_GETFPREGS, PT_CONTINUE, PT_TRACE_ME,
|
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"
|
# include "tdep-ia64/rse.h"
|
||||||
#endif
|
#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
|
int
|
||||||
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
||||||
int write, void *arg)
|
int write, void *arg)
|
||||||
|
|
Loading…
Reference in a new issue