?? signal.c
字號:
force_sig(TARGET_SIGSEGV /* , current */);}static intrestore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax){ unsigned int err = 0; abi_ulong fpstate_addr; unsigned int tmpflags; cpu_x86_load_seg(env, R_GS, tswap16(sc->gs)); cpu_x86_load_seg(env, R_FS, tswap16(sc->fs)); cpu_x86_load_seg(env, R_ES, tswap16(sc->es)); cpu_x86_load_seg(env, R_DS, tswap16(sc->ds)); env->regs[R_EDI] = tswapl(sc->edi); env->regs[R_ESI] = tswapl(sc->esi); env->regs[R_EBP] = tswapl(sc->ebp); env->regs[R_ESP] = tswapl(sc->esp); env->regs[R_EBX] = tswapl(sc->ebx); env->regs[R_EDX] = tswapl(sc->edx); env->regs[R_ECX] = tswapl(sc->ecx); env->eip = tswapl(sc->eip); cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3); cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3); tmpflags = tswapl(sc->eflags); env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5); // regs->orig_eax = -1; /* disable syscall checks */ fpstate_addr = tswapl(sc->fpstate); if (fpstate_addr != 0) { if (!access_ok(VERIFY_READ, fpstate_addr, sizeof(struct target_fpstate))) goto badframe; cpu_x86_frstor(env, fpstate_addr, 1); } *peax = tswapl(sc->eax); return err;badframe: return 1;}long do_sigreturn(CPUX86State *env){ struct sigframe *frame; abi_ulong frame_addr = env->regs[R_ESP] - 8; target_sigset_t target_set; sigset_t set; int eax, i;#if defined(DEBUG_SIGNAL) fprintf(stderr, "do_sigreturn\n");#endif if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) goto badframe; /* set blocked signals */ if (__get_user(target_set.sig[0], &frame->sc.oldmask)) goto badframe; for(i = 1; i < TARGET_NSIG_WORDS; i++) { if (__get_user(target_set.sig[i], &frame->extramask[i - 1])) goto badframe; } target_to_host_sigset_internal(&set, &target_set); sigprocmask(SIG_SETMASK, &set, NULL); /* restore registers */ if (restore_sigcontext(env, &frame->sc, &eax)) goto badframe; unlock_user_struct(frame, frame_addr, 0); return eax;badframe: unlock_user_struct(frame, frame_addr, 0); force_sig(TARGET_SIGSEGV); return 0;}long do_rt_sigreturn(CPUX86State *env){ abi_ulong frame_addr; struct rt_sigframe *frame; sigset_t set; int eax; frame_addr = env->regs[R_ESP] - 4; if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) goto badframe; target_to_host_sigset(&set, &frame->uc.tuc_sigmask); sigprocmask(SIG_SETMASK, &set, NULL); if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax)) goto badframe; if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT) goto badframe; unlock_user_struct(frame, frame_addr, 0); return eax;badframe: unlock_user_struct(frame, frame_addr, 0); force_sig(TARGET_SIGSEGV); return 0;}#elif defined(TARGET_ARM)struct target_sigcontext { abi_ulong trap_no; abi_ulong error_code; abi_ulong oldmask; abi_ulong arm_r0; abi_ulong arm_r1; abi_ulong arm_r2; abi_ulong arm_r3; abi_ulong arm_r4; abi_ulong arm_r5; abi_ulong arm_r6; abi_ulong arm_r7; abi_ulong arm_r8; abi_ulong arm_r9; abi_ulong arm_r10; abi_ulong arm_fp; abi_ulong arm_ip; abi_ulong arm_sp; abi_ulong arm_lr; abi_ulong arm_pc; abi_ulong arm_cpsr; abi_ulong fault_address;};struct target_ucontext { abi_ulong tuc_flags; abi_ulong tuc_link; target_stack_t tuc_stack; struct target_sigcontext tuc_mcontext; target_sigset_t tuc_sigmask; /* mask last for extensibility */};struct sigframe{ struct target_sigcontext sc; abi_ulong extramask[TARGET_NSIG_WORDS-1]; abi_ulong retcode;};struct rt_sigframe{ abi_ulong pinfo; abi_ulong puc; struct target_siginfo info; struct target_ucontext uc; abi_ulong retcode;};#define TARGET_CONFIG_CPU_32 1/* * For ARM syscalls, we encode the syscall number into the instruction. */#define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))#define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))/* * For Thumb syscalls, we pass the syscall number via r7. We therefore * need two 16-bit instructions. */#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))static const abi_ulong retcodes[4] = { SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN};#define __put_user_error(x,p,e) __put_user(x, p)#define __get_user_error(x,p,e) __get_user(x, p)static inline int valid_user_regs(CPUState *regs){ return 1;}static intsetup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ CPUState *env, abi_ulong mask){ int err = 0; __put_user_error(env->regs[0], &sc->arm_r0, err); __put_user_error(env->regs[1], &sc->arm_r1, err); __put_user_error(env->regs[2], &sc->arm_r2, err); __put_user_error(env->regs[3], &sc->arm_r3, err); __put_user_error(env->regs[4], &sc->arm_r4, err); __put_user_error(env->regs[5], &sc->arm_r5, err); __put_user_error(env->regs[6], &sc->arm_r6, err); __put_user_error(env->regs[7], &sc->arm_r7, err); __put_user_error(env->regs[8], &sc->arm_r8, err); __put_user_error(env->regs[9], &sc->arm_r9, err); __put_user_error(env->regs[10], &sc->arm_r10, err); __put_user_error(env->regs[11], &sc->arm_fp, err); __put_user_error(env->regs[12], &sc->arm_ip, err); __put_user_error(env->regs[13], &sc->arm_sp, err); __put_user_error(env->regs[14], &sc->arm_lr, err); __put_user_error(env->regs[15], &sc->arm_pc, err);#ifdef TARGET_CONFIG_CPU_32 __put_user_error(cpsr_read(env), &sc->arm_cpsr, err);#endif __put_user_error(/* current->thread.trap_no */ 0, &sc->trap_no, err); __put_user_error(/* current->thread.error_code */ 0, &sc->error_code, err); __put_user_error(/* current->thread.address */ 0, &sc->fault_address, err); __put_user_error(mask, &sc->oldmask, err); return err;}static inline abi_ulongget_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize){ unsigned long sp = regs->regs[13]; /* * This is the X/Open sanctioned signal stack switching. */ if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; /* * ATPCS B01 mandates 8-byte alignment */ return (sp - framesize) & ~7;}static intsetup_return(CPUState *env, struct emulated_sigaction *ka, abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr){ abi_ulong handler = ka->sa._sa_handler; abi_ulong retcode; int thumb = 0;#if defined(TARGET_CONFIG_CPU_32)#if 0 abi_ulong cpsr = env->cpsr; /* * Maybe we need to deliver a 32-bit signal to a 26-bit task. */ if (ka->sa.sa_flags & SA_THIRTYTWO) cpsr = (cpsr & ~MODE_MASK) | USR_MODE;#ifdef CONFIG_ARM_THUMB if (elf_hwcap & HWCAP_THUMB) { /* * The LSB of the handler determines if we're going to * be using THUMB or ARM mode for this signal handler. */ thumb = handler & 1; if (thumb) cpsr |= T_BIT; else cpsr &= ~T_BIT; }#endif /* CONFIG_ARM_THUMB */#endif /* 0 */#endif /* TARGET_CONFIG_CPU_32 */ if (ka->sa.sa_flags & TARGET_SA_RESTORER) { retcode = ka->sa.sa_restorer; } else { unsigned int idx = thumb; if (ka->sa.sa_flags & TARGET_SA_SIGINFO) idx += 2; if (__put_user(retcodes[idx], rc)) return 1;#if 0 flush_icache_range((abi_ulong)rc, (abi_ulong)(rc + 1));#endif retcode = rc_addr + thumb; } env->regs[0] = usig; env->regs[13] = frame_addr; env->regs[14] = retcode; env->regs[15] = handler & (thumb ? ~1 : ~3);#if 0#ifdef TARGET_CONFIG_CPU_32 env->cpsr = cpsr;#endif#endif return 0;}/* compare linux/arch/arm/kernel/signal.c:setup_frame() */static void setup_frame(int usig, struct emulated_sigaction *ka, target_sigset_t *set, CPUState *regs){ struct sigframe *frame; abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame)); int i, err = 0; if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) return; err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]); for(i = 1; i < TARGET_NSIG_WORDS; i++) { if (__put_user(set->sig[i], &frame->extramask[i - 1])) goto end; } if (err == 0) err = setup_return(regs, ka, &frame->retcode, frame_addr, usig, frame_addr + offsetof(struct sigframe, retcode));end: unlock_user_struct(frame, frame_addr, 1); // return err;}/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */static void setup_rt_frame(int usig, struct emulated_sigaction *ka, target_siginfo_t *info, target_sigset_t *set, CPUState *env){ struct rt_sigframe *frame; abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame)); struct target_sigaltstack stack; int i, err = 0; abi_ulong info_addr, uc_addr; if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) return /* 1 */; info_addr = frame_addr + offsetof(struct rt_sigframe, info); __put_user_error(info_addr, &frame->pinfo, err); uc_addr = frame_addr + offsetof(struct rt_sigframe, uc); __put_user_error(uc_addr, &frame->puc, err); err |= copy_siginfo_to_user(&frame->info, info); /* Clear all the bits of the ucontext we don't use. */ memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext)); memset(&stack, 0, sizeof(stack)); __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp); __put_user(target_sigaltstack_used.ss_size, &stack.ss_size); __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags); memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack)); err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/ env, set->sig[0]); for(i = 0; i < TARGET_NSIG_WORDS; i++) { if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i])) goto end; } if (err == 0) err = setup_return(env, ka, &frame->retcode, frame_addr, usig, frame_addr + offsetof(struct rt_sigframe, retcode)); if (err == 0) { /* * For realtime signals we must also set the second and third * arguments for the signal handler. * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06 */ env->regs[1] = info_addr; env->regs[2] = uc_addr; }end: unlock_user_struct(frame, frame_addr, 1); // return err;}static intrestore_sigcontext(CPUState *env, struct target_sigcontext *sc){ int err = 0; uint32_t cpsr; __get_user_error(env->regs[0], &sc->arm_r0, err); __get_user_error(env->regs[1], &sc->arm_r1, err); __get_user_error(env->regs[2], &sc->arm_r2, err); __get_user_error(env->regs[3], &sc->arm_r3, err); __get_user_error(env->regs[4], &sc->arm_r4, err); __get_user_error(env->regs[5], &sc->arm_r5, err); __get_user_error(env->regs[6], &sc->arm_r6, err); __get_user_error(env->regs[7], &sc->arm_r7, err); __get_user_error(env->regs[8], &sc->arm_r8, err); __get_user_error(env->regs[9], &sc->arm_r9, err); __get_user_error(env->regs[10], &sc->arm_r10, err); __get_user_error(env->regs[11], &sc->arm_fp, err); __get_user_error(env->regs[12], &sc->arm_ip, err); __get_user_error(env->regs[13], &sc->arm_sp, err); __get_user_error(env->regs[14], &sc->arm_lr, err); __get_user_error(env->regs[15], &sc->arm_pc, err);#ifdef TARGET_CONFIG_CPU_32 __get_user_error(cpsr, &sc->arm_cpsr, err); cpsr_write(env, cpsr, 0xffffffff);#endif err |= !valid_user_regs(env); return err;}long do_sigreturn(CPUState *env){ abi_ulong frame_addr; struct sigframe *frame; target_sigset_t set; sigset_t host_set; int i; /* * Since we stacked the signal on a 64-bit boundary, * then 'sp' should be word aligned here. If it's * not, then the user is trying to mess with us. */ if (env->regs[13] & 7) goto badframe; frame_addr = env->regs[13]; if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask)) goto badframe; for(i = 1; i < TARGET_NSIG_WORDS; i++) { if (__get_user(set.sig[i], &frame->extramask[i - 1]))
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -