]> granicus.if.org Git - strace/commitdiff
Unify per-architecture post-execve SIGTRAP check.
authorDenys Vlasenko <dvlasenk@redhat.com>
Wed, 24 Aug 2011 15:25:32 +0000 (17:25 +0200)
committerDenys Vlasenko <dvlasenk@redhat.com>
Wed, 24 Aug 2011 15:25:32 +0000 (17:25 +0200)
Move post-execve SIGTRAP check from get_scno_on_sysenter
(multitude of places on many architectures) to a single location
in trace_syscall_entering. This loosens the logic for some arches,
since many of them had additional checks such as scno == 0.
However, on non-ancient Linux kernels we should never have post-execve
SIGTRAP in the first place, by virtue of using PTRACE_O_TRACEEXEC.

* syscall.c (get_scno_on_sysenter): Remove tcp->flags & TCB_WAITEXECVE checks.
(trace_syscall_entering): Do tcp->flags & TCB_WAITEXECVE check here.
(get_scno_on_sysexit): Tweak comment.
(syscall_fixup): Likewise.
(trace_syscall_exiting): Likewise.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
syscall.c

index fc502bf27a8464d255a2a5560ee61380712534a5..8ffa4a6a24bb9800633191cac8a496813a3d89f4 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -754,12 +754,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 
 #ifdef LINUX
 # if defined(S390) || defined(S390X)
-       if (tcp->flags & TCB_WAITEXECVE) {
-               /* This is the post-execve SIGTRAP. */
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
-
        if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
                return -1;
 
@@ -843,11 +837,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 # elif defined (POWERPC)
        if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
                return -1;
-       /* Check if this is the post-execve SIGTRAP. */
-       if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
 #  ifdef POWERPC64
        /* TODO: speed up strace by not doing this at every syscall.
         * We only need to do it after execve.
@@ -872,19 +861,10 @@ get_scno_on_sysenter(struct tcb *tcp)
        }
 #  endif
 # elif defined(AVR32)
-       /*
-        * Read complete register set in one go.
-        */
+       /* Read complete register set in one go. */
        if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, &regs) < 0)
                return -1;
-
        scno = regs.r8;
-
-       /* Check if this is the post-execve SIGTRAP. */
-       if (tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
 # elif defined(BFIN)
        if (upeek(tcp, PT_ORIG_P0, &scno))
                return -1;
@@ -969,15 +949,8 @@ get_scno_on_sysenter(struct tcb *tcp)
                if (upeek(tcp, PT_R15, &scno) < 0)
                        return -1;
        }
-       /* Check if this is the post-execve SIGTRAP. */
-       if (tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
 # elif defined (ARM)
-       /*
-        * Read complete register set in one go.
-        */
+       /* Read complete register set in one go. */
        if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)&regs) == -1)
                return -1;
 
