summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2003-06-02 19:18:58 +0000
committerRoland McGrath <roland@redhat.com>2003-06-02 19:18:58 +0000
commite1e584b8fa0d97caad461f82a5427cd37d6327f3 (patch)
treea7e62671f7c4e01ad6f27c98acfb0efa132bac2a
parentd0835361d61de0051771a5c1ae60ddc2c7c5152d (diff)
downloadstrace-e1e584b8fa0d97caad461f82a5427cd37d6327f3.tar.gz
strace-e1e584b8fa0d97caad461f82a5427cd37d6327f3.tar.bz2
strace-e1e584b8fa0d97caad461f82a5427cd37d6327f3.tar.xz
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>.
-rw-r--r--configure.ac4
-rw-r--r--defs.h18
-rw-r--r--mem.c16
-rw-r--r--process.c166
-rw-r--r--sock.c2
-rw-r--r--syscall.c67
-rw-r--r--util.c17
7 files changed, 282 insertions, 8 deletions
diff --git a/configure.ac b/configure.ac
index 28fbeed..4aa93c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,6 +91,10 @@ sh)
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 @@ extern int ptrace();
# 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 @@ 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) || 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 @@ struct tcb *tcp;
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 @@ int
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 @@ int new;
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 @@ struct xlat struct_user_offsets[] = {
{ 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 @@ struct xlat struct_user_offsets[] = {
{ 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 @@ struct tcb *tcp;
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 @@ struct tcb *tcp;
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 @@ struct tcb *tcp;
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 @@ force_result(tcp, error, rval)
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 @@ struct tcb *tcp;
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 @@ struct tcb *tcp;
#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 @@ struct tcb *tcp;
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 @@ typedef struct regs arg_setup_state;
# 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