0

我阅读了有关信号句柄的内核代码,据我所知,x32 从堆栈而不是寄存器中获取参数。但我无法理解下面的代码。

void (*sa_sigaction)(int, siginfo_t *, void *);

if (is_ia32_frame(ksig)) {
    if (ksig->ka.sa.sa_flags & SA_SIGINFO)
        return ia32_setup_rt_frame(usig, ksig, cset, regs);
    else
        return ia32_setup_frame(usig, ksig, cset, regs);
} else if (is_x32_frame(ksig)) {
    return **x32_setup_rt_frame**(ksig, cset, regs);
} else {
    return __setup_rt_frame(ksig->sig, ksig, set, regs);
}


static int x32_setup_rt_frame(struct ksignal *ksig,
                    compat_sigset_t *set,
                    struct pt_regs *regs)
{
#ifdef CONFIG_X86_X32_ABI
    struct rt_sigframe_x32 __user *frame;
    void __user *restorer;
    int err = 0;
    void __user *fpstate = NULL;

    frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);

    if (!access_ok(frame, sizeof(*frame)))
        return -EFAULT;

    if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
        if (__copy_siginfo_to_user32(&frame->info, &ksig->info, true))
            return -EFAULT;
    }

    put_user_try {
        /* Create the ucontext.  */
        put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags);
        put_user_ex(0, &frame->uc.uc_link);
        compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
        put_user_ex(0, &frame->uc.uc__pad0);

        if (ksig->ka.sa.sa_flags & SA_RESTORER) {
            restorer = ksig->ka.sa.sa_restorer;
        } else {
            /* could use a vstub here */
            restorer = NULL;
            err |= -EFAULT;
        }
        put_user_ex(restorer, &frame->pretcode);
    } put_user_catch(err);

    err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
                regs, set->sig[0]);
    err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

    if (err)
        return -EFAULT;

    /* Set up registers for signal handler */
    regs->sp = (unsigned long) frame;
    regs->ip = (unsigned long) ksig->ka.sa.sa_handler;

    /* We use the x32 calling convention here... */
    regs->di = ksig->sig;
    **regs->si = (unsigned long) &frame->info;
    regs->dx = (unsigned long) &frame->uc;**

    loadsegment(ds, __USER_DS);
    loadsegment(es, __USER_DS);

    regs->cs = __USER_CS;
    regs->ss = __USER_DS;

    #endif  /* CONFIG_X86_X32_ABI */

    return 0;
}

我希望“&frame->info”和“&frame->uc”应该放在“frame”,因为“frame”是堆栈,信号句柄从堆栈中获取参数。

但是上面的代码显示“&frame->info”和“&frame->uc”位于regs,那么信号句柄如何获取这两个参数

4

0 回答 0