if (entering(tcp)) {
tcp->flags |= TCB_EXITING;
#ifdef __NR_exit_group
+# ifdef IA64
+ if (ia32) {
+ if (tcp->scno == 252)
+ tcp->flags |= TCB_GROUP_EXITING;
+ } else
+# endif
if (tcp->scno == __NR_exit_group)
tcp->flags |= TCB_GROUP_EXITING;
#endif
return -1;
return 0;
#elif defined(IA64)
- if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
+ if (ia32) {
+ switch (new) {
+ case 2: break; /* x86 SYS_fork */
+ case SYS_clone: new = 120; break;
+ default:
+ fprintf(stderr, "%s: unexpected syscall %d\n",
+ __FUNCTION__, new);
+ return -1;
+ }
+ if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
+ return -1;
+ } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
return -1;
return 0;
#elif defined(HPPA)
#ifdef IA64
+/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
+ subsystem has them for x86... */
+#define SYS_fork 2
+#define SYS_vfork 190
+
typedef unsigned long *arg_setup_state;
static int
{
unsigned long *bsp, cfm, sof, sol;
+ if (ia32)
+ return 0;
+
if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0)
return -1;
if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0)
static int
get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
{
- return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 0),
- sizeof(long), (void *) valp);
+ int ret;
+
+ if (ia32)
+ ret = upeek (tcp->pid, PT_R11, valp);
+ else
+ ret = umoven (tcp,
+ (unsigned long) ia64_rse_skip_regs(*state, 0),
+ sizeof(long), (void *) valp);
+ return ret;
}
static int
get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
{
- return umoven (tcp, (unsigned long) ia64_rse_skip_regs(*state, 1),
- sizeof(long), (void *) valp);
+ int ret;
+
+ if (ia32)
+ ret = upeek (tcp->pid, PT_R9, valp);
+ else
+ ret = umoven (tcp,
+ (unsigned long) ia64_rse_skip_regs(*state, 1),
+ sizeof(long), (void *) valp);
+ return ret;
}
#endif
static int
set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
{
- unsigned long *ap;
- ap = ia64_rse_skip_regs(*state, 0);
+ int req = PTRACE_POKEDATA;
+ void *ap;
+
+ if (ia32) {
+ ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */
+ req = PTRACE_POKEUSER;
+ } else
+ ap = ia64_rse_skip_regs(*state, 0);
errno = 0;
- ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val);
+ ptrace(req, tcp->pid, ap, val);
return errno ? -1 : 0;
}
static int
set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
{
- unsigned long *ap;
- ap = ia64_rse_skip_regs(*state, 1);
+ int req = PTRACE_POKEDATA;
+ void *ap;
+
+ if (ia32) {
+ ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */
+ req = PTRACE_POKEUSER;
+ } else
+ ap = ia64_rse_skip_regs(*state, 1);
errno = 0;
- ptrace(PTRACE_POKEDATA, tcp->pid, (void *) ap, val);
+ ptrace(req, tcp->pid, ap, val);
return errno ? -1 : 0;
}