Alexandre Julliard : winebuild: Generate Windows-style syscall thunks on x86.
Alexandre Julliard
julliard at winehq.org
Wed Jul 8 15:34:35 CDT 2020
Module: wine
Branch: master
Commit: 20715ee3fdaa794a7b6ba285cdb72b68991c65af
URL: https://source.winehq.org/git/wine.git/?a=commit;h=20715ee3fdaa794a7b6ba285cdb72b68991c65af
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jul 8 08:26:54 2020 +0200
winebuild: Generate Windows-style syscall thunks on x86.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
tools/winebuild/import.c | 54 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 46 insertions(+), 8 deletions(-)
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index dcdca021c0..b40c2c3107 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1441,19 +1441,47 @@ void output_syscalls( DLLSPEC *spec )
switch (target_cpu)
{
case CPU_x86:
+ output( "\tpushl %%ebp\n" );
+ output_cfi( ".cfi_adjust_cfa_offset 4\n" );
+ output_cfi( ".cfi_rel_offset %%ebp,0\n" );
+ output( "\tmovl %%esp,%%ebp\n" );
+ output_cfi( ".cfi_def_cfa_register %%ebp\n" );
+ output( "\tpushl %%esi\n" );
+ output_cfi( ".cfi_rel_offset %%esi,-4\n" );
+ output( "\tpushl %%edi\n" );
+ output_cfi( ".cfi_rel_offset %%edi,-8\n" );
output( "\tcmpl $%u,%%eax\n", count );
- output( "\tjae 1f\n" );
- output( "\taddl $4,%%esp\n" );
+ output( "\tjae 3f\n" );
if (UsePIC)
{
output( "\tmovl %%eax,%%edx\n" );
output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
- output( "1:\tjmp *.Lsyscall_table-1b(%%eax,%%edx,4)\n" );
+ output( "1:\tmovzbl .Lsyscall_args-1b(%%eax,%%edx,1),%%ecx\n" );
needs_get_pc_thunk = 1;
}
- else output( "\tjmp *.Lsyscall_table(,%%eax,4)\n" );
- output( "1:\tmovl $0x%x,%%eax\n", invalid_param );
+ else output( "\tmovzbl .Lsyscall_args(%%eax),%%ecx\n" );
+ output( "\tsubl %%ecx,%%esp\n" );
+ output( "\tshrl $2,%%ecx\n" );
+ output( "\tleal 12(%%ebp),%%esi\n" );
+ output( "\tandl $~15,%%esp\n" );
+ output( "\tmovl %%esp,%%edi\n" );
+ output( "\tcld\n" );
+ output( "\trep; movsl\n" );
+ if (UsePIC)
+ output( "\tcall *.Lsyscall_table-1b(%%eax,%%edx,4)\n" );
+ else
+ output( "\tcall *.Lsyscall_table(,%%eax,4)\n" );
+ output( "\tleal -8(%%ebp),%%esp\n" );
+ output( "2:\tpopl %%edi\n" );
+ output_cfi( ".cfi_same_value %%edi\n" );
+ output( "\tpopl %%esi\n" );
+ output_cfi( ".cfi_same_value %%esi\n" );
+ output( "\tpopl %%ebp\n" );
+ output_cfi( ".cfi_def_cfa %%esp,4\n" );
+ output_cfi( ".cfi_same_value %%ebp\n" );
output( "\tret\n" );
+ output( "3:\tmovl $0x%x,%%eax\n", invalid_param );
+ output( "\tjmp 2b\n" );
break;
case CPU_x86_64:
output( "\tcmpq $%u,%%rax\n", count );
@@ -1501,6 +1529,9 @@ void output_syscalls( DLLSPEC *spec )
output( ".Lsyscall_table:\n" );
for (i = 0; i < count; i++)
output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name( get_link_name( syscalls[i] )));
+ output( ".Lsyscall_args:\n" );
+ for (i = 0; i < count; i++)
+ output( "\t.byte %u\n", get_args_size( syscalls[i] ));
return;
}
@@ -1515,20 +1546,19 @@ void output_syscalls( DLLSPEC *spec )
switch (target_cpu)
{
case CPU_x86:
- /* FIXME: syscall thunks not binary-compatible yet */
if (UsePIC)
{
output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
output( "1:\tmovl %s-1b(%%eax),%%edx\n", asm_name("__wine_syscall_dispatcher") );
output( "\tmovl $%u,%%eax\n", i );
- output( "\tcall *%%edx\n" );
needs_get_pc_thunk = 1;
}
else
{
output( "\tmovl $%u,%%eax\n", i );
- output( "\tcall *(%s)\n", asm_name("__wine_syscall_dispatcher") );
+ output( "\tmovl $__wine_syscall,%%edx\n" );
}
+ output( "\tcall *%%edx\n" );
output( "\tret $%u\n", get_args_size( odp ));
break;
case CPU_x86_64:
@@ -1559,6 +1589,14 @@ void output_syscalls( DLLSPEC *spec )
output_function_size( name );
}
+ if (target_cpu == CPU_x86 && !UsePIC)
+ {
+ output( "\t.align %d\n", get_alignment(16) );
+ output( "\t%s\n", func_declaration("__wine_syscall") );
+ output( "__wine_syscall:\n" );
+ output( "\tjmp *(%s)\n", asm_name("__wine_syscall_dispatcher") );
+ output_function_size( "__wine_syscall" );
+ }
output( "\t.data\n" );
output( "\t.align %d\n", get_alignment( get_ptr_size() ) );
output( "%s\n", asm_globl("__wine_syscall_dispatcher") );
More information about the wine-cvs
mailing list