if ( (b & _SEGMENT_G) )
limit <<= 12;
- switch ( b & (_SEGMENT_CODE | _SEGMENT_EC) )
+ if ( (b & (_SEGMENT_CODE | _SEGMENT_EC)) == _SEGMENT_EC )
{
- case 0: /* Data segment, grows-up */
/*
+ * DATA, GROWS-DOWN.
+ * Grows-down limit check.
+ * NB. limit == 0xFFFFF provides no access (if G=1).
+ * limit == 0x00000 provides 4GB-4kB access (if G=1).
+ */
+ if ( (base + limit) > base )
+ {
+ limit = -(base & PAGE_MASK);
+ goto truncate;
+ }
+ }
+ else
+ {
+ /*
+ * DATA, GROWS-UP.
+ * CODE (CONFORMING AND NON-CONFORMING).
* Grows-up limit check.
* NB. limit == 0xFFFFF provides 4GB access (if G=1).
* limit == 0x00000 provides 4kB access (if G=1).
d->a &= ~0x0ffff; d->a |= limit & 0x0ffff;
d->b &= ~0xf0000; d->b |= limit & 0xf0000;
}
- goto good;
- case _SEGMENT_EC: /* Data segment, grows-down */
- /*
- * Grows-down limit check.
- * NB. limit == 0xFFFFF provides no access (if G=1).
- * limit == 0x00000 provides 4GB-4kB access (if G=1).
- */
- if ( (base + limit) > base )
- {
- limit = -(base & PAGE_MASK);
- goto truncate;
- }
- goto good;
- case _SEGMENT_CODE: /* Code segment, non-conforming */
- goto good;
- case _SEGMENT_CODE|_SEGMENT_EC: /* Code segment, conforming */
- goto bad;
}
good:
if ( (b & _SEGMENT_DPL) != 3 )
goto bad;
- /* Most code and data segments are okay. No base/limit checking. */
+ /* All code and data segments are okay. No base/limit checking. */
if ( (b & _SEGMENT_S) )
- {
- /* Disallow conforming code segments. I'm not sure they're safe. */
- if ( (b & (_SEGMENT_CODE|_SEGMENT_EC)) == (_SEGMENT_CODE|_SEGMENT_EC) )
- goto bad;
goto good;
- }
/* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */
if ( (b & _SEGMENT_TYPE) == 0x000 )