Author: aandrejevic Date: Tue May 27 21:10:45 2014 New Revision: 63482
URL: http://svn.reactos.org/svn/reactos?rev=63482&view=rev Log: [FAST486][NTVDM] Several fixes in fast486 and ntvdm: DosCopyEnvironmentBlock - prepend the program name tag (0x0001) to the program name. Fast486OpcodePushByteImm, Fast486OpcodePushImm - sign-extend instead of zero-extending. Fast486InterruptInternal - The parameter is supposed to be the type of the gate, not a boolean. GET_SEGMENT_RPL will not work on real-mode selectors, use a special field for the RPL. Loading a data segment with the NULL selector should never generate an exception. Mask out the highest-order byte of the physical address when loading a descriptor table in 16-bit mode. Fast486InterruptInternal - The interrupt gate type determines the size. CORE-8257 #resolve #comment Fixed in revision r63482.
Modified: trunk/reactos/include/reactos/libs/fast486/fast486.h trunk/reactos/lib/fast486/common.c trunk/reactos/lib/fast486/common.h trunk/reactos/lib/fast486/common.inl trunk/reactos/lib/fast486/opcodes.c trunk/reactos/lib/fast486/opgroups.c trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h
Modified: trunk/reactos/include/reactos/libs/fast486/fast486.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fast48... ============================================================================== --- trunk/reactos/include/reactos/libs/fast486/fast486.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/libs/fast486/fast486.h [iso-8859-1] Tue May 27 21:10:45 2014 @@ -251,6 +251,7 @@ ULONG DirConf : 1; ULONG Executable : 1; ULONG SystemType : 1; + ULONG Rpl : 2; ULONG Dpl : 2; ULONG Present : 1; ULONG Size : 1;
Modified: trunk/reactos/lib/fast486/common.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=63... ============================================================================== --- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Tue May 27 21:10:45 2014 @@ -65,7 +65,7 @@ return FALSE; }
- if ((!InstFetch && (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl)) + if ((!InstFetch && (CachedDescriptor->Rpl > CachedDescriptor->Dpl)) || (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl)) { Fast486Exception(State, FAST486_EXCEPTION_GP); @@ -132,7 +132,7 @@ return FALSE; }
- if ((GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl) + if ((CachedDescriptor->Rpl > CachedDescriptor->Dpl) || (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl)) { Fast486Exception(State, FAST486_EXCEPTION_GP); @@ -164,14 +164,26 @@ Fast486InterruptInternal(PFAST486_STATE State, USHORT SegmentSelector, ULONG Offset, - BOOLEAN InterruptGate) + ULONG GateType) { + BOOLEAN GateSize = (GateType == FAST486_IDT_INT_GATE_32) + || (GateType == FAST486_IDT_TRAP_GATE_32); + /* Check for protected mode */ if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) { FAST486_TSS Tss; USHORT OldSs = State->SegmentRegs[FAST486_REG_SS].Selector; ULONG OldEsp = State->GeneralRegs[FAST486_REG_ESP].Long; + + if (GateSize != (State->SegmentRegs[FAST486_REG_CS].Size)) + { + /* + * The gate size doesn't match the current operand size, so toggle + * the OPSIZE flag. + */ + State->PrefixFlags ^= FAST486_PREFIX_OPSIZE; + }
/* Check if the interrupt handler is more privileged */ if (Fast486GetCurrentPrivLevel(State) > GET_SEGMENT_RPL(SegmentSelector)) @@ -257,7 +269,7 @@ /* Push the instruction pointer */ if (!Fast486StackPush(State, State->InstPtr.Long)) return FALSE;
- if (InterruptGate) + if ((GateType == FAST486_IDT_INT_GATE) || (GateType == FAST486_IDT_INT_GATE_32)) { /* Disable interrupts after a jump to an interrupt gate handler */ State->Flags.If = FALSE; @@ -270,7 +282,7 @@ return FALSE; }
- if (State->SegmentRegs[FAST486_REG_CS].Size) + if (GateSize) { /* 32-bit code segment, use EIP */ State->InstPtr.Long = Offset;
Modified: trunk/reactos/lib/fast486/common.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.h?rev=63... ============================================================================== --- trunk/reactos/lib/fast486/common.h [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.h [iso-8859-1] Tue May 27 21:10:45 2014 @@ -159,7 +159,7 @@ PFAST486_STATE State, USHORT SegmentSelector, ULONG Offset, - BOOLEAN InterruptGate + ULONG GateType );
VOID
Modified: trunk/reactos/lib/fast486/common.inl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.inl?rev=... ============================================================================== --- trunk/reactos/lib/fast486/common.inl [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.inl [iso-8859-1] Tue May 27 21:10:45 2014 @@ -542,24 +542,32 @@ { /* Loading a data segment */
- if (!GdtEntry.SystemType) - { - /* This is a special descriptor */ - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); - return FALSE; - } - - if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl) - || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl)) - { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); - return FALSE; - } - - if (!GdtEntry.Present) - { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector); - return FALSE; + if (GET_SEGMENT_INDEX(Selector) != 0) + { + if (!GdtEntry.SystemType) + { + /* This is a special descriptor */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + return FALSE; + } + + if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl) + || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl)) + { + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + return FALSE; + } + + if (!GdtEntry.Present) + { + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector); + return FALSE; + } + } + else + { + /* This is a NULL selector */ + RtlZeroMemory(&GdtEntry, sizeof(GdtEntry)); } }
@@ -572,6 +580,7 @@ CachedDescriptor->DirConf = GdtEntry.DirConf; CachedDescriptor->Executable = GdtEntry.Executable; CachedDescriptor->SystemType = GdtEntry.SystemType; + CachedDescriptor->Rpl = GET_SEGMENT_RPL(Selector); CachedDescriptor->Dpl = GdtEntry.Dpl; CachedDescriptor->Present = GdtEntry.Present; CachedDescriptor->Size = GdtEntry.Size;
Modified: trunk/reactos/lib/fast486/opcodes.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opcodes.c?rev=6... ============================================================================== --- trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] Tue May 27 21:10:45 2014 @@ -3702,9 +3702,9 @@ } else { - USHORT Data; - - if (!Fast486FetchWord(State, &Data)) + SHORT Data; + + if (!Fast486FetchWord(State, (PUSHORT)&Data)) { /* Exception occurred */ return FALSE; @@ -3837,12 +3837,12 @@
FAST486_OPCODE_HANDLER(Fast486OpcodePushByteImm) { - UCHAR Data; + CHAR Data;
/* Make sure this is the right instruction */ ASSERT(Opcode == 0x6A);
- if (!Fast486FetchByte(State, &Data)) + if (!Fast486FetchByte(State, (PUCHAR)&Data)) { /* Exception occurred */ return FALSE;
Modified: trunk/reactos/lib/fast486/opgroups.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opgroups.c?rev=... ============================================================================== --- trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] Tue May 27 21:10:45 2014 @@ -2018,10 +2018,13 @@ { UCHAR TableReg[6]; FAST486_MOD_REG_RM ModRegRm; - BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + BOOLEAN OperandSize, AddressSize; FAST486_SEG_REGS Segment = FAST486_REG_DS;
+ OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + NO_LOCK_PREFIX(); + TOGGLE_OPSIZE(OperandSize); TOGGLE_ADSIZE(AddressSize);
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) @@ -2117,6 +2120,9 @@ State->Gdtr.Size = *((PUSHORT)TableReg); State->Gdtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
+ /* In 16-bit mode the highest byte is masked out */ + if (!OperandSize) State->Gdtr.Address &= 0x00FFFFFF; + return TRUE; }
@@ -2153,6 +2159,9 @@ State->Idtr.Size = *((PUSHORT)TableReg); State->Idtr.Address = *((PULONG)&TableReg[sizeof(USHORT)]);
+ /* In 16-bit mode the highest byte is masked out */ + if (!OperandSize) State->Idtr.Address &= 0x00FFFFFF; + return TRUE; }
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32k... ============================================================================== --- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Tue May 27 21:10:45 2014 @@ -441,6 +441,10 @@
/* Set the final zero */ *(DestBuffer++) = 0; + + /* Store the special program name tag */ + *(DestBuffer++) = LOWORD(DOS_PROGRAM_NAME_TAG); + *(DestBuffer++) = HIWORD(DOS_PROGRAM_NAME_TAG);
/* Copy the program name after the environment block */ strcpy(DestBuffer, ProgramName);
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32k... ============================================================================== --- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] Tue May 27 21:10:45 2014 @@ -47,6 +47,7 @@ #define DOS_DIR_LENGTH 64 #define NUM_DRIVES ('Z' - 'A' + 1) #define DOS_CHAR_ATTRIBUTE 0x07 +#define DOS_PROGRAM_NAME_TAG 0x0001
enum DOS_ALLOC_STRATEGY {