Add NDS32 support to syscall.c

Signed-off-by: Macpaul Lin <[email protected]>
---
 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, [email protected].
+                */
+               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


------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to