ReactOS  0.4.13-dev-99-g7e18b6d
unwind.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * PURPOSE: Unwinding related functions
5  * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
6  */
7 
8 /* INCLUDES *****************************************************************/
9 
10 #include <rtl.h>
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define UNWIND_HISTORY_TABLE_NONE 0
16 #define UNWIND_HISTORY_TABLE_GLOBAL 1
17 #define UNWIND_HISTORY_TABLE_LOCAL 2
18 
19 #define UWOP_PUSH_NONVOL 0
20 #define UWOP_ALLOC_LARGE 1
21 #define UWOP_ALLOC_SMALL 2
22 #define UWOP_SET_FPREG 3
23 #define UWOP_SAVE_NONVOL 4
24 #define UWOP_SAVE_NONVOL_FAR 5
25 #define UWOP_SAVE_XMM 6
26 #define UWOP_SAVE_XMM_FAR 7
27 #define UWOP_SAVE_XMM128 8
28 #define UWOP_SAVE_XMM128_FAR 9
29 #define UWOP_PUSH_MACHFRAME 10
30 
31 
32 typedef unsigned char UBYTE;
33 
34 typedef union _UNWIND_CODE
35 {
36  struct
37  {
41  };
44 
45 typedef struct _UNWIND_INFO
46 {
54 /* union {
55  OPTIONAL ULONG ExceptionHandler;
56  OPTIONAL ULONG FunctionEntry;
57  };
58  OPTIONAL ULONG ExceptionData[];
59 */
61 
62 /* FUNCTIONS *****************************************************************/
63 
76 NTAPI
78  IN DWORD64 ControlPc,
79  OUT PDWORD64 ImageBase,
81 {
82  PVOID Table;
83  ULONG Size;
84 
85  /* Find corresponding file header from code address */
86  if (!RtlPcToFileHeader((PVOID)ControlPc, (PVOID*)ImageBase))
87  {
88  /* Nothing found */
89  return NULL;
90  }
91 
92  /* Locate the exception directory */
94  TRUE,
96  &Size);
97 
98  /* Return the number of entries */
99  *Length = Size / sizeof(RUNTIME_FUNCTION);
100 
101  /* Return the address of the table */
102  return Table;
103 }
104 
111 NTAPI
113  IN DWORD64 ControlPc,
114  OUT PDWORD64 ImageBase,
115  OUT PUNWIND_HISTORY_TABLE HistoryTable)
116 {
117  PRUNTIME_FUNCTION FunctionTable, FunctionEntry;
118  ULONG TableLength;
119  ULONG IndexLo, IndexHi, IndexMid;
120 
121  /* Find the corresponding table */
122  FunctionTable = RtlLookupFunctionTable(ControlPc, ImageBase, &TableLength);
123 
124  /* Fail, if no table is found */
125  if (!FunctionTable)
126  {
127  return NULL;
128  }
129 
130  /* Use relative virtual address */
131  ControlPc -= *ImageBase;
132 
133  /* Do a binary search */
134  IndexLo = 0;
135  IndexHi = TableLength;
136  while (IndexHi > IndexLo)
137  {
138  IndexMid = (IndexLo + IndexHi) / 2;
139  FunctionEntry = &FunctionTable[IndexMid];
140 
141  if (ControlPc < FunctionEntry->BeginAddress)
142  {
143  /* Continue search in lower half */
144  IndexHi = IndexMid;
145  }
146  else if (ControlPc >= FunctionEntry->EndAddress)
147  {
148  /* Continue search in upper half */
149  IndexLo = IndexMid + 1;
150  }
151  else
152  {
153  /* ControlPc is within limits, return entry */
154  return FunctionEntry;
155  }
156  }
157 
158  /* Nothing found, return NULL */
159  return NULL;
160 }
161 
162 BOOLEAN
163 NTAPI
166  IN DWORD EntryCount,
168 {
170  return FALSE;
171 }
172 
173 BOOLEAN
174 NTAPI
177 {
179  return FALSE;
180 }
181 
182 BOOLEAN
183 NTAPI
185  IN DWORD64 TableIdentifier,
187  IN DWORD Length,
188  IN PGET_RUNTIME_FUNCTION_CALLBACK Callback,
189  IN PVOID Context,
190  IN PCWSTR OutOfProcessCallbackDll)
191 {
193  return FALSE;
194 }
195 
196 void
199 {
200  ((DWORD64*)(&Context->Rax))[Reg] = Value;
201 }
202 
203 DWORD64
206 {
207  return ((DWORD64*)(&Context->Rax))[Reg];
208 }
209 
210 void
213 {
214  DWORD64 Value = *(DWORD64*)Context->Rsp;
215  Context->Rsp += 8;
216  SetReg(Context, Reg, Value);
217 }
218 
229 BOOLEAN
230 static
231 __inline
234  ULONG64 ImageBase,
235  PRUNTIME_FUNCTION FunctionEntry)
236 {
237  CONTEXT LocalContext;
238  BYTE *InstrPtr;
239  DWORD Instr;
240  BYTE Reg, Mod;
241  ULONG64 EndAddress;
242 
243  /* Make a local copy of the context */
244  LocalContext = *Context;
245 
246  InstrPtr = (BYTE*)LocalContext.Rip;
247 
248  /* Check if first instruction of epilog is "add rsp, x" */
249  Instr = *(DWORD*)InstrPtr;
250  if ( (Instr & 0x00fffdff) == 0x00c48148 )
251  {
252  if ( (Instr & 0x0000ff00) == 0x8300 )
253  {
254  /* This is "add rsp, 0x??" */
255  LocalContext.Rsp += Instr >> 24;
256  InstrPtr += 4;
257  }
258  else
259  {
260  /* This is "add rsp, 0x???????? */
261  LocalContext.Rsp += *(DWORD*)(InstrPtr + 3);
262  InstrPtr += 7;
263  }
264  }
265  /* Check if first instruction of epilog is "lea rsp, ..." */
266  else if ( (Instr & 0x38fffe) == 0x208d48 )
267  {
268  /* Get the register */
269  Reg = ((Instr << 8) | (Instr >> 16)) & 0x7;
270 
271  LocalContext.Rsp = GetReg(&LocalContext, Reg);
272 
273  /* Get adressing mode */
274  Mod = (Instr >> 22) & 0x3;
275  if (Mod == 0)
276  {
277  /* No displacement */
278  InstrPtr += 3;
279  }
280  else if (Mod == 1)
281  {
282  /* 1 byte displacement */
283  LocalContext.Rsp += Instr >> 24;
284  InstrPtr += 4;
285  }
286  else if (Mod == 2)
287  {
288  /* 4 bytes displacement */
289  LocalContext.Rsp += *(DWORD*)(InstrPtr + 3);
290  InstrPtr += 7;
291  }
292  }
293 
294  /* Loop the following instructions before the ret */
295  EndAddress = FunctionEntry->EndAddress + ImageBase - 1;
296  while ((DWORD64)InstrPtr < EndAddress)
297  {
298  Instr = *(DWORD*)InstrPtr;
299 
300  /* Check for a simple pop */
301  if ( (Instr & 0xf8) == 0x58 )
302  {
303  /* Opcode pops a basic register from stack */
304  Reg = Instr & 0x7;
305  PopReg(&LocalContext, Reg);
306  InstrPtr++;
307  continue;
308  }
309 
310  /* Check for REX + pop */
311  if ( (Instr & 0xf8fb) == 0x5841 )
312  {
313  /* Opcode is pop r8 .. r15 */
314  Reg = ((Instr >> 8) & 0x7) + 8;
315  PopReg(&LocalContext, Reg);
316  InstrPtr += 2;
317  continue;
318  }
319 
320  /* Opcode not allowed for Epilog */
321  return FALSE;
322  }
323 
324  /* Check if we are at the ret instruction */
325  if ((DWORD64)InstrPtr != EndAddress)
326  {
327  /* If we went past the end of the function, something is broken! */
328  ASSERT((DWORD64)InstrPtr <= EndAddress);
329  return FALSE;
330  }
331 
332  /* Make sure this is really a ret instruction */
333  if (*InstrPtr != 0xc3)
334  {
335  ASSERT(FALSE);
336  return FALSE;
337  }
338 
339  /* Unwind is finished, pop new Rip from Stack */
340  LocalContext.Rip = *(DWORD64*)LocalContext.Rsp;
341  LocalContext.Rsp += sizeof(DWORD64);
342 
343  *Context = LocalContext;
344  return TRUE;
345 }
346 
348 NTAPI
351  _In_ ULONG64 ImageBase,
352  _In_ ULONG64 ControlPc,
353  _In_ PRUNTIME_FUNCTION FunctionEntry,
355  _Outptr_ PVOID *HandlerData,
357  _Inout_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers)
358 {
359  PUNWIND_INFO UnwindInfo;
360  ULONG_PTR CodeOffset;
361  ULONG i;
362  UNWIND_CODE UnwindCode;
363  BYTE Reg;
364 
365  /* Use relative virtual address */
366  ControlPc -= ImageBase;
367 
368  /* Sanity checks */
369  if ( (ControlPc < FunctionEntry->BeginAddress) ||
370  (ControlPc >= FunctionEntry->EndAddress) )
371  {
372  return NULL;
373  }
374 
375  /* Get a pointer to the unwind info */
376  UnwindInfo = RVA(ImageBase, FunctionEntry->UnwindData);
377 
378  /* Calculate relative offset to function start */
379  CodeOffset = ControlPc - FunctionEntry->BeginAddress;
380 
381  /* Check if we are in the function epilog and try to finish it */
382  if (CodeOffset > UnwindInfo->SizeOfProlog)
383  {
384  if (RtlpTryToUnwindEpilog(Context, ImageBase, FunctionEntry))
385  {
386  /* There's no exception routine */
387  return NULL;
388  }
389  }
390 
391  /* Skip all Ops with an offset greater than the current Offset */
392  i = 0;
393  while (i < UnwindInfo->CountOfCodes &&
394  CodeOffset < UnwindInfo->UnwindCode[i].CodeOffset)
395  {
396  UnwindCode = UnwindInfo->UnwindCode[i];
397  switch (UnwindCode.UnwindOp)
398  {
399  case UWOP_SAVE_NONVOL:
400  case UWOP_SAVE_XMM:
401  case UWOP_SAVE_XMM128:
402  i += 2;
403  break;
404 
406  case UWOP_SAVE_XMM_FAR:
408  i += 3;
409  break;
410 
411  case UWOP_ALLOC_LARGE:
412  i += UnwindCode.OpInfo ? 3 : 2;
413  break;
414 
415  default:
416  i++;
417  }
418  }
419 
420  /* Process the remaining unwind ops */
421  while (i < UnwindInfo->CountOfCodes)
422  {
423  UnwindCode = UnwindInfo->UnwindCode[i];
424  switch (UnwindCode.UnwindOp)
425  {
426  case UWOP_PUSH_NONVOL:
427  Reg = UnwindCode.OpInfo;
428  SetReg(Context, Reg, *(DWORD64*)Context->Rsp);
429  Context->Rsp += sizeof(DWORD64);
430  i++;
431  break;
432 
433  case UWOP_ALLOC_LARGE:
434  if (UnwindCode.OpInfo)
435  {
436  ULONG Offset = *(ULONG*)(&UnwindInfo->UnwindCode[i+1]);
437  Context->Rsp += Offset;
438  i += 3;
439  }
440  else
441  {
442  USHORT Offset = UnwindInfo->UnwindCode[i+1].FrameOffset;
443  Context->Rsp += Offset * 8;
444  i += 2;
445  }
446  break;
447 
448  case UWOP_ALLOC_SMALL:
449  Context->Rsp += (UnwindCode.OpInfo + 1) * 8;
450  i++;
451  break;
452 
453  case UWOP_SET_FPREG:
454  i++;
455  break;
456 
457  case UWOP_SAVE_NONVOL:
458  i += 2;
459  break;
460 
462  i += 3;
463  break;
464 
465  case UWOP_SAVE_XMM:
466  i += 2;
467  break;
468 
469  case UWOP_SAVE_XMM_FAR:
470  i += 3;
471  break;
472 
473  case UWOP_SAVE_XMM128:
474  i += 2;
475  break;
476 
478  i += 3;
479  break;
480 
481  case UWOP_PUSH_MACHFRAME:
482  i += 1;
483  break;
484  }
485  }
486 
487  /* Unwind is finished, pop new Rip from Stack */
488  Context->Rip = *(DWORD64*)Context->Rsp;
489  Context->Rsp += sizeof(DWORD64);
490 
491  return 0;
492 }
493 
494 VOID
495 NTAPI
497  _In_opt_ PVOID TargetFrame,
498  _In_opt_ PVOID TargetIp,
499  _In_opt_ PEXCEPTION_RECORD ExceptionRecord,
502  _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable)
503 {
504  __debugbreak();
505  return;
506 }
507 
508 VOID
509 NTAPI
511  IN PVOID TargetFrame,
512  IN PVOID TargetIp,
513  IN PEXCEPTION_RECORD ExceptionRecord,
515 {
517  return;
518 }
519 
520 ULONG
521 NTAPI
523  IN ULONG Count,
524  IN ULONG Flags)
525 {
527  ULONG64 ControlPc, ImageBase, EstablisherFrame;
528  ULONG64 StackLow, StackHigh;
529  PVOID HandlerData;
530  ULONG i, FramesToSkip;
531  PRUNTIME_FUNCTION FunctionEntry;
532 
533  DPRINT("Enter RtlWalkFrameChain\n");
534 
535  /* The upper bits in Flags define how many frames to skip */
536  FramesToSkip = Flags >> 8;
537 
538  /* Capture the current Context */
540  ControlPc = Context.Rip;
541 
542  /* Get the stack limits */
543  RtlpGetStackLimits(&StackLow, &StackHigh);
544 
545  /* Check if we want the user-mode stack frame */
546  if (Flags & 1)
547  {
548  }
549 
550  /* Loop the frames */
551  for (i = 0; i < FramesToSkip + Count; i++)
552  {
553  /* Lookup the FunctionEntry for the current ControlPc */
554  FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL);
555 
556  /* Is this a leaf function? */
557  if (!FunctionEntry)
558  {
559  Context.Rip = *(DWORD64*)Context.Rsp;
560  Context.Rsp += sizeof(DWORD64);
561  DPRINT("leaf funtion, new Rip = %p, new Rsp = %p\n", (PVOID)Context.Rip, (PVOID)Context.Rsp);
562  }
563  else
564  {
566  ImageBase,
567  ControlPc,
568  FunctionEntry,
569  &Context,
570  &HandlerData,
572  NULL);
573  DPRINT("normal funtion, new Rip = %p, new Rsp = %p\n", (PVOID)Context.Rip, (PVOID)Context.Rsp);
574  }
575 
576  /* Check if new Rip is valid */
577  if (!Context.Rip)
578  {
579  break;
580  }
581 
582  /* Check, if we have left our stack */
583  if ((Context.Rsp < StackLow) || (Context.Rsp > StackHigh))
584  {
585  break;
586  }
587 
588  /* Continue with new Rip */
589  ControlPc = Context.Rip;
590 
591  /* Save value, if we are past the frames to skip */
592  if (i >= FramesToSkip)
593  {
594  Callers[i - FramesToSkip] = (PVOID)ControlPc;
595  }
596  }
597 
598  DPRINT("RtlWalkFrameChain returns %ld\n", i);
599  return i;
600 }
601 
605 #undef RtlGetCallersAddress
606 VOID
607 NTAPI
609  OUT PVOID *CallersAddress,
610  OUT PVOID *CallersCaller )
611 {
612  PVOID Callers[4];
613  ULONG Number;
614 
615  /* Get callers:
616  * RtlWalkFrameChain -> RtlGetCallersAddress -> x -> y */
617  Number = RtlWalkFrameChain(Callers, 4, 0);
618 
619  *CallersAddress = (Number >= 3) ? Callers[2] : NULL;
620  *CallersCaller = (Number == 4) ? Callers[3] : NULL;
621 
622  return;
623 }
624 
625 // FIXME: move to different file
626 VOID
627 NTAPI
629 {
632  ULONG64 ImageBase;
633  PRUNTIME_FUNCTION FunctionEntry;
634  PVOID HandlerData;
636 
637  /* Capture the context */
639 
640  /* Get the function entry for this function */
641  FunctionEntry = RtlLookupFunctionEntry(Context.Rip,
642  &ImageBase,
643  NULL);
644 
645  /* Check if we found it */
646  if (FunctionEntry)
647  {
648  /* Unwind to the caller of this function */
650  ImageBase,
651  Context.Rip,
652  FunctionEntry,
653  &Context,
654  &HandlerData,
656  NULL);
657 
658  /* Save the exception address */
659  ExceptionRecord->ExceptionAddress = (PVOID)Context.Rip;
660 
661  /* Write the context flag */
662  Context.ContextFlags = CONTEXT_FULL;
663 
664  /* Check if user mode debugger is active */
666  {
667  /* Raise an exception immediately */
668  Status = ZwRaiseException(ExceptionRecord, &Context, TRUE);
669  }
670  else
671  {
672  /* Dispatch the exception and check if we should continue */
673  if (!RtlDispatchException(ExceptionRecord, &Context))
674  {
675  /* Raise the exception */
676  Status = ZwRaiseException(ExceptionRecord, &Context, FALSE);
677  }
678  else
679  {
680  /* Continue, go back to previous context */
682  }
683  }
684  }
685 
686  /* If we returned, raise a status */
688 }
689 
#define UWOP_ALLOC_LARGE
Definition: unwind.c:20
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
ASMGENDATA Table[]
Definition: genincdata.c:61
#define TRUE
Definition: types.h:120
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
Definition: ntbasedef.h:660
UBYTE FrameOffset
Definition: unwind.c:52
static BOOLEAN __inline RtlpTryToUnwindEpilog(PCONTEXT Context, ULONG64 ImageBase, PRUNTIME_FUNCTION FunctionEntry)
Helper function that tries to unwind epilog instructions.
Definition: unwind.c:232
void FORCEINLINE SetReg(PCONTEXT Context, BYTE Reg, DWORD64 Value)
Definition: unwind.c:198
struct _RUNTIME_FUNCTION RUNTIME_FUNCTION
VOID NTAPI RtlUnwindEx(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue, _In_ PCONTEXT ContextRecord, _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable)
Definition: unwind.c:496
ULONG NTAPI RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags)
Definition: unwind.c:522
VOID NTAPI RtlGetCallersAddress(OUT PVOID *CallersAddress, OUT PVOID *CallersCaller)
Definition: unwind.c:608
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI ZwRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context, _In_ BOOLEAN SearchFrames)
BYTE UnwindOp
Definition: cpu_x86_64.c:54
#define _Outptr_
Definition: no_sal2.h:396
struct _UNWIND_INFO * PUNWIND_INFO
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
PEXCEPTION_ROUTINE NTAPI RtlVirtualUnwind(_In_ ULONG HandlerType, _In_ ULONG64 ImageBase, _In_ ULONG64 ControlPc, _In_ PRUNTIME_FUNCTION FunctionEntry, _Inout_ PCONTEXT Context, _Outptr_ PVOID *HandlerData, _Out_ PULONG64 EstablisherFrame, _Inout_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers)
Definition: unwind.c:349
#define CONTEXT_FULL
Definition: compat.h:270
PRUNTIME_FUNCTION NTAPI RtlLookupFunctionTable(IN DWORD64 ControlPc, OUT PDWORD64 ImageBase, OUT PULONG Length)
Locates the table of RUNTIME_FUNCTION entries for a code address.
Definition: unwind.c:77
PVOID NTAPI RtlPcToFileHeader(IN PVOID PcValue, PVOID *BaseOfImage)
Definition: libsupp.c:616
NTSYSAPI VOID NTAPI RtlCaptureContext(_Out_ PCONTEXT ContextRecord)
#define UWOP_SAVE_XMM
Definition: unwind.c:25
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
#define _In_opt_
Definition: no_sal2.h:213
void FORCEINLINE PopReg(PCONTEXT Context, BYTE Reg)
Definition: unwind.c:212
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI RtlInstallFunctionTableCallback(IN DWORD64 TableIdentifier, IN DWORD64 BaseAddress, IN DWORD Length, IN PGET_RUNTIME_FUNCTION_CALLBACK Callback, IN PVOID Context, IN PCWSTR OutOfProcessCallbackDll)
Definition: unwind.c:184
NTSYSAPI NTSTATUS NTAPI ZwContinue(_In_ PCONTEXT Context, _In_ BOOLEAN TestAlert)
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 HandlerType
Definition: acpixf.h:801
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
UBYTE UnwindOp
Definition: unwind.c:39
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
UINT32 void void ** ReturnValue
Definition: acevents.h:213
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define STATUS_INVALID_DISPOSITION
Definition: ntstatus.h:261
#define UWOP_SAVE_XMM_FAR
Definition: unwind.c:26
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define FORCEINLINE
Definition: ntbasedef.h:221
#define _Out_
Definition: no_sal2.h:323
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
UBYTE Flags
Definition: unwind.c:48
EXCEPTION_ROUTINE * PEXCEPTION_ROUTINE
Definition: compat.h:369
NTSYSAPI BOOLEAN NTAPI RtlDispatchException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context)
Definition: except.c:34
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define UWOP_SET_FPREG
Definition: unwind.c:22
#define UWOP_PUSH_NONVOL
Definition: unwind.c:19
if(!(yy_init))
Definition: macro.lex.yy.c:714
VOID NTAPI RtlUnwind(IN PVOID TargetFrame, IN PVOID TargetIp, IN PEXCEPTION_RECORD ExceptionRecord, IN PVOID ReturnValue)
Definition: unwind.c:510
UBYTE Version
Definition: unwind.c:47
UBYTE FrameRegister
Definition: unwind.c:51
unsigned long DWORD
Definition: ntddk_ex.h:95
#define _Inout_
Definition: no_sal2.h:244
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
unsigned char UBYTE
Definition: lzx.c:48
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define UWOP_SAVE_XMM128_FAR
Definition: unwind.c:28
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
Definition: ntbasedef.h:661
unsigned __int64 ULONG64
Definition: imports.h:198
UBYTE OpInfo
Definition: unwind.c:40
BOOLEAN NTAPI RtlpCheckForActiveDebugger(VOID)
Definition: libsupp.c:25
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
unsigned char BYTE
Definition: mem.h:68
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
VOID NTAPI RtlpGetStackLimits(PULONG_PTR StackBase, PULONG_PTR StackLimit)
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
UNWIND_CODE UnwindCode[1]
Definition: cpu_x86_64.c:68
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
#define RVA(m, b)
Definition: freeldr.h:24
#define UWOP_PUSH_MACHFRAME
Definition: unwind.c:29
UBYTE SizeOfProlog
Definition: unwind.c:49
USHORT FrameOffset
Definition: cpu_x86_64.c:57
#define UWOP_SAVE_XMM128
Definition: unwind.c:27
BOOLEAN NTAPI RtlDeleteFunctionTable(IN PRUNTIME_FUNCTION FunctionTable)
Definition: unwind.c:175
uint64_t DWORD64
Definition: typedefs.h:65
unsigned short USHORT
Definition: pedump.c:61
union _UNWIND_CODE * PUNWIND_CODE
PRUNTIME_FUNCTION NTAPI RtlLookupFunctionEntry(IN DWORD64 ControlPc, OUT PDWORD64 ImageBase, OUT PUNWIND_HISTORY_TABLE HistoryTable)
Locates the RUNTIME_FUNCTION entry corresponding to a code address. http://msdn.microsoft....
Definition: unwind.c:112
struct _UNWIND_INFO UNWIND_INFO
unsigned int * PULONG
Definition: retypes.h:1
UBYTE CodeOffset
Definition: unwind.c:38
DWORD64 FORCEINLINE GetReg(PCONTEXT Context, BYTE Reg)
Definition: unwind.c:205
#define UWOP_SAVE_NONVOL
Definition: unwind.c:23
#define UWOP_ALLOC_SMALL
Definition: unwind.c:21
#define OUT
Definition: typedefs.h:39
#define UWOP_SAVE_NONVOL_FAR
Definition: unwind.c:24
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
uint64_t * PDWORD64
Definition: typedefs.h:65
#define UNIMPLEMENTED
Definition: debug.h:114
BOOLEAN NTAPI RtlAddFunctionTable(IN PRUNTIME_FUNCTION FunctionTable, IN DWORD EntryCount, IN DWORD64 BaseAddress)
Definition: unwind.c:164
static WLX_DISPATCH_VERSION_1_4 FunctionTable
Definition: wlx.c:736
unsigned __int64 * PULONG64
Definition: imports.h:198
LPFNPSPCALLBACK Callback
Definition: desk.c:111
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION
Definition: pedump.c:262
UBYTE CountOfCodes
Definition: unwind.c:50
VOID NTAPI RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord)
Definition: unwind.c:628
unsigned char UBYTE
Definition: unwind.c:32
union _UNWIND_CODE UNWIND_CODE
#define UNW_FLAG_NHANDLER
Definition: gs_support.c:32