Author: sserapion
Date: Sun Dec 14 20:45:33 2008
New Revision: 38096
URL:
http://svn.reactos.org/svn/reactos?rev=38096&view=rev
Log:
Sync to wine64. Adds support for amd64 relays.. not that we use this feature.
Modified:
branches/ros-amd64-bringup/reactos/tools/winebuild/spec32.c
Modified: branches/ros-amd64-bringup/reactos/tools/winebuild/spec32.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/tools…
==============================================================================
--- branches/ros-amd64-bringup/reactos/tools/winebuild/spec32.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/tools/winebuild/spec32.c [iso-8859-1] Sun Dec 14
20:45:33 2008
@@ -42,6 +42,7 @@
if (!odp) return 0;
/* skip non-functions */
if ((odp->type != TYPE_STDCALL) && (odp->type != TYPE_CDECL)) return
0;
+ if ((odp->type == TYPE_CDECL) && (target_cpu == CPU_x86_64)) return 0;
/* skip norelay and forward entry points */
if (odp->flags & (FLAG_NORELAY|FLAG_FORWARD)) return 0;
return 1;
@@ -52,7 +53,7 @@
{
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++)
{
@@ -83,6 +84,95 @@
return buffer;
}
+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( ".type __wine_spec_relay_entry_point_%d,@function\n", i );
+ output( "__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 ]
+ * [ fixed alignment ]
+ * [ 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 $%u, %%rdx\n", (flags << 24) | (args << 16) |
(i - spec->base) );
+
+ output( "\tmovq %%rsp, %%r8\n" );
+
+ output( "\tcall *8(%%rcx)\n" );
+ output( "\tmovq 0x20(%%rsp), %%rcx\n" );
+ output( "\tmovq 0x28(%%rsp), %%rdx\n" );
+ output( "\tmovq 0x30(%%rsp), %%r8\n" );
+ output( "\tmovq 0x38(%%rsp), %%r9\n" );
+ output( "\taddq $0x40, %%rsp\n" );
+ output( "\tleaveq\n" );
+ output( "\tret\n" );
+}
/*******************************************************************
* output_relay_debug
@@ -92,12 +182,12 @@
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++)
@@ -105,14 +195,14 @@
ORDDEF *odp = spec->ordinals[i];
if (needs_relay( odp ))
- output( "\t.long
.L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i );
+ output( "\t.long
__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points\n", i );
else
output( "\t.long 0\n" );
}
/* 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++)
@@ -143,40 +233,12 @@
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" );
+ 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( "\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" );
- }
+ assert(0);
}
}
@@ -307,8 +369,8 @@
/* 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;
@@ -721,12 +783,10 @@
output( "#include <windows.h>\n");
output( "#include <reactos/debug.h>\n");
- output( "DWORD __stdcall __wine_spec_unimplemented_stub( const char *module,
const char *function )\n");
+ output( "void __stdcall __wine_spec_unimplemented_stub( const char *module,
const char *function )\n");
output( "{\n");
- output( " DPRINT1(\"%%s hit stub for
%%s\\n\",module,function);");
- output( "\n");
+ output( " DPRINT1(\"%%s hit stub for
%%s\\n\",module,function);\n");
output( " SetLastError(ERROR_CALL_NOT_IMPLEMENTED);\n");
- output( " return -1;\n");
output( "}\n");
output( "static const char __wine_spec_file_name[] =
\"%s\";\n\n", spec->file_name );