2003-06-02  Roland McGrath  <roland@redhat.com>

	* configure.ac, defs.h, mem.c, process.c, sock.c, syscall.c, util.c:
	Merged in SHmedia port from Stephen Thomas <stephen.thomas@superh.com>.
diff --git a/configure.ac b/configure.ac
index 28fbeed..4aa93c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,6 +91,10 @@
 	arch=sh
 	AC_DEFINE([SH], 1, [Define for the SH architecture.])
 	;;
+shmedia)
+	arch=shmedia
+	AC_DEFINE([SHMEDIA], 1, [Define for the SHmedia architecture.])
+	;;
 x86?64*)
 	arch=x86_64
 	AC_DEFINE([X86_64], 1, [Define for the AMD x86-64 architecture.])
diff --git a/defs.h b/defs.h
index 4138894..b42d114 100644
--- a/defs.h
+++ b/defs.h
@@ -170,6 +170,22 @@
 #  define PT_IAOQ0 (106*4)
 #  define PT_IAOQ1 (107*4)
 #endif /* HPPA */
+#ifdef SHMEDIA
+   /* SHmedia Linux - this code assumes the following kernel API for system calls:
+          PC           Offset 0
+          System Call  Offset 16 (actually, (syscall no.) | (0x1n << 16),
+                       where n = no. of parameters.
+          Other regs   Offset 24+
+
+          On entry:    R2-7 = parameters 1-6 (as many as necessary)
+          On return:   R9   = result. */
+
+   /* Offset for peeks of registers */
+#  define REG_OFFSET         (24)
+#  define REG_GENERAL(x)     (8*(x)+REG_OFFSET)
+#  define REG_PC             (0*8)
+#  define REG_SYSCALL        (2*8)
+#endif /* SHMEDIA */
 #endif /* LINUX */
 
 #define SUPPORTED_PERSONALITIES 1
@@ -302,7 +318,7 @@
 #define TCB_FOLLOWFORK	00400	/* Process should have forks followed */
 #define TCB_REPRINT	01000	/* We should reprint this syscall on exit */
 #ifdef LINUX
-# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(S390) || defined(S390X)
+# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(SHMEDIA) || defined(S390) || defined(S390X)
 #  define TCB_WAITEXECVE 02000	/* ignore SIGTRAP after exceve */
 # endif
 # define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */
diff --git a/mem.c b/mem.c
index f8cc09d..44e67e6 100644
--- a/mem.c
+++ b/mem.c
@@ -3,6 +3,8 @@
  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
+ * Copyright (c) 2000 PocketPenguins Inc.  Linux for Hitachi SuperH
+ *                    port by Greg Banks <gbanks@pocketpenguins.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,6 +42,9 @@
 #if defined(LINUX) && defined(I386)
 #include <asm/ldt.h>
 #endif
+#if defined(LINUX) && defined(SHMEDIA)
+#include <asm/page.h>	    /* for PAGE_SHIFT */
+#endif
 
 #ifdef HAVE_LONG_LONG_OFF_T
 /*
@@ -222,7 +227,7 @@
 		return 0;
 	else
 		u_arg[i] = v;
-#elif defined(SH)
+#elif defined(SH) || defined(SHMEDIA)
     /* SH has always passed the args in registers */
     int i;
     for (i=0; i<6; i++)
@@ -240,6 +245,15 @@
 sys_mmap(tcp)
 struct tcb *tcp;
 {
+#if defined(LINUX) && defined(SHMEDIA)
+    /*
+     * Old mmap differs from new mmap in specifying the
+     * offset in units of bytes rather than pages.  We
+     * pretend it's in byte units so the user only ever
+     * sees bytes in the printout.
+     */
+    tcp->u_arg[5] <<= PAGE_SHIFT;
+#endif
     return print_mmap(tcp, tcp->u_arg);
 }
 #endif /* !HAVE_LONG_LONG_OFF_T */
diff --git a/process.c b/process.c
index 0a6f839..bb33a20 100644
--- a/process.c
+++ b/process.c
@@ -663,6 +663,13 @@
        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
                return -1;
        return 0;
+#elif defined(SHMEDIA)
+       /* Top half of reg encodes the no. of args n as 0x1n.
+          Assume 0 args as kernel never actually checks... */
+       if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
+                                   0x100000 | new) < 0)
+                       return -1;
+       return 0;
 #else
 #warning Do not know how to handle change_syscall for this architecture
 #endif /* architecture */
@@ -2465,6 +2472,160 @@
        { 4*REG_XDREG14,        "4*REG_XDREG14"                         },
        { 4*REG_FPSCR,          "4*REG_FPSCR"                           },
 #endif /* SH */
