Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
615 | serge | 1 | ;***************************************************************************** |
2 | ;* |
||
3 | ;* Open Watcom Project |
||
4 | ;* |
||
5 | ;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
||
6 | ;* |
||
7 | ;* ======================================================================== |
||
8 | ;* |
||
9 | ;* This file contains Original Code and/or Modifications of Original |
||
10 | ;* Code as defined in and that are subject to the Sybase Open Watcom |
||
11 | ;* Public License version 1.0 (the 'License'). You may not use this file |
||
12 | ;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
||
13 | ;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
||
14 | ;* provided with the Original Code and Modifications, and is also |
||
15 | ;* available at www.sybase.com/developer/opensource. |
||
16 | ;* |
||
17 | ;* The Original Code and all software distributed under the License are |
||
18 | ;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
||
19 | ;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
||
20 | ;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
||
21 | ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
||
22 | ;* NON-INFRINGEMENT. Please see the License for the specific language |
||
23 | ;* governing rights and limitations under the License. |
||
24 | ;* |
||
25 | ;* ======================================================================== |
||
26 | ;* |
||
27 | ;* Description: C library setjmp/longjmp support for 386 processors |
||
28 | ;* |
||
29 | ;***************************************************************************** |
||
30 | |||
31 | .386p |
||
32 | include mdef.inc |
||
33 | include struct.inc |
||
34 | |||
35 | codeptr "C",__longjmp_handler |
||
36 | |||
37 | modstart setjmp |
||
38 | |||
39 | ifdef __386__ |
||
40 | ifdef __OS2__ |
||
41 | xref DosUnwindException |
||
42 | endif |
||
43 | endif |
||
44 | ifdef __NT__ |
||
45 | xref _RtlUnwind@16 |
||
46 | endif |
||
47 | |||
48 | xdefp "C",_setjmp |
||
49 | defpe _setjmp |
||
50 | mov [eax],ebx ; save registers |
||
51 | mov 4[eax],ecx |
||
52 | mov 8[eax],edx |
||
53 | mov 12[eax],esi |
||
54 | mov 16[eax],edi |
||
55 | mov 20[eax],ebp |
||
56 | pop 24[eax] ; get return address |
||
57 | mov 28[eax],esp |
||
58 | push 24[eax] ; push return address back on stack |
||
59 | mov 32[eax],es ; save segment registers |
||
60 | mov 34[eax],ds |
||
61 | mov 36[eax],cs |
||
62 | mov 38[eax],fs |
||
63 | mov 40[eax],gs |
||
64 | mov 42[eax],ss |
||
65 | ifdef __NT__ |
||
66 | push fs:[0] ; touched this line to cause recompile |
||
67 | pop 44[eax] |
||
68 | endif |
||
69 | ifdef __386__ |
||
70 | ifdef __OS2__ |
||
71 | push fs:[0] ; get exception chain |
||
72 | pop 44[eax] ; ... |
||
73 | endif |
||
74 | endif |
||
75 | sub eax,eax ; return 0 |
||
76 | ret ; return |
||
77 | _setjmp endp |
||
78 | |||
79 | ; |
||
80 | ; There is a pragma for longjmp, saying that it aborts, therefore |
||
81 | ; the code generator does a jmp to here as opposed to a call. |
||
82 | |||
83 | xdefp "C",longjmp |
||
84 | defpe longjmp |
||
85 | ifdef __STACK__ |
||
86 | pop eax ; get address of jmp_buf |
||
87 | pop edx ; get return code |
||
88 | endif |
||
89 | ; Warning, warning! |
||
90 | ; the profiler knows about the stack frame that longjmp generates. |
||
91 | ; do not change these 3 instructions without also changing the findLongJmpStack |
||
92 | ; pragma in profilog.c |
||
93 | ; |
||
94 | push edx |
||
95 | push eax ; save jmp_buf & retval in safe place |
||
96 | mov ebp,esp |
||
97 | ; |
||
98 | ; end warning |
||
99 | ; |
||
100 | ifdef __NT__ |
||
101 | push eax ; save address of jmp_buf |
||
102 | mov eax,[eax+44] |
||
103 | cmp eax,fs:[0] |
||
104 | jne dounwind |
||
105 | jmp short done_unwind |
||
106 | dounwind: |
||
107 | push 0 |
||
108 | push offset done_unwind |
||
109 | push eax ; unwind up to but not including SEH active |
||
110 | ; at setjmp() |
||
111 | call _RtlUnwind@16 ; trashes most registers except for ebp |
||
112 | done_unwind: |
||
113 | mov esp,ebp |
||
114 | mov eax,0[ebp] |
||
115 | mov edx,4[ebp] |
||
116 | endif |
||
117 | ifdef __386__ |
||
118 | ifdef __OS2__ |
||
119 | push eax ; save address of jmp_buf |
||
120 | push 0 |
||
121 | ;; push offset unwind |
||
122 | mov eax, offset unwind |
||
123 | push eax |
||
124 | mov eax,8[esp] |
||
125 | push 44[eax] |
||
126 | call DosUnwindException |
||
127 | unwind: add esp,12 |
||
128 | pop eax ; restore address of jmp_buf |
||
129 | endif |
||
130 | endif |
||
131 | push eax ; save parm regs |
||
132 | push edx |
||
133 | mov dx,42[eax] ; setup old ss:esp as a parm |
||
134 | mov eax,28[eax] |
||
135 | call __longjmp_handler ; call handler |
||
136 | pop edx ; restore parm regs |
||
137 | pop eax |
||
138 | |||
139 | mov ss,42[eax] ; load old ss:esp |
||
140 | mov esp,28[eax] ; ... |
||
141 | push 24[eax] ; push saved eip (our return address) |
||
142 | or edx,edx ; if return code is 0 |
||
143 | _if e ; then |
||
144 | inc edx ; - set it to 1 |
||
145 | _endif ; endif |
||
146 | push edx ; save return code |
||
147 | mov ebx,[eax] ; load up the saved registers |
||
148 | mov ecx,4[eax] |
||
149 | mov esi,12[eax] |
||
150 | mov edi,16[eax] |
||
151 | mov ebp,20[eax] |
||
152 | mov dx,32[eax] |
||
153 | verr dx ; verify segment |
||
154 | _if ne |
||
155 | sub edx,edx |
||
156 | _endif |
||
157 | mov es,dx |
||
158 | mov dx,38[eax] |
||
159 | verr dx ; verify segment |
||
160 | _if ne |
||
161 | sub edx,edx |
||
162 | _endif |
||
163 | mov fs,dx |
||
164 | mov dx,40[eax] |
||
165 | verr dx ; verify segment |
||
166 | _if ne |
||
167 | sub edx,edx |
||
168 | _endif |
||
169 | mov gs,dx |
||
170 | mov edx,8[eax] |
||
171 | mov ds,34[eax] |
||
172 | pop eax ; get return code |
||
173 | ret ; return to point following setjmp call |
||
174 | longjmp endp |
||
175 | |||
176 | _TEXT ends |
||
177 | end |