2003-12-31 David Mosberger <davidm@hpl.hp.com>

* 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.
This commit is contained in:
Roland McGrath 2004-02-20 22:56:43 +00:00
parent 13aeab3558
commit 08267b8d67
3 changed files with 65 additions and 11 deletions

View File

@ -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)

View File

@ -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;

54
util.c
View File

@ -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;
}