Am 10.01.2024 um 13:34 schrieb Eli Zaretskii:
Date: Tue, 9 Jan 2024 21:02:44 +0100
Cc: i...@google.com, gcc-patches@gcc.gnu.org, g...@gcc.gnu.org
From: Björn Schäpers <g...@hazardy.de>

Am 07.01.2024 um 18:03 schrieb Eli Zaretskii:
In that case, you an call either GetModuleHandeExA or
GetModuleHandeExW, the difference is minor.

Here an updated version without relying on TEXT or TCHAR, directly calling
GetModuleHandleExW.

Thanks, this LGTM (but I couldn't test it, I just looked at the
sour ce code).

Here an updated version. It is rebased on the combined approach of getting the loaded DLLs and two minor changes to suppress warnings.
From 55d0f312c0a9c4e2305d72fa2329b37937a02e44 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Sch=C3=A4pers?= <bjo...@hazardy.de>
Date: Sat, 6 Jan 2024 22:53:54 +0100
Subject: [PATCH 2/2] libbacktrace: Add loaded dlls after initialize

libbacktrace/Changelog:

        * pecoff.c [HAVE_WINDOWS_H]:
          (dll_notification_data): Added
          (dll_notification_context): Added
          (dll_notification): Added
          (backtrace_initialize): Use LdrRegisterDllNotification to load
                                  debug information of later loaded
                                  dlls.
---
 libbacktrace/pecoff.c | 106 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index faa0be0b700..455a5c2191d 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -61,6 +61,34 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #undef Module32Next
 #endif
 #endif
+
+#if defined(_ARM_)
+#define NTAPI
+#else
+#define NTAPI __stdcall
+#endif
+
+/* This is a simplified (but binary compatible) version of what Microsoft
+   defines in their documentation. */
+struct dll_notifcation_data
+{
+  ULONG reserved;
+  /* The name as UNICODE_STRING struct. */
+  PVOID full_dll_name;
+  PVOID base_dll_name;
+  PVOID dll_base;
+  ULONG size_of_image;
+};
+
+#define LDR_DLL_NOTIFICATION_REASON_LOADED 1
+
+typedef LONG NTSTATUS;
+typedef VOID CALLBACK (*LDR_DLL_NOTIFICATION)(ULONG,
+                                             struct dll_notifcation_data*,
+                                             PVOID);
+typedef NTSTATUS NTAPI (*LDR_REGISTER_FUNCTION)(ULONG,
+                                               LDR_DLL_NOTIFICATION, PVOID,
+                                               PVOID*);
 #endif
 
 /* Coff file header.  */
@@ -911,6 +939,53 @@ coff_add (struct backtrace_state *state, int descriptor,
   return 0;
 }
 
+#ifdef HAVE_WINDOWS_H
+struct dll_notification_context
+{
+  struct backtrace_state *state;
+  backtrace_error_callback error_callback;
+  void *data;
+};
+
+static VOID CALLBACK
+dll_notification (ULONG reason,
+                 struct dll_notifcation_data *notification_data,
+                 PVOID context)
+{
+  char module_name[MAX_PATH];
+  int descriptor;
+  struct dll_notification_context* dll_context =
+    (struct dll_notification_context*) context;
+  struct backtrace_state *state = dll_context->state;
+  void *data = dll_context->data;
+  backtrace_error_callback error_callback = dll_context->data;
+  fileline fileline;
+  int found_sym;
+  int found_dwarf;
+  HMODULE module_handle;
+
+  if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+    return;
+
+  if (!GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+                          | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+                          (wchar_t*) notification_data->dll_base,
+                          &module_handle))
+    return;
+
+  if (!GetModuleFileNameA ((HMODULE) module_handle, module_name, MAX_PATH - 1))
+    return;
+
+  descriptor = backtrace_open (module_name, error_callback, data, NULL);
+
+  if (descriptor < 0)
+    return;
+
+  coff_add (state, descriptor, error_callback, data, &fileline, &found_sym,
+           &found_dwarf, (uintptr_t) module_handle);
+}
+#endif
+
 /* Initialize the backtrace data we need from an ELF executable.  At
    the ELF level, all we need to do is find the debug info
    sections.  */
@@ -935,6 +1010,8 @@ backtrace_initialize (struct backtrace_state *state,
 #endif
 
 #ifdef HAVE_WINDOWS_H
+  HMODULE nt_dll_handle;
+
   module_handle = (uintptr_t) GetModuleHandle (NULL);
 #endif
 
@@ -981,6 +1058,35 @@ backtrace_initialize (struct backtrace_state *state,
     }
 #endif
 
+#ifdef HAVE_WINDOWS_H
+  nt_dll_handle = GetModuleHandleW (L"ntdll.dll");
+  if (nt_dll_handle)
+    {
+      LDR_REGISTER_FUNCTION register_func;
+      const char register_name[] = "LdrRegisterDllNotification";
+      register_func = (void*) GetProcAddress (nt_dll_handle,
+                                             register_name);
+
+      if (register_func)
+       {
+         PVOID cookie;
+         struct dll_notification_context *context
+           = backtrace_alloc (state,
+                              sizeof(struct dll_notification_context),
+                              error_callback, data);
+
+         if (context)
+           {
+             context->state = state;
+             context->data = data;
+             context->error_callback = error_callback;
+
+             register_func (0, &dll_notification, context, &cookie);
+           }
+       }
+    }
+#endif
+
   if (!state->threaded)
     {
       if (found_sym)
-- 
2.43.0

Reply via email to