]> granicus.if.org Git - strace/commitdiff
Add x32 support to strace
authorH.J. Lu <hongjiu.lu@intel.com>
Mon, 16 Apr 2012 11:00:01 +0000 (13:00 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 16 Apr 2012 11:00:01 +0000 (13:00 +0200)
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>
19 files changed:
Makefile.am
configure.ac
defs.h
file.c
ipc.c
linux/x32/errnoent.h [new file with mode: 0644]
linux/x32/ioctlent.h.in [new file with mode: 0644]
linux/x32/signalent.h [new file with mode: 0644]
linux/x32/syscallent.h [new file with mode: 0644]
linux/x86_64/errnoent2.h [new file with mode: 0644]
linux/x86_64/ioctlent2.h [new file with mode: 0644]
linux/x86_64/signalent2.h [new file with mode: 0644]
linux/x86_64/syscallent2.h [new file with mode: 0644]
mem.c
pathtrace.c
process.c
signal.c
syscall.c
util.c

index 8edcf8905d9e8c0e3235d003debdc06ce1f2f5b4..bbc5790b2ee0160e688ce9b3d0a85f7e5afe2ed2 100644 (file)
@@ -78,10 +78,14 @@ EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \
             linux/sparc64/syscallent.h linux/sparc64/syscallent1.h \
             linux/sparc64/syscallent2.h \
             linux/tile/ioctlent.h.in linux/tile/syscallent.h \
+            linux/x32/errnoent.h linux/x32/ioctlent.h.in \
+            linux/x32/signalent.h linux/x32/syscallent.h \
             linux/x86_64/ioctlent.h.in linux/x86_64/syscallent.h \
             linux/x86_64/gentab.pl \
             linux/x86_64/errnoent1.h linux/x86_64/ioctlent1.h \
             linux/x86_64/signalent1.h linux/x86_64/syscallent1.h \
+            linux/x86_64/errnoent2.h linux/x86_64/ioctlent2.h \
+            linux/x86_64/signalent2.h linux/x86_64/syscallent2.h \
             xlate.el
 
 .PHONY: srpm
index 86d1de260fed9494bf791fea747d49dcc2aac30b..f55b8a204a85511782c433d76eda87d638478268 100644 (file)
@@ -8,6 +8,11 @@ AM_INIT_AUTOMAKE([foreign check-news dist-xz no-dist-gzip silent-rules])
 AM_MAINTAINER_MODE
 AC_CANONICAL_HOST
 
+AC_PROG_CC
+AC_GNU_SOURCE
+
+AC_USE_SYSTEM_EXTENSIONS
+
 AC_MSG_CHECKING([for supported architecture])
 case "$host_cpu" in
 bfin)
@@ -78,8 +83,15 @@ sh*)
        AC_DEFINE([SH], 1, [Define for the SH architecture.])
        ;;
 x86?64*)
