linux-user/ia64: workaround ia64 strangenesses

ia64 has some strangenesses that need to be workaround:
- it has a __clone2() syscall instead of the using clone() one, with
  different arguments, and which is not declared in the usual headers.
- ucontext.uc_sigmask is declared with type long int, while it is
  actually of type sigset_t.
- uc_mcontext, uc_sigmask, uc_stack, uc_link are declared using #define,
  which clashes with the target_ucontext fields. Change their names to
  tuc_*, as already done for some target architectures.
This commit is contained in:
Aurelien Jarno 2010-03-29 02:12:51 +02:00
parent 9bc6304c15
commit 60e99246d6
3 changed files with 114 additions and 106 deletions

View File

@ -81,7 +81,11 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
if (puc) { if (puc) {
/* XXX: use siglongjmp ? */ /* XXX: use siglongjmp ? */
#ifdef __linux__ #ifdef __linux__
#ifdef __ia64
sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
#else
sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL); sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
#endif
#elif defined(__OpenBSD__) #elif defined(__OpenBSD__)
sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL); sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
#endif #endif
@ -1150,7 +1154,7 @@ int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
} }
return handle_cpu_signal(ip, (unsigned long)info->si_addr, return handle_cpu_signal(ip, (unsigned long)info->si_addr,
is_write, is_write,
&uc->uc_sigmask, puc); (sigset_t *)&uc->uc_sigmask, puc);
} }
#elif defined(__s390__) #elif defined(__s390__)

View File

