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;
 }