Add AArch64 support to strace
AArch64 has been included in linux from 3.7 onwards.
Add support for AArch64 in strace, tested on linux in a simulator.
* configure.ac: Support AArch64.
* defs.h [AARCH64]: Include <sys/ptrace.h>, define TCB_WAITEXECVE.
* ipc.c (indirect_ipccall): Support AArch64.
* process.c (struct_user_offsets): Likewise.
* syscall.c [AARCH64]: Include <asm/ptrace.h>, <sys/uio.h>, and
<elf.h>. Define struct user_pt_regs regs.
(get_scno, get_syscall_result): Support AArch64 using PTRACE_GETREGSET.
(get_syscall_args, get_error): Support AArch64.
* linux/aarch64/ioctlent.h.in: New file.
* linux/aarch64/syscallent.h: New file, based on linux 3.7 version of
asm-generic/unistd.h.
Signed-off-by: Steve McIntyre <steve.mcintyre@linaro.org>
diff --git a/syscall.c b/syscall.c
index 37936ad..680cbc3 100644
--- a/syscall.c
+++ b/syscall.c
@@ -65,6 +65,12 @@
# include <asm/rse.h>
#endif
+#if defined(AARCH64)
+# include <asm/ptrace.h>
+# include <sys/uio.h>
+# include <elf.h>
+#endif
+
#ifndef ERESTARTSYS
# define ERESTARTSYS 512
#endif
@@ -657,6 +663,8 @@
static long r0;
#elif defined(ARM)
static struct pt_regs regs;
+#elif defined(AARCH64)
+static struct user_pt_regs regs;
#elif defined(ALPHA)
static long r0;
static long a3;
@@ -967,6 +975,13 @@
fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
tcp->flags |= TCB_INSYSCALL;
}
+#elif defined(AARCH64)
+ struct iovec io;
+ io.iov_base = ®s;
+ io.iov_len = sizeof(regs);
+ if (ptrace(PTRACE_GETREGSET, tcp->pid, NT_PRSTATUS, (void *)&io) == -1)
+ return -1;
+ scno = regs.regs[8];
#elif defined(M68K)
if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
return -1;
@@ -1403,6 +1418,9 @@
#elif defined(ARM)
for (i = 0; i < nargs; ++i)
tcp->u_arg[i] = regs.uregs[i];
+#elif defined(AARCH64)
+ for (i = 0; i < nargs; ++i)
+ tcp->u_arg[i] = regs.regs[i];
#elif defined(AVR32)
(void)i;
(void)nargs;
@@ -1641,6 +1659,12 @@
/* Read complete register set in one go. */
if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
return -1;
+#elif defined(AARCH64)
+ struct iovec io;
+ io.iov_base = ®s;
+ io.iov_len = sizeof(regs);
+ if (ptrace(PTRACE_GETREGSET, tcp->pid, NT_PRSTATUS, (void *)&io) == -1)
+ return -1;
#elif defined(M68K)
if (upeek(tcp, 4*PT_D0, &d0) < 0)
return -1;
@@ -1823,6 +1847,14 @@
else {
tcp->u_rval = regs.ARM_r0;
}
+#elif defined(AARCH64)
+ if (check_errno && is_negated_errno(regs.regs[0])) {
+ tcp->u_rval = -1;
+ u_error = -regs.regs[0];
+ }
+ else {
+ tcp->u_rval = regs.regs[0];
+ }
#elif defined(AVR32)
if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) {
tcp->u_rval = -1;