+#ifdef SHMEDIA
+	{ 0,		        "PC(L)"				        },
+	{ 4,	                "PC(U)"				        },
+	{ 8, 	                "SR(L)"	  	         		},
+	{ 12,               	"SR(U)"     				},
+	{ 16,            	"syscall no.(L)" 			},
+	{ 20,            	"syscall_no.(U)"			},
+	{ 24,            	"R0(L)"     				},
+	{ 28,            	"R0(U)"     				},
+	{ 32,            	"R1(L)"     				},
+	{ 36,            	"R1(U)"     				},
+	{ 40,            	"R2(L)"     				},
+	{ 44,            	"R2(U)"     				},
+	{ 48,            	"R3(L)"     				},
+	{ 52,            	"R3(U)"     				},
+	{ 56,            	"R4(L)"     				},
+	{ 60,            	"R4(U)"     				},
+	{ 64,            	"R5(L)"     				},
+	{ 68,            	"R5(U)"     				},
+	{ 72,            	"R6(L)"     				},
+	{ 76,            	"R6(U)"     				},
+	{ 80,            	"R7(L)"     				},
+	{ 84,            	"R7(U)"     				},
+	{ 88,            	"R8(L)"     				},
+	{ 92,            	"R8(U)"     				},
+	{ 96,            	"R9(L)"     				},
+	{ 100,           	"R9(U)"     				},
+	{ 104,           	"R10(L)"     				},
+	{ 108,           	"R10(U)"     				},
+	{ 112,           	"R11(L)"     				},
+	{ 116,           	"R11(U)"     				},
+	{ 120,           	"R12(L)"     				},
+	{ 124,           	"R12(U)"     				},
+	{ 128,           	"R13(L)"     				},
+	{ 132,           	"R13(U)"     				},
+	{ 136,           	"R14(L)"     				},
+	{ 140,           	"R14(U)"     				},
+	{ 144,           	"R15(L)"     				},
+	{ 148,           	"R15(U)"     				},
+	{ 152,           	"R16(L)"     				},
+	{ 156,           	"R16(U)"     				},
+	{ 160,           	"R17(L)"     				},
+	{ 164,           	"R17(U)"     				},
+	{ 168,           	"R18(L)"     				},
+	{ 172,           	"R18(U)"     				},
+	{ 176,           	"R19(L)"     				},
+	{ 180,           	"R19(U)"     				},
+	{ 184,           	"R20(L)"     				},
+	{ 188,           	"R20(U)"     				},
+	{ 192,           	"R21(L)"     				},
+	{ 196,           	"R21(U)"     				},
+	{ 200,           	"R22(L)"     				},
+	{ 204,           	"R22(U)"     				},
+	{ 208,           	"R23(L)"     				},
+	{ 212,           	"R23(U)"     				},
+	{ 216,           	"R24(L)"     				},
+	{ 220,           	"R24(U)"     				},
+	{ 224,           	"R25(L)"     				},
+	{ 228,           	"R25(U)"     				},
+	{ 232,           	"R26(L)"     				},
+	{ 236,           	"R26(U)"     				},
+	{ 240,           	"R27(L)"     				},
+	{ 244,           	"R27(U)"     				},
+	{ 248,           	"R28(L)"     				},
+	{ 252,           	"R28(U)"     				},
+	{ 256,           	"R29(L)"     				},
+	{ 260,           	"R29(U)"     				},
+	{ 264,           	"R30(L)"     				},
+	{ 268,           	"R30(U)"     				},
+	{ 272,           	"R31(L)"     				},
+	{ 276,           	"R31(U)"     				},
+	{ 280,           	"R32(L)"     				},
+	{ 284,           	"R32(U)"     				},
+	{ 288,           	"R33(L)"     				},
+	{ 292,           	"R33(U)"     				},
+	{ 296,           	"R34(L)"     				},
+	{ 300,           	"R34(U)"     				},
+	{ 304,           	"R35(L)"     				},
+	{ 308,           	"R35(U)"     				},
+	{ 312,           	"R36(L)"     				},
+	{ 316,           	"R36(U)"     				},
+	{ 320,           	"R37(L)"     				},
+	{ 324,           	"R37(U)"     				},
+	{ 328,           	"R38(L)"     				},
+	{ 332,           	"R38(U)"     				},
+	{ 336,           	"R39(L)"     				},
+	{ 340,           	"R39(U)"     				},
+	{ 344,           	"R40(L)"     				},
+	{ 348,           	"R40(U)"     				},
+	{ 352,           	"R41(L)"     				},
+	{ 356,           	"R41(U)"     				},
+	{ 360,           	"R42(L)"     				},
+	{ 364,           	"R42(U)"     				},
+	{ 368,           	"R43(L)"     				},
+	{ 372,           	"R43(U)"     				},
+	{ 376,           	"R44(L)"     				},
+	{ 380,           	"R44(U)"     				},
+	{ 384,           	"R45(L)"     				},
+	{ 388,           	"R45(U)"     				},
+	{ 392,           	"R46(L)"     				},
+	{ 396,           	"R46(U)"     				},
+	{ 400,           	"R47(L)"     				},
+	{ 404,           	"R47(U)"     				},
+	{ 408,           	"R48(L)"     				},
+	{ 412,           	"R48(U)"     				},
+	{ 416,           	"R49(L)"     				},
+	{ 420,           	"R49(U)"     				},
+	{ 424,           	"R50(L)"     				},
+	{ 428,           	"R50(U)"     				},
+	{ 432,           	"R51(L)"     				},
+	{ 436,           	"R51(U)"     				},
+	{ 440,           	"R52(L)"     				},
+	{ 444,           	"R52(U)"     				},
+	{ 448,           	"R53(L)"     				},
+	{ 452,           	"R53(U)"     				},
+	{ 456,           	"R54(L)"     				},
+	{ 460,           	"R54(U)"     				},
+	{ 464,           	"R55(L)"     				},
+	{ 468,           	"R55(U)"     				},
+	{ 472,           	"R56(L)"     				},
+	{ 476,           	"R56(U)"     				},
+	{ 480,           	"R57(L)"     				},
+	{ 484,           	"R57(U)"     				},
+	{ 488,           	"R58(L)"     				},
+	{ 492,           	"R58(U)"     				},
+	{ 496,           	"R59(L)"     				},
+	{ 500,           	"R59(U)"     				},
+	{ 504,           	"R60(L)"     				},
+	{ 508,           	"R60(U)"     				},
+	{ 512,           	"R61(L)"     				},
+	{ 516,           	"R61(U)"     				},
+	{ 520,           	"R62(L)"     				},
+	{ 524,           	"R62(U)"     				},
+	{ 528,                  "TR0(L)"                                },
+	{ 532,                  "TR0(U)"                                },
+	{ 536,                  "TR1(L)"                                },
+	{ 540,                  "TR1(U)"                                },
+	{ 544,                  "TR2(L)"                                },
+	{ 548,                  "TR2(U)"                                },
+	{ 552,                  "TR3(L)"                                },
+	{ 556,                  "TR3(U)"                                },
+	{ 560,                  "TR4(L)"                                },
+	{ 564,                  "TR4(U)"                                },
+	{ 568,                  "TR5(L)"                                },
+	{ 572,                  "TR5(U)"                                },
+	{ 576,                  "TR6(L)"                                },
+	{ 580,                  "TR6(U)"                                },
+	{ 584,                  "TR7(L)"                                },
+	{ 588,                  "TR7(U)"                                },
+        /* This entry is in case pt_regs contains dregs (depends on
+           the kernel build options). */
+	{ uoff(regs),	        "offsetof(struct user, regs)"	        },
+	{ uoff(fpu),	        "offsetof(struct user, fpu)"	        },
+#endif
 
 #if !defined(S390) && !defined(S390X) && !defined(MIPS)
 	{ uoff(u_fpvalid),	"offsetof(struct user, u_fpvalid)"	},
