Add Linux MIPS support
diff --git a/CREDITS b/CREDITS
index 239c676..7a59c7f 100644
--- a/CREDITS
+++ b/CREDITS
@@ -36,3 +36,4 @@
 	Jakub Jelinek <jj@ultra.linux.cz>
 	John Hughes <john@Calva.COM>
 	Richard Braakman <dark@xs4all.nl>
+	Florian Lohoff <flo@rfc822.org>
diff --git a/ChangeLog b/ChangeLog
index 89cf634..486cf67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Sun Oct 31 22:03:00 CET 1999 Wichert Akkerman <wakkerma@debian.org>
+
+  * Merge Linux mips patch from Florian Lohoff <flo@rfc822.org>
+
 Mon Oct 11 00:36:25 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
 
   * Merge patch from Keith Owens <kaos@ocs.com.au> to sys_query_module
diff --git a/configure.in b/configure.in
index ab0e724..9486668 100644
--- a/configure.in
+++ b/configure.in
@@ -41,7 +41,7 @@
 sparc)
 	arch=sparc
 	;;
-mips)
+mips*)
 	arch=mips
 	;;
 alpha*)
diff --git a/defs.h b/defs.h
index 1e6c446..7b02da6 100644
--- a/defs.h
+++ b/defs.h
@@ -116,12 +116,19 @@
 #define	PTRACE_POKEUSER	PTRACE_POKEUSR
 #endif
 #ifdef ALPHA
-#define REG_R0 0
-#define REG_A0 16
-#define REG_A3 19
-#define REG_FP 30
-#define REG_PC 64
+#  define REG_R0 0
+#  define REG_A0 16
+#  define REG_A3 19
+#  define REG_FP 30
+#  define REG_PC 64
 #endif /* ALPHA */
+#ifdef MIPS
+#  define REG_V0 2
+#  define REG_A0 4
+#  define REG_A3 7
+#  define REG_SP 29
+#  define REG_EPC 64
+#endif /* MIPS */
 #endif /* LINUX */
 
 #define SUPPORTED_PERSONALITIES 1
diff --git a/linux/Makefile.in b/linux/Makefile.in
index 8cc135d..e87543d 100644
--- a/linux/Makefile.in
+++ b/linux/Makefile.in
@@ -3,7 +3,7 @@
 #
 
 srcdir = @srcdir@
-VPATH = $(srcdir)
+VPATH = @srcdir@
 
 CC = @CC@
 CPP = @CPP@
diff --git a/linux/alpha/Makefile.in b/linux/alpha/Makefile.in
index 4c5344d..6b029aa 100644
--- a/linux/alpha/Makefile.in
+++ b/linux/alpha/Makefile.in
@@ -3,7 +3,7 @@
 #
 
 srcdir = @srcdir@
-VPATH = $(srcdir)
+VPATH = @srcdir@
 
 CC = @CC@
 CPP = @CPP@
diff --git a/linux/powerpc/.cvsignore b/linux/powerpc/.cvsignore
new file mode 100644
index 0000000..f3c7a7c
--- /dev/null
+++ b/linux/powerpc/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/linux/powerpc/Makefile.in b/linux/powerpc/Makefile.in
index 4c5344d..6b029aa 100644
--- a/linux/powerpc/Makefile.in
+++ b/linux/powerpc/Makefile.in
@@ -3,7 +3,7 @@
 #
 
 srcdir = @srcdir@
-VPATH = $(srcdir)
+VPATH = @srcdir@
 
 CC = @CC@
 CPP = @CPP@
diff --git a/linux/sparc/Makefile.in b/linux/sparc/Makefile.in
index 4c5344d..6b029aa 100644
--- a/linux/sparc/Makefile.in
+++ b/linux/sparc/Makefile.in
@@ -3,7 +3,7 @@
 #
 
 srcdir = @srcdir@
-VPATH = $(srcdir)
+VPATH = @srcdir@
 
 CC = @CC@
 CPP = @CPP@
diff --git a/linux/syscall.h b/linux/syscall.h
index 52219fb..1400a44 100644
--- a/linux/syscall.h
+++ b/linux/syscall.h
@@ -95,7 +95,7 @@
 int sys_query_module();
 int sys_poll();
 
-#ifndef ALPHA
+#if !defined(ALPHA) && !defined(MIPS)
 #ifdef POWERPC
 #  define SYS_socket_subcall	256
 #else
@@ -126,7 +126,7 @@
 int sys_msgsnd(), sys_msgrcv(), sys_msgget(), sys_msgctl();
 int sys_shmat(), sys_shmdt(), sys_shmget(), sys_shmctl();
 
-#ifndef ALPHA
+#if !defined(ALPHA) && !defined(MIPS)
 #ifdef POWERPC
 #  define SYS_ipc_subcall		((SYS_socket_subcall)+(SYS_socket_nsubcalls))
 #else
