00001
00018
#if !defined(BUILD_DBGHELP) && !defined(BUILD_IMAGEHLP)
00019
00020
#include "ntrtlp.h"
00021
00022
#else // !BUILD_DBGHELP && !BUILD_IMAGEHLP
00023
00024
#define TARGET_IA64
00025
#define _CROSS_PLATFORM_
00026
#define _IA64REG_
00027
#include "walk.h"
00028
#include "private.h"
00029
#include <stdlib.h>
00030
00031
#endif // !BUILD_DBGHELP && !BUILD_IMAGEHLP
00032
00033
#ifdef _IMAGEHLP_SOURCE_
00034
00035
#define NOT_IMAGEHLP(E)
00036
#define FUNCTION_ENTRY_IS_IMAGE_STYLE
00037
#define RtlVirtualUnwind VirtualUnwindIa64
00038
#define PRUNTIME_FUNCTION PIMAGE_RUNTIME_FUNCTION_ENTRY
00039
#define RUNTIME_FUNCTION IMAGE_RUNTIME_FUNCTION_ENTRY
00040
#define VUW_DEBUG_PRINT OutputDebugString
00041
00042
#else // !_IMAGEHLP_SOURCE_
00043
00044 #define NOT_IMAGEHLP(E) E
00045 #define VUW_DEBUG_PRINT DbgPrint
00046
00047
#endif // !_IMAGEHLP_SOURCE_
00048
00049
#ifdef MASK
00050
#undef MASK
00051
#endif // MASK
00052 #define MASK(bp,value) (value << bp)
00053
00054
00055
00056
00057
00058 #define SVR4_ABI 0
00059 #define HPUX_ABI 1
00060 #define NT_ABI 2
00061
00062
00063
#ifdef KERNEL_DEBUGGER
00064
#define FUNCTION_ENTRY_IS_IMAGE_STYLE
00065
#define RtlVirtualUnwind VirtualUnwind
00066
#endif
00067
00068 #define STATE_RECORD_STACK_SIZE 32
00069
00070 #define SPILLSIZE_OF_FLOAT128_IN_DWORDS 4
00071 #define SPILLSIZE_OF_ULONGLONG_IN_DWORDS 2
00072
00073 #define REGISTER_SIZE sizeof(ULONGLONG)
00074 #define STATIC_REGISTER_SET_SIZE 32
00075 #define SLOTS_PER_BUNDLE 3
00076
00077 #define R1_MASK 0xC0
00078 #define R1_PREFIX 0x0
00079 #define R1_REGION_TYPE_MASK 0x20
00080 #define R1_LENGTH_MASK 0x1F
00081
00082 #define R2_MASK 0xE0
00083 #define R2_PREFIX 0x40
00084
00085 #define R3_MASK 0xE0
00086 #define R3_PREFIX 0x60
00087 #define R3_REGION_TYPE_MASK 0x3
00088
00089 #define P1_MASK 0xE0
00090 #define P1_PREFIX 0x80
00091 #define P2_MASK 0xF0
00092 #define P2_PREFIX 0xA0
00093 #define P3_MASK 0xF8
00094 #define P3_PREFIX 0xB0
00095 #define P4_MASK 0xFF
00096 #define P4_PREFIX 0xB8
00097 #define P5_MASK 0xFF
00098 #define P5_PREFIX 0xB9
00099 #define P6_MASK 0xE0
00100 #define P6_PREFIX 0xC0
00101 #define P7_MASK 0xF0
00102 #define P7_PREFIX 0xE0
00103 #define P8_MASK 0xFF
00104 #define P8_PREFIX 0xF0
00105 #define P9_MASK 0xFF
00106 #define P9_PREFIX 0xF1
00107 #define P10_MASK 0xFF
00108 #define P10_PREFIX 0xFF
00109
00110 #define B1_MASK 0xC0
00111 #define B1_PREFIX 0x80
00112 #define B1_TYPE_MASK 0x20
00113 #define B1_LABEL_MASK 0x1F
00114 #define B2_MASK 0xE0
00115 #define B2_PREFIX 0xC0
00116 #define B2_ECOUNT_MASK 0x1F
00117 #define B3_MASK 0xF0
00118 #define B3_PREFIX 0xE0
00119 #define B4_MASK 0xF0
00120 #define B4_PREFIX 0xF0
00121 #define B4_TYPE_MASK 0x08
00122
00123
00124
00125
00126
00127 #define PSP_GR 0
00128 #define RP_GR 1
00129 #define PFS_GR 2
00130 #define PREDS_GR 3
00131 #define UNAT_GR 4
00132 #define LC_GR 5
00133 #define RP_BR 6
00134 #define RNAT_GR 7
00135 #define BSP_GR 8
00136 #define BSPSTORE_GR 9
00137 #define FPSR_GR 10
00138 #define PRIUNAT_GR 11
00139
00140
00141
00142
00143
00144 #define MEM_STACK_F 0
00145 #define MEM_STACK_V 1
00146 #define SPILL_BASE 2
00147 #define PSP_SPREL 3
00148 #define RP_WHEN 4
00149 #define RP_PSPREL 5
00150 #define PFS_WHEN 6
00151 #define PFS_PSPREL 7
00152 #define PREDS_WHEN 8
00153 #define PREDS_PSPREL 9
00154 #define LC_WHEN 10
00155 #define LC_PSPREL 11
00156 #define UNAT_WHEN 12
00157 #define UNAT_PSPREL 13
00158 #define FPSR_WHEN 14
00159 #define FPSR_PSPREL 15
00160
00161
00162
00163
00164
00165 #define PSP_PSPREL 0
00166 #define RP_SPREL 1
00167 #define PFS_SPREL 2
00168 #define PREDS_SPREL 3
00169 #define LC_SPREL 4
00170 #define UNAT_SPREL 5
00171 #define FPSR_SPREL 6
00172 #define BSP_WHEN 7
00173 #define BSP_PSPREL 8
00174 #define BSP_SPREL 9
00175 #define BSPSTORE_WHEN 10
00176 #define BSPSTORE_PSPREL 11
00177 #define BSPSTORE_SPREL 12
00178 #define RNAT_WHEN 13
00179 #define RNAT_PSPREL 14
00180 #define RNAT_SPREL 15
00181 #define PRIUNAT_WHEN 16
00182 #define PRIUNAT_PSPREL 17
00183 #define PRIUNAT_SPREL 18
00184
00185
00186 #define STACK_POINTER_GR 12
00187
00188 #define FIRST_PRESERVED_GR 4
00189 #define LAST_PRESERVED_GR 7
00190 #define NUMBER_OF_PRESERVED_GR 4
00191
00192 #define FIRST_LOW_PRESERVED_FR 2
00193 #define LAST_LOW_PRESERVED_FR 5
00194 #define NUMBER_OF_LOW_PRESERVED_FR 4
00195
00196 #define FIRST_HIGH_PRESERVED_FR 16
00197 #define LAST_HIGH_PRESERVED_FR 31
00198 #define NUMBER_OF_HIGH_PRESERVED_FR 16
00199 #define NUMBER_OF_PRESERVED_FR NUMBER_OF_LOW_PRESERVED_FR+NUMBER_OF_HIGH_PRESERVED_FR
00200
00201 #define FIRST_PRESERVED_BR 1
00202 #define LAST_PRESERVED_BR 5
00203 #define NUMBER_OF_PRESERVED_BR 5
00204
00205 #define NUMBER_OF_PRESERVED_MISC 7
00206
00207 #define NUMBER_OF_PRESERVED_REGISTERS 12
00208
00209
00210 #define REG_MISC_BASE 0
00211 #define REG_PREDS REG_MISC_BASE+0
00212 #define REG_SP REG_MISC_BASE+1
00213 #define REG_PFS REG_MISC_BASE+2
00214 #define REG_RP REG_MISC_BASE+3
00215 #define REG_UNAT REG_MISC_BASE+4
00216 #define REG_LC REG_MISC_BASE+5
00217 #define REG_NATS REG_MISC_BASE+6
00218
00219 #define REG_BR_BASE REG_MISC_BASE+NUMBER_OF_PRESERVED_MISC
00220
00221 #define REG_FPSR 0xff // REG_MISC_BASE+7
00222 #define REG_BSP 0xff // REG_MISC_BASE+8
00223 #define REG_BSPSTORE 0xff // REG_MISC_BASE+9
00224 #define REG_RNAT 0xff // REG_MISC_BASE+10
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 #define GENERAL_REG 0
00236 #define PSP_RELATIVE 1
00237 #define SP_RELATIVE 2
00238 #define BRANCH_REG 3
00239
00240
00241 #define ADD_STATE_RECORD(States, RegionLength, DescBeginIndex) \
00242
States.Top++; \
00243
States.Top->IsTarget = FALSE; \
00244
States.Top->MiscMask = 0; \
00245
States.Top->FrMask = 0; \
00246
States.Top->GrMask = 0; \
00247
States.Top->Label = (LABEL)0; \
00248
States.Top->Ecount = 0; \
00249
States.Top->RegionLen = RegionLength; \
00250
States.Top->RegionBegin = UnwindContext.SlotCount; \
00251
States.Top->SpWhen = 0; \
00252
States.Top->SpAdjustment = 0; \
00253
States.Top->SpillBase = (States.Top-1)->SpillPtr; \
00254
States.Top->SpillPtr = (States.Top-1)->SpillPtr; \
00255
States.Top->Previous = States.Current; \
00256
States.Top->DescBegin = DescBeginIndex; \
00257
States.Current = States.Top
00258
00259
00260 #define VALID_LABEL_BIT_POSITION 15
00261
00262 #define LABEL_REGION(Region, Label) \
00263
Region->Label = Label; \
00264
Region->MiscMask |= (1 << VALID_LABEL_BIT_POSITION)
00265
00266 #define IS_REGION_LABELED(Region) \
00267
(Region->MiscMask & (1 << VALID_LABEL_BIT_POSITION))
00268
00269 #define CHECK_LABEL(State, Label) \
00270
( (IS_REGION_LABELED(State)) && (Label == State->Label) )
00271
00272
00273 #define EXTRACT_NAT_FROM_UNAT(NatBit) \
00274
NatBit = (UCHAR)((IntNats >> (((ULONG_PTR)Source & 0x1F8) >> 3)) & 0x1);
00275
00276
00277
#if DBG
00278
int UnwindDebugLevel = 0;
00279
# ifdef _IMAGEHLP_SOURCE_
00280
# define UW_DEBUG(x) if (UnwindDebugLevel) dbPrint##x
00281
# else
00282
# define UW_DEBUG(x) if (UnwindDebugLevel) DbgPrint##x
00283
# endif
00284
#else
00285 # define UW_DEBUG(x)
00286
#endif // DBG
00287
00288
00289
00290 typedef struct _REGISTER_RECORD {
00291 ULONG
Where : 2;
00292 ULONG
SaveOffset : 30;
00293 ULONG
When;
00294 }
REGISTER_RECORD, *
PREGISTER_RECORD;
00295
00296 typedef ULONG
LABEL;
00297
00298 typedef struct _STATE_RECORD {
00299 struct _STATE_RECORD *
Previous;
00300 BOOLEAN
IsTarget;
00301 UCHAR
GrMask;
00302 USHORT MiscMask;
00303
00304
00305 ULONG
FrMask;
00306 ULONG
SpAdjustment;
00307 ULONG
SpWhen;
00308 ULONG
SpillPtr;
00309 ULONG
SpillBase;
00310 ULONG
RegionBegin;
00311 ULONG
RegionLen;
00312 LABEL Label;
00313 ULONG
Ecount;
00314 ULONG
DescBegin;
00315 ULONG
DescEnd;
00316 }
STATE_RECORD, *
PSTATE_RECORD;
00317
00318 typedef struct _UNWIND_CONTEXT {
00319 REGISTER_RECORD MiscRegs[
NUMBER_OF_PRESERVED_REGISTERS];
00320 REGISTER_RECORD Float[
NUMBER_OF_PRESERVED_FR];
00321 REGISTER_RECORD Integer[
NUMBER_OF_PRESERVED_GR];
00322 BOOLEAN
ActiveRegionFound;
00323 USHORT Version;
00324 PUCHAR
Descriptors;
00325 ULONG
Size;
00326 ULONG
DescCount;
00327 ULONG
TargetSlot;
00328 ULONG
SlotCount;
00329 }
UNWIND_CONTEXT, *
PUNWIND_CONTEXT;
00330
00331 typedef struct _STATE_RECORD_STACK {
00332 ULONG
Size;
00333 PSTATE_RECORD Current;
00334 PSTATE_RECORD Top;
00335 PSTATE_RECORD Base;
00336 }
STATE_RECORD_STACK, *
PSTATE_RECORD_STACK;
00337
00338 #define OFFSET(type, field) ((ULONG_PTR)(&((type *)0)->field))
00339
00340 static USHORT MiscContextOffset[
NUMBER_OF_PRESERVED_REGISTERS] = {
00341
OFFSET(CONTEXT, Preds),
00342
OFFSET(CONTEXT, IntSp),
00343
OFFSET(CONTEXT, RsPFS),
00344
OFFSET(CONTEXT, BrRp),
00345
OFFSET(CONTEXT, ApUNAT),
00346
OFFSET(CONTEXT, ApLC),
00347 0,
00348
OFFSET(CONTEXT, BrS0),
00349
OFFSET(CONTEXT, BrS1),
00350
OFFSET(CONTEXT, BrS2),
00351
OFFSET(CONTEXT, BrS3),
00352
OFFSET(CONTEXT, BrS4)
00353 };
00354
00355 static USHORT MiscContextPointersOffset[
NUMBER_OF_PRESERVED_REGISTERS] = {
00356
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, Preds),
00357
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, IntSp),
00358
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, RsPFS),
00359
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrRp),
00360
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, ApUNAT),
00361
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, ApLC),
00362 0,
00363
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS0),
00364
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS1),
00365
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS2),
00366
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS3),
00367
OFFSET(KNONVOLATILE_CONTEXT_POINTERS, BrS4)
00368 };
00369
00370 static UCHAR
P3RecordTypeToRegisterIndex[] =
00371 {
REG_SP,
REG_RP,
REG_PFS,
REG_PREDS,
REG_UNAT,
REG_LC,
REG_RP};
00372
00373 static UCHAR
P7RecordTypeToRegisterIndex[] =
00374 {0,
REG_SP, 0,
REG_SP,
REG_RP,
REG_RP,
REG_PFS,
REG_PFS,
REG_PREDS,
00375
REG_PREDS,
REG_LC,
REG_LC,
REG_UNAT,
REG_UNAT,
REG_FPSR,
REG_FPSR};
00376
00377 static UCHAR
P8RecordTypeToRegisterIndex[] =
00378 {
REG_SP,
REG_RP,
REG_PFS,
REG_PREDS,
REG_LC,
REG_UNAT,
REG_FPSR,
00379
REG_BSP,
REG_BSP,
REG_BSP,
REG_BSPSTORE,
REG_BSPSTORE,
REG_BSPSTORE,
00380
REG_RNAT,
REG_RNAT,
REG_RNAT,
REG_NATS,
REG_NATS,
REG_NATS};
00381
00382 UCHAR
00383
NewParsePrologueRegionPhase0 (
00384 IN PUNWIND_CONTEXT UwContext,
00385 IN PSTATE_RECORD StateRecord,
00386 IN OUT PUCHAR AbiImmContext
00387 );
00388
00389
VOID
00390
NewParsePrologueRegionPhase1 (
00391 IN PUNWIND_CONTEXT UwContext,
00392 IN PSTATE_RECORD StateRecord
00393 );
00394
00395
00396
VOID
00397 SrInitialize (
00398 IN PSTATE_RECORD_STACK StateTable,
00399 IN PSTATE_RECORD StateRecord,
00400 IN ULONG Size
00401 )
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 }
00409
00410
00411 ULONG
00412 ReadLEB128 (
00413 IN PUCHAR Descriptors,
00414 IN OUT PULONG CurrentDescIndex
00415 )
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 }
00441
00442
00443 ULONGLONG
00444 RestorePreservedRegisterFromGR (
00445 IN PCONTEXT Context,
00446 IN SHORT BsFrameSize,
00447 IN SHORT RNatSaveIndex,
00448 IN SHORT GrNumber,
00449 #ifdef _IMAGEHLP_SOURCE_
00450 IN HANDLE hProcess,
00451 IN PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
00452 OUT BOOL *Succeed,
00453 #
else
00454 OUT ULONG64 *SourceAddress,
00455 #endif
00456 OUT PUCHAR Nat OPTIONAL
00457 )
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
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
00523
00524
00525 *Nat = (UCHAR) 0;
00526
00527 }
00528
00529
return (Result);
00530 }
00531
00532
00533 UCHAR
00534 ParseBodyRegionDescriptors (
00535 IN PUNWIND_CONTEXT UnwindContext,
00536 IN PSTATE_RECORD_STACK StateTable,
00537 IN ULONG RegionLen
00538 )
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
00563
00564
00565 CopyLabel =
TRUE;
00566
00567 }
else {
00568
00569
00570
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
00605
00606
00607 CopyLabel =
TRUE;
00608
00609 }
else {
00610
00611
00612
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
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++;
00648
00649
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
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 }
00700
00701
00702 ULONGLONG
00703 ProcessInterruptRegion (
00704 #ifdef _IMAGEHLP_SOURCE_
00705 IN HANDLE hProcess,
00706 IN PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory,
00707 #
else
00708 IN PKNONVOLATILE_CONTEXT_POINTERS ContextPointers,
00709 #endif _IMAGEHLP_SOURCE_
00710 IN PUNWIND_CONTEXT UnwindContext,
00711 IN PCONTEXT Context,
00712 IN SHORT BsFrameSize,
00713 IN SHORT RNatSaveIndex,
00714 IN UCHAR AbiImmContext
00715 )
00716 {
00717
00718
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
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
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
00818
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 }
00860
00861
00862 ULONGLONG
00863 RtlVirtualUnwind (
00864 #ifdef _IMAGEHLP_SOURCE_
00865 HANDLE hProcess,
00866 ULONGLONG ImageBase,
00867 ULONGLONG ControlPc,
00868 PRUNTIME_FUNCTION FunctionEntry,
00869 PCONTEXT ContextRecord,
00870 PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemory
00871 #define ContextPointers ((PKNONVOLATILE_CONTEXT_POINTERS)0)
00872 #
else
00873 IN ULONGLONG ImageBase,
00874 IN ULONGLONG ControlPc,
00875 IN PRUNTIME_FUNCTION FunctionEntry,
00876 IN OUT PCONTEXT ContextRecord,
00877 OUT PBOOLEAN InFunction,
00878 OUT PFRAME_POINTERS EstablisherFrame,
00879 IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL
00880 #endif
00881 )
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
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;
00947
SHORT LocalFrameSize;
00948
SHORT TempFrameSize;
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
01022
01023
01024 IsPrologueRegion =
TRUE;
01025
01026
01027
01028
01029
01030
01031
01032
01033
if ((FirstByte &
R1_MASK) ==
R1_PREFIX) {
01034
01035
01036
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
01054
01055
01056
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
01071
01072
01073 RegionLen =
ReadLEB128(Descriptors, &UnwindContext.
DescCount);
01074
01075
switch (FirstByte &
R3_REGION_TYPE_MASK) {
01076
01077
case 0:
01078
01079
ADD_STATE_RECORD(StateTable, RegionLen, UnwindContext.
DescCount);
01080
break;
01081
01082
case 1:
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
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
01122
01123
01124
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
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;
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
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
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
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
01293
01294
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
01326
01327
01328
break;
01329 }
01330
01331 Mask = Mask >> 1;
01332 }
01333
01334
01335
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
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
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
01463
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
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 }
01514
01515
01516 UCHAR
01517 NewParsePrologueRegionPhase0 (
01518 IN PUNWIND_CONTEXT UwContext,
01519 IN PSTATE_RECORD State,
01520 IN OUT PUCHAR AbiImmContext
01521 )
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
01700
01701
01702
break;
01703 }
01704 }
01705
01706 State->DescEnd = UwContext->DescCount - 2;
01707
01708
return FirstByte;
01709 }
01710
01711
VOID
01712 NewParsePrologueRegionPhase1 (
01713 IN PUNWIND_CONTEXT UwContext,
01714 IN PSTATE_RECORD State
01715 )
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;
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
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);
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;
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
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
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
01944
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
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
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
02040
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
02081
02082
02083
02084
02085
02086
02087
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
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
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
02140
02141
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:
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:
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:
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:
02225
break;
02226
02227 }
02228 }
02229 }
02230 }