Ignore:
Timestamp:
Apr 18, 2012, 10:46:37 PM (13 years ago)
Author:
dmik
Message:

kernel32: Make SEH work in OS/2 context.

See #82 for details.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/seh/sehutil.s

    r21916 r21999  
    88
    99.global ___seh_handler
    10 .global ___seh_get_prev_frame
     10.global ___seh_handler_filter
     11.global ___seh_handler_win32
     12.global ___seh_get_prev_frame_win32
     13
     14#define sizeof_WINEXCEPTION_RECORD 80
     15#define sizeof_WINCONTEXT          296
    1116
    1217/*
    1318 * extern "C"
    14  * int __seh_handler(PEXCEPTION_RECORD pRec,
     19 * int __seh_handler(PEXCEPTIONREPORTRECORD pRec,
    1520 *                   struct ___seh_EXCEPTION_FRAME *pFrame,
    16  *                   PCONTEXT pContext, PVOID)
    17  *
    18  * Win32 structured exception handler that implements the __try/__except
    19  * functionality for GCC.
     21 *                   PCONTEXTRECORD pContext, PVOID)
     22 *
     23 * OS/2 exception handler that implements the __try/__except
     24 * functionality for GCC in non-ODIN_FORCE_WIN32_TIB mode.
    2025 *
    2126 * NOTE: This is a heavily platform specific stuff. The code depends on the
     
    2631 * the stack.
    2732 */
    28 
    2933___seh_handler:
    3034
    31     pushl %ebp
    32     movl %esp, %ebp
     35    /* call the common handler to do the job */
     36    jmp OS2ExceptionHandler2ndLevel
     37
     38/*
     39 * extern "C"
     40 * BOOL __seh_handler_filter(PEXCEPTIONREPORTRECORD pRec,
     41 *                           struct ___seh_EXCEPTION_FRAME *pFrame,
     42 *                           PCONTEXTRECORD pContext)
     43 *
     44 * Calls the filter expression of the __try/__except block
     45 * in non-ODIN_FORCE_WIN32_TIB mode.
     46 *
     47 * Return TRUE if the filter asks to continue execution and FALSE
     48 * otherwise. Note that if the filter chooses to execute the __except block,
     49 * this function does not return.
     50 *
     51 * NOTE: This is a heavily platform specific stuff. The code depends on the
     52 * struct ___seh_EXCEPTION_FRAME layout so be very careful and keep both
     53 * in sync!
     54 *
     55 * __cdecl: EAX/ECX/EDX are not preserved, result in EAX/EDX, caller cleans up
     56 * the stack.
     57 */
     58
     59___seh_handler_filter:
    3360
    3461    /*
     
    3663     * 12(%ebp) - pFrame
    3764     * 16(%ebp) - pContext
    38      * 20(%ebp) - pVoid
    3965     */
     66
     67    pushl %ebp
     68    movl %esp, %ebp
    4069
    4170    /* preserve used registers */
     
    4473    pushl %esi
    4574
    46     movl %fs, %eax
    47     andl $0x0000FFFF, %eax
    48     cmpl $Dos32TIB, %eax /* Running along the OS/2 chain? */
    49     jne ___seh_handler_Win32 /* No, assume the Win32 chain */
    50 
    51     /* Note: Unwinding is disabled here since a) it is more correct to do
    52      * centralized unwinding from OS2ExceptionHandler2ndLevel() (i.e. not only
    53      * for SEH frames) and b) it crashes under SMP kernel due to stack being
    54      * corrupt by the time when unwinding happens. See comments in
    55      * OS2ExceptionHandler2ndLevel() for more details. */
    56 
    57 #if 0
    58 
    59     movl 8(%ebp), %eax
    60     movl 4(%eax), %eax /* fHandlerFlags */
    61     testl $0x02, %eax  /* EH_UNWINDING? */
    62     jne ___seh_handler_OS2_Unwind
    63 
    64     /* restore the OS/2 chain in our frame */
    65     movl 12(%ebp), %eax
    66     movl 44(%eax), %ecx /* pPrevFrameOS2 */
    67     movl %ecx, 0(%eax)  /* pPrev */
    68 
    69     xorl %eax, %eax  /* return XCPT_CONTINUE_SEARCH (0) */
    70     jmp ___seh_handler_Return
    71 
    72 ___seh_handler_OS2_Unwind:
    73 
    74     /* unwind the Win32 chain including our frame as someone's definitely
    75      * jumping outside it if we're being unwound by OS/2 */
    76     movl 12(%ebp), %eax
    77     cmpl $0, 64(%eax)                   /* Win32FS == 0? */
    78     je ___seh_handler_OS2_Unwind_End    /* Yes, we already unwound this frame */
    79 
    80     /* restore the Win32 chain in our frame */
    81     movl 60(%eax), %ebx /* pPrevFrameWin32 */
    82     movl %ebx, 0(%eax)  /* pPrev */
    83 
    84     pushl %fs
    85 
    86     pushl 64(%eax)  /* Win32FS */
    87     popl %fs
    88 
    89     pushl $0        /* DWORD (unused) */
    90     pushl $0        /* PEXCEPTION_RECORD */
    91     pushl $0        /* LPVOID (unused) */
    92     pushl %ebx      /* PEXCEPTION_FRAME */
    93     call _RtlUnwind@16 /* _stdcall, rtl, callee cleans stack */
    94 
    95     popl %fs
    96 
    97     /* restore the OS/2 chain in our frame */
    98     movl 12(%ebp), %eax
    99     movl 44(%eax), %ecx /* pPrevFrameOS2 */
    100     movl %ecx, 0(%eax)  /* pPrev */
    101 
    102 ___seh_handler_OS2_Unwind_End:
    103 
    104     xor %eax, %eax  /* return code is irrelevant for EH_UNWINDING */
    105     jmp ___seh_handler_Return
    106 
    107 #else
    108 
    109     /* restore the OS/2 chain in our frame */
    110     movl 12(%ebp), %eax
    111     movl 44(%eax), %ecx /* pPrevFrameOS2 */
    112     movl %ecx, 0(%eax)  /* pPrev */
    113 
    114     xorl %eax, %eax  /* return XCPT_CONTINUE_SEARCH (0) */
    115     jmp ___seh_handler_Return
    116 
    117 #endif
    118 
    119 ___seh_handler_Win32:
    120 
    121     /* restore the Win32 chain in our frame */
    122     movl 12(%ebp), %eax
    123     movl 60(%eax), %ecx /* pPrevFrameWin32 */
    124     movl %ecx, 0(%eax)  /* pPrev */
    125 
    126     /* skip EH_UNWINDING calls (for compatibility with MSVC) */
    127     movl 8(%ebp), %ebx
    128     movl 4(%ebx), %eax                      /* pRec->ExceptionFlags */
    129     testl $0x2, %eax                        /* EH_UNWINDING? */
    130     je ___seh_handler_Win32_NotUnwinding    /* No, continue normally */
    131 
    132     /* See the comment above */
    133 #if 0
    134     /* clear out the Win32FS field so that we will not attempt to unwind twice
    135      * (first, as a result of forced unwind from ExitProcess/ExitThread/etc and
    136      * then from the OS/2 EH_UNWINDING call of our handler) */
    137     movl 12(%ebp), %eax
    138     movl $0, 64(%eax)   /* Win32FS */
    139 #endif
    140 
    141     movl $1, %eax /* ExceptionContinueSearch */
    142     jmp ___seh_handler_Return
    143 
    144 ___seh_handler_Win32_NotUnwinding:
    145 
    14675    /* save handler's context */
    14776    pushl %ebp
     
    15382
    15483    /* get the size of the handler's stack */
    155     movl 40(%ebx), %ecx /* pFrame->pTryRegs[4] is ESP */
     84    movl 40(%ebx), %ecx /* pFrame->ESP */
    15685    subl %esp, %ecx
    15786    jle ___seh_handler_Error /* Invalid stack! */
    15887    movl %ecx, 4(%esp) /* save length */
    15988
    160     /* check that EXCEPTION_RECORD and CONTEXT are on our stack
    161      * and save their offsets in pFrame */
    162     movl 8(%ebp), %eax
    163     subl %esp, %eax
    164     jl ___seh_handler_Error /* Invalid stack! */
    165     cmpl %ecx, %eax
    166     jg ___seh_handler_Error /* Invalid stack! */
    167     movl %eax, 48(%ebx) /* pFrame->Pointers.ExceptionRecord */
    168 
    169     movl 16(%ebp), %eax
    170     subl %esp, %eax
    171     jl ___seh_handler_Error /* Invalid stack! */
    172     cmpl %ecx, %eax
    173     jg ___seh_handler_Error /* Invalid stack! */
    174     movl %eax, 52(%ebx) /* pFrame->Pointers.ContextRecord */
    175 
    17689    /* save the handler's stack on heap */
    17790    movl %ecx, %eax /* size_t */
     91    /* also reserve space for Win32 exeption info structs */
     92    addl $(sizeof_WINEXCEPTION_RECORD + sizeof_WINCONTEXT), %eax
    17893    subl $4, %esp
    17994    movl %eax, 0(%esp)
     
    188103    rep movsb
    189104
    190     /* correct Pointers offsets to point to the saved stack on heap */
     105    /* convert OS/2 exception info -> Win32 */
     106    movl 16(%ebx), %eax          /* pFrame->pHandlerContext */
     107    addl 4(%esp), %eax           /* + size of stack = ptr to WINCONTEXT */
     108    movl %eax, 48(%ebx)          /* pFrame->Pointers.ContextRecord */
     109    addl $sizeof_WINCONTEXT, %eax/* = ptr to WINEXCEPTION_RECORD */
     110    movl %eax, 44(%ebx)          /* pFrame->Pointers.ExceptionRecord */
     111    pushl $0                     /* TEB* */
     112    pushl 48(%ebx)               /* WINCONTEXT */
     113    pushl 44(%ebx)               /* WINEXCEPTION_RECORD */
     114    pushl 16(%ebp)               /* pContext */
     115    pushl 8(%ebp)                /* pRec */
     116    call OSLibConvertExceptionInfo
     117    addl $20, %esp
     118    jne ___seh_handler_CallFilter/* conversion successful? */
     119
     120    /* free heap block */
    191121    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
    192     addl %eax, 48(%ebx) /* pFrame->Pointers.ExceptionRecord */
    193     addl %eax, 52(%ebx) /* pFrame->Pointers.ContextRecord */
     122    subl $4, %esp
     123    movl %eax, 0(%esp)
     124    call _free /* __cdecl (and _Optlink compatible -> EAX/EDX/ECX-in) */
     125    addl $4, %esp
     126    jmp ___seh_handler_Error /* Info conversion error! */
     127
     128___seh_handler_CallFilter:
    194129
    195130    /* restore __try/__catch context */
    196131    movl 12(%ebp), %eax
    197     movl 24(%eax), %ebx /* pFrame->pTryRegs */
    198     movl 28(%eax), %esi
    199     movl 32(%eax), %edi
    200     movl 36(%eax), %ebp
    201     movl 40(%eax), %esp
     132    movl 24(%eax), %ebx /* pFrame->EBX */
     133    movl 28(%eax), %esi /* pFrame->ESI */
     134    movl 32(%eax), %edi /* pFrame->EDI */
     135    movl 36(%eax), %ebp /* pFrame->EBP */
     136    movl 40(%eax), %esp /* pFrame->ESP */
    202137
    203138    /* jump to the filter callback */
    204     movl $1, 56(%eax) /* pFrame->state */
     139    movl $1, 52(%eax) /* pFrame->state */
    205140    jmp *8(%eax) /* pFrame->pFilterCallback */
    206141
     
    232167    cmpl $-1, %eax /* EXCEPTION_CONTINUE_EXECUTION? */
    233168    jne 1f
    234     movl $0, 56(%ebx) /* pFrame->state */
    235     movl $0, %eax /* ExceptionContinueExecution */
     169    movl $0, 52(%ebx) /* pFrame->state */
     170    //movl $-1, %eax /* XCPT_CONTINUE_EXECUTION (-1) */
     171    movl $1, %eax
    236172    jmp ___seh_handler_Return
    2371731:
    238174    /* assume EXCEPTION_CONTINUE_SEARCH (0) */
     175    xorl %eax, %eax /* return XCPT_CONTINUE_SEARCH (0) */
     176    jmp ___seh_handler_Return
     177
     178___seh_handler_Unwind:
     179
     180    /* unwind OS/2 exception chain up to ours */
     181    pushl $0        /* PEXCEPTIONREPORTRECORD */
     182    pushl $1f       /* PVOID pTargetIP */
     183    pushl 12(%ebp)  /* PEXCEPTIONREGISTRATIONRECORD */
     184    call _DosUnwindException /* _syscall, rtl, but stack is not restored! */
     1851:
     186    /* restore __try/__except context */
     187    movl 12(%ebp), %eax
     188    movl 24(%eax), %ebx
     189    movl 28(%eax), %esi
     190    movl 32(%eax), %edi
     191    movl 36(%eax), %ebp
     192    movl 40(%eax), %esp
     193
     194    /* jump to __except */
     195    movl $2, 52(%eax) /* pFrame->state */
     196    jmp *8(%eax) /* pFrame->pFilterCallback */
     197
     198___seh_handler_Error:
     199
     200    addl $8, %esp
     201    popl %ebp
     202
     203    xorl %eax, %eax  /* return XCPT_CONTINUE_SEARCH (0) */
     204
     205___seh_handler_Return:
     206
     207    popl %esi
     208    popl %edi
     209    popl %ebx
     210
     211    popl %ebp
     212    ret
     213
     214/*
     215 * extern "C"
     216 * int __seh_handler_win32(PEXCEPTION_RECORD pRec,
     217 *                         struct ___seh_EXCEPTION_FRAME *pFrame,
     218 *                         PCONTEXT pContext, PVOID)
     219 *
     220 * Win32 structured exception handler that implements the __try/__except
     221 * functionality for GCC in ODIN_FORCE_WIN32_TIB mode.
     222 *
     223 * NOTE: This is a heavily platform specific stuff. The code depends on the
     224 * struct ___seh_EXCEPTION_FRAME layout so be very careful and keep both
     225 * in sync!
     226 *
     227 * __cdecl: EAX/ECX/EDX are not preserved, result in EAX/EDX, caller cleans up
     228 * the stack.
     229 */
     230
     231___seh_handler_win32:
     232
     233    pushl %ebp
     234    movl %esp, %ebp
     235
     236    /*
     237     * 8(%ebp)  - pRec
     238     * 12(%ebp) - pFrame
     239     * 16(%ebp) - pContext
     240     * 20(%ebp) - pVoid
     241     */
     242
     243    /* preserve used registers */
     244    pushl %ebx
     245    pushl %edi
     246    pushl %esi
     247
     248    movl %fs, %eax
     249    andl $0x0000FFFF, %eax
     250    cmpl $Dos32TIB, %eax /* Running along the OS/2 chain? */
     251    jne __seh_handler_win32_Win32 /* No, assume the Win32 chain */
     252
     253    /* Note: Unwinding is disabled here since a) it is more correct to do
     254     * centralized unwinding from OS2ExceptionHandler2ndLevel() (i.e. not only
     255     * for SEH frames) and b) it crashes under SMP kernel due to stack being
     256     * corrupt by the time when unwinding happens. See comments in
     257     * OS2ExceptionHandler2ndLevel() for more details. */
     258
     259#if 0
     260
     261    movl 8(%ebp), %eax
     262    movl 4(%eax), %eax /* fHandlerFlags */
     263    testl $0x02, %eax  /* EH_UNWINDING? */
     264    jne __seh_handler_win32_OS2_Unwind
     265
     266    /* restore the OS/2 chain in our frame */
     267    movl 12(%ebp), %eax
     268    movl 44(%eax), %ecx /* pPrevFrameOS2 */
     269    movl %ecx, 0(%eax)  /* pPrev */
     270
     271    xorl %eax, %eax  /* return XCPT_CONTINUE_SEARCH (0) */
     272    jmp __seh_handler_win32_Return
     273
     274__seh_handler_win32_OS2_Unwind:
     275
     276    /* unwind the Win32 chain including our frame as someone's definitely
     277     * jumping outside it if we're being unwound by OS/2 */
     278    movl 12(%ebp), %eax
     279    cmpl $0, 64(%eax)                   /* Win32FS == 0? */
     280    je __seh_handler_win32_OS2_Unwind_End    /* Yes, we already unwound this frame */
     281
     282    /* restore the Win32 chain in our frame */
     283    movl 60(%eax), %ebx /* pPrevFrameWin32 */
     284    movl %ebx, 0(%eax)  /* pPrev */
     285
     286    pushl %fs
     287
     288    pushl 64(%eax)  /* Win32FS */
     289    popl %fs
     290
     291    pushl $0        /* DWORD (unused) */
     292    pushl $0        /* PEXCEPTION_RECORD */
     293    pushl $0        /* LPVOID (unused) */
     294    pushl %ebx      /* PEXCEPTION_FRAME */
     295    call _RtlUnwind@16 /* _stdcall, rtl, callee cleans stack */
     296
     297    popl %fs
     298
     299    /* restore the OS/2 chain in our frame */
     300    movl 12(%ebp), %eax
     301    movl 44(%eax), %ecx /* pPrevFrameOS2 */
     302    movl %ecx, 0(%eax)  /* pPrev */
     303
     304__seh_handler_win32_OS2_Unwind_End:
     305
     306    xor %eax, %eax  /* return code is irrelevant for EH_UNWINDING */
     307    jmp __seh_handler_win32_Return
     308
     309#else
     310
     311    /* restore the OS/2 chain in our frame */
     312    movl 12(%ebp), %eax
     313    movl 44(%eax), %ecx /* pPrevFrameOS2 */
     314    movl %ecx, 0(%eax)  /* pPrev */
     315
     316    xorl %eax, %eax  /* return XCPT_CONTINUE_SEARCH (0) */
     317    jmp __seh_handler_win32_Return
     318
     319#endif
     320
     321__seh_handler_win32_Win32:
     322
     323    /* restore the Win32 chain in our frame */
     324    movl 12(%ebp), %eax
     325    movl 60(%eax), %ecx /* pPrevFrameWin32 */
     326    movl %ecx, 0(%eax)  /* pPrev */
     327
     328    /* skip EH_UNWINDING calls (for compatibility with MSVC) */
     329    movl 8(%ebp), %ebx
     330    movl 4(%ebx), %eax                      /* pRec->ExceptionFlags */
     331    testl $0x2, %eax                        /* EH_UNWINDING? */
     332    je ___seh_handler_win32_Win32_NotUnwinding    /* No, continue normally */
     333
     334    /* See the comment above */
     335#if 0
     336    /* clear out the Win32FS field so that we will not attempt to unwind twice
     337     * (first, as a result of forced unwind from ExitProcess/ExitThread/etc and
     338     * then from the OS/2 EH_UNWINDING call of our handler) */
     339    movl 12(%ebp), %eax
     340    movl $0, 64(%eax)   /* Win32FS */
     341#endif
     342
    239343    movl $1, %eax /* ExceptionContinueSearch */
    240     jmp ___seh_handler_Return
    241 
    242 ___seh_handler_Unwind:
     344    jmp __seh_handler_win32_Return
     345
     346___seh_handler_win32_Win32_NotUnwinding:
     347
     348    /* save handler's context */
     349    pushl %ebp
     350    pushl $0   /* reserve space for length, must be saved right before ESP! */
     351    pushl %esp /* ESP must be saved last! */
     352
     353    movl 12(%ebp), %ebx
     354    movl $0f, 12(%ebx) /* pFrame->pHandlerCallback */
     355
     356    /* get the size of the handler's stack */
     357    movl 40(%ebx), %ecx /* pFrame->pTryRegs[4] is ESP */
     358    subl %esp, %ecx
     359    jle __seh_handler_win32_Error /* Invalid stack! */
     360    movl %ecx, 4(%esp) /* save length */
     361
     362    /* check that EXCEPTION_RECORD and CONTEXT are on our stack
     363     * and save their offsets in pFrame */
     364    movl 8(%ebp), %eax
     365    subl %esp, %eax
     366    jl __seh_handler_win32_Error /* Invalid stack! */
     367    cmpl %ecx, %eax
     368    jg __seh_handler_win32_Error /* Invalid stack! */
     369    movl %eax, 48(%ebx) /* pFrame->Pointers.ExceptionRecord */
     370
     371    movl 16(%ebp), %eax
     372    subl %esp, %eax
     373    jl __seh_handler_win32_Error /* Invalid stack! */
     374    cmpl %ecx, %eax
     375    jg __seh_handler_win32_Error /* Invalid stack! */
     376    movl %eax, 52(%ebx) /* pFrame->Pointers.ContextRecord */
     377
     378    /* save the handler's stack on heap */
     379    movl %ecx, %eax /* size_t */
     380    subl $4, %esp
     381    movl %eax, 0(%esp)
     382    call _malloc /* __cdecl (and _Optlink compatible -> EAX/EDX/ECX-in) */
     383    addl $4, %esp
     384    testl %eax, %eax
     385    je __seh_handler_win32_Error /* No memory! */
     386    movl 4(%esp), %ecx
     387    movl %eax, %edi
     388    movl %edi, 16(%ebx) /* pFrame->pHandlerContext */
     389    movl %esp, %esi
     390    rep movsb
     391
     392    /* correct Pointers offsets to point to the saved stack on heap */
     393    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
     394    addl %eax, 48(%ebx) /* pFrame->Pointers.ExceptionRecord */
     395    addl %eax, 52(%ebx) /* pFrame->Pointers.ContextRecord */
     396
     397    /* restore __try/__catch context */
     398    movl 12(%ebp), %eax
     399    movl 24(%eax), %ebx /* pFrame->pTryRegs */
     400    movl 28(%eax), %esi
     401    movl 32(%eax), %edi
     402    movl 36(%eax), %ebp
     403    movl 40(%eax), %esp
     404
     405    /* jump to the filter callback */
     406    movl $1, 56(%eax) /* pFrame->state */
     407    jmp *8(%eax) /* pFrame->pFilterCallback */
     408
     4090:
     410    /* restore handler's context (we assume that the callback puts the address
     411     * of pFrame back to EBX!) */
     412    movl 16(%ebx), %esi /* pFrame->pHandlerContext */
     413    movl 0(%esi), %esp  /* restore saved ESP */
     414    movl 4(%esi), %ecx  /* saved stack length */
     415    subl $4, %esp /* correct ESP to compensate for PUSH ESP logic */
     416    movl %esp, %edi
     417    rep movsb
     418
     419    popl %esp
     420    addl $4, %esp
     421    popl %ebp
     422
     423    /* free heap block */
     424    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
     425    subl $4, %esp
     426    movl %eax, 0(%esp)
     427    call _free /* __cdecl (and _Optlink compatible -> EAX/EDX/ECX-in) */
     428    addl $4, %esp
     429
     430    /* analyze filter result */
     431    movl 20(%ebx), %eax /* pFrame->filterResult */
     432    cmpl $1, %eax /* EXCEPTION_EXECUTE_HANDLER? */
     433    je __seh_handler_win32_Unwind
     434    cmpl $-1, %eax /* EXCEPTION_CONTINUE_EXECUTION? */
     435    jne 1f
     436    movl $0, 56(%ebx) /* pFrame->state */
     437    movl $0, %eax /* ExceptionContinueExecution */
     438    jmp __seh_handler_win32_Return
     4391:
     440    /* assume EXCEPTION_CONTINUE_SEARCH (0) */
     441    movl $1, %eax /* ExceptionContinueSearch */
     442    jmp __seh_handler_win32_Return
     443
     444__seh_handler_win32_Unwind:
    243445
    244446    /* unwind Win32 exception chain up to ours */
     
    282484    jmp *8(%eax) /* pFrame->pFilterCallback */
    283485
    284 ___seh_handler_Error:
     486__seh_handler_win32_Error:
    285487
    286488    addl $8, %esp
     
    289491    movl $1, %eax /* ExceptionContinueSearch */
    290492
    291 ___seh_handler_Return:
     493__seh_handler_win32_Return:
    292494
    293495    popl %esi
     
    300502/*
    301503 * extern "C"
    302  * EXCEPTION_FRAME *__seh_get_prev_frame(EXCEPTION_FRAME *pFrame)
     504 * EXCEPTION_FRAME *__seh_get_prev_frame_win32(EXCEPTION_FRAME *pFrame)
    303505 *
    304506 * Returns the previous Win32 exception frame given an existing frame.
     
    319521 */
    320522
    321 ___seh_get_prev_frame:
     523___seh_get_prev_frame_win32:
    322524
    323525    /*
     
    328530    /*leal ___seh_handler, %ecx*/
    329531    movl 4(%eax), %ecx /* pFrame->Handler */
    330     cmpl $___seh_handler, %ecx
    331     jne ___seh_get_prev_frame_Normal
     532    cmpl $___seh_handler_win32, %ecx
     533    jne ___seh_get_prev_frame_win32_Normal
    332534
    333535    movl 60(%eax), %eax /* pPrevFrameWin32 */
    334536    ret
    335537
    336 ___seh_get_prev_frame_Normal:
     538___seh_get_prev_frame_win32_Normal:
    337539
    338540    movl 0(%eax), %eax /* pFrame->Prev */
Note: See TracChangeset for help on using the changeset viewer.