105 lines
3.2 KiB
ArmAsm
105 lines
3.2 KiB
ArmAsm
|
// TITLE("Runtime Stack Checking")
|
|||
|
//++
|
|||
|
//
|
|||
|
// Copyright (c) 1991 Microsoft Corporation
|
|||
|
//
|
|||
|
// Module Name:
|
|||
|
//
|
|||
|
// chkstk.s
|
|||
|
//
|
|||
|
// Abstract:
|
|||
|
//
|
|||
|
// This module implements runtime stack checking.
|
|||
|
//
|
|||
|
// Author:
|
|||
|
//
|
|||
|
// David N. Cutler (davec) 14-Mar-1991
|
|||
|
//
|
|||
|
// Environment:
|
|||
|
//
|
|||
|
// User mode.
|
|||
|
//
|
|||
|
// Revision History:
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
#include "ksmips.h"
|
|||
|
|
|||
|
SBTTL("Check Stack")
|
|||
|
//++
|
|||
|
//
|
|||
|
// ULONG
|
|||
|
// _RtlCheckStack (
|
|||
|
// IN ULONG Allocation
|
|||
|
// )
|
|||
|
//
|
|||
|
// 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.
|
|||
|
//
|
|||
|
// N.B. This routine is called using a calling sequence that assumes that
|
|||
|
// all registers are preserved.
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Allocation (t8) - Supplies the size of the allocation on the stack.
|
|||
|
//
|
|||
|
// Return Value:
|
|||
|
//
|
|||
|
// None.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
NESTED_ENTRY(_RtlCheckStack, 0, ra)
|
|||
|
|
|||
|
sw t7,0(sp) // save temporary register
|
|||
|
sw t8,4(sp) // save allocation size
|
|||
|
sw t9,8(sp) // save temporary register
|
|||
|
|
|||
|
PROLOGUE_END
|
|||
|
|
|||
|
.set noreorder
|
|||
|
.set noat
|
|||
|
li t9,UsPcr // get address of user PCR
|
|||
|
bgez sp,10f // if gez, running on user stack
|
|||
|
subu t8,sp,t8 // compute new bottom of stack
|
|||
|
|
|||
|
//
|
|||
|
// Running on kernel stack - compute stack limit from initial kernel stack.
|
|||
|
//
|
|||
|
|
|||
|
lw t9,KiPcr + PcInitialStack(zero) // get initial kernel stack
|
|||
|
b 20f // finish in common code
|
|||
|
subu t9,t9,KERNEL_STACK_SIZE // compute low limit of kernel stack
|
|||
|
|
|||
|
//
|
|||
|
// Running on user stack - get stack limit from thread environment block.
|
|||
|
//
|
|||
|
|
|||
|
10: lw t9,PcTeb(t9) // get address of environment block
|
|||
|
nop // fill
|
|||
|
lw t9,TeStackLimit(t9) // get low stack address
|
|||
|
nop // fill
|
|||
|
20: sltu t7,t8,t9 // new stack address within limits?
|
|||
|
beq zero,t7,40f // if eq, stack within limits
|
|||
|
li t7,~(PAGE_SIZE - 1) // set address mask
|
|||
|
and t8,t8,t7 // round down new stack address
|
|||
|
30: subu t9,t9,PAGE_SIZE // compute next address to check
|
|||
|
bne t8,t9,30b // if ne, more pages to probe
|
|||
|
sw zero,0(t9) // check stack address
|
|||
|
40: lw t7,0(sp) // restore temporary register
|
|||
|
lw t8,4(sp) // restore allocation size
|
|||
|
j ra // return
|
|||
|
lw t9,8(sp) // restore temporary register
|
|||
|
.set at
|
|||
|
.set reorder
|
|||
|
|
|||
|
.end _RtlCheckStack
|