-       arch=x86_64
-       AC_DEFINE([X86_64], 1, [Define for the AMD x86-64 architecture.])
+       AC_TRY_COMPILE(
+[#ifndef __ILP32__
+# error not x32
+#endif], [], arch=x32, arch=x86_64)
+       if test "$arch" = "x86_64"; then
+               AC_DEFINE([X86_64], 1, [Define for the 64bit AMD x86-64 architecture.])
+       else
+               AC_DEFINE([X32], 1, [Define for the 32bit AMD x86-64 architecture.])
+       fi
        ;;
 cris|crisv10)
        arch=crisv10
@@ -108,9 +120,7 @@ AC_SUBST(arch)
 
 AM_CONDITIONAL([I386], [test x$arch = xi386])
 AM_CONDITIONAL([X86_64], [test x$arch = xx86_64])
-
-AC_PROG_CC
-AC_GNU_SOURCE
+AM_CONDITIONAL([X32], [test x$arch = xx32])
 
 AC_INCLUDEDIR
 
diff --git a/defs.h b/defs.h
index 7cf91b730674fb8cb0f06fe5ef8ccfb28b561021..50a54dd203026a6536d729089580f6059610588e 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -153,7 +153,7 @@ extern long ptrace(int, int, char *, long);
 # define PTRACE_PEEKUSER PTRACE_PEEKUSR
 # define PTRACE_POKEUSER PTRACE_POKEUSR
 #endif
-#if defined(X86_64) || defined(I386)
+#if defined(X86_64) || defined(X32) || defined(I386)
 /* For struct pt_regs. x86 strace uses PTRACE_GETREGS.
  * PTRACE_GETREGS returns registers in the layout of this struct.
  */
@@ -221,9 +221,10 @@ extern long ptrace(int, int, char *, long);
 
 #ifdef X86_64
 # undef SUPPORTED_PERSONALITIES
-# define SUPPORTED_PERSONALITIES 2
+# define SUPPORTED_PERSONALITIES 3
 # define PERSONALITY0_WORDSIZE 8
 # define PERSONALITY1_WORDSIZE 4
+# define PERSONALITY2_WORDSIZE 4
 #endif
 
 #ifdef ARM
@@ -324,7 +325,7 @@ struct tcb {
        int u_error;            /* Error code */
        long scno;              /* System call number */
        long u_arg[MAX_ARGS];   /* System call arguments */
-#if defined(LINUX_MIPSN32)
+#if defined(LINUX_MIPSN32) || defined(X32)
        long long ext_arg[MAX_ARGS];    /* System call arguments */
 #endif
        long u_rval;            /* return value */
diff --git a/file.c b/file.c
index fa4b3149b63d3bed1cacc2f3ed9fa1b1909f444f..58585f382edfa6269b05c9cbc68603a6f868dc37 100644 (file)
--- a/file.c
+++ b/file.c
@@ -73,6 +73,29 @@ struct stat_sparc64 {
 # define stat kernel_stat
 # include <asm/stat.h>
 # undef stat
+#elif defined(X32)
+struct stat {
+       unsigned long long      st_dev;
+       unsigned long long      st_ino;
+       unsigned long long      st_nlink;
+
+       unsigned int            st_mode;
+       unsigned int            st_uid;
+       unsigned int            st_gid;
+       unsigned int            __pad0;
+       unsigned long long      st_rdev;
+       long long               st_size;
+       long long               st_blksize;
+       long long               st_blocks;
+
+       unsigned long long      st_atime;
+       unsigned long long      st_atime_nsec;
+       unsigned long long      st_mtime;
+       unsigned long long      st_mtime_nsec;
+       unsigned long long      st_ctime;
+       unsigned long long      st_ctime_nsec;
+       long long               __unused[3];
+};
 #else
 # undef dev_t
 # undef ino_t
@@ -1032,7 +1055,7 @@ printstat64(struct tcb *tcp, long addr)
 #endif /* LINUXSPARC */
 
 #if defined X86_64
-       if (current_personality == 0) {
+       if (current_personality != 1) {
                printstat(tcp, addr);
                return;
        }
diff --git a/ipc.c b/ipc.c
index 34e32a37f10672a1516e55c2db3c813a3a4a9dda..f4ec522e60e2cc76c5b11c56b6c4f59464969a33 100644 (file)
--- a/ipc.c
+++ b/ipc.c
@@ -169,7 +169,7 @@ static int
 indirect_ipccall(struct tcb *tcp)
 {
 #ifdef X86_64
-       return current_personality > 0;
+       return current_personality == 1;
 #endif
 #if defined IA64
        return tcp->scno < 1024; /* ia32 emulation syscalls are low */
diff --git a/linux/x32/errnoent.h b/linux/x32/errnoent.h
new file mode 100644 (file)
index 0000000..441c66b
--- /dev/null
@@ -0,0 +1 @@
+#include "../errnoent.h"
diff --git a/linux/x32/ioctlent.h.in b/linux/x32/ioctlent.h.in
new file mode 100644 (file)
index 0000000..52ac99b
--- /dev/null
@@ -0,0 +1 @@
+#include "../i386/ioctlent.h.in"
diff --git a/linux/x32/signalent.h b/linux/x32/signalent.h
new file mode 100644 (file)
index 0000000..d31e6a4
--- /dev/null
@@ -0,0 +1 @@
+#include "../signalent.h"
diff --git a/linux/x32/syscallent.h b/linux/x32/syscallent.h
new file mode 100644 (file)
index 0000000..fcb6a23
--- /dev/null
@@ -0,0 +1,344 @@
+       { 3,    TD,     sys_read,               "read"          },  /* 0 */
+       { 3,    TD,     sys_write,              "write"         },  /* 1 */
+       { 3,    TD|TF,  sys_open,               "open"          },  /* 2 */
+       { 1,    TD,     sys_close,              "close"         },  /* 3 */
+       { 2,    TF,     sys_stat,               "stat"          },  /* 4 */
+       { 2,    TD,     sys_fstat,              "fstat"         },  /* 5 */
+       { 2,    TF,     sys_lstat,              "lstat"         },  /* 6 */
+       { 3,    TD,     sys_poll,               "poll"          },  /* 7 */
+       { 3,    TD,     sys_lseek,              "lseek"         },  /* 8 */
+       { 6,    TD,     sys_mmap,               "mmap"          },  /* 9 */
+       { 3,    0,      sys_mprotect,           "mprotect"      },  /* 10 */
+       { 2,    0,      sys_munmap,             "munmap"        },  /* 11 */
+       { 1,    0,      sys_brk,                "brk"           },  /* 12 */
+       { },                                                        /* 13 */
+       { 4,    TS,     sys_rt_sigprocmask,     "rt_sigprocmask"},  /* 14 */
+       { },                                                        /* 15 */
+       { },                                                        /* 16 */
+       { 5,    TD,     sys_pread,              "pread"         },  /* 17 */
+       { 5,    TD,     sys_pwrite,             "pwrite"        },  /* 18 */
+       { },                                                        /* 19 */
+       { },                                                        /* 20 */
+       { 2,    TF,     sys_access,             "access"        },  /* 21 */
+       { 1,    TD,     sys_pipe,               "pipe"          },  /* 22 */
+       { 5,    TD,     sys_select,             "select"        },  /* 23 */
+       { 0,    0,      sys_sched_yield,        "sched_yield"   },  /* 24 */
+       { 5,    0,      sys_mremap,             "mremap"        },  /* 25 */
+       { 3,    0,      sys_msync,              "msync"         },  /* 26 */
+       { 3,    0,      sys_mincore,            "mincore"       },  /* 27 */
+       { 3,    0,      sys_madvise,            "madvise"       },  /* 28 */
+       { 4,    TI,     sys_shmget,             "shmget"        },  /* 29 */
+       { 4,    TI,     sys_shmat,              "shmat"         },  /* 30 */
+       { 4,    TI,     sys_shmctl,             "shmctl"        },  /* 31 */
+       { 1,    TD,     sys_dup,                "dup"           },  /* 32 */
+       { 2,    TD,     sys_dup2,               "dup2"          },  /* 33 */
+       { 0,    TS,     sys_pause,              "pause"         },  /* 34 */
+       { 2,    0,      sys_nanosleep,          "nanosleep"     },  /* 35 */
+       { 2,    0,      sys_getitimer,          "getitimer"     },  /* 36 */
+       { 1,    0,      sys_alarm,              "alarm"         },  /* 37 */
+       { 3,    0,      sys_setitimer,          "setitimer"     },  /* 38 */
+       { 0,    0,      sys_getpid,             "getpid"        },  /* 39 */
+       { 4,    TD|TN,  sys_sendfile,           "sendfile"      },  /* 40 */
+       { 3,    TN,     sys_socket,             "socket"        },  /* 41 */
+       { 3,    TN,     sys_connect,            "connect"       },  /* 42 */
+       { 3,    TN,     sys_accept,             "accept"        },  /* 43 */
+       { 6,    TN,     sys_sendto,             "sendto"        },  /* 44 */
+       { },                                                        /* 45 */
+       { },                                                        /* 46 */
+       { },                                                        /* 47 */
+       { 2,    TN,     sys_shutdown,           "shutdown"      },  /* 48 */
+       { 3,    TN,     sys_bind,               "bind"          },  /* 49 */
+       { 2,    TN,     sys_listen,             "listen"        },  /* 50 */
+       { 3,    TN,     sys_getsockname,        "getsockname"   },  /* 51 */
+       { 3,    TN,     sys_getpeername,        "getpeername"   },  /* 52 */
+       { 4,    TN,     sys_socketpair,         "socketpair"    },  /* 53 */
+       { 5,    TN,     sys_setsockopt,         "setsockopt"    },  /* 54 */
+       { 5,    TN,     sys_getsockopt,         "getsockopt"    },  /* 55 */
+       { 5,    TP,     sys_clone,              "clone"         },  /* 56 */
+       { 0,    TP,     sys_fork,               "fork"          },  /* 57 */
+       { 0,    TP,     sys_vfork,              "vfork"         },  /* 58 */
+       { },                                                        /* 47 */
+       { 1,    TP,     sys_exit,               "_exit"         },  /* 60 */
+       { 4,    TP,     sys_wait4,              "wait4"         },  /* 61 */
+       { 2,    TS,     sys_kill,               "kill"          },  /* 62 */
+       { 1,    0,      sys_uname,              "uname"         },  /* 63 */
+       { 4,    TI,     sys_semget,             "semget"        },  /* 64 */
+       { 4,    TI,     sys_semop,              "semop"         },  /* 65 */
+       { 4,    TI,     sys_semctl,             "semctl"        },  /* 66 */
+       { 4,    TI,     sys_shmdt,              "shmdt"         },  /* 67 */
+       { 4,    TI,     sys_msgget,             "msgget"        },  /* 68 */
+       { 4,    TI,     sys_msgsnd,             "msgsnd"        },  /* 69 */
+       { 5,    TI,     sys_msgrcv,             "msgrcv"        },  /* 70 */
+       { 3,    TI,     sys_msgctl,             "msgctl"        },  /* 71 */
+       { 3,    TD,     sys_fcntl,              "fcntl"         },  /* 72 */
+       { 2,    TD,     sys_flock,              "flock"         },  /* 73 */
+       { 1,    TD,     sys_fsync,              "fsync"         },  /* 74 */
+       { 1,    TD,     sys_fdatasync,          "fdatasync"     },  /* 75 */
+       { 2,    TF,     sys_truncate,           "truncate"      },  /* 76 */
+       { 2,    TD,     sys_ftruncate,          "ftruncate"     },  /* 77 */
+       { },                                                        /* 78 */
+       { 2,    TF,     sys_getcwd,             "getcwd"        },  /* 79 */
+       { 1,    TF,     sys_chdir,              "chdir"         },  /* 80 */
+       { 1,    TD,     sys_fchdir,             "fchdir"        },  /* 81 */
+       { 2,    TF,     sys_rename,             "rename"        },  /* 82 */
+       { 2,    TF,     sys_mkdir,              "mkdir"         },  /* 83 */
+       { 1,    TF,     sys_rmdir,              "rmdir"         },  /* 84 */
+       { 2,    TD|TF,  sys_creat,              "creat"         },  /* 85 */
+       { 2,    TF,     sys_link,               "link"          },  /* 86 */
+       { 1,    TF,     sys_unlink,             "unlink"        },  /* 87 */
+       { 2,    TF,     sys_symlink,            "symlink"       },  /* 88 */
+       { 3,    TF,     sys_readlink,           "readlink"      },  /* 89 */
+       { 2,    TF,     sys_chmod,              "chmod"         },  /* 90 */
+       { 2,    TD,     sys_fchmod,             "fchmod"        },  /* 91 */
+       { 3,    TF,     sys_chown,              "chown"         },  /* 92 */
+       { 3,    TD,     sys_fchown,             "fchown"        },  /* 93 */
+       { 3,    TF,     sys_chown,              "lchown"        },  /* 94 */
+       { 1,    0,      sys_umask,              "umask"         },  /* 95 */
+       { 2,    0,      sys_gettimeofday,       "gettimeofday"  },  /* 96 */
+       { 2,    0,      sys_getrlimit,          "getrlimit"     },  /* 97 */
+       { 2,    0,      sys_getrusage,          "getrusage"     },  /* 98 */
+       { 1,    0,      sys_sysinfo,            "sysinfo"       },  /* 99 */
+       { 1,    0,      sys_times,              "times"         },  /* 100 */
+       { },                                                        /* 101 */
+       { 0,    NF,     sys_getuid,             "getuid"        },  /* 102 */
+       { 3,    0,      sys_syslog,             "syslog"        },  /* 103 */
+       { 0,    NF,     sys_getgid,             "getgid"        },  /* 104 */
+       { 1,    0,      sys_setuid,             "setuid"        },  /* 105 */
+       { 1,    0,      sys_setgid,             "setgid"        },  /* 106 */
+       { 0,    NF,     sys_geteuid,            "geteuid"       },  /* 107 */
+       { 0,    NF,     sys_getegid,            "getegid"       },  /* 108 */
+       { 2,    0,      sys_setpgid,            "setpgid"       },  /* 109 */
+       { 0,    0,      sys_getppid,            "getppid"       },  /* 110 */
+       { 0,    0,      sys_getpgrp,            "getpgrp"       },  /* 111 */
+       { 0,    0,      sys_setsid,             "setsid"        },  /* 112 */
+       { 2,    0,      sys_setreuid,           "setreuid"      },  /* 113 */
+       { 2,    0,      sys_setregid,           "setregid"      },  /* 114 */
+       { 2,    0,      sys_getgroups,          "getgroups"     },  /* 115 */
+       { 2,    0,      sys_setgroups,          "setgroups"     },  /* 116 */
+       { 3,    0,      sys_setresuid,          "setresuid"     },  /* 117 */
+       { 3,    0,      sys_getresuid,          "getresuid"     },  /* 118 */
+       { 3,    0,      sys_setresgid,          "setresgid"     },  /* 119 */
+       { 3,    0,      sys_getresgid,          "getresgid"     },  /* 120 */
+       { 1,    0,      sys_getpgid,            "getpgid"       },  /* 121 */
+       { 1,    NF,     sys_setfsuid,           "setfsuid"      },  /* 122 */
+       { 1,    NF,     sys_setfsgid,           "setfsgid"      },  /* 123 */
+       { 1,    0,      sys_getsid,             "getsid"        },  /* 124 */
+       { 2,    0,      sys_capget,             "capget"        },  /* 125 */
+       { 2,    0,      sys_capset,             "capset"        },  /* 126 */
+       { },                                                        /* 127 */
+       { },                                                        /* 128 */
+       { },                                                        /* 129 */
+       { 2,    TS,     sys_rt_sigsuspend,      "rt_sigsuspend" },  /* 130 */
+       { },                                                        /* 131 */
+       { 2,    TF,     sys_utime,              "utime"         },  /* 132 */
+       { 3,    TF,     sys_mknod,              "mknod"         },  /* 133 */
+       { },                                                        /* 134 */
+       { 1,    0,      sys_personality,        "personality"   },  /* 135 */
+       { 2,    0,      sys_ustat,              "ustat"         },  /* 136 */
+       { 2,    TF,     sys_statfs,             "statfs"        },  /* 137 */
+       { 2,    TD,     sys_fstatfs,            "fstatfs"       },  /* 138 */
+       { 3,    0,      sys_sysfs,              "sysfs"         },  /* 139 */
+       { 2,    0,      sys_getpriority,        "getpriority"   },  /* 140 */
+       { 3,    0,      sys_setpriority,        "setpriority"   },  /* 141 */
+       { 0,    0,      sys_sched_setparam,     "sched_setparam"        },  /* 142 */
+       { 2,    0,      sys_sched_getparam,     "sched_getparam"        },  /* 143 */
+       { 3,    0,      sys_sched_setscheduler, "sched_setscheduler"    },  /* 144 */
+       { 1,    0,      sys_sched_getscheduler, "sched_getscheduler"    },  /* 145 */
+       { 1,    0,      sys_sched_get_priority_max,     "sched_get_priority_max"        },  /* 146 */
+       { 1,    0,      sys_sched_get_priority_min,     "sched_get_priority_min"        },  /* 147 */
+       { 2,    0,      sys_sched_rr_get_interval,      "sched_rr_get_interval" },  /* 148 */
+       { 2,    0,      sys_mlock,              "mlock"         },  /* 149 */
+       { 2,    0,      sys_munlock,            "munlock"       },  /* 150 */
+       { 1,    0,      sys_mlockall,           "mlockall"      },  /* 151 */
+       { 0,    0,      sys_munlockall,         "munlockall"    },  /* 152 */
+       { 0,    0,      sys_vhangup,            "vhangup"       },  /* 153 */
+       { 3,    0,      sys_modify_ldt,         "modify_ldt"    },  /* 154 */
+       { 2,    TF,     sys_pivotroot,          "pivot_root"    },  /* 155 */
+       { },                                                        /* 156 */
+       { 5,    0,      sys_prctl,              "prctl"         },  /* 157 */
+       { 2,    TP,     sys_arch_prctl,         "arch_prctl"    },  /* 158 */
+       { 1,    0,      sys_adjtimex,           "adjtimex"      },  /* 159 */
+       { 2,    0,      sys_setrlimit,          "setrlimit"     },  /* 160 */
+       { 1,    TF,     sys_chroot,             "chroot"        },  /* 161 */
+       { 0,    0,      sys_sync,               "sync"          },  /* 162 */
+       { 1,    TF,     sys_acct,               "acct"          },  /* 163 */
+       { 2,    0,      sys_settimeofday,       "settimeofday"  },  /* 164 */
+       { 5,    TF,     sys_mount,              "mount"         },  /* 165 */
+       { 2,    TF,     sys_umount2,            "umount"        }, /* 166 */
+       { 2,    TF,     sys_swapon,             "swapon"        },  /* 167 */
+       { 1,    TF,     sys_swapoff,            "swapoff"       },  /* 168 */
+       { 4,    0,      sys_reboot,             "reboot"        },  /* 169 */
+       { 2,    0,      sys_sethostname,        "sethostname"   },  /* 170 */
+       { 2,    0,      sys_setdomainname,      "setdomainname" },  /* 171 */
+       { 1,    0,      sys_iopl,               "iopl"          },  /* 172 */
+       { 3,    0,      sys_ioperm,             "ioperm"        },  /* 173 */
+       { 2,    0,      sys_create_module,      "create_module" },  /* 174 */
+       { 3,    0,      sys_init_module,        "init_module"   },  /* 175 */
+       { 2,    0,      sys_delete_module,      "delete_module" },  /* 176 */
+       { },                                                        /* 177 */
+       { },                                                        /* 178 */
+       { 4,    0,      sys_quotactl,           "quotactl"      },  /* 179 */
+       { },                                                        /* 180 */
+       { },                                                        /* 181 */
+       { },                                                        /* 182 */
+       { },                                                        /* 183 */
+       { },                                                        /* 184 */
+       { },                                                        /* 185 */
+       { 0,    0,      sys_gettid,             "gettid"        }, /* 186 */
+       { 4,    TD,     sys_readahead,          "readahead"     }, /* 187 */
+       { 5,    TF,     sys_setxattr,           "setxattr"      }, /* 188 */
+       { 5,    TF,     sys_setxattr,           "lsetxattr"     }, /* 189 */
+       { 5,    TD,     sys_fsetxattr,          "fsetxattr"     }, /* 190 */
+       { 4,    TF,     sys_getxattr,           "getxattr"      }, /* 191 */
+       { 4,    TF,     sys_getxattr,           "lgetxattr"     }, /* 192 */
+       { 4,    TD,     sys_fgetxattr,          "fgetxattr"     }, /* 193 */
+       { 3,    TF,     sys_listxattr,          "listxattr"     }, /* 194 */
+       { 3,    TF,     sys_listxattr,          "llistxattr"    }, /* 195 */
+       { 3,    TD,     sys_flistxattr,         "flistxattr"    }, /* 196 */
+       { 2,    TF,     sys_removexattr,        "removexattr"   }, /* 197 */
+       { 2,    TF,     sys_removexattr,        "lremovexattr"  }, /* 198 */
+       { 2,    TD,     sys_fremovexattr,       "fremovexattr"  }, /* 199 */
+       { 2,    TS,     sys_kill,               "tkill"         }, /* 200 */
+       { 1,    0,      sys_time,               "time"          },  /* 201 */
+       { 6,    0,      sys_futex,              "futex"         }, /* 202 */
+       { 3,    0,      sys_sched_setaffinity,  "sched_setaffinity" },/* 203 */
+       { 3,    0,      sys_sched_getaffinity,  "sched_getaffinity" },/* 204 */
+       { },                                                       /* 205 */
+       { 2,    0,      sys_io_setup,           "io_setup"      }, /* 206 */
+       { 1,    0,      sys_io_destroy,         "io_destroy"    }, /* 207 */
+       { 5,    0,      sys_io_getevents,       "io_getevents"  }, /* 208 */
+       { 3,    0,      sys_io_submit,          "io_submit"     }, /* 209 */
+       { 3,    0,      sys_io_cancel,          "io_cancel"     }, /* 210 */
+       { },                                                       /* 211 */
+       { 4,    0,      sys_lookup_dcookie,     "lookup_dcookie"}, /* 212 */
+       { 1,    TD,     sys_epoll_create,       "epoll_create"  }, /* 213 */
+       { },                                                       /* 214 */
+       { },                                                       /* 215 */
+       { 5,    0,      sys_remap_file_pages,   "remap_file_pages"}, /* 216 */
+       { 3,    TD,     sys_getdents64,         "getdents64"    }, /* 217 */
+       { 1,    0,      sys_set_tid_address,    "set_tid_address"}, /* 218 */
+       { 0,    0,      sys_restart_syscall,    "restart_syscall"}, /* 219 */
+       { 5,    TI,     sys_semtimedop,         "semtimedop"    }, /* 220 */
+       { 4,    TD,     sys_fadvise64_64,       "fadvise64"     }, /* 221 */
+       { },                                                       /* 222 */
+       { 4,    0,      sys_timer_settime,      "timer_settime" }, /* 223 */
+       { 2,    0,      sys_timer_gettime,      "timer_gettime" }, /* 224 */
+       { 1,    0,      sys_timer_getoverrun,   "timer_getoverrun"}, /* 225 */
+       { 1,    0,      sys_timer_delete,       "timer_delete"  }, /* 226 */
+       { 2,    0,      sys_clock_settime,      "clock_settime" }, /* 227 */
+       { 2,    0,      sys_clock_gettime,      "clock_gettime" }, /* 228 */
+       { 2,    0,      sys_clock_getres,       "clock_getres"  }, /* 229 */
+       { 4,    0,      sys_clock_nanosleep,    "clock_nanosleep"}, /* 230 */
+       { 1,    TP,     sys_exit,               "exit_group"    }, /* 231 */
+       { 4,    TD,     sys_epoll_wait,         "epoll_wait"    }, /* 232 */
+       { 4,    TD,     sys_epoll_ctl,          "epoll_ctl"     }, /* 233 */
+       { 3,    TS,     sys_tgkill,             "tgkill"        }, /* 234 */
+       { 2,    TF,     sys_utimes,             "utimes"        }, /* 235 */
+       { },                                                       /* 236 */
+       { 6,    0,      sys_mbind,              "mbind"         }, /* 237 */
+       { 3,    0,      sys_set_mempolicy,      "set_mempolicy" }, /* 238 */
+       { 5,    0,      sys_get_mempolicy,      "get_mempolicy" }, /* 239 */
+       { 4,    0,      sys_mq_open,            "mq_open"       }, /* 240 */
+       { 1,    0,      sys_mq_unlink,          "mq_unlink"     }, /* 241 */
+       { 5,    0,      sys_mq_timedsend,       "mq_timedsend"  }, /* 242 */
+       { 5,    0,      sys_mq_timedreceive,    "mq_timedreceive" }, /* 243 */
+       { },                                                       /* 244 */
+       { 3,    0,      sys_mq_getsetattr,      "mq_getsetattr" }, /* 245 */
+       { },                                                       /* 246 */
+       { },                                                       /* 247 */
+       { 5,    0,      sys_add_key,            "add_key"       }, /* 248 */
+       { 4,    0,      sys_request_key,        "request_key"   }, /* 249 */
+       { 5,    0,      sys_keyctl,             "keyctl"        }, /* 250 */
+       { 3,    0,      sys_ioprio_set,         "ioprio_set"    }, /* 251 */
+       { 2,    0,      sys_ioprio_get,         "ioprio_get"    }, /* 252 */
+       { 0,    TD,     sys_inotify_init,       "inotify_init"  }, /* 253 */
+       { 3,    TD,     sys_inotify_add_watch,  "inotify_add_watch" }, /* 254 */
+       { 2,    TD,     sys_inotify_rm_watch,   "inotify_rm_watch" }, /* 255 */
+       { 4,    0,      sys_migrate_pages,      "migrate_pages" }, /* 256 */
+       { 4,    TD|TF,  sys_openat,             "openat"        }, /* 257 */
+       { 3,    TD|TF,  sys_mkdirat,            "mkdirat"       }, /* 258 */
+       { 4,    TD|TF,  sys_mknodat,            "mknodat"       }, /* 259 */
+       { 5,    TD|TF,  sys_fchownat,           "fchownat"      }, /* 260 */
+       { 3,    TD|TF,  sys_futimesat,          "futimesat"     }, /* 261 */
+       { 4,    TD|TF,  sys_newfstatat,         "newfstatat"    }, /* 262 */
+       { 3,    TD|TF,  sys_unlinkat,           "unlinkat"      }, /* 263 */
+       { 4,    TD|TF,  sys_renameat,           "renameat"      }, /* 264 */
+       { 5,    TD|TF,  sys_linkat,             "linkat"        }, /* 265 */
+       { 3,    TD|TF,  sys_symlinkat,          "symlinkat"     }, /* 266 */
+       { 4,    TD|TF,  sys_readlinkat,         "readlinkat"    }, /* 267 */
+       { 3,    TD|TF,  sys_fchmodat,           "fchmodat"      }, /* 268 */
+       { 3,    TD|TF,  sys_faccessat,          "faccessat"     }, /* 269 */
+       { 6,    TD,     sys_pselect6,           "pselect6"      }, /* 270 */
+       { 5,    TD,     sys_ppoll,              "ppoll"         }, /* 271 */
+       { 1,    TP,     sys_unshare,            "unshare"       }, /* 272 */
+       { },                                                       /* 273 */
+       { },                                                       /* 274 */
+       { 6,    TD,     sys_splice,             "splice"        }, /* 275 */
+       { 4,    TD,     sys_tee,                "tee"           }, /* 276 */
+       { 4,    TD,     sys_sync_file_range,    "sync_file_range" }, /* 277 */
+       { },                                                       /* 278 */
+       { },                                                       /* 279 */
+       { 4,    TD|TF,  sys_utimensat,          "utimensat"     }, /* 280 */
+       { 6,    TD,     sys_epoll_pwait,        "epoll_pwait"   }, /* 281 */
+       { 3,    TD|TS,  sys_signalfd,           "signalfd"      }, /* 282 */
+       { 2,    TD,     sys_timerfd_create,     "timerfd_create"}, /* 283 */
+       { 1,    TD,     sys_eventfd,            "eventfd"       }, /* 284 */
+       { 6,    TD,     sys_fallocate,          "fallocate"     }, /* 285 */
+       { 4,    TD,     sys_timerfd_settime,    "timerfd_settime"}, /* 286 */
+       { 2,    TD,     sys_timerfd_gettime,    "timerfd_gettime"}, /* 287 */
+       { 4,    TN,     sys_accept4,            "accept4"       }, /* 288 */
+       { 4,    TD|TS,  sys_signalfd4,          "signalfd4"     }, /* 289 */
+       { 2,    TD,     sys_eventfd2,           "eventfd2"      }, /* 290 */
+       { 1,    TD,     sys_epoll_create1,      "epoll_create1" }, /* 291 */
+       { 3,    TD,     sys_dup3,               "dup3"          }, /* 292 */
+       { 2,    TD,     sys_pipe2,              "pipe2"         }, /* 293 */
+       { 1,    TD,     sys_inotify_init1,      "inotify_init1" }, /* 294 */
+       { },                                                       /* 295 */
+       { },                                                       /* 296 */
+       { },                                                       /* 297 */
+       { 5,    TD,     sys_perf_event_open,    "perf_event_open"}, /* 298 */
+       { },                                                       /* 299 */
+       { 2,    TD,     sys_fanotify_init,      "fanotify_init" }, /* 300 */
+       { 5,    TD|TF,  sys_fanotify_mark,      "fanotify_mark" }, /* 301 */
+       { 4,    0,      sys_prlimit64,          "prlimit64"     }, /* 302 */
+       { 5,    TD|TF,  sys_name_to_handle_at,  "name_to_handle_at"}, /* 303 */
+       { 3,    TD,     sys_open_by_handle_at,  "open_by_handle_at"}, /* 304 */
+       { 2,    0,      sys_clock_adjtime,      "clock_adjtime" }, /* 305 */
+       { 1,    TD,     sys_syncfs,             "syncfs"        }, /* 306 */
+       { },                                                       /* 307 */
+       { 2,    TD,     sys_setns,              "setns"         }, /* 308 */
+       { 3,    0,      sys_getcpu,             "getcpu"        }, /* 309 */
+       { },                                                       /* 310 */
+       { },                                                       /* 311 */
+
+       [312 ... 511] = {},
+
+       { 4,    TS,     sys_rt_sigaction,       "rt_sigaction"  },  /* 512 */
+       { 0,    TS,     sys_rt_sigreturn,       "rt_sigreturn"  },  /* 513 */
+       { 3,    TD,     sys_ioctl,              "ioctl"         },  /* 514 */
+       { 3,    TD,     sys_readv,              "readv"         },  /* 515 */
+       { 3,    TD,     sys_writev,             "writev"        },  /* 516 */
+       { 6,    TN,     sys_recvfrom,           "recvfrom"      },  /* 517 */
+       { 3,    TN,     sys_sendmsg,            "sendmsg"       },  /* 518 */
+       { 5,    TN,     sys_recvmsg,            "recvmsg"       },  /* 519 */
+       { 3,    TF|TP,  sys_execve,             "execve"        },  /* 520 */
+       { 4,    0,      sys_ptrace,             "ptrace"        },  /* 521 */
+       { 2,    TS,     sys_rt_sigpending,      "rt_sigpending" },  /* 522 */
+       { 4,    TS,     sys_rt_sigtimedwait,    "rt_sigtimedwait" },  /* 523 */
+       { 3,    TS,     sys_rt_sigqueueinfo,    "rt_sigqueueinfo" },  /* 524 */
+       { 2,    TS,     sys_sigaltstack,        "sigaltstack"   },  /* 525 */
+       { 3,    0,      sys_timer_create,       "timer_create"  }, /* 526 */
+       { 2,    0,      sys_mq_notify,          "mq_notify"     }, /* 527 */
+       { 4,    0,      sys_kexec_load,         "kexec_load"    }, /* 528 */
+       { 5,    TP,     sys_waitid,             "waitid"        }, /* 529 */
+       { 2,    0,      sys_set_robust_list,    "set_robust_list" }, /* 530 */
+       { 3,    0,      sys_get_robust_list,    "get_robust_list" }, /* 531 */
+       { 4,    TD,     sys_vmsplice,           "vmsplice"      }, /* 532 */
+       { 6,    0,      sys_move_pages,         "move_pages"    }, /* 533 */
+       { 5,    TD,     sys_preadv,             "preadv"        }, /* 534 */
+       { 5,    TD,     sys_pwritev,            "pwritev"       }, /* 535 */
+       { 4,    TP|TS,  sys_rt_tgsigqueueinfo,  "rt_tgsigqueueinfo"}, /* 536 */
+       { 5,    TN,     sys_recvmmsg,           "recvmmsg"      }, /* 537 */
+       { 4,    TN,     sys_sendmmsg,           "sendmmsg"      }, /* 538 */
+       { 6,    0,      sys_process_vm_readv,   "process_vm_readv"}, /* 539 */
+       { 6,    0,      sys_process_vm_writev,  "process_vm_writev"}, /* 540 */
diff --git a/linux/x86_64/errnoent2.h b/linux/x86_64/errnoent2.h
new file mode 100644 (file)
index 0000000..00de57b
--- /dev/null
@@ -0,0 +1,2 @@
+/* Our third set is for x32.  */
+#include "../errnoent.h"
diff --git a/linux/x86_64/ioctlent2.h b/linux/x86_64/ioctlent2.h
new file mode 100644 (file)
index 0000000..060003b
--- /dev/null
@@ -0,0 +1,2 @@
+/* Our third set is for x32.  */
+#include "linux/ioctlent.h"
diff --git a/linux/x86_64/signalent2.h b/linux/x86_64/signalent2.h
new file mode 100644 (file)
index 0000000..6fbcab1
--- /dev/null
@@ -0,0 +1,2 @@
+/* Our third set is for x32.  */
+#include "../signalent.h"
diff --git a/linux/x86_64/syscallent2.h b/linux/x86_64/syscallent2.h
new file mode 100644 (file)
index 0000000..1d35f53
--- /dev/null
@@ -0,0 +1,2 @@
+/* Our third set is for x32.  */
+#include "x32/syscallent.h"
diff --git a/mem.c b/mem.c
index 72b30decc2380ffa8dcc54de71af8753e8fbc8be..8e34f966eee3aad937783a432a5816679daa241d 100644 (file)
--- a/mem.c
+++ b/mem.c
@@ -320,7 +320,7 @@ int
 sys_mmap64(struct tcb *tcp)
 {
        if (entering(tcp)) {
-#if defined(ALPHA)
+#if defined(ALPHA) || defined(X32)
                long *u_arg = tcp->u_arg;
 #else
                long u_arg[7];
@@ -349,7 +349,7 @@ sys_mmap64(struct tcb *tcp)
                tprints(", ");
                printfd(tcp, u_arg[4]);
                /* offset */
-#if defined(ALPHA)
+#if defined(ALPHA) || defined(X32)
                printllval(tcp, ", %#llx", 5);
 #else
                /* NOTE: not verified that [5] and [6] should be used.
index 87d98278bc4360910df33c29c87f62669c0befa2..886932c87392ccceb930629bc996bffcf2c9d5ab 100644 (file)
@@ -223,7 +223,11 @@ pathtrace_match(struct tcb *tcp)
                        upathmatch(tcp, tcp->u_arg[3]);
        }
 
-       if (s->sys_func == sys_old_mmap || s->sys_func == sys_mmap) {
+       if (
+#if !defined X32
+           s->sys_func == sys_old_mmap ||
+#endif
+           s->sys_func == sys_mmap) {
                /* x, x, x, x, fd */
                return fdmatch(tcp, tcp->u_arg[4]);
        }
index 100ccd44f06b13e35d131d57b5795e6fad3dc9e6..2fb6c9271019a39cbb908111bf6a9e9b9785f54b 100644 (file)
--- a/process.c
+++ b/process.c
@@ -465,7 +465,7 @@ extern void print_ldt_entry();
 # define ARG_PTID      2
 # define ARG_CTID      3
 # define ARG_TLS       4
-#elif defined X86_64 || defined ALPHA
+#elif defined X86_64 || defined X32 || defined ALPHA
 # define ARG_FLAGS     0
 # define ARG_STACK     1
 # define ARG_PTID      2
@@ -1589,7 +1589,7 @@ const struct xlat struct_user_offsets[] = {
        { 4*EFL,                "4*EFL"                                 },
        { 4*UESP,               "4*UESP"                                },
        { 4*SS,                 "4*SS"                                  },
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
        { 8*R15,                "8*R15"                                 },
        { 8*R14,                "8*R14"                                 },
        { 8*R13,                "8*R13"                                 },
@@ -2124,7 +2124,7 @@ const struct xlat struct_user_offsets[] = {
 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
        { uoff(u_fpvalid),      "offsetof(struct user, u_fpvalid)"      },
 # endif
-# if defined(I386) || defined(X86_64)
+# if defined(I386) || defined(X86_64) || defined(X32)
        { uoff(i387),           "offsetof(struct user, i387)"           },
 # endif
 # if defined(M68K)
@@ -2154,7 +2154,7 @@ const struct xlat struct_user_offsets[] = {
 # endif
        { uoff(magic),          "offsetof(struct user, magic)"          },
        { uoff(u_comm),         "offsetof(struct user, u_comm)"         },
-# if defined(I386) || defined(X86_64)
+# if defined(I386) || defined(X86_64) || defined(X32)
        { uoff(u_debugreg),     "offsetof(struct user, u_debugreg)"     },
 # endif
 #endif /* !defined(many arches) */
@@ -2566,7 +2566,7 @@ sys_sched_rr_get_interval(struct tcb *tcp)
        return 0;
 }
 
-#ifdef X86_64
+#if defined X86_64 || defined X32
 # include <asm/prctl.h>
 
 static const struct xlat archvals[] = {
@@ -2600,7 +2600,7 @@ sys_arch_prctl(struct tcb *tcp)
        }
        return 0;
 }
-#endif /* X86_64 */
+#endif /* X86_64 || X32 */
 
 int
 sys_getcpu(struct tcb *tcp)
index ab7ae564065820f2e0f76f9465d2bad654709f0c..17be957d3fd28e578f5ea11cb414383ddd41f6ab 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -73,7 +73,7 @@ typedef struct {
        int                     si_mask;
 } m_siginfo_t;
 #elif defined HAVE_ASM_SIGCONTEXT_H
-# if !defined(IA64) && !defined(X86_64)
+# if !defined(IA64) && !defined(X86_64) && !defined(X32)
 #  include <asm/sigcontext.h>
 # endif
 #else /* !HAVE_ASM_SIGCONTEXT_H */
@@ -132,7 +132,7 @@ struct sigcontext
 
 #ifdef HAVE_SIGACTION
 
-#if defined(I386) || defined(X86_64)
+#if defined I386 || defined X86_64 || defined X32
 /* The libc headers do not define this constant since it should only be
    used by the implementation.  So we define it here.  */
 # ifndef SA_RESTORER
@@ -723,8 +723,8 @@ printsiginfo(siginfo_t *sip, int verbose)
                                        tprints(", ...");
                                else
                                        tprintf(", si_utime=%lu, si_stime=%lu",
-                                               sip->si_utime,
-                                               sip->si_stime);
+                                               (unsigned long) sip->si_utime,
+                                               (unsigned long) sip->si_stime);
                                break;
                        case SIGILL: case SIGFPE:
                        case SIGSEGV: case SIGBUS:
index 7f3ff34667815fd00c2f806a7dca80d062e2649a..44964bccb6aec995f8e8c50759ffe898cedad965 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -261,12 +261,18 @@ update_personality(struct tcb *tcp, int personality)
                return;
        tcp->currpers = personality;
 
-# if defined(POWERPC64) || defined(X86_64)
+# if defined(POWERPC64)
        if (!qflag) {
                static const char *const names[] = {"64 bit", "32 bit"};
                fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
                        tcp->pid, names[personality]);
        }
+# elif defined(X86_64)
+       if (!qflag) {
+               static const char *const names[] = {"64 bit", "32 bit", "x32"};
+               fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
+                       tcp->pid, names[personality]);
+       }
 # endif
 }
 #endif
@@ -622,7 +628,7 @@ is_restart_error(struct tcb *tcp)
 
 #if defined(I386)
 struct pt_regs i386_regs;
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
 /*
  * On 32 bits, pt_regs and user_regs_struct are the same,
  * but on 64 bits, user_regs_struct has six more fields:
@@ -795,7 +801,14 @@ get_scno(struct tcb *tcp)
        if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &i386_regs) < 0)
                return -1;
        scno = i386_regs.orig_eax;
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
+# ifndef __X32_SYSCALL_BIT
+#  define __X32_SYSCALL_BIT    0x40000000
+# endif
+# ifndef __X32_SYSCALL_MASK
+#  define __X32_SYSCALL_MASK   __X32_SYSCALL_BIT
+# endif
+
        int currpers;
        if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &x86_64_regs) < 0)
                return -1;
@@ -804,10 +817,18 @@ get_scno(struct tcb *tcp)
        /* Check CS register value. On x86-64 linux it is:
         *      0x33    for long mode (64 bit)
         *      0x23    for compatibility mode (32 bit)
+        * Check DS register value. On x86-64 linux it is:
+        *      0x2b    for x32 mode (x86-64 in 32 bit)
         */
        switch (x86_64_regs.cs) {
                case 0x23: currpers = 1; break;
-               case 0x33: currpers = 0; break;
+               case 0x33:
+                       if (x86_64_regs.ds == 0x2b) {
+                               currpers = 2;
+                               scno &= ~__X32_SYSCALL_MASK;
+                       } else
+                               currpers = 0;
+                       break;
                default:
                        fprintf(stderr, "Unknown value CS=0x%08X while "
                                 "detecting personality of process "
@@ -846,7 +867,16 @@ get_scno(struct tcb *tcp)
                        break;
        }
 # endif
+# ifdef X32
+       if (currpers == 0 || currpers == 1) {
+               fprintf(stderr, "syscall_%lu (...) in unsupported %s "
+                       "mode of process PID=%d\n", scno,
+                       currpers == 0 ? "64-bit" : "32-bit", tcp->pid);
+               return 0;
+       }
+# else
        update_personality(tcp, currpers);
+# endif
 #elif defined(IA64)
 #      define IA64_PSR_IS      ((long)1 << 34)
        if (upeek(tcp, PT_CR_IPSR, &psr) >= 0)
@@ -1096,7 +1126,7 @@ syscall_fixup_on_sysenter(struct tcb *tcp)
                        fprintf(stderr, "not a syscall entry (eax = %ld)\n", i386_regs.eax);
                return 0;
        }
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
        {
                long rax = x86_64_regs.rax;
                if (current_personality == 1)
@@ -1385,16 +1415,24 @@ get_syscall_args(struct tcb *tcp)
        for (i = 0; i < nargs; ++i)
                if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
                        return -1;
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
        (void)i;
        (void)nargs;
-       if (current_personality == 0) { /* x86-64 ABI */
+       if (current_personality != 1) { /* x86-64 or x32 ABI */
                tcp->u_arg[0] = x86_64_regs.rdi;
                tcp->u_arg[1] = x86_64_regs.rsi;
                tcp->u_arg[2] = x86_64_regs.rdx;
                tcp->u_arg[3] = x86_64_regs.r10;
                tcp->u_arg[4] = x86_64_regs.r8;
                tcp->u_arg[5] = x86_64_regs.r9;
+#  ifdef X32
+               tcp->ext_arg[0] = x86_64_regs.rdi;
+               tcp->ext_arg[1] = x86_64_regs.rsi;
+               tcp->ext_arg[2] = x86_64_regs.rdx;
+               tcp->ext_arg[3] = x86_64_regs.r10;
+               tcp->ext_arg[4] = x86_64_regs.r8;
+               tcp->ext_arg[5] = x86_64_regs.r9;
+#  endif
        } else { /* i386 ABI */
                /* Sign-extend lower 32 bits */
                tcp->u_arg[0] = (long)(int)x86_64_regs.rbx;
@@ -1569,7 +1607,7 @@ get_syscall_result(struct tcb *tcp)
 #elif defined(I386)
        if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &i386_regs) < 0)
                return -1;
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
        if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &x86_64_regs) < 0)
                return -1;
 #elif defined(IA64)
@@ -1701,13 +1739,16 @@ get_error(struct tcb *tcp)
        else {
                tcp->u_rval = i386_regs.eax;
        }
-#elif defined(X86_64)
+#elif defined(X86_64) || defined(X32)
        if (check_errno && is_negated_errno(x86_64_regs.rax)) {
                tcp->u_rval = -1;
                u_error = -x86_64_regs.rax;
        }
        else {
                tcp->u_rval = x86_64_regs.rax;
+# if defined(X32)
+               tcp->u_lrval = x86_64_regs.rax;
+# endif
        }
 #elif defined(IA64)
        if (ia32) {
diff --git a/util.c b/util.c
index 348d77f498fdd3314f7ac3ab7a8d921e21dad487..6588de2f758e1d5df08d3efea9e484d15c36fc95 100644 (file)
--- a/util.c
+++ b/util.c
@@ -212,7 +212,7 @@ printllval(struct tcb *tcp, const char *format, int llarg)
 # 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 @@ printcall(struct tcb *tcp)
        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 @@ change_syscall(struct tcb *tcp, int new)
        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 @@ typedef struct pt_regs arg_setup_state;
 # 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)