Add support for ARC Cores from Synopsys
Take #2 on mainlining strace support for ARC (last one was 4.6 based back
in March 2011), see
http://sourceforge.net/p/strace/mailman/message/27210168/
The syscall ABI is asm-generic/unistd.h based (so no legacy syscalls),
hence very similar to metag port.
test/* all seem to work well.
* linux/arc/ioctlent.h.in: New file.
* linux/arc/syscallent.h: Likewise.
* Makefile.am (EXTRA_DIST): Add linux/arc/ioctlent.h.in and
linux/arc/syscallent.h.
* configure.ac: Add ARC to the list of supported architectures.
* defs.h: Add ARC support.
* process.c (struct_user_offsets): Likewise.
* signal.c (sys_sigreturn): Likewise.
* syscall.c (print_pc, get_regset, get_regs, get_scno, get_syscall_args,
get_syscall_result, get_error): Likewise.
* util.c (change_syscall): Likewise.
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Acked-by: Mike Frysinger <vapier@gentoo.org>
diff --git a/syscall.c b/syscall.c
index 1b49bb3..83a95bd 100644
--- a/syscall.c
+++ b/syscall.c
@@ -774,6 +774,9 @@
# define ARCH_REGS_FOR_GETREGSET metag_regs
#elif defined(XTENSA)
static long xtensa_a2;
+# elif defined(ARC)
+static struct user_regs_struct arc_regs;
+# define ARCH_REGS_FOR_GETREGSET arc_regs
#endif
void
@@ -914,6 +917,8 @@
return;
}
tprintf("[%08lx] ", pc);
+#elif defined(ARC)
+ tprintf("[%08lx] ", arc_regs.efa);
#endif /* architecture */
}
@@ -1009,7 +1014,8 @@
# if defined(ARM) \
|| defined(I386) \
|| defined(METAG) \
- || defined(OR1K)
+ || defined(OR1K) \
+ || defined(ARC)
static struct iovec io = {
.iov_base = &ARCH_REGS_FOR_GETREGSET,
.iov_len = sizeof(ARCH_REGS_FOR_GETREGSET)
@@ -1035,7 +1041,7 @@
get_regs(pid_t pid)
{
/* PTRACE_GETREGSET only */
-# if defined(METAG) || defined(OR1K) || defined(X32) || defined(AARCH64)
+# if defined(METAG) || defined(OR1K) || defined(X32) || defined(AARCH64) || defined(ARC)
get_regset(pid);
/* PTRACE_GETREGS only */
@@ -1542,6 +1548,8 @@
#elif defined(XTENSA)
if (upeek(tcp->pid, SYSCALL_NR, &scno) < 0)
return -1;
+# elif defined(ARC)
+ scno = arc_regs.scratch.r8;
#endif
tcp->scno = scno;
@@ -1932,6 +1940,11 @@
for (i = 0; i < nargs; ++i)
if (upeek(tcp->pid, REG_A_BASE + xtensaregs[i], &tcp->u_arg[i]) < 0)
return -1;
+# elif defined(ARC)
+ long *arc_args = &arc_regs.scratch.r0;
+ for (i = 0; i < nargs; ++i)
+ tcp->u_arg[i] = *arc_args--;
+
#else /* Other architecture (32bits specific) */
for (i = 0; i < nargs; ++i)
if (upeek(tcp->pid, i*4, &tcp->u_arg[i]) < 0)
@@ -2130,6 +2143,8 @@
#elif defined(XTENSA)
if (upeek(tcp->pid, REG_A_BASE + 2, &xtensa_a2) < 0)
return -1;
+#elif defined(ARC)
+ /* already done by get_regs */
#endif
return 1;
}
@@ -2435,6 +2450,14 @@
else {
tcp->u_rval = xtensa_a2;
}
+#elif defined(ARC)
+ if (check_errno && is_negated_errno(arc_regs.scratch.r0)) {
+ tcp->u_rval = -1;
+ u_error = -arc_regs.scratch.r0;
+ }
+ else {
+ tcp->u_rval = arc_regs.scratch.r0;
+ }
#endif
tcp->u_error = u_error;
}