From: Denys Vlasenko Date: Fri, 8 Feb 2013 11:38:51 +0000 (+0100) Subject: Optimize AArch64 handling of 32-bit personality X-Git-Tag: v4.8~185 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=28ac68f2ab90e85663ecedcf9b56847290cd1ed4;p=strace Optimize AArch64 handling of 32-bit personality 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 --- diff --git a/defs.h b/defs.h index 7b18b5d1..97561796 100644 --- 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 diff --git a/syscall.c b/syscall.c index 3385c242..fcd48505 100644 --- 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 *)®s, 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;