Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
.file "chkstk.s"
/* _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.
;
; The link register is b7 to avoid conflicts with linker thunks.
;
;
;Entry:
; r26: Size of the storage to allocate
; (This is rounded up to the next multiple of 16)
;
;Exit:
;
;
;*******************************************************************************
*/ #include "ksia64.h"
.section .text .align 32
LEAF_ENTRY(__chkstk) ALTERNATE_ENTRY(__alloca_probe)
.prologue
cond_reg1 = p6 cond_discard = p0
return_branch_register = b7
argument_reg = r26 discard_reg = r27 new_stack_pointer = r28 page_size_reg = r29 alloc_size_reg = r30
.altrp return_branch_register
mov discard_reg = 15 mov page_size_reg = PAGE_SIZE // load page size into a register, we'll need to use it again.
add alloc_size_reg=15,argument_reg // Make sure the requested size is = 0 mod 16: round up ;;
.body
mov new_stack_pointer = sp // Save the stack pointer to a different register for manipulation // new_stack_pointer is scratch
andcm alloc_size_reg=alloc_size_reg,discard_reg // setting the lower four bits to zero
;;
cmp.le cond_reg1,p0 = alloc_size_reg, page_size_reg // assume greater than 1 page most of the time.
(cond_reg1) br.cond.dpnt ._last_page // if size is <= 1 page, branch to
._probepages: sub alloc_size_reg = alloc_size_reg,page_size_reg
// The size is more than 1 page, subtract a page from sp sub new_stack_pointer = new_stack_pointer,page_size_reg ;;
// Do we still have more than 1 page? cmp.gt cond_reg1,cond_discard = alloc_size_reg, page_size_reg ;;
// Use non-temporal locality hint so the cache is not polluted ld8.nta discard_reg = [new_stack_pointer] // probe it (cond_reg1) br.cond.dpnt ._probepages ;;
// .mmi ._last_page: sub new_stack_pointer = new_stack_pointer, alloc_size_reg ;;
// subtract the last piecemill, which is in alloc_size_reg. // the new stack pointer.
ld8.nta discard_reg = [new_stack_pointer] // probe it.
// If we are here, everything is ok. br.ret.dpnt return_branch_register
LEAF_EXIT(__chkstk)
|