Optimize out PTRACE_PEEKUSER with -i

strace -i was fetching PC with a separate PEEKUSER
despite having GETREGS data:

ptrace(PTRACE_GETREGS, 22331, 0, 0x8087f00) = 0
ptrace(PTRACE_PEEKUSER, 22331, 4*EIP, [0x80dd7b7]) = 0
write(3, "[080dd7b7] ioctl(0, SNDCTL_TMR_T"..., 82) = 82
ptrace(PTRACE_SYSCALL, 22331, 0, SIG_0) = 0

Now it does this:

ptrace(PTRACE_GETREGS, 22549, 0, 0x8087ea0) = 0
write(3, "[080dd7b7] ioctl(0, SNDCTL_TMR_T"..., 82) = 82
ptrace(PTRACE_SYSCALL, 22549, 0, SIG_0) = 0

Analogous improvement in sys_sigreturn() is also implemented.

* defs.h: Declare extern struct pt_regs regs for SPARC[64] and ARM.
Declare clear_regs(), get_regs() and get_regs_error flag variable.
* strace.c (trace): Call get_regs(pid) as soon as we know the tcb
and that it is stopped.
* syscall.c (get_regs): New function. Used to fetch registers early,
just after tracee has stopped.
(printcall): Move it here from util.c. Use global regs.REG data,
if available on the arch, instead of re-fetching it.
(get_scno): Use global regs.REG data.
(get_syscall_result): Likewise.
* signal.c (sys_sigreturn): Likewise.
* util.c (printcall): Moved to syscall.c.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/defs.h b/defs.h
index 0e05c6e..dab5cff 100644
--- a/defs.h
+++ b/defs.h
@@ -356,6 +356,12 @@
 #if defined(IA64)
 extern long ia32;
 #endif
+#if defined(SPARC) || defined(SPARC64)
+extern struct pt_regs regs;
+#endif
+#if defined(ARM)
+extern struct pt_regs regs;
+#endif
 
 /* Trace Control Block */
 struct tcb {
@@ -535,6 +541,20 @@
 extern void count_syscall(struct tcb *, struct timeval *);
 extern void call_summary(FILE *);
 
+#if defined(AVR32) \
+ || defined(I386) \
+ || defined(X86_64) || defined(X32) \
+ || defined(AARCH64) \
+ || defined(ARM) \
+ || defined(SPARC) || defined(SPARC64)
+extern long get_regs_error;
+# define clear_regs()  (get_regs_error = -1)
+extern void get_regs(pid_t pid);
+#else
+# define get_regs_error 0
+# define clear_regs()  ((void)0)
+# define get_regs(pid) ((void)0)
+#endif
 extern int umoven(struct tcb *, long, int, char *);
 #define umove(pid, addr, objp)	\
 	umoven((pid), (addr), sizeof(*(objp)), (char *) (objp))