[PATCH 4/6] nds32: add NDS32 support to syscall.c

Macpaul Lin macpaul at andestech.com
Fri Feb 11 09:37:59 UTC 2011


Add NDS32 support to syscall.c

Signed-off-by: Macpaul Lin <macpaul at andestech.com>
---
 syscall.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/syscall.c b/syscall.c
index dc82b2a..e174b10 100644
--- a/syscall.c
+++ b/syscall.c
@@ -98,6 +98,10 @@
 #undef NR_SYSCALL_BASE
 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
 #endif
+#ifdef NDS32
+#undef NR_SYSCALL_BASE
+#define NR_SYSCALL_BASE __NR_SYSCALL_BASE
+#endif
 #endif /* LINUX */
 
 #include "syscall.h"
@@ -721,6 +725,8 @@ internal_syscall(struct tcb *tcp)
 	static long r10;
 #elif defined(MICROBLAZE)
 	static long r3;
+#elif defined(NDS32)
+	static long r0;
 #endif
 #endif /* LINUX */
 #ifdef FREEBSD
@@ -1279,6 +1285,43 @@ get_scno(struct tcb *tcp)
 # elif defined(MICROBLAZE)
 	if (upeek(tcp, 0, &scno) < 0)
 		return -1;
+# elif defined(NDS32)
+	if(!(tcp->flags & TCB_INSYSCALL)) {
+		unsigned int op, pc, psw;
+
+		/* Check if we return from execve. */
+		if ((tcp->flags & TCB_WAITEXECVE)) {
+			tcp->flags &= ~TCB_WAITEXECVE;
+			return 0;
+		}
+
+		/* IPC */
+		if (upeek(pid, 4*2, &pc) < 0)
+			return -1;
+
+		/* IPSW */
+		if (upeek(pid, 4*1, &psw) < 0)
+			return -1;
+
+		/*
+		 * FIXME, if kennel endian diff with user program, this will be
+		 * terrible, Harry at Jan.30.2008.
+		 */
+		op = ptrace(PTRACE_PEEKTEXT, pid, (char *)(pc - 4), 0);
+
+		if (0 == (psw & (1 << 5)))
+			op = ((((op) & 0xff000000) >> 24) | (((op) & 0x00ff0000) >>  8) | \
+				(((op) & 0x0000ff00) <<  8) | (((op) & 0x000000ff) << 24));
+
+		if((op & 0xfff0000f) != 0x6400000b)
+			fprintf(stderr, "opcode: %x\n", op);
+
+		/* Fixup opcode to SWID */
+		scno = ((op >> 5) & 0x7fff) - NR_SYSCALL_BASE;
+	} else {
+		if (upeek(pid, 4*13, &r0) < 0)
+			return -1;
+	}
 # endif
 #endif /* LINUX */
 
@@ -1720,6 +1763,16 @@ get_error(struct tcb *tcp)
 			tcp->u_rval = r3;
 			u_error = 0;
 		}
+# elif defined(NDS32)
+		/* interpret result as return value or error number */
+		if (check_errno && is_negated_errno(r0)) {
+			tcp->u_rval = -1;
+			u_error = -r0;
+		}
+		else {
+			tcp->u_rval = r0;
+			u_error = 0;
+		}
 # endif
 #endif /* LINUX */
 #ifdef SUNOS4
@@ -1928,6 +1981,10 @@ force_result(tcp, error, rval)
 	r9 = error ? -error : rval;
 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
 		return -1;
+# elif defined(NDS32)
+	r0 = error ? -error : rval;
+	if (ptrace(PTRACE_POKEUSER, tcp->pid, 4*13, r0) < 0)
+		return -1;
 # endif
 #endif /* LINUX */
 
@@ -2283,6 +2340,18 @@ syscall_enter(struct tcb *tcp)
 				return -1;
 		}
 	}
+#elif defined(NDS32)
+	{
+		int i;
+		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+			tcp->u_nargs = sysent[tcp->scno].nargs;
+		else
+			tcp->u_nargs = MAX_ARGS;
+		for (i = 0; i < tcp->u_nargs; i++) {
+			if (upeek(pid, 4*(13+i), &tcp->u_arg[i]) < 0)
+				return -1;
+		}
+	}
 #else /* Other architecture (like i386) (32bits specific) */
 	{
 		int i;
@@ -2757,6 +2826,9 @@ struct tcb *tcp;
 #elif defined(IA64)
 	if (upeek(tcp, PT_R9, &val) < 0)
 		return -1;
+#elif defined(NDS32)
+	if (upeek(tcp->pid, 4*13, &val) < 0)
+		return -1;
 #endif
 #endif /* LINUX */
 
-- 
1.7.3.5





More information about the Strace-devel mailing list