mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
52 lines
2.2 KiB
Diff
52 lines
2.2 KiB
Diff
|
From 8c7754a1da9f43cf15057a8467c0b76c9da2ce40 Mon Sep 17 00:00:00 2001
|
||
|
From: Sebastian Lackner <sebastian@fds-team.de>
|
||
|
Date: Sat, 22 Nov 2014 05:49:30 +0100
|
||
|
Subject: ntdll: Fix issues with write watches when using Exagear.
|
||
|
|
||
|
---
|
||
|
dlls/ntdll/virtual.c | 21 +++++++++++++++++++++
|
||
|
1 file changed, 21 insertions(+)
|
||
|
|
||
|
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
|
||
|
index 1a8e4a4..4140323 100644
|
||
|
--- a/dlls/ntdll/virtual.c
|
||
|
+++ b/dlls/ntdll/virtual.c
|
||
|
@@ -1558,6 +1558,26 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err )
|
||
|
{
|
||
|
void *page = ROUND_ADDR( addr, page_mask );
|
||
|
BYTE *vprot = &view->prot[((const char *)page - (const char *)view->base) >> page_shift];
|
||
|
+#ifdef EXAGEAR_COMPAT
|
||
|
+ /* Exagear doesn't correctly set err, so always check for write watches, and
|
||
|
+ * retry after removing the VPROT_WRITEWATCH or VPROT_WRITECOPY flag. In
|
||
|
+ * contrary to the general implementation below this is not completely race-
|
||
|
+ * condition safe. When multiple threads trigger the write watch at the same
|
||
|
+ * time only the first thread will properly continue the execution, the rest
|
||
|
+ * will crash. */
|
||
|
+ if ((view->protect & VPROT_WRITEWATCH) && (*vprot & VPROT_WRITEWATCH))
|
||
|
+ {
|
||
|
+ *vprot &= ~VPROT_WRITEWATCH;
|
||
|
+ VIRTUAL_SetProt( view, page, page_size, *vprot );
|
||
|
+ if (VIRTUAL_GetUnixProt( *vprot ) & PROT_WRITE) ret = STATUS_SUCCESS;
|
||
|
+ }
|
||
|
+ if (*vprot & VPROT_WRITECOPY)
|
||
|
+ {
|
||
|
+ *vprot = (*vprot & ~VPROT_WRITECOPY) | VPROT_WRITE;
|
||
|
+ VIRTUAL_SetProt( view, page, page_size, *vprot );
|
||
|
+ if (VIRTUAL_GetUnixProt( *vprot ) & PROT_WRITE) ret = STATUS_SUCCESS;
|
||
|
+ }
|
||
|
+#else
|
||
|
if (err & EXCEPTION_WRITE_FAULT)
|
||
|
{
|
||
|
if ((view->protect & VPROT_WRITEWATCH) && (*vprot & VPROT_WRITEWATCH))
|
||
|
@@ -1573,6 +1593,7 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err )
|
||
|
/* ignore fault if page is writable now */
|
||
|
if (VIRTUAL_GetUnixProt( *vprot ) & PROT_WRITE) ret = STATUS_SUCCESS;
|
||
|
}
|
||
|
+#endif
|
||
|
if (*vprot & VPROT_GUARD)
|
||
|
{
|
||
|
VIRTUAL_SetProt( view, page, page_size, *vprot & ~VPROT_GUARD );
|
||
|
--
|
||
|
2.1.3
|
||
|
|