Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

vunwind.c File Reference

#include "ntrtlp.h"

Go to the source code of this file.

Classes

struct  _REGISTER_RECORD
struct  _STATE_RECORD
struct  _UNWIND_CONTEXT
struct  _STATE_RECORD_STACK

Defines

#define NOT_IMAGEHLP(E)   E
#define VUW_DEBUG_PRINT   DbgPrint
#define MASK(bp, value)   (value << bp)
#define SVR4_ABI   0
#define HPUX_ABI   1
#define NT_ABI   2
#define STATE_RECORD_STACK_SIZE   32
#define SPILLSIZE_OF_FLOAT128_IN_DWORDS   4
#define SPILLSIZE_OF_ULONGLONG_IN_DWORDS   2
#define REGISTER_SIZE   sizeof(ULONGLONG)
#define STATIC_REGISTER_SET_SIZE   32
#define SLOTS_PER_BUNDLE   3
#define R1_MASK   0xC0
#define R1_PREFIX   0x0
#define R1_REGION_TYPE_MASK   0x20
#define R1_LENGTH_MASK   0x1F
#define R2_MASK   0xE0
#define R2_PREFIX   0x40
#define R3_MASK   0xE0
#define R3_PREFIX   0x60
#define R3_REGION_TYPE_MASK   0x3
#define P1_MASK   0xE0
#define P1_PREFIX   0x80
#define P2_MASK   0xF0
#define P2_PREFIX   0xA0
#define P3_MASK   0xF8
#define P3_PREFIX   0xB0
#define P4_MASK   0xFF
#define P4_PREFIX   0xB8
#define P5_MASK   0xFF
#define P5_PREFIX   0xB9
#define P6_MASK   0xE0
#define P6_PREFIX   0xC0
#define P7_MASK   0xF0
#define P7_PREFIX   0xE0
#define P8_MASK   0xFF
#define P8_PREFIX   0xF0
#define P9_MASK   0xFF
#define P9_PREFIX   0xF1
#define P10_MASK   0xFF
#define P10_PREFIX   0xFF
#define B1_MASK   0xC0
#define B1_PREFIX   0x80
#define B1_TYPE_MASK   0x20
#define B1_LABEL_MASK   0x1F
#define B2_MASK   0xE0
#define B2_PREFIX   0xC0
#define B2_ECOUNT_MASK   0x1F
#define B3_MASK   0xF0
#define B3_PREFIX   0xE0
#define B4_MASK   0xF0
#define B4_PREFIX   0xF0
#define B4_TYPE_MASK   0x08
#define PSP_GR   0
#define RP_GR   1
#define PFS_GR   2
#define PREDS_GR   3
#define UNAT_GR   4
#define LC_GR   5
#define RP_BR   6
#define RNAT_GR   7
#define BSP_GR   8
#define BSPSTORE_GR   9
#define FPSR_GR   10
#define PRIUNAT_GR   11
#define MEM_STACK_F   0
#define MEM_STACK_V   1
#define SPILL_BASE   2
#define PSP_SPREL   3
#define RP_WHEN   4
#define RP_PSPREL   5
#define PFS_WHEN   6
#define PFS_PSPREL   7
#define PREDS_WHEN   8
#define PREDS_PSPREL   9
#define LC_WHEN   10
#define LC_PSPREL   11
#define UNAT_WHEN   12
#define UNAT_PSPREL   13
#define FPSR_WHEN   14
#define FPSR_PSPREL   15
#define PSP_PSPREL   0
#define RP_SPREL   1
#define PFS_SPREL   2
#define PREDS_SPREL   3
#define LC_SPREL   4
#define UNAT_SPREL   5
#define FPSR_SPREL   6
#define BSP_WHEN   7
#define BSP_PSPREL   8
#define BSP_SPREL   9
#define BSPSTORE_WHEN   10
#define BSPSTORE_PSPREL   11
#define BSPSTORE_SPREL   12
#define RNAT_WHEN   13
#define RNAT_PSPREL   14
#define RNAT_SPREL   15
#define PRIUNAT_WHEN   16
#define PRIUNAT_PSPREL   17
#define PRIUNAT_SPREL   18
#define STACK_POINTER_GR   12
#define FIRST_PRESERVED_GR   4
#define LAST_PRESERVED_GR   7
#define NUMBER_OF_PRESERVED_GR   4
#define FIRST_LOW_PRESERVED_FR   2
#define LAST_LOW_PRESERVED_FR   5
#define NUMBER_OF_LOW_PRESERVED_FR   4
#define FIRST_HIGH_PRESERVED_FR   16
#define LAST_HIGH_PRESERVED_FR   31
#define NUMBER_OF_HIGH_PRESERVED_FR   16
#define NUMBER_OF_PRESERVED_FR   NUMBER_OF_LOW_PRESERVED_FR+NUMBER_OF_HIGH_PRESERVED_FR
#define FIRST_PRESERVED_BR   1
#define LAST_PRESERVED_BR   5
#define NUMBER_OF_PRESERVED_BR   5
#define NUMBER_OF_PRESERVED_MISC   7
#define NUMBER_OF_PRESERVED_REGISTERS   12
#define REG_MISC_BASE   0
#define REG_PREDS   REG_MISC_BASE+0
#define REG_SP   REG_MISC_BASE+1
#define REG_PFS   REG_MISC_BASE+2
#define REG_RP   REG_MISC_BASE+3
#define REG_UNAT   REG_MISC_BASE+4
#define REG_LC   REG_MISC_BASE+5
#define REG_NATS   REG_MISC_BASE+6
#define REG_BR_BASE   REG_MISC_BASE+NUMBER_OF_PRESERVED_MISC
#define REG_FPSR   0xff
#define REG_BSP   0xff
#define REG_BSPSTORE   0xff
#define REG_RNAT   0xff
#define GENERAL_REG   0
#define PSP_RELATIVE   1
#define SP_RELATIVE   2
#define BRANCH_REG   3
#define ADD_STATE_RECORD(States, RegionLength, DescBeginIndex)
#define VALID_LABEL_BIT_POSITION   15
#define LABEL_REGION(Region, Label)
#define IS_REGION_LABELED(Region)   (Region->MiscMask & (1 << VALID_LABEL_BIT_POSITION))
#define CHECK_LABEL(State, Label)   ( (IS_REGION_LABELED(State)) && (Label == State->Label) )
#define EXTRACT_NAT_FROM_UNAT(NatBit)   NatBit = (UCHAR)((IntNats >> (((ULONG_PTR)Source & 0x1F8) >> 3)) & 0x1);
#define UW_DEBUG(x)
#define OFFSET(type, field)   ((ULONG_PTR)(&((type *)0)->field))

Typedefs

typedef _REGISTER_RECORD REGISTER_RECORD
typedef _REGISTER_RECORDPREGISTER_RECORD
typedef ULONG LABEL
typedef _STATE_RECORD STATE_RECORD
typedef _STATE_RECORDPSTATE_RECORD
typedef _UNWIND_CONTEXT UNWIND_CONTEXT
typedef _UNWIND_CONTEXTPUNWIND_CONTEXT
typedef _STATE_RECORD_STACK STATE_RECORD_STACK
typedef _STATE_RECORD_STACKPSTATE_RECORD_STACK

Functions

UCHAR NewParsePrologueRegionPhase0 (IN PUNWIND_CONTEXT UwContext, IN PSTATE_RECORD StateRecord, IN OUT PUCHAR AbiImmContext)
VOID NewParsePrologueRegionPhase1 (IN PUNWIND_CONTEXT UwContext, IN PSTATE_RECORD StateRecord)
VOID SrInitialize (IN PSTATE_RECORD_STACK StateTable, IN PSTATE_RECORD StateRecord, IN ULONG Size)
ULONG ReadLEB128 (IN PUCHAR Descriptors, IN OUT PULONG CurrentDescIndex)
ULONGLONG RestorePreservedRegisterFromGR (IN PCONTEXT Context, IN SHORT BsFrameSize, IN SHORT RNatSaveIndex, IN SHORT GrNumber, OUT ULONG64 *SourceAddress, OUT PUCHAR Nat OPTIONAL)
UCHAR ParseBodyRegionDescriptors (IN PUNWIND_CONTEXT UnwindContext, IN PSTATE_RECORD_STACK StateTable, IN ULONG RegionLen)
ULONGLONG ProcessInterruptRegion (IN PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, IN PUNWIND_CONTEXT UnwindContext, IN PCONTEXT Context, IN SHORT BsFrameSize, IN SHORT RNatSaveIndex, IN UCHAR AbiImmContext)
ULONGLONG RtlVirtualUnwind (IN ULONGLONG ImageBase, IN ULONGLONG ControlPc, IN PRUNTIME_FUNCTION FunctionEntry, IN OUT PCONTEXT ContextRecord, OUT PBOOLEAN InFunction, OUT PFRAME_POINTERS EstablisherFrame, IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL)

Variables

USHORT MiscContextOffset [NUMBER_OF_PRESERVED_REGISTERS]
USHORT MiscContextPointersOffset [NUMBER_OF_PRESERVED_REGISTERS]
UCHAR P3RecordTypeToRegisterIndex []
UCHAR P7RecordTypeToRegisterIndex []
UCHAR P8RecordTypeToRegisterIndex []


Define Documentation

#define ADD_STATE_RECORD States,
RegionLength,
DescBeginIndex   ) 
 

Value:

States.Top++; \ States.Top->IsTarget = FALSE; \ States.Top->MiscMask = 0; \ States.Top->FrMask = 0; \ States.Top->GrMask = 0; \ States.Top->Label = (LABEL)0; \ States.Top->Ecount = 0; \ States.Top->RegionLen = RegionLength; \ States.Top->RegionBegin = UnwindContext.SlotCount; \ States.Top->SpWhen = 0; \ States.Top->SpAdjustment = 0; \ States.Top->SpillBase = (States.Top-1)->SpillPtr; \ States.Top->SpillPtr = (States.Top-1)->SpillPtr; \ States.Top->Previous = States.Current; \ States.Top->DescBegin = DescBeginIndex; \ States.Current = States.Top

Definition at line 241 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define B1_LABEL_MASK   0x1F
 

Definition at line 113 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B1_MASK   0xC0
 

Definition at line 110 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B1_PREFIX   0x80
 

Definition at line 111 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B1_TYPE_MASK   0x20
 

Definition at line 112 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B2_ECOUNT_MASK   0x1F
 

Definition at line 116 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B2_MASK   0xE0
 

Definition at line 114 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B2_PREFIX   0xC0
 

Definition at line 115 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B3_MASK   0xF0
 

Definition at line 117 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B3_PREFIX   0xE0
 

Definition at line 118 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B4_MASK   0xF0
 

Definition at line 119 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B4_PREFIX   0xF0
 

Definition at line 120 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define B4_TYPE_MASK   0x08
 

Definition at line 121 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define BRANCH_REG   3
 

Definition at line 238 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and RtlVirtualUnwind().

#define BSP_GR   8
 

Definition at line 135 of file ia64/vunwind.c.

#define BSP_PSPREL   8
 

Definition at line 173 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define BSP_SPREL   9
 

Definition at line 174 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define BSP_WHEN   7
 

Definition at line 172 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define BSPSTORE_GR   9
 

Definition at line 136 of file ia64/vunwind.c.

#define BSPSTORE_PSPREL   11
 

Definition at line 176 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define BSPSTORE_SPREL   12
 

Definition at line 177 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define BSPSTORE_WHEN   10
 

Definition at line 175 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define CHECK_LABEL State,
Label   )     ( (IS_REGION_LABELED(State)) && (Label == State->Label) )
 

Definition at line 269 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define EXTRACT_NAT_FROM_UNAT NatBit   )     NatBit = (UCHAR)((IntNats >> (((ULONG_PTR)Source & 0x1F8) >> 3)) & 0x1);
 

Definition at line 273 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define FIRST_HIGH_PRESERVED_FR   16
 

Definition at line 196 of file ia64/vunwind.c.

#define FIRST_LOW_PRESERVED_FR   2
 

Definition at line 192 of file ia64/vunwind.c.

#define FIRST_PRESERVED_BR   1
 

Definition at line 201 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define FIRST_PRESERVED_GR   4
 

Definition at line 188 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define FPSR_GR   10
 

Definition at line 137 of file ia64/vunwind.c.

#define FPSR_PSPREL   15
 

Definition at line 159 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define FPSR_SPREL   6
 

Definition at line 171 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define FPSR_WHEN   14
 

Definition at line 158 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define GENERAL_REG   0
 

Definition at line 235 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and RtlVirtualUnwind().

#define HPUX_ABI   1
 

Definition at line 59 of file ia64/vunwind.c.

#define IS_REGION_LABELED Region   )     (Region->MiscMask & (1 << VALID_LABEL_BIT_POSITION))
 

Definition at line 266 of file ia64/vunwind.c.

#define LABEL_REGION Region,
Label   ) 
 

