From d97c9280671444215da845bb71c2d624a08be4df Mon Sep 17 00:00:00 2001 From: samuel Date: Tue, 20 Nov 2018 10:17:39 +0000 Subject: [PATCH] Better (?) support for Windows TIB. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65867 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- coroutine/win32/Context.asm | 22 ++++++++++++++++------ coroutine/win32/Context.h | 7 ++++--- coroutine/win64/Context.asm | 21 ++++++++++++++++----- coroutine/win64/Context.h | 7 ++++--- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/coroutine/win32/Context.asm b/coroutine/win32/Context.asm index 4917faf9d7..b024b22fc7 100644 --- a/coroutine/win32/Context.asm +++ b/coroutine/win32/Context.asm @@ -14,28 +14,38 @@ ; to touch these in order to pass them to the destination coroutine. @coroutine_transfer@8 proc - ; Save caller registers + ; Save the thread information block: + push fs:[0] + push fs:[4] + push fs:[8] + + ; Save caller registers: push ebp push ebx push edi push esi - ; Save caller stack pointer + ; Save caller stack pointer: mov dword ptr [ecx], esp - ; Restore callee stack pointer + ; Restore callee stack pointer: mov esp, dword ptr [edx] - ; Restore callee stack + ; Restore callee stack: pop esi pop edi pop ebx pop ebp - ; Save the first argument as the return value + ; Restore the thread information block: + pop fs:[8] + pop fs:[4] + pop fs:[0] + + ; Save the first argument as the return value: mov eax, dword ptr ecx - ; Jump to the address on the stack + ; Jump to the address on the stack: ret @coroutine_transfer@8 endp diff --git a/coroutine/win32/Context.h b/coroutine/win32/Context.h index 8dd47696c5..ba6b1fd07b 100644 --- a/coroutine/win32/Context.h +++ b/coroutine/win32/Context.h @@ -16,6 +16,7 @@ extern "C" { #define COROUTINE __declspec(noreturn) void __fastcall +/* This doesn't include thread information block */ const size_t COROUTINE_REGISTERS = 4; struct coroutine_context @@ -40,9 +41,9 @@ static inline void coroutine_initialize( } /* Windows Thread Information Block */ - *--context->stack_pointer = 0; - *--context->stack_pointer = stack_pointer; - *--context->stack_pointer = (void*)stack_size; + *--context->stack_pointer = 0; /* fs:[0] */ + *--context->stack_pointer = stack_pointer + stack_size; /* fs:[4] */ + *--context->stack_pointer = (void*)stack_pointer; /* fs:[8] */ *--context->stack_pointer = (void*)start; diff --git a/coroutine/win64/Context.asm b/coroutine/win64/Context.asm index a9f819a8c6..4031c613fe 100644 --- a/coroutine/win64/Context.asm +++ b/coroutine/win64/Context.asm @@ -8,6 +8,12 @@ .code coroutine_transfer proc + ; Save the thread information block: + push gs:[0x00] + push gs:[0x08] + push gs:[0x10] + + ; Save caller registers: push rbp push rbx push rdi @@ -17,13 +23,13 @@ coroutine_transfer proc push r14 push r15 - ; Save caller stack pointer + ; Save caller stack pointer: mov [rcx], rsp - ; Restore callee stack pointer + ; Restore callee stack pointer: mov rsp, [rdx] - ; Restore callee stack + ; Restore callee stack: pop r15 pop r14 pop r13 @@ -33,10 +39,15 @@ coroutine_transfer proc pop rbx pop rbp - ; Put the first argument into the return value + ; Restore the thread information block: + pop gs:[0x10] + pop gs:[0x08] + pop gs:[0x00] + + ; Put the first argument into the return value: mov rax, rcx - ; We pop the return address and jump to it + ; We pop the return address and jump to it: ret coroutine_transfer endp diff --git a/coroutine/win64/Context.h b/coroutine/win64/Context.h index 3b6ffb2175..32d6e1038b 100644 --- a/coroutine/win64/Context.h +++ b/coroutine/win64/Context.h @@ -40,9 +40,10 @@ static inline void coroutine_initialize( } /* Windows Thread Information Block */ - *--context->stack_pointer = 0; - *--context->stack_pointer = stack_pointer; - *--context->stack_pointer = (void*)stack_size; + *--context->stack_pointer = 0; /* gs:[0x00] */ + *--context->stack_pointer = stack_pointer + stack_size; /* gs:[0x08] */ + *--context->stack_pointer = (void*)stack_pointer; /* gs:[0x10] */ + *--context->stack_pointer = (void*)start;