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