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 2731  
2732 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 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 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 2786 static void setup_frame(int sig, struct emulated_sigaction *ka,
2784 2787 target_sigset_t *set, CPUState *env)
2785 2788 {
2786 2789 struct target_signal_frame *frame;
  2790 + abi_ulong frame_addr;
2787 2791 int err = 0;
2788 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 2796 goto badframe;
2796 2797  
2797 2798 /*
... ... @@ -2825,10 +2826,10 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
2825 2826 /* Link SRP so the guest returns through the trampoline. */
2826 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 2830 return;
2830 2831 badframe:
2831   - unlock_user_struct(frame, (abi_ulong)frame, 0);
  2832 + unlock_user_struct(frame, frame_addr, 1);
2832 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 2843 long do_sigreturn(CPUState *env)
2843 2844 {
2844 2845 struct target_signal_frame *frame;
  2846 + abi_ulong frame_addr;
2845 2847 target_sigset_t target_set;
2846 2848 sigset_t set;
2847 2849 int i;
2848 2850  
2849   - frame = (void *) env->regs[R_SP];
  2851 + frame_addr = env->regs[R_SP];
2850 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 2854 goto badframe;
2853 2855  
2854 2856 /* Restore blocked signals */
... ... @@ -2862,14 +2864,13 @@ long do_sigreturn(CPUState *env)
2862 2864 sigprocmask(SIG_SETMASK, &set, NULL);
2863 2865  
2864 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 2871 return env->regs[10];
2871 2872 badframe:
2872   - unlock_user_struct(frame, (abi_ulong)frame, 0);
  2873 + unlock_user_struct(frame, frame_addr, 0);
2873 2874 force_sig(TARGET_SIGSEGV);
2874 2875 }
2875 2876  
... ...