1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
;***
;setjmp3.asm
;
; Copyright (C) 1994 Microsoft Corporation. All rights reserved.
;
;Purpose:
; Contains setjmp(), longjmp() & raisex() routines;
; split from exsup.asm for granularity purposes.
;
;Notes:
;
;Revision History:
; 01-12-94 PML Split from setjmp.asm, added C9.0 generic EH
; callback for unwind.
; 02-10-94 GJF -1 is the end-of-exception-handler chain marker, not
; 0.
;
;*******************************************************************************
;hnt = -D_WIN32_ -Dsmall32 -Dflat32 -Mx $this;
;Define small32 and flat32 since these are not defined in the NT build process
small32 equ 1
flat32 equ 1
.xlist
include pversion.inc
?DFDATA = 1
?NODATA = 1
include cmacros.mas
include exsup.inc
.list
assumes DS,DATA
assumes FS,DATA
BeginCODE
if @Version LT 600
;this needs to go here to work around a masm5 bug. (emits wrong fixup)
assumes CS,FLAT
endif
; Following symbol defined in exsup.asm
extrn __except_list:near
; int
; _setjmp3 (
; OUT jmp_buf env,
; int count,
; ...)
;
; Routine Description:
;
; (New) implementation of setjmp intrinsic. Saves the current
; nonvolatile register state in the specified jump buffer and returns
; a function value of zero.
;
; Saves the callee-save registers, stack pointer and return address.
; Also saves the exception registration list head. If setjmp is
; called from a function using any form of exception handling, then
; additional data is also saved allowing some form of local unwind
; at longjmp time to restore the proper exception handling state.
;
; Arguments:
;
; env - Address of the buffer for storing the state information
; count - count of additional DWORDs of information. Zero if setjmp
; not called from a function with any form of EH.
; ... Additional data pushed by the setjmp intrinsic if called
; from a function with any form of EH. The first DWORD is
; a function ptr which will be called at longjmp time to do
; the local unwind. The second DWORD is the try level to be
; restored (if applicable). Any further data is saved in the
; generic data array in the jmp_buf for use by the local
; unwind function.
;
; Return Value:
;
; A value of zero is returned.
public __setjmp3
__setjmp3 PROC NEAR
mov edx, [esp+4]
mov [edx.saved_ebp], ebp ; old bp and the rest
mov [edx.saved_ebx], ebx
mov [edx.saved_edi], edi
mov [edx.saved_esi], esi
mov [edx.saved_esp], esp
mov eax, [esp] ; return address
mov [edx.saved_return], eax
mov dword ptr [edx.version_cookie], JMPBUF_COOKIE
mov dword ptr [edx.unwind_func], 0
mov eax, dword ptr fs:__except_list
mov [edx.saved_xregistration], eax
cmp eax, -1 ; -1 means no higher-level handler
jnz short _s3_get_count
mov dword ptr [edx.saved_trylevel], -1 ;something invalid
jmp short _s3_done
_s3_get_count:
mov ecx, [esp+8] ; count of additional data
or ecx, ecx
jz short _s3_default_trylevel
mov eax, [esp+12] ; func to do local unwind at longjmp
mov [edx.unwind_func], eax
dec ecx
jnz _s3_save_trylevel
; Not called from a function with any form of EH, or no trylevel
; passed. Save the TryLevel from the topmost EH node anyway,
; assuming a C8.0 SEH node. If we're linked to an obsolete CRTDLL
; and call the old longjmp, then we'll still do the right thing.
_s3_default_trylevel:
mov eax, [eax + C8_TRYLEVEL]
mov [edx.saved_trylevel], eax
jmp short _s3_done
_s3_save_trylevel:
mov eax, [esp+16] ; try level to unwind to
mov [edx.saved_trylevel], eax
dec ecx
jz short _s3_done
push esi
push edi
lea esi, [esp+20+8]
lea edi, [edx.unwind_data]
cmp ecx, 6 ; save up to 6 more DWORDs in jmp_buf
jbe _s3_save_data
mov ecx, 6
_s3_save_data:
rep movsd
pop edi
pop esi
_s3_done:
sub eax, eax
ret
__setjmp3 ENDP
EndCODE
END
|