ntdll: Fix export and calling convention of RtlUlonglongByteSwap().
The RtlU*ByteSwap() family: - has FASTCALL calling convention - is only exported from ntdll and ntoskrnl.exe in 32bit mode (didn't check ARM though) Wine's support for RtlUlonglongByteSwap() doesn't follow these constraints. Note: in __fastcall, 64bit paramaters are passed on the stack, to RtlUlonglongByteSwap() calling convention acts as __stdcall. So: - fix ntdll.spec (resp. ntoskrnl.exe.spec) to only export (resp. forward) RtlUlonglongByteSwap for i386 - always provide an inline implementation in winternl.h - reimplement ntdll.RtlUlonglongByteSwap() for i386 with __fastcall calling convention. - fix ntdll/tests/rtl.c to use correct calling convention. - add test in ntdll/tests/rtl.c for inlined version. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53536 Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
This commit is contained in:
parent
b7380acb6c
commit
495711c251
6 changed files with 44 additions and 24 deletions
|
@ -1039,7 +1039,7 @@
|
|||
@ stdcall RtlTryEnterCriticalSection(ptr)
|
||||
@ stdcall RtlUTF8ToUnicodeN(ptr long ptr ptr long)
|
||||
@ cdecl -i386 -norelay RtlUlongByteSwap() NTDLL_RtlUlongByteSwap
|
||||
@ cdecl -ret64 RtlUlonglongByteSwap(int64)
|
||||
@ stdcall -fastcall -arch=i386 -norelay RtlUlonglongByteSwap(int64)
|
||||
# @ stub RtlUnhandledExceptionFilter2
|
||||
# @ stub RtlUnhandledExceptionFilter
|
||||
@ stdcall RtlUnicodeStringToAnsiSize(ptr)
|
||||
|
|
|
@ -641,10 +641,14 @@ DWORD WINAPI RtlComputeCrc32(DWORD dwInitial, const BYTE *pData, INT iLen)
|
|||
* RETURNS
|
||||
* The value with its bytes swapped.
|
||||
*/
|
||||
ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG i)
|
||||
{
|
||||
return ((ULONGLONG)RtlUlongByteSwap(i) << 32) | RtlUlongByteSwap(i>>32);
|
||||
}
|
||||
#ifdef __i386__
|
||||
__ASM_FASTCALL_FUNC(RtlUlonglongByteSwap, 8,
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"bswap %edx\n\t"
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"bswap %eax\n\t"
|
||||
"ret $8")
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
* RtlUlongByteSwap [NTDLL.@]
|
||||
|
|
|
@ -68,7 +68,7 @@ static VOID (WINAPI *pRtlMoveMemory)(LPVOID,LPCVOID,SIZE_T);
|
|||
static VOID (WINAPI *pRtlFillMemory)(LPVOID,SIZE_T,BYTE);
|
||||
static VOID (WINAPI *pRtlFillMemoryUlong)(LPVOID,SIZE_T,ULONG);
|
||||
static VOID (WINAPI *pRtlZeroMemory)(LPVOID,SIZE_T);
|
||||
static ULONGLONG (WINAPIV *pRtlUlonglongByteSwap)(ULONGLONG source);
|
||||
static ULONGLONG (FASTCALL *pRtlUlonglongByteSwap)(ULONGLONG source);
|
||||
static DWORD (WINAPI *pRtlGetThreadErrorMode)(void);
|
||||
static NTSTATUS (WINAPI *pRtlSetThreadErrorMode)(DWORD, LPDWORD);
|
||||
static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG);
|
||||
|
@ -319,18 +319,22 @@ static void test_RtlZeroMemory(void)
|
|||
|
||||
static void test_RtlUlonglongByteSwap(void)
|
||||
{
|
||||
ULONGLONG result;
|
||||
ULONGLONG llresult;
|
||||
|
||||
if ( !pRtlUlonglongByteSwap )
|
||||
#ifdef _WIN64
|
||||
/* the Rtl*ByteSwap() are always inlined and not exported from ntdll on 64bit */
|
||||
llresult = RtlUlonglongByteSwap( 0x7654321087654321ull );
|
||||
ok( 0x2143658710325476 == llresult,
|
||||
"inlined RtlUlonglongByteSwap() returns %#I64x\n", llresult );
|
||||
#else
|
||||
ok( pRtlUlonglongByteSwap != NULL, "RtlUlonglongByteSwap is not available\n");
|
||||
if ( pRtlUlonglongByteSwap )
|
||||
{
|
||||
win_skip("RtlUlonglongByteSwap is not available\n");
|
||||
return;
|
||||
llresult = pRtlUlonglongByteSwap( 0x7654321087654321ull );
|
||||
ok( 0x2143658710325476ull == llresult,
|
||||
"ntdll.RtlUlonglongByteSwap() returns %#I64x\n", llresult );
|
||||
}
|
||||
|
||||
result = pRtlUlonglongByteSwap( ((ULONGLONG)0x76543210 << 32) | 0x87654321 );
|
||||
ok( (((ULONGLONG)0x21436587 << 32) | 0x10325476) == result,
|
||||
"RtlUlonglongByteSwap(0x7654321087654321) returns 0x%s, expected 0x2143658710325476\n",
|
||||
wine_dbgstr_longlong(result));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2185,6 +2185,19 @@ LONG FASTCALL NTOSKRNL_InterlockedIncrement( LONG volatile *dest )
|
|||
return InterlockedIncrement( dest );
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
/*************************************************************************
|
||||
* RtlUlonglongByteSwap (NTOSKRNL.EXE.@)
|
||||
*/
|
||||
__ASM_FASTCALL_FUNC(RtlUlonglongByteSwap, 8,
|
||||
"movl 4(%esp),%edx\n\t"
|
||||
"bswap %edx\n\t"
|
||||
"movl 8(%esp),%eax\n\t"
|
||||
"bswap %eax\n\t"
|
||||
"ret $8")
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
/***********************************************************************
|
||||
* ExAllocatePool (NTOSKRNL.EXE.@)
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
@ stdcall -fastcall ObfReferenceObject(ptr)
|
||||
@ stub RtlPrefetchMemoryNonTemporal
|
||||
@ cdecl -i386 -norelay RtlUlongByteSwap()
|
||||
@ cdecl -ret64 RtlUlonglongByteSwap(int64)
|
||||
@ stdcall -fastcall -arch=i386 -norelay RtlUlonglongByteSwap(int64)
|
||||
@ cdecl -i386 -norelay RtlUshortByteSwap()
|
||||
@ stub WmiGetClock
|
||||
@ stub Kei386EoiHelper
|
||||
|
|
|
@ -4567,7 +4567,6 @@ NTSYSAPI BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive(RTL_SRWLOCK *);
|
|||
NTSYSAPI BOOLEAN WINAPI RtlTryAcquireSRWLockShared(RTL_SRWLOCK *);
|
||||
NTSYSAPI BOOL WINAPI RtlTryEnterCriticalSection(RTL_CRITICAL_SECTION *);
|
||||
NTSYSAPI NTSTATUS WINAPI RtlUTF8ToUnicodeN(WCHAR*,DWORD,DWORD*,const char*,DWORD);
|
||||
NTSYSAPI ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG);
|
||||
NTSYSAPI DWORD WINAPI RtlUnicodeStringToAnsiSize(const UNICODE_STRING*);
|
||||
NTSYSAPI NTSTATUS WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING,PCUNICODE_STRING,BOOLEAN);
|
||||
NTSYSAPI NTSTATUS WINAPI RtlUnicodeStringToInteger(const UNICODE_STRING *,ULONG,ULONG *);
|
||||
|
@ -4733,20 +4732,20 @@ static inline BOOLEAN RtlCheckBit(PCRTL_BITMAP lpBits, ULONG ulBit)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* These are implemented as __fastcall, so we can't let Winelib apps link with them */
|
||||
/* These are implemented as __fastcall, so we can't let Winelib apps link with them.
|
||||
* Moreover, they're always inlined and not exported on 64bit systems.
|
||||
*/
|
||||
static inline USHORT RtlUshortByteSwap(USHORT s)
|
||||
{
|
||||
return (s >> 8) | (s << 8);
|
||||
}
|
||||
static inline ULONG RtlUlongByteSwap(ULONG i)
|
||||
{
|
||||
#if defined(__i386__) && defined(__GNUC__)
|
||||
ULONG ret;
|
||||
__asm__("bswap %0" : "=r" (ret) : "0" (i) );
|
||||
return ret;
|
||||
#else
|
||||
return ((ULONG)RtlUshortByteSwap((USHORT)i) << 16) | RtlUshortByteSwap((USHORT)(i >> 16));
|
||||
#endif
|
||||
}
|
||||
static inline ULONGLONG RtlUlonglongByteSwap(ULONGLONG i)
|
||||
{
|
||||
return ((ULONGLONG)RtlUlongByteSwap((ULONG)i) << 32) | RtlUlongByteSwap((ULONG)(i >> 32));
|
||||
}
|
||||
|
||||
/* list manipulation macros */
|
||||
|
|
Loading…
Add table
Reference in a new issue