]> granicus.if.org Git - strace/commitdiff
Refactor tamper_with_syscall_exiting()
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 5 Dec 2018 16:10:05 +0000 (16:10 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 5 Dec 2018 16:10:05 +0000 (16:10 +0000)
Move the code than deals with updating the return and error values
to separate functions.

* syscall.c (set_error, set_success): New functions.
(tamper_with_syscall_exiting): Use them.

syscall.c

index 9ff95591007521dae6f3b9663a5243ce53391604..a0902eca22048619bbab41fc3e4e29febcc9b03b 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -478,7 +478,9 @@ static long get_regs(struct tcb *);
 static int get_syscall_args(struct tcb *);
 static int get_syscall_result(struct tcb *);
 static void get_error(struct tcb *, bool);
-static int arch_get_scno(struct tcb *tcp);
+static void set_error(struct tcb *, unsigned long);
+static void set_success(struct tcb *, kernel_long_t);
+static int arch_get_scno(struct tcb *);
 static int arch_set_scno(struct tcb *, kernel_ulong_t);
 static int arch_get_syscall_args(struct tcb *);
 static void arch_get_error(struct tcb *, bool);
@@ -564,37 +566,10 @@ tamper_with_syscall_exiting(struct tcb *tcp)
                return 1;
        }
 
-       bool update_tcb = false;
-
-       if (opts->data.flags & INJECT_F_RETVAL) {
-               kernel_long_t inject_rval =
-                       retval_get(opts->data.rval_idx);
-               kernel_long_t u_rval = tcp->u_rval;
-
-               tcp->u_rval = inject_rval;
-               if (arch_set_success(tcp)) {
-                       tcp->u_rval = u_rval;
-               } else {
-                       update_tcb = true;
-                       tcp->u_error = 0;
-               }
-       } else {
-               unsigned long new_error = retval_get(opts->data.rval_idx);
-
-               if (new_error != tcp->u_error && new_error <= MAX_ERRNO_VALUE) {
-                       unsigned long u_error = tcp->u_error;
-
-                       tcp->u_error = new_error;
-                       if (arch_set_error(tcp)) {
-                               tcp->u_error = u_error;
-                       } else {
-                               update_tcb = true;
-                       }
-               }
-       }
-
-       if (update_tcb)
-               get_error(tcp, !(tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS));
+       if (opts->data.flags & INJECT_F_RETVAL)
+               set_success(tcp, retval_get(opts->data.rval_idx));
+       else
+               set_error(tcp, retval_get(opts->data.rval_idx));
 
        return 0;
 }
@@ -1302,6 +1277,37 @@ get_error(struct tcb *tcp, const bool check_errno)
        arch_get_error(tcp, check_errno);
 }
 
+static void
+set_error(struct tcb *tcp, unsigned long new_error)
+{
+       const unsigned long old_error = tcp->u_error;
+
+       if (new_error == old_error || new_error > MAX_ERRNO_VALUE)
+               return;
+
+       tcp->u_error = new_error;
+       if (arch_set_error(tcp)) {
+               tcp->u_error = old_error;
+               /* arch_set_error does not update u_rval */
+       } else {
+               get_error(tcp, !(tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS));
+       }
+}
+
+static void
+set_success(struct tcb *tcp, kernel_long_t new_rval)
+{
+       const kernel_long_t old_rval = tcp->u_rval;
+
+       tcp->u_rval = new_rval;
+       if (arch_set_success(tcp)) {
+               tcp->u_rval = old_rval;
+               /* arch_set_error does not update u_error */
+       } else {
+               get_error(tcp, !(tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS));
+       }
+}
+
 #include "get_scno.c"
 #include "set_scno.c"
 #include "get_syscall_args.c"