Revision 28be6234 linux-user/signal.c

b/linux-user/signal.c
667 667
/* XXX: save x87 state */
668 668
static int
669 669
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
670
		 CPUX86State *env, unsigned long mask)
670
		 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
671 671
{
672 672
	int err = 0;
673 673
        uint16_t magic;
......
693 693
	err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
694 694
	err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
695 695

  
696
        cpu_x86_fsave(env, (void *)fpstate, 1);
696
        cpu_x86_fsave(env, fpstate_addr, 1);
697 697
        fpstate->status = fpstate->sw;
698 698
        magic = 0xffff;
699 699
        err |= __put_user(magic, &fpstate->magic);
700
        err |= __put_user(fpstate, &sc->fpstate);
700
        err |= __put_user(fpstate_addr, &sc->fpstate);
701 701

  
702 702
	/* non-iBCS2 extensions.. */
703 703
	err |= __put_user(mask, &sc->oldmask);
......
754 754
	if (err)
755 755
		goto give_sigsegv;
756 756

  
757
	setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
757
	setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
758
                         frame_addr + offsetof(struct sigframe, fpstate));
758 759
	if (err)
759 760
		goto give_sigsegv;
760 761

  
......
769 770
		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
770 771
	} else {
771 772
                uint16_t val16;
772
		err |= __put_user(frame->retcode, &frame->pretcode);
773
                abi_ulong retcode_addr;
774
                retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
775
		err |= __put_user(retcode_addr, &frame->pretcode);
773 776
		/* This is popl %eax ; movl $,%eax ; int $0x80 */
774 777
                val16 = 0xb858;
775 778
		err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
......
782 785
		goto give_sigsegv;
783 786

  
784 787
	/* Set up registers for signal handler */
785
	env->regs[R_ESP] = h2g(frame);
786
	env->eip = (unsigned long) ka->sa._sa_handler;
788
	env->regs[R_ESP] = frame_addr;
789
	env->eip = ka->sa._sa_handler;
787 790

  
788 791
        cpu_x86_load_seg(env, R_DS, __USER_DS);
789 792
        cpu_x86_load_seg(env, R_ES, __USER_DS);
......
807 810
                           target_siginfo_t *info,
808 811
			   target_sigset_t *set, CPUX86State *env)
809 812
{
810
	abi_ulong frame_addr;
813
        abi_ulong frame_addr, addr;
811 814
	struct rt_sigframe *frame;
812 815
	int i, err = 0;
813 816

  
......
822 825
		    	   ? current->exec_domain->signal_invmap[sig]
823 826
			   : */sig),
824 827
			  &frame->sig);
825
	err |= __put_user((abi_ulong)&frame->info, &frame->pinfo);
826
	err |= __put_user((abi_ulong)&frame->uc, &frame->puc);
828
        addr = frame_addr + offsetof(struct rt_sigframe, info);
829
	err |= __put_user(addr, &frame->pinfo);
830
        addr = frame_addr + offsetof(struct rt_sigframe, uc);
831
	err |= __put_user(addr, &frame->puc);
827 832
	err |= copy_siginfo_to_user(&frame->info, info);
828 833
	if (err)
829 834
		goto give_sigsegv;
......
838 843
	err |= __put_user(target_sigaltstack_used.ss_size,
839 844
			  &frame->uc.tuc_stack.ss_size);
840 845
	err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
841
			        env, set->sig[0]);
846
			        env, set->sig[0], 
847
                                frame_addr + offsetof(struct rt_sigframe, fpstate));
842 848
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
843 849
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
844 850
                goto give_sigsegv;
......
850 856
		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
