|
|
/*++ 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_
|