Commit 459a40172e7ee1be269771c355dbb3ef3c3903db

Authored by bellard
1 parent eeeac3f3

removed warnings - improved sparc32/64 signal frame setup - disabled x86 frame setup for x86_64


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3608 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 92 additions and 59 deletions
linux-user/signal.c
... ... @@ -143,7 +143,7 @@ static void host_to_target_sigset_internal(target_sigset_t *d,
143 143 d->sig[0] = target_sigmask;
144 144 d->sig[1] = sigmask >> 32;
145 145 #else
146   -#warning host_to_target_sigset
  146 + /* XXX: do it */
147 147 #endif
148 148 }
149 149  
... ... @@ -177,7 +177,7 @@ void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s)
177 177 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
178 178 ((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32);
179 179 #else
180   -#warning target_to_host_sigset
  180 + /* XXX: do it */
181 181 #endif /* TARGET_ABI_BITS */
182 182 }
183 183  
... ... @@ -233,7 +233,7 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
233 233 tinfo->_sifields._rt._uid = info->si_uid;
234 234 /* XXX: potential problem if 64 bit */
235 235 tinfo->_sifields._rt._sigval.sival_ptr =
236   - (abi_ulong)info->si_value.sival_ptr;
  236 + (abi_ulong)(unsigned long)info->si_value.sival_ptr;
237 237 }
238 238 }
239 239  
... ... @@ -276,7 +276,7 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
276 276 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
277 277 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
278 278 info->si_value.sival_ptr =
279   - (void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
  279 + (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
280 280 }
281 281  
282 282 void signal_init(void)
... ... @@ -562,7 +562,7 @@ static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
562 562 return 0;
563 563 }
564 564  
565   -#ifdef TARGET_I386
  565 +#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
566 566  
567 567 /* from the Linux kernel */
568 568  
... ... @@ -773,11 +773,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
773 773 /* This is popl %eax ; movl $,%eax ; int $0x80 */
774 774 val16 = 0xb858;
775 775 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
776   -#if defined(TARGET_X86_64)
777   -#warning "Fix this !"
778   -#else
779 776 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
780   -#endif
781 777 val16 = 0x80cd;
782 778 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
783 779 }
... ... @@ -1486,9 +1482,10 @@ struct target_rt_signal_frame {
1486 1482 #define UREG_FP UREG_I6
1487 1483 #define UREG_SP UREG_O6
1488 1484  
1489   -static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, unsigned long framesize)
  1485 +static inline abi_ulong get_sigframe(struct emulated_sigaction *sa,
  1486 + CPUState *env, unsigned long framesize)
1490 1487 {
1491   - unsigned long sp;
  1488 + abi_ulong sp;
1492 1489  
1493 1490 sp = env->regwptr[UREG_FP];
1494 1491  
... ... @@ -1498,7 +1495,7 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u
1498 1495 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1499 1496 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1500 1497 }
1501   - return g2h(sp - framesize);
  1498 + return sp - framesize;
