Commit 9664d92872de669dbf87bdc376f3d993a6aa859a

Authored by edgar_igl
1 parent ccd4a219

CRIS signals:

* Save $mof across signals.
* Cleaned up frame accesses.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4012 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 58 additions and 57 deletions
linux-user/signal.c
@@ -2731,67 +2731,68 @@ struct rt_signal_frame { @@ -2731,67 +2731,68 @@ struct rt_signal_frame {
2731 2731
2732 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env) 2732 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2733 { 2733 {
2734 - sc->regs.r0 = env->regs[0];  
2735 - sc->regs.r1 = env->regs[1];  
2736 - sc->regs.r2 = env->regs[2];  
2737 - sc->regs.r3 = env->regs[3];  
2738 - sc->regs.r4 = env->regs[4];  
2739 - sc->regs.r5 = env->regs[5];  
2740 - sc->regs.r6 = env->regs[6];  
2741 - sc->regs.r7 = env->regs[7];  
2742 - sc->regs.r8 = env->regs[8];  
2743 - sc->regs.r9 = env->regs[9];  
2744 - sc->regs.r10 = env->regs[10];  
2745 - sc->regs.r11 = env->regs[11];  
2746 - sc->regs.r12 = env->regs[12];  
2747 - sc->regs.r13 = env->regs[13];  
2748 - sc->usp = env->regs[14];  
2749 - sc->regs.acr = env->regs[15];  
2750 - sc->regs.srp = env->pregs[PR_SRP];  
2751 - sc->regs.erp = env->pc;  
2752 -  
2753 - env->pregs[PR_ERP] = env->pc; 2734 + __put_user(env->regs[0], &sc->regs.r0);
  2735 + __put_user(env->regs[1], &sc->regs.r1);
  2736 + __put_user(env->regs[2], &sc->regs.r2);
  2737 + __put_user(env->regs[3], &sc->regs.r3);
  2738 + __put_user(env->regs[4], &sc->regs.r4);
  2739 + __put_user(env->regs[5], &sc->regs.r5);
  2740 + __put_user(env->regs[6], &sc->regs.r6);
  2741 + __put_user(env->regs[7], &sc->regs.r7);
  2742 + __put_user(env->regs[8], &sc->regs.r8);
  2743 + __put_user(env->regs[9], &sc->regs.r9);
  2744 + __put_user(env->regs[10], &sc->regs.r10);
  2745 + __put_user(env->regs[11], &sc->regs.r11);
  2746 + __put_user(env->regs[12], &sc->regs.r12);
  2747 + __put_user(env->regs[13], &sc->regs.r13);
  2748 + __put_user(env->regs[14], &sc->usp);
  2749 + __put_user(env->regs[15], &sc->regs.acr);
  2750 + __put_user(env->pregs[PR_MOF], &sc->regs.mof);
  2751 + __put_user(env->pregs[PR_SRP], &sc->regs.srp);
  2752 + __put_user(env->pc, &sc->regs.erp);
2754 } 2753 }
  2754 +
2755 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env) 2755 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2756 { 2756 {
2757 - env->regs[0] = sc->regs.r0;  
2758 - env->regs[1] = sc->regs.r1;  
2759 - env->regs[2] = sc->regs.r2;  
2760 - env->regs[3] = sc->regs.r3;  
2761 - env->regs[4] = sc->regs.r4;  
2762 - env->regs[5] = sc->regs.r5;  
2763 - env->regs[6] = sc->regs.r6;  
2764 - env->regs[7] = sc->regs.r7;  
2765 - env->regs[8] = sc->regs.r8;  
2766 - env->regs[9] = sc->regs.r9;  
2767 - env->regs[10] = sc->regs.r10;  
2768 - env->regs[11] = sc->regs.r11;  
2769 - env->regs[12] = sc->regs.r12;  
2770 - env->regs[13] = sc->regs.r13;  
2771 - env->regs[14] = sc->usp;  
2772 - env->regs[15] = sc->regs.acr;  
2773 -}  
2774 -  
2775 -static struct target_signal_frame *get_sigframe(CPUState *env, int framesize)  
2776 -{  
2777 - uint8_t *sp; 2757 + __get_user(env->regs[0], &sc->regs.r0);
  2758 + __get_user(env->regs[1], &sc->regs.r1);
  2759 + __get_user(env->regs[2], &sc->regs.r2);
  2760 + __get_user(env->regs[3], &sc->regs.r3);
  2761 + __get_user(env->regs[4], &sc->regs.r4);
  2762 + __get_user(env->regs[5], &sc->regs.r5);
  2763 + __get_user(env->regs[6], &sc->regs.r6);
  2764 + __get_user(env->regs[7], &sc->regs.r7);
  2765 + __get_user(env->regs[8], &sc->regs.r8);
  2766 + __get_user(env->regs[9], &sc->regs.r9);
  2767 + __get_user(env->regs[10], &sc->regs.r10);
  2768 + __get_user(env->regs[11], &sc->regs.r11);
  2769 + __get_user(env->regs[12], &sc->regs.r12);
  2770 + __get_user(env->regs[13], &sc->regs.r13);
  2771 + __get_user(env->regs[14], &sc->usp);
  2772 + __get_user(env->regs[15], &sc->regs.acr);
  2773 + __get_user(env->pregs[PR_MOF], &sc->regs.mof);
  2774 + __get_user(env->pregs[PR_SRP], &sc->regs.srp);
  2775 + __get_user(env->pc, &sc->regs.erp);
  2776 +}
  2777 +
  2778 +static abi_ulong get_sigframe(CPUState *env, int framesize)
  2779 +{
  2780 + abi_ulong sp;
2778 /* Align the stack downwards to 4. */ 2781 /* Align the stack downwards to 4. */
2779 - sp = (uint8_t *) (env->regs[R_SP] & ~3);  
2780 - return (void *)(sp - framesize); 2782 + sp = (env->regs[R_SP] & ~3);
  2783 + return sp - framesize;
2781 } 2784 }
2782 2785
2783 static void setup_frame(int sig, struct emulated_sigaction *ka, 2786 static void setup_frame(int sig, struct emulated_sigaction *ka,
2784 target_sigset_t *set, CPUState *env) 2787 target_sigset_t *set, CPUState *env)
2785 { 2788 {
2786 struct target_signal_frame *frame; 2789 struct target_signal_frame *frame;
  2790 + abi_ulong frame_addr;
2787 int err = 0; 2791 int err = 0;
2788 int i; 2792 int i;
2789 - uint32_t old_usp;  
2790 -  
2791 - old_usp = env->regs[R_SP];  
2792 2793
2793 - frame = get_sigframe(env, sizeof *frame);  
2794 - if (!lock_user_struct(VERIFY_WRITE, frame, (abi_ulong)frame, 1)) 2794 + frame_addr = get_sigframe(env, sizeof *frame);
  2795 + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2795 goto badframe; 2796 goto badframe;
2796 2797
2797 /* 2798 /*
@@ -2825,10 +2826,10 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -2825,10 +2826,10 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
2825 /* Link SRP so the guest returns through the trampoline. */ 2826 /* Link SRP so the guest returns through the trampoline. */
2826 env->pregs[PR_SRP] = (uint32_t) &frame->retcode[0]; 2827 env->pregs[PR_SRP] = (uint32_t) &frame->retcode[0];
2827 2828
2828 - unlock_user_struct(frame, (abi_ulong)frame, 0); 2829 + unlock_user_struct(frame, frame_addr, 1);
2829 return; 2830 return;
2830 badframe: 2831 badframe:
2831 - unlock_user_struct(frame, (abi_ulong)frame, 0); 2832 + unlock_user_struct(frame, frame_addr, 1);
2832 force_sig(TARGET_SIGSEGV); 2833 force_sig(TARGET_SIGSEGV);
2833 } 2834 }
2834 2835
@@ -2842,13 +2843,14 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -2842,13 +2843,14 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
2842 long do_sigreturn(CPUState *env) 2843 long do_sigreturn(CPUState *env)
2843 { 2844 {
2844 struct target_signal_frame *frame; 2845 struct target_signal_frame *frame;
  2846 + abi_ulong frame_addr;
2845 target_sigset_t target_set; 2847 target_sigset_t target_set;
2846 sigset_t set; 2848 sigset_t set;
2847 int i; 2849 int i;
2848 2850
2849 - frame = (void *) env->regs[R_SP]; 2851 + frame_addr = env->regs[R_SP];
2850 /* Make sure the guest isn't playing games. */ 2852 /* Make sure the guest isn't playing games. */
2851 - if (!lock_user_struct(VERIFY_READ, frame, (abi_ulong)frame, 1)) 2853 + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
2852 goto badframe; 2854 goto badframe;
2853 2855
2854 /* Restore blocked signals */ 2856 /* Restore blocked signals */
@@ -2862,14 +2864,13 @@ long do_sigreturn(CPUState *env) @@ -2862,14 +2864,13 @@ long do_sigreturn(CPUState *env)
2862 sigprocmask(SIG_SETMASK, &set, NULL); 2864 sigprocmask(SIG_SETMASK, &set, NULL);
2863 2865
2864 restore_sigcontext(&frame->sc, env); 2866 restore_sigcontext(&frame->sc, env);
2865 - /* Compensate -2 for the syscall return path advancing brk. */  
2866 - env->pc = frame->sc.regs.erp - 2;  
2867 - env->pregs[PR_SRP] = frame->sc.regs.srp; 2867 + /* Compensate for the syscall return path advancing brk. */
  2868 + env->pc -= 2;
2868 2869
2869 - unlock_user_struct(frame, (abi_ulong)frame, 0); 2870 + unlock_user_struct(frame, frame_addr, 0);
2870 return env->regs[10]; 2871 return env->regs[10];
2871 badframe: 2872 badframe:
2872 - unlock_user_struct(frame, (abi_ulong)frame, 0); 2873 + unlock_user_struct(frame, frame_addr, 0);
2873 force_sig(TARGET_SIGSEGV); 2874 force_sig(TARGET_SIGSEGV);
2874 } 2875 }
2875 2876