Import lots of ia64 related changes from David Mosberger
diff --git a/syscall.c b/syscall.c
index dcd3504..308080a 100644
--- a/syscall.c
+++ b/syscall.c
@@ -455,7 +455,7 @@
};
#endif /* FREEBSD */
-#if !(defined(LINUX) && ( defined(ALPHA) || defined(IA64) || defined(MIPS) ))
+#if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) ))
const int socket_map [] = {
/* SYS_SOCKET */ 97,
@@ -610,6 +610,11 @@
internal_clone(tcp);
break;
#endif
+#ifdef SYS_clone2
+ case SYS_clone2:
+ internal_clone(tcp);
+ break;
+#endif
#ifdef SYS_execv
case SYS_execv:
#endif
@@ -628,6 +633,9 @@
#ifdef SYS_wait4
case SYS_wait4:
#endif
+#ifdef SYS32_wait4
+ case SYS32_wait4:
+#endif
#ifdef SYS_waitpid
case SYS_waitpid:
#endif
@@ -640,6 +648,9 @@
#ifdef SYS_exit
case SYS_exit:
#endif
+#ifdef SYS32_exit
+ case SYS32_exit:
+#endif
internal_exit(tcp);
break;
}
@@ -710,13 +721,14 @@
if (upeek(pid, 4*ORIG_EAX, &scno) < 0)
return -1;
#elif defined(IA64)
-#define IA64_PSR_IS ((long)1 << 34)
+# define IA64_PSR_IS ((long)1 << 34)
if (upeek (pid, PT_CR_IPSR, &psr) >= 0)
- ia32 = (psr & IA64_PSR_IS);
+ ia32 = (psr & IA64_PSR_IS) != 0;
if (!(tcp->flags & TCB_INSYSCALL)) {
if (ia32) {
- if (upeek(pid, PT_R8, &scno) < 0)
+ if (upeek(pid, PT_R1, &scno) < 0) /* orig eax */
return -1;
+ /* Check if we return from execve. */
} else {
if (upeek (pid, PT_R15, &scno) < 0)
return -1;
@@ -728,6 +740,11 @@
if (upeek (pid, PT_R10, &r10) < 0)
return -1;
}
+ if (tcp->flags & TCB_WAITEXECVE) {
+ tcp->flags &= ~TCB_WAITEXECVE;
+ return 0;
+ }
+
#elif defined (ARM)
{
long pc;
@@ -1003,6 +1020,16 @@
#elif defined (HPPA)
if (upeek(pid, PT_GR28, &r28) < 0)
return -1;
+#elif defined(IA64)
+ if (upeek(pid, PT_R10, &r10) < 0)
+ return -1;
+ if (upeek(pid, PT_R8, &r8) < 0)
+ return -1;
+ if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
+ if (debug)
+ fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
+ return 0;
+ }
#endif
#endif /* LINUX */
return 1;
@@ -1236,24 +1263,58 @@
}
#elif defined (IA64)
{
- unsigned long *bsp, cfm, i;
+ if (!ia32) {
+ unsigned long *out0, *rbs_end, cfm, sof, sol, i;
+ /* be backwards compatible with kernel < 2.4.4... */
+# ifndef PT_RBS_END
+# define PT_RBS_END PT_AR_BSP
+# endif
- if (upeek(pid, PT_AR_BSP, (long *) &bsp) < 0)
- return -1;
- if (upeek(pid, PT_CFM, (long *) &cfm) < 0)
- return -1;
-
- bsp = ia64_rse_skip_regs(bsp, -(cfm & 0x7f));
-
- if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
- tcp->u_nargs = sysent[tcp->scno].nargs;
- else
- tcp->u_nargs = MAX_ARGS;
- for (i = 0; i < tcp->u_nargs; ++i) {
- if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(bsp, i), sizeof(long),
- (char *) &tcp->u_arg[i])
- < 0)
+ if (upeek(pid, PT_RBS_END, (long *) &rbs_end) < 0)
return -1;
+ if (upeek(pid, PT_CFM, (long *) &cfm) < 0)
+ return -1;
+
+ sof = (cfm >> 0) & 0x7f;
+ sol = (cfm >> 7) & 0x7f;
+ out0 = ia64_rse_skip_regs(rbs_end, -sof + sol);
+
+ if (tcp->scno >= 0 && tcp->scno < nsyscalls
+ && sysent[tcp->scno].nargs != -1)
+ tcp->u_nargs = sysent[tcp->scno].nargs;
+ else
+ tcp->u_nargs = MAX_ARGS;
+ for (i = 0; i < tcp->u_nargs; ++i) {
+ if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
+ sizeof(long), (char *) &tcp->u_arg[i]) < 0)
+ return -1;
+ }
+ } else {
+ int i;
+
+ if (/* EBX = out0 */
+ upeek(pid, PT_R11, (long *) &tcp->u_arg[0]) < 0
+ /* ECX = out1 */
+ || upeek(pid, PT_R9, (long *) &tcp->u_arg[1]) < 0
+ /* EDX = out2 */
+ || upeek(pid, PT_R10, (long *) &tcp->u_arg[2]) < 0
+ /* ESI = out3 */
+ || upeek(pid, PT_R14, (long *) &tcp->u_arg[3]) < 0
+ /* EDI = out4 */
+ || upeek(pid, PT_R15, (long *) &tcp->u_arg[4]) < 0
+ /* EBP = out5 */
+ || upeek(pid, PT_R13, (long *) &tcp->u_arg[5]) < 0)
+ return -1;
+
+ for (i = 0; i < 6; ++i)
+ /* truncate away IVE sign-extension */
+ tcp->u_arg[i] &= 0xffffffff;
+
+ if (tcp->scno >= 0 && tcp->scno < nsyscalls
+ && sysent[tcp->scno].nargs != -1)
+ tcp->u_nargs = sysent[tcp->scno].nargs;
+ else
+ tcp->u_nargs = 5;
}
}
#elif defined (MIPS)
@@ -1604,7 +1665,7 @@
switch (tcp->scno + NR_SYSCALL_BASE) {
#ifdef LINUX
-#if !defined (ALPHA) && !defined(IA64) && !defined(SPARC) && !defined(MIPS) && !defined(HPPA)
+#if !defined (ALPHA) && !defined(SPARC) && !defined(MIPS) && !defined(HPPA)
case SYS_socketcall:
decode_subcall(tcp, SYS_socket_subcall,
SYS_socket_nsubcalls, deref_style);
@@ -1613,7 +1674,7 @@
decode_subcall(tcp, SYS_ipc_subcall,
SYS_ipc_nsubcalls, shift_style);
break;
-#endif /* !ALPHA && !IA64 && !MIPS && !SPARC */
+#endif /* !ALPHA && !MIPS && !SPARC */
#ifdef SPARC
case SYS_socketcall:
sparc_socket_decode (tcp);
@@ -1676,7 +1737,7 @@
decode_subcall(tcp, SYS_kaio_subcall,
SYS_kaio_nsubcalls, shift_style);
break;
-#endif
+#endif
#endif /* SVR4 */
#ifdef FREEBSD
case SYS_msgsys:
@@ -1684,7 +1745,7 @@
case SYS_semsys:
decode_subcall(tcp, 0, 0, table_style);
break;
-#endif
+#endif
#ifdef SUNOS4
case SYS_semsys:
decode_subcall(tcp, SYS_semsys_subcall,