summaryrefslogtreecommitdiffstats
path: root/private/crt32/misc/i386/setjmp3.asm
blob: 9c03e9a8c5fb9d1db4609f395b764636a1986027 (plain) (blame)
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