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