diff --git a/mem.c b/mem.c
index e293038..479cbbe 100644
--- a/mem.c
+++ b/mem.c
@@ -138,7 +138,7 @@
 struct tcb *tcp;
 {
 #ifdef LINUX
-#  if defined(ALPHA) || defined(sparc) || defined(POWERPC)
+#  if defined(ALPHA) || defined(sparc) || defined(POWERPC) || defined(MIPS)
 	long *u_arg = tcp->u_arg;
 #  else /* !ALPHA */
 	long u_arg[6];
@@ -148,7 +148,7 @@
 #endif /* !LINUX */
 
 	if (entering(tcp)) {
-#if defined(LINUX) && !defined(ALPHA) && !defined(sparc) && !defined(POWERPC)
+#if defined(LINUX) && !defined(ALPHA) && !defined(sparc) && !defined(POWERPC) && !defined(MIPS)
 		if (umoven(tcp, tcp->u_arg[0], sizeof u_arg,
 				(char *) u_arg) == -1)
 			return 0;
diff --git a/process.c b/process.c
index 9d09c8a..f985e21 100644
--- a/process.c
+++ b/process.c
@@ -1536,7 +1536,9 @@
 	{ 4*PT_PC,		"4*PT_PC"				},
 #endif /* M68K */
 #endif /* !I386 */
+#ifndef MIPS
 	{ uoff(u_fpvalid),	"offsetof(struct user, u_fpvalid)"	},
+#endif
 #ifdef I386
 	{ uoff(i387),		"offsetof(struct user, i387)"		},
 #else /* !I386 */
@@ -1550,9 +1552,11 @@
 	{ uoff(start_code),	"offsetof(struct user, start_code)"	},
 	{ uoff(start_stack),	"offsetof(struct user, start_stack)"	},
 	{ uoff(signal),		"offsetof(struct user, signal)"		},
+#ifndef MIPS
 	{ uoff(reserved),	"offsetof(struct user, reserved)"	},
+#endif
 	{ uoff(u_ar0),		"offsetof(struct user, u_ar0)"		},
-#ifndef ARM
+#if !defined(ARM) && !defined(MIPS)
 	{ uoff(u_fpstate),	"offsetof(struct user, u_fpstate)"	},
 #endif
 	{ uoff(magic),		"offsetof(struct user, magic)"		},
diff --git a/signal.c b/signal.c
index 3d4b7c1..f0b9546 100644
--- a/signal.c
+++ b/signal.c
@@ -812,6 +812,28 @@
 		return RVAL_NONE | RVAL_STR;
 	}
 	return 0;
+#else  
+#ifdef MIPS
+	long sp;
+	struct sigcontext sc;
+
+	if(entering(tcp)) {
+	  	tcp->u_arg[0] = 0;
+		if (upeek(tcp->pid, REG_SP, &sp) < 0)
+		  	return 0;
+		if (umove(tcp, sp, &sc) < 0)
+		  	return 0;
+		tcp->u_arg[0] = 1;
+		tcp->u_arg[1] = sc.sc_sigset;
+	} else {
+	  	tcp->u_rval = tcp->u_error = 0;
+		if(tcp->u_arg[0] == 0)
+		  	return 0;
+		tcp->auxstr = sprintsigmask("mask now ", tcp->u_arg[1]);
+		return RVAL_NONE | RVAL_STR;
+	}
+	return 0;
+#endif /* MIPS */
 #endif /* SPARC */
 #endif /* ALPHA */
 #endif /* !M68K */
diff --git a/sunos4/Makefile.in b/sunos4/Makefile.in
index efc973d..3b3f7fee 100644
--- a/sunos4/Makefile.in
+++ b/sunos4/Makefile.in
@@ -3,7 +3,7 @@
 #
 
 srcdir = @srcdir@
-VPATH = $(srcdir)
+VPATH = @srcdir@
 
 CC = @CC@
 CPP = @CPP@
diff --git a/svr4/Makefile.in b/svr4/Makefile.in
index e9627fe..f52f440 100644
--- a/svr4/Makefile.in
+++ b/svr4/Makefile.in
@@ -3,7 +3,7 @@
 #
 
 srcdir = @srcdir@
-VPATH = $(srcdir)
+VPATH = @srcdir@
 
 CC = @CC@
 CPP = @CPP@
diff --git a/syscall.c b/syscall.c
index 7c31fc0..3b3f7fe2 100644
--- a/syscall.c
+++ b/syscall.c
@@ -406,7 +406,7 @@
 
 enum subcall_style { shift_style, deref_style, mask_style, door_style };
 
-#if !(defined(LINUX) && defined(ALPHA))
+#if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) ))
 
 const int socket_map [] = {
 	       /* SYS_SOCKET      */ 97,
@@ -585,6 +585,8 @@
 #elif defined (ALPHA)
 	long r0;
 	long a3;
+#elif defined(MIPS)
+	long r2,a3;
 #elif defined (SPARC)
 	struct regs regs;
 	unsigned long trap;
@@ -622,6 +624,25 @@
 #elif defined (M68K)
 	if (upeek(pid, 4*PT_ORIG_D0, &scno) < 0)
 		return -1;
+#elif defined (MIPS)
+	if (upeek(pid, REG_A3, &a3) < 0)
+	  	return -1;
+
+	if(!(tcp->flags & TCB_INSYSCALL)) {
+	  	if (upeek(pid, REG_V0, &scno) < 0)
+		  	return -1;
+
+		if (scno < 0 || scno > nsyscalls) {
+			if(a3 == 0 || a3 == -1) {
+				if(debug)
+					fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
+				return 0;
+			}
+		}
+	} else {
+	  	if (upeek(pid, REG_V0, &r2) < 0)
+	    		return -1;
+	}
 #elif defined (ALPHA)
 	if (upeek(pid, REG_A3, &a3) < 0)
 		return -1;
@@ -821,6 +842,15 @@
 			u_error = 0;
 		}
 #else /* !I386 */
+#ifdef MIPS
+		if (a3) {
+		  	tcp->u_rval = -1;
+			u_error = r2;
+		} else {
+		  	tcp->u_rval = r2;
+			u_error = 0;
+		}
+#else
 #ifdef POWERPC
 		if (result && (unsigned) -result < nerrnos) {
 			tcp->u_rval = -1;
@@ -875,6 +905,7 @@
 #endif /* ARM */
 #endif /* M68K */
 #endif /* POWERPC */
+#endif /* MIPS */
 #endif /* I386 */
 #endif /* LINUX */
 #ifdef SUNOS4
@@ -1067,6 +1098,28 @@
 				return -1;
 		}
 	}
