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.

106 lines
3.0 KiB

  1. .file "chkstk.s"
  2. /* _chkstk - check stack upon procedure entry
  3. ;Purpose:
  4. ; Provide stack checking on procedure entry. Method is to simply probe
  5. ; each page of memory required for the stack in descending order. This
  6. ; causes the necessary pages of memory to be allocated via the guard
  7. ; page scheme, if possible. In the event of failure, the OS raises the
  8. ; _XCPT_UNABLE_TO_GROW_STACK exception.
  9. ;
  10. ; The link register is b7 to avoid conflicts with linker thunks.
  11. ;
  12. ;
  13. ;Entry:
  14. ; r26: Size of the storage to allocate
  15. ; (This is rounded up to the next multiple of 16)
  16. ;
  17. ;Exit:
  18. ;
  19. ;
  20. ;*******************************************************************************
  21. */
  22. #include "ksia64.h"
  23. .section .text
  24. .align 32
  25. LEAF_ENTRY(__chkstk)
  26. ALTERNATE_ENTRY(__alloca_probe)
  27. .prologue
  28. cond_reg1 = p6
  29. cond_discard = p0
  30. return_branch_register = b7
  31. argument_reg = r26
  32. discard_reg = r27
  33. new_stack_pointer = r28
  34. page_size_reg = r29
  35. alloc_size_reg = r30
  36. .altrp return_branch_register
  37. mov discard_reg = 15
  38. mov page_size_reg = PAGE_SIZE
  39. // load page size into a register, we'll need to use it again.
  40. add alloc_size_reg=15,argument_reg
  41. // Make sure the requested size is = 0 mod 16: round up
  42. ;;
  43. .body
  44. mov new_stack_pointer = sp
  45. // Save the stack pointer to a different register for manipulation
  46. // new_stack_pointer is scratch
  47. andcm alloc_size_reg=alloc_size_reg,discard_reg
  48. // setting the lower four bits to zero
  49. ;;
  50. cmp.le cond_reg1,p0 = alloc_size_reg, page_size_reg
  51. // assume greater than 1 page most of the time.
  52. (cond_reg1) br.cond.dpnt ._last_page
  53. // if size is <= 1 page, branch to
  54. ._probepages:
  55. sub alloc_size_reg = alloc_size_reg,page_size_reg
  56. // The size is more than 1 page, subtract a page from sp
  57. sub new_stack_pointer = new_stack_pointer,page_size_reg
  58. ;;
  59. // Do we still have more than 1 page?
  60. cmp.gt cond_reg1,cond_discard = alloc_size_reg, page_size_reg
  61. ;;
  62. // Use non-temporal locality hint so the cache is not polluted
  63. ld8.nta discard_reg = [new_stack_pointer] // probe it
  64. (cond_reg1) br.cond.dpnt ._probepages
  65. ;;
  66. // .mmi
  67. ._last_page:
  68. sub new_stack_pointer = new_stack_pointer, alloc_size_reg
  69. ;;
  70. // subtract the last piecemill, which is in alloc_size_reg.
  71. // the new stack pointer.
  72. ld8.nta discard_reg = [new_stack_pointer] // probe it.
  73. // If we are here, everything is ok.
  74. br.ret.dpnt return_branch_register
  75. LEAF_EXIT(__chkstk)