x32: add ia32 support

* Makefile.am (EXTRA_DIST): Add linux/x32/errnoent1.h,
linux/x32/ioctlent1.h, linux/x32/signalent1.h and
linux/x32/syscallent1.h.
* configure.ac: Remove AC_GNU_SOURCE, obsoleted by
AC_USE_SYSTEM_EXTENSIONS.
* defs.h (SUPPORTED_PERSONALITIES): Set to 2 for X32.
(PERSONALITY1_WORDSIZE): Set to 4 for X32.
* file.c (stat64): New struct for X32.
(sys_lseek32): New function for X32.
(stat64): Undef.
(sys_fstat64): Likewise.
(sys_stat64): Likewise.
(realprintstat64): New function for X32.
(sys_fstat64): Likewise.
(sys_stat64): Likewise.
* mem.c (sys_old_mmap): New function for X32.
* pathtrace.c (pathtrace_match): Also check sys_old_mmap for X32.
* syscall.c (update_personality): Add X32 support.
(get_scno): Support currpers == 1 for X32.
* linux/syscall.h (sys_lseek32): New function prototype for X32.
* linux/x32/errnoent1.h: New file.
* linux/x32/ioctlent1.h: Likewise.
* linux/x32/signalent1.h: Likewise.
* linux/x32/syscallent1.h: Likewise.
diff --git a/file.c b/file.c
index 5f3b506..0cda7e1 100644
--- a/file.c
+++ b/file.c
@@ -96,6 +96,28 @@
 	unsigned long long	st_ctime_nsec;
 	long long		__unused[3];
 };
+
+struct stat64 {
+	unsigned long long	st_dev;
+	unsigned char		__pad0[4];
+	unsigned long		__st_ino;
+	unsigned int		st_mode;
+	unsigned int		st_nlink;
+	unsigned long		st_uid;
+	unsigned long		st_gid;
+	unsigned long long	st_rdev;
+	unsigned char		__pad3[4];
+	long long		st_size;
+	unsigned long		st_blksize;
+	unsigned long long	st_blocks;
+	unsigned long		st_atime;
+	unsigned long		st_atime_nsec;
+	unsigned long		st_mtime;
+	unsigned int		st_mtime_nsec;
+	unsigned long		st_ctime;
+	unsigned long		st_ctime_nsec;
+	unsigned long long	st_ino;
+};
 #else
 # undef dev_t
 # undef ino_t
@@ -521,6 +543,28 @@
 	}
 	return RVAL_LUDECIMAL;
 }
+
+# if defined(X32)
+int
+sys_lseek32(struct tcb *tcp)
+{
+	long offset;
+	int _whence;
+
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+		offset = tcp->u_arg[1];
+		_whence = tcp->u_arg[2];
+		if (_whence == SEEK_SET)
+			tprintf("%lu, ", offset);
+		else
+			tprintf("%ld, ", offset);
+		printxval(whence, _whence, "SEEK_???");
+	}
+	return RVAL_UDECIMAL;
+}
+# endif
 #else
 int
 sys_lseek(struct tcb *tcp)
@@ -2722,3 +2766,88 @@
 	}
 	return 0;
 }
+
+#ifdef X32
+# undef stat64
+# undef sys_fstat64
+# undef sys_stat64
+
+static void
+realprintstat64(struct tcb *tcp, long addr)
+{
+	struct stat64 statbuf;
+
+	if (!addr) {
+		tprints("NULL");
+		return;
+	}
+	if (syserror(tcp) || !verbose(tcp)) {
+		tprintf("%#lx", addr);
+		return;
+	}
+
+	if (umove(tcp, addr, &statbuf) < 0) {
+		tprints("{...}");
+		return;
+	}
+
+	if (!abbrev(tcp)) {
+		tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
+			(unsigned long) major(statbuf.st_dev),
+			(unsigned long) minor(statbuf.st_dev),
+			(unsigned long long) statbuf.st_ino,
+			sprintmode(statbuf.st_mode));
+		tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
+			(unsigned long) statbuf.st_nlink,
+			(unsigned long) statbuf.st_uid,
+			(unsigned long) statbuf.st_gid);
+		tprintf("st_blksize=%lu, ",
+			(unsigned long) statbuf.st_blksize);
+		tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
+	}
+	else
+		tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
+	switch (statbuf.st_mode & S_IFMT) {
+	case S_IFCHR: case S_IFBLK:
+		tprintf("st_rdev=makedev(%lu, %lu), ",
+			(unsigned long) major(statbuf.st_rdev),
+			(unsigned long) minor(statbuf.st_rdev));
+		break;
+	default:
+		tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
+		break;
+	}
+	if (!abbrev(tcp)) {
+		tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
+		tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
+		tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
+		tprints("}");
+	}
+	else
+		tprints("...}");
+}
+
+int
+sys_fstat64(struct tcb *tcp)
+{
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		realprintstat64(tcp, tcp->u_arg[1]);
+	}
+	return 0;
+}
+
+int
+sys_stat64(struct tcb *tcp)
+{
+	if (entering(tcp)) {
+		printpath(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		realprintstat64(tcp, tcp->u_arg[1]);
+	}
+	return 0;
+}
+#endif