]> granicus.if.org Git - strace/commitdiff
powerpc: skip poking CCR if it is unchanged
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 4 Jul 2019 18:25:49 +0000 (18:25 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 4 Jul 2019 18:25:49 +0000 (18:25 +0000)
* linux/powerpc/set_error.c (arch_set_r3_ccr): New function.
(arch_set_error, arch_set_success): Use it.

linux/powerpc/set_error.c

index 068d6b749b028fb5c499cfbcb187da1a75fff41e..7585dd3382d2ec06d36ffb229976b7f6d6de1efd 100644 (file)
@@ -6,25 +6,30 @@
  */
 
 static int
-arch_set_error(struct tcb *tcp)
+arch_set_r3_ccr(struct tcb *tcp, const unsigned long r3,
+               const unsigned long ccr_set, const unsigned long ccr_clear)
 {
        if (ptrace_syscall_info_is_valid() &&
            upeek(tcp, sizeof(long) * PT_CCR, &ppc_regs.ccr))
                 return -1;
-       ppc_regs.gpr[3] = tcp->u_error;
-       ppc_regs.ccr |= 0x10000000;
-       return upoke(tcp, sizeof(long) * PT_CCR, ppc_regs.ccr) ||
-              upoke(tcp, sizeof(long) * (PT_R0 + 3), ppc_regs.gpr[3]);
+       const unsigned long old_ccr = ppc_regs.ccr;
+       ppc_regs.gpr[3] = r3;
+       ppc_regs.ccr |= ccr_set;
+       ppc_regs.ccr &= ~ccr_clear;
+       if (ppc_regs.ccr != old_ccr &&
+           upoke(tcp, sizeof(long) * PT_CCR, ppc_regs.ccr))
+               return -1;
+       return upoke(tcp, sizeof(long) * (PT_R0 + 3), ppc_regs.gpr[3]);
+}
+
+static int
+arch_set_error(struct tcb *tcp)
+{
+       return arch_set_r3_ccr(tcp, tcp->u_error, 0x10000000, 0);
 }
 
 static int
 arch_set_success(struct tcb *tcp)
 {
-       if (ptrace_syscall_info_is_valid() &&
-           upeek(tcp, sizeof(long) * PT_CCR, &ppc_regs.ccr))
-                return -1;
-       ppc_regs.gpr[3] = tcp->u_rval;
-       ppc_regs.ccr &= ~0x10000000;
-       return upoke(tcp, sizeof(long) * PT_CCR, ppc_regs.ccr) ||
-              upoke(tcp, sizeof(long) * (PT_R0 + 3), ppc_regs.gpr[3]);
+       return arch_set_r3_ccr(tcp, tcp->u_rval, 0, 0x10000000);
 }