]> granicus.if.org Git - strace/commitdiff
Optimize AArch64 handling of 32-bit personality
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 8 Feb 2013 11:38:51 +0000 (12:38 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 8 Feb 2013 11:38:51 +0000 (12:38 +0100)
By putting aarch64_regs and arm_regs into a union,
register copying is eliminated.
No need to check and change personality on syscall exit.

* defs.h: Remove unused NUM_ARM_REGS define. Fix indentation.
* syscall.c: Put aarch64_regs and arm_regs into a union.
(update_personality): Shorten bitness message.
(printcall): Add commented-out PC printing.
(get_regs): Remove now-unnecessary 64-to-32 bits register copying.
(get_syscall_result): Drop personality changing code.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
defs.h
syscall.c

diff --git a/defs.h b/defs.h
index 7b18b5d176ce2174577c6431344ee0358dd204c0..975617967622e8c3dc73dd72dbb87ce1c74e68fb 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -197,28 +197,27 @@ extern long ptrace(int, int, char *, long);
 # define REG_SYSCALL        (2*8)
 #endif /* SH64 */
 #ifdef AARCH64
-#define NUM_ARM_REGS 18
 struct arm_pt_regs {
-        int uregs[NUM_ARM_REGS];
+        int uregs[18];
 };
-#define ARM_cpsr        uregs[16]
-#define ARM_pc          uregs[15]
-#define ARM_lr          uregs[14]
-#define ARM_sp          uregs[13]
-#define ARM_ip          uregs[12]
-#define ARM_fp          uregs[11]
-#define ARM_r10         uregs[10]
-#define ARM_r9          uregs[9]
-#define ARM_r8          uregs[8]
-#define ARM_r7          uregs[7]
-#define ARM_r6          uregs[6]
-#define ARM_r5          uregs[5]
-#define ARM_r4          uregs[4]
-#define ARM_r3          uregs[3]
-#define ARM_r2          uregs[2]
-#define ARM_r1          uregs[1]
-#define ARM_r0          uregs[0]
-#define ARM_ORIG_r0     uregs[17]
+# define ARM_cpsr       uregs[16]
+# define ARM_pc         uregs[15]
+# define ARM_lr         uregs[14]
+# define ARM_sp         uregs[13]
+# define ARM_ip         uregs[12]
+# define ARM_fp         uregs[11]
+# define ARM_r10        uregs[10]
+# define ARM_r9         uregs[9]
+# define ARM_r8         uregs[8]
+# define ARM_r7         uregs[7]
+# define ARM_r6         uregs[6]
+# define ARM_r5         uregs[5]
+# define ARM_r4         uregs[4]
+# define ARM_r3         uregs[3]
+# define ARM_r2         uregs[2]
+# define ARM_r1         uregs[1]
+# define ARM_r0         uregs[0]
+# define ARM_ORIG_r0    uregs[17]
 #endif /* AARCH64 */
 
 #define SUPPORTED_PERSONALITIES 1
index 3385c24249615d5efee6ee8c04623723bb0c28e9..fcd48505397a2ec2b6b80c4ad82352d21cceff30 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -295,7 +295,7 @@ update_personality(struct tcb *tcp, int personality)
        }
 # elif defined(AARCH64)
        if (!qflag) {
-               static const char *const names[] = {"32-bit ARM", "AArch64"};
+               static const char *const names[] = {"32-bit", "AArch64"};
                fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
                        tcp->pid, names[personality]);
        }
@@ -681,8 +681,12 @@ static long r0;
 #elif defined(ARM)
 struct pt_regs arm_regs; /* not static */
 #elif defined(AARCH64)
-static struct user_pt_regs aarch64_regs;
-static struct arm_pt_regs arm_regs;
+static union {
+       struct user_pt_regs aarch64;
+       struct arm_pt_regs  arm;
+} arm_regs_union;
+# define aarch64_regs arm_regs_union.aarch64
+# define arm_regs     arm_regs_union.arm
 static struct iovec aarch64_io = {
        .iov_base = &aarch64_regs
 };
