Add assembly based libcontext implementation for MSVC builds
This commit is contained in:
parent
1fc399fa31
commit
320b519278
|
@ -9,9 +9,28 @@ if( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STR
|
|||
)
|
||||
endif()
|
||||
|
||||
list(APPEND LIBCONTEXT_SOURCES
|
||||
libcontext.cpp
|
||||
)
|
||||
|
||||
if( MSVC )
|
||||
enable_language(ASM_MASM)
|
||||
|
||||
if ( NOT CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
list(APPEND LIBCONTEXT_SOURCES
|
||||
make_i386_ms_pe_masm.asm
|
||||
jump_i386_ms_pe_masm.asm
|
||||
)
|
||||
elseif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
list(APPEND LIBCONTEXT_SOURCES
|
||||
make_x86_64_ms_pe_masm.asm
|
||||
jump_x86_64_ms_pe_masm.asm
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library( libcontext OBJECT
|
||||
libcontext.cpp
|
||||
${LIBCONTEXT_SOURCES}
|
||||
)
|
||||
|
||||
target_include_directories( libcontext PUBLIC
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
|
||||
; Copyright Oliver Kowalke 2009.
|
||||
; Distributed under the Boost Software License, Version 1.0.
|
||||
; (See accompanying file LICENSE_1_0.txt or copy at
|
||||
; http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | ESI | EBX | EBP | EIP | EXIT | | SEH NXT |SEH HNDLR|
|
||||
; ---------------------------------------------------------------------------------
|
||||
|
||||
.386
|
||||
.XMM
|
||||
.model flat, c
|
||||
.code
|
||||
|
||||
jump_fcontext PROC EXPORT
|
||||
; fourth arg of jump_fcontext() == flag indicating preserving FPU
|
||||
mov ecx, [esp+010h]
|
||||
|
||||
push ebp ; save EBP
|
||||
push ebx ; save EBX
|
||||
push esi ; save ESI
|
||||
push edi ; save EDI
|
||||
|
||||
assume fs:nothing
|
||||
; load NT_TIB into ECX
|
||||
mov edx, fs:[018h]
|
||||
assume fs:error
|
||||
|
||||
; load current SEH exception list
|
||||
mov eax, [edx]
|
||||
push eax
|
||||
|
||||
; load current stack base
|
||||
mov eax, [edx+04h]
|
||||
push eax
|
||||
|
||||
; load current stack limit
|
||||
mov eax, [edx+08h]
|
||||
push eax
|
||||
|
||||
; load current deallocation stack
|
||||
mov eax, [edx+0e0ch]
|
||||
push eax
|
||||
|
||||
; load fiber local storage
|
||||
mov eax, [edx+010h]
|
||||
push eax
|
||||
|
||||
; prepare stack for FPU
|
||||
lea esp, [esp-08h]
|
||||
|
||||
; test for flag preserve_fpu
|
||||
test ecx, ecx
|
||||
je nxt1
|
||||
|
||||
; save MMX control- and status-word
|
||||
stmxcsr [esp]
|
||||
; save x87 control-word
|
||||
fnstcw [esp+04h]
|
||||
|
||||
nxt1:
|
||||
; first arg of jump_fcontext() == context jumping from
|
||||
mov eax, [esp+030h]
|
||||
|
||||
; store ESP (pointing to context-data) in EAX
|
||||
mov [eax], esp
|
||||
|
||||
; second arg of jump_fcontext() == context jumping to
|
||||
mov edx, [esp+034h]
|
||||
|
||||
; third arg of jump_fcontext() == value to be returned after jump
|
||||
mov eax, [esp+038h]
|
||||
|
||||
; restore ESP (pointing to context-data) from EDX
|
||||
mov esp, edx
|
||||
|
||||
; test for flag preserve_fpu
|
||||
test ecx, ecx
|
||||
je nxt2
|
||||
|
||||
; restore MMX control- and status-word
|
||||
ldmxcsr [esp]
|
||||
; restore x87 control-word
|
||||
fldcw [esp+04h]
|
||||
|
||||
nxt2:
|
||||
; prepare stack for FPU
|
||||
lea esp, [esp+08h]
|
||||
|
||||
assume fs:nothing
|
||||
; load NT_TIB into ECX
|
||||
mov edx, fs:[018h]
|
||||
assume fs:error
|
||||
|
||||
; restore fiber local storage
|
||||
pop ecx
|
||||
mov [edx+010h], ecx
|
||||
|
||||
; restore current deallocation stack
|
||||
pop ecx
|
||||
mov [edx+0e0ch], ecx
|
||||
|
||||
; restore current stack limit
|
||||
pop ecx
|
||||
mov [edx+08h], ecx
|
||||
|
||||
; restore current stack base
|
||||
pop ecx
|
||||
mov [edx+04h], ecx
|
||||
|
||||
; restore current SEH exception list
|
||||
pop ecx
|
||||
mov [edx], ecx
|
||||
|
||||
pop edi ; save EDI
|
||||
pop esi ; save ESI
|
||||
pop ebx ; save EBX
|
||||
pop ebp ; save EBP
|
||||
|
||||
; restore return-address
|
||||
pop edx
|
||||
|
||||
; use value in EAX as return-value after jump
|
||||
; use value in EAX as first arg in context function
|
||||
mov [esp+04h], eax
|
||||
|
||||
; indirect jump to context
|
||||
jmp edx
|
||||
jump_fcontext ENDP
|
||||
END
|
|
@ -0,0 +1,216 @@
|
|||
|
||||
; Copyright Oliver Kowalke 2009.
|
||||
; Distributed under the Boost Software License, Version 1.0.
|
||||
; (See accompanying file LICENSE_1_0.txt or copy at
|
||||
; http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0 | 1 | |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x0 | 0x4 | |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | <indicator> | |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | 0x20 | 0x24 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | 0x40 | 0x44 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | 0x60 | 0x64 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | 0x80 | 0x84 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | 0xa0 | 0xa4 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | 0xc0 | 0xc4 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | 0xe0 | 0xe4 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | limit | base | R12 | R13 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | 0x100 | 0x104 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | R14 | R15 | RDI | RSI |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | 0x120 | 0x124 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | RBX | RBP | RIP | EXIT |
|
||||
; ----------------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
jump_fcontext PROC EXPORT FRAME
|
||||
.endprolog
|
||||
|
||||
push rbp ; save RBP
|
||||
push rbx ; save RBX
|
||||
push rsi ; save RSI
|
||||
push rdi ; save RDI
|
||||
push r15 ; save R15
|
||||
push r14 ; save R14
|
||||
push r13 ; save R13
|
||||
push r12 ; save R12
|
||||
|
||||
; load NT_TIB
|
||||
mov r10, gs:[030h]
|
||||
; save current stack base
|
||||
mov rax, [r10+08h]
|
||||
push rax
|
||||
; save current stack limit
|
||||
mov rax, [r10+010h]
|
||||
push rax
|
||||
; save current deallocation stack
|
||||
mov rax, [r10+01478h]
|
||||
push rax
|
||||
; save fiber local storage
|
||||
mov rax, [r10+018h]
|
||||
push rax
|
||||
|
||||
; prepare stack for FPU
|
||||
lea rsp, [rsp-0a8h]
|
||||
|
||||
; test for flag preserve_fpu
|
||||
test r9, r9
|
||||
je nxt1
|
||||
|
||||
; save MMX control- and status-word
|
||||
stmxcsr [rsp+0a0h]
|
||||
; save x87 control-word
|
||||
fnstcw [rsp+0a4h]
|
||||
|
||||
; save XMM storage
|
||||
movaps [rsp], xmm6
|
||||
movaps [rsp+010h], xmm7
|
||||
movaps [rsp+020h], xmm8
|
||||
movaps [rsp+030h], xmm9
|
||||
movaps [rsp+040h], xmm10
|
||||
movaps [rsp+050h], xmm11
|
||||
movaps [rsp+060h], xmm12
|
||||
movaps [rsp+070h], xmm13
|
||||
movaps [rsp+080h], xmm14
|
||||
movaps [rsp+090h], xmm15
|
||||
|
||||
nxt1:
|
||||
; set R10 to zero
|
||||
xor r10, r10
|
||||
; set indicator
|
||||
push r10
|
||||
|
||||
; store RSP (pointing to context-data) in RCX
|
||||
mov [rcx], rsp
|
||||
|
||||
; restore RSP (pointing to context-data) from RDX
|
||||
mov rsp, rdx
|
||||
|
||||
; load indicator
|
||||
pop r10
|
||||
|
||||
; test for flag preserve_fpu
|
||||
test r9, r9
|
||||
je nxt2
|
||||
|
||||
; restore MMX control- and status-word
|
||||
ldmxcsr [rsp+0a0h]
|
||||
; save x87 control-word
|
||||
fldcw [rsp+0a4h]
|
||||
|
||||
; restore XMM storage
|
||||
movaps xmm6, [rsp]
|
||||
movaps xmm7, [rsp+010h]
|
||||
movaps xmm8, [rsp+020h]
|
||||
movaps xmm9, [rsp+030h]
|
||||
movaps xmm10, [rsp+040h]
|
||||
movaps xmm11, [rsp+050h]
|
||||
movaps xmm12, [rsp+060h]
|
||||
movaps xmm13, [rsp+070h]
|
||||
movaps xmm14, [rsp+080h]
|
||||
movaps xmm15, [rsp+090h]
|
||||
|
||||
nxt2:
|
||||
; set offset of stack
|
||||
mov rcx, 0a8h
|
||||
|
||||
; test for indicator
|
||||
test r10, r10
|
||||
je nxt3
|
||||
|
||||
add rcx, 08h
|
||||
|
||||
nxt3:
|
||||
; prepare stack for FPU
|
||||
lea rsp, [rsp+rcx]
|
||||
|
||||
; load NT_TIB
|
||||
mov r10, gs:[030h]
|
||||
; restore fiber local storage
|
||||
pop rax
|
||||
mov [r10+018h], rax
|
||||
; restore deallocation stack
|
||||
pop rax
|
||||
mov [r10+01478h], rax
|
||||
; restore stack limit
|
||||
pop rax
|
||||
mov [r10+010h], rax
|
||||
; restore stack base
|
||||
pop rax
|
||||
mov [r10+08h], rax
|
||||
|
||||
pop r12 ; restore R12
|
||||
pop r13 ; restore R13
|
||||
pop r14 ; restore R14
|
||||
pop r15 ; restore R15
|
||||
pop rdi ; restore RDI
|
||||
pop rsi ; restore RSI
|
||||
pop rbx ; restore RBX
|
||||
pop rbp ; restore RBP
|
||||
|
||||
; restore return-address
|
||||
pop r10
|
||||
|
||||
; use third arg as return-value after jump
|
||||
mov rax, r8
|
||||
; use third arg as first arg in context function
|
||||
mov rcx, r8
|
||||
|
||||
; indirect jump to context
|
||||
jmp r10
|
||||
jump_fcontext ENDP
|
||||
END
|
|
@ -1340,7 +1340,7 @@ __asm (
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(LIBCONTEXT_PLATFORM_msvc_x86_64) || defined(LIBCONTEXT_PLATFORM_msvc_i386)
|
||||
#if defined(LIBCONTEXT_USE_WINFIBER) && (defined(LIBCONTEXT_PLATFORM_msvc_x86_64) || defined(LIBCONTEXT_PLATFORM_msvc_i386))
|
||||
|
||||
#include <map>
|
||||
|
||||
|
@ -1411,7 +1411,7 @@ void LIBCONTEXT_CALL_CONVENTION release_fcontext( fcontext_t ctx )
|
|||
};
|
||||
#endif
|
||||
|
||||
#else // defined(LIBCONTEXT_PLATFORM_msvc_x86_64) || defined(LIBCONTEXT_PLATFORM_msvc_i386)
|
||||
#else // defined(LIBCONTEXT_USE_WINFIBER) && (defined(LIBCONTEXT_PLATFORM_msvc_x86_64) || defined(LIBCONTEXT_PLATFORM_msvc_i386))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -78,9 +78,11 @@
|
|||
#define LIBCONTEXT_CALL_CONVENTION
|
||||
#endif
|
||||
#endif
|
||||
#elif defined (_MSC_VER)
|
||||
#elif defined (_MSC_VER )
|
||||
|
||||
#if defined( LIBCONTEXT_USE_WINFIBER )
|
||||
#define LIBCONTEXT_HAS_OWN_STACK
|
||||
#endif
|
||||
|
||||
#define LIBCONTEXT_CALL_CONVENTION __cdecl
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
|
||||
; Copyright Oliver Kowalke 2009.
|
||||
; Distributed under the Boost Software License, Version 1.0.
|
||||
; (See accompanying file LICENSE_1_0.txt or copy at
|
||||
; http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
|
||||
; ---------------------------------------------------------------------------------
|
||||
; | ESI | EBX | EBP | EIP | EXIT | | SEH NXT |SEH HNDLR|
|
||||
; ---------------------------------------------------------------------------------
|
||||
|
||||
.386
|
||||
.XMM
|
||||
.model flat, c
|
||||
; standard C library function
|
||||
_exit PROTO, value:SDWORD
|
||||
.code
|
||||
|
||||
make_fcontext PROC EXPORT
|
||||
; first arg of make_fcontext() == top of context-stack
|
||||
mov eax, [esp+04h]
|
||||
|
||||
; reserve space for first argument of context-function
|
||||
; EAX might already point to a 16byte border
|
||||
lea eax, [eax-08h]
|
||||
|
||||
; shift address in EAX to lower 16 byte boundary
|
||||
and eax, -16
|
||||
|
||||
; reserve space for context-data on context-stack
|
||||
; size for fc_mxcsr .. EIP + return-address for context-function
|
||||
; on context-function entry: (ESP -0x4) % 8 == 0
|
||||
; additional space is required for SEH
|
||||
lea eax, [eax-03ch]
|
||||
|
||||
; first arg of make_fcontext() == top of context-stack
|
||||
mov ecx, [esp+04h]
|
||||
; save top address of context stack as 'base'
|
||||
mov [eax+014h], ecx
|
||||
; second arg of make_fcontext() == size of context-stack
|
||||
mov edx, [esp+08h]
|
||||
; negate stack size for LEA instruction (== substraction)
|
||||
neg edx
|
||||
; compute bottom address of context stack (limit)
|
||||
lea ecx, [ecx+edx]
|
||||
; save bottom address of context-stack as 'limit'
|
||||
mov [eax+010h], ecx
|
||||
; save bottom address of context-stack as 'dealloction stack'
|
||||
mov [eax+0ch], ecx
|
||||
|
||||
; third arg of make_fcontext() == address of context-function
|
||||
mov ecx, [esp+0ch]
|
||||
mov [eax+02ch], ecx
|
||||
|
||||
; save MMX control- and status-word
|
||||
stmxcsr [eax]
|
||||
; save x87 control-word
|
||||
fnstcw [eax+04h]
|
||||
|
||||
; compute abs address of label finish
|
||||
mov ecx, finish
|
||||
; save address of finish as return-address for context-function
|
||||
; will be entered after context-function returns
|
||||
mov [eax+030h], ecx
|
||||
|
||||
; traverse current seh chain to get the last exception handler installed by Windows
|
||||
; note that on Windows Server 2008 and 2008 R2, SEHOP is activated by default
|
||||
; the exception handler chain is tested for the presence of ntdll.dll!FinalExceptionHandler
|
||||
; at its end by RaiseException all seh-handlers are disregarded if not present and the
|
||||
; program is aborted
|
||||
assume fs:nothing
|
||||
; load NT_TIB into ECX
|
||||
mov ecx, fs:[0h]
|
||||
assume fs:error
|
||||
|
||||
walk:
|
||||
; load 'next' member of current SEH into EDX
|
||||
mov edx, [ecx]
|
||||
; test if 'next' of current SEH is last (== 0xffffffff)
|
||||
inc edx
|
||||
jz found
|
||||
dec edx
|
||||
; exchange content; ECX contains address of next SEH
|
||||
xchg edx, ecx
|
||||
; inspect next SEH
|
||||
jmp walk
|
||||
|
||||
found:
|
||||
; load 'handler' member of SEH == address of last SEH handler installed by Windows
|
||||
mov ecx, [ecx+04h]
|
||||
; save address in ECX as SEH handler for context
|
||||
mov [eax+03ch], ecx
|
||||
; set ECX to -1
|
||||
mov ecx, 0ffffffffh
|
||||
; save ECX as next SEH item
|
||||
mov [eax+038h], ecx
|
||||
; load address of next SEH item
|
||||
lea ecx, [eax+038h]
|
||||
; save next SEH
|
||||
mov [eax+018h], ecx
|
||||
|
||||
ret ; return pointer to context-data
|
||||
|
||||
finish:
|
||||
; exit code is zero
|
||||
xor eax, eax
|
||||
mov [esp], eax
|
||||
; exit application
|
||||
call _exit
|
||||
hlt
|
||||
make_fcontext ENDP
|
||||
END
|
|
@ -0,0 +1,144 @@
|
|||
|
||||
; Copyright Oliver Kowalke 2009.
|
||||
; Distributed under the Boost Software License, Version 1.0.
|
||||
; (See accompanying file LICENSE_1_0.txt or copy at
|
||||
; http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0 | 1 | |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x0 | 0x4 | |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | <indicator> | |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | 0x20 | 0x24 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | 0x40 | 0x44 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | 0x60 | 0x64 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | 0x80 | 0x84 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | 0xa0 | 0xa4 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | SEE registers (XMM6-XMM15) |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | 0xc0 | 0xc4 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | 0xe0 | 0xe4 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | limit | base | R12 | R13 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | 0x100 | 0x104 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | R14 | R15 | RDI | RSI |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | 0x120 | 0x124 |
|
||||
; ----------------------------------------------------------------------------------
|
||||
; | RBX | RBP | RIP | EXIT |
|
||||
; ----------------------------------------------------------------------------------
|
||||
|
||||
; standard C library function
|
||||
EXTERN _exit:PROC
|
||||
.code
|
||||
|
||||
; generate function table entry in .pdata and unwind information in
|
||||
make_fcontext PROC EXPORT FRAME
|
||||
; .xdata for a function's structured exception handling unwind behavior
|
||||
.endprolog
|
||||
|
||||
; first arg of make_fcontext() == top of context-stack
|
||||
mov rax, rcx
|
||||
|
||||
; reserve 32byte shadow-space for context-function
|
||||
sub rax, 028h
|
||||
|
||||
; shift address in RAX to lower 16 byte boundary
|
||||
; == pointer to fcontext_t and address of context stack
|
||||
and rax, -16
|
||||
|
||||
; reserve space for context-data on context-stack
|
||||
; size for fc_mxcsr .. RIP + return-address for context-function
|
||||
; on context-function entry: (RSP -0x8) % 16 == 0
|
||||
sub rax, 0128h
|
||||
|
||||
; third arg of make_fcontext() == address of context-function
|
||||
mov [rax+0118h], r8
|
||||
|
||||
; first arg of make_fcontext() == top of context-stack
|
||||
; save top address of context stack as 'base'
|
||||
mov [rax+0d0h], rcx
|
||||
; second arg of make_fcontext() == size of context-stack
|
||||
; negate stack size for LEA instruction (== substraction)
|
||||
neg rdx
|
||||
; compute bottom address of context stack (limit)
|
||||
lea rcx, [rcx+rdx]
|
||||
; save bottom address of context stack as 'limit'
|
||||
mov [rax+0c8h], rcx
|
||||
; save address of context stack limit as 'dealloction stack'
|
||||
mov [rax+0c0h], rcx
|
||||
|
||||
; save MMX control- and status-word
|
||||
stmxcsr [rax+0a8h]
|
||||
; save x87 control-word
|
||||
fnstcw [rax+0ach]
|
||||
|
||||
; compute abs address of label finish
|
||||
lea rcx, finish
|
||||
; save address of finish as return-address for context-function
|
||||
; will be entered after context-function returns
|
||||
mov [rax+0120h], rcx
|
||||
|
||||
; set indicator
|
||||
mov rcx, 1
|
||||
mov [rax], rcx
|
||||
|
||||
ret ; return pointer to context-data
|
||||
|
||||
finish:
|
||||
; 32byte shadow-space for _exit() are
|
||||
; already reserved by make_fcontext()
|
||||
; exit code is zero
|
||||
xor rcx, rcx
|
||||
; exit application
|
||||
call _exit
|
||||
hlt
|
||||
make_fcontext ENDP
|
||||
END
|
Loading…
Reference in New Issue