Value:

Region->Label = Label; \ Region->MiscMask |= (1 << VALID_LABEL_BIT_POSITION)

Definition at line 262 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

#define LAST_HIGH_PRESERVED_FR   31
 

Definition at line 197 of file ia64/vunwind.c.

#define LAST_LOW_PRESERVED_FR   5
 

Definition at line 193 of file ia64/vunwind.c.

#define LAST_PRESERVED_BR   5
 

Definition at line 202 of file ia64/vunwind.c.

#define LAST_PRESERVED_GR   7
 

Definition at line 189 of file ia64/vunwind.c.

#define LC_GR   5
 

Definition at line 132 of file ia64/vunwind.c.

#define LC_PSPREL   11
 

Definition at line 155 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define LC_SPREL   4
 

Definition at line 169 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define LC_WHEN   10
 

Definition at line 154 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define MASK bp,
value   )     (value << bp)
 

Definition at line 52 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), NewParsePrologueRegionPhase1(), and RtlVirtualUnwind().

#define MEM_STACK_F   0
 

Definition at line 144 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define MEM_STACK_V   1
 

Definition at line 145 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define NOT_IMAGEHLP  )     E
 

Copyright (C) 1996-1999 Intel Corporation. All rights reserved.

The information and source code contained herein is the exclusive property of Intel Corporation and may not be disclosed, examined or reproduced in whole or in part without explicit written authorization from the company.

WARNING: ntos.c and sdktools.c are identical. For sake of maintenance and for debug purposes, please keep them as this. Thank you.

Definition at line 44 of file ia64/vunwind.c.

Referenced by RestorePreservedRegisterFromGR(), and RtlVirtualUnwind().

#define NT_ABI   2
 

Definition at line 60 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0().

#define NUMBER_OF_HIGH_PRESERVED_FR   16
 

Definition at line 198 of file ia64/vunwind.c.

Referenced by ProcessInterruptRegion().

#define NUMBER_OF_LOW_PRESERVED_FR   4
 

Definition at line 194 of file ia64/vunwind.c.

Referenced by ProcessInterruptRegion(), and RtlVirtualUnwind().

#define NUMBER_OF_PRESERVED_BR   5
 

Definition at line 203 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and ProcessInterruptRegion().

#define NUMBER_OF_PRESERVED_FR   NUMBER_OF_LOW_PRESERVED_FR+NUMBER_OF_HIGH_PRESERVED_FR
 

Definition at line 199 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and RtlVirtualUnwind().

#define NUMBER_OF_PRESERVED_GR   4
 

Definition at line 190 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), ProcessInterruptRegion(), and RtlVirtualUnwind().

#define NUMBER_OF_PRESERVED_MISC   7
 

Definition at line 205 of file ia64/vunwind.c.

#define NUMBER_OF_PRESERVED_REGISTERS   12
 

Definition at line 207 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define OFFSET type,
field   )     ((ULONG_PTR)(&((type *)0)->field))
 

Definition at line 338 of file ia64/vunwind.c.

#define P10_MASK   0xFF
 

Definition at line 107 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P10_PREFIX   0xFF
 

Definition at line 108 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P1_MASK   0xE0
 

Definition at line 89 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P1_PREFIX   0x80
 

Definition at line 90 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P2_MASK   0xF0
 

Definition at line 91 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P2_PREFIX   0xA0
 

Definition at line 92 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P3_MASK   0xF8
 

Definition at line 93 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P3_PREFIX   0xB0
 

Definition at line 94 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P4_MASK   0xFF
 

Definition at line 95 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P4_PREFIX   0xB8
 

Definition at line 96 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P5_MASK   0xFF
 

Definition at line 97 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P5_PREFIX   0xB9
 

Definition at line 98 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P6_MASK   0xE0
 

Definition at line 99 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P6_PREFIX   0xC0
 

Definition at line 100 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P7_MASK   0xF0
 

Definition at line 101 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P7_PREFIX   0xE0
 

Definition at line 102 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P8_MASK   0xFF
 

Definition at line 103 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P8_PREFIX   0xF0
 

Definition at line 104 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P9_MASK   0xFF
 

Definition at line 105 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define P9_PREFIX   0xF1
 

Definition at line 106 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PFS_GR   2
 

Definition at line 129 of file ia64/vunwind.c.

#define PFS_PSPREL   7
 

Definition at line 151 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PFS_SPREL   2
 

Definition at line 167 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PFS_WHEN   6
 

Definition at line 150 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PREDS_GR   3
 

Definition at line 130 of file ia64/vunwind.c.

#define PREDS_PSPREL   9
 

Definition at line 153 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PREDS_SPREL   3
 

Definition at line 168 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PREDS_WHEN   8
 

Definition at line 152 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PRIUNAT_GR   11
 

Definition at line 138 of file ia64/vunwind.c.

#define PRIUNAT_PSPREL   17
 

Definition at line 182 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PRIUNAT_SPREL   18
 

Definition at line 183 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PRIUNAT_WHEN   16
 

Definition at line 181 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PSP_GR   0
 

Definition at line 127 of file ia64/vunwind.c.

#define PSP_PSPREL   0
 

Definition at line 165 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define PSP_RELATIVE   1
 

Definition at line 236 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and RtlVirtualUnwind().

#define PSP_SPREL   3
 

Definition at line 147 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define R1_LENGTH_MASK   0x1F
 

Definition at line 80 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define R1_MASK   0xC0
 

Definition at line 77 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define R1_PREFIX   0x0
 

Definition at line 78 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define R1_REGION_TYPE_MASK   0x20
 

Definition at line 79 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define R2_MASK   0xE0
 

Definition at line 82 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and RtlVirtualUnwind().

#define R2_PREFIX   0x40
 

Definition at line 83 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and RtlVirtualUnwind().

#define R3_MASK   0xE0
 

Definition at line 85 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define R3_PREFIX   0x60
 

Definition at line 86 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define R3_REGION_TYPE_MASK   0x3
 

Definition at line 87 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define REG_BR_BASE   REG_MISC_BASE+NUMBER_OF_PRESERVED_MISC
 

Definition at line 219 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1().

#define REG_BSP   0xff
 

Definition at line 222 of file ia64/vunwind.c.

#define REG_BSPSTORE   0xff
 

Definition at line 223 of file ia64/vunwind.c.

#define REG_FPSR   0xff
 

Definition at line 221 of file ia64/vunwind.c.

#define REG_LC   REG_MISC_BASE+5
 

Definition at line 216 of file ia64/vunwind.c.

#define REG_MISC_BASE   0
 

Definition at line 210 of file ia64/vunwind.c.

#define REG_NATS   REG_MISC_BASE+6
 

Definition at line 217 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define REG_PFS   REG_MISC_BASE+2
 

Definition at line 213 of file ia64/vunwind.c.

#define REG_PREDS   REG_MISC_BASE+0
 

Definition at line 211 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1().

#define REG_RNAT   0xff
 

Definition at line 224 of file ia64/vunwind.c.

#define REG_RP   REG_MISC_BASE+3
 

Definition at line 214 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1().

#define REG_SP   REG_MISC_BASE+1
 

Definition at line 212 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define REG_UNAT   REG_MISC_BASE+4
 

Definition at line 215 of file ia64/vunwind.c.

#define REGISTER_SIZE   sizeof(ULONGLONG)
 

Definition at line 73 of file ia64/vunwind.c.

#define RNAT_GR   7
 

Definition at line 134 of file ia64/vunwind.c.

#define RNAT_PSPREL   14
 

Definition at line 179 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define RNAT_SPREL   15
 

Definition at line 180 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define RNAT_WHEN   13
 

Definition at line 178 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define RP_BR   6
 

Definition at line 133 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1().

#define RP_GR   1
 

Definition at line 128 of file ia64/vunwind.c.

#define RP_PSPREL   5
 

Definition at line 149 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define RP_SPREL   1
 

Definition at line 166 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define RP_WHEN   4
 

Definition at line 148 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define SLOTS_PER_BUNDLE   3
 

Definition at line 75 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define SP_RELATIVE   2
 

Definition at line 237 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and RtlVirtualUnwind().

#define SPILL_BASE   2
 

Definition at line 146 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define SPILLSIZE_OF_FLOAT128_IN_DWORDS   4
 

Definition at line 70 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1().

#define SPILLSIZE_OF_ULONGLONG_IN_DWORDS   2
 

Definition at line 71 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1().

#define STACK_POINTER_GR   12
 

Definition at line 186 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define STATE_RECORD_STACK_SIZE   32
 

Definition at line 68 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

#define STATIC_REGISTER_SET_SIZE   32
 

Definition at line 74 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1(), and RestorePreservedRegisterFromGR().

#define SVR4_ABI   0
 

Definition at line 58 of file ia64/vunwind.c.

#define UNAT_GR   4
 

Definition at line 131 of file ia64/vunwind.c.

#define UNAT_PSPREL   13
 

Definition at line 157 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define UNAT_SPREL   5
 

Definition at line 170 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define UNAT_WHEN   12
 

Definition at line 156 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

#define UW_DEBUG  ) 
 

Definition at line 285 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), NewParsePrologueRegionPhase1(), ParseBodyRegionDescriptors(), RestorePreservedRegisterFromGR(), and RtlVirtualUnwind().

#define VALID_LABEL_BIT_POSITION   15
 

Definition at line 260 of file ia64/vunwind.c.

#define VUW_DEBUG_PRINT   DbgPrint
 

Definition at line 45 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().


Typedef Documentation

typedef ULONG LABEL
 

Definition at line 296 of file ia64/vunwind.c.

Referenced by ParseBodyRegionDescriptors().

typedef struct _REGISTER_RECORD * PREGISTER_RECORD
 

typedef struct _STATE_RECORD * PSTATE_RECORD
 

Referenced by ParseBodyRegionDescriptors(), and RtlVirtualUnwind().

typedef struct _STATE_RECORD_STACK * PSTATE_RECORD_STACK
 

typedef struct _UNWIND_CONTEXT * PUNWIND_CONTEXT
 

typedef struct _REGISTER_RECORD REGISTER_RECORD
 

typedef struct _STATE_RECORD STATE_RECORD
 

typedef struct _STATE_RECORD_STACK STATE_RECORD_STACK
 

typedef struct _UNWIND_CONTEXT UNWIND_CONTEXT
 


Function Documentation

UCHAR NewParsePrologueRegionPhase0 IN PUNWIND_CONTEXT  UwContext,
IN PSTATE_RECORD  StateRecord,
IN OUT PUCHAR  AbiImmContext
 

Definition at line 1517 of file ia64/vunwind.c.

References BSP_PSPREL, BSP_SPREL, BSP_WHEN, BSPSTORE_PSPREL, BSPSTORE_SPREL, BSPSTORE_WHEN, FPSR_PSPREL, FPSR_SPREL, FPSR_WHEN, Index, LC_PSPREL, LC_SPREL, LC_WHEN, MASK, MEM_STACK_F, MEM_STACK_V, NT_ABI, Offset, P10_MASK, P10_PREFIX, P1_MASK, P1_PREFIX, P2_MASK, P2_PREFIX, P3_MASK, P3_PREFIX, P4_MASK, P4_PREFIX, P5_MASK, P5_PREFIX, P6_MASK, P6_PREFIX, P7_MASK, P7_PREFIX, P7RecordTypeToRegisterIndex, P8_MASK, P8_PREFIX, P9_MASK, P9_PREFIX, PFS_PSPREL, PFS_SPREL, PFS_WHEN, PREDS_PSPREL, PREDS_SPREL, PREDS_WHEN, PRIUNAT_PSPREL, PRIUNAT_SPREL, PRIUNAT_WHEN, PSP_PSPREL, PSP_SPREL, ReadLEB128(), RNAT_PSPREL, RNAT_SPREL, RNAT_WHEN, RP_PSPREL, RP_SPREL, RP_WHEN, SPILL_BASE, UNAT_PSPREL, UNAT_SPREL, UNAT_WHEN, UW_DEBUG, and VUW_DEBUG_PRINT.

Referenced by RtlVirtualUnwind().

