[binutils-gdb] gdb/amd-dbgapi-target: Add amd-dbgapi-mingw-hdep.c for Windows

Pedro Alves via Gdb-cvs <[email protected]> Fri, 12 Jun 2026 13:37:18 +0000 (GMT)
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9e6e6a2272c78ab8e975692427c641609c0b4573

commit 9e6e6a2272c78ab8e975692427c641609c0b4573
Author: Lancelot SIX <[email protected]>
Date:   Wed May 8 11:36:28 2024 +0100

    gdb/amd-dbgapi-target: Add amd-dbgapi-mingw-hdep.c for Windows
    
    This patch adds amd-dbgapi-mingw-hdep.c which provides the
    implementations for all the host specific interactions with dbgapi on
    MinGW.
    
    Co-Authored-By: Pedro Alves <[email protected]>
    Change-Id: Ie244f2606b1e0af8f85b9113c3d93585eda893ed

Diff:
---
 gdb/Makefile.in             |   1 +
 gdb/amd-dbgapi-hdep.h       |   4 ++
 gdb/amd-dbgapi-mingw-hdep.c | 172 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/amd-dbgapi-posix-hdep.c |   7 ++
 gdb/amd-dbgapi-target.c     |   1 +
 gdb/configure               |   3 +
 gdb/configure.ac            |   3 +
 7 files changed, 191 insertions(+)

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index f67305a00b0..57f384170ab 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1793,6 +1793,7 @@ ALLDEPFILES = \
 	alpha-netbsd-tdep.c \
 	alpha-obsd-tdep.c \
 	alpha-tdep.c \
+	amd-dbgapi-mingw-hdep.c \
 	amd-dbgapi-posix-hdep.c \
 	amd-dbgapi-target.c \
 	amd64-bsd-nat.c \
diff --git a/gdb/amd-dbgapi-hdep.h b/gdb/amd-dbgapi-hdep.h
index 5d6fccb980c..795f94c81a6 100644
--- a/gdb/amd-dbgapi-hdep.h
+++ b/gdb/amd-dbgapi-hdep.h
@@ -31,4 +31,8 @@ extern void amd_dbgapi_notifier_clear (amd_dbgapi_notifier_t notifier);
 /* Get the file descriptor associated with the notifier.  */
 extern int amd_dbgapi_notifier_get_fd (amd_dbgapi_notifier_t notifier);
 
+/* Ensure that we do not keep a reference to NOTIFIER, which is about
+   to get invalidated.  */
+extern void amd_dbgapi_notifier_release (amd_dbgapi_notifier_t notifier);
+
 #endif /* GDB_AMD_DBGAPI_HDEP_H */
