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.

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