Added patch to implement ntdll._aulldvrm.

This commit is contained in:
Sebastian Lackner 2017-01-21 22:56:05 +01:00
parent b2341b8d08
commit 65a5de8630
3 changed files with 225 additions and 0 deletions

View File

@ -0,0 +1,205 @@
From 39a879a7f82766177f6eb47fada8536e95543104 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 21 Jan 2017 22:54:40 +0100
Subject: ntdll: Implement _alldvrm/_aulldvrm and add tests.
---
dlls/ntdll/large_int.c | 62 ++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/ntdll.spec | 4 +--
dlls/ntdll/tests/large_int.c | 68 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 132 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/large_int.c b/dlls/ntdll/large_int.c
index a0d465c494a..18f06889e3b 100644
--- a/dlls/ntdll/large_int.c
+++ b/dlls/ntdll/large_int.c
@@ -660,4 +660,66 @@ ULONGLONG WINAPI _aullshr( ULONGLONG a, LONG b )
return a >> b;
}
+void CDECL _alldvrm_helper( LONGLONG *res, LONGLONG *arg )
+{
+ res[0] = arg[0] / arg[1];
+ res[1] = arg[0] % arg[1];
+}
+
+void CDECL _aulldvrm_helper( ULONGLONG *res, ULONGLONG *arg )
+{
+ res[0] = arg[0] / arg[1];
+ res[1] = arg[0] % arg[1];
+}
+
+/******************************************************************************
+ * _alldvrm (NTDLL.@)
+ */
+__ASM_GLOBAL_FUNC( _alldvrm,
+ "pushl %ebp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+ "movl %esp,%ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+ "subl $20,%esp\n\t"
+ "leal 8(%ebp),%eax\n\t"
+ "leal -16(%ebp),%ecx\n\t"
+ "pushl %eax\n\t"
+ "pushl %ecx\n\t"
+ "call " __ASM_NAME("_alldvrm_helper") "\n\t"
+ "leal -16(%ebp),%esp\n\t"
+ "popl %eax\n\t"
+ "popl %edx\n\t"
+ "popl %ecx\n\t"
+ "popl %ebx\n\t"
+ "popl %ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
+ "ret $16" )
+
+/******************************************************************************
+ * _aulldvrm (NTDLL.@)
+ */
+__ASM_GLOBAL_FUNC( _aulldvrm,
+ "pushl %ebp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+ "movl %esp,%ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+ "subl $20,%esp\n\t"
+ "leal 8(%ebp),%eax\n\t"
+ "leal -16(%ebp),%ecx\n\t"
+ "pushl %eax\n\t"
+ "pushl %ecx\n\t"
+ "call " __ASM_NAME("_aulldvrm_helper") "\n\t"
+ "leal -16(%ebp),%esp\n\t"
+ "popl %eax\n\t"
+ "popl %edx\n\t"
+ "popl %ecx\n\t"
+ "popl %ebx\n\t"
+ "popl %ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
+ "ret $16" )
+
#endif /* __i386__ */
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index f38401dd172..127fc71fb7f 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1330,7 +1330,7 @@
@ cdecl -private __iscsymf(long) NTDLL___iscsymf
@ cdecl -private __toascii(long) NTDLL___toascii
@ stdcall -private -arch=i386 -ret64 _alldiv(int64 int64)
-# @ stub _alldvrm
+@ stdcall -private -arch=i386 -norelay _alldvrm(int64 int64)
@ stdcall -private -arch=i386 -ret64 _allmul(int64 int64)
@ stdcall -private -arch=i386 -norelay _alloca_probe()
@ stdcall -private -arch=i386 -ret64 _allrem(int64 int64)
@@ -1338,7 +1338,7 @@
@ stdcall -private -arch=i386 -ret64 _allshr(int64 long)
@ cdecl -private -ret64 _atoi64(str)
@ stdcall -private -arch=i386 -ret64 _aulldiv(int64 int64)
-# @ stub _aulldvrm
+@ stdcall -private -arch=i386 -norelay _aulldvrm(int64 int64)
@ stdcall -private -arch=i386 -ret64 _aullrem(int64 int64)
@ stdcall -private -arch=i386 -ret64 _aullshr(int64 long)
@ stdcall -private -arch=i386 -norelay _chkstk()
diff --git a/dlls/ntdll/tests/large_int.c b/dlls/ntdll/tests/large_int.c
index f13ae882d05..a0d041daf8d 100644
--- a/dlls/ntdll/tests/large_int.c
+++ b/dlls/ntdll/tests/large_int.c
@@ -33,6 +33,8 @@ static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING);
static NTSTATUS (WINAPI *pRtlInt64ToUnicodeString)(ULONGLONG, ULONG, UNICODE_STRING *);
static NTSTATUS (WINAPI *pRtlLargeIntegerToChar)(ULONGLONG *, ULONG, ULONG, PCHAR);
static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
+static void (WINAPI *p_alldvrm)(LONGLONG, LONGLONG);
+static void (WINAPI *p_aulldvrm)(ULONGLONG, ULONGLONG);
static void InitFunctionPtrs(void)
@@ -45,6 +47,8 @@ static void InitFunctionPtrs(void)
pRtlInt64ToUnicodeString = (void *)GetProcAddress(hntdll, "RtlInt64ToUnicodeString");
pRtlLargeIntegerToChar = (void *)GetProcAddress(hntdll, "RtlLargeIntegerToChar");
pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
+ p_alldvrm = (void *)GetProcAddress(hntdll, "_alldvrm");
+ p_aulldvrm = (void *)GetProcAddress(hntdll, "_aulldvrm");
} /* if */
}
@@ -439,6 +443,66 @@ static void test_RtlLargeIntegerToChar(void)
}
+#ifdef __i386__
+
+#include "pshpack1.h"
+struct lldvrm_thunk
+{
+ BYTE push_ebx; /* pushl %ebx */
+ DWORD push_esp1; /* pushl 24(%esp) */
+ DWORD push_esp2; /* pushl 24(%esp) */
+ DWORD push_esp3; /* pushl 24(%esp) */
+ DWORD push_esp4; /* pushl 24(%esp) */
+ DWORD call; /* call 24(%esp) */
+ WORD mov_ecx_eax; /* movl %ecx,%eax */
+ WORD mov_ebx_edx; /* movl %ebx,%edx */
+ BYTE pop_ebx; /* popl %ebx */
+ BYTE ret; /* ret */
+};
+#include "poppack.h"
+
+static void test__alldvrm(void)
+{
+ struct lldvrm_thunk *thunk = VirtualAlloc(NULL, sizeof(*thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+ ULONGLONG (CDECL *call_lldvrm_func)(void *func, ULONGLONG, ULONGLONG) = (void *)thunk;
+ ULONGLONG ret;
+
+ memset(thunk, 0x90, sizeof(*thunk));
+ thunk->push_ebx = 0x53; /* pushl %ebx */
+ thunk->push_esp1 = 0x182474ff; /* pushl 24(%esp) */
+ thunk->push_esp2 = 0x182474ff; /* pushl 24(%esp) */
+ thunk->push_esp3 = 0x182474ff; /* pushl 24(%esp) */
+ thunk->push_esp4 = 0x182474ff; /* pushl 24(%esp) */
+ thunk->call = 0x182454ff; /* call 24(%esp) */
+ thunk->pop_ebx = 0x5b; /* popl %ebx */
+ thunk->ret = 0xc3; /* ret */
+
+ ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, 3);
+ ok(ret == 0x61172255b66c77ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
+ ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, -3);
+ ok(ret == 0xff9ee8ddaa499389ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
+
+ ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, 3);
+ ok(ret == 0x61172255b66c77ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
+ ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, -3);
+ ok(ret == 0, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
+
+ thunk->mov_ecx_eax = 0xc889;
+ thunk->mov_ebx_edx = 0xda89;
+
+ ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, 3);
+ ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
+ ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, -3);
+ ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
+
+ ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, 3);
+ ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
+ ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, -3);
+ ok(ret == 0x123456701234567ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
+}
+#endif /* __i386__ */
+
+
START_TEST(large_int)
{
InitFunctionPtrs();
@@ -449,4 +513,8 @@ START_TEST(large_int)
test_RtlInt64ToUnicodeString();
if (pRtlLargeIntegerToChar)
test_RtlLargeIntegerToChar();
+
+#ifdef __i386__
+ test__alldvrm();
+#endif /* __i386__ */
}
--
2.11.0

