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