From 7662ea100426f6bb062190dd90d9e4fef099a62d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 14 Dec 2001 23:14:22 +0000 Subject: [PATCH] Made register and interrupt flags instead of entry point types, so that we can have both stdcall and cdecl register functions. Changed 16-bit .spec.c file generation to avoid including builtin16.h. --- Make.rules.in | 4 +- dlls/kernel/kernel.spec | 34 ++--- dlls/kernel/kernel32.spec | 131 +++++++++--------- dlls/kernel/thunk.c | 6 +- dlls/kernel/win87em.spec | 2 +- dlls/kernel/windebug.spec | 2 +- dlls/kernel/wprocs.spec | 68 ++++----- dlls/ntdll/ntdll.spec | 4 +- if1632/builtin.c | 67 ++------- if1632/relay.c | 233 ++++++++++++++++++------------- include/builtin16.h | 43 +++--- relay32/relay386.c | 224 +++++++++++++++--------------- tools/winebuild/README | 16 +-- tools/winebuild/build.h | 4 +- tools/winebuild/import.c | 7 +- tools/winebuild/parser.c | 33 +---- tools/winebuild/spec16.c | 281 +++++++++++++++++++++++--------------- tools/winebuild/spec32.c | 52 ++++--- 18 files changed, 627 insertions(+), 584 deletions(-) diff --git a/Make.rules.in b/Make.rules.in index 8c9cab2c13d..b4d9bf09e27 100644 --- a/Make.rules.in +++ b/Make.rules.in @@ -228,9 +228,9 @@ $(SUBDIRS:%=%/__uninstall__): dummy # Misc. rules -$(SPEC_SRCS:.spec=.spec.c): $(WINEBUILD) $(TOPSRCDIR)/include/builtin16.h +$(SPEC_SRCS:.spec=.spec.c): $(WINEBUILD) -$(GLUE:.c=.glue.c): $(WINEBUILD) $(TOPSRCDIR)/include/builtin16.h +$(GLUE:.c=.glue.c): $(WINEBUILD) $(RC_SRCS:.rc=.res): $(WRC) diff --git a/dlls/kernel/kernel.spec b/dlls/kernel/kernel.spec index 6a3f8391535..5a6025ff5fd 100644 --- a/dlls/kernel/kernel.spec +++ b/dlls/kernel/kernel.spec @@ -61,8 +61,8 @@ rsrc version16.res 52 pascal16 FreeProcInstance(segptr) FreeProcInstance16 53 stub CallProcInstance 54 pascal16 GetInstanceData(word word word) GetInstanceData16 -55 register Catch(ptr) Catch16 -56 register Throw(ptr word) Throw16 +55 pascal -register Catch(ptr) Catch16 +56 pascal -register Throw(ptr word) Throw16 57 pascal16 GetProfileInt(str str s_word) GetProfileInt16 58 pascal16 GetProfileString(str str str ptr word) GetProfileString16 59 pascal16 WriteProfileString(str str str) WriteProfileString16 @@ -98,7 +98,7 @@ rsrc version16.res 88 pascal lstrcpy(segptr str) lstrcpy16 89 pascal lstrcat(segstr str) lstrcat16 90 pascal16 lstrlen(str) lstrlen16 -91 register InitTask() InitTask16 +91 pascal -register InitTask() InitTask16 92 pascal GetTempDrive(word) GetTempDrive 93 pascal16 GetCodeHandle(segptr) GetCodeHandle16 94 pascal16 DefineHandleTable(word) DefineHandleTable16 @@ -109,14 +109,14 @@ rsrc version16.res 99 stub GetLPErrMode 100 pascal16 ValidateCodeSegments() KERNEL_nop 101 stub NoHookDosCall -102 register DOS3Call() DOS3Call -103 register NetBIOSCall() NetBIOSCall16 +102 pascal -register DOS3Call() DOS3Call +103 pascal -register NetBIOSCall() NetBIOSCall16 104 pascal16 GetCodeInfo(segptr ptr) GetCodeInfo16 105 pascal16 GetExeVersion() GetExeVersion16 106 pascal SetSwapAreaSize(word) SetSwapAreaSize16 107 pascal16 SetErrorMode(word) SetErrorMode16 108 pascal16 SwitchStackTo(word word word) SwitchStackTo16 # STO in W2.0 -109 register SwitchStackBack() SwitchStackBack16 # SBACK in W2.0 +109 pascal -register SwitchStackBack() SwitchStackBack16 # SBACK in W2.0 110 pascal PatchCodeHandle(word) PatchCodeHandle16 111 pascal GlobalWire(word) GlobalWire16 112 pascal16 GlobalUnWire(word) GlobalUnWire16 @@ -211,7 +211,7 @@ rsrc version16.res 200 pascal16 ValidateFreeSpaces() KERNEL_nop 201 stub ReplaceInst 202 stub RegisterPtrace -203 register DebugBreak() DebugBreak16 +203 pascal -register DebugBreak() DebugBreak16 204 stub SwapRecording 205 stub CVWBreak 206 pascal16 AllocSelectorArray(word) AllocSelectorArray16 @@ -274,7 +274,7 @@ rsrc version16.res 324 pascal16 LogError(word ptr) LogError16 325 pascal16 LogParamError(word ptr ptr) LogParamError16 326 pascal16 IsRomFile(word) IsRomFile16 -327 register K327() HandleParamError +327 pascal -register K327() HandleParamError 328 pascal16 _DebugOutput() _DebugOutput 329 pascal16 K329(str word) DebugFillBuffer 332 variable THHOOK(0 0 0 0 0 0 0 0) @@ -313,7 +313,7 @@ rsrc version16.res 360 pascal16 OpenFileEx(str ptr word) OpenFile16 361 pascal16 PIGLET_361() KERNEL_nop 362 stub ThunkTerminateProcess -365 register GlobalChangeLockCount(word word) GlobalChangeLockCount16 +365 pascal -register GlobalChangeLockCount(word word) GlobalChangeLockCount16 # 403-404 are common to all versions @@ -382,8 +382,8 @@ rsrc version16.res 469 stub WOAGimmeTitle 470 stub WOADestroyConsole 471 pascal GetCurrentProcessId() GetCurrentProcessId -472 register MapHInstLS() MapHInstLS -473 register MapHInstSL() MapHInstSL +472 pascal -register MapHInstLS() MapHInstLS +473 pascal -register MapHInstSL() MapHInstSL 474 pascal CloseW32Handle(long) CloseHandle 475 pascal16 GetTEBSelectorFS() GetTEBSelectorFS16 476 pascal ConvertToGlobalHandle(long) ConvertToGlobalHandle @@ -482,7 +482,7 @@ rsrc version16.res 601 stub FreeCodeAlias 602 pascal16 GetDummyModuleHandleDS() GetDummyModuleHandleDS16 603 stub KERNEL_603 # OutputDebugString (?) -604 register CBClientGlueSL() CBClientGlueSL +604 pascal -register CBClientGlueSL() CBClientGlueSL # FIXME: 605 is duplicate of 562 605 pascal AllocSLThunkletCallback_dup(long long) AllocSLThunkletCallback16 # FIXME: 606 is duplicate of 561 @@ -502,16 +502,16 @@ rsrc version16.res 617 pascal16 GetMenu32Size(ptr) GetMenu32Size16 618 pascal16 GetDialog32Size(ptr) GetDialog32Size16 619 pascal16 RegisterCBClient(word segptr long) RegisterCBClient16 -620 register CBClientThunkSL() CBClientThunkSL -621 register CBClientThunkSLEx() CBClientThunkSLEx +620 pascal -register CBClientThunkSL() CBClientThunkSL +621 pascal -register CBClientThunkSLEx() CBClientThunkSLEx 622 pascal16 UnRegisterCBClient(word segptr long) UnRegisterCBClient16 623 pascal16 InitCBClient(long) InitCBClient16 624 pascal SetFastQueue(long long) SetFastQueue16 625 pascal GetFastQueue() GetFastQueue16 626 stub SmashEnvironment 627 pascal16 IsBadFlatReadWritePtr(segptr long word) IsBadFlatReadWritePtr16 -630 register C16ThkSL() C16ThkSL -631 register C16ThkSL01() C16ThkSL01 +630 pascal -register C16ThkSL() C16ThkSL +631 pascal -register C16ThkSL01() C16ThkSL01 651 pascal ThunkConnect16(str str word long ptr str word) ThunkConnect16 652 stub IsThreadId 653 stub OkWithKernelToChangeUsers @@ -529,7 +529,7 @@ rsrc version16.res 701 stub SSOnBigStack 702 stub SSCall 703 stub CallProc32WFix -704 register SSConfirmSmallStack() SSConfirmSmallStack +704 pascal -register SSConfirmSmallStack() SSConfirmSmallStack # Win95 krnl386.exe also exports ordinals 802-864, diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index 8ae4dfd1fb2..da07c7818c3 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -17,15 +17,15 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) # - code generated by the MS Thunk Compiler # - symbols exported by the Oct 94 beta version of kernel32.dll - 1 register -i386 VxDCall0(long) VxDCall - 2 register -i386 VxDCall1(long) VxDCall - 3 register -i386 VxDCall2(long) VxDCall - 4 register -i386 VxDCall3(long) VxDCall - 5 register -i386 VxDCall4(long) VxDCall - 6 register -i386 VxDCall5(long) VxDCall - 7 register -i386 VxDCall6(long) VxDCall - 8 register -i386 VxDCall7(long) VxDCall - 9 register -i386 VxDCall8(long) VxDCall + 1 stdcall -register -i386 VxDCall0(long) VxDCall + 2 stdcall -register -i386 VxDCall1(long) VxDCall + 3 stdcall -register -i386 VxDCall2(long) VxDCall + 4 stdcall -register -i386 VxDCall3(long) VxDCall + 5 stdcall -register -i386 VxDCall4(long) VxDCall + 6 stdcall -register -i386 VxDCall5(long) VxDCall + 7 stdcall -register -i386 VxDCall6(long) VxDCall + 8 stdcall -register -i386 VxDCall7(long) VxDCall + 9 stdcall -register -i386 VxDCall8(long) VxDCall 10 stdcall k32CharToOemA(str ptr) k32CharToOemA 11 stdcall k32CharToOemBuffA(str ptr long) k32CharToOemBuffA 12 stdcall k32OemToCharA(ptr ptr) k32OemToCharA @@ -33,7 +33,7 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) 14 stdcall k32LoadStringA(long long ptr long) k32LoadStringA 15 varargs k32wsprintfA(str str) k32wsprintfA 16 stdcall k32wvsprintfA(ptr str ptr) k32wvsprintfA - 17 register -i386 CommonUnimpStub() CommonUnimpStub + 17 stdcall -register -i386 CommonUnimpStub() CommonUnimpStub 18 stdcall GetProcessDword(long long) GetProcessDword 19 stub ThunkTheTemplateHandle 20 stdcall DosFileHandleToWin32Handle(long) DosFileHandleToWin32Handle @@ -54,20 +54,20 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) 35 stdcall LoadLibrary16(str) LoadLibrary16 36 stdcall FreeLibrary16(long) FreeLibrary16 37 stdcall GetProcAddress16(long str) WIN32_GetProcAddress16 - 38 register -i386 AllocMappedBuffer() AllocMappedBuffer - 39 register -i386 FreeMappedBuffer() FreeMappedBuffer - 40 register -i386 OT_32ThkLSF() OT_32ThkLSF + 38 stdcall -register -i386 AllocMappedBuffer() AllocMappedBuffer + 39 stdcall -register -i386 FreeMappedBuffer() FreeMappedBuffer + 40 stdcall -register -i386 OT_32ThkLSF() OT_32ThkLSF 41 stdcall ThunkInitLSF(long str long str str) ThunkInitLSF - 42 register -i386 LogApiThkLSF(str) LogApiThkLSF + 42 stdcall -register -i386 LogApiThkLSF(str) LogApiThkLSF 43 stdcall ThunkInitLS(long str long str str) ThunkInitLS - 44 register -i386 LogApiThkSL(str) LogApiThkSL - 45 register -i386 Common32ThkLS() Common32ThkLS + 44 stdcall -register -i386 LogApiThkSL(str) LogApiThkSL + 45 stdcall -register -i386 Common32ThkLS() Common32ThkLS 46 stdcall ThunkInitSL(long str long str str) ThunkInitSL - 47 register -i386 LogCBThkSL(str) LogCBThkSL + 47 stdcall -register -i386 LogCBThkSL(str) LogCBThkSL 48 stdcall ReleaseThunkLock(ptr) ReleaseThunkLock 49 stdcall RestoreThunkLock(long) RestoreThunkLock - 51 register -i386 W32S_BackTo32() W32S_BackTo32 + 51 stdcall -register -i386 W32S_BackTo32() W32S_BackTo32 52 stdcall GetThunkBuff() GetThunkBuff 53 stdcall GetThunkStuff(str str) GetThunkStuff 54 stdcall K32WOWCallback16(long long) K32WOWCallback16 @@ -105,8 +105,8 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) 86 stdcall @(ptr) _KERNEL32_86 87 stdcall SSOnBigStack() SSOnBigStack 88 varargs SSCall(long long ptr) SSCall - 89 register -i386 FT_PrologPrime() FT_PrologPrime - 90 register -i386 QT_ThunkPrime() QT_ThunkPrime + 89 stdcall -register -i386 FT_PrologPrime() FT_PrologPrime + 90 stdcall -register -i386 QT_ThunkPrime() QT_ThunkPrime 91 stdcall PK16FNF(ptr) PK16FNF 92 stdcall GetPK16SysVar() GetPK16SysVar 93 stdcall GetpWin16Lock(ptr) GetpWin16Lock @@ -259,23 +259,23 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) @ stdcall ExitThread(long) ExitThread @ stdcall ExpandEnvironmentStringsA(str ptr long) ExpandEnvironmentStringsA @ stdcall ExpandEnvironmentStringsW(wstr ptr long) ExpandEnvironmentStringsW -@ register -i386 FT_Exit0() FT_Exit0 -@ register -i386 FT_Exit12() FT_Exit12 -@ register -i386 FT_Exit16() FT_Exit16 -@ register -i386 FT_Exit20() FT_Exit20 -@ register -i386 FT_Exit24() FT_Exit24 -@ register -i386 FT_Exit28() FT_Exit28 -@ register -i386 FT_Exit32() FT_Exit32 -@ register -i386 FT_Exit36() FT_Exit36 -@ register -i386 FT_Exit40() FT_Exit40 -@ register -i386 FT_Exit44() FT_Exit44 -@ register -i386 FT_Exit48() FT_Exit48 -@ register -i386 FT_Exit4() FT_Exit4 -@ register -i386 FT_Exit52() FT_Exit52 -@ register -i386 FT_Exit56() FT_Exit56 -@ register -i386 FT_Exit8() FT_Exit8 -@ register -i386 FT_Prolog() FT_Prolog -@ register -i386 FT_Thunk() FT_Thunk +@ stdcall -register -i386 FT_Exit0() FT_Exit0 +@ stdcall -register -i386 FT_Exit12() FT_Exit12 +@ stdcall -register -i386 FT_Exit16() FT_Exit16 +@ stdcall -register -i386 FT_Exit20() FT_Exit20 +@ stdcall -register -i386 FT_Exit24() FT_Exit24 +@ stdcall -register -i386 FT_Exit28() FT_Exit28 +@ stdcall -register -i386 FT_Exit32() FT_Exit32 +@ stdcall -register -i386 FT_Exit36() FT_Exit36 +@ stdcall -register -i386 FT_Exit40() FT_Exit40 +@ stdcall -register -i386 FT_Exit44() FT_Exit44 +@ stdcall -register -i386 FT_Exit48() FT_Exit48 +@ stdcall -register -i386 FT_Exit4() FT_Exit4 +@ stdcall -register -i386 FT_Exit52() FT_Exit52 +@ stdcall -register -i386 FT_Exit56() FT_Exit56 +@ stdcall -register -i386 FT_Exit8() FT_Exit8 +@ stdcall -register -i386 FT_Prolog() FT_Prolog +@ stdcall -register -i386 FT_Thunk() FT_Thunk @ stdcall FatalAppExitA(long str) FatalAppExitA @ stdcall FatalAppExitW(long wstr) FatalAppExitW @ stub FatalExit @@ -531,8 +531,8 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) @ stub IsSLCallback @ stdcall IsValidCodePage(long) IsValidCodePage @ stdcall IsValidLocale(long long) IsValidLocale -@ register -i386 K32Thk1632Epilog() K32Thk1632Epilog -@ register -i386 K32Thk1632Prolog() K32Thk1632Prolog +@ stdcall -register -i386 K32Thk1632Epilog() K32Thk1632Epilog +@ 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 @@ -557,10 +557,10 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) @ stdcall LockFileEx(long long long long long ptr) LockFileEx @ stdcall LockResource(long) LockResource @ stdcall MakeCriticalSectionGlobal(ptr) MakeCriticalSectionGlobal -@ register -i386 MapHInstLS() MapHInstLS -@ register -i386 MapHInstLS_PN() MapHInstLS_PN -@ register -i386 MapHInstSL() MapHInstSL -@ register -i386 MapHInstSL_PN() MapHInstSL_PN +@ stdcall -register -i386 MapHInstLS() MapHInstLS +@ stdcall -register -i386 MapHInstLS_PN() MapHInstLS_PN +@ stdcall -register -i386 MapHInstSL() MapHInstSL +@ stdcall -register -i386 MapHInstSL_PN() MapHInstSL_PN @ stdcall MapHModuleLS(long) MapHModuleLS @ stdcall MapHModuleSL(long) MapHModuleSL @ stdcall MapLS(ptr) MapLS @@ -602,7 +602,7 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) @ stdcall Process32Next (ptr ptr) Process32Next @ stdcall PulseEvent(long) PulseEvent @ stdcall PurgeComm(long long) PurgeComm -@ register -i386 QT_Thunk() QT_Thunk +@ stdcall -register -i386 QT_Thunk() QT_Thunk @ stdcall QueryDosDeviceA(str ptr long) QueryDosDeviceA @ stdcall QueryDosDeviceW(wstr ptr long) QueryDosDeviceW @ stub QueryNumberOfEventLogRecords @@ -635,26 +635,26 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) @ forward RtlMoveMemory NTDLL.RtlMoveMemory @ forward RtlUnwind NTDLL.RtlUnwind @ forward RtlZeroMemory NTDLL.RtlZeroMemory -@ register -i386 SMapLS() SMapLS -@ register -i386 SMapLS_IP_EBP_12() SMapLS_IP_EBP_12 -@ register -i386 SMapLS_IP_EBP_16() SMapLS_IP_EBP_16 -@ register -i386 SMapLS_IP_EBP_20() SMapLS_IP_EBP_20 -@ register -i386 SMapLS_IP_EBP_24() SMapLS_IP_EBP_24 -@ register -i386 SMapLS_IP_EBP_28() SMapLS_IP_EBP_28 -@ register -i386 SMapLS_IP_EBP_32() SMapLS_IP_EBP_32 -@ register -i386 SMapLS_IP_EBP_36() SMapLS_IP_EBP_36 -@ register -i386 SMapLS_IP_EBP_40() SMapLS_IP_EBP_40 -@ register -i386 SMapLS_IP_EBP_8() SMapLS_IP_EBP_8 -@ register -i386 SUnMapLS() SUnMapLS -@ register -i386 SUnMapLS_IP_EBP_12() SUnMapLS_IP_EBP_12 -@ register -i386 SUnMapLS_IP_EBP_16() SUnMapLS_IP_EBP_16 -@ register -i386 SUnMapLS_IP_EBP_20() SUnMapLS_IP_EBP_20 -@ register -i386 SUnMapLS_IP_EBP_24() SUnMapLS_IP_EBP_24 -@ register -i386 SUnMapLS_IP_EBP_28() SUnMapLS_IP_EBP_28 -@ register -i386 SUnMapLS_IP_EBP_32() SUnMapLS_IP_EBP_32 -@ register -i386 SUnMapLS_IP_EBP_36() SUnMapLS_IP_EBP_36 -@ register -i386 SUnMapLS_IP_EBP_40() SUnMapLS_IP_EBP_40 -@ register -i386 SUnMapLS_IP_EBP_8() SUnMapLS_IP_EBP_8 +@ 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 +@ stdcall -register -i386 SMapLS_IP_EBP_20() SMapLS_IP_EBP_20 +@ stdcall -register -i386 SMapLS_IP_EBP_24() SMapLS_IP_EBP_24 +@ stdcall -register -i386 SMapLS_IP_EBP_28() SMapLS_IP_EBP_28 +@ stdcall -register -i386 SMapLS_IP_EBP_32() SMapLS_IP_EBP_32 +@ stdcall -register -i386 SMapLS_IP_EBP_36() SMapLS_IP_EBP_36 +@ stdcall -register -i386 SMapLS_IP_EBP_40() SMapLS_IP_EBP_40 +@ stdcall -register -i386 SMapLS_IP_EBP_8() SMapLS_IP_EBP_8 +@ stdcall -register -i386 SUnMapLS() SUnMapLS +@ stdcall -register -i386 SUnMapLS_IP_EBP_12() SUnMapLS_IP_EBP_12 +@ stdcall -register -i386 SUnMapLS_IP_EBP_16() SUnMapLS_IP_EBP_16 +@ stdcall -register -i386 SUnMapLS_IP_EBP_20() SUnMapLS_IP_EBP_20 +@ stdcall -register -i386 SUnMapLS_IP_EBP_24() SUnMapLS_IP_EBP_24 +@ stdcall -register -i386 SUnMapLS_IP_EBP_28() SUnMapLS_IP_EBP_28 +@ stdcall -register -i386 SUnMapLS_IP_EBP_32() SUnMapLS_IP_EBP_32 +@ stdcall -register -i386 SUnMapLS_IP_EBP_36() SUnMapLS_IP_EBP_36 +@ stdcall -register -i386 SUnMapLS_IP_EBP_40() SUnMapLS_IP_EBP_40 +@ stdcall -register -i386 SUnMapLS_IP_EBP_8() SUnMapLS_IP_EBP_8 @ stdcall ScrollConsoleScreenBufferA(long ptr ptr ptr ptr) ScrollConsoleScreenBufferA @ stdcall ScrollConsoleScreenBufferW(long ptr ptr ptr ptr) ScrollConsoleScreenBufferW @ stdcall SearchPathA(str str str long ptr ptr) SearchPathA @@ -744,7 +744,7 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) @ stdcall UTRegister(long str str str ptr ptr ptr) UTRegister @ stdcall UTUnRegister(long) UTUnRegister @ stdcall UnMapLS(long) UnMapLS -@ register -i386 UnMapSLFixArray(long long) UnMapSLFixArray +@ stdcall -register -i386 UnMapSLFixArray(long long) UnMapSLFixArray @ stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter @ stdcall UninitializeCriticalSection(ptr) UninitializeCriticalSection @ stdcall UnlockFile(long long long long long) UnlockFile @@ -996,7 +996,6 @@ debug_channels (comm debugstr dll int resource stress thunk toolhelp win32) @ varargs __wine_call_from_16_word() __wine_call_from_16_word @ varargs __wine_call_from_16_long() __wine_call_from_16_long @ varargs __wine_call_from_16_regs() __wine_call_from_16_regs -@ varargs __wine_call_from_16_thunk() __wine_call_from_16_thunk @ stdcall wine_call_to_16_word(ptr long) wine_call_to_16_word @ stdcall wine_call_to_16_long(ptr long) wine_call_to_16_long @ stdcall wine_call_to_16_regs_short(ptr long) wine_call_to_16_regs_short diff --git a/dlls/kernel/thunk.c b/dlls/kernel/thunk.c index 5c1b2a01b49..44cac8a3e71 100644 --- a/dlls/kernel/thunk.c +++ b/dlls/kernel/thunk.c @@ -16,7 +16,6 @@ #include "winerror.h" #include "wine/winbase16.h" -#include "builtin16.h" #include "callback.h" #include "debugtools.h" #include "flatthunk.h" @@ -28,6 +27,11 @@ DEFAULT_DEBUG_CHANNEL(thunk); +#ifdef __i386__ +extern void __wine_call_from_16_thunk(); +#else +static void __wine_call_from_16_thunk() { } +#endif /*********************************************************************** * * diff --git a/dlls/kernel/win87em.spec b/dlls/kernel/win87em.spec index b5615335111..79eb3372f31 100644 --- a/dlls/kernel/win87em.spec +++ b/dlls/kernel/win87em.spec @@ -2,7 +2,7 @@ name win87em type win16 owner kernel32 -1 register _fpMath() WIN87_fpmath +1 pascal -register _fpMath() WIN87_fpmath 3 pascal16 __WinEm87Info(ptr word) WIN87_WinEm87Info 4 pascal16 __WinEm87Restore(ptr word) WIN87_WinEm87Restore 5 pascal16 __WinEm87Save(ptr word) WIN87_WinEm87Save diff --git a/dlls/kernel/windebug.spec b/dlls/kernel/windebug.spec index 08db7571344..4dcb921ba9c 100644 --- a/dlls/kernel/windebug.spec +++ b/dlls/kernel/windebug.spec @@ -4,4 +4,4 @@ owner kernel32 1 stub WINDEBUG 2 stub WEP - 3 register WinNotify() WinNotify16 + 3 pascal -register WinNotify() WinNotify16 diff --git a/dlls/kernel/wprocs.spec b/dlls/kernel/wprocs.spec index eeafdf5643a..d9ca913f25f 100644 --- a/dlls/kernel/wprocs.spec +++ b/dlls/kernel/wprocs.spec @@ -3,43 +3,43 @@ type win16 owner kernel32 # Interrupt vectors 0-255 are ordinals 100-355 -# The 'interrupt' keyword takes care of the flags pushed on the stack by the interrupt -117 interrupt INT_Int11Handler() INT_Int11Handler -118 interrupt INT_Int12Handler() INT_Int12Handler -119 interrupt INT_Int13Handler() INT_Int13Handler -121 interrupt INT_Int15Handler() INT_Int15Handler -126 interrupt INT_Int1aHandler() INT_Int1aHandler -132 interrupt INT_Int20Handler() INT_Int20Handler -133 interrupt INT_Int21Handler() DOS3Call +# The '-interrupt' keyword takes care of the flags pushed on the stack by the interrupt +117 pascal -interrupt INT_Int11Handler() INT_Int11Handler +118 pascal -interrupt INT_Int12Handler() INT_Int12Handler +119 pascal -interrupt INT_Int13Handler() INT_Int13Handler +121 pascal -interrupt INT_Int15Handler() INT_Int15Handler +126 pascal -interrupt INT_Int1aHandler() INT_Int1aHandler +132 pascal -interrupt INT_Int20Handler() INT_Int20Handler +133 pascal -interrupt INT_Int21Handler() DOS3Call # Note: int 25 and 26 don't pop the flags from the stack -137 register INT_Int25Handler() INT_Int25Handler -138 register INT_Int26Handler() INT_Int26Handler -142 interrupt INT_Int2aHandler() INT_Int2aHandler -147 interrupt INT_Int2fHandler() INT_Int2fHandler -149 interrupt INT_Int31Handler() INT_Int31Handler -161 interrupt INT_Int3dHandler() INT_Int3dHandler -165 interrupt INT_Int41Handler() INT_Int41Handler -175 interrupt INT_Int4bHandler() INT_Int4bHandler -192 interrupt INT_Int5cHandler() NetBIOSCall16 +137 pascal -register INT_Int25Handler() INT_Int25Handler +138 pascal -register INT_Int26Handler() INT_Int26Handler +142 pascal -interrupt INT_Int2aHandler() INT_Int2aHandler +147 pascal -interrupt INT_Int2fHandler() INT_Int2fHandler +149 pascal -interrupt INT_Int31Handler() INT_Int31Handler +161 pascal -interrupt INT_Int3dHandler() INT_Int3dHandler +165 pascal -interrupt INT_Int41Handler() INT_Int41Handler +175 pascal -interrupt INT_Int4bHandler() INT_Int4bHandler +192 pascal -interrupt INT_Int5cHandler() NetBIOSCall16 # default handler for unimplemented interrupts -356 interrupt INT_DefaultHandler() INT_DefaultHandler +356 pascal -interrupt INT_DefaultHandler() INT_DefaultHandler # VxDs. The first Vxd is at 400 # -#400+VXD_ID register () +#400+VXD_ID pascal -register () # -401 register VXD_VMM() VXD_VMM -405 register VXD_Timer() VXD_Timer -409 register VXD_Reboot() VXD_Reboot -410 register VXD_VDD() VXD_VDD -412 register VXD_VMD() VXD_VMD -414 register VXD_Comm() VXD_Comm -#415 register VXD_Printer() VXD_Printer -423 register VXD_Shell() VXD_Shell -433 register VXD_PageFile() VXD_PageFile -438 register VXD_APM() VXD_APM -439 register VXD_VXDLoader() VXD_VXDLoader -445 register VXD_Win32s() VXD_Win32s -451 register VXD_ConfigMG() VXD_ConfigMG -455 register VXD_Enable() VXD_Enable -1490 register VXD_TimerAPI() VXD_TimerAPI +401 pascal -register VXD_VMM() VXD_VMM +405 pascal -register VXD_Timer() VXD_Timer +409 pascal -register VXD_Reboot() VXD_Reboot +410 pascal -register VXD_VDD() VXD_VDD +412 pascal -register VXD_VMD() VXD_VMD +414 pascal -register VXD_Comm() VXD_Comm +#415 pascal -register VXD_Printer() VXD_Printer +423 pascal -register VXD_Shell() VXD_Shell +433 pascal -register VXD_PageFile() VXD_PageFile +438 pascal -register VXD_APM() VXD_APM +439 pascal -register VXD_VXDLoader() VXD_VXDLoader +445 pascal -register VXD_Win32s() VXD_Win32s +451 pascal -register VXD_ConfigMG() VXD_ConfigMG +455 pascal -register VXD_Enable() VXD_Enable +1490 pascal -register VXD_TimerAPI() VXD_TimerAPI diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index e12175ecf3c..3ac3485667f 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -878,11 +878,11 @@ debug_channels (atom cdrom console debug delayhlp dll dosfs dosmem file fixup @ stub __eGetStatusWord @ stdcall -ret64 _alldiv(long long long long) _alldiv @ stdcall -ret64 _allmul(long long long long) _allmul -@ register -i386 _alloca_probe() NTDLL_alloca_probe +@ stdcall -register -i386 _alloca_probe() NTDLL_alloca_probe @ stdcall -ret64 _allrem(long long long long) _allrem @ stdcall -ret64 _aulldiv(long long long long) _aulldiv @ stdcall -ret64 _aullrem(long long long long) _aullrem -@ register -i386 _chkstk() NTDLL_chkstk +@ stdcall -register -i386 _chkstk() NTDLL_chkstk @ stub _fltused @ cdecl _ftol() NTDLL__ftol @ cdecl _itoa(long ptr long) _itoa diff --git a/if1632/builtin.c b/if1632/builtin.c index bffd41b538c..d8a2df1ff88 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -21,6 +21,16 @@ DEFAULT_DEBUG_CHANNEL(module); +typedef struct +{ + void *module_start; /* 32-bit address of the module data */ + int module_size; /* Size of the module data */ + void *code_start; /* 32-bit address of DLL code */ + void *data_start; /* 32-bit address of DLL data */ + const char *owner; /* 32-bit dll that contains this dll */ + const void *rsrc; /* resources data */ +} BUILTIN16_DESCRIPTOR; + /* Table of all built-in DLLs */ #define MAX_DLLS 50 @@ -167,63 +177,6 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name ) } -/*********************************************************************** - * BUILTIN_GetEntryPoint16 - * - * Return the ordinal, name, and type info corresponding to a CS:IP address. - * This is used only by relay debugging. - */ -LPCSTR BUILTIN_GetEntryPoint16( STACK16FRAME *frame, LPSTR name, WORD *pOrd ) -{ - WORD i, max_offset; - register BYTE *p; - NE_MODULE *pModule; - ET_BUNDLE *bundle; - ET_ENTRY *entry; - - if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16( frame->module_cs ) )))) - return NULL; - - max_offset = 0; - *pOrd = 0; - bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table); - do - { - entry = (ET_ENTRY *)((BYTE *)bundle+6); - for (i = bundle->first + 1; i <= bundle->last; i++) - { - if ((entry->offs < frame->entry_ip) - && (entry->segnum == 1) /* code segment ? */ - && (entry->offs >= max_offset)) - { - max_offset = entry->offs; - *pOrd = i; - } - entry++; - } - } while ( (bundle->next) - && (bundle = (ET_BUNDLE *)((BYTE *)pModule+bundle->next))); - - /* Search for the name in the resident names table */ - /* (built-in modules have no non-resident table) */ - - p = (BYTE *)pModule + pModule->name_table; - while (*p) - { - p += *p + 1 + sizeof(WORD); - if (*(WORD *)(p + *p + 1) == *pOrd) break; - } - - sprintf( name, "%.*s.%d: %.*s", - *((BYTE *)pModule + pModule->name_table), - (char *)pModule + pModule->name_table + 1, - *pOrd, *p, (char *)(p + 1) ); - - /* Retrieve type info string */ - return *(LPCSTR *)((LPBYTE)MapSL( MAKESEGPTR( frame->module_cs, frame->callfrom_ip )) + 4); -} - - /*********************************************************************** * __wine_register_dll_16 (KERNEL32.@) * diff --git a/if1632/relay.c b/if1632/relay.c index f73c2560d01..597dc1db827 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -6,6 +6,8 @@ #include #include #include +#include + #include "wine/winbase16.h" #include "winnt.h" #include "module.h" @@ -116,14 +118,6 @@ void __wine_call_from_16_regs() assert( FALSE ); } -/*********************************************************************** - * __wine_call_from_16_thunk (KERNEL32.@) - */ -void __wine_call_from_16_thunk() -{ - assert( FALSE ); -} - DWORD WINAPI CALL32_CBClient( FARPROC proc, LPWORD args, DWORD *esi ) { assert( FALSE ); } @@ -136,6 +130,65 @@ DWORD WINAPI CALL32_CBClientEx( FARPROC proc, LPWORD args, DWORD *esi, INT *nArg extern char **debug_relay_excludelist,**debug_relay_includelist; extern int RELAY_ShowDebugmsgRelay(const char *func); + +/*********************************************************************** + * get_entry_point + * + * Return the ordinal, name, and type info corresponding to a CS:IP address. + */ +static const CALLFROM16 *get_entry_point( STACK16FRAME *frame, LPSTR name, WORD *pOrd ) +{ + WORD i, max_offset; + register BYTE *p; + NE_MODULE *pModule; + ET_BUNDLE *bundle; + ET_ENTRY *entry; + + if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16( frame->module_cs ) )))) + return NULL; + + max_offset = 0; + *pOrd = 0; + bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table); + do + { + entry = (ET_ENTRY *)((BYTE *)bundle+6); + for (i = bundle->first + 1; i <= bundle->last; i++) + { + if ((entry->offs < frame->entry_ip) + && (entry->segnum == 1) /* code segment ? */ + && (entry->offs >= max_offset)) + { + max_offset = entry->offs; + *pOrd = i; + } + entry++; + } + } while ( (bundle->next) + && (bundle = (ET_BUNDLE *)((BYTE *)pModule+bundle->next))); + + /* Search for the name in the resident names table */ + /* (built-in modules have no non-resident table) */ + + p = (BYTE *)pModule + pModule->name_table; + while (*p) + { + p += *p + 1 + sizeof(WORD); + if (*(WORD *)(p + *p + 1) == *pOrd) break; + } + + sprintf( name, "%.*s.%d: %.*s", + *((BYTE *)pModule + pModule->name_table), + (char *)pModule + pModule->name_table + 1, + *pOrd, *p, (char *)(p + 1) ); + + /* Retrieve entry point call structure */ + p = MapSL( MAKESEGPTR( frame->module_cs, frame->callfrom_ip ) ); + /* p now points to lret, get the start of CALLFROM16 structure */ + return (CALLFROM16 *)(p - (BYTE *)&((CALLFROM16 *)0)->lret); +} + + /*********************************************************************** * RELAY_DebugCallFrom16 */ @@ -144,111 +197,101 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context ) STACK16FRAME *frame; WORD ordinal; char *args16, funstr[80]; - const char *args; - int i, usecdecl, reg_func; + const CALLFROM16 *call; + int i; if (!TRACE_ON(relay)) return; frame = CURRENT_STACK16; - args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal ); - if (!args) return; /* happens for the two snoop register relays */ + call = get_entry_point( frame, funstr, &ordinal ); + if (!call) return; /* happens for the two snoop register relays */ if (!RELAY_ShowDebugmsgRelay(funstr)) return; DPRINTF( "%08lx:Call %s(",GetCurrentThreadId(),funstr); VA_START16( args16 ); - usecdecl = ( *args == 'c' ); - args += 2; - reg_func = ( memcmp( args, "regs_", 5 ) == 0 - || memcmp( args, "intr_", 5 ) == 0 ); - args += 5; - - if (usecdecl) + if (call->lret == 0xcb66) /* cdecl */ { - while (*args) + for (i = 0; i < 20; i++) { - switch(*args) + int type = (call->arg_types[i / 10] >> (3 * (i % 10))) & 7; + + if (type == ARG_NONE) break; + if (i) DPRINTF( "," ); + switch(type) { - case 'w': - case 's': - DPRINTF( "0x%04x", *(WORD *)args16 ); - args16 += 2; + case ARG_WORD: + case ARG_SWORD: + DPRINTF( "%04x", *(WORD *)args16 ); + args16 += sizeof(WORD); break; - case 'l': - DPRINTF( "0x%08x", *(int *)args16 ); - args16 += 4; + case ARG_LONG: + DPRINTF( "%08x", *(int *)args16 ); + args16 += sizeof(int); break; - case 'p': + case ARG_PTR: DPRINTF( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 ); - args16 += 4; + args16 += sizeof(SEGPTR); break; - case 't': - case 'T': + case ARG_STR: + DPRINTF( "%08x %s", *(int *)args16, + debugres_a( MapSL(*(SEGPTR *)args16 ))); + args16 += sizeof(int); + break; + case ARG_SEGSTR: DPRINTF( "%04x:%04x %s", *(WORD *)(args16+2), *(WORD *)args16, debugres_a( MapSL(*(SEGPTR *)args16 )) ); - args16 += 4; + args16 += sizeof(SEGPTR); + break; + default: break; } - args++; - if (*args) DPRINTF( "," ); } } else /* not cdecl */ { /* Start with the last arg */ - for (i = 0; args[i]; i++) + args16 += call->nArgs; + for (i = 0; i < 20; i++) { - switch(args[i]) - { - case 'w': - case 's': - args16 += 2; - break; - case 'l': - case 'p': - case 't': - case 'T': - args16 += 4; - break; - } - } + int type = (call->arg_types[i / 10] >> (3 * (i % 10))) & 7; - while (*args) - { - switch(*args) + if (type == ARG_NONE) break; + if (i) DPRINTF( "," ); + switch(type) { - case 'w': - case 's': - args16 -= 2; - DPRINTF( "0x%04x", *(WORD *)args16 ); + case ARG_WORD: + case ARG_SWORD: + args16 -= sizeof(WORD); + DPRINTF( "%04x", *(WORD *)args16 ); break; - case 'l': - args16 -= 4; - DPRINTF( "0x%08x", *(int *)args16 ); + case ARG_LONG: + args16 -= sizeof(int); + DPRINTF( "%08x", *(int *)args16 ); break; - case 't': - args16 -= 4; - DPRINTF( "0x%08x %s", *(int *)args16, - debugres_a( MapSL(*(SEGPTR *)args16 ))); - break; - case 'p': - args16 -= 4; + case ARG_PTR: + args16 -= sizeof(SEGPTR); DPRINTF( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 ); break; - case 'T': - args16 -= 4; - DPRINTF( "%04x:%04x %s", *(WORD *)(args16+2), *(WORD *)args16, + case ARG_STR: + args16 -= sizeof(int); + DPRINTF( "%08x %s", *(int *)args16, debugres_a( MapSL(*(SEGPTR *)args16 ))); break; + case ARG_SEGSTR: + args16 -= sizeof(SEGPTR); + DPRINTF( "%04x:%04x %s", *(WORD *)(args16+2), *(WORD *)args16, + debugres_a( MapSL(*(SEGPTR *)args16 )) ); + break; + default: + break; } - args++; - if (*args) DPRINTF( "," ); } } DPRINTF( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds ); VA_END16( args16 ); - if (reg_func) + if (call->arg_types[0] & ARG_REGISTER) DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n", AX_reg(context), BX_reg(context), CX_reg(context), DX_reg(context), SI_reg(context), DI_reg(context), @@ -266,27 +309,16 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val ) STACK16FRAME *frame; WORD ordinal; char funstr[80]; - const char *args; + const CALLFROM16 *call; if (!TRACE_ON(relay)) return; frame = CURRENT_STACK16; - args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal ); - if (!args) return; + call = get_entry_point( frame, funstr, &ordinal ); + if (!call) return; if (!RELAY_ShowDebugmsgRelay(funstr)) return; DPRINTF( "%08lx:Ret %s() ",GetCurrentThreadId(),funstr); - if ( memcmp( args+2, "long_", 5 ) == 0 ) - { - DPRINTF( "retval=0x%08x ret=%04x:%04x ds=%04x\n", - ret_val, frame->cs, frame->ip, frame->ds ); - } - else if ( memcmp( args+2, "word_", 5 ) == 0 ) - { - DPRINTF( "retval=0x%04x ret=%04x:%04x ds=%04x\n", - ret_val & 0xffff, frame->cs, frame->ip, frame->ds ); - } - else if ( memcmp( args+2, "regs_", 5 ) == 0 - || memcmp( args+2, "intr_", 5 ) == 0 ) + if (call->arg_types[0] & ARG_REGISTER) { DPRINTF("retval=none ret=%04x:%04x ds=%04x\n", (WORD)context->SegCs, LOWORD(context->Eip), (WORD)context->SegDs); @@ -295,7 +327,16 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val ) DX_reg(context), SI_reg(context), DI_reg(context), (WORD)context->SegEs, context->EFlags ); } - + else if (call->arg_types[0] & ARG_RET16) + { + DPRINTF( "retval=%04x ret=%04x:%04x ds=%04x\n", + ret_val & 0xffff, frame->cs, frame->ip, frame->ds ); + } + else + { + DPRINTF( "retval=%08x ret=%04x:%04x ds=%04x\n", + ret_val, frame->cs, frame->ip, frame->ds ); + } SYSLEVEL_CheckNotLevel( 2 ); } @@ -326,10 +367,10 @@ void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func ) DPRINTF("%08lx:CallTo16(func=%04lx:%04x,ds=%04lx", GetCurrentThreadId(), context->SegCs, LOWORD(context->Eip), context->SegDs ); - while (nb_args--) DPRINTF( ",0x%04x", *--stack16 ); - DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack), + while (nb_args--) DPRINTF( ",%04x", *--stack16 ); + DPRINTF(") ss:sp=%04x:%04x", SELECTOROF(teb->cur_stack), OFFSETOF(teb->cur_stack) ); - DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x BP=%04x ES=%04x FS=%04x\n", + DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x si=%04x di=%04x bp=%04x es=%04x fs=%04x\n", AX_reg(context), BX_reg(context), CX_reg(context), DX_reg(context), SI_reg(context), DI_reg(context), BP_reg(context), (WORD)context->SegEs, (WORD)context->SegFs ); @@ -339,7 +380,7 @@ void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func ) DPRINTF("%08lx:CallTo16(func=%04x:%04x,ds=%04x", GetCurrentThreadId(), HIWORD(target), LOWORD(target), SELECTOROF(teb->cur_stack) ); - while (nb_args--) DPRINTF( ",0x%04x", *--stack16 ); + while (nb_args--) DPRINTF( ",%04x", *--stack16 ); DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack), OFFSETOF(teb->cur_stack) ); } @@ -357,7 +398,7 @@ void RELAY_DebugCallTo16Ret( BOOL reg_func, int ret_val ) if (!reg_func) { - DPRINTF("%08lx:RetFrom16() ss:sp=%04x:%04x retval=0x%08x\n", + DPRINTF("%08lx:RetFrom16() ss:sp=%04x:%04x retval=%08x\n", GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack), ret_val); @@ -366,11 +407,11 @@ void RELAY_DebugCallTo16Ret( BOOL reg_func, int ret_val ) { CONTEXT86 *context = (CONTEXT86 *)ret_val; - DPRINTF("%08lx:RetFrom16() ss:sp=%04x:%04x\n", + DPRINTF("%08lx:RetFrom16() ss:sp=%04x:%04x ", GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack)); - DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x BP=%04x SP=%04x\n", + DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x bp=%04x sp=%04x\n", AX_reg(context), BX_reg(context), CX_reg(context), DX_reg(context), BP_reg(context), LOWORD(context->Esp)); } diff --git a/include/builtin16.h b/include/builtin16.h index 390ee0dfc4f..567c8833cb2 100644 --- a/include/builtin16.h +++ b/include/builtin16.h @@ -13,9 +13,10 @@ struct _CONTEXT86; struct _STACK16FRAME; -#ifdef __i386__ #include "pshpack1.h" +#ifdef __i386__ + typedef struct { WORD pushw_bp; /* pushw %bp */ @@ -32,45 +33,51 @@ typedef struct BYTE lcall; /* lcall __FLATCS__:glue */ void *glue; WORD flatcs; - BYTE prefix; /* lret $nArgs */ - BYTE lret; + WORD lret; /* lret $nArgs */ WORD nArgs; - LPCSTR profile; /* profile string */ + DWORD arg_types[2]; /* type of each argument */ } CALLFROM16; -#include "poppack.h" #else typedef struct { void (*target)(); - int callfrom16; + WORD call; /* call CALLFROM16 */ + short callfrom16; } ENTRYPOINT16; typedef struct { - LPCSTR profile; + WORD lret; /* lret $nArgs */ + WORD nArgs; + DWORD arg_types[2]; /* type of each argument */ } CALLFROM16; #endif -typedef struct +#include "poppack.h" + +/* argument type flags for relay debugging */ +enum arg_types { - void *module_start; /* 32-bit address of the module data */ - int module_size; /* Size of the module data */ - void *code_start; /* 32-bit address of DLL code */ - void *data_start; /* 32-bit address of DLL data */ - const char *owner; /* 32-bit dll that contains this dll */ - const void *rsrc; /* resources data */ -} BUILTIN16_DESCRIPTOR; + ARG_NONE = 0, /* indicates end of arg list */ + ARG_WORD, /* unsigned word */ + ARG_SWORD, /* signed word */ + ARG_LONG, /* long or segmented pointer */ + ARG_PTR, /* linear pointer */ + ARG_STR, /* linear pointer to null-terminated string */ + ARG_SEGSTR /* segmented pointer to null-terminated string */ +}; + +/* flags added to arg_types[0] */ +#define ARG_RET16 0x80000000 /* function returns 16-bit value */ +#define ARG_REGISTER 0x40000000 /* function is register */ extern HMODULE16 BUILTIN_LoadModule( LPCSTR name ); -extern LPCSTR BUILTIN_GetEntryPoint16( struct _STACK16FRAME *frame, LPSTR name, WORD *pOrd ); -extern void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr ); extern WORD __wine_call_from_16_word(); extern LONG __wine_call_from_16_long(); extern void __wine_call_from_16_regs(); -extern void __wine_call_from_16_thunk(); #endif /* __WINE_BUILTIN16_H */ diff --git a/relay32/relay386.c b/relay32/relay386.c index 3ea67580265..29b0e05370b 100644 --- a/relay32/relay386.c +++ b/relay32/relay386.c @@ -157,8 +157,108 @@ static inline void RELAY_PrintArgs( int *args, int nb_args, unsigned int typemas } +typedef LONGLONG (*LONGLONG_CPROC)(); typedef LONGLONG WINAPI (*LONGLONG_FARPROC)(); + +/*********************************************************************** + * call_cdecl_function + */ +static LONGLONG call_cdecl_function( LONGLONG_CPROC func, int nb_args, const int *args ) +{ + LONGLONG ret; + switch(nb_args) + { + case 0: ret = func(); break; + case 1: ret = func(args[0]); break; + case 2: ret = func(args[0],args[1]); break; + case 3: ret = func(args[0],args[1],args[2]); break; + case 4: ret = func(args[0],args[1],args[2],args[3]); break; + case 5: ret = func(args[0],args[1],args[2],args[3],args[4]); break; + case 6: ret = func(args[0],args[1],args[2],args[3],args[4], + args[5]); break; + case 7: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6]); break; + case 8: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7]); break; + case 9: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8]); break; + case 10: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9]); break; + case 11: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10]); break; + case 12: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10], + args[11]); break; + case 13: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10],args[11], + args[12]); break; + case 14: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10],args[11], + args[12],args[13]); break; + case 15: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10],args[11], + args[12],args[13],args[14]); break; + case 16: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10],args[11], + args[12],args[13],args[14],args[15]); break; + default: + ERR( "Unsupported nb of args %d\n", nb_args ); + assert(FALSE); + } + return ret; +} + + +/*********************************************************************** + * call_stdcall_function + */ +static LONGLONG call_stdcall_function( LONGLONG_FARPROC func, int nb_args, const int *args ) +{ + LONGLONG ret; + switch(nb_args) + { + case 0: ret = func(); break; + case 1: ret = func(args[0]); break; + case 2: ret = func(args[0],args[1]); break; + case 3: ret = func(args[0],args[1],args[2]); break; + case 4: ret = func(args[0],args[1],args[2],args[3]); break; + case 5: ret = func(args[0],args[1],args[2],args[3],args[4]); break; + case 6: ret = func(args[0],args[1],args[2],args[3],args[4], + args[5]); break; + case 7: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6]); break; + case 8: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7]); break; + case 9: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8]); break; + case 10: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9]); break; + case 11: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10]); break; + case 12: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10], + args[11]); break; + case 13: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10],args[11], + args[12]); break; + case 14: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10],args[11], + args[12],args[13]); break; + case 15: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10],args[11], + args[12],args[13],args[14]); break; + case 16: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], + args[6],args[7],args[8],args[9],args[10],args[11], + args[12],args[13],args[14],args[15]); break; + default: + ERR( "Unsupported nb of args %d\n", nb_args ); + assert(FALSE); + } + return ret; +} + + /*********************************************************************** * RELAY_CallFrom32 * @@ -190,90 +290,13 @@ static LONGLONG RELAY_CallFrom32( int ret_addr, ... ) if (relay->ret == 0xc3) /* cdecl */ { - LONGLONG (*cfunc)() = relay->orig; - switch(nb_args) - { - case 0: ret = cfunc(); break; - case 1: ret = cfunc(args[0]); break; - case 2: ret = cfunc(args[0],args[1]); break; - case 3: ret = cfunc(args[0],args[1],args[2]); break; - case 4: ret = cfunc(args[0],args[1],args[2],args[3]); break; - case 5: ret = cfunc(args[0],args[1],args[2],args[3],args[4]); break; - case 6: ret = cfunc(args[0],args[1],args[2],args[3],args[4], - args[5]); break; - case 7: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6]); break; - case 8: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7]); break; - case 9: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8]); break; - case 10: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9]); break; - case 11: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10]); break; - case 12: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10], - args[11]); break; - case 13: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10],args[11], - args[12]); break; - case 14: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10],args[11], - args[12],args[13]); break; - case 15: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10],args[11], - args[12],args[13],args[14]); break; - case 16: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10],args[11], - args[12],args[13],args[14],args[15]); break; - default: - ERR( "Unsupported nb of args %d\n", nb_args ); - assert(FALSE); - } + ret = call_cdecl_function( (LONGLONG_CPROC)relay->orig, nb_args, args ); } else /* stdcall */ { - LONGLONG_FARPROC func = relay->orig; - switch(nb_args) - { - case 0: ret = func(); break; - case 1: ret = func(args[0]); break; - case 2: ret = func(args[0],args[1]); break; - case 3: ret = func(args[0],args[1],args[2]); break; - case 4: ret = func(args[0],args[1],args[2],args[3]); break; - case 5: ret = func(args[0],args[1],args[2],args[3],args[4]); break; - case 6: ret = func(args[0],args[1],args[2],args[3],args[4], - args[5]); break; - case 7: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6]); break; - case 8: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7]); break; - case 9: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8]); break; - case 10: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9]); break; - case 11: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10]); break; - case 12: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10], - args[11]); break; - case 13: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10],args[11], - args[12]); break; - case 14: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10],args[11], - args[12],args[13]); break; - case 15: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10],args[11], - args[12],args[13],args[14]); break; - case 16: ret = func(args[0],args[1],args[2],args[3],args[4],args[5], - args[6],args[7],args[8],args[9],args[10],args[11], - args[12],args[13],args[14],args[15]); break; - default: - ERR( "Unsupported nb of args %d\n", nb_args ); - assert(FALSE); - } + ret = call_stdcall_function( (LONGLONG_FARPROC)relay->orig, nb_args, args ); } + if (ret64) DPRINTF( "%08lx:Ret %s() retval=%08x%08x ret=%08x\n", GetCurrentThreadId(), @@ -303,7 +326,7 @@ void WINAPI RELAY_DoCallFrom32Regs( CONTEXT86 *context ) { char buffer[80]; int* args; - FARPROC func; + int args_copy[17]; BYTE *entry_point; BYTE *relay_addr = *((BYTE **)context->Esp - 1); @@ -319,7 +342,6 @@ void WINAPI RELAY_DoCallFrom32Regs( CONTEXT86 *context ) entry_point = (BYTE *)relay->orig; assert( *entry_point == 0xe8 /* lcall */ ); - func = *(FARPROC *)(entry_point + 5); get_entry_point( buffer, relay ); @@ -335,36 +357,16 @@ void WINAPI RELAY_DoCallFrom32Regs( CONTEXT86 *context ) context->SegEs, context->SegGs, context->EFlags ); /* Now call the real function */ - switch(nb_args) + + memcpy( args_copy, args, nb_args * sizeof(args[0]) ); + args_copy[nb_args] = (int)context; /* append context argument */ + if (relay->ret == 0xc3) /* cdecl */ { - case 0: func(context); break; - case 1: func(args[0],context); break; - case 2: func(args[0],args[1],context); break; - case 3: func(args[0],args[1],args[2],context); break; - case 4: func(args[0],args[1],args[2],args[3],context); break; - case 5: func(args[0],args[1],args[2],args[3],args[4],context); break; - case 6: func(args[0],args[1],args[2],args[3],args[4],args[5],context); break; - case 7: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],context); break; - case 8: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],context); break; - case 9: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], - context); break; - case 10: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], - args[9],context); break; - case 11: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], - args[9],args[10],context); break; - case 12: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], - args[9],args[10],args[11],context); break; - case 13: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], - args[9],args[10],args[11],args[12],context); break; - case 14: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], - args[9],args[10],args[11],args[12],args[13],context); break; - case 15: func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], - args[9],args[10],args[11],args[12],args[13],args[14],context); break; - case 16: func(args[0],args[1],args[2],args[3],args[4],args[5], args[6],args[7],args[8], - args[9],args[10],args[11],args[12],args[13],args[14],args[15],context); break; - default: - ERR( "Unsupported nb of args %d\n", nb_args ); - assert(FALSE); + call_cdecl_function( *(LONGLONG_CPROC *)(entry_point + 5), nb_args+1, args_copy ); + } + else /* stdcall */ + { + call_stdcall_function( *(LONGLONG_FARPROC *)(entry_point + 5), nb_args+1, args_copy ); } DPRINTF( "%08lx:Ret %s() retval=%08lx ret=%08lx fs=%04lx\n", diff --git a/tools/winebuild/README b/tools/winebuild/README index 3b5310715de..cc49bf3ae6b 100644 --- a/tools/winebuild/README +++ b/tools/winebuild/README @@ -73,12 +73,14 @@ point, or "@" for automatic ordinal allocation (Win32 only). "FLAGS" is a series of optional flags, preceded by a '-' character. The supported flags are: - "-noimport": the entry point is not made available for importing - from winelib applications (Win32 only). - "-norelay": the entry point is not displayed in relay debugging - traces (Win32 only). - "-ret64": the function returns a 64-bit value (Win32 only). - "-i386": the entry point is only available on i386 platforms. + "-noimport": the entry point is not made available for importing + from winelib applications (Win32 only). + "-norelay": the entry point is not displayed in relay debugging + traces (Win32 only). + "-ret64": the function returns a 64-bit value (Win32 only). + "-i386": the entry point is only available on i386 platforms. + "-register": the function uses CPU register to pass arguments. + "-interrupt": the function is an interrupt handler routine. Lines whose first character is a '#' will be ignored as comments. @@ -105,8 +107,6 @@ instead of "EXPORTNAME" for ordinal-only exports. "FUNCTYPE" should be one of: - "pascal16" for a Win16 function returning a 16-bit value - "pascal" for a Win16 function returning a 32-bit value -- "register" for a function using CPU register to pass arguments -- "interrupt" for a Win16 interrupt handler routine - "stdcall" for a normal Win32 function - "cdecl" for a Win32 function using the C calling convention - "varargs" for a Win32 function taking a variable number of arguments diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index e47949717fe..9a5e382c7af 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -40,8 +40,6 @@ typedef enum TYPE_PASCAL_16, /* pascal function with 16-bit return (Win16) */ TYPE_PASCAL, /* pascal function with 32-bit return (Win16) */ TYPE_ABS, /* absolute value (Win16) */ - TYPE_REGISTER, /* register function */ - TYPE_INTERRUPT, /* interrupt handler function (Win16) */ TYPE_STUB, /* unimplemented stub */ TYPE_STDCALL, /* stdcall function (Win32) */ TYPE_CDECL, /* cdecl function (Win32) */ @@ -106,6 +104,8 @@ typedef struct #define FLAG_NORELAY 0x02 /* don't use relay debugging for this function */ #define FLAG_RET64 0x04 /* function returns a 64-bit value */ #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 */ /* Offset of a structure field relative to the start of the struct */ #define STRUCTOFFSET(type,field) ((int)&((type *)0)->field) diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index d0a2c8cf669..2fda7860981 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -250,8 +250,11 @@ static void add_extra_undef_symbols(void) for (i = 0; i < nb_entry_points; i++) { ORDDEF *odp = EntryPoints[i]; - if (odp->type != TYPE_REGISTER) continue; - ADD_SYM( "__wine_call_from_32_regs" ); + if (odp->flags & FLAG_REGISTER) + { + ADD_SYM( "__wine_call_from_32_regs" ); + break; + } } if (count) diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 14842610ac2..b483e98ed4e 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -35,8 +35,6 @@ static const char * const TypeNames[TYPE_NBTYPES] = "pascal16", /* TYPE_PASCAL_16 */ "pascal", /* TYPE_PASCAL */ "equate", /* TYPE_ABS */ - "register", /* TYPE_REGISTER */ - "interrupt", /* TYPE_INTERRUPT */ "stub", /* TYPE_STUB */ "stdcall", /* TYPE_STDCALL */ "cdecl", /* TYPE_CDECL */ @@ -51,6 +49,8 @@ static const char * const FlagNames[] = "norelay", /* FLAG_NORELAY */ "ret64", /* FLAG_RET64 */ "i386", /* FLAG_I386 */ + "register", /* FLAG_REGISTER */ + "interrupt", /* FLAG_INTERRUPT */ NULL }; @@ -214,6 +214,8 @@ static void ParseExportFunction( ORDDEF *odp ) case SPEC_WIN32: if ((odp->type == TYPE_PASCAL) || (odp->type == TYPE_PASCAL_16)) fatal_error( "'pascal' not supported for Win32\n" ); + if (odp->flags & FLAG_INTERRUPT) + fatal_error( "'interrupt' not supported for Win32\n" ); break; default: break; @@ -302,29 +304,6 @@ static void ParseStub( ORDDEF *odp ) } -/******************************************************************* - * ParseInterrupt - * - * Parse an 'interrupt' definition. - */ -static void ParseInterrupt( ORDDEF *odp ) -{ - const char *token; - - if (SpecType == SPEC_WIN32) - fatal_error( "'interrupt' not supported for Win32\n" ); - - token = GetToken(0); - if (*token != '(') fatal_error( "Expected '(' got '%s'\n", token ); - - token = GetToken(0); - if (*token != ')') fatal_error( "Expected ')' got '%s'\n", token ); - - odp->u.func.arg_types[0] = '\0'; - odp->link_name = xstrdup( GetToken(0) ); -} - - /******************************************************************* * ParseExtern * @@ -423,7 +402,6 @@ static void ParseOrdinal(int ordinal) case TYPE_VARIABLE: ParseVariable( odp ); break; - case TYPE_REGISTER: case TYPE_PASCAL_16: case TYPE_PASCAL: case TYPE_STDCALL: @@ -431,9 +409,6 @@ static void ParseOrdinal(int ordinal) case TYPE_CDECL: ParseExportFunction( odp ); break; - case TYPE_INTERRUPT: - ParseInterrupt( odp ); - break; case TYPE_ABS: ParseEquate( odp ); break; diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 39e50d5d82f..ef842d1bf07 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -27,6 +27,28 @@ __ASM_GLOBAL_FUNC( __get_cs, "movw %cs,%ax\n\tret" ); #endif /* __i386__ */ +/******************************************************************* + * output_file_header + * + * Output a file header with the common declarations we need. + */ +static void output_file_header( FILE *outfile ) +{ + fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n", + input_file_name ); + fprintf( outfile, "extern struct\n{\n" ); + fprintf( outfile, " void *base[8192];\n" ); + fprintf( outfile, " unsigned long limit[8192];\n" ); + fprintf( outfile, " unsigned char flags[8192];\n" ); + fprintf( outfile, "} wine_ldt_copy;\n\n" ); +#ifdef __i386__ + fprintf( outfile, "#define __stdcall __attribute__((__stdcall__))\n\n" ); +#else + fprintf( outfile, "#define __stdcall\n\n" ); +#endif +} + + /******************************************************************* * StoreVariableCode * @@ -200,8 +222,6 @@ static int BuildModule16( FILE *outfile, int max_code_offset, case TYPE_CDECL: case TYPE_PASCAL: case TYPE_PASCAL_16: - case TYPE_REGISTER: - case TYPE_INTERRUPT: case TYPE_STUB: selector = 1; /* Code selector */ break; @@ -323,7 +343,6 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile, char *prefix, int case 's': /* s_word */ argsize += 2; break; - case 'l': /* long or segmented pointer */ case 'T': /* segmented pointer to null-terminated string */ case 'p': /* linear pointer */ @@ -332,34 +351,32 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile, char *prefix, int break; } - ret_type = reg_func? "void" : short_ret? "WORD" : "LONG"; + ret_type = reg_func? "void" : short_ret ? "unsigned short" : "unsigned int"; - fprintf( outfile, "typedef %s WINAPI (*proc_%s_t)( ", - ret_type, profile ); + fprintf( outfile, "typedef %s __stdcall (*proc_%s_t)( ", ret_type, profile ); args = profile + 7; for ( i = 0; args[i]; i++ ) { if ( i ) fprintf( outfile, ", " ); switch (args[i]) { - case 'w': fprintf( outfile, "WORD" ); break; - case 's': fprintf( outfile, "INT16" ); break; - case 'l': case 'T': fprintf( outfile, "LONG" ); break; - case 'p': case 't': fprintf( outfile, "LPVOID" ); break; + case 'w': fprintf( outfile, "unsigned short" ); break; + case 's': fprintf( outfile, "short" ); break; + case 'l': case 'T': fprintf( outfile, "unsigned int" ); break; + case 'p': case 't': fprintf( outfile, "void *" ); break; } } if ( reg_func ) - fprintf( outfile, "%sstruct _CONTEXT86 *", i? ", " : "" ); + fprintf( outfile, "%svoid *", i? ", " : "" ); else if ( !i ) fprintf( outfile, "void" ); fprintf( outfile, " );\n" ); - - fprintf( outfile, "%s%s WINAPI %s_CallFrom16_%s( FARPROC proc, LPBYTE args%s )\n{\n", - local? "static " : "", ret_type, prefix, profile, - reg_func? ", struct _CONTEXT86 *context" : "" ); - fprintf( outfile, " %s((proc_%s_t) proc) (\n", - reg_func? "" : "return ", profile ); + fprintf( outfile, "%s%s __stdcall %s_CallFrom16_%s( proc_%s_t proc, unsigned char *args%s )\n", + local? "static " : "", ret_type, prefix, profile, profile, + reg_func? ", void *context" : "" ); + + fprintf( outfile, "{\n %sproc(\n", reg_func ? "" : "return " ); args = profile + 7; pos = !usecdecl? argsize : 0; for ( i = 0; args[i]; i++ ) @@ -370,27 +387,27 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile, char *prefix, int { case 'w': /* word */ if ( !usecdecl ) pos -= 2; - fprintf( outfile, "*(WORD *)(args+%d)", pos ); + fprintf( outfile, "*(unsigned short *)(args+%d)", pos ); if ( usecdecl ) pos += 2; break; case 's': /* s_word */ if ( !usecdecl ) pos -= 2; - fprintf( outfile, "*(INT16 *)(args+%d)", pos ); + fprintf( outfile, "*(short *)(args+%d)", pos ); if ( usecdecl ) pos += 2; break; case 'l': /* long or segmented pointer */ case 'T': /* segmented pointer to null-terminated string */ if ( !usecdecl ) pos -= 4; - fprintf( outfile, "*(LONG *)(args+%d)", pos ); + fprintf( outfile, "*(unsigned int *)(args+%d)", pos ); if ( usecdecl ) pos += 4; break; case 'p': /* linear pointer */ case 't': /* linear pointer to null-terminated string */ if ( !usecdecl ) pos -= 4; - fprintf( outfile, "((char*)wine_ldt_copy.base[*(WORD*)(args+%d) >> 3] + *(WORD*)(args+%d))", + fprintf( outfile, "((char*)wine_ldt_copy.base[*(unsigned short*)(args+%d) >> 3] + *(unsigned short*)(args+%d))", pos + 2, pos ); if ( usecdecl ) pos += 4; break; @@ -435,31 +452,44 @@ static void BuildCallTo16Func( FILE *outfile, char *profile, char *prefix ) exit(1); } - fprintf( outfile, "%s CALLBACK %s_CallTo16_%s( FARPROC16 proc", - short_ret? "WORD" : "LONG", prefix, profile ); + fprintf( outfile, "unsigned %s __stdcall %s_CallTo16_%s( void (*proc)()", + short_ret? "short" : "int", prefix, profile ); args = profile + 5; for ( i = 0; args[i]; i++ ) { fprintf( outfile, ", " ); switch (args[i]) { - case 'w': fprintf( outfile, "WORD" ); argsize += 2; break; - case 'l': fprintf( outfile, "LONG" ); argsize += 4; break; + case 'w': fprintf( outfile, "unsigned short" ); argsize += 2; break; + case 'l': fprintf( outfile, "unsigned int" ); argsize += 4; break; } fprintf( outfile, " arg%d", i+1 ); } fprintf( outfile, " )\n{\n" ); +#ifdef __i386__ if ( argsize > 0 ) - fprintf( outfile, " LPBYTE args = (LPBYTE)CURRENT_STACK16;\n" ); + { + fprintf( outfile, " char *args;\n" ); + fprintf( outfile, " unsigned int cur_stack;\n\n" ); + fprintf( outfile, "#ifdef __GNUC__\n" ); + fprintf( outfile, " __asm__(\".byte 0x64\\n\\tmovl (0x%x),%%0\" : \"=r\" (cur_stack));\n", + STACKOFFSET ); + fprintf( outfile, "#else\n" ); + fprintf( outfile, " extern char *NtCurrentTeb(void);\n" ); + fprintf( outfile, " cur_stack = *(unsigned int *)(NtCurrentTeb() + 0x%x);\n", + STACKOFFSET ); + fprintf( outfile, "#endif\n" ); + fprintf( outfile, " args = (char *)wine_ldt_copy.base[cur_stack >> 19] + (cur_stack & 0xffff);\n" ); + } args = profile + 5; for ( i = 0; args[i]; i++ ) { switch (args[i]) { - case 'w': fprintf( outfile, " args -= sizeof(WORD); *(WORD" ); break; - case 'l': fprintf( outfile, " args -= sizeof(LONG); *(LONG" ); break; + case 'w': fprintf( outfile, " args -= sizeof(unsigned short); *(unsigned short" ); break; + case 'l': fprintf( outfile, " args -= sizeof(unsigned int); *(unsigned int" ); break; default: fprintf( stderr, "Unexpected case '%c' in BuildCallTo16Func\n", args[i] ); } @@ -468,6 +498,26 @@ static void BuildCallTo16Func( FILE *outfile, char *profile, char *prefix ) fprintf( outfile, " return wine_call_to_16_%s( proc, %d );\n}\n\n", short_ret? "word" : "long", argsize ); +#else /* __i386__ */ + fprintf( outfile, " assert(0);\n}\n\n" ); +#endif /* __i386__ */ +} + + +/******************************************************************* + * get_function_name + */ +static const char *get_function_name( const ORDDEF *odp ) +{ + static char buffer[80]; + + sprintf( buffer, "%s_%s_%s", + (odp->type == TYPE_CDECL) ? "c" : "p", + (odp->flags & FLAG_REGISTER) ? "regs" : + (odp->flags & FLAG_INTERRUPT) ? "intr" : + (odp->type == TYPE_PASCAL_16) ? "word" : "long", + odp->u.func.arg_types ); + return buffer; } @@ -478,18 +528,20 @@ static int Spec16TypeCompare( const void *e1, const void *e2 ) { const ORDDEF *odp1 = *(const ORDDEF **)e1; const ORDDEF *odp2 = *(const ORDDEF **)e2; + int retval; int type1 = (odp1->type == TYPE_CDECL) ? 0 - : (odp1->type == TYPE_REGISTER) ? 3 - : (odp1->type == TYPE_INTERRUPT) ? 4 : (odp1->type == TYPE_PASCAL_16) ? 1 : 2; int type2 = (odp2->type == TYPE_CDECL) ? 0 - : (odp2->type == TYPE_REGISTER) ? 3 - : (odp2->type == TYPE_INTERRUPT) ? 4 : (odp2->type == TYPE_PASCAL_16) ? 1 : 2; - int retval = type1 - type2; + if (odp1->flags & FLAG_REGISTER) type1 += 4; + if (odp1->flags & FLAG_INTERRUPT) type1 += 8; + if (odp2->flags & FLAG_REGISTER) type2 += 4; + if (odp2->flags & FLAG_INTERRUPT) type2 += 8; + + retval = type1 - type2; if ( !retval ) retval = strcmp( odp1->u.func.arg_types, odp2->u.func.arg_types ); @@ -567,15 +619,11 @@ void BuildSpec16File( FILE *outfile ) /* File header */ - fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n", - input_file_name ); - fprintf( outfile, "#include \"builtin16.h\"\n\n" ); - - fprintf( outfile, "extern struct\n{\n" ); - fprintf( outfile, " void *base[8192];\n" ); - fprintf( outfile, " unsigned long limit[8192];\n" ); - fprintf( outfile, " unsigned char flags[8192];\n" ); - fprintf( outfile, "} wine_ldt_copy;\n\n" ); + output_file_header( outfile ); + fprintf( outfile, "extern unsigned short __wine_call_from_16_word();\n" ); + fprintf( outfile, "extern unsigned int __wine_call_from_16_long();\n" ); + fprintf( outfile, "extern void __wine_call_from_16_regs();\n" ); + fprintf( outfile, "extern void __wine_call_from_16_thunk();\n" ); data = (unsigned char *)xmalloc( 0x10000 ); memset( data, 0, 16 ); @@ -584,12 +632,6 @@ void BuildSpec16File( FILE *outfile ) fprintf( outfile, "static const char dllname[] = \"%s\";\n\n", DLLName ); -#ifdef __i386__ - fprintf( outfile, "#define __stdcall __attribute__((__stdcall__))\n\n" ); -#else - fprintf( outfile, "#define __stdcall\n\n" ); -#endif - output_stub_funcs( outfile ); /* Build sorted list of all argument types, without duplicates */ @@ -602,8 +644,6 @@ void BuildSpec16File( FILE *outfile ) if (!odp) continue; switch (odp->type) { - case TYPE_REGISTER: - case TYPE_INTERRUPT: case TYPE_CDECL: case TYPE_PASCAL: case TYPE_PASCAL_16: @@ -631,13 +671,7 @@ void BuildSpec16File( FILE *outfile ) { char profile[101]; - sprintf( profile, "%s_%s_%s", - (typelist[i]->type == TYPE_CDECL) ? "c" : "p", - (typelist[i]->type == TYPE_REGISTER) ? "regs" : - (typelist[i]->type == TYPE_INTERRUPT) ? "intr" : - (typelist[i]->type == TYPE_PASCAL_16) ? "word" : "long", - typelist[i]->u.func.arg_types ); - + strcpy( profile, get_function_name( typelist[i] )); BuildCallFrom16Func( outfile, profile, DLLName, TRUE ); } #endif @@ -650,8 +684,6 @@ void BuildSpec16File( FILE *outfile ) if (!odp) continue; switch(odp->type) { - case TYPE_REGISTER: - case TYPE_INTERRUPT: case TYPE_CDECL: case TYPE_PASCAL: case TYPE_PASCAL_16: @@ -664,23 +696,40 @@ void BuildSpec16File( FILE *outfile ) /* Output code segment */ - fprintf( outfile, "\nstatic struct\n{\n CALLFROM16 call[%d];\n" - " ENTRYPOINT16 entry[%d];\n} Code_Segment = \n{\n {\n", - nTypes, nFuncs ); + fprintf( outfile, "\n#include \"pshpack1.h\"\n" ); + fprintf( outfile, "\nstatic struct code_segment\n{\n" ); + fprintf( outfile, " struct {\n" ); +#ifdef __i386__ + fprintf( outfile, " unsigned char pushl;\n" ); /* pushl $relay */ + fprintf( outfile, " void *relay;\n" ); + fprintf( outfile, " unsigned char lcall;\n" ); /* lcall __FLATCS__:glue */ + fprintf( outfile, " void *glue;\n" ); + fprintf( outfile, " unsigned short flatcs;\n" ); +#endif + fprintf( outfile, " unsigned short lret;\n" ); /* lret $args */ + fprintf( outfile, " unsigned short args;\n" ); + fprintf( outfile, " unsigned int arg_types[2];\n" ); + fprintf( outfile, " } call[%d];\n", nTypes ); + fprintf( outfile, " struct {\n" ); +#ifdef __i386__ + fprintf( outfile, " unsigned short pushw_bp;\n" ); /* pushw %bp */ + fprintf( outfile, " unsigned char pushl;\n" ); /* pushl $target */ +#endif + fprintf( outfile, " void (*target)();\n" ); + fprintf( outfile, " unsigned short call;\n" ); /* call CALLFROM16 */ + fprintf( outfile, " short callfrom16;\n" ); + fprintf( outfile, " } entry[%d];\n", nFuncs ); + fprintf( outfile, "} code_segment =\n{\n {\n" ); + code_offset = 0; for ( i = 0; i < nTypes; i++ ) { char profile[101], *arg; - int argsize = 0; - - sprintf( profile, "%s_%s_%s", - (typelist[i]->type == TYPE_CDECL) ? "c" : "p", - (typelist[i]->type == TYPE_REGISTER) ? "regs" : - (typelist[i]->type == TYPE_INTERRUPT) ? "intr" : - (typelist[i]->type == TYPE_PASCAL_16) ? "word" : "long", - typelist[i]->u.func.arg_types ); + unsigned int arg_types[2]; + int j, argsize = 0; + strcpy( profile, get_function_name( typelist[i] )); if ( typelist[i]->type != TYPE_CDECL ) for ( arg = typelist[i]->u.func.arg_types; *arg; arg++ ) switch ( *arg ) @@ -697,25 +746,46 @@ void BuildSpec16File( FILE *outfile ) break; } - if ( typelist[i]->type == TYPE_INTERRUPT ) - argsize += 2; + if (typelist[i]->flags & FLAG_INTERRUPT) argsize += 2; + + /* build the arg types bit fields */ + arg_types[0] = arg_types[1] = 0; + for (j = 0; typelist[i]->u.func.arg_types[j]; j++) + { + int type = 0; + switch(typelist[i]->u.func.arg_types[j]) + { + case 'w': type = ARG_WORD; break; + case 's': type = ARG_SWORD; break; + case 'l': type = ARG_LONG; break; + case 'p': type = ARG_PTR; break; + case 't': type = ARG_STR; break; + case 'T': type = ARG_SEGSTR; break; + } + arg_types[j / 10] |= type << (3 * (j % 10)); + } + if (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) arg_types[0] |= ARG_REGISTER; + if (typelist[i]->type == TYPE_PASCAL_16) arg_types[0] |= ARG_RET16; #ifdef __i386__ fprintf( outfile, " { 0x68, %s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n", DLLName, profile, - (typelist[i]->type == TYPE_REGISTER - || typelist[i]->type == TYPE_INTERRUPT)? "regs": + (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) ? "regs": typelist[i]->type == TYPE_PASCAL_16? "word" : "long" ); if (argsize) - fprintf( outfile, " 0x%04x, 0x66, 0xca, %d, \"%s\" },\n", - code_selector, argsize, profile ); + fprintf( outfile, " 0x%04x, 0xca66, %d, { 0x%08x, 0x%08x } },\n", + code_selector, argsize, arg_types[0], arg_types[1] ); else - fprintf( outfile, " 0x%04x, 0x66, 0xcb, 0x9090, \"%s\" },\n", - code_selector, profile ); + fprintf( outfile, " 0x%04x, 0xcb66, 0x9090, { 0x%08x, 0x%08x } },\n", + code_selector, arg_types[0], arg_types[1] ); #else - fprintf( outfile, " { \"%s\" },\n", profile ); + if (argsize) + fprintf( outfile, " { 0xca66, %d, { 0x%08x, 0x%08x } },\n", + argsize, arg_types[0], arg_types[1] ); + else + fprintf( outfile, " { 0xcb66, 0x9090, { 0x%08x, 0x%08x } },\n", + arg_types[0], arg_types[1] ); #endif - code_offset += sizeof(CALLFROM16); } fprintf( outfile, " },\n {\n" ); @@ -735,8 +805,6 @@ void BuildSpec16File( FILE *outfile ) data_offset += StoreVariableCode( data + data_offset, 4, odp); break; - case TYPE_REGISTER: - case TYPE_INTERRUPT: case TYPE_CDECL: case TYPE_PASCAL: case TYPE_PASCAL_16: @@ -746,18 +814,14 @@ void BuildSpec16File( FILE *outfile ) fprintf( outfile, " /* %s.%d */ ", DLLName, i ); #ifdef __i386__ - fprintf( outfile, "{ 0x5566, 0x68, %s, 0xe866, %d /* %s_%s_%s */ },\n", + fprintf( outfile, "{ 0x5566, 0x68, %s, 0xe866, %d /* %s */ },\n", #else - fprintf( outfile, "{ %s, %d, /* %s_%s_%s */ },\n", + fprintf( outfile, "{ %s, 0xe866, %d, /* %s */ },\n", #endif odp->link_name, (type-typelist)*sizeof(CALLFROM16) - (code_offset + sizeof(ENTRYPOINT16)), - (odp->type == TYPE_CDECL) ? "c" : "p", - (odp->type == TYPE_REGISTER) ? "regs" : - (odp->type == TYPE_INTERRUPT) ? "intr" : - (odp->type == TYPE_PASCAL_16) ? "word" : "long", - odp->u.func.arg_types ); + get_function_name( odp ) ); odp->offset = code_offset; code_offset += sizeof(ENTRYPOINT16); @@ -783,10 +847,19 @@ void BuildSpec16File( FILE *outfile ) /* Output the DLL descriptor */ - fprintf( outfile, "\nstatic const BUILTIN16_DESCRIPTOR descriptor = \n{\n" ); + fprintf( outfile, "#include \"poppack.h\"\n\n" ); + + fprintf( outfile, "static const struct dll_descriptor\n{\n" ); + fprintf( outfile, " unsigned char *module_start;\n" ); + fprintf( outfile, " int module_size;\n" ); + fprintf( outfile, " struct code_segment *code_start;\n" ); + fprintf( outfile, " unsigned char *data_start;\n" ); + fprintf( outfile, " const char *owner;\n" ); + fprintf( outfile, " const unsigned char *rsrc;\n" ); + fprintf( outfile, "} descriptor =\n{\n" ); fprintf( outfile, " Module,\n" ); fprintf( outfile, " sizeof(Module),\n" ); - fprintf( outfile, " &Code_Segment,\n" ); + fprintf( outfile, " &code_segment,\n" ); fprintf( outfile, " Data_Segment,\n" ); fprintf( outfile, " \"%s\",\n", owner_name ); fprintf( outfile, " %s\n", res_size ? "resource_data" : "0" ); @@ -822,6 +895,7 @@ void BuildSpec16File( FILE *outfile ) fprintf( outfile, "void __wine_spec_%s_init(void)\n" "{\n" + " extern void __wine_register_dll_16( const struct dll_descriptor *descr );\n" " __wine_register_dll_16( &descriptor );\n" "}\n", DLLName ); } @@ -838,12 +912,14 @@ void BuildGlue( FILE *outfile, FILE *infile ) /* File header */ - fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n", - input_file_name ); - fprintf( outfile, "#include \"stackframe.h\"\n\n" ); + output_file_header( outfile ); - fprintf( outfile, "extern WORD WINAPI wine_call_to_16_word( FARPROC16 target, INT nArgs );\n" ); - fprintf( outfile, "extern LONG WINAPI wine_call_to_16_long( FARPROC16 target, INT nArgs );\n" ); +#ifdef __i386__ + fprintf( outfile, "extern unsigned short __stdcall wine_call_to_16_word( void (*target)(), int args );\n" ); + fprintf( outfile, "extern unsigned int __stdcall wine_call_to_16_long( void (*target)(), int args );\n\n" ); +#else + fprintf( outfile, "#include \n\n" ); +#endif /* Build the callback glue functions */ @@ -853,18 +929,7 @@ void BuildGlue( FILE *outfile, FILE *infile ) } while (fgets( buffer, sizeof(buffer), infile )) { - char *p; - if ( (p = strstr( buffer, "CallFrom16_" )) != NULL ) - { - char *q, *profile = p + strlen( "CallFrom16_" ); - for (q = profile; (*q == '_') || isalpha(*q); q++ ) - ; - *q = '\0'; - for (q = p-1; q > buffer && ((*q == '_') || isalnum(*q)); q-- ) - ; - if ( ++q < p ) p[-1] = '\0'; else q = ""; - BuildCallFrom16Func( outfile, profile, q, FALSE ); - } + char *p; if ( (p = strstr( buffer, "CallTo16_" )) != NULL ) { char *q, *profile = p + strlen( "CallTo16_" ); diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index f754c80fbbf..3c600782365 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -159,14 +159,12 @@ static int output_exports( FILE *outfile, int nr_exports ) case TYPE_STDCALL: case TYPE_VARARGS: case TYPE_CDECL: - fprintf( outfile, " \"\\t.long " PREFIX "%s\\n\"\n", odp->link_name); + fprintf( outfile, " \"\\t.long " PREFIX "%s\\n\"\n", + (odp->flags & FLAG_REGISTER) ? make_internal_name(odp,"regs") : odp->link_name ); break; case TYPE_STUB: fprintf( outfile, " \"\\t.long " PREFIX "%s\\n\"\n", make_internal_name( odp, "stub" ) ); break; - case TYPE_REGISTER: - fprintf( outfile, " \"\\t.long " PREFIX "%s\\n\"\n", make_internal_name( odp, "regs" ) ); - break; case TYPE_VARIABLE: fprintf( outfile, " \"\\t.long " PREFIX "%s\\n\"\n", make_internal_name( odp, "var" ) ); break; @@ -239,14 +237,13 @@ static int output_exports( FILE *outfile, int nr_exports ) for (i = Base; i <= Limit; i++) { ORDDEF *odp = Ordinals[i]; - unsigned int j, mask = 0; + unsigned int j, args, mask = 0; + const char *name; /* skip non-existent entry points */ if (!odp) goto ignore; /* skip non-functions */ - if ((odp->type != TYPE_STDCALL) && - (odp->type != TYPE_CDECL) && - (odp->type != TYPE_REGISTER)) goto ignore; + if ((odp->type != TYPE_STDCALL) && (odp->type != TYPE_CDECL)) goto ignore; /* skip norelay entry points */ if (odp->flags & FLAG_NORELAY) goto ignore; @@ -257,31 +254,26 @@ static int output_exports( FILE *outfile, int nr_exports ) } if ((odp->flags & FLAG_RET64) && (j < 16)) mask |= 0x80000000; + name = odp->link_name; + args = strlen(odp->u.func.arg_types) * sizeof(int); + if (odp->flags & FLAG_REGISTER) + { + name = make_internal_name( odp, "regs" ); + args |= 0x8000; + } + switch(odp->type) { case TYPE_STDCALL: - fprintf( outfile, " \"\\tjmp " PREFIX "%s\\n\"\n", odp->link_name ); - fprintf( outfile, " \"\\tret $%d\\n\"\n", - strlen(odp->u.func.arg_types) * sizeof(int) ); - fprintf( outfile, " \"\\t.long " PREFIX "%s,0x%08x\\n\"\n", - odp->link_name, mask ); + fprintf( outfile, " \"\\tjmp " PREFIX "%s\\n\"\n", name ); + fprintf( outfile, " \"\\tret $0x%04x\\n\"\n", args ); + fprintf( outfile, " \"\\t.long " PREFIX "%s,0x%08x\\n\"\n", name, mask ); break; case TYPE_CDECL: - fprintf( outfile, " \"\\tjmp " PREFIX "%s\\n\"\n", odp->link_name ); + fprintf( outfile, " \"\\tjmp " PREFIX "%s\\n\"\n", name ); fprintf( outfile, " \"\\tret\\n\"\n" ); - fprintf( outfile, " \"\\t.short %d\\n\"\n", - strlen(odp->u.func.arg_types) * sizeof(int) ); - fprintf( outfile, " \"\\t.long " PREFIX "%s,0x%08x\\n\"\n", - odp->link_name, mask ); - break; - case TYPE_REGISTER: - fprintf( outfile, " \"\\tjmp " PREFIX "%s\\n\"\n", - make_internal_name( odp, "regs" ) ); - fprintf( outfile, " \"\\tret\\n\"\n" ); - fprintf( outfile, " \"\\t.short 0x%04x\\n\"\n", - 0x8000 | strlen(odp->u.func.arg_types) * sizeof(int) ); - fprintf( outfile, " \"\\t.long " PREFIX "%s,0x%08x\\n\"\n", - make_internal_name( odp, "regs" ), mask ); + fprintf( outfile, " \"\\t.short 0x%04x\\n\"\n", args ); + fprintf( outfile, " \"\\t.long " PREFIX "%s,0x%08x\\n\"\n", name, mask ); break; default: assert(0); @@ -401,7 +393,8 @@ static void output_register_funcs( FILE *outfile ) for (i = 0; i < nb_entry_points; i++) { ORDDEF *odp = EntryPoints[i]; - if (odp->type != TYPE_REGISTER) continue; + if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL) continue; + if (!(odp->flags & FLAG_REGISTER)) continue; name = make_internal_name( odp, "regs" ); fprintf( outfile, "asm(\".align %d\\n\\t\"\n" @@ -412,7 +405,8 @@ static void output_register_funcs( FILE *outfile ) " \".byte %d,%d\");\n", get_alignment(4), name, name, odp->link_name, - 4 * strlen(odp->u.func.arg_types), 4 * strlen(odp->u.func.arg_types) ); + strlen(odp->u.func.arg_types) * sizeof(int), + (odp->type == TYPE_CDECL) ? 0 : (strlen(odp->u.func.arg_types) * sizeof(int)) ); } }