From: Wichert Akkerman Date: Wed, 1 May 2002 16:39:22 +0000 (+0000) Subject: Merge patch from Greg Banks for Linux/SuperH support X-Git-Tag: v4.5.18~986 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ccef63782c10d9ce9da77ef7530861a3d14b1300;p=strace Merge patch from Greg Banks for Linux/SuperH support --- diff --git a/CREDITS b/CREDITS index 7e16aa82..c6070d81 100644 --- a/CREDITS +++ b/CREDITS @@ -43,3 +43,4 @@ porting to new systems: Gaƫl Roualland Richard Hirst Ganesan Rajagopal + Greg Banks diff --git a/ChangeLog b/ChangeLog index 64f5ef81..61a9faa3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2002-05-01 Wichert Akkerman + + * configure.in, defs.h, process.c, sock.c, syscall.c, util.c: merge + patch from Greg Banks for Linux/SuperH + support + 2002-04-01 Wichert Akkerman * strace.c: close tcp->outf in droptcb() diff --git a/configure.in b/configure.in index b24a8685..ca016ee1 100644 --- a/configure.in +++ b/configure.in @@ -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 3a2142df..e6b3539e 100644 --- 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 */ diff --git a/process.c b/process.c index a1609822..afc8f4b9 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 * + * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH + * port by Greg Banks + * * 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 327a3de8..6d494b7e 100644 --- a/sock.c +++ b/sock.c @@ -35,7 +35,7 @@ #include #endif -#ifdef ALPHA +#if defined (ALPHA) || defined(SH) #ifdef HAVE_SYS_IOCTL_H #include #elif defined(HAVE_IOCTLS_H) diff --git a/syscall.c b/syscall.c index 95c4bad1..dfad8f04 100644 --- 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 c59d25a7..3d4fee30 100644 --- 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 ,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 */