@@ -985,12 +958,6 @@ get_scno_on_sysenter(struct tcb *tcp)
         * We only need to grab the syscall number on syscall entry.
         */
        if (regs.ARM_ip == 0) {
-               /* Check if this is the post-execve SIGTRAP. */
-               if (tcp->flags & TCB_WAITEXECVE) {
-                       tcp->flags &= ~TCB_WAITEXECVE;
-                       return 0;
-               }
-
                /*
                 * Note: we only deal with only 32-bit CPUs here.
                 */
@@ -1008,14 +975,6 @@ get_scno_on_sysenter(struct tcb *tcp)
                        if (errno)
                                return -1;
 
-               /* FIXME: bogus check? it is already done before,
-                * so we never can see it here?
-                */
-                       if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
-                               tcp->flags &= ~TCB_WAITEXECVE;
-                               return 0;
-                       }
-
                        /* Handle the EABI syscall convention.  We do not
                           bother converting structures between the two
                           ABIs, but basic functionality should work even
@@ -1061,13 +1020,6 @@ get_scno_on_sysenter(struct tcb *tcp)
        r2 = regs[REG_V0];
 
        scno = r2;
-
-       /* Check if this is the post-execve SIGTRAP. */
-       if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
-
        if (scno < 0 || scno > nsyscalls) {
                if (a3 == 0 || a3 == -1) {
                        if (debug)
@@ -1081,12 +1033,6 @@ get_scno_on_sysenter(struct tcb *tcp)
        if (upeek(tcp, REG_V0, &scno) < 0)
                return -1;
 
-       /* Check if this is the post-execve SIGTRAP. */
-       if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
-
        if (scno < 0 || scno > nsyscalls) {
                if (a3 == 0 || a3 == -1) {
                        if (debug)
@@ -1097,16 +1043,9 @@ get_scno_on_sysenter(struct tcb *tcp)
 # elif defined (ALPHA)
        if (upeek(tcp, REG_A3, &a3) < 0)
                return -1;
-
        if (upeek(tcp, REG_R0, &scno) < 0)
                return -1;
 
-       /* Check if this is the post-execve SIGTRAP. */
-       if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
-
        /*
         * Do some sanity checks to figure out if it's
         * really a syscall entry
@@ -1162,11 +1101,6 @@ get_scno_on_sysenter(struct tcb *tcp)
                set_personality(1);
                break;
        default:
-               /* Check if this is the post-execve SIGTRAP. */
-               if (tcp->flags & TCB_WAITEXECVE) {
-                       tcp->flags &= ~TCB_WAITEXECVE;
-                       return 0;
-               }
 #  if defined (SPARC64)
                fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
 #  else
@@ -1187,11 +1121,6 @@ get_scno_on_sysenter(struct tcb *tcp)
 # elif defined(HPPA)
        if (upeek(tcp, PT_GR20, &scno) < 0)
                return -1;
-       /* Check if this is the post-execve SIGTRAP. */
-       if (tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
 # elif defined(SH)
        /*
         * In the new syscall ABI, the system call number is in R3.
@@ -1212,34 +1141,16 @@ get_scno_on_sysenter(struct tcb *tcp)
                                correct_scno);
                scno = correct_scno;
        }
-
-       /* Check if this is the post-execve SIGTRAP. */
-       if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
 # elif defined(SH64)
        if (upeek(tcp, REG_SYSCALL, &scno) < 0)
                return -1;
        scno &= 0xFFFF;
-
-       /* Check if this is the post-execve SIGTRAP. */
-       if (tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
 # elif defined(CRISV10) || defined(CRISV32)
        if (upeek(tcp, 4*PT_R9, &scno) < 0)
                return -1;
 # elif defined(TILE)
        if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
                return -1;
-
-       /* Check if this is the post-execve SIGTRAP. */
-       if (tcp->flags & TCB_WAITEXECVE) {
-               tcp->flags &= ~TCB_WAITEXECVE;
-               return 0;
-       }
 # elif defined(MICROBLAZE)
        if (upeek(tcp, 0, &scno) < 0)
                return -1;
@@ -1300,9 +1211,7 @@ get_scno_on_sysexit(struct tcb *tcp)
 # if defined(S390) || defined(S390X)
 # elif defined (POWERPC)
 # elif defined(AVR32)
-       /*
-        * Read complete register set in one go.
-        */
+       /* Read complete register set in one go. */
        if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, &regs) < 0)
                return -1;
 # elif defined(BFIN)
@@ -1321,9 +1230,7 @@ get_scno_on_sysexit(struct tcb *tcp)
        if (upeek(tcp, PT_R10, &r10) < 0)
                return -1;
 # elif defined (ARM)
-       /*
-        * Read complete register set in one go.
-        */
+       /* Read complete register set in one go. */
        if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)&regs) == -1)
                return -1;
 # elif defined (M68K)
@@ -1511,6 +1418,7 @@ syscall_fixup(struct tcb *tcp)
                  == (TCB_INSYSCALL|TCB_WAITEXECVE))
                 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
                /*
+                * Return from execve.
                 * Fake a return value of zero.  We leave the TCB_WAITEXECVE
                 * flag set for the post-execve SIGTRAP to see and reset.
                 */
@@ -2308,6 +2216,14 @@ trace_syscall_entering(struct tcb *tcp)
 {
        int res, scno_good;
 
+#if defined TCB_WAITEXECVE
+       if (tcp->flags & TCB_WAITEXECVE) {
+               /* This is the post-execve SIGTRAP. */
+               tcp->flags &= ~TCB_WAITEXECVE;
+               return 0;
+       }
+#endif
+
        scno_good = res = get_scno_on_sysenter(tcp);
        if (res == 0)
                return res;
@@ -2477,9 +2393,6 @@ trace_syscall_exiting(struct tcb *tcp)
        if (dtime || cflag)
                gettimeofday(&tv, NULL);
 
-       /* BTW, why we don't just memorize syscall no. on entry
-        * in tcp->something?
-        */
        scno_good = res = get_scno_on_sysexit(tcp);
        if (res == 0)
                return res;