Revision 492a8744 linux-user/signal.c

b/linux-user/signal.c
4028 4028
    return 0;
4029 4029
}
4030 4030

  
4031
#elif defined(TARGET_M68K)
4032

  
4033
struct target_sigcontext {
4034
    abi_ulong  sc_mask;
4035
    abi_ulong  sc_usp;
4036
    abi_ulong  sc_d0;
4037
    abi_ulong  sc_d1;
4038
    abi_ulong  sc_a0;
4039
    abi_ulong  sc_a1;
4040
    unsigned short sc_sr;
4041
    abi_ulong  sc_pc;
4042
};
4043

  
4044
struct target_sigframe
4045
{
4046
    abi_ulong pretcode;
4047
    int sig;
4048
    int code;
4049
    abi_ulong psc;
4050
    char retcode[8];
4051
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
4052
    struct target_sigcontext sc;
4053
};
4054

  
4055
static int
4056
setup_sigcontext(struct target_sigcontext *sc, CPUState *env, abi_ulong mask)
4057
{
4058
    int err = 0;
4059

  
4060
    err |= __put_user(mask, &sc->sc_mask);
4061
    err |= __put_user(env->aregs[7], &sc->sc_usp);
4062
    err |= __put_user(env->dregs[0], &sc->sc_d0);
4063
    err |= __put_user(env->dregs[1], &sc->sc_d1);
4064
    err |= __put_user(env->aregs[0], &sc->sc_a0);
4065
    err |= __put_user(env->aregs[1], &sc->sc_a1);
4066
    err |= __put_user(env->sr, &sc->sc_sr);
4067
    err |= __put_user(env->pc, &sc->sc_pc);
4068

  
4069
    return err;
4070
}
4071

  
4072
static int
4073
restore_sigcontext(CPUState *env, struct target_sigcontext *sc, int *pd0)
4074
{
4075
    int err = 0;
4076
    int temp;
4077

  
4078
    err |= __get_user(env->aregs[7], &sc->sc_usp);
4079
    err |= __get_user(env->dregs[1], &sc->sc_d1);
4080
    err |= __get_user(env->aregs[0], &sc->sc_a0);
4081
    err |= __get_user(env->aregs[1], &sc->sc_a1);
4082
    err |= __get_user(env->pc, &sc->sc_pc);
4083
    err |= __get_user(temp, &sc->sc_sr);
4084
    env->sr = (env->sr & 0xff00) | (temp & 0xff);
4085

  
4086
    *pd0 = tswapl(sc->sc_d0);
4087

  
4088
    return err;
4089
}
4090

  
4091
/*
4092
 * Determine which stack to use..
4093
 */
4094
static inline abi_ulong
4095
get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
4096
{
4097
    unsigned long sp;
4098

  
4099
    sp = regs->aregs[7];
4100

  
4101
    /* This is the X/Open sanctioned signal stack switching.  */
4102
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
4103
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4104
    }
4105

  
4106
    return ((sp - frame_size) & -8UL);
4107
}
4108

  
4109
static void setup_frame(int sig, struct target_sigaction *ka,
4110
			target_sigset_t *set, CPUState *env)
4111
{
4112
    struct target_sigframe *frame;
4113
    abi_ulong frame_addr;
4114
    abi_ulong retcode_addr;
4115
    abi_ulong sc_addr;
4116
    int err = 0;
4117
    int i;
4118

  
4119
    frame_addr = get_sigframe(ka, env, sizeof *frame);
4120
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4121
	goto give_sigsegv;
4122

  
4123
    err |= __put_user(sig, &frame->sig);
4124

  
4125
    sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
4126
    err |= __put_user(sc_addr, &frame->psc);
4127

  
4128
    err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4129
    if (err)
4130
	goto give_sigsegv;
4131

  
4132
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4133
        if (__put_user(set->sig[i], &frame->extramask[i - 1]))
4134
            goto give_sigsegv;
4135
    }
4136

  
4137
    /* Set up to return from userspace.  */
4138

  
4139
    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4140
    err |= __put_user(retcode_addr, &frame->pretcode);
4141

  
4142
    /* moveq #,d0; trap #0 */
4143

  
4144
    err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
4145
                      (long *)(frame->retcode));
4146

  
4147
    if (err)
4148
        goto give_sigsegv;
4149

  
4150
    /* Set up to return from userspace */
4151

  
4152
    env->aregs[7] = frame_addr;
4153
    env->pc = ka->_sa_handler;
4154

  
4155
    unlock_user_struct(frame, frame_addr, 1);
4156
    return;
4157

  
4158
give_sigsegv:
4159
    unlock_user_struct(frame, frame_addr, 1);
4160
    force_sig(SIGSEGV);
4161
}
4162

  
4163
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4164
                           target_siginfo_t *info,
4165
			   target_sigset_t *set, CPUState *env)
4166
{
4167
    fprintf(stderr, "setup_rt_frame: not implemented\n");
4168
}
4169

  
4170
long do_sigreturn(CPUState *env)
4171
{
4172
    struct target_sigframe *frame;
4173
    abi_ulong frame_addr = env->aregs[7] - 4;
4174
    target_sigset_t target_set;
4175
    sigset_t set;
4176
    int d0, i;
4177

  
4178
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4179
        goto badframe;
4180

  
4181
    /* set blocked signals */
4182

  
4183
    if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
4184
        goto badframe;
4185

  
4186
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4187
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
4188
            goto badframe;
4189
    }
4190

  
4191
    target_to_host_sigset_internal(&set, &target_set);
4192
    sigprocmask(SIG_SETMASK, &set, NULL);
4193

  
4194
    /* restore registers */
4195

  
4196
    if (restore_sigcontext(env, &frame->sc, &d0))
4197
        goto badframe;
4198

  
4199
    unlock_user_struct(frame, frame_addr, 0);
4200
    return d0;
4201

  
4202
badframe:
4203
    unlock_user_struct(frame, frame_addr, 0);
4204
    force_sig(TARGET_SIGSEGV);
4205
    return 0;
4206
}
4207

  
4208
long do_rt_sigreturn(CPUState *env)
4209
{
4210
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
4211
    return -TARGET_ENOSYS;
4212
}
4213

  
4031 4214
#else
4032 4215

  
4033 4216
static void setup_frame(int sig, struct target_sigaction *ka,

Also available in: Unified diff