851 857
	} else {
852 858
                uint16_t val16;
853
                
854
		err |= __put_user(frame->retcode, &frame->pretcode);
859
                addr = frame_addr + offsetof(struct rt_sigframe, retcode);
860
		err |= __put_user(addr, &frame->pretcode);
855 861
		/* This is movl $,%eax ; int $0x80 */
856 862
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
857 863
		err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
......
863 869
		goto give_sigsegv;
864 870

  
865 871
	/* Set up registers for signal handler */
866
	env->regs[R_ESP] = (unsigned long) frame;
867
	env->eip = (unsigned long) ka->sa._sa_handler;
872
	env->regs[R_ESP] = frame_addr;
873
	env->eip = ka->sa._sa_handler;
868 874

  
869 875
        cpu_x86_load_seg(env, R_DS, __USER_DS);
870 876
        cpu_x86_load_seg(env, R_ES, __USER_DS);
......
887 893
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
888 894
{
889 895
	unsigned int err = 0;
890

  
891
        cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
892
        cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
893
        cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
894
        cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
895

  
896
        env->regs[R_EDI] = ldl(&sc->edi);
897
        env->regs[R_ESI] = ldl(&sc->esi);
898
        env->regs[R_EBP] = ldl(&sc->ebp);
899
        env->regs[R_ESP] = ldl(&sc->esp);
900
        env->regs[R_EBX] = ldl(&sc->ebx);
901
        env->regs[R_EDX] = ldl(&sc->edx);
902
        env->regs[R_ECX] = ldl(&sc->ecx);
903
        env->eip = ldl(&sc->eip);
896
        abi_ulong fpstate_addr;
897
        unsigned int tmpflags;
898

  
899
        cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
900
        cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
901
        cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
902
        cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
903

  
904
        env->regs[R_EDI] = tswapl(sc->edi);
905
        env->regs[R_ESI] = tswapl(sc->esi);
906
        env->regs[R_EBP] = tswapl(sc->ebp);
907
        env->regs[R_ESP] = tswapl(sc->esp);
908
        env->regs[R_EBX] = tswapl(sc->ebx);
909
        env->regs[R_EDX] = tswapl(sc->edx);
910
        env->regs[R_ECX] = tswapl(sc->ecx);
911
        env->eip = tswapl(sc->eip);
904 912

  
905 913
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
906 914
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
907 915

  
908
	{
909
		unsigned int tmpflags;
910
                tmpflags = ldl(&sc->eflags);
911
		env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
912
                //		regs->orig_eax = -1;		/* disable syscall checks */
913
	}
916
        tmpflags = tswapl(sc->eflags);
917
        env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
918
        //		regs->orig_eax = -1;		/* disable syscall checks */
914 919

  
915
	{
916
		struct _fpstate * buf;
917
                buf = (void *)ldl(&sc->fpstate);
918
		if (buf) {
919
#if 0
920
			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
921
				goto badframe;
922
#endif
923
                        cpu_x86_frstor(env, (void *)buf, 1);
924
		}
920
        fpstate_addr = tswapl(sc->fpstate);
921
	if (fpstate_addr != 0) {
922
                if (!access_ok(VERIFY_READ, fpstate_addr, 
923
                               sizeof(struct target_fpstate)))
924
                        goto badframe;
925
                cpu_x86_frstor(env, fpstate_addr, 1);
925 926
	}
926 927

  
927
        *peax = ldl(&sc->eax);
928
        *peax = tswapl(sc->eax);
928 929
	return err;
929
#if 0
930 930
badframe:
931 931
	return 1;
932
#endif
933 932
}
934 933

  
935 934
long do_sigreturn(CPUX86State *env)
......
970 969

  
971 970
long do_rt_sigreturn(CPUX86State *env)
972 971
{
973
	struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4);
972
        abi_ulong frame_addr;
973
	struct rt_sigframe *frame;
974 974
        sigset_t set;
975 975
	int eax;
976 976

  
977
#if 0
978
	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
979
		goto badframe;
980
#endif
977
        frame_addr = env->regs[R_ESP] - 4;
978
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
979
                goto badframe;
981 980
        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
982 981
        sigprocmask(SIG_SETMASK, &set, NULL);
983 982

  
984 983
	if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
985 984
		goto badframe;
986 985

  
987
	if (do_sigaltstack(h2g(&frame->uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
986
	if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
987
                           get_sp_from_cpustate(env)) == -EFAULT)
988 988
		goto badframe;
989 989

  
990
        unlock_user_struct(frame, frame_addr, 0);
990 991
	return eax;
991 992

  
992 993
badframe:
993
	force_sig(TARGET_SIGSEGV);
994
        unlock_user_struct(frame, frame_addr, 0);
995
        force_sig(TARGET_SIGSEGV);
994 996
	return 0;
995 997
}
996 998

  

Also available in: Unified diff