diff mbox

[2/2] Add AArch64 support to strace

Message ID 20121024165807.GA23768@einval.com
State New
Headers show

Commit Message

Steve McIntyre Oct. 24, 2012, 4:58 p.m. UTC
On Tue, Oct 23, 2012 at 02:11:59PM -0400, Mike Frysinger wrote:
>On Tuesday 23 October 2012 12:38:22 Steve McIntyre wrote:
>> Add AArch64 support to strace
>> 
>> AArch64 has been included in Linux from 3.7 onwards. Add support for
>> AArch64 in strace, tested on Linux in a simulator.
>
>any plans to support tracing of 32bit arm ELFs ?

Yes, that's the next plan for me.

>> --- /dev/null
>> +++ b/linux/aarch64/syscallent.h
>>
>> +	/* Arch-specific block, not used on AArch64 */
>> +	{ MA,	0,	NULL,				"NULL"				}, /*  244 
>*/
>
>x32 just does something like:
>	[244 ... 259] = { },
>
>can't you do the same ?
>
>> +	/* Blank down to 1023 */

ACK, just hadn't noticed that. Updated to match, thanks. :-)

>same here:
>	[272 ... 1023] = { },
>
>> --- a/syscall.c
>> +++ b/syscall.c
>>
>> +	if (ptrace(PTRACE_GETREGSET, tcp->pid, NT_PRSTATUS, (void *)&io) == -1)
>> +	{
>> +		return -1;
>> +	}

ACK.

New patch included here with these changes included.

Add AArch64 support to strace

AArch64 has been included in Linux from 3.7 onwards. Add support for
AArch64 in strace, tested on Linux in a simulator.

* configure.ac: Support AArch64.
* defs.h: Support AArch64.
* ipc.c: Support AArch64.
* process.c: Support AArch64.
* syscall.c: Support AArch64. Uses new PTRACE_GETREGSET ptrace request
instead of PTRACE_GETREGS, so also include sys/uio.h and elf.h for needed
definitions.
* linux/aarch64/*: Set up definitions for AArch64. Initially based on
ARM defs, added syscallent.h based on kernel 3.7 version of
asm-generic/unistd.h.

Signed-off-by: Steve McIntyre <steve.mcintyre@linaro.org>
---
 configure.ac                |    4 +
 defs.h                      |    5 +-
 ipc.c                       |    2 +-
 linux/aarch64/ioctlent.h.in |    1 +
 linux/aarch64/syscallent.h  |  330 +++++++++++++++++++++++++++++++++++++++++++
 process.c                   |    7 +-
 syscall.c                   |   32 +++++
 7 files changed, 375 insertions(+), 6 deletions(-)
 create mode 100644 linux/aarch64/ioctlent.h.in
 create mode 100644 linux/aarch64/syscallent.h

Comments

Dmitry V. Levin Oct. 27, 2012, 3:44 p.m. UTC | #1
On Wed, Oct 24, 2012 at 05:58:16PM +0100, Steve McIntyre wrote:
> On Tue, Oct 23, 2012 at 02:11:59PM -0400, Mike Frysinger wrote:
> >On Tuesday 23 October 2012 12:38:22 Steve McIntyre wrote:
> >> Add AArch64 support to strace
[...]
> New patch included here with these changes included.

Applied with linux/aarch64/syscallent.h updated for newly introduced
trace=memory support.  Thanks!
diff mbox

Patch

diff --git a/configure.ac b/configure.ac
index a9f8d15..f44eaf1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,10 @@  arm*)
 	arch=arm
 	AC_DEFINE([ARM], 1, [Define for the ARM architecture.])
 	;;
+aarch64*)
+	arch=aarch64
+	AC_DEFINE([AARCH64], 1, [Define for the AArch64 architecture.])
+	;;
 avr32*)
 	arch=avr32
 	AC_DEFINE([AVR32], 1, [Define for the AVR32 architecture.])
diff --git a/defs.h b/defs.h
index 7814bbd..b0846cd 100644
--- a/defs.h
+++ b/defs.h
@@ -134,7 +134,7 @@  extern char *stpcpy(char *dst, const char *src);
 # define LINUX_MIPS64
 #endif
 
-#if (defined(LINUXSPARC) || defined(X86_64) || defined(ARM) || defined(AVR32)) && defined(__GLIBC__)
+#if (defined(LINUXSPARC) || defined(X86_64) || defined(ARM) || defined(AARCH64) || defined(AVR32)) && defined(__GLIBC__)
 # include <sys/ptrace.h>
 #else
 /* Work around awkward prototype in ptrace.h. */