1502 1499 }
1503 1500  
1504 1501 static int
... ... @@ -1543,6 +1540,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1543 1540 static void setup_frame(int sig, struct emulated_sigaction *ka,
1544 1541 target_sigset_t *set, CPUState *env)
1545 1542 {
  1543 + abi_ulong sf_addr;
1546 1544 struct target_signal_frame *sf;
1547 1545 int sigframe_size, err, i;
1548 1546  
... ... @@ -1550,10 +1548,13 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1550 1548 //synchronize_user_stack();
1551 1549  
1552 1550 sigframe_size = NF_ALIGNEDSZ;
  1551 + sf_addr = get_sigframe(ka, env, sigframe_size);
1553 1552  
1554   - sf = (struct target_signal_frame *)
1555   - get_sigframe(ka, env, sigframe_size);
1556   -
  1553 + sf = lock_user(VERIFY_WRITE, sf_addr,
  1554 + sizeof(struct target_signal_frame), 0);
  1555 + if (!sf)
  1556 + goto sigsegv;
  1557 +
1557 1558 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1558 1559 #if 0
1559 1560 if (invalid_frame_pointer(sf, sigframe_size))
... ... @@ -1581,20 +1582,24 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1581 1582 goto sigsegv;
1582 1583  
1583 1584 /* 3. signal handler back-trampoline and parameters */
1584   - env->regwptr[UREG_FP] = h2g(sf);
  1585 + env->regwptr[UREG_FP] = sf_addr;
1585 1586 env->regwptr[UREG_I0] = sig;
1586   - env->regwptr[UREG_I1] = h2g(&sf->info);
1587   - env->regwptr[UREG_I2] = h2g(&sf->info);
  1587 + env->regwptr[UREG_I1] = sf_addr +
  1588 + offsetof(struct target_signal_frame, info);
  1589 + env->regwptr[UREG_I2] = sf_addr +
  1590 + offsetof(struct target_signal_frame, info);
1588 1591  
1589 1592 /* 4. signal handler */
1590   - env->pc = (unsigned long) ka->sa._sa_handler;
  1593 + env->pc = ka->sa._sa_handler;
1591 1594 env->npc = (env->pc + 4);
1592 1595 /* 5. return to kernel instructions */
1593 1596 if (ka->sa.sa_restorer)
1594   - env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer;
  1597 + env->regwptr[UREG_I7] = ka->sa.sa_restorer;
1595 1598 else {
1596 1599 uint32_t val32;
1597   - env->regwptr[UREG_I7] = h2g(&(sf->insns[0]) - 2);
  1600 +
  1601 + env->regwptr[UREG_I7] = sf_addr +
  1602 + offsetof(struct target_signal_frame, insns) - 2 * 4;
1598 1603  
1599 1604 /* mov __NR_sigreturn, %g1 */
1600 1605 val32 = 0x821020d8;
... ... @@ -1610,12 +1615,15 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1610 1615 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1611 1616 // tb_flush(env);
1612 1617 }
  1618 + unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1613 1619 return;
1614   -
1615   - //sigill_and_return:
  1620 +#if 0
  1621 +sigill_and_return:
1616 1622 force_sig(TARGET_SIGILL);
  1623 +#endif
1617 1624 sigsegv:
1618 1625 //fprintf(stderr, "force_sig\n");
  1626 + unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1619 1627 force_sig(TARGET_SIGSEGV);
1620 1628 }
1621 1629 static inline int
... ... @@ -1744,7 +1752,7 @@ long do_rt_sigreturn(CPUState *env)
1744 1752 return -ENOSYS;
1745 1753 }
1746 1754  
1747   -#ifdef TARGET_SPARC64
  1755 +#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1748 1756 #define MC_TSTATE 0
1749 1757 #define MC_PC 1
1750 1758 #define MC_NPC 2
... ... @@ -1815,16 +1823,18 @@ struct target_reg_window {
1815 1823 /* {set, get}context() needed for 64-bit SparcLinux userland. */
1816 1824 void sparc64_set_context(CPUSPARCState *env)
1817 1825 {
1818   - struct target_ucontext *ucp = (struct target_ucontext *)
1819   - env->regwptr[UREG_I0];
  1826 + abi_ulong ucp_addr;
  1827 + struct target_ucontext *ucp;
1820 1828 target_mc_gregset_t *grp;
1821 1829 abi_ulong pc, npc, tstate;
1822   - abi_ulong fp, i7;
  1830 + abi_ulong fp, i7, w_addr;
1823 1831 unsigned char fenab;
1824 1832 int err;
1825 1833 unsigned int i;
1826   - abi_ulong *src, *dst;
1827 1834  
  1835 + ucp_addr = env->regwptr[UREG_I0];
  1836 + if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
  1837 + goto do_sigsegv;
1828 1838 grp = &ucp->uc_mcontext.mc_gregs;
1829 1839 err = __get_user(pc, &((*grp)[MC_PC]));
1830 1840 err |= __get_user(npc, &((*grp)[MC_NPC]));
... ... @@ -1838,11 +1848,12 @@ void sparc64_set_context(CPUSPARCState *env)
1838 1848 if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
1839 1849 goto do_sigsegv;
1840 1850 } else {
1841   - src = &ucp->uc_sigmask;
1842   - dst = &target_set;
  1851 + abi_ulong *src, *dst;
  1852 + src = ucp->uc_sigmask.sig;
  1853 + dst = target_set.sig;
1843 1854 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
1844 1855 i++, dst++, src++)
1845   - err |= __get_user(dst, src);
  1856 + err |= __get_user(*dst, src);
1846 1857 if (err)
1847 1858 goto do_sigsegv;
1848 1859 }
... ... @@ -1874,42 +1885,53 @@ void sparc64_set_context(CPUSPARCState *env)
1874 1885  
1875 1886 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
1876 1887 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
1877   - err |= __put_user(fp,
1878   - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
1879   - err |= __put_user(i7,
1880   - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
1881 1888  
  1889 + w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
  1890 + if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
  1891 + abi_ulong) != 0)
  1892 + goto do_sigsegv;
  1893 + if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
  1894 + abi_ulong) != 0)
  1895 + goto do_sigsegv;
1882 1896 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
1883 1897 err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
1884   - src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
1885   - dst = &env->fpr;
1886   - for (i = 0; i < 64; i++, dst++, src++)
1887   - err |= __get_user(dst, src);
  1898 + {
  1899 + uint32_t *src, *dst;
  1900 + src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
  1901 + dst = env->fpr;
  1902 + /* XXX: check that the CPU storage is the same as user context */
  1903 + for (i = 0; i < 64; i++, dst++, src++)
  1904 + err |= __get_user(*dst, src);
  1905 + }
1888 1906 err |= __get_user(env->fsr,
1889 1907 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
1890 1908 err |= __get_user(env->gsr,
1891 1909 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
1892 1910 if (err)
1893 1911 goto do_sigsegv;
1894   -
  1912 + unlock_user_struct(ucp, ucp_addr, 0);
1895 1913 return;
1896 1914 do_sigsegv:
  1915 + unlock_user_struct(ucp, ucp_addr, 0);
1897 1916 force_sig(SIGSEGV);
1898 1917 }
1899 1918  
1900 1919 void sparc64_get_context(CPUSPARCState *env)
1901 1920 {
1902   - struct target_ucontext *ucp = (struct target_ucontext *)
1903   - env->regwptr[UREG_I0];
  1921 + abi_ulong ucp_addr;
  1922 + struct target_ucontext *ucp;
1904 1923 target_mc_gregset_t *grp;
1905 1924 target_mcontext_t *mcp;
1906   - abi_ulong fp, i7;
  1925 + abi_ulong fp, i7, w_addr;
1907 1926 int err;
1908 1927 unsigned int i;
1909   - abi_ulong *src, *dst;
1910 1928 target_sigset_t target_set;
1911 1929 sigset_t set;
1912 1930  
  1931 + ucp_addr = env->regwptr[UREG_I0];
  1932 + if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
  1933 + goto do_sigsegv;
  1934 +
1913 1935 mcp = &ucp->uc_mcontext;
1914 1936 grp = &mcp->mc_gregs;
1915 1937  
... ... @@ -1921,20 +1943,22 @@ void sparc64_get_context(CPUSPARCState *env)
1921 1943  
1922 1944 sigprocmask(0, NULL, &set);
1923 1945 host_to_target_sigset_internal(&target_set, &set);
1924   - if (TARGET_NSIG_WORDS == 1)
  1946 + if (TARGET_NSIG_WORDS == 1) {
1925 1947 err |= __put_user(target_set.sig[0],
1926 1948 (abi_ulong *)&ucp->uc_sigmask);
1927   - else {
1928   - src = &target_set;
1929   - dst = &ucp->uc_sigmask;
  1949 + } else {
  1950 + abi_ulong *src, *dst;
  1951 + src = target_set.sig;
  1952 + dst = ucp->uc_sigmask.sig;
1930 1953 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
1931 1954 i++, dst++, src++)
1932   - err |= __put_user(src, dst);
  1955 + err |= __put_user(*src, dst);
1933 1956 if (err)
1934 1957 goto do_sigsegv;
1935 1958 }
1936 1959  
1937   - err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
  1960 + /* XXX: tstate must be saved properly */
  1961 + // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
1938 1962 err |= __put_user(env->pc, &((*grp)[MC_PC]));
1939 1963 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
1940 1964 err |= __put_user(env->y, &((*grp)[MC_Y]));
... ... @@ -1954,26 +1978,35 @@ void sparc64_get_context(CPUSPARCState *env)
1954 1978 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
1955 1979 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
1956 1980  
1957   - err |= __get_user(fp,
1958   - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
1959   - err |= __get_user(i7,
1960   - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
  1981 + w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
  1982 + fp = i7 = 0;
  1983 + if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
  1984 + abi_ulong) != 0)
  1985 + goto do_sigsegv;
  1986 + if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
  1987 + abi_ulong) != 0)
  1988 + goto do_sigsegv;
1961 1989 err |= __put_user(fp, &(mcp->mc_fp));
1962 1990 err |= __put_user(i7, &(mcp->mc_i7));
1963 1991  
1964   - src = &env->fpr;
1965   - dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);
1966   - for (i = 0; i < 64; i++, dst++, src++)
1967   - err |= __put_user(src, dst);
  1992 + {
  1993 + uint32_t *src, *dst;
  1994 + src = env->fpr;
  1995 + dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
  1996 + /* XXX: check that the CPU storage is the same as user context */
  1997 + for (i = 0; i < 64; i++, dst++, src++)
  1998 + err |= __put_user(*src, dst);
  1999 + }
1968 2000 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
1969 2001 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
1970 2002 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
1971 2003  
1972 2004 if (err)
1973 2005 goto do_sigsegv;
1974   -
  2006 + unlock_user_struct(ucp, ucp_addr, 1);
1975 2007 return;
1976 2008 do_sigsegv:
  2009 + unlock_user_struct(ucp, ucp_addr, 1);
1977 2010 force_sig(SIGSEGV);
1978 2011 }
1979 2012 #endif
... ...