diff options
Diffstat (limited to 'private/crt32/startup/ppc')
-rw-r--r-- | private/crt32/startup/ppc/chkstk.s | 190 | ||||
-rw-r--r-- | private/crt32/startup/ppc/sources | 3 |
2 files changed, 193 insertions, 0 deletions
diff --git a/private/crt32/startup/ppc/chkstk.s b/private/crt32/startup/ppc/chkstk.s new file mode 100644 index 000000000..ceec550f7 --- /dev/null +++ b/private/crt32/startup/ppc/chkstk.s @@ -0,0 +1,190 @@ +// TITLE("C-Runtime Stack Checking") +//++ +// +// Copyright (c) 1993,1994 IBM Corporation +// +// Module Name: +// +// chkstk.s +// +// Abstract: +// +// This module implements runtime stack checking. +// +// Author: +// +// Mark D. Johnson +// +// Environment: +// +// User/Kernel mode. +// +// Revision History: +// +//-- + +#include <ksppc.h> + + + SBTTL("Check Stack") +//++ +// +// VOID _RtlCheckStack(in ULONG n_alloc) +// +// Routine Description: +// +// This function provides runtime stack checking for local allocations +// that are more than a page and for storage dynamically allocated with +// the alloca function. Stack checking consists of probing downward in +// the stack a page at a time. If the current stack commitment is exceeded, +// then the system will automatically attempt to expand the stack. If the +// attempt succeeds, then another page is committed. Otherwise, a stack +// overflow exception is raised. It is the responsiblity of the caller to +// handle this exception. +// +// Two entry points are supported. The first/standard entry point +// calls for n_alloc to be passed as single argument (in r.3). In +// the second case, the single argument is the negative of the amount +// requested (the amount by which to decrement the stack pointer), and +// is passed in r.12. +// +// Registers r.0 and r.11 are modified. +// +// Arguments: +// +// n_alloc(r.3/r.12) - Supplies the size of the allocation on the stack. +// With standard entry, passed in r.3. In alternate +// entry, passed in r.12. In the latter case (r.12) +// the value supplied is the quanitity by which to +// decrement r.sp (a negative value). +// +// Return Value: +// +// None. +// +// Assumptions: +// +// The value of Teb_Ptr is provided in r.13. +// +// The bottom of stack "bot" (r.11) is multiple of PAGE_SIZE. +// + +// +// low +// : +// | : +// | | +// | | +// |.......|<--- r.sp + r.12 - (PAGE_SIZE-1) +// | ^ | +// | |< -|- - - - - - always < PAGE_SIZE +// | v | +// +-------+<--- bot - m*PAGE_SIZE +// | | +// | : | +// | | +// +-------+<--- r.sp + r.12 +// | | +// | | +// | | +// | : | +// | : | +// | : | +// | : | +// | | +// | | +// | | +// | | +// +=======+<--- bottom of stack "bot" (r.11) +// | | +// | | +// | | +// | : | +// | : | +// | : | +// | | +// | | +// +-------+<--- r.sp +// | | +// | | +// | : | +// | : +// | : high +// : m is count for add'l pages to commit +// +// +// m:=max(0,{bot-[(r.sp+r.12)-(PAGE_SIZE-1)]}/PAGE_SIZE) +// =max(0,bot-[r.12-(PAGE_SIZE-1)+r.sp])/PAGE_SIZE +// +// Operands in expression [r.12-(PAGE_SIZE-1)+r.sp) are known upon entry +// to routine. This intermediate quantity is calculated early in r.0, +// behind user/kernel mode test. + + + .text + .align 5 + + // want entry for _RtlCheckStack aligned on a 2**5-1 byte boundary so that + // more commonly used (internal) entry _RtlCheckStack.12 is aligned on + // 2**5 byte (cache-line) boundary ... and most often used code fits in + // single cache-line + + or r.11, r.11, r.11; or r.11, r.11, r.11 + or r.11, r.11, r.11; or r.11, r.11, r.11 + + or r.11, r.11, r.11; or r.11, r.11, r.11 + or r.11, r.11, r.11; or r.11, r.11, r.11 + + or r.11, r.11, r.11; or r.11, r.11, r.11 + or r.11, r.11, r.11; or r.11, r.11, r.11 + + or r.11, r.11, r.11; or r.11, r.11, r.11 + or r.11, r.11, r.11 + + LEAF_ENTRY(_RtlCheckStack) + + neg r.12,r.3 + + ALTERNATE_ENTRY(_RtlCheckStack.12) + + cmpwi r.sp,0 // user or kernel mode? + + // partial comp of num pages to commit moved here for performance + + subi r.0,r.12,(PAGE_SIZE-1) + add r.0,r.0,r.sp + + bge+ UsrMode // sp >=0 indicates user mode + + // kernel mode, KIPCR is system mode macro to get KiPcr + + KIPCR(r.11) + lwz r.11,PcInitialStack(r.11) + subi r.11,r.11,KERNEL_STACK_SIZE + b CommonCode + +UsrMode: + + // r.13 contains the TEB pointer + + lwz r.11,TeStackLimit(r.13) // Get low stack address + +CommonCode: + + // r.11 contains computed "bot" of stack + + sub r.0,r.11,r.0 + srawi. r.0,r.0,PAGE_SHIFT // Number pages to add/commit + blelr // if <=0, return + + mtctr r.0 + +PageLoop: + + // Attempt to commit pages beyond the limit + + lwzu r.0,-PAGE_SIZE(r.11) + bdnz PageLoop + + + LEAF_EXIT(_RtlCheckStack) diff --git a/private/crt32/startup/ppc/sources b/private/crt32/startup/ppc/sources new file mode 100644 index 000000000..d82d03db9 --- /dev/null +++ b/private/crt32/startup/ppc/sources @@ -0,0 +1,3 @@ +PPC_SOURCES=ppc\chkstk.s + + |