+#elif defined (MIPS)
+	{
+	  	long sp;
+	  	int i, nargs;
+
+		nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
+		if(nargs > 4) {
+		  	if(upeek(pid, REG_SP, &sp) < 0)
+			  	return -1;
+			for(i = 0; i < 4; i++) {
+			  	if (upeek(pid, REG_A0 + i, &tcp->u_arg[i])<0)
+				  	return -1;
+			}
+			umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
+			       (char *)(tcp->u_arg + 4));
+		} else {
+		  	for(i = 0; i < nargs; i++) {
+			  	if (upeek(pid, REG_A0 + i, &tcp->u_arg[i]) < 0)
+				  	return -1;
+			}
+		}
+	}
 #elif defined (POWERPC)
 	{
 		int i;
@@ -1161,7 +1214,7 @@
 	switch (tcp->scno) {
 #endif
 #ifdef LINUX
-#if !defined (ALPHA) && !defined(SPARC)
+#if !defined (ALPHA) && !defined(SPARC) && !defined(MIPS)
 	case SYS_socketcall:
 		decode_subcall(tcp, SYS_socket_subcall,
 			SYS_socket_nsubcalls, deref_style);
diff --git a/util.c b/util.c
index 41a8b3a..8893039 100644
--- a/util.c
+++ b/util.c
@@ -868,37 +868,30 @@
 #ifdef LINUX
 	long pc;
 
-#ifdef I386
+#if defined(I386)
 	if (upeek(tcp->pid, 4*EIP, &pc) < 0)
 		return -1;
-#else /* !I386 */
-#ifdef ARM
+#elif defined(ARM)
 	if (upeek(tcp->pid, 4*15, &pc) < 0)
 		return -1;
-#else /* !ARM */
-#ifdef POWERPC
+#elif defined(POWERPC)
 	if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0)
 		return -1;
-#else
-#ifdef M68K
+#elif defined(M68k)
 	if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
 		return -1;
-#else /* !M68K */
-#ifdef ALPHA
+#elif defined(ALPHA)
 	if (upeek(tcp->pid, REG_PC, &pc) < 0)
 		return -1;
-#else /* !ALPHA */
-#ifdef SPARC
+#elif defined(MIPS)
+ 	if (upeek(tcp->pid, REG_EPC, &pc) < 0)
+ 		return -1;
+#elif defined(SPARC)
 	struct regs regs;
 	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
 		return -1;
 	pc = regs.r_pc;
-#endif /* SPARC */
-#endif /* ALPHA */
-#endif /* !M68K */
-#endif /* !POWERPC */
-#endif /* !ARM */
-#endif /* !I386 */
+#endif
 	return pc;
 #endif /* LINUX */
 
@@ -1057,6 +1050,8 @@
 #define LOOP 0x0000feeb
 #elif defined(ARM)
 #define LOOP -1  /* almost certainly wrong, jws */
+#elif defined(MIPS)
+#define LOOP 0x1000ffff
 #else
 #error unknown architecture
 #endif
@@ -1075,6 +1070,8 @@
 	return -1;
 #elif defined (ARM)
 	return -1;
+#elif defined (MIPS)
+	return -1;		/* FIXME: I do not know what i do - Flo */
 #elif defined (POWERPC)
 	if (upeek(tcp->pid, 4*PT_NIP, &tcp->baddr) < 0)
 		return -1;