]> granicus.if.org Git - strace/commitdiff
Merge patch from Greg Banks for Linux/SuperH support
authorWichert Akkerman <wichert@deephackmode.org>
Wed, 1 May 2002 16:39:22 +0000 (16:39 +0000)
committerWichert Akkerman <wichert@deephackmode.org>
Wed, 1 May 2002 16:39:22 +0000 (16:39 +0000)
CREDITS
ChangeLog
configure.in
defs.h
process.c
sock.c
syscall.c
util.c

diff --git a/CREDITS b/CREDITS
index 7e16aa820e548724e898b1998039cc5c64957f24..c6070d81594e9bdb50fcff8fd4ddccf54eaa7e93 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -43,3 +43,4 @@ porting to new systems:
        GaĆ«l Roualland <gael.roualland@iname.com>
        Richard Hirst <rhirst@linuxcare.com>
        Ganesan Rajagopal <rganesan@myrealbox.com>
+       Greg Banks <gbanks@pocketpenguins.com>
index 64f5ef8199ee54d2683046610a70e6612e9dc5c8..61a9faa3826f6d27c706e5c0c76fcbe57327840e 100644 (file)
--- 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()
index b24a868532407a1cd83b7ca5cf4dd714b318420a..ca016ee14792a58d43d4e460daa8f1d5e0b8f8ca 100644 (file)
@@ -68,6 +68,9 @@ s390)
 hppa*|parisc*)
        arch=hppa
        ;;
+sh)
+       arch=sh
+       ;;
 *)
        AC_MSG_ERROR(this architecture is not yet supported by strace)
        ;;
@@ -76,7 +79,7 @@ AC_MSG_RESULT($arch)
 
 # 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 3a2142dfc19f19717f4645252bbfac61dc7b90bf..e6b3539ea26b1ec55d01b90001bd262a3bef16bf 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -289,7 +289,7 @@ struct tcb {
 #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 */
index a1609822c117af42fc747ed556bb9a9d714ab22d..afc8f4b91258f0fcd536db6e7bbac5772018ab92 100644 (file)
--- 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 @@ int new;
        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 @@ struct tcb *tcp;
                }
        }
 #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 @@ struct xlat struct_user_offsets[] = {
        { 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 @@ struct xlat struct_user_offsets[] = {
        { 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 327a3de859e12f78a8885d6549219fab381729a9..6d494b7e3d06ded7901a4f37aaa014fda45ba083 100644 (file)
--- 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)
index 95c4bad1dc723f328fa1f9d1d7a7e6e0b9621cf3..dfad8f040691d3bc693630a7c113266cfd819ddc 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -684,6 +684,9 @@ struct tcb *tcp;
        static long pc;
 #elif defined(HPPA)
        static long r28;
+#elif defined(SH)
+       static long r0;
+
 #endif 
 #endif /* LINUX */
 #ifdef FREEBSD
@@ -873,11 +876,44 @@ struct tcb *tcp;
                        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 @@ struct tcb *tcp;
                        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 @@ struct tcb *tcp;
                                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 c59d25a7e0ded63e239fddb0d6b381bc708999e7..3d4fee305db8c381121f4667196e0a57a3ec0341 100644 (file)
--- a/util.c
+++ b/util.c
@@ -955,6 +955,9 @@ struct tcb *tcp;
 #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 @@ struct tcb *tcp;
                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 @@ struct tcb *tcp;
 #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 @@ struct tcb *tcp;
        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 @@ struct tcb *tcp;
        long pc;
 #elif defined(HPPA)
        long iaoq;
+#elif defined(SH)
+       long pc;
 #endif /* architecture */
 
 #ifdef SPARC
@@ -1493,6 +1515,17 @@ struct tcb *tcp;
         */
        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 */