Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
adac42ba
Commit
adac42ba
authored
Aug 08, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Reimplement fiber switching in assembly.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3b1bf387
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
152 additions
and
34 deletions
+152
-34
fiber.c
dlls/kernel32/fiber.c
+152
-34
No files found.
dlls/kernel32/fiber.c
View file @
adac42ba
...
...
@@ -21,14 +21,8 @@
* - proper handling of 16-bit stack and signal stack
*/
/* Fortify source chokes on siglongjmp stack switching, so disable it */
#undef _FORTIFY_SOURCE
#define _FORTIFY_SOURCE 0
#include "config.h"
#include "wine/port.h"
#include <setjmp.h>
#include <stdarg.h>
#define NONAMELESSUNION
...
...
@@ -37,31 +31,144 @@
#include "winerror.h"
#include "winternl.h"
#include "wine/exception.h"
#include "wine/
library
.h"
#include "wine/
asm
.h"
struct
fiber_data
{
LPVOID
param
;
/* 00 fiber param */
void
*
except
;
/* 04 saved exception handlers list */
void
*
stack_base
;
/* 08 top of fiber stack */
void
*
stack_limit
;
/* 0c fiber stack low-water mark */
void
*
stack_allocation
;
/* 10 base of the fiber stack allocation */
sigjmp_buf
jmpbuf
;
/* 14 setjmp buffer (on Windows: CONTEXT)
*/
DWORD
flags
;
/* fiber flags */
LPFIBER_START_ROUTINE
start
;
/* start routine */
void
**
fls_slots
;
/* fiber storage slots */
LPVOID
param
;
/* 00
/00
fiber param */
void
*
except
;
/* 04
/08
saved exception handlers list */
void
*
stack_base
;
/* 08
/10
top of fiber stack */
void
*
stack_limit
;
/* 0c
/18
fiber stack low-water mark */
void
*
stack_allocation
;
/* 10
/20
base of the fiber stack allocation */
CONTEXT
context
;
/* 14/30 fiber context
*/
DWORD
flags
;
/*
fiber flags */
LPFIBER_START_ROUTINE
start
;
/*
start routine */
void
**
fls_slots
;
/*
fiber storage slots */
};
extern
void
WINAPI
switch_fiber
(
CONTEXT
*
old
,
CONTEXT
*
new
);
#ifdef __i386__
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"movl 4(%esp),%ecx
\n\t
"
/* old */
"movl %edi,0x9c(%ecx)
\n\t
"
/* old->Edi */
"movl %esi,0xa0(%ecx)
\n\t
"
/* old->Esi */
"movl %ebx,0xa4(%ecx)
\n\t
"
/* old->Ebx */
"movl %ebp,0xb4(%ecx)
\n\t
"
/* old->Ebp */
"movl 0(%esp),%eax
\n\t
"
"movl %eax,0xb8(%ecx)
\n\t
"
/* old->Eip */
"leal 12(%esp),%eax
\n\t
"
"movl %eax,0xc4(%ecx)
\n\t
"
/* old->Esp */
"movl 8(%esp),%ecx
\n\t
"
/* new */
"movl 0x9c(%ecx),%edi
\n\t
"
/* new->Edi */
"movl 0xa0(%ecx),%esi
\n\t
"
/* new->Esi */
"movl 0xa4(%ecx),%ebx
\n\t
"
/* new->Ebx */
"movl 0xb4(%ecx),%ebp
\n\t
"
/* new->Ebp */
"movl 0xc4(%ecx),%esp
\n\t
"
/* new->Esp */
"jmp *0xb8(%ecx)"
)
/* new->Eip */
#elif defined(__x86_64__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"movq %rbx,0x90(%rcx)
\n\t
"
/* old->Rbx */
"leaq 0x8(%rsp),%rax
\n\t
"
"movq %rax,0x98(%rcx)
\n\t
"
/* old->Rsp */
"movq %rbp,0xa0(%rcx)
\n\t
"
/* old->Rbp */
"movq %rsi,0xa8(%rcx)
\n\t
"
/* old->Rsi */
"movq %rdi,0xb0(%rcx)
\n\t
"
/* old->Rdi */
"movq %r12,0xd8(%rcx)
\n\t
"
/* old->R12 */
"movq %r13,0xe0(%rcx)
\n\t
"
/* old->R13 */
"movq %r14,0xe8(%rcx)
\n\t
"
/* old->R14 */
"movq %r15,0xf0(%rcx)
\n\t
"
/* old->R15 */
"movq (%rsp),%rax
\n\t
"
"movq %rax,0xf8(%rcx)
\n\t
"
/* old->Rip */
"movdqa %xmm6,0x200(%rcx)
\n\t
"
/* old->Xmm6 */
"movdqa %xmm7,0x210(%rcx)
\n\t
"
/* old->Xmm7 */
"movdqa %xmm8,0x220(%rcx)
\n\t
"
/* old->Xmm8 */
"movdqa %xmm9,0x230(%rcx)
\n\t
"
/* old->Xmm9 */
"movdqa %xmm10,0x240(%rcx)
\n\t
"
/* old->Xmm10 */
"movdqa %xmm11,0x250(%rcx)
\n\t
"
/* old->Xmm11 */
"movdqa %xmm12,0x260(%rcx)
\n\t
"
/* old->Xmm12 */
"movdqa %xmm13,0x270(%rcx)
\n\t
"
/* old->Xmm13 */
"movdqa %xmm14,0x280(%rcx)
\n\t
"
/* old->Xmm14 */
"movdqa %xmm15,0x290(%rcx)
\n\t
"
/* old->Xmm15 */
"movq 0x90(%rdx),%rbx
\n\t
"
/* new->Rbx */
"movq 0xa0(%rdx),%rbp
\n\t
"
/* new->Rbp */
"movq 0xa8(%rdx),%rsi
\n\t
"
/* new->Rsi */
"movq 0xb0(%rdx),%rdi
\n\t
"
/* new->Rdi */
"movq 0xd8(%rdx),%r12
\n\t
"
/* new->R12 */
"movq 0xe0(%rdx),%r13
\n\t
"
/* new->R13 */
"movq 0xe8(%rdx),%r14
\n\t
"
/* new->R14 */
"movq 0xf0(%rdx),%r15
\n\t
"
/* new->R15 */
"movdqa 0x200(%rdx),%xmm6
\n\t
"
/* new->Xmm6 */
"movdqa 0x210(%rdx),%xmm7
\n\t
"
/* new->Xmm7 */
"movdqa 0x220(%rdx),%xmm8
\n\t
"
/* new->Xmm8 */
"movdqa 0x230(%rdx),%xmm9
\n\t
"
/* new->Xmm9 */
"movdqa 0x240(%rdx),%xmm10
\n\t
"
/* new->Xmm10 */
"movdqa 0x250(%rdx),%xmm11
\n\t
"
/* new->Xmm11 */
"movdqa 0x260(%rdx),%xmm12
\n\t
"
/* new->Xmm12 */
"movdqa 0x270(%rdx),%xmm13
\n\t
"
/* new->Xmm13 */
"movdqa 0x280(%rdx),%xmm14
\n\t
"
/* new->Xmm14 */
"movdqa 0x290(%rdx),%xmm15
\n\t
"
/* new->Xmm15 */
"movq 0x98(%rdx),%rsp
\n\t
"
/* new->Rsp */
"jmp *0xf8(%rdx)"
)
/* new->Rip */
#elif defined(__arm__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"str r4, [r0, #0x14]
\n\t
"
/* old->R4 */
"str r5, [r0, #0x18]
\n\t
"
/* old->R5 */
"str r6, [r0, #0x1c]
\n\t
"
/* old->R6 */
"str r7, [r0, #0x20]
\n\t
"
/* old->R7 */
"str r8, [r0, #0x24]
\n\t
"
/* old->R8 */
"str r9, [r0, #0x28]
\n\t
"
/* old->R9 */
"str r10, [r0, #0x2c]
\n\t
"
/* old->R10 */
"str r11, [r0, #0x30]
\n\t
"
/* old->R11 */
"str sp, [r0, #0x38]
\n\t
"
/* old->Sp */
"str lr, [r0, #0x40]
\n\t
"
/* old->Pc */
"ldr r4, [r1, #0x14]
\n\t
"
/* new->R4 */
"ldr r5, [r1, #0x18]
\n\t
"
/* new->R5 */
"ldr r6, [r1, #0x1c]
\n\t
"
/* new->R6 */
"ldr r7, [r1, #0x20]
\n\t
"
/* new->R7 */
"ldr r8, [r1, #0x24]
\n\t
"
/* new->R8 */
"ldr r9, [r1, #0x28]
\n\t
"
/* new->R9 */
"ldr r10, [r1, #0x2c]
\n\t
"
/* new->R10 */
"ldr r11, [r1, #0x30]
\n\t
"
/* new->R11 */
"ldr sp, [r1, #0x38]
\n\t
"
/* new->Sp */
"ldr r2, [r1, #0x40]
\n\t
"
/* new->Pc */
"bx r2"
)
#elif defined(__aarch64__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"stp x19, x20, [x0, #0xa0]
\n\t
"
/* old->X19,X20 */
"stp x21, x22, [x0, #0xb0]
\n\t
"
/* old->X21,X22 */
"stp x23, x24, [x0, #0xc0]
\n\t
"
/* old->X23,X24 */
"stp x25, x26, [x0, #0xd0]
\n\t
"
/* old->X25,X26 */
"stp x27, x28, [x0, #0xe0]
\n\t
"
/* old->X27,X28 */
"str x29, [x0, #0xf0]
\n\t
"
/* old->Fp */
"mov x2, sp
\n\t
"
"str x2, [x0, #0x100]
\n\t
"
/* old->Sp */
"str x30, [x0, #0x108]
\n\t
"
/* old->Pc */
"ldp x19, x20, [x1, #0xa0]
\n\t
"
/* new->X19,X20 */
"ldp x21, x22, [x1, #0xb0]
\n\t
"
/* new->X21,X22 */
"ldp x23, x24, [x1, #0xc0]
\n\t
"
/* new->X23,X24 */
"ldp x25, x26, [x1, #0xd0]
\n\t
"
/* new->X25,X26 */
"ldp x27, x28, [x1, #0xe0]
\n\t
"
/* new->X27,X28 */
"ldr x29, [x1, #0xf0]
\n\t
"
/* new->Fp */
"ldr x2, [x1, #0x100]
\n\t
"
/* new->Sp */
"ldr x30, [x1, #0x108]
\n\t
"
/* new->Pc */
"mov sp, x2
\n\t
"
"ret"
)
#else
void
WINAPI
switch_fiber
(
CONTEXT
*
old
,
CONTEXT
*
new
)
{
DbgBreakPoint
();
}
#endif
/* call the fiber initial function once we have switched stack */
static
void
start_fiber
(
void
*
arg
)
static
void
CDECL
start_fiber
(
void
)
{
struct
fiber_data
*
fiber
=
arg
;
struct
fiber_data
*
fiber
=
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
;
LPFIBER_START_ROUTINE
start
=
fiber
->
start
;
__TRY
{
fiber
->
start
=
NULL
;
start
(
fiber
->
param
);
ExitThread
(
1
);
}
...
...
@@ -72,6 +179,23 @@ static void start_fiber( void *arg )
__ENDTRY
}
static
void
init_fiber_context
(
struct
fiber_data
*
fiber
)
{
#ifdef __i386__
fiber
->
context
.
Esp
=
(
ULONG_PTR
)
fiber
->
stack_base
-
4
;
fiber
->
context
.
Eip
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__x86_64__)
fiber
->
context
.
Rsp
=
(
ULONG_PTR
)
fiber
->
stack_base
-
0x28
;
fiber
->
context
.
Rip
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__arm__)
fiber
->
context
.
Sp
=
(
ULONG_PTR
)
fiber
->
stack_base
;
fiber
->
context
.
Pc
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__aarch64__)
fiber
->
context
.
Sp
=
(
ULONG_PTR
)
fiber
->
stack_base
;
fiber
->
context
.
Pc
=
(
ULONG_PTR
)
start_fiber
;
#endif
}
/***********************************************************************
* CreateFiber (KERNEL32.@)
...
...
@@ -92,7 +216,7 @@ LPVOID WINAPI CreateFiberEx( SIZE_T stack_commit, SIZE_T stack_reserve, DWORD fl
INITIAL_TEB
stack
;
NTSTATUS
status
;
if
(
!
(
fiber
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
fiber
)
)))
if
(
!
(
fiber
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
fiber
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
NULL
;
...
...
@@ -111,7 +235,7 @@ LPVOID WINAPI CreateFiberEx( SIZE_T stack_commit, SIZE_T stack_reserve, DWORD fl
fiber
->
except
=
(
void
*
)
-
1
;
fiber
->
start
=
start
;
fiber
->
flags
=
flags
;
fiber
->
fls_slots
=
NULL
;
init_fiber_context
(
fiber
)
;
return
fiber
;
}
...
...
@@ -199,19 +323,13 @@ void WINAPI SwitchToFiber( LPVOID fiber )
/* stack_allocation and stack_base never change */
/* FIXME: should save floating point context if requested in fiber->flags */
if
(
!
sigsetjmp
(
current_fiber
->
jmpbuf
,
0
))
{
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
=
new_fiber
;
NtCurrentTeb
()
->
Tib
.
ExceptionList
=
new_fiber
->
except
;
NtCurrentTeb
()
->
Tib
.
StackBase
=
new_fiber
->
stack_base
;
NtCurrentTeb
()
->
Tib
.
StackLimit
=
new_fiber
->
stack_limit
;
NtCurrentTeb
()
->
DeallocationStack
=
new_fiber
->
stack_allocation
;
NtCurrentTeb
()
->
FlsSlots
=
new_fiber
->
fls_slots
;
if
(
new_fiber
->
start
)
/* first time */
wine_switch_to_stack
(
start_fiber
,
new_fiber
,
new_fiber
->
stack_base
);
else
siglongjmp
(
new_fiber
->
jmpbuf
,
1
);
}
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
=
new_fiber
;
NtCurrentTeb
()
->
Tib
.
ExceptionList
=
new_fiber
->
except
;
NtCurrentTeb
()
->
Tib
.
StackBase
=
new_fiber
->
stack_base
;
NtCurrentTeb
()
->
Tib
.
StackLimit
=
new_fiber
->
stack_limit
;
NtCurrentTeb
()
->
DeallocationStack
=
new_fiber
->
stack_allocation
;
NtCurrentTeb
()
->
FlsSlots
=
new_fiber
->
fls_slots
;
switch_fiber
(
&
current_fiber
->
context
,
&
new_fiber
->
context
);
}
/***********************************************************************
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment