Revision 5bfb56b2 linux-user/signal.c
b/linux-user/signal.c | ||
---|---|---|
1443 | 1443 |
#define UREG_I0 0 |
1444 | 1444 |
#define UREG_I1 1 |
1445 | 1445 |
#define UREG_I2 2 |
1446 |
#define UREG_I3 3 |
|
1447 |
#define UREG_I4 4 |
|
1448 |
#define UREG_I5 5 |
|
1446 | 1449 |
#define UREG_I6 6 |
1447 | 1450 |
#define UREG_I7 7 |
1448 | 1451 |
#define UREG_L0 8 |
... | ... | |
1704 | 1707 |
return -ENOSYS; |
1705 | 1708 |
} |
1706 | 1709 |
|
1710 |
#ifdef TARGET_SPARC64 |
|
1711 |
#define MC_TSTATE 0 |
|
1712 |
#define MC_PC 1 |
|
1713 |
#define MC_NPC 2 |
|
1714 |
#define MC_Y 3 |
|
1715 |
#define MC_G1 4 |
|
1716 |
#define MC_G2 5 |
|
1717 |
#define MC_G3 6 |
|
1718 |
#define MC_G4 7 |
|
1719 |
#define MC_G5 8 |
|
1720 |
#define MC_G6 9 |
|
1721 |
#define MC_G7 10 |
|
1722 |
#define MC_O0 11 |
|
1723 |
#define MC_O1 12 |
|
1724 |
#define MC_O2 13 |
|
1725 |
#define MC_O3 14 |
|
1726 |
#define MC_O4 15 |
|
1727 |
#define MC_O5 16 |
|
1728 |
#define MC_O6 17 |
|
1729 |
#define MC_O7 18 |
|
1730 |
#define MC_NGREG 19 |
|
1731 |
|
|
1732 |
typedef target_ulong target_mc_greg_t; |
|
1733 |
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG]; |
|
1734 |
|
|
1735 |
struct target_mc_fq { |
|
1736 |
target_ulong *mcfq_addr; |
|
1737 |
uint32_t mcfq_insn; |
|
1738 |
}; |
|
1739 |
|
|
1740 |
struct target_mc_fpu { |
|
1741 |
union { |
|
1742 |
uint32_t sregs[32]; |
|
1743 |
uint64_t dregs[32]; |
|
1744 |
//uint128_t qregs[16]; |
|
1745 |
} mcfpu_fregs; |
|
1746 |
target_ulong mcfpu_fsr; |
|
1747 |
target_ulong mcfpu_fprs; |
|
1748 |
target_ulong mcfpu_gsr; |
|
1749 |
struct target_mc_fq *mcfpu_fq; |
|
1750 |
unsigned char mcfpu_qcnt; |
|
1751 |
unsigned char mcfpu_qentsz; |
|
1752 |
unsigned char mcfpu_enab; |
|
1753 |
}; |
|
1754 |
typedef struct target_mc_fpu target_mc_fpu_t; |
|
1755 |
|
|
1756 |
typedef struct { |
|
1757 |
target_mc_gregset_t mc_gregs; |
|
1758 |
target_mc_greg_t mc_fp; |
|
1759 |
target_mc_greg_t mc_i7; |
|
1760 |
target_mc_fpu_t mc_fpregs; |
|
1761 |
} target_mcontext_t; |
|
1762 |
|
|
1763 |
struct target_ucontext { |
|
1764 |
struct target_ucontext *uc_link; |
|
1765 |
target_ulong uc_flags; |
|
1766 |
target_sigset_t uc_sigmask; |
|
1767 |
target_mcontext_t uc_mcontext; |
|
1768 |
}; |
|
1769 |
|
|
1770 |
/* A V9 register window */ |
|
1771 |
struct target_reg_window { |
|
1772 |
target_ulong locals[8]; |
|
1773 |
target_ulong ins[8]; |
|
1774 |
}; |
|
1775 |
|
|
1776 |
#define TARGET_STACK_BIAS 2047 |
|
1777 |
|
|
1778 |
/* {set, get}context() needed for 64-bit SparcLinux userland. */ |
|
1779 |
void sparc64_set_context(CPUSPARCState *env) |
|
1780 |
{ |
|
1781 |
struct target_ucontext *ucp = (struct target_ucontext *) |
|
1782 |
env->regwptr[UREG_I0]; |
|
1783 |
target_mc_gregset_t *grp; |
|
1784 |
target_ulong pc, npc, tstate; |
|
1785 |
target_ulong fp, i7; |
|
1786 |
unsigned char fenab; |
|
1787 |
int err; |
|
1788 |
unsigned int i; |
|
1789 |
target_ulong *src, *dst; |
|
1790 |
|
|
1791 |
grp = &ucp->uc_mcontext.mc_gregs; |
|
1792 |
err = get_user(pc, &((*grp)[MC_PC])); |
|
1793 |
err |= get_user(npc, &((*grp)[MC_NPC])); |
|
1794 |
if (err || ((pc | npc) & 3)) |
|
1795 |
goto do_sigsegv; |
|
1796 |
if (env->regwptr[UREG_I1]) { |
|
1797 |
target_sigset_t target_set; |
|
1798 |
sigset_t set; |
|
1799 |
|
|
1800 |
if (TARGET_NSIG_WORDS == 1) { |
|
1801 |
if (get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0])) |
|
1802 |
goto do_sigsegv; |
|
1803 |
} else { |
|
1804 |
src = &ucp->uc_sigmask; |
|
1805 |
dst = &target_set; |
|
1806 |
for (i = 0; i < sizeof(target_sigset_t) / sizeof(target_ulong); |
|
1807 |
i++, dst++, src++) |
|
1808 |
err |= get_user(dst, src); |
|
1809 |
if (err) |
|
1810 |
goto do_sigsegv; |
|
1811 |
} |
|
1812 |
target_to_host_sigset_internal(&set, &target_set); |
|
1813 |
sigprocmask(SIG_SETMASK, &set, NULL); |
|
1814 |
} |
|
1815 |
env->pc = pc; |
|
1816 |
env->npc = npc; |
|
1817 |
err |= get_user(env->y, &((*grp)[MC_Y])); |
|
1818 |
err |= get_user(tstate, &((*grp)[MC_TSTATE])); |
|
1819 |
env->asi = (tstate >> 24) & 0xff; |
|
1820 |
PUT_CCR(env, tstate >> 32); |
|
1821 |
PUT_CWP64(env, tstate & 0x1f); |
|
1822 |
err |= get_user(env->gregs[1], (&(*grp)[MC_G1])); |
|
1823 |
err |= get_user(env->gregs[2], (&(*grp)[MC_G2])); |
|
1824 |
err |= get_user(env->gregs[3], (&(*grp)[MC_G3])); |
|
1825 |
err |= get_user(env->gregs[4], (&(*grp)[MC_G4])); |
|
1826 |
err |= get_user(env->gregs[5], (&(*grp)[MC_G5])); |
|
1827 |
err |= get_user(env->gregs[6], (&(*grp)[MC_G6])); |
|
1828 |
err |= get_user(env->gregs[7], (&(*grp)[MC_G7])); |
|
1829 |
err |= get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0])); |
|
1830 |
err |= get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1])); |
|
1831 |
err |= get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2])); |
|
1832 |
err |= get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3])); |
|
1833 |
err |= get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4])); |
|
1834 |
err |= get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5])); |
|
1835 |
err |= get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6])); |
|
1836 |
err |= get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7])); |
|
1837 |
|
|
1838 |
err |= get_user(fp, &(ucp->uc_mcontext.mc_fp)); |
|
1839 |
err |= get_user(i7, &(ucp->uc_mcontext.mc_i7)); |
|
1840 |
err |= put_user(fp, |
|
1841 |
(&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6]))); |
|
1842 |
err |= put_user(i7, |
|
1843 |
(&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7]))); |
|
1844 |
|
|
1845 |
err |= get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab)); |
|
1846 |
err |= get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs)); |
|
1847 |
src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs); |
|
1848 |
dst = &env->fpr; |
|
1849 |
for (i = 0; i < 64; i++, dst++, src++) |
|
1850 |
err |= get_user(dst, src); |
|
1851 |
err |= get_user(env->fsr, |
|
1852 |
&(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr)); |
|
1853 |
err |= get_user(env->gsr, |
|
1854 |
&(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr)); |
|
1855 |
if (err) |
|
1856 |
goto do_sigsegv; |
|
1857 |
|
|
1858 |
return; |
|
1859 |
do_sigsegv: |
|
1860 |
force_sig(SIGSEGV); |
|
1861 |
} |
|
1862 |
|
|
1863 |
void sparc64_get_context(CPUSPARCState *env) |
|
1864 |
{ |
|
1865 |
struct target_ucontext *ucp = (struct target_ucontext *) |
|
1866 |
env->regwptr[UREG_I0]; |
|
1867 |
target_mc_gregset_t *grp; |
|
1868 |
target_mcontext_t *mcp; |
|
1869 |
target_ulong fp, i7; |
|
1870 |
int err; |
|
1871 |
unsigned int i; |
|
1872 |
target_ulong *src, *dst; |
|
1873 |
target_sigset_t target_set; |
|
1874 |
sigset_t set; |
|
1875 |
|
|
1876 |
mcp = &ucp->uc_mcontext; |
|
1877 |
grp = &mcp->mc_gregs; |
|
1878 |
|
|
1879 |
/* Skip over the trap instruction, first. */ |
|
1880 |
env->pc = env->npc; |
|
1881 |
env->npc += 4; |
|
1882 |
|
|
1883 |
err = 0; |
|
1884 |
|
|
1885 |
sigprocmask(0, NULL, &set); |
|
1886 |
host_to_target_sigset_internal(&target_set, &set); |
|
1887 |
if (TARGET_NSIG_WORDS == 1) |
|
1888 |
err |= put_user(target_set.sig[0], |
|
1889 |
(target_ulong *)&ucp->uc_sigmask); |
|
1890 |
else { |
|
1891 |
src = &target_set; |
|
1892 |
dst = &ucp->uc_sigmask; |
|
1893 |
for (i = 0; i < sizeof(target_sigset_t) / sizeof(target_ulong); |
|
1894 |
i++, dst++, src++) |
|
1895 |
err |= put_user(src, dst); |
|
1896 |
if (err) |
|
1897 |
goto do_sigsegv; |
|
1898 |
} |
|
1899 |
|
|
1900 |
err |= put_user(env->tstate, &((*grp)[MC_TSTATE])); |
|
1901 |
err |= put_user(env->pc, &((*grp)[MC_PC])); |
|
1902 |
err |= put_user(env->npc, &((*grp)[MC_NPC])); |
|
1903 |
err |= put_user(env->y, &((*grp)[MC_Y])); |
|
1904 |
err |= put_user(env->gregs[1], &((*grp)[MC_G1])); |
|
1905 |
err |= put_user(env->gregs[2], &((*grp)[MC_G2])); |
|
1906 |
err |= put_user(env->gregs[3], &((*grp)[MC_G3])); |
|
1907 |
err |= put_user(env->gregs[4], &((*grp)[MC_G4])); |
|
1908 |
err |= put_user(env->gregs[5], &((*grp)[MC_G5])); |
|
1909 |
err |= put_user(env->gregs[6], &((*grp)[MC_G6])); |
|
1910 |
err |= put_user(env->gregs[7], &((*grp)[MC_G7])); |
|
1911 |
err |= put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0])); |
|
1912 |
err |= put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1])); |
|
1913 |
err |= put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2])); |
|
1914 |
err |= put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3])); |
|
1915 |
err |= put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4])); |
|
1916 |
err |= put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5])); |
|
1917 |
err |= put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6])); |
|
1918 |
err |= put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7])); |
|
1919 |
|
|
1920 |
err |= get_user(fp, |
|
1921 |
(&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6]))); |
|
1922 |
err |= get_user(i7, |
|
1923 |
(&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7]))); |
|
1924 |
err |= put_user(fp, &(mcp->mc_fp)); |
|
1925 |
err |= put_user(i7, &(mcp->mc_i7)); |
|
1926 |
|
|
1927 |
src = &env->fpr; |
|
1928 |
dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs); |
|
1929 |
for (i = 0; i < 64; i++, dst++, src++) |
|
1930 |
err |= put_user(src, dst); |
|
1931 |
err |= put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr)); |
|
1932 |
err |= put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr)); |
|
1933 |
err |= put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs)); |
|
1934 |
|
|
1935 |
if (err) |
|
1936 |
goto do_sigsegv; |
|
1937 |
|
|
1938 |
return; |
|
1939 |
do_sigsegv: |
|
1940 |
force_sig(SIGSEGV); |
|
1941 |
} |
|
1942 |
#endif |
|
1707 | 1943 |
#elif defined(TARGET_MIPS64) |
1708 | 1944 |
|
1709 | 1945 |
# warning signal handling not implemented |
Also available in: Unified diff