microblaze: Pass a ucontext * as 3rd sighandler arg

There is disagreement between microblaze glibc and the kernel
to what the third arg of signal handlers should point to.

Change QEMU linux-user to match the kernel port. glibc patches
are pending.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@petalogix.com>
master
Edgar E. Iglesias 2010-07-23 09:30:37 +02:00 committed by Edgar E. Iglesias
parent 24ab68ac72
commit b2178704e4
1 changed files with 20 additions and 6 deletions

View File

@ -3064,9 +3064,23 @@ struct target_sigcontext {
uint32_t oldmask; uint32_t oldmask;
}; };
struct target_stack_t {
abi_ulong ss_sp;
int ss_flags;
unsigned int ss_size;
};
struct target_ucontext {
abi_ulong uc_flags;
abi_ulong uc_link;
struct target_stack_t uc_stack;
struct target_sigcontext sc;
uint32_t extramask[TARGET_NSIG_WORDS - 1];
};
/* Signal frames. */ /* Signal frames. */
struct target_signal_frame { struct target_signal_frame {
struct target_sigcontext sc; struct target_ucontext uc;
uint32_t extramask[TARGET_NSIG_WORDS - 1]; uint32_t extramask[TARGET_NSIG_WORDS - 1];
uint32_t tramp[2]; uint32_t tramp[2];
}; };
@ -3175,7 +3189,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
goto badframe; goto badframe;
/* Save the mask. */ /* Save the mask. */
err |= __put_user(set->sig[0], &frame->sc.oldmask); err |= __put_user(set->sig[0], &frame->uc.sc.oldmask);
if (err) if (err)
goto badframe; goto badframe;
@ -3184,7 +3198,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
goto badframe; goto badframe;
} }
setup_sigcontext(&frame->sc, env); setup_sigcontext(&frame->uc.sc, env);
/* Set up to return from userspace. If provided, use a stub /* Set up to return from userspace. If provided, use a stub
already in userspace. */ already in userspace. */
@ -3214,7 +3228,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
/* Signal handler args: */ /* Signal handler args: */
env->regs[5] = sig; /* Arg 0: signum */ env->regs[5] = sig; /* Arg 0: signum */
env->regs[6] = 0; env->regs[6] = 0;
env->regs[7] = (unsigned long) &frame->sc; /* arg 1: sigcontext */ env->regs[7] = (unsigned long) &frame->uc; /* arg 1: sigcontext */
/* Offset of 4 to handle microblaze rtid r14, 0 */ /* Offset of 4 to handle microblaze rtid r14, 0 */
env->sregs[SR_PC] = (unsigned long)ka->_sa_handler; env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
@ -3247,7 +3261,7 @@ long do_sigreturn(CPUState *env)
goto badframe; goto badframe;
/* Restore blocked signals */ /* Restore blocked signals */
if (__get_user(target_set.sig[0], &frame->sc.oldmask)) if (__get_user(target_set.sig[0], &frame->uc.sc.oldmask))
goto badframe; goto badframe;
for(i = 1; i < TARGET_NSIG_WORDS; i++) { for(i = 1; i < TARGET_NSIG_WORDS; i++) {
if (__get_user(target_set.sig[i], &frame->extramask[i - 1])) if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
@ -3256,7 +3270,7 @@ long do_sigreturn(CPUState *env)
target_to_host_sigset_internal(&set, &target_set); target_to_host_sigset_internal(&set, &target_set);
sigprocmask(SIG_SETMASK, &set, NULL); sigprocmask(SIG_SETMASK, &set, NULL);
restore_sigcontext(&frame->sc, env); restore_sigcontext(&frame->uc.sc, env);
/* We got here through a sigreturn syscall, our path back is via an /* We got here through a sigreturn syscall, our path back is via an
rtb insn so setup r14 for that. */ rtb insn so setup r14 for that. */
env->regs[14] = env->sregs[SR_PC]; env->regs[14] = env->sregs[SR_PC];