Commit 470cbf27 authored by Alexandre Julliard's avatar Alexandre Julliard

Added support for defining forward functions as stdcall so that we can

get the proper number of arguments for stdcall decoration.
parent f1b4819e
......@@ -221,7 +221,7 @@
@ stub DefineDosDeviceW
@ stub DelayLoadFailureHook
@ stdcall DeleteAtom(long) DeleteAtom
@ forward DeleteCriticalSection ntdll.RtlDeleteCriticalSection
@ stdcall DeleteCriticalSection(ptr) ntdll.RtlDeleteCriticalSection
@ stdcall DeleteFileA(str) DeleteFileA
@ stdcall DeleteFileW(wstr) DeleteFileW
@ stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) DeviceIoControl
......@@ -231,7 +231,7 @@
@ stdcall DuplicateHandle(long long long ptr long long long) DuplicateHandle
@ stub EndUpdateResourceA
@ stub EndUpdateResourceW
@ forward EnterCriticalSection ntdll.RtlEnterCriticalSection
@ stdcall EnterCriticalSection(ptr) ntdll.RtlEnterCriticalSection
@ stdcall EnumCalendarInfoA(ptr long long long) EnumCalendarInfoA
@ stub EnumCalendarInfoW
@ stub EnumCalendarInfoExA
......@@ -542,15 +542,15 @@
@ stub Heap32ListFirst
@ stub Heap32ListNext
@ stub Heap32Next
@ forward HeapAlloc ntdll.RtlAllocateHeap
@ stdcall HeapAlloc(long long long) ntdll.RtlAllocateHeap
@ stdcall HeapCompact(long long) HeapCompact
@ stdcall HeapCreate(long long long) HeapCreate
@ stdcall HeapDestroy(long) HeapDestroy
@ forward HeapFree ntdll.RtlFreeHeap
@ stdcall HeapFree(long long long) ntdll.RtlFreeHeap
@ stdcall HeapLock(long) HeapLock
@ forward HeapReAlloc ntdll.RtlReAllocateHeap
@ stdcall HeapReAlloc(long long ptr long) ntdll.RtlReAllocateHeap
@ stub HeapSetFlags
@ forward HeapSize ntdll.RtlSizeHeap
@ stdcall HeapSize(long long ptr) ntdll.RtlSizeHeap
@ stdcall HeapUnlock(long) HeapUnlock
@ stdcall HeapValidate(long long ptr) HeapValidate
@ stdcall HeapWalk(long ptr) HeapWalk
......@@ -579,7 +579,7 @@
@ stdcall -register -i386 K32Thk1632Prolog() K32Thk1632Prolog
@ stdcall LCMapStringA(long long str long ptr long) LCMapStringA
@ stdcall LCMapStringW(long long wstr long ptr long) LCMapStringW
@ forward LeaveCriticalSection ntdll.RtlLeaveCriticalSection
@ stdcall LeaveCriticalSection(ptr) ntdll.RtlLeaveCriticalSection
@ stdcall LoadLibraryA(str) LoadLibraryA
@ stdcall LoadLibraryExA( str long long) LoadLibraryExA
@ stdcall LoadLibraryExW(wstr long long) LoadLibraryExW
......@@ -693,10 +693,10 @@
@ stdcall ResetEvent(long) ResetEvent
@ stub ResetWriteWatch
@ stdcall ResumeThread(long) ResumeThread
@ forward RtlFillMemory NTDLL.RtlFillMemory
@ forward RtlMoveMemory NTDLL.RtlMoveMemory
@ forward RtlUnwind NTDLL.RtlUnwind
@ forward RtlZeroMemory NTDLL.RtlZeroMemory
@ stdcall RtlFillMemory(ptr long long) ntdll.RtlFillMemory
@ stdcall RtlMoveMemory(ptr ptr long) ntdll.RtlMoveMemory
@ stdcall RtlUnwind(ptr ptr ptr long) ntdll.RtlUnwind
@ stdcall RtlZeroMemory(ptr long) ntdll.RtlZeroMemory
@ stdcall -register -i386 SMapLS() SMapLS
@ stdcall -register -i386 SMapLS_IP_EBP_12() SMapLS_IP_EBP_12
@ stdcall -register -i386 SMapLS_IP_EBP_16() SMapLS_IP_EBP_16
......@@ -1020,7 +1020,7 @@
@ stub SignalObjectAndWait
@ stub SwitchToFiber
@ stdcall SwitchToThread() SwitchToThread
@ forward TryEnterCriticalSection ntdll.RtlTryEnterCriticalSection
@ stdcall TryEnterCriticalSection(ptr) ntdll.RtlTryEnterCriticalSection
@ stdcall VirtualAllocEx(long ptr long long long) VirtualAllocEx
@ stdcall VirtualFreeEx(long ptr long long) VirtualFreeEx
@ stub WriteFileGather
......
......@@ -109,6 +109,7 @@ typedef struct
#define FLAG_I386 0x08 /* function is i386 only */
#define FLAG_REGISTER 0x10 /* use register calling convention */
#define FLAG_INTERRUPT 0x20 /* function is an interrupt handler */
#define FLAG_FORWARD 0x100 /* function is a forwarded name */
/* Offset of a structure field relative to the start of the struct */
#define STRUCTOFFSET(type,field) ((int)&((type *)0)->field)
......
......@@ -559,7 +559,7 @@ static void warn_unused( const struct import* imp )
for (i = Base; i <= Limit; i++)
{
ORDDEF *odp = Ordinals[i];
if (!odp || odp->type != TYPE_FORWARD) continue;
if (!odp || !(odp->flags & FLAG_FORWARD)) continue;
if (!strncasecmp( odp->link_name, imp->dll, len ) &&
odp->link_name[len] == '.')
return; /* found an import, do not warn */
......
......@@ -244,6 +244,11 @@ static void ParseExportFunction( ORDDEF *odp )
if (odp->type == TYPE_VARARGS)
odp->flags |= FLAG_NORELAY; /* no relay debug possible for varags entry point */
odp->link_name = xstrdup( GetToken(0) );
if (strchr( odp->link_name, '.' ))
{
if (SpecType == SPEC_WIN16) fatal_error( "Forwarded functions not supported for Win16\n" );
odp->flags |= FLAG_FORWARD;
}
}
......@@ -299,6 +304,7 @@ static void ParseForward( ORDDEF *odp )
{
if (SpecType == SPEC_WIN16) fatal_error( "'forward' not supported for Win16\n" );
odp->link_name = xstrdup( GetToken(0) );
odp->flags |= FLAG_FORWARD;
}
......
......@@ -173,8 +173,16 @@ static int output_exports( FILE *outfile, int nr_exports )
case TYPE_STDCALL:
case TYPE_VARARGS:
case TYPE_CDECL:
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n",
(odp->flags & FLAG_REGISTER) ? make_internal_name(odp,"regs") : odp->link_name );
if (!(odp->flags & FLAG_FORWARD))
{
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n",
(odp->flags & FLAG_REGISTER) ? make_internal_name(odp,"regs") : odp->link_name );
break;
}
/* else fall through */
case TYPE_FORWARD:
fprintf( outfile, " \"\\t.long __wine_spec_forwards+%d\\n\"\n", fwd_size );
fwd_size += strlen(odp->link_name) + 1;
break;
case TYPE_STUB:
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", make_internal_name( odp, "stub" ) );
......@@ -182,10 +190,6 @@ static int output_exports( FILE *outfile, int nr_exports )
case TYPE_VARIABLE:
fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", make_internal_name( odp, "var" ) );
break;
case TYPE_FORWARD:
fprintf( outfile, " \"\\t.long __wine_spec_forwards+%d\\n\"\n", fwd_size );
fwd_size += strlen(odp->link_name) + 1;
break;
default:
assert(0);
}
......@@ -237,7 +241,7 @@ static int output_exports( FILE *outfile, int nr_exports )
for (i = Base; i <= Limit; i++)
{
ORDDEF *odp = Ordinals[i];
if (odp && odp->type == TYPE_FORWARD)
if (odp && (odp->flags & FLAG_FORWARD))
fprintf( outfile, " \"\\t" STRING " \\\"%s\\\"\\n\"\n", odp->link_name );
}
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) );
......@@ -258,8 +262,8 @@ static int output_exports( FILE *outfile, int nr_exports )
if (!odp) goto ignore;
/* skip non-functions */
if ((odp->type != TYPE_STDCALL) && (odp->type != TYPE_CDECL)) goto ignore;
/* skip norelay entry points */
if (odp->flags & FLAG_NORELAY) goto ignore;
/* skip norelay and forward entry points */
if (odp->flags & (FLAG_NORELAY|FLAG_FORWARD)) goto ignore;
for (j = 0; odp->u.func.arg_types[j]; j++)
{
......@@ -852,15 +856,18 @@ void BuildDef32File(FILE *outfile)
case TYPE_VARARGS:
case TYPE_CDECL:
/* try to reduce output */
if(strcmp(name, odp->link_name))
if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD))
fprintf(outfile, "=%s", odp->link_name);
break;
case TYPE_STDCALL:
{
int at_param = strlen(odp->u.func.arg_types) * sizeof(int);
if (!kill_at) fprintf(outfile, "@%d", at_param);
/* try to reduce output */
if(strcmp(name, odp->link_name))
if (odp->flags & FLAG_FORWARD)
{
fprintf(outfile, "=%s", odp->link_name);
}
else if (strcmp(name, odp->link_name)) /* try to reduce output */
{
fprintf(outfile, "=%s", odp->link_name);
if (!kill_at) fprintf(outfile, "@%d", at_param);
......
......@@ -308,7 +308,10 @@ are valid for Win32 functions.
.PP
.I handler
is the name of the actual C function that will implement that entry
point in 32-bit mode.
point in 32-bit mode. The handler can also be specified as
.IB dllname . function
to define a forwarded function (one whose implementation is in another
dll).
.PP
This first example defines an entry point for the 16-bit
CreateWindow() call (the ordinal 100 is just an example):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment