windows-nt/Source/XPSP1/NT/sdktools/debuggers/minidump/platform.h

187 lines
5.2 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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')