/[qemu]/qemu/target-i386/helper.c
ViewVC logotype

Diff of /qemu/target-i386/helper.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by bellard, Wed Nov 12 23:39:19 2003 UTC revision 1.5 by bellard, Thu Nov 13 01:42:19 2003 UTC
# Line 1037  void helper_ltr_T0(void) Line 1037  void helper_ltr_T0(void)
1037      env->tr.selector = selector;      env->tr.selector = selector;
1038  }  }
1039    
1040  /* only works if protected mode and not VM86. Calling load_seg with  /* only works if protected mode and not VM86. seg_reg must be != R_CS */
    seg_reg == R_CS is discouraged */  
 /* XXX: add ring level checks */  
1041  void load_seg(int seg_reg, int selector, unsigned int cur_eip)  void load_seg(int seg_reg, int selector, unsigned int cur_eip)
1042  {  {
1043      uint32_t e1, e2;      uint32_t e1, e2;
1044            int cpl, dpl, rpl;
1045        SegmentCache *dt;
1046        int index;
1047        uint8_t *ptr;
1048    
1049      if ((selector & 0xfffc) == 0) {      if ((selector & 0xfffc) == 0) {
1050          /* null selector case */          /* null selector case */
1051          if (seg_reg == R_SS) {          if (seg_reg == R_SS) {
# Line 1053  void load_seg(int seg_reg, int selector, Line 1055  void load_seg(int seg_reg, int selector,
1055              cpu_x86_load_seg_cache(env, seg_reg, selector, NULL, 0, 0);              cpu_x86_load_seg_cache(env, seg_reg, selector, NULL, 0, 0);
1056          }          }
1057      } else {      } else {
1058          if (load_segment(&e1, &e2, selector) != 0) {          
1059            if (selector & 0x4)
1060                dt = &env->ldt;
1061            else
1062                dt = &env->gdt;
1063            index = selector & ~7;
1064            if ((index + 7) > dt->limit) {
1065              EIP = cur_eip;              EIP = cur_eip;
1066              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1067          }          }
1068          if (!(e2 & DESC_S_MASK) ||          ptr = dt->base + index;
1069              (e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {          e1 = ldl_kernel(ptr);
1070            e2 = ldl_kernel(ptr + 4);
1071    
1072            if (!(e2 & DESC_S_MASK)) {
1073              EIP = cur_eip;              EIP = cur_eip;
1074              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1075          }          }
1076            rpl = selector & 3;
1077            dpl = (e2 >> DESC_DPL_SHIFT) & 3;
1078            cpl = env->hflags & HF_CPL_MASK;
1079          if (seg_reg == R_SS) {          if (seg_reg == R_SS) {
1080                /* must be writable segment */
1081              if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) {              if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) {
1082                  EIP = cur_eip;                  EIP = cur_eip;
1083                  raise_exception_err(EXCP0D_GPF, selector & 0xfffc);                  raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1084              }              }
1085                if (rpl != cpl || dpl != cpl) {
1086                    EIP = cur_eip;
1087                    raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1088                }
1089          } else {          } else {
1090                /* must be readable segment */
1091              if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {              if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {
1092                  EIP = cur_eip;                  EIP = cur_eip;
1093                  raise_exception_err(EXCP0D_GPF, selector & 0xfffc);                  raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1094              }              }
1095                
1096                if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
1097                    /* if not conforming code, test rights */
1098                    if (dpl < cpl || dpl < rpl) {
1099                        EIP = cur_eip;
1100                        raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1101                    }
1102                }
1103          }          }
1104    
1105          if (!(e2 & DESC_P_MASK)) {          if (!(e2 & DESC_P_MASK)) {
# Line 1082  void load_seg(int seg_reg, int selector, Line 1109  void load_seg(int seg_reg, int selector,
1109              else              else
1110                  raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);                  raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
1111          }          }
1112    
1113            /* set the access bit if not already set */
1114            if (!(e2 & DESC_A_MASK)) {
1115                e2 |= DESC_A_MASK;
1116                stl_kernel(ptr + 4, e2);
1117            }
1118    
1119          cpu_x86_load_seg_cache(env, seg_reg, selector,          cpu_x86_load_seg_cache(env, seg_reg, selector,
1120                         get_seg_base(e1, e2),                         get_seg_base(e1, e2),
1121                         get_seg_limit(e1, e2),                         get_seg_limit(e1, e2),
# Line 1696  void helper_lsl(void) Line 1730  void helper_lsl(void)
1730  {  {
1731      unsigned int selector, limit;      unsigned int selector, limit;
1732      uint32_t e1, e2;      uint32_t e1, e2;
1733        int rpl, dpl, cpl, type;
1734    
1735      CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;      CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
1736      selector = T0 & 0xffff;      selector = T0 & 0xffff;
1737      if (load_segment(&e1, &e2, selector) != 0)      if (load_segment(&e1, &e2, selector) != 0)
1738          return;          return;
1739      limit = (e1 & 0xffff) | (e2 & 0x000f0000);      rpl = selector & 3;
1740      if (e2 & (1 << 23))      dpl = (e2 >> DESC_DPL_SHIFT) & 3;
1741          limit = (limit << 12) | 0xfff;      cpl = env->hflags & HF_CPL_MASK;
1742        if (e2 & DESC_S_MASK) {
1743            if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) {
1744                /* conforming */
1745            } else {
1746                if (dpl < cpl || dpl < rpl)
1747                    return;
1748            }
1749        } else {
1750            type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
1751            switch(type) {
1752            case 1:
1753            case 2:
1754            case 3:
1755            case 9:
1756            case 11:
1757                break;
1758            default:
1759                return;
1760            }
1761            if (dpl < cpl || dpl < rpl)
1762                return;
1763        }
1764        limit = get_seg_limit(e1, e2);
1765      T1 = limit;      T1 = limit;
1766      CC_SRC |= CC_Z;      CC_SRC |= CC_Z;
1767  }  }
# Line 1712  void helper_lar(void) Line 1770  void helper_lar(void)
1770  {  {
1771      unsigned int selector;      unsigned int selector;
1772      uint32_t e1, e2;      uint32_t e1, e2;
1773        int rpl, dpl, cpl, type;
1774    
1775      CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;      CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
1776      selector = T0 & 0xffff;      selector = T0 & 0xffff;
1777        if ((selector & 0xfffc) == 0)
1778            return;
1779      if (load_segment(&e1, &e2, selector) != 0)      if (load_segment(&e1, &e2, selector) != 0)
1780          return;          return;
1781        rpl = selector & 3;
1782        dpl = (e2 >> DESC_DPL_SHIFT) & 3;
1783        cpl = env->hflags & HF_CPL_MASK;
1784        if (e2 & DESC_S_MASK) {
1785            if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) {
1786                /* conforming */
1787            } else {
1788                if (dpl < cpl || dpl < rpl)
1789                    return;
1790            }
1791        } else {
1792            type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
1793            switch(type) {
1794            case 1:
1795            case 2:
1796            case 3:
1797            case 4:
1798            case 5:
1799            case 9:
1800            case 11:
1801            case 12:
1802                break;
1803            default:
1804                return;
1805            }
1806            if (dpl < cpl || dpl < rpl)
1807                return;
1808        }
1809      T1 = e2 & 0x00f0ff00;      T1 = e2 & 0x00f0ff00;
1810      CC_SRC |= CC_Z;      CC_SRC |= CC_Z;
1811  }  }
1812    
1813    void helper_verr(void)
1814    {
1815        unsigned int selector;
1816        uint32_t e1, e2;
1817        int rpl, dpl, cpl;
1818    
1819        CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
1820        selector = T0 & 0xffff;
1821        if ((selector & 0xfffc) == 0)
1822            return;
1823        if (load_segment(&e1, &e2, selector) != 0)
1824            return;
1825        if (!(e2 & DESC_S_MASK))
1826            return;
1827        rpl = selector & 3;
1828        dpl = (e2 >> DESC_DPL_SHIFT) & 3;
1829        cpl = env->hflags & HF_CPL_MASK;
1830        if (e2 & DESC_CS_MASK) {
1831            if (!(e2 & DESC_R_MASK))
1832                return;
1833            if (!(e2 & DESC_C_MASK)) {
1834                if (dpl < cpl || dpl < rpl)
1835                    return;
1836            }
1837        } else {
1838            if (dpl < cpl || dpl < rpl)
1839                return;
1840        }
1841        /* ok */
1842    }
1843    
1844    void helper_verw(void)
1845    {
1846        unsigned int selector;
1847        uint32_t e1, e2;
1848        int rpl, dpl, cpl;
1849    
1850        CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
1851        selector = T0 & 0xffff;
1852        if ((selector & 0xfffc) == 0)
1853            return;
1854        if (load_segment(&e1, &e2, selector) != 0)
1855            return;
1856        if (!(e2 & DESC_S_MASK))
1857            return;
1858        rpl = selector & 3;
1859        dpl = (e2 >> DESC_DPL_SHIFT) & 3;
1860        cpl = env->hflags & HF_CPL_MASK;
1861        if (e2 & DESC_CS_MASK) {
1862            return;
1863        } else {
1864            if (dpl < cpl || dpl < rpl)
1865                return;
1866            if (!(e2 & DESC_W_MASK))
1867                return;
1868        }
1869        /* ok */
1870    }
1871    
1872  /* FPU helpers */  /* FPU helpers */
1873    
1874  void helper_fldt_ST0_A0(void)  void helper_fldt_ST0_A0(void)

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26