Martin Storsjo : kernel32: Add a special case to EnumProcessModules for the local process.

Alexandre Julliard julliard at winehq.org
Mon Nov 4 16:40:25 CST 2019


Module: wine
Branch: master
Commit: fbda8db334f0703c0e66a2b84dda6bb56537f50b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=fbda8db334f0703c0e66a2b84dda6bb56537f50b

Author: Martin Storsjo <martin at martin.st>
Date:   Wed Oct 30 14:13:34 2019 +0200

kernel32: Add a special case to EnumProcessModules for the local process.

LLVM's libunwind uses EnumProcessModules for locating .eh_frame
sections when unwinding dwarf exceptions (used on i686).

When running wine in docker (without adding custom additional
permissions), EnumProcessModules currently fails as it uses
ReadProcessMemory, which requires the SYS_PTRACE capability.

The current implementation also is slower than necessary (by a
couple orders of magnituide), for accessing the current process.
Currently, unwinding 10000 exception throws with libunwind on i686
takes 24 seconds when run in wine, while it runs in less than 0.1
second with this patch.

Signed-off-by: Martin Storsjo <martin at martin.st>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/module.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/dlls/kernel32/module.c b/dlls/kernel32/module.c
index b7f19ffe36..45814dbff3 100644
--- a/dlls/kernel32/module.c
+++ b/dlls/kernel32/module.c
@@ -555,6 +555,40 @@ BOOL WINAPI K32EnumProcessModules(HANDLE process, HMODULE *lphModule,
     DWORD size = 0;
     INT ret;
 
+    if (process == GetCurrentProcess())
+    {
+        PPEB_LDR_DATA ldr_data = NtCurrentTeb()->Peb->LdrData;
+        PLIST_ENTRY head = &ldr_data->InLoadOrderModuleList;
+        PLIST_ENTRY entry = head->Flink;
+
+        if (cb && !lphModule)
+        {
+            SetLastError(ERROR_NOACCESS);
+            return FALSE;
+        }
+        while (entry != head)
+        {
+            PLDR_MODULE table_entry = (PLDR_MODULE)
+                ((PBYTE)entry - offsetof(LDR_MODULE, InLoadOrderModuleList));
+            if (cb >= sizeof(HMODULE))
+            {
+                *lphModule++ = table_entry->BaseAddress;
+                cb -= sizeof(HMODULE);
+            }
+            size += sizeof(HMODULE);
+            entry = entry->Flink;
+        }
+
+        if (!needed)
+        {
+            SetLastError(ERROR_NOACCESS);
+            return FALSE;
+        }
+        *needed = size;
+
+        return TRUE;
+    }
+
     if (!init_module_iterator(&iter, process))
         return FALSE;
 




More information about the wine-cvs mailing list