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.

257 lines
8.4 KiB

  1. ;***
  2. ;exsup2.asm
  3. ;
  4. ; Copyright (c) 1994-2001, Microsoft Corporation. All rights reserved.
  5. ;
  6. ;Purpose:
  7. ; Exception handling for i386. This is just the C8.0 version of
  8. ; the language-specific exception handler. The C9.0 version is
  9. ; found in exsup3.asm, and the routines common to both C8 and C9
  10. ; are found in exsup.asm.
  11. ;
  12. ;Notes:
  13. ;
  14. ;Revision History:
  15. ; 01-10-94 PML Created with __except_handler2 from exsup.asm
  16. ; 01-11-95 SKS Remove MASM 5.X support
  17. ;
  18. ;*******************************************************************************
  19. ;hnt = -D_WIN32 -Dsmall32 -Dflat32 -Mx $this;
  20. ;Define small32 and flat32 since these are not defined in the NT build process
  21. small32 equ 1
  22. flat32 equ 1
  23. .xlist
  24. include pversion.inc
  25. ?DFDATA = 1
  26. ?NODATA = 1
  27. include cmacros.inc
  28. include exsup.inc
  29. .list
  30. ;REVIEW: can we get rid of _global_unwind2, and just use
  31. ; the C runtimes version, _global_unwind?
  32. extrn __global_unwind2:near
  33. extrn __local_unwind2:near
  34. ;typedef struct _EXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION;
  35. ;struct _EXCEPTION_REGISTRATION{
  36. ; struct _EXCEPTION_REGISTRATION *prev;
  37. ; void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_REGISTRATION, PCONTEXT, PEXCEPTION_RECORD);
  38. ; struct scopetable_entry *scopetable;
  39. ; int trylevel;
  40. ; int _ebp;
  41. ; PEXCEPTION_POINTERS xpointers;
  42. ;};
  43. _C8_EXCEPTION_REGISTRATION struc ; C8.0 version
  44. dd ? ; prev (common)
  45. dd ? ; handler (common)
  46. ;private:
  47. scopetable dd ?
  48. trylevel dd ?
  49. _ebp dd ?
  50. xpointers dd ?
  51. _C8_EXCEPTION_REGISTRATION ends
  52. ;#define EXCEPTION_MAXIMUM_PARAMETERS 4
  53. ;typedef struct _EXCEPTION_RECORD EXCEPTION_RECORD;
  54. ;typedef EXCEPTION_RECORD *PEXCEPTION_RECORD;
  55. ;struct _EXCEPTION_RECORD{
  56. ; NTSTATUS ExceptionCode;
  57. ; ULONG ExceptionFlags;
  58. ; struct _EXCEPTION_RECORD *ExceptionRecord;
  59. ; PVOID ExceptionAddress;
  60. ; ULONG NumberParameters;
  61. ; ULONG ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
  62. ;};
  63. _EXCEPTION_RECORD struc
  64. exception_number dd ?
  65. exception_flags dd ?
  66. exception_record dd ?
  67. exception_address dd ?
  68. number_parameters dd ?
  69. exception_information dd 4 dup(?)
  70. _EXCEPTION_RECORD ends
  71. SIZEOF_EXCEPTION_RECORD equ 36
  72. ;/* following is the structure returned by the _exception_info() intrinsic. */
  73. ;typedef struct _EXCEPTION_POINTERS EXCEPTION_POINTERS;
  74. ;typedef struct EXCEPTION_POINTERS *PEXCEPTION_POINTERS;
  75. ;struct _EXCEPTION_POINTERS{
  76. ; PEXCEPTION_RECORD ExceptionRecord;
  77. ; PCONTEXT Context;
  78. ;};
  79. _EXCEPTION_POINTERS struc
  80. ep_xrecord dd ?
  81. ep_context dd ?
  82. _EXCEPTION_POINTERS ends
  83. SIZEOF_EXCEPTION_POINTERS equ 8
  84. assumes DS,DATA
  85. assumes FS,DATA
  86. __except_list equ 0
  87. ;struct _SCOPETABLE_ENTRY{
  88. ; int enclosing_level; /* lexical level of enclosing scope */
  89. ; int (*filter)(PEXCEPTION_RECORD); /* NULL for a termination handler */
  90. ; void (*specific_handler)(void); /* xcpt or termination handler */
  91. ;};
  92. ;struct _SCOPETABLE_ENTRY Scopetable[NUMTRYS];
  93. _SCOPETABLE_ENTRY struc
  94. enclosing_level dd ?
  95. filter dd ?
  96. specific_handler dd ?
  97. _SCOPETABLE_ENTRY ends
  98. BeginCODE
  99. ;/* _EXCEPT_HANDLER2 - Try to find an exception handler listed in the scope
  100. ; * table associated with the given registration record, that wants to accept
  101. ; * the current exception. If we find one, run it (and never return).
  102. ; * RETURNS: (*if* it returns)
  103. ; * DISPOSITION_DISMISS - dismiss the exception.
  104. ; * DISPOSITION_CONTINUE_SEARCH - pass the exception up to enclosing handlers
  105. ; */
  106. ;int _except_handler2(
  107. ; PEXCEPTION_RECORD exception_record,
  108. ; PEXCEPTION_REGISTRATION registration,
  109. ; PCONTEXT context,
  110. ; PEXCEPTION_REGISTRATION dispatcher)
  111. ;{
  112. ; int ix, filter_result;
  113. ;
  114. ; for(ix=registration->trylevel; ix!=-1; ix=registration->xscope[ix].enclosing_level){
  115. ; /* if filter==NULL, then this is an entry for a termination handler */
  116. ; if(registration->xscope[ix].filter){
  117. ; /* NB: call to the filter may trash the callee save
  118. ; registers. (this is *not* a standard cdecl function) */
  119. ; filter_result=(*registration->xscope[ix].filter)(xinfo);
  120. ; if(filter_result==FILTER_DISMISS)
  121. ; return(-1); /* dismiss */
  122. ; if(filter_result==FILTER_ACCEPT){
  123. ; _global_unwind2(registration);
  124. ; _local_unwind2(registration, ix);
  125. ; (*registration->xscope[ix].specific_handler)(void);
  126. ; assert(UNREACHED); /*should never return from handler*/
  127. ; }
  128. ; assert(filter_result==FILTER_CONTINUE_SEARCH);
  129. ; }
  130. ; }
  131. ; return(0); /* didnt find one */
  132. ;}
  133. db 'VC10' ;; VC/C++ 1.0/32-bit (C8.0) version
  134. db 'XC00' ;; so debugger can recognize this proc (cuda:3936)
  135. cProc _except_handler2,<C,PUBLIC>,<IBX,ISI,IDI,IBP>
  136. parmDP xrecord
  137. parmDP registration
  138. parmDP context
  139. parmDP dispatcher
  140. localV xp,SIZEOF_EXCEPTION_POINTERS
  141. cBegin
  142. ;4*4b for callee saves + 4b return address + 4b param = 24
  143. ;DF in indeterminate state at time of exception, so clear it
  144. cld
  145. mov ebx, registration ;ebx= PEXCEPTION_REGISTRATION
  146. mov eax, xrecord
  147. test [eax.exception_flags], EXCEPTION_UNWIND_CONTEXT
  148. jnz short _lh_unwinding
  149. ;build the EXCEPTION_POINTERS locally store its address in the
  150. ; registration record. this is the pointer that is returned by
  151. ; the _eception_info intrinsic.
  152. mov xp.ep_xrecord, eax
  153. mov eax, context
  154. mov xp.ep_context, eax
  155. lea eax, xp
  156. mov [ebx.xpointers], eax
  157. mov esi, [ebx.trylevel] ;esi= try level
  158. mov edi, [ebx.scopetable] ;edi= scope table base
  159. _lh_top:
  160. cmp esi, -1
  161. je short _lh_bagit
  162. lea ecx, [esi+esi*2] ;ecx= trylevel*3
  163. cmp dword ptr [(edi+ecx*4).filter], 0
  164. je short _lh_continue ;term handler, so keep looking
  165. ;filter may trash *all* registers, so save ebp and scopetable offset
  166. push esi
  167. push ebp
  168. mov ebp, [ebx._ebp]
  169. call [(edi+ecx*4).filter] ;call the filter
  170. pop ebp
  171. pop esi
  172. ;ebx may have been trashed by the filter, so we must reload
  173. mov ebx, registration
  174. ; Accept <0, 0, >0 instead of just -1, 0, +1
  175. or eax, eax
  176. jz short _lh_continue
  177. js short _lh_dismiss
  178. ;assert(eax==FILTER_ACCEPT)
  179. ;reload xscope base, cuz it was trashed by the filter call
  180. mov edi, [ebx.scopetable]
  181. ;load handler address before we loose components of address mode
  182. push ebx ;registration*
  183. call __global_unwind2 ;run term handlers
  184. add esp, 4
  185. ;setup ebp for the local unwinder and the specific handler
  186. mov ebp, [ebx._ebp]
  187. ;the stop try level == accepting except level
  188. push esi ;stop try level
  189. push ebx ;registration*
  190. call __local_unwind2
  191. add esp, 8
  192. lea ecx, [esi+esi*2] ;ecx=trylevel*3
  193. ; set the current trylevel to our enclosing level immediately
  194. ; before giving control to the handler. it is the enclosing
  195. ; level, if any, that guards the handler.
  196. mov eax, [(edi+ecx*4).enclosing_level]
  197. mov [ebx.trylevel], eax
  198. call [(edi+ecx*4).specific_handler] ;call the except handler
  199. ;assert(0) ;(NB! should not return)
  200. _lh_continue:
  201. ;reload the scope table base, possibly trashed by call to filter
  202. mov edi, [ebx.scopetable]
  203. lea ecx, [esi+esi*2]
  204. mov esi, [edi+ecx*4+0] ;load the enclosing trylevel
  205. jmp short _lh_top
  206. _lh_dismiss:
  207. mov eax, DISPOSITION_DISMISS ;dismiss the exception
  208. jmp short _lh_return
  209. _lh_bagit:
  210. mov eax, DISPOSITION_CONTINUE_SEARCH
  211. jmp short _lh_return
  212. _lh_unwinding:
  213. push ebp
  214. mov ebp, [ebx._ebp]
  215. push -1
  216. push ebx
  217. call __local_unwind2
  218. add esp, 8
  219. pop ebp
  220. ;the return value is not really relevent in an unwind context
  221. mov eax, DISPOSITION_CONTINUE_SEARCH
  222. _lh_return:
  223. cEnd
  224. EndCODE
  225. END