@@ -389,7 +389,8 @@  struct tcb {
 #if defined(ALPHA) || defined(AVR32) || defined(SPARC) || defined(SPARC64) \
   || defined(POWERPC) || defined(IA64) || defined(HPPA) \
   || defined(SH) || defined(SH64) || defined(S390) || defined(S390X) \
-  || defined(ARM) || defined(MIPS) || defined(BFIN) || defined(TILE)
+  || defined(ARM) || defined(AARCH64) || defined(MIPS) || defined(BFIN) \
+  || defined(TILE)
 /* This tracee has entered into execve syscall. Expect post-execve SIGTRAP
  * to happen. (When it is detected, tracee is continued and this bit is cleared.)
  */
diff --git a/ipc.c b/ipc.c
index f4ec522..0bde1cf 100644
--- a/ipc.c
+++ b/ipc.c
@@ -174,7 +174,7 @@  indirect_ipccall(struct tcb *tcp)
 #if defined IA64
 	return tcp->scno < 1024; /* ia32 emulation syscalls are low */
 #endif
-#if defined(ALPHA) || defined(MIPS) || defined(HPPA) || defined(__ARM_EABI__)
+#if defined(ALPHA) || defined(MIPS) || defined(HPPA) || defined(__ARM_EABI__) || defined(AARCH64)
 	return 0;
 #endif
 	return 1;
diff --git a/linux/aarch64/ioctlent.h.in b/linux/aarch64/ioctlent.h.in
new file mode 100644
index 0000000..83e6eb2
--- /dev/null
+++ b/linux/aarch64/ioctlent.h.in
@@ -0,0 +1 @@ 
+#include "../arm/ioctlent.h.in"
diff --git a/linux/aarch64/syscallent.h b/linux/aarch64/syscallent.h
new file mode 100644
index 0000000..9a30fbd
--- /dev/null
+++ b/linux/aarch64/syscallent.h
@@ -0,0 +1,330 @@ 
+	{ 2,	0,	sys_io_setup,			"io_setup"			}, /*    0 */
+	{ 1,	0,	sys_io_destroy,			"io_destroy"			}, /*    1 */
+	{ 3,	0,	sys_io_submit,			"io_submit"			}, /*    2 */
+	{ 3,	0,	sys_io_cancel,			"io_cancel"			}, /*    3 */
+	{ 5,	0,	sys_io_getevents,		"io_getevents"			}, /*    4 */
+	{ 5,	TF,	sys_setxattr,			"setxattr"			}, /*    5 */
+	{ 5,	TF,	sys_setxattr,			"lsetxattr"			}, /*    6 */
+	{ 5,	TD,	sys_fsetxattr,			"fsetxattr"			}, /*    7 */
+	{ 4,	TF,	sys_getxattr,			"getxattr"			}, /*    8 */
+	{ 4,	TF,	sys_getxattr,			"lgetxattr"			}, /*    9 */
+	{ 4,	TD,	sys_fgetxattr,			"fgetxattr"			}, /*   10 */
+	{ 3,	TF,	sys_listxattr,			"listxattr"			}, /*   11 */
+	{ 3,	TF,	sys_listxattr,			"llistxattr"			}, /*   12 */
+	{ 3,	TD,	sys_flistxattr,			"flistxattr"			}, /*   13 */
+	{ 2,	TF,	sys_removexattr,		"removexattr"			}, /*   14 */
+	{ 2,	TF,	sys_removexattr,		"lremovexattr"			}, /*   15 */
+	{ 2,	TD,	sys_fremovexattr,		"fremovexattr"			}, /*   16 */
+	{ 2,	TF,	sys_getcwd,			"getcwd"			}, /*   17 */
+	{ 4,	0,	sys_lookup_dcookie,		"lookup_dcookie"		}, /*   18 */
+	{ 2,	TD,	sys_eventfd2,			"eventfd2"			}, /*   19 */
+	{ 1,	TD,	sys_epoll_create1,		"epoll_create1"			}, /*   20 */
+	{ 4,	TD,	sys_epoll_ctl,			"epoll_ctl"			}, /*   21 */
+	{ 6,	TD,	sys_epoll_pwait,		"epoll_pwait"			}, /*   22 */
+	{ 1,	TD,	sys_dup,			"dup"				}, /*   23 */
+	{ 3,	TD,	sys_dup3,			"dup3"				}, /*   24 */
+	{ 3,	TD,	sys_fcntl,			"fcntl"				}, /*   25 */
+	{ 1,	TD,	sys_inotify_init1,		"inotify_init1"			}, /*   26 */
+	{ 3,	TD,	sys_inotify_add_watch,		"inotify_add_watch"		}, /*   27 */
+	{ 2,	TD,	sys_inotify_rm_watch,		"inotify_rm_watch"		}, /*   28 */
+	{ 3,	TD,	sys_ioctl,			"ioctl"				}, /*   29 */
+	{ 3,	0,	sys_ioprio_set,			"ioprio_set"			}, /*   30 */
+	{ 2,	0,	sys_ioprio_get,			"ioprio_get"			}, /*   31 */
+	{ 2,	TD,	sys_flock,			"flock"				}, /*   32 */
+	{ 4,	TD|TF,	sys_mknodat,			"mknodat"			}, /*   33 */
+	{ 3,	TD|TF,	sys_mkdirat,			"mkdirat"			}, /*   34 */
+	{ 3,	TD|TF,	sys_unlinkat,			"unlinkat"			}, /*   35 */
+	{ 3,	TD|TF,	sys_symlinkat,			"symlinkat"			}, /*   36 */
+	{ 5,	TD|TF,	sys_linkat,			"linkat"			}, /*   37 */
+	{ 4,	TD|TF,	sys_renameat,			"renameat"			}, /*   38 */
+	{ 2,	TF,	sys_umount2,			"umount2"			}, /*   39 */
+	{ 5,	TF,	sys_mount,			"mount"				}, /*   40 */
+	{ 2,	TF,	sys_pivotroot,			"pivot_root"			}, /*   41 */
+	{ 3,	0,	sys_nfsservctl,			"nfsservctl"			}, /*   42 */
+	{ 2,	TF,	sys_statfs,			"statfs64"			}, /*   43 */
+	{ 2,	TD,	sys_fstatfs,			"fstatfs64"			}, /*   44 */
+	{ 2,	TF,	sys_truncate,			"truncate64"			}, /*   45 */
+	{ 2,	TD,	sys_ftruncate,			"ftruncate64"			}, /*   46 */
+	{ 6,	TD,	sys_fallocate,			"fallocate"			}, /*   47 */
+	{ 3,	TD|TF,	sys_faccessat,			"faccessat"			}, /*   48 */
+	{ 1,	TF,	sys_chdir,			"chdir"				}, /*   49 */
+	{ 1,	TD,	sys_fchdir,			"fchdir"			}, /*   50 */
+	{ 1,	TF,	sys_chroot,			"chroot"			}, /*   51 */
+	{ 2,	TD,	sys_fchmod,			"fchmod"			}, /*   52 */
+	{ 3,	TD|TF,	sys_fchmodat,			"fchmodat"			}, /*   53 */
+	{ 5,	TD|TF,	sys_fchownat,			"fchownat"			}, /*   54 */
+	{ 3,	TD,	sys_fchown,			"fchown"			}, /*   55 */
+	{ 4,	TD|TF,	sys_openat,			"openat"			}, /*   56 */
+	{ 1,	TD,	sys_close,			"close"				}, /*   57 */
+	{ 0,	0,	sys_vhangup,			"vhangup"			}, /*   58 */
+	{ 2,	TD,	sys_pipe2,			"pipe2"				}, /*   59 */
+	{ 4,	0,	sys_quotactl,			"quotactl"			}, /*   60 */
+	{ 3,	TD,	sys_getdents64,			"getdents64"			}, /*   61 */
+	{ 3,	TD,	sys_lseek,			"lseek"				}, /*   62 */
+	{ 3,	TD,	sys_read,			"read"				}, /*   63 */
+	{ 3,	TD,	sys_write,			"write"				}, /*   64 */
+	{ 3,	TD,	sys_readv,			"readv"				}, /*   65 */
+	{ 3,	TD,	sys_writev,			"writev"			}, /*   66 */
+	{ 5,	TD,	sys_pread,			"pread64"			}, /*   67 */
+	{ 5,	TD,	sys_pwrite,			"pwrite64"			}, /*   68 */
+	{ 5,	TD,	sys_preadv,			"preadv"			}, /*   69 */
+	{ 5,	TD,	sys_pwritev,			"pwritev"			}, /*   70 */
+	{ 4,	TD|TN,	sys_sendfile,			"sendfile"			}, /*   71 */
+	{ 6,	TD,	sys_pselect6,			"pselect6"			}, /*   72 */
+	{ 5,	TD,	sys_ppoll,			"ppoll"				}, /*   73 */
+	{ 4,	TD|TS,	sys_signalfd4,			"signalfd4"			}, /*   74 */
+	{ 4,	TD,	sys_vmsplice,			"vmsplice"			}, /*   75 */
+	{ 6,	TD,	sys_splice,			"splice"			}, /*   76 */
+	{ 4,	TD,	sys_tee,			"tee"				}, /*   77 */
+	{ 4,	TD|TF,	sys_readlinkat,			"readlinkat"			}, /*   78 */
+	{ 4,	TD|TF,	sys_newfstatat,			"newfstatat"			}, /*   79 */
+	{ 2,	TD,	sys_fstat,			"fstat"				}, /*   80 */
+	{ 0,	0,	sys_sync,			"sync"				}, /*   81 */
+	{ 1,	TD,	sys_fsync,			"fsync"				}, /*   82 */
+	{ 1,	TD,	sys_fdatasync,			"fdatasync"			}, /*   83 */
+	{ 4,	TD,	sys_sync_file_range,		"sync_file_range"		}, /*   84 */
+	{ 2,	TD,	sys_timerfd_create,		"timerfd_create"		}, /*   85 */
+	{ 4,	TD,	sys_timerfd_settime,		"timerfd_settime"		}, /*   86 */
+	{ 2,	TD,	sys_timerfd_gettime,		"timerfd_gettime"		}, /*   87 */
+	{ 4,	TD|TF,	sys_utimensat,			"utimensat"			}, /*   88 */
+	{ 1,	TF,	sys_acct,			"acct"				}, /*   89 */
+	{ 2,	0,	sys_capget,			"capget"			}, /*   90 */
+	{ 2,	0,	sys_capset,			"capset"			}, /*   91 */
+	{ 1,	0,	sys_personality,		"personality"			}, /*   92 */
+	{ 1,	TP,	sys_exit,			"exit"				}, /*   93 */
+	{ 1,	TP,	sys_exit,			"exit_group"			}, /*   94 */
+	{ 5,	TP,	sys_waitid,			"waitid"			}, /*   95 */
+	{ 1,	0,	sys_set_tid_address,		"set_tid_address"		}, /*   96 */
+	{ 1,	TP,	sys_unshare,			"unshare"			}, /*   97 */
+	{ 6,	0,	sys_futex,			"futex"				}, /*   98 */
+	{ 2,	0,	sys_set_robust_list,		"set_robust_list"		}, /*   99 */
+	{ 3,	0,	sys_get_robust_list,		"get_robust_list"		}, /*  100 */
+	{ 2,	0,	sys_nanosleep,			"nanosleep"			}, /*  101 */
+	{ 2,	0,	sys_getitimer,			"getitimer"			}, /*  102 */
+	{ 3,	0,	sys_setitimer,			"setitimer"			}, /*  103 */
+	{ 4,	0,	sys_kexec_load,			"kexec_load"			}, /*  104 */
+	{ 3,	0,	sys_init_module,		"init_module"			}, /*  105 */
+	{ 2,	0,	sys_delete_module,		"delete_module"			}, /*  106 */
+	{ 3,	0,	sys_timer_create,		"timer_create"			}, /*  107 */
+	{ 2,	0,	sys_timer_gettime,		"timer_gettime"			}, /*  108 */
+	{ 1,	0,	sys_timer_getoverrun,		"timer_getoverrun"		}, /*  109 */
+	{ 4,	0,	sys_timer_settime,		"timer_settime"			}, /*  110 */
+	{ 1,	0,	sys_timer_delete,		"timer_delete"			}, /*  111 */
+	{ 2,	0,	sys_clock_settime,		"clock_settime"			}, /*  112 */
+	{ 2,	0,	sys_clock_gettime,		"clock_gettime"			}, /*  113 */
+	{ 2,	0,	sys_clock_getres,		"clock_getres"			}, /*  114 */
+	{ 4,	0,	sys_clock_nanosleep,		"clock_nanosleep"		}, /*  115 */
+	{ 3,	0,	sys_syslog,			"syslog"			}, /*  116 */
+	{ 4,	0,	sys_ptrace,			"ptrace"			}, /*  117 */
+	{ 0,	0,	sys_sched_setparam,		"sched_setparam"		}, /*  118 */
+	{ 3,	0,	sys_sched_setscheduler,		"sched_setscheduler"		}, /*  119 */
+	{ 1,	0,	sys_sched_getscheduler,		"sched_getscheduler"		}, /*  120 */
+	{ 2,	0,	sys_sched_getparam,		"sched_getparam"		}, /*  121 */
+	{ 3,	0,	sys_sched_setaffinity,		"sched_setaffinity"		}, /*  122 */
+	{ 3,	0,	sys_sched_getaffinity,		"sched_getaffinity"		}, /*  123 */
+	{ 0,	0,	sys_sched_yield,		"sched_yield"			}, /*  124 */
+	{ 1,	0,	sys_sched_get_priority_max,	"sched_get_priority_max"	}, /*  125 */
+	{ 1,	0,	sys_sched_get_priority_min,	"sched_get_priority_min"	}, /*  126 */
+	{ 2,	0,	sys_sched_rr_get_interval,	"sched_rr_get_interval"		}, /*  127 */
+	{ 0,	0,	sys_restart_syscall,		"restart_syscall"		}, /*  128 */
+	{ 2,	TS,	sys_kill,			"kill"				}, /*  129 */
+	{ 2,	TS,	sys_kill,			"tkill"				}, /*  130 */
+	{ 3,	TS,	sys_tgkill,			"tgkill"			}, /*  131 */
+	{ 2,	TS,	sys_sigaltstack,		"sigaltstack"			}, /*  132 */
+	{ 2,	TS,	sys_rt_sigsuspend,		"rt_sigsuspend"			}, /*  133 */
+	{ 4,	TS,	sys_rt_sigaction,		"rt_sigaction"			}, /*  134 */
+	{ 4,	TS,	sys_rt_sigprocmask,		"rt_sigprocmask"		}, /*  135 */
+	{ 2,	TS,	sys_rt_sigpending,		"rt_sigpending"			}, /*  136 */
+	{ 4,	TS,	sys_rt_sigtimedwait,		"rt_sigtimedwait"		}, /*  137 */
+	{ 3,	TS,	sys_rt_sigqueueinfo,		"rt_sigqueueinfo"		}, /*  138 */
+	{ 0,	TS,	sys_rt_sigreturn,		"rt_sigreturn"			}, /*  139 */
+	{ 3,	0,	sys_setpriority,		"setpriority"			}, /*  140 */
+	{ 2,	0,	sys_getpriority,		"getpriority"			}, /*  141 */
+	{ 4,	0,	sys_reboot,			"reboot"			}, /*  142 */
+	{ 2,	0,	sys_setregid,			"setregid"			}, /*  143 */
+	{ 1,	0,	sys_setgid,			"setgid"			}, /*  144 */
+	{ 2,	0,	sys_setreuid,			"setreuid"			}, /*  145 */
+	{ 1,	0,	sys_setuid,			"setuid"			}, /*  146 */
+	{ 3,	0,	sys_setresuid,			"setresuid"			}, /*  147 */
+	{ 3,	0,	sys_getresuid,			"getresuid"			}, /*  148 */
+	{ 3,	0,	sys_setresgid,			"setresgid"			}, /*  149 */
+	{ 3,	0,	sys_getresgid,			"getresgid"			}, /*  150 */
+	{ 1,	NF,	sys_setfsuid,			"setfsuid"			}, /*  151 */
+	{ 1,	NF,	sys_setfsgid,			"setfsgid"			}, /*  152 */
+	{ 1,	0,	sys_times,			"times"				}, /*  153 */
+	{ 2,	0,	sys_setpgid,			"setpgid"			}, /*  154 */
+	{ 1,	0,	sys_getpgid,			"getpgid"			}, /*  155 */
+	{ 1,	0,	sys_getsid,			"getsid"			}, /*  156 */
+	{ 0,	0,	sys_setsid,			"setsid"			}, /*  157 */
+	{ 2,	0,	sys_getgroups,			"getgroups"			}, /*  158 */
+	{ 2,	0,	sys_setgroups,			"setgroups"			}, /*  159 */
+	{ 1,	0,	sys_uname,			"uname"				}, /*  160 */
+	{ 2,	0,	sys_sethostname,		"sethostname"			}, /*  161 */
+	{ 2,	0,	sys_setdomainname,		"setdomainname"			}, /*  162 */
+	{ 2,	0,	sys_getrlimit,			"getrlimit"			}, /*  163 */
+	{ 2,	0,	sys_setrlimit,			"setrlimit"			}, /*  164 */
+	{ 2,	0,	sys_getrusage,			"getrusage"			}, /*  165 */
+	{ 1,	0,	sys_umask,			"umask"				}, /*  166 */
+	{ 5,	0,	sys_prctl,			"prctl"				}, /*  167 */
+	{ 3,	0,	sys_getcpu,			"getcpu"			}, /*  168 */
+	{ 2,	0,	sys_gettimeofday,		"gettimeofday"			}, /*  169 */
+	{ 2,	0,	sys_settimeofday,		"settimeofday"			}, /*  170 */
+	{ 1,	0,	sys_adjtimex,			"adjtimex"			}, /*  171 */
+	{ 0,	0,	sys_getpid,			"getpid"			}, /*  172 */
+	{ 0,	0,	sys_getppid,			"getppid"			}, /*  173 */
+	{ 0,	NF,	sys_getuid,			"getuid"			}, /*  174 */
+	{ 0,	NF,	sys_geteuid,			"geteuid"			}, /*  175 */
+	{ 0,	NF,	sys_getgid,			"getgid"			}, /*  176 */
+	{ 0,	NF,	sys_getegid,			"getegid"			}, /*  177 */
+	{ 0,	0,	sys_gettid,			"gettid"			}, /*  178 */
+	{ 1,	0,	sys_sysinfo,			"sysinfo"			}, /*  179 */
+	{ 4,	0,	sys_mq_open,			"mq_open"			}, /*  180 */
+	{ 1,	0,	sys_mq_unlink,			"mq_unlink"			}, /*  181 */
+	{ 5,	0,	sys_mq_timedsend,		"mq_timedsend"			}, /*  182 */
+	{ 5,	0,	sys_mq_timedreceive,		"mq_timedreceive"		}, /*  183 */
+	{ 2,	0,	sys_mq_notify,			"mq_notify"			}, /*  184 */
+	{ 3,	0,	sys_mq_getsetattr,		"mq_getsetattr"			}, /*  185 */
+	{ 4,	TI,	sys_msgget,			"msgget"			}, /*  186 */
+	{ 3,	TI,	sys_msgctl,			"msgctl"			}, /*  187 */
+	{ 5,	TI,	sys_msgrcv,			"msgrcv"			}, /*  188 */
+	{ 4,	TI,	sys_msgsnd,			"msgsnd"			}, /*  189 */
+	{ 4,	TI,	sys_semget,			"semget"			}, /*  190 */
+	{ 4,	TI,	sys_semctl,			"semctl"			}, /*  191 */
+	{ 5,	TI,	sys_semtimedop,			"semtimedop"			}, /*  192 */
+	{ 4,	TI,	sys_semop,			"semop"				}, /*  193 */
+	{ 4,	TI,	sys_shmget,			"shmget"			}, /*  194 */
+	{ 4,	TI,	sys_shmctl,			"shmctl"			}, /*  195 */
+	{ 4,	TI,	sys_shmat,			"shmat"				}, /*  196 */
+	{ 4,	TI,	sys_shmdt,			"shmdt"				}, /*  197 */
+	{ 3,	TN,	sys_socket,			"socket"			}, /*  198 */
+	{ 4,	TN,	sys_socketpair,			"socketpair"			}, /*  199 */
+	{ 3,	TN,	sys_bind,			"bind"				}, /*  200 */
+	{ 2,	TN,	sys_listen,			"listen"			}, /*  201 */
+	{ 3,	TN,	sys_accept,			"accept"			}, /*  202 */
+	{ 3,	TN,	sys_connect,			"connect"			}, /*  203 */
+	{ 3,	TN,	sys_getsockname,		"getsockname"			}, /*  204 */
+	{ 3,	TN,	sys_getpeername,		"getpeername"			}, /*  205 */
+	{ 6,	TN,	sys_sendto,			"sendto"			}, /*  206 */
+	{ 6,	TN,	sys_recvfrom,			"recvfrom"			}, /*  207 */
+	{ 5,	TN,	sys_setsockopt,			"setsockopt"			}, /*  208 */
+	{ 5,	TN,	sys_getsockopt,			"getsockopt"			}, /*  209 */
+	{ 2,	TN,	sys_shutdown,			"shutdown"			}, /*  210 */
+	{ 3,	TN,	sys_sendmsg,			"sendmsg"			}, /*  211 */
+	{ 5,	TN,	sys_recvmsg,			"recvmsg"			}, /*  212 */
+	{ 4,	TD,	sys_readahead,			"readahead"			}, /*  213 */
+	{ 1,	0,	sys_brk,			"brk"				}, /*  214 */
+	{ 2,	0,	sys_munmap,			"munmap"			}, /*  215 */
+	{ 5,	0,	sys_mremap,			"mremap"			}, /*  216 */
+	{ 5,	0,	sys_add_key,			"add_key"			}, /*  217 */
+	{ 4,	0,	sys_request_key,		"request_key"			}, /*  218 */
+	{ 5,	0,	sys_keyctl,			"keyctl"			}, /*  219 */
+	{ 5,	TP,	sys_clone,			"clone"				}, /*  220 */
+	{ 3,	TF|TP,	sys_execve,			"execve"			}, /*  221 */
+	{ 6,	TD,	sys_mmap,			"mmap"				}, /*  222 */
+	{ 4,	TD,	sys_fadvise64,			"fadvise64"			}, /*  223 */
+	{ 2,	TF,	sys_swapon,			"swapon"			}, /*  224 */
+	{ 1,	TF,	sys_swapoff,			"swapoff"			}, /*  225 */
+	{ 3,	0,	sys_mprotect,			"mprotect"			}, /*  226 */
+	{ 3,	0,	sys_msync,			"msync"				}, /*  227 */
+	{ 3,	0,	sys_msync,			"msync"				}, /*  228 */
+	{ 2,	0,	sys_munlock,			"munlock"			}, /*  229 */
+	{ 1,	0,	sys_mlockall,			"mlockall"			}, /*  230 */
+	{ 0,	0,	sys_munlockall,			"munlockall"			}, /*  231 */
+	{ 3,	0,	sys_mincore,			"mincore"			}, /*  232 */
+	{ 3,	0,	sys_madvise,			"madvise"			}, /*  233 */
+	{ 5,	0,	sys_remap_file_pages,		"remap_file_pages"		}, /*  234 */
+	{ 6,	0,	sys_mbind,			"mbind"				}, /*  235 */
+	{ 5,	0,	sys_get_mempolicy,		"get_mempolicy"			}, /*  236 */
+	{ 3,	0,	sys_set_mempolicy,		"set_mempolicy"			}, /*  237 */
+	{ 4,	0,	sys_migrate_pages,		"migrate_pages"			}, /*  238 */
+	{ 6,	0,	sys_move_pages,			"move_pages"			}, /*  239 */
+	{ 4,	TP|TS,	sys_rt_tgsigqueueinfo,		"rt_tgsigqueueinfo"		}, /*  240 */
+	{ 5,	TD,	sys_perf_event_open,		"perf_event_open"		}, /*  241 */
+	{ 4,	TN,	sys_accept4,			"accept4"			}, /*  242 */
+	{ 5,	TN,	sys_recvmmsg,			"recvmmsg"			}, /*  243 */
+
+	/* Arch-specific block, not used on AArch64 */
+	[244 ... 259] = { },
+
+	{ 4,	TP,	sys_wait4,			"wait4"				}, /*  260 */
+	{ 4,	0,	sys_prlimit64,			"prlimit64"			}, /*  261 */
+	{ 2,	TD,	sys_fanotify_init,		"fanotify_init"			}, /*  262 */
+	{ 5,	TD|TF,	sys_fanotify_mark,		"fanotify_mark"			}, /*  263 */
+	{ 5,	TD|TF,	sys_name_to_handle_at,		"name_to_handle_at"		}, /*  264 */
+	{ 3,	TD,	sys_open_by_handle_at,		"open_by_handle_at"		}, /*  265 */
+	{ 2,	0,	sys_clock_adjtime,		"clock_adjtime"			}, /*  266 */
+	{ 1,	TD,	sys_syncfs,			"syncfs"			}, /*  267 */
+	{ 2,	TD,	sys_setns,			"setns"				}, /*  268 */
+	{ 4,	TN,	sys_sendmmsg,			"sendmmsg"			}, /*  269 */
+	{ 6,	0,	sys_process_vm_readv,		"process_vm_readv"		}, /*  270 */
+	{ 6,	0,	sys_process_vm_writev,		"process_vm_writev"		}, /*  271 */
+
+	/* Blank down to 1023 */
+	[272 ... 1023] = { },
+
+	/* Quote from asm-generic/unistd.h:
+	 *
+	 * All syscalls below here should go away really,
+	 * these are provided for both review and as a porting
+	 * help for the C library version.
+	 *
+	 * Last chance: are any of these important enough to
+	 * enable by default?
+	 */
+
+	{ 3,	TD|TF,	sys_open,			"open"				}, /* 1024 */
+	{ 2,	TF,	sys_link,			"link"				}, /* 1025 */
+	{ 1,	TF,	sys_unlink,			"unlink"			}, /* 1026 */
+	{ 3,	TF,	sys_mknod,			"mknod"				}, /* 1027 */
+	{ 2,	TF,	sys_chmod,			"chmod"				}, /* 1028 */
+	{ 3,	TF,	sys_chown,			"chown"				}, /* 1029 */
+	{ 2,	TF,	sys_mkdir,			"mkdir"				}, /* 1030 */
+	{ 1,	TF,	sys_rmdir,			"rmdir"				}, /* 1031 */
+	{ 3,	TF,	sys_chown,			"lchown"			}, /* 1032 */
+	{ 2,	TF,	sys_access,			"access"			}, /* 1033 */
+	{ 2,	TF,	sys_rename,			"rename"			}, /* 1034 */
+	{ 3,	TF,	sys_readlink,			"readlink"			}, /* 1035 */
+	{ 2,	TF,	sys_symlink,			"symlink"			}, /* 1036 */
+	{ 2,	TF,	sys_utimes,			"utimes"			}, /* 1037 */
+	{ 2,	TF,	sys_stat,			"stat"				}, /* 1038 */
+	{ 2,	TF,	sys_lstat,			"lstat"				}, /* 1039 */
+	{ 1,	TD,	sys_pipe,			"pipe"				}, /* 1040 */
+	{ 2,	TD,	sys_dup2,			"dup2"				}, /* 1041 */
+	{ 1,	TD,	sys_epoll_create,		"epoll_create"			}, /* 1042 */
+	{ 0,	TD,	sys_inotify_init,		"inotify_init"			}, /* 1043 */
+	{ 1,	TD,	sys_eventfd,			"eventfd"			}, /* 1044 */
+	{ 3,	TD|TS,	sys_signalfd,			"signalfd"			}, /* 1045 */
+	{ 4,	TD|TN,	sys_sendfile,			"sendfile"			}, /* 1046 */
+	{ 2,	TD,	sys_ftruncate,			"ftruncate"			}, /* 1047 */
+	{ 2,	TF,	sys_truncate,			"truncate"			}, /* 1048 */
+	{ 2,	TF,	sys_stat,			"stat"				}, /* 1049 */
+	{ 2,	TF,	sys_lstat,			"lstat"				}, /* 1050 */
+	{ 2,	TD,	sys_fstat,			"fstat"				}, /* 1051 */
+	{ 3,	TD,	sys_fcntl,			"fcntl"				}, /* 1052 */
+	{ 4,	TD,	sys_fadvise64,			"fadvise64"			}, /* 1053 */
+	{ 4,	TD|TF,	sys_newfstatat,			"newfstatat"			}, /* 1054 */
+	{ 2,	TD,	sys_fstatfs,			"fstatfs"			}, /* 1055 */
+	{ 2,	TF,	sys_statfs,			"statfs"			}, /* 1056 */
+	{ 3,	TD,	sys_lseek,			"lseek"				}, /* 1057 */
+	{ 6,	TD,	sys_mmap,			"mmap"				}, /* 1058 */
+	{ 1,	0,	sys_alarm,			"alarm"				}, /* 1059 */
+	{ 0,	0,	sys_getpgrp,			"getpgrp"			}, /* 1060 */
+	{ 0,	TS,	sys_pause,			"pause"				}, /* 1061 */
+	{ 1,	0,	sys_time,			"time"				}, /* 1062 */
+	{ 2,	TF,	sys_utime,			"utime"				}, /* 1063 */
+	{ 2,	TD|TF,	sys_creat,			"creat"				}, /* 1064 */
+	{ 3,	TD,	sys_getdents,			"getdents"			}, /* 1065 */
+	{ 3,	TD|TF,	sys_futimesat,			"futimesat"			}, /* 1066 */
+	{ 5,	TD,	sys_select,			"select"			}, /* 1067 */
+	{ 3,	TD,	sys_poll,			"poll"				}, /* 1068 */
+	{ 4,	TD,	sys_epoll_wait,			"epoll_wait"			}, /* 1069 */
+	{ 2,	0,	sys_ustat,			"ustat"				}, /* 1070 */
+	{ 0,	TP,	sys_vfork,			"vfork"				}, /* 1071 */
+	{ 4,	TP,	sys_wait4,			"wait4"				}, /* 1072 */
+	{ 6,	TN,	sys_recv,			"recv"				}, /* 1073 */
+	{ 4,	TD|TN,	sys_send,			"send"				}, /* 1074 */
+	{ 2,	0,	sys_bdflush,			"bdflush"			}, /* 1075 */
+	{ 2,	TF,	sys_umount,			"umount"			}, /* 1076 */
+	{ 1,	TF,	sys_uselib,			"uselib"			}, /* 1077 */
+	{ 1,	0,	sys_sysctl,			"sysctl"			}, /* 1078 */
+	{ 0,	TP,	sys_fork,			"fork"				}, /* 1079 */
diff --git a/process.c b/process.c
index fa304e5..467c096 100644
--- a/process.c
+++ b/process.c
@@ -2119,7 +2119,8 @@  const struct xlat struct_user_offsets[] = {
 
 #if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
 		&& !defined(ALPHA) && !defined(IA64) \
-		&& !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE)
+		&& !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE) \
+		&& !defined(AARCH64)
 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
 	{ uoff(u_fpvalid),	"offsetof(struct user, u_fpvalid)"	},
 # endif