View File

@ -0,0 +1 @@
Fixes: [42267] Implement ntdll._aulldvrm

View File

@ -267,6 +267,7 @@ patch_enable_all ()
enable_ntdll_Wait_User_APC="$1"
enable_ntdll_WriteWatches="$1"
enable_ntdll_Zero_mod_name="$1"
enable_ntdll__aulldvrm="$1"
enable_ntdll_call_thread_func_wrapper="$1"
enable_ntoskrnl_DriverTest="$1"
enable_ntoskrnl_Stubs="$1"
@ -1020,6 +1021,9 @@ patch_enable ()
ntdll-Zero_mod_name)
enable_ntdll_Zero_mod_name="$2"
;;
ntdll-_aulldvrm)
enable_ntdll__aulldvrm="$2"
;;
ntdll-call_thread_func_wrapper)
enable_ntdll_call_thread_func_wrapper="$2"
;;
@ -6059,6 +6063,21 @@ if test "$enable_ntdll_Zero_mod_name" -eq 1; then
) >> "$patchlist"
fi
# Patchset ntdll-_aulldvrm
# |
# | This patchset fixes the following Wine bugs:
# | * [#42267] Implement ntdll._aulldvrm
# |
# | Modified files:
# | * dlls/ntdll/large_int.c, dlls/ntdll/ntdll.spec, dlls/ntdll/tests/large_int.c
# |
if test "$enable_ntdll__aulldvrm" -eq 1; then
patch_apply ntdll-_aulldvrm/0001-ntdll-Implement-_alldvrm-_aulldvrm-and-add-tests.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Implement _alldvrm/_aulldvrm and add tests.", 1 },';
) >> "$patchlist"
fi
# Patchset ntdll-call_thread_func_wrapper
# |
# | This patchset fixes the following Wine bugs: