windows-nt/Source/XPSP1/NT/sdktools/mtscript/util/dbgstk.cxx
2020-09-26 16:20:57 +08:00

184 lines
6.2 KiB
C++

/***
*dbgstk.c - debug check stack routine
*
* Copyright (c) 1986-1995, Microsoft Corporation. All rights reserved.
*
*Purpose:
* This module contains a debug impelmentation of the standard _chkstk
* for i386. It will do the standard stack probe (code copied from
* VC5 CRT) and then call a debug routine which will have the oportunity
* top spew the stack before it gets initialized (or not).
*
*******************************************************************************/
#include "headers.hxx"
#if defined(USE_STACK_SPEW) && defined(_X86_)
#pragma check_stack(off)
static BOOL g_fStackSpewEnabled = FALSE;
static DWORD g_dwSpew = 0x0;
extern "C" void __declspec(naked) __cdecl _chkstk()
{
_asm
{
; First probe the stack. We do this because
; we don't want to write past the stack guard page
; Note that this code came from the original
; c run time source.
push ecx ; save ecx
push eax ; save eax (size of stack needed)
cmp eax,1000h ; more than one page requested?
lea ecx,[esp] + 12 ; compute new stack pointer in ecx
; correct for return address and
; saved ecx, eax
jb short lastpage ; no
probepages:
sub ecx,1000h ; yes, move down a page
sub eax,1000h ; adjust request and...
test dword ptr [ecx],eax ; ...probe it
cmp eax,1000h ; more than one page requested?
jae short probepages ; no
lastpage:
sub ecx,eax ; move stack down by eax
mov eax,esp ; save current tos and do a...
test dword ptr [ecx],eax ; ...probe in case a page was crossed
; Now set up and write our data into the area of the stack
; that was opened up
lea esp,[ecx] - 12 ; set the stack pointer to the bottom
; leave room 12 in padding so we don't
; clobber ourselves
mov ecx,dword ptr [eax+8] ; recover return address
push ecx
cmp g_fStackSpewEnabled,0 ; see if we are enabled
mov ecx,dword ptr [eax+4] ; recover original ecx
je done ; not enabled
push ecx ; save original ecx
pushfd ; save flags
std ; set DI: decr edi after stosd
mov ecx,dword ptr [eax] ; recover original eax (stack size)
push edi ; save edi on stack also
lea edi,[eax]+8 ; load up iterator start address
shr ecx,2 ; get count of dwords
mov eax,g_dwSpew ; load up value
rep stosd ; let 'er rip
pop edi ; pop saved edi
popfd ; pop flags
pop ecx ; pop saved ecx
done:
ret 12 ; return, popping off 12 padding
}
}
// NOTE: _alloca_probe is impelemented exactly the same as _chkstk
// I'd like to find some way to merge these two pieces of code but I
// don't know how with inline assembly...
extern "C" void __declspec(naked) __cdecl _alloca_probe()
{
_asm
{
; First probe the stack. We do this because
; we don't want to write past the stack guard page
; Note that this code came from the original
; c run time source.
push ecx ; save ecx
push eax ; save eax (size of stack needed)
cmp eax,1000h ; more than one page requested?
lea ecx,[esp] + 12 ; compute new stack pointer in ecx
; correct for return address and
; saved ecx, eax
jb short lastpage ; no
probepages:
sub ecx,1000h ; yes, move down a page
sub eax,1000h ; adjust request and...
test dword ptr [ecx],eax ; ...probe it
cmp eax,1000h ; more than one page requested?
jae short probepages ; no
lastpage:
sub ecx,eax ; move stack down by eax
mov eax,esp ; save current tos and do a...
test dword ptr [ecx],eax ; ...probe in case a page was crossed
; Now set up and write our data into the area of the stack
; that was opened up
lea esp,[ecx] - 12 ; set the stack pointer to the bottom
; leave room 12 in padding so we don't
; clobber ourselves
mov ecx,dword ptr [eax+8] ; recover return address
push ecx
cmp g_fStackSpewEnabled,0 ; see if we are enabled
mov ecx,dword ptr [eax+4] ; recover original ecx
je done ; not enabled
push ecx ; save original ecx
pushfd ; save flags
std ; set DI: decr edi after stosd
mov ecx,dword ptr [eax] ; recover original eax (stack size)
push edi ; save edi on stack also
lea edi,[eax]+8 ; load up iterator start address
shr ecx,2 ; get count of dwords
mov eax,g_dwSpew ; load up value
rep stosd ; let 'er rip
pop edi ; pop saved edi
popfd ; pop flags
pop ecx ; pop saved ecx
done:
ret 12 ; return, popping off 12 padding
}
}
//
// Initialize the debug stack system
//
extern "C" void
InitChkStk(BOOL dwFill)
{
g_dwSpew = dwFill;
g_fStackSpewEnabled = TRUE;
}
#endif