From: Denys Vlasenko Date: Wed, 8 Jun 2011 23:36:29 +0000 (+0200) Subject: Optimize sigreturn handling X-Git-Tag: v4.7~381 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=56a52984ae5d629160074c4c02445bc069024d0c;p=strace Optimize sigreturn handling * signal.c (sys_sigreturn): move stack pointer variables, and for SPARC and MIPS, stack pointer and sigmask reading code into "if (entering) ..." block, because it is only needed in this branch; load tcp->u_arg[1] into sigmask for display _after_ we know for sure u_arg[1] does contain valid sigmask (IOW: perform operation only when we know we will need the result) Signed-off-by: Denys Vlasenko --- diff --git a/signal.c b/signal.c index e4ae7d4c..85e74b57 100644 --- a/signal.c +++ b/signal.c @@ -1233,35 +1233,30 @@ int sys_sigreturn(struct tcb *tcp) { #if defined(ARM) - struct pt_regs regs; - struct sigcontext_struct sc; - if (entering(tcp)) { + struct pt_regs regs; + struct sigcontext_struct sc; tcp->u_arg[0] = 0; - if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1) return 0; - if (umove(tcp, regs.ARM_sp, &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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(S390) || defined(S390X) - long usp; - struct sigcontext_struct sc; - if (entering(tcp)) { + long usp; + struct sigcontext_struct sc; tcp->u_arg[0] = 0; if (upeek(tcp, PT_GPR15, &usp) < 0) return 0; @@ -1278,10 +1273,9 @@ sys_sigreturn(struct tcb *tcp) } return 0; #elif defined(I386) - long esp; - struct sigcontext_struct sc; - if (entering(tcp)) { + long esp; + struct sigcontext_struct sc; tcp->u_arg[0] = 0; if (upeek(tcp, 4*UESP, &esp) < 0) return 0; @@ -1292,19 +1286,18 @@ sys_sigreturn(struct tcb *tcp) } 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(IA64) - struct sigcontext sc; - long sp; - if (entering(tcp)) { + struct sigcontext sc; + long sp; /* offset of sigcontext in the kernel's sigframe structure: */ # define SIGFRAME_SC_OFFSET 0x90 tcp->u_arg[0] = 0; @@ -1317,20 +1310,18 @@ sys_sigreturn(struct tcb *tcp) } else { sigset_t sigm; - - memcpy(&sigm, tcp->u_arg + 1, sizeof(sigm)); tcp->u_rval = tcp->u_error = 0; if (tcp->u_arg[0] == 0) return 0; + memcpy(&sigm, tcp->u_arg + 1, sizeof(sigm)); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(POWERPC) - long esp; - struct sigcontext_struct sc; - if (entering(tcp)) { + long esp; + struct sigcontext_struct sc; tcp->u_arg[0] = 0; if (upeek(tcp, sizeof(unsigned long)*PT_R1, &esp) < 0) return 0; @@ -1350,19 +1341,18 @@ sys_sigreturn(struct tcb *tcp) } 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(M68K) - long usp; - struct sigcontext sc; - if (entering(tcp)) { + long usp; + struct sigcontext sc; tcp->u_arg[0] = 0; if (upeek(tcp, 4*PT_USP, &usp) < 0) return 0; @@ -1373,19 +1363,18 @@ sys_sigreturn(struct tcb *tcp) } 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(ALPHA) - long fp; - struct sigcontext_struct sc; - if (entering(tcp)) { + long fp; + struct sigcontext_struct sc; tcp->u_arg[0] = 0; if (upeek(tcp, REG_FP, &fp) < 0) return 0; @@ -1396,38 +1385,37 @@ sys_sigreturn(struct tcb *tcp) } 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined (SPARC) || defined (SPARC64) - long i1; - struct pt_regs regs; - m_siginfo_t si; - - if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { - perror("sigreturn: PTRACE_GETREGS "); - return 0; - } if (entering(tcp)) { + long i1; + struct pt_regs regs; + m_siginfo_t si; tcp->u_arg[0] = 0; + if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { + perror("sigreturn: PTRACE_GETREGS"); + return 0; + } i1 = regs.u_regs[U_REG_O1]; if (umove(tcp, i1, &si) < 0) { - perror("sigreturn: umove "); + perror("sigreturn: umove"); return 0; } tcp->u_arg[0] = 1; tcp->u_arg[1] = si.si_mask; } 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } @@ -1435,10 +1423,9 @@ sys_sigreturn(struct tcb *tcp) #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64) /* This decodes rt_sigreturn. The 64-bit ABIs do not have sigreturn. */ - long sp; - struct ucontext uc; - if (entering(tcp)) { + long sp; + struct ucontext uc; tcp->u_arg[0] = 0; if (upeek(tcp, REG_SP, &sp) < 0) return 0; @@ -1450,25 +1437,24 @@ sys_sigreturn(struct tcb *tcp) tcp->u_arg[1] = *(long *) &uc.uc_sigmask; } 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(MIPS) - long sp; - struct pt_regs regs; - m_siginfo_t si; - - if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { - perror("sigreturn: PTRACE_GETREGS "); - return 0; - } if (entering(tcp)) { + long sp; + struct pt_regs regs; + m_siginfo_t si; tcp->u_arg[0] = 0; + if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) { + perror("sigreturn: PTRACE_GETREGS"); + return 0; + } sp = regs.regs[29]; if (umove(tcp, sp, &si) < 0) return 0; @@ -1476,22 +1462,19 @@ sys_sigreturn(struct tcb *tcp) tcp->u_arg[1] = si.si_mask; } 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(CRISV10) || defined(CRISV32) - struct sigcontext sc; - if (entering(tcp)) { + struct sigcontext sc; 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; @@ -1502,23 +1485,21 @@ sys_sigreturn(struct tcb *tcp) 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(TILE) - struct ucontext uc; - long sp; - - /* offset of ucontext in the kernel's sigframe structure */ -# define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(struct siginfo) - if (entering(tcp)) { + struct ucontext uc; + long sp; + + /* offset of ucontext in the kernel's sigframe structure */ +# define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(struct siginfo) tcp->u_arg[0] = 0; if (upeek(tcp, PTREGS_OFFSET_SP, &sp) < 0) return 0; @@ -1529,24 +1510,20 @@ sys_sigreturn(struct tcb *tcp) } else { sigset_t sigm; - - memcpy(&sigm, tcp->u_arg + 1, sizeof(sigm)); tcp->u_rval = tcp->u_error = 0; if (tcp->u_arg[0] == 0) return 0; + memcpy(&sigm, tcp->u_arg + 1, sizeof(sigm)); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; } return 0; #elif defined(MICROBLAZE) - struct sigcontext sc; - /* TODO: Verify that this is correct... */ if (entering(tcp)) { + struct sigcontext sc; long sp; - tcp->u_arg[0] = 0; - /* Read r1, the stack pointer. */ if (upeek(tcp, 1 * 4, &sp) < 0) return 0; @@ -1556,10 +1533,10 @@ sys_sigreturn(struct tcb *tcp) 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; + long_to_sigset(tcp->u_arg[1], &sigm); tcp->auxstr = sprintsigmask("mask now ", &sigm, 0); return RVAL_NONE | RVAL_STR; }