summaryrefslogtreecommitdiffstats
path: root/private/crt32/startup/i386/chkstk.asm
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/startup/i386/chkstk.asm')
-rw-r--r--private/crt32/startup/i386/chkstk.asm127
1 files changed, 127 insertions, 0 deletions
diff --git a/private/crt32/startup/i386/chkstk.asm b/private/crt32/startup/i386/chkstk.asm
new file mode 100644
index 000000000..bd05942d5
--- /dev/null
+++ b/private/crt32/startup/i386/chkstk.asm
@@ -0,0 +1,127 @@
+ 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
+ include msdos.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