@@ -2148,7 +2149,7 @@  const struct xlat struct_user_offsets[] = {
 # if !defined(SPARC64)
 	{ uoff(u_ar0),		"offsetof(struct user, u_ar0)"		},
 # endif
-# if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
+# if !defined(ARM) && !defined(AARCH64) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
 	{ uoff(u_fpstate),	"offsetof(struct user, u_fpstate)"	},
 # endif
 	{ uoff(magic),		"offsetof(struct user, magic)"		},
@@ -2158,7 +2159,7 @@  const struct xlat struct_user_offsets[] = {
 # endif
 #endif /* !defined(many arches) */
 
-#ifndef HPPA
+#if !defined(HPPA) && !defined(AARCH64)
 	{ sizeof(struct user),	"sizeof(struct user)"			},
 #endif
 	{ 0,			NULL					},
diff --git a/syscall.c b/syscall.c
index c4c5e86..0caeaae 100644
--- a/syscall.c
+++ b/syscall.c
@@ -65,6 +65,12 @@ 
 # include <asm/rse.h>
 #endif
 
+#if defined(AARCH64)
+# include <asm/ptrace.h>
+# include <sys/uio.h>
+# include <elf.h>
+#endif
+
 #ifndef ERESTARTSYS
 # define ERESTARTSYS	512
 #endif
@@ -653,6 +659,8 @@  static long d0;
 static long r0;
 #elif defined(ARM)
 static struct pt_regs regs;
+#elif defined(AARCH64)
+static struct user_pt_regs regs;
 #elif defined(ALPHA)
 static long r0;
 static long a3;
@@ -963,6 +971,13 @@  get_scno(struct tcb *tcp)
 		fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
 		tcp->flags |= TCB_INSYSCALL;
 	}
+#elif defined(AARCH64)
+	struct iovec io;
+	io.iov_base = &regs;
+	io.iov_len = sizeof(regs);
+	if (ptrace(PTRACE_GETREGSET, tcp->pid, NT_PRSTATUS, (void *)&io) == -1)
+		return -1;
+	scno = regs.regs[8];
 #elif defined(M68K)
 	if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
 		return -1;
@@ -1399,6 +1414,9 @@  get_syscall_args(struct tcb *tcp)
 #elif defined(ARM)
 	for (i = 0; i < nargs; ++i)
 		tcp->u_arg[i] = regs.uregs[i];
+#elif defined(AARCH64)
+	for (i = 0; i < nargs; ++i)
+		tcp->u_arg[i] = regs.regs[i];
 #elif defined(AVR32)
 	(void)i;
 	(void)nargs;
@@ -1637,6 +1655,12 @@  get_syscall_result(struct tcb *tcp)
 	/* Read complete register set in one go. */
 	if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)&regs) == -1)
 		return -1;
+#elif defined(AARCH64)
+	struct iovec io;
+	io.iov_base = &regs;
+	io.iov_len = sizeof(regs);
+	if (ptrace(PTRACE_GETREGSET, tcp->pid, NT_PRSTATUS, (void *)&io) == -1)
+		return -1;
 #elif defined(M68K)
 	if (upeek(tcp, 4*PT_D0, &d0) < 0)
 		return -1;
@@ -1819,6 +1843,14 @@  get_error(struct tcb *tcp)
 	else {
 		tcp->u_rval = regs.ARM_r0;
 	}
+#elif defined(AARCH64)
+	if (check_errno && is_negated_errno(regs.regs[0])) {
+		tcp->u_rval = -1;
+		u_error = -regs.regs[0];
+	}
+	else {
+		tcp->u_rval = regs.regs[0];
+	}
 #elif defined(AVR32)
 	if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) {
 		tcp->u_rval = -1;