Source code of Windows XP (NT5)
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.

158 lines
4.0 KiB

  1. ;***
  2. ;longjmp.asm
  3. ;
  4. ; Copyright (C) 1994-2001, Microsoft Corporation. All rights reserved.
  5. ;
  6. ;Purpose:
  7. ; Contains setjmp(), longjmp() & raisex() routines;
  8. ; split from exsup.asm for granularity purposes.
  9. ;
  10. ;Notes:
  11. ;
  12. ;Revision History:
  13. ; 01-12-94 PML Split from setjmp.asm, added C9.0 generic EH
  14. ; callback for unwind.
  15. ; 01-11-95 SKS Remove MASM 5.X support
  16. ; 04-11-95 JWM Added NLG support
  17. ; 06-07-95 JWM __SetNLGCode() used, for multithread safety.
  18. ; 06-20-95 JWM __SetNLGCode() removed, code passed on stack (11803).
  19. ;
  20. ;*******************************************************************************
  21. ;hnt = -D_WIN32 -Dsmall32 -Dflat32 -Mx $this;
  22. ;Define small32 and flat32 since these are not defined in the NT build process
  23. small32 equ 1
  24. flat32 equ 1
  25. .xlist
  26. include pversion.inc
  27. ?DFDATA = 1
  28. ?NODATA = 1
  29. include cmacros.inc
  30. include exsup.inc
  31. .list
  32. BeginDATA
  33. COMM __setjmpexused:dword
  34. EndDATA
  35. extern __NLG_Destination:_NLG_INFO
  36. assumes DS,DATA
  37. assumes FS,DATA
  38. BeginCODE
  39. ; Following symbols defined in exsup.asm, sehsupp.c
  40. extrn __except_list:near
  41. extrn __global_unwind2:near
  42. extrn __local_unwind2:near
  43. extrn __rt_probe_read4@4:near
  44. extrn __NLG_Notify:near
  45. ;EXTERN C __SetNLGCode:near
  46. ; int
  47. ; longjmp (
  48. ; IN jmp_buf env
  49. ; IN int val)
  50. ;
  51. ; Routine Description:
  52. ;
  53. ; Restore the stack and register environment saved by _setjmp.
  54. ; Reloads callee-save registers and stack pointer to that saved in
  55. ; the jmp_buf, then returns to the point of the _setjmp call.
  56. ;
  57. ; If exception unwinding is enabled, also reload the exception state
  58. ; from the jmp_buf by doing an unwind (both global and local) back
  59. ; to the old state. Do so by checking for a new-format (C9.0)
  60. ; jmp_buf, and call the EH longjmp unwinder saved therein if
  61. ; found, else assume a C8.0-vintage jmp_buf and SEH.
  62. ;
  63. ; Arguments:
  64. ;
  65. ; env - Address of the buffer holding the reload state
  66. ; val - Value to return from the _setjmp callsite (if nonzero)
  67. ;
  68. ; Return Value:
  69. ;
  70. ; None. longjmp does not return directly, but instead continues
  71. ; execution from the point of the _setjmp used to initialize the
  72. ; jmp_buf. That call will return the 'val' parameter if nonzero,
  73. ; else a one.
  74. cProc longjmp,<C,PUBLIC>
  75. cBegin
  76. mov ebx, [esp+4] ;get jmp_buf
  77. ;restore ebp before possible call to local_unwind-er
  78. ; the call to global/local unwind will preserve this (callee save).
  79. mov ebp, [ebx.saved_ebp] ;set up bp
  80. ifdef _NTSDK
  81. cmp __setjmpexused, 0
  82. je short _lj_no_unwind
  83. endif
  84. mov esi, [ebx.saved_xregistration]
  85. cmp esi, dword ptr fs:__except_list
  86. je short _lj_local_unwind
  87. push esi
  88. call __global_unwind2
  89. add esp,4
  90. _lj_local_unwind:
  91. cmp esi, 0
  92. je short _lj_no_unwind
  93. ; Check if called with old or new format jmp_buf. Look for the
  94. ; version cookie that's only present in the new format.
  95. lea eax, [ebx.version_cookie]
  96. push eax
  97. call __rt_probe_read4@4
  98. or eax, eax
  99. jz short _lj_old_unwind
  100. mov eax, [ebx.version_cookie]
  101. cmp eax, JMPBUF_COOKIE
  102. jnz short _lj_old_unwind
  103. ; Called with a new-format jmp_buf. Call unwind function supplied
  104. ; to the jmp_buf at setjmp time.
  105. mov eax, [ebx.unwind_func]
  106. or eax, eax
  107. jz short _lj_no_unwind ;no local unwind necessary
  108. push ebx
  109. call eax
  110. jmp short _lj_no_unwind
  111. ; Called with an old-format jmp_buf. Duplicate old longjmp behavior,
  112. ; assuming there's a C8.0 SEH node at top.
  113. _lj_old_unwind:
  114. mov eax, [ebx.saved_trylevel]
  115. push eax
  116. push esi
  117. call __local_unwind2
  118. add esp, 8
  119. _lj_no_unwind:
  120. push 0h
  121. mov eax, [ebx.saved_return]
  122. call __NLG_Notify
  123. mov edx, ebx
  124. mov ebx, [edx.saved_ebx] ;recover registers...
  125. mov edi, [edx.saved_edi]
  126. mov esi, [edx.saved_esi]
  127. mov eax, [esp+8] ;load the return value
  128. cmp eax, 1 ;make sure it's not 0
  129. adc eax, 0
  130. mov esp, [edx.saved_esp] ;here, sp gets scorched
  131. add esp, 4 ;punt the (old) return address
  132. jmp [edx.saved_return] ;return
  133. cEnd
  134. EndCODE
  135. END