windows-nt/Source/XPSP1/NT/com/ole32/common/cruntime/i386/chkstk.asm

127 lines
3.8 KiB
NASM
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
page ,132
title chkstk - C stack checking routine
;***
;chkstk.asm - C stack checking routine
;
; Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
;
;Purpose:
; Provides support for automatic stack checking in C procedures
; when stack checking is enabled.
;
;Revision History:
; 04-21-87 SKS Added conditional assembly switch for STKHQQ = 0
; 07-23-87 MAG [1] Added run-time CS:IP error processing for QC
; 08-17-87 JLS [2] Remove all references to DGROUP
; 08-25-87 JLS [3] Shift include files
; 11-13-87 SKS OS/2 Reentrant version, add thread ID check
; 11-18-87 SKS Make STKHQQ an array (oops!)
; 12-14-87 SKS add .286p to allow PUSH immediate value
; 02-19-88 SKS Change minimum bottom limit to STACKSLOP, not 0
; 06-01-88 PHG Merge DLL and normal versions
; 09-21-88 WAJ initial 386 version
; 10-18-88 JCR Chkstk was trashing bx... not good on 386
; 06-06-89 JCR 386 mthread support
; 06-20-89 JCR 386: Removed _LOAD_DGROUP code
; 04-06-90 GJF Fixed the copyright.
; 06-21-90 GJF Rewritten to probe pages
; 10-15-90 GJF Restored _end and STKHQQ.
; 03-19-91 GJF Revised to preserve all registers except eax. Note
; this is _rchkstk functionality so there is no longer
; a separate _rchkstk routine.
; 08-01-91 GJF Got rid of _end and STKHQQ, except for Cruiser
; (probably not needed for Cruiser either) [_WIN32_].
; 09-27-91 JCR Merged Stevewo' changes from NT tree
;
;*******************************************************************************
.xlist
include cruntime.inc
.list
; size of a page of memory
_PAGESIZE_ equ 1000h
ifdef _CRUISER_
.data
extrn pascal _end:dword ; stack bottom
ifndef MTHREAD
public pascal STKHQQ ; used by parasitic heap
STKHQQ dd dataoffset _end+STACKSLOP ; initial value
endif ;MTHREAD
endif ;_CRUISER_
CODESEG
page
;***
;_chkstk - check stack upon procedure entry
;
;Purpose:
; Provide stack checking on procedure entry. Method is to simply probe
; each page of memory required for the stack in descending order. This
; causes the necessary pages of memory to be allocated via the guard
; page scheme, if possible. In the event of failure, the OS raises the
; _XCPT_UNABLE_TO_GROW_STACK exception.
;
; NOTE: Currently, the (EAX < _PAGESIZE_) code path falls through
; to the "lastpage" label of the (EAX >= _PAGESIZE_) code path. This
; is small; a minor speed optimization would be to special case
; this up top. This would avoid the painful save/restore of
; ecx and would shorten the code path by 4-6 instructions.
;
;Entry:
; EAX = size of local frame
;
;Exit:
; ESP = new stackframe, if successful
;
;Uses:
; EAX
;
;Exceptions:
; _XCPT_GUARD_PAGE_VIOLATION - May be raised on a page probe. NEVER TRAP
; THIS!!!! It is used by the OS to grow the
; stack on demand.
; _XCPT_UNABLE_TO_GROW_STACK - The stack cannot be grown. More precisely,
; the attempt by the OS memory manager to
; allocate another guard page in response
; to a _XCPT_GUARD_PAGE_VIOLATION has
; failed.
;
;*******************************************************************************
labelP _alloca_probe, PUBLIC
labelP _chkstk, PUBLIC
push ecx ; save ecx
mov ecx,esp ; compute new stack pointer in ecx
add ecx,8 ; correct for return address and saved
; ecx value
probepages:
cmp eax,_PAGESIZE_ ; more than one page requested?
jb short lastpage ; no
sub ecx,_PAGESIZE_ ; yes, move down a page and...
or dword ptr [ecx],0 ; ...probe it
sub eax,_PAGESIZE_ ; adjust request
jmp probepages
lastpage:
sub ecx,eax ; move stack down by eax and do a...
or dword ptr [ecx],0 ; ...probe in case a page was crossed
mov eax,esp ; save pointer to current tos
mov esp,ecx ; set the new stack pointer
mov ecx,dword ptr [eax] ; recover ecx
mov eax,dword ptr [eax + 4] ; recover return address
jmp eax ; return
end