aarch64: implement rt_sigreturn decoding

* linux/64/syscallent.h (139): Use sys_sigreturn for rt_sigreturn
decoding.
* syscall.c [ARM] (arm_regs): Make static.
[ARM] (arm_sp_ptr): New variable.
[AARCH64] (aarch64_sp_ptr, arm_sp_ptr): New variables.
* linux/aarch64/arch_regs.h: New file.
* linux/arm/arch_regs.h (arm_regs): Remove.
(arm_sp_ptr): New declaration.
* signal.c (sys_sigreturn) [ARM]: Use arm_sp_ptr.
[AARCH64]: Print signal mask.
diff --git a/linux/64/syscallent.h b/linux/64/syscallent.h
index 6c67c9c..dda9be9 100644
--- a/linux/64/syscallent.h
+++ b/linux/64/syscallent.h
@@ -137,7 +137,7 @@
 [136] = { 2,	TS,		sys_rt_sigpending,		"rt_sigpending"		},
 [137] = { 4,	TS,		sys_rt_sigtimedwait,		"rt_sigtimedwait"	},
 [138] = { 3,	TS,		sys_rt_sigqueueinfo,		"rt_sigqueueinfo"	},
-[139] = { 0,	TS,		sys_rt_sigreturn,		"rt_sigreturn"		},
+[139] = { 0,	TS,		sys_sigreturn,			"rt_sigreturn"		},
 [140] = { 3,	0,		sys_setpriority,		"setpriority"		},
 [141] = { 2,	0,		sys_getpriority,		"getpriority"		},
 [142] = { 4,	0,		sys_reboot,			"reboot"		},
diff --git a/linux/aarch64/arch_regs.h b/linux/aarch64/arch_regs.h
new file mode 100644
index 0000000..290a00e
--- /dev/null
+++ b/linux/aarch64/arch_regs.h
@@ -0,0 +1,2 @@
+extern uint64_t *const aarch64_sp_ptr;
+extern int *const arm_sp_ptr;
diff --git a/linux/arm/arch_regs.h b/linux/arm/arch_regs.h
index b7638ae..bdbc8e9 100644
--- a/linux/arm/arch_regs.h
+++ b/linux/arm/arch_regs.h
@@ -1 +1 @@
-extern struct pt_regs arm_regs;
+extern long *const arm_sp_ptr;
diff --git a/signal.c b/signal.c
index bc78379..1d52f73 100644
--- a/signal.c
+++ b/signal.c
@@ -690,16 +690,19 @@
 int
 sys_sigreturn(struct tcb *tcp)
 {
-#if defined(ARM)
+#if defined AARCH64 || defined ARM
 	if (entering(tcp)) {
-		/*
-		 * Kernel fills out uc.sc.oldmask too when it sets up signal stack,
-		 * but for sigmask restore, sigreturn syscall uses uc.uc_sigmask instead.
-		 */
+# define SIZEOF_STRUCT_SIGINFO 128
 # define SIZEOF_STRUCT_SIGCONTEXT (21 * 4)
 # define OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK (5 * 4 + SIZEOF_STRUCT_SIGCONTEXT)
-		const long addr = arm_regs.ARM_sp +
-			OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK;
+		const long addr =
+# ifdef AARCH64
+			current_personality == 0 ?
+				(*aarch64_sp_ptr + SIZEOF_STRUCT_SIGINFO +
+				 offsetof(struct ucontext, uc_sigmask)) :
+# endif
+				(*arm_sp_ptr +
+				 OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK);
 		tprints(") (mask ");
 		print_sigset_addr_len(tcp, addr, NSIG / 8);
 	}
diff --git a/syscall.c b/syscall.c
index cfedc9f..59f7d9a 100644
--- a/syscall.c
+++ b/syscall.c
@@ -712,7 +712,8 @@
 #elif defined(BFIN)
 static long bfin_r0;
 #elif defined(ARM)
-struct pt_regs arm_regs; /* not static */
+static struct pt_regs arm_regs;
+long *const arm_sp_ptr = &arm_regs.ARM_sp;
 # define ARCH_REGS_FOR_GETREGS arm_regs
 #elif defined(AARCH64)
 struct arm_pt_regs {
@@ -742,6 +743,8 @@
 } arm_regs_union;
 # define aarch64_regs arm_regs_union.aarch64_r
 # define arm_regs     arm_regs_union.arm_r
+uint64_t *const aarch64_sp_ptr = &aarch64_regs.sp;
+int *const arm_sp_ptr = &arm_regs.ARM_sp;
 static struct iovec aarch64_io = {
 	.iov_base = &arm_regs_union
 };