diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2011-06-09 01:36:29 +0200 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2011-06-09 01:36:29 +0200 |
commit | 56a52984ae5d629160074c4c02445bc069024d0c (patch) | |
tree | b30999eeee2db087174027247d8e24292d04f95b /signal.c | |
parent | 4660fe610c2b3707b15b170728a981440e1b54d4 (diff) | |
download | strace-56a52984ae5d629160074c4c02445bc069024d0c.tar.gz strace-56a52984ae5d629160074c4c02445bc069024d0c.tar.bz2 strace-56a52984ae5d629160074c4c02445bc069024d0c.tar.xz |
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 <dvlasenk@redhat.com>
Diffstat (limited to 'signal.c')
-rw-r--r-- | signal.c | 123 |
1 files changed, 50 insertions, 73 deletions
@@ -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; } |