You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
688 lines
15 KiB
688 lines
15 KiB
/*++ BUILD Version: 0002 // Increment this if a change has global effects
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
nti386.h
|
|
|
|
Abstract:
|
|
|
|
User-mode visible i386 specific i386 structures and constants
|
|
|
|
Author:
|
|
|
|
Mark Lucovsky (markl) 30-Nov-1989
|
|
|
|
Revision History:
|
|
|
|
Bryan Willman (bryanwi) 8-Jan-90
|
|
|
|
port to the 386
|
|
|
|
--*/
|
|
|
|
#ifndef _NTI386_
|
|
#define _NTI386_
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// begin_ntddk begin_wdm begin_nthal begin_winnt begin_ntminiport begin_wx86
|
|
|
|
#ifdef _X86_
|
|
|
|
//
|
|
// Disable these two pragmas that evaluate to "sti" "cli" on x86 so that driver
|
|
// writers to not leave them inadvertantly in their code.
|
|
//
|
|
|
|
#if !defined(MIDL_PASS)
|
|
#if !defined(RC_INVOKED)
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(push)
|
|
#endif
|
|
#pragma warning(disable:4164) // disable C4164 warning so that apps that
|
|
// build with /Od don't get weird errors !
|
|
#ifdef _M_IX86
|
|
#pragma function(_enable)
|
|
#pragma function(_disable)
|
|
#endif
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(pop)
|
|
#else
|
|
#pragma warning(default:4164) // reenable C4164 warning
|
|
#endif
|
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#if !defined(MIDL_PASS) || defined(_M_IX86)
|
|
|
|
#if (_MSC_FULL_VER >= 13012035)
|
|
|
|
//
|
|
// Define bit scan intrinsics.
|
|
//
|
|
|
|
//#define BitScanForward _BitScanForward
|
|
//#define BitScanReverse _BitScanReverse
|
|
|
|
//BOOLEAN
|
|
//_BitScanForward (
|
|
// OUT ULONG *Index,
|
|
// IN ULONG Mask
|
|
// );
|
|
|
|
//BOOLEAN
|
|
//_BitScanReverse (
|
|
// OUT ULONG *Index,
|
|
// IN ULONG Mask
|
|
// );
|
|
|
|
|
|
//#pragma intrinsic(_BitScanForward)
|
|
//#pragma intrinsic(_BitScanReverse)
|
|
|
|
//
|
|
// Define FS referencing intrinsics
|
|
//
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
UCHAR
|
|
__readfsbyte (
|
|
IN ULONG Offset
|
|
);
|
|
|
|
USHORT
|
|
__readfsword (
|
|
IN ULONG Offset
|
|
);
|
|
|
|
ULONG
|
|
__readfsdword (
|
|
IN ULONG Offset
|
|
);
|
|
|
|
VOID
|
|
__writefsbyte (
|
|
IN ULONG Offset,
|
|
IN UCHAR Data
|
|
);
|
|
|
|
VOID
|
|
__writefsword (
|
|
IN ULONG Offset,
|
|
IN USHORT Data
|
|
);
|
|
|
|
VOID
|
|
__writefsdword (
|
|
IN ULONG Offset,
|
|
IN ULONG Data
|
|
);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#pragma intrinsic(__readfsbyte)
|
|
#pragma intrinsic(__readfsword)
|
|
#pragma intrinsic(__readfsdword)
|
|
#pragma intrinsic(__writefsbyte)
|
|
#pragma intrinsic(__writefsword)
|
|
#pragma intrinsic(__writefsdword)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
// end_ntddk end_wdm end_nthal end_winnt end_ntminiport end_wx86
|
|
|
|
//
|
|
// Values put in ExceptionRecord.ExceptionInformation[0]
|
|
// First parameter is always in ExceptionInformation[1],
|
|
// Second parameter is always in ExceptionInformation[2]
|
|
//
|
|
|
|
#define BREAKPOINT_BREAK 0
|
|
#define BREAKPOINT_PRINT 1
|
|
#define BREAKPOINT_PROMPT 2
|
|
#define BREAKPOINT_LOAD_SYMBOLS 3
|
|
#define BREAKPOINT_UNLOAD_SYMBOLS 4
|
|
#define BREAKPOINT_COMMAND_STRING 5
|
|
|
|
|
|
//
|
|
// Define Address of User Shared Data
|
|
//
|
|
|
|
#define MM_SHARED_USER_DATA_VA 0x7FFE0000
|
|
|
|
#define USER_SHARED_DATA ((KUSER_SHARED_DATA * const)MM_SHARED_USER_DATA_VA)
|
|
|
|
// Add definitions for quick user mode test of i386 system architecture type
|
|
#ifndef IsNEC_98
|
|
#define IsNEC_98 (USER_SHARED_DATA->AlternativeArchitecture == NEC98x86)
|
|
#endif
|
|
#ifndef IsNotNEC_98
|
|
#define IsNotNEC_98 (USER_SHARED_DATA->AlternativeArchitecture != NEC98x86)
|
|
#endif
|
|
#ifndef SetNEC_98
|
|
#define SetNEC_98
|
|
#endif
|
|
|
|
#if defined(MIDL_PASS) || !defined(_M_IX86)
|
|
|
|
struct _TEB *
|
|
NTAPI
|
|
NtCurrentTeb( void );
|
|
#else
|
|
|
|
|
|
#define PcTeb 0x18
|
|
|
|
#if (_MSC_FULL_VER >= 13012035)
|
|
|
|
_inline struct _TEB * NtCurrentTeb( void ) { return (struct _TEB *) (ULONG_PTR) __readfsdword (PcTeb); }
|
|
|
|
#else
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(push)
|
|
#endif
|
|
|
|
#pragma warning (disable:4035) // disable 4035 (function must return something)
|
|
|
|
_inline struct _TEB * NtCurrentTeb( void ) { __asm mov eax, fs:[PcTeb] }
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(pop)
|
|
#else
|
|
#pragma warning (default:4035) // reenable it
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif // defined(MIDL_PASS) || defined(__cplusplus) || !defined(_M_IX86)
|
|
|
|
// begin_ntddk begin_nthal
|
|
//
|
|
// Size of kernel mode stack.
|
|
//
|
|
|
|
#define KERNEL_STACK_SIZE 12288
|
|
|
|
//
|
|
// Define size of large kernel mode stack for callbacks.
|
|
//
|
|
|
|
#define KERNEL_LARGE_STACK_SIZE 61440
|
|
|
|
//
|
|
// Define number of pages to initialize in a large kernel stack.
|
|
//
|
|
|
|
#define KERNEL_LARGE_STACK_COMMIT 12288
|
|
|
|
// end_ntddk end_nthal
|
|
|
|
#define DOUBLE_FAULT_STACK_SIZE KERNEL_STACK_SIZE
|
|
|
|
//
|
|
// Call frame record definition.
|
|
//
|
|
// There is no standard call frame for NT/386, but there is a linked
|
|
// list structure used to register exception handlers, this is it.
|
|
//
|
|
|
|
// begin_nthal
|
|
//
|
|
// Exception Registration structure
|
|
//
|
|
|
|
typedef struct _EXCEPTION_REGISTRATION_RECORD {
|
|
struct _EXCEPTION_REGISTRATION_RECORD *Next;
|
|
PEXCEPTION_ROUTINE Handler;
|
|
} EXCEPTION_REGISTRATION_RECORD;
|
|
|
|
typedef EXCEPTION_REGISTRATION_RECORD *PEXCEPTION_REGISTRATION_RECORD;
|
|
|
|
//
|
|
// Define constants for system IDTs
|
|
//
|
|
|
|
#define MAXIMUM_IDTVECTOR 0xff
|
|
#define MAXIMUM_PRIMARY_VECTOR 0xff
|
|
#define PRIMARY_VECTOR_BASE 0x30 // 0-2f are x86 trap vectors
|
|
|
|
// begin_ntddk
|
|
#ifdef _X86_
|
|
// end_ntddk
|
|
|
|
// begin_ntddk begin_winnt
|
|
|
|
#if !defined(MIDL_PASS) && defined(_M_IX86)
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
MemoryBarrier (
|
|
VOID
|
|
)
|
|
{
|
|
LONG Barrier;
|
|
__asm {
|
|
xchg Barrier, eax
|
|
}
|
|
}
|
|
|
|
#define YieldProcessor() __asm { rep nop }
|
|
|
|
//
|
|
// Prefetch is not supported on all x86 procssors.
|
|
//
|
|
|
|
#define PreFetchCacheLine(l, a)
|
|
|
|
//
|
|
// PreFetchCacheLine level defines.
|
|
//
|
|
|
|
#define PF_TEMPORAL_LEVEL_1
|
|
#define PF_NON_TEMPORAL_LEVEL_ALL
|
|
// end_ntddk
|
|
|
|
#if (_MSC_FULL_VER >= 13012035)
|
|
|
|
_inline PVOID GetFiberData( void ) { return *(PVOID *) (ULONG_PTR) __readfsdword (0x10);}
|
|
_inline PVOID GetCurrentFiber( void ) { return (PVOID) (ULONG_PTR) __readfsdword (0x10);}
|
|
|
|
#else
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(push)
|
|
#endif
|
|
#pragma warning (disable:4035) // disable 4035 (function must return something)
|
|
_inline PVOID GetFiberData( void ) { __asm {
|
|
mov eax, fs:[0x10]
|
|
mov eax,[eax]
|
|
}
|
|
}
|
|
_inline PVOID GetCurrentFiber( void ) { __asm mov eax, fs:[0x10] }
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(pop)
|
|
#else
|
|
#pragma warning (default:4035) // Reenable it
|
|
#endif
|
|
#endif
|
|
|
|
// begin_ntddk
|
|
#endif
|
|
|
|
// begin_wx86
|
|
|
|
//
|
|
// Define the size of the 80387 save area, which is in the context frame.
|
|
//
|
|
|
|
#define SIZE_OF_80387_REGISTERS 80
|
|
|
|
//
|
|
// The following flags control the contents of the CONTEXT structure.
|
|
//
|
|
|
|
#if !defined(RC_INVOKED)
|
|
|
|
#define CONTEXT_i386 0x00010000 // this assumes that i386 and
|
|
#define CONTEXT_i486 0x00010000 // i486 have identical context records
|
|
|
|
// end_wx86
|
|
|
|
#define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
|
|
#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
|
|
#define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L) // DS, ES, FS, GS
|
|
#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L) // 387 state
|
|
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7
|
|
#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386 | 0x00000020L) // cpu specific extensions
|
|
|
|
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER |\
|
|
CONTEXT_SEGMENTS)
|
|
|
|
#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS)
|
|
|
|
// begin_wx86
|
|
|
|
#endif
|
|
|
|
#define MAXIMUM_SUPPORTED_EXTENSION 512
|
|
|
|
typedef struct _FLOATING_SAVE_AREA {
|
|
ULONG ControlWord;
|
|
ULONG StatusWord;
|
|
ULONG TagWord;
|
|
ULONG ErrorOffset;
|
|
ULONG ErrorSelector;
|
|
ULONG DataOffset;
|
|
ULONG DataSelector;
|
|
UCHAR RegisterArea[SIZE_OF_80387_REGISTERS];
|
|
ULONG Cr0NpxState;
|
|
} FLOATING_SAVE_AREA;
|
|
|
|
typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;
|
|
|
|
//
|
|
// Context Frame
|
|
//
|
|
// This frame has a several purposes: 1) it is used as an argument to
|
|
// NtContinue, 2) is is used to constuct a call frame for APC delivery,
|
|
// and 3) it is used in the user level thread creation routines.
|
|
//
|
|
// The layout of the record conforms to a standard call frame.
|
|
//
|
|
|
|
typedef struct _CONTEXT {
|
|
|
|
//
|
|
// The flags values within this flag control the contents of
|
|
// a CONTEXT record.
|
|
//
|
|
// If the context record is used as an input parameter, then
|
|
// for each portion of the context record controlled by a flag
|
|
// whose value is set, it is assumed that that portion of the
|
|
// context record contains valid context. If the context record
|
|
// is being used to modify a threads context, then only that
|
|
// portion of the threads context will be modified.
|
|
//
|
|
// If the context record is used as an IN OUT parameter to capture
|
|
// the context of a thread, then only those portions of the thread's
|
|
// context corresponding to set flags will be returned.
|
|
//
|
|
// The context record is never used as an OUT only parameter.
|
|
//
|
|
|
|
ULONG ContextFlags;
|
|
|
|
//
|
|
// This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
|
|
// set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
|
|
// included in CONTEXT_FULL.
|
|
//
|
|
|
|
ULONG Dr0;
|
|
ULONG Dr1;
|
|
ULONG Dr2;
|
|
ULONG Dr3;
|
|
ULONG Dr6;
|
|
ULONG Dr7;
|
|
|
|
//
|
|
// This section is specified/returned if the
|
|
// ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
|
|
//
|
|
|
|
FLOATING_SAVE_AREA FloatSave;
|
|
|
|
//
|
|
// This section is specified/returned if the
|
|
// ContextFlags word contians the flag CONTEXT_SEGMENTS.
|
|
//
|
|
|
|
ULONG SegGs;
|
|
ULONG SegFs;
|
|
ULONG SegEs;
|
|
ULONG SegDs;
|
|
|
|
//
|
|
// This section is specified/returned if the
|
|
// ContextFlags word contians the flag CONTEXT_INTEGER.
|
|
//
|
|
|
|
ULONG Edi;
|
|
ULONG Esi;
|
|
ULONG Ebx;
|
|
ULONG Edx;
|
|
ULONG Ecx;
|
|
ULONG Eax;
|
|
|
|
//
|
|
// This section is specified/returned if the
|
|
// ContextFlags word contians the flag CONTEXT_CONTROL.
|
|
//
|
|
|
|
ULONG Ebp;
|
|
ULONG Eip;
|
|
ULONG SegCs; // MUST BE SANITIZED
|
|
ULONG EFlags; // MUST BE SANITIZED
|
|
ULONG Esp;
|
|
ULONG SegSs;
|
|
|
|
//
|
|
// This section is specified/returned if the ContextFlags word
|
|
// contains the flag CONTEXT_EXTENDED_REGISTERS.
|
|
// The format and contexts are processor specific
|
|
//
|
|
|
|
UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
|
|
|
|
} CONTEXT;
|
|
|
|
|
|
|
|
typedef CONTEXT *PCONTEXT;
|
|
|
|
// begin_ntminiport
|
|
|
|
#endif //_X86_
|
|
|
|
// end_ntddk end_nthal end_winnt end_ntminiport end_wx86
|
|
|
|
//
|
|
// Define the size of FP registers in the FXSAVE format
|
|
//
|
|
#define SIZE_OF_FX_REGISTERS 128
|
|
|
|
//
|
|
// Format of data for fnsave/frstor instruction
|
|
//
|
|
|
|
typedef struct _FNSAVE_FORMAT {
|
|
ULONG ControlWord;
|
|
ULONG StatusWord;
|
|
ULONG TagWord;
|
|
ULONG ErrorOffset;
|
|
ULONG ErrorSelector;
|
|
ULONG DataOffset;
|
|
ULONG DataSelector;
|
|
UCHAR RegisterArea[SIZE_OF_80387_REGISTERS];
|
|
} FNSAVE_FORMAT, *PFNSAVE_FORMAT;
|
|
|
|
//
|
|
// Format of data for fxsave/fxrstor instruction
|
|
//
|
|
|
|
#include "pshpack1.h"
|
|
typedef struct _FXSAVE_FORMAT {
|
|
USHORT ControlWord;
|
|
USHORT StatusWord;
|
|
USHORT TagWord;
|
|
USHORT ErrorOpcode;
|
|
ULONG ErrorOffset;
|
|
ULONG ErrorSelector;
|
|
ULONG DataOffset;
|
|
ULONG DataSelector;
|
|
ULONG MXCsr;
|
|
ULONG MXCsrMask;
|
|
UCHAR RegisterArea[SIZE_OF_FX_REGISTERS];
|
|
UCHAR Reserved3[SIZE_OF_FX_REGISTERS];
|
|
UCHAR Reserved4[224];
|
|
UCHAR Align16Byte[8];
|
|
} FXSAVE_FORMAT, *PFXSAVE_FORMAT;
|
|
#include "poppack.h"
|
|
|
|
//
|
|
// Union for FLOATING_SAVE_AREA and MMX_FLOATING_SAVE_AREA
|
|
//
|
|
typedef struct _FX_SAVE_AREA {
|
|
union {
|
|
FNSAVE_FORMAT FnArea;
|
|
FXSAVE_FORMAT FxArea;
|
|
} U;
|
|
ULONG NpxSavedCpu; // Cpu that last did fxsave for this thread
|
|
ULONG Cr0NpxState; // Has to be the last field because of the
|
|
// Boot thread
|
|
} FX_SAVE_AREA, *PFX_SAVE_AREA;
|
|
|
|
#define CONTEXT_TO_PROGRAM_COUNTER(Context) ((Context)->Eip)
|
|
#define PROGRAM_COUNTER_TO_CONTEXT(Context, ProgramCounter) ((Context)->Eip = (ProgramCounter))
|
|
|
|
#define CONTEXT_LENGTH (sizeof(CONTEXT))
|
|
#define CONTEXT_ALIGN (sizeof(ULONG))
|
|
#define CONTEXT_ROUND (CONTEXT_ALIGN - 1)
|
|
|
|
|
|
// begin_wx86
|
|
//
|
|
// GDT selectors - These defines are R0 selector numbers, which means
|
|
// they happen to match the byte offset relative to
|
|
// the base of the GDT.
|
|
//
|
|
|
|
#define KGDT_NULL 0
|
|
#define KGDT_R0_CODE 8
|
|
#define KGDT_R0_DATA 16
|
|
#define KGDT_R3_CODE 24
|
|
#define KGDT_R3_DATA 32
|
|
#define KGDT_TSS 40
|
|
#define KGDT_R0_PCR 48
|
|
#define KGDT_R3_TEB 56
|
|
#define KGDT_VDM_TILE 64
|
|
#define KGDT_LDT 72
|
|
#define KGDT_DF_TSS 80
|
|
#define KGDT_NMI_TSS 88
|
|
|
|
// end_wx86
|
|
|
|
#ifdef ABIOS
|
|
|
|
//
|
|
// raid 72661 shielint Should be NEW os2ldr. The ABIOS ifdef will be
|
|
// removed once we switch to new os2ldr.
|
|
//
|
|
|
|
#define KGDT_ALIAS 0x70
|
|
#define KGDT_NUMBER 11
|
|
#else
|
|
#define KGDT_NUMBER 10
|
|
#endif
|
|
|
|
//
|
|
// LDT descriptor entry
|
|
//
|
|
|
|
// begin_winnt begin_wx86
|
|
|
|
#ifndef _LDT_ENTRY_DEFINED
|
|
#define _LDT_ENTRY_DEFINED
|
|
|
|
typedef struct _LDT_ENTRY {
|
|
USHORT LimitLow;
|
|
USHORT BaseLow;
|
|
union {
|
|
struct {
|
|
UCHAR BaseMid;
|
|
UCHAR Flags1; // Declare as bytes to avoid alignment
|
|
UCHAR Flags2; // Problems.
|
|
UCHAR BaseHi;
|
|
} Bytes;
|
|
struct {
|
|
ULONG BaseMid : 8;
|
|
ULONG Type : 5;
|
|
ULONG Dpl : 2;
|
|
ULONG Pres : 1;
|
|
ULONG LimitHi : 4;
|
|
ULONG Sys : 1;
|
|
ULONG Reserved_0 : 1;
|
|
ULONG Default_Big : 1;
|
|
ULONG Granularity : 1;
|
|
ULONG BaseHi : 8;
|
|
} Bits;
|
|
} HighWord;
|
|
} LDT_ENTRY, *PLDT_ENTRY;
|
|
|
|
#endif
|
|
|
|
// end_winnt end_wx86
|
|
|
|
//
|
|
// Process Ldt Information
|
|
// NtQueryInformationProcess using ProcessLdtInformation
|
|
//
|
|
|
|
typedef struct _LDT_INFORMATION {
|
|
ULONG Start;
|
|
ULONG Length;
|
|
LDT_ENTRY LdtEntries[1];
|
|
} PROCESS_LDT_INFORMATION, *PPROCESS_LDT_INFORMATION;
|
|
|
|
//
|
|
// Process Ldt Size
|
|
// NtSetInformationProcess using ProcessLdtSize
|
|
//
|
|
|
|
typedef struct _LDT_SIZE {
|
|
ULONG Length;
|
|
} PROCESS_LDT_SIZE, *PPROCESS_LDT_SIZE;
|
|
|
|
//
|
|
// Thread Descriptor Table Entry
|
|
// NtQueryInformationThread using ThreadDescriptorTableEntry
|
|
//
|
|
|
|
// begin_windbgkd
|
|
|
|
#ifndef _DESCRIPTOR_TABLE_ENTRY_DEFINED
|
|
#define _DESCRIPTOR_TABLE_ENTRY_DEFINED
|
|
|
|
typedef struct _DESCRIPTOR_TABLE_ENTRY {
|
|
ULONG Selector;
|
|
LDT_ENTRY Descriptor;
|
|
} DESCRIPTOR_TABLE_ENTRY, *PDESCRIPTOR_TABLE_ENTRY;
|
|
|
|
#endif // _DESCRIPTOR_TABLE_ENTRY_DEFINED
|
|
|
|
// end_windbgkd
|
|
|
|
// begin_ntddk begin_wdm begin_nthal
|
|
#endif // _X86_
|
|
// end_ntddk end_wdm end_nthal
|
|
|
|
PVOID
|
|
RtlLookupFunctionTable (
|
|
IN PVOID ControlPc,
|
|
OUT PVOID *ImageBase,
|
|
OUT PULONG SizeOfTable
|
|
);
|
|
|
|
//
|
|
// Additional information supplied in QuerySectionInformation for images.
|
|
//
|
|
|
|
#define SECTION_ADDITIONAL_INFO_USED 0
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // _NTI386_
|