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.

183 lines
6.2 KiB

  1. /***
  2. *dbgstk.c - debug check stack routine
  3. *
  4. * Copyright (c) 1986-1995, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * This module contains a debug impelmentation of the standard _chkstk
  8. * for i386. It will do the standard stack probe (code copied from
  9. * VC5 CRT) and then call a debug routine which will have the oportunity
  10. * top spew the stack before it gets initialized (or not).
  11. *
  12. *******************************************************************************/
  13. #include "headers.hxx"
  14. #if defined(USE_STACK_SPEW) && defined(_X86_)
  15. #pragma check_stack(off)
  16. static BOOL g_fStackSpewEnabled = FALSE;
  17. static DWORD g_dwSpew = 0x0;
  18. extern "C" void __declspec(naked) __cdecl _chkstk()
  19. {
  20. _asm
  21. {
  22. ; First probe the stack. We do this because
  23. ; we don't want to write past the stack guard page
  24. ; Note that this code came from the original
  25. ; c run time source.
  26. push ecx ; save ecx
  27. push eax ; save eax (size of stack needed)
  28. cmp eax,1000h ; more than one page requested?
  29. lea ecx,[esp] + 12 ; compute new stack pointer in ecx
  30. ; correct for return address and
  31. ; saved ecx, eax
  32. jb short lastpage ; no
  33. probepages:
  34. sub ecx,1000h ; yes, move down a page
  35. sub eax,1000h ; adjust request and...
  36. test dword ptr [ecx],eax ; ...probe it
  37. cmp eax,1000h ; more than one page requested?
  38. jae short probepages ; no
  39. lastpage:
  40. sub ecx,eax ; move stack down by eax
  41. mov eax,esp ; save current tos and do a...
  42. test dword ptr [ecx],eax ; ...probe in case a page was crossed
  43. ; Now set up and write our data into the area of the stack
  44. ; that was opened up
  45. lea esp,[ecx] - 12 ; set the stack pointer to the bottom
  46. ; leave room 12 in padding so we don't
  47. ; clobber ourselves
  48. mov ecx,dword ptr [eax+8] ; recover return address
  49. push ecx
  50. cmp g_fStackSpewEnabled,0 ; see if we are enabled
  51. mov ecx,dword ptr [eax+4] ; recover original ecx
  52. je done ; not enabled
  53. push ecx ; save original ecx
  54. pushfd ; save flags
  55. std ; set DI: decr edi after stosd
  56. mov ecx,dword ptr [eax] ; recover original eax (stack size)
  57. push edi ; save edi on stack also
  58. lea edi,[eax]+8 ; load up iterator start address
  59. shr ecx,2 ; get count of dwords
  60. mov eax,g_dwSpew ; load up value
  61. rep stosd ; let 'er rip
  62. pop edi ; pop saved edi
  63. popfd ; pop flags
  64. pop ecx ; pop saved ecx
  65. done:
  66. ret 12 ; return, popping off 12 padding
  67. }
  68. }
  69. // NOTE: _alloca_probe is impelemented exactly the same as _chkstk
  70. // I'd like to find some way to merge these two pieces of code but I
  71. // don't know how with inline assembly...
  72. extern "C" void __declspec(naked) __cdecl _alloca_probe()
  73. {
  74. _asm
  75. {
  76. ; First probe the stack. We do this because
  77. ; we don't want to write past the stack guard page
  78. ; Note that this code came from the original
  79. ; c run time source.
  80. push ecx ; save ecx
  81. push eax ; save eax (size of stack needed)
  82. cmp eax,1000h ; more than one page requested?
  83. lea ecx,[esp] + 12 ; compute new stack pointer in ecx
  84. ; correct for return address and
  85. ; saved ecx, eax
  86. jb short lastpage ; no
  87. probepages:
  88. sub ecx,1000h ; yes, move down a page
  89. sub eax,1000h ; adjust request and...
  90. test dword ptr [ecx],eax ; ...probe it
  91. cmp eax,1000h ; more than one page requested?
  92. jae short probepages ; no
  93. lastpage:
  94. sub ecx,eax ; move stack down by eax
  95. mov eax,esp ; save current tos and do a...
  96. test dword ptr [ecx],eax ; ...probe in case a page was crossed
  97. ; Now set up and write our data into the area of the stack
  98. ; that was opened up
  99. lea esp,[ecx] - 12 ; set the stack pointer to the bottom
  100. ; leave room 12 in padding so we don't
  101. ; clobber ourselves
  102. mov ecx,dword ptr [eax+8] ; recover return address
  103. push ecx
  104. cmp g_fStackSpewEnabled,0 ; see if we are enabled
  105. mov ecx,dword ptr [eax+4] ; recover original ecx
  106. je done ; not enabled
  107. push ecx ; save original ecx
  108. pushfd ; save flags
  109. std ; set DI: decr edi after stosd
  110. mov ecx,dword ptr [eax] ; recover original eax (stack size)
  111. push edi ; save edi on stack also
  112. lea edi,[eax]+8 ; load up iterator start address
  113. shr ecx,2 ; get count of dwords
  114. mov eax,g_dwSpew ; load up value
  115. rep stosd ; let 'er rip
  116. pop edi ; pop saved edi
  117. popfd ; pop flags
  118. pop ecx ; pop saved ecx
  119. done:
  120. ret 12 ; return, popping off 12 padding
  121. }
  122. }
  123. //
  124. // Initialize the debug stack system
  125. //
  126. extern "C" void
  127. InitChkStk(BOOL dwFill)
  128. {
  129. g_dwSpew = dwFill;
  130. g_fStackSpewEnabled = TRUE;
  131. }
  132. #endif