summaryrefslogtreecommitdiffstats
path: root/private/ntos/dll/i386/emerror.asm
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/dll/i386/emerror.asm
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/dll/i386/emerror.asm')
-rw-r--r--private/ntos/dll/i386/emerror.asm469
1 files changed, 469 insertions, 0 deletions
diff --git a/private/ntos/dll/i386/emerror.asm b/private/ntos/dll/i386/emerror.asm
new file mode 100644
index 000000000..3fc135a06
--- /dev/null
+++ b/private/ntos/dll/i386/emerror.asm
@@ -0,0 +1,469 @@
+ page ,132
+ subttl emerror.asm - Emulator error handler
+;***
+;emerror.asm - Emulator error handler
+;
+; Microsoft Confidential
+;
+; Copyright (c) Microsoft Corporation 1987, 1991
+;
+; All Rights Reserved
+;
+;Purpose:
+; Emulator error handler
+;
+;Revision History: (also see emulator.hst)
+;
+; 10/30/89 WAJ Added this header.
+; 11/15/89 WAJ Major changes for Dos32RaiseExcpetion().
+; 12/01/89 WAJ Now set cbExceptionInfo correctly.
+; 02/08/90 WAJ Fixed GP fault in 32 bit exception handler.
+; 09/03/91 JWM Modified entry/exit sequence for DOSX32.
+; 02/15/92 JWM Adapted for NT.
+;
+;*******************************************************************************
+
+ifdef _DOS32EXT
+include except32.inc
+endif
+
+;*** error_return - return to user code (regardless of error)
+;
+; This macro returns to user code. It goes to some lengths
+; to restore the flags on the instruction immediately before
+; the return so that any pending trace trap will be
+; acknowledged immediately after the retfd (and before the
+; next user instruction) instead of after the instruction
+; following the return as would be the case if we returned
+; using iretd.
+;
+; ENTRY ((SS:ESP)) = user's EAX
+; ((SS:ESP)+4) = return EIP
+; ((SS:ESP)+8) = return CS
+; ((SS:ESP)+12) = user's EFLAGS
+; EXIT return to user program, above arguments
+; popped off stack, user's EAX and EFLAGS
+; restored.
+
+error_return macro noerror
+ifdef _DOS32EXT
+ sti ; JWM, 9/3/91
+ push dword ptr [esp+8] ; JWM, 9/6/91
+ popfd ; JWM, 9/6/91
+endif ; DOS32EXT
+
+ifdef NT386
+if DBG
+ push dword ptr [esp+8] ; On checked build, allow
+ popfd ; single step to work
+endif
+endif
+ iretd
+ endm
+
+
+TESTif macro nam
+ mov bl,err&nam ; default error number
+ if (nam ge 100h)
+ test ah,nam/256
+ else ;not (nam ge 100h)
+ test al,nam
+ endif ;(nam ge 100h)
+ JSNZ signalerror
+ endm
+
+EM_ENTRY eCommonExceptions
+CommonExceptions:
+ mov ebx,[esp].[OldLongStatus]
+ and ebx,LongSavedFlags ;preserve condition codes, error flags
+ or EMSEG:[LongStatusWord],ebx ;merge saved status word, condition codes
+ pop eax
+ pop ecx
+ pop edx
+ pop ebx
+ add esp,4 ; toss esp value
+ pop ebp
+ pop esi
+ pop edi
+ add esp,8 ;toss old PrevCodeOff and StatusWord
+ pop ds
+ call Emexcept
+ error_return noerror
+
+ifdef _DOS32EXT
+
+EmExcept PROC C, OldEIP:DWORD, OldCS:DWORD, OldFlags:DWORD
+
+LOCAL SSAR:DWORD
+LOCAL ec:_DX32_CONTEXT
+
+ ;*
+ ;* Set up SS access rights.
+ ;*
+
+ push ds
+ mov [ec.R_Eax], eax
+ GetEmData ds,ax
+
+ mov eax, ss
+ lar eax, eax
+ mov [SSAR], eax
+
+ ;*
+ ;* Fill in ExceptionContext structure.
+ ;*
+
+
+ mov [ec.NPXContextFlags], NPX_CONTEXT_FULL
+ mov [ec.R_Edi], edi
+ mov [ec.R_Esi], esi
+
+ mov eax, [ebp]
+ mov [ec.R_Ebp], eax
+
+ lea eax, [OldFlags+4]
+ mov [ec.R_Esp], eax
+
+ mov [ec.R_Ebx], ebx
+ mov [ec.R_Edx], edx
+ mov [ec.R_Ecx], ecx
+
+ mov eax, EMSEG:[PrevCodeOff]
+
+ mov [ec.R_Eip], eax
+ mov eax, [OldFlags]
+ mov [ec.EFlags], eax
+
+ mov eax, [OldCS]
+ movzx eax,ax
+ mov [ec.SegCs], eax
+ mov ax,ss
+ movzx eax,ax
+ mov [ec.SegSs], eax
+
+ pop eax
+ movzx eax,ax
+ mov [ec.SegDs], eax ; ds was pushed on entry.
+
+ mov ax,es
+ movzx eax,ax
+ mov [ec.SegEs], eax
+
+ mov ax,fs
+ movzx eax,ax
+ mov [ec.SegFs], eax
+
+ mov ax,gs
+ movzx eax,ax
+ mov [ec.SegGs], eax
+
+ lea esi, [ec]
+ add esi, 4
+
+ push ebp
+ call SaveState
+ pop ebp
+
+ lea eax, [ec]
+ push ds
+ push es
+
+ mov bx, seg FLAT:CURstk
+ mov ds, ebx
+ mov es, ebx
+ push eax
+
+ call DOS32RAISEEXCEPTION
+
+ add esp, 4
+
+ pop es
+ pop ds
+
+RaiseExceptRet:
+ or eax, eax
+ JZ ExceptNotHandled
+
+ ;*
+ ;* Copy new flags, cs, eip to new stack.
+ ;*
+
+ mov ds, [ec.SegSs]
+ mov esi, [ec.R_Esp] ; ds:esi == new ss:esp
+
+ mov eax, [ec.Eflags] ; set up iretd frame
+ mov [esi-4], eax
+
+ mov eax, [ec.SegCs]
+ mov [esi-8], eax
+
+ mov eax, [ec.R_Eip]
+ mov [esi-12], eax
+
+ ;*
+ ;* Put new stack pointer on stack.
+ ;*
+
+ push ds
+ sub esi, 12
+ push esi
+
+ ;*
+ ;* Reset other registers.
+ ;*
+
+ mov edi, [ec.R_Edi]
+ mov esi, [ec.R_Esi]
+ mov ebx, [ec.R_Ebx]
+ mov edx, [ec.R_Edx]
+ mov ecx, [ec.R_Ecx]
+ mov eax, [ec.R_Eax]
+ mov ds, [ec.SegDs]
+ mov es, [ec.SegEs]
+ mov fs, [ec.SegFs]
+ mov gs, [ec.SegGs]
+
+ mov ebp, [ec.R_Ebp] ; must do this last.
+
+ lss esp, fword ptr [esp] ; reset ss:esp
+
+ sti ; JWM, 9/3/91
+ push [esp+8] ; JWM, 9/6/91
+ popfd ; JWM, 9/6/91
+
+ iretd ; reset flags, cs, eip
+
+ExceptNotHandled:
+EmExcept ENDP
+
+endif ; ifdef _DOS32EXT
+
+ifdef NT386
+
+ISIZE equ 4
+ISizeEC equ (ContextFrameLength + ISIZE - 1) and (not (ISIZE - 1))
+ISizeExceptStruct equ (ExceptionRecordLength + ISIZE - 1) and (not (ISIZE - 1))
+
+ec_off EQU 4+ISizeEc
+estruct_off EQU ec_off+ISizeExceptStruct
+
+SSAR EQU <[ebp][-4]>
+ec EQU <[ebp][-ec_off]>
+eStruct EQU <[ebp][-estruct_off]>
+
+OldEIP EQU <ebp+8>
+OldCS EQU <ebp+12>
+OldFlags EQU <ebp+16>
+
+
+EmExcept PROC NEAR
+
+ push ebp
+ mov ebp,esp
+ sub esp,estruct_off
+
+
+ ;*
+ ;* Set up SS access rights.
+ ;*
+
+ push ds
+ mov [ec.ctx_RegEax], eax
+ GetEmData ds,ax
+
+ mov eax, ss
+ lar eax, eax
+ mov [SSAR], eax
+
+ ;*
+ ;* Fill in ExceptionContext structure.
+ ;*
+
+
+ mov dword ptr [ec.ContextFlags], NPX_CONTEXT_FULL
+ mov dword ptr [ec.ctx_Cr0NpxState], CR0_EM
+ mov [ec.ctx_RegEdi], edi
+ mov [ec.ctx_RegEsi], esi
+
+ mov eax, [ebp]
+ mov [ec.ctx_RegEbp], eax
+
+ lea eax, [OldFlags+4]
+ mov [ec.ctx_RegEsp], eax
+
+ mov [ec.ctx_RegEbx], ebx
+ mov [ec.ctx_RegEdx], edx
+ mov [ec.ctx_RegEcx], ecx
+
+ mov eax, [OldEIP]
+
+ mov [ec.ctx_RegEip], eax
+ mov eax, [OldFlags]
+ mov [ec.ctx_EFlags], eax
+
+ mov eax, [OldCS]
+ movzx eax,ax
+ mov [ec.ctx_SegCs], eax
+ mov ax,ss
+ movzx eax,ax
+ mov [ec.ctx_SegSs], eax
+
+ pop eax
+ movzx eax,ax
+ mov [ec.ctx_SegDs], eax ; ds was pushed on entry.
+
+ mov ax,es
+ movzx eax,ax
+ mov [ec.ctx_SegEs], eax
+
+ mov ax,fs
+ movzx eax,ax
+ mov [ec.ctx_SegFs], eax
+
+ mov ax,gs
+ movzx eax,ax
+ mov [ec.ctx_SegGs], eax
+
+ lea esi, [ec]
+ add esi, ctx_env
+
+ or EMSEG:[StatusWord], 8000H ; set 'busy' bit
+ or EMSEG:[SWerr], Summary ; set Summary bit
+ or EMSEG:[CURerr], Summary
+
+ mov cl, EMSEG:[ErrMask]
+ push ecx
+ push ebp
+ call SaveState
+ pop ebp
+ pop ecx
+
+ call GetEMSEGStatusWord ; EAX = status word
+ test al, cl ; test status word against mask
+ jne short Err00
+
+ifdef TRACENPX
+ mov edx, 0C1020304h ; Raise bogus exception code, to trace with
+ jmp short Err50
+endif
+ mov al, Invalid
+
+;
+; According to the floating error priority, we test what is the cause of
+; the NPX error and raise an appropriate exception.
+;
+
+Err00:
+ test al, Invalid ; Invalid Op?
+ jz short Err10 ; No, go check next
+
+ mov edx, XCPT_FLOAT_INVALID_OPERATION
+ test al, StackFlag ; Stack fault?
+ jz short Err50 ; No, go raise invalid op
+ mov edx, XCPT_FLOAT_STACK_CHECK
+ jmp short Err50 ; Go raise stack fault
+
+Err10: mov edx, XCPT_FLOAT_DIVIDE_BY_ZERO
+ test al, ZeroDivide
+ jnz short Err50
+ mov edx, XCPT_FLOAT_DENORMAL_OPERAND
+ test al, Denormal
+ jnz short Err50
+ mov edx, XCPT_FLOAT_OVERFLOW
+ test al, Overflow
+ jnz short Err50
+ mov edx, XCPT_FLOAT_UNDERFLOW
+ test al, Underflow
+ jnz short Err50
+ mov edx, XCPT_FLOAT_INEXACT_RESULT
+
+Err50: mov [eStruct.ExceptionNum], edx
+
+ xor eax,eax
+ mov [eStruct.fHandlerFlags], eax
+ mov [eStruct.NestedExceptionReportRecord], eax
+ mov dword ptr [eStruct.CParameters], 1 ; GeorgioP convention
+ mov [eStruct.ErExceptionInformation], eax ; GeorgioP convention
+
+ mov eax, EMSEG:[PrevCodeOff]
+ mov [eStruct.ExceptionAddress], eax
+
+ lea edx, [eStruct]
+
+ lea eax, [ec]
+ push ds
+ push es
+
+
+;TRUE, this is a first-chance exception
+
+ stdCall _NtRaiseException,<edx, eax, 1>
+ stdCall _RtlRaiseStatus, <eax>
+
+ pop es
+ pop ds
+
+RaiseExceptRet:
+ or eax, eax
+ JZ ExceptNotHandled
+
+ ;*
+ ;* Copy new flags, cs, eip to new stack.
+ ;*
+
+ mov ds, [ec.ctx_SegSs]
+ mov esi, [ec.ctx_RegEsp] ; ds:esi == new ss:esp
+
+ mov eax, [ec.ctx_Eflags] ; set up iretd frame
+ mov [esi-4], eax
+
+ mov eax, [ec.ctx_SegCs]
+ mov [esi-8], eax
+
+ mov eax, [ec.ctx_RegEip]
+ mov [esi-12], eax
+
+ ;*
+ ;* Put new stack pointer on stack.
+ ;*
+
+ push ds
+ sub esi, 12
+ push esi
+
+ ;*
+ ;* Reset other registers.
+ ;*
+
+ mov edi, [ec.ctx_RegEdi]
+ mov esi, [ec.ctx_RegEsi]
+ mov ebx, [ec.ctx_RegEbx]
+ mov edx, [ec.ctx_RegEdx]
+ mov ecx, [ec.ctx_RegEcx]
+ mov eax, [ec.ctx_RegEax]
+ mov ds, [ec.ctx_SegDs]
+ mov es, [ec.ctx_SegEs]
+ mov fs, [ec.ctx_SegFs]
+ mov gs, [ec.ctx_SegGs]
+
+ mov ebp, [ec.ctx_RegEbp] ; must do this last.
+
+ lss esp, fword ptr [esp] ; reset ss:esp
+
+ sti ; JWM, 9/3/91
+ push [esp+8] ; JWM, 9/6/91
+ popfd ; JWM, 9/6/91
+
+ iretd ; reset flags, cs, eip
+
+ExceptNotHandled:
+EmExcept ENDP
+
+endif ; ifdef NT386
+
+ifdef DEBUG
+
+lab PageFault
+ mov al, byte ptr cs:[iax]
+ ret
+endif