Module: wine Branch: master Commit: 28debd82fc90e551e8fa8fbee8858df237cb3301 URL: https://source.winehq.org/git/wine.git/?a=commit;h=28debd82fc90e551e8fa8fbee...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Feb 27 17:09:51 2019 +0100
winebuild: Make thiscall an entry point flag instead of a function type.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
tools/winebuild/build.h | 2 +- tools/winebuild/import.c | 2 -- tools/winebuild/parser.c | 40 +++++++++++++++++++++++++++------------- tools/winebuild/spec32.c | 12 +++++------- tools/winebuild/winebuild.man.in | 11 ++++++----- 5 files changed, 39 insertions(+), 28 deletions(-)
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index fbc2cd9..15d22a0 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -47,7 +47,6 @@ typedef enum TYPE_STDCALL, /* stdcall function (Win32) */ TYPE_CDECL, /* cdecl function (Win32) */ TYPE_VARARGS, /* varargs function (Win32) */ - TYPE_THISCALL, /* thiscall function (Win32 on i386) */ TYPE_EXTERN, /* external symbol (Win32) */ TYPE_NBTYPES } ORD_TYPE; @@ -173,6 +172,7 @@ struct strarray #define FLAG_REGISTER 0x10 /* use register calling convention */ #define FLAG_PRIVATE 0x20 /* function is private (cannot be imported) */ #define FLAG_ORDINAL 0x40 /* function should be imported by ordinal */ +#define FLAG_THISCALL 0x80 /* use thiscall calling convention */
#define FLAG_FORWARD 0x100 /* function is a forwarded name */ #define FLAG_EXT_LINK 0x200 /* function links to an external symbol */ diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 5e5866c..893691e 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -466,7 +466,6 @@ static void check_undefined_exports( DLLSPEC *spec ) case TYPE_STDCALL: case TYPE_CDECL: case TYPE_VARARGS: - case TYPE_THISCALL: if (link_ext_symbols) { odp->flags |= FLAG_EXT_LINK; @@ -1444,7 +1443,6 @@ static void build_unix_import_lib( DLLSPEC *spec ) case TYPE_VARARGS: case TYPE_CDECL: case TYPE_STDCALL: - case TYPE_THISCALL: prefix = (!odp->name || (odp->flags & FLAG_ORDINAL)) ? import_ord_prefix : import_func_prefix; new_output_as_file( spec->file_name ); output( "\t.text\n" ); diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index ad99654..11b05aa 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -56,7 +56,6 @@ static const char * const TypeNames[TYPE_NBTYPES] = "stdcall", /* TYPE_STDCALL */ "cdecl", /* TYPE_CDECL */ "varargs", /* TYPE_VARARGS */ - "thiscall", /* TYPE_THISCALL */ "extern" /* TYPE_EXTERN */ };
@@ -69,6 +68,7 @@ static const char * const FlagNames[] = "register", /* FLAG_REGISTER */ "private", /* FLAG_PRIVATE */ "ordinal", /* FLAG_ORDINAL */ + "thiscall", /* FLAG_THISCALL */ NULL };
@@ -287,10 +287,18 @@ static int parse_spec_arguments( ORDDEF *odp, DLLSPEC *spec, int optional ) }
odp->u.func.nb_args = i; - if (odp->type == TYPE_THISCALL && (!i || odp->u.func.args[0] != ARG_PTR)) + if (odp->flags & FLAG_THISCALL) { - error( "First argument of a thiscall function must be a pointer\n" ); - return 0; + if (odp->type != TYPE_STDCALL) + { + error( "A thiscall function must use the stdcall convention\n" ); + return 0; + } + if (!i || odp->u.func.args[0] != ARG_PTR) + { + error( "First argument of a thiscall function must be a pointer\n" ); + return 0; + } } return 1; } @@ -311,11 +319,6 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) error( "'stdcall' not supported for Win16\n" ); return 0; } - if (!is_win32 && odp->type == TYPE_THISCALL) - { - error( "'thiscall' not supported for Win16\n" ); - return 0; - } if (is_win32 && odp->type == TYPE_PASCAL) { error( "'pascal' not supported for Win32\n" ); @@ -327,6 +330,9 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) if (odp->type == TYPE_VARARGS) odp->flags |= FLAG_NORELAY; /* no relay debug possible for varags entry point */
+ if (target_cpu != CPU_x86) + odp->flags &= ~FLAG_THISCALL; + if (!(token = GetToken(1))) { if (!strcmp( odp->name, "@" )) @@ -349,7 +355,7 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec ) odp->flags |= FLAG_FORWARD; } } - if (target_cpu == CPU_x86 && odp->type == TYPE_THISCALL && !(odp->flags & FLAG_FORWARD)) + if ((odp->flags & FLAG_THISCALL) && !(odp->flags & FLAG_FORWARD)) { char *link_name = strmake( "__thiscall_%s", odp->link_name ); free( odp->link_name ); @@ -506,6 +512,7 @@ static const char *parse_spec_flags( DLLSPEC *spec, ORDDEF *odp ) error( "Flag '%s' is not supported in Win32\n", FlagNames[i] ); break; case FLAG_RET64: + case FLAG_THISCALL: if (spec->type == SPEC_WIN16) error( "Flag '%s' is not supported in Win16\n", FlagNames[i] ); break; @@ -538,8 +545,16 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
if (odp->type >= TYPE_NBTYPES) { - error( "Expected type after ordinal, found '%s' instead\n", token ); - goto error; + if (!strcmp( token, "thiscall" )) /* for backwards compatibility */ + { + odp->type = TYPE_STDCALL; + odp->flags |= FLAG_THISCALL; + } + else + { + error( "Expected type after ordinal, found '%s' instead\n", token ); + goto error; + } }
if (!(token = GetToken(0))) goto error; @@ -571,7 +586,6 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec ) case TYPE_STDCALL: case TYPE_VARARGS: case TYPE_CDECL: - case TYPE_THISCALL: if (!parse_spec_export( odp, spec )) goto error; break; case TYPE_ABS: diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 3552eca..1b4e534 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -58,7 +58,6 @@ static inline int needs_relay( const ORDDEF *odp ) { case TYPE_STDCALL: case TYPE_CDECL: - case TYPE_THISCALL: break; case TYPE_STUB: if (odp->u.func.nb_args != -1) break; @@ -129,7 +128,7 @@ static void get_arg_string( ORDDEF *odp, char str[MAX_ARGUMENTS + 1] ) break; } } - if (target_cpu == CPU_x86 && odp->type == TYPE_THISCALL) str[0] = 't'; + if (odp->flags & FLAG_THISCALL) str[0] = 't';
/* append return value */ if (get_ptr_size() == 4 && (odp->flags & FLAG_RET64)) @@ -225,7 +224,7 @@ static void output_relay_debug( DLLSPEC *spec ) switch (target_cpu) { case CPU_x86: - if (odp->type == TYPE_THISCALL) /* add the this pointer */ + if (odp->flags & FLAG_THISCALL) /* add the this pointer */ { output( "\tpopl %%eax\n" ); output( "\tpushl %%ecx\n" ); @@ -246,7 +245,7 @@ static void output_relay_debug( DLLSPEC *spec )
output( "\tcall *4(%%eax)\n" ); output_cfi( ".cfi_adjust_cfa_offset -8" ); - if (odp->type == TYPE_STDCALL || odp->type == TYPE_THISCALL) + if (odp->type == TYPE_STDCALL) output( "\tret $%u\n", get_args_size( odp )); else output( "\tret\n" ); @@ -392,7 +391,6 @@ void output_exports( DLLSPEC *spec ) case TYPE_STDCALL: case TYPE_VARARGS: case TYPE_CDECL: - case TYPE_THISCALL: if (odp->flags & FLAG_FORWARD) { output( "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size ); @@ -953,7 +951,6 @@ void output_def_file( DLLSPEC *spec, int include_private ) /* fall through */ case TYPE_VARARGS: case TYPE_CDECL: - case TYPE_THISCALL: /* try to reduce output */ if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD)) output( "=%s", odp->link_name ); @@ -969,7 +966,8 @@ void output_def_file( DLLSPEC *spec, int include_private ) else if (strcmp(name, odp->link_name)) /* try to reduce output */ { output( "=%s", odp->link_name ); - if (!kill_at && target_cpu == CPU_x86) output( "@%d", at_param ); + if (!kill_at && target_cpu == CPU_x86 && !(odp->flags & FLAG_THISCALL)) + output( "@%d", at_param ); } break; } diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index 51ad544..4455e63 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -299,6 +299,12 @@ accessed through GetProcAddress. The entry point will be imported by ordinal instead of by name. The name is still exported. .TP +.B -thiscall +The function uses the +.I thiscall +calling convention (first parameter in %ecx register on i386). +.TP +.RE .BI -arch= cpu\fR[\fB,\fIcpu\fR] The entry point is only available on the specified CPU architecture(s). The names \fBwin32\fR and \fBwin64\fR match all @@ -335,11 +341,6 @@ for a Win16 or Win32 function using the C calling convention .B varargs for a Win16 or Win32 function using the C calling convention with a variable number of arguments -.TP -.B thiscall -for a Win32 function using the -.I thiscall -calling convention (first parameter in %ecx register on i386) .RE .PP .I args