01522 { 01523 PUCHAR Desc = UwContext->Descriptors; 01524 ULONG Offset; 01525 ULONG FrameSize; 01526 ULONG Index; 01527 UCHAR RecType; 01528 UCHAR FirstByte; 01529 UCHAR SecondByte; 01530 ULONG GrSave; 01531 ULONG TempMask; 01532 ULONG i; 01533 01534 while (UwContext->DescCount < UwContext->Size) { 01535 01536 FirstByte = Desc[UwContext->DescCount++]; 01537 01538 if ( (FirstByte & P1_MASK) == P1_PREFIX) { 01539 01540 continue; 01541 01542 } else if ( (FirstByte & P2_MASK) == P2_PREFIX ) { 01543 01544 UwContext->DescCount++; 01545 01546 } else if ( (FirstByte & P3_MASK) == P3_PREFIX ) { 01547 01548 UwContext->DescCount++; 01549 01550 } else if ( (FirstByte & P4_MASK) == P4_PREFIX ) { 01551 01552 UwContext->DescCount += ((State->RegionLen+3) >> 2); 01553 01554 } else if ( (FirstByte & P5_MASK) == P5_PREFIX ) { 01555 01556 UwContext->DescCount += 3; 01557 01558 } else if ( (FirstByte & P6_MASK) == P6_PREFIX ) { 01559 01560 continue; 01561 01562 } else if ( (FirstByte & P7_MASK) == P7_PREFIX ) { 01563 01564 RecType = FirstByte & ~P7_MASK; 01565 01566 switch (RecType) { 01567 01568 case MEM_STACK_F: 01569 01570 Offset = ReadLEB128(Desc, &UwContext->DescCount); 01571 FrameSize = ReadLEB128(Desc, &UwContext->DescCount); 01572 01573 if (UwContext->TargetSlot > (UwContext->SlotCount+Offset)) 01574 { 01575 State->SpAdjustment += FrameSize*4; 01576 State->SpWhen = Offset; 01577 } 01578 break; 01579 01580 case SPILL_BASE: 01581 01582 State->SpillBase = ReadLEB128(Desc, &UwContext->DescCount); 01583 State->SpillPtr = State->SpillBase; 01584 break; 01585 01586 case MEM_STACK_V: 01587 case RP_WHEN: 01588 case PFS_WHEN: 01589 case PREDS_WHEN: 01590 case LC_WHEN: 01591 case UNAT_WHEN: 01592 case FPSR_WHEN: 01593 01594 Offset = ReadLEB128(Desc, &UwContext->DescCount); 01595 if ((State->IsTarget) && 01596 (UwContext->TargetSlot > (UwContext->SlotCount+Offset))) 01597 { 01598 Index = P7RecordTypeToRegisterIndex[RecType]; 01599 if (!(State->MiscMask & (1 << Index))) { 01600 State->MiscMask |= MASK(Index,1); 01601 UwContext->MiscRegs[Index].When = Offset; 01602 } else { 01603 UW_DEBUG(("Duplicate descriptors,")); 01604 UW_DEBUG(("unwinder may produce incorrect result!\n")); 01605 } 01606 } 01607 UW_DEBUG(("Prolog P7: type=%d slot= %d\n", RecType, Offset)); 01608 break; 01609 01610 case PSP_SPREL: 01611 case RP_PSPREL: 01612 case PFS_PSPREL: 01613 case PREDS_PSPREL: 01614 case LC_PSPREL: 01615 case UNAT_PSPREL: 01616 case FPSR_PSPREL: 01617 01618 Offset = ReadLEB128(Desc, &UwContext->DescCount); 01619 break; 01620 01621 default: 01622 01623 UW_DEBUG(("Invalid record type for descriptor P7!\n")); 01624 01625 } 01626 01627 } else if ( (FirstByte & P8_MASK) == P8_PREFIX ) { 01628 01629 RecType = Desc[UwContext->DescCount++]; 01630 01631 switch (RecType) { 01632 01633 case PSP_PSPREL: 01634 case RP_SPREL: 01635 case PFS_SPREL: 01636 case PREDS_SPREL: 01637 case LC_SPREL: 01638 case UNAT_SPREL: 01639 case FPSR_SPREL: 01640 case BSP_PSPREL: 01641 case BSP_SPREL: 01642 case BSPSTORE_PSPREL: 01643 case BSPSTORE_SPREL: 01644 case RNAT_PSPREL: 01645 case RNAT_SPREL: 01646 case PRIUNAT_PSPREL: 01647 case PRIUNAT_SPREL: 01648 01649 Offset = ReadLEB128(Desc, &UwContext->DescCount); 01650 UW_DEBUG(("Prolog P8: type=%d slot= %d\n", RecType, Offset)); 01651 break; 01652 01653 case BSP_WHEN: 01654 case BSPSTORE_WHEN: 01655 case RNAT_WHEN: 01656 case PRIUNAT_WHEN: 01657 01658 Offset = ReadLEB128(Desc, &UwContext->DescCount); 01659 if ((State->IsTarget) && 01660 (UwContext->TargetSlot > (UwContext->SlotCount+Offset))) 01661 { 01662 Index = P7RecordTypeToRegisterIndex[RecType]; 01663 if (!(State->MiscMask & (1 << Index))) { 01664 State->MiscMask |= MASK(Index,1); 01665 UwContext->MiscRegs[Index].When = Offset; 01666 } else { 01667 UW_DEBUG(("Duplicate descriptors,")); 01668 UW_DEBUG(("unwinder may produce incorrect result!\n")); 01669 } 01670 } 01671 UW_DEBUG(("Prolog P8: type=%d slot= %d\n", RecType, Offset)); 01672 break; 01673 01674 default: 01675 01676 UW_DEBUG(("Invalid record type for descriptor P8!\n")); 01677 01678 } 01679 01680 } else if ( (FirstByte & P9_MASK) == P9_PREFIX ) { 01681 01682 UwContext->DescCount += 2; 01683 VUW_DEBUG_PRINT("Format P9 not supported yet!\n"); 01684 01685 } else if ( (FirstByte & P10_MASK) == P10_PREFIX ) { 01686 01687 UCHAR Abi = Desc[UwContext->DescCount++]; 01688 UCHAR Context = Desc[UwContext->DescCount++]; 01689 01690 *AbiImmContext = Context; 01691 01692 if (Abi != NT_ABI) { 01693 VUW_DEBUG_PRINT("Unknown ABI unwind descriptor\n"); 01694 } 01695 01696 } else { 01697 01698 // 01699 // Encounter another region header record 01700 // 01701 01702 break; 01703 } 01704 } 01705 01706 State->DescEnd = UwContext->DescCount - 2; 01707 01708 return FirstByte; 01709 }

VOID NewParsePrologueRegionPhase1 IN PUNWIND_CONTEXT  UwContext,
IN PSTATE_RECORD  StateRecord
 

Definition at line 1712 of file ia64/vunwind.c.

References BRANCH_REG, BSP_PSPREL, BSP_SPREL, BSP_WHEN, BSPSTORE_PSPREL, BSPSTORE_SPREL, BSPSTORE_WHEN, Count, FALSE, FPSR_PSPREL, FPSR_SPREL, FPSR_WHEN, GENERAL_REG, Index, LC_PSPREL, LC_SPREL, LC_WHEN, MASK, MEM_STACK_F, MEM_STACK_V, NUMBER_OF_PRESERVED_BR, NUMBER_OF_PRESERVED_FR, NUMBER_OF_PRESERVED_GR, Offset, P10_MASK, P10_PREFIX, P1_MASK, P1_PREFIX, P2_MASK, P2_PREFIX, P3_MASK, P3_PREFIX, P3RecordTypeToRegisterIndex, P4_MASK, P4_PREFIX, P5_MASK, P5_PREFIX, P6_MASK, P6_PREFIX, P7_MASK, P7_PREFIX, P7RecordTypeToRegisterIndex, P8_MASK, P8_PREFIX, P8RecordTypeToRegisterIndex, P9_MASK, P9_PREFIX, PFS_PSPREL, PFS_SPREL, PFS_WHEN, PREDS_PSPREL, PREDS_SPREL, PREDS_WHEN, PRIUNAT_PSPREL, PRIUNAT_SPREL, PRIUNAT_WHEN, PSP_PSPREL, PSP_RELATIVE, PSP_SPREL, R2_MASK, R2_PREFIX, ReadLEB128(), REG_BR_BASE, REG_PREDS, REG_RP, RNAT_PSPREL, RNAT_SPREL, RNAT_WHEN, RP_BR, RP_PSPREL, RP_SPREL, RP_WHEN, SP_RELATIVE, SPILL_BASE, SPILLSIZE_OF_FLOAT128_IN_DWORDS, SPILLSIZE_OF_ULONGLONG_IN_DWORDS, STATIC_REGISTER_SET_SIZE, TRUE, UNAT_PSPREL, UNAT_SPREL, UNAT_WHEN, USHORT, UW_DEBUG, and VUW_DEBUG_PRINT.

Referenced by RtlVirtualUnwind().

01716 { 01717 ULONG FrameSize; 01718 ULONG Offset; 01719 ULONG GrSave; 01720 ULONG BrBase; 01721 ULONG Index; 01722 ULONG Count; 01723 UCHAR RecType; 01724 UCHAR FirstByte, SecondByte; // 1st & 2nd bytes of a region header record 01725 ULONG DescIndex; 01726 ULONG ImaskBegin; 01727 UCHAR NextBr, NextGr, NextFr; 01728 USHORT MiscMask; 01729 ULONG TempMask; 01730 ULONG FrMask = 0; 01731 UCHAR BrMask = 0; 01732 UCHAR GrMask = 0; 01733 PUCHAR Desc = UwContext->Descriptors; 01734 BOOLEAN SpillMaskOmitted = TRUE; 01735 01736 DescIndex = State->DescBegin; 01737 01738 FirstByte = Desc[DescIndex]; 01739 01740 if ((FirstByte & R2_MASK) == R2_PREFIX) { 01741 01742 // 01743 // general prologue region header; need to process it first 01744 // 01745 01746 ULONG GrSave, Count; 01747 UCHAR MiscMask; 01748 UCHAR SecondByte; 01749 USHORT i; 01750 01751 DescIndex++; 01752 SecondByte = Desc[DescIndex++]; 01753 MiscMask = ((FirstByte & 0x7) << 1) | ((SecondByte & 0x80) >> 7); 01754 GrSave = SecondByte & 0x7F; 01755 ReadLEB128(Desc, &DescIndex); // advance the descriptor index 01756 01757 if (GrSave < STATIC_REGISTER_SET_SIZE) { 01758 UW_DEBUG(("Invalid unwind descriptor!\n")); 01759 } 01760 01761 UW_DEBUG(("Region R2: rmask=%x,grsave=%d,length=%d\n", 01762 MiscMask, GrSave, State->RegionLen)); 01763 01764 Count = 0; 01765 for (Index = REG_PREDS; Index <= REG_RP; Index++) { 01766 if (MiscMask & 0x1) { 01767 if (!(State->IsTarget) || 01768 (State->MiscMask & MASK(Index,1))) 01769 { 01770 UwContext->MiscRegs[Index].Where = GENERAL_REG; 01771 UwContext->MiscRegs[Index].SaveOffset = GrSave+Count; 01772 UwContext->MiscRegs[Index].When = 0; 01773 State->MiscMask |= MASK(Index,1); 01774 } 01775 Count++; 01776 } 01777 MiscMask = MiscMask >> 1; 01778 } 01779 } 01780 01781 while (DescIndex <= State->DescEnd) { 01782 01783 FirstByte = Desc[DescIndex++]; 01784 01785 if ( (FirstByte & P1_MASK) == P1_PREFIX) { 01786 01787 BrMask = FirstByte & ~P1_MASK; 01788 State->MiscMask |= (BrMask << REG_BR_BASE); 01789 01790 UW_DEBUG(("Prolog P1: brmask=%x\n", BrMask)); 01791 01792 for (Count = REG_BR_BASE; 01793 Count < REG_BR_BASE+NUMBER_OF_PRESERVED_BR; 01794 Count++) 01795 { 01796 if (BrMask & 0x1) { 01797 UwContext->MiscRegs[Count].Where = PSP_RELATIVE; 01798 UwContext->MiscRegs[Count].When = State->RegionLen; 01799 } 01800 BrMask = BrMask >> 1; 01801 } 01802 01803 } else if ( (FirstByte & P2_MASK) == P2_PREFIX ) { 01804 01805 SecondByte = Desc[DescIndex++]; 01806 GrSave = SecondByte & 0x7F; 01807 BrMask = ((FirstByte & ~P2_MASK) << 1) | ((SecondByte & 0x80) >> 7); 01808 UW_DEBUG(("Prolog P2: brmask=%x reg base=%d\n", BrMask, GrSave)); 01809 01810 State->MiscMask |= (BrMask << REG_BR_BASE); 01811 01812 for (Count = REG_BR_BASE; 01813 Count < REG_BR_BASE+NUMBER_OF_PRESERVED_BR; 01814 Count++) 01815 { 01816 if (BrMask & 0x1) { 01817 UwContext->MiscRegs[Count].Where = GENERAL_REG; 01818 UwContext->MiscRegs[Count].SaveOffset = GrSave++; 01819 } 01820 BrMask = BrMask >> 1; 01821 } 01822 01823 } else if ( (FirstByte & P3_MASK) == P3_PREFIX ) { 01824 01825 SecondByte = Desc[DescIndex++]; 01826 RecType = ((SecondByte & 0x80) >> 7) | ((FirstByte & 0x7) << 1); 01827 Index = P3RecordTypeToRegisterIndex[RecType]; 01828 01829 if (!(State->IsTarget) || 01830 (State->MiscMask & MASK(Index,1))) 01831 { 01832 if (RecType == RP_BR) { 01833 UwContext->MiscRegs[Index].Where = BRANCH_REG; 01834 } else { 01835 UwContext->MiscRegs[Index].Where = GENERAL_REG; 01836 } 01837 UwContext->MiscRegs[Index].SaveOffset = SecondByte & 0x7F; 01838 UwContext->MiscRegs[Index].When = 0; 01839 State->MiscMask |= MASK(Index,1); 01840 01841 UW_DEBUG(("Prolog P3: type=%d reg=%d\n", 01842 RecType, UwContext->MiscRegs[Index].SaveOffset)); 01843 } 01844 01845 } else if ( (FirstByte & P4_MASK) == P4_PREFIX ) { 01846 01847 SpillMaskOmitted = FALSE; 01848 ImaskBegin = DescIndex; 01849 DescIndex += ((State->RegionLen+3) >> 2); 01850 01851 } else if ( (FirstByte & P5_MASK) == P5_PREFIX ) { 01852 01853 GrMask = (Desc[DescIndex] & 0xF0) >> 4; 01854 FrMask = ((ULONG)(Desc[DescIndex] & 0xF) << 16) | 01855 ((ULONG)Desc[DescIndex+1] << 8) | 01856 ((ULONG)Desc[DescIndex+2]); 01857 01858 DescIndex += 3; // increment the descriptor index 01859 01860 State->GrMask |= GrMask; 01861 State->FrMask |= FrMask; 01862 01863 UW_DEBUG(("Prolog P5: grmask = %x, frmask = %x\n", 01864 State->GrMask, State->FrMask)); 01865 01866 } else if ( (FirstByte & P6_MASK) == P6_PREFIX ) { 01867 01868 if (FirstByte & 0x10) { 01869 01870 GrMask = FirstByte & 0xF; 01871 State->GrMask |= GrMask; 01872 01873 } else { 01874 01875 FrMask = FirstByte & 0xF; 01876 State->FrMask |= FrMask; 01877 01878 } 01879 01880 UW_DEBUG(("Prolog P6: is_gr = %d, mask = %x\n", 01881 (FirstByte & 0x10) ? 1 : 0, 01882 (FirstByte & 0x10) ? State->GrMask : State->FrMask)); 01883 01884 } else if ( (FirstByte & P7_MASK) == P7_PREFIX ) { 01885 01886 RecType = FirstByte & ~P7_MASK; 01887 01888 switch (RecType) { 01889 01890 case PSP_SPREL: 01891 01892 // 01893 // sp-relative location 01894 // 01895 01896 Index = P7RecordTypeToRegisterIndex[RecType]; 01897 Offset = ReadLEB128(Desc, &DescIndex); 01898 if (!(State->IsTarget) || (State->MiscMask & MASK(Index,1))) 01899 { 01900 UwContext->MiscRegs[Index].Where = SP_RELATIVE; 01901 UwContext->MiscRegs[Index].SaveOffset = Offset; 01902 if (!(State->MiscMask & MASK(Index,1))) { 01903 UwContext->MiscRegs[Index].When = State->RegionLen; 01904 State->MiscMask |= MASK(Index,1); 01905 } 01906 } 01907 UW_DEBUG(("Prolog P7: type=%d spoff = %d\n", RecType, Offset)); 01908 break; 01909 01910 01911 case RP_PSPREL: 01912 case PFS_PSPREL: 01913 case PREDS_PSPREL: 01914 case LC_PSPREL: 01915 case UNAT_PSPREL: 01916 case FPSR_PSPREL: 01917 01918 // 01919 // psp-relative location 01920 // 01921 01922 Index = P7RecordTypeToRegisterIndex[RecType]; 01923 Offset = ReadLEB128(Desc, &DescIndex); 01924 if (!(State->IsTarget) || (State->MiscMask & MASK(Index,1))) 01925 { 01926 UwContext->MiscRegs[Index].Where = PSP_RELATIVE; 01927 UwContext->MiscRegs[Index].SaveOffset = Offset; 01928 UwContext->MiscRegs[Index].When = 0; 01929 State->MiscMask |= MASK(Index,1); 01930 } 01931 UW_DEBUG(("Prolog P7: type=%d pspoff= %d\n", RecType, Offset)); 01932 break; 01933 01934 case MEM_STACK_V: 01935 case RP_WHEN: 01936 case PFS_WHEN: 01937 case PREDS_WHEN: 01938 case LC_WHEN: 01939 case UNAT_WHEN: 01940 case FPSR_WHEN: 01941 01942 // 01943 // Nevermind processing these descriptors because they 01944 // have been taken care of in phase 0 01945 // 01946 01947 Offset = ReadLEB128(Desc, &DescIndex); 01948 break; 01949 01950 case MEM_STACK_F: 01951 01952 Offset = ReadLEB128(Desc, &DescIndex); 01953 FrameSize = ReadLEB128(Desc, &DescIndex); 01954 01955 UW_DEBUG(("Prolog P7: type=%d Slot=%d FrameSize=%d\n", 01956 RecType, Offset, FrameSize)); 01957 break; 01958 01959 case SPILL_BASE: 01960 01961 State->SpillBase = ReadLEB128(Desc, &DescIndex); 01962 State->SpillPtr = State->SpillBase; 01963 UW_DEBUG(("Prolog P7: type=%d, spillbase=%d\n", 01964 RecType, State->SpillBase)); 01965 break; 01966 01967 default: 01968 01969 UW_DEBUG(("invalid unwind descriptors\n")); 01970 01971 } 01972 01973 } else if ( (FirstByte & P8_MASK) == P8_PREFIX ) { 01974 01975 RecType = Desc[DescIndex++]; 01976 01977 switch (RecType) { 01978 01979 case PSP_PSPREL: 01980 VUW_DEBUG_PRINT("Unsupported Unwind Descriptor!\n"); 01981 break; 01982 01983 case RP_SPREL: 01984 case PFS_SPREL: 01985 case PREDS_SPREL: 01986 case LC_SPREL: 01987 case UNAT_SPREL: 01988 case FPSR_SPREL: 01989 case BSP_SPREL: 01990 case BSPSTORE_SPREL: 01991 case RNAT_SPREL: 01992 case PRIUNAT_SPREL: 01993 01994 // 01995 // sp-relative location 01996 // 01997 01998 Index = P8RecordTypeToRegisterIndex[RecType]; 01999 Offset = ReadLEB128(Desc, &DescIndex); 02000 if (!(State->IsTarget) || (State->MiscMask & MASK(Index,1))) 02001 { 02002 UwContext->MiscRegs[Index].Where = SP_RELATIVE; 02003 UwContext->MiscRegs[Index].SaveOffset = Offset; 02004 if (!(State->MiscMask & MASK(Index,1))) { 02005 UwContext->MiscRegs[Index].When=State->RegionLen; 02006 State->MiscMask |= MASK(Index,1); 02007 } 02008 } 02009 UW_DEBUG(("Prolog P8: type=%d spoff= %d\n", RecType, Offset)); 02010 break; 02011 02012 case BSP_PSPREL: 02013 case BSPSTORE_PSPREL: 02014 case RNAT_PSPREL: 02015 case PRIUNAT_PSPREL: 02016 02017 // 02018 // psp-relative location 02019 // 02020 02021 Index = P8RecordTypeToRegisterIndex[RecType]; 02022 Offset = ReadLEB128(Desc, &DescIndex); 02023 if (!(State->IsTarget) || (State->MiscMask & MASK(Index,1))) 02024 { 02025 UwContext->MiscRegs[Index].Where = PSP_RELATIVE; 02026 UwContext->MiscRegs[Index].SaveOffset = Offset; 02027 UwContext->MiscRegs[Index].When = 0; 02028 State->MiscMask |= MASK(Index,1); 02029 } 02030 UW_DEBUG(("Prolog P8: type=%d pspoff= %d\n", RecType, Offset)); 02031 break; 02032 02033 case BSP_WHEN: 02034 case BSPSTORE_WHEN: 02035 case RNAT_WHEN: 02036 case PRIUNAT_WHEN: 02037 02038 // 02039 // Nevermind processing these descriptors because they 02040 // have been taken care of in phase 0 02041 // 02042 02043 Offset = ReadLEB128(Desc, &DescIndex); 02044 break; 02045 02046 default: 02047 02048 UW_DEBUG(("Invalid record type for descriptor P8!\n")); 02049 02050 } 02051 02052 } else if ( (FirstByte & P9_MASK) == P9_PREFIX ) { 02053 02054 DescIndex += 2; 02055 VUW_DEBUG_PRINT("Format P9 not supported yet!\n"); 02056 02057 } else if ( (FirstByte & P10_MASK) == P10_PREFIX ) { 02058 02059 UCHAR Abi = Desc[DescIndex++]; 02060 UCHAR Context = Desc[DescIndex++]; 02061 02062 } else { 02063 02064 UW_DEBUG(("Invalid descriptor!\n")); 02065 02066 } 02067 } 02068 02069 GrMask = State->GrMask; 02070 FrMask = State->FrMask; 02071 BrMask = State->MiscMask >> REG_BR_BASE; 02072 02073 if (!(GrMask | FrMask | BrMask)) { 02074 02075 return; 02076 02077 } else if (SpillMaskOmitted && !(State->IsTarget)) { 02078 02079 // 02080 // When spillmask is omitted, floating point registers, general 02081 // registers, and then branch regisers are spilled in order. 02082 // They are not modified in the prologue region; therefore, there 02083 // is no need to restore their contents when the control ip is 02084 // in this prologue region. 02085 // 02086 02087 // 1. floating point registers 02088 02089 State->SpillPtr &= ~(SPILLSIZE_OF_FLOAT128_IN_DWORDS - 1); 02090 NextFr = NUMBER_OF_PRESERVED_FR - 1; 02091 while (FrMask & 0xFFFFF) { 02092 if (FrMask & 0x80000) { 02093 State->SpillPtr += SPILLSIZE_OF_FLOAT128_IN_DWORDS; 02094 UwContext->Float[NextFr].SaveOffset = State->SpillPtr; 02095 } 02096 FrMask = FrMask << 1; 02097 NextFr--; 02098 } 02099 02100 // 2. branch registers 02101 02102 NextBr = REG_BR_BASE + NUMBER_OF_PRESERVED_BR - 1; 02103 while (BrMask & 0x1F) { 02104 if (BrMask & 0x10) { 02105 if (UwContext->MiscRegs[Index].Where == PSP_RELATIVE) { 02106 State->SpillPtr += SPILLSIZE_OF_ULONGLONG_IN_DWORDS; 02107 UwContext->MiscRegs[NextBr].SaveOffset = State->SpillPtr; 02108 } 02109 } 02110 BrMask = BrMask << 1; 02111 NextBr--; 02112 } 02113 02114 // 3. general registers 02115 02116 NextGr = NUMBER_OF_PRESERVED_GR - 1; 02117 while (GrMask & 0xF) { 02118 if (GrMask & 0x8) { 02119 State->SpillPtr += SPILLSIZE_OF_ULONGLONG_IN_DWORDS; 02120 UwContext->Integer[NextGr].SaveOffset = State->SpillPtr; 02121 } 02122 GrMask = GrMask << 1; 02123 NextGr--; 02124 } 02125 02126 } else if (SpillMaskOmitted && State->IsTarget) { 02127 02128 State->GrMask = 0; 02129 State->FrMask = 0; 02130 State->MiscMask &= MASK(REG_BR_BASE, 1) - 1; 02131 02132 } else if (SpillMaskOmitted == FALSE) { 02133 02134 ULONG Length; 02135 02136 if (State->IsTarget) { 02137 02138 // 02139 // control ip is in the prologue region; clear the masks 02140 // and then process the imask to determine which preserved 02141 // Gr/Fr/Br have been saved and set the corresponding bits. 02142 // 02143 02144 State->GrMask = 0; 02145 State->FrMask = 0; 02146 State->MiscMask &= MASK(REG_BR_BASE, 1) - 1; 02147 Length = UwContext->TargetSlot - State->RegionBegin; 02148 } else { 02149 Length = State->RegionLen; 02150 } 02151 02152 NextGr = NUMBER_OF_PRESERVED_GR - 1; 02153 NextBr = NUMBER_OF_PRESERVED_BR - 1; 02154 NextFr = NUMBER_OF_PRESERVED_FR - 1; 02155 for (Count = 0; Count < Length; Count++) { 02156 02157 if ((Count % 4) == 0) { 02158 FirstByte = Desc[ImaskBegin++]; 02159 } else { 02160 FirstByte = FirstByte << 2; 02161 } 02162 02163 switch (FirstByte & 0xC0) { 02164 02165 case 0x40: // 0x01 - save next fr 02166 02167 while ( !(FrMask & 0x80000) && (NextFr > 0) ) { 02168 NextFr--; 02169 FrMask = FrMask << 1; 02170 } 02171 02172 UW_DEBUG(("spilled register FS%lx\n", (ULONG)NextFr)); 02173 02174 State->FrMask |= MASK(NextFr,1); 02175 UwContext->Float[NextFr].When = Count; 02176 State->SpillPtr += SPILLSIZE_OF_ULONGLONG_IN_DWORDS; 02177 State->SpillPtr &= ~(SPILLSIZE_OF_FLOAT128_IN_DWORDS - 1); 02178 State->SpillPtr += SPILLSIZE_OF_FLOAT128_IN_DWORDS; 02179 UwContext->Float[NextFr].SaveOffset = State->SpillPtr; 02180 02181 NextFr--; 02182 FrMask = FrMask << 1; 02183 break; 02184 02185 case 0x80: // 0x10 - save next gr 02186 02187 while ( !(GrMask & 0x8) && (NextGr > 0) ) { 02188 NextGr--; 02189 GrMask = GrMask << 1; 02190 } 02191 02192 UW_DEBUG(("spilled register S%lx\n", (ULONG)NextGr)); 02193 02194 State->GrMask |= MASK(NextGr,1); 02195 UwContext->Integer[NextGr].When = Count; 02196 State->SpillPtr += SPILLSIZE_OF_ULONGLONG_IN_DWORDS; 02197 UwContext->Integer[NextGr].SaveOffset = State->SpillPtr; 02198 02199 NextGr--; 02200 GrMask = GrMask << 1; 02201 break; 02202 02203 case 0xC0: // 0x11 - save next br 02204 02205 while ( !(BrMask & 0x10) && (NextBr > 0) ) { 02206 NextBr--; 02207 BrMask = BrMask << 1; 02208 } 02209 02210 UW_DEBUG(("spilled register BS%lx\n", (ULONG)NextBr)); 02211 02212 Index = REG_BR_BASE + NextBr; 02213 State->MiscMask |= MASK(Index,1); 02214 UwContext->MiscRegs[Index].When = Count; 02215 if (UwContext->MiscRegs[Index].Where == PSP_RELATIVE) { 02216 State->SpillPtr += SPILLSIZE_OF_ULONGLONG_IN_DWORDS; 02217 UwContext->MiscRegs[Index].SaveOffset = State->SpillPtr; 02218 } 02219 02220 NextBr--; 02221 BrMask = BrMask << 1; 02222 break; 02223 02224 default: // 0x00 - save no register 02225 break; 02226 02227 } 02228 } 02229 } 02230 }

UCHAR ParseBodyRegionDescriptors IN PUNWIND_CONTEXT  UnwindContext,
IN PSTATE_RECORD_STACK  StateTable,
IN ULONG  RegionLen
 

Definition at line 534 of file ia64/vunwind.c.

References B1_LABEL_MASK, B1_MASK, B1_PREFIX, B1_TYPE_MASK, B2_ECOUNT_MASK, B2_MASK, B2_PREFIX, B3_MASK, B3_PREFIX, B4_MASK, B4_PREFIX, B4_TYPE_MASK, CHECK_LABEL, _STATE_RECORD::Ecount, FALSE, LABEL, LABEL_REGION, _STATE_RECORD::Previous, PSTATE_RECORD, ReadLEB128(), _STATE_RECORD::SpAdjustment, _STATE_RECORD::SpWhen, TRUE, and UW_DEBUG.

Referenced by RtlVirtualUnwind().

00539 { 00540 LABEL Label; 00541 UCHAR FirstByte; 00542 BOOLEAN EcountDefined; 00543 BOOLEAN CopyLabel; 00544 ULONG Ecount; 00545 ULONG SlotOffset; 00546 PSTATE_RECORD StateTablePtr; 00547 PUCHAR Descriptors; 00548 00549 CopyLabel = EcountDefined = FALSE; 00550 Descriptors = UnwindContext->Descriptors; 00551 00552 while (UnwindContext->DescCount < UnwindContext->Size) { 00553 00554 FirstByte = Descriptors[UnwindContext->DescCount++]; 00555 00556 if ( (FirstByte & B1_MASK) == B1_PREFIX ) { 00557 00558 Label = (LABEL)(FirstByte & B1_LABEL_MASK); 00559 if (FirstByte & B1_TYPE_MASK) { 00560 00561 // 00562 // copy the entry state 00563 // 00564 00565 CopyLabel = TRUE; 00566 00567 } else { 00568 00569 // 00570 // label the entry state 00571 // 00572 00573 LABEL_REGION(StateTable->Top, Label); 00574 } 00575 00576 UW_DEBUG(("Body region desc B1: copy=%d, label_num=%d\n", 00577 FirstByte & B1_TYPE_MASK ? TRUE : FALSE, Label)); 00578 00579 } else if ( (FirstByte & B2_MASK) == B2_PREFIX ) { 00580 00581 Ecount = FirstByte & B2_ECOUNT_MASK; 00582 SlotOffset = ReadLEB128(Descriptors, &UnwindContext->DescCount); 00583 EcountDefined = TRUE; 00584 00585 UW_DEBUG(("Epilog desc B2: ecount=%d, LEB128(slot)=%d\n", 00586 Ecount, SlotOffset)); 00587 00588 } else if ( (FirstByte & B3_MASK) == B3_PREFIX ) { 00589 00590 SlotOffset = ReadLEB128(Descriptors, &UnwindContext->DescCount); 00591 Ecount = ReadLEB128(Descriptors, &UnwindContext->DescCount); 00592 EcountDefined = TRUE; 00593 00594 UW_DEBUG(("Epilog desc B3: ecount=%d, LEB128 val=%d\n", 00595 Ecount, SlotOffset)); 00596 00597 } else if ( (FirstByte & B4_MASK) == B4_PREFIX ) { 00598 00599 Label = ReadLEB128(Descriptors, &UnwindContext->DescCount); 00600 00601 if (FirstByte & B4_TYPE_MASK) { 00602 00603 // 00604 // copy the entry state 00605 // 00606 00607 CopyLabel = TRUE; 00608 00609 } else { 00610 00611 // 00612 // label the current top of stack 00613 // 00614 00615 LABEL_REGION(StateTable->Top, Label); 00616 } 00617 00618 UW_DEBUG(("Body region desc B4: copy=%d, label_num=%d\n", 00619 FirstByte & B4_TYPE_MASK, Label)); 00620 00621 } else { 00622 00623 // 00624 // Encounter another region header record 00625 // 00626 00627 break; 00628 } 00629 } 00630 00631 if (CopyLabel) { 00632 StateTablePtr = StateTable->Top; 00633 while (TRUE) { 00634 if (CHECK_LABEL(StateTablePtr, Label)) { 00635 StateTable->Current = StateTablePtr; 00636 break; 00637 } else if ((StateTablePtr == StateTable->Base)) { 00638 UW_DEBUG(("Undefined Label %d\n", Label)); 00639 break; 00640 } 00641 StateTablePtr--; 00642 } 00643 } 00644 00645 if (EcountDefined) { 00646 00647 Ecount++; // Ecount specifies additional level of prologue 00648 // regions to undo (i.e. a value of 0 implies 1 00649 // prologue region) 00650 00651 if (UnwindContext->ActiveRegionFound == FALSE) { 00652 while (Ecount-- > 0) { 00653 if (StateTable->Current->Previous) { 00654 StateTable->Current = StateTable->Current->Previous; 00655 } 00656 00657 #if DBG 00658 else { 00659 UW_DEBUG(("WARNING: Ecount is greater than the # of active prologues!\n")); 00660 } 00661 #endif // DBG 00662 00663 } 00664 } else { 00665 00666 // 00667 // control PC is in this body/epilog region 00668 // 00669 00670 if ((UnwindContext->SlotCount + RegionLen - SlotOffset) 00671 <= UnwindContext->TargetSlot) 00672 { 00673 PSTATE_RECORD SrPointer; 00674 00675 StateTable->Current->Ecount = Ecount; 00676 SrPointer = StateTable->Current; 00677 while (Ecount > 0) { 00678 00679 if (SrPointer->Previous) { 00680 SrPointer->Ecount = Ecount; 00681 SrPointer->SpWhen = 0; 00682 SrPointer->SpAdjustment = 0; 00683 SrPointer = SrPointer->Previous; 00684 } 00685 00686 #if DBG 00687 else { 00688 UW_DEBUG(("WARNING: Ecount is greater than the # of active prologues!\n")); 00689 } 00690 #endif // DBG 00691 Ecount--; 00692 00693 } 00694 } 00695 } 00696 } 00697 00698 return FirstByte; 00699 }

ULONGLONG ProcessInterruptRegion IN PKNONVOLATILE_CONTEXT_POINTERS  ContextPointers,
IN PUNWIND_CONTEXT  UnwindContext,
IN PCONTEXT  Context,
IN SHORT  BsFrameSize,
IN SHORT  RNatSaveIndex,
IN UCHAR  AbiImmContext
 

Definition at line 703 of file ia64/vunwind.c.

References Index, NUMBER_OF_HIGH_PRESERVED_FR, NUMBER_OF_LOW_PRESERVED_FR, NUMBER_OF_PRESERVED_BR, NUMBER_OF_PRESERVED_GR, SHORT, and Size.

Referenced by RtlVirtualUnwind().

00716 { 00717 // 00718 // no prologue descriptor in interrupt region. 00719 // 00720 00721 PCONTEXT PrevContext; 00722 ULONGLONG NextPc; 00723 ULONG Index; 00724 SHORT TempFrameSize; 00725 BOOLEAN Success; 00726 #ifdef _IMAGEHLP_SOURCE_ 00727 ULONG Size; 00728 #else 00729 PVOID *Source; 00730 PVOID Address; 00731 #endif _IMAGEHLP_SOURCE_ 00732 00733 00734 if (AbiImmContext != CONTEXT_FRAME) { 00735 00736 PKTRAP_FRAME TrapFrame; 00737 PKEXCEPTION_FRAME ExFrame; 00738 #ifdef _IMAGEHLP_SOURCE_ 00739 KTRAP_FRAME TF; 00740 KEXCEPTION_FRAME ExF; 00741 #endif // _IMAGEHLP_SOURCE_ 00742 00743 TrapFrame = (PKTRAP_FRAME) Context->IntSp; 00744 #ifdef _IMAGEHLP_SOURCE_ 00745 if (!ReadMemory(hProcess, Context->IntSp, &TF, sizeof(KTRAP_FRAME), &Size)) 00746 { 00747 return 0; 00748 } 00749 TrapFrame = &TF; 00750 #endif // _IMAGEHLP_SOURCE_ 00751 00752 Context->ApDCR = TrapFrame->ApDCR; 00753 Context->ApUNAT = TrapFrame->ApUNAT; 00754 Context->StFPSR = TrapFrame->StFPSR; 00755 Context->Preds = TrapFrame->Preds; 00756 Context->IntSp = TrapFrame->IntSp; 00757 Context->StIPSR = TrapFrame->StIPSR; 00758 Context->StIFS = TrapFrame->StIFS; 00759 Context->BrRp = TrapFrame->BrRp; 00760 Context->RsPFS = TrapFrame->RsPFS; 00761 00762 #ifndef _IMAGEHLP_SOURCE_ 00763 if (ARGUMENT_PRESENT(ContextPointers)) { 00764 ContextPointers->ApUNAT = &TrapFrame->ApUNAT; 00765 ContextPointers->IntSp = &TrapFrame->IntSp; 00766 ContextPointers->BrRp = &TrapFrame->BrRp; 00767 ContextPointers->RsPFS = &TrapFrame->RsPFS; 00768 ContextPointers->Preds = &TrapFrame->Preds; 00769 } 00770 #endif // _IMAGEHLP_SOURCE_ 00771 00772 switch (AbiImmContext) { 00773 00774 case SYSCALL_FRAME: 00775 00776 // 00777 // System Call Handler Frame 00778 // 00779 00780 BsFrameSize = (SHORT)(TrapFrame->StIFS >> PFS_SIZE_SHIFT); 00781 BsFrameSize &= PFS_SIZE_MASK; 00782 break; 00783 00784 case INTERRUPT_FRAME: 00785 case EXCEPTION_FRAME: 00786 00787 // 00788 // External Interrupt Frame / Exception Frame 00789 // 00790 00791 BsFrameSize = (SHORT)TrapFrame->StIFS & PFS_SIZE_MASK; 00792 break; 00793 00794 default: 00795 00796 break; 00797 } 00798 00799 RNatSaveIndex = (SHORT)(TrapFrame->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG; 00800 TempFrameSize = BsFrameSize - RNatSaveIndex; 00801 while (TempFrameSize > 0) { 00802 BsFrameSize++; 00803 TempFrameSize -= NAT_BITS_PER_RNAT_REG; 00804 } 00805 00806 Context->RsBSP = TrapFrame->RsBSP - BsFrameSize * sizeof(ULONGLONG); 00807 Context->RsBSPSTORE = Context->RsBSP; 00808 Context->RsRNAT = TrapFrame->RsRNAT; 00809 00810 NextPc = RtlIa64InsertIPSlotNumber(TrapFrame->StIIP, 00811 ((TrapFrame->StIPSR >> PSR_RI) & 0x3)); 00812 00813 return (NextPc); 00814 } 00815 00816 // 00817 // Kernel-to-User thunk, context of the previous frame can be 00818 // found on the user stack (i.e. context's address = sp+SCRATCH_AREA) 00819 // 00820 00821 PrevContext = (PCONTEXT)(Context->IntSp + STACK_SCRATCH_AREA); 00822 #ifdef _IMAGEHLP_SOURCE_ 00823 if (!ReadMemory(hProcess, (DWORD64)PrevContext, Context, sizeof(CONTEXT), &Size)) 00824 { 00825 return 0; 00826 } 00827 NextPc = RtlIa64InsertIPSlotNumber(Context->StIIP, 00828 ((Context->StIPSR >> PSR_RI) & 0x3)); 00829 #else 00830 00831 RtlCopyMemory(&Context->BrRp, &PrevContext->BrRp, 00832 (NUMBER_OF_PRESERVED_BR+1) * sizeof(ULONGLONG)); 00833 RtlCopyMemory(&Context->FltS0, &PrevContext->FltS0, 00834 NUMBER_OF_LOW_PRESERVED_FR * sizeof(FLOAT128)); 00835 RtlCopyMemory(&Context->FltS4, &PrevContext->FltS4, 00836 NUMBER_OF_HIGH_PRESERVED_FR * sizeof(FLOAT128)); 00837 RtlCopyMemory(&Context->IntS0, &PrevContext->IntS0, 00838 NUMBER_OF_PRESERVED_GR * sizeof(ULONGLONG)); 00839 00840 Context->IntSp = PrevContext->IntSp; 00841 Context->IntNats = PrevContext->IntNats; 00842 Context->ApUNAT = PrevContext->ApUNAT; 00843 Context->ApLC = PrevContext->ApLC; 00844 Context->ApEC = PrevContext->ApEC; 00845 Context->Preds = PrevContext->Preds; 00846 Context->RsPFS = PrevContext->RsPFS; 00847 Context->RsBSP = PrevContext->RsBSP; 00848 Context->RsBSPSTORE = PrevContext->RsBSPSTORE; 00849 Context->RsRSC = PrevContext->RsRSC; 00850 Context->RsRNAT = PrevContext->RsRNAT; 00851 Context->StIFS = PrevContext->StIFS; 00852 Context->StIPSR = PrevContext->StIPSR; 00853 NextPc = RtlIa64InsertIPSlotNumber(PrevContext->StIIP, 00854 ((PrevContext->StIPSR >> PSR_RI) & 0x3)); 00855 00856 #endif // _IMAGEHLP_SOURCE_ 00857 00858 return(NextPc); 00859 }

ULONG ReadLEB128 IN PUCHAR  Descriptors,
IN OUT PULONG  CurrentDescIndex
 

Definition at line 412 of file ia64/vunwind.c.

References Buffer, Count, and TRUE.

Referenced by NewParsePrologueRegionPhase0(), NewParsePrologueRegionPhase1(), ParseBodyRegionDescriptors(), and RtlVirtualUnwind().

00416 { 00417 PUCHAR Buffer; 00418 ULONG Value; 00419 ULONG ShiftCount = 7; 00420 ULONG Count; 00421 00422 Buffer = Descriptors + *CurrentDescIndex; 00423 Count = 1; 00424 00425 Value = Buffer[0] & 0x7F; 00426 if (Buffer[0] & 0x80) { 00427 while (TRUE) { 00428 Value += ((Buffer[Count] & 0x7F) << ShiftCount); 00429 if (Buffer[Count++] & 0x80) { 00430 ShiftCount += 7; 00431 } else { 00432 break; 00433 } 00434 } 00435 } 00436 00437 *CurrentDescIndex += Count; 00438 00439 return Value; 00440 }

ULONGLONG RestorePreservedRegisterFromGR IN PCONTEXT  Context,
IN SHORT  BsFrameSize,
IN SHORT  RNatSaveIndex,
IN SHORT  GrNumber,
OUT ULONG64 *  SourceAddress,
OUT PUCHAR Nat  OPTIONAL
 

Definition at line 444 of file ia64/vunwind.c.

References FALSE, NOT_IMAGEHLP, Offset, SHORT, Size, STATIC_REGISTER_SET_SIZE, TRUE, and UW_DEBUG.

Referenced by RtlVirtualUnwind().

00458 { 00459 ULONGLONG Result; 00460 SHORT Offset; 00461 SHORT Temp; 00462 #ifdef _IMAGEHLP_SOURCE_ 00463 ULONG Size; 00464 #endif // _IMAGEHLP_SOURCE_ 00465 00466 #ifdef _IMAGEHLP_SOURCE_ 00467 *Succeed = FALSE; 00468 #endif // _IMAGEHLP_SOURCE_ 00469 00470 if (GrNumber >= STATIC_REGISTER_SET_SIZE) { 00471 00472 Offset = GrNumber - STATIC_REGISTER_SET_SIZE; 00473 if ( Offset < BsFrameSize ) { 00474 00475 Temp = Offset + RNatSaveIndex - NAT_BITS_PER_RNAT_REG; 00476 while (Temp >= 0) { 00477 Offset++; 00478 Temp -= NAT_BITS_PER_RNAT_REG; 00479 } 00480 Offset = Offset * sizeof(ULONGLONG); 00481 00482 #ifdef _IMAGEHLP_SOURCE_ 00483 *Succeed = ReadMemory(hProcess, Context->RsBSP + Offset, 00484 &Result, sizeof(ULONGLONG), &Size); 00485 #else 00486 *SourceAddress = (ULONG64)(Context->RsBSP + Offset); 00487 Result = *(PULONGLONG)(Context->RsBSP + Offset); 00488 #endif // _IMAGEHLP_SOURCE_ 00489 00490 } else { 00491 00492 UW_DEBUG(("ERROR: Invalid GR!\n")); 00493 } 00494 00495 } else { 00496 00497 if (GrNumber == 0 || GrNumber == 12) { 00498 00499 // 00500 // Invalid GR number -> Invalid Unwind Descriptor 00501 // 00502 00503 UW_DEBUG(("ERROR: Invalid GR!\n")); 00504 00505 } else { 00506 00507 UW_DEBUG(("WARNING: Target register is not a stacked GR!\n")); 00508 Offset = GrNumber - 1; 00509 NOT_IMAGEHLP(*SourceAddress = (ULONG64)(&Context->IntGp + Offset)); 00510 Result = *(&Context->IntGp + Offset); 00511 00512 #ifdef _IMAGEHLP_SOURCE_ 00513 *Succeed = TRUE; 00514 #endif // _IMAGEHLP_SOURCE_ 00515 00516 } 00517 } 00518 00519 if (ARGUMENT_PRESENT(Nat)) { 00520 00521 // 00522 // TBD: Pick up the corresponding Nat bit 00523 // 00524 00525 *Nat = (UCHAR) 0; 00526 00527 } 00528 00529 return (Result); 00530 }

ULONGLONG RtlVirtualUnwind IN ULONGLONG  ImageBase,
IN ULONGLONG  ControlPc,
IN PRUNTIME_FUNCTION  FunctionEntry,
IN OUT PCONTEXT  ContextRecord,
OUT PBOOLEAN  InFunction,
OUT PFRAME_POINTERS  EstablisherFrame,
IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers  OPTIONAL
 

Definition at line 863 of file ia64/vunwind.c.

References _UNWIND_CONTEXT::ActiveRegionFound, ADD_STATE_RECORD, _STATE_RECORD_STACK::Base, BOOL, BRANCH_REG, Buffer, _STATE_RECORD_STACK::Current, _UNWIND_CONTEXT::DescCount, _UNWIND_CONTEXT::Descriptors, _STATE_RECORD::Ecount, EXTRACT_NAT_FROM_UNAT, FALSE, FIRST_PRESERVED_BR, FIRST_PRESERVED_GR, _UNWIND_CONTEXT::Float, _STATE_RECORD::FrMask, GENERAL_REG, _STATE_RECORD::GrMask, _UNWIND_CONTEXT::Integer, _STATE_RECORD::IsTarget, MASK, MemAlloc(), MemFree(), MiscContextOffset, MiscContextPointersOffset, _STATE_RECORD::MiscMask, _UNWIND_CONTEXT::MiscRegs, NewParsePrologueRegionPhase0(), NewParsePrologueRegionPhase1(), NOT_IMAGEHLP, NULL, NUMBER_OF_LOW_PRESERVED_FR, NUMBER_OF_PRESERVED_FR, NUMBER_OF_PRESERVED_GR, NUMBER_OF_PRESERVED_REGISTERS, Offset, ParseBodyRegionDescriptors(), _STATE_RECORD::Previous, ProcessInterruptRegion(), PSP_RELATIVE, PSTATE_RECORD, R1_LENGTH_MASK, R1_MASK, R1_PREFIX, R1_REGION_TYPE_MASK, R2_MASK, R2_PREFIX, R3_MASK, R3_PREFIX, R3_REGION_TYPE_MASK, ReadLEB128(), REG_NATS, REG_SP, RestorePreservedRegisterFromGR(), _REGISTER_RECORD::SaveOffset, SHORT, _UNWIND_CONTEXT::Size, Size, _UNWIND_CONTEXT::SlotCount, SLOTS_PER_BUNDLE, SP_RELATIVE, _STATE_RECORD::SpAdjustment, _STATE_RECORD::SpWhen, SrInitialize(), STACK_POINTER_GR, STATE_RECORD_STACK_SIZE, _UNWIND_CONTEXT::TargetSlot, TRUE, USHORT, UW_DEBUG, _UNWIND_CONTEXT::Version, _REGISTER_RECORD::When, and _REGISTER_RECORD::Where.

00885 : 00886 00887 This function virtually unwinds the specfified function by executing its 00888 prologue code backwards. 00889 00890 If the function is a leaf function, then the address where control left 00891 the previous frame is obtained from the context record. If the function 00892 is a nested function, but not an exception or interrupt frame, then the 00893 prologue code is executed backwards and the address where control left 00894 the previous frame is obtained from the updated context record. 00895 00896 Otherwise, an exception or interrupt entry to the system is being unwound 00897 and an especially coded prologue restores the return address twice. Once 00898 from the fault instruction address and once from the saved return address 00899 register. The first restore is returned as the function value and the 00900 second restore is placed in the updated context record. 00901 00902 If a context pointers record is specified, then the address where each 00903 nonvolatile registers is restored from is recorded in the appropriate 00904 element of the context pointers record. 00905 00906 Arguments: 00907 00908 ImageBase - Supplies the base address of the module to which the 00909 function belongs. 00910 00911 ControlPc - Supplies the address where control left the specified 00912 function. 00913 00914 FunctionEntry - Supplies the address of the function table entry for the 00915 specified function. 00916 00917 ContextRecord - Supplies the address of a context record. 00918 00919 InFunction - Supplies a pointer to a variable that receives whether the 00920 control PC is within the current function. 00921 00922 EstablisherFrame - Supplies a pointer to a variable that receives the 00923 the establisher frame pointer value. 00924 00925 ContextPointers - Supplies an optional pointer to a context pointers 00926 record. 00927 00928 Return Value: 00929 00930 The address where control left the previous frame is returned as the 00931 function value. 00932 00933 --*/ 00934 00935 { 00936 #ifdef _IMAGEHLP_SOURCE_ 00937 BOOL Succeed; 00938 #endif // _IMAGEHLP_SOURCE_ 00939 PUCHAR Descriptors = NULL; 00940 UCHAR AbiImmContext = 0xFF; 00941 ULONG Mask; 00942 ULONGLONG NextPc; 00943 ULONG RegionLen; 00944 UCHAR FirstByte; 00945 UCHAR Nat; 00946 SHORT BsFrameSize; // in 8-byte units 00947 SHORT LocalFrameSize; // in 8-byte units 00948 SHORT TempFrameSize; // in 8-byte units 00949 SHORT RNatSaveIndex; 00950 ULONG i; 00951 PULONG Buffer; 00952 BOOLEAN IsPrologueRegion; 00953 BOOLEAN PspRestored; 00954 ULONGLONG PreviousIntSp; 00955 PVOID Destination; 00956 ULONG64 Source; 00957 ULONG64 *CtxPtr; 00958 ULONG64 *NatCtxPtr; 00959 ULONG64 IntNatsSource; 00960 ULONG64 IntNats; 00961 ULONG Size; 00962 ULONGLONG OldTopRnat; 00963 ULONGLONG NewTopRnat; 00964 UNWIND_INFO UnwindInfo; 00965 ULONG64 UnwindInfoPtr; 00966 UNWIND_CONTEXT UnwindContext; 00967 PSTATE_RECORD SrPointer; 00968 STATE_RECORD_STACK StateTable; 00969 STATE_RECORD StateRecords[STATE_RECORD_STACK_SIZE]; 00970 00971 00972 BsFrameSize = (SHORT)ContextRecord->StIFS & PFS_SIZE_MASK; 00973 RNatSaveIndex = (SHORT)(ContextRecord->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG; 00974 TempFrameSize = RNatSaveIndex + BsFrameSize - NAT_BITS_PER_RNAT_REG; 00975 while (TempFrameSize >= 0) { 00976 BsFrameSize++; 00977 TempFrameSize -= NAT_BITS_PER_RNAT_REG; 00978 } 00979 00980 UnwindInfoPtr = ImageBase + FunctionEntry->UnwindInfoAddress; 00981 #ifdef _IMAGEHLP_SOURCE_ 00982 if (!ReadMemory( hProcess, (ULONG64)UnwindInfoPtr, 00983 &UnwindInfo, sizeof(UNWIND_INFO), &Size)) 00984 { 00985 return 0; 00986 } 00987 00988 UnwindContext.Version = UnwindInfo.Version; 00989 Size = UnwindInfo.DataLength * sizeof(ULONGLONG); 00990 if (Size) { 00991 Descriptors = (PUCHAR) MemAlloc (Size); 00992 if (!ReadMemory(hProcess,(ULONG64)(UnwindInfoPtr+sizeof(UNWIND_INFO)), Descriptors, Size, &Size)) { 00993 return 0; 00994 } 00995 } 00996 #else 00997 UnwindContext.Version = ((PUNWIND_INFO)UnwindInfoPtr)->Version; 00998 Size = ((PUNWIND_INFO)UnwindInfoPtr)->DataLength * sizeof(ULONGLONG); 00999 Descriptors = (PUCHAR)UnwindInfoPtr + sizeof(UNWIND_INFO); 01000 #endif // _IMAGEHLP_SOURCE_ 01001 01002 UnwindContext.Size = Size; 01003 UnwindContext.ActiveRegionFound = FALSE; 01004 UnwindContext.DescCount = 0; 01005 UnwindContext.SlotCount = 0; 01006 UnwindContext.TargetSlot = (ULONG)(((ControlPc - FunctionEntry->BeginAddress - ImageBase) >> 4) * SLOTS_PER_BUNDLE + ((ControlPc >> 2) & 0x3)); 01007 UnwindContext.Descriptors = Descriptors; 01008 01009 SrInitialize(&StateTable, StateRecords, STATE_RECORD_STACK_SIZE); 01010 01011 if (Size) { 01012 FirstByte = Descriptors[UnwindContext.DescCount++]; 01013 } 01014 01015 01016 while ( (UnwindContext.DescCount < UnwindContext.Size) && 01017 (!UnwindContext.ActiveRegionFound) ) 01018 { 01019 01020 // 01021 // Assume a prologue region but not an interrupt region. 01022 // 01023 01024 IsPrologueRegion = TRUE; 01025 01026 // 01027 // Based on the type of region header, dispatch 01028 // to the corresponding routine that processes 01029 // the succeeding descriptors until the next 01030 // region header record. 01031 // 01032 01033 if ((FirstByte & R1_MASK) == R1_PREFIX) { 01034 01035 // 01036 // region header record in short format 01037 // 01038 01039 RegionLen = FirstByte & R1_LENGTH_MASK; 01040 01041 if (FirstByte & R1_REGION_TYPE_MASK) { 01042 IsPrologueRegion = FALSE; 01043 } else { 01044 ADD_STATE_RECORD(StateTable, RegionLen, UnwindContext.DescCount); 01045 } 01046 01047 UW_DEBUG(("Region R1 format: body=%x, length=%d\n", 01048 IsPrologueRegion ? 0 : 1, RegionLen)); 01049 01050 } else if ((FirstByte & R2_MASK) == R2_PREFIX) { 01051 01052 // 01053 // general prologue region header 01054 // N.B. Skip the 2nd byte of the header and proceed to read 01055 // the region length; the header descriptors will be 01056 // processed again in phase 1. 01057 // 01058 01059 ULONG R2DescIndex; 01060 01061 R2DescIndex = UnwindContext.DescCount - 1; 01062 UnwindContext.DescCount++; 01063 RegionLen = ReadLEB128(Descriptors, &UnwindContext.DescCount); 01064 ADD_STATE_RECORD(StateTable, RegionLen, R2DescIndex); 01065 UW_DEBUG(("Region R2: body=0, length=%d\n", RegionLen)); 01066 01067 } else if ((FirstByte & R3_MASK) == R3_PREFIX) { 01068 01069 // 01070 // region header record in long format 01071 // 01072 01073 RegionLen = ReadLEB128(Descriptors, &UnwindContext.DescCount); 01074 01075 switch (FirstByte & R3_REGION_TYPE_MASK) { 01076 01077 case 0: // prologue region header 01078 01079 ADD_STATE_RECORD(StateTable, RegionLen, UnwindContext.DescCount); 01080 break; 01081 01082 case 1: // body region header 01083 01084 IsPrologueRegion = FALSE; 01085 break; 01086 01087 } 01088 01089 UW_DEBUG(("Region R3: body=%x, length=%d\n", 01090 IsPrologueRegion ? 0 : 1, RegionLen)); 01091 01092 } else { 01093 01094 // 01095 // Not a region header record -> Invalid unwind descriptor. 01096 // 01097 01098 UW_DEBUG(("Invalid unwind descriptor!\n")); 01099 01100 } 01101 01102 if (UnwindContext.TargetSlot < (UnwindContext.SlotCount + RegionLen)) { 01103 UnwindContext.ActiveRegionFound = TRUE; 01104 StateTable.Current->IsTarget = IsPrologueRegion; 01105 } 01106 01107 if (IsPrologueRegion) { 01108 FirstByte = NewParsePrologueRegionPhase0(&UnwindContext, 01109 StateTable.Current, 01110 &AbiImmContext); 01111 } else { 01112 FirstByte = ParseBodyRegionDescriptors(&UnwindContext, 01113 &StateTable, 01114 RegionLen); 01115 } 01116 01117 UnwindContext.SlotCount += RegionLen; 01118 } 01119 01120 // 01121 // Restore the value of psp and save the current NatCr. 01122 // N.B. If the value is restored from stack/bstore, turn off the 01123 // corresponding sp bit in the saved mask associated with the 01124 // prologue region in which psp is saved. 01125 // 01126 01127 if (ARGUMENT_PRESENT(ContextPointers)) { 01128 IntNatsSource = (ULONG64)ContextPointers->ApUNAT; 01129 } 01130 IntNats = ContextRecord->ApUNAT; 01131 PreviousIntSp = ContextRecord->IntSp; 01132 PspRestored = FALSE; 01133 01134 SrPointer = StateTable.Current; 01135 while (SrPointer != StateTable.Base) { 01136 NewParsePrologueRegionPhase1(&UnwindContext, SrPointer); 01137 01138 if (SrPointer->MiscMask & (1 << REG_SP)) { 01139 if (UnwindContext.MiscRegs[REG_SP].Where == GENERAL_REG) { 01140 PreviousIntSp = RestorePreservedRegisterFromGR ( 01141 ContextRecord, 01142 BsFrameSize, 01143 RNatSaveIndex, 01144 (SHORT)UnwindContext.MiscRegs[REG_SP].SaveOffset, 01145 #ifdef _IMAGEHLP_SOURCE_ 01146 hProcess, 01147 ReadMemory, 01148 &Succeed, 01149 #else 01150 &Source, 01151 #endif // _IMAGEHLP_SOURCE_ 01152 &Nat 01153 ); 01154 #ifdef _IMAGEHLP_SOURCE_ 01155 if (!Succeed) { 01156 return 0; 01157 } 01158 #endif // _IMAGEHLP_SOURCE_ 01159 01160 } else { 01161 01162 Source = ContextRecord->IntSp + UnwindContext.MiscRegs[REG_SP].SaveOffset*4; 01163 #ifdef _IMAGEHLP_SOURCE_ 01164 if (!ReadMemory(hProcess, (ULONG64)(Source), &PreviousIntSp, sizeof(ULONGLONG), &Size)) { 01165 return 0; 01166 } 01167 #else 01168 PreviousIntSp = *(PULONGLONG)Source; 01169 #endif // _IMAGEHLP_SOURCE_ 01170 EXTRACT_NAT_FROM_UNAT(Nat); 01171 01172 } 01173 ContextRecord->IntNats &= ~(0x1 << STACK_POINTER_GR); 01174 ContextRecord->IntNats |= (Nat << STACK_POINTER_GR); 01175 SrPointer->MiscMask &= ~(1 << REG_SP); 01176 if (ARGUMENT_PRESENT(ContextPointers)) { 01177 CtxPtr = (ULONG64 *)((ULONG_PTR)ContextPointers + 01178 MiscContextPointersOffset[REG_SP]); 01179 *CtxPtr = Source; 01180 } 01181 PspRestored = TRUE; 01182 } 01183 if (PspRestored == FALSE) { 01184 PreviousIntSp += SrPointer->SpAdjustment * 4; 01185 } 01186 SrPointer = SrPointer->Previous; 01187 } 01188 01189 if (AbiImmContext != 0xFF) { 01190 01191 ContextRecord->IntSp = PreviousIntSp; // trap/context frame address 01192 NextPc = ProcessInterruptRegion( 01193 #ifdef _IMAGEHLP_SOURCE_ 01194 hProcess, 01195 ReadMemory, 01196 #else 01197 ContextPointers, 01198 #endif _IMAGEHLP_SOURCE_ 01199 &UnwindContext, 01200 ContextRecord, 01201 BsFrameSize, 01202 RNatSaveIndex, 01203 AbiImmContext); 01204 01205 goto FastExit; 01206 } 01207 01208 // 01209 // Restore the contents of any preserved registers saved in this frame. 01210 // 01211 01212 SrPointer = StateTable.Current; 01213 while (SrPointer != StateTable.Base) { 01214 01215 Mask = SrPointer->MiscMask; 01216 UW_DEBUG(("MiscMask = 0x%x\n", Mask)); 01217 01218 for (i = 0; i < NUMBER_OF_PRESERVED_REGISTERS; i++) { 01219 Destination = (PVOID)((ULONG_PTR)ContextRecord + MiscContextOffset[i]); 01220 if (Mask & 0x1) { 01221 01222 if (ARGUMENT_PRESENT(ContextPointers)) { 01223 CtxPtr = (ULONG64 *)((ULONG_PTR)ContextPointers + 01224 MiscContextPointersOffset[i]); 01225 Source = *CtxPtr; 01226 } 01227 01228 if (UnwindContext.MiscRegs[i].Where == GENERAL_REG) { 01229 01230 *(PULONGLONG)Destination = 01231 RestorePreservedRegisterFromGR ( 01232 ContextRecord, 01233 BsFrameSize, 01234 RNatSaveIndex, 01235 (SHORT)UnwindContext.MiscRegs[i].SaveOffset, 01236 #ifdef _IMAGEHLP_SOURCE_ 01237 hProcess, 01238 ReadMemory, 01239 &Succeed, 01240 #else 01241 &Source, 01242 #endif // _IMAGEHLP_SOURCE_ 01243 NULL 01244 ); 01245 #ifdef _IMAGEHLP_SOURCE_ 01246 if (!Succeed) { 01247 return 0; 01248 } 01249 #endif // _IMAGEHLP_SOURCE_ 01250 01251 } else if (UnwindContext.MiscRegs[i].Where == BRANCH_REG) { 01252 01253 // 01254 // restore return pointer from branch register 01255 // 01256 01257 USHORT Offset; 01258 01259 Offset = (USHORT)UnwindContext.MiscRegs[i].SaveOffset-FIRST_PRESERVED_BR; 01260 Source = (ULONG64)(&ContextRecord->BrS0 + Offset); 01261 #ifdef _IMAGEHLP_SOURCE_ 01262 if (!ReadMemory(hProcess, (ULONG64)(Source), Destination, sizeof(ULONGLONG), &Size)) { 01263 return 0; 01264 } 01265 #else 01266 *(PULONGLONG)Destination = *(PULONGLONG)(Source); 01267 #endif // _IMAGEHLP_SOURCE_ 01268 01269 } else if (UnwindContext.MiscRegs[i].Where == PSP_RELATIVE) { 01270 01271 if ((SrPointer->Ecount == 0) || (UnwindContext.MiscRegs[i].SaveOffset <= (STACK_SCRATCH_AREA/sizeof(ULONG)))) { 01272 Source = PreviousIntSp + STACK_SCRATCH_AREA 01273 - UnwindContext.MiscRegs[i].SaveOffset*4; 01274 01275 if (i == REG_NATS) { 01276 Destination = (PVOID)&IntNats; 01277 IntNatsSource = Source; 01278 } 01279 01280 #ifdef _IMAGEHLP_SOURCE_ 01281 if (!ReadMemory(hProcess, (ULONG64)(Source), Destination, sizeof(ULONGLONG), &Size)) { 01282 return 0; 01283 } 01284 #else 01285 *(PULONGLONG)Destination = *(PULONGLONG)(Source); 01286 #endif // _IMAGEHLP_SOURCE_ 01287 } 01288 01289 } else if (UnwindContext.MiscRegs[i].Where == SP_RELATIVE) { 01290 01291 // 01292 // Make the necessary adjustment depending on whether 01293 // the preserved register is saved before or after the 01294 // stack pointer has been adjusted in this prologue. 01295 // 01296 01297 if (UnwindContext.MiscRegs[i].When >= SrPointer->SpWhen) 01298 Source = ContextRecord->IntSp 01299 + UnwindContext.MiscRegs[i].SaveOffset*4; 01300 else 01301 Source = ContextRecord->IntSp+SrPointer->SpAdjustment*4 01302 + UnwindContext.MiscRegs[i].SaveOffset*4; 01303 01304 if (i == REG_NATS) { 01305 Destination = (PVOID)&IntNats; 01306 IntNatsSource = Source; 01307 } 01308 01309 #ifdef _IMAGEHLP_SOURCE_ 01310 if (!ReadMemory(hProcess, (ULONG64)(Source), Destination, sizeof(ULONGLONG), &Size)) { 01311 return 0; 01312 } 01313 #else 01314 *(PULONGLONG)Destination = *(PULONGLONG)(Source); 01315 #endif // _IMAGEHLP_SOURCE_ 01316 } 01317 01318 if (ARGUMENT_PRESENT(ContextPointers) && (i != REG_NATS)) { 01319 *CtxPtr = Source; 01320 } 01321 01322 } else if (Mask == 0) { 01323 01324 // 01325 // No more registers to restore 01326 // 01327 01328 break; 01329 } 01330 01331 Mask = Mask >> 1; 01332 } 01333 01334 // 01335 // Restore preserved FRs (f2 - f5, f16 - f31) 01336 // 01337 01338 Mask = SrPointer->FrMask; 01339 Destination = (PVOID)&ContextRecord->FltS0; 01340 CtxPtr = (ULONG64 *)&ContextPointers->FltS0; 01341 01342 UW_DEBUG(("FrMask = 0x%x\n", Mask)); 01343 for (i = 0; i < NUMBER_OF_PRESERVED_FR; i++) { 01344 if (Mask & 0x1) { 01345 01346 if ((SrPointer->Ecount == 0) || (UnwindContext.Float[i].SaveOffset <= (STACK_SCRATCH_AREA/sizeof(ULONG)))) { 01347 Source = PreviousIntSp + STACK_SCRATCH_AREA 01348 - UnwindContext.Float[i].SaveOffset*4; 01349 #ifdef _IMAGEHLP_SOURCE_ 01350 if (!ReadMemory(hProcess, (ULONG64)(Source), Destination, sizeof(FLOAT128), &Size)) { 01351 return 0; 01352 } 01353 #else 01354 *(FLOAT128 *)Destination = *(FLOAT128 *)Source; 01355 #endif // _IMAGEHLP_SOURCE_ 01356 01357 if (ARGUMENT_PRESENT(ContextPointers)) { 01358 *CtxPtr = Source; 01359 } 01360 } 01361 01362 } else if (Mask == 0) { 01363 break; 01364 } 01365 01366 Mask = Mask >> 1; 01367 01368 if (i == (NUMBER_OF_LOW_PRESERVED_FR - 1)) { 01369 Destination = (PVOID)&ContextRecord->FltS4; 01370 CtxPtr = (ULONG64 *)(&ContextPointers->FltS4); 01371 } else { 01372 Destination = (PVOID)((FLOAT128 *)Destination+1); 01373 CtxPtr++; 01374 } 01375 } 01376 01377 // 01378 // Restore preserved GRs (r4 - r7) 01379 // 01380 01381 Mask = SrPointer->GrMask; 01382 Destination = (PVOID)&ContextRecord->IntS0; 01383 CtxPtr = (ULONG64 *)&ContextPointers->IntS0; 01384 NatCtxPtr = (ULONG64 *)&ContextPointers->IntS0Nat; 01385 01386 UW_DEBUG(("GrMask = 0x%x\n", Mask)); 01387 for (i = 0; i < NUMBER_OF_PRESERVED_GR; i++) 01388 { 01389 if (Mask & 0x1) { 01390 01391 if ((SrPointer->Ecount == 0) || (UnwindContext.Integer[i].SaveOffset <= (STACK_SCRATCH_AREA/sizeof(ULONG)))) { 01392 Source = PreviousIntSp + STACK_SCRATCH_AREA 01393 - UnwindContext.Integer[i].SaveOffset*4; 01394 01395 #ifdef _IMAGEHLP_SOURCE_ 01396 if (!ReadMemory(hProcess, (ULONG64)(Source), Destination, sizeof(ULONGLONG), &Size)) { 01397 return 0; 01398 } 01399 #else 01400 *(PULONGLONG)Destination = *(PULONGLONG)Source; 01401 #endif // _IMAGEHLP_SOURCE_ 01402 EXTRACT_NAT_FROM_UNAT(Nat); 01403 Nat = (UCHAR)((IntNats >> (((ULONG_PTR)Source & 0x1F8) >> 3)) & 0x1); 01404 ContextRecord->IntNats &= ~(0x1 << (i+FIRST_PRESERVED_GR)); 01405 ContextRecord->IntNats |= (Nat << (i+FIRST_PRESERVED_GR)); 01406 01407 #ifndef _IMAGEHLP_SOURCE_ 01408 if (ARGUMENT_PRESENT(ContextPointers)) { 01409 *CtxPtr = Source; 01410 *NatCtxPtr = IntNatsSource; 01411 } 01412 #endif 01413 } 01414 01415 } else if (Mask == 0) { 01416 break; 01417 } 01418 01419 Mask = Mask >> 1; 01420 Destination = (PVOID)((PULONGLONG)Destination+1); 01421 CtxPtr++; 01422 NatCtxPtr++; 01423 } 01424 01425 ContextRecord->IntSp += SrPointer->SpAdjustment * 4; 01426 SrPointer = SrPointer->Previous; 01427 } 01428 01429 ContextRecord->IntSp = PreviousIntSp; 01430 01431 // 01432 // Restore the value of the epilogue count from the PFS 01433 // 01434 01435 ContextRecord->ApEC = (ContextRecord->RsPFS >> PFS_EC_SHIFT) & 01436 ~(((ULONGLONG)1 << PFS_EC_SIZE) - 1); 01437 if (ARGUMENT_PRESENT(ContextPointers)) { 01438 ContextPointers->ApEC = ContextPointers->RsPFS; 01439 } 01440 01441 01442 FastExit: 01443 01444 NOT_IMAGEHLP(*InFunction = TRUE); 01445 NOT_IMAGEHLP(EstablisherFrame->MemoryStackFp = ContextRecord->IntSp); 01446 NOT_IMAGEHLP(EstablisherFrame->BackingStoreFp = ContextRecord->RsBSP); 01447 01448 #ifdef _IMAGEHLP_SOURCE_ 01449 if (Descriptors) 01450 MemFree(Descriptors); 01451 #endif // _IMAGEHLP_SOURCE_ 01452 01453 if (AbiImmContext == 0xFF) { 01454 01455 #ifdef _IMAGEHLP_SOURCE_ 01456 NextPc = ContextRecord->BrRp; 01457 #else 01458 NextPc = RtlIa64InsertIPSlotNumber((ContextRecord->BrRp-16), 2); 01459 #endif // _IMAGEHLP_SOURCE_ 01460 01461 // 01462 // determine the local frame size of previous frame and compute 01463 // the new bsp. 01464 // 01465 01466 OldTopRnat = (ContextRecord->RsBSP+(BsFrameSize-1)*8) | RNAT_ALIGNMENT; 01467 01468 ContextRecord->StIFS = MASK(IFS_V, (ULONGLONG)1) | ContextRecord->RsPFS; 01469 BsFrameSize = (SHORT)ContextRecord->StIFS & PFS_SIZE_MASK; 01470 LocalFrameSize = (SHORT)(ContextRecord->StIFS >> PFS_SIZE_SHIFT) & PFS_SIZE_MASK; 01471 TempFrameSize = LocalFrameSize - RNatSaveIndex; 01472 while (TempFrameSize > 0) { 01473 LocalFrameSize++; 01474 BsFrameSize++; 01475 TempFrameSize -= NAT_BITS_PER_RNAT_REG; 01476 } 01477 ContextRecord->RsBSP -= LocalFrameSize * 8; 01478 ContextRecord->RsBSPSTORE = ContextRecord->RsBSP; 01479 01480 // 01481 // determine if the RNAT field needs to be updated. 01482 // 01483 01484 NewTopRnat = (ContextRecord->RsBSP+(BsFrameSize-1)*8) | RNAT_ALIGNMENT; 01485 01486 if (NewTopRnat < OldTopRnat) { 01487 01488 #ifdef _IMAGEHLP_SOURCE_ 01489 Destination = &ContextRecord->RsRNAT; 01490 Source = NewTopRnat; 01491 if (!ReadMemory(hProcess, (ULONG64)Source, Destination, 8, &Size)) { 01492 return 0; 01493 } 01494 #else 01495 ContextRecord->RsRNAT = *(PULONGLONG)(NewTopRnat); 01496 #endif // _IMAGEHLP_SOURCE_ 01497 01498 } 01499 } 01500 01501 #ifdef _IMAGEHLP_SOURCE_ 01502 UW_DEBUG(("NextPc = 0x%lx, PSP = 0x%lx, BSP = 0x%lx\n", 01503 (ULONGLONG)NextPc, 01504 (ULONGLONG)ContextRecord->IntSp, 01505 (ULONGLONG)ContextRecord->RsBSP)); 01506 #else 01507 UW_DEBUG(("NextPc = 0x%lx, PSP = 0x%lx, BSP = 0x%lx\n", 01508 (ULONGLONG)NextPc, 01509 EstablisherFrame->MemoryStackFp, 01510 EstablisherFrame->BackingStoreFp)); 01511 #endif // _IMAGEHLP_SOURCE_ 01512 return (NextPc); 01513 }

VOID SrInitialize IN PSTATE_RECORD_STACK  StateTable,
IN PSTATE_RECORD  StateRecord,
IN ULONG  Size
 

Definition at line 397 of file ia64/vunwind.c.

References Size.

Referenced by RtlVirtualUnwind().

00402 { 00403 StateTable->Size = Size; 00404 StateTable->Base = StateRecord; 00405 StateTable->Top = StateRecord; 00406 StateTable->Current = StateRecord; 00407 RtlZeroMemory(StateTable->Top, sizeof(STATE_RECORD)); 00408 }


Variable Documentation

USHORT MiscContextOffset[NUMBER_OF_PRESERVED_REGISTERS] [static]
 

Initial value:

{ OFFSET(CONTEXT, Preds), OFFSET(CONTEXT, IntSp), OFFSET(CONTEXT, RsPFS), OFFSET(CONTEXT, BrRp), OFFSET(CONTEXT, ApUNAT), OFFSET(CONTEXT, ApLC), 0, OFFSET(CONTEXT, BrS0), OFFSET(CONTEXT, BrS1), OFFSET(CONTEXT, BrS2), OFFSET(CONTEXT, BrS3), }

Definition at line 340 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

USHORT MiscContextPointersOffset[NUMBER_OF_PRESERVED_REGISTERS] [static]
 

Initial value:

{ OFFSET(KNONVOLATILE_CONTEXT_POINTERS, Preds), OFFSET(KNONVOLATILE_CONTEXT_POINTERS, IntSp), OFFSET(KNONVOLATILE_CONTEXT_POINTERS, RsPFS), OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrRp), OFFSET(KNONVOLATILE_CONTEXT_POINTERS, ApUNAT), OFFSET(KNONVOLATILE_CONTEXT_POINTERS, ApLC), 0, OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS0), OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS1), OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS2), OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS3), }

Definition at line 355 of file ia64/vunwind.c.

Referenced by RtlVirtualUnwind().

UCHAR P3RecordTypeToRegisterIndex[] [static]
 

Initial value:

Definition at line 370 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1().

UCHAR P7RecordTypeToRegisterIndex[] [static]
 

Initial value:

Definition at line 373 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase0(), and NewParsePrologueRegionPhase1().

UCHAR P8RecordTypeToRegisterIndex[] [static]
 

Initial value:

Definition at line 377 of file ia64/vunwind.c.

Referenced by NewParsePrologueRegionPhase1().


Generated on Sat May 15 19:46:08 2004 for test by doxygen 1.3.7