diff --git a/gdb/amd-dbgapi-mingw-hdep.c b/gdb/amd-dbgapi-mingw-hdep.c
new file mode 100644
index 00000000000..14cc614961a
--- /dev/null
+++ b/gdb/amd-dbgapi-mingw-hdep.c
@@ -0,0 +1,172 @@
+/* Host dependent utilities for the amd-dbgapi target on MinGW.
+
+   Copyright (C) 2024-2026 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "amd-dbgapi-hdep.h"
+#include <amd-dbgapi/amd-dbgapi.h>
+
+#include <winsock2.h>
+#include <windows.h>
+#include <io.h>
+#include <cstdio>
+#include <unordered_map>
+#include <algorithm>
+
+#include "serial.h"
+
+/* See amd-dbgapi-hdep.h.  */
+const amd_dbgapi_notifier_t null_amd_dbgapi_notifier = nullptr;
+
+/* Use a custom implementation of serial for events from dbgapi.  This is
+   really similar to what is implemented in ser-event.c, except that here:
+   - The underlying event object is not managed by us, but by dbgapi
+     instead.
+   - We keep a handy mapping from event object handles to serial
+     events for lookup.
+*/
+
+struct amd_dbgapi_serial_event_state
+{
+  /* The Windows event handle, provided by dbgapi.  */
+  HANDLE event;
+};
+
+/* Mapping from event object handles to serial events for lookup.  */
+static std::unordered_map<HANDLE, serial *> serial_event_cache;
+
+/* serial_ops::open implementation for the amd-dbgapi serial
+   event.  */
+
+static void
+amd_dbgapi_serial_event_state_open (struct serial *scb,
+				    const char *name)
+{
+  auto *state = new amd_dbgapi_serial_event_state;
+  scb->state = state;
+
+  HANDLE dummy_file = CreateFile ("nul", 0, 0, nullptr, OPEN_EXISTING, 0,
+				  nullptr);
+  scb->fd = _open_osfhandle ((intptr_t) dummy_file, 0);
+};
+
+/* serial_ops::close implementation for the amd-dbgapi serial
+   event.  */
+
+static void
+amd_dbgapi_serial_event_state_close (struct serial *scb)
+{
+  scb->fd = -1;
+  delete (amd_dbgapi_serial_event_state *) scb->state;
+  scb->state = nullptr;
+}
+
+/* serial_ops::wait_handle implementation for the amd-dbgapi serial
+   event.  */
+
+static void
+amd_dbgapi_serial_event_state_wait_handle (struct serial *scb,
+					   HANDLE *read,
+					   HANDLE *except)
+{
+  auto *state = (amd_dbgapi_serial_event_state *) scb->state;
+  *read = state->event;
+}
+
+static const struct serial_ops amd_dbgapi_serial_event_ops =
+{
+  "amd-dbgapi-event",
+  amd_dbgapi_serial_event_state_open,
+  amd_dbgapi_serial_event_state_close,
+  nullptr, /* fdopen */
+  nullptr, /* readchar */
+  nullptr, /* write */
+  nullptr, /* flush_output */
+  nullptr, /* flush_input */
+  nullptr, /* send_break */
+  nullptr, /* go_raw */
+  nullptr, /* get_tty_state */
+  nullptr, /* copy_tty_state */
+  nullptr, /* set_tty_state */
+  nullptr, /* print_tty_state */
+  nullptr, /* setbaudrate */
+  nullptr, /* setstopbits */
+  nullptr, /* setparity */
+  nullptr, /* drain_output */
+  nullptr, /* async */
+  nullptr, /* read_prim */
+  nullptr, /* write_prim */
+  nullptr, /* avail */
+  amd_dbgapi_serial_event_state_wait_handle,
+  nullptr, /* done_wait_handle */
+};
+
+/* Return the serial object associated with EVENT_HANDLE, creating it
+   if necessary.  */
+
+static serial *
+get_serial_event (HANDLE event_handle)
+{
+  auto it = serial_event_cache.find (event_handle);
+
+  /* If we already have a FD for this event, return it.  */
+  if (it != serial_event_cache.end ())
+    return it->second;
+
+  serial *scb = serial_open_ops (&amd_dbgapi_serial_event_ops);
+
+  /* Set the underlying Windows event object.  */
+  auto *state = (amd_dbgapi_serial_event_state *) scb->state;
+  state->event = event_handle;
+  serial_event_cache.insert ({event_handle, scb});
+
+  /* Keep one reference for the cache.  This will be released by
+     amd_dbgapi_notifier_release.  */
+  serial_ref (scb);
+
+  return scb;
+}
+
+/* See amd-dbgapi-hdep.h.  */
+
+void
+amd_dbgapi_notifier_clear (amd_dbgapi_notifier_t notifier)
+{
+  ResetEvent (notifier);
+}
+
+/* See amd-dbgapi-hdep.h.  */
+
+int
+amd_dbgapi_notifier_get_fd (amd_dbgapi_notifier_t notifier)
+{
+  return get_serial_event (notifier)->fd;
+}
+
+/* See amd-dbgapi-hdep.h.  */
+
+void
+amd_dbgapi_notifier_release (amd_dbgapi_notifier_t notifier)
+{
+  /* Remove the serial from the cache.  */
+  auto it = serial_event_cache.find (notifier);
+  if (it != serial_event_cache.end ())
+    {
+      serial_event_cache.erase (it);
+      serial_unref (get_serial_event (notifier));
+    }
+}
diff --git a/gdb/amd-dbgapi-posix-hdep.c b/gdb/amd-dbgapi-posix-hdep.c
index b8f6b44987f..3a818ae3fc1 100644
--- a/gdb/amd-dbgapi-posix-hdep.c
+++ b/gdb/amd-dbgapi-posix-hdep.c
@@ -46,3 +46,10 @@ amd_dbgapi_notifier_get_fd (amd_dbgapi_notifier_t notifier)
 {
   return notifier;
 }
+
+/* See amd-dbgapi-hdep.h.  */
+void
+amd_dbgapi_notifier_release (amd_dbgapi_notifier_t notifier)
+{
+  /* Nothing to do.  */
+}
diff --git a/gdb/amd-dbgapi-target.c b/gdb/amd-dbgapi-target.c
index 0d0ccdc082d..08f79006d57 100644
--- a/gdb/amd-dbgapi-target.c
+++ b/gdb/amd-dbgapi-target.c
@@ -1915,6 +1915,7 @@ detach_amd_dbgapi (inferior *inf)
 
   gdb_assert (info.notifier != null_amd_dbgapi_notifier);
   delete_file_handler (amd_dbgapi_notifier_get_fd (info.notifier));
+  amd_dbgapi_notifier_release (info.notifier);
 
   /* This is a noop if the target is not pushed.  */
   inf->unpush_target (&the_amd_dbgapi_target);
diff --git a/gdb/configure b/gdb/configure
index a03b7ad39ae..3733ef76948 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -25450,6 +25450,9 @@ $as_echo "#define HAVE_AMD_DBGAPI 1" >>confdefs.h
       *linux*)
 	gdb_host_obs="${gdb_host_obs} amd-dbgapi-posix-hdep.o"
 	;;
+      *mingw*)
+	gdb_host_obs="${gdb_host_obs} amd-dbgapi-mingw-hdep.o"
+	;;
       *)
 	as_fn_error $? "amd-dbgapi not supported for host ${gdb_host}" "$LINENO" 5
 	;;
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 03ed2b386bb..5296d76f2cf 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -347,6 +347,9 @@ if test "$gdb_require_amd_dbgapi" = true \
       *linux*)
 	gdb_host_obs="${gdb_host_obs} amd-dbgapi-posix-hdep.o"
 	;;
+      *mingw*)
+	gdb_host_obs="${gdb_host_obs} amd-dbgapi-mingw-hdep.o"
+	;;
       *)
 	AC_MSG_ERROR([amd-dbgapi not supported for host ${gdb_host}])
 	;;