summaryrefslogtreecommitdiff
path: root/syscall.c
diff options
context:
space:
mode:
authorVineet Gupta <Vineet.Gupta1@synopsys.com>2013-08-16 12:47:06 +0530
committerDmitry V. Levin <ldv@altlinux.org>2013-09-11 14:44:54 +0000
commit7daacbbbe7349677476a3d2fbf174dcf86f171be (patch)
tree7e1488f3451b29804ff007f35d5dc30594f3a4f5 /syscall.c
parent16b9dcf8b870f47305aa2db174f5abccefb7cd94 (diff)
downloadstrace-7daacbbbe7349677476a3d2fbf174dcf86f171be.tar.gz
strace-7daacbbbe7349677476a3d2fbf174dcf86f171be.tar.bz2
strace-7daacbbbe7349677476a3d2fbf174dcf86f171be.tar.xz
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>
Diffstat (limited to 'syscall.c')
-rw-r--r--syscall.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/syscall.c b/syscall.c
index 1b49bb3..83a95bd 100644
--- a/syscall.c
+++ b/syscall.c
@@ -774,6 +774,9 @@ static struct user_gp_regs metag_regs;
# 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 @@ print_pc(struct tcb *tcp)
return;
}
tprintf("[%08lx] ", pc);
+#elif defined(ARC)
+ tprintf("[%08lx] ", arc_regs.efa);
#endif /* architecture */
}
@@ -1009,7 +1014,8 @@ static void get_regset(pid_t pid)
# 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 @@ void
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 @@ get_scno(struct tcb *tcp)
#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 @@ get_syscall_args(struct tcb *tcp)
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 @@ get_syscall_result(struct tcb *tcp)
#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 @@ get_error(struct tcb *tcp)
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;
}