@ -2052,10 +2052,10 @@ typedef struct {
} target_mcontext_t; } target_mcontext_t;
struct target_ucontext { struct target_ucontext {
struct target_ucontext *uc_link; struct target_ucontext *tuc_link;
abi_ulong uc_flags; abi_ulong tuc_flags;
target_sigset_t uc_sigmask; target_sigset_t tuc_sigmask;
target_mcontext_t uc_mcontext; target_mcontext_t tuc_mcontext;
}; };
/* A V9 register window */ /* A V9 register window */
@ -2081,7 +2081,7 @@ void sparc64_set_context(CPUSPARCState *env)
ucp_addr = env->regwptr[UREG_I0]; ucp_addr = env->regwptr[UREG_I0];
if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
goto do_sigsegv; goto do_sigsegv;
grp = &ucp->uc_mcontext.mc_gregs; grp = &ucp->tuc_mcontext.mc_gregs;
err = __get_user(pc, &((*grp)[MC_PC])); err = __get_user(pc, &((*grp)[MC_PC]));
err |= __get_user(npc, &((*grp)[MC_NPC])); err |= __get_user(npc, &((*grp)[MC_NPC]));
if (err || ((pc | npc) & 3)) if (err || ((pc | npc) & 3))
@ -2091,11 +2091,11 @@ void sparc64_set_context(CPUSPARCState *env)
sigset_t set; sigset_t set;
if (TARGET_NSIG_WORDS == 1) { if (TARGET_NSIG_WORDS == 1) {
if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0])) if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
goto do_sigsegv; goto do_sigsegv;
} else { } else {
abi_ulong *src, *dst; abi_ulong *src, *dst;
src = ucp->uc_sigmask.sig; src = ucp->tuc_sigmask.sig;
dst = target_set.sig; dst = target_set.sig;
for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
i++, dst++, src++) i++, dst++, src++)
@ -2129,8 +2129,8 @@ void sparc64_set_context(CPUSPARCState *env)
err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6])); err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7])); err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp)); err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7)); err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6]; w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
@ -2139,20 +2139,20 @@ void sparc64_set_context(CPUSPARCState *env)
if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
abi_ulong) != 0) abi_ulong) != 0)
goto do_sigsegv; goto do_sigsegv;
err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab)); err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs)); err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
{ {
uint32_t *src, *dst; uint32_t *src, *dst;
src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs; src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
dst = env->fpr; dst = env->fpr;
/* XXX: check that the CPU storage is the same as user context */ /* XXX: check that the CPU storage is the same as user context */
for (i = 0; i < 64; i++, dst++, src++) for (i = 0; i < 64; i++, dst++, src++)
err |= __get_user(*dst, src); err |= __get_user(*dst, src);
} }
err |= __get_user(env->fsr, err |= __get_user(env->fsr,
&(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr)); &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
err |= __get_user(env->gsr, err |= __get_user(env->gsr,
&(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr)); &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
if (err) if (err)
goto do_sigsegv; goto do_sigsegv;
unlock_user_struct(ucp, ucp_addr, 0); unlock_user_struct(ucp, ucp_addr, 0);
@ -2178,7 +2178,7 @@ void sparc64_get_context(CPUSPARCState *env)
if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0)) if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
goto do_sigsegv; goto do_sigsegv;
mcp = &ucp->uc_mcontext; mcp = &ucp->tuc_mcontext;
grp = &mcp->mc_gregs; grp = &mcp->mc_gregs;
/* Skip over the trap instruction, first. */ /* Skip over the trap instruction, first. */
@ -2191,11 +2191,11 @@ void sparc64_get_context(CPUSPARCState *env)
host_to_target_sigset_internal(&target_set, &set); host_to_target_sigset_internal(&target_set, &set);
if (TARGET_NSIG_WORDS == 1) { if (TARGET_NSIG_WORDS == 1) {
err |= __put_user(target_set.sig[0], err |= __put_user(target_set.sig[0],
(abi_ulong *)&ucp->uc_sigmask); (abi_ulong *)&ucp->tuc_sigmask);
} else { } else {
abi_ulong *src, *dst; abi_ulong *src, *dst;
src = target_set.sig; src = target_set.sig;
dst = ucp->uc_sigmask.sig; dst = ucp->tuc_sigmask.sig;
for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
i++, dst++, src++) i++, dst++, src++)
err |= __put_user(*src, dst); err |= __put_user(*src, dst);
@ -2238,7 +2238,7 @@ void sparc64_get_context(CPUSPARCState *env)
{ {
uint32_t *src, *dst; uint32_t *src, *dst;
src = env->fpr; src = env->fpr;
dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs; dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
/* XXX: check that the CPU storage is the same as user context */ /* XXX: check that the CPU storage is the same as user context */
for (i = 0; i < 64; i++, dst++, src++) for (i = 0; i < 64; i++, dst++, src++)
err |= __put_user(*src, dst); err |= __put_user(*src, dst);
@ -2346,12 +2346,12 @@ struct sigframe {
}; };
struct target_ucontext { struct target_ucontext {
target_ulong uc_flags; target_ulong tuc_flags;
target_ulong uc_link; target_ulong tuc_link;
target_stack_t uc_stack; target_stack_t tuc_stack;
target_ulong pad0; target_ulong pad0;
struct target_sigcontext uc_mcontext; struct target_sigcontext tuc_mcontext;
target_sigset_t uc_sigmask; target_sigset_t tuc_sigmask;
}; };
struct target_rt_sigframe { struct target_rt_sigframe {
@ -2663,17 +2663,17 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
copy_siginfo_to_user(&frame->rs_info, info); copy_siginfo_to_user(&frame->rs_info, info);
__put_user(0, &frame->rs_uc.uc_flags); __put_user(0, &frame->rs_uc.tuc_flags);
__put_user(0, &frame->rs_uc.uc_link); __put_user(0, &frame->rs_uc.tuc_link);
__put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.uc_stack.ss_sp); __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
__put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.uc_stack.ss_size); __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
__put_user(sas_ss_flags(get_sp_from_cpustate(env)), __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
&frame->rs_uc.uc_stack.ss_flags); &frame->rs_uc.tuc_stack.ss_flags);
setup_sigcontext(env, &frame->rs_uc.uc_mcontext); setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
for(i = 0; i < TARGET_NSIG_WORDS; i++) { for(i = 0; i < TARGET_NSIG_WORDS; i++) {
__put_user(set->sig[i], &frame->rs_uc.uc_sigmask.sig[i]); __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
} }
/* /*
@ -2720,14 +2720,14 @@ long do_rt_sigreturn(CPUState *env)
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe; goto badframe;
target_to_host_sigset(&blocked, &frame->rs_uc.uc_sigmask); target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
sigprocmask(SIG_SETMASK, &blocked, NULL); sigprocmask(SIG_SETMASK, &blocked, NULL);
if (restore_sigcontext(env, &frame->rs_uc.uc_mcontext)) if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
goto badframe; goto badframe;
if (do_sigaltstack(frame_addr + if (do_sigaltstack(frame_addr +
offsetof(struct target_rt_sigframe, rs_uc.uc_stack), offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
0, get_sp_from_cpustate(env)) == -EFAULT) 0, get_sp_from_cpustate(env)) == -EFAULT)
goto badframe; goto badframe;
@ -2779,11 +2779,11 @@ struct target_sigframe
struct target_ucontext { struct target_ucontext {
target_ulong uc_flags; target_ulong tuc_flags;
struct target_ucontext *uc_link; struct target_ucontext *tuc_link;
target_stack_t uc_stack; target_stack_t tuc_stack;
struct target_sigcontext uc_mcontext; struct target_sigcontext tuc_mcontext;
target_sigset_t uc_sigmask; /* mask last for extensibility */ target_sigset_t tuc_sigmask; /* mask last for extensibility */
}; };
struct target_rt_sigframe struct target_rt_sigframe
@ -2940,18 +2940,18 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
err |= copy_siginfo_to_user(&frame->info, info); err |= copy_siginfo_to_user(&frame->info, info);
/* Create the ucontext. */ /* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags); err |= __put_user(0, &frame->uc.tuc_flags);
err |= __put_user(0, (unsigned long *)&frame->uc.uc_link); err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp, err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
&frame->uc.uc_stack.ss_sp); &frame->uc.tuc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->gregs[15]), err |= __put_user(sas_ss_flags(regs->gregs[15]),
&frame->uc.uc_stack.ss_flags); &frame->uc.tuc_stack.ss_flags);
err |= __put_user(target_sigaltstack_used.ss_size, err |= __put_user(target_sigaltstack_used.ss_size,
&frame->uc.uc_stack.ss_size); &frame->uc.tuc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext, err |= setup_sigcontext(&frame->uc.tuc_mcontext,
regs, set->sig[0]); regs, set->sig[0]);
for(i = 0; i < TARGET_NSIG_WORDS; i++) { for(i = 0; i < TARGET_NSIG_WORDS; i++) {
err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]); err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
} }
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. If provided, use a stub
@ -3038,14 +3038,14 @@ long do_rt_sigreturn(CPUState *regs)
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
goto badframe; goto badframe;
target_to_host_sigset(&blocked, &frame->uc.uc_sigmask); target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
sigprocmask(SIG_SETMASK, &blocked, NULL); sigprocmask(SIG_SETMASK, &blocked, NULL);
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
goto badframe; goto badframe;
if (do_sigaltstack(frame_addr + if (do_sigaltstack(frame_addr +
offsetof(struct target_rt_sigframe, uc.uc_stack), offsetof(struct target_rt_sigframe, uc.tuc_stack),
0, get_sp_from_cpustate(regs)) == -EFAULT) 0, get_sp_from_cpustate(regs)) == -EFAULT)
goto badframe; goto badframe;
@ -3555,22 +3555,22 @@ struct target_mcontext {
}; };
struct target_ucontext { struct target_ucontext {
target_ulong uc_flags; target_ulong tuc_flags;
target_ulong uc_link; /* struct ucontext __user * */ target_ulong tuc_link; /* struct ucontext __user * */
struct target_sigaltstack uc_stack; struct target_sigaltstack tuc_stack;
#if !defined(TARGET_PPC64) #if !defined(TARGET_PPC64)
int32_t uc_pad[7]; int32_t tuc_pad[7];
target_ulong uc_regs; /* struct mcontext __user * target_ulong tuc_regs; /* struct mcontext __user *
points to uc_mcontext field */ points to uc_mcontext field */
#endif #endif
target_sigset_t uc_sigmask; target_sigset_t tuc_sigmask;
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
target_sigset_t unused[15]; /* Allow for uc_sigmask growth */ target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
struct target_sigcontext uc_mcontext; struct target_sigcontext tuc_mcontext;
#else #else
int32_t uc_maskext[30]; int32_t tuc_maskext[30];
int32_t uc_pad2[3]; int32_t tuc_pad2[3];
struct target_mcontext uc_mcontext; struct target_mcontext tuc_mcontext;
#endif #endif
}; };
@ -3883,21 +3883,21 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
err |= copy_siginfo_to_user(&rt_sf->info, info); err |= copy_siginfo_to_user(&rt_sf->info, info);
err |= __put_user(0, &rt_sf->uc.uc_flags); err |= __put_user(0, &rt_sf->uc.tuc_flags);
err |= __put_user(0, &rt_sf->uc.uc_link); err |= __put_user(0, &rt_sf->uc.tuc_link);
err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp, err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
&rt_sf->uc.uc_stack.ss_sp); &rt_sf->uc.tuc_stack.ss_sp);
err |= __put_user(sas_ss_flags(env->gpr[1]), err |= __put_user(sas_ss_flags(env->gpr[1]),
&rt_sf->uc.uc_stack.ss_flags); &rt_sf->uc.tuc_stack.ss_flags);
err |= __put_user(target_sigaltstack_used.ss_size, err |= __put_user(target_sigaltstack_used.ss_size,
&rt_sf->uc.uc_stack.ss_size); &rt_sf->uc.tuc_stack.ss_size);
err |= __put_user(h2g (&rt_sf->uc.uc_mcontext), err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
&rt_sf->uc.uc_regs); &rt_sf->uc.tuc_regs);
for(i = 0; i < TARGET_NSIG_WORDS; i++) { for(i = 0; i < TARGET_NSIG_WORDS; i++) {
err |= __put_user(set->sig[i], &rt_sf->uc.uc_sigmask.sig[i]); err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
} }
frame = &rt_sf->uc.uc_mcontext; frame = &rt_sf->uc.tuc_mcontext;
err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn); err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
/* The kernel checks for the presence of a VDSO here. We don't /* The kernel checks for the presence of a VDSO here. We don't
@ -3985,7 +3985,7 @@ static int do_setcontext(struct target_ucontext *ucp, CPUState *env, int sig)
sigset_t blocked; sigset_t blocked;
target_sigset_t set; target_sigset_t set;
if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, uc_sigmask), if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
sizeof (set))) sizeof (set)))
return 1; return 1;
@ -3993,7 +3993,7 @@ static int do_setcontext(struct target_ucontext *ucp, CPUState *env, int sig)
fprintf (stderr, "do_setcontext: not implemented\n"); fprintf (stderr, "do_setcontext: not implemented\n");
return 0; return 0;
#else #else
if (__get_user(mcp_addr, &ucp->uc_regs)) if (__get_user(mcp_addr, &ucp->tuc_regs))
return 1; return 1;
if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1)) if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
@ -4026,7 +4026,7 @@ long do_rt_sigreturn(CPUState *env)
goto sigsegv; goto sigsegv;
do_sigaltstack(rt_sf_addr do_sigaltstack(rt_sf_addr
+ offsetof(struct target_rt_sigframe, uc.uc_stack), + offsetof(struct target_rt_sigframe, uc.tuc_stack),
0, env->gpr[1]); 0, env->gpr[1]);
unlock_user_struct(rt_sf, rt_sf_addr, 1); unlock_user_struct(rt_sf, rt_sf_addr, 1);
@ -4082,12 +4082,12 @@ struct target_mcontext {
#define TARGET_MCONTEXT_VERSION 2 #define TARGET_MCONTEXT_VERSION 2
struct target_ucontext { struct target_ucontext {
abi_ulong uc_flags; abi_ulong tuc_flags;
abi_ulong uc_link; abi_ulong tuc_link;
target_stack_t uc_stack; target_stack_t tuc_stack;
struct target_mcontext uc_mcontext; struct target_mcontext tuc_mcontext;
abi_long uc_filler[80]; abi_long tuc_filler[80];
target_sigset_t uc_sigmask; target_sigset_t tuc_sigmask;
}; };
struct target_rt_sigframe struct target_rt_sigframe
@ -4212,10 +4212,10 @@ give_sigsegv:
static inline int target_rt_setup_ucontext(struct target_ucontext *uc, static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
CPUState *env) CPUState *env)
{ {
target_greg_t *gregs = uc->uc_mcontext.gregs; target_greg_t *gregs = uc->tuc_mcontext.gregs;
int err; int err;
err = __put_user(TARGET_MCONTEXT_VERSION, &uc->uc_mcontext.version); err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
err |= __put_user(env->dregs[0], &gregs[0]); err |= __put_user(env->dregs[0], &gregs[0]);
err |= __put_user(env->dregs[1], &gregs[1]); err |= __put_user(env->dregs[1], &gregs[1]);
err |= __put_user(env->dregs[2], &gregs[2]); err |= __put_user(env->dregs[2], &gregs[2]);
@ -4244,9 +4244,9 @@ static inline int target_rt_restore_ucontext(CPUState *env,
{ {
int temp; int temp;
int err; int err;
target_greg_t *gregs = uc->uc_mcontext.gregs; target_greg_t *gregs = uc->tuc_mcontext.gregs;
err = __get_user(temp, &uc->uc_mcontext.version); err = __get_user(temp, &uc->tuc_mcontext.version);
if (temp != TARGET_MCONTEXT_VERSION) if (temp != TARGET_MCONTEXT_VERSION)
goto badframe; goto badframe;
@ -4306,21 +4306,21 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
/* Create the ucontext */ /* Create the ucontext */
err |= __put_user(0, &frame->uc.uc_flags); err |= __put_user(0, &frame->uc.tuc_flags);
err |= __put_user(0, &frame->uc.uc_link); err |= __put_user(0, &frame->uc.tuc_link);
err |= __put_user(target_sigaltstack_used.ss_sp, err |= __put_user(target_sigaltstack_used.ss_sp,
&frame->uc.uc_stack.ss_sp); &frame->uc.tuc_stack.ss_sp);
err |= __put_user(sas_ss_flags(env->aregs[7]), err |= __put_user(sas_ss_flags(env->aregs[7]),
&frame->uc.uc_stack.ss_flags); &frame->uc.tuc_stack.ss_flags);
err |= __put_user(target_sigaltstack_used.ss_size, err |= __put_user(target_sigaltstack_used.ss_size,
&frame->uc.uc_stack.ss_size); &frame->uc.tuc_stack.ss_size);
err |= target_rt_setup_ucontext(&frame->uc, env); err |= target_rt_setup_ucontext(&frame->uc, env);
if (err) if (err)
goto give_sigsegv; goto give_sigsegv;
for(i = 0; i < TARGET_NSIG_WORDS; i++) { for(i = 0; i < TARGET_NSIG_WORDS; i++) {
if (__put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i])) if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
goto give_sigsegv; goto give_sigsegv;
} }
@ -4409,7 +4409,7 @@ long do_rt_sigreturn(CPUState *env)
goto badframe; goto badframe;
if (do_sigaltstack(frame_addr + if (do_sigaltstack(frame_addr +
offsetof(struct target_rt_sigframe, uc.uc_stack), offsetof(struct target_rt_sigframe, uc.tuc_stack),
0, get_sp_from_cpustate(env)) == -EFAULT) 0, get_sp_from_cpustate(env)) == -EFAULT)
goto badframe; goto badframe;
@ -4447,12 +4447,12 @@ struct target_sigcontext {
}; };
struct target_ucontext { struct target_ucontext {
abi_ulong uc_flags; abi_ulong tuc_flags;
abi_ulong uc_link; abi_ulong tuc_link;
abi_ulong uc_osf_sigmask; abi_ulong tuc_osf_sigmask;
target_stack_t uc_stack; target_stack_t tuc_stack;
struct target_sigcontext uc_mcontext; struct target_sigcontext tuc_mcontext;
target_sigset_t uc_sigmask; target_sigset_t tuc_sigmask;
}; };
struct target_sigframe { struct target_sigframe {
@ -4588,18 +4588,18 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
err |= copy_siginfo_to_user(&frame->info, info); err |= copy_siginfo_to_user(&frame->info, info);
err |= __put_user(0, &frame->uc.uc_flags); err |= __put_user(0, &frame->uc.tuc_flags);
err |= __put_user(0, &frame->uc.uc_link); err |= __put_user(0, &frame->uc.tuc_link);
err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask); err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
err |= __put_user(target_sigaltstack_used.ss_sp, err |= __put_user(target_sigaltstack_used.ss_sp,
&frame->uc.uc_stack.ss_sp); &frame->uc.tuc_stack.ss_sp);
err |= __put_user(sas_ss_flags(env->ir[IR_SP]), err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
&frame->uc.uc_stack.ss_flags); &frame->uc.tuc_stack.ss_flags);
err |= __put_user(target_sigaltstack_used.ss_size, err |= __put_user(target_sigaltstack_used.ss_size,
&frame->uc.uc_stack.ss_size); &frame->uc.tuc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext, env, frame_addr, set); err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
for (i = 0; i < TARGET_NSIG_WORDS; ++i) { for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]); err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
} }
if (ka->sa_restorer) { if (ka->sa_restorer) {
@ -4668,14 +4668,14 @@ long do_rt_sigreturn(CPUState *env)
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
goto badframe; goto badframe;
} }
target_to_host_sigset(&set, &frame->uc.uc_sigmask); target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
sigprocmask(SIG_SETMASK, &set, NULL); sigprocmask(SIG_SETMASK, &set, NULL);
if (restore_sigcontext(env, &frame->uc.uc_mcontext)) { if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
goto badframe; goto badframe;
} }
if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe, if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
uc.uc_stack), uc.tuc_stack),
0, env->ir[IR_SP]) == -EFAULT) { 0, env->ir[IR_SP]) == -EFAULT) {
goto badframe; goto badframe;
} }

View File

@ -41,6 +41,10 @@
#include <sys/swap.h> #include <sys/swap.h>
#include <signal.h> #include <signal.h>
#include <sched.h> #include <sched.h>
#ifdef __ia64__
int __clone2(int (*fn)(void *), void *child_stack_base,
size_t stack_size, int flags, void *arg, ...);
#endif
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/uio.h> #include <sys/uio.h>
@ -3628,7 +3632,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
return -EINVAL; return -EINVAL;
/* This is probably going to die very quickly, but do it anyway. */ /* This is probably going to die very quickly, but do it anyway. */
#ifdef __ia64__ #ifdef __ia64__
ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
#else #else
ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
#endif #endif