@@ -2480,9 +2641,12 @@
 	{ uoff(u_dsize),	"offsetof(struct user, u_dsize)"	},
 	{ uoff(u_ssize),	"offsetof(struct user, u_ssize)"	},
 	{ uoff(start_code),	"offsetof(struct user, start_code)"	},
+#ifdef SHMEDIA
+	{ uoff(start_data),	"offsetof(struct user, start_data)"	},
+#endif
 	{ uoff(start_stack),	"offsetof(struct user, start_stack)"	},
 	{ uoff(signal),		"offsetof(struct user, signal)"		},
-#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
+#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SHMEDIA)
 	{ uoff(reserved),	"offsetof(struct user, reserved)"	},
 #endif
 	{ uoff(u_ar0),		"offsetof(struct user, u_ar0)"		},
diff --git a/sock.c b/sock.c
index aa0bf88..285a69a 100644
--- a/sock.c
+++ b/sock.c
@@ -35,7 +35,7 @@
 #include <sys/sockio.h>
 #endif
 
-#if defined (ALPHA) || defined(SH)
+#if defined (ALPHA) || defined(SH) || defined(SHMEDIA)
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #elif defined(HAVE_IOCTLS_H)
diff --git a/syscall.c b/syscall.c
index a1c3734..f06e172 100644
--- a/syscall.c
+++ b/syscall.c
@@ -713,6 +713,8 @@
 	static long r28;
 #elif defined(SH)
        static long r0;