@@ -816,7 +820,8 @@ printcall(struct tcb *tcp)
        tprintf("[%08lx] ", pc);
 #elif defined(ARM)
        tprintf("[%08lx] ", arm_regs.ARM_pc);
-/*#elif defined(AARCH64) ??? */
+#elif defined(AARCH64)
+       /* tprintf("[%016lx] ", aarch64_regs.regs[???]); */
 #elif defined(AVR32)
        tprintf("[%08lx] ", regs.pc);
 #elif defined(BFIN)
@@ -868,21 +873,22 @@ void get_regs(pid_t pid)
        /*aarch64_io.iov_base = &aarch64_regs; - already is */
        aarch64_io.iov_len = sizeof(aarch64_regs);
        get_regs_error = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, (void *)&aarch64_io);
+#  if 0
+       /* Paranoia checks */
        if (get_regs_error)
                return;
        switch (aarch64_io.iov_len) {
-               case sizeof(regs):
-                       /* We are in 32-bit mode */
-                       memcpy(&arm_regs, &aarch64_regs, sizeof(arm_regs));
-                       break;
                case sizeof(aarch64_regs):
                        /* We are in 64-bit mode */
-                       /* Data is already in aarch64_regs */
+                       break;
+               case sizeof(arm_regs):
+                       /* We are in 32-bit mode */
                        break;
                default:
                        get_regs_error = -1;
                        break;
        }
+#  endif
 # elif defined(SPARC) || defined(SPARC64)
        get_regs_error = ptrace(PTRACE_GETREGS, pid, (char *)&regs, 0);
 # elif defined(TILE)
@@ -1113,9 +1119,9 @@ get_scno(struct tcb *tcp)
                        scno = aarch64_regs.regs[8];
                        update_personality(tcp, 1);
                        break;
-               case sizeof(regs):
+               case sizeof(arm_regs):
                        /* We are in 32-bit mode */
-                       scno = arm_regs.uregs[7];
+                       scno = arm_regs.ARM_r7;
                        update_personality(tcp, 0);
                        break;
        }
@@ -1627,7 +1633,7 @@ get_syscall_args(struct tcb *tcp)
                for (i = 0; i < nargs; ++i)
                        tcp->u_arg[i] = aarch64_regs.regs[i];
        else
-# endif /* AARCH64 */
+# endif
        for (i = 0; i < nargs; ++i)
                tcp->u_arg[i] = arm_regs.uregs[i];
 #elif defined(AVR32)
@@ -1861,14 +1867,16 @@ get_syscall_result(struct tcb *tcp)
                return -1;
        if (upeek(tcp, PT_R10, &ia64_r10) < 0)
                return -1;
+#elif defined(ARM)
+       /* already done by get_regs */
 #elif defined(AARCH64)
-/* FIXME: uh, why do we do it on syscall *exit*? We did it on entry already... */
+       /* register reading already done by get_regs */
+
+       /* Used to do this, but we did it on syscall entry already: */
        /* We are in 64-bit mode (personality 1) if register struct is aarch64_regs,
         * else it's personality 0.
         */
-       update_personality(tcp, aarch64_io.iov_len == sizeof(aarch64_regs));
-#elif defined(ARM)
-       /* already done by get_regs */
+       /*update_personality(tcp, aarch64_io.iov_len == sizeof(aarch64_regs));*/
 #elif defined(M68K)
        if (upeek(tcp, 4*PT_D0, &m68k_d0) < 0)
                return -1;
@@ -2049,7 +2057,7 @@ get_error(struct tcb *tcp)
                }
        }
        else
-# endif /* AARCH64 */
+# endif
        {
                if (check_errno && is_negated_errno(arm_regs.ARM_r0)) {
                        tcp->u_rval = -1;