[PATCH] winebuild: Add support to output relay debugging information for amd64

Maarten Lankhorst m.b.lankhorst at gmail.com
Tue Dec 16 11:25:44 CST 2008


---
 tools/winebuild/spec32.c |  136 ++++++++++++++++++++++++++++++++--------------
 1 files changed, 96 insertions(+), 40 deletions(-)

diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c
index 276639e..4b41877 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++)
     {
@@ -63,6 +63,90 @@ int has_relays( DLLSPEC *spec )
     return 0;
 }
 
+static void output_relay_debug_x86(DLLSPEC *spec, int i)
+{
+    unsigned int args, flags;
+    ORDDEF *odp = spec->ordinals[i];
+
+    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)
+    {
+        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( "\tcall *4(%%eax)\n" );
+        if (odp->type == TYPE_STDCALL)
+            output( "\tret $%u\n", args * get_ptr_size() );
+        else
+            output( "\tret\n" );
+    }
+}
+
+
+static void output_relay_debug_amd64(DLLSPEC *spec, int i)
+{
+    unsigned int args, flags;
+    ORDDEF *odp = spec->ordinals[i];
+
+    output( "\t.align %d\n", get_alignment(8) );
+    output( ".L__wine_spec_relay_entry_point_%d:\n", i );
+
+    /* Save the original registers on the stack, so +relay can use them */
+    /* This makes the stack layout a bit weird:
+     * [ 4 longs reserved by abi ]
+     * [ rcx, rdx, r8, r9 ]
+     * [ (saved rbp) ]
+     * [ ret address ]
+     * [ 4 longs reserved by abi ]
+     * [ possibly additonal args ]
+     */
+    output( "\tpushq %%rbp\n" );
+    output( "\tmovq %%rsp, %%rbp\n" );
+    output( "\tsubq $0x40, %%rsp\n" );
+    output( "\tmovq %%rcx, 0x20(%%rsp)\n" );
+    output( "\tmovq %%rdx, 0x28(%%rsp)\n" );
+    output( "\tmovq %%r8, 0x30(%%rsp)\n" );
+    output( "\tmovq %%r9, 0x38(%%rsp)\n" );
+
+    if (UsePIC)
+    {
+        output( "\tleaq .L__wine_spec_relay_descr(%%rip),%%rcx\n" );
+    }
+    else output( "\tmovq $.L__wine_spec_relay_descr,%%rcx\n" );
+
+    args = strlen(odp->u.func.arg_types);
+    flags = 0; /* For later use */
+    output( "\tmovq $0x%x, %%rdx\n", (flags << 24) | (args << 16) | (i - spec->base) );
+
+    output( "\tmovq %%rsp, %%r8\n" );
+
+    output( "\tcall *8(%%rcx)\n" );
+    output( "\tleaveq\n" );
+    output( "\tret\n" );
+}
+
 /*******************************************************************
  *         output_relay_debug
  *
@@ -71,12 +155,12 @@ int has_relays( DLLSPEC *spec )
 static void output_relay_debug( DLLSPEC *spec )
 {
     int i;
-    unsigned int j, args, flags;
+    unsigned int j;
 
     /* first the table of entry point offsets */
 
     output( "\t%s\n", get_asm_rodata_section() );
-    output( "\t.align %d\n", get_alignment(4) );
+    output( "\t.align %d\n", get_alignment(get_ptr_size()) );
     output( ".L__wine_spec_relay_entry_point_offsets:\n" );
 
     for (i = spec->base; i <= spec->limit; i++)
@@ -91,7 +175,7 @@ static void output_relay_debug( DLLSPEC *spec )
 
     /* then the table of argument types */
 
-    output( "\t.align %d\n", get_alignment(4) );
+    output( "\t.align %d\n", get_alignment(get_ptr_size()) );
     output( ".L__wine_spec_relay_arg_types:\n" );
 
     for (i = spec->base; i <= spec->limit; i++)
@@ -111,8 +195,8 @@ static void output_relay_debug( DLLSPEC *spec )
     }
 
     /* then the relay thunks */
-
     output( "\t.text\n" );
+    output( "\t.align %d\n", get_alignment(get_page_size()) );
     output( "__wine_spec_relay_entry_points:\n" );
     output( "\tnop\n" );  /* to avoid 0 offset */
 
@@ -122,40 +206,12 @@ static void output_relay_debug( DLLSPEC *spec )
 
         if (!needs_relay( odp )) continue;
 
-        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)
-        {
-            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" );
-        }
+        if (target_cpu == CPU_x86)
+            output_relay_debug_x86( spec, i );
+        else if (target_cpu == CPU_x86_64)
+            output_relay_debug_amd64( spec, i );
         else
-        {
-            output( "\tcall *4(%%eax)\n" );
-            if (odp->type == TYPE_STDCALL)
-                output( "\tret $%u\n", args * get_ptr_size() );
-            else
-                output( "\tret\n" );
-        }
+            assert(0);
     }
 }
 
@@ -286,8 +342,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 amd64 */
+    if (target_cpu != CPU_x86 && target_cpu != CPU_x86_64)
     {
         output( "\t%s 0\n", get_asm_ptr_keyword() );
         return;
-- 
1.5.6.5


--------------010405090506090301030601--



More information about the wine-patches mailing list