Merge patch from Greg Banks for Linux/SuperH support
diff --git a/CREDITS b/CREDITS
index 7e16aa8..c6070d8 100644
--- a/CREDITS
+++ b/CREDITS
@@ -43,3 +43,4 @@
Gaël Roualland <gael.roualland@iname.com>
Richard Hirst <rhirst@linuxcare.com>
Ganesan Rajagopal <rganesan@myrealbox.com>
+ Greg Banks <gbanks@pocketpenguins.com>
diff --git a/ChangeLog b/ChangeLog
index 64f5ef8..61a9faa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2002-05-01 Wichert Akkerman <wichert@deephackmode.org>
+
+ * configure.in, defs.h, process.c, sock.c, syscall.c, util.c: merge
+ patch from Greg Banks <gbanks@pocketpenguins.com> for Linux/SuperH
+ support
+
2002-04-01 Wichert Akkerman <wichert@deephackmode.org>
* strace.c: close tcp->outf in droptcb()
diff --git a/configure.in b/configure.in
index b24a868..ca016ee 100644
--- a/configure.in
+++ b/configure.in
@@ -68,6 +68,9 @@
hppa*|parisc*)
arch=hppa
;;
+sh)
+ arch=sh
+ ;;
*)
AC_MSG_ERROR(this architecture is not yet supported by strace)
;;
@@ -76,7 +79,7 @@
# Autoheader trick. Heh, heh.
arch_list='
-@@@syms="$syms I386 IA64 M68K SPARC MIPS ALPHA ARM POWERPC S390 HPPA"@@@
+@@@syms="$syms I386 IA64 M68K SPARC MIPS ALPHA ARM POWERPC S390 HPPA SH"@@@
'
osarch="$opsys"
diff --git a/defs.h b/defs.h
index 3a2142d..e6b3539 100644
--- a/defs.h
+++ b/defs.h
@@ -289,7 +289,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)
+# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
# define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */
# endif
#endif /* LINUX */
diff --git a/process.c b/process.c
index a160982..afc8f4b 100644
--- a/process.c
+++ b/process.c
@@ -6,6 +6,9 @@
* Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Linux for s390 port by D.J. Barrow
* <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
+ * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
+ * port by Greg Banks <gbanks@pocketpenguins.com>
+
*
* All rights reserved.
*
@@ -530,6 +533,10 @@
if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
return -1;
return 0;
+#elif defined(SH)
+ if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
+ return -1;
+ return 0;
#else
#warning Do not know how to handle change_syscall for this architecture
#endif /* architecture */
@@ -1223,9 +1230,9 @@
}
}
#ifdef LINUX
-#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA)
+#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
tcp->flags |= TCB_WAITEXECVE;
-#endif /* ALPHA || SPARC || POWERPC */
+#endif /* ALPHA || SPARC || POWERPC || IA64 || HPPA || SH */
#endif /* LINUX */
return 0;
}
@@ -1910,6 +1917,58 @@
{ 4*PT_PC, "4*PT_PC" },
#endif /* M68K */
#endif /* !I386 */
+#ifdef SH
+ { 4*REG_REG0, "4*REG_REG0" },
+ { 4*(REG_REG0+1), "4*REG_REG1" },
+ { 4*(REG_REG0+2), "4*REG_REG2" },
+ { 4*(REG_REG0+3), "4*REG_REG3" },
+ { 4*(REG_REG0+4), "4*REG_REG4" },
+ { 4*(REG_REG0+5), "4*REG_REG5" },
+ { 4*(REG_REG0+6), "4*REG_REG6" },
+ { 4*(REG_REG0+7), "4*REG_REG7" },
+ { 4*(REG_REG0+8), "4*REG_REG8" },
+ { 4*(REG_REG0+9), "4*REG_REG9" },
+ { 4*(REG_REG0+10), "4*REG_REG10" },
+ { 4*(REG_REG0+11), "4*REG_REG11" },
+ { 4*(REG_REG0+12), "4*REG_REG12" },
+ { 4*(REG_REG0+13), "4*REG_REG13" },
+ { 4*(REG_REG0+14), "4*REG_REG14" },
+ { 4*REG_REG15, "4*REG_REG15" },
+ { 4*REG_PC, "4*REG_PC" },
+ { 4*REG_PR, "4*REG_PR" },
+ { 4*REG_SR, "4*REG_SR" },
+ { 4*REG_GBR, "4*REG_GBR" },
+ { 4*REG_MACH, "4*REG_MACH" },
+ { 4*REG_MACL, "4*REG_MACL" },
+ { 4*REG_SYSCALL, "4*REG_SYSCALL" },
+ { 4*REG_FPUL, "4*REG_FPUL" },
+ { 4*REG_FPREG0, "4*REG_FPREG0" },
+ { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
+ { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
+ { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
+ { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
+ { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
+ { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
+ { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
+ { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
+ { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
+ { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
+ { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
+ { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
+ { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
+ { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
+ { 4*REG_FPREG15, "4*REG_FPREG15" },
+ { 4*REG_XDREG0, "4*REG_XDREG0" },
+ { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
+ { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
+ { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
+ { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
+ { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
+ { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
+ { 4*REG_XDREG14, "4*REG_XDREG14" },
+ { 4*REG_FPSCR, "4*REG_FPSCR" },
+#endif /* SH */
+
#if !defined(S390) && !defined(MIPS)
{ uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
#endif
@@ -1926,7 +1985,7 @@
{ uoff(start_code), "offsetof(struct user, start_code)" },
{ uoff(start_stack), "offsetof(struct user, start_stack)" },
{ uoff(signal), "offsetof(struct user, signal)" },
-#if !defined(S390) && !defined(MIPS)
+#if !defined(S390) && !defined(MIPS) && !defined(SH)
{ uoff(reserved), "offsetof(struct user, reserved)" },
#endif
{ uoff(u_ar0), "offsetof(struct user, u_ar0)" },
diff --git a/sock.c b/sock.c
index 327a3de..6d494b7 100644
--- a/sock.c
+++ b/sock.c
@@ -35,7 +35,7 @@
#include <sys/sockio.h>
#endif
-#ifdef ALPHA
+#if defined (ALPHA) || defined(SH)
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#elif defined(HAVE_IOCTLS_H)
diff --git a/syscall.c b/syscall.c
index 95c4bad..dfad8f0 100644
--- a/syscall.c
+++ b/syscall.c
@@ -684,6 +684,9 @@
static long pc;
#elif defined(HPPA)
static long r28;
+#elif defined(SH)
+ static long r0;
+
#endif
#endif /* LINUX */
#ifdef FREEBSD
@@ -873,11 +876,44 @@
return 0;
}
}
-#endif
+#elif defined(SH)
+ /*
+ * In the new syscall ABI, the system call number is in R3.
+ */
+ if (upeek(pid, 4*(REG_REG0+3), &scno) < 0)
+ return -1;
+
+ if (scno < 0) {
+ /* Odd as it may seem, a glibc bug has been known to cause
+ glibc to issue bogus negative syscall numbers. So for
+ our purposes, make strace print what it *should* have been */
+ long correct_scno = (scno & 0xff);
+ if (debug)
+ fprintf(stderr,
+ "Detected glibc bug: bogus system call number = %ld,
+correcting to %ld\n",
+ scno,
+ correct_scno);
+ scno = correct_scno;
+ }
+
+
+ if (!(tcp->flags & TCB_INSYSCALL)) {
+ /* Check if we return from execve. */
+ if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
+ tcp->flags &= ~TCB_WAITEXECVE;
+ return 0;
+ }
+ }
+#endif /* SH */
#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;
#endif
#ifdef USE_PROCFS
#ifdef HAVE_PR_SYSCALL
@@ -1152,6 +1188,18 @@
tcp->u_rval = r28;
u_error = 0;
}
+#else
+#ifdef SH
+ /* interpret R0 as return value or error number */
+ if (r0 && (unsigned) -r0 < nerrnos) {
+ tcp->u_rval = -1;
+ u_error = -r0;
+ }
+ else {
+ tcp->u_rval = r0;
+ u_error = 0;
+ }
+#endif /* SH */
#endif /* HPPA */
#endif /* SPARC */
#endif /* ALPHA */
@@ -1378,6 +1426,20 @@
return -1;
}
}
+#elif defined(SH)
+ {
+ int i;
+ static int syscall_regs[] = {
+ REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
+ REG_REG0, REG_REG0+1, REG_REG0+2
+ };
+
+ tcp->u_nargs = sysent[tcp->scno].nargs;
+ for (i = 0; i < tcp->u_nargs; i++) {
+ if (upeek(pid, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
+ return -1;
+ }
+ }
#else /* Other architecture (like i386) (32bits specific) */
{
int i;
diff --git a/util.c b/util.c
index c59d25a..3d4fee3 100644
--- a/util.c
+++ b/util.c
@@ -955,6 +955,9 @@
#elif defined(HPPA)
if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0)
return -1;
+#elif defined(SH)
+ if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0)
+ return -1;
#endif
return pc;
#endif /* LINUX */
@@ -1054,6 +1057,14 @@
return;
}
tprintf("[%08lx] ", pc);
+#elif defined(SH)
+ long pc;
+
+ if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) {
+ tprintf ("[????????] ");
+ return;
+ }
+ tprintf("[%08lx] ", pc);
#endif /* !architecture */
#endif /* LINUX */
@@ -1217,6 +1228,12 @@
#define LOOP 0xa7f40000 /* BRC 15,0 */
#elif defined(HPPA)
#define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */
+#elif defined(SH)
+#ifdef __LITTLE_ENDIAN__
+#define LOOP 0x0000affe
+#else
+#define LOOP 0xfeaf0000
+#endif
#else
#error unknown architecture
#endif
@@ -1247,6 +1264,9 @@
if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0)
return -1;
tcp->baddr &= ~0x03;
+#elif defined(SH)
+ if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0)
+ return -1;
#else
#error unknown architecture
#endif
@@ -1336,6 +1356,8 @@
long pc;
#elif defined(HPPA)
long iaoq;
+#elif defined(SH)
+ long pc;
#endif /* architecture */
#ifdef SPARC
@@ -1493,6 +1515,17 @@
*/
ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
+#elif defined(SH)
+ if (upeek(tcp->pid, 4*REG_PC, &pc) < 0)
+ return -1;
+ if (pc != tcp->baddr) {
+ /* The breakpoint has not been reached yet. */
+ if (debug)
+ fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
+ pc, tcp->baddr);
+ return 0;
+ }
+
#endif /* arch */
#endif /* !SPARC && !IA64 */
#endif /* LINUX */