187 lines
5.2 KiB
C
187 lines
5.2 KiB
C
|
|
/*++
|
|
|
|
Copyright (c) 1999-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
platform.h
|
|
|
|
Abstract:
|
|
|
|
Platform specific macros and functions.
|
|
|
|
Author:
|
|
|
|
Matthew D Hendel (math) 28-Aug-1999
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
// Some processors use both a stack and a backing store.
|
|
// If a particular processor supports backing store add
|
|
// DUMP_BACKING_STORE.
|
|
|
|
#if defined (i386)
|
|
|
|
#define PROGRAM_COUNTER(_context) ((_context)->Eip)
|
|
#define STACK_POINTER(_context) ((_context)->Esp)
|
|
#define INSTRUCTION_WINDOW_SIZE 256
|
|
#define PAGE_SIZE 4096
|
|
|
|
//
|
|
// The CONTEXT_FULL definition on x86 doesn't really get all
|
|
// the registers. Use ALL_REGISTERS to get the compelte
|
|
// context.
|
|
//
|
|
|
|
#define ALL_REGISTERS (CONTEXT_CONTROL |\
|
|
CONTEXT_INTEGER |\
|
|
CONTEXT_SEGMENTS |\
|
|
CONTEXT_FLOATING_POINT |\
|
|
CONTEXT_DEBUG_REGISTERS |\
|
|
CONTEXT_EXTENDED_REGISTERS)
|
|
|
|
//
|
|
// The following are flags specific to the CPUID instruction on x86 only.
|
|
//
|
|
|
|
#define CPUID_VENDOR_ID (0)
|
|
#define CPUID_VERSION_FEATURES (1)
|
|
#define CPUID_AMD_EXTENDED_FEATURES (0x80000001)
|
|
|
|
// X86 doesn't have function entries but it makes the code
|
|
// cleaner to provide placeholder types to avoid some ifdefs in the code
|
|
// itself.
|
|
typedef struct _DYNAMIC_FUNCTION_TABLE {
|
|
LIST_ENTRY Links;
|
|
ULONG64 MinimumAddress;
|
|
ULONG64 MaximumAddress;
|
|
ULONG64 BaseAddress;
|
|
ULONG EntryCount;
|
|
PVOID FunctionTable;
|
|
} DYNAMIC_FUNCTION_TABLE, *PDYNAMIC_FUNCTION_TABLE;
|
|
|
|
typedef struct _RUNTIME_FUNCTION {
|
|
ULONG64 Unused;
|
|
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
|
|
|
|
typedef struct _UNWIND_INFO {
|
|
ULONG64 Unused;
|
|
} UNWIND_INFO, *PUNWIND_INFO;
|
|
|
|
#elif defined(_AMD64_)
|
|
|
|
#define PROGRAM_COUNTER(_context) ((_context)->Rip)
|
|
#define STACK_POINTER(_context) ((_context)->Rsp)
|
|
#define INSTRUCTION_WINDOW_SIZE 256
|
|
#define PAGE_SIZE 4096
|
|
|
|
#define ALL_REGISTERS (CONTEXT_FULL | CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS)
|
|
|
|
#elif defined (ALPHA)
|
|
|
|
#define PROGRAM_COUNTER(_context) ((_context)->Fir)
|
|
#define STACK_POINTER(_context) ((_context)->IntSp)
|
|
#define INSTRUCTION_WINDOW_SIZE 512
|
|
#define PAGE_SIZE 8192
|
|
#define ALL_REGISTERS (CONTEXT_FULL)
|
|
|
|
#elif defined (_IA64_)
|
|
|
|
#define PROGRAM_COUNTER(_context) ((_context)->StIIP)
|
|
#define STACK_POINTER(_context) ((_context)->IntSp)
|
|
#define INSTRUCTION_WINDOW_SIZE 768
|
|
#define PAGE_SIZE 8192
|
|
#define ALL_REGISTERS (CONTEXT_FULL | CONTEXT_DEBUG)
|
|
|
|
#define DUMP_BACKING_STORE
|
|
#if 1
|
|
// XXX drewb - The TEB bstore values don't seem to point to
|
|
// the actual base of the backing store. Just
|
|
// assume it's contiguous with the stack.
|
|
#define BSTORE_BASE(_teb) ((_teb)->NtTib.StackBase)
|
|
#else
|
|
#define BSTORE_BASE(_teb) ((_teb)->DeallocationBStore)
|
|
#endif
|
|
#define BSTORE_LIMIT(_teb) ((_teb)->BStoreLimit)
|
|
// The BSP points to the bottom of the current frame's
|
|
// storage area. We need to add on the size of the
|
|
// current frame to get the amount of memory that
|
|
// really needs to be stored. When computing the
|
|
// size of the current frame space for NAT bits
|
|
// must be figured in properly based on the number
|
|
// of entries in the frame. The NAT collection
|
|
// is spilled on every 63'rd spilled register to
|
|
// make each block an every 64 ULONG64s long.
|
|
// On NT the backing store base is always 9-bit aligned
|
|
// so we can tell when exactly the next NAT spill
|
|
// will occur by looking for when the 9-bit spill
|
|
// region will overflow.
|
|
__inline ULONG64
|
|
BSTORE_POINTER(CONTEXT* Context)
|
|
{
|
|
ULONG64 Limit = Context->RsBSP;
|
|
ULONG Count = (ULONG)(Context->StIFS & 0x7f);
|
|
|
|
// Add in a ULONG64 for every register in the
|
|
// current frame. While doing so, check for
|
|
// spill entries.
|
|
while (Count-- > 0)
|
|
{
|
|
Limit += sizeof(ULONG64);
|
|
if ((Limit & 0x1f8) == 0x1f8)
|
|
{
|
|
// Spill will be placed at this address so
|
|
// account for it.
|
|
Limit += sizeof(ULONG64);
|
|
}
|
|
}
|
|
|
|
return Limit;
|
|
}
|
|
|
|
#elif defined (ARM)
|
|
|
|
#define PROGRAM_COUNTER(_context) ((_context)->Pc)
|
|
#define STACK_POINTER(_context) ((_context)->Sp)
|
|
#define INSTRUCTION_WINDOW_SIZE 512
|
|
#define PAGE_SIZE 4096
|
|
#define ALL_REGISTERS (CONTEXT_CONTROL | CONTEXT_INTEGER)
|
|
|
|
// ARM doesn't have function entries but it makes the code
|
|
// cleaner to provide placeholder types to avoid some ifdefs in the code
|
|
// itself.
|
|
typedef struct _DYNAMIC_FUNCTION_TABLE {
|
|
LIST_ENTRY Links;
|
|
ULONG64 MinimumAddress;
|
|
ULONG64 MaximumAddress;
|
|
ULONG64 BaseAddress;
|
|
ULONG EntryCount;
|
|
PVOID FunctionTable;
|
|
} DYNAMIC_FUNCTION_TABLE, *PDYNAMIC_FUNCTION_TABLE;
|
|
|
|
typedef struct _RUNTIME_FUNCTION {
|
|
ULONG64 Unused;
|
|
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
|
|
|
|
typedef struct _UNWIND_INFO {
|
|
ULONG64 Unused;
|
|
} UNWIND_INFO, *PUNWIND_INFO;
|
|
|
|
#else
|
|
|
|
#error ("unknown processor type")
|
|
|
|
#endif
|
|
|
|
#define AMD_VENDOR_ID_0 ('htuA')
|
|
#define AMD_VENDOR_ID_1 ('itne')
|
|
#define AMD_VENDOR_ID_2 ('DMAc')
|
|
|
|
#define INTEL_VENDOR_ID_0 ('uneG')
|
|
#define INTEL_VENDOR_ID_1 ('Ieni')
|
|
#define INTEL_VENDOR_ID_2 ('letn')
|
|
|