diff options
author | Roland McGrath <roland@redhat.com> | 2003-06-02 19:18:58 +0000 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2003-06-02 19:18:58 +0000 |
commit | e1e584b8fa0d97caad461f82a5427cd37d6327f3 (patch) | |
tree | a7e62671f7c4e01ad6f27c98acfb0efa132bac2a | |
parent | d0835361d61de0051771a5c1ae60ddc2c7c5152d (diff) | |
download | strace-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.ac | 4 | ||||
-rw-r--r-- | defs.h | 18 | ||||
-rw-r--r-- | mem.c | 16 | ||||
-rw-r--r-- | process.c | 166 | ||||
-rw-r--r-- | sock.c | 2 | ||||
-rw-r--r-- | syscall.c | 67 | ||||
-rw-r--r-- | util.c | 17 |
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.]) @@ -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 */ @@ -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 */ @@ -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)" }, @@ -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) @@ -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; @@ -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 |