Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.7 KiB

  1. /***
  2. *throw.cxx - Implementation of the 'throw' command.
  3. *
  4. * Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Implementation of the exception handling 'throw' command.
  8. *
  9. * Entry points:
  10. * * _CxxThrowException - does the throw.
  11. *
  12. *Revision History:
  13. * 05-25-93 BS Module created
  14. * 09-29-94 GJF Made (__)pMyUnhandledExceptionFilter global so the
  15. * compiler (DEC Alpha) wouldn't optimize it away.
  16. * 10-17-94 BWT Disable code for PPC.
  17. * 02-03-95 BWT Remove Alpha export hack.
  18. * 02-09-95 JWM Mac merge.
  19. * 04-13-95 DAK Add NT Kernel EH support
  20. * 04-25-95 DAK More Kernel work
  21. * 03-02-98 RKP Add 64 bit support
  22. * 05-17-99 PML Remove all Macintosh support.
  23. * 03-15-00 PML Remove CC_P7_SOFT25, which is now on permanently.
  24. *
  25. ****/
  26. #include <stddef.h>
  27. #if defined(_NTSUBSET_)
  28. extern "C" {
  29. #include <nt.h>
  30. #include <ntrtl.h>
  31. #include <nturtl.h>
  32. #include <ntstatus.h> // STATUS_UNHANDLED_EXCEPTION
  33. #include <ntos.h>
  34. #include <ex.h> // ExRaiseException
  35. }
  36. #endif
  37. #include <windows.h>
  38. #include <mtdll.h>
  39. #include <ehdata.h>
  40. #include <eh.h>
  41. #include <ehhooks.h>
  42. #include <ehassert.h>
  43. #pragma hdrstop
  44. //
  45. // Make sure PULONG_PTR is available
  46. //
  47. #if defined(_X86_) && _MSC_VER >= 1300
  48. #define _W64 __w64
  49. #else
  50. #define _W64
  51. #endif
  52. #if !defined(PULONG_PTR)
  53. #if defined(_WIN64)
  54. typedef unsigned __int64 * PULONG_PTR;
  55. #else
  56. typedef _W64 unsigned long * PULONG_PTR;
  57. #endif
  58. #endif
  59. #if defined(_M_IA64) || defined(_M_AMD64)
  60. extern "C" PVOID RtlPcToFileHeader(PVOID, PVOID*);
  61. extern "C" PVOID _ReturnAddress(VOID);
  62. #pragma intrinsic(_ReturnAddress)
  63. #endif
  64. //
  65. // Make sure the terminate wrapper is dragged in:
  66. //
  67. #if defined(_NTSUBSET_)
  68. void * __pMyUnhandledExceptionFilter = 0;
  69. #else
  70. void * __pMyUnhandledExceptionFilter = &__CxxUnhandledExceptionFilter;
  71. #endif
  72. /////////////////////////////////////////////////////////////////////////////
  73. //
  74. // _CxxThrowException - implementation of 'throw'
  75. //
  76. // Description:
  77. // Builds the NT Exception record, and calls the NT runtime to initiate
  78. // exception processing.
  79. //
  80. // Why is pThrowInfo defined as _ThrowInfo? Because _ThrowInfo is secretly
  81. // snuck into the compiler, as is the prototype for _CxxThrowException, so
  82. // we have to use the same type to keep the compiler happy.
  83. //
  84. // Another result of this is that _CRTIMP can't be used here. Instead, we
  85. // synthesisze the -export directive below.
  86. //
  87. // Returns:
  88. // NEVER. (until we implement resumable exceptions, that is)
  89. //
  90. extern "C" void __stdcall _CxxThrowException(
  91. void* pExceptionObject, // The object thrown
  92. #if _MSC_VER >= 900 /*IFSTRIP=IGN*/
  93. _ThrowInfo* pThrowInfo // Everything we need to know about it
  94. #else
  95. ThrowInfo* pThrowInfo // Everything we need to know about it
  96. #endif
  97. ) {
  98. EHTRACE_ENTER_FMT1("Throwing object @ 0x%p", pExceptionObject);
  99. static const EHExceptionRecord ExceptionTemplate = { // A generic exception record
  100. EH_EXCEPTION_NUMBER, // Exception number
  101. EXCEPTION_NONCONTINUABLE, // Exception flags (we don't do resume)
  102. NULL, // Additional record (none)
  103. NULL, // Address of exception (OS fills in)
  104. EH_EXCEPTION_PARAMETERS, // Number of parameters
  105. { EH_MAGIC_NUMBER1, // Our version control magic number
  106. NULL, // pExceptionObject
  107. NULL,
  108. #if defined(_M_IA64) || defined (_M_AMD64)
  109. NULL // Image base of thrown object
  110. #endif
  111. } // pThrowInfo
  112. };
  113. EHExceptionRecord ThisException = ExceptionTemplate; // This exception
  114. //
  115. // Fill in the blanks:
  116. //
  117. ThisException.params.pExceptionObject = pExceptionObject;
  118. ThisException.params.pThrowInfo = (ThrowInfo*)pThrowInfo;
  119. #if defined(_M_IA64) || defined(_M_AMD64)
  120. PVOID ThrowImageBase = RtlPcToFileHeader(_ReturnAddress(), &ThrowImageBase);
  121. ThisException.params.pThrowImageBase = ThrowImageBase;
  122. #endif
  123. //
  124. // Hand it off to the OS:
  125. //
  126. EHTRACE_EXIT;
  127. #if defined(_M_AMD64)
  128. RtlRaiseException( (PEXCEPTION_RECORD) &ThisException );
  129. #else
  130. #if defined(_NTSUBSET_)
  131. ExRaiseException( (PEXCEPTION_RECORD) &ThisException );
  132. #else
  133. RaiseException( ThisException.ExceptionCode,
  134. ThisException.ExceptionFlags,
  135. ThisException.NumberParameters,
  136. (PULONG_PTR)&ThisException.params );
  137. #endif
  138. #endif
  139. }