;***************************************************************************** ;* ;* Open Watcom Project ;* ;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. ;* ;* ======================================================================== ;* ;* This file contains Original Code and/or Modifications of Original ;* Code as defined in and that are subject to the Sybase Open Watcom ;* Public License version 1.0 (the 'License'). You may not use this file ;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO ;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is ;* provided with the Original Code and Modifications, and is also ;* available at www.sybase.com/developer/opensource. ;* ;* The Original Code and all software distributed under the License are ;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER ;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM ;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR ;* NON-INFRINGEMENT. Please see the License for the specific language ;* governing rights and limitations under the License. ;* ;* ======================================================================== ;* ;* Description: C library setjmp/longjmp support for 386 processors ;* ;***************************************************************************** .386p include mdef.inc include struct.inc codeptr "C",__longjmp_handler modstart setjmp ifdef __386__ ifdef __OS2__ xref DosUnwindException endif endif ifdef __NT__ xref _RtlUnwind@16 endif xdefp "C",_setjmp defpe _setjmp mov [eax],ebx ; save registers mov 4[eax],ecx mov 8[eax],edx mov 12[eax],esi mov 16[eax],edi mov 20[eax],ebp pop 24[eax] ; get return address mov 28[eax],esp push 24[eax] ; push return address back on stack mov 32[eax],es ; save segment registers mov 34[eax],ds mov 36[eax],cs mov 38[eax],fs mov 40[eax],gs mov 42[eax],ss ifdef __NT__ push fs:[0] ; touched this line to cause recompile pop 44[eax] endif ifdef __386__ ifdef __OS2__ push fs:[0] ; get exception chain pop 44[eax] ; ... endif endif sub eax,eax ; return 0 ret ; return _setjmp endp ; ; There is a pragma for longjmp, saying that it aborts, therefore ; the code generator does a jmp to here as opposed to a call. xdefp "C",longjmp defpe longjmp ifdef __STACK__ pop eax ; get address of jmp_buf pop edx ; get return code endif ; Warning, warning! ; the profiler knows about the stack frame that longjmp generates. ; do not change these 3 instructions without also changing the findLongJmpStack ; pragma in profilog.c ; push edx push eax ; save jmp_buf & retval in safe place mov ebp,esp ; ; end warning ; ifdef __NT__ push eax ; save address of jmp_buf mov eax,[eax+44] cmp eax,fs:[0] jne dounwind jmp short done_unwind dounwind: push 0 push offset done_unwind push eax ; unwind up to but not including SEH active ; at setjmp() call _RtlUnwind@16 ; trashes most registers except for ebp done_unwind: mov esp,ebp mov eax,0[ebp] mov edx,4[ebp] endif ifdef __386__ ifdef __OS2__ push eax ; save address of jmp_buf push 0 ;; push offset unwind mov eax, offset unwind push eax mov eax,8[esp] push 44[eax] call DosUnwindException unwind: add esp,12 pop eax ; restore address of jmp_buf endif endif push eax ; save parm regs push edx mov dx,42[eax] ; setup old ss:esp as a parm mov eax,28[eax] call __longjmp_handler ; call handler pop edx ; restore parm regs pop eax mov ss,42[eax] ; load old ss:esp mov esp,28[eax] ; ... push 24[eax] ; push saved eip (our return address) or edx,edx ; if return code is 0 _if e ; then inc edx ; - set it to 1 _endif ; endif push edx ; save return code mov ebx,[eax] ; load up the saved registers mov ecx,4[eax] mov esi,12[eax] mov edi,16[eax] mov ebp,20[eax] mov dx,32[eax] verr dx ; verify segment _if ne sub edx,edx _endif mov es,dx mov dx,38[eax] verr dx ; verify segment _if ne sub edx,edx _endif mov fs,dx mov dx,40[eax] verr dx ; verify segment _if ne sub edx,edx _endif mov gs,dx mov edx,8[eax] mov ds,34[eax] pop eax ; get return code ret ; return to point following setjmp call longjmp endp _TEXT ends end