From 08267b8d6703c23332e39b1296e10e327196acb3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 20 Feb 2004 22:56:43 +0000 Subject: [PATCH] 2003-12-31 David Mosberger * process.c (internal_exit): For ia64, also recognize IA-32 252 as exit_group(). (change_syscall): For IA64, also support changing IA-32 syscalls. * syscall.c (internal_syscall): For IA64, also recognize IA-32 syscall 252 (exit_group) as an internal_exit() syscall. * util.c (SYS_fork): For IA64, define them to the IA-32 syscall number. (SYS_vfork): Likewise. (arg_setup): For IA64 version, also support IA-32 syscalls. (get_arg0): Likewise. (get_arg1): Likewise. (set_arg0): Likewise. (set_arg1): Likewise. --- process.c | 19 ++++++++++++++++++- syscall.c | 3 +++ util.c | 54 ++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/process.c b/process.c index de7833f6..1839463c 100644 --- a/process.c +++ b/process.c @@ -373,6 +373,12 @@ struct tcb *tcp; 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 @@ -657,7 +663,18 @@ int new; 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) diff --git a/syscall.c b/syscall.c index 2a04c2a4..d2981b7b 100644 --- a/syscall.c +++ b/syscall.c @@ -679,6 +679,9 @@ struct tcb *tcp; #endif #ifdef __NR_exit_group case __NR_exit_group: +#endif +#ifdef IA64 + case 252: /* IA-32 __NR_exit_group */ #endif internal_exit(tcp); break; diff --git a/util.c b/util.c index 7dcc5b3b..4663bc9c 100644 --- a/util.c +++ b/util.c @@ -1154,6 +1154,11 @@ struct tcb *tcp; #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 @@ -1161,6 +1166,9 @@ arg_setup(struct tcb *tcp, arg_setup_state *state) { 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) @@ -1180,35 +1188,61 @@ arg_setup(struct tcb *tcp, arg_setup_state *state) 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; } -- 2.40.0