Add x32 support to strace

X32 support is added to Linux kernel 3.4. In a nutshell, x32 is x86-64 with
32bit pointers.  At system call level, x32 is also identical to x86-64,
as shown by many changes like "defined(X86_64) || defined(X32)".  The
main differerence bewteen x32 and x86-64 is off_t in x32 is long long
instead of long.

This patch adds x32 support to strace.  Tested on Linux/x32.

* configure.ac: Support X32.
* defs.h: Set SUPPORTED_PERSONALITIES to 3 for X86_64,
Set PERSONALITY2_WORDSIZE to 4 for X86_64.
Add tcb::ext_arg for X32.
* file.c (stat): New for X32.
(sys_lseek): Use 64-bit version for X32.
(printstat64): Check current_personality != 1 for X86_64.
* ipc.c (indirect_ipccall): Check current_personality == 1
for X86_64.
* mem.c (sys_mmap64): Also use tcp->u_arg for X32.  Print NULL
for zero address.  Call printllval for offset for X32.
* pathtrace.c (pathtrace_match): Don't check sys_old_mmap for
X32.
* process.c (ARG_FLAGS): Defined for X32.
(ARG_STACK): Likewise.
(ARG_PTID): Likewise.
(change_syscall): Handle X32.
(struct_user_offsets): Support X32.
(sys_arch_prctl): Likewise.
* signal.c: Include <asm/sigcontext.h> for X32.
(SA_RESTORER): Also define for X32.
* syscall.c (update_personality): Support X32 for X86_64.
(is_restart_error): Likewise.
(syscall_fixup_on_sysenter): Likewise.
(get_syscall_args): Likewise.
(get_syscall_result): Likewise.
(get_error): Likewise.
(__X32_SYSCALL_BIT): Define if not defined.
(__X32_SYSCALL_MASK): Likewise.
(get_scno): Check DS register value for X32.  Use
__X32_SYSCALL_MASK on X32 system calls.
* util.c (printllval): Use ext_arg for X32.
(printcall): Support X32.
(change_syscall): Likewise.
(arg0_offset): Likewise.
(arg1_offset): Likewise.
* Makefile.am (EXTRA_DIST): Add linux/x32/errnoent.h,
linux/x32/ioctlent.h.in, linux/x32/signalent.h,
linux/x32/syscallent.h, linux/x86_64/errnoent2.h,
linux/x86_64/ioctlent2.h, linux/x86_64/signalent2.h and
linux/x86_64/syscallent2.h.
* linux/x32/errnoent.h: New.
* linux/x32/ioctlent.h.in: Likewise.
* linux/x32/signalent.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/errnoent2.h: Likewise.
* linux/x86_64/ioctlent2.h: Likewise.
* linux/x86_64/signalent2.h: Likewise.
* linux/x86_64/syscallent2.h: Likewise.

Signed-off-by: H.J. Lu <hongjiu.lu@intel.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/util.c b/util.c
index 348d77f..6588de2 100644
--- a/util.c
+++ b/util.c
@@ -212,7 +212,7 @@
 # elif defined IA64 || defined ALPHA
 	tprintf(format, tcp->u_arg[llarg]);
 	llarg++;
-# elif defined LINUX_MIPSN32
+# elif defined LINUX_MIPSN32 || defined X32
 	tprintf(format, tcp->ext_arg[llarg]);
 	llarg++;
 # else
@@ -997,7 +997,7 @@
 	tprintf("[%16lx] ", psw);
 # endif
 
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
 	long rip;
 
 	if (upeek(tcp, 8*RIP, &rip) < 0) {
@@ -1151,7 +1151,7 @@
 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
 		return -1;
 	return 0;
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
 		return -1;
 	return 0;
@@ -1392,7 +1392,7 @@
 # elif defined(HPPA)
 #  define arg0_offset	PT_GR26
 #  define arg1_offset	(PT_GR26-4)
-# elif defined(X86_64)
+# elif defined(X86_64) || defined(X32)
 #  define arg0_offset	((long)(8*(current_personality ? RBX : RDI)))
 #  define arg1_offset	((long)(8*(current_personality ? RCX : RSI)))
 # elif defined(SH)