delorie.com/djgpp/doc/dpmi/ch4.5.html | search |
Handlers for exceptions can only be installed with Int 31H Functions 0203H, 0212H, or 0213H. If the client does not install a handler for a particular exception, or installs a handler but chains to the host's default handler, the host reflects the exception as a real mode interrupt for exceptions 0,1,2,3,4,5, and 7. The default behavior of exceptions 6 and 8-1FH is to terminate the client (some hosts may decide that they have to terminate the VM because the fault came from real mode code or it is in a non-terminatable state).
Function 0203H was defined in DPMI version 0.9 and continues to be supported in DPMI version 1.0 for compatibility reasons. Exception handlers installed with Function 0203H are only called for exceptions that occur in protected mode. All exceptions are examined by the DPMI host. The host processes any exception that it is responsible for, such as page fault for virtual memory management. These transparent exceptions are never passed to the client exception handlers. All other exceptions become visible exceptions to a client and are passed to the client exception handler (if any) from the DPMI host. The client exception handlers must return with a FAR RETURN, with interrupts disabled on a locked stack, and with SS, (E)SP, CS, and (E)IP registers at the point of exception pushed on the stack. All other registers are unchanged from their contents at the point of exception. The stack frame for 16-bit handlers installed with Function 0203H has the following format:
15 0 +---------------+ | SS | |---------------| 0EH | SP | |---------------| 0CH | Flags | |---------------| 0AH | CS | |---------------| 08H | IP | |---------------| 06H | Error Code | |---------------| 04H | Return CS | |---------------| 02H | Return IP | |---------------| 00H <-- SS:SPThe stack frame for 32-bit handlers installed with Function 0203H has the following format:
31 15 0 +---------------+---------------| | Reserved | SS | +---------------+---------------| 1CH | ESP | |-------------------------------| 18H | EFLAGS | |---------------+---------------| 14H | Reserved | CS | |---------------+---------------| 10H | EIP | |-------------------------------| 0CH | Error Code | |---------------+---------------| 08H | | Return CS | |---------------+---------------| 04H | Return EIP | |-------------------------------| 00H <-- SS:ESPThe error code in the stack frame is only valid for the following exceptions:
08H | Double fault |
0AH | Invalid TSS |
0BH | Segment not present |
0CH | Stack fault |
0DH | General protection fault |
0EH | Page Fault |
The exception handler must preserve and restore all registers, and must either jump to the next handler in the chain or terminate with a RETF (far return) instruction. In the latter case, the original SS:(E)SP, CS:(E)IP and flags on the stack, including the interrupt flag, will be restored. The exception handler can arrange to transfer control to a more general error-handling routine within the application by modifying the CS:(E)IP that is stored in the stack frame above the Return CS:(E)IP.
DPMI version 1.0 supports an expanded stack frame for exception handlers, and the ability to install separate handlers for exceptions which occur in real mode and in protected mode with Functions 0212H and 0213H. The expanded frame is defined on the stack above the frame previously described for handlers installed with Function 0203H. This allows DPMI 0.9-compatible handlers and DPMI 1.0-compatible handlers to coexist in the same handler chain; old handlers will be oblivious to the additional information available beyond the old stack frame, while new handlers can ignore the old frame and use only the expanded frame higher up on the stack.
The format of the expanded stack frame for both 16-bit and 32-bit handlers installed with Functions 0212H and 0213H is as follows:
31 15 0 +---------------------------------------------------------------+ 58H | PTE | |---------------------------------------------------------------| 54H | CR2 | |---------------------------------------------------------------| 50H | Reserved | GS | |---------------------------------------------------------------| 4CH | Reserved | FS | |---------------------------------------------------------------| 48H | Reserved | DS | |---------------------------------------------------------------| 44H | Reserved | ES | |---------------------------------------------------------------| 40H | Reserved | SS | |---------------------------------------------------------------| 3CH | ESP | |---------------------------------------------------------------| 38H | EFLAGS | |-------------------------------+-------------------------------| 34H | Exception information bits | CS | |-------------------------------+-------------------------------| 30H | EIP | |-------------------------------+-------------------------------| 2CH | Error Code | |-------------------------------+-------------------------------| 28H | Reserved | Return CS (32-bit) or 0 | |-------------------------------+-------------------------------| 24H | Return EIP (32-bit) or CS:IP (16-bit) | |-------------------------------+-------------------------------| 20H+SS:(E)SPA 32-bit stack frame image is always presented, even for 16-bit handlers, and the offset from SS:(E)SP to the expanded stack frame is always 20H (32) regardless of the handler type. The DS, ES, FS, and GS registers are saved for both real and protected mode. The client can inspect the VM bit in EFLAGS to determine the mode at the point of exception. The CS field at SS:(E)SP+24H is zero if the handler is running in 16-bit protected mode.
The exception information bits at SS:(E)SP+32H have the following meanings:
Bit | Significance | |
---|---|---|
0 | 0 | exception occurred in the client | 1 | exception occurred in the host (most likely due to page fault or invalid selector passed to host in an Int 31H call) |
1 | 0 | exception can be retried | 1 | Exception cannot be retried, handler should perform whatever cleanup is possible |
2 | 0 | host exception should be retried (invalid selector or page causing fault corrected by exception handler, this is the default) | 1 | host exception is being redirected somewhere other than a retry address |
3 | reserved |
Bits 0 through 2 of the exception information bits are relevant on hosts which support the Exceptions Restartability capability (see Int 31H Function 0401H). Bits 0 and 1 of the exception information bits are supplied to the client by the host. The default state of bit 2 as set by the host is zero, and the client may st the bit to 1 before returning from the exception handler.
Bit 0-14 of the error code at SS:(E)SP+28H are the "virtual" DR6 on debug (Int 1) exceptions, and correspond to debug breakpoint 0-14. In other words, if bits 0 and 2 are set in the error code field on an Int 1 exception, then debug watchpoints 0 and 2 have fired. The handle returned by the Set Debug Watchpoint (Function 0B00H) corresponds to the bit number in the virtual DR6. Bit 15 of the virtual DR6 is set (1) if the Int 1 is due to the trap flag. Breakpoints may be virtualized, and there is no guarantee of correspondence with the actual hardware. The provision for up to 15 breakpoints is made for future CPUs or external debugging hardware (80386 and 80486 CPUs support only four hardware breakpoints).
The PTE and CR2 fields of the expanded stack frame at SS:(E)SP+50H and 54H respectively are only valid for page faults (Int 0EH). Bits 0-7 of the PTE (page table entry) field are from the actual PTE and may be virtualized by the host; the remaining bits of the PTE field are undefined. The CR2 field contains the linear address that caused the fault.
Exception handlers installed with Functions 0212H and 0213H may terminate in any of the following three ways:
Example: The following code illustrates how a client would install its own exception handler for general protection (GP) faults. The actual handler does nothing more than reach into the stack frame and alter the return address, so that control within the application restarts at a different point after the exception handler exits.
prevgp dd 0 ; address of previous ; GP fault handler . . ; this code is executed during . ; application initialization... mov ax,0210h ; get address of previous mov bl,13 ; owner of GP fault vector int 31h mov word ptr prevgp,dx ; save as far pointer mov word ptr prevgp+2,cx mov ax,0212h ; install our GP fault handler mov bl,13 mov cx,cs ; CX:DX = handler address mov dx,offset _TEXT:gpfisr int 31h jc init9 ; jump, couldn't install . ; continue with initialization . . gpfisr proc far ; this is the actual exception ; handler for GP faults add sp,20h ; discard "old" stack frame push bp ; point CS:IP in stack frmae to mov bp,sp ; GP fault error message routine mov word ptr [bp+0eh],offset _TEXT: gpferr mov word ptr [bp+12h],cs pop bp ret ; now return from exception gpfisr endp gpferr proc near ; this routine executes after ; GPFISR returns to DPMI host mov ax,4c01h ; terminate DPMI client with int 21h ; nonzero return code gpferr endp
webmaster | delorie software privacy |
Copyright © 1999 | Updated Feb 1999 |