|
|
/***
*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
|