From: Denys Vlasenko Date: Wed, 25 Feb 2009 17:08:40 +0000 (+0000) Subject: CRIS support by Hinko Kocevar (hinko.kocevar AT cetrtapot.si) X-Git-Tag: v4.5.19~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ea0e6e80260d2b1b7ad40282012b0e47869bcddf;p=strace CRIS support by Hinko Kocevar (hinko.kocevar AT cetrtapot.si) * configure.ac: Make it recognize cris. * process.c: Define ARG_xxx constants for cris. (change_syscall): Add support for cris. (struct_user_offsets): Add cris-specific data. * signal.c (sys_sigreturn): Add support for cris. * syscall.c (get_scno): Add support for cris. (syscall_fixup): Add support for cris. (get_error): Add support for cris. (syscall_enter): Add support for cris. (force_result): While at it, fix cpp directives indentation. * util.c (printcall): Add support for cris. --- diff --git a/ChangeLog b/ChangeLog index d833dd59..aa01b186 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2009-02-25 Denys Vlasenko + + CRIS support by Hinko Kocevar (hinko.kocevar AT cetrtapot.si) + * configure.ac: Make it recognize cris. + * process.c: Define ARG_xxx constants for cris. + (change_syscall): Add support for cris. + (struct_user_offsets): Add cris-specific data. + * signal.c (sys_sigreturn): Add support for cris. + * syscall.c (get_scno): Add support for cris. + (syscall_fixup): Add support for cris. + (get_error): Add support for cris. + (syscall_enter): Add support for cris. + (force_result): While at it, fix cpp directives indentation. + * util.c (printcall): Add support for cris. + 2009-02-24 Denys Vlasenko Replace many more bare ptrace calls with calls to wrappers diff --git a/configure.ac b/configure.ac index fb777887..47267c57 100644 --- a/configure.ac +++ b/configure.ac @@ -107,6 +107,14 @@ x86?64*) arch=x86_64 AC_DEFINE([X86_64], 1, [Define for the AMD x86-64 architecture.]) ;; +cris|crisv10) + arch=crisv10 + AC_DEFINE([CRISV10], 1, [Define for the CRISv10 architecture.]) + ;; +crisv32) + arch=crisv32 + AC_DEFINE([CRISV32], 1, [Define for the CRISv32 architecture.]) + ;; *) AC_MSG_RESULT([NO!]) AC_MSG_ERROR([architecture $host_cpu is not supported by strace]) diff --git a/process.c b/process.c index cf538808..4cb21cda 100644 --- a/process.c +++ b/process.c @@ -604,7 +604,7 @@ extern void print_ldt_entry(); # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2) # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3) # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4) -# elif defined S390 || defined S390X +# elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32 # define ARG_STACK 0 # define ARG_FLAGS 1 # define ARG_PTID 2 @@ -765,6 +765,10 @@ change_syscall(struct tcb *tcp, int new) 0x100000 | new) < 0) return -1; return 0; +#elif defined(CRISV10) || defined(CRISV32) + if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0) + return -1; + return 0; #elif defined(ARM) /* Some kernels support this, some (pre-2.6.16 or so) don't. */ # ifndef PTRACE_SET_SYSCALL @@ -3059,8 +3063,79 @@ const struct xlat struct_user_offsets[] = { { 69, "fpcsr" }, { 70, "fpeir" }, # endif +# ifdef CRISV10 + { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" }, + { 4*PT_ORIG_R10, "4*PT_ORIG_R10" }, + { 4*PT_R13, "4*PT_R13" }, + { 4*PT_R12, "4*PT_R12" }, + { 4*PT_R11, "4*PT_R11" }, + { 4*PT_R10, "4*PT_R10" }, + { 4*PT_R9, "4*PT_R9" }, + { 4*PT_R8, "4*PT_R8" }, + { 4*PT_R7, "4*PT_R7" }, + { 4*PT_R6, "4*PT_R6" }, + { 4*PT_R5, "4*PT_R5" }, + { 4*PT_R4, "4*PT_R4" }, + { 4*PT_R3, "4*PT_R3" }, + { 4*PT_R2, "4*PT_R2" }, + { 4*PT_R1, "4*PT_R1" }, + { 4*PT_R0, "4*PT_R0" }, + { 4*PT_MOF, "4*PT_MOF" }, + { 4*PT_DCCR, "4*PT_DCCR" }, + { 4*PT_SRP, "4*PT_SRP" }, + { 4*PT_IRP, "4*PT_IRP" }, + { 4*PT_CSRINSTR, "4*PT_CSRINSTR" }, + { 4*PT_CSRADDR, "4*PT_CSRADDR" }, + { 4*PT_CSRDATA, "4*PT_CSRDATA" }, + { 4*PT_USP, "4*PT_USP" }, +# endif +# ifdef CRISV32 + { 4*PT_ORIG_R10, "4*PT_ORIG_R10" }, + { 4*PT_R0, "4*PT_R0" }, + { 4*PT_R1, "4*PT_R1" }, + { 4*PT_R2, "4*PT_R2" }, + { 4*PT_R3, "4*PT_R3" }, + { 4*PT_R4, "4*PT_R4" }, + { 4*PT_R5, "4*PT_R5" }, + { 4*PT_R6, "4*PT_R6" }, + { 4*PT_R7, "4*PT_R7" }, + { 4*PT_R8, "4*PT_R8" }, + { 4*PT_R9, "4*PT_R9" }, + { 4*PT_R10, "4*PT_R10" }, + { 4*PT_R11, "4*PT_R11" }, + { 4*PT_R12, "4*PT_R12" }, + { 4*PT_R13, "4*PT_R13" }, + { 4*PT_ACR, "4*PT_ACR" }, + { 4*PT_SRS, "4*PT_SRS" }, + { 4*PT_MOF, "4*PT_MOF" }, + { 4*PT_SPC, "4*PT_SPC" }, + { 4*PT_CCS, "4*PT_CCS" }, + { 4*PT_SRP, "4*PT_SRP" }, + { 4*PT_ERP, "4*PT_ERP" }, + { 4*PT_EXS, "4*PT_EXS" }, + { 4*PT_EDA, "4*PT_EDA" }, + { 4*PT_USP, "4*PT_USP" }, + { 4*PT_PPC, "4*PT_PPC" }, + { 4*PT_BP_CTRL, "4*PT_BP_CTRL" }, + { 4*PT_BP+4, "4*PT_BP+4" }, + { 4*PT_BP+8, "4*PT_BP+8" }, + { 4*PT_BP+12, "4*PT_BP+12" }, + { 4*PT_BP+16, "4*PT_BP+16" }, + { 4*PT_BP+20, "4*PT_BP+20" }, + { 4*PT_BP+24, "4*PT_BP+24" }, + { 4*PT_BP+28, "4*PT_BP+28" }, + { 4*PT_BP+32, "4*PT_BP+32" }, + { 4*PT_BP+36, "4*PT_BP+36" }, + { 4*PT_BP+40, "4*PT_BP+40" }, + { 4*PT_BP+44, "4*PT_BP+44" }, + { 4*PT_BP+48, "4*PT_BP+48" }, + { 4*PT_BP+52, "4*PT_BP+52" }, + { 4*PT_BP+56, "4*PT_BP+56" }, +# endif -# if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) && !defined(ALPHA) && !defined(IA64) +# if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \ + && !defined(ALPHA) && !defined(IA64) \ + && !defined(CRISV10) && !defined(CRISV32) # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN) { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" }, # endif @@ -3097,7 +3172,7 @@ const struct xlat struct_user_offsets[] = { # if defined(I386) || defined(X86_64) { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" }, # endif -# endif /* !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) && !defined(ALPHA) && !defined(IA64) */ +# endif /* !defined(many arches) */ # endif /* LINUX */ diff --git a/signal.c b/signal.c index 179b7f4b..242a0f33 100644 --- a/signal.c +++ b/signal.c @@ -1232,10 +1232,9 @@ struct tcb *tcp; #ifdef LINUX int -sys_sigreturn(tcp) -struct tcb *tcp; +sys_sigreturn(struct tcb *tcp) { -#ifdef ARM +#if defined(ARM) struct pt_regs regs; struct sigcontext_struct sc; @@ -1280,8 +1279,7 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; -#else -#ifdef I386 +#elif defined(I386) long esp; struct sigcontext_struct sc; @@ -1304,8 +1302,7 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; -#else /* !I386 */ -#ifdef IA64 +#elif defined(IA64) struct sigcontext sc; long sp; @@ -1331,8 +1328,7 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; -#else /* !IA64 */ -#ifdef POWERPC +#elif defined(POWERPC) long esp; struct sigcontext_struct sc; @@ -1355,8 +1351,7 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; -#else /* !POWERPC */ -#ifdef M68K +#elif defined(M68K) long usp; struct sigcontext sc; @@ -1379,8 +1374,7 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; -#else /* !M68K */ -#ifdef ALPHA +#elif defined(ALPHA) long fp; struct sigcontext_struct sc; @@ -1403,8 +1397,7 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; -#else -#if defined (SPARC) || defined (SPARC64) +#elif defined (SPARC) || defined (SPARC64) long i1; struct regs regs; m_siginfo_t si; @@ -1431,8 +1424,7 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; -#else -#if defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64) +#elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64) /* This decodes rt_sigreturn. The 64-bit ABIs do not have sigreturn. */ long sp; @@ -1458,8 +1450,7 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; -#else -#ifdef MIPS +#elif defined(MIPS) long sp; struct pt_regs regs; m_siginfo_t si; @@ -1484,19 +1475,38 @@ struct tcb *tcp; return RVAL_NONE | RVAL_STR; } return 0; +#elif defined(CRISV10) || defined(CRISV32) + struct sigcontext sc; + + if (entering(tcp)) { + long regs[PT_MAX+1]; + + tcp->u_arg[0] = 0; + + if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long)regs) < 0) { + perror("sigreturn: PTRACE_GETREGS"); + return 0; + } + if (umove(tcp, regs[PT_USP], &sc) < 0) + return 0; + tcp->u_arg[0] = 1; + tcp->u_arg[1] = sc.oldmask; + } else { + sigset_t sigm; + long_to_sigset(tcp->u_arg[1], &sigm); + tcp->u_rval = tcp->u_error = 0; + + if (tcp->u_arg[0] == 0) + return 0; + tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); + return RVAL_NONE | RVAL_STR; + } + return 0; #else #warning No sys_sigreturn() for this architecture #warning (no problem, just a reminder :-) return 0; -#endif /* MIPS */ -#endif /* LINUX_MIPSN32 || LINUX_MIPSN64 */ -#endif /* SPARC || SPARC64 */ -#endif /* ALPHA */ -#endif /* !M68K */ -#endif /* !POWERPC */ -#endif /* !IA64 */ -#endif /* !I386 */ -#endif /* S390 */ +#endif } int diff --git a/syscall.c b/syscall.c index 9722519f..128622de 100644 --- a/syscall.c +++ b/syscall.c @@ -774,6 +774,8 @@ internal_syscall(struct tcb *tcp) static long r9; #elif defined(X86_64) static long rax; +#elif defined(CRISV10) || defined(CRISV32) + static long r10; #endif #endif /* LINUX */ #ifdef FREEBSD @@ -786,7 +788,7 @@ get_scno(struct tcb *tcp) long scno = 0; #ifdef LINUX -#if defined(S390) || defined(S390X) +# if defined(S390) || defined(S390X) if (tcp->flags & TCB_WAITEXECVE) { /* * When the execve system call completes successfully, the @@ -874,11 +876,11 @@ get_scno(struct tcb *tcp) scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0); if (errno) return -1; -#if defined(S390X) +# if defined(S390X) scno >>= 48; -#else +# else scno >>= 16; -#endif +# endif tmp = 0; offset_reg = (opcode & 0x00f00000) >> 20; if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) @@ -887,7 +889,7 @@ get_scno(struct tcb *tcp) scno = (scno | tmp) & 0xff; } } -#elif defined (POWERPC) +# elif defined (POWERPC) if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0) return -1; if (!(tcp->flags & TCB_INSYSCALL)) { @@ -897,16 +899,16 @@ get_scno(struct tcb *tcp) return 0; } } -#elif defined(BFIN) +# elif defined(BFIN) if (upeek(tcp, PT_ORIG_P0, &scno)) return -1; /* Check if we return from execve. */ if (tcp->flags & TCB_WAITEXECVE && tcp->flags & TCB_INSYSCALL) tcp->flags &= ~(TCB_INSYSCALL | TCB_WAITEXECVE); -#elif defined (I386) +# elif defined (I386) if (upeek(tcp, 4*ORIG_EAX, &scno) < 0) return -1; -#elif defined (X86_64) +# elif defined (X86_64) if (upeek(tcp, 8*ORIG_RAX, &scno) < 0) return -1; @@ -933,7 +935,7 @@ get_scno(struct tcb *tcp) currpers = current_personality; break; } -#if 0 +# if 0 /* This version analyzes the opcode of a syscall instruction. * (int 0x80 on i386 vs. syscall on x86-64) * It works, but is too complicated. @@ -964,7 +966,7 @@ get_scno(struct tcb *tcp) "PID=%d\n", (int)call, pid); break; } -#endif +# endif if (currpers != current_personality) { static const char *const names[] = {"64 bit", "32 bit"}; set_personality(currpers); @@ -972,7 +974,7 @@ get_scno(struct tcb *tcp) pid, names[current_personality]); } } -#elif defined(IA64) +# elif defined(IA64) # define IA64_PSR_IS ((long)1 << 34) if (upeek(tcp, PT_CR_IPSR, &psr) >= 0) ia32 = (psr & IA64_PSR_IS) != 0; @@ -986,7 +988,7 @@ get_scno(struct tcb *tcp) } /* Check if we return from execve. */ if (tcp->flags & TCB_WAITEXECVE) { -#if defined PTRACE_GETSIGINFO +# if defined PTRACE_GETSIGINFO siginfo_t si; tcp->flags &= ~TCB_WAITEXECVE; @@ -1005,10 +1007,10 @@ get_scno(struct tcb *tcp) ptrace(PTRACE_GETSIGINFO, tcp->pid, (void*) 0, (void*) &si); if (si.si_code == SI_USER) return 0; -#else +# else tcp->flags &= ~TCB_WAITEXECVE; return 0; -#endif +# endif } } else { /* syscall in progress */ @@ -1017,7 +1019,7 @@ get_scno(struct tcb *tcp) if (upeek(tcp, PT_R10, &r10) < 0) return -1; } -#elif defined (ARM) +# elif defined (ARM) /* * Read complete register set in one go. */ @@ -1097,10 +1099,10 @@ get_scno(struct tcb *tcp) tcp->flags |= TCB_INSYSCALL; } } -#elif defined (M68K) +# elif defined (M68K) if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0) return -1; -#elif defined (LINUX_MIPSN32) +# elif defined (LINUX_MIPSN32) unsigned long long regs[38]; if (do_ptrace(PTRACE_GETREGS, tcp, NULL, (long) ®s) < 0) @@ -1125,7 +1127,7 @@ get_scno(struct tcb *tcp) } } } -#elif defined (MIPS) +# elif defined (MIPS) if (upeek(tcp, REG_A3, &a3) < 0) return -1; if(!(tcp->flags & TCB_INSYSCALL)) { @@ -1149,7 +1151,7 @@ get_scno(struct tcb *tcp) if (upeek(tcp, REG_V0, &r2) < 0) return -1; } -#elif defined (ALPHA) +# elif defined (ALPHA) if (upeek(tcp, REG_A3, &a3) < 0) return -1; @@ -1179,7 +1181,7 @@ get_scno(struct tcb *tcp) if (upeek(tcp, REG_R0, &r0) < 0) return -1; } -#elif defined (SPARC) || defined (SPARC64) +# elif defined (SPARC) || defined (SPARC64) /* Everything we need is in the current register set. */ if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) return -1; @@ -1189,9 +1191,9 @@ get_scno(struct tcb *tcp) /* Retrieve the syscall trap instruction. */ errno = 0; trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.r_pc, 0); -#if defined(SPARC64) +# if defined(SPARC64) trap >>= 32; -#endif +# endif if (errno) return -1; @@ -1227,11 +1229,11 @@ get_scno(struct tcb *tcp) tcp->flags &= ~TCB_WAITEXECVE; return 0; } -#if defined (SPARC64) +# if defined (SPARC64) fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.r_tpc); -#else +# else fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc); -#endif +# endif return -1; } @@ -1245,7 +1247,7 @@ get_scno(struct tcb *tcp) memmove (®s.r_o0, ®s.r_o1, 7*sizeof(regs.r_o0)); } } -#elif defined(HPPA) +# elif defined(HPPA) if (upeek(tcp, PT_GR20, &scno) < 0) return -1; if (!(tcp->flags & TCB_INSYSCALL)) { @@ -1255,7 +1257,7 @@ get_scno(struct tcb *tcp) return 0; } } -#elif defined(SH) +# elif defined(SH) /* * In the new syscall ABI, the system call number is in R3. */ @@ -1283,7 +1285,7 @@ get_scno(struct tcb *tcp) return 0; } } -#elif defined(SH64) +# elif defined(SH64) if (upeek(tcp, REG_SYSCALL, &scno) < 0) return -1; scno &= 0xFFFF; @@ -1295,8 +1297,12 @@ get_scno(struct tcb *tcp) return 0; } } -#endif /* SH64 */ +# elif defined(CRISV10) || defined(CRISV32) + if (upeek(tcp, 4*PT_R9, &scno) < 0) + return -1; +# endif #endif /* LINUX */ + #ifdef SUNOS4 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0) return -1; @@ -1308,15 +1314,15 @@ get_scno(struct tcb *tcp) /* ABI defines result returned in r9 */ if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0) return -1; - #endif + #ifdef USE_PROCFS -#ifdef HAVE_PR_SYSCALL +# ifdef HAVE_PR_SYSCALL scno = tcp->status.PR_SYSCALL; -#else /* !HAVE_PR_SYSCALL */ -#ifndef FREEBSD +# else +# ifndef FREEBSD scno = tcp->status.PR_WHAT; -#else /* FREEBSD */ +# else if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { perror("pread"); return -1; @@ -1330,9 +1336,10 @@ get_scno(struct tcb *tcp) scno = regs.r_eax; break; } -#endif /* FREEBSD */ -#endif /* !HAVE_PR_SYSCALL */ +# endif /* FREEBSD */ +# endif /* !HAVE_PR_SYSCALL */ #endif /* USE_PROCFS */ + if (!(tcp->flags & TCB_INSYSCALL)) tcp->scno = scno; return 1; @@ -1359,8 +1366,7 @@ struct tcb *tcp; * ("????" etc) and bail out. */ static int -syscall_fixup(tcp) -struct tcb *tcp; +syscall_fixup(struct tcb *tcp) { #ifdef USE_PROCFS int scno = known_scno(tcp); @@ -1498,6 +1504,14 @@ struct tcb *tcp; fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8); return 0; } +#elif defined(CRISV10) || defined(CRISV32) + if (upeek(tcp->pid, 4*PT_R10, &r10) < 0) + return -1; + if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) { + if (debug) + fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10); + return 0; + } #endif #endif /* LINUX */ return 1; @@ -1521,12 +1535,11 @@ is_negated_errno(unsigned long int val) #endif static int -get_error(tcp) -struct tcb *tcp; +get_error(struct tcb *tcp) { int u_error = 0; #ifdef LINUX -#if defined(S390) || defined(S390X) +# if defined(S390) || defined(S390X) if (is_negated_errno(gpr2)) { tcp->u_rval = -1; u_error = -gpr2; @@ -1535,8 +1548,7 @@ struct tcb *tcp; tcp->u_rval = gpr2; u_error = 0; } -#else /* !S390 && !S390X */ -#ifdef I386 +# elif defined(I386) if (is_negated_errno(eax)) { tcp->u_rval = -1; u_error = -eax; @@ -1545,8 +1557,7 @@ struct tcb *tcp; tcp->u_rval = eax; u_error = 0; } -#else /* !I386 */ -#ifdef X86_64 +# elif defined(X86_64) if (is_negated_errno(rax)) { tcp->u_rval = -1; u_error = -rax; @@ -1555,8 +1566,7 @@ struct tcb *tcp; tcp->u_rval = rax; u_error = 0; } -#else -#ifdef IA64 +# elif defined(IA64) if (ia32) { int err; @@ -1578,8 +1588,7 @@ struct tcb *tcp; u_error = 0; } } -#else /* !IA64 */ -#ifdef MIPS +# elif defined(MIPS) if (a3) { tcp->u_rval = -1; u_error = r2; @@ -1587,8 +1596,7 @@ struct tcb *tcp; tcp->u_rval = r2; u_error = 0; } -#else -#ifdef POWERPC +# elif defined(POWERPC) if (is_negated_errno(result)) { tcp->u_rval = -1; u_error = -result; @@ -1597,8 +1605,7 @@ struct tcb *tcp; tcp->u_rval = result; u_error = 0; } -#else /* !POWERPC */ -#ifdef M68K +# elif defined(M68K) if (is_negated_errno(d0)) { tcp->u_rval = -1; u_error = -d0; @@ -1607,8 +1614,7 @@ struct tcb *tcp; tcp->u_rval = d0; u_error = 0; } -#else /* !M68K */ -#ifdef ARM +# elif defined(ARM) if (is_negated_errno(regs.ARM_r0)) { tcp->u_rval = -1; u_error = -regs.ARM_r0; @@ -1617,8 +1623,7 @@ struct tcb *tcp; tcp->u_rval = regs.ARM_r0; u_error = 0; } -#else /* !ARM */ -#ifdef BFIN +# elif defined(BFIN) if (is_negated_errno(r0)) { tcp->u_rval = -1; u_error = -r0; @@ -1626,8 +1631,7 @@ struct tcb *tcp; tcp->u_rval = r0; u_error = 0; } -#else /* !BFIN */ -#ifdef ALPHA +# elif defined(ALPHA) if (a3) { tcp->u_rval = -1; u_error = r0; @@ -1636,8 +1640,7 @@ struct tcb *tcp; tcp->u_rval = r0; u_error = 0; } -#else /* !ALPHA */ -#ifdef SPARC +# elif defined(SPARC) if (regs.r_psr & PSR_C) { tcp->u_rval = -1; u_error = regs.r_o0; @@ -1646,8 +1649,7 @@ struct tcb *tcp; tcp->u_rval = regs.r_o0; u_error = 0; } -#else /* !SPARC */ -#ifdef SPARC64 +# elif defined(SPARC64) if (regs.r_tstate & 0x1100000000UL) { tcp->u_rval = -1; u_error = regs.r_o0; @@ -1656,8 +1658,7 @@ struct tcb *tcp; tcp->u_rval = regs.r_o0; u_error = 0; } -#else /* !SPARC64 */ -#ifdef HPPA +# elif defined(HPPA) if (is_negated_errno(r28)) { tcp->u_rval = -1; u_error = -r28; @@ -1666,8 +1667,7 @@ struct tcb *tcp; tcp->u_rval = r28; u_error = 0; } -#else -#ifdef SH +# elif defined(SH) /* interpret R0 as return value or error number */ if (is_negated_errno(r0)) { tcp->u_rval = -1; @@ -1677,8 +1677,7 @@ struct tcb *tcp; tcp->u_rval = r0; u_error = 0; } -#else -#ifdef SH64 +# elif defined(SH64) /* interpret result as return value or error number */ if (is_negated_errno(r9)) { tcp->u_rval = -1; @@ -1688,21 +1687,16 @@ struct tcb *tcp; tcp->u_rval = r9; u_error = 0; } -#endif /* SH64 */ -#endif /* SH */ -#endif /* HPPA */ -#endif /* SPARC */ -#endif /* SPARC64 */ -#endif /* ALPHA */ -#endif /* BFIN */ -#endif /* ARM */ -#endif /* M68K */ -#endif /* POWERPC */ -#endif /* MIPS */ -#endif /* IA64 */ -#endif /* X86_64 */ -#endif /* I386 */ -#endif /* S390 || S390X */ +# elif defined(CRISV10) || defined(CRISV32) + if (r10 && (unsigned) -r10 < nerrnos) { + tcp->u_rval = -1; + u_error = -r10; + } + else { + tcp->u_rval = r10; + u_error = 0; + } +# endif #endif /* LINUX */ #ifdef SUNOS4 /* get error code from user struct */ @@ -1786,22 +1780,19 @@ force_result(tcp, error, rval) long rval; { #ifdef LINUX -#if defined(S390) || defined(S390X) +# if defined(S390) || defined(S390X) gpr2 = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0) return -1; -#else /* !S390 && !S390X */ -#ifdef I386 +# elif defined(I386) eax = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0) return -1; -#else /* !I386 */ -#ifdef X86_64 +# elif defined(X86_64) rax = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0) return -1; -#else -#ifdef IA64 +# elif defined(IA64) if (ia32) { r8 = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0) @@ -1820,13 +1811,11 @@ force_result(tcp, error, rval) ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0) return -1; } -#else /* !IA64 */ -#ifdef BFIN +# elif defined(BFIN) r0 = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0) return -1; -#else /* !BFIN */ -#ifdef MIPS +# elif defined(MIPS) if (error) { r2 = error; a3 = -1; @@ -1839,8 +1828,7 @@ force_result(tcp, error, rval) if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 || ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0) return -1; -#else -#ifdef POWERPC +# elif defined(POWERPC) if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0) return -1; if (error) { @@ -1854,18 +1842,15 @@ force_result(tcp, error, rval) if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 || ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0) return -1; -#else /* !POWERPC */ -#ifdef M68K +# elif defined(M68K) d0 = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0) return -1; -#else /* !M68K */ -#ifdef ARM +# elif defined(ARM) regs.ARM_r0 = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0) return -1; -#else /* !ARM */ -#ifdef ALPHA +# elif defined(ALPHA) if (error) { a3 = -1; r0 = error; @@ -1877,8 +1862,7 @@ force_result(tcp, error, rval) if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 || ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0) return -1; -#else /* !ALPHA */ -#ifdef SPARC +# elif defined(SPARC) if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) return -1; if (error) { @@ -1891,8 +1875,7 @@ force_result(tcp, error, rval) } if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) return -1; -#else /* !SPARC */ -#ifdef SPARC64 +# elif defined(SPARC64) if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) return -1; if (error) { @@ -1905,37 +1888,21 @@ force_result(tcp, error, rval) } if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) return -1; -#else /* !SPARC64 */ -#ifdef HPPA +# elif defined(HPPA) r28 = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0) return -1; -#else -#ifdef SH +# elif defined(SH) r0 = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0) return -1; -#else -#ifdef SH64 +# elif defined(SH64) r9 = error ? -error : rval; if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0) return -1; -#endif /* SH64 */ -#endif /* SH */ -#endif /* HPPA */ -#endif /* SPARC */ -#endif /* SPARC64 */ -#endif /* ALPHA */ -#endif /* ARM */ -#endif /* M68K */ -#endif /* POWERPC */ -#endif /* MIPS */ -#endif /* BFIN */ -#endif /* IA64 */ -#endif /* X86_64 */ -#endif /* I386 */ -#endif /* S390 || S390X */ +# endif #endif /* LINUX */ + #ifdef SUNOS4 if (do_ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error), error << 24) < 0 || do_ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0 @@ -1943,10 +1910,12 @@ force_result(tcp, error, rval) return -1; } #endif /* SUNOS4 */ + #ifdef SVR4 /* XXX no clue */ return -1; #endif /* SVR4 */ + #ifdef FREEBSD if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { perror("pread"); @@ -1973,8 +1942,7 @@ force_result(tcp, error, rval) } static int -syscall_enter(tcp) -struct tcb *tcp; +syscall_enter(struct tcb *tcp) { #ifdef LINUX #if defined(S390) || defined(S390X) @@ -2108,9 +2076,9 @@ struct tcb *tcp; } } #elif defined (POWERPC) -#ifndef PT_ORIG_R3 -#define PT_ORIG_R3 34 -#endif +# ifndef PT_ORIG_R3 +# define PT_ORIG_R3 34 +# endif { int i; if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) @@ -2227,6 +2195,23 @@ struct tcb *tcp; return -1; } } +#elif defined(CRISV10) || defined(CRISV32) + { + int i; + static const int crisregs[] = { + 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12, + 4*PT_R13, 4*PT_MOF, 4*PT_SRP + }; + + if (tcp->scno >= 0 && tcp->scno < nsyscalls) + tcp->u_nargs = sysent[tcp->scno].nargs; + else + tcp->u_nargs = 0; + for (i = 0; i < tcp->u_nargs; i++) { + if (upeek(tcp->pid, crisregs[i], &tcp->u_arg[i]) < 0) + return -1; + } + } #else /* Other architecture (like i386) (32bits specific) */ { int i; @@ -2692,7 +2677,7 @@ struct tcb *tcp; #elif defined(IA64) if (upeek(tcp, PT_R9, &val) < 0) return -1; -#endif /* SPARC || SPARC64 */ +#endif #endif /* LINUX */ #ifdef SUNOS4 @@ -2714,6 +2699,7 @@ struct tcb *tcp; val = tcp->status.PR_REG[CTX_V1]; #endif /* MIPS */ #endif /* SVR4 */ + #ifdef FREEBSD struct reg regs; pread(tcp->pfd_reg, ®s, sizeof(regs), 0); diff --git a/util.c b/util.c index 4a17d40e..6a095597 100644 --- a/util.c +++ b/util.c @@ -1218,8 +1218,7 @@ struct tcb *tcp; #endif /* 0 */ void -printcall(tcp) -struct tcb *tcp; +printcall(struct tcb *tcp) { #define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ sizeof(long) == 8 ? "[????????????????] " : \ @@ -1342,6 +1341,22 @@ struct tcb *tcp; return; } tprintf("[%08lx] ", pc); +#elif defined(CRISV10) + long pc; + + if (upeek(tcp->pid, 4*PT_IRP, &pc) < 0) { + PRINTBADPC; + return; + } + tprintf("[%08lx] ", pc); +#elif defined(CRISV32) + long pc; + + if (upeek(tcp->pid, 4*PT_ERP, &pc) < 0) { + PRINTBADPC; + return; + } + tprintf("[%08lx] ", pc); # endif /* architecture */ #endif /* LINUX */ @@ -1545,6 +1560,13 @@ typedef struct regs arg_setup_state; # define arg0_offset (REG_OFFSET+16) # define arg1_offset (REG_OFFSET+24) # define restore_arg0(tcp, state, val) 0 +# elif defined CRISV10 || defined CRISV32 +# define arg0_offset (4*PT_R11) +# define arg1_offset (4*PT_ORIG_R10) +# define restore_arg0(tcp, state, val) 0 +# define restore_arg1(tcp, state, val) 0 +# define arg0_index 1 +# define arg1_index 0 # else # define arg0_offset 0 # define arg1_offset 4