]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | ; Copyright Oliver Kowalke 2009. | |
3 | ; Distributed under the Boost Software License, Version 1.0. | |
4 | ; (See accompanying file LICENSE_1_0.txt or copy at | |
5 | ; http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | ; --------------------------------------------------------------------------------- | |
8 | ; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | |
9 | ; --------------------------------------------------------------------------------- | |
10 | ; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | | |
11 | ; --------------------------------------------------------------------------------- | |
b32b8144 | 12 | ; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI | |
7c673cae FG |
13 | ; --------------------------------------------------------------------------------- |
14 | ; --------------------------------------------------------------------------------- | |
15 | ; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | | |
16 | ; --------------------------------------------------------------------------------- | |
17 | ; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | | |
18 | ; --------------------------------------------------------------------------------- | |
b32b8144 | 19 | ; | ESI | EBX | EBP | EIP | to | data | EH NXT |SEH HNDLR| |
7c673cae FG |
20 | ; --------------------------------------------------------------------------------- |
21 | ||
22 | .386 | |
23 | .XMM | |
24 | .model flat, c | |
25 | ; standard C library function | |
26 | _exit PROTO, value:SDWORD | |
27 | .code | |
28 | ||
29 | make_fcontext PROC BOOST_CONTEXT_EXPORT | |
30 | ; first arg of make_fcontext() == top of context-stack | |
31 | mov eax, [esp+04h] | |
32 | ||
33 | ; reserve space for first argument of context-function | |
34 | ; EAX might already point to a 16byte border | |
35 | lea eax, [eax-08h] | |
36 | ||
37 | ; shift address in EAX to lower 16 byte boundary | |
38 | and eax, -16 | |
39 | ||
40 | ; reserve space for context-data on context-stack | |
41 | ; on context-function entry: (ESP -0x4) % 8 == 0 | |
42 | ; additional space is required for SEH | |
b32b8144 FG |
43 | lea eax, [eax-040h] |
44 | ||
45 | ; save MMX control- and status-word | |
46 | stmxcsr [eax] | |
47 | ; save x87 control-word | |
48 | fnstcw [eax+04h] | |
7c673cae FG |
49 | |
50 | ; first arg of make_fcontext() == top of context-stack | |
51 | mov ecx, [esp+04h] | |
52 | ; save top address of context stack as 'base' | |
b32b8144 | 53 | mov [eax+014h], ecx |
7c673cae FG |
54 | ; second arg of make_fcontext() == size of context-stack |
55 | mov edx, [esp+08h] | |
56 | ; negate stack size for LEA instruction (== substraction) | |
57 | neg edx | |
58 | ; compute bottom address of context stack (limit) | |
59 | lea ecx, [ecx+edx] | |
60 | ; save bottom address of context-stack as 'limit' | |
b32b8144 | 61 | mov [eax+010h], ecx |
7c673cae | 62 | ; save bottom address of context-stack as 'dealloction stack' |
b32b8144 | 63 | mov [eax+0ch], ecx |
7c673cae FG |
64 | ; set fiber-storage to zero |
65 | xor ecx, ecx | |
b32b8144 | 66 | mov [eax+08h], ecx |
7c673cae FG |
67 | |
68 | ; third arg of make_fcontext() == address of context-function | |
69 | ; stored in EBX | |
70 | mov ecx, [esp+0ch] | |
b32b8144 | 71 | mov [eax+024h], ecx |
7c673cae FG |
72 | |
73 | ; compute abs address of label trampoline | |
74 | mov ecx, trampoline | |
75 | ; save address of trampoline as return-address for context-function | |
76 | ; will be entered after calling jump_fcontext() first time | |
b32b8144 | 77 | mov [eax+02ch], ecx |
7c673cae FG |
78 | |
79 | ; compute abs address of label finish | |
80 | mov ecx, finish | |
b32b8144 | 81 | ; save address of finish as return-address for context-function in EBP |
7c673cae | 82 | ; will be entered after context-function returns |
b32b8144 | 83 | mov [eax+028h], ecx |
7c673cae FG |
84 | |
85 | ; traverse current seh chain to get the last exception handler installed by Windows | |
86 | ; note that on Windows Server 2008 and 2008 R2, SEHOP is activated by default | |
87 | ; the exception handler chain is tested for the presence of ntdll.dll!FinalExceptionHandler | |
88 | ; at its end by RaiseException all seh-handlers are disregarded if not present and the | |
89 | ; program is aborted | |
90 | assume fs:nothing | |
91 | ; load NT_TIB into ECX | |
92 | mov ecx, fs:[0h] | |
93 | assume fs:error | |
94 | ||
95 | walk: | |
96 | ; load 'next' member of current SEH into EDX | |
97 | mov edx, [ecx] | |
98 | ; test if 'next' of current SEH is last (== 0xffffffff) | |
99 | inc edx | |
100 | jz found | |
101 | dec edx | |
102 | ; exchange content; ECX contains address of next SEH | |
103 | xchg edx, ecx | |
104 | ; inspect next SEH | |
105 | jmp walk | |
106 | ||
107 | found: | |
108 | ; load 'handler' member of SEH == address of last SEH handler installed by Windows | |
109 | mov ecx, [ecx+04h] | |
110 | ; save address in ECX as SEH handler for context | |
b32b8144 | 111 | mov [eax+03ch], ecx |
7c673cae FG |
112 | ; set ECX to -1 |
113 | mov ecx, 0ffffffffh | |
114 | ; save ECX as next SEH item | |
b32b8144 | 115 | mov [eax+038h], ecx |
7c673cae | 116 | ; load address of next SEH item |
b32b8144 | 117 | lea ecx, [eax+038h] |
7c673cae | 118 | ; save next SEH |
b32b8144 | 119 | mov [eax+018h], ecx |
7c673cae FG |
120 | |
121 | ret ; return pointer to context-data | |
122 | ||
123 | trampoline: | |
124 | ; move transport_t for entering context-function | |
125 | ; FCTX == EAX, DATA == EDX | |
126 | mov [esp], eax | |
127 | mov [esp+04h], edx | |
128 | push ebp | |
129 | ; jump to context-function | |
130 | jmp ebx | |
131 | ||
132 | finish: | |
133 | ; exit code is zero | |
134 | xor eax, eax | |
135 | mov [esp], eax | |
136 | ; exit application | |
137 | call _exit | |
138 | hlt | |
139 | make_fcontext ENDP | |
140 | END |