From: Anton Blanchard Date: Wed, 26 Jun 2013 13:53:33 +0000 (+0200) Subject: powerpc: Use PTRACE_GETREGS to fetch all registers X-Git-Tag: v4.9~219 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce6e33be1dbfc16620ea7991a414e879ef84fe22;p=strace powerpc: Use PTRACE_GETREGS to fetch all registers * defs.h: declare ppc_regs and get_regs_error. * signal.c (sys_sigreturn): Use ppc_regs instead of upeek. * syscall.c: define ppc_regs. (printcall): Use ppc_regs instead of upeek. (get_scno): Replace multiple upeek calls with one PTRACE_GETREGS call. (get_syscall_result): Likewise. Signed-off-by: Anton Blanchard Signed-off-by: Denys Vlasenko --- diff --git a/defs.h b/defs.h index 1f1602a2..76eb3003 100644 --- a/defs.h +++ b/defs.h @@ -375,6 +375,8 @@ extern struct pt_regs sparc_regs; extern struct pt_regs arm_regs; #elif defined(TILE) extern struct pt_regs tile_regs; +#elif defined(POWERPC) +extern struct pt_regs ppc_regs; #endif typedef struct sysent { @@ -591,7 +593,8 @@ extern void call_summary(FILE *); || defined(SPARC) || defined(SPARC64) \ || defined(TILE) \ || defined(OR1K) \ - || defined(METAG) + || defined(METAG) \ + || defined(POWERPC) extern long get_regs_error; # define clear_regs() (get_regs_error = -1) extern void get_regs(pid_t pid); diff --git a/signal.c b/signal.c index 55815aa0..3371ee74 100644 --- a/signal.c +++ b/signal.c @@ -866,8 +866,9 @@ sys_sigreturn(struct tcb *tcp) long esp; struct sigcontext_struct sc; sigset_t sigm; - if (upeek(tcp, sizeof(unsigned long) * PT_R1, &esp) < 0) - return 0; + + esp = ppc_regs.gpr[1]; + /* Skip dummy stack frame. */ #ifdef POWERPC64 if (current_personality == 0) diff --git a/syscall.c b/syscall.c index 7efee0e4..f5263a74 100644 --- a/syscall.c +++ b/syscall.c @@ -751,6 +751,7 @@ static struct iovec x86_io = { long ia32 = 0; /* not static */ static long ia64_r8, ia64_r10; #elif defined(POWERPC) +struct pt_regs ppc_regs; static long ppc_result; #elif defined(M68K) static long m68k_d0; @@ -849,11 +850,7 @@ printcall(struct tcb *tcp) } tprintf("[%08lx] ", ip); #elif defined(POWERPC) - long pc; - if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) { - PRINTBADPC; - return; - } + long pc = ppc_regs.nip; # ifdef POWERPC64 tprintf("[%016lx] ", pc); # else @@ -1043,6 +1040,8 @@ get_regs(pid_t pid) get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &tile_regs); # elif defined(SPARC) || defined(SPARC64) get_regs_error = ptrace(PTRACE_GETREGS, pid, (char *)&sparc_regs, 0); +# elif defined(POWERPC) + get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &ppc_regs); /* try PTRACE_GETREGSET first, fallback to PTRACE_GETREGS */ # else @@ -1195,20 +1194,13 @@ get_scno(struct tcb *tcp) } } #elif defined(POWERPC) - if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0) - return -1; + scno = ppc_regs.gpr[0]; # ifdef POWERPC64 - /* TODO: speed up strace by not doing this at every syscall. - * We only need to do it after execve. - */ int currpers; - long val; /* Check for 64/32 bit mode. */ - if (upeek(tcp, sizeof(unsigned long)*PT_MSR, &val) < 0) - return -1; /* SF is bit 0 of MSR */ - if (val < 0) + if ((ppc_regs.msr >> 63) & 1) currpers = 0; else currpers = 1; @@ -1805,16 +1797,14 @@ get_syscall_args(struct tcb *tcp) return -1; } #elif defined(POWERPC) -# ifndef PT_ORIG_R3 -# define PT_ORIG_R3 34 -# endif - for (i = 0; i < nargs; ++i) { - if (upeek(tcp, (i==0) ? - (sizeof(unsigned long) * PT_ORIG_R3) : - ((i+PT_R3) * sizeof(unsigned long)), - &tcp->u_arg[i]) < 0) - return -1; - } + (void)i; + (void)nargs; + tcp->u_arg[0] = ppc_regs.orig_gpr3; + tcp->u_arg[1] = ppc_regs.gpr[4]; + tcp->u_arg[2] = ppc_regs.gpr[5]; + tcp->u_arg[3] = ppc_regs.gpr[6]; + tcp->u_arg[4] = ppc_regs.gpr[7]; + tcp->u_arg[5] = ppc_regs.gpr[8]; #elif defined(SPARC) || defined(SPARC64) for (i = 0; i < nargs; ++i) tcp->u_arg[i] = sparc_regs.u_regs[U_REG_O0 + i]; @@ -2060,15 +2050,9 @@ get_syscall_result(struct tcb *tcp) return -1; #elif defined(POWERPC) # define SO_MASK 0x10000000 - { - long flags; - if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0) - return -1; - if (upeek(tcp, sizeof(unsigned long)*PT_R3, &ppc_result) < 0) - return -1; - if (flags & SO_MASK) - ppc_result = -ppc_result; - } + ppc_result = ppc_regs.gpr[3]; + if (ppc_regs.ccr & SO_MASK) + ppc_result = -ppc_result; #elif defined(AVR32) /* already done by get_regs */ #elif defined(BFIN)