[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