Module: wine Branch: master Commit: 01722d601091aba73a173763768c9547b44eecb0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=01722d601091aba73a17376376...
Author: Alexandre Julliard julliard@winehq.org Date: Sat Dec 27 19:59:55 2008 +0100
winebuild: Generate relay debugging thunks for x86_64.
---
tools/winebuild/spec32.c | 77 ++++++++++++++++++++++++++++++---------------- 1 files changed, 50 insertions(+), 27 deletions(-)
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 276639e..9cf60c3 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -53,7 +53,7 @@ int has_relays( DLLSPEC *spec ) { int i;
- if (target_cpu != CPU_x86) return 0; + if (target_cpu != CPU_x86 && target_cpu != CPU_x86_64) return 0;
for (i = spec->base; i <= spec->limit; i++) { @@ -125,36 +125,59 @@ static void output_relay_debug( DLLSPEC *spec ) output( "\t.align %d\n", get_alignment(4) ); output( ".L__wine_spec_relay_entry_point_%d:\n", i );
- if (odp->flags & FLAG_REGISTER) - output( "\tpushl %%eax\n" ); - else - output( "\tpushl %%esp\n" ); - args = strlen(odp->u.func.arg_types); flags = 0; - if (odp->flags & FLAG_RET64) flags |= 1; - if (odp->type == TYPE_STDCALL) flags |= 2; - output( "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) );
- if (UsePIC) + switch (target_cpu) { - output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); - output( "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" ); - } - else output( "\tmovl $.L__wine_spec_relay_descr,%%eax\n" ); - output( "\tpushl %%eax\n" ); + case CPU_x86: + if (odp->flags & FLAG_REGISTER) + output( "\tpushl %%eax\n" ); + else + output( "\tpushl %%esp\n" );
- if (odp->flags & FLAG_REGISTER) - { - output( "\tcall *8(%%eax)\n" ); - } - else - { - output( "\tcall *4(%%eax)\n" ); - if (odp->type == TYPE_STDCALL) - output( "\tret $%u\n", args * get_ptr_size() ); + if (odp->flags & FLAG_RET64) flags |= 1; + if (odp->type == TYPE_STDCALL) flags |= 2; + output( "\tpushl $%u\n", (flags << 24) | (args << 16) | (i - spec->base) ); + + if (UsePIC) + { + output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); + output( "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" ); + } + else output( "\tmovl $.L__wine_spec_relay_descr,%%eax\n" ); + output( "\tpushl %%eax\n" ); + + if (odp->flags & FLAG_REGISTER) + { + output( "\tcall *8(%%eax)\n" ); + } else - output( "\tret\n" ); + { + output( "\tcall *4(%%eax)\n" ); + if (odp->type == TYPE_STDCALL) + output( "\tret $%u\n", args * get_ptr_size() ); + else + output( "\tret\n" ); + } + break; + + case CPU_x86_64: + output( "\tmovq %%rcx,8(%%rsp)\n" ); + output( "\tmovq %%rdx,16(%%rsp)\n" ); + output( "\tmovq %%r8,24(%%rsp)\n" ); + output( "\tmovq %%r9,32(%%rsp)\n" ); + output( "\tmovq %%rsp,%%r8\n" ); + output( "\tmovq $%u,%%rdx\n", (flags << 24) | (args << 16) | (i - spec->base) ); + output( "\tleaq .L__wine_spec_relay_descr(%%rip),%%rcx\n" ); + output( "\tsubq $40,%%rsp\n" ); + output( "\tcallq *8(%%rcx)\n" ); + output( "\taddq $40,%%rsp\n" ); + output( "\tret\n" ); + break; + + default: + assert(0); } } } @@ -286,8 +309,8 @@ static void output_exports( DLLSPEC *spec )
/* output relays */
- /* we only support relay debugging on i386 */ - if (target_cpu != CPU_x86) + /* we only support relay debugging on i386 and x86_64 */ + if (target_cpu != CPU_x86 && target_cpu != CPU_x86_64) { output( "\t%s 0\n", get_asm_ptr_keyword() ); return;