+#elif defined(SHMEDIA)
+       static long r9;	
 #elif defined(X86_64)
        static long rax;
 #endif
@@ -1093,15 +1095,32 @@
                        return 0;
                }
        }
-#endif /* SH */
+#elif defined(SHMEDIA)
+	if (upeek(pid, REG_SYSCALL, &scno) < 0)
+		return -1;
+        scno &= 0xFFFF;
+
+	if (!(tcp->flags & TCB_INSYSCALL)) {
+		/* Check if we return from execve. */
+		if (tcp->flags & TCB_WAITEXECVE) {
+			tcp->flags &= ~TCB_WAITEXECVE;
+			return 0;
+		}
+	}
+#endif /* SHMEDIA */
 #endif /* LINUX */
 #ifdef SUNOS4
 	if (upeek(pid, uoff(u_arg[7]), &scno) < 0)
 		return -1;
 #elif defined(SH)
-       /* new syscall ABI returns result in R0 */
-       if (upeek(pid, 4*REG_REG0, (long *)&r0) < 0)
-               return -1;
+        /* new syscall ABI returns result in R0 */
+        if (upeek(pid, 4*REG_REG0, (long *)&r0) < 0)
+                return -1;
+#elif defined(SHMEDIA)
+        /* ABI defines result returned in r9 */
+        if (upeek(pid, REG_GENERAL(9), (long *)&r9) < 0)
+                return -1;
+
 #endif
 #ifdef USE_PROCFS
 #ifdef HAVE_PR_SYSCALL
@@ -1416,6 +1435,18 @@
                        tcp->u_rval = r0;
                        u_error = 0;
                }
+#else
+#ifdef SHMEDIA
+                /* interpret result as return value or error number */
+                if (r9 && (unsigned) -r9 < nerrnos) {
+	                tcp->u_rval = -1;
+	                u_error = -r9;
+                }
+                else {
+                        tcp->u_rval = r9;
+	                u_error = 0;
+                }
+#endif /* SHMEDIA */
 #endif /* SH */
 #endif /* HPPA */
 #endif /* SPARC */
@@ -1622,6 +1653,12 @@
 	r0 = error ? -error : rval;
 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
 		return -1;
+#else
+#ifdef SHMEDIA
+        r9 = error ? -error : rval;
+	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
+		return -1;
+#endif /* SHMEDIA */
 #endif /* SH */
 #endif /* HPPA */
 #endif /* SPARC */
@@ -1841,6 +1878,28 @@
                                return -1;
                }
         }
+#elif defined(SHMEDIA)
+	{
+		int i;
+                /* Registers used by SH5 Linux system calls for parameters */
+		static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
+
+		/*
+		 * TODO: should also check that the number of arguments encoded
+		 *       in the trap number matches the number strace expects.
+		 */
+		/*
+		    assert(sysent[tcp->scno].nargs <
+		    	sizeof(syscall_regs)/sizeof(syscall_regs[0]));
+		 */
+
+		tcp->u_nargs = sysent[tcp->scno].nargs;
+		for (i = 0; i < tcp->u_nargs; i++) {
+			if (upeek(pid, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
+				return -1;
+		}
+	}
+
 #elif defined(X86_64)
 	{
 		int i;
diff --git a/util.c b/util.c
index a3cde44..a1e8cc6 100644
--- a/util.c
+++ b/util.c
@@ -974,6 +974,9 @@
 #elif defined(SH)
        if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0)
                return -1;
+#elif defined(SHMEDIA)
+       if (upeek(tcp->pid, REG_PC ,&pc) < 0)
+               return -1;
 #endif
 	return pc;
 #endif /* LINUX */
@@ -1089,6 +1092,15 @@
                return;
        }
        tprintf("[%08lx] ", pc);
+#elif defined(SHMEDIA)
+	long pc;
+
+	if (upeek(tcp->pid, REG_PC, &pc) < 0) {
+		tprintf ("[????????] ");
+		return;
+	}
+	tprintf("[%08lx] ", pc);
+
 #endif /* !architecture */
 #endif /* LINUX */
 
@@ -1226,6 +1238,11 @@
 # elif defined (SH)
 #  define arg0_offset	(4*(REG_REG0+4))
 #  define arg1_offset	(4*(REG_REG0+5))
+# elif defined (SHMEDIA)
+   /* ABI defines arg0 & 1 in r2 & r3 */
+#  define arg0_offset   (REG_OFFSET+16)
+#  define arg1_offset   (REG_OFFSET+24)
+#  define restore_arg0(tcp, state, val) 0
 # else
 #  define arg0_offset	0
 #  define arg1_offset	4