mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:56:00 +00:00
[CRT]
Implement ms compatible __SEH_prolog svn path=/branches/cmake-bringup/; revision=50482
This commit is contained in:
parent
d5fecffd28
commit
776c09f1fd
2 changed files with 133 additions and 12 deletions
|
@ -279,15 +279,12 @@ list(APPEND CRT_SOURCE
|
||||||
wine/heap.c
|
wine/heap.c
|
||||||
wine/undname.c)
|
wine/undname.c)
|
||||||
|
|
||||||
if(NOT ARCH MATCHES arm)
|
|
||||||
list(APPEND CRT_SOURCE
|
|
||||||
except/${ARCH}/seh.s)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ARCH MATCHES i386)
|
if(ARCH MATCHES i386)
|
||||||
list(APPEND CRT_SOURCE
|
list(APPEND CRT_SOURCE
|
||||||
except/i386/chkstk_asm.s
|
except/i386/chkstk_asm.s
|
||||||
except/i386/prolog.s
|
except/i386/prolog.s
|
||||||
|
except/i386/seh.s
|
||||||
|
except/i386/seh_prolog.s
|
||||||
except/i386/unwind.c
|
except/i386/unwind.c
|
||||||
float/i386/clearfp.c
|
float/i386/clearfp.c
|
||||||
float/i386/cntrlfp.c
|
float/i386/cntrlfp.c
|
||||||
|
@ -298,6 +295,7 @@ if(ARCH MATCHES i386)
|
||||||
elseif(ARCH MATCHES amd64)
|
elseif(ARCH MATCHES amd64)
|
||||||
list(APPEND CRT_SOURCE
|
list(APPEND CRT_SOURCE
|
||||||
except/amd64/chkstk_asm.s
|
except/amd64/chkstk_asm.s
|
||||||
|
except/amd64/seh.s
|
||||||
float/i386/clearfp.c
|
float/i386/clearfp.c
|
||||||
float/i386/cntrlfp.c
|
float/i386/cntrlfp.c
|
||||||
float/i386/fpreset.c
|
float/i386/fpreset.c
|
||||||
|
@ -470,15 +468,12 @@ list(APPEND LIBCNTPR_SOURCE
|
||||||
wstring/wcsspn.c
|
wstring/wcsspn.c
|
||||||
wstring/wcsstr.c)
|
wstring/wcsstr.c)
|
||||||
|
|
||||||
if(NOT ARCH MATCHES arm)
|
|
||||||
list(APPEND LIBCNTPR_SOURCE
|
|
||||||
except/${ARCH}/chkstk_asm.s
|
|
||||||
except/${ARCH}/seh.s
|
|
||||||
setjmp/${ARCH}/setjmp.s)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ARCH MATCHES i386)
|
if(ARCH MATCHES i386)
|
||||||
list(APPEND LIBCNTPR_SOURCE
|
list(APPEND LIBCNTPR_SOURCE
|
||||||
|
except/i386/chkstk_asm.s
|
||||||
|
except/i386/seh.s
|
||||||
|
except/i386/seh_prolog.s
|
||||||
|
setjmp/i386/setjmp.s
|
||||||
math/i386/alldiv_asm.s
|
math/i386/alldiv_asm.s
|
||||||
math/i386/alldvrm_asm.s
|
math/i386/alldvrm_asm.s
|
||||||
math/i386/allmul_asm.s
|
math/i386/allmul_asm.s
|
||||||
|
@ -505,6 +500,9 @@ if(ARCH MATCHES i386)
|
||||||
misc/i386/readcr4.S)
|
misc/i386/readcr4.S)
|
||||||
elseif(ARCH MATCHES amd64)
|
elseif(ARCH MATCHES amd64)
|
||||||
list(APPEND LIBCNTPR_SOURCE
|
list(APPEND LIBCNTPR_SOURCE
|
||||||
|
except/amd64/chkstk_asm.s
|
||||||
|
except/amd64/seh.s
|
||||||
|
setjmp/amd64/setjmp.s
|
||||||
math/cos.c
|
math/cos.c
|
||||||
math/sin.c
|
math/sin.c
|
||||||
math/amd64/alldiv.S
|
math/amd64/alldiv.S
|
||||||
|
|
123
lib/sdk/crt/except/i386/seh_prolog.s
Normal file
123
lib/sdk/crt/except/i386/seh_prolog.s
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: GNU GPL, see COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS CRT
|
||||||
|
* FILE: lib/crt/misc/i386/seh_prolog.S
|
||||||
|
* PURPOSE: SEH Support for MSVC
|
||||||
|
* PROGRAMMERS: Timo Kreuzer
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <asm.inc>
|
||||||
|
|
||||||
|
EXTERN __except_handler3:PROC
|
||||||
|
|
||||||
|
/* The very first thing a function compiled with MSVC containing SEH
|
||||||
|
* will do is call __SEH_prolog like this:
|
||||||
|
*
|
||||||
|
* push <Number of stackbytes>
|
||||||
|
* push <Address of exception handler>
|
||||||
|
* call __SEH_prolog
|
||||||
|
*
|
||||||
|
* When entering the function the stack layout is like this:
|
||||||
|
*
|
||||||
|
* esp + 08: OLDFRAME.StackBytes
|
||||||
|
* esp + 04: OLDFRAME.SEHTable
|
||||||
|
* esp + 00: OLDFRAME.ReturnAddress
|
||||||
|
*
|
||||||
|
* __SEH_prolog will now setup the stack to the following layout:
|
||||||
|
*
|
||||||
|
* esp + N + 24: SEH_FRAME.OriginalEbp OLDFRAME.StackBytes
|
||||||
|
* esp + N + 20: SEH_FRAME.Disable OLDFRAME.SEHTable
|
||||||
|
* esp + N + 1C: SEH_FRAME.SEHTable OLDFRAME.ReturnAddress
|
||||||
|
* esp + N + 18: SEH_FRAME.Handler
|
||||||
|
* esp + N + 14: SEH_FRAME.PreviousRecord
|
||||||
|
* esp + N + 10: SEH_FRAME.unused
|
||||||
|
* esp + N + 0c: SEH_FRAME.NewEsp
|
||||||
|
*
|
||||||
|
* N bytes local variables
|
||||||
|
* ...
|
||||||
|
* esp + 08: SAFE_AREA.Ebx
|
||||||
|
* esp + 04: SAFE_AREA.Esi
|
||||||
|
* esp + 00: SAFE_AREA.Edi
|
||||||
|
*
|
||||||
|
* all this is documented here (with some minor errors):
|
||||||
|
* http://reactos-blog.blogspot.com/2009/08/inside-mind-of-reactos-developer.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
OLDFRAME_ReturnAddress = 0 /* 0x00 */
|
||||||
|
OLDFRAME_SEHTable = 4 /* 0x04 */
|
||||||
|
OLDFRAME_StackBytes = 8 /* 0x08 */
|
||||||
|
OLDFRAME_Size = 12 /* 0x0c */
|
||||||
|
|
||||||
|
SEH_FRAME_NewEsp = 0 /* 0x00 */
|
||||||
|
SEH_FRAME_unused = 4 /* 0x04 */
|
||||||
|
SEH_FRAME_PreviousRecord = 8 /* 0x08 */
|
||||||
|
SEH_FRAME_Handler = 12 /* 0x0c */
|
||||||
|
SEH_FRAME_SEHTable = 16 /* 0x10 */
|
||||||
|
SEH_FRAME_Disable = 20 /* 0x14 */
|
||||||
|
SEH_FRAME_OriginalEbp = 24 /* 0x18 */
|
||||||
|
SEH_FRAME_Size = 28 /* 0x1c */
|
||||||
|
|
||||||
|
SAFE_AREA_Edi = 0 /* 0x00 */
|
||||||
|
SAFE_AREA_Esi = 4 /* 0x04 */
|
||||||
|
SAFE_AREA_Ebx = 8 /* 0x08 */
|
||||||
|
SAFE_AREA_Size = 12 /* 0x0c */
|
||||||
|
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
PUBLIC __SEH_prolog
|
||||||
|
__SEH_prolog:
|
||||||
|
|
||||||
|
/* Get the number of stack bytes to reserve */
|
||||||
|
mov eax, [esp + OLDFRAME_StackBytes]
|
||||||
|
|
||||||
|
/* Push address of __except_handler3 on the stack */
|
||||||
|
push offset __except_handler3
|
||||||
|
|
||||||
|
/* Push the old exception record on the stack */
|
||||||
|
push dword ptr fs:0
|
||||||
|
|
||||||
|
/* Adjust stack allocation, add size of the stack frame minus 2 pushes */
|
||||||
|
add eax, SEH_FRAME_Size + SAFE_AREA_Size - OLDFRAME_Size - 8
|
||||||
|
|
||||||
|
/* Save old ebp, overwriting OLDFRAME.StackBytes */
|
||||||
|
mov [esp + 8 + OLDFRAME_StackBytes], ebp
|
||||||
|
|
||||||
|
/* Load new ebp, pointing to OLDFRAME.StackBytes */
|
||||||
|
lea ebp, [esp + 8 + OLDFRAME_StackBytes]
|
||||||
|
|
||||||
|
/* Allocate stack space */
|
||||||
|
sub esp, eax
|
||||||
|
|
||||||
|
/* Push the return address on the stack */
|
||||||
|
push dword ptr [ebp - OLDFRAME_StackBytes + OLDFRAME_ReturnAddress]
|
||||||
|
|
||||||
|
/* Get address of the SEH table */
|
||||||
|
mov eax, [ebp + OLDFRAME_SEHTable]
|
||||||
|
|
||||||
|
/* Save new esp */
|
||||||
|
mov [ebp - SEH_FRAME_OriginalEbp + SEH_FRAME_NewEsp], esp
|
||||||
|
|
||||||
|
/* Safe SEH table, overwriting OLDFRAME.ReturnAddress */
|
||||||
|
mov [ebp - SEH_FRAME_OriginalEbp + SEH_FRAME_SEHTable], eax
|
||||||
|
|
||||||
|
/* Save registers */
|
||||||
|
mov [esp + SAFE_AREA_Edi], edi
|
||||||
|
mov [esp + SAFE_AREA_Esi], esi
|
||||||
|
mov [esp + SAFE_AREA_Ebx], ebx
|
||||||
|
|
||||||
|
/* Load the address of the new registration record */
|
||||||
|
lea eax, [ebp - SEH_FRAME_OriginalEbp + SEH_FRAME_PreviousRecord]
|
||||||
|
|
||||||
|
/* Safe the disable value, overwriting OLDFRAME.SEHTable */
|
||||||
|
mov dword ptr [ebp - SEH_FRAME_OriginalEbp + SEH_FRAME_Disable], -1
|
||||||
|
|
||||||
|
/* Enqueue the new record */
|
||||||
|
mov fs:[0], eax
|
||||||
|
|
||||||
|
/* Return to the caller */
|
||||||
|
ret
|
||||||
|
|
||||||
|
END
|
Loading…
Add table
Add a link
Reference in a new issue