Leaked source code of windows server 2003
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.

128 lines
3.8 KiB

  1. /***
  2. *ehprolg2.c - Defines _EH_prolog2 compiler helper
  3. *
  4. * Copyright (c) 1999-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * EH prologue helper function for an aligned stack.
  8. *
  9. *Revision History:
  10. * 11-14-99 JB Module created
  11. * 03-18-02 PML Disable warning about unsafe FS:0 modifications
  12. *
  13. ****/
  14. #pragma warning(disable:4733) // ignore unsafe FS:0 modifications
  15. /***
  16. *void _EH_prolog2(alignment) - set up aligned stack with EH frame
  17. *
  18. *Purpose:
  19. * Sets up an aligned frame for a C++ EH function with unwinds, by
  20. * creating a link in the __except_list, setting EBX as the frame
  21. * parameter pointer, and EBP as the frame base pointer.
  22. *
  23. *Entry:
  24. * EAX = address of EH handler thunk
  25. * Incoming stack frame has:
  26. * [ESP + 8] = callee's return address
  27. * [ESP + 4] = stack alignment requirement
  28. * [ESP + 0] = _EH_prolog2's return address
  29. *
  30. *Exit:
  31. * EAX = destroyed
  32. * EBX = pointer to callee's parameters
  33. * EBP = aligned pointer to callee's locals
  34. * ESP = EBP - 12
  35. * FS:[0] = set to EBP-8 to create new link in EH chain
  36. * Stack frame has been set up as follows:
  37. * [EBX + 4] = (entry [ESP+8]) callee's return address
  38. * [EBX + 0] = saved EBX
  39. * padding to align stack (if needed)
  40. * [EBP + 4] = callee's return address (from [EBX+4])
  41. * [EBP + 0] = saved EBP
  42. * [EBP - 4] = EH record state index, initialized to -1
  43. * [EBP - 8] = address of EH handler thunk
  44. * [EBP - 12] = saved FS:[0]
  45. *
  46. *Exceptions:
  47. *
  48. *******************************************************************************/
  49. #ifdef __cplusplus
  50. extern "C"
  51. #endif
  52. void __declspec(naked) _EH_prolog2(void)
  53. {
  54. /*
  55. * We want to generate a frame that is equivalent to
  56. * push ebx
  57. * ebx = esp
  58. * sub esp, 8
  59. * and esp, ~alignment
  60. * add esp, 4
  61. * push ebp
  62. * ebp = esp
  63. * mov [ebp+4], [ebx+4]
  64. * [EH record]
  65. */
  66. __asm {
  67. ; stack has:
  68. ; alignment
  69. ; ret addr <== esp
  70. push ecx ; save ecx
  71. ; with ret addr == sub esp, 8
  72. ; stack has:
  73. ; alignment
  74. ; ret addr
  75. ; saved ecx <== esp
  76. mov ecx, [esp+8] ; get alignment
  77. mov [esp+8], ebx ; save ebx over alignment
  78. lea ebx, [esp+8] ; set param pointer
  79. ; stack has:
  80. ; saved ebx <== ebx
  81. ; ret addr
  82. ; saved ecx <== esp
  83. neg ecx ; create alignment mask
  84. and esp, ecx ; align stack
  85. mov ecx, [ebx-8] ; restore ecx since it will be in the same
  86. ; location we want to store ebp if no
  87. ; padding is inserted (esp is aligned at and)
  88. mov [esp], ebp ; save ebp
  89. mov ebp, esp ; initialize ebp
  90. ; stack has
  91. ; saved ebx <== ebx
  92. ; ret addr
  93. ; [padding]
  94. ; saved ebp <== ebp, esp
  95. push -1 ; create EH record
  96. push eax
  97. mov eax,fs:[00000000]
  98. push eax
  99. mov dword ptr fs:[0],esp
  100. push ecx ; we need this again
  101. mov eax, [ebx-4] ; get helper return address
  102. mov ecx, [ebx+4] ; copy orig function caller return address
  103. mov [ebp+4], ecx ; (for ebp-based stack walks)
  104. pop ecx ; we are done
  105. push eax ; eax has return address
  